summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorreyk <reyk@openbsd.org>2014-08-06 09:36:31 +0000
committerreyk <reyk@openbsd.org>2014-08-06 09:36:31 +0000
commit720c14e513bba2c96fd407d06b2b9afd59feb651 (patch)
treed0e9cbd478230ff05b5ae975da6d56df01796712
parentAdd braces. Style-only change. (diff)
downloadwireguard-openbsd-720c14e513bba2c96fd407d06b2b9afd59feb651.tar.xz
wireguard-openbsd-720c14e513bba2c96fd407d06b2b9afd59feb651.zip
Adjust the read/write watermarks according to the TCP send buffer.
This fixes sending of large files. Previously, httpd was reading the input file too quickly and could run out of memory when filling the input buffer. Found by jsg@ OK florian@
-rw-r--r--usr.sbin/httpd/httpd.h3
-rw-r--r--usr.sbin/httpd/server.c14
-rw-r--r--usr.sbin/httpd/server_file.c6
3 files changed, 20 insertions, 3 deletions
diff --git a/usr.sbin/httpd/httpd.h b/usr.sbin/httpd/httpd.h
index 0983ce22500..449c10fc59c 100644
--- a/usr.sbin/httpd/httpd.h
+++ b/usr.sbin/httpd/httpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: httpd.h,v 1.47 2014/08/06 02:04:42 jsing Exp $ */
+/* $OpenBSD: httpd.h,v 1.48 2014/08/06 09:36:31 reyk Exp $ */
/*
* Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org>
@@ -273,6 +273,7 @@ struct client {
struct evbuffer *clt_output;
struct event clt_ev;
void *clt_desc;
+ int clt_sndbufsiz;
int clt_fd;
struct ressl *clt_ressl_ctx;
diff --git a/usr.sbin/httpd/server.c b/usr.sbin/httpd/server.c
index e3727aed1b9..b9d3c757f3f 100644
--- a/usr.sbin/httpd/server.c
+++ b/usr.sbin/httpd/server.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: server.c,v 1.31 2014/08/06 04:39:50 jsg Exp $ */
+/* $OpenBSD: server.c,v 1.32 2014/08/06 09:36:31 reyk Exp $ */
/*
* Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org>
@@ -631,6 +631,7 @@ server_input(struct client *clt)
struct server_config *srv_conf = clt->clt_srv_conf;
evbuffercb inrd = server_read;
evbuffercb inwr = server_write;
+ socklen_t slen;
if (server_httpdesc_init(clt) == -1) {
server_close(clt, "failed to allocate http descriptor");
@@ -640,6 +641,13 @@ server_input(struct client *clt)
clt->clt_toread = TOREAD_HTTP_HEADER;
inrd = server_read_http;
+ slen = sizeof(clt->clt_sndbufsiz);
+ if (getsockopt(clt->clt_s, SOL_SOCKET, SO_SNDBUF,
+ &clt->clt_sndbufsiz, &slen) == -1) {
+ server_close(clt, "failed to get send buffer size");
+ return;
+ }
+
/*
* Client <-> Server
*/
@@ -657,6 +665,10 @@ server_input(struct client *clt)
server_ssl_writecb, clt->clt_bev);
}
+ /* Adjust write watermark to the socket buffer output size */
+ bufferevent_setwatermark(clt->clt_bev, EV_WRITE,
+ clt->clt_sndbufsiz, 0);
+
bufferevent_settimeout(clt->clt_bev,
srv_conf->timeout.tv_sec, srv_conf->timeout.tv_sec);
bufferevent_enable(clt->clt_bev, EV_READ|EV_WRITE);
diff --git a/usr.sbin/httpd/server_file.c b/usr.sbin/httpd/server_file.c
index 4989f195663..5b72aaf4683 100644
--- a/usr.sbin/httpd/server_file.c
+++ b/usr.sbin/httpd/server_file.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: server_file.c,v 1.29 2014/08/04 17:43:20 reyk Exp $ */
+/* $OpenBSD: server_file.c,v 1.30 2014/08/06 09:36:31 reyk Exp $ */
/*
* Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org>
@@ -201,6 +201,10 @@ server_file(struct httpd *env, struct client *clt)
goto fail;
}
+ /* Adjust read watermark to the socket output buffer size */
+ bufferevent_setwatermark(clt->clt_srvbev, EV_READ, 0,
+ clt->clt_sndbufsiz);
+
bufferevent_settimeout(clt->clt_srvbev,
srv_conf->timeout.tv_sec, srv_conf->timeout.tv_sec);
bufferevent_enable(clt->clt_srvbev, EV_READ);