xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/platform/api/quic_socket_address_test.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright (c) 2019 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 "quiche/quic/platform/api/quic_socket_address.h"
6 
7 #include <memory>
8 #include <sstream>
9 
10 #include "quiche/quic/platform/api/quic_ip_address.h"
11 #include "quiche/quic/platform/api/quic_test.h"
12 
13 namespace quic {
14 namespace {
15 
TEST(QuicSocketAddress,Uninitialized)16 TEST(QuicSocketAddress, Uninitialized) {
17   QuicSocketAddress uninitialized;
18   EXPECT_FALSE(uninitialized.IsInitialized());
19 }
20 
TEST(QuicSocketAddress,ExplicitConstruction)21 TEST(QuicSocketAddress, ExplicitConstruction) {
22   QuicSocketAddress ipv4_address(QuicIpAddress::Loopback4(), 443);
23   QuicSocketAddress ipv6_address(QuicIpAddress::Loopback6(), 443);
24   EXPECT_TRUE(ipv4_address.IsInitialized());
25   EXPECT_EQ("127.0.0.1:443", ipv4_address.ToString());
26   EXPECT_EQ("[::1]:443", ipv6_address.ToString());
27   EXPECT_EQ(QuicIpAddress::Loopback4(), ipv4_address.host());
28   EXPECT_EQ(QuicIpAddress::Loopback6(), ipv6_address.host());
29   EXPECT_EQ(443, ipv4_address.port());
30 }
31 
TEST(QuicSocketAddress,OutputToStream)32 TEST(QuicSocketAddress, OutputToStream) {
33   QuicSocketAddress ipv4_address(QuicIpAddress::Loopback4(), 443);
34   std::stringstream stream;
35   stream << ipv4_address;
36   EXPECT_EQ("127.0.0.1:443", stream.str());
37 }
38 
TEST(QuicSocketAddress,FromSockaddrIPv4)39 TEST(QuicSocketAddress, FromSockaddrIPv4) {
40   union {
41     sockaddr_storage storage;
42     sockaddr addr;
43     sockaddr_in v4;
44   } address;
45 
46   memset(&address, 0, sizeof(address));
47   address.v4.sin_family = AF_INET;
48   address.v4.sin_addr = QuicIpAddress::Loopback4().GetIPv4();
49   address.v4.sin_port = htons(443);
50   EXPECT_EQ("127.0.0.1:443",
51             QuicSocketAddress(&address.addr, sizeof(address.v4)).ToString());
52   EXPECT_EQ("127.0.0.1:443", QuicSocketAddress(address.storage).ToString());
53 }
54 
TEST(QuicSocketAddress,FromSockaddrIPv6)55 TEST(QuicSocketAddress, FromSockaddrIPv6) {
56   union {
57     sockaddr_storage storage;
58     sockaddr addr;
59     sockaddr_in6 v6;
60   } address;
61 
62   memset(&address, 0, sizeof(address));
63   address.v6.sin6_family = AF_INET6;
64   address.v6.sin6_addr = QuicIpAddress::Loopback6().GetIPv6();
65   address.v6.sin6_port = htons(443);
66   EXPECT_EQ("[::1]:443",
67             QuicSocketAddress(&address.addr, sizeof(address.v6)).ToString());
68   EXPECT_EQ("[::1]:443", QuicSocketAddress(address.storage).ToString());
69 }
70 
TEST(QuicSocketAddres,ToSockaddrIPv4)71 TEST(QuicSocketAddres, ToSockaddrIPv4) {
72   union {
73     sockaddr_storage storage;
74     sockaddr_in v4;
75   } address;
76 
77   address.storage =
78       QuicSocketAddress(QuicIpAddress::Loopback4(), 443).generic_address();
79   ASSERT_EQ(AF_INET, address.v4.sin_family);
80   EXPECT_EQ(QuicIpAddress::Loopback4(), QuicIpAddress(address.v4.sin_addr));
81   EXPECT_EQ(htons(443), address.v4.sin_port);
82 }
83 
TEST(QuicSocketAddress,Normalize)84 TEST(QuicSocketAddress, Normalize) {
85   QuicIpAddress dual_stacked;
86   ASSERT_TRUE(dual_stacked.FromString("::ffff:127.0.0.1"));
87   ASSERT_TRUE(dual_stacked.IsIPv6());
88   QuicSocketAddress not_normalized(dual_stacked, 443);
89   QuicSocketAddress normalized = not_normalized.Normalized();
90   EXPECT_EQ("[::ffff:127.0.0.1]:443", not_normalized.ToString());
91   EXPECT_EQ("127.0.0.1:443", normalized.ToString());
92 }
93 
94 // TODO(vasilvv): either ensure this works on all platforms, or deprecate and
95 // remove this API.
96 #if defined(__linux__) && !defined(ANDROID)
97 #include <errno.h>
98 #include <sys/socket.h>
99 #include <sys/types.h>
100 
TEST(QuicSocketAddress,FromSocket)101 TEST(QuicSocketAddress, FromSocket) {
102   int fd;
103   QuicSocketAddress address;
104   bool bound = false;
105   for (int port = 50000; port < 50400; port++) {
106     fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
107     ASSERT_GT(fd, 0);
108 
109     address = QuicSocketAddress(QuicIpAddress::Loopback6(), port);
110     sockaddr_storage raw_address = address.generic_address();
111     int bind_result = bind(fd, reinterpret_cast<const sockaddr*>(&raw_address),
112                            sizeof(sockaddr_in6));
113 
114     if (bind_result < 0 && errno == EADDRINUSE) {
115       close(fd);
116       continue;
117     }
118 
119     ASSERT_EQ(0, bind_result);
120     bound = true;
121     break;
122   }
123   ASSERT_TRUE(bound);
124 
125   QuicSocketAddress real_address;
126   ASSERT_EQ(0, real_address.FromSocket(fd));
127   ASSERT_TRUE(real_address.IsInitialized());
128   EXPECT_EQ(real_address, address);
129   close(fd);
130 }
131 #endif
132 
133 }  // namespace
134 }  // namespace quic
135