SNode.C
Loading...
Searching...
No Matches
SocketAcceptor.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 "core/State.h"
21#include "core/socket/stream/SocketAcceptor.h"
22
23#ifndef DOXYGEN_SHOULD_SKIP_THIS
24
25#include "log/Logger.h"
26#include "utils/PreserveErrno.h"
27
28#include <iomanip>
29#include <string>
30#include <utility>
31
32#endif // DOXYGEN_SHOULD_SKIP_THIS
33
34namespace core::socket::stream {
35
36 template <typename SocketAddress, typename PhysicalSocket, typename Config>
37 SocketAddress getLocalSocketAddress(PhysicalSocket& physicalSocket, Config& config) {
38 typename SocketAddress::SockAddr localSockAddr;
39 typename SocketAddress::SockLen localSockAddrLen = sizeof(typename SocketAddress::SockAddr);
40
41 SocketAddress localPeerAddress;
42 if (physicalSocket.getSockName(localSockAddr, localSockAddrLen) == 0) {
43 try {
44 localPeerAddress = config->Local::getSocketAddress(localSockAddr, localSockAddrLen);
45 LOG(TRACE) << config->getInstanceName() << " [" << physicalSocket.getFd() << "]" << std::setw(25)
46 << " PeerAddress (local): " << localPeerAddress.toString();
47 } catch (const typename SocketAddress::BadSocketAddress& badSocketAddress) {
48 LOG(WARNING) << config->getInstanceName() << " [" << physicalSocket.getFd() << "]" << std::setw(25)
49 << " PeerAddress (local): " << badSocketAddress.what();
50 }
51 } else {
52 PLOG(WARNING) << config->getInstanceName() << " [" << physicalSocket.getFd() << "]" << std::setw(25)
53 << " PeerAddress (local) not retrievable";
54 }
56 return localPeerAddress;
57 }
58
59 template <typename SocketAddress, typename PhysicalSocket, typename Config>
60 SocketAddress getRemoteSocketAddress(PhysicalSocket& physicalSocket, Config& config) {
61 typename SocketAddress::SockAddr remoteSockAddr;
62 typename SocketAddress::SockLen remoteSockAddrLen = sizeof(typename SocketAddress::SockAddr);
63
64 SocketAddress remotePeerAddress;
65 if (physicalSocket.getPeerName(remoteSockAddr, remoteSockAddrLen) == 0) {
66 try {
67 remotePeerAddress = config->Remote::getSocketAddress(remoteSockAddr, remoteSockAddrLen);
68 LOG(TRACE) << config->getInstanceName() << " [" << physicalSocket.getFd() << "]" << std::setw(25)
69 << " PeerAddress (remote): " << remotePeerAddress.toString();
70 } catch (const typename SocketAddress::BadSocketAddress& badSocketAddress) {
71 LOG(WARNING) << config->getInstanceName() << " [" << physicalSocket.getFd() << "]" << std::setw(25)
72 << " PeerAddress (remote): " << badSocketAddress.what();
73 }
74 } else {
75 PLOG(WARNING) << config->getInstanceName() << " [" << physicalSocket.getFd() << "]" << std::setw(25)
76 << " PeerAddress (remote) not retrievable";
77 }
78
79 return remotePeerAddress;
80 }
81
82 template <typename PhysicalSocketServer, typename Config, template <typename PhysicalSocketServerT> typename SocketConnection>
101
102 template <typename PhysicalSocketServer, typename Config, template <typename PhysicalSocketServerT> typename SocketConnection>
115
116 template <typename PhysicalSocketServer, typename Config, template <typename PhysicalSocketServerT> typename SocketConnection>
119
120 template <typename PhysicalSocketServer, typename Config, template <typename PhysicalSocketServerT> typename SocketConnection>
123 try {
124 LOG(TRACE) << config->getInstanceName() << " Starting";
125
127
129
131 switch (errno) {
132 case EMFILE:
133 case ENFILE:
134 case ENOBUFS:
135 case ENOMEM:
136 PLOG(DEBUG) << config->getInstanceName() << " open: '" << localAddress.toString() << "'";
137
139 break;
140 default:
141 PLOG(DEBUG) << config->getInstanceName() << " open: '" << localAddress.toString() << "'";
142
144 break;
145 }
146 } else if (physicalServerSocket.bind(localAddress) < 0) {
147 switch (errno) {
148 case EADDRINUSE:
149 PLOG(DEBUG) << config->getInstanceName() << " bind: '" << localAddress.toString() << "'";
150
152 break;
153 default:
154 PLOG(DEBUG) << config->getInstanceName() << " bind: '" << localAddress.toString() << "'";
155
157 break;
158 }
159 } else if (physicalServerSocket.listen(config->getBacklog()) < 0) {
160 switch (errno) {
161 case EADDRINUSE:
162 PLOG(DEBUG) << config->getInstanceName() << " listen: '" << localAddress.toString() << "'";
163
165 break;
166 default:
167 PLOG(DEBUG) << config->getInstanceName() << " listen: '" << localAddress.toString() << "'";
168
170 break;
171 }
172 } else {
174 LOG(DEBUG) << config->getInstanceName() << " enabled: '" << localAddress.toString() << "' success";
175 } else {
176 LOG(DEBUG) << config->getInstanceName() << " enabled: '" << localAddress.toString() << "' failed";
177
178 state = core::socket::STATE(core::socket::STATE_FATAL, ECANCELED, "SocketAcceptor not enabled");
179 }
180 }
181
182 if (localAddress.useNext()) {
183 LOG(DEBUG) << config->getInstanceName() << " using next SocketAddress: '"
184 << config->Local::getSocketAddress().toString() << "'";
185
187
189 } else {
191 }
192 } catch (const typename SocketAddress::BadSocketAddress& badSocketAddress) {
193 LOG(DEBUG) << config->getInstanceName() << " " << badSocketAddress.what();
194
196 }
197 } else {
198 LOG(DEBUG) << config->getInstanceName() << " disabled";
199
201 }
202
203 if (isEnabled()) {
205 } else {
206 destruct();
207 }
208 }
209
210 template <typename PhysicalSocketServer, typename Config, template <typename PhysicalSocketServerT> typename SocketConnection>
242
243 template <typename PhysicalSocketServer, typename Config, template <typename PhysicalSocketServerT> typename SocketConnection>
247
248 template <typename PhysicalSocketServer, typename Config, template <typename PhysicalSocketServerT> typename SocketConnection>
252
253} // namespace core::socket::stream
SocketAcceptor(const SocketAcceptor &socketAcceptor)
SocketAddress getRemoteSocketAddress(PhysicalSocket &physicalSocket, Config &config)
SocketAddress getLocalSocketAddress(PhysicalSocket &physicalSocket, Config &config)