SNode.C
Loading...
Searching...
No Matches
PhysicalSocket.hpp
Go to the documentation of this file.
1/*
2 * SNode.C - a slim toolkit for network communication
3 * Copyright (C) Volker Christian <me@vchrist.at>
4 * 2020, 2021, 2022, 2023, 2024, 2025
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published
8 * by the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "net/phy/PhysicalSocket.h" // IWYU pragma: export
21
22#ifndef DOXYGEN_SHOULD_SKIP_THIS
23
24#include <map>
25#include <utility>
26
27#endif /* DOXYGEN_SHOULD_SKIP_THIS */
28
29namespace net::phy {
30
31 template <typename SocketAddress>
32 PhysicalSocket<SocketAddress>::PhysicalSocket(int domain, int type, int protocol)
33 : Descriptor(-1)
34 , domain(domain)
35 , type(type)
36 , protocol(protocol) {
37 }
38
39 template <typename SocketAddress>
40 PhysicalSocket<SocketAddress>::PhysicalSocket(int fd, const SocketAddress& bindAddress)
41 : Descriptor(fd)
42 , bindAddress(bindAddress) {
43 typename SocketAddress::SockLen optLen = sizeof(domain);
44 getSockopt(SOL_SOCKET, SO_DOMAIN, &domain, &optLen);
45
46 optLen = sizeof(type);
47 getSockopt(SOL_SOCKET, SO_TYPE, &type, &optLen);
49 optLen = sizeof(protocol);
50 getSockopt(SOL_SOCKET, SO_PROTOCOL, &protocol, &optLen);
51 }
52
53 template <typename SocketAddress>
54 PhysicalSocket<SocketAddress>::~PhysicalSocket() {
55 }
56
57 template <typename SocketAddress>
58 int PhysicalSocket<SocketAddress>::open(const std::map<int, const net::phy::PhysicalSocketOption>& socketOptions, Flags flags) {
59 int ret = Super::operator=(core::system::socket(domain, type | flags, protocol)).getFd();
60
61 if (ret >= 0) {
62 for (const auto& [optName, socketOption] : socketOptions) {
63 int setSockoptRet =
64 setSockopt(socketOption.getOptLevel(), socketOption.getOptName(), socketOption.getOptValue(), socketOption.getOptLen());
65
66 ret = (ret >= 0 && setSockoptRet < 0) ? setSockoptRet : ret;
67
68 if (ret < 0) {
69 break;
70 }
71 }
72 }
74 return ret;
75 }
76
77 template <typename SocketAddress>
78 int PhysicalSocket<SocketAddress>::bind(SocketAddress& bindAddress) {
79 int ret = core::system::bind(core::Descriptor::getFd(), &bindAddress.getSockAddr(), bindAddress.getSockAddrLen());
80
81 if (ret == 0) {
82 this->bindAddress = bindAddress;
83 }
84
85 return ret;
86 }
87
88 template <typename SocketAddress>
89 bool PhysicalSocket<SocketAddress>::isValid() const {
90 return core::Descriptor::getFd() >= 0;
91 }
92
93 template <typename SocketAddress>
94 int PhysicalSocket<SocketAddress>::getSockError(int& cErrno) const {
95 typename SocketAddress::SockLen cErrnoLen = sizeof(cErrno);
96 return getSockopt(SOL_SOCKET, SO_ERROR, &cErrno, &cErrnoLen);
97 }
98
99 template <typename SocketAddress>
100 int
101 PhysicalSocket<SocketAddress>::setSockopt(int level, int optname, const void* optval, typename SocketAddress::SockLen optlen) const {
102 return core::system::setsockopt(PhysicalSocket::getFd(), level, optname, optval, optlen);
103 }
104
105 template <typename SocketAddress>
106 int PhysicalSocket<SocketAddress>::getSockopt(int level, int optname, void* optval, typename SocketAddress::SockLen* optlen) const {
107 return core::system::getsockopt(PhysicalSocket::getFd(), level, optname, optval, optlen);
108 }
109
110 template <typename SocketAddress>
111 int PhysicalSocket<SocketAddress>::getSockName(typename SocketAddress::SockAddr& localSockAddr,
112 typename SocketAddress::SockLen& localSockAddrLen) {
113 return core::system::getsockname(core::Descriptor::getFd(), reinterpret_cast<sockaddr*>(&localSockAddr), &localSockAddrLen);
114 }
115
116 template <typename SocketAddress>
117 int PhysicalSocket<SocketAddress>::getPeerName(typename SocketAddress::SockAddr& remoteSockAddr,
118 typename SocketAddress::SockLen& remoteSockAddrLen) {
119 return core::system::getpeername(core::Descriptor::getFd(), reinterpret_cast<sockaddr*>(&remoteSockAddr), &remoteSockAddrLen);
120 }
121
122 template <typename SocketAddress>
123 SocketAddress PhysicalSocket<SocketAddress>::getBindAddress() const {
124 return bindAddress;
125 }
126
127} // namespace net::phy
int getPeerName(typename SocketAddress::SockAddr &remoteSockAddr, typename SocketAddress::SockLen &remoteSockAddrLen)
PhysicalSocket(int domain, int type, int protocol)
int setSockopt(int level, int optname, const void *optval, typename SocketAddress::SockLen optlen) const
int getSockError(int &cErrno) const
int open(const std::map< int, const PhysicalSocketOption > &socketOptions, Flags flags)
int bind(SocketAddress &bindAddress)
PhysicalSocket(int fd, const SocketAddress &bindAddress)
int getSockName(typename SocketAddress::SockAddr &localSockAddr, typename SocketAddress::SockLen &localSockAddrLen)
SocketAddress getBindAddress() const
int getSockopt(int level, int optname, void *optval, typename SocketAddress::SockLen *optlen) const