From: Adam Dickmeiss Date: Mon, 24 Feb 2014 19:20:26 +0000 (+0100) Subject: tcpip: connect tries all getaddrinfo addresses YAZ-743 X-Git-Tag: v5.0.16~3 X-Git-Url: http://lists.indexdata.dk/?a=commitdiff_plain;h=63b0249c36ae686af992c1426749ebfb14ad2a03;p=yaz-moved-to-github.git tcpip: connect tries all getaddrinfo addresses YAZ-743 --- diff --git a/src/tcpip.c b/src/tcpip.c index 57f15af..0fde196 100644 --- a/src/tcpip.c +++ b/src/tcpip.c @@ -119,6 +119,7 @@ typedef struct tcpip_state int (*complete)(const char *buf, int len); /* length/complete. */ #if HAVE_GETADDRINFO struct addrinfo *ai; + struct addrinfo *ai_this; #else struct sockaddr_in addr; /* returned by cs_straddr */ #endif @@ -423,13 +424,16 @@ void *tcpip_straddr(COMSTACK h, const char *str) if (sp->ai && h->state == CS_ST_UNBND) { int s = -1; - for (ai = sp->ai; ai; ai = ai->ai_next) + if (ipv6_only >= 0) { - if (ai->ai_family == AF_INET6) + for (ai = sp->ai; ai; ai = ai->ai_next) { - s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - if (s != -1) - break; + if (ai->ai_family == AF_INET6) + { + s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if (s != -1) + break; + } } } if (s == -1) @@ -443,6 +447,8 @@ void *tcpip_straddr(COMSTACK h, const char *str) } if (s == -1) return 0; + fprintf(stderr, "First socket fd=%d\n", s); + sp->ai_this = ai; assert(ai); h->iofile = s; if (ai->ai_family == AF_INET6 && ipv6_only >= 0 && @@ -494,6 +500,36 @@ int tcpip_more(COMSTACK h) return sp->altlen && (*sp->complete)(sp->altbuf, sp->altlen); } +static int cont_connect(COMSTACK h) +{ +#if HAVE_GETADDRINFO + tcpip_state *sp = (tcpip_state *)h->cprivate; + struct addrinfo *ai = sp->ai_this; + while (ai && (ai = ai->ai_next)) + { + int s; + s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if (s != -1) + { +#ifdef WIN32 + closesocket(h->iofile); +#else + close(h->iofile); +#endif + fprintf(stderr, "Other socket call fd=%d\n", s); + h->state = CS_ST_UNBND; + h->iofile = s; + sp->ai_this = ai; + tcpip_set_blocking(h, h->flags); + return tcpip_connect(h, ai); + } +#endif + } + h->cerrno = CSYSERR; + return -1; +} + + /* * connect(2) will block (sometimes) - nothing we can do short of doing * weird things like spawning subprocesses or threading or some weird junk @@ -503,7 +539,6 @@ int tcpip_connect(COMSTACK h, void *address) { #if HAVE_GETADDRINFO struct addrinfo *ai = (struct addrinfo *) address; - tcpip_state *sp = (tcpip_state *)h->cprivate; #else struct sockaddr_in *add = (struct sockaddr_in *) address; #endif @@ -517,8 +552,6 @@ int tcpip_connect(COMSTACK h, void *address) } #if HAVE_GETADDRINFO r = connect(h->iofile, ai->ai_addr, ai->ai_addrlen); - freeaddrinfo(sp->ai); - sp->ai = 0; #else r = connect(h->iofile, (struct sockaddr *) add, sizeof(*add)); #endif @@ -535,14 +568,14 @@ int tcpip_connect(COMSTACK h, void *address) #else if (yaz_errno() == EINPROGRESS) { + fprintf(stderr, "Pending fd=%d\n", h->iofile); h->event = CS_CONNECT; h->state = CS_ST_CONNECTING; h->io_pending = CS_WANT_WRITE|CS_WANT_READ; return 1; } #endif - h->cerrno = CSYSERR; - return -1; + return cont_connect(h); } h->event = CS_CONNECT; h->state = CS_ST_CONNECTING; @@ -1159,8 +1192,7 @@ int tcpip_put(COMSTACK h, char *buf, int size) h->io_pending = CS_WANT_WRITE; return 1; } - h->cerrno = CSYSERR; - return -1; + return cont_connect(h); } state->written += res; TRC(fprintf(stderr, " Wrote %d, written=%d, nbytes=%d\n",