X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=comstack%2Ftcpip.c;h=a106805155e03738040ddfa5d2e185530865f0f8;hb=2c8ec8c2d1dd7dd698e406ff99e1b7b439c4fa9b;hp=c6076b05cee7e742ba02661d79c03fd3e2d32206;hpb=8e4eabe621f8b8195faa6625a38a2e1ae7b68aa1;p=yaz-moved-to-github.git diff --git a/comstack/tcpip.c b/comstack/tcpip.c index c6076b0..a106805 100644 --- a/comstack/tcpip.c +++ b/comstack/tcpip.c @@ -1,10 +1,37 @@ /* - * Copyright (c) 1995-2000, Index Data + * Copyright (c) 1995-2001, Index Data * See the file LICENSE for details. - * Sebastian Hammer, Adam Dickmeiss * * $Log: tcpip.c,v $ - * Revision 1.34 2000-11-23 10:58:32 adam + * Revision 1.43 2001-10-22 16:00:04 adam + * Renamed states for COMSTACKs to avoid confusion with events. + * + * Revision 1.42 2001/10/22 13:57:24 adam + * Implemented cs_rcvconnect and cs_look as described in the documentation. + * + * Revision 1.41 2001/10/12 21:49:26 adam + * For accept/recv/send check for EAGAIN if it's differs from EWOULDBLOCK. + * + * Revision 1.40 2001/08/23 09:02:46 adam + * WIN32 fixes: Socket not re-used for bind. yaz_log logs WIN32 error + * message. + * + * Revision 1.39 2001/07/19 19:49:40 adam + * Fixed bug in tcpip_set_blocking. + * + * Revision 1.38 2001/03/21 12:43:36 adam + * Implemented cs_create_host. Better error reporting for SSL comstack. + * + * Revision 1.37 2001/03/08 20:18:55 adam + * Added cs_set_blocking. Patch from Matthew Carey. + * + * Revision 1.36 2001/02/21 13:46:53 adam + * C++ fixes. + * + * Revision 1.35 2000/11/27 15:17:40 adam + * Using SSLeay_add_all_algorithms instead of OpenSSL_add_all_algorithms. + * + * Revision 1.34 2000/11/23 10:58:32 adam * SSL comstack support. Separate POSIX thread support library. * * Revision 1.33 2000/09/04 08:27:11 adam @@ -208,6 +235,7 @@ int tcpip_bind(COMSTACK h, void *address, int mode); int tcpip_listen(COMSTACK h, char *raddr, int *addrlen, int (*check_ip)(void *cd, const char *a, int len, int type), void *cd); +int static tcpip_set_blocking(COMSTACK p, int blocking); #if HAVE_OPENSSL_SSL_H int ssl_get(COMSTACK h, char **buf, int *bufsize); @@ -330,8 +358,9 @@ COMSTACK tcpip_type(int s, int blocking, int protocol, void *vp) p->f_accept = tcpip_accept; p->f_addrstr = tcpip_addrstr; p->f_straddr = tcpip_straddr; + p->f_set_blocking = tcpip_set_blocking; - p->state = new_socket ? CS_UNBND : CS_IDLE; /* state of line */ + p->state = new_socket ? CS_ST_UNBND : CS_ST_IDLE; /* state of line */ p->event = CS_NONE; p->cerrno = 0; p->stackerr = 0; @@ -375,7 +404,7 @@ COMSTACK ssl_type(int s, int blocking, int protocol, void *vp) else { SSL_load_error_strings(); - OpenSSL_add_all_algorithms(); + SSLeay_add_all_algorithms(); state->ctx = state->ctx_alloc = SSL_CTX_new (SSLv23_method()); if (!state->ctx) @@ -464,7 +493,7 @@ int tcpip_connect(COMSTACK h, void *address) TRC(fprintf(stderr, "tcpip_connect\n")); h->io_pending = 0; - if (h->state == CS_UNBND) + if (h->state == CS_ST_UNBND) { r = connect(h->iofile, (struct sockaddr *) add, sizeof(*add)); if (r < 0) @@ -472,23 +501,27 @@ int tcpip_connect(COMSTACK h, void *address) #ifdef WIN32 if (WSAGetLastError() == WSAEWOULDBLOCK) { - h->state = CS_CONNECTING; + h->event = CS_CONNECT; + h->state = CS_ST_CONNECTING; h->io_pending = CS_WANT_WRITE; return 1; } #else if (errno == EINPROGRESS) { - h->state = CS_CONNECTING; + 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; } - h->state = CS_CONNECTING; + h->event = CS_CONNECT; + h->state = CS_ST_CONNECTING; } - if (h->state != CS_CONNECTING) + if (h->state != CS_ST_CONNECTING) { h->cerrno = CSOUTSTATE; return -1; @@ -519,21 +552,53 @@ int tcpip_connect(COMSTACK h, void *address) h->io_pending = CS_WANT_WRITE; return 1; } + h->cerrno = CSERRORSSL; return -1; } } #endif - h->state = CS_DATAXFER; + h->event = CS_DATA; + h->state = CS_ST_DATAXFER; return 0; } /* * nop */ -int tcpip_rcvconnect(COMSTACK h) +int tcpip_rcvconnect(COMSTACK cs) { TRC(fprintf(stderr, "tcpip_rcvconnect\n")); - return 0; + + if (cs->event == CS_CONNECT) + { + int fd = cs->iofile; + fd_set input, output; + struct timeval tv; + int r; + + tv.tv_sec = 0; + tv.tv_usec = 1; + + FD_ZERO(&input); + FD_ZERO(&output); + FD_SET (fd, &input); + FD_SET (fd, &output); + + r = select (fd+1, &input, &output, 0, &tv); + if (r > 0) + { + if (FD_ISSET(cs->iofile, &output)) + { + cs->event = CS_DATA; + return 0; /* write OK, we're OK */ + } + else + return -1; /* an error, for sure */ + } + else if (r == 0) + return 0; /* timeout - incomplete */ + } + return -1; /* wrong state or bad select */ } #define CERTF "ztest.pem" @@ -585,13 +650,15 @@ int tcpip_bind(COMSTACK h, void *address, int mode) #else TRC (fprintf (stderr, "tcpip_bind\n")); #endif +#ifndef WIN32 if (setsockopt(h->iofile, SOL_SOCKET, SO_REUSEADDR, (char*) &one, sizeof(one)) < 0) { h->cerrno = CSYSERR; return -1; } - if (bind(h->iofile, addr, sizeof(struct sockaddr_in)) < 0) +#endif + if (bind(h->iofile, addr, sizeof(struct sockaddr_in))) { h->cerrno = CSYSERR; return -1; @@ -601,7 +668,8 @@ int tcpip_bind(COMSTACK h, void *address, int mode) h->cerrno = CSYSERR; return -1; } - h->state = CS_IDLE; + h->state = CS_ST_IDLE; + h->event = CS_LISTEN; return 0; } @@ -610,10 +678,14 @@ int tcpip_listen(COMSTACK h, char *raddr, int *addrlen, void *cd) { struct sockaddr_in addr; +#ifdef __cplusplus + socklen_t len = sizeof(addr); +#else int len = sizeof(addr); +#endif TRC(fprintf(stderr, "tcpip_listen pid=%d\n", getpid())); - if (h->state != CS_IDLE) + if (h->state != CS_ST_IDLE) { h->cerrno = CSOUTSTATE; return -1; @@ -625,7 +697,12 @@ int tcpip_listen(COMSTACK h, char *raddr, int *addrlen, #ifdef WIN32 WSAGetLastError() == WSAEWOULDBLOCK #else - errno == EWOULDBLOCK + errno == EWOULDBLOCK +#ifdef EAGAIN +#if EAGAIN != EWOULDBLOCK + || errno == EAGAIN +#endif +#endif #endif ) h->cerrno = CSNODATA; @@ -649,7 +726,7 @@ int tcpip_listen(COMSTACK h, char *raddr, int *addrlen, h->newfd = -1; return -1; } - h->state = CS_INCON; + h->state = CS_ST_INCON; return 0; } @@ -662,7 +739,7 @@ COMSTACK tcpip_accept(COMSTACK h) #endif TRC(fprintf(stderr, "tcpip_accept\n")); - if (h->state == CS_INCON) + if (h->state == CS_ST_INCON) { if (!(cnew = (COMSTACK)xmalloc(sizeof(*cnew)))) { @@ -720,8 +797,8 @@ COMSTACK tcpip_accept(COMSTACK h) state->altsize = state->altlen = 0; state->towrite = state->written = -1; state->complete = st->complete; - cnew->state = CS_ACCEPT; - h->state = CS_IDLE; + cnew->state = CS_ST_ACCEPT; + h->state = CS_ST_IDLE; #if HAVE_OPENSSL_SSL_H state->ctx = st->ctx; @@ -735,7 +812,7 @@ COMSTACK tcpip_accept(COMSTACK h) #endif h = cnew; } - if (h->state == CS_ACCEPT) + if (h->state == CS_ST_ACCEPT) { #if HAVE_OPENSSL_SSL_H tcpip_state *state = (tcpip_state *)h->cprivate; @@ -770,7 +847,8 @@ COMSTACK tcpip_accept(COMSTACK h) return 0; } h->io_pending = 0; - h->state = CS_DATAXFER; + h->state = CS_ST_DATAXFER; + h->event = CS_DATA; return h; } @@ -825,10 +903,13 @@ int tcpip_get(COMSTACK h, char **buf, int *bufsize) else return -1; #else - if (errno == EWOULDBLOCK -#ifdef EINPROGRESS - || errno == EINPROGRESS + if (errno == EWOULDBLOCK +#ifdef EAGAIN +#if EAGAIN != EWOULDBLOCK + || errno == EAGAIN #endif +#endif + || errno == EINPROGRESS ) { h->io_pending = CS_WANT_READ; @@ -926,6 +1007,7 @@ int ssl_get(COMSTACK h, char **buf, int *bufsize) } if (res == 0) return 0; + h->cerrno = CSERRORSSL; return -1; } hasread += res; @@ -968,6 +1050,7 @@ int tcpip_put(COMSTACK h, char *buf, int size) TRC(fprintf(stderr, "tcpip_put: size=%d\n", size)); h->io_pending = 0; + h->event = CS_DATA; if (state->towrite < 0) { state->towrite = size; @@ -980,14 +1063,26 @@ int tcpip_put(COMSTACK h, char *buf, int size) } while (state->towrite > state->written) { - if ((res = send(h->iofile, buf + state->written, size - - state->written, 0)) < 0) + if ((res = + send(h->iofile, buf + state->written, size - + state->written, +#ifdef MSG_NOSIGNAL + MSG_NOSIGNAL +#else + 0 +#endif + )) < 0) { if ( #ifdef WIN32 WSAGetLastError() == WSAEWOULDBLOCK #else - errno == EAGAIN + errno == EWOULDBLOCK +#ifdef EAGAIN +#if EAGAIN != EWOULDBLOCK + || errno == EAGAIN +#endif +#endif #endif ) { @@ -1021,6 +1116,7 @@ int ssl_put(COMSTACK h, char *buf, int size) TRC(fprintf(stderr, "ssl_put: size=%d\n", size)); h->io_pending = 0; + h->event = CS_DATA; if (state->towrite < 0) { state->towrite = size; @@ -1050,6 +1146,7 @@ int ssl_put(COMSTACK h, char *buf, int size) yaz_log (LOG_LOG, "SSL_write. want_write"); return 1; } + h->cerrno = CSERRORSSL; return -1; } state->written += res; @@ -1124,3 +1221,26 @@ char *tcpip_addrstr(COMSTACK h) #endif return buf; } + +int static tcpip_set_blocking(COMSTACK p, int blocking) +{ + unsigned long flag; + + if (p->blocking == blocking) + return 1; +#ifdef WIN32 + flag = 1; + if (ioctlsocket(p->iofile, FIONBIO, &flag) < 0) + return 0; +#else + flag = fcntl(p->iofile, F_GETFL, 0); + if(!blocking) + flag = flag & ~O_NONBLOCK; + else + flag = flag | O_NONBLOCK; + if (fcntl(p->iofile, F_SETFL, flag) < 0) + return 0; +#endif + p->blocking = blocking; + return 1; +}