24 #include <sys/socket.h> 25 #include <netinet/in.h> 27 typedef uint16_t in_port_t;
35 typedef uint16_t sa_family_t;
36 typedef uint16_t in_port_t;
49 OPENDHT_PUBLIC std::string print_addr(
const sockaddr* sa, socklen_t slen);
50 OPENDHT_PUBLIC std::string print_addr(
const sockaddr_storage& ss, socklen_t sslen);
68 SockAddr(
const sockaddr* sa, socklen_t length) {
69 if (length >
sizeof(sockaddr_storage))
70 throw std::runtime_error(
"Socket address length is too large");
76 if (sa->sa_family == AF_INET)
77 len =
sizeof(sockaddr_in);
78 else if(sa->sa_family == AF_INET6)
79 len =
sizeof(sockaddr_in6);
81 throw std::runtime_error(
"Unknown address family");
89 SockAddr(
const sockaddr_storage& ss, socklen_t len) :
SockAddr((const sockaddr*)&ss, len) {}
91 static std::vector<SockAddr> resolve(
const std::string& host,
const std::string& service = {});
93 bool operator<(
const SockAddr& o)
const {
96 return std::memcmp((
const uint8_t*)
get(), (
const uint8_t*)o.get(), len) < 0;
99 bool equals(
const SockAddr& o)
const {
101 && std::memcmp((
const uint8_t*)
get(), (
const uint8_t*)o.get(), len) == 0;
103 SockAddr& operator=(
const SockAddr& o) {
104 set(o.get(), o.getLength());
107 SockAddr& operator=(SockAddr&& o) {
110 addr = std::move(o.addr);
114 std::string toString()
const {
115 return print_addr(
get(), getLength());
121 sa_family_t
getFamily()
const {
return len >
sizeof(sa_family_t) ? addr->sa_family : AF_UNSPEC; }
129 socklen_t new_length;
132 new_length =
sizeof(sockaddr_in);
135 new_length =
sizeof(sockaddr_in6);
140 if (new_length != len) {
142 if (len) addr.reset((sockaddr*)::calloc(len, 1));
145 if (len >
sizeof(sa_family_t))
146 addr->sa_family = af;
154 switch(getFamily()) {
156 return ntohs(getIPv4().sin_port);
158 return ntohs(getIPv6().sin6_port);
168 switch(getFamily()) {
170 getIPv4().sin_port = htons(p);
173 getIPv6().sin6_port = htons(p);
187 explicit operator bool() const noexcept {
195 const sockaddr*
get()
const {
return addr.get(); }
201 sockaddr*
get() {
return addr.get(); }
203 const sockaddr_in& getIPv4()
const {
204 return *
reinterpret_cast<const sockaddr_in*
>(
get());
206 const sockaddr_in6& getIPv6()
const {
207 return *
reinterpret_cast<const sockaddr_in6*
>(
get());
209 sockaddr_in& getIPv4() {
210 return *
reinterpret_cast<sockaddr_in*
>(
get());
212 sockaddr_in6& getIPv6() {
213 return *
reinterpret_cast<sockaddr_in6*
>(
get());
219 bool isLoopback()
const;
224 bool isPrivate()
const;
226 bool isUnspecified()
const;
228 bool isMappedIPv4()
const;
229 SockAddr getMappedIPv4()
const;
238 return a.len < b.len;
239 socklen_t start, len;
242 start = offsetof(sockaddr_in, sin_addr);
243 len =
sizeof(in_addr);
246 start = offsetof(sockaddr_in6, sin6_addr);
255 return std::memcmp((uint8_t*)a.
get()+start,
256 (uint8_t*)b.
get()+start, len) < 0;
261 struct free_delete {
void operator()(
void* p) { ::free(p); } };
262 std::unique_ptr<sockaddr, free_delete> addr {};
264 void set(
const sockaddr* sa, socklen_t length) {
267 if (len) addr.reset((sockaddr*)::malloc(len));
271 std::memcpy((uint8_t*)
get(), (
const uint8_t*)sa, len);
276 OPENDHT_PUBLIC
bool operator==(
const SockAddr& a,
const SockAddr& b);
void setPort(in_port_t p)
sa_family_t getFamily() const
SockAddr(const sockaddr_storage &ss, socklen_t len)
void setFamily(sa_family_t af)
SockAddr(const sockaddr *sa, socklen_t length)
socklen_t getLength() const
in_port_t getPort() const
const sockaddr * get() const