[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [msmtp-users] msmtp: runtime fails with "Bad value for ai_flags"
Hi Lonnie!
On Wed, 31 Dec 2014 17:00:24 -0600, Lonnie Abelbeck wrote:
> msmtp: cannot locate host foo.example.com: Bad value for ai_flags
> msmtp: could not send mail...
>
> [...]
>
> So the bottom line seems to be that checking the headers for AI_IDN
> (via autoconf) is not good enough.
This is not good. I asked on the glibc-help mailing list if this is
really intended, and how one is supposed to check if AI_IDN actually
works.
In my opinion, AI_IDN should only be defined if it is actually
supported. Otherwise, you need to build with a fall back code path that
uses libidn, and if you need that anyway, then why bother with an
unreliable AI_IDN? There's nothing to gain, you just make the code less
readable.
> The question is can autoconf determine if glibc was build with
> libidn ?
I did not find a way, except for AC_RUN_IFELSE, which does not work
when cross-compiling.
> Another solution would be a --with-idn configure switch which would
> add a USE_IDN config.h define.
I suggest --enable-gai-idn. The --with-* switches are typically
used to include external libraries.
See the attached patch.
This also allows for future systems that simply support IDN without
having to use AI_IDN (although we then need a way for configure to
detect this). For example, musl plans to support IDN by default
http://wiki.musl-libc.org/wiki/Functional_differences_from_glibc#Name_Resolver_.2F_DNS).
I think they are right.
An unrelated question: why are you using glibc without IDN support?
Libidn is included in the glibc sources; I cannot see a reason to
disable it.
Regards,
Martin
diff --git a/configure.ac b/configure.ac
index 8205335..95fd2e0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -136,33 +136,45 @@ if test "$libgsasl" != "no"; then
fi
AM_CONDITIONAL([HAVE_LIBGSASL], [test "$libgsasl" = "yes"])
-dnl Do we need libidn for IDN support? Modern systems don't.
-want_libidn=yes
-AC_CHECK_DECL([AI_IDN], [], [], [#include <netdb.h>])
-if test "$ac_cv_have_decl_AI_IDN" = "yes"; then
- if test "$have_tls" = "no"; then
- want_libidn=no
- elif test "$tls_lib" = "GnuTLS"; then
- gnutls_has_idn=no
- AC_MSG_CHECKING([if GnuTLS has builtin IDN support])
- CFLAGS_BAK="$CFLAGS"
- CFLAGS="$CFLAGS $tls_CFLAGS"
- AC_COMPILE_IFELSE(
- [AC_LANG_PROGRAM([[
- #include <gnutls/gnutls.h>
- #if GNUTLS_VERSION_NUMBER < 0x030400
- error: GnuTLS does not have builtin IDN support
- #endif]],
- [[int x = 0;]])],
- [gnutls_has_idn="yes"], [])
- CFLAGS="$CFLAGS_BAK"
- AC_MSG_RESULT([$gnutls_has_idn])
- if test "$gnutls_has_idn" = "yes"; then
- want_libidn=no
- fi
+dnl Check if getaddrinfo() has IDN support (and we want to use it)
+AC_ARG_ENABLE([gai-idn],
+ [AS_HELP_STRING([--enable-gai-idn], [Use IDN support from getaddrinfo if available. Enabled by default.])],
+ [if test "$enableval" = "yes"; then want_gai_idn="yes"; else want_gai_idn="no"; fi], [want_gai_idn="yes"])
+have_gai_idn=no
+if test "$want_gai_idn" = "yes"; then
+ AC_CHECK_DECL([AI_IDN], [], [], [#include <netdb.h>])
+ if test "$ac_cv_have_decl_AI_IDN" = "yes"; then
+ have_gai_idn=yes
+ AC_DEFINE([HAVE_GAI_IDN], [1], [Define to 1 if getaddrinfo supports IDN])
fi
fi
+
+dnl Check if TLS has IDN support
+have_tls_idn=no
+if test "$tls_lib" = "GnuTLS"; then
+ AC_MSG_CHECKING([if GnuTLS has builtin IDN support])
+ CFLAGS_BAK="$CFLAGS"
+ CFLAGS="$CFLAGS $tls_CFLAGS"
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[
+ #include <gnutls/gnutls.h>
+ #if GNUTLS_VERSION_NUMBER < 0x030400
+ error: GnuTLS does not have builtin IDN support
+ #endif]],
+ [[int x = 0;]])],
+ [have_tls_idn="yes"], [])
+ CFLAGS="$CFLAGS_BAK"
+ AC_MSG_RESULT([$have_tls_idn])
+fi
+
+dnl Do we need libidn for IDN support? Modern systems don't.
AC_MSG_CHECKING([if libidn is needed for IDN support])
+want_libidn=no
+if test "$have_gai_idn" = "no"; then
+ want_libidn=yes
+elif test "$have_tls" = "yes" -a "$have_tls_idn" = "no"; then
+ want_libidn=yes
+fi
AC_MSG_RESULT([$want_libidn])
dnl GNU Libidn
diff --git a/src/net.c b/src/net.c
index eae0948..85644b9 100644
--- a/src/net.c
+++ b/src/net.c
@@ -620,8 +620,10 @@ int net_open_socket(
hints.ai_addr = NULL;
hints.ai_next = NULL;
port_string = xasprintf("%d", port);
-#ifdef AI_IDN
+#ifdef HAVE_GAI_IDN
+# ifdef AI_IDN
hints.ai_flags |= AI_IDN;
+# endif
#elif defined(HAVE_LIBIDN)
idna_to_ascii_lz(hostname, &idn_hostname, 0);
#endif