/** @file

  A brief file description

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

 */

#pragma once

#include <netinet/in.h>
#include <netdb.h>
#include <sys/socket.h>
#include <string_view>

#include "tscore/ink_memory.h"
#include "tscore/ink_apidefs.h"
#include "tscore/BufferWriterForward.h"

#if !TS_HAS_IN6_IS_ADDR_UNSPECIFIED
#if defined(IN6_IS_ADDR_UNSPECIFIED)
#undef IN6_IS_ADDR_UNSPECIFIED
#endif
static inline bool
IN6_IS_ADDR_UNSPECIFIED(in6_addr const *addr)
{
  uint64_t const *w = reinterpret_cast<uint64_t const *>(addr);
  return 0 == w[0] && 0 == w[1];
}
#endif

/*
 * IP protocol stack tags.
 *
 * When adding support for an additional protocol, the following minimum steps
 * should be done:
 *
 * 1. This set of string_views should be updated with the new tag.
 * 2. A populate_protocol function overload should be implemented for the
 *    appropriate VConnection or ProxySession virtual function.
 * 3. Traffic Dump should be updated to handle the new tag in:
 *    plugins/experimental/traffic_dump/session_data.cc
 */
extern const std::string_view IP_PROTO_TAG_IPV4;
extern const std::string_view IP_PROTO_TAG_IPV6;
extern const std::string_view IP_PROTO_TAG_UDP;
extern const std::string_view IP_PROTO_TAG_TCP;
extern const std::string_view IP_PROTO_TAG_QUIC;
extern const std::string_view IP_PROTO_TAG_TLS_1_0;
extern const std::string_view IP_PROTO_TAG_TLS_1_1;
extern const std::string_view IP_PROTO_TAG_TLS_1_2;
extern const std::string_view IP_PROTO_TAG_TLS_1_3;
extern const std::string_view IP_PROTO_TAG_HTTP_0_9;
extern const std::string_view IP_PROTO_TAG_HTTP_1_0;
extern const std::string_view IP_PROTO_TAG_HTTP_1_1;
extern const std::string_view IP_PROTO_TAG_HTTP_2_0;
extern const std::string_view IP_PROTO_TAG_HTTP_QUIC;
extern const std::string_view IP_PROTO_TAG_HTTP_3;

struct IpAddr; // forward declare.

/** A union to hold the standard IP address structures.
    By standard we mean @c sockaddr compliant.

    We use the term "endpoint" because these contain more than just the
    raw address, all of the data for an IP endpoint is present.

    @internal This might be useful to promote to avoid strict aliasing
    problems.  Experiment with it here to see how it works in the
    field.

    @internal @c sockaddr_storage is not present because it is so
    large and the benefits of including it are small. Use of this
    structure will make it easy to add if that becomes necessary.

 */
union IpEndpoint {
  typedef IpEndpoint self; ///< Self reference type.

  struct sockaddr sa;       ///< Generic address.
  struct sockaddr_in sin;   ///< IPv4
  struct sockaddr_in6 sin6; ///< IPv6

  /** Assign from a socket address.
      The entire address (all parts) are copied if the @a ip is valid.
  */
  self &assign(sockaddr const *ip ///< Source address, family, port.
  );
  /// Assign from an @a addr and @a port.
  self &assign(IpAddr const &addr, ///< Address and address family.
               in_port_t port = 0  ///< Port (network order).
  );

  /// Test for valid IP address.
  bool isValid() const;
  /// Test for IPv4.
  bool isIp4() const;
  /// Test for IPv6.
  bool isIp6() const;

  uint16_t family() const;

  /// Set to be any address for family @a family.
  /// @a family must be @c AF_INET or @c AF_INET6.
  /// @return This object.
  self &setToAnyAddr(int family ///< Address family.
  );
  /// Set to be loopback for family @a family.
  /// @a family must be @c AF_INET or @c AF_INET6.
  /// @return This object.
  self &setToLoopback(int family ///< Address family.
  );

  /// Port in network order.
  in_port_t &port();
  /// Port in network order.
  in_port_t port() const;
  /// Port in host order.
  in_port_t host_order_port() const;

  operator sockaddr *() { return &sa; }
  operator sockaddr const *() const { return &sa; }
};

/** Return the detected maximum listen(2) backlog for TCP. */
int ats_tcp_somaxconn();

/** Parse a string for pieces of an IP address.

    This doesn't parse the actual IP address, but picks it out from @a
    src. It is intended to deal with the brackets that can optionally
    surround an IP address (usually IPv6) which in turn are used to
    differentiate between an address and an attached port. E.g.
    @code
      [FE80:9312::192:168:1:1]:80
    @endcode
    @a addr or @a port can be @c nullptr in which case that value isn't returned.

    @return 0 if an address was found, non-zero otherwise.
*/
int ats_ip_parse(std::string_view src,            ///< [in] String to search.
                 std::string_view *addr,          ///< [out] Range containing IP address.
                 std::string_view *port,          ///< [out] Range containing port.
                 std::string_view *rest = nullptr ///< [out] Remnant past the addr/port if any.
);

/**  Check to see if a buffer contains only IP address characters.
     @return
    - AF_UNSPEC - not a numeric address.
    - AF_INET - only digits and dots.
    - AF_INET6 - colons found.
*/
int ats_ip_check_characters(std::string_view text);

/**
  Wrapper for inet_addr().

  @param s IP address in the Internet standard dot notation.

*/
inkcoreapi uint32_t ats_inet_addr(const char *s);

const char *ats_ip_ntop(const struct sockaddr *addr, char *dst, size_t size);

// --
/// Size in bytes of an IPv6 address.
static size_t const TS_IP6_SIZE = sizeof(in6_addr);

/// Reset an address to invalid.
/// @note Useful for marking a member as not yet set.
inline void
ats_ip_invalidate(sockaddr *addr)
{
  addr->sa_family = AF_UNSPEC;
}
inline void
ats_ip_invalidate(sockaddr_in6 *addr)
{
  addr->sin6_family = AF_UNSPEC;
}
inline void
ats_ip_invalidate(IpEndpoint *ip)
{
  ip->sa.sa_family = AF_UNSPEC;
}

/** Get a string name for an IP address family.
    @return The string name (never @c nullptr).
*/
std::string_view ats_ip_family_name(int family);

