query/include/matador/net/address_resolver.hpp

116 lines
2.8 KiB
C++

#ifndef MATADOR_ADDRESS_RESOLVER_HPP
#define MATADOR_ADDRESS_RESOLVER_HPP
#include "matador/net/export.hpp"
#include "matador/net/peer.hpp"
#include "matador/net/error.hpp"
#include <vector>
namespace matador {
/// @cond MATADOR_DEV
class tcp;
class udp;
namespace detail {
template < class P >
int determine_socktype();
template <>
OOS_NET_API int determine_socktype<tcp>();
template <>
OOS_NET_API int determine_socktype<udp>();
template < class P >
void initialize_hints(struct addrinfo &hints, int flags) {
memset(&hints,0,sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = determine_socktype<P>();
hints.ai_protocol = 0;
hints.ai_flags = flags;
}
/// @endcond
}
/**
* The address resolver resolves a given host and port
* to a peer object representing the given address
*
* @tparam P Type of protocol
*/
template < class P >
class address_resolver
{
public:
typedef typename P::peer peer; /**< Shortcut to peer type */
/**
* Default constructor
*/
address_resolver() = default;
/**
* Resolves the given host and port to a list
* of valid peers representing the ip addresses
* of the host either in IPv4 or IPv6 format
*
* @param hostname Hostname to resolve
* @param port Port to resolve
* @return A list of peers representing the host and port
*/
std::vector<peer> resolve(const std::string &hostname, const std::string &port);
/**
* Resolves the given host and port to a list
* of valid peers representing the ip addresses
* of the host either in IPv4 or IPv6 format
*
* @param hostname Hostname to resolve
* @param port Port to resolve
* @return A list of peers representing the host and port
*/
std::vector<peer> resolve(const char *hostname, const char *port);
};
/// @cond MATADOR_DEV
template<class P>
std::vector<typename address_resolver<P>::peer> address_resolver<P>::resolve(const std::string &hostname, const std::string &port)
{
return resolve(hostname.c_str(), port.c_str());
}
template < class P >
std::vector<typename address_resolver<P>::peer> address_resolver<P>::resolve(const char *hostname, const char *port)
{
struct addrinfo hints = {};
detail::initialize_hints<P>(hints, AI_PASSIVE);
struct addrinfo* res = nullptr;
struct addrinfo* head = nullptr;
int err = getaddrinfo(hostname, port, &hints, &res);
if (err != 0) {
detail::throw_logic_error_with_gai_errno("error on getaddrinfo: %s", err);
}
head = res;
std::vector<peer> peers;
do {
if (res->ai_family == PF_INET) {
peers.push_back(peer(address(*(struct sockaddr_in*)res->ai_addr)));
} else if (res->ai_family == PF_INET6) {
peers.push_back(peer(address(*(struct sockaddr_in6*)res->ai_addr)));
} // else -> not supported
} while ( (res = res->ai_next) != nullptr);
freeaddrinfo(head);
return peers;
}
/// @endcond
}
#endif //MATADOR_ADDRESS_RESOLVER_HPP