1 // Copyright 2012 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_BASE_IP_ENDPOINT_H_ 6 #define NET_BASE_IP_ENDPOINT_H_ 7 8 #include <stdint.h> 9 10 #include <optional> 11 #include <ostream> 12 #include <string> 13 14 #include "base/values.h" 15 #include "build/build_config.h" 16 #include "net/base/address_family.h" 17 #include "net/base/ip_address.h" 18 #include "net/base/net_export.h" 19 20 // Replicate these from Windows headers to avoid pulling net/sys_addrinfo.h. 21 // Doing that transitively brings in windows.h. Including windows.h pollutes the 22 // global namespace with thousands of macro definitions. This file is 23 // transitively included in enough files that including windows.h potentially 24 // impacts build performance. 25 // Similarly, just pull in the minimal header necessary on non-Windows platforms 26 // to help with build performance. 27 struct sockaddr; 28 #if BUILDFLAG(IS_WIN) 29 typedef int socklen_t; 30 #else 31 #include <sys/socket.h> 32 #endif 33 34 namespace net { 35 36 // An IPEndPoint represents the address of a transport endpoint: 37 // * IP address (either v4 or v6) 38 // * Port 39 // * IPv6 link local scope ID (only for IPv6 link local address) 40 class NET_EXPORT IPEndPoint { 41 public: 42 // Function signatures of if_nametoindex() and if_indextoname(). 43 using NameToIndexFunc = uint32_t (*)(const char*); 44 using IndexToNameFunc = char* (*)(unsigned int, char*); 45 46 // Set fake if_nametoindex() and if_indextoname() functions for testing. 47 static void SetNameToIndexFuncForTesting(NameToIndexFunc func); 48 static void SetIndexToNameFuncForTesting(IndexToNameFunc func); 49 50 // Nullopt if `value` is malformed to be serialized to IPEndPoint. 51 static std::optional<IPEndPoint> FromValue(const base::Value& value); 52 53 IPEndPoint(); 54 ~IPEndPoint(); 55 IPEndPoint(const IPAddress& address, 56 uint16_t port, 57 std::optional<uint32_t> scope_id = std::nullopt); 58 IPEndPoint(const IPEndPoint& endpoint); 59 address()60 const IPAddress& address() const { return address_; } 61 62 // Returns the IPv4/IPv6 port if it has been set by the constructor or 63 // `FromSockAddr`. This function will crash if the IPEndPoint is for a 64 // Bluetooth socket. 65 uint16_t port() const; 66 67 // Returns the IPv6 scope identifier if it has been set by FromSockAddr() and 68 // the address is link-local. scope_id()69 std::optional<uint32_t> scope_id() const { return scope_id_; } 70 71 // Returns AddressFamily of the address. Returns ADDRESS_FAMILY_UNSPECIFIED if 72 // this is the IPEndPoint for a Bluetooth socket. 73 AddressFamily GetFamily() const; 74 75 // Returns the sockaddr family of the address, AF_INET or AF_INET6. Returns 76 // AF_BTH if this is the IPEndPoint for a Bluetooth socket. 77 int GetSockAddrFamily() const; 78 79 // Convert to a provided sockaddr struct. This function will crash if the 80 // IPEndPoint is for a Bluetooth socket. 81 // |address| is the sockaddr to copy into. Should be at least 82 // sizeof(struct sockaddr_storage) bytes. 83 // |address_length| is an input/output parameter. On input, it is the 84 // size of data in |address| available. On output, it is the size of 85 // the address that was copied into |address|. 86 // Returns true on success, false on failure. 87 [[nodiscard]] bool ToSockAddr(struct sockaddr* address, 88 socklen_t* address_length) const; 89 90 // Convert from a sockaddr struct. 91 // |address| is the address. 92 // |address_length| is the length of |address|. 93 // Returns true on success, false on failure. 94 [[nodiscard]] bool FromSockAddr(const struct sockaddr* address, 95 socklen_t address_length); 96 97 // Returns value as a string (e.g. "127.0.0.1:80"). Returns the empty string 98 // when |address_| is invalid (the port will be ignored). This function will 99 // crash if the IPEndPoint is for a Bluetooth socket. This function doesn't 100 // include IPv6 scope id intentionally because exposing scope id is 101 // discouraged for web purpose. See 102 // https://datatracker.ietf.org/doc/html/draft-ietf-6man-zone-ui#section-5 103 std::string ToString() const; 104 105 // As above, but without port. Returns the empty string when address_ is 106 // invalid. The function will crash if the IPEndPoint is for a Bluetooth 107 // socket. This function doesn't include IPv6 scope id intentionally. 108 std::string ToStringWithoutPort() const; 109 110 bool operator<(const IPEndPoint& that) const; 111 bool operator==(const IPEndPoint& that) const; 112 bool operator!=(const IPEndPoint& that) const; 113 114 base::Value ToValue() const; 115 116 private: 117 static NameToIndexFunc name_to_index_func_for_testing_; 118 static IndexToNameFunc index_to_name_func_for_testing_; 119 120 // Returns a scope ID from `dict` when `dict` has a valid interface name that 121 // can be converted to an interface index. 122 static std::optional<uint32_t> ScopeIdFromDict(const base::Value::Dict& dict); 123 124 // Converts `scope_id` to an interface name as a base::Value. 125 static base::Value ScopeIdToValue(std::optional<uint32_t> scope_id); 126 127 bool IsIPv6LinkLocal() const; 128 129 IPAddress address_; 130 uint16_t port_ = 0; 131 std::optional<uint32_t> scope_id_; 132 }; 133 134 NET_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, 135 const IPEndPoint& ip_endpoint); 136 137 } // namespace net 138 139 #endif // NET_BASE_IP_ENDPOINT_H_ 140