/*
- * Copyright (c) 1995-2001, Index Data
+ * Copyright (c) 1995-2002, Index Data
* See the file LICENSE for details.
*
- * $Id: tcpip.c,v 1.44 2001-11-06 17:01:25 adam Exp $
+ * $Id: tcpip.c,v 1.50 2002-09-25 12:37:07 adam Exp $
*/
#include <stdio.h>
#endif
#include <errno.h>
#include <fcntl.h>
+#include <signal.h>
#if HAVE_OPENSSL_SSL_H
#include <openssl/ssl.h>
#include <openssl/err.h>
#define TRC(X)
#endif
+#ifndef YAZ_SOCKLEN_T
+#define YAZ_SOCKLEN_T int
+#endif
+
/* this state is used for both SSL and straight TCP/IP */
typedef struct tcpip_state
{
#ifdef WIN32
if (!(p->blocking = blocking) && ioctlsocket(s, FIONBIO, &tru) < 0)
+ return 0;
#else
- if (!(p->blocking = blocking) && fcntl(s, F_SETFL, O_NONBLOCK) < 0)
+ if (!(p->blocking = blocking))
+ {
+ if (fcntl(s, F_SETFL, O_NONBLOCK) < 0)
+ return 0;
+#ifndef MSG_NOSIGNAL
+ signal (SIGPIPE, SIG_IGN);
+#endif
+ }
#endif
- return 0;
p->io_pending = 0;
p->iofile = s;
{
struct sockaddr_in *add = (struct sockaddr_in *)address;
#if HAVE_OPENSSL_SSL_H
- tcpip_state *sp = (tcpip_state *)h->cprivate;
+ tcpip_state *sp = (tcpip_state *)h->cprivate;
#endif
int r;
TRC(fprintf(stderr, "tcpip_connect\n"));
h->io_pending = 0;
- if (h->state == CS_ST_UNBND)
+ if (h->state != CS_ST_UNBND)
+ {
+ h->cerrno = CSOUTSTATE;
+ return -1;
+ }
+ r = connect(h->iofile, (struct sockaddr *) add, sizeof(*add));
+ if (r < 0)
{
- r = connect(h->iofile, (struct sockaddr *) add, sizeof(*add));
- if (r < 0)
- {
#ifdef WIN32
- if (WSAGetLastError() == WSAEWOULDBLOCK)
- {
- h->event = CS_CONNECT;
- h->state = CS_ST_CONNECTING;
- h->io_pending = CS_WANT_WRITE;
- return 1;
- }
+ if (WSAGetLastError() == WSAEWOULDBLOCK)
+ {
+ h->event = CS_CONNECT;
+ h->state = CS_ST_CONNECTING;
+ h->io_pending = CS_WANT_WRITE;
+ return 1;
+ }
#else
- if (errno == EINPROGRESS)
- {
- h->event = CS_CONNECT;
- h->state = CS_ST_CONNECTING;
- h->io_pending = CS_WANT_WRITE|CS_WANT_READ;
- return 1;
- }
+ if (yaz_errno() == EINPROGRESS)
+ {
+ 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->event = CS_CONNECT;
- h->state = CS_ST_CONNECTING;
+ h->cerrno = CSYSERR;
+ return -1;
}
+ h->event = CS_CONNECT;
+ h->state = CS_ST_CONNECTING;
+
+ return tcpip_rcvconnect (h);
+}
+
+/*
+ * nop
+ */
+int tcpip_rcvconnect(COMSTACK h)
+{
+ tcpip_state *sp = (tcpip_state *)h->cprivate;
+ TRC(fprintf(stderr, "tcpip_rcvconnect\n"));
+
+ if (h->state == CS_ST_DATAXFER)
+ return 0;
if (h->state != CS_ST_CONNECTING)
{
h->cerrno = CSOUTSTATE;
int err = SSL_get_error(sp->ssl, res);
if (err == SSL_ERROR_WANT_READ)
{
- yaz_log (LOG_LOG, "SSL_connect. want_read");
h->io_pending = CS_WANT_READ;
return 1;
}
if (err == SSL_ERROR_WANT_WRITE)
{
- yaz_log (LOG_LOG, "SSL_connect. want_write");
h->io_pending = CS_WANT_WRITE;
return 1;
}
return 0;
}
-/*
- * nop
- */
-int tcpip_rcvconnect(COMSTACK cs)
-{
- TRC(fprintf(stderr, "tcpip_rcvconnect\n"));
-
- 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"
#define KEYF "ztest.pem"
void *cd)
{
struct sockaddr_in addr;
-#ifdef __cplusplus
- socklen_t len = sizeof(addr);
-#else
- int len = sizeof(addr);
-#endif
+ YAZ_SOCKLEN_T len = sizeof(addr);
TRC(fprintf(stderr, "tcpip_listen pid=%d\n", getpid()));
if (h->state != CS_ST_IDLE)
#ifdef WIN32
WSAGetLastError() == WSAEWOULDBLOCK
#else
- errno == EWOULDBLOCK
+ yaz_errno() == EWOULDBLOCK
#ifdef EAGAIN
#if EAGAIN != EWOULDBLOCK
- || errno == EAGAIN
+ || yaz_errno() == EAGAIN
#endif
#endif
#endif
if (err == SSL_ERROR_WANT_READ)
{
h->io_pending = CS_WANT_READ;
- yaz_log (LOG_LOG, "SSL_accept. want_read");
return h;
}
if (err == SSL_ERROR_WANT_WRITE)
{
h->io_pending = CS_WANT_WRITE;
- yaz_log (LOG_LOG, "SSL_accept. want_write");
return h;
}
cs_close (h);
else
return -1;
#else
- if (errno == EWOULDBLOCK
+ if (yaz_errno() == EWOULDBLOCK
#ifdef EAGAIN
#if EAGAIN != EWOULDBLOCK
- || errno == EAGAIN
+ || yaz_errno() == EAGAIN
+#endif
#endif
+ || yaz_errno() == EINPROGRESS
+#ifdef __sun__
+ || yaz_errno() == ENOENT /* Sun's sometimes set errno to this */
#endif
- || errno == EINPROGRESS
)
{
h->io_pending = CS_WANT_READ;
break;
}
- else if (errno == 0)
+ else if (yaz_errno() == 0)
continue;
else
return -1;
if (ssl_err == SSL_ERROR_WANT_READ)
{
h->io_pending = CS_WANT_READ;
- yaz_log (LOG_LOG, "SSL_read. want_read");
break;
}
if (ssl_err == SSL_ERROR_WANT_WRITE)
{
h->io_pending = CS_WANT_WRITE;
- yaz_log (LOG_LOG, "SSL_read. want_write");
break;
}
if (res == 0)
#ifdef WIN32
WSAGetLastError() == WSAEWOULDBLOCK
#else
- errno == EWOULDBLOCK
+ yaz_errno() == EWOULDBLOCK
#ifdef EAGAIN
#if EAGAIN != EWOULDBLOCK
- || errno == EAGAIN
+ || yaz_errno() == EAGAIN
#endif
#endif
#endif
if (ssl_err == SSL_ERROR_WANT_READ)
{
h->io_pending = CS_WANT_READ;
- yaz_log (LOG_LOG, "SSL_write. want_read");
return 1;
}
if (ssl_err == SSL_ERROR_WANT_WRITE)
{
h->io_pending = CS_WANT_WRITE;
- yaz_log (LOG_LOG, "SSL_write. want_write");
return 1;
}
h->cerrno = CSERRORSSL;
struct sockaddr_in addr;
tcpip_state *sp = (struct tcpip_state *)h->cprivate;
char *r, *buf = sp->buf;
- size_t len;
+ YAZ_SOCKLEN_T len;
struct hostent *host;
len = sizeof(addr);