mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-24 09:12:28 +02:00
GH #68: DNS::hostByAddress can be slow
GH #68: DNS::hostByAddress can be slow - added parameters in the interface to pass hint flags to hostByAddress() and hostByName() calls
This commit is contained in:
@@ -57,9 +57,31 @@ class Net_API DNS
|
|||||||
/// An internal DNS cache is used to speed up name lookups.
|
/// An internal DNS cache is used to speed up name lookups.
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static HostEntry hostByName(const std::string& hostname);
|
|
||||||
|
enum HintFlag
|
||||||
|
{
|
||||||
|
DNS_HINT_NONE = 0,
|
||||||
|
#ifdef POCO_HAVE_ADDRINFO
|
||||||
|
DNS_HINT_AI_PASSIVE = AI_PASSIVE, // Socket address will be used in bind() call
|
||||||
|
DNS_HINT_AI_CANONNAME = AI_CANONNAME, // Return canonical name in first ai_canonname
|
||||||
|
DNS_HINT_AI_NUMERICHOST = AI_NUMERICHOST, // Nodename must be a numeric address string
|
||||||
|
DNS_HINT_AI_NUMERICSERV = AI_NUMERICSERV, // Servicename must be a numeric port number
|
||||||
|
DNS_HINT_AI_ALL = AI_ALL, // Query both IP6 and IP4 with AI_V4MAPPED
|
||||||
|
DNS_HINT_AI_ADDRCONFIG = AI_ADDRCONFIG, // Resolution only if global address configured
|
||||||
|
DNS_HINT_AI_V4MAPPED = AI_V4MAPPED, // On v6 failure, query v4 and convert to V4MAPPED format
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static HostEntry hostByName(const std::string& hostname, unsigned hintFlags =
|
||||||
|
#ifdef POCO_HAVE_ADDRINFO
|
||||||
|
DNS_HINT_AI_CANONNAME | DNS_HINT_AI_ADDRCONFIG
|
||||||
|
#else
|
||||||
|
DNS_HINT_NONE
|
||||||
|
#endif
|
||||||
|
);
|
||||||
/// Returns a HostEntry object containing the DNS information
|
/// Returns a HostEntry object containing the DNS information
|
||||||
/// for the host with the given name.
|
/// for the host with the given name. HintFlag argument is only
|
||||||
|
/// used on platforms that have getaddrinfo().
|
||||||
///
|
///
|
||||||
/// Throws a HostNotFoundException if a host with the given
|
/// Throws a HostNotFoundException if a host with the given
|
||||||
/// name cannot be found.
|
/// name cannot be found.
|
||||||
@@ -71,9 +93,16 @@ public:
|
|||||||
///
|
///
|
||||||
/// Throws an IOException in case of any other error.
|
/// Throws an IOException in case of any other error.
|
||||||
|
|
||||||
static HostEntry hostByAddress(const IPAddress& address);
|
static HostEntry hostByAddress(const IPAddress& address, unsigned hintFlags =
|
||||||
|
#ifdef POCO_HAVE_ADDRINFO
|
||||||
|
DNS_HINT_AI_CANONNAME | DNS_HINT_AI_ADDRCONFIG
|
||||||
|
#else
|
||||||
|
DNS_HINT_NONE
|
||||||
|
#endif
|
||||||
|
);
|
||||||
/// Returns a HostEntry object containing the DNS information
|
/// Returns a HostEntry object containing the DNS information
|
||||||
/// for the host with the given IP address.
|
/// for the host with the given IP address. HintFlag argument is only
|
||||||
|
/// used on platforms that have getaddrinfo().
|
||||||
///
|
///
|
||||||
/// Throws a HostNotFoundException if a host with the given
|
/// Throws a HostNotFoundException if a host with the given
|
||||||
/// name cannot be found.
|
/// name cannot be found.
|
||||||
|
|||||||
@@ -62,17 +62,21 @@ static Poco::RWLock resolverLock;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
HostEntry DNS::hostByName(const std::string& hostname)
|
HostEntry DNS::hostByName(const std::string& hostname, unsigned
|
||||||
|
#ifdef POCO_HAVE_ADDRINFO
|
||||||
|
hintFlags
|
||||||
|
#endif
|
||||||
|
)
|
||||||
{
|
{
|
||||||
#if defined(POCO_HAVE_LIBRESOLV)
|
#if defined(POCO_HAVE_LIBRESOLV)
|
||||||
Poco::ScopedReadRWLock readLock(resolverLock);
|
Poco::ScopedReadRWLock readLock(resolverLock);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(POCO_HAVE_IPv6) || defined(POCO_HAVE_ADDRINFO)
|
#if defined(POCO_HAVE_ADDRINFO)
|
||||||
struct addrinfo* pAI;
|
struct addrinfo* pAI;
|
||||||
struct addrinfo hints;
|
struct addrinfo hints;
|
||||||
std::memset(&hints, 0, sizeof(hints));
|
std::memset(&hints, 0, sizeof(hints));
|
||||||
hints.ai_flags = AI_CANONNAME | AI_ADDRCONFIG;
|
hints.ai_flags = hintFlags;
|
||||||
int rc = getaddrinfo(hostname.c_str(), NULL, &hints, &pAI);
|
int rc = getaddrinfo(hostname.c_str(), NULL, &hints, &pAI);
|
||||||
if (rc == 0)
|
if (rc == 0)
|
||||||
{
|
{
|
||||||
@@ -102,13 +106,17 @@ HostEntry DNS::hostByName(const std::string& hostname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HostEntry DNS::hostByAddress(const IPAddress& address)
|
HostEntry DNS::hostByAddress(const IPAddress& address, unsigned
|
||||||
|
#ifdef POCO_HAVE_ADDRINFO
|
||||||
|
hintFlags
|
||||||
|
#endif
|
||||||
|
)
|
||||||
{
|
{
|
||||||
#if defined(POCO_HAVE_LIBRESOLV)
|
#if defined(POCO_HAVE_LIBRESOLV)
|
||||||
Poco::ScopedReadRWLock readLock(resolverLock);
|
Poco::ScopedReadRWLock readLock(resolverLock);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(POCO_HAVE_IPv6) || defined(POCO_HAVE_ADDRINFO)
|
#if defined(POCO_HAVE_ADDRINFO)
|
||||||
SocketAddress sa(address, 0);
|
SocketAddress sa(address, 0);
|
||||||
static char fqname[1024];
|
static char fqname[1024];
|
||||||
int rc = getnameinfo(sa.addr(), sa.length(), fqname, sizeof(fqname), NULL, 0, NI_NAMEREQD);
|
int rc = getnameinfo(sa.addr(), sa.length(), fqname, sizeof(fqname), NULL, 0, NI_NAMEREQD);
|
||||||
@@ -117,7 +125,7 @@ HostEntry DNS::hostByAddress(const IPAddress& address)
|
|||||||
struct addrinfo* pAI;
|
struct addrinfo* pAI;
|
||||||
struct addrinfo hints;
|
struct addrinfo hints;
|
||||||
std::memset(&hints, 0, sizeof(hints));
|
std::memset(&hints, 0, sizeof(hints));
|
||||||
hints.ai_flags = AI_CANONNAME | AI_ADDRCONFIG;
|
hints.ai_flags = hintFlags;
|
||||||
rc = getaddrinfo(fqname, NULL, &hints, &pAI);
|
rc = getaddrinfo(fqname, NULL, &hints, &pAI);
|
||||||
if (rc == 0)
|
if (rc == 0)
|
||||||
{
|
{
|
||||||
@@ -148,7 +156,7 @@ HostEntry DNS::hostByAddress(const IPAddress& address)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
int err = lastError();
|
int err = lastError();
|
||||||
error(err, address.toString()); // will throw an appropriate exception
|
error(err, address.toString()); // will throw an appropriate exception
|
||||||
throw NetException(); // to silence compiler
|
throw NetException(); // to silence compiler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -167,13 +167,15 @@ void HTTPClientSessionTest::testPostLargeChunked()
|
|||||||
HTTPRequest request(HTTPRequest::HTTP_POST, "/echo");
|
HTTPRequest request(HTTPRequest::HTTP_POST, "/echo");
|
||||||
std::string body(16000, 'x');
|
std::string body(16000, 'x');
|
||||||
request.setChunkedTransferEncoding(true);
|
request.setChunkedTransferEncoding(true);
|
||||||
s.sendRequest(request) << body;
|
std::ostream& os = s.sendRequest(request);
|
||||||
|
os << body;
|
||||||
|
os.flush();
|
||||||
HTTPResponse response;
|
HTTPResponse response;
|
||||||
std::istream& rs = s.receiveResponse(response);
|
std::istream& rs = s.receiveResponse(response);
|
||||||
assert (response.getChunkedTransferEncoding());
|
assert (response.getChunkedTransferEncoding());
|
||||||
assert (response.getContentLength() == HTTPMessage::UNKNOWN_CONTENT_LENGTH);
|
assert (response.getContentLength() == HTTPMessage::UNKNOWN_CONTENT_LENGTH);
|
||||||
std::ostringstream ostr;
|
std::ostringstream ostr;
|
||||||
StreamCopier::copyStream(rs, ostr);
|
StreamCopier::copyStream(rs, ostr, 16000);
|
||||||
assert (ostr.str() == body);
|
assert (ostr.str() == body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user