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