/// Test for IP protocol.
/// @return @c true if the address is IP, @c false otherwise.
inline bool
ats_is_ip(sockaddr const *addr)
{
  return addr && (AF_INET == addr->sa_family || AF_INET6 == addr->sa_family);
}
/// @return @c true if the address is IP, @c false otherwise.
inline bool
ats_is_ip(IpEndpoint const *addr)
{
  return addr && (AF_INET == addr->sa.sa_family || AF_INET6 == addr->sa.sa_family);
}
/// Test for IP protocol.
/// @return @c true if the value is an IP address family, @c false otherwise.
inline bool
ats_is_ip(int family)
{
  return AF_INET == family || AF_INET6 == family;
}
/// Test for IPv4 protocol.
/// @return @c true if the address is IPv4, @c false otherwise.
inline bool
ats_is_ip4(sockaddr const *addr)
{
  return addr && AF_INET == addr->sa_family;
}
/// Test for IPv4 protocol.
/// @note Convenience overload.
/// @return @c true if the address is IPv4, @c false otherwise.
inline bool
ats_is_ip4(IpEndpoint const *addr)
{
  return addr && AF_INET == addr->sa.sa_family;
}
/// Test for IPv6 protocol.
/// @return @c true if the address is IPv6, @c false otherwise.
inline bool
ats_is_ip6(sockaddr const *addr)
{
  return addr && AF_INET6 == addr->sa_family;
}
/// Test for IPv6 protocol.
/// @note Convenience overload.
/// @return @c true if the address is IPv6, @c false otherwise.
inline bool
ats_is_ip6(IpEndpoint const *addr)
{
  return addr && AF_INET6 == addr->sa.sa_family;
}

/// @return @c true if the address families are compatible.
inline bool
ats_ip_are_compatible(sockaddr const *lhs, ///< Address to test.
                      sockaddr const *rhs  ///< Address to test.
)
{
  return lhs->sa_family == rhs->sa_family;
}
/// @return @c true if the address families are compatible.
inline bool
ats_ip_are_compatible(IpEndpoint const *lhs, ///< Address to test.
                      IpEndpoint const *rhs  ///< Address to test.
)
{
  return ats_ip_are_compatible(&lhs->sa, &rhs->sa);
}
/// @return @c true if the address families are compatible.
inline bool
ats_ip_are_compatible(int lhs,            ///< Address family to test.
                      sockaddr const *rhs ///< Address to test.
)
{
  return lhs == rhs->sa_family;
}
/// @return @c true if the address families are compatible.
inline bool
ats_ip_are_compatible(sockaddr const *lhs, ///< Address to test.
                      int rhs              ///< Family to test.
)
{
  return lhs->sa_family == rhs;
}

// IP address casting.
// sa_cast to cast to sockaddr*.
// ss_cast to cast to sockaddr_storage*.
// ip4_cast converts to sockaddr_in (because that's effectively an IPv4 addr).
// ip6_cast converts to sockaddr_in6

inline sockaddr *
ats_ip_sa_cast(sockaddr_storage *a)
{
  return static_cast<sockaddr *>(static_cast<void *>(a));
}
inline sockaddr const *
ats_ip_sa_cast(sockaddr_storage const *a)
{
  return static_cast<sockaddr const *>(static_cast<void const *>(a));
}

inline sockaddr *
ats_ip_sa_cast(sockaddr_in *a)
{
  return static_cast<sockaddr *>(static_cast<void *>(a));
}
inline sockaddr const *
ats_ip_sa_cast(sockaddr_in const *a)
{
  return static_cast<sockaddr const *>(static_cast<void const *>(a));
}

inline sockaddr *
ats_ip_sa_cast(sockaddr_in6 *a)
{
  return static_cast<sockaddr *>(static_cast<void *>(a));
}
inline sockaddr const *
ats_ip_sa_cast(sockaddr_in6 const *a)
{
  return static_cast<sockaddr const *>(static_cast<void const *>(a));
}

inline sockaddr_storage *
ats_ip_ss_cast(sockaddr *a)
{
  return static_cast<sockaddr_storage *>(static_cast<void *>(a));
}
inline sockaddr_storage const *
ats_ip_ss_cast(sockaddr const *a)
{
  return static_cast<sockaddr_storage const *>(static_cast<void const *>(a));
}

inline sockaddr_in *
ats_ip4_cast(sockaddr *a)
{
  return static_cast<sockaddr_in *>(static_cast<void *>(a));
}
inline sockaddr_in const *
ats_ip4_cast(sockaddr const *a)
{
  return static_cast<sockaddr_in const *>(static_cast<void const *>(a));
}

inline sockaddr_in &
ats_ip4_cast(sockaddr &a)
{
  return *static_cast<sockaddr_in *>(static_cast<void *>(&a));
}
inline sockaddr_in const &
ats_ip4_cast(sockaddr const &a)
{
  return *static_cast<sockaddr_in const *>(static_cast<void const *>(&a));
}

inline sockaddr_in *
ats_ip4_cast(sockaddr_in6 *a)
{
  return static_cast<sockaddr_in *>(static_cast<void *>(a));
}
inline sockaddr_in const *
ats_ip4_cast(sockaddr_in6 const *a)
{
  return static_cast<sockaddr_in const *>(static_cast<void const *>(a));
}

inline sockaddr_in &
ats_ip4_cast(sockaddr_in6 &a)
{
  return *static_cast<sockaddr_in *>(static_cast<void *>(&a));
}
inline sockaddr_in const &
ats_ip4_cast(sockaddr_in6 const &a)
{
  return *static_cast<sockaddr_in const *>(static_cast<void const *>(&a));
}

inline sockaddr_in6 *
ats_ip6_cast(sockaddr *a)
{
  return static_cast<sockaddr_in6 *>(static_cast<void *>(a));
}
inline sockaddr_in6 const *
ats_ip6_cast(sockaddr const *a)
{
  return static_cast<sockaddr_in6 const *>(static_cast<void const *>(a));
}
inline sockaddr_in6 &
ats_ip6_cast(sockaddr &a)
{
  return *static_cast<sockaddr_in6 *>(static_cast<void *>(&a));
}
inline sockaddr_in6 const &
ats_ip6_cast(sockaddr const &a)
{
  return *static_cast<sockaddr_in6 const *>(static_cast<void const *>(&a));
}

