#pragma once #ifndef _WIN32 #include #include #else #include #include #include extern "C" const char* inet_ntop(int af, const void* src, char* dst, size_t size); extern "C" int inet_pton(int af, const char* src, void* dst); #define inet_aton(x, y) inet_pton(AF_INET, x, y) #endif #include #include namespace llarp { /// A simple SockAddr wrapper which provides a sockaddr_in (IPv4). Memory management is handled /// in constructor and destructor (if needed) and copying is disabled. struct SockAddr { SockAddr(); SockAddr(uint8_t a, uint8_t b, uint8_t c, uint8_t d); SockAddr(uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint16_t port); SockAddr(std::string_view addr); SockAddr(const SockAddr&); SockAddr& operator=(const SockAddr&); SockAddr(const sockaddr& addr); SockAddr& operator=(const sockaddr& addr); SockAddr(const sockaddr_in& addr); SockAddr& operator=(const sockaddr_in& addr); SockAddr(const sockaddr_in6& addr); SockAddr& operator=(const sockaddr_in6& addr); SockAddr(const in6_addr& addr); SockAddr& operator=(const in6_addr& addr); operator const sockaddr*() const; operator const sockaddr_in*() const; operator const sockaddr_in6*() const; bool operator<(const SockAddr& other) const; bool operator==(const SockAddr& other) const; void fromString(std::string_view str); std::string toString() const; /// Returns true if this is an empty SockAddr, defined by having no IP address set. An empty IP /// address with a valid port is still considered empty. /// /// @return true if this is empty, false otherwise bool isEmpty() const; void setIPv4(uint8_t a, uint8_t b, uint8_t c, uint8_t d); void setPort(uint16_t port); uint16_t getPort() const; private: bool m_empty = true; sockaddr_in6 m_addr; sockaddr_in m_addr4; void init(); void applySIITBytes(); }; std::ostream& operator<<(std::ostream& out, const SockAddr& address); } // namespace llarp