join 1.0
lightweight network framework library
Loading...
Searching...
No Matches
acceptor.hpp
Go to the documentation of this file.
1
25#ifndef JOIN_CORE_ACCEPTOR_HPP
26#define JOIN_CORE_ACCEPTOR_HPP
27
28// libjoin.
30
31namespace join
32{
36 template <class Protocol>
38 {
39 public:
40 using Endpoint = typename Protocol::Endpoint;
41 using Socket = typename Protocol::Socket;
42 using Stream = typename Protocol::Stream;
43
47 BasicStreamAcceptor () = default;
48
54
61
67 : _handle (other._handle)
68 , _protocol (other._protocol)
69 {
70 other._handle = -1;
71 other._protocol = Protocol ();
72 }
73
80 {
81 close ();
82
83 _handle = other._handle;
84 _protocol = other._protocol;
85
86 other._handle = -1;
87 other._protocol = Protocol ();
88
89 return *this;
90 }
91
96 {
97 close ();
98 }
99
106 int create (const Endpoint& endpoint, int flags = SOCK_CLOEXEC) noexcept
107 {
108 if (opened ())
109 {
110 lastError = make_error_code (Errc::InUse);
111 return -1;
112 }
113
114 _handle = ::socket (endpoint.protocol ().family (), endpoint.protocol ().type () | flags,
115 endpoint.protocol ().protocol ());
116 if (_handle == -1)
117 {
118 // LCOV_EXCL_START
119 lastError = std::error_code (errno, std::generic_category ());
120 close ();
121 return -1;
122 // LCOV_EXCL_STOP
123 }
124
125 if (endpoint.protocol ().family () == AF_INET6)
126 {
127 int off = 0;
128
129 if (::setsockopt (_handle, IPPROTO_IPV6, IPV6_V6ONLY, &off, sizeof (off)) == -1)
130 {
131 // LCOV_EXCL_START
132 lastError = std::error_code (errno, std::generic_category ());
133 close ();
134 return -1;
135 // LCOV_EXCL_STOP
136 }
137 }
138
139 if (endpoint.protocol ().family () == AF_UNIX)
140 {
141 ::unlink (endpoint.device ().c_str ());
142 }
143 else if (endpoint.protocol ().protocol () == IPPROTO_TCP)
144 {
145 int on = 1;
146
147 if (::setsockopt (_handle, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) == -1)
148 {
149 // LCOV_EXCL_START
150 lastError = std::error_code (errno, std::generic_category ());
151 close ();
152 return -1;
153 // LCOV_EXCL_STOP
154 }
155 }
156
157 if ((::bind (_handle, endpoint.addr (), endpoint.length ()) == -1) || (::listen (_handle, SOMAXCONN) == -1))
158 {
159 lastError = std::error_code (errno, std::generic_category ());
160 close ();
161 return -1;
162 }
163
164 _protocol = endpoint.protocol ();
165
166 return 0;
167 }
168
172 void close () noexcept
173 {
174 if (_handle != -1)
175 {
176 ::close (_handle);
177 _handle = -1;
178 }
179
180 _protocol = Protocol ();
181 }
182
188 Socket accept (int flags = SOCK_NONBLOCK | SOCK_CLOEXEC) const
189 {
190 struct sockaddr_storage sa;
191 socklen_t sa_len = sizeof (struct sockaddr_storage);
192
193 int fd = ::accept4 (_handle, reinterpret_cast<struct sockaddr*> (&sa), &sa_len, flags);
194 if (fd == -1)
195 {
196 lastError = std::error_code (errno, std::generic_category ());
197 return {};
198 }
199
200 return Socket (fd, Endpoint (reinterpret_cast<struct sockaddr*> (&sa), sa_len),
201 (flags & SOCK_NONBLOCK) ? Socket::NonBlocking : Socket::Blocking);
202 }
203
209 {
210 Stream stream;
211 stream.socket () = accept ();
212 return stream;
213 }
214
220 {
221 struct sockaddr_storage sa;
222 socklen_t sa_len = sizeof (struct sockaddr_storage);
223
224 if (::getsockname (_handle, reinterpret_cast<struct sockaddr*> (&sa), &sa_len) == -1)
225 {
226 lastError = std::error_code (errno, std::generic_category ());
227 return {};
228 }
229
230 return Endpoint (reinterpret_cast<struct sockaddr*> (&sa), sa_len);
231 }
232
237 bool opened () const noexcept
238 {
239 return (_handle != -1);
240 }
241
246 int family () const noexcept
247 {
248 return _protocol.family ();
249 }
250
255 int type () const noexcept
256 {
257 return _protocol.type ();
258 }
259
264 int protocol () const noexcept
265 {
266 return _protocol.protocol ();
267 }
268
273 int handle () const noexcept
274 {
275 return _handle;
276 }
277
278 private:
280 int _handle = -1;
281
283 Protocol _protocol;
284 };
285}
286
287#endif
basic stream acceptor class.
Definition protocol.hpp:53
BasicStreamAcceptor()=default
create the acceptor instance.
~BasicStreamAcceptor()
destroy instance.
Definition acceptor.hpp:95
bool opened() const noexcept
check if the socket is opened.
Definition acceptor.hpp:237
BasicStreamAcceptor(const BasicStreamAcceptor &other)=delete
copy constructor.
typename Protocol::Endpoint Endpoint
Definition acceptor.hpp:40
Endpoint localEndpoint() const
determine the local endpoint associated with this socket.
Definition acceptor.hpp:219
void close() noexcept
close acceptor.
Definition acceptor.hpp:172
int family() const noexcept
get address family.
Definition acceptor.hpp:246
typename Protocol::Stream Stream
Definition acceptor.hpp:42
int protocol() const noexcept
get acceptor protocol.
Definition acceptor.hpp:264
int type() const noexcept
get the protocol communication semantic.
Definition acceptor.hpp:255
Stream acceptStream() const
accept new connection and fill in the client object with connection parameters.
Definition acceptor.hpp:208
Socket accept(int flags=SOCK_NONBLOCK|SOCK_CLOEXEC) const
accept new connection and fill in the client object with connection parameters.
Definition acceptor.hpp:188
typename Protocol::Socket Socket
Definition acceptor.hpp:41
int handle() const noexcept
get socket native handle.
Definition acceptor.hpp:273
BasicStreamAcceptor(BasicStreamAcceptor &&other)
move constructor.
Definition acceptor.hpp:66
int create(const Endpoint &endpoint, int flags=SOCK_CLOEXEC) noexcept
create acceptor
Definition acceptor.hpp:106
BasicStreamAcceptor & operator=(const BasicStreamAcceptor &other)=delete
copy assignment operator.
Definition acceptor.hpp:32
std::error_code make_error_code(join::Errc code) noexcept
Create an std::error_code object.
Definition error.cpp:195