LibSWOC++ 1.5.14
Solid Wall of C++
Loading...
Searching...
No Matches
IPSrv.h
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0
2// Copyright Network Geographics 2014
6
7#pragma once
8
9#include <netinet/in.h>
10#include <sys/socket.h>
11
12#include "swoc/swoc_version.h"
13#include "swoc/IPAddr.h"
14
15namespace swoc { inline namespace SWOC_VERSION_NS {
16
17class IPSrv;
18
20class IP4Srv {
21private:
22 using self_type = IP4Srv;
23
24public:
25 constexpr IP4Srv() = default;
26
32 explicit IP4Srv(IP4Addr addr, in_port_t port = 0);
33
40 explicit IP4Srv(IPSrv const &that);
41
46 IP4Srv(sockaddr_in const *s) : _addr(s), _port(ntohs(s->sin_port)) {}
47
54 explicit IP4Srv(swoc::TextView text);
55
57 constexpr operator IP4Addr const &() const;
58
60 constexpr IP4Addr const &addr() const;
61
63 in_port_t host_order_port() const;
64
66 in_port_t network_order_port() const;
67
71 static constexpr sa_family_t family();
72
73 bool operator==(self_type that) const;
74 bool operator!=(self_type that) const;
75
76 bool operator<(self_type that) const;
77 bool operator<=(self_type const &that) const;
78 bool operator>(self_type const &that) const;
79 bool operator>=(self_type const &that) const;
80
86 bool load(swoc::TextView text);
87
93 self_type &assign(IP4Addr const &addr);
94
100 self_type &assign(in_port_t port);
101
108 self_type &assign(IP4Addr const &addr, in_port_t port);
109
115 self_type &assign(sockaddr_in const *s);
116
117protected:
119 in_port_t _port = 0;
120};
121
123class IP6Srv {
124private:
125 using self_type = IP6Srv;
126
127public:
128 IP6Srv() = default;
129
135 explicit IP6Srv(IP6Addr addr, in_port_t port = 0);
136
143 explicit IP6Srv(IPSrv const &that);
144
149 explicit IP6Srv(sockaddr_in6 const *s);
150
157 explicit IP6Srv(swoc::TextView text);
158
164 bool load(swoc::TextView text);
165
167 constexpr operator IP6Addr const &() const;
168
170 constexpr IP6Addr const &addr() const;
172 in_port_t host_order_port() const;
174 in_port_t network_order_port() const;
175
179 static constexpr sa_family_t family();
180
181 bool operator==(self_type that) const;
182 bool operator!=(self_type that) const;
183
184 bool operator<(self_type that) const;
185 bool operator<=(self_type const &that) const;
186 bool operator>(self_type const &that) const;
187 bool operator>=(self_type const &that) const;
188
194 self_type &assign(IP6Addr const &addr);
195
201 self_type &assign(in_port_t port);
202
209 self_type &assign(IP6Addr const &addr, in_port_t port);
210
216 self_type &assign(sockaddr_in6 const *s);
217
218protected:
220 in_port_t _port = 0;
221};
222
224class IPSrv {
225private:
226 using self_type = IPSrv;
227
228public:
229 IPSrv() = default;
230 explicit IPSrv(IP4Addr addr, in_port_t port = 0) : _srv(IP4Srv{addr, port}), _family(addr.family()) {}
232 explicit IPSrv(IP6Addr addr, in_port_t port = 0) : _srv(IP6Srv{addr, port}), _family(addr.family()) {}
234 explicit IPSrv(IPAddr addr, in_port_t port = 0);
236 explicit IPSrv(sockaddr const *sa);
238 explicit IPSrv(sockaddr_in const *s);
240 explicit IPSrv(sockaddr_in6 const *s);
242 explicit IPSrv(IPEndpoint const &ep);
243
250 explicit IPSrv(swoc::TextView text);
251
257 bool load(swoc::TextView text);
258
260 IPAddr addr() const;
262 constexpr in_port_t host_order_port() const;
264 in_port_t network_order_port() const;
266 constexpr sa_family_t family() const;
267
269 bool is_valid() const;
271 bool is_ip4() const;
273 bool is_ip6() const;
274
276 IP4Srv const & ip4() const;
278 IP6Srv const & ip6() const;
279
285 self_type &assign(IP4Addr const &addr);
286
292 self_type &assign(IP6Addr const &addr);
293
302 self_type &assign(IPAddr const &addr);
303
309 self_type &assign(in_port_t port);
310
317 self_type &assign(IP4Addr const &addr, in_port_t port);
318
325 self_type &assign(IP6Addr const &addr, in_port_t port);
326
335 self_type &assign(sockaddr const *sa);
336
342 self_type &assign(sockaddr_in const *s);
343
349 self_type &assign(sockaddr_in6 const *s);
350
360 self_type &assign(IPAddr const &addr, in_port_t port);
361
363 self_type &operator=(self_type const &that) = default;
365 self_type &operator=(IP4Srv const &that);
367 self_type &operator=(IP6Srv const &that);
369 self_type & operator=(sockaddr const *sa);
371 self_type & operator=(sockaddr_in const *s);
373 self_type & operator=(sockaddr_in6 const *s);
374
375protected:
377 union data {
378 std::monostate _nil;
381
382 data(){}; // enable default construction.
383
385 explicit data(IP4Srv const &srv) : _ip4(srv) {}
386 explicit data(sockaddr_in const *s) : _ip4(s) {}
387
389 explicit data(IP6Srv const &srv) : _ip6(srv) {}
390 explicit data(sockaddr_in6 const *s) : _ip6(s) {}
391
393 IPAddr addr(sa_family_t f) const;
394
396 constexpr in_port_t port(sa_family_t f) const;
397 } _srv;
398
399 sa_family_t _family = AF_UNSPEC;
400};
401
402// --- Implementation
403
404inline IP4Srv::IP4Srv(IP4Addr addr, in_port_t port) : _addr(addr), _port(port) {}
405inline IP4Srv::IP4Srv(IPSrv const &that) : IP4Srv(that.is_ip4() ? that.ip4() : self_type{}) {}
406
407inline auto
408IP4Srv::assign(IP4Addr const &addr) -> self_type & {
409 _addr = addr;
410 return *this;
411}
412inline auto
413IP4Srv::assign(in_port_t port) -> self_type & {
414 _port = port;
415 return *this;
416}
417inline auto
418IP4Srv::assign(IP4Addr const &addr, in_port_t port) -> self_type & {
419 _addr = addr;
420 _port = port;
421 return *this;
422}
423inline auto
424IP4Srv::assign(sockaddr_in const *s) -> self_type & {
425 _addr = s;
426 _port = ntohs(s->sin_port);
427 return *this;
428}
429inline constexpr IP4Srv::operator IP4Addr const &() const {
430 return _addr;
431}
432inline constexpr IP4Addr const &
434 return _addr;
435}
436inline in_port_t
438 return _port;
439}
440inline in_port_t
442 return htons(_port);
443}
444inline constexpr sa_family_t
446 return AF_INET;
447}
448
449inline bool
450IP4Srv::operator==(IP4Srv::self_type that) const {
451 return _addr == that._addr && _port == that._port;
452}
453inline bool
454IP4Srv::operator!=(IP4Srv::self_type that) const {
455 return _addr != that._addr || _port != that._port;
456}
457inline bool
458IP4Srv::operator<(IP4Srv::self_type that) const {
459 return _addr < that._addr || (_addr == that._addr && _port < that._port);
460}
461inline bool
462IP4Srv::operator<=(IP4Srv::self_type const &that) const {
463 return _addr < that._addr || (_addr == that._addr && _port <= that._port);
464}
465inline bool
466IP4Srv::operator>(IP4Srv::self_type const &that) const {
467 return that < *this;
468}
469inline bool
470IP4Srv::operator>=(IP4Srv::self_type const &that) const {
471 return that <= *this;
472}
473
475
476inline IP6Srv::IP6Srv(IP6Addr addr, in_port_t port) : _addr(addr), _port(port) {}
477inline IP6Srv::IP6Srv(IPSrv const &that) : IP6Srv(that.is_ip6() ? that.ip6() : self_type{}) {}
478inline IP6Srv::IP6Srv(const sockaddr_in6 *s) : _addr(s->sin6_addr), _port(ntohs(s->sin6_port)) {}
479
480inline constexpr IP6Srv::operator IP6Addr const &() const {
481 return _addr;
482}
483inline constexpr IP6Addr const &
485 return _addr;
486}
487inline in_port_t
489 return _port;
490}
491inline in_port_t
493 return htons(_port);
494}
495inline constexpr sa_family_t
497 return AF_INET6;
498}
499
500inline bool
501IP6Srv::operator==(IP6Srv::self_type that) const {
502 return _addr == that._addr && _port == that._port;
503}
504inline bool
505IP6Srv::operator!=(IP6Srv::self_type that) const {
506 return _port != that._port || _addr != that._addr;
507}
508inline bool
509IP6Srv::operator<(IP6Srv::self_type that) const {
510 return _addr < that._addr || (_addr == that._addr && _port < that._port);
511}
512inline bool
513IP6Srv::operator<=(IP6Srv::self_type const &that) const {
514 return _addr < that._addr || (_addr == that._addr && _port <= that._port);
515}
516inline bool
517IP6Srv::operator>(IP6Srv::self_type const &that) const {
518 return that < *this;
519}
520inline bool
521IP6Srv::operator>=(IP6Srv::self_type const &that) const {
522 return that <= *this;
523}
524
525inline auto
526IP6Srv::assign(in_port_t port) -> self_type & {
527 _port = port;
528 return *this;
529}
530
531inline auto
532IP6Srv::assign(IP6Addr const &addr) -> self_type & {
533 _addr = addr;
534 return *this;
535}
536
537inline auto
538IP6Srv::assign(IP6Addr const &addr, in_port_t port) -> self_type & {
539 _addr = addr;
540 _port = port;
541 return *this;
542}
543
544inline auto
545IP6Srv::assign(sockaddr_in6 const *s) -> self_type & {
546 _addr = s;
547 _port = ntohs(s->sin6_port);
548 return *this;
549}
550
551// --- Generic SRV
552
553inline IPSrv::IPSrv(const sockaddr_in *s) : _srv(s), _family(AF_INET) {}
554inline IPSrv::IPSrv(const sockaddr_in6 *s) : _srv(s), _family(AF_INET6) {}
555inline IPSrv::IPSrv(const sockaddr *sa) {
556 this->assign(sa);
557}
558
559inline IPAddr
560IPSrv::addr() const {
561 return _srv.addr(_family);
562}
563
564inline constexpr sa_family_t
566 return _family;
567}
568
569inline bool IPSrv::is_valid() const { return AF_INET == _family || AF_INET6 == _family; }
570
571inline bool
573 return _family == AF_INET;
574}
575
576inline bool
578 return _family == AF_INET6;
579}
580
581inline IP4Srv const& IPSrv::ip4() const {
582 return _srv._ip4;
583}
584
585inline IP6Srv const& IPSrv::ip6() const {
586 return _srv._ip6;
587}
588
589inline constexpr in_port_t
591 return _srv.port(_family);
592}
593
594inline in_port_t
596 return ntohs(_srv.port(_family));
597}
598
599inline auto
600IPSrv::assign(IP6Addr const &addr) -> self_type & {
601 _srv._ip6.assign(addr, this->host_order_port());
602 _family = addr.family();
603 return *this;
604}
605
606inline auto
607IPSrv::assign(IP4Addr const &addr, in_port_t port) -> self_type & {
608 _srv._ip4.assign(addr, port);
609 _family = addr.family();
610 return *this;
611}
612
613inline auto
614IPSrv::assign(IP6Addr const &addr, in_port_t port) -> self_type & {
615 _srv._ip6.assign(addr, port);
616 _family = addr.family();
617 return *this;
618}
619
620inline auto
621IPSrv::assign(IP4Addr const &addr) -> self_type & {
622 _srv._ip4.assign(addr, this->host_order_port());
623 _family = addr.family();
624 return *this;
625}
626
627inline auto
628IPSrv::assign(in_port_t port) -> self_type & {
629 if (this->is_ip4()) {
630 _srv._ip4.assign(port);
631 } else if (this->is_ip6()) {
632 _srv._ip6.assign(port);
633 }
634 return *this;
635}
636
637inline auto
638IPSrv::assign(IPAddr const &addr) -> self_type & {
639 if (addr.is_ip4()) {
640 this->assign(addr.ip4());
641 } else if (addr.is_ip6()) {
642 this->assign(addr.ip6());
643 }
644 return *this;
645}
646
647inline auto
648IPSrv::assign(IPAddr const &addr, in_port_t port) -> self_type & {
649 if (addr.is_ip4()) {
650 this->assign(addr.ip4(), port);
651 _family = addr.family();
652 } else if (addr.is_ip6()) {
653 this->assign(addr.ip6(), port);
654 _family = addr.family();
655 }
656 return *this;
657}
658
659inline auto
660IPSrv::operator=(IP4Srv const &that) -> self_type & {
661 _family = that.family();
662 _srv._ip4 = that;
663 return *this;
664}
665
666inline auto
667IPSrv::operator=(IP6Srv const &that) -> self_type & {
668 _family = that.family();
669 _srv._ip6 = that;
670 return *this;
671}
672
673inline auto
674IPSrv::assign(sockaddr_in const *s) -> self_type & {
675 _family = _srv._ip4.family();
676 _srv._ip4.assign(s);
677 return *this;
678}
679
680inline auto
681IPSrv::assign(sockaddr_in6 const *s) -> self_type & {
682 _family = _srv._ip6.family();
683 _srv._ip6.assign(s);
684 return *this;
685}
686
687inline IPSrv::self_type & IPSrv::operator=(sockaddr const *sa) {
688 return this->assign(sa);
689}
690
691inline IPSrv::self_type & IPSrv::operator=(sockaddr_in const *s) {
692 return this->assign(s);
693}
694
695inline IPSrv::self_type & IPSrv::operator=(sockaddr_in6 const *s) {
696 return this->assign(s);
697}
698
699inline IPAddr
700IPSrv::data::addr(sa_family_t f) const {
701 return (f == AF_INET) ? _ip4.addr() : (f == AF_INET6) ? _ip6.addr() : IPAddr::INVALID;
702}
703
704constexpr inline in_port_t
705IPSrv::data::port(sa_family_t f) const {
706 return (f == AF_INET) ? _ip4.host_order_port() : (f == AF_INET6) ? _ip6.host_order_port() : 0;
707}
708
709// --- Independent comparisons.
710
711inline bool
712operator==(IPSrv const &lhs, IP4Srv const &rhs) {
713 return lhs.is_ip4() && lhs.ip4() == rhs;
714}
715
716inline bool
717operator==(IP4Srv const &lhs, IPSrv const &rhs) {
718 return rhs.is_ip4() && rhs.ip4() == lhs;
719}
720
721inline bool
722operator!=(IPSrv const &lhs, IP4Srv const &rhs) {
723 return !lhs.is_ip4() || lhs.ip4() != rhs;
724}
725
726inline bool
727operator!=(IP4Srv const &lhs, IPSrv const &rhs) {
728 return !rhs.is_ip4() || rhs.ip4() != lhs;
729}
730
731inline bool
732operator<(IPSrv const &lhs, IP4Srv const &rhs) {
733 return lhs.is_ip4() && lhs.ip4() < rhs;
734}
735
736inline bool
737operator<(IP4Srv const &lhs, IPSrv const &rhs) {
738 return rhs.is_ip4() && lhs < rhs.ip4();
739}
740
741inline bool
742operator<=(IPSrv const &lhs, IP4Srv const &rhs) {
743 return lhs.is_ip4() && lhs.ip4() <= rhs;
744}
745
746inline bool
747operator<=(IP4Srv const &lhs, IPSrv const &rhs) {
748 return rhs.is_ip4() && lhs <= rhs.ip4();
749}
750
751inline bool
752operator>(IPSrv const &lhs, IP4Srv const &rhs) {
753 return lhs.is_ip4() && lhs.ip4() > rhs;
754}
755
756inline bool
757operator>(IP4Srv const &lhs, IPSrv const &rhs) {
758 return rhs.is_ip4() && lhs > rhs.ip4();
759}
760
761inline bool
762operator>=(IPSrv const &lhs, IP4Srv const &rhs) {
763 return lhs.is_ip4() && lhs.ip4() >= rhs;
764}
765
766inline bool
767operator>=(IP4Srv const &lhs, IPSrv const &rhs) {
768 return rhs.is_ip4() && lhs >= rhs.ip4();
769}
770
771inline bool
772operator==(IPSrv const &lhs, IP6Srv const &rhs) {
773 return lhs.is_ip6() && lhs.ip6() == rhs;
774}
775
776inline bool
777operator==(IP6Srv const &lhs, IPSrv const &rhs) {
778 return rhs.is_ip6() && rhs.ip6() == lhs;
779}
780
781inline bool
782operator!=(IPSrv const &lhs, IP6Srv const &rhs) {
783 return !lhs.is_ip6() || lhs.ip6() != rhs;
784}
785
786inline bool
787operator!=(IP6Srv const &lhs, IPSrv const &rhs) {
788 return !rhs.is_ip6() || rhs.ip6() != lhs;
789}
790
791inline bool
792operator<(IPSrv const &lhs, IP6Srv const &rhs) {
793 return lhs.is_ip6() && lhs.ip6() < rhs;
794}
795
796inline bool
797operator<(IP6Srv const &lhs, IPSrv const &rhs) {
798 return rhs.is_ip6() && lhs < rhs.ip6();
799}
800
801inline bool
802operator<=(IPSrv const &lhs, IP6Srv const &rhs) {
803 return lhs.is_ip6() && lhs.ip6() <= rhs;
804}
805
806inline bool
807operator<=(IP6Srv const &lhs, IPSrv const &rhs) {
808 return rhs.is_ip6() && lhs <= rhs.ip6();
809}
810
811inline bool
812operator>(IPSrv const &lhs, IP6Srv const &rhs) {
813 return lhs.is_ip6() && lhs.ip6() > rhs;
814}
815
816inline bool
817operator>(IP6Srv const &lhs, IPSrv const &rhs) {
818 return rhs.is_ip6() && lhs > rhs.ip6();
819}
820
821inline bool
822operator>=(IPSrv const &lhs, IP6Srv const &rhs) {
823 return lhs.is_ip6() && lhs.ip6() >= rhs;
824}
825
826inline bool
827operator>=(IP6Srv const &lhs, IPSrv const &rhs) {
828 return rhs.is_ip6() && lhs >= rhs.ip6();
829}
830
831// --- Cross address equality
832
833inline bool
834operator==(IPSrv const &lhs, IP4Addr const &rhs) {
835 return lhs.is_ip4() && lhs.ip4() == rhs;
836}
837
838inline bool
839operator==(IP4Addr const &lhs, IPSrv const &rhs) {
840 return rhs.is_ip4() && lhs == rhs.ip4();
841}
842
843inline bool
844operator!=(IPSrv const &lhs, IP4Addr const &rhs) {
845 return !lhs.is_ip4() || lhs.ip4() != rhs;
846}
847
848inline bool
849operator!=(IP4Addr const &lhs, IPSrv const &rhs) {
850 return !rhs.is_ip4() || lhs != rhs.ip4();
851}
852
853inline bool
854operator==(IPSrv const &lhs, IP6Addr const &rhs) {
855 return lhs.is_ip6() && lhs.ip6() == rhs;
856}
857
858inline bool
859operator==(IP6Addr const &lhs, IPSrv const &rhs) {
860 return rhs.is_ip6() && lhs == rhs.ip6();
861}
862
863inline bool
864operator!=(IPSrv const &lhs, IP6Addr const &rhs) {
865 return !lhs.is_ip6() || lhs.ip6() != rhs;
866}
867
868inline bool
869operator!=(IP6Addr const &lhs, IPSrv const &rhs) {
870 return !rhs.is_ip6() || lhs != rhs.ip6();
871}
872
873}} // namespace swoc::SWOC_VERSION_NS
in_addr_t _addr
Address in host order.
Definition IPAddr.h:192
An IPv4 address and host_order_port, modeled on an SRV type for DNS.
Definition IPSrv.h:20
constexpr IP4Addr const & addr() const
Definition IPSrv.h:433
in_port_t network_order_port() const
Definition IPSrv.h:441
in_port_t _port
Port [host order].
Definition IPSrv.h:119
IP4Addr _addr
Address.
Definition IPSrv.h:118
constexpr IP4Srv()=default
Default constructor.
in_port_t host_order_port() const
Definition IPSrv.h:437
self_type & assign(IP4Addr const &addr)
Definition IPSrv.h:408
IP4Srv(sockaddr_in const *s)
Definition IPSrv.h:46
static constexpr sa_family_t family()
Definition IPSrv.h:445
An IPv6 address and host_order_port, modeled on an SRV type for DNS.
Definition IPSrv.h:123
self_type & assign(IP6Addr const &addr)
Definition IPSrv.h:532
bool load(swoc::TextView text)
Definition swoc_ip.cc:769
IP6Srv()=default
Default constructor.
in_port_t host_order_port() const
Definition IPSrv.h:488
static constexpr sa_family_t family()
Definition IPSrv.h:496
IP6Addr _addr
Address.
Definition IPSrv.h:219
in_port_t _port
Port [host order].
Definition IPSrv.h:220
in_port_t network_order_port() const
Definition IPSrv.h:492
constexpr IP6Addr const & addr() const
Definition IPSrv.h:484
An IP address and host_order_port, modeled on an SRV type for DNS.
Definition IPSrv.h:224
bool is_ip4() const
Definition IPSrv.h:572
in_port_t network_order_port() const
Definition IPSrv.h:595
bool is_ip6() const
Definition IPSrv.h:577
IP4Srv const & ip4() const
Definition IPSrv.h:581
bool is_valid() const
Definition IPSrv.h:569
IP6Srv const & ip6() const
Definition IPSrv.h:585
sa_family_t _family
Protocol family.
Definition IPSrv.h:399
constexpr in_port_t host_order_port() const
Definition IPSrv.h:590
IPSrv(IP6Addr addr, in_port_t port=0)
Construct for IPv6 address and port.
Definition IPSrv.h:232
IPAddr addr() const
Definition IPSrv.h:560
IPSrv()=default
Default constructor.
constexpr sa_family_t family() const
Definition IPSrv.h:565
self_type & operator=(self_type const &that)=default
Copy assignment.
self_type & assign(IP4Addr const &addr)
Definition IPSrv.h:621
For template deduction guides.
Definition ArenaWriter.cc:9
bool operator>(IP4Addr const &lhs, IP4Addr const &rhs)
Definition IPAddr.h:863
bool operator<=(IP4Addr const &lhs, IP4Addr const &rhs)
Definition IPAddr.h:857
bool operator>=(IP4Addr const &lhs, IP4Addr const &rhs)
Definition IPAddr.h:869
bool operator==(IPAddr const &lhs, sockaddr const *sa)
Equality.
Definition swoc_ip.cc:650
bool operator!=(IP4Addr const &lhs, IP4Addr const &rhs)
Definition IPAddr.h:845
bool operator<(IP4Addr const &lhs, IP4Addr const &rhs)
Definition IPAddr.h:851
Family specialized data.
Definition IPSrv.h:377
constexpr in_port_t port(sa_family_t f) const
Definition IPSrv.h:705
IPAddr addr(sa_family_t f) const
Definition IPSrv.h:700
data(IP6Srv const &srv)
Construct from IPv6 data.
Definition IPSrv.h:389
data(IP4Srv const &srv)
Construct from IPv4 data.
Definition IPSrv.h:385
std::monostate _nil
Nil / invalid state.
Definition IPSrv.h:378
IP4Srv _ip4
IPv4 address (host)
Definition IPSrv.h:379
IP6Srv _ip6
IPv6 address (host)
Definition IPSrv.h:380