X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=src%2Ftcpip.c;h=8ffdfe80012246a4cab7c5fea1d073d93a0af39e;hp=9a7458c5aa1b6099aa5da713ebb425cf3d7e4567;hb=4f8ea8cfaf2f3d95e4efcf9494526c2b4be43eb8;hpb=8fbe86c3ff80837cb658fd6f237675ad6c17556d diff --git a/src/tcpip.c b/src/tcpip.c index 9a7458c..8ffdfe8 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.25 2006-09-01 10:39:09 adam Exp $ + * $Id: tcpip.c,v 1.34 2007-01-19 10:28:42 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 @@ -137,7 +144,7 @@ static int tcpip_init (void) * This function is always called through the cs_create() macro. * s >= 0: socket has already been established for us. */ -COMSTACK tcpip_type(int s, int blocking, int protocol, void *vp) +COMSTACK tcpip_type(int s, int flags, int protocol, void *vp) { COMSTACK p; tcpip_state *sp; @@ -150,7 +157,7 @@ COMSTACK tcpip_type(int s, int blocking, int protocol, void *vp) xmalloc(sizeof(tcpip_state))))) return 0; - p->blocking = blocking; + p->flags = flags; p->io_pending = 0; p->iofile = s; @@ -202,12 +209,12 @@ COMSTACK tcpip_type(int s, int blocking, int protocol, void *vp) #if HAVE_OPENSSL_SSL_H -COMSTACK ssl_type(int s, int blocking, int protocol, void *vp) +COMSTACK ssl_type(int s, int flags, int protocol, void *vp) { tcpip_state *sp; COMSTACK p; - p = tcpip_type (s, blocking, protocol, 0); + p = tcpip_type (s, flags, protocol, 0); if (!p) return 0; p->f_get = ssl_get; @@ -243,7 +250,7 @@ struct addrinfo *tcpip_getaddrinfo(const char *str, const char *port) host[sizeof(host)-1] = 0; if ((p = strchr(host, '/'))) *p = 0; - if ((p = strchr(host, ':'))) + if ((p = strrchr(host, ':'))) { *p = '\0'; port = p+1; @@ -282,7 +289,7 @@ int tcpip_strtoaddr_ex(const char *str, struct sockaddr_in *add, buf[sizeof(buf)-1] = 0; if ((p = strchr(buf, '/'))) *p = 0; - if ((p = strchr(buf, ':'))) + if ((p = strrchr(buf, ':'))) { *p = 0; port = atoi(p + 1); @@ -322,14 +329,19 @@ 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; - if (!tcpip_set_blocking(h, h->blocking)) + if (!tcpip_set_blocking(h, h->flags)) return 0; } return sp->ai; @@ -354,7 +366,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; @@ -482,8 +494,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 +572,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 +586,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) @@ -744,7 +756,7 @@ COMSTACK tcpip_accept(COMSTACK h) } return 0; } - if (!tcpip_set_blocking(cnew, cnew->blocking)) + if (!tcpip_set_blocking(cnew, cnew->flags)) { h->cerrno = CSYSERR; if (h->newfd != -1) @@ -874,7 +886,7 @@ int tcpip_get(COMSTACK h, char **buf, int *bufsize) TRC(fprintf(stderr, " recv res=%d, hasread=%d\n", res, hasread)); if (res < 0) { - TRC(fprintf(stderr, " recv errno=%d, (%s)\n", yaz_errno(), + TRC(fprintf(stderr, " recv errno=%d, (%s)\n", yaz_errno(), strerror(yaz_errno()))); #ifdef WIN32 if (WSAGetLastError() == WSAEWOULDBLOCK) @@ -883,7 +895,10 @@ int tcpip_get(COMSTACK h, char **buf, int *bufsize) break; } else + { + h->cerrno = CSYSERR; return -1; + } #else if (yaz_errno() == EWOULDBLOCK #ifdef EAGAIN @@ -903,7 +918,10 @@ int tcpip_get(COMSTACK h, char **buf, int *bufsize) else if (yaz_errno() == 0) continue; else + { + h->cerrno = CSYSERR; return -1; + } #endif } else if (!res) @@ -927,10 +945,16 @@ int tcpip_get(COMSTACK h, char **buf, int *bufsize) if (!sp->altbuf) { if (!(sp->altbuf = (char *)xmalloc(sp->altsize = req))) + { + h->cerrno = CSYSERR; return -1; + } } else if (sp->altsize < req) if (!(sp->altbuf =(char *)xrealloc(sp->altbuf, sp->altsize = req))) + { + h->cerrno = CSYSERR; return -1; + } TRC(fprintf(stderr, " Moving %d bytes to altbuf(0x%x)\n", tomove, (unsigned) sp->altbuf)); memcpy(sp->altbuf, *buf + berlen, sp->altlen = tomove); @@ -1191,25 +1215,50 @@ int tcpip_close(COMSTACK h) char *tcpip_addrstr(COMSTACK h) { - struct sockaddr_in addr; tcpip_state *sp = (struct tcpip_state *)h->cprivate; char *r = 0, *buf = sp->buf; - YAZ_SOCKLEN_T len; + +#if HAVE_GETADDRINFO + char host[120]; + struct sockaddr_storage addr; + YAZ_SOCKLEN_T len = sizeof(addr); + + if (getpeername(h->iofile, (struct sockaddr *)&addr, &len) < 0) + { + h->cerrno = CSYSERR; + return 0; + } + if (getnameinfo((struct sockaddr *) &addr, len, host, sizeof(host)-1, + 0, 0, + (h->flags & CS_FLAGS_NUMERICHOST) ? NI_NUMERICHOST : 0)) + { + r = "unknown"; + } + else + r = host; + +#else + + struct sockaddr_in addr; + YAZ_SOCKLEN_T len = sizeof(addr); struct hostent *host; - len = sizeof(addr); if (getpeername(h->iofile, (struct sockaddr*) &addr, &len) < 0) { h->cerrno = CSYSERR; return 0; } - if (!(h->blocking&2)) { - if ((host = gethostbyaddr((char*)&addr.sin_addr, sizeof(addr.sin_addr), - AF_INET))) + if (!(h->flags & CS_FLAGS_NUMERICHOST)) + { + if ((host = gethostbyaddr((char*)&addr.sin_addr, + sizeof(addr.sin_addr), + AF_INET))) r = (char*) host->h_name; } if (!r) - r = inet_ntoa(addr.sin_addr); + r = inet_ntoa(addr.sin_addr); +#endif + if (h->protocol == PROTO_HTTP) sprintf(buf, "http:%s", r); else @@ -1226,17 +1275,17 @@ char *tcpip_addrstr(COMSTACK h) return buf; } -int static tcpip_set_blocking(COMSTACK p, int blocking) +int static tcpip_set_blocking(COMSTACK p, int flags) { unsigned long flag; #ifdef WIN32 - flag = 1; + flag = (flags & CS_FLAGS_BLOCKING) ? 0 : 1; if (ioctlsocket(p->iofile, FIONBIO, &flag) < 0) return 0; #else flag = fcntl(p->iofile, F_GETFL, 0); - if (blocking & 1) + if (flags & CS_FLAGS_BLOCKING) flag = flag & ~O_NONBLOCK; /* blocking */ else { @@ -1246,7 +1295,7 @@ int static tcpip_set_blocking(COMSTACK p, int blocking) if (fcntl(p->iofile, F_SETFL, flag) < 0) return 0; #endif - p->blocking = blocking; + p->flags = flags; return 1; }