/// @return The @c sockaddr size for the family of @a addr.
inline size_t
ats_ip_size(sockaddr const *addr ///< Address object.
)
{
  return AF_INET == addr->sa_family ? sizeof(sockaddr_in) : AF_INET6 == addr->sa_family ? sizeof(sockaddr_in6) : 0;
}
inline size_t
ats_ip_size(IpEndpoint const *addr ///< Address object.
)
{
  return AF_INET == addr->sa.sa_family ? sizeof(sockaddr_in) : AF_INET6 == addr->sa.sa_family ? sizeof(sockaddr_in6) : 0;
}
/// @return The size of the IP address only.
inline size_t
ats_ip_addr_size(sockaddr const *addr ///< Address object.
)
{
  return AF_INET == addr->sa_family ? sizeof(in_addr_t) : AF_INET6 == addr->sa_family ? sizeof(in6_addr) : 0;
}
inline size_t
ats_ip_addr_size(IpEndpoint const *addr ///< Address object.
)
{
  return AF_INET == addr->sa.sa_family ? sizeof(in_addr_t) : AF_INET6 == addr->sa.sa_family ? sizeof(in6_addr) : 0;
}

/** Get a reference to the port in an address.
    @note Because this is direct access, the port value is in network order.
    @see ats_ip_port_host_order.
    @return A reference to the port value in an IPv4 or IPv6 address.
    @internal This is primarily for internal use but it might be handy for
    clients so it is exposed.
*/
inline in_port_t &
ats_ip_port_cast(sockaddr *sa)
{
  static in_port_t dummy = 0;
  return ats_is_ip4(sa) ? ats_ip4_cast(sa)->sin_port : ats_is_ip6(sa) ? ats_ip6_cast(sa)->sin6_port : (dummy = 0);
}
inline in_port_t const &
ats_ip_port_cast(sockaddr const *sa)
{
  return ats_ip_port_cast(const_cast<sockaddr *>(sa));
}
inline in_port_t const &
ats_ip_port_cast(IpEndpoint const *ip)
{
  return ats_ip_port_cast(const_cast<sockaddr *>(&ip->sa));
}
inline in_port_t &
ats_ip_port_cast(IpEndpoint *ip)
{
  return ats_ip_port_cast(&ip->sa);
}

/** Access the IPv4 address.

    If this is not an IPv4 address a zero valued address is returned.
    @note This is direct access to the address so it will be in
    network order.

    @return A reference to the IPv4 address in @a addr.
*/
inline in_addr_t &
ats_ip4_addr_cast(sockaddr *addr)
{
  static in_addr_t dummy = 0;
  return ats_is_ip4(addr) ? ats_ip4_cast(addr)->sin_addr.s_addr : (dummy = 0);
}

/** Access the IPv4 address.

    If this is not an IPv4 address a zero valued address is returned.
    @note This is direct access to the address so it will be in
    network order.

    @return A reference to the IPv4 address in @a addr.
*/
inline in_addr_t const &
ats_ip4_addr_cast(sockaddr const *addr)
{
  static in_addr_t dummy = 0;
  return ats_is_ip4(addr) ? ats_ip4_cast(addr)->sin_addr.s_addr : static_cast<in_addr_t const &>(dummy = 0);
}

/** Access the IPv4 address.

    If this is not an IPv4 address a zero valued address is returned.
    @note This is direct access to the address so it will be in
    network order.
    @note Convenience overload.

    @return A reference to the IPv4 address in @a addr.
*/
inline in_addr_t &
ats_ip4_addr_cast(IpEndpoint *ip)
{
  return ats_ip4_addr_cast(&ip->sa);
}

/** Access the IPv4 address.

    If this is not an IPv4 address a zero valued address is returned.
    @note This is direct access to the address so it will be in
    network order.
    @note Convenience overload.

    @return A reference to the IPv4 address in @a addr.
*/
inline in_addr_t const &
ats_ip4_addr_cast(IpEndpoint const *ip)
{
  return ats_ip4_addr_cast(&ip->sa);
}

/** Access the IPv6 address.

    If this is not an IPv6 address a zero valued address is returned.
    @note This is direct access to the address so it will be in
    network order.

    @return A reference to the IPv6 address in @a addr.
*/
inline in6_addr &
ats_ip6_addr_cast(sockaddr *addr)
{
  return ats_ip6_cast(addr)->sin6_addr;
}
inline in6_addr const &
ats_ip6_addr_cast(sockaddr const *addr)
{
  return ats_ip6_cast(addr)->sin6_addr;
}
inline in6_addr &
ats_ip6_addr_cast(IpEndpoint *ip)
{
  return ip->sin6.sin6_addr;
}
inline in6_addr const &
ats_ip6_addr_cast(IpEndpoint const *ip)
{
  return ip->sin6.sin6_addr;
}

/** Cast an IP address to an array of @c uint32_t.
    @note The size of the array is dependent on the address type which
    must be checked independently of this function.
    @return A pointer to the address information in @a addr or @c nullptr
    if @a addr is not an IP address.
*/
inline uint32_t *
ats_ip_addr32_cast(sockaddr *addr)
{
  uint32_t *zret = nullptr;
  switch (addr->sa_family) {
  case AF_INET:
    zret = reinterpret_cast<uint32_t *>(&ats_ip4_addr_cast(addr));
    break;
  case AF_INET6:
    zret = reinterpret_cast<uint32_t *>(&ats_ip6_addr_cast(addr));
    break;
  }
  return zret;
}
inline uint32_t const *
ats_ip_addr32_cast(sockaddr const *addr)
{
  return ats_ip_addr32_cast(const_cast<sockaddr *>(addr));
}

/** Cast an IP address to an array of @c uint8_t.
    @note The size of the array is dependent on the address type which
    must be checked independently of this function.
    @return A pointer to the address information in @a addr or @c nullptr
    if @a addr is not an IP address.
    @see ats_ip_addr_size
*/
inline uint8_t *
ats_ip_addr8_cast(sockaddr *addr)
{
  uint8_t *zret = nullptr;
  switch (addr->sa_family) {
  case AF_INET:
    zret = reinterpret_cast<uint8_t *>(&ats_ip4_addr_cast(addr));
    break;
  case AF_INET6:
    zret = reinterpret_cast<uint8_t *>(&ats_ip6_addr_cast(addr));
    break;
  }
  return zret;
}
inline uint8_t const *
ats_ip_addr8_cast(sockaddr const *addr)
{
  return ats_ip_addr8_cast(const_cast<sockaddr *>(addr));
}
inline uint8_t *
ats_ip_addr8_cast(IpEndpoint *ip)
{
  return ats_ip_addr8_cast(&ip->sa);
}
inline uint8_t const *
ats_ip_addr8_cast(IpEndpoint const *ip)
{
  return ats_ip_addr8_cast(&ip->sa);
}

