diff options
Diffstat (limited to 'lib/asio/ip')
41 files changed, 7847 insertions, 0 deletions
diff --git a/lib/asio/ip/address.hpp b/lib/asio/ip/address.hpp new file mode 100644 index 0000000..cf852a6 --- /dev/null +++ b/lib/asio/ip/address.hpp @@ -0,0 +1,260 @@ +// +// ip/address.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_ADDRESS_HPP +#define ASIO_IP_ADDRESS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include <string> +#include "asio/detail/throw_exception.hpp" +#include "asio/detail/string_view.hpp" +#include "asio/detail/type_traits.hpp" +#include "asio/error_code.hpp" +#include "asio/ip/address_v4.hpp" +#include "asio/ip/address_v6.hpp" +#include "asio/ip/bad_address_cast.hpp" + +#if !defined(ASIO_NO_IOSTREAM) +# include <iosfwd> +#endif // !defined(ASIO_NO_IOSTREAM) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// Implements version-independent IP addresses. +/** + * The asio::ip::address class provides the ability to use either IP + * version 4 or version 6 addresses. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +class address +{ +public: + /// Default constructor. + ASIO_DECL address(); + + /// Construct an address from an IPv4 address. + ASIO_DECL address(const asio::ip::address_v4& ipv4_address); + + /// Construct an address from an IPv6 address. + ASIO_DECL address(const asio::ip::address_v6& ipv6_address); + + /// Copy constructor. + ASIO_DECL address(const address& other); + +#if defined(ASIO_HAS_MOVE) + /// Move constructor. + ASIO_DECL address(address&& other); +#endif // defined(ASIO_HAS_MOVE) + + /// Assign from another address. + ASIO_DECL address& operator=(const address& other); + +#if defined(ASIO_HAS_MOVE) + /// Move-assign from another address. + ASIO_DECL address& operator=(address&& other); +#endif // defined(ASIO_HAS_MOVE) + + /// Assign from an IPv4 address. + ASIO_DECL address& operator=( + const asio::ip::address_v4& ipv4_address); + + /// Assign from an IPv6 address. + ASIO_DECL address& operator=( + const asio::ip::address_v6& ipv6_address); + + /// Get whether the address is an IP version 4 address. + bool is_v4() const + { + return type_ == ipv4; + } + + /// Get whether the address is an IP version 6 address. + bool is_v6() const + { + return type_ == ipv6; + } + + /// Get the address as an IP version 4 address. + ASIO_DECL asio::ip::address_v4 to_v4() const; + + /// Get the address as an IP version 6 address. + ASIO_DECL asio::ip::address_v6 to_v6() const; + + /// Get the address as a string. + ASIO_DECL std::string to_string() const; + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use other overload.) Get the address as a string. + ASIO_DECL std::string to_string(asio::error_code& ec) const; + + /// (Deprecated: Use make_address().) Create an address from an IPv4 address + /// string in dotted decimal form, or from an IPv6 address in hexadecimal + /// notation. + static address from_string(const char* str); + + /// (Deprecated: Use make_address().) Create an address from an IPv4 address + /// string in dotted decimal form, or from an IPv6 address in hexadecimal + /// notation. + static address from_string(const char* str, asio::error_code& ec); + + /// (Deprecated: Use make_address().) Create an address from an IPv4 address + /// string in dotted decimal form, or from an IPv6 address in hexadecimal + /// notation. + static address from_string(const std::string& str); + + /// (Deprecated: Use make_address().) Create an address from an IPv4 address + /// string in dotted decimal form, or from an IPv6 address in hexadecimal + /// notation. + static address from_string( + const std::string& str, asio::error_code& ec); +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Determine whether the address is a loopback address. + ASIO_DECL bool is_loopback() const; + + /// Determine whether the address is unspecified. + ASIO_DECL bool is_unspecified() const; + + /// Determine whether the address is a multicast address. + ASIO_DECL bool is_multicast() const; + + /// Compare two addresses for equality. + ASIO_DECL friend bool operator==(const address& a1, const address& a2); + + /// Compare two addresses for inequality. + friend bool operator!=(const address& a1, const address& a2) + { + return !(a1 == a2); + } + + /// Compare addresses for ordering. + ASIO_DECL friend bool operator<(const address& a1, const address& a2); + + /// Compare addresses for ordering. + friend bool operator>(const address& a1, const address& a2) + { + return a2 < a1; + } + + /// Compare addresses for ordering. + friend bool operator<=(const address& a1, const address& a2) + { + return !(a2 < a1); + } + + /// Compare addresses for ordering. + friend bool operator>=(const address& a1, const address& a2) + { + return !(a1 < a2); + } + +private: + // The type of the address. + enum { ipv4, ipv6 } type_; + + // The underlying IPv4 address. + asio::ip::address_v4 ipv4_address_; + + // The underlying IPv6 address. + asio::ip::address_v6 ipv6_address_; +}; + +/// Create an address from an IPv4 address string in dotted decimal form, +/// or from an IPv6 address in hexadecimal notation. +/** + * @relates address + */ +ASIO_DECL address make_address(const char* str); + +/// Create an address from an IPv4 address string in dotted decimal form, +/// or from an IPv6 address in hexadecimal notation. +/** + * @relates address + */ +ASIO_DECL address make_address( + const char* str, asio::error_code& ec); + +/// Create an address from an IPv4 address string in dotted decimal form, +/// or from an IPv6 address in hexadecimal notation. +/** + * @relates address + */ +ASIO_DECL address make_address(const std::string& str); + +/// Create an address from an IPv4 address string in dotted decimal form, +/// or from an IPv6 address in hexadecimal notation. +/** + * @relates address + */ +ASIO_DECL address make_address( + const std::string& str, asio::error_code& ec); + +#if defined(ASIO_HAS_STRING_VIEW) \ + || defined(GENERATING_DOCUMENTATION) + +/// Create an address from an IPv4 address string in dotted decimal form, +/// or from an IPv6 address in hexadecimal notation. +/** + * @relates address + */ +ASIO_DECL address make_address(string_view str); + +/// Create an address from an IPv4 address string in dotted decimal form, +/// or from an IPv6 address in hexadecimal notation. +/** + * @relates address + */ +ASIO_DECL address make_address( + string_view str, asio::error_code& ec); + +#endif // defined(ASIO_HAS_STRING_VIEW) + // || defined(GENERATING_DOCUMENTATION) + +#if !defined(ASIO_NO_IOSTREAM) + +/// Output an address as a string. +/** + * Used to output a human-readable string for a specified address. + * + * @param os The output stream to which the string will be written. + * + * @param addr The address to be written. + * + * @return The output stream. + * + * @relates asio::ip::address + */ +template <typename Elem, typename Traits> +std::basic_ostream<Elem, Traits>& operator<<( + std::basic_ostream<Elem, Traits>& os, const address& addr); + +#endif // !defined(ASIO_NO_IOSTREAM) + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/ip/impl/address.hpp" +#if defined(ASIO_HEADER_ONLY) +# include "asio/ip/impl/address.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_IP_ADDRESS_HPP diff --git a/lib/asio/ip/address_v4.hpp b/lib/asio/ip/address_v4.hpp new file mode 100644 index 0000000..4e1cc9a --- /dev/null +++ b/lib/asio/ip/address_v4.hpp @@ -0,0 +1,329 @@ +// +// ip/address_v4.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_ADDRESS_V4_HPP +#define ASIO_IP_ADDRESS_V4_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include <string> +#include "asio/detail/array.hpp" +#include "asio/detail/cstdint.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/string_view.hpp" +#include "asio/detail/winsock_init.hpp" +#include "asio/error_code.hpp" + +#if !defined(ASIO_NO_IOSTREAM) +# include <iosfwd> +#endif // !defined(ASIO_NO_IOSTREAM) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// Implements IP version 4 style addresses. +/** + * The asio::ip::address_v4 class provides the ability to use and + * manipulate IP version 4 addresses. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +class address_v4 +{ +public: + /// The type used to represent an address as an unsigned integer. + typedef uint_least32_t uint_type; + + /// The type used to represent an address as an array of bytes. + /** + * @note This type is defined in terms of the C++0x template @c std::array + * when it is available. Otherwise, it uses @c boost:array. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef array<unsigned char, 4> bytes_type; +#else + typedef asio::detail::array<unsigned char, 4> bytes_type; +#endif + + /// Default constructor. + address_v4() + { + addr_.s_addr = 0; + } + + /// Construct an address from raw bytes. + ASIO_DECL explicit address_v4(const bytes_type& bytes); + + /// Construct an address from an unsigned integer in host byte order. + ASIO_DECL explicit address_v4(uint_type addr); + + /// Copy constructor. + address_v4(const address_v4& other) + : addr_(other.addr_) + { + } + +#if defined(ASIO_HAS_MOVE) + /// Move constructor. + address_v4(address_v4&& other) + : addr_(other.addr_) + { + } +#endif // defined(ASIO_HAS_MOVE) + + /// Assign from another address. + address_v4& operator=(const address_v4& other) + { + addr_ = other.addr_; + return *this; + } + +#if defined(ASIO_HAS_MOVE) + /// Move-assign from another address. + address_v4& operator=(address_v4&& other) + { + addr_ = other.addr_; + return *this; + } +#endif // defined(ASIO_HAS_MOVE) + + /// Get the address in bytes, in network byte order. + ASIO_DECL bytes_type to_bytes() const; + + /// Get the address as an unsigned integer in host byte order + ASIO_DECL uint_type to_uint() const; + +#if !defined(ASIO_NO_DEPRECATED) + /// Get the address as an unsigned long in host byte order + ASIO_DECL unsigned long to_ulong() const; +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Get the address as a string in dotted decimal format. + ASIO_DECL std::string to_string() const; + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use other overload.) Get the address as a string in dotted + /// decimal format. + ASIO_DECL std::string to_string(asio::error_code& ec) const; + + /// (Deprecated: Use make_address_v4().) Create an address from an IP address + /// string in dotted decimal form. + static address_v4 from_string(const char* str); + + /// (Deprecated: Use make_address_v4().) Create an address from an IP address + /// string in dotted decimal form. + static address_v4 from_string( + const char* str, asio::error_code& ec); + + /// (Deprecated: Use make_address_v4().) Create an address from an IP address + /// string in dotted decimal form. + static address_v4 from_string(const std::string& str); + + /// (Deprecated: Use make_address_v4().) Create an address from an IP address + /// string in dotted decimal form. + static address_v4 from_string( + const std::string& str, asio::error_code& ec); +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Determine whether the address is a loopback address. + ASIO_DECL bool is_loopback() const; + + /// Determine whether the address is unspecified. + ASIO_DECL bool is_unspecified() const; + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use network_v4 class.) Determine whether the address is a + /// class A address. + ASIO_DECL bool is_class_a() const; + + /// (Deprecated: Use network_v4 class.) Determine whether the address is a + /// class B address. + ASIO_DECL bool is_class_b() const; + + /// (Deprecated: Use network_v4 class.) Determine whether the address is a + /// class C address. + ASIO_DECL bool is_class_c() const; +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Determine whether the address is a multicast address. + ASIO_DECL bool is_multicast() const; + + /// Compare two addresses for equality. + friend bool operator==(const address_v4& a1, const address_v4& a2) + { + return a1.addr_.s_addr == a2.addr_.s_addr; + } + + /// Compare two addresses for inequality. + friend bool operator!=(const address_v4& a1, const address_v4& a2) + { + return a1.addr_.s_addr != a2.addr_.s_addr; + } + + /// Compare addresses for ordering. + friend bool operator<(const address_v4& a1, const address_v4& a2) + { + return a1.to_uint() < a2.to_uint(); + } + + /// Compare addresses for ordering. + friend bool operator>(const address_v4& a1, const address_v4& a2) + { + return a1.to_uint() > a2.to_uint(); + } + + /// Compare addresses for ordering. + friend bool operator<=(const address_v4& a1, const address_v4& a2) + { + return a1.to_uint() <= a2.to_uint(); + } + + /// Compare addresses for ordering. + friend bool operator>=(const address_v4& a1, const address_v4& a2) + { + return a1.to_uint() >= a2.to_uint(); + } + + /// Obtain an address object that represents any address. + static address_v4 any() + { + return address_v4(); + } + + /// Obtain an address object that represents the loopback address. + static address_v4 loopback() + { + return address_v4(0x7F000001); + } + + /// Obtain an address object that represents the broadcast address. + static address_v4 broadcast() + { + return address_v4(0xFFFFFFFF); + } + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use network_v4 class.) Obtain an address object that + /// represents the broadcast address that corresponds to the specified + /// address and netmask. + ASIO_DECL static address_v4 broadcast( + const address_v4& addr, const address_v4& mask); + + /// (Deprecated: Use network_v4 class.) Obtain the netmask that corresponds + /// to the address, based on its address class. + ASIO_DECL static address_v4 netmask(const address_v4& addr); +#endif // !defined(ASIO_NO_DEPRECATED) + +private: + // The underlying IPv4 address. + asio::detail::in4_addr_type addr_; +}; + +/// Create an IPv4 address from raw bytes in network order. +/** + * @relates address_v4 + */ +inline address_v4 make_address_v4(const address_v4::bytes_type& bytes) +{ + return address_v4(bytes); +} + +/// Create an IPv4 address from an unsigned integer in host byte order. +/** + * @relates address_v4 + */ +inline address_v4 make_address_v4(address_v4::uint_type addr) +{ + return address_v4(addr); +} + +/// Create an IPv4 address from an IP address string in dotted decimal form. +/** + * @relates address_v4 + */ +ASIO_DECL address_v4 make_address_v4(const char* str); + +/// Create an IPv4 address from an IP address string in dotted decimal form. +/** + * @relates address_v4 + */ +ASIO_DECL address_v4 make_address_v4( + const char* str, asio::error_code& ec); + +/// Create an IPv4 address from an IP address string in dotted decimal form. +/** + * @relates address_v4 + */ +ASIO_DECL address_v4 make_address_v4(const std::string& str); + +/// Create an IPv4 address from an IP address string in dotted decimal form. +/** + * @relates address_v4 + */ +ASIO_DECL address_v4 make_address_v4( + const std::string& str, asio::error_code& ec); + +#if defined(ASIO_HAS_STRING_VIEW) \ + || defined(GENERATING_DOCUMENTATION) + +/// Create an IPv4 address from an IP address string in dotted decimal form. +/** + * @relates address_v4 + */ +ASIO_DECL address_v4 make_address_v4(string_view str); + +/// Create an IPv4 address from an IP address string in dotted decimal form. +/** + * @relates address_v4 + */ +ASIO_DECL address_v4 make_address_v4( + string_view str, asio::error_code& ec); + +#endif // defined(ASIO_HAS_STRING_VIEW) + // || defined(GENERATING_DOCUMENTATION) + +#if !defined(ASIO_NO_IOSTREAM) + +/// Output an address as a string. +/** + * Used to output a human-readable string for a specified address. + * + * @param os The output stream to which the string will be written. + * + * @param addr The address to be written. + * + * @return The output stream. + * + * @relates asio::ip::address_v4 + */ +template <typename Elem, typename Traits> +std::basic_ostream<Elem, Traits>& operator<<( + std::basic_ostream<Elem, Traits>& os, const address_v4& addr); + +#endif // !defined(ASIO_NO_IOSTREAM) + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/ip/impl/address_v4.hpp" +#if defined(ASIO_HEADER_ONLY) +# include "asio/ip/impl/address_v4.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_IP_ADDRESS_V4_HPP diff --git a/lib/asio/ip/address_v4_iterator.hpp b/lib/asio/ip/address_v4_iterator.hpp new file mode 100644 index 0000000..e2ef393 --- /dev/null +++ b/lib/asio/ip/address_v4_iterator.hpp @@ -0,0 +1,162 @@ +// +// ip/address_v4_iterator.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_ADDRESS_V4_ITERATOR_HPP +#define ASIO_IP_ADDRESS_V4_ITERATOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/ip/address_v4.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +template <typename> class basic_address_iterator; + +/// An input iterator that can be used for traversing IPv4 addresses. +/** + * In addition to satisfying the input iterator requirements, this iterator + * also supports decrement. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template <> class basic_address_iterator<address_v4> +{ +public: + /// The type of the elements pointed to by the iterator. + typedef address_v4 value_type; + + /// Distance between two iterators. + typedef std::ptrdiff_t difference_type; + + /// The type of a pointer to an element pointed to by the iterator. + typedef const address_v4* pointer; + + /// The type of a reference to an element pointed to by the iterator. + typedef const address_v4& reference; + + /// Denotes that the iterator satisfies the input iterator requirements. + typedef std::input_iterator_tag iterator_category; + + /// Construct an iterator that points to the specified address. + basic_address_iterator(const address_v4& addr) ASIO_NOEXCEPT + : address_(addr) + { + } + + /// Copy constructor. + basic_address_iterator( + const basic_address_iterator& other) ASIO_NOEXCEPT + : address_(other.address_) + { + } + +#if defined(ASIO_HAS_MOVE) + /// Move constructor. + basic_address_iterator(basic_address_iterator&& other) ASIO_NOEXCEPT + : address_(ASIO_MOVE_CAST(address_v4)(other.address_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + /// Assignment operator. + basic_address_iterator& operator=( + const basic_address_iterator& other) ASIO_NOEXCEPT + { + address_ = other.address_; + return *this; + } + +#if defined(ASIO_HAS_MOVE) + /// Move assignment operator. + basic_address_iterator& operator=( + basic_address_iterator&& other) ASIO_NOEXCEPT + { + address_ = ASIO_MOVE_CAST(address_v4)(other.address_); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) + + /// Dereference the iterator. + const address_v4& operator*() const ASIO_NOEXCEPT + { + return address_; + } + + /// Dereference the iterator. + const address_v4* operator->() const ASIO_NOEXCEPT + { + return &address_; + } + + /// Pre-increment operator. + basic_address_iterator& operator++() ASIO_NOEXCEPT + { + address_ = address_v4((address_.to_uint() + 1) & 0xFFFFFFFF); + return *this; + } + + /// Post-increment operator. + basic_address_iterator operator++(int) ASIO_NOEXCEPT + { + basic_address_iterator tmp(*this); + ++*this; + return tmp; + } + + /// Pre-decrement operator. + basic_address_iterator& operator--() ASIO_NOEXCEPT + { + address_ = address_v4((address_.to_uint() - 1) & 0xFFFFFFFF); + return *this; + } + + /// Post-decrement operator. + basic_address_iterator operator--(int) + { + basic_address_iterator tmp(*this); + --*this; + return tmp; + } + + /// Compare two addresses for equality. + friend bool operator==(const basic_address_iterator& a, + const basic_address_iterator& b) + { + return a.address_ == b.address_; + } + + /// Compare two addresses for inequality. + friend bool operator!=(const basic_address_iterator& a, + const basic_address_iterator& b) + { + return a.address_ != b.address_; + } + +private: + address_v4 address_; +}; + +/// An input iterator that can be used for traversing IPv4 addresses. +typedef basic_address_iterator<address_v4> address_v4_iterator; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_ADDRESS_V4_ITERATOR_HPP diff --git a/lib/asio/ip/address_v4_range.hpp b/lib/asio/ip/address_v4_range.hpp new file mode 100644 index 0000000..a402842 --- /dev/null +++ b/lib/asio/ip/address_v4_range.hpp @@ -0,0 +1,134 @@ +// +// ip/address_v4_range.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_ADDRESS_V4_RANGE_HPP +#define ASIO_IP_ADDRESS_V4_RANGE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/ip/address_v4_iterator.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +template <typename> class basic_address_range; + +/// Represents a range of IPv4 addresses. +/** + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template <> class basic_address_range<address_v4> +{ +public: + /// The type of an iterator that points into the range. + typedef basic_address_iterator<address_v4> iterator; + + /// Construct an empty range. + basic_address_range() ASIO_NOEXCEPT + : begin_(address_v4()), + end_(address_v4()) + { + } + + /// Construct an range that represents the given range of addresses. + explicit basic_address_range(const iterator& first, + const iterator& last) ASIO_NOEXCEPT + : begin_(first), + end_(last) + { + } + + /// Copy constructor. + basic_address_range(const basic_address_range& other) ASIO_NOEXCEPT + : begin_(other.begin_), + end_(other.end_) + { + } + +#if defined(ASIO_HAS_MOVE) + /// Move constructor. + basic_address_range(basic_address_range&& other) ASIO_NOEXCEPT + : begin_(ASIO_MOVE_CAST(iterator)(other.begin_)), + end_(ASIO_MOVE_CAST(iterator)(other.end_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + /// Assignment operator. + basic_address_range& operator=( + const basic_address_range& other) ASIO_NOEXCEPT + { + begin_ = other.begin_; + end_ = other.end_; + return *this; + } + +#if defined(ASIO_HAS_MOVE) + /// Move assignment operator. + basic_address_range& operator=( + basic_address_range&& other) ASIO_NOEXCEPT + { + begin_ = ASIO_MOVE_CAST(iterator)(other.begin_); + end_ = ASIO_MOVE_CAST(iterator)(other.end_); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) + + /// Obtain an iterator that points to the start of the range. + iterator begin() const ASIO_NOEXCEPT + { + return begin_; + } + + /// Obtain an iterator that points to the end of the range. + iterator end() const ASIO_NOEXCEPT + { + return end_; + } + + /// Determine whether the range is empty. + bool empty() const ASIO_NOEXCEPT + { + return size() == 0; + } + + /// Return the size of the range. + std::size_t size() const ASIO_NOEXCEPT + { + return end_->to_uint() - begin_->to_uint(); + } + + /// Find an address in the range. + iterator find(const address_v4& addr) const ASIO_NOEXCEPT + { + return addr >= *begin_ && addr < *end_ ? iterator(addr) : end_; + } + +private: + iterator begin_; + iterator end_; +}; + +/// Represents a range of IPv4 addresses. +typedef basic_address_range<address_v4> address_v4_range; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_ADDRESS_V4_RANGE_HPP diff --git a/lib/asio/ip/address_v6.hpp b/lib/asio/ip/address_v6.hpp new file mode 100644 index 0000000..fece332 --- /dev/null +++ b/lib/asio/ip/address_v6.hpp @@ -0,0 +1,336 @@ +// +// ip/address_v6.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_ADDRESS_V6_HPP +#define ASIO_IP_ADDRESS_V6_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include <string> +#include "asio/detail/array.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/string_view.hpp" +#include "asio/detail/winsock_init.hpp" +#include "asio/error_code.hpp" +#include "asio/ip/address_v4.hpp" + +#if !defined(ASIO_NO_IOSTREAM) +# include <iosfwd> +#endif // !defined(ASIO_NO_IOSTREAM) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +template <typename> class basic_address_iterator; + +/// Implements IP version 6 style addresses. +/** + * The asio::ip::address_v6 class provides the ability to use and + * manipulate IP version 6 addresses. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +class address_v6 +{ +public: + /// The type used to represent an address as an array of bytes. + /** + * @note This type is defined in terms of the C++0x template @c std::array + * when it is available. Otherwise, it uses @c boost:array. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef array<unsigned char, 16> bytes_type; +#else + typedef asio::detail::array<unsigned char, 16> bytes_type; +#endif + + /// Default constructor. + ASIO_DECL address_v6(); + + /// Construct an address from raw bytes and scope ID. + ASIO_DECL explicit address_v6(const bytes_type& bytes, + unsigned long scope_id = 0); + + /// Copy constructor. + ASIO_DECL address_v6(const address_v6& other); + +#if defined(ASIO_HAS_MOVE) + /// Move constructor. + ASIO_DECL address_v6(address_v6&& other); +#endif // defined(ASIO_HAS_MOVE) + + /// Assign from another address. + ASIO_DECL address_v6& operator=(const address_v6& other); + +#if defined(ASIO_HAS_MOVE) + /// Move-assign from another address. + ASIO_DECL address_v6& operator=(address_v6&& other); +#endif // defined(ASIO_HAS_MOVE) + + /// The scope ID of the address. + /** + * Returns the scope ID associated with the IPv6 address. + */ + unsigned long scope_id() const + { + return scope_id_; + } + + /// The scope ID of the address. + /** + * Modifies the scope ID associated with the IPv6 address. + */ + void scope_id(unsigned long id) + { + scope_id_ = id; + } + + /// Get the address in bytes, in network byte order. + ASIO_DECL bytes_type to_bytes() const; + + /// Get the address as a string. + ASIO_DECL std::string to_string() const; + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use other overload.) Get the address as a string. + ASIO_DECL std::string to_string(asio::error_code& ec) const; + + /// (Deprecated: Use make_address_v6().) Create an IPv6 address from an IP + /// address string. + static address_v6 from_string(const char* str); + + /// (Deprecated: Use make_address_v6().) Create an IPv6 address from an IP + /// address string. + static address_v6 from_string( + const char* str, asio::error_code& ec); + + /// (Deprecated: Use make_address_v6().) Create an IPv6 address from an IP + /// address string. + static address_v6 from_string(const std::string& str); + + /// (Deprecated: Use make_address_v6().) Create an IPv6 address from an IP + /// address string. + static address_v6 from_string( + const std::string& str, asio::error_code& ec); + + /// (Deprecated: Use make_address_v4().) Converts an IPv4-mapped or + /// IPv4-compatible address to an IPv4 address. + ASIO_DECL address_v4 to_v4() const; +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Determine whether the address is a loopback address. + ASIO_DECL bool is_loopback() const; + + /// Determine whether the address is unspecified. + ASIO_DECL bool is_unspecified() const; + + /// Determine whether the address is link local. + ASIO_DECL bool is_link_local() const; + + /// Determine whether the address is site local. + ASIO_DECL bool is_site_local() const; + + /// Determine whether the address is a mapped IPv4 address. + ASIO_DECL bool is_v4_mapped() const; + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: No replacement.) Determine whether the address is an + /// IPv4-compatible address. + ASIO_DECL bool is_v4_compatible() const; +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Determine whether the address is a multicast address. + ASIO_DECL bool is_multicast() const; + + /// Determine whether the address is a global multicast address. + ASIO_DECL bool is_multicast_global() const; + + /// Determine whether the address is a link-local multicast address. + ASIO_DECL bool is_multicast_link_local() const; + + /// Determine whether the address is a node-local multicast address. + ASIO_DECL bool is_multicast_node_local() const; + + /// Determine whether the address is a org-local multicast address. + ASIO_DECL bool is_multicast_org_local() const; + + /// Determine whether the address is a site-local multicast address. + ASIO_DECL bool is_multicast_site_local() const; + + /// Compare two addresses for equality. + ASIO_DECL friend bool operator==( + const address_v6& a1, const address_v6& a2); + + /// Compare two addresses for inequality. + friend bool operator!=(const address_v6& a1, const address_v6& a2) + { + return !(a1 == a2); + } + + /// Compare addresses for ordering. + ASIO_DECL friend bool operator<( + const address_v6& a1, const address_v6& a2); + + /// Compare addresses for ordering. + friend bool operator>(const address_v6& a1, const address_v6& a2) + { + return a2 < a1; + } + + /// Compare addresses for ordering. + friend bool operator<=(const address_v6& a1, const address_v6& a2) + { + return !(a2 < a1); + } + + /// Compare addresses for ordering. + friend bool operator>=(const address_v6& a1, const address_v6& a2) + { + return !(a1 < a2); + } + + /// Obtain an address object that represents any address. + static address_v6 any() + { + return address_v6(); + } + + /// Obtain an address object that represents the loopback address. + ASIO_DECL static address_v6 loopback(); + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use make_address_v6().) Create an IPv4-mapped IPv6 address. + ASIO_DECL static address_v6 v4_mapped(const address_v4& addr); + + /// (Deprecated: No replacement.) Create an IPv4-compatible IPv6 address. + ASIO_DECL static address_v6 v4_compatible(const address_v4& addr); +#endif // !defined(ASIO_NO_DEPRECATED) + +private: + friend class basic_address_iterator<address_v6>; + + // The underlying IPv6 address. + asio::detail::in6_addr_type addr_; + + // The scope ID associated with the address. + unsigned long scope_id_; +}; + +/// Create an IPv6 address from raw bytes and scope ID. +/** + * @relates address_v6 + */ +inline address_v6 make_address_v6(const address_v6::bytes_type& bytes, + unsigned long scope_id = 0) +{ + return address_v6(bytes, scope_id); +} + +/// Create an IPv6 address from an IP address string. +/** + * @relates address_v6 + */ +ASIO_DECL address_v6 make_address_v6(const char* str); + +/// Create an IPv6 address from an IP address string. +/** + * @relates address_v6 + */ +ASIO_DECL address_v6 make_address_v6( + const char* str, asio::error_code& ec); + +/// Createan IPv6 address from an IP address string. +/** + * @relates address_v6 + */ +ASIO_DECL address_v6 make_address_v6(const std::string& str); + +/// Create an IPv6 address from an IP address string. +/** + * @relates address_v6 + */ +ASIO_DECL address_v6 make_address_v6( + const std::string& str, asio::error_code& ec); + +#if defined(ASIO_HAS_STRING_VIEW) \ + || defined(GENERATING_DOCUMENTATION) + +/// Create an IPv6 address from an IP address string. +/** + * @relates address_v6 + */ +ASIO_DECL address_v6 make_address_v6(string_view str); + +/// Create an IPv6 address from an IP address string. +/** + * @relates address_v6 + */ +ASIO_DECL address_v6 make_address_v6( + string_view str, asio::error_code& ec); + +#endif // defined(ASIO_HAS_STRING_VIEW) + // || defined(GENERATING_DOCUMENTATION) + +/// Tag type used for distinguishing overloads that deal in IPv4-mapped IPv6 +/// addresses. +enum v4_mapped_t { v4_mapped }; + +/// Create an IPv4 address from a IPv4-mapped IPv6 address. +/** + * @relates address_v4 + */ +ASIO_DECL address_v4 make_address_v4( + v4_mapped_t, const address_v6& v6_addr); + +/// Create an IPv4-mapped IPv6 address from an IPv4 address. +/** + * @relates address_v6 + */ +ASIO_DECL address_v6 make_address_v6( + v4_mapped_t, const address_v4& v4_addr); + +#if !defined(ASIO_NO_IOSTREAM) + +/// Output an address as a string. +/** + * Used to output a human-readable string for a specified address. + * + * @param os The output stream to which the string will be written. + * + * @param addr The address to be written. + * + * @return The output stream. + * + * @relates asio::ip::address_v6 + */ +template <typename Elem, typename Traits> +std::basic_ostream<Elem, Traits>& operator<<( + std::basic_ostream<Elem, Traits>& os, const address_v6& addr); + +#endif // !defined(ASIO_NO_IOSTREAM) + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/ip/impl/address_v6.hpp" +#if defined(ASIO_HEADER_ONLY) +# include "asio/ip/impl/address_v6.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_IP_ADDRESS_V6_HPP diff --git a/lib/asio/ip/address_v6_iterator.hpp b/lib/asio/ip/address_v6_iterator.hpp new file mode 100644 index 0000000..0a1fb3f --- /dev/null +++ b/lib/asio/ip/address_v6_iterator.hpp @@ -0,0 +1,183 @@ +// +// ip/address_v6_iterator.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Oliver Kowalke (oliver dot kowalke at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_ADDRESS_V6_ITERATOR_HPP +#define ASIO_IP_ADDRESS_V6_ITERATOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/ip/address_v6.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +template <typename> class basic_address_iterator; + +/// An input iterator that can be used for traversing IPv6 addresses. +/** + * In addition to satisfying the input iterator requirements, this iterator + * also supports decrement. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template <> class basic_address_iterator<address_v6> +{ +public: + /// The type of the elements pointed to by the iterator. + typedef address_v6 value_type; + + /// Distance between two iterators. + typedef std::ptrdiff_t difference_type; + + /// The type of a pointer to an element pointed to by the iterator. + typedef const address_v6* pointer; + + /// The type of a reference to an element pointed to by the iterator. + typedef const address_v6& reference; + + /// Denotes that the iterator satisfies the input iterator requirements. + typedef std::input_iterator_tag iterator_category; + + /// Construct an iterator that points to the specified address. + basic_address_iterator(const address_v6& addr) ASIO_NOEXCEPT + : address_(addr) + { + } + + /// Copy constructor. + basic_address_iterator( + const basic_address_iterator& other) ASIO_NOEXCEPT + : address_(other.address_) + { + } + +#if defined(ASIO_HAS_MOVE) + /// Move constructor. + basic_address_iterator(basic_address_iterator&& other) ASIO_NOEXCEPT + : address_(ASIO_MOVE_CAST(address_v6)(other.address_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + /// Assignment operator. + basic_address_iterator& operator=( + const basic_address_iterator& other) ASIO_NOEXCEPT + { + address_ = other.address_; + return *this; + } + +#if defined(ASIO_HAS_MOVE) + /// Move assignment operator. + basic_address_iterator& operator=( + basic_address_iterator&& other) ASIO_NOEXCEPT + { + address_ = ASIO_MOVE_CAST(address_v6)(other.address_); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) + + /// Dereference the iterator. + const address_v6& operator*() const ASIO_NOEXCEPT + { + return address_; + } + + /// Dereference the iterator. + const address_v6* operator->() const ASIO_NOEXCEPT + { + return &address_; + } + + /// Pre-increment operator. + basic_address_iterator& operator++() ASIO_NOEXCEPT + { + for (int i = 15; i >= 0; --i) + { + if (address_.addr_.s6_addr[i] < 0xFF) + { + ++address_.addr_.s6_addr[i]; + break; + } + + address_.addr_.s6_addr[i] = 0; + } + + return *this; + } + + /// Post-increment operator. + basic_address_iterator operator++(int) ASIO_NOEXCEPT + { + basic_address_iterator tmp(*this); + ++*this; + return tmp; + } + + /// Pre-decrement operator. + basic_address_iterator& operator--() ASIO_NOEXCEPT + { + for (int i = 15; i >= 0; --i) + { + if (address_.addr_.s6_addr[i] > 0) + { + --address_.addr_.s6_addr[i]; + break; + } + + address_.addr_.s6_addr[i] = 0xFF; + } + + return *this; + } + + /// Post-decrement operator. + basic_address_iterator operator--(int) + { + basic_address_iterator tmp(*this); + --*this; + return tmp; + } + + /// Compare two addresses for equality. + friend bool operator==(const basic_address_iterator& a, + const basic_address_iterator& b) + { + return a.address_ == b.address_; + } + + /// Compare two addresses for inequality. + friend bool operator!=(const basic_address_iterator& a, + const basic_address_iterator& b) + { + return a.address_ != b.address_; + } + +private: + address_v6 address_; +}; + +/// An input iterator that can be used for traversing IPv6 addresses. +typedef basic_address_iterator<address_v6> address_v6_iterator; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_ADDRESS_V6_ITERATOR_HPP diff --git a/lib/asio/ip/address_v6_range.hpp b/lib/asio/ip/address_v6_range.hpp new file mode 100644 index 0000000..9d7062e --- /dev/null +++ b/lib/asio/ip/address_v6_range.hpp @@ -0,0 +1,129 @@ +// +// ip/address_v6_range.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Oliver Kowalke (oliver dot kowalke at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_ADDRESS_V6_RANGE_HPP +#define ASIO_IP_ADDRESS_V6_RANGE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/ip/address_v6_iterator.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +template <typename> class basic_address_range; + +/// Represents a range of IPv6 addresses. +/** + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template <> class basic_address_range<address_v6> +{ +public: + /// The type of an iterator that points into the range. + typedef basic_address_iterator<address_v6> iterator; + + /// Construct an empty range. + basic_address_range() ASIO_NOEXCEPT + : begin_(address_v6()), + end_(address_v6()) + { + } + + /// Construct an range that represents the given range of addresses. + explicit basic_address_range(const iterator& first, + const iterator& last) ASIO_NOEXCEPT + : begin_(first), + end_(last) + { + } + + /// Copy constructor. + basic_address_range(const basic_address_range& other) ASIO_NOEXCEPT + : begin_(other.begin_), + end_(other.end_) + { + } + +#if defined(ASIO_HAS_MOVE) + /// Move constructor. + basic_address_range(basic_address_range&& other) ASIO_NOEXCEPT + : begin_(ASIO_MOVE_CAST(iterator)(other.begin_)), + end_(ASIO_MOVE_CAST(iterator)(other.end_)) + { + } +#endif // defined(ASIO_HAS_MOVE) + + /// Assignment operator. + basic_address_range& operator=( + const basic_address_range& other) ASIO_NOEXCEPT + { + begin_ = other.begin_; + end_ = other.end_; + return *this; + } + +#if defined(ASIO_HAS_MOVE) + /// Move assignment operator. + basic_address_range& operator=( + basic_address_range&& other) ASIO_NOEXCEPT + { + begin_ = ASIO_MOVE_CAST(iterator)(other.begin_); + end_ = ASIO_MOVE_CAST(iterator)(other.end_); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) + + /// Obtain an iterator that points to the start of the range. + iterator begin() const ASIO_NOEXCEPT + { + return begin_; + } + + /// Obtain an iterator that points to the end of the range. + iterator end() const ASIO_NOEXCEPT + { + return end_; + } + + /// Determine whether the range is empty. + bool empty() const ASIO_NOEXCEPT + { + return begin_ == end_; + } + + /// Find an address in the range. + iterator find(const address_v6& addr) const ASIO_NOEXCEPT + { + return addr >= *begin_ && addr < *end_ ? iterator(addr) : end_; + } + +private: + iterator begin_; + iterator end_; +}; + +/// Represents a range of IPv6 addresses. +typedef basic_address_range<address_v6> address_v6_range; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_ADDRESS_V6_RANGE_HPP diff --git a/lib/asio/ip/bad_address_cast.hpp b/lib/asio/ip/bad_address_cast.hpp new file mode 100644 index 0000000..8c71f70 --- /dev/null +++ b/lib/asio/ip/bad_address_cast.hpp @@ -0,0 +1,48 @@ +// +// ip/bad_address_cast.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_BAD_ADDRESS_CAST_HPP +#define ASIO_IP_BAD_ADDRESS_CAST_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include <typeinfo> + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// Thrown to indicate a failed address conversion. +class bad_address_cast : public std::bad_cast +{ +public: + /// Default constructor. + bad_address_cast() {} + + /// Destructor. + virtual ~bad_address_cast() ASIO_NOEXCEPT_OR_NOTHROW {} + + /// Get the message associated with the exception. + virtual const char* what() const ASIO_NOEXCEPT_OR_NOTHROW + { + return "bad address cast"; + } +}; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_ADDRESS_HPP diff --git a/lib/asio/ip/basic_endpoint.hpp b/lib/asio/ip/basic_endpoint.hpp new file mode 100644 index 0000000..4418ee7 --- /dev/null +++ b/lib/asio/ip/basic_endpoint.hpp @@ -0,0 +1,263 @@ +// +// ip/basic_endpoint.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_BASIC_ENDPOINT_HPP +#define ASIO_IP_BASIC_ENDPOINT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/ip/address.hpp" +#include "asio/ip/detail/endpoint.hpp" + +#if !defined(ASIO_NO_IOSTREAM) +# include <iosfwd> +#endif // !defined(ASIO_NO_IOSTREAM) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// Describes an endpoint for a version-independent IP socket. +/** + * The asio::ip::basic_endpoint class template describes an endpoint that + * may be associated with a particular socket. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Concepts: + * Endpoint. + */ +template <typename InternetProtocol> +class basic_endpoint +{ +public: + /// The protocol type associated with the endpoint. + typedef InternetProtocol protocol_type; + + /// The type of the endpoint structure. This type is dependent on the + /// underlying implementation of the socket layer. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined data_type; +#else + typedef asio::detail::socket_addr_type data_type; +#endif + + /// Default constructor. + basic_endpoint() + : impl_() + { + } + + /// Construct an endpoint using a port number, specified in the host's byte + /// order. The IP address will be the any address (i.e. INADDR_ANY or + /// in6addr_any). This constructor would typically be used for accepting new + /// connections. + /** + * @par Examples + * To initialise an IPv4 TCP endpoint for port 1234, use: + * @code + * asio::ip::tcp::endpoint ep(asio::ip::tcp::v4(), 1234); + * @endcode + * + * To specify an IPv6 UDP endpoint for port 9876, use: + * @code + * asio::ip::udp::endpoint ep(asio::ip::udp::v6(), 9876); + * @endcode + */ + basic_endpoint(const InternetProtocol& internet_protocol, + unsigned short port_num) + : impl_(internet_protocol.family(), port_num) + { + } + + /// Construct an endpoint using a port number and an IP address. This + /// constructor may be used for accepting connections on a specific interface + /// or for making a connection to a remote endpoint. + basic_endpoint(const asio::ip::address& addr, unsigned short port_num) + : impl_(addr, port_num) + { + } + + /// Copy constructor. + basic_endpoint(const basic_endpoint& other) + : impl_(other.impl_) + { + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move constructor. + basic_endpoint(basic_endpoint&& other) + : impl_(other.impl_) + { + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Assign from another endpoint. + basic_endpoint& operator=(const basic_endpoint& other) + { + impl_ = other.impl_; + return *this; + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-assign from another endpoint. + basic_endpoint& operator=(basic_endpoint&& other) + { + impl_ = other.impl_; + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// The protocol associated with the endpoint. + protocol_type protocol() const + { + if (impl_.is_v4()) + return InternetProtocol::v4(); + return InternetProtocol::v6(); + } + + /// Get the underlying endpoint in the native type. + data_type* data() + { + return impl_.data(); + } + + /// Get the underlying endpoint in the native type. + const data_type* data() const + { + return impl_.data(); + } + + /// Get the underlying size of the endpoint in the native type. + std::size_t size() const + { + return impl_.size(); + } + + /// Set the underlying size of the endpoint in the native type. + void resize(std::size_t new_size) + { + impl_.resize(new_size); + } + + /// Get the capacity of the endpoint in the native type. + std::size_t capacity() const + { + return impl_.capacity(); + } + + /// Get the port associated with the endpoint. The port number is always in + /// the host's byte order. + unsigned short port() const + { + return impl_.port(); + } + + /// Set the port associated with the endpoint. The port number is always in + /// the host's byte order. + void port(unsigned short port_num) + { + impl_.port(port_num); + } + + /// Get the IP address associated with the endpoint. + asio::ip::address address() const + { + return impl_.address(); + } + + /// Set the IP address associated with the endpoint. + void address(const asio::ip::address& addr) + { + impl_.address(addr); + } + + /// Compare two endpoints for equality. + friend bool operator==(const basic_endpoint<InternetProtocol>& e1, + const basic_endpoint<InternetProtocol>& e2) + { + return e1.impl_ == e2.impl_; + } + + /// Compare two endpoints for inequality. + friend bool operator!=(const basic_endpoint<InternetProtocol>& e1, + const basic_endpoint<InternetProtocol>& e2) + { + return !(e1 == e2); + } + + /// Compare endpoints for ordering. + friend bool operator<(const basic_endpoint<InternetProtocol>& e1, + const basic_endpoint<InternetProtocol>& e2) + { + return e1.impl_ < e2.impl_; + } + + /// Compare endpoints for ordering. + friend bool operator>(const basic_endpoint<InternetProtocol>& e1, + const basic_endpoint<InternetProtocol>& e2) + { + return e2.impl_ < e1.impl_; + } + + /// Compare endpoints for ordering. + friend bool operator<=(const basic_endpoint<InternetProtocol>& e1, + const basic_endpoint<InternetProtocol>& e2) + { + return !(e2 < e1); + } + + /// Compare endpoints for ordering. + friend bool operator>=(const basic_endpoint<InternetProtocol>& e1, + const basic_endpoint<InternetProtocol>& e2) + { + return !(e1 < e2); + } + +private: + // The underlying IP endpoint. + asio::ip::detail::endpoint impl_; +}; + +#if !defined(ASIO_NO_IOSTREAM) + +/// Output an endpoint as a string. +/** + * Used to output a human-readable string for a specified endpoint. + * + * @param os The output stream to which the string will be written. + * + * @param endpoint The endpoint to be written. + * + * @return The output stream. + * + * @relates asio::ip::basic_endpoint + */ +template <typename Elem, typename Traits, typename InternetProtocol> +std::basic_ostream<Elem, Traits>& operator<<( + std::basic_ostream<Elem, Traits>& os, + const basic_endpoint<InternetProtocol>& endpoint); + +#endif // !defined(ASIO_NO_IOSTREAM) + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/ip/impl/basic_endpoint.hpp" + +#endif // ASIO_IP_BASIC_ENDPOINT_HPP diff --git a/lib/asio/ip/basic_resolver.hpp b/lib/asio/ip/basic_resolver.hpp new file mode 100644 index 0000000..812dbec --- /dev/null +++ b/lib/asio/ip/basic_resolver.hpp @@ -0,0 +1,1018 @@ +// +// ip/basic_resolver.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_BASIC_RESOLVER_HPP +#define ASIO_IP_BASIC_RESOLVER_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include <string> +#include "asio/async_result.hpp" +#include "asio/basic_io_object.hpp" +#include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/string_view.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/error.hpp" +#include "asio/io_context.hpp" +#include "asio/ip/basic_resolver_iterator.hpp" +#include "asio/ip/basic_resolver_query.hpp" +#include "asio/ip/basic_resolver_results.hpp" +#include "asio/ip/resolver_base.hpp" + +#if defined(ASIO_HAS_MOVE) +# include <utility> +#endif // defined(ASIO_HAS_MOVE) + +#if defined(ASIO_ENABLE_OLD_SERVICES) +# include "asio/ip/resolver_service.hpp" +#else // defined(ASIO_ENABLE_OLD_SERVICES) +# if defined(ASIO_WINDOWS_RUNTIME) +# include "asio/detail/winrt_resolver_service.hpp" +# define ASIO_SVC_T \ + asio::detail::winrt_resolver_service<InternetProtocol> +# else +# include "asio/detail/resolver_service.hpp" +# define ASIO_SVC_T \ + asio::detail::resolver_service<InternetProtocol> +# endif +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// Provides endpoint resolution functionality. +/** + * The basic_resolver class template provides the ability to resolve a query + * to a list of endpoints. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template <typename InternetProtocol + ASIO_SVC_TPARAM_DEF1(= resolver_service<InternetProtocol>)> +class basic_resolver + : ASIO_SVC_ACCESS basic_io_object<ASIO_SVC_T>, + public resolver_base +{ +public: + /// The type of the executor associated with the object. + typedef io_context::executor_type executor_type; + + /// The protocol type. + typedef InternetProtocol protocol_type; + + /// The endpoint type. + typedef typename InternetProtocol::endpoint endpoint_type; + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated.) The query type. + typedef basic_resolver_query<InternetProtocol> query; + + /// (Deprecated.) The iterator type. + typedef basic_resolver_iterator<InternetProtocol> iterator; +#endif // !defined(ASIO_NO_DEPRECATED) + + /// The results type. + typedef basic_resolver_results<InternetProtocol> results_type; + + /// Constructor. + /** + * This constructor creates a basic_resolver. + * + * @param io_context The io_context object that the resolver will use to + * dispatch handlers for any asynchronous operations performed on the + * resolver. + */ + explicit basic_resolver(asio::io_context& io_context) + : basic_io_object<ASIO_SVC_T>(io_context) + { + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a basic_resolver from another. + /** + * This constructor moves a resolver from one object to another. + * + * @param other The other basic_resolver object from which the move will + * occur. + * + * @note Following the move, the moved-from object is in the same state as if + * constructed using the @c basic_resolver(io_context&) constructor. + */ + basic_resolver(basic_resolver&& other) + : basic_io_object<ASIO_SVC_T>(std::move(other)) + { + } + + /// Move-assign a basic_resolver from another. + /** + * This assignment operator moves a resolver from one object to another. + * Cancels any outstanding asynchronous operations associated with the target + * object. + * + * @param other The other basic_resolver object from which the move will + * occur. + * + * @note Following the move, the moved-from object is in the same state as if + * constructed using the @c basic_resolver(io_context&) constructor. + */ + basic_resolver& operator=(basic_resolver&& other) + { + basic_io_object<ASIO_SVC_T>::operator=(std::move(other)); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Destroys the resolver. + /** + * This function destroys the resolver, cancelling any outstanding + * asynchronous wait operations associated with the resolver as if by calling + * @c cancel. + */ + ~basic_resolver() + { + } + +#if defined(ASIO_ENABLE_OLD_SERVICES) + // These functions are provided by basic_io_object<>. +#else // defined(ASIO_ENABLE_OLD_SERVICES) +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use get_executor().) Get the io_context associated with the + /// object. + /** + * This function may be used to obtain the io_context object that the I/O + * object uses to dispatch handlers for asynchronous operations. + * + * @return A reference to the io_context object that the I/O object will use + * to dispatch handlers. Ownership is not transferred to the caller. + */ + asio::io_context& get_io_context() + { + return basic_io_object<ASIO_SVC_T>::get_io_context(); + } + + /// (Deprecated: Use get_executor().) Get the io_context associated with the + /// object. + /** + * This function may be used to obtain the io_context object that the I/O + * object uses to dispatch handlers for asynchronous operations. + * + * @return A reference to the io_context object that the I/O object will use + * to dispatch handlers. Ownership is not transferred to the caller. + */ + asio::io_context& get_io_service() + { + return basic_io_object<ASIO_SVC_T>::get_io_service(); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Get the executor associated with the object. + executor_type get_executor() ASIO_NOEXCEPT + { + return basic_io_object<ASIO_SVC_T>::get_executor(); + } +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + + /// Cancel any asynchronous operations that are waiting on the resolver. + /** + * This function forces the completion of any pending asynchronous + * operations on the host resolver. The handler for each cancelled operation + * will be invoked with the asio::error::operation_aborted error code. + */ + void cancel() + { + return this->get_service().cancel(this->get_implementation()); + } + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated.) Perform forward resolution of a query to a list of entries. + /** + * This function is used to resolve a query into a list of endpoint entries. + * + * @param q A query object that determines what endpoints will be returned. + * + * @returns A range object representing the list of endpoint entries. A + * successful call to this function is guaranteed to return a non-empty + * range. + * + * @throws asio::system_error Thrown on failure. + */ + results_type resolve(const query& q) + { + asio::error_code ec; + results_type r = this->get_service().resolve( + this->get_implementation(), q, ec); + asio::detail::throw_error(ec, "resolve"); + return r; + } + + /// (Deprecated.) Perform forward resolution of a query to a list of entries. + /** + * This function is used to resolve a query into a list of endpoint entries. + * + * @param q A query object that determines what endpoints will be returned. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns A range object representing the list of endpoint entries. An + * empty range is returned if an error occurs. A successful call to this + * function is guaranteed to return a non-empty range. + */ + results_type resolve(const query& q, asio::error_code& ec) + { + return this->get_service().resolve(this->get_implementation(), q, ec); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Perform forward resolution of a query to a list of entries. + /** + * This function is used to resolve host and service names into a list of + * endpoint entries. + * + * @param host A string identifying a location. May be a descriptive name or + * a numeric address string. If an empty string and the passive flag has been + * specified, the resolved endpoints are suitable for local service binding. + * If an empty string and passive is not specified, the resolved endpoints + * will use the loopback address. + * + * @param service A string identifying the requested service. This may be a + * descriptive name or a numeric string corresponding to a port number. May + * be an empty string, in which case all resolved endpoints will have a port + * number of 0. + * + * @returns A range object representing the list of endpoint entries. A + * successful call to this function is guaranteed to return a non-empty + * range. + * + * @throws asio::system_error Thrown on failure. + * + * @note On POSIX systems, host names may be locally defined in the file + * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file + * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name + * resolution is performed using DNS. Operating systems may use additional + * locations when resolving host names (such as NETBIOS names on Windows). + * + * On POSIX systems, service names are typically defined in the file + * <tt>/etc/services</tt>. On Windows, service names may be found in the file + * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems + * may use additional locations when resolving service names. + */ + results_type resolve(ASIO_STRING_VIEW_PARAM host, + ASIO_STRING_VIEW_PARAM service) + { + return resolve(host, service, resolver_base::flags()); + } + + /// Perform forward resolution of a query to a list of entries. + /** + * This function is used to resolve host and service names into a list of + * endpoint entries. + * + * @param host A string identifying a location. May be a descriptive name or + * a numeric address string. If an empty string and the passive flag has been + * specified, the resolved endpoints are suitable for local service binding. + * If an empty string and passive is not specified, the resolved endpoints + * will use the loopback address. + * + * @param service A string identifying the requested service. This may be a + * descriptive name or a numeric string corresponding to a port number. May + * be an empty string, in which case all resolved endpoints will have a port + * number of 0. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns A range object representing the list of endpoint entries. An + * empty range is returned if an error occurs. A successful call to this + * function is guaranteed to return a non-empty range. + * + * @note On POSIX systems, host names may be locally defined in the file + * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file + * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name + * resolution is performed using DNS. Operating systems may use additional + * locations when resolving host names (such as NETBIOS names on Windows). + * + * On POSIX systems, service names are typically defined in the file + * <tt>/etc/services</tt>. On Windows, service names may be found in the file + * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems + * may use additional locations when resolving service names. + */ + results_type resolve(ASIO_STRING_VIEW_PARAM host, + ASIO_STRING_VIEW_PARAM service, asio::error_code& ec) + { + return resolve(host, service, resolver_base::flags(), ec); + } + + /// Perform forward resolution of a query to a list of entries. + /** + * This function is used to resolve host and service names into a list of + * endpoint entries. + * + * @param host A string identifying a location. May be a descriptive name or + * a numeric address string. If an empty string and the passive flag has been + * specified, the resolved endpoints are suitable for local service binding. + * If an empty string and passive is not specified, the resolved endpoints + * will use the loopback address. + * + * @param service A string identifying the requested service. This may be a + * descriptive name or a numeric string corresponding to a port number. May + * be an empty string, in which case all resolved endpoints will have a port + * number of 0. + * + * @param resolve_flags A set of flags that determine how name resolution + * should be performed. The default flags are suitable for communication with + * remote hosts. + * + * @returns A range object representing the list of endpoint entries. A + * successful call to this function is guaranteed to return a non-empty + * range. + * + * @throws asio::system_error Thrown on failure. + * + * @note On POSIX systems, host names may be locally defined in the file + * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file + * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name + * resolution is performed using DNS. Operating systems may use additional + * locations when resolving host names (such as NETBIOS names on Windows). + * + * On POSIX systems, service names are typically defined in the file + * <tt>/etc/services</tt>. On Windows, service names may be found in the file + * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems + * may use additional locations when resolving service names. + */ + results_type resolve(ASIO_STRING_VIEW_PARAM host, + ASIO_STRING_VIEW_PARAM service, resolver_base::flags resolve_flags) + { + asio::error_code ec; + basic_resolver_query<protocol_type> q(static_cast<std::string>(host), + static_cast<std::string>(service), resolve_flags); + results_type r = this->get_service().resolve( + this->get_implementation(), q, ec); + asio::detail::throw_error(ec, "resolve"); + return r; + } + + /// Perform forward resolution of a query to a list of entries. + /** + * This function is used to resolve host and service names into a list of + * endpoint entries. + * + * @param host A string identifying a location. May be a descriptive name or + * a numeric address string. If an empty string and the passive flag has been + * specified, the resolved endpoints are suitable for local service binding. + * If an empty string and passive is not specified, the resolved endpoints + * will use the loopback address. + * + * @param service A string identifying the requested service. This may be a + * descriptive name or a numeric string corresponding to a port number. May + * be an empty string, in which case all resolved endpoints will have a port + * number of 0. + * + * @param resolve_flags A set of flags that determine how name resolution + * should be performed. The default flags are suitable for communication with + * remote hosts. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns A range object representing the list of endpoint entries. An + * empty range is returned if an error occurs. A successful call to this + * function is guaranteed to return a non-empty range. + * + * @note On POSIX systems, host names may be locally defined in the file + * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file + * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name + * resolution is performed using DNS. Operating systems may use additional + * locations when resolving host names (such as NETBIOS names on Windows). + * + * On POSIX systems, service names are typically defined in the file + * <tt>/etc/services</tt>. On Windows, service names may be found in the file + * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems + * may use additional locations when resolving service names. + */ + results_type resolve(ASIO_STRING_VIEW_PARAM host, + ASIO_STRING_VIEW_PARAM service, resolver_base::flags resolve_flags, + asio::error_code& ec) + { + basic_resolver_query<protocol_type> q(static_cast<std::string>(host), + static_cast<std::string>(service), resolve_flags); + return this->get_service().resolve(this->get_implementation(), q, ec); + } + + /// Perform forward resolution of a query to a list of entries. + /** + * This function is used to resolve host and service names into a list of + * endpoint entries. + * + * @param protocol A protocol object, normally representing either the IPv4 or + * IPv6 version of an internet protocol. + * + * @param host A string identifying a location. May be a descriptive name or + * a numeric address string. If an empty string and the passive flag has been + * specified, the resolved endpoints are suitable for local service binding. + * If an empty string and passive is not specified, the resolved endpoints + * will use the loopback address. + * + * @param service A string identifying the requested service. This may be a + * descriptive name or a numeric string corresponding to a port number. May + * be an empty string, in which case all resolved endpoints will have a port + * number of 0. + * + * @returns A range object representing the list of endpoint entries. A + * successful call to this function is guaranteed to return a non-empty + * range. + * + * @throws asio::system_error Thrown on failure. + * + * @note On POSIX systems, host names may be locally defined in the file + * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file + * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name + * resolution is performed using DNS. Operating systems may use additional + * locations when resolving host names (such as NETBIOS names on Windows). + * + * On POSIX systems, service names are typically defined in the file + * <tt>/etc/services</tt>. On Windows, service names may be found in the file + * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems + * may use additional locations when resolving service names. + */ + results_type resolve(const protocol_type& protocol, + ASIO_STRING_VIEW_PARAM host, ASIO_STRING_VIEW_PARAM service) + { + return resolve(protocol, host, service, resolver_base::flags()); + } + + /// Perform forward resolution of a query to a list of entries. + /** + * This function is used to resolve host and service names into a list of + * endpoint entries. + * + * @param protocol A protocol object, normally representing either the IPv4 or + * IPv6 version of an internet protocol. + * + * @param host A string identifying a location. May be a descriptive name or + * a numeric address string. If an empty string and the passive flag has been + * specified, the resolved endpoints are suitable for local service binding. + * If an empty string and passive is not specified, the resolved endpoints + * will use the loopback address. + * + * @param service A string identifying the requested service. This may be a + * descriptive name or a numeric string corresponding to a port number. May + * be an empty string, in which case all resolved endpoints will have a port + * number of 0. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns A range object representing the list of endpoint entries. An + * empty range is returned if an error occurs. A successful call to this + * function is guaranteed to return a non-empty range. + * + * @note On POSIX systems, host names may be locally defined in the file + * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file + * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name + * resolution is performed using DNS. Operating systems may use additional + * locations when resolving host names (such as NETBIOS names on Windows). + * + * On POSIX systems, service names are typically defined in the file + * <tt>/etc/services</tt>. On Windows, service names may be found in the file + * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems + * may use additional locations when resolving service names. + */ + results_type resolve(const protocol_type& protocol, + ASIO_STRING_VIEW_PARAM host, ASIO_STRING_VIEW_PARAM service, + asio::error_code& ec) + { + return resolve(protocol, host, service, resolver_base::flags(), ec); + } + + /// Perform forward resolution of a query to a list of entries. + /** + * This function is used to resolve host and service names into a list of + * endpoint entries. + * + * @param protocol A protocol object, normally representing either the IPv4 or + * IPv6 version of an internet protocol. + * + * @param host A string identifying a location. May be a descriptive name or + * a numeric address string. If an empty string and the passive flag has been + * specified, the resolved endpoints are suitable for local service binding. + * If an empty string and passive is not specified, the resolved endpoints + * will use the loopback address. + * + * @param service A string identifying the requested service. This may be a + * descriptive name or a numeric string corresponding to a port number. May + * be an empty string, in which case all resolved endpoints will have a port + * number of 0. + * + * @param resolve_flags A set of flags that determine how name resolution + * should be performed. The default flags are suitable for communication with + * remote hosts. + * + * @returns A range object representing the list of endpoint entries. A + * successful call to this function is guaranteed to return a non-empty + * range. + * + * @throws asio::system_error Thrown on failure. + * + * @note On POSIX systems, host names may be locally defined in the file + * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file + * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name + * resolution is performed using DNS. Operating systems may use additional + * locations when resolving host names (such as NETBIOS names on Windows). + * + * On POSIX systems, service names are typically defined in the file + * <tt>/etc/services</tt>. On Windows, service names may be found in the file + * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems + * may use additional locations when resolving service names. + */ + results_type resolve(const protocol_type& protocol, + ASIO_STRING_VIEW_PARAM host, ASIO_STRING_VIEW_PARAM service, + resolver_base::flags resolve_flags) + { + asio::error_code ec; + basic_resolver_query<protocol_type> q( + protocol, static_cast<std::string>(host), + static_cast<std::string>(service), resolve_flags); + results_type r = this->get_service().resolve( + this->get_implementation(), q, ec); + asio::detail::throw_error(ec, "resolve"); + return r; + } + + /// Perform forward resolution of a query to a list of entries. + /** + * This function is used to resolve host and service names into a list of + * endpoint entries. + * + * @param protocol A protocol object, normally representing either the IPv4 or + * IPv6 version of an internet protocol. + * + * @param host A string identifying a location. May be a descriptive name or + * a numeric address string. If an empty string and the passive flag has been + * specified, the resolved endpoints are suitable for local service binding. + * If an empty string and passive is not specified, the resolved endpoints + * will use the loopback address. + * + * @param service A string identifying the requested service. This may be a + * descriptive name or a numeric string corresponding to a port number. May + * be an empty string, in which case all resolved endpoints will have a port + * number of 0. + * + * @param resolve_flags A set of flags that determine how name resolution + * should be performed. The default flags are suitable for communication with + * remote hosts. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns A range object representing the list of endpoint entries. An + * empty range is returned if an error occurs. A successful call to this + * function is guaranteed to return a non-empty range. + * + * @note On POSIX systems, host names may be locally defined in the file + * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file + * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name + * resolution is performed using DNS. Operating systems may use additional + * locations when resolving host names (such as NETBIOS names on Windows). + * + * On POSIX systems, service names are typically defined in the file + * <tt>/etc/services</tt>. On Windows, service names may be found in the file + * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems + * may use additional locations when resolving service names. + */ + results_type resolve(const protocol_type& protocol, + ASIO_STRING_VIEW_PARAM host, ASIO_STRING_VIEW_PARAM service, + resolver_base::flags resolve_flags, asio::error_code& ec) + { + basic_resolver_query<protocol_type> q( + protocol, static_cast<std::string>(host), + static_cast<std::string>(service), resolve_flags); + return this->get_service().resolve(this->get_implementation(), q, ec); + } + +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated.) Asynchronously perform forward resolution of a query to a + /// list of entries. + /** + * This function is used to asynchronously resolve a query into a list of + * endpoint entries. + * + * @param q A query object that determines what endpoints will be returned. + * + * @param handler The handler to be called when the resolve operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * resolver::results_type results // Resolved endpoints as a range. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_context::post(). + * + * A successful resolve operation is guaranteed to pass a non-empty range to + * the handler. + */ + template <typename ResolveHandler> + ASIO_INITFN_RESULT_TYPE(ResolveHandler, + void (asio::error_code, results_type)) + async_resolve(const query& q, + ASIO_MOVE_ARG(ResolveHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ResolveHandler. + ASIO_RESOLVE_HANDLER_CHECK( + ResolveHandler, handler, results_type) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_resolve(this->get_implementation(), q, + ASIO_MOVE_CAST(ResolveHandler)(handler)); +#else // defined(ASIO_ENABLE_OLD_SERVICES) + asio::async_completion<ResolveHandler, + void (asio::error_code, results_type)> init(handler); + + this->get_service().async_resolve( + this->get_implementation(), q, init.completion_handler); + + return init.result.get(); +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// Asynchronously perform forward resolution of a query to a list of entries. + /** + * This function is used to resolve host and service names into a list of + * endpoint entries. + * + * @param host A string identifying a location. May be a descriptive name or + * a numeric address string. If an empty string and the passive flag has been + * specified, the resolved endpoints are suitable for local service binding. + * If an empty string and passive is not specified, the resolved endpoints + * will use the loopback address. + * + * @param service A string identifying the requested service. This may be a + * descriptive name or a numeric string corresponding to a port number. May + * be an empty string, in which case all resolved endpoints will have a port + * number of 0. + * + * @param handler The handler to be called when the resolve operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * resolver::results_type results // Resolved endpoints as a range. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_context::post(). + * + * A successful resolve operation is guaranteed to pass a non-empty range to + * the handler. + * + * @note On POSIX systems, host names may be locally defined in the file + * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file + * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name + * resolution is performed using DNS. Operating systems may use additional + * locations when resolving host names (such as NETBIOS names on Windows). + * + * On POSIX systems, service names are typically defined in the file + * <tt>/etc/services</tt>. On Windows, service names may be found in the file + * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems + * may use additional locations when resolving service names. + */ + template <typename ResolveHandler> + ASIO_INITFN_RESULT_TYPE(ResolveHandler, + void (asio::error_code, results_type)) + async_resolve(ASIO_STRING_VIEW_PARAM host, + ASIO_STRING_VIEW_PARAM service, + ASIO_MOVE_ARG(ResolveHandler) handler) + { + return async_resolve(host, service, resolver_base::flags(), + ASIO_MOVE_CAST(ResolveHandler)(handler)); + } + + /// Asynchronously perform forward resolution of a query to a list of entries. + /** + * This function is used to resolve host and service names into a list of + * endpoint entries. + * + * @param host A string identifying a location. May be a descriptive name or + * a numeric address string. If an empty string and the passive flag has been + * specified, the resolved endpoints are suitable for local service binding. + * If an empty string and passive is not specified, the resolved endpoints + * will use the loopback address. + * + * @param service A string identifying the requested service. This may be a + * descriptive name or a numeric string corresponding to a port number. May + * be an empty string, in which case all resolved endpoints will have a port + * number of 0. + * + * @param resolve_flags A set of flags that determine how name resolution + * should be performed. The default flags are suitable for communication with + * remote hosts. + * + * @param handler The handler to be called when the resolve operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * resolver::results_type results // Resolved endpoints as a range. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_context::post(). + * + * A successful resolve operation is guaranteed to pass a non-empty range to + * the handler. + * + * @note On POSIX systems, host names may be locally defined in the file + * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file + * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name + * resolution is performed using DNS. Operating systems may use additional + * locations when resolving host names (such as NETBIOS names on Windows). + * + * On POSIX systems, service names are typically defined in the file + * <tt>/etc/services</tt>. On Windows, service names may be found in the file + * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems + * may use additional locations when resolving service names. + */ + template <typename ResolveHandler> + ASIO_INITFN_RESULT_TYPE(ResolveHandler, + void (asio::error_code, results_type)) + async_resolve(ASIO_STRING_VIEW_PARAM host, + ASIO_STRING_VIEW_PARAM service, + resolver_base::flags resolve_flags, + ASIO_MOVE_ARG(ResolveHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ResolveHandler. + ASIO_RESOLVE_HANDLER_CHECK( + ResolveHandler, handler, results_type) type_check; + + basic_resolver_query<protocol_type> q(static_cast<std::string>(host), + static_cast<std::string>(service), resolve_flags); + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_resolve(this->get_implementation(), q, + ASIO_MOVE_CAST(ResolveHandler)(handler)); +#else // defined(ASIO_ENABLE_OLD_SERVICES) + asio::async_completion<ResolveHandler, + void (asio::error_code, results_type)> init(handler); + + this->get_service().async_resolve( + this->get_implementation(), q, init.completion_handler); + + return init.result.get(); +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + } + + /// Asynchronously perform forward resolution of a query to a list of entries. + /** + * This function is used to resolve host and service names into a list of + * endpoint entries. + * + * @param protocol A protocol object, normally representing either the IPv4 or + * IPv6 version of an internet protocol. + * + * @param host A string identifying a location. May be a descriptive name or + * a numeric address string. If an empty string and the passive flag has been + * specified, the resolved endpoints are suitable for local service binding. + * If an empty string and passive is not specified, the resolved endpoints + * will use the loopback address. + * + * @param service A string identifying the requested service. This may be a + * descriptive name or a numeric string corresponding to a port number. May + * be an empty string, in which case all resolved endpoints will have a port + * number of 0. + * + * @param handler The handler to be called when the resolve operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * resolver::results_type results // Resolved endpoints as a range. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_context::post(). + * + * A successful resolve operation is guaranteed to pass a non-empty range to + * the handler. + * + * @note On POSIX systems, host names may be locally defined in the file + * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file + * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name + * resolution is performed using DNS. Operating systems may use additional + * locations when resolving host names (such as NETBIOS names on Windows). + * + * On POSIX systems, service names are typically defined in the file + * <tt>/etc/services</tt>. On Windows, service names may be found in the file + * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems + * may use additional locations when resolving service names. + */ + template <typename ResolveHandler> + ASIO_INITFN_RESULT_TYPE(ResolveHandler, + void (asio::error_code, results_type)) + async_resolve(const protocol_type& protocol, + ASIO_STRING_VIEW_PARAM host, ASIO_STRING_VIEW_PARAM service, + ASIO_MOVE_ARG(ResolveHandler) handler) + { + return async_resolve(protocol, host, service, resolver_base::flags(), + ASIO_MOVE_CAST(ResolveHandler)(handler)); + } + + /// Asynchronously perform forward resolution of a query to a list of entries. + /** + * This function is used to resolve host and service names into a list of + * endpoint entries. + * + * @param protocol A protocol object, normally representing either the IPv4 or + * IPv6 version of an internet protocol. + * + * @param host A string identifying a location. May be a descriptive name or + * a numeric address string. If an empty string and the passive flag has been + * specified, the resolved endpoints are suitable for local service binding. + * If an empty string and passive is not specified, the resolved endpoints + * will use the loopback address. + * + * @param service A string identifying the requested service. This may be a + * descriptive name or a numeric string corresponding to a port number. May + * be an empty string, in which case all resolved endpoints will have a port + * number of 0. + * + * @param resolve_flags A set of flags that determine how name resolution + * should be performed. The default flags are suitable for communication with + * remote hosts. + * + * @param handler The handler to be called when the resolve operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * resolver::results_type results // Resolved endpoints as a range. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_context::post(). + * + * A successful resolve operation is guaranteed to pass a non-empty range to + * the handler. + * + * @note On POSIX systems, host names may be locally defined in the file + * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file + * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name + * resolution is performed using DNS. Operating systems may use additional + * locations when resolving host names (such as NETBIOS names on Windows). + * + * On POSIX systems, service names are typically defined in the file + * <tt>/etc/services</tt>. On Windows, service names may be found in the file + * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems + * may use additional locations when resolving service names. + */ + template <typename ResolveHandler> + ASIO_INITFN_RESULT_TYPE(ResolveHandler, + void (asio::error_code, results_type)) + async_resolve(const protocol_type& protocol, + ASIO_STRING_VIEW_PARAM host, ASIO_STRING_VIEW_PARAM service, + resolver_base::flags resolve_flags, + ASIO_MOVE_ARG(ResolveHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ResolveHandler. + ASIO_RESOLVE_HANDLER_CHECK( + ResolveHandler, handler, results_type) type_check; + + basic_resolver_query<protocol_type> q( + protocol, static_cast<std::string>(host), + static_cast<std::string>(service), resolve_flags); + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_resolve(this->get_implementation(), q, + ASIO_MOVE_CAST(ResolveHandler)(handler)); +#else // defined(ASIO_ENABLE_OLD_SERVICES) + asio::async_completion<ResolveHandler, + void (asio::error_code, results_type)> init(handler); + + this->get_service().async_resolve( + this->get_implementation(), q, init.completion_handler); + + return init.result.get(); +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + } + + /// Perform reverse resolution of an endpoint to a list of entries. + /** + * This function is used to resolve an endpoint into a list of endpoint + * entries. + * + * @param e An endpoint object that determines what endpoints will be + * returned. + * + * @returns A range object representing the list of endpoint entries. A + * successful call to this function is guaranteed to return a non-empty + * range. + * + * @throws asio::system_error Thrown on failure. + */ + results_type resolve(const endpoint_type& e) + { + asio::error_code ec; + results_type i = this->get_service().resolve( + this->get_implementation(), e, ec); + asio::detail::throw_error(ec, "resolve"); + return i; + } + + /// Perform reverse resolution of an endpoint to a list of entries. + /** + * This function is used to resolve an endpoint into a list of endpoint + * entries. + * + * @param e An endpoint object that determines what endpoints will be + * returned. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns A range object representing the list of endpoint entries. An + * empty range is returned if an error occurs. A successful call to this + * function is guaranteed to return a non-empty range. + */ + results_type resolve(const endpoint_type& e, asio::error_code& ec) + { + return this->get_service().resolve(this->get_implementation(), e, ec); + } + + /// Asynchronously perform reverse resolution of an endpoint to a list of + /// entries. + /** + * This function is used to asynchronously resolve an endpoint into a list of + * endpoint entries. + * + * @param e An endpoint object that determines what endpoints will be + * returned. + * + * @param handler The handler to be called when the resolve operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * resolver::results_type results // Resolved endpoints as a range. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * asio::io_context::post(). + * + * A successful resolve operation is guaranteed to pass a non-empty range to + * the handler. + */ + template <typename ResolveHandler> + ASIO_INITFN_RESULT_TYPE(ResolveHandler, + void (asio::error_code, results_type)) + async_resolve(const endpoint_type& e, + ASIO_MOVE_ARG(ResolveHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ResolveHandler. + ASIO_RESOLVE_HANDLER_CHECK( + ResolveHandler, handler, results_type) type_check; + +#if defined(ASIO_ENABLE_OLD_SERVICES) + return this->get_service().async_resolve(this->get_implementation(), e, + ASIO_MOVE_CAST(ResolveHandler)(handler)); +#else // defined(ASIO_ENABLE_OLD_SERVICES) + asio::async_completion<ResolveHandler, + void (asio::error_code, results_type)> init(handler); + + this->get_service().async_resolve( + this->get_implementation(), e, init.completion_handler); + + return init.result.get(); +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + } +}; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if !defined(ASIO_ENABLE_OLD_SERVICES) +# undef ASIO_SVC_T +#endif // !defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_IP_BASIC_RESOLVER_HPP diff --git a/lib/asio/ip/basic_resolver_entry.hpp b/lib/asio/ip/basic_resolver_entry.hpp new file mode 100644 index 0000000..99bcbd2 --- /dev/null +++ b/lib/asio/ip/basic_resolver_entry.hpp @@ -0,0 +1,113 @@ +// +// ip/basic_resolver_entry.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_BASIC_RESOLVER_ENTRY_HPP +#define ASIO_IP_BASIC_RESOLVER_ENTRY_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include <string> +#include "asio/detail/string_view.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// An entry produced by a resolver. +/** + * The asio::ip::basic_resolver_entry class template describes an entry + * as returned by a resolver. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template <typename InternetProtocol> +class basic_resolver_entry +{ +public: + /// The protocol type associated with the endpoint entry. + typedef InternetProtocol protocol_type; + + /// The endpoint type associated with the endpoint entry. + typedef typename InternetProtocol::endpoint endpoint_type; + + /// Default constructor. + basic_resolver_entry() + { + } + + /// Construct with specified endpoint, host name and service name. + basic_resolver_entry(const endpoint_type& ep, + ASIO_STRING_VIEW_PARAM host, ASIO_STRING_VIEW_PARAM service) + : endpoint_(ep), + host_name_(static_cast<std::string>(host)), + service_name_(static_cast<std::string>(service)) + { + } + + /// Get the endpoint associated with the entry. + endpoint_type endpoint() const + { + return endpoint_; + } + + /// Convert to the endpoint associated with the entry. + operator endpoint_type() const + { + return endpoint_; + } + + /// Get the host name associated with the entry. + std::string host_name() const + { + return host_name_; + } + + /// Get the host name associated with the entry. + template <class Allocator> + std::basic_string<char, std::char_traits<char>, Allocator> host_name( + const Allocator& alloc = Allocator()) const + { + return std::basic_string<char, std::char_traits<char>, Allocator>( + host_name_.c_str(), alloc); + } + + /// Get the service name associated with the entry. + std::string service_name() const + { + return service_name_; + } + + /// Get the service name associated with the entry. + template <class Allocator> + std::basic_string<char, std::char_traits<char>, Allocator> service_name( + const Allocator& alloc = Allocator()) const + { + return std::basic_string<char, std::char_traits<char>, Allocator>( + service_name_.c_str(), alloc); + } + +private: + endpoint_type endpoint_; + std::string host_name_; + std::string service_name_; +}; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_BASIC_RESOLVER_ENTRY_HPP diff --git a/lib/asio/ip/basic_resolver_iterator.hpp b/lib/asio/ip/basic_resolver_iterator.hpp new file mode 100644 index 0000000..ec5412c --- /dev/null +++ b/lib/asio/ip/basic_resolver_iterator.hpp @@ -0,0 +1,192 @@ +// +// ip/basic_resolver_iterator.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_BASIC_RESOLVER_ITERATOR_HPP +#define ASIO_IP_BASIC_RESOLVER_ITERATOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include <cstddef> +#include <cstring> +#include <iterator> +#include <string> +#include <vector> +#include "asio/detail/memory.hpp" +#include "asio/detail/socket_ops.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/ip/basic_resolver_entry.hpp" + +#if defined(ASIO_WINDOWS_RUNTIME) +# include "asio/detail/winrt_utils.hpp" +#endif // defined(ASIO_WINDOWS_RUNTIME) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// An iterator over the entries produced by a resolver. +/** + * The asio::ip::basic_resolver_iterator class template is used to define + * iterators over the results returned by a resolver. + * + * The iterator's value_type, obtained when the iterator is dereferenced, is: + * @code const basic_resolver_entry<InternetProtocol> @endcode + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template <typename InternetProtocol> +class basic_resolver_iterator +{ +public: + /// The type used for the distance between two iterators. + typedef std::ptrdiff_t difference_type; + + /// The type of the value pointed to by the iterator. + typedef basic_resolver_entry<InternetProtocol> value_type; + + /// The type of the result of applying operator->() to the iterator. + typedef const basic_resolver_entry<InternetProtocol>* pointer; + + /// The type of the result of applying operator*() to the iterator. + typedef const basic_resolver_entry<InternetProtocol>& reference; + + /// The iterator category. + typedef std::forward_iterator_tag iterator_category; + + /// Default constructor creates an end iterator. + basic_resolver_iterator() + : index_(0) + { + } + + /// Copy constructor. + basic_resolver_iterator(const basic_resolver_iterator& other) + : values_(other.values_), + index_(other.index_) + { + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move constructor. + basic_resolver_iterator(basic_resolver_iterator&& other) + : values_(ASIO_MOVE_CAST(values_ptr_type)(other.values_)), + index_(other.index_) + { + other.index_ = 0; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Assignment operator. + basic_resolver_iterator& operator=(const basic_resolver_iterator& other) + { + values_ = other.values_; + index_ = other.index_; + return *this; + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-assignment operator. + basic_resolver_iterator& operator=(basic_resolver_iterator&& other) + { + if (this != &other) + { + values_ = ASIO_MOVE_CAST(values_ptr_type)(other.values_); + index_ = other.index_; + other.index_ = 0; + } + + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Dereference an iterator. + const basic_resolver_entry<InternetProtocol>& operator*() const + { + return dereference(); + } + + /// Dereference an iterator. + const basic_resolver_entry<InternetProtocol>* operator->() const + { + return &dereference(); + } + + /// Increment operator (prefix). + basic_resolver_iterator& operator++() + { + increment(); + return *this; + } + + /// Increment operator (postfix). + basic_resolver_iterator operator++(int) + { + basic_resolver_iterator tmp(*this); + ++*this; + return tmp; + } + + /// Test two iterators for equality. + friend bool operator==(const basic_resolver_iterator& a, + const basic_resolver_iterator& b) + { + return a.equal(b); + } + + /// Test two iterators for inequality. + friend bool operator!=(const basic_resolver_iterator& a, + const basic_resolver_iterator& b) + { + return !a.equal(b); + } + +protected: + void increment() + { + if (++index_ == values_->size()) + { + // Reset state to match a default constructed end iterator. + values_.reset(); + index_ = 0; + } + } + + bool equal(const basic_resolver_iterator& other) const + { + if (!values_ && !other.values_) + return true; + if (values_ != other.values_) + return false; + return index_ == other.index_; + } + + const basic_resolver_entry<InternetProtocol>& dereference() const + { + return (*values_)[index_]; + } + + typedef std::vector<basic_resolver_entry<InternetProtocol> > values_type; + typedef asio::detail::shared_ptr<values_type> values_ptr_type; + values_ptr_type values_; + std::size_t index_; +}; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_BASIC_RESOLVER_ITERATOR_HPP diff --git a/lib/asio/ip/basic_resolver_query.hpp b/lib/asio/ip/basic_resolver_query.hpp new file mode 100644 index 0000000..84cd98d --- /dev/null +++ b/lib/asio/ip/basic_resolver_query.hpp @@ -0,0 +1,244 @@ +// +// ip/basic_resolver_query.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_BASIC_RESOLVER_QUERY_HPP +#define ASIO_IP_BASIC_RESOLVER_QUERY_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include <string> +#include "asio/detail/socket_ops.hpp" +#include "asio/ip/resolver_query_base.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// An query to be passed to a resolver. +/** + * The asio::ip::basic_resolver_query class template describes a query + * that can be passed to a resolver. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template <typename InternetProtocol> +class basic_resolver_query + : public resolver_query_base +{ +public: + /// The protocol type associated with the endpoint query. + typedef InternetProtocol protocol_type; + + /// Construct with specified service name for any protocol. + /** + * This constructor is typically used to perform name resolution for local + * service binding. + * + * @param service A string identifying the requested service. This may be a + * descriptive name or a numeric string corresponding to a port number. + * + * @param resolve_flags A set of flags that determine how name resolution + * should be performed. The default flags are suitable for local service + * binding. + * + * @note On POSIX systems, service names are typically defined in the file + * <tt>/etc/services</tt>. On Windows, service names may be found in the file + * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems + * may use additional locations when resolving service names. + */ + basic_resolver_query(const std::string& service, + resolver_query_base::flags resolve_flags = passive | address_configured) + : hints_(), + host_name_(), + service_name_(service) + { + typename InternetProtocol::endpoint endpoint; + hints_.ai_flags = static_cast<int>(resolve_flags); + hints_.ai_family = PF_UNSPEC; + hints_.ai_socktype = endpoint.protocol().type(); + hints_.ai_protocol = endpoint.protocol().protocol(); + hints_.ai_addrlen = 0; + hints_.ai_canonname = 0; + hints_.ai_addr = 0; + hints_.ai_next = 0; + } + + /// Construct with specified service name for a given protocol. + /** + * This constructor is typically used to perform name resolution for local + * service binding with a specific protocol version. + * + * @param protocol A protocol object, normally representing either the IPv4 or + * IPv6 version of an internet protocol. + * + * @param service A string identifying the requested service. This may be a + * descriptive name or a numeric string corresponding to a port number. + * + * @param resolve_flags A set of flags that determine how name resolution + * should be performed. The default flags are suitable for local service + * binding. + * + * @note On POSIX systems, service names are typically defined in the file + * <tt>/etc/services</tt>. On Windows, service names may be found in the file + * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems + * may use additional locations when resolving service names. + */ + basic_resolver_query(const protocol_type& protocol, + const std::string& service, + resolver_query_base::flags resolve_flags = passive | address_configured) + : hints_(), + host_name_(), + service_name_(service) + { + hints_.ai_flags = static_cast<int>(resolve_flags); + hints_.ai_family = protocol.family(); + hints_.ai_socktype = protocol.type(); + hints_.ai_protocol = protocol.protocol(); + hints_.ai_addrlen = 0; + hints_.ai_canonname = 0; + hints_.ai_addr = 0; + hints_.ai_next = 0; + } + + /// Construct with specified host name and service name for any protocol. + /** + * This constructor is typically used to perform name resolution for + * communication with remote hosts. + * + * @param host A string identifying a location. May be a descriptive name or + * a numeric address string. If an empty string and the passive flag has been + * specified, the resolved endpoints are suitable for local service binding. + * If an empty string and passive is not specified, the resolved endpoints + * will use the loopback address. + * + * @param service A string identifying the requested service. This may be a + * descriptive name or a numeric string corresponding to a port number. May + * be an empty string, in which case all resolved endpoints will have a port + * number of 0. + * + * @param resolve_flags A set of flags that determine how name resolution + * should be performed. The default flags are suitable for communication with + * remote hosts. + * + * @note On POSIX systems, host names may be locally defined in the file + * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file + * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name + * resolution is performed using DNS. Operating systems may use additional + * locations when resolving host names (such as NETBIOS names on Windows). + * + * On POSIX systems, service names are typically defined in the file + * <tt>/etc/services</tt>. On Windows, service names may be found in the file + * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems + * may use additional locations when resolving service names. + */ + basic_resolver_query(const std::string& host, const std::string& service, + resolver_query_base::flags resolve_flags = address_configured) + : hints_(), + host_name_(host), + service_name_(service) + { + typename InternetProtocol::endpoint endpoint; + hints_.ai_flags = static_cast<int>(resolve_flags); + hints_.ai_family = ASIO_OS_DEF(AF_UNSPEC); + hints_.ai_socktype = endpoint.protocol().type(); + hints_.ai_protocol = endpoint.protocol().protocol(); + hints_.ai_addrlen = 0; + hints_.ai_canonname = 0; + hints_.ai_addr = 0; + hints_.ai_next = 0; + } + + /// Construct with specified host name and service name for a given protocol. + /** + * This constructor is typically used to perform name resolution for + * communication with remote hosts. + * + * @param protocol A protocol object, normally representing either the IPv4 or + * IPv6 version of an internet protocol. + * + * @param host A string identifying a location. May be a descriptive name or + * a numeric address string. If an empty string and the passive flag has been + * specified, the resolved endpoints are suitable for local service binding. + * If an empty string and passive is not specified, the resolved endpoints + * will use the loopback address. + * + * @param service A string identifying the requested service. This may be a + * descriptive name or a numeric string corresponding to a port number. May + * be an empty string, in which case all resolved endpoints will have a port + * number of 0. + * + * @param resolve_flags A set of flags that determine how name resolution + * should be performed. The default flags are suitable for communication with + * remote hosts. + * + * @note On POSIX systems, host names may be locally defined in the file + * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file + * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name + * resolution is performed using DNS. Operating systems may use additional + * locations when resolving host names (such as NETBIOS names on Windows). + * + * On POSIX systems, service names are typically defined in the file + * <tt>/etc/services</tt>. On Windows, service names may be found in the file + * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems + * may use additional locations when resolving service names. + */ + basic_resolver_query(const protocol_type& protocol, + const std::string& host, const std::string& service, + resolver_query_base::flags resolve_flags = address_configured) + : hints_(), + host_name_(host), + service_name_(service) + { + hints_.ai_flags = static_cast<int>(resolve_flags); + hints_.ai_family = protocol.family(); + hints_.ai_socktype = protocol.type(); + hints_.ai_protocol = protocol.protocol(); + hints_.ai_addrlen = 0; + hints_.ai_canonname = 0; + hints_.ai_addr = 0; + hints_.ai_next = 0; + } + + /// Get the hints associated with the query. + const asio::detail::addrinfo_type& hints() const + { + return hints_; + } + + /// Get the host name associated with the query. + std::string host_name() const + { + return host_name_; + } + + /// Get the service name associated with the query. + std::string service_name() const + { + return service_name_; + } + +private: + asio::detail::addrinfo_type hints_; + std::string host_name_; + std::string service_name_; +}; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_BASIC_RESOLVER_QUERY_HPP diff --git a/lib/asio/ip/basic_resolver_results.hpp b/lib/asio/ip/basic_resolver_results.hpp new file mode 100644 index 0000000..185075f --- /dev/null +++ b/lib/asio/ip/basic_resolver_results.hpp @@ -0,0 +1,311 @@ +// +// ip/basic_resolver_results.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_BASIC_RESOLVER_RESULTS_HPP +#define ASIO_IP_BASIC_RESOLVER_RESULTS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include <cstddef> +#include <cstring> +#include "asio/detail/socket_ops.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/ip/basic_resolver_iterator.hpp" + +#if defined(ASIO_WINDOWS_RUNTIME) +# include "asio/detail/winrt_utils.hpp" +#endif // defined(ASIO_WINDOWS_RUNTIME) + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// A range of entries produced by a resolver. +/** + * The asio::ip::basic_resolver_results class template is used to define + * a range over the results returned by a resolver. + * + * The iterator's value_type, obtained when a results iterator is dereferenced, + * is: @code const basic_resolver_entry<InternetProtocol> @endcode + * + * @note For backward compatibility, basic_resolver_results is derived from + * basic_resolver_iterator. This derivation is deprecated. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template <typename InternetProtocol> +class basic_resolver_results +#if !defined(ASIO_NO_DEPRECATED) + : public basic_resolver_iterator<InternetProtocol> +#else // !defined(ASIO_NO_DEPRECATED) + : private basic_resolver_iterator<InternetProtocol> +#endif // !defined(ASIO_NO_DEPRECATED) +{ +public: + /// The protocol type associated with the results. + typedef InternetProtocol protocol_type; + + /// The endpoint type associated with the results. + typedef typename protocol_type::endpoint endpoint_type; + + /// The type of a value in the results range. + typedef basic_resolver_entry<protocol_type> value_type; + + /// The type of a const reference to a value in the range. + typedef const value_type& const_reference; + + /// The type of a non-const reference to a value in the range. + typedef value_type& reference; + + /// The type of an iterator into the range. + typedef basic_resolver_iterator<protocol_type> const_iterator; + + /// The type of an iterator into the range. + typedef const_iterator iterator; + + /// Type used to represent the distance between two iterators in the range. + typedef std::ptrdiff_t difference_type; + + /// Type used to represent a count of the elements in the range. + typedef std::size_t size_type; + + /// Default constructor creates an empty range. + basic_resolver_results() + { + } + + /// Copy constructor. + basic_resolver_results(const basic_resolver_results& other) + : basic_resolver_iterator<InternetProtocol>(other) + { + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move constructor. + basic_resolver_results(basic_resolver_results&& other) + : basic_resolver_iterator<InternetProtocol>( + ASIO_MOVE_CAST(basic_resolver_results)(other)) + { + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Assignment operator. + basic_resolver_results& operator=(const basic_resolver_results& other) + { + basic_resolver_iterator<InternetProtocol>::operator=(other); + return *this; + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-assignment operator. + basic_resolver_results& operator=(basic_resolver_results&& other) + { + basic_resolver_iterator<InternetProtocol>::operator=( + ASIO_MOVE_CAST(basic_resolver_results)(other)); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + +#if !defined(GENERATING_DOCUMENTATION) + // Create results from an addrinfo list returned by getaddrinfo. + static basic_resolver_results create( + asio::detail::addrinfo_type* address_info, + const std::string& host_name, const std::string& service_name) + { + basic_resolver_results results; + if (!address_info) + return results; + + std::string actual_host_name = host_name; + if (address_info->ai_canonname) + actual_host_name = address_info->ai_canonname; + + results.values_.reset(new values_type); + + while (address_info) + { + if (address_info->ai_family == ASIO_OS_DEF(AF_INET) + || address_info->ai_family == ASIO_OS_DEF(AF_INET6)) + { + using namespace std; // For memcpy. + typename InternetProtocol::endpoint endpoint; + endpoint.resize(static_cast<std::size_t>(address_info->ai_addrlen)); + memcpy(endpoint.data(), address_info->ai_addr, + address_info->ai_addrlen); + results.values_->push_back( + basic_resolver_entry<InternetProtocol>(endpoint, + actual_host_name, service_name)); + } + address_info = address_info->ai_next; + } + + return results; + } + + // Create results from an endpoint, host name and service name. + static basic_resolver_results create(const endpoint_type& endpoint, + const std::string& host_name, const std::string& service_name) + { + basic_resolver_results results; + results.values_.reset(new values_type); + results.values_->push_back( + basic_resolver_entry<InternetProtocol>( + endpoint, host_name, service_name)); + return results; + } + + // Create results from a sequence of endpoints, host and service name. + template <typename EndpointIterator> + static basic_resolver_results create( + EndpointIterator begin, EndpointIterator end, + const std::string& host_name, const std::string& service_name) + { + basic_resolver_results results; + if (begin != end) + { + results.values_.reset(new values_type); + for (EndpointIterator ep_iter = begin; ep_iter != end; ++ep_iter) + { + results.values_->push_back( + basic_resolver_entry<InternetProtocol>( + *ep_iter, host_name, service_name)); + } + } + return results; + } + +# if defined(ASIO_WINDOWS_RUNTIME) + // Create results from a Windows Runtime list of EndpointPair objects. + static basic_resolver_results create( + Windows::Foundation::Collections::IVectorView< + Windows::Networking::EndpointPair^>^ endpoints, + const asio::detail::addrinfo_type& hints, + const std::string& host_name, const std::string& service_name) + { + basic_resolver_results results; + if (endpoints->Size) + { + results.values_.reset(new values_type); + for (unsigned int i = 0; i < endpoints->Size; ++i) + { + auto pair = endpoints->GetAt(i); + + if (hints.ai_family == ASIO_OS_DEF(AF_INET) + && pair->RemoteHostName->Type + != Windows::Networking::HostNameType::Ipv4) + continue; + + if (hints.ai_family == ASIO_OS_DEF(AF_INET6) + && pair->RemoteHostName->Type + != Windows::Networking::HostNameType::Ipv6) + continue; + + results.values_->push_back( + basic_resolver_entry<InternetProtocol>( + typename InternetProtocol::endpoint( + ip::make_address( + asio::detail::winrt_utils::string( + pair->RemoteHostName->CanonicalName)), + asio::detail::winrt_utils::integer( + pair->RemoteServiceName)), + host_name, service_name)); + } + } + return results; + } +# endif // defined(ASIO_WINDOWS_RUNTIME) +#endif // !defined(GENERATING_DOCUMENTATION) + + /// Get the number of entries in the results range. + size_type size() const ASIO_NOEXCEPT + { + return this->values_->size(); + } + + /// Get the maximum number of entries permitted in a results range. + size_type max_size() const ASIO_NOEXCEPT + { + return this->values_->max_size(); + } + + /// Determine whether the results range is empty. + bool empty() const ASIO_NOEXCEPT + { + return this->values_->empty(); + } + + /// Obtain a begin iterator for the results range. + const_iterator begin() const + { + basic_resolver_results tmp(*this); + tmp.index_ = 0; + return tmp; + } + + /// Obtain an end iterator for the results range. + const_iterator end() const + { + return const_iterator(); + } + + /// Obtain a begin iterator for the results range. + const_iterator cbegin() const + { + return begin(); + } + + /// Obtain an end iterator for the results range. + const_iterator cend() const + { + return end(); + } + + /// Swap the results range with another. + void swap(basic_resolver_results& that) ASIO_NOEXCEPT + { + if (this != &that) + { + this->values_.swap(that.values_); + std::size_t index = this->index_; + this->index_ = that.index_; + that.index_ = index; + } + } + + /// Test two iterators for equality. + friend bool operator==(const basic_resolver_results& a, + const basic_resolver_results& b) + { + return a.equal(b); + } + + /// Test two iterators for inequality. + friend bool operator!=(const basic_resolver_results& a, + const basic_resolver_results& b) + { + return !a.equal(b); + } + +private: + typedef std::vector<basic_resolver_entry<InternetProtocol> > values_type; +}; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_BASIC_RESOLVER_RESULTS_HPP diff --git a/lib/asio/ip/detail/endpoint.hpp b/lib/asio/ip/detail/endpoint.hpp new file mode 100644 index 0000000..9acefe5 --- /dev/null +++ b/lib/asio/ip/detail/endpoint.hpp @@ -0,0 +1,139 @@ +// +// ip/detail/endpoint.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_DETAIL_ENDPOINT_HPP +#define ASIO_IP_DETAIL_ENDPOINT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include <string> +#include "asio/detail/socket_types.hpp" +#include "asio/detail/winsock_init.hpp" +#include "asio/error_code.hpp" +#include "asio/ip/address.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { +namespace detail { + +// Helper class for implementating an IP endpoint. +class endpoint +{ +public: + // Default constructor. + ASIO_DECL endpoint(); + + // Construct an endpoint using a family and port number. + ASIO_DECL endpoint(int family, unsigned short port_num); + + // Construct an endpoint using an address and port number. + ASIO_DECL endpoint(const asio::ip::address& addr, + unsigned short port_num); + + // Copy constructor. + endpoint(const endpoint& other) + : data_(other.data_) + { + } + + // Assign from another endpoint. + endpoint& operator=(const endpoint& other) + { + data_ = other.data_; + return *this; + } + + // Get the underlying endpoint in the native type. + asio::detail::socket_addr_type* data() + { + return &data_.base; + } + + // Get the underlying endpoint in the native type. + const asio::detail::socket_addr_type* data() const + { + return &data_.base; + } + + // Get the underlying size of the endpoint in the native type. + std::size_t size() const + { + if (is_v4()) + return sizeof(asio::detail::sockaddr_in4_type); + else + return sizeof(asio::detail::sockaddr_in6_type); + } + + // Set the underlying size of the endpoint in the native type. + ASIO_DECL void resize(std::size_t new_size); + + // Get the capacity of the endpoint in the native type. + std::size_t capacity() const + { + return sizeof(data_); + } + + // Get the port associated with the endpoint. + ASIO_DECL unsigned short port() const; + + // Set the port associated with the endpoint. + ASIO_DECL void port(unsigned short port_num); + + // Get the IP address associated with the endpoint. + ASIO_DECL asio::ip::address address() const; + + // Set the IP address associated with the endpoint. + ASIO_DECL void address(const asio::ip::address& addr); + + // Compare two endpoints for equality. + ASIO_DECL friend bool operator==( + const endpoint& e1, const endpoint& e2); + + // Compare endpoints for ordering. + ASIO_DECL friend bool operator<( + const endpoint& e1, const endpoint& e2); + + // Determine whether the endpoint is IPv4. + bool is_v4() const + { + return data_.base.sa_family == ASIO_OS_DEF(AF_INET); + } + +#if !defined(ASIO_NO_IOSTREAM) + // Convert to a string. + ASIO_DECL std::string to_string() const; +#endif // !defined(ASIO_NO_IOSTREAM) + +private: + // The underlying IP socket address. + union data_union + { + asio::detail::socket_addr_type base; + asio::detail::sockaddr_in4_type v4; + asio::detail::sockaddr_in6_type v6; + } data_; +}; + +} // namespace detail +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/ip/detail/impl/endpoint.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_IP_DETAIL_ENDPOINT_HPP diff --git a/lib/asio/ip/detail/impl/endpoint.ipp b/lib/asio/ip/detail/impl/endpoint.ipp new file mode 100644 index 0000000..304bdf3 --- /dev/null +++ b/lib/asio/ip/detail/impl/endpoint.ipp @@ -0,0 +1,199 @@ +// +// ip/detail/impl/endpoint.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_DETAIL_IMPL_ENDPOINT_IPP +#define ASIO_IP_DETAIL_IMPL_ENDPOINT_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include <cstring> +#if !defined(ASIO_NO_IOSTREAM) +# include <sstream> +#endif // !defined(ASIO_NO_IOSTREAM) +#include "asio/detail/socket_ops.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/error.hpp" +#include "asio/ip/detail/endpoint.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { +namespace detail { + +endpoint::endpoint() + : data_() +{ + data_.v4.sin_family = ASIO_OS_DEF(AF_INET); + data_.v4.sin_port = 0; + data_.v4.sin_addr.s_addr = ASIO_OS_DEF(INADDR_ANY); +} + +endpoint::endpoint(int family, unsigned short port_num) + : data_() +{ + using namespace std; // For memcpy. + if (family == ASIO_OS_DEF(AF_INET)) + { + data_.v4.sin_family = ASIO_OS_DEF(AF_INET); + data_.v4.sin_port = + asio::detail::socket_ops::host_to_network_short(port_num); + data_.v4.sin_addr.s_addr = ASIO_OS_DEF(INADDR_ANY); + } + else + { + data_.v6.sin6_family = ASIO_OS_DEF(AF_INET6); + data_.v6.sin6_port = + asio::detail::socket_ops::host_to_network_short(port_num); + data_.v6.sin6_flowinfo = 0; + data_.v6.sin6_addr.s6_addr[0] = 0; data_.v6.sin6_addr.s6_addr[1] = 0; + data_.v6.sin6_addr.s6_addr[2] = 0; data_.v6.sin6_addr.s6_addr[3] = 0; + data_.v6.sin6_addr.s6_addr[4] = 0; data_.v6.sin6_addr.s6_addr[5] = 0; + data_.v6.sin6_addr.s6_addr[6] = 0; data_.v6.sin6_addr.s6_addr[7] = 0; + data_.v6.sin6_addr.s6_addr[8] = 0; data_.v6.sin6_addr.s6_addr[9] = 0; + data_.v6.sin6_addr.s6_addr[10] = 0; data_.v6.sin6_addr.s6_addr[11] = 0; + data_.v6.sin6_addr.s6_addr[12] = 0; data_.v6.sin6_addr.s6_addr[13] = 0; + data_.v6.sin6_addr.s6_addr[14] = 0; data_.v6.sin6_addr.s6_addr[15] = 0; + data_.v6.sin6_scope_id = 0; + } +} + +endpoint::endpoint(const asio::ip::address& addr, + unsigned short port_num) + : data_() +{ + using namespace std; // For memcpy. + if (addr.is_v4()) + { + data_.v4.sin_family = ASIO_OS_DEF(AF_INET); + data_.v4.sin_port = + asio::detail::socket_ops::host_to_network_short(port_num); + data_.v4.sin_addr.s_addr = + asio::detail::socket_ops::host_to_network_long( + addr.to_v4().to_uint()); + } + else + { + data_.v6.sin6_family = ASIO_OS_DEF(AF_INET6); + data_.v6.sin6_port = + asio::detail::socket_ops::host_to_network_short(port_num); + data_.v6.sin6_flowinfo = 0; + asio::ip::address_v6 v6_addr = addr.to_v6(); + asio::ip::address_v6::bytes_type bytes = v6_addr.to_bytes(); + memcpy(data_.v6.sin6_addr.s6_addr, bytes.data(), 16); + data_.v6.sin6_scope_id = + static_cast<asio::detail::u_long_type>( + v6_addr.scope_id()); + } +} + +void endpoint::resize(std::size_t new_size) +{ + if (new_size > sizeof(asio::detail::sockaddr_storage_type)) + { + asio::error_code ec(asio::error::invalid_argument); + asio::detail::throw_error(ec); + } +} + +unsigned short endpoint::port() const +{ + if (is_v4()) + { + return asio::detail::socket_ops::network_to_host_short( + data_.v4.sin_port); + } + else + { + return asio::detail::socket_ops::network_to_host_short( + data_.v6.sin6_port); + } +} + +void endpoint::port(unsigned short port_num) +{ + if (is_v4()) + { + data_.v4.sin_port + = asio::detail::socket_ops::host_to_network_short(port_num); + } + else + { + data_.v6.sin6_port + = asio::detail::socket_ops::host_to_network_short(port_num); + } +} + +asio::ip::address endpoint::address() const +{ + using namespace std; // For memcpy. + if (is_v4()) + { + return asio::ip::address_v4( + asio::detail::socket_ops::network_to_host_long( + data_.v4.sin_addr.s_addr)); + } + else + { + asio::ip::address_v6::bytes_type bytes; +#if defined(ASIO_HAS_STD_ARRAY) + memcpy(bytes.data(), data_.v6.sin6_addr.s6_addr, 16); +#else // defined(ASIO_HAS_STD_ARRAY) + memcpy(bytes.elems, data_.v6.sin6_addr.s6_addr, 16); +#endif // defined(ASIO_HAS_STD_ARRAY) + return asio::ip::address_v6(bytes, data_.v6.sin6_scope_id); + } +} + +void endpoint::address(const asio::ip::address& addr) +{ + endpoint tmp_endpoint(addr, port()); + data_ = tmp_endpoint.data_; +} + +bool operator==(const endpoint& e1, const endpoint& e2) +{ + return e1.address() == e2.address() && e1.port() == e2.port(); +} + +bool operator<(const endpoint& e1, const endpoint& e2) +{ + if (e1.address() < e2.address()) + return true; + if (e1.address() != e2.address()) + return false; + return e1.port() < e2.port(); +} + +#if !defined(ASIO_NO_IOSTREAM) +std::string endpoint::to_string() const +{ + std::ostringstream tmp_os; + tmp_os.imbue(std::locale::classic()); + if (is_v4()) + tmp_os << address(); + else + tmp_os << '[' << address() << ']'; + tmp_os << ':' << port(); + + return tmp_os.str(); +} +#endif // !defined(ASIO_NO_IOSTREAM) + +} // namespace detail +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_DETAIL_IMPL_ENDPOINT_IPP diff --git a/lib/asio/ip/detail/socket_option.hpp b/lib/asio/ip/detail/socket_option.hpp new file mode 100644 index 0000000..051ef30 --- /dev/null +++ b/lib/asio/ip/detail/socket_option.hpp @@ -0,0 +1,566 @@ +// +// detail/socket_option.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_DETAIL_SOCKET_OPTION_HPP +#define ASIO_IP_DETAIL_SOCKET_OPTION_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include <cstddef> +#include <cstring> +#include <stdexcept> +#include "asio/detail/socket_ops.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/detail/throw_exception.hpp" +#include "asio/ip/address.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { +namespace detail { +namespace socket_option { + +// Helper template for implementing multicast enable loopback options. +template <int IPv4_Level, int IPv4_Name, int IPv6_Level, int IPv6_Name> +class multicast_enable_loopback +{ +public: +#if defined(__sun) || defined(__osf__) + typedef unsigned char ipv4_value_type; + typedef unsigned char ipv6_value_type; +#elif defined(_AIX) || defined(__hpux) || defined(__QNXNTO__) + typedef unsigned char ipv4_value_type; + typedef unsigned int ipv6_value_type; +#else + typedef int ipv4_value_type; + typedef int ipv6_value_type; +#endif + + // Default constructor. + multicast_enable_loopback() + : ipv4_value_(0), + ipv6_value_(0) + { + } + + // Construct with a specific option value. + explicit multicast_enable_loopback(bool v) + : ipv4_value_(v ? 1 : 0), + ipv6_value_(v ? 1 : 0) + { + } + + // Set the value of the boolean. + multicast_enable_loopback& operator=(bool v) + { + ipv4_value_ = v ? 1 : 0; + ipv6_value_ = v ? 1 : 0; + return *this; + } + + // Get the current value of the boolean. + bool value() const + { + return !!ipv4_value_; + } + + // Convert to bool. + operator bool() const + { + return !!ipv4_value_; + } + + // Test for false. + bool operator!() const + { + return !ipv4_value_; + } + + // Get the level of the socket option. + template <typename Protocol> + int level(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Level; + return IPv4_Level; + } + + // Get the name of the socket option. + template <typename Protocol> + int name(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Name; + return IPv4_Name; + } + + // Get the address of the boolean data. + template <typename Protocol> + void* data(const Protocol& protocol) + { + if (protocol.family() == PF_INET6) + return &ipv6_value_; + return &ipv4_value_; + } + + // Get the address of the boolean data. + template <typename Protocol> + const void* data(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return &ipv6_value_; + return &ipv4_value_; + } + + // Get the size of the boolean data. + template <typename Protocol> + std::size_t size(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return sizeof(ipv6_value_); + return sizeof(ipv4_value_); + } + + // Set the size of the boolean data. + template <typename Protocol> + void resize(const Protocol& protocol, std::size_t s) + { + if (protocol.family() == PF_INET6) + { + if (s != sizeof(ipv6_value_)) + { + std::length_error ex("multicast_enable_loopback socket option resize"); + asio::detail::throw_exception(ex); + } + ipv4_value_ = ipv6_value_ ? 1 : 0; + } + else + { + if (s != sizeof(ipv4_value_)) + { + std::length_error ex("multicast_enable_loopback socket option resize"); + asio::detail::throw_exception(ex); + } + ipv6_value_ = ipv4_value_ ? 1 : 0; + } + } + +private: + ipv4_value_type ipv4_value_; + ipv6_value_type ipv6_value_; +}; + +// Helper template for implementing unicast hops options. +template <int IPv4_Level, int IPv4_Name, int IPv6_Level, int IPv6_Name> +class unicast_hops +{ +public: + // Default constructor. + unicast_hops() + : value_(0) + { + } + + // Construct with a specific option value. + explicit unicast_hops(int v) + : value_(v) + { + } + + // Set the value of the option. + unicast_hops& operator=(int v) + { + value_ = v; + return *this; + } + + // Get the current value of the option. + int value() const + { + return value_; + } + + // Get the level of the socket option. + template <typename Protocol> + int level(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Level; + return IPv4_Level; + } + + // Get the name of the socket option. + template <typename Protocol> + int name(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Name; + return IPv4_Name; + } + + // Get the address of the data. + template <typename Protocol> + int* data(const Protocol&) + { + return &value_; + } + + // Get the address of the data. + template <typename Protocol> + const int* data(const Protocol&) const + { + return &value_; + } + + // Get the size of the data. + template <typename Protocol> + std::size_t size(const Protocol&) const + { + return sizeof(value_); + } + + // Set the size of the data. + template <typename Protocol> + void resize(const Protocol&, std::size_t s) + { + if (s != sizeof(value_)) + { + std::length_error ex("unicast hops socket option resize"); + asio::detail::throw_exception(ex); + } +#if defined(__hpux) + if (value_ < 0) + value_ = value_ & 0xFF; +#endif + } + +private: + int value_; +}; + +// Helper template for implementing multicast hops options. +template <int IPv4_Level, int IPv4_Name, int IPv6_Level, int IPv6_Name> +class multicast_hops +{ +public: +#if defined(ASIO_WINDOWS) && defined(UNDER_CE) + typedef int ipv4_value_type; +#else + typedef unsigned char ipv4_value_type; +#endif + typedef int ipv6_value_type; + + // Default constructor. + multicast_hops() + : ipv4_value_(0), + ipv6_value_(0) + { + } + + // Construct with a specific option value. + explicit multicast_hops(int v) + { + if (v < 0 || v > 255) + { + std::out_of_range ex("multicast hops value out of range"); + asio::detail::throw_exception(ex); + } + ipv4_value_ = (ipv4_value_type)v; + ipv6_value_ = v; + } + + // Set the value of the option. + multicast_hops& operator=(int v) + { + if (v < 0 || v > 255) + { + std::out_of_range ex("multicast hops value out of range"); + asio::detail::throw_exception(ex); + } + ipv4_value_ = (ipv4_value_type)v; + ipv6_value_ = v; + return *this; + } + + // Get the current value of the option. + int value() const + { + return ipv6_value_; + } + + // Get the level of the socket option. + template <typename Protocol> + int level(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Level; + return IPv4_Level; + } + + // Get the name of the socket option. + template <typename Protocol> + int name(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Name; + return IPv4_Name; + } + + // Get the address of the data. + template <typename Protocol> + void* data(const Protocol& protocol) + { + if (protocol.family() == PF_INET6) + return &ipv6_value_; + return &ipv4_value_; + } + + // Get the address of the data. + template <typename Protocol> + const void* data(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return &ipv6_value_; + return &ipv4_value_; + } + + // Get the size of the data. + template <typename Protocol> + std::size_t size(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return sizeof(ipv6_value_); + return sizeof(ipv4_value_); + } + + // Set the size of the data. + template <typename Protocol> + void resize(const Protocol& protocol, std::size_t s) + { + if (protocol.family() == PF_INET6) + { + if (s != sizeof(ipv6_value_)) + { + std::length_error ex("multicast hops socket option resize"); + asio::detail::throw_exception(ex); + } + if (ipv6_value_ < 0) + ipv4_value_ = 0; + else if (ipv6_value_ > 255) + ipv4_value_ = 255; + else + ipv4_value_ = (ipv4_value_type)ipv6_value_; + } + else + { + if (s != sizeof(ipv4_value_)) + { + std::length_error ex("multicast hops socket option resize"); + asio::detail::throw_exception(ex); + } + ipv6_value_ = ipv4_value_; + } + } + +private: + ipv4_value_type ipv4_value_; + ipv6_value_type ipv6_value_; +}; + +// Helper template for implementing ip_mreq-based options. +template <int IPv4_Level, int IPv4_Name, int IPv6_Level, int IPv6_Name> +class multicast_request +{ +public: + // Default constructor. + multicast_request() + : ipv4_value_(), // Zero-initialisation gives the "any" address. + ipv6_value_() // Zero-initialisation gives the "any" address. + { + } + + // Construct with multicast address only. + explicit multicast_request(const address& multicast_address) + : ipv4_value_(), // Zero-initialisation gives the "any" address. + ipv6_value_() // Zero-initialisation gives the "any" address. + { + if (multicast_address.is_v6()) + { + using namespace std; // For memcpy. + address_v6 ipv6_address = multicast_address.to_v6(); + address_v6::bytes_type bytes = ipv6_address.to_bytes(); + memcpy(ipv6_value_.ipv6mr_multiaddr.s6_addr, bytes.data(), 16); + ipv6_value_.ipv6mr_interface = ipv6_address.scope_id(); + } + else + { + ipv4_value_.imr_multiaddr.s_addr = + asio::detail::socket_ops::host_to_network_long( + multicast_address.to_v4().to_uint()); + ipv4_value_.imr_interface.s_addr = + asio::detail::socket_ops::host_to_network_long( + address_v4::any().to_uint()); + } + } + + // Construct with multicast address and IPv4 address specifying an interface. + explicit multicast_request(const address_v4& multicast_address, + const address_v4& network_interface = address_v4::any()) + : ipv6_value_() // Zero-initialisation gives the "any" address. + { + ipv4_value_.imr_multiaddr.s_addr = + asio::detail::socket_ops::host_to_network_long( + multicast_address.to_uint()); + ipv4_value_.imr_interface.s_addr = + asio::detail::socket_ops::host_to_network_long( + network_interface.to_uint()); + } + + // Construct with multicast address and IPv6 network interface index. + explicit multicast_request( + const address_v6& multicast_address, + unsigned long network_interface = 0) + : ipv4_value_() // Zero-initialisation gives the "any" address. + { + using namespace std; // For memcpy. + address_v6::bytes_type bytes = multicast_address.to_bytes(); + memcpy(ipv6_value_.ipv6mr_multiaddr.s6_addr, bytes.data(), 16); + if (network_interface) + ipv6_value_.ipv6mr_interface = network_interface; + else + ipv6_value_.ipv6mr_interface = multicast_address.scope_id(); + } + + // Get the level of the socket option. + template <typename Protocol> + int level(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Level; + return IPv4_Level; + } + + // Get the name of the socket option. + template <typename Protocol> + int name(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Name; + return IPv4_Name; + } + + // Get the address of the option data. + template <typename Protocol> + const void* data(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return &ipv6_value_; + return &ipv4_value_; + } + + // Get the size of the option data. + template <typename Protocol> + std::size_t size(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return sizeof(ipv6_value_); + return sizeof(ipv4_value_); + } + +private: + asio::detail::in4_mreq_type ipv4_value_; + asio::detail::in6_mreq_type ipv6_value_; +}; + +// Helper template for implementing options that specify a network interface. +template <int IPv4_Level, int IPv4_Name, int IPv6_Level, int IPv6_Name> +class network_interface +{ +public: + // Default constructor. + network_interface() + { + ipv4_value_.s_addr = + asio::detail::socket_ops::host_to_network_long( + address_v4::any().to_uint()); + ipv6_value_ = 0; + } + + // Construct with IPv4 interface. + explicit network_interface(const address_v4& ipv4_interface) + { + ipv4_value_.s_addr = + asio::detail::socket_ops::host_to_network_long( + ipv4_interface.to_uint()); + ipv6_value_ = 0; + } + + // Construct with IPv6 interface. + explicit network_interface(unsigned int ipv6_interface) + { + ipv4_value_.s_addr = + asio::detail::socket_ops::host_to_network_long( + address_v4::any().to_uint()); + ipv6_value_ = ipv6_interface; + } + + // Get the level of the socket option. + template <typename Protocol> + int level(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Level; + return IPv4_Level; + } + + // Get the name of the socket option. + template <typename Protocol> + int name(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return IPv6_Name; + return IPv4_Name; + } + + // Get the address of the option data. + template <typename Protocol> + const void* data(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return &ipv6_value_; + return &ipv4_value_; + } + + // Get the size of the option data. + template <typename Protocol> + std::size_t size(const Protocol& protocol) const + { + if (protocol.family() == PF_INET6) + return sizeof(ipv6_value_); + return sizeof(ipv4_value_); + } + +private: + asio::detail::in4_addr_type ipv4_value_; + unsigned int ipv6_value_; +}; + +} // namespace socket_option +} // namespace detail +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_DETAIL_SOCKET_OPTION_HPP diff --git a/lib/asio/ip/host_name.hpp b/lib/asio/ip/host_name.hpp new file mode 100644 index 0000000..d06de50 --- /dev/null +++ b/lib/asio/ip/host_name.hpp @@ -0,0 +1,42 @@ +// +// ip/host_name.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_HOST_NAME_HPP +#define ASIO_IP_HOST_NAME_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include <string> +#include "asio/error_code.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// Get the current host name. +ASIO_DECL std::string host_name(); + +/// Get the current host name. +ASIO_DECL std::string host_name(asio::error_code& ec); + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#if defined(ASIO_HEADER_ONLY) +# include "asio/ip/impl/host_name.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_IP_HOST_NAME_HPP diff --git a/lib/asio/ip/icmp.hpp b/lib/asio/ip/icmp.hpp new file mode 100644 index 0000000..92e1953 --- /dev/null +++ b/lib/asio/ip/icmp.hpp @@ -0,0 +1,115 @@ +// +// ip/icmp.hpp +// ~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_ICMP_HPP +#define ASIO_IP_ICMP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/basic_raw_socket.hpp" +#include "asio/ip/basic_endpoint.hpp" +#include "asio/ip/basic_resolver.hpp" +#include "asio/ip/basic_resolver_iterator.hpp" +#include "asio/ip/basic_resolver_query.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// Encapsulates the flags needed for ICMP. +/** + * The asio::ip::icmp class contains flags necessary for ICMP sockets. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Safe. + * + * @par Concepts: + * Protocol, InternetProtocol. + */ +class icmp +{ +public: + /// The type of a ICMP endpoint. + typedef basic_endpoint<icmp> endpoint; + + /// Construct to represent the IPv4 ICMP protocol. + static icmp v4() + { + return icmp(ASIO_OS_DEF(IPPROTO_ICMP), + ASIO_OS_DEF(AF_INET)); + } + + /// Construct to represent the IPv6 ICMP protocol. + static icmp v6() + { + return icmp(ASIO_OS_DEF(IPPROTO_ICMPV6), + ASIO_OS_DEF(AF_INET6)); + } + + /// Obtain an identifier for the type of the protocol. + int type() const + { + return ASIO_OS_DEF(SOCK_RAW); + } + + /// Obtain an identifier for the protocol. + int protocol() const + { + return protocol_; + } + + /// Obtain an identifier for the protocol family. + int family() const + { + return family_; + } + + /// The ICMP socket type. + typedef basic_raw_socket<icmp> socket; + + /// The ICMP resolver type. + typedef basic_resolver<icmp> resolver; + + /// Compare two protocols for equality. + friend bool operator==(const icmp& p1, const icmp& p2) + { + return p1.protocol_ == p2.protocol_ && p1.family_ == p2.family_; + } + + /// Compare two protocols for inequality. + friend bool operator!=(const icmp& p1, const icmp& p2) + { + return p1.protocol_ != p2.protocol_ || p1.family_ != p2.family_; + } + +private: + // Construct with a specific family. + explicit icmp(int protocol_id, int protocol_family) + : protocol_(protocol_id), + family_(protocol_family) + { + } + + int protocol_; + int family_; +}; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_ICMP_HPP diff --git a/lib/asio/ip/impl/address.hpp b/lib/asio/ip/impl/address.hpp new file mode 100644 index 0000000..085b93f --- /dev/null +++ b/lib/asio/ip/impl/address.hpp @@ -0,0 +1,67 @@ +// +// ip/impl/address.hpp +// ~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_IMPL_ADDRESS_HPP +#define ASIO_IP_IMPL_ADDRESS_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#if !defined(ASIO_NO_IOSTREAM) + +#include "asio/detail/throw_error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +#if !defined(ASIO_NO_DEPRECATED) + +inline address address::from_string(const char* str) +{ + return asio::ip::make_address(str); +} + +inline address address::from_string( + const char* str, asio::error_code& ec) +{ + return asio::ip::make_address(str, ec); +} + +inline address address::from_string(const std::string& str) +{ + return asio::ip::make_address(str); +} + +inline address address::from_string( + const std::string& str, asio::error_code& ec) +{ + return asio::ip::make_address(str, ec); +} + +#endif // !defined(ASIO_NO_DEPRECATED) + +template <typename Elem, typename Traits> +std::basic_ostream<Elem, Traits>& operator<<( + std::basic_ostream<Elem, Traits>& os, const address& addr) +{ + return os << addr.to_string().c_str(); +} + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // !defined(ASIO_NO_IOSTREAM) + +#endif // ASIO_IP_IMPL_ADDRESS_HPP diff --git a/lib/asio/ip/impl/address.ipp b/lib/asio/ip/impl/address.ipp new file mode 100644 index 0000000..0523071 --- /dev/null +++ b/lib/asio/ip/impl/address.ipp @@ -0,0 +1,234 @@ +// +// ip/impl/address.ipp +// ~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_IMPL_ADDRESS_IPP +#define ASIO_IP_IMPL_ADDRESS_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include <typeinfo> +#include "asio/detail/throw_error.hpp" +#include "asio/detail/throw_exception.hpp" +#include "asio/error.hpp" +#include "asio/ip/address.hpp" +#include "asio/ip/bad_address_cast.hpp" +#include "asio/system_error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +address::address() + : type_(ipv4), + ipv4_address_(), + ipv6_address_() +{ +} + +address::address(const asio::ip::address_v4& ipv4_address) + : type_(ipv4), + ipv4_address_(ipv4_address), + ipv6_address_() +{ +} + +address::address(const asio::ip::address_v6& ipv6_address) + : type_(ipv6), + ipv4_address_(), + ipv6_address_(ipv6_address) +{ +} + +address::address(const address& other) + : type_(other.type_), + ipv4_address_(other.ipv4_address_), + ipv6_address_(other.ipv6_address_) +{ +} + +#if defined(ASIO_HAS_MOVE) +address::address(address&& other) + : type_(other.type_), + ipv4_address_(other.ipv4_address_), + ipv6_address_(other.ipv6_address_) +{ +} +#endif // defined(ASIO_HAS_MOVE) + +address& address::operator=(const address& other) +{ + type_ = other.type_; + ipv4_address_ = other.ipv4_address_; + ipv6_address_ = other.ipv6_address_; + return *this; +} + +#if defined(ASIO_HAS_MOVE) +address& address::operator=(address&& other) +{ + type_ = other.type_; + ipv4_address_ = other.ipv4_address_; + ipv6_address_ = other.ipv6_address_; + return *this; +} +#endif // defined(ASIO_HAS_MOVE) + +address& address::operator=(const asio::ip::address_v4& ipv4_address) +{ + type_ = ipv4; + ipv4_address_ = ipv4_address; + ipv6_address_ = asio::ip::address_v6(); + return *this; +} + +address& address::operator=(const asio::ip::address_v6& ipv6_address) +{ + type_ = ipv6; + ipv4_address_ = asio::ip::address_v4(); + ipv6_address_ = ipv6_address; + return *this; +} + +address make_address(const char* str) +{ + asio::error_code ec; + address addr = make_address(str, ec); + asio::detail::throw_error(ec); + return addr; +} + +address make_address(const char* str, asio::error_code& ec) +{ + asio::ip::address_v6 ipv6_address = + asio::ip::make_address_v6(str, ec); + if (!ec) + return address(ipv6_address); + + asio::ip::address_v4 ipv4_address = + asio::ip::make_address_v4(str, ec); + if (!ec) + return address(ipv4_address); + + return address(); +} + +address make_address(const std::string& str) +{ + return make_address(str.c_str()); +} + +address make_address(const std::string& str, + asio::error_code& ec) +{ + return make_address(str.c_str(), ec); +} + +#if defined(ASIO_HAS_STRING_VIEW) + +address make_address(string_view str) +{ + return make_address(static_cast<std::string>(str)); +} + +address make_address(string_view str, + asio::error_code& ec) +{ + return make_address(static_cast<std::string>(str), ec); +} + +#endif // defined(ASIO_HAS_STRING_VIEW) + +asio::ip::address_v4 address::to_v4() const +{ + if (type_ != ipv4) + { + bad_address_cast ex; + asio::detail::throw_exception(ex); + } + return ipv4_address_; +} + +asio::ip::address_v6 address::to_v6() const +{ + if (type_ != ipv6) + { + bad_address_cast ex; + asio::detail::throw_exception(ex); + } + return ipv6_address_; +} + +std::string address::to_string() const +{ + if (type_ == ipv6) + return ipv6_address_.to_string(); + return ipv4_address_.to_string(); +} + +#if !defined(ASIO_NO_DEPRECATED) +std::string address::to_string(asio::error_code& ec) const +{ + if (type_ == ipv6) + return ipv6_address_.to_string(ec); + return ipv4_address_.to_string(ec); +} +#endif // !defined(ASIO_NO_DEPRECATED) + +bool address::is_loopback() const +{ + return (type_ == ipv4) + ? ipv4_address_.is_loopback() + : ipv6_address_.is_loopback(); +} + +bool address::is_unspecified() const +{ + return (type_ == ipv4) + ? ipv4_address_.is_unspecified() + : ipv6_address_.is_unspecified(); +} + +bool address::is_multicast() const +{ + return (type_ == ipv4) + ? ipv4_address_.is_multicast() + : ipv6_address_.is_multicast(); +} + +bool operator==(const address& a1, const address& a2) +{ + if (a1.type_ != a2.type_) + return false; + if (a1.type_ == address::ipv6) + return a1.ipv6_address_ == a2.ipv6_address_; + return a1.ipv4_address_ == a2.ipv4_address_; +} + +bool operator<(const address& a1, const address& a2) +{ + if (a1.type_ < a2.type_) + return true; + if (a1.type_ > a2.type_) + return false; + if (a1.type_ == address::ipv6) + return a1.ipv6_address_ < a2.ipv6_address_; + return a1.ipv4_address_ < a2.ipv4_address_; +} + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_IMPL_ADDRESS_IPP diff --git a/lib/asio/ip/impl/address_v4.hpp b/lib/asio/ip/impl/address_v4.hpp new file mode 100644 index 0000000..d1cf407 --- /dev/null +++ b/lib/asio/ip/impl/address_v4.hpp @@ -0,0 +1,67 @@ +// +// ip/impl/address_v4.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_IMPL_ADDRESS_V4_HPP +#define ASIO_IP_IMPL_ADDRESS_V4_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#if !defined(ASIO_NO_IOSTREAM) + +#include "asio/detail/throw_error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +#if !defined(ASIO_NO_DEPRECATED) + +inline address_v4 address_v4::from_string(const char* str) +{ + return asio::ip::make_address_v4(str); +} + +inline address_v4 address_v4::from_string( + const char* str, asio::error_code& ec) +{ + return asio::ip::make_address_v4(str, ec); +} + +inline address_v4 address_v4::from_string(const std::string& str) +{ + return asio::ip::make_address_v4(str); +} + +inline address_v4 address_v4::from_string( + const std::string& str, asio::error_code& ec) +{ + return asio::ip::make_address_v4(str, ec); +} + +#endif // !defined(ASIO_NO_DEPRECATED) + +template <typename Elem, typename Traits> +std::basic_ostream<Elem, Traits>& operator<<( + std::basic_ostream<Elem, Traits>& os, const address_v4& addr) +{ + return os << addr.to_string().c_str(); +} + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // !defined(ASIO_NO_IOSTREAM) + +#endif // ASIO_IP_IMPL_ADDRESS_V4_HPP diff --git a/lib/asio/ip/impl/address_v4.ipp b/lib/asio/ip/impl/address_v4.ipp new file mode 100644 index 0000000..9559add --- /dev/null +++ b/lib/asio/ip/impl/address_v4.ipp @@ -0,0 +1,210 @@ +// +// ip/impl/address_v4.ipp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_IMPL_ADDRESS_V4_IPP +#define ASIO_IP_IMPL_ADDRESS_V4_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include <climits> +#include <limits> +#include <stdexcept> +#include "asio/error.hpp" +#include "asio/detail/socket_ops.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/detail/throw_exception.hpp" +#include "asio/ip/address_v4.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +address_v4::address_v4(const address_v4::bytes_type& bytes) +{ +#if UCHAR_MAX > 0xFF + if (bytes[0] > 0xFF || bytes[1] > 0xFF + || bytes[2] > 0xFF || bytes[3] > 0xFF) + { + std::out_of_range ex("address_v4 from bytes_type"); + asio::detail::throw_exception(ex); + } +#endif // UCHAR_MAX > 0xFF + + using namespace std; // For memcpy. + memcpy(&addr_.s_addr, bytes.data(), 4); +} + +address_v4::address_v4(address_v4::uint_type addr) +{ + if ((std::numeric_limits<uint_type>::max)() > 0xFFFFFFFF) + { + std::out_of_range ex("address_v4 from unsigned integer"); + asio::detail::throw_exception(ex); + } + + addr_.s_addr = asio::detail::socket_ops::host_to_network_long( + static_cast<asio::detail::u_long_type>(addr)); +} + +address_v4::bytes_type address_v4::to_bytes() const +{ + using namespace std; // For memcpy. + bytes_type bytes; +#if defined(ASIO_HAS_STD_ARRAY) + memcpy(bytes.data(), &addr_.s_addr, 4); +#else // defined(ASIO_HAS_STD_ARRAY) + memcpy(bytes.elems, &addr_.s_addr, 4); +#endif // defined(ASIO_HAS_STD_ARRAY) + return bytes; +} + +address_v4::uint_type address_v4::to_uint() const +{ + return asio::detail::socket_ops::network_to_host_long(addr_.s_addr); +} + +#if !defined(ASIO_NO_DEPRECATED) +unsigned long address_v4::to_ulong() const +{ + return asio::detail::socket_ops::network_to_host_long(addr_.s_addr); +} +#endif // !defined(ASIO_NO_DEPRECATED) + +std::string address_v4::to_string() const +{ + asio::error_code ec; + char addr_str[asio::detail::max_addr_v4_str_len]; + const char* addr = + asio::detail::socket_ops::inet_ntop( + ASIO_OS_DEF(AF_INET), &addr_, addr_str, + asio::detail::max_addr_v4_str_len, 0, ec); + if (addr == 0) + asio::detail::throw_error(ec); + return addr; +} + +#if !defined(ASIO_NO_DEPRECATED) +std::string address_v4::to_string(asio::error_code& ec) const +{ + char addr_str[asio::detail::max_addr_v4_str_len]; + const char* addr = + asio::detail::socket_ops::inet_ntop( + ASIO_OS_DEF(AF_INET), &addr_, addr_str, + asio::detail::max_addr_v4_str_len, 0, ec); + if (addr == 0) + return std::string(); + return addr; +} +#endif // !defined(ASIO_NO_DEPRECATED) + +bool address_v4::is_loopback() const +{ + return (to_uint() & 0xFF000000) == 0x7F000000; +} + +bool address_v4::is_unspecified() const +{ + return to_uint() == 0; +} + +#if !defined(ASIO_NO_DEPRECATED) +bool address_v4::is_class_a() const +{ + return (to_uint() & 0x80000000) == 0; +} + +bool address_v4::is_class_b() const +{ + return (to_uint() & 0xC0000000) == 0x80000000; +} + +bool address_v4::is_class_c() const +{ + return (to_uint() & 0xE0000000) == 0xC0000000; +} +#endif // !defined(ASIO_NO_DEPRECATED) + +bool address_v4::is_multicast() const +{ + return (to_uint() & 0xF0000000) == 0xE0000000; +} + +#if !defined(ASIO_NO_DEPRECATED) +address_v4 address_v4::broadcast(const address_v4& addr, const address_v4& mask) +{ + return address_v4(addr.to_uint() | (mask.to_uint() ^ 0xFFFFFFFF)); +} + +address_v4 address_v4::netmask(const address_v4& addr) +{ + if (addr.is_class_a()) + return address_v4(0xFF000000); + if (addr.is_class_b()) + return address_v4(0xFFFF0000); + if (addr.is_class_c()) + return address_v4(0xFFFFFF00); + return address_v4(0xFFFFFFFF); +} +#endif // !defined(ASIO_NO_DEPRECATED) + +address_v4 make_address_v4(const char* str) +{ + asio::error_code ec; + address_v4 addr = make_address_v4(str, ec); + asio::detail::throw_error(ec); + return addr; +} + +address_v4 make_address_v4( + const char* str, asio::error_code& ec) +{ + address_v4::bytes_type bytes; + if (asio::detail::socket_ops::inet_pton( + ASIO_OS_DEF(AF_INET), str, &bytes, 0, ec) <= 0) + return address_v4(); + return address_v4(bytes); +} + +address_v4 make_address_v4(const std::string& str) +{ + return make_address_v4(str.c_str()); +} + +address_v4 make_address_v4( + const std::string& str, asio::error_code& ec) +{ + return make_address_v4(str.c_str(), ec); +} + +#if defined(ASIO_HAS_STRING_VIEW) + +address_v4 make_address_v4(string_view str) +{ + return make_address_v4(static_cast<std::string>(str)); +} + +address_v4 make_address_v4(string_view str, + asio::error_code& ec) +{ + return make_address_v4(static_cast<std::string>(str), ec); +} + +#endif // defined(ASIO_HAS_STRING_VIEW) + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_IMPL_ADDRESS_V4_IPP diff --git a/lib/asio/ip/impl/address_v6.hpp b/lib/asio/ip/impl/address_v6.hpp new file mode 100644 index 0000000..330eafd --- /dev/null +++ b/lib/asio/ip/impl/address_v6.hpp @@ -0,0 +1,67 @@ +// +// ip/impl/address_v6.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_IMPL_ADDRESS_V6_HPP +#define ASIO_IP_IMPL_ADDRESS_V6_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#if !defined(ASIO_NO_IOSTREAM) + +#include "asio/detail/throw_error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +#if !defined(ASIO_NO_DEPRECATED) + +inline address_v6 address_v6::from_string(const char* str) +{ + return asio::ip::make_address_v6(str); +} + +inline address_v6 address_v6::from_string( + const char* str, asio::error_code& ec) +{ + return asio::ip::make_address_v6(str, ec); +} + +inline address_v6 address_v6::from_string(const std::string& str) +{ + return asio::ip::make_address_v6(str); +} + +inline address_v6 address_v6::from_string( + const std::string& str, asio::error_code& ec) +{ + return asio::ip::make_address_v6(str, ec); +} + +#endif // !defined(ASIO_NO_DEPRECATED) + +template <typename Elem, typename Traits> +std::basic_ostream<Elem, Traits>& operator<<( + std::basic_ostream<Elem, Traits>& os, const address_v6& addr) +{ + return os << addr.to_string().c_str(); +} + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // !defined(ASIO_NO_IOSTREAM) + +#endif // ASIO_IP_IMPL_ADDRESS_V6_HPP diff --git a/lib/asio/ip/impl/address_v6.ipp b/lib/asio/ip/impl/address_v6.ipp new file mode 100644 index 0000000..36bd68c --- /dev/null +++ b/lib/asio/ip/impl/address_v6.ipp @@ -0,0 +1,350 @@ +// +// ip/impl/address_v6.ipp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_IMPL_ADDRESS_V6_IPP +#define ASIO_IP_IMPL_ADDRESS_V6_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include <cstring> +#include <stdexcept> +#include <typeinfo> +#include "asio/detail/socket_ops.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/detail/throw_exception.hpp" +#include "asio/error.hpp" +#include "asio/ip/address_v6.hpp" +#include "asio/ip/bad_address_cast.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +address_v6::address_v6() + : addr_(), + scope_id_(0) +{ +} + +address_v6::address_v6(const address_v6::bytes_type& bytes, + unsigned long scope) + : scope_id_(scope) +{ +#if UCHAR_MAX > 0xFF + for (std::size_t i = 0; i < bytes.size(); ++i) + { + if (bytes[i] > 0xFF) + { + std::out_of_range ex("address_v6 from bytes_type"); + asio::detail::throw_exception(ex); + } + } +#endif // UCHAR_MAX > 0xFF + + using namespace std; // For memcpy. + memcpy(addr_.s6_addr, bytes.data(), 16); +} + +address_v6::address_v6(const address_v6& other) + : addr_(other.addr_), + scope_id_(other.scope_id_) +{ +} + +#if defined(ASIO_HAS_MOVE) +address_v6::address_v6(address_v6&& other) + : addr_(other.addr_), + scope_id_(other.scope_id_) +{ +} +#endif // defined(ASIO_HAS_MOVE) + +address_v6& address_v6::operator=(const address_v6& other) +{ + addr_ = other.addr_; + scope_id_ = other.scope_id_; + return *this; +} + +#if defined(ASIO_HAS_MOVE) +address_v6& address_v6::operator=(address_v6&& other) +{ + addr_ = other.addr_; + scope_id_ = other.scope_id_; + return *this; +} +#endif // defined(ASIO_HAS_MOVE) + +address_v6::bytes_type address_v6::to_bytes() const +{ + using namespace std; // For memcpy. + bytes_type bytes; +#if defined(ASIO_HAS_STD_ARRAY) + memcpy(bytes.data(), addr_.s6_addr, 16); +#else // defined(ASIO_HAS_STD_ARRAY) + memcpy(bytes.elems, addr_.s6_addr, 16); +#endif // defined(ASIO_HAS_STD_ARRAY) + return bytes; +} + +std::string address_v6::to_string() const +{ + asio::error_code ec; + char addr_str[asio::detail::max_addr_v6_str_len]; + const char* addr = + asio::detail::socket_ops::inet_ntop( + ASIO_OS_DEF(AF_INET6), &addr_, addr_str, + asio::detail::max_addr_v6_str_len, scope_id_, ec); + if (addr == 0) + asio::detail::throw_error(ec); + return addr; +} + +#if !defined(ASIO_NO_DEPRECATED) +std::string address_v6::to_string(asio::error_code& ec) const +{ + char addr_str[asio::detail::max_addr_v6_str_len]; + const char* addr = + asio::detail::socket_ops::inet_ntop( + ASIO_OS_DEF(AF_INET6), &addr_, addr_str, + asio::detail::max_addr_v6_str_len, scope_id_, ec); + if (addr == 0) + return std::string(); + return addr; +} + +address_v4 address_v6::to_v4() const +{ + if (!is_v4_mapped() && !is_v4_compatible()) + { + bad_address_cast ex; + asio::detail::throw_exception(ex); + } + + address_v4::bytes_type v4_bytes = { { addr_.s6_addr[12], + addr_.s6_addr[13], addr_.s6_addr[14], addr_.s6_addr[15] } }; + return address_v4(v4_bytes); +} +#endif // !defined(ASIO_NO_DEPRECATED) + +bool address_v6::is_loopback() const +{ + return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0) + && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0) + && (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0) + && (addr_.s6_addr[6] == 0) && (addr_.s6_addr[7] == 0) + && (addr_.s6_addr[8] == 0) && (addr_.s6_addr[9] == 0) + && (addr_.s6_addr[10] == 0) && (addr_.s6_addr[11] == 0) + && (addr_.s6_addr[12] == 0) && (addr_.s6_addr[13] == 0) + && (addr_.s6_addr[14] == 0) && (addr_.s6_addr[15] == 1)); +} + +bool address_v6::is_unspecified() const +{ + return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0) + && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0) + && (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0) + && (addr_.s6_addr[6] == 0) && (addr_.s6_addr[7] == 0) + && (addr_.s6_addr[8] == 0) && (addr_.s6_addr[9] == 0) + && (addr_.s6_addr[10] == 0) && (addr_.s6_addr[11] == 0) + && (addr_.s6_addr[12] == 0) && (addr_.s6_addr[13] == 0) + && (addr_.s6_addr[14] == 0) && (addr_.s6_addr[15] == 0)); +} + +bool address_v6::is_link_local() const +{ + return ((addr_.s6_addr[0] == 0xfe) && ((addr_.s6_addr[1] & 0xc0) == 0x80)); +} + +bool address_v6::is_site_local() const +{ + return ((addr_.s6_addr[0] == 0xfe) && ((addr_.s6_addr[1] & 0xc0) == 0xc0)); +} + +bool address_v6::is_v4_mapped() const +{ + return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0) + && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0) + && (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0) + && (addr_.s6_addr[6] == 0) && (addr_.s6_addr[7] == 0) + && (addr_.s6_addr[8] == 0) && (addr_.s6_addr[9] == 0) + && (addr_.s6_addr[10] == 0xff) && (addr_.s6_addr[11] == 0xff)); +} + +#if !defined(ASIO_NO_DEPRECATED) +bool address_v6::is_v4_compatible() const +{ + return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0) + && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0) + && (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0) + && (addr_.s6_addr[6] == 0) && (addr_.s6_addr[7] == 0) + && (addr_.s6_addr[8] == 0) && (addr_.s6_addr[9] == 0) + && (addr_.s6_addr[10] == 0) && (addr_.s6_addr[11] == 0) + && !((addr_.s6_addr[12] == 0) + && (addr_.s6_addr[13] == 0) + && (addr_.s6_addr[14] == 0) + && ((addr_.s6_addr[15] == 0) || (addr_.s6_addr[15] == 1)))); +} +#endif // !defined(ASIO_NO_DEPRECATED) + +bool address_v6::is_multicast() const +{ + return (addr_.s6_addr[0] == 0xff); +} + +bool address_v6::is_multicast_global() const +{ + return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x0e)); +} + +bool address_v6::is_multicast_link_local() const +{ + return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x02)); +} + +bool address_v6::is_multicast_node_local() const +{ + return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x01)); +} + +bool address_v6::is_multicast_org_local() const +{ + return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x08)); +} + +bool address_v6::is_multicast_site_local() const +{ + return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x05)); +} + +bool operator==(const address_v6& a1, const address_v6& a2) +{ + using namespace std; // For memcmp. + return memcmp(&a1.addr_, &a2.addr_, + sizeof(asio::detail::in6_addr_type)) == 0 + && a1.scope_id_ == a2.scope_id_; +} + +bool operator<(const address_v6& a1, const address_v6& a2) +{ + using namespace std; // For memcmp. + int memcmp_result = memcmp(&a1.addr_, &a2.addr_, + sizeof(asio::detail::in6_addr_type)); + if (memcmp_result < 0) + return true; + if (memcmp_result > 0) + return false; + return a1.scope_id_ < a2.scope_id_; +} + +address_v6 address_v6::loopback() +{ + address_v6 tmp; + tmp.addr_.s6_addr[15] = 1; + return tmp; +} + +#if !defined(ASIO_NO_DEPRECATED) +address_v6 address_v6::v4_mapped(const address_v4& addr) +{ + address_v4::bytes_type v4_bytes = addr.to_bytes(); + bytes_type v6_bytes = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, + v4_bytes[0], v4_bytes[1], v4_bytes[2], v4_bytes[3] } }; + return address_v6(v6_bytes); +} + +address_v6 address_v6::v4_compatible(const address_v4& addr) +{ + address_v4::bytes_type v4_bytes = addr.to_bytes(); + bytes_type v6_bytes = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + v4_bytes[0], v4_bytes[1], v4_bytes[2], v4_bytes[3] } }; + return address_v6(v6_bytes); +} +#endif // !defined(ASIO_NO_DEPRECATED) + +address_v6 make_address_v6(const char* str) +{ + asio::error_code ec; + address_v6 addr = make_address_v6(str, ec); + asio::detail::throw_error(ec); + return addr; +} + +address_v6 make_address_v6( + const char* str, asio::error_code& ec) +{ + address_v6::bytes_type bytes; + unsigned long scope_id = 0; + if (asio::detail::socket_ops::inet_pton( + ASIO_OS_DEF(AF_INET6), str, &bytes[0], &scope_id, ec) <= 0) + return address_v6(); + return address_v6(bytes, scope_id); +} + +address_v6 make_address_v6(const std::string& str) +{ + return make_address_v6(str.c_str()); +} + +address_v6 make_address_v6( + const std::string& str, asio::error_code& ec) +{ + return make_address_v6(str.c_str(), ec); +} + +#if defined(ASIO_HAS_STRING_VIEW) + +address_v6 make_address_v6(string_view str) +{ + return make_address_v6(static_cast<std::string>(str)); +} + +address_v6 make_address_v6(string_view str, + asio::error_code& ec) +{ + return make_address_v6(static_cast<std::string>(str), ec); +} + +#endif // defined(ASIO_HAS_STRING_VIEW) + +address_v4 make_address_v4( + v4_mapped_t, const address_v6& v6_addr) +{ + if (!v6_addr.is_v4_mapped()) + { + bad_address_cast ex; + asio::detail::throw_exception(ex); + } + + address_v6::bytes_type v6_bytes = v6_addr.to_bytes(); + address_v4::bytes_type v4_bytes = { { v6_bytes[12], + v6_bytes[13], v6_bytes[14], v6_bytes[15] } }; + return address_v4(v4_bytes); +} + +address_v6 make_address_v6( + v4_mapped_t, const address_v4& v4_addr) +{ + address_v4::bytes_type v4_bytes = v4_addr.to_bytes(); + address_v6::bytes_type v6_bytes = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0xFF, 0xFF, v4_bytes[0], v4_bytes[1], v4_bytes[2], v4_bytes[3] } }; + return address_v6(v6_bytes); +} + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_IMPL_ADDRESS_V6_IPP diff --git a/lib/asio/ip/impl/basic_endpoint.hpp b/lib/asio/ip/impl/basic_endpoint.hpp new file mode 100644 index 0000000..5680a43 --- /dev/null +++ b/lib/asio/ip/impl/basic_endpoint.hpp @@ -0,0 +1,43 @@ +// +// ip/impl/basic_endpoint.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_IMPL_BASIC_ENDPOINT_HPP +#define ASIO_IP_IMPL_BASIC_ENDPOINT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#if !defined(ASIO_NO_IOSTREAM) + +#include "asio/detail/throw_error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +template <typename Elem, typename Traits, typename InternetProtocol> +std::basic_ostream<Elem, Traits>& operator<<( + std::basic_ostream<Elem, Traits>& os, + const basic_endpoint<InternetProtocol>& endpoint) +{ + asio::ip::detail::endpoint tmp_ep(endpoint.address(), endpoint.port()); + return os << tmp_ep.to_string().c_str(); +} + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // !defined(ASIO_NO_IOSTREAM) + +#endif // ASIO_IP_IMPL_BASIC_ENDPOINT_HPP diff --git a/lib/asio/ip/impl/host_name.ipp b/lib/asio/ip/impl/host_name.ipp new file mode 100644 index 0000000..932ab1c --- /dev/null +++ b/lib/asio/ip/impl/host_name.ipp @@ -0,0 +1,54 @@ +// +// ip/impl/host_name.ipp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_IMPL_HOST_NAME_IPP +#define ASIO_IP_IMPL_HOST_NAME_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/socket_ops.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/detail/winsock_init.hpp" +#include "asio/ip/host_name.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +std::string host_name() +{ + char name[1024]; + asio::error_code ec; + if (asio::detail::socket_ops::gethostname(name, sizeof(name), ec) != 0) + { + asio::detail::throw_error(ec); + return std::string(); + } + return std::string(name); +} + +std::string host_name(asio::error_code& ec) +{ + char name[1024]; + if (asio::detail::socket_ops::gethostname(name, sizeof(name), ec) != 0) + return std::string(); + return std::string(name); +} + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_IMPL_HOST_NAME_IPP diff --git a/lib/asio/ip/impl/network_v4.hpp b/lib/asio/ip/impl/network_v4.hpp new file mode 100644 index 0000000..911a45c --- /dev/null +++ b/lib/asio/ip/impl/network_v4.hpp @@ -0,0 +1,54 @@ +// +// ip/impl/network_v4.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2014 Oliver Kowalke (oliver dot kowalke at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_IMPL_NETWORK_V4_HPP +#define ASIO_IP_IMPL_NETWORK_V4_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#if !defined(ASIO_NO_IOSTREAM) + +#include "asio/detail/throw_error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +template <typename Elem, typename Traits> +std::basic_ostream<Elem, Traits>& operator<<( + std::basic_ostream<Elem, Traits>& os, const network_v4& addr) +{ + asio::error_code ec; + std::string s = addr.to_string(ec); + if (ec) + { + if (os.exceptions() & std::basic_ostream<Elem, Traits>::failbit) + asio::detail::throw_error(ec); + else + os.setstate(std::basic_ostream<Elem, Traits>::failbit); + } + else + for (std::string::iterator i = s.begin(); i != s.end(); ++i) + os << os.widen(*i); + return os; +} + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // !defined(ASIO_NO_IOSTREAM) + +#endif // ASIO_IP_IMPL_NETWORK_V4_HPP diff --git a/lib/asio/ip/impl/network_v4.ipp b/lib/asio/ip/impl/network_v4.ipp new file mode 100644 index 0000000..4b27887 --- /dev/null +++ b/lib/asio/ip/impl/network_v4.ipp @@ -0,0 +1,216 @@ +// +// ip/impl/network_v4.ipp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2014 Oliver Kowalke (oliver dot kowalke at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_IMPL_NETWORK_V4_IPP +#define ASIO_IP_IMPL_NETWORK_V4_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include <climits> +#include <cstdio> +#include <cstdlib> +#include <stdexcept> +#include "asio/error.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/detail/throw_exception.hpp" +#include "asio/ip/network_v4.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +network_v4::network_v4(const address_v4& addr, unsigned short prefix_len) + : address_(addr), + prefix_length_(prefix_len) +{ + if (prefix_len > 32) + { + std::out_of_range ex("prefix length too large"); + asio::detail::throw_exception(ex); + } +} + +network_v4::network_v4(const address_v4& addr, const address_v4& mask) + : address_(addr), + prefix_length_(0) +{ + address_v4::bytes_type mask_bytes = mask.to_bytes(); + bool finished = false; + for (std::size_t i = 0; i < mask_bytes.size(); ++i) + { + if (finished) + { + if (mask_bytes[i]) + { + std::invalid_argument ex("non-contiguous netmask"); + asio::detail::throw_exception(ex); + } + continue; + } + else + { + switch (mask_bytes[i]) + { + case 255: + prefix_length_ += 8; + break; + case 254: // prefix_length_ += 7 + prefix_length_ += 1; + case 252: // prefix_length_ += 6 + prefix_length_ += 1; + case 248: // prefix_length_ += 5 + prefix_length_ += 1; + case 240: // prefix_length_ += 4 + prefix_length_ += 1; + case 224: // prefix_length_ += 3 + prefix_length_ += 1; + case 192: // prefix_length_ += 2 + prefix_length_ += 1; + case 128: // prefix_length_ += 1 + prefix_length_ += 1; + case 0: // nbits += 0 + finished = true; + break; + default: + std::out_of_range ex("non-contiguous netmask"); + asio::detail::throw_exception(ex); + } + } + } +} + +address_v4 network_v4::netmask() const ASIO_NOEXCEPT +{ + uint32_t nmbits = 0xffffffff; + if (prefix_length_ == 0) + nmbits = 0; + else + nmbits = nmbits << (32 - prefix_length_); + return address_v4(nmbits); +} + +address_v4_range network_v4::hosts() const ASIO_NOEXCEPT +{ + return is_host() + ? address_v4_range(address_, address_v4(address_.to_uint() + 1)) + : address_v4_range(address_v4(network().to_uint() + 1), broadcast()); +} + +bool network_v4::is_subnet_of(const network_v4& other) const +{ + if (other.prefix_length_ >= prefix_length_) + return false; // Only real subsets are allowed. + const network_v4 me(address_, other.prefix_length_); + return other.canonical() == me.canonical(); +} + +std::string network_v4::to_string() const +{ + asio::error_code ec; + std::string addr = to_string(ec); + asio::detail::throw_error(ec); + return addr; +} + +std::string network_v4::to_string(asio::error_code& ec) const +{ + using namespace std; // For sprintf. + ec = asio::error_code(); + char prefix_len[16]; +#if defined(ASIO_HAS_SECURE_RTL) + sprintf_s(prefix_len, sizeof(prefix_len), "/%u", prefix_length_); +#else // defined(ASIO_HAS_SECURE_RTL) + sprintf(prefix_len, "/%u", prefix_length_); +#endif // defined(ASIO_HAS_SECURE_RTL) + return address_.to_string() + prefix_len; +} + +network_v4 make_network_v4(const char* str) +{ + return make_network_v4(std::string(str)); +} + +network_v4 make_network_v4(const char* str, asio::error_code& ec) +{ + return make_network_v4(std::string(str), ec); +} + +network_v4 make_network_v4(const std::string& str) +{ + asio::error_code ec; + network_v4 net = make_network_v4(str, ec); + asio::detail::throw_error(ec); + return net; +} + +network_v4 make_network_v4(const std::string& str, + asio::error_code& ec) +{ + std::string::size_type pos = str.find_first_of("/"); + + if (pos == std::string::npos) + { + ec = asio::error::invalid_argument; + return network_v4(); + } + + if (pos == str.size() - 1) + { + ec = asio::error::invalid_argument; + return network_v4(); + } + + std::string::size_type end = str.find_first_not_of("0123456789", pos + 1); + if (end != std::string::npos) + { + ec = asio::error::invalid_argument; + return network_v4(); + } + + const address_v4 addr = make_address_v4(str.substr(0, pos), ec); + if (ec) + return network_v4(); + + const int prefix_len = std::atoi(str.substr(pos + 1).c_str()); + if (prefix_len < 0 || prefix_len > 32) + { + ec = asio::error::invalid_argument; + return network_v4(); + } + + return network_v4(addr, static_cast<unsigned short>(prefix_len)); +} + +#if defined(ASIO_HAS_STRING_VIEW) + +network_v4 make_network_v4(string_view str) +{ + return make_network_v4(static_cast<std::string>(str)); +} + +network_v4 make_network_v4(string_view str, + asio::error_code& ec) +{ + return make_network_v4(static_cast<std::string>(str), ec); +} + +#endif // defined(ASIO_HAS_STRING_VIEW) + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_IMPL_NETWORK_V4_IPP diff --git a/lib/asio/ip/impl/network_v6.hpp b/lib/asio/ip/impl/network_v6.hpp new file mode 100644 index 0000000..b0eedad --- /dev/null +++ b/lib/asio/ip/impl/network_v6.hpp @@ -0,0 +1,53 @@ +// +// ip/impl/network_v6.hpp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_IMPL_NETWORK_V6_HPP +#define ASIO_IP_IMPL_NETWORK_V6_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#if !defined(ASIO_NO_IOSTREAM) + +#include "asio/detail/throw_error.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +template <typename Elem, typename Traits> +std::basic_ostream<Elem, Traits>& operator<<( + std::basic_ostream<Elem, Traits>& os, const network_v6& addr) +{ + asio::error_code ec; + std::string s = addr.to_string(ec); + if (ec) + { + if (os.exceptions() & std::basic_ostream<Elem, Traits>::failbit) + asio::detail::throw_error(ec); + else + os.setstate(std::basic_ostream<Elem, Traits>::failbit); + } + else + for (std::string::iterator i = s.begin(); i != s.end(); ++i) + os << os.widen(*i); + return os; +} + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // !defined(ASIO_NO_IOSTREAM) + +#endif // ASIO_IP_IMPL_NETWORK_V6_HPP diff --git a/lib/asio/ip/impl/network_v6.ipp b/lib/asio/ip/impl/network_v6.ipp new file mode 100644 index 0000000..2e37a99 --- /dev/null +++ b/lib/asio/ip/impl/network_v6.ipp @@ -0,0 +1,185 @@ +// +// ip/impl/network_v6.ipp +// ~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2014 Oliver Kowalke (oliver dot kowalke at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_IMPL_NETWORK_V6_IPP +#define ASIO_IP_IMPL_NETWORK_V6_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include <climits> +#include <cstdio> +#include <cstdlib> +#include <stdexcept> +#include "asio/error.hpp" +#include "asio/detail/throw_error.hpp" +#include "asio/detail/throw_exception.hpp" +#include "asio/ip/network_v6.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +network_v6::network_v6(const address_v6& addr, unsigned short prefix_len) + : address_(addr), + prefix_length_(prefix_len) +{ + if (prefix_len > 128) + { + std::out_of_range ex("prefix length too large"); + asio::detail::throw_exception(ex); + } +} + +ASIO_DECL address_v6 network_v6::network() const ASIO_NOEXCEPT +{ + address_v6::bytes_type bytes(address_.to_bytes()); + for (std::size_t i = 0; i < 16; ++i) + { + if (prefix_length_ <= i * 8) + bytes[i] = 0; + else if (prefix_length_ < (i + 1) * 8) + bytes[i] &= 0xFF00 >> (prefix_length_ % 8); + } + return address_v6(bytes, address_.scope_id()); +} + +address_v6_range network_v6::hosts() const ASIO_NOEXCEPT +{ + address_v6::bytes_type begin_bytes(address_.to_bytes()); + address_v6::bytes_type end_bytes(address_.to_bytes()); + for (std::size_t i = 0; i < 16; ++i) + { + if (prefix_length_ <= i * 8) + { + begin_bytes[i] = 0; + end_bytes[i] = 0xFF; + } + else if (prefix_length_ < (i + 1) * 8) + { + begin_bytes[i] &= 0xFF00 >> (prefix_length_ % 8); + end_bytes[i] |= 0xFF >> (prefix_length_ % 8); + } + } + return address_v6_range( + address_v6_iterator(address_v6(begin_bytes, address_.scope_id())), + ++address_v6_iterator(address_v6(end_bytes, address_.scope_id()))); +} + +bool network_v6::is_subnet_of(const network_v6& other) const +{ + if (other.prefix_length_ >= prefix_length_) + return false; // Only real subsets are allowed. + const network_v6 me(address_, other.prefix_length_); + return other.canonical() == me.canonical(); +} + +std::string network_v6::to_string() const +{ + asio::error_code ec; + std::string addr = to_string(ec); + asio::detail::throw_error(ec); + return addr; +} + +std::string network_v6::to_string(asio::error_code& ec) const +{ + using namespace std; // For sprintf. + ec = asio::error_code(); + char prefix_len[16]; +#if defined(ASIO_HAS_SECURE_RTL) + sprintf_s(prefix_len, sizeof(prefix_len), "/%u", prefix_length_); +#else // defined(ASIO_HAS_SECURE_RTL) + sprintf(prefix_len, "/%u", prefix_length_); +#endif // defined(ASIO_HAS_SECURE_RTL) + return address_.to_string() + prefix_len; +} + +network_v6 make_network_v6(const char* str) +{ + return make_network_v6(std::string(str)); +} + +network_v6 make_network_v6(const char* str, asio::error_code& ec) +{ + return make_network_v6(std::string(str), ec); +} + +network_v6 make_network_v6(const std::string& str) +{ + asio::error_code ec; + network_v6 net = make_network_v6(str, ec); + asio::detail::throw_error(ec); + return net; +} + +network_v6 make_network_v6(const std::string& str, + asio::error_code& ec) +{ + std::string::size_type pos = str.find_first_of("/"); + + if (pos == std::string::npos) + { + ec = asio::error::invalid_argument; + return network_v6(); + } + + if (pos == str.size() - 1) + { + ec = asio::error::invalid_argument; + return network_v6(); + } + + std::string::size_type end = str.find_first_not_of("0123456789", pos + 1); + if (end != std::string::npos) + { + ec = asio::error::invalid_argument; + return network_v6(); + } + + const address_v6 addr = make_address_v6(str.substr(0, pos), ec); + if (ec) + return network_v6(); + + const int prefix_len = std::atoi(str.substr(pos + 1).c_str()); + if (prefix_len < 0 || prefix_len > 128) + { + ec = asio::error::invalid_argument; + return network_v6(); + } + + return network_v6(addr, static_cast<unsigned short>(prefix_len)); +} + +#if defined(ASIO_HAS_STRING_VIEW) + +network_v6 make_network_v6(string_view str) +{ + return make_network_v6(static_cast<std::string>(str)); +} + +network_v6 make_network_v6(string_view str, + asio::error_code& ec) +{ + return make_network_v6(static_cast<std::string>(str), ec); +} + +#endif // defined(ASIO_HAS_STRING_VIEW) + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_IMPL_NETWORK_V6_IPP diff --git a/lib/asio/ip/multicast.hpp b/lib/asio/ip/multicast.hpp new file mode 100644 index 0000000..ea624e1 --- /dev/null +++ b/lib/asio/ip/multicast.hpp @@ -0,0 +1,191 @@ +// +// ip/multicast.hpp +// ~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_MULTICAST_HPP +#define ASIO_IP_MULTICAST_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include <cstddef> +#include "asio/ip/detail/socket_option.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { +namespace multicast { + +/// Socket option to join a multicast group on a specified interface. +/** + * Implements the IPPROTO_IP/IP_ADD_MEMBERSHIP socket option. + * + * @par Examples + * Setting the option to join a multicast group: + * @code + * asio::ip::udp::socket socket(io_context); + * ... + * asio::ip::address multicast_address = + * asio::ip::address::from_string("225.0.0.1"); + * asio::ip::multicast::join_group option(multicast_address); + * socket.set_option(option); + * @endcode + * + * @par Concepts: + * SettableSocketOption. + */ +#if defined(GENERATING_DOCUMENTATION) +typedef implementation_defined join_group; +#else +typedef asio::ip::detail::socket_option::multicast_request< + ASIO_OS_DEF(IPPROTO_IP), + ASIO_OS_DEF(IP_ADD_MEMBERSHIP), + ASIO_OS_DEF(IPPROTO_IPV6), + ASIO_OS_DEF(IPV6_JOIN_GROUP)> join_group; +#endif + +/// Socket option to leave a multicast group on a specified interface. +/** + * Implements the IPPROTO_IP/IP_DROP_MEMBERSHIP socket option. + * + * @par Examples + * Setting the option to leave a multicast group: + * @code + * asio::ip::udp::socket socket(io_context); + * ... + * asio::ip::address multicast_address = + * asio::ip::address::from_string("225.0.0.1"); + * asio::ip::multicast::leave_group option(multicast_address); + * socket.set_option(option); + * @endcode + * + * @par Concepts: + * SettableSocketOption. + */ +#if defined(GENERATING_DOCUMENTATION) +typedef implementation_defined leave_group; +#else +typedef asio::ip::detail::socket_option::multicast_request< + ASIO_OS_DEF(IPPROTO_IP), + ASIO_OS_DEF(IP_DROP_MEMBERSHIP), + ASIO_OS_DEF(IPPROTO_IPV6), + ASIO_OS_DEF(IPV6_LEAVE_GROUP)> leave_group; +#endif + +/// Socket option for local interface to use for outgoing multicast packets. +/** + * Implements the IPPROTO_IP/IP_MULTICAST_IF socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::udp::socket socket(io_context); + * ... + * asio::ip::address_v4 local_interface = + * asio::ip::address_v4::from_string("1.2.3.4"); + * asio::ip::multicast::outbound_interface option(local_interface); + * socket.set_option(option); + * @endcode + * + * @par Concepts: + * SettableSocketOption. + */ +#if defined(GENERATING_DOCUMENTATION) +typedef implementation_defined outbound_interface; +#else +typedef asio::ip::detail::socket_option::network_interface< + ASIO_OS_DEF(IPPROTO_IP), + ASIO_OS_DEF(IP_MULTICAST_IF), + ASIO_OS_DEF(IPPROTO_IPV6), + ASIO_OS_DEF(IPV6_MULTICAST_IF)> outbound_interface; +#endif + +/// Socket option for time-to-live associated with outgoing multicast packets. +/** + * Implements the IPPROTO_IP/IP_MULTICAST_TTL socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::udp::socket socket(io_context); + * ... + * asio::ip::multicast::hops option(4); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::udp::socket socket(io_context); + * ... + * asio::ip::multicast::hops option; + * socket.get_option(option); + * int ttl = option.value(); + * @endcode + * + * @par Concepts: + * GettableSocketOption, SettableSocketOption. + */ +#if defined(GENERATING_DOCUMENTATION) +typedef implementation_defined hops; +#else +typedef asio::ip::detail::socket_option::multicast_hops< + ASIO_OS_DEF(IPPROTO_IP), + ASIO_OS_DEF(IP_MULTICAST_TTL), + ASIO_OS_DEF(IPPROTO_IPV6), + ASIO_OS_DEF(IPV6_MULTICAST_HOPS)> hops; +#endif + +/// Socket option determining whether outgoing multicast packets will be +/// received on the same socket if it is a member of the multicast group. +/** + * Implements the IPPROTO_IP/IP_MULTICAST_LOOP socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::udp::socket socket(io_context); + * ... + * asio::ip::multicast::enable_loopback option(true); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::udp::socket socket(io_context); + * ... + * asio::ip::multicast::enable_loopback option; + * socket.get_option(option); + * bool is_set = option.value(); + * @endcode + * + * @par Concepts: + * GettableSocketOption, SettableSocketOption. + */ +#if defined(GENERATING_DOCUMENTATION) +typedef implementation_defined enable_loopback; +#else +typedef asio::ip::detail::socket_option::multicast_enable_loopback< + ASIO_OS_DEF(IPPROTO_IP), + ASIO_OS_DEF(IP_MULTICAST_LOOP), + ASIO_OS_DEF(IPPROTO_IPV6), + ASIO_OS_DEF(IPV6_MULTICAST_LOOP)> enable_loopback; +#endif + +} // namespace multicast +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_MULTICAST_HPP diff --git a/lib/asio/ip/network_v4.hpp b/lib/asio/ip/network_v4.hpp new file mode 100644 index 0000000..e38f60f --- /dev/null +++ b/lib/asio/ip/network_v4.hpp @@ -0,0 +1,261 @@ +// +// ip/network_v4.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2014 Oliver Kowalke (oliver dot kowalke at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_NETWORK_V4_HPP +#define ASIO_IP_NETWORK_V4_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include <string> +#include "asio/detail/string_view.hpp" +#include "asio/error_code.hpp" +#include "asio/ip/address_v4_range.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// Represents an IPv4 network. +/** + * The asio::ip::network_v4 class provides the ability to use and + * manipulate IP version 4 networks. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +class network_v4 +{ +public: + /// Default constructor. + network_v4() ASIO_NOEXCEPT + : address_(), + prefix_length_(0) + { + } + + /// Construct a network based on the specified address and prefix length. + ASIO_DECL network_v4(const address_v4& addr, + unsigned short prefix_len); + + /// Construct network based on the specified address and netmask. + ASIO_DECL network_v4(const address_v4& addr, + const address_v4& mask); + + /// Copy constructor. + network_v4(const network_v4& other) ASIO_NOEXCEPT + : address_(other.address_), + prefix_length_(other.prefix_length_) + { + } + +#if defined(ASIO_HAS_MOVE) + /// Move constructor. + network_v4(network_v4&& other) ASIO_NOEXCEPT + : address_(ASIO_MOVE_CAST(address_v4)(other.address_)), + prefix_length_(other.prefix_length_) + { + } +#endif // defined(ASIO_HAS_MOVE) + + /// Assign from another network. + network_v4& operator=(const network_v4& other) ASIO_NOEXCEPT + { + address_ = other.address_; + prefix_length_ = other.prefix_length_; + return *this; + } + +#if defined(ASIO_HAS_MOVE) + /// Move-assign from another network. + network_v4& operator=(network_v4&& other) ASIO_NOEXCEPT + { + address_ = ASIO_MOVE_CAST(address_v4)(other.address_); + prefix_length_ = other.prefix_length_; + return *this; + } +#endif // defined(ASIO_HAS_MOVE) + + /// Obtain the address object specified when the network object was created. + address_v4 address() const ASIO_NOEXCEPT + { + return address_; + } + + /// Obtain the prefix length that was specified when the network object was + /// created. + unsigned short prefix_length() const ASIO_NOEXCEPT + { + return prefix_length_; + } + + /// Obtain the netmask that was specified when the network object was created. + ASIO_DECL address_v4 netmask() const ASIO_NOEXCEPT; + + /// Obtain an address object that represents the network address. + address_v4 network() const ASIO_NOEXCEPT + { + return address_v4(address_.to_uint() & netmask().to_uint()); + } + + /// Obtain an address object that represents the network's broadcast address. + address_v4 broadcast() const ASIO_NOEXCEPT + { + return address_v4(network().to_uint() | (netmask().to_uint() ^ 0xFFFFFFFF)); + } + + /// Obtain an address range corresponding to the hosts in the network. + ASIO_DECL address_v4_range hosts() const ASIO_NOEXCEPT; + + /// Obtain the true network address, omitting any host bits. + network_v4 canonical() const ASIO_NOEXCEPT + { + return network_v4(network(), netmask()); + } + + /// Test if network is a valid host address. + bool is_host() const ASIO_NOEXCEPT + { + return prefix_length_ == 32; + } + + /// Test if a network is a real subnet of another network. + ASIO_DECL bool is_subnet_of(const network_v4& other) const; + + /// Get the network as an address in dotted decimal format. + ASIO_DECL std::string to_string() const; + + /// Get the network as an address in dotted decimal format. + ASIO_DECL std::string to_string(asio::error_code& ec) const; + + /// Compare two networks for equality. + friend bool operator==(const network_v4& a, const network_v4& b) + { + return a.address_ == b.address_ && a.prefix_length_ == b.prefix_length_; + } + + /// Compare two networks for inequality. + friend bool operator!=(const network_v4& a, const network_v4& b) + { + return !(a == b); + } + +private: + address_v4 address_; + unsigned short prefix_length_; +}; + +/// Create an IPv4 network from an address and prefix length. +/** + * @relates address_v4 + */ +inline network_v4 make_network_v4( + const address_v4& addr, unsigned short prefix_len) +{ + return network_v4(addr, prefix_len); +} + +/// Create an IPv4 network from an address and netmask. +/** + * @relates address_v4 + */ +inline network_v4 make_network_v4( + const address_v4& addr, const address_v4& mask) +{ + return network_v4(addr, mask); +} + +/// Create an IPv4 network from a string containing IP address and prefix +/// length. +/** + * @relates network_v4 + */ +ASIO_DECL network_v4 make_network_v4(const char* str); + +/// Create an IPv4 network from a string containing IP address and prefix +/// length. +/** + * @relates network_v4 + */ +ASIO_DECL network_v4 make_network_v4( + const char* str, asio::error_code& ec); + +/// Create an IPv4 network from a string containing IP address and prefix +/// length. +/** + * @relates network_v4 + */ +ASIO_DECL network_v4 make_network_v4(const std::string& str); + +/// Create an IPv4 network from a string containing IP address and prefix +/// length. +/** + * @relates network_v4 + */ +ASIO_DECL network_v4 make_network_v4( + const std::string& str, asio::error_code& ec); + +#if defined(ASIO_HAS_STRING_VIEW) \ + || defined(GENERATING_DOCUMENTATION) + +/// Create an IPv4 network from a string containing IP address and prefix +/// length. +/** + * @relates network_v4 + */ +ASIO_DECL network_v4 make_network_v4(string_view str); + +/// Create an IPv4 network from a string containing IP address and prefix +/// length. +/** + * @relates network_v4 + */ +ASIO_DECL network_v4 make_network_v4( + string_view str, asio::error_code& ec); + +#endif // defined(ASIO_HAS_STRING_VIEW) + // || defined(GENERATING_DOCUMENTATION) + +#if !defined(ASIO_NO_IOSTREAM) + +/// Output a network as a string. +/** + * Used to output a human-readable string for a specified network. + * + * @param os The output stream to which the string will be written. + * + * @param net The network to be written. + * + * @return The output stream. + * + * @relates asio::ip::address_v4 + */ +template <typename Elem, typename Traits> +std::basic_ostream<Elem, Traits>& operator<<( + std::basic_ostream<Elem, Traits>& os, const network_v4& net); + +#endif // !defined(ASIO_NO_IOSTREAM) + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/ip/impl/network_v4.hpp" +#if defined(ASIO_HEADER_ONLY) +# include "asio/ip/impl/network_v4.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_IP_NETWORK_V4_HPP diff --git a/lib/asio/ip/network_v6.hpp b/lib/asio/ip/network_v6.hpp new file mode 100644 index 0000000..7b6b7e6 --- /dev/null +++ b/lib/asio/ip/network_v6.hpp @@ -0,0 +1,235 @@ +// +// ip/network_v6.hpp +// ~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2014 Oliver Kowalke (oliver dot kowalke at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_NETWORK_V6_HPP +#define ASIO_IP_NETWORK_V6_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include <string> +#include "asio/detail/string_view.hpp" +#include "asio/error_code.hpp" +#include "asio/ip/address_v6_range.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// Represents an IPv6 network. +/** + * The asio::ip::network_v6 class provides the ability to use and + * manipulate IP version 6 networks. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +class network_v6 +{ +public: + /// Default constructor. + network_v6() ASIO_NOEXCEPT + : address_(), + prefix_length_(0) + { + } + + /// Construct a network based on the specified address and prefix length. + ASIO_DECL network_v6(const address_v6& addr, + unsigned short prefix_len); + + /// Copy constructor. + network_v6(const network_v6& other) ASIO_NOEXCEPT + : address_(other.address_), + prefix_length_(other.prefix_length_) + { + } + +#if defined(ASIO_HAS_MOVE) + /// Move constructor. + network_v6(network_v6&& other) ASIO_NOEXCEPT + : address_(ASIO_MOVE_CAST(address_v6)(other.address_)), + prefix_length_(other.prefix_length_) + { + } +#endif // defined(ASIO_HAS_MOVE) + + /// Assign from another network. + network_v6& operator=(const network_v6& other) ASIO_NOEXCEPT + { + address_ = other.address_; + prefix_length_ = other.prefix_length_; + return *this; + } + +#if defined(ASIO_HAS_MOVE) + /// Move-assign from another network. + network_v6& operator=(network_v6&& other) ASIO_NOEXCEPT + { + address_ = ASIO_MOVE_CAST(address_v6)(other.address_); + prefix_length_ = other.prefix_length_; + return *this; + } +#endif // defined(ASIO_HAS_MOVE) + + /// Obtain the address object specified when the network object was created. + address_v6 address() const ASIO_NOEXCEPT + { + return address_; + } + + /// Obtain the prefix length that was specified when the network object was + /// created. + unsigned short prefix_length() const ASIO_NOEXCEPT + { + return prefix_length_; + } + + /// Obtain an address object that represents the network address. + ASIO_DECL address_v6 network() const ASIO_NOEXCEPT; + + /// Obtain an address range corresponding to the hosts in the network. + ASIO_DECL address_v6_range hosts() const ASIO_NOEXCEPT; + + /// Obtain the true network address, omitting any host bits. + network_v6 canonical() const ASIO_NOEXCEPT + { + return network_v6(network(), prefix_length()); + } + + /// Test if network is a valid host address. + bool is_host() const ASIO_NOEXCEPT + { + return prefix_length_ == 128; + } + + /// Test if a network is a real subnet of another network. + ASIO_DECL bool is_subnet_of(const network_v6& other) const; + + /// Get the network as an address in dotted decimal format. + ASIO_DECL std::string to_string() const; + + /// Get the network as an address in dotted decimal format. + ASIO_DECL std::string to_string(asio::error_code& ec) const; + + /// Compare two networks for equality. + friend bool operator==(const network_v6& a, const network_v6& b) + { + return a.address_ == b.address_ && a.prefix_length_ == b.prefix_length_; + } + + /// Compare two networks for inequality. + friend bool operator!=(const network_v6& a, const network_v6& b) + { + return !(a == b); + } + +private: + address_v6 address_; + unsigned short prefix_length_; +}; + +/// Create an IPv6 network from an address and prefix length. +/** + * @relates address_v6 + */ +inline network_v6 make_network_v6( + const address_v6& addr, unsigned short prefix_len) +{ + return network_v6(addr, prefix_len); +} + +/// Create an IPv6 network from a string containing IP address and prefix +/// length. +/** + * @relates network_v6 + */ +ASIO_DECL network_v6 make_network_v6(const char* str); + +/// Create an IPv6 network from a string containing IP address and prefix +/// length. +/** + * @relates network_v6 + */ +ASIO_DECL network_v6 make_network_v6( + const char* str, asio::error_code& ec); + +/// Create an IPv6 network from a string containing IP address and prefix +/// length. +/** + * @relates network_v6 + */ +ASIO_DECL network_v6 make_network_v6(const std::string& str); + +/// Create an IPv6 network from a string containing IP address and prefix +/// length. +/** + * @relates network_v6 + */ +ASIO_DECL network_v6 make_network_v6( + const std::string& str, asio::error_code& ec); + +#if defined(ASIO_HAS_STRING_VIEW) \ + || defined(GENERATING_DOCUMENTATION) + +/// Create an IPv6 network from a string containing IP address and prefix +/// length. +/** + * @relates network_v6 + */ +ASIO_DECL network_v6 make_network_v6(string_view str); + +/// Create an IPv6 network from a string containing IP address and prefix +/// length. +/** + * @relates network_v6 + */ +ASIO_DECL network_v6 make_network_v6( + string_view str, asio::error_code& ec); + +#endif // defined(ASIO_HAS_STRING_VIEW) + // || defined(GENERATING_DOCUMENTATION) + +#if !defined(ASIO_NO_IOSTREAM) + +/// Output a network as a string. +/** + * Used to output a human-readable string for a specified network. + * + * @param os The output stream to which the string will be written. + * + * @param net The network to be written. + * + * @return The output stream. + * + * @relates asio::ip::address_v6 + */ +template <typename Elem, typename Traits> +std::basic_ostream<Elem, Traits>& operator<<( + std::basic_ostream<Elem, Traits>& os, const network_v6& net); + +#endif // !defined(ASIO_NO_IOSTREAM) + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/ip/impl/network_v6.hpp" +#if defined(ASIO_HEADER_ONLY) +# include "asio/ip/impl/network_v6.ipp" +#endif // defined(ASIO_HEADER_ONLY) + +#endif // ASIO_IP_NETWORK_V6_HPP diff --git a/lib/asio/ip/resolver_base.hpp b/lib/asio/ip/resolver_base.hpp new file mode 100644 index 0000000..d32c911 --- /dev/null +++ b/lib/asio/ip/resolver_base.hpp @@ -0,0 +1,129 @@ +// +// ip/resolver_base.hpp +// ~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_RESOLVER_BASE_HPP +#define ASIO_IP_RESOLVER_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/socket_types.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// The resolver_base class is used as a base for the basic_resolver class +/// templates to provide a common place to define the flag constants. +class resolver_base +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// A bitmask type (C++ Std [lib.bitmask.types]). + typedef unspecified flags; + + /// Determine the canonical name of the host specified in the query. + static const flags canonical_name = implementation_defined; + + /// Indicate that returned endpoint is intended for use as a locally bound + /// socket endpoint. + static const flags passive = implementation_defined; + + /// Host name should be treated as a numeric string defining an IPv4 or IPv6 + /// address and no name resolution should be attempted. + static const flags numeric_host = implementation_defined; + + /// Service name should be treated as a numeric string defining a port number + /// and no name resolution should be attempted. + static const flags numeric_service = implementation_defined; + + /// If the query protocol family is specified as IPv6, return IPv4-mapped + /// IPv6 addresses on finding no IPv6 addresses. + static const flags v4_mapped = implementation_defined; + + /// If used with v4_mapped, return all matching IPv6 and IPv4 addresses. + static const flags all_matching = implementation_defined; + + /// Only return IPv4 addresses if a non-loopback IPv4 address is configured + /// for the system. Only return IPv6 addresses if a non-loopback IPv6 address + /// is configured for the system. + static const flags address_configured = implementation_defined; +#else + enum flags + { + canonical_name = ASIO_OS_DEF(AI_CANONNAME), + passive = ASIO_OS_DEF(AI_PASSIVE), + numeric_host = ASIO_OS_DEF(AI_NUMERICHOST), + numeric_service = ASIO_OS_DEF(AI_NUMERICSERV), + v4_mapped = ASIO_OS_DEF(AI_V4MAPPED), + all_matching = ASIO_OS_DEF(AI_ALL), + address_configured = ASIO_OS_DEF(AI_ADDRCONFIG) + }; + + // Implement bitmask operations as shown in C++ Std [lib.bitmask.types]. + + friend flags operator&(flags x, flags y) + { + return static_cast<flags>( + static_cast<unsigned int>(x) & static_cast<unsigned int>(y)); + } + + friend flags operator|(flags x, flags y) + { + return static_cast<flags>( + static_cast<unsigned int>(x) | static_cast<unsigned int>(y)); + } + + friend flags operator^(flags x, flags y) + { + return static_cast<flags>( + static_cast<unsigned int>(x) ^ static_cast<unsigned int>(y)); + } + + friend flags operator~(flags x) + { + return static_cast<flags>(~static_cast<unsigned int>(x)); + } + + friend flags& operator&=(flags& x, flags y) + { + x = x & y; + return x; + } + + friend flags& operator|=(flags& x, flags y) + { + x = x | y; + return x; + } + + friend flags& operator^=(flags& x, flags y) + { + x = x ^ y; + return x; + } +#endif + +protected: + /// Protected destructor to prevent deletion through this type. + ~resolver_base() + { + } +}; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_RESOLVER_BASE_HPP diff --git a/lib/asio/ip/resolver_query_base.hpp b/lib/asio/ip/resolver_query_base.hpp new file mode 100644 index 0000000..be36858 --- /dev/null +++ b/lib/asio/ip/resolver_query_base.hpp @@ -0,0 +1,43 @@ +// +// ip/resolver_query_base.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_RESOLVER_QUERY_BASE_HPP +#define ASIO_IP_RESOLVER_QUERY_BASE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/ip/resolver_base.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// The resolver_query_base class is used as a base for the +/// basic_resolver_query class templates to provide a common place to define +/// the flag constants. +class resolver_query_base : public resolver_base +{ +protected: + /// Protected destructor to prevent deletion through this type. + ~resolver_query_base() + { + } +}; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_RESOLVER_QUERY_BASE_HPP diff --git a/lib/asio/ip/resolver_service.hpp b/lib/asio/ip/resolver_service.hpp new file mode 100644 index 0000000..519d72d --- /dev/null +++ b/lib/asio/ip/resolver_service.hpp @@ -0,0 +1,200 @@ +// +// ip/resolver_service.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_RESOLVER_SERVICE_HPP +#define ASIO_IP_RESOLVER_SERVICE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_ENABLE_OLD_SERVICES) + +#include "asio/async_result.hpp" +#include "asio/error_code.hpp" +#include "asio/io_context.hpp" +#include "asio/ip/basic_resolver_iterator.hpp" +#include "asio/ip/basic_resolver_query.hpp" +#include "asio/ip/basic_resolver_results.hpp" + +#if defined(ASIO_WINDOWS_RUNTIME) +# include "asio/detail/winrt_resolver_service.hpp" +#else +# include "asio/detail/resolver_service.hpp" +#endif + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// Default service implementation for a resolver. +template <typename InternetProtocol> +class resolver_service +#if defined(GENERATING_DOCUMENTATION) + : public asio::io_context::service +#else + : public asio::detail::service_base< + resolver_service<InternetProtocol> > +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static asio::io_context::id id; +#endif + + /// The protocol type. + typedef InternetProtocol protocol_type; + + /// The endpoint type. + typedef typename InternetProtocol::endpoint endpoint_type; + + /// The query type. + typedef basic_resolver_query<InternetProtocol> query_type; + + /// The iterator type. + typedef basic_resolver_iterator<InternetProtocol> iterator_type; + + /// The results type. + typedef basic_resolver_results<InternetProtocol> results_type; + +private: + // The type of the platform-specific implementation. +#if defined(ASIO_WINDOWS_RUNTIME) + typedef asio::detail::winrt_resolver_service<InternetProtocol> + service_impl_type; +#else + typedef asio::detail::resolver_service<InternetProtocol> + service_impl_type; +#endif + +public: + /// The type of a resolver implementation. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined implementation_type; +#else + typedef typename service_impl_type::implementation_type implementation_type; +#endif + + /// Construct a new resolver service for the specified io_context. + explicit resolver_service(asio::io_context& io_context) + : asio::detail::service_base< + resolver_service<InternetProtocol> >(io_context), + service_impl_(io_context) + { + } + + /// Construct a new resolver implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a new resolver implementation. + void move_construct(implementation_type& impl, + implementation_type& other_impl) + { + service_impl_.move_construct(impl, other_impl); + } + + /// Move-assign from another resolver implementation. + void move_assign(implementation_type& impl, + resolver_service& other_service, + implementation_type& other_impl) + { + service_impl_.move_assign(impl, other_service.service_impl_, other_impl); + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Destroy a resolver implementation. + void destroy(implementation_type& impl) + { + service_impl_.destroy(impl); + } + + /// Cancel pending asynchronous operations. + void cancel(implementation_type& impl) + { + service_impl_.cancel(impl); + } + + /// Resolve a query to a list of entries. + results_type resolve(implementation_type& impl, const query_type& query, + asio::error_code& ec) + { + return service_impl_.resolve(impl, query, ec); + } + + /// Asynchronously resolve a query to a list of entries. + template <typename ResolveHandler> + ASIO_INITFN_RESULT_TYPE(ResolveHandler, + void (asio::error_code, results_type)) + async_resolve(implementation_type& impl, const query_type& query, + ASIO_MOVE_ARG(ResolveHandler) handler) + { + asio::async_completion<ResolveHandler, + void (asio::error_code, results_type)> init(handler); + + service_impl_.async_resolve(impl, query, init.completion_handler); + + return init.result.get(); + } + + /// Resolve an endpoint to a list of entries. + results_type resolve(implementation_type& impl, + const endpoint_type& endpoint, asio::error_code& ec) + { + return service_impl_.resolve(impl, endpoint, ec); + } + + /// Asynchronously resolve an endpoint to a list of entries. + template <typename ResolveHandler> + ASIO_INITFN_RESULT_TYPE(ResolveHandler, + void (asio::error_code, results_type)) + async_resolve(implementation_type& impl, const endpoint_type& endpoint, + ASIO_MOVE_ARG(ResolveHandler) handler) + { + asio::async_completion<ResolveHandler, + void (asio::error_code, results_type)> init(handler); + + service_impl_.async_resolve(impl, endpoint, init.completion_handler); + + return init.result.get(); + } + +private: + // Destroy all user-defined handler objects owned by the service. + void shutdown() + { + service_impl_.shutdown(); + } + + // Perform any fork-related housekeeping. + void notify_fork(asio::io_context::fork_event event) + { + service_impl_.notify_fork(event); + } + + // The platform-specific implementation. + service_impl_type service_impl_; +}; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // defined(ASIO_ENABLE_OLD_SERVICES) + +#endif // ASIO_IP_RESOLVER_SERVICE_HPP diff --git a/lib/asio/ip/tcp.hpp b/lib/asio/ip/tcp.hpp new file mode 100644 index 0000000..f1adeb0 --- /dev/null +++ b/lib/asio/ip/tcp.hpp @@ -0,0 +1,155 @@ +// +// ip/tcp.hpp +// ~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_TCP_HPP +#define ASIO_IP_TCP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/basic_socket_acceptor.hpp" +#include "asio/basic_socket_iostream.hpp" +#include "asio/basic_stream_socket.hpp" +#include "asio/detail/socket_option.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/ip/basic_endpoint.hpp" +#include "asio/ip/basic_resolver.hpp" +#include "asio/ip/basic_resolver_iterator.hpp" +#include "asio/ip/basic_resolver_query.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// Encapsulates the flags needed for TCP. +/** + * The asio::ip::tcp class contains flags necessary for TCP sockets. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Safe. + * + * @par Concepts: + * Protocol, InternetProtocol. + */ +class tcp +{ +public: + /// The type of a TCP endpoint. + typedef basic_endpoint<tcp> endpoint; + + /// Construct to represent the IPv4 TCP protocol. + static tcp v4() + { + return tcp(ASIO_OS_DEF(AF_INET)); + } + + /// Construct to represent the IPv6 TCP protocol. + static tcp v6() + { + return tcp(ASIO_OS_DEF(AF_INET6)); + } + + /// Obtain an identifier for the type of the protocol. + int type() const + { + return ASIO_OS_DEF(SOCK_STREAM); + } + + /// Obtain an identifier for the protocol. + int protocol() const + { + return ASIO_OS_DEF(IPPROTO_TCP); + } + + /// Obtain an identifier for the protocol family. + int family() const + { + return family_; + } + + /// The TCP socket type. + typedef basic_stream_socket<tcp> socket; + + /// The TCP acceptor type. + typedef basic_socket_acceptor<tcp> acceptor; + + /// The TCP resolver type. + typedef basic_resolver<tcp> resolver; + +#if !defined(ASIO_NO_IOSTREAM) + /// The TCP iostream type. + typedef basic_socket_iostream<tcp> iostream; +#endif // !defined(ASIO_NO_IOSTREAM) + + /// Socket option for disabling the Nagle algorithm. + /** + * Implements the IPPROTO_TCP/TCP_NODELAY socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::ip::tcp::no_delay option(true); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::ip::tcp::no_delay option; + * socket.get_option(option); + * bool is_set = option.value(); + * @endcode + * + * @par Concepts: + * Socket_Option, Boolean_Socket_Option. + */ +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined no_delay; +#else + typedef asio::detail::socket_option::boolean< + ASIO_OS_DEF(IPPROTO_TCP), ASIO_OS_DEF(TCP_NODELAY)> no_delay; +#endif + + /// Compare two protocols for equality. + friend bool operator==(const tcp& p1, const tcp& p2) + { + return p1.family_ == p2.family_; + } + + /// Compare two protocols for inequality. + friend bool operator!=(const tcp& p1, const tcp& p2) + { + return p1.family_ != p2.family_; + } + +private: + // Construct with a specific family. + explicit tcp(int protocol_family) + : family_(protocol_family) + { + } + + int family_; +}; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_TCP_HPP diff --git a/lib/asio/ip/udp.hpp b/lib/asio/ip/udp.hpp new file mode 100644 index 0000000..1c93f9b --- /dev/null +++ b/lib/asio/ip/udp.hpp @@ -0,0 +1,111 @@ +// +// ip/udp.hpp +// ~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_UDP_HPP +#define ASIO_IP_UDP_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/basic_datagram_socket.hpp" +#include "asio/detail/socket_types.hpp" +#include "asio/ip/basic_endpoint.hpp" +#include "asio/ip/basic_resolver.hpp" +#include "asio/ip/basic_resolver_iterator.hpp" +#include "asio/ip/basic_resolver_query.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// Encapsulates the flags needed for UDP. +/** + * The asio::ip::udp class contains flags necessary for UDP sockets. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Safe. + * + * @par Concepts: + * Protocol, InternetProtocol. + */ +class udp +{ +public: + /// The type of a UDP endpoint. + typedef basic_endpoint<udp> endpoint; + + /// Construct to represent the IPv4 UDP protocol. + static udp v4() + { + return udp(ASIO_OS_DEF(AF_INET)); + } + + /// Construct to represent the IPv6 UDP protocol. + static udp v6() + { + return udp(ASIO_OS_DEF(AF_INET6)); + } + + /// Obtain an identifier for the type of the protocol. + int type() const + { + return ASIO_OS_DEF(SOCK_DGRAM); + } + + /// Obtain an identifier for the protocol. + int protocol() const + { + return ASIO_OS_DEF(IPPROTO_UDP); + } + + /// Obtain an identifier for the protocol family. + int family() const + { + return family_; + } + + /// The UDP socket type. + typedef basic_datagram_socket<udp> socket; + + /// The UDP resolver type. + typedef basic_resolver<udp> resolver; + + /// Compare two protocols for equality. + friend bool operator==(const udp& p1, const udp& p2) + { + return p1.family_ == p2.family_; + } + + /// Compare two protocols for inequality. + friend bool operator!=(const udp& p1, const udp& p2) + { + return p1.family_ != p2.family_; + } + +private: + // Construct with a specific family. + explicit udp(int protocol_family) + : family_(protocol_family) + { + } + + int family_; +}; + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_UDP_HPP diff --git a/lib/asio/ip/unicast.hpp b/lib/asio/ip/unicast.hpp new file mode 100644 index 0000000..14e3e48 --- /dev/null +++ b/lib/asio/ip/unicast.hpp @@ -0,0 +1,70 @@ +// +// ip/unicast.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_UNICAST_HPP +#define ASIO_IP_UNICAST_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include <cstddef> +#include "asio/ip/detail/socket_option.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { +namespace unicast { + +/// Socket option for time-to-live associated with outgoing unicast packets. +/** + * Implements the IPPROTO_IP/IP_UNICAST_TTL socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::udp::socket socket(io_context); + * ... + * asio::ip::unicast::hops option(4); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::udp::socket socket(io_context); + * ... + * asio::ip::unicast::hops option; + * socket.get_option(option); + * int ttl = option.value(); + * @endcode + * + * @par Concepts: + * GettableSocketOption, SettableSocketOption. + */ +#if defined(GENERATING_DOCUMENTATION) +typedef implementation_defined hops; +#else +typedef asio::ip::detail::socket_option::unicast_hops< + ASIO_OS_DEF(IPPROTO_IP), + ASIO_OS_DEF(IP_TTL), + ASIO_OS_DEF(IPPROTO_IPV6), + ASIO_OS_DEF(IPV6_UNICAST_HOPS)> hops; +#endif + +} // namespace unicast +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_UNICAST_HPP diff --git a/lib/asio/ip/v6_only.hpp b/lib/asio/ip/v6_only.hpp new file mode 100644 index 0000000..ac7234e --- /dev/null +++ b/lib/asio/ip/v6_only.hpp @@ -0,0 +1,69 @@ +// +// ip/v6_only.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ASIO_IP_V6_ONLY_HPP +#define ASIO_IP_V6_ONLY_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/socket_option.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace ip { + +/// Socket option for determining whether an IPv6 socket supports IPv6 +/// communication only. +/** + * Implements the IPPROTO_IPV6/IP_V6ONLY socket option. + * + * @par Examples + * Setting the option: + * @code + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::ip::v6_only option(true); + * socket.set_option(option); + * @endcode + * + * @par + * Getting the current option value: + * @code + * asio::ip::tcp::socket socket(io_context); + * ... + * asio::ip::v6_only option; + * socket.get_option(option); + * bool v6_only = option.value(); + * @endcode + * + * @par Concepts: + * GettableSocketOption, SettableSocketOption. + */ +#if defined(GENERATING_DOCUMENTATION) +typedef implementation_defined v6_only; +#elif defined(IPV6_V6ONLY) +typedef asio::detail::socket_option::boolean< + IPPROTO_IPV6, IPV6_V6ONLY> v6_only; +#else +typedef asio::detail::socket_option::boolean< + asio::detail::custom_socket_option_level, + asio::detail::always_fail_option> v6_only; +#endif + +} // namespace ip +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_IP_V6_ONLY_HPP |