From: Niels Provos Date: Mon, 13 Feb 2006 01:51:58 +0000 (+0000) Subject: limit the amount of data bufferevents are going to consume to something X-Git-Tag: release-2.0.1-alpha~747 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7b78c82823a8d65338503b8aabd3a606116d7cfc;p=libevent limit the amount of data bufferevents are going to consume to something reasonable; in some circumstances it could happen that libevent happily allocated 100MB in read buffers without telling the user; found by christopher maxwell - parts of these changes are from his patch. svn:r200 --- diff --git a/buffer.c b/buffer.c index 7ce5bef1..e3c0ef9a 100644 --- a/buffer.c +++ b/buffer.c @@ -340,8 +340,21 @@ evbuffer_read(struct evbuffer *buf, int fd, int howmuch) #endif #ifdef FIONREAD - if (ioctl(fd, FIONREAD, &n) == -1 || n == 0) + if (ioctl(fd, FIONREAD, &n) == -1 || n == 0) { n = EVBUFFER_MAX_READ; + } else if (n > EVBUFFER_MAX_READ && n > howmuch) { + /* + * It's possible that a lot of data is available for + * reading. We do not want to exhaust resources + * before the reader has a chance to do something + * about it. If the reader does not tell us how much + * data we should read, we artifically limit it. + */ + if (n > buf->totallen << 2) + n = buf->totallen << 2; + if (n < EVBUFFER_MAX_READ) + n = EVBUFFER_MAX_READ; + } #endif if (howmuch < 0 || howmuch > n) howmuch = n; diff --git a/evbuffer.c b/evbuffer.c index 0e7ef00c..7bd8d49a 100644 --- a/evbuffer.c +++ b/evbuffer.c @@ -92,13 +92,21 @@ bufferevent_readcb(int fd, short event, void *arg) int res = 0; short what = EVBUFFER_READ; size_t len; + int howmuch = -1; if (event == EV_TIMEOUT) { what |= EVBUFFER_TIMEOUT; goto error; } - res = evbuffer_read(bufev->input, fd, -1); + /* + * If we have a high watermark configured then we don't want to + * read more data than would make us reach the watermark. + */ + if (bufev->wm_read.high != 0) + howmuch = bufev->wm_read.high; + + res = evbuffer_read(bufev->input, fd, howmuch); if (res == -1) { if (errno == EAGAIN || errno == EINTR) goto reschedule;