aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Richard <[email protected]>2005-12-26 18:20:47 +0000
committerVincent Richard <[email protected]>2005-12-26 18:20:47 +0000
commit69e0083549f8dcc986f31d83541bd214c1c22f08 (patch)
tree112bfc048edb07f88bbfa093bc5969cd798cdd90
parentFixed typo causing infinite loop. (diff)
downloadvmime-69e0083549f8dcc986f31d83541bd214c1c22f08.tar.gz
vmime-69e0083549f8dcc986f31d83541bd214c1c22f08.zip
Added support for getaddrinfo() on POSIX.
-rw-r--r--ChangeLog5
-rw-r--r--SConstruct11
-rw-r--r--src/platforms/posix/posixSocket.cpp61
3 files changed, 77 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 0a6ad965..260d1e5b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,11 @@
VERSION 0.8.1cvs
================
+2005-12-26 Vincent Richard <[email protected]>
+
+ * posixSocket.cpp: use getaddrinfo() if available. This should bring
+ thread-safe DNS resolution and IPv6 support.
+
2005-12-18 Vincent Richard <[email protected]>
* IMAPParser.hpp: compatibility bugs + enhanced debugging trace.
diff --git a/SConstruct b/SConstruct
index 01e293d0..dd7847fb 100644
--- a/SConstruct
+++ b/SConstruct
@@ -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
+
""")
diff --git a/src/platforms/posix/posixSocket.cpp b/src/platforms/posix/posixSocket.cpp
index 5585492a..d514a1a6 100644
--- a/src/platforms/posix/posixSocket.cpp
+++ b/src/platforms/posix/posixSocket.cpp
@@ -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);
}