Toolbox snapshot
The Reactive C++ Toolbox
Loading...
Searching...
No Matches
Socket.hpp
Go to the documentation of this file.
1// The Reactive C++ Toolbox.
2// Copyright (C) 2013-2019 Swirly Cloud Limited
3// Copyright (C) 2022 Reactive Markets Limited
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17#ifndef TOOLBOX_NET_SOCKET_HPP
18#define TOOLBOX_NET_SOCKET_HPP
19
20#include <toolbox/net/Error.hpp>
21
22#include <toolbox/io/File.hpp>
23
24#include <net/if.h>
25#include <netdb.h>
26#include <netinet/tcp.h>
27#include <linux/net_tstamp.h>
28
29namespace toolbox {
30inline namespace net {
31using AddrInfoPtr = std::unique_ptr<addrinfo, void (*)(addrinfo*)>;
32} // namespace net
33namespace os {
34
36inline AddrInfoPtr getaddrinfo(const char* node, const char* service, const addrinfo& hints,
37 std::error_code& ec) noexcept
38{
39 addrinfo* ai{nullptr};
40 const auto err = ::getaddrinfo(node, service, &hints, &ai);
41 if (err != 0) {
43 }
44 return {ai, freeaddrinfo};
45}
46
48inline AddrInfoPtr getaddrinfo(const char* node, const char* service, const addrinfo& hints)
49{
50 addrinfo* ai{nullptr};
51 const auto err = ::getaddrinfo(node, service, &hints, &ai);
52 if (err != 0) {
53 throw std::system_error{make_gai_error_code(err),
54 "getaddrinfo (" + std::string{node ? node : ""} + ")"};
55 }
56 return {ai, freeaddrinfo};
57}
58
60inline AddrInfoPtr getaddrinfo(const char* node, const char* service, int family, int type,
61 int protocol, std::error_code& ec) noexcept
62{
64 // If node is not specified, then return a wildcard address suitable for bind()ing.
65 hints.ai_flags = node ? 0 : AI_PASSIVE;
66 hints.ai_family = family;
67 hints.ai_socktype = type;
68 hints.ai_protocol = protocol;
69 return getaddrinfo(node, service, hints, ec);
70}
71
73inline AddrInfoPtr getaddrinfo(const char* node, const char* service, int family, int type,
74 int protocol)
75{
77 // If node is not specified, then return a wildcard address suitable for bind()ing.
78 hints.ai_flags = node ? 0 : AI_PASSIVE;
79 hints.ai_family = family;
80 hints.ai_socktype = type;
81 hints.ai_protocol = protocol;
82 return getaddrinfo(node, service, hints);
83}
84
86template <typename ProtocolT>
87inline AddrInfoPtr getaddrinfo(const char* node, const char* service, ProtocolT protocol,
88 std::error_code& ec) noexcept
89{
90 return getaddrinfo(node, service, protocol.family(), protocol.type(), protocol.protocol(), ec);
91}
92
94template <typename ProtocolT>
95inline AddrInfoPtr getaddrinfo(const char* node, const char* service, ProtocolT protocol)
96{
97 return getaddrinfo(node, service, protocol.family(), protocol.type(), protocol.protocol());
98}
99
100inline std::string gethostname()
101{
102 char buffer[HOST_NAME_MAX + 1];
103 if (::gethostname(buffer, sizeof(buffer)) < 0) {
104 throw std::system_error{make_error(errno), "gethostname"};
105 }
106 buffer[HOST_NAME_MAX] = '\0';
107 return std::string{buffer};
108}
109
110inline std::string gethostname(std::error_code& ec) noexcept
111{
112 char buffer[HOST_NAME_MAX + 1];
113 if (::gethostname(buffer, sizeof(buffer)) < 0) {
115 return {};
116 }
117 buffer[HOST_NAME_MAX] = '\0';
118 return std::string{buffer};
119}
120
122inline unsigned if_nametoindex(const char* ifname, std::error_code& ec) noexcept
123{
124 unsigned ifindex{0};
125 if (ifname) {
126 if (!(ifindex = ::if_nametoindex(ifname))) {
128 }
129 }
130 return ifindex;
131}
132
134inline unsigned if_nametoindex(const char* ifname)
135{
136 unsigned ifindex{0};
137 if (ifname) {
138 if (!(ifindex = ::if_nametoindex(ifname))) {
139 throw std::system_error{make_error(errno), "if_nametoindex"};
140 }
141 }
142 return ifindex;
143}
144
146inline FileHandle socket(int family, int type, int protocol, std::error_code& ec) noexcept
147{
148 const auto sockfd = ::socket(family, type, protocol);
149 if (sockfd < 0) {
151 }
152 return sockfd;
153}
154
156inline FileHandle socket(int family, int type, int protocol)
157{
158 const auto sockfd = ::socket(family, type, protocol);
159 if (sockfd < 0) {
160 throw std::system_error{make_error(errno), "socket"};
161 }
162 return sockfd;
163}
164
166template <typename ProtocolT>
167inline FileHandle socket(ProtocolT protocol, std::error_code& ec) noexcept
168{
169 return socket(protocol.family(), protocol.type(), protocol.protocol(), ec);
170}
171
173template <typename ProtocolT>
175{
176 return socket(protocol.family(), protocol.type(), protocol.protocol());
177}
178
180inline std::pair<FileHandle, FileHandle> socketpair(int family, int type, int protocol,
181 std::error_code& ec) noexcept
182{
183 int sv[2];
184 if (::socketpair(family, type, protocol, sv) < 0) {
186 }
187 return {FileHandle{sv[0]}, FileHandle{sv[1]}};
188}
189
191inline std::pair<FileHandle, FileHandle> socketpair(int family, int type, int protocol)
192{
193 int sv[2];
194 if (::socketpair(family, type, protocol, sv) < 0) {
195 throw std::system_error{make_error(errno), "socketpair"};
196 }
197 return {FileHandle{sv[0]}, FileHandle{sv[1]}};
198}
199
201template <typename ProtocolT>
202inline std::pair<FileHandle, FileHandle> socketpair(ProtocolT protocol,
203 std::error_code& ec) noexcept
204{
205 return socketpair(protocol.family(), protocol.type(), protocol.protocol(), ec);
206}
207
209template <typename ProtocolT>
210inline std::pair<FileHandle, FileHandle> socketpair(ProtocolT protocol)
211{
212 return socketpair(protocol.family(), protocol.type(), protocol.protocol());
213}
214
217 std::error_code& ec) noexcept
218{
219 // The addrlen argument is updated to contain the actual size of the source address.
220 // The returned address is truncated if the buffer provided is too small.
221 const auto fd = ::accept(sockfd, &addr, &addrlen);
222 if (fd < 0) {
224 }
225 return fd;
226}
227
230{
231 // The addrlen argument is updated to contain the actual size of the source address.
232 // The returned address is truncated if the buffer provided is too small.
233 const auto fd = ::accept(sockfd, &addr, &addrlen);
234 if (fd < 0) {
235 throw std::system_error{make_error(errno), "accept"};
236 }
237 return fd;
238}
239
241inline FileHandle accept(int sockfd, std::error_code& ec) noexcept
242{
243 const auto fd = ::accept(sockfd, nullptr, nullptr);
244 if (fd < 0) {
246 }
247 return fd;
248}
249
252{
253 const auto fd = ::accept(sockfd, nullptr, nullptr);
254 if (fd < 0) {
255 throw std::system_error{make_error(errno), "accept"};
256 }
257 return fd;
258}
259
261template <typename EndpointT>
262inline FileHandle accept(int sockfd, EndpointT& ep, std::error_code& ec) noexcept
263{
264 socklen_t addrlen = ep.capacity();
265 FileHandle fh{accept(sockfd, *ep.data(), addrlen, ec)};
266 if (!ec) {
267 ep.resize(std::min<std::size_t>(addrlen, ep.capacity()));
268 }
269 return fh;
270}
271
273template <typename EndpointT>
275{
276 socklen_t addrlen = ep.capacity();
277 FileHandle fh{accept(sockfd, *ep.data(), addrlen)};
278 ep.resize(std::min<std::size_t>(addrlen, ep.capacity()));
279 return fh;
280}
281
283inline void bind(int sockfd, const sockaddr& addr, socklen_t addrlen, std::error_code& ec) noexcept
284{
285 if (::bind(sockfd, &addr, addrlen) < 0) {
287 }
288}
289
291inline void bind(int sockfd, const sockaddr& addr, socklen_t addrlen)
292{
293 if (::bind(sockfd, &addr, addrlen) < 0) {
294 throw std::system_error{make_error(errno), "bind"};
295 }
296}
297
299template <typename EndpointT>
300inline void bind(int sockfd, const EndpointT& ep, std::error_code& ec) noexcept
301{
302 bind(sockfd, *ep.data(), ep.size(), ec);
303}
304
306template <typename EndpointT>
307inline void bind(int sockfd, const EndpointT& ep)
308{
309 bind(sockfd, *ep.data(), ep.size());
310}
311
313inline void connect(int sockfd, const sockaddr& addr, socklen_t addrlen,
314 std::error_code& ec) noexcept
315{
316 if (::connect(sockfd, &addr, addrlen) < 0) {
318 }
319}
320
322inline void connect(int sockfd, const sockaddr& addr, socklen_t addrlen)
323{
324 if (::connect(sockfd, &addr, addrlen) < 0) {
325 throw std::system_error{make_error(errno), "connect"};
326 }
327}
328
330template <typename EndpointT>
331inline void connect(int sockfd, const EndpointT& ep, std::error_code& ec) noexcept
332{
333 connect(sockfd, *ep.data(), ep.size(), ec);
334}
335
337template <typename EndpointT>
338inline void connect(int sockfd, const EndpointT& ep)
339{
340 connect(sockfd, *ep.data(), ep.size());
341}
342
344inline void listen(int sockfd, int backlog, std::error_code& ec) noexcept
345{
346 if (::listen(sockfd, backlog) < 0) {
348 }
349}
350
352inline void listen(int sockfd, int backlog)
353{
354 if (::listen(sockfd, backlog) < 0) {
355 throw std::system_error{make_error(errno), "listen"};
356 }
357}
358
360inline void shutdown(int sockfd, int how, std::error_code& ec) noexcept
361{
362 if (::shutdown(sockfd, how) < 0) {
364 }
365}
366
368inline void shutdown(int sockfd, int how)
369{
370 if (::shutdown(sockfd, how) < 0) {
371 throw std::system_error{make_error(errno), "shutdown"};
372 }
373}
374
376inline ssize_t recv(int sockfd, void* buf, std::size_t len, int flags, std::error_code& ec) noexcept
377{
378 const auto ret = ::recv(sockfd, buf, len, flags);
379 if (ret < 0) {
381 }
382 return ret;
383}
384
386inline std::size_t recv(int sockfd, void* buf, std::size_t len, int flags)
387{
388 const auto ret = ::recv(sockfd, buf, len, flags);
389 if (ret < 0) {
390 throw std::system_error{make_error(errno), "recv"};
391 }
392 return ret;
393}
394
396inline ssize_t recv(int sockfd, MutableBuffer buf, int flags, std::error_code& ec) noexcept
397{
398 return recv(sockfd, static_cast<void*>(buf.data()), buffer_size(buf), flags, ec);
399}
400
402inline std::size_t recv(int sockfd, MutableBuffer buf, int flags)
403{
404 return recv(sockfd, static_cast<void*>(buf.data()), buffer_size(buf), flags);
405}
406
407inline ssize_t recvmsg(int sockfd, msghdr& msg, int flags, std::error_code& ec) noexcept
408{
409 const auto ret = ::recvmsg(sockfd, &msg, flags);
410 if (ret < 0) {
412 }
413 return ret;
414}
415
416inline std::size_t recvmsg(int sockfd, msghdr& msg, int flags)
417{
418 const auto ret = ::recvmsg(sockfd, &msg, flags);
419 if (ret < 0) {
420 throw std::system_error{make_error(errno), "recvmsg"};
421 }
422 return ret;
423}
424
426inline ssize_t recvfrom(int sockfd, void* buf, std::size_t len, int flags, sockaddr& addr,
427 socklen_t& addrlen, std::error_code& ec) noexcept
428{
429 // The addrlen argument is updated to contain the actual size of the source address.
430 // The returned address is truncated if the buffer provided is too small.
431 const auto ret = ::recvfrom(sockfd, buf, len, flags, &addr, &addrlen);
432 if (ret < 0) {
434 }
435 return ret;
436}
437
439inline std::size_t recvfrom(int sockfd, void* buf, std::size_t len, int flags, sockaddr& addr,
441{
442 // The addrlen argument is updated to contain the actual size of the source address.
443 // The returned address is truncated if the buffer provided is too small.
444 const auto ret = ::recvfrom(sockfd, buf, len, flags, &addr, &addrlen);
445 if (ret < 0) {
446 throw std::system_error{make_error(errno), "recvfrom"};
447 }
448 return ret;
449}
450
452template <typename EndpointT>
453inline ssize_t recvfrom(int sockfd, void* buf, std::size_t len, int flags, EndpointT& ep,
454 std::error_code& ec) noexcept
455{
456 socklen_t addrlen = ep.capacity();
457 const auto ret = recvfrom(sockfd, buf, len, flags, *ep.data(), addrlen, ec);
458 if (!ec) {
459 ep.resize(std::min<std::size_t>(addrlen, ep.capacity()));
460 }
461 return ret;
462}
463
465template <typename EndpointT>
466inline std::size_t recvfrom(int sockfd, void* buf, std::size_t len, int flags, EndpointT& ep)
467{
468 socklen_t addrlen = ep.capacity();
469 const auto ret = recvfrom(sockfd, buf, len, flags, *ep.data(), addrlen);
470 ep.resize(std::min<std::size_t>(addrlen, ep.capacity()));
471 return ret;
472}
473
475template <typename EndpointT>
477 std::error_code& ec) noexcept
478{
479 return recvfrom(sockfd, static_cast<void*>(buf.data()), buffer_size(buf), flags, ep, ec);
480}
481
483template <typename EndpointT>
484inline std::size_t recvfrom(int sockfd, MutableBuffer buf, int flags, EndpointT& ep)
485{
486 return recvfrom(sockfd, static_cast<void*>(buf.data()), buffer_size(buf), flags, ep);
487}
488
490inline ssize_t send(int sockfd, const void* buf, std::size_t len, int flags,
491 std::error_code& ec) noexcept
492{
493 const auto ret = ::send(sockfd, buf, len, flags);
494 if (ret < 0) {
496 }
497 return ret;
498}
499
501inline std::size_t send(int sockfd, const void* buf, std::size_t len, int flags)
502{
503 const auto ret = ::send(sockfd, buf, len, flags);
504 if (ret < 0) {
505 throw std::system_error{make_error(errno), "send"};
506 }
507 return ret;
508}
509
511inline ssize_t send(int sockfd, ConstBuffer buf, int flags, std::error_code& ec) noexcept
512{
513 return send(sockfd, static_cast<const void*>(buf.data()), buffer_size(buf), flags, ec);
514}
515
517inline std::size_t send(int sockfd, ConstBuffer buf, int flags)
518{
519 return send(sockfd, static_cast<const void*>(buf.data()), buffer_size(buf), flags);
520}
521
523inline ssize_t sendto(int sockfd, const void* buf, std::size_t len, int flags, const sockaddr& addr,
524 socklen_t addrlen, std::error_code& ec) noexcept
525{
526 const auto ret = ::sendto(sockfd, buf, len, flags, &addr, addrlen);
527 if (ret < 0) {
529 }
530 return ret;
531}
532
534inline std::size_t sendto(int sockfd, const void* buf, std::size_t len, int flags,
536{
537 const auto ret = ::sendto(sockfd, buf, len, flags, &addr, addrlen);
538 if (ret < 0) {
539 throw std::system_error{make_error(errno), "sendto"};
540 }
541 return ret;
542}
543
545template <typename EndpointT>
546inline ssize_t sendto(int sockfd, const void* buf, std::size_t len, int flags, const EndpointT& ep,
547 std::error_code& /*ec*/) noexcept
548{
549 return sendto(sockfd, buf, len, flags, *ep.data(), ep.size());
550}
551
553template <typename EndpointT>
554inline std::size_t sendto(int sockfd, const void* buf, std::size_t len, int flags,
555 const EndpointT& ep)
556{
557 return sendto(sockfd, buf, len, flags, *ep.data(), ep.size());
558}
559
561template <typename EndpointT>
563 std::error_code& ec) noexcept
564{
565 return sendto(sockfd, static_cast<const void*>(buf.data()), buffer_size(buf), flags, *ep.data(),
566 ep.size(), ec);
567}
568
570template <typename EndpointT>
571inline std::size_t sendto(int sockfd, ConstBuffer buf, int flags, const EndpointT& ep)
572{
573 return sendto(sockfd, static_cast<const void*>(buf.data()), buffer_size(buf), flags, *ep.data(),
574 ep.size());
575}
576
579 std::error_code& ec) noexcept
580{
581 // The addrlen argument is updated to contain the actual size of the source address.
582 // The returned address is truncated if the buffer provided is too small.
583 if (::getsockname(sockfd, &addr, &addrlen) < 0) {
585 }
586}
587
590{
591 // The addrlen argument is updated to contain the actual size of the source address.
592 // The returned address is truncated if the buffer provided is too small.
593 if (::getsockname(sockfd, &addr, &addrlen) < 0) {
594 throw std::system_error{make_error(errno), "getsockname"};
595 }
596}
597
599template <typename EndpointT>
600inline void getsockname(int sockfd, EndpointT& ep, std::error_code& ec) noexcept
601{
602 socklen_t addrlen = ep.capacity();
603 getsockname(sockfd, *ep.data(), addrlen, ec);
604 if (!ec) {
605 ep.resize(std::min<std::size_t>(addrlen, ep.capacity()));
606 }
607}
608
610template <typename EndpointT>
611inline void getsockname(int sockfd, EndpointT& ep)
612{
613 socklen_t addrlen = ep.capacity();
614 getsockname(sockfd, *ep.data(), addrlen);
615 ep.resize(std::min<std::size_t>(addrlen, ep.capacity()));
616}
617
619inline void getsockopt(int sockfd, int level, int optname, void* optval, socklen_t& optlen,
620 std::error_code& ec) noexcept
621{
622 if (::getsockopt(sockfd, level, optname, optval, &optlen) < 0) {
624 }
625}
626
628inline void getsockopt(int sockfd, int level, int optname, void* optval, socklen_t& optlen)
629{
630 if (::getsockopt(sockfd, level, optname, optval, &optlen) < 0) {
631 throw std::system_error{make_error(errno), "getsockopt"};
632 }
633}
634
636inline void setsockopt(int sockfd, int level, int optname, const void* optval, socklen_t optlen,
637 std::error_code& ec) noexcept
638{
639 if (::setsockopt(sockfd, level, optname, optval, optlen) < 0) {
641 }
642}
643
645inline void setsockopt(int sockfd, int level, int optname, const void* optval, socklen_t optlen)
646{
647 if (::setsockopt(sockfd, level, optname, optval, optlen) < 0) {
648 throw std::system_error{make_error(errno), "setsockopt"};
649 }
650}
651
652} // namespace os
653inline namespace net {
654
656TOOLBOX_API AddrInfoPtr get_unix_addrinfo(std::string_view path, int type);
657
658template <typename EndpointT>
659inline void get_sock_name(int sockfd, EndpointT& ep, std::error_code& ec) noexcept
660{
662}
663
664template <typename EndpointT>
666{
668}
669
670inline std::error_code get_so_error(int sockfd, std::error_code& ec) noexcept
671{
672 int optval{};
673 socklen_t optlen{sizeof(optval)};
675 return make_error(optval);
676}
677
678inline std::error_code get_so_error(int sockfd)
679{
680 int optval{};
681 socklen_t optlen{sizeof(optval)};
683 return make_error(optval);
684}
685
686inline int get_so_rcv_buf(int sockfd, std::error_code& ec) noexcept
687{
688 int optval{};
689 socklen_t optlen{sizeof(optval)};
691 return optval;
692}
693
694inline int get_so_rcv_buf(int sockfd)
695{
696 int optval{};
697 socklen_t optlen{sizeof(optval)};
699 return optval;
700}
701
702inline int get_so_snd_buf(int sockfd, std::error_code& ec) noexcept
703{
704 int optval{};
705 socklen_t optlen{sizeof(optval)};
707 return optval;
708}
709
710inline int get_so_snd_buf(int sockfd)
711{
712 int optval{};
713 socklen_t optlen{sizeof(optval)};
715 return optval;
716}
717
718inline bool is_tcp_no_delay(int sockfd, std::error_code& ec) noexcept
719{
720 int optval{};
721 socklen_t optlen{sizeof(optval)};
723 return optval != 0;
724}
725
726inline bool is_tcp_no_delay(int sockfd)
727{
728 int optval{};
729 socklen_t optlen{sizeof(optval)};
731 return optval != 0;
732}
733
734inline void set_so_rcv_buf(int sockfd, int size, std::error_code& ec) noexcept
735{
737}
738
739inline void set_so_rcv_buf(int sockfd, int size)
740{
742}
743
744inline void set_so_reuse_addr(int sockfd, bool enabled, std::error_code& ec) noexcept
745{
746 int optval{enabled ? 1 : 0};
748}
749
750inline void set_so_reuse_addr(int sockfd, bool enabled)
751{
752 int optval{enabled ? 1 : 0};
754}
755
756inline void set_so_snd_buf(int sockfd, int size, std::error_code& ec) noexcept
757{
759}
760
761inline void set_so_snd_buf(int sockfd, int size)
762{
764}
765
776inline void set_tcp_no_delay(int sockfd, bool enabled, std::error_code& ec) noexcept
777{
778 int optval{enabled ? 1 : 0};
780}
781
791inline void set_tcp_no_delay(int sockfd, bool enabled)
792{
793 int optval{enabled ? 1 : 0};
795}
796
804inline void set_tcp_syn_nt(int sockfd, int retrans, std::error_code& ec) noexcept
805{
807}
808
815inline void set_tcp_syn_nt(int sockfd, int retrans)
816{
818}
819
820inline void set_so_timestamping(int sockfd, int flags, std::error_code& ec) noexcept
821{
823}
824
825inline void set_so_timestamping(int sockfd, int flags)
826{
828}
829
830inline int get_so_timestamping(int sockfd, std::error_code& ec) noexcept
831{
832 int optval{};
833 socklen_t optlen{sizeof(optval)};
835 return optval;
836}
837
839{
840 int optval{};
841 socklen_t optlen{sizeof(optval)};
843 return optval;
844}
845
846struct Sock : FileHandle {
849 , family_{family}
850 {
851 }
853
854 int family() const noexcept { return family_; }
855 bool is_ip_family() const noexcept { return family_ == AF_INET || family_ == AF_INET6; }
856
857 // Logically const.
858 std::error_code get_error(std::error_code& ec) const noexcept
859 {
860 return toolbox::get_so_error(get(), ec);
861 }
862 std::error_code get_error() const { return toolbox::get_so_error(get()); }
863
864 int get_rcv_buf(std::error_code& ec) const noexcept
865 {
866 return toolbox::get_so_rcv_buf(get(), ec);
867 }
868 int get_rcv_buf() const { return toolbox::get_so_rcv_buf(get()); }
869
870 int get_snd_buf(std::error_code& ec) const noexcept
871 {
872 return toolbox::get_so_snd_buf(get(), ec);
873 }
874 int get_snd_buf() const { return toolbox::get_so_snd_buf(get()); }
875
876 bool is_tcp_no_delay(std::error_code& ec) const noexcept
877 {
879 }
880 bool is_tcp_no_delay() const { return toolbox::is_tcp_no_delay(get()); }
881 void close() { reset(); }
882
883 void set_non_block(std::error_code& ec) noexcept { toolbox::set_non_block(get(), ec); }
885
886 void set_rcv_buf(int size, std::error_code& ec) noexcept
887 {
889 }
891
892 void set_reuse_addr(bool enabled, std::error_code& ec) noexcept
893 {
895 }
897
898 void set_snd_buf(int size, std::error_code& ec) noexcept
899 {
901 }
903
910
911 void enable_hardware_rcv_timestamps(std::error_code& ec) noexcept
912 {
913 if (int flags = get_so_timestamping(get(), ec); !ec) {
916 }
917 }
918
928
929 void disable_hardware_rcv_timestamps(std::error_code& ec) noexcept
930 {
931 if (int flags = get_so_timestamping(get(), ec); !ec) {
935 }
937 }
938 }
939
940 private:
941 int family_{};
942};
943
944} // namespace net
945} // namespace toolbox
946
947#endif // TOOLBOX_NET_SOCKET_HPP
#define TOOLBOX_API
Definition Config.h:39
STL namespace.
boost::asio::const_buffer ConstBuffer
Definition Buffer.hpp:28
boost::asio::mutable_buffer MutableBuffer
Definition Buffer.hpp:29
void set_non_block(int fd, std::error_code &ec) noexcept
Definition File.hpp:287
int get_so_snd_buf(int sockfd, std::error_code &ec) noexcept
Definition Socket.hpp:702
void set_so_reuse_addr(int sockfd, bool enabled, std::error_code &ec) noexcept
Definition Socket.hpp:744
std::unique_ptr< addrinfo, void(*)(addrinfo *)> AddrInfoPtr
Definition Socket.hpp:31
void set_so_snd_buf(int sockfd, int size, std::error_code &ec) noexcept
Definition Socket.hpp:756
void set_so_rcv_buf(int sockfd, int size, std::error_code &ec) noexcept
Definition Socket.hpp:734
std::error_code get_so_error(int sockfd, std::error_code &ec) noexcept
Definition Socket.hpp:670
void set_tcp_no_delay(int sockfd, bool enabled, std::error_code &ec) noexcept
Definition Socket.hpp:776
int get_so_timestamping(int sockfd, std::error_code &ec) noexcept
Definition Socket.hpp:830
void set_tcp_syn_nt(int sockfd, int retrans, std::error_code &ec) noexcept
Definition Socket.hpp:804
void get_sock_name(int sockfd, EndpointT &ep, std::error_code &ec) noexcept
Definition Socket.hpp:659
std::error_code make_gai_error_code(int err) noexcept
Definition Error.cpp:54
AddrInfoPtr get_unix_addrinfo(string_view path, int type)
Create an addrinfo structure for a Unix domain address.
Definition Socket.cpp:35
bool is_tcp_no_delay(int sockfd, std::error_code &ec) noexcept
Definition Socket.hpp:718
void set_so_timestamping(int sockfd, int flags, std::error_code &ec) noexcept
Definition Socket.hpp:820
int get_so_rcv_buf(int sockfd, std::error_code &ec) noexcept
Definition Socket.hpp:686
FileHandle accept(int sockfd, sockaddr &addr, socklen_t &addrlen, std::error_code &ec) noexcept
Accept a connection on a socket.
Definition Socket.hpp:216
void getsockopt(int sockfd, int level, int optname, void *optval, socklen_t &optlen, std::error_code &ec) noexcept
Get socket option.
Definition Socket.hpp:619
ssize_t recvmsg(int sockfd, msghdr &msg, int flags, std::error_code &ec) noexcept
Definition Socket.hpp:407
void setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen, std::error_code &ec) noexcept
Set socket option.
Definition Socket.hpp:636
std::pair< FileHandle, FileHandle > socketpair(int family, int type, int protocol, std::error_code &ec) noexcept
Create a pair of connected sockets.
Definition Socket.hpp:180
std::string gethostname()
Definition Socket.hpp:100
AddrInfoPtr getaddrinfo(const char *node, const char *service, const addrinfo &hints, std::error_code &ec) noexcept
Get network address from Internet host and service.
Definition Socket.hpp:36
void listen(int sockfd, int backlog, std::error_code &ec) noexcept
Listen for connections on a socket.
Definition Socket.hpp:344
ssize_t recvfrom(int sockfd, void *buf, std::size_t len, int flags, sockaddr &addr, socklen_t &addrlen, std::error_code &ec) noexcept
Receive a message from a socket.
Definition Socket.hpp:426
void getsockname(int sockfd, sockaddr &addr, socklen_t &addrlen, std::error_code &ec) noexcept
Get the socket name.
Definition Socket.hpp:578
unsigned if_nametoindex(const char *ifname, std::error_code &ec) noexcept
Returns the index of the network interface corresponding to the name ifname.
Definition Socket.hpp:122
FileHandle socket(int family, int type, int protocol, std::error_code &ec) noexcept
Create an endpoint for communication.
Definition Socket.hpp:146
ssize_t send(int sockfd, const void *buf, std::size_t len, int flags, std::error_code &ec) noexcept
Send a message on a socket.
Definition Socket.hpp:490
void shutdown(int sockfd, int how, std::error_code &ec) noexcept
Shut-down part of a full-duplex connection.
Definition Socket.hpp:360
void connect(int sockfd, const sockaddr &addr, socklen_t addrlen, std::error_code &ec) noexcept
Initiate a connection on a socket.
Definition Socket.hpp:313
ssize_t sendto(int sockfd, const void *buf, std::size_t len, int flags, const sockaddr &addr, socklen_t addrlen, std::error_code &ec) noexcept
Send a message on a socket.
Definition Socket.hpp:523
ssize_t recv(int sockfd, void *buf, std::size_t len, int flags, std::error_code &ec) noexcept
Receive a message from a socket.
Definition Socket.hpp:376
std::error_code make_error(int err) noexcept
Definition Error.hpp:25
constexpr std::size_t size(const detail::Struct< detail::Member< TagsT, ValuesT >... > &s)
Definition Struct.hpp:98
std::string_view sv
Definition Tokeniser.hpp:26
constexpr const auto & get(const detail::Struct< detail::Member< TagsT, ValuesT >... > &s, TagT tag={})
Definition Struct.hpp:110
constexpr auto bind() noexcept
Definition Slot.hpp:97
bool is_tcp_no_delay() const
Definition Socket.hpp:880
void enable_hardware_rcv_timestamps()
Definition Socket.hpp:904
void set_reuse_addr(bool enabled)
Definition Socket.hpp:896
void disable_hardware_rcv_timestamps()
Definition Socket.hpp:919
int family() const noexcept
Definition Socket.hpp:854
int get_rcv_buf(std::error_code &ec) const noexcept
Definition Socket.hpp:864
int get_snd_buf() const
Definition Socket.hpp:874
std::error_code get_error(std::error_code &ec) const noexcept
Definition Socket.hpp:858
void set_rcv_buf(int size)
Definition Socket.hpp:890
bool is_tcp_no_delay(std::error_code &ec) const noexcept
Definition Socket.hpp:876
int get_rcv_buf() const
Definition Socket.hpp:868
void disable_hardware_rcv_timestamps(std::error_code &ec) noexcept
Definition Socket.hpp:929
Sock() noexcept=default
void set_snd_buf(int size)
Definition Socket.hpp:902
Sock(FileHandle &&sock, int family)
Definition Socket.hpp:847
void set_reuse_addr(bool enabled, std::error_code &ec) noexcept
Definition Socket.hpp:892
void enable_hardware_rcv_timestamps(std::error_code &ec) noexcept
Definition Socket.hpp:911
int get_snd_buf(std::error_code &ec) const noexcept
Definition Socket.hpp:870
void set_non_block(std::error_code &ec) noexcept
Definition Socket.hpp:883
std::error_code get_error() const
Definition Socket.hpp:862
void set_snd_buf(int size, std::error_code &ec) noexcept
Definition Socket.hpp:898
void set_rcv_buf(int size, std::error_code &ec) noexcept
Definition Socket.hpp:886
bool is_ip_family() const noexcept
Definition Socket.hpp:855