xref: /aosp_15_r20/external/cronet/net/quic/address_utils.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2019 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef NET_QUIC_ADDRESS_UTILS_H_
6 #define NET_QUIC_ADDRESS_UTILS_H_
7 
8 #include <string.h>
9 
10 #include "base/containers/span.h"
11 #include "net/base/ip_address.h"
12 #include "net/base/ip_endpoint.h"
13 #include "net/third_party/quiche/src/quiche/common/quiche_ip_address.h"
14 #include "net/third_party/quiche/src/quiche/common/quiche_ip_address_family.h"
15 #include "net/third_party/quiche/src/quiche/quic/platform/api/quic_socket_address.h"
16 
17 namespace net {
18 
ToIPEndPoint(quic::QuicSocketAddress address)19 inline IPEndPoint ToIPEndPoint(quic::QuicSocketAddress address) {
20   if (!address.IsInitialized()) {
21     return IPEndPoint();
22   }
23 
24   IPEndPoint result;
25   sockaddr_storage storage = address.generic_address();
26   const bool success = result.FromSockAddr(
27       reinterpret_cast<const sockaddr*>(&storage), sizeof(storage));
28   DCHECK(success);
29   return result;
30 }
31 
ToIPAddress(quic::QuicIpAddress address)32 inline IPAddress ToIPAddress(quic::QuicIpAddress address) {
33   if (!address.IsInitialized()) {
34     return IPAddress();
35   }
36 
37   switch (address.address_family()) {
38     case quiche::IpAddressFamily::IP_V4: {
39       in_addr raw_address = address.GetIPv4();
40       // `s_addr` is a `uint32_t`, but it is already in network byte order.
41       return IPAddress(base::byte_span_from_ref(raw_address.s_addr));
42     }
43     case quiche::IpAddressFamily::IP_V6: {
44       in6_addr raw_address = address.GetIPv6();
45       return IPAddress(raw_address.s6_addr);
46     }
47     default:
48       DCHECK_EQ(address.address_family(), quiche::IpAddressFamily::IP_UNSPEC);
49       return IPAddress();
50   }
51 }
52 
ToQuicSocketAddress(IPEndPoint address)53 inline quic::QuicSocketAddress ToQuicSocketAddress(IPEndPoint address) {
54   if (address.address().empty()) {
55     return quic::QuicSocketAddress();
56   }
57 
58   sockaddr_storage result;
59   socklen_t size = sizeof(result);
60   if (!address.ToSockAddr(reinterpret_cast<sockaddr*>(&result), &size)) {
61     return quic::QuicSocketAddress();
62   }
63   return quic::QuicSocketAddress(result);
64 }
65 
ToQuicIpAddress(net::IPAddress address)66 inline quic::QuicIpAddress ToQuicIpAddress(net::IPAddress address) {
67   if (address.IsIPv4()) {
68     in_addr result;
69     static_assert(sizeof(result) == IPAddress::kIPv4AddressSize,
70                   "Address size mismatch");
71     memcpy(&result, address.bytes().data(), IPAddress::kIPv4AddressSize);
72     return quic::QuicIpAddress(result);
73   }
74   if (address.IsIPv6()) {
75     in6_addr result;
76     static_assert(sizeof(result) == IPAddress::kIPv6AddressSize,
77                   "Address size mismatch");
78     memcpy(&result, address.bytes().data(), IPAddress::kIPv6AddressSize);
79     return quic::QuicIpAddress(result);
80   }
81 
82   DCHECK(address.empty());
83   return quic::QuicIpAddress();
84 }
85 
86 }  // namespace net
87 
88 #endif  // NET_QUIC_ADDRESS_UTILS_H_
89