1 // Copyright (c) 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
6
7 #include <limits>
8 #include <string>
9
10 #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
11 #include "net/third_party/quiche/src/quic/platform/api/quic_ip_address.h"
12 #include "net/third_party/quiche/src/quic/platform/api/quic_ip_address_family.h"
13 #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h"
14
15 namespace quic {
16
QuicSocketAddress(QuicIpAddress address,uint16_t port)17 QuicSocketAddress::QuicSocketAddress(QuicIpAddress address, uint16_t port)
18 : host_(address), port_(port) {}
19
QuicSocketAddress(const struct sockaddr_storage & saddr)20 QuicSocketAddress::QuicSocketAddress(const struct sockaddr_storage& saddr) {
21 switch (saddr.ss_family) {
22 case AF_INET: {
23 const sockaddr_in* v4 = reinterpret_cast<const sockaddr_in*>(&saddr);
24 host_ = QuicIpAddress(v4->sin_addr);
25 port_ = ntohs(v4->sin_port);
26 break;
27 }
28 case AF_INET6: {
29 const sockaddr_in6* v6 = reinterpret_cast<const sockaddr_in6*>(&saddr);
30 host_ = QuicIpAddress(v6->sin6_addr);
31 port_ = ntohs(v6->sin6_port);
32 break;
33 }
34 default:
35 QUIC_BUG << "Unknown address family passed: " << saddr.ss_family;
36 break;
37 }
38 }
39
QuicSocketAddress(const sockaddr * saddr,socklen_t len)40 QuicSocketAddress::QuicSocketAddress(const sockaddr* saddr, socklen_t len) {
41 sockaddr_storage storage;
42 static_assert(std::numeric_limits<socklen_t>::max() >= sizeof(storage),
43 "Cannot cast sizeof(storage) to socklen_t as it does not fit");
44 if (len < static_cast<socklen_t>(sizeof(sockaddr)) ||
45 (saddr->sa_family == AF_INET &&
46 len < static_cast<socklen_t>(sizeof(sockaddr_in))) ||
47 (saddr->sa_family == AF_INET6 &&
48 len < static_cast<socklen_t>(sizeof(sockaddr_in6))) ||
49 len > static_cast<socklen_t>(sizeof(storage))) {
50 QUIC_BUG << "Socket address of invalid length provided";
51 return;
52 }
53 memcpy(&storage, saddr, len);
54 *this = QuicSocketAddress(storage);
55 }
56
operator ==(const QuicSocketAddress & lhs,const QuicSocketAddress & rhs)57 bool operator==(const QuicSocketAddress& lhs, const QuicSocketAddress& rhs) {
58 return lhs.host_ == rhs.host_ && lhs.port_ == rhs.port_;
59 }
60
operator !=(const QuicSocketAddress & lhs,const QuicSocketAddress & rhs)61 bool operator!=(const QuicSocketAddress& lhs, const QuicSocketAddress& rhs) {
62 return !(lhs == rhs);
63 }
64
IsInitialized() const65 bool QuicSocketAddress::IsInitialized() const {
66 return host_.IsInitialized();
67 }
68
ToString() const69 std::string QuicSocketAddress::ToString() const {
70 switch (host_.address_family()) {
71 case IpAddressFamily::IP_V4:
72 return quiche::QuicheStrCat(host_.ToString(), ":", port_);
73 case IpAddressFamily::IP_V6:
74 return quiche::QuicheStrCat("[", host_.ToString(), "]:", port_);
75 default:
76 return "";
77 }
78 }
79
FromSocket(int fd)80 int QuicSocketAddress::FromSocket(int fd) {
81 sockaddr_storage addr;
82 socklen_t addr_len = sizeof(addr);
83 int result = getsockname(fd, reinterpret_cast<sockaddr*>(&addr), &addr_len);
84
85 bool success = result == 0 && addr_len > 0 &&
86 static_cast<size_t>(addr_len) <= sizeof(addr);
87 if (success) {
88 *this = QuicSocketAddress(addr);
89 return 0;
90 }
91 return -1;
92 }
93
Normalized() const94 QuicSocketAddress QuicSocketAddress::Normalized() const {
95 return QuicSocketAddress(host_.Normalized(), port_);
96 }
97
host() const98 QuicIpAddress QuicSocketAddress::host() const {
99 return host_;
100 }
101
port() const102 uint16_t QuicSocketAddress::port() const {
103 return port_;
104 }
105
generic_address() const106 sockaddr_storage QuicSocketAddress::generic_address() const {
107 union {
108 sockaddr_storage storage;
109 sockaddr_in v4;
110 sockaddr_in6 v6;
111 } result;
112 memset(&result.storage, 0, sizeof(result.storage));
113
114 switch (host_.address_family()) {
115 case IpAddressFamily::IP_V4:
116 result.v4.sin_family = AF_INET;
117 result.v4.sin_addr = host_.GetIPv4();
118 result.v4.sin_port = htons(port_);
119 break;
120 case IpAddressFamily::IP_V6:
121 result.v6.sin6_family = AF_INET6;
122 result.v6.sin6_addr = host_.GetIPv6();
123 result.v6.sin6_port = htons(port_);
124 break;
125 default:
126 result.storage.ss_family = AF_UNSPEC;
127 break;
128 }
129 return result.storage;
130 }
131
132 } // namespace quic
133