Added support for getaddrinfo() on POSIX.

This commit is contained in:
Vincent Richard 2005-12-26 18:20:47 +00:00
parent d906896132
commit 69e0083549
3 changed files with 77 additions and 0 deletions

View File

@ -2,6 +2,11 @@
VERSION 0.8.1cvs
================
2005-12-26 Vincent Richard <vincent@vincent-richard.net>
* posixSocket.cpp: use getaddrinfo() if available. This should bring
thread-safe DNS resolution and IPv6 support.
2005-12-18 Vincent Richard <vincent@vincent-richard.net>
* IMAPParser.hpp: compatibility bugs + enhanced debugging trace.

View File

@ -827,6 +827,10 @@ if IsProtocolSupported(messaging_protocols, 'sendmail'):
config_hpp.write("""
// Additional defines
#define VMIME_HAVE_GETADDRINFO 1
#endif // VMIME_CONFIG_HPP_INCLUDED
""")
@ -1661,10 +1665,17 @@ AC_PATH_PROG(SENDMAIL, sendmail, /usr/sbin/sendmail, /usr/sbin:/usr/lib)
# Detect some platform-specific stuff
#
# -- MLang (Windows)
if test "x$VMIME_DETECT_PLATFORM" = "xwindows"; then
AC_CHECK_HEADER(mlang.h, [VMIME_ADDITIONAL_DEFINES="$VMIME_ADDITIONAL_DEFINES HAVE_MLANG_H"])
fi
# -- getaddrinfo (POSIX)
if test "x$VMIME_DETECT_PLATFORM" = "xposix"; then
AC_CHECK_HEADERS(netdb.h sys/types.h sys/socket.h,)
AC_CHECK_FUNC(getaddrinfo, [VMIME_ADDITIONAL_DEFINES="$VMIME_ADDITIONAL_DEFINES HAVE_GETADDRINFO"])
fi
""")

View File

@ -67,6 +67,65 @@ void posixSocket::connect(const vmime::string& address, const vmime::port_t port
m_desc = -1;
}
#if VMIME_HAVE_GETADDRINFO // use thread-safe and IPv6-aware getaddrinfo() if available
// Resolve address, if needed
struct ::addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_CANONNAME;
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
std::ostringstream portStr;
portStr << port;
struct ::addrinfo* res0;
if (::getaddrinfo(address.c_str(), portStr.str().c_str(), &hints, &res0) != 0)
{
// Error: cannot resolve address
throw vmime::exceptions::connection_error("Cannot resolve address.");
}
// Connect to host
int sock = -1;
struct ::addrinfo* res = res0;
for ( ; sock == -1 && res != NULL ; res = res->ai_next)
{
sock = ::socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (sock < 0)
continue; // try next
if (::connect(sock, res->ai_addr, res->ai_addrlen) < 0)
{
::close(sock);
sock = -1;
continue; // try next
}
}
::freeaddrinfo(res0);
if (sock == -1)
{
try
{
throwSocketError(errno);
}
catch (exceptions::socket_exception& e)
{
throw vmime::exceptions::connection_error
("Error while connecting socket.", e);
}
}
m_desc = sock;
#else // !VMIME_HAVE_GETADDRINFO
// Resolve address
::sockaddr_in addr;
@ -123,6 +182,8 @@ void posixSocket::connect(const vmime::string& address, const vmime::port_t port
}
}
#endif // VMIME_HAVE_GETADDRINFO
::fcntl(m_desc, F_SETFL, ::fcntl(m_desc, F_GETFL) | O_NONBLOCK);
}