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