Replace QuicSocketAddress with a platform-independent implementation. Not having to rely directly on a platform-specified type would make it easier to port QUIC to new embedders. gfe-relnote: n/a (no functional change) PiperOrigin-RevId: 253124606 Change-Id: Ifd2a171f007e9e055d9c913500608b4161fca373
diff --git a/quic/platform/api/quic_socket_address.cc b/quic/platform/api/quic_socket_address.cc index f6d40df..eefad84 100644 --- a/quic/platform/api/quic_socket_address.cc +++ b/quic/platform/api/quic_socket_address.cc
@@ -2,58 +2,128 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" + #include <string> -#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_ip_address.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_ip_address_family.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.h" namespace quic { QuicSocketAddress::QuicSocketAddress(QuicIpAddress address, uint16_t port) - : impl_(address, port) {} + : host_(address), port_(port) {} -QuicSocketAddress::QuicSocketAddress(const struct sockaddr_storage& saddr) - : impl_(saddr) {} +QuicSocketAddress::QuicSocketAddress(const struct sockaddr_storage& saddr) { + switch (saddr.ss_family) { + case AF_INET: { + const sockaddr_in* v4 = reinterpret_cast<const sockaddr_in*>(&saddr); + host_ = QuicIpAddress(v4->sin_addr); + port_ = ntohs(v4->sin_port); + break; + } + case AF_INET6: { + const sockaddr_in6* v6 = reinterpret_cast<const sockaddr_in6*>(&saddr); + host_ = QuicIpAddress(v6->sin6_addr); + port_ = ntohs(v6->sin6_port); + break; + } + default: + QUIC_BUG << "Unknown address family passed: " << saddr.ss_family; + break; + } +} -QuicSocketAddress::QuicSocketAddress(const sockaddr* saddr, socklen_t len) - : impl_(saddr, len) {} - -QuicSocketAddress::QuicSocketAddress(const QuicSocketAddressImpl& impl) - : impl_(impl) {} +QuicSocketAddress::QuicSocketAddress(const sockaddr* saddr, socklen_t len) { + sockaddr_storage storage; + if (len < 0 || + (saddr->sa_family == AF_INET && + static_cast<size_t>(len) < sizeof(sockaddr_in)) || + (saddr->sa_family == AF_INET6 && + static_cast<size_t>(len) < sizeof(sockaddr_in6)) || + static_cast<size_t>(len) > sizeof(storage)) { + QUIC_BUG << "Socket address of invalid length provided"; + return; + } + memcpy(&storage, saddr, len); + *this = QuicSocketAddress(storage); +} bool operator==(const QuicSocketAddress& lhs, const QuicSocketAddress& rhs) { - return lhs.impl_ == rhs.impl_; + return lhs.host_ == rhs.host_ && lhs.port_ == rhs.port_; } bool operator!=(const QuicSocketAddress& lhs, const QuicSocketAddress& rhs) { - return lhs.impl_ != rhs.impl_; + return !(lhs == rhs); } bool QuicSocketAddress::IsInitialized() const { - return impl_.IsInitialized(); + return host_.IsInitialized(); } std::string QuicSocketAddress::ToString() const { - return impl_.ToString(); + switch (host_.address_family()) { + case IpAddressFamily::IP_V4: + return QuicStrCat(host_.ToString(), ":", port_); + case IpAddressFamily::IP_V6: + return QuicStrCat("[", host_.ToString(), "]:", port_); + default: + return ""; + } } int QuicSocketAddress::FromSocket(int fd) { - return impl_.FromSocket(fd); + sockaddr_storage addr; + socklen_t addr_len = sizeof(addr); + int result = getsockname(fd, reinterpret_cast<sockaddr*>(&addr), &addr_len); + + bool success = result == 0 && addr_len > 0 && + static_cast<size_t>(addr_len) <= sizeof(addr); + if (success) { + *this = QuicSocketAddress(addr); + return 0; + } + return -1; } QuicSocketAddress QuicSocketAddress::Normalized() const { - return QuicSocketAddress(impl_.Normalized()); + return QuicSocketAddress(host_.Normalized(), port_); } QuicIpAddress QuicSocketAddress::host() const { - return QuicIpAddress(impl_.host()); + return host_; } uint16_t QuicSocketAddress::port() const { - return impl_.port(); + return port_; } sockaddr_storage QuicSocketAddress::generic_address() const { - return impl_.generic_address(); + union { + sockaddr_storage storage; + sockaddr_in v4; + sockaddr_in6 v6; + } result; + memset(&result.storage, 0, sizeof(result.storage)); + + switch (host_.address_family()) { + case IpAddressFamily::IP_V4: + result.v4.sin_family = AF_INET; + result.v4.sin_addr = host_.GetIPv4(); + result.v4.sin_port = htons(port_); + break; + case IpAddressFamily::IP_V6: + result.v6.sin6_family = AF_INET6; + result.v6.sin6_addr = host_.GetIPv6(); + result.v6.sin6_port = htons(port_); + break; + default: + result.storage.ss_family = AF_UNSPEC; + break; + } + return result.storage; } } // namespace quic
diff --git a/quic/platform/api/quic_socket_address.h b/quic/platform/api/quic_socket_address.h index 94e78a6..1a200e1 100644 --- a/quic/platform/api/quic_socket_address.h +++ b/quic/platform/api/quic_socket_address.h
@@ -9,20 +9,17 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" #include "net/third_party/quiche/src/quic/platform/api/quic_ip_address.h" -#include "net/quic/platform/impl/quic_socket_address_impl.h" namespace quic { +// A class representing a socket endpoint address (i.e., IP address plus a +// port) in QUIC. class QUIC_EXPORT_PRIVATE QuicSocketAddress { - // A class representing a socket endpoint address (i.e., IP address plus a - // port) in QUIC. The actual implementation (platform dependent) of a socket - // address is in QuicSocketAddressImpl. public: - QuicSocketAddress() = default; + QuicSocketAddress() {} QuicSocketAddress(QuicIpAddress address, uint16_t port); explicit QuicSocketAddress(const struct sockaddr_storage& saddr); explicit QuicSocketAddress(const sockaddr* saddr, socklen_t len); - explicit QuicSocketAddress(const QuicSocketAddressImpl& impl); QuicSocketAddress(const QuicSocketAddress& other) = default; QuicSocketAddress& operator=(const QuicSocketAddress& other) = default; QuicSocketAddress& operator=(QuicSocketAddress&& other) = default; @@ -41,7 +38,8 @@ sockaddr_storage generic_address() const; private: - QuicSocketAddressImpl impl_; + QuicIpAddress host_; + uint16_t port_ = 0; }; } // namespace quic