From b335dcd534287a207ef75b35e486df21293feddb Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Wed, 30 Aug 2006 18:58:58 +0000 Subject: [PATCH] TCP/IP COMSTACK uses getaddrinfo as resolver on systems that have it - instead of gethostbyname_r which is not portable. --- configure.ac | 4 +- include/yaz/tcpip.h | 3 +- src/tcpip.c | 137 +++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 103 insertions(+), 41 deletions(-) diff --git a/configure.ac b/configure.ac index 53257da..9055ac2 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ dnl YAZ Toolkit, Index Data 1994-2006 dnl See the file LICENSE for details. -dnl $Id: configure.ac,v 1.33 2006-08-30 12:04:42 adam Exp $ +dnl $Id: configure.ac,v 1.34 2006-08-30 18:58:58 adam Exp $ AC_PREREQ(2.59) AC_INIT([yaz],[2.1.27],[adam@indexdata.dk]) AC_CONFIG_SRCDIR(configure.ac) @@ -164,7 +164,7 @@ if test "$with_iconv" != "no"; then ]) fi dnl ------ various functions -AC_CHECK_FUNCS(gethostbyname_r vsnprintf gettimeofday poll strerror_r localtime_r usleep fopen64) +AC_CHECK_FUNCS(getaddrinfo vsnprintf gettimeofday poll strerror_r localtime_r usleep fopen64) case $host in *-*-darwin*) trypoll="no"; diff --git a/include/yaz/tcpip.h b/include/yaz/tcpip.h index 16aaf99..b9afb09 100644 --- a/include/yaz/tcpip.h +++ b/include/yaz/tcpip.h @@ -23,7 +23,7 @@ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. * - * $Id: tcpip.h,v 1.7 2005-06-25 15:46:03 adam Exp $ + * $Id: tcpip.h,v 1.8 2006-08-30 18:58:58 adam Exp $ */ /** * \file tcpip.h @@ -39,7 +39,6 @@ YAZ_BEGIN_CDECL YAZ_EXPORT int completeWAIS(const unsigned char *buf, int len); -YAZ_EXPORT struct sockaddr_in *tcpip_strtoaddr(const char *str); YAZ_EXPORT COMSTACK tcpip_type(int s, int blocking, int protocol, void *vp); YAZ_EXPORT COMSTACK ssl_type(int s, int blocking, int protocol, void *vp); diff --git a/src/tcpip.c b/src/tcpip.c index 6d69d2f..66dbd09 100644 --- a/src/tcpip.c +++ b/src/tcpip.c @@ -1,8 +1,8 @@ /* - * Copyright (C) 1995-2005, Index Data ApS + * Copyright (C) 1995-2006, Index Data ApS * See the file LICENSE for details. * - * $Id: tcpip.c,v 1.22 2006-08-30 12:55:12 adam Exp $ + * $Id: tcpip.c,v 1.23 2006-08-30 18:58:59 adam Exp $ */ /** * \file tcpip.c @@ -94,7 +94,11 @@ 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. */ +#if HAVE_GETADDRINFO + struct addrinfo *res; +#else struct sockaddr_in addr; /* returned by cs_straddr */ +#endif char buf[128]; /* returned by cs_addrstr */ #if HAVE_OPENSSL_SSL_H SSL_CTX *ctx; /* current CTX. */ @@ -201,6 +205,9 @@ COMSTACK tcpip_type(int s, int blocking, int protocol, void *vp) strcpy(sp->cert_fname, "yaz.pem"); #endif +#if HAVE_GETADDRINFO + sp->res = 0; +#endif sp->altbuf = 0; sp->altsize = sp->altlen = 0; sp->towrite = sp->written = -1; @@ -237,15 +244,53 @@ COMSTACK ssl_type(int s, int blocking, int protocol, void *vp) } #endif +#if HAVE_GETADDRINFO +/* resolve using getaddrinfo */ +struct addrinfo *tcpip_getaddrinfo(const char *str, const char *port) +{ + struct addrinfo hints, *res; + int error; + char host[512], *p; + + hints.ai_flags = 0; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = 0; + hints.ai_addrlen = 0; + hints.ai_addr = NULL; + hints.ai_canonname = NULL; + hints.ai_next = NULL; + + strncpy(host, str, sizeof(host)-1); + host[sizeof(host)-1] = 0; + if ((p = strchr(host, '/'))) + *p = 0; + if ((p = strchr(host, ':'))) + { + *p = '\0'; + port = p+1; + } + + if (!strcmp("@", host)) + { + hints.ai_flags = AI_PASSIVE; + error = getaddrinfo(0, port, &hints, &res); + } + else + { + error = getaddrinfo(host, port, &hints, &res); + } + if (error) + return 0; + return res; +} + +#endif +/* gethostbyname .. old systems */ int tcpip_strtoaddr_ex(const char *str, struct sockaddr_in *add, int default_port) { struct hostent *hp; -#if HAVE_GETHOSTBYNAME_R - struct hostent h; - char hbuf[1024]; - int h_error; -#endif char *p, buf[512]; short int port = default_port; #ifdef WIN32 @@ -253,17 +298,10 @@ int tcpip_strtoaddr_ex(const char *str, struct sockaddr_in *add, #else in_addr_t tmpadd; #endif - -#ifndef INADDR_NONE -#define INADDR_NONE -1 -#endif - - if (!tcpip_init ()) - return 0; TRC(fprintf(stderr, "tcpip_strtoaddress: %s\n", str ? str : "NULL")); add->sin_family = AF_INET; - strncpy(buf, str, 511); - buf[511] = 0; + strncpy(buf, str, sizeof(buf)-1); + buf[sizeof(buf)-1] = 0; if ((p = strchr(buf, '/'))) *p = 0; if ((p = strchr(buf, ':'))) @@ -276,49 +314,51 @@ int tcpip_strtoaddr_ex(const char *str, struct sockaddr_in *add, { add->sin_addr.s_addr = INADDR_ANY; } - else if ((tmpadd = inet_addr(buf)) != INADDR_NONE) + else if ((tmpadd = inet_addr(buf)) != -1) { memcpy(&add->sin_addr.s_addr, &tmpadd, sizeof(struct in_addr)); } -#if HAVE_GETHOSTBYNAME_R - else if (gethostbyname_r(buf, &h, hbuf, sizeof(hbuf), &hp, &h_error) == 0) - { - memcpy(&add->sin_addr.s_addr, *hp->h_addr_list, - sizeof(struct in_addr)); - } -#else else if ((hp = gethostbyname(buf))) { memcpy(&add->sin_addr.s_addr, *hp->h_addr_list, sizeof(struct in_addr)); } -#endif else return 0; return 1; } + +#if HAVE_GETADDRINFO void *tcpip_straddr(COMSTACK h, const char *str) { tcpip_state *sp = (tcpip_state *)h->cprivate; - int port = 210; + const char *port = "210"; + if (h->protocol == PROTO_HTTP) + port = "80"; + if (!tcpip_init ()) + return 0; + if (sp->res) + freeaddrinfo(sp->res); + sp->res = tcpip_getaddrinfo(str, port); + return sp->res; +} +#else +void *tcpip_straddr(COMSTACK h, const char *str) +{ + tcpip_state *sp = (tcpip_state *)h->cprivate; + int port = 210; if (h->protocol == PROTO_HTTP) port = 80; + if (!tcpip_init ()) + return 0; if (!tcpip_strtoaddr_ex (str, &sp->addr, port)) return 0; return &sp->addr; } - -struct sockaddr_in *tcpip_strtoaddr(const char *str) -{ - static struct sockaddr_in add; - - if (!tcpip_strtoaddr_ex (str, &add, 210)) - return 0; - return &add; -} +#endif int tcpip_more(COMSTACK h) { @@ -335,7 +375,11 @@ int tcpip_more(COMSTACK h) */ int tcpip_connect(COMSTACK h, void *address) { - struct sockaddr_in *add = (struct sockaddr_in *)address; +#if HAVE_GETADDRINFO + struct addrinfo *ai = (struct addrinfo *) address; +#else + struct sockaddr_in *add = (struct sockaddr_in *) address; +#endif int r; #ifdef __sun__ int recbuflen; @@ -374,7 +418,12 @@ int tcpip_connect(COMSTACK h, void *address) TRC(fprintf( stderr, "New Size of TCP Receive Buffer = %d\n", recbuflen )); #endif + +#if HAVE_GETADDRINFO + r = connect(h->iofile, ai->ai_addr, ai->ai_addrlen); +#else r = connect(h->iofile, (struct sockaddr *) add, sizeof(*add)); +#endif if (r < 0) { #ifdef WIN32 @@ -492,7 +541,12 @@ static void tcpip_setsockopt (int fd) static int tcpip_bind(COMSTACK h, void *address, int mode) { + int r; +#if HAVE_GETADDRINFO + struct addrinfo *ai = (struct addrinfo *)address; +#else struct sockaddr *addr = (struct sockaddr *)address; +#endif #ifdef WIN32 BOOL one = 1; #else @@ -556,7 +610,12 @@ static int tcpip_bind(COMSTACK h, void *address, int mode) } #endif tcpip_setsockopt(h->iofile); - if (bind(h->iofile, addr, sizeof(struct sockaddr_in))) +#if HAVE_GETADDRINFO + r = bind(h->iofile, ai->ai_addr, ai->ai_addrlen); +#else + r = bind(h->iofile, addr, sizeof(struct sockaddr_in)); +#endif + if (r) { h->cerrno = CSYSERR; return -1; @@ -1105,6 +1164,10 @@ int tcpip_close(COMSTACK h) if (sp->ctx_alloc) SSL_CTX_free (sp->ctx_alloc); #endif +#if HAVE_GETADDRINFO + if (sp->res) + freeaddrinfo(sp->res); +#endif xfree(sp); xfree(h); return 0; -- 1.7.10.4