join 1.0
lightweight network framework library
Loading...
Searching...
No Matches
endpoint.hpp
Go to the documentation of this file.
1
25#ifndef JOIN_CORE_ENDPOINT_HPP
26#define JOIN_CORE_ENDPOINT_HPP
27
28// libjoin.
29#include <join/mac_address.hpp>
30
31// C++.
32#include <ostream>
33#include <compare>
34
35// C.
36#include <linux/if_packet.h>
37#ifdef JOIN_HAS_XDP
38#include <linux/if_xdp.h>
39#endif
40#include <sys/un.h>
41#include <cstring>
42
43namespace join
44{
48 template <class Protocol>
50 {
51 public:
55 constexpr BasicEndpoint () noexcept
56 {
57 this->_addr.ss_family = Protocol ().family ();
58 }
59
65 BasicEndpoint (const struct sockaddr* addr, socklen_t len) noexcept
66 {
67 memcpy (&this->_addr, addr, len);
68 }
69
74 struct sockaddr* addr () noexcept
75 {
76 return reinterpret_cast<struct sockaddr*> (&this->_addr);
77 }
78
83 const struct sockaddr* addr () const noexcept
84 {
85 return reinterpret_cast<const struct sockaddr*> (&this->_addr);
86 }
87
88 protected:
90 struct sockaddr_storage _addr = {};
91 };
92
96 template <class Protocol>
97 class BasicLinkLayerEndpoint : public BasicEndpoint<Protocol>
98 {
99 public:
104 : BasicEndpoint<Protocol> ()
105 {
106 reinterpret_cast<struct sockaddr_ll*> (&this->_addr)->sll_protocol = this->protocol ().protocol ();
107 }
108
114 BasicLinkLayerEndpoint (const struct sockaddr* addr, socklen_t len) noexcept
116 {
117 }
118
123 BasicLinkLayerEndpoint (const char* dev) noexcept
125 {
126 reinterpret_cast<struct sockaddr_ll*> (&this->_addr)->sll_ifindex = if_nametoindex (dev);
127 }
128
133 BasicLinkLayerEndpoint (const std::string& dev) noexcept
134 : BasicLinkLayerEndpoint<Protocol> (dev.c_str ())
135 {
136 }
137
142 constexpr Protocol protocol () const noexcept
143 {
144 return Protocol ();
145 }
146
151 constexpr socklen_t length () const noexcept
152 {
153 return sizeof (struct sockaddr_ll);
154 }
155
160 void device (const std::string& dev) noexcept
161 {
162 reinterpret_cast<struct sockaddr_ll*> (&this->_addr)->sll_ifindex = if_nametoindex (dev.c_str ());
163 }
164
169 std::string device () const
170 {
171 char ifname[IFNAMSIZ];
172 if (if_indextoname (reinterpret_cast<const struct sockaddr_ll*> (&this->_addr)->sll_ifindex, ifname))
173 {
174 return ifname;
175 }
176 return {};
177 }
178
183 int index () const noexcept
184 {
185 return reinterpret_cast<const struct sockaddr_ll*> (&this->_addr)->sll_ifindex;
186 }
187 };
188
195 template <class Protocol>
197 {
198 return a.index () == b.index ();
199 }
200
207 template <class Protocol>
208 std::strong_ordering operator<=> (const BasicLinkLayerEndpoint<Protocol>& a,
209 const BasicLinkLayerEndpoint<Protocol>& b) noexcept
210 {
211 return a.index () <=> b.index ();
212 }
213
220 template <class Protocol>
221 std::ostream& operator<< (std::ostream& os, const BasicLinkLayerEndpoint<Protocol>& endpoint)
222 {
223 os << endpoint.device ();
224 return os;
225 }
226
227#ifdef JOIN_HAS_XDP
231 template <class Protocol>
232 class BasicXdpEndpoint : public BasicEndpoint<Protocol>
233 {
234 public:
238 BasicXdpEndpoint () noexcept
239 : BasicEndpoint<Protocol> ()
240 {
241 }
242
248 BasicXdpEndpoint (const struct sockaddr* addr, socklen_t len) noexcept
249 : BasicEndpoint<Protocol> (addr, len)
250 {
251 }
252
258 BasicXdpEndpoint (const char* dev, uint32_t queue = 0) noexcept
259 : BasicXdpEndpoint ()
260 {
261 struct sockaddr_xdp* sa = reinterpret_cast<struct sockaddr_xdp*> (&this->_addr);
262 sa->sxdp_ifindex = if_nametoindex (dev);
263 sa->sxdp_queue_id = queue;
264 }
265
271 BasicXdpEndpoint (const std::string& dev, uint32_t queue = 0) noexcept
272 : BasicXdpEndpoint<Protocol> (dev.c_str (), queue)
273 {
274 }
275
280 constexpr Protocol protocol () const noexcept
281 {
282 return Protocol ();
283 }
284
289 constexpr socklen_t length () const noexcept
290 {
291 return sizeof (struct sockaddr_xdp);
292 }
293
298 void device (const std::string& dev) noexcept
299 {
300 reinterpret_cast<struct sockaddr_xdp*> (&this->_addr)->sxdp_ifindex = if_nametoindex (dev.c_str ());
301 }
302
307 std::string device () const
308 {
309 char ifname[IFNAMSIZ];
310 if (if_indextoname (reinterpret_cast<const struct sockaddr_xdp*> (&this->_addr)->sxdp_ifindex, ifname))
311 {
312 return ifname;
313 }
314 return {};
315 }
316
321 uint32_t index () const noexcept
322 {
323 return reinterpret_cast<const struct sockaddr_xdp*> (&this->_addr)->sxdp_ifindex;
324 }
325
330 void queue (uint32_t queue) noexcept
331 {
332 reinterpret_cast<struct sockaddr_xdp*> (&this->_addr)->sxdp_queue_id = queue;
333 }
334
339 uint32_t queue () const noexcept
340 {
341 return reinterpret_cast<const struct sockaddr_xdp*> (&this->_addr)->sxdp_queue_id;
342 }
343 };
344
351 template <class Protocol>
352 bool operator== (const BasicXdpEndpoint<Protocol>& a, const BasicXdpEndpoint<Protocol>& b) noexcept
353 {
354 return a.index () == b.index () && a.queue () == b.queue ();
355 }
356
363 template <class Protocol>
364 std::strong_ordering operator<=> (const BasicXdpEndpoint<Protocol>& a, const BasicXdpEndpoint<Protocol>& b) noexcept
365 {
366 if (auto cmp = a.index () <=> b.index (); cmp != 0)
367 {
368 return cmp;
369 }
370 return a.queue () <=> b.queue ();
371 }
372
379 template <class Protocol>
380 std::ostream& operator<< (std::ostream& os, const BasicXdpEndpoint<Protocol>& endpoint)
381 {
382 os << endpoint.device () << ":" << endpoint.queue ();
383 return os;
384 }
385#endif
386
390 template <class Protocol>
391 class BasicUnixEndpoint : public BasicEndpoint<Protocol>
392 {
393 public:
397 constexpr BasicUnixEndpoint () noexcept
398 : BasicEndpoint<Protocol> ()
399 {
400 }
401
407 BasicUnixEndpoint (const struct sockaddr* addr, socklen_t len) noexcept
409 {
410 }
411
416 BasicUnixEndpoint (const char* dev) noexcept
418 {
419 struct sockaddr_un* sa = reinterpret_cast<struct sockaddr_un*> (&this->_addr);
420 strncpy (sa->sun_path, dev, sizeof (sa->sun_path) - 1);
421 }
422
427 BasicUnixEndpoint (const std::string& dev) noexcept
428 : BasicUnixEndpoint<Protocol> (dev.c_str ())
429 {
430 }
431
436 constexpr Protocol protocol () const noexcept
437 {
438 return Protocol ();
439 }
440
445 constexpr socklen_t length () const noexcept
446 {
447 return sizeof (struct sockaddr_un);
448 }
449
454 void device (const std::string& dev) noexcept
455 {
456 struct sockaddr_un* sa = reinterpret_cast<struct sockaddr_un*> (&this->_addr);
457 strncpy (sa->sun_path, dev.c_str (), sizeof (sa->sun_path) - 1);
458 }
459
464 std::string device () const
465 {
466 return reinterpret_cast<const struct sockaddr_un*> (&this->_addr)->sun_path;
467 }
468 };
469
476 template <class Protocol>
478 {
479 return std::strncmp (reinterpret_cast<const struct sockaddr_un*> (a.addr ())->sun_path,
480 reinterpret_cast<const struct sockaddr_un*> (b.addr ())->sun_path,
481 sizeof (sockaddr_un::sun_path)) == 0;
482 }
483
490 template <class Protocol>
491 std::strong_ordering operator<=> (const BasicUnixEndpoint<Protocol>& a,
492 const BasicUnixEndpoint<Protocol>& b) noexcept
493 {
494 return std::strncmp (reinterpret_cast<const struct sockaddr_un*> (a.addr ())->sun_path,
495 reinterpret_cast<const struct sockaddr_un*> (b.addr ())->sun_path,
496 sizeof (sockaddr_un::sun_path)) <=> 0;
497 }
498
505 template <class Protocol>
506 std::ostream& operator<< (std::ostream& os, const BasicUnixEndpoint<Protocol>& endpoint)
507 {
508 os << endpoint.device ();
509 return os;
510 }
511
515 template <class Protocol>
516 class BasicInternetEndpoint : public BasicEndpoint<Protocol>
517 {
518 public:
522 constexpr BasicInternetEndpoint () noexcept
523 : BasicEndpoint<Protocol> ()
524 {
525 }
526
531 BasicInternetEndpoint (const struct sockaddr* addr, socklen_t len) noexcept
533 {
534 }
535
541 BasicInternetEndpoint (const IpAddress& ip, uint16_t port = 0) noexcept
542 : BasicEndpoint<Protocol> ()
543 {
544 if (ip.family () == AF_INET6)
545 {
546 struct sockaddr_in6* sa = reinterpret_cast<struct sockaddr_in6*> (&this->_addr);
547 sa->sin6_family = AF_INET6;
548 sa->sin6_port = htons (port);
549 memcpy (&sa->sin6_addr, ip.addr (), ip.length ());
550 sa->sin6_scope_id = ip.scope ();
551 }
552 else
553 {
554 struct sockaddr_in* sa = reinterpret_cast<struct sockaddr_in*> (&this->_addr);
555 sa->sin_family = AF_INET;
556 sa->sin_port = htons (port);
557 memcpy (&sa->sin_addr, ip.addr (), ip.length ());
558 }
559 }
560
566 BasicInternetEndpoint (const std::string& ip, uint16_t port = 0)
567 : BasicInternetEndpoint<Protocol> (IpAddress (ip), port)
568 {
569 }
570
576 BasicInternetEndpoint (const char* ip, uint16_t port = 0)
577 : BasicInternetEndpoint<Protocol> (IpAddress (ip), port)
578 {
579 }
580
586 BasicInternetEndpoint (const Protocol& protocol, uint16_t port = 0) noexcept
587 : BasicEndpoint<Protocol> ()
588 {
589 if (protocol.family () == AF_INET6)
590 {
591 struct sockaddr_in6* sa = reinterpret_cast<struct sockaddr_in6*> (&this->_addr);
592 sa->sin6_family = AF_INET6;
593 sa->sin6_port = htons (port);
594 }
595 else
596 {
597 struct sockaddr_in* sa = reinterpret_cast<struct sockaddr_in*> (&this->_addr);
598 sa->sin_family = AF_INET;
599 sa->sin_port = htons (port);
600 }
601 }
602
607 void hostname (const std::string& hostname) noexcept
608 {
610 }
611
616 const std::string& hostname () const noexcept
617 {
618 return _hostname;
619 }
620
625 void ip (const IpAddress& ip) noexcept
626 {
627 if (ip.family () == AF_INET6)
628 {
629 struct sockaddr_in6* sa = reinterpret_cast<struct sockaddr_in6*> (&this->_addr);
630 sa->sin6_family = AF_INET6;
631 memcpy (&sa->sin6_addr, ip.addr (), ip.length ());
632 sa->sin6_scope_id = ip.scope ();
633 }
634 else
635 {
636 struct sockaddr_in* sa = reinterpret_cast<struct sockaddr_in*> (&this->_addr);
637 sa->sin_family = AF_INET;
638 memcpy (&sa->sin_addr, ip.addr (), ip.length ());
639 }
640 }
641
646 IpAddress ip () const noexcept
647 {
648 return *reinterpret_cast<const struct sockaddr*> (&this->_addr);
649 }
650
655 void port (uint16_t p) noexcept
656 {
657 if (this->_addr.ss_family == AF_INET6)
658 {
659 reinterpret_cast<struct sockaddr_in6*> (&this->_addr)->sin6_port = htons (p);
660 }
661 else
662 {
663 reinterpret_cast<struct sockaddr_in*> (&this->_addr)->sin_port = htons (p);
664 }
665 }
666
671 uint16_t port () const noexcept
672 {
673 if (this->_addr.ss_family == AF_INET6)
674 {
675 return ntohs (reinterpret_cast<const struct sockaddr_in6*> (&this->_addr)->sin6_port);
676 }
677 else
678 {
679 return ntohs (reinterpret_cast<const struct sockaddr_in*> (&this->_addr)->sin_port);
680 }
681 }
682
687 Protocol protocol () const noexcept
688 {
689 if (this->_addr.ss_family == AF_INET)
690 {
691 return Protocol::v4 ();
692 }
693 return Protocol::v6 ();
694 }
695
700 socklen_t length () const noexcept
701 {
702 if (this->_addr.ss_family == AF_INET)
703 {
704 return sizeof (struct sockaddr_in);
705 }
706 return sizeof (struct sockaddr_in6);
707 }
708
713 void device (const std::string& dev) noexcept
714 {
715 if (this->_addr.ss_family == AF_INET6)
716 {
717 reinterpret_cast<struct sockaddr_in6*> (&this->_addr)->sin6_scope_id = if_nametoindex (dev.c_str ());
718 }
719 }
720
725 std::string device () const
726 {
727 if (this->_addr.ss_family == AF_INET6)
728 {
729 char ifname[IFNAMSIZ];
730 if (if_indextoname (reinterpret_cast<const struct sockaddr_in6*> (&this->_addr)->sin6_scope_id, ifname))
731 {
732 return ifname;
733 }
734 }
735 return {};
736 }
737
738 protected:
740 std::string _hostname;
741 };
742
749 template <class Protocol>
751 {
752 return a.ip () == b.ip () && a.port () == b.port ();
753 }
754
761 template <class Protocol>
762 std::strong_ordering operator<=> (const BasicInternetEndpoint<Protocol>& a,
763 const BasicInternetEndpoint<Protocol>& b) noexcept
764 {
765 if (auto cmp = a.ip () <=> b.ip (); cmp != 0)
766 {
767 return cmp;
768 }
769 return a.port () <=> b.port ();
770 }
771
778 template <class Protocol>
779 std::ostream& operator<< (std::ostream& os, const BasicInternetEndpoint<Protocol>& endpoint)
780 {
781 if (endpoint.protocol () == Protocol::v6 ())
782 os << "[" << endpoint.ip () << "]";
783 else
784 os << endpoint.ip ();
785 if (endpoint.port ())
786 os << ":" << endpoint.port ();
787 return os;
788 }
789}
790
791#endif
basic endpoint class.
Definition endpoint.hpp:50
constexpr BasicEndpoint() noexcept
default constructor.
Definition endpoint.hpp:55
BasicEndpoint(const struct sockaddr *addr, socklen_t len) noexcept
create instance using socket address.
Definition endpoint.hpp:65
const struct sockaddr * addr() const noexcept
get socket address.
Definition endpoint.hpp:83
struct sockaddr * addr() noexcept
get socket address.
Definition endpoint.hpp:74
struct sockaddr_storage _addr
socket address storage.
Definition endpoint.hpp:90
basic internet endpoint class.
Definition endpoint.hpp:517
void port(uint16_t p) noexcept
set endpoint port number.
Definition endpoint.hpp:655
std::string _hostname
endpoint hostname.
Definition endpoint.hpp:740
const std::string & hostname() const noexcept
get the endpoint hostname.
Definition endpoint.hpp:616
std::string device() const
get endpoint device name.
Definition endpoint.hpp:725
uint16_t port() const noexcept
get endpoint port number.
Definition endpoint.hpp:671
void device(const std::string &dev) noexcept
set endpoint device name.
Definition endpoint.hpp:713
BasicInternetEndpoint(const std::string &ip, uint16_t port=0)
create the endpoint instance.
Definition endpoint.hpp:566
IpAddress ip() const noexcept
get endpoint IP address.
Definition endpoint.hpp:646
BasicInternetEndpoint(const Protocol &protocol, uint16_t port=0) noexcept
create the endpoint instance.
Definition endpoint.hpp:586
BasicInternetEndpoint(const IpAddress &ip, uint16_t port=0) noexcept
create the endpoint instance.
Definition endpoint.hpp:541
Protocol protocol() const noexcept
get endpoint protocol.
Definition endpoint.hpp:687
BasicInternetEndpoint(const struct sockaddr *addr, socklen_t len) noexcept
create the endpoint instance.
Definition endpoint.hpp:531
void hostname(const std::string &hostname) noexcept
set endpoint hostname.
Definition endpoint.hpp:607
socklen_t length() const noexcept
get socket address length.
Definition endpoint.hpp:700
constexpr BasicInternetEndpoint() noexcept
default constructor.
Definition endpoint.hpp:522
BasicInternetEndpoint(const char *ip, uint16_t port=0)
create the endpoint instance.
Definition endpoint.hpp:576
void ip(const IpAddress &ip) noexcept
set endpoint IP address.
Definition endpoint.hpp:625
basic link layer endpoint class.
Definition endpoint.hpp:98
void device(const std::string &dev) noexcept
set endpoint device name.
Definition endpoint.hpp:160
constexpr Protocol protocol() const noexcept
get endpoint protocol.
Definition endpoint.hpp:142
BasicLinkLayerEndpoint(const struct sockaddr *addr, socklen_t len) noexcept
create instance using socket address.
Definition endpoint.hpp:114
constexpr socklen_t length() const noexcept
get socket address length.
Definition endpoint.hpp:151
BasicLinkLayerEndpoint() noexcept
default constructor.
Definition endpoint.hpp:103
std::string device() const
get endpoint device name.
Definition endpoint.hpp:169
int index() const noexcept
get endpoint interface index.
Definition endpoint.hpp:183
BasicLinkLayerEndpoint(const char *dev) noexcept
create instance using device name.
Definition endpoint.hpp:123
BasicLinkLayerEndpoint(const std::string &dev) noexcept
create instance using device name.
Definition endpoint.hpp:133
basic unix endpoint class.
Definition endpoint.hpp:392
BasicUnixEndpoint(const char *dev) noexcept
create instance using device name.
Definition endpoint.hpp:416
BasicUnixEndpoint(const struct sockaddr *addr, socklen_t len) noexcept
create instance using socket address.
Definition endpoint.hpp:407
std::string device() const
get endpoint device name.
Definition endpoint.hpp:464
constexpr socklen_t length() const noexcept
get socket address length.
Definition endpoint.hpp:445
constexpr BasicUnixEndpoint() noexcept
default constructor.
Definition endpoint.hpp:397
BasicUnixEndpoint(const std::string &dev) noexcept
create instance using device name.
Definition endpoint.hpp:427
constexpr Protocol protocol() const noexcept
get endpoint protocol.
Definition endpoint.hpp:436
void device(const std::string &dev) noexcept
set endpoint device name.
Definition endpoint.hpp:454
IPv6, IPv4 address class.
Definition ip_address.hpp:52
uint32_t scope() const
get the scope identifier of the address.
Definition ip_address.cpp:1277
int family() const
get address family.
Definition ip_address.cpp:1250
socklen_t length() const
get the size in byte of the internal address structure.
Definition ip_address.cpp:1268
const void * addr() const
get the internal address structure.
Definition ip_address.cpp:1259
Definition acceptor.hpp:32
bool operator==(const BasicLinkLayerEndpoint< Protocol > &a, const BasicLinkLayerEndpoint< Protocol > &b) noexcept
compare if endpoints are equal.
Definition endpoint.hpp:196
std::ostream & operator<<(std::ostream &os, const BasicLinkLayerEndpoint< Protocol > &endpoint)
push endpoint representation into a stream.
Definition endpoint.hpp:221
std::strong_ordering operator<=>(const BasicLinkLayerEndpoint< Protocol > &a, const BasicLinkLayerEndpoint< Protocol > &b) noexcept
three-way compare endpoints.
Definition endpoint.hpp:208