/// Check for loopback.
/// @return @c true if this is an IP loopback address, @c false otherwise.
inline bool
ats_is_ip_loopback(sockaddr const *ip)
{
  return ip && ((AF_INET == ip->sa_family && 0x7F == ats_ip_addr8_cast(ip)[0]) ||
                (AF_INET6 == ip->sa_family && IN6_IS_ADDR_LOOPBACK(&ats_ip6_addr_cast(ip))));
}

/// Check for loopback.
/// @return @c true if this is an IP loopback address, @c false otherwise.
inline bool
ats_is_ip_loopback(IpEndpoint const *ip)
{
  return ats_is_ip_loopback(&ip->sa);
}

/// Check for multicast.
/// @return @true if @a ip is multicast.
inline bool
ats_is_ip_multicast(sockaddr const *ip)
{
  return ip && ((AF_INET == ip->sa_family && 0xe == (ats_ip_addr8_cast(ip)[0] >> 4)) ||
                (AF_INET6 == ip->sa_family && IN6_IS_ADDR_MULTICAST(&ats_ip6_addr_cast(ip))));
}
/// Check for multicast.
/// @return @true if @a ip is multicast.
inline bool
ats_is_ip_multicast(IpEndpoint const *ip)
{
  return ats_is_ip_multicast(&ip->sa);
}

/// Check for Private.
/// @return @true if @a ip is private.
inline bool
ats_is_ip_private(sockaddr const *ip)
{
  bool zret = false;
  if (ats_is_ip4(ip)) {
    in_addr_t a = ats_ip4_addr_cast(ip);
    zret        = ((a & htonl(0xFF000000)) == htonl(0x0A000000)) || // 10.0.0.0/8
           ((a & htonl(0xFFC00000)) == htonl(0x64400000)) ||        // 100.64.0.0/10
           ((a & htonl(0xFFF00000)) == htonl(0xAC100000)) ||        // 172.16.0.0/12
           ((a & htonl(0xFFFF0000)) == htonl(0xC0A80000))           // 192.168.0.0/16
      ;
  } else if (ats_is_ip6(ip)) {
    in6_addr a = ats_ip6_addr_cast(ip);
    zret       = ((a.s6_addr[0] & 0xFE) == 0xFC) // fc00::/7
      ;
  }
  return zret;
}

/// Check for Private.
/// @return @true if @a ip is private.
inline bool
ats_is_ip_private(IpEndpoint const *ip)
{
  return ats_is_ip_private(&ip->sa);
}

/// Check for Link Local.
/// @return @true if @a ip is link local.
inline bool
ats_is_ip_linklocal(sockaddr const *ip)
{
  bool zret = false;
  if (ats_is_ip4(ip)) {
    in_addr_t a = ats_ip4_addr_cast(ip);
    zret        = ((a & htonl(0xFFFF0000)) == htonl(0xA9FE0000)) // 169.254.0.0/16
      ;
  } else if (ats_is_ip6(ip)) {
    in6_addr a = ats_ip6_addr_cast(ip);
    zret       = ((a.s6_addr[0] == 0xFE) && ((a.s6_addr[1] & 0xC0) == 0x80)) // fe80::/10
      ;
  }
  return zret;
}

/// Check for Link Local.
/// @return @true if @a ip is link local.
inline bool
ats_is_ip_linklocal(IpEndpoint const *ip)
{
  return ats_is_ip_linklocal(&ip->sa);
}

/// Check for being "any" address.
/// @return @c true if @a ip is the any / unspecified address.
inline bool
ats_is_ip_any(sockaddr const *ip)
{
  return (ats_is_ip4(ip) && INADDR_ANY == ats_ip4_addr_cast(ip)) ||
         (ats_is_ip6(ip) && IN6_IS_ADDR_UNSPECIFIED(&ats_ip6_addr_cast(ip)));
}

/// @name Address operators
//@{

/** Copy the address from @a src to @a dst if it's IP.
    This attempts to do a minimal copy based on the type of @a src.
    If @a src is not an IP address type it is @b not copied and
    @a dst is marked as invalid.
    @return @c true if @a src was an IP address, @c false otherwise.
*/
inline bool
ats_ip_copy(sockaddr *dst,      ///< Destination object.
            sockaddr const *src ///< Source object.
)
{
  size_t n = 0;
  if (src) {
    switch (src->sa_family) {
    case AF_INET:
      n = sizeof(sockaddr_in);
      break;
    case AF_INET6:
      n = sizeof(sockaddr_in6);
      break;
    }
  }
  if (n) {
    if (src != dst) {
      memcpy(dst, src, n);
#if HAVE_STRUCT_SOCKADDR_SA_LEN
      dst->sa_len = n;
#endif
    }
  } else {
    ats_ip_invalidate(dst);
  }
  return n != 0;
}

inline bool
ats_ip_copy(IpEndpoint *dst,    ///< Destination object.
            sockaddr const *src ///< Source object.
)
{
  return ats_ip_copy(&dst->sa, src);
}
inline bool
ats_ip_copy(IpEndpoint *dst,      ///< Destination object.
            IpEndpoint const *src ///< Source object.
)
{
  return ats_ip_copy(&dst->sa, &src->sa);
}
inline bool
ats_ip_copy(sockaddr *dst, IpEndpoint const *src)
{
  return ats_ip_copy(dst, &src->sa);
}

