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