Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
SocketAddress.h
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#ifndef _Stroika_Foundation_IO_Network_SocketAddress_h_
5#define _Stroika_Foundation_IO_Network_SocketAddress_h_ 1
6
7#include "Stroika/Foundation/StroikaPreComp.h"
8
9#if qStroika_Foundation_Common_Platform_POSIX
10#include <sys/socket.h>
11#elif qStroika_Foundation_Common_Platform_Windows
12#include <WinSock2.h>
13
14#include <WS2tcpip.h>
15#endif
16
19
20/**
21 * \note Code-Status: <a href="Code-Status.md#Beta">Beta</a>
22 */
23
25
26 /**
27 * Friendly C++ wrapper on Berkley socket sockaddr structure (so sockaddr, sockaddr_in, sockaddr_storage, etc).
28 * A SocketAddress is the combination of an @see InternetAddress with a port#.
29 *
30 * \note we support empty/clear () APIs, because the underlying model supports UNSPEC (AF_UNSPEC).
31 *
32 * TODO:
33 * @todo Optimize storage for case when sockaddr_storage is too large (128 bytes vs 28 for ipv6); use InlineBuffer<byte> with default
34 * buffer size of IPV4 (16)? maybe
35 */
37 public:
38 /**
39 * \brief Socket address family - also sometimes referred to as domain (argument to ::socket calls it domain)
40 */
41 enum class FamilyType : u_short {
42 UNSPEC = AF_UNSPEC,
43 UNIX = AF_UNIX,
44 INET = AF_INET,
45 INET6 = AF_INET6,
46 };
47 using FamilyType::INET;
48 using FamilyType::INET6;
49
50 public:
51 /**
52 * This value can only be used in the SocketAddress constructor to mean for the OS to select a random (available) port.
53 */
54 static constexpr PortType kAnyPort{0};
55
56 public:
57 /**
58 * any raw sock_addr, sockaddr_in, or sockaddr_storage arguments must already be in network order.
59 *
60 * The overload with InternetAddress and portNumber, take care of this automatically, with the portNumber
61 * in host-byte-order.
62 */
63 constexpr SocketAddress () noexcept;
64 constexpr SocketAddress (const sockaddr& iaddr) noexcept;
65 constexpr SocketAddress (const sockaddr_in& iaddr) noexcept;
66 constexpr SocketAddress (const sockaddr_in6& iaddr) noexcept;
67 constexpr SocketAddress (const sockaddr_storage& iaddr) noexcept;
68#if qStroika_Foundation_Common_Platform_Windows
69 SocketAddress (const SOCKET_ADDRESS& sockaddr);
70#endif
71 explicit SocketAddress (const InternetAddress& iaddr, PortType portNumber = kAnyPort);
72
73 public:
74 /**
75 * Check if unspecified.
76 */
77 nonvirtual bool empty () const;
78
79 public:
80 /**
81 * Make it empty().
82 */
83 nonvirtual void clear ();
84
85 public:
86 /**
87 * Returns the address family (POSIX defined - but without any defined type): af_family field of sockaddr.
88 */
89 nonvirtual FamilyType GetAddressFamily () const;
90
91 public:
92 /**
93 * Return the size in bytes for this socket address' address family. This is well defined for
94 * V4 and V6, sizeof (sockaddr_storage) otherwise.
95 */
96 nonvirtual size_t GetRequiredSize () const;
97
98 public:
99 /**
100 * SocketAddresses can refer to InternetAddresses, but they can also refer to local structures like
101 * named pipes, special files, etc. This is true if IPv4 or IPv6.
102 */
103 nonvirtual bool IsInternetAddress () const;
104
105 public:
106 /**
107 * \pre IsInternetAddress()
108 */
109 nonvirtual InternetAddress GetInternetAddress () const;
110
111 public:
112 /**
113 * \pre IsInternetAddress()
114 */
115 nonvirtual PortType GetPort () const;
116
117 public:
118 /**
119 * Only specifically specialized variants are supported. As<T> supported variants include:
120 * As<sockaddr> ();
121 * As<sockaddr_storage> ()
122 * As<sockaddr_in> (); // requires GetAddressFamily() == AF_INET
123 * As<sockaddr_in6> (); // requires GetAddressFamily() == AF_INET6
124 *
125 * \note As<sockaddr_storage> () is nearly always best!
126 */
127 template <typename T>
128 nonvirtual T As () const;
129
130 public:
131 /**
132 * @see Characters::ToString ()
133 */
134 nonvirtual String ToString () const;
135
136 private:
137 union {
138 sockaddr_storage fSocketAddressStorage_;
139 sockaddr fSocketAddress_;
140 sockaddr_in fSocketAddress_V4_;
141 sockaddr_in6 fSocketAddress_V6_;
142 };
143 };
144
145 // Supported specializations
146 template <>
147 sockaddr SocketAddress::As<sockaddr> () const;
148 template <>
149 sockaddr_storage SocketAddress::As<sockaddr_storage> () const;
150 template <>
151 sockaddr_in SocketAddress::As<sockaddr_in> () const;
152 template <>
153 sockaddr_in6 SocketAddress::As<sockaddr_in6> () const;
154
155 /**
156 * Take the argument list of internet addresses and convert them to an equivalent list of SocketAddresses - with the given port.
157 *
158 * \par Example Usage
159 * \code
160 * Listener l{SocketAddresses (InternetAddresses_Any (), usingPortNumber), options.fBindFlags.Value (), ....
161 * \endcode
162 */
164
165 /**
166 * \brief return V4::kLocalhost or V6::kLocalhost depending on argument address family
167 */
168 constexpr InternetAddress LocalHost (SocketAddress::FamilyType fm);
169
170}
171
172/*
173 ********************************************************************************
174 ***************************** Implementation Details ***************************
175 ********************************************************************************
176 */
177#include "SocketAddress.inl"
178
179#endif /*_Stroika_Foundation_IO_Network_SocketAddress_h_*/
String is like std::u32string, except it is much easier to use, often much more space efficient,...
Definition String.h:201
nonvirtual InternetAddress GetInternetAddress() const
FamilyType
Socket address family - also sometimes referred to as domain (argument to ::socket calls it domain)
nonvirtual FamilyType GetAddressFamily() const
Iterable<T> is a base class for containers which easily produce an Iterator<T> to traverse them.
Definition Iterable.h:237
Traversal::Iterable< SocketAddress > SocketAddresses(const Traversal::Iterable< InternetAddress > &internetAddresses, PortType portNumber)
constexpr InternetAddress LocalHost(SocketAddress::FamilyType fm)
return V4::kLocalhost or V6::kLocalhost depending on argument address family