/** Compare two addresses.
    This is useful for IPv4, IPv6, and the unspecified address type.
    If the addresses are of different types they are ordered

    Non-IP < IPv4 < IPv6

     - all non-IP addresses are the same ( including @c AF_UNSPEC )
     - IPv4 addresses are compared numerically (host order)
     - IPv6 addresses are compared byte wise in network order (MSB to LSB)

    @return
      - -1 if @a lhs is less than @a rhs.
      - 0 if @a lhs is identical to @a rhs.
      - 1 if @a lhs is greater than @a rhs.

    @internal This looks like a lot of code for an inline but I think it
    should compile down to something reasonable.
*/
inline int
ats_ip_addr_cmp(sockaddr const *lhs, ///< Left hand operand.
                sockaddr const *rhs  ///< Right hand operand.
)
{
  int zret       = 0;
  uint16_t rtype = rhs->sa_family;
  uint16_t ltype = lhs->sa_family;

  // We lump all non-IP addresses into a single equivalence class
  // that is less than an IP address. This includes AF_UNSPEC.
  if (AF_INET == ltype) {
    if (AF_INET == rtype) {
      in_addr_t la = ntohl(ats_ip4_cast(lhs)->sin_addr.s_addr);
      in_addr_t ra = ntohl(ats_ip4_cast(rhs)->sin_addr.s_addr);
      if (la < ra)
        zret = -1;
      else if (la > ra)
        zret = 1;
      else
        zret = 0;
    } else if (AF_INET6 == rtype) { // IPv4 < IPv6
      zret = -1;
    } else { // IP > not IP
      zret = 1;
    }
  } else if (AF_INET6 == ltype) {
    if (AF_INET6 == rtype) {
      sockaddr_in6 const *lhs_in6 = ats_ip6_cast(lhs);
      zret                        = memcmp(&lhs_in6->sin6_addr, &ats_ip6_cast(rhs)->sin6_addr, sizeof(lhs_in6->sin6_addr));
    } else {
      zret = 1; // IPv6 greater than any other type.
    }
  } else if (AF_INET == rtype || AF_INET6 == rtype) {
    // ltype is non-IP so it's less than either IP type.
    zret = -1;
  } else {
    // Both types are non-IP so they're equal.
    zret = 0;
  }

  return zret;
}

/** Compare two addresses.
    @note Convenience overload.
    @see ats_ip_addr_cmp(sockaddr const* lhs, sockaddr const* rhs)
*/
inline int
ats_ip_addr_cmp(IpEndpoint const *lhs, IpEndpoint const *rhs)
{
  return ats_ip_addr_cmp(&lhs->sa, &rhs->sa);
}

/** Check if two addresses are equal.
    @return @c true if @a lhs and @a rhs point to equal addresses,
    @c false otherwise.
*/
inline bool
ats_ip_addr_eq(sockaddr const *lhs, sockaddr const *rhs)
{
  return 0 == ats_ip_addr_cmp(lhs, rhs);
}
inline bool
ats_ip_addr_eq(IpEndpoint const *lhs, IpEndpoint const *rhs)
{
  return 0 == ats_ip_addr_cmp(&lhs->sa, &rhs->sa);
}

inline bool
operator==(IpEndpoint const &lhs, IpEndpoint const &rhs)
{
  return 0 == ats_ip_addr_cmp(&lhs.sa, &rhs.sa);
}
inline bool
operator!=(IpEndpoint const &lhs, IpEndpoint const &rhs)
{
  return 0 != ats_ip_addr_cmp(&lhs.sa, &rhs.sa);
}

/// Compare address and port for equality.
inline bool
ats_ip_addr_port_eq(sockaddr const *lhs, sockaddr const *rhs)
{
  bool zret = false;
  if (lhs->sa_family == rhs->sa_family && ats_ip_port_cast(lhs) == ats_ip_port_cast(rhs)) {
    if (AF_INET == lhs->sa_family)
      zret = ats_ip4_cast(lhs)->sin_addr.s_addr == ats_ip4_cast(rhs)->sin_addr.s_addr;
    else if (AF_INET6 == lhs->sa_family)
      zret = 0 == memcmp(&ats_ip6_cast(lhs)->sin6_addr, &ats_ip6_cast(rhs)->sin6_addr, sizeof(in6_addr));
  }
  return zret;
}

//@}

/// Get IP TCP/UDP port.
/// @return The port in host order for an IPv4 or IPv6 address,
/// or zero if neither.
inline in_port_t
ats_ip_port_host_order(sockaddr const *addr ///< Address with port.
)
{
  // We can discard the const because this function returns
  // by value.
  return ntohs(ats_ip_port_cast(const_cast<sockaddr *>(addr)));
}

/// Get IP TCP/UDP port.
/// @return The port in host order for an IPv4 or IPv6 address,
/// or zero if neither.
inline in_port_t
ats_ip_port_host_order(IpEndpoint const *ip ///< Address with port.
)
{
  // We can discard the const because this function returns
  // by value.
  return ntohs(ats_ip_port_cast(const_cast<sockaddr *>(&ip->sa)));
}

/** Extract the IPv4 address.
    @return Host order IPv4 address.
*/
inline in_addr_t
ats_ip4_addr_host_order(sockaddr const *addr ///< Address object.
)
{
  return ntohl(ats_ip4_addr_cast(const_cast<sockaddr *>(addr)));
}

/// Write IPv4 data to storage @a dst.
inline sockaddr *
ats_ip4_set(sockaddr_in *dst,  ///< Destination storage.
            in_addr_t addr,    ///< address, IPv4 network order.
            in_port_t port = 0 ///< port, network order.
)
{
  ink_zero(*dst);
#if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
  dst->sin_len = sizeof(sockaddr_in);
#endif
  dst->sin_family      = AF_INET;
  dst->sin_addr.s_addr = addr;
  dst->sin_port        = port;
  return ats_ip_sa_cast(dst);
}

/** Write IPv4 data to @a dst.
    @note Convenience overload.
*/
inline sockaddr *
ats_ip4_set(IpEndpoint *dst,   ///< Destination storage.
            in_addr_t ip4,     ///< address, IPv4 network order.
            in_port_t port = 0 ///< port, network order.
)
{
  return ats_ip4_set(&dst->sin, ip4, port);
}

/** Write IPv4 data to storage @a dst.

    This is the generic overload. Caller must verify that @a dst is at
    least @c sizeof(sockaddr_in) bytes.
*/
inline sockaddr *
ats_ip4_set(sockaddr *dst,     ///< Destination storage.
            in_addr_t ip4,     ///< address, IPv4 network order.
            in_port_t port = 0 ///< port, network order.
)
{
  return ats_ip4_set(ats_ip4_cast(dst), ip4, port);
}
/** Write IPv6 data to storage @a dst.
    @return @a dst cast to @c sockaddr*.
 */
