24#include <sys/socket.h>
25#include <netinet/in.h>
28typedef uint16_t in_port_t;
36typedef uint16_t sa_family_t;
37typedef uint16_t in_port_t;
51OPENDHT_PUBLIC std::string print_addr(
const sockaddr* sa, socklen_t slen);
52OPENDHT_PUBLIC std::string print_addr(
const sockaddr_storage& ss, socklen_t sslen);
70 SockAddr(
const sockaddr* sa, socklen_t length) {
71 if (length >
static_cast<socklen_t
>(
sizeof(sockaddr_storage)))
72 throw std::runtime_error(
"Socket address length is too large");
78 if (sa->sa_family == AF_INET)
79 len =
sizeof(sockaddr_in);
80 else if(sa->sa_family == AF_INET6)
81 len =
sizeof(sockaddr_in6);
83 throw std::runtime_error(
"Unknown address family");
91 SockAddr(
const sockaddr_storage& ss, socklen_t len) :
SockAddr((const sockaddr*)&ss, len) {}
93 static std::vector<SockAddr> resolve(
const std::string& host,
const std::string& service = {});
95 bool operator<(
const SockAddr& o)
const {
98 return std::memcmp((
const uint8_t*)get(), (
const uint8_t*)o.get(), len) < 0;
101 bool equals(
const SockAddr& o)
const {
103 && std::memcmp((
const uint8_t*)get(), (
const uint8_t*)o.get(), len) == 0;
105 SockAddr& operator=(
const SockAddr& o) {
106 set(o.get(), o.getLength());
109 SockAddr& operator=(SockAddr&& o) {
112 addr = std::move(o.addr);
116 std::string toString()
const {
117 return print_addr(get(), getLength());
123 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) {
144 if (len) addr.reset((sockaddr*)::calloc(len, 1));
148 addr->sa_family = af;
155 auto family = getFamily();
158 getIPv4().sin_addr.s_addr = htonl(INADDR_ANY);
161 getIPv6().sin6_addr = in6addr_any;
171 switch(getFamily()) {
173 return ntohs(getIPv4().sin_port);
175 return ntohs(getIPv6().sin6_port);
185 switch(getFamily()) {
187 getIPv4().sin_port = htons(p);
190 getIPv6().sin6_port = htons(p);
210 explicit operator bool() const noexcept {
218 const sockaddr*
get()
const {
return addr.get(); }
224 sockaddr*
get() {
return addr.get(); }
226 inline const sockaddr_in& getIPv4()
const {
227 return *
reinterpret_cast<const sockaddr_in*
>(get());
229 inline const sockaddr_in6& getIPv6()
const {
230 return *
reinterpret_cast<const sockaddr_in6*
>(get());
232 inline sockaddr_in& getIPv4() {
233 return *
reinterpret_cast<sockaddr_in*
>(get());
235 inline sockaddr_in6& getIPv6() {
236 return *
reinterpret_cast<sockaddr_in6*
>(get());
249 bool isUnspecified()
const;
251 bool isMappedIPv4()
const;
262 return a.len < b.len;
263 socklen_t start, len;
266 start = offsetof(sockaddr_in, sin_addr);
267 len =
sizeof(in_addr);
270 start = offsetof(sockaddr_in6, sin6_addr);
279 return std::memcmp((uint8_t*)a.
get()+start,
280 (uint8_t*)b.
get()+start, len) < 0;
284 struct free_delete {
void operator()(
void* p) { ::free(p); } };
285 std::unique_ptr<sockaddr, free_delete> addr {};
288 void set(
const sockaddr* sa, socklen_t length) {
291 if (len) addr.reset((sockaddr*)::malloc(len));
295 std::memcpy((uint8_t*)get(), (
const uint8_t*)sa, len);
300OPENDHT_PUBLIC
bool operator==(
const SockAddr& a,
const SockAddr& b);
SockAddr(const sockaddr *sa, socklen_t length)
SockAddr(const sockaddr_storage &ss, socklen_t len)
void setFamily(sa_family_t af)
void setPort(in_port_t p)
const sockaddr * get() const
socklen_t getLength() const
void setAddress(const char *address)
sa_family_t getFamily() const
in_port_t getPort() const