X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Ftcpip.c;h=2ef9dc2c054d047803e39fb6c48d22cec5b4b481;hb=377e50914cd78d52e77032a3eaf8972f23b4e7b9;hp=af2d8132c2cecf6564434c863f9bf59f3c3800bd;hpb=11dbebdf973d652e486f2b5e457cc46d1478556f;p=yaz-moved-to-github.git diff --git a/src/tcpip.c b/src/tcpip.c index af2d813..2ef9dc2 100644 --- a/src/tcpip.c +++ b/src/tcpip.c @@ -1,8 +1,8 @@ /* - * Copyright (C) 1995-2006, Index Data ApS + * Copyright (C) 1995-2007, Index Data ApS * See the file LICENSE for details. * - * $Id: tcpip.c,v 1.28 2006-09-06 15:01:53 adam Exp $ + * $Id: tcpip.c,v 1.36 2007-10-09 06:00:56 adam Exp $ */ /** * \file tcpip.c @@ -26,10 +26,17 @@ #endif #ifdef WIN32 + +/* VS 2003 or later has getaddrinfo; older versions do not */ #include +#if _MSC_VER >= 1300 #include #define HAVE_GETADDRINFO 1 #else +#define HAVE_GETADDRINFO 0 +#endif + +#else #include #include #include @@ -58,6 +65,8 @@ static int tcpip_close(COMSTACK h); static int tcpip_put(COMSTACK h, char *buf, int size); static int tcpip_get(COMSTACK h, char **buf, int *bufsize); +static int tcpip_put_connect(COMSTACK h, char *buf, int size); +static int tcpip_get_connect(COMSTACK h, char **buf, int *bufsize); static int tcpip_connect(COMSTACK h, void *address); static int tcpip_more(COMSTACK h); static int tcpip_rcvconnect(COMSTACK h); @@ -95,7 +104,7 @@ typedef struct tcpip_state int written; /* -1 if we aren't writing */ int towrite; /* to verify against user input */ - int (*complete)(const unsigned char *buf, int len); /* length/comple. */ + int (*complete)(const char *buf, int len); /* length/complete. */ #if HAVE_GETADDRINFO struct addrinfo *ai; #else @@ -108,6 +117,10 @@ typedef struct tcpip_state SSL *ssl; char cert_fname[256]; #endif + char *connect_request_buf; + int connect_request_len; + char *connect_response_buf; + int connect_response_len; } tcpip_state; #ifdef WIN32 @@ -194,12 +207,38 @@ COMSTACK tcpip_type(int s, int flags, int protocol, void *vp) else 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; + p->timeout = COMSTACK_DEFAULT_TIMEOUT; TRC(fprintf(stderr, "Created new TCPIP comstack\n")); return p; } +COMSTACK yaz_tcpip_create(int s, int flags, int protocol, + const char *connect_host) +{ + COMSTACK p = tcpip_type(s, flags, protocol, 0); + if (!p) + return 0; + if (connect_host) + { + tcpip_state *sp = (tcpip_state *) p->cprivate; + sp->connect_request_buf = xmalloc(strlen(connect_host) + 30); + sprintf(sp->connect_request_buf, "CONNECT %s HTTP/1.0\r\n\r\n", + connect_host); + sp->connect_request_len = strlen(sp->connect_request_buf); + p->f_put = tcpip_put_connect; + p->f_get = tcpip_get_connect; + sp->complete = cs_complete_auto_head; /* only want HTTP header */ + } + return p; +} + + #if HAVE_OPENSSL_SSL_H COMSTACK ssl_type(int s, int flags, int protocol, void *vp) @@ -322,10 +361,15 @@ void *tcpip_straddr(COMSTACK h, const char *str) sp->ai = tcpip_getaddrinfo(str, port); if (sp->ai && h->state == CS_ST_UNBND) { - int s; + int s = -1; struct addrinfo *ai = sp->ai; - s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - if (s < 0) + for (; ai; ai = ai->ai_next) + { + s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if (s != -1) + break; + } + if (s == -1) return 0; h->iofile = s; @@ -354,7 +398,7 @@ void *tcpip_straddr(COMSTACK h, const char *str) return 0; h->iofile = s; - if (!tcpip_set_blocking(h, h->blocking)) + if (!tcpip_set_blocking(h, h->flags)) return 0; } return &sp->addr; @@ -365,8 +409,7 @@ int tcpip_more(COMSTACK h) { tcpip_state *sp = (tcpip_state *)h->cprivate; - return sp->altlen && (*sp->complete)((unsigned char *) sp->altbuf, - sp->altlen); + return sp->altlen && (*sp->complete)(sp->altbuf, sp->altlen); } /* @@ -482,8 +525,8 @@ int tcpip_rcvconnect(COMSTACK h) #if HAVE_OPENSSL_SSL_H if (h->type == ssl_type && !sp->ctx) { + SSL_library_init(); SSL_load_error_strings(); - SSLeay_add_all_algorithms(); sp->ctx = sp->ctx_alloc = SSL_CTX_new (SSLv23_method()); if (!sp->ctx) @@ -560,7 +603,7 @@ static int tcpip_bind(COMSTACK h, void *address, int mode) #ifdef WIN32 BOOL one = 1; #else - unsigned long one = 1; + int one = 1; #endif #if HAVE_GETADDRINFO @@ -574,8 +617,8 @@ static int tcpip_bind(COMSTACK h, void *address, int mode) #if HAVE_OPENSSL_SSL_H if (h->type == ssl_type && !sp->ctx) { + SSL_library_init(); SSL_load_error_strings(); - SSLeay_add_all_algorithms(); sp->ctx = sp->ctx_alloc = SSL_CTX_new (SSLv23_method()); if (!sp->ctx) @@ -780,6 +823,8 @@ COMSTACK tcpip_accept(COMSTACK h) state->ssl = SSL_new (state->ctx); SSL_set_fd (state->ssl, cnew->iofile); } + state->connect_request_buf = 0; + state->connect_response_buf = 0; #endif h = cnew; } @@ -849,7 +894,7 @@ int tcpip_get(COMSTACK h, char **buf, int *bufsize) sp->altsize = tmpi; } h->io_pending = 0; - while (!(berlen = (*sp->complete)((unsigned char *)*buf, hasread))) + while (!(berlen = (*sp->complete)(*buf, hasread))) { if (!*bufsize) { @@ -980,7 +1025,7 @@ int ssl_get(COMSTACK h, char **buf, int *bufsize) sp->altsize = tmpi; } h->io_pending = 0; - while (!(berlen = (*sp->complete)((unsigned char *)*buf, hasread))) + while (!(berlen = (*sp->complete)(*buf, hasread))) { if (!*bufsize) { @@ -1196,6 +1241,8 @@ int tcpip_close(COMSTACK h) if (sp->ai) freeaddrinfo(sp->ai); #endif + xfree(sp->connect_request_buf); + xfree(sp->connect_response_buf); xfree(sp); xfree(h); return 0; @@ -1363,6 +1410,38 @@ int cs_set_ssl_certificate_file(COMSTACK cs, const char *fname) } #endif + +static int tcpip_put_connect(COMSTACK h, char *buf, int size) +{ + struct tcpip_state *state = (struct tcpip_state *)h->cprivate; + + int r = tcpip_put(h, state->connect_request_buf, + state->connect_request_len); + if (r == 0) + { + /* it's sent */ + h->f_put = tcpip_put; /* switch to normal tcpip put */ + r = tcpip_put(h, buf, size); + } + return r; +} + +static int tcpip_get_connect(COMSTACK h, char **buf, int *bufsize) +{ + struct tcpip_state *state = (struct tcpip_state *)h->cprivate; + int r; + + r = tcpip_get(h, &state->connect_response_buf, + &state->connect_response_len); + if (r < 1) + return r; + /* got the connect response completely */ + state->complete = cs_complete_auto; /* switch to normal tcpip get */ + h->f_get = tcpip_get; + return tcpip_get(h, buf, bufsize); +} + + /* * Local variables: * c-basic-offset: 4