inline sockaddr *
ats_ip6_set(sockaddr_in6 *dst,    ///< Destination storage.
            in6_addr const &addr, ///< address in network order.
            in_port_t port = 0    ///< Port, network order.
)
{
  ink_zero(*dst);
#if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
  dst->sin6_len = sizeof(sockaddr_in6);
#endif
  dst->sin6_family = AF_INET6;
  memcpy(&dst->sin6_addr, &addr, sizeof addr);
  dst->sin6_port = port;
  return ats_ip_sa_cast(dst);
}
/** Write IPv6 data to storage @a dst.
    @return @a dst cast to @c sockaddr*.
 */
inline sockaddr *
ats_ip6_set(sockaddr *dst,        ///< Destination storage.
            in6_addr const &addr, ///< address in network order.
            in_port_t port = 0    ///< Port, network order.
)
{
  return ats_ip6_set(ats_ip6_cast(dst), addr, port);
}
/** Write IPv6 data to storage @a dst.
    @return @a dst cast to @c sockaddr*.
 */
inline sockaddr *
ats_ip6_set(IpEndpoint *dst,      ///< Destination storage.
            in6_addr const &addr, ///< address in network order.
            in_port_t port = 0    ///< Port, network order.
)
{
  return ats_ip6_set(&dst->sin6, addr, port);
}

/** Write a null terminated string for @a addr to @a dst.
    A buffer of size INET6_ADDRSTRLEN suffices, including a terminating nul.
 */
const char *ats_ip_ntop(const sockaddr *addr, ///< Address.
                        char *dst,            ///< Output buffer.
                        size_t size           ///< Length of buffer.
);

/** Write a null terminated string for @a addr to @a dst.
    A buffer of size INET6_ADDRSTRLEN suffices, including a terminating nul.
 */
inline const char *
ats_ip_ntop(IpEndpoint const *addr, ///< Address.
            char *dst,              ///< Output buffer.
            size_t size             ///< Length of buffer.
)
{
  return ats_ip_ntop(&addr->sa, dst, size);
}

/// Buffer size sufficient for IPv6 address and port.
static size_t const INET6_ADDRPORTSTRLEN = INET6_ADDRSTRLEN + 6;
/// Convenience type for address formatting.
typedef char ip_text_buffer[INET6_ADDRSTRLEN];
/// Convenience type for address formatting.
typedef char ip_port_text_buffer[INET6_ADDRPORTSTRLEN];

/** Write a null terminated string for @a addr to @a dst with port.
    A buffer of size INET6_ADDRPORTSTRLEN suffices, including a terminating nul.
 */
const char *ats_ip_nptop(const sockaddr *addr, ///< Address.
                         char *dst,            ///< Output buffer.
                         size_t size           ///< Length of buffer.
);

/** Write a null terminated string for @a addr to @a dst with port.
    A buffer of size INET6_ADDRPORTSTRLEN suffices, including a terminating nul.
 */
inline const char *
ats_ip_nptop(IpEndpoint const *addr, ///< Address.
             char *dst,              ///< Output buffer.
             size_t size             ///< Length of buffer.
)
{
  return ats_ip_nptop(&addr->sa, dst, size);
}

/** Convert @a text to an IP address and write it to @a addr.

    @a text is expected to be an explicit address, not a hostname.  No
    hostname resolution is done. The call must provide an @a ip large
    enough to hold the address value.

    This attempts to recognize and process a port value if
    present. The port in @a ip is set appropriately, or to zero if no
    port was found or it was malformed.

    @note The return values are logically reversed from @c inet_pton.
    @note This uses @c getaddrinfo internally and so involves memory
    allocation.

    @return 0 on success, non-zero on failure.
*/
int ats_ip_pton(const std::string_view &text, ///< [in] text.
                sockaddr *addr                ///< [out] address
);

/** Convert @a text to an IP address and write it to @a addr.

    @a text is expected to be an explicit address, not a hostname.  No
    hostname resolution is done.

    @note This uses @c getaddrinfo internally and so involves memory
    allocation.
    @note Convenience overload.

    @return 0 on success, non-zero on failure.
*/
inline int
ats_ip_pton(const char *text,  ///< [in] text.
            sockaddr_in6 *addr ///< [out] address
)
{
  return ats_ip_pton(std::string_view(text, strlen(text)), ats_ip_sa_cast(addr));
}

inline int
ats_ip_pton(const std::string_view &text, ///< [in] text.
            IpEndpoint *addr              ///< [out] address
)
{
  return ats_ip_pton(text, &addr->sa);
}

inline int
ats_ip_pton(const char *text, ///< [in] text.
            IpEndpoint *addr  ///< [out] address
)
{
  return ats_ip_pton(std::string_view(text, strlen(text)), &addr->sa);
}

inline int
ats_ip_pton(const char *text, ///< [in] text.
            sockaddr *addr    ///< [out] address
)
{
  return ats_ip_pton(std::string_view(text, strlen(text)), addr);
}

/** Get the best address info for @a name.

    @name is passed to @c getaddrinfo which does a host lookup if @a
    name is not in IP address format. The results are examined for the
    "best" addresses. This is only significant for the host name case
    (for IP address data, there is at most one result). The preference is
    Global > Non-Routable > Multicast > Loopback.

    IPv4 and IPv4 results are handled independently and stored in @a
    ip4 and @a ip6 respectively. If @a name is known to be a numeric
    IP address @c ats_ip_pton is a better choice. Use this function
    if the type of @a name is not known. If you want to look at the
    addresses and not just get the "best", use @c getaddrinfo
    directly.

    @a ip4 or @a ip6 can be @c nullptr and the result for that family is
    discarded. It is legal for both to be @c nullptr in which case this
    is just a format check.

    @return 0 if an address was found, non-zero otherwise.

    @see ats_ip_pton
    @see getaddrinfo
 */

int ats_ip_getbestaddrinfo(const char *name, ///< [in] Address name (IPv4, IPv6, or host name)
                           IpEndpoint *ip4,  ///< [out] Storage for IPv4 address.
                           IpEndpoint *ip6   ///< [out] Storage for IPv6 address
);

/** Generic IP address hash function.
 */
uint32_t ats_ip_hash(sockaddr const *addr);

uint64_t ats_ip_port_hash(sockaddr const *addr);

