Snapshot of libevent 2.1, as of 2.0.12-stable release.
bk: 4deb6714l4796Fn6rDPicqsu2TGkJQ
+Changes in version 2.0.13-stable (?? Jul 2011)
+
+
+
+Changes in version 2.0.12-stable (4 Jun 2011)
+BUGFIXES
+ o Fix a warn-and-fail bug in kqueue by providing kevent() room to report errors (28317a0)
+ o Fix an assert-inducing fencepost bug in the select backend (d90149d)
+ o Fix failing http assertion introducd in commit 0d6622e (0848814 Kevin Ko)
+ o Fix a bug that prevented us from configuring IPv6 nameservers. (74760f1)
+ o Prevent size_t overflow in evhttp_htmlescape. (06c51cd Mansour Moufid)
+ o Added several checks for under/overflow conditions in evhttp_handle_chunked_read (a279272 Mark Ellzey)
+ o Added overflow checks in evhttp_read_body and evhttp_get_body (84560fc Mark Ellzey)
+
+DOCUMENTATION:
+ o Add missing words to EVLOOP_NONBLOCK documentation (9556a7d)
+
+BUILD FIXES
+ o libssl depends on libcrypto, not the other way around. (274dd03 Peter Rosin)
+ o Libtool brings in the dependencies of libevent_openssl.la automatically (7b819f2 Peter Rosin)
+ o Use OPENSSL_LIBS in Makefile.am (292092e Sebastian Hahn)
+ o Move the win32 detection in configure.in (ceb03b9 Sebastian Hahn)
+ o Correctly detect openssl on windows (6619385 Sebastian Hahn)
+ o Fix a compile warning with zlib 1.2.4 and 1.2.5 (5786b91 Sebastian Hahn)
+ o Fix compilation with GCC 2, which had no __builtin_expect (09d39a1 Dave Hart)
+ o Fix new warnings from GCC 4.6 (06a714f)
+ o Link with -lshell32 and -ladvapi32 on Win32. (86090ee Peter Rosin)
+ o Make the tests build when OpenSSL is not available. (07c41be Peter Rosin)
+ o Bring in the compile script from automake, if needed. (f3c7a4c Peter Rosin)
+ o MSVC does not provide S_ISDIR, so provide it manually. (70be7d1 Peter Rosin)
+ o unistd.h and sys/time.h might not exist. (fe93022 Peter Rosin)
+ o Make sure TINYTEST_LOCAL is defined when building tinytest.c (8fa030c Peter Rosin)
+ o Fix winsock2.h #include issues with MSVC (3d768dc Peter Rosin)
+ o Use evutil_gettimeofday instead of relying on the system gettimeofday. (0de87fe Peter Rosin)
+ o Always use evutil_snprintf, even if OS provides it (d1b2d11 Sebastian Hahn)
+ o InitializeCriticalSectionAndSpinCount requires _WIN32_WINNT >= 0x0403. (816115a Peter Rosin)
+ o cygwin: make it possible to build DLLs (d54d3fc)
+
+
+
Changes in version 2.0.11-stable (27 Apr 2011)
[Autogenerated from the Git log, sorted and cleaned by hand.]
BUGFIXES:
VERSION_INFO = 1:0:0
# History: RELEASE VERSION_INFO
+# 2.0.1-alpha -- 2.0 1:0:0
+# 2.0.2-alpha -- 2:0:0
+# 2.0.3-alpha -- 2:0:0 (should have incremented; didn't.)
+# 2.0.4-alpha -- 3:0:0
+# 2.0.5-beta -- 4:0:0
+# 2.0.6-rc -- 2.0 2:0:0
+# 2.0.7-rc -- 2.0 3:0:1
+# 2.0.8-rc -- 2.0 4:0:2
+# 2.0.9-rc -- 2.0 5:0:0 (ABI changed slightly)
+# 2.0.10-stable-- 2.0 5:1:0 (No ABI change)
+# 2.0.11-stable-- 2.0 6:0:1 (ABI changed, backward-compatible)
+# 2.0.12-stable-- 2.0 6:1:1 (No ABI change)
+#
+# For Libevent 2.1:
# 2.1.1-alpha -- 2.1 1:0:0
evmap.c log.c evutil.c evutil_rand.c strlcpy.c $(SYS_SRC)
EXTRA_SRC = event_tagging.c http.c evdns.c evrpc.c
-if BUILD_WIN32
+if BUILD_WITH_NO_UNDEFINED
NO_UNDEFINED = -no-undefined
MAYBE_CORE = libevent_core.la
else
if PTHREADS
libevent_pthreads_la_SOURCES = evthread_pthread.c
+libevent_pthreads_la_LIBADD = $(MAYBE_CORE)
libevent_pthreads_la_LDFLAGS = $(GENERIC_LDFLAGS)
endif
Claudio Jeker
Evan Jones
Phua Keat
+ Kevin Ko
+ Brian Koehmstedt
Marko Kreen
Valery Kyholodov
Scott Lamb
Andrey Matveev
Caitlin Mercer
Dagobert Michelsen
+ Mansour Moufid
Felix Nawothnig
Trond Norbye
Linus Nordberg
Dimitre Piskyulev
Pavel Plesov
Jon Poland
+ Robert Ransom
Bert JW Regeer
+ Peter Rosin
Hanna Schroeter
Ralf Schmitt
Mike Smellie
const struct evbuffer_ptr *pos, const char *mem, size_t len);
static struct evbuffer_chain *evbuffer_expand_singlechain(struct evbuffer *buf,
size_t datlen);
+static int evbuffer_ptr_subtract(struct evbuffer *buf, struct evbuffer_ptr *pos,
+ size_t howfar);
static struct evbuffer_chain *
evbuffer_chain_new(size_t size)
break;
}
case EVBUFFER_EOL_CRLF:
- while (1) {
- if (evbuffer_find_eol_char(&it) < 0)
- goto done;
- if (evbuffer_getchr(&it) == '\n') {
- extra_drain = 1;
- break;
- } else if (!evbuffer_ptr_memcmp(
- buffer, &it, "\r\n", 2)) {
- extra_drain = 2;
- break;
- } else {
- if (evbuffer_ptr_set(buffer, &it, 1,
- EVBUFFER_PTR_ADD)<0)
- goto done;
- }
+ /* Look for a LF ... */
+ if (evbuffer_strchr(&it, '\n') < 0)
+ goto done;
+ extra_drain = 1;
+ /* ... optionally preceeded by a CR. */
+ if (it.pos < 1) break;
+ /* This potentially does an extra linear walk over the first
+ * few chains. Probably, that's not too expensive unless you
+ * have a really pathological setup. */
+ memcpy(&it2, &it, sizeof(it));
+ if (evbuffer_ptr_subtract(buffer, &it2, 1)<0)
+ break;
+ if (evbuffer_getchr(&it2) == '\r') {
+ memcpy(&it, &it2, sizeof(it));
+ extra_drain = 2;
}
break;
case EVBUFFER_EOL_LF:
return search;
}
+/* Subract <b>howfar</b> from the position of <b>pos</b> within
+ * <b>buf</b>. Returns 0 on success, -1 on failure.
+ *
+ * This isn't exposed yet, because of potential inefficiency issues.
+ * Maybe it should be. */
+static int
+evbuffer_ptr_subtract(struct evbuffer *buf, struct evbuffer_ptr *pos,
+ size_t howfar)
+{
+ if (howfar > (size_t)pos->pos)
+ return -1;
+ if (howfar <= pos->_internal.pos_in_chain) {
+ pos->_internal.pos_in_chain -= howfar;
+ pos->pos -= howfar;
+ return 0;
+ } else {
+ const size_t newpos = pos->pos - howfar;
+ /* Here's the inefficient part: it walks over the
+ * chains until we hit newpos. */
+ return evbuffer_ptr_set(buf, pos, newpos, EVBUFFER_PTR_SET);
+ }
+}
+
int
evbuffer_ptr_set(struct evbuffer *buf, struct evbuffer_ptr *pos,
size_t position, enum evbuffer_ptr_how how)
FILE_MAP_READ,
offset_rounded >> 32,
offset_rounded & 0xfffffffful,
- length);
+ length + offset_remaining);
if (data == NULL) {
mm_free(chain);
goto err;
bwin32=false; AC_MSG_RESULT(no),
)
+dnl - check if the macro __CYGWIN__ is defined on this compiler.
+dnl - (this is how we check for a cygwin version of GCC)
+AC_MSG_CHECKING(for CYGWIN)
+AC_TRY_COMPILE(,
+ [
+#ifndef __CYGWIN__
+die horribly
+#endif
+ ],
+ cygwin=true; AC_MSG_RESULT(yes),
+ cygwin=false; AC_MSG_RESULT(no),
+)
+
AC_CHECK_HEADERS([zlib.h])
if test "x$ac_cv_header_zlib_h" = "xyes"; then
fi
AM_CONDITIONAL(BUILD_WIN32, test x$bwin32 = xtrue)
+AM_CONDITIONAL(BUILD_CYGWIN, test x$cygwin = xtrue)
+AM_CONDITIONAL(BUILD_WITH_NO_UNDEFINED, test x$bwin32 = xtrue || test x$cygwin = xtrue)
if test x$bwin32 = xtrue; then
AC_SEARCH_LIBS([getservbyname],[ws2_32])
if (base->evbase == NULL) {
event_warnx("%s: no event mechanism available",
__func__);
+ base->evsel = NULL;
event_base_free(base);
return NULL;
}
base->th_notify_fd[0] = -1;
base->th_notify_fd[1] = -1;
event_debug_unassign(&base->th_notify);
+ base->th_notify_fn = NULL;
}
if (base->evsel->dealloc != NULL)
if (!base)
return -1;
- if (base->th_notify_fd[0] >= 0)
+ if (base->th_notify_fn != NULL) {
+ /* The base is already notifiable: we're doing fine. */
return 0;
+ }
#if defined(_EVENT_HAVE_EVENTFD) && defined(_EVENT_HAVE_SYS_EVENTFD_H)
#ifndef EFD_CLOEXEC
*/
#include "evconfig-private.h"
+#ifndef _WIN32_WINNT
+/* Minimum required for InitializeCriticalSectionAndSpinCount */
+#define _WIN32_WINNT 0x0403
+#endif
#include <winsock2.h>
#include <windows.h>
#include <process.h>
#include "evsignal-internal.h"
#include "evmap-internal.h"
-/*
- * Default value for ed_nevents, which is the maximum file descriptor number we
- * can handle. If an event comes in for a file descriptor F > nevents, we will
- * grow the array of file descriptors, doubling its size.
- */
-#define DEFAULT_NFDS 16
-
-
-/*
- * EVENTS_PER_GETN is the maximum number of events to retrieve from port_getn on
- * any particular call. You can speed things up by increasing this, but it will
- * (obviously) require more memory.
- */
-#define EVENTS_PER_GETN 8
+#define INITIAL_EVENTS_PER_GETN 8
+#define MAX_EVENTS_PER_GETN 4096
/*
* Per-file-descriptor information about what events we're subscribed to. These
*/
struct fd_info {
- short fdi_what; /* combinations of EV_READ and EV_WRITE */
+ /* combinations of EV_READ and EV_WRITE */
+ short fdi_what;
+ /* Index of this fd within ed_pending, plus 1. Zero if this fd is
+ * not in ed_pending. (The +1 is a hack so that memset(0) will set
+ * it to a nil index. */
+ int pending_idx_plus_1;
};
#define FDI_HAS_READ(fdi) ((fdi)->fdi_what & EV_READ)
struct evport_data {
int ed_port; /* event port for system events */
- int ed_nevents; /* number of allocated fdi's */
- struct fd_info *ed_fds; /* allocated fdi table */
+ /* How many elements of ed_pending should we look at? */
+ int ed_npending;
+ /* How many elements are allocated in ed_pending and pevtlist? */
+ int ed_maxevents;
/* fdi's that we need to reassoc */
- int ed_pending[EVENTS_PER_GETN]; /* fd's with pending events */
+ int *ed_pending;
+ /* storage space for incoming events. */
+ port_event_t *ed_pevtlist;
+
};
static void* evport_init(struct event_base *);
static int evport_del(struct event_base *, int fd, short old, short events, void *);
static int evport_dispatch(struct event_base *, struct timeval *);
static void evport_dealloc(struct event_base *);
+static int grow(struct evport_data *, int min_events);
const struct eventop evportops = {
"evport",
evport_dealloc,
1, /* need reinit */
0, /* features */
- 0, /* fdinfo length */
+ sizeof(struct fd_info), /* fdinfo length */
};
/*
evport_init(struct event_base *base)
{
struct evport_data *evpd;
- int i;
if (!(evpd = mm_calloc(1, sizeof(struct evport_data))))
return (NULL);
return (NULL);
}
- /*
- * Initialize file descriptor structure
- */
- evpd->ed_fds = mm_calloc(DEFAULT_NFDS, sizeof(struct fd_info));
- if (evpd->ed_fds == NULL) {
+ if (grow(evpd, INITIAL_EVENTS_PER_GETN) < 0) {
close(evpd->ed_port);
mm_free(evpd);
- return (NULL);
+ return NULL;
}
- evpd->ed_nevents = DEFAULT_NFDS;
- for (i = 0; i < EVENTS_PER_GETN; i++)
- evpd->ed_pending[i] = -1;
+
+ evpd->ed_npending = 0;
evsig_init(base);
return (evpd);
}
+static int
+grow(struct evport_data *data, int min_events)
+{
+ int newsize;
+ int *new_pending;
+ port_event_t *new_pevtlist;
+ if (data->ed_maxevents) {
+ newsize = data->ed_maxevents;
+ do {
+ newsize *= 2;
+ } while (newsize < min_events);
+ } else {
+ newsize = min_events;
+ }
+
+ new_pending = mm_realloc(data->ed_pending, sizeof(int)*newsize);
+ if (new_pending == NULL)
+ return -1;
+ data->ed_pending = new_pending;
+ new_pevtlist = mm_realloc(data->ed_pevtlist, sizeof(port_event_t)*newsize);
+ if (new_pevtlist == NULL)
+ return -1;
+ data->ed_pevtlist = new_pevtlist;
+
+ data->ed_maxevents = newsize;
+ return 0;
+}
+
#ifdef CHECK_INVARIANTS
/*
* Checks some basic properties about the evport_data structure. Because it
check_evportop(struct evport_data *evpd)
{
EVUTIL_ASSERT(evpd);
- EVUTIL_ASSERT(evpd->ed_nevents > 0);
EVUTIL_ASSERT(evpd->ed_port > 0);
- EVUTIL_ASSERT(evpd->ed_fds > 0);
}
/*
* PORT_SOURCE_FD.
*/
EVUTIL_ASSERT(pevt->portev_source == PORT_SOURCE_FD);
- EVUTIL_ASSERT(pevt->portev_user == NULL);
}
#else
#define check_event(pevt)
#endif /* CHECK_INVARIANTS */
-/*
- * Doubles the size of the allocated file descriptor array.
- */
-static int
-grow(struct evport_data *epdp, int factor)
-{
- struct fd_info *tmp;
- int oldsize = epdp->ed_nevents;
- int newsize = factor * oldsize;
- EVUTIL_ASSERT(factor > 1);
-
- check_evportop(epdp);
-
- tmp = mm_realloc(epdp->ed_fds, sizeof(struct fd_info) * newsize);
- if (NULL == tmp)
- return -1;
- epdp->ed_fds = tmp;
- memset((char*) (epdp->ed_fds + oldsize), 0,
- (newsize - oldsize)*sizeof(struct fd_info));
- epdp->ed_nevents = newsize;
-
- check_evportop(epdp);
-
- return 0;
-}
-
-
/*
* (Re)associates the given file descriptor with the event port. The OS events
* are specified (implicitly) from the fd_info struct.
if (sysevents != 0) {
if (port_associate(epdp->ed_port, PORT_SOURCE_FD,
- fd, sysevents, NULL) == -1) {
+ fd, sysevents, fdip) == -1) {
event_warn("port_associate");
return (-1);
}
{
int i, res;
struct evport_data *epdp = base->evbase;
- port_event_t pevtlist[EVENTS_PER_GETN];
+ port_event_t *pevtlist = epdp->ed_pevtlist;
/*
* port_getn will block until it has at least nevents events. It will
* also return how many it's given us (which may be more than we asked
- * for, as long as it's less than our maximum (EVENTS_PER_GETN)) in
+ * for, as long as it's less than our maximum (ed_maxevents)) in
* nevents.
*/
int nevents = 1;
* last time which need reassociation. See comment at the end of the
* loop below.
*/
- for (i = 0; i < EVENTS_PER_GETN; ++i) {
+ for (i = 0; i < epdp->ed_npending; ++i) {
struct fd_info *fdi = NULL;
- if (epdp->ed_pending[i] != -1) {
- fdi = &(epdp->ed_fds[epdp->ed_pending[i]]);
+ const int fd = epdp->ed_pending[i];
+ if (fd != -1) {
+ /* We might have cleared out this event; we need
+ * to be sure that it's still set. */
+ fdi = evmap_io_get_fdinfo(&base->io, fd);
}
if (fdi != NULL && FDI_HAS_EVENTS(fdi)) {
- int fd = epdp->ed_pending[i];
reassociate(epdp, fdi, fd);
- epdp->ed_pending[i] = -1;
+// epdp->ed_pending[i] = -1;
+ fdi->pending_idx_plus_1 = 0;
}
}
EVBASE_RELEASE_LOCK(base, th_base_lock);
- res = port_getn(epdp->ed_port, pevtlist, EVENTS_PER_GETN,
+ res = port_getn(epdp->ed_port, pevtlist, epdp->ed_maxevents,
(unsigned int *) &nevents, ts_p);
EVBASE_ACQUIRE_LOCK(base, th_base_lock);
event_debug(("%s: port_getn reports %d events", __func__, nevents));
for (i = 0; i < nevents; ++i) {
- struct fd_info *fdi;
port_event_t *pevt = &pevtlist[i];
int fd = (int) pevt->portev_object;
+ struct fd_info *fdi = pevt->portev_user;
+ //EVUTIL_ASSERT(evmap_io_get_fdinfo(&base->io, fd) == fdi);
check_evportop(epdp);
check_event(pevt);
epdp->ed_pending[i] = fd;
+ fdi->pending_idx_plus_1 = i + 1;
/*
* Figure out what kind of event it was
if (pevt->portev_events & (POLLERR|POLLHUP|POLLNVAL))
res |= EV_READ|EV_WRITE;
- EVUTIL_ASSERT(epdp->ed_nevents > fd);
- fdi = &(epdp->ed_fds[fd]);
-
evmap_io_active(base, fd, res);
} /* end of all events gotten */
+ epdp->ed_npending = nevents;
+
+ if (nevents == epdp->ed_maxevents &&
+ epdp->ed_maxevents < MAX_EVENTS_PER_GETN) {
+ /* we used all the space this time. We should be ready
+ * for more events next time around. */
+ grow(epdp, epdp->ed_maxevents * 2);
+ }
check_evportop(epdp);
evport_add(struct event_base *base, int fd, short old, short events, void *p)
{
struct evport_data *evpd = base->evbase;
- struct fd_info *fdi;
- int factor;
- (void)p;
+ struct fd_info *fdi = p;
check_evportop(evpd);
- /*
- * If necessary, grow the file descriptor info table
- */
-
- factor = 1;
- while (fd >= factor * evpd->ed_nevents)
- factor *= 2;
-
- if (factor > 1) {
- if (-1 == grow(evpd, factor)) {
- return (-1);
- }
- }
-
- fdi = &evpd->ed_fds[fd];
fdi->fdi_what |= events;
return reassociate(evpd, fdi, fd);
evport_del(struct event_base *base, int fd, short old, short events, void *p)
{
struct evport_data *evpd = base->evbase;
- struct fd_info *fdi;
- int i;
- int associated = 1;
- (void)p;
+ struct fd_info *fdi = p;
+ int associated = ! fdi->pending_idx_plus_1;
check_evportop(evpd);
- if (evpd->ed_nevents < fd) {
- return (-1);
- }
-
- for (i = 0; i < EVENTS_PER_GETN; ++i) {
- if (evpd->ed_pending[i] == fd) {
- associated = 0;
- break;
- }
- }
-
- fdi = &evpd->ed_fds[fd];
- if (events & EV_READ)
- fdi->fdi_what &= ~EV_READ;
- if (events & EV_WRITE)
- fdi->fdi_what &= ~EV_WRITE;
+ fdi->fdi_what &= ~(events &(EV_READ|EV_WRITE));
if (associated) {
if (!FDI_HAS_EVENTS(fdi) &&
}
} else {
if ((fdi->fdi_what & (EV_READ|EV_WRITE)) == 0) {
+ const int i = fdi->pending_idx_plus_1 - 1;
+ EVUTIL_ASSERT(evpd->ed_pending[i] == fd);
evpd->ed_pending[i] = -1;
+ fdi->pending_idx_plus_1 = 0;
}
}
return 0;
close(evpd->ed_port);
- if (evpd->ed_fds)
- mm_free(evpd->ed_fds);
+ if (evpd->ed_pending)
+ mm_free(evpd->ed_pending);
+ if (evpd->ed_pevtlist)
+ mm_free(evpd->ed_pevtlist);
+
mm_free(evpd);
}
#include "evconfig-private.h"
#ifdef _WIN32
+#ifndef _WIN32_WINNT
+/* Minimum required for InitializeCriticalSectionAndSpinCount */
+#define _WIN32_WINNT 0x0403
+#endif
#include <winsock2.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
static enum message_read_status
evhttp_handle_chunked_read(struct evhttp_request *req, struct evbuffer *buf)
{
- ev_ssize_t len;
+ if (req == NULL || buf == NULL) {
+ return DATA_CORRUPTED;
+ }
+
+ while (1) {
+ size_t buflen;
+
+ if ((buflen = evbuffer_get_length(buf)) == 0) {
+ break;
+ }
+
+ /* evbuffer_get_length returns size_t, but len variable is ssize_t,
+ * check for overflow conditions */
+ if (buflen > EV_SSIZE_MAX) {
+ return DATA_CORRUPTED;
+ }
- while ((len = evbuffer_get_length(buf)) > 0) {
if (req->ntoread < 0) {
/* Read chunk size */
ev_int64_t ntoread;
/* could not get chunk size */
return (DATA_CORRUPTED);
}
+
+ /* ntoread is signed int64, body_size is unsigned size_t, check for under/overflow conditions */
+ if ((ev_uint64_t)ntoread > EV_SIZE_MAX - req->body_size) {
+ return DATA_CORRUPTED;
+ }
+
if (req->body_size + (size_t)ntoread > req->evcon->max_body_size) {
/* failed body length test */
event_debug(("Request body is too long"));
return (DATA_TOO_LONG);
}
+
req->body_size += (size_t)ntoread;
req->ntoread = ntoread;
if (req->ntoread == 0) {
continue;
}
+ /* req->ntoread is signed int64, len is ssize_t, based on arch,
+ * ssize_t could only be 32b, check for these conditions */
+ if (req->ntoread > EV_SSIZE_MAX) {
+ return DATA_CORRUPTED;
+ }
+
/* don't have enough to complete a chunk; wait for more */
- if (len < req->ntoread)
+ if (req->ntoread > 0 && buflen < (ev_uint64_t)req->ntoread)
return (MORE_DATA_EXPECTED);
/* Completed chunk */
- /* XXXX fixme: what if req->ntoread is > SIZE_T_MAX? */
evbuffer_remove_buffer(buf, req->input_buffer, (size_t)req->ntoread);
req->ntoread = -1;
if (req->chunk_cb != NULL) {
}
} else if (req->ntoread < 0) {
/* Read until connection close. */
+ if ((size_t)(req->body_size + evbuffer_get_length(buf)) < req->body_size) {
+ evhttp_connection_fail(evcon, EVCON_HTTP_INVALID_HEADER);
+ return;
+ }
+
req->body_size += evbuffer_get_length(buf);
evbuffer_add_buffer(req->input_buffer, buf);
- } else if (req->chunk_cb != NULL ||
- evbuffer_get_length(buf) >= (size_t)req->ntoread) {
+ } else if (req->chunk_cb != NULL || evbuffer_get_length(buf) >= (size_t)req->ntoread) {
+ /* XXX: the above get_length comparison has to be fixed for overflow conditions! */
/* We've postponed moving the data until now, but we're
* about to use it. */
size_t n = evbuffer_get_length(buf);
+
if (n > (size_t) req->ntoread)
n = (size_t) req->ntoread;
req->ntoread -= n;
if (req->body_size > req->evcon->max_body_size ||
(!req->chunked && req->ntoread >= 0 &&
(size_t)req->ntoread > req->evcon->max_body_size)) {
+ /* XXX: The above casted comparison must checked for overflow */
/* failed body length test */
event_debug(("Request body is too long"));
evhttp_connection_fail(evcon,
no, we should respond with an error. For
now, just optimistically tell the client to
send their message body. */
- if (req->ntoread > 0 &&
- (size_t)req->ntoread > req->evcon->max_body_size) {
- evhttp_send_error(req, HTTP_ENTITYTOOLARGE,
- NULL);
- return;
+ if (req->ntoread > 0) {
+ /* ntoread is ev_int64_t, max_body_size is ev_uint64_t */
+ if ((req->evcon->max_body_size <= EV_INT64_MAX) && (ev_uint64_t)req->ntoread > req->evcon->max_body_size) {
+ evhttp_send_error(req, HTTP_ENTITYTOOLARGE, NULL);
+ return;
+ }
}
if (!evbuffer_get_length(bufferevent_get_input(evcon->bufev)))
evhttp_send_continue(evcon, req);
#include <sys/types.h>
#ifdef _WIN32
+#ifndef _WIN32_WINNT
+/* Minimum required for InitializeCriticalSectionAndSpinCount */
+#define _WIN32_WINNT 0x0403
+#endif
#include <winsock2.h>
#include <ws2tcpip.h>
#include <mswsock.h>
event_debug(("%s: select reports %d", __func__, res));
check_selectop(sop);
- i = random() % (nfds+1);
- for (j = 0; j <= nfds; ++j) {
- if (++i >= nfds+1)
+ i = random() % nfds;
+ for (j = 0; j < nfds; ++j) {
+ if (++i >= nfds)
i = 0;
res = 0;
if (FD_ISSET(i, sop->event_readset_out))
evhttp_free(http);
http = NULL;
- /* Pick an unroutable address. The limited broadcast address should do
- * when working with TCP. */
- evcon = evhttp_connection_base_new(data->base, NULL, "255.255.255.255", 80);
+ /* Pick an unroutable address. This administratively scoped multicast
+ * address should do when working with TCP. */
+ evcon = evhttp_connection_base_new(data->base, NULL, "239.10.20.30", 80);
tt_assert(evcon);
/*
#endif
#ifndef _WIN32
+#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#endif