#endif
#ifdef WIN32
-
/* VS 2003 or later has getaddrinfo; older versions do not */
#include <winsock2.h>
#if _MSC_VER >= 1300
#else
#define HAVE_GETADDRINFO 0
#endif
+#endif
-#else
+#if HAVE_NETINET_IN_H
#include <netinet/in.h>
+#endif
+#if HAVE_NETDB_H
#include <netdb.h>
+#endif
+#if HAVE_ARPA_INET_H
#include <arpa/inet.h>
+#endif
+#if HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
#endif
-
#if HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
static void tcpip_create_cred(COMSTACK cs)
{
tcpip_state *sp = (tcpip_state *) cs->cprivate;
- sp->cred_ptr = xmalloc(sizeof(*sp->cred_ptr));
+ sp->cred_ptr = (struct tcpip_cred_ptr *) xmalloc(sizeof(*sp->cred_ptr));
sp->cred_ptr->ref = 1;
gnutls_certificate_allocate_credentials(&sp->cred_ptr->xcred);
}
return 1;
}
-
#if HAVE_GETADDRINFO
+/** \brief Creates socket using particular address family (AF_)
+ \param ai getaddrinfo result
+ \param mask family mask
+ \returns socket or -1 if none could be created
+
+*/
+static int create_socket_family(struct addrinfo *ai, unsigned mask)
+{
+ for (; ai; ai = ai->ai_next)
+ {
+ if ((ai->ai_family & mask) == mask)
+ {
+ int s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+ if (s != -1)
+ return s;
+ }
+ }
+ return -1;
+}
+
void *tcpip_straddr(COMSTACK h, const char *str)
{
tcpip_state *sp = (tcpip_state *)h->cprivate;
sp->ai = tcpip_getaddrinfo(str, port);
if (sp->ai && h->state == CS_ST_UNBND)
{
- int s = -1;
- struct addrinfo *ai = sp->ai;
- for (; ai; ai = ai->ai_next)
- {
- s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
- if (s != -1)
- break;
- }
+ /* The getaddrinfo call may return multiple addresses when passive
+ flags are used (AI_PASSIVE). This function picks the IPV6 if a
+ socket can be created for it. Otherwise IPV4 is used.
+ See also bug #2350 */
+ int s = create_socket_family(sp->ai, AF_INET6);
+ if (s == -1)
+ s = create_socket_family(sp->ai, AF_INET);
if (s == -1)
return 0;
h->iofile = s;
tcpip_create_cred(h);
gnutls_init(&sp->session, GNUTLS_CLIENT);
- gnutls_priority_set_direct(sp->session, "PERFORMANCE", NULL);
+ gnutls_set_default_priority(sp->session);
gnutls_credentials_set (sp->session, GNUTLS_CRD_CERTIFICATE,
sp->cred_ptr->xcred);
xfree(state);
return 0;
}
- res = gnutls_priority_set_direct(state->session,
- "PERFORMANCE", NULL);
+ res = gnutls_set_default_priority(state->session);
if (res != GNUTLS_E_SUCCESS)
{
xfree(cnew);