Fixed issue #23. Avoid additional queries if gethostname() is already a FQDN. Use getaddrinfo() instead of gethostbyname() for IPv6 compatibility.
This commit is contained in:
parent
3829cc2f86
commit
4457dec512
@ -31,6 +31,8 @@
|
|||||||
|
|
||||||
#include "vmime/platforms/posix/posixCriticalSection.hpp"
|
#include "vmime/platforms/posix/posixCriticalSection.hpp"
|
||||||
|
|
||||||
|
#include "vmime/utility/stringUtils.hpp"
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -174,47 +176,55 @@ const vmime::charset posixHandler::getLocaleCharset() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline bool isFQDN(const vmime::string& str)
|
||||||
|
{
|
||||||
|
if (utility::stringUtils::isStringEqualNoCase(str, "localhost", 9))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const vmime::string::size_type p = str.find_first_of(".");
|
||||||
|
return p != vmime::string::npos && p > 0 && p != str.length() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const vmime::string posixHandler::getHostName() const
|
const vmime::string posixHandler::getHostName() const
|
||||||
{
|
{
|
||||||
std::vector <vmime::string> hostnames;
|
char hostname[256];
|
||||||
char buffer[256];
|
|
||||||
|
|
||||||
// Try with 'gethostname'
|
// Try with 'gethostname'
|
||||||
::gethostname(buffer, sizeof(buffer));
|
::gethostname(hostname, sizeof(hostname));
|
||||||
buffer[sizeof(buffer) - 1] = '\0';
|
hostname[sizeof(hostname) - 1] = '\0';
|
||||||
|
|
||||||
if (::strlen(buffer) == 0)
|
// If this is a Fully-Qualified Domain Name (FQDN), return immediately
|
||||||
::strcpy(buffer, "localhost");
|
if (isFQDN(hostname))
|
||||||
|
return hostname;
|
||||||
|
|
||||||
hostnames.push_back(buffer);
|
if (::strlen(hostname) == 0)
|
||||||
|
::strcpy(hostname, "localhost");
|
||||||
|
|
||||||
// And with 'gethostbyname'
|
// Try to get canonical name for the hostname
|
||||||
struct hostent* he = ::gethostbyname(buffer);
|
struct addrinfo hints;
|
||||||
|
memset(&hints, 0, sizeof hints);
|
||||||
|
hints.ai_family = AF_UNSPEC; // either IPV4 or IPV6
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
hints.ai_flags = AI_CANONNAME;
|
||||||
|
|
||||||
if (he != NULL)
|
struct addrinfo* info;
|
||||||
|
|
||||||
|
if (getaddrinfo(hostname, "http", &hints, &info) == 0)
|
||||||
{
|
{
|
||||||
if (::strlen(he->h_name) != 0)
|
for (struct addrinfo* p = info ; p != NULL ; p = p->ai_next)
|
||||||
hostnames.push_back(he->h_name);
|
|
||||||
|
|
||||||
char** alias = he->h_aliases;
|
|
||||||
|
|
||||||
while (alias && *alias)
|
|
||||||
{
|
{
|
||||||
if (::strlen(*alias) != 0)
|
if (isFQDN(p->ai_canonname))
|
||||||
hostnames.push_back(*alias);
|
{
|
||||||
|
freeaddrinfo(info);
|
||||||
++alias;
|
return p->ai_canonname;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find a Fully-Qualified Domain Name (FQDN)
|
freeaddrinfo(info);
|
||||||
for (unsigned int i = 0 ; i < hostnames.size() ; ++i)
|
|
||||||
{
|
|
||||||
if (hostnames[i].find_first_of(".") != vmime::string::npos)
|
|
||||||
return (hostnames[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (hostnames[0]);
|
return hostname;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -198,47 +198,55 @@ const vmime::charset windowsHandler::getLocaleCharset() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline bool isFQDN(const vmime::string& str)
|
||||||
|
{
|
||||||
|
if (utility::stringUtils::isStringEqualNoCase(str, "localhost", 9))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const vmime::string::size_type p = str.find_first_of(".");
|
||||||
|
return p != vmime::string::npos && p > 0 && p != str.length() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const vmime::string windowsHandler::getHostName() const
|
const vmime::string windowsHandler::getHostName() const
|
||||||
{
|
{
|
||||||
std::vector <vmime::string> hostnames;
|
char hostname[256];
|
||||||
char buffer[256];
|
|
||||||
|
|
||||||
// Try with 'gethostname'
|
// Try with 'gethostname'
|
||||||
::gethostname(buffer, sizeof(buffer));
|
::gethostname(hostname, sizeof(hostname));
|
||||||
buffer[sizeof(buffer) - 1] = '\0';
|
hostname[sizeof(hostname) - 1] = '\0';
|
||||||
|
|
||||||
if (::strlen(buffer) == 0)
|
// If this is a Fully-Qualified Domain Name (FQDN), return immediately
|
||||||
::strcpy(buffer, "localhost");
|
if (isFQDN(hostname))
|
||||||
|
return hostname;
|
||||||
|
|
||||||
hostnames.push_back(buffer);
|
if (::strlen(hostname) == 0)
|
||||||
|
::strcpy(hostname, "localhost");
|
||||||
|
|
||||||
// And with 'gethostbyname'
|
// Try to get canonical name for the hostname
|
||||||
struct hostent* he = ::gethostbyname(buffer);
|
struct addrinfo hints;
|
||||||
|
memset(&hints, 0, sizeof hints);
|
||||||
|
hints.ai_family = AF_UNSPEC; // either IPV4 or IPV6
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
hints.ai_flags = AI_CANONNAME;
|
||||||
|
|
||||||
if (he != NULL)
|
struct addrinfo* info;
|
||||||
|
|
||||||
|
if (getaddrinfo(hostname, "http", &hints, &info) == 0)
|
||||||
{
|
{
|
||||||
if (::strlen(he->h_name) != 0)
|
for (struct addrinfo* p = info ; p != NULL ; p = p->ai_next)
|
||||||
hostnames.push_back(he->h_name);
|
|
||||||
|
|
||||||
char** alias = he->h_aliases;
|
|
||||||
|
|
||||||
while (alias && *alias)
|
|
||||||
{
|
{
|
||||||
if (::strlen(*alias) != 0)
|
if (isFQDN(p->ai_canonname))
|
||||||
hostnames.push_back(*alias);
|
{
|
||||||
|
freeaddrinfo(info);
|
||||||
++alias;
|
return p->ai_canonname;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find a Fully-Qualified Domain Name (FQDN)
|
freeaddrinfo(info);
|
||||||
for (unsigned int i = 0 ; i < hostnames.size() ; ++i)
|
|
||||||
{
|
|
||||||
if (hostnames[i].find_first_of(".") != vmime::string::npos)
|
|
||||||
return (hostnames[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (hostnames[0]);
|
return hostname;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user