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/*
21 * MIT License
22 *
23 * Permission is hereby granted, free of charge, to any person obtaining a copy
24 * of this software and associated documentation files (the "Software"), to deal
25 * in the Software without restriction, including without limitation the rights
26 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
27 * copies of the Software, and to permit persons to whom the Software is
28 * furnished to do so, subject to the following conditions:
29 *
30 * The above copyright notice and this permission notice shall be included in
31 * all copies or substantial portions of the Software.
32 *
33 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
39 * THE SOFTWARE.
40 */
41
42#include "net/phy/PhysicalSocket.h" // IWYU pragma: export
43
44#ifndef DOXYGEN_SHOULD_SKIP_THIS
45
46#include <map>
47#include <utility>
48
49#endif /* DOXYGEN_SHOULD_SKIP_THIS */
50
51namespace net::phy {
52
53 template <typename SocketAddress>
54 PhysicalSocket<SocketAddress>::PhysicalSocket(int domain, int type, int protocol)
55 : Descriptor(-1)
56 , domain(domain)
57 , type(type)
58 , protocol(protocol) {
59 }
60
61 template <typename SocketAddress>
62 PhysicalSocket<SocketAddress>::PhysicalSocket(int fd, const SocketAddress& bindAddress)
63 : Descriptor(fd)
64 , bindAddress(bindAddress) {
65 typename SocketAddress::SockLen optLen = sizeof(domain);
66 getSockopt(SOL_SOCKET, SO_DOMAIN, &domain, &optLen);
67
68 optLen = sizeof(type);
69 getSockopt(SOL_SOCKET, SO_TYPE, &type, &optLen);
70
71 optLen = sizeof(protocol);
72 getSockopt(SOL_SOCKET, SO_PROTOCOL, &protocol, &optLen);
73 }
74
75 template <typename SocketAddress>
76 PhysicalSocket<SocketAddress>::~PhysicalSocket() {
77 }
78
79 template <typename SocketAddress>
80 int PhysicalSocket<SocketAddress>::open(const std::map<int, std::map<int, PhysicalSocketOption>>& socketOptionsMapMap, Flags flags) {
81 int ret = Super::operator=(core::system::socket(domain, type | flags, protocol)).getFd();
82
83 if (ret >= 0) {
84 for (const auto& [optLevel, socketOptionsMap] : socketOptionsMapMap) {
85 for (const auto& [optName, socketOption] : socketOptionsMap) {
86 int setSockoptRet = setSockopt(
87 socketOption.getOptLevel(), socketOption.getOptName(), socketOption.getOptValue(), socketOption.getOptLen());
88
89 ret = (ret >= 0 && setSockoptRet < 0) ? setSockoptRet : ret;
90
91 if (ret < 0) {
92 break;
93 }
94 }
95
96 if (ret < 0) {
97 break;
98 }
99 }
100 }
101
102 return ret;
103 }
104
105 template <typename SocketAddress>
106 int PhysicalSocket<SocketAddress>::bind(SocketAddress& bindAddress) {
107 int ret = core::system::bind(core::Descriptor::getFd(), &bindAddress.getSockAddr(), bindAddress.getSockAddrLen());
108
109 if (ret == 0) {
110 this->bindAddress = bindAddress;
111 }
112
113 return ret;
114 }
115
116 template <typename SocketAddress>
117 bool PhysicalSocket<SocketAddress>::isValid() const {
118 return core::Descriptor::getFd() >= 0;
119 }
120
121 template <typename SocketAddress>
122 int PhysicalSocket<SocketAddress>::getSockError(int& cErrno) const {
123 typename SocketAddress::SockLen cErrnoLen = sizeof(cErrno);
124 return getSockopt(SOL_SOCKET, SO_ERROR, &cErrno, &cErrnoLen);
125 }
126
127 template <typename SocketAddress>
128 int
129 PhysicalSocket<SocketAddress>::setSockopt(int level, int optname, const void* optval, typename SocketAddress::SockLen optlen) const {
130 return core::system::setsockopt(PhysicalSocket::getFd(), level, optname, optval, optlen);
131 }
132
133 template <typename SocketAddress>
134 int PhysicalSocket<SocketAddress>::getSockopt(int level, int optname, void* optval, typename SocketAddress::SockLen* optlen) const {
135 return core::system::getsockopt(PhysicalSocket::getFd(), level, optname, optval, optlen);
136 }
137
138 template <typename SocketAddress>
139 int PhysicalSocket<SocketAddress>::getSockName(typename SocketAddress::SockAddr& localSockAddr,
140 typename SocketAddress::SockLen& localSockAddrLen) {
141 return core::system::getsockname(core::Descriptor::getFd(), reinterpret_cast<sockaddr*>(&localSockAddr), &localSockAddrLen);
142 }
143
144 template <typename SocketAddress>
145 int PhysicalSocket<SocketAddress>::getPeerName(typename SocketAddress::SockAddr& remoteSockAddr,
146 typename SocketAddress::SockLen& remoteSockAddrLen) {
147 return core::system::getpeername(core::Descriptor::getFd(), reinterpret_cast<sockaddr*>(&remoteSockAddr), &remoteSockAddrLen);
148 }
149
150 template <typename SocketAddress>
151 const SocketAddress& PhysicalSocket<SocketAddress>::getBindAddress() const {
152 return bindAddress;
153 }
154
155} // namespace net::phy
int getFd() const
int open(const std::map< int, std::map< int, PhysicalSocketOption > > &socketOptionsMapMap, Flags flags)
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 bind(SocketAddress &bindAddress)
PhysicalSocket(int fd, const SocketAddress &bindAddress)
int getSockName(typename SocketAddress::SockAddr &localSockAddr, typename SocketAddress::SockLen &localSockAddrLen)
const SocketAddress & getBindAddress() const
int getSockopt(int level, int optname, void *optval, typename SocketAddress::SockLen *optlen) const
int getsockname(int sockfd, sockaddr *addr, socklen_t *addrlen)
Definition socket.cpp:81
int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen)
Definition socket.cpp:101
int socket(int domain, int type, int protocol)
Definition socket.cpp:52
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen)
Definition socket.cpp:106
int getpeername(int sockfd, sockaddr *addr, socklen_t *addrlen)
Definition socket.cpp:86
int bind(int sockfd, const sockaddr *addr, socklen_t addrlen)
Definition socket.cpp:57