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, const PhysicalSocketOption>>& socketOptionsMapMap,
81 Flags flags) {
82 int ret = Super::operator=(core::system::socket(domain, type | flags, protocol)).getFd();
83
84 if (ret >= 0) {
85 for (const auto& [optLevel, socketOptionsMap] : socketOptionsMapMap) {
86 for (const auto& [optName, socketOption] : socketOptionsMap) {
87 int setSockoptRet = setSockopt(
88 socketOption.getOptLevel(), socketOption.getOptName(), socketOption.getOptValue(), socketOption.getOptLen());
89
90 ret = (ret >= 0 && setSockoptRet < 0) ? setSockoptRet : ret;
91
92 if (ret < 0) {
93 break;
94 }
95 }
96
97 if (ret < 0) {
98 break;
99 }
100 }
101 }
102
103 return ret;
104 }
105
106 template <typename SocketAddress>
107 int PhysicalSocket<SocketAddress>::bind(SocketAddress& bindAddress) {
108 int ret = core::system::bind(core::Descriptor::getFd(), &bindAddress.getSockAddr(), bindAddress.getSockAddrLen());
109
110 if (ret == 0) {
111 this->bindAddress = bindAddress;
112 }
113
114 return ret;
115 }
116
117 template <typename SocketAddress>
118 bool PhysicalSocket<SocketAddress>::isValid() const {
119 return core::Descriptor::getFd() >= 0;
120 }
121
122 template <typename SocketAddress>
123 int PhysicalSocket<SocketAddress>::getSockError(int& cErrno) const {
124 typename SocketAddress::SockLen cErrnoLen = sizeof(cErrno);
125 return getSockopt(SOL_SOCKET, SO_ERROR, &cErrno, &cErrnoLen);
126 }
127
128 template <typename SocketAddress>
129 int
130 PhysicalSocket<SocketAddress>::setSockopt(int level, int optname, const void* optval, typename SocketAddress::SockLen optlen) const {
131 return core::system::setsockopt(PhysicalSocket::getFd(), level, optname, optval, optlen);
132 }
133
134 template <typename SocketAddress>
135 int PhysicalSocket<SocketAddress>::getSockopt(int level, int optname, void* optval, typename SocketAddress::SockLen* optlen) const {
136 return core::system::getsockopt(PhysicalSocket::getFd(), level, optname, optval, optlen);
137 }
138
139 template <typename SocketAddress>
140 int PhysicalSocket<SocketAddress>::getSockName(typename SocketAddress::SockAddr& localSockAddr,
141 typename SocketAddress::SockLen& localSockAddrLen) {
142 return core::system::getsockname(core::Descriptor::getFd(), reinterpret_cast<sockaddr*>(&localSockAddr), &localSockAddrLen);
143 }
144
145 template <typename SocketAddress>
146 int PhysicalSocket<SocketAddress>::getPeerName(typename SocketAddress::SockAddr& remoteSockAddr,
147 typename SocketAddress::SockLen& remoteSockAddrLen) {
148 return core::system::getpeername(core::Descriptor::getFd(), reinterpret_cast<sockaddr*>(&remoteSockAddr), &remoteSockAddrLen);
149 }
150
151 template <typename SocketAddress>
152 SocketAddress PhysicalSocket<SocketAddress>::getBindAddress() const {
153 return bindAddress;
154 }
155
156} // namespace net::phy
int getFd() const
int getPeerName(typename SocketAddress::SockAddr &remoteSockAddr, typename SocketAddress::SockLen &remoteSockAddrLen)
PhysicalSocket(int domain, int type, int protocol)
int open(const std::map< int, std::map< int, const PhysicalSocketOption > > &socketOptionsMapMap, Flags flags)
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)
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