39OPENDHT_PUBLIC
void print_addr(std::ostream& os,
const sockaddr* sa, socklen_t slen);
40OPENDHT_PUBLIC std::string print_addr(
const sockaddr* sa, socklen_t slen);
41OPENDHT_PUBLIC std::string print_addr(
const sockaddr_storage& ss, socklen_t sslen);
46class OPENDHT_PUBLIC SockAddr
50 SockAddr(
const SockAddr& o) { set(o.
get(), o.
getLength()); }
51 SockAddr(SockAddr&& o) noexcept
52 : addr(std::move(o.addr))
63 if (length >
static_cast<socklen_t
>(
sizeof(sockaddr_storage)))
64 throw std::runtime_error(
"Socket address length is too large");
71 if (sa->sa_family == AF_INET)
72 len =
sizeof(sockaddr_in);
73 else if (sa->sa_family == AF_INET6)
74 len =
sizeof(sockaddr_in6);
76 throw std::runtime_error(
"Unknown address family");
84 SockAddr(
const sockaddr_storage& ss, socklen_t len)
85 : SockAddr((const sockaddr*) &ss, len)
88 static std::vector<SockAddr> resolve(
const std::string& host,
const std::string& service = {});
90 bool operator<(
const SockAddr& o)
const
94 return std::memcmp((
const uint8_t*) get(), (
const uint8_t*) o.get(), len) < 0;
97 bool equals(
const SockAddr& o)
const
99 return len == o.len && std::memcmp((
const uint8_t*) get(), (
const uint8_t*) o.get(), len) == 0;
101 bool operator==(
const SockAddr& o)
const {
return equals(o); }
102 bool operator!=(
const SockAddr& o)
const {
return !equals(o); }
104 SockAddr& operator=(
const SockAddr& o)
106 set(o.get(), o.getLength());
109 SockAddr& operator=(SockAddr&& o)
113 addr = std::move(o.addr);
117 std::string toString()
const {
return print_addr(get(), getLength()); }
122 sa_family_t
getFamily()
const {
return len ? addr->sa_family : AF_UNSPEC; }
131 socklen_t new_length;
134 new_length =
sizeof(sockaddr_in);
137 new_length =
sizeof(sockaddr_in6);
142 if (new_length != len) {
145 addr.reset((sockaddr*) ::calloc(len, 1));
150 addr->sa_family = af;
161 getIPv4().sin_addr.s_addr = htonl(INADDR_ANY);
164 getIPv6().sin6_addr = in6addr_any;
177 getIPv4().sin_addr.s_addr = htonl(INADDR_LOOPBACK);
180 getIPv6().sin6_addr = in6addr_loopback;
193 return ntohs(getIPv4().sin_port);
195 return ntohs(getIPv6().sin6_port);
208 getIPv4().sin_port = htons(p);
211 getIPv6().sin6_port = htons(p);
231 explicit operator bool() const noexcept {
return len; }
237 const sockaddr*
get()
const {
return addr.get(); }
243 sockaddr*
get() {
return addr.get(); }
245 inline const sockaddr_in& getIPv4()
const {
return *
reinterpret_cast<const sockaddr_in*
>(get()); }
246 inline const sockaddr_in6& getIPv6()
const {
return *
reinterpret_cast<const sockaddr_in6*
>(get()); }
247 inline sockaddr_in& getIPv4() {
return *
reinterpret_cast<sockaddr_in*
>(get()); }
248 inline sockaddr_in6& getIPv6() {
return *
reinterpret_cast<sockaddr_in6*
>(get()); }
257 return addr.release();
270 bool isUnspecified()
const;
272 bool isMappedIPv4()
const;
273 SockAddr getMappedIPv4();
274 SockAddr getMappedIPv6();
282 bool operator()(
const SockAddr& a,
const SockAddr& b)
const
285 return a.len < b.len;
286 socklen_t start, len;
289 start = offsetof(sockaddr_in, sin_addr);
290 len =
sizeof(in_addr);
293 start = offsetof(sockaddr_in6, sin6_addr);
302 return std::memcmp((uint8_t*) a.
get() + start, (uint8_t*) b.
get() + start, len) < 0;
305 friend std::ostream& operator<<(std::ostream& s,
const SockAddr& h)
314 void operator()(
void* p) { ::free(p); }
316 std::unique_ptr<sockaddr, free_delete> addr {};
319 void set(
const sockaddr* sa, socklen_t length)
324 addr.reset((sockaddr*) ::malloc(len));
329 std::memcpy((uint8_t*) get(), (
const uint8_t*) sa, len);