From: Adam Dickmeiss Date: Wed, 22 Oct 2014 13:34:33 +0000 (+0200) Subject: Extended comstack with outgoing IP YAZ-795 X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=commitdiff_plain;h=06485f9b118b91d56e88e412ba54ce43fae9d0b8 Extended comstack with outgoing IP YAZ-795 --- diff --git a/client/client.c b/client/client.c index 596b76a..d64884c 100644 --- a/client/client.c +++ b/client/client.c @@ -151,6 +151,7 @@ static Odr_int last_hit_count = 0; static int pretty_xml = 0; static Odr_int sru_maximumRecords = 0; static yaz_cookies_t yaz_cookies = 0; +static char *bind_host = 0; typedef enum { QueryType_Prefix, @@ -703,7 +704,7 @@ static int session_connect_base(const char *arg, const char **basep) strncpy(type_and_host, arg, sizeof(type_and_host)-1); type_and_host[sizeof(type_and_host)-1] = '\0'; - conn = cs_create_host_proxy(arg, 1, &add, yazProxy); + conn = cs_create_host2(arg, 1, &add, yazProxy, bind_host); if (!conn) { printf("Could not resolve address %s\n", arg); @@ -755,6 +756,15 @@ static int session_connect(void) return r; } +static int cmd_bind(const char *arg) +{ + xfree(bind_host); + bind_host = 0; + if (arg && *arg) + bind_host = xstrdup(arg); + return 0; +} + static int cmd_open(const char *arg) { int r; @@ -5051,6 +5061,7 @@ static struct { {"init", cmd_init, "", NULL,0,NULL}, {"sru", cmd_sru, " ", NULL,0,NULL}, {"url", cmd_url, "", NULL,0,NULL}, + {"bind", cmd_bind, "", NULL,0,NULL}, {"exit", cmd_quit, "",NULL,0,NULL}, {0,0,0,0,0,0} }; diff --git a/include/yaz/comstack.h b/include/yaz/comstack.h index 2b4b4d5..e3dada7 100644 --- a/include/yaz/comstack.h +++ b/include/yaz/comstack.h @@ -123,6 +123,10 @@ YAZ_EXPORT COMSTACK cs_create_host(const char *type_and_host, YAZ_EXPORT COMSTACK cs_create_host_proxy(const char *vhost, int blocking, void **vp, const char *proxy_host); +YAZ_EXPORT COMSTACK cs_create_host2(const char *vhost, + int blocking, void **vp, + const char *proxy_host, + const char *bind_host); YAZ_EXPORT void cs_get_host_args(const char *type_and_host, const char **args); YAZ_EXPORT int cs_complete_auto_head(const char *buf, int len); YAZ_EXPORT int cs_complete_auto(const char *buf, int len); diff --git a/include/yaz/tcpip.h b/include/yaz/tcpip.h index 812ee2c..d744009 100644 --- a/include/yaz/tcpip.h +++ b/include/yaz/tcpip.h @@ -41,6 +41,9 @@ YAZ_EXPORT COMSTACK tcpip_type(int s, int flags, int protocol, void *vp); YAZ_EXPORT COMSTACK ssl_type(int s, int flags, int protocol, void *vp); YAZ_EXPORT COMSTACK yaz_tcpip_create(int s, int flags, int protocol, const char *connect_host); +YAZ_EXPORT COMSTACK yaz_tcpip_create2(int s, int flags, int protocol, + const char *connect_host, + const char *bind_host); YAZ_END_CDECL diff --git a/src/comstack.c b/src/comstack.c index d364f05..ee64fc8 100644 --- a/src/comstack.c +++ b/src/comstack.c @@ -175,8 +175,8 @@ COMSTACK cs_create_host(const char *vhost, int blocking, void **vp) return cs_create_host_proxy(vhost, blocking, vp, 0); } -COMSTACK cs_create_host_proxy(const char *vhost, int blocking, void **vp, - const char *proxy_host) +COMSTACK cs_create_host2(const char *vhost, int blocking, void **vp, + const char *proxy_host, const char *bind_host) { enum oid_proto proto = PROTO_Z3950; const char *host = 0; @@ -198,7 +198,8 @@ COMSTACK cs_create_host_proxy(const char *vhost, int blocking, void **vp, if (t == tcpip_type) { - cs = yaz_tcpip_create(-1, blocking, proto, connect_host ? host : 0); + cs = yaz_tcpip_create2(-1, blocking, proto, connect_host ? host : 0, + bind_host); } else { @@ -216,6 +217,12 @@ COMSTACK cs_create_host_proxy(const char *vhost, int blocking, void **vp, return cs; } +COMSTACK cs_create_host_proxy(const char *vhost, int blocking, void **vp, + const char *proxy_host) +{ + return cs_create_host2(vhost, blocking, vp, proxy_host, 0); +} + int cs_look (COMSTACK cs) { return cs->event; diff --git a/src/tcpip.c b/src/tcpip.c index ab9f6c4..6d00525 100644 --- a/src/tcpip.c +++ b/src/tcpip.c @@ -90,6 +90,12 @@ static int ssl_get(COMSTACK h, char **buf, int *bufsize); static int ssl_put(COMSTACK h, char *buf, int size); #endif + +#if HAVE_GETADDRINFO +struct addrinfo *tcpip_getaddrinfo(const char *str, const char *port, + int *ipv6_only); +#endif + static COMSTACK tcpip_accept(COMSTACK h); static const char *tcpip_addrstr(COMSTACK h); static void *tcpip_straddr(COMSTACK h, const char *str); @@ -125,6 +131,7 @@ typedef struct tcpip_state struct addrinfo *ai; struct addrinfo *ai_connect; int ipv6_only; + char *bind_host; #if RESOLVER_THREAD int pipefd[2]; char *hoststr; @@ -179,6 +186,7 @@ static struct tcpip_state *tcpip_state_create(void) #if HAVE_GETADDRINFO sp->ai = 0; sp->ai_connect = 0; + sp->bind_host = 0; #if RESOLVER_THREAD sp->hoststr = 0; sp->pipefd[0] = sp->pipefd[1] = -1; @@ -243,12 +251,18 @@ COMSTACK tcpip_type(int s, int flags, int protocol, void *vp) return p; } -COMSTACK yaz_tcpip_create(int s, int flags, int protocol, - const char *connect_host) +COMSTACK yaz_tcpip_create2(int s, int flags, int protocol, + const char *connect_host, + const char *bind_host) { COMSTACK p = tcpip_type(s, flags, protocol, 0); if (!p) return 0; + if (bind_host) + { + tcpip_state *sp = (tcpip_state *) p->cprivate; + sp->bind_host = xstrdup(bind_host); + } if (connect_host) { tcpip_state *sp = (tcpip_state *) p->cprivate; @@ -263,6 +277,12 @@ COMSTACK yaz_tcpip_create(int s, int flags, int protocol, return p; } +COMSTACK yaz_tcpip_create(int s, int flags, int protocol, + const char *connect_host) +{ + return yaz_tcpip_create2(s, flags, protocol, connect_host, 0); +} + #if HAVE_GNUTLS_H static void tcpip_create_cred(COMSTACK cs) { @@ -456,6 +476,27 @@ static struct addrinfo *create_net_socket(COMSTACK h) return 0; if (!tcpip_set_blocking(h, h->flags)) return 0; + if (sp->bind_host) + { + int r; + int ipv6_only = 0; + struct addrinfo *ai = tcpip_getaddrinfo(sp->bind_host, "210", + &ipv6_only); + if (!ai) + return 0; + r = bind(h->iofile, ai->ai_addr, ai->ai_addrlen); + if (r) + { + int xerrno = errno; + if (xerrno == EINVAL) + fprintf(stderr, "bind returned EINVAL\n"); + fprintf(stderr, "bind failed errno=%d %s\n", xerrno, + strerror(xerrno)); + freeaddrinfo(ai); + return 0; + } + freeaddrinfo(ai); + } return ai; } @@ -1325,6 +1366,7 @@ void tcpip_close(COMSTACK h) TRC(fprintf(stderr, "tcpip_close: h=%p pid=%d\n", h, getpid())); #if HAVE_GETADDRINFO + xfree(sp->bind_host); #if RESOLVER_THREAD if (sp->pipefd[0] != -1) {