/* This file is part of the YAZ toolkit.
- * Copyright (C) 1995-2009 Index Data
+ * Copyright (C) 1995-2010 Index Data
* See the file LICENSE for details.
*/
/**
#include <yaz/tcpip.h>
#include <yaz/errno.h>
-static int tcpip_close(COMSTACK h);
+static void 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);
#endif
static COMSTACK tcpip_accept(COMSTACK h);
-static char *tcpip_addrstr(COMSTACK h);
+static const char *tcpip_addrstr(COMSTACK h);
static void *tcpip_straddr(COMSTACK h, const char *str);
#if 0
p->state = s < 0 ? CS_ST_UNBND : CS_ST_IDLE; /* state of line */
p->event = CS_NONE;
p->cerrno = 0;
- p->stackerr = 0;
p->user = 0;
#if HAVE_GNUTLS_H
{
tcpip_state *sp = (tcpip_state *)h->cprivate;
const char *port = "210";
+ struct addrinfo *ai = 0;
if (h->protocol == PROTO_HTTP)
port = "80";
if (!tcpip_init())
if (sp->ai && h->state == CS_ST_UNBND)
{
int s = -1;
- struct addrinfo *ai = sp->ai;
- for (; ai; ai = ai->ai_next)
+ /* try to make IPV6 socket first */
+ for (ai = sp->ai; ai; ai = ai->ai_next)
{
- s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
- if (s != -1)
+ if (ai->ai_family == AF_INET6)
{
- sp->ai = ai;
- break;
+ s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+ if (s != -1)
+ break;
+ }
+ }
+ if (s == -1)
+ {
+ /* no IPV6 could be made.. Try them all */
+ for (ai = sp->ai; 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;
+ assert(ai);
h->iofile = s;
if (!tcpip_set_blocking(h, h->flags))
return 0;
}
- return sp->ai;
+ return ai;
}
#else
void *tcpip_straddr(COMSTACK h, const char *str)
int tcpip_connect(COMSTACK h, void *address)
{
#if HAVE_GETADDRINFO
+ struct addrinfo *ai = (struct addrinfo *) address;
tcpip_state *sp = (tcpip_state *)h->cprivate;
#else
struct sockaddr_in *add = (struct sockaddr_in *) address;
#endif
int r;
-#ifdef __sun__
- int recbuflen;
- YAZ_SOCKLEN_T rbufsize = sizeof(recbuflen);
-#endif
TRC(fprintf(stderr, "tcpip_connect\n"));
h->io_pending = 0;
if (h->state != CS_ST_UNBND)
return -1;
}
#if HAVE_GETADDRINFO
- if (sp->ai != (struct addrinfo *) address)
- {
- h->cerrno = CSOUTSTATE;
- return -1;
- }
-#endif
-#ifdef __sun__
- /* On Suns, you must set a bigger Receive Buffer BEFORE a call to connect
- * This gives the connect a chance to negotiate with the other side
- * (see 'man tcp')
- */
- if (getsockopt(h->iofile, SOL_SOCKET, SO_RCVBUF, (void *)&recbuflen, &rbufsize ) < 0 )
- {
- h->cerrno = CSYSERR;
- return -1;
- }
- TRC(fprintf( stderr, "Current Size of TCP Receive Buffer= %d\n",
- recbuflen ));
- recbuflen *= 10; /* lets be optimistic */
- if (setsockopt(h->iofile, SOL_SOCKET, SO_RCVBUF, (void *)&recbuflen, rbufsize ) < 0 )
- {
- h->cerrno = CSYSERR;
- return -1;
- }
- if (getsockopt(h->iofile, SOL_SOCKET, SO_RCVBUF, (void *)&recbuflen, &rbufsize ) )
- {
- h->cerrno = CSYSERR;
- return -1;
- }
- TRC(fprintf(stderr, "New Size of TCP Receive Buffer = %d\n",
- recbuflen ));
-#endif
-
-#if HAVE_GETADDRINFO
- r = connect(h->iofile, sp->ai->ai_addr, sp->ai->ai_addrlen);
+ r = connect(h->iofile, ai->ai_addr, ai->ai_addrlen);
freeaddrinfo(sp->ai);
sp->ai = 0;
#else
gnutls_credentials_set (sp->session, GNUTLS_CRD_CERTIFICATE,
sp->cred_ptr->xcred);
- gnutls_transport_set_ptr(sp->session, (gnutls_transport_ptr_t) h->iofile);
-
+ /* cast to intermediate size_t to avoid GCC warning. */
+ gnutls_transport_set_ptr(sp->session,
+ (gnutls_transport_ptr_t)
+ (size_t) h->iofile);
res = gnutls_handshake(sp->session);
if (res < 0)
{
#define CERTF "ztest.pem"
#define KEYF "ztest.pem"
-static void tcpip_setsockopt(int fd)
-{
-#if 0
- int len = 4096;
- int set = 1;
-
- if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&set, sizeof(int)))
- {
- yaz_log(LOG_WARN|LOG_ERRNO, "setsockopt TCP_NODELAY");
- }
- if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int)))
- {
- yaz_log(LOG_WARN|LOG_ERRNO, "setsockopt SNDBUF");
- }
- if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char*)&len, sizeof(int)))
- {
- yaz_log(LOG_WARN|LOG_ERRNO, "setsockopt RCVBUF");
- }
-#endif
-}
-
static int tcpip_bind(COMSTACK h, void *address, int mode)
{
int r;
tcpip_state *sp = (tcpip_state *)h->cprivate;
-#if HAVE_GETADDRINFO
+#if HAVE_GETADDRINFO
+ struct addrinfo *ai = (struct addrinfo *) address;
#else
struct sockaddr *addr = (struct sockaddr *)address;
#endif
int one = 1;
#endif
-#if HAVE_GETADDRINFO
- if (sp->ai != (struct addrinfo *) address)
- {
- h->cerrno = CSOUTSTATE;
- return -1;
- }
-#endif
-
#if HAVE_GNUTLS_H
if (h->type == ssl_type && !sp->session)
{
return -1;
}
#endif
- tcpip_setsockopt(h->iofile);
#if HAVE_GETADDRINFO
- r = bind(h->iofile, sp->ai->ai_addr, sp->ai->ai_addrlen);
+ r = bind(h->iofile, ai->ai_addr, ai->ai_addrlen);
freeaddrinfo(sp->ai);
sp->ai = 0;
#else
int (*check_ip)(void *cd, const char *a, int len, int t),
void *cd)
{
+#ifdef WIN32
+ /* we don't get peer address on Windows (via accept) */
+#else
struct sockaddr_in addr;
YAZ_SOCKLEN_T len = sizeof(addr);
+#endif
TRC(fprintf(stderr, "tcpip_listen pid=%d\n", getpid()));
if (h->state != CS_ST_IDLE)
}
return -1;
}
+#ifdef WIN32
+ if (addrlen)
+ *addrlen = 0;
+#else
if (addrlen && (size_t) (*addrlen) >= sizeof(struct sockaddr_in))
memcpy(raddr, &addr, *addrlen = sizeof(struct sockaddr_in));
else if (addrlen)
h->newfd = -1;
return -1;
}
+#endif
h->state = CS_ST_INCON;
- tcpip_setsockopt(h->newfd);
return 0;
}
xfree(state);
return 0;
}
+ /* cast to intermediate size_t to avoid GCC warning. */
gnutls_transport_set_ptr(state->session,
- (gnutls_transport_ptr_t) cnew->iofile);
+ (gnutls_transport_ptr_t)
+ (size_t) cnew->iofile);
}
#elif HAVE_OPENSSL_SSL_H
state->ctx = st->ctx;
}
#endif
-int tcpip_close(COMSTACK h)
+void tcpip_close(COMSTACK h)
{
tcpip_state *sp = (struct tcpip_state *)h->cprivate;
xfree(sp->connect_response_buf);
xfree(sp);
xfree(h);
- return 0;
}
-char *tcpip_addrstr(COMSTACK h)
+const char *tcpip_addrstr(COMSTACK h)
{
tcpip_state *sp = (struct tcpip_state *)h->cprivate;
char *r = 0, *buf = sp->buf;