size can be set with cs_ste_max_recv_bytes. By default, maximum is
5000000 (approx 5 MB). If max size is received error comstack error
CSBUFSIZE is returned. The generic frontend server checks for this error
and sends a close + logs if this condition occur.
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*
- * $Id: comstack.h,v 1.21 2005-06-25 15:46:01 adam Exp $
+ * $Id: comstack.h,v 1.22 2006-08-24 13:25:44 adam Exp $
int iofile; /* UNIX file descriptor for iochannel */
int timeout; /* how long to wait for trailing blocks (ignored for now) */
void *cprivate;/* state info for lower stack */
int iofile; /* UNIX file descriptor for iochannel */
int timeout; /* how long to wait for trailing blocks (ignored for now) */
void *cprivate;/* state info for lower stack */
- int more; /* connection has extra data in buffer */
+ int max_recv_bytes; /* max size of incoming package */
int state; /* current state */
#define CS_ST_UNBND 0
#define CS_ST_IDLE 1
int state; /* current state */
#define CS_ST_UNBND 0
#define CS_ST_IDLE 1
YAZ_EXPORT int cs_set_ssl_ctx(COMSTACK cs, void *ctx);
YAZ_EXPORT int cs_set_ssl_certificate_file(COMSTACK cs, const char *fname);
YAZ_EXPORT int cs_get_peer_certificate_x509(COMSTACK cs, char **buf, int *len);
YAZ_EXPORT int cs_set_ssl_ctx(COMSTACK cs, void *ctx);
YAZ_EXPORT int cs_set_ssl_certificate_file(COMSTACK cs, const char *fname);
YAZ_EXPORT int cs_get_peer_certificate_x509(COMSTACK cs, char **buf, int *len);
+YAZ_EXPORT void cs_set_max_recv_bytes(COMSTACK cs, int max_recv_bytes);
#define CSWRONGBUF 4
#define CSDENY 5
#define CSERRORSSL 6
#define CSWRONGBUF 4
#define CSDENY 5
#define CSERRORSSL 6
-#define CSLASTERROR CSERRORSSL /* must be the value of last CS error */
+#define CSBUFSIZE 7
+#define CSLASTERROR CSBUFSIZE /* must be the value of last CS error */
/* backwards compatibility */
#define CS_SR PROTO_SR
/* backwards compatibility */
#define CS_SR PROTO_SR
- * Copyright (C) 1995-2005, Index Data ApS
+ * Copyright (C) 1995-2006, Index Data ApS
* See the file LICENSE for details.
*
* See the file LICENSE for details.
*
- * $Id: comstack.c,v 1.15 2005-06-25 15:46:03 adam Exp $
+ * $Id: comstack.c,v 1.16 2006-08-24 13:25:45 adam Exp $
#include <ctype.h>
#include <errno.h>
#include <ctype.h>
#include <errno.h>
#include <yaz/comstack.h>
#include <yaz/tcpip.h>
#include <yaz/unix.h>
#include <yaz/comstack.h>
#include <yaz/tcpip.h>
#include <yaz/unix.h>
"No data (operation would block)",
"New data while half of old buffer is on the line (flow control)",
"Permission denied",
"No data (operation would block)",
"New data while half of old buffer is on the line (flow control)",
"Permission denied",
+ "SSL error",
+ "Too large incoming buffer"
};
const char *cs_errmsg(int n)
};
const char *cs_errmsg(int n)
{
/* deal with HTTP request/response */
int i = 2, content_len = 0, chunked = 0;
{
/* deal with HTTP request/response */
int i = 2, content_len = 0, chunked = 0;
/* if dealing with HTTP responses - then default
content length is unlimited (socket close) */
if (!memcmp(buf, "HTTP/", 5))
/* if dealing with HTTP responses - then default
content length is unlimited (socket close) */
if (!memcmp(buf, "HTTP/", 5))
}
return completeBER(buf, len);
}
}
return completeBER(buf, len);
}
+
+void cs_set_max_recv_bytes(COMSTACK cs, int max_recv_bytes)
+{
+ cs->max_recv_bytes = max_recv_bytes;
+}
+
/*
* Local variables:
* c-basic-offset: 4
/*
* Local variables:
* c-basic-offset: 4
* Copyright (C) 1995-2005, Index Data ApS
* See the file LICENSE for details.
*
* Copyright (C) 1995-2005, Index Data ApS
* See the file LICENSE for details.
*
- * $Id: seshigh.c,v 1.95 2006-07-31 12:15:02 adam Exp $
+ * $Id: seshigh.c,v 1.96 2006-08-24 13:25:45 adam Exp $
}
assoc->cs_get_mask = EVENT_INPUT;
if ((res = cs_get(conn, &assoc->input_buffer,
}
assoc->cs_get_mask = EVENT_INPUT;
if ((res = cs_get(conn, &assoc->input_buffer,
- &assoc->input_buffer_len)) <= 0)
+ &assoc->input_buffer_len)) == 0)
{
yaz_log(log_sessiondetail, "Connection closed by client");
cs_close(conn);
{
yaz_log(log_sessiondetail, "Connection closed by client");
cs_close(conn);
iochan_destroy(h);
return;
}
iochan_destroy(h);
return;
}
+ else if (res < 0)
+ {
+ yaz_log(log_session, "Connection error: %s",
+ cs_errmsg(cs_errno(conn)));
+ req = request_get(&assoc->incoming); /* get a new request */
+ do_close_req(assoc, Z_Close_protocolError,
+ "Incoming package too large", req);
+ return;
+ }
else if (res == 1) /* incomplete read - wait for more */
{
if (conn->io_pending & CS_WANT_WRITE)
else if (res == 1) /* incomplete read - wait for more */
{
if (conn->io_pending & CS_WANT_WRITE)
yaz_log(YLOG_WARN, "PDU dump:");
odr_dumpBER(yaz_log_file(), assoc->input_buffer, res);
request_release(req);
yaz_log(YLOG_WARN, "PDU dump:");
odr_dumpBER(yaz_log_file(), assoc->input_buffer, res);
request_release(req);
- do_close(assoc, Z_Close_protocolError,"Malformed package");
+ do_close(assoc, Z_Close_protocolError, "Malformed package");
assoc->init->implementation_name,
odr_prepend(assoc->encode, "GFS", resp->implementationName));
assoc->init->implementation_name,
odr_prepend(assoc->encode, "GFS", resp->implementationName));
- version = odr_strdup(assoc->encode, "$Revision: 1.95 $");
+ version = odr_strdup(assoc->encode, "$Revision: 1.96 $");
if (strlen(version) > 10) /* check for unexpanded CVS strings */
version[strlen(version)-2] = '\0';
resp->implementationVersion = odr_prepend(assoc->encode,
if (strlen(version) > 10) /* check for unexpanded CVS strings */
version[strlen(version)-2] = '\0';
resp->implementationVersion = odr_prepend(assoc->encode,
* Copyright (C) 1995-2005, Index Data ApS
* See the file LICENSE for details.
*
* Copyright (C) 1995-2005, Index Data ApS
* See the file LICENSE for details.
*
- * $Id: tcpip.c,v 1.18 2006-06-09 12:40:53 adam Exp $
+ * $Id: tcpip.c,v 1.19 2006-08-24 13:25:45 adam Exp $
p->f_addrstr = tcpip_addrstr;
p->f_straddr = tcpip_straddr;
p->f_set_blocking = tcpip_set_blocking;
p->f_addrstr = tcpip_addrstr;
p->f_straddr = tcpip_straddr;
p->f_set_blocking = tcpip_set_blocking;
+ p->max_recv_bytes = 5000000;
p->state = new_socket ? CS_ST_UNBND : CS_ST_IDLE; /* state of line */
p->event = CS_NONE;
p->state = new_socket ? CS_ST_UNBND : CS_ST_IDLE; /* state of line */
p->event = CS_NONE;
if (!*bufsize)
{
if (!(*buf = (char *)xmalloc(*bufsize = CS_TCPIP_BUFCHUNK)))
if (!*bufsize)
{
if (!(*buf = (char *)xmalloc(*bufsize = CS_TCPIP_BUFCHUNK)))
+ {
+ h->cerrno = CSYSERR;
}
else if (*bufsize - hasread < CS_TCPIP_BUFCHUNK)
if (!(*buf =(char *)xrealloc(*buf, *bufsize *= 2)))
}
else if (*bufsize - hasread < CS_TCPIP_BUFCHUNK)
if (!(*buf =(char *)xrealloc(*buf, *bufsize *= 2)))
+ {
+ h->cerrno = CSYSERR;
#ifdef __sun__
yaz_set_errno( 0 );
/* unfortunatly, sun sometimes forgets to set errno in recv
#ifdef __sun__
yaz_set_errno( 0 );
/* unfortunatly, sun sometimes forgets to set errno in recv
else if (!res)
return hasread;
hasread += res;
else if (!res)
return hasread;
hasread += res;
+ if (hasread > h->max_recv_bytes)
+ {
+ h->cerrno = CSBUFSIZE;
+ return -1;
+ }
}
TRC (fprintf (stderr, " Out of read loop with hasread=%d, berlen=%d\n",
hasread, berlen));
}
TRC (fprintf (stderr, " Out of read loop with hasread=%d, berlen=%d\n",
hasread, berlen));