| // Copyright 2017 The Fuchsia Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #ifndef SRC_LIB_INET_SOCKET_ADDRESS_H_ | |
| #define SRC_LIB_INET_SOCKET_ADDRESS_H_ | |
| #include <arpa/inet.h> | |
| #include <fuchsia/net/cpp/fidl.h> | |
| #include <fuchsia/netstack/cpp/fidl.h> | |
| #include <lib/syslog/cpp/macros.h> | |
| #include <sys/socket.h> | |
| #include <ostream> | |
| #include "src/lib/inet/ip_address.h" | |
| #include "src/lib/inet/ip_port.h" | |
| namespace inet { | |
| // Represents a V4 or V6 socket address. | |
| class SocketAddress { | |
| public: | |
| static const SocketAddress kInvalid; | |
| // Creates an invalid socket. | |
| SocketAddress(); | |
| // Creates an IPV4 socket address from four address bytes and an IpPort. | |
| SocketAddress(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, IpPort port); | |
| // Creates an IPV4 socket address from an in_addr_t and an IpPort. | |
| SocketAddress(in_addr_t addr, IpPort port); | |
| // Creates an IPV4 socket address from an sockaddr_in struct. | |
| explicit SocketAddress(const sockaddr_in& addr); | |
| // Creates an IPV6 socket address from eight address words and an IpPort. | |
| SocketAddress(uint16_t w0, uint16_t w1, uint16_t w2, uint16_t w3, uint16_t w4, uint16_t w5, | |
| uint16_t w6, uint16_t w7, IpPort port); | |
| // Creates an IPV6 socket address from two address words and an IpPort. | |
| SocketAddress(uint16_t w0, uint16_t w7, IpPort port); | |
| // Creates an IPV6 socket address from an in6_addr struct and an IpPort. | |
| SocketAddress(const in6_addr& addr, IpPort port); | |
| // Creates an IPV6 socket address from an sockaddr_in6 struct. | |
| explicit SocketAddress(const sockaddr_in6& addr); | |
| // Creates a socket address from a IpAddress and an IpPort. | |
| SocketAddress(const IpAddress& addr, IpPort port, uint32_t scope_id = 0); | |
| // Creates a socket address from an sockaddr_storage struct. | |
| explicit SocketAddress(const sockaddr_storage& addr); | |
| // Creates a socket address from a fuchsia.netstack SocketAddress struct. | |
| explicit SocketAddress(const fuchsia::netstack::SocketAddress* addr); | |
| // Creates a socket address from a fuchsia.net SocketAddress struct. | |
| explicit SocketAddress(const fuchsia::net::SocketAddress* addr); | |
| // Creates a socket address from a fuchsia.net Ipv4SocketAddress struct. | |
| explicit SocketAddress(const fuchsia::net::Ipv4SocketAddress* addr); | |
| // Creates a socket address from a fuchsia.net Ipv6SocketAddress struct. | |
| explicit SocketAddress(const fuchsia::net::Ipv6SocketAddress* addr); | |
| bool is_valid() const { return family() != AF_UNSPEC; } | |
| sa_family_t family() const { return v4_.sin_family; } | |
| bool is_v4() const { return family() == AF_INET; } | |
| bool is_v6() const { return family() == AF_INET6; } | |
| IpAddress address() const { return is_v4() ? IpAddress(v4_.sin_addr) : IpAddress(v6_.sin6_addr); } | |
| IpPort port() const { return IpPort::From_in_port_t(v4_.sin_port); } | |
| uint32_t scope_id() const { return as_sockaddr_in6().sin6_scope_id; } | |
| const sockaddr_in& as_sockaddr_in() const { | |
| FX_DCHECK(is_v4()); | |
| return v4_; | |
| } | |
| const sockaddr_in6& as_sockaddr_in6() const { | |
| FX_DCHECK(is_v6()); | |
| return v6_; | |
| } | |
| const sockaddr* as_sockaddr() const { return reinterpret_cast<const sockaddr*>(&v4_); } | |
| socklen_t socklen() const { return is_v4() ? sizeof(v4_) : sizeof(v6_); } | |
| std::string ToString() const; | |
| explicit operator bool() const { return is_valid(); } | |
| bool operator==(const SocketAddress& other) const { | |
| return is_v4() == other.is_v4() && | |
| std::memcmp(as_sockaddr(), other.as_sockaddr(), socklen()) == 0; | |
| } | |
| bool operator!=(const SocketAddress& other) const { return !(*this == other); } | |
| private: | |
| void Build(const IpAddress& address, IpPort port, uint32_t scope_id); | |
| union { | |
| sockaddr_in v4_; | |
| sockaddr_in6 v6_; | |
| }; | |
| }; | |
| std::ostream& operator<<(std::ostream& os, const SocketAddress& value); | |
| } // namespace inet | |
| template <> | |
| struct std::hash<inet::SocketAddress> { | |
| std::size_t operator()(const inet::SocketAddress& address) const noexcept { | |
| return std::hash<inet::IpAddress>{}(address.address()) ^ | |
| (std::hash<uint16_t>{}(address.port().as_uint16_t()) << 1); | |
| } | |
| }; | |
| #endif // SRC_LIB_INET_SOCKET_ADDRESS_H_ |