diff --git a/net/socket.h b/net/socket.h index d589c9a1..24939b80 100644 --- a/net/socket.h +++ b/net/socket.h @@ -20,6 +20,7 @@ limitations under the License. #include #include #include +#include #include #include @@ -40,8 +41,8 @@ LogBuffer& operator << (LogBuffer& log, const sockaddr_in6& addr); LogBuffer& operator << (LogBuffer& log, const sockaddr& addr); namespace photon { -namespace net -{ +namespace net { + struct __attribute__ ((packed)) IPAddr { public: union { @@ -109,7 +110,6 @@ namespace net // Should ONLY be used for IPv4 address uint32_t to_nl() const { - assert(is_ipv4()); return addr._in_addr_field[3]; } @@ -180,60 +180,38 @@ namespace net } }; + static_assert(sizeof(IPAddr) == 16, "IPAddr size incorrect"); + struct __attribute__ ((packed)) EndPoint { IPAddr addr; uint16_t port = 0; + EndPoint() = default; - EndPoint(IPAddr ip, uint16_t port): addr(ip), port(port) {} - // explicit EndPoint(const sockaddr_storage* sock_addr) { - // from_sockaddr_storage(sock_addr); - // } + + EndPoint(IPAddr ip, uint16_t port) : addr(ip), port(port) {} + bool is_ipv4() const { return addr.is_ipv4(); }; - // // The caller is responsible to zero-initialize sockaddr_storage - // sockaddr* get_sockaddr(const sockaddr_storage& storage) const { - // if (addr.is_ipv4()) { - // auto* in4 = (sockaddr_in*) &storage; - // in4->sin_family = AF_INET; - // in4->sin_port = htons(port); - // in4->sin_addr.s_addr = addr.to_nl(); - // return (sockaddr*) in4; - // } else { - // auto* in6 = (sockaddr_in6*) &storage; - // in6->sin6_family = AF_INET6; - // in6->sin6_port = htons(port); - // in6->sin6_addr = addr.addr; - // return (sockaddr*) in6; - // } - // } - // socklen_t get_sockaddr_len() const { - // return addr.is_ipv4() ? sizeof(sockaddr_in) : sizeof(sockaddr_in6); - // } - // void from_sockaddr_storage(const sockaddr_storage* storage) { - // if (storage->ss_family == AF_INET6) { - // auto s6 = (sockaddr_in6*) storage; - // addr = IPAddr(s6->sin6_addr); - // port = ntohs(s6->sin6_port); - // } else if (storage->ss_family == AF_INET) { - // auto s4 = (sockaddr_in*) storage; - // addr = IPAddr(s4->sin_addr); - // port = ntohs(s4->sin_port); - // } - // } + bool operator==(const EndPoint& rhs) const { return rhs.addr == addr && rhs.port == port; } + bool operator!=(const EndPoint& rhs) const { return !operator==(rhs); } + bool undefined() const { return addr.undefined() && port == 0; } }; + static_assert(sizeof(EndPoint) == 18, "Endpoint size incorrect"); + struct sockaddr_storage { sockaddr_storage() = default; + explicit sockaddr_storage(const EndPoint& ep) { if (ep.is_ipv4()) { auto* in4 = (sockaddr_in*) &store; @@ -247,15 +225,19 @@ namespace net in6->sin6_addr = ep.addr.addr; } } + explicit sockaddr_storage(const sockaddr_in& addr) { *((sockaddr_in*) &store) = addr; } + explicit sockaddr_storage(const sockaddr_in6& addr) { *((sockaddr_in6*) &store) = addr; } + explicit sockaddr_storage(const sockaddr& addr) { *((sockaddr*) &store) = addr; } + EndPoint to_endpoint() const { EndPoint ep; if (store.ss_family == AF_INET6) { @@ -269,9 +251,11 @@ namespace net } return ep; } + sockaddr* get_sockaddr() const { return (sockaddr*) &store; } + socklen_t get_socklen() const { switch (store.ss_family) { case AF_INET: @@ -282,6 +266,7 @@ namespace net return 0; } } + // store must be zero initialized ::sockaddr_storage store = {}; };