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