From 40da44bd9b969a2330d6cb28edf9313bf77535dd Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 29 Jan 2017 17:23:14 +0300 Subject: Fix -Werror=implicit-fallthrough (fixes gcc-7) Fixes: #447 (cherry picked from commit 94e7dcebc320bf496ff6b613d8e4b771fa0a161c) --- bufferevent_filter.c | 3 +++ evdns.c | 7 ++++--- event.c | 1 + util-internal.h | 10 ++++++++++ 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/bufferevent_filter.c b/bufferevent_filter.c index d47f9452..b5efd5c0 100644 --- a/bufferevent_filter.c +++ b/bufferevent_filter.c @@ -612,9 +612,12 @@ be_filter_ctrl(struct bufferevent *bev, enum bufferevent_ctrl_op op, bevf->underlying->be_ops->ctrl) { return (bevf->underlying->be_ops->ctrl)(bevf->underlying, op, data); } + EVUTIL_FALLTHROUGH; case BEV_CTRL_GET_FD: + EVUTIL_FALLTHROUGH; case BEV_CTRL_CANCEL_ALL: + EVUTIL_FALLTHROUGH; default: return -1; } diff --git a/evdns.c b/evdns.c index e9dbc35c..40042925 100644 --- a/evdns.c +++ b/evdns.c @@ -2265,10 +2265,11 @@ evdns_request_transmit(struct request *req) { nameserver_write_waiting(req->ns, 1); return 1; case 2: - /* failed to transmit the request entirely. */ + /* failed to transmit the request entirely. we can fallthrough since + * we'll set a timeout, which will time out, and make us retransmit the + * request anyway. */ retcode = 1; - /* fall through: we'll set a timeout, which will time out, - * and make us retransmit the request anyway. */ + EVUTIL_FALLTHROUGH; default: /* all ok */ log(EVDNS_LOG_DEBUG, diff --git a/event.c b/event.c index 503003e2..7230d1ab 100644 --- a/event.c +++ b/event.c @@ -2960,6 +2960,7 @@ event_callback_activate_nolock_(struct event_base *base, switch (evcb->evcb_flags & (EVLIST_ACTIVE|EVLIST_ACTIVE_LATER)) { default: EVUTIL_ASSERT(0); + EVUTIL_FALLTHROUGH; case EVLIST_ACTIVE_LATER: event_queue_remove_active_later(base, evcb); r = 0; diff --git a/util-internal.h b/util-internal.h index 38d0f595..54e9fa30 100644 --- a/util-internal.h +++ b/util-internal.h @@ -50,6 +50,10 @@ extern "C" { #endif +#if !defined(__has_attribute) +#define __has_attribute(x) 0 +#endif + /* If we need magic to say "inline", get it for free internally. */ #ifdef EVENT__inline #define inline EVENT__inline @@ -308,6 +312,12 @@ ev_int32_t evutil_weakrand_range_(struct evutil_weakrand_state *seed, ev_int32_t #define EVUTIL_UNLIKELY(p) (p) #endif +#if __has_attribute(fallthrough) +#define EVUTIL_FALLTHROUGH __attribute__((fallthrough)) +#else +#define EVUTIL_FALLTHROUGH /* fallthrough */ +#endif + /* Replacement for assert() that calls event_errx on failure. */ #ifdef NDEBUG #define EVUTIL_ASSERT(cond) EVUTIL_NIL_CONDITION_(cond) -- cgit v1.2.1 From 3a1f47fd1de8b8a4b726c34e87c1c0e34ad5c0c3 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 29 Jan 2017 19:32:10 +0300 Subject: Do not overwrite version from GIT if it is older then defaults (cherry picked from commit 0344edf62dc49d822315a8d832f17be8d2c43643) --- cmake/VersionViaGit.cmake | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/cmake/VersionViaGit.cmake b/cmake/VersionViaGit.cmake index a9882d8a..28f7a51a 100644 --- a/cmake/VersionViaGit.cmake +++ b/cmake/VersionViaGit.cmake @@ -4,7 +4,6 @@ # # Usful for auto-versionin in ou CMakeLists # -# EVENT_GIT___VERSION_FOUND - Version variables foud # EVENT_GIT___VERSION_MAJOR - Major version. # EVENT_GIT___VERSION_MINOR - Minor version # EVENT_GIT___VERSION_STAGE - Stage version @@ -12,7 +11,6 @@ # Example usage: # # event_fuzzy_version_from_git() -# if (EVENT_GIT___VERSION_FOUND) # message("Libvent major=${EVENT_GIT___VERSION_MAJOR}") # message(" minor=${EVENT_GIT___VERSION_MINOR}") # message(" patch=${EVENT_GIT___VERSION_PATCH}") @@ -22,8 +20,6 @@ include(FindGit) macro(event_fuzzy_version_from_git) - set(EVENT_GIT___VERSION_FOUND FALSE) - # set our defaults. set(EVENT_GIT___VERSION_MAJOR 2) set(EVENT_GIT___VERSION_MINOR 1) @@ -41,13 +37,25 @@ macro(event_fuzzy_version_from_git) RESULT_VARIABLE GITRET OUTPUT_VARIABLE - GITVERSION) + GITVERSION + OUTPUT_STRIP_TRAILING_WHITESPACE) if (GITRET EQUAL 0) - string(REGEX REPLACE "^release-([0-9]+)\\.([0-9]+)\\.([0-9]+)-(.*)" "\\1" EVENT_GIT___VERSION_MAJOR ${GITVERSION}) - string(REGEX REPLACE "^release-([0-9]+)\\.([0-9]+)\\.([0-9]+)-(.*)" "\\2" EVENT_GIT___VERSION_MINOR ${GITVERSION}) - string(REGEX REPLACE "^release-([0-9]+)\\.([0-9]+)\\.([0-9]+)-(.*)" "\\3" EVENT_GIT___VERSION_PATCH ${GITVERSION}) - string(REGEX REPLACE "^release-([0-9]+)\\.([0-9]+)\\.([0-9]+)-([aA-zZ]+)" "\\4" EVENT_GIT___VERSION_STAGE ${GITVERSION}) + string(REGEX REPLACE "[\\._-]" ";" VERSION_LIST "${GITVERSION}") + list(GET VERSION_LIST 1 _MAJOR) + list(GET VERSION_LIST 2 _MINOR) + list(GET VERSION_LIST 3 _PATCH) + list(GET VERSION_LIST 4 _STAGE) + + set(_DEFAULT_VERSION "${EVENT_GIT___VERSION_MAJOR}.${EVENT_GIT___VERSION_MINOR}.${EVENT_GIT___VERSION_PATCH}-${EVENT_GIT___VERSION_STAGE}") + set(_GIT_VERSION "${_MAJOR}.${_MINOR}.${_PATCH}-${_STAGE}") + + if (${_DEFAULT_VERSION} VERSION_LESS ${_GIT_VERSION}) + set(EVENT_GIT___VERSION_MAJOR ${_MAJOR}) + set(EVENT_GIT___VERSION_MINOR ${_MINOR}) + set(EVENT_GIT___VERSION_PATCH ${_PATCH}) + set(EVENT_GIT___VERSION_STAGE ${_STAGE}) + endif() endif() endif() endmacro() -- cgit v1.2.1 From d9d11cb2e9e9f7ca3f1b63e4a951ed9888a14e8c Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 29 Jan 2017 20:19:06 +0300 Subject: Make EVENT_STAGE_NAME non cached It did not work before correctly anyway, since cmake do not reset cache entries by default, so that reset to "beta" didn't work. But I don't think that making this variable cached is useful, so let's remove this. (cherry picked from commit fe2c2622c389d7e9529b3c2fa828fb69cc985a1e) --- CMakeLists.txt | 32 ++++++++++++++++---------------- README.md | 3 --- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b4a34f3d..dd6bf670 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,25 +76,25 @@ set(EVENT_PACKAGE_VERSION set(EVENT_NUMERIC_VERSION 0x02010800) # only a subset of names can be used, defaults to "beta" -set(EVENT_STAGE_NAME ${EVENT_VERSION_STAGE} - CACHE STRING "set the stage name (beta|alpha|release)") +set(EVENT_STAGE_NAME ${EVENT_VERSION_STAGE}) # a list that defines what can set for EVENT_STAGE_VERSION set(EVENT__ALLOWED_STAGE_NAMES - rc - beta - alpha - release) - -# attempt to find the EVENT__STAGE_VERSION in the allowed list -# of accepted stage names, the return value is stord in -# EVENT__STAGE_RET - -list(FIND EVENT__ALLOWED_STAGE_NAMES - ${EVENT_STAGE_NAME} - EVENT__STAGE_RET) - -if (EVENT__STAGE_RET EQUAL "-1") + rc + beta + alpha + alpha-dev + release + stable +) +list( + FIND EVENT__ALLOWED_STAGE_NAMES + "${EVENT_STAGE_NAME}" + EVENT__STAGE_RET +) +if (EVENT__STAGE_RET EQUAL -1) + message(WARNING + "stage ${EVENT_STAGE_NAME} is not allowed, reset to beta") set(EVENT_STAGE_NAME beta) endif() diff --git a/README.md b/README.md index 5e3eb4df..150bfe0d 100644 --- a/README.md +++ b/README.md @@ -77,9 +77,6 @@ EVENT__ENABLE_VERBOSE_DEBUG:BOOL=OFF # on the the cross compilation target to verify that it works. See cmake # documentation for try_run for more details EVENT__FORCE_KQUEUE_CHECK:BOOL=OFF - -# set EVENT_STAGE_VERSION -EVENT__STAGE_VERSION:STRING=beta ``` __More variables can be found by running `cmake -LAH `__ -- cgit v1.2.1 From 08658136193380df56380acb08440f75532b5b5c Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 29 Jan 2017 21:37:31 +0300 Subject: Include openssl-compat.h into dist archive Refs: nmathewson/Libevent@140 Refs: http://archives.seul.org/libevent/users/Jan-2017/msg00001.html (cherry picked from commit 7bc822cad9d06775e366e6c5ac523b13522a6a81) --- Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 0f741bc9..0c07d77e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -283,7 +283,8 @@ noinst_HEADERS += \ ratelim-internal.h \ strlcpy-internal.h \ time-internal.h \ - util-internal.h + util-internal.h \ + openssl-compat.h EVENT1_HDRS = \ include/evdns.h \ -- cgit v1.2.1 From 8567f2f56e2dc9907980e8fd4127bc01983af177 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 29 Jan 2017 23:07:40 +0300 Subject: Merge branch 'fix-struct-linger' @jbech "Accidentally disabled by 0dda56a due to confusion between struct linger vs. SO_LINGER and #define vs. AC_DEFINE. Try adding synthetic #error test to confirm." * fix-struct-linger: cmake: check for 'struct linger' existence test/bench*: prefix event-config.h macros after 0dda56a48e94 test/bench_httpclient: restore SO_LINGER usage after 0dda56a48e94 Fixes: #444 (original pull-request) (cherry picked from commit 9d5a4bdc5cfbf2385efc7c58103161b3512c4500) --- CMakeLists.txt | 2 ++ configure.ac | 3 +-- event-config.h.cmake | 3 +++ test/bench.c | 4 ++-- test/bench_cascade.c | 4 ++-- test/bench_httpclient.c | 4 ++-- 6 files changed, 12 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dd6bf670..1d6bafc5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -578,6 +578,8 @@ if(EVENT__HAVE_STRUCT_SOCKADDR_STORAGE) __ss_family "${SOCKADDR_HEADERS}" EVENT__HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY) endif() +CHECK_TYPE_SIZE("struct linger" EVENT__HAVE_STRUCT_LINGER) + # Group the source files. set(HDR_PRIVATE bufferevent-internal.h diff --git a/configure.ac b/configure.ac index 7528d37e..ebb59110 100644 --- a/configure.ac +++ b/configure.ac @@ -715,8 +715,7 @@ AC_CHECK_MEMBERS([struct in6_addr.s6_addr32, struct in6_addr.s6_addr16, struct s #endif ]) -AC_CHECK_TYPES([struct so_linger], -[#define HAVE_SO_LINGER], , +AC_CHECK_TYPES([struct linger],,, [ #ifdef HAVE_SYS_SOCKET_H #include diff --git a/event-config.h.cmake b/event-config.h.cmake index c1355be9..faa159b7 100644 --- a/event-config.h.cmake +++ b/event-config.h.cmake @@ -313,6 +313,9 @@ /* Define to 1 if `__ss_family' is a member of `struct sockaddr_storage'. */ #cmakedefine EVENT__HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY +/* Define to 1 if the system has the type `struct linger'. */ +#cmakedefine EVENT__HAVE_STRUCT_LINGER + /* Define to 1 if you have the `sysctl' function. */ #cmakedefine EVENT__HAVE_SYSCTL diff --git a/test/bench.c b/test/bench.c index 214479c1..c2c8983d 100644 --- a/test/bench.c +++ b/test/bench.c @@ -136,7 +136,7 @@ run_once(void) int main(int argc, char **argv) { -#ifdef HAVE_SETRLIMIT +#ifdef EVENT__HAVE_SETRLIMIT struct rlimit rl; #endif int i, c; @@ -167,7 +167,7 @@ main(int argc, char **argv) } } -#ifdef HAVE_SETRLIMIT +#ifdef EVENT__HAVE_SETRLIMIT rl.rlim_cur = rl.rlim_max = num_pipes * 2 + 50; if (setrlimit(RLIMIT_NOFILE, &rl) == -1) { perror("setrlimit"); diff --git a/test/bench_cascade.c b/test/bench_cascade.c index 2d85cc1f..1248835d 100644 --- a/test/bench_cascade.c +++ b/test/bench_cascade.c @@ -139,7 +139,7 @@ run_once(int num_pipes) int main(int argc, char **argv) { -#ifdef HAVE_SETRLIMIT +#ifdef EVENT__HAVE_SETRLIMIT struct rlimit rl; #endif int i, c; @@ -162,7 +162,7 @@ main(int argc, char **argv) } } -#ifdef HAVE_SETRLIMIT +#ifdef EVENT__HAVE_SETRLIMIT rl.rlim_cur = rl.rlim_max = num_pipes * 2 + 50; if (setrlimit(RLIMIT_NOFILE, &rl) == -1) { perror("setrlimit"); diff --git a/test/bench_httpclient.c b/test/bench_httpclient.c index e1592951..7c7ee470 100644 --- a/test/bench_httpclient.c +++ b/test/bench_httpclient.c @@ -113,13 +113,13 @@ errorcb(struct bufferevent *b, short what, void *arg) static void frob_socket(evutil_socket_t sock) { -#ifdef HAVE_SO_LINGER +#ifdef EVENT__HAVE_STRUCT_LINGER struct linger l; #endif int one = 1; if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*)&one, sizeof(one))<0) perror("setsockopt(SO_REUSEADDR)"); -#ifdef HAVE_SO_LINGER +#ifdef EVENT__HAVE_STRUCT_LINGER l.l_onoff = 1; l.l_linger = 0; if (setsockopt(sock, SOL_SOCKET, SO_LINGER, (void*)&l, sizeof(l))<0) -- cgit v1.2.1 From 230af9f0e86756028e84f5b7a2d4fd434f064dee Mon Sep 17 00:00:00 2001 From: Jan Beich Date: Sat, 28 Jan 2017 16:42:13 +0000 Subject: Unbreak build with LibreSSL after openssl 1.1 support added Fixes: 3e9e0a0d46e4 ("Make it build using OpenSSL 1.1.0") Fixes: #445 (cherry picked from commit d057c45e8f48aa90d8b340cac4c8ae4cc8b5d0ac) --- openssl-compat.h | 4 ++-- sample/https-client.c | 6 +++--- sample/le-proxy.c | 2 +- sample/openssl_hostname_validation.c | 2 +- test/regress_ssl.c | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/openssl-compat.h b/openssl-compat.h index 69afc716..0f2dcb75 100644 --- a/openssl-compat.h +++ b/openssl-compat.h @@ -1,7 +1,7 @@ #ifndef OPENSSL_COMPAT_H #define OPENSSL_COMPAT_H -#if OPENSSL_VERSION_NUMBER < 0x10100000L +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) static inline BIO_METHOD *BIO_meth_new(int type, const char *name) { @@ -30,6 +30,6 @@ static inline BIO_METHOD *BIO_meth_new(int type, const char *name) #define TLS_method SSLv23_method -#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ +#endif /* (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) */ #endif /* OPENSSL_COMPAT_H */ diff --git a/sample/https-client.c b/sample/https-client.c index 74839565..75666836 100644 --- a/sample/https-client.c +++ b/sample/https-client.c @@ -312,7 +312,7 @@ main(int argc, char **argv) } uri[sizeof(uri) - 1] = '\0'; -#if OPENSSL_VERSION_NUMBER < 0x10100000L +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) // Initialize OpenSSL SSL_library_init(); ERR_load_crypto_strings(); @@ -480,7 +480,7 @@ cleanup: SSL_CTX_free(ssl_ctx); if (type == HTTP && ssl) SSL_free(ssl); -#if OPENSSL_VERSION_NUMBER < 0x10100000L +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) EVP_cleanup(); ERR_free_strings(); @@ -492,7 +492,7 @@ cleanup: CRYPTO_cleanup_all_ex_data(); sk_SSL_COMP_free(SSL_COMP_get_compression_methods()); -#endif /*OPENSSL_VERSION_NUMBER < 0x10100000L */ +#endif /* (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) */ #ifdef _WIN32 WSACleanup(); diff --git a/sample/le-proxy.c b/sample/le-proxy.c index 8d9b529e..e2fbf452 100644 --- a/sample/le-proxy.c +++ b/sample/le-proxy.c @@ -259,7 +259,7 @@ main(int argc, char **argv) if (use_ssl) { int r; -#if OPENSSL_VERSION_NUMBER < 0x10100000L +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) SSL_library_init(); ERR_load_crypto_strings(); SSL_load_error_strings(); diff --git a/sample/openssl_hostname_validation.c b/sample/openssl_hostname_validation.c index 40312f2e..a60e38c4 100644 --- a/sample/openssl_hostname_validation.c +++ b/sample/openssl_hostname_validation.c @@ -48,7 +48,7 @@ SOFTWARE. #define HOSTNAME_MAX_SIZE 255 -#if OPENSSL_VERSION_NUMBER < 0x10100000L +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) #define ASN1_STRING_get0_data ASN1_STRING_data #endif diff --git a/test/regress_ssl.c b/test/regress_ssl.c index 681705fc..490853fc 100644 --- a/test/regress_ssl.c +++ b/test/regress_ssl.c @@ -186,7 +186,7 @@ get_ssl_ctx(void) void init_ssl(void) { -#if OPENSSL_VERSION_NUMBER < 0x10100000L +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) SSL_library_init(); ERR_load_crypto_strings(); SSL_load_error_strings(); -- cgit v1.2.1 From df01f798c2d63354e6a51b90017c2b7655927093 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 30 Jan 2017 01:58:22 +0300 Subject: Fix clang 3 (some versions) misbehaviour for __has_attribute() Refs: #447 Clang: https://reviews.llvm.org/rL223468 ("Modify __has_attribute so that it only looks for GNU-style attributes") (cherry picked from commit ffbce578c40a06491ce6585ab2d82ebb69a52d30) --- util-internal.h | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/util-internal.h b/util-internal.h index 54e9fa30..77e17ab0 100644 --- a/util-internal.h +++ b/util-internal.h @@ -50,8 +50,18 @@ extern "C" { #endif -#if !defined(__has_attribute) -#define __has_attribute(x) 0 +/* __has_attribute() wrapper */ +#ifdef __has_attribute +#define EVUTIL_HAS_ATTRIBUTE __has_attribute +#endif +/** clang 3 __has_attribute misbehaves in some versions */ +#if defined(__clang__) && \ + __clang__ == 1 && __clang_major__ == 3 && \ + (__clang_minor__ >= 2 && __clang_minor__ <= 5) +#undef EVUTIL_HAS_ATTRIBUTE +#endif +#ifndef EVUTIL_HAS_ATTRIBUTE +#define EVUTIL_HAS_ATTRIBUTE(x) 0 #endif /* If we need magic to say "inline", get it for free internally. */ @@ -312,7 +322,7 @@ ev_int32_t evutil_weakrand_range_(struct evutil_weakrand_state *seed, ev_int32_t #define EVUTIL_UNLIKELY(p) (p) #endif -#if __has_attribute(fallthrough) +#if EVUTIL_HAS_ATTRIBUTE(fallthrough) #define EVUTIL_FALLTHROUGH __attribute__((fallthrough)) #else #define EVUTIL_FALLTHROUGH /* fallthrough */ -- cgit v1.2.1 From 5c0132f315db195bfdb12faa1d13648ffaf5f42e Mon Sep 17 00:00:00 2001 From: David Disseldorp Date: Mon, 20 Feb 2017 14:47:59 +0100 Subject: sample/https-client: use host SSL certificate store by default Currently a static (Debian) certificate path is used by default, which can be overridden using the -crt parameter. This commit changes the default behaviour such that the openssl default certificate store is used, unless overridden by -crt. Signed-off-by: David Disseldorp (cherry picked from commit e139cbac0a277cc4eff58bff345fbbcaf0858903) --- sample/https-client.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/sample/https-client.c b/sample/https-client.c index 75666836..18cea906 100644 --- a/sample/https-client.c +++ b/sample/https-client.c @@ -191,7 +191,7 @@ main(int argc, char **argv) struct evhttp_uri *http_uri = NULL; const char *url = NULL, *data_file = NULL; - const char *crt = "/etc/ssl/certs/ca-certificates.crt"; + const char *crt = NULL; const char *scheme, *host, *path, *query; char uri[256]; int port; @@ -338,11 +338,19 @@ main(int argc, char **argv) #ifndef _WIN32 /* TODO: Add certificate loading on Windows as well */ - /* Attempt to use the system's trusted root certificates. - * (This path is only valid for Debian-based systems.) */ - if (1 != SSL_CTX_load_verify_locations(ssl_ctx, crt, NULL)) { - err_openssl("SSL_CTX_load_verify_locations"); - goto error; + if (crt == NULL) { + X509_STORE *store; + /* Attempt to use the system's trusted root certificates. */ + store = SSL_CTX_get_cert_store(ssl_ctx); + if (X509_STORE_set_default_paths(store) != 1) { + err_openssl("X509_STORE_set_default_paths"); + goto error; + } + } else { + if (SSL_CTX_load_verify_locations(ssl_ctx, crt, NULL) != 1) { + err_openssl("SSL_CTX_load_verify_locations"); + goto error; + } } /* Ask OpenSSL to verify the server certificate. Note that this * does NOT include verifying that the hostname is correct. -- cgit v1.2.1 From d3e1c440c9b27bee6b23f5c85dafd99317f5dc52 Mon Sep 17 00:00:00 2001 From: David Disseldorp Date: Mon, 20 Feb 2017 16:55:57 +0100 Subject: sample/dns-example: fix compiler warning (getopt() returns an int) Signed-off-by: David Disseldorp Closes: #449 (cherry picked from commit 55cadb2b03c95505f6adbb836f0e975772d80bce) --- sample/dns-example.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sample/dns-example.c b/sample/dns-example.c index fb705664..e180edfe 100644 --- a/sample/dns-example.c +++ b/sample/dns-example.c @@ -154,12 +154,12 @@ main(int c, char **v) { const char *ns; }; struct options o; - char opt; + int opt; struct event_base *event_base = NULL; struct evdns_base *evdns_base = NULL; memset(&o, 0, sizeof(o)); - + if (c < 2) { fprintf(stderr, "syntax: %s [-x] [-v] [-c resolv.conf] [-s ns] hostname\n", v[0]); fprintf(stderr, "syntax: %s [-T]\n", v[0]); -- cgit v1.2.1 From 45b1f379d42441456357f0b22cd6397c716cf094 Mon Sep 17 00:00:00 2001 From: Trond Norbye Date: Tue, 21 Feb 2017 12:54:02 +0100 Subject: Fix RPATH for APPLE By setting the CMake minimum version to 3.1 CMake automatically adds the correct magic to make the library relocatable on the filesystem (instead of burning the location of the library at link time into the binary). ex: otool -L bin/http-connect bin/http-connect: @rpath/libevent_extra.2.2.0.dylib (compatibility version 2.2.0, current version 0.0.0) /usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.8) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.0.0) Fixes: #468 (cherry-picked) (cherry picked from commit cc0e04d798643b76ce1874213cb6cc3b2c6b5ac4) --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1d6bafc5..4cda730e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,7 +18,7 @@ # cmake -G "Visual Studio 10" .. # start libevent.sln # -if (WIN32) +if (WIN32 OR APPLE) cmake_minimum_required(VERSION 3.1 FATAL_ERROR) else() cmake_minimum_required(VERSION 2.8.0 FATAL_ERROR) -- cgit v1.2.1 From 8dddccd019f525a51b9ff4d839dca29b4dad39ff Mon Sep 17 00:00:00 2001 From: tim-le Date: Sun, 5 Mar 2017 23:10:27 +0800 Subject: evutil: fix a typo of comment Fixes: #481 Fixes: #480 (cherry picked from commit 8df81546f3f25ac83888eca31843484703232492) --- evutil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evutil.c b/evutil.c index 1e8ef7bd..4dd4a2e1 100644 --- a/evutil.c +++ b/evutil.c @@ -1053,7 +1053,7 @@ evutil_getaddrinfo_common_(const char *nodename, const char *servname, struct sockaddr_in sin; memset(&sin, 0, sizeof(sin)); if (1==evutil_inet_pton(AF_INET, nodename, &sin.sin_addr)) { - /* Got an ipv6 address. */ + /* Got an ipv4 address. */ sin.sin_family = AF_INET; sin.sin_port = htons(port); *res = evutil_new_addrinfo_((struct sockaddr*)&sin, -- cgit v1.2.1 From e7bd9e0380163dd8df75039c061195ceb7e68ae8 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 6 Mar 2017 02:46:23 +0300 Subject: Merge branch 'fix-openssl-linking' * fix-openssl-linking: sample/https-client: use ERR_remove_*state() when we have them Do not check for ERR_remove_thread_state() (do not link ssl into every library) Closes: #476 (cherry picked from commit 98faf19895bd6aa41c68f7da050179e207f05ae1) --- CMakeLists.txt | 4 ---- configure.ac | 4 ---- event-config.h.cmake | 3 --- sample/https-client.c | 7 ++++--- 4 files changed, 4 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4cda730e..8cc5e66a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -879,10 +879,6 @@ if (NOT EVENT__DISABLE_SAMPLES) time-test) if (NOT EVENT__DISABLE_OPENSSL AND OPENSSL_LIBRARIES) - set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES}) - CHECK_FUNCTION_EXISTS_EX(ERR_remove_thread_state EVENT__HAVE_ERR_REMOVE_THREAD_STATE) - set(CMAKE_REQUIRED_LIBRARIES "") - # Special sample with more than one file. add_executable(https-client sample/https-client.c diff --git a/configure.ac b/configure.ac index ebb59110..03389241 100644 --- a/configure.ac +++ b/configure.ac @@ -790,10 +790,6 @@ fi # check if we have and should use openssl AM_CONDITIONAL(OPENSSL, [test "$enable_openssl" != "no" && test "$have_openssl" = "yes"]) -if test "x$enable_openssl" = "xyes"; then - AC_SEARCH_LIBS([ERR_remove_thread_state], [crypto eay32], - [AC_DEFINE(HAVE_ERR_REMOVE_THREAD_STATE, 1, [Define to 1 if you have ERR_remove_thread_stat().])]) -fi # Add some more warnings which we use in development but not in the # released versions. (Some relevant gcc versions can't handle these.) diff --git a/event-config.h.cmake b/event-config.h.cmake index faa159b7..472ffe17 100644 --- a/event-config.h.cmake +++ b/event-config.h.cmake @@ -526,9 +526,6 @@ #cmakedefine EVENT__NEED_DLLIMPORT -/* Define to 1 if you have ERR_remove_thread_stat(). */ -#cmakedefine EVENT__HAVE_ERR_REMOVE_THREAD_STATE - /* Define if waitpid() supports WNOWAIT */ #cmakedefine EVENT__HAVE_WAITPID_WITH_WNOWAIT diff --git a/sample/https-client.c b/sample/https-client.c index 18cea906..8ef75987 100644 --- a/sample/https-client.c +++ b/sample/https-client.c @@ -492,11 +492,12 @@ cleanup: EVP_cleanup(); ERR_free_strings(); -#ifdef EVENT__HAVE_ERR_REMOVE_THREAD_STATE - ERR_remove_thread_state(NULL); -#else +#if OPENSSL_VERSION_NUMBER < 0x10000000L ERR_remove_state(0); +#else + ERR_remove_thread_state(NULL); #endif + CRYPTO_cleanup_all_ex_data(); sk_SSL_COMP_free(SSL_COMP_get_compression_methods()); -- cgit v1.2.1 From 0864138a8fb731762193ab2adf0032c462b1a47d Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 6 Mar 2017 02:52:46 +0300 Subject: travis-ci: remove -DEVENT__ENABLE_VERBOSE_DEBUG=ON (too much useless logs) I guess we can revert part of 59649f7 commit, we tried, but it adds more problems than solves. Refs: https://github.com/libevent/libevent/pull/476#issuecomment-284259602 (cherry picked from commit c199df7bc78824ff579ff34c5f9f922034e8fa31) --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index cc370e9f..fe8d77ef 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,6 @@ env: - EVENT_BUILD_METHOD=cmake EVENT_CMAKE_OPTIONS="-DEVENT__DISABLE_THREAD_SUPPORT=ON" - EVENT_BUILD_METHOD=cmake EVENT_CMAKE_OPTIONS="-DEVENT__DISABLE_DEBUG_MODE=ON" - EVENT_BUILD_METHOD=cmake EVENT_CMAKE_OPTIONS="-DEVENT__DISABLE_MM_REPLACEMENT=ON" - - EVENT_BUILD_METHOD=cmake EVENT_CMAKE_OPTIONS="-DEVENT__ENABLE_VERBOSE_DEBUG=ON" - EVENT_BUILD_METHOD=autotools EVENT_CONFIGURE_OPTIONS="" - EVENT_BUILD_METHOD=autotools EVENT_CONFIGURE_OPTIONS="--disable-openssl" - EVENT_BUILD_METHOD=autotools EVENT_CONFIGURE_OPTIONS="--disable-thread-support" -- cgit v1.2.1 From a0bfe2c451bc375c5945c684a6409ac4d7114e61 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Wed, 8 Mar 2017 17:58:26 +0300 Subject: Merge branch 'cmake-configure-fixes-v2' Fixes in cmake, to make it more like configure and support some cross-compiling. * cmake-configure-fixes-v2: cmake: fix extracting of the version from git (check for number of matches) Detect arch4random_addrandom() existence Use off_t instead of ev_off_t for sendfile() (fixes android build) cmake: detect _GNU_SOURCE not by __GNU_LIBRARY__ only (fallback to _GNU_SOURCE) Check for WNOWAIT in waitpid() in runtime (not in cmake/configure) cmake: add into CMAKE_REQUIRED_INCLUDES for sizeof(pthread_t) cmake: fix values for #cmakedefine cmake: drop duplicates from event-config template cmake: add value for the #cmakedefine macros (like autoconf) cmake: Fix checking of enum values from sysctl.h (cherry picked from commit 5aade2d30b6c5eff226cbf7b63fda5a01987ba4f) --- CMakeLists.txt | 22 ++- buffer.c | 2 +- cmake/CheckConstExists.cmake | 23 +++ cmake/CheckWaitpidSupportWNOWAIT.cmake | 18 --- cmake/VersionViaGit.cmake | 39 ++--- configure.ac | 21 +-- event-config.h.cmake | 277 ++++++++++++++++----------------- evutil_rand.c | 2 + include/event2/util.h | 2 + test/regress.c | 8 +- 10 files changed, 204 insertions(+), 210 deletions(-) create mode 100644 cmake/CheckConstExists.cmake delete mode 100644 cmake/CheckWaitpidSupportWNOWAIT.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 8cc5e66a..4b3f1797 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,6 +52,7 @@ include(CheckStructHasMember) include(CheckCSourceCompiles) include(CheckPrototypeDefinition) include(CheckFunctionKeywords) +include(CheckConstExists) include(AddCompilerFlags) include(VersionViaGit) @@ -223,7 +224,14 @@ if (SOLARIS) endif() # Check if _GNU_SOURCE is available. -CHECK_SYMBOL_EXISTS(__GNU_LIBRARY__ "features.h" _GNU_SOURCE) +if (NOT _GNU_SOURCE) + CHECK_SYMBOL_EXISTS(__GNU_LIBRARY__ "features.h" _GNU_SOURCE) + + if (NOT _GNU_SOURCE) + unset(_GNU_SOURCE CACHE) + CHECK_SYMBOL_EXISTS(_GNU_SOURCE "features.h" _GNU_SOURCE) + endif() +endif() if (_GNU_SOURCE) add_definitions(-D_GNU_SOURCE) @@ -330,6 +338,7 @@ CHECK_FUNCTION_EXISTS_EX(sysctl EVENT__HAVE_SYSCTL) CHECK_FUNCTION_EXISTS_EX(accept4 EVENT__HAVE_ACCEPT4) CHECK_FUNCTION_EXISTS_EX(arc4random EVENT__HAVE_ARC4RANDOM) CHECK_FUNCTION_EXISTS_EX(arc4random_buf EVENT__HAVE_ARC4RANDOM_BUF) +CHECK_FUNCTION_EXISTS_EX(arc4random_addrandom EVENT__HAVE_ARC4RANDOM_ADDRANDOM) CHECK_FUNCTION_EXISTS_EX(epoll_create1 EVENT__HAVE_EPOLL_CREATE1) CHECK_FUNCTION_EXISTS_EX(getegid EVENT__HAVE_GETEGID) CHECK_FUNCTION_EXISTS_EX(geteuid EVENT__HAVE_GETEUID) @@ -412,10 +421,10 @@ else() endif() CHECK_SYMBOL_EXISTS(TAILQ_FOREACH sys/queue.h EVENT__HAVE_TAILQFOREACH) -CHECK_SYMBOL_EXISTS(CTL_KERN sys/sysctl.h EVENT__HAVE_DECL_CTL_KERN) -CHECK_SYMBOL_EXISTS(KERN_ARND sys/sysctl.h EVENT__HAVE_DECL_KERN_ARND) -CHECK_SYMBOL_EXISTS(KERN_RANDOM sys/sysctl.h EVENT__HAVE_DECL_KERN_RANDOM) -CHECK_SYMBOL_EXISTS(RANDOM_UUID sys/sysctl.h EVENT__HAVE_DECL_RANDOM_UUID) +CHECK_CONST_EXISTS(CTL_KERN sys/sysctl.h EVENT__HAVE_DECL_CTL_KERN) +CHECK_CONST_EXISTS(KERN_ARND sys/sysctl.h EVENT__HAVE_DECL_KERN_ARND) +CHECK_CONST_EXISTS(KERN_RANDOM sys/sysctl.h EVENT__HAVE_DECL_KERN_RANDOM) +CHECK_CONST_EXISTS(RANDOM_UUID sys/sysctl.h EVENT__HAVE_DECL_RANDOM_UUID) CHECK_SYMBOL_EXISTS(F_SETFD fcntl.h EVENT__HAVE_SETFD) CHECK_TYPE_SIZE(fd_mask EVENT__HAVE_FD_MASK) @@ -470,6 +479,7 @@ else() endif() if (NOT EVENT__DISABLE_THREAD_SUPPORT) + list(APPEND CMAKE_EXTRA_INCLUDE_FILES pthread.h) CHECK_TYPE_SIZE(pthread_t EVENT__SIZEOF_PTHREAD_T) endif() @@ -492,8 +502,6 @@ CHECK_TYPE_SIZE("void *" EVENT__SIZEOF_VOID_P) #CHECK_FILE_OFFSET_BITS() #set(EVENT___FILE_OFFSET_BITS _FILE_OFFSET_BITS) -include(CheckWaitpidSupportWNOWAIT) - # Verify kqueue works with pipes. if (EVENT__HAVE_KQUEUE) if (CMAKE_CROSSCOMPILING AND NOT EVENT__FORCE_KQUEUE_CHECK) diff --git a/buffer.c b/buffer.c index b7e3a69f..be958feb 100644 --- a/buffer.c +++ b/buffer.c @@ -2465,7 +2465,7 @@ evbuffer_write_sendfile(struct evbuffer *buffer, evutil_socket_t dest_fd, ev_off_t len = chain->off; #elif defined(SENDFILE_IS_LINUX) || defined(SENDFILE_IS_SOLARIS) ev_ssize_t res; - ev_off_t offset = chain->misalign; + off_t offset = chain->misalign; #endif ASSERT_EVBUFFER_LOCKED(buffer); diff --git a/cmake/CheckConstExists.cmake b/cmake/CheckConstExists.cmake new file mode 100644 index 00000000..56b49882 --- /dev/null +++ b/cmake/CheckConstExists.cmake @@ -0,0 +1,23 @@ +include(CheckCSourceCompiles) + +macro(check_const_exists CONST FILES VARIABLE) + set(check_const_exists_source "") + foreach(file ${FILES}) + set(check_const_exists_source + "${check_const_exists_source} + #include <${file}>") + endforeach() + set(check_const_exists_source + "${check_const_exists_source} + int main() { (void)${CONST}; return 0; }") + + check_c_source_compiles("${check_const_exists_source}" ${VARIABLE}) + + if (${${VARIABLE}}) + set(${VARIABLE} 1 CACHE INTERNAL "Have const ${CONST}") + message(STATUS "Looking for ${CONST} - found") + else() + set(${VARIABLE} 0 CACHE INTERNAL "Have const ${CONST}") + message(STATUS "Looking for ${CONST} - not found") + endif() +endmacro(check_const_exists) diff --git a/cmake/CheckWaitpidSupportWNOWAIT.cmake b/cmake/CheckWaitpidSupportWNOWAIT.cmake deleted file mode 100644 index 1a73db37..00000000 --- a/cmake/CheckWaitpidSupportWNOWAIT.cmake +++ /dev/null @@ -1,18 +0,0 @@ -include(CheckCSourceRuns) - -check_c_source_runs( -" -#include -#include -#include -#include - -int -main(int argc, char** argv) -{ - pid_t pid; - int status; - if ((pid = fork()) == 0) _exit(0); - _exit(waitpid(pid, &status, WNOWAIT) == -1); -}" -EVENT__HAVE_WAITPID_WITH_WNOWAIT) diff --git a/cmake/VersionViaGit.cmake b/cmake/VersionViaGit.cmake index 28f7a51a..b17764c3 100644 --- a/cmake/VersionViaGit.cmake +++ b/cmake/VersionViaGit.cmake @@ -38,24 +38,27 @@ macro(event_fuzzy_version_from_git) GITRET OUTPUT_VARIABLE GITVERSION - OUTPUT_STRIP_TRAILING_WHITESPACE) - - if (GITRET EQUAL 0) - string(REGEX REPLACE "[\\._-]" ";" VERSION_LIST "${GITVERSION}") - list(GET VERSION_LIST 1 _MAJOR) - list(GET VERSION_LIST 2 _MINOR) - list(GET VERSION_LIST 3 _PATCH) - list(GET VERSION_LIST 4 _STAGE) - - set(_DEFAULT_VERSION "${EVENT_GIT___VERSION_MAJOR}.${EVENT_GIT___VERSION_MINOR}.${EVENT_GIT___VERSION_PATCH}-${EVENT_GIT___VERSION_STAGE}") - set(_GIT_VERSION "${_MAJOR}.${_MINOR}.${_PATCH}-${_STAGE}") - - if (${_DEFAULT_VERSION} VERSION_LESS ${_GIT_VERSION}) - set(EVENT_GIT___VERSION_MAJOR ${_MAJOR}) - set(EVENT_GIT___VERSION_MINOR ${_MINOR}) - set(EVENT_GIT___VERSION_PATCH ${_PATCH}) - set(EVENT_GIT___VERSION_STAGE ${_STAGE}) - endif() + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + string(REGEX REPLACE "[\\._-]" ";" VERSION_LIST "${GITVERSION}") + list(LENGTH VERSION_LIST VERSION_LIST_LENGTH) + + if ((GITRET EQUAL 0) AND (VERSION_LIST_LENGTH EQUAL 5)) + list(GET VERSION_LIST 1 _MAJOR) + list(GET VERSION_LIST 2 _MINOR) + list(GET VERSION_LIST 3 _PATCH) + list(GET VERSION_LIST 4 _STAGE) + + set(_DEFAULT_VERSION "${EVENT_GIT___VERSION_MAJOR}.${EVENT_GIT___VERSION_MINOR}.${EVENT_GIT___VERSION_PATCH}-${EVENT_GIT___VERSION_STAGE}") + set(_GIT_VERSION "${_MAJOR}.${_MINOR}.${_PATCH}-${_STAGE}") + + if (${_DEFAULT_VERSION} VERSION_LESS ${_GIT_VERSION}) + set(EVENT_GIT___VERSION_MAJOR ${_MAJOR}) + set(EVENT_GIT___VERSION_MINOR ${_MINOR}) + set(EVENT_GIT___VERSION_PATCH ${_PATCH}) + set(EVENT_GIT___VERSION_STAGE ${_STAGE}) endif() endif() + endif() endmacro() diff --git a/configure.ac b/configure.ac index 03389241..43baeecf 100644 --- a/configure.ac +++ b/configure.ac @@ -342,6 +342,7 @@ AC_CHECK_FUNCS([ \ accept4 \ arc4random \ arc4random_buf \ + arc4random_addrandom \ eventfd \ epoll_create1 \ fcntl \ @@ -599,26 +600,6 @@ main(int argc, char **argv) fi AM_CONDITIONAL(EPOLL_BACKEND, [test "x$haveepoll" = "xyes"]) -AC_MSG_CHECKING(waitpid support WNOWAIT) -AC_TRY_RUN( -#include -#include -#include -#include - -int -main(int argc, char** argv) -{ - pid_t pid; - int status; - if ((pid = fork()) == 0) _exit(0); - _exit(waitpid(pid, &status, WNOWAIT) == -1); -}, [AC_MSG_RESULT(yes) -AC_DEFINE(HAVE_WAITPID_WITH_WNOWAIT, 1, -[Define if waitpid() supports WNOWAIT]) -], AC_MSG_RESULT(no), AC_MSG_RESULT(no)) - - haveeventports=no AC_CHECK_FUNCS(port_create, [haveeventports=yes], ) if test "x$haveeventports" = "xyes" ; then diff --git a/event-config.h.cmake b/event-config.h.cmake index 472ffe17..65a0f5dd 100644 --- a/event-config.h.cmake +++ b/event-config.h.cmake @@ -36,397 +36,397 @@ #define EVENT__PACKAGE_TARNAME "" /* Define if libevent should build without support for a debug mode */ -#cmakedefine EVENT__DISABLE_DEBUG_MODE +#cmakedefine EVENT__DISABLE_DEBUG_MODE 1 /* Define if libevent should not allow replacing the mm functions */ -#cmakedefine EVENT__DISABLE_MM_REPLACEMENT +#cmakedefine EVENT__DISABLE_MM_REPLACEMENT 1 /* Define if libevent should not be compiled with thread support */ -#cmakedefine EVENT__DISABLE_THREAD_SUPPORT +#cmakedefine EVENT__DISABLE_THREAD_SUPPORT 1 /* Define to 1 if you have the `accept4' function. */ -#cmakedefine EVENT__HAVE_ACCEPT4 +#cmakedefine EVENT__HAVE_ACCEPT4 1 /* Define to 1 if you have the `arc4random' function. */ -#cmakedefine EVENT__HAVE_ARC4RANDOM +#cmakedefine EVENT__HAVE_ARC4RANDOM 1 /* Define to 1 if you have the `arc4random_buf' function. */ -#cmakedefine EVENT__HAVE_ARC4RANDOM_BUF +#cmakedefine EVENT__HAVE_ARC4RANDOM_BUF 1 /* Define if clock_gettime is available in libc */ -#cmakedefine EVENT__DNS_USE_CPU_CLOCK_FOR_ID +#cmakedefine EVENT__DNS_USE_CPU_CLOCK_FOR_ID 1 /* Define is no secure id variant is available */ -#cmakedefine EVENT__DNS_USE_GETTIMEOFDAY_FOR_ID -#cmakedefine EVENT__DNS_USE_FTIME_FOR_ID +#cmakedefine EVENT__DNS_USE_GETTIMEOFDAY_FOR_ID 1 +#cmakedefine EVENT__DNS_USE_FTIME_FOR_ID 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_ARPA_INET_H +#cmakedefine EVENT__HAVE_ARPA_INET_H 1 /* Define to 1 if you have the `clock_gettime' function. */ -#cmakedefine EVENT__HAVE_CLOCK_GETTIME +#cmakedefine EVENT__HAVE_CLOCK_GETTIME 1 /* Define to 1 if you have the declaration of `CTL_KERN'. */ -#cmakedefine EVENT__HAVE_DECL_CTL_KERN +#define EVENT__HAVE_DECL_CTL_KERN @EVENT__HAVE_DECL_CTL_KERN@ /* Define to 1 if you have the declaration of `KERN_ARND'. */ -#cmakedefine EVENT__HAVE_DECL_KERN_ARND +#define EVENT__HAVE_DECL_KERN_ARND @EVENT__HAVE_DECL_KERN_ARND@ /* Define to 1 if you have the declaration of `KERN_RANDOM'. */ -#cmakedefine EVENT__HAVE_DECL_KERN_RANDOM +#define EVENT__HAVE_DECL_KERN_RANDOM @EVENT__HAVE_DECL_KERN_RANDOM@ + +/* Define to 1 if you have the declaration of `RANDOM_UUID'. */ +#define EVENT__HAVE_DECL_RANDOM_UUID @EVENT__HAVE_DECL_RANDOM_UUID@ /* Define if /dev/poll is available */ -#cmakedefine EVENT__HAVE_DEVPOLL +#cmakedefine EVENT__HAVE_DEVPOLL 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_NETDB_H +#cmakedefine EVENT__HAVE_NETDB_H 1 /* Define to 1 if fd_mask type is defined */ -#cmakedefine EVENT__HAVE_FD_MASK +#cmakedefine EVENT__HAVE_FD_MASK 1 /* Define to 1 if the header file defines TAILQ_FOREACH. */ -#cmakedefine EVENT__HAVE_TAILQFOREACH +#cmakedefine EVENT__HAVE_TAILQFOREACH 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_DLFCN_H +#cmakedefine EVENT__HAVE_DLFCN_H 1 /* Define if your system supports the epoll system calls */ -#cmakedefine EVENT__HAVE_EPOLL +#cmakedefine EVENT__HAVE_EPOLL 1 /* Define to 1 if you have the `epoll_create1' function. */ -#cmakedefine EVENT__HAVE_EPOLL_CREATE1 +#cmakedefine EVENT__HAVE_EPOLL_CREATE1 1 /* Define to 1 if you have the `epoll_ctl' function. */ -#cmakedefine EVENT__HAVE_EPOLL_CTL +#cmakedefine EVENT__HAVE_EPOLL_CTL 1 /* Define to 1 if you have the `eventfd' function. */ -#cmakedefine EVENT__HAVE_EVENTFD +#cmakedefine EVENT__HAVE_EVENTFD 1 /* Define if your system supports event ports */ -#cmakedefine EVENT__HAVE_EVENT_PORTS +#cmakedefine EVENT__HAVE_EVENT_PORTS 1 /* Define to 1 if you have the `fcntl' function. */ -#cmakedefine EVENT__HAVE_FCNTL +#cmakedefine EVENT__HAVE_FCNTL 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_FCNTL_H +#cmakedefine EVENT__HAVE_FCNTL_H 1 /* Define to 1 if you have the `getaddrinfo' function. */ -#cmakedefine EVENT__HAVE_GETADDRINFO +#cmakedefine EVENT__HAVE_GETADDRINFO 1 /* Define to 1 if you have the `getegid' function. */ -#cmakedefine EVENT__HAVE_GETEGID +#cmakedefine EVENT__HAVE_GETEGID 1 /* Define to 1 if you have the `geteuid' function. */ -#cmakedefine EVENT__HAVE_GETEUID +#cmakedefine EVENT__HAVE_GETEUID 1 /* TODO: Check for different gethostname argument counts. CheckPrototypeDefinition.cmake can be used. */ /* Define this if you have any gethostbyname_r() */ -#cmakedefine EVENT__HAVE_GETHOSTBYNAME_R +#cmakedefine EVENT__HAVE_GETHOSTBYNAME_R 1 /* Define this if gethostbyname_r takes 3 arguments */ -#cmakedefine EVENT__HAVE_GETHOSTBYNAME_R_3_ARG +#cmakedefine EVENT__HAVE_GETHOSTBYNAME_R_3_ARG 1 /* Define this if gethostbyname_r takes 5 arguments */ -#cmakedefine EVENT__HAVE_GETHOSTBYNAME_R_5_ARG +#cmakedefine EVENT__HAVE_GETHOSTBYNAME_R_5_ARG 1 /* Define this if gethostbyname_r takes 6 arguments */ -#cmakedefine EVENT__HAVE_GETHOSTBYNAME_R_6_ARG +#cmakedefine EVENT__HAVE_GETHOSTBYNAME_R_6_ARG 1 /* Define to 1 if you have the `getifaddrs' function. */ -#cmakedefine EVENT__HAVE_GETIFADDRS +#cmakedefine EVENT__HAVE_GETIFADDRS 1 /* Define to 1 if you have the `getnameinfo' function. */ -#cmakedefine EVENT__HAVE_GETNAMEINFO +#cmakedefine EVENT__HAVE_GETNAMEINFO 1 /* Define to 1 if you have the `getprotobynumber' function. */ -#cmakedefine EVENT__HAVE_GETPROTOBYNUMBER +#cmakedefine EVENT__HAVE_GETPROTOBYNUMBER 1 /* Define to 1 if you have the `getservbyname' function. */ -#cmakedefine EVENT__HAVE_GETSERVBYNAME +#cmakedefine EVENT__HAVE_GETSERVBYNAME 1 /* Define to 1 if you have the `gettimeofday' function. */ -#cmakedefine EVENT__HAVE_GETTIMEOFDAY +#cmakedefine EVENT__HAVE_GETTIMEOFDAY 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_IFADDRS_H +#cmakedefine EVENT__HAVE_IFADDRS_H 1 /* Define to 1 if you have the `inet_ntop' function. */ -#cmakedefine EVENT__HAVE_INET_NTOP +#cmakedefine EVENT__HAVE_INET_NTOP 1 /* Define to 1 if you have the `inet_pton' function. */ -#cmakedefine EVENT__HAVE_INET_PTON +#cmakedefine EVENT__HAVE_INET_PTON 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_INTTYPES_H +#cmakedefine EVENT__HAVE_INTTYPES_H 1 /* Define to 1 if you have the `issetugid' function. */ -#cmakedefine EVENT__HAVE_ISSETUGID +#cmakedefine EVENT__HAVE_ISSETUGID 1 /* Define to 1 if you have the `kqueue' function. */ -#cmakedefine EVENT__HAVE_KQUEUE +#cmakedefine EVENT__HAVE_KQUEUE 1 /* Define if the system has zlib */ -#cmakedefine EVENT__HAVE_LIBZ +#cmakedefine EVENT__HAVE_LIBZ 1 /* Define to 1 if you have the `mach_absolute_time' function. */ -#cmakedefine EVENT__HAVE_MACH_ABSOLUTE_TIME +#cmakedefine EVENT__HAVE_MACH_ABSOLUTE_TIME 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_MACH_MACH_TIME_H +#cmakedefine EVENT__HAVE_MACH_MACH_TIME_H 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_MEMORY_H +#cmakedefine EVENT__HAVE_MEMORY_H 1 /* Define to 1 if you have the `mmap' function. */ -#cmakedefine EVENT__HAVE_MMAP +#cmakedefine EVENT__HAVE_MMAP 1 /* Define to 1 if you have the `nanosleep' function. */ -#cmakedefine EVENT__HAVE_NANOSLEEP +#cmakedefine EVENT__HAVE_NANOSLEEP 1 /* Define to 1 if you have the `usleep' function. */ -#cmakedefine EVENT__HAVE_USLEEP +#cmakedefine EVENT__HAVE_USLEEP 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_NETINET_IN6_H +#cmakedefine EVENT__HAVE_NETINET_IN6_H 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_NETINET_IN_H +#cmakedefine EVENT__HAVE_NETINET_IN_H 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_NETINET_TCP_H +#cmakedefine EVENT__HAVE_NETINET_TCP_H 1 /* Define if the system has openssl */ -#cmakedefine EVENT__HAVE_OPENSSL +#cmakedefine EVENT__HAVE_OPENSSL 1 /* Define to 1 if you have the `pipe' function. */ -#cmakedefine EVENT__HAVE_PIPE +#cmakedefine EVENT__HAVE_PIPE 1 /* Define to 1 if you have the `pipe2' function. */ -#cmakedefine EVENT__HAVE_PIPE2 +#cmakedefine EVENT__HAVE_PIPE2 1 /* Define to 1 if you have the `poll' function. */ -#cmakedefine EVENT__HAVE_POLL +#cmakedefine EVENT__HAVE_POLL 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_POLL_H +#cmakedefine EVENT__HAVE_POLL_H 1 /* Define to 1 if you have the `port_create' function. */ -#cmakedefine EVENT__HAVE_PORT_CREATE +#cmakedefine EVENT__HAVE_PORT_CREATE 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_PORT_H +#cmakedefine EVENT__HAVE_PORT_H 1 /* Define if we have pthreads on this system */ -#cmakedefine EVENT__HAVE_PTHREADS +#cmakedefine EVENT__HAVE_PTHREADS 1 /* Define to 1 if you have the `putenv' function. */ -#cmakedefine EVENT__HAVE_PUTENV +#cmakedefine EVENT__HAVE_PUTENV 1 /* Define to 1 if the system has the type `sa_family_t'. */ -#cmakedefine EVENT__HAVE_SA_FAMILY_T +#cmakedefine EVENT__HAVE_SA_FAMILY_T 1 /* Define to 1 if you have the `select' function. */ -#cmakedefine EVENT__HAVE_SELECT +#cmakedefine EVENT__HAVE_SELECT 1 /* Define to 1 if you have the `setenv' function. */ -#cmakedefine EVENT__HAVE_SETENV +#cmakedefine EVENT__HAVE_SETENV 1 /* Define if F_SETFD is defined in */ -#cmakedefine EVENT__HAVE_SETFD +#cmakedefine EVENT__HAVE_SETFD 1 /* Define to 1 if you have the `setrlimit' function. */ -#cmakedefine EVENT__HAVE_SETRLIMIT +#cmakedefine EVENT__HAVE_SETRLIMIT 1 /* Define to 1 if you have the `sendfile' function. */ -#cmakedefine EVENT__HAVE_SENDFILE - -/* Define if F_SETFD is defined in */ -#cmakedefine EVENT__HAVE_SETFD +#cmakedefine EVENT__HAVE_SENDFILE 1 /* Define to 1 if you have the `sigaction' function. */ -#cmakedefine EVENT__HAVE_SIGACTION +#cmakedefine EVENT__HAVE_SIGACTION 1 /* Define to 1 if you have the `signal' function. */ -#cmakedefine EVENT__HAVE_SIGNAL +#cmakedefine EVENT__HAVE_SIGNAL 1 /* Define to 1 if you have the `splice' function. */ -#cmakedefine EVENT__HAVE_SPLICE +#cmakedefine EVENT__HAVE_SPLICE 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_STDARG_H +#cmakedefine EVENT__HAVE_STDARG_H 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_STDDEF_H +#cmakedefine EVENT__HAVE_STDDEF_H 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_STDINT_H +#cmakedefine EVENT__HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_STDLIB_H +#cmakedefine EVENT__HAVE_STDLIB_H 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_STRINGS_H +#cmakedefine EVENT__HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_STRING_H +#cmakedefine EVENT__HAVE_STRING_H 1 /* Define to 1 if you have the `strlcpy' function. */ -#cmakedefine EVENT__HAVE_STRLCPY +#cmakedefine EVENT__HAVE_STRLCPY 1 /* Define to 1 if you have the `strsep' function. */ -#cmakedefine EVENT__HAVE_STRSEP +#cmakedefine EVENT__HAVE_STRSEP 1 /* Define to 1 if you have the `strtok_r' function. */ -#cmakedefine EVENT__HAVE_STRTOK_R +#cmakedefine EVENT__HAVE_STRTOK_R 1 /* Define to 1 if you have the `strtoll' function. */ -#cmakedefine EVENT__HAVE_STRTOLL +#cmakedefine EVENT__HAVE_STRTOLL 1 /* Define to 1 if the system has the type `struct addrinfo'. */ -#cmakedefine EVENT__HAVE_STRUCT_ADDRINFO +#cmakedefine EVENT__HAVE_STRUCT_ADDRINFO 1 /* Define to 1 if the system has the type `struct in6_addr'. */ -#cmakedefine EVENT__HAVE_STRUCT_IN6_ADDR +#cmakedefine EVENT__HAVE_STRUCT_IN6_ADDR 1 /* Define to 1 if `s6_addr16' is member of `struct in6_addr'. */ -#cmakedefine EVENT__HAVE_STRUCT_IN6_ADDR_S6_ADDR16 +#cmakedefine EVENT__HAVE_STRUCT_IN6_ADDR_S6_ADDR16 1 /* Define to 1 if `s6_addr32' is member of `struct in6_addr'. */ -#cmakedefine EVENT__HAVE_STRUCT_IN6_ADDR_S6_ADDR32 +#cmakedefine EVENT__HAVE_STRUCT_IN6_ADDR_S6_ADDR32 1 /* Define to 1 if the system has the type `struct sockaddr_in6'. */ -#cmakedefine EVENT__HAVE_STRUCT_SOCKADDR_IN6 +#cmakedefine EVENT__HAVE_STRUCT_SOCKADDR_IN6 1 /* Define to 1 if `sin6_len' is member of `struct sockaddr_in6'. */ -#cmakedefine EVENT__HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN +#cmakedefine EVENT__HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN 1 /* Define to 1 if `sin_len' is member of `struct sockaddr_in'. */ -#cmakedefine EVENT__HAVE_STRUCT_SOCKADDR_IN_SIN_LEN +#cmakedefine EVENT__HAVE_STRUCT_SOCKADDR_IN_SIN_LEN 1 /* Define to 1 if the system has the type `struct sockaddr_storage'. */ -#cmakedefine EVENT__HAVE_STRUCT_SOCKADDR_STORAGE +#cmakedefine EVENT__HAVE_STRUCT_SOCKADDR_STORAGE 1 /* Define to 1 if `ss_family' is a member of `struct sockaddr_storage'. */ -#cmakedefine EVENT__HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY +#cmakedefine EVENT__HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY 1 /* Define to 1 if `__ss_family' is a member of `struct sockaddr_storage'. */ -#cmakedefine EVENT__HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY +#cmakedefine EVENT__HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY 1 /* Define to 1 if the system has the type `struct linger'. */ -#cmakedefine EVENT__HAVE_STRUCT_LINGER +#cmakedefine EVENT__HAVE_STRUCT_LINGER 1 /* Define to 1 if you have the `sysctl' function. */ -#cmakedefine EVENT__HAVE_SYSCTL +#cmakedefine EVENT__HAVE_SYSCTL 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_SYS_DEVPOLL_H +#cmakedefine EVENT__HAVE_SYS_DEVPOLL_H 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_SYS_EPOLL_H +#cmakedefine EVENT__HAVE_SYS_EPOLL_H 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_SYS_EVENTFD_H +#cmakedefine EVENT__HAVE_SYS_EVENTFD_H 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_SYS_EVENT_H +#cmakedefine EVENT__HAVE_SYS_EVENT_H 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_SYS_IOCTL_H +#cmakedefine EVENT__HAVE_SYS_IOCTL_H 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_SYS_MMAN_H +#cmakedefine EVENT__HAVE_SYS_MMAN_H 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_SYS_PARAM_H +#cmakedefine EVENT__HAVE_SYS_PARAM_H 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_SYS_QUEUE_H +#cmakedefine EVENT__HAVE_SYS_QUEUE_H 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_SYS_RESOURCE_H +#cmakedefine EVENT__HAVE_SYS_RESOURCE_H 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_SYS_SELECT_H +#cmakedefine EVENT__HAVE_SYS_SELECT_H 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_SYS_SENDFILE_H +#cmakedefine EVENT__HAVE_SYS_SENDFILE_H 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_SYS_SOCKET_H +#cmakedefine EVENT__HAVE_SYS_SOCKET_H 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_SYS_STAT_H +#cmakedefine EVENT__HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_SYS_SYSCTL_H +#cmakedefine EVENT__HAVE_SYS_SYSCTL_H 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_SYS_TIMERFD_H */ +#cmakedefine EVENT__HAVE_SYS_TIMERFD_H 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_SYS_TIME_H +#cmakedefine EVENT__HAVE_SYS_TIME_H 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_SYS_TYPES_H +#cmakedefine EVENT__HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_SYS_UIO_H +#cmakedefine EVENT__HAVE_SYS_UIO_H 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_SYS_WAIT_H +#cmakedefine EVENT__HAVE_SYS_WAIT_H 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_ERRNO_H +#cmakedefine EVENT__HAVE_ERRNO_H 1 /* Define if TAILQ_FOREACH is defined in */ -#cmakedefine EVENT__HAVE_TAILQFOREACH +#cmakedefine EVENT__HAVE_TAILQFOREACH 1 /* Define if timeradd is defined in */ -#cmakedefine EVENT__HAVE_TIMERADD +#cmakedefine EVENT__HAVE_TIMERADD 1 /* Define if timerclear is defined in */ -#cmakedefine EVENT__HAVE_TIMERCLEAR +#cmakedefine EVENT__HAVE_TIMERCLEAR 1 /* Define if timercmp is defined in */ -#cmakedefine EVENT__HAVE_TIMERCMP +#cmakedefine EVENT__HAVE_TIMERCMP 1 /* Define to 1 if you have the `timerfd_create' function. */ -#cmakedefine EVENT__HAVE_TIMERFD_CREATE +#cmakedefine EVENT__HAVE_TIMERFD_CREATE 1 /* Define if timerisset is defined in */ -#cmakedefine EVENT__HAVE_TIMERISSET +#cmakedefine EVENT__HAVE_TIMERISSET 1 /* Define to 1 if the system has the type `uint8_t'. */ -#cmakedefine EVENT__HAVE_UINT8_T +#cmakedefine EVENT__HAVE_UINT8_T 1 /* Define to 1 if the system has the type `uint16_t'. */ -#cmakedefine EVENT__HAVE_UINT16_T +#cmakedefine EVENT__HAVE_UINT16_T 1 /* Define to 1 if the system has the type `uint32_t'. */ -#cmakedefine EVENT__HAVE_UINT32_T +#cmakedefine EVENT__HAVE_UINT32_T 1 /* Define to 1 if the system has the type `uint64_t'. */ -#cmakedefine EVENT__HAVE_UINT64_T +#cmakedefine EVENT__HAVE_UINT64_T 1 /* Define to 1 if the system has the type `uintptr_t'. */ -#cmakedefine EVENT__HAVE_UINTPTR_T +#cmakedefine EVENT__HAVE_UINTPTR_T 1 /* Define to 1 if you have the `umask' function. */ -#cmakedefine EVENT__HAVE_UMASK +#cmakedefine EVENT__HAVE_UMASK 1 /* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_UNISTD_H +#cmakedefine EVENT__HAVE_UNISTD_H 1 /* Define to 1 if you have the `unsetenv' function. */ -#cmakedefine EVENT__HAVE_UNSETENV +#cmakedefine EVENT__HAVE_UNSETENV 1 /* Define to 1 if you have the `vasprintf' function. */ -#cmakedefine EVENT__HAVE_VASPRINTF +#cmakedefine EVENT__HAVE_VASPRINTF 1 /* Define if kqueue works correctly with pipes */ -#cmakedefine EVENT__HAVE_WORKING_KQUEUE +#cmakedefine EVENT__HAVE_WORKING_KQUEUE 1 #ifdef __USE_UNUSED_DEFINITIONS__ /* Define to necessary symbol if this constant uses a non-standard name on your system. */ @@ -459,10 +459,10 @@ #define EVENT__SIZEOF_SIZE_T @EVENT__SIZEOF_SIZE_T@ /* Define to 1 if you have the ANSI C header files. */ -#cmakedefine EVENT__STDC_HEADERS +#cmakedefine EVENT__STDC_HEADERS 1 /* Define to 1 if you can safely include both and . */ -#cmakedefine EVENT__TIME_WITH_SYS_TIME +#cmakedefine EVENT__TIME_WITH_SYS_TIME 1 /* The size of `socklen_t', as computed by sizeof. */ #define EVENT__SIZEOF_SOCKLEN_T @EVENT__SIZEOF_SOCKLEN_T@ @@ -524,9 +524,6 @@ /* Define to `int' if does not define. */ #define EVENT__ssize_t @EVENT__ssize_t@ -#cmakedefine EVENT__NEED_DLLIMPORT +#cmakedefine EVENT__NEED_DLLIMPORT 1 -/* Define if waitpid() supports WNOWAIT */ -#cmakedefine EVENT__HAVE_WAITPID_WITH_WNOWAIT - -#endif +#endif /* \EVENT2_EVENT_CONFIG_H_INCLUDED_ */ diff --git a/evutil_rand.c b/evutil_rand.c index 046a14b0..4be0b1c5 100644 --- a/evutil_rand.c +++ b/evutil_rand.c @@ -192,12 +192,14 @@ evutil_secure_rng_get_bytes(void *buf, size_t n) ev_arc4random_buf(buf, n); } +#if !defined(EVENT__HAVE_ARC4RANDOM) || defined(EVENT__HAVE_ARC4RANDOM_ADDRANDOM) void evutil_secure_rng_add_bytes(const char *buf, size_t n) { arc4random_addrandom((unsigned char*)buf, n>(size_t)INT_MAX ? INT_MAX : (int)n); } +#endif void evutil_free_secure_rng_globals_(void) diff --git a/include/event2/util.h b/include/event2/util.h index dd4bbb69..c4af2bd6 100644 --- a/include/event2/util.h +++ b/include/event2/util.h @@ -842,6 +842,7 @@ int evutil_secure_rng_init(void); EVENT2_EXPORT_SYMBOL int evutil_secure_rng_set_urandom_device_file(char *fname); +#ifdef EVENT__HAVE_ARC4RANDOM_ADDRANDOM /** Seed the random number generator with extra random bytes. You should almost never need to call this function; it should be @@ -858,6 +859,7 @@ int evutil_secure_rng_set_urandom_device_file(char *fname); */ EVENT2_EXPORT_SYMBOL void evutil_secure_rng_add_bytes(const char *dat, size_t datlen); +#endif #ifdef __cplusplus } diff --git a/test/regress.c b/test/regress.c index d8a6b9b8..94fcbec9 100644 --- a/test/regress.c +++ b/test/regress.c @@ -855,11 +855,6 @@ test_fork(void) int status; struct event ev, sig_ev, usr_ev, existing_ev; pid_t pid; - int wait_flags = 0; - -#ifdef EVENT__HAVE_WAITPID_WITH_WNOWAIT - wait_flags |= WNOWAIT; -#endif setup_test("After fork: "); @@ -934,7 +929,8 @@ test_fork(void) } TT_BLATHER(("Before waitpid")); - if (waitpid(pid, &status, wait_flags) == -1) { + if ((waitpid(pid, &status, WNOWAIT) == -1 && errno == EINVAL) && + waitpid(pid, &status, 0) == -1) { perror("waitpid"); exit(1); } -- cgit v1.2.1 From cea61de6094afb2c7d47c035687be97122ba0f05 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Wed, 8 Mar 2017 23:15:33 +0300 Subject: Do not add epoll_sub (syscall wrappers) for epoll in cmake Nowadays mostly all supported OS'es has this wrappers, and some of them (like SmartOS) has wrappers but doesn't have __NR_epoll* defines for syscall numbers, so just drop them (instead of adding yet another check int cmake like autotools has, since this will break building in cross-compile environment). Also one minor note, configure doesn't added epoll_sub.c either, since it check epoll_create() in runtime. And I tested it in SmartOS and it even works (`make verify`). Fixes: #463 (cherry picked from commit 819d04937729b7f8b7c84d6c5c40c5fcd6d68dfd) --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4b3f1797..6bd188c9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -682,7 +682,7 @@ if(EVENT__HAVE_DEVPOLL) endif() if(EVENT__HAVE_EPOLL) - list(APPEND SRC_CORE epoll_sub.c epoll.c) + list(APPEND SRC_CORE epoll.c) endif() if(EVENT__HAVE_EVENT_PORTS) -- cgit v1.2.1 From e50af3315a55b46d47c62c777d32b46015e90240 Mon Sep 17 00:00:00 2001 From: Shuo Chen Date: Sun, 12 Mar 2017 01:00:41 -0800 Subject: Fix detection of timerfd_create() in CMake. (cherry picked from commit 65870949e7ce8110cb987cdeaa432c482cd9aabc) --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6bd188c9..403804f6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -350,7 +350,7 @@ CHECK_FUNCTION_EXISTS_EX(usleep EVENT__HAVE_USLEEP) CHECK_FUNCTION_EXISTS_EX(timeradd EVENT__HAVE_TIMERADD) CHECK_FUNCTION_EXISTS_EX(timerclear EVENT__HAVE_TIMERCLEAR) CHECK_FUNCTION_EXISTS_EX(timercmp EVENT__HAVE_TIMERCMP) -CHECK_FUNCTION_EXISTS_EX(timerfd_create HAVE_TIMERFD_CREATE) +CHECK_FUNCTION_EXISTS_EX(timerfd_create EVENT__HAVE_TIMERFD_CREATE) CHECK_FUNCTION_EXISTS_EX(timerisset EVENT__HAVE_TIMERISSET) CHECK_FUNCTION_EXISTS_EX(putenv EVENT__HAVE_PUTENV) CHECK_FUNCTION_EXISTS_EX(setenv EVENT__HAVE_SETENV) -- cgit v1.2.1 From c785e1dbadb471ecfe087643961334c93b4302ea Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Wed, 8 Mar 2017 23:48:30 +0300 Subject: appveyor: remove -DEVENT__ENABLE_VERBOSE_DEBUG=ON build See-also: c199df7bc78824ff579ff34c5f9f922034e8fa31 ("travis-ci: remove -DEVENT__ENABLE_VERBOSE_DEBUG=ON (too much useless logs)") (cherry picked from commit e01b993703f840a030e9b1cdcdc9b3fd448c77b2) --- appveyor.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 6beb5457..7001cd4c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -29,8 +29,6 @@ environment: EVENT_CMAKE_OPTIONS: "-DEVENT__DISABLE_DEBUG_MODE=ON" - EVENT_BUILD_METHOD: "cmake" EVENT_CMAKE_OPTIONS: "-DEVENT__DISABLE_MM_REPLACEMENT=ON" - - EVENT_BUILD_METHOD: "cmake" - EVENT_CMAKE_OPTIONS: "-DEVENT__ENABLE_VERBOSE_DEBUG=ON" - EVENT_BUILD_METHOD: "cmake" EVENT_CMAKE_OPTIONS: "-DCMAKE_C_FLAGS='-DUNICODE -D_UNICODE'" init: -- cgit v1.2.1 From d914115cd96240717187b2a379b7504944e9aaef Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 12 Mar 2017 13:12:53 +0300 Subject: travis-ci: do not run coverage on osx First of all we don't really need two of them, and also with apple-clang it will fail (because of our checks in cmake), so just exclude it from the build matrix. (cherry picked from commit 83b1584700ec453e89017b5f12cf338a50b101b4) --- .travis.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.travis.yml b/.travis.yml index fe8d77ef..0758b0ae 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,6 +18,11 @@ env: - EVENT_BUILD_METHOD=autotools EVENT_CONFIGURE_OPTIONS="--disable-debug-mode" - EVENT_BUILD_METHOD=autotools EVENT_CONFIGURE_OPTIONS="--disable-malloc-replacement" +matrix: + exclude: + - os: osx + env: EVENT_BUILD_METHOD=cmake EVENT_CMAKE_OPTIONS="-DEVENT__COVERAGE=ON -DCMAKE_BUILD_TYPE=debug" COVERALLS=yes + language: c compiler: - gcc -- cgit v1.2.1 From 9806b12637908dfede3f1f1b0deb02612d39ab69 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 13 Mar 2017 21:05:32 +0300 Subject: Merge branch 'cmake-missing-bits' This patchset adds next missing things (in compare to autotools): - pkgconfig - event_pthreads/event_openssl - compile shared/static libraries always And some fixes, because it will not build after fixing other things: - export missing symbols for cmake (-fvisibility=hidden) * cmake-missing-bits: cmake: support visibility for AppleClang too cmake: fix export absolute path and relative path and cleanup a bit cmake: generate and install pkgconfig files cmake: build SHARED and STATIC libraries (like autoconf does) cmake: add missing event_openssl/event_pthreads libraries Export symbols for -fvisibility=hidden (under cmake) Refs: #246 (cherry picked from commit 489991a2b2628ba1ff4e6879b9f67ec35d224c38) --- CMakeLists.txt | 551 ++++++++++++++++-------------------- README.md | 12 - bufferevent-internal.h | 20 ++ cmake/AddEventLibrary.cmake | 108 +++++++ cmake/LibeventConfig.cmake.in | 9 +- defer-internal.h | 3 + event-config.h.cmake | 2 - event-internal.h | 5 + event.c | 1 + event_tagging.c | 4 + evthread-internal.h | 5 + evthread.c | 2 +- http-internal.h | 4 + include/event2/bufferevent_compat.h | 4 + include/event2/dns_compat.h | 24 +- include/event2/http_compat.h | 3 + include/event2/rpc.h | 34 ++- include/event2/visibility.h | 8 +- iocp-internal.h | 1 + log-internal.h | 10 + mm-internal.h | 5 + strlcpy-internal.h | 2 + time-internal.h | 3 + util-internal.h | 22 ++ 24 files changed, 503 insertions(+), 339 deletions(-) create mode 100644 cmake/AddEventLibrary.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 403804f6..28b40a97 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,7 @@ if (WIN32 OR APPLE) cmake_minimum_required(VERSION 3.1 FATAL_ERROR) else() - cmake_minimum_required(VERSION 2.8.0 FATAL_ERROR) + cmake_minimum_required(VERSION 2.8.3 FATAL_ERROR) endif() if(NOT CMAKE_BUILD_TYPE) @@ -102,9 +102,6 @@ endif() set(EVENT_VERSION "${EVENT_VERSION_MAJOR}.${EVENT_VERSION_MINOR}.${EVENT_VERSION_PATCH}-${EVENT_STAGE_NAME}") -option(EVENT__BUILD_SHARED_LIBRARIES - "Define if libevent should be built with shared libraries instead of archives" OFF) - option(EVENT__DISABLE_DEBUG_MODE "Define if libevent should build without support for a debug mode" OFF) @@ -699,7 +696,7 @@ if (NOT EVENT__DISABLE_OPENSSL) include_directories(${OPENSSL_INCLUDE_DIR}) - list(APPEND SRC_CORE bufferevent_openssl.c) + list(APPEND SRC_OPENSSL bufferevent_openssl.c) list(APPEND HDR_PUBLIC include/event2/bufferevent_ssl.h) list(APPEND LIB_APPS ${OPENSSL_LIBRARIES}) endif() @@ -711,11 +708,10 @@ if (NOT EVENT__DISABLE_THREAD_SUPPORT) find_package(Threads REQUIRED) if (NOT CMAKE_USE_PTHREADS_INIT) message(FATAL_ERROR - "Failed to find Pthreads, set EVENT__DISABLE_THREAD_SUPPORT to disable") + "Failed to find Pthreads, set EVENT__DISABLE_THREAD_SUPPORT to disable") endif() set(EVENT__HAVE_PTHREADS 1) - list(APPEND SRC_CORE evthread_pthread.c) list(APPEND LIB_APPS ${CMAKE_THREAD_LIBS_INIT}) endif() endif() @@ -764,10 +760,6 @@ if(WIN32) include_directories(./WIN32-Code) endif() -if (UNIX) - list(APPEND LIB_PLATFORM m) -endif() - if (SOLARIS) list(APPEND LIB_PLATFORM socket nsl) endif() @@ -782,19 +774,13 @@ source_group("Source Extra" FILES ${SRC_EXTRA}) # (Place them in the build dir so we don't polute the source tree with generated files). include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}/include) -if (EVENT__BUILD_SHARED_LIBRARIES) - set(EVENT__LIBRARY_TYPE SHARED) - - if ((CMAKE_COMPILER_IS_GNUCC) OR (${CMAKE_C_COMPILER_ID} STREQUAL "Clang")) - add_compiler_flags(-fvisibility=hidden) - elseif ("${CMAKE_C_COMPILER_ID}" STREQUAL "SunPro") - add_compiler_flags(-xldscope=hidden) - endif() - - set(EVENT__NEED_DLLIMPORT 1) -else (EVENT__BUILD_SHARED_LIBRARIES) - set(EVENT__LIBRARY_TYPE STATIC) -endif (EVENT__BUILD_SHARED_LIBRARIES) +if ((CMAKE_COMPILER_IS_GNUCC) OR + (${CMAKE_C_COMPILER_ID} STREQUAL "Clang") OR + (${CMAKE_C_COMPILER_ID} STREQUAL "AppleClang")) + set(EVENT_SHARED_FLAGS -fvisibility=hidden) +elseif ("${CMAKE_C_COMPILER_ID}" STREQUAL "SunPro") + set(EVENT_SHARED_FLAGS -xldscope=hidden) +endif() configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/event-config.h.cmake @@ -808,74 +794,50 @@ configure_file( # # Create the libraries. # +include(AddEventLibrary) +add_event_library(event_core SOURCES ${SRC_CORE}) +add_event_library(event_extra + LIBRARIES event_core_shared + SOURCES ${SRC_EXTRA}) -# TODO: Add dynamic versions of the libraries as well. -add_library(event_core ${EVENT__LIBRARY_TYPE} - ${HDR_PRIVATE} - ${HDR_COMPAT} - ${HDR_PUBLIC} - ${SRC_CORE}) +if (NOT EVENT__DISABLE_OPENSSL) + add_event_library(event_openssl + LIBRARIES event_core_shared ${OPENSSL_LIBRARIES} + SOURCES ${SRC_OPENSSL}) +endif() -add_library(event_extra ${EVENT__LIBRARY_TYPE} - ${HDR_PRIVATE} - ${HDR_COMPAT} - ${HDR_PUBLIC} - ${SRC_CORE} - ${SRC_EXTRA}) +if (CMAKE_USE_PTHREADS_INIT) + set(SRC_PTHREADS evthread_pthread.c) + add_event_library(event_pthreads + LIBRARIES event_core_shared + SOURCES ${SRC_PTHREADS}) +endif() # library exists for historical reasons; it contains the contents of # both libevent_core and libevent_extra. You shouldn’t use it; it may # go away in a future version of Libevent. -add_library(event ${EVENT__LIBRARY_TYPE} - ${HDR_PRIVATE} - ${HDR_COMPAT} - ${HDR_PUBLIC} - ${SRC_CORE} - ${SRC_EXTRA}) - -if (EVENT__BUILD_SHARED_LIBRARIES) - # Prepare static library to be linked to tests that need hidden symbols - add_library(event_extra_static STATIC - ${HDR_PRIVATE} - ${HDR_COMPAT} - ${HDR_PUBLIC} - ${SRC_CORE} - ${SRC_EXTRA}) - - set(EVENT_EXTRA_FOR_TEST event_extra_static) - - target_link_libraries(event_core ${OPENSSL_LIBRARIES} - ${CMAKE_THREAD_LIBS_INIT} - ${LIB_PLATFORM}) - - target_link_libraries(event ${OPENSSL_LIBRARIES} - ${CMAKE_THREAD_LIBS_INIT} - ${LIB_PLATFORM}) - - target_link_libraries(event_extra ${OPENSSL_LIBRARIES} - ${CMAKE_THREAD_LIBS_INIT} - ${LIB_PLATFORM}) - - set_target_properties(event - PROPERTIES SOVERSION - ${EVENT_ABI_LIBVERSION}) - - set_target_properties(event_core - PROPERTIES SOVERSION - ${EVENT_ABI_LIBVERSION}) - - set_target_properties(event_extra - PROPERTIES SOVERSION - ${EVENT_ABI_LIBVERSION}) - -else (EVENT__BUILD_SHARED_LIBRARIES) - set(EVENT_EXTRA_FOR_TEST event_extra) -endif (EVENT__BUILD_SHARED_LIBRARIES) +add_event_library(event SOURCES ${SRC_CORE} ${SRC_EXTRA}) # # Samples. # - +macro(add_sample_prog ssl name) + add_executable(${name} ${ARGN}) + + target_link_libraries(${name} + event_extra_static + event_core_static + ${LIB_APPS} + ${LIB_PLATFORM}) + add_dependencies(${name} + event_core_static + event_extra_static) + + if (${ssl}) + target_link_libraries(${name} event_openssl_static) + add_dependencies(${name} event_openssl_static) + endif() +endmacro() if (NOT EVENT__DISABLE_SAMPLES) set(SAMPLES dns-example @@ -886,69 +848,72 @@ if (NOT EVENT__DISABLE_SAMPLES) http-connect time-test) - if (NOT EVENT__DISABLE_OPENSSL AND OPENSSL_LIBRARIES) - # Special sample with more than one file. - add_executable(https-client - sample/https-client.c - sample/openssl_hostname_validation.c - sample/hostcheck.c) - - target_link_libraries(https-client - event_extra - ${LIB_APPS} - ${LIB_PLATFORM}) - - add_dependencies(https-client event_extra) - - # Requires OpenSSL. - list(APPEND SAMPLES le-proxy) - endif() - foreach(SAMPLE ${SAMPLES}) - add_executable(${SAMPLE} - sample/${SAMPLE}.c) - - target_link_libraries(${SAMPLE} - event_extra - ${LIB_APPS} - ${LIB_PLATFORM}) - - add_dependencies(${SAMPLE} event_extra) + add_sample_prog(OFF ${SAMPLE} sample/${SAMPLE}.c) endforeach() + if (NOT EVENT__DISABLE_OPENSSL) + add_sample_prog(ON https-client + sample/https-client.c + sample/openssl_hostname_validation.c + sample/hostcheck.c) + add_sample_prog(ON le-proxy + sample/le-proxy.c) + endif() + if (WIN32) + # requires cmake 3.1 target_sources(dns-example PUBLIC WIN32-Code/getopt.c WIN32-Code/getopt_long.c) endif() endif() +# +# Benchmarks +# +macro(add_bench_prog prog) + add_executable(${prog} test/${prog}.c) + if (WIN32) + list(APPEND BENCH_SRC + WIN32-Code/getopt.c + WIN32-Code/getopt_long.c) + endif() + target_link_libraries(${BENCHMARK} + event_extra_static + event_core_static + ${LIB_APPS} + ${LIB_PLATFORM}) + add_dependencies(${BENCHMARK} + event_extra_static + event_core_static) +endmacro() if (NOT EVENT__DISABLE_BENCHMARK) foreach (BENCHMARK bench bench_cascade bench_http bench_httpclient) - set(BENCH_SRC test/${BENCHMARK}.c) - - if (WIN32) - list(APPEND BENCH_SRC - WIN32-Code/getopt.c - WIN32-Code/getopt_long.c) - endif() - - add_executable(${BENCHMARK} ${BENCH_SRC}) - - target_link_libraries(${BENCHMARK} - event_extra - ${LIB_PLATFORM}) - - add_dependencies(${BENCHMARK} event_extra) + add_bench_prog(${BENCHMARK}) endforeach() endif() +# +# Tests +# +macro(add_test_prog prog) + add_executable(${prog} test/${prog}.c) + target_link_libraries(${prog} + ${LIB_APPS} + ${LIB_PLATFORM} + event_core_shared + event_extra_shared + ${ARGN}) + add_dependencies(${prog} + event_core_shared + event_extra_shared) +endmacro() if (NOT EVENT__DISABLE_TESTS) # # Generate Regress tests. # if (NOT EVENT__DISABLE_REGRESS) - # (We require python2 to generate the regress tests) foreach (PY python2.6 python2.7 python2) unset(FIND_PYTHON2 CACHE) @@ -980,34 +945,30 @@ if (NOT EVENT__DISABLE_TESTS) WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test) list(APPEND SRC_REGRESS - test/regress.c - test/regress.gen.c - test/regress.gen.h - test/regress_buffer.c - test/regress_bufferevent.c - test/regress_dns.c - test/regress_et.c - test/regress_finalize.c - test/regress_http.c - test/regress_listener.c - test/regress_main.c - test/regress_minheap.c - test/regress_rpc.c - test/regress_testutils.c - test/regress_testutils.h - test/regress_util.c - test/tinytest.c - ${SRC_CORE} - ${SRC_EXTRA}) + test/regress.c + test/regress.gen.c + test/regress.gen.h + test/regress_buffer.c + test/regress_bufferevent.c + test/regress_dns.c + test/regress_et.c + test/regress_finalize.c + test/regress_http.c + test/regress_listener.c + test/regress_main.c + test/regress_minheap.c + test/regress_rpc.c + test/regress_testutils.c + test/regress_testutils.h + test/regress_util.c + test/tinytest.c) if (WIN32) list(APPEND SRC_REGRESS test/regress_iocp.c) if (NOT EVENT__DISABLE_THREAD_SUPPORT) list(APPEND SRC_REGRESS test/regress_thread.c) endif() - endif() - - if (CMAKE_USE_PTHREADS_INIT) + elseif (CMAKE_USE_PTHREADS_INIT) list(APPEND SRC_REGRESS test/regress_thread.c) endif() @@ -1015,7 +976,7 @@ if (NOT EVENT__DISABLE_TESTS) list(APPEND SRC_REGRESS test/regress_zlib.c) endif() - if (OPENSSL_LIBRARIES) + if (NOT EVENT__DISABLE_OPENSSL) list(APPEND SRC_REGRESS test/regress_ssl.c) endif() @@ -1025,13 +986,21 @@ if (NOT EVENT__DISABLE_TESTS) # header trying to "dllimport" the symbols on windows (it # generates a ton of warnings due to different link # attributes for all of the symbols) - SET_TARGET_PROPERTIES(regress - PROPERTIES COMPILE_DEFINITIONS - "EVENT_BUILDING_REGRESS_TEST=1") + set_target_properties(regress + PROPERTIES COMPILE_DEFINITIONS + "EVENT_BUILDING_REGRESS_TEST=1") target_link_libraries(regress - ${LIB_APPS} - ${LIB_PLATFORM}) + ${LIB_APPS} + ${LIB_PLATFORM} + event_core_shared + event_extra_static) + if (NOT EVENT__DISABLE_OPENSSL) + target_link_libraries(regress event_openssl_shared) + endif() + if (CMAKE_USE_PTHREADS_INIT) + target_link_libraries(regress event_pthreads_shared) + endif() else() message(WARNING "No suitable Python interpreter found, cannot generate regress tests!") endif() @@ -1040,44 +1009,41 @@ if (NOT EVENT__DISABLE_TESTS) # # Test programs. # - # all of these, including the cmakelists.txt should be moved - # into the dirctory 'tests' first. - # - # doing this, we can remove all the DISABLE_TESTS stuff, and simply - # do something like: - # - # add_custom_targets(tests) - # add_executable(... EXCLUDE_FROM_ALL ...c) - # add_dependencis(tests testa testb testc) - # add_test(....) - # - # then you can just run 'make tests' instead of them all - # auto-compile|running - # - ellzey - set(TESTPROGS test-changelist - test-eof - test-fdleak - test-init - test-time - test-weof) + # all of these, including the cmakelists.txt should be moved + # into the dirctory 'tests' first. + # + # doing this, we can remove all the DISABLE_TESTS stuff, and simply + # do something like: + # + # add_custom_targets(tests) + # add_executable(... EXCLUDE_FROM_ALL ...c) + # add_dependencis(tests testa testb testc) + # add_test(....) + # + # then you can just run 'make tests' instead of them all + # auto-compile|running + # - ellzey + set(TESTPROGS test-changelist + test-eof + test-fdleak + test-init + test-time + test-weof) + + foreach (TESTPROG ${TESTPROGS} test-dumpevents) + add_test_prog(${TESTPROG}) + endforeach() + if (UNIX) + add_test_prog(test-ratelim m) + else() + add_test_prog(test-ratelim) + endif() set(ALL_TESTPROGS - ${TESTPROGS} - test-dumpevents - test-ratelim) - - # Create test program executables. - foreach (TESTPROG ${ALL_TESTPROGS}) - add_executable(${TESTPROG} - test/${TESTPROG}.c) - - target_link_libraries(${TESTPROG} - ${EVENT_EXTRA_FOR_TEST} - ${LIB_PLATFORM}) - - add_dependencies(${TESTPROG} - ${EVENT_EXTRA_FOR_TEST}) - endforeach() + ${TESTPROGS} + test-dumpevents + test-ratelim + ) # # We run all tests with the different backends turned on one at a time. @@ -1131,12 +1097,12 @@ if (NOT EVENT__DISABLE_TESTS) set(TEST_NAME ${TESTPROG}__${BACKEND_TEST_NAME}) add_test(${TEST_NAME} - ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${TESTPROG}) + ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${TESTPROG}) list(APPEND TEST_NAMES ${TEST_NAME}) set_tests_properties(${TEST_NAME} - PROPERTIES ENVIRONMENT "${ENV_VARS}") + PROPERTIES ENVIRONMENT "${ENV_VARS}") endforeach() # Dump events test. @@ -1144,21 +1110,21 @@ if (NOT EVENT__DISABLE_TESTS) set(TEST_NAME test-dumpevents__${BACKEND_TEST_NAME}) add_test(${TEST_NAME} - ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test-dumpevents | - ${PYTHON_EXECUTABLE} - ${CMAKE_CURRENT_SOURCE_DIR}/test/check-dumpevents.py) + ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test-dumpevents | + ${PYTHON_EXECUTABLE} + ${CMAKE_CURRENT_SOURCE_DIR}/test/check-dumpevents.py) set_tests_properties(${TEST_NAME} - PROPERTIES ENVIRONMENT "${ENV_VARS}") + PROPERTIES ENVIRONMENT "${ENV_VARS}") else() message(WARNING "test-dumpevents will be run without output check since python was not found!") set(TEST_NAME test-dumpevents__${BACKEND_TEST_NAME}_no_check) add_test(${TEST_NAME} - ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test-dumpevents) + ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test-dumpevents) set_tests_properties(${TEST_NAME} - PROPERTIES ENVIRONMENT "${ENV_VARS}") + PROPERTIES ENVIRONMENT "${ENV_VARS}") endif() # Regress tests. @@ -1166,16 +1132,16 @@ if (NOT EVENT__DISABLE_TESTS) set(TEST_NAME regress__${BACKEND_TEST_NAME}) add_test(${TEST_NAME} - ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/regress) + ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/regress) set_tests_properties(${TEST_NAME} - PROPERTIES ENVIRONMENT "${ENV_VARS}") + PROPERTIES ENVIRONMENT "${ENV_VARS}") add_test(${TEST_NAME}_debug - ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/regress) + ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/regress) set_tests_properties(${TEST_NAME}_debug - PROPERTIES ENVIRONMENT "${ENV_VARS};EVENT_DEBUG_MODE=1") + PROPERTIES ENVIRONMENT "${ENV_VARS};EVENT_DEBUG_MODE=1") endif() endmacro() @@ -1205,47 +1171,47 @@ if (NOT EVENT__DISABLE_TESTS) # # Group limits, no connection limit. - set(RL_BIN ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test-ratelim) + set(RL_BIN ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test-ratelim) add_test(test-ratelim__group_lim - ${RL_BIN} - -g 30000 - -n 30 - -t 100 - --check-grouplimit 1000 - --check-stddev 100) + ${RL_BIN} + -g 30000 + -n 30 + -t 100 + --check-grouplimit 1000 + --check-stddev 100) # Connection limit, no group limit. add_test(test-ratelim__con_lim - ${RL_BIN} - -c 1000 - -n 30 - -t 100 - --check-connlimit 50 - --check-stddev 50) + ${RL_BIN} + -c 1000 + -n 30 + -t 100 + --check-connlimit 50 + --check-stddev 50) # Connection limit and group limit. add_test(test-ratelim__group_con_lim - ${RL_BIN} - -c 1000 - -g 30000 - -n 30 - -t 100 - --check-grouplimit 1000 - --check-connlimit 50 - --check-stddev 50) + ${RL_BIN} + -c 1000 + -g 30000 + -n 30 + -t 100 + --check-grouplimit 1000 + --check-connlimit 50 + --check-stddev 50) # Connection limit and group limit with independent drain. add_test(test-ratelim__group_con_lim_drain - ${RL_BIN} - -c 1000 - -g 35000 - -n 30 - -t 100 - -G 500 - --check-grouplimit 1000 - --check-connlimit 50 - --check-stddev 50) + ${RL_BIN} + -c 1000 + -g 35000 + -n 30 + -t 100 + -G 500 + --check-grouplimit 1000 + --check-connlimit 50 + --check-stddev 50) # Add a "make verify" target, same as for autoconf. # (Important! This will unset all EVENT_NO* environment variables. @@ -1265,21 +1231,20 @@ if (NOT EVENT__DISABLE_TESTS) message(STATUS "${WINDOWS_CTEST_COMMAND}") file(COPY ${CMAKE_CURRENT_BINARY_DIR}/tmp/verify_tests.bat - DESTINATION - ${CMAKE_CURRENT_BINARY_DIR} - FILE_PERMISSIONS - OWNER_READ - OWNER_WRITE - OWNER_EXECUTE - GROUP_READ - GROUP_EXECUTE - WORLD_READ WORLD_EXECUTE) + DESTINATION ${CMAKE_CURRENT_BINARY_DIR} + FILE_PERMISSIONS + OWNER_READ + OWNER_WRITE + OWNER_EXECUTE + GROUP_READ + GROUP_EXECUTE + WORLD_READ WORLD_EXECUTE) file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/verify_tests.bat" VERIFY_PATH) add_custom_target(verify COMMAND "${VERIFY_PATH}" - DEPENDS event ${ALL_TESTPROGS}) + DEPENDS event ${ALL_TESTPROGS}) else() # On some platforms doing exec(unset) as CMake does won't work, so make sure # we run the unset command in a shell instead. @@ -1293,23 +1258,20 @@ if (NOT EVENT__DISABLE_TESTS) # Then we copy the file (this allows us to set execute permission on it) file(COPY ${CMAKE_CURRENT_BINARY_DIR}/tmp/verify_tests.sh - DESTINATION ${CMAKE_CURRENT_BINARY_DIR} - FILE_PERMISSIONS - OWNER_READ - OWNER_WRITE - OWNER_EXECUTE - GROUP_READ - GROUP_EXECUTE - WORLD_READ - WORLD_EXECUTE) + DESTINATION ${CMAKE_CURRENT_BINARY_DIR} + FILE_PERMISSIONS + OWNER_READ + OWNER_WRITE + OWNER_EXECUTE + GROUP_READ + GROUP_EXECUTE + WORLD_READ + WORLD_EXECUTE) # Create the target that runs the script. add_custom_target(verify - COMMAND - ${CMAKE_CURRENT_BINARY_DIR}/verify_tests.sh - DEPENDS - event - ${ALL_TESTPROGS}) + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/verify_tests.sh + DEPENDS event ${ALL_TESTPROGS}) endif() if (NOT EVENT__DISABLE_REGRESS AND __FOUND_USABLE_PYTHON) @@ -1335,30 +1297,16 @@ endif() # Installation preparation. # -# Allow the user to override installation directories. -set(EVENT_INSTALL_LIB_DIR lib CACHE PATH "Installation directory for libraries") -set(EVENT_INSTALL_BIN_DIR bin CACHE PATH "Installation directory for executables") -set(EVENT_INSTALL_INCLUDE_DIR include CACHE PATH "Installation directory for header files") - if(WIN32 AND NOT CYGWIN) set(DEF_INSTALL_CMAKE_DIR cmake) else() set(DEF_INSTALL_CMAKE_DIR lib/cmake/libevent) endif() -set(EVENT_INSTALL_CMAKE_DIR ${DEF_INSTALL_CMAKE_DIR} CACHE PATH "Installation directory for CMake files") - -# Make sure the paths are absolute. -foreach(p LIB BIN INCLUDE CMAKE) - set(var EVENT_INSTALL_${p}_DIR) - if(NOT IS_ABSOLUTE "${${var}}") - set(${var} "${CMAKE_INSTALL_PREFIX}/${${var}}") - endif() -endforeach() +set(EVENT_INSTALL_CMAKE_DIR + "${CMAKE_INSTALL_PREFIX}/${DEF_INSTALL_CMAKE_DIR}" + CACHE PATH "Installation directory for CMake files") -# Export targets (This is used for other CMake projects to easily find the libraries and include files). -export(TARGETS event event_extra event_core - FILE "${PROJECT_BINARY_DIR}/LibeventTargets.cmake") export(PACKAGE libevent) # Generate the config file for the build-tree. @@ -1371,70 +1319,47 @@ set(LIBEVENT_INCLUDE_DIRS CACHE PATH "Libevent include directories") configure_file(${PROJECT_SOURCE_DIR}/cmake/LibeventConfigBuildTree.cmake.in - ${PROJECT_BINARY_DIR}/LibeventConfig.cmake - @ONLY) + ${PROJECT_BINARY_DIR}/LibeventConfig.cmake + @ONLY) # Generate the config file for the installation tree. +# Calculate the relative directory from the Cmake dir. file(RELATIVE_PATH - REL_INCLUDE_DIR - "${EVENT_INSTALL_CMAKE_DIR}" - "${EVENT_INSTALL_INCLUDE_DIR}") # Calculate the relative directory from the Cmake dir. + REL_INCLUDE_DIR + "${EVENT_INSTALL_CMAKE_DIR}" + "${CMAKE_INSTALL_PREFIX}/include") # Note the EVENT_CMAKE_DIR is defined in LibeventConfig.cmake.in, # we escape it here so it's evaluated when it is included instead # so that the include dirs are givenrelative to where the # config file is located. -set(EVENT__INCLUDE_DIRS - "\${EVENT_CMAKE_DIR}/${REL_INCLUDE_DIR}") +set(EVENT__INCLUDE_DIRS "\${EVENT_CMAKE_DIR}/${REL_INCLUDE_DIR}") configure_file(${PROJECT_SOURCE_DIR}/cmake/LibeventConfig.cmake.in - ${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/LibeventConfig.cmake - @ONLY) + ${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/LibeventConfig.cmake + @ONLY) # Generate version info for both build-tree and install-tree. configure_file(${PROJECT_SOURCE_DIR}/cmake/LibeventConfigVersion.cmake.in - ${PROJECT_BINARY_DIR}/LibeventConfigVersion.cmake - @ONLY) - -# Define the public headers. -set_target_properties(event event_core event_extra - PROPERTIES PUBLIC_HEADER "${HDR_PUBLIC}") - -# -# Install targets. -# -install(TARGETS event event_core event_extra - EXPORT LibeventTargets - RUNTIME DESTINATION "${EVENT_INSTALL_BIN_DIR}" COMPONENT bin - LIBRARY DESTINATION "${EVENT_INSTALL_LIB_DIR}" COMPONENT lib - ARCHIVE DESTINATION "${EVENT_INSTALL_LIB_DIR}" COMPONENT lib - PUBLIC_HEADER DESTINATION "${EVENT_INSTALL_INCLUDE_DIR}/event2" COMPONENT dev) + ${PROJECT_BINARY_DIR}/LibeventConfigVersion.cmake + @ONLY) # Install compat headers install(FILES ${HDR_COMPAT} - DESTINATION - "${EVENT_INSTALL_INCLUDE_DIR}" - COMPONENT dev) + DESTINATION "include" + COMPONENT dev) # Install the configs. install(FILES - ${PROJECT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/LibeventConfig.cmake - ${PROJECT_BINARY_DIR}/LibeventConfigVersion.cmake - DESTINATION - "${EVENT_INSTALL_CMAKE_DIR}" + ${PROJECT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/LibeventConfig.cmake + ${PROJECT_BINARY_DIR}/LibeventConfigVersion.cmake + DESTINATION "${EVENT_INSTALL_CMAKE_DIR}" COMPONENT dev) # Install exports for the install-tree. install(EXPORT LibeventTargets - DESTINATION - "${EVENT_INSTALL_CMAKE_DIR}" - COMPONENT dev) - -set(LIBEVENT_LIBRARIES - event - event_core - event_extra - CACHE STRING "Libevent libraries") + DESTINATION "${DEF_INSTALL_CMAKE_DIR}" + COMPONENT dev) message(STATUS "") message(STATUS " ---( Libevent " ${EVENT_VERSION} " )---") diff --git a/README.md b/README.md index 150bfe0d..9134e298 100644 --- a/README.md +++ b/README.md @@ -26,21 +26,9 @@ The following Libevent specific Cmake variables are as follows (the values being the default). ``` -# Installation directory for executables -EVENT_INSTALL_BIN_DIR:PATH=bin - # Installation directory for CMake files EVENT_INSTALL_CMAKE_DIR:PATH=lib/cmake/libevent -## Installation directory for header files -EVENT_INSTALL_INCLUDE_DIR:PATH=include - -## Installation directory for libraries -EVENT_INSTALL_LIB_DIR:PATH=lib - -## Define if libevent should be built with shared libraries instead of archives -EVENT__BUILD_SHARED_LIBRARIES:BOOL=OFF - # Enable running gcov to get a test coverage report (only works with # GCC/CLang). Make sure to enable -DCMAKE_BUILD_TYPE=Debug as well. EVENT__COVERAGE:BOOL=OFF diff --git a/bufferevent-internal.h b/bufferevent-internal.h index 9960aefa..b448eead 100644 --- a/bufferevent-internal.h +++ b/bufferevent-internal.h @@ -314,13 +314,16 @@ extern const struct bufferevent_ops bufferevent_ops_async; #endif /** Initialize the shared parts of a bufferevent. */ +EVENT2_EXPORT_SYMBOL int bufferevent_init_common_(struct bufferevent_private *, struct event_base *, const struct bufferevent_ops *, enum bufferevent_options options); /** For internal use: temporarily stop all reads on bufev, until the conditions * in 'what' are over. */ +EVENT2_EXPORT_SYMBOL void bufferevent_suspend_read_(struct bufferevent *bufev, bufferevent_suspend_flags what); /** For internal use: clear the conditions 'what' on bufev, and re-enable * reading if there are no conditions left. */ +EVENT2_EXPORT_SYMBOL void bufferevent_unsuspend_read_(struct bufferevent *bufev, bufferevent_suspend_flags what); /** For internal use: temporarily stop all writes on bufev, until the conditions @@ -347,16 +350,19 @@ void bufferevent_unsuspend_write_(struct bufferevent *bufev, bufferevent_suspend @return 0 if successful, or -1 if an error occurred @see bufferevent_disable() */ +EVENT2_EXPORT_SYMBOL int bufferevent_disable_hard_(struct bufferevent *bufev, short event); /** Internal: Set up locking on a bufferevent. If lock is set, use it. * Otherwise, use a new lock. */ +EVENT2_EXPORT_SYMBOL int bufferevent_enable_locking_(struct bufferevent *bufev, void *lock); /** Internal: backwards compat macro for the now public function * Increment the reference count on bufev. */ #define bufferevent_incref_(bufev) bufferevent_incref(bufev) /** Internal: Lock bufev and increase its reference count. * unlocking it otherwise. */ +EVENT2_EXPORT_SYMBOL void bufferevent_incref_and_lock_(struct bufferevent *bufev); /** Internal: backwards compat macro for the now public function * Decrement the reference count on bufev. Returns 1 if it freed @@ -365,17 +371,21 @@ void bufferevent_incref_and_lock_(struct bufferevent *bufev); /** Internal: Drop the reference count on bufev, freeing as necessary, and * unlocking it otherwise. Returns 1 if it freed the bufferevent. */ +EVENT2_EXPORT_SYMBOL int bufferevent_decref_and_unlock_(struct bufferevent *bufev); /** Internal: If callbacks are deferred and we have a read callback, schedule * a readcb. Otherwise just run the readcb. Ignores watermarks. */ +EVENT2_EXPORT_SYMBOL void bufferevent_run_readcb_(struct bufferevent *bufev, int options); /** Internal: If callbacks are deferred and we have a write callback, schedule * a writecb. Otherwise just run the writecb. Ignores watermarks. */ +EVENT2_EXPORT_SYMBOL void bufferevent_run_writecb_(struct bufferevent *bufev, int options); /** Internal: If callbacks are deferred and we have an eventcb, schedule * it to run with events "what". Otherwise just run the eventcb. * See bufferevent_trigger_event for meaning of "options". */ +EVENT2_EXPORT_SYMBOL void bufferevent_run_eventcb_(struct bufferevent *bufev, short what, int options); /** Internal: Run or schedule (if deferred or options contain @@ -399,6 +409,7 @@ bufferevent_trigger_nolock_(struct bufferevent *bufev, short iotype, int options /** Internal: Add the event 'ev' with timeout tv, unless tv is set to 0, in * which case add ev with no timeout. */ +EVENT2_EXPORT_SYMBOL int bufferevent_add_event_(struct event *ev, const struct timeval *tv); /* ========= @@ -408,16 +419,21 @@ int bufferevent_add_event_(struct event *ev, const struct timeval *tv); /** Internal use: Set up the ev_read and ev_write callbacks so that * the other "generic_timeout" functions will work on it. Call this from * the constructor function. */ +EVENT2_EXPORT_SYMBOL void bufferevent_init_generic_timeout_cbs_(struct bufferevent *bev); /** Internal use: Add or delete the generic timeout events as appropriate. * (If an event is enabled and a timeout is set, we add the event. Otherwise * we delete it.) Call this from anything that changes the timeout values, * that enabled EV_READ or EV_WRITE, or that disables EV_READ or EV_WRITE. */ +EVENT2_EXPORT_SYMBOL int bufferevent_generic_adj_timeouts_(struct bufferevent *bev); +EVENT2_EXPORT_SYMBOL int bufferevent_generic_adj_existing_timeouts_(struct bufferevent *bev); +EVENT2_EXPORT_SYMBOL enum bufferevent_options bufferevent_get_options_(struct bufferevent *bev); +EVENT2_EXPORT_SYMBOL const struct sockaddr* bufferevent_socket_get_conn_address_(struct bufferevent *bev); @@ -465,11 +481,15 @@ bufferevent_socket_get_conn_address_(struct bufferevent *bev); /* ==== For rate-limiting. */ +EVENT2_EXPORT_SYMBOL int bufferevent_decrement_write_buckets_(struct bufferevent_private *bev, ev_ssize_t bytes); +EVENT2_EXPORT_SYMBOL int bufferevent_decrement_read_buckets_(struct bufferevent_private *bev, ev_ssize_t bytes); +EVENT2_EXPORT_SYMBOL ev_ssize_t bufferevent_get_read_max_(struct bufferevent_private *bev); +EVENT2_EXPORT_SYMBOL ev_ssize_t bufferevent_get_write_max_(struct bufferevent_private *bev); int bufferevent_ratelim_init_(struct bufferevent_private *bev); diff --git a/cmake/AddEventLibrary.cmake b/cmake/AddEventLibrary.cmake new file mode 100644 index 00000000..8cf72d24 --- /dev/null +++ b/cmake/AddEventLibrary.cmake @@ -0,0 +1,108 @@ +include(CMakeParseArguments) + +set(LIBEVENT_SHARED_LIBRARIES "") +set(LIBEVENT_STATIC_LIBRARIES "") + +macro(set_event_lib_properties LIB_NAME) + set_target_properties("${LIB_NAME}_static" PROPERTIES ${ARGN}) + set_target_properties("${LIB_NAME}_shared" PROPERTIES ${ARGN}) +endmacro() + +macro(set_event_shared_lib_flags LIB_NAME) + set_target_properties("${LIB_NAME}_shared" PROPERTIES + COMPILE_FLAGS ${ARGN}) + set_target_properties("${LIB_NAME}_shared" PROPERTIES + LINK_FLAGS ${ARGN}) +endmacro() + +macro(generate_pkgconfig LIB_NAME) + set(prefix ${CMAKE_INSTALL_PREFIX}) + set(exec_prefix ${CMAKE_INSTALL_PREFIX}) + set(libdir ${CMAKE_INSTALL_PREFIX}/lib) + set(includedir ${CMAKE_INSTALL_PREFIX}/include) + + set(VERSION ${EVENT_ABI_LIBVERSION}) + + set(LIBS "") + foreach (LIB ${LIB_PLATFORM}) + set(OPENSSL_LIBS "${LIBS} -L${LIB}") + endforeach() + + set(OPENSSL_LIBS "") + foreach(LIB ${OPENSSL_LIBRARIES}) + set(OPENSSL_LIBS "${LIBS} -L${LIB}") + endforeach() + + configure_file("lib${LIB_NAME}.pc.in" "lib${LIB_NAME}.pc" @ONLY) + install( + FILES "${CMAKE_CURRENT_BINARY_DIR}/lib${LIB_NAME}.pc" + DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/pkgconfig" + ) +endmacro() + + +# Global variables that it uses: +# - EVENT_ABI_LIBVERSION +# - CMAKE_THREAD_LIBS_INIT LIB_PLATFORM +# - OPENSSL_LIBRARIES +# - HDR_PUBLIC +# - EVENT_INSTALL_INCLUDE_DIR +# - EVENT_SHARED_FLAGS +# +# Exported variables: +# - LIBEVENT_SHARED_LIBRARIES +# - LIBEVENT_STATIC_LIBRARIES +macro(add_event_library LIB_NAME) + cmake_parse_arguments(LIB + "" # Options + "VERSION" # One val + "SOURCES;LIBRARIES" # Multi val + ${ARGN} + ) + + add_library("${LIB_NAME}_static" STATIC ${LIB_SOURCES}) + add_library("${LIB_NAME}_shared" SHARED ${LIB_SOURCES}) + + target_link_libraries("${LIB_NAME}_shared" + ${CMAKE_THREAD_LIBS_INIT} + ${LIB_PLATFORM} + ${LIB_LIBRARIES}) + + if (EVENT_SHARED_FLAGS) + set_event_shared_lib_flags("${LIB_NAME}" "${EVENT_SHARED_FLAGS}") + endif() + + set_event_lib_properties("${LIB_NAME}" + OUTPUT_NAME "${LIB_NAME}" + CLEAN_DIRECT_OUTPUT 1 + ) + + set_target_properties( + "${LIB_NAME}_shared" PROPERTIES + PUBLIC_HEADER "${HDR_PUBLIC}") + set_target_properties( + "${LIB_NAME}_static" PROPERTIES + PUBLIC_HEADER "${HDR_PUBLIC}") + + set_target_properties( + "${LIB_NAME}_shared" PROPERTIES + SOVERSION ${EVENT_ABI_LIBVERSION} + ) + + export(TARGETS "${LIB_NAME}_static" "${LIB_NAME}_shared" + FILE "${PROJECT_BINARY_DIR}/LibeventTargets.cmake" + ) + + install(TARGETS "${LIB_NAME}_static" "${LIB_NAME}_shared" + EXPORT LibeventTargets + LIBRARY DESTINATION "lib" COMPONENT lib + ARCHIVE DESTINATION "lib" COMPONENT lib + PUBLIC_HEADER DESTINATION "include/event2" + COMPONENT dev + ) + + list(APPEND LIBEVENT_SHARED_LIBRARIES "${LIB_NAME}_shared") + list(APPEND LIBEVENT_STATIC_LIBRARIES "${LIB_NAME}_static") + + generate_pkgconfig("${LIB_NAME}") +endmacro() diff --git a/cmake/LibeventConfig.cmake.in b/cmake/LibeventConfig.cmake.in index b28cacb5..54223360 100644 --- a/cmake/LibeventConfig.cmake.in +++ b/cmake/LibeventConfig.cmake.in @@ -1,7 +1,8 @@ # - Config file for the Libevent package # It defines the following variables -# LIBEVENT_INCLUDE_DIRS - include directories for FooBar -# LIBEVENT_LIBRARIES - libraries to link against +# LIBEVENT_INCLUDE_DIRS - include directories +# LIBEVENT_STATIC_LIBRARIES - libraries to link against (archive/static) +# LIBEVENT_SHARED_LIBRARIES - libraries to link against (shared) # Get the path of the current file. get_filename_component(LIBEVENT_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) @@ -13,5 +14,5 @@ set(LIBEVENT_INCLUDE_DIRS "@EVENT_INSTALL_INCLUDE_DIR@") include(${LIBEVENT_CMAKE_DIR}/LibeventTargets.cmake) # IMPORTED targets from LibeventTargets.cmake -set(LIBEVENT_LIBRARIES event event_core event_extra) - +set(LIBEVENT_STATIC_LIBRARIES "@LIBEVENT_STATIC_LIBRARIES@") +set(LIBEVENT_SHARED_LIBRARIES "@LIBEVENT_SHARED_LIBRARIES@") diff --git a/defer-internal.h b/defer-internal.h index e3c7d7da..d6f80a11 100644 --- a/defer-internal.h +++ b/defer-internal.h @@ -46,6 +46,7 @@ typedef void (*deferred_cb_fn)(struct event_callback *, void *); @param cb The function to run when the struct event_callback executes. @param arg The function's second argument. */ +EVENT2_EXPORT_SYMBOL void event_deferred_cb_init_(struct event_callback *, ev_uint8_t, deferred_cb_fn, void *); /** Change the priority of a non-pending event_callback. @@ -54,12 +55,14 @@ void event_deferred_cb_set_priority_(struct event_callback *, ev_uint8_t); /** Cancel a struct event_callback if it is currently scheduled in an event_base. */ +EVENT2_EXPORT_SYMBOL void event_deferred_cb_cancel_(struct event_base *, struct event_callback *); /** Activate a struct event_callback if it is not currently scheduled in an event_base. Return true if it was not previously scheduled. */ +EVENT2_EXPORT_SYMBOL int event_deferred_cb_schedule_(struct event_base *, struct event_callback *); #ifdef __cplusplus diff --git a/event-config.h.cmake b/event-config.h.cmake index 65a0f5dd..f1786929 100644 --- a/event-config.h.cmake +++ b/event-config.h.cmake @@ -524,6 +524,4 @@ /* Define to `int' if does not define. */ #define EVENT__ssize_t @EVENT__ssize_t@ -#cmakedefine EVENT__NEED_DLLIMPORT 1 - #endif /* \EVENT2_EVENT_CONFIG_H_INCLUDED_ */ diff --git a/event-internal.h b/event-internal.h index 66dcfc32..08a2bde1 100644 --- a/event-internal.h +++ b/event-internal.h @@ -421,16 +421,19 @@ int event_del_nolock_(struct event *ev, int blocking); int event_remove_timer_nolock_(struct event *ev); void event_active_nolock_(struct event *ev, int res, short count); +EVENT2_EXPORT_SYMBOL int event_callback_activate_(struct event_base *, struct event_callback *); int event_callback_activate_nolock_(struct event_base *, struct event_callback *); int event_callback_cancel_(struct event_base *base, struct event_callback *evcb); void event_callback_finalize_nolock_(struct event_base *base, unsigned flags, struct event_callback *evcb, void (*cb)(struct event_callback *, void *)); +EVENT2_EXPORT_SYMBOL void event_callback_finalize_(struct event_base *base, unsigned flags, struct event_callback *evcb, void (*cb)(struct event_callback *, void *)); int event_callback_finalize_many_(struct event_base *base, int n_cbs, struct event_callback **evcb, void (*cb)(struct event_callback *, void *)); +EVENT2_EXPORT_SYMBOL void event_active_later_(struct event *ev, int res); void event_active_later_nolock_(struct event *ev, int res); int event_callback_activate_later_nolock_(struct event_base *base, @@ -441,6 +444,7 @@ void event_callback_init_(struct event_base *base, struct event_callback *cb); /* FIXME document. */ +EVENT2_EXPORT_SYMBOL void event_base_add_virtual_(struct event_base *base); void event_base_del_virtual_(struct event_base *base); @@ -450,6 +454,7 @@ void event_base_del_virtual_(struct event_base *base); Returns on success; aborts on failure. */ +EVENT2_EXPORT_SYMBOL void event_base_assert_ok_(struct event_base *base); void event_base_assert_ok_nolock_(struct event_base *base); diff --git a/event.c b/event.c index 7230d1ab..89579a6b 100644 --- a/event.c +++ b/event.c @@ -123,6 +123,7 @@ static const struct eventop *eventops[] = { }; /* Global state; deprecated */ +EVENT2_EXPORT_SYMBOL struct event_base *event_global_current_base_ = NULL; #define current_base event_global_current_base_ diff --git a/event_tagging.c b/event_tagging.c index 6459dfa7..b021e8c8 100644 --- a/event_tagging.c +++ b/event_tagging.c @@ -93,9 +93,13 @@ a final padding nibble with value 0 is appended. */ +EVENT2_EXPORT_SYMBOL int evtag_decode_int(ev_uint32_t *pnumber, struct evbuffer *evbuf); +EVENT2_EXPORT_SYMBOL int evtag_decode_int64(ev_uint64_t *pnumber, struct evbuffer *evbuf); +EVENT2_EXPORT_SYMBOL int evtag_encode_tag(struct evbuffer *evbuf, ev_uint32_t tag); +EVENT2_EXPORT_SYMBOL int evtag_decode_tag(ev_uint32_t *ptag, struct evbuffer *evbuf); void diff --git a/evthread-internal.h b/evthread-internal.h index efdecf81..bd573296 100644 --- a/evthread-internal.h +++ b/evthread-internal.h @@ -49,9 +49,12 @@ struct event_base; #if ! defined(EVENT__DISABLE_THREAD_SUPPORT) && defined(EVTHREAD_EXPOSE_STRUCTS) /* Global function pointers to lock-related functions. NULL if locking isn't enabled. */ +EVENT2_EXPORT_SYMBOL extern struct evthread_lock_callbacks evthread_lock_fns_; +EVENT2_EXPORT_SYMBOL extern struct evthread_condition_callbacks evthread_cond_fns_; extern unsigned long (*evthread_id_fn_)(void); +EVENT2_EXPORT_SYMBOL extern int evthread_lock_debugging_enabled_; /** Return the ID of the current thread, or 1 if threading isn't enabled. */ @@ -355,6 +358,7 @@ EVLOCK_TRY_LOCK_(void *lock) EVLOCK_UNLOCK(lock1_tmplock_,mode1); \ } while (0) +EVENT2_EXPORT_SYMBOL int evthread_is_debug_lock_held_(void *lock); void *evthread_debug_get_real_lock_(void *lock); @@ -377,6 +381,7 @@ int evutil_global_setup_locks_(const int enable_locks); int evutil_secure_rng_global_setup_locks_(const int enable_locks); /** Return current evthread_lock_callbacks */ +EVENT2_EXPORT_SYMBOL struct evthread_lock_callbacks *evthread_get_lock_callbacks(void); /** Return current evthread_condition_callbacks */ struct evthread_condition_callbacks *evthread_get_condition_callbacks(void); diff --git a/evthread.c b/evthread.c index f3f1eddc..3eac594d 100644 --- a/evthread.c +++ b/evthread.c @@ -46,7 +46,7 @@ #endif #ifndef EVENT__DISABLE_DEBUG_MODE -extern int event_debug_created_threadable_ctx_; +extern int event_debug_created_threadable_ctx_; extern int event_debug_mode_on_; #endif diff --git a/http-internal.h b/http-internal.h index 45555171..b7d21ef9 100644 --- a/http-internal.h +++ b/http-internal.h @@ -184,12 +184,15 @@ int evhttp_connection_connect_(struct evhttp_connection *); enum evhttp_request_error; /* notifies the current request that it failed; resets connection */ +EVENT2_EXPORT_SYMBOL void evhttp_connection_fail_(struct evhttp_connection *, enum evhttp_request_error error); enum message_read_status; +EVENT2_EXPORT_SYMBOL enum message_read_status evhttp_parse_firstline_(struct evhttp_request *, struct evbuffer*); +EVENT2_EXPORT_SYMBOL enum message_read_status evhttp_parse_headers_(struct evhttp_request *, struct evbuffer*); void evhttp_start_read_(struct evhttp_connection *); @@ -199,6 +202,7 @@ void evhttp_start_write_(struct evhttp_connection *); void evhttp_response_code_(struct evhttp_request *, int, const char *); void evhttp_send_page_(struct evhttp_request *, struct evbuffer *); +EVENT2_EXPORT_SYMBOL int evhttp_decode_uri_internal(const char *uri, size_t length, char *ret, int decode_plus); diff --git a/include/event2/bufferevent_compat.h b/include/event2/bufferevent_compat.h index 65482042..a5a3c720 100644 --- a/include/event2/bufferevent_compat.h +++ b/include/event2/bufferevent_compat.h @@ -28,6 +28,8 @@ #ifndef EVENT2_BUFFEREVENT_COMPAT_H_INCLUDED_ #define EVENT2_BUFFEREVENT_COMPAT_H_INCLUDED_ +#include + #define evbuffercb bufferevent_data_cb #define everrorcb bufferevent_event_cb @@ -72,6 +74,7 @@ error occurred @see bufferevent_base_set(), bufferevent_free() */ +EVENT2_EXPORT_SYMBOL struct bufferevent *bufferevent_new(evutil_socket_t fd, evbuffercb readcb, evbuffercb writecb, everrorcb errorcb, void *cbarg); @@ -83,6 +86,7 @@ struct bufferevent *bufferevent_new(evutil_socket_t fd, @param timeout_read the read timeout @param timeout_write the write timeout */ +EVENT2_EXPORT_SYMBOL void bufferevent_settimeout(struct bufferevent *bufev, int timeout_read, int timeout_write); diff --git a/include/event2/dns_compat.h b/include/event2/dns_compat.h index 965fd654..a58c4b29 100644 --- a/include/event2/dns_compat.h +++ b/include/event2/dns_compat.h @@ -49,6 +49,7 @@ extern "C" { /* For int types. */ #include +#include /** Initialize the asynchronous DNS library. @@ -66,6 +67,7 @@ extern "C" { @return 0 if successful, or -1 if an error occurred @see evdns_shutdown() */ +EVENT2_EXPORT_SYMBOL int evdns_init(void); struct evdns_base; @@ -76,6 +78,7 @@ struct evdns_base; @deprecated This function is deprecated because use of the global evdns_base is error-prone. */ +EVENT2_EXPORT_SYMBOL struct evdns_base *evdns_get_global_base(void); /** @@ -93,6 +96,7 @@ struct evdns_base *evdns_get_global_base(void); active requests will return DNS_ERR_SHUTDOWN. @see evdns_init() */ +EVENT2_EXPORT_SYMBOL void evdns_shutdown(int fail_requests); /** @@ -109,6 +113,7 @@ void evdns_shutdown(int fail_requests); @return 0 if successful, or -1 if an error occurred @see evdns_nameserver_ip_add() */ +EVENT2_EXPORT_SYMBOL int evdns_nameserver_add(unsigned long int address); /** @@ -126,6 +131,7 @@ int evdns_nameserver_add(unsigned long int address); @return the number of configured nameservers @see evdns_nameserver_add() */ +EVENT2_EXPORT_SYMBOL int evdns_count_nameservers(void); /** @@ -140,6 +146,7 @@ int evdns_count_nameservers(void); @return 0 if successful, or -1 if an error occurred @see evdns_resume() */ +EVENT2_EXPORT_SYMBOL int evdns_clear_nameservers_and_suspend(void); /** @@ -155,6 +162,7 @@ int evdns_clear_nameservers_and_suspend(void); @return 0 if successful, or -1 if an error occurred @see evdns_clear_nameservers_and_suspend() */ +EVENT2_EXPORT_SYMBOL int evdns_resume(void); /** @@ -170,6 +178,7 @@ int evdns_resume(void); @return 0 if successful, or -1 if an error occurred @see evdns_nameserver_add() */ +EVENT2_EXPORT_SYMBOL int evdns_nameserver_ip_add(const char *ip_as_string); /** @@ -186,6 +195,7 @@ int evdns_nameserver_ip_add(const char *ip_as_string); @return 0 if successful, or -1 if an error occurred @see evdns_resolve_ipv6(), evdns_resolve_reverse(), evdns_resolve_reverse_ipv6() */ +EVENT2_EXPORT_SYMBOL int evdns_resolve_ipv4(const char *name, int flags, evdns_callback_type callback, void *ptr); /** @@ -198,6 +208,7 @@ int evdns_resolve_ipv4(const char *name, int flags, evdns_callback_type callback @return 0 if successful, or -1 if an error occurred @see evdns_resolve_ipv4(), evdns_resolve_reverse(), evdns_resolve_reverse_ipv6() */ +EVENT2_EXPORT_SYMBOL int evdns_resolve_ipv6(const char *name, int flags, evdns_callback_type callback, void *ptr); struct in_addr; @@ -217,6 +228,7 @@ struct in6_addr; @return 0 if successful, or -1 if an error occurred @see evdns_resolve_reverse_ipv6() */ +EVENT2_EXPORT_SYMBOL int evdns_resolve_reverse(const struct in_addr *in, int flags, evdns_callback_type callback, void *ptr); /** @@ -233,6 +245,7 @@ int evdns_resolve_reverse(const struct in_addr *in, int flags, evdns_callback_ty @return 0 if successful, or -1 if an error occurred @see evdns_resolve_reverse_ipv6() */ +EVENT2_EXPORT_SYMBOL int evdns_resolve_reverse_ipv6(const struct in6_addr *in, int flags, evdns_callback_type callback, void *ptr); /** @@ -251,6 +264,7 @@ int evdns_resolve_reverse_ipv6(const struct in6_addr *in, int flags, evdns_callb @param flags Ignored. @return 0 if successful, or -1 if an error occurred */ +EVENT2_EXPORT_SYMBOL int evdns_set_option(const char *option, const char *val, int flags); /** @@ -278,6 +292,7 @@ int evdns_set_option(const char *option, const char *val, int flags); occurred (see above) @see resolv.conf(3), evdns_config_windows_nameservers() */ +EVENT2_EXPORT_SYMBOL int evdns_resolv_conf_parse(int flags, const char *const filename); /** @@ -287,6 +302,7 @@ int evdns_resolv_conf_parse(int flags, const char *const filename); caller to specify which evdns_base it applies to. The recommended function is evdns_base_search_clear(). */ +EVENT2_EXPORT_SYMBOL void evdns_search_clear(void); /** @@ -298,6 +314,7 @@ void evdns_search_clear(void); @param domain the domain to be added to the search list */ +EVENT2_EXPORT_SYMBOL void evdns_search_add(const char *domain); /** @@ -312,6 +329,7 @@ void evdns_search_add(const char *domain); @param ndots the new ndots parameter */ +EVENT2_EXPORT_SYMBOL void evdns_search_ndots_set(const int ndots); /** @@ -322,9 +340,13 @@ void evdns_search_ndots_set(const int ndots); function is evdns_add_server_port_with_base(). */ -struct evdns_server_port *evdns_add_server_port(evutil_socket_t socket, int flags, evdns_request_callback_fn_type callback, void *user_data); +EVENT2_EXPORT_SYMBOL +struct evdns_server_port * +evdns_add_server_port(evutil_socket_t socket, int flags, + evdns_request_callback_fn_type callback, void *user_data); #ifdef _WIN32 +EVENT2_EXPORT_SYMBOL int evdns_config_windows_nameservers(void); #define EVDNS_CONFIG_WINDOWS_NAMESERVERS_IMPLEMENTED #endif diff --git a/include/event2/http_compat.h b/include/event2/http_compat.h index 43c2c43e..a9eb5972 100644 --- a/include/event2/http_compat.h +++ b/include/event2/http_compat.h @@ -58,6 +58,7 @@ extern "C" { * @param port the port number on which the HTTP server should listen * @return an struct evhttp object */ +EVENT2_EXPORT_SYMBOL struct evhttp *evhttp_start(const char *address, ev_uint16_t port); /** @@ -67,6 +68,7 @@ struct evhttp *evhttp_start(const char *address, ev_uint16_t port); * * @deprecated It does not allow an event base to be specified */ +EVENT2_EXPORT_SYMBOL struct evhttp_connection *evhttp_connection_new( const char *address, ev_uint16_t port); @@ -76,6 +78,7 @@ struct evhttp_connection *evhttp_connection_new( * * @deprecated XXXX Why? */ +EVENT2_EXPORT_SYMBOL void evhttp_connection_set_base(struct evhttp_connection *evcon, struct event_base *base); diff --git a/include/event2/rpc.h b/include/event2/rpc.h index dd43df26..9c55b513 100644 --- a/include/event2/rpc.h +++ b/include/event2/rpc.h @@ -27,6 +27,8 @@ #ifndef EVENT2_RPC_H_INCLUDED_ #define EVENT2_RPC_H_INCLUDED_ +#include + #ifdef __cplusplus extern "C" { #endif @@ -178,6 +180,7 @@ EVRPC_STRUCT(rpcname) { \ struct evhttp_request* http_req; \ struct evbuffer* rpc_data; \ }; \ +EVENT2_EXPORT_SYMBOL \ int evrpc_send_request_##rpcname(struct evrpc_pool *, \ struct reqstruct *, struct rplystruct *, \ void (*)(struct evrpc_status *, \ @@ -187,6 +190,7 @@ int evrpc_send_request_##rpcname(struct evrpc_pool *, \ struct evrpc_pool; /** use EVRPC_GENERATE instead */ +EVENT2_EXPORT_SYMBOL struct evrpc_request_wrapper *evrpc_make_request_ctx( struct evrpc_pool *pool, void *request, void *reply, const char *rpcname, @@ -257,10 +261,13 @@ struct evrpc_request_wrapper *evrpc_make_request_ctx( #define EVRPC_REQUEST_HTTP(rpc_req) (rpc_req)->http_req /** completes the server response to an rpc request */ +EVENT2_EXPORT_SYMBOL void evrpc_request_done(struct evrpc_req_generic *req); /** accessors for request and reply */ +EVENT2_EXPORT_SYMBOL void *evrpc_get_request(struct evrpc_req_generic *req); +EVENT2_EXPORT_SYMBOL void *evrpc_get_reply(struct evrpc_req_generic *req); /** Creates the reply to an RPC request @@ -288,6 +295,7 @@ struct evhttp; * @return a newly allocated evrpc_base struct * @see evrpc_free() */ +EVENT2_EXPORT_SYMBOL struct evrpc_base *evrpc_init(struct evhttp *server); /** @@ -298,6 +306,7 @@ struct evrpc_base *evrpc_init(struct evhttp *server); * @param base the evrpc_base object to be freed * @see evrpc_init */ +EVENT2_EXPORT_SYMBOL void evrpc_free(struct evrpc_base *base); /** register RPCs with the HTTP Server @@ -334,6 +343,7 @@ void evrpc_free(struct evrpc_base *base); @see EVRPC_REGISTER() */ +EVENT2_EXPORT_SYMBOL int evrpc_register_rpc(struct evrpc_base *, struct evrpc *, void (*)(struct evrpc_req_generic*, void *), void *); @@ -347,6 +357,7 @@ int evrpc_register_rpc(struct evrpc_base *, struct evrpc *, */ #define EVRPC_UNREGISTER(base, name) evrpc_unregister_rpc((base), #name) +EVENT2_EXPORT_SYMBOL int evrpc_unregister_rpc(struct evrpc_base *base, const char *name); /* @@ -385,6 +396,7 @@ struct evrpc_status; @returns 0 on success, -1 otherwise. @see EVRPC_MAKE_REQUEST(), EVRPC_MAKE_CTX() */ +EVENT2_EXPORT_SYMBOL int evrpc_make_request(struct evrpc_request_wrapper *ctx); /** creates an rpc connection pool @@ -397,12 +409,14 @@ int evrpc_make_request(struct evrpc_request_wrapper *ctx); * @return a newly allocated struct evrpc_pool object * @see evrpc_pool_free() */ +EVENT2_EXPORT_SYMBOL struct evrpc_pool *evrpc_pool_new(struct event_base *base); /** frees an rpc connection pool * * @param pool a pointer to an evrpc_pool allocated via evrpc_pool_new() * @see evrpc_pool_new() */ +EVENT2_EXPORT_SYMBOL void evrpc_pool_free(struct evrpc_pool *pool); /** @@ -413,6 +427,7 @@ void evrpc_pool_free(struct evrpc_pool *pool); * @param pool the pool to which to add the connection * @param evcon the connection to add to the pool. */ +EVENT2_EXPORT_SYMBOL void evrpc_pool_add_connection(struct evrpc_pool *pool, struct evhttp_connection *evcon); @@ -424,6 +439,7 @@ void evrpc_pool_add_connection(struct evrpc_pool *pool, * @param pool the pool from which to remove the connection * @param evcon the connection to remove from the pool. */ +EVENT2_EXPORT_SYMBOL void evrpc_pool_remove_connection(struct evrpc_pool *pool, struct evhttp_connection *evcon); @@ -442,6 +458,7 @@ void evrpc_pool_remove_connection(struct evrpc_pool *pool, * @param timeout_in_secs the number of seconds after which a request should * timeout and a failure be returned to the callback. */ +EVENT2_EXPORT_SYMBOL void evrpc_pool_set_timeout(struct evrpc_pool *pool, int timeout_in_secs); /** @@ -489,6 +506,7 @@ enum EVRPC_HOOK_RESULT { * @return a handle to the hook so it can be removed later * @see evrpc_remove_hook() */ +EVENT2_EXPORT_SYMBOL void *evrpc_add_hook(void *vbase, enum EVRPC_HOOK_TYPE hook_type, int (*cb)(void *, struct evhttp_request *, struct evbuffer *, void *), @@ -502,6 +520,7 @@ void *evrpc_add_hook(void *vbase, * @return 1 on success or 0 on failure * @see evrpc_add_hook() */ +EVENT2_EXPORT_SYMBOL int evrpc_remove_hook(void *vbase, enum EVRPC_HOOK_TYPE hook_type, void *handle); @@ -511,8 +530,8 @@ int evrpc_remove_hook(void *vbase, * @param vbase a pointer to either struct evrpc_base or struct evrpc_pool * @param ctx the context pointer provided to the original hook call */ -int -evrpc_resume_request(void *vbase, void *ctx, enum EVRPC_HOOK_RESULT res); +EVENT2_EXPORT_SYMBOL +int evrpc_resume_request(void *vbase, void *ctx, enum EVRPC_HOOK_RESULT res); /** adds meta data to request * @@ -525,6 +544,7 @@ evrpc_resume_request(void *vbase, void *ctx, enum EVRPC_HOOK_RESULT res); * @param data the data to be associated with the key * @param data_size the size of the data */ +EVENT2_EXPORT_SYMBOL void evrpc_hook_add_meta(void *ctx, const char *key, const void *data, size_t data_size); @@ -538,6 +558,7 @@ void evrpc_hook_add_meta(void *ctx, const char *key, * @param data_size pointer to the size of the data * @return 0 on success or -1 on failure */ +EVENT2_EXPORT_SYMBOL int evrpc_hook_find_meta(void *ctx, const char *key, void **data, size_t *data_size); @@ -547,6 +568,7 @@ int evrpc_hook_find_meta(void *ctx, const char *key, * @param ctx the context provided to the hook call * @return a pointer to the evhttp_connection object */ +EVENT2_EXPORT_SYMBOL struct evhttp_connection *evrpc_hook_get_connection(void *ctx); /** @@ -556,6 +578,7 @@ struct evhttp_connection *evrpc_hook_get_connection(void *ctx); @see EVRPC_MAKE_REQUEST() */ +EVENT2_EXPORT_SYMBOL int evrpc_send_request_generic(struct evrpc_pool *pool, void *request, void *reply, void (*cb)(struct evrpc_status *, void *, void *, void *), @@ -572,8 +595,8 @@ int evrpc_send_request_generic(struct evrpc_pool *pool, @see EVRPC_REGISTER() */ -int -evrpc_register_generic(struct evrpc_base *base, const char *name, +EVENT2_EXPORT_SYMBOL +int evrpc_register_generic(struct evrpc_base *base, const char *name, void (*callback)(struct evrpc_req_generic *, void *), void *cbarg, void *(*req_new)(void *), void *req_new_arg, void (*req_free)(void *), int (*req_unmarshal)(void *, struct evbuffer *), @@ -582,9 +605,12 @@ evrpc_register_generic(struct evrpc_base *base, const char *name, void (*rpl_marshal)(struct evbuffer *, void *)); /** accessors for obscure and undocumented functionality */ +EVENT2_EXPORT_SYMBOL struct evrpc_pool* evrpc_request_get_pool(struct evrpc_request_wrapper *ctx); +EVENT2_EXPORT_SYMBOL void evrpc_request_set_pool(struct evrpc_request_wrapper *ctx, struct evrpc_pool *pool); +EVENT2_EXPORT_SYMBOL void evrpc_request_set_cb(struct evrpc_request_wrapper *ctx, void (*cb)(struct evrpc_status*, void *request, void *reply, void *arg), void *cb_arg); diff --git a/include/event2/visibility.h b/include/event2/visibility.h index fb16dbee..74d259a9 100644 --- a/include/event2/visibility.h +++ b/include/event2/visibility.h @@ -29,7 +29,11 @@ #include -#if defined(event_EXPORTS) || defined(event_extra_EXPORTS) || defined(event_core_EXPORTS) +#if defined(event_shared_EXPORTS) || \ + defined(event_extra_shared_EXPORTS) || \ + defined(event_core_shared_EXPORTS) || \ + defined(event_pthreads_shared_EXPORTS) || \ + defined(event_openssl_shared_EXPORTS) # if defined (__SUNPRO_C) && (__SUNPRO_C >= 0x550) # define EVENT2_EXPORT_SYMBOL __global # elif defined __GNUC__ @@ -40,7 +44,7 @@ # define EVENT2_EXPORT_SYMBOL /* unknown compiler */ # endif #else -# if defined(EVENT__NEED_DLLIMPORT) && defined(_MSC_VER) && !defined(EVENT_BUILDING_REGRESS_TEST) +# if defined(_MSC_VER) && !defined(EVENT_BUILDING_REGRESS_TEST) # define EVENT2_EXPORT_SYMBOL extern __declspec(dllimport) # else # define EVENT2_EXPORT_SYMBOL diff --git a/iocp-internal.h b/iocp-internal.h index 93dbe2b1..089754d6 100644 --- a/iocp-internal.h +++ b/iocp-internal.h @@ -181,6 +181,7 @@ struct event_base; struct event_iocp_port *event_base_get_iocp_(struct event_base *base); /* FIXME document. */ +EVENT2_EXPORT_SYMBOL int event_base_start_iocp_(struct event_base *base, int n_cpus); void event_base_stop_iocp_(struct event_base *base); diff --git a/log-internal.h b/log-internal.h index 330478a9..e92fa88d 100644 --- a/log-internal.h +++ b/log-internal.h @@ -47,6 +47,7 @@ #ifdef EVENT_DEBUG_LOGGING_ENABLED #ifdef USE_GLOBAL_FOR_DEBUG_LOGGING +EVENT2_EXPORT_SYMBOL extern ev_uint32_t event_debug_logging_mask_; #define event_debug_get_logging_mask_() (event_debug_logging_mask_) #else @@ -56,15 +57,24 @@ ev_uint32_t event_debug_get_logging_mask_(void); #define event_debug_get_logging_mask_() (0) #endif +EVENT2_EXPORT_SYMBOL void event_err(int eval, const char *fmt, ...) EV_CHECK_FMT(2,3) EV_NORETURN; +EVENT2_EXPORT_SYMBOL void event_warn(const char *fmt, ...) EV_CHECK_FMT(1,2); +EVENT2_EXPORT_SYMBOL void event_sock_err(int eval, evutil_socket_t sock, const char *fmt, ...) EV_CHECK_FMT(3,4) EV_NORETURN; +EVENT2_EXPORT_SYMBOL void event_sock_warn(evutil_socket_t sock, const char *fmt, ...) EV_CHECK_FMT(2,3); +EVENT2_EXPORT_SYMBOL void event_errx(int eval, const char *fmt, ...) EV_CHECK_FMT(2,3) EV_NORETURN; +EVENT2_EXPORT_SYMBOL void event_warnx(const char *fmt, ...) EV_CHECK_FMT(1,2); +EVENT2_EXPORT_SYMBOL void event_msgx(const char *fmt, ...) EV_CHECK_FMT(1,2); +EVENT2_EXPORT_SYMBOL void event_debugx_(const char *fmt, ...) EV_CHECK_FMT(1,2); +EVENT2_EXPORT_SYMBOL void event_logv_(int severity, const char *errstr, const char *fmt, va_list ap) EV_CHECK_FMT(3,0); diff --git a/mm-internal.h b/mm-internal.h index 4ba6fce4..7a95c995 100644 --- a/mm-internal.h +++ b/mm-internal.h @@ -43,6 +43,7 @@ extern "C" { * On failure, set errno to ENOMEM and return NULL. * If the argument sz is 0, simply return NULL. */ +EVENT2_EXPORT_SYMBOL void *event_mm_malloc_(size_t sz); /** Allocate memory initialized to zero. @@ -53,6 +54,7 @@ void *event_mm_malloc_(size_t sz); * set errno to ENOMEM and return NULL. * If either arguments are 0, simply return NULL. */ +EVENT2_EXPORT_SYMBOL void *event_mm_calloc_(size_t count, size_t size); /** Duplicate a string. @@ -63,9 +65,12 @@ void *event_mm_calloc_(size_t count, size_t size); * occurs (or would occur) in the process. * If the argument str is NULL, set errno to EINVAL and return NULL. */ +EVENT2_EXPORT_SYMBOL char *event_mm_strdup_(const char *str); +EVENT2_EXPORT_SYMBOL void *event_mm_realloc_(void *p, size_t sz); +EVENT2_EXPORT_SYMBOL void event_mm_free_(void *p); #define mm_malloc(sz) event_mm_malloc_(sz) #define mm_calloc(count, size) event_mm_calloc_((count), (size)) diff --git a/strlcpy-internal.h b/strlcpy-internal.h index cfc27ec6..4151d601 100644 --- a/strlcpy-internal.h +++ b/strlcpy-internal.h @@ -6,10 +6,12 @@ extern "C" { #endif #include "event2/event-config.h" +#include "event2/visibility.h" #include "evconfig-private.h" #ifndef EVENT__HAVE_STRLCPY #include +EVENT2_EXPORT_SYMBOL size_t event_strlcpy_(char *dst, const char *src, size_t siz); #define strlcpy event_strlcpy_ #endif diff --git a/time-internal.h b/time-internal.h index 2c584fa7..e79e6a52 100644 --- a/time-internal.h +++ b/time-internal.h @@ -54,6 +54,7 @@ extern "C" { #endif long evutil_tv_to_msec_(const struct timeval *tv); +EVENT2_EXPORT_SYMBOL void evutil_usleep_(const struct timeval *tv); #ifdef _WIN32 @@ -86,8 +87,10 @@ struct evutil_monotonic_timer { struct timeval last_time; }; +EVENT2_EXPORT_SYMBOL int evutil_configure_monotonic_time_(struct evutil_monotonic_timer *mt, int flags); +EVENT2_EXPORT_SYMBOL int evutil_gettime_monotonic_(struct evutil_monotonic_timer *mt, struct timeval *tv); diff --git a/util-internal.h b/util-internal.h index 77e17ab0..7ae42fa0 100644 --- a/util-internal.h +++ b/util-internal.h @@ -233,19 +233,26 @@ extern "C" { * when you care about ASCII's notion of character types, because you are about * to send those types onto the wire. */ +EVENT2_EXPORT_SYMBOL int EVUTIL_ISALPHA_(char c); +EVENT2_EXPORT_SYMBOL int EVUTIL_ISALNUM_(char c); int EVUTIL_ISSPACE_(char c); +EVENT2_EXPORT_SYMBOL int EVUTIL_ISDIGIT_(char c); +EVENT2_EXPORT_SYMBOL int EVUTIL_ISXDIGIT_(char c); int EVUTIL_ISPRINT_(char c); int EVUTIL_ISLOWER_(char c); int EVUTIL_ISUPPER_(char c); +EVENT2_EXPORT_SYMBOL char EVUTIL_TOUPPER_(char c); +EVENT2_EXPORT_SYMBOL char EVUTIL_TOLOWER_(char c); /** Remove all trailing horizontal whitespace (space or tab) from the end of a * string */ +EVENT2_EXPORT_SYMBOL void evutil_rtrim_lws_(char *); @@ -272,13 +279,16 @@ void evutil_rtrim_lws_(char *); */ int evutil_open_closeonexec_(const char *pathname, int flags, unsigned mode); +EVENT2_EXPORT_SYMBOL int evutil_read_file_(const char *filename, char **content_out, size_t *len_out, int is_binary); +EVENT2_EXPORT_SYMBOL int evutil_socket_connect_(evutil_socket_t *fd_ptr, const struct sockaddr *sa, int socklen); int evutil_socket_finished_connecting_(evutil_socket_t fd); +EVENT2_EXPORT_SYMBOL int evutil_ersatz_socketpair_(int, int , int, evutil_socket_t[]); int evutil_resolve_(int family, const char *hostname, struct sockaddr *sa, @@ -303,15 +313,18 @@ struct evutil_weakrand_state { * attacker can't predict, or which passes strong statistical tests, use the * evutil_secure_rng* functions instead. */ +EVENT2_EXPORT_SYMBOL ev_uint32_t evutil_weakrand_seed_(struct evutil_weakrand_state *state, ev_uint32_t seed); /* Return a pseudorandom value between 0 and EVUTIL_WEAKRAND_MAX inclusive. * Updates the state in 'seed' as needed -- this value must be protected by a * lock. */ +EVENT2_EXPORT_SYMBOL ev_int32_t evutil_weakrand_(struct evutil_weakrand_state *seed); /* Return a pseudorandom value x such that 0 <= x < top. top must be no more * than EVUTIL_WEAKRAND_MAX. Updates the state in 'seed' as needed -- this * value must be proteced by a lock */ +EVENT2_EXPORT_SYMBOL ev_int32_t evutil_weakrand_range_(struct evutil_weakrand_state *seed, ev_int32_t top); /* Evaluates to the same boolean value as 'p', and hints to the compiler that @@ -377,16 +390,22 @@ typedef struct evdns_getaddrinfo_request* (*evdns_getaddrinfo_fn)( const char *nodename, const char *servname, const struct evutil_addrinfo *hints_in, void (*cb)(int, struct evutil_addrinfo *, void *), void *arg); +EVENT2_EXPORT_SYMBOL void evutil_set_evdns_getaddrinfo_fn_(evdns_getaddrinfo_fn fn); typedef void (*evdns_getaddrinfo_cancel_fn)( struct evdns_getaddrinfo_request *req); +EVENT2_EXPORT_SYMBOL void evutil_set_evdns_getaddrinfo_cancel_fn_(evdns_getaddrinfo_cancel_fn fn); +EVENT2_EXPORT_SYMBOL struct evutil_addrinfo *evutil_new_addrinfo_(struct sockaddr *sa, ev_socklen_t socklen, const struct evutil_addrinfo *hints); +EVENT2_EXPORT_SYMBOL struct evutil_addrinfo *evutil_addrinfo_append_(struct evutil_addrinfo *first, struct evutil_addrinfo *append); +EVENT2_EXPORT_SYMBOL void evutil_adjust_hints_for_addrconfig_(struct evutil_addrinfo *hints); +EVENT2_EXPORT_SYMBOL int evutil_getaddrinfo_common_(const char *nodename, const char *servname, struct evutil_addrinfo *hints, struct evutil_addrinfo **res, int *portnum); @@ -399,6 +418,7 @@ void evutil_getaddrinfo_cancel_async_(struct evdns_getaddrinfo_request *data); /** Return true iff sa is a looback address. (That is, it is 127.0.0.1/8, or * ::1). */ +EVENT2_EXPORT_SYMBOL int evutil_sockaddr_is_loopback_(const struct sockaddr *sa); @@ -407,6 +427,7 @@ int evutil_sockaddr_is_loopback_(const struct sockaddr *sa); Returns a pointer to out. Always writes something into out, so it's safe to use the output of this function without checking it for NULL. */ +EVENT2_EXPORT_SYMBOL const char *evutil_format_sockaddr_port_(const struct sockaddr *sa, char *out, size_t outlen); int evutil_hex_char_to_int_(char c); @@ -464,6 +485,7 @@ HMODULE evutil_load_windows_system_library_(const TCHAR *library_name); #endif #endif +EVENT2_EXPORT_SYMBOL evutil_socket_t evutil_socket_(int domain, int type, int protocol); evutil_socket_t evutil_accept4_(evutil_socket_t sockfd, struct sockaddr *addr, ev_socklen_t *addrlen, int flags); -- cgit v1.2.1 From cc554d87cefd99b8a5a8f4a65e32cafcbce09972 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 13 Mar 2017 21:40:52 +0300 Subject: cmake: fix pkgconfig generation (copy-paste typo) (cherry picked from commit 882f537c409d9c51ede581a3e13de7519227edb7) --- cmake/AddEventLibrary.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/AddEventLibrary.cmake b/cmake/AddEventLibrary.cmake index 8cf72d24..23a8d4ca 100644 --- a/cmake/AddEventLibrary.cmake +++ b/cmake/AddEventLibrary.cmake @@ -25,12 +25,12 @@ macro(generate_pkgconfig LIB_NAME) set(LIBS "") foreach (LIB ${LIB_PLATFORM}) - set(OPENSSL_LIBS "${LIBS} -L${LIB}") + set(LIBS "${LIBS} -L${LIB}") endforeach() set(OPENSSL_LIBS "") foreach(LIB ${OPENSSL_LIBRARIES}) - set(OPENSSL_LIBS "${LIBS} -L${LIB}") + set(OPENSSL_LIBS "${OPENSSL_LIBS} -L${LIB}") endforeach() configure_file("lib${LIB_NAME}.pc.in" "lib${LIB_NAME}.pc" @ONLY) -- cgit v1.2.1 From ebd12e6de7b4f8bf93383192b2477a06a4b35238 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 14 Mar 2017 13:31:02 +0300 Subject: Merge branch 'win32-fixes' This patchset fixes win32 builds after some previous patches (referenced in particular commits), and also removes some quirks for win32. * win32-fixes: test: do not return void log/win32: fix exporting extern variable log-internal: missing extern "C" log: remove USE_GLOBAL_FOR_DEBUG_LOGGING cmake: Export missing symbols for win32 cmake: eliminate EVENT_BUILDING_REGRESS_TEST, since we link with shared libs test: windows doesn't have WNOWAIT cmake: clean not used #defines from event-config.h cmake: add only for non-win32 (cherry picked from commit d84f0205453941235b0e04729098d4329c189bba) --- CMakeLists.txt | 15 +++--------- WIN32-Code/nmake/event2/event-config.h | 3 --- event-config.h.cmake | 16 ------------ evthread-internal.h | 9 +++++++ include/event2/visibility.h | 14 +++++++++-- iocp-internal.h | 13 ++++++++++ log-internal.h | 18 ++++++++------ log.c | 10 +------- test/regress.c | 40 +++++++++++++++++++----------- test/regress_dns.c | 12 ++------- test/regress_http.c | 45 +++++++++++++++++----------------- util-internal.h | 1 + 12 files changed, 100 insertions(+), 96 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 28b40a97..48f8c5c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -476,7 +476,9 @@ else() endif() if (NOT EVENT__DISABLE_THREAD_SUPPORT) - list(APPEND CMAKE_EXTRA_INCLUDE_FILES pthread.h) + if (NOT WIN32) + list(APPEND CMAKE_EXTRA_INCLUDE_FILES pthread.h) + endif() CHECK_TYPE_SIZE(pthread_t EVENT__SIZEOF_PTHREAD_T) endif() @@ -497,7 +499,6 @@ CHECK_TYPE_SIZE("void *" EVENT__SIZEOF_VOID_P) # - ellzey #CHECK_FILE_OFFSET_BITS() -#set(EVENT___FILE_OFFSET_BITS _FILE_OFFSET_BITS) # Verify kqueue works with pipes. if (EVENT__HAVE_KQUEUE) @@ -982,19 +983,11 @@ if (NOT EVENT__DISABLE_TESTS) add_executable(regress ${SRC_REGRESS}) - # While building the test suite we don't want the visibility - # header trying to "dllimport" the symbols on windows (it - # generates a ton of warnings due to different link - # attributes for all of the symbols) - set_target_properties(regress - PROPERTIES COMPILE_DEFINITIONS - "EVENT_BUILDING_REGRESS_TEST=1") - target_link_libraries(regress ${LIB_APPS} ${LIB_PLATFORM} event_core_shared - event_extra_static) + event_extra_shared) if (NOT EVENT__DISABLE_OPENSSL) target_link_libraries(regress event_openssl_shared) endif() diff --git a/WIN32-Code/nmake/event2/event-config.h b/WIN32-Code/nmake/event2/event-config.h index e6ed3aa4..a3664aa2 100644 --- a/WIN32-Code/nmake/event2/event-config.h +++ b/WIN32-Code/nmake/event2/event-config.h @@ -336,9 +336,6 @@ /* Define to appropriate substitue if compiler doesnt have __func__ */ #define EVENT____func__ __FUNCTION__ -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef EVENT__const */ - /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef _EVENT___cplusplus diff --git a/event-config.h.cmake b/event-config.h.cmake index f1786929..b7f0be57 100644 --- a/event-config.h.cmake +++ b/event-config.h.cmake @@ -480,22 +480,6 @@ #endif -#ifdef __THESE_ARE_NOT_CONFIG_H_THINGS_THEY_ARE_DASH_D_THINGS__ -/* Number of bits in a file offset, on hosts where this is settable. */ -/* Ellzey is not satisfied */ -#define EVENT___FILE_OFFSET_BITS @EVENT___FILE_OFFSET_BITS@ - -/* Define for large files, on AIX-style hosts. */ -#define @_LARGE_FILES@ -#endif - -#ifdef _WhAT_DOES_THIS_EVEN_DO_ -/* Define to empty if `const' does not conform to ANSI C. */ -/* lolwut? - ellzey */ -#undef EVENT__const -#endif - - /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus diff --git a/evthread-internal.h b/evthread-internal.h index bd573296..5fdf3161 100644 --- a/evthread-internal.h +++ b/evthread-internal.h @@ -185,14 +185,23 @@ EVLOCK_TRY_LOCK_(void *lock) #elif ! defined(EVENT__DISABLE_THREAD_SUPPORT) unsigned long evthreadimpl_get_id_(void); +EVENT2_EXPORT_SYMBOL int evthreadimpl_is_lock_debugging_enabled_(void); +EVENT2_EXPORT_SYMBOL void *evthreadimpl_lock_alloc_(unsigned locktype); +EVENT2_EXPORT_SYMBOL void evthreadimpl_lock_free_(void *lock, unsigned locktype); +EVENT2_EXPORT_SYMBOL int evthreadimpl_lock_lock_(unsigned mode, void *lock); +EVENT2_EXPORT_SYMBOL int evthreadimpl_lock_unlock_(unsigned mode, void *lock); +EVENT2_EXPORT_SYMBOL void *evthreadimpl_cond_alloc_(unsigned condtype); +EVENT2_EXPORT_SYMBOL void evthreadimpl_cond_free_(void *cond); +EVENT2_EXPORT_SYMBOL int evthreadimpl_cond_signal_(void *cond, int broadcast); +EVENT2_EXPORT_SYMBOL int evthreadimpl_cond_wait_(void *cond, void *lock, const struct timeval *tv); int evthreadimpl_locking_enabled_(void); diff --git a/include/event2/visibility.h b/include/event2/visibility.h index 74d259a9..af30905d 100644 --- a/include/event2/visibility.h +++ b/include/event2/visibility.h @@ -34,6 +34,7 @@ defined(event_core_shared_EXPORTS) || \ defined(event_pthreads_shared_EXPORTS) || \ defined(event_openssl_shared_EXPORTS) + # if defined (__SUNPRO_C) && (__SUNPRO_C >= 0x550) # define EVENT2_EXPORT_SYMBOL __global # elif defined __GNUC__ @@ -43,12 +44,21 @@ # else # define EVENT2_EXPORT_SYMBOL /* unknown compiler */ # endif -#else -# if defined(_MSC_VER) && !defined(EVENT_BUILDING_REGRESS_TEST) + +#else /* event_*_EXPORTS */ + +# if defined(_MSC_VER) # define EVENT2_EXPORT_SYMBOL extern __declspec(dllimport) # else # define EVENT2_EXPORT_SYMBOL # endif + +#endif /* event_*_EXPORTS */ + +#if defined(_MSC_VER) +# define EVENT2_EXPORT_SYMBOL_DECL __declspec(dllimport) +#else +# define EVENT2_EXPORT_SYMBOL_DECL extern #endif #endif /* EVENT2_VISIBILITY_H_INCLUDED_ */ diff --git a/iocp-internal.h b/iocp-internal.h index 089754d6..21e0e0af 100644 --- a/iocp-internal.h +++ b/iocp-internal.h @@ -92,6 +92,7 @@ struct event_iocp_port { HANDLE *shutdownSemaphore; }; +EVENT2_EXPORT_SYMBOL const struct win32_extension_fns *event_get_win32_extension_fns_(void); #else /* Dummy definition so we can test-compile more things on unix. */ @@ -106,12 +107,14 @@ struct event_overlapped { @param cb The callback that should be invoked once the IO operation has finished. */ +EVENT2_EXPORT_SYMBOL void event_overlapped_init_(struct event_overlapped *, iocp_callback cb); /** Allocate and return a new evbuffer that supports overlapped IO on a given socket. The socket must be associated with an IO completion port using event_iocp_port_associate_. */ +EVENT2_EXPORT_SYMBOL struct evbuffer *evbuffer_overlapped_new_(evutil_socket_t fd); /** XXXX Document (nickm) */ @@ -131,6 +134,7 @@ void evbuffer_overlapped_set_fd_(struct evbuffer *buf, evutil_socket_t fd); @param ol Overlapped object with associated completion callback. @return 0 on success, -1 on error. */ +EVENT2_EXPORT_SYMBOL int evbuffer_launch_read_(struct evbuffer *buf, size_t n, struct event_overlapped *ol); /** Start writing data from the start of an evbuffer. @@ -145,21 +149,26 @@ int evbuffer_launch_read_(struct evbuffer *buf, size_t n, struct event_overlappe @param ol Overlapped object with associated completion callback. @return 0 on success, -1 on error. */ +EVENT2_EXPORT_SYMBOL int evbuffer_launch_write_(struct evbuffer *buf, ev_ssize_t n, struct event_overlapped *ol); /** XXX document */ +EVENT2_EXPORT_SYMBOL void evbuffer_commit_read_(struct evbuffer *, ev_ssize_t); +EVENT2_EXPORT_SYMBOL void evbuffer_commit_write_(struct evbuffer *, ev_ssize_t); /** Create an IOCP, and launch its worker threads. Internal use only. This interface is unstable, and will change. */ +EVENT2_EXPORT_SYMBOL struct event_iocp_port *event_iocp_port_launch_(int n_cpus); /** Associate a file descriptor with an iocp, such that overlapped IO on the fd will happen on one of the iocp's worker threads. */ +EVENT2_EXPORT_SYMBOL int event_iocp_port_associate_(struct event_iocp_port *port, evutil_socket_t fd, ev_uintptr_t key); @@ -169,15 +178,18 @@ int event_iocp_port_associate_(struct event_iocp_port *port, evutil_socket_t fd, 0. Otherwise, return -1. If you get a -1 return value, it is safe to call this function again. */ +EVENT2_EXPORT_SYMBOL int event_iocp_shutdown_(struct event_iocp_port *port, long waitMsec); /* FIXME document. */ +EVENT2_EXPORT_SYMBOL int event_iocp_activate_overlapped_(struct event_iocp_port *port, struct event_overlapped *o, ev_uintptr_t key, ev_uint32_t n_bytes); struct event_base; /* FIXME document. */ +EVENT2_EXPORT_SYMBOL struct event_iocp_port *event_base_get_iocp_(struct event_base *base); /* FIXME document. */ @@ -186,6 +198,7 @@ int event_base_start_iocp_(struct event_base *base, int n_cpus); void event_base_stop_iocp_(struct event_base *base); /* FIXME document. */ +EVENT2_EXPORT_SYMBOL struct bufferevent *bufferevent_async_new_(struct event_base *base, evutil_socket_t fd, int options); diff --git a/log-internal.h b/log-internal.h index e92fa88d..b9d19f13 100644 --- a/log-internal.h +++ b/log-internal.h @@ -29,6 +29,10 @@ #include "event2/util.h" +#ifdef __cplusplus +extern "C" { +#endif + #ifdef __GNUC__ #define EV_CHECK_FMT(a,b) __attribute__((format(printf, a, b))) #define EV_NORETURN __attribute__((noreturn)) @@ -39,21 +43,15 @@ #define EVENT_ERR_ABORT_ ((int)0xdeaddead) -#define USE_GLOBAL_FOR_DEBUG_LOGGING - #if !defined(EVENT__DISABLE_DEBUG_MODE) || defined(USE_DEBUG) #define EVENT_DEBUG_LOGGING_ENABLED #endif #ifdef EVENT_DEBUG_LOGGING_ENABLED -#ifdef USE_GLOBAL_FOR_DEBUG_LOGGING -EVENT2_EXPORT_SYMBOL -extern ev_uint32_t event_debug_logging_mask_; +EVENT2_EXPORT_SYMBOL_DECL +ev_uint32_t event_debug_logging_mask_; #define event_debug_get_logging_mask_() (event_debug_logging_mask_) #else -ev_uint32_t event_debug_get_logging_mask_(void); -#endif -#else #define event_debug_get_logging_mask_() (0) #endif @@ -90,4 +88,8 @@ void event_logv_(int severity, const char *errstr, const char *fmt, va_list ap) #undef EV_CHECK_FMT +#ifdef __cplusplus +} #endif + +#endif /* LOG_INTERNAL_H_INCLUDED_ */ diff --git a/log.c b/log.c index e8ae9fdc..ed955575 100644 --- a/log.c +++ b/log.c @@ -69,16 +69,8 @@ static event_fatal_cb fatal_fn = NULL; #define DEFAULT_MASK 0 #endif -#ifdef USE_GLOBAL_FOR_DEBUG_LOGGING +EVENT2_EXPORT_SYMBOL ev_uint32_t event_debug_logging_mask_ = DEFAULT_MASK; -#else -static ev_uint32_t event_debug_logging_mask_ = DEFAULT_MASK; -ev_uint32_t -event_debug_get_logging_mask_(void) -{ - return event_debug_logging_mask_; -} -#endif #endif /* EVENT_DEBUG_LOGGING_ENABLED */ void diff --git a/test/regress.c b/test/regress.c index 94fcbec9..dcfb598c 100644 --- a/test/regress.c +++ b/test/regress.c @@ -848,11 +848,34 @@ simple_child_read_cb(evutil_socket_t fd, short event, void *arg) called++; } + +#define TEST_FORK_EXIT_SUCCESS 76 +static void fork_wait_check(int pid) +{ + int status; + + TT_BLATHER(("Before waitpid")); + +#ifdef WNOWAIT + if ((waitpid(pid, &status, WNOWAIT) == -1 && errno == EINVAL) && +#else + if ( +#endif + waitpid(pid, &status, 0) == -1) { + perror("waitpid"); + exit(1); + } + TT_BLATHER(("After waitpid")); + + if (WEXITSTATUS(status) != TEST_FORK_EXIT_SUCCESS) { + fprintf(stdout, "FAILED (exit): %d\n", WEXITSTATUS(status)); + exit(1); + } +} static void test_fork(void) { char c; - int status; struct event ev, sig_ev, usr_ev, existing_ev; pid_t pid; @@ -917,7 +940,7 @@ test_fork(void) /* we do not send an EOF; simple_read_cb requires an EOF * to set test_ok. we just verify that the callback was * called. */ - exit(test_ok != 0 || called != 2 ? -2 : 76); + exit(test_ok != 0 || called != 2 ? -2 : TEST_FORK_EXIT_SUCCESS); } /** wait until client read first message */ @@ -928,18 +951,7 @@ test_fork(void) tt_fail_perror("write"); } - TT_BLATHER(("Before waitpid")); - if ((waitpid(pid, &status, WNOWAIT) == -1 && errno == EINVAL) && - waitpid(pid, &status, 0) == -1) { - perror("waitpid"); - exit(1); - } - TT_BLATHER(("After waitpid")); - - if (WEXITSTATUS(status) != 76) { - fprintf(stdout, "FAILED (exit): %d\n", WEXITSTATUS(status)); - exit(1); - } + fork_wait_check(pid); /* test that the current event loop still works */ if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) { diff --git a/test/regress_dns.c b/test/regress_dns.c index 8950440f..51dc0093 100644 --- a/test/regress_dns.c +++ b/test/regress_dns.c @@ -612,16 +612,8 @@ end: if (dns) evdns_base_free(dns, 0); } -static void -dns_search_test(void *arg) -{ - return dns_search_test_impl(arg, 0); -} -static void -dns_search_lower_test(void *arg) -{ - return dns_search_test_impl(arg, 1); -} +static void dns_search_test(void *arg) { dns_search_test_impl(arg, 0); } +static void dns_search_lower_test(void *arg) { dns_search_test_impl(arg, 1); } static int request_count = 0; static struct evdns_request *current_req = NULL; diff --git a/test/regress_http.c b/test/regress_http.c index 80100500..e9ead77e 100644 --- a/test/regress_http.c +++ b/test/regress_http.c @@ -545,8 +545,7 @@ http_basic_test_impl(void *arg, int ssl) if (bev) bufferevent_free(bev); } -static void http_basic_test(void *arg) -{ return http_basic_test_impl(arg, 0); } +static void http_basic_test(void *arg) { http_basic_test_impl(arg, 0); } static void @@ -3327,7 +3326,7 @@ http_chunk_out_test_impl(void *arg, int ssl) evhttp_free(http); } static void http_chunk_out_test(void *arg) -{ return http_chunk_out_test_impl(arg, 0); } +{ http_chunk_out_test_impl(arg, 0); } static void http_stream_out_test_impl(void *arg, int ssl) @@ -3373,7 +3372,7 @@ http_stream_out_test_impl(void *arg, int ssl) evhttp_free(http); } static void http_stream_out_test(void *arg) -{ return http_stream_out_test_impl(arg, 0); } +{ http_stream_out_test_impl(arg, 0); } static void http_stream_in_chunk(struct evhttp_request *req, void *arg) @@ -3569,7 +3568,7 @@ http_connection_fail_test_impl(void *arg, int ssl) ; } static void http_connection_fail_test(void *arg) -{ return http_connection_fail_test_impl(arg, 0); } +{ http_connection_fail_test_impl(arg, 0); } static void http_connection_retry_done(struct evhttp_request *req, void *arg) @@ -3641,7 +3640,7 @@ http_simple_test_impl(void *arg, int ssl, int dirty) evhttp_free(http); } static void http_simple_test(void *arg) -{ return http_simple_test_impl(arg, 0, 0); } +{ http_simple_test_impl(arg, 0, 0); } static void http_connection_retry_test_basic(void *arg, const char *addr, struct evdns_base *dns_base, int ssl) @@ -3798,16 +3797,16 @@ http_connection_retry_conn_address_test_impl(void *arg, int ssl) /** dnsserver will be cleaned in http_connection_retry_test_basic() */ } static void http_connection_retry_conn_address_test(void *arg) -{ return http_connection_retry_conn_address_test_impl(arg, 0); } +{ http_connection_retry_conn_address_test_impl(arg, 0); } static void http_connection_retry_test_impl(void *arg, int ssl) { - return http_connection_retry_test_basic(arg, "127.0.0.1", NULL, ssl); + http_connection_retry_test_basic(arg, "127.0.0.1", NULL, ssl); } static void http_connection_retry_test(void *arg) -{ return http_connection_retry_test_impl(arg, 0); } +{ http_connection_retry_test_impl(arg, 0); } static void http_primitives(void *ptr) @@ -4474,7 +4473,7 @@ http_write_during_read_test_impl(void *arg, int ssl) evhttp_free(http); } static void http_write_during_read_test(void *arg) -{ return http_write_during_read_test_impl(arg, 0); } +{ http_write_during_read_test_impl(arg, 0); } static void http_request_own_test(void *arg) @@ -4526,35 +4525,35 @@ http_request_own_test(void *arg) #ifdef EVENT__HAVE_OPENSSL static void https_basic_test(void *arg) -{ return http_basic_test_impl(arg, 1); } +{ http_basic_test_impl(arg, 1); } static void https_filter_basic_test(void *arg) -{ return http_basic_test_impl(arg, 1 | HTTP_SSL_FILTER); } +{ http_basic_test_impl(arg, 1 | HTTP_SSL_FILTER); } static void https_incomplete_test(void *arg) { http_incomplete_test_(arg, 0, 1); } static void https_incomplete_timeout_test(void *arg) { http_incomplete_test_(arg, 1, 1); } static void https_simple_test(void *arg) -{ return http_simple_test_impl(arg, 1, 0); } +{ http_simple_test_impl(arg, 1, 0); } static void https_simple_dirty_test(void *arg) -{ return http_simple_test_impl(arg, 1, 1); } +{ http_simple_test_impl(arg, 1, 1); } static void https_connection_retry_conn_address_test(void *arg) -{ return http_connection_retry_conn_address_test_impl(arg, 1); } +{ http_connection_retry_conn_address_test_impl(arg, 1); } static void https_connection_retry_test(void *arg) -{ return http_connection_retry_test_impl(arg, 1); } +{ http_connection_retry_test_impl(arg, 1); } static void https_chunk_out_test(void *arg) -{ return http_chunk_out_test_impl(arg, 1); } +{ http_chunk_out_test_impl(arg, 1); } static void https_filter_chunk_out_test(void *arg) -{ return http_chunk_out_test_impl(arg, 1 | HTTP_SSL_FILTER); } +{ http_chunk_out_test_impl(arg, 1 | HTTP_SSL_FILTER); } static void https_stream_out_test(void *arg) -{ return http_stream_out_test_impl(arg, 1); } +{ http_stream_out_test_impl(arg, 1); } static void https_connection_fail_test(void *arg) -{ return http_connection_fail_test_impl(arg, 1); } +{ http_connection_fail_test_impl(arg, 1); } static void https_write_during_read_test(void *arg) -{ return http_write_during_read_test_impl(arg, 1); } +{ http_write_during_read_test_impl(arg, 1); } static void https_connection_test(void *arg) -{ return http_connection_test_(arg, 0, "127.0.0.1", NULL, 0, AF_UNSPEC, 1); } +{ http_connection_test_(arg, 0, "127.0.0.1", NULL, 0, AF_UNSPEC, 1); } static void https_persist_connection_test(void *arg) -{ return http_connection_test_(arg, 1, "127.0.0.1", NULL, 0, AF_UNSPEC, 1); } +{ http_connection_test_(arg, 1, "127.0.0.1", NULL, 0, AF_UNSPEC, 1); } #endif struct testcase_t http_testcases[] = { diff --git a/util-internal.h b/util-internal.h index 7ae42fa0..507dceb7 100644 --- a/util-internal.h +++ b/util-internal.h @@ -437,6 +437,7 @@ void evutil_free_secure_rng_globals_(void); void evutil_free_globals_(void); #ifdef _WIN32 +EVENT2_EXPORT_SYMBOL HMODULE evutil_load_windows_system_library_(const TCHAR *library_name); #endif -- cgit v1.2.1 From 5398cbcdedc08dd0c61c1dfd56e69b74b5398e77 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 14 Mar 2017 13:33:31 +0300 Subject: cmake: use APPEND during exporting targets (for old cmake) On centos with cmake 2.8.12.2: CMake Error at cmake/AddEventLibrary.cmake:92 (export): export called with target "event_extra_shared" which requires target "event_core_shared" that is not in the export list. If the required target is not easy to reference in this call, consider using the APPEND option with multiple separate calls. But on newer cmake I guess everything is ok. Fixes: 7182c2f561570cd9ceb704623ebe9ae3608c7b43 ("cmake: build SHARED and STATIC libraries (like autoconf does)") (cherry picked from commit b1e8a4138f0da3c8a4bc303ff72b620b41c066d6) --- cmake/AddEventLibrary.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/AddEventLibrary.cmake b/cmake/AddEventLibrary.cmake index 23a8d4ca..8475e086 100644 --- a/cmake/AddEventLibrary.cmake +++ b/cmake/AddEventLibrary.cmake @@ -91,6 +91,7 @@ macro(add_event_library LIB_NAME) export(TARGETS "${LIB_NAME}_static" "${LIB_NAME}_shared" FILE "${PROJECT_BINARY_DIR}/LibeventTargets.cmake" + APPEND ) install(TARGETS "${LIB_NAME}_static" "${LIB_NAME}_shared" -- cgit v1.2.1 From 7f0a7564c381538f58906ddb3784331ccb305a8c Mon Sep 17 00:00:00 2001 From: Xiang Zhang Date: Thu, 16 Mar 2017 23:32:43 +0800 Subject: fix evutil_make_internal_pipe_'s comment that fd[0] for read and f[1] for write (cherry picked from commit 2e52bace9f9998826bd3819af328efc8d18decf9) --- event-internal.h | 2 +- evutil.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/event-internal.h b/event-internal.h index 08a2bde1..03eb2a87 100644 --- a/event-internal.h +++ b/event-internal.h @@ -219,7 +219,7 @@ struct event_base { /** Function pointers used to describe the backend that this event_base * uses for signals */ const struct eventop *evsigsel; - /** Data to implement the common signal handelr code. */ + /** Data to implement the common signal handler code. */ struct evsig_info sig; /** Number of virtual events */ diff --git a/evutil.c b/evutil.c index 4dd4a2e1..49c9014f 100644 --- a/evutil.c +++ b/evutil.c @@ -2593,7 +2593,7 @@ evutil_accept4_(evutil_socket_t sockfd, struct sockaddr *addr, } /* Internal function: Set fd[0] and fd[1] to a pair of fds such that writes on - * fd[0] get read from fd[1]. Make both fds nonblocking and close-on-exec. + * fd[1] get read from fd[0]. Make both fds nonblocking and close-on-exec. * Return 0 on success, -1 on failure. */ int -- cgit v1.2.1 From 27a2ef5c8bd52f4ce5a59038e12105263d7a5794 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Fri, 24 Mar 2017 16:49:59 +0800 Subject: Make event_count macros cleaner Fixes: #489 (cherry picked from commit 177e2171cb44e3929fbb0ec43b1bffb325b0e8ed) --- event.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/event.c b/event.c index 89579a6b..918b412d 100644 --- a/event.c +++ b/event.c @@ -3150,10 +3150,6 @@ timeout_process(struct event_base *base) } } -#if (EVLIST_INTERNAL >> 4) != 1 -#error "Mismatch for value of EVLIST_INTERNAL" -#endif - #ifndef MAX #define MAX(a,b) (((a)>(b))?(a):(b)) #endif @@ -3161,13 +3157,13 @@ timeout_process(struct event_base *base) #define MAX_EVENT_COUNT(var, v) var = MAX(var, v) /* These are a fancy way to spell - if (flags & EVLIST_INTERNAL) + if (~flags & EVLIST_INTERNAL) base->event_count--/++; */ #define DECR_EVENT_COUNT(base,flags) \ - ((base)->event_count -= (~((flags) >> 4) & 1)) + ((base)->event_count -= !((flags) & EVLIST_INTERNAL)) #define INCR_EVENT_COUNT(base,flags) do { \ - ((base)->event_count += (~((flags) >> 4) & 1)); \ + ((base)->event_count += !((flags) & EVLIST_INTERNAL)); \ MAX_EVENT_COUNT((base)->event_count_max, (base)->event_count); \ } while (0) -- cgit v1.2.1 From 303d6d77c7d66a69462d500857480f7e265eac07 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 27 Mar 2017 15:50:23 +0300 Subject: Fix arc4random_addrandom() detecting and fallback (regression) But this is kind of hot-fix, we definitelly need more sane arc4random compat layer. Fixes: #488 Introduced-in: 6541168 ("Detect arch4random_addrandom() existence") (cherry picked from commit 266f43af7798befa3d27bfabaa9ae699259c3924) --- event-config.h.cmake | 3 +++ include/event2/util.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/event-config.h.cmake b/event-config.h.cmake index b7f0be57..5c233a3d 100644 --- a/event-config.h.cmake +++ b/event-config.h.cmake @@ -53,6 +53,9 @@ /* Define to 1 if you have the `arc4random_buf' function. */ #cmakedefine EVENT__HAVE_ARC4RANDOM_BUF 1 +/* Define to 1 if you have the `arc4random_addrandom' function. */ +#cmakedefine EVENT__HAVE_ARC4RANDOM_ADDRANDOM 1 + /* Define if clock_gettime is available in libc */ #cmakedefine EVENT__DNS_USE_CPU_CLOCK_FOR_ID 1 diff --git a/include/event2/util.h b/include/event2/util.h index c4af2bd6..ca404894 100644 --- a/include/event2/util.h +++ b/include/event2/util.h @@ -842,7 +842,7 @@ int evutil_secure_rng_init(void); EVENT2_EXPORT_SYMBOL int evutil_secure_rng_set_urandom_device_file(char *fname); -#ifdef EVENT__HAVE_ARC4RANDOM_ADDRANDOM +#if !defined(EVENT__HAVE_ARC4RANDOM) || defined(EVENT__HAVE_ARC4RANDOM_ADDRANDOM) /** Seed the random number generator with extra random bytes. You should almost never need to call this function; it should be -- cgit v1.2.1 From 56faf02bae144742b4aa6b173a2ac034d953a7c3 Mon Sep 17 00:00:00 2001 From: Dominic Chen Date: Thu, 13 Apr 2017 14:58:13 -0400 Subject: bufferevent: refactor to use type check macros (cherry picked from commit 92cc0b9c3db38088f79c5d1e432c429fbc366968) --- bufferevent-internal.h | 7 +++++++ bufferevent_async.c | 2 +- bufferevent_filter.c | 4 ++-- bufferevent_openssl.c | 6 +++--- bufferevent_pair.c | 4 ++-- bufferevent_sock.c | 8 ++++---- 6 files changed, 19 insertions(+), 12 deletions(-) diff --git a/bufferevent-internal.h b/bufferevent-internal.h index b448eead..f79e74d3 100644 --- a/bufferevent-internal.h +++ b/bufferevent-internal.h @@ -306,6 +306,13 @@ extern const struct bufferevent_ops bufferevent_ops_pair; #define BEV_IS_FILTER(bevp) ((bevp)->be_ops == &bufferevent_ops_filter) #define BEV_IS_PAIR(bevp) ((bevp)->be_ops == &bufferevent_ops_pair) +#if defined(EVENT__HAVE_OPENSSL) +extern const struct bufferevent_ops bufferevent_ops_openssl; +#define BEV_IS_OPENSSL(bevp) ((bevp)->be_ops == &bufferevent_ops_openssl) +#else +#define BEV_IS_OPENSSL(bevp) 0 +#endif + #ifdef _WIN32 extern const struct bufferevent_ops bufferevent_ops_async; #define BEV_IS_ASYNC(bevp) ((bevp)->be_ops == &bufferevent_ops_async) diff --git a/bufferevent_async.c b/bufferevent_async.c index 6395e57a..1521d896 100644 --- a/bufferevent_async.c +++ b/bufferevent_async.c @@ -104,7 +104,7 @@ static inline struct bufferevent_async * upcast(struct bufferevent *bev) { struct bufferevent_async *bev_a; - if (bev->be_ops != &bufferevent_ops_async) + if (!BEV_IS_ASYNC(bev)) return NULL; bev_a = EVUTIL_UPCAST(bev, struct bufferevent_async, bev.bev); return bev_a; diff --git a/bufferevent_filter.c b/bufferevent_filter.c index b5efd5c0..d9e8540f 100644 --- a/bufferevent_filter.c +++ b/bufferevent_filter.c @@ -118,11 +118,11 @@ static inline struct bufferevent_filtered * upcast(struct bufferevent *bev) { struct bufferevent_filtered *bev_f; - if (bev->be_ops != &bufferevent_ops_filter) + if (!BEV_IS_FILTER(bev)) return NULL; bev_f = (void*)( ((char*)bev) - evutil_offsetof(struct bufferevent_filtered, bev.bev)); - EVUTIL_ASSERT(bev_f->bev.bev.be_ops == &bufferevent_ops_filter); + EVUTIL_ASSERT(BEV_IS_FILTER(&bev_f->bev.bev)); return bev_f; } diff --git a/bufferevent_openssl.c b/bufferevent_openssl.c index da3963af..252627ec 100644 --- a/bufferevent_openssl.c +++ b/bufferevent_openssl.c @@ -354,11 +354,11 @@ static inline struct bufferevent_openssl * upcast(struct bufferevent *bev) { struct bufferevent_openssl *bev_o; - if (bev->be_ops != &bufferevent_ops_openssl) + if (!BEV_IS_OPENSSL(bev)) return NULL; bev_o = (void*)( ((char*)bev) - evutil_offsetof(struct bufferevent_openssl, bev.bev)); - EVUTIL_ASSERT(bev_o->bev.bev.be_ops == &bufferevent_ops_openssl); + EVUTIL_ASSERT(BEV_IS_OPENSSL(&bev_o->bev.bev)); return bev_o; } @@ -803,7 +803,7 @@ consider_reading(struct bufferevent_openssl *bev_ssl) if (bev_ssl->bev.read_suspended) break; - + /* Read all pending data. This won't hit the network * again, and will (most importantly) put us in a state * where we don't need to read anything else until the diff --git a/bufferevent_pair.c b/bufferevent_pair.c index 1e93f572..f88cd751 100644 --- a/bufferevent_pair.c +++ b/bufferevent_pair.c @@ -56,10 +56,10 @@ static inline struct bufferevent_pair * upcast(struct bufferevent *bev) { struct bufferevent_pair *bev_p; - if (bev->be_ops != &bufferevent_ops_pair) + if (!BEV_IS_PAIR(bev)) return NULL; bev_p = EVUTIL_UPCAST(bev, struct bufferevent_pair, bev.bev); - EVUTIL_ASSERT(bev_p->bev.bev.be_ops == &bufferevent_ops_pair); + EVUTIL_ASSERT(BEV_IS_PAIR(&bev_p->bev.bev)); return bev_p; } diff --git a/bufferevent_sock.c b/bufferevent_sock.c index 93aedb33..e305ec55 100644 --- a/bufferevent_sock.c +++ b/bufferevent_sock.c @@ -607,7 +607,7 @@ be_socket_destruct(struct bufferevent *bufev) struct bufferevent_private *bufev_p = EVUTIL_UPCAST(bufev, struct bufferevent_private, bev); evutil_socket_t fd; - EVUTIL_ASSERT(bufev->be_ops == &bufferevent_ops_socket); + EVUTIL_ASSERT(BEV_IS_SOCKET(bufev)); fd = event_get_fd(&bufev->ev_read); @@ -632,7 +632,7 @@ be_socket_setfd(struct bufferevent *bufev, evutil_socket_t fd) EVUTIL_UPCAST(bufev, struct bufferevent_private, bev); BEV_LOCK(bufev); - EVUTIL_ASSERT(bufev->be_ops == &bufferevent_ops_socket); + EVUTIL_ASSERT(BEV_IS_SOCKET(bufev)); event_del(&bufev->ev_read); event_del(&bufev->ev_write); @@ -662,7 +662,7 @@ bufferevent_priority_set(struct bufferevent *bufev, int priority) EVUTIL_UPCAST(bufev, struct bufferevent_private, bev); BEV_LOCK(bufev); - if (bufev->be_ops != &bufferevent_ops_socket) + if (!BEV_IS_SOCKET(bufev)) goto done; if (event_priority_set(&bufev->ev_read, priority) == -1) @@ -685,7 +685,7 @@ bufferevent_base_set(struct event_base *base, struct bufferevent *bufev) int res = -1; BEV_LOCK(bufev); - if (bufev->be_ops != &bufferevent_ops_socket) + if (!BEV_IS_SOCKET(bufev)) goto done; bufev->ev_base = base; -- cgit v1.2.1 From 29b7a516fdd5a71994f37482562f2fd9691959ee Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Thu, 20 Apr 2017 18:03:50 -0400 Subject: Explicitly call SSL_clear when reseting the fd. If reconnecting the via BEV_CTRL_SET_FD, bufferevent_openssl.c expects OpenSSL to reuse the configuration state in the SSL object but retain connection state. This corresponds to the SSL_clear API. The code currently only calls SSL_set_connect_state or SSL_set_accept_state. Due to a quirk in OpenSSL, doing this causes the handshake to implicitly SSL_clear the next time it is entered. However, this, in the intervening time, leaves the SSL object in an odd state as the connection state has not been dropped yet. This behavior also does not appear to be documented by OpenSSL. Instead, call SSL_clear explicitly: https://www.openssl.org/docs/manmaster/man3/SSL_clear.html (cherry picked from commit c6c74ce2652fd02527a1212e36cbfd788962132a) --- bufferevent_openssl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bufferevent_openssl.c b/bufferevent_openssl.c index 252627ec..f7f5c0f1 100644 --- a/bufferevent_openssl.c +++ b/bufferevent_openssl.c @@ -1267,11 +1267,15 @@ be_openssl_set_fd(struct bufferevent_openssl *bev_ssl, switch (state) { case BUFFEREVENT_SSL_ACCEPTING: + if (!SSL_clear(bev_ssl->ssl)) + return -1; SSL_set_accept_state(bev_ssl->ssl); if (set_handshake_callbacks(bev_ssl, fd) < 0) return -1; break; case BUFFEREVENT_SSL_CONNECTING: + if (!SSL_clear(bev_ssl->ssl)) + return -1; SSL_set_connect_state(bev_ssl->ssl); if (set_handshake_callbacks(bev_ssl, fd) < 0) return -1; -- cgit v1.2.1 From 5dbcae8578ba5fe88a18bd62b80c58e175a486ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gon=C3=A7alo=20Ribeiro?= Date: Fri, 28 Apr 2017 19:36:42 +0100 Subject: Correct URL for the libevent logo (cherry picked from commit f988c5ca0eb654a8e60df174abfc63dd9476be5e) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9134e298..24cf618a 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

- libevent logo + libevent logo

-- cgit v1.2.1 From 23db747652a90b49ca699ef64dcbdd1b60447fe3 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 30 Apr 2017 01:11:31 +0300 Subject: test: cover that after event_del() callback will not be scheduled again Refs: #236 Refs: #225 (cherry picked from commit 5ff83989f30daef93a851c2162667375ed1663a5) --- test/regress.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test/regress.c b/test/regress.c index dcfb598c..e4ce98c0 100644 --- a/test/regress.c +++ b/test/regress.c @@ -997,9 +997,9 @@ static void del_wait_cb(evutil_socket_t fd, short event, void *arg) { struct timeval delay = { 0, 300*1000 }; - TT_BLATHER(("Sleeping")); + TT_BLATHER(("Sleeping: %i", test_ok)); evutil_usleep_(&delay); - test_ok = 1; + ++test_ok; } static void @@ -1010,7 +1010,7 @@ test_del_wait(void) setup_test("event_del will wait: "); - event_set(&ev, pair[1], EV_READ, del_wait_cb, &ev); + event_set(&ev, pair[1], EV_READ|EV_PERSIST, del_wait_cb, &ev); event_add(&ev, NULL); pthread_create(&thread, NULL, del_wait_thread, NULL); @@ -1034,6 +1034,8 @@ test_del_wait(void) pthread_join(thread, NULL); + tt_int_op(test_ok, ==, 1); + end: ; } -- cgit v1.2.1 From 876c7ac7ff86a4cf9d772d1bf129b59d0a08d80c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Luis=20Mill=C3=A1n?= Date: Mon, 13 Apr 2015 08:54:52 +0200 Subject: Return from event_del() after the last event callback termination Delete the event from the queue before blocking for the current event callback termination. Ensures that no callback is being executed when event_del() returns, hence making this function a secure mechanism to access data which is handled in the event callack. Fixes: #236 Fixes: #225 Refs: 6b4b77a Fixes: del_wait (cherry picked from commit 0b4b0efdb8ee710ccae5bad320fc24843fd428e5) --- event.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/event.c b/event.c index 918b412d..d2768793 100644 --- a/event.c +++ b/event.c @@ -2780,21 +2780,7 @@ event_del_nolock_(struct event *ev, int blocking) } } - /* If the main thread is currently executing this event's callback, - * and we are not the main thread, then we want to wait until the - * callback is done before we start removing the event. That way, - * when this function returns, it will be safe to free the - * user-supplied argument. */ base = ev->ev_base; -#ifndef EVENT__DISABLE_THREAD_SUPPORT - if (blocking != EVENT_DEL_NOBLOCK && - base->current_event == event_to_event_callback(ev) && - !EVBASE_IN_THREAD(base) && - (blocking == EVENT_DEL_BLOCK || !(ev->ev_events & EV_FINALIZE))) { - ++base->current_event_waiters; - EVTHREAD_COND_WAIT(base->current_event_cond, base->th_base_lock); - } -#endif EVUTIL_ASSERT(!(ev->ev_flags & ~EVLIST_ALL)); @@ -2841,6 +2827,21 @@ event_del_nolock_(struct event *ev, int blocking) event_debug_note_del_(ev); + /* If the main thread is currently executing this event's callback, + * and we are not the main thread, then we want to wait until the + * callback is done before returning. That way, when this function + * returns, it will be safe to free the user-supplied argument. + */ +#ifndef EVENT__DISABLE_THREAD_SUPPORT + if (blocking != EVENT_DEL_NOBLOCK && + base->current_event == event_to_event_callback(ev) && + !EVBASE_IN_THREAD(base) && + (blocking == EVENT_DEL_BLOCK || !(ev->ev_events & EV_FINALIZE))) { + ++base->current_event_waiters; + EVTHREAD_COND_WAIT(base->current_event_cond, base->th_base_lock); + } +#endif + return (res); } -- cgit v1.2.1 From 56a520035becfae9c3f0fc61971a3ebc48f3b072 Mon Sep 17 00:00:00 2001 From: Maximilian Brunner Date: Tue, 25 Apr 2017 23:10:13 +0200 Subject: le-proxy: add missing return statement (UAF) Refs: #501501501501501501501501501 (cherry picked from commit 00ae45fe53e9e01f61f97c90deba1deb6ac1bc9f) --- sample/le-proxy.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sample/le-proxy.c b/sample/le-proxy.c index e2fbf452..aee9ead6 100644 --- a/sample/le-proxy.c +++ b/sample/le-proxy.c @@ -194,6 +194,7 @@ accept_cb(struct evconnlistener *listener, evutil_socket_t fd, perror("Bufferevent_openssl_new"); bufferevent_free(b_out); bufferevent_free(b_in); + return; } b_out = b_ssl; } -- cgit v1.2.1 From 822d6462762b8801a217138e8a7ed9abc09e4abe Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 1 May 2017 21:55:00 +0300 Subject: Add missing print-winsock-errors.c into dist archive Refs: #497 (cherry picked from commit 8d89c212587c560df8cd7089fb1a2fcd2a3dca82) --- test/include.am | 1 + 1 file changed, 1 insertion(+) diff --git a/test/include.am b/test/include.am index eea249f8..132bbcd4 100644 --- a/test/include.am +++ b/test/include.am @@ -12,6 +12,7 @@ EXTRA_DIST+= \ test/regress.gen.h \ test/regress.rpc \ test/rpcgen_wrapper.sh \ + test/print-winsock-errors.c \ test/test.sh TESTPROGRAMS = \ -- cgit v1.2.1 From 300a0dc6e09bc2a8d0fb3e1f4935269f414a8a8d Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 1 May 2017 21:56:27 +0300 Subject: test: do not use .fieldname in structure initializations (fixes win32) Fixes: #497 (cherry picked from commit 15da23cfdbeb5d5b4eeafca0cd93962c26641ae5) --- test/regress_http.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/regress_http.c b/test/regress_http.c index e9ead77e..58ccf1f7 100644 --- a/test/regress_http.c +++ b/test/regress_http.c @@ -3607,7 +3607,7 @@ http_simple_test_impl(void *arg, int ssl, int dirty) struct evhttp_connection *evcon = NULL; struct evhttp_request *req = NULL; struct bufferevent *bev; - struct http_server hs = { .port = 0, .ssl = ssl, }; + struct http_server hs = { 0, ssl, NULL, }; struct evhttp *http = http_setup(&hs.port, data->base, ssl ? HTTP_BIND_SSL : 0); exit_base = data->base; @@ -3650,7 +3650,7 @@ http_connection_retry_test_basic(void *arg, const char *addr, struct evdns_base struct evhttp_request *req = NULL; struct timeval tv, tv_start, tv_end; struct bufferevent *bev; - struct http_server hs = { .port = 0, .ssl = ssl, }; + struct http_server hs = { 0, ssl, NULL, }; struct evhttp *http = http_setup(&hs.port, data->base, ssl ? HTTP_BIND_SSL : 0); exit_base = data->base; -- cgit v1.2.1 From c544222f191e98c0b83837d5186c44720ba36ab4 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 28 May 2017 16:38:20 +0300 Subject: http-connect: exit on error (cherry picked from commit d22e12eefa11aab34b95e8b07b823f3ad0597239) --- sample/http-connect.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sample/http-connect.c b/sample/http-connect.c index a44d001a..af2c86a8 100644 --- a/sample/http-connect.c +++ b/sample/http-connect.c @@ -11,6 +11,7 @@ #define VERIFY(cond) do { \ if (!(cond)) { \ fprintf(stderr, "[error] %s\n", #cond); \ + exit(EXIT_FAILURE); \ } \ } while (0); \ @@ -26,8 +27,11 @@ static void get_cb(struct evhttp_request *req, void *arg) { ev_ssize_t len; struct evbuffer *evbuf; + struct evhttp_connection *evcon; VERIFY(req); + evcon = evhttp_request_get_connection(req); + VERIFY(evcon); evbuf = evhttp_request_get_input_buffer(req); len = evbuffer_get_length(evbuf); @@ -72,7 +76,7 @@ int main(int argc, const char **argv) } { - proxy = evhttp_uri_parse(argv[1]); + VERIFY(proxy = evhttp_uri_parse(argv[1])); VERIFY(evhttp_uri_get_host(proxy)); VERIFY(evhttp_uri_get_port(proxy) > 0); } -- cgit v1.2.1 From 449f5a57467d9ee50abc7f3fccc843446aaf34ea Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 29 May 2017 16:24:48 +0300 Subject: le-proxy: fix compiling under win32 (because of no "inline" in C) Include for regular "inline", since it is used everywhere. (cherry picked from commit 74a2f5935abc78cc9479f649e96c2e090623aa84) --- sample/le-proxy.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sample/le-proxy.c b/sample/le-proxy.c index aee9ead6..c764afc7 100644 --- a/sample/le-proxy.c +++ b/sample/le-proxy.c @@ -30,6 +30,8 @@ #include #include +#include "util-internal.h" +#include #include #include #include -- cgit v1.2.1 From d2a41a50a8ec614294ab9ac1b0ea0796316d5aed Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 29 May 2017 16:32:30 +0300 Subject: cmake: avoid requiring cmake 3.1 on win32 for dns-example Avoid using target_sources() from cmake 3.1, just pass needable sources as list. (cherry picked from commit 346f8e17080f4649986e0d48176c0a0a5618ea98) --- CMakeLists.txt | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 48f8c5c6..a4649115 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,7 +18,7 @@ # cmake -G "Visual Studio 10" .. # start libevent.sln # -if (WIN32 OR APPLE) +if (APPLE) cmake_minimum_required(VERSION 3.1 FATAL_ERROR) else() cmake_minimum_required(VERSION 2.8.3 FATAL_ERROR) @@ -819,6 +819,13 @@ endif() # go away in a future version of Libevent. add_event_library(event SOURCES ${SRC_CORE} ${SRC_EXTRA}) +set(WIN32_GETOPT) +if (WIN32) + list(APPEND WIN32_GETOPT + WIN32-Code/getopt.c + WIN32-Code/getopt_long.c) +endif() + # # Samples. # @@ -841,7 +848,6 @@ macro(add_sample_prog ssl name) endmacro() if (NOT EVENT__DISABLE_SAMPLES) set(SAMPLES - dns-example event-read-fifo hello-world signal-test @@ -862,12 +868,7 @@ if (NOT EVENT__DISABLE_SAMPLES) sample/le-proxy.c) endif() - if (WIN32) - # requires cmake 3.1 - target_sources(dns-example PUBLIC - WIN32-Code/getopt.c - WIN32-Code/getopt_long.c) - endif() + add_sample_prog(OFF dns-example sample/dns-example.c ${WIN32_GETOPT}) endif() # -- cgit v1.2.1 From 3e69029008f8a209d1e2b8479f9ddf8b237e00d9 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 29 May 2017 16:36:24 +0300 Subject: cmake: fix building bench/bench_cascade under win32 (missing getopt) Because of typo in cmake, now rewrote to make it less error prone (since even for non-win32 there are variables overlap). (cherry picked from commit 8b29b136793f3bfdb22fba117527763434363a3f) --- CMakeLists.txt | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a4649115..b40a60e9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -875,25 +875,23 @@ endif() # Benchmarks # macro(add_bench_prog prog) - add_executable(${prog} test/${prog}.c) - if (WIN32) - list(APPEND BENCH_SRC - WIN32-Code/getopt.c - WIN32-Code/getopt_long.c) - endif() - target_link_libraries(${BENCHMARK} + add_executable(${prog} ${ARGN}) + target_link_libraries(${prog} event_extra_static event_core_static ${LIB_APPS} ${LIB_PLATFORM}) - add_dependencies(${BENCHMARK} + add_dependencies(${prog} event_extra_static event_core_static) endmacro() if (NOT EVENT__DISABLE_BENCHMARK) - foreach (BENCHMARK bench bench_cascade bench_http bench_httpclient) - add_bench_prog(${BENCHMARK}) + foreach (BENCHMARK bench_http bench_httpclient) + add_bench_prog(${BENCHMARK} test/${BENCHMARK}.c) endforeach() + + add_bench_prog(bench test/bench.c ${WIN32_GETOPT}) + add_bench_prog(bench_cascade test/bench_cascade.c ${WIN32_GETOPT}) endif() # -- cgit v1.2.1 From 6f749540175120f5114b9c57be87d5b4bf096c2d Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 29 May 2017 18:48:48 +0300 Subject: cmake: set CMP0054 to NEW to avoid variables over expansion (since cmake 3.8) ==> win: CMake Warning (dev) at CMakeLists.txt:782 (elseif): ==> win: Policy CMP0054 is not set: Only interpret if() arguments as variables or ==> win: keywords when unquoted. Run "cmake --help-policy CMP0054" for policy ==> win: details. Use the cmake_policy command to set the policy and suppress this ==> win: warning. ==> win: ==> win: Quoted variables like "MSVC" will no longer be dereferenced when the policy ==> win: is set to NEW. Since the policy is not set the OLD behavior will be used. ==> win: This warning is for project developers. Use -Wno-dev to suppress it. (cherry picked from commit 2773a5ed5e75540d43500e054581ea1fab2132ac) --- CMakeLists.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b40a60e9..638a537c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,6 +23,7 @@ if (APPLE) else() cmake_minimum_required(VERSION 2.8.3 FATAL_ERROR) endif() +cmake_policy(SET CMP0054 NEW) if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release @@ -776,8 +777,8 @@ source_group("Source Extra" FILES ${SRC_EXTRA}) include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}/include) if ((CMAKE_COMPILER_IS_GNUCC) OR - (${CMAKE_C_COMPILER_ID} STREQUAL "Clang") OR - (${CMAKE_C_COMPILER_ID} STREQUAL "AppleClang")) + ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") OR + ("${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang")) set(EVENT_SHARED_FLAGS -fvisibility=hidden) elseif ("${CMAKE_C_COMPILER_ID}" STREQUAL "SunPro") set(EVENT_SHARED_FLAGS -xldscope=hidden) -- cgit v1.2.1 From a1f28e2f9c7ea4524960d54fe44b82a975062d8d Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 29 May 2017 15:04:50 +0300 Subject: Fix visibility issues under (mostly on win32) Refs: #511 Fixes: 7182c2f561570cd9ceb704623ebe9ae3608c7b43 ("cmake: build SHARED and STATIC libraries (like autoconf does)") (cherry picked from commit ce3af533f1b11c4b302d404483f28660eb5d7190) --- include/event2/visibility.h | 14 ++------------ log-internal.h | 3 +-- log.c | 3 +-- 3 files changed, 4 insertions(+), 16 deletions(-) diff --git a/include/event2/visibility.h b/include/event2/visibility.h index af30905d..412a061c 100644 --- a/include/event2/visibility.h +++ b/include/event2/visibility.h @@ -40,25 +40,15 @@ # elif defined __GNUC__ # define EVENT2_EXPORT_SYMBOL __attribute__ ((visibility("default"))) # elif defined(_MSC_VER) -# define EVENT2_EXPORT_SYMBOL extern __declspec(dllexport) +# define EVENT2_EXPORT_SYMBOL __declspec(dllexport) # else # define EVENT2_EXPORT_SYMBOL /* unknown compiler */ # endif #else /* event_*_EXPORTS */ -# if defined(_MSC_VER) -# define EVENT2_EXPORT_SYMBOL extern __declspec(dllimport) -# else -# define EVENT2_EXPORT_SYMBOL -# endif +# define EVENT2_EXPORT_SYMBOL #endif /* event_*_EXPORTS */ -#if defined(_MSC_VER) -# define EVENT2_EXPORT_SYMBOL_DECL __declspec(dllimport) -#else -# define EVENT2_EXPORT_SYMBOL_DECL extern -#endif - #endif /* EVENT2_VISIBILITY_H_INCLUDED_ */ diff --git a/log-internal.h b/log-internal.h index b9d19f13..fb53df41 100644 --- a/log-internal.h +++ b/log-internal.h @@ -48,8 +48,7 @@ extern "C" { #endif #ifdef EVENT_DEBUG_LOGGING_ENABLED -EVENT2_EXPORT_SYMBOL_DECL -ev_uint32_t event_debug_logging_mask_; +EVENT2_EXPORT_SYMBOL extern ev_uint32_t event_debug_logging_mask_; #define event_debug_get_logging_mask_() (event_debug_logging_mask_) #else #define event_debug_get_logging_mask_() (0) diff --git a/log.c b/log.c index ed955575..a9debb86 100644 --- a/log.c +++ b/log.c @@ -69,8 +69,7 @@ static event_fatal_cb fatal_fn = NULL; #define DEFAULT_MASK 0 #endif -EVENT2_EXPORT_SYMBOL -ev_uint32_t event_debug_logging_mask_ = DEFAULT_MASK; +EVENT2_EXPORT_SYMBOL ev_uint32_t event_debug_logging_mask_ = DEFAULT_MASK; #endif /* EVENT_DEBUG_LOGGING_ENABLED */ void -- cgit v1.2.1 From 802be13afd3d6c5ad67784c9ebac2972a8a25a9d Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 29 May 2017 22:11:48 +0300 Subject: Fix event_debug_logging_mask_ exporting on win32 (cherry picked from commit cd285e425a906276efafab901d1b9da0e388be48) --- include/event2/visibility.h | 12 ++++++++++++ log-internal.h | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/include/event2/visibility.h b/include/event2/visibility.h index 412a061c..779eb68d 100644 --- a/include/event2/visibility.h +++ b/include/event2/visibility.h @@ -51,4 +51,16 @@ #endif /* event_*_EXPORTS */ +/** We need to dllimport event_debug_logging_mask_ into event_extra */ +#if defined(_MSC_VER) +# if defined(event_core_shared_EXPORTS) /** from core export */ +# define EVENT2_CORE_EXPORT_SYMBOL __declspec(dllexport) +# elif defined(event_extra_shared_EXPORTS) /** from extra import */ +# define EVENT2_CORE_EXPORT_SYMBOL __declspec(dllimport) +# endif +#endif /* _MSC_VER */ +#if !defined(EVENT2_CORE_EXPORT_SYMBOL) +# define EVENT2_CORE_EXPORT_SYMBOL EVENT2_EXPORT_SYMBOL +#endif + #endif /* EVENT2_VISIBILITY_H_INCLUDED_ */ diff --git a/log-internal.h b/log-internal.h index fb53df41..2c31608b 100644 --- a/log-internal.h +++ b/log-internal.h @@ -48,7 +48,7 @@ extern "C" { #endif #ifdef EVENT_DEBUG_LOGGING_ENABLED -EVENT2_EXPORT_SYMBOL extern ev_uint32_t event_debug_logging_mask_; +EVENT2_CORE_EXPORT_SYMBOL extern ev_uint32_t event_debug_logging_mask_; #define event_debug_get_logging_mask_() (event_debug_logging_mask_) #else #define event_debug_get_logging_mask_() (0) -- cgit v1.2.1 From 59240e83fa21005835852beecfc695680a8d0405 Mon Sep 17 00:00:00 2001 From: Nikolay Edigaryev Date: Fri, 30 Jun 2017 02:27:08 +0500 Subject: Document some obvious cases where a function might also return NULL Closes: #525 (cherry picked from commit 808524252f888303e4e95f09c3f8c225ef08f096) --- include/event2/dns.h | 3 ++- include/event2/event.h | 2 +- include/event2/http.h | 9 ++++++--- include/event2/http_compat.h | 3 ++- include/event2/rpc.h | 8 +++++--- 5 files changed, 16 insertions(+), 9 deletions(-) diff --git a/include/event2/dns.h b/include/event2/dns.h index 17cd86a2..2025b9e6 100644 --- a/include/event2/dns.h +++ b/include/event2/dns.h @@ -615,7 +615,8 @@ typedef void (*evdns_request_callback_fn_type)(struct evdns_server_request *, vo @param callback A function to invoke whenever we get a DNS request on the socket. @param user_data Data to pass to the callback. - @return an evdns_server_port structure for this server port. + @return an evdns_server_port structure for this server port or NULL if + an error occurred. */ EVENT2_EXPORT_SYMBOL struct evdns_server_port *evdns_add_server_port_with_base(struct event_base *base, evutil_socket_t socket, int flags, evdns_request_callback_fn_type callback, void *user_data); diff --git a/include/event2/event.h b/include/event2/event.h index 6e0a4f04..450bc33c 100644 --- a/include/event2/event.h +++ b/include/event2/event.h @@ -1073,7 +1073,7 @@ void *event_self_cbarg(void); @param callback_arg an argument to be passed to the callback function @return a newly allocated struct event that must later be freed with - event_free(). + event_free() or NULL if an error occurred. @see event_free(), event_add(), event_del(), event_assign() */ EVENT2_EXPORT_SYMBOL diff --git a/include/event2/http.h b/include/event2/http.h index 8fb5642f..acee5520 100644 --- a/include/event2/http.h +++ b/include/event2/http.h @@ -78,7 +78,8 @@ struct evdns_base; * Create a new HTTP server. * * @param base (optional) the event base to receive the HTTP events - * @return a pointer to a newly initialized evhttp server structure + * @return a pointer to a newly initialized evhttp server structure or NULL + * on error * @see evhttp_free() */ EVENT2_EXPORT_SYMBOL @@ -516,7 +517,8 @@ enum evhttp_request_kind { EVHTTP_REQUEST, EVHTTP_RESPONSE }; * when the connection closes. It must have no fd set on it. * @param address the address to which to connect * @param port the port to connect to - * @return an evhttp_connection object that can be used for making requests + * @return an evhttp_connection object that can be used for making requests or + * NULL on error */ EVENT2_EXPORT_SYMBOL struct evhttp_connection *evhttp_connection_base_bufferevent_new( @@ -636,7 +638,8 @@ void evhttp_request_free(struct evhttp_request *req); * specified host name resolution will block. * @param address the address to which to connect * @param port the port to connect to - * @return an evhttp_connection object that can be used for making requests + * @return an evhttp_connection object that can be used for making requests or + * NULL on error */ EVENT2_EXPORT_SYMBOL struct evhttp_connection *evhttp_connection_base_new( diff --git a/include/event2/http_compat.h b/include/event2/http_compat.h index a9eb5972..794a5810 100644 --- a/include/event2/http_compat.h +++ b/include/event2/http_compat.h @@ -56,7 +56,8 @@ extern "C" { * * @param address the address to which the HTTP server should be bound * @param port the port number on which the HTTP server should listen - * @return an struct evhttp object + * @return a pointer to a newly initialized evhttp server structure + * or NULL on error */ EVENT2_EXPORT_SYMBOL struct evhttp *evhttp_start(const char *address, ev_uint16_t port); diff --git a/include/event2/rpc.h b/include/event2/rpc.h index 9c55b513..830d0c62 100644 --- a/include/event2/rpc.h +++ b/include/event2/rpc.h @@ -292,7 +292,7 @@ struct evhttp; /** Creates a new rpc base from which RPC requests can be received * * @param server a pointer to an existing HTTP server - * @return a newly allocated evrpc_base struct + * @return a newly allocated evrpc_base struct or NULL if an error occurred * @see evrpc_free() */ EVENT2_EXPORT_SYMBOL @@ -406,7 +406,8 @@ int evrpc_make_request(struct evrpc_request_wrapper *ctx); * * @param base a pointer to an struct event_based object; can be left NULL * in singled-threaded applications - * @return a newly allocated struct evrpc_pool object + * @return a newly allocated struct evrpc_pool object or NULL if an error + * occurred * @see evrpc_pool_free() */ EVENT2_EXPORT_SYMBOL @@ -566,7 +567,8 @@ int evrpc_hook_find_meta(void *ctx, const char *key, * returns the connection object associated with the request * * @param ctx the context provided to the hook call - * @return a pointer to the evhttp_connection object + * @return a pointer to the evhttp_connection object or NULL if an error + * occurred */ EVENT2_EXPORT_SYMBOL struct evhttp_connection *evrpc_hook_get_connection(void *ctx); -- cgit v1.2.1 From c46ff4393abcc9350391de1b3c76b00dd09e4879 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Kuzn=C3=ADk?= Date: Wed, 28 Jun 2017 12:29:29 +0100 Subject: Fix tests with detached builds Closes: #524 (cherry picked from commit cf7f5b0dc484152ae3be7ea6ba57552595891608) --- test/include.am | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/test/include.am b/test/include.am index 132bbcd4..ee2ab5ff 100644 --- a/test/include.am +++ b/test/include.am @@ -57,26 +57,26 @@ TESTS = \ LOG_COMPILER = true TESTS_COMPILER = true -test_runner_epoll: test/test.sh - test/test.sh -b EPOLL -test_runner_select: test/test.sh - test/test.sh -b SELECT -test_runner_kqueue: test/test.sh - test/test.sh -b KQUEUE -test_runner_evport: test/test.sh - test/test.sh -b EVPORT -test_runner_devpoll: test/test.sh - test/test.sh -b DEVPOLL -test_runner_poll: test/test.sh - test/test.sh -b POLL -test_runner_win32: test/test.sh - test/test.sh -b WIN32 -test_runner_timerfd: test/test.sh - test/test.sh -b "" -t -test_runner_changelist: test/test.sh - test/test.sh -b "" -c -test_runner_timerfd_changelist: test/test.sh - test/test.sh -b "" -T +test_runner_epoll: $(top_srcdir)/test/test.sh + $(top_srcdir)/test/test.sh -b EPOLL +test_runner_select: $(top_srcdir)/test/test.sh + $(top_srcdir)/test/test.sh -b SELECT +test_runner_kqueue: $(top_srcdir)/test/test.sh + $(top_srcdir)/test/test.sh -b KQUEUE +test_runner_evport: $(top_srcdir)/test/test.sh + $(top_srcdir)/test/test.sh -b EVPORT +test_runner_devpoll: $(top_srcdir)/test/test.sh + $(top_srcdir)/test/test.sh -b DEVPOLL +test_runner_poll: $(top_srcdir)/test/test.sh + $(top_srcdir)/test/test.sh -b POLL +test_runner_win32: $(top_srcdir)/test/test.sh + $(top_srcdir)/test/test.sh -b WIN32 +test_runner_timerfd: $(top_srcdir)/test/test.sh + $(top_srcdir)/test/test.sh -b "" -t +test_runner_changelist: $(top_srcdir)/test/test.sh + $(top_srcdir)/test/test.sh -b "" -c +test_runner_timerfd_changelist: $(top_srcdir)/test/test.sh + $(top_srcdir)/test/test.sh -b "" -T DISTCLEANFILES += test/regress.gen.c test/regress.gen.h -- cgit v1.2.1 From 980394b98b866346f2b625cda7a253421392a090 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 16 Jul 2017 21:40:18 +0300 Subject: Merge remote-tracking branch 'official/pr/527' -- documentation fixes * official/pr/527: Fix a few trivial documentation typos Clarify event_free() documentation regarding pending/active events (cherry picked from commit e83443ec67d45447296c2ce320620a07c88e1d32) --- include/event2/event.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/event2/event.h b/include/event2/event.h index 450bc33c..2ad2ec83 100644 --- a/include/event2/event.h +++ b/include/event2/event.h @@ -232,7 +232,7 @@ struct event_base * * Generally, you can create events with event_new(), then make them * pending with event_add(). As your event_base runs, it will run the - * callbacks of an events whose conditions are triggered. When you + * callbacks of an events whose conditions are triggered. When you no * longer want the event, free it with event_free(). * * In more depth: @@ -692,7 +692,7 @@ EVENT2_EXPORT_SYMBOL void event_base_free(struct event_base *); /** - As event_free, but do not run finalizers. + As event_base_free, but do not run finalizers. THIS IS AN EXPERIMENTAL API. IT MIGHT CHANGE BEFORE THE LIBEVENT 2.1 SERIES BECOMES STABLE. @@ -1124,8 +1124,8 @@ int event_assign(struct event *, struct event_base *, evutil_socket_t, short, ev /** Deallocate a struct event * returned by event_new(). - If the event is pending or active, first make it non-pending and - non-active. + If the event is pending or active, this function makes it non-pending + and non-active first. */ EVENT2_EXPORT_SYMBOL void event_free(struct event *); -- cgit v1.2.1 From 9f4d0dceef925dd2a954f6ce067c4227e1c55656 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 14 Aug 2017 23:03:48 +0300 Subject: Fix wrong assert in evbuffer_drain() "chain" cannot be NULL here because we have at least one chain (we handle empty buffer separatelly) and hence loop will be executed at least once. Link: https://github.com/libevent/libevent/commit/841ecbd96105c84ac2e7c9594aeadbcc6fb38bc4#commitcomment-23631347 Signed-off-by: Ivan Maidanski Signed-off-by: Azat Khuzhin (cherry picked from commit b26996a05d9e7aad32e78a7bfab6454d5c11500a) --- buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buffer.c b/buffer.c index be958feb..9a7b2a6a 100644 --- a/buffer.c +++ b/buffer.c @@ -1146,7 +1146,7 @@ evbuffer_drain(struct evbuffer *buf, size_t len) } buf->first = chain; - EVUTIL_ASSERT(chain && remaining <= chain->off); + EVUTIL_ASSERT(remaining < chain->off); chain->misalign += remaining; chain->off -= remaining; } -- cgit v1.2.1 From 2bf8b0ff0e37b4439661cd91b98e544d9f5b8cd3 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 14 Aug 2017 23:11:53 +0300 Subject: Remove check against passed bufferevent in bufferevent_socket_connect() It is a bit confusing to check against the result of EVUTIL_UPCAST(), because it can return not NULL for NULL pointers, but for even though with bufferevent we are fine (because bufferevent is the first field in bufferevent_private), there are no checks for "bufev" in bufferevent's API, so just remove it to make it generic. Fixes: #542 Signed-off-by: Ivan Maidanski Signed-off-by: Azat Khuzhin (cherry picked from commit a10a6f4ed918ea1432820d99e9373f37f906d6f0) --- bufferevent_sock.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/bufferevent_sock.c b/bufferevent_sock.c index e305ec55..38f791ee 100644 --- a/bufferevent_sock.c +++ b/bufferevent_sock.c @@ -389,9 +389,6 @@ bufferevent_socket_connect(struct bufferevent *bev, bufferevent_incref_and_lock_(bev); - if (!bufev_p) - goto done; - fd = bufferevent_getfd(bev); if (fd < 0) { if (!sa) -- cgit v1.2.1 From 43d92a6dab058914f6d2e83dd1b3ba7e337fa8b4 Mon Sep 17 00:00:00 2001 From: James Synge Date: Mon, 7 Aug 2017 11:06:28 -0400 Subject: Fix race in access to ev_res from event loop with event_active() Detected using ThreadSanitizer, resolved by capturing the value of ev_res in a local variable while the event is locked, then passing that captured variable to the callback. TSAN report: I0728 14:35:09.822118 WARNING: ThreadSanitizer: data race (pid=815501) I0728 14:35:09.822186 Write of size 2 at 0x7b2c00001bf2 by thread T80 (mutexes: write M1110835549570434736): I0728 14:35:09.822248 #0 event_active_nolock_ libevent/event.c:2893:14 (0a2b90577e830d775300664df77d0b91+0x1fdab28) I0728 14:35:09.822316 #1 event_active libevent/event.c:2858:2 (0a2b90577e830d775300664df77d0b91+0x1fdd10e) I0728 14:35:09.822379 #2 Envoy::Event::TimerImpl::enableTimer(std::chrono::duration > const&) envoy/source/common/event/timer_impl.cc:24:5 (0a2b90577e830d775300664df77d0b91+0x459fa0) ... I0728 14:35:09.824146 Previous read of size 2 at 0x7b2c00001bf2 by main thread: I0728 14:35:09.824232 #0 event_process_active_single_queue libevent/event.c:1646:33 (0a2b90577e830d775300664df77d0b91+0x1fdf83d) I0728 14:35:09.824350 #1 event_process_active libevent/event.c (0a2b90577e830d775300664df77d0b91+0x1fd9ad8) I0728 14:35:09.824445 #2 event_base_loop libevent/event.c:1961 (0a2b90577e830d775300664df77d0b91+0x1fd9ad8) I0728 14:35:09.824550 #3 Envoy::Event::DispatcherImpl::run(Envoy::Event::Dispatcher::RunType) envoy/source/common/event/dispatcher_impl.cc:166:3 (0a2b90577e830d775300664df77d0b91+0x4576d9) ... Fixes: #543 (pull-request) (cherry picked from commit 27934f0b39991172dcfdad23faea9874dd386f10) --- event.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/event.c b/event.c index d2768793..98b1bc4a 100644 --- a/event.c +++ b/event.c @@ -1641,10 +1641,12 @@ event_process_active_single_queue(struct event_base *base, break; case EV_CLOSURE_EVENT: { void (*evcb_callback)(evutil_socket_t, short, void *); + short res; EVUTIL_ASSERT(ev != NULL); evcb_callback = *ev->ev_callback; + res = ev->ev_res; EVBASE_RELEASE_LOCK(base, th_base_lock); - evcb_callback(ev->ev_fd, ev->ev_res, ev->ev_arg); + evcb_callback(ev->ev_fd, res, ev->ev_arg); } break; case EV_CLOSURE_CB_SELF: { -- cgit v1.2.1 From d433201e133893a56cbb67053d3d460ebaeb368a Mon Sep 17 00:00:00 2001 From: Redfoxmoon Date: Tue, 15 Aug 2017 05:11:05 +0200 Subject: Add configure check for midipix Fixes: #540 (cherry picked from commit 94e5cc84d5adf8075a1a98263d16756faec8ea30) --- configure.ac | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 43baeecf..05ef57a7 100644 --- a/configure.ac +++ b/configure.ac @@ -160,6 +160,19 @@ die horribly bwin32=false; AC_MSG_RESULT(no), ) +dnl - check if the macro __midipix__ is defined on this compiler. +dnl - (this is how we check for a midipix version of GCC) +AC_MSG_CHECKING(for MIDIPIX) +AC_TRY_COMPILE(, + [ +#ifndef __midipix__ +die horribly +#endif + ], + midipix=true; AC_MSG_RESULT(yes), + midipix=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) @@ -326,7 +339,8 @@ 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) +AM_CONDITIONAL(BUILD_MIDIPIX, test x$midipix = xtrue) +AM_CONDITIONAL(BUILD_WITH_NO_UNDEFINED, test x$bwin32 = xtrue || test x$cygwin = xtrue || test x$midipix = xtrue) if test x$bwin32 = xtrue; then AC_SEARCH_LIBS([getservbyname],[ws2_32]) -- cgit v1.2.1 From 25150a629eceb9964732580bf10b6a7d26622d90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlo=20Marcelo=20Arenas=20Bel=C3=B3n?= Date: Thu, 17 Aug 2017 01:37:01 -0700 Subject: always define EV_INT16_MIN somehow missing from 043ae7481f4a73b0f48055a0260afa454f02d136 (cherry picked from commit 5698cff73dac815dab937fd0262dd1f910ad1c3c) --- include/event2/util.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/event2/util.h b/include/event2/util.h index ca404894..70aabb66 100644 --- a/include/event2/util.h +++ b/include/event2/util.h @@ -259,6 +259,7 @@ extern "C" { #define EV_INT32_MAX INT32_MAX #define EV_INT32_MIN INT32_MIN #define EV_UINT16_MAX UINT16_MAX +#define EV_INT16_MIN INT16_MIN #define EV_INT16_MAX INT16_MAX #define EV_UINT8_MAX UINT8_MAX #define EV_INT8_MAX INT8_MAX -- cgit v1.2.1 From c2495265b1faa91df5f6c835fdae4d5ec4605683 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlo=20Marcelo=20Arenas=20Bel=C3=B3n?= Date: Mon, 21 Aug 2017 01:08:15 -0700 Subject: autotools: pass $(OPENSSL_INCS) for samples (FTBFS macOS) if OpenSSL is in a non standard location, need to pass that information to any sample that needs it Closes: #550 (cherry picked from commit 0ec5edde503096a81831f36441a4115574ac45f0) --- sample/include.am | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sample/include.am b/sample/include.am index d1a7242f..cc003b78 100644 --- a/sample/include.am +++ b/sample/include.am @@ -16,16 +16,16 @@ SAMPLES = \ if OPENSSL SAMPLES += sample/le-proxy sample_le_proxy_SOURCES = sample/le-proxy.c -sample_le_proxy_LDADD = libevent.la libevent_openssl.la ${OPENSSL_LIBS} ${OPENSSL_LIBADD} -sample_le_proxy_INCLUDES = $(OPENSSL_INCS) +sample_le_proxy_LDADD = libevent.la libevent_openssl.la $(OPENSSL_LIBS) $(OPENSSL_LIBADD) +sample_le_proxy_CPPFLAGS = $(AM_CPPFLAGS) $(OPENSSL_INCS) SAMPLES += sample/https-client sample_https_client_SOURCES = \ sample/https-client.c \ sample/hostcheck.c \ sample/openssl_hostname_validation.c -sample_https_client_LDADD = libevent.la libevent_openssl.la ${OPENSSL_LIBS} ${OPENSSL_LIBADD} -sample_https_client_INCLUDES = $(OPENSSL_INCS) +sample_https_client_LDADD = libevent.la libevent_openssl.la $(OPENSSL_LIBS) $(OPENSSL_LIBADD) +sample_https_client_CPPFLAGS = $(AM_CPPFLAGS) $(OPENSSL_INCS) noinst_HEADERS += \ sample/hostcheck.h \ sample/openssl_hostname_validation.h -- cgit v1.2.1 From 8983e5117be43196c12dd7b52765bd047c211361 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlo=20Marcelo=20Arenas=20Bel=C3=B3n?= Date: Fri, 1 Sep 2017 15:50:36 -0700 Subject: test: fix 32bit linux regress (cherry picked from commit 63c4bf78d6af3c6ff46d2e8e4b53dd9f577a9ca9) --- CMakeLists.txt | 2 +- WIN32-Code/nmake/event2/event-config.h | 7 +++++++ configure.ac | 1 + test/regress_util.c | 2 ++ 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 638a537c..ee07541f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -458,7 +458,6 @@ else() set(EVENT__SIZEOF_SSIZE_T ${EVENT__SIZEOF_INT}) endif() - CHECK_TYPE_SIZE(socklen_t EVENT__SIZEOF_SOCKLEN_T) if(NOT EVENT__SIZEOF_SOCKLEN_T) set(EVENT__socklen_t "unsigned int") @@ -490,6 +489,7 @@ endif() # we're just getting lazy now. CHECK_TYPE_SIZE("uintptr_t" EVENT__HAVE_UINTPTR_T) CHECK_TYPE_SIZE("void *" EVENT__SIZEOF_VOID_P) +CHECK_TYPE_SIZE("time_t" EVENT__SIZEOF_TIME_T) # Tests file offset bits. # TODO: Add AIX test for if -D_LARGE_FILES is needed. diff --git a/WIN32-Code/nmake/event2/event-config.h b/WIN32-Code/nmake/event2/event-config.h index a3664aa2..c09ec3f9 100644 --- a/WIN32-Code/nmake/event2/event-config.h +++ b/WIN32-Code/nmake/event2/event-config.h @@ -324,6 +324,13 @@ #define EVENT__SIZEOF_VOID_P 4 #endif +/* The size of `time_t`, as computed by sizeof. */ +#ifdef _WIN64 +#define EVENT__SIZEOF_TIME_T 8 +#else +#define EVENT__SIZEOF_TIME_T 4 +#endif + /* Define to 1 if you have the ANSI C header files. */ #define EVENT__STDC_HEADERS 1 diff --git a/configure.ac b/configure.ac index 05ef57a7..4c7f1f6e 100644 --- a/configure.ac +++ b/configure.ac @@ -658,6 +658,7 @@ AC_CHECK_SIZEOF(short) AC_CHECK_SIZEOF(size_t) AC_CHECK_SIZEOF(void *) AC_CHECK_SIZEOF(off_t) +AC_CHECK_SIZEOF(time_t) AC_CHECK_TYPES([struct in6_addr, struct sockaddr_in6, sa_family_t, struct addrinfo, struct sockaddr_storage], , , [#define _GNU_SOURCE diff --git a/test/regress_util.c b/test/regress_util.c index ef6a1487..68281e61 100644 --- a/test/regress_util.c +++ b/test/regress_util.c @@ -1412,10 +1412,12 @@ static struct date_rfc1123_case { { 1289433600, "Thu, 11 Nov 2010 00:00:00 GMT"}, { 1323648000, "Mon, 12 Dec 2011 00:00:00 GMT"}, #ifndef _WIN32 +#if EVENT__SIZEOF_TIME_T > 4 /** In win32 case we have max "23:59:59 January 18, 2038, UTC" for time32 */ { 4294967296, "Sun, 07 Feb 2106 06:28:16 GMT"} /* 2^32 */, /** In win32 case we have max "23:59:59, December 31, 3000, UTC" for time64 */ {253402300799, "Fri, 31 Dec 9999 23:59:59 GMT"} /* long long future no one can imagine */, +#endif /* time_t != 32bit */ { 1456704000, "Mon, 29 Feb 2016 00:00:00 GMT"} /* leap year */, #endif { 1435708800, "Wed, 01 Jul 2015 00:00:00 GMT"} /* leap second */, -- cgit v1.2.1 From b39ccf8e0b864490b51c6b1ce37900ac8d703b20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlo=20Marcelo=20Arenas=20Bel=C3=B3n?= Date: Tue, 29 Aug 2017 00:44:57 -0700 Subject: autotools: confirm openssl is working before using latest versions of macOS provide pkg-config and libraries for an ancient version of openssl as part of the system, but no headers (cherry picked from commit 506df426dbeb0187bbd3654bd286b4100628fb16) --- m4/libevent_openssl.m4 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/m4/libevent_openssl.m4 b/m4/libevent_openssl.m4 index c2040595..7b458134 100644 --- a/m4/libevent_openssl.m4 +++ b/m4/libevent_openssl.m4 @@ -39,6 +39,10 @@ case "$enable_openssl" in done ;; esac + CPPFLAGS_SAVE=$CPPFLAGS + CPPFLAGS+=$OPENSSL_INCS + AC_CHECK_HEADERS([openssl/ssl.h], [], [have_openssl=no]) + CPPFLAGS=$CPPFLAGS_SAVE AC_SUBST(OPENSSL_INCS) AC_SUBST(OPENSSL_LIBS) case "$have_openssl" in -- cgit v1.2.1 From 1811a040ef54180c208a6d2cf19bec7a36ebe337 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlo=20Marcelo=20Arenas=20Bel=C3=B3n?= Date: Wed, 16 Aug 2017 16:52:33 -0700 Subject: test: avoid regress hanging in macOS a backtrace of the process without this patch : * thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP * frame #0: 0x00007fffb1fb7d96 libsystem_kernel.dylib`kevent + 10 frame #1: 0x0000000108ed0a58 libevent-2.2.1.dylib`kq_dispatch + 696 frame #2: 0x0000000108ec53d8 libevent-2.2.1.dylib`event_base_loop + 696 frame #3: 0x0000000108e1763b regress`test_fork + 1931 frame #4: 0x0000000108e5c7ad regress`run_legacy_test_fn + 45 frame #5: 0x0000000108e690aa regress`testcase_run_one + 858 frame #6: 0x0000000108e6954f regress`tinytest_main + 495 frame #7: 0x0000000108e5c94b regress`main + 171 frame #8: 0x00007fffb1e88235 libdyld.dylib`start + 1 frame #9: 0x00007fffb1e88235 libdyld.dylib`start + 1 Issue: #546 (cherry picked from commit a86f89d333d870e6714bd28c695ba1774df3d7f5) --- test/regress.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/regress.c b/test/regress.c index e4ce98c0..f86963fa 100644 --- a/test/regress.c +++ b/test/regress.c @@ -3445,7 +3445,7 @@ struct testcase_t main_testcases[] = { BASIC(active_by_fd, TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR), -#ifndef _WIN32 +#if !defined(_WIN32) && !defined(__APPLE__) LEGACY(fork, TT_ISOLATED), #endif #ifdef EVENT__HAVE_PTHREADS -- cgit v1.2.1 From 9c720b70731b27acc115bb12b5a8b6c480d92442 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlo=20Marcelo=20Arenas=20Bel=C3=B3n?= Date: Sat, 19 Aug 2017 16:01:46 -0700 Subject: configure: avoid false positive in DragonFlyBSD by default, the max buffer size is 16K and histeresis is at 50%, so a bigger read is needed to unlock writes than you would expect from other BSD (512 bytes) this doesn't introduce any regression on FreeBSD 11.1, OpenBSD 6.1, NetBSD 7.1, macOS 10.12.6 and of course DragonFlyBSD 4.8.1, and most of them show a max pipe size of 64K, so the read call should drain them all regardless of how conservative they are on the free pipe space they will require (usually 512 bytes) before kevent reports the fd as ready for write. I couldn't find a reference to which bug this code was trying to look for and it seems to be there from the beginning of git history so it might be no longer relevant. Issue: #548 (cherry picked from commit 1dfec8a97094a26317eac9b3d8a1c16eb1a7dbea) --- cmake/CheckWorkingKqueue.cmake | 6 +++--- configure.ac | 8 +++++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/cmake/CheckWorkingKqueue.cmake b/cmake/CheckWorkingKqueue.cmake index 47bf4e83..f22f011b 100644 --- a/cmake/CheckWorkingKqueue.cmake +++ b/cmake/CheckWorkingKqueue.cmake @@ -17,7 +17,7 @@ main(int argc, char **argv) int fd[2]; struct kevent ev; struct timespec ts; - char buf[8000]; + char buf[80000]; if (pipe(fd) == -1) exit(1); @@ -27,7 +27,7 @@ main(int argc, char **argv) while ((n = write(fd[1], buf, sizeof(buf))) == sizeof(buf)) ; - if ((kq = kqueue()) == -1) + if ((kq = kqueue()) == -1) exit(1); memset(&ev, 0, sizeof(ev)); @@ -49,4 +49,4 @@ main(int argc, char **argv) exit(0); } -" EVENT__HAVE_WORKING_KQUEUE) \ No newline at end of file +" EVENT__HAVE_WORKING_KQUEUE) diff --git a/configure.ac b/configure.ac index 4c7f1f6e..a3b7fd41 100644 --- a/configure.ac +++ b/configure.ac @@ -517,6 +517,12 @@ if test "x$ac_cv_header_sys_event_h" = "xyes"; then if test "x$havekqueue" = "xyes" ; then AC_MSG_CHECKING(for working kqueue) AC_TRY_RUN( +#ifdef HAVE_STDLIB_H +#include +#endif +#ifdef HAVE_STRING_H +#include +#endif #include #include #include @@ -532,7 +538,7 @@ main(int argc, char **argv) int fd[[2]]; struct kevent ev; struct timespec ts; - char buf[[8000]]; + char buf[[80000]]; if (pipe(fd) == -1) exit(1); -- cgit v1.2.1 From 7cc034c37d4f0f5194b46708fdebc1b0187d179b Mon Sep 17 00:00:00 2001 From: Vincent JARDIN Date: Mon, 11 Sep 2017 21:56:30 +0200 Subject: test: fix warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In function ‘send_a_byte_cb’: test/regress.c:1853:2: warning: ignoring return value of ‘write’, declared with attribute warn_unused_result [-Wunused-result] (void) write(*sockp, "A", 1); (cherry picked from commit 56010f37ae5b49881f7fd255d5c8a936e1c36909) --- test/regress.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/regress.c b/test/regress.c index f86963fa..88e9b259 100644 --- a/test/regress.c +++ b/test/regress.c @@ -1850,7 +1850,8 @@ static void send_a_byte_cb(evutil_socket_t fd, short what, void *arg) { evutil_socket_t *sockp = arg; (void) fd; (void) what; - (void) write(*sockp, "A", 1); + if (write(*sockp, "A", 1) < 0) + tt_fail_perror("write"); } struct read_not_timeout_param { -- cgit v1.2.1 From 02312d506be8afdb3e52c0f2922c97e8aea178fe Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 24 Sep 2017 15:12:13 +0300 Subject: Remove OpenSSL paragram from README Because it is mauvais ton to use binaries instead of normal packages (like apt-get in debian, pacman in arch, and others). Plus that link was borken and according to [1] OpenSSL do not ship binaries officially. And personally I don't think that this is not obvious that you need openssl libraries to build libevent with it's support, and BTW you need headers too (of course). [1]: https://www.openssl.org/community/binaries.html Fixes: #562 (cherry picked from commit 62866f98a5979e3b9ee8db0287be79749fcf7d6a) --- README.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/README.md b/README.md index 24cf618a..7e40bb22 100644 --- a/README.md +++ b/README.md @@ -168,11 +168,6 @@ $ cmake -LH .. CMake also provides a GUI that lets you specify the source directory and output (binary) directory that the build should be placed in. -### OpenSSL support - -To build Libevent with OpenSSL support you will need to have OpenSSL binaries available when building, -these can be found here: - # 2. USEFUL LINKS: For the latest released version of Libevent, see the official website at -- cgit v1.2.1 From 532a8cc301db39e82166b4fe98146534fdc242ce Mon Sep 17 00:00:00 2001 From: Kiyoshi Aman Date: Thu, 14 Sep 2017 17:39:20 -0500 Subject: Port `event_rpcgen.py` and `test/check-dumpevents.py` to Python 3. These scripts remain compatible with Python 2. (cherry picked from commit 8b0aa7b36a3250fad4953f194c8a94ab25032583) --- CMakeLists.txt | 21 +++--- event_rpcgen.py | 167 +++++++++++++++++++++++------------------------ test/check-dumpevents.py | 10 +-- test/rpcgen_wrapper.sh | 11 +--- test/test.sh | 4 +- 5 files changed, 100 insertions(+), 113 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ee07541f..d5273a87 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -915,19 +915,18 @@ if (NOT EVENT__DISABLE_TESTS) # Generate Regress tests. # if (NOT EVENT__DISABLE_REGRESS) - # (We require python2 to generate the regress tests) - foreach (PY python2.6 python2.7 python2) - unset(FIND_PYTHON2 CACHE) - find_program(FIND_PYTHON2 ${PY}) - if (FIND_PYTHON2) - set(PYTHON_EXECUTABLE "${PY}") - break() - endif() - endforeach() - find_package(PythonInterp) + # (We require python to generate the regress tests) + find_package(PythonInterp 3) - if (PYTHONINTERP_FOUND AND PYTHON_VERSION_STRING VERSION_LESS "3.0.0") + if (PYTHONINTERP_FOUND) set(__FOUND_USABLE_PYTHON 1) + else() + find_package(PythonInterp 2) + if (PYTHONINTERP_FOUND) + set(__FOUND_USABLE_PYTHON 1) + else() + message(ERROR "No suitable Python version found, bailing...") + endif() endif() if (__FOUND_USABLE_PYTHON) diff --git a/event_rpcgen.py b/event_rpcgen.py index 9baf7302..2004090a 100755 --- a/event_rpcgen.py +++ b/event_rpcgen.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python # # Copyright (c) 2005-2007 Niels Provos # Copyright (c) 2007-2012 Niels Provos and Nick Mathewson @@ -36,10 +36,10 @@ QUIETLY = 0 def declare(s): if not QUIETLY: - print s + print(s) def TranslateList(mylist, mydict): - return map(lambda x: x % mydict, mylist) + return [x % mydict for x in mylist] # Exception class for parse errors class RpcGenError(Exception): @@ -57,7 +57,7 @@ class Struct: declare(' Created struct: %s' % name) def AddEntry(self, entry): - if self._tags.has_key(entry.Tag()): + if entry.Tag() in self._tags: raise RpcGenError( 'Entry "%s" duplicates tag number %d from "%s" ' 'around line %d' % (entry.Name(), entry.Tag(), @@ -78,7 +78,7 @@ class Struct: def PrintIndented(self, file, ident, code): """Takes an array, add indentation to each entry and prints it.""" for entry in code: - print >>file, '%s%s' % (ident, entry) + file.write('%s%s\n' % (ident, entry)) class StructCCode(Struct): """ Knows how to generate C code for a struct """ @@ -88,20 +88,19 @@ class StructCCode(Struct): def PrintTags(self, file): """Prints the tag definitions for a structure.""" - print >>file, '/* Tag definition for %s */' % self._name - print >>file, 'enum %s_ {' % self._name.lower() + file.write('/* Tag definition for %s */\n' % self._name) + file.write('enum %s_ {\n' % self._name.lower()) for entry in self._entries: - print >>file, ' %s=%d,' % (self.EntryTagName(entry), - entry.Tag()) - print >>file, ' %s_MAX_TAGS' % (self._name.upper()) - print >>file, '};\n' + file.write(' %s=%d,\n' % (self.EntryTagName(entry), entry.Tag())) + file.write(' %s_MAX_TAGS\n' % (self._name.upper())) + file.write('};\n\n') def PrintForwardDeclaration(self, file): - print >>file, 'struct %s;' % self._name + file.write('struct %s;\n' % self._name) def PrintDeclaration(self, file): - print >>file, '/* Structure declaration for %s */' % self._name - print >>file, 'struct %s_access_ {' % self._name + file.write('/* Structure declaration for %s */\n' % self._name) + file.write('struct %s_access_ {\n' % self._name) for entry in self._entries: dcl = entry.AssignDeclaration('(*%s_assign)' % entry.Name()) dcl.extend( @@ -110,20 +109,19 @@ class StructCCode(Struct): dcl.extend( entry.AddDeclaration('(*%s_add)' % entry.Name())) self.PrintIndented(file, ' ', dcl) - print >>file, '};\n' + file.write('};\n\n') - print >>file, 'struct %s {' % self._name - print >>file, ' struct %s_access_ *base;\n' % self._name + file.write('struct %s {\n' % self._name) + file.write(' struct %s_access_ *base;\n\n' % self._name) for entry in self._entries: dcl = entry.Declaration() self.PrintIndented(file, ' ', dcl) - print >>file, '' + file.write('\n') for entry in self._entries: - print >>file, ' ev_uint8_t %s_set;' % entry.Name() - print >>file, '};\n' + file.write(' ev_uint8_t %s_set;\n' % entry.Name()) + file.write('};\n\n') - print >>file, \ -"""struct %(name)s *%(name)s_new(void); + file.write("""struct %(name)s *%(name)s_new(void); struct %(name)s *%(name)s_new_with_arg(void *); void %(name)s_free(struct %(name)s *); void %(name)s_clear(struct %(name)s *); @@ -133,7 +131,7 @@ int %(name)s_complete(struct %(name)s *); void evtag_marshal_%(name)s(struct evbuffer *, ev_uint32_t, const struct %(name)s *); int evtag_unmarshal_%(name)s(struct evbuffer *, ev_uint32_t, - struct %(name)s *);""" % { 'name' : self._name } + struct %(name)s *);\n""" % { 'name' : self._name }) # Write a setting function of every variable @@ -146,22 +144,21 @@ int evtag_unmarshal_%(name)s(struct evbuffer *, ev_uint32_t, self.PrintIndented(file, '', entry.AddDeclaration( entry.AddFuncName())) - print >>file, '/* --- %s done --- */\n' % self._name + file.write('/* --- %s done --- */\n\n' % self._name) def PrintCode(self, file): - print >>file, ('/*\n' + file.write(('/*\n' ' * Implementation of %s\n' - ' */\n') % self._name + ' */\n\n') % self._name) - print >>file, \ - 'static struct %(name)s_access_ %(name)s_base__ = {' % \ - { 'name' : self._name } + file.write('static struct %(name)s_access_ %(name)s_base__ = {\n' % \ + { 'name' : self._name }) for entry in self._entries: self.PrintIndented(file, ' ', entry.CodeBase()) - print >>file, '};\n' + file.write('};\n\n') # Creation - print >>file, ( + file.write(( 'struct %(name)s *\n' '%(name)s_new(void)\n' '{\n' @@ -176,77 +173,77 @@ int evtag_unmarshal_%(name)s(struct evbuffer *, ev_uint32_t, ' event_warn("%%s: malloc", __func__);\n' ' return (NULL);\n' ' }\n' - ' tmp->base = &%(name)s_base__;\n') % { 'name' : self._name } + ' tmp->base = &%(name)s_base__;\n\n') % { 'name' : self._name }) for entry in self._entries: self.PrintIndented(file, ' ', entry.CodeInitialize('tmp')) - print >>file, ' tmp->%s_set = 0;\n' % entry.Name() + file.write(' tmp->%s_set = 0;\n\n' % entry.Name()) - print >>file, ( + file.write(( ' return (tmp);\n' - '}\n') + '}\n\n')) # Adding for entry in self._entries: if entry.Array(): self.PrintIndented(file, '', entry.CodeAdd()) - print >>file, '' + file.write('\n') # Assigning for entry in self._entries: self.PrintIndented(file, '', entry.CodeAssign()) - print >>file, '' + file.write('\n') # Getting for entry in self._entries: self.PrintIndented(file, '', entry.CodeGet()) - print >>file, '' + file.write('\n') # Clearing - print >>file, ( 'void\n' + file.write(( 'void\n' '%(name)s_clear(struct %(name)s *tmp)\n' '{' - ) % { 'name' : self._name } + '\n') % { 'name' : self._name }) for entry in self._entries: self.PrintIndented(file, ' ', entry.CodeClear('tmp')) - print >>file, '}\n' + file.write('}\n\n') # Freeing - print >>file, ( 'void\n' + file.write(( 'void\n' '%(name)s_free(struct %(name)s *tmp)\n' '{' - ) % { 'name' : self._name } + '\n') % { 'name' : self._name }) for entry in self._entries: self.PrintIndented(file, ' ', entry.CodeFree('tmp')) - print >>file, (' free(tmp);\n' - '}\n') + file.write((' free(tmp);\n' + '}\n\n')) # Marshaling - print >>file, ('void\n' + file.write(('void\n' '%(name)s_marshal(struct evbuffer *evbuf, ' 'const struct %(name)s *tmp)' - '{') % { 'name' : self._name } + '{\n') % { 'name' : self._name }) for entry in self._entries: indent = ' ' # Optional entries do not have to be set if entry.Optional(): indent += ' ' - print >>file, ' if (tmp->%s_set) {' % entry.Name() + file.write(' if (tmp->%s_set) {\n' % entry.Name()) self.PrintIndented( file, indent, entry.CodeMarshal('evbuf', self.EntryTagName(entry), entry.GetVarName('tmp'), entry.GetVarLen('tmp'))) if entry.Optional(): - print >>file, ' }' + file.write(' }\n') - print >>file, '}\n' + file.write('}\n\n') # Unmarshaling - print >>file, ('int\n' + file.write(('int\n' '%(name)s_unmarshal(struct %(name)s *tmp, ' ' struct evbuffer *evbuf)\n' '{\n' @@ -255,14 +252,14 @@ int evtag_unmarshal_%(name)s(struct evbuffer *, ev_uint32_t, ' if (evtag_peek(evbuf, &tag) == -1)\n' ' return (-1);\n' ' switch (tag) {\n' - ) % { 'name' : self._name } + '\n') % { 'name' : self._name }) for entry in self._entries: - print >>file, ' case %s:\n' % self.EntryTagName(entry) + file.write(' case %s:\n' % self.EntryTagName(entry)) if not entry.Array(): - print >>file, ( + file.write(( ' if (tmp->%s_set)\n' ' return (-1);' - ) % (entry.Name()) + '\n') % (entry.Name())) self.PrintIndented( file, ' ', @@ -271,26 +268,26 @@ int evtag_unmarshal_%(name)s(struct evbuffer *, ev_uint32_t, entry.GetVarName('tmp'), entry.GetVarLen('tmp'))) - print >>file, ( ' tmp->%s_set = 1;\n' % entry.Name() + - ' break;\n' ) - print >>file, ( ' default:\n' + file.write(( ' tmp->%s_set = 1;\n' % entry.Name() + + ' break;\n' )) + file.write(( ' default:\n' ' return -1;\n' ' }\n' - ' }\n' ) + ' }\n\n' )) # Check if it was decoded completely - print >>file, ( ' if (%(name)s_complete(tmp) == -1)\n' + file.write(( ' if (%(name)s_complete(tmp) == -1)\n' ' return (-1);' - ) % { 'name' : self._name } + '\n') % { 'name' : self._name }) # Successfully decoded - print >>file, ( ' return (0);\n' - '}\n') + file.write(( ' return (0);\n' + '}\n\n')) # Checking if a structure has all the required data - print >>file, ( + file.write(( 'int\n' '%(name)s_complete(struct %(name)s *msg)\n' - '{' ) % { 'name' : self._name } + '{\n' ) % { 'name' : self._name }) for entry in self._entries: if not entry.Optional(): code = [ @@ -303,12 +300,12 @@ int evtag_unmarshal_%(name)s(struct evbuffer *, ev_uint32_t, self.PrintIndented( file, ' ', entry.CodeComplete('msg', entry.GetVarName('msg'))) - print >>file, ( + file.write(( ' return (0);\n' - '}\n' ) + '}\n\n' )) # Complete message unmarshaling - print >>file, ( + file.write(( 'int\n' 'evtag_unmarshal_%(name)s(struct evbuffer *evbuf, ' 'ev_uint32_t need_tag, struct %(name)s *msg)\n' @@ -330,10 +327,10 @@ int evtag_unmarshal_%(name)s(struct evbuffer *, ev_uint32_t, ' error:\n' ' evbuffer_free(tmp);\n' ' return (res);\n' - '}\n' ) % { 'name' : self._name } + '}\n\n' ) % { 'name' : self._name }) # Complete message marshaling - print >>file, ( + file.write(( 'void\n' 'evtag_marshal_%(name)s(struct evbuffer *evbuf, ev_uint32_t tag, ' 'const struct %(name)s *msg)\n' @@ -343,7 +340,7 @@ int evtag_unmarshal_%(name)s(struct evbuffer *, ev_uint32_t, ' %(name)s_marshal(buf_, msg);\n' ' evtag_marshal_buffer(evbuf, tag, buf_);\n ' ' evbuffer_free(buf_);\n' - '}\n' ) % { 'name' : self._name } + '}\n\n' ) % { 'name' : self._name }) class Entry: def __init__(self, type, name, tag): @@ -420,7 +417,7 @@ class Entry: "optaddarg" : self._optaddarg and ", const %s value" % self._ctype or "" } - for (k, v) in extradict.items(): + for (k, v) in list(extradict.items()): mapping[k] = v return mapping @@ -1127,7 +1124,7 @@ class EntryArray(Entry): codearrayassign = self._entry.CodeArrayAssign( 'msg->%(name)s_data[off]' % self.GetTranslation(), 'value') - code += map(lambda x: ' ' + x, codearrayassign) + code += [' ' + x for x in codearrayassign] code += TranslateList([ ' }', @@ -1168,7 +1165,7 @@ class EntryArray(Entry): code = TranslateList(code, self.GetTranslation()) - code += map(lambda x: ' ' + x, codearrayadd) + code += [' ' + x for x in codearrayadd] code += TranslateList([ ' msg->%(name)s_set = 1;', @@ -1196,7 +1193,7 @@ class EntryArray(Entry): code = TranslateList(code, translate) - code += map(lambda x: ' ' + x, tmp) + code += [' ' + x for x in tmp] code += [ ' }', @@ -1261,7 +1258,7 @@ class EntryArray(Entry): code = TranslateList(code, translate) if codearrayfree: - code += map(lambda x: ' ' + x, codearrayfree) + code += [' ' + x for x in codearrayfree] code += [ ' }' ] @@ -1687,23 +1684,23 @@ class CommandLine: declare('... creating "%s"' % header_file) header_fp = open(header_file, 'w') - print >>header_fp, factory.HeaderPreamble(filename) + header_fp.write(factory.HeaderPreamble(filename)) # Create forward declarations: allows other structs to reference # each other for entry in entities: entry.PrintForwardDeclaration(header_fp) - print >>header_fp, '' + header_fp.write('\n') for entry in entities: entry.PrintTags(header_fp) entry.PrintDeclaration(header_fp) - print >>header_fp, factory.HeaderPostamble(filename) + header_fp.write(factory.HeaderPostamble(filename)) header_fp.close() declare('... creating "%s"' % impl_file) impl_fp = open(impl_file, 'w') - print >>impl_fp, factory.BodyPreamble(filename, header_file) + impl_fp.write(factory.BodyPreamble(filename, header_file)) for entry in entities: entry.PrintCode(impl_fp) impl_fp.close() @@ -1713,16 +1710,16 @@ if __name__ == '__main__': CommandLine(sys.argv).run() sys.exit(0) - except RpcGenError, e: - print >>sys.stderr, e + except RpcGenError as e: + sys.stderr.write(e) sys.exit(1) - except EnvironmentError, e: + except EnvironmentError as e: if e.filename and e.strerror: - print >>sys.stderr, "%s: %s" % (e.filename, e.strerror) + sys.stderr.write("%s: %s" % (e.filename, e.strerror)) sys.exit(1) elif e.strerror: - print >> sys.stderr, e.strerror + sys.stderr.write(e.strerror) sys.exit(1) else: raise diff --git a/test/check-dumpevents.py b/test/check-dumpevents.py index 16fe9bc9..3e1df30c 100755 --- a/test/check-dumpevents.py +++ b/test/check-dumpevents.py @@ -1,4 +1,4 @@ -#!/usr/bin/python2 +#!/usr/bin/env python # # Post-process the output of test-dumpevents and check it for correctness. # @@ -15,12 +15,12 @@ try: got_inserted_pos = text.index("Inserted events:\n") got_active_pos = text.index("Active events:\n") except ValueError: - print >>sys.stderr, "Missing expected dividing line in dumpevents output" + sys.stderr.write("Missing expected dividing line in dumpevents output") sys.exit(1) if not (expect_inserted_pos < expect_active_pos < got_inserted_pos < got_active_pos): - print >>sys.stderr, "Sections out of order in dumpevents output" + sys.stderr.write("Sections out of order in dumpevents output") sys.exit(1) now,T= text[1].split() @@ -45,10 +45,10 @@ cleaned_inserted = set( pat.sub(replace_time, s) for s in got_inserted if "Internal" not in s) if cleaned_inserted != want_inserted: - print >>sys.stderr, "Inserted event lists were not as expected!" + sys.stderr.write("Inserted event lists were not as expected!") sys.exit(1) if set(got_active) != set(want_active): - print >>sys.stderr, "Active event lists were not as expected!" + sys.stderr.write("Active event lists were not as expected!") sys.exit(1) diff --git a/test/rpcgen_wrapper.sh b/test/rpcgen_wrapper.sh index aaa03031..fe582d57 100755 --- a/test/rpcgen_wrapper.sh +++ b/test/rpcgen_wrapper.sh @@ -25,19 +25,10 @@ exit_failed() { echo "Could not generate regress.gen.\[ch\] using event_rpcgen.sh" >&2 exit 1 } - -if [ -x /usr/bin/python2 ] ; then - PYTHON2=/usr/bin/python2 -elif [ "x`which python2`" != x ] ; then - PYTHON2=python2 -else - PYTHON2=python -fi - srcdir=$1 srcdir=${srcdir:-.} -${PYTHON2} ${srcdir}/../event_rpcgen.py --quiet ${srcdir}/regress.rpc \ +${srcdir}/../event_rpcgen.py --quiet ${srcdir}/regress.rpc \ test/regress.gen.h test/regress.gen.c case "$?" in diff --git a/test/test.sh b/test/test.sh index dd3d9867..f91a8b04 100755 --- a/test/test.sh +++ b/test/test.sh @@ -82,8 +82,8 @@ run_tests () { fi done announce_n " test-dumpevents: " - if python2 -c 'import sys; assert(sys.version_info >= (2, 4))' 2>/dev/null && test -f $TEST_SRC_DIR/check-dumpevents.py; then - if $TEST_DIR/test-dumpevents | python2 $TEST_SRC_DIR/check-dumpevents.py >> "$TEST_OUTPUT_FILE" ; + if python -c 'import sys; assert(sys.version_info >= (2, 4))' 2>/dev/null && test -f $TEST_SRC_DIR/check-dumpevents.py; then + if $TEST_DIR/test-dumpevents | $TEST_SRC_DIR/check-dumpevents.py >> "$TEST_OUTPUT_FILE" ; then announce OKAY ; else -- cgit v1.2.1 From 7e91622b68dfbfcb7a8e32c136311aca2e37fbb9 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Wed, 13 Sep 2017 21:39:32 +0300 Subject: fix handling of close_notify (ssl) in http with openssl bufferevents Since it can arrive after we disabled events in that bufferevent and reseted fd, hence evhttp_error_cb() could be called after SSL_RECEIVED_SHUTDOWN. Closes: #557 (cherry picked from commit da3f2ba22adcabaf7355a90d537b4928d0c168d2) --- http.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/http.c b/http.c index f5a2ef93..3983b3dd 100644 --- a/http.c +++ b/http.c @@ -1309,6 +1309,8 @@ evhttp_connection_reset_(struct evhttp_connection *evcon) struct evbuffer *tmp; int err; + bufferevent_setcb(evcon->bufev, NULL, NULL, NULL, NULL); + /* XXXX This is not actually an optimal fix. Instead we ought to have an API for "stop connecting", or use bufferevent_setfd to turn off connecting. But for Libevent 2.0, this seems like a minimal change -- cgit v1.2.1 From 5b40744d1581447f5b4496ee8d4807383e468e7a Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 23 Oct 2017 00:13:37 +0300 Subject: Fix crashing http server when callback do not reply in place General http callback looks like: static void http_cb(struct evhttp_request *req, void *arg) { evhttp_send_reply(req, HTTP_OK, "Everything is fine", NULL); } And they will work fine becuase in this case http will write request first, and during write preparation it will disable *read callback* (in evhttp_write_buffer()), but if we don't reply immediately, for example: static void http_cb(struct evhttp_request *req, void *arg) { return; } This will leave connection in incorrect state, and if another request will be written to the same connection libevent will abort with: [err] ../http.c: illegal connection state 7 Because it thinks that read for now is not possible, since there were no write. Fix this by disabling EV_READ entirely. We couldn't just reset callbacks because this will leave EOF detection, which we don't need, since user hasn't replied to callback yet. Reported-by: Cory Fields (cherry picked from commit 5ff8eb26371c4dc56f384b2de35bea2d87814779) --- http.c | 8 ++++--- test/regress_http.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 3 deletions(-) diff --git a/http.c b/http.c index 3983b3dd..8aa2b120 100644 --- a/http.c +++ b/http.c @@ -368,15 +368,15 @@ evhttp_write_buffer(struct evhttp_connection *evcon, evcon->cb_arg = arg; /* Disable the read callback: we don't actually care about data; - * we only care about close detection. (We don't disable reading, - * since we *do* want to learn about any close events.) */ + * we only care about close detection. (We don't disable reading -- + * EV_READ, since we *do* want to learn about any close events.) */ bufferevent_setcb(evcon->bufev, NULL, /*read*/ evhttp_write_cb, evhttp_error_cb, evcon); - bufferevent_enable(evcon->bufev, EV_WRITE); + bufferevent_enable(evcon->bufev, EV_READ|EV_WRITE); } static void @@ -3437,6 +3437,8 @@ evhttp_handle_request(struct evhttp_request *req, void *arg) } if ((cb = evhttp_dispatch_callback(&http->callbacks, req)) != NULL) { + bufferevent_disable(req->evcon->bufev, EV_READ); + (*cb->cb)(req, cb->cbarg); return; } diff --git a/test/regress_http.c b/test/regress_http.c index 58ccf1f7..86fdf433 100644 --- a/test/regress_http.c +++ b/test/regress_http.c @@ -72,6 +72,7 @@ static struct event_base *exit_base; static char const BASIC_REQUEST_BODY[] = "This is funny"; static void http_basic_cb(struct evhttp_request *req, void *arg); +static void http_timeout_cb(struct evhttp_request *req, void *arg); static void http_large_cb(struct evhttp_request *req, void *arg); static void http_chunked_cb(struct evhttp_request *req, void *arg); static void http_post_cb(struct evhttp_request *req, void *arg); @@ -146,6 +147,7 @@ http_setup(ev_uint16_t *pport, struct event_base *base, int mask) /* Register a callback for certain types of requests */ evhttp_set_cb(myhttp, "/test", http_basic_cb, myhttp); + evhttp_set_cb(myhttp, "/timeout", http_timeout_cb, myhttp); evhttp_set_cb(myhttp, "/large", http_large_cb, base); evhttp_set_cb(myhttp, "/chunked", http_chunked_cb, base); evhttp_set_cb(myhttp, "/streamed", http_chunked_cb, base); @@ -346,6 +348,20 @@ end: evbuffer_free(evb); } +static void http_timeout_reply_cb(int fd, short events, void *arg) +{ + struct evhttp_request *req = arg; + evhttp_send_reply(req, HTTP_OK, "Everything is fine", NULL); + test_ok++; +} +static void +http_timeout_cb(struct evhttp_request *req, void *arg) +{ + struct timeval when = { 0, 100 }; + event_base_once(exit_base, -1, EV_TIMEOUT, + http_timeout_reply_cb, req, &when); +} + static void http_large_cb(struct evhttp_request *req, void *arg) { @@ -4510,6 +4526,54 @@ http_request_own_test(void *arg) test_ok = 1; } +static void +http_request_extra_body_test(void *arg) +{ + struct basic_test_data *data = arg; + struct bufferevent *bev = NULL; + evutil_socket_t fd; + ev_uint16_t port = 0; + int i; + struct evhttp *http = http_setup(&port, data->base, 0); + struct evbuffer *out, *body = NULL; + + exit_base = data->base; + test_ok = 0; + + fd = http_connect("127.0.0.1", port); + + /* Stupid thing to send a request */ + bev = create_bev(data->base, fd, 0); + bufferevent_setcb(bev, http_readcb, http_writecb, + http_errorcb, data->base); + out = bufferevent_get_output(bev); + body = evbuffer_new(); + + for (i = 0; i < 10000; ++i) + evbuffer_add_printf(body, "this is the body that HEAD should not have"); + + evbuffer_add_printf(out, + "HEAD /timeout HTTP/1.1\r\n" + "Host: somehost\r\n" + "Connection: close\r\n" + "Content-Length: %i\r\n" + "\r\n", + (int)evbuffer_get_length(body) + ); + evbuffer_add_buffer(out, body); + + event_base_dispatch(data->base); + + tt_assert(test_ok == -2); + + end: + evhttp_free(http); + if (bev) + bufferevent_free(bev); + if (body) + evbuffer_free(body); +} + #define HTTP_LEGACY(name) \ { #name, run_legacy_test_fn, TT_ISOLATED|TT_LEGACY, &legacy_setup, \ http_##name##_test } @@ -4629,6 +4693,8 @@ struct testcase_t http_testcases[] = { HTTP(write_during_read), HTTP(request_own), + HTTP(request_extra_body), + #ifdef EVENT__HAVE_OPENSSL HTTPS(basic), HTTPS(filter_basic), -- cgit v1.2.1 From 826f1134b879cafdb73fed6c4ac1174e3022e410 Mon Sep 17 00:00:00 2001 From: Andreas Gustafsson Date: Tue, 26 Sep 2017 19:23:29 +0300 Subject: Do not crash when evhttp_send_reply_start() is called after a timeout. This fixes the crash reported in issue #509. The "would be nice" items discussed in #509 can be addressed separately. (cherry picked from commit 99d0a952dada771b91acf63f5208b994e80a2986) --- http.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/http.c b/http.c index 8aa2b120..d6dfeea1 100644 --- a/http.c +++ b/http.c @@ -2822,6 +2822,10 @@ evhttp_send_reply_start(struct evhttp_request *req, int code, const char *reason) { evhttp_response_code_(req, code, reason); + + if (req->evcon == NULL) + return; + if (evhttp_find_header(req->output_headers, "Content-Length") == NULL && REQ_VERSION_ATLEAST(req, 1, 1) && evhttp_response_needs_body(req)) { -- cgit v1.2.1 From 23eb38b9713121b89f984254d7c5c588e8ebe915 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 29 Oct 2017 22:53:41 +0300 Subject: Allow bodies for GET/DELETE/OPTIONS/CONNECT I checked with nginx, and via it's lua bindings it allows body for all this methods. Also everybody knows that some of web-servers allows body for GET even though this is not RFC conformant. Refs: #408 (cherry picked from commit db483e3b002b33890fc88cadd77f6fd1fccad2d2) --- http.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/http.c b/http.c index d6dfeea1..db0fdc21 100644 --- a/http.c +++ b/http.c @@ -2129,7 +2129,7 @@ evhttp_get_body_length(struct evhttp_request *req) event_warnx("%s: we got no content length, but the " "server wants to keep the connection open: %s.", __func__, connection); - return (-1); + req->ntoread = 0; } else if (content_length == NULL) { req->ntoread = -1; } else { @@ -2157,16 +2157,15 @@ evhttp_method_may_have_body(enum evhttp_cmd_type type) case EVHTTP_REQ_POST: case EVHTTP_REQ_PUT: case EVHTTP_REQ_PATCH: - return 1; - case EVHTTP_REQ_TRACE: - return 0; - /* XXX May any of the below methods have a body? */ + case EVHTTP_REQ_GET: - case EVHTTP_REQ_HEAD: case EVHTTP_REQ_DELETE: case EVHTTP_REQ_OPTIONS: case EVHTTP_REQ_CONNECT: - return 0; + return 1; + + case EVHTTP_REQ_TRACE: + case EVHTTP_REQ_HEAD: default: return 0; } -- cgit v1.2.1 From 4a2373eec0f8e263737f07ae569970e14019597b Mon Sep 17 00:00:00 2001 From: lightningkay Date: Thu, 2 Nov 2017 14:58:17 +0800 Subject: cmake doesn't has POLICY CMP0054 in low version (cherry picked from commit 3f19c5eb8335500ca6f0dd3b62c32d06103757d0) --- CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d5273a87..3e1b0f71 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,7 +23,10 @@ if (APPLE) else() cmake_minimum_required(VERSION 2.8.3 FATAL_ERROR) endif() -cmake_policy(SET CMP0054 NEW) + +if (POLICY CMP0054) + cmake_policy(SET CMP0054 NEW) +endif() if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release -- cgit v1.2.1 From b25813800f97179b2355a7b4b3557e6a7f568df2 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sat, 4 Nov 2017 19:13:28 +0300 Subject: Fix crashing http server when callback do not reply in place from *gencb* This is the second hunk of the first patch 5ff8eb26371c4dc56f384b2de35bea2d87814779 ("Fix crashing http server when callback do not reply in place") Fixes: #567 (cherry picked from commit 306747e51c1f0de679a3b165b9429418c89f8d6a) --- http.c | 4 ++-- test/regress_http.c | 66 ++++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 50 insertions(+), 20 deletions(-) diff --git a/http.c b/http.c index db0fdc21..4a77fbb8 100644 --- a/http.c +++ b/http.c @@ -3421,6 +3421,8 @@ evhttp_handle_request(struct evhttp_request *req, void *arg) /* we have a new request on which the user needs to take action */ req->userdone = 0; + bufferevent_disable(req->evcon->bufev, EV_READ); + if (req->type == 0 || req->uri == NULL) { evhttp_send_error(req, req->response_code, NULL); return; @@ -3440,8 +3442,6 @@ evhttp_handle_request(struct evhttp_request *req, void *arg) } if ((cb = evhttp_dispatch_callback(&http->callbacks, req)) != NULL) { - bufferevent_disable(req->evcon->bufev, EV_READ); - (*cb->cb)(req, cb->cbarg); return; } diff --git a/test/regress_http.c b/test/regress_http.c index 86fdf433..b761df0d 100644 --- a/test/regress_http.c +++ b/test/regress_http.c @@ -129,7 +129,8 @@ https_bev(struct event_base *base, void *arg) } #endif static struct evhttp * -http_setup(ev_uint16_t *pport, struct event_base *base, int mask) +http_setup_gencb(ev_uint16_t *pport, struct event_base *base, int mask, + void (*cb)(struct evhttp_request *, void *), void *cbarg) { struct evhttp *myhttp; @@ -145,6 +146,8 @@ http_setup(ev_uint16_t *pport, struct event_base *base, int mask) } #endif + evhttp_set_gencb(myhttp, cb, cbarg); + /* Register a callback for certain types of requests */ evhttp_set_cb(myhttp, "/test", http_basic_cb, myhttp); evhttp_set_cb(myhttp, "/timeout", http_timeout_cb, myhttp); @@ -161,6 +164,9 @@ http_setup(ev_uint16_t *pport, struct event_base *base, int mask) evhttp_set_cb(myhttp, "/", http_dispatcher_cb, base); return (myhttp); } +static struct evhttp * +http_setup(ev_uint16_t *pport, struct event_base *base, int mask) +{ return http_setup_gencb(pport, base, mask, NULL, NULL); } #ifndef NI_MAXSERV #define NI_MAXSERV 1024 @@ -4526,44 +4532,68 @@ http_request_own_test(void *arg) test_ok = 1; } +static void http_run_bev_request(struct event_base *base, int port, + const char *fmt, ...) +{ + struct bufferevent *bev = NULL; + va_list ap; + evutil_socket_t fd; + struct evbuffer *out; + + fd = http_connect("127.0.0.1", port); + + /* Stupid thing to send a request */ + bev = create_bev(base, fd, 0); + bufferevent_setcb(bev, http_readcb, http_writecb, + http_errorcb, base); + out = bufferevent_get_output(bev); + + va_start(ap, fmt); + evbuffer_add_vprintf(out, fmt, ap); + va_end(ap); + + event_base_dispatch(base); + + bufferevent_free(bev); +} static void http_request_extra_body_test(void *arg) { struct basic_test_data *data = arg; struct bufferevent *bev = NULL; - evutil_socket_t fd; ev_uint16_t port = 0; int i; - struct evhttp *http = http_setup(&port, data->base, 0); - struct evbuffer *out, *body = NULL; + struct evhttp *http = + http_setup_gencb(&port, data->base, 0, http_timeout_cb, NULL); + struct evbuffer *body = NULL; exit_base = data->base; test_ok = 0; - fd = http_connect("127.0.0.1", port); - - /* Stupid thing to send a request */ - bev = create_bev(data->base, fd, 0); - bufferevent_setcb(bev, http_readcb, http_writecb, - http_errorcb, data->base); - out = bufferevent_get_output(bev); body = evbuffer_new(); - for (i = 0; i < 10000; ++i) evbuffer_add_printf(body, "this is the body that HEAD should not have"); - evbuffer_add_printf(out, + http_run_bev_request(data->base, port, "HEAD /timeout HTTP/1.1\r\n" "Host: somehost\r\n" "Connection: close\r\n" "Content-Length: %i\r\n" - "\r\n", - (int)evbuffer_get_length(body) + "\r\n%s", + (int)evbuffer_get_length(body), + evbuffer_pullup(body, -1) ); - evbuffer_add_buffer(out, body); - - event_base_dispatch(data->base); + tt_assert(test_ok == -2); + http_run_bev_request(data->base, port, + "HEAD /__gencb__ HTTP/1.1\r\n" + "Host: somehost\r\n" + "Connection: close\r\n" + "Content-Length: %i\r\n" + "\r\n%s", + (int)evbuffer_get_length(body), + evbuffer_pullup(body, -1) + ); tt_assert(test_ok == -2); end: -- cgit v1.2.1 From da4619b3c9d5fc218255e64b310bc9f763275e25 Mon Sep 17 00:00:00 2001 From: ejurgensen Date: Sun, 5 Nov 2017 12:18:49 +0100 Subject: Fix incorrect ref to evhttp_get_decoded_uri in http.h Replaces reference in the http.h include header file to evhttp_get_decoded_uri with evhttp_uridecode. There is no function called evhttp_get_decoded_uri. (cherry picked from commit b49c70cc2ed54f511e2b41f7ed61d357c88300be) --- include/event2/http.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/event2/http.h b/include/event2/http.h index acee5520..2a41303e 100644 --- a/include/event2/http.h +++ b/include/event2/http.h @@ -930,14 +930,14 @@ char *evhttp_uriencode(const char *str, ev_ssize_t size, int space_to_plus); /** Helper function to sort of decode a URI-encoded string. Unlike - evhttp_get_decoded_uri, it decodes all plus characters that appear + evhttp_uridecode, it decodes all plus characters that appear _after_ the first question mark character, but no plusses that occur before. This is not a good way to decode URIs in whole or in part. The returned string must be freed by the caller @deprecated This function is deprecated; you probably want to use - evhttp_get_decoded_uri instead. + evhttp_uridecode instead. @param uri an encoded URI @return a newly allocated unencoded URI or NULL on failure -- cgit v1.2.1 From 27b59783f352bbef4f0c6346f62ca9637c85ac35 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 20 Nov 2017 02:07:54 +0300 Subject: Free dns/event bases in dns-example to avoid leaks (cherry picked from commit 33e363f3dfcd21f5125134395e4a7b3531bc3066) --- sample/dns-example.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sample/dns-example.c b/sample/dns-example.c index e180edfe..6243458a 100644 --- a/sample/dns-example.c +++ b/sample/dns-example.c @@ -252,6 +252,8 @@ main(int c, char **v) { } fflush(stdout); event_base_dispatch(event_base); + evdns_base_free(evdns_base, 1); + event_base_free(event_base); return 0; } -- cgit v1.2.1 From 01bc36c1f49b55058b4a5cfa541bd60d69bed86d Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Wed, 22 Nov 2017 10:33:15 +0300 Subject: Add missing includes into openssl-compat.h Before it depends from the caller #include appropriate headers (at least for OPENSSL_VERSION_NUMBER), but let's make it independent. Fixes: #574 (cherry picked from commit c2c08e0203da93938fe35234fa3a1be4d1c3c2e1) --- bufferevent_openssl.c | 1 - openssl-compat.h | 3 +++ sample/le-proxy.c | 1 - test/regress_ssl.c | 1 - 4 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bufferevent_openssl.c b/bufferevent_openssl.c index f7f5c0f1..6a803a63 100644 --- a/bufferevent_openssl.c +++ b/bufferevent_openssl.c @@ -63,7 +63,6 @@ #include "bufferevent-internal.h" #include "log-internal.h" -#include #include #include #include "openssl-compat.h" diff --git a/openssl-compat.h b/openssl-compat.h index 0f2dcb75..bffd2593 100644 --- a/openssl-compat.h +++ b/openssl-compat.h @@ -1,6 +1,9 @@ #ifndef OPENSSL_COMPAT_H #define OPENSSL_COMPAT_H +#include +#include "util-internal.h" + #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) static inline BIO_METHOD *BIO_meth_new(int type, const char *name) diff --git a/sample/le-proxy.c b/sample/le-proxy.c index c764afc7..4e1cf033 100644 --- a/sample/le-proxy.c +++ b/sample/le-proxy.c @@ -31,7 +31,6 @@ #include #include "util-internal.h" -#include #include #include #include diff --git a/test/regress_ssl.c b/test/regress_ssl.c index 490853fc..5004f7e8 100644 --- a/test/regress_ssl.c +++ b/test/regress_ssl.c @@ -53,7 +53,6 @@ #include "tinytest.h" #include "tinytest_macros.h" -#include #include #include #include "openssl-compat.h" -- cgit v1.2.1 From 7fa08c4b75fa394aaa5884393edd489a5a68319e Mon Sep 17 00:00:00 2001 From: Andrey Okoshkin Date: Wed, 29 Nov 2017 11:13:51 +0300 Subject: Fix generation of LibeventConfig.cmake for the installation tree 'LIBEVENT_INCLUDE_DIRS' is properly initialized in 'LibeventConfig.cmake' as 'LibeventConfig.cmake.in' contains usage of 'LIBEVENT_CMAKE_DIR' and 'EVENT_INSTALL_INCLUDE_DIR' variables but not 'EVENT_CMAKE_DIR' and 'EVENT__INCLUDE_DIRS'. Related typos are fixed. (cherry picked from commit 6ee73ea9b0b15a9f4909c51e171b7799210ec26c) --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3e1b0f71..123f9cdb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1324,11 +1324,11 @@ file(RELATIVE_PATH "${EVENT_INSTALL_CMAKE_DIR}" "${CMAKE_INSTALL_PREFIX}/include") -# Note the EVENT_CMAKE_DIR is defined in LibeventConfig.cmake.in, +# Note the LIBEVENT_CMAKE_DIR is defined in LibeventConfig.cmake.in, # we escape it here so it's evaluated when it is included instead -# so that the include dirs are givenrelative to where the +# so that the include dirs are given relative to where the # config file is located. -set(EVENT__INCLUDE_DIRS "\${EVENT_CMAKE_DIR}/${REL_INCLUDE_DIR}") +set(EVENT_INSTALL_INCLUDE_DIR "\${LIBEVENT_CMAKE_DIR}/${REL_INCLUDE_DIR}") configure_file(${PROJECT_SOURCE_DIR}/cmake/LibeventConfig.cmake.in ${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/LibeventConfig.cmake -- cgit v1.2.1 From 42e851bb8c38e799bbd31fcf0a4c6b11fdb10df6 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 10 Dec 2017 23:57:19 +0300 Subject: Merge branch 'evconnlistener-do-not-close-client-fd' Fixes: #577 * evconnlistener-do-not-close-client-fd: listener: cover closing of fd in case evconnlistener_free() called from acceptcb Revert "Fix potential fd leak in listener_read_cb()" (cherry picked from commit bc65ffc14c62c10feffefe6c3d9975ce1d1a8cd8) --- listener.c | 2 -- test/regress_listener.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/listener.c b/listener.c index 2862d32e..942fa451 100644 --- a/listener.c +++ b/listener.c @@ -421,8 +421,6 @@ listener_read_cb(evutil_socket_t fd, short what, void *p) if (lev->refcnt == 1) { int freed = listener_decref_and_unlock(lev); EVUTIL_ASSERT(freed); - - evutil_closesocket(new_fd); return; } --lev->refcnt; diff --git a/test/regress_listener.c b/test/regress_listener.c index 72f7237b..32f23074 100644 --- a/test/regress_listener.c +++ b/test/regress_listener.c @@ -185,6 +185,51 @@ end: evconnlistener_free(listener); } +static void +acceptcb_free(struct evconnlistener *listener, evutil_socket_t fd, + struct sockaddr *addr, int socklen, void *arg) +{ + int *ptr = arg; + --*ptr; + TT_BLATHER(("Got one for %p", ptr)); + evutil_closesocket(fd); + + if (! *ptr) + evconnlistener_free(listener); +} +static void +regress_listener_close_accepted_fd(void *arg) +{ + struct basic_test_data *data = arg; + struct event_base *base = data->base; + struct evconnlistener *listener = NULL; + struct sockaddr_in sin; + struct sockaddr_storage ss; + ev_socklen_t slen = sizeof(ss); + int count = 1; + unsigned int flags = LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE; + int fd = -1; + + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = htonl(0x7f000001); /* 127.0.0.1 */ + sin.sin_port = 0; /* "You pick!" */ + + /* Start a listener with a bogus socket. */ + listener = evconnlistener_new_bind(base, acceptcb_free, &count, + flags, -1, (struct sockaddr *)&sin, sizeof(sin)); + tt_assert(listener); + + tt_assert(getsockname(evconnlistener_get_fd(listener), + (struct sockaddr*)&ss, &slen) == 0); + evutil_socket_connect_(&fd, (struct sockaddr*)&ss, slen); + + event_base_dispatch(base); + +end: + ; +} + #ifdef EVENT__HAVE_SETRLIMIT static void regress_listener_error_unlock(void *arg) @@ -242,6 +287,9 @@ struct testcase_t listener_testcases[] = { TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR, &basic_setup, (char*)"ts"}, + { "close_accepted_fd", regress_listener_close_accepted_fd, + TT_FORK|TT_NEED_BASE, &basic_setup, NULL, }, + END_OF_TESTCASES, }; -- cgit v1.2.1 From 27dee54d039f7cdb07f1c9e107262a679eb70c05 Mon Sep 17 00:00:00 2001 From: "yongqing.jiao" Date: Sat, 9 Dec 2017 14:39:07 +0800 Subject: If precise_time is false, we should not set EVENT_BASE_FLAG_PRECISE_TIMER Fixes: 630f077c296de61c7b99ed83bf30de11e75e2740 ("Simple unit tests for monotonic timers") (cherry picked from commit 6cce7458d0f94e320f201eb5be94866e6918d66c) --- event.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/event.c b/event.c index 98b1bc4a..3e24d3d4 100644 --- a/event.c +++ b/event.c @@ -591,7 +591,9 @@ event_base_new_with_config(const struct event_config *cfg) int flags; if (should_check_environment && !precise_time) { precise_time = evutil_getenv_("EVENT_PRECISE_TIMER") != NULL; - base->flags |= EVENT_BASE_FLAG_PRECISE_TIMER; + if (precise_time) { + base->flags |= EVENT_BASE_FLAG_PRECISE_TIMER; + } } flags = precise_time ? EV_MONOT_PRECISE : 0; evutil_configure_monotonic_time_(&base->monotonic_timer, flags); -- cgit v1.2.1 From 7d1ffe64742385fa0f1f8947eeb31a9a7b3e4eb3 Mon Sep 17 00:00:00 2001 From: Greg Hazel Date: Sat, 2 Dec 2017 12:53:57 -0800 Subject: CONNECT method only takes an authority (cherry picked from commit 65eb529a9f4dd886d01a9d77ce6d971de9fb1b97) --- http.c | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/http.c b/http.c index 4a77fbb8..b3087b5b 100644 --- a/http.c +++ b/http.c @@ -173,6 +173,7 @@ extern int debug; static evutil_socket_t bind_socket_ai(struct evutil_addrinfo *, int reuse); static evutil_socket_t bind_socket(const char *, ev_uint16_t, int reuse); static void name_from_addr(struct sockaddr *, ev_socklen_t, char **, char **); +static struct evhttp_uri *evhttp_uri_parse_authority(char *source_uri); static int evhttp_associate_new_request_with_connection( struct evhttp_connection *evcon); static void evhttp_connection_start_detectclose( @@ -1831,9 +1832,15 @@ evhttp_parse_request_line(struct evhttp_request *req, char *line) return (-1); } - if ((req->uri_elems = evhttp_uri_parse_with_flags(req->uri, - EVHTTP_URI_NONCONFORMANT)) == NULL) { - return -1; + if (type == EVHTTP_REQ_CONNECT) { + if ((req->uri_elems = evhttp_uri_parse_authority(req->uri)) == NULL) { + return -1; + } + } else { + if ((req->uri_elems = evhttp_uri_parse_with_flags(req->uri, + EVHTTP_URI_NONCONFORMANT)) == NULL) { + return -1; + } } /* If we have an absolute-URI, check to see if it is an http request @@ -4828,6 +4835,34 @@ err: return NULL; } +static struct evhttp_uri * +evhttp_uri_parse_authority(char *source_uri) +{ + struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri)); + if (uri == NULL) { + event_warn("%s: calloc", __func__); + goto err; + } + uri->port = -1; + uri->flags = 0; + + char *end = end_of_authority(source_uri); + if (parse_authority(uri, source_uri, end) < 0) + goto err; + + uri->path = mm_strdup(""); + if (uri->path == NULL) { + event_warn("%s: strdup", __func__); + goto err; + } + + return uri; +err: + if (uri) + evhttp_uri_free(uri); + return NULL; +} + void evhttp_uri_free(struct evhttp_uri *uri) { -- cgit v1.2.1 From 3375750ad7cda30088ffe7041b536bcf80ad2384 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sat, 16 Dec 2017 23:28:41 +0300 Subject: Fix typo in cmake because of which EVENT__SIZEOF_SIZE_T was wrong Fixes: #580 (cherry picked from commit 6e5c15d095d37036553d491b52d27fbbda08e7f2) --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 123f9cdb..64ece249 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -430,7 +430,7 @@ CHECK_SYMBOL_EXISTS(F_SETFD fcntl.h EVENT__HAVE_SETFD) CHECK_TYPE_SIZE(fd_mask EVENT__HAVE_FD_MASK) -CHECK_TYPE_SIZE(size_t EVENT__SIZEOF_SIZEE_T) +CHECK_TYPE_SIZE(size_t EVENT__SIZEOF_SIZE_T) if(NOT EVENT__SIZEOF_SIZE_T) set(EVENT__size_t "unsigned") set(EVENT__SIZEOF_SIZE_T ${EVENT__SIZEOF_UNSIGNED}) -- cgit v1.2.1 From caceb8f5585e1696cf18c8543f72add370df9177 Mon Sep 17 00:00:00 2001 From: Marcin Szewczyk Date: Mon, 18 Dec 2017 14:01:15 +0100 Subject: Fixed last_with_datap description Grammar and typo fix (cherry picked from commit 88a1abe809e5d29618b722ff81ee2fb14119314f) --- evbuffer-internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evbuffer-internal.h b/evbuffer-internal.h index cf4bddc8..d09b4f1d 100644 --- a/evbuffer-internal.h +++ b/evbuffer-internal.h @@ -92,7 +92,7 @@ struct evbuffer { * If the buffer has no chains, it is NULL. * * The last_with_datap pointer points at _whatever 'next' pointer_ - * points at the last_with_datap chain. If the last_with_data chain + * pointing at the last_with_data chain. If the last_with_data chain * is the first chain, or it is NULL, then the last_with_datap pointer * is &buf->first. */ -- cgit v1.2.1 From df2ed13f8f3b1cc286965f6909e3cd80420828d6 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Thu, 4 Jan 2018 19:28:59 +0300 Subject: Merge branch 'listener-immediate-close' * listener-immediate-close: test/listener: cover immediate-close logic Immediately stop trying to accept more connections if listener disabled (cherry picked from commit 416b48ba7a0b44407b7a053bd21830aa75d7162f) --- listener.c | 5 +++++ test/regress_listener.c | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/listener.c b/listener.c index 942fa451..2835df17 100644 --- a/listener.c +++ b/listener.c @@ -424,6 +424,11 @@ listener_read_cb(evutil_socket_t fd, short what, void *p) return; } --lev->refcnt; + if (!lev->enabled) { + /* the callback could have disabled the listener */ + UNLOCK(lev); + return; + } } err = evutil_socket_geterror(fd); if (EVUTIL_ERR_ACCEPT_RETRIABLE(err)) { diff --git a/test/regress_listener.c b/test/regress_listener.c index 32f23074..070e5e34 100644 --- a/test/regress_listener.c +++ b/test/regress_listener.c @@ -230,6 +230,44 @@ end: ; } +static void +regress_listener_immediate_close(void *arg) +{ + struct basic_test_data *data = arg; + struct event_base *base = data->base; + struct evconnlistener *listener = NULL; + struct sockaddr_in sin; + struct sockaddr_storage ss; + ev_socklen_t slen = sizeof(ss); + int count = 1; + unsigned int flags = LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE; + int fd1 = -1, fd2 = -1; + + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = htonl(0x7f000001); /* 127.0.0.1 */ + sin.sin_port = 0; /* "You pick!" */ + + /* Start a listener with a bogus socket. */ + listener = evconnlistener_new_bind(base, acceptcb, &count, + flags, -1, (struct sockaddr *)&sin, sizeof(sin)); + tt_assert(listener); + + tt_assert(getsockname(evconnlistener_get_fd(listener), + (struct sockaddr*)&ss, &slen) == 0); + + evutil_socket_connect_(&fd1, (struct sockaddr*)&ss, slen); + evutil_socket_connect_(&fd2, (struct sockaddr*)&ss, slen); + + event_base_dispatch(base); + + tt_int_op(count, ==, 0); + +end: + if (listener) + evconnlistener_free(listener); +} + #ifdef EVENT__HAVE_SETRLIMIT static void regress_listener_error_unlock(void *arg) @@ -290,6 +328,9 @@ struct testcase_t listener_testcases[] = { { "close_accepted_fd", regress_listener_close_accepted_fd, TT_FORK|TT_NEED_BASE, &basic_setup, NULL, }, + { "immediate_close", regress_listener_immediate_close, + TT_FORK|TT_NEED_BASE, &basic_setup, NULL, }, + END_OF_TESTCASES, }; -- cgit v1.2.1 From 123362e9a81ca4b6d3944357f80e508896837049 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 9 Jan 2018 21:44:57 +0300 Subject: http: fix leaks in evhttp_uriencode() Fixes: #584 (cherry picked from commit 61c21492680505706cad9240c39666ee3b56a89c) --- http.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/http.c b/http.c index b3087b5b..196ddd1d 100644 --- a/http.c +++ b/http.c @@ -3071,16 +3071,15 @@ evhttp_uriencode(const char *uri, ev_ssize_t len, int space_as_plus) { struct evbuffer *buf = evbuffer_new(); const char *p, *end; - char *result; + char *result = NULL; - if (buf == NULL) { - return (NULL); + if (!buf) { + goto out; } - if (len >= 0) { if (uri + len < uri) { - return (NULL); + goto out; } end = uri + len; @@ -3089,11 +3088,11 @@ evhttp_uriencode(const char *uri, ev_ssize_t len, int space_as_plus) if (slen >= EV_SSIZE_MAX) { /* we don't want to mix signed and unsigned */ - return (NULL); + goto out; } if (uri + slen < uri) { - return (NULL); + goto out; } end = uri + slen; @@ -3115,9 +3114,10 @@ evhttp_uriencode(const char *uri, ev_ssize_t len, int space_as_plus) if (result) evbuffer_remove(buf, result, evbuffer_get_length(buf)); - evbuffer_free(buf); - - return (result); +out: + if (buf) + evbuffer_free(buf); + return result; } char * -- cgit v1.2.1 From 6200b821ebac42b2ba432e8b5351ea5f1b5e077a Mon Sep 17 00:00:00 2001 From: Dmitry Alimov Date: Mon, 15 Jan 2018 17:30:08 +0300 Subject: Fix typos in comments (cherry picked from commit f24b28e4aff1dbc3440e283f70ac15aa7cebcc8d) --- include/event2/event.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/include/event2/event.h b/include/event2/event.h index 2ad2ec83..af56c9ed 100644 --- a/include/event2/event.h +++ b/include/event2/event.h @@ -1029,7 +1029,7 @@ EVENT2_EXPORT_SYMBOL void *event_self_cbarg(void); /** - Allocate and asssign a new event structure, ready to be added. + Allocate and assign a new event structure, ready to be added. The function event_new() returns a new event that can be used in future calls to event_add() and event_del(). The fd and events @@ -1055,10 +1055,10 @@ void *event_self_cbarg(void); The EV_TIMEOUT flag has no effect here. It is okay to have multiple events all listening on the same fds; but - they must either all be edge-triggered, or all not be edge triggerd. + they must either all be edge-triggered, or all not be edge triggered. When the event becomes active, the event loop will run the provided - callbuck function, with three arguments. The first will be the provided + callback function, with three arguments. The first will be the provided fd value. The second will be a bitfield of the events that triggered: EV_READ, EV_WRITE, or EV_SIGNAL. Here the EV_TIMEOUT flag indicates that a timeout occurred, and EV_ET indicates that an edge-triggered @@ -1163,13 +1163,13 @@ typedef void (*event_finalize_callback_fn)(struct event *, void *); event_finalize() does not. A finalizer callback must not make events pending or active. It must not - add events, activate events, or attempt to "resucitate" the event being + add events, activate events, or attempt to "resuscitate" the event being finalized in any way. THIS IS AN EXPERIMENTAL API. IT MIGHT CHANGE BEFORE THE LIBEVENT 2.1 SERIES BECOMES STABLE. - @return 0 on succes, -1 on failure. + @return 0 on success, -1 on failure. */ /**@{*/ EVENT2_EXPORT_SYMBOL @@ -1199,7 +1199,7 @@ int event_free_finalize(unsigned, struct event *, event_finalize_callback_fn); @param arg an argument to be passed to the callback function @param timeout the maximum amount of time to wait for the event. NULL makes an EV_READ/EV_WRITE event make forever; NULL makes an - EV_TIMEOUT event succees immediately. + EV_TIMEOUT event success immediately. @return 0 if successful, or -1 if an error occurred */ EVENT2_EXPORT_SYMBOL @@ -1210,7 +1210,7 @@ int event_base_once(struct event_base *, evutil_socket_t, short, event_callback_ The function event_add() schedules the execution of the event 'ev' when the condition specified by event_assign() or event_new() occurs, or when the time - specified in timeout has elapesed. If atimeout is NULL, no timeout + specified in timeout has elapsed. If a timeout is NULL, no timeout occurs and the function will only be called if a matching event occurs. The event in the ev argument must be already initialized by event_assign() or event_new() @@ -1236,7 +1236,7 @@ int event_add(struct event *ev, const struct timeval *timeout); leaves the event otherwise pending. @param ev an event struct initialized via event_assign() or event_new() - @return 0 on success, or -1 if an error occurrect. + @return 0 on success, or -1 if an error occurred. */ EVENT2_EXPORT_SYMBOL int event_remove_timer(struct event *ev); @@ -1531,7 +1531,7 @@ const struct timeval *event_base_init_common_timeout(struct event_base *base, Note also that if you are going to call this function, you should do so before any call to any Libevent function that does allocation. - Otherwise, those funtions will allocate their memory using malloc(), but + Otherwise, those functions will allocate their memory using malloc(), but then later free it using your provided free_fn. @param malloc_fn A replacement for malloc. @@ -1627,7 +1627,7 @@ int event_base_foreach_event(struct event_base *base, event_base_foreach_event_c cached time. Generally, this value will only be cached while actually - processing event callbacks, and may be very inaccuate if your + processing event callbacks, and may be very inaccurate if your callbacks take a long time to execute. Returns 0 on success, negative on failure. -- cgit v1.2.1 From 2b4d127dbe159c7b559fe75891354d66031ffbe6 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 12 Feb 2018 19:43:13 +0300 Subject: buffer: fix incorrect unlock of the buffer mutex (for deferred callbacks) TSAN reports: WARNING: ThreadSanitizer: unlock of an unlocked mutex (or by a wrong thread) (pid=17111) #0 pthread_mutex_unlock /build/gcc/src/gcc/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:3621 (libtsan.so.0+0x00000003b71c) #1 evbuffer_add (libevent_core-2.2.so.1+0x00000000ddb6) ... Mutex M392 (0x7b0c00000f00) created at: #0 pthread_mutex_init /build/gcc/src/gcc/libsanitizer/tsan/tsan_interceptors.cc:1117 (libtsan.so.0+0x0000000291af) #1 (libevent_pthreads-2.2.so.1+0x000000000d46) ... $ addr2line -e /lib/libevent_core-2.2.so.1 0x00000000ddb6 /src/libevent/buffer.c:1815 (discriminator 1) Introduced-in: ae2b84b2575be93d0aebba5c0b78453836f89f3c ("Replace deferred_cbs with event_callback-based implementation.") (cherry picked from commit 93913da1c4a528e0a832dc8dc163fa30f3e580d4) --- buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buffer.c b/buffer.c index 9a7b2a6a..8113ce6c 100644 --- a/buffer.c +++ b/buffer.c @@ -522,8 +522,8 @@ evbuffer_invoke_callbacks_(struct evbuffer *buffer) evbuffer_incref_and_lock_(buffer); if (buffer->parent) bufferevent_incref_(buffer->parent); + EVBUFFER_UNLOCK(buffer); } - EVBUFFER_UNLOCK(buffer); } evbuffer_run_callbacks(buffer, 0); -- cgit v1.2.1 From 0dfabd347e406588774fb4e509cce8bfd65e335d Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 13 Feb 2018 17:43:02 +0300 Subject: http: remove message in case !Content-Length and Connection!=close Since [1] GET can have body, and hence for every incomming connection it will print this error. [1] db483e3b002b33890fc88cadd77f6fd1fccad2d2 ("Allow bodies for GET/DELETE/OPTIONS/CONNECT") Noticed-by: BotoX (irc) Refs: #408 (cherry picked from commit cd57e38c3f77d0f6a718d9c1f2e3ead78a98bd06) --- http.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/http.c b/http.c index 196ddd1d..8541fdc1 100644 --- a/http.c +++ b/http.c @@ -2132,10 +2132,6 @@ evhttp_get_body_length(struct evhttp_request *req) req->ntoread = -1; else if (content_length == NULL && evutil_ascii_strcasecmp(connection, "Close") != 0) { - /* Bad combination, we don't know when it will end */ - event_warnx("%s: we got no content length, but the " - "server wants to keep the connection open: %s.", - __func__, connection); req->ntoread = 0; } else if (content_length == NULL) { req->ntoread = -1; -- cgit v1.2.1 From 2f060c5f23b849ca82571a823d3be71f42899aff Mon Sep 17 00:00:00 2001 From: stenn Date: Sun, 14 May 2017 06:22:11 -0400 Subject: Provide Makefile variables LIBEVENT_{CFLAGS,CPPFLAGS,LDFLAGS} This will allow a parent package to specify compiler, CPP, and linker flags to a libevent built as a sub-package. Picked-from: #506 Closes: #506 (cherry picked from commit 1a448088e3aef5b6baf161eb0f6d17e18a77313c) --- Makefile.am | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Makefile.am b/Makefile.am index 0c07d77e..9ec7ca2e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -228,7 +228,11 @@ NO_UNDEFINED = MAYBE_CORE = endif -GENERIC_LDFLAGS = -version-info $(VERSION_INFO) $(RELEASE) $(NO_UNDEFINED) +AM_CFLAGS = $(LIBEVENT_CFLAGS) +AM_CPPFLAGS = -I$(srcdir)/compat -I$(srcdir)/include -I./include $(SYS_INCLUDES) $(LIBEVENT_CPPFLAGS) +AM_LDFLAGS = $(LIBEVENT_LDFLAGS) + +GENERIC_LDFLAGS = -version-info $(VERSION_INFO) $(RELEASE) $(NO_UNDEFINED) $(AM_LDFLAGS) libevent_la_SOURCES = $(CORE_SRC) $(EXTRAS_SRC) libevent_la_LIBADD = @LTLIBOBJS@ $(SYS_LIBS) @@ -299,8 +303,6 @@ else noinst_HEADERS += $(EVENT1_HDRS) endif -AM_CPPFLAGS = -I$(srcdir)/compat -I$(srcdir)/include -I./include $(SYS_INCLUDES) - verify: check doxygen: FORCE -- cgit v1.2.1 From f45543e2f8ec737d11cbf4f1756100a657d9273d Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 27 Feb 2018 21:08:35 +0300 Subject: Convert event_debug_*() helpers from macros to static functions (cherry picked from commit f0fd92f2c41fd5bf3b270ee338089dd9329d0354) --- event.c | 275 +++++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 150 insertions(+), 125 deletions(-) diff --git a/event.c b/event.c index 3e24d3d4..17570c27 100644 --- a/event.c +++ b/event.c @@ -229,133 +229,158 @@ HT_PROTOTYPE(event_debug_map, event_debug_entry, node, hash_debug_entry, HT_GENERATE(event_debug_map, event_debug_entry, node, hash_debug_entry, eq_debug_entry, 0.5, mm_malloc, mm_realloc, mm_free) -/* Macro: record that ev is now setup (that is, ready for an add) */ -#define event_debug_note_setup_(ev) do { \ - if (event_debug_mode_on_) { \ - struct event_debug_entry *dent,find; \ - find.ptr = (ev); \ - EVLOCK_LOCK(event_debug_map_lock_, 0); \ - dent = HT_FIND(event_debug_map, &global_debug_map, &find); \ - if (dent) { \ - dent->added = 0; \ - } else { \ - dent = mm_malloc(sizeof(*dent)); \ - if (!dent) \ - event_err(1, \ - "Out of memory in debugging code"); \ - dent->ptr = (ev); \ - dent->added = 0; \ - HT_INSERT(event_debug_map, &global_debug_map, dent); \ - } \ - EVLOCK_UNLOCK(event_debug_map_lock_, 0); \ - } \ - event_debug_mode_too_late = 1; \ - } while (0) -/* Macro: record that ev is no longer setup */ -#define event_debug_note_teardown_(ev) do { \ - if (event_debug_mode_on_) { \ - struct event_debug_entry *dent,find; \ - find.ptr = (ev); \ - EVLOCK_LOCK(event_debug_map_lock_, 0); \ - dent = HT_REMOVE(event_debug_map, &global_debug_map, &find); \ - if (dent) \ - mm_free(dent); \ - EVLOCK_UNLOCK(event_debug_map_lock_, 0); \ - } \ - event_debug_mode_too_late = 1; \ - } while (0) +/* record that ev is now setup (that is, ready for an add) */ +static void event_debug_note_setup_(const struct event *ev) +{ + struct event_debug_entry *dent, find; + + if (!event_debug_mode_on_) { + goto out; + } + + find.ptr = ev; + EVLOCK_LOCK(event_debug_map_lock_, 0); + dent = HT_FIND(event_debug_map, &global_debug_map, &find); + if (dent) { + dent->added = 0; + } else { + dent = mm_malloc(sizeof(*dent)); + if (!dent) + event_err(1, + "Out of memory in debugging code"); + dent->ptr = ev; + dent->added = 0; + HT_INSERT(event_debug_map, &global_debug_map, dent); + } + EVLOCK_UNLOCK(event_debug_map_lock_, 0); + +out: + event_debug_mode_too_late = 1; +} +/* record that ev is no longer setup */ +static void event_debug_note_teardown_(const struct event *ev) +{ + struct event_debug_entry *dent, find; + + if (!event_debug_mode_on_) { + goto out; + } + + find.ptr = ev; + EVLOCK_LOCK(event_debug_map_lock_, 0); + dent = HT_REMOVE(event_debug_map, &global_debug_map, &find); + if (dent) + mm_free(dent); + EVLOCK_UNLOCK(event_debug_map_lock_, 0); + +out: + event_debug_mode_too_late = 1; +} /* Macro: record that ev is now added */ -#define event_debug_note_add_(ev) do { \ - if (event_debug_mode_on_) { \ - struct event_debug_entry *dent,find; \ - find.ptr = (ev); \ - EVLOCK_LOCK(event_debug_map_lock_, 0); \ - dent = HT_FIND(event_debug_map, &global_debug_map, &find); \ - if (dent) { \ - dent->added = 1; \ - } else { \ - event_errx(EVENT_ERR_ABORT_, \ - "%s: noting an add on a non-setup event %p" \ - " (events: 0x%x, fd: "EV_SOCK_FMT \ - ", flags: 0x%x)", \ - __func__, (ev), (ev)->ev_events, \ - EV_SOCK_ARG((ev)->ev_fd), (ev)->ev_flags); \ - } \ - EVLOCK_UNLOCK(event_debug_map_lock_, 0); \ - } \ - event_debug_mode_too_late = 1; \ - } while (0) -/* Macro: record that ev is no longer added */ -#define event_debug_note_del_(ev) do { \ - if (event_debug_mode_on_) { \ - struct event_debug_entry *dent,find; \ - find.ptr = (ev); \ - EVLOCK_LOCK(event_debug_map_lock_, 0); \ - dent = HT_FIND(event_debug_map, &global_debug_map, &find); \ - if (dent) { \ - dent->added = 0; \ - } else { \ - event_errx(EVENT_ERR_ABORT_, \ - "%s: noting a del on a non-setup event %p" \ - " (events: 0x%x, fd: "EV_SOCK_FMT \ - ", flags: 0x%x)", \ - __func__, (ev), (ev)->ev_events, \ - EV_SOCK_ARG((ev)->ev_fd), (ev)->ev_flags); \ - } \ - EVLOCK_UNLOCK(event_debug_map_lock_, 0); \ - } \ - event_debug_mode_too_late = 1; \ - } while (0) -/* Macro: assert that ev is setup (i.e., okay to add or inspect) */ -#define event_debug_assert_is_setup_(ev) do { \ - if (event_debug_mode_on_) { \ - struct event_debug_entry *dent,find; \ - find.ptr = (ev); \ - EVLOCK_LOCK(event_debug_map_lock_, 0); \ - dent = HT_FIND(event_debug_map, &global_debug_map, &find); \ - if (!dent) { \ - event_errx(EVENT_ERR_ABORT_, \ - "%s called on a non-initialized event %p" \ - " (events: 0x%x, fd: "EV_SOCK_FMT\ - ", flags: 0x%x)", \ - __func__, (ev), (ev)->ev_events, \ - EV_SOCK_ARG((ev)->ev_fd), (ev)->ev_flags); \ - } \ - EVLOCK_UNLOCK(event_debug_map_lock_, 0); \ - } \ - } while (0) -/* Macro: assert that ev is not added (i.e., okay to tear down or set - * up again) */ -#define event_debug_assert_not_added_(ev) do { \ - if (event_debug_mode_on_) { \ - struct event_debug_entry *dent,find; \ - find.ptr = (ev); \ - EVLOCK_LOCK(event_debug_map_lock_, 0); \ - dent = HT_FIND(event_debug_map, &global_debug_map, &find); \ - if (dent && dent->added) { \ - event_errx(EVENT_ERR_ABORT_, \ - "%s called on an already added event %p" \ - " (events: 0x%x, fd: "EV_SOCK_FMT", " \ - "flags: 0x%x)", \ - __func__, (ev), (ev)->ev_events, \ - EV_SOCK_ARG((ev)->ev_fd), (ev)->ev_flags); \ - } \ - EVLOCK_UNLOCK(event_debug_map_lock_, 0); \ - } \ - } while (0) +static void event_debug_note_add_(const struct event *ev) +{ + struct event_debug_entry *dent,find; + + if (!event_debug_mode_on_) { + goto out; + } + + find.ptr = ev; + EVLOCK_LOCK(event_debug_map_lock_, 0); + dent = HT_FIND(event_debug_map, &global_debug_map, &find); + if (dent) { + dent->added = 1; + } else { + event_errx(EVENT_ERR_ABORT_, + "%s: noting an add on a non-setup event %p" + " (events: 0x%x, fd: "EV_SOCK_FMT + ", flags: 0x%x)", + __func__, ev, ev->ev_events, + EV_SOCK_ARG(ev->ev_fd), ev->ev_flags); + } + EVLOCK_UNLOCK(event_debug_map_lock_, 0); + +out: + event_debug_mode_too_late = 1; +} +/* record that ev is no longer added */ +static void event_debug_note_del_(const struct event *ev) +{ + struct event_debug_entry *dent, find; + + if (!event_debug_mode_on_) { + goto out; + } + + find.ptr = ev; + EVLOCK_LOCK(event_debug_map_lock_, 0); + dent = HT_FIND(event_debug_map, &global_debug_map, &find); + if (dent) { + dent->added = 0; + } else { + event_errx(EVENT_ERR_ABORT_, + "%s: noting a del on a non-setup event %p" + " (events: 0x%x, fd: "EV_SOCK_FMT + ", flags: 0x%x)", + __func__, ev, ev->ev_events, + EV_SOCK_ARG(ev->ev_fd), ev->ev_flags); + } + EVLOCK_UNLOCK(event_debug_map_lock_, 0); + +out: + event_debug_mode_too_late = 1; +} +/* assert that ev is setup (i.e., okay to add or inspect) */ +static void event_debug_assert_is_setup_(const struct event *ev) +{ + struct event_debug_entry *dent, find; + + if (!event_debug_mode_on_) { + return; + } + + find.ptr = ev; + EVLOCK_LOCK(event_debug_map_lock_, 0); + dent = HT_FIND(event_debug_map, &global_debug_map, &find); + if (!dent) { + event_errx(EVENT_ERR_ABORT_, + "%s called on a non-initialized event %p" + " (events: 0x%x, fd: "EV_SOCK_FMT + ", flags: 0x%x)", + __func__, ev, ev->ev_events, + EV_SOCK_ARG(ev->ev_fd), ev->ev_flags); + } + EVLOCK_UNLOCK(event_debug_map_lock_, 0); +} +/* assert that ev is not added (i.e., okay to tear down or set up again) */ +static void event_debug_assert_not_added_(const struct event *ev) +{ + struct event_debug_entry *dent, find; + + if (!event_debug_mode_on_) { + return; + } + + find.ptr = ev; + EVLOCK_LOCK(event_debug_map_lock_, 0); + dent = HT_FIND(event_debug_map, &global_debug_map, &find); + if (dent && dent->added) { + event_errx(EVENT_ERR_ABORT_, + "%s called on an already added event %p" + " (events: 0x%x, fd: "EV_SOCK_FMT", " + "flags: 0x%x)", + __func__, ev, ev->ev_events, + EV_SOCK_ARG(ev->ev_fd), ev->ev_flags); + } + EVLOCK_UNLOCK(event_debug_map_lock_, 0); +} #else -#define event_debug_note_setup_(ev) \ - ((void)0) -#define event_debug_note_teardown_(ev) \ - ((void)0) -#define event_debug_note_add_(ev) \ - ((void)0) -#define event_debug_note_del_(ev) \ - ((void)0) -#define event_debug_assert_is_setup_(ev) \ - ((void)0) -#define event_debug_assert_not_added_(ev) \ - ((void)0) +static void event_debug_note_setup_(const struct event *ev) { (void)ev; } +static void event_debug_note_teardown_(const struct event *ev) { (void)ev; } +static void event_debug_note_add_(const struct event *ev) { (void)ev; } +static void event_debug_note_del_(const struct event *ev) { (void)ev; } +static void event_debug_assert_is_setup_(const struct event *ev) { (void)ev; } +static void event_debug_assert_not_added_(const struct event *ev) { (void)ev; } #endif #define EVENT_BASE_ASSERT_LOCKED(base) \ -- cgit v1.2.1 From 4f0f40e31e58677f3e05af64f1412d7a1a8d03d1 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 27 Feb 2018 21:12:14 +0300 Subject: Fix base unlocking in event_del() if event_base_set() runned in another thread Image next situation: T1: T2: event_del_() lock the event.ev_base.th_base_lock event_del_nolock_() event_set_base() unlock the event.ev_base.th_base_lock In this case we will unlock the wrong base after event_del_nolock_() returns, and deadlock is likely to happens, since event_base_set() do not check any mutexes (due to it is possible to do this only if event is not inserted anywhere). So event_del_() has to cache the base before removing the event, and cached base.th_base_lock after. (cherry picked from commit 08a0d366073eacf800027725891c2f668f2f0144) --- event.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/event.c b/event.c index 17570c27..c5560707 100644 --- a/event.c +++ b/event.c @@ -2749,17 +2749,16 @@ static int event_del_(struct event *ev, int blocking) { int res; + struct event_base *base = ev->ev_base; - if (EVUTIL_FAILURE_CHECK(!ev->ev_base)) { + if (EVUTIL_FAILURE_CHECK(!base)) { event_warnx("%s: event has no event_base set.", __func__); return -1; } - EVBASE_ACQUIRE_LOCK(ev->ev_base, th_base_lock); - + EVBASE_ACQUIRE_LOCK(base, th_base_lock); res = event_del_nolock_(ev, blocking); - - EVBASE_RELEASE_LOCK(ev->ev_base, th_base_lock); + EVBASE_RELEASE_LOCK(base, th_base_lock); return (res); } -- cgit v1.2.1 From ebfac5179796a4f090e29ecb15c0008113dc55f3 Mon Sep 17 00:00:00 2001 From: Greg Hazel Date: Tue, 20 Mar 2018 15:12:07 -0700 Subject: Call underlying bev ctrl GET_FD on filtered bufferevents Fixes: #611 Fixes: #610 (cherry picked from commit 4055081499cba32642dd72427a8f9d3ad7e50e79) --- bufferevent_filter.c | 3 +-- test/regress_bufferevent.c | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/bufferevent_filter.c b/bufferevent_filter.c index d9e8540f..858d4684 100644 --- a/bufferevent_filter.c +++ b/bufferevent_filter.c @@ -605,6 +605,7 @@ be_filter_ctrl(struct bufferevent *bev, enum bufferevent_ctrl_op op, data->ptr = bevf->underlying; return 0; case BEV_CTRL_SET_FD: + case BEV_CTRL_GET_FD: bevf = upcast(bev); if (bevf->underlying && @@ -614,8 +615,6 @@ be_filter_ctrl(struct bufferevent *bev, enum bufferevent_ctrl_op op, } EVUTIL_FALLTHROUGH; - case BEV_CTRL_GET_FD: - EVUTIL_FALLTHROUGH; case BEV_CTRL_CANCEL_ALL: EVUTIL_FALLTHROUGH; default: diff --git a/test/regress_bufferevent.c b/test/regress_bufferevent.c index 249985e9..6d69655f 100644 --- a/test/regress_bufferevent.c +++ b/test/regress_bufferevent.c @@ -569,8 +569,8 @@ test_bufferevent_filters_impl(int use_pair, int disable) tt_ptr_op(bufferevent_get_underlying(bev1), ==, bev1_base); tt_ptr_op(bufferevent_get_underlying(bev2), ==, bev2_base); - tt_int_op(bufferevent_getfd(bev1), ==, -1); - tt_int_op(bufferevent_getfd(bev2), ==, -1); + tt_int_op(bufferevent_getfd(bev1), ==, bufferevent_getfd(bev1_base)); + tt_int_op(bufferevent_getfd(bev2), ==, bufferevent_getfd(bev2_base)); bufferevent_disable(bev1, EV_READ); bufferevent_enable(bev2, EV_READ); -- cgit v1.2.1 From b92b07924df198312fc7e0f53f96d4057723967f Mon Sep 17 00:00:00 2001 From: Greg Hazel Date: Tue, 20 Mar 2018 18:04:53 -0700 Subject: don't fail be_null_filter if bytes are copied Otherwise it will not reset timeouts for the IO, but other things should still works correctly. Also evbuffer_remove_buffer() could return 0, due to empty buffers, for example during flushing bufferevent, so let's count this is BEV_OK too. (cherry picked from commit 4ba48739673060baea581774992970fa46c2f813) --- bufferevent_filter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bufferevent_filter.c b/bufferevent_filter.c index 858d4684..a7bdeddd 100644 --- a/bufferevent_filter.c +++ b/bufferevent_filter.c @@ -160,7 +160,7 @@ be_null_filter(struct evbuffer *src, struct evbuffer *dst, ev_ssize_t lim, enum bufferevent_flush_mode state, void *ctx) { (void)state; - if (evbuffer_remove_buffer(src, dst, lim) == 0) + if (evbuffer_remove_buffer(src, dst, lim) >= 0) return BEV_OK; else return BEV_ERROR; -- cgit v1.2.1 From 8818c86caf1deb15d5075de1f7b951d4c60be602 Mon Sep 17 00:00:00 2001 From: Philip Prindeville Date: Wed, 28 Mar 2018 08:25:28 -0600 Subject: Avoid possible SEGVs in select() (in unit tests) Per the POSIX definition of select(): http://pubs.opengroup.org/onlinepubs/009696699/functions/pselect.html "Upon successful completion, the select() function may modify the object pointed to by the timout argument." If "struct timeval" pointer is a "static const", it could potentially be allocated in a RO text segment. The kernel would then try to copy back the modified value (with the time remaining) into a read-only address and SEGV. Signed-off-by: Philip Prindeville Closes: #614 (cherry picked from commit 33baa4e59fbf9432d77a19c6b2b45402580b79a5) --- evutil_time.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/evutil_time.c b/evutil_time.c index 00fd5fb4..d658b30e 100644 --- a/evutil_time.c +++ b/evutil_time.c @@ -141,7 +141,10 @@ evutil_usleep_(const struct timeval *tv) sleep(tv->tv_sec); usleep(tv->tv_usec); #else - select(0, NULL, NULL, NULL, tv); + { + struct timeval tv2 = *tv; + select(0, NULL, NULL, NULL, &tv2); + } #endif } -- cgit v1.2.1 From 894ca48a1159d595289fe5775e64558bf1d20499 Mon Sep 17 00:00:00 2001 From: Bernard Spil Date: Mon, 2 Apr 2018 13:18:27 +0200 Subject: Fix build with LibreSSL 2.7 LibreSSL 2.7 implements OpenSSL 1.1 API except for BIO_get_init() See also: https://bugs.freebsd.org/226900 Signed-off-by: Bernard Spil Closes: #617 (cherry-pick) (cherry picked from commit 28b8075400c70b2d2da2ce07e590c2ec6d11783d) --- openssl-compat.h | 10 ++++++++-- sample/https-client.c | 9 ++++++--- sample/le-proxy.c | 3 ++- sample/openssl_hostname_validation.c | 3 ++- test/regress_ssl.c | 3 ++- 5 files changed, 20 insertions(+), 8 deletions(-) diff --git a/openssl-compat.h b/openssl-compat.h index bffd2593..5d91ac64 100644 --- a/openssl-compat.h +++ b/openssl-compat.h @@ -4,7 +4,8 @@ #include #include "util-internal.h" -#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \ + (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L) static inline BIO_METHOD *BIO_meth_new(int type, const char *name) { @@ -33,6 +34,11 @@ static inline BIO_METHOD *BIO_meth_new(int type, const char *name) #define TLS_method SSLv23_method -#endif /* (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) */ +#endif /* (OPENSSL_VERSION_NUMBER < 0x10100000L) || \ + (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L) */ + +#if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x20700000L +#define BIO_get_init(b) (b)->init +#endif #endif /* OPENSSL_COMPAT_H */ diff --git a/sample/https-client.c b/sample/https-client.c index 8ef75987..4292f094 100644 --- a/sample/https-client.c +++ b/sample/https-client.c @@ -312,7 +312,8 @@ main(int argc, char **argv) } uri[sizeof(uri) - 1] = '\0'; -#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \ + (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L) // Initialize OpenSSL SSL_library_init(); ERR_load_crypto_strings(); @@ -488,7 +489,8 @@ cleanup: SSL_CTX_free(ssl_ctx); if (type == HTTP && ssl) SSL_free(ssl); -#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \ + (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L) EVP_cleanup(); ERR_free_strings(); @@ -501,7 +503,8 @@ cleanup: CRYPTO_cleanup_all_ex_data(); sk_SSL_COMP_free(SSL_COMP_get_compression_methods()); -#endif /* (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) */ +#endif /* (OPENSSL_VERSION_NUMBER < 0x10100000L) || \ + (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L) */ #ifdef _WIN32 WSACleanup(); diff --git a/sample/le-proxy.c b/sample/le-proxy.c index 4e1cf033..73c48881 100644 --- a/sample/le-proxy.c +++ b/sample/le-proxy.c @@ -261,7 +261,8 @@ main(int argc, char **argv) if (use_ssl) { int r; -#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \ + (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L) SSL_library_init(); ERR_load_crypto_strings(); SSL_load_error_strings(); diff --git a/sample/openssl_hostname_validation.c b/sample/openssl_hostname_validation.c index a60e38c4..4036ccba 100644 --- a/sample/openssl_hostname_validation.c +++ b/sample/openssl_hostname_validation.c @@ -48,7 +48,8 @@ SOFTWARE. #define HOSTNAME_MAX_SIZE 255 -#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \ + (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L) #define ASN1_STRING_get0_data ASN1_STRING_data #endif diff --git a/test/regress_ssl.c b/test/regress_ssl.c index 5004f7e8..92026976 100644 --- a/test/regress_ssl.c +++ b/test/regress_ssl.c @@ -185,7 +185,8 @@ get_ssl_ctx(void) void init_ssl(void) { -#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \ + (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L) SSL_library_init(); ERR_load_crypto_strings(); SSL_load_error_strings(); -- cgit v1.2.1 From 80b70ee0298941becd8d86c9c50a52f716f5fbef Mon Sep 17 00:00:00 2001 From: dpayne Date: Tue, 3 Apr 2018 15:17:51 -0700 Subject: Fixing doxygen docs for evdns_base_search_clear when generated on non-windows machines (cherry picked from commit 2c1562949c49febe9a4d5ec33cabe99f1f6a82e1) --- include/event2/dns.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/event2/dns.h b/include/event2/dns.h index 2025b9e6..80da2dee 100644 --- a/include/event2/dns.h +++ b/include/event2/dns.h @@ -478,6 +478,7 @@ int evdns_base_resolv_conf_parse(struct evdns_base *base, int flags, const char EVENT2_EXPORT_SYMBOL int evdns_base_load_hosts(struct evdns_base *base, const char *hosts_fname); +#ifdef _WIN32 /** Obtain nameserver information using the Windows API. @@ -488,7 +489,6 @@ int evdns_base_load_hosts(struct evdns_base *base, const char *hosts_fname); @return 0 if successful, or -1 if an error occurred @see evdns_resolv_conf_parse() */ -#ifdef _WIN32 EVENT2_EXPORT_SYMBOL int evdns_base_config_windows_nameservers(struct evdns_base *); #define EVDNS_BASE_CONFIG_WINDOWS_NAMESERVERS_IMPLEMENTED -- cgit v1.2.1 From 3bd2ce439d2deaba8885fe68fef24431ffb81a64 Mon Sep 17 00:00:00 2001 From: dpayne Date: Tue, 3 Apr 2018 15:43:22 -0700 Subject: Generating evdns_base_config_windows_nameservers docs on all platforms (cherry picked from commit 791e3de0c38f9f413f33addcac2d8bca68590ca6) --- include/event2/dns.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/event2/dns.h b/include/event2/dns.h index 80da2dee..902544c2 100644 --- a/include/event2/dns.h +++ b/include/event2/dns.h @@ -478,7 +478,7 @@ int evdns_base_resolv_conf_parse(struct evdns_base *base, int flags, const char EVENT2_EXPORT_SYMBOL int evdns_base_load_hosts(struct evdns_base *base, const char *hosts_fname); -#ifdef _WIN32 +#if defined(EVENT_IN_DOXYGEN_) || defined(_WIN32) /** Obtain nameserver information using the Windows API. -- cgit v1.2.1 From 29590718cfc8d09217d056d7674d6c9c4d2d337e Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Thu, 5 Apr 2018 15:17:06 +0100 Subject: cmake: ensure windows dll's are installed as well as lib files Closes: #621 (cherry picked from commit 0fa43c99fbba6f3b1827ada98302f548206a358f) --- cmake/AddEventLibrary.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/AddEventLibrary.cmake b/cmake/AddEventLibrary.cmake index 8475e086..3f4e800e 100644 --- a/cmake/AddEventLibrary.cmake +++ b/cmake/AddEventLibrary.cmake @@ -98,6 +98,7 @@ macro(add_event_library LIB_NAME) EXPORT LibeventTargets LIBRARY DESTINATION "lib" COMPONENT lib ARCHIVE DESTINATION "lib" COMPONENT lib + RUNTIME DESTINATION "lib" COMPONENT lib PUBLIC_HEADER DESTINATION "include/event2" COMPONENT dev ) -- cgit v1.2.1 From 8886eed498c1994c7f3ba7c0567d0e7a2c8a7ba3 Mon Sep 17 00:00:00 2001 From: The Gitter Badger Date: Sun, 15 Apr 2018 23:02:05 +0000 Subject: Add Gitter badge (cherry picked from commit ba78ba9e8ba4c964dd5d14a281d7421c95d37937) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 7e40bb22..3342cf1a 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ [![Appveyor Win32 Build Status](https://ci.appveyor.com/api/projects/status/github/libevent/libevent?branch=master&svg=true)](https://ci.appveyor.com/project/nmathewson/libevent) [![Travis Build Status](https://travis-ci.org/libevent/libevent.svg?branch=master)](https://travis-ci.org/libevent/libevent) [![Coverage Status](https://coveralls.io/repos/github/libevent/libevent/badge.svg)](https://coveralls.io/github/libevent/libevent) +[![Join the chat at https://gitter.im/libevent/libevent](https://badges.gitter.im/libevent/libevent.svg)](https://gitter.im/libevent/libevent?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -- cgit v1.2.1 From d6326104681ae2be87f4df0a7d080f3a5f9d1f7d Mon Sep 17 00:00:00 2001 From: SuckShit Date: Fri, 20 Apr 2018 15:48:32 +0800 Subject: Fix assert() condition in evbuffer_drain() for IOCP In the case of iocp, in the for loop above, there is a situation where: remaining == chain->off == 0 And this happens due to CHAIN_PINNED_R() case (that is used only in buffer_iocp.c) Closes: #630 (picked) (cherry picked from commit ab3224c3e66cf92779f8bd91ffe90445e636fa50) --- buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buffer.c b/buffer.c index 8113ce6c..80cb54ad 100644 --- a/buffer.c +++ b/buffer.c @@ -1146,7 +1146,7 @@ evbuffer_drain(struct evbuffer *buf, size_t len) } buf->first = chain; - EVUTIL_ASSERT(remaining < chain->off); + EVUTIL_ASSERT(remaining <= chain->off); chain->misalign += remaining; chain->off -= remaining; } -- cgit v1.2.1 From 3ffa3ca7f72a04f001edd5c0db2b5805a6e53934 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 23 Apr 2018 00:26:08 +0300 Subject: Adopt ignore rules for cmake + ninja In case we have build directory differs from source directory there will be bunch of files we should ignore, so just remove leading "/" for some or rules. And fix others. (cherry picked from commit e2874d95af584b3657eb5dc1d2e5404811dce117) --- .gitignore | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/.gitignore b/.gitignore index 99610045..e85f9f38 100644 --- a/.gitignore +++ b/.gitignore @@ -84,9 +84,6 @@ cscope* /stamp-h1 /stamp-h2 -/include/event2/event-config.h -/evconfig-private.h - /sample/dns-example /sample/event-read-fifo /sample/hello-world @@ -118,29 +115,36 @@ cscope* /test/test-changelist /test/test-fdleak +**/include/event2/event-config.h +**/include/evconfig-private.h # Files generated by cmake -/CMakeCache.txt -/CMakeFiles/ -/CTestTestfile.cmake -/DartConfiguration.tcl -/LibeventConfig.cmake -/LibeventConfigVersion.cmake -/LibeventTargets.cmake -/bin/ -/cmake_install.cmake -/include/evconfig-private.h -/lib/ -/tmp/ -/verify_tests.sh -/verify_tests.bat -/event.dir -/event_core.dir -/event_extra.dir +CMakeCache.txt +CMakeFiles/ +CTestTestfile.cmake +DartConfiguration.tcl +LibeventConfig.cmake +LibeventConfigVersion.cmake +LibeventTargets.cmake +bin/ +cmake_install.cmake +lib/ +tmp/ +verify_tests.sh +verify_tests.bat +event.dir +event_core.dir +event_extra.dir *.vcxproj *.sln *.filters +# ninja +build.ninja +rules.ninja +.ninja_deps +.ninja_log + # make dist /COPYING /INSTALL -- cgit v1.2.1 From 7e56c8b2da4f8457e6d82b329deae889a3fce868 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 23 Apr 2018 00:52:57 +0300 Subject: Merge branch 'pull-628' * pull-628: Give priority to the build directory headers Do not ship evconfig-private.h in dist archive Closes: #628 (cherry picked from commit a5f19422fdc91cf1e645fc318a174f33f132b9ac) --- Makefile.am | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index 9ec7ca2e..9e0f6995 100644 --- a/Makefile.am +++ b/Makefile.am @@ -229,7 +229,7 @@ MAYBE_CORE = endif AM_CFLAGS = $(LIBEVENT_CFLAGS) -AM_CPPFLAGS = -I$(srcdir)/compat -I$(srcdir)/include -I./include $(SYS_INCLUDES) $(LIBEVENT_CPPFLAGS) +AM_CPPFLAGS = -I$(srcdir)/compat -I./include -I$(srcdir)/include $(SYS_INCLUDES) $(LIBEVENT_CPPFLAGS) AM_LDFLAGS = $(LIBEVENT_LDFLAGS) GENERIC_LDFLAGS = -version-info $(VERSION_INFO) $(RELEASE) $(NO_UNDEFINED) $(AM_LDFLAGS) @@ -269,7 +269,6 @@ noinst_HEADERS += \ defer-internal.h \ epolltable-internal.h \ evbuffer-internal.h \ - evconfig-private.h \ event-internal.h \ evmap-internal.h \ evrpc-internal.h \ -- cgit v1.2.1 From 442c7d947f291b2dc6b3b6cf63560042c5fb7dd8 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 24 Apr 2018 01:34:06 +0300 Subject: test/dns: cleanup test_bufferevent_connect_hostname() (cherry picked from commit 623ef3ccdc0aafac7ae77a723cbad6d552ff9a01) --- test/regress_dns.c | 79 +++++++++++++++++++++--------------------------------- 1 file changed, 31 insertions(+), 48 deletions(-) diff --git a/test/regress_dns.c b/test/regress_dns.c index 51dc0093..583f002f 100644 --- a/test/regress_dns.c +++ b/test/regress_dns.c @@ -1185,10 +1185,9 @@ test_bufferevent_connect_hostname(void *arg) { struct basic_test_data *data = arg; struct evconnlistener *listener = NULL; - struct bufferevent *be1=NULL, *be2=NULL, *be3=NULL, *be4=NULL, *be5=NULL; - struct be_conn_hostname_result be1_outcome={0,0}, be2_outcome={0,0}, - be3_outcome={0,0}, be4_outcome={0,0}, be5_outcome={0,0}; - int expect_err5; + struct bufferevent *be[5]; + struct be_conn_hostname_result be_outcome[ARRAY_SIZE(be)]; + int expect_err; struct evdns_base *dns=NULL; struct evdns_server_port *port=NULL; struct sockaddr_in sin; @@ -1196,7 +1195,7 @@ test_bufferevent_connect_hostname(void *arg) ev_uint16_t dns_port=0; int n_accept=0, n_dns=0; char buf[128]; - + be_connect_hostname_base = data->base; /* Bind an address and figure out what port it's on. */ @@ -1225,29 +1224,19 @@ test_bufferevent_connect_hostname(void *arg) /* Now, finally, at long last, launch the bufferevents. One should do * a failing lookup IP, one should do a successful lookup by IP, * and one should do a successful lookup by hostname. */ - be1 = bufferevent_socket_new(data->base, -1, BEV_OPT_CLOSE_ON_FREE); - be2 = bufferevent_socket_new(data->base, -1, BEV_OPT_CLOSE_ON_FREE); - be3 = bufferevent_socket_new(data->base, -1, BEV_OPT_CLOSE_ON_FREE); - be4 = bufferevent_socket_new(data->base, -1, BEV_OPT_CLOSE_ON_FREE); - be5 = bufferevent_socket_new(data->base, -1, BEV_OPT_CLOSE_ON_FREE); - - bufferevent_setcb(be1, NULL, NULL, be_connect_hostname_event_cb, - &be1_outcome); - bufferevent_setcb(be2, NULL, NULL, be_connect_hostname_event_cb, - &be2_outcome); - bufferevent_setcb(be3, NULL, NULL, be_connect_hostname_event_cb, - &be3_outcome); - bufferevent_setcb(be4, NULL, NULL, be_connect_hostname_event_cb, - &be4_outcome); - bufferevent_setcb(be5, NULL, NULL, be_connect_hostname_event_cb, - &be5_outcome); + for (int i = 0; i < ARRAY_SIZE(be); ++i) { + memset(&be_outcome[i], 0, sizeof(be_outcome[i])); + be[i] = bufferevent_socket_new(data->base, -1, BEV_OPT_CLOSE_ON_FREE); + bufferevent_setcb(be[i], NULL, NULL, be_connect_hostname_event_cb, + &be_outcome[i]); + } /* Use the blocking resolver. This one will fail if your resolver * can't resolve localhost to 127.0.0.1 */ - tt_assert(!bufferevent_socket_connect_hostname(be4, NULL, AF_INET, + tt_assert(!bufferevent_socket_connect_hostname(be[3], NULL, AF_INET, "localhost", listener_port)); /* Use the blocking resolver with a nonexistent hostname. */ - tt_assert(!bufferevent_socket_connect_hostname(be5, NULL, AF_INET, + tt_assert(!bufferevent_socket_connect_hostname(be[4], NULL, AF_INET, "nonesuch.nowhere.example.com", 80)); { /* The blocking resolver will use the system nameserver, which @@ -1258,32 +1247,32 @@ test_bufferevent_connect_hostname(void *arg) hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; - expect_err5 = evutil_getaddrinfo( + expect_err = evutil_getaddrinfo( "nonesuch.nowhere.example.com", "80", &hints, &ai); } /* Launch an async resolve that will fail. */ - tt_assert(!bufferevent_socket_connect_hostname(be1, dns, AF_INET, + tt_assert(!bufferevent_socket_connect_hostname(be[0], dns, AF_INET, "nosuchplace.example.com", listener_port)); /* Connect to the IP without resolving. */ - tt_assert(!bufferevent_socket_connect_hostname(be2, dns, AF_INET, + tt_assert(!bufferevent_socket_connect_hostname(be[1], dns, AF_INET, "127.0.0.1", listener_port)); /* Launch an async resolve that will succeed. */ - tt_assert(!bufferevent_socket_connect_hostname(be3, dns, AF_INET, + tt_assert(!bufferevent_socket_connect_hostname(be[2], dns, AF_INET, "nobodaddy.example.com", listener_port)); event_base_dispatch(data->base); - tt_int_op(be1_outcome.what, ==, BEV_EVENT_ERROR); - tt_int_op(be1_outcome.dnserr, ==, EVUTIL_EAI_NONAME); - tt_int_op(be2_outcome.what, ==, BEV_EVENT_CONNECTED); - tt_int_op(be2_outcome.dnserr, ==, 0); - tt_int_op(be3_outcome.what, ==, BEV_EVENT_CONNECTED); - tt_int_op(be3_outcome.dnserr, ==, 0); - tt_int_op(be4_outcome.what, ==, BEV_EVENT_CONNECTED); - tt_int_op(be4_outcome.dnserr, ==, 0); - if (expect_err5) { - tt_int_op(be5_outcome.what, ==, BEV_EVENT_ERROR); - tt_int_op(be5_outcome.dnserr, ==, expect_err5); + tt_int_op(be_outcome[0].what, ==, BEV_EVENT_ERROR); + tt_int_op(be_outcome[0].dnserr, ==, EVUTIL_EAI_NONAME); + tt_int_op(be_outcome[1].what, ==, BEV_EVENT_CONNECTED); + tt_int_op(be_outcome[1].dnserr, ==, 0); + tt_int_op(be_outcome[2].what, ==, BEV_EVENT_CONNECTED); + tt_int_op(be_outcome[2].dnserr, ==, 0); + tt_int_op(be_outcome[3].what, ==, BEV_EVENT_CONNECTED); + tt_int_op(be_outcome[3].dnserr, ==, 0); + if (expect_err) { + tt_int_op(be_outcome[4].what, ==, BEV_EVENT_ERROR); + tt_int_op(be_outcome[4].dnserr, ==, expect_err); } tt_int_op(n_accept, ==, 3); @@ -1296,16 +1285,10 @@ end: evdns_close_server_port(port); if (dns) evdns_base_free(dns, 0); - if (be1) - bufferevent_free(be1); - if (be2) - bufferevent_free(be2); - if (be3) - bufferevent_free(be3); - if (be4) - bufferevent_free(be4); - if (be5) - bufferevent_free(be5); + for (int i = 0; i < ARRAY_SIZE(be); ++i) { + if (be[i]) + bufferevent_free(be[i]); + } } -- cgit v1.2.1 From 1dde74efa8ef1912184562e15e8863b908593591 Mon Sep 17 00:00:00 2001 From: Jesse Fang Date: Fri, 23 Feb 2018 19:15:12 +0800 Subject: bufferevent_socket_connect{,_hostname}() missing event callback and use ret code - When socket() failed in bufferevent_socket_connect() , the event callback should be called also in bufferevent_socket_connect_hostname(). eg. when use bufferevent_socket_connect_hostname() to resolve and connect an IP address but process have a smaller ulimit open files, socket() fails always but caller is not notified. - Make bufferevent_socket_connect()'s behavior more consistent: function return error then no callback, function return ok then error passed by event callback. Fixes: #597 Closes: #599 Closes: #600 (cherry picked from commit f7bc1337977553f5f966f13840a5f7feba2d0bd5) --- bufferevent_sock.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/bufferevent_sock.c b/bufferevent_sock.c index 38f791ee..8c78c045 100644 --- a/bufferevent_sock.c +++ b/bufferevent_sock.c @@ -396,7 +396,7 @@ bufferevent_socket_connect(struct bufferevent *bev, fd = evutil_socket_(sa->sa_family, SOCK_STREAM|EVUTIL_SOCK_NONBLOCK, 0); if (fd < 0) - goto done; + goto freesock; ownfd = 1; } if (sa) { @@ -446,10 +446,8 @@ bufferevent_socket_connect(struct bufferevent *bev, goto done; freesock: - bufferevent_run_eventcb_(bev, BEV_EVENT_ERROR, 0); if (ownfd) evutil_closesocket(fd); - /* do something about the error? */ done: bufferevent_decref_and_unlock_(bev); return result; @@ -485,10 +483,10 @@ bufferevent_connect_getaddrinfo_cb(int result, struct evutil_addrinfo *ai, } /* XXX use the other addrinfos? */ - /* XXX use this return value */ bufferevent_socket_set_conn_address(bev_p, ai->ai_addr, (int)ai->ai_addrlen); r = bufferevent_socket_connect(bev, ai->ai_addr, (int)ai->ai_addrlen); - (void)r; + if (r < 0) + bufferevent_run_eventcb_(bev, BEV_EVENT_ERROR, 0); bufferevent_decref_and_unlock_(bev); evutil_freeaddrinfo(ai); } -- cgit v1.2.1 From f3eb294f799d6098c343d7cd775c817818f29049 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 24 Apr 2018 01:45:00 +0300 Subject: test/dns: verify bufferevent_socket_connect() errorcb invoking if socket() fails Refs: #600 (cherry picked from commit a3d8f2e09302536c6c0ffc3ccb1fc6f43b51dc4f) --- test/regress_dns.c | 52 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/test/regress_dns.c b/test/regress_dns.c index 583f002f..b2ea8651 100644 --- a/test/regress_dns.c +++ b/test/regress_dns.c @@ -59,6 +59,10 @@ #include #include +#ifdef EVENT__HAVE_SYS_RESOURCE_H +#include +#endif + #include "event2/dns.h" #include "event2/dns_compat.h" #include "event2/dns_struct.h" @@ -1162,15 +1166,22 @@ be_connect_hostname_event_cb(struct bufferevent *bev, short what, void *ctx) got->what = what; if ((what & BEV_EVENT_CONNECTED) || (what & BEV_EVENT_ERROR)) { - int r; - if ((r = bufferevent_socket_get_dns_error(bev))) { + int expected = 3; + int r = bufferevent_socket_get_dns_error(bev); + + if (r) { got->dnserr = r; TT_BLATHER(("DNS error %d: %s", r, evutil_gai_strerror(r))); } ++total_connected_or_failed; TT_BLATHER(("Got %d connections or errors.", total_connected_or_failed)); - if (total_n_accepted >= 3 && total_connected_or_failed >= 5) + /** emfile test */ + if (errno == EMFILE) { + expected = 0; + } + + if (total_n_accepted >= expected && total_connected_or_failed >= 5) event_base_loopexit(be_connect_hostname_base, NULL); } @@ -1195,7 +1206,15 @@ test_bufferevent_connect_hostname(void *arg) ev_uint16_t dns_port=0; int n_accept=0, n_dns=0; char buf[128]; - + int emfile = data->setup_data && !strcmp(data->setup_data, "emfile"); + int success = BEV_EVENT_CONNECTED; + int default_error = 0; + + if (emfile) { + success = BEV_EVENT_ERROR; + default_error = EVUTIL_EAI_SYSTEM; + } + be_connect_hostname_base = data->base; /* Bind an address and figure out what port it's on. */ @@ -1221,6 +1240,13 @@ test_bufferevent_connect_hostname(void *arg) evutil_snprintf(buf, sizeof(buf), "127.0.0.1:%d", (int)dns_port); evdns_base_nameserver_ip_add(dns, buf); +#ifdef EVENT__HAVE_SETRLIMIT + if (emfile) { + struct rlimit file = { 1, 1 }; + setrlimit(RLIMIT_NOFILE, &file); + } +#endif + /* Now, finally, at long last, launch the bufferevents. One should do * a failing lookup IP, one should do a successful lookup by IP, * and one should do a successful lookup by hostname. */ @@ -1264,18 +1290,22 @@ test_bufferevent_connect_hostname(void *arg) tt_int_op(be_outcome[0].what, ==, BEV_EVENT_ERROR); tt_int_op(be_outcome[0].dnserr, ==, EVUTIL_EAI_NONAME); - tt_int_op(be_outcome[1].what, ==, BEV_EVENT_CONNECTED); + tt_int_op(be_outcome[1].what, ==, success); tt_int_op(be_outcome[1].dnserr, ==, 0); - tt_int_op(be_outcome[2].what, ==, BEV_EVENT_CONNECTED); + tt_int_op(be_outcome[2].what, ==, success); tt_int_op(be_outcome[2].dnserr, ==, 0); - tt_int_op(be_outcome[3].what, ==, BEV_EVENT_CONNECTED); - tt_int_op(be_outcome[3].dnserr, ==, 0); + tt_int_op(be_outcome[3].what, ==, success); + tt_int_op(be_outcome[3].dnserr, ==, default_error); if (expect_err) { tt_int_op(be_outcome[4].what, ==, BEV_EVENT_ERROR); tt_int_op(be_outcome[4].dnserr, ==, expect_err); } - tt_int_op(n_accept, ==, 3); + if (emfile) { + tt_int_op(n_accept, ==, 0); + } else { + tt_int_op(n_accept, ==, 3); + } tt_int_op(n_dns, ==, 2); end: @@ -2113,6 +2143,10 @@ struct testcase_t dns_testcases[] = { { "inflight", dns_inflight_test, TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, { "bufferevent_connect_hostname", test_bufferevent_connect_hostname, TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, +#ifdef EVENT__HAVE_SETRLIMIT + { "bufferevent_connect_hostname_emfile", test_bufferevent_connect_hostname, + TT_FORK|TT_NEED_BASE, &basic_setup, (char*)"emfile" }, +#endif { "disable_when_inactive", dns_disable_when_inactive_test, TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, { "disable_when_inactive_no_ns", dns_disable_when_inactive_no_ns_test, -- cgit v1.2.1 From 4215c003f11768c4be544939740e81a90f4e3039 Mon Sep 17 00:00:00 2001 From: Greg Hazel Date: Sun, 11 Feb 2018 16:28:58 -0800 Subject: Fix evhttp_connection_get_addr() fox incomming http connections Install conn_address of the bufferevent on incomping http connections (even though this is kind of subsytem violation, so let's fix it in a simplest way and thinkg about long-term solution). Fixes: #510 Closes: #595 (pick) (cherry picked from commit 367cd9e5c2b8e3f9b8dbed40bfe8a0ed79285c36) --- bufferevent-internal.h | 9 +++++++++ bufferevent_sock.c | 19 +++++++++++++------ http.c | 1 + 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/bufferevent-internal.h b/bufferevent-internal.h index f79e74d3..c3f6b60b 100644 --- a/bufferevent-internal.h +++ b/bufferevent-internal.h @@ -444,6 +444,15 @@ EVENT2_EXPORT_SYMBOL const struct sockaddr* bufferevent_socket_get_conn_address_(struct bufferevent *bev); +EVENT2_EXPORT_SYMBOL +void +bufferevent_socket_set_conn_address_fd_(struct bufferevent *bev, int fd); + +EVENT2_EXPORT_SYMBOL +void +bufferevent_socket_set_conn_address_(struct bufferevent *bev, struct sockaddr *addr, size_t addrlen); + + /** Internal use: We have just successfully read data into an inbuf, so * reset the read timeout (if any). */ #define BEV_RESET_GENERIC_READ_TIMEOUT(bev) \ diff --git a/bufferevent_sock.c b/bufferevent_sock.c index 8c78c045..c878aa95 100644 --- a/bufferevent_sock.c +++ b/bufferevent_sock.c @@ -104,19 +104,26 @@ bufferevent_socket_get_conn_address_(struct bufferevent *bev) return (struct sockaddr *)&bev_p->conn_address; } -static void -bufferevent_socket_set_conn_address_fd(struct bufferevent_private *bev_p, int fd) + +void +bufferevent_socket_set_conn_address_fd_(struct bufferevent *bev, int fd) { + struct bufferevent_private *bev_p = + EVUTIL_UPCAST(bev, struct bufferevent_private, bev); + socklen_t len = sizeof(bev_p->conn_address); struct sockaddr *addr = (struct sockaddr *)&bev_p->conn_address; if (addr->sa_family != AF_UNSPEC) getpeername(fd, addr, &len); } -static void -bufferevent_socket_set_conn_address(struct bufferevent_private *bev_p, + +void +bufferevent_socket_set_conn_address_(struct bufferevent *bev, struct sockaddr *addr, size_t addrlen) { + struct bufferevent_private *bev_p = + EVUTIL_UPCAST(bev, struct bufferevent_private, bev); EVUTIL_ASSERT(addrlen <= sizeof(bev_p->conn_address)); memcpy(&bev_p->conn_address, addr, addrlen); } @@ -264,7 +271,7 @@ bufferevent_writecb(evutil_socket_t fd, short event, void *arg) goto done; } else { connected = 1; - bufferevent_socket_set_conn_address_fd(bufev_p, fd); + bufferevent_socket_set_conn_address_fd_(bufev, fd); #ifdef _WIN32 if (BEV_IS_ASYNC(bufev)) { event_del(&bufev->ev_write); @@ -483,7 +490,7 @@ bufferevent_connect_getaddrinfo_cb(int result, struct evutil_addrinfo *ai, } /* XXX use the other addrinfos? */ - bufferevent_socket_set_conn_address(bev_p, ai->ai_addr, (int)ai->ai_addrlen); + bufferevent_socket_set_conn_address_(bev, ai->ai_addr, (int)ai->ai_addrlen); r = bufferevent_socket_connect(bev, ai->ai_addr, (int)ai->ai_addrlen); if (r < 0) bufferevent_run_eventcb_(bev, BEV_EVENT_ERROR, 0); diff --git a/http.c b/http.c index 8541fdc1..c79e710c 100644 --- a/http.c +++ b/http.c @@ -4213,6 +4213,7 @@ evhttp_get_request_connection( bufferevent_enable(evcon->bufev, EV_READ); bufferevent_disable(evcon->bufev, EV_WRITE); bufferevent_setfd(evcon->bufev, fd); + bufferevent_socket_set_conn_address_(evcon->bufev, sa, salen); return (evcon); } -- cgit v1.2.1 From 61b95600a06bf8c32a1a5996a067e865fd4fc413 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 24 Apr 2018 02:22:58 +0300 Subject: test/http: cover evhttp_connection_get_addr() for incomming connections Refs: #510 (cherry picked from commit e4edc7fc27bb96b4811f1c24d591f5c5bca69bdd) --- test/regress_http.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/regress_http.c b/test/regress_http.c index b761df0d..e3312091 100644 --- a/test/regress_http.c +++ b/test/regress_http.c @@ -314,12 +314,31 @@ http_basic_cb(struct evhttp_request *req, void *arg) struct evbuffer *evb = evbuffer_new(); struct evhttp_connection *evcon; int empty = evhttp_find_header(evhttp_request_get_input_headers(req), "Empty") != NULL; + event_debug(("%s: called\n", __func__)); evbuffer_add_printf(evb, BASIC_REQUEST_BODY); evcon = evhttp_request_get_connection(req); tt_assert(evhttp_connection_get_server(evcon) == arg); + { + const struct sockaddr *sa; + char addrbuf[128]; + + sa = evhttp_connection_get_addr(evcon); + tt_assert(sa); + + if (sa->sa_family == AF_INET) { + evutil_format_sockaddr_port_((struct sockaddr *)sa, addrbuf, sizeof(addrbuf)); + tt_assert(!strncmp(addrbuf, "127.0.0.1:", strlen("127.0.0.1:"))); + } else if (sa->sa_family == AF_INET6) { + evutil_format_sockaddr_port_((struct sockaddr *)sa, addrbuf, sizeof(addrbuf)); + tt_assert(!strncmp(addrbuf, "[::1]:", strlen("[::1]:"))); + } else { + tt_fail_msg("Unsupported family"); + } + } + /* For multi-line headers test */ { const char *multi = -- cgit v1.2.1 From dfb5fc167575e18ed4b3b273a52875091fd89f10 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 24 Apr 2018 02:56:08 +0300 Subject: travis-ci: allow tests under osx to fail (temporary, until we will fix them) (cherry picked from commit da028dec497722793ada3ce1a0358c1bf68161de) --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 0758b0ae..d0cab03c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,6 +22,8 @@ matrix: exclude: - os: osx env: EVENT_BUILD_METHOD=cmake EVENT_CMAKE_OPTIONS="-DEVENT__COVERAGE=ON -DCMAKE_BUILD_TYPE=debug" COVERALLS=yes + allow_failures: + - os: osx language: c compiler: -- cgit v1.2.1 From 0d194c4e49a483c2f6b81aaf4549c0ea484beb27 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 24 Apr 2018 14:46:06 +0300 Subject: test/dns: install correct RLIMIT_NOFILE in bufferevent_connect_hostname_emfile Otherwise poll() will fail with EINVAL: EINVAL The nfds value exceeds the RLIMIT_NOFILE value. P.S. and cleanup this test a little, with early-return. CI: https://travis-ci.org/libevent/libevent/jobs/370350426 (cherry picked from commit d1c8993c3c34030b68ecb6079bd9dce8cb3d3604) --- test/regress_dns.c | 59 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 26 deletions(-) diff --git a/test/regress_dns.c b/test/regress_dns.c index b2ea8651..17cd7099 100644 --- a/test/regress_dns.c +++ b/test/regress_dns.c @@ -1161,34 +1161,36 @@ static void be_connect_hostname_event_cb(struct bufferevent *bev, short what, void *ctx) { struct be_conn_hostname_result *got = ctx; - if (!got->what) { - TT_BLATHER(("Got a bufferevent event %d", what)); - got->what = what; - - if ((what & BEV_EVENT_CONNECTED) || (what & BEV_EVENT_ERROR)) { - int expected = 3; - int r = bufferevent_socket_get_dns_error(bev); - - if (r) { - got->dnserr = r; - TT_BLATHER(("DNS error %d: %s", r, - evutil_gai_strerror(r))); - } ++total_connected_or_failed; - TT_BLATHER(("Got %d connections or errors.", total_connected_or_failed)); - - /** emfile test */ - if (errno == EMFILE) { - expected = 0; - } - if (total_n_accepted >= expected && total_connected_or_failed >= 5) - event_base_loopexit(be_connect_hostname_base, - NULL); - } - } else { + if (got->what) { TT_FAIL(("Two events on one bufferevent. %d,%d", got->what, (int)what)); } + + TT_BLATHER(("Got a bufferevent event %d", what)); + got->what = what; + + if ((what & BEV_EVENT_CONNECTED) || (what & BEV_EVENT_ERROR)) { + int expected = 3; + int r = bufferevent_socket_get_dns_error(bev); + + if (r) { + got->dnserr = r; + TT_BLATHER(("DNS error %d: %s", r, + evutil_gai_strerror(r))); + } + ++total_connected_or_failed; + TT_BLATHER(("Got %d connections or errors.", total_connected_or_failed)); + + /** emfile test */ + if (errno == EMFILE) { + expected = 0; + } + + if (total_n_accepted >= expected && total_connected_or_failed >= 5) + event_base_loopexit(be_connect_hostname_base, + NULL); + } } static void @@ -1242,8 +1244,13 @@ test_bufferevent_connect_hostname(void *arg) #ifdef EVENT__HAVE_SETRLIMIT if (emfile) { - struct rlimit file = { 1, 1 }; - setrlimit(RLIMIT_NOFILE, &file); + int fd = socket(AF_INET, SOCK_STREAM, 0); + struct rlimit file = { fd, fd }; + + tt_int_op(fd, >=, 0); + tt_assert(!close(fd)); + + tt_assert(!setrlimit(RLIMIT_NOFILE, &file)); } #endif -- cgit v1.2.1 From 44fa5b19f71e2441a22d308fae8487295e7ce63c Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 23 Apr 2018 01:50:55 +0300 Subject: Fix CheckFunctionExistsEx() cmake macro on win32 For example under mingw64 it could not detect that strtok_r() exists, because it checks with: void *p = func_name; And for this you need the function to be defined, so just sync our CheckFunctionExistsEx.c with CheckFunctionExists.c from cmake (and later we should drop them out) since it does correct things to detech functions existence. Also for WIN32 there is -FIwinsock2.h -FIws2tcpip.h, and I guess that is not works for mingw gcc (since -F in gcc is framework, and in windows -FI is like -include in gcc). But looks like we do not need them already (due to fixed CheckFunctionExistsEx()). Refs: #605 (cherry picked from commit accf383e044257ecdef002ea255056a5d15a4811) --- cmake/CheckFunctionExistsEx.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/cmake/CheckFunctionExistsEx.c b/cmake/CheckFunctionExistsEx.c index 5ee3e591..224e3404 100644 --- a/cmake/CheckFunctionExistsEx.c +++ b/cmake/CheckFunctionExistsEx.c @@ -1,30 +1,28 @@ #ifdef CHECK_FUNCTION_EXISTS -#ifndef _WIN32 -char CHECK_FUNCTION_EXISTS(); +#ifdef __cplusplus +extern "C" #endif - + char + CHECK_FUNCTION_EXISTS(void); #ifdef __CLASSIC_C__ -int main(){ +int main() +{ int ac; - char*av[]; + char* av[]; #else -int main(int ac, char*av[]){ +int main(int ac, char* av[]) +{ #endif -#ifdef _WIN32 - void * p = &CHECK_FUNCTION_EXISTS; -#else CHECK_FUNCTION_EXISTS(); -#endif - if(ac > 1000) - { + if (ac > 1000) { return *av[0]; - } + } return 0; } -#else /* CHECK_FUNCTION_EXISTS */ +#else /* CHECK_FUNCTION_EXISTS */ -# error "CHECK_FUNCTION_EXISTS has to specify the function" +#error "CHECK_FUNCTION_EXISTS has to specify the function" #endif /* CHECK_FUNCTION_EXISTS */ -- cgit v1.2.1 From d9d1c09e259ddbc3a5103a66567b0c0c7b2c19a9 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 24 Apr 2018 00:59:11 +0300 Subject: Notify event base if there are no more events, so it can exit without delay Fixes: #623 (cherry picked from commit 23c2914f6b430f2c2d74c267c13ffab3dda1b325) --- event.c | 4 ++++ test/regress.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/event.c b/event.c index c5560707..caf766b5 100644 --- a/event.c +++ b/event.c @@ -2847,6 +2847,10 @@ event_del_nolock_(struct event *ev, int blocking) notify = 1; res = 0; } + /* If we do not have events, let's notify event base so it can + * exit without waiting */ + if (!event_haveevents(base) && !N_ACTIVE_CALLBACKS(base)) + notify = 1; } /* if we are not in the right thread, we need to wake up the loop */ diff --git a/test/regress.c b/test/regress.c index 88e9b259..6daa17ed 100644 --- a/test/regress.c +++ b/test/regress.c @@ -1039,6 +1039,34 @@ test_del_wait(void) end: ; } + +static void null_cb(evutil_socket_t fd, short what, void *arg) {} +static void* test_del_notify_thread(void *arg) +{ + event_dispatch(); + return NULL; +} +static void +test_del_notify(void) +{ + struct event ev; + pthread_t thread; + + test_ok = 1; + + event_set(&ev, -1, EV_READ, null_cb, &ev); + event_add(&ev, NULL); + + pthread_create(&thread, NULL, test_del_notify_thread, NULL); + + { + struct timeval delay = { 0, 1000 }; + evutil_usleep_(&delay); + } + + event_del(&ev); + pthread_join(thread, NULL); +} #endif static void @@ -3452,6 +3480,7 @@ struct testcase_t main_testcases[] = { #ifdef EVENT__HAVE_PTHREADS /** TODO: support win32 */ LEGACY(del_wait, TT_ISOLATED|TT_NEED_THREADS), + LEGACY(del_notify, TT_ISOLATED|TT_NEED_THREADS), #endif END_OF_TESTCASES -- cgit v1.2.1 From e2732c9063503220e137c37aca48f706da0c29ed Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 7 May 2018 02:39:44 +0300 Subject: Make rpc headers self-compilable Fixes: #633 (cherry picked from commit c57f5c34903b02c6e7378865f71a2b83a5befb96) --- include/event2/rpc.h | 2 ++ include/event2/rpc_struct.h | 14 ++++++++++++++ test/regress_rpc.c | 1 - 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/include/event2/rpc.h b/include/event2/rpc.h index 830d0c62..e7ada0b6 100644 --- a/include/event2/rpc.h +++ b/include/event2/rpc.h @@ -27,6 +27,8 @@ #ifndef EVENT2_RPC_H_INCLUDED_ #define EVENT2_RPC_H_INCLUDED_ +/* For int types. */ +#include #include #ifdef __cplusplus diff --git a/include/event2/rpc_struct.h b/include/event2/rpc_struct.h index 8f691f49..f3cb460a 100644 --- a/include/event2/rpc_struct.h +++ b/include/event2/rpc_struct.h @@ -38,6 +38,16 @@ extern "C" { */ +/* Fix so that people don't have to run with */ +#ifndef TAILQ_ENTRY +#define EVENT_DEFINED_TQENTRY_ +#define TAILQ_ENTRY(type) \ +struct { \ + struct type *tqe_next; /* next element */ \ + struct type **tqe_prev; /* address of previous next element */ \ +} +#endif /* !TAILQ_ENTRY */ + /** * provides information about the completed RPC request. */ @@ -93,6 +103,10 @@ struct evrpc { struct evrpc_base *base; }; +#ifdef EVENT_DEFINED_TQENTRY_ +#undef TAILQ_ENTRY +#endif + #ifdef __cplusplus } #endif diff --git a/test/regress_rpc.c b/test/regress_rpc.c index 01a058cb..2cb2bcd9 100644 --- a/test/regress_rpc.c +++ b/test/regress_rpc.c @@ -61,7 +61,6 @@ #include "event2/http_compat.h" #include "event2/http_struct.h" #include "event2/rpc.h" -#include "event2/rpc.h" #include "event2/rpc_struct.h" #include "event2/tag.h" #include "log-internal.h" -- cgit v1.2.1 From 63a054f8c6f160bd93257b6be2c126ff4f497d0e Mon Sep 17 00:00:00 2001 From: Philip Prindeville Date: Wed, 18 Apr 2018 15:09:35 -0600 Subject: config.h can't be prefixed unconditionally The script make-event-config.sed was mangling all the symbols by prefixing them with "EVENT__". The problem here is that some symbols aren't for local consumption within libevent, but rather influence other system header files (ex: __USE_FILE_OFFSET64 is used by dozens of header files including ). As a workaround, all symbols starting with a capital letter only (with the exception of STDC_HEADERS which must also be left untouched) will be mangled. Future contributors will need to be aware of this distinction. (cherry picked from commit 587e9f5828c4eb3c6e79e9eb29f174e4ae0c05bd) --- make-event-config.sed | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/make-event-config.sed b/make-event-config.sed index e31018a2..3dc404b5 100644 --- a/make-event-config.sed +++ b/make-event-config.sed @@ -18,6 +18,10 @@ $a\ \ #endif /* event2/event-config.h */ -s/#\( *\)define /#\1define EVENT__/ -s/#\( *\)undef /#\1undef EVENT__/ -s/#\( *\)if\(n*\)def /#\1if\2def EVENT__/ +/#\( *\)undef STDC_HEADERS\>/b +/#\( *\)define STDC_HEADERS\>/b + +# Only rewrite symbols starting with capitals +s/#\( *\)define \([A-Z]\)/#\1define EVENT__\2/ +s/#\( *\)undef \([A-Z]\)/#\1undef EVENT__\2/ +s/#\( *\)if\(n*\)def \([A-Z]\)/#\1if\2def EVENT__\2/ -- cgit v1.2.1 From 00761b436d6ffccffd0758880a44e8320ebf25ea Mon Sep 17 00:00:00 2001 From: an-tao <20741618@qq.com> Date: Fri, 25 May 2018 18:07:28 +0800 Subject: fix spelling mistakes Closes: nmathewson/Libevent#162 (cherry picked from commit 0789bc5220af6eaa9b483afcd1405be6f01d2187) --- bufferevent_openssl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bufferevent_openssl.c b/bufferevent_openssl.c index 6a803a63..6915f36a 100644 --- a/bufferevent_openssl.c +++ b/bufferevent_openssl.c @@ -154,7 +154,7 @@ bio_bufferevent_read(BIO *b, char *out, int outlen) return r; } -/* Called to write data info the BIO */ +/* Called to write data into the BIO */ static int bio_bufferevent_write(BIO *b, const char *in, int inlen) { -- cgit v1.2.1 From 8ab60087c3028f3edf87ec38bf7b84a8ccae8107 Mon Sep 17 00:00:00 2001 From: Philip Prindeville Date: Sat, 16 Jun 2018 16:44:06 -0600 Subject: Get rid of macros which are never used There are no expansions of these macros or tests for their existence. Signed-off-by: Philip Prindeville (cherry picked from commit 755896efe25e5caecd498c08cce072c713720783) --- CMakeLists.txt | 6 ------ WIN32-Code/nmake/event2/event-config.h | 8 -------- event-config.h.cmake | 6 ------ 3 files changed, 20 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 64ece249..c45e61e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -471,10 +471,8 @@ endif() CHECK_TYPE_SIZE(pid_t EVENT__SIZEOF_PID_T) if(NOT EVENT__SIZEOF_PID_T) - set(EVENT__pid_t "int") set(EVENT__SIZEOF_PID_T ${EVENT__SIZEOF_INT}) else() - set(EVENT__pid_t "pid_t") set(EVENT__SIZEOF_PID_T EVENT__SIZEOF_PID_T) endif() @@ -515,10 +513,6 @@ if (EVENT__HAVE_KQUEUE) endif() endif() -CHECK_SYMBOL_EXISTS(_MINIX "stdio.h" EVENT___MINIX) -CHECK_SYMBOL_EXISTS(_POSIX_1_SOURCE "stdio.h" EVENT___POSIX_1_SOURCE) -CHECK_SYMBOL_EXISTS(_POSIX_SOURCE "stdio.h" EVENT___POSIX_SOURCE) - if(EVENT__HAVE_NETDB_H) list(APPEND CMAKE_EXTRA_INCLUDE_FILES netdb.h) CHECK_TYPE_SIZE("struct addrinfo" EVENT__HAVE_STRUCT_ADDRINFO) diff --git a/WIN32-Code/nmake/event2/event-config.h b/WIN32-Code/nmake/event2/event-config.h index c09ec3f9..af809398 100644 --- a/WIN32-Code/nmake/event2/event-config.h +++ b/WIN32-Code/nmake/event2/event-config.h @@ -331,9 +331,6 @@ #define EVENT__SIZEOF_TIME_T 4 #endif -/* Define to 1 if you have the ANSI C header files. */ -#define EVENT__STDC_HEADERS 1 - /* Define to 1 if you can safely include both and . */ #define EVENT__TIME_WITH_SYS_TIME 1 @@ -345,12 +342,7 @@ /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ -#ifndef _EVENT___cplusplus #define EVENT__inline __inline -#endif - -/* Define to `int' if does not define. */ -/* #undef EVENT__pid_t */ /* Define to `unsigned' if does not define. */ /* #undef EVENT__size_t */ diff --git a/event-config.h.cmake b/event-config.h.cmake index 5c233a3d..6cfbb953 100644 --- a/event-config.h.cmake +++ b/event-config.h.cmake @@ -461,9 +461,6 @@ /* The size of `size_t', as computed by sizeof. */ #define EVENT__SIZEOF_SIZE_T @EVENT__SIZEOF_SIZE_T@ -/* Define to 1 if you have the ANSI C header files. */ -#cmakedefine EVENT__STDC_HEADERS 1 - /* Define to 1 if you can safely include both and . */ #cmakedefine EVENT__TIME_WITH_SYS_TIME 1 @@ -499,9 +496,6 @@ #define EVENT__inline @EVENT__inline@ #endif -/* Define to `int' if does not define. */ -#define EVENT__pid_t @EVENT__pid_t@ - /* Define to `unsigned' if does not define. */ #define EVENT__size_t @EVENT__size_t@ -- cgit v1.2.1 From 06ec5de6154a6eb2df0a3a901b59a4d0f1cc61bb Mon Sep 17 00:00:00 2001 From: Philip Prindeville Date: Sat, 16 Jun 2018 17:39:34 -0600 Subject: Add convenience macros for user-triggered events Signed-off-by: Philip Prindeville Closes: #647 (picked) (cherry picked from commit d2acf67ec3ad2916236396992f094c0c65016028) --- include/event2/event.h | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/include/event2/event.h b/include/event2/event.h index af56c9ed..a95b5b9d 100644 --- a/include/event2/event.h +++ b/include/event2/event.h @@ -963,11 +963,13 @@ int event_base_got_break(struct event_base *); /** @name evtimer_* macros - Aliases for working with one-shot timer events */ + Aliases for working with one-shot timer events + If you need EV_PERSIST timer use event_*() functions. + */ /**@{*/ #define evtimer_assign(ev, b, cb, arg) \ event_assign((ev), (b), -1, 0, (cb), (arg)) -#define evtimer_new(b, cb, arg) event_new((b), -1, 0, (cb), (arg)) +#define evtimer_new(b, cb, arg) event_new((b), -1, 0, (cb), (arg)) #define evtimer_add(ev, tv) event_add((ev), (tv)) #define evtimer_del(ev) event_del(ev) #define evtimer_pending(ev, tv) event_pending((ev), EV_TIMEOUT, (tv)) @@ -990,6 +992,20 @@ int event_base_got_break(struct event_base *); #define evsignal_initialized(ev) event_initialized(ev) /**@}*/ +/** + @name evuser_* macros + + Aliases for working with user-triggered events + If you need EV_PERSIST event use event_*() functions. + */ +/**@{*/ +#define evuser_new(b, cb, arg) event_new((b), -1, 0, (cb), (arg)) +#define evuser_del(ev) event_del(ev) +#define evuser_pending(ev, tv) event_pending((ev), 0, (tv)) +#define evuser_initialized(ev) event_initialized(ev) +#define evuser_trigger(ev) event_active((ev), 0, 0) +/**@}*/ + /** A callback function for an event. -- cgit v1.2.1 From 85fed75f7edbfcdabb69a52620e8350b4eca0a46 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 19 Jun 2018 10:18:46 +0300 Subject: Replace all EVENT_HAVE with EVENT__HAVE (EVENT__HAVE_USLEEP) (cherry picked from commit 35258a1f4e09d9e7fcb003cd0572343670180495) --- evutil_time.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evutil_time.c b/evutil_time.c index d658b30e..c3a23589 100644 --- a/evutil_time.c +++ b/evutil_time.c @@ -43,7 +43,7 @@ #ifndef EVENT__HAVE_GETTIMEOFDAY #include #endif -#if !defined(EVENT__HAVE_NANOSLEEP) && !defined(EVENT_HAVE_USLEEP) && \ +#if !defined(EVENT__HAVE_NANOSLEEP) && !defined(EVENT__HAVE_USLEEP) && \ !defined(_WIN32) #include #endif -- cgit v1.2.1 From 37423849e61a765b24792cae46b7888ba77f9030 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Thu, 21 Jun 2018 02:37:24 +0300 Subject: Ignore evconfig-private.h for autotools Fixes: e2874d95af584b3657eb5dc1d2e5404811dce117 ("Adopt ignore rules for cmake + ninja") (cherry picked from commit 064a598716e69a1ac3937dd1bbc74194d0f3d3cf) --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index e85f9f38..4af03587 100644 --- a/.gitignore +++ b/.gitignore @@ -117,6 +117,7 @@ cscope* **/include/event2/event-config.h **/include/evconfig-private.h +/evconfig-private.h # Files generated by cmake CMakeCache.txt -- cgit v1.2.1 From 780eaac827d480805218b4ce90bded74486f86e9 Mon Sep 17 00:00:00 2001 From: Leo Zhang Date: Tue, 15 May 2018 12:14:05 +0800 Subject: test: make regress_dns C89 compatible Closes: #635 (cherry-picked) (cherry picked from commit d9ffd2213702bc22c467bd83c230a1a5e97e9e67) --- test/regress_dns.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/regress_dns.c b/test/regress_dns.c index 17cd7099..579963d2 100644 --- a/test/regress_dns.c +++ b/test/regress_dns.c @@ -1211,6 +1211,7 @@ test_bufferevent_connect_hostname(void *arg) int emfile = data->setup_data && !strcmp(data->setup_data, "emfile"); int success = BEV_EVENT_CONNECTED; int default_error = 0; + unsigned i; if (emfile) { success = BEV_EVENT_ERROR; @@ -1257,7 +1258,7 @@ test_bufferevent_connect_hostname(void *arg) /* Now, finally, at long last, launch the bufferevents. One should do * a failing lookup IP, one should do a successful lookup by IP, * and one should do a successful lookup by hostname. */ - for (int i = 0; i < ARRAY_SIZE(be); ++i) { + for (i = 0; i < ARRAY_SIZE(be); ++i) { memset(&be_outcome[i], 0, sizeof(be_outcome[i])); be[i] = bufferevent_socket_new(data->base, -1, BEV_OPT_CLOSE_ON_FREE); bufferevent_setcb(be[i], NULL, NULL, be_connect_hostname_event_cb, @@ -1322,7 +1323,7 @@ end: evdns_close_server_port(port); if (dns) evdns_base_free(dns, 0); - for (int i = 0; i < ARRAY_SIZE(be); ++i) { + for (i = 0; i < ARRAY_SIZE(be); ++i) { if (be[i]) bufferevent_free(be[i]); } -- cgit v1.2.1 From 061823b14796e4c633b1dbb4c0f702d0a391230e Mon Sep 17 00:00:00 2001 From: Philip Prindeville Date: Wed, 20 Jun 2018 23:47:51 -0600 Subject: Tell Travis to use quiet git clone Otherwise the logs show a bunch of pointless progress, which is really only useful for interactive sessions. Signed-off-by: Philip Prindeville Closes: #651 (cherry-picked) (cherry picked from commit 24236aed01798303745470e6c498bf606e88724a) --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index d0cab03c..581b5b1d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,9 @@ os: sudo: false dist: trusty +git: + quiet: true + env: matrix: - EVENT_BUILD_METHOD=cmake EVENT_CMAKE_OPTIONS="-DEVENT__COVERAGE=ON -DCMAKE_BUILD_TYPE=debug" COVERALLS=yes -- cgit v1.2.1 From 0d5dde5357221f2d1ad3b01b2cad78adae618ca4 Mon Sep 17 00:00:00 2001 From: Nathan French Date: Thu, 5 Jul 2018 12:46:51 -0400 Subject: [http] fix C90 warnings (cherry picked from commit 514dc7579c43e673bdf613e01690371438661260) --- http.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/http.c b/http.c index c79e710c..c22f953c 100644 --- a/http.c +++ b/http.c @@ -4836,6 +4836,8 @@ static struct evhttp_uri * evhttp_uri_parse_authority(char *source_uri) { struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri)); + char *end; + if (uri == NULL) { event_warn("%s: calloc", __func__); goto err; @@ -4843,7 +4845,7 @@ evhttp_uri_parse_authority(char *source_uri) uri->port = -1; uri->flags = 0; - char *end = end_of_authority(source_uri); + end = end_of_authority(source_uri); if (parse_authority(uri, source_uri, end) < 0) goto err; -- cgit v1.2.1 From aade513b4e256e0190c4f41f26efd3a494b0126b Mon Sep 17 00:00:00 2001 From: Xiaozhou Liu Date: Thu, 5 Jul 2018 11:25:24 +0800 Subject: Fix typo Closes: #658 (cherry picked from commit 30d77f1b59bcd1433a89e803b9fa045c50883868) --- include/event2/event.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/event2/event.h b/include/event2/event.h index a95b5b9d..1e106f76 100644 --- a/include/event2/event.h +++ b/include/event2/event.h @@ -285,7 +285,7 @@ struct event * There are many options that can be used to alter the behavior and * implementation of an event_base. To avoid having to pass them all in a * complex many-argument constructor, we provide an abstract data type - * wrhere you set up configation information before passing it to + * where you set up configation information before passing it to * event_base_new_with_config(). * * @see event_config_new(), event_config_free(), event_base_new_with_config(), -- cgit v1.2.1 From 9bcfcbda95088734f56bccec6f65fe2996b4aba0 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Wed, 1 Aug 2018 03:01:43 +0300 Subject: appveyor: disable almost all configurations (except autotools/cmake basic) Since we have FREE plan, we have a lot of limits on our builds, so let's reduce their amount to make them run/start faster (I hope). (cherry picked from commit bdd531288affe9fa46184bb9b492defbcf379c63) --- appveyor.yml | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 7001cd4c..cd1b470a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -11,26 +11,29 @@ environment: matrix: - EVENT_BUILD_METHOD: "autotools" EVENT_CONFIGURE_OPTIONS: "" - - EVENT_BUILD_METHOD: "autotools" - EVENT_CONFIGURE_OPTIONS: "--disable-openssl" - - EVENT_BUILD_METHOD: "autotools" - EVENT_CONFIGURE_OPTIONS: "--disable-thread-support" - - EVENT_BUILD_METHOD: "autotools" - EVENT_CONFIGURE_OPTIONS: "--disable-debug-mode" - - EVENT_BUILD_METHOD: "autotools" - EVENT_CONFIGURE_OPTIONS: "--disable-malloc-replacement" - EVENT_BUILD_METHOD: "cmake" EVENT_CMAKE_OPTIONS: "" - - EVENT_BUILD_METHOD: "cmake" - EVENT_CMAKE_OPTIONS: "-DEVENT__DISABLE_OPENSSL=ON" - - EVENT_BUILD_METHOD: "cmake" - EVENT_CMAKE_OPTIONS: "-DEVENT__DISABLE_THREAD_SUPPORT=ON" - - EVENT_BUILD_METHOD: "cmake" - EVENT_CMAKE_OPTIONS: "-DEVENT__DISABLE_DEBUG_MODE=ON" - - EVENT_BUILD_METHOD: "cmake" - EVENT_CMAKE_OPTIONS: "-DEVENT__DISABLE_MM_REPLACEMENT=ON" - - EVENT_BUILD_METHOD: "cmake" - EVENT_CMAKE_OPTIONS: "-DCMAKE_C_FLAGS='-DUNICODE -D_UNICODE'" + # Since we have FREE billing plan, let's reduce amount of builds to make + # primary two runs/starts faster. + # + # - EVENT_BUILD_METHOD: "autotools" + # EVENT_CONFIGURE_OPTIONS: "--disable-openssl" + # - EVENT_BUILD_METHOD: "autotools" + # EVENT_CONFIGURE_OPTIONS: "--disable-thread-support" + # - EVENT_BUILD_METHOD: "autotools" + # EVENT_CONFIGURE_OPTIONS: "--disable-debug-mode" + # - EVENT_BUILD_METHOD: "autotools" + # EVENT_CONFIGURE_OPTIONS: "--disable-malloc-replacement" + # - EVENT_BUILD_METHOD: "cmake" + # EVENT_CMAKE_OPTIONS: "-DEVENT__DISABLE_OPENSSL=ON" + # - EVENT_BUILD_METHOD: "cmake" + # EVENT_CMAKE_OPTIONS: "-DEVENT__DISABLE_THREAD_SUPPORT=ON" + # - EVENT_BUILD_METHOD: "cmake" + # EVENT_CMAKE_OPTIONS: "-DEVENT__DISABLE_DEBUG_MODE=ON" + # - EVENT_BUILD_METHOD: "cmake" + # EVENT_CMAKE_OPTIONS: "-DEVENT__DISABLE_MM_REPLACEMENT=ON" + # - EVENT_BUILD_METHOD: "cmake" + # EVENT_CMAKE_OPTIONS: "-DCMAKE_C_FLAGS='-DUNICODE -D_UNICODE'" init: - 'echo Building libevent %version% for Windows' - 'echo System architecture: %PLATFORM%' -- cgit v1.2.1 From d7579fb95808bd0da7af8b3575e71c943397ab12 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Wed, 1 Aug 2018 00:58:02 +0300 Subject: autotools: include win32 specific headers for socklen_t detection on win32/mingw The [1] removes EVENT__ prefix, and now if we will incorrectly detect that "foobar" (or socklen_t in our case) type is not available, but somewhere later it will be available then we will get next error [2]: error: two or more data types in declaration specifiers According to [3]: - Compile something in Cygwin and you are compiling it for Cygwin. - Compile something in MinGW and you are compiling it for Windows. And I can confirm this, since there is _WIN32 defined (according to [4]) And since according to [5] our image in appveyour (Visual Studion 2015) has mingw (and we use it, not cygwin) we need ws2tcpip.h (over sys/socket.h -- which does not exist in win32) header to detect socklen_t existence. [1]: 587e9f5828c4eb3c6e79e9eb29f174e4ae0c05bd ("config.h can't be prefixed unconditionally") [2]: https://ci.appveyor.com/project/nmathewson/libevent/build/job/yonukoc5q3tr3e5e#L372 [3]: https://stackoverflow.com/questions/771756/what-is-the-difference-between-cygwin-and-mingw [4]: https://www.appveyor.com/docs/build-environment/#mingw-msys-cygwin [5]: https://ci.appveyor.com/project/nmathewson/libevent/build/job/yonukoc5q3tr3e5e#L164 Fixes: #649 (cherry picked from commit 4728ffed865985ab663b2e067afb904d124fc1db) --- configure.ac | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index a3b7fd41..d28c5918 100644 --- a/configure.ac +++ b/configure.ac @@ -727,7 +727,11 @@ AC_CHECK_TYPES([struct linger],,, AC_MSG_CHECKING([for socklen_t]) AC_TRY_COMPILE([ #include - #include ], + #ifdef _WIN32 + #include + #else + #include + #endif], [socklen_t x;], AC_MSG_RESULT([yes]), [AC_MSG_RESULT([no]) -- cgit v1.2.1 From 21bfaa702f4e67fc171e0f909be1c8181d57311b Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Wed, 1 Aug 2018 09:48:42 +0300 Subject: Merge branch 'official/pr/671' -- README cleanup * official/pr/671: Capitalise project names consistently in README.md Indent configure flag section to make markdown format them as code Use https for resources that support it Rewords awkward sentences in README.md Fix typos in README.md (cherry picked from commit c3a6fe75e1511a4c7a7a6ef0a5954b1918902933) --- README.md | 60 ++++++++++++++++++++++++++++++------------------------------ 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 3342cf1a..967fbdfe 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

- libevent logo + libevent logo

@@ -20,10 +20,10 @@ $ make verify # (optional) $ sudo make install -## Cmake (General) +## CMake (General) -The following Libevent specific Cmake variables are as follows (the values being +The following Libevent specific CMake variables are as follows (the values being the default). ``` @@ -34,16 +34,16 @@ EVENT_INSTALL_CMAKE_DIR:PATH=lib/cmake/libevent # GCC/CLang). Make sure to enable -DCMAKE_BUILD_TYPE=Debug as well. EVENT__COVERAGE:BOOL=OFF -# Defines if libevent should build without the benchmark exectuables +# Defines if Libevent should build without the benchmark executables EVENT__DISABLE_BENCHMARK:BOOL=OFF -# Define if libevent should build without support for a debug mode +# Define if Libevent should build without support for a debug mode EVENT__DISABLE_DEBUG_MODE:BOOL=OFF -# Define if libevent should not allow replacing the mm functions +# Define if Libevent should not allow replacing the mm functions EVENT__DISABLE_MM_REPLACEMENT:BOOL=OFF -# Define if libevent should build without support for OpenSSL encrpytion +# Define if Libevent should build without support for OpenSSL encryption EVENT__DISABLE_OPENSSL:BOOL=OFF # Disable the regress tests @@ -55,15 +55,15 @@ EVENT__DISABLE_SAMPLES:BOOL=OFF # If tests should be compiled or not EVENT__DISABLE_TESTS:BOOL=OFF -# Define if libevent should not be compiled with thread support +# Define if Libevent should not be compiled with thread support EVENT__DISABLE_THREAD_SUPPORT:BOOL=OFF # Enables verbose debugging EVENT__ENABLE_VERBOSE_DEBUG:BOOL=OFF -# When crosscompiling forces running a test program that verifies that Kqueue +# When cross compiling, forces running a test program that verifies that Kqueue # works with pipes. Note that this requires you to manually run the test program -# on the the cross compilation target to verify that it works. See cmake +# on the the cross compilation target to verify that it works. See CMake # documentation for try_run for more details EVENT__FORCE_KQUEUE_CHECK:BOOL=OFF ``` @@ -73,7 +73,7 @@ __More variables can be found by running `cmake -LAH `__ ## CMake (Windows) -Install CMake: +Install CMake: $ md build && cd build @@ -92,12 +92,12 @@ Install CMake: ## Autoconf -To build libevent, type +To build Libevent, type $ ./configure && make - (If you got libevent from the git repository, you will + (If you got Libevent from the git repository, you will first need to run the included "autogen.sh" script in order to generate the configure script.) @@ -111,36 +111,36 @@ Install as root via Before reporting any problems, please run the regression tests. -To enable the low-level tracing build the library as: +To enable low-level tracing, build the library as: $ CFLAGS=-DUSE_DEBUG ./configure [...] Standard configure flags should work. In particular, see: - --disable-shared Only build static libraries - --prefix Install all files relative to this directory. + --disable-shared Only build static libraries. + --prefix Install all files relative to this directory. The configure script also supports the following flags: - --enable-gcc-warnings Enable extra compiler checking with GCC. - --disable-malloc-replacement - Don't let applications replace our memory - management functions - --disable-openssl Disable support for OpenSSL encryption. - --disable-thread-support Don't support multithreaded environments. + --enable-gcc-warnings Enable extra compiler checking with GCC. + --disable-malloc-replacement + Don't let applications replace our memory + management functions. + --disable-openssl Disable support for OpenSSL encryption. + --disable-thread-support Don't support multithreaded environments. ## CMake (Windows) (Note that autoconf is currently the most mature and supported build -enviroment for libevent; the cmake instructions here are new and -experimental, though they _should_ be solid. We hope that cmake will +environment for Libevent; the CMake instructions here are new and +experimental, though they _should_ be solid. We hope that CMake will still be supported in future versions of Libevent, and will try to make sure that happens.) -First of all install . +First of all install . -To build libevent using Microsoft Visual studio open the "Visual Studio Command prompt" and type: +To build Libevent using Microsoft Visual studio open the "Visual Studio Command prompt" and type: ``` $ cd @@ -186,15 +186,15 @@ $ git clone https://github.com/libevent/libevent.git You can browse the git repository online at: - + To report bugs, issues, or ask for new features: __Patches__: https://github.com/libevent/libevent/pulls -> OK, those are not really _patches_ You fork, modify, and hit the "Create Pull Request" button. -> You can still submit normal git patchs via the mailing list. +> OK, those are not really _patches_. You fork, modify, and hit the "Create Pull Request" button. +> You can still submit normal git patches via the mailing list. -__Bugs, Features [RFC], and Issus__: https://github.com/libevent/libevent/issues +__Bugs, Features [RFC], and Issues__: https://github.com/libevent/libevent/issues > Or you can do it via the mailing list. There's also a libevent-users mailing list for talking about Libevent -- cgit v1.2.1 From b3af7bdde3ec25a045edcd4090483d470f421905 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 19 Jun 2018 10:15:08 +0300 Subject: Cleanup __func__ detection First of all __func__ is not a macro, it is char[] array, so the code that we had before in cmake, was incorrect, i.e.: #if defined (__func__) #define EVENT____func__ __func__ #elif defined(__FUNCTION__) #define EVENT____func__ __FUNCTION__ #else #define EVENT____func__ __FILE__ #endif So just detect do we have __func__/__FUNCTION__ in configure/cmake before build and define EVENT__HAVE___func__/EVENT__HAVE___FUNCTION__ to use the later to choose which should be used as a __func__ (if it is not presented). Closes: #644 (cherry picked from commit e85818d24850540d220e6d7bc0a30653ba2135f2) --- CMakeLists.txt | 6 +++++- WIN32-Code/nmake/event2/event-config.h | 3 --- configure.ac | 28 +++++++++++++++------------- event-config.h.cmake | 13 +++---------- event_rpcgen.py | 10 ++++++++-- util-internal.h | 12 ++++++++++-- 6 files changed, 41 insertions(+), 31 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c45e61e4..e1631602 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -412,7 +412,7 @@ endif() check_function_keywords("inline" "__inline" "__inline__") if (HAVE_INLINE) - set (EVENT__inline inline) + set(EVENT__inline inline) elseif (HAVE___INLINE) set(EVENT__inline __inline) elseif(HAVE___INLINE__) @@ -421,6 +421,10 @@ else() set(EVENT__inline) endif() +# __func__/__FUNCTION__ is not a macros in general +CHECK_SYMBOL_EXISTS("__func__" "" EVENT__HAVE___func__) +CHECK_SYMBOL_EXISTS("__FUNCTION__" "" EVENT__HAVE___FUNCTION__) + CHECK_SYMBOL_EXISTS(TAILQ_FOREACH sys/queue.h EVENT__HAVE_TAILQFOREACH) CHECK_CONST_EXISTS(CTL_KERN sys/sysctl.h EVENT__HAVE_DECL_CTL_KERN) CHECK_CONST_EXISTS(KERN_ARND sys/sysctl.h EVENT__HAVE_DECL_KERN_ARND) diff --git a/WIN32-Code/nmake/event2/event-config.h b/WIN32-Code/nmake/event2/event-config.h index af809398..6080f5ae 100644 --- a/WIN32-Code/nmake/event2/event-config.h +++ b/WIN32-Code/nmake/event2/event-config.h @@ -337,9 +337,6 @@ /* Version number of package */ #define EVENT__VERSION "2.1.8-stable" -/* Define to appropriate substitue if compiler doesnt have __func__ */ -#define EVENT____func__ __FUNCTION__ - /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #define EVENT__inline __inline diff --git a/configure.ac b/configure.ac index d28c5918..fe4b7325 100644 --- a/configure.ac +++ b/configure.ac @@ -739,21 +739,23 @@ AC_TRY_COMPILE([ [Define to unsigned int if you dont have it])] ) +# __func__/__FUNCTION__ is not a macros in general AC_MSG_CHECKING([whether our compiler supports __func__]) AC_TRY_COMPILE([], - [ const char *cp = __func__; ], - AC_MSG_RESULT([yes]), - AC_MSG_RESULT([no]) - AC_MSG_CHECKING([whether our compiler supports __FUNCTION__]) - AC_TRY_COMPILE([], - [ const char *cp = __FUNCTION__; ], - AC_MSG_RESULT([yes]) - AC_DEFINE(__func__, __FUNCTION__, - [Define to appropriate substitue if compiler doesnt have __func__]), - AC_MSG_RESULT([no]) - AC_DEFINE(__func__, __FILE__, - [Define to appropriate substitue if compiler doesnt have __func__]))) - + [ const char *cp = __func__; ], + [ AC_DEFINE(HAVE___func__, 1, [Define to 1 if compiler have __func__]) + AC_MSG_RESULT([yes]) + ], + AC_MSG_RESULT([no]) +) +AC_MSG_CHECKING([whether our compiler supports __FUNCTION__]) +AC_TRY_COMPILE([], + [ const char *cp = __FUNCTION__; ], + [ AC_DEFINE(HAVE___FUNCTION__, 1, [Define to 1 if compiler have __FUNCTION__]) + AC_MSG_RESULT([yes]) + ], + AC_MSG_RESULT([no]) +) # check if we can compile with pthreads have_pthreads=no diff --git a/event-config.h.cmake b/event-config.h.cmake index 6cfbb953..3f8a9b59 100644 --- a/event-config.h.cmake +++ b/event-config.h.cmake @@ -470,16 +470,6 @@ /* The size of 'void *', as computer by sizeof */ #define EVENT__SIZEOF_VOID_P @EVENT__SIZEOF_VOID_P@ -/* set an alias for whatever __func__ __FUNCTION__ is, what sillyness */ -#if defined (__func__) -#define EVENT____func__ __func__ -#elif defined(__FUNCTION__) -#define EVENT____func__ __FUNCTION__ -#else -#define EVENT____func__ __FILE__ -#endif - - /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus @@ -496,6 +486,9 @@ #define EVENT__inline @EVENT__inline@ #endif +#cmakedefine EVENT__HAVE___func__ 1 +#cmakedefine EVENT__HAVE___FUNCTION__ 1 + /* Define to `unsigned' if does not define. */ #define EVENT__size_t @EVENT__size_t@ diff --git a/event_rpcgen.py b/event_rpcgen.py index 2004090a..0911ca25 100755 --- a/event_rpcgen.py +++ b/event_rpcgen.py @@ -1582,8 +1582,14 @@ class CCodeGenerator: '#include \n' '#include \n' '#include \n\n' - '#if defined(EVENT____func__) && !defined(__func__)\n' - '#define __func__ EVENT____func__\n' + '#if defined(EVENT__HAVE___func__)\n' + '# ifndef __func__\n' + '# define __func__ __func__\n' + '# endif\n' + '#elif defined(EVENT__HAVE___FUNCTION__)\n' + '# define __func__ __FUNCTION__\n' + '#else\n' + '# define __func__ __FILE__\n' '#endif\n\n' ) diff --git a/util-internal.h b/util-internal.h index 507dceb7..fe416409 100644 --- a/util-internal.h +++ b/util-internal.h @@ -68,8 +68,16 @@ extern "C" { #ifdef EVENT__inline #define inline EVENT__inline #endif -#if defined(EVENT____func__) && !defined(__func__) -#define __func__ EVENT____func__ + +/* Define to appropriate substitute if compiler doesnt have __func__ */ +#if defined(EVENT__HAVE___func__) +# ifndef __func__ +# define __func__ __func__ +# endif +#elif defined(EVENT__HAVE___FUNCTION__) +# define __func__ __FUNCTION__ +#else +# define __func__ __FILE__ #endif /* A good no-op to use in macro definitions. */ -- cgit v1.2.1 From 3237d6972d58fb56590ab7acdea5a2ba6788cdd7 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Thu, 2 Aug 2018 09:29:29 +0300 Subject: Merge branch 'evdns_getaddrinfo-race-fix' * evdns_getaddrinfo-race-fix: evdns: add regress test for getaddrinfo race evdns: fix race condition in evdns_getaddrinfo() Merges: #673 (cherry picked from commit ee12c516cf5766b2c32203dcc20c32b8691a8ebb) --- evdns.c | 9 +++- test/regress_dns.c | 148 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+), 1 deletion(-) diff --git a/evdns.c b/evdns.c index 40042925..a3f1226a 100644 --- a/evdns.c +++ b/evdns.c @@ -4637,6 +4637,7 @@ evdns_getaddrinfo(struct evdns_base *dns_base, int err; int port = 0; int want_cname = 0; + int started = 0; if (!dns_base) { dns_base = current_base; @@ -4715,6 +4716,8 @@ evdns_getaddrinfo(struct evdns_base *dns_base, * launching those requests. (XXX we don't do that yet.) */ + EVDNS_LOCK(dns_base); + if (hints.ai_family != PF_INET6) { log(EVDNS_LOG_DEBUG, "Sending request for %s on ipv4 as %p", nodename, &data->ipv4_request); @@ -4741,7 +4744,11 @@ evdns_getaddrinfo(struct evdns_base *dns_base, evtimer_assign(&data->timeout, dns_base->event_base, evdns_getaddrinfo_timeout_cb, data); - if (data->ipv4_request.r || data->ipv6_request.r) { + started = (data->ipv4_request.r || data->ipv6_request.r); + + EVDNS_UNLOCK(dns_base); + + if (started) { return data; } else { mm_free(data); diff --git a/test/regress_dns.c b/test/regress_dns.c index 579963d2..eaf17157 100644 --- a/test/regress_dns.c +++ b/test/regress_dns.c @@ -72,9 +72,12 @@ #include "event2/util.h" #include "event2/listener.h" #include "event2/bufferevent.h" +#include #include "log-internal.h" +#include "evthread-internal.h" #include "regress.h" #include "regress_testutils.h" +#include "regress_thread.h" #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) @@ -2126,6 +2129,146 @@ end: evdns_close_server_port(dns_port); } +#ifdef EVTHREAD_USE_PTHREADS_IMPLEMENTED +struct race_param +{ + void *lock; + void *reqs_cmpl_cond; + int bw_threads; + void *bw_threads_exited_cond; + volatile int stopping; + void *base; + void *dns; +}; +static void * +race_base_run(void *arg) +{ + struct race_param *rp = (struct race_param *)arg; + event_base_loop(rp->base, EVLOOP_NO_EXIT_ON_EMPTY); + THREAD_RETURN(); +} +static void * +race_busywait_run(void *arg) +{ + struct race_param *rp = (struct race_param *)arg; + struct sockaddr_storage ss; + while (!rp->stopping) + evdns_base_get_nameserver_addr(rp->dns, 0, (struct sockaddr *)&ss, sizeof(ss)); + EVLOCK_LOCK(rp->lock, 0); + if (--rp->bw_threads == 0) + EVTHREAD_COND_SIGNAL(rp->bw_threads_exited_cond); + EVLOCK_UNLOCK(rp->lock, 0); + THREAD_RETURN(); +} +static void +race_gai_cb(int result, struct evutil_addrinfo *res, void *arg) +{ + (void)result; + (void)res; + struct race_param *rp = arg; + + --n_replies_left; + if (n_replies_left == 0) { + EVLOCK_LOCK(rp->lock, 0); + EVTHREAD_COND_SIGNAL(rp->reqs_cmpl_cond); + EVLOCK_UNLOCK(rp->lock, 0); + } +} +static void +getaddrinfo_race_gotresolve_test(void *arg) +{ + (void)arg; + struct race_param rp; + struct evdns_server_port *dns_port = NULL; + ev_uint16_t portnum = 0; + char buf[64]; + int i; + + // Some stress is needed to yield inside getaddrinfo between resolve_ipv4 and resolve_ipv6 + int n_reqs = 16384; +#ifdef _SC_NPROCESSORS_ONLN + int n_threads = sysconf(_SC_NPROCESSORS_ONLN) + 1; +#else + int n_threads = 17; +#endif + THREAD_T thread[n_threads]; + struct timeval tv; + + evthread_use_pthreads(); + + rp.base = event_base_new(); + tt_assert(rp.base); + if (evthread_make_base_notifiable(rp.base) < 0) + tt_abort_msg("Couldn't make base notifiable!"); + + dns_port = regress_get_dnsserver(rp.base, &portnum, NULL, + regress_dns_server_cb, reissue_table); + tt_assert(dns_port); + + evutil_snprintf(buf, sizeof(buf), "127.0.0.1:%d", (int)portnum); + + rp.dns = evdns_base_new(rp.base, 0); + tt_assert(!evdns_base_nameserver_ip_add(rp.dns, buf)); + + n_replies_left = n_reqs; + + EVTHREAD_ALLOC_LOCK(rp.lock, 0); + EVTHREAD_ALLOC_COND(rp.reqs_cmpl_cond); + EVTHREAD_ALLOC_COND(rp.bw_threads_exited_cond); + tt_assert(rp.lock); + tt_assert(rp.reqs_cmpl_cond); + tt_assert(rp.bw_threads_exited_cond); + rp.bw_threads = 0; + rp.stopping = 0; + + // Run resolver thread + THREAD_START(thread[0], race_base_run, &rp); + // Run busy-wait threads used to force yield this thread + for (i = 1; i < n_threads; i++) { + rp.bw_threads++; + THREAD_START(thread[i], race_busywait_run, &rp); + } + + EVLOCK_LOCK(rp.lock, 0); + + for (i = 0; i < n_reqs; ++i) { + tt_assert(evdns_getaddrinfo(rp.dns, "foof.example.com", "ssh", NULL, race_gai_cb, &rp)); + // This magic along with busy-wait threads make this thread yield frequently + if (i % 100 == 0) { + tv.tv_sec = 0; + tv.tv_usec = 10000; + evutil_usleep_(&tv); + } + } + + exit_base = rp.base; + + // Wait for some time + tv.tv_sec = 5; + tv.tv_usec = 0; + EVTHREAD_COND_WAIT_TIMED(rp.reqs_cmpl_cond, rp.lock, &tv); + + // Stop busy-wait threads + tv.tv_sec = 1; + tv.tv_usec = 0; + rp.stopping = 1; + tt_assert(EVTHREAD_COND_WAIT_TIMED(rp.bw_threads_exited_cond, rp.lock, &tv) == 0); + + EVLOCK_UNLOCK(rp.lock, 0); + + evdns_base_free(rp.dns, 1 /** fail requests */); + + tt_int_op(n_replies_left, ==, 0); + +end: + EVTHREAD_FREE_LOCK(rp.lock, 0); + EVTHREAD_FREE_COND(rp.reqs_cmpl_cond); + EVTHREAD_FREE_COND(rp.bw_threads_exited_cond); + evdns_close_server_port(dns_port); + event_base_loopbreak(rp.base); + event_base_free(rp.base); +} +#endif #define DNS_LEGACY(name, flags) \ { #name, run_legacy_test_fn, flags|TT_LEGACY, &legacy_setup, \ @@ -2183,6 +2326,11 @@ struct testcase_t dns_testcases[] = { { "client_fail_requests_getaddrinfo", dns_client_fail_requests_getaddrinfo_test, TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, +#ifdef EVTHREAD_USE_PTHREADS_IMPLEMENTED + { "getaddrinfo_race_gotresolve", + getaddrinfo_race_gotresolve_test, + TT_FORK, NULL, NULL }, +#endif END_OF_TESTCASES }; -- cgit v1.2.1 From d6c293af00ea3e00e23e1e3f0e20597f00081a4d Mon Sep 17 00:00:00 2001 From: Philip Prindeville Date: Sat, 16 Jun 2018 17:16:10 -0600 Subject: Eliminate compiler warnings (at least for gcc/linux) Signed-off-by: Philip Prindeville Closes: #646 # cherry-picked from the PR (cherry picked from commit be371163027d3988a30620537bf3fcb81fb7f077) --- test/regress_dns.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/test/regress_dns.c b/test/regress_dns.c index eaf17157..7bbae123 100644 --- a/test/regress_dns.c +++ b/test/regress_dns.c @@ -1020,7 +1020,7 @@ be_getaddrinfo_server_cb(struct evdns_server_request *req, void *data) int added_any=0; ++*n_got_p; - for (i=0;inquestions;++i) { + for (i = 0; i < req->nquestions; ++i) { const int qtype = req->questions[i]->type; const int qclass = req->questions[i]->dns_question_class; const char *qname = req->questions[i]->name; @@ -1368,7 +1368,7 @@ test_getaddrinfo_async(void *arg) struct evutil_addrinfo hints, *a; struct gai_outcome local_outcome; struct gai_outcome a_out[12]; - int i; + unsigned i; struct evdns_getaddrinfo_request *r; char buf[128]; struct evdns_server_port *port = NULL; @@ -1726,7 +1726,7 @@ test_getaddrinfo_async(void *arg) end: if (local_outcome.ai) evutil_freeaddrinfo(local_outcome.ai); - for (i=0;i<(int)ARRAY_SIZE(a_out);++i) { + for (i = 0; i < ARRAY_SIZE(a_out); ++i) { if (a_out[i].ai) evutil_freeaddrinfo(a_out[i].ai); } @@ -2000,7 +2000,7 @@ test_getaddrinfo_async_cancel_stress(void *ptr) struct sockaddr_in sin; struct sockaddr_storage ss; ev_socklen_t slen; - int i; + unsigned i; base = event_base_new(); dns_base = evdns_base_new(base, 0); @@ -2055,7 +2055,7 @@ dns_client_fail_requests_test(void *arg) char buf[64]; struct generic_dns_callback_result r[20]; - int i; + unsigned i; dns_port = regress_get_dnsserver(base, &portnum, NULL, regress_dns_server_cb, reissue_table); @@ -2163,9 +2163,9 @@ race_busywait_run(void *arg) static void race_gai_cb(int result, struct evutil_addrinfo *res, void *arg) { + struct race_param *rp = arg; (void)result; (void)res; - struct race_param *rp = arg; --n_replies_left; if (n_replies_left == 0) { @@ -2177,7 +2177,6 @@ race_gai_cb(int result, struct evutil_addrinfo *res, void *arg) static void getaddrinfo_race_gotresolve_test(void *arg) { - (void)arg; struct race_param rp; struct evdns_server_port *dns_port = NULL; ev_uint16_t portnum = 0; @@ -2194,6 +2193,8 @@ getaddrinfo_race_gotresolve_test(void *arg) THREAD_T thread[n_threads]; struct timeval tv; + (void)arg; + evthread_use_pthreads(); rp.base = event_base_new(); -- cgit v1.2.1 From d0cde45477c69fb7987115e6fc2d34fa9a2b7db2 Mon Sep 17 00:00:00 2001 From: Bogdan Harjoc Date: Thu, 9 Aug 2018 14:47:17 +0300 Subject: dns-example: free result in getaddrinfo callback According to evdns.c, the result not freed by libevent after the callback runs: evdns_getaddrinfo_gotresolve() { ... data->user_cb(0, data->pending_result, data->user_data); data->pending_result = NULL; ... } To reproduce, build with -fsanitize=address, add -g to the getopt list in dns-example.c like in the current commit and run dns-example -g google.com Closes: #681 # cherry-picked (cherry picked from commit 855f0804305a545da6880850d16809969ce72edd) --- sample/dns-example.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sample/dns-example.c b/sample/dns-example.c index 6243458a..21a75de8 100644 --- a/sample/dns-example.c +++ b/sample/dns-example.c @@ -78,6 +78,8 @@ gai_callback(int err, struct evutil_addrinfo *ai, void *arg) { const char *name = arg; int i; + struct evutil_addrinfo *first_ai = ai; + if (err) { printf("%s: %s\n", name, evutil_gai_strerror(err)); } @@ -99,6 +101,9 @@ gai_callback(int err, struct evutil_addrinfo *ai, void *arg) printf("[%d] %s: %s\n",i,name,buf); } } + + if (first_ai) + evutil_freeaddrinfo(first_ai); } static void @@ -166,7 +171,7 @@ main(int c, char **v) { return 1; } - while ((opt = getopt(c, v, "xvc:Ts:")) != -1) { + while ((opt = getopt(c, v, "xvc:Ts:g")) != -1) { switch (opt) { case 'x': o.reverse = 1; break; case 'v': ++verbose; break; -- cgit v1.2.1 From 6e81eaf2353ecf5a6e824841d1358cf00f271182 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sat, 18 Aug 2018 23:50:10 +0300 Subject: appveyor: add all build tree into artifacts in case of failure This will help in investigations of win32 failures... P.S. looks like there is no better way, since "artifacts.*.publish_on_failure" hadn't been implemented yet (while was requiested in 2015). (cherry picked from commit 29cc8386a2f7911eaa9336692a2c5544d8b4734f) --- appveyor.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index cd1b470a..b76997d1 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -59,3 +59,7 @@ build_script: $env:CTEST_PARALLEL_LEVEL="20" ctest --output-on-failure } + +on_failure: + - 7z a libevent.zip . + - appveyor PushArtifact libevent.zip -- cgit v1.2.1 From 7d6c88dd11ae1ab4ec8d4266854185f88884e271 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlo=20Marcelo=20Arenas=20Bel=C3=B3n?= Date: Wed, 15 Aug 2018 13:57:01 -0700 Subject: test: make sure pthread is defined avoid warnings with any modern C99 compiler due to implicit function declaration for pthread_create, as shown by the following : test/regress_dns.c:2226:2: warning: implicit declaration of function 'pthread_create' is invalid in C99 [-Wimplicit-function-declaration] THREAD_START(thread[0], race_base_run, &rp); ^ test/regress_thread.h:35:2: note: expanded from macro 'THREAD_START' pthread_create(&(threadvar), NULL, fn, arg) ^ test/regress_dns.c:2226:2: warning: this function declaration is not a prototype [-Wstrict-prototypes] test/regress_thread.h:35:2: note: expanded from macro 'THREAD_START' pthread_create(&(threadvar), NULL, fn, arg) ^ $ clang --version Apple LLVM version 9.1.0 (clang-902.0.39.2) Target: x86_64-apple-darwin17.7.0 Thread model: posix InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin Closes: #686 (cherry-picked) (cherry picked from commit 7af974eeaa7e5cf2f73e3176782c5a788a74f08e) --- test/regress_thread.h | 1 + 1 file changed, 1 insertion(+) diff --git a/test/regress_thread.h b/test/regress_thread.h index 831b51e5..db0d8d19 100644 --- a/test/regress_thread.h +++ b/test/regress_thread.h @@ -28,6 +28,7 @@ #define REGRESS_THREAD_H_INCLUDED_ #ifdef EVENT__HAVE_PTHREADS +#include #define THREAD_T pthread_t #define THREAD_FN void * #define THREAD_RETURN() return (NULL) -- cgit v1.2.1 From e05136c76a7bbb7c42216f0ce25200b55bf2f6c9 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Fri, 14 Sep 2018 02:24:44 +0300 Subject: evrpc: avoid NULL dereference on request is not EVHTTP_REQ_POST Fixes: #660 (cherry picked from commit 8483c5351abdd18766232de8431290165717bd57) --- evrpc.c | 3 ++- test/regress_rpc.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/evrpc.c b/evrpc.c index 2443ab27..68fa1b90 100644 --- a/evrpc.c +++ b/evrpc.c @@ -329,7 +329,8 @@ evrpc_request_cb(struct evhttp_request *req, void *arg) return; error: - evrpc_reqstate_free_(rpc_state); + if (rpc_state) + evrpc_reqstate_free_(rpc_state); evhttp_send_error(req, HTTP_SERVUNAVAIL, NULL); return; } diff --git a/test/regress_rpc.c b/test/regress_rpc.c index 2cb2bcd9..87a7efa1 100644 --- a/test/regress_rpc.c +++ b/test/regress_rpc.c @@ -879,6 +879,53 @@ end: evbuffer_free(tmp); } +static void +rpc_invalid_type(void) +{ + ev_uint16_t port; + struct evhttp *http = NULL; + struct evrpc_base *base = NULL; + struct evhttp_connection *evcon = NULL; + struct evhttp_request *req = NULL; + + rpc_setup(&http, &port, &base); + + evcon = evhttp_connection_new("127.0.0.1", port); + tt_assert(evcon); + + /* + * At this point, we want to schedule an HTTP POST request + * server using our make request method. + */ + + req = evhttp_request_new(rpc_postrequest_failure, NULL); + tt_assert(req); + + /* Add the information that we care about */ + evhttp_add_header(req->output_headers, "Host", "somehost"); + evbuffer_add_printf(req->output_buffer, "Some Nonsense"); + + if (evhttp_make_request(evcon, req, + EVHTTP_REQ_GET, + "/.rpc.Message") == -1) { + tt_abort(); + } + + test_ok = 0; + + event_dispatch(); + + evhttp_connection_free(evcon); + + rpc_teardown(base); + + tt_assert(test_ok == 1); + +end: + evhttp_free(http); +} + + #define RPC_LEGACY(name) \ { #name, run_legacy_test_fn, TT_FORK|TT_NEED_BASE|TT_LEGACY, \ &legacy_setup, \ @@ -897,6 +944,7 @@ struct testcase_t rpc_testcases[] = { RPC_LEGACY(basic_client), RPC_LEGACY(basic_queued_client), RPC_LEGACY(basic_client_with_pause), + RPC_LEGACY(invalid_type), RPC_LEGACY(client_timeout), RPC_LEGACY(test), -- cgit v1.2.1 From 2594a96ff6818d32b73bf7b63c99999f834cf830 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Wed, 17 Oct 2018 11:14:48 +0300 Subject: Add -fdiagnostics-color=always for Ninja (cherry picked from commit cec4a37120b7fe07525018e4415db8adcfba9299) --- CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index e1631602..7999699b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -153,6 +153,11 @@ if (EVENT__ENABLE_VERBOSE_DEBUG) add_definitions(-DUSE_DEBUG=1) endif() +# make it colorful under ninja-build +if ("${CMAKE_GENERATOR}" STREQUAL "Ninja") + add_compiler_flags(-fdiagnostics-color=always) +endif() + # Setup compiler flags for coverage. if (EVENT__COVERAGE) if (NOT "${CMAKE_BUILD_TYPE_LOWER}" STREQUAL "debug") -- cgit v1.2.1 From 3f692fff329733ba19f263afb7d706c7ee34fb0b Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Wed, 17 Oct 2018 23:21:32 +0300 Subject: Merge branch 'be-wm-overrun-v2' * be-wm-overrun-v2: Fix hangs due to watermarks overruns in bufferevents implementations test: cover watermarks (with some corner cases) in ssl bufferevent Fixes: #690 (cherry picked from commit 878bb2d3b9484b27594308da1d0d6a7c9bdf6647) --- bufferevent.c | 25 +++++++ include/event2/bufferevent.h | 3 + test/regress_ssl.c | 168 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 196 insertions(+) diff --git a/bufferevent.c b/bufferevent.c index 490b5983..89ad6e2b 100644 --- a/bufferevent.c +++ b/bufferevent.c @@ -111,6 +111,28 @@ bufferevent_unsuspend_write_(struct bufferevent *bufev, bufferevent_suspend_flag BEV_UNLOCK(bufev); } +/** + * Sometimes bufferevent's implementation can overrun high watermarks + * (one of examples is openssl) and in this case if the read callback + * will not handle enough data do over condition above the read + * callback will never be called again (due to suspend above). + * + * To avoid this we are scheduling read callback again here, but only + * from the user callback to avoid multiple scheduling: + * - when the data had been added to it + * - when the data had been drained from it (user specified read callback) + */ +static void bufferevent_inbuf_wm_check(struct bufferevent *bev) +{ + if (!bev->wm_read.high) + return; + if (!(bev->enabled & EV_READ)) + return; + if (evbuffer_get_length(bev->input) < bev->wm_read.high) + return; + + bufferevent_trigger(bev, EV_READ, BEV_OPT_DEFER_CALLBACKS); +} /* Callback to implement watermarks on the input buffer. Only enabled * if the watermark is set. */ @@ -147,6 +169,7 @@ bufferevent_run_deferred_callbacks_locked(struct event_callback *cb, void *arg) if (bufev_private->readcb_pending && bufev->readcb) { bufev_private->readcb_pending = 0; bufev->readcb(bufev, bufev->cbarg); + bufferevent_inbuf_wm_check(bufev); } if (bufev_private->writecb_pending && bufev->writecb) { bufev_private->writecb_pending = 0; @@ -187,6 +210,7 @@ bufferevent_run_deferred_callbacks_unlocked(struct event_callback *cb, void *arg void *cbarg = bufev->cbarg; bufev_private->readcb_pending = 0; UNLOCKED(readcb(bufev, cbarg)); + bufferevent_inbuf_wm_check(bufev); } if (bufev_private->writecb_pending && bufev->writecb) { bufferevent_data_cb writecb = bufev->writecb; @@ -230,6 +254,7 @@ bufferevent_run_readcb_(struct bufferevent *bufev, int options) SCHEDULE_DEFERRED(p); } else { bufev->readcb(bufev, bufev->cbarg); + bufferevent_inbuf_wm_check(bufev); } } diff --git a/include/event2/bufferevent.h b/include/event2/bufferevent.h index 825918e3..dac34dc7 100644 --- a/include/event2/bufferevent.h +++ b/include/event2/bufferevent.h @@ -518,6 +518,9 @@ int bufferevent_set_timeouts(struct bufferevent *bufev, On input, a bufferevent does not invoke the user read callback unless there is at least low watermark data in the buffer. If the read buffer is beyond the high watermark, the bufferevent stops reading from the network. + But be aware that bufferevent input/read buffer can overrun high watermark + limit (typical example is openssl bufferevent), so you should not relay in + this. On output, the user write callback is invoked whenever the buffered data falls below the low watermark. Filters that write to this bufev will try diff --git a/test/regress_ssl.c b/test/regress_ssl.c index 92026976..0eba2323 100644 --- a/test/regress_ssl.c +++ b/test/regress_ssl.c @@ -733,6 +733,169 @@ end: ; } +struct wm_context +{ + int server; + struct evbuffer *data; + size_t to_read; + size_t wm_high; + size_t limit; + size_t get; + struct bufferevent *bev; +}; +static void +wm_transfer(struct bufferevent *bev, void *arg) +{ + struct wm_context *ctx = arg; + struct evbuffer *in = bufferevent_get_input(bev); + struct evbuffer *out = bufferevent_get_output(bev); + size_t len = evbuffer_get_length(in); + size_t drain = len < ctx->to_read ? len : ctx->to_read; + + evbuffer_drain(in, drain); + ctx->get += drain; + + TT_BLATHER(("wm_transfer-%s: in: %zu, out: %zu, got: %zu", + ctx->server ? "server" : "client", + evbuffer_get_length(in), + evbuffer_get_length(out), + ctx->get)); + + evbuffer_add_buffer_reference(out, ctx->data); + if (ctx->get >= ctx->limit) { + TT_BLATHER(("wm_transfer-%s: break", + ctx->server ? "server" : "client")); + bufferevent_setcb(bev, NULL, NULL, NULL, NULL); + bufferevent_disable(bev, EV_READ); + } +} +static void +wm_eventcb(struct bufferevent *bev, short what, void *arg) +{ + struct wm_context *ctx = arg; + TT_BLATHER(("wm_eventcb-%s: %i", + ctx->server ? "server" : "client", what)); + if (what & BEV_EVENT_CONNECTED) { + } else { + ctx->get = 0; + } +} +static void +wm_acceptcb(struct evconnlistener *listener, evutil_socket_t fd, + struct sockaddr *addr, int socklen, void *arg) +{ + struct wm_context *ctx = arg; + struct bufferevent *bev; + struct event_base *base = evconnlistener_get_base(listener); + SSL *ssl = SSL_new(get_ssl_ctx()); + + SSL_use_certificate(ssl, ssl_getcert()); + SSL_use_PrivateKey(ssl, ssl_getkey()); + + bev = bufferevent_openssl_socket_new( + base, fd, ssl, BUFFEREVENT_SSL_ACCEPTING, BEV_OPT_CLOSE_ON_FREE); + + bufferevent_setwatermark(bev, EV_READ, 0, ctx->wm_high); + bufferevent_setcb(bev, wm_transfer, NULL, wm_eventcb, ctx); + bufferevent_enable(bev, EV_READ|EV_WRITE); + ctx->bev = bev; + + /* Only accept once, then disable ourself. */ + evconnlistener_disable(listener); +} +static void +regress_bufferevent_openssl_wm(void *arg) +{ + struct basic_test_data *data = arg; + struct event_base *base = data->base; + + struct evconnlistener *listener; + struct bufferevent *bev; + struct sockaddr_in sin; + struct sockaddr_storage ss; + enum regress_openssl_type type = + (enum regress_openssl_type)data->setup_data; + int bev_flags = BEV_OPT_CLOSE_ON_FREE; + ev_socklen_t slen; + SSL *ssl; + struct wm_context client, server; + char *payload; + size_t payload_len = 1<<10; + size_t wm_high = 5<<10; + + init_ssl(); + + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = htonl(0x7f000001); + + memset(&ss, 0, sizeof(ss)); + slen = sizeof(ss); + + memset(&client, 0, sizeof(client)); + memset(&server, 0, sizeof(server)); + client.server = 0; + server.server = 1; + client.data = evbuffer_new(); + server.data = evbuffer_new(); + payload = calloc(1, payload_len); + memset(payload, 'A', payload_len); + evbuffer_add(server.data, payload, payload_len); + evbuffer_add(client.data, payload, payload_len); + client.wm_high = server.wm_high = wm_high; + client.limit = server.limit = wm_high<<3; + client.to_read = server.to_read = payload_len>>1; + + TT_BLATHER(("openssl_wm: payload_len = %zu, wm_high = %zu, limit = %zu, to_read: %zu", + payload_len, wm_high, server.limit, server.to_read)); + + listener = evconnlistener_new_bind(base, wm_acceptcb, &server, + LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, + -1, (struct sockaddr *)&sin, sizeof(sin)); + + tt_assert(listener); + tt_assert(evconnlistener_get_fd(listener) >= 0); + + ssl = SSL_new(get_ssl_ctx()); + tt_assert(ssl); + + if (type & REGRESS_OPENSSL_FILTER) { + bev = bufferevent_socket_new(data->base, -1, bev_flags); + tt_assert(bev); + bev = bufferevent_openssl_filter_new( + base, bev, ssl, BUFFEREVENT_SSL_CONNECTING, bev_flags); + } else { + bev = bufferevent_openssl_socket_new( + data->base, -1, ssl, + BUFFEREVENT_SSL_CONNECTING, + bev_flags); + } + tt_assert(bev); + client.bev = bev; + + bufferevent_setwatermark(bev, EV_READ, 0, client.wm_high); + bufferevent_setcb(bev, wm_transfer, NULL, wm_eventcb, &client); + + tt_assert(getsockname(evconnlistener_get_fd(listener), + (struct sockaddr*)&ss, &slen) == 0); + + tt_assert(!bufferevent_socket_connect(bev, (struct sockaddr*)&ss, slen)); + tt_assert(!evbuffer_add_buffer_reference(bufferevent_get_output(bev), client.data)); + tt_assert(!bufferevent_enable(bev, EV_READ|EV_WRITE)); + + event_base_dispatch(base); + + tt_int_op(client.get, ==, client.limit); + tt_int_op(server.get, ==, server.limit); +end: + free(payload); + evbuffer_free(client.data); + evbuffer_free(server.data); + evconnlistener_free(listener); + bufferevent_free(client.bev); + bufferevent_free(server.bev); +} + struct testcase_t ssl_testcases[] = { #define T(a) ((void *)(a)) { "bufferevent_socketpair", regress_bufferevent_openssl, @@ -808,6 +971,11 @@ struct testcase_t ssl_testcases[] = { { "bufferevent_connect_sleep", regress_bufferevent_openssl_connect, TT_FORK|TT_NEED_BASE, &basic_setup, T(REGRESS_OPENSSL_SLEEP) }, + { "bufferevent_wm", regress_bufferevent_openssl_wm, + TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, + { "bufferevent_wm_filter", regress_bufferevent_openssl_wm, + TT_FORK|TT_NEED_BASE, &basic_setup, T(REGRESS_OPENSSL_FILTER) }, + #undef T END_OF_TESTCASES, -- cgit v1.2.1 From 235b55215ba24f67405bcbc8b30d97f0bb26efae Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Thu, 18 Oct 2018 23:16:05 +0300 Subject: Make cmake's check_const_exists() rely on cache (cherry picked from commit 4c61a04cd5207f2140b65f955559aa4ffc848e9c) --- cmake/CheckConstExists.cmake | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/cmake/CheckConstExists.cmake b/cmake/CheckConstExists.cmake index 56b49882..de074581 100644 --- a/cmake/CheckConstExists.cmake +++ b/cmake/CheckConstExists.cmake @@ -1,23 +1,25 @@ include(CheckCSourceCompiles) macro(check_const_exists CONST FILES VARIABLE) - set(check_const_exists_source "") - foreach(file ${FILES}) + if (NOT DEFINED ${VARIABLE}) + set(check_const_exists_source "") + foreach(file ${FILES}) + set(check_const_exists_source + "${check_const_exists_source} + #include <${file}>") + endforeach() set(check_const_exists_source "${check_const_exists_source} - #include <${file}>") - endforeach() - set(check_const_exists_source - "${check_const_exists_source} - int main() { (void)${CONST}; return 0; }") + int main() { (void)${CONST}; return 0; }") - check_c_source_compiles("${check_const_exists_source}" ${VARIABLE}) + check_c_source_compiles("${check_const_exists_source}" ${VARIABLE}) - if (${${VARIABLE}}) - set(${VARIABLE} 1 CACHE INTERNAL "Have const ${CONST}") - message(STATUS "Looking for ${CONST} - found") - else() - set(${VARIABLE} 0 CACHE INTERNAL "Have const ${CONST}") - message(STATUS "Looking for ${CONST} - not found") + if (${${VARIABLE}}) + set(${VARIABLE} 1 CACHE INTERNAL "Have const ${CONST}") + message(STATUS "Looking for ${CONST} - found") + else() + set(${VARIABLE} 0 CACHE INTERNAL "Have const ${CONST}") + message(STATUS "Looking for ${CONST} - not found") + endif() endif() endmacro(check_const_exists) -- cgit v1.2.1 From cdd52e7f81b340bb8386bb4cf3303331eb709bb6 Mon Sep 17 00:00:00 2001 From: Jiri Luznicky Date: Wed, 23 May 2018 15:39:13 +0200 Subject: Fix missing LIST_HEAD Despite the presence of 'sys/queue.h' in some stdlib implementations (i.e. uclibc) 'LIST_HEAD' macro can be missing. This fix defines this macro in the same manner as was done previously for 'TAILQ_'. Fixes: #539 Closes: #639 (cherry-picked) Backport: 2.1.9 (cherry picked from commit 95918754d2ba7e6bffe0fc74bebed60bd917c10c) --- buffer.c | 1 + event-internal.h | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/buffer.c b/buffer.c index 80cb54ad..8e88fdf5 100644 --- a/buffer.c +++ b/buffer.c @@ -95,6 +95,7 @@ #include "evthread-internal.h" #include "evbuffer-internal.h" #include "bufferevent-internal.h" +#include "event-internal.h" /* some systems do not have MAP_FAILED */ #ifndef MAP_FAILED diff --git a/event-internal.h b/event-internal.h index 03eb2a87..92941b71 100644 --- a/event-internal.h +++ b/event-internal.h @@ -368,6 +368,10 @@ struct event_config { }; /* Internal use only: Functions that might be missing from */ +#ifndef LIST_END +#define LIST_END(head) NULL +#endif + #ifndef TAILQ_FIRST #define TAILQ_FIRST(head) ((head)->tqh_first) #endif -- cgit v1.2.1 From 6e759975b5f0042d5f2ced890ea4824bda5b8a39 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 21 Oct 2018 03:15:34 +0300 Subject: Merge branch 'regress-dns-fixes' * regress-dns-fixes: Do not rely on getservbyname() for most of the dns regression tests Turn off dns/getaddrinfo_race_gotresolve by default Fix an error for debug locking in dns/getaddrinfo_race_gotresolve (cherry picked from commit bd2184d8d42f721fa523d01b9a9250c75fedb855) --- test/regress_dns.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/test/regress_dns.c b/test/regress_dns.c index 7bbae123..9a3f88dc 100644 --- a/test/regress_dns.c +++ b/test/regress_dns.c @@ -2112,7 +2112,7 @@ dns_client_fail_requests_getaddrinfo_test(void *arg) tt_assert(!evdns_base_nameserver_ip_add(dns, buf)); for (i = 0; i < 20; ++i) - tt_assert(evdns_getaddrinfo(dns, "foof.example.com", "ssh", NULL, getaddrinfo_cb, &r[i])); + tt_assert(evdns_getaddrinfo(dns, "foof.example.com", "80", NULL, getaddrinfo_cb, &r[i])); n_replies_left = 20; exit_base = base; @@ -2139,6 +2139,8 @@ struct race_param volatile int stopping; void *base; void *dns; + + int locked; }; static void * race_base_run(void *arg) @@ -2231,9 +2233,10 @@ getaddrinfo_race_gotresolve_test(void *arg) } EVLOCK_LOCK(rp.lock, 0); + rp.locked = 1; for (i = 0; i < n_reqs; ++i) { - tt_assert(evdns_getaddrinfo(rp.dns, "foof.example.com", "ssh", NULL, race_gai_cb, &rp)); + tt_assert(evdns_getaddrinfo(rp.dns, "foof.example.com", "80", NULL, race_gai_cb, &rp)); // This magic along with busy-wait threads make this thread yield frequently if (i % 100 == 0) { tv.tv_sec = 0; @@ -2256,12 +2259,15 @@ getaddrinfo_race_gotresolve_test(void *arg) tt_assert(EVTHREAD_COND_WAIT_TIMED(rp.bw_threads_exited_cond, rp.lock, &tv) == 0); EVLOCK_UNLOCK(rp.lock, 0); + rp.locked = 0; evdns_base_free(rp.dns, 1 /** fail requests */); tt_int_op(n_replies_left, ==, 0); end: + if (rp.locked) + EVLOCK_UNLOCK(rp.lock, 0); EVTHREAD_FREE_LOCK(rp.lock, 0); EVTHREAD_FREE_COND(rp.reqs_cmpl_cond); EVTHREAD_FREE_COND(rp.bw_threads_exited_cond); @@ -2330,7 +2336,7 @@ struct testcase_t dns_testcases[] = { #ifdef EVTHREAD_USE_PTHREADS_IMPLEMENTED { "getaddrinfo_race_gotresolve", getaddrinfo_race_gotresolve_test, - TT_FORK, NULL, NULL }, + TT_FORK|TT_OFF_BY_DEFAULT, NULL, NULL }, #endif END_OF_TESTCASES -- cgit v1.2.1 From 0033f5cc4966b5922ebcb8c735037dff6f33cd7e Mon Sep 17 00:00:00 2001 From: Bogdan Harjoc Date: Thu, 9 Aug 2018 13:04:52 +0300 Subject: evdns: handle NULL filename explicitly Otherwise we will try to open NULL filename and got EFAULT and anyway will got the same return code from evdns_base_resolv_conf_parse_impl() Closes: #680 (cherry-picked) (cherry picked from commit 3e6553a1808989c15b8dd1945b4707b7d35667ad) --- evdns.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/evdns.c b/evdns.c index a3f1226a..58209626 100644 --- a/evdns.c +++ b/evdns.c @@ -3623,6 +3623,11 @@ evdns_base_resolv_conf_parse_impl(struct evdns_base *base, int flags, const char mm_free(fname); } + if (!filename) { + evdns_resolv_set_defaults(base, flags); + return 1; + } + if ((err = evutil_read_file_(filename, &resolv, &n, 0)) < 0) { if (err == -1) { /* No file. */ -- cgit v1.2.1 From 731053b06916ae3719d160387bf702087408b10d Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 21 Oct 2018 18:31:01 +0300 Subject: Simplify bufferevent timeout tests to reduce CPU usage in between start/compare Between start (setting "started_at") and comparing the time when timeouts triggered with the start (test_timeval_diff_eq), there is too much various things that can introduce extra delays and eventually could fail the test on machine with shortage of CPU. And this is exactly what happend on: - travis-ci - #262 Here is a simple reproducer that I came up with for this issue: docker run --cpus=0.01 -e LD_LIBRARY_PATH=$PWD/lib -e PATH=/usr/bin:/bin:$PWD/bin -v $PWD:$PWD --rm -it debian:testing regress --no-fork --verbose bufferevent/bufferevent_timeout Under limited CPU (see reproducer) the test almost always has problems with that "write_timeout_at" exceed default timeval diff tolerance (test_timeval_diff_eq() has 50 tolerance), i.e.: FAIL ../test/regress_bufferevent.c:1040: assert(labs(timeval_msec_diff(((&started_at)), ((&res1.write_timeout_at))) - (100)) <= 50): 101 vs 50 But under some setup write timeout can even not triggered, and the reason for this is that we write to the bufferevent 1024*1024 bytes, and hence if evbuffer_write_iovec() will has some delay after writev() and not send more then one vector at a time [1], it is pretty simple to trigger, i.e.: FAIL ../test/regress_bufferevent.c:1040: assert(labs(timeval_msec_diff(((&started_at)), ((&res1.write_timeout_at))) - (100)) <= 50): 1540155888478 vs 50 [1]: https://gist.github.com/azat/b72773dfe7549fed865d439e03de05c1 So this patch just send static small payload for all cases (plus a few more asserts added). The outcome of this patch is that all regression tests passed on travis-ci for linux box [2]. While before it fails almost always [3]. Also reproducer with CPU limiting via docker also survive some iterations (and strictly speaking it should has less CPU then travis-ci workers I guess). [2]: https://travis-ci.org/azat/libevent/builds/444391481 [3]: https://travis-ci.org/libevent/libevent/builds/444336505 (cherry picked from commit 6ac8e775bb3cba49c276c90e288554635d38b466) --- test/regress_bufferevent.c | 51 +++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/test/regress_bufferevent.c b/test/regress_bufferevent.c index 6d69655f..faf87a7f 100644 --- a/test/regress_bufferevent.c +++ b/test/regress_bufferevent.c @@ -908,18 +908,24 @@ struct timeout_cb_result { struct timeval read_timeout_at; struct timeval write_timeout_at; struct timeval last_wrote_at; + struct timeval last_read_at; int n_read_timeouts; int n_write_timeouts; int total_calls; }; +static void +bev_timeout_read_cb(struct bufferevent *bev, void *arg) +{ + struct timeout_cb_result *res = arg; + evutil_gettimeofday(&res->last_read_at, NULL); +} static void bev_timeout_write_cb(struct bufferevent *bev, void *arg) { struct timeout_cb_result *res = arg; evutil_gettimeofday(&res->last_wrote_at, NULL); } - static void bev_timeout_event_cb(struct bufferevent *bev, short what, void *arg) { @@ -947,7 +953,6 @@ test_bufferevent_timeouts(void *arg) int use_pair = 0, use_filter = 0; struct timeval tv_w, tv_r, started_at; struct timeout_cb_result res1, res2; - char buf[1024]; memset(&res1, 0, sizeof(res1)); memset(&res2, 0, sizeof(res2)); @@ -966,7 +971,6 @@ test_bufferevent_timeouts(void *arg) bev1 = bufferevent_socket_new(data->base, data->pair[0], 0); bev2 = bufferevent_socket_new(data->base, data->pair[1], 0); } - tt_assert(bev1); tt_assert(bev2); @@ -990,30 +994,14 @@ test_bufferevent_timeouts(void *arg) tv_w.tv_sec = tv_r.tv_sec = 0; tv_w.tv_usec = 100*1000; tv_r.tv_usec = 150*1000; - bufferevent_setcb(bev1, NULL, bev_timeout_write_cb, + bufferevent_setcb(bev1, bev_timeout_read_cb, bev_timeout_write_cb, bev_timeout_event_cb, &res1); - bufferevent_setwatermark(bev1, EV_WRITE, 1024*1024+10, 0); bufferevent_set_timeouts(bev1, &tv_r, &tv_w); - if (use_pair) { - /* For a pair, the fact that the other side isn't reading - * makes the writer stall */ - bufferevent_write(bev1, "ABCDEFG", 7); - } else { - /* For a real socket, the kernel's TCP buffers can eat a - * fair number of bytes; make sure that at some point we - * have some bytes that will stall. */ - struct evbuffer *output = bufferevent_get_output(bev1); - int i; - memset(buf, 0xbb, sizeof(buf)); - for (i=0;i<1024;++i) { - evbuffer_add_reference(output, buf, sizeof(buf), - NULL, NULL); - } - } + bufferevent_write(bev1, "ABCDEFG", 7); bufferevent_enable(bev1, EV_READ|EV_WRITE); /* bev2 has nothing to say, and isn't listening. */ - bufferevent_setcb(bev2, NULL, bev_timeout_write_cb, + bufferevent_setcb(bev2, bev_timeout_read_cb, bev_timeout_write_cb, bev_timeout_event_cb, &res2); tv_w.tv_sec = tv_r.tv_sec = 0; tv_w.tv_usec = 200*1000; @@ -1030,15 +1018,26 @@ test_bufferevent_timeouts(void *arg) /* XXXX Test that actually reading or writing a little resets the * timeouts. */ - /* Each buf1 timeout happens, and happens only once. */ - tt_want(res1.n_read_timeouts); - tt_want(res1.n_write_timeouts); + tt_want(res1.total_calls == 2); tt_want(res1.n_read_timeouts == 1); tt_want(res1.n_write_timeouts == 1); + tt_want(res2.total_calls == !(use_pair && !use_filter)); + tt_want(res2.n_write_timeouts == !(use_pair && !use_filter)); + tt_want(!res2.n_read_timeouts); test_timeval_diff_eq(&started_at, &res1.read_timeout_at, 150); test_timeval_diff_eq(&started_at, &res1.write_timeout_at, 100); +#define tt_assert_timeval_empty(tv) do { \ + tt_int_op((tv).tv_sec, ==, 0); \ + tt_int_op((tv).tv_usec, ==, 0); \ +} while(0) + tt_assert_timeval_empty(res1.last_read_at); + tt_assert_timeval_empty(res2.last_read_at); + tt_assert_timeval_empty(res2.last_wrote_at); + tt_assert_timeval_empty(res2.last_wrote_at); +#undef tt_assert_timeval_empty + end: if (bev1) bufferevent_free(bev1); @@ -1363,7 +1362,7 @@ struct testcase_t bufferevent_testcases[] = { { "bufferevent_connect_fail", test_bufferevent_connect_fail, TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, { "bufferevent_timeout", test_bufferevent_timeouts, - TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR, &basic_setup, (void*)"" }, + TT_FORK|TT_NEED_BASE, &basic_setup, (void*)"" }, { "bufferevent_timeout_pair", test_bufferevent_timeouts, TT_FORK|TT_NEED_BASE, &basic_setup, (void*)"pair" }, { "bufferevent_timeout_filter", test_bufferevent_timeouts, -- cgit v1.2.1 From dd472e7d71b7d0bf5d1e4025ce1123248c531849 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 22 Oct 2018 01:00:54 +0300 Subject: Use matrix.fast_finish for the travis-ci to mark the build ASAP AFAIR there is shortage of osx workers on travis-ci, IOW builds that requires them can wait fair amount of time in the queue by just waiting. Plus linux workers AFAICS can run multiple jobs in parallel (4-5), while osx does not. Hence if we do allow failures for osx (and right now they have a lot of failed tests) let's mark build result based on tests under linux only. So in a nut shell this will reduce build time from 5 hours to 20-30 minutes. (cherry picked from commit 5d3e8c15e7482c35ae7c9768f6f61a5e6850c035) --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 581b5b1d..80abefc7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,6 +27,7 @@ matrix: env: EVENT_BUILD_METHOD=cmake EVENT_CMAKE_OPTIONS="-DEVENT__COVERAGE=ON -DCMAKE_BUILD_TYPE=debug" COVERALLS=yes allow_failures: - os: osx + fast_finish: true language: c compiler: -- cgit v1.2.1 From 698ebed67a9d37aa9d8ec475023ce854bcd3a33b Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 22 Oct 2018 01:06:48 +0300 Subject: Disable parallel jobs for the osx (due to CPU time deficit) in travis-ci As you can see right now linux workers has zero failed tests, while osx workers has 18 failed tests: [bufferevent_connect_hostname_emfile FAILED] [bufferevent_pair_release_lock FAILED] [bufferevent_timeout FAILED] [bufferevent_timeout_filter FAILED] [bufferevent_timeout_pair FAILED] [common_timeout FAILED] [del_wait FAILED] [immediatesignal FAILED] [loopexit FAILED] [loopexit_multiple FAILED] [monotonic_res FAILED] [no_events FAILED] [persistent_active_timeout FAILED] [persistent_timeout_jump FAILED] [signal_switchbase FAILED] [signal_while_processing FAILED] [simpletimeout FAILED] [usleep FAILED] And this patch should remove from this list time related failures (though maybe not all of them). (cherry picked from commit 2f43d1d4091f4f87b8679de4b4967561861141de) --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 80abefc7..e8c46230 100644 --- a/.travis.yml +++ b/.travis.yml @@ -57,7 +57,7 @@ before_install: CFLAGS=-I$CMAKE_INCLUDE_PATH LDFLAGS=-L$CMAKE_LIBRARY_PATH; - export JOBS=4; + export JOBS=1; fi addons: -- cgit v1.2.1 From cdcfbafe4024b8e1822cba8ad7726630dedc48cb Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 23 Oct 2018 00:12:23 +0300 Subject: Merge branch 'http-request-line-parsing' * http-request-line-parsing: Fix http https_basic/https_filter_basic under valgrind (increase timeout) http: cover various non RFC3986 conformant URIs http: allow non RFC3986 conformant during parsing request-line (http server) http: do not try to parse request-line if we do not have enough bytes http: allow trailing spaces (and only them) in request-line (like nginx) http: cleanup of the request-line parsing (cherry picked from commit 0ec12bc84cf09307e01dc3b00d08ac1f816b6ff7) --- http.c | 50 +++++++++++++++++++++++++++++--------------------- test/regress_http.c | 53 +++++++++++++++++++++++++++++++---------------------- 2 files changed, 60 insertions(+), 43 deletions(-) diff --git a/http.c b/http.c index c22f953c..f7c6490f 100644 --- a/http.c +++ b/http.c @@ -1686,8 +1686,9 @@ evhttp_parse_response_line(struct evhttp_request *req, char *line) /* Parse the first line of a HTTP request */ static int -evhttp_parse_request_line(struct evhttp_request *req, char *line) +evhttp_parse_request_line(struct evhttp_request *req, char *line, size_t len) { + char *eos = line + len; char *method; char *uri; char *version; @@ -1696,16 +1697,24 @@ evhttp_parse_request_line(struct evhttp_request *req, char *line) size_t method_len; enum evhttp_cmd_type type; + while (eos > line && *(eos-1) == ' ') { + *(eos-1) = '\0'; + --eos; + --len; + } + if (len < strlen("GET / HTTP/1.0")) + return -1; + /* Parse the request line */ method = strsep(&line, " "); - if (line == NULL) - return (-1); - uri = strsep(&line, " "); - if (line == NULL) - return (-1); - version = strsep(&line, " "); - if (line != NULL) - return (-1); + if (!line) + return -1; + uri = line; + version = strrchr(uri, ' '); + if (!version || uri == version) + return -1; + *version = '\0'; + version++; method_len = (uri - method) - 1; type = EVHTTP_REQ_UNKNOWN_; @@ -1825,11 +1834,11 @@ evhttp_parse_request_line(struct evhttp_request *req, char *line) req->type = type; if (evhttp_parse_http_version(version, req) < 0) - return (-1); + return -1; if ((req->uri = mm_strdup(uri)) == NULL) { event_debug(("%s: mm_strdup", __func__)); - return (-1); + return -1; } if (type == EVHTTP_REQ_CONNECT) { @@ -1854,7 +1863,7 @@ evhttp_parse_request_line(struct evhttp_request *req, char *line) !evhttp_find_vhost(req->evcon->http_server, NULL, hostname)) req->flags |= EVHTTP_PROXY_REQUEST; - return (0); + return 0; } const char * @@ -1989,9 +1998,9 @@ evhttp_parse_firstline_(struct evhttp_request *req, struct evbuffer *buffer) char *line; enum message_read_status status = ALL_DATA_READ; - size_t line_length; + size_t len; /* XXX try */ - line = evbuffer_readln(buffer, &line_length, EVBUFFER_EOL_CRLF); + line = evbuffer_readln(buffer, &len, EVBUFFER_EOL_CRLF); if (line == NULL) { if (req->evcon != NULL && evbuffer_get_length(buffer) > req->evcon->max_headers_size) @@ -2000,17 +2009,16 @@ evhttp_parse_firstline_(struct evhttp_request *req, struct evbuffer *buffer) return (MORE_DATA_EXPECTED); } - if (req->evcon != NULL && - line_length > req->evcon->max_headers_size) { + if (req->evcon != NULL && len > req->evcon->max_headers_size) { mm_free(line); return (DATA_TOO_LONG); } - req->headers_size = line_length; + req->headers_size = len; switch (req->kind) { case EVHTTP_REQUEST: - if (evhttp_parse_request_line(req, line) == -1) + if (evhttp_parse_request_line(req, line, len) == -1) status = DATA_CORRUPTED; break; case EVHTTP_RESPONSE: @@ -2063,12 +2071,12 @@ evhttp_parse_headers_(struct evhttp_request *req, struct evbuffer* buffer) enum message_read_status status = MORE_DATA_EXPECTED; struct evkeyvalq* headers = req->input_headers; - size_t line_length; - while ((line = evbuffer_readln(buffer, &line_length, EVBUFFER_EOL_CRLF)) + size_t len; + while ((line = evbuffer_readln(buffer, &len, EVBUFFER_EOL_CRLF)) != NULL) { char *skey, *svalue; - req->headers_size += line_length; + req->headers_size += len; if (req->evcon != NULL && req->headers_size > req->evcon->max_headers_size) { diff --git a/test/regress_http.c b/test/regress_http.c index e3312091..5203bcd4 100644 --- a/test/regress_http.c +++ b/test/regress_http.c @@ -150,6 +150,7 @@ http_setup_gencb(ev_uint16_t *pport, struct event_base *base, int mask, /* Register a callback for certain types of requests */ evhttp_set_cb(myhttp, "/test", http_basic_cb, myhttp); + evhttp_set_cb(myhttp, "/test nonconformant", http_basic_cb, myhttp); evhttp_set_cb(myhttp, "/timeout", http_timeout_cb, myhttp); evhttp_set_cb(myhttp, "/large", http_large_cb, base); evhttp_set_cb(myhttp, "/chunked", http_chunked_cb, base); @@ -493,7 +494,7 @@ create_bev(struct event_base *base, int fd, int ssl_mask) } static void -http_basic_test_impl(void *arg, int ssl) +http_basic_test_impl(void *arg, int ssl, const char *request_line) { struct basic_test_data *data = arg; struct timeval tv; @@ -503,6 +504,7 @@ http_basic_test_impl(void *arg, int ssl) ev_uint16_t port = 0, port2 = 0; int server_flags = ssl ? HTTP_BIND_SSL : 0; struct evhttp *http = http_setup(&port, data->base, server_flags); + struct evbuffer *out; exit_base = data->base; test_ok = 0; @@ -519,21 +521,23 @@ http_basic_test_impl(void *arg, int ssl) bev = create_bev(data->base, fd, ssl); bufferevent_setcb(bev, http_readcb, http_writecb, http_errorcb, data->base); + out = bufferevent_get_output(bev); /* first half of the http request */ - http_request = - "GET /test HTTP/1.1\r\n" - "Host: some"; + evbuffer_add_printf(out, + "%s\r\n" + "Host: some", request_line); - bufferevent_write(bev, http_request, strlen(http_request)); evutil_timerclear(&tv); tv.tv_usec = 100000; + if (ssl) + tv.tv_usec *= 10; event_base_once(data->base, -1, EV_TIMEOUT, http_complete_write, bev, &tv); event_base_dispatch(data->base); - tt_assert(test_ok == 3); + tt_int_op(test_ok, ==, 3); /* connect to the second port */ bufferevent_free(bev); @@ -545,18 +549,17 @@ http_basic_test_impl(void *arg, int ssl) bev = create_bev(data->base, fd, ssl); bufferevent_setcb(bev, http_readcb, http_writecb, http_errorcb, data->base); + out = bufferevent_get_output(bev); - http_request = - "GET /test HTTP/1.1\r\n" + evbuffer_add_printf(out, + "%s\r\n" "Host: somehost\r\n" "Connection: close\r\n" - "\r\n"; - - bufferevent_write(bev, http_request, strlen(http_request)); + "\r\n", request_line); event_base_dispatch(data->base); - tt_assert(test_ok == 5); + tt_int_op(test_ok, ==, 5); /* Connect to the second port again. This time, send an absolute uri. */ bufferevent_free(bev); @@ -579,14 +582,17 @@ http_basic_test_impl(void *arg, int ssl) event_base_dispatch(data->base); - tt_assert(test_ok == 7); + tt_int_op(test_ok, ==, 7); evhttp_free(http); end: if (bev) bufferevent_free(bev); } -static void http_basic_test(void *arg) { http_basic_test_impl(arg, 0); } +static void http_basic_test(void *arg)\ +{ http_basic_test_impl(arg, 0, "GET /test HTTP/1.1"); } +static void http_basic_trailing_space_test(void *arg) +{ http_basic_test_impl(arg, 0, "GET /test HTTP/1.1 "); } static void @@ -3642,7 +3648,7 @@ http_make_web_server(evutil_socket_t fd, short what, void *arg) } static void -http_simple_test_impl(void *arg, int ssl, int dirty) +http_simple_test_impl(void *arg, int ssl, int dirty, const char *uri) { struct basic_test_data *data = arg; struct evhttp_connection *evcon = NULL; @@ -3667,9 +3673,8 @@ http_simple_test_impl(void *arg, int ssl, int dirty) req = evhttp_request_new(http_request_done, (void*) BASIC_REQUEST_BODY); tt_assert(req); - if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") == -1) { + if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, uri) == -1) tt_abort_msg("Couldn't make request"); - } event_base_dispatch(data->base); tt_int_op(test_ok, ==, 1); @@ -3681,7 +3686,9 @@ http_simple_test_impl(void *arg, int ssl, int dirty) evhttp_free(http); } static void http_simple_test(void *arg) -{ http_simple_test_impl(arg, 0, 0); } +{ http_simple_test_impl(arg, 0, 0, "/test"); } +static void http_simple_nonconformant_test(void *arg) +{ http_simple_test_impl(arg, 0, 0, "/test nonconformant"); } static void http_connection_retry_test_basic(void *arg, const char *addr, struct evdns_base *dns_base, int ssl) @@ -4638,17 +4645,17 @@ http_request_extra_body_test(void *arg) #ifdef EVENT__HAVE_OPENSSL static void https_basic_test(void *arg) -{ http_basic_test_impl(arg, 1); } +{ http_basic_test_impl(arg, 1, "GET /test HTTP/1.1"); } static void https_filter_basic_test(void *arg) -{ http_basic_test_impl(arg, 1 | HTTP_SSL_FILTER); } +{ http_basic_test_impl(arg, 1 | HTTP_SSL_FILTER, "GET /test HTTP/1.1"); } static void https_incomplete_test(void *arg) { http_incomplete_test_(arg, 0, 1); } static void https_incomplete_timeout_test(void *arg) { http_incomplete_test_(arg, 1, 1); } static void https_simple_test(void *arg) -{ http_simple_test_impl(arg, 1, 0); } +{ http_simple_test_impl(arg, 1, 0, "/test"); } static void https_simple_dirty_test(void *arg) -{ http_simple_test_impl(arg, 1, 1); } +{ http_simple_test_impl(arg, 1, 1, "/test"); } static void https_connection_retry_conn_address_test(void *arg) { http_connection_retry_conn_address_test_impl(arg, 1); } static void https_connection_retry_test(void *arg) @@ -4678,7 +4685,9 @@ struct testcase_t http_testcases[] = { { "parse_uri_nc", http_parse_uri_test, 0, &basic_setup, (void*)"nc" }, { "uriencode", http_uriencode_test, 0, NULL, NULL }, HTTP(basic), + HTTP(basic_trailing_space), HTTP(simple), + HTTP(simple_nonconformant), HTTP_N(cancel, cancel, BASIC), HTTP_N(cancel_by_host, cancel, BY_HOST), -- cgit v1.2.1 From b07e43e607f34d8a1592a03172941bc4d9b429b7 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Thu, 25 Oct 2018 00:50:50 +0300 Subject: Merge branch 'evutil_found_ifaddr-dev' * evutil_found_ifaddr-dev: Cover evutil_v4addr_is_local_()/evutil_v6addr_is_local_() Split evutil_found_ifaddr() into helpers (evutil_v{4,6}addr_is_local()) Use INADDR_ANY over 0 in evutil_found_ifaddr() Replace EVUTIL_V4ADDR_IS_*() macroses with static inline functions Filter link-local IPv4 addresses in evutil_found_ifaddr() (cherry picked from commit b2667b76969c2ea382373f885062b45e82d0ac59) --- evutil.c | 64 +++++++++++++++++++++++++------------------ test/regress_util.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++ util-internal.h | 11 ++++++++ 3 files changed, 128 insertions(+), 26 deletions(-) diff --git a/evutil.c b/evutil.c index 49c9014f..d93eff5f 100644 --- a/evutil.c +++ b/evutil.c @@ -595,44 +595,56 @@ evutil_socket_finished_connecting_(evutil_socket_t fd) set by evutil_check_interfaces. */ static int have_checked_interfaces, had_ipv4_address, had_ipv6_address; -/* Macro: True iff the IPv4 address 'addr', in host order, is in 127.0.0.0/8 - */ -#define EVUTIL_V4ADDR_IS_LOCALHOST(addr) (((addr)>>24) == 127) +/* True iff the IPv4 address 'addr', in host order, is in 127.0.0.0/8 */ +static inline int evutil_v4addr_is_localhost(ev_uint32_t addr) +{ return addr>>24 == 127; } -/* Macro: True iff the IPv4 address 'addr', in host order, is a class D - * (multiclass) address. - */ -#define EVUTIL_V4ADDR_IS_CLASSD(addr) ((((addr)>>24) & 0xf0) == 0xe0) +/* True iff the IPv4 address 'addr', in host order, is link-local + * 169.254.0.0/16 (RFC3927) */ +static inline int evutil_v4addr_is_linklocal(ev_uint32_t addr) +{ return ((addr & 0xffff0000U) == 0xa9fe0000U); } + +/* True iff the IPv4 address 'addr', in host order, is a class D + * (multiclass) address. */ +static inline int evutil_v4addr_is_classd(ev_uint32_t addr) +{ return ((addr>>24) & 0xf0) == 0xe0; } + +int +evutil_v4addr_is_local_(const struct in_addr *in) +{ + const ev_uint32_t addr = ntohl(in->s_addr); + return addr == INADDR_ANY || + evutil_v4addr_is_localhost(addr) || + evutil_v4addr_is_linklocal(addr) || + evutil_v4addr_is_classd(addr); +} +int +evutil_v6addr_is_local_(const struct in6_addr *in) +{ + static const char ZEROES[] = + "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00"; + + const unsigned char *addr = (const unsigned char *)in->s6_addr; + return !memcmp(addr, ZEROES, 8) || + ((addr[0] & 0xfe) == 0xfc) || + (addr[0] == 0xfe && (addr[1] & 0xc0) == 0x80) || + (addr[0] == 0xfe && (addr[1] & 0xc0) == 0xc0) || + (addr[0] == 0xff); +} static void evutil_found_ifaddr(const struct sockaddr *sa) { - const char ZEROES[] = "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00"; - if (sa->sa_family == AF_INET) { const struct sockaddr_in *sin = (struct sockaddr_in *)sa; - ev_uint32_t addr = ntohl(sin->sin_addr.s_addr); - if (addr == 0 || - EVUTIL_V4ADDR_IS_LOCALHOST(addr) || - EVUTIL_V4ADDR_IS_CLASSD(addr)) { - /* Not actually a usable external address. */ - } else { + if (!evutil_v4addr_is_local_(&sin->sin_addr)) { event_debug(("Detected an IPv4 interface")); had_ipv4_address = 1; } } else if (sa->sa_family == AF_INET6) { const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; - const unsigned char *addr = - (unsigned char*)sin6->sin6_addr.s6_addr; - if (!memcmp(addr, ZEROES, 8) || - ((addr[0] & 0xfe) == 0xfc) || - (addr[0] == 0xfe && (addr[1] & 0xc0) == 0x80) || - (addr[0] == 0xfe && (addr[1] & 0xc0) == 0xc0) || - (addr[0] == 0xff)) { - /* This is a reserved, ipv4compat, ipv4map, loopback, - * link-local, multicast, or unspecified address. */ - } else { + if (!evutil_v6addr_is_local_(&sin6->sin6_addr)) { event_debug(("Detected an IPv6 interface")); had_ipv6_address = 1; } diff --git a/test/regress_util.c b/test/regress_util.c index 68281e61..320047fa 100644 --- a/test/regress_util.c +++ b/test/regress_util.c @@ -1455,6 +1455,83 @@ end: ; } +static void +test_evutil_v4addr_is_local(void *arg) +{ + struct sockaddr_in sin; + sin.sin_family = AF_INET; + + /* we use evutil_inet_pton() here to fill in network-byte order */ +#define LOCAL(str, yes) do { \ + tt_int_op(evutil_inet_pton(AF_INET, str, &sin.sin_addr), ==, 1); \ + tt_int_op(evutil_v4addr_is_local_(&sin.sin_addr), ==, yes); \ +} while (0) + + /** any */ + sin.sin_addr.s_addr = INADDR_ANY; + tt_int_op(evutil_v4addr_is_local_(&sin.sin_addr), ==, 1); + + /** loopback */ + sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + tt_int_op(evutil_v4addr_is_local_(&sin.sin_addr), ==, 1); + LOCAL("127.0.0.1", 1); + LOCAL("127.255.255.255", 1); + LOCAL("121.0.0.1", 0); + + /** link-local */ + LOCAL("169.254.0.1", 1); + LOCAL("169.254.255.255", 1); + LOCAL("170.0.0.0", 0); + + /** Multicast */ + LOCAL("224.0.0.0", 1); + LOCAL("239.255.255.255", 1); + LOCAL("240.0.0.0", 0); +end: + ; +} + +static void +test_evutil_v6addr_is_local(void *arg) +{ + struct sockaddr_in6 sin6; + struct in6_addr anyaddr = IN6ADDR_ANY_INIT; + struct in6_addr loopback = IN6ADDR_LOOPBACK_INIT; + + sin6.sin6_family = AF_INET6; +#define LOCAL6(str, yes) do { \ + tt_int_op(evutil_inet_pton(AF_INET6, str, &sin6.sin6_addr), ==, 1);\ + tt_int_op(evutil_v6addr_is_local_(&sin6.sin6_addr), ==, yes); \ +} while (0) + + /** any */ + tt_int_op(evutil_v6addr_is_local_(&anyaddr), ==, 1); + LOCAL6("::0", 1); + + /** loopback */ + tt_int_op(evutil_v6addr_is_local_(&loopback), ==, 1); + LOCAL6("::1", 1); + + /** IPV4 mapped */ + LOCAL6("::ffff:0:0", 1); + /** IPv4 translated */ + LOCAL6("::ffff:0:0:0", 1); + /** IPv4/IPv6 translation */ + LOCAL6("64:ff9b::", 0); + /** Link-local */ + LOCAL6("fe80::", 1); + /** Multicast */ + LOCAL6("ff00::", 1); + /** Unspecified */ + LOCAL6("::", 1); + + /** Global Internet */ + LOCAL6("2001::", 0); + LOCAL6("2001:4860:4802:32::1b", 0); +end: + ; +} + struct testcase_t util_testcases[] = { { "ipv4_parse", regress_ipv4_parse, 0, NULL, NULL }, { "ipv6_parse", regress_ipv6_parse, 0, NULL, NULL }, @@ -1486,6 +1563,8 @@ struct testcase_t util_testcases[] = { { "monotonic_prc_precise", test_evutil_monotonic_prc, 0, &basic_setup, (void*)"precise" }, { "monotonic_prc_fallback", test_evutil_monotonic_prc, 0, &basic_setup, (void*)"fallback" }, { "date_rfc1123", test_evutil_date_rfc1123, 0, NULL, NULL }, + { "evutil_v4addr_is_local", test_evutil_v4addr_is_local, 0, NULL, NULL }, + { "evutil_v6addr_is_local", test_evutil_v6addr_is_local, 0, NULL, NULL }, END_OF_TESTCASES, }; diff --git a/util-internal.h b/util-internal.h index fe416409..b727bf1f 100644 --- a/util-internal.h +++ b/util-internal.h @@ -527,6 +527,17 @@ evutil_socket_t evutil_eventfd_(unsigned initval, int flags); void evutil_memclear_(void *mem, size_t len); +struct in_addr; +struct in6_addr; + +/* This is a any, loopback, link-local, multicast */ +EVENT2_EXPORT_SYMBOL +int evutil_v4addr_is_local_(const struct in_addr *in); +/* This is a reserved, ipv4compat, ipv4map, loopback, + * link-local, multicast, or unspecified address. */ +EVENT2_EXPORT_SYMBOL +int evutil_v6addr_is_local_(const struct in6_addr *in); + #ifdef __cplusplus } #endif -- cgit v1.2.1 From ba14879661ed3499013f85a3df3fe6be02ae52d1 Mon Sep 17 00:00:00 2001 From: Murat Demirten Date: Mon, 4 Jun 2018 16:43:34 +0300 Subject: listener: ipv6only socket bind support According to RFC3493 and most Linux distributions, default value is to work in IPv4-mapped mode. If there is a requirement to bind same port on same ip addresses but different handlers for both IPv4 and IPv6, it is required to set IPV6_V6ONLY socket option to be sure that the code works as expected without affected by bindv6only sysctl setting in system. See an example working with this patch: https://gist.github.com/demirten/023008a63cd966e48b0ebcf9af7fc113 Closes: #640 (cherry-pick) (cherry picked from commit 387d91f9ab95df8ac3d7bb58493310ad4a377dcf) --- evutil.c | 8 ++++++++ include/event2/listener.h | 12 ++++++++++++ include/event2/util.h | 12 ++++++++++++ listener.c | 5 +++++ 4 files changed, 37 insertions(+) diff --git a/evutil.c b/evutil.c index d93eff5f..5d385bdc 100644 --- a/evutil.c +++ b/evutil.c @@ -385,6 +385,14 @@ evutil_make_listen_socket_reuseable_port(evutil_socket_t sock) #endif } +int +evutil_make_listen_socket_ipv6only(evutil_socket_t sock) +{ + int one = 1; + return setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (void*) &one, + (ev_socklen_t)sizeof(one)); +} + int evutil_make_tcp_listen_socket_deferred(evutil_socket_t sock) { diff --git a/include/event2/listener.h b/include/event2/listener.h index 84b4da05..789a27c2 100644 --- a/include/event2/listener.h +++ b/include/event2/listener.h @@ -97,6 +97,18 @@ typedef void (*evconnlistener_errorcb)(struct evconnlistener *, void *); * This is only available on Linux and kernel 3.9+ */ #define LEV_OPT_REUSEABLE_PORT (1u<<7) +/** Flag: Indicates that the listener wants to work only in IPv6 socket. + * + * According to RFC3493 and most Linux distributions, default value is to + * work in IPv4-mapped mode. If there is a requirement to bind same port + * on same ip addresses but different handlers for both IPv4 and IPv6, + * it is required to set IPV6_V6ONLY socket option to be sure that the + * code works as expected without affected by bindv6only sysctl setting in + * system. + * + * This socket option also supported by Windows. + */ +#define LEV_OPT_BIND_IPV6ONLY (1u<<8) /** Allocate a new evconnlistener object to listen for incoming TCP connections diff --git a/include/event2/util.h b/include/event2/util.h index 70aabb66..c0f5f80b 100644 --- a/include/event2/util.h +++ b/include/event2/util.h @@ -426,6 +426,18 @@ int evutil_make_listen_socket_reuseable(evutil_socket_t sock); EVENT2_EXPORT_SYMBOL int evutil_make_listen_socket_reuseable_port(evutil_socket_t sock); +/** Set ipv6 only bind socket option to make listener work only in ipv6 sockets. + + According to RFC3493 and most Linux distributions, default value for the + sockets is to work in IPv4-mapped mode. In IPv4-mapped mode, it is not possible + to bind same port from different IPv4 and IPv6 handlers. + + @param sock The socket to make in ipv6only working mode + @return 0 on success, -1 on failure + */ +EVENT2_EXPORT_SYMBOL +int evutil_make_listen_socket_ipv6only(evutil_socket_t sock); + /** Do platform-specific operations as needed to close a socket upon a successful execution of one of the exec*() functions. diff --git a/listener.c b/listener.c index 2835df17..e803bed1 100644 --- a/listener.c +++ b/listener.c @@ -245,6 +245,11 @@ evconnlistener_new_bind(struct event_base *base, evconnlistener_cb cb, goto err; } + if (flags & LEV_OPT_BIND_IPV6ONLY) { + if (evutil_make_listen_socket_ipv6only(fd) < 0) + goto err; + } + if (sa) { if (bind(fd, sa, socklen)<0) goto err; -- cgit v1.2.1 From bff1423d7964b0af698c733d10bc13a937051dc8 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sat, 27 Oct 2018 16:49:39 +0300 Subject: autotools: do not add warnings that is included into -Wall already Plus remove duplicates (cherry picked from commit 006c528a21f8beec8993134c12610bd16cde7fff) --- configure.ac | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index fe4b7325..ea34555e 100644 --- a/configure.ac +++ b/configure.ac @@ -823,7 +823,8 @@ if test x$enable_gcc_warnings != xno && test "$GCC" = "yes"; then #error #endif])], have_clang=yes, have_clang=no) - CFLAGS="$CFLAGS -W -Wfloat-equal -Wundef -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes -Wwrite-strings -Wredundant-decls -Wchar-subscripts -Wcomment -Wformat -Wwrite-strings -Wmissing-declarations -Wredundant-decls -Wnested-externs -Wbad-function-cast -Wswitch" + # -W is the same as -Wextra + CFLAGS="$CFLAGS -W -Wfloat-equal -Wundef -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes -Wwrite-strings -Wredundant-decls -Wmissing-declarations -Wredundant-decls -Wnested-externs -Wbad-function-cast" if test x$enable_gcc_warnings = xyes; then CFLAGS="$CFLAGS -Werror" fi -- cgit v1.2.1 From acf4821d7c7b0cae397be15a201c0d32911e55a6 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sat, 27 Oct 2018 14:58:30 +0300 Subject: cmake: add various warning flags like autotools has This is mostly to match autotools and reduce amount mixiing declarations and code. Added: - -Wextra (the same as -W), -Wno-unused-parameter -Wstrict-aliasing - -fno-strict-aliasing (gcc 2.9.5+) - -Winit-self -Wmissing-field-initializers -Wdeclaration-after-statement (4.0+) - -Waddress -Wno-unused-function -Wnormalized=id -Woverride-init (4.2+) - -Wlogical-op (4.5+) Removed: - -Wformat (include in -Wall) Plus use CMAKE_C_COMPILER_ID over CMAKE_COMPILER_IS_GNUCC, as cmake-variables(7) suggesting, and add common GNUC/CLANG variables. v2: drop checks for flags, since add_compiler_flags() will check if such flags exists anyway (but just to note, gcc ignores non existing warning flags by default). (cherry picked from commit 8348b41308a7126d009bb6e0b33aa5f465e1dc33) --- CMakeLists.txt | 84 +++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 54 insertions(+), 30 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7999699b..48885a32 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -171,14 +171,44 @@ if (EVENT__COVERAGE) set(CMAKE_REQUIRED_LIBRARIES "") endif() -# GCC specific options. -if (CMAKE_COMPILER_IS_GNUCC) +set(GNUC 0) +set(CLANG 0) +if (("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") OR + ("${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang")) + set(CLANG 1) +endif() +if ((${CMAKE_C_COMPILER_ID} STREQUAL GNU) OR (${CLANG})) + set(GNUC 1) +endif() + +# GNUC specific options. +if (${GNUC}) option(EVENT__DISABLE_GCC_WARNINGS "Disable verbose warnings with GCC" OFF) option(EVENT__ENABLE_GCC_HARDENING "Enable compiler security checks" OFF) option(EVENT__ENABLE_GCC_FUNCTION_SECTIONS "Enable gcc function sections" OFF) option(EVENT__ENABLE_GCC_WARNINGS "Make all GCC warnings into errors" OFF) - list(APPEND __FLAGS -Wall -Wswitch) + set(GCC_V ${CMAKE_C_COMPILER_VERSION}) + + list(APPEND __FLAGS + -Wall -Wextra -Wno-unused-parameter -Wstrict-aliasing + + -fno-strict-aliasing # gcc 2.9.5+ + + # gcc 4 + -Winit-self + -Wmissing-field-initializers + -Wdeclaration-after-statement + + # gcc 4.2 + -Waddress + -Wno-unused-function + -Wnormalized=id + -Woverride-init + + # gcc 4.5 + -Wlogical-op + ) if (EVENT__DISABLE_GCC_WARNINGS) list(APPEND __FLAGS -w) @@ -204,10 +234,6 @@ if (CMAKE_COMPILER_IS_GNUCC) list(APPEND __FLAGS -Werror) endif() - # We need to test for at least gcc 2.95 here, because older versions don't - # have -fno-strict-aliasing - list(APPEND __FLAGS -fno-strict-aliasing) - add_compiler_flags(${__FLAGS}) endif() @@ -782,9 +808,7 @@ source_group("Source Extra" FILES ${SRC_EXTRA}) # (Place them in the build dir so we don't polute the source tree with generated files). include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}/include) -if ((CMAKE_COMPILER_IS_GNUCC) OR - ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") OR - ("${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang")) +if (${GNUC}) set(EVENT_SHARED_FLAGS -fvisibility=hidden) elseif ("${CMAKE_C_COMPILER_ID}" STREQUAL "SunPro") set(EVENT_SHARED_FLAGS -xldscope=hidden) @@ -1363,25 +1387,25 @@ message(STATUS "") message(STATUS " ---( Libevent " ${EVENT_VERSION} " )---") message(STATUS "") message(STATUS "Available event backends: ${BACKENDS}") -message(STATUS "CMAKE_BINARY_DIR: " ${CMAKE_BINARY_DIR}) -message(STATUS "CMAKE_CURRENT_BINARY_DIR: " ${CMAKE_CURRENT_BINARY_DIR}) -message(STATUS "CMAKE_SOURCE_DIR: " ${CMAKE_SOURCE_DIR}) -message(STATUS "CMAKE_CURRENT_SOURCE_DIR: " ${CMAKE_CURRENT_SOURCE_DIR}) -message(STATUS "PROJECT_BINARY_DIR: " ${PROJECT_BINARY_DIR}) -message(STATUS "PROJECT_SOURCE_DIR: " ${PROJECT_SOURCE_DIR}) -message(STATUS "CMAKE_MODULE_PATH: " ${CMAKE_MODULE_PATH}) -message(STATUS "CMAKE_COMMAND: " ${CMAKE_COMMAND}) -message(STATUS "CMAKE_ROOT: " ${CMAKE_ROOT} ) -message(STATUS "CMAKE_SYSTEM: " ${CMAKE_SYSTEM} ) -message(STATUS "CMAKE_SYSTEM_NAME: " ${CMAKE_SYSTEM_NAME} ) -message(STATUS "CMAKE_SYSTEM_VERSION: " ${CMAKE_SYSTEM_VERSION} ) -message(STATUS "CMAKE_SYSTEM_PROCESSOR: " ${CMAKE_SYSTEM_PROCESSOR} ) -message(STATUS "CMAKE_SKIP_RPATH: " ${CMAKE_SKIP_RPATH} ) -message(STATUS "CMAKE_VERBOSE_MAKEFILE: " ${CMAKE_VERBOSE_MAKEFILE} ) -message(STATUS "CMAKE_C_FLAGS: " ${CMAKE_C_FLAGS} ) -message(STATUS "CMAKE_BUILD_TYPE: " ${CMAKE_BUILD_TYPE} ) -message(STATUS "CMAKE_C_COMPILER: " ${CMAKE_C_COMPILER} ) -message(STATUS "CMAKE_AR: " ${CMAKE_AR} ) -message(STATUS "CMAKE_RANLIB: " ${CMAKE_RANLIB} ) +message(STATUS "CMAKE_BINARY_DIR: ${CMAKE_BINARY_DIR}") +message(STATUS "CMAKE_CURRENT_BINARY_DIR: ${CMAKE_CURRENT_BINARY_DIR}") +message(STATUS "CMAKE_SOURCE_DIR: ${CMAKE_SOURCE_DIR}") +message(STATUS "CMAKE_CURRENT_SOURCE_DIR: ${CMAKE_CURRENT_SOURCE_DIR}") +message(STATUS "PROJECT_BINARY_DIR: ${PROJECT_BINARY_DIR}") +message(STATUS "PROJECT_SOURCE_DIR: ${PROJECT_SOURCE_DIR}") +message(STATUS "CMAKE_MODULE_PATH: ${CMAKE_MODULE_PATH}") +message(STATUS "CMAKE_COMMAND: ${CMAKE_COMMAND}") +message(STATUS "CMAKE_ROOT: ${CMAKE_ROOT}") +message(STATUS "CMAKE_SYSTEM: ${CMAKE_SYSTEM}") +message(STATUS "CMAKE_SYSTEM_NAME: ${CMAKE_SYSTEM_NAME}") +message(STATUS "CMAKE_SYSTEM_VERSION: ${CMAKE_SYSTEM_VERSION}") +message(STATUS "CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}") +message(STATUS "CMAKE_SKIP_RPATH: ${CMAKE_SKIP_RPATH}") +message(STATUS "CMAKE_VERBOSE_MAKEFILE: ${CMAKE_VERBOSE_MAKEFILE}") +message(STATUS "CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}") +message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}") +message(STATUS "CMAKE_C_COMPILER: ${CMAKE_C_COMPILER} (id ${CMAKE_C_COMPILER_ID}, clang ${CLANG}, GNUC ${GNUC})") +message(STATUS "CMAKE_AR: ${CMAKE_AR}") +message(STATUS "CMAKE_RANLIB: ${CMAKE_RANLIB}") message(STATUS "") -- cgit v1.2.1 From f3aa6a47fcb636ba102afbc72f6de884670d4554 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sat, 27 Oct 2018 17:36:09 +0300 Subject: regress_http: basic evhttp_parse_query_str() coverage (cherry picked from commit d161ec3842259f2896fc9b15a1e4d5a1ed178bb2) --- test/regress_http.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/test/regress_http.c b/test/regress_http.c index 5203bcd4..a27199e3 100644 --- a/test/regress_http.c +++ b/test/regress_http.c @@ -2496,6 +2496,27 @@ http_parse_query_test(void *ptr) tt_want(validate_header(&headers, "q3", "") == 0); evhttp_clear_headers(&headers); +end: + evhttp_clear_headers(&headers); +} +static void +http_parse_query_str_test(void *ptr) +{ + struct evkeyvalq headers; + int r; + + TAILQ_INIT(&headers); + + r = evhttp_parse_query_str("http://www.test.com/?q=test", &headers); + tt_assert(evhttp_find_header(&headers, "q") == NULL); + tt_int_op(r, ==, 0); + evhttp_clear_headers(&headers); + + r = evhttp_parse_query_str("q=test", &headers); + tt_want(validate_header(&headers, "q", "test") == 0); + tt_int_op(r, ==, 0); + evhttp_clear_headers(&headers); + end: evhttp_clear_headers(&headers); } @@ -4681,6 +4702,7 @@ struct testcase_t http_testcases[] = { { "base", http_base_test, TT_FORK, NULL, NULL }, { "bad_headers", http_bad_header_test, 0, NULL, NULL }, { "parse_query", http_parse_query_test, 0, NULL, NULL }, + { "parse_query_str", http_parse_query_str_test, 0, NULL, NULL }, { "parse_uri", http_parse_uri_test, 0, NULL, NULL }, { "parse_uri_nc", http_parse_uri_test, 0, &basic_setup, (void*)"nc" }, { "uriencode", http_uriencode_test, 0, NULL, NULL }, -- cgit v1.2.1 From 83275459c3dfc060f138ef7c2a05c107e644f21e Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sat, 27 Oct 2018 18:29:57 +0300 Subject: be_openssl: drop close_flag parameter of the BIO_new_bufferevent() (cherry picked from commit 474d72aeac818198737aa7cb009578c464db11ca) --- bufferevent_openssl.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/bufferevent_openssl.c b/bufferevent_openssl.c index 6915f36a..c7f736d6 100644 --- a/bufferevent_openssl.c +++ b/bufferevent_openssl.c @@ -250,7 +250,7 @@ BIO_s_bufferevent(void) /* Create a new BIO to wrap communication around a bufferevent. If close_flag * is true, the bufferevent will be freed when the BIO is closed. */ static BIO * -BIO_new_bufferevent(struct bufferevent *bufferevent, int close_flag) +BIO_new_bufferevent(struct bufferevent *bufferevent) { BIO *result; if (!bufferevent) @@ -259,7 +259,9 @@ BIO_new_bufferevent(struct bufferevent *bufferevent, int close_flag) return NULL; BIO_set_init(result, 1); BIO_set_data(result, bufferevent); - BIO_set_shutdown(result, close_flag ? 1 : 0); + /* We don't tell the BIO to close the bufferevent; we do it ourselves on + * be_openssl_destruct() */ + BIO_set_shutdown(result, 0); return result; } @@ -1303,7 +1305,7 @@ be_openssl_ctrl(struct bufferevent *bev, SSL_set_bio(bev_ssl->ssl, bio, bio); } else { BIO *bio; - if (!(bio = BIO_new_bufferevent(bev_ssl->underlying, 0))) + if (!(bio = BIO_new_bufferevent(bev_ssl->underlying))) return -1; SSL_set_bio(bev_ssl->ssl, bio, bio); } @@ -1407,13 +1409,10 @@ bufferevent_openssl_filter_new(struct event_base *base, enum bufferevent_ssl_state state, int options) { - /* We don't tell the BIO to close the bufferevent; we do it ourselves - * on be_openssl_destruct */ - int close_flag = 0; /* options & BEV_OPT_CLOSE_ON_FREE; */ BIO *bio; if (!underlying) return NULL; - if (!(bio = BIO_new_bufferevent(underlying, close_flag))) + if (!(bio = BIO_new_bufferevent(underlying))) return NULL; SSL_set_bio(ssl, bio, bio); -- cgit v1.2.1 From e86ccfe545c31ba47ba72b435af8915b3a758ac3 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sat, 27 Oct 2018 18:35:08 +0300 Subject: be_openssl: avoid leaking of SSL structure From nmathewson/Libevent#83 by @fancycode: There are a few code paths where the passed SSL object is not released in error cases, even if BEV_OPT_CLOSE_ON_FREE is passed as option while for others it is released. That way it's impossible for the caller to know it he has to free it on errors himself or not. Line numbers are from "bufferevent_openssl.c" in 911abf3: L1414 ("underlying == NULL" passed) L1416 (bio could not be created) L1446 (different fd passed) L1325 (both underlying and fd passed) L1328 (out-of-memory) L1333 ("bufferevent_init_common_" failed) In all error cases after the "bufferevent_ops_openssl" has been assigned, the option is evaluated on "bufferevent_free" (L1399) and the SSL object released (L1226). Fixes: nmathewson/Libevent#83 (cherry picked from commit acf09c00e2825420cc4ff801518e4ecfe2b31a03) --- bufferevent_openssl.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/bufferevent_openssl.c b/bufferevent_openssl.c index c7f736d6..8e2b361c 100644 --- a/bufferevent_openssl.c +++ b/bufferevent_openssl.c @@ -1348,8 +1348,9 @@ bufferevent_openssl_new_impl(struct event_base *base, struct bufferevent_private *bev_p = NULL; int tmp_options = options & ~BEV_OPT_THREADSAFE; + /* Only one can be set. */ if (underlying != NULL && fd >= 0) - return NULL; /* Only one can be set. */ + goto err; if (!(bev_ssl = mm_calloc(1, sizeof(struct bufferevent_openssl)))) goto err; @@ -1397,8 +1398,12 @@ bufferevent_openssl_new_impl(struct event_base *base, return &bev_ssl->bev.bev; err: - if (bev_ssl) + if (options & BEV_OPT_CLOSE_ON_FREE) + SSL_free(ssl); + if (bev_ssl) { + bev_ssl->ssl = NULL; bufferevent_free(&bev_ssl->bev.bev); + } return NULL; } @@ -1410,15 +1415,23 @@ bufferevent_openssl_filter_new(struct event_base *base, int options) { BIO *bio; + struct bufferevent *bev; + if (!underlying) - return NULL; + goto err; if (!(bio = BIO_new_bufferevent(underlying))) - return NULL; + goto err; SSL_set_bio(ssl, bio, bio); - return bufferevent_openssl_new_impl( + bev = bufferevent_openssl_new_impl( base, underlying, -1, ssl, state, options); + return bev; + +err: + if (options & BEV_OPT_CLOSE_ON_FREE) + SSL_free(ssl); + return NULL; } struct bufferevent * @@ -1445,9 +1458,9 @@ bufferevent_openssl_socket_new(struct event_base *base, } else { /* We specified an fd different from that of the SSL. This is probably an error on our part. Fail. */ - return NULL; + goto err; } - (void) BIO_set_close(bio, 0); + BIO_set_close(bio, 0); } else { /* The SSL isn't configured with a BIO with an fd. */ if (fd >= 0) { @@ -1461,6 +1474,11 @@ bufferevent_openssl_socket_new(struct event_base *base, return bufferevent_openssl_new_impl( base, NULL, fd, ssl, state, options); + +err: + if (options & BEV_OPT_CLOSE_ON_FREE) + SSL_free(ssl); + return NULL; } int -- cgit v1.2.1 From d76823d411c2c89f4184304d237217cc19fe8f16 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sat, 27 Oct 2018 23:58:18 +0300 Subject: travis-ci: do not notify irc.oftc.net#libevent I think that this just introduce noise that people just turns off. So very questionable let's remove it. (cherry picked from commit 5264c03f8a8ac759ef42e5dfdfb3fda0accd12f6) --- .travis.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index e8c46230..61f3cc14 100644 --- a/.travis.yml +++ b/.travis.yml @@ -105,6 +105,3 @@ after_script: --exclude build/CMakeFiles/CompilerIdC --gcov-options '\-lp'; fi - -notifications: - irc: "irc.oftc.net#libevent" -- cgit v1.2.1 From a9a5cf4de04fe325eb9297f09e8ce23a1af9c514 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sat, 27 Oct 2018 19:41:52 +0300 Subject: test: export basic_test_setup/basic_test_cleanup to extend them (cherry picked from commit 7cec9b95a3aefb85fcf75610abc8e27e284b251d) --- test/regress.h | 3 +++ test/regress_main.c | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/test/regress.h b/test/regress.h index de1aed30..3976a626 100644 --- a/test/regress.h +++ b/test/regress.h @@ -137,6 +137,9 @@ SSL_CTX *get_ssl_ctx(void); void init_ssl(void); #endif +void * basic_test_setup(const struct testcase_t *testcase); +int basic_test_cleanup(const struct testcase_t *testcase, void *ptr); + #ifdef __cplusplus } #endif diff --git a/test/regress_main.c b/test/regress_main.c index 44e29111..094ff23b 100644 --- a/test/regress_main.c +++ b/test/regress_main.c @@ -186,7 +186,7 @@ ignore_log_cb(int s, const char *msg) { } -static void * +void * basic_test_setup(const struct testcase_t *testcase) { struct event_base *base = NULL; @@ -262,7 +262,7 @@ basic_test_setup(const struct testcase_t *testcase) return data; } -static int +int basic_test_cleanup(const struct testcase_t *testcase, void *ptr) { struct basic_test_data *data = ptr; -- cgit v1.2.1 From f895e17e6e3383304681a047952e7ec64da91123 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sat, 27 Oct 2018 19:34:52 +0300 Subject: regress_ssl: reset static variables on test setup/cleanup and eliminate leaks One tricky bit is reply to the BIO_C_GET_FD command, since otherwise it will try to close(0) and accepted bev in ssl/bufferevent_connect_sleep will leak. Other seems more or less trivial. This was done to make sure that for at least generic cases does not leak (tricky cases was listed here nmathewson/Libevent#83). And this will allow run ssl/.. with --no-fork (cherry picked from commit 9fe952a0aea25474de3dbc30350b1ffa5abcd65a) --- test/regress.h | 2 +- test/regress_http.c | 2 +- test/regress_ssl.c | 187 ++++++++++++++++++++++++++++++++++------------------ 3 files changed, 125 insertions(+), 66 deletions(-) diff --git a/test/regress.h b/test/regress.h index 3976a626..b5347268 100644 --- a/test/regress.h +++ b/test/regress.h @@ -132,7 +132,7 @@ pid_t regress_fork(void); #ifdef EVENT__HAVE_OPENSSL #include EVP_PKEY *ssl_getkey(void); -X509 *ssl_getcert(void); +X509 *ssl_getcert(EVP_PKEY *key); SSL_CTX *get_ssl_ctx(void); void init_ssl(void); #endif diff --git a/test/regress_http.c b/test/regress_http.c index a27199e3..7d45d851 100644 --- a/test/regress_http.c +++ b/test/regress_http.c @@ -120,7 +120,7 @@ https_bev(struct event_base *base, void *arg) { SSL *ssl = SSL_new(get_ssl_ctx()); - SSL_use_certificate(ssl, ssl_getcert()); + SSL_use_certificate(ssl, ssl_getcert(ssl_getkey())); SSL_use_PrivateKey(ssl, ssl_getkey()); return bufferevent_openssl_socket_new( diff --git a/test/regress_ssl.c b/test/regress_ssl.c index 0eba2323..18d2ba89 100644 --- a/test/regress_ssl.c +++ b/test/regress_ssl.c @@ -118,14 +118,13 @@ end: } X509 * -ssl_getcert(void) +ssl_getcert(EVP_PKEY *key) { /* Dummy code to make a quick-and-dirty valid certificate with OpenSSL. Don't copy this code into your own program! It does a number of things in a stupid and insecure way. */ X509 *x509 = NULL; X509_NAME *name = NULL; - EVP_PKEY *key = ssl_getkey(); int nid; time_t now = time(NULL); @@ -147,6 +146,7 @@ ssl_getcert(void) X509_set_subject_name(x509, name); X509_set_issuer_name(x509, name); + X509_NAME_free(name); X509_time_adj(X509_get_notBefore(x509), 0, &now); now += 3600; @@ -157,6 +157,7 @@ ssl_getcert(void) return x509; end: X509_free(x509); + X509_NAME_free(name); return NULL; } @@ -182,6 +183,18 @@ get_ssl_ctx(void) return the_ssl_ctx; } +static int test_is_done; +static int n_connected; +static int got_close; +static int got_error; +static int got_timeout; +static int renegotiate_at = -1; +static int stop_when_connected; +static int pending_connect_events; +static struct event_base *exit_base; +static X509 *the_cert; +EVP_PKEY *the_key; + void init_ssl(void) { @@ -192,26 +205,64 @@ init_ssl(void) SSL_load_error_strings(); OpenSSL_add_all_algorithms(); if (SSLeay() != OPENSSL_VERSION_NUMBER) { - TT_DECLARE("WARN", ("Version mismatch for openssl: compiled with %lx but running with %lx", (unsigned long)OPENSSL_VERSION_NUMBER, (unsigned long) SSLeay())); + TT_DECLARE("WARN", + ("Version mismatch for openssl: compiled with %lx but running with %lx", + (unsigned long)OPENSSL_VERSION_NUMBER, (unsigned long)SSLeay())); } #endif } +static void * +ssl_test_setup(const struct testcase_t *testcase) +{ + init_ssl(); + + the_key = ssl_getkey(); + EVUTIL_ASSERT(the_key); + + the_cert = ssl_getcert(the_key); + EVUTIL_ASSERT(the_cert); + + disable_tls_11_and_12 = 0; + + return basic_test_setup(testcase); +} +static int +ssl_test_cleanup(const struct testcase_t *testcase, void *ptr) +{ + int ret = basic_test_cleanup(testcase, ptr); + if (!ret) { + return ret; + } + + test_is_done = 0; + n_connected = 0; + got_close = 0; + got_error = 0; + got_timeout = 0; + renegotiate_at = -1; + stop_when_connected = 0; + pending_connect_events = 0; + exit_base = NULL; + + X509_free(the_cert); + EVP_PKEY_free(the_key); + + SSL_CTX_free(the_ssl_ctx); + the_ssl_ctx = NULL; + + return 1; +} +const struct testcase_setup_t ssl_setup = { + ssl_test_setup, ssl_test_cleanup +}; + + /* ==================== Here's a simple test: we read a number from the input, increment it, and reply, until we get to 1001. */ -static int test_is_done = 0; -static int n_connected = 0; -static int got_close = 0; -static int got_error = 0; -static int got_timeout = 0; -static int renegotiate_at = -1; -static int stop_when_connected = 0; -static int pending_connect_events = 0; -static struct event_base *exit_base = NULL; - enum regress_openssl_type { REGRESS_OPENSSL_SOCKETPAIR = 1, @@ -255,6 +306,13 @@ end: ; } +static void +free_on_cb(struct bufferevent *bev, void *ctx) +{ + TT_BLATHER(("free_on_cb: %p", bev)); + bufferevent_free(bev); +} + static void respond_to_number(struct bufferevent *bev, void *ctx) { @@ -303,13 +361,14 @@ done_writing_cb(struct bufferevent *bev, void *ctx) static void eventcb(struct bufferevent *bev, short what, void *ctx) { + X509 *peer_cert = NULL; enum regress_openssl_type type; + type = (enum regress_openssl_type)ctx; TT_BLATHER(("Got event %d", (int)what)); if (what & BEV_EVENT_CONNECTED) { SSL *ssl; - X509 *peer_cert; ++n_connected; ssl = bufferevent_openssl_get_ssl(bev); tt_assert(ssl); @@ -357,8 +416,10 @@ eventcb(struct bufferevent *bev, short what, void *ctx) } bufferevent_free(bev); } + end: - ; + if (peer_cert) + X509_free(peer_cert); } static void @@ -398,8 +459,6 @@ regress_bufferevent_openssl(void *arg) struct bufferevent *bev1, *bev2; SSL *ssl1, *ssl2; - X509 *cert = ssl_getcert(); - EVP_PKEY *key = ssl_getkey(); int flags = BEV_OPT_DEFER_CALLBACKS; struct bufferevent *bev_ll[2] = { NULL, NULL }; evutil_socket_t *fd_pair = NULL; @@ -407,11 +466,6 @@ regress_bufferevent_openssl(void *arg) enum regress_openssl_type type; type = (enum regress_openssl_type)data->setup_data; - tt_assert(cert); - tt_assert(key); - - init_ssl(); - if (type & REGRESS_OPENSSL_RENEGOTIATE) { if (SSLeay() >= 0x10001000 && SSLeay() < 0x1000104f) { @@ -425,8 +479,8 @@ regress_bufferevent_openssl(void *arg) ssl1 = SSL_new(get_ssl_ctx()); ssl2 = SSL_new(get_ssl_ctx()); - SSL_use_certificate(ssl2, cert); - SSL_use_PrivateKey(ssl2, key); + SSL_use_certificate(ssl2, the_cert); + SSL_use_PrivateKey(ssl2, the_key); if (!(type & REGRESS_OPENSSL_OPEN)) flags |= BEV_OPT_CLOSE_ON_FREE; @@ -504,7 +558,10 @@ regress_bufferevent_openssl(void *arg) tt_int_op(got_close, ==, 0); tt_int_op(got_error, ==, 0); tt_int_op(got_timeout, ==, 1); + + bufferevent_free(bev2); } + end: return; } @@ -526,15 +583,13 @@ acceptcb(struct evconnlistener *listener, evutil_socket_t fd, type = (enum regress_openssl_type)data->setup_data; - SSL_use_certificate(ssl, ssl_getcert()); - SSL_use_PrivateKey(ssl, ssl_getkey()); + SSL_use_certificate(ssl, the_cert); + SSL_use_PrivateKey(ssl, the_key); bev = bufferevent_openssl_socket_new( - data->base, - fd, - ssl, - BUFFEREVENT_SSL_ACCEPTING, + data->base, fd, ssl, BUFFEREVENT_SSL_ACCEPTING, BEV_OPT_CLOSE_ON_FREE|BEV_OPT_DEFER_CALLBACKS); + tt_assert(bev); bufferevent_setcb(bev, respond_to_number, NULL, eventcb, (void*)(REGRESS_OPENSSL_SERVER)); @@ -550,6 +605,9 @@ acceptcb(struct evconnlistener *listener, evutil_socket_t fd, /* Only accept once, then disable ourself. */ evconnlistener_disable(listener); + +end: + ; } struct rwcount @@ -568,6 +626,7 @@ bio_rwcount_new(BIO *b) static int bio_rwcount_free(BIO *b) { + TT_BLATHER(("bio_rwcount_free: %p", b)); if (!b) return 0; if (BIO_get_shutdown(b)) { @@ -590,7 +649,6 @@ bio_rwcount_read(BIO *b, char *out, int outlen) static int bio_rwcount_write(BIO *b, const char *in, int inlen) { - struct rwcount *rw = BIO_get_data(b); ev_ssize_t ret = send(rw->fd, in, inlen, 0); ++rw->write; @@ -602,8 +660,12 @@ bio_rwcount_write(BIO *b, const char *in, int inlen) static long bio_rwcount_ctrl(BIO *b, int cmd, long num, void *ptr) { + struct rwcount *rw = BIO_get_data(b); long ret = 0; switch (cmd) { + case BIO_C_GET_FD: + ret = rw->fd; + break; case BIO_CTRL_GET_CLOSE: ret = BIO_get_shutdown(b); break; @@ -672,14 +734,11 @@ regress_bufferevent_openssl_connect(void *arg) struct sockaddr_storage ss; ev_socklen_t slen; SSL *ssl; - BIO *bio; struct rwcount rw = { -1, 0, 0 }; enum regress_openssl_type type; type = (enum regress_openssl_type)data->setup_data; - init_ssl(); - memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl(0x7f000001); @@ -703,7 +762,7 @@ regress_bufferevent_openssl_connect(void *arg) BEV_OPT_CLOSE_ON_FREE|BEV_OPT_DEFER_CALLBACKS); tt_assert(bev); - bufferevent_setcb(bev, respond_to_number, NULL, eventcb, + bufferevent_setcb(bev, respond_to_number, free_on_cb, eventcb, (void*)(REGRESS_OPENSSL_CLIENT)); tt_assert(getsockname(evconnlistener_get_fd(listener), @@ -716,6 +775,8 @@ regress_bufferevent_openssl_connect(void *arg) /* Possible only when we have fd, since be_openssl can and will overwrite * bio otherwise before */ if (type & REGRESS_OPENSSL_SLEEP) { + BIO *bio; + rw.fd = bufferevent_getfd(bev); bio = BIO_new_rwcount(0); tt_assert(bio); @@ -730,7 +791,7 @@ regress_bufferevent_openssl_connect(void *arg) tt_int_op(rw.read, <=, 100); tt_int_op(rw.write, <=, 100); end: - ; + evconnlistener_free(listener); } struct wm_context @@ -789,8 +850,8 @@ wm_acceptcb(struct evconnlistener *listener, evutil_socket_t fd, struct event_base *base = evconnlistener_get_base(listener); SSL *ssl = SSL_new(get_ssl_ctx()); - SSL_use_certificate(ssl, ssl_getcert()); - SSL_use_PrivateKey(ssl, ssl_getkey()); + SSL_use_certificate(ssl, the_cert); + SSL_use_PrivateKey(ssl, the_key); bev = bufferevent_openssl_socket_new( base, fd, ssl, BUFFEREVENT_SSL_ACCEPTING, BEV_OPT_CLOSE_ON_FREE); @@ -823,8 +884,6 @@ regress_bufferevent_openssl_wm(void *arg) size_t payload_len = 1<<10; size_t wm_high = 5<<10; - init_ssl(); - memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl(0x7f000001); @@ -899,82 +958,82 @@ end: struct testcase_t ssl_testcases[] = { #define T(a) ((void *)(a)) { "bufferevent_socketpair", regress_bufferevent_openssl, - TT_ISOLATED, &basic_setup, T(REGRESS_OPENSSL_SOCKETPAIR) }, + TT_ISOLATED, &ssl_setup, T(REGRESS_OPENSSL_SOCKETPAIR) }, { "bufferevent_socketpair_write_after_connect", regress_bufferevent_openssl, - TT_ISOLATED, &basic_setup, + TT_ISOLATED, &ssl_setup, T(REGRESS_OPENSSL_SOCKETPAIR|REGRESS_OPENSSL_CLIENT_WRITE) }, { "bufferevent_filter", regress_bufferevent_openssl, - TT_ISOLATED, &basic_setup, T(REGRESS_OPENSSL_FILTER) }, + TT_ISOLATED, &ssl_setup, T(REGRESS_OPENSSL_FILTER) }, { "bufferevent_filter_write_after_connect", regress_bufferevent_openssl, - TT_ISOLATED, &basic_setup, + TT_ISOLATED, &ssl_setup, T(REGRESS_OPENSSL_FILTER|REGRESS_OPENSSL_CLIENT_WRITE) }, { "bufferevent_renegotiate_socketpair", regress_bufferevent_openssl, - TT_ISOLATED, &basic_setup, + TT_ISOLATED, &ssl_setup, T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_RENEGOTIATE) }, { "bufferevent_renegotiate_filter", regress_bufferevent_openssl, - TT_ISOLATED, &basic_setup, + TT_ISOLATED, &ssl_setup, T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_RENEGOTIATE) }, { "bufferevent_socketpair_startopen", regress_bufferevent_openssl, - TT_ISOLATED, &basic_setup, + TT_ISOLATED, &ssl_setup, T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_OPEN) }, { "bufferevent_filter_startopen", regress_bufferevent_openssl, - TT_ISOLATED, &basic_setup, + TT_ISOLATED, &ssl_setup, T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_OPEN) }, { "bufferevent_socketpair_dirty_shutdown", regress_bufferevent_openssl, - TT_ISOLATED, &basic_setup, + TT_ISOLATED, &ssl_setup, T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_DIRTY_SHUTDOWN) }, { "bufferevent_filter_dirty_shutdown", regress_bufferevent_openssl, - TT_ISOLATED, &basic_setup, + TT_ISOLATED, &ssl_setup, T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_DIRTY_SHUTDOWN) }, { "bufferevent_renegotiate_socketpair_dirty_shutdown", regress_bufferevent_openssl, TT_ISOLATED, - &basic_setup, + &ssl_setup, T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_RENEGOTIATE | REGRESS_OPENSSL_DIRTY_SHUTDOWN) }, { "bufferevent_renegotiate_filter_dirty_shutdown", regress_bufferevent_openssl, TT_ISOLATED, - &basic_setup, + &ssl_setup, T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_RENEGOTIATE | REGRESS_OPENSSL_DIRTY_SHUTDOWN) }, { "bufferevent_socketpair_startopen_dirty_shutdown", regress_bufferevent_openssl, - TT_ISOLATED, &basic_setup, + TT_ISOLATED, &ssl_setup, T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_OPEN | REGRESS_OPENSSL_DIRTY_SHUTDOWN) }, { "bufferevent_filter_startopen_dirty_shutdown", regress_bufferevent_openssl, - TT_ISOLATED, &basic_setup, + TT_ISOLATED, &ssl_setup, T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_OPEN | REGRESS_OPENSSL_DIRTY_SHUTDOWN) }, { "bufferevent_socketpair_fd", regress_bufferevent_openssl, - TT_ISOLATED, &basic_setup, + TT_ISOLATED, &ssl_setup, T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_FD) }, { "bufferevent_socketpair_freed", regress_bufferevent_openssl, - TT_ISOLATED, &basic_setup, + TT_ISOLATED, &ssl_setup, T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_FREED) }, { "bufferevent_socketpair_freed_fd", regress_bufferevent_openssl, - TT_ISOLATED, &basic_setup, + TT_ISOLATED, &ssl_setup, T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_FREED | REGRESS_OPENSSL_FD) }, { "bufferevent_filter_freed_fd", regress_bufferevent_openssl, - TT_ISOLATED, &basic_setup, + TT_ISOLATED, &ssl_setup, T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_FREED | REGRESS_OPENSSL_FD) }, { "bufferevent_socketpair_timeout", regress_bufferevent_openssl, - TT_ISOLATED, &basic_setup, + TT_ISOLATED, &ssl_setup, T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_TIMEOUT) }, { "bufferevent_socketpair_timeout_freed_fd", regress_bufferevent_openssl, - TT_ISOLATED, &basic_setup, + TT_ISOLATED, &ssl_setup, T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_TIMEOUT | REGRESS_OPENSSL_FREED | REGRESS_OPENSSL_FD) }, { "bufferevent_connect", regress_bufferevent_openssl_connect, - TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, + TT_FORK|TT_NEED_BASE, &ssl_setup, NULL }, { "bufferevent_connect_sleep", regress_bufferevent_openssl_connect, - TT_FORK|TT_NEED_BASE, &basic_setup, T(REGRESS_OPENSSL_SLEEP) }, + TT_FORK|TT_NEED_BASE, &ssl_setup, T(REGRESS_OPENSSL_SLEEP) }, { "bufferevent_wm", regress_bufferevent_openssl_wm, - TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, + TT_FORK|TT_NEED_BASE, &ssl_setup, NULL }, { "bufferevent_wm_filter", regress_bufferevent_openssl_wm, - TT_FORK|TT_NEED_BASE, &basic_setup, T(REGRESS_OPENSSL_FILTER) }, + TT_FORK|TT_NEED_BASE, &ssl_setup, T(REGRESS_OPENSSL_FILTER) }, #undef T -- cgit v1.2.1 From a2176f2c06a01c9edf2c3232f4af47672a643450 Mon Sep 17 00:00:00 2001 From: Maya Rashish Date: Sat, 23 Sep 2017 06:57:16 +0300 Subject: Define __EXT_POSIX2 for QNX POSIX 1003.2 extension is necessary for getopt interface. Reported here [1] (not mine, I can't test) [1]: https://mail-index.netbsd.org/pkgsrc-users/2017/09/20/msg025601.html Closes: #563 (cherry-pick) (cherry picked from commit 99a3887d66885204ed8fa13405ae04b632dc8d33) --- evconfig-private.h.cmake | 5 +++++ evconfig-private.h.in | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/evconfig-private.h.cmake b/evconfig-private.h.cmake index 32f04794..1adf9c03 100644 --- a/evconfig-private.h.cmake +++ b/evconfig-private.h.cmake @@ -32,4 +32,9 @@ /* Define to 1 if you need to in order for `stat' and other things to work. */ #cmakedefine _POSIX_SOURCE 1 +/* Enable POSIX.2 extensions on QNX for getopt */ +#ifdef __QNX__ +#cmakedefine __EXT_POSIX2 1 +#endif + #endif diff --git a/evconfig-private.h.in b/evconfig-private.h.in index 7b3dfdb1..8cd64787 100644 --- a/evconfig-private.h.in +++ b/evconfig-private.h.in @@ -45,4 +45,11 @@ #undef _POSIX_SOURCE #endif +/* Enable POSIX.2 extensions on QNX for getopt */ +#ifdef __QNX__ +# ifndef __EXT_POSIX2 +# define __EXT_POSIX2 +# endif +#endif + #endif -- cgit v1.2.1 From 2ad11022fef409551f5033f05004cffd883a02d8 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 28 Oct 2018 02:00:16 +0300 Subject: bench_cascase: include getopt.h only for _WIN32 (like in other places) Fixes: #561 (cherry picked from commit fb42e0fac60d31e081cce4c19df6061bcb56df20) --- test/bench_cascade.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/bench_cascade.c b/test/bench_cascade.c index 1248835d..29a3203e 100644 --- a/test/bench_cascade.c +++ b/test/bench_cascade.c @@ -35,7 +35,8 @@ #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #include -#else +#include +#else /* _WIN32 */ #include #include #endif @@ -48,7 +49,6 @@ #include #endif #include -#include #include #include -- cgit v1.2.1 From 5e439e50d30ed80c72b74d11a478e8acc9c20c9d Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 28 Oct 2018 15:16:24 +0300 Subject: buffer: add an assert for last_with_datap to suppress static analyzer ../buffer.c:2231:6: warning: Access to field 'flags' results in a dereference of a null pointer if (CHAIN_SPACE_LEN(*firstchainp) == 0) { ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../buffer.c:130:30: note: expanded from macro 'CHAIN_SPACE_LEN' #define CHAIN_SPACE_LEN(ch) ((ch)->flags & EVBUFFER_IMMUTABLE ? \ (cherry picked from commit f83ac92da9fff789135d1e5b9050653cf7fdb517) --- buffer.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/buffer.c b/buffer.c index 8e88fdf5..25a6e528 100644 --- a/buffer.c +++ b/buffer.c @@ -2228,11 +2228,13 @@ evbuffer_read_setup_vecs_(struct evbuffer *buf, ev_ssize_t howmuch, so_far = 0; /* Let firstchain be the first chain with any space on it */ firstchainp = buf->last_with_datap; + EVUTIL_ASSERT(*firstchainp); if (CHAIN_SPACE_LEN(*firstchainp) == 0) { firstchainp = &(*firstchainp)->next; } chain = *firstchainp; + EVUTIL_ASSERT(chain); for (i = 0; i < n_vecs_avail && so_far < (size_t)howmuch; ++i) { size_t avail = (size_t) CHAIN_SPACE_LEN(chain); if (avail > (howmuch - so_far) && exact) -- cgit v1.2.1 From 12e0d88911a31159db68d01213b4ff5405f37169 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 28 Oct 2018 16:46:24 +0300 Subject: Convert evbuffer_strspn() (internal helper) to use size_t As pointed by @yankeehacker in #590: Signed to Unsigned Conversion Error - buffer.c:1623 Description: This assignment creates a type mismatch by populating an unsigned variable with a signed value. The signed integer will be implicitly cast to an unsigned integer, converting negative values into positive ones. If an attacker can control the signed value, it may be possible to trigger a buffer overflow if the value specifies the length of a memory write. Remediation: Do not rely on implicit casts between signed and unsigned values because the result can take on an unexpected value and violate weak assumptions made elsewhere in the program. Fixes: #590 (cherry picked from commit 931ec2370228e40309af51b86e10fa364a37a20e) --- buffer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/buffer.c b/buffer.c index 25a6e528..f6ff8431 100644 --- a/buffer.c +++ b/buffer.c @@ -1535,11 +1535,11 @@ evbuffer_find_eol_char(struct evbuffer_ptr *it) return (-1); } -static inline int +static inline size_t evbuffer_strspn( struct evbuffer_ptr *ptr, const char *chrset) { - int count = 0; + size_t count = 0; struct evbuffer_chain *chain = ptr->internal_.chain; size_t i = ptr->internal_.pos_in_chain; -- cgit v1.2.1 From 1c865238527f7e18fec2ce94dae31b93b2b92ce2 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 28 Oct 2018 18:11:22 +0300 Subject: Check existence of IPV6_V6ONLY in evutil_make_listen_socket_ipv6only() (mingw32) MinGW 32-bit 5.3.0 does not defines it and our appveyour [1] build reports this instantly: evutil.c: In function 'evutil_make_listen_socket_ipv6only': evutil.c:392:40: error: 'IPV6_V6ONLY' undeclared (first use in this function) return setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (void*) &one, [1]: https://www.appveyor.com/docs/windows-images-software/#mingw-msys-cygwin Another solution will be to use mingw64 which has it, but I guess we do want that #ifdef anyway. (cherry picked from commit 23e79fd764b9f36f560d470f0fb60295dd942ac2) --- evutil.c | 3 +++ include/event2/util.h | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/evutil.c b/evutil.c index 5d385bdc..402ab0d8 100644 --- a/evutil.c +++ b/evutil.c @@ -388,9 +388,12 @@ evutil_make_listen_socket_reuseable_port(evutil_socket_t sock) int evutil_make_listen_socket_ipv6only(evutil_socket_t sock) { +#if defined(IPV6_V6ONLY) int one = 1; return setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (void*) &one, (ev_socklen_t)sizeof(one)); +#endif + return 0; } int diff --git a/include/event2/util.h b/include/event2/util.h index c0f5f80b..80574c71 100644 --- a/include/event2/util.h +++ b/include/event2/util.h @@ -451,7 +451,8 @@ int evutil_make_socket_closeonexec(evutil_socket_t sock); socket() or accept(). @param sock The socket to be closed - @return 0 on success, -1 on failure + @return 0 on success (whether the operation is supported or not), + -1 on failure */ EVENT2_EXPORT_SYMBOL int evutil_closesocket(evutil_socket_t sock); -- cgit v1.2.1 From 349081e143ce9d2fb6d971aa121b922d6667b250 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 28 Oct 2018 19:48:37 +0300 Subject: Merge branch 'win32-visibility-event_debug_logging_mask_' * win32-visibility-event_debug_logging_mask_: Introduce EVENT_VISIBILITY_WANT_DLLIMPORT regress_http: use TT_BLAZER() over event_debug() Fixes: #702 (cherry picked from commit fb8666453ce8bb1d599a68636bed5db5ef4a7a57) --- include/event2/visibility.h | 3 ++- test/regress_http.c | 20 ++++++++++---------- test/regress_util.c | 4 ++++ 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/include/event2/visibility.h b/include/event2/visibility.h index 779eb68d..006bbf06 100644 --- a/include/event2/visibility.h +++ b/include/event2/visibility.h @@ -55,7 +55,8 @@ #if defined(_MSC_VER) # if defined(event_core_shared_EXPORTS) /** from core export */ # define EVENT2_CORE_EXPORT_SYMBOL __declspec(dllexport) -# elif defined(event_extra_shared_EXPORTS) /** from extra import */ +# elif defined(event_extra_shared_EXPORTS) || /** from extra import */ \ + defined(EVENT_VISIBILITY_WANT_DLLIMPORT) # define EVENT2_CORE_EXPORT_SYMBOL __declspec(dllimport) # endif #endif /* _MSC_VER */ diff --git a/test/regress_http.c b/test/regress_http.c index 7d45d851..49cbed02 100644 --- a/test/regress_http.c +++ b/test/regress_http.c @@ -316,7 +316,7 @@ http_basic_cb(struct evhttp_request *req, void *arg) struct evhttp_connection *evcon; int empty = evhttp_find_header(evhttp_request_get_input_headers(req), "Empty") != NULL; - event_debug(("%s: called\n", __func__)); + TT_BLATHER(("%s: called\n", __func__)); evbuffer_add_printf(evb, BASIC_REQUEST_BODY); evcon = evhttp_request_get_connection(req); @@ -438,7 +438,7 @@ http_chunked_cb(struct evhttp_request *req, void *arg) { struct timeval when = { 0, 0 }; struct chunk_req_state *state = malloc(sizeof(struct chunk_req_state)); - event_debug(("%s: called\n", __func__)); + TT_BLATHER(("%s: called\n", __func__)); memset(state, 0, sizeof(struct chunk_req_state)); state->req = req; @@ -631,7 +631,7 @@ http_badreq_cb(struct evhttp_request *req, void *arg) static void http_badreq_errorcb(struct bufferevent *bev, short what, void *arg) { - event_debug(("%s: called (what=%04x, arg=%p)", __func__, what, arg)); + TT_BLATHER(("%s: called (what=%04x, arg=%p)", __func__, what, arg)); /* ignore */ } @@ -677,7 +677,7 @@ http_badreq_readcb(struct bufferevent *bev, void *arg) static void http_badreq_successcb(evutil_socket_t fd, short what, void *arg) { - event_debug(("%s: called (what=%04x, arg=%p)", __func__, what, arg)); + TT_BLATHER(("%s: called (what=%04x, arg=%p)", __func__, what, arg)); event_base_loopexit(exit_base, NULL); } @@ -793,7 +793,7 @@ http_delete_cb(struct evhttp_request *req, void *arg) exit(1); } - event_debug(("%s: called\n", __func__)); + TT_BLATHER(("%s: called\n", __func__)); evbuffer_add_printf(evb, BASIC_REQUEST_BODY); /* allow sending of an empty reply */ @@ -864,7 +864,7 @@ http_sent_cb(struct evhttp_request *req, void *arg) exit(1); } - event_debug(("%s: called\n", __func__)); + TT_BLATHER(("%s: called\n", __func__)); ++test_ok; } @@ -876,7 +876,7 @@ http_on_complete_cb(struct evhttp_request *req, void *arg) evhttp_request_set_on_complete_cb(req, http_sent_cb, (void *)0xDEADBEEF); - event_debug(("%s: called\n", __func__)); + TT_BLATHER(("%s: called\n", __func__)); evbuffer_add_printf(evb, BASIC_REQUEST_BODY); /* allow sending of an empty reply */ @@ -1871,7 +1871,7 @@ http_dispatcher_cb(struct evhttp_request *req, void *arg) { struct evbuffer *evb = evbuffer_new(); - event_debug(("%s: called\n", __func__)); + TT_BLATHER(("%s: called\n", __func__)); evbuffer_add_printf(evb, "DISPATCHER_TEST"); evhttp_send_reply(req, HTTP_OK, "Everything is fine", evb); @@ -2029,7 +2029,7 @@ void http_post_cb(struct evhttp_request *req, void *arg) { struct evbuffer *evb; - event_debug(("%s: called\n", __func__)); + TT_BLATHER(("%s: called\n", __func__)); /* Yes, we are expecting a post request */ if (evhttp_request_get_command(req) != EVHTTP_REQ_POST) { @@ -2146,7 +2146,7 @@ void http_put_cb(struct evhttp_request *req, void *arg) { struct evbuffer *evb; - event_debug(("%s: called\n", __func__)); + TT_BLATHER(("%s: called\n", __func__)); /* Expecting a PUT request */ if (evhttp_request_get_command(req) != EVHTTP_REQ_PUT) { diff --git a/test/regress_util.c b/test/regress_util.c index 320047fa..721537cc 100644 --- a/test/regress_util.c +++ b/test/regress_util.c @@ -23,6 +23,10 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + +/** For event_debug() usage/coverage */ +#define EVENT_VISIBILITY_WANT_DLLIMPORT + #include "../util-internal.h" #ifdef _WIN32 -- cgit v1.2.1 From 5e97b6e6f72d690a0f9fa2625fe6f7f05229a81a Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 28 Oct 2018 20:52:32 +0300 Subject: appveyor: reconfigure tests with allow_failure and fast_finish (cherry picked from commit e17e1ee91d292e8a1c7b6ac9e76dd29906d517dc) --- appveyor.yml | 64 +++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index b76997d1..973625d7 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -8,32 +8,48 @@ build: environment: global: CYG_ROOT: C:/MinGW/msys/1.0 + EVENT_TESTS_PARALLEL: 20 matrix: + # !EVENT_ALLOW_FAILURE + - EVENT_BUILD_METHOD: "cmake" + EVENT_CMAKE_OPTIONS: "" + # EVENT_ALLOW_FAILURE - EVENT_BUILD_METHOD: "autotools" EVENT_CONFIGURE_OPTIONS: "" + EVENT_ALLOW_FAILURE: 1 + - EVENT_BUILD_METHOD: "autotools" + EVENT_CONFIGURE_OPTIONS: "--disable-openssl" + EVENT_ALLOW_FAILURE: 1 + - EVENT_BUILD_METHOD: "autotools" + EVENT_CONFIGURE_OPTIONS: "--disable-thread-support" + EVENT_ALLOW_FAILURE: 1 + - EVENT_BUILD_METHOD: "autotools" + EVENT_CONFIGURE_OPTIONS: "--disable-debug-mode" + EVENT_ALLOW_FAILURE: 1 + - EVENT_BUILD_METHOD: "autotools" + EVENT_CONFIGURE_OPTIONS: "--disable-malloc-replacement" + EVENT_ALLOW_FAILURE: 1 - EVENT_BUILD_METHOD: "cmake" - EVENT_CMAKE_OPTIONS: "" - # Since we have FREE billing plan, let's reduce amount of builds to make - # primary two runs/starts faster. - # - # - EVENT_BUILD_METHOD: "autotools" - # EVENT_CONFIGURE_OPTIONS: "--disable-openssl" - # - EVENT_BUILD_METHOD: "autotools" - # EVENT_CONFIGURE_OPTIONS: "--disable-thread-support" - # - EVENT_BUILD_METHOD: "autotools" - # EVENT_CONFIGURE_OPTIONS: "--disable-debug-mode" - # - EVENT_BUILD_METHOD: "autotools" - # EVENT_CONFIGURE_OPTIONS: "--disable-malloc-replacement" - # - EVENT_BUILD_METHOD: "cmake" - # EVENT_CMAKE_OPTIONS: "-DEVENT__DISABLE_OPENSSL=ON" - # - EVENT_BUILD_METHOD: "cmake" - # EVENT_CMAKE_OPTIONS: "-DEVENT__DISABLE_THREAD_SUPPORT=ON" - # - EVENT_BUILD_METHOD: "cmake" - # EVENT_CMAKE_OPTIONS: "-DEVENT__DISABLE_DEBUG_MODE=ON" - # - EVENT_BUILD_METHOD: "cmake" - # EVENT_CMAKE_OPTIONS: "-DEVENT__DISABLE_MM_REPLACEMENT=ON" - # - EVENT_BUILD_METHOD: "cmake" - # EVENT_CMAKE_OPTIONS: "-DCMAKE_C_FLAGS='-DUNICODE -D_UNICODE'" + EVENT_CMAKE_OPTIONS: "-DEVENT__DISABLE_OPENSSL=ON" + EVENT_ALLOW_FAILURE: 1 + - EVENT_BUILD_METHOD: "cmake" + EVENT_CMAKE_OPTIONS: "-DEVENT__DISABLE_THREAD_SUPPORT=ON" + EVENT_ALLOW_FAILURE: 1 + - EVENT_BUILD_METHOD: "cmake" + EVENT_CMAKE_OPTIONS: "-DEVENT__DISABLE_DEBUG_MODE=ON" + EVENT_ALLOW_FAILURE: 1 + - EVENT_BUILD_METHOD: "cmake" + EVENT_CMAKE_OPTIONS: "-DEVENT__DISABLE_MM_REPLACEMENT=ON" + EVENT_ALLOW_FAILURE: 1 + - EVENT_BUILD_METHOD: "cmake" + EVENT_CMAKE_OPTIONS: "-DCMAKE_C_FLAGS='-DUNICODE -D_UNICODE'" + EVENT_ALLOW_FAILURE: 1 + +matrix: + allow_failures: + - EVENT_ALLOW_FAILURE: 1 + fast_finish: true + init: - 'echo Building libevent %version% for Windows' - 'echo System architecture: %PLATFORM%' @@ -50,13 +66,13 @@ build_script: bash -lc "echo 'C:\MinGW /mingw' > /etc/fstab" bash -lc "echo 'C:\OpenSSL-Win32 /ssl' >> /etc/fstab" $env:APPVEYOR_BUILD_FOLDER = $env:APPVEYOR_BUILD_FOLDER -replace "\\", "/" - bash -lc "exec 0&1; cd $env:APPVEYOR_BUILD_FOLDER; bash -x ./autogen.sh && ./configure LDFLAGS='-L/ssl -L/ssl/lib -L/ssl/lib/MinGW' CFLAGS=-I/ssl/include $env:EVENT_CONFIGURE_OPTIONS && make && make verify -j20" + bash -lc "exec 0&1; cd $env:APPVEYOR_BUILD_FOLDER; bash -x ./autogen.sh && ./configure LDFLAGS='-L/ssl -L/ssl/lib -L/ssl/lib/MinGW' CFLAGS=-I/ssl/include $env:EVENT_CONFIGURE_OPTIONS && make && make verify -j$env:EVENT_TESTS_PARALLEL" } else { md build cd build cmake .. $env:EVENT_CMAKE_OPTIONS cmake --build . - $env:CTEST_PARALLEL_LEVEL="20" + $env:CTEST_PARALLEL_LEVEL=$env:EVENT_TESTS_PARALLEL ctest --output-on-failure } -- cgit v1.2.1 From ca4b640490de49dc3f8708429fbe0197377a2198 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Wed, 31 Oct 2018 01:22:30 +0300 Subject: Merge branch 'event-ET-#636-v2' * event-ET-#636-v2: Preserve ET bit for backends with changelist Epoll ET setting lost with multiple events for same fd Cover ET with multiple events for same fd Add ET flag into event_base_dump_events() Fixes: #636 (cherry picked from commit 33053cdd8a9e1a7330b47759dee9cb209bed8f1b) --- epoll.c | 9 +++-- event.c | 3 +- evmap.c | 29 +++++++--------- test/regress_et.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 114 insertions(+), 27 deletions(-) diff --git a/epoll.c b/epoll.c index bf730b23..a0df0d21 100644 --- a/epoll.c +++ b/epoll.c @@ -401,11 +401,14 @@ epoll_nochangelist_del(struct event_base *base, evutil_socket_t fd, ch.old_events = old; ch.read_change = ch.write_change = ch.close_change = 0; if (events & EV_WRITE) - ch.write_change = EV_CHANGE_DEL; + ch.write_change = EV_CHANGE_DEL | + (events & EV_ET); if (events & EV_READ) - ch.read_change = EV_CHANGE_DEL; + ch.read_change = EV_CHANGE_DEL | + (events & EV_ET); if (events & EV_CLOSED) - ch.close_change = EV_CHANGE_DEL; + ch.close_change = EV_CHANGE_DEL | + (events & EV_ET); return epoll_apply_one_change(base, base->evbase, &ch); } diff --git a/event.c b/event.c index caf766b5..ea72ddd3 100644 --- a/event.c +++ b/event.c @@ -3728,13 +3728,14 @@ dump_inserted_event_fn(const struct event_base *base, const struct event *e, voi if (! (e->ev_flags & (EVLIST_INSERTED|EVLIST_TIMEOUT))) return 0; - fprintf(output, " %p [%s "EV_SOCK_FMT"]%s%s%s%s%s%s", + fprintf(output, " %p [%s "EV_SOCK_FMT"]%s%s%s%s%s%s%s", (void*)e, gloss, EV_SOCK_ARG(e->ev_fd), (e->ev_events&EV_READ)?" Read":"", (e->ev_events&EV_WRITE)?" Write":"", (e->ev_events&EV_CLOSED)?" EOF":"", (e->ev_events&EV_SIGNAL)?" Signal":"", (e->ev_events&EV_PERSIST)?" Persist":"", + (e->ev_events&EV_ET)?" ET":"", (e->ev_flags&EVLIST_INTERNAL)?" Internal":""); if (e->ev_flags & EVLIST_TIMEOUT) { struct timeval tv; diff --git a/evmap.c b/evmap.c index 3f76dd0a..31ab4fee 100644 --- a/evmap.c +++ b/evmap.c @@ -393,7 +393,8 @@ evmap_io_del_(struct event_base *base, evutil_socket_t fd, struct event *ev) if (res) { void *extra = ((char*)ctx) + sizeof(struct evmap_io); - if (evsel->del(base, ev->ev_fd, old, res, extra) == -1) { + if (evsel->del(base, ev->ev_fd, + old, (ev->ev_events & EV_ET) | res, extra) == -1) { retval = -1; } else { retval = 1; @@ -858,6 +859,7 @@ event_changelist_add_(struct event_base *base, evutil_socket_t fd, short old, sh struct event_changelist *changelist = &base->changelist; struct event_changelist_fdinfo *fdinfo = p; struct event_change *change; + short evchange = EV_CHANGE_ADD | (events & (EV_ET|EV_PERSIST|EV_SIGNAL)); event_changelist_check(base); @@ -869,18 +871,12 @@ event_changelist_add_(struct event_base *base, evutil_socket_t fd, short old, sh * since the delete might fail (because the fd had been closed since * the last add, for instance. */ - if (events & (EV_READ|EV_SIGNAL)) { - change->read_change = EV_CHANGE_ADD | - (events & (EV_ET|EV_PERSIST|EV_SIGNAL)); - } - if (events & EV_WRITE) { - change->write_change = EV_CHANGE_ADD | - (events & (EV_ET|EV_PERSIST|EV_SIGNAL)); - } - if (events & EV_CLOSED) { - change->close_change = EV_CHANGE_ADD | - (events & (EV_ET|EV_PERSIST|EV_SIGNAL)); - } + if (events & (EV_READ|EV_SIGNAL)) + change->read_change = evchange; + if (events & EV_WRITE) + change->write_change = evchange; + if (events & EV_CLOSED) + change->close_change = evchange; event_changelist_check(base); return (0); @@ -893,6 +889,7 @@ event_changelist_del_(struct event_base *base, evutil_socket_t fd, short old, sh struct event_changelist *changelist = &base->changelist; struct event_changelist_fdinfo *fdinfo = p; struct event_change *change; + short del = EV_CHANGE_DEL | (events & EV_ET); event_changelist_check(base); change = event_changelist_get_or_construct(changelist, fd, old, fdinfo); @@ -919,19 +916,19 @@ event_changelist_del_(struct event_base *base, evutil_socket_t fd, short old, sh if (!(change->old_events & (EV_READ | EV_SIGNAL))) change->read_change = 0; else - change->read_change = EV_CHANGE_DEL; + change->read_change = del; } if (events & EV_WRITE) { if (!(change->old_events & EV_WRITE)) change->write_change = 0; else - change->write_change = EV_CHANGE_DEL; + change->write_change = del; } if (events & EV_CLOSED) { if (!(change->old_events & EV_CLOSED)) change->close_change = 0; else - change->close_change = EV_CHANGE_DEL; + change->close_change = del; } event_changelist_check(base); diff --git a/test/regress_et.c b/test/regress_et.c index f75c59b3..b9bd317e 100644 --- a/test/regress_et.c +++ b/test/regress_et.c @@ -51,6 +51,14 @@ static int was_et = 0; +static int base_supports_et(struct event_base *base) +{ + return + (!strcmp(event_base_get_method(base), "epoll") || + !strcmp(event_base_get_method(base), "epoll (with changelist)") || + !strcmp(event_base_get_method(base), "kqueue")); +} + static void read_cb(evutil_socket_t fd, short event, void *arg) { @@ -106,13 +114,7 @@ test_edgetriggered(void *et) /* Initalize the event library */ base = event_base_new(); - if (!strcmp(event_base_get_method(base), "epoll") || - !strcmp(event_base_get_method(base), "epoll (with changelist)") || - !strcmp(event_base_get_method(base), "kqueue")) - supports_et = 1; - else - supports_et = 0; - + supports_et = base_supports_et(base); TT_BLATHER(("Checking for edge-triggered events with %s, which should %s" "support edge-triggering", event_base_get_method(base), supports_et?"":"not ")); @@ -196,9 +198,93 @@ end: event_base_free(base); } +static int read_notification_count; +static int last_read_notification_was_et; +static void +read_notification_cb(evutil_socket_t fd, short event, void *arg) +{ + read_notification_count++; + last_read_notification_was_et = (event & EV_ET); +} + +static int write_notification_count; +static int last_write_notification_was_et; +static void +write_notification_cb(evutil_socket_t fd, short event, void *arg) +{ + write_notification_count++; + last_write_notification_was_et = (event & EV_ET); +} + +/* After two or more events have been registered for the same + * file descriptor using EV_ET, if one of the events is + * deleted, then the epoll_ctl() call issued by libevent drops + * the EPOLLET flag resulting in level triggered + * notifications. + */ +static void +test_edge_triggered_multiple_events(void *data_) +{ + struct basic_test_data *data = data_; + struct event *read_ev = NULL; + struct event *write_ev = NULL; + const char c = 'A'; + struct event_base *base = data->base; + int *pair = data->pair; + + if (!base_supports_et(base)) { + tt_skip(); + return; + } + + read_notification_count = 0; + last_read_notification_was_et = 0; + write_notification_count = 0; + last_write_notification_was_et = 0; + + /* Make pair[1] readable */ + tt_int_op(send(pair[0], &c, 1, 0), >, 0); + + read_ev = event_new(base, pair[1], EV_READ|EV_ET|EV_PERSIST, + read_notification_cb, NULL); + write_ev = event_new(base, pair[1], EV_WRITE|EV_ET|EV_PERSIST, + write_notification_cb, NULL); + + event_add(read_ev, NULL); + event_add(write_ev, NULL); + event_base_loop(base, EVLOOP_NONBLOCK|EVLOOP_ONCE); + event_base_loop(base, EVLOOP_NONBLOCK|EVLOOP_ONCE); + + tt_assert(last_read_notification_was_et); + tt_int_op(read_notification_count, ==, 1); + tt_assert(last_write_notification_was_et); + tt_int_op(write_notification_count, ==, 1); + + event_del(read_ev); + + /* trigger acitivity second time for the backend that can have multiple + * events for one fd (like kqueue) */ + close(pair[0]); + pair[0] = -1; + + /* Verify that we are still edge-triggered for write notifications */ + event_base_loop(base, EVLOOP_NONBLOCK|EVLOOP_ONCE); + event_base_loop(base, EVLOOP_NONBLOCK|EVLOOP_ONCE); + tt_assert(last_write_notification_was_et); + tt_int_op(write_notification_count, ==, 2); + +end: + if (read_ev) + event_free(read_ev); + if (write_ev) + event_free(write_ev); +} + struct testcase_t edgetriggered_testcases[] = { { "et", test_edgetriggered, TT_FORK, NULL, NULL }, { "et_mix_error", test_edgetriggered_mix_error, TT_FORK|TT_NEED_SOCKETPAIR|TT_NO_LOGS, &basic_setup, NULL }, + { "et_multiple_events", test_edge_triggered_multiple_events, + TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR, &basic_setup, NULL }, END_OF_TESTCASES }; -- cgit v1.2.1 From bf3a67cfc5d9a4651f0bcc1b6d37f39debe5a9e4 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Wed, 31 Oct 2018 06:34:40 +0300 Subject: Add cmake rules into dist archive Fixes: #502 Refs: #551 (cherry picked from commit 69bc2da79fb2f358c22feba45e9ad4752729d320) --- Makefile.am | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/Makefile.am b/Makefile.am index 9e0f6995..efc17eba 100644 --- a/Makefile.am +++ b/Makefile.am @@ -104,6 +104,30 @@ PLATFORM_DEPENDENT_SRC = \ arc4random.c \ epoll_sub.c +CMAKE_FILES = \ + cmake/AddCompilerFlags.cmake \ + cmake/AddEventLibrary.cmake \ + cmake/CheckConstExists.cmake \ + cmake/CheckFileOffsetBits.c \ + cmake/CheckFileOffsetBits.cmake \ + cmake/CheckFunctionExistsEx.c \ + cmake/CheckFunctionExistsEx.cmake \ + cmake/CheckFunctionKeywords.cmake \ + cmake/CheckPrototypeDefinition.c.in \ + cmake/CheckPrototypeDefinition.cmake \ + cmake/CheckWorkingKqueue.cmake \ + cmake/CodeCoverage.cmake \ + cmake/COPYING-CMAKE-SCRIPTS \ + cmake/Copyright.txt \ + cmake/FindGit.cmake \ + cmake/LibeventConfigBuildTree.cmake.in \ + cmake/LibeventConfig.cmake.in \ + cmake/LibeventConfigVersion.cmake.in \ + cmake/VersionViaGit.cmake \ + event-config.h.cmake \ + evconfig-private.h.cmake \ + CMakeLists.txt + EXTRA_DIST = \ ChangeLog-1.4 \ ChangeLog-2.0 \ @@ -116,6 +140,7 @@ EXTRA_DIST = \ make-event-config.sed \ whatsnew-2.0.txt \ whatsnew-2.1.txt \ + $(CMAKE_FILES) \ $(PLATFORM_DEPENDENT_SRC) LIBEVENT_LIBS_LA = libevent.la libevent_core.la libevent_extra.la -- cgit v1.2.1 From a39898f363450b59f3bced7ed8e605ca4a20c4d1 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 4 Nov 2018 01:21:48 +0300 Subject: Merge branch 'check-O_NONBLOCK-in-debug' * check-O_NONBLOCK-in-debug: regress: use non blocking descriptors whenever it is possible assert that fds are nonblocking in debug mode Closes: nmathewson/Libevent#90 (cherry picked from commit 6f988ee161680925fc3308f17d293c680e3ac916) --- event.c | 39 +++++++++++++++++++++++++++------------ test/regress.c | 15 ++++++--------- test/regress_et.c | 34 +++++++--------------------------- 3 files changed, 40 insertions(+), 48 deletions(-) diff --git a/event.c b/event.c index ea72ddd3..5ee7d81b 100644 --- a/event.c +++ b/event.c @@ -52,6 +52,9 @@ #include #include #include +#ifdef EVENT__HAVE_FCNTL_H +#include +#endif #include "event2/event.h" #include "event2/event_struct.h" @@ -234,9 +237,8 @@ static void event_debug_note_setup_(const struct event *ev) { struct event_debug_entry *dent, find; - if (!event_debug_mode_on_) { + if (!event_debug_mode_on_) goto out; - } find.ptr = ev; EVLOCK_LOCK(event_debug_map_lock_, 0); @@ -262,9 +264,8 @@ static void event_debug_note_teardown_(const struct event *ev) { struct event_debug_entry *dent, find; - if (!event_debug_mode_on_) { + if (!event_debug_mode_on_) goto out; - } find.ptr = ev; EVLOCK_LOCK(event_debug_map_lock_, 0); @@ -281,9 +282,8 @@ static void event_debug_note_add_(const struct event *ev) { struct event_debug_entry *dent,find; - if (!event_debug_mode_on_) { + if (!event_debug_mode_on_) goto out; - } find.ptr = ev; EVLOCK_LOCK(event_debug_map_lock_, 0); @@ -308,9 +308,8 @@ static void event_debug_note_del_(const struct event *ev) { struct event_debug_entry *dent, find; - if (!event_debug_mode_on_) { + if (!event_debug_mode_on_) goto out; - } find.ptr = ev; EVLOCK_LOCK(event_debug_map_lock_, 0); @@ -335,9 +334,8 @@ static void event_debug_assert_is_setup_(const struct event *ev) { struct event_debug_entry *dent, find; - if (!event_debug_mode_on_) { + if (!event_debug_mode_on_) return; - } find.ptr = ev; EVLOCK_LOCK(event_debug_map_lock_, 0); @@ -357,9 +355,8 @@ static void event_debug_assert_not_added_(const struct event *ev) { struct event_debug_entry *dent, find; - if (!event_debug_mode_on_) { + if (!event_debug_mode_on_) return; - } find.ptr = ev; EVLOCK_LOCK(event_debug_map_lock_, 0); @@ -374,6 +371,21 @@ static void event_debug_assert_not_added_(const struct event *ev) } EVLOCK_UNLOCK(event_debug_map_lock_, 0); } +static void event_debug_assert_socket_nonblocking_(evutil_socket_t fd) +{ + int flags; + + if (!event_debug_mode_on_) + return; + +#ifndef _WIN32 + if ((flags = fcntl(fd, F_GETFL, NULL)) >= 0) { + EVUTIL_ASSERT(flags & O_NONBLOCK); + } +#else + (void)flags; +#endif +} #else static void event_debug_note_setup_(const struct event *ev) { (void)ev; } static void event_debug_note_teardown_(const struct event *ev) { (void)ev; } @@ -381,6 +393,7 @@ static void event_debug_note_add_(const struct event *ev) { (void)ev; } static void event_debug_note_del_(const struct event *ev) { (void)ev; } static void event_debug_assert_is_setup_(const struct event *ev) { (void)ev; } static void event_debug_assert_not_added_(const struct event *ev) { (void)ev; } +static void event_debug_assert_socket_nonblocking_(evutil_socket_t fd) { (void)fd; } #endif #define EVENT_BASE_ASSERT_LOCKED(base) \ @@ -2099,6 +2112,8 @@ event_assign(struct event *ev, struct event_base *base, evutil_socket_t fd, shor if (arg == &event_self_cbarg_ptr_) arg = ev; + if (!(events & EV_SIGNAL)) + event_debug_assert_socket_nonblocking_(fd); event_debug_assert_not_added_(ev); ev->ev_base = base; diff --git a/test/regress.c b/test/regress.c index 6daa17ed..e3966247 100644 --- a/test/regress.c +++ b/test/regress.c @@ -1389,18 +1389,14 @@ test_free_active_base(void *ptr) struct event ev1; base1 = event_init(); - if (base1) { - event_assign(&ev1, base1, data->pair[1], EV_READ, - dummy_read_cb, NULL); - event_add(&ev1, NULL); - event_base_free(base1); /* should not crash */ - } else { - tt_fail_msg("failed to create event_base for test"); - } + tt_assert(base1); + event_assign(&ev1, base1, data->pair[1], EV_READ, dummy_read_cb, NULL); + event_add(&ev1, NULL); + event_base_free(base1); /* should not crash */ base1 = event_init(); tt_assert(base1); - event_assign(&ev1, base1, 0, 0, dummy_read_cb, NULL); + event_assign(&ev1, base1, data->pair[0], 0, dummy_read_cb, NULL); event_active(&ev1, EV_READ, 1); event_base_free(base1); end: @@ -3080,6 +3076,7 @@ test_many_events(void *arg) * instance of that. */ sock[i] = socket(AF_INET, SOCK_DGRAM, 0); tt_assert(sock[i] >= 0); + tt_assert(!evutil_make_socket_nonblocking(sock[i])); called[i] = 0; ev[i] = event_new(base, sock[i], EV_WRITE|evflags, many_event_cb, &called[i]); diff --git a/test/regress_et.c b/test/regress_et.c index b9bd317e..07bcd4a5 100644 --- a/test/regress_et.c +++ b/test/regress_et.c @@ -75,19 +75,14 @@ read_cb(evutil_socket_t fd, short event, void *arg) event_del(arg); } -#ifdef _WIN32 -#define LOCAL_SOCKETPAIR_AF AF_INET -#else -#define LOCAL_SOCKETPAIR_AF AF_UNIX -#endif - static void -test_edgetriggered(void *et) +test_edgetriggered(void *data_) { + struct basic_test_data *data = data_; + struct event_base *base = data->base; + int *pair = data->pair; struct event *ev = NULL; - struct event_base *base = NULL; const char *test = "test string"; - evutil_socket_t pair[2] = {-1,-1}; int supports_et; /* On Linux 3.2.1 (at least, as patched by Fedora and tested by Nick), @@ -96,24 +91,12 @@ test_edgetriggered(void *et) * get edge-triggered behavior. Yuck! Linux 3.1.9 didn't have this * problem. */ -#ifdef __linux__ - if (evutil_ersatz_socketpair_(AF_INET, SOCK_STREAM, 0, pair) == -1) { - tt_abort_perror("socketpair"); - } -#else - if (evutil_socketpair(LOCAL_SOCKETPAIR_AF, SOCK_STREAM, 0, pair) == -1) { - tt_abort_perror("socketpair"); - } -#endif called = was_et = 0; tt_int_op(send(pair[0], test, (int)strlen(test)+1, 0), >, 0); shutdown(pair[0], EVUTIL_SHUT_WR); - /* Initalize the event library */ - base = event_base_new(); - supports_et = base_supports_et(base); TT_BLATHER(("Checking for edge-triggered events with %s, which should %s" "support edge-triggering", event_base_get_method(base), @@ -142,15 +125,11 @@ test_edgetriggered(void *et) tt_assert(!was_et); } - end: +end: if (ev) { event_del(ev); event_free(ev); } - if (base) - event_base_free(base); - evutil_closesocket(pair[0]); - evutil_closesocket(pair[1]); } static void @@ -281,7 +260,8 @@ end: } struct testcase_t edgetriggered_testcases[] = { - { "et", test_edgetriggered, TT_FORK, NULL, NULL }, + { "et", test_edgetriggered, + TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR, &basic_setup, NULL }, { "et_mix_error", test_edgetriggered_mix_error, TT_FORK|TT_NEED_SOCKETPAIR|TT_NO_LOGS, &basic_setup, NULL }, { "et_multiple_events", test_edge_triggered_multiple_events, -- cgit v1.2.1 From 6594bfb41eac93cb7cb4e3385f41f48d127e8150 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Fri, 2 Nov 2018 23:43:57 +0300 Subject: regress_http: make https_basic non time dependent Fixes: #454 (cherry picked from commit e29afd4b9428631444b208edfe3a4ba6ce4423af) --- test/regress_http.c | 49 +++++++++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/test/regress_http.c b/test/regress_http.c index 49cbed02..bae5ea33 100644 --- a/test/regress_http.c +++ b/test/regress_http.c @@ -456,16 +456,6 @@ http_chunked_cb(struct evhttp_request *req, void *arg) event_base_once(arg, -1, EV_TIMEOUT, http_chunked_trickle_cb, state, &when); } -static void -http_complete_write(evutil_socket_t fd, short what, void *arg) -{ - struct bufferevent *bev = arg; - const char *http_request = "host\r\n" - "Connection: close\r\n" - "\r\n"; - bufferevent_write(bev, http_request, strlen(http_request)); -} - static struct bufferevent * create_bev(struct event_base *base, int fd, int ssl_mask) { @@ -493,11 +483,26 @@ create_bev(struct event_base *base, int fd, int ssl_mask) return bev; } +static void +http_half_writecb(struct bufferevent *bev, void *arg) +{ + if (evbuffer_get_length(bufferevent_get_output(bev)) == 0) { + if (!test_ok) { + const char http_request[] = "host\r\n" + "Connection: close\r\n" + "\r\n"; + bufferevent_write(bev, http_request, strlen(http_request)); + } + /* enable reading of the reply */ + bufferevent_enable(bev, EV_READ); + test_ok++; + } +} + static void http_basic_test_impl(void *arg, int ssl, const char *request_line) { struct basic_test_data *data = arg; - struct timeval tv; struct bufferevent *bev = NULL; evutil_socket_t fd; const char *http_request; @@ -507,7 +512,6 @@ http_basic_test_impl(void *arg, int ssl, const char *request_line) struct evbuffer *out; exit_base = data->base; - test_ok = 0; /* bind to a second socket */ if (http_bind(http, &port2, server_flags) == -1) { @@ -519,7 +523,7 @@ http_basic_test_impl(void *arg, int ssl, const char *request_line) /* Stupid thing to send a request */ bev = create_bev(data->base, fd, ssl); - bufferevent_setcb(bev, http_readcb, http_writecb, + bufferevent_setcb(bev, http_readcb, http_half_writecb, http_errorcb, data->base); out = bufferevent_get_output(bev); @@ -528,15 +532,8 @@ http_basic_test_impl(void *arg, int ssl, const char *request_line) "%s\r\n" "Host: some", request_line); - evutil_timerclear(&tv); - tv.tv_usec = 100000; - if (ssl) - tv.tv_usec *= 10; - event_base_once(data->base, - -1, EV_TIMEOUT, http_complete_write, bev, &tv); - + test_ok = 0; event_base_dispatch(data->base); - tt_int_op(test_ok, ==, 3); /* connect to the second port */ @@ -557,9 +554,9 @@ http_basic_test_impl(void *arg, int ssl, const char *request_line) "Connection: close\r\n" "\r\n", request_line); + test_ok = 0; event_base_dispatch(data->base); - - tt_int_op(test_ok, ==, 5); + tt_int_op(test_ok, ==, 2); /* Connect to the second port again. This time, send an absolute uri. */ bufferevent_free(bev); @@ -580,12 +577,12 @@ http_basic_test_impl(void *arg, int ssl, const char *request_line) bufferevent_write(bev, http_request, strlen(http_request)); + test_ok = 0; event_base_dispatch(data->base); - - tt_int_op(test_ok, ==, 7); + tt_int_op(test_ok, ==, 2); evhttp_free(http); - end: +end: if (bev) bufferevent_free(bev); } -- cgit v1.2.1 From 30020a35070c6585c69eee5d1c2e08585ce40afa Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 4 Nov 2018 21:41:20 +0300 Subject: Merge branch 'ssl_bufferevent_wm_filter-fix' * ssl_bufferevent_wm_filter-fix: Fix ssl/bufferevent_wm_filter when bev does not reach watermark on break regress_ssl: cover watermarks with deferred callbacks regress_ssl: improve bufferevent_wm/bufferevent_wm_filter logging (cherry picked from commit 9d93fbe77968da5ca5b2dbe8973e6f3c3045c5ba) --- test/regress_ssl.c | 57 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/test/regress_ssl.c b/test/regress_ssl.c index 18d2ba89..5b2dce87 100644 --- a/test/regress_ssl.c +++ b/test/regress_ssl.c @@ -280,6 +280,8 @@ enum regress_openssl_type REGRESS_OPENSSL_SLEEP = 1024, REGRESS_OPENSSL_CLIENT_WRITE = 2048, + + REGRESS_DEFERRED_CALLBACKS = 4096, }; static void @@ -797,6 +799,7 @@ end: struct wm_context { int server; + int flags; struct evbuffer *data; size_t to_read; size_t wm_high; @@ -813,29 +816,33 @@ wm_transfer(struct bufferevent *bev, void *arg) size_t len = evbuffer_get_length(in); size_t drain = len < ctx->to_read ? len : ctx->to_read; + if (ctx->get+drain >= ctx->limit) { + TT_BLATHER(("wm_transfer-%s(%p): break", + ctx->server ? "server" : "client", bev)); + bufferevent_setcb(bev, NULL, NULL, NULL, NULL); + bufferevent_disable(bev, EV_READ); + } + evbuffer_drain(in, drain); ctx->get += drain; - TT_BLATHER(("wm_transfer-%s: in: %zu, out: %zu, got: %zu", - ctx->server ? "server" : "client", + TT_BLATHER(("wm_transfer-%s(%p): " + "in: " EV_SIZE_FMT ", " + "out: " EV_SIZE_FMT ", " + "got: " EV_SIZE_FMT "", + ctx->server ? "server" : "client", bev, evbuffer_get_length(in), evbuffer_get_length(out), ctx->get)); evbuffer_add_buffer_reference(out, ctx->data); - if (ctx->get >= ctx->limit) { - TT_BLATHER(("wm_transfer-%s: break", - ctx->server ? "server" : "client")); - bufferevent_setcb(bev, NULL, NULL, NULL, NULL); - bufferevent_disable(bev, EV_READ); - } } static void wm_eventcb(struct bufferevent *bev, short what, void *arg) { struct wm_context *ctx = arg; - TT_BLATHER(("wm_eventcb-%s: %i", - ctx->server ? "server" : "client", what)); + TT_BLATHER(("wm_eventcb-%s(%p): %i", + ctx->server ? "server" : "client", bev, what)); if (what & BEV_EVENT_CONNECTED) { } else { ctx->get = 0; @@ -854,7 +861,10 @@ wm_acceptcb(struct evconnlistener *listener, evutil_socket_t fd, SSL_use_PrivateKey(ssl, the_key); bev = bufferevent_openssl_socket_new( - base, fd, ssl, BUFFEREVENT_SSL_ACCEPTING, BEV_OPT_CLOSE_ON_FREE); + base, fd, ssl, BUFFEREVENT_SSL_ACCEPTING, ctx->flags); + + TT_BLATHER(("wm_transfer-%s(%p): accept", + ctx->server ? "server" : "client", bev)); bufferevent_setwatermark(bev, EV_READ, 0, ctx->wm_high); bufferevent_setcb(bev, wm_transfer, NULL, wm_eventcb, ctx); @@ -891,10 +901,14 @@ regress_bufferevent_openssl_wm(void *arg) memset(&ss, 0, sizeof(ss)); slen = sizeof(ss); + if (type & REGRESS_DEFERRED_CALLBACKS) + bev_flags |= BEV_OPT_DEFER_CALLBACKS; + memset(&client, 0, sizeof(client)); memset(&server, 0, sizeof(server)); client.server = 0; server.server = 1; + client.flags = server.flags = bev_flags; client.data = evbuffer_new(); server.data = evbuffer_new(); payload = calloc(1, payload_len); @@ -905,8 +919,15 @@ regress_bufferevent_openssl_wm(void *arg) client.limit = server.limit = wm_high<<3; client.to_read = server.to_read = payload_len>>1; - TT_BLATHER(("openssl_wm: payload_len = %zu, wm_high = %zu, limit = %zu, to_read: %zu", - payload_len, wm_high, server.limit, server.to_read)); + TT_BLATHER(("openssl_wm: " + "payload_len = " EV_SIZE_FMT ", " + "wm_high = " EV_SIZE_FMT ", " + "limit = " EV_SIZE_FMT ", " + "to_read: " EV_SIZE_FMT "", + payload_len, + wm_high, + server.limit, + server.to_read)); listener = evconnlistener_new_bind(base, wm_acceptcb, &server, LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, @@ -919,15 +940,15 @@ regress_bufferevent_openssl_wm(void *arg) tt_assert(ssl); if (type & REGRESS_OPENSSL_FILTER) { - bev = bufferevent_socket_new(data->base, -1, bev_flags); + bev = bufferevent_socket_new(data->base, -1, client.flags); tt_assert(bev); bev = bufferevent_openssl_filter_new( - base, bev, ssl, BUFFEREVENT_SSL_CONNECTING, bev_flags); + base, bev, ssl, BUFFEREVENT_SSL_CONNECTING, client.flags); } else { bev = bufferevent_openssl_socket_new( data->base, -1, ssl, BUFFEREVENT_SSL_CONNECTING, - bev_flags); + client.flags); } tt_assert(bev); client.bev = bev; @@ -1034,6 +1055,10 @@ struct testcase_t ssl_testcases[] = { TT_FORK|TT_NEED_BASE, &ssl_setup, NULL }, { "bufferevent_wm_filter", regress_bufferevent_openssl_wm, TT_FORK|TT_NEED_BASE, &ssl_setup, T(REGRESS_OPENSSL_FILTER) }, + { "bufferevent_wm_defer", regress_bufferevent_openssl_wm, + TT_FORK|TT_NEED_BASE, &ssl_setup, T(REGRESS_DEFERRED_CALLBACKS) }, + { "bufferevent_wm_filter_defer", regress_bufferevent_openssl_wm, + TT_FORK|TT_NEED_BASE, &ssl_setup, T(REGRESS_OPENSSL_FILTER|REGRESS_DEFERRED_CALLBACKS) }, #undef T -- cgit v1.2.1 From b52c6498753262549bcf088e7c7836ddd4d50ce1 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 4 Nov 2018 19:48:11 +0300 Subject: cmake: do not detect _GNU_SOURCE/__GNU_LIBRARY__ if it is cached (cherry picked from commit 3ed93997387296e374d8a2dd770e43ddfa3328e9) --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 48885a32..ae0be78d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -256,7 +256,7 @@ if (SOLARIS) endif() # Check if _GNU_SOURCE is available. -if (NOT _GNU_SOURCE) +if (NOT DEFINED _GNU_SOURCE) CHECK_SYMBOL_EXISTS(__GNU_LIBRARY__ "features.h" _GNU_SOURCE) if (NOT _GNU_SOURCE) -- cgit v1.2.1 From f12cd17b7ca5e03a1bf37190719095eb60eaa291 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 5 Nov 2018 18:02:05 +0300 Subject: travis-ci: exclude appveyor branches (cherry picked from commit 0345adf7e43d0c776f73edf95b0648dbb43fdf52) --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index 61f3cc14..7186c36d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,10 @@ os: sudo: false dist: trusty +branches: + except: + - /.*appveyor.*/ + git: quiet: true -- cgit v1.2.1 From 35ca9643936b645fdc310a3bdea084145b28e701 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 5 Nov 2018 21:33:54 +0300 Subject: regress_http: disable http/read_on_write_error under win32 EVHTTP_CON_READ_ON_WRITE_ERROR works only if an error already read from the socket, but if we already got EPIPE on write we cannot read from the socket anymore, and win32 does not guarantee that read will happens before (although it happens from time to time). In the referenced patch I just replaced callback with not expecting 417, but like I already wrote, this is not always true (i.e. it is flacky). Fixes: 3b581693ac1967f7f8d98491cb772a1b415eb4cd ("test/http: read_on_write_error: fix it for win32") (cherry picked from commit 9040707fb176040acf250b09a223d6b4400f4086) --- test/regress_http.c | 8 -------- test/regress_main.c | 1 + 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/test/regress_http.c b/test/regress_http.c index bae5ea33..86120259 100644 --- a/test/regress_http.c +++ b/test/regress_http.c @@ -4025,7 +4025,6 @@ http_large_entity_test_done(struct evhttp_request *req, void *arg) end: event_base_loopexit(arg, NULL); } -#ifndef WIN32 static void http_expectation_failed_done(struct evhttp_request *req, void *arg) { @@ -4034,7 +4033,6 @@ http_expectation_failed_done(struct evhttp_request *req, void *arg) end: event_base_loopexit(arg, NULL); } -#endif static void http_data_length_constraints_test_impl(void *arg, int read_on_write_error) @@ -4051,10 +4049,8 @@ http_data_length_constraints_test_impl(void *arg, int read_on_write_error) test_ok = 0; cb = http_failed_request_done; -#ifndef WIN32 if (read_on_write_error) cb = http_data_length_constraints_test_done; -#endif tt_assert(continue_size < size); @@ -4098,10 +4094,8 @@ http_data_length_constraints_test_impl(void *arg, int read_on_write_error) } event_base_dispatch(data->base); -#ifndef WIN32 if (read_on_write_error) cb = http_large_entity_test_done; -#endif evhttp_set_max_body_size(http, size - 2); req = evhttp_request_new(cb, data->base); evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); @@ -4130,10 +4124,8 @@ http_data_length_constraints_test_impl(void *arg, int read_on_write_error) } event_base_dispatch(data->base); -#ifndef WIN32 if (read_on_write_error) cb = http_expectation_failed_done; -#endif req = evhttp_request_new(cb, data->base); evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); evhttp_add_header(evhttp_request_get_output_headers(req), "Expect", "101-continue"); diff --git a/test/regress_main.c b/test/regress_main.c index 094ff23b..a5fda7c5 100644 --- a/test/regress_main.c +++ b/test/regress_main.c @@ -435,6 +435,7 @@ main(int argc, const char **argv) #ifdef _WIN32 tinytest_skip(testgroups, "http/connection_retry"); tinytest_skip(testgroups, "http/https_connection_retry"); + tinytest_skip(testgroups, "http/read_on_write_error"); #endif #ifndef EVENT__DISABLE_THREAD_SUPPORT -- cgit v1.2.1 From 98d0f923302cac91f55c55d0bf9253fe85f9c45c Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 5 Nov 2018 22:25:15 +0300 Subject: regress_ssl: make ssl/bufferevent_wm_filter more fault-tolerance Due to inplace callbacks (i.e. no BEV_OPT_DEFER_CALLBACKS) we cannot be sure that wm_transfer() will not be called recursively and indeed it still happens sometimes, and the referenced patch increase amount of this times, especially for linux/poll. Fixes: 66304a23cf748714159c988e78f35401c5352827 ("Fix ssl/bufferevent_wm_filter when bev does not reach watermark on break") (cherry picked from commit 54c6fe3c06cb5342130467ecf0f78e3f6d854a36) --- test/regress_ssl.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/regress_ssl.c b/test/regress_ssl.c index 5b2dce87..88010a92 100644 --- a/test/regress_ssl.c +++ b/test/regress_ssl.c @@ -816,16 +816,16 @@ wm_transfer(struct bufferevent *bev, void *arg) size_t len = evbuffer_get_length(in); size_t drain = len < ctx->to_read ? len : ctx->to_read; - if (ctx->get+drain >= ctx->limit) { + if (ctx->get >= ctx->limit) { TT_BLATHER(("wm_transfer-%s(%p): break", ctx->server ? "server" : "client", bev)); bufferevent_setcb(bev, NULL, NULL, NULL, NULL); bufferevent_disable(bev, EV_READ); + } else { + evbuffer_drain(in, drain); + ctx->get += drain; } - evbuffer_drain(in, drain); - ctx->get += drain; - TT_BLATHER(("wm_transfer-%s(%p): " "in: " EV_SIZE_FMT ", " "out: " EV_SIZE_FMT ", " -- cgit v1.2.1 From b021b979a15b230b783c2b255a008270801365d4 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 5 Nov 2018 22:58:25 +0300 Subject: travis: use homebrew via addon (-~4min/16% from the build time) (cherry picked from commit 58e853f2c54dca223cd2d42665e74c2208c84cf1) --- .travis.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7186c36d..7451995a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -45,10 +45,6 @@ before_install: - export JOBS=20 - export TIMEOUT=50 - if [ "$TRAVIS_OS_NAME" == "osx" ]; then - brew update; - brew uninstall libtool && brew install libtool; - brew install openssl; - brew install lcov; if [ "$CC" == "gcc" ]; then export CC=$(ls -t /usr/local/bin/gcc-?.?); fi @@ -77,6 +73,12 @@ addons: - autoconf - cmake - lcov + homebrew: + packages: + - openssl + - lcov + - libtool + script: - if [ "$EVENT_BUILD_METHOD" = "autotools" ]; then -- cgit v1.2.1 From 3d3d1e0530827e7d360e9b15e70524aa52db690b Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 5 Nov 2018 18:23:31 +0300 Subject: cmake: set CMP0074 to NEW (for OPENSSL_ROOT in appveyor) We have $env:OPENSSL_ROOT (env) equals to -DOPENSSL_ROOT (cmake variable) anyway. cmake complains: Policy CMP0074 is not set: find_package uses _ROOT variables. Run "cmake --help-policy CMP0074" for policy details. Use the cmake_policy command to set the policy and suppress this warning. Environment variable OpenSSL_ROOT is set to: C:/OpenSSL-Win64/bin For compatibility, CMake is ignoring the variable. This warning is for project developers. Use -Wno-dev to suppress it. (cherry picked from commit 65904773f2bf965e2050d4d7c91e30d4f123a787) --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index ae0be78d..ac128ed6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,9 @@ endif() if (POLICY CMP0054) cmake_policy(SET CMP0054 NEW) endif() +if (POLICY CMP0074) + cmake_policy(SET CMP0074 NEW) +endif() if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release -- cgit v1.2.1 From 5e5de36f85b50beece099333fe69a5c386fd9032 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 5 Nov 2018 18:30:38 +0300 Subject: cmake: set CMP0075 to NEW (for ws2_32.lib in win32) Otherwise cmake complains: Policy CMP0075 is not set: Include file check macros honor CMAKE_REQUIRED_LIBRARIES. Run "cmake --help-policy CMP0075" for policy details. Use the cmake_policy command to set the policy and suppress this warning. CMAKE_REQUIRED_LIBRARIES is set to: ws2_32.lib For compatibility with CMake 3.11 and below this check is ignoring it. (cherry picked from commit 6d3a53966bc822fd580a6a02301838aca601391b) --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index ac128ed6..a82d6f57 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,9 @@ endif() if (POLICY CMP0074) cmake_policy(SET CMP0074 NEW) endif() +if (POLICY CMP0075) + cmake_policy(SET CMP0075 NEW) +endif() if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release -- cgit v1.2.1 From e7292a59e829f5619e1e4f8b2e991cb76c0ef65a Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 5 Nov 2018 18:00:41 +0300 Subject: appveyor: do not run on branches that has "travis" in it's name (cherry picked from commit 1503a9a1a6aea641784fa7aae83ad00e57e35431) --- appveyor.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index 973625d7..c3b3e3f3 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -5,6 +5,10 @@ os: Visual Studio 2015 build: verbosity: detailed +branches: + except: + - /.*travis.*/ + environment: global: CYG_ROOT: C:/MinGW/msys/1.0 -- cgit v1.2.1 From 2ffa59da04a588f96afb8050fb57f2c190ebc9d6 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 6 Nov 2018 01:22:13 +0300 Subject: appveyor: disable verbosity (cherry picked from commit 506189350889dd7270801f3383524eb2acbfb862) --- appveyor.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index c3b3e3f3..f51e9afa 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,9 +2,6 @@ version: 2.1.8.{build} os: Visual Studio 2015 -build: - verbosity: detailed - branches: except: - /.*travis.*/ -- cgit v1.2.1 From cb8b6f17b25569a182d35d36f9c933eef151ccda Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 5 Nov 2018 17:04:47 +0300 Subject: appveyor: cache build directory to reduce overall time (6x time faster) various build checks (i.e. detecting headers/macroses/functions) takes 7 minutes (from 13 minutes in total) for cmake, which is too high. By using cache we can reduce this to ~0. And set APPVEYOR_SAVE_CACHE_ON_ERROR so that cmake checks will be cached (anyway all sources will be built from scratch due to timestamp updates while extracting from sources). (cherry picked from commit 54fdd6bb6ebe6b0a672c79d30a712d97536500c8) --- appveyor.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index f51e9afa..81fbe3da 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -8,6 +8,7 @@ branches: environment: global: + APPVEYOR_SAVE_CACHE_ON_ERROR: true CYG_ROOT: C:/MinGW/msys/1.0 EVENT_TESTS_PARALLEL: 20 matrix: @@ -67,16 +68,20 @@ build_script: bash -lc "echo 'C:\MinGW /mingw' > /etc/fstab" bash -lc "echo 'C:\OpenSSL-Win32 /ssl' >> /etc/fstab" $env:APPVEYOR_BUILD_FOLDER = $env:APPVEYOR_BUILD_FOLDER -replace "\\", "/" - bash -lc "exec 0&1; cd $env:APPVEYOR_BUILD_FOLDER; bash -x ./autogen.sh && ./configure LDFLAGS='-L/ssl -L/ssl/lib -L/ssl/lib/MinGW' CFLAGS=-I/ssl/include $env:EVENT_CONFIGURE_OPTIONS && make && make verify -j$env:EVENT_TESTS_PARALLEL" + bash -lc "exec 0&1; cd $env:APPVEYOR_BUILD_FOLDER; bash -x ./autogen.sh && mkdir -p build-autotools && cd build-autotools && ../configure LDFLAGS='-L/ssl -L/ssl/lib -L/ssl/lib/MinGW' CFLAGS=-I/ssl/include $env:EVENT_CONFIGURE_OPTIONS && make && make verify -j$env:EVENT_TESTS_PARALLEL" } else { - md build - cd build + md build-cmake 2> $null + cd build-cmake cmake .. $env:EVENT_CMAKE_OPTIONS cmake --build . $env:CTEST_PARALLEL_LEVEL=$env:EVENT_TESTS_PARALLEL ctest --output-on-failure } +cache: + - build-cmake + - build-autotools + on_failure: - 7z a libevent.zip . - appveyor PushArtifact libevent.zip -- cgit v1.2.1 From 1b6ce89bd857028ff7931dc564a106ba38e7643a Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 6 Nov 2018 11:30:18 +0300 Subject: appveyor: skip travis patches (by commit subject/files) (cherry picked from commit 9afe7a6c12c112a6cbc49cf1bd684781275b2579) --- appveyor.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index 81fbe3da..1ba6770c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -5,6 +5,10 @@ os: Visual Studio 2015 branches: except: - /.*travis.*/ +skip_commits: + message: /travis/ + files: + - .travis.yml environment: global: -- cgit v1.2.1 From 3bc602c2616e63728a97b9a892f644639d9c0d46 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Thu, 8 Nov 2018 00:36:07 +0300 Subject: regress_ssl: fix ssl/bufferevent_wm_filter for non defered callbacks Even after referenced patch there is still possible recursive callbacks from evbuffer_drain(bev_input), i.e.: wm_transfer() -> evbuffer_drain() -> wm_transfer() inc(ctx->get) But if we will increment ctx->get before drain that we will not add more data to buffer. Refs: 54c6fe3c ("regress_ssl: make ssl/bufferevent_wm_filter more fault-tolerance") CI: https://ci.appveyor.com/project/nmathewson/libevent/build/job/f0rv299i71wnuxdq#L2546 (cherry picked from commit 1fc1c7ef1dabbbb358b99b893712bccc5761f82d) --- test/regress_ssl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/regress_ssl.c b/test/regress_ssl.c index 88010a92..45ce540d 100644 --- a/test/regress_ssl.c +++ b/test/regress_ssl.c @@ -822,8 +822,8 @@ wm_transfer(struct bufferevent *bev, void *arg) bufferevent_setcb(bev, NULL, NULL, NULL, NULL); bufferevent_disable(bev, EV_READ); } else { - evbuffer_drain(in, drain); ctx->get += drain; + evbuffer_drain(in, drain); } TT_BLATHER(("wm_transfer-%s(%p): " -- cgit v1.2.1 From b6309bccfc9e40b4c3f9684d1148642d2a059e76 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 13 Nov 2018 11:10:25 +0300 Subject: Merge branch 'sample-http-server' Some improvements for http-server sample: - getopt - persistent port via -p option - IOCP for win32 via -I - disable buffering - enable debug logging via -v/EVENT_DEBUG_LOGGING_ALL - cleanup (by signal and separate error path on errors) * sample-http-server: s/http-server: graceful cleanup s/http-server: enable debug logging if EVENT_DEBUG_LOGGING_ALL env isset s/http-server: turn off buffering (otherwise do output on win32) s/http-server: add an option to use IOCP s/http-server: add options (for persistent port) Refs: #709 (cherry picked from commit 9a4b8ec1b64fab27544f154076261afdf1efac07) --- CMakeLists.txt | 9 +++- sample/http-server.c | 131 +++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 113 insertions(+), 27 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a82d6f57..d8651609 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -888,7 +888,6 @@ if (NOT EVENT__DISABLE_SAMPLES) event-read-fifo hello-world signal-test - http-server http-connect time-test) @@ -905,7 +904,13 @@ if (NOT EVENT__DISABLE_SAMPLES) sample/le-proxy.c) endif() - add_sample_prog(OFF dns-example sample/dns-example.c ${WIN32_GETOPT}) + set(SAMPLES_WOPT + dns-example + http-server + ) + foreach (SAMPLE ${SAMPLES_WOPT}) + add_sample_prog(OFF ${SAMPLE} sample/${SAMPLE}.c ${WIN32_GETOPT}) + endforeach() endif() # diff --git a/sample/http-server.c b/sample/http-server.c index 579feea6..bb067fb8 100644 --- a/sample/http-server.c +++ b/sample/http-server.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #ifndef S_ISDIR @@ -28,11 +29,11 @@ #else #include #include -#include #include #include #include #endif +#include #include #include @@ -40,6 +41,10 @@ #include #include +#ifdef _WIN32 +#include +#endif + #ifdef EVENT__HAVE_NETINET_IN_H #include # ifdef _XOPEN_SOURCE_EXTENDED @@ -86,6 +91,13 @@ static const struct table_entry { { NULL, NULL }, }; +struct options +{ + int port; + int iocp; + int verbose; +}; + /* Try to guess a good content-type for 'path' */ static const char * guess_content_type(const char *path) @@ -320,43 +332,93 @@ done: evbuffer_free(evb); } +static struct options +parse_opts(int argc, char **argv) +{ + struct options o; + int opt; + + memset(&o, 0, sizeof(o)); + + while ((opt = getopt(argc, argv, "p:Iv")) != -1) { + switch (opt) { + case 'p': o.port = atoi(optarg); break; + case 'I': o.iocp = 1; break; + case 'v': ++o.verbose; break; + default : fprintf(stderr, "Unknown option %c\n", opt); break; + } + } + + if (optind >= argc || (argc-optind) > 1) { + fprintf(stdout, "Syntax: %s \n", argv[0]); + exit(1); + } + + return o; +} + static void -syntax(void) +do_term(int sig, short events, void *arg) { - fprintf(stdout, "Syntax: http-server \n"); + struct event_base *base = arg; + event_base_loopbreak(base); + fprintf(stderr, "Got %i, Terminating\n", sig); } int main(int argc, char **argv) { - struct event_base *base; - struct evhttp *http; - struct evhttp_bound_socket *handle; + struct event_config *cfg = NULL; + struct event_base *base = NULL; + struct evhttp *http = NULL; + struct evhttp_bound_socket *handle = NULL; + struct event *term = NULL; + struct options o = parse_opts(argc, argv); + int ret = 0; - ev_uint16_t port = 0; #ifdef _WIN32 - WSADATA WSAData; - WSAStartup(0x101, &WSAData); + { + WORD wVersionRequested; + WSADATA wsaData; + wVersionRequested = MAKEWORD(2, 2); + WSAStartup(wVersionRequested, &wsaData); + } #else - if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) - return (1); + if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) { + ret = 1; + goto err; + } #endif - if (argc < 2) { - syntax(); - return 1; + + setbuf(stdout, NULL); + setbuf(stderr, NULL); + + /** Read env like in regress" */ + if (o.verbose || getenv("EVENT_DEBUG_LOGGING_ALL")) + event_enable_debug_logging(EVENT_DBG_ALL); + + cfg = event_config_new(); +#ifdef _WIN32 + if (o.iocp) { + evthread_use_windows_threads(); + event_config_set_flag(cfg, EVENT_BASE_FLAG_STARTUP_IOCP); + event_config_set_num_cpus_hint(cfg, 8); } +#endif - base = event_base_new(); + base = event_base_new_with_config(cfg); if (!base) { fprintf(stderr, "Couldn't create an event_base: exiting\n"); - return 1; + ret = 1; } + event_config_free(cfg); + cfg = NULL; /* Create a new evhttp object to handle requests. */ http = evhttp_new(base); if (!http) { fprintf(stderr, "couldn't create evhttp. Exiting.\n"); - return 1; + ret = 1; } /* The /dump URI will dump all requests to stdout and say 200 ok. */ @@ -367,11 +429,10 @@ main(int argc, char **argv) evhttp_set_gencb(http, send_document_cb, argv[1]); /* Now we tell the evhttp what port to listen on */ - handle = evhttp_bind_socket_with_handle(http, "0.0.0.0", port); + handle = evhttp_bind_socket_with_handle(http, "0.0.0.0", o.port); if (!handle) { - fprintf(stderr, "couldn't bind to port %d. Exiting.\n", - (int)port); - return 1; + fprintf(stderr, "couldn't bind to port %d. Exiting.\n", o.port); + ret = 1; } { @@ -387,7 +448,7 @@ main(int argc, char **argv) memset(&ss, 0, sizeof(ss)); if (getsockname(fd, (struct sockaddr *)&ss, &socklen)) { perror("getsockname() failed"); - return 1; + ret = 1; } if (ss.ss_family == AF_INET) { got_port = ntohs(((struct sockaddr_in*)&ss)->sin_port); @@ -398,7 +459,7 @@ main(int argc, char **argv) } else { fprintf(stderr, "Weird address family %d\n", ss.ss_family); - return 1; + ret = 1; } addr = evutil_inet_ntop(ss.ss_family, inaddr, addrbuf, sizeof(addrbuf)); @@ -408,11 +469,31 @@ main(int argc, char **argv) "http://%s:%d",addr,got_port); } else { fprintf(stderr, "evutil_inet_ntop failed\n"); - return 1; + ret = 1; } } + term = evsignal_new(base, SIGINT, do_term, base); + if (!term) + goto err; + if (event_add(term, NULL)) + goto err; + event_base_dispatch(base); - return 0; +#ifdef _WIN32 + WSACleanup(); +#endif + +err: + if (cfg) + event_config_free(cfg); + if (http) + evhttp_free(http); + if (term) + event_free(term); + if (base) + event_base_free(base); + + return ret; } -- cgit v1.2.1 From ca69a10f4cce761209e6c84274445f3b9d808f5b Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 13 Nov 2018 08:24:55 +0300 Subject: event: add some debug information into loop for event_base_free_queues_() Refs: 7c8d0152dda18ecc52d3099fea235b04ddb850d9 ("Free event queues even for recursive finalizers") (cherry picked from commit f2da6198401e2ef6763e5acc5d4e51a9928b9dde) --- event.c | 1 + 1 file changed, 1 insertion(+) diff --git a/event.c b/event.c index 5ee7d81b..4f4c9d77 100644 --- a/event.c +++ b/event.c @@ -903,6 +903,7 @@ event_base_free_(struct event_base *base, int run_finalizers) * A simple case is bufferevent with underlying (i.e. filters). */ int i = event_base_free_queues_(base, run_finalizers); + event_debug(("%s: %d events freed", __func__, i)); if (!i) { break; } -- cgit v1.2.1 From 91bb15e63ed92ed64e85f3689c90940f7c6ae591 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 13 Nov 2018 09:25:13 +0300 Subject: regress: add EVENT_NO_FILE_BUFFERING, to disable buffering for stdout/stderr Useful for win32 (cherry picked from commit b2d4fb4176c645b45b8514e4a5a942228ea4e6a9) --- test/regress_main.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/regress_main.c b/test/regress_main.c index a5fda7c5..d3c6c3ce 100644 --- a/test/regress_main.c +++ b/test/regress_main.c @@ -455,6 +455,11 @@ main(int argc, const char **argv) evutil_weakrand_seed_(&test_weakrand_state, 0); + if (getenv("EVENT_NO_FILE_BUFFERING")) { + setbuf(stdout, NULL); + setbuf(stderr, NULL); + } + if (tinytest_main(argc,argv,testgroups)) return 1; -- cgit v1.2.1 From 74517b2a11b630970c88c063b1afec1e9ece9d0f Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Fri, 30 Nov 2018 22:25:41 +0300 Subject: Use BEV_UPCASE() everywhere Done with coccinelle and manual line rewrap: $ cat > BEV_UPCAST.cocci @@ expression field_; expression var; @@ - EVUTIL_UPCAST(var, struct bufferevent_private, field_) + BEV_UPCAST(var) $ spatch --sp-file BEV_UPCASE.cocci --in-place bufferevent*.c > /dev/null (cherry picked from commit 7bcf576b396b22f218074c446691526a3ce509a6) --- bufferevent.c | 48 ++++++++++++++++-------------------------------- bufferevent_ratelim.c | 9 +++------ bufferevent_sock.c | 43 ++++++++++++++----------------------------- 3 files changed, 33 insertions(+), 67 deletions(-) diff --git a/bufferevent.c b/bufferevent.c index 89ad6e2b..f7f97bcf 100644 --- a/bufferevent.c +++ b/bufferevent.c @@ -66,8 +66,7 @@ static void bufferevent_finalize_cb_(struct event_callback *evcb, void *arg_); void bufferevent_suspend_read_(struct bufferevent *bufev, bufferevent_suspend_flags what) { - struct bufferevent_private *bufev_private = - EVUTIL_UPCAST(bufev, struct bufferevent_private, bev); + struct bufferevent_private *bufev_private = BEV_UPCAST(bufev); BEV_LOCK(bufev); if (!bufev_private->read_suspended) bufev->be_ops->disable(bufev, EV_READ); @@ -78,8 +77,7 @@ bufferevent_suspend_read_(struct bufferevent *bufev, bufferevent_suspend_flags w void bufferevent_unsuspend_read_(struct bufferevent *bufev, bufferevent_suspend_flags what) { - struct bufferevent_private *bufev_private = - EVUTIL_UPCAST(bufev, struct bufferevent_private, bev); + struct bufferevent_private *bufev_private = BEV_UPCAST(bufev); BEV_LOCK(bufev); bufev_private->read_suspended &= ~what; if (!bufev_private->read_suspended && (bufev->enabled & EV_READ)) @@ -90,8 +88,7 @@ bufferevent_unsuspend_read_(struct bufferevent *bufev, bufferevent_suspend_flags void bufferevent_suspend_write_(struct bufferevent *bufev, bufferevent_suspend_flags what) { - struct bufferevent_private *bufev_private = - EVUTIL_UPCAST(bufev, struct bufferevent_private, bev); + struct bufferevent_private *bufev_private = BEV_UPCAST(bufev); BEV_LOCK(bufev); if (!bufev_private->write_suspended) bufev->be_ops->disable(bufev, EV_WRITE); @@ -102,8 +99,7 @@ bufferevent_suspend_write_(struct bufferevent *bufev, bufferevent_suspend_flags void bufferevent_unsuspend_write_(struct bufferevent *bufev, bufferevent_suspend_flags what) { - struct bufferevent_private *bufev_private = - EVUTIL_UPCAST(bufev, struct bufferevent_private, bev); + struct bufferevent_private *bufev_private = BEV_UPCAST(bufev); BEV_LOCK(bufev); bufev_private->write_suspended &= ~what; if (!bufev_private->write_suspended && (bufev->enabled & EV_WRITE)) @@ -245,8 +241,7 @@ void bufferevent_run_readcb_(struct bufferevent *bufev, int options) { /* Requires that we hold the lock and a reference */ - struct bufferevent_private *p = - EVUTIL_UPCAST(bufev, struct bufferevent_private, bev); + struct bufferevent_private *p = BEV_UPCAST(bufev); if (bufev->readcb == NULL) return; if ((p->options|options) & BEV_OPT_DEFER_CALLBACKS) { @@ -262,8 +257,7 @@ void bufferevent_run_writecb_(struct bufferevent *bufev, int options) { /* Requires that we hold the lock and a reference */ - struct bufferevent_private *p = - EVUTIL_UPCAST(bufev, struct bufferevent_private, bev); + struct bufferevent_private *p = BEV_UPCAST(bufev); if (bufev->writecb == NULL) return; if ((p->options|options) & BEV_OPT_DEFER_CALLBACKS) { @@ -291,8 +285,7 @@ void bufferevent_run_eventcb_(struct bufferevent *bufev, short what, int options) { /* Requires that we hold the lock and a reference */ - struct bufferevent_private *p = - EVUTIL_UPCAST(bufev, struct bufferevent_private, bev); + struct bufferevent_private *p = BEV_UPCAST(bufev); if (bufev->errorcb == NULL) return; if ((p->options|options) & BEV_OPT_DEFER_CALLBACKS) { @@ -484,8 +477,7 @@ bufferevent_read_buffer(struct bufferevent *bufev, struct evbuffer *buf) int bufferevent_enable(struct bufferevent *bufev, short event) { - struct bufferevent_private *bufev_private = - EVUTIL_UPCAST(bufev, struct bufferevent_private, bev); + struct bufferevent_private *bufev_private = BEV_UPCAST(bufev); short impl_events = event; int r = 0; @@ -558,8 +550,7 @@ int bufferevent_disable_hard_(struct bufferevent *bufev, short event) { int r = 0; - struct bufferevent_private *bufev_private = - EVUTIL_UPCAST(bufev, struct bufferevent_private, bev); + struct bufferevent_private *bufev_private = BEV_UPCAST(bufev); BEV_LOCK(bufev); bufev->enabled &= ~event; @@ -595,8 +586,7 @@ void bufferevent_setwatermark(struct bufferevent *bufev, short events, size_t lowmark, size_t highmark) { - struct bufferevent_private *bufev_private = - EVUTIL_UPCAST(bufev, struct bufferevent_private, bev); + struct bufferevent_private *bufev_private = BEV_UPCAST(bufev); BEV_LOCK(bufev); if (events & EV_WRITE) { @@ -681,8 +671,7 @@ bufferevent_flush(struct bufferevent *bufev, void bufferevent_incref_and_lock_(struct bufferevent *bufev) { - struct bufferevent_private *bufev_private = - BEV_UPCAST(bufev); + struct bufferevent_private *bufev_private = BEV_UPCAST(bufev); BEV_LOCK(bufev); ++bufev_private->refcnt; } @@ -708,8 +697,7 @@ bufferevent_transfer_lock_ownership_(struct bufferevent *donor, int bufferevent_decref_and_unlock_(struct bufferevent *bufev) { - struct bufferevent_private *bufev_private = - EVUTIL_UPCAST(bufev, struct bufferevent_private, bev); + struct bufferevent_private *bufev_private = BEV_UPCAST(bufev); int n_cbs = 0; #define MAX_CBS 16 struct event_callback *cbs[MAX_CBS]; @@ -752,8 +740,7 @@ bufferevent_finalize_cb_(struct event_callback *evcb, void *arg_) { struct bufferevent *bufev = arg_; struct bufferevent *underlying; - struct bufferevent_private *bufev_private = - EVUTIL_UPCAST(bufev, struct bufferevent_private, bev); + struct bufferevent_private *bufev_private = BEV_UPCAST(bufev); BEV_LOCK(bufev); underlying = bufferevent_get_underlying(bufev); @@ -819,8 +806,7 @@ bufferevent_free(struct bufferevent *bufev) void bufferevent_incref(struct bufferevent *bufev) { - struct bufferevent_private *bufev_private = - EVUTIL_UPCAST(bufev, struct bufferevent_private, bev); + struct bufferevent_private *bufev_private = BEV_UPCAST(bufev); /* XXX: now that this function is public, we might want to * - return the count from this function @@ -896,8 +882,7 @@ bufferevent_getfd(struct bufferevent *bev) enum bufferevent_options bufferevent_get_options_(struct bufferevent *bev) { - struct bufferevent_private *bev_p = - EVUTIL_UPCAST(bev, struct bufferevent_private, bev); + struct bufferevent_private *bev_p = BEV_UPCAST(bev); enum bufferevent_options options; BEV_LOCK(bev); @@ -973,8 +958,7 @@ int bufferevent_generic_adj_timeouts_(struct bufferevent *bev) { const short enabled = bev->enabled; - struct bufferevent_private *bev_p = - EVUTIL_UPCAST(bev, struct bufferevent_private, bev); + struct bufferevent_private *bev_p = BEV_UPCAST(bev); int r1=0, r2=0; if ((enabled & EV_READ) && !bev_p->read_suspended && evutil_timerisset(&bev->timeout_read)) diff --git a/bufferevent_ratelim.c b/bufferevent_ratelim.c index bde19202..25874968 100644 --- a/bufferevent_ratelim.c +++ b/bufferevent_ratelim.c @@ -560,8 +560,7 @@ int bufferevent_set_rate_limit(struct bufferevent *bev, struct ev_token_bucket_cfg *cfg) { - struct bufferevent_private *bevp = - EVUTIL_UPCAST(bev, struct bufferevent_private, bev); + struct bufferevent_private *bevp = BEV_UPCAST(bev); int r = -1; struct bufferevent_rate_limit *rlim; struct timeval now; @@ -737,8 +736,7 @@ bufferevent_add_to_rate_limit_group(struct bufferevent *bev, struct bufferevent_rate_limit_group *g) { int wsuspend, rsuspend; - struct bufferevent_private *bevp = - EVUTIL_UPCAST(bev, struct bufferevent_private, bev); + struct bufferevent_private *bevp = BEV_UPCAST(bev); BEV_LOCK(bev); if (!bevp->rate_limiting) { @@ -789,8 +787,7 @@ int bufferevent_remove_from_rate_limit_group_internal_(struct bufferevent *bev, int unsuspend) { - struct bufferevent_private *bevp = - EVUTIL_UPCAST(bev, struct bufferevent_private, bev); + struct bufferevent_private *bevp = BEV_UPCAST(bev); BEV_LOCK(bev); if (bevp->rate_limiting && bevp->rate_limiting->group) { struct bufferevent_rate_limit_group *g = diff --git a/bufferevent_sock.c b/bufferevent_sock.c index c878aa95..48d6c7e9 100644 --- a/bufferevent_sock.c +++ b/bufferevent_sock.c @@ -99,17 +99,14 @@ const struct bufferevent_ops bufferevent_ops_socket = { const struct sockaddr* bufferevent_socket_get_conn_address_(struct bufferevent *bev) { - struct bufferevent_private *bev_p = - EVUTIL_UPCAST(bev, struct bufferevent_private, bev); - + struct bufferevent_private *bev_p = BEV_UPCAST(bev); return (struct sockaddr *)&bev_p->conn_address; } void bufferevent_socket_set_conn_address_fd_(struct bufferevent *bev, int fd) { - struct bufferevent_private *bev_p = - EVUTIL_UPCAST(bev, struct bufferevent_private, bev); + struct bufferevent_private *bev_p = BEV_UPCAST(bev); socklen_t len = sizeof(bev_p->conn_address); @@ -122,8 +119,7 @@ void bufferevent_socket_set_conn_address_(struct bufferevent *bev, struct sockaddr *addr, size_t addrlen) { - struct bufferevent_private *bev_p = - EVUTIL_UPCAST(bev, struct bufferevent_private, bev); + struct bufferevent_private *bev_p = BEV_UPCAST(bev); EVUTIL_ASSERT(addrlen <= sizeof(bev_p->conn_address)); memcpy(&bev_p->conn_address, addr, addrlen); } @@ -134,8 +130,7 @@ bufferevent_socket_outbuf_cb(struct evbuffer *buf, void *arg) { struct bufferevent *bufev = arg; - struct bufferevent_private *bufev_p = - EVUTIL_UPCAST(bufev, struct bufferevent_private, bev); + struct bufferevent_private *bufev_p = BEV_UPCAST(bufev); if (cbinfo->n_added && (bufev->enabled & EV_WRITE) && @@ -153,8 +148,7 @@ static void bufferevent_readcb(evutil_socket_t fd, short event, void *arg) { struct bufferevent *bufev = arg; - struct bufferevent_private *bufev_p = - EVUTIL_UPCAST(bufev, struct bufferevent_private, bev); + struct bufferevent_private *bufev_p = BEV_UPCAST(bufev); struct evbuffer *input; int res = 0; short what = BEV_EVENT_READING; @@ -235,8 +229,7 @@ static void bufferevent_writecb(evutil_socket_t fd, short event, void *arg) { struct bufferevent *bufev = arg; - struct bufferevent_private *bufev_p = - EVUTIL_UPCAST(bufev, struct bufferevent_private, bev); + struct bufferevent_private *bufev_p = BEV_UPCAST(bufev); int res = 0; short what = BEV_EVENT_WRITING; int connected = 0; @@ -386,8 +379,7 @@ int bufferevent_socket_connect(struct bufferevent *bev, const struct sockaddr *sa, int socklen) { - struct bufferevent_private *bufev_p = - EVUTIL_UPCAST(bev, struct bufferevent_private, bev); + struct bufferevent_private *bufev_p = BEV_UPCAST(bev); evutil_socket_t fd; int r = 0; @@ -465,8 +457,7 @@ bufferevent_connect_getaddrinfo_cb(int result, struct evutil_addrinfo *ai, void *arg) { struct bufferevent *bev = arg; - struct bufferevent_private *bev_p = - EVUTIL_UPCAST(bev, struct bufferevent_private, bev); + struct bufferevent_private *bev_p = BEV_UPCAST(bev); int r; BEV_LOCK(bev); @@ -504,8 +495,7 @@ bufferevent_socket_connect_hostname(struct bufferevent *bev, { char portbuf[10]; struct evutil_addrinfo hint; - struct bufferevent_private *bev_p = - EVUTIL_UPCAST(bev, struct bufferevent_private, bev); + struct bufferevent_private *bev_p = BEV_UPCAST(bev); if (family != AF_INET && family != AF_INET6 && family != AF_UNSPEC) return -1; @@ -537,8 +527,7 @@ int bufferevent_socket_get_dns_error(struct bufferevent *bev) { int rv; - struct bufferevent_private *bev_p = - EVUTIL_UPCAST(bev, struct bufferevent_private, bev); + struct bufferevent_private *bev_p = BEV_UPCAST(bev); BEV_LOCK(bev); rv = bev_p->dns_error; @@ -589,8 +578,7 @@ be_socket_enable(struct bufferevent *bufev, short event) static int be_socket_disable(struct bufferevent *bufev, short event) { - struct bufferevent_private *bufev_p = - EVUTIL_UPCAST(bufev, struct bufferevent_private, bev); + struct bufferevent_private *bufev_p = BEV_UPCAST(bufev); if (event & EV_READ) { if (event_del(&bufev->ev_read) == -1) return -1; @@ -606,8 +594,7 @@ be_socket_disable(struct bufferevent *bufev, short event) static void be_socket_destruct(struct bufferevent *bufev) { - struct bufferevent_private *bufev_p = - EVUTIL_UPCAST(bufev, struct bufferevent_private, bev); + struct bufferevent_private *bufev_p = BEV_UPCAST(bufev); evutil_socket_t fd; EVUTIL_ASSERT(BEV_IS_SOCKET(bufev)); @@ -630,8 +617,7 @@ be_socket_flush(struct bufferevent *bev, short iotype, static void be_socket_setfd(struct bufferevent *bufev, evutil_socket_t fd) { - struct bufferevent_private *bufev_p = - EVUTIL_UPCAST(bufev, struct bufferevent_private, bev); + struct bufferevent_private *bufev_p = BEV_UPCAST(bufev); BEV_LOCK(bufev); EVUTIL_ASSERT(BEV_IS_SOCKET(bufev)); @@ -660,8 +646,7 @@ int bufferevent_priority_set(struct bufferevent *bufev, int priority) { int r = -1; - struct bufferevent_private *bufev_p = - EVUTIL_UPCAST(bufev, struct bufferevent_private, bev); + struct bufferevent_private *bufev_p = BEV_UPCAST(bufev); BEV_LOCK(bufev); if (!BEV_IS_SOCKET(bufev)) -- cgit v1.2.1 From 6ac2ec2500e004b9169bd6987e49572dc4685262 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 13 Nov 2018 21:26:12 +0300 Subject: Fix conceivable UAF of the bufferevent in evhttp_connection_free() Although this is not a problem, since bufferevent uses finalizers and will free itself only from the loop (well this is not a problem if you do not play games with various event_base in different threads) it generates questions, so rewrite it in more reliable way. Fixes: #712 (cherry picked from commit 5dc88b387f7baa4bcd528832e94987a85be3b263) --- http.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/http.c b/http.c index f7c6490f..8677bba1 100644 --- a/http.c +++ b/http.c @@ -1203,6 +1203,7 @@ void evhttp_connection_free(struct evhttp_connection *evcon) { struct evhttp_request *req; + int need_close = 0; /* notify interested parties that this connection is going down */ if (evcon->fd != -1) { @@ -1229,21 +1230,22 @@ evhttp_connection_free(struct evhttp_connection *evcon) event_debug_unassign(&evcon->retry_ev); } - if (evcon->bufev != NULL) - bufferevent_free(evcon->bufev); - event_deferred_cb_cancel_(get_deferred_queue(evcon), &evcon->read_more_deferred_cb); - if (evcon->fd == -1) - evcon->fd = bufferevent_getfd(evcon->bufev); + if (evcon->bufev != NULL) { + need_close = + !(bufferevent_get_options_(evcon->bufev) & BEV_OPT_CLOSE_ON_FREE); + if (evcon->fd == -1) + evcon->fd = bufferevent_getfd(evcon->bufev); + + bufferevent_free(evcon->bufev); + } if (evcon->fd != -1) { - bufferevent_disable(evcon->bufev, EV_READ|EV_WRITE); shutdown(evcon->fd, EVUTIL_SHUT_WR); - if (!(bufferevent_get_options_(evcon->bufev) & BEV_OPT_CLOSE_ON_FREE)) { + if (need_close) evutil_closesocket(evcon->fd); - } } if (evcon->bind_address != NULL) -- cgit v1.2.1 From 6bfac964e7d960c2715e1b0df84605635ff7c785 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 13 Nov 2018 22:47:43 +0300 Subject: Merge branch 'iocp-fixes' * iocp-fixes: regress: test for HTTP/HTTPS with IOCP enabled bev_async: trigger/run only deferred callbacks bev_async: do not initialize timeouts multiple times bev_async: set "ok" on setfd if fd>=0 (like we do during creation) bev_async: ignore ERROR_INVALID_PARAMETER on .setfd for iocp Closes: #709 Refs: nmathewson/Libevent#160 (cherry picked from commit 3d815cf22074792f31274fd6d810a94984661dbf) --- bufferevent_async.c | 55 +++++++++++++++++++++++++++++++++++------------------ test/regress.h | 1 + test/regress_http.c | 5 +++++ test/regress_main.c | 1 + 4 files changed, 44 insertions(+), 18 deletions(-) diff --git a/bufferevent_async.c b/bufferevent_async.c index 1521d896..d2eefed4 100644 --- a/bufferevent_async.c +++ b/bufferevent_async.c @@ -100,6 +100,27 @@ const struct bufferevent_ops bufferevent_ops_async = { be_async_ctrl, }; +static inline void +be_async_run_eventcb(struct bufferevent *bev, short what, int options) +{ bufferevent_run_eventcb_(bev, what, options|BEV_TRIG_DEFER_CALLBACKS); } + +static inline void +be_async_trigger_nolock(struct bufferevent *bev, short what, int options) +{ bufferevent_trigger_nolock_(bev, what, options|BEV_TRIG_DEFER_CALLBACKS); } + +static inline int +fatal_error(int err) +{ + switch (err) { + /* We may have already associated this fd with a port. + * Let's hope it's this port, and that the error code + * for doing this neer changes. */ + case ERROR_INVALID_PARAMETER: + return 0; + } + return 1; +} + static inline struct bufferevent_async * upcast(struct bufferevent *bev) { @@ -217,7 +238,7 @@ bev_async_consider_writing(struct bufferevent_async *beva) &beva->write_overlapped)) { bufferevent_decref_(bev); beva->ok = 0; - bufferevent_run_eventcb_(bev, BEV_EVENT_ERROR, 0); + be_async_run_eventcb(bev, BEV_EVENT_ERROR, 0); } else { beva->write_in_progress = at_most; bufferevent_decrement_write_buckets_(&beva->bev, at_most); @@ -270,7 +291,7 @@ bev_async_consider_reading(struct bufferevent_async *beva) bufferevent_incref_(bev); if (evbuffer_launch_read_(bev->input, at_most, &beva->read_overlapped)) { beva->ok = 0; - bufferevent_run_eventcb_(bev, BEV_EVENT_ERROR, 0); + be_async_run_eventcb(bev, BEV_EVENT_ERROR, 0); bufferevent_decref_(bev); } else { beva->read_in_progress = at_most; @@ -428,8 +449,7 @@ connect_complete(struct event_overlapped *eo, ev_uintptr_t key, else bev_async_set_wsa_error(bev, eo); - bufferevent_run_eventcb_(bev, - ok? BEV_EVENT_CONNECTED : BEV_EVENT_ERROR, 0); + be_async_run_eventcb(bev, ok ? BEV_EVENT_CONNECTED : BEV_EVENT_ERROR, 0); event_base_del_virtual_(bev->ev_base); @@ -459,16 +479,16 @@ read_complete(struct event_overlapped *eo, ev_uintptr_t key, if (bev_a->ok) { if (ok && nbytes) { BEV_RESET_GENERIC_READ_TIMEOUT(bev); - bufferevent_trigger_nolock_(bev, EV_READ, 0); + be_async_trigger_nolock(bev, EV_READ, 0); bev_async_consider_reading(bev_a); } else if (!ok) { what |= BEV_EVENT_ERROR; bev_a->ok = 0; - bufferevent_run_eventcb_(bev, what, 0); + be_async_run_eventcb(bev, what, 0); } else if (!nbytes) { what |= BEV_EVENT_EOF; bev_a->ok = 0; - bufferevent_run_eventcb_(bev, what, 0); + be_async_run_eventcb(bev, what, 0); } } @@ -502,16 +522,16 @@ write_complete(struct event_overlapped *eo, ev_uintptr_t key, if (bev_a->ok) { if (ok && nbytes) { BEV_RESET_GENERIC_WRITE_TIMEOUT(bev); - bufferevent_trigger_nolock_(bev, EV_WRITE, 0); + be_async_trigger_nolock(bev, EV_WRITE, 0); bev_async_consider_writing(bev_a); } else if (!ok) { what |= BEV_EVENT_ERROR; bev_a->ok = 0; - bufferevent_run_eventcb_(bev, what, 0); + be_async_run_eventcb(bev, what, 0); } else if (!nbytes) { what |= BEV_EVENT_EOF; bev_a->ok = 0; - bufferevent_run_eventcb_(bev, what, 0); + be_async_run_eventcb(bev, what, 0); } } @@ -532,11 +552,7 @@ bufferevent_async_new_(struct event_base *base, return NULL; if (fd >= 0 && event_iocp_port_associate_(iocp, fd, 1)<0) { - int err = GetLastError(); - /* We may have alrady associated this fd with a port. - * Let's hope it's this port, and that the error code - * for doing this neer changes. */ - if (err != ERROR_INVALID_PARAMETER) + if (fatal_error(GetLastError())) return NULL; } @@ -580,7 +596,6 @@ bufferevent_async_set_connected_(struct bufferevent *bev) { struct bufferevent_async *bev_async = upcast(bev); bev_async->ok = 1; - bufferevent_init_generic_timeout_cbs_(bev); /* Now's a good time to consider reading/writing */ be_async_enable(bev, bev->enabled); } @@ -654,16 +669,20 @@ be_async_ctrl(struct bufferevent *bev, enum bufferevent_ctrl_op op, data->fd = evbuffer_overlapped_get_fd_(bev->input); return 0; case BEV_CTRL_SET_FD: { + struct bufferevent_async *bev_a = upcast(bev); struct event_iocp_port *iocp; if (data->fd == evbuffer_overlapped_get_fd_(bev->input)) return 0; if (!(iocp = event_base_get_iocp_(bev->ev_base))) return -1; - if (event_iocp_port_associate_(iocp, data->fd, 1) < 0) - return -1; + if (event_iocp_port_associate_(iocp, data->fd, 1) < 0) { + if (fatal_error(GetLastError())) + return -1; + } evbuffer_overlapped_set_fd_(bev->input, data->fd); evbuffer_overlapped_set_fd_(bev->output, data->fd); + bev_a->ok = data->fd >= 0; return 0; } case BEV_CTRL_CANCEL_ALL: { diff --git a/test/regress.h b/test/regress.h index b5347268..643b82ba 100644 --- a/test/regress.h +++ b/test/regress.h @@ -43,6 +43,7 @@ extern struct testcase_t bufferevent_iocp_testcases[]; extern struct testcase_t util_testcases[]; extern struct testcase_t signal_testcases[]; extern struct testcase_t http_testcases[]; +extern struct testcase_t http_iocp_testcases[]; extern struct testcase_t dns_testcases[]; extern struct testcase_t rpc_testcases[]; extern struct testcase_t edgetriggered_testcases[]; diff --git a/test/regress_http.c b/test/regress_http.c index 86120259..c13987f1 100644 --- a/test/regress_http.c +++ b/test/regress_http.c @@ -4786,3 +4786,8 @@ struct testcase_t http_testcases[] = { END_OF_TESTCASES }; +struct testcase_t http_iocp_testcases[] = { + { "simple", http_simple_test, TT_FORK|TT_NEED_BASE|TT_ENABLE_IOCP, &basic_setup, NULL }, + { "https_simple", https_simple_test, TT_FORK|TT_NEED_BASE|TT_ENABLE_IOCP, &basic_setup, NULL }, + END_OF_TESTCASES +}; diff --git a/test/regress_main.c b/test/regress_main.c index d3c6c3ce..c9372825 100644 --- a/test/regress_main.c +++ b/test/regress_main.c @@ -384,6 +384,7 @@ struct testgroup_t testgroups[] = { { "iocp/", iocp_testcases }, { "iocp/bufferevent/", bufferevent_iocp_testcases }, { "iocp/listener/", listener_iocp_testcases }, + { "iocp/http/", http_iocp_testcases }, #endif #ifdef EVENT__HAVE_OPENSSL { "ssl/", ssl_testcases }, -- cgit v1.2.1 From 84f6fb410b38c2dc9583b70af43e594243964d2a Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 13 Nov 2018 23:23:09 +0300 Subject: s/http-server: check for EVTHREAD_USE_WINDOWS_THREADS_IMPLEMENTED (cherry picked from commit 56f3bdefcae915af3107ab20cc7548d048d56421) --- sample/http-server.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sample/http-server.c b/sample/http-server.c index bb067fb8..e2fc8499 100644 --- a/sample/http-server.c +++ b/sample/http-server.c @@ -400,9 +400,11 @@ main(int argc, char **argv) cfg = event_config_new(); #ifdef _WIN32 if (o.iocp) { +#ifdef EVTHREAD_USE_WINDOWS_THREADS_IMPLEMENTED evthread_use_windows_threads(); - event_config_set_flag(cfg, EVENT_BASE_FLAG_STARTUP_IOCP); event_config_set_num_cpus_hint(cfg, 8); +#endif + event_config_set_flag(cfg, EVENT_BASE_FLAG_STARTUP_IOCP); } #endif -- cgit v1.2.1 From 77b587b3ecd684dffd02ad60f7b7201200f25292 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 13 Nov 2018 23:30:51 +0300 Subject: t/bench_http: disable buffering (win32 do not show anything otherwise) Refs: #255 (cherry picked from commit 903c6acea52a2a2922b5cd43faec1e64631c3da8) --- test/bench_http.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/bench_http.c b/test/bench_http.c index d20d3bc7..80377ee6 100644 --- a/test/bench_http.c +++ b/test/bench_http.c @@ -101,6 +101,9 @@ main(int argc, char **argv) return (1); #endif + setbuf(stdout, NULL); + setbuf(stderr, NULL); + for (i = 1; i < argc; ++i) { if (*argv[i] != '-') continue; -- cgit v1.2.1 From 018ac6fd42fb1024e98919196ffbbeb01a960562 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 13 Nov 2018 23:20:10 +0300 Subject: regress_bufferevent: add TT_IOCP_LEGACY/TT_IOCP (cherry picked from commit f8d510f61777bcb194b945163b84047969a46cef) --- test/regress_bufferevent.c | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/test/regress_bufferevent.c b/test/regress_bufferevent.c index faf87a7f..55d8e135 100644 --- a/test/regress_bufferevent.c +++ b/test/regress_bufferevent.c @@ -1405,38 +1405,35 @@ struct testcase_t bufferevent_testcases[] = { END_OF_TESTCASES, }; +#define TT_IOCP (TT_FORK|TT_NEED_BASE|TT_ENABLE_IOCP) +#define TT_IOCP_LEGACY (TT_ISOLATED|TT_ENABLE_IOCP) struct testcase_t bufferevent_iocp_testcases[] = { - - LEGACY(bufferevent, TT_ISOLATED|TT_ENABLE_IOCP), + LEGACY(bufferevent, TT_IOCP_LEGACY), LEGACY(bufferevent_flush_normal, TT_ISOLATED), LEGACY(bufferevent_flush_flush, TT_ISOLATED), LEGACY(bufferevent_flush_finished, TT_ISOLATED), - LEGACY(bufferevent_watermarks, TT_ISOLATED|TT_ENABLE_IOCP), - LEGACY(bufferevent_filters, TT_ISOLATED|TT_ENABLE_IOCP), - LEGACY(bufferevent_filters_disable, TT_ISOLATED|TT_ENABLE_IOCP), + LEGACY(bufferevent_watermarks, TT_IOCP_LEGACY), + LEGACY(bufferevent_filters, TT_IOCP_LEGACY), + LEGACY(bufferevent_filters_disable, TT_IOCP_LEGACY), + { "bufferevent_connect", test_bufferevent_connect, - TT_FORK|TT_NEED_BASE|TT_ENABLE_IOCP, &basic_setup, (void*)"" }, + TT_IOCP, &basic_setup, (void*)"" }, { "bufferevent_connect_defer", test_bufferevent_connect, - TT_FORK|TT_NEED_BASE|TT_ENABLE_IOCP, &basic_setup, (void*)"defer" }, + TT_IOCP, &basic_setup, (void*)"defer" }, { "bufferevent_connect_lock", test_bufferevent_connect, - TT_FORK|TT_NEED_BASE|TT_NEED_THREADS|TT_ENABLE_IOCP, &basic_setup, - (void*)"lock" }, + TT_IOCP, &basic_setup, (void*)"lock" }, { "bufferevent_connect_lock_defer", test_bufferevent_connect, - TT_FORK|TT_NEED_BASE|TT_NEED_THREADS|TT_ENABLE_IOCP, &basic_setup, - (void*)"defer lock" }, + TT_IOCP, &basic_setup, (void*)"defer lock" }, { "bufferevent_connect_fail", test_bufferevent_connect_fail, - TT_FORK|TT_NEED_BASE|TT_ENABLE_IOCP, &basic_setup, NULL }, + TT_IOCP, &basic_setup, NULL }, { "bufferevent_connect_nonblocking", test_bufferevent_connect, - TT_FORK|TT_NEED_BASE|TT_ENABLE_IOCP, &basic_setup, - (void*)"unset_connectex" }, + TT_IOCP, &basic_setup, (void*)"unset_connectex" }, { "bufferevent_connect_fail_eventcb_defer", test_bufferevent_connect_fail_eventcb, - TT_FORK|TT_NEED_BASE|TT_ENABLE_IOCP, &basic_setup, - (void*)BEV_OPT_DEFER_CALLBACKS }, + TT_IOCP, &basic_setup, (void*)BEV_OPT_DEFER_CALLBACKS }, { "bufferevent_connect_fail_eventcb", - test_bufferevent_connect_fail_eventcb, - TT_FORK|TT_NEED_BASE|TT_ENABLE_IOCP, &basic_setup, NULL }, + test_bufferevent_connect_fail_eventcb, TT_IOCP, &basic_setup, NULL }, END_OF_TESTCASES, }; -- cgit v1.2.1 From 241780bdde7f6d03bcf8cd5dcf0738c35cc5a4c6 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 20 Nov 2018 06:20:51 +0300 Subject: regress_http: fix compilation with !EVENT__HAVE_OPENSSL Fixes: 811c63f7 ("regress: test for HTTP/HTTPS with IOCP enabled") (cherry picked from commit 3036f15a176b038f42d3896463c39058c6bac943) --- test/regress_http.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/regress_http.c b/test/regress_http.c index c13987f1..c555a263 100644 --- a/test/regress_http.c +++ b/test/regress_http.c @@ -4788,6 +4788,8 @@ struct testcase_t http_testcases[] = { struct testcase_t http_iocp_testcases[] = { { "simple", http_simple_test, TT_FORK|TT_NEED_BASE|TT_ENABLE_IOCP, &basic_setup, NULL }, +#ifdef EVENT__HAVE_OPENSSL { "https_simple", https_simple_test, TT_FORK|TT_NEED_BASE|TT_ENABLE_IOCP, &basic_setup, NULL }, +#endif END_OF_TESTCASES }; -- cgit v1.2.1 From a8cc449ed21b29b52c801b3354d6e03613eba8fd Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Wed, 14 Nov 2018 00:20:20 +0300 Subject: http: improve error path for bufferevent_{setfd,enable,disable}() We have calls to the next functions but do not check return values, though they can be invalid and it is better to show this somehow. Also do bufferevent_setfd() first and only after it bufferevent_enable()/bufferevent_disable() since: a) it is more natural b) it will avoid extra operations c) it will not fail first bufferevent_enable() (this is the case for buffbufferevent_async at least) In this case we could add more information for issues like #709 (cherry picked from commit b98d32d0c90864ff60bc689f3bcf738af58ca79c) --- http.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/http.c b/http.c index 8677bba1..ae2fe591 100644 --- a/http.c +++ b/http.c @@ -1339,7 +1339,8 @@ evhttp_connection_reset_(struct evhttp_connection *evcon) evutil_closesocket(evcon->fd); evcon->fd = -1; } - bufferevent_setfd(evcon->bufev, -1); + err = bufferevent_setfd(evcon->bufev, -1); + EVUTIL_ASSERT(!err && "setfd"); /* we need to clean up any buffered data */ tmp = bufferevent_get_output(evcon->bufev); @@ -1358,7 +1359,6 @@ static void evhttp_connection_start_detectclose(struct evhttp_connection *evcon) { evcon->flags |= EVHTTP_CON_CLOSEDETECT; - bufferevent_enable(evcon->bufev, EV_READ); } @@ -1366,7 +1366,6 @@ static void evhttp_connection_stop_detectclose(struct evhttp_connection *evcon) { evcon->flags &= ~EVHTTP_CON_CLOSEDETECT; - bufferevent_disable(evcon->bufev, EV_READ); } @@ -2558,9 +2557,11 @@ evhttp_connection_connect_(struct evhttp_connection *evcon) return (-1); } - bufferevent_setfd(evcon->bufev, evcon->fd); + if (bufferevent_setfd(evcon->bufev, evcon->fd)) + return (-1); } else { - bufferevent_setfd(evcon->bufev, -1); + if (bufferevent_setfd(evcon->bufev, -1)) + return (-1); } /* Set up a callback for successful connection setup */ @@ -2576,7 +2577,8 @@ evhttp_connection_connect_(struct evhttp_connection *evcon) bufferevent_set_timeouts(evcon->bufev, &evcon->timeout, &evcon->timeout); } /* make sure that we get a write callback */ - bufferevent_enable(evcon->bufev, EV_WRITE); + if (bufferevent_enable(evcon->bufev, EV_WRITE)) + return (-1); evcon->state = EVCON_CONNECTING; @@ -4220,12 +4222,19 @@ evhttp_get_request_connection( evcon->fd = fd; - bufferevent_enable(evcon->bufev, EV_READ); - bufferevent_disable(evcon->bufev, EV_WRITE); - bufferevent_setfd(evcon->bufev, fd); + if (bufferevent_setfd(evcon->bufev, fd)) + goto err; + if (bufferevent_enable(evcon->bufev, EV_READ)) + goto err; + if (bufferevent_disable(evcon->bufev, EV_WRITE)) + goto err; bufferevent_socket_set_conn_address_(evcon->bufev, sa, salen); return (evcon); + +err: + evhttp_connection_free(evcon); + return (NULL); } static int -- cgit v1.2.1 From 22609d66efaf660d4951852e760ae562b82ff27e Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 20 Nov 2018 00:58:47 +0300 Subject: bufferevent: add debug messages when .setfd/.getfd/.enable/.disable failed (cherry picked from commit 57765b23c81a9150ca0f77ed5f4d9b64a43cf30d) --- bufferevent.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/bufferevent.c b/bufferevent.c index f7f97bcf..ef7c2eaf 100644 --- a/bufferevent.c +++ b/bufferevent.c @@ -491,6 +491,8 @@ bufferevent_enable(struct bufferevent *bufev, short event) if (impl_events && bufev->be_ops->enable(bufev, impl_events) < 0) r = -1; + if (r) + event_debug(("%s: cannot enable 0x%hx on %p", __func__, event, bufev)); bufferevent_decref_and_unlock_(bufev); return r; @@ -573,6 +575,8 @@ bufferevent_disable(struct bufferevent *bufev, short event) if (bufev->be_ops->disable(bufev, event) < 0) r = -1; + if (r) + event_debug(("%s: cannot disable 0x%hx on %p", __func__, event, bufev)); BEV_UNLOCK(bufev); return r; @@ -862,6 +866,8 @@ bufferevent_setfd(struct bufferevent *bev, evutil_socket_t fd) BEV_LOCK(bev); if (bev->be_ops->ctrl) res = bev->be_ops->ctrl(bev, BEV_CTRL_SET_FD, &d); + if (res) + event_debug(("%s: cannot set fd for %p to "EV_SOCK_FMT, __func__, bev, fd)); BEV_UNLOCK(bev); return res; } @@ -875,6 +881,8 @@ bufferevent_getfd(struct bufferevent *bev) BEV_LOCK(bev); if (bev->be_ops->ctrl) res = bev->be_ops->ctrl(bev, BEV_CTRL_GET_FD, &d); + if (res) + event_debug(("%s: cannot get fd for %p", __func__, bev)); BEV_UNLOCK(bev); return (res<0) ? -1 : d.fd; } -- cgit v1.2.1 From 6ea1ec68cedbc8ae64b136962a13edb896a069a2 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Wed, 21 Nov 2018 00:10:43 +0300 Subject: Merge branch 'TT_RETRIABLE' * TT_RETRIABLE: Mark a lot of flacky tests with TT_RETRIABLE (for linux/win32 only) regress: introduce TT_RETRIABLE Fixes: #704 (cherry picked from commit 4d2f013b5d20e674b22e5a8244f7fa63172dbdbf) --- test/regress.c | 6 +++--- test/regress_http.c | 10 ++++++---- test/regress_thread.c | 8 ++++---- test/regress_util.c | 4 ++-- test/tinytest.c | 37 +++++++++++++++++++++++++++++-------- test/tinytest.h | 5 ++++- test/tinytest_demo.c | 30 ++++++++++++++++++++++++++++++ 7 files changed, 78 insertions(+), 22 deletions(-) diff --git a/test/regress.c b/test/regress.c index e3966247..057765ea 100644 --- a/test/regress.c +++ b/test/regress.c @@ -3416,14 +3416,14 @@ struct testcase_t main_testcases[] = { BASIC(bad_assign, TT_FORK|TT_NEED_BASE|TT_NO_LOGS), BASIC(bad_reentrant, TT_FORK|TT_NEED_BASE|TT_NO_LOGS), - BASIC(active_later, TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR), + BASIC(active_later, TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR|TT_RETRIABLE), BASIC(event_remove_timeout, TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR), /* These are still using the old API */ LEGACY(persistent_timeout, TT_FORK|TT_NEED_BASE), { "persistent_timeout_jump", test_persistent_timeout_jump, TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, { "persistent_active_timeout", test_persistent_active_timeout, - TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, + TT_FORK|TT_NEED_BASE|TT_RETRIABLE, &basic_setup, NULL }, LEGACY(priorities, TT_FORK|TT_NEED_BASE), BASIC(priority_active_inversion, TT_FORK|TT_NEED_BASE), { "common_timeout", test_common_timeout, TT_FORK|TT_NEED_BASE, @@ -3476,7 +3476,7 @@ struct testcase_t main_testcases[] = { #endif #ifdef EVENT__HAVE_PTHREADS /** TODO: support win32 */ - LEGACY(del_wait, TT_ISOLATED|TT_NEED_THREADS), + LEGACY(del_wait, TT_ISOLATED|TT_NEED_THREADS|TT_RETRIABLE), LEGACY(del_notify, TT_ISOLATED|TT_NEED_THREADS), #endif diff --git a/test/regress_http.c b/test/regress_http.c index c555a263..634f2912 100644 --- a/test/regress_http.c +++ b/test/regress_http.c @@ -4647,6 +4647,8 @@ http_request_extra_body_test(void *arg) #define HTTP_CAST_ARG(a) ((void *)(a)) #define HTTP_OFF_N(title, name, arg) \ { #title, http_##name##_test, TT_ISOLATED|TT_OFF_BY_DEFAULT, &basic_setup, HTTP_CAST_ARG(arg) } +#define HTTP_RET_N(title, name, arg) \ + { #title, http_##name##_test, TT_ISOLATED|TT_RETRIABLE, &basic_setup, HTTP_CAST_ARG(arg) } #define HTTP_N(title, name, arg) \ { #title, http_##name##_test, TT_ISOLATED, &basic_setup, HTTP_CAST_ARG(arg) } #define HTTP(name) HTTP_N(name, name, NULL) @@ -4701,17 +4703,17 @@ struct testcase_t http_testcases[] = { HTTP(simple_nonconformant), HTTP_N(cancel, cancel, BASIC), - HTTP_N(cancel_by_host, cancel, BY_HOST), + HTTP_RET_N(cancel_by_host, cancel, BY_HOST), + HTTP_RET_N(cancel_by_host_inactive_server, cancel, BY_HOST | INACTIVE_SERVER), HTTP_N(cancel_by_host_no_ns, cancel, BY_HOST | NO_NS), - HTTP_N(cancel_by_host_inactive_server, cancel, BY_HOST | INACTIVE_SERVER), HTTP_N(cancel_inactive_server, cancel, INACTIVE_SERVER), HTTP_N(cancel_by_host_no_ns_inactive_server, cancel, BY_HOST | NO_NS | INACTIVE_SERVER), HTTP_OFF_N(cancel_by_host_server_timeout, cancel, BY_HOST | INACTIVE_SERVER | SERVER_TIMEOUT), HTTP_OFF_N(cancel_server_timeout, cancel, INACTIVE_SERVER | SERVER_TIMEOUT), HTTP_OFF_N(cancel_by_host_no_ns_server_timeout, cancel, BY_HOST | NO_NS | INACTIVE_SERVER | SERVER_TIMEOUT), HTTP_OFF_N(cancel_by_host_ns_timeout_server_timeout, cancel, BY_HOST | NO_NS | NS_TIMEOUT | INACTIVE_SERVER | SERVER_TIMEOUT), - HTTP_N(cancel_by_host_ns_timeout, cancel, BY_HOST | NO_NS | NS_TIMEOUT), - HTTP_N(cancel_by_host_ns_timeout_inactive_server, cancel, BY_HOST | NO_NS | NS_TIMEOUT | INACTIVE_SERVER), + HTTP_RET_N(cancel_by_host_ns_timeout, cancel, BY_HOST | NO_NS | NS_TIMEOUT), + HTTP_RET_N(cancel_by_host_ns_timeout_inactive_server, cancel, BY_HOST | NO_NS | NS_TIMEOUT | INACTIVE_SERVER), HTTP(virtual_host), HTTP(post), diff --git a/test/regress_thread.c b/test/regress_thread.c index 689c23d1..1e0ce41f 100644 --- a/test/regress_thread.c +++ b/test/regress_thread.c @@ -564,8 +564,8 @@ end: ; } -#define TEST(name) \ - { #name, thread_##name, TT_FORK|TT_NEED_THREADS|TT_NEED_BASE, \ +#define TEST(name, f) \ + { #name, thread_##name, TT_FORK|TT_NEED_THREADS|TT_NEED_BASE|(f), \ &basic_setup, NULL } struct testcase_t thread_testcases[] = { @@ -575,7 +575,7 @@ struct testcase_t thread_testcases[] = { { "forking", thread_basic, TT_FORK|TT_NEED_THREADS|TT_NEED_BASE, &basic_setup, (char*)"forking" }, #endif - TEST(conditions_simple), + TEST(conditions_simple, TT_RETRIABLE), { "deferred_cb_skew", thread_deferred_cb_skew, TT_FORK|TT_NEED_THREADS|TT_OFF_BY_DEFAULT, &basic_setup, NULL }, @@ -583,7 +583,7 @@ struct testcase_t thread_testcases[] = { /****** XXX TODO FIXME windows seems to be having some timing trouble, * looking into it now. / ellzey ******/ - TEST(no_events), + TEST(no_events, TT_RETRIABLE), #endif END_OF_TESTCASES }; diff --git a/test/regress_util.c b/test/regress_util.c index 721537cc..3da20703 100644 --- a/test/regress_util.c +++ b/test/regress_util.c @@ -1559,12 +1559,12 @@ struct testcase_t util_testcases[] = { { "mm_malloc", test_event_malloc, 0, NULL, NULL }, { "mm_calloc", test_event_calloc, 0, NULL, NULL }, { "mm_strdup", test_event_strdup, 0, NULL, NULL }, - { "usleep", test_evutil_usleep, 0, NULL, NULL }, + { "usleep", test_evutil_usleep, TT_RETRIABLE, NULL, NULL }, { "monotonic_res", test_evutil_monotonic_res, 0, &basic_setup, (void*)"" }, { "monotonic_res_precise", test_evutil_monotonic_res, TT_OFF_BY_DEFAULT, &basic_setup, (void*)"precise" }, { "monotonic_res_fallback", test_evutil_monotonic_res, TT_OFF_BY_DEFAULT, &basic_setup, (void*)"fallback" }, { "monotonic_prc", test_evutil_monotonic_prc, 0, &basic_setup, (void*)"" }, - { "monotonic_prc_precise", test_evutil_monotonic_prc, 0, &basic_setup, (void*)"precise" }, + { "monotonic_prc_precise", test_evutil_monotonic_prc, TT_RETRIABLE, &basic_setup, (void*)"precise" }, { "monotonic_prc_fallback", test_evutil_monotonic_prc, 0, &basic_setup, (void*)"fallback" }, { "date_rfc1123", test_evutil_date_rfc1123, 0, NULL, NULL }, { "evutil_v4addr_is_local", test_evutil_v4addr_is_local, 0, NULL, NULL }, diff --git a/test/tinytest.c b/test/tinytest.c index 3a8e3310..a27a906a 100644 --- a/test/tinytest.c +++ b/test/tinytest.c @@ -253,15 +253,12 @@ testcase_run_one(const struct testgroup_t *group, } if (outcome == OK) { - ++n_ok; if (opt_verbosity>0 && !opt_forked) puts(opt_verbosity==1?"OK":""); } else if (outcome == SKIP) { - ++n_skipped; if (opt_verbosity>0 && !opt_forked) puts("SKIPPED"); } else { - ++n_bad; if (!opt_forked) printf("\n [%s FAILED]\n", testcase->name); } @@ -428,11 +425,35 @@ tinytest_main(int c, const char **v, struct testgroup_t *groups) #endif ++in_tinytest_main; - for (i=0; groups[i].prefix; ++i) - for (j=0; groups[i].cases[j].name; ++j) - if (groups[i].cases[j].flags & TT_ENABLED_) - testcase_run_one(&groups[i], - &groups[i].cases[j]); + for (i = 0; groups[i].prefix; ++i) { + struct testgroup_t *group = &groups[i]; + for (j = 0; group->cases[j].name; ++j) { + struct testcase_t *testcase = &group->cases[j]; + int test_attempts = 3; + int test_ret_err; + + if (!(testcase->flags & TT_ENABLED_)) + continue; + + for (;;) { + test_ret_err = testcase_run_one(group, testcase); + + if (test_ret_err == OK) + break; + if (!(testcase->flags & TT_RETRIABLE)) + break; + printf("\n [RETRYING %s (%i)]\n", testcase->name, test_attempts); + if (!test_attempts--) + break; + } + + switch (test_ret_err) { + case OK: ++n_ok; break; + case SKIP: ++n_skipped; break; + default: ++n_bad; break; + } + } + } --in_tinytest_main; diff --git a/test/tinytest.h b/test/tinytest.h index ed07b26b..d321dd46 100644 --- a/test/tinytest.h +++ b/test/tinytest.h @@ -34,8 +34,11 @@ #define TT_ENABLED_ (1<<2) /** Flag for a test that's off by default. */ #define TT_OFF_BY_DEFAULT (1<<3) +/** Flag for a test that should be runned again in case of failure (but not + * more then 3 times). */ +#define TT_RETRIABLE (1<<4) /** If you add your own flags, make them start at this point. */ -#define TT_FIRST_USER_FLAG (1<<4) +#define TT_FIRST_USER_FLAG (1<<5) typedef void (*testcase_fn)(void *); diff --git a/test/tinytest_demo.c b/test/tinytest_demo.c index f6bfd66a..123855ff 100644 --- a/test/tinytest_demo.c +++ b/test/tinytest_demo.c @@ -192,6 +192,32 @@ test_timeout(void *ptr) ; } +void +test_timeout_retry(void *ptr) +{ + static int i = 0; + + ++i; + tt_int_op(i, !=, 1); + + time_t t1, t2; + (void)ptr; + t1 = time(NULL); +#ifdef _WIN32 + Sleep(5000); +#else + sleep(5); +#endif + t2 = time(NULL); + + tt_int_op(t2-t1, >=, 4); + + tt_int_op(t2-t1, <=, 6); + + end: + ; +} + /* ============================================================ */ /* Now we need to make sure that our tests get invoked. First, you take @@ -212,6 +238,10 @@ struct testcase_t demo_tests[] = { * can enable it manually by passing +demo/timeout at the command line.*/ { "timeout", test_timeout, TT_OFF_BY_DEFAULT }, + /* This test will be retried. (and it will not pass from the first + * time) */ + { "timeout_retry", test_timeout_retry, TT_RETRIABLE }, + /* The array has to end with END_OF_TESTCASES. */ END_OF_TESTCASES }; -- cgit v1.2.1 From a28c83464cd55d711b9c4a8479a202b6c8244acd Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Wed, 21 Nov 2018 07:31:57 +0300 Subject: cmake: drop redundant add_dependencies() (cherry picked from commit d705e8c0e924d3b815697a075c27a36298f04078) --- CMakeLists.txt | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d8651609..bc54a4b6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -874,13 +874,9 @@ macro(add_sample_prog ssl name) event_core_static ${LIB_APPS} ${LIB_PLATFORM}) - add_dependencies(${name} - event_core_static - event_extra_static) if (${ssl}) target_link_libraries(${name} event_openssl_static) - add_dependencies(${name} event_openssl_static) endif() endmacro() if (NOT EVENT__DISABLE_SAMPLES) @@ -923,9 +919,6 @@ macro(add_bench_prog prog) event_core_static ${LIB_APPS} ${LIB_PLATFORM}) - add_dependencies(${prog} - event_extra_static - event_core_static) endmacro() if (NOT EVENT__DISABLE_BENCHMARK) foreach (BENCHMARK bench_http bench_httpclient) @@ -947,9 +940,6 @@ macro(add_test_prog prog) event_core_shared event_extra_shared ${ARGN}) - add_dependencies(${prog} - event_core_shared - event_extra_shared) endmacro() if (NOT EVENT__DISABLE_TESTS) # -- cgit v1.2.1 From eb10a7387cc1026ab11c111ff2bb8b111110a696 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Thu, 22 Nov 2018 23:00:11 +0300 Subject: cmake: introduce EVENT__LIBRARY_TYPE option Long time ago in [1] cmake build was forced to compile both libraries (SHARED and STATIC), since this is how our autotools build works. [1]: 7182c2f561570cd9ceb704623ebe9ae3608c7b43 ("cmake: build SHARED and STATIC libraries (like autoconf does)") And there is no way to configure this (and indeed you need to do this for MSVC for example), so let's introduce option for this -- EVENT__LIBRARY_TYPE. Plus now we have INTERFACE libraries, that we can use internally in libevent's cmake rules to avoid strict to _shared/_static variant of the libraries to link with samples/tests (we prefer SHARED over STATIC for linking). Also bump minimal cmake required version to 3.1 by the following reasons: - 3.1 is required for RPATH configuration under APPLE - 3.0 is required for add_library(INTERFACE) (did not found it in 2.8.x documentation) - remove extra conditions (anyway 3.1 was release 4 years ago, so I guess that most of the systems will have it) (cherry picked from commit c9a073eae8f86a74fbbb125db34b881ef40108b7) --- CMakeLists.txt | 52 ++++++++++++++++++++--------- README.md | 4 +++ cmake/AddEventLibrary.cmake | 81 +++++++++++++++++++++++++++------------------ 3 files changed, 88 insertions(+), 49 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bc54a4b6..6daf3317 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,11 +18,8 @@ # cmake -G "Visual Studio 10" .. # start libevent.sln # -if (APPLE) - cmake_minimum_required(VERSION 3.1 FATAL_ERROR) -else() - cmake_minimum_required(VERSION 2.8.3 FATAL_ERROR) -endif() + +cmake_minimum_required(VERSION 3.1 FATAL_ERROR) if (POLICY CMP0054) cmake_policy(SET CMP0054 NEW) @@ -44,6 +41,9 @@ string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER) # what? why would you get id of other useful build types? - Ellzey set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "Limited configurations" FORCE) +set(EVENT__LIBRARY_TYPE DEFAULT CACHE STRING + "Set library type to SHARED/STATIC/BOTH (default BOTH)") + project(libevent C) set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/") @@ -187,6 +187,26 @@ if ((${CMAKE_C_COMPILER_ID} STREQUAL GNU) OR (${CLANG})) set(GNUC 1) endif() +# Detect library type +set(EVENT_LIBRARY_TYPE) +if ("${EVENT__LIBRARY_TYPE}" STREQUAL "DEFAULT") + set(EVENT_LIBRARY_TYPE BOTH) +else() + string(TOUPPER "${EVENT__LIBRARY_TYPE}" EVENT_LIBRARY_TYPE) +endif() +set(EVENT_LIBRARY_STATIC OFF) +set(EVENT_LIBRARY_SHARED OFF) +if ("${EVENT_LIBRARY_TYPE}" STREQUAL "BOTH") + set(EVENT_LIBRARY_STATIC ON) + set(EVENT_LIBRARY_SHARED ON) +elseif ("${EVENT_LIBRARY_TYPE}" STREQUAL "STATIC") + set(EVENT_LIBRARY_STATIC ON) +elseif ("${EVENT_LIBRARY_TYPE}" STREQUAL "SHARED") + set(EVENT_LIBRARY_SHARED ON) +else() + message(FATAL_ERROR "${EVENT_LIBRARY_TYPE} is not supported") +endif() + # GNUC specific options. if (${GNUC}) option(EVENT__DISABLE_GCC_WARNINGS "Disable verbose warnings with GCC" OFF) @@ -870,13 +890,13 @@ macro(add_sample_prog ssl name) add_executable(${name} ${ARGN}) target_link_libraries(${name} - event_extra_static - event_core_static + event_extra + event_core ${LIB_APPS} ${LIB_PLATFORM}) if (${ssl}) - target_link_libraries(${name} event_openssl_static) + target_link_libraries(${name} event_openssl) endif() endmacro() if (NOT EVENT__DISABLE_SAMPLES) @@ -915,8 +935,8 @@ endif() macro(add_bench_prog prog) add_executable(${prog} ${ARGN}) target_link_libraries(${prog} - event_extra_static - event_core_static + event_extra + event_core ${LIB_APPS} ${LIB_PLATFORM}) endmacro() @@ -937,8 +957,8 @@ macro(add_test_prog prog) target_link_libraries(${prog} ${LIB_APPS} ${LIB_PLATFORM} - event_core_shared - event_extra_shared + event_core + event_extra ${ARGN}) endmacro() if (NOT EVENT__DISABLE_TESTS) @@ -1016,13 +1036,13 @@ if (NOT EVENT__DISABLE_TESTS) target_link_libraries(regress ${LIB_APPS} ${LIB_PLATFORM} - event_core_shared - event_extra_shared) + event_core + event_extra) if (NOT EVENT__DISABLE_OPENSSL) - target_link_libraries(regress event_openssl_shared) + target_link_libraries(regress event_openssl) endif() if (CMAKE_USE_PTHREADS_INIT) - target_link_libraries(regress event_pthreads_shared) + target_link_libraries(regress event_pthreads) endif() else() message(WARNING "No suitable Python interpreter found, cannot generate regress tests!") diff --git a/README.md b/README.md index 967fbdfe..61735731 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,10 @@ The following Libevent specific CMake variables are as follows (the values being the default). ``` +# Type of the library to build (SHARED or STATIC) +# Default is to build BOTH +EVENT__LIBRARY_TYPE:STRING=DEFAULT + # Installation directory for CMake files EVENT_INSTALL_CMAKE_DIR:PATH=lib/cmake/libevent diff --git a/cmake/AddEventLibrary.cmake b/cmake/AddEventLibrary.cmake index 3f4e800e..9de4484c 100644 --- a/cmake/AddEventLibrary.cmake +++ b/cmake/AddEventLibrary.cmake @@ -3,11 +3,6 @@ include(CMakeParseArguments) set(LIBEVENT_SHARED_LIBRARIES "") set(LIBEVENT_STATIC_LIBRARIES "") -macro(set_event_lib_properties LIB_NAME) - set_target_properties("${LIB_NAME}_static" PROPERTIES ${ARGN}) - set_target_properties("${LIB_NAME}_shared" PROPERTIES ${ARGN}) -endmacro() - macro(set_event_shared_lib_flags LIB_NAME) set_target_properties("${LIB_NAME}_shared" PROPERTIES COMPILE_FLAGS ${ARGN}) @@ -48,6 +43,8 @@ endmacro() # - HDR_PUBLIC # - EVENT_INSTALL_INCLUDE_DIR # - EVENT_SHARED_FLAGS +# - EVENT_LIBRARY_STATIC +# - EVENT_LIBRARY_SHARED # # Exported variables: # - LIBEVENT_SHARED_LIBRARIES @@ -60,41 +57,59 @@ macro(add_event_library LIB_NAME) ${ARGN} ) - add_library("${LIB_NAME}_static" STATIC ${LIB_SOURCES}) - add_library("${LIB_NAME}_shared" SHARED ${LIB_SOURCES}) + set(ADD_EVENT_LIBRARY_TARGETS) + set(ADD_EVENT_LIBRARY_INTERFACE) - target_link_libraries("${LIB_NAME}_shared" - ${CMAKE_THREAD_LIBS_INIT} - ${LIB_PLATFORM} - ${LIB_LIBRARIES}) - - if (EVENT_SHARED_FLAGS) - set_event_shared_lib_flags("${LIB_NAME}" "${EVENT_SHARED_FLAGS}") - endif() + if (${EVENT_LIBRARY_STATIC}) + add_library("${LIB_NAME}_static" STATIC ${LIB_SOURCES}) + set_target_properties("${LIB_NAME}_static" PROPERTIES + OUTPUT_NAME "${LIB_NAME}" + CLEAN_DIRECT_OUTPUT 1) + set_target_properties( + "${LIB_NAME}_static" PROPERTIES + PUBLIC_HEADER "${HDR_PUBLIC}") - set_event_lib_properties("${LIB_NAME}" - OUTPUT_NAME "${LIB_NAME}" - CLEAN_DIRECT_OUTPUT 1 - ) + list(APPEND LIBEVENT_STATIC_LIBRARIES "${LIB_NAME}_static") + list(APPEND ADD_EVENT_LIBRARY_TARGETS "${LIB_NAME}_static") - set_target_properties( - "${LIB_NAME}_shared" PROPERTIES - PUBLIC_HEADER "${HDR_PUBLIC}") - set_target_properties( - "${LIB_NAME}_static" PROPERTIES - PUBLIC_HEADER "${HDR_PUBLIC}") + set(ADD_EVENT_LIBRARY_INTERFACE "${LIB_NAME}_static") + endif() - set_target_properties( - "${LIB_NAME}_shared" PROPERTIES - SOVERSION ${EVENT_ABI_LIBVERSION} - ) + if (${EVENT_LIBRARY_SHARED}) + add_library("${LIB_NAME}_shared" SHARED ${LIB_SOURCES}) + + target_link_libraries("${LIB_NAME}_shared" + ${CMAKE_THREAD_LIBS_INIT} + ${LIB_PLATFORM} + ${LIB_LIBRARIES}) + + if (EVENT_SHARED_FLAGS) + set_event_shared_lib_flags("${LIB_NAME}" "${EVENT_SHARED_FLAGS}") + endif() + + set_target_properties("${LIB_NAME}_shared" PROPERTIES + OUTPUT_NAME "${LIB_NAME}" + CLEAN_DIRECT_OUTPUT 1) + set_target_properties( + "${LIB_NAME}_shared" PROPERTIES + PUBLIC_HEADER "${HDR_PUBLIC}") + set_target_properties( + "${LIB_NAME}_shared" PROPERTIES + SOVERSION ${EVENT_ABI_LIBVERSION} + ) + + list(APPEND LIBEVENT_SHARED_LIBRARIES "${LIB_NAME}_shared") + list(APPEND ADD_EVENT_LIBRARY_TARGETS "${LIB_NAME}_shared") + + set(ADD_EVENT_LIBRARY_INTERFACE "${LIB_NAME}_shared") + endif() - export(TARGETS "${LIB_NAME}_static" "${LIB_NAME}_shared" + export(TARGETS ${ADD_EVENT_LIBRARY_TARGETS} FILE "${PROJECT_BINARY_DIR}/LibeventTargets.cmake" APPEND ) - install(TARGETS "${LIB_NAME}_static" "${LIB_NAME}_shared" + install(TARGETS ${ADD_EVENT_LIBRARY_TARGETS} EXPORT LibeventTargets LIBRARY DESTINATION "lib" COMPONENT lib ARCHIVE DESTINATION "lib" COMPONENT lib @@ -103,8 +118,8 @@ macro(add_event_library LIB_NAME) COMPONENT dev ) - list(APPEND LIBEVENT_SHARED_LIBRARIES "${LIB_NAME}_shared") - list(APPEND LIBEVENT_STATIC_LIBRARIES "${LIB_NAME}_static") + add_library(${LIB_NAME} INTERFACE) + target_link_libraries(${LIB_NAME} INTERFACE ${ADD_EVENT_LIBRARY_INTERFACE}) generate_pkgconfig("${LIB_NAME}") endmacro() -- cgit v1.2.1 From bc7f2fd9f29fe8ec3b4df308d7201e1bdf001e33 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Fri, 23 Nov 2018 00:29:55 +0300 Subject: cmake: do not build both (SHARED and STATIC) for MSVC/win32 MSVC does not support SHARED and STATIC libraries with the same name, so let's just build SHARED libraries by default instead (yes we can add prefix but let's stick with this). The reason for this is that in windows shared libraries requires .lib file too, but this is not static library it is imported library for shared (doh...), for more info [1] and [2]. [1]: https://docs.microsoft.com/en-us/windows/desktop/dlls/dynamic-link-library-creation [2]: https://blogs.msdn.microsoft.com/oldnewthing/20091013-00/?p=16403 And when we build both static library can and will override shared library imported part, let's take a look at event_extra.lib: - before patch [3]: $ less libevent-fail/lib/Debug/event_extra.lib | head ==> use library:contained_file to view a file in the archive rw-rw-rw- 100666/100666 59568 Nov 21 23:55 2018 event_extra_static.dir/Debug/evrpc.obj rw-rw-rw- 100666/100666 252219 Nov 21 23:55 2018 event_extra_static.dir/Debug/evdns.obj rw-rw-rw- 100666/100666 203850 Nov 21 23:55 2018 event_extra_static.dir/Debug/http.obj rw-rw-rw- 100666/100666 25907 Nov 21 23:55 2018 event_extra_static.dir/Debug/event_tagging.obj [3]: https://ci.appveyor.com/project/azat/libevent/builds/20472024/job/t0o93v042jai0dj7 - "after patch" [4] (not after but the same effect): $ less libevent-ok/lib/Debug/event_extra.lib | head ==> use library:contained_file to view a file in the archive --------- 0/0 509 Nov 21 23:38 2018 event_extra.dll ... [4]: https://ci.appveyor.com/project/azat/libevent/builds/20478998/job/ca9k3c76amc4qr76 Refs: #691 (cherry picked from commit 90d80ef4167d97b11e01e80fcc4eaa447712e92f) --- CMakeLists.txt | 20 +++++++++++++++++--- README.md | 2 +- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6daf3317..fa0de482 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,7 +42,7 @@ string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER) set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "Limited configurations" FORCE) set(EVENT__LIBRARY_TYPE DEFAULT CACHE STRING - "Set library type to SHARED/STATIC/BOTH (default BOTH)") + "Set library type to SHARED/STATIC/BOTH (default SHARED for MSVC, otherwise BOTH)") project(libevent C) @@ -179,21 +179,35 @@ endif() set(GNUC 0) set(CLANG 0) +set(MSVC 0) if (("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") OR ("${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang")) set(CLANG 1) endif() -if ((${CMAKE_C_COMPILER_ID} STREQUAL GNU) OR (${CLANG})) +if (("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") OR (${CLANG})) set(GNUC 1) endif() +if (("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC") OR (${CLANG})) + set(MSVC 1) +endif() # Detect library type set(EVENT_LIBRARY_TYPE) if ("${EVENT__LIBRARY_TYPE}" STREQUAL "DEFAULT") - set(EVENT_LIBRARY_TYPE BOTH) + if (${MSVC}) + set(EVENT_LIBRARY_TYPE SHARED) + else() + set(EVENT_LIBRARY_TYPE BOTH) + endif() else() string(TOUPPER "${EVENT__LIBRARY_TYPE}" EVENT_LIBRARY_TYPE) endif() +if ((${MSVC}) AND ("${EVENT_LIBRARY_TYPE}" STREQUAL "BOTH")) + message(WARNING + "Building SHARED and STATIC is not supported for MSVC " + "(due to conflicts in library name" + " between STATIC library and IMPORTED library for SHARED libraries)") +endif() set(EVENT_LIBRARY_STATIC OFF) set(EVENT_LIBRARY_SHARED OFF) if ("${EVENT_LIBRARY_TYPE}" STREQUAL "BOTH") diff --git a/README.md b/README.md index 61735731..5d66021c 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ the default). ``` # Type of the library to build (SHARED or STATIC) -# Default is to build BOTH +# Default is: SHARED for MSVC, otherwise BOTH EVENT__LIBRARY_TYPE:STRING=DEFAULT # Installation directory for CMake files -- cgit v1.2.1 From d156c6085a189d08658b5d7443f58d330496d521 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Wed, 21 Nov 2018 07:04:33 +0300 Subject: appveyor: enable parallel build (cherry picked from commit 1a79fd38aa3bd34d941c4949ad3e4ba09aa8142b) --- appveyor.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 1ba6770c..ee4d7751 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -15,6 +15,7 @@ environment: APPVEYOR_SAVE_CACHE_ON_ERROR: true CYG_ROOT: C:/MinGW/msys/1.0 EVENT_TESTS_PARALLEL: 20 + EVENT_BUILD_PARALLEL: 10 matrix: # !EVENT_ALLOW_FAILURE - EVENT_BUILD_METHOD: "cmake" @@ -72,12 +73,12 @@ build_script: bash -lc "echo 'C:\MinGW /mingw' > /etc/fstab" bash -lc "echo 'C:\OpenSSL-Win32 /ssl' >> /etc/fstab" $env:APPVEYOR_BUILD_FOLDER = $env:APPVEYOR_BUILD_FOLDER -replace "\\", "/" - bash -lc "exec 0&1; cd $env:APPVEYOR_BUILD_FOLDER; bash -x ./autogen.sh && mkdir -p build-autotools && cd build-autotools && ../configure LDFLAGS='-L/ssl -L/ssl/lib -L/ssl/lib/MinGW' CFLAGS=-I/ssl/include $env:EVENT_CONFIGURE_OPTIONS && make && make verify -j$env:EVENT_TESTS_PARALLEL" + bash -lc "exec 0&1; cd $env:APPVEYOR_BUILD_FOLDER; bash -x ./autogen.sh && mkdir -p build-autotools && cd build-autotools && ../configure LDFLAGS='-L/ssl -L/ssl/lib -L/ssl/lib/MinGW' CFLAGS=-I/ssl/include $env:EVENT_CONFIGURE_OPTIONS && make -j $env:EVENT_BUILD_PARALLEL && make verify -j$env:EVENT_TESTS_PARALLEL" } else { md build-cmake 2> $null cd build-cmake cmake .. $env:EVENT_CMAKE_OPTIONS - cmake --build . + cmake --build . -j $env:EVENT_BUILD_PARALLEL $env:CTEST_PARALLEL_LEVEL=$env:EVENT_TESTS_PARALLEL ctest --output-on-failure } -- cgit v1.2.1 From f9b592aa27c5a2e184d6cb6ca68d61e8ef4eaba1 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Fri, 23 Nov 2018 00:42:46 +0300 Subject: test: add TT_RETRIABLE for http/cancel_by_host_no_ns Could fail from time to time in travis-ci: https://travis-ci.org/libevent/libevent/jobs/458554097#L1702 Follow-up-for: fe5b0719 ("Mark a lot of flacky tests with TT_RETRIABLE (for linux/win32 only)") (cherry picked from commit 1d2ef90032bc842bc2e295ee4adce3408b6d85da) --- test/regress_http.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/regress_http.c b/test/regress_http.c index 634f2912..624aefc0 100644 --- a/test/regress_http.c +++ b/test/regress_http.c @@ -4705,7 +4705,7 @@ struct testcase_t http_testcases[] = { HTTP_N(cancel, cancel, BASIC), HTTP_RET_N(cancel_by_host, cancel, BY_HOST), HTTP_RET_N(cancel_by_host_inactive_server, cancel, BY_HOST | INACTIVE_SERVER), - HTTP_N(cancel_by_host_no_ns, cancel, BY_HOST | NO_NS), + HTTP_RET_N(cancel_by_host_no_ns, cancel, BY_HOST | NO_NS), HTTP_N(cancel_inactive_server, cancel, INACTIVE_SERVER), HTTP_N(cancel_by_host_no_ns_inactive_server, cancel, BY_HOST | NO_NS | INACTIVE_SERVER), HTTP_OFF_N(cancel_by_host_server_timeout, cancel, BY_HOST | INACTIVE_SERVER | SERVER_TIMEOUT), -- cgit v1.2.1 From 260db3410a369e48b1ca0a495076e8ecb6176143 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Wed, 5 Dec 2018 11:46:30 +0300 Subject: Add mailmap (cherry picked from commit 196e3a7b2bceaca5bee1914a92b9cfed41d8917d) --- .mailmap | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .mailmap diff --git a/.mailmap b/.mailmap new file mode 100644 index 00000000..0aec4646 --- /dev/null +++ b/.mailmap @@ -0,0 +1,5 @@ +# name -> email +Azat Khuzhin + +# email -> email + -- cgit v1.2.1 From 412be74a86eda7cbf89c0eb1fc6ebad19d386e87 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Wed, 5 Dec 2018 11:40:40 +0300 Subject: travis-ci: do not run coveralls with clang (SIGSEGV) This will fix coveralls badge See: https://travis-ci.org/libevent/libevent/jobs/458590276#L1425 (cherry picked from commit 3e6bec7c1aa416e3e6e85c7bda1bdc98b778d23c) --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index 7451995a..a25b78ff 100644 --- a/.travis.yml +++ b/.travis.yml @@ -39,6 +39,10 @@ compiler: - clang before_install: + # do not run with clang, since it fails (SIGSEGV) + - if [ "$CC" = "clang" ]; then + unset COVERALLS; + fi - if [ -n "$COVERALLS" ]; then pip install --user cpp-coveralls; fi -- cgit v1.2.1 From f9c5d17b0a5857fccc81397fee72de26d98f21db Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sat, 8 Dec 2018 17:35:53 +0300 Subject: test-fdleak: fix memory leaks Fixes: #726 (cherry picked from commit e5ec52d100ee94af14753513f4b4594e94eb02e1) --- test/test-fdleak.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/test/test-fdleak.c b/test/test-fdleak.c index 4c4eba25..a1fb4ed1 100644 --- a/test/test-fdleak.c +++ b/test/test-fdleak.c @@ -95,8 +95,11 @@ server_event_cb(struct bufferevent *bev, short events, void *ctx) if (events & BEV_EVENT_ERROR) { my_perror("Error from bufferevent"); exit(1); - } else if (events & (BEV_EVENT_EOF | BEV_EVENT_ERROR)) { + } else if (events & BEV_EVENT_EOF) { bufferevent_free(bev); + if (num_requests == MAX_REQUESTS) { + event_base_loopbreak(bufferevent_get_base(bev)); + } } } @@ -107,8 +110,7 @@ listener_accept_cb(struct evconnlistener *listener, evutil_socket_t sock, { struct event_base *base = evconnlistener_get_base(listener); struct bufferevent *bev = bufferevent_socket_new(base, sock, - BEV_OPT_CLOSE_ON_FREE); - + BEV_OPT_CLOSE_ON_FREE); bufferevent_setcb(bev, server_read_cb, NULL, server_event_cb, NULL); bufferevent_enable(bev, EV_READ|EV_WRITE); } @@ -154,6 +156,9 @@ start_loop(void) start_client(base); event_base_dispatch(base); + + evconnlistener_free(listener); + event_base_free(base); } /* @@ -178,9 +183,7 @@ client_read_cb(struct bufferevent *bev, void *ctx) bufferevent_free(bev); num_requests++; - if (num_requests == MAX_REQUESTS) { - event_base_loopbreak(base); - } else { + if (++num_requests < MAX_REQUESTS) { start_client(base); } } -- cgit v1.2.1 From a8155c62d899549344f9571597a24b0207dffdf3 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 9 Dec 2018 14:48:44 +0300 Subject: Do not check O_NONBLOCK for invalid fds Fixes: 6f988ee1 ("Merge branch 'check-O_NONBLOCK-in-debug'") (cherry picked from commit 9d3a415a99bbc6a7e0f0b12ae3c6c5c7e4613cf1) --- event.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/event.c b/event.c index 4f4c9d77..3816650e 100644 --- a/event.c +++ b/event.c @@ -373,17 +373,18 @@ static void event_debug_assert_not_added_(const struct event *ev) } static void event_debug_assert_socket_nonblocking_(evutil_socket_t fd) { - int flags; - if (!event_debug_mode_on_) return; + if (fd < 0) + return; #ifndef _WIN32 - if ((flags = fcntl(fd, F_GETFL, NULL)) >= 0) { - EVUTIL_ASSERT(flags & O_NONBLOCK); + { + int flags; + if ((flags = fcntl(fd, F_GETFL, NULL)) >= 0) { + EVUTIL_ASSERT(flags & O_NONBLOCK); + } } -#else - (void)flags; #endif } #else -- cgit v1.2.1 From d30e7bbac9f1669eab601c3937debb08fc01fe45 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Fri, 7 Dec 2018 21:46:27 +0300 Subject: http: fix connection retries when there more then one request for connection We should not attemp to establishe the connection if there is retry timer active, since otherwise there will be a bug. Imagine next situation: con = evhttp_connection_base_new() evhttp_connection_set_retries(con, 2) req = evhttp_request_new() evhttp_make_request(con, req, ...) # failed during connecting, and timer for 2 second scheduler (retry_ev) Then another request scheduled for this evcon: evhttp_make_request(con, req, ...) # got request from server, # and now it tries to read the response from the server # (req.kind == EVHTTP_RESPONSE) # # but at this point retry_ev scheduled, # and it schedules the connect again, # and after the connect will succeeed, it will pick request with # EVHTTP_RESPONSE for sending and this is completelly wrong and will # fail in evhttp_make_header_response() since there is no # "http_server" for this evcon This was a long standing issue, that I came across few years ago firstly, bad only now I had time to dig into it (but right now it was pretty simple, by limiting amount of CPU for the process and using rr for debug to go back and forth). (cherry picked from commit f3f7aa5afff2c0be4a1a299a1a7d0a64558abc23) --- http.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/http.c b/http.c index ae2fe591..3ed3fd9b 100644 --- a/http.c +++ b/http.c @@ -1290,6 +1290,8 @@ evhttp_request_dispatch(struct evhttp_connection* evcon) if (req == NULL) return; + EVUTIL_ASSERT(req->kind == EVHTTP_REQUEST); + /* delete possible close detection events */ evhttp_connection_stop_detectclose(evcon); @@ -2644,6 +2646,10 @@ evhttp_make_request(struct evhttp_connection *evcon, TAILQ_INSERT_TAIL(&evcon->requests, req, next); + /* We do not want to conflict with retry_ev */ + if (evcon->retry_cnt) + return (0); + /* If the connection object is not connected; make it so */ if (!evhttp_connected(evcon)) { int res = evhttp_connection_connect_(evcon); @@ -2654,7 +2660,7 @@ evhttp_make_request(struct evhttp_connection *evcon, if (res != 0) TAILQ_REMOVE(&evcon->requests, req, next); - return res; + return (res); } /* -- cgit v1.2.1 From c264028cd3e963310ce01492ff89bb1d8984ffab Mon Sep 17 00:00:00 2001 From: Fredrik Strupe Date: Sat, 15 Dec 2018 12:54:31 +0100 Subject: cmake: Fix some typos in option descriptions (cherry picked from commit f33c2ce5f89bc334230867f37d07dbfd5e3921bd) --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fa0de482..4c192262 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -125,10 +125,10 @@ option(EVENT__DISABLE_THREAD_SUPPORT "Define if libevent should not be compiled with thread support" OFF) option(EVENT__DISABLE_OPENSSL - "Define if libevent should build without support for OpenSSL encrpytion" OFF) + "Define if libevent should build without support for OpenSSL encryption" OFF) option(EVENT__DISABLE_BENCHMARK - "Defines if libevent should build without the benchmark exectuables" OFF) + "Defines if libevent should build without the benchmark executables" OFF) option(EVENT__DISABLE_TESTS "If tests should be compiled or not" OFF) @@ -143,7 +143,7 @@ option(EVENT__DISABLE_CLOCK_GETTIME "Do not use clock_gettime even if it is available" OFF) option(EVENT__FORCE_KQUEUE_CHECK - "When crosscompiling forces running a test program that verifies that Kqueue works with pipes. Note that this requires you to manually run the test program on the the cross compilation target to verify that it works. See cmake documentation for try_run for more details" OFF) + "When crosscompiling forces running a test program that verifies that Kqueue works with pipes. Note that this requires you to manually run the test program on the cross compilation target to verify that it works. See cmake documentation for try_run for more details" OFF) # TODO: Add --disable-largefile omit support for large files option(EVENT__COVERAGE -- cgit v1.2.1 From 339f76c0dc85a2096cb88a46617e7d3289f7556d Mon Sep 17 00:00:00 2001 From: baixiangcpp Date: Sat, 15 Dec 2018 21:45:36 +0800 Subject: fix a comment error Closes: #736 (cherry-picked) (cherry picked from commit 972da7c838b54c224889525a5cb9561f4024aff2) --- epolltable-internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/epolltable-internal.h b/epolltable-internal.h index da30e097..73c2e364 100644 --- a/epolltable-internal.h +++ b/epolltable-internal.h @@ -34,7 +34,7 @@ Note also that this table is a little sparse, since ADD+DEL is nonsensical ("xxx" in the list below.) - Note also also that we are shifting old_events by only 5 bits, since + Note also that we are shifting old_events by only 5 bits, since EV_READ is 2 and EV_WRITE is 4. The table was auto-generated with a python script, according to this -- cgit v1.2.1 From 61fb055a43880c2ba5c9edd6cfc7fb754c0160e8 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 17 Dec 2018 21:41:32 +0300 Subject: appveyor: cover static libs for MSVC (cherry picked from commit 51945fd9399d2392010456a6d2c49815bc8f938e) --- appveyor.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index ee4d7751..26d9f1c0 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -20,6 +20,8 @@ environment: # !EVENT_ALLOW_FAILURE - EVENT_BUILD_METHOD: "cmake" EVENT_CMAKE_OPTIONS: "" + - EVENT_BUILD_METHOD: "cmake" + EVENT_CMAKE_OPTIONS: "-DEVENT__LIBRARY_TYPE=STATIC" # EVENT_ALLOW_FAILURE - EVENT_BUILD_METHOD: "autotools" EVENT_CONFIGURE_OPTIONS: "" -- cgit v1.2.1 From c8b3ec17114ab0cd7f22b23ab576b1f8092d7b8a Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 17 Dec 2018 21:31:54 +0300 Subject: cmake: support static runtime (MSVC) Fixes: #737 (cherry picked from commit 246f44041e0782f728fa5ff2d39113005a1ab02d) --- CMakeLists.txt | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c192262..854c7e9d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -221,6 +221,34 @@ else() message(FATAL_ERROR "${EVENT_LIBRARY_TYPE} is not supported") endif() +if (${MSVC}) + set(msvc_static_runtime OFF) + if ("${EVENT_LIBRARY_TYPE}" STREQUAL "STATIC") + set(msvc_static_runtime ON) + endif() + + # For more info: + # - https://docs.microsoft.com/en-us/cpp/build/reference/md-mt-ld-use-run-time-library?view=vs-2017 + # - https://gitlab.kitware.com/cmake/community/wikis/FAQ#how-can-i-build-my-msvc-application-with-a-static-runtime + option(EVENT__MSVC_STATIC_RUNTIME + "Link static runtime libraries" + ${msvc_static_runtime}) + + if (EVENT__MSVC_STATIC_RUNTIME) + foreach (flag_var + CMAKE_C_FLAGS + CMAKE_C_FLAGS_DEBUG + CMAKE_C_FLAGS_RELEASE + CMAKE_C_FLAGS_MINSIZEREL + CMAKE_C_FLAGS_RELWITHDEBINFO + ) + if (${flag_var} MATCHES "/MD") + string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") + endif() + endforeach() + endif() +endif() + # GNUC specific options. if (${GNUC}) option(EVENT__DISABLE_GCC_WARNINGS "Disable verbose warnings with GCC" OFF) -- cgit v1.2.1 From 2ccd00a68b339e84bd4c1a51305656a260659480 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Fri, 28 Dec 2018 04:42:20 +0000 Subject: http: Preserve socket error from listen across closesocket cleanup Closes: #738 (cherry-picked) (cherry picked from commit 28d7221b851093611c65b5961e138403dd7332b6) --- http.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/http.c b/http.c index 3ed3fd9b..69071867 100644 --- a/http.c +++ b/http.c @@ -3531,13 +3531,16 @@ evhttp_bind_socket_with_handle(struct evhttp *http, const char *address, ev_uint { evutil_socket_t fd; struct evhttp_bound_socket *bound; + int serrno; if ((fd = bind_socket(address, port, 1 /*reuse*/)) == -1) return (NULL); if (listen(fd, 128) == -1) { + serrno = EVUTIL_SOCKET_ERROR(); event_sock_warn(fd, "%s: listen", __func__); evutil_closesocket(fd); + EVUTIL_SET_SOCKET_ERROR(serrno); return (NULL); } -- cgit v1.2.1 From a95cc9e39fa7961a7a3a8f75a0daa079a2a86a27 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Fri, 11 Jan 2019 21:52:11 +0300 Subject: rpc: use *_new_with_arg() to match function prototype In 755fbf16c ("Add void* arguments to request_new and reply_new evrpc hooks") this new functions had been introduced, but newer used, what for? So let's use them. (cherry picked from commit 99b231b0d875bc0814b0e4a940b6c9890d2a7754) --- include/event2/rpc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/event2/rpc.h b/include/event2/rpc.h index e7ada0b6..1bc31d57 100644 --- a/include/event2/rpc.h +++ b/include/event2/rpc.h @@ -330,10 +330,10 @@ void evrpc_free(struct evrpc_base *base); #define EVRPC_REGISTER(base, name, request, reply, callback, cbarg) \ evrpc_register_generic(base, #name, \ (void (*)(struct evrpc_req_generic *, void *))callback, cbarg, \ - (void *(*)(void *))request##_new, NULL, \ + (void *(*)(void *))request##_new_with_arg, NULL, \ (void (*)(void *))request##_free, \ (int (*)(void *, struct evbuffer *))request##_unmarshal, \ - (void *(*)(void *))reply##_new, NULL, \ + (void *(*)(void *))reply##_new_with_arg, NULL, \ (void (*)(void *))reply##_free, \ (int (*)(void *))reply##_complete, \ (void (*)(struct evbuffer *, void *))reply##_marshal) -- cgit v1.2.1 From 982a7e889b8758dc803443e49ff72f66fb30790e Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sat, 12 Jan 2019 13:58:50 +0300 Subject: test/nonpersist_readd: use assert helpers To debug failure under win32 in appveyor: https://ci.appveyor.com/project/nmathewson/libevent/builds/21559140/job/dn16qdo1j6sr497t#L1620 (cherry picked from commit 91a2f1346e80c67526261ba81c8f3b3736107bcb) --- test/regress.c | 58 +++++++++++++++++++++++----------------------------------- 1 file changed, 23 insertions(+), 35 deletions(-) diff --git a/test/regress.c b/test/regress.c index 057765ea..c08accc5 100644 --- a/test/regress.c +++ b/test/regress.c @@ -2105,60 +2105,48 @@ re_add_read_cb(evutil_socket_t fd, short event, void *arg) if (n_read < 0) { tt_fail_perror("read"); event_base_loopbreak(event_get_base(ev_other)); - return; } else { event_add(ev_other, NULL); ++test_ok; } } - static void -test_nonpersist_readd(void) +test_nonpersist_readd(void *_data) { struct event ev1, ev2; + struct basic_test_data *data = _data; - setup_test("Re-add nonpersistent events: "); - event_set(&ev1, pair[0], EV_READ, re_add_read_cb, &ev2); - event_set(&ev2, pair[1], EV_READ, re_add_read_cb, &ev1); + memset(&ev1, 0, sizeof(ev1)); + memset(&ev2, 0, sizeof(ev2)); - if (write(pair[0], "Hello", 5) < 0) { - tt_fail_perror("write(pair[0])"); - } + tt_assert(!event_assign(&ev1, data->base, data->pair[0], EV_READ, re_add_read_cb, &ev2)); + tt_assert(!event_assign(&ev2, data->base, data->pair[1], EV_READ, re_add_read_cb, &ev1)); - if (write(pair[1], "Hello", 5) < 0) { - tt_fail_perror("write(pair[1])\n"); - } + tt_int_op(write(data->pair[0], "Hello", 5), ==, 5); + tt_int_op(write(data->pair[1], "Hello", 5), ==, 5); + + tt_int_op(event_add(&ev1, NULL), ==, 0); + tt_int_op(event_add(&ev2, NULL), ==, 0); + tt_int_op(event_base_loop(data->base, EVLOOP_ONCE), ==, 0); + tt_int_op(test_ok, ==, 2); - if (event_add(&ev1, NULL) == -1 || - event_add(&ev2, NULL) == -1) { - test_ok = 0; - } - if (test_ok != 0) - exit(1); - event_loop(EVLOOP_ONCE); - if (test_ok != 2) - exit(1); /* At this point, we executed both callbacks. Whichever one got * called first added the second, but the second then immediately got * deleted before its callback was called. At this point, though, it * re-added the first. */ - if (!readd_test_event_last_added) { - test_ok = 0; - } else if (readd_test_event_last_added == &ev1) { - if (!event_pending(&ev1, EV_READ, NULL) || - event_pending(&ev2, EV_READ, NULL)) - test_ok = 0; + tt_assert(readd_test_event_last_added); + if (readd_test_event_last_added == &ev1) { + tt_assert(event_pending(&ev1, EV_READ, NULL) && !event_pending(&ev2, EV_READ, NULL)); } else { - if (event_pending(&ev1, EV_READ, NULL) || - !event_pending(&ev2, EV_READ, NULL)) - test_ok = 0; + tt_assert(event_pending(&ev2, EV_READ, NULL) && !event_pending(&ev1, EV_READ, NULL)); } - event_del(&ev1); - event_del(&ev2); - - cleanup_test(); +end: + if (event_initialized(&ev1)) + event_del(&ev1); + if (event_initialized(&ev2)) + event_del(&ev2); } struct test_pri_event { @@ -3442,7 +3430,7 @@ struct testcase_t main_testcases[] = { LEGACY(loopbreak, TT_ISOLATED), LEGACY(loopexit, TT_ISOLATED), LEGACY(loopexit_multiple, TT_ISOLATED), - LEGACY(nonpersist_readd, TT_ISOLATED), + { "nonpersist_readd", test_nonpersist_readd, TT_FORK|TT_NEED_SOCKETPAIR|TT_NEED_BASE, &basic_setup, NULL }, LEGACY(multiple_events_for_same_fd, TT_ISOLATED), LEGACY(want_only_once, TT_ISOLATED), { "event_once", test_event_once, TT_ISOLATED, &basic_setup, NULL }, -- cgit v1.2.1 From 170debc7820beabc521744b2e61c79652e2c6a32 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sat, 26 Jan 2019 18:52:33 +0300 Subject: test: adjust expecting error for getaddrinfo() under EMFILE When getaddrinfo() cannot allocate file descriptor glibc/musl-libc on linux report EAI_SYSTEM error. But this is not true for freebsd libc [1] (and hence apple libc [2]), they report EAI_NONAME error instead, so adjust expectation. [1]: https://github.com/freebsd/freebsd/blob/master/lib/libc/net/getaddrinfo.c [2]: https://opensource.apple.com/source/Libc/ Refs: #749 Refs: https://github.com/libevent/libevent/issues/749#issuecomment-457838159 (cherry picked from commit 4ffc7116177230ad2b8b94d51bbf89a14dc83687) --- test/regress_dns.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/regress_dns.c b/test/regress_dns.c index 9a3f88dc..75988a95 100644 --- a/test/regress_dns.c +++ b/test/regress_dns.c @@ -1218,7 +1218,14 @@ test_bufferevent_connect_hostname(void *arg) if (emfile) { success = BEV_EVENT_ERROR; +#ifdef __linux__ + /* on linux glibc/musl reports EAI_SYSTEM, when getaddrinfo() cannot + * open file for resolving service. */ default_error = EVUTIL_EAI_SYSTEM; +#else + /* on osx/freebsd it returns EAI_NONAME */ + default_error = EVUTIL_EAI_NONAME; +#endif } be_connect_hostname_base = data->base; -- cgit v1.2.1 From 9f02b39ce10b3cca9961dcba3d83113225042f3e Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 28 Jan 2019 22:19:20 +0300 Subject: Merge branch 'travis-ci-osx-fixes' * travis-ci-osx-fixes: travis-ci/osx: switch to xcode 10.1, since 9.4 is not compatible with gcc-8 travis-ci/osx: install gcc and fix CC (cherry picked from commit 5613bfb8dcd70ea1c89d04b550d9f97958cc48d2) --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a25b78ff..5cf9ed30 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,7 @@ os: - osx sudo: false dist: trusty +osx_image: xcode10.1 branches: except: @@ -50,7 +51,7 @@ before_install: - export TIMEOUT=50 - if [ "$TRAVIS_OS_NAME" == "osx" ]; then if [ "$CC" == "gcc" ]; then - export CC=$(ls -t /usr/local/bin/gcc-?.?); + export CC=$(ls /usr/local/Cellar/gcc/*/bin/gcc-?); fi export OPENSSL_ROOT=$(echo /usr/local/Cellar/openssl/*); @@ -82,6 +83,7 @@ addons: - openssl - lcov - libtool + - gcc script: -- cgit v1.2.1 From eb7b472b1f5f3dbeaa1196c908e6cdf95cc12097 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 29 Jan 2019 01:18:39 +0300 Subject: Merge branch 'http-EVHTTP_CON_READ_ON_WRITE_ERROR-fixes-v2' * http-EVHTTP_CON_READ_ON_WRITE_ERROR-fixes-v2: http: try to read existing data in buffer under EVHTTP_CON_READ_ON_WRITE_ERROR test: add logging for http/read_on_write_error and rearrange code http: do not call deferred readcb if readcb is not set Refs: #749 (cherry picked from commit 7bfe93886d7fccad2d9a6c76cf47c47d3668f9d1) --- http.c | 12 +++++++++++- test/regress_http.c | 33 ++++++++++++++++++--------------- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/http.c b/http.c index 69071867..5bc4a24c 100644 --- a/http.c +++ b/http.c @@ -1171,7 +1171,9 @@ static void evhttp_deferred_read_cb(struct event_callback *cb, void *data) { struct evhttp_connection *evcon = data; - evhttp_read_cb(evcon->bufev, evcon); + struct bufferevent *bev = evcon->bufev; + if (bev->readcb) + (bev->readcb)(evcon->bufev, evcon); } static void @@ -1532,6 +1534,14 @@ evhttp_error_cb(struct bufferevent *bufev, short what, void *arg) return; } + if (what & BEV_EVENT_READING && + evcon->flags & EVHTTP_CON_READ_ON_WRITE_ERROR && + evbuffer_get_length(bufferevent_get_input(bufev))) { + event_deferred_cb_schedule_(get_deferred_queue(evcon), + &evcon->read_more_deferred_cb); + return; + } + evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF); } else if (what == BEV_EVENT_CONNECTED) { } else { diff --git a/test/regress_http.c b/test/regress_http.c index 624aefc0..6309f600 100644 --- a/test/regress_http.c +++ b/test/regress_http.c @@ -4054,31 +4054,27 @@ http_data_length_constraints_test_impl(void *arg, int read_on_write_error) tt_assert(continue_size < size); + long_str = malloc(size); + memset(long_str, 'a', size); + long_str[size - 1] = '\0'; + + TT_BLATHER(("Creating connection to :%i", port)); evcon = evhttp_connection_base_new(data->base, NULL, "127.0.0.1", port); tt_assert(evcon); if (read_on_write_error) tt_assert(!evhttp_connection_set_flags(evcon, EVHTTP_CON_READ_ON_WRITE_ERROR)); - /* also bind to local host */ evhttp_connection_set_local_address(evcon, "127.0.0.1"); - /* - * At this point, we want to schedule an HTTP GET request - * server using our make request method. - */ + evhttp_set_max_headers_size(http, size - 1); + TT_BLATHER(("Set max header size %zu", size - 1)); req = evhttp_request_new(http_data_length_constraints_test_done, data->base); tt_assert(req); - - long_str = malloc(size); - memset(long_str, 'a', size); - long_str[size - 1] = '\0'; - /* Add the information that we care about */ - evhttp_set_max_headers_size(http, size - 1); evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); evhttp_add_header(evhttp_request_get_output_headers(req), "Longheader", long_str); - + TT_BLATHER(("GET /?arg=val")); if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/?arg=val") == -1) { tt_abort_msg("Couldn't make request"); } @@ -4087,19 +4083,22 @@ http_data_length_constraints_test_impl(void *arg, int read_on_write_error) req = evhttp_request_new(http_data_length_constraints_test_done, data->base); tt_assert(req); evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); - /* GET /?arg=verylongvalue HTTP/1.1 */ + TT_BLATHER(("GET %s", long_str)); if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, long_str) == -1) { tt_abort_msg("Couldn't make request"); } event_base_dispatch(data->base); + evhttp_set_max_body_size(http, size - 2); + TT_BLATHER(("Set body header size %zu", size - 2)); + if (read_on_write_error) cb = http_large_entity_test_done; - evhttp_set_max_body_size(http, size - 2); req = evhttp_request_new(cb, data->base); evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); evbuffer_add_printf(evhttp_request_get_output_buffer(req), "%s", long_str); + TT_BLATHER(("POST /")); if (evhttp_make_request(evcon, req, EVHTTP_REQ_POST, "/") == -1) { tt_abort_msg("Couldn't make request"); } @@ -4109,16 +4108,19 @@ http_data_length_constraints_test_impl(void *arg, int read_on_write_error) evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); evhttp_add_header(evhttp_request_get_output_headers(req), "Expect", "100-continue"); evbuffer_add_printf(evhttp_request_get_output_buffer(req), "%s", long_str); + TT_BLATHER(("POST / (Expect: 100-continue, http_large_entity_test_done)")); if (evhttp_make_request(evcon, req, EVHTTP_REQ_POST, "/") == -1) { tt_abort_msg("Couldn't make request"); } event_base_dispatch(data->base); + long_str[continue_size] = '\0'; + req = evhttp_request_new(http_dispatcher_test_done, data->base); evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); evhttp_add_header(evhttp_request_get_output_headers(req), "Expect", "100-continue"); - long_str[continue_size] = '\0'; evbuffer_add_printf(evhttp_request_get_output_buffer(req), "%s", long_str); + TT_BLATHER(("POST / (Expect: 100-continue, http_dispatcher_test_done)")); if (evhttp_make_request(evcon, req, EVHTTP_REQ_POST, "/") == -1) { tt_abort_msg("Couldn't make request"); } @@ -4130,6 +4132,7 @@ http_data_length_constraints_test_impl(void *arg, int read_on_write_error) evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); evhttp_add_header(evhttp_request_get_output_headers(req), "Expect", "101-continue"); evbuffer_add_printf(evhttp_request_get_output_buffer(req), "%s", long_str); + TT_BLATHER(("POST / (Expect: 101-continue)")); if (evhttp_make_request(evcon, req, EVHTTP_REQ_POST, "/") == -1) { tt_abort_msg("Couldn't make request"); } -- cgit v1.2.1 From 8eb00842142839af1458021a23695a7ebbdea4d4 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 29 Jan 2019 01:23:02 +0300 Subject: s/http-server: fix cleanup routines Fixes: bdd71f18 ("s/http-server: graceful cleanup") (cherry picked from commit afdccee9b3648a76e119fb4d5f922191cd09d748) --- sample/http-server.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sample/http-server.c b/sample/http-server.c index e2fc8499..75379968 100644 --- a/sample/http-server.c +++ b/sample/http-server.c @@ -435,6 +435,7 @@ main(int argc, char **argv) if (!handle) { fprintf(stderr, "couldn't bind to port %d. Exiting.\n", o.port); ret = 1; + goto err; } { @@ -462,6 +463,7 @@ main(int argc, char **argv) fprintf(stderr, "Weird address family %d\n", ss.ss_family); ret = 1; + goto err; } addr = evutil_inet_ntop(ss.ss_family, inaddr, addrbuf, sizeof(addrbuf)); @@ -472,6 +474,7 @@ main(int argc, char **argv) } else { fprintf(stderr, "evutil_inet_ntop failed\n"); ret = 1; + goto err; } } -- cgit v1.2.1 From 3ebd7edd024589f3e7581cc89014cea90ea1a2f9 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 29 Jan 2019 10:10:23 +0300 Subject: Add OS-specific exclude patterns of the branch names for the CI (cherry picked from commit f88b8946f3da988f7aa80e36681037b4f474840e) --- .travis.yml | 3 +++ appveyor.yml | 3 +++ 2 files changed, 6 insertions(+) diff --git a/.travis.yml b/.travis.yml index 5cf9ed30..f7bd6d85 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,9 @@ osx_image: xcode10.1 branches: except: - /.*appveyor.*/ + - /.*win.*/ + - /.*mingw.*/ + - /.*freebsd.*/ git: quiet: true diff --git a/appveyor.yml b/appveyor.yml index 26d9f1c0..2c5caaa4 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -5,6 +5,9 @@ os: Visual Studio 2015 branches: except: - /.*travis.*/ + - /.*linux.*/ + - /.*freebsd.*/ + - /.*osx.*/ skip_commits: message: /travis/ files: -- cgit v1.2.1 From 1d9319c7fb13b3e3fa662fc5a2b7212373ac9d13 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 29 Jan 2019 07:56:21 +0300 Subject: win32select: print an error in case of failure (cherry picked from commit 8882f4fd60aa61fe1caf8b372989427a9872c3b9) --- win32select.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/win32select.c b/win32select.c index 1766858c..0ddfe4b4 100644 --- a/win32select.c +++ b/win32select.c @@ -326,6 +326,8 @@ win32_dispatch(struct event_base *base, struct timeval *tv) event_debug(("%s: select returned %d", __func__, res)); if (res <= 0) { + event_debug(("%s: %s", __func__, + evutil_socket_error_to_string(EVUTIL_SOCKET_ERROR()))); return res; } -- cgit v1.2.1 From aee0fcd57c2f42c10ce83db3450541057ed59c52 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 29 Jan 2019 10:54:39 +0300 Subject: Merge branch 'win64-fixes' * win64-fixes: test/et/et: fix it by using appropriate type for the SOCKET (evutil_socket_t) test/et/et: verify return codes appveyor: switch to new VS/MinGW and x64 (cherry picked from commit 97a3e7f5802ce1baa3c959905e312cab2bebf4bf) --- appveyor.yml | 37 ++++++++++++++++++++++--------------- test/regress_et.c | 12 ++++++------ 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 2c5caaa4..c6f72a21 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,6 +1,8 @@ version: 2.1.8.{build} -os: Visual Studio 2015 +os: Visual Studio 2017 +platform: + - x64 branches: except: @@ -16,7 +18,9 @@ skip_commits: environment: global: APPVEYOR_SAVE_CACHE_ON_ERROR: true - CYG_ROOT: C:/MinGW/msys/1.0 + MINGW_ROOT: C:/mingw-w64/x86_64-7.2.0-posix-seh-rt_v5-rev1 + OPENSSL_ROOT: C:/OpenSSL-Win64 + MPATH: C:/mingw-w64/x86_64-7.2.0-posix-seh-rt_v5-rev1/bin;C:/msys64/bin;C:/cygwin64/bin EVENT_TESTS_PARALLEL: 20 EVENT_BUILD_PARALLEL: 10 matrix: @@ -63,29 +67,32 @@ matrix: fast_finish: true init: - - 'echo Building libevent %version% for Windows' - - 'echo System architecture: %PLATFORM%' - 'echo Repo build branch is: %APPVEYOR_REPO_BRANCH%' - 'echo Build folder is: %APPVEYOR_BUILD_FOLDER%' - 'echo Repo build commit is: %APPVEYOR_REPO_COMMIT%' - - 'echo Cygwin root is: %CYG_ROOT%' -install: - - C:\MinGW\bin\mingw-get install autotools autoconf automake + - 'echo PATH is: %PATH%' + build_script: - ps: | if ($env:EVENT_BUILD_METHOD -eq 'autotools') { - $env:PATH="$env:CYG_ROOT\bin;C:\MinGW\bin;$($env:PATH)" - bash -lc "echo 'C:\MinGW /mingw' > /etc/fstab" - bash -lc "echo 'C:\OpenSSL-Win32 /ssl' >> /etc/fstab" - $env:APPVEYOR_BUILD_FOLDER = $env:APPVEYOR_BUILD_FOLDER -replace "\\", "/" - bash -lc "exec 0&1; cd $env:APPVEYOR_BUILD_FOLDER; bash -x ./autogen.sh && mkdir -p build-autotools && cd build-autotools && ../configure LDFLAGS='-L/ssl -L/ssl/lib -L/ssl/lib/MinGW' CFLAGS=-I/ssl/include $env:EVENT_CONFIGURE_OPTIONS && make -j $env:EVENT_BUILD_PARALLEL && make verify -j$env:EVENT_TESTS_PARALLEL" + $env:PATH="$env:MPATH;$env:OPENSSL_ROOT/bin;$env:PATH" + $env:LDFLAGS="-L$($env:OPENSSL_ROOT)/lib -L$($env:OPENSSL_ROOT)" + $env:CFLAGS="-I$($env:OPENSSL_ROOT)/include" + + bash ./autogen.sh 2>&1 3>&1 + + md build-autotools 2> $null + cd build-autotools + + bash ../configure $env:EVENT_CONFIGURE_OPTIONS 2>&1 + make -j $env:EVENT_BUILD_PARALLEL 2>&1 + make verify -j $env:EVENT_TESTS_PARALLEL 2>&1 } else { md build-cmake 2> $null cd build-cmake - cmake .. $env:EVENT_CMAKE_OPTIONS + cmake -G "Visual Studio 15 2017 Win64" .. $env:EVENT_CMAKE_OPTIONS cmake --build . -j $env:EVENT_BUILD_PARALLEL - $env:CTEST_PARALLEL_LEVEL=$env:EVENT_TESTS_PARALLEL - ctest --output-on-failure + ctest --output-on-failure -j $env:EVENT_TESTS_PARALLEL } cache: diff --git a/test/regress_et.c b/test/regress_et.c index 07bcd4a5..4c7dc45f 100644 --- a/test/regress_et.c +++ b/test/regress_et.c @@ -95,7 +95,7 @@ test_edgetriggered(void *data_) called = was_et = 0; tt_int_op(send(pair[0], test, (int)strlen(test)+1, 0), >, 0); - shutdown(pair[0], EVUTIL_SHUT_WR); + tt_int_op(shutdown(pair[0], EVUTIL_SHUT_WR), ==, 0); supports_et = base_supports_et(base); TT_BLATHER(("Checking for edge-triggered events with %s, which should %s" @@ -104,8 +104,8 @@ test_edgetriggered(void *data_) /* Initalize one event */ ev = event_new(base, pair[1], EV_READ|EV_ET|EV_PERSIST, read_cb, &ev); - - event_add(ev, NULL); + tt_assert(ev != NULL); + tt_int_op(event_add(ev, NULL), ==, 0); /* We're going to call the dispatch function twice. The first invocation * will read a single byte from pair[1] in either case. If we're edge @@ -114,8 +114,8 @@ test_edgetriggered(void *data_) * do nothing. If we're level triggered, the second invocation of * event_base_loop will also activate the event (because there's still * data to read). */ - event_base_loop(base,EVLOOP_NONBLOCK|EVLOOP_ONCE); - event_base_loop(base,EVLOOP_NONBLOCK|EVLOOP_ONCE); + tt_int_op(event_base_loop(base,EVLOOP_NONBLOCK|EVLOOP_ONCE), ==, 0); + tt_int_op(event_base_loop(base,EVLOOP_NONBLOCK|EVLOOP_ONCE), ==, 0); if (supports_et) { tt_int_op(called, ==, 1); @@ -209,7 +209,7 @@ test_edge_triggered_multiple_events(void *data_) struct event *write_ev = NULL; const char c = 'A'; struct event_base *base = data->base; - int *pair = data->pair; + evutil_socket_t *pair = data->pair; if (!base_supports_et(base)) { tt_skip(); -- cgit v1.2.1 From fa193d128f97371c2674a9c2ce94d05666fd9ee8 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 29 Jan 2019 20:58:01 +0300 Subject: appveyor: disable verbosity of MSBuild (cherry picked from commit e2e82241d182807b154dad5c546d9ef4581eb489) --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index c6f72a21..be71576e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -91,7 +91,7 @@ build_script: md build-cmake 2> $null cd build-cmake cmake -G "Visual Studio 15 2017 Win64" .. $env:EVENT_CMAKE_OPTIONS - cmake --build . -j $env:EVENT_BUILD_PARALLEL + cmake --build . -j $env:EVENT_BUILD_PARALLEL -- /nologo /verbosity:minimal ctest --output-on-failure -j $env:EVENT_TESTS_PARALLEL } -- cgit v1.2.1 From 283da0472133fd65dc2b5af04689dbdfcc7a572b Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 29 Jan 2019 21:06:37 +0300 Subject: test/et/et: use evutil_socket_t* over int* for pointer to the pair Next code will not work correctly under win x64: evutil_socket_t very_long_pair_name[2]; int *pair = very_long_pair_name; // <-- accessing the second word of the first element Because sizeof(evutil_socket_t) == sizeof(intptr_t) == 8 P.S. in the 5334762f another test had been fixed instead of the one that really fails. Fixes: 5334762f ("test/et/et: fix it by using appropriate type for the SOCKET (evutil_socket_t)") Refs: #750 (cherry picked from commit 0791a17204ff70bbea92520352a0c6e8d185fa4b) --- test/regress_et.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/regress_et.c b/test/regress_et.c index 4c7dc45f..5fa87a39 100644 --- a/test/regress_et.c +++ b/test/regress_et.c @@ -80,7 +80,7 @@ test_edgetriggered(void *data_) { struct basic_test_data *data = data_; struct event_base *base = data->base; - int *pair = data->pair; + evutil_socket_t *pair = data->pair; struct event *ev = NULL; const char *test = "test string"; int supports_et; -- cgit v1.2.1 From 048bee0a124e851d2ce0e87107304428f85f931c Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 29 Jan 2019 21:31:19 +0300 Subject: evmap: use approparite type for changes to avoid warnings under windows (cherry picked from commit 74c10894117f9dd2b230ec8d0e30d41c08df3b45) --- evmap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/evmap.c b/evmap.c index 31ab4fee..9f46dd0f 100644 --- a/evmap.c +++ b/evmap.c @@ -859,7 +859,7 @@ event_changelist_add_(struct event_base *base, evutil_socket_t fd, short old, sh struct event_changelist *changelist = &base->changelist; struct event_changelist_fdinfo *fdinfo = p; struct event_change *change; - short evchange = EV_CHANGE_ADD | (events & (EV_ET|EV_PERSIST|EV_SIGNAL)); + ev_uint8_t evchange = EV_CHANGE_ADD | (events & (EV_ET|EV_PERSIST|EV_SIGNAL)); event_changelist_check(base); @@ -889,7 +889,7 @@ event_changelist_del_(struct event_base *base, evutil_socket_t fd, short old, sh struct event_changelist *changelist = &base->changelist; struct event_changelist_fdinfo *fdinfo = p; struct event_change *change; - short del = EV_CHANGE_DEL | (events & EV_ET); + ev_uint8_t del = EV_CHANGE_DEL | (events & EV_ET); event_changelist_check(base); change = event_changelist_get_or_construct(changelist, fd, old, fdinfo); -- cgit v1.2.1 From e66078a04372d7bb2c7b2ae0c55b56cf514fcf64 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 29 Jan 2019 21:12:33 +0300 Subject: Eliminate fd conversion warnings and introduce EVUTIL_INVALID_SOCKET (windows) windows has intptr_t instead of regular int. Also tt_fd_op() had been introduced, since we cannot use tt_int_op() for comparing fd, since it is not always int. (cherry picked from commit b29207dceee33832bb28ab103a833df6a2fd29d3) --- bufferevent_async.c | 8 +++---- bufferevent_openssl.c | 14 ++++++------ bufferevent_sock.c | 3 ++- event_iocp.c | 2 +- include/event2/util.h | 7 ++++-- listener.c | 16 ++++++------- test/regress.c | 2 +- test/regress_bufferevent.c | 10 ++++----- test/regress_http.c | 56 ++++++++++++++++++++++++++-------------------- test/regress_listener.c | 13 ++++++----- test/regress_ssl.c | 12 +++++----- test/tinytest_macros.h | 8 +++++++ 12 files changed, 86 insertions(+), 65 deletions(-) diff --git a/bufferevent_async.c b/bufferevent_async.c index d2eefed4..141cf34f 100644 --- a/bufferevent_async.c +++ b/bufferevent_async.c @@ -402,10 +402,10 @@ be_async_destruct(struct bufferevent *bev) bev_async_del_write(bev_async); fd = evbuffer_overlapped_get_fd_(bev->input); - if (fd != (evutil_socket_t)INVALID_SOCKET && + if (fd != (evutil_socket_t)EVUTIL_INVALID_SOCKET && (bev_p->options & BEV_OPT_CLOSE_ON_FREE)) { evutil_closesocket(fd); - evbuffer_overlapped_set_fd_(bev->input, INVALID_SOCKET); + evbuffer_overlapped_set_fd_(bev->input, EVUTIL_INVALID_SOCKET); } } @@ -688,10 +688,10 @@ be_async_ctrl(struct bufferevent *bev, enum bufferevent_ctrl_op op, case BEV_CTRL_CANCEL_ALL: { struct bufferevent_async *bev_a = upcast(bev); evutil_socket_t fd = evbuffer_overlapped_get_fd_(bev->input); - if (fd != (evutil_socket_t)INVALID_SOCKET && + if (fd != (evutil_socket_t)EVUTIL_INVALID_SOCKET && (bev_a->bev.options & BEV_OPT_CLOSE_ON_FREE)) { closesocket(fd); - evbuffer_overlapped_set_fd_(bev->input, INVALID_SOCKET); + evbuffer_overlapped_set_fd_(bev->input, EVUTIL_INVALID_SOCKET); } bev_a->ok = 0; return 0; diff --git a/bufferevent_openssl.c b/bufferevent_openssl.c index 8e2b361c..beebe071 100644 --- a/bufferevent_openssl.c +++ b/bufferevent_openssl.c @@ -964,8 +964,8 @@ be_openssl_writeeventcb(evutil_socket_t fd, short what, void *ptr) bufferevent_decref_and_unlock_(&bev_ssl->bev.bev); } -static int -be_openssl_auto_fd(struct bufferevent_openssl *bev_ssl, int fd) +static evutil_socket_t +be_openssl_auto_fd(struct bufferevent_openssl *bev_ssl, evutil_socket_t fd) { if (!bev_ssl->underlying) { struct bufferevent *bev = &bev_ssl->bev.bev; @@ -1031,7 +1031,7 @@ do_handshake(struct bufferevent_openssl *bev_ssl) decrement_buckets(bev_ssl); if (r==1) { - int fd = event_get_fd(&bev_ssl->bev.bev.ev_read); + evutil_socket_t fd = event_get_fd(&bev_ssl->bev.bev.ev_read); /* We're done! */ bev_ssl->state = BUFFEREVENT_SSL_OPEN; set_open_callbacks(bev_ssl, fd); /* XXXX handle failure */ @@ -1229,7 +1229,7 @@ be_openssl_destruct(struct bufferevent *bev) if (bev_ssl->bev.options & BEV_OPT_CLOSE_ON_FREE) { if (! bev_ssl->underlying) { - evutil_socket_t fd = -1; + evutil_socket_t fd = EVUTIL_INVALID_SOCKET; BIO *bio = SSL_get_wbio(bev_ssl->ssl); if (bio) fd = BIO_get_fd(bio, NULL); @@ -1262,7 +1262,7 @@ be_openssl_flush(struct bufferevent *bufev, static int be_openssl_set_fd(struct bufferevent_openssl *bev_ssl, - enum bufferevent_ssl_state state, int fd) + enum bufferevent_ssl_state state, evutil_socket_t fd) { bev_ssl->state = state; @@ -1301,7 +1301,7 @@ be_openssl_ctrl(struct bufferevent *bev, case BEV_CTRL_SET_FD: if (!bev_ssl->underlying) { BIO *bio; - bio = BIO_new_socket(data->fd, 0); + bio = BIO_new_socket((int)data->fd, 0); SSL_set_bio(bev_ssl->ssl, bio, bio); } else { BIO *bio; @@ -1465,7 +1465,7 @@ bufferevent_openssl_socket_new(struct event_base *base, /* The SSL isn't configured with a BIO with an fd. */ if (fd >= 0) { /* ... and we have an fd we want to use. */ - bio = BIO_new_socket(fd, 0); + bio = BIO_new_socket((int)fd, 0); SSL_set_bio(ssl, bio, bio); } else { /* Leave the fd unset. */ diff --git a/bufferevent_sock.c b/bufferevent_sock.c index 48d6c7e9..f275b023 100644 --- a/bufferevent_sock.c +++ b/bufferevent_sock.c @@ -104,7 +104,8 @@ bufferevent_socket_get_conn_address_(struct bufferevent *bev) } void -bufferevent_socket_set_conn_address_fd_(struct bufferevent *bev, int fd) +bufferevent_socket_set_conn_address_fd_(struct bufferevent *bev, + evutil_socket_t fd) { struct bufferevent_private *bev_p = BEV_UPCAST(bev); diff --git a/event_iocp.c b/event_iocp.c index a9902fbc..6b2a2e15 100644 --- a/event_iocp.c +++ b/event_iocp.c @@ -151,7 +151,7 @@ init_extension_functions(struct win32_extension_fns *ext) const GUID connectex = WSAID_CONNECTEX; const GUID getacceptexsockaddrs = WSAID_GETACCEPTEXSOCKADDRS; SOCKET s = socket(AF_INET, SOCK_STREAM, 0); - if (s == INVALID_SOCKET) + if (s == EVUTIL_INVALID_SOCKET) return; ext->AcceptEx = get_extension_function(s, &acceptex); ext->ConnectEx = get_extension_function(s, &connectex); diff --git a/include/event2/util.h b/include/event2/util.h index 80574c71..7c872737 100644 --- a/include/event2/util.h +++ b/include/event2/util.h @@ -484,6 +484,7 @@ int evutil_socket_geterror(evutil_socket_t sock); /** Convert a socket error to a string. */ EVENT2_EXPORT_SYMBOL const char *evutil_socket_error_to_string(int errcode); +#define EVUTIL_INVALID_SOCKET INVALID_SOCKET #elif defined(EVENT_IN_DOXYGEN_) /** @name Socket error functions @@ -507,14 +508,16 @@ const char *evutil_socket_error_to_string(int errcode); #define evutil_socket_geterror(sock) ... /** Convert a socket error to a string. */ #define evutil_socket_error_to_string(errcode) ... +#define EVUTIL_INVALID_SOCKET -1 /**@}*/ -#else +#else /** !EVENT_IN_DOXYGEN_ && !_WIN32 */ #define EVUTIL_SOCKET_ERROR() (errno) #define EVUTIL_SET_SOCKET_ERROR(errcode) \ do { errno = (errcode); } while (0) #define evutil_socket_geterror(sock) (errno) #define evutil_socket_error_to_string(errcode) (strerror(errcode)) -#endif +#define EVUTIL_INVALID_SOCKET -1 +#endif /** !_WIN32 */ /** diff --git a/listener.c b/listener.c index e803bed1..387a89e9 100644 --- a/listener.c +++ b/listener.c @@ -512,7 +512,7 @@ new_accepting_socket(struct evconnlistener_iocp *lev, int family) return NULL; event_overlapped_init_(&res->overlapped, accepted_socket_cb); - res->s = INVALID_SOCKET; + res->s = EVUTIL_INVALID_SOCKET; res->lev = lev; res->buflen = buflen; res->family = family; @@ -530,7 +530,7 @@ static void free_and_unlock_accepting_socket(struct accepting_socket *as) { /* requires lock. */ - if (as->s != INVALID_SOCKET) + if (as->s != EVUTIL_INVALID_SOCKET) closesocket(as->s); LeaveCriticalSection(&as->lock); @@ -550,7 +550,7 @@ start_accepting(struct accepting_socket *as) if (!as->lev->base.enabled) return 0; - if (s == INVALID_SOCKET) { + if (s == EVUTIL_INVALID_SOCKET) { error = WSAGetLastError(); goto report_err; } @@ -597,7 +597,7 @@ stop_accepting(struct accepting_socket *as) { /* requires lock. */ SOCKET s = as->s; - as->s = INVALID_SOCKET; + as->s = EVUTIL_INVALID_SOCKET; closesocket(s); } @@ -639,7 +639,7 @@ accepted_socket_invoke_user_cb(struct event_callback *dcb, void *arg) &socklen_remote); sock = as->s; cb = lev->cb; - as->s = INVALID_SOCKET; + as->s = EVUTIL_INVALID_SOCKET; /* We need to call this so getsockname, getpeername, and * shutdown work correctly on the accepted socket. */ @@ -687,7 +687,7 @@ accepted_socket_cb(struct event_overlapped *o, ev_uintptr_t key, ev_ssize_t n, i free_and_unlock_accepting_socket(as); listener_decref_and_unlock(lev); return; - } else if (as->s == INVALID_SOCKET) { + } else if (as->s == EVUTIL_INVALID_SOCKET) { /* This is okay; we were disabled by iocp_listener_disable. */ LeaveCriticalSection(&as->lock); } else { @@ -725,7 +725,7 @@ iocp_listener_enable(struct evconnlistener *lev) if (!as) continue; EnterCriticalSection(&as->lock); - if (!as->free_on_cb && as->s == INVALID_SOCKET) + if (!as->free_on_cb && as->s == EVUTIL_INVALID_SOCKET) start_accepting(as); LeaveCriticalSection(&as->lock); } @@ -747,7 +747,7 @@ iocp_listener_disable_impl(struct evconnlistener *lev, int shutdown) if (!as) continue; EnterCriticalSection(&as->lock); - if (!as->free_on_cb && as->s != INVALID_SOCKET) { + if (!as->free_on_cb && as->s != EVUTIL_INVALID_SOCKET) { if (shutdown) as->free_on_cb = 1; stop_accepting(as); diff --git a/test/regress.c b/test/regress.c index c08accc5..2c17dba3 100644 --- a/test/regress.c +++ b/test/regress.c @@ -3118,7 +3118,7 @@ test_get_assignment(void *arg) event_get_assignment(ev1, &b, &s, &what, &cb, &cb_arg); tt_ptr_op(b, ==, base); - tt_int_op(s, ==, data->pair[1]); + tt_fd_op(s, ==, data->pair[1]); tt_int_op(what, ==, EV_READ); tt_ptr_op(cb, ==, dummy_read_cb); tt_ptr_op(cb_arg, ==, str); diff --git a/test/regress_bufferevent.c b/test/regress_bufferevent.c index 55d8e135..3ed48fae 100644 --- a/test/regress_bufferevent.c +++ b/test/regress_bufferevent.c @@ -137,14 +137,14 @@ test_bufferevent_impl(int use_pair, int flush) bev2 = pair[1]; bufferevent_setcb(bev1, readcb, writecb, errorcb, bev1); bufferevent_setcb(bev2, readcb, writecb, errorcb, NULL); - tt_int_op(bufferevent_getfd(bev1), ==, -1); + tt_fd_op(bufferevent_getfd(bev1), ==, EVUTIL_INVALID_SOCKET); tt_ptr_op(bufferevent_get_underlying(bev1), ==, NULL); tt_ptr_op(bufferevent_pair_get_partner(bev1), ==, bev2); tt_ptr_op(bufferevent_pair_get_partner(bev2), ==, bev1); } else { bev1 = bufferevent_new(pair[0], readcb, writecb, errorcb, NULL); bev2 = bufferevent_new(pair[1], readcb, writecb, errorcb, NULL); - tt_int_op(bufferevent_getfd(bev1), ==, pair[0]); + tt_fd_op(bufferevent_getfd(bev1), ==, pair[0]); tt_ptr_op(bufferevent_get_underlying(bev1), ==, NULL); tt_ptr_op(bufferevent_pair_get_partner(bev1), ==, NULL); tt_ptr_op(bufferevent_pair_get_partner(bev2), ==, NULL); @@ -569,8 +569,8 @@ test_bufferevent_filters_impl(int use_pair, int disable) tt_ptr_op(bufferevent_get_underlying(bev1), ==, bev1_base); tt_ptr_op(bufferevent_get_underlying(bev2), ==, bev2_base); - tt_int_op(bufferevent_getfd(bev1), ==, bufferevent_getfd(bev1_base)); - tt_int_op(bufferevent_getfd(bev2), ==, bufferevent_getfd(bev2_base)); + tt_fd_op(bufferevent_getfd(bev1), ==, bufferevent_getfd(bev1_base)); + tt_fd_op(bufferevent_getfd(bev2), ==, bufferevent_getfd(bev2_base)); bufferevent_disable(bev1, EV_READ); bufferevent_enable(bev2, EV_READ); @@ -640,7 +640,7 @@ end: ; } -static int +static evutil_socket_t fake_listener_create(struct sockaddr_in *localhost) { struct sockaddr *sa = (struct sockaddr *)localhost; diff --git a/test/regress_http.c b/test/regress_http.c index 6309f600..e6d3cdff 100644 --- a/test/regress_http.c +++ b/test/regress_http.c @@ -181,7 +181,7 @@ http_connect(const char *address, ev_uint16_t port) char strport[NI_MAXSERV]; struct sockaddr *sa; - int slen; + size_t slen; evutil_socket_t fd; memset(&ai, 0, sizeof(ai)); @@ -374,7 +374,7 @@ end: evbuffer_free(evb); } -static void http_timeout_reply_cb(int fd, short events, void *arg) +static void http_timeout_reply_cb(evutil_socket_t fd, short events, void *arg) { struct evhttp_request *req = arg; evhttp_send_reply(req, HTTP_OK, "Everything is fine", NULL); @@ -457,7 +457,7 @@ http_chunked_cb(struct evhttp_request *req, void *arg) } static struct bufferevent * -create_bev(struct event_base *base, int fd, int ssl_mask) +create_bev(struct event_base *base, evutil_socket_t fd, int ssl_mask) { int flags = BEV_OPT_DEFER_CALLBACKS; struct bufferevent *bev = NULL; @@ -684,7 +684,7 @@ http_bad_request_test(void *arg) struct basic_test_data *data = arg; struct timeval tv; struct bufferevent *bev = NULL; - evutil_socket_t fd = -1; + evutil_socket_t fd = EVUTIL_INVALID_SOCKET; const char *http_request; ev_uint16_t port=0, port2=0; struct evhttp *http = http_setup(&port, data->base, 0); @@ -698,7 +698,7 @@ http_bad_request_test(void *arg) /* NULL request test */ fd = http_connect("127.0.0.1", port); - tt_int_op(fd, >=, 0); + tt_assert(fd != EVUTIL_INVALID_SOCKET); /* Stupid thing to send a request */ bev = bufferevent_socket_new(data->base, fd, 0); @@ -730,6 +730,7 @@ http_bad_request_test(void *arg) /* connect to the second port */ fd = http_connect("127.0.0.1", port2); + tt_assert(fd != EVUTIL_INVALID_SOCKET); /* Stupid thing to send a request */ bev = bufferevent_socket_new(data->base, fd, 0); @@ -805,7 +806,7 @@ http_delete_test(void *arg) { struct basic_test_data *data = arg; struct bufferevent *bev; - evutil_socket_t fd = -1; + evutil_socket_t fd = EVUTIL_INVALID_SOCKET; const char *http_request; ev_uint16_t port = 0; struct evhttp *http = http_setup(&port, data->base, 0); @@ -815,7 +816,7 @@ http_delete_test(void *arg) tt_assert(http); fd = http_connect("127.0.0.1", port); - tt_int_op(fd, >=, 0); + tt_assert(fd != EVUTIL_INVALID_SOCKET); /* Stupid thing to send a request */ bev = bufferevent_socket_new(data->base, fd, 0); @@ -834,7 +835,7 @@ http_delete_test(void *arg) bufferevent_free(bev); evutil_closesocket(fd); - fd = -1; + fd = EVUTIL_INVALID_SOCKET; evhttp_free(http); @@ -889,7 +890,7 @@ http_on_complete_test(void *arg) { struct basic_test_data *data = arg; struct bufferevent *bev; - evutil_socket_t fd = -1; + evutil_socket_t fd = EVUTIL_INVALID_SOCKET; const char *http_request; ev_uint16_t port = 0; struct evhttp *http = http_setup(&port, data->base, 0); @@ -898,7 +899,7 @@ http_on_complete_test(void *arg) test_ok = 0; fd = http_connect("127.0.0.1", port); - tt_int_op(fd, >=, 0); + tt_assert(fd != EVUTIL_INVALID_SOCKET); /* Stupid thing to send a request */ bev = bufferevent_socket_new(data->base, fd, 0); @@ -959,7 +960,7 @@ http_allowed_methods_test(void *arg) test_ok = 0; fd1 = http_connect("127.0.0.1", port); - tt_int_op(fd1, >=, 0); + tt_assert(fd1 != EVUTIL_INVALID_SOCKET); /* GET is out; PATCH is in. */ evhttp_set_allowed_methods(http, EVHTTP_REQ_PATCH); @@ -981,7 +982,7 @@ http_allowed_methods_test(void *arg) event_base_dispatch(data->base); fd2 = http_connect("127.0.0.1", port); - tt_int_op(fd2, >=, 0); + tt_assert(fd2 != EVUTIL_INVALID_SOCKET); bev2 = bufferevent_socket_new(data->base, fd2, 0); bufferevent_enable(bev2, EV_READ|EV_WRITE); @@ -999,7 +1000,7 @@ http_allowed_methods_test(void *arg) event_base_dispatch(data->base); fd3 = http_connect("127.0.0.1", port); - tt_int_op(fd3, >=, 0); + tt_assert(fd3 != EVUTIL_INVALID_SOCKET); bev3 = bufferevent_socket_new(data->base, fd3, 0); bufferevent_enable(bev3, EV_READ|EV_WRITE); @@ -1787,6 +1788,7 @@ http_virtual_host_test(void *arg) /* Now make a raw request with an absolute URI. */ fd = http_connect("127.0.0.1", port); + tt_assert(fd != EVUTIL_INVALID_SOCKET); /* Stupid thing to send a request */ bev = bufferevent_socket_new(data->base, fd, 0); @@ -2229,7 +2231,7 @@ http_failure_test(void *arg) { struct basic_test_data *data = arg; struct bufferevent *bev; - evutil_socket_t fd = -1; + evutil_socket_t fd = EVUTIL_INVALID_SOCKET; const char *http_request; ev_uint16_t port = 0; struct evhttp *http = http_setup(&port, data->base, 0); @@ -2237,7 +2239,7 @@ http_failure_test(void *arg) test_ok = 0; fd = http_connect("127.0.0.1", port); - tt_int_op(fd, >=, 0); + tt_assert(fd != EVUTIL_INVALID_SOCKET); /* Stupid thing to send a request */ bev = bufferevent_socket_new(data->base, fd, 0); @@ -3027,7 +3029,7 @@ http_base_test(void *ptr) http = http_setup(&port, base, 0); fd = http_connect("127.0.0.1", port); - tt_int_op(fd, >=, 0); + tt_assert(fd != EVUTIL_INVALID_SOCKET); /* Stupid thing to send a request */ bev = bufferevent_socket_new(base, fd, 0); @@ -3114,7 +3116,7 @@ http_incomplete_test_(struct basic_test_data *data, int use_timeout, int ssl) evhttp_set_timeout(http, 1); fd = http_connect("127.0.0.1", port); - tt_int_op(fd, >=, 0); + tt_assert(fd != EVUTIL_INVALID_SOCKET); /* Stupid thing to send a request */ bev = create_bev(data->base, fd, ssl); @@ -3138,7 +3140,7 @@ http_incomplete_test_(struct basic_test_data *data, int use_timeout, int ssl) bufferevent_free(bev); if (use_timeout) { evutil_closesocket(fd); - fd = -1; + fd = EVUTIL_INVALID_SOCKET; } evhttp_free(http); @@ -3331,6 +3333,7 @@ http_chunk_out_test_impl(void *arg, int ssl) test_ok = 0; fd = http_connect("127.0.0.1", port); + tt_assert(fd != EVUTIL_INVALID_SOCKET); /* Stupid thing to send a request */ bev = create_bev(data->base, fd, ssl); @@ -3909,7 +3912,7 @@ http_multi_line_header_test(void *arg) { struct basic_test_data *data = arg; struct bufferevent *bev= NULL; - evutil_socket_t fd = -1; + evutil_socket_t fd = EVUTIL_INVALID_SOCKET; const char *http_start_request; ev_uint16_t port = 0; struct evhttp *http = http_setup(&port, data->base, 0); @@ -3920,8 +3923,7 @@ http_multi_line_header_test(void *arg) tt_ptr_op(http, !=, NULL); fd = http_connect("127.0.0.1", port); - - tt_int_op(fd, !=, -1); + tt_assert(fd != EVUTIL_INVALID_SOCKET); /* Stupid thing to send a request */ bev = bufferevent_socket_new(data->base, fd, 0); @@ -4313,7 +4315,7 @@ http_terminate_chunked_test_impl(void *arg, int oneshot) struct timeval tv; const char *http_request; ev_uint16_t port = 0; - evutil_socket_t fd = -1; + evutil_socket_t fd = EVUTIL_INVALID_SOCKET; struct terminate_state terminate_state; struct evhttp *http = http_setup(&port, data->base, 0); @@ -4324,6 +4326,7 @@ http_terminate_chunked_test_impl(void *arg, int oneshot) terminate_chunked_cb, &terminate_state) == 0); fd = http_connect("127.0.0.1", port); + tt_assert(fd != EVUTIL_INVALID_SOCKET); /* Stupid thing to send a request */ bev = bufferevent_socket_new(data->base, fd, 0); @@ -4504,7 +4507,7 @@ http_write_during_read_test_impl(void *arg, int ssl) ev_uint16_t port = 0; struct bufferevent *bev = NULL; struct timeval tv; - int fd; + evutil_socket_t fd; const char *http_request; struct evhttp *http = http_setup(&port, data->base, ssl ? HTTP_BIND_SSL : 0); @@ -4512,6 +4515,7 @@ http_write_during_read_test_impl(void *arg, int ssl) exit_base = data->base; fd = http_connect("127.0.0.1", port); + tt_assert(fd != EVUTIL_INVALID_SOCKET); bev = create_bev(data->base, fd, 0); bufferevent_setcb(bev, NULL, NULL, NULL, data->base); bufferevent_disable(bev, EV_READ); @@ -4528,6 +4532,7 @@ http_write_during_read_test_impl(void *arg, int ssl) event_base_dispatch(data->base); +end: if (bev) bufferevent_free(bev); if (http) @@ -4580,6 +4585,7 @@ static void http_run_bev_request(struct event_base *base, int port, struct evbuffer *out; fd = http_connect("127.0.0.1", port); + tt_assert(fd != EVUTIL_INVALID_SOCKET); /* Stupid thing to send a request */ bev = create_bev(base, fd, 0); @@ -4593,7 +4599,9 @@ static void http_run_bev_request(struct event_base *base, int port, event_base_dispatch(base); - bufferevent_free(bev); +end: + if (bev) + bufferevent_free(bev); } static void http_request_extra_body_test(void *arg) diff --git a/test/regress_listener.c b/test/regress_listener.c index 070e5e34..b60529f2 100644 --- a/test/regress_listener.c +++ b/test/regress_listener.c @@ -80,8 +80,9 @@ regress_pick_a_port(void *arg) ev_socklen_t slen1 = sizeof(ss1), slen2 = sizeof(ss2); unsigned int flags = LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_EXEC; + evutil_socket_t fd1, fd2, fd3; - evutil_socket_t fd1 = -1, fd2 = -1, fd3 = -1; + fd1 = fd2 = fd3 = EVUTIL_INVALID_SOCKET; if (data->setup_data && strstr((char*)data->setup_data, "ts")) { flags |= LEV_OPT_THREADSAFE; @@ -99,8 +100,8 @@ regress_pick_a_port(void *arg) flags, -1, (struct sockaddr *)&sin, sizeof(sin)); tt_assert(listener2); - tt_int_op(evconnlistener_get_fd(listener1), >=, 0); - tt_int_op(evconnlistener_get_fd(listener2), >=, 0); + tt_assert(evconnlistener_get_fd(listener1) != EVUTIL_INVALID_SOCKET); + tt_assert(evconnlistener_get_fd(listener2) != EVUTIL_INVALID_SOCKET); tt_assert(getsockname(evconnlistener_get_fd(listener1), (struct sockaddr*)&ss1, &slen1) == 0); tt_assert(getsockname(evconnlistener_get_fd(listener2), @@ -117,7 +118,7 @@ regress_pick_a_port(void *arg) tt_ptr_op(evconnlistener_get_base(listener1), ==, base); tt_ptr_op(evconnlistener_get_base(listener2), ==, base); - fd1 = fd2 = fd3 = -1; + fd1 = fd2 = fd3 = EVUTIL_INVALID_SOCKET; evutil_socket_connect_(&fd1, (struct sockaddr*)&ss1, slen1); evutil_socket_connect_(&fd2, (struct sockaddr*)&ss1, slen1); evutil_socket_connect_(&fd3, (struct sockaddr*)&ss2, slen2); @@ -208,7 +209,7 @@ regress_listener_close_accepted_fd(void *arg) ev_socklen_t slen = sizeof(ss); int count = 1; unsigned int flags = LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE; - int fd = -1; + evutil_socket_t fd = EVUTIL_INVALID_SOCKET; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; @@ -241,7 +242,7 @@ regress_listener_immediate_close(void *arg) ev_socklen_t slen = sizeof(ss); int count = 1; unsigned int flags = LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE; - int fd1 = -1, fd2 = -1; + evutil_socket_t fd1 = EVUTIL_INVALID_SOCKET, fd2 = EVUTIL_INVALID_SOCKET; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; diff --git a/test/regress_ssl.c b/test/regress_ssl.c index 45ce540d..b486b803 100644 --- a/test/regress_ssl.c +++ b/test/regress_ssl.c @@ -287,12 +287,12 @@ enum regress_openssl_type static void bufferevent_openssl_check_fd(struct bufferevent *bev, int filter) { - tt_int_op(bufferevent_getfd(bev), !=, -1); - tt_int_op(bufferevent_setfd(bev, -1), ==, 0); + tt_fd_op(bufferevent_getfd(bev), !=, EVUTIL_INVALID_SOCKET); + tt_fd_op(bufferevent_setfd(bev, EVUTIL_INVALID_SOCKET), ==, 0); if (filter) { - tt_int_op(bufferevent_getfd(bev), !=, -1); + tt_fd_op(bufferevent_getfd(bev), !=, EVUTIL_INVALID_SOCKET); } else { - tt_int_op(bufferevent_getfd(bev), ==, -1); + tt_fd_op(bufferevent_getfd(bev), ==, EVUTIL_INVALID_SOCKET); } end: @@ -501,7 +501,7 @@ regress_bufferevent_openssl(void *arg) fd_pair, bev_ll, type); if (!(type & REGRESS_OPENSSL_FILTER)) { - tt_int_op(bufferevent_getfd(bev1), ==, data->pair[0]); + tt_fd_op(bufferevent_getfd(bev1), ==, data->pair[0]); } else { tt_ptr_op(bufferevent_get_underlying(bev1), ==, bev_ll[0]); } @@ -614,7 +614,7 @@ end: struct rwcount { - int fd; + evutil_socket_t fd; size_t read; size_t write; }; diff --git a/test/tinytest_macros.h b/test/tinytest_macros.h index 2c02a741..e34e74ec 100644 --- a/test/tinytest_macros.h +++ b/test/tinytest_macros.h @@ -158,6 +158,14 @@ tt_assert_test_type(a,b,#a" "#op" "#b,long,(val1_ op val2_), \ "%ld",TT_EXIT_TEST_FUNCTION) +/** To compare SOCKET(windows)/fd */ +#define tt_fd_op(a,op,b) do { \ + int _a = (int)(a); \ + int _b = (int)(b); \ + tt_assert_test_type(_a,_b,#a" "#op" "#b,long,(val1_ op val2_), \ + "%ld",TT_EXIT_TEST_FUNCTION); \ +} while (0) + #define tt_uint_op(a,op,b) \ tt_assert_test_type(a,b,#a" "#op" "#b,unsigned long, \ (val1_ op val2_),"%lu",TT_EXIT_TEST_FUNCTION) -- cgit v1.2.1 From ce4e2b7b8ca3af9a5bff0cd1455899591ff58f36 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 3 Feb 2019 18:47:14 +0300 Subject: test/ssl/bufferevent_wm: explicitly break the loop once client/server received enough There can be tricky cases (that can be reproduced by reducing SO_RCVBUF/SO_SNDBUF to 6144, on linux, and be aware, since linux doubles this const), when there is still write event pending, although we read enough. This should be fixed in a more sophisticated way, but to backport the patch, let's simply break the loop manually. The ssl/bufferevent_wm originally failed on solaris. (cherry picked from commit ae9b285d2d7c9b898049072c157d50769d8014ea) --- test/regress_ssl.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/regress_ssl.c b/test/regress_ssl.c index b486b803..68c28114 100644 --- a/test/regress_ssl.c +++ b/test/regress_ssl.c @@ -806,6 +806,7 @@ struct wm_context size_t limit; size_t get; struct bufferevent *bev; + struct wm_context *neighbour; }; static void wm_transfer(struct bufferevent *bev, void *arg) @@ -821,6 +822,9 @@ wm_transfer(struct bufferevent *bev, void *arg) ctx->server ? "server" : "client", bev)); bufferevent_setcb(bev, NULL, NULL, NULL, NULL); bufferevent_disable(bev, EV_READ); + if (ctx->neighbour->get >= ctx->neighbour->limit) { + event_base_loopbreak(bufferevent_get_base(bev)); + } } else { ctx->get += drain; evbuffer_drain(in, drain); @@ -953,6 +957,9 @@ regress_bufferevent_openssl_wm(void *arg) tt_assert(bev); client.bev = bev; + server.neighbour = &client; + client.neighbour = &server; + bufferevent_setwatermark(bev, EV_READ, 0, client.wm_high); bufferevent_setcb(bev, wm_transfer, NULL, wm_eventcb, &client); -- cgit v1.2.1 From 5a26e7bd073bd88edb68ac1cf1c32374e390b7dd Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 3 Feb 2019 18:54:00 +0300 Subject: test/dns: in solaris under EMFILE the error is EAI_FAIL (cherry picked from commit d234902da713cb722596f6bf66bb0dde8a3842dc) --- test/regress_dns.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/regress_dns.c b/test/regress_dns.c index 75988a95..df696f0c 100644 --- a/test/regress_dns.c +++ b/test/regress_dns.c @@ -1218,10 +1218,13 @@ test_bufferevent_connect_hostname(void *arg) if (emfile) { success = BEV_EVENT_ERROR; -#ifdef __linux__ +#if defined(__linux__) /* on linux glibc/musl reports EAI_SYSTEM, when getaddrinfo() cannot * open file for resolving service. */ default_error = EVUTIL_EAI_SYSTEM; +#elif defined(__sun__) + /* on solaris it returns EAI_FAIL */ + default_error = EVUTIL_EAI_FAIL; #else /* on osx/freebsd it returns EAI_NONAME */ default_error = EVUTIL_EAI_NONAME; -- cgit v1.2.1 From 7f1619022799ce1c4e3704f19618ed476d091676 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 4 Feb 2019 22:18:45 +0300 Subject: cmake: fix checking of devpoll backend (like in autotools, by devpoll.h existence) (cherry picked from commit 8e87de3c24cad940516f49aa0466cfe53fa042bf) --- CMakeLists.txt | 2 +- WIN32-Code/nmake/event2/event-config.h | 3 --- event-config.h.cmake | 3 --- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 854c7e9d..df26ebce 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -379,7 +379,7 @@ CHECK_INCLUDE_FILE(stdint.h EVENT__HAVE_STDINT_H) CHECK_INCLUDE_FILE(stdlib.h EVENT__HAVE_STDLIB_H) CHECK_INCLUDE_FILE(strings.h EVENT__HAVE_STRINGS_H) CHECK_INCLUDE_FILE(string.h EVENT__HAVE_STRING_H) -CHECK_INCLUDE_FILE(sys/devpoll.h EVENT__HAVE_SYS_DEVPOLL_H) +CHECK_INCLUDE_FILE(sys/devpoll.h EVENT__HAVE_DEVPOLL) CHECK_INCLUDE_FILE(sys/epoll.h EVENT__HAVE_SYS_EPOLL_H) CHECK_INCLUDE_FILE(sys/eventfd.h EVENT__HAVE_SYS_EVENTFD_H) CHECK_INCLUDE_FILE(sys/event.h EVENT__HAVE_SYS_EVENT_H) diff --git a/WIN32-Code/nmake/event2/event-config.h b/WIN32-Code/nmake/event2/event-config.h index 6080f5ae..9086f80f 100644 --- a/WIN32-Code/nmake/event2/event-config.h +++ b/WIN32-Code/nmake/event2/event-config.h @@ -192,9 +192,6 @@ /* Define to 1 if the system has the type `struct sockaddr_storage'. */ #define EVENT__HAVE_STRUCT_SOCKADDR_STORAGE 1 -/* Define to 1 if you have the header file. */ -/* #undef EVENT__HAVE_SYS_DEVPOLL_H */ - /* Define to 1 if you have the header file. */ /* #undef EVENT__HAVE_SYS_EPOLL_H */ diff --git a/event-config.h.cmake b/event-config.h.cmake index 3f8a9b59..ee0df54b 100644 --- a/event-config.h.cmake +++ b/event-config.h.cmake @@ -322,9 +322,6 @@ /* Define to 1 if you have the `sysctl' function. */ #cmakedefine EVENT__HAVE_SYSCTL 1 -/* Define to 1 if you have the header file. */ -#cmakedefine EVENT__HAVE_SYS_DEVPOLL_H 1 - /* Define to 1 if you have the header file. */ #cmakedefine EVENT__HAVE_SYS_EPOLL_H 1 -- cgit v1.2.1 From e0e5d53b2112b6d669e6d03d9415bf1d0bb541de Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 4 Feb 2019 22:34:10 +0300 Subject: test/dns: in solaris under EMFILE devpoll does not dispatch (cherry picked from commit 3ce38f6d2d74edcacfe17d612c611ae35e97acfc) --- test/regress_dns.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/test/regress_dns.c b/test/regress_dns.c index df696f0c..9f1d6283 100644 --- a/test/regress_dns.c +++ b/test/regress_dns.c @@ -1215,6 +1215,7 @@ test_bufferevent_connect_hostname(void *arg) int success = BEV_EVENT_CONNECTED; int default_error = 0; unsigned i; + int ret; if (emfile) { success = BEV_EVENT_ERROR; @@ -1225,6 +1226,7 @@ test_bufferevent_connect_hostname(void *arg) #elif defined(__sun__) /* on solaris it returns EAI_FAIL */ default_error = EVUTIL_EAI_FAIL; + /** the DP_POLL can also fail with EINVAL under EMFILE */ #else /* on osx/freebsd it returns EAI_NONAME */ default_error = EVUTIL_EAI_NONAME; @@ -1307,7 +1309,17 @@ test_bufferevent_connect_hostname(void *arg) tt_assert(!bufferevent_socket_connect_hostname(be[2], dns, AF_INET, "nobodaddy.example.com", listener_port)); - event_base_dispatch(data->base); + ret = event_base_dispatch(data->base); +#ifdef __sun__ + if (emfile && !strcmp(event_base_get_method(data->base), "devpoll")) { + tt_int_op(ret, ==, -1); + /** DP_POLL failed */ + tt_skip(); + } else +#endif + { + tt_int_op(ret, ==, 0); + } tt_int_op(be_outcome[0].what, ==, BEV_EVENT_ERROR); tt_int_op(be_outcome[0].dnserr, ==, EVUTIL_EAI_NONAME); -- cgit v1.2.1 From 9e0a1e06cdbdd194020d8fbba1d20dc54c3b7f8e Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 10 Feb 2019 14:39:49 +0300 Subject: Bump AUTHORS section --- README.md | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/README.md b/README.md index 5d66021c..f550c677 100644 --- a/README.md +++ b/README.md @@ -412,5 +412,45 @@ fixing bugs: * johnsonlee * Philip Prindeville * Vis Virial + * Andreas Gustafsson + * Andrey Okoshkin + * an-tao + * baixiangcpp + * Bernard Spil + * Bogdan Harjoc + * Carlo Marcelo Arenas Belón + * David Benjamin + * David Disseldorp + * Dmitry Alimov + * Dominic Chen + * dpayne + * ejurgensen + * Fredrik Strupe + * Gonçalo Ribeiro + * James Synge + * Jan Beich + * Jesse Fang + * Jiri Luznicky + * José Luis Millán + * Kiyoshi Aman + * Leo Zhang + * lightningkay + * Luke Dashjr + * Marcin Szewczyk + * Maximilian Brunner + * Maya Rashish + * Murat Demirten + * Nathan French + * Nikolay Edigaryev + * Philip Herron + * Redfoxmoon + * stenn + * SuckShit + * The Gitter Badger + * tim-le + * Vincent JARDIN + * Xiang Zhang + * Xiaozhou Liu + * yongqing.jiao If we have forgotten your name, please contact us. -- cgit v1.2.1 From b5126dbe0c64b72899b7026f15ec79909b192f6a Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 3 Feb 2019 19:25:09 +0300 Subject: Bump ChangeLog --- ChangeLog | 136 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) diff --git a/ChangeLog b/ChangeLog index 740bdfcc..4d0dfba4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,139 @@ +Changes in version 2.1.9-beta (10 February 2019) + + This changelog will differs from other releases in the next few clauses: + - contains only highlighted changes (so now it will not contains a lot of + patches that fixes some stuff in regression tests, typos, leaks fixes in + samples and so forth) + - no authors (since merge commits breaks them anyway, but AUTHORS sections in + README will be kept up to date) + - group name trimmed from commit subjects trimmed + - it's been 2 years since the previoius release, so it is pretty huge + + And I think that this is more useful, so from now on it will always has the + same look (until there will too many objections of course). + + To view full changelog please use git: + git log --format=' o %s (%h %aN)' release-2.1.8-stable...release-2.1.9-beta + + + dist archive: + o Add cmake rules into dist archive (bf3a67cfg) + o Add missing print-winsock-errors.c into dist archive (822d6462g) + o Include openssl-compat.h into dist archive (08658136g) + + core: + o Merge branch 'check-O_NONBLOCK-in-debug' (a39898f3g, a8155c62g) + o Merge branch 'event-ET-#636-v2' (ca4b6404g) + o Fix visibility issues under (mostly on win32) + (349081e1g, 802be13ag, a1f28e2fg) + o Define __EXT_POSIX2 for QNX (a2176f2c) + o Cleanup __func__ detection (b3af7bddg) + o Add convenience macros for user-triggered events (06ec5de6) + o Notify event base if there are no more events, so it can exit without delay (d9d1c09eg) + o Fix base unlocking in event_del() if event_base_set() runned in another thread (4f0f40e3g) + o If precise_time is false, we should not set EVENT_BASE_FLAG_PRECISE_TIMER (27dee54d) + o Fix race in access to ev_res from event loop with event_active() (43d92a6d) + o Return from event_del() after the last event callback termination (876c7ac7) + + http: + o Merge branch 'http-EVHTTP_CON_READ_ON_WRITE_ERROR-fixes-v2' (eb7b472bg) + o Preserve socket error from listen across closesocket cleanup (2ccd00a6) + o fix connection retries when there more then one request for connection (d30e7bbag) + o improve error path for bufferevent_{setfd,enable,disable}() (a8cc449eg) + o Fix conceivable UAF of the bufferevent in evhttp_connection_free() (6ac2ec25g) + o Merge branch 'http-request-line-parsing' (cdcfbafeg) + o Fix evhttp_connection_get_addr() fox incomming http connections (4215c003) + o fix leaks in evhttp_uriencode() (123362e9g) + o CONNECT method only takes an authority (7d1ffe64) + o Allow bodies for GET/DELETE/OPTIONS/CONNECT (23eb38b9g) + o Do not crash when evhttp_send_reply_start() is called after a timeout. (826f1134) + o Fix crashing http server when callback do not reply in place (5b40744dg, b2581380g) + o fix handling of close_notify (ssl) in http with openssl bufferevents (7e91622bg) + + evprc: + o use *_new_with_arg() to match function prototype (a95cc9e3g) + o avoid NULL dereference on request is not EVHTTP_REQ_POST (e05136c7g) + + regression tests: + o Merge branch 'TT_RETRIABLE' (6ea1ec68g, f9b592aag) + + bufferevent: + o Merge branch 'iocp-fixes' (6bfac964g) + o Merge branch 'be-wm-overrun-v2' (3f692fffg) + o bufferevent_socket_connect{,_hostname}() missing event callback and use ret code (1dde74ef) + o don't fail be_null_filter if bytes are copied (b92b0792) + o Call underlying bev ctrl GET_FD on filtered bufferevents (ebfac517) + + bufferevent_openssl/openssl: + o Merge branch 'ssl_bufferevent_wm_filter-fix' (30020a35g) + o be_openssl: avoid leaking of SSL structure (e86ccfe5g) + o Fix build with LibreSSL 2.7 (894ca48a) + o Add missing includes into openssl-compat.h (01bc36c1g) + o Explicitly call SSL_clear when reseting the fd. (29b7a516) + o Unbreak build with LibreSSL after openssl 1.1 support added (230af9f0) + + samples: + o Merge branch 'sample-http-server' (b6309bccg) + o sample/https-client: use host SSL certificate store by default (5c0132f3) + + listener: + o ipv6only socket bind support (ba148796) + o Merge branch 'listener-immediate-close' (df2ed13fg) + o Merge branch 'evconnlistener-do-not-close-client-fd' (42e851bbg) + + evdns: + o evdns: handle NULL filename explicitly (0033f5cc) + o Merge branch 'evdns_getaddrinfo-race-fix' (3237d697g) + o Generating evdns_base_config_windows_nameservers docs on all platforms (3bd2ce43) + + utils: + o Merge branch 'evutil_found_ifaddr-dev' (b07e43e6g) + o Avoid possible SEGVs in select() (in unit tests) (8818c86c) + o Port `event_rpcgen.py` and `test/check-dumpevents.py` to Python 3. (532a8cc3) + + buffer: + o Fix assert() condition in evbuffer_drain() for IOCP (d6326104) + o fix incorrect unlock of the buffer mutex (for deferred callbacks) (2b4d127dg) + o Fix wrong assert in evbuffer_drain() (9f4d0dceg) + + cmake: + o fix checking of devpoll backend (like in autotools, by devpoll.h existence) (7f161902) + o support static runtime (MSVC) (c8b3ec17, 61fb055a) + o do not build both (SHARED and STATIC) for MSVC/win32 (bc7f2fd9g) + o introduce EVENT__LIBRARY_TYPE option (eb10a738g) + o ensure windows dll's are installed as well as lib files (29590718) + o Fix generation of LibeventConfig.cmake for the installation tree (7fa08c4b) + o fix pkgconfig generation (copy-paste typo) (cc554d87g) + o Merge branch 'cmake-missing-bits' (9806b126g) + o Fix detection of timerfd_create() in CMake. (e50af331) + o Merge branch 'cmake-configure-fixes-v2' (a0bfe2c4g) + o Do not add epoll_sub (syscall wrappers) for epoll in cmake (cea61de6g) + o Fix RPATH for APPLE (45b1f379) + + autotools: + o include win32 specific headers for socklen_t detection on win32/mingw (d7579fb9g) + o Ignore evconfig-private.h for autotools (37423849g) + o config.h can't be prefixed unconditionally (63a054f8) + o Merge branch 'pull-628' (7e56c8b2g) + o Provide Makefile variables LIBEVENT_{CFLAGS,CPPFLAGS,LDFLAGS} (2f060c5f) + o confirm openssl is working before using (b39ccf8e) + o pass $(OPENSSL_INCS) for samples (FTBFS macOS) (c2495265) + o Add configure check for midipix (d433201e) + o Fix tests with detached builds (c46ff439) + + build: + o Fix arc4random_addrandom() detecting and fallback (regression) (303d6d77g) + o Merge branch 'win32-fixes' (ebd12e6dg) + o Merge branch 'fix-openssl-linking' (e7bd9e03g) + o Merge branch 'fix-struct-linger' (8567f2f5g) + + CI: + o travis-ci/appveyor now uses fast_finish+allow_failures + (5e97b6e6, dd472e7d, dfb5fc167) + o Merge branch 'travis-ci-osx-fixes' (9f02b39c) + o Merge branch 'win64-fixes' (aee0fcd5) + + Changes in version 2.1.8-stable (22 January 2017) Libevent 2.1.8-stable, it contains openssl fixes for resetting fd and using -- cgit v1.2.1 From 900f5c4503208c654c0e9ef64ac196c0deac5c18 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 3 Feb 2019 19:19:46 +0300 Subject: Bump version to 2.1.9-beta everywhere --- CMakeLists.txt | 2 +- Makefile.am | 5 +++-- WIN32-Code/nmake/event2/event-config.h | 4 ++-- appveyor.yml | 2 +- cmake/VersionViaGit.cmake | 2 +- configure.ac | 4 ++-- 6 files changed, 10 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index df26ebce..98082cde 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,7 +84,7 @@ set(EVENT_ABI_LIBVERSION set(EVENT_PACKAGE_VERSION "${EVENT_VERSION_MAJOR}.${EVENT_VERSION_MINOR}.${EVENT_VERSION_PATCH}") -set(EVENT_NUMERIC_VERSION 0x02010800) +set(EVENT_NUMERIC_VERSION 0x02010900) # only a subset of names can be used, defaults to "beta" set(EVENT_STAGE_NAME ${EVENT_VERSION_STAGE}) diff --git a/Makefile.am b/Makefile.am index efc17eba..9ebce429 100644 --- a/Makefile.am +++ b/Makefile.am @@ -38,7 +38,7 @@ RELEASE = -release 2.1 # # Once an RC is out, DO NOT MAKE ANY ABI-BREAKING CHANGES IN THAT SERIES # UNLESS YOU REALLY REALLY HAVE TO. -VERSION_INFO = 6:2:0 +VERSION_INFO = 6:3:0 # History: RELEASE VERSION_INFO # 2.0.1-alpha -- 2.0 1:0:0 @@ -71,7 +71,8 @@ VERSION_INFO = 6:2:0 # 2.1.5-beta -- 2.1 5:0:0 (ABI changed slightly) # 2.1.6-beta -- 2.1 6:0:0 (ABI changed slightly) # 2.1.7-beta -- 2.1 6:1:0 (ABI changed slightly) -# 2.1.8-stable-- 2.1 6:2:0 (ABI changed slightly) +# 2.1.8-stable-- 2.1 6:2:0 (No ABI change) +# 2.1.9-beta-- 2.1 6:3:0 (No ABI change) # ABI version history for this package effectively restarts every time # we change RELEASE. Version 1.4.x had RELEASE of 1.4. diff --git a/WIN32-Code/nmake/event2/event-config.h b/WIN32-Code/nmake/event2/event-config.h index 9086f80f..3d1439b3 100644 --- a/WIN32-Code/nmake/event2/event-config.h +++ b/WIN32-Code/nmake/event2/event-config.h @@ -271,7 +271,7 @@ /* #undef EVENT__HAVE_WORKING_KQUEUE */ /* Numeric representation of the version */ -#define EVENT__NUMERIC_VERSION 0x02010800 +#define EVENT__NUMERIC_VERSION 0x02010900 /* Name of package */ #define EVENT__PACKAGE "libevent" @@ -332,7 +332,7 @@ #define EVENT__TIME_WITH_SYS_TIME 1 /* Version number of package */ -#define EVENT__VERSION "2.1.8-stable" +#define EVENT__VERSION "2.1.9-beta" /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ diff --git a/appveyor.yml b/appveyor.yml index be71576e..2d7cee2c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.1.8.{build} +version: 2.1.9.{build} os: Visual Studio 2017 platform: diff --git a/cmake/VersionViaGit.cmake b/cmake/VersionViaGit.cmake index b17764c3..008d0188 100644 --- a/cmake/VersionViaGit.cmake +++ b/cmake/VersionViaGit.cmake @@ -23,7 +23,7 @@ macro(event_fuzzy_version_from_git) # set our defaults. set(EVENT_GIT___VERSION_MAJOR 2) set(EVENT_GIT___VERSION_MINOR 1) - set(EVENT_GIT___VERSION_PATCH 8) + set(EVENT_GIT___VERSION_PATCH 9) set(EVENT_GIT___VERSION_STAGE "beta") find_package(Git) diff --git a/configure.ac b/configure.ac index ea34555e..0f5495d6 100644 --- a/configure.ac +++ b/configure.ac @@ -5,7 +5,7 @@ dnl See LICENSE for copying information. dnl dnl Original version Dug Song -AC_INIT(libevent,2.1.8-stable) +AC_INIT(libevent,2.1.9-beta) AC_PREREQ(2.59) AC_CONFIG_SRCDIR(event.c) @@ -14,7 +14,7 @@ AM_INIT_AUTOMAKE dnl AM_SILENT_RULES req. automake 1.11. [no] defaults V=1 m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) AC_CONFIG_HEADERS(config.h evconfig-private.h:evconfig-private.h.in) -AC_DEFINE(NUMERIC_VERSION, 0x02010800, [Numeric representation of the version]) +AC_DEFINE(NUMERIC_VERSION, 0x02010900, [Numeric representation of the version]) dnl Initialize prefix. if test "$prefix" = "NONE"; then -- cgit v1.2.1