X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=src%2Ftcpip.c;h=ab9f6c426b38e9d7049d1d7cf2bfc8a27acd0b20;hp=72461c11a28be08052b3391ed3e4b2b7ea915179;hb=7e13f7fc5c0865a6f995ad7735f62015694890e1;hpb=c753bab9ac07a09f1bd7ba1dc363e58310e307a7 diff --git a/src/tcpip.c b/src/tcpip.c index 72461c1..ab9f6c4 100644 --- a/src/tcpip.c +++ b/src/tcpip.c @@ -67,7 +67,9 @@ #include #include +#ifndef WIN32 #define RESOLVER_THREAD 1 +#endif static void tcpip_close(COMSTACK h); static int tcpip_put(COMSTACK h, char *buf, int size); @@ -122,6 +124,13 @@ typedef struct tcpip_state #if HAVE_GETADDRINFO struct addrinfo *ai; struct addrinfo *ai_connect; + int ipv6_only; +#if RESOLVER_THREAD + int pipefd[2]; + char *hoststr; + const char *port; + yaz_thread_t thread_id; +#endif #else struct sockaddr_in addr; /* returned by cs_straddr */ #endif @@ -135,13 +144,6 @@ typedef struct tcpip_state int connect_request_len; char *connect_response_buf; int connect_response_len; - int ipv6_only; -#if RESOLVER_THREAD - int pipefd[2]; - char *hoststr; - const char *port; - yaz_thread_t thread_id; -#endif } tcpip_state; static int tcpip_init(void) @@ -165,6 +167,37 @@ static int tcpip_init(void) return 1; } +static struct tcpip_state *tcpip_state_create(void) +{ + tcpip_state *sp = (struct tcpip_state *) xmalloc(sizeof(*sp)); + + sp->altbuf = 0; + sp->altsize = sp->altlen = 0; + sp->towrite = sp->written = -1; + sp->complete = cs_complete_auto; + +#if HAVE_GETADDRINFO + sp->ai = 0; + sp->ai_connect = 0; +#if RESOLVER_THREAD + sp->hoststr = 0; + sp->pipefd[0] = sp->pipefd[1] = -1; + sp->port = 0; +#endif +#endif + +#if HAVE_GNUTLS_H + sp->cred_ptr = 0; + sp->session = 0; + strcpy(sp->cert_fname, "yaz.pem"); +#endif + sp->connect_request_buf = 0; + sp->connect_request_len = 0; + sp->connect_response_buf = 0; + sp->connect_response_len = 0; + return sp; +} + /* * This function is always called through the cs_create() macro. * s >= 0: socket has already been established for us. @@ -172,16 +205,13 @@ static int tcpip_init(void) COMSTACK tcpip_type(int s, int flags, int protocol, void *vp) { COMSTACK p; - tcpip_state *sp; if (!tcpip_init()) return 0; if (!(p = (struct comstack *)xmalloc(sizeof(struct comstack)))) return 0; - if (!(sp = (struct tcpip_state *)(p->cprivate = - xmalloc(sizeof(tcpip_state))))) - return 0; + p->cprivate = tcpip_state_create(); p->flags = flags; p->io_pending = 0; @@ -208,30 +238,6 @@ COMSTACK tcpip_type(int s, int flags, int protocol, void *vp) p->cerrno = 0; p->user = 0; -#if HAVE_GNUTLS_H - sp->cred_ptr = 0; - sp->session = 0; - strcpy(sp->cert_fname, "yaz.pem"); -#endif - -#if HAVE_GETADDRINFO -#if RESOLVER_THREAD - sp->hoststr = 0; - sp->pipefd[0] = sp->pipefd[1] = -1; - sp->port = 0; -#endif - sp->ai = 0; -#endif - sp->altbuf = 0; - sp->altsize = sp->altlen = 0; - sp->towrite = sp->written = -1; - sp->complete = cs_complete_auto; - - sp->connect_request_buf = 0; - sp->connect_request_len = 0; - sp->connect_response_buf = 0; - sp->connect_response_len = 0; - TRC(fprintf(stderr, "Created new TCPIP comstack h=%p\n", p)); return p; @@ -478,6 +484,7 @@ static struct addrinfo *wait_resolver_thread(COMSTACK h) close(sp->pipefd[0]); close(sp->pipefd[1]); sp->pipefd[0] = -1; + h->iofile = -1; return create_net_socket(h); } @@ -499,17 +506,20 @@ void *tcpip_straddr(COMSTACK h, const char *str) port = "80"; } #if RESOLVER_THREAD - if (sp->pipefd[0] != -1) - return 0; - if (pipe(sp->pipefd) == -1) - return 0; + if (h->flags & CS_FLAGS_DNS_NO_BLOCK) + { + if (sp->pipefd[0] != -1) + return 0; + if (pipe(sp->pipefd) == -1) + return 0; - sp->port = port; - xfree(sp->hoststr); - sp->hoststr = xstrdup(str); - sp->thread_id = yaz_thread_create(resolver_thread, h); - return sp->hoststr; -#else + sp->port = port; + xfree(sp->hoststr); + sp->hoststr = xstrdup(str); + sp->thread_id = yaz_thread_create(resolver_thread, h); + return sp->hoststr; + } +#endif if (sp->ai) freeaddrinfo(sp->ai); sp->ai = tcpip_getaddrinfo(str, port, &sp->ipv6_only); @@ -518,7 +528,6 @@ void *tcpip_straddr(COMSTACK h, const char *str) return create_net_socket(h); } return sp->ai; -#endif } #else @@ -590,8 +599,8 @@ static int cont_connect(COMSTACK h) tcpip_set_blocking(h, h->flags); return tcpip_connect(h, ai); } -#endif } +#endif h->cerrno = CSYSERR; return -1; } @@ -618,6 +627,7 @@ int tcpip_connect(COMSTACK h, void *address) h->cerrno = CSOUTSTATE; return -1; } +#if HAVE_GETADDRINFO #if RESOLVER_THREAD if (sp->pipefd[0] != -1) { @@ -637,7 +647,6 @@ int tcpip_connect(COMSTACK h, void *address) } } #endif -#if HAVE_GETADDRINFO r = connect(h->iofile, ai->ai_addr, ai->ai_addrlen); sp->ai_connect = ai; #else @@ -676,13 +685,12 @@ int tcpip_connect(COMSTACK h, void *address) */ int tcpip_rcvconnect(COMSTACK h) { -#if HAVE_GNUTLS_H tcpip_state *sp = (tcpip_state *)h->cprivate; -#endif TRC(fprintf(stderr, "tcpip_rcvconnect\n")); if (h->state == CS_ST_DATAXFER) return 0; +#if HAVE_GETADDRINFO #if RESOLVER_THREAD if (sp->pipefd[0] != -1) { @@ -693,6 +701,7 @@ int tcpip_rcvconnect(COMSTACK h) return tcpip_connect(h, ai); } #endif +#endif if (h->state != CS_ST_CONNECTING) { h->cerrno = CSOUTSTATE; @@ -745,6 +754,7 @@ static int tcpip_bind(COMSTACK h, void *address, int mode) int one = 1; #endif +#if HAVE_GETADDRINFO #if RESOLVER_THREAD if (sp->pipefd[0] != -1) { @@ -753,6 +763,7 @@ static int tcpip_bind(COMSTACK h, void *address, int mode) return -1; } #endif +#endif #if HAVE_GNUTLS_H if (h->type == ssl_type && !sp->session) { @@ -764,7 +775,6 @@ static int tcpip_bind(COMSTACK h, void *address, int mode) GNUTLS_X509_FMT_PEM); if (res != GNUTLS_E_SUCCESS) { - fprintf(stderr, "Error 1\n"); h->cerrno = CSERRORSSL; return -1; } @@ -887,37 +897,15 @@ COMSTACK tcpip_accept(COMSTACK h) TRC(fprintf(stderr, "tcpip_accept h=%p pid=%d\n", h, getpid())); if (h->state == CS_ST_INCON) { - tcpip_state *state, *st = (tcpip_state *)h->cprivate; - if (!(cnew = (COMSTACK)xmalloc(sizeof(*cnew)))) - { - h->cerrno = CSYSERR; -#ifdef WIN32 - closesocket(h->newfd); -#else - close(h->newfd); -#endif - h->newfd = -1; - return 0; - } + tcpip_state *st = (tcpip_state *)h->cprivate; + tcpip_state *state = tcpip_state_create(); + cnew = (COMSTACK) xmalloc(sizeof(*cnew)); + memcpy(cnew, h, sizeof(*h)); cnew->iofile = h->newfd; cnew->io_pending = 0; + cnew->cprivate = state; - if (!(state = (tcpip_state *) - (cnew->cprivate = xmalloc(sizeof(tcpip_state))))) - { - h->cerrno = CSYSERR; - if (h->newfd != -1) - { -#ifdef WIN32 - closesocket(h->newfd); -#else - close(h->newfd); -#endif - h->newfd = -1; - } - return 0; - } if (!tcpip_set_blocking(cnew, cnew->flags)) { h->cerrno = CSYSERR; @@ -930,24 +918,16 @@ COMSTACK tcpip_accept(COMSTACK h) #endif h->newfd = -1; } - xfree(cnew); xfree(state); + xfree(cnew); return 0; } h->newfd = -1; - state->altbuf = 0; - state->altsize = state->altlen = 0; - state->towrite = state->written = -1; - state->complete = st->complete; -#if HAVE_GETADDRINFO - state->ai = 0; -#endif cnew->state = CS_ST_ACCEPT; h->state = CS_ST_IDLE; #if HAVE_GNUTLS_H state->cred_ptr = st->cred_ptr; - state->session = 0; if (st->cred_ptr) { int res; @@ -982,8 +962,6 @@ COMSTACK tcpip_accept(COMSTACK h) (size_t) cnew->iofile); } #endif - state->connect_request_buf = 0; - state->connect_response_buf = 0; h = cnew; } if (h->state == CS_ST_ACCEPT) @@ -1346,6 +1324,17 @@ void tcpip_close(COMSTACK h) tcpip_state *sp = (struct tcpip_state *)h->cprivate; TRC(fprintf(stderr, "tcpip_close: h=%p pid=%d\n", h, getpid())); +#if HAVE_GETADDRINFO +#if RESOLVER_THREAD + if (sp->pipefd[0] != -1) + { + yaz_thread_join(&sp->thread_id, 0); + close(sp->pipefd[0]); + close(sp->pipefd[1]); + h->iofile = -1; + } +#endif +#endif if (h->iofile != -1) { #if HAVE_GNUTLS_H