/** Convert address to string as a hexidecimal value.
    The string is always nul terminated, the output string is clipped
    if @a dst is insufficient.
    @return The length of the resulting string (not including nul).
*/
int ats_ip_to_hex(sockaddr const *addr, ///< Address to convert. Must be IP.
                  char *dst,            ///< Destination buffer.
                  size_t len            ///< Length of @a dst.
);

/** Storage for an IP address.
    In some cases we want to store just the address and not the
    ancillary information (such as port, or flow data).
    @note This is not easily used as an address for system calls.
*/
struct IpAddr {
  typedef IpAddr self; ///< Self reference type.

  /// Default construct (invalid address).
  IpAddr() {}

  /** Construct from IPv4 address.
   *
   * @param addr Source address.
   */
  explicit constexpr IpAddr(in_addr_t addr) : _family(AF_INET), _addr(addr) {}

  /** Construct from IPv6 address.
   *
   * @param addr Source address.
   */
  explicit constexpr IpAddr(in6_addr const &addr) : _family(AF_INET6), _addr(addr) {}

  /// Construct from @c sockaddr.
  explicit IpAddr(sockaddr const *addr) { this->assign(addr); }
  /// Construct from @c sockaddr_in6.
  explicit IpAddr(sockaddr_in6 const &addr) { this->assign(ats_ip_sa_cast(&addr)); }
  /// Construct from @c sockaddr_in6.
  explicit IpAddr(sockaddr_in6 const *addr) { this->assign(ats_ip_sa_cast(addr)); }
  /// Construct from @c IpEndpoint.
  explicit IpAddr(IpEndpoint const &addr) { this->assign(&addr.sa); }
  /// Construct from @c IpEndpoint.
  explicit IpAddr(IpEndpoint const *addr) { this->assign(&addr->sa); }
  /// Assign sockaddr storage.
  self &assign(sockaddr const *addr ///< May be @c nullptr
  );

  /// Assign from end point.
  self &
  operator=(IpEndpoint const &ip)
  {
    return this->assign(&ip.sa);
  }
  /// Assign from IPv4 raw address.
  /// @param ip Network order IPv4 address.
  self &operator=(in_addr_t ip);

  /// Assign from IPv6 raw address.
  self &operator=(in6_addr const &ip);

  /** Load from string.
      The address is copied to this object if the conversion is successful,
      otherwise this object is invalidated.
      @return 0 on success, non-zero on failure.
  */
  int load(const char *str ///< Nul terminated input string.
  );

  /** Load from string.
      The address is copied to this object if the conversion is successful,
      otherwise this object is invalidated.
      @return 0 on success, non-zero on failure.
  */
  int load(std::string_view const &str ///< Text of IP address.
  );

  /** Output to a string.
      @return The string @a dest.
  */
  char *toString(char *dest, ///< [out] Destination string buffer.
                 size_t len  ///< [in] Size of buffer.
  ) const;

  /// Equality.
  bool
  operator==(self const &that) const
  {
    return _family == AF_INET ?
             (that._family == AF_INET && _addr._ip4 == that._addr._ip4) :
             _family == AF_INET6 ? (that._family == AF_INET6 && 0 == memcmp(&_addr._ip6, &that._addr._ip6, TS_IP6_SIZE)) :
                                   (_family == AF_UNSPEC && that._family == AF_UNSPEC);
  }

  /// Inequality.
  bool
  operator!=(self const &that) const
  {
    return !(*this == that);
  }

  /// Generic compare.
  int cmp(self const &that) const;

  /** Return a normalized hash value.
      - Ipv4: the address in host order.
      - Ipv6: folded 32 bit of the address.
      - Else: 0.
  */
  uint32_t hash() const;

  /** The hashing function embedded in a functor.
      @see hash
  */
  struct Hasher {
    uint32_t
    operator()(self const &ip) const
    {
      return ip.hash();
    }
  };

  /// Test for same address family.
  /// @c return @c true if @a that is the same address family as @a this.
  bool isCompatibleWith(self const &that);

  /// Get the address family.
  /// @return The address family.
  uint16_t family() const;
  /// Test for IPv4.
  bool isIp4() const;
  /// Test for IPv6.
  bool isIp6() const;

  /// Test for validity.
  bool
  isValid() const
  {
    return _family == AF_INET || _family == AF_INET6;
  }
  /// Make invalid.
  self &
  invalidate()
  {
    _family = AF_UNSPEC;
    return *this;
  }
  /// Test for multicast
  bool isMulticast() const;
  /// Test for loopback
  bool isLoopback() const;

  /// Test for any addr
  bool isAnyAddr() const;

  uint16_t _family = AF_UNSPEC; ///< Protocol family.
  /// Address data.
  union Addr {
    in_addr_t _ip4;                                                    ///< IPv4 address storage.
    in6_addr _ip6;                                                     ///< IPv6 address storage.
    uint8_t _byte[TS_IP6_SIZE];                                        ///< As raw bytes.
    uint32_t _u32[TS_IP6_SIZE / (sizeof(uint32_t) / sizeof(uint8_t))]; ///< As 32 bit chunks.
    uint64_t _u64[TS_IP6_SIZE / (sizeof(uint64_t) / sizeof(uint8_t))]; ///< As 64 bit chunks.

    // This is required by the @c constexpr constructor.
    constexpr Addr() : _ip4(0) {}
    constexpr Addr(in_addr_t addr) : _ip4(addr) {}
    constexpr Addr(in6_addr const &addr) : _ip6(addr) {}
  } _addr;

  ///< Pre-constructed invalid instance.
  static self const INVALID;
};

inline IpAddr &
IpAddr::operator=(in_addr_t ip)
{
  _family    = AF_INET;
  _addr._ip4 = ip;
  return *this;
}

inline IpAddr &
IpAddr::operator=(in6_addr const &ip)
{
  _family    = AF_INET6;
  _addr._ip6 = ip;
  return *this;
}

inline uint16_t
IpAddr::family() const
{
  return _family;
}

inline bool
IpAddr::isCompatibleWith(self const &that)
{
  return this->isValid() && _family == that._family;
}

inline bool
IpAddr::isIp4() const
{
  return AF_INET == _family;
}
inline bool
IpAddr::isIp6() const
{
  return AF_INET6 == _family;
}

