X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=src%2Ftcpip.c;h=b992319ca2c12d4006206c6a260717ff8369cd79;hp=a16fe5eb202c58d9edaf00a45c5f67a4ec29fb1d;hb=ee6ab2ee3a9ee1a8c65d7272ec7fba1d886f5af0;hpb=13f137b81808f6a3359f898614cc988995af3965 diff --git a/src/tcpip.c b/src/tcpip.c index a16fe5e..b992319 100644 --- a/src/tcpip.c +++ b/src/tcpip.c @@ -1,8 +1,6 @@ -/* - * Copyright (C) 1995-2006, Index Data ApS +/* This file is part of the YAZ toolkit. + * Copyright (C) 1995-2008 Index Data * See the file LICENSE for details. - * - * $Id: tcpip.c,v 1.31 2006-09-21 15:55:25 adam Exp $ */ /** * \file tcpip.c @@ -26,10 +24,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 @@ -39,9 +44,6 @@ #if HAVE_SYS_SOCKET_H #include #endif -#if HAVE_SYS_SELECT_H -#include -#endif #if HAVE_SYS_WAIT_H #include #endif @@ -58,6 +60,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 +99,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 +112,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 +202,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 = (char *) 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) @@ -370,8 +404,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); } /* @@ -487,8 +520,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) @@ -579,8 +612,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) @@ -685,7 +718,15 @@ int tcpip_listen(COMSTACK h, char *raddr, int *addrlen, ) h->cerrno = CSNODATA; else + { +#ifdef WIN32 + shutdown(h->iofile, SD_RECEIVE); +#else + shutdown(h->iofile, SHUT_RD); +#endif + listen(h->iofile, SOMAXCONN); h->cerrno = CSYSERR; + } return -1; } if (addrlen && (size_t) (*addrlen) >= sizeof(struct sockaddr_in)) @@ -786,6 +827,8 @@ COMSTACK tcpip_accept(COMSTACK h) SSL_set_fd (state->ssl, cnew->iofile); } #endif + state->connect_request_buf = 0; + state->connect_response_buf = 0; h = cnew; } if (h->state == CS_ST_ACCEPT) @@ -854,7 +897,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) { @@ -985,7 +1028,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) { @@ -1201,6 +1244,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; @@ -1368,6 +1413,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