inline bool
IpAddr::isLoopback() const
{
  return (AF_INET == _family && 0x7F == _addr._byte[0]) || (AF_INET6 == _family && IN6_IS_ADDR_LOOPBACK(&_addr._ip6));
}

inline bool
IpAddr::isAnyAddr() const
{
  return (AF_INET == _family && INADDR_ANY == _addr._ip4) || (AF_INET6 == _family && IN6_IS_ADDR_UNSPECIFIED(&_addr._ip6));
}

/// Assign sockaddr storage.
inline IpAddr &
IpAddr::assign(sockaddr const *addr)
{
  if (addr) {
    _family = addr->sa_family;
    if (ats_is_ip4(addr)) {
      _addr._ip4 = ats_ip4_addr_cast(addr);
    } else if (ats_is_ip6(addr)) {
      _addr._ip6 = ats_ip6_addr_cast(addr);
    } else {
      _family = AF_UNSPEC;
    }
  } else {
    _family = AF_UNSPEC;
  }
  return *this;
}

// Associated operators.
bool operator==(IpAddr const &lhs, sockaddr const *rhs);
inline bool
operator==(sockaddr const *lhs, IpAddr const &rhs)
{
  return rhs == lhs;
}
inline bool
operator!=(IpAddr const &lhs, sockaddr const *rhs)
{
  return !(lhs == rhs);
}
inline bool
operator!=(sockaddr const *lhs, IpAddr const &rhs)
{
  return !(rhs == lhs);
}
inline bool
operator==(IpAddr const &lhs, IpEndpoint const &rhs)
{
  return lhs == &rhs.sa;
}
inline bool
operator==(IpEndpoint const &lhs, IpAddr const &rhs)
{
  return &lhs.sa == rhs;
}
inline bool
operator!=(IpAddr const &lhs, IpEndpoint const &rhs)
{
  return !(lhs == &rhs.sa);
}
inline bool
operator!=(IpEndpoint const &lhs, IpAddr const &rhs)
{
  return !(rhs == &lhs.sa);
}

inline bool
operator<(IpAddr const &lhs, IpAddr const &rhs)
{
  return -1 == lhs.cmp(rhs);
}

inline bool
operator>=(IpAddr const &lhs, IpAddr const &rhs)
{
  return lhs.cmp(rhs) >= 0;
}

inline bool
operator>(IpAddr const &lhs, IpAddr const &rhs)
{
  return 1 == lhs.cmp(rhs);
}

inline bool
operator<=(IpAddr const &lhs, IpAddr const &rhs)
{
  return lhs.cmp(rhs) <= 0;
}

inline uint32_t
IpAddr::hash() const
{
  uint32_t zret = 0;
  if (this->isIp4()) {
    zret = ntohl(_addr._ip4);
  } else if (this->isIp6()) {
    zret = _addr._u32[0] ^ _addr._u32[1] ^ _addr._u32[2] ^ _addr._u32[3];
  }
  return zret;
}

/// Write IP @a addr to storage @a dst.
/// @return @s dst.
sockaddr *ats_ip_set(sockaddr *dst,      ///< Destination storage.
                     IpAddr const &addr, ///< source address.
                     in_port_t port = 0  ///< port, network order.
);

/** Convert @a text to an IP address and write it to @a addr.
    Convenience overload.
    @return 0 on success, non-zero on failure.
*/
inline int
ats_ip_pton(const char *text, ///< [in] text.
            IpAddr &addr      ///< [out] address
)
{
  return addr.load(text) ? 0 : -1;
}

int ats_ip_range_parse(std::string_view src, IpAddr &lower, IpAddr &upper);

inline IpEndpoint &
IpEndpoint::assign(IpAddr const &addr, in_port_t port)
{
  ats_ip_set(&sa, addr, port);
  return *this;
}

inline IpEndpoint &
IpEndpoint::assign(sockaddr const *ip)
{
  ats_ip_copy(&sa, ip);
  return *this;
}

inline in_port_t &
IpEndpoint::port()
{
  return ats_ip_port_cast(&sa);
}

inline in_port_t
IpEndpoint::port() const
{
  return ats_ip_port_cast(&sa);
}

inline in_port_t
IpEndpoint::host_order_port() const
{
  return ntohs(this->port());
}

inline bool
IpEndpoint::isValid() const
{
  return ats_is_ip(this);
}

inline bool
IpEndpoint::isIp4() const
{
  return AF_INET == sa.sa_family;
}
inline bool
IpEndpoint::isIp6() const
{
  return AF_INET6 == sa.sa_family;
}
inline uint16_t
IpEndpoint::family() const
{
  return sa.sa_family;
}

inline IpEndpoint &
IpEndpoint::setToAnyAddr(int family)
{
  ink_zero(*this);
  sa.sa_family = family;
  if (AF_INET == family) {
    sin.sin_addr.s_addr = INADDR_ANY;
#if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
    sin.sin_len = sizeof(sockaddr_in);
#endif
  } else if (AF_INET6 == family) {
    sin6.sin6_addr = in6addr_any;
#if HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
    sin6.sin6_len = sizeof(sockaddr_in6);
#endif
  }
  return *this;
}

inline IpEndpoint &
IpEndpoint::setToLoopback(int family)
{
  ink_zero(*this);
  sa.sa_family = family;
  if (AF_INET == family) {
    sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
#if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
    sin.sin_len = sizeof(sockaddr_in);
#endif
  } else if (AF_INET6 == family) {
    static const struct in6_addr init = IN6ADDR_LOOPBACK_INIT;
    sin6.sin6_addr                    = init;
#if HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
    sin6.sin6_len = sizeof(sockaddr_in6);
#endif
  }
  return *this;
}

// BufferWriter formatting support.
namespace ts
{
BufferWriter &bwformat(BufferWriter &w, BWFSpec const &spec, IpAddr const &addr);
BufferWriter &bwformat(BufferWriter &w, BWFSpec const &spec, sockaddr const *addr);
inline BufferWriter &
bwformat(BufferWriter &w, BWFSpec const &spec, IpEndpoint const &addr)
{
  return bwformat(w, spec, &addr.sa);
}

namespace bwf
{
  namespace detail
  {
    struct MemDump;
  } // namespace detail

  detail::MemDump Hex_Dump(IpEndpoint const &addr);
} // namespace bwf
} // namespace ts
