diff options
Diffstat (limited to 'protocols/Telegram/tgl/libevent/test')
80 files changed, 0 insertions, 24042 deletions
diff --git a/protocols/Telegram/tgl/libevent/test/Makefile.nmake b/protocols/Telegram/tgl/libevent/test/Makefile.nmake deleted file mode 100644 index 30c3eb792b..0000000000 --- a/protocols/Telegram/tgl/libevent/test/Makefile.nmake +++ /dev/null @@ -1,79 +0,0 @@ -# WATCH OUT! This makefile is a work in progress. -*- makefile -*- - -!IFDEF OPENSSL_DIR -SSL_CFLAGS=/I$(OPENSSL_DIR)\include /DEVENT__HAVE_OPENSSL -SSL_OBJS=regress_ssl.obj -SSL_LIBS=..\libevent_openssl.lib $(OPENSSL_DIR)\lib\libeay32.lib $(OPENSSL_DIR)\lib\ssleay32.lib gdi32.lib User32.lib -!ELSE -SSL_CFLAGS= -SSL_OBJS= -SSL_LIBS= -!ENDIF - -CFLAGS=/I.. /I../WIN32-Code /I../WIN32-Code/nmake /I../include /I../compat /DHAVE_CONFIG_H /DTINYTEST_LOCAL $(SSL_CFLAGS) - -CFLAGS=$(CFLAGS) /Ox /W3 /wd4996 /nologo - -REGRESS_OBJS=regress.obj regress_buffer.obj regress_http.obj regress_dns.obj \ - regress_testutils.obj \ - regress_rpc.obj regress.gen.obj \ - regress_et.obj regress_bufferevent.obj \ - regress_listener.obj regress_util.obj tinytest.obj \ - regress_main.obj regress_minheap.obj regress_iocp.obj \ - regress_thread.obj regress_finalize.obj $(SSL_OBJS) - -OTHER_OBJS=test-init.obj test-eof.obj test-closed.obj test-weof.obj test-time.obj \ - bench.obj bench_cascade.obj bench_http.obj bench_httpclient.obj \ - test-changelist.obj \ - print-winsock-errors.obj - -PROGRAMS=regress.exe \ - test-init.exe test-eof.exe test-closed.exe test-weof.exe test-time.exe \ - test-changelist.exe \ - print-winsock-errors.exe - -# Disabled for now: -# bench.exe bench_cascade.exe bench_http.exe bench_httpclient.exe - - -LIBS=..\libevent.lib ws2_32.lib shell32.lib advapi32.lib - -all: $(PROGRAMS) - -regress.exe: $(REGRESS_OBJS) - $(CC) $(CFLAGS) $(LIBS) $(SSL_LIBS) $(REGRESS_OBJS) - -test-init.exe: test-init.obj - $(CC) $(CFLAGS) $(LIBS) test-init.obj -test-eof.exe: test-eof.obj - $(CC) $(CFLAGS) $(LIBS) test-eof.obj -test-closed.exe: test-closed.obj - $(CC) $(CFLAGS) $(LIBS) test-closed.obj -test-changelist.exe: test-changelist.obj - $(CC) $(CFLAGS) $(LIBS) test-changelist.obj -test-weof.exe: test-weof.obj - $(CC) $(CFLAGS) $(LIBS) test-weof.obj -test-time.exe: test-time.obj - $(CC) $(CFLAGS) $(LIBS) test-time.obj - -print-winsock-errors.exe: print-winsock-errors.obj - $(CC) $(CFLAGS) $(LIBS) print-winsock-errors.obj - -bench.exe: bench.obj - $(CC) $(CFLAGS) $(LIBS) bench.obj -bench_cascade.exe: bench_cascade.obj - $(CC) $(CFLAGS) $(LIBS) bench_cascade.obj -bench_http.exe: bench_http.obj - $(CC) $(CFLAGS) $(LIBS) bench_http.obj -bench_httpclient.exe: bench_httpclient.obj - $(CC) $(CFLAGS) $(LIBS) bench_httpclient.obj - -regress.gen.c regress.gen.h: regress.rpc ../event_rpcgen.py - echo // > regress.gen.c - echo #define NO_PYTHON_EXISTS > regress.gen.h - -python ..\event_rpcgen.py regress.rpc - -clean: - -del $(REGRESS_OBJS) - -del $(OTHER_OBJS) - -del $(PROGRAMS) diff --git a/protocols/Telegram/tgl/libevent/test/bench.c b/protocols/Telegram/tgl/libevent/test/bench.c deleted file mode 100644 index 214479c1ff..0000000000 --- a/protocols/Telegram/tgl/libevent/test/bench.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright 2003-2007 Niels Provos <provos@citi.umich.edu> - * Copyright 2007-2012 Niels Provos and Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * Mon 03/10/2003 - Modified by Davide Libenzi <davidel@xmailserver.org> - * - * Added chain event propagation to improve the sensitivity of - * the measure respect to the event loop efficency. - * - * - */ - -#include "event2/event-config.h" - -#include <sys/types.h> -#include <sys/stat.h> -#ifdef EVENT__HAVE_SYS_TIME_H -#include <sys/time.h> -#endif -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#else -#include <sys/socket.h> -#include <signal.h> -#include <sys/resource.h> -#endif -#include <fcntl.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#ifdef EVENT__HAVE_UNISTD_H -#include <unistd.h> -#endif -#include <errno.h> - -#ifdef _WIN32 -#include <getopt.h> -#endif - -#include <event.h> -#include <evutil.h> - -static int count, writes, fired, failures; -static evutil_socket_t *pipes; -static int num_pipes, num_active, num_writes; -static struct event *events; - - -static void -read_cb(evutil_socket_t fd, short which, void *arg) -{ - ev_intptr_t idx = (ev_intptr_t) arg, widx = idx + 1; - unsigned char ch; - ev_ssize_t n; - - n = recv(fd, (char*)&ch, sizeof(ch), 0); - if (n >= 0) - count += n; - else - failures++; - if (writes) { - if (widx >= num_pipes) - widx -= num_pipes; - n = send(pipes[2 * widx + 1], "e", 1, 0); - if (n != 1) - failures++; - writes--; - fired++; - } -} - -static struct timeval * -run_once(void) -{ - evutil_socket_t *cp, space; - long i; - static struct timeval ts, te; - - for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) { - if (event_initialized(&events[i])) - event_del(&events[i]); - event_set(&events[i], cp[0], EV_READ | EV_PERSIST, read_cb, (void *)(ev_intptr_t) i); - event_add(&events[i], NULL); - } - - event_loop(EVLOOP_ONCE | EVLOOP_NONBLOCK); - - fired = 0; - space = num_pipes / num_active; - space = space * 2; - for (i = 0; i < num_active; i++, fired++) - (void) send(pipes[i * space + 1], "e", 1, 0); - - count = 0; - writes = num_writes; - { int xcount = 0; - evutil_gettimeofday(&ts, NULL); - do { - event_loop(EVLOOP_ONCE | EVLOOP_NONBLOCK); - xcount++; - } while (count != fired); - evutil_gettimeofday(&te, NULL); - - if (xcount != count) fprintf(stderr, "Xcount: %d, Rcount: %d\n", xcount, count); - } - - evutil_timersub(&te, &ts, &te); - - return (&te); -} - -int -main(int argc, char **argv) -{ -#ifdef HAVE_SETRLIMIT - struct rlimit rl; -#endif - int i, c; - struct timeval *tv; - evutil_socket_t *cp; - -#ifdef _WIN32 - WSADATA WSAData; - WSAStartup(0x101, &WSAData); -#endif - num_pipes = 100; - num_active = 1; - num_writes = num_pipes; - while ((c = getopt(argc, argv, "n:a:w:")) != -1) { - switch (c) { - case 'n': - num_pipes = atoi(optarg); - break; - case 'a': - num_active = atoi(optarg); - break; - case 'w': - num_writes = atoi(optarg); - break; - default: - fprintf(stderr, "Illegal argument \"%c\"\n", c); - exit(1); - } - } - -#ifdef HAVE_SETRLIMIT - rl.rlim_cur = rl.rlim_max = num_pipes * 2 + 50; - if (setrlimit(RLIMIT_NOFILE, &rl) == -1) { - perror("setrlimit"); - exit(1); - } -#endif - - events = calloc(num_pipes, sizeof(struct event)); - pipes = calloc(num_pipes * 2, sizeof(evutil_socket_t)); - if (events == NULL || pipes == NULL) { - perror("malloc"); - exit(1); - } - - event_init(); - - for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) { -#ifdef USE_PIPES - if (pipe(cp) == -1) { -#else - if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, cp) == -1) { -#endif - perror("pipe"); - exit(1); - } - } - - for (i = 0; i < 25; i++) { - tv = run_once(); - if (tv == NULL) - exit(1); - fprintf(stdout, "%ld\n", - tv->tv_sec * 1000000L + tv->tv_usec); - } - - exit(0); -} diff --git a/protocols/Telegram/tgl/libevent/test/bench_cascade.c b/protocols/Telegram/tgl/libevent/test/bench_cascade.c deleted file mode 100644 index 2d85cc1f10..0000000000 --- a/protocols/Telegram/tgl/libevent/test/bench_cascade.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright 2007-2012 Niels Provos and Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "event2/event-config.h" - -#include <sys/types.h> -#include <sys/stat.h> -#ifdef EVENT__HAVE_SYS_TIME_H -#include <sys/time.h> -#endif -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#else -#include <sys/socket.h> -#include <sys/resource.h> -#endif -#include <signal.h> -#include <fcntl.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#ifdef EVENT__HAVE_UNISTD_H -#include <unistd.h> -#endif -#include <errno.h> -#include <getopt.h> -#include <event.h> -#include <evutil.h> - -/* - * This benchmark tests how quickly we can propagate a write down a chain - * of socket pairs. We start by writing to the first socket pair and all - * events will fire subsequently until the last socket pair has been reached - * and the benchmark terminates. - */ - -static int fired; -static evutil_socket_t *pipes; -static struct event *events; - -static void -read_cb(evutil_socket_t fd, short which, void *arg) -{ - char ch; - evutil_socket_t sock = (evutil_socket_t)(ev_intptr_t)arg; - - (void) recv(fd, &ch, sizeof(ch), 0); - if (sock >= 0) { - if (send(sock, "e", 1, 0) < 0) - perror("send"); - } - fired++; -} - -static struct timeval * -run_once(int num_pipes) -{ - int i; - evutil_socket_t *cp; - static struct timeval ts, te, tv_timeout; - - events = (struct event *)calloc(num_pipes, sizeof(struct event)); - pipes = (evutil_socket_t *)calloc(num_pipes * 2, sizeof(evutil_socket_t)); - - if (events == NULL || pipes == NULL) { - perror("malloc"); - exit(1); - } - - for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) { - if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, cp) == -1) { - perror("socketpair"); - exit(1); - } - } - - /* measurements includes event setup */ - evutil_gettimeofday(&ts, NULL); - - /* provide a default timeout for events */ - evutil_timerclear(&tv_timeout); - tv_timeout.tv_sec = 60; - - for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) { - evutil_socket_t fd = i < num_pipes - 1 ? cp[3] : -1; - event_set(&events[i], cp[0], EV_READ, read_cb, - (void *)(ev_intptr_t)fd); - event_add(&events[i], &tv_timeout); - } - - fired = 0; - - /* kick everything off with a single write */ - if (send(pipes[1], "e", 1, 0) < 0) - perror("send"); - - event_dispatch(); - - evutil_gettimeofday(&te, NULL); - evutil_timersub(&te, &ts, &te); - - for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) { - event_del(&events[i]); - evutil_closesocket(cp[0]); - evutil_closesocket(cp[1]); - } - - free(pipes); - free(events); - - return (&te); -} - -int -main(int argc, char **argv) -{ -#ifdef HAVE_SETRLIMIT - struct rlimit rl; -#endif - int i, c; - struct timeval *tv; - - int num_pipes = 100; -#ifdef _WIN32 - WSADATA WSAData; - WSAStartup(0x101, &WSAData); -#endif - - while ((c = getopt(argc, argv, "n:")) != -1) { - switch (c) { - case 'n': - num_pipes = atoi(optarg); - break; - default: - fprintf(stderr, "Illegal argument \"%c\"\n", c); - exit(1); - } - } - -#ifdef HAVE_SETRLIMIT - rl.rlim_cur = rl.rlim_max = num_pipes * 2 + 50; - if (setrlimit(RLIMIT_NOFILE, &rl) == -1) { - perror("setrlimit"); - exit(1); - } -#endif - - event_init(); - - for (i = 0; i < 25; i++) { - tv = run_once(num_pipes); - if (tv == NULL) - exit(1); - fprintf(stdout, "%ld\n", - tv->tv_sec * 1000000L + tv->tv_usec); - } - -#ifdef _WIN32 - WSACleanup(); -#endif - - exit(0); -} diff --git a/protocols/Telegram/tgl/libevent/test/bench_http.c b/protocols/Telegram/tgl/libevent/test/bench_http.c deleted file mode 100644 index 6d0d971799..0000000000 --- a/protocols/Telegram/tgl/libevent/test/bench_http.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright 2008-2012 Niels Provos and Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include <sys/types.h> -#include <sys/stat.h> -#ifdef _WIN32 -#include <winsock2.h> -#else -#include <sys/socket.h> -#include <sys/resource.h> -#include <sys/time.h> -#include <unistd.h> -#endif -#include <fcntl.h> -#include <signal.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> - -#include "event2/event.h" -#include "event2/buffer.h" -#include "event2/util.h" -#include "event2/http.h" -#include "event2/thread.h" - -static void http_basic_cb(struct evhttp_request *req, void *arg); - -static char *content; -static size_t content_len = 0; - -static void -http_basic_cb(struct evhttp_request *req, void *arg) -{ - struct evbuffer *evb = evbuffer_new(); - - evbuffer_add(evb, content, content_len); - - /* allow sending of an empty reply */ - evhttp_send_reply(req, HTTP_OK, "Everything is fine", evb); - - evbuffer_free(evb); -} - -#if LIBEVENT_VERSION_NUMBER >= 0x02000200 -static void -http_ref_cb(struct evhttp_request *req, void *arg) -{ - struct evbuffer *evb = evbuffer_new(); - - evbuffer_add_reference(evb, content, content_len, NULL, NULL); - - /* allow sending of an empty reply */ - evhttp_send_reply(req, HTTP_OK, "Everything is fine", evb); - - evbuffer_free(evb); -} -#endif - -int -main(int argc, char **argv) -{ - struct event_config *cfg = event_config_new(); - struct event_base *base; - struct evhttp *http; - int i; - int c; - int use_iocp = 0; - unsigned short port = 8080; - char *endptr = NULL; - -#ifdef _WIN32 - WSADATA WSAData; - WSAStartup(0x101, &WSAData); -#else - if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) - return (1); -#endif - - for (i = 1; i < argc; ++i) { - if (*argv[i] != '-') - continue; - - c = argv[i][1]; - - if ((c == 'p' || c == 'l') && i + 1 >= argc) { - fprintf(stderr, "-%c requires argument.\n", c); - exit(1); - } - - switch (c) { - case 'p': - if (i+1 >= argc || !argv[i+1]) { - fprintf(stderr, "Missing port\n"); - exit(1); - } - port = (int)strtol(argv[i+1], &endptr, 10); - if (*endptr != '\0') { - fprintf(stderr, "Bad port\n"); - exit(1); - } - break; - case 'l': - if (i+1 >= argc || !argv[i+1]) { - fprintf(stderr, "Missing content length\n"); - exit(1); - } - content_len = (size_t)strtol(argv[i+1], &endptr, 10); - if (*endptr != '\0' || content_len == 0) { - fprintf(stderr, "Bad content length\n"); - exit(1); - } - break; -#ifdef _WIN32 - case 'i': - use_iocp = 1; - evthread_use_windows_threads(); - event_config_set_flag(cfg,EVENT_BASE_FLAG_STARTUP_IOCP); - break; -#endif - default: - fprintf(stderr, "Illegal argument \"%c\"\n", c); - exit(1); - } - } - - base = event_base_new_with_config(cfg); - if (!base) { - fprintf(stderr, "creating event_base failed. Exiting.\n"); - return 1; - } - - http = evhttp_new(base); - - content = malloc(content_len); - if (content == NULL) { - fprintf(stderr, "Cannot allocate content\n"); - exit(1); - } else { - int i = 0; - for (i = 0; i < (int)content_len; ++i) - content[i] = (i & 255); - } - - evhttp_set_cb(http, "/ind", http_basic_cb, NULL); - fprintf(stderr, "/ind - basic content (memory copy)\n"); - - evhttp_set_cb(http, "/ref", http_ref_cb, NULL); - fprintf(stderr, "/ref - basic content (reference)\n"); - - fprintf(stderr, "Serving %d bytes on port %d using %s\n", - (int)content_len, port, - use_iocp? "IOCP" : event_base_get_method(base)); - - evhttp_bind_socket(http, "0.0.0.0", port); - -#ifdef _WIN32 - if (use_iocp) { - struct timeval tv={99999999,0}; - event_base_loopexit(base, &tv); - } -#endif - event_base_dispatch(base); - -#ifdef _WIN32 - WSACleanup(); -#endif - - /* NOTREACHED */ - return (0); -} diff --git a/protocols/Telegram/tgl/libevent/test/bench_httpclient.c b/protocols/Telegram/tgl/libevent/test/bench_httpclient.c deleted file mode 100644 index bcddc95f43..0000000000 --- a/protocols/Telegram/tgl/libevent/test/bench_httpclient.c +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright 2009-2012 Niels Provos and Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (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 EVUTIL_ERR_CONNECT_RETRIABLE macro */ -#include "util-internal.h" - -#include <sys/types.h> -#ifdef _WIN32 -#include <winsock2.h> -#else -#include <sys/socket.h> -#include <netinet/in.h> -# ifdef _XOPEN_SOURCE_EXTENDED -# include <arpa/inet.h> -# endif -#endif -#include <stdlib.h> -#include <string.h> -#include <errno.h> - -#include "event2/event.h" -#include "event2/bufferevent.h" -#include "event2/buffer.h" -#include "event2/util.h" - -const char *resource = NULL; -struct event_base *base = NULL; - -int total_n_handled = 0; -int total_n_errors = 0; -int total_n_launched = 0; -size_t total_n_bytes = 0; -struct timeval total_time = {0,0}; -int n_errors = 0; - -const int PARALLELISM = 200; -const int N_REQUESTS = 20000; - -struct request_info { - size_t n_read; - struct timeval started; -}; - -static int launch_request(void); -static void readcb(struct bufferevent *b, void *arg); -static void errorcb(struct bufferevent *b, short what, void *arg); - -static void -readcb(struct bufferevent *b, void *arg) -{ - struct request_info *ri = arg; - struct evbuffer *input = bufferevent_get_input(b); - size_t n = evbuffer_get_length(input); - - ri->n_read += n; - evbuffer_drain(input, n); -} - -static void -errorcb(struct bufferevent *b, short what, void *arg) -{ - struct request_info *ri = arg; - struct timeval now, diff; - if (what & BEV_EVENT_EOF) { - ++total_n_handled; - total_n_bytes += ri->n_read; - evutil_gettimeofday(&now, NULL); - evutil_timersub(&now, &ri->started, &diff); - evutil_timeradd(&diff, &total_time, &total_time); - - if (total_n_handled && (total_n_handled%1000)==0) - printf("%d requests done\n",total_n_handled); - - if (total_n_launched < N_REQUESTS) { - if (launch_request() < 0) - perror("Can't launch"); - } - } else { - ++total_n_errors; - perror("Unexpected error"); - } - - bufferevent_setcb(b, NULL, NULL, NULL, NULL); - free(ri); - bufferevent_disable(b, EV_READ|EV_WRITE); - bufferevent_free(b); -} - -static void -frob_socket(evutil_socket_t sock) -{ -#ifdef HAVE_SO_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 - l.l_onoff = 1; - l.l_linger = 0; - if (setsockopt(sock, SOL_SOCKET, SO_LINGER, (void*)&l, sizeof(l))<0) - perror("setsockopt(SO_LINGER)"); -#endif -} - -static int -launch_request(void) -{ - evutil_socket_t sock; - struct sockaddr_in sin; - struct bufferevent *b; - - struct request_info *ri; - - memset(&sin, 0, sizeof(sin)); - - ++total_n_launched; - - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = htonl(0x7f000001); - sin.sin_port = htons(8080); - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) - return -1; - if (evutil_make_socket_nonblocking(sock) < 0) { - evutil_closesocket(sock); - return -1; - } - frob_socket(sock); - if (connect(sock, (struct sockaddr*)&sin, sizeof(sin)) < 0) { - int e = evutil_socket_geterror(sock); - if (! EVUTIL_ERR_CONNECT_RETRIABLE(e)) { - evutil_closesocket(sock); - return -1; - } - } - - ri = malloc(sizeof(*ri)); - ri->n_read = 0; - evutil_gettimeofday(&ri->started, NULL); - - b = bufferevent_socket_new(base, sock, BEV_OPT_CLOSE_ON_FREE); - - bufferevent_setcb(b, readcb, NULL, errorcb, ri); - bufferevent_enable(b, EV_READ|EV_WRITE); - - evbuffer_add_printf(bufferevent_get_output(b), - "GET %s HTTP/1.0\r\n\r\n", resource); - - return 0; -} - - -int -main(int argc, char **argv) -{ - int i; - struct timeval start, end, total; - long long usec; - double throughput; - resource = "/ref"; - -#ifdef _WIN32 - WSADATA WSAData; - WSAStartup(0x101, &WSAData); -#endif - - setvbuf(stdout, NULL, _IONBF, 0); - - base = event_base_new(); - - for (i=0; i < PARALLELISM; ++i) { - if (launch_request() < 0) - perror("launch"); - } - - evutil_gettimeofday(&start, NULL); - - event_base_dispatch(base); - - evutil_gettimeofday(&end, NULL); - evutil_timersub(&end, &start, &total); - usec = total_time.tv_sec * (long long)1000000 + total_time.tv_usec; - - if (!total_n_handled) { - puts("Nothing worked. You probably did something dumb."); - return 0; - } - - - throughput = total_n_handled / - (total.tv_sec+ ((double)total.tv_usec)/1000000.0); - -#ifdef _WIN32 -#define I64_FMT "%I64d" -#define I64_TYP __int64 -#else -#define I64_FMT "%lld" -#define I64_TYP long long int -#endif - - printf("\n%d requests in %d.%06d sec. (%.2f throughput)\n" - "Each took about %.02f msec latency\n" - I64_FMT "bytes read. %d errors.\n", - total_n_handled, - (int)total.tv_sec, (int)total.tv_usec, - throughput, - (double)(usec/1000) / total_n_handled, - (I64_TYP)total_n_bytes, n_errors); - -#ifdef _WIN32 - WSACleanup(); -#endif - - return 0; -} diff --git a/protocols/Telegram/tgl/libevent/test/check-dumpevents.py b/protocols/Telegram/tgl/libevent/test/check-dumpevents.py deleted file mode 100644 index 16fe9bc92f..0000000000 --- a/protocols/Telegram/tgl/libevent/test/check-dumpevents.py +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/python2 -# -# Post-process the output of test-dumpevents and check it for correctness. -# - -import math -import re -import sys - -text = sys.stdin.readlines() - -try: - expect_inserted_pos = text.index("Inserted:\n") - expect_active_pos = text.index("Active:\n") - 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.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.exit(1) - -now,T= text[1].split() -T = float(T) - -want_inserted = set(text[expect_inserted_pos+1:expect_active_pos]) -want_active = set(text[expect_active_pos+1:got_inserted_pos-1]) -got_inserted = set(text[got_inserted_pos+1:got_active_pos]) -got_active = set(text[got_active_pos+1:]) - -pat = re.compile(r'Timeout=([0-9\.]+)') -def replace_time(m): - t = float(m.group(1)) - if .9 < abs(t-T) < 1.1: - return "Timeout=T+1" - elif 2.4 < abs(t-T) < 2.6: - return "Timeout=T+2.5" - else: - return m.group(0) - -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.exit(1) - -if set(got_active) != set(want_active): - print >>sys.stderr, "Active event lists were not as expected!" - sys.exit(1) - diff --git a/protocols/Telegram/tgl/libevent/test/include.am b/protocols/Telegram/tgl/libevent/test/include.am deleted file mode 100644 index 4cd49ef630..0000000000 --- a/protocols/Telegram/tgl/libevent/test/include.am +++ /dev/null @@ -1,146 +0,0 @@ -# test/Makefile.am for libevent -# Copyright 2000-2007 Niels Provos -# Copyright 2007-2012 Niels Provos and Nick Mathewson -# -# See LICENSE for copying information. - -regress_CPPFLAGS = -DTINYTEST_LOCAL - -EXTRA_DIST+= \ - test/check-dumpevents.py \ - test/regress.gen.c \ - test/regress.gen.h \ - test/regress.rpc \ - test/rpcgen_wrapper.sh \ - test/test.sh - -TESTPROGRAMS = \ - test/bench \ - test/bench_cascade \ - test/bench_http \ - test/bench_httpclient \ - test/test-changelist \ - test/test-dumpevents \ - test/test-eof \ - test/test-closed \ - test/test-fdleak \ - test/test-init \ - test/test-ratelim \ - test/test-time \ - test/test-weof \ - test/regress - -if BUILD_REGRESS -noinst_PROGRAMS += $(TESTPROGRAMS) -EXTRA_PROGRAMS+= test/regress -endif - -noinst_HEADERS+= \ - test/regress.h \ - test/regress_thread.h \ - test/tinytest.h \ - test/tinytest_local.h \ - test/tinytest_macros.h - -# We need to copy this file, since automake doesn't want us to use top_srcdir -# in TESTS. -TESTS = test/test-script.sh - -test/test-script.sh: test/test.sh - cp $(top_srcdir)/test/test.sh $@ - -DISTCLEANFILES += test/test-script.sh -DISTCLEANFILES += test/regress.gen.c test/regress.gen.h - -if BUILD_REGRESS -BUILT_SOURCES += test/regress.gen.c test/regress.gen.h -endif - -test_test_init_SOURCES = test/test-init.c -test_test_init_LDADD = libevent_core.la -test_test_dumpevents_SOURCES = test/test-dumpevents.c -test_test_dumpevents_LDADD = libevent_core.la -test_test_eof_SOURCES = test/test-eof.c -test_test_eof_LDADD = libevent_core.la -test_test_closed_SOURCES = test/test-closed.c -test_test_closed_LDADD = libevent_core.la -test_test_changelist_SOURCES = test/test-changelist.c -test_test_changelist_LDADD = libevent_core.la -test_test_weof_SOURCES = test/test-weof.c -test_test_weof_LDADD = libevent_core.la -test_test_time_SOURCES = test/test-time.c -test_test_time_LDADD = libevent_core.la -test_test_ratelim_SOURCES = test/test-ratelim.c -test_test_ratelim_LDADD = libevent_core.la -lm -test_test_fdleak_SOURCES = test/test-fdleak.c -test_test_fdleak_LDADD = libevent_core.la - -test_regress_SOURCES = \ - 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 \ - $(regress_thread_SOURCES) \ - $(regress_zlib_SOURCES) - -if PTHREADS -regress_thread_SOURCES = test/regress_thread.c -PTHREAD_LIBS += libevent_pthreads.la -endif -if BUILD_WIN32 -regress_thread_SOURCES = test/regress_thread.c -endif -if ZLIB_REGRESS -regress_zlib_SOURCES = test/regress_zlib.c -endif -if BUILD_WIN32 -test_regress_SOURCES += test/regress_iocp.c -endif - -test_regress_LDADD = $(LIBEVENT_GC_SECTIONS) libevent.la $(PTHREAD_LIBS) $(ZLIB_LIBS) -test_regress_CPPFLAGS = $(AM_CPPFLAGS) $(PTHREAD_CFLAGS) $(ZLIB_CFLAGS) -Itest -test_regress_LDFLAGS = $(PTHREAD_CFLAGS) - -if OPENSSL -test_regress_SOURCES += test/regress_ssl.c -test_regress_CPPFLAGS += $(OPENSSL_INCS) -test_regress_LDADD += libevent_openssl.la $(OPENSSL_LIBS) ${OPENSSL_LIBADD} -endif - -test_bench_SOURCES = test/bench.c -test_bench_LDADD = $(LIBEVENT_GC_SECTIONS) libevent.la -test_bench_cascade_SOURCES = test/bench_cascade.c -test_bench_cascade_LDADD = $(LIBEVENT_GC_SECTIONS) libevent.la -test_bench_http_SOURCES = test/bench_http.c -test_bench_http_LDADD = $(LIBEVENT_GC_SECTIONS) libevent.la -test_bench_httpclient_SOURCES = test/bench_httpclient.c -test_bench_httpclient_LDADD = $(LIBEVENT_GC_SECTIONS) libevent_core.la - -test/regress.gen.c test/regress.gen.h: test/rpcgen-attempted - -test/rpcgen-attempted: test/regress.rpc event_rpcgen.py test/rpcgen_wrapper.sh - $(AM_V_GEN)date -u > $@ - $(AM_V_at)if $(srcdir)/test/rpcgen_wrapper.sh $(srcdir)/test; then \ - true; \ - else \ - echo "No Python installed; stubbing out RPC test." >&2; \ - echo " "> test/regress.gen.c; \ - echo "#define NO_PYTHON_EXISTS" > test/regress.gen.h; \ - fi - -CLEANFILES += test/rpcgen-attempted - -$(TESTPROGRAMS) : libevent.la diff --git a/protocols/Telegram/tgl/libevent/test/print-winsock-errors.c b/protocols/Telegram/tgl/libevent/test/print-winsock-errors.c deleted file mode 100644 index ab6e610e84..0000000000 --- a/protocols/Telegram/tgl/libevent/test/print-winsock-errors.c +++ /dev/null @@ -1,84 +0,0 @@ -#include <winsock2.h> -#include <windows.h> - -#include <stdlib.h> -#include <stdio.h> - -#include "event2/event.h" -#include "event2/util.h" -#include "event2/thread.h" - -#define E(x) printf (#x " -> \"%s\"\n", evutil_socket_error_to_string (x)); - -int main (int argc, char **argv) -{ - int i, j; - const char *s1, *s2; - - evthread_use_windows_threads (); - - s1 = evutil_socket_error_to_string (WSAEINTR); - - for (i = 0; i < 3; i++) { - printf ("\niteration %d:\n\n", i); - E(WSAEINTR); - E(WSAEACCES); - E(WSAEFAULT); - E(WSAEINVAL); - E(WSAEMFILE); - E(WSAEWOULDBLOCK); - E(WSAEINPROGRESS); - E(WSAEALREADY); - E(WSAENOTSOCK); - E(WSAEDESTADDRREQ); - E(WSAEMSGSIZE); - E(WSAEPROTOTYPE); - E(WSAENOPROTOOPT); - E(WSAEPROTONOSUPPORT); - E(WSAESOCKTNOSUPPORT); - E(WSAEOPNOTSUPP); - E(WSAEPFNOSUPPORT); - E(WSAEAFNOSUPPORT); - E(WSAEADDRINUSE); - E(WSAEADDRNOTAVAIL); - E(WSAENETDOWN); - E(WSAENETUNREACH); - E(WSAENETRESET); - E(WSAECONNABORTED); - E(WSAECONNRESET); - E(WSAENOBUFS); - E(WSAEISCONN); - E(WSAENOTCONN); - E(WSAESHUTDOWN); - E(WSAETIMEDOUT); - E(WSAECONNREFUSED); - E(WSAEHOSTDOWN); - E(WSAEHOSTUNREACH); - E(WSAEPROCLIM); - E(WSASYSNOTREADY); - E(WSAVERNOTSUPPORTED); - E(WSANOTINITIALISED); - E(WSAEDISCON); - E(WSATYPE_NOT_FOUND); - E(WSAHOST_NOT_FOUND); - E(WSATRY_AGAIN); - E(WSANO_RECOVERY); - E(WSANO_DATA); - E(0xdeadbeef); /* test the case where no message is available */ - - /* fill up the hash table a bit to make sure it grows properly */ - for (j = 0; j < 50; j++) { - int err; - evutil_secure_rng_get_bytes(&err, sizeof(err)); - evutil_socket_error_to_string(err); - } - } - - s2 = evutil_socket_error_to_string (WSAEINTR); - if (s1 != s2) - printf ("caching failed!\n"); - - libevent_global_shutdown (); - - return EXIT_SUCCESS; -} diff --git a/protocols/Telegram/tgl/libevent/test/print-winsock-errors.exe b/protocols/Telegram/tgl/libevent/test/print-winsock-errors.exe Binary files differdeleted file mode 100644 index 7bdbd19034..0000000000 --- a/protocols/Telegram/tgl/libevent/test/print-winsock-errors.exe +++ /dev/null diff --git a/protocols/Telegram/tgl/libevent/test/print-winsock-errors.obj b/protocols/Telegram/tgl/libevent/test/print-winsock-errors.obj Binary files differdeleted file mode 100644 index ca803f6340..0000000000 --- a/protocols/Telegram/tgl/libevent/test/print-winsock-errors.obj +++ /dev/null diff --git a/protocols/Telegram/tgl/libevent/test/regress.c b/protocols/Telegram/tgl/libevent/test/regress.c deleted file mode 100644 index b12c66dfa0..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress.c +++ /dev/null @@ -1,3401 +0,0 @@ -/* - * Copyright (c) 2003-2007 Niels Provos <provos@citi.umich.edu> - * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "util-internal.h" - -#ifdef _WIN32 -#include <winsock2.h> -#include <windows.h> -#endif - -#ifdef EVENT__HAVE_PTHREADS -#include <pthread.h> -#endif - -#include "event2/event-config.h" - -#include <sys/types.h> -#include <sys/stat.h> -#ifdef EVENT__HAVE_SYS_TIME_H -#include <sys/time.h> -#endif -#include <sys/queue.h> -#ifndef _WIN32 -#include <sys/socket.h> -#include <sys/wait.h> -#include <signal.h> -#include <unistd.h> -#include <netdb.h> -#endif -#include <fcntl.h> -#include <signal.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <assert.h> -#include <ctype.h> - -#include "event2/event.h" -#include "event2/event_struct.h" -#include "event2/event_compat.h" -#include "event2/tag.h" -#include "event2/buffer.h" -#include "event2/buffer_compat.h" -#include "event2/util.h" -#include "event-internal.h" -#include "evthread-internal.h" -#include "log-internal.h" -#include "time-internal.h" - -#include "regress.h" - -#ifndef _WIN32 -#include "regress.gen.h" -#endif - -evutil_socket_t pair[2]; -int test_ok; -int called; -struct event_base *global_base; - -static char wbuf[4096]; -static char rbuf[4096]; -static int woff; -static int roff; -static int usepersist; -static struct timeval tset; -static struct timeval tcalled; - - -#define TEST1 "this is a test" - -#ifndef SHUT_WR -#define SHUT_WR 1 -#endif - -#ifdef _WIN32 -#define write(fd,buf,len) send((fd),(buf),(int)(len),0) -#define read(fd,buf,len) recv((fd),(buf),(int)(len),0) -#endif - -struct basic_cb_args -{ - struct event_base *eb; - struct event *ev; - unsigned int callcount; -}; - -static void -simple_read_cb(evutil_socket_t fd, short event, void *arg) -{ - char buf[256]; - int len; - - len = read(fd, buf, sizeof(buf)); - - if (len) { - if (!called) { - if (event_add(arg, NULL) == -1) - exit(1); - } - } else if (called == 1) - test_ok = 1; - - called++; -} - -static void -basic_read_cb(evutil_socket_t fd, short event, void *data) -{ - char buf[256]; - int len; - struct basic_cb_args *arg = data; - - len = read(fd, buf, sizeof(buf)); - - if (len < 0) { - tt_fail_perror("read (callback)"); - } else { - switch (arg->callcount++) { - case 0: /* first call: expect to read data; cycle */ - if (len > 0) - return; - - tt_fail_msg("EOF before data read"); - break; - - case 1: /* second call: expect EOF; stop */ - if (len > 0) - tt_fail_msg("not all data read on first cycle"); - break; - - default: /* third call: should not happen */ - tt_fail_msg("too many cycles"); - } - } - - event_del(arg->ev); - event_base_loopexit(arg->eb, NULL); -} - -static void -dummy_read_cb(evutil_socket_t fd, short event, void *arg) -{ -} - -static void -simple_write_cb(evutil_socket_t fd, short event, void *arg) -{ - int len; - - len = write(fd, TEST1, strlen(TEST1) + 1); - if (len == -1) - test_ok = 0; - else - test_ok = 1; -} - -static void -multiple_write_cb(evutil_socket_t fd, short event, void *arg) -{ - struct event *ev = arg; - int len; - - len = 128; - if (woff + len >= (int)sizeof(wbuf)) - len = sizeof(wbuf) - woff; - - len = write(fd, wbuf + woff, len); - if (len == -1) { - fprintf(stderr, "%s: write\n", __func__); - if (usepersist) - event_del(ev); - return; - } - - woff += len; - - if (woff >= (int)sizeof(wbuf)) { - shutdown(fd, SHUT_WR); - if (usepersist) - event_del(ev); - return; - } - - if (!usepersist) { - if (event_add(ev, NULL) == -1) - exit(1); - } -} - -static void -multiple_read_cb(evutil_socket_t fd, short event, void *arg) -{ - struct event *ev = arg; - int len; - - len = read(fd, rbuf + roff, sizeof(rbuf) - roff); - if (len == -1) - fprintf(stderr, "%s: read\n", __func__); - if (len <= 0) { - if (usepersist) - event_del(ev); - return; - } - - roff += len; - if (!usepersist) { - if (event_add(ev, NULL) == -1) - exit(1); - } -} - -static void -timeout_cb(evutil_socket_t fd, short event, void *arg) -{ - evutil_gettimeofday(&tcalled, NULL); -} - -struct both { - struct event ev; - int nread; -}; - -static void -combined_read_cb(evutil_socket_t fd, short event, void *arg) -{ - struct both *both = arg; - char buf[128]; - int len; - - len = read(fd, buf, sizeof(buf)); - if (len == -1) - fprintf(stderr, "%s: read\n", __func__); - if (len <= 0) - return; - - both->nread += len; - if (event_add(&both->ev, NULL) == -1) - exit(1); -} - -static void -combined_write_cb(evutil_socket_t fd, short event, void *arg) -{ - struct both *both = arg; - char buf[128]; - int len; - - len = sizeof(buf); - if (len > both->nread) - len = both->nread; - - memset(buf, 'q', len); - - len = write(fd, buf, len); - if (len == -1) - fprintf(stderr, "%s: write\n", __func__); - if (len <= 0) { - shutdown(fd, SHUT_WR); - return; - } - - both->nread -= len; - if (event_add(&both->ev, NULL) == -1) - exit(1); -} - -/* These macros used to replicate the work of the legacy test wrapper code */ -#define setup_test(x) do { \ - if (!in_legacy_test_wrapper) { \ - TT_FAIL(("Legacy test %s not wrapped properly", x)); \ - return; \ - } \ - } while (0) -#define cleanup_test() setup_test("cleanup") - -static void -test_simpleread(void) -{ - struct event ev; - - /* Very simple read test */ - setup_test("Simple read: "); - - if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) { - tt_fail_perror("write"); - } - - shutdown(pair[0], SHUT_WR); - - event_set(&ev, pair[1], EV_READ, simple_read_cb, &ev); - if (event_add(&ev, NULL) == -1) - exit(1); - event_dispatch(); - - cleanup_test(); -} - -static void -test_simplewrite(void) -{ - struct event ev; - - /* Very simple write test */ - setup_test("Simple write: "); - - event_set(&ev, pair[0], EV_WRITE, simple_write_cb, &ev); - if (event_add(&ev, NULL) == -1) - exit(1); - event_dispatch(); - - cleanup_test(); -} - -static void -simpleread_multiple_cb(evutil_socket_t fd, short event, void *arg) -{ - if (++called == 2) - test_ok = 1; -} - -static void -test_simpleread_multiple(void) -{ - struct event one, two; - - /* Very simple read test */ - setup_test("Simple read to multiple evens: "); - - if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) { - tt_fail_perror("write"); - } - - shutdown(pair[0], SHUT_WR); - - event_set(&one, pair[1], EV_READ, simpleread_multiple_cb, NULL); - if (event_add(&one, NULL) == -1) - exit(1); - event_set(&two, pair[1], EV_READ, simpleread_multiple_cb, NULL); - if (event_add(&two, NULL) == -1) - exit(1); - event_dispatch(); - - cleanup_test(); -} - -static int have_closed = 0; -static int premature_event = 0; -static void -simpleclose_close_fd_cb(evutil_socket_t s, short what, void *ptr) -{ - evutil_socket_t **fds = ptr; - TT_BLATHER(("Closing")); - evutil_closesocket(*fds[0]); - evutil_closesocket(*fds[1]); - *fds[0] = -1; - *fds[1] = -1; - have_closed = 1; -} - -static void -record_event_cb(evutil_socket_t s, short what, void *ptr) -{ - short *whatp = ptr; - if (!have_closed) - premature_event = 1; - *whatp = what; - TT_BLATHER(("Recorded %d on socket %d", (int)what, (int)s)); -} - -static void -test_simpleclose(void *ptr) -{ - /* Test that a close of FD is detected as a read and as a write. */ - struct event_base *base = event_base_new(); - evutil_socket_t pair1[2]={-1,-1}, pair2[2] = {-1, -1}; - evutil_socket_t *to_close[2]; - struct event *rev=NULL, *wev=NULL, *closeev=NULL; - struct timeval tv; - short got_read_on_close = 0, got_write_on_close = 0; - char buf[1024]; - memset(buf, 99, sizeof(buf)); -#ifdef _WIN32 -#define LOCAL_SOCKETPAIR_AF AF_INET -#else -#define LOCAL_SOCKETPAIR_AF AF_UNIX -#endif - if (evutil_socketpair(LOCAL_SOCKETPAIR_AF, SOCK_STREAM, 0, pair1)<0) - TT_DIE(("socketpair: %s", strerror(errno))); - if (evutil_socketpair(LOCAL_SOCKETPAIR_AF, SOCK_STREAM, 0, pair2)<0) - TT_DIE(("socketpair: %s", strerror(errno))); - if (evutil_make_socket_nonblocking(pair1[1]) < 0) - TT_DIE(("make_socket_nonblocking")); - if (evutil_make_socket_nonblocking(pair2[1]) < 0) - TT_DIE(("make_socket_nonblocking")); - - /** Stuff pair2[1] full of data, until write fails */ - while (1) { - int r = write(pair2[1], buf, sizeof(buf)); - if (r<0) { - int err = evutil_socket_geterror(pair2[1]); - if (! EVUTIL_ERR_RW_RETRIABLE(err)) - TT_DIE(("write failed strangely: %s", - evutil_socket_error_to_string(err))); - break; - } - } - to_close[0] = &pair1[0]; - to_close[1] = &pair2[0]; - - closeev = event_new(base, -1, EV_TIMEOUT, simpleclose_close_fd_cb, - to_close); - rev = event_new(base, pair1[1], EV_READ, record_event_cb, - &got_read_on_close); - TT_BLATHER(("Waiting for read on %d", (int)pair1[1])); - wev = event_new(base, pair2[1], EV_WRITE, record_event_cb, - &got_write_on_close); - TT_BLATHER(("Waiting for write on %d", (int)pair2[1])); - tv.tv_sec = 0; - tv.tv_usec = 100*1000; /* Close pair1[0] after a little while, and make - * sure we get a read event. */ - event_add(closeev, &tv); - event_add(rev, NULL); - event_add(wev, NULL); - /* Don't let the test go on too long. */ - tv.tv_sec = 0; - tv.tv_usec = 200*1000; - event_base_loopexit(base, &tv); - event_base_loop(base, 0); - - tt_int_op(got_read_on_close, ==, EV_READ); - tt_int_op(got_write_on_close, ==, EV_WRITE); - tt_int_op(premature_event, ==, 0); - -end: - if (pair1[0] >= 0) - evutil_closesocket(pair1[0]); - if (pair1[1] >= 0) - evutil_closesocket(pair1[1]); - if (pair2[0] >= 0) - evutil_closesocket(pair2[0]); - if (pair2[1] >= 0) - evutil_closesocket(pair2[1]); - if (rev) - event_free(rev); - if (wev) - event_free(wev); - if (closeev) - event_free(closeev); - if (base) - event_base_free(base); -} - - -static void -test_multiple(void) -{ - struct event ev, ev2; - int i; - - /* Multiple read and write test */ - setup_test("Multiple read/write: "); - memset(rbuf, 0, sizeof(rbuf)); - for (i = 0; i < (int)sizeof(wbuf); i++) - wbuf[i] = i; - - roff = woff = 0; - usepersist = 0; - - event_set(&ev, pair[0], EV_WRITE, multiple_write_cb, &ev); - if (event_add(&ev, NULL) == -1) - exit(1); - event_set(&ev2, pair[1], EV_READ, multiple_read_cb, &ev2); - if (event_add(&ev2, NULL) == -1) - exit(1); - event_dispatch(); - - if (roff == woff) - test_ok = memcmp(rbuf, wbuf, sizeof(wbuf)) == 0; - - cleanup_test(); -} - -static void -test_persistent(void) -{ - struct event ev, ev2; - int i; - - /* Multiple read and write test with persist */ - setup_test("Persist read/write: "); - memset(rbuf, 0, sizeof(rbuf)); - for (i = 0; i < (int)sizeof(wbuf); i++) - wbuf[i] = i; - - roff = woff = 0; - usepersist = 1; - - event_set(&ev, pair[0], EV_WRITE|EV_PERSIST, multiple_write_cb, &ev); - if (event_add(&ev, NULL) == -1) - exit(1); - event_set(&ev2, pair[1], EV_READ|EV_PERSIST, multiple_read_cb, &ev2); - if (event_add(&ev2, NULL) == -1) - exit(1); - event_dispatch(); - - if (roff == woff) - test_ok = memcmp(rbuf, wbuf, sizeof(wbuf)) == 0; - - cleanup_test(); -} - -static void -test_combined(void) -{ - struct both r1, r2, w1, w2; - - setup_test("Combined read/write: "); - memset(&r1, 0, sizeof(r1)); - memset(&r2, 0, sizeof(r2)); - memset(&w1, 0, sizeof(w1)); - memset(&w2, 0, sizeof(w2)); - - w1.nread = 4096; - w2.nread = 8192; - - event_set(&r1.ev, pair[0], EV_READ, combined_read_cb, &r1); - event_set(&w1.ev, pair[0], EV_WRITE, combined_write_cb, &w1); - event_set(&r2.ev, pair[1], EV_READ, combined_read_cb, &r2); - event_set(&w2.ev, pair[1], EV_WRITE, combined_write_cb, &w2); - tt_assert(event_add(&r1.ev, NULL) != -1); - tt_assert(!event_add(&w1.ev, NULL)); - tt_assert(!event_add(&r2.ev, NULL)); - tt_assert(!event_add(&w2.ev, NULL)); - event_dispatch(); - - if (r1.nread == 8192 && r2.nread == 4096) - test_ok = 1; - -end: - cleanup_test(); -} - -static void -test_simpletimeout(void) -{ - struct timeval tv; - struct event ev; - - setup_test("Simple timeout: "); - - tv.tv_usec = 200*1000; - tv.tv_sec = 0; - evutil_timerclear(&tcalled); - evtimer_set(&ev, timeout_cb, NULL); - evtimer_add(&ev, &tv); - - evutil_gettimeofday(&tset, NULL); - event_dispatch(); - test_timeval_diff_eq(&tset, &tcalled, 200); - - test_ok = 1; -end: - cleanup_test(); -} - -static void -periodic_timeout_cb(evutil_socket_t fd, short event, void *arg) -{ - int *count = arg; - - (*count)++; - if (*count == 6) { - /* call loopexit only once - on slow machines(?), it is - * apparently possible for this to get called twice. */ - test_ok = 1; - event_base_loopexit(global_base, NULL); - } -} - -static void -test_persistent_timeout(void) -{ - struct timeval tv; - struct event ev; - int count = 0; - - evutil_timerclear(&tv); - tv.tv_usec = 10000; - - event_assign(&ev, global_base, -1, EV_TIMEOUT|EV_PERSIST, - periodic_timeout_cb, &count); - event_add(&ev, &tv); - - event_dispatch(); - - event_del(&ev); -} - -static void -test_persistent_timeout_jump(void *ptr) -{ - struct basic_test_data *data = ptr; - struct event ev; - int count = 0; - struct timeval msec100 = { 0, 100 * 1000 }; - struct timeval msec50 = { 0, 50 * 1000 }; - struct timeval msec300 = { 0, 300 * 1000 }; - - event_assign(&ev, data->base, -1, EV_PERSIST, periodic_timeout_cb, &count); - event_add(&ev, &msec100); - /* Wait for a bit */ - evutil_usleep_(&msec300); - event_base_loopexit(data->base, &msec50); - event_base_dispatch(data->base); - tt_int_op(count, ==, 1); - -end: - event_del(&ev); -} - -struct persist_active_timeout_called { - int n; - short events[16]; - struct timeval tvs[16]; -}; - -static void -activate_cb(evutil_socket_t fd, short event, void *arg) -{ - struct event *ev = arg; - event_active(ev, EV_READ, 1); -} - -static void -persist_active_timeout_cb(evutil_socket_t fd, short event, void *arg) -{ - struct persist_active_timeout_called *c = arg; - if (c->n < 15) { - c->events[c->n] = event; - evutil_gettimeofday(&c->tvs[c->n], NULL); - ++c->n; - } -} - -static void -test_persistent_active_timeout(void *ptr) -{ - struct timeval tv, tv2, tv_exit, start; - struct event ev; - struct persist_active_timeout_called res; - - struct basic_test_data *data = ptr; - struct event_base *base = data->base; - - memset(&res, 0, sizeof(res)); - - tv.tv_sec = 0; - tv.tv_usec = 200 * 1000; - event_assign(&ev, base, -1, EV_TIMEOUT|EV_PERSIST, - persist_active_timeout_cb, &res); - event_add(&ev, &tv); - - tv2.tv_sec = 0; - tv2.tv_usec = 100 * 1000; - event_base_once(base, -1, EV_TIMEOUT, activate_cb, &ev, &tv2); - - tv_exit.tv_sec = 0; - tv_exit.tv_usec = 600 * 1000; - event_base_loopexit(base, &tv_exit); - - event_base_assert_ok_(base); - evutil_gettimeofday(&start, NULL); - - event_base_dispatch(base); - event_base_assert_ok_(base); - - tt_int_op(res.n, ==, 3); - tt_int_op(res.events[0], ==, EV_READ); - tt_int_op(res.events[1], ==, EV_TIMEOUT); - tt_int_op(res.events[2], ==, EV_TIMEOUT); - test_timeval_diff_eq(&start, &res.tvs[0], 100); - test_timeval_diff_eq(&start, &res.tvs[1], 300); - test_timeval_diff_eq(&start, &res.tvs[2], 500); -end: - event_del(&ev); -} - -struct common_timeout_info { - struct event ev; - struct timeval called_at; - int which; - int count; -}; - -static void -common_timeout_cb(evutil_socket_t fd, short event, void *arg) -{ - struct common_timeout_info *ti = arg; - ++ti->count; - evutil_gettimeofday(&ti->called_at, NULL); - if (ti->count >= 4) - event_del(&ti->ev); -} - -static void -test_common_timeout(void *ptr) -{ - struct basic_test_data *data = ptr; - - struct event_base *base = data->base; - int i; - struct common_timeout_info info[100]; - - struct timeval start; - struct timeval tmp_100_ms = { 0, 100*1000 }; - struct timeval tmp_200_ms = { 0, 200*1000 }; - struct timeval tmp_5_sec = { 5, 0 }; - struct timeval tmp_5M_usec = { 0, 5*1000*1000 }; - - const struct timeval *ms_100, *ms_200, *sec_5; - - ms_100 = event_base_init_common_timeout(base, &tmp_100_ms); - ms_200 = event_base_init_common_timeout(base, &tmp_200_ms); - sec_5 = event_base_init_common_timeout(base, &tmp_5_sec); - tt_assert(ms_100); - tt_assert(ms_200); - tt_assert(sec_5); - tt_ptr_op(event_base_init_common_timeout(base, &tmp_200_ms), - ==, ms_200); - tt_ptr_op(event_base_init_common_timeout(base, ms_200), ==, ms_200); - tt_ptr_op(event_base_init_common_timeout(base, &tmp_5M_usec), ==, sec_5); - tt_int_op(ms_100->tv_sec, ==, 0); - tt_int_op(ms_200->tv_sec, ==, 0); - tt_int_op(sec_5->tv_sec, ==, 5); - tt_int_op(ms_100->tv_usec, ==, 100000|0x50000000); - tt_int_op(ms_200->tv_usec, ==, 200000|0x50100000); - tt_int_op(sec_5->tv_usec, ==, 0|0x50200000); - - memset(info, 0, sizeof(info)); - - for (i=0; i<100; ++i) { - info[i].which = i; - event_assign(&info[i].ev, base, -1, EV_TIMEOUT|EV_PERSIST, - common_timeout_cb, &info[i]); - if (i % 2) { - if ((i%20)==1) { - /* Glass-box test: Make sure we survive the - * transition to non-common timeouts. It's - * a little tricky. */ - event_add(&info[i].ev, ms_200); - event_add(&info[i].ev, &tmp_100_ms); - } else if ((i%20)==3) { - /* Check heap-to-common too. */ - event_add(&info[i].ev, &tmp_200_ms); - event_add(&info[i].ev, ms_100); - } else if ((i%20)==5) { - /* Also check common-to-common. */ - event_add(&info[i].ev, ms_200); - event_add(&info[i].ev, ms_100); - } else { - event_add(&info[i].ev, ms_100); - } - } else { - event_add(&info[i].ev, ms_200); - } - } - - event_base_assert_ok_(base); - evutil_gettimeofday(&start, NULL); - event_base_dispatch(base); - - event_base_assert_ok_(base); - - for (i=0; i<10; ++i) { - tt_int_op(info[i].count, ==, 4); - if (i % 2) { - test_timeval_diff_eq(&start, &info[i].called_at, 400); - } else { - test_timeval_diff_eq(&start, &info[i].called_at, 800); - } - } - - /* Make sure we can free the base with some events in. */ - for (i=0; i<100; ++i) { - if (i % 2) { - event_add(&info[i].ev, ms_100); - } else { - event_add(&info[i].ev, ms_200); - } - } - -end: - event_base_free(data->base); /* need to do this here before info is - * out-of-scope */ - data->base = NULL; -} - -#ifndef _WIN32 - -#define current_base event_global_current_base_ -extern struct event_base *current_base; - -static void -fork_signal_cb(evutil_socket_t fd, short events, void *arg) -{ - event_del(arg); -} - - -static void -test_fork(void) -{ - int status; - struct event ev, sig_ev, usr_ev, existing_ev; - pid_t pid; - - setup_test("After fork: "); - - tt_assert(current_base); - evthread_make_base_notifiable(current_base); - - if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) { - tt_fail_perror("write"); - } - - event_set(&ev, pair[1], EV_READ, simple_read_cb, &ev); - if (event_add(&ev, NULL) == -1) - exit(1); - - evsignal_set(&sig_ev, SIGCHLD, fork_signal_cb, &sig_ev); - evsignal_add(&sig_ev, NULL); - - evsignal_set(&existing_ev, SIGUSR2, fork_signal_cb, &existing_ev); - evsignal_add(&existing_ev, NULL); - - event_base_assert_ok_(current_base); - TT_BLATHER(("Before fork")); - if ((pid = regress_fork()) == 0) { - /* in the child */ - TT_BLATHER(("In child, before reinit")); - event_base_assert_ok_(current_base); - if (event_reinit(current_base) == -1) { - fprintf(stdout, "FAILED (reinit)\n"); - exit(1); - } - TT_BLATHER(("After reinit")); - event_base_assert_ok_(current_base); - TT_BLATHER(("After assert-ok")); - - evsignal_del(&sig_ev); - - evsignal_set(&usr_ev, SIGUSR1, fork_signal_cb, &usr_ev); - evsignal_add(&usr_ev, NULL); - raise(SIGUSR1); - raise(SIGUSR2); - - called = 0; - - event_dispatch(); - - event_base_free(current_base); - - /* 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); - } - - /* wait for the child to read the data */ - { - const struct timeval tv = { 0, 100000 }; - evutil_usleep_(&tv); - } - - if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) { - tt_fail_perror("write"); - } - - TT_BLATHER(("Before waitpid")); - if (waitpid(pid, &status, 0) == -1) { - fprintf(stdout, "FAILED (fork)\n"); - exit(1); - } - TT_BLATHER(("After waitpid")); - - if (WEXITSTATUS(status) != 76) { - fprintf(stdout, "FAILED (exit): %d\n", WEXITSTATUS(status)); - exit(1); - } - - /* test that the current event loop still works */ - if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) { - fprintf(stderr, "%s: write\n", __func__); - } - - shutdown(pair[0], SHUT_WR); - - evsignal_set(&usr_ev, SIGUSR1, fork_signal_cb, &usr_ev); - evsignal_add(&usr_ev, NULL); - raise(SIGUSR1); - raise(SIGUSR2); - - event_dispatch(); - - evsignal_del(&sig_ev); - - end: - cleanup_test(); -} - -#ifdef EVENT__HAVE_PTHREADS -static void* del_wait_thread(void *arg) -{ - struct timeval tv_start, tv_end; - - evutil_gettimeofday(&tv_start, NULL); - event_dispatch(); - evutil_gettimeofday(&tv_end, NULL); - - test_timeval_diff_eq(&tv_start, &tv_end, 300); - - end: - return NULL; -} - -static void -del_wait_cb(evutil_socket_t fd, short event, void *arg) -{ - struct timeval delay = { 0, 300*1000 }; - TT_BLATHER(("Sleeping")); - evutil_usleep_(&delay); - test_ok = 1; -} - -static void -test_del_wait(void) -{ - struct event ev; - pthread_t thread; - - setup_test("event_del will wait: "); - - event_set(&ev, pair[1], EV_READ, del_wait_cb, &ev); - event_add(&ev, NULL); - - pthread_create(&thread, NULL, del_wait_thread, NULL); - - if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) { - tt_fail_perror("write"); - } - - { - struct timeval delay = { 0, 30*1000 }; - evutil_usleep_(&delay); - } - - { - struct timeval tv_start, tv_end; - evutil_gettimeofday(&tv_start, NULL); - event_del(&ev); - evutil_gettimeofday(&tv_end, NULL); - test_timeval_diff_eq(&tv_start, &tv_end, 270); - } - - pthread_join(thread, NULL); - - end: - ; -} -#endif - -static void -signal_cb_sa(int sig) -{ - test_ok = 2; -} - -static void -signal_cb(evutil_socket_t fd, short event, void *arg) -{ - struct event *ev = arg; - - evsignal_del(ev); - test_ok = 1; -} - -static void -test_simplesignal_impl(int find_reorder) -{ - struct event ev; - struct itimerval itv; - - evsignal_set(&ev, SIGALRM, signal_cb, &ev); - evsignal_add(&ev, NULL); - /* find bugs in which operations are re-ordered */ - if (find_reorder) { - evsignal_del(&ev); - evsignal_add(&ev, NULL); - } - - memset(&itv, 0, sizeof(itv)); - itv.it_value.tv_sec = 0; - itv.it_value.tv_usec = 100000; - if (setitimer(ITIMER_REAL, &itv, NULL) == -1) - goto skip_simplesignal; - - event_dispatch(); - skip_simplesignal: - if (evsignal_del(&ev) == -1) - test_ok = 0; - - cleanup_test(); -} - -static void -test_simplestsignal(void) -{ - setup_test("Simplest one signal: "); - test_simplesignal_impl(0); -} - -static void -test_simplesignal(void) -{ - setup_test("Simple signal: "); - test_simplesignal_impl(1); -} - -static void -test_multiplesignal(void) -{ - struct event ev_one, ev_two; - struct itimerval itv; - - setup_test("Multiple signal: "); - - evsignal_set(&ev_one, SIGALRM, signal_cb, &ev_one); - evsignal_add(&ev_one, NULL); - - evsignal_set(&ev_two, SIGALRM, signal_cb, &ev_two); - evsignal_add(&ev_two, NULL); - - memset(&itv, 0, sizeof(itv)); - itv.it_value.tv_sec = 0; - itv.it_value.tv_usec = 100000; - if (setitimer(ITIMER_REAL, &itv, NULL) == -1) - goto skip_simplesignal; - - event_dispatch(); - - skip_simplesignal: - if (evsignal_del(&ev_one) == -1) - test_ok = 0; - if (evsignal_del(&ev_two) == -1) - test_ok = 0; - - cleanup_test(); -} - -static void -test_immediatesignal(void) -{ - struct event ev; - - test_ok = 0; - evsignal_set(&ev, SIGUSR1, signal_cb, &ev); - evsignal_add(&ev, NULL); - raise(SIGUSR1); - event_loop(EVLOOP_NONBLOCK); - evsignal_del(&ev); - cleanup_test(); -} - -static void -test_signal_dealloc(void) -{ - /* make sure that evsignal_event is event_del'ed and pipe closed */ - struct event ev; - struct event_base *base = event_init(); - evsignal_set(&ev, SIGUSR1, signal_cb, &ev); - evsignal_add(&ev, NULL); - evsignal_del(&ev); - event_base_free(base); - /* If we got here without asserting, we're fine. */ - test_ok = 1; - cleanup_test(); -} - -static void -test_signal_pipeloss(void) -{ - /* make sure that the base1 pipe is closed correctly. */ - struct event_base *base1, *base2; - int pipe1; - test_ok = 0; - base1 = event_init(); - pipe1 = base1->sig.ev_signal_pair[0]; - base2 = event_init(); - event_base_free(base2); - event_base_free(base1); - if (close(pipe1) != -1 || errno!=EBADF) { - /* fd must be closed, so second close gives -1, EBADF */ - printf("signal pipe not closed. "); - test_ok = 0; - } else { - test_ok = 1; - } - cleanup_test(); -} - -/* - * make two bases to catch signals, use both of them. this only works - * for event mechanisms that use our signal pipe trick. kqueue handles - * signals internally, and all interested kqueues get all the signals. - */ -static void -test_signal_switchbase(void) -{ - struct event ev1, ev2; - struct event_base *base1, *base2; - int is_kqueue; - test_ok = 0; - base1 = event_init(); - base2 = event_init(); - is_kqueue = !strcmp(event_get_method(),"kqueue"); - evsignal_set(&ev1, SIGUSR1, signal_cb, &ev1); - evsignal_set(&ev2, SIGUSR1, signal_cb, &ev2); - if (event_base_set(base1, &ev1) || - event_base_set(base2, &ev2) || - event_add(&ev1, NULL) || - event_add(&ev2, NULL)) { - fprintf(stderr, "%s: cannot set base, add\n", __func__); - exit(1); - } - - tt_ptr_op(event_get_base(&ev1), ==, base1); - tt_ptr_op(event_get_base(&ev2), ==, base2); - - test_ok = 0; - /* can handle signal before loop is called */ - raise(SIGUSR1); - event_base_loop(base2, EVLOOP_NONBLOCK); - if (is_kqueue) { - if (!test_ok) - goto end; - test_ok = 0; - } - event_base_loop(base1, EVLOOP_NONBLOCK); - if (test_ok && !is_kqueue) { - test_ok = 0; - - /* set base1 to handle signals */ - event_base_loop(base1, EVLOOP_NONBLOCK); - raise(SIGUSR1); - event_base_loop(base1, EVLOOP_NONBLOCK); - event_base_loop(base2, EVLOOP_NONBLOCK); - } -end: - event_base_free(base1); - event_base_free(base2); - cleanup_test(); -} - -/* - * assert that a signal event removed from the event queue really is - * removed - with no possibility of it's parent handler being fired. - */ -static void -test_signal_assert(void) -{ - struct event ev; - struct event_base *base = event_init(); - test_ok = 0; - /* use SIGCONT so we don't kill ourselves when we signal to nowhere */ - evsignal_set(&ev, SIGCONT, signal_cb, &ev); - evsignal_add(&ev, NULL); - /* - * if evsignal_del() fails to reset the handler, it's current handler - * will still point to evsig_handler(). - */ - evsignal_del(&ev); - - raise(SIGCONT); -#if 0 - /* only way to verify we were in evsig_handler() */ - /* XXXX Now there's no longer a good way. */ - if (base->sig.evsig_caught) - test_ok = 0; - else - test_ok = 1; -#else - test_ok = 1; -#endif - - event_base_free(base); - cleanup_test(); - return; -} - -/* - * assert that we restore our previous signal handler properly. - */ -static void -test_signal_restore(void) -{ - struct event ev; - struct event_base *base = event_init(); -#ifdef EVENT__HAVE_SIGACTION - struct sigaction sa; -#endif - - test_ok = 0; -#ifdef EVENT__HAVE_SIGACTION - sa.sa_handler = signal_cb_sa; - sa.sa_flags = 0x0; - sigemptyset(&sa.sa_mask); - if (sigaction(SIGUSR1, &sa, NULL) == -1) - goto out; -#else - if (signal(SIGUSR1, signal_cb_sa) == SIG_ERR) - goto out; -#endif - evsignal_set(&ev, SIGUSR1, signal_cb, &ev); - evsignal_add(&ev, NULL); - evsignal_del(&ev); - - raise(SIGUSR1); - /* 1 == signal_cb, 2 == signal_cb_sa, we want our previous handler */ - if (test_ok != 2) - test_ok = 0; -out: - event_base_free(base); - cleanup_test(); - return; -} - -static void -signal_cb_swp(int sig, short event, void *arg) -{ - called++; - if (called < 5) - raise(sig); - else - event_loopexit(NULL); -} -static void -timeout_cb_swp(evutil_socket_t fd, short event, void *arg) -{ - if (called == -1) { - struct timeval tv = {5, 0}; - - called = 0; - evtimer_add((struct event *)arg, &tv); - raise(SIGUSR1); - return; - } - test_ok = 0; - event_loopexit(NULL); -} - -static void -test_signal_while_processing(void) -{ - struct event_base *base = event_init(); - struct event ev, ev_timer; - struct timeval tv = {0, 0}; - - setup_test("Receiving a signal while processing other signal: "); - - called = -1; - test_ok = 1; - signal_set(&ev, SIGUSR1, signal_cb_swp, NULL); - signal_add(&ev, NULL); - evtimer_set(&ev_timer, timeout_cb_swp, &ev_timer); - evtimer_add(&ev_timer, &tv); - event_dispatch(); - - event_base_free(base); - cleanup_test(); - return; -} -#endif - -static void -test_free_active_base(void *ptr) -{ - struct basic_test_data *data = ptr; - struct event_base *base1; - 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"); - } - - base1 = event_init(); - tt_assert(base1); - event_assign(&ev1, base1, 0, 0, dummy_read_cb, NULL); - event_active(&ev1, EV_READ, 1); - event_base_free(base1); -end: - ; -} - -static void -test_manipulate_active_events(void *ptr) -{ - struct basic_test_data *data = ptr; - struct event_base *base = data->base; - struct event ev1; - - event_assign(&ev1, base, -1, EV_TIMEOUT, dummy_read_cb, NULL); - - /* Make sure an active event is pending. */ - event_active(&ev1, EV_READ, 1); - tt_int_op(event_pending(&ev1, EV_READ|EV_TIMEOUT|EV_WRITE, NULL), - ==, EV_READ); - - /* Make sure that activating an event twice works. */ - event_active(&ev1, EV_WRITE, 1); - tt_int_op(event_pending(&ev1, EV_READ|EV_TIMEOUT|EV_WRITE, NULL), - ==, EV_READ|EV_WRITE); - -end: - event_del(&ev1); -} - -static void -event_selfarg_cb(evutil_socket_t fd, short event, void *arg) -{ - struct event *ev = arg; - struct event_base *base = event_get_base(ev); - event_base_assert_ok_(base); - event_base_loopexit(base, NULL); - tt_want(ev == event_base_get_running_event(base)); -} - -static void -test_event_new_selfarg(void *ptr) -{ - struct basic_test_data *data = ptr; - struct event_base *base = data->base; - struct event *ev = event_new(base, -1, EV_READ, event_selfarg_cb, - event_self_cbarg()); - - event_active(ev, EV_READ, 1); - event_base_dispatch(base); - - event_free(ev); -} - -static void -test_event_assign_selfarg(void *ptr) -{ - struct basic_test_data *data = ptr; - struct event_base *base = data->base; - struct event ev; - - event_assign(&ev, base, -1, EV_READ, event_selfarg_cb, - event_self_cbarg()); - event_active(&ev, EV_READ, 1); - event_base_dispatch(base); -} - -static void -test_event_base_get_num_events(void *ptr) -{ - struct basic_test_data *data = ptr; - struct event_base *base = data->base; - struct event ev; - int event_count_active; - int event_count_virtual; - int event_count_added; - int event_count_active_virtual; - int event_count_active_added; - int event_count_virtual_added; - int event_count_active_added_virtual; - - struct timeval qsec = {0, 100000}; - - event_assign(&ev, base, -1, EV_READ, event_selfarg_cb, - event_self_cbarg()); - - event_add(&ev, &qsec); - event_count_active = event_base_get_num_events(base, - EVENT_BASE_COUNT_ACTIVE); - event_count_virtual = event_base_get_num_events(base, - EVENT_BASE_COUNT_VIRTUAL); - event_count_added = event_base_get_num_events(base, - EVENT_BASE_COUNT_ADDED); - event_count_active_virtual = event_base_get_num_events(base, - EVENT_BASE_COUNT_ACTIVE|EVENT_BASE_COUNT_VIRTUAL); - event_count_active_added = event_base_get_num_events(base, - EVENT_BASE_COUNT_ACTIVE|EVENT_BASE_COUNT_ADDED); - event_count_virtual_added = event_base_get_num_events(base, - EVENT_BASE_COUNT_VIRTUAL|EVENT_BASE_COUNT_ADDED); - event_count_active_added_virtual = event_base_get_num_events(base, - EVENT_BASE_COUNT_ACTIVE| - EVENT_BASE_COUNT_ADDED| - EVENT_BASE_COUNT_VIRTUAL); - tt_int_op(event_count_active, ==, 0); - tt_int_op(event_count_virtual, ==, 0); - /* libevent itself adds a timeout event, so the event_count is 2 here */ - tt_int_op(event_count_added, ==, 2); - tt_int_op(event_count_active_virtual, ==, 0); - tt_int_op(event_count_active_added, ==, 2); - tt_int_op(event_count_virtual_added, ==, 2); - tt_int_op(event_count_active_added_virtual, ==, 2); - - event_active(&ev, EV_READ, 1); - event_count_active = event_base_get_num_events(base, - EVENT_BASE_COUNT_ACTIVE); - event_count_virtual = event_base_get_num_events(base, - EVENT_BASE_COUNT_VIRTUAL); - event_count_added = event_base_get_num_events(base, - EVENT_BASE_COUNT_ADDED); - event_count_active_virtual = event_base_get_num_events(base, - EVENT_BASE_COUNT_ACTIVE|EVENT_BASE_COUNT_VIRTUAL); - event_count_active_added = event_base_get_num_events(base, - EVENT_BASE_COUNT_ACTIVE|EVENT_BASE_COUNT_ADDED); - event_count_virtual_added = event_base_get_num_events(base, - EVENT_BASE_COUNT_VIRTUAL|EVENT_BASE_COUNT_ADDED); - event_count_active_added_virtual = event_base_get_num_events(base, - EVENT_BASE_COUNT_ACTIVE| - EVENT_BASE_COUNT_ADDED| - EVENT_BASE_COUNT_VIRTUAL); - tt_int_op(event_count_active, ==, 1); - tt_int_op(event_count_virtual, ==, 0); - tt_int_op(event_count_added, ==, 3); - tt_int_op(event_count_active_virtual, ==, 1); - tt_int_op(event_count_active_added, ==, 4); - tt_int_op(event_count_virtual_added, ==, 3); - tt_int_op(event_count_active_added_virtual, ==, 4); - - event_base_loop(base, 0); - event_count_active = event_base_get_num_events(base, - EVENT_BASE_COUNT_ACTIVE); - event_count_virtual = event_base_get_num_events(base, - EVENT_BASE_COUNT_VIRTUAL); - event_count_added = event_base_get_num_events(base, - EVENT_BASE_COUNT_ADDED); - event_count_active_virtual = event_base_get_num_events(base, - EVENT_BASE_COUNT_ACTIVE|EVENT_BASE_COUNT_VIRTUAL); - event_count_active_added = event_base_get_num_events(base, - EVENT_BASE_COUNT_ACTIVE|EVENT_BASE_COUNT_ADDED); - event_count_virtual_added = event_base_get_num_events(base, - EVENT_BASE_COUNT_VIRTUAL|EVENT_BASE_COUNT_ADDED); - event_count_active_added_virtual = event_base_get_num_events(base, - EVENT_BASE_COUNT_ACTIVE| - EVENT_BASE_COUNT_ADDED| - EVENT_BASE_COUNT_VIRTUAL); - tt_int_op(event_count_active, ==, 0); - tt_int_op(event_count_virtual, ==, 0); - tt_int_op(event_count_added, ==, 0); - tt_int_op(event_count_active_virtual, ==, 0); - tt_int_op(event_count_active_added, ==, 0); - tt_int_op(event_count_virtual_added, ==, 0); - tt_int_op(event_count_active_added_virtual, ==, 0); - - event_base_add_virtual_(base); - event_count_active = event_base_get_num_events(base, - EVENT_BASE_COUNT_ACTIVE); - event_count_virtual = event_base_get_num_events(base, - EVENT_BASE_COUNT_VIRTUAL); - event_count_added = event_base_get_num_events(base, - EVENT_BASE_COUNT_ADDED); - event_count_active_virtual = event_base_get_num_events(base, - EVENT_BASE_COUNT_ACTIVE|EVENT_BASE_COUNT_VIRTUAL); - event_count_active_added = event_base_get_num_events(base, - EVENT_BASE_COUNT_ACTIVE|EVENT_BASE_COUNT_ADDED); - event_count_virtual_added = event_base_get_num_events(base, - EVENT_BASE_COUNT_VIRTUAL|EVENT_BASE_COUNT_ADDED); - event_count_active_added_virtual = event_base_get_num_events(base, - EVENT_BASE_COUNT_ACTIVE| - EVENT_BASE_COUNT_ADDED| - EVENT_BASE_COUNT_VIRTUAL); - tt_int_op(event_count_active, ==, 0); - tt_int_op(event_count_virtual, ==, 1); - tt_int_op(event_count_added, ==, 0); - tt_int_op(event_count_active_virtual, ==, 1); - tt_int_op(event_count_active_added, ==, 0); - tt_int_op(event_count_virtual_added, ==, 1); - tt_int_op(event_count_active_added_virtual, ==, 1); - -end: - ; -} - -static void -test_event_base_get_max_events(void *ptr) -{ - struct basic_test_data *data = ptr; - struct event_base *base = data->base; - struct event ev; - struct event ev2; - int event_count_active; - int event_count_virtual; - int event_count_added; - int event_count_active_virtual; - int event_count_active_added; - int event_count_virtual_added; - int event_count_active_added_virtual; - - struct timeval qsec = {0, 100000}; - - event_assign(&ev, base, -1, EV_READ, event_selfarg_cb, - event_self_cbarg()); - event_assign(&ev2, base, -1, EV_READ, event_selfarg_cb, - event_self_cbarg()); - - event_add(&ev, &qsec); - event_add(&ev2, &qsec); - event_del(&ev2); - - event_count_active = event_base_get_max_events(base, - EVENT_BASE_COUNT_ACTIVE, 0); - event_count_virtual = event_base_get_max_events(base, - EVENT_BASE_COUNT_VIRTUAL, 0); - event_count_added = event_base_get_max_events(base, - EVENT_BASE_COUNT_ADDED, 0); - event_count_active_virtual = event_base_get_max_events(base, - EVENT_BASE_COUNT_ACTIVE | EVENT_BASE_COUNT_VIRTUAL, 0); - event_count_active_added = event_base_get_max_events(base, - EVENT_BASE_COUNT_ACTIVE | EVENT_BASE_COUNT_ADDED, 0); - event_count_virtual_added = event_base_get_max_events(base, - EVENT_BASE_COUNT_VIRTUAL | EVENT_BASE_COUNT_ADDED, 0); - event_count_active_added_virtual = event_base_get_max_events(base, - EVENT_BASE_COUNT_ACTIVE | - EVENT_BASE_COUNT_ADDED | - EVENT_BASE_COUNT_VIRTUAL, 0); - - tt_int_op(event_count_active, ==, 0); - tt_int_op(event_count_virtual, ==, 0); - /* libevent itself adds a timeout event, so the event_count is 4 here */ - tt_int_op(event_count_added, ==, 4); - tt_int_op(event_count_active_virtual, ==, 0); - tt_int_op(event_count_active_added, ==, 4); - tt_int_op(event_count_virtual_added, ==, 4); - tt_int_op(event_count_active_added_virtual, ==, 4); - - event_active(&ev, EV_READ, 1); - event_count_active = event_base_get_max_events(base, - EVENT_BASE_COUNT_ACTIVE, 0); - event_count_virtual = event_base_get_max_events(base, - EVENT_BASE_COUNT_VIRTUAL, 0); - event_count_added = event_base_get_max_events(base, - EVENT_BASE_COUNT_ADDED, 0); - event_count_active_virtual = event_base_get_max_events(base, - EVENT_BASE_COUNT_ACTIVE | EVENT_BASE_COUNT_VIRTUAL, 0); - event_count_active_added = event_base_get_max_events(base, - EVENT_BASE_COUNT_ACTIVE | EVENT_BASE_COUNT_ADDED, 0); - event_count_virtual_added = event_base_get_max_events(base, - EVENT_BASE_COUNT_VIRTUAL | EVENT_BASE_COUNT_ADDED, 0); - event_count_active_added_virtual = event_base_get_max_events(base, - EVENT_BASE_COUNT_ACTIVE | - EVENT_BASE_COUNT_ADDED | - EVENT_BASE_COUNT_VIRTUAL, 0); - - tt_int_op(event_count_active, ==, 1); - tt_int_op(event_count_virtual, ==, 0); - tt_int_op(event_count_added, ==, 4); - tt_int_op(event_count_active_virtual, ==, 1); - tt_int_op(event_count_active_added, ==, 5); - tt_int_op(event_count_virtual_added, ==, 4); - tt_int_op(event_count_active_added_virtual, ==, 5); - - event_base_loop(base, 0); - event_count_active = event_base_get_max_events(base, - EVENT_BASE_COUNT_ACTIVE, 1); - event_count_virtual = event_base_get_max_events(base, - EVENT_BASE_COUNT_VIRTUAL, 1); - event_count_added = event_base_get_max_events(base, - EVENT_BASE_COUNT_ADDED, 1); - event_count_active_virtual = event_base_get_max_events(base, - EVENT_BASE_COUNT_ACTIVE | EVENT_BASE_COUNT_VIRTUAL, 0); - event_count_active_added = event_base_get_max_events(base, - EVENT_BASE_COUNT_ACTIVE | EVENT_BASE_COUNT_ADDED, 0); - event_count_virtual_added = event_base_get_max_events(base, - EVENT_BASE_COUNT_VIRTUAL | EVENT_BASE_COUNT_ADDED, 0); - event_count_active_added_virtual = event_base_get_max_events(base, - EVENT_BASE_COUNT_ACTIVE | - EVENT_BASE_COUNT_ADDED | - EVENT_BASE_COUNT_VIRTUAL, 1); - - tt_int_op(event_count_active, ==, 1); - tt_int_op(event_count_virtual, ==, 0); - tt_int_op(event_count_added, ==, 4); - tt_int_op(event_count_active_virtual, ==, 0); - tt_int_op(event_count_active_added, ==, 0); - tt_int_op(event_count_virtual_added, ==, 0); - tt_int_op(event_count_active_added_virtual, ==, 0); - - event_count_active = event_base_get_max_events(base, - EVENT_BASE_COUNT_ACTIVE, 0); - event_count_virtual = event_base_get_max_events(base, - EVENT_BASE_COUNT_VIRTUAL, 0); - event_count_added = event_base_get_max_events(base, - EVENT_BASE_COUNT_ADDED, 0); - tt_int_op(event_count_active, ==, 0); - tt_int_op(event_count_virtual, ==, 0); - tt_int_op(event_count_added, ==, 0); - - event_base_add_virtual_(base); - event_count_active = event_base_get_max_events(base, - EVENT_BASE_COUNT_ACTIVE, 0); - event_count_virtual = event_base_get_max_events(base, - EVENT_BASE_COUNT_VIRTUAL, 0); - event_count_added = event_base_get_max_events(base, - EVENT_BASE_COUNT_ADDED, 0); - event_count_active_virtual = event_base_get_max_events(base, - EVENT_BASE_COUNT_ACTIVE | EVENT_BASE_COUNT_VIRTUAL, 0); - event_count_active_added = event_base_get_max_events(base, - EVENT_BASE_COUNT_ACTIVE | EVENT_BASE_COUNT_ADDED, 0); - event_count_virtual_added = event_base_get_max_events(base, - EVENT_BASE_COUNT_VIRTUAL | EVENT_BASE_COUNT_ADDED, 0); - event_count_active_added_virtual = event_base_get_max_events(base, - EVENT_BASE_COUNT_ACTIVE | - EVENT_BASE_COUNT_ADDED | - EVENT_BASE_COUNT_VIRTUAL, 0); - - tt_int_op(event_count_active, ==, 0); - tt_int_op(event_count_virtual, ==, 1); - tt_int_op(event_count_added, ==, 0); - tt_int_op(event_count_active_virtual, ==, 1); - tt_int_op(event_count_active_added, ==, 0); - tt_int_op(event_count_virtual_added, ==, 1); - tt_int_op(event_count_active_added_virtual, ==, 1); - -end: - ; -} - -static void -test_bad_assign(void *ptr) -{ - struct event ev; - int r; - /* READ|SIGNAL is not allowed */ - r = event_assign(&ev, NULL, -1, EV_SIGNAL|EV_READ, dummy_read_cb, NULL); - tt_int_op(r,==,-1); - -end: - ; -} - -static int reentrant_cb_run = 0; - -static void -bad_reentrant_run_loop_cb(evutil_socket_t fd, short what, void *ptr) -{ - struct event_base *base = ptr; - int r; - reentrant_cb_run = 1; - /* This reentrant call to event_base_loop should be detected and - * should fail */ - r = event_base_loop(base, 0); - tt_int_op(r, ==, -1); -end: - ; -} - -static void -test_bad_reentrant(void *ptr) -{ - struct basic_test_data *data = ptr; - struct event_base *base = data->base; - struct event ev; - int r; - event_assign(&ev, base, -1, - 0, bad_reentrant_run_loop_cb, base); - - event_active(&ev, EV_WRITE, 1); - r = event_base_loop(base, 0); - tt_int_op(r, ==, 1); - tt_int_op(reentrant_cb_run, ==, 1); -end: - ; -} - -static int n_write_a_byte_cb=0; -static int n_read_and_drain_cb=0; -static int n_activate_other_event_cb=0; -static void -write_a_byte_cb(evutil_socket_t fd, short what, void *arg) -{ - char buf[] = "x"; - if (write(fd, buf, 1) == 1) - ++n_write_a_byte_cb; -} -static void -read_and_drain_cb(evutil_socket_t fd, short what, void *arg) -{ - char buf[128]; - int n; - ++n_read_and_drain_cb; - while ((n = read(fd, buf, sizeof(buf))) > 0) - ; -} - -static void -activate_other_event_cb(evutil_socket_t fd, short what, void *other_) -{ - struct event *ev_activate = other_; - ++n_activate_other_event_cb; - event_active_later_(ev_activate, EV_READ); -} - -static void -test_active_later(void *ptr) -{ - struct basic_test_data *data = ptr; - struct event *ev1 = NULL, *ev2 = NULL; - struct event ev3, ev4; - struct timeval qsec = {0, 100000}; - ev1 = event_new(data->base, data->pair[0], EV_READ|EV_PERSIST, read_and_drain_cb, NULL); - ev2 = event_new(data->base, data->pair[1], EV_WRITE|EV_PERSIST, write_a_byte_cb, NULL); - event_assign(&ev3, data->base, -1, 0, activate_other_event_cb, &ev4); - event_assign(&ev4, data->base, -1, 0, activate_other_event_cb, &ev3); - event_add(ev1, NULL); - event_add(ev2, NULL); - event_active_later_(&ev3, EV_READ); - - event_base_loopexit(data->base, &qsec); - - event_base_loop(data->base, 0); - - TT_BLATHER(("%d write calls, %d read calls, %d activate-other calls.", - n_write_a_byte_cb, n_read_and_drain_cb, n_activate_other_event_cb)); - event_del(&ev3); - event_del(&ev4); - - tt_int_op(n_write_a_byte_cb, ==, n_activate_other_event_cb); - tt_int_op(n_write_a_byte_cb, >, 100); - tt_int_op(n_read_and_drain_cb, >, 100); - tt_int_op(n_activate_other_event_cb, >, 100); - - event_active_later_(&ev4, EV_READ); - event_active(&ev4, EV_READ, 1); /* This should make the event - active immediately. */ - tt_assert((ev4.ev_flags & EVLIST_ACTIVE) != 0); - tt_assert((ev4.ev_flags & EVLIST_ACTIVE_LATER) == 0); - - /* Now leave this one around, so that event_free sees it and removes - * it. */ - event_active_later_(&ev3, EV_READ); - event_base_assert_ok_(data->base); - -end: - if (ev1) - event_free(ev1); - if (ev2) - event_free(ev2); - - event_base_free(data->base); - data->base = NULL; -} - - -static void incr_arg_cb(evutil_socket_t fd, short what, void *arg) -{ - int *intptr = arg; - (void) fd; (void) what; - ++*intptr; -} -static void remove_timers_cb(evutil_socket_t fd, short what, void *arg) -{ - struct event **ep = arg; - (void) fd; (void) what; - event_remove_timer(ep[0]); - event_remove_timer(ep[1]); -} -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); -} -struct read_not_timeout_param -{ - struct event **ev; - int events; - int count; -}; -static void read_not_timeout_cb(evutil_socket_t fd, short what, void *arg) -{ - struct read_not_timeout_param *rntp = arg; - char c; - ev_ssize_t n; - (void) fd; (void) what; - n = read(fd, &c, 1); - tt_int_op(n, ==, 1); - rntp->events |= what; - ++rntp->count; - if(2 == rntp->count) event_del(rntp->ev[0]); -end: - ; -} - -static void -test_event_remove_timeout(void *ptr) -{ - struct basic_test_data *data = ptr; - struct event_base *base = data->base; - struct event *ev[5]; - int ev1_fired=0; - struct timeval ms25 = { 0, 25*1000 }, - ms40 = { 0, 40*1000 }, - ms75 = { 0, 75*1000 }, - ms125 = { 0, 125*1000 }; - struct read_not_timeout_param rntp = { ev, 0, 0 }; - - event_base_assert_ok_(base); - - ev[0] = event_new(base, data->pair[0], EV_READ|EV_PERSIST, - read_not_timeout_cb, &rntp); - ev[1] = evtimer_new(base, incr_arg_cb, &ev1_fired); - ev[2] = evtimer_new(base, remove_timers_cb, ev); - ev[3] = evtimer_new(base, send_a_byte_cb, &data->pair[1]); - ev[4] = evtimer_new(base, send_a_byte_cb, &data->pair[1]); - tt_assert(base); - event_add(ev[2], &ms25); /* remove timers */ - event_add(ev[4], &ms40); /* write to test if timer re-activates */ - event_add(ev[0], &ms75); /* read */ - event_add(ev[1], &ms75); /* timer */ - event_add(ev[3], &ms125); /* timeout. */ - event_base_assert_ok_(base); - - event_base_dispatch(base); - - tt_int_op(ev1_fired, ==, 0); - tt_int_op(rntp.events, ==, EV_READ); - - event_base_assert_ok_(base); -end: - event_free(ev[0]); - event_free(ev[1]); - event_free(ev[2]); - event_free(ev[3]); - event_free(ev[4]); -} - -static void -test_event_base_new(void *ptr) -{ - struct basic_test_data *data = ptr; - struct event_base *base = 0; - struct event ev1; - struct basic_cb_args args; - - int towrite = (int)strlen(TEST1)+1; - int len = write(data->pair[0], TEST1, towrite); - - if (len < 0) - tt_abort_perror("initial write"); - else if (len != towrite) - tt_abort_printf(("initial write fell short (%d of %d bytes)", - len, towrite)); - - if (shutdown(data->pair[0], SHUT_WR)) - tt_abort_perror("initial write shutdown"); - - base = event_base_new(); - if (!base) - tt_abort_msg("failed to create event base"); - - args.eb = base; - args.ev = &ev1; - args.callcount = 0; - event_assign(&ev1, base, data->pair[1], - EV_READ|EV_PERSIST, basic_read_cb, &args); - - if (event_add(&ev1, NULL)) - tt_abort_perror("initial event_add"); - - if (event_base_loop(base, 0)) - tt_abort_msg("unsuccessful exit from event loop"); - -end: - if (base) - event_base_free(base); -} - -static void -test_loopexit(void) -{ - struct timeval tv, tv_start, tv_end; - struct event ev; - - setup_test("Loop exit: "); - - tv.tv_usec = 0; - tv.tv_sec = 60*60*24; - evtimer_set(&ev, timeout_cb, NULL); - evtimer_add(&ev, &tv); - - tv.tv_usec = 300*1000; - tv.tv_sec = 0; - event_loopexit(&tv); - - evutil_gettimeofday(&tv_start, NULL); - event_dispatch(); - evutil_gettimeofday(&tv_end, NULL); - - evtimer_del(&ev); - - tt_assert(event_base_got_exit(global_base)); - tt_assert(!event_base_got_break(global_base)); - - test_timeval_diff_eq(&tv_start, &tv_end, 300); - - test_ok = 1; -end: - cleanup_test(); -} - -static void -test_loopexit_multiple(void) -{ - struct timeval tv, tv_start, tv_end; - struct event_base *base; - - setup_test("Loop Multiple exit: "); - - base = event_base_new(); - - tv.tv_usec = 200*1000; - tv.tv_sec = 0; - event_base_loopexit(base, &tv); - - tv.tv_usec = 0; - tv.tv_sec = 3; - event_base_loopexit(base, &tv); - - evutil_gettimeofday(&tv_start, NULL); - event_base_dispatch(base); - evutil_gettimeofday(&tv_end, NULL); - - tt_assert(event_base_got_exit(base)); - tt_assert(!event_base_got_break(base)); - - event_base_free(base); - - test_timeval_diff_eq(&tv_start, &tv_end, 200); - - test_ok = 1; - -end: - cleanup_test(); -} - -static void -break_cb(evutil_socket_t fd, short events, void *arg) -{ - test_ok = 1; - event_loopbreak(); -} - -static void -fail_cb(evutil_socket_t fd, short events, void *arg) -{ - test_ok = 0; -} - -static void -test_loopbreak(void) -{ - struct event ev1, ev2; - struct timeval tv; - - setup_test("Loop break: "); - - tv.tv_sec = 0; - tv.tv_usec = 0; - evtimer_set(&ev1, break_cb, NULL); - evtimer_add(&ev1, &tv); - evtimer_set(&ev2, fail_cb, NULL); - evtimer_add(&ev2, &tv); - - event_dispatch(); - - tt_assert(!event_base_got_exit(global_base)); - tt_assert(event_base_got_break(global_base)); - - evtimer_del(&ev1); - evtimer_del(&ev2); - -end: - cleanup_test(); -} - -static struct event *readd_test_event_last_added = NULL; -static void -re_add_read_cb(evutil_socket_t fd, short event, void *arg) -{ - char buf[256]; - struct event *ev_other = arg; - ev_ssize_t n_read; - - readd_test_event_last_added = ev_other; - - n_read = read(fd, buf, sizeof(buf)); - - 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) -{ - struct event ev1, ev2; - - 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); - - if (write(pair[0], "Hello", 5) < 0) { - tt_fail_perror("write(pair[0])"); - } - - if (write(pair[1], "Hello", 5) < 0) { - tt_fail_perror("write(pair[1])\n"); - } - - 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; - } else { - if (event_pending(&ev1, EV_READ, NULL) || - !event_pending(&ev2, EV_READ, NULL)) - test_ok = 0; - } - - event_del(&ev1); - event_del(&ev2); - - cleanup_test(); -} - -struct test_pri_event { - struct event ev; - int count; -}; - -static void -test_priorities_cb(evutil_socket_t fd, short what, void *arg) -{ - struct test_pri_event *pri = arg; - struct timeval tv; - - if (pri->count == 3) { - event_loopexit(NULL); - return; - } - - pri->count++; - - evutil_timerclear(&tv); - event_add(&pri->ev, &tv); -} - -static void -test_priorities_impl(int npriorities) -{ - struct test_pri_event one, two; - struct timeval tv; - - TT_BLATHER(("Testing Priorities %d: ", npriorities)); - - event_base_priority_init(global_base, npriorities); - - memset(&one, 0, sizeof(one)); - memset(&two, 0, sizeof(two)); - - timeout_set(&one.ev, test_priorities_cb, &one); - if (event_priority_set(&one.ev, 0) == -1) { - fprintf(stderr, "%s: failed to set priority", __func__); - exit(1); - } - - timeout_set(&two.ev, test_priorities_cb, &two); - if (event_priority_set(&two.ev, npriorities - 1) == -1) { - fprintf(stderr, "%s: failed to set priority", __func__); - exit(1); - } - - evutil_timerclear(&tv); - - if (event_add(&one.ev, &tv) == -1) - exit(1); - if (event_add(&two.ev, &tv) == -1) - exit(1); - - event_dispatch(); - - event_del(&one.ev); - event_del(&two.ev); - - if (npriorities == 1) { - if (one.count == 3 && two.count == 3) - test_ok = 1; - } else if (npriorities == 2) { - /* Two is called once because event_loopexit is priority 1 */ - if (one.count == 3 && two.count == 1) - test_ok = 1; - } else { - if (one.count == 3 && two.count == 0) - test_ok = 1; - } -} - -static void -test_priorities(void) -{ - test_priorities_impl(1); - if (test_ok) - test_priorities_impl(2); - if (test_ok) - test_priorities_impl(3); -} - -/* priority-active-inversion: activate a higher-priority event, and make sure - * it keeps us from running a lower-priority event first. */ -static int n_pai_calls = 0; -static struct event pai_events[3]; - -static void -prio_active_inversion_cb(evutil_socket_t fd, short what, void *arg) -{ - int *call_order = arg; - *call_order = n_pai_calls++; - if (n_pai_calls == 1) { - /* This should activate later, even though it shares a - priority with us. */ - event_active(&pai_events[1], EV_READ, 1); - /* This should activate next, since its priority is higher, - even though we activated it second. */ - event_active(&pai_events[2], EV_TIMEOUT, 1); - } -} - -static void -test_priority_active_inversion(void *data_) -{ - struct basic_test_data *data = data_; - struct event_base *base = data->base; - int call_order[3]; - int i; - tt_int_op(event_base_priority_init(base, 8), ==, 0); - - n_pai_calls = 0; - memset(call_order, 0, sizeof(call_order)); - - for (i=0;i<3;++i) { - event_assign(&pai_events[i], data->base, -1, 0, - prio_active_inversion_cb, &call_order[i]); - } - - event_priority_set(&pai_events[0], 4); - event_priority_set(&pai_events[1], 4); - event_priority_set(&pai_events[2], 0); - - event_active(&pai_events[0], EV_WRITE, 1); - - event_base_dispatch(base); - tt_int_op(n_pai_calls, ==, 3); - tt_int_op(call_order[0], ==, 0); - tt_int_op(call_order[1], ==, 2); - tt_int_op(call_order[2], ==, 1); -end: - ; -} - - -static void -test_multiple_cb(evutil_socket_t fd, short event, void *arg) -{ - if (event & EV_READ) - test_ok |= 1; - else if (event & EV_WRITE) - test_ok |= 2; -} - -static void -test_multiple_events_for_same_fd(void) -{ - struct event e1, e2; - - setup_test("Multiple events for same fd: "); - - event_set(&e1, pair[0], EV_READ, test_multiple_cb, NULL); - event_add(&e1, NULL); - event_set(&e2, pair[0], EV_WRITE, test_multiple_cb, NULL); - event_add(&e2, NULL); - event_loop(EVLOOP_ONCE); - event_del(&e2); - - if (write(pair[1], TEST1, strlen(TEST1)+1) < 0) { - tt_fail_perror("write"); - } - - event_loop(EVLOOP_ONCE); - event_del(&e1); - - if (test_ok != 3) - test_ok = 0; - - cleanup_test(); -} - -int evtag_decode_int(ev_uint32_t *pnumber, struct evbuffer *evbuf); -int evtag_decode_int64(ev_uint64_t *pnumber, struct evbuffer *evbuf); -int evtag_encode_tag(struct evbuffer *evbuf, ev_uint32_t number); -int evtag_decode_tag(ev_uint32_t *pnumber, struct evbuffer *evbuf); - -static void -read_once_cb(evutil_socket_t fd, short event, void *arg) -{ - char buf[256]; - int len; - - len = read(fd, buf, sizeof(buf)); - - if (called) { - test_ok = 0; - } else if (len) { - /* Assumes global pair[0] can be used for writing */ - if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) { - tt_fail_perror("write"); - test_ok = 0; - } else { - test_ok = 1; - } - } - - called++; -} - -static void -test_want_only_once(void) -{ - struct event ev; - struct timeval tv; - - /* Very simple read test */ - setup_test("Want read only once: "); - - if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) { - tt_fail_perror("write"); - } - - /* Setup the loop termination */ - evutil_timerclear(&tv); - tv.tv_usec = 300*1000; - event_loopexit(&tv); - - event_set(&ev, pair[1], EV_READ, read_once_cb, &ev); - if (event_add(&ev, NULL) == -1) - exit(1); - event_dispatch(); - - cleanup_test(); -} - -#define TEST_MAX_INT 6 - -static void -evtag_int_test(void *ptr) -{ - struct evbuffer *tmp = evbuffer_new(); - ev_uint32_t integers[TEST_MAX_INT] = { - 0xaf0, 0x1000, 0x1, 0xdeadbeef, 0x00, 0xbef000 - }; - ev_uint32_t integer; - ev_uint64_t big_int; - int i; - - evtag_init(); - - for (i = 0; i < TEST_MAX_INT; i++) { - int oldlen, newlen; - oldlen = (int)EVBUFFER_LENGTH(tmp); - evtag_encode_int(tmp, integers[i]); - newlen = (int)EVBUFFER_LENGTH(tmp); - TT_BLATHER(("encoded 0x%08x with %d bytes", - (unsigned)integers[i], newlen - oldlen)); - big_int = integers[i]; - big_int *= 1000000000; /* 1 billion */ - evtag_encode_int64(tmp, big_int); - } - - for (i = 0; i < TEST_MAX_INT; i++) { - tt_int_op(evtag_decode_int(&integer, tmp), !=, -1); - tt_uint_op(integer, ==, integers[i]); - tt_int_op(evtag_decode_int64(&big_int, tmp), !=, -1); - tt_assert((big_int / 1000000000) == integers[i]); - } - - tt_uint_op(EVBUFFER_LENGTH(tmp), ==, 0); -end: - evbuffer_free(tmp); -} - -static void -evtag_fuzz(void *ptr) -{ - unsigned char buffer[4096]; - struct evbuffer *tmp = evbuffer_new(); - struct timeval tv; - int i, j; - - int not_failed = 0; - - evtag_init(); - - for (j = 0; j < 100; j++) { - for (i = 0; i < (int)sizeof(buffer); i++) - buffer[i] = test_weakrand(); - evbuffer_drain(tmp, -1); - evbuffer_add(tmp, buffer, sizeof(buffer)); - - if (evtag_unmarshal_timeval(tmp, 0, &tv) != -1) - not_failed++; - } - - /* The majority of decodes should fail */ - tt_int_op(not_failed, <, 10); - - /* Now insert some corruption into the tag length field */ - evbuffer_drain(tmp, -1); - evutil_timerclear(&tv); - tv.tv_sec = 1; - evtag_marshal_timeval(tmp, 0, &tv); - evbuffer_add(tmp, buffer, sizeof(buffer)); - - ((char *)EVBUFFER_DATA(tmp))[1] = '\xff'; - if (evtag_unmarshal_timeval(tmp, 0, &tv) != -1) { - tt_abort_msg("evtag_unmarshal_timeval should have failed"); - } - -end: - evbuffer_free(tmp); -} - -static void -evtag_tag_encoding(void *ptr) -{ - struct evbuffer *tmp = evbuffer_new(); - ev_uint32_t integers[TEST_MAX_INT] = { - 0xaf0, 0x1000, 0x1, 0xdeadbeef, 0x00, 0xbef000 - }; - ev_uint32_t integer; - int i; - - evtag_init(); - - for (i = 0; i < TEST_MAX_INT; i++) { - int oldlen, newlen; - oldlen = (int)EVBUFFER_LENGTH(tmp); - evtag_encode_tag(tmp, integers[i]); - newlen = (int)EVBUFFER_LENGTH(tmp); - TT_BLATHER(("encoded 0x%08x with %d bytes", - (unsigned)integers[i], newlen - oldlen)); - } - - for (i = 0; i < TEST_MAX_INT; i++) { - tt_int_op(evtag_decode_tag(&integer, tmp), !=, -1); - tt_uint_op(integer, ==, integers[i]); - } - - tt_uint_op(EVBUFFER_LENGTH(tmp), ==, 0); - -end: - evbuffer_free(tmp); -} - -static void -evtag_test_peek(void *ptr) -{ - struct evbuffer *tmp = evbuffer_new(); - ev_uint32_t u32; - - evtag_marshal_int(tmp, 30, 0); - evtag_marshal_string(tmp, 40, "Hello world"); - - tt_int_op(evtag_peek(tmp, &u32), ==, 1); - tt_int_op(u32, ==, 30); - tt_int_op(evtag_peek_length(tmp, &u32), ==, 0); - tt_int_op(u32, ==, 1+1+1); - tt_int_op(evtag_consume(tmp), ==, 0); - - tt_int_op(evtag_peek(tmp, &u32), ==, 1); - tt_int_op(u32, ==, 40); - tt_int_op(evtag_peek_length(tmp, &u32), ==, 0); - tt_int_op(u32, ==, 1+1+11); - tt_int_op(evtag_payload_length(tmp, &u32), ==, 0); - tt_int_op(u32, ==, 11); - -end: - evbuffer_free(tmp); -} - - -static void -test_methods(void *ptr) -{ - const char **methods = event_get_supported_methods(); - struct event_config *cfg = NULL; - struct event_base *base = NULL; - const char *backend; - int n_methods = 0; - - tt_assert(methods); - - backend = methods[0]; - while (*methods != NULL) { - TT_BLATHER(("Support method: %s", *methods)); - ++methods; - ++n_methods; - } - - cfg = event_config_new(); - assert(cfg != NULL); - - tt_int_op(event_config_avoid_method(cfg, backend), ==, 0); - event_config_set_flag(cfg, EVENT_BASE_FLAG_IGNORE_ENV); - - base = event_base_new_with_config(cfg); - if (n_methods > 1) { - tt_assert(base); - tt_str_op(backend, !=, event_base_get_method(base)); - } else { - tt_assert(base == NULL); - } - -end: - if (base) - event_base_free(base); - if (cfg) - event_config_free(cfg); -} - -static void -test_version(void *arg) -{ - const char *vstr; - ev_uint32_t vint; - int major, minor, patch, n; - - vstr = event_get_version(); - vint = event_get_version_number(); - - tt_assert(vstr); - tt_assert(vint); - - tt_str_op(vstr, ==, LIBEVENT_VERSION); - tt_int_op(vint, ==, LIBEVENT_VERSION_NUMBER); - - n = sscanf(vstr, "%d.%d.%d", &major, &minor, &patch); - tt_assert(3 == n); - tt_int_op((vint&0xffffff00), ==, ((major<<24)|(minor<<16)|(patch<<8))); -end: - ; -} - -static void -test_base_features(void *arg) -{ - struct event_base *base = NULL; - struct event_config *cfg = NULL; - - cfg = event_config_new(); - - tt_assert(0 == event_config_require_features(cfg, EV_FEATURE_ET)); - - base = event_base_new_with_config(cfg); - if (base) { - tt_int_op(EV_FEATURE_ET, ==, - event_base_get_features(base) & EV_FEATURE_ET); - } else { - base = event_base_new(); - tt_int_op(0, ==, event_base_get_features(base) & EV_FEATURE_ET); - } - -end: - if (base) - event_base_free(base); - if (cfg) - event_config_free(cfg); -} - -#ifdef EVENT__HAVE_SETENV -#define SETENV_OK -#elif !defined(EVENT__HAVE_SETENV) && defined(EVENT__HAVE_PUTENV) -static void setenv(const char *k, const char *v, int o_) -{ - char b[256]; - evutil_snprintf(b, sizeof(b), "%s=%s",k,v); - putenv(b); -} -#define SETENV_OK -#endif - -#ifdef EVENT__HAVE_UNSETENV -#define UNSETENV_OK -#elif !defined(EVENT__HAVE_UNSETENV) && defined(EVENT__HAVE_PUTENV) -static void unsetenv(const char *k) -{ - char b[256]; - evutil_snprintf(b, sizeof(b), "%s=",k); - putenv(b); -} -#define UNSETENV_OK -#endif - -#if defined(SETENV_OK) && defined(UNSETENV_OK) -static void -methodname_to_envvar(const char *mname, char *buf, size_t buflen) -{ - char *cp; - evutil_snprintf(buf, buflen, "EVENT_NO%s", mname); - for (cp = buf; *cp; ++cp) { - *cp = EVUTIL_TOUPPER_(*cp); - } -} -#endif - -static void -test_base_environ(void *arg) -{ - struct event_base *base = NULL; - struct event_config *cfg = NULL; - -#if defined(SETENV_OK) && defined(UNSETENV_OK) - const char **basenames; - int i, n_methods=0; - char varbuf[128]; - const char *defaultname, *ignoreenvname; - - /* See if unsetenv works before we rely on it. */ - setenv("EVENT_NOWAFFLES", "1", 1); - unsetenv("EVENT_NOWAFFLES"); - if (getenv("EVENT_NOWAFFLES") != NULL) { -#ifndef EVENT__HAVE_UNSETENV - TT_DECLARE("NOTE", ("Can't fake unsetenv; skipping test")); -#else - TT_DECLARE("NOTE", ("unsetenv doesn't work; skipping test")); -#endif - tt_skip(); - } - - basenames = event_get_supported_methods(); - for (i = 0; basenames[i]; ++i) { - methodname_to_envvar(basenames[i], varbuf, sizeof(varbuf)); - unsetenv(varbuf); - ++n_methods; - } - - base = event_base_new(); - tt_assert(base); - - defaultname = event_base_get_method(base); - TT_BLATHER(("default is <%s>", defaultname)); - event_base_free(base); - base = NULL; - - /* Can we disable the method with EVENT_NOfoo ? */ - if (!strcmp(defaultname, "epoll (with changelist)")) { - setenv("EVENT_NOEPOLL", "1", 1); - ignoreenvname = "epoll"; - } else { - methodname_to_envvar(defaultname, varbuf, sizeof(varbuf)); - setenv(varbuf, "1", 1); - ignoreenvname = defaultname; - } - - /* Use an empty cfg rather than NULL so a failure doesn't exit() */ - cfg = event_config_new(); - base = event_base_new_with_config(cfg); - event_config_free(cfg); - cfg = NULL; - if (n_methods == 1) { - tt_assert(!base); - } else { - tt_assert(base); - tt_str_op(defaultname, !=, event_base_get_method(base)); - event_base_free(base); - base = NULL; - } - - /* Can we disable looking at the environment with IGNORE_ENV ? */ - cfg = event_config_new(); - event_config_set_flag(cfg, EVENT_BASE_FLAG_IGNORE_ENV); - base = event_base_new_with_config(cfg); - tt_assert(base); - tt_str_op(ignoreenvname, ==, event_base_get_method(base)); -#else - tt_skip(); -#endif - -end: - if (base) - event_base_free(base); - if (cfg) - event_config_free(cfg); -} - -static void -read_called_once_cb(evutil_socket_t fd, short event, void *arg) -{ - tt_int_op(event, ==, EV_READ); - called += 1; -end: - ; -} - -static void -timeout_called_once_cb(evutil_socket_t fd, short event, void *arg) -{ - tt_int_op(event, ==, EV_TIMEOUT); - called += 100; -end: - ; -} - -static void -immediate_called_twice_cb(evutil_socket_t fd, short event, void *arg) -{ - tt_int_op(event, ==, EV_TIMEOUT); - called += 1000; -end: - ; -} - -static void -test_event_once(void *ptr) -{ - struct basic_test_data *data = ptr; - struct timeval tv; - int r; - - tv.tv_sec = 0; - tv.tv_usec = 50*1000; - called = 0; - r = event_base_once(data->base, data->pair[0], EV_READ, - read_called_once_cb, NULL, NULL); - tt_int_op(r, ==, 0); - r = event_base_once(data->base, -1, EV_TIMEOUT, - timeout_called_once_cb, NULL, &tv); - tt_int_op(r, ==, 0); - r = event_base_once(data->base, -1, 0, NULL, NULL, NULL); - tt_int_op(r, <, 0); - r = event_base_once(data->base, -1, EV_TIMEOUT, - immediate_called_twice_cb, NULL, NULL); - tt_int_op(r, ==, 0); - tv.tv_sec = 0; - tv.tv_usec = 0; - r = event_base_once(data->base, -1, EV_TIMEOUT, - immediate_called_twice_cb, NULL, &tv); - tt_int_op(r, ==, 0); - - if (write(data->pair[1], TEST1, strlen(TEST1)+1) < 0) { - tt_fail_perror("write"); - } - - shutdown(data->pair[1], SHUT_WR); - - event_base_dispatch(data->base); - - tt_int_op(called, ==, 2101); -end: - ; -} - -static void -test_event_once_never(void *ptr) -{ - struct basic_test_data *data = ptr; - struct timeval tv; - - /* Have one trigger in 10 seconds (don't worry, because) */ - tv.tv_sec = 10; - tv.tv_usec = 0; - called = 0; - event_base_once(data->base, -1, EV_TIMEOUT, - timeout_called_once_cb, NULL, &tv); - - /* But shut down the base in 75 msec. */ - tv.tv_sec = 0; - tv.tv_usec = 75*1000; - event_base_loopexit(data->base, &tv); - - event_base_dispatch(data->base); - - tt_int_op(called, ==, 0); -end: - ; -} - -static void -test_event_pending(void *ptr) -{ - struct basic_test_data *data = ptr; - struct event *r=NULL, *w=NULL, *t=NULL; - struct timeval tv, now, tv2; - - tv.tv_sec = 0; - tv.tv_usec = 500 * 1000; - r = event_new(data->base, data->pair[0], EV_READ, simple_read_cb, - NULL); - w = event_new(data->base, data->pair[1], EV_WRITE, simple_write_cb, - NULL); - t = evtimer_new(data->base, timeout_cb, NULL); - - tt_assert(r); - tt_assert(w); - tt_assert(t); - - evutil_gettimeofday(&now, NULL); - event_add(r, NULL); - event_add(t, &tv); - - tt_assert( event_pending(r, EV_READ, NULL)); - tt_assert(!event_pending(w, EV_WRITE, NULL)); - tt_assert(!event_pending(r, EV_WRITE, NULL)); - tt_assert( event_pending(r, EV_READ|EV_WRITE, NULL)); - tt_assert(!event_pending(r, EV_TIMEOUT, NULL)); - tt_assert( event_pending(t, EV_TIMEOUT, NULL)); - tt_assert( event_pending(t, EV_TIMEOUT, &tv2)); - - tt_assert(evutil_timercmp(&tv2, &now, >)); - - test_timeval_diff_eq(&now, &tv2, 500); - -end: - if (r) { - event_del(r); - event_free(r); - } - if (w) { - event_del(w); - event_free(w); - } - if (t) { - event_del(t); - event_free(t); - } -} - -#ifndef _WIN32 -/* You can't do this test on windows, since dup2 doesn't work on sockets */ - -static void -dfd_cb(evutil_socket_t fd, short e, void *data) -{ - *(int*)data = (int)e; -} - -/* Regression test for our workaround for a fun epoll/linux related bug - * where fd2 = dup(fd1); add(fd2); close(fd2); dup2(fd1,fd2); add(fd2) - * will get you an EEXIST */ -static void -test_dup_fd(void *arg) -{ - struct basic_test_data *data = arg; - struct event_base *base = data->base; - struct event *ev1=NULL, *ev2=NULL; - int fd, dfd=-1; - int ev1_got, ev2_got; - - tt_int_op(write(data->pair[0], "Hello world", - strlen("Hello world")), >, 0); - fd = data->pair[1]; - - dfd = dup(fd); - tt_int_op(dfd, >=, 0); - - ev1 = event_new(base, fd, EV_READ|EV_PERSIST, dfd_cb, &ev1_got); - ev2 = event_new(base, dfd, EV_READ|EV_PERSIST, dfd_cb, &ev2_got); - ev1_got = ev2_got = 0; - event_add(ev1, NULL); - event_add(ev2, NULL); - event_base_loop(base, EVLOOP_ONCE); - tt_int_op(ev1_got, ==, EV_READ); - tt_int_op(ev2_got, ==, EV_READ); - - /* Now close and delete dfd then dispatch. We need to do the - * dispatch here so that when we add it later, we think there - * was an intermediate delete. */ - close(dfd); - event_del(ev2); - ev1_got = ev2_got = 0; - event_base_loop(base, EVLOOP_ONCE); - tt_want_int_op(ev1_got, ==, EV_READ); - tt_int_op(ev2_got, ==, 0); - - /* Re-duplicate the fd. We need to get the same duplicated - * value that we closed to provoke the epoll quirk. Also, we - * need to change the events to write, or else the old lingering - * read event will make the test pass whether the change was - * successful or not. */ - tt_int_op(dup2(fd, dfd), ==, dfd); - event_free(ev2); - ev2 = event_new(base, dfd, EV_WRITE|EV_PERSIST, dfd_cb, &ev2_got); - event_add(ev2, NULL); - ev1_got = ev2_got = 0; - event_base_loop(base, EVLOOP_ONCE); - tt_want_int_op(ev1_got, ==, EV_READ); - tt_int_op(ev2_got, ==, EV_WRITE); - -end: - if (ev1) - event_free(ev1); - if (ev2) - event_free(ev2); - if (dfd >= 0) - close(dfd); -} -#endif - -#ifdef EVENT__DISABLE_MM_REPLACEMENT -static void -test_mm_functions(void *arg) -{ - tinytest_set_test_skipped_(); -} -#else -static int -check_dummy_mem_ok(void *mem_) -{ - char *mem = mem_; - mem -= 16; - return !memcmp(mem, "{[<guardedram>]}", 16); -} - -static void * -dummy_malloc(size_t len) -{ - char *mem = malloc(len+16); - memcpy(mem, "{[<guardedram>]}", 16); - return mem+16; -} - -static void * -dummy_realloc(void *mem_, size_t len) -{ - char *mem = mem_; - if (!mem) - return dummy_malloc(len); - tt_want(check_dummy_mem_ok(mem_)); - mem -= 16; - mem = realloc(mem, len+16); - return mem+16; -} - -static void -dummy_free(void *mem_) -{ - char *mem = mem_; - tt_want(check_dummy_mem_ok(mem_)); - mem -= 16; - free(mem); -} - -static void -test_mm_functions(void *arg) -{ - struct event_base *b = NULL; - struct event_config *cfg = NULL; - event_set_mem_functions(dummy_malloc, dummy_realloc, dummy_free); - cfg = event_config_new(); - event_config_avoid_method(cfg, "Nonesuch"); - b = event_base_new_with_config(cfg); - tt_assert(b); - tt_assert(check_dummy_mem_ok(b)); -end: - if (cfg) - event_config_free(cfg); - if (b) - event_base_free(b); -} -#endif - -static void -many_event_cb(evutil_socket_t fd, short event, void *arg) -{ - int *calledp = arg; - *calledp += 1; -} - -static void -test_many_events(void *arg) -{ - /* Try 70 events that should all be ready at once. This will - * exercise the "resize" code on most of the backends, and will make - * sure that we can get past the 64-handle limit of some windows - * functions. */ -#define MANY 70 - - struct basic_test_data *data = arg; - struct event_base *base = data->base; - int one_at_a_time = data->setup_data != NULL; - evutil_socket_t sock[MANY]; - struct event *ev[MANY]; - int called[MANY]; - int i; - int loopflags = EVLOOP_NONBLOCK, evflags=0; - if (one_at_a_time) { - loopflags |= EVLOOP_ONCE; - evflags = EV_PERSIST; - } - - memset(sock, 0xff, sizeof(sock)); - memset(ev, 0, sizeof(ev)); - memset(called, 0, sizeof(called)); - - for (i = 0; i < MANY; ++i) { - /* We need an event that will hit the backend, and that will - * be ready immediately. "Send a datagram" is an easy - * instance of that. */ - sock[i] = socket(AF_INET, SOCK_DGRAM, 0); - tt_assert(sock[i] >= 0); - called[i] = 0; - ev[i] = event_new(base, sock[i], EV_WRITE|evflags, - many_event_cb, &called[i]); - event_add(ev[i], NULL); - if (one_at_a_time) - event_base_loop(base, EVLOOP_NONBLOCK|EVLOOP_ONCE); - } - - event_base_loop(base, loopflags); - - for (i = 0; i < MANY; ++i) { - if (one_at_a_time) - tt_int_op(called[i], ==, MANY - i + 1); - else - tt_int_op(called[i], ==, 1); - } - -end: - for (i = 0; i < MANY; ++i) { - if (ev[i]) - event_free(ev[i]); - if (sock[i] >= 0) - evutil_closesocket(sock[i]); - } -#undef MANY -} - -static void -test_struct_event_size(void *arg) -{ - tt_int_op(event_get_struct_event_size(), <=, sizeof(struct event)); -end: - ; -} - -static void -test_get_assignment(void *arg) -{ - struct basic_test_data *data = arg; - struct event_base *base = data->base; - struct event *ev1 = NULL; - const char *str = "foo"; - - struct event_base *b; - evutil_socket_t s; - short what; - event_callback_fn cb; - void *cb_arg; - - ev1 = event_new(base, data->pair[1], EV_READ, dummy_read_cb, (void*)str); - event_get_assignment(ev1, &b, &s, &what, &cb, &cb_arg); - - tt_ptr_op(b, ==, base); - tt_int_op(s, ==, data->pair[1]); - tt_int_op(what, ==, EV_READ); - tt_ptr_op(cb, ==, dummy_read_cb); - tt_ptr_op(cb_arg, ==, str); - - /* Now make sure this doesn't crash. */ - event_get_assignment(ev1, NULL, NULL, NULL, NULL, NULL); - -end: - if (ev1) - event_free(ev1); -} - -struct foreach_helper { - int count; - const struct event *ev; -}; - -static int -foreach_count_cb(const struct event_base *base, const struct event *ev, void *arg) -{ - struct foreach_helper *h = event_get_callback_arg(ev); - struct timeval *tv = arg; - if (event_get_callback(ev) != timeout_cb) - return 0; - tt_ptr_op(event_get_base(ev), ==, base); - tt_int_op(tv->tv_sec, ==, 10); - h->ev = ev; - h->count++; - return 0; -end: - return -1; -} - -static int -foreach_find_cb(const struct event_base *base, const struct event *ev, void *arg) -{ - const struct event **ev_out = arg; - struct foreach_helper *h = event_get_callback_arg(ev); - if (event_get_callback(ev) != timeout_cb) - return 0; - if (h->count == 99) { - *ev_out = ev; - return 101; - } - return 0; -} - -static void -test_event_foreach(void *arg) -{ - struct basic_test_data *data = arg; - struct event_base *base = data->base; - struct event *ev[5]; - struct foreach_helper visited[5]; - int i; - struct timeval ten_sec = {10,0}; - const struct event *ev_found = NULL; - - for (i = 0; i < 5; ++i) { - visited[i].count = 0; - visited[i].ev = NULL; - ev[i] = event_new(base, -1, 0, timeout_cb, &visited[i]); - } - - tt_int_op(-1, ==, event_base_foreach_event(NULL, foreach_count_cb, NULL)); - tt_int_op(-1, ==, event_base_foreach_event(base, NULL, NULL)); - - event_add(ev[0], &ten_sec); - event_add(ev[1], &ten_sec); - event_active(ev[1], EV_TIMEOUT, 1); - event_active(ev[2], EV_TIMEOUT, 1); - event_add(ev[3], &ten_sec); - /* Don't touch ev[4]. */ - - tt_int_op(0, ==, event_base_foreach_event(base, foreach_count_cb, - &ten_sec)); - tt_int_op(1, ==, visited[0].count); - tt_int_op(1, ==, visited[1].count); - tt_int_op(1, ==, visited[2].count); - tt_int_op(1, ==, visited[3].count); - tt_ptr_op(ev[0], ==, visited[0].ev); - tt_ptr_op(ev[1], ==, visited[1].ev); - tt_ptr_op(ev[2], ==, visited[2].ev); - tt_ptr_op(ev[3], ==, visited[3].ev); - - visited[2].count = 99; - tt_int_op(101, ==, event_base_foreach_event(base, foreach_find_cb, - &ev_found)); - tt_ptr_op(ev_found, ==, ev[2]); - -end: - for (i=0; i<5; ++i) { - event_free(ev[i]); - } -} - -static struct event_base *cached_time_base = NULL; -static int cached_time_reset = 0; -static int cached_time_sleep = 0; -static void -cache_time_cb(evutil_socket_t fd, short what, void *arg) -{ - struct timeval *tv = arg; - tt_int_op(0, ==, event_base_gettimeofday_cached(cached_time_base, tv)); - if (cached_time_sleep) { - struct timeval delay = { 0, 30*1000 }; - evutil_usleep_(&delay); - } - if (cached_time_reset) { - event_base_update_cache_time(cached_time_base); - } -end: - ; -} - -static void -test_gettimeofday_cached(void *arg) -{ - struct basic_test_data *data = arg; - struct event_config *cfg = NULL; - struct event_base *base = NULL; - struct timeval tv1, tv2, tv3, now; - struct event *ev1=NULL, *ev2=NULL, *ev3=NULL; - int cached_time_disable = strstr(data->setup_data, "disable") != NULL; - - cfg = event_config_new(); - if (cached_time_disable) { - event_config_set_flag(cfg, EVENT_BASE_FLAG_NO_CACHE_TIME); - } - cached_time_base = base = event_base_new_with_config(cfg); - tt_assert(base); - - /* Try gettimeofday_cached outside of an event loop. */ - evutil_gettimeofday(&now, NULL); - tt_int_op(0, ==, event_base_gettimeofday_cached(NULL, &tv1)); - tt_int_op(0, ==, event_base_gettimeofday_cached(base, &tv2)); - tt_int_op(timeval_msec_diff(&tv1, &tv2), <, 10); - tt_int_op(timeval_msec_diff(&tv1, &now), <, 10); - - cached_time_reset = strstr(data->setup_data, "reset") != NULL; - cached_time_sleep = strstr(data->setup_data, "sleep") != NULL; - - ev1 = event_new(base, -1, 0, cache_time_cb, &tv1); - ev2 = event_new(base, -1, 0, cache_time_cb, &tv2); - ev3 = event_new(base, -1, 0, cache_time_cb, &tv3); - - event_active(ev1, EV_TIMEOUT, 1); - event_active(ev2, EV_TIMEOUT, 1); - event_active(ev3, EV_TIMEOUT, 1); - - event_base_dispatch(base); - - if (cached_time_reset && cached_time_sleep) { - tt_int_op(labs(timeval_msec_diff(&tv1,&tv2)), >, 10); - tt_int_op(labs(timeval_msec_diff(&tv2,&tv3)), >, 10); - } else if (cached_time_disable && cached_time_sleep) { - tt_int_op(labs(timeval_msec_diff(&tv1,&tv2)), >, 10); - tt_int_op(labs(timeval_msec_diff(&tv2,&tv3)), >, 10); - } else if (! cached_time_disable) { - tt_assert(evutil_timercmp(&tv1, &tv2, ==)); - tt_assert(evutil_timercmp(&tv2, &tv3, ==)); - } - -end: - if (ev1) - event_free(ev1); - if (ev2) - event_free(ev2); - if (ev3) - event_free(ev3); - if (base) - event_base_free(base); - if (cfg) - event_config_free(cfg); -} - -static void -tabf_cb(evutil_socket_t fd, short what, void *arg) -{ - int *ptr = arg; - *ptr = what; - *ptr += 0x10000; -} - -static void -test_active_by_fd(void *arg) -{ - struct basic_test_data *data = arg; - struct event_base *base = data->base; - struct event *ev1 = NULL, *ev2 = NULL, *ev3 = NULL, *ev4 = NULL; - int e1,e2,e3,e4; -#ifndef _WIN32 - struct event *evsig = NULL; - int es; -#endif - struct timeval tenmin = { 600, 0 }; - - /* Ensure no crash on nonexistent FD. */ - event_base_active_by_fd(base, 1000, EV_READ); - - /* Ensure no crash on bogus FD. */ - event_base_active_by_fd(base, -1, EV_READ); - - /* Ensure no crash on nonexistent/bogus signal. */ - event_base_active_by_signal(base, 1000); - event_base_active_by_signal(base, -1); - - event_base_assert_ok_(base); - - e1 = e2 = e3 = e4 = 0; - ev1 = event_new(base, data->pair[0], EV_READ, tabf_cb, &e1); - ev2 = event_new(base, data->pair[0], EV_WRITE, tabf_cb, &e2); - ev3 = event_new(base, data->pair[1], EV_READ, tabf_cb, &e3); - ev4 = event_new(base, data->pair[1], EV_READ, tabf_cb, &e4); - tt_assert(ev1); - tt_assert(ev2); - tt_assert(ev3); - tt_assert(ev4); -#ifndef _WIN32 - evsig = event_new(base, SIGHUP, EV_SIGNAL, tabf_cb, &es); - tt_assert(evsig); - event_add(evsig, &tenmin); -#endif - - event_add(ev1, &tenmin); - event_add(ev2, NULL); - event_add(ev3, NULL); - event_add(ev4, &tenmin); - - - event_base_assert_ok_(base); - - /* Trigger 2, 3, 4 */ - event_base_active_by_fd(base, data->pair[0], EV_WRITE); - event_base_active_by_fd(base, data->pair[1], EV_READ); -#ifndef _WIN32 - event_base_active_by_signal(base, SIGHUP); -#endif - - event_base_assert_ok_(base); - - event_base_loop(base, EVLOOP_ONCE); - - tt_int_op(e1, ==, 0); - tt_int_op(e2, ==, EV_WRITE | 0x10000); - tt_int_op(e3, ==, EV_READ | 0x10000); - /* Mask out EV_WRITE here, since it could be genuinely writeable. */ - tt_int_op((e4 & ~EV_WRITE), ==, EV_READ | 0x10000); -#ifndef _WIN32 - tt_int_op(es, ==, EV_SIGNAL | 0x10000); -#endif - -end: - if (ev1) - event_free(ev1); - if (ev2) - event_free(ev2); - if (ev3) - event_free(ev3); - if (ev4) - event_free(ev4); -#ifndef _WIN32 - if (evsig) - event_free(evsig); -#endif -} - -struct testcase_t main_testcases[] = { - /* Some converted-over tests */ - { "methods", test_methods, TT_FORK, NULL, NULL }, - { "version", test_version, 0, NULL, NULL }, - BASIC(base_features, TT_FORK|TT_NO_LOGS), - { "base_environ", test_base_environ, TT_FORK, NULL, NULL }, - - BASIC(event_base_new, TT_FORK|TT_NEED_SOCKETPAIR), - BASIC(free_active_base, TT_FORK|TT_NEED_SOCKETPAIR), - - BASIC(manipulate_active_events, TT_FORK|TT_NEED_BASE), - BASIC(event_new_selfarg, TT_FORK|TT_NEED_BASE), - BASIC(event_assign_selfarg, TT_FORK|TT_NEED_BASE), - BASIC(event_base_get_num_events, TT_FORK|TT_NEED_BASE), - BASIC(event_base_get_max_events, TT_FORK|TT_NEED_BASE), - - 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(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 }, - 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, - &basic_setup, NULL }, - - /* These legacy tests may not all need all of these flags. */ - LEGACY(simpleread, TT_ISOLATED), - LEGACY(simpleread_multiple, TT_ISOLATED), - LEGACY(simplewrite, TT_ISOLATED), - { "simpleclose", test_simpleclose, TT_FORK, &basic_setup, - NULL }, - LEGACY(multiple, TT_ISOLATED), - LEGACY(persistent, TT_ISOLATED), - LEGACY(combined, TT_ISOLATED), - LEGACY(simpletimeout, TT_ISOLATED), - LEGACY(loopbreak, TT_ISOLATED), - LEGACY(loopexit, TT_ISOLATED), - LEGACY(loopexit_multiple, TT_ISOLATED), - LEGACY(nonpersist_readd, TT_ISOLATED), - LEGACY(multiple_events_for_same_fd, TT_ISOLATED), - LEGACY(want_only_once, TT_ISOLATED), - { "event_once", test_event_once, TT_ISOLATED, &basic_setup, NULL }, - { "event_once_never", test_event_once_never, TT_ISOLATED, &basic_setup, NULL }, - { "event_pending", test_event_pending, TT_ISOLATED, &basic_setup, - NULL }, -#ifndef _WIN32 - { "dup_fd", test_dup_fd, TT_ISOLATED, &basic_setup, NULL }, -#endif - { "mm_functions", test_mm_functions, TT_FORK, NULL, NULL }, - { "many_events", test_many_events, TT_ISOLATED, &basic_setup, NULL }, - { "many_events_slow_add", test_many_events, TT_ISOLATED, &basic_setup, (void*)1 }, - - { "struct_event_size", test_struct_event_size, 0, NULL, NULL }, - BASIC(get_assignment, TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR), - - BASIC(event_foreach, TT_FORK|TT_NEED_BASE), - { "gettimeofday_cached", test_gettimeofday_cached, TT_FORK, &basic_setup, (void*)"" }, - { "gettimeofday_cached_sleep", test_gettimeofday_cached, TT_FORK, &basic_setup, (void*)"sleep" }, - { "gettimeofday_cached_reset", test_gettimeofday_cached, TT_FORK, &basic_setup, (void*)"sleep reset" }, - { "gettimeofday_cached_disabled", test_gettimeofday_cached, TT_FORK, &basic_setup, (void*)"sleep disable" }, - { "gettimeofday_cached_disabled_nosleep", test_gettimeofday_cached, TT_FORK, &basic_setup, (void*)"disable" }, - - BASIC(active_by_fd, TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR), - -#ifndef _WIN32 - LEGACY(fork, TT_ISOLATED), -#endif -#ifdef EVENT__HAVE_PTHREADS - /** TODO: support win32 */ - LEGACY(del_wait, TT_ISOLATED|TT_NEED_THREADS), -#endif - - END_OF_TESTCASES -}; - -struct testcase_t evtag_testcases[] = { - { "int", evtag_int_test, TT_FORK, NULL, NULL }, - { "fuzz", evtag_fuzz, TT_FORK, NULL, NULL }, - { "encoding", evtag_tag_encoding, TT_FORK, NULL, NULL }, - { "peek", evtag_test_peek, 0, NULL, NULL }, - - END_OF_TESTCASES -}; - -struct testcase_t signal_testcases[] = { -#ifndef _WIN32 - LEGACY(simplestsignal, TT_ISOLATED), - LEGACY(simplesignal, TT_ISOLATED), - LEGACY(multiplesignal, TT_ISOLATED), - LEGACY(immediatesignal, TT_ISOLATED), - LEGACY(signal_dealloc, TT_ISOLATED), - LEGACY(signal_pipeloss, TT_ISOLATED), - LEGACY(signal_switchbase, TT_ISOLATED|TT_NO_LOGS), - LEGACY(signal_restore, TT_ISOLATED), - LEGACY(signal_assert, TT_ISOLATED), - LEGACY(signal_while_processing, TT_ISOLATED), -#endif - END_OF_TESTCASES -}; - diff --git a/protocols/Telegram/tgl/libevent/test/regress.exe b/protocols/Telegram/tgl/libevent/test/regress.exe Binary files differdeleted file mode 100644 index 651b62c564..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress.exe +++ /dev/null diff --git a/protocols/Telegram/tgl/libevent/test/regress.gen.c b/protocols/Telegram/tgl/libevent/test/regress.gen.c deleted file mode 100644 index 2cf8925e9a..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress.gen.c +++ /dev/null @@ -1 +0,0 @@ -//
diff --git a/protocols/Telegram/tgl/libevent/test/regress.gen.h b/protocols/Telegram/tgl/libevent/test/regress.gen.h deleted file mode 100644 index 4578e5f7f3..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress.gen.h +++ /dev/null @@ -1 +0,0 @@ -#define NO_PYTHON_EXISTS
diff --git a/protocols/Telegram/tgl/libevent/test/regress.gen.obj b/protocols/Telegram/tgl/libevent/test/regress.gen.obj Binary files differdeleted file mode 100644 index ba20c4cca8..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress.gen.obj +++ /dev/null diff --git a/protocols/Telegram/tgl/libevent/test/regress.h b/protocols/Telegram/tgl/libevent/test/regress.h deleted file mode 100644 index de1aed3089..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (c) 2000-2007 Niels Provos <provos@citi.umich.edu> - * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef REGRESS_H_INCLUDED_ -#define REGRESS_H_INCLUDED_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "tinytest.h" -#include "tinytest_macros.h" - -extern struct testcase_t main_testcases[]; -extern struct testcase_t evtag_testcases[]; -extern struct testcase_t evbuffer_testcases[]; -extern struct testcase_t finalize_testcases[]; -extern struct testcase_t bufferevent_testcases[]; -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 dns_testcases[]; -extern struct testcase_t rpc_testcases[]; -extern struct testcase_t edgetriggered_testcases[]; -extern struct testcase_t minheap_testcases[]; -extern struct testcase_t iocp_testcases[]; -extern struct testcase_t ssl_testcases[]; -extern struct testcase_t listener_testcases[]; -extern struct testcase_t listener_iocp_testcases[]; -extern struct testcase_t thread_testcases[]; - -extern struct evutil_weakrand_state test_weakrand_state; - -#define test_weakrand() (evutil_weakrand_(&test_weakrand_state)) - -void regress_threads(void *); -void test_bufferevent_zlib(void *); - -/* Helpers to wrap old testcases */ -extern evutil_socket_t pair[2]; -extern int test_ok; -extern int called; -extern struct event_base *global_base; -extern int in_legacy_test_wrapper; - -int regress_make_tmpfile(const void *data, size_t datalen, char **filename_out); - -struct basic_test_data { - struct event_base *base; - evutil_socket_t pair[2]; - - void (*legacy_test_fn)(void); - - void *setup_data; -}; -extern const struct testcase_setup_t basic_setup; - - -extern const struct testcase_setup_t legacy_setup; -void run_legacy_test_fn(void *ptr); - -extern int libevent_tests_running_in_debug_mode; - -/* A couple of flags that basic/legacy_setup can support. */ -#define TT_NEED_SOCKETPAIR TT_FIRST_USER_FLAG -#define TT_NEED_BASE (TT_FIRST_USER_FLAG<<1) -#define TT_NEED_DNS (TT_FIRST_USER_FLAG<<2) -#define TT_LEGACY (TT_FIRST_USER_FLAG<<3) -#define TT_NEED_THREADS (TT_FIRST_USER_FLAG<<4) -#define TT_NO_LOGS (TT_FIRST_USER_FLAG<<5) -#define TT_ENABLE_IOCP_FLAG (TT_FIRST_USER_FLAG<<6) -#define TT_ENABLE_IOCP (TT_ENABLE_IOCP_FLAG|TT_NEED_THREADS) - -/* All the flags that a legacy test needs. */ -#define TT_ISOLATED TT_FORK|TT_NEED_SOCKETPAIR|TT_NEED_BASE - - -#define BASIC(name,flags) \ - { #name, test_## name, flags, &basic_setup, NULL } - -#define LEGACY(name,flags) \ - { #name, run_legacy_test_fn, flags|TT_LEGACY, &legacy_setup, \ - test_## name } - -struct evutil_addrinfo; -struct evutil_addrinfo *ai_find_by_family(struct evutil_addrinfo *ai, int f); -struct evutil_addrinfo *ai_find_by_protocol(struct evutil_addrinfo *ai, int p); -int test_ai_eq_(const struct evutil_addrinfo *ai, const char *sockaddr_port, - int socktype, int protocol, int line); - -#define test_ai_eq(ai, str, s, p) do { \ - if (test_ai_eq_((ai), (str), (s), (p), __LINE__)<0) \ - goto end; \ - } while (0) - -#define test_timeval_diff_leq(tv1, tv2, diff, tolerance) \ - tt_int_op(labs(timeval_msec_diff((tv1), (tv2)) - diff), <=, tolerance) - -#define test_timeval_diff_eq(tv1, tv2, diff) \ - test_timeval_diff_leq((tv1), (tv2), (diff), 50) - -long timeval_msec_diff(const struct timeval *start, const struct timeval *end); - -#ifndef _WIN32 -pid_t regress_fork(void); -#endif - -#ifdef EVENT__HAVE_OPENSSL -#include <openssl/ssl.h> -EVP_PKEY *ssl_getkey(void); -X509 *ssl_getcert(void); -SSL_CTX *get_ssl_ctx(void); -void init_ssl(void); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* REGRESS_H_INCLUDED_ */ diff --git a/protocols/Telegram/tgl/libevent/test/regress.obj b/protocols/Telegram/tgl/libevent/test/regress.obj Binary files differdeleted file mode 100644 index b3832b8411..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress.obj +++ /dev/null diff --git a/protocols/Telegram/tgl/libevent/test/regress.rpc b/protocols/Telegram/tgl/libevent/test/regress.rpc deleted file mode 100644 index 0ee904e913..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress.rpc +++ /dev/null @@ -1,25 +0,0 @@ -/* tests data packing and unpacking */ - -struct msg { - string /* sender */ from_name = 1; /* be verbose */ - string to_name = 2; - optional struct[kill] attack = 3; - array struct[run] run = 4; -} - -struct kill { - string weapon = 0x10121; - string action = 2; - array int how_often = 3; -} - -struct run { - string how = 1; - optional bytes some_bytes = 2; - - bytes fixed_bytes[24] = 3; - array string notes = 4; - - optional int64 large_number = 5; - array int other_numbers = 6; -} diff --git a/protocols/Telegram/tgl/libevent/test/regress_buffer.c b/protocols/Telegram/tgl/libevent/test/regress_buffer.c deleted file mode 100644 index 957e59f178..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress_buffer.c +++ /dev/null @@ -1,2281 +0,0 @@ -/* - * Copyright (c) 2003-2007 Niels Provos <provos@citi.umich.edu> - * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "util-internal.h" - -#ifdef _WIN32 -#include <winsock2.h> -#include <windows.h> -#endif - -#include "event2/event-config.h" - -#include <sys/types.h> -#include <sys/stat.h> -#ifdef EVENT__HAVE_SYS_TIME_H -#include <sys/time.h> -#endif -#include <sys/queue.h> -#ifndef _WIN32 -#include <sys/socket.h> -#include <sys/wait.h> -#include <signal.h> -#include <unistd.h> -#include <netdb.h> -#endif -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#include "event2/event.h" -#include "event2/buffer.h" -#include "event2/buffer_compat.h" -#include "event2/util.h" - -#include "defer-internal.h" -#include "evbuffer-internal.h" -#include "log-internal.h" - -#include "regress.h" - -/* Validates that an evbuffer is good. Returns false if it isn't, true if it - * is*/ -static int -evbuffer_validate_(struct evbuffer *buf) -{ - struct evbuffer_chain *chain; - size_t sum = 0; - int found_last_with_datap = 0; - - if (buf->first == NULL) { - tt_assert(buf->last == NULL); - tt_assert(buf->total_len == 0); - } - - chain = buf->first; - - tt_assert(buf->last_with_datap); - if (buf->last_with_datap == &buf->first) - found_last_with_datap = 1; - - while (chain != NULL) { - if (&chain->next == buf->last_with_datap) - found_last_with_datap = 1; - sum += chain->off; - if (chain->next == NULL) { - tt_assert(buf->last == chain); - } - tt_assert(chain->buffer_len >= chain->misalign + chain->off); - chain = chain->next; - } - - if (buf->first) - tt_assert(*buf->last_with_datap); - - if (*buf->last_with_datap) { - chain = *buf->last_with_datap; - if (chain->off == 0 || buf->total_len == 0) { - tt_assert(chain->off == 0) - tt_assert(chain == buf->first); - tt_assert(buf->total_len == 0); - } - chain = chain->next; - while (chain != NULL) { - tt_assert(chain->off == 0); - chain = chain->next; - } - } else { - tt_assert(buf->last_with_datap == &buf->first); - } - tt_assert(found_last_with_datap); - - tt_assert(sum == buf->total_len); - return 1; - end: - return 0; -} - -static void -evbuffer_get_waste(struct evbuffer *buf, size_t *allocatedp, size_t *wastedp, size_t *usedp) -{ - struct evbuffer_chain *chain; - size_t a, w, u; - int n = 0; - u = a = w = 0; - - chain = buf->first; - /* skip empty at start */ - while (chain && chain->off==0) { - ++n; - a += chain->buffer_len; - chain = chain->next; - } - /* first nonempty chain: stuff at the end only is wasted. */ - if (chain) { - ++n; - a += chain->buffer_len; - u += chain->off; - if (chain->next && chain->next->off) - w += (size_t)(chain->buffer_len - (chain->misalign + chain->off)); - chain = chain->next; - } - /* subsequent nonempty chains */ - while (chain && chain->off) { - ++n; - a += chain->buffer_len; - w += (size_t)chain->misalign; - u += chain->off; - if (chain->next && chain->next->off) - w += (size_t) (chain->buffer_len - (chain->misalign + chain->off)); - chain = chain->next; - } - /* subsequent empty chains */ - while (chain) { - ++n; - a += chain->buffer_len; - } - *allocatedp = a; - *wastedp = w; - *usedp = u; -} - -#define evbuffer_validate(buf) \ - TT_STMT_BEGIN if (!evbuffer_validate_(buf)) TT_DIE(("Buffer format invalid")); TT_STMT_END - -static void -test_evbuffer(void *ptr) -{ - static char buffer[512], *tmp; - struct evbuffer *evb = evbuffer_new(); - struct evbuffer *evb_two = evbuffer_new(); - size_t sz_tmp; - int i; - - evbuffer_validate(evb); - evbuffer_add_printf(evb, "%s/%d", "hello", 1); - evbuffer_validate(evb); - - tt_assert(evbuffer_get_length(evb) == 7); - tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "hello/1", 1)); - - evbuffer_add_buffer(evb, evb_two); - evbuffer_validate(evb); - - evbuffer_drain(evb, strlen("hello/")); - evbuffer_validate(evb); - tt_assert(evbuffer_get_length(evb) == 1); - tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "1", 1)); - - evbuffer_add_printf(evb_two, "%s", "/hello"); - evbuffer_validate(evb); - evbuffer_add_buffer(evb, evb_two); - evbuffer_validate(evb); - - tt_assert(evbuffer_get_length(evb_two) == 0); - tt_assert(evbuffer_get_length(evb) == 7); - tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "1/hello", 7)); - - memset(buffer, 0, sizeof(buffer)); - evbuffer_add(evb, buffer, sizeof(buffer)); - evbuffer_validate(evb); - tt_assert(evbuffer_get_length(evb) == 7 + 512); - - tmp = (char *)evbuffer_pullup(evb, 7 + 512); - tt_assert(tmp); - tt_assert(!strncmp(tmp, "1/hello", 7)); - tt_assert(!memcmp(tmp + 7, buffer, sizeof(buffer))); - evbuffer_validate(evb); - - evbuffer_prepend(evb, "something", 9); - evbuffer_validate(evb); - evbuffer_prepend(evb, "else", 4); - evbuffer_validate(evb); - - tmp = (char *)evbuffer_pullup(evb, 4 + 9 + 7); - tt_assert(!strncmp(tmp, "elsesomething1/hello", 4 + 9 + 7)); - evbuffer_validate(evb); - - evbuffer_drain(evb, -1); - evbuffer_validate(evb); - evbuffer_drain(evb_two, -1); - evbuffer_validate(evb); - - for (i = 0; i < 3; ++i) { - evbuffer_add(evb_two, buffer, sizeof(buffer)); - evbuffer_validate(evb_two); - evbuffer_add_buffer(evb, evb_two); - evbuffer_validate(evb); - evbuffer_validate(evb_two); - } - - tt_assert(evbuffer_get_length(evb_two) == 0); - tt_assert(evbuffer_get_length(evb) == i * sizeof(buffer)); - - /* test remove buffer */ - sz_tmp = (size_t)(sizeof(buffer)*2.5); - evbuffer_remove_buffer(evb, evb_two, sz_tmp); - tt_assert(evbuffer_get_length(evb_two) == sz_tmp); - tt_assert(evbuffer_get_length(evb) == sizeof(buffer) / 2); - evbuffer_validate(evb); - - if (memcmp(evbuffer_pullup( - evb, -1), buffer, sizeof(buffer) / 2) != 0 || - memcmp(evbuffer_pullup( - evb_two, -1), buffer, sizeof(buffer)) != 0) - tt_abort_msg("Pullup did not preserve content"); - - evbuffer_validate(evb); - - - /* testing one-vector reserve and commit */ - { - struct evbuffer_iovec v[1]; - char *buf; - int i, j, r; - - for (i = 0; i < 3; ++i) { - r = evbuffer_reserve_space(evb, 10000, v, 1); - tt_int_op(r, ==, 1); - tt_assert(v[0].iov_len >= 10000); - tt_assert(v[0].iov_base != NULL); - - evbuffer_validate(evb); - buf = v[0].iov_base; - for (j = 0; j < 10000; ++j) { - buf[j] = j; - } - evbuffer_validate(evb); - - tt_int_op(evbuffer_commit_space(evb, v, 1), ==, 0); - evbuffer_validate(evb); - - tt_assert(evbuffer_get_length(evb) >= 10000); - - evbuffer_drain(evb, j * 5000); - evbuffer_validate(evb); - } - } - - end: - evbuffer_free(evb); - evbuffer_free(evb_two); -} - -static void -no_cleanup(const void *data, size_t datalen, void *extra) -{ -} - -static void -test_evbuffer_remove_buffer_with_empty(void *ptr) -{ - struct evbuffer *src = evbuffer_new(); - struct evbuffer *dst = evbuffer_new(); - char buf[2]; - - evbuffer_validate(src); - evbuffer_validate(dst); - - /* setup the buffers */ - /* we need more data in src than we will move later */ - evbuffer_add_reference(src, buf, sizeof(buf), no_cleanup, NULL); - evbuffer_add_reference(src, buf, sizeof(buf), no_cleanup, NULL); - /* we need one buffer in dst and one empty buffer at the end */ - evbuffer_add(dst, buf, sizeof(buf)); - evbuffer_add_reference(dst, buf, 0, no_cleanup, NULL); - - evbuffer_validate(src); - evbuffer_validate(dst); - - /* move three bytes over */ - evbuffer_remove_buffer(src, dst, 3); - - evbuffer_validate(src); - evbuffer_validate(dst); - -end: - evbuffer_free(src); - evbuffer_free(dst); -} - -static void -test_evbuffer_reserve2(void *ptr) -{ - /* Test the two-vector cases of reserve/commit. */ - struct evbuffer *buf = evbuffer_new(); - int n, i; - struct evbuffer_iovec v[2]; - size_t remaining; - char *cp, *cp2; - - /* First chunk will necessarily be one chunk. Use 512 bytes of it.*/ - n = evbuffer_reserve_space(buf, 1024, v, 2); - tt_int_op(n, ==, 1); - tt_int_op(evbuffer_get_length(buf), ==, 0); - tt_assert(v[0].iov_base != NULL); - tt_int_op(v[0].iov_len, >=, 1024); - memset(v[0].iov_base, 'X', 512); - cp = v[0].iov_base; - remaining = v[0].iov_len - 512; - v[0].iov_len = 512; - evbuffer_validate(buf); - tt_int_op(0, ==, evbuffer_commit_space(buf, v, 1)); - tt_int_op(evbuffer_get_length(buf), ==, 512); - evbuffer_validate(buf); - - /* Ask for another same-chunk request, in an existing chunk. Use 8 - * bytes of it. */ - n = evbuffer_reserve_space(buf, 32, v, 2); - tt_int_op(n, ==, 1); - tt_assert(cp + 512 == v[0].iov_base); - tt_int_op(remaining, ==, v[0].iov_len); - memset(v[0].iov_base, 'Y', 8); - v[0].iov_len = 8; - tt_int_op(0, ==, evbuffer_commit_space(buf, v, 1)); - tt_int_op(evbuffer_get_length(buf), ==, 520); - remaining -= 8; - evbuffer_validate(buf); - - /* Now ask for a request that will be split. Use only one byte of it, - though. */ - n = evbuffer_reserve_space(buf, remaining+64, v, 2); - tt_int_op(n, ==, 2); - tt_assert(cp + 520 == v[0].iov_base); - tt_int_op(remaining, ==, v[0].iov_len); - tt_assert(v[1].iov_base); - tt_assert(v[1].iov_len >= 64); - cp2 = v[1].iov_base; - memset(v[0].iov_base, 'Z', 1); - v[0].iov_len = 1; - tt_int_op(0, ==, evbuffer_commit_space(buf, v, 1)); - tt_int_op(evbuffer_get_length(buf), ==, 521); - remaining -= 1; - evbuffer_validate(buf); - - /* Now ask for a request that will be split. Use some of the first - * part and some of the second. */ - n = evbuffer_reserve_space(buf, remaining+64, v, 2); - evbuffer_validate(buf); - tt_int_op(n, ==, 2); - tt_assert(cp + 521 == v[0].iov_base); - tt_int_op(remaining, ==, v[0].iov_len); - tt_assert(v[1].iov_base == cp2); - tt_assert(v[1].iov_len >= 64); - memset(v[0].iov_base, 'W', 400); - v[0].iov_len = 400; - memset(v[1].iov_base, 'x', 60); - v[1].iov_len = 60; - tt_int_op(0, ==, evbuffer_commit_space(buf, v, 2)); - tt_int_op(evbuffer_get_length(buf), ==, 981); - evbuffer_validate(buf); - - /* Now peek to make sure stuff got made how we like. */ - memset(v,0,sizeof(v)); - n = evbuffer_peek(buf, -1, NULL, v, 2); - tt_int_op(n, ==, 2); - tt_int_op(v[0].iov_len, ==, 921); - tt_int_op(v[1].iov_len, ==, 60); - - cp = v[0].iov_base; - for (i=0; i<512; ++i) - tt_int_op(cp[i], ==, 'X'); - for (i=512; i<520; ++i) - tt_int_op(cp[i], ==, 'Y'); - for (i=520; i<521; ++i) - tt_int_op(cp[i], ==, 'Z'); - for (i=521; i<921; ++i) - tt_int_op(cp[i], ==, 'W'); - - cp = v[1].iov_base; - for (i=0; i<60; ++i) - tt_int_op(cp[i], ==, 'x'); - -end: - evbuffer_free(buf); -} - -static void -test_evbuffer_reserve_many(void *ptr) -{ - /* This is a glass-box test to handle expanding a buffer with more - * chunks and reallocating chunks as needed */ - struct evbuffer *buf = evbuffer_new(); - struct evbuffer_iovec v[8]; - int n; - size_t sz; - int add_data = ptr && !strcmp(ptr, "add"); - int fill_first = ptr && !strcmp(ptr, "fill"); - char *cp1, *cp2; - - /* When reserving the the first chunk, we just allocate it */ - n = evbuffer_reserve_space(buf, 128, v, 2); - evbuffer_validate(buf); - tt_int_op(n, ==, 1); - tt_assert(v[0].iov_len >= 128); - sz = v[0].iov_len; - cp1 = v[0].iov_base; - if (add_data) { - *(char*)v[0].iov_base = 'X'; - v[0].iov_len = 1; - n = evbuffer_commit_space(buf, v, 1); - tt_int_op(n, ==, 0); - } else if (fill_first) { - memset(v[0].iov_base, 'X', v[0].iov_len); - n = evbuffer_commit_space(buf, v, 1); - tt_int_op(n, ==, 0); - n = evbuffer_reserve_space(buf, 128, v, 2); - tt_int_op(n, ==, 1); - sz = v[0].iov_len; - tt_assert(v[0].iov_base != cp1); - cp1 = v[0].iov_base; - } - - /* Make another chunk get added. */ - n = evbuffer_reserve_space(buf, sz+128, v, 2); - evbuffer_validate(buf); - tt_int_op(n, ==, 2); - sz = v[0].iov_len + v[1].iov_len; - tt_int_op(sz, >=, v[0].iov_len+128); - if (add_data) { - tt_assert(v[0].iov_base == cp1 + 1); - } else { - tt_assert(v[0].iov_base == cp1); - } - cp1 = v[0].iov_base; - cp2 = v[1].iov_base; - - /* And a third chunk. */ - n = evbuffer_reserve_space(buf, sz+128, v, 3); - evbuffer_validate(buf); - tt_int_op(n, ==, 3); - tt_assert(cp1 == v[0].iov_base); - tt_assert(cp2 == v[1].iov_base); - sz = v[0].iov_len + v[1].iov_len + v[2].iov_len; - - /* Now force a reallocation by asking for more space in only 2 - * buffers. */ - n = evbuffer_reserve_space(buf, sz+128, v, 2); - evbuffer_validate(buf); - if (add_data) { - tt_int_op(n, ==, 2); - tt_assert(cp1 == v[0].iov_base); - } else { - tt_int_op(n, ==, 1); - } - -end: - evbuffer_free(buf); -} - -static void -test_evbuffer_expand(void *ptr) -{ - char data[4096]; - struct evbuffer *buf; - size_t a,w,u; - void *buffer; - - memset(data, 'X', sizeof(data)); - - /* Make sure that expand() works on an empty buffer */ - buf = evbuffer_new(); - tt_int_op(evbuffer_expand(buf, 20000), ==, 0); - evbuffer_validate(buf); - a=w=u=0; - evbuffer_get_waste(buf, &a,&w,&u); - tt_assert(w == 0); - tt_assert(u == 0); - tt_assert(a >= 20000); - tt_assert(buf->first); - tt_assert(buf->first == buf->last); - tt_assert(buf->first->off == 0); - tt_assert(buf->first->buffer_len >= 20000); - - /* Make sure that expand() works as a no-op when there's enough - * contiguous space already. */ - buffer = buf->first->buffer; - evbuffer_add(buf, data, 1024); - tt_int_op(evbuffer_expand(buf, 1024), ==, 0); - tt_assert(buf->first->buffer == buffer); - evbuffer_validate(buf); - evbuffer_free(buf); - - /* Make sure that expand() can work by moving misaligned data - * when it makes sense to do so. */ - buf = evbuffer_new(); - evbuffer_add(buf, data, 400); - { - int n = (int)(buf->first->buffer_len - buf->first->off - 1); - tt_assert(n < (int)sizeof(data)); - evbuffer_add(buf, data, n); - } - tt_assert(buf->first == buf->last); - tt_assert(buf->first->off == buf->first->buffer_len - 1); - evbuffer_drain(buf, buf->first->off - 1); - tt_assert(1 == evbuffer_get_length(buf)); - tt_assert(buf->first->misalign > 0); - tt_assert(buf->first->off == 1); - buffer = buf->first->buffer; - tt_assert(evbuffer_expand(buf, 40) == 0); - tt_assert(buf->first == buf->last); - tt_assert(buf->first->off == 1); - tt_assert(buf->first->buffer == buffer); - tt_assert(buf->first->misalign == 0); - evbuffer_validate(buf); - evbuffer_free(buf); - - /* add, expand, pull-up: This used to crash libevent. */ - buf = evbuffer_new(); - - evbuffer_add(buf, data, sizeof(data)); - evbuffer_add(buf, data, sizeof(data)); - evbuffer_add(buf, data, sizeof(data)); - - evbuffer_validate(buf); - evbuffer_expand(buf, 1024); - evbuffer_validate(buf); - evbuffer_pullup(buf, -1); - evbuffer_validate(buf); - -end: - evbuffer_free(buf); -} - - -static int reference_cb_called; -static void -reference_cb(const void *data, size_t len, void *extra) -{ - tt_str_op(data, ==, "this is what we add as read-only memory."); - tt_int_op(len, ==, strlen(data)); - tt_want(extra == (void *)0xdeadaffe); - ++reference_cb_called; -end: - ; -} - -static void -test_evbuffer_reference(void *ptr) -{ - struct evbuffer *src = evbuffer_new(); - struct evbuffer *dst = evbuffer_new(); - struct evbuffer_iovec v[1]; - const char *data = "this is what we add as read-only memory."; - reference_cb_called = 0; - - tt_assert(evbuffer_add_reference(src, data, strlen(data), - reference_cb, (void *)0xdeadaffe) != -1); - - evbuffer_reserve_space(dst, strlen(data), v, 1); - tt_assert(evbuffer_remove(src, v[0].iov_base, 10) != -1); - - evbuffer_validate(src); - evbuffer_validate(dst); - - /* make sure that we don't write data at the beginning */ - evbuffer_prepend(src, "aaaaa", 5); - evbuffer_validate(src); - evbuffer_drain(src, 5); - - tt_assert(evbuffer_remove(src, ((char*)(v[0].iov_base)) + 10, - strlen(data) - 10) != -1); - - v[0].iov_len = strlen(data); - - evbuffer_commit_space(dst, v, 1); - evbuffer_validate(src); - evbuffer_validate(dst); - - tt_int_op(reference_cb_called, ==, 1); - - tt_assert(!memcmp(evbuffer_pullup(dst, strlen(data)), - data, strlen(data))); - evbuffer_validate(dst); - - end: - evbuffer_free(dst); - evbuffer_free(src); -} - -static struct event_base *addfile_test_event_base = NULL; -static int addfile_test_done_writing = 0; -static int addfile_test_total_written = 0; -static int addfile_test_total_read = 0; - -static void -addfile_test_writecb(evutil_socket_t fd, short what, void *arg) -{ - struct evbuffer *b = arg; - int r; - evbuffer_validate(b); - while (evbuffer_get_length(b)) { - r = evbuffer_write(b, fd); - if (r > 0) { - addfile_test_total_written += r; - TT_BLATHER(("Wrote %d/%d bytes", r, addfile_test_total_written)); - } else { - int e = evutil_socket_geterror(fd); - if (EVUTIL_ERR_RW_RETRIABLE(e)) - return; - tt_fail_perror("write"); - event_base_loopexit(addfile_test_event_base,NULL); - } - evbuffer_validate(b); - } - addfile_test_done_writing = 1; - return; -end: - event_base_loopexit(addfile_test_event_base,NULL); -} - -static void -addfile_test_readcb(evutil_socket_t fd, short what, void *arg) -{ - struct evbuffer *b = arg; - int e, r = 0; - do { - r = evbuffer_read(b, fd, 1024); - if (r > 0) { - addfile_test_total_read += r; - TT_BLATHER(("Read %d/%d bytes", r, addfile_test_total_read)); - } - } while (r > 0); - if (r < 0) { - e = evutil_socket_geterror(fd); - if (! EVUTIL_ERR_RW_RETRIABLE(e)) { - tt_fail_perror("read"); - event_base_loopexit(addfile_test_event_base,NULL); - } - } - if (addfile_test_done_writing && - addfile_test_total_read >= addfile_test_total_written) { - event_base_loopexit(addfile_test_event_base,NULL); - } -} - -static void -test_evbuffer_add_file(void *ptr) -{ - struct basic_test_data *testdata = ptr; - const char *impl = testdata->setup_data; - struct evbuffer *src = evbuffer_new(), *dest = evbuffer_new(); - char *tmpfilename = NULL; - char *data = NULL; - const char *expect_data; - size_t datalen, expect_len; - const char *compare; - int fd = -1; - int want_ismapping = -1, want_cansendfile = -1; - unsigned flags = 0; - int use_segment = 1, use_bigfile = 0, map_from_offset = 0, - view_from_offset = 0; - struct evbuffer_file_segment *seg = NULL; - ev_off_t starting_offset = 0, mapping_len = -1; - ev_off_t segment_offset = 0, segment_len = -1; - struct event *rev=NULL, *wev=NULL; - struct event_base *base = testdata->base; - evutil_socket_t pair[2] = {-1, -1}; - struct evutil_weakrand_state seed = { 123456789U }; - - /* This test is highly parameterized based on substrings of its - * argument. The strings are: */ - tt_assert(impl); - if (strstr(impl, "nosegment")) { - /* If nosegment is set, use the older evbuffer_add_file - * interface */ - use_segment = 0; - } - if (strstr(impl, "bigfile")) { - /* If bigfile is set, use a 512K file. Else use a smaller - * one. */ - use_bigfile = 1; - } - if (strstr(impl, "map_offset")) { - /* If map_offset is set, we build the file segment starting - * from a point other than byte 0 and ending somewhere other - * than the last byte. Otherwise we map the whole thing */ - map_from_offset = 1; - } - if (strstr(impl, "offset_in_segment")) { - /* If offset_in_segment is set, we add a subsection of the - * file semgment starting from a point other than byte 0 of - * the segment. */ - view_from_offset = 1; - } - if (strstr(impl, "sendfile")) { - /* If sendfile is set, we try to use a sendfile/splice style - * backend. */ - flags = EVBUF_FS_DISABLE_MMAP; - want_cansendfile = 1; - want_ismapping = 0; - } else if (strstr(impl, "mmap")) { - /* If sendfile is set, we try to use a mmap/CreateFileMapping - * style backend. */ - flags = EVBUF_FS_DISABLE_SENDFILE; - want_ismapping = 1; - want_cansendfile = 0; - } else if (strstr(impl, "linear")) { - /* If linear is set, we try to use a read-the-whole-thing - * backend. */ - flags = EVBUF_FS_DISABLE_SENDFILE|EVBUF_FS_DISABLE_MMAP; - want_ismapping = 0; - want_cansendfile = 0; - } else if (strstr(impl, "default")) { - /* The caller doesn't care which backend we use. */ - ; - } else { - /* The caller must choose a backend. */ - TT_DIE(("Didn't recognize the implementation")); - } - - if (use_bigfile) { - unsigned int i; - datalen = 1024*512; - data = malloc(1024*512); - tt_assert(data); - for (i = 0; i < datalen; ++i) - data[i] = (char)evutil_weakrand_(&seed); - } else { - data = strdup("here is a relatively small string."); - tt_assert(data); - datalen = strlen(data); - } - - fd = regress_make_tmpfile(data, datalen, &tmpfilename); - - if (map_from_offset) { - starting_offset = datalen/4 + 1; - mapping_len = datalen / 2 - 1; - expect_data = data + starting_offset; - expect_len = mapping_len; - } else { - expect_data = data; - expect_len = datalen; - } - if (view_from_offset) { - tt_assert(use_segment); /* Can't do this with add_file*/ - segment_offset = expect_len / 3; - segment_len = expect_len / 2; - expect_data = expect_data + segment_offset; - expect_len = segment_len; - } - - if (use_segment) { - seg = evbuffer_file_segment_new(fd, starting_offset, - mapping_len, flags); - tt_assert(seg); - if (want_ismapping >= 0) { - if (seg->is_mapping != (unsigned)want_ismapping) - tt_skip(); - } - if (want_cansendfile >= 0) { - if (seg->can_sendfile != (unsigned)want_cansendfile) - tt_skip(); - } - } - - /* Say that it drains to a fd so that we can use sendfile. */ - evbuffer_set_flags(src, EVBUFFER_FLAG_DRAINS_TO_FD); - -#if defined(EVENT__HAVE_SENDFILE) && defined(__sun__) && defined(__svr4__) - /* We need to use a pair of AF_INET sockets, since Solaris - doesn't support sendfile() over AF_UNIX. */ - if (evutil_ersatz_socketpair_(AF_INET, SOCK_STREAM, 0, pair) == -1) - tt_abort_msg("ersatz_socketpair failed"); -#else - if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) - tt_abort_msg("socketpair failed"); -#endif - evutil_make_socket_nonblocking(pair[0]); - evutil_make_socket_nonblocking(pair[1]); - - tt_assert(fd != -1); - - if (use_segment) { - tt_assert(evbuffer_add_file_segment(src, seg, - segment_offset, segment_len)!=-1); - } else { - tt_assert(evbuffer_add_file(src, fd, starting_offset, - mapping_len) != -1); - } - - evbuffer_validate(src); - - addfile_test_event_base = base; - wev = event_new(base, pair[0], EV_WRITE|EV_PERSIST, - addfile_test_writecb, src); - rev = event_new(base, pair[1], EV_READ|EV_PERSIST, - addfile_test_readcb, dest); - - event_add(wev, NULL); - event_add(rev, NULL); - event_base_dispatch(base); - - evbuffer_validate(src); - evbuffer_validate(dest); - - tt_assert(addfile_test_done_writing); - tt_int_op(addfile_test_total_written, ==, expect_len); - tt_int_op(addfile_test_total_read, ==, expect_len); - - compare = (char *)evbuffer_pullup(dest, expect_len); - tt_assert(compare != NULL); - if (memcmp(compare, expect_data, expect_len)) { - tt_abort_msg("Data from add_file differs."); - } - - evbuffer_validate(dest); - end: - if (data) - free(data); - if (seg) - evbuffer_file_segment_free(seg); - if (src) - evbuffer_free(src); - if (dest) - evbuffer_free(dest); - if (pair[0] >= 0) - evutil_closesocket(pair[0]); - if (pair[1] >= 0) - evutil_closesocket(pair[1]); - if (wev) - event_free(wev); - if (rev) - event_free(rev); - if (tmpfilename) { - unlink(tmpfilename); - free(tmpfilename); - } -} - -static int file_segment_cleanup_cb_called_count = 0; -static struct evbuffer_file_segment const* file_segment_cleanup_cb_called_with = NULL; -static int file_segment_cleanup_cb_called_with_flags = 0; -static void* file_segment_cleanup_cb_called_with_arg = NULL; -static void -file_segment_cleanup_cp(struct evbuffer_file_segment const* seg, int flags, void* arg) -{ - ++file_segment_cleanup_cb_called_count; - file_segment_cleanup_cb_called_with = seg; - file_segment_cleanup_cb_called_with_flags = flags; - file_segment_cleanup_cb_called_with_arg = arg; -} - -static void -test_evbuffer_file_segment_add_cleanup_cb(void* ptr) -{ - char *tmpfilename = NULL; - int fd = -1; - struct evbuffer *evb = NULL; - struct evbuffer_file_segment *seg = NULL, *segptr; - char const* arg = "token"; - - fd = regress_make_tmpfile("file_segment_test_file", 22, &tmpfilename); - tt_int_op(fd, >=, 0); - - evb = evbuffer_new(); - tt_assert(evb); - - segptr = seg = evbuffer_file_segment_new(fd, 0, -1, 0); - tt_assert(seg); - - evbuffer_file_segment_add_cleanup_cb( - seg, &file_segment_cleanup_cp, (void*)arg); - - tt_assert(fd != -1); - - tt_assert(evbuffer_add_file_segment(evb, seg, 0, -1)!=-1); - - evbuffer_validate(evb); - - tt_int_op(file_segment_cleanup_cb_called_count, ==, 0); - evbuffer_file_segment_free(seg); - seg = NULL; /* Prevent double-free. */ - - tt_int_op(file_segment_cleanup_cb_called_count, ==, 0); - evbuffer_free(evb); - evb = NULL; /* pevent double-free */ - - tt_int_op(file_segment_cleanup_cb_called_count, ==, 1); - tt_assert(file_segment_cleanup_cb_called_with == segptr); - tt_assert(file_segment_cleanup_cb_called_with_flags == 0); - tt_assert(file_segment_cleanup_cb_called_with_arg == (void*)arg); - -end: - if (evb) - evbuffer_free(evb); - if (seg) - evbuffer_file_segment_free(seg); - if (tmpfilename) { - unlink(tmpfilename); - free(tmpfilename); - } -} - -#ifndef EVENT__DISABLE_MM_REPLACEMENT -static void * -failing_malloc(size_t how_much) -{ - errno = ENOMEM; - return NULL; -} -#endif - -static void -test_evbuffer_readln(void *ptr) -{ - struct evbuffer *evb = evbuffer_new(); - struct evbuffer *evb_tmp = evbuffer_new(); - const char *s; - char *cp = NULL; - size_t sz; - -#define tt_line_eq(content) \ - TT_STMT_BEGIN \ - if (!cp || sz != strlen(content) || strcmp(cp, content)) { \ - TT_DIE(("Wanted %s; got %s [%d]", content, cp, (int)sz)); \ - } \ - TT_STMT_END - - /* Test EOL_ANY. */ - s = "complex silly newline\r\n\n\r\n\n\rmore\0\n"; - evbuffer_add(evb, s, strlen(s)+2); - evbuffer_validate(evb); - cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY); - tt_line_eq("complex silly newline"); - free(cp); - evbuffer_validate(evb); - cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY); - if (!cp || sz != 5 || memcmp(cp, "more\0\0", 6)) - tt_abort_msg("Not as expected"); - tt_uint_op(evbuffer_get_length(evb), ==, 0); - evbuffer_validate(evb); - s = "\nno newline"; - evbuffer_add(evb, s, strlen(s)); - free(cp); - evbuffer_validate(evb); - cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY); - tt_line_eq(""); - free(cp); - evbuffer_validate(evb); - cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY); - tt_assert(!cp); - evbuffer_validate(evb); - evbuffer_drain(evb, evbuffer_get_length(evb)); - tt_assert(evbuffer_get_length(evb) == 0); - evbuffer_validate(evb); - - /* Test EOL_CRLF */ - s = "Line with\rin the middle\nLine with good crlf\r\n\nfinal\n"; - evbuffer_add(evb, s, strlen(s)); - evbuffer_validate(evb); - cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF); - tt_line_eq("Line with\rin the middle"); - free(cp); - evbuffer_validate(evb); - - cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF); - tt_line_eq("Line with good crlf"); - free(cp); - evbuffer_validate(evb); - - cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF); - tt_line_eq(""); - free(cp); - evbuffer_validate(evb); - - cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF); - tt_line_eq("final"); - s = "x"; - evbuffer_validate(evb); - evbuffer_add(evb, s, 1); - evbuffer_validate(evb); - free(cp); - cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF); - tt_assert(!cp); - evbuffer_validate(evb); - - /* Test CRLF_STRICT */ - s = " and a bad crlf\nand a good one\r\n\r\nMore\r"; - evbuffer_add(evb, s, strlen(s)); - evbuffer_validate(evb); - cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT); - tt_line_eq("x and a bad crlf\nand a good one"); - free(cp); - evbuffer_validate(evb); - - cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT); - tt_line_eq(""); - free(cp); - evbuffer_validate(evb); - - cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT); - tt_assert(!cp); - evbuffer_validate(evb); - evbuffer_add(evb, "\n", 1); - evbuffer_validate(evb); - - cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT); - tt_line_eq("More"); - free(cp); - tt_assert(evbuffer_get_length(evb) == 0); - evbuffer_validate(evb); - - s = "An internal CR\r is not an eol\r\nNor is a lack of one"; - evbuffer_add(evb, s, strlen(s)); - cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT); - tt_line_eq("An internal CR\r is not an eol"); - free(cp); - evbuffer_validate(evb); - - cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT); - tt_assert(!cp); - evbuffer_validate(evb); - - evbuffer_add(evb, "\r\n", 2); - evbuffer_validate(evb); - cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT); - tt_line_eq("Nor is a lack of one"); - free(cp); - tt_assert(evbuffer_get_length(evb) == 0); - evbuffer_validate(evb); - - /* Test LF */ - s = "An\rand a nl\n\nText"; - evbuffer_add(evb, s, strlen(s)); - evbuffer_validate(evb); - - cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF); - tt_line_eq("An\rand a nl"); - free(cp); - evbuffer_validate(evb); - - cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF); - tt_line_eq(""); - free(cp); - evbuffer_validate(evb); - - cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF); - tt_assert(!cp); - free(cp); - evbuffer_add(evb, "\n", 1); - evbuffer_validate(evb); - cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF); - tt_line_eq("Text"); - free(cp); - evbuffer_validate(evb); - - /* Test NUL */ - tt_int_op(evbuffer_get_length(evb), ==, 0); - { - char x[] = - "NUL\n\0\0" - "The all-zeros character which may serve\0" - "to accomplish time fill\0and media fill"; - /* Add all but the final NUL of x. */ - evbuffer_add(evb, x, sizeof(x)-1); - } - cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_NUL); - tt_line_eq("NUL\n"); - free(cp); - cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_NUL); - tt_line_eq(""); - free(cp); - cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_NUL); - tt_line_eq("The all-zeros character which may serve"); - free(cp); - cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_NUL); - tt_line_eq("to accomplish time fill"); - free(cp); - cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_NUL); - tt_ptr_op(cp, ==, NULL); - evbuffer_drain(evb, -1); - - /* Test CRLF_STRICT - across boundaries*/ - s = " and a bad crlf\nand a good one\r"; - evbuffer_add(evb_tmp, s, strlen(s)); - evbuffer_validate(evb); - evbuffer_add_buffer(evb, evb_tmp); - evbuffer_validate(evb); - s = "\n\r"; - evbuffer_add(evb_tmp, s, strlen(s)); - evbuffer_validate(evb); - evbuffer_add_buffer(evb, evb_tmp); - evbuffer_validate(evb); - s = "\nMore\r"; - evbuffer_add(evb_tmp, s, strlen(s)); - evbuffer_validate(evb); - evbuffer_add_buffer(evb, evb_tmp); - evbuffer_validate(evb); - - cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT); - tt_line_eq(" and a bad crlf\nand a good one"); - free(cp); - evbuffer_validate(evb); - - cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT); - tt_line_eq(""); - free(cp); - evbuffer_validate(evb); - - cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT); - tt_assert(!cp); - free(cp); - evbuffer_validate(evb); - evbuffer_add(evb, "\n", 1); - evbuffer_validate(evb); - cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT); - tt_line_eq("More"); - free(cp); cp = NULL; - evbuffer_validate(evb); - tt_assert(evbuffer_get_length(evb) == 0); - - /* Test memory problem*/ - s = "one line\ntwo line\nblue line"; - evbuffer_add(evb_tmp, s, strlen(s)); - evbuffer_validate(evb); - evbuffer_add_buffer(evb, evb_tmp); - evbuffer_validate(evb); - - cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF); - tt_line_eq("one line"); - free(cp); cp = NULL; - evbuffer_validate(evb); - - /* the next call to readline should fail */ -#ifndef EVENT__DISABLE_MM_REPLACEMENT - event_set_mem_functions(failing_malloc, realloc, free); - cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF); - tt_assert(cp == NULL); - evbuffer_validate(evb); - - /* now we should get the next line back */ - event_set_mem_functions(malloc, realloc, free); -#endif - cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF); - tt_line_eq("two line"); - free(cp); cp = NULL; - evbuffer_validate(evb); - - end: - evbuffer_free(evb); - evbuffer_free(evb_tmp); - if (cp) free(cp); -} - -static void -test_evbuffer_search_eol(void *ptr) -{ - struct evbuffer *buf = evbuffer_new(); - struct evbuffer_ptr ptr1, ptr2; - const char *s; - size_t eol_len; - - s = "string! \r\n\r\nx\n"; - evbuffer_add(buf, s, strlen(s)); - eol_len = -1; - ptr1 = evbuffer_search_eol(buf, NULL, &eol_len, EVBUFFER_EOL_CRLF); - tt_int_op(ptr1.pos, ==, 8); - tt_int_op(eol_len, ==, 2); - - eol_len = -1; - ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_CRLF); - tt_int_op(ptr2.pos, ==, 8); - tt_int_op(eol_len, ==, 2); - - evbuffer_ptr_set(buf, &ptr1, 1, EVBUFFER_PTR_ADD); - eol_len = -1; - ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_CRLF); - tt_int_op(ptr2.pos, ==, 9); - tt_int_op(eol_len, ==, 1); - - eol_len = -1; - ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_CRLF_STRICT); - tt_int_op(ptr2.pos, ==, 10); - tt_int_op(eol_len, ==, 2); - - eol_len = -1; - ptr1 = evbuffer_search_eol(buf, NULL, &eol_len, EVBUFFER_EOL_LF); - tt_int_op(ptr1.pos, ==, 9); - tt_int_op(eol_len, ==, 1); - - eol_len = -1; - ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_LF); - tt_int_op(ptr2.pos, ==, 9); - tt_int_op(eol_len, ==, 1); - - evbuffer_ptr_set(buf, &ptr1, 1, EVBUFFER_PTR_ADD); - eol_len = -1; - ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_LF); - tt_int_op(ptr2.pos, ==, 11); - tt_int_op(eol_len, ==, 1); - - tt_assert(evbuffer_ptr_set(buf, &ptr1, evbuffer_get_length(buf), EVBUFFER_PTR_SET) == 0); - eol_len = -1; - ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_LF); - tt_int_op(ptr2.pos, ==, -1); - tt_int_op(eol_len, ==, 0); - -end: - evbuffer_free(buf); -} - -static void -test_evbuffer_iterative(void *ptr) -{ - struct evbuffer *buf = evbuffer_new(); - const char *abc = "abcdefghijklmnopqrstvuwxyzabcdefghijklmnopqrstvuwxyzabcdefghijklmnopqrstvuwxyzabcdefghijklmnopqrstvuwxyz"; - unsigned i, j, sum, n; - - sum = 0; - n = 0; - for (i = 0; i < 1000; ++i) { - for (j = 1; j < strlen(abc); ++j) { - char format[32]; - evutil_snprintf(format, sizeof(format), "%%%u.%us", j, j); - evbuffer_add_printf(buf, format, abc); - - /* Only check for rep violations every so often. - Walking over the whole list of chains can get - pretty expensive as it gets long. - */ - if ((n % 337) == 0) - evbuffer_validate(buf); - - sum += j; - n++; - } - } - evbuffer_validate(buf); - - tt_uint_op(sum, ==, evbuffer_get_length(buf)); - - { - size_t a,w,u; - a=w=u=0; - evbuffer_get_waste(buf, &a, &w, &u); - if (0) - printf("Allocated: %u.\nWasted: %u.\nUsed: %u.", - (unsigned)a, (unsigned)w, (unsigned)u); - tt_assert( ((double)w)/a < .125); - } - end: - evbuffer_free(buf); - -} - -static void -test_evbuffer_find(void *ptr) -{ - unsigned char* p; - const char* test1 = "1234567890\r\n"; - const char* test2 = "1234567890\r"; -#define EVBUFFER_INITIAL_LENGTH 256 - char test3[EVBUFFER_INITIAL_LENGTH]; - unsigned int i; - struct evbuffer * buf = evbuffer_new(); - - tt_assert(buf); - - /* make sure evbuffer_find doesn't match past the end of the buffer */ - evbuffer_add(buf, (unsigned char*)test1, strlen(test1)); - evbuffer_validate(buf); - evbuffer_drain(buf, strlen(test1)); - evbuffer_validate(buf); - evbuffer_add(buf, (unsigned char*)test2, strlen(test2)); - evbuffer_validate(buf); - p = evbuffer_find(buf, (unsigned char*)"\r\n", 2); - tt_want(p == NULL); - - /* - * drain the buffer and do another find; in r309 this would - * read past the allocated buffer causing a valgrind error. - */ - evbuffer_drain(buf, strlen(test2)); - evbuffer_validate(buf); - for (i = 0; i < EVBUFFER_INITIAL_LENGTH; ++i) - test3[i] = 'a'; - test3[EVBUFFER_INITIAL_LENGTH - 1] = 'x'; - evbuffer_add(buf, (unsigned char *)test3, EVBUFFER_INITIAL_LENGTH); - evbuffer_validate(buf); - p = evbuffer_find(buf, (unsigned char *)"xy", 2); - tt_want(p == NULL); - - /* simple test for match at end of allocated buffer */ - p = evbuffer_find(buf, (unsigned char *)"ax", 2); - tt_assert(p != NULL); - tt_want(strncmp((char*)p, "ax", 2) == 0); - -end: - if (buf) - evbuffer_free(buf); -} - -static void -test_evbuffer_ptr_set(void *ptr) -{ - struct evbuffer *buf = evbuffer_new(); - struct evbuffer_ptr pos; - struct evbuffer_iovec v[1]; - - tt_assert(buf); - - tt_int_op(evbuffer_get_length(buf), ==, 0); - - tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0); - tt_assert(pos.pos == 0); - tt_assert(evbuffer_ptr_set(buf, &pos, 1, EVBUFFER_PTR_ADD) == -1); - tt_assert(pos.pos == -1); - tt_assert(evbuffer_ptr_set(buf, &pos, 1, EVBUFFER_PTR_SET) == -1); - tt_assert(pos.pos == -1); - - /* create some chains */ - evbuffer_reserve_space(buf, 5000, v, 1); - v[0].iov_len = 5000; - memset(v[0].iov_base, 1, v[0].iov_len); - evbuffer_commit_space(buf, v, 1); - evbuffer_validate(buf); - - evbuffer_reserve_space(buf, 4000, v, 1); - v[0].iov_len = 4000; - memset(v[0].iov_base, 2, v[0].iov_len); - evbuffer_commit_space(buf, v, 1); - - evbuffer_reserve_space(buf, 3000, v, 1); - v[0].iov_len = 3000; - memset(v[0].iov_base, 3, v[0].iov_len); - evbuffer_commit_space(buf, v, 1); - evbuffer_validate(buf); - - tt_int_op(evbuffer_get_length(buf), ==, 12000); - - tt_assert(evbuffer_ptr_set(buf, &pos, 13000, EVBUFFER_PTR_SET) == -1); - tt_assert(pos.pos == -1); - tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0); - tt_assert(pos.pos == 0); - tt_assert(evbuffer_ptr_set(buf, &pos, 13000, EVBUFFER_PTR_ADD) == -1); - - tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0); - tt_assert(pos.pos == 0); - tt_assert(evbuffer_ptr_set(buf, &pos, 10000, EVBUFFER_PTR_ADD) == 0); - tt_assert(pos.pos == 10000); - tt_assert(evbuffer_ptr_set(buf, &pos, 1000, EVBUFFER_PTR_ADD) == 0); - tt_assert(pos.pos == 11000); - tt_assert(evbuffer_ptr_set(buf, &pos, 1000, EVBUFFER_PTR_ADD) == 0); - tt_assert(pos.pos == 12000); - tt_assert(evbuffer_ptr_set(buf, &pos, 1000, EVBUFFER_PTR_ADD) == -1); - tt_assert(pos.pos == -1); - -end: - if (buf) - evbuffer_free(buf); -} - -static void -test_evbuffer_search(void *ptr) -{ - struct evbuffer *buf = evbuffer_new(); - struct evbuffer *tmp = evbuffer_new(); - struct evbuffer_ptr pos, end; - - tt_assert(buf); - tt_assert(tmp); - - pos = evbuffer_search(buf, "x", 1, NULL); - tt_int_op(pos.pos, ==, -1); - tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0); - pos = evbuffer_search(buf, "x", 1, &pos); - tt_int_op(pos.pos, ==, -1); - tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0); - pos = evbuffer_search_range(buf, "x", 1, &pos, &pos); - tt_int_op(pos.pos, ==, -1); - tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0); - pos = evbuffer_search_range(buf, "x", 1, &pos, NULL); - tt_int_op(pos.pos, ==, -1); - - /* set up our chains */ - evbuffer_add_printf(tmp, "hello"); /* 5 chars */ - evbuffer_add_buffer(buf, tmp); - evbuffer_add_printf(tmp, "foo"); /* 3 chars */ - evbuffer_add_buffer(buf, tmp); - evbuffer_add_printf(tmp, "cat"); /* 3 chars */ - evbuffer_add_buffer(buf, tmp); - evbuffer_add_printf(tmp, "attack"); - evbuffer_add_buffer(buf, tmp); - - pos = evbuffer_search(buf, "attack", 6, NULL); - tt_int_op(pos.pos, ==, 11); - pos = evbuffer_search(buf, "attacker", 8, NULL); - tt_int_op(pos.pos, ==, -1); - - /* test continuing search */ - pos = evbuffer_search(buf, "oc", 2, NULL); - tt_int_op(pos.pos, ==, 7); - pos = evbuffer_search(buf, "cat", 3, &pos); - tt_int_op(pos.pos, ==, 8); - pos = evbuffer_search(buf, "tacking", 7, &pos); - tt_int_op(pos.pos, ==, -1); - - evbuffer_ptr_set(buf, &pos, 5, EVBUFFER_PTR_SET); - pos = evbuffer_search(buf, "foo", 3, &pos); - tt_int_op(pos.pos, ==, 5); - - evbuffer_ptr_set(buf, &pos, 2, EVBUFFER_PTR_ADD); - pos = evbuffer_search(buf, "tat", 3, &pos); - tt_int_op(pos.pos, ==, 10); - - /* test bounded search. */ - /* Set "end" to the first t in "attack". */ - evbuffer_ptr_set(buf, &end, 12, EVBUFFER_PTR_SET); - pos = evbuffer_search_range(buf, "foo", 3, NULL, &end); - tt_int_op(pos.pos, ==, 5); - pos = evbuffer_search_range(buf, "foocata", 7, NULL, &end); - tt_int_op(pos.pos, ==, 5); - pos = evbuffer_search_range(buf, "foocatat", 8, NULL, &end); - tt_int_op(pos.pos, ==, -1); - pos = evbuffer_search_range(buf, "ack", 3, NULL, &end); - tt_int_op(pos.pos, ==, -1); - - /* Set "end" after the last byte in the buffer. */ - tt_assert(evbuffer_ptr_set(buf, &end, 17, EVBUFFER_PTR_SET) == 0); - - pos = evbuffer_search_range(buf, "attack", 6, NULL, &end); - tt_int_op(pos.pos, ==, 11); - tt_assert(evbuffer_ptr_set(buf, &pos, 11, EVBUFFER_PTR_SET) == 0); - pos = evbuffer_search_range(buf, "attack", 6, &pos, &end); - tt_int_op(pos.pos, ==, 11); - tt_assert(evbuffer_ptr_set(buf, &pos, 17, EVBUFFER_PTR_SET) == 0); - pos = evbuffer_search_range(buf, "attack", 6, &pos, &end); - tt_int_op(pos.pos, ==, -1); - tt_assert(evbuffer_ptr_set(buf, &pos, 17, EVBUFFER_PTR_SET) == 0); - pos = evbuffer_search_range(buf, "attack", 6, &pos, NULL); - tt_int_op(pos.pos, ==, -1); - -end: - if (buf) - evbuffer_free(buf); - if (tmp) - evbuffer_free(tmp); -} - -static void -log_change_callback(struct evbuffer *buffer, - const struct evbuffer_cb_info *cbinfo, - void *arg) -{ - - size_t old_len = cbinfo->orig_size; - size_t new_len = old_len + cbinfo->n_added - cbinfo->n_deleted; - struct evbuffer *out = arg; - evbuffer_add_printf(out, "%lu->%lu; ", (unsigned long)old_len, - (unsigned long)new_len); -} -static void -self_draining_callback(struct evbuffer *evbuffer, size_t old_len, - size_t new_len, void *arg) -{ - if (new_len > old_len) - evbuffer_drain(evbuffer, new_len); -} - -static void -test_evbuffer_callbacks(void *ptr) -{ - struct evbuffer *buf = evbuffer_new(); - struct evbuffer *buf_out1 = evbuffer_new(); - struct evbuffer *buf_out2 = evbuffer_new(); - struct evbuffer_cb_entry *cb1, *cb2; - - tt_assert(buf); - tt_assert(buf_out1); - tt_assert(buf_out2); - - cb1 = evbuffer_add_cb(buf, log_change_callback, buf_out1); - cb2 = evbuffer_add_cb(buf, log_change_callback, buf_out2); - - /* Let's run through adding and deleting some stuff from the buffer - * and turning the callbacks on and off and removing them. The callback - * adds a summary of length changes to buf_out1/buf_out2 when called. */ - /* size: 0-> 36. */ - evbuffer_add_printf(buf, "The %d magic words are spotty pudding", 2); - evbuffer_validate(buf); - evbuffer_cb_clear_flags(buf, cb2, EVBUFFER_CB_ENABLED); - evbuffer_drain(buf, 10); /*36->26*/ - evbuffer_validate(buf); - evbuffer_prepend(buf, "Hello", 5);/*26->31*/ - evbuffer_cb_set_flags(buf, cb2, EVBUFFER_CB_ENABLED); - evbuffer_add_reference(buf, "Goodbye", 7, NULL, NULL); /*31->38*/ - evbuffer_remove_cb_entry(buf, cb1); - evbuffer_validate(buf); - evbuffer_drain(buf, evbuffer_get_length(buf)); /*38->0*/; - tt_assert(-1 == evbuffer_remove_cb(buf, log_change_callback, NULL)); - evbuffer_add(buf, "X", 1); /* 0->1 */ - tt_assert(!evbuffer_remove_cb(buf, log_change_callback, buf_out2)); - evbuffer_validate(buf); - - tt_str_op((const char *) evbuffer_pullup(buf_out1, -1), ==, - "0->36; 36->26; 26->31; 31->38; "); - tt_str_op((const char *) evbuffer_pullup(buf_out2, -1), ==, - "0->36; 31->38; 38->0; 0->1; "); - evbuffer_drain(buf_out1, evbuffer_get_length(buf_out1)); - evbuffer_drain(buf_out2, evbuffer_get_length(buf_out2)); - /* Let's test the obsolete buffer_setcb function too. */ - cb1 = evbuffer_add_cb(buf, log_change_callback, buf_out1); - tt_assert(cb1 != NULL); - cb2 = evbuffer_add_cb(buf, log_change_callback, buf_out2); - tt_assert(cb2 != NULL); - evbuffer_setcb(buf, self_draining_callback, NULL); - evbuffer_add_printf(buf, "This should get drained right away."); - tt_uint_op(evbuffer_get_length(buf), ==, 0); - tt_uint_op(evbuffer_get_length(buf_out1), ==, 0); - tt_uint_op(evbuffer_get_length(buf_out2), ==, 0); - evbuffer_setcb(buf, NULL, NULL); - evbuffer_add_printf(buf, "This will not."); - tt_str_op((const char *) evbuffer_pullup(buf, -1), ==, "This will not."); - evbuffer_validate(buf); - evbuffer_drain(buf, evbuffer_get_length(buf)); - evbuffer_validate(buf); -#if 0 - /* Now let's try a suspended callback. */ - cb1 = evbuffer_add_cb(buf, log_change_callback, buf_out1); - cb2 = evbuffer_add_cb(buf, log_change_callback, buf_out2); - evbuffer_cb_suspend(buf,cb2); - evbuffer_prepend(buf,"Hello world",11); /*0->11*/ - evbuffer_validate(buf); - evbuffer_cb_suspend(buf,cb1); - evbuffer_add(buf,"more",4); /* 11->15 */ - evbuffer_cb_unsuspend(buf,cb2); - evbuffer_drain(buf, 4); /* 15->11 */ - evbuffer_cb_unsuspend(buf,cb1); - evbuffer_drain(buf, evbuffer_get_length(buf)); /* 11->0 */ - - tt_str_op(evbuffer_pullup(buf_out1, -1), ==, - "0->11; 11->11; 11->0; "); - tt_str_op(evbuffer_pullup(buf_out2, -1), ==, - "0->15; 15->11; 11->0; "); -#endif - - end: - if (buf) - evbuffer_free(buf); - if (buf_out1) - evbuffer_free(buf_out1); - if (buf_out2) - evbuffer_free(buf_out2); -} - -static int ref_done_cb_called_count = 0; -static void *ref_done_cb_called_with = NULL; -static const void *ref_done_cb_called_with_data = NULL; -static size_t ref_done_cb_called_with_len = 0; -static void ref_done_cb(const void *data, size_t len, void *info) -{ - ++ref_done_cb_called_count; - ref_done_cb_called_with = info; - ref_done_cb_called_with_data = data; - ref_done_cb_called_with_len = len; -} - -static void -test_evbuffer_add_reference(void *ptr) -{ - const char chunk1[] = "If you have found the answer to such a problem"; - const char chunk2[] = "you ought to write it up for publication"; - /* -- Knuth's "Notes on the Exercises" from TAOCP */ - char tmp[16]; - size_t len1 = strlen(chunk1), len2=strlen(chunk2); - - struct evbuffer *buf1 = NULL, *buf2 = NULL; - - buf1 = evbuffer_new(); - tt_assert(buf1); - - evbuffer_add_reference(buf1, chunk1, len1, ref_done_cb, (void*)111); - evbuffer_add(buf1, ", ", 2); - evbuffer_add_reference(buf1, chunk2, len2, ref_done_cb, (void*)222); - tt_int_op(evbuffer_get_length(buf1), ==, len1+len2+2); - - /* Make sure we can drain a little from a reference. */ - tt_int_op(evbuffer_remove(buf1, tmp, 6), ==, 6); - tt_int_op(memcmp(tmp, "If you", 6), ==, 0); - tt_int_op(evbuffer_remove(buf1, tmp, 5), ==, 5); - tt_int_op(memcmp(tmp, " have", 5), ==, 0); - - /* Make sure that prepending does not meddle with immutable data */ - tt_int_op(evbuffer_prepend(buf1, "I have ", 7), ==, 0); - tt_int_op(memcmp(chunk1, "If you", 6), ==, 0); - evbuffer_validate(buf1); - - /* Make sure that when the chunk is over, the callback is invoked. */ - evbuffer_drain(buf1, 7); /* Remove prepended stuff. */ - evbuffer_drain(buf1, len1-11-1); /* remove all but one byte of chunk1 */ - tt_int_op(ref_done_cb_called_count, ==, 0); - evbuffer_remove(buf1, tmp, 1); - tt_int_op(tmp[0], ==, 'm'); - tt_assert(ref_done_cb_called_with == (void*)111); - tt_assert(ref_done_cb_called_with_data == chunk1); - tt_assert(ref_done_cb_called_with_len == len1); - tt_int_op(ref_done_cb_called_count, ==, 1); - evbuffer_validate(buf1); - - /* Drain some of the remaining chunk, then add it to another buffer */ - evbuffer_drain(buf1, 6); /* Remove the ", you ". */ - buf2 = evbuffer_new(); - tt_assert(buf2); - tt_int_op(ref_done_cb_called_count, ==, 1); - evbuffer_add(buf2, "I ", 2); - - evbuffer_add_buffer(buf2, buf1); - tt_int_op(ref_done_cb_called_count, ==, 1); - evbuffer_remove(buf2, tmp, 16); - tt_int_op(memcmp("I ought to write", tmp, 16), ==, 0); - evbuffer_drain(buf2, evbuffer_get_length(buf2)); - tt_int_op(ref_done_cb_called_count, ==, 2); - tt_assert(ref_done_cb_called_with == (void*)222); - evbuffer_validate(buf2); - - /* Now add more stuff to buf1 and make sure that it gets removed on - * free. */ - evbuffer_add(buf1, "You shake and shake the ", 24); - evbuffer_add_reference(buf1, "ketchup bottle", 14, ref_done_cb, - (void*)3333); - evbuffer_add(buf1, ". Nothing comes and then a lot'll.", 35); - evbuffer_free(buf1); - buf1 = NULL; - tt_int_op(ref_done_cb_called_count, ==, 3); - tt_assert(ref_done_cb_called_with == (void*)3333); - -end: - if (buf1) - evbuffer_free(buf1); - if (buf2) - evbuffer_free(buf2); -} - -static void -test_evbuffer_multicast(void *ptr) -{ - const char chunk1[] = "If you have found the answer to such a problem"; - const char chunk2[] = "you ought to write it up for publication"; - /* -- Knuth's "Notes on the Exercises" from TAOCP */ - char tmp[16]; - size_t len1 = strlen(chunk1), len2=strlen(chunk2); - - struct evbuffer *buf1 = NULL, *buf2 = NULL; - - buf1 = evbuffer_new(); - tt_assert(buf1); - - evbuffer_add(buf1, chunk1, len1); - evbuffer_add(buf1, ", ", 2); - evbuffer_add(buf1, chunk2, len2); - tt_int_op(evbuffer_get_length(buf1), ==, len1+len2+2); - - buf2 = evbuffer_new(); - tt_assert(buf2); - - tt_int_op(evbuffer_add_buffer_reference(buf2, buf1), ==, 0); - /* nested references are not allowed */ - tt_int_op(evbuffer_add_buffer_reference(buf2, buf2), ==, -1); - tt_int_op(evbuffer_add_buffer_reference(buf1, buf2), ==, -1); - - /* both buffers contain the same amount of data */ - tt_int_op(evbuffer_get_length(buf1), ==, evbuffer_get_length(buf1)); - - /* Make sure we can drain a little from the first buffer. */ - tt_int_op(evbuffer_remove(buf1, tmp, 6), ==, 6); - tt_int_op(memcmp(tmp, "If you", 6), ==, 0); - tt_int_op(evbuffer_remove(buf1, tmp, 5), ==, 5); - tt_int_op(memcmp(tmp, " have", 5), ==, 0); - - /* Make sure that prepending does not meddle with immutable data */ - tt_int_op(evbuffer_prepend(buf1, "I have ", 7), ==, 0); - tt_int_op(memcmp(chunk1, "If you", 6), ==, 0); - evbuffer_validate(buf1); - - /* Make sure we can drain a little from the second buffer. */ - tt_int_op(evbuffer_remove(buf2, tmp, 6), ==, 6); - tt_int_op(memcmp(tmp, "If you", 6), ==, 0); - tt_int_op(evbuffer_remove(buf2, tmp, 5), ==, 5); - tt_int_op(memcmp(tmp, " have", 5), ==, 0); - - /* Make sure that prepending does not meddle with immutable data */ - tt_int_op(evbuffer_prepend(buf2, "I have ", 7), ==, 0); - tt_int_op(memcmp(chunk1, "If you", 6), ==, 0); - evbuffer_validate(buf2); - - /* Make sure the data can be read from the second buffer when the first is freed */ - evbuffer_free(buf1); - buf1 = NULL; - - tt_int_op(evbuffer_remove(buf2, tmp, 6), ==, 6); - tt_int_op(memcmp(tmp, "I have", 6), ==, 0); - - tt_int_op(evbuffer_remove(buf2, tmp, 6), ==, 6); - tt_int_op(memcmp(tmp, " foun", 6), ==, 0); - -end: - if (buf1) - evbuffer_free(buf1); - if (buf2) - evbuffer_free(buf2); -} - -static void -test_evbuffer_multicast_drain(void *ptr) -{ - const char chunk1[] = "If you have found the answer to such a problem"; - const char chunk2[] = "you ought to write it up for publication"; - /* -- Knuth's "Notes on the Exercises" from TAOCP */ - size_t len1 = strlen(chunk1), len2=strlen(chunk2); - - struct evbuffer *buf1 = NULL, *buf2 = NULL; - - buf1 = evbuffer_new(); - tt_assert(buf1); - - evbuffer_add(buf1, chunk1, len1); - evbuffer_add(buf1, ", ", 2); - evbuffer_add(buf1, chunk2, len2); - tt_int_op(evbuffer_get_length(buf1), ==, len1+len2+2); - - buf2 = evbuffer_new(); - tt_assert(buf2); - - tt_int_op(evbuffer_add_buffer_reference(buf2, buf1), ==, 0); - tt_int_op(evbuffer_get_length(buf2), ==, len1+len2+2); - tt_int_op(evbuffer_drain(buf1, evbuffer_get_length(buf1)), ==, 0); - tt_int_op(evbuffer_get_length(buf2), ==, len1+len2+2); - tt_int_op(evbuffer_drain(buf2, evbuffer_get_length(buf2)), ==, 0); - evbuffer_validate(buf1); - evbuffer_validate(buf2); - -end: - if (buf1) - evbuffer_free(buf1); - if (buf2) - evbuffer_free(buf2); -} - -/* Some cases that we didn't get in test_evbuffer() above, for more coverage. */ -static void -test_evbuffer_prepend(void *ptr) -{ - struct evbuffer *buf1 = NULL, *buf2 = NULL; - char tmp[128]; - int n; - - buf1 = evbuffer_new(); - tt_assert(buf1); - - /* Case 0: The evbuffer is entirely empty. */ - evbuffer_prepend(buf1, "This string has 29 characters", 29); - evbuffer_validate(buf1); - - /* Case 1: Prepend goes entirely in new chunk. */ - evbuffer_prepend(buf1, "Short.", 6); - evbuffer_validate(buf1); - - /* Case 2: prepend goes entirely in first chunk. */ - evbuffer_drain(buf1, 6+11); - evbuffer_prepend(buf1, "it", 2); - evbuffer_validate(buf1); - tt_assert(!memcmp(buf1->first->buffer+buf1->first->misalign, - "it has", 6)); - - /* Case 3: prepend is split over multiple chunks. */ - evbuffer_prepend(buf1, "It is no longer true to say ", 28); - evbuffer_validate(buf1); - n = evbuffer_remove(buf1, tmp, sizeof(tmp)-1); - tt_int_op(n, >=, 0); - tmp[n]='\0'; - tt_str_op(tmp,==,"It is no longer true to say it has 29 characters"); - - buf2 = evbuffer_new(); - tt_assert(buf2); - - /* Case 4: prepend a buffer to an empty buffer. */ - n = 999; - evbuffer_add_printf(buf1, "Here is string %d. ", n++); - evbuffer_prepend_buffer(buf2, buf1); - evbuffer_validate(buf2); - - /* Case 5: prepend a buffer to a nonempty buffer. */ - evbuffer_add_printf(buf1, "Here is string %d. ", n++); - evbuffer_prepend_buffer(buf2, buf1); - evbuffer_validate(buf2); - evbuffer_validate(buf1); - n = evbuffer_remove(buf2, tmp, sizeof(tmp)-1); - tt_int_op(n, >=, 0); - tmp[n]='\0'; - tt_str_op(tmp,==,"Here is string 1000. Here is string 999. "); - -end: - if (buf1) - evbuffer_free(buf1); - if (buf2) - evbuffer_free(buf2); - -} - -static void -test_evbuffer_peek_first_gt(void *info) -{ - struct evbuffer *buf = NULL, *tmp_buf = NULL; - struct evbuffer_ptr ptr; - struct evbuffer_iovec v[2]; - - buf = evbuffer_new(); - tmp_buf = evbuffer_new(); - evbuffer_add_printf(tmp_buf, "Contents of chunk 100\n"); - evbuffer_add_buffer(buf, tmp_buf); - evbuffer_add_printf(tmp_buf, "Contents of chunk 1\n"); - evbuffer_add_buffer(buf, tmp_buf); - - evbuffer_ptr_set(buf, &ptr, 0, EVBUFFER_PTR_SET); - - /** The only case that matters*/ - tt_int_op(evbuffer_peek(buf, -1, &ptr, NULL, 0), ==, 2); - /** Just in case */ - tt_int_op(evbuffer_peek(buf, -1, &ptr, v, 2), ==, 2); - - evbuffer_ptr_set(buf, &ptr, 20, EVBUFFER_PTR_ADD); - tt_int_op(evbuffer_peek(buf, -1, &ptr, NULL, 0), ==, 2); - tt_int_op(evbuffer_peek(buf, -1, &ptr, v, 2), ==, 2); - tt_int_op(evbuffer_peek(buf, 2, &ptr, NULL, 0), ==, 1); - tt_int_op(evbuffer_peek(buf, 2, &ptr, v, 2), ==, 1); - tt_int_op(evbuffer_peek(buf, 3, &ptr, NULL, 0), ==, 2); - tt_int_op(evbuffer_peek(buf, 3, &ptr, v, 2), ==, 2); - -end: - if (buf) - evbuffer_free(buf); - if (tmp_buf) - evbuffer_free(tmp_buf); -} - -static void -test_evbuffer_peek(void *info) -{ - struct evbuffer *buf = NULL, *tmp_buf = NULL; - int i; - struct evbuffer_iovec v[20]; - struct evbuffer_ptr ptr; - -#define tt_iov_eq(v, s) \ - tt_int_op((v)->iov_len, ==, strlen(s)); \ - tt_assert(!memcmp((v)->iov_base, (s), strlen(s))) - - /* Let's make a very fragmented buffer. */ - buf = evbuffer_new(); - tmp_buf = evbuffer_new(); - for (i = 0; i < 16; ++i) { - evbuffer_add_printf(tmp_buf, "Contents of chunk [%d]\n", i); - evbuffer_add_buffer(buf, tmp_buf); - } - - /* How many chunks do we need for everything? */ - i = evbuffer_peek(buf, -1, NULL, NULL, 0); - tt_int_op(i, ==, 16); - - /* Simple peek: get everything. */ - i = evbuffer_peek(buf, -1, NULL, v, 20); - tt_int_op(i, ==, 16); /* we used only 16 chunks. */ - tt_iov_eq(&v[0], "Contents of chunk [0]\n"); - tt_iov_eq(&v[3], "Contents of chunk [3]\n"); - tt_iov_eq(&v[12], "Contents of chunk [12]\n"); - tt_iov_eq(&v[15], "Contents of chunk [15]\n"); - - /* Just get one chunk worth. */ - memset(v, 0, sizeof(v)); - i = evbuffer_peek(buf, -1, NULL, v, 1); - tt_int_op(i, ==, 1); - tt_iov_eq(&v[0], "Contents of chunk [0]\n"); - tt_assert(v[1].iov_base == NULL); - - /* Suppose we want at least the first 40 bytes. */ - memset(v, 0, sizeof(v)); - i = evbuffer_peek(buf, 40, NULL, v, 16); - tt_int_op(i, ==, 2); - tt_iov_eq(&v[0], "Contents of chunk [0]\n"); - tt_iov_eq(&v[1], "Contents of chunk [1]\n"); - tt_assert(v[2].iov_base == NULL); - - /* How many chunks do we need for 100 bytes? */ - memset(v, 0, sizeof(v)); - i = evbuffer_peek(buf, 100, NULL, NULL, 0); - tt_int_op(i, ==, 5); - tt_assert(v[0].iov_base == NULL); - - /* Now we ask for more bytes than we provide chunks for */ - memset(v, 0, sizeof(v)); - i = evbuffer_peek(buf, 60, NULL, v, 1); - tt_int_op(i, ==, 3); - tt_iov_eq(&v[0], "Contents of chunk [0]\n"); - tt_assert(v[1].iov_base == NULL); - - /* Now we ask for more bytes than the buffer has. */ - memset(v, 0, sizeof(v)); - i = evbuffer_peek(buf, 65536, NULL, v, 20); - tt_int_op(i, ==, 16); /* we used only 16 chunks. */ - tt_iov_eq(&v[0], "Contents of chunk [0]\n"); - tt_iov_eq(&v[3], "Contents of chunk [3]\n"); - tt_iov_eq(&v[12], "Contents of chunk [12]\n"); - tt_iov_eq(&v[15], "Contents of chunk [15]\n"); - tt_assert(v[16].iov_base == NULL); - - /* What happens if we try an empty buffer? */ - memset(v, 0, sizeof(v)); - i = evbuffer_peek(tmp_buf, -1, NULL, v, 20); - tt_int_op(i, ==, 0); - tt_assert(v[0].iov_base == NULL); - memset(v, 0, sizeof(v)); - i = evbuffer_peek(tmp_buf, 50, NULL, v, 20); - tt_int_op(i, ==, 0); - tt_assert(v[0].iov_base == NULL); - - /* Okay, now time to have fun with pointers. */ - memset(v, 0, sizeof(v)); - evbuffer_ptr_set(buf, &ptr, 30, EVBUFFER_PTR_SET); - i = evbuffer_peek(buf, 50, &ptr, v, 20); - tt_int_op(i, ==, 3); - tt_iov_eq(&v[0], " of chunk [1]\n"); - tt_iov_eq(&v[1], "Contents of chunk [2]\n"); - tt_iov_eq(&v[2], "Contents of chunk [3]\n"); /*more than we asked for*/ - - /* advance to the start of another chain. */ - memset(v, 0, sizeof(v)); - evbuffer_ptr_set(buf, &ptr, 14, EVBUFFER_PTR_ADD); - i = evbuffer_peek(buf, 44, &ptr, v, 20); - tt_int_op(i, ==, 2); - tt_iov_eq(&v[0], "Contents of chunk [2]\n"); - tt_iov_eq(&v[1], "Contents of chunk [3]\n"); /*more than we asked for*/ - - /* peek at the end of the buffer */ - memset(v, 0, sizeof(v)); - tt_assert(evbuffer_ptr_set(buf, &ptr, evbuffer_get_length(buf), EVBUFFER_PTR_SET) == 0); - i = evbuffer_peek(buf, 44, &ptr, v, 20); - tt_int_op(i, ==, 0); - tt_assert(v[0].iov_base == NULL); - -end: - if (buf) - evbuffer_free(buf); - if (tmp_buf) - evbuffer_free(tmp_buf); -} - -/* Check whether evbuffer freezing works right. This is called twice, - once with the argument "start" and once with the argument "end". - When we test "start", we freeze the start of an evbuffer and make sure - that modifying the start of the buffer doesn't work. When we test - "end", we freeze the end of an evbuffer and make sure that modifying - the end of the buffer doesn't work. - */ -static void -test_evbuffer_freeze(void *ptr) -{ - struct evbuffer *buf = NULL, *tmp_buf=NULL; - const char string[] = /* Year's End, Richard Wilbur */ - "I've known the wind by water banks to shake\n" - "The late leaves down, which frozen where they fell\n" - "And held in ice as dancers in a spell\n" - "Fluttered all winter long into a lake..."; - const int start = !strcmp(ptr, "start"); - char *cp; - char charbuf[128]; - int r; - size_t orig_length; - struct evbuffer_iovec v[1]; - - if (!start) - tt_str_op(ptr, ==, "end"); - - buf = evbuffer_new(); - tmp_buf = evbuffer_new(); - tt_assert(tmp_buf); - - evbuffer_add(buf, string, strlen(string)); - evbuffer_freeze(buf, start); /* Freeze the start or the end.*/ - -#define FREEZE_EQ(a, startcase, endcase) \ - do { \ - if (start) { \ - tt_int_op((a), ==, (startcase)); \ - } else { \ - tt_int_op((a), ==, (endcase)); \ - } \ - } while (0) - - - orig_length = evbuffer_get_length(buf); - - /* These functions all manipulate the end of buf. */ - r = evbuffer_add(buf, "abc", 0); - FREEZE_EQ(r, 0, -1); - r = evbuffer_reserve_space(buf, 10, v, 1); - FREEZE_EQ(r, 1, -1); - if (r == 1) { - memset(v[0].iov_base, 'X', 10); - v[0].iov_len = 10; - } - r = evbuffer_commit_space(buf, v, 1); - FREEZE_EQ(r, 0, -1); - r = evbuffer_add_reference(buf, string, 5, NULL, NULL); - FREEZE_EQ(r, 0, -1); - r = evbuffer_add_printf(buf, "Hello %s", "world"); - FREEZE_EQ(r, 11, -1); - /* TODO: test add_buffer, add_file, read */ - - if (!start) - tt_int_op(orig_length, ==, evbuffer_get_length(buf)); - - orig_length = evbuffer_get_length(buf); - - /* These functions all manipulate the start of buf. */ - r = evbuffer_remove(buf, charbuf, 1); - FREEZE_EQ(r, -1, 1); - r = evbuffer_drain(buf, 3); - FREEZE_EQ(r, -1, 0); - r = evbuffer_prepend(buf, "dummy", 5); - FREEZE_EQ(r, -1, 0); - cp = evbuffer_readln(buf, NULL, EVBUFFER_EOL_LF); - FREEZE_EQ(cp==NULL, 1, 0); - if (cp) - free(cp); - /* TODO: Test remove_buffer, add_buffer, write, prepend_buffer */ - - if (start) - tt_int_op(orig_length, ==, evbuffer_get_length(buf)); - -end: - if (buf) - evbuffer_free(buf); - - if (tmp_buf) - evbuffer_free(tmp_buf); -} - -static void -test_evbuffer_add_iovec(void * ptr) -{ - struct evbuffer * buf = NULL; - struct evbuffer_iovec vec[4]; - const char * data[] = { - "Guilt resembles a sword with two edges.", - "On the one hand, it cuts for Justice, imposing practical morality upon those who fear it.", - "Conscience does not always adhere to rational judgment.", - "Guilt is always a self-imposed burden, but it is not always rightly imposed." - /* -- R.A. Salvatore, _Sojurn_ */ - }; - size_t expected_length = 0; - size_t returned_length = 0; - int i; - - buf = evbuffer_new(); - - tt_assert(buf); - - for (i = 0; i < 4; i++) { - vec[i].iov_len = strlen(data[i]); - vec[i].iov_base = (char*) data[i]; - expected_length += vec[i].iov_len; - } - - returned_length = evbuffer_add_iovec(buf, vec, 4); - - tt_int_op(returned_length, ==, evbuffer_get_length(buf)); - tt_int_op(evbuffer_get_length(buf), ==, expected_length); - - for (i = 0; i < 4; i++) { - char charbuf[1024]; - - memset(charbuf, 0, 1024); - evbuffer_remove(buf, charbuf, strlen(data[i])); - tt_assert(strcmp(charbuf, data[i]) == 0); - } - - tt_assert(evbuffer_get_length(buf) == 0); -end: - if (buf) { - evbuffer_free(buf); - } -} - -static void -test_evbuffer_copyout(void *dummy) -{ - const char string[] = - "Still they skirmish to and fro, men my messmates on the snow " - "When we headed off the aurochs turn for turn; " - "When the rich Allobrogenses never kept amanuenses, " - "And our only plots were piled in lakes at Berne."; - /* -- Kipling, "In The Neolithic Age" */ - char tmp[1024]; - struct evbuffer_ptr ptr; - struct evbuffer *buf; - - (void)dummy; - - buf = evbuffer_new(); - tt_assert(buf); - - tt_int_op(strlen(string), ==, 206); - - /* Ensure separate chains */ - evbuffer_add_reference(buf, string, 80, no_cleanup, NULL); - evbuffer_add_reference(buf, string+80, 80, no_cleanup, NULL); - evbuffer_add(buf, string+160, strlen(string)-160); - - tt_int_op(206, ==, evbuffer_get_length(buf)); - - /* First, let's test plain old copyout. */ - - /* Copy a little from the beginning. */ - tt_int_op(10, ==, evbuffer_copyout(buf, tmp, 10)); - tt_int_op(0, ==, memcmp(tmp, "Still they", 10)); - - /* Now copy more than a little from the beginning */ - memset(tmp, 0, sizeof(tmp)); - tt_int_op(100, ==, evbuffer_copyout(buf, tmp, 100)); - tt_int_op(0, ==, memcmp(tmp, string, 100)); - - /* Copy too much; ensure truncation. */ - memset(tmp, 0, sizeof(tmp)); - tt_int_op(206, ==, evbuffer_copyout(buf, tmp, 230)); - tt_int_op(0, ==, memcmp(tmp, string, 206)); - - /* That was supposed to be nondestructive, btw */ - tt_int_op(206, ==, evbuffer_get_length(buf)); - - /* Now it's time to test copyout_from! First, let's start in the - * first chain. */ - evbuffer_ptr_set(buf, &ptr, 15, EVBUFFER_PTR_SET); - memset(tmp, 0, sizeof(tmp)); - tt_int_op(10, ==, evbuffer_copyout_from(buf, &ptr, tmp, 10)); - tt_int_op(0, ==, memcmp(tmp, "mish to an", 10)); - - /* Right up to the end of the first chain */ - memset(tmp, 0, sizeof(tmp)); - tt_int_op(65, ==, evbuffer_copyout_from(buf, &ptr, tmp, 65)); - tt_int_op(0, ==, memcmp(tmp, string+15, 65)); - - /* Span into the second chain */ - memset(tmp, 0, sizeof(tmp)); - tt_int_op(90, ==, evbuffer_copyout_from(buf, &ptr, tmp, 90)); - tt_int_op(0, ==, memcmp(tmp, string+15, 90)); - - /* Span into the third chain */ - memset(tmp, 0, sizeof(tmp)); - tt_int_op(160, ==, evbuffer_copyout_from(buf, &ptr, tmp, 160)); - tt_int_op(0, ==, memcmp(tmp, string+15, 160)); - - /* Overrun */ - memset(tmp, 0, sizeof(tmp)); - tt_int_op(206-15, ==, evbuffer_copyout_from(buf, &ptr, tmp, 999)); - tt_int_op(0, ==, memcmp(tmp, string+15, 206-15)); - - /* That was supposed to be nondestructive, too */ - tt_int_op(206, ==, evbuffer_get_length(buf)); - -end: - if (buf) - evbuffer_free(buf); -} - -static void * -setup_passthrough(const struct testcase_t *testcase) -{ - return testcase->setup_data; -} -static int -cleanup_passthrough(const struct testcase_t *testcase, void *ptr) -{ - (void) ptr; - return 1; -} - -static const struct testcase_setup_t nil_setup = { - setup_passthrough, - cleanup_passthrough -}; - -struct testcase_t evbuffer_testcases[] = { - { "evbuffer", test_evbuffer, 0, NULL, NULL }, - { "remove_buffer_with_empty", test_evbuffer_remove_buffer_with_empty, 0, NULL, NULL }, - { "reserve2", test_evbuffer_reserve2, 0, NULL, NULL }, - { "reserve_many", test_evbuffer_reserve_many, 0, NULL, NULL }, - { "reserve_many2", test_evbuffer_reserve_many, 0, &nil_setup, (void*)"add" }, - { "reserve_many3", test_evbuffer_reserve_many, 0, &nil_setup, (void*)"fill" }, - { "expand", test_evbuffer_expand, 0, NULL, NULL }, - { "reference", test_evbuffer_reference, 0, NULL, NULL }, - { "iterative", test_evbuffer_iterative, 0, NULL, NULL }, - { "readln", test_evbuffer_readln, TT_NO_LOGS, &basic_setup, NULL }, - { "search_eol", test_evbuffer_search_eol, 0, NULL, NULL }, - { "find", test_evbuffer_find, 0, NULL, NULL }, - { "ptr_set", test_evbuffer_ptr_set, 0, NULL, NULL }, - { "search", test_evbuffer_search, 0, NULL, NULL }, - { "callbacks", test_evbuffer_callbacks, 0, NULL, NULL }, - { "add_reference", test_evbuffer_add_reference, 0, NULL, NULL }, - { "multicast", test_evbuffer_multicast, 0, NULL, NULL }, - { "multicast_drain", test_evbuffer_multicast_drain, 0, NULL, NULL }, - { "prepend", test_evbuffer_prepend, TT_FORK, NULL, NULL }, - { "peek", test_evbuffer_peek, 0, NULL, NULL }, - { "peek_first_gt", test_evbuffer_peek_first_gt, 0, NULL, NULL }, - { "freeze_start", test_evbuffer_freeze, 0, &nil_setup, (void*)"start" }, - { "freeze_end", test_evbuffer_freeze, 0, &nil_setup, (void*)"end" }, - { "add_iovec", test_evbuffer_add_iovec, 0, NULL, NULL}, - { "copyout", test_evbuffer_copyout, 0, NULL, NULL}, - { "file_segment_add_cleanup_cb", test_evbuffer_file_segment_add_cleanup_cb, 0, NULL, NULL }, - -#define ADDFILE_TEST(name, parameters) \ - { name, test_evbuffer_add_file, TT_FORK|TT_NEED_BASE, \ - &basic_setup, (void*)(parameters) } - -#define ADDFILE_TEST_GROUP(name, parameters) \ - ADDFILE_TEST(name "_sendfile", "sendfile " parameters), \ - ADDFILE_TEST(name "_mmap", "mmap " parameters), \ - ADDFILE_TEST(name "_linear", "linear " parameters) - - ADDFILE_TEST_GROUP("add_file", ""), - ADDFILE_TEST("add_file_nosegment", "default nosegment"), - - ADDFILE_TEST_GROUP("add_big_file", "bigfile"), - ADDFILE_TEST("add_big_file_nosegment", "default nosegment bigfile"), - - ADDFILE_TEST_GROUP("add_file_offset", "bigfile map_offset"), - ADDFILE_TEST("add_file_offset_nosegment", - "default nosegment bigfile map_offset"), - - ADDFILE_TEST_GROUP("add_file_offset2", "bigfile offset_in_segment"), - - ADDFILE_TEST_GROUP("add_file_offset3", - "bigfile offset_in_segment map_offset"), - - END_OF_TESTCASES -}; diff --git a/protocols/Telegram/tgl/libevent/test/regress_buffer.obj b/protocols/Telegram/tgl/libevent/test/regress_buffer.obj Binary files differdeleted file mode 100644 index a2db69f000..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress_buffer.obj +++ /dev/null diff --git a/protocols/Telegram/tgl/libevent/test/regress_bufferevent.c b/protocols/Telegram/tgl/libevent/test/regress_bufferevent.c deleted file mode 100644 index 68e6876405..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress_bufferevent.c +++ /dev/null @@ -1,1284 +0,0 @@ -/* - * Copyright (c) 2003-2007 Niels Provos <provos@citi.umich.edu> - * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "util-internal.h" - -/* The old tests here need assertions to work. */ -#undef NDEBUG - -#ifdef _WIN32 -#include <winsock2.h> -#include <windows.h> -#endif - -#include "event2/event-config.h" - -#include <sys/types.h> -#include <sys/stat.h> -#ifdef EVENT__HAVE_SYS_TIME_H -#include <sys/time.h> -#endif -#include <sys/queue.h> -#ifndef _WIN32 -#include <sys/socket.h> -#include <sys/wait.h> -#include <signal.h> -#include <unistd.h> -#include <netdb.h> -#include <netinet/in.h> -#endif -#include <fcntl.h> -#include <signal.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#ifdef EVENT__HAVE_ARPA_INET_H -#include <arpa/inet.h> -#endif - -#include "event2/event-config.h" -#include "event2/event.h" -#include "event2/event_struct.h" -#include "event2/event_compat.h" -#include "event2/tag.h" -#include "event2/buffer.h" -#include "event2/bufferevent.h" -#include "event2/bufferevent_compat.h" -#include "event2/bufferevent_struct.h" -#include "event2/listener.h" -#include "event2/util.h" - -#include "bufferevent-internal.h" -#include "evthread-internal.h" -#include "util-internal.h" -#ifdef _WIN32 -#include "iocp-internal.h" -#endif - -#include "regress.h" -#include "regress_testutils.h" - -/* - * simple bufferevent test - */ - -static void -readcb(struct bufferevent *bev, void *arg) -{ - if (evbuffer_get_length(bev->input) == 8333) { - struct evbuffer *evbuf = evbuffer_new(); - assert(evbuf != NULL); - - /* gratuitous test of bufferevent_read_buffer */ - bufferevent_read_buffer(bev, evbuf); - - bufferevent_disable(bev, EV_READ); - - if (evbuffer_get_length(evbuf) == 8333) { - test_ok++; - } - - evbuffer_free(evbuf); - } -} - -static void -writecb(struct bufferevent *bev, void *arg) -{ - if (evbuffer_get_length(bev->output) == 0) { - test_ok++; - } -} - -static void -errorcb(struct bufferevent *bev, short what, void *arg) -{ - test_ok = -2; -} - -static void -test_bufferevent_impl(int use_pair, int flush) -{ - struct bufferevent *bev1 = NULL, *bev2 = NULL; - char buffer[8333]; - int i; - int expected = 2; - - if (use_pair) { - struct bufferevent *pair[2]; - tt_assert(0 == bufferevent_pair_new(NULL, 0, pair)); - bev1 = pair[0]; - 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_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_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); - } - - { - /* Test getcb. */ - bufferevent_data_cb r, w; - bufferevent_event_cb e; - void *a; - bufferevent_getcb(bev1, &r, &w, &e, &a); - tt_ptr_op(r, ==, readcb); - tt_ptr_op(w, ==, writecb); - tt_ptr_op(e, ==, errorcb); - tt_ptr_op(a, ==, use_pair ? bev1 : NULL); - } - - bufferevent_disable(bev1, EV_READ); - bufferevent_enable(bev2, EV_READ); - - tt_int_op(bufferevent_get_enabled(bev1), ==, EV_WRITE); - tt_int_op(bufferevent_get_enabled(bev2), ==, EV_WRITE|EV_READ); - - for (i = 0; i < (int)sizeof(buffer); i++) - buffer[i] = i; - - bufferevent_write(bev1, buffer, sizeof(buffer)); - if (flush >= 0) { - tt_int_op(bufferevent_flush(bev1, EV_WRITE, flush), >=, 0); - } - - event_dispatch(); - - bufferevent_free(bev2); - tt_ptr_op(bufferevent_pair_get_partner(bev1), ==, NULL); - bufferevent_free(bev1); - - /** Only pair call errorcb for BEV_FINISHED */ - if (use_pair && flush == BEV_FINISHED) { - expected = -1; - } - if (test_ok != expected) - test_ok = 0; -end: - ; -} - -static void test_bufferevent(void) { test_bufferevent_impl(0, -1); } -static void test_bufferevent_pair(void) { test_bufferevent_impl(1, -1); } - -static void test_bufferevent_flush_normal(void) { test_bufferevent_impl(0, BEV_NORMAL); } -static void test_bufferevent_flush_flush(void) { test_bufferevent_impl(0, BEV_FLUSH); } -static void test_bufferevent_flush_finished(void) { test_bufferevent_impl(0, BEV_FINISHED); } - -static void test_bufferevent_pair_flush_normal(void) { test_bufferevent_impl(1, BEV_NORMAL); } -static void test_bufferevent_pair_flush_flush(void) { test_bufferevent_impl(1, BEV_FLUSH); } -static void test_bufferevent_pair_flush_finished(void) { test_bufferevent_impl(1, BEV_FINISHED); } - -#if defined(EVTHREAD_USE_PTHREADS_IMPLEMENTED) -/** - * Trace lock/unlock/alloc/free for locks. - * (More heavier then evthread_debug*) - */ -typedef struct -{ - void *lock; - enum { - ALLOC, FREE, - } status; - size_t locked /** allow recursive locking */; -} lock_wrapper; -struct lock_unlock_base -{ - /* Original callbacks */ - struct evthread_lock_callbacks cbs; - /* Map of locks */ - lock_wrapper *locks; - size_t nr_locks; -} lu_base = { - .locks = NULL, -}; - -static lock_wrapper *lu_find(void *lock_) -{ - size_t i; - for (i = 0; i < lu_base.nr_locks; ++i) { - lock_wrapper *lock = &lu_base.locks[i]; - if (lock->lock == lock_) - return lock; - } - return NULL; -} - -static void *trace_lock_alloc(unsigned locktype) -{ - void *lock; - ++lu_base.nr_locks; - lu_base.locks = realloc(lu_base.locks, - sizeof(lock_wrapper) * lu_base.nr_locks); - lock = lu_base.cbs.alloc(locktype); - lu_base.locks[lu_base.nr_locks - 1] = (lock_wrapper){ lock, ALLOC, 0 }; - return lock; -} -static void trace_lock_free(void *lock_, unsigned locktype) -{ - lock_wrapper *lock = lu_find(lock_); - if (!lock || lock->status == FREE || lock->locked) { - TT_FAIL(("lock: free error")); - } else { - lock->status = FREE; - lu_base.cbs.free(lock_, locktype); - } -} -static int trace_lock_lock(unsigned mode, void *lock_) -{ - lock_wrapper *lock = lu_find(lock_); - if (!lock || lock->status == FREE) { - TT_FAIL(("lock: lock error")); - return -1; - } else { - ++lock->locked; - return lu_base.cbs.lock(mode, lock_); - } -} -static int trace_lock_unlock(unsigned mode, void *lock_) -{ - lock_wrapper *lock = lu_find(lock_); - if (!lock || lock->status == FREE || !lock->locked) { - TT_FAIL(("lock: unlock error")); - return -1; - } else { - --lock->locked; - return lu_base.cbs.unlock(mode, lock_); - } -} -static void lock_unlock_free_thread_cbs(void) -{ - event_base_free(NULL); - - if (libevent_tests_running_in_debug_mode) - libevent_global_shutdown(); - - /** drop immutable flag */ - evthread_set_lock_callbacks(NULL); - /** avoid calling of event_global_setup_locks_() for new cbs */ - libevent_global_shutdown(); - /** drop immutable flag for non-debug ops (since called after shutdown) */ - evthread_set_lock_callbacks(NULL); -} - -static int use_lock_unlock_profiler(void) -{ - struct evthread_lock_callbacks cbs = { - EVTHREAD_LOCK_API_VERSION, - EVTHREAD_LOCKTYPE_RECURSIVE, - trace_lock_alloc, - trace_lock_free, - trace_lock_lock, - trace_lock_unlock, - }; - memcpy(&lu_base.cbs, evthread_get_lock_callbacks(), - sizeof(lu_base.cbs)); - { - lock_unlock_free_thread_cbs(); - - evthread_set_lock_callbacks(&cbs); - /** re-create debug locks correctly */ - evthread_enable_lock_debugging(); - - event_init(); - } - return 0; -} -static void free_lock_unlock_profiler(struct basic_test_data *data) -{ - /** fix "held_by" for kqueue */ - evthread_set_lock_callbacks(NULL); - - lock_unlock_free_thread_cbs(); - free(lu_base.locks); - data->base = NULL; -} - -static void test_bufferevent_pair_release_lock(void *arg) -{ - struct basic_test_data *data = arg; - use_lock_unlock_profiler(); - { - struct bufferevent *pair[2]; - if (!bufferevent_pair_new(NULL, BEV_OPT_THREADSAFE, pair)) { - bufferevent_free(pair[0]); - bufferevent_free(pair[1]); - } else - tt_abort_perror("bufferevent_pair_new"); - } - free_lock_unlock_profiler(data); -end: - ; -} -#endif - -/* - * test watermarks and bufferevent - */ - -static void -wm_readcb(struct bufferevent *bev, void *arg) -{ - struct evbuffer *evbuf = evbuffer_new(); - int len = (int)evbuffer_get_length(bev->input); - static int nread; - - assert(len >= 10 && len <= 20); - - assert(evbuf != NULL); - - /* gratuitous test of bufferevent_read_buffer */ - bufferevent_read_buffer(bev, evbuf); - - nread += len; - if (nread == 65000) { - bufferevent_disable(bev, EV_READ); - test_ok++; - } - - evbuffer_free(evbuf); -} - -static void -wm_writecb(struct bufferevent *bev, void *arg) -{ - assert(evbuffer_get_length(bev->output) <= 100); - if (evbuffer_get_length(bev->output) == 0) { - evbuffer_drain(bev->output, evbuffer_get_length(bev->output)); - test_ok++; - } -} - -static void -wm_errorcb(struct bufferevent *bev, short what, void *arg) -{ - test_ok = -2; -} - -static void -test_bufferevent_watermarks_impl(int use_pair) -{ - struct bufferevent *bev1 = NULL, *bev2 = NULL; - char buffer[65000]; - size_t low, high; - int i; - test_ok = 0; - - if (use_pair) { - struct bufferevent *pair[2]; - tt_assert(0 == bufferevent_pair_new(NULL, 0, pair)); - bev1 = pair[0]; - bev2 = pair[1]; - bufferevent_setcb(bev1, NULL, wm_writecb, errorcb, NULL); - bufferevent_setcb(bev2, wm_readcb, NULL, errorcb, NULL); - } else { - bev1 = bufferevent_new(pair[0], NULL, wm_writecb, wm_errorcb, NULL); - bev2 = bufferevent_new(pair[1], wm_readcb, NULL, wm_errorcb, NULL); - } - tt_assert(bev1); - tt_assert(bev2); - bufferevent_disable(bev1, EV_READ); - bufferevent_enable(bev2, EV_READ); - - /* By default, low watermarks are set to 0 */ - bufferevent_getwatermark(bev1, EV_READ, &low, NULL); - tt_int_op(low, ==, 0); - bufferevent_getwatermark(bev2, EV_WRITE, &low, NULL); - tt_int_op(low, ==, 0); - - for (i = 0; i < (int)sizeof(buffer); i++) - buffer[i] = (char)i; - - /* limit the reading on the receiving bufferevent */ - bufferevent_setwatermark(bev2, EV_READ, 10, 20); - - bufferevent_getwatermark(bev2, EV_READ, &low, &high); - tt_int_op(low, ==, 10); - tt_int_op(high, ==, 20); - - /* Tell the sending bufferevent not to notify us till it's down to - 100 bytes. */ - bufferevent_setwatermark(bev1, EV_WRITE, 100, 2000); - - bufferevent_getwatermark(bev1, EV_WRITE, &low, &high); - tt_int_op(low, ==, 100); - tt_int_op(high, ==, 2000); - - { - int r = bufferevent_getwatermark(bev1, EV_WRITE | EV_READ, &low, &high); - tt_int_op(r, !=, 0); - } - - bufferevent_write(bev1, buffer, sizeof(buffer)); - - event_dispatch(); - - tt_int_op(test_ok, ==, 2); - - /* The write callback drained all the data from outbuf, so we - * should have removed the write event... */ - tt_assert(!event_pending(&bev2->ev_write, EV_WRITE, NULL)); - -end: - if (bev1) - bufferevent_free(bev1); - if (bev2) - bufferevent_free(bev2); -} - -static void -test_bufferevent_watermarks(void) -{ - test_bufferevent_watermarks_impl(0); -} - -static void -test_bufferevent_pair_watermarks(void) -{ - test_bufferevent_watermarks_impl(1); -} - -/* - * Test bufferevent filters - */ - -/* strip an 'x' from each byte */ - -static enum bufferevent_filter_result -bufferevent_input_filter(struct evbuffer *src, struct evbuffer *dst, - ev_ssize_t lim, enum bufferevent_flush_mode state, void *ctx) -{ - const unsigned char *buffer; - unsigned i; - - buffer = evbuffer_pullup(src, evbuffer_get_length(src)); - for (i = 0; i < evbuffer_get_length(src); i += 2) { - assert(buffer[i] == 'x'); - evbuffer_add(dst, buffer + i + 1, 1); - - if (i + 2 > evbuffer_get_length(src)) - break; - } - - evbuffer_drain(src, i); - return (BEV_OK); -} - -/* add an 'x' before each byte */ - -static enum bufferevent_filter_result -bufferevent_output_filter(struct evbuffer *src, struct evbuffer *dst, - ev_ssize_t lim, enum bufferevent_flush_mode state, void *ctx) -{ - const unsigned char *buffer; - unsigned i; - - buffer = evbuffer_pullup(src, evbuffer_get_length(src)); - for (i = 0; i < evbuffer_get_length(src); ++i) { - evbuffer_add(dst, "x", 1); - evbuffer_add(dst, buffer + i, 1); - } - - evbuffer_drain(src, evbuffer_get_length(src)); - return (BEV_OK); -} - -static void -test_bufferevent_filters_impl(int use_pair) -{ - struct bufferevent *bev1 = NULL, *bev2 = NULL; - struct bufferevent *bev1_base = NULL, *bev2_base = NULL; - char buffer[8333]; - int i; - - test_ok = 0; - - if (use_pair) { - struct bufferevent *pair[2]; - tt_assert(0 == bufferevent_pair_new(NULL, 0, pair)); - bev1 = pair[0]; - bev2 = pair[1]; - } else { - bev1 = bufferevent_socket_new(NULL, pair[0], 0); - bev2 = bufferevent_socket_new(NULL, pair[1], 0); - } - bev1_base = bev1; - bev2_base = bev2; - - for (i = 0; i < (int)sizeof(buffer); i++) - buffer[i] = i; - - bev1 = bufferevent_filter_new(bev1, NULL, bufferevent_output_filter, - BEV_OPT_CLOSE_ON_FREE, NULL, NULL); - - bev2 = bufferevent_filter_new(bev2, bufferevent_input_filter, - NULL, BEV_OPT_CLOSE_ON_FREE, NULL, NULL); - bufferevent_setcb(bev1, NULL, writecb, errorcb, NULL); - bufferevent_setcb(bev2, readcb, NULL, errorcb, NULL); - - 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); - - bufferevent_disable(bev1, EV_READ); - bufferevent_enable(bev2, EV_READ); - /* insert some filters */ - bufferevent_write(bev1, buffer, sizeof(buffer)); - - event_dispatch(); - - if (test_ok != 2) - test_ok = 0; - -end: - if (bev1) - bufferevent_free(bev1); - if (bev2) - bufferevent_free(bev2); - -} - -static void -test_bufferevent_filters(void) -{ - test_bufferevent_filters_impl(0); -} - -static void -test_bufferevent_pair_filters(void) -{ - test_bufferevent_filters_impl(1); -} - - -static void -sender_writecb(struct bufferevent *bev, void *ctx) -{ - if (evbuffer_get_length(bufferevent_get_output(bev)) == 0) { - bufferevent_disable(bev,EV_READ|EV_WRITE); - TT_BLATHER(("Flushed %d: freeing it.", (int)bufferevent_getfd(bev))); - bufferevent_free(bev); - } -} - -static void -sender_errorcb(struct bufferevent *bev, short what, void *ctx) -{ - TT_FAIL(("Got sender error %d",(int)what)); -} - -static int bufferevent_connect_test_flags = 0; -static int bufferevent_trigger_test_flags = 0; -static int n_strings_read = 0; -static int n_reads_invoked = 0; -static int n_events_invoked = 0; - -#define TEST_STR "Now is the time for all good events to signal for " \ - "the good of their protocol" -static void -listen_cb(struct evconnlistener *listener, evutil_socket_t fd, - struct sockaddr *sa, int socklen, void *arg) -{ - struct event_base *base = arg; - struct bufferevent *bev; - const char s[] = TEST_STR; - TT_BLATHER(("Got a request on socket %d", (int)fd )); - bev = bufferevent_socket_new(base, fd, bufferevent_connect_test_flags); - tt_assert(bev); - bufferevent_setcb(bev, NULL, sender_writecb, sender_errorcb, NULL); - bufferevent_write(bev, s, sizeof(s)); -end: - ; -} - -static int -fake_listener_create(struct sockaddr_in *localhost) -{ - struct sockaddr *sa = (struct sockaddr *)localhost; - evutil_socket_t fd = -1; - ev_socklen_t slen = sizeof(*localhost); - - memset(localhost, 0, sizeof(*localhost)); - localhost->sin_port = 0; /* have the kernel pick a port */ - localhost->sin_addr.s_addr = htonl(0x7f000001L); - localhost->sin_family = AF_INET; - - /* bind, but don't listen or accept. should trigger - "Connection refused" reliably on most platforms. */ - fd = socket(localhost->sin_family, SOCK_STREAM, 0); - tt_assert(fd >= 0); - tt_assert(bind(fd, sa, slen) == 0); - tt_assert(getsockname(fd, sa, &slen) == 0); - - return fd; - -end: - return -1; -} - -static void -reader_eventcb(struct bufferevent *bev, short what, void *ctx) -{ - struct event_base *base = ctx; - if (what & BEV_EVENT_ERROR) { - perror("foobar"); - TT_FAIL(("got connector error %d", (int)what)); - return; - } - if (what & BEV_EVENT_CONNECTED) { - TT_BLATHER(("connected on %d", (int)bufferevent_getfd(bev))); - bufferevent_enable(bev, EV_READ); - } - if (what & BEV_EVENT_EOF) { - char buf[512]; - size_t n; - n = bufferevent_read(bev, buf, sizeof(buf)-1); - tt_int_op(n, >=, 0); - buf[n] = '\0'; - tt_str_op(buf, ==, TEST_STR); - if (++n_strings_read == 2) - event_base_loopexit(base, NULL); - TT_BLATHER(("EOF on %d: %d strings read.", - (int)bufferevent_getfd(bev), n_strings_read)); - } -end: - ; -} - -static void -reader_eventcb_simple(struct bufferevent *bev, short what, void *ctx) -{ - TT_BLATHER(("Read eventcb simple invoked on %d.", - (int)bufferevent_getfd(bev))); - n_events_invoked++; -} - -static void -reader_readcb(struct bufferevent *bev, void *ctx) -{ - TT_BLATHER(("Read invoked on %d.", (int)bufferevent_getfd(bev))); - n_reads_invoked++; -} - -static void -test_bufferevent_connect(void *arg) -{ - struct basic_test_data *data = arg; - struct evconnlistener *lev=NULL; - struct bufferevent *bev1=NULL, *bev2=NULL; - struct sockaddr_in localhost; - struct sockaddr_storage ss; - struct sockaddr *sa; - ev_socklen_t slen; - - int be_flags=BEV_OPT_CLOSE_ON_FREE; - - if (strstr((char*)data->setup_data, "defer")) { - be_flags |= BEV_OPT_DEFER_CALLBACKS; - } - if (strstr((char*)data->setup_data, "unlocked")) { - be_flags |= BEV_OPT_UNLOCK_CALLBACKS; - } - if (strstr((char*)data->setup_data, "lock")) { - be_flags |= BEV_OPT_THREADSAFE; - } - bufferevent_connect_test_flags = be_flags; -#ifdef _WIN32 - if (!strcmp((char*)data->setup_data, "unset_connectex")) { - struct win32_extension_fns *ext = - (struct win32_extension_fns *) - event_get_win32_extension_fns_(); - ext->ConnectEx = NULL; - } -#endif - - memset(&localhost, 0, sizeof(localhost)); - - localhost.sin_port = 0; /* pick-a-port */ - localhost.sin_addr.s_addr = htonl(0x7f000001L); - localhost.sin_family = AF_INET; - sa = (struct sockaddr *)&localhost; - lev = evconnlistener_new_bind(data->base, listen_cb, data->base, - LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, - 16, sa, sizeof(localhost)); - tt_assert(lev); - - sa = (struct sockaddr *)&ss; - slen = sizeof(ss); - if (regress_get_listener_addr(lev, sa, &slen) < 0) { - tt_abort_perror("getsockname"); - } - - tt_assert(!evconnlistener_enable(lev)); - bev1 = bufferevent_socket_new(data->base, -1, be_flags); - bev2 = bufferevent_socket_new(data->base, -1, be_flags); - tt_assert(bev1); - tt_assert(bev2); - bufferevent_setcb(bev1, reader_readcb,NULL, reader_eventcb, data->base); - bufferevent_setcb(bev2, reader_readcb,NULL, reader_eventcb, data->base); - - bufferevent_enable(bev1, EV_READ); - bufferevent_enable(bev2, EV_READ); - - tt_want(!bufferevent_socket_connect(bev1, sa, sizeof(localhost))); - tt_want(!bufferevent_socket_connect(bev2, sa, sizeof(localhost))); - - event_base_dispatch(data->base); - - tt_int_op(n_strings_read, ==, 2); - tt_int_op(n_reads_invoked, >=, 2); -end: - if (lev) - evconnlistener_free(lev); - - if (bev1) - bufferevent_free(bev1); - - if (bev2) - bufferevent_free(bev2); -} - -static void -test_bufferevent_connect_fail_eventcb(void *arg) -{ - struct basic_test_data *data = arg; - int flags = BEV_OPT_CLOSE_ON_FREE | (long)data->setup_data; - struct bufferevent *bev = NULL; - struct evconnlistener *lev = NULL; - struct sockaddr_in localhost; - ev_socklen_t slen = sizeof(localhost); - evutil_socket_t fake_listener = -1; - - fake_listener = fake_listener_create(&localhost); - - tt_int_op(n_events_invoked, ==, 0); - - bev = bufferevent_socket_new(data->base, -1, flags); - tt_assert(bev); - bufferevent_setcb(bev, reader_readcb, reader_readcb, - reader_eventcb_simple, data->base); - bufferevent_enable(bev, EV_READ|EV_WRITE); - tt_int_op(n_events_invoked, ==, 0); - tt_int_op(n_reads_invoked, ==, 0); - /** @see also test_bufferevent_connect_fail() */ - bufferevent_socket_connect(bev, (struct sockaddr *)&localhost, slen); - tt_int_op(n_events_invoked, ==, 0); - tt_int_op(n_reads_invoked, ==, 0); - event_base_dispatch(data->base); - tt_int_op(n_events_invoked, ==, 1); - tt_int_op(n_reads_invoked, ==, 0); - -end: - if (lev) - evconnlistener_free(lev); - if (bev) - bufferevent_free(bev); - if (fake_listener >= 0) - evutil_closesocket(fake_listener); -} - -static void -want_fail_eventcb(struct bufferevent *bev, short what, void *ctx) -{ - struct event_base *base = ctx; - const char *err; - evutil_socket_t s; - - if (what & BEV_EVENT_ERROR) { - s = bufferevent_getfd(bev); - err = evutil_socket_error_to_string(evutil_socket_geterror(s)); - TT_BLATHER(("connection failure on "EV_SOCK_FMT": %s", - EV_SOCK_ARG(s), err)); - test_ok = 1; - } else { - TT_FAIL(("didn't fail? what %hd", what)); - } - - event_base_loopexit(base, NULL); -} - -static void -close_socket_cb(evutil_socket_t fd, short what, void *arg) -{ - evutil_socket_t *fdp = arg; - if (*fdp >= 0) { - evutil_closesocket(*fdp); - *fdp = -1; - } -} - -static void -test_bufferevent_connect_fail(void *arg) -{ - struct basic_test_data *data = (struct basic_test_data *)arg; - struct bufferevent *bev=NULL; - struct event close_listener_event; - int close_listener_event_added = 0; - struct timeval one_second = { 1, 0 }; - struct sockaddr_in localhost; - ev_socklen_t slen = sizeof(localhost); - evutil_socket_t fake_listener = -1; - int r; - - test_ok = 0; - - fake_listener = fake_listener_create(&localhost); - bev = bufferevent_socket_new(data->base, -1, - BEV_OPT_CLOSE_ON_FREE | BEV_OPT_DEFER_CALLBACKS); - tt_assert(bev); - bufferevent_setcb(bev, NULL, NULL, want_fail_eventcb, data->base); - - r = bufferevent_socket_connect(bev, (struct sockaddr *)&localhost, slen); - /* XXXX we'd like to test the '0' case everywhere, but FreeBSD tells - * detects the error immediately, which is not really wrong of it. */ - tt_want(r == 0 || r == -1); - - /* Close the listener socket after a second. This should trigger - "connection refused" on some other platforms, including OSX. */ - evtimer_assign(&close_listener_event, data->base, close_socket_cb, - &fake_listener); - event_add(&close_listener_event, &one_second); - close_listener_event_added = 1; - - event_base_dispatch(data->base); - - tt_int_op(test_ok, ==, 1); - -end: - if (fake_listener >= 0) - evutil_closesocket(fake_listener); - - if (bev) - bufferevent_free(bev); - - if (close_listener_event_added) - event_del(&close_listener_event); -} - -struct timeout_cb_result { - struct timeval read_timeout_at; - struct timeval write_timeout_at; - struct timeval last_wrote_at; - int n_read_timeouts; - int n_write_timeouts; - int total_calls; -}; - -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) -{ - struct timeout_cb_result *res = arg; - ++res->total_calls; - - if ((what & (BEV_EVENT_READING|BEV_EVENT_TIMEOUT)) - == (BEV_EVENT_READING|BEV_EVENT_TIMEOUT)) { - evutil_gettimeofday(&res->read_timeout_at, NULL); - ++res->n_read_timeouts; - } - if ((what & (BEV_EVENT_WRITING|BEV_EVENT_TIMEOUT)) - == (BEV_EVENT_WRITING|BEV_EVENT_TIMEOUT)) { - evutil_gettimeofday(&res->write_timeout_at, NULL); - ++res->n_write_timeouts; - } -} - -static void -test_bufferevent_timeouts(void *arg) -{ - /* "arg" is a string containing "pair" and/or "filter". */ - struct bufferevent *bev1 = NULL, *bev2 = NULL; - struct basic_test_data *data = 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)); - - if (strstr((char*)data->setup_data, "pair")) - use_pair = 1; - if (strstr((char*)data->setup_data, "filter")) - use_filter = 1; - - if (use_pair) { - struct bufferevent *p[2]; - tt_int_op(0, ==, bufferevent_pair_new(data->base, 0, p)); - bev1 = p[0]; - bev2 = p[1]; - } else { - 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); - - if (use_filter) { - struct bufferevent *bevf1, *bevf2; - bevf1 = bufferevent_filter_new(bev1, NULL, NULL, - BEV_OPT_CLOSE_ON_FREE, NULL, NULL); - bevf2 = bufferevent_filter_new(bev2, NULL, NULL, - BEV_OPT_CLOSE_ON_FREE, NULL, NULL); - tt_assert(bevf1); - tt_assert(bevf2); - bev1 = bevf1; - bev2 = bevf2; - } - - /* Do this nice and early. */ - bufferevent_disable(bev2, EV_READ); - - /* bev1 will try to write and read. Both will time out. */ - evutil_gettimeofday(&started_at, NULL); - 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, - 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_enable(bev1, EV_READ|EV_WRITE); - - /* bev2 has nothing to say, and isn't listening. */ - bufferevent_setcb(bev2, NULL, bev_timeout_write_cb, - bev_timeout_event_cb, &res2); - tv_w.tv_sec = tv_r.tv_sec = 0; - tv_w.tv_usec = 200*1000; - tv_r.tv_usec = 100*1000; - bufferevent_set_timeouts(bev2, &tv_r, &tv_w); - bufferevent_enable(bev2, EV_WRITE); - - tv_r.tv_sec = 0; - tv_r.tv_usec = 350000; - - event_base_loopexit(data->base, &tv_r); - event_base_dispatch(data->base); - - /* 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.n_read_timeouts == 1); - tt_want(res1.n_write_timeouts == 1); - - test_timeval_diff_eq(&started_at, &res1.read_timeout_at, 150); - test_timeval_diff_eq(&started_at, &res1.write_timeout_at, 100); - -end: - if (bev1) - bufferevent_free(bev1); - if (bev2) - bufferevent_free(bev2); -} - -static void -trigger_failure_cb(evutil_socket_t fd, short what, void *ctx) -{ - TT_FAIL(("The triggered callback did not fire or the machine is really slow (try increasing timeout).")); -} - -static void -trigger_eventcb(struct bufferevent *bev, short what, void *ctx) -{ - struct event_base *base = ctx; - if (what == ~0) { - TT_BLATHER(("Event successfully triggered.")); - event_base_loopexit(base, NULL); - return; - } - reader_eventcb(bev, what, ctx); -} - -static void -trigger_readcb_triggered(struct bufferevent *bev, void *ctx) -{ - TT_BLATHER(("Read successfully triggered.")); - n_reads_invoked++; - bufferevent_trigger_event(bev, ~0, bufferevent_trigger_test_flags); -} - -static void -trigger_readcb(struct bufferevent *bev, void *ctx) -{ - struct timeval timeout = { 30, 0 }; - struct event_base *base = ctx; - size_t low, high, len; - int expected_reads; - - TT_BLATHER(("Read invoked on %d.", (int)bufferevent_getfd(bev))); - expected_reads = ++n_reads_invoked; - - bufferevent_setcb(bev, trigger_readcb_triggered, NULL, trigger_eventcb, ctx); - - bufferevent_getwatermark(bev, EV_READ, &low, &high); - len = evbuffer_get_length(bufferevent_get_input(bev)); - - bufferevent_setwatermark(bev, EV_READ, len + 1, 0); - bufferevent_trigger(bev, EV_READ, bufferevent_trigger_test_flags); - /* no callback expected */ - tt_int_op(n_reads_invoked, ==, expected_reads); - - if ((bufferevent_trigger_test_flags & BEV_TRIG_DEFER_CALLBACKS) || - (bufferevent_connect_test_flags & BEV_OPT_DEFER_CALLBACKS)) { - /* will be deferred */ - } else { - expected_reads++; - } - - event_base_once(base, -1, EV_TIMEOUT, trigger_failure_cb, NULL, &timeout); - - bufferevent_trigger(bev, EV_READ, - bufferevent_trigger_test_flags | BEV_TRIG_IGNORE_WATERMARKS); - tt_int_op(n_reads_invoked, ==, expected_reads); - - bufferevent_setwatermark(bev, EV_READ, low, high); -end: - ; -} - -static void -test_bufferevent_trigger(void *arg) -{ - struct basic_test_data *data = arg; - struct evconnlistener *lev=NULL; - struct bufferevent *bev=NULL; - struct sockaddr_in localhost; - struct sockaddr_storage ss; - struct sockaddr *sa; - ev_socklen_t slen; - - int be_flags=BEV_OPT_CLOSE_ON_FREE; - int trig_flags=0; - - if (strstr((char*)data->setup_data, "defer")) { - be_flags |= BEV_OPT_DEFER_CALLBACKS; - } - bufferevent_connect_test_flags = be_flags; - - if (strstr((char*)data->setup_data, "postpone")) { - trig_flags |= BEV_TRIG_DEFER_CALLBACKS; - } - bufferevent_trigger_test_flags = trig_flags; - - memset(&localhost, 0, sizeof(localhost)); - - localhost.sin_port = 0; /* pick-a-port */ - localhost.sin_addr.s_addr = htonl(0x7f000001L); - localhost.sin_family = AF_INET; - sa = (struct sockaddr *)&localhost; - lev = evconnlistener_new_bind(data->base, listen_cb, data->base, - LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, - 16, sa, sizeof(localhost)); - tt_assert(lev); - - sa = (struct sockaddr *)&ss; - slen = sizeof(ss); - if (regress_get_listener_addr(lev, sa, &slen) < 0) { - tt_abort_perror("getsockname"); - } - - tt_assert(!evconnlistener_enable(lev)); - bev = bufferevent_socket_new(data->base, -1, be_flags); - tt_assert(bev); - bufferevent_setcb(bev, trigger_readcb, NULL, trigger_eventcb, data->base); - - bufferevent_enable(bev, EV_READ); - - tt_want(!bufferevent_socket_connect(bev, sa, sizeof(localhost))); - - event_base_dispatch(data->base); - - tt_int_op(n_reads_invoked, ==, 2); -end: - if (lev) - evconnlistener_free(lev); - - if (bev) - bufferevent_free(bev); -} - -static void -test_bufferevent_socket_filter_inactive(void *arg) -{ - struct basic_test_data *data = arg; - struct bufferevent *bev = NULL, *bevf = NULL; - - bev = bufferevent_socket_new(data->base, -1, 0); - tt_assert(bev); - bevf = bufferevent_filter_new(bev, NULL, NULL, 0, NULL, NULL); - tt_assert(bevf); - -end: - if (bevf) - bufferevent_free(bevf); - if (bev) - bufferevent_free(bev); -} - - -struct testcase_t bufferevent_testcases[] = { - - LEGACY(bufferevent, TT_ISOLATED), - LEGACY(bufferevent_pair, TT_ISOLATED), - LEGACY(bufferevent_flush_normal, TT_ISOLATED), - LEGACY(bufferevent_flush_flush, TT_ISOLATED), - LEGACY(bufferevent_flush_finished, TT_ISOLATED), - LEGACY(bufferevent_pair_flush_normal, TT_ISOLATED), - LEGACY(bufferevent_pair_flush_flush, TT_ISOLATED), - LEGACY(bufferevent_pair_flush_finished, TT_ISOLATED), -#if defined(EVTHREAD_USE_PTHREADS_IMPLEMENTED) - { "bufferevent_pair_release_lock", test_bufferevent_pair_release_lock, - TT_FORK|TT_ISOLATED|TT_NEED_THREADS|TT_NEED_BASE|TT_LEGACY, - &basic_setup, NULL }, -#endif - LEGACY(bufferevent_watermarks, TT_ISOLATED), - LEGACY(bufferevent_pair_watermarks, TT_ISOLATED), - LEGACY(bufferevent_filters, TT_ISOLATED), - LEGACY(bufferevent_pair_filters, TT_ISOLATED), - { "bufferevent_connect", test_bufferevent_connect, TT_FORK|TT_NEED_BASE, - &basic_setup, (void*)"" }, - { "bufferevent_connect_defer", test_bufferevent_connect, - TT_FORK|TT_NEED_BASE, &basic_setup, (void*)"defer" }, - { "bufferevent_connect_lock", test_bufferevent_connect, - TT_FORK|TT_NEED_BASE|TT_NEED_THREADS, &basic_setup, (void*)"lock" }, - { "bufferevent_connect_lock_defer", test_bufferevent_connect, - TT_FORK|TT_NEED_BASE|TT_NEED_THREADS, &basic_setup, - (void*)"defer lock" }, - { "bufferevent_connect_unlocked_cbs", test_bufferevent_connect, - TT_FORK|TT_NEED_BASE|TT_NEED_THREADS, &basic_setup, - (void*)"lock defer unlocked" }, - { "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*)"" }, - { "bufferevent_timeout_pair", test_bufferevent_timeouts, - TT_FORK|TT_NEED_BASE, &basic_setup, (void*)"pair" }, - { "bufferevent_timeout_filter", test_bufferevent_timeouts, - TT_FORK|TT_NEED_BASE, &basic_setup, (void*)"filter" }, - { "bufferevent_timeout_filter_pair", test_bufferevent_timeouts, - TT_FORK|TT_NEED_BASE, &basic_setup, (void*)"filter pair" }, - { "bufferevent_trigger", test_bufferevent_trigger, TT_FORK|TT_NEED_BASE, - &basic_setup, (void*)"" }, - { "bufferevent_trigger_defer", test_bufferevent_trigger, - TT_FORK|TT_NEED_BASE, &basic_setup, (void*)"defer" }, - { "bufferevent_trigger_postpone", test_bufferevent_trigger, - TT_FORK|TT_NEED_BASE|TT_NEED_THREADS, &basic_setup, - (void*)"postpone" }, - { "bufferevent_trigger_defer_postpone", test_bufferevent_trigger, - TT_FORK|TT_NEED_BASE|TT_NEED_THREADS, &basic_setup, - (void*)"defer postpone" }, -#ifdef EVENT__HAVE_LIBZ - LEGACY(bufferevent_zlib, TT_ISOLATED), -#else - { "bufferevent_zlib", NULL, TT_SKIP, NULL, NULL }, -#endif - - { "bufferevent_connect_fail_eventcb_defer", - test_bufferevent_connect_fail_eventcb, - TT_FORK|TT_NEED_BASE, &basic_setup, (void*)BEV_OPT_DEFER_CALLBACKS }, - { "bufferevent_connect_fail_eventcb", - test_bufferevent_connect_fail_eventcb, - TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, - - { "bufferevent_socket_filter_inactive", - test_bufferevent_socket_filter_inactive, - TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, - - END_OF_TESTCASES, -}; - -struct testcase_t bufferevent_iocp_testcases[] = { - - LEGACY(bufferevent, TT_ISOLATED|TT_ENABLE_IOCP), - 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), - { "bufferevent_connect", test_bufferevent_connect, - TT_FORK|TT_NEED_BASE|TT_ENABLE_IOCP, &basic_setup, (void*)"" }, - { "bufferevent_connect_defer", test_bufferevent_connect, - TT_FORK|TT_NEED_BASE|TT_ENABLE_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" }, - { "bufferevent_connect_lock_defer", test_bufferevent_connect, - TT_FORK|TT_NEED_BASE|TT_NEED_THREADS|TT_ENABLE_IOCP, &basic_setup, - (void*)"defer lock" }, - { "bufferevent_connect_fail", test_bufferevent_connect_fail, - TT_FORK|TT_NEED_BASE|TT_ENABLE_IOCP, &basic_setup, NULL }, - { "bufferevent_connect_nonblocking", test_bufferevent_connect, - TT_FORK|TT_NEED_BASE|TT_ENABLE_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 }, - { "bufferevent_connect_fail", - test_bufferevent_connect_fail_eventcb, - TT_FORK|TT_NEED_BASE|TT_ENABLE_IOCP, &basic_setup, NULL }, - - END_OF_TESTCASES, -}; diff --git a/protocols/Telegram/tgl/libevent/test/regress_bufferevent.obj b/protocols/Telegram/tgl/libevent/test/regress_bufferevent.obj Binary files differdeleted file mode 100644 index 1142945e51..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress_bufferevent.obj +++ /dev/null diff --git a/protocols/Telegram/tgl/libevent/test/regress_dns.c b/protocols/Telegram/tgl/libevent/test/regress_dns.c deleted file mode 100644 index 1873636245..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress_dns.c +++ /dev/null @@ -1,2151 +0,0 @@ -/* - * Copyright (c) 2003-2007 Niels Provos <provos@citi.umich.edu> - * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "../util-internal.h" - -#ifdef _WIN32 -#include <winsock2.h> -#include <windows.h> -#include <ws2tcpip.h> -#endif - -#include "event2/event-config.h" - -#include <sys/types.h> -#include <sys/stat.h> -#ifdef EVENT__HAVE_SYS_TIME_H -#include <sys/time.h> -#endif -#include <sys/queue.h> -#ifndef _WIN32 -#include <sys/socket.h> -#include <signal.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <unistd.h> -#endif -#ifdef EVENT__HAVE_NETINET_IN6_H -#include <netinet/in6.h> -#endif -#ifdef HAVE_NETDB_H -#include <netdb.h> -#endif -#include <fcntl.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> - -#include "event2/dns.h" -#include "event2/dns_compat.h" -#include "event2/dns_struct.h" -#include "event2/event.h" -#include "event2/event_compat.h" -#include "event2/event_struct.h" -#include "event2/util.h" -#include "event2/listener.h" -#include "event2/bufferevent.h" -#include "log-internal.h" -#include "regress.h" -#include "regress_testutils.h" - -#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) - -static int dns_ok = 0; -static int dns_got_cancel = 0; -static int dns_err = 0; - - -static void -dns_gethostbyname_cb(int result, char type, int count, int ttl, - void *addresses, void *arg) -{ - dns_ok = dns_err = 0; - - if (result == DNS_ERR_TIMEOUT) { - printf("[Timed out] "); - dns_err = result; - goto out; - } - - if (result != DNS_ERR_NONE) { - printf("[Error code %d] ", result); - goto out; - } - - TT_BLATHER(("type: %d, count: %d, ttl: %d: ", type, count, ttl)); - - switch (type) { - case DNS_IPv6_AAAA: { -#if defined(EVENT__HAVE_STRUCT_IN6_ADDR) && defined(EVENT__HAVE_INET_NTOP) && defined(INET6_ADDRSTRLEN) - struct in6_addr *in6_addrs = addresses; - char buf[INET6_ADDRSTRLEN+1]; - int i; - /* a resolution that's not valid does not help */ - if (ttl < 0) - goto out; - for (i = 0; i < count; ++i) { - const char *b = evutil_inet_ntop(AF_INET6, &in6_addrs[i], buf,sizeof(buf)); - if (b) - TT_BLATHER(("%s ", b)); - else - TT_BLATHER(("%s ", strerror(errno))); - } -#endif - break; - } - case DNS_IPv4_A: { - struct in_addr *in_addrs = addresses; - int i; - /* a resolution that's not valid does not help */ - if (ttl < 0) - goto out; - for (i = 0; i < count; ++i) - TT_BLATHER(("%s ", inet_ntoa(in_addrs[i]))); - break; - } - case DNS_PTR: - /* may get at most one PTR */ - if (count != 1) - goto out; - - TT_BLATHER(("%s ", *(char **)addresses)); - break; - default: - goto out; - } - - dns_ok = type; - -out: - if (arg == NULL) - event_loopexit(NULL); - else - event_base_loopexit((struct event_base *)arg, NULL); -} - -static void -dns_gethostbyname(void) -{ - dns_ok = 0; - evdns_resolve_ipv4("www.monkey.org", 0, dns_gethostbyname_cb, NULL); - event_dispatch(); - - tt_int_op(dns_ok, ==, DNS_IPv4_A); - test_ok = dns_ok; -end: - ; -} - -static void -dns_gethostbyname6(void) -{ - dns_ok = 0; - evdns_resolve_ipv6("www.ietf.org", 0, dns_gethostbyname_cb, NULL); - event_dispatch(); - - if (!dns_ok && dns_err == DNS_ERR_TIMEOUT) { - tt_skip(); - } - - tt_int_op(dns_ok, ==, DNS_IPv6_AAAA); - test_ok = 1; -end: - ; -} - -static void -dns_gethostbyaddr(void) -{ - struct in_addr in; - in.s_addr = htonl(0x7f000001ul); /* 127.0.0.1 */ - dns_ok = 0; - evdns_resolve_reverse(&in, 0, dns_gethostbyname_cb, NULL); - event_dispatch(); - - tt_int_op(dns_ok, ==, DNS_PTR); - test_ok = dns_ok; -end: - ; -} - -static void -dns_resolve_reverse(void *ptr) -{ - struct in_addr in; - struct event_base *base = event_base_new(); - struct evdns_base *dns = evdns_base_new(base, 1/* init name servers */); - struct evdns_request *req = NULL; - - tt_assert(base); - tt_assert(dns); - in.s_addr = htonl(0x7f000001ul); /* 127.0.0.1 */ - dns_ok = 0; - - req = evdns_base_resolve_reverse( - dns, &in, 0, dns_gethostbyname_cb, base); - tt_assert(req); - - event_base_dispatch(base); - - tt_int_op(dns_ok, ==, DNS_PTR); - -end: - if (dns) - evdns_base_free(dns, 0); - if (base) - event_base_free(base); -} - -static int n_server_responses = 0; - -static void -dns_server_request_cb(struct evdns_server_request *req, void *data) -{ - int i, r; - const char TEST_ARPA[] = "11.11.168.192.in-addr.arpa"; - const char TEST_IN6[] = - "f.e.f.e." "0.0.0.0." "0.0.0.0." "1.1.1.1." - "a.a.a.a." "0.0.0.0." "0.0.0.0." "0.f.f.f.ip6.arpa"; - - 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; - - struct in_addr ans; - ans.s_addr = htonl(0xc0a80b0bUL); /* 192.168.11.11 */ - if (qtype == EVDNS_TYPE_A && - qclass == EVDNS_CLASS_INET && - !evutil_ascii_strcasecmp(qname, "zz.example.com")) { - r = evdns_server_request_add_a_reply(req, qname, - 1, &ans.s_addr, 12345); - if (r<0) - dns_ok = 0; - } else if (qtype == EVDNS_TYPE_AAAA && - qclass == EVDNS_CLASS_INET && - !evutil_ascii_strcasecmp(qname, "zz.example.com")) { - char addr6[17] = "abcdefghijklmnop"; - r = evdns_server_request_add_aaaa_reply(req, - qname, 1, addr6, 123); - if (r<0) - dns_ok = 0; - } else if (qtype == EVDNS_TYPE_PTR && - qclass == EVDNS_CLASS_INET && - !evutil_ascii_strcasecmp(qname, TEST_ARPA)) { - r = evdns_server_request_add_ptr_reply(req, NULL, - qname, "ZZ.EXAMPLE.COM", 54321); - if (r<0) - dns_ok = 0; - } else if (qtype == EVDNS_TYPE_PTR && - qclass == EVDNS_CLASS_INET && - !evutil_ascii_strcasecmp(qname, TEST_IN6)){ - r = evdns_server_request_add_ptr_reply(req, NULL, - qname, - "ZZ-INET6.EXAMPLE.COM", 54322); - if (r<0) - dns_ok = 0; - } else if (qtype == EVDNS_TYPE_A && - qclass == EVDNS_CLASS_INET && - !evutil_ascii_strcasecmp(qname, "drop.example.com")) { - if (evdns_server_request_drop(req)<0) - dns_ok = 0; - return; - } else { - printf("Unexpected question %d %d \"%s\" ", - qtype, qclass, qname); - dns_ok = 0; - } - } - r = evdns_server_request_respond(req, 0); - if (r<0) { - printf("Couldn't send reply. "); - dns_ok = 0; - } -} - -static void -dns_server_gethostbyname_cb(int result, char type, int count, int ttl, - void *addresses, void *arg) -{ - if (result == DNS_ERR_CANCEL) { - if (arg != (void*)(char*)90909) { - printf("Unexpected cancelation"); - dns_ok = 0; - } - dns_got_cancel = 1; - goto out; - } - if (result != DNS_ERR_NONE) { - printf("Unexpected result %d. ", result); - dns_ok = 0; - goto out; - } - if (count != 1) { - printf("Unexpected answer count %d. ", count); - dns_ok = 0; - goto out; - } - switch (type) { - case DNS_IPv4_A: { - struct in_addr *in_addrs = addresses; - if (in_addrs[0].s_addr != htonl(0xc0a80b0bUL) || ttl != 12345) { - printf("Bad IPv4 response \"%s\" %d. ", - inet_ntoa(in_addrs[0]), ttl); - dns_ok = 0; - goto out; - } - break; - } - case DNS_IPv6_AAAA: { -#if defined (EVENT__HAVE_STRUCT_IN6_ADDR) && defined(EVENT__HAVE_INET_NTOP) && defined(INET6_ADDRSTRLEN) - struct in6_addr *in6_addrs = addresses; - char buf[INET6_ADDRSTRLEN+1]; - if (memcmp(&in6_addrs[0].s6_addr, "abcdefghijklmnop", 16) - || ttl != 123) { - const char *b = evutil_inet_ntop(AF_INET6, &in6_addrs[0],buf,sizeof(buf)); - printf("Bad IPv6 response \"%s\" %d. ", b, ttl); - dns_ok = 0; - goto out; - } -#endif - break; - } - case DNS_PTR: { - char **addrs = addresses; - if (arg != (void*)6) { - if (strcmp(addrs[0], "ZZ.EXAMPLE.COM") || - ttl != 54321) { - printf("Bad PTR response \"%s\" %d. ", - addrs[0], ttl); - dns_ok = 0; - goto out; - } - } else { - if (strcmp(addrs[0], "ZZ-INET6.EXAMPLE.COM") || - ttl != 54322) { - printf("Bad ipv6 PTR response \"%s\" %d. ", - addrs[0], ttl); - dns_ok = 0; - goto out; - } - } - break; - } - default: - printf("Bad response type %d. ", type); - dns_ok = 0; - } - out: - if (++n_server_responses == 3) { - event_loopexit(NULL); - } -} - -static void -dns_server(void) -{ - evutil_socket_t sock=-1; - struct sockaddr_in my_addr; - struct sockaddr_storage ss; - ev_socklen_t slen; - struct evdns_server_port *port=NULL; - struct in_addr resolve_addr; - struct in6_addr resolve_addr6; - struct evdns_base *base=NULL; - struct evdns_request *req=NULL; - - dns_ok = 1; - - base = evdns_base_new(NULL, 0); - - /* Now configure a nameserver port. */ - sock = socket(AF_INET, SOCK_DGRAM, 0); - if (sock<0) { - tt_abort_perror("socket"); - } - - evutil_make_socket_nonblocking(sock); - - memset(&my_addr, 0, sizeof(my_addr)); - my_addr.sin_family = AF_INET; - my_addr.sin_port = 0; /* kernel picks */ - my_addr.sin_addr.s_addr = htonl(0x7f000001UL); - if (bind(sock, (struct sockaddr*)&my_addr, sizeof(my_addr)) < 0) { - tt_abort_perror("bind"); - } - slen = sizeof(ss); - if (getsockname(sock, (struct sockaddr*)&ss, &slen) < 0) { - tt_abort_perror("getsockname"); - } - - port = evdns_add_server_port(sock, 0, dns_server_request_cb, NULL); - - /* Add ourself as the only nameserver, and make sure we really are - * the only nameserver. */ - evdns_base_nameserver_sockaddr_add(base, (struct sockaddr*)&ss, slen, 0); - tt_int_op(evdns_base_count_nameservers(base), ==, 1); - { - struct sockaddr_storage ss2; - int slen2; - - memset(&ss2, 0, sizeof(ss2)); - - slen2 = evdns_base_get_nameserver_addr(base, 0, (struct sockaddr *)&ss2, 3); - tt_int_op(slen2, ==, slen); - tt_int_op(ss2.ss_family, ==, 0); - slen2 = evdns_base_get_nameserver_addr(base, 0, (struct sockaddr *)&ss2, sizeof(ss2)); - tt_int_op(slen2, ==, slen); - tt_mem_op(&ss2, ==, &ss, slen); - - slen2 = evdns_base_get_nameserver_addr(base, 1, (struct sockaddr *)&ss2, sizeof(ss2)); - tt_int_op(-1, ==, slen2); - } - - /* Send some queries. */ - evdns_base_resolve_ipv4(base, "zz.example.com", DNS_QUERY_NO_SEARCH, - dns_server_gethostbyname_cb, NULL); - evdns_base_resolve_ipv6(base, "zz.example.com", DNS_QUERY_NO_SEARCH, - dns_server_gethostbyname_cb, NULL); - resolve_addr.s_addr = htonl(0xc0a80b0bUL); /* 192.168.11.11 */ - evdns_base_resolve_reverse(base, &resolve_addr, 0, - dns_server_gethostbyname_cb, NULL); - memcpy(resolve_addr6.s6_addr, - "\xff\xf0\x00\x00\x00\x00\xaa\xaa" - "\x11\x11\x00\x00\x00\x00\xef\xef", 16); - evdns_base_resolve_reverse_ipv6(base, &resolve_addr6, 0, - dns_server_gethostbyname_cb, (void*)6); - - req = evdns_base_resolve_ipv4(base, - "drop.example.com", DNS_QUERY_NO_SEARCH, - dns_server_gethostbyname_cb, (void*)(char*)90909); - - evdns_cancel_request(base, req); - - event_dispatch(); - - tt_assert(dns_got_cancel); - test_ok = dns_ok; - -end: - if (port) - evdns_close_server_port(port); - if (sock >= 0) - evutil_closesocket(sock); - if (base) - evdns_base_free(base, 0); -} - -static int n_replies_left; -static struct event_base *exit_base; -static struct evdns_server_port *exit_port; - -struct generic_dns_callback_result { - int result; - char type; - int count; - int ttl; - size_t addrs_len; - void *addrs; - char addrs_buf[256]; -}; - -static void -generic_dns_callback(int result, char type, int count, int ttl, void *addresses, - void *arg) -{ - size_t len; - struct generic_dns_callback_result *res = arg; - res->result = result; - res->type = type; - res->count = count; - res->ttl = ttl; - - if (type == DNS_IPv4_A) - len = count * 4; - else if (type == DNS_IPv6_AAAA) - len = count * 16; - else if (type == DNS_PTR) - len = strlen(addresses)+1; - else { - res->addrs_len = len = 0; - res->addrs = NULL; - } - if (len) { - res->addrs_len = len; - if (len > 256) - len = 256; - memcpy(res->addrs_buf, addresses, len); - res->addrs = res->addrs_buf; - } - - --n_replies_left; - if (n_replies_left == 0) { - if (exit_port) { - evdns_close_server_port(exit_port); - exit_port = NULL; - } else - event_base_loopexit(exit_base, NULL); - } -} - -static struct regress_dns_server_table search_table[] = { - { "host.a.example.com", "err", "3", 0, 0 }, - { "host.b.example.com", "err", "3", 0, 0 }, - { "host.c.example.com", "A", "11.22.33.44", 0, 0 }, - { "host2.a.example.com", "err", "3", 0, 0 }, - { "host2.b.example.com", "A", "200.100.0.100", 0, 0 }, - { "host2.c.example.com", "err", "3", 0, 0 }, - { "hostn.a.example.com", "errsoa", "0", 0, 0 }, - { "hostn.b.example.com", "errsoa", "3", 0, 0 }, - { "hostn.c.example.com", "err", "0", 0, 0 }, - - { "host", "err", "3", 0, 0 }, - { "host2", "err", "3", 0, 0 }, - { "*", "err", "3", 0, 0 }, - { NULL, NULL, NULL, 0, 0 } -}; -static void -dns_search_test_impl(void *arg, int lower) -{ - struct regress_dns_server_table table[ARRAY_SIZE(search_table)]; - struct basic_test_data *data = arg; - struct event_base *base = data->base; - struct evdns_base *dns = NULL; - ev_uint16_t portnum = 0; - char buf[64]; - - struct generic_dns_callback_result r[8]; - size_t i; - - for (i = 0; i < ARRAY_SIZE(table); ++i) { - table[i] = search_table[i]; - table[i].lower = lower; - } - - tt_assert(regress_dnsserver(base, &portnum, table)); - evutil_snprintf(buf, sizeof(buf), "127.0.0.1:%d", (int)portnum); - - dns = evdns_base_new(base, 0); - tt_assert(!evdns_base_nameserver_ip_add(dns, buf)); - - evdns_base_search_add(dns, "a.example.com"); - evdns_base_search_add(dns, "b.example.com"); - evdns_base_search_add(dns, "c.example.com"); - - n_replies_left = ARRAY_SIZE(r); - exit_base = base; - - evdns_base_resolve_ipv4(dns, "host", 0, generic_dns_callback, &r[0]); - evdns_base_resolve_ipv4(dns, "host2", 0, generic_dns_callback, &r[1]); - evdns_base_resolve_ipv4(dns, "host", DNS_NO_SEARCH, generic_dns_callback, &r[2]); - evdns_base_resolve_ipv4(dns, "host2", DNS_NO_SEARCH, generic_dns_callback, &r[3]); - evdns_base_resolve_ipv4(dns, "host3", 0, generic_dns_callback, &r[4]); - evdns_base_resolve_ipv4(dns, "hostn.a.example.com", DNS_NO_SEARCH, generic_dns_callback, &r[5]); - evdns_base_resolve_ipv4(dns, "hostn.b.example.com", DNS_NO_SEARCH, generic_dns_callback, &r[6]); - evdns_base_resolve_ipv4(dns, "hostn.c.example.com", DNS_NO_SEARCH, generic_dns_callback, &r[7]); - - event_base_dispatch(base); - - tt_int_op(r[0].type, ==, DNS_IPv4_A); - tt_int_op(r[0].count, ==, 1); - tt_int_op(((ev_uint32_t*)r[0].addrs)[0], ==, htonl(0x0b16212c)); - tt_int_op(r[1].type, ==, DNS_IPv4_A); - tt_int_op(r[1].count, ==, 1); - tt_int_op(((ev_uint32_t*)r[1].addrs)[0], ==, htonl(0xc8640064)); - tt_int_op(r[2].result, ==, DNS_ERR_NOTEXIST); - tt_int_op(r[3].result, ==, DNS_ERR_NOTEXIST); - tt_int_op(r[4].result, ==, DNS_ERR_NOTEXIST); - tt_int_op(r[5].result, ==, DNS_ERR_NODATA); - tt_int_op(r[5].ttl, ==, 42); - tt_int_op(r[6].result, ==, DNS_ERR_NOTEXIST); - tt_int_op(r[6].ttl, ==, 42); - tt_int_op(r[7].result, ==, DNS_ERR_NODATA); - tt_int_op(r[7].ttl, ==, 0); - -end: - if (dns) - evdns_base_free(dns, 0); - - regress_clean_dnsserver(); -} -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 int request_count = 0; -static struct evdns_request *current_req = NULL; - -static void -search_cancel_server_cb(struct evdns_server_request *req, void *data) -{ - const char *question; - - if (req->nquestions != 1) - TT_DIE(("Only handling one question at a time; got %d", - req->nquestions)); - - question = req->questions[0]->name; - - TT_BLATHER(("got question, %s", question)); - - tt_assert(request_count > 0); - tt_assert(!evdns_server_request_respond(req, 3)); - - if (!--request_count) - evdns_cancel_request(NULL, current_req); - -end: - ; -} - -static void -dns_search_cancel_test(void *arg) -{ - struct basic_test_data *data = arg; - struct event_base *base = data->base; - struct evdns_base *dns = NULL; - struct evdns_server_port *port = NULL; - ev_uint16_t portnum = 0; - struct generic_dns_callback_result r1; - char buf[64]; - - port = regress_get_dnsserver(base, &portnum, NULL, - search_cancel_server_cb, NULL); - tt_assert(port); - evutil_snprintf(buf, sizeof(buf), "127.0.0.1:%d", (int)portnum); - - dns = evdns_base_new(base, 0); - tt_assert(!evdns_base_nameserver_ip_add(dns, buf)); - - evdns_base_search_add(dns, "a.example.com"); - evdns_base_search_add(dns, "b.example.com"); - evdns_base_search_add(dns, "c.example.com"); - evdns_base_search_add(dns, "d.example.com"); - - exit_base = base; - request_count = 3; - n_replies_left = 1; - - current_req = evdns_base_resolve_ipv4(dns, "host", 0, - generic_dns_callback, &r1); - event_base_dispatch(base); - - tt_int_op(r1.result, ==, DNS_ERR_CANCEL); - -end: - if (port) - evdns_close_server_port(port); - if (dns) - evdns_base_free(dns, 0); -} - -static void -fail_server_cb(struct evdns_server_request *req, void *data) -{ - const char *question; - int *count = data; - struct in_addr in; - - /* Drop the first N requests that we get. */ - if (*count > 0) { - --*count; - tt_want(! evdns_server_request_drop(req)); - return; - } - - if (req->nquestions != 1) - TT_DIE(("Only handling one question at a time; got %d", - req->nquestions)); - - question = req->questions[0]->name; - - if (!evutil_ascii_strcasecmp(question, "google.com")) { - /* Detect a probe, and get out of the loop. */ - event_base_loopexit(exit_base, NULL); - } - - tt_assert(evutil_inet_pton(AF_INET, "16.32.64.128", &in)); - evdns_server_request_add_a_reply(req, question, 1, &in.s_addr, - 100); - tt_assert(! evdns_server_request_respond(req, 0)) - return; -end: - tt_want(! evdns_server_request_drop(req)); -} - -static void -dns_retry_test_impl(void *arg, int flags) -{ - struct basic_test_data *data = arg; - struct event_base *base = data->base; - struct evdns_server_port *port = NULL; - struct evdns_base *dns = NULL; - int drop_count = 2; - ev_uint16_t portnum = 0; - char buf[64]; - - struct generic_dns_callback_result r1; - - port = regress_get_dnsserver(base, &portnum, NULL, - fail_server_cb, &drop_count); - tt_assert(port); - evutil_snprintf(buf, sizeof(buf), "127.0.0.1:%d", (int)portnum); - - dns = evdns_base_new(base, flags); - tt_assert(!evdns_base_nameserver_ip_add(dns, buf)); - tt_assert(! evdns_base_set_option(dns, "timeout", "0.2")); - tt_assert(! evdns_base_set_option(dns, "max-timeouts:", "10")); - tt_assert(! evdns_base_set_option(dns, "initial-probe-timeout", "0.1")); - - evdns_base_resolve_ipv4(dns, "host.example.com", 0, - generic_dns_callback, &r1); - - n_replies_left = 1; - exit_base = base; - - event_base_dispatch(base); - - tt_int_op(drop_count, ==, 0); - - tt_int_op(r1.type, ==, DNS_IPv4_A); - tt_int_op(r1.count, ==, 1); - tt_int_op(((ev_uint32_t*)r1.addrs)[0], ==, htonl(0x10204080)); - - /* Now try again, but this time have the server get treated as - * failed, so we can send it a test probe. */ - drop_count = 4; - tt_assert(! evdns_base_set_option(dns, "max-timeouts:", "2")); - tt_assert(! evdns_base_set_option(dns, "attempts:", "3")); - memset(&r1, 0, sizeof(r1)); - - evdns_base_resolve_ipv4(dns, "host.example.com", 0, - generic_dns_callback, &r1); - - n_replies_left = 2; - - /* This will run until it answers the "google.com" probe request. */ - event_base_dispatch(base); - - /* We'll treat the server as failed here. */ - tt_int_op(r1.result, ==, DNS_ERR_TIMEOUT); - - /* It should work this time. */ - tt_int_op(drop_count, ==, 0); - evdns_base_resolve_ipv4(dns, "host.example.com", 0, - generic_dns_callback, &r1); - - event_base_dispatch(base); - tt_int_op(r1.result, ==, DNS_ERR_NONE); - tt_int_op(r1.type, ==, DNS_IPv4_A); - tt_int_op(r1.count, ==, 1); - tt_int_op(((ev_uint32_t*)r1.addrs)[0], ==, htonl(0x10204080)); - -end: - if (dns) - evdns_base_free(dns, 0); - if (port) - evdns_close_server_port(port); -} -static void -dns_retry_test(void *arg) -{ - dns_retry_test_impl(arg, 0); -} -static void -dns_retry_disable_when_inactive_test(void *arg) -{ - dns_retry_test_impl(arg, EVDNS_BASE_DISABLE_WHEN_INACTIVE); -} - -static struct regress_dns_server_table internal_error_table[] = { - /* Error 4 (NOTIMPL) makes us reissue the request to another server - if we can. - - XXXX we should reissue under a much wider set of circumstances! - */ - { "foof.example.com", "err", "4", 0, 0 }, - { NULL, NULL, NULL, 0, 0 } -}; - -static struct regress_dns_server_table reissue_table[] = { - { "foof.example.com", "A", "240.15.240.15", 0, 0 }, - { NULL, NULL, NULL, 0, 0 } -}; - -static void -dns_reissue_test_impl(void *arg, int flags) -{ - struct basic_test_data *data = arg; - struct event_base *base = data->base; - struct evdns_server_port *port1 = NULL, *port2 = NULL; - struct evdns_base *dns = NULL; - struct generic_dns_callback_result r1; - ev_uint16_t portnum1 = 0, portnum2=0; - char buf1[64], buf2[64]; - - port1 = regress_get_dnsserver(base, &portnum1, NULL, - regress_dns_server_cb, internal_error_table); - tt_assert(port1); - port2 = regress_get_dnsserver(base, &portnum2, NULL, - regress_dns_server_cb, reissue_table); - tt_assert(port2); - evutil_snprintf(buf1, sizeof(buf1), "127.0.0.1:%d", (int)portnum1); - evutil_snprintf(buf2, sizeof(buf2), "127.0.0.1:%d", (int)portnum2); - - dns = evdns_base_new(base, flags); - tt_assert(!evdns_base_nameserver_ip_add(dns, buf1)); - tt_assert(! evdns_base_set_option(dns, "timeout:", "0.3")); - tt_assert(! evdns_base_set_option(dns, "max-timeouts:", "2")); - tt_assert(! evdns_base_set_option(dns, "attempts:", "5")); - - memset(&r1, 0, sizeof(r1)); - evdns_base_resolve_ipv4(dns, "foof.example.com", 0, - generic_dns_callback, &r1); - - /* Add this after, so that we are sure to get a reissue. */ - tt_assert(!evdns_base_nameserver_ip_add(dns, buf2)); - - n_replies_left = 1; - exit_base = base; - - event_base_dispatch(base); - tt_int_op(r1.result, ==, DNS_ERR_NONE); - tt_int_op(r1.type, ==, DNS_IPv4_A); - tt_int_op(r1.count, ==, 1); - tt_int_op(((ev_uint32_t*)r1.addrs)[0], ==, htonl(0xf00ff00f)); - - /* Make sure we dropped at least once. */ - tt_int_op(internal_error_table[0].seen, >, 0); - -end: - if (dns) - evdns_base_free(dns, 0); - if (port1) - evdns_close_server_port(port1); - if (port2) - evdns_close_server_port(port2); -} -static void -dns_reissue_test(void *arg) -{ - dns_reissue_test_impl(arg, 0); -} -static void -dns_reissue_disable_when_inactive_test(void *arg) -{ - dns_reissue_test_impl(arg, EVDNS_BASE_DISABLE_WHEN_INACTIVE); -} - -#if 0 -static void -dumb_bytes_fn(char *p, size_t n) -{ - unsigned i; - /* This gets us 6 bits of entropy per transaction ID, which means we - * will have probably have collisions and need to pick again. */ - for (i=0;i<n;++i) - p[i] = (char)(rand() & 7); -} -#endif - -static void -dns_inflight_test_impl(void *arg, int flags) -{ - struct basic_test_data *data = arg; - struct event_base *base = data->base; - struct evdns_base *dns = NULL; - struct evdns_server_port *dns_port = NULL; - ev_uint16_t portnum = 0; - char buf[64]; - int disable_when_inactive = flags & EVDNS_BASE_DISABLE_WHEN_INACTIVE; - - struct generic_dns_callback_result r[20]; - int i; - - dns_port = regress_get_dnsserver(base, &portnum, NULL, - regress_dns_server_cb, reissue_table); - tt_assert(dns_port); - if (disable_when_inactive) { - exit_port = dns_port; - } - - evutil_snprintf(buf, sizeof(buf), "127.0.0.1:%d", (int)portnum); - - dns = evdns_base_new(base, flags); - tt_assert(!evdns_base_nameserver_ip_add(dns, buf)); - tt_assert(! evdns_base_set_option(dns, "max-inflight:", "3")); - tt_assert(! evdns_base_set_option(dns, "randomize-case:", "0")); - - for (i=0;i<20;++i) - evdns_base_resolve_ipv4(dns, "foof.example.com", 0, generic_dns_callback, &r[i]); - - n_replies_left = 20; - exit_base = base; - - event_base_dispatch(base); - - for (i=0;i<20;++i) { - tt_int_op(r[i].type, ==, DNS_IPv4_A); - tt_int_op(r[i].count, ==, 1); - tt_int_op(((ev_uint32_t*)r[i].addrs)[0], ==, htonl(0xf00ff00f)); - } - -end: - if (dns) - evdns_base_free(dns, 0); - if (exit_port) { - evdns_close_server_port(exit_port); - exit_port = NULL; - } else if (! disable_when_inactive) { - evdns_close_server_port(dns_port); - } -} - -static void -dns_inflight_test(void *arg) -{ - dns_inflight_test_impl(arg, 0); -} - -static void -dns_disable_when_inactive_test(void *arg) -{ - dns_inflight_test_impl(arg, EVDNS_BASE_DISABLE_WHEN_INACTIVE); -} - -static void -dns_disable_when_inactive_no_ns_test(void *arg) -{ - struct basic_test_data *data = arg; - struct event_base *base = data->base, *inactive_base; - struct evdns_base *dns = NULL; - ev_uint16_t portnum = 0; - char buf[64]; - struct generic_dns_callback_result r; - - inactive_base = event_base_new(); - tt_assert(inactive_base); - - /** Create dns server with inactive base, to avoid replying to clients */ - tt_assert(regress_dnsserver(inactive_base, &portnum, search_table)); - evutil_snprintf(buf, sizeof(buf), "127.0.0.1:%d", (int)portnum); - - dns = evdns_base_new(base, EVDNS_BASE_DISABLE_WHEN_INACTIVE); - tt_assert(!evdns_base_nameserver_ip_add(dns, buf)); - tt_assert(! evdns_base_set_option(dns, "timeout:", "0.1")); - - evdns_base_resolve_ipv4(dns, "foof.example.com", 0, generic_dns_callback, &r); - n_replies_left = 1; - exit_base = base; - - event_base_dispatch(base); - - tt_int_op(n_replies_left, ==, 0); - - tt_int_op(r.result, ==, DNS_ERR_TIMEOUT); - tt_int_op(r.count, ==, 0); - tt_ptr_op(r.addrs, ==, NULL); - -end: - if (dns) - evdns_base_free(dns, 0); - regress_clean_dnsserver(); - if (inactive_base) - event_base_free(inactive_base); -} - -/* === Test for bufferevent_socket_connect_hostname */ - -static int total_connected_or_failed = 0; -static int total_n_accepted = 0; -static struct event_base *be_connect_hostname_base = NULL; - -/* Implements a DNS server for the connect_hostname test and the - * getaddrinfo_async test */ -static void -be_getaddrinfo_server_cb(struct evdns_server_request *req, void *data) -{ - int i; - int *n_got_p=data; - int added_any=0; - ++*n_got_p; - - 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; - struct in_addr ans; - struct in6_addr ans6; - memset(&ans6, 0, sizeof(ans6)); - - TT_BLATHER(("Got question about %s, type=%d", qname, qtype)); - - if (qtype == EVDNS_TYPE_A && - qclass == EVDNS_CLASS_INET && - !evutil_ascii_strcasecmp(qname, "nobodaddy.example.com")) { - ans.s_addr = htonl(0x7f000001); - evdns_server_request_add_a_reply(req, qname, - 1, &ans.s_addr, 2000); - added_any = 1; - } else if (!evutil_ascii_strcasecmp(qname, - "nosuchplace.example.com")) { - /* ok, just say notfound. */ - } else if (!evutil_ascii_strcasecmp(qname, - "both.example.com")) { - if (qtype == EVDNS_TYPE_A) { - ans.s_addr = htonl(0x50502020); - evdns_server_request_add_a_reply(req, qname, - 1, &ans.s_addr, 2000); - added_any = 1; - } else if (qtype == EVDNS_TYPE_AAAA) { - ans6.s6_addr[0] = 0x80; - ans6.s6_addr[1] = 0xff; - ans6.s6_addr[14] = 0xbb; - ans6.s6_addr[15] = 0xbb; - evdns_server_request_add_aaaa_reply(req, qname, - 1, &ans6.s6_addr, 2000); - added_any = 1; - } - evdns_server_request_add_cname_reply(req, qname, - "both-canonical.example.com", 1000); - } else if (!evutil_ascii_strcasecmp(qname, - "v4only.example.com") || - !evutil_ascii_strcasecmp(qname, "v4assert.example.com")) { - if (qtype == EVDNS_TYPE_A) { - ans.s_addr = htonl(0x12345678); - evdns_server_request_add_a_reply(req, qname, - 1, &ans.s_addr, 2000); - added_any = 1; - } else if (!evutil_ascii_strcasecmp(qname, - "v4assert.example.com")) { - TT_FAIL(("Got an AAAA request for v4assert")); - } - } else if (!evutil_ascii_strcasecmp(qname, - "v6only.example.com") || - !evutil_ascii_strcasecmp(qname, "v6assert.example.com")) { - if (qtype == EVDNS_TYPE_AAAA) { - ans6.s6_addr[0] = 0x0b; - ans6.s6_addr[1] = 0x0b; - ans6.s6_addr[14] = 0xf0; - ans6.s6_addr[15] = 0x0d; - evdns_server_request_add_aaaa_reply(req, qname, - 1, &ans6.s6_addr, 2000); - added_any = 1; - } else if (!evutil_ascii_strcasecmp(qname, - "v6assert.example.com")) { - TT_FAIL(("Got a A request for v6assert")); - } - } else if (!evutil_ascii_strcasecmp(qname, - "v6timeout.example.com")) { - if (qtype == EVDNS_TYPE_A) { - ans.s_addr = htonl(0xabcdef01); - evdns_server_request_add_a_reply(req, qname, - 1, &ans.s_addr, 2000); - added_any = 1; - } else if (qtype == EVDNS_TYPE_AAAA) { - /* Let the v6 request time out.*/ - evdns_server_request_drop(req); - return; - } - } else if (!evutil_ascii_strcasecmp(qname, - "v4timeout.example.com")) { - if (qtype == EVDNS_TYPE_AAAA) { - ans6.s6_addr[0] = 0x0a; - ans6.s6_addr[1] = 0x0a; - ans6.s6_addr[14] = 0xff; - ans6.s6_addr[15] = 0x01; - evdns_server_request_add_aaaa_reply(req, qname, - 1, &ans6.s6_addr, 2000); - added_any = 1; - } else if (qtype == EVDNS_TYPE_A) { - /* Let the v4 request time out.*/ - evdns_server_request_drop(req); - return; - } - } else if (!evutil_ascii_strcasecmp(qname, - "v6timeout-nonexist.example.com")) { - if (qtype == EVDNS_TYPE_A) { - /* Fall through, give an nexist. */ - } else if (qtype == EVDNS_TYPE_AAAA) { - /* Let the v6 request time out.*/ - evdns_server_request_drop(req); - return; - } - } else if (!evutil_ascii_strcasecmp(qname, - "all-timeout.example.com")) { - /* drop all requests */ - evdns_server_request_drop(req); - return; - } else { - TT_GRIPE(("Got weird request for %s",qname)); - } - } - if (added_any) { - TT_BLATHER(("answering")); - evdns_server_request_respond(req, 0); - } else { - TT_BLATHER(("saying nexist.")); - evdns_server_request_respond(req, 3); - } -} - -/* Implements a listener for connect_hostname test. */ -static void -nil_accept_cb(struct evconnlistener *l, evutil_socket_t fd, struct sockaddr *s, - int socklen, void *arg) -{ - int *p = arg; - (*p)++; - ++total_n_accepted; - /* don't do anything with the socket; let it close when we exit() */ - if (total_n_accepted >= 3 && total_connected_or_failed >= 5) - event_base_loopexit(be_connect_hostname_base, - NULL); -} - -struct be_conn_hostname_result { - int dnserr; - int what; -}; - -/* Bufferevent event callback for the connect_hostname test: remembers what - * event we got. */ -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 r; - if ((r = bufferevent_socket_get_dns_error(bev))) { - 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) - event_base_loopexit(be_connect_hostname_base, - NULL); - } - } else { - TT_FAIL(("Two events on one bufferevent. %d,%d", - got->what, (int)what)); - } -} - -static void -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 evdns_base *dns=NULL; - struct evdns_server_port *port=NULL; - struct sockaddr_in sin; - int listener_port=-1; - 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. */ - 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; - listener = evconnlistener_new_bind(data->base, nil_accept_cb, - &n_accept, - LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_EXEC, - -1, (struct sockaddr *)&sin, sizeof(sin)); - tt_assert(listener); - listener_port = regress_get_socket_port( - evconnlistener_get_fd(listener)); - - port = regress_get_dnsserver(data->base, &dns_port, NULL, - be_getaddrinfo_server_cb, &n_dns); - tt_assert(port); - tt_int_op(dns_port, >=, 0); - - /* Start an evdns_base that uses the server as its resolver. */ - dns = evdns_base_new(data->base, 0); - evutil_snprintf(buf, sizeof(buf), "127.0.0.1:%d", (int)dns_port); - evdns_base_nameserver_ip_add(dns, buf); - - /* 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); - - /* Launch an async resolve that will fail. */ - tt_assert(!bufferevent_socket_connect_hostname(be1, dns, AF_INET, - "nosuchplace.example.com", listener_port)); - /* Connect to the IP without resolving. */ - tt_assert(!bufferevent_socket_connect_hostname(be2, 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, - "nobodaddy.example.com", listener_port)); - /* 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, - "localhost", listener_port)); - /* Use the blocking resolver with a nonexistent hostname. */ - tt_assert(!bufferevent_socket_connect_hostname(be5, NULL, AF_INET, - "nonesuch.nowhere.example.com", 80)); - { - /* The blocking resolver will use the system nameserver, which - * might tell us anything. (Yes, some twits even pretend that - * example.com is real.) Let's see what answer to expect. */ - struct evutil_addrinfo hints, *ai = NULL; - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - expect_err5 = evutil_getaddrinfo( - "nonesuch.nowhere.example.com", "80", &hints, &ai); - } - - 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(n_accept, ==, 3); - tt_int_op(n_dns, ==, 2); - -end: - if (listener) - evconnlistener_free(listener); - if (port) - 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); -} - - -struct gai_outcome { - int err; - struct evutil_addrinfo *ai; -}; - -static int n_gai_results_pending = 0; -static struct event_base *exit_base_on_no_pending_results = NULL; - -static void -gai_cb(int err, struct evutil_addrinfo *res, void *ptr) -{ - struct gai_outcome *go = ptr; - go->err = err; - go->ai = res; - if (--n_gai_results_pending <= 0 && exit_base_on_no_pending_results) - event_base_loopexit(exit_base_on_no_pending_results, NULL); - if (n_gai_results_pending < 900) - TT_BLATHER(("Got an answer; expecting %d more.", - n_gai_results_pending)); -} - -static void -cancel_gai_cb(evutil_socket_t fd, short what, void *ptr) -{ - struct evdns_getaddrinfo_request *r = ptr; - evdns_getaddrinfo_cancel(r); -} - -static void -test_getaddrinfo_async(void *arg) -{ - struct basic_test_data *data = arg; - struct evutil_addrinfo hints, *a; - struct gai_outcome local_outcome; - struct gai_outcome a_out[12]; - int i; - struct evdns_getaddrinfo_request *r; - char buf[128]; - struct evdns_server_port *port = NULL; - ev_uint16_t dns_port = 0; - int n_dns_questions = 0; - struct evdns_base *dns_base; - - memset(a_out, 0, sizeof(a_out)); - memset(&local_outcome, 0, sizeof(local_outcome)); - - dns_base = evdns_base_new(data->base, 0); - tt_assert(dns_base); - - /* for localhost */ - evdns_base_load_hosts(dns_base, NULL); - - tt_assert(! evdns_base_set_option(dns_base, "timeout", "0.3")); - tt_assert(! evdns_base_set_option(dns_base, "getaddrinfo-allow-skew", "0.2")); - - n_gai_results_pending = 10000; /* don't think about exiting yet. */ - - /* 1. Try some cases that will never hit the asynchronous resolver. */ - /* 1a. Simple case with a symbolic service name */ - memset(&hints, 0, sizeof(hints)); - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - memset(&local_outcome, 0, sizeof(local_outcome)); - r = evdns_getaddrinfo(dns_base, "1.2.3.4", "http", - &hints, gai_cb, &local_outcome); - tt_assert(! r); - if (!local_outcome.err) { - tt_ptr_op(local_outcome.ai,!=,NULL); - test_ai_eq(local_outcome.ai, "1.2.3.4:80", SOCK_STREAM, IPPROTO_TCP); - evutil_freeaddrinfo(local_outcome.ai); - local_outcome.ai = NULL; - } else { - TT_BLATHER(("Apparently we have no getservbyname.")); - } - - /* 1b. EVUTIL_AI_NUMERICHOST is set */ - memset(&hints, 0, sizeof(hints)); - hints.ai_family = PF_UNSPEC; - hints.ai_flags = EVUTIL_AI_NUMERICHOST; - memset(&local_outcome, 0, sizeof(local_outcome)); - r = evdns_getaddrinfo(dns_base, "www.google.com", "80", - &hints, gai_cb, &local_outcome); - tt_ptr_op(r,==,NULL); - tt_int_op(local_outcome.err,==,EVUTIL_EAI_NONAME); - tt_ptr_op(local_outcome.ai,==,NULL); - - /* 1c. We give a numeric address (ipv6) */ - memset(&hints, 0, sizeof(hints)); - memset(&local_outcome, 0, sizeof(local_outcome)); - hints.ai_family = PF_UNSPEC; - hints.ai_protocol = IPPROTO_TCP; - r = evdns_getaddrinfo(dns_base, "f::f", "8008", - &hints, gai_cb, &local_outcome); - tt_assert(!r); - tt_int_op(local_outcome.err,==,0); - tt_assert(local_outcome.ai); - tt_ptr_op(local_outcome.ai->ai_next,==,NULL); - test_ai_eq(local_outcome.ai, "[f::f]:8008", SOCK_STREAM, IPPROTO_TCP); - evutil_freeaddrinfo(local_outcome.ai); - local_outcome.ai = NULL; - - /* 1d. We give a numeric address (ipv4) */ - memset(&hints, 0, sizeof(hints)); - memset(&local_outcome, 0, sizeof(local_outcome)); - hints.ai_family = PF_UNSPEC; - r = evdns_getaddrinfo(dns_base, "5.6.7.8", NULL, - &hints, gai_cb, &local_outcome); - tt_assert(!r); - tt_int_op(local_outcome.err,==,0); - tt_assert(local_outcome.ai); - a = ai_find_by_protocol(local_outcome.ai, IPPROTO_TCP); - tt_assert(a); - test_ai_eq(a, "5.6.7.8", SOCK_STREAM, IPPROTO_TCP); - a = ai_find_by_protocol(local_outcome.ai, IPPROTO_UDP); - tt_assert(a); - test_ai_eq(a, "5.6.7.8", SOCK_DGRAM, IPPROTO_UDP); - evutil_freeaddrinfo(local_outcome.ai); - local_outcome.ai = NULL; - - /* 1e. nodename is NULL (bind) */ - memset(&hints, 0, sizeof(hints)); - memset(&local_outcome, 0, sizeof(local_outcome)); - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_DGRAM; - hints.ai_flags = EVUTIL_AI_PASSIVE; - r = evdns_getaddrinfo(dns_base, NULL, "9090", - &hints, gai_cb, &local_outcome); - tt_assert(!r); - tt_int_op(local_outcome.err,==,0); - tt_assert(local_outcome.ai); - /* we should get a v4 address of 0.0.0.0... */ - a = ai_find_by_family(local_outcome.ai, PF_INET); - tt_assert(a); - test_ai_eq(a, "0.0.0.0:9090", SOCK_DGRAM, IPPROTO_UDP); - /* ... and a v6 address of ::0 */ - a = ai_find_by_family(local_outcome.ai, PF_INET6); - tt_assert(a); - test_ai_eq(a, "[::]:9090", SOCK_DGRAM, IPPROTO_UDP); - evutil_freeaddrinfo(local_outcome.ai); - local_outcome.ai = NULL; - - /* 1f. nodename is NULL (connect) */ - memset(&hints, 0, sizeof(hints)); - memset(&local_outcome, 0, sizeof(local_outcome)); - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - r = evdns_getaddrinfo(dns_base, NULL, "2", - &hints, gai_cb, &local_outcome); - tt_assert(!r); - tt_int_op(local_outcome.err,==,0); - tt_assert(local_outcome.ai); - /* we should get a v4 address of 127.0.0.1 .... */ - a = ai_find_by_family(local_outcome.ai, PF_INET); - tt_assert(a); - test_ai_eq(a, "127.0.0.1:2", SOCK_STREAM, IPPROTO_TCP); - /* ... and a v6 address of ::1 */ - a = ai_find_by_family(local_outcome.ai, PF_INET6); - tt_assert(a); - test_ai_eq(a, "[::1]:2", SOCK_STREAM, IPPROTO_TCP); - evutil_freeaddrinfo(local_outcome.ai); - local_outcome.ai = NULL; - - /* 1g. We find localhost immediately. (pf_unspec) */ - memset(&hints, 0, sizeof(hints)); - memset(&local_outcome, 0, sizeof(local_outcome)); - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - r = evdns_getaddrinfo(dns_base, "LOCALHOST", "80", - &hints, gai_cb, &local_outcome); - tt_assert(!r); - tt_int_op(local_outcome.err,==,0); - tt_assert(local_outcome.ai); - /* we should get a v4 address of 127.0.0.1 .... */ - a = ai_find_by_family(local_outcome.ai, PF_INET); - tt_assert(a); - test_ai_eq(a, "127.0.0.1:80", SOCK_STREAM, IPPROTO_TCP); - /* ... and a v6 address of ::1 */ - a = ai_find_by_family(local_outcome.ai, PF_INET6); - tt_assert(a); - test_ai_eq(a, "[::1]:80", SOCK_STREAM, IPPROTO_TCP); - evutil_freeaddrinfo(local_outcome.ai); - local_outcome.ai = NULL; - - /* 1g. We find localhost immediately. (pf_inet6) */ - memset(&hints, 0, sizeof(hints)); - memset(&local_outcome, 0, sizeof(local_outcome)); - hints.ai_family = PF_INET6; - hints.ai_socktype = SOCK_STREAM; - r = evdns_getaddrinfo(dns_base, "LOCALHOST", "9999", - &hints, gai_cb, &local_outcome); - tt_assert(! r); - tt_int_op(local_outcome.err,==,0); - tt_assert(local_outcome.ai); - a = local_outcome.ai; - test_ai_eq(a, "[::1]:9999", SOCK_STREAM, IPPROTO_TCP); - tt_ptr_op(a->ai_next, ==, NULL); - evutil_freeaddrinfo(local_outcome.ai); - local_outcome.ai = NULL; - - /* 2. Okay, now we can actually test the asynchronous resolver. */ - /* Start a dummy local dns server... */ - port = regress_get_dnsserver(data->base, &dns_port, NULL, - be_getaddrinfo_server_cb, &n_dns_questions); - tt_assert(port); - tt_int_op(dns_port, >=, 0); - /* ... and tell the evdns_base about it. */ - evutil_snprintf(buf, sizeof(buf), "127.0.0.1:%d", dns_port); - evdns_base_nameserver_ip_add(dns_base, buf); - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = EVUTIL_AI_CANONNAME; - /* 0: Request for both.example.com should return both addresses. */ - r = evdns_getaddrinfo(dns_base, "both.example.com", "8000", - &hints, gai_cb, &a_out[0]); - tt_assert(r); - - /* 1: Request for v4only.example.com should return one address. */ - r = evdns_getaddrinfo(dns_base, "v4only.example.com", "8001", - &hints, gai_cb, &a_out[1]); - tt_assert(r); - - /* 2: Request for v6only.example.com should return one address. */ - hints.ai_flags = 0; - r = evdns_getaddrinfo(dns_base, "v6only.example.com", "8002", - &hints, gai_cb, &a_out[2]); - tt_assert(r); - - /* 3: PF_INET request for v4assert.example.com should not generate a - * v6 request. The server will fail the test if it does. */ - hints.ai_family = PF_INET; - r = evdns_getaddrinfo(dns_base, "v4assert.example.com", "8003", - &hints, gai_cb, &a_out[3]); - tt_assert(r); - - /* 4: PF_INET6 request for v6assert.example.com should not generate a - * v4 request. The server will fail the test if it does. */ - hints.ai_family = PF_INET6; - r = evdns_getaddrinfo(dns_base, "v6assert.example.com", "8004", - &hints, gai_cb, &a_out[4]); - tt_assert(r); - - /* 5: PF_INET request for nosuchplace.example.com should give NEXIST. */ - hints.ai_family = PF_INET; - r = evdns_getaddrinfo(dns_base, "nosuchplace.example.com", "8005", - &hints, gai_cb, &a_out[5]); - tt_assert(r); - - /* 6: PF_UNSPEC request for nosuchplace.example.com should give NEXIST. - */ - hints.ai_family = PF_UNSPEC; - r = evdns_getaddrinfo(dns_base, "nosuchplace.example.com", "8006", - &hints, gai_cb, &a_out[6]); - tt_assert(r); - - /* 7: PF_UNSPEC request for v6timeout.example.com should give an ipv4 - * address only. */ - hints.ai_family = PF_UNSPEC; - r = evdns_getaddrinfo(dns_base, "v6timeout.example.com", "8007", - &hints, gai_cb, &a_out[7]); - tt_assert(r); - - /* 8: PF_UNSPEC request for v6timeout-nonexist.example.com should give - * a NEXIST */ - hints.ai_family = PF_UNSPEC; - r = evdns_getaddrinfo(dns_base, "v6timeout-nonexist.example.com", - "8008", &hints, gai_cb, &a_out[8]); - tt_assert(r); - - /* 9: AI_ADDRCONFIG should at least not crash. Can't test it more - * without knowing what kind of internet we have. */ - hints.ai_flags |= EVUTIL_AI_ADDRCONFIG; - r = evdns_getaddrinfo(dns_base, "both.example.com", - "8009", &hints, gai_cb, &a_out[9]); - tt_assert(r); - - /* 10: PF_UNSPEC for v4timeout.example.com should give an ipv6 address - * only. */ - hints.ai_family = PF_UNSPEC; - hints.ai_flags = 0; - r = evdns_getaddrinfo(dns_base, "v4timeout.example.com", "8010", - &hints, gai_cb, &a_out[10]); - tt_assert(r); - - /* 11: timeout.example.com: cancel it after 100 msec. */ - r = evdns_getaddrinfo(dns_base, "all-timeout.example.com", "8011", - &hints, gai_cb, &a_out[11]); - tt_assert(r); - { - struct timeval tv; - tv.tv_sec = 0; - tv.tv_usec = 100*1000; /* 100 msec */ - event_base_once(data->base, -1, EV_TIMEOUT, cancel_gai_cb, - r, &tv); - } - - /* XXXXX There are more tests we could do, including: - - - A test to elicit NODATA. - - */ - - n_gai_results_pending = 12; - exit_base_on_no_pending_results = data->base; - - event_base_dispatch(data->base); - - /* 0: both.example.com */ - tt_int_op(a_out[0].err, ==, 0); - tt_assert(a_out[0].ai); - tt_assert(a_out[0].ai->ai_next); - tt_assert(!a_out[0].ai->ai_next->ai_next); - a = ai_find_by_family(a_out[0].ai, PF_INET); - tt_assert(a); - test_ai_eq(a, "80.80.32.32:8000", SOCK_STREAM, IPPROTO_TCP); - a = ai_find_by_family(a_out[0].ai, PF_INET6); - tt_assert(a); - test_ai_eq(a, "[80ff::bbbb]:8000", SOCK_STREAM, IPPROTO_TCP); - tt_assert(a_out[0].ai->ai_canonname); - tt_str_op(a_out[0].ai->ai_canonname, ==, "both-canonical.example.com"); - - /* 1: v4only.example.com */ - tt_int_op(a_out[1].err, ==, 0); - tt_assert(a_out[1].ai); - tt_assert(! a_out[1].ai->ai_next); - test_ai_eq(a_out[1].ai, "18.52.86.120:8001", SOCK_STREAM, IPPROTO_TCP); - tt_assert(a_out[1].ai->ai_canonname == NULL); - - - /* 2: v6only.example.com */ - tt_int_op(a_out[2].err, ==, 0); - tt_assert(a_out[2].ai); - tt_assert(! a_out[2].ai->ai_next); - test_ai_eq(a_out[2].ai, "[b0b::f00d]:8002", SOCK_STREAM, IPPROTO_TCP); - - /* 3: v4assert.example.com */ - tt_int_op(a_out[3].err, ==, 0); - tt_assert(a_out[3].ai); - tt_assert(! a_out[3].ai->ai_next); - test_ai_eq(a_out[3].ai, "18.52.86.120:8003", SOCK_STREAM, IPPROTO_TCP); - - /* 4: v6assert.example.com */ - tt_int_op(a_out[4].err, ==, 0); - tt_assert(a_out[4].ai); - tt_assert(! a_out[4].ai->ai_next); - test_ai_eq(a_out[4].ai, "[b0b::f00d]:8004", SOCK_STREAM, IPPROTO_TCP); - - /* 5: nosuchplace.example.com (inet) */ - tt_int_op(a_out[5].err, ==, EVUTIL_EAI_NONAME); - tt_assert(! a_out[5].ai); - - /* 6: nosuchplace.example.com (unspec) */ - tt_int_op(a_out[6].err, ==, EVUTIL_EAI_NONAME); - tt_assert(! a_out[6].ai); - - /* 7: v6timeout.example.com */ - tt_int_op(a_out[7].err, ==, 0); - tt_assert(a_out[7].ai); - tt_assert(! a_out[7].ai->ai_next); - test_ai_eq(a_out[7].ai, "171.205.239.1:8007", SOCK_STREAM, IPPROTO_TCP); - - /* 8: v6timeout-nonexist.example.com */ - tt_int_op(a_out[8].err, ==, EVUTIL_EAI_NONAME); - tt_assert(! a_out[8].ai); - - /* 9: both (ADDRCONFIG) */ - tt_int_op(a_out[9].err, ==, 0); - tt_assert(a_out[9].ai); - a = ai_find_by_family(a_out[9].ai, PF_INET); - if (a) - test_ai_eq(a, "80.80.32.32:8009", SOCK_STREAM, IPPROTO_TCP); - else - tt_assert(ai_find_by_family(a_out[9].ai, PF_INET6)); - a = ai_find_by_family(a_out[9].ai, PF_INET6); - if (a) - test_ai_eq(a, "[80ff::bbbb]:8009", SOCK_STREAM, IPPROTO_TCP); - else - tt_assert(ai_find_by_family(a_out[9].ai, PF_INET)); - - /* 10: v4timeout.example.com */ - tt_int_op(a_out[10].err, ==, 0); - tt_assert(a_out[10].ai); - tt_assert(! a_out[10].ai->ai_next); - test_ai_eq(a_out[10].ai, "[a0a::ff01]:8010", SOCK_STREAM, IPPROTO_TCP); - - /* 11: cancelled request. */ - tt_int_op(a_out[11].err, ==, EVUTIL_EAI_CANCEL); - tt_assert(a_out[11].ai == NULL); - -end: - if (local_outcome.ai) - evutil_freeaddrinfo(local_outcome.ai); - for (i=0;i<(int)ARRAY_SIZE(a_out);++i) { - if (a_out[i].ai) - evutil_freeaddrinfo(a_out[i].ai); - } - if (port) - evdns_close_server_port(port); - if (dns_base) - evdns_base_free(dns_base, 0); -} - -struct gaic_request_status { - int magic; - struct event_base *base; - struct evdns_base *dns_base; - struct evdns_getaddrinfo_request *request; - struct event cancel_event; - int canceled; -}; - -#define GAIC_MAGIC 0x1234abcd - -static int pending = 0; - -static void -gaic_cancel_request_cb(evutil_socket_t fd, short what, void *arg) -{ - struct gaic_request_status *status = arg; - - tt_assert(status->magic == GAIC_MAGIC); - status->canceled = 1; - evdns_getaddrinfo_cancel(status->request); - return; -end: - event_base_loopexit(status->base, NULL); -} - -static void -gaic_server_cb(struct evdns_server_request *req, void *arg) -{ - ev_uint32_t answer = 0x7f000001; - tt_assert(req->nquestions); - evdns_server_request_add_a_reply(req, req->questions[0]->name, 1, - &answer, 100); - evdns_server_request_respond(req, 0); - return; -end: - evdns_server_request_respond(req, DNS_ERR_REFUSED); -} - - -static void -gaic_getaddrinfo_cb(int result, struct evutil_addrinfo *res, void *arg) -{ - struct gaic_request_status *status = arg; - struct event_base *base = status->base; - tt_assert(status->magic == GAIC_MAGIC); - - if (result == EVUTIL_EAI_CANCEL) { - tt_assert(status->canceled); - } - event_del(&status->cancel_event); - - memset(status, 0xf0, sizeof(*status)); - free(status); - -end: - if (--pending <= 0) - event_base_loopexit(base, NULL); -} - -static void -gaic_launch(struct event_base *base, struct evdns_base *dns_base) -{ - struct gaic_request_status *status = calloc(1,sizeof(*status)); - struct timeval tv = { 0, 10000 }; - status->magic = GAIC_MAGIC; - status->base = base; - status->dns_base = dns_base; - event_assign(&status->cancel_event, base, -1, 0, gaic_cancel_request_cb, - status); - status->request = evdns_getaddrinfo(dns_base, - "foobar.bazquux.example.com", "80", NULL, gaic_getaddrinfo_cb, - status); - event_add(&status->cancel_event, &tv); - ++pending; -} - -#ifdef EVENT_SET_MEM_FUNCTIONS_IMPLEMENTED -/* FIXME: We should move this to regress_main.c if anything else needs it.*/ - -/* Trivial replacements for malloc/free/realloc to check for memory leaks. - * Not threadsafe. */ -static int allocated_chunks = 0; - -static void * -cnt_malloc(size_t sz) -{ - allocated_chunks += 1; - return malloc(sz); -} - -static void * -cnt_realloc(void *old, size_t sz) -{ - if (!old) - allocated_chunks += 1; - if (!sz) - allocated_chunks -= 1; - return realloc(old, sz); -} - -static void -cnt_free(void *ptr) -{ - allocated_chunks -= 1; - free(ptr); -} - -struct testleak_env_t { - struct event_base *base; - struct evdns_base *dns_base; - struct evdns_request *req; - struct generic_dns_callback_result r; -}; - -static void * -testleak_setup(const struct testcase_t *testcase) -{ - struct testleak_env_t *env; - - allocated_chunks = 0; - - /* Reset allocation counter, to start allocations from the very beginning. - * (this will avoid false-positive negative numbers for allocated_chunks) - */ - libevent_global_shutdown(); - - event_set_mem_functions(cnt_malloc, cnt_realloc, cnt_free); - - event_enable_debug_mode(); - - /* not mm_calloc: we don't want to mess with the count. */ - env = calloc(1, sizeof(struct testleak_env_t)); - env->base = event_base_new(); - env->dns_base = evdns_base_new(env->base, 0); - env->req = evdns_base_resolve_ipv4( - env->dns_base, "example.com", DNS_QUERY_NO_SEARCH, - generic_dns_callback, &env->r); - return env; -} - -static int -testleak_cleanup(const struct testcase_t *testcase, void *env_) -{ - int ok = 0; - struct testleak_env_t *env = env_; - tt_assert(env); -#ifdef EVENT__DISABLE_DEBUG_MODE - tt_int_op(allocated_chunks, ==, 0); -#else - libevent_global_shutdown(); - tt_int_op(allocated_chunks, ==, 0); -#endif - ok = 1; -end: - if (env) { - if (env->dns_base) - evdns_base_free(env->dns_base, 0); - if (env->base) - event_base_free(env->base); - free(env); - } - return ok; -} - -static struct testcase_setup_t testleak_funcs = { - testleak_setup, testleak_cleanup -}; - -static void -test_dbg_leak_cancel(void *env_) -{ - /* cancel, loop, free/dns, free/base */ - struct testleak_env_t *env = env_; - int send_err_shutdown = 1; - evdns_cancel_request(env->dns_base, env->req); - env->req = 0; - - /* `req` is freed in callback, that's why one loop is required. */ - event_base_loop(env->base, EVLOOP_NONBLOCK); - - /* send_err_shutdown means nothing as soon as our request is - * already canceled */ - evdns_base_free(env->dns_base, send_err_shutdown); - env->dns_base = 0; - event_base_free(env->base); - env->base = 0; -} - -static void -dbg_leak_resume(void *env_, int cancel, int send_err_shutdown) -{ - /* cancel, loop, free/dns, free/base */ - struct testleak_env_t *env = env_; - if (cancel) { - evdns_cancel_request(env->dns_base, env->req); - tt_assert(!evdns_base_resume(env->dns_base)); - } else { - /* TODO: No nameservers, request can't be processed, must be errored */ - tt_assert(!evdns_base_resume(env->dns_base)); - } - - event_base_loop(env->base, EVLOOP_NONBLOCK); - /** - * Because we don't cancel request, and want our callback to recieve - * DNS_ERR_SHUTDOWN, we use deferred callback, and there was: - * - one extra malloc(), - * @see reply_schedule_callback() - * - and one missing free - * @see request_finished() (req->handle->pending_cb = 1) - * than we don't need to count in testleak_cleanup(), but we can clean them - * if we will run loop once again, but *after* evdns base freed. - */ - evdns_base_free(env->dns_base, send_err_shutdown); - env->dns_base = 0; - event_base_loop(env->base, EVLOOP_NONBLOCK); - -end: - event_base_free(env->base); - env->base = 0; -} - -#define IMPL_DBG_LEAK_RESUME(name, cancel, send_err_shutdown) \ - static void \ - test_dbg_leak_##name##_(void *env_) \ - { \ - dbg_leak_resume(env_, cancel, send_err_shutdown); \ - } -IMPL_DBG_LEAK_RESUME(resume, 0, 0) -IMPL_DBG_LEAK_RESUME(cancel_and_resume, 1, 0) -IMPL_DBG_LEAK_RESUME(resume_send_err, 0, 1) -IMPL_DBG_LEAK_RESUME(cancel_and_resume_send_err, 1, 1) - -static void -test_dbg_leak_shutdown(void *env_) -{ - /* free/dns, loop, free/base */ - struct testleak_env_t *env = env_; - int send_err_shutdown = 1; - - /* `req` is freed both with `send_err_shutdown` and without it, - * the only difference is `evdns_callback` call */ - env->req = 0; - - evdns_base_free(env->dns_base, send_err_shutdown); - env->dns_base = 0; - - /* `req` is freed in callback, that's why one loop is required */ - event_base_loop(env->base, EVLOOP_NONBLOCK); - event_base_free(env->base); - env->base = 0; -} -#endif - -static void -test_getaddrinfo_async_cancel_stress(void *ptr) -{ - struct event_base *base; - struct evdns_base *dns_base = NULL; - struct evdns_server_port *server = NULL; - evutil_socket_t fd = -1; - struct sockaddr_in sin; - struct sockaddr_storage ss; - ev_socklen_t slen; - int i; - - base = event_base_new(); - dns_base = evdns_base_new(base, 0); - - memset(&sin, 0, sizeof(sin)); - sin.sin_family = AF_INET; - sin.sin_port = 0; - sin.sin_addr.s_addr = htonl(0x7f000001); - if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - tt_abort_perror("socket"); - } - evutil_make_socket_nonblocking(fd); - if (bind(fd, (struct sockaddr*)&sin, sizeof(sin))<0) { - tt_abort_perror("bind"); - } - server = evdns_add_server_port_with_base(base, fd, 0, gaic_server_cb, - base); - - memset(&ss, 0, sizeof(ss)); - slen = sizeof(ss); - if (getsockname(fd, (struct sockaddr*)&ss, &slen)<0) { - tt_abort_perror("getsockname"); - } - evdns_base_nameserver_sockaddr_add(dns_base, - (struct sockaddr*)&ss, slen, 0); - - for (i = 0; i < 1000; ++i) { - gaic_launch(base, dns_base); - } - - event_base_dispatch(base); - -end: - if (dns_base) - evdns_base_free(dns_base, 1); - if (server) - evdns_close_server_port(server); - if (base) - event_base_free(base); - if (fd >= 0) - evutil_closesocket(fd); -} - -static void -dns_client_fail_requests_test(void *arg) -{ - struct basic_test_data *data = arg; - struct event_base *base = data->base; - struct evdns_base *dns = NULL; - struct evdns_server_port *dns_port = NULL; - ev_uint16_t portnum = 0; - char buf[64]; - - struct generic_dns_callback_result r[20]; - int i; - - dns_port = regress_get_dnsserver(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); - - dns = evdns_base_new(base, EVDNS_BASE_DISABLE_WHEN_INACTIVE); - tt_assert(!evdns_base_nameserver_ip_add(dns, buf)); - - for (i = 0; i < 20; ++i) - evdns_base_resolve_ipv4(dns, "foof.example.com", 0, generic_dns_callback, &r[i]); - - n_replies_left = 20; - exit_base = base; - - evdns_base_free(dns, 1 /** fail requests */); - /** run defered callbacks, to trigger UAF */ - event_base_dispatch(base); - - tt_int_op(n_replies_left, ==, 0); - for (i = 0; i < 20; ++i) - tt_int_op(r[i].result, ==, DNS_ERR_SHUTDOWN); - -end: - evdns_close_server_port(dns_port); -} - -static void -getaddrinfo_cb(int err, struct evutil_addrinfo *res, void *ptr) -{ - generic_dns_callback(err, 0, 0, 0, NULL, ptr); -} -static void -dns_client_fail_requests_getaddrinfo_test(void *arg) -{ - struct basic_test_data *data = arg; - struct event_base *base = data->base; - struct evdns_base *dns = NULL; - struct evdns_server_port *dns_port = NULL; - ev_uint16_t portnum = 0; - char buf[64]; - - struct generic_dns_callback_result r[20]; - int i; - - dns_port = regress_get_dnsserver(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); - - dns = evdns_base_new(base, EVDNS_BASE_DISABLE_WHEN_INACTIVE); - tt_assert(!evdns_base_nameserver_ip_add(dns, buf)); - - for (i = 0; i < 20; ++i) - tt_assert(evdns_getaddrinfo(dns, "foof.example.com", "http", NULL, getaddrinfo_cb, &r[i])); - - n_replies_left = 20; - exit_base = base; - - evdns_base_free(dns, 1 /** fail requests */); - /** run defered callbacks, to trigger UAF */ - event_base_dispatch(base); - - tt_int_op(n_replies_left, ==, 0); - for (i = 0; i < 20; ++i) - tt_int_op(r[i].result, ==, EVUTIL_EAI_FAIL); - -end: - evdns_close_server_port(dns_port); -} - - -#define DNS_LEGACY(name, flags) \ - { #name, run_legacy_test_fn, flags|TT_LEGACY, &legacy_setup, \ - dns_##name } - -struct testcase_t dns_testcases[] = { - DNS_LEGACY(server, TT_FORK|TT_NEED_BASE), - DNS_LEGACY(gethostbyname, TT_FORK|TT_NEED_BASE|TT_NEED_DNS|TT_OFF_BY_DEFAULT), - DNS_LEGACY(gethostbyname6, TT_FORK|TT_NEED_BASE|TT_NEED_DNS|TT_OFF_BY_DEFAULT), - DNS_LEGACY(gethostbyaddr, TT_FORK|TT_NEED_BASE|TT_NEED_DNS|TT_OFF_BY_DEFAULT), - { "resolve_reverse", dns_resolve_reverse, TT_FORK|TT_OFF_BY_DEFAULT, NULL, NULL }, - { "search", dns_search_test, TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, - { "search_lower", dns_search_lower_test, TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, - { "search_cancel", dns_search_cancel_test, - TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, - { "retry", dns_retry_test, TT_FORK|TT_NEED_BASE|TT_NO_LOGS, &basic_setup, NULL }, - { "retry_disable_when_inactive", dns_retry_disable_when_inactive_test, - TT_FORK|TT_NEED_BASE|TT_NO_LOGS, &basic_setup, NULL }, - { "reissue", dns_reissue_test, TT_FORK|TT_NEED_BASE|TT_NO_LOGS, &basic_setup, NULL }, - { "reissue_disable_when_inactive", dns_reissue_disable_when_inactive_test, - TT_FORK|TT_NEED_BASE|TT_NO_LOGS, &basic_setup, NULL }, - { "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 }, - { "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, - TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, - - { "getaddrinfo_async", test_getaddrinfo_async, - TT_FORK|TT_NEED_BASE, &basic_setup, (char*)"" }, - { "getaddrinfo_cancel_stress", test_getaddrinfo_async_cancel_stress, - TT_FORK, NULL, NULL }, - -#ifdef EVENT_SET_MEM_FUNCTIONS_IMPLEMENTED - { "leak_shutdown", test_dbg_leak_shutdown, TT_FORK, &testleak_funcs, NULL }, - { "leak_cancel", test_dbg_leak_cancel, TT_FORK, &testleak_funcs, NULL }, - - { "leak_resume", test_dbg_leak_resume_, TT_FORK, &testleak_funcs, NULL }, - { "leak_cancel_and_resume", test_dbg_leak_cancel_and_resume_, - TT_FORK, &testleak_funcs, NULL }, - { "leak_resume_send_err", test_dbg_leak_resume_send_err_, - TT_FORK, &testleak_funcs, NULL }, - { "leak_cancel_and_resume_send_err", test_dbg_leak_cancel_and_resume_send_err_, - TT_FORK, &testleak_funcs, NULL }, -#endif - - { "client_fail_requests", dns_client_fail_requests_test, - TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, - { "client_fail_requests_getaddrinfo", - dns_client_fail_requests_getaddrinfo_test, - TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, - - END_OF_TESTCASES -}; - diff --git a/protocols/Telegram/tgl/libevent/test/regress_dns.obj b/protocols/Telegram/tgl/libevent/test/regress_dns.obj Binary files differdeleted file mode 100644 index 4406585f06..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress_dns.obj +++ /dev/null diff --git a/protocols/Telegram/tgl/libevent/test/regress_et.c b/protocols/Telegram/tgl/libevent/test/regress_et.c deleted file mode 100644 index 229a78e2d4..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress_et.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (c) 2009-2012 Niels Provos and Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "../util-internal.h" -#include "event2/event-config.h" - -#ifdef _WIN32 -#include <winsock2.h> -#endif -#include <sys/types.h> -#include <sys/stat.h> -#ifdef EVENT__HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#include <fcntl.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#ifndef _WIN32 -#include <sys/time.h> -#include <unistd.h> -#endif -#include <errno.h> - -#include "event2/event.h" -#include "event2/util.h" - -#include "regress.h" - -static int was_et = 0; - -static void -read_cb(evutil_socket_t fd, short event, void *arg) -{ - char buf; - int len; - - len = recv(fd, &buf, sizeof(buf), 0); - - called++; - if (event & EV_ET) - was_et = 1; - - if (!len) - event_del(arg); -} - -#ifndef SHUT_WR -#define SHUT_WR 1 -#endif - -#ifdef _WIN32 -#define LOCAL_SOCKETPAIR_AF AF_INET -#else -#define LOCAL_SOCKETPAIR_AF AF_UNIX -#endif - -static void -test_edgetriggered(void *et) -{ - 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), - * doing a "recv" on an AF_UNIX socket resets the readability of the - * socket, even though there is no state change, so we don't actually - * 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], SHUT_WR); - - /* 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; - - TT_BLATHER(("Checking for edge-triggered events with %s, which should %s" - "support edge-triggering", event_base_get_method(base), - supports_et?"":"not ")); - - /* Initalize one event */ - ev = event_new(base, pair[1], EV_READ|EV_ET|EV_PERSIST, read_cb, &ev); - - event_add(ev, NULL); - - /* 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 - * triggered, we'll only see the event once (since we only see transitions - * from no data to data), so the second invocation of event_base_loop will - * 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); - - if (supports_et) { - tt_int_op(called, ==, 1); - tt_assert(was_et); - } else { - tt_int_op(called, ==, 2); - tt_assert(!was_et); - } - - 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 -test_edgetriggered_mix_error(void *data_) -{ - struct basic_test_data *data = data_; - struct event_base *base = NULL; - struct event *ev_et=NULL, *ev_lt=NULL; - -#ifdef EVENT__DISABLE_DEBUG_MODE - if (1) - tt_skip(); -#endif - - if (!libevent_tests_running_in_debug_mode) - event_enable_debug_mode(); - - base = event_base_new(); - - /* try mixing edge-triggered and level-triggered to make sure it fails*/ - ev_et = event_new(base, data->pair[0], EV_READ|EV_ET, read_cb, ev_et); - tt_assert(ev_et); - ev_lt = event_new(base, data->pair[0], EV_READ, read_cb, ev_lt); - tt_assert(ev_lt); - - /* Add edge-triggered, then level-triggered. Get an error. */ - tt_int_op(0, ==, event_add(ev_et, NULL)); - tt_int_op(-1, ==, event_add(ev_lt, NULL)); - tt_int_op(EV_READ, ==, event_pending(ev_et, EV_READ, NULL)); - tt_int_op(0, ==, event_pending(ev_lt, EV_READ, NULL)); - - tt_int_op(0, ==, event_del(ev_et)); - /* Add level-triggered, then edge-triggered. Get an error. */ - tt_int_op(0, ==, event_add(ev_lt, NULL)); - tt_int_op(-1, ==, event_add(ev_et, NULL)); - tt_int_op(EV_READ, ==, event_pending(ev_lt, EV_READ, NULL)); - tt_int_op(0, ==, event_pending(ev_et, EV_READ, NULL)); - -end: - if (ev_et) - event_free(ev_et); - if (ev_lt) - event_free(ev_lt); - if (base) - event_base_free(base); -} - -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 }, - END_OF_TESTCASES -}; diff --git a/protocols/Telegram/tgl/libevent/test/regress_et.obj b/protocols/Telegram/tgl/libevent/test/regress_et.obj Binary files differdeleted file mode 100644 index e745dc87e6..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress_et.obj +++ /dev/null diff --git a/protocols/Telegram/tgl/libevent/test/regress_finalize.c b/protocols/Telegram/tgl/libevent/test/regress_finalize.c deleted file mode 100644 index 552210fe9d..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress_finalize.c +++ /dev/null @@ -1,347 +0,0 @@ -/* - * Copyright (c) 2013 Niels Provos and Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "event2/event-config.h" -#include "evconfig-private.h" -#include "tinytest.h" -#include "tinytest_macros.h" -#include <stdlib.h> - -#include "event2/event.h" -#include "event2/util.h" -#include "event-internal.h" -#include "defer-internal.h" - -#include "regress.h" -#include "regress_thread.h" - -static void -timer_callback(evutil_socket_t fd, short what, void *arg) -{ - int *int_arg = arg; - *int_arg += 1; - (void)fd; - (void)what; -} -static void -simple_callback(struct event_callback *evcb, void *arg) -{ - int *int_arg = arg; - *int_arg += 1; - (void)evcb; -} -static void -event_finalize_callback_1(struct event *ev, void *arg) -{ - int *int_arg = arg; - *int_arg += 100; - (void)ev; -} -static void -callback_finalize_callback_1(struct event_callback *evcb, void *arg) -{ - int *int_arg = arg; - *int_arg += 100; - (void)evcb; -} - - -static void -test_fin_cb_invoked(void *arg) -{ - struct basic_test_data *data = arg; - struct event_base *base = data->base; - - struct event *ev; - struct event ev2; - struct event_callback evcb; - int cb_called = 0; - int ev_called = 0; - - const struct timeval ten_sec = {10,0}; - - event_deferred_cb_init_(&evcb, 0, simple_callback, &cb_called); - ev = evtimer_new(base, timer_callback, &ev_called); - /* Just finalize them; don't bother adding. */ - event_free_finalize(0, ev, event_finalize_callback_1); - event_callback_finalize_(base, 0, &evcb, callback_finalize_callback_1); - - event_base_dispatch(base); - - tt_int_op(cb_called, ==, 100); - tt_int_op(ev_called, ==, 100); - - ev_called = cb_called = 0; - event_base_assert_ok_(base); - - /* Now try it when they're active. (actually, don't finalize: make - * sure activation can happen! */ - ev = evtimer_new(base, timer_callback, &ev_called); - event_deferred_cb_init_(&evcb, 0, simple_callback, &cb_called); - - event_active(ev, EV_TIMEOUT, 1); - event_callback_activate_(base, &evcb); - - event_base_dispatch(base); - tt_int_op(cb_called, ==, 1); - tt_int_op(ev_called, ==, 1); - - ev_called = cb_called = 0; - event_base_assert_ok_(base); - - /* Great, it worked. Now activate and finalize and make sure only - * finalizing happens. */ - event_active(ev, EV_TIMEOUT, 1); - event_callback_activate_(base, &evcb); - event_free_finalize(0, ev, event_finalize_callback_1); - event_callback_finalize_(base, 0, &evcb, callback_finalize_callback_1); - - event_base_dispatch(base); - tt_int_op(cb_called, ==, 100); - tt_int_op(ev_called, ==, 100); - - ev_called = 0; - - event_base_assert_ok_(base); - - /* Okay, now add but don't have it become active, and make sure *that* - * works. */ - ev = evtimer_new(base, timer_callback, &ev_called); - event_add(ev, &ten_sec); - event_free_finalize(0, ev, event_finalize_callback_1); - - event_base_dispatch(base); - tt_int_op(ev_called, ==, 100); - - ev_called = 0; - event_base_assert_ok_(base); - - /* Now try adding and deleting after finalizing. */ - ev = evtimer_new(base, timer_callback, &ev_called); - evtimer_assign(&ev2, base, timer_callback, &ev_called); - event_add(ev, &ten_sec); - event_free_finalize(0, ev, event_finalize_callback_1); - event_finalize(0, &ev2, event_finalize_callback_1); - - event_add(&ev2, &ten_sec); - event_del(ev); - event_active(&ev2, EV_TIMEOUT, 1); - - event_base_dispatch(base); - tt_int_op(ev_called, ==, 200); - - event_base_assert_ok_(base); - -end: - ; -} - -#ifndef EVENT__DISABLE_MM_REPLACEMENT -static void * -tfff_malloc(size_t n) -{ - return malloc(n); -} -static void *tfff_p1=NULL, *tfff_p2=NULL; -static int tfff_p1_freed=0, tfff_p2_freed=0; -static void -tfff_free(void *p) -{ - if (! p) - return; - if (p == tfff_p1) - ++tfff_p1_freed; - if (p == tfff_p2) - ++tfff_p2_freed; - free(p); -} -static void * -tfff_realloc(void *p, size_t sz) -{ - return realloc(p,sz); -} -#endif - -static void -test_fin_free_finalize(void *arg) -{ -#ifdef EVENT__DISABLE_MM_REPLACEMENT - tinytest_set_test_skipped_(); -#else - struct event_base *base = NULL; - struct event *ev, *ev2; - int ev_called = 0; - int ev2_called = 0; - - (void)arg; - - event_set_mem_functions(tfff_malloc, tfff_realloc, tfff_free); - - base = event_base_new(); - tt_assert(base); - - ev = evtimer_new(base, timer_callback, &ev_called); - ev2 = evtimer_new(base, timer_callback, &ev2_called); - tfff_p1 = ev; - tfff_p2 = ev2; - event_free_finalize(0, ev, event_finalize_callback_1); - event_finalize(0, ev2, event_finalize_callback_1); - - event_base_dispatch(base); - - tt_int_op(ev_called, ==, 100); - tt_int_op(ev2_called, ==, 100); - - event_base_assert_ok_(base); - tt_int_op(tfff_p1_freed, ==, 1); - tt_int_op(tfff_p2_freed, ==, 0); - - event_free(ev2); - -end: - if (base) - event_base_free(base); -#endif -} - -/* For test_fin_within_cb */ -struct event_and_count { - struct event *ev; - struct event *ev2; - int count; -}; -static void -event_finalize_callback_2(struct event *ev, void *arg) -{ - struct event_and_count *evc = arg; - evc->count += 100; - event_free(ev); -} -static void -timer_callback_2(evutil_socket_t fd, short what, void *arg) -{ - struct event_and_count *evc = arg; - event_finalize(0, evc->ev, event_finalize_callback_2); - event_finalize(0, evc->ev2, event_finalize_callback_2); - ++ evc->count; - (void)fd; - (void)what; -} - -static void -test_fin_within_cb(void *arg) -{ - struct basic_test_data *data = arg; - struct event_base *base = data->base; - - struct event_and_count evc1, evc2; - evc1.count = evc2.count = 0; - evc2.ev2 = evc1.ev = evtimer_new(base, timer_callback_2, &evc1); - evc1.ev2 = evc2.ev = evtimer_new(base, timer_callback_2, &evc2); - - /* Activate both. The first one will have its callback run, which - * will finalize both of them, preventing the second one's callback - * from running. */ - event_active(evc1.ev, EV_TIMEOUT, 1); - event_active(evc2.ev, EV_TIMEOUT, 1); - - event_base_dispatch(base); - tt_int_op(evc1.count, ==, 101); - tt_int_op(evc2.count, ==, 100); - - event_base_assert_ok_(base); - /* Now try with EV_PERSIST events. */ - evc1.count = evc2.count = 0; - evc2.ev2 = evc1.ev = event_new(base, -1, EV_PERSIST, timer_callback_2, &evc1); - evc1.ev2 = evc2.ev = event_new(base, -1, EV_PERSIST, timer_callback_2, &evc2); - - event_active(evc1.ev, EV_TIMEOUT, 1); - event_active(evc2.ev, EV_TIMEOUT, 1); - - event_base_dispatch(base); - tt_int_op(evc1.count, ==, 101); - tt_int_op(evc2.count, ==, 100); - - event_base_assert_ok_(base); -end: - ; -} - -#if 0 -static void -timer_callback_3(evutil_socket_t *fd, short what, void *arg) -{ - (void)fd; - (void)what; - -} -static void -test_fin_many(void *arg) -{ - struct basic_test_data *data = arg; - struct event_base *base = data->base; - - struct event *ev1, *ev2; - struct event_callback evcb1, evcb2; - int ev1_count = 0, ev2_count = 0; - int evcb1_count = 0, evcb2_count = 0; - struct event_callback *array[4]; - - int n; - - /* First attempt: call finalize_many with no events running */ - ev1 = evtimer_new(base, timer_callback, &ev1_count); - ev1 = evtimer_new(base, timer_callback, &ev2_count); - event_deferred_cb_init_(&evcb1, 0, simple_callback, &evcb1_called); - event_deferred_cb_init_(&evcb2, 0, simple_callback, &evcb2_called); - array[0] = &ev1->ev_evcallback; - array[1] = &ev2->ev_evcallback; - array[2] = &evcb1; - array[3] = &evcb2; - - - - n = event_callback_finalize_many(base, 4, array, - callback_finalize_callback_1); - -} -#endif - - -#define TEST(name, flags) \ - { #name, test_fin_##name, (flags), &basic_setup, NULL } - -struct testcase_t finalize_testcases[] = { - - TEST(cb_invoked, TT_FORK|TT_NEED_BASE), - TEST(free_finalize, TT_FORK), - TEST(within_cb, TT_FORK|TT_NEED_BASE), -// TEST(many, TT_FORK|TT_NEED_BASE), - - - END_OF_TESTCASES -}; - diff --git a/protocols/Telegram/tgl/libevent/test/regress_finalize.obj b/protocols/Telegram/tgl/libevent/test/regress_finalize.obj Binary files differdeleted file mode 100644 index 765fd66e38..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress_finalize.obj +++ /dev/null diff --git a/protocols/Telegram/tgl/libevent/test/regress_http.c b/protocols/Telegram/tgl/libevent/test/regress_http.c deleted file mode 100644 index cbe7aea34c..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress_http.c +++ /dev/null @@ -1,4335 +0,0 @@ -/* - * Copyright (c) 2003-2007 Niels Provos <provos@citi.umich.edu> - * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "util-internal.h" - -#ifdef _WIN32 -#include <winsock2.h> -#include <ws2tcpip.h> -#include <windows.h> -#endif - -#include "event2/event-config.h" - -#include <sys/types.h> -#include <sys/stat.h> -#ifdef EVENT__HAVE_SYS_TIME_H -#include <sys/time.h> -#endif -#include <sys/queue.h> -#ifndef _WIN32 -#include <sys/socket.h> -#include <signal.h> -#include <unistd.h> -#include <netdb.h> -#endif -#include <fcntl.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> - -#include "event2/dns.h" - -#include "event2/event.h" -#include "event2/http.h" -#include "event2/buffer.h" -#include "event2/bufferevent.h" -#include "event2/bufferevent_ssl.h" -#include "event2/util.h" -#include "event2/listener.h" -#include "log-internal.h" -#include "http-internal.h" -#include "regress.h" -#include "regress_testutils.h" - -static struct evhttp *http; -/* set if a test needs to call loopexit on a base */ -static struct event_base *exit_base; - -static char const BASIC_REQUEST_BODY[] = "This is funny"; - -#define IMPL_HTTP_REQUEST_ERROR_CB(name, expecting_error) \ - static void \ - http_request_error_cb_with_##name##_(enum evhttp_request_error error, \ - void *arg) \ - { \ - if (error != expecting_error) { \ - fprintf(stderr, "FAILED\n"); \ - exit(1); \ - } \ - test_ok = 1; \ - } -IMPL_HTTP_REQUEST_ERROR_CB(cancel, EVREQ_HTTP_REQUEST_CANCEL) - -static void http_basic_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); -static void http_put_cb(struct evhttp_request *req, void *arg); -static void http_delete_cb(struct evhttp_request *req, void *arg); -static void http_delay_cb(struct evhttp_request *req, void *arg); -static void http_large_delay_cb(struct evhttp_request *req, void *arg); -static void http_badreq_cb(struct evhttp_request *req, void *arg); -static void http_dispatcher_cb(struct evhttp_request *req, void *arg); -static void http_on_complete_cb(struct evhttp_request *req, void *arg); - -#define HTTP_BIND_IPV6 1 -#define HTTP_BIND_SSL 2 -static int -http_bind(struct evhttp *myhttp, ev_uint16_t *pport, int mask) -{ - int port; - struct evhttp_bound_socket *sock; - int ipv6 = mask & HTTP_BIND_IPV6; - - if (ipv6) - sock = evhttp_bind_socket_with_handle(myhttp, "::1", *pport); - else - sock = evhttp_bind_socket_with_handle(myhttp, "127.0.0.1", *pport); - - if (sock == NULL) { - if (ipv6) - return -1; - else - event_errx(1, "Could not start web server"); - } - - port = regress_get_socket_port(evhttp_bound_socket_get_fd(sock)); - if (port < 0) - return -1; - *pport = (ev_uint16_t) port; - - return 0; -} - -#ifdef EVENT__HAVE_OPENSSL -static struct bufferevent * -https_bev(struct event_base *base, void *arg) -{ - SSL *ssl = SSL_new(get_ssl_ctx()); - - SSL_use_certificate(ssl, ssl_getcert()); - SSL_use_PrivateKey(ssl, ssl_getkey()); - - return bufferevent_openssl_socket_new( - base, -1, ssl, BUFFEREVENT_SSL_ACCEPTING, - BEV_OPT_CLOSE_ON_FREE); -} -#endif -static struct evhttp * -http_setup(ev_uint16_t *pport, struct event_base *base, int mask) -{ - struct evhttp *myhttp; - - /* Try a few different ports */ - myhttp = evhttp_new(base); - - if (http_bind(myhttp, pport, mask) < 0) - return NULL; -#ifdef EVENT__HAVE_OPENSSL - if (mask & HTTP_BIND_SSL) { - init_ssl(); - evhttp_set_bevcb(myhttp, https_bev, NULL); - } -#endif - - /* Register a callback for certain types of requests */ - evhttp_set_cb(myhttp, "/test", http_basic_cb, base); - 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); - evhttp_set_cb(myhttp, "/postit", http_post_cb, base); - evhttp_set_cb(myhttp, "/putit", http_put_cb, base); - evhttp_set_cb(myhttp, "/deleteit", http_delete_cb, base); - evhttp_set_cb(myhttp, "/delay", http_delay_cb, base); - evhttp_set_cb(myhttp, "/largedelay", http_large_delay_cb, base); - evhttp_set_cb(myhttp, "/badrequest", http_badreq_cb, base); - evhttp_set_cb(myhttp, "/oncomplete", http_on_complete_cb, base); - evhttp_set_cb(myhttp, "/", http_dispatcher_cb, base); - return (myhttp); -} - -#ifndef NI_MAXSERV -#define NI_MAXSERV 1024 -#endif - -static evutil_socket_t -http_connect(const char *address, unsigned short port) -{ - /* Stupid code for connecting */ - struct evutil_addrinfo ai, *aitop; - char strport[NI_MAXSERV]; - - struct sockaddr *sa; - int slen; - evutil_socket_t fd; - - memset(&ai, 0, sizeof(ai)); - ai.ai_family = AF_INET; - ai.ai_socktype = SOCK_STREAM; - evutil_snprintf(strport, sizeof(strport), "%d", port); - if (evutil_getaddrinfo(address, strport, &ai, &aitop) != 0) { - event_warn("getaddrinfo"); - return (-1); - } - sa = aitop->ai_addr; - slen = aitop->ai_addrlen; - - fd = socket(AF_INET, SOCK_STREAM, 0); - if (fd == -1) - event_err(1, "socket failed"); - - evutil_make_socket_nonblocking(fd); - if (connect(fd, sa, slen) == -1) { -#ifdef _WIN32 - int tmp_err = WSAGetLastError(); - if (tmp_err != WSAEINPROGRESS && tmp_err != WSAEINVAL && - tmp_err != WSAEWOULDBLOCK) - event_err(1, "connect failed"); -#else - if (errno != EINPROGRESS) - event_err(1, "connect failed"); -#endif - } - - evutil_freeaddrinfo(aitop); - - return (fd); -} - -/* Helper: do a strcmp on the contents of buf and the string s. */ -static int -evbuffer_datacmp(struct evbuffer *buf, const char *s) -{ - size_t b_sz = evbuffer_get_length(buf); - size_t s_sz = strlen(s); - unsigned char *d; - int r; - - if (b_sz < s_sz) - return -1; - - d = evbuffer_pullup(buf, s_sz); - if ((r = memcmp(d, s, s_sz))) - return r; - - if (b_sz > s_sz) - return 1; - else - return 0; -} - -/* Helper: Return true iff buf contains s */ -static int -evbuffer_contains(struct evbuffer *buf, const char *s) -{ - struct evbuffer_ptr ptr; - ptr = evbuffer_search(buf, s, strlen(s), NULL); - return ptr.pos != -1; -} - -static void -http_readcb(struct bufferevent *bev, void *arg) -{ - const char *what = BASIC_REQUEST_BODY; - struct event_base *my_base = arg; - - if (evbuffer_contains(bufferevent_get_input(bev), what)) { - struct evhttp_request *req = evhttp_request_new(NULL, NULL); - enum message_read_status done; - - /* req->kind = EVHTTP_RESPONSE; */ - done = evhttp_parse_firstline_(req, bufferevent_get_input(bev)); - if (done != ALL_DATA_READ) - goto out; - - done = evhttp_parse_headers_(req, bufferevent_get_input(bev)); - if (done != ALL_DATA_READ) - goto out; - - if (done == 1 && - evhttp_find_header(evhttp_request_get_input_headers(req), - "Content-Type") != NULL) - test_ok++; - - out: - evhttp_request_free(req); - bufferevent_disable(bev, EV_READ); - if (exit_base) - event_base_loopexit(exit_base, NULL); - else if (my_base) - event_base_loopexit(my_base, NULL); - else { - fprintf(stderr, "No way to exit loop!\n"); - exit(1); - } - } -} - -static void -http_writecb(struct bufferevent *bev, void *arg) -{ - if (evbuffer_get_length(bufferevent_get_output(bev)) == 0) { - /* enable reading of the reply */ - bufferevent_enable(bev, EV_READ); - test_ok++; - } -} - -static void -http_errorcb(struct bufferevent *bev, short what, void *arg) -{ - /** For ssl */ - if (what & BEV_EVENT_CONNECTED) - return; - test_ok = -2; - event_base_loopexit(arg, NULL); -} - -static int found_multi = 0; -static int found_multi2 = 0; - -static void -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) == http); - - /* For multi-line headers test */ - { - const char *multi = - evhttp_find_header(evhttp_request_get_input_headers(req),"X-Multi"); - if (multi) { - found_multi = !strcmp(multi,"aaaaaaaa a END"); - if (strcmp("END", multi + strlen(multi) - 3) == 0) - test_ok++; - if (evhttp_find_header(evhttp_request_get_input_headers(req), "X-Last")) - test_ok++; - } - } - { - const char *multi2 = - evhttp_find_header(evhttp_request_get_input_headers(req),"X-Multi-Extra-WS"); - if (multi2) { - found_multi2 = !strcmp(multi2,"libevent 2.1"); - } - } - - - /* injecting a bad content-length */ - if (evhttp_find_header(evhttp_request_get_input_headers(req), "X-Negative")) - evhttp_add_header(evhttp_request_get_output_headers(req), - "Content-Length", "-100"); - - /* allow sending of an empty reply */ - evhttp_send_reply(req, HTTP_OK, "Everything is fine", - !empty ? evb : NULL); - -end: - evbuffer_free(evb); -} - -static void -http_large_cb(struct evhttp_request *req, void *arg) -{ - struct evbuffer *evb = evbuffer_new(); - int i; - - for (i = 0; i < 1<<20; ++i) { - evbuffer_add_printf(evb, BASIC_REQUEST_BODY); - } - evhttp_send_reply(req, HTTP_OK, "Everything is fine", evb); - evbuffer_free(evb); -} - -static char const* const CHUNKS[] = { - "This is funny", - "but not hilarious.", - "bwv 1052" -}; - -struct chunk_req_state { - struct event_base *base; - struct evhttp_request *req; - int i; -}; - -static void -http_chunked_trickle_cb(evutil_socket_t fd, short events, void *arg) -{ - struct evbuffer *evb = evbuffer_new(); - struct chunk_req_state *state = arg; - struct timeval when = { 0, 0 }; - - evbuffer_add_printf(evb, "%s", CHUNKS[state->i]); - evhttp_send_reply_chunk(state->req, evb); - evbuffer_free(evb); - - if (++state->i < (int) (sizeof(CHUNKS)/sizeof(CHUNKS[0]))) { - event_base_once(state->base, -1, EV_TIMEOUT, - http_chunked_trickle_cb, state, &when); - } else { - evhttp_send_reply_end(state->req); - free(state); - } -} - -static void -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__)); - - memset(state, 0, sizeof(struct chunk_req_state)); - state->req = req; - state->base = arg; - - if (strcmp(evhttp_request_get_uri(req), "/streamed") == 0) { - evhttp_add_header(evhttp_request_get_output_headers(req), "Content-Length", "39"); - } - - /* generate a chunked/streamed reply */ - evhttp_send_reply_start(req, HTTP_OK, "Everything is fine"); - - /* but trickle it across several iterations to ensure we're not - * assuming it comes all at once */ - 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) -{ - int flags = BEV_OPT_DEFER_CALLBACKS; - struct bufferevent *bev = NULL; - - if (!ssl) { - bev = bufferevent_socket_new(base, fd, flags); - } else { -#ifdef EVENT__HAVE_OPENSSL - SSL *ssl = SSL_new(get_ssl_ctx()); - bev = bufferevent_openssl_socket_new( - base, fd, ssl, BUFFEREVENT_SSL_CONNECTING, flags); - bufferevent_openssl_set_allow_dirty_shutdown(bev, 1); -#endif - } - - return bev; -} - -static void -http_basic_test_impl(void *arg, int ssl) -{ - struct basic_test_data *data = arg; - struct timeval tv; - struct bufferevent *bev = NULL; - evutil_socket_t fd; - const char *http_request; - ev_uint16_t port = 0, port2 = 0; - int server_flags = ssl ? HTTP_BIND_SSL : 0; - - test_ok = 0; - - http = http_setup(&port, data->base, server_flags); - - /* bind to a second socket */ - if (http_bind(http, &port2, server_flags) == -1) { - fprintf(stdout, "FAILED (bind)\n"); - exit(1); - } - - fd = http_connect("127.0.0.1", port); - - /* Stupid thing to send a request */ - bev = create_bev(data->base, fd, ssl); - bufferevent_setcb(bev, http_readcb, http_writecb, - http_errorcb, data->base); - - /* first half of the http request */ - http_request = - "GET /test HTTP/1.1\r\n" - "Host: some"; - - bufferevent_write(bev, http_request, strlen(http_request)); - evutil_timerclear(&tv); - tv.tv_usec = 10000; - event_base_once(data->base, - -1, EV_TIMEOUT, http_complete_write, bev, &tv); - - event_base_dispatch(data->base); - - tt_assert(test_ok == 3); - - /* connect to the second port */ - bufferevent_free(bev); - evutil_closesocket(fd); - - fd = http_connect("127.0.0.1", port2); - - /* Stupid thing to send a request */ - bev = create_bev(data->base, fd, ssl); - bufferevent_setcb(bev, http_readcb, http_writecb, - http_errorcb, data->base); - - http_request = - "GET /test HTTP/1.1\r\n" - "Host: somehost\r\n" - "Connection: close\r\n" - "\r\n"; - - bufferevent_write(bev, http_request, strlen(http_request)); - - event_base_dispatch(data->base); - - tt_assert(test_ok == 5); - - /* Connect to the second port again. This time, send an absolute uri. */ - bufferevent_free(bev); - evutil_closesocket(fd); - - fd = http_connect("127.0.0.1", port2); - - /* Stupid thing to send a request */ - bev = create_bev(data->base, fd, ssl); - bufferevent_setcb(bev, http_readcb, http_writecb, - http_errorcb, data->base); - - http_request = - "GET http://somehost.net/test HTTP/1.1\r\n" - "Host: somehost\r\n" - "Connection: close\r\n" - "\r\n"; - - bufferevent_write(bev, http_request, strlen(http_request)); - - event_base_dispatch(data->base); - - tt_assert(test_ok == 7); - - evhttp_free(http); - end: - if (bev) - bufferevent_free(bev); -} -static void http_basic_test(void *arg) -{ return http_basic_test_impl(arg, 0); } - - -static void -http_delay_reply(evutil_socket_t fd, short what, void *arg) -{ - struct evhttp_request *req = arg; - - evhttp_send_reply(req, HTTP_OK, "Everything is fine", NULL); - - ++test_ok; -} - -static void -http_delay_cb(struct evhttp_request *req, void *arg) -{ - struct timeval tv; - evutil_timerclear(&tv); - tv.tv_sec = 0; - tv.tv_usec = 200 * 1000; - - event_base_once(arg, -1, EV_TIMEOUT, http_delay_reply, req, &tv); -} - -static void -http_badreq_cb(struct evhttp_request *req, void *arg) -{ - struct evbuffer *buf = evbuffer_new(); - - evhttp_add_header(evhttp_request_get_output_headers(req), "Content-Type", "text/xml; charset=UTF-8"); - evbuffer_add_printf(buf, "Hello, %s!", "127.0.0.1"); - - evhttp_send_reply(req, HTTP_OK, "OK", buf); - evbuffer_free(buf); -} - -static void -http_badreq_errorcb(struct bufferevent *bev, short what, void *arg) -{ - event_debug(("%s: called (what=%04x, arg=%p)", __func__, what, arg)); - /* ignore */ -} - -#ifndef SHUT_WR -#ifdef _WIN32 -#define SHUT_WR SD_SEND -#else -#define SHUT_WR 1 -#endif -#endif - -static void -http_badreq_readcb(struct bufferevent *bev, void *arg) -{ - const char *what = "Hello, 127.0.0.1"; - const char *bad_request = "400 Bad Request"; - - if (evbuffer_contains(bufferevent_get_input(bev), bad_request)) { - TT_FAIL(("%s:bad request detected", __func__)); - bufferevent_disable(bev, EV_READ); - event_base_loopexit(arg, NULL); - return; - } - - if (evbuffer_contains(bufferevent_get_input(bev), what)) { - struct evhttp_request *req = evhttp_request_new(NULL, NULL); - enum message_read_status done; - - /* req->kind = EVHTTP_RESPONSE; */ - done = evhttp_parse_firstline_(req, bufferevent_get_input(bev)); - if (done != ALL_DATA_READ) - goto out; - - done = evhttp_parse_headers_(req, bufferevent_get_input(bev)); - if (done != ALL_DATA_READ) - goto out; - - if (done == 1 && - evhttp_find_header(evhttp_request_get_input_headers(req), - "Content-Type") != NULL) - test_ok++; - - out: - evhttp_request_free(req); - evbuffer_drain(bufferevent_get_input(bev), evbuffer_get_length(bufferevent_get_input(bev))); - } - - shutdown(bufferevent_getfd(bev), SHUT_WR); -} - -static void -http_badreq_successcb(evutil_socket_t fd, short what, void *arg) -{ - event_debug(("%s: called (what=%04x, arg=%p)", __func__, what, arg)); - event_base_loopexit(exit_base, NULL); -} - -static void -http_bad_request_test(void *arg) -{ - struct basic_test_data *data = arg; - struct timeval tv; - struct bufferevent *bev = NULL; - evutil_socket_t fd = -1; - const char *http_request; - ev_uint16_t port=0, port2=0; - - test_ok = 0; - exit_base = data->base; - - http = http_setup(&port, data->base, 0); - - /* bind to a second socket */ - if (http_bind(http, &port2, 0) == -1) - TT_DIE(("Bind socket failed")); - - /* NULL request test */ - fd = http_connect("127.0.0.1", port); - tt_int_op(fd, >=, 0); - - /* Stupid thing to send a request */ - bev = bufferevent_socket_new(data->base, fd, 0); - bufferevent_setcb(bev, http_badreq_readcb, http_writecb, - http_badreq_errorcb, data->base); - bufferevent_enable(bev, EV_READ); - - /* real NULL request */ - http_request = ""; - - bufferevent_write(bev, http_request, strlen(http_request)); - - shutdown(fd, SHUT_WR); - timerclear(&tv); - tv.tv_usec = 10000; - event_base_once(data->base, -1, EV_TIMEOUT, http_badreq_successcb, bev, &tv); - - event_base_dispatch(data->base); - - bufferevent_free(bev); - evutil_closesocket(fd); - - if (test_ok != 0) { - fprintf(stdout, "FAILED\n"); - exit(1); - } - - /* Second answer (BAD REQUEST) on connection close */ - - /* connect to the second port */ - fd = http_connect("127.0.0.1", port2); - - /* Stupid thing to send a request */ - bev = bufferevent_socket_new(data->base, fd, 0); - bufferevent_setcb(bev, http_badreq_readcb, http_writecb, - http_badreq_errorcb, data->base); - bufferevent_enable(bev, EV_READ); - - /* first half of the http request */ - http_request = - "GET /badrequest HTTP/1.0\r\n" \ - "Connection: Keep-Alive\r\n" \ - "\r\n"; - - bufferevent_write(bev, http_request, strlen(http_request)); - - timerclear(&tv); - tv.tv_usec = 10000; - event_base_once(data->base, -1, EV_TIMEOUT, http_badreq_successcb, bev, &tv); - - event_base_dispatch(data->base); - - tt_int_op(test_ok, ==, 2); - -end: - evhttp_free(http); - if (bev) - bufferevent_free(bev); - if (fd >= 0) - evutil_closesocket(fd); -} - -static struct evhttp_connection *delayed_client; - -static void -http_large_delay_cb(struct evhttp_request *req, void *arg) -{ - struct timeval tv; - evutil_timerclear(&tv); - tv.tv_usec = 500000; - - event_base_once(arg, -1, EV_TIMEOUT, http_delay_reply, req, &tv); - evhttp_connection_fail_(delayed_client, EVREQ_HTTP_EOF); -} - -/* - * HTTP DELETE test, just piggyback on the basic test - */ - -static void -http_delete_cb(struct evhttp_request *req, void *arg) -{ - struct evbuffer *evb = evbuffer_new(); - int empty = evhttp_find_header(evhttp_request_get_input_headers(req), "Empty") != NULL; - - /* Expecting a DELETE request */ - if (evhttp_request_get_command(req) != EVHTTP_REQ_DELETE) { - fprintf(stdout, "FAILED (delete type)\n"); - exit(1); - } - - event_debug(("%s: called\n", __func__)); - evbuffer_add_printf(evb, BASIC_REQUEST_BODY); - - /* allow sending of an empty reply */ - evhttp_send_reply(req, HTTP_OK, "Everything is fine", - !empty ? evb : NULL); - - evbuffer_free(evb); -} - -static void -http_delete_test(void *arg) -{ - struct basic_test_data *data = arg; - struct bufferevent *bev; - evutil_socket_t fd = -1; - const char *http_request; - ev_uint16_t port = 0; - - test_ok = 0; - - http = http_setup(&port, data->base, 0); - - tt_assert(http); - fd = http_connect("127.0.0.1", port); - tt_int_op(fd, >=, 0); - - /* Stupid thing to send a request */ - bev = bufferevent_socket_new(data->base, fd, 0); - bufferevent_setcb(bev, http_readcb, http_writecb, - http_errorcb, data->base); - - http_request = - "DELETE /deleteit HTTP/1.1\r\n" - "Host: somehost\r\n" - "Connection: close\r\n" - "\r\n"; - - bufferevent_write(bev, http_request, strlen(http_request)); - - event_base_dispatch(data->base); - - bufferevent_free(bev); - evutil_closesocket(fd); - fd = -1; - - evhttp_free(http); - - tt_int_op(test_ok, ==, 2); - end: - if (fd >= 0) - evutil_closesocket(fd); -} - -static void -http_sent_cb(struct evhttp_request *req, void *arg) -{ - ev_uintptr_t val = (ev_uintptr_t)arg; - struct evbuffer *b; - - if (val != 0xDEADBEEF) { - fprintf(stdout, "FAILED on_complete_cb argument\n"); - exit(1); - } - - b = evhttp_request_get_output_buffer(req); - if (evbuffer_get_length(b) != 0) { - fprintf(stdout, "FAILED on_complete_cb output buffer not written\n"); - exit(1); - } - - event_debug(("%s: called\n", __func__)); - - ++test_ok; -} - -static void -http_on_complete_cb(struct evhttp_request *req, void *arg) -{ - struct evbuffer *evb = evbuffer_new(); - - evhttp_request_set_on_complete_cb(req, http_sent_cb, (void *)0xDEADBEEF); - - event_debug(("%s: called\n", __func__)); - evbuffer_add_printf(evb, BASIC_REQUEST_BODY); - - /* allow sending of an empty reply */ - evhttp_send_reply(req, HTTP_OK, "Everything is fine", evb); - - evbuffer_free(evb); - - ++test_ok; -} - -static void -http_on_complete_test(void *arg) -{ - struct basic_test_data *data = arg; - struct bufferevent *bev; - evutil_socket_t fd = -1; - const char *http_request; - ev_uint16_t port = 0; - - test_ok = 0; - - http = http_setup(&port, data->base, 0); - - fd = http_connect("127.0.0.1", port); - tt_int_op(fd, >=, 0); - - /* Stupid thing to send a request */ - bev = bufferevent_socket_new(data->base, fd, 0); - bufferevent_setcb(bev, http_readcb, http_writecb, - http_errorcb, data->base); - - http_request = - "GET /oncomplete HTTP/1.1\r\n" - "Host: somehost\r\n" - "Connection: close\r\n" - "\r\n"; - - bufferevent_write(bev, http_request, strlen(http_request)); - - event_base_dispatch(data->base); - - bufferevent_free(bev); - - evhttp_free(http); - - tt_int_op(test_ok, ==, 4); - end: - if (fd >= 0) - evutil_closesocket(fd); -} - -static void -http_allowed_methods_eventcb(struct bufferevent *bev, short what, void *arg) -{ - char **output = arg; - if ((what & (BEV_EVENT_ERROR|BEV_EVENT_EOF))) { - char buf[4096]; - int n; - n = evbuffer_remove(bufferevent_get_input(bev), buf, - sizeof(buf)-1); - if (n >= 0) { - buf[n]='\0'; - if (*output) - free(*output); - *output = strdup(buf); - } - event_base_loopexit(exit_base, NULL); - } -} - -static void -http_allowed_methods_test(void *arg) -{ - struct basic_test_data *data = arg; - struct bufferevent *bev1, *bev2, *bev3; - evutil_socket_t fd1=-1, fd2=-1, fd3=-1; - const char *http_request; - char *result1=NULL, *result2=NULL, *result3=NULL; - ev_uint16_t port = 0; - - exit_base = data->base; - test_ok = 0; - - http = http_setup(&port, data->base, 0); - - fd1 = http_connect("127.0.0.1", port); - tt_int_op(fd1, >=, 0); - - /* GET is out; PATCH is in. */ - evhttp_set_allowed_methods(http, EVHTTP_REQ_PATCH); - - /* Stupid thing to send a request */ - bev1 = bufferevent_socket_new(data->base, fd1, 0); - bufferevent_enable(bev1, EV_READ|EV_WRITE); - bufferevent_setcb(bev1, NULL, NULL, - http_allowed_methods_eventcb, &result1); - - http_request = - "GET /index.html HTTP/1.1\r\n" - "Host: somehost\r\n" - "Connection: close\r\n" - "\r\n"; - - bufferevent_write(bev1, http_request, strlen(http_request)); - - event_base_dispatch(data->base); - - fd2 = http_connect("127.0.0.1", port); - tt_int_op(fd2, >=, 0); - - bev2 = bufferevent_socket_new(data->base, fd2, 0); - bufferevent_enable(bev2, EV_READ|EV_WRITE); - bufferevent_setcb(bev2, NULL, NULL, - http_allowed_methods_eventcb, &result2); - - http_request = - "PATCH /test HTTP/1.1\r\n" - "Host: somehost\r\n" - "Connection: close\r\n" - "\r\n"; - - bufferevent_write(bev2, http_request, strlen(http_request)); - - event_base_dispatch(data->base); - - fd3 = http_connect("127.0.0.1", port); - tt_int_op(fd3, >=, 0); - - bev3 = bufferevent_socket_new(data->base, fd3, 0); - bufferevent_enable(bev3, EV_READ|EV_WRITE); - bufferevent_setcb(bev3, NULL, NULL, - http_allowed_methods_eventcb, &result3); - - http_request = - "FLOOP /test HTTP/1.1\r\n" - "Host: somehost\r\n" - "Connection: close\r\n" - "\r\n"; - - bufferevent_write(bev3, http_request, strlen(http_request)); - - event_base_dispatch(data->base); - - bufferevent_free(bev1); - bufferevent_free(bev2); - bufferevent_free(bev3); - - evhttp_free(http); - - /* Method known but disallowed */ - tt_assert(result1); - tt_assert(!strncmp(result1, "HTTP/1.1 501 ", strlen("HTTP/1.1 501 "))); - - /* Method known and allowed */ - tt_assert(result2); - tt_assert(!strncmp(result2, "HTTP/1.1 200 ", strlen("HTTP/1.1 200 "))); - - /* Method unknown */ - tt_assert(result3); - tt_assert(!strncmp(result3, "HTTP/1.1 501 ", strlen("HTTP/1.1 501 "))); - - end: - if (result1) - free(result1); - if (result2) - free(result2); - if (result3) - free(result3); - if (fd1 >= 0) - evutil_closesocket(fd1); - if (fd2 >= 0) - evutil_closesocket(fd2); - if (fd3 >= 0) - evutil_closesocket(fd3); -} - -static void http_request_no_action_done(struct evhttp_request *, void *); -static void http_request_done(struct evhttp_request *, void *); -static void http_request_empty_done(struct evhttp_request *, void *); - -static void -http_connection_test_(struct basic_test_data *data, int persistent, - const char *address, struct evdns_base *dnsbase, int ipv6, int family) -{ - ev_uint16_t port = 0; - struct evhttp_connection *evcon = NULL; - struct evhttp_request *req = NULL; - - test_ok = 0; - - http = http_setup(&port, data->base, ipv6); - if (!http && ipv6) { - tt_skip(); - } - tt_assert(http); - - evcon = evhttp_connection_base_new(data->base, dnsbase, address, port); - tt_assert(evcon); - evhttp_connection_set_family(evcon, family); - - tt_assert(evhttp_connection_get_base(evcon) == data->base); - - exit_base = data->base; - - tt_assert(evhttp_connection_get_server(evcon) == NULL); - - /* - * At this point, we want to schedule a request to the HTTP - * server using our make request method. - */ - req = evhttp_request_new(http_request_done, (void*) BASIC_REQUEST_BODY); - - /* Add the information that we care about */ - evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); - - /* We give ownership of the request to the connection */ - if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") == -1) { - fprintf(stdout, "FAILED\n"); - exit(1); - } - - event_base_dispatch(data->base); - - tt_assert(test_ok); - - /* try to make another request over the same connection */ - test_ok = 0; - - req = evhttp_request_new(http_request_done, (void*) BASIC_REQUEST_BODY); - - /* Add the information that we care about */ - evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); - - /* - * if our connections are not supposed to be persistent; request - * a close from the server. - */ - if (!persistent) - evhttp_add_header(evhttp_request_get_output_headers(req), "Connection", "close"); - - /* We give ownership of the request to the connection */ - if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") == -1) { - tt_abort_msg("couldn't make request"); - } - - event_base_dispatch(data->base); - - /* make another request: request empty reply */ - test_ok = 0; - - req = evhttp_request_new(http_request_empty_done, data->base); - - /* Add the information that we care about */ - evhttp_add_header(evhttp_request_get_output_headers(req), "Empty", "itis"); - - /* We give ownership of the request to the connection */ - if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") == -1) { - tt_abort_msg("Couldn't make request"); - } - - event_base_dispatch(data->base); - - end: - if (evcon) - evhttp_connection_free(evcon); - if (http) - evhttp_free(http); -} - -static void -http_connection_test(void *arg) -{ - http_connection_test_(arg, 0, "127.0.0.1", NULL, 0, AF_UNSPEC); -} -static void -http_persist_connection_test(void *arg) -{ - http_connection_test_(arg, 1, "127.0.0.1", NULL, 0, AF_UNSPEC); -} - -static struct regress_dns_server_table search_table[] = { - { "localhost", "A", "127.0.0.1", 0, 0 }, - { NULL, NULL, NULL, 0, 0 } -}; - -static void -http_connection_async_test(void *arg) -{ - struct basic_test_data *data = arg; - ev_uint16_t port = 0; - struct evhttp_connection *evcon = NULL; - struct evhttp_request *req = NULL; - struct evdns_base *dns_base = NULL; - ev_uint16_t portnum = 0; - char address[64]; - - exit_base = data->base; - tt_assert(regress_dnsserver(data->base, &portnum, search_table)); - - dns_base = evdns_base_new(data->base, 0/* init name servers */); - tt_assert(dns_base); - - /* Add ourself as the only nameserver, and make sure we really are - * the only nameserver. */ - evutil_snprintf(address, sizeof(address), "127.0.0.1:%d", portnum); - evdns_base_nameserver_ip_add(dns_base, address); - - test_ok = 0; - - http = http_setup(&port, data->base, 0); - - evcon = evhttp_connection_base_new(data->base, dns_base, "127.0.0.1", port); - tt_assert(evcon); - - /* - * At this point, we want to schedule a request to the HTTP - * server using our make request method. - */ - - req = evhttp_request_new(http_request_done, (void*) BASIC_REQUEST_BODY); - - /* Add the information that we care about */ - evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); - - /* We give ownership of the request to the connection */ - if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") == -1) { - fprintf(stdout, "FAILED\n"); - exit(1); - } - - event_base_dispatch(data->base); - - tt_assert(test_ok); - - /* try to make another request over the same connection */ - test_ok = 0; - - req = evhttp_request_new(http_request_done, (void*) BASIC_REQUEST_BODY); - - /* Add the information that we care about */ - evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); - - /* - * if our connections are not supposed to be persistent; request - * a close from the server. - */ - evhttp_add_header(evhttp_request_get_output_headers(req), "Connection", "close"); - - /* We give ownership of the request to the connection */ - if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") == -1) { - tt_abort_msg("couldn't make request"); - } - - event_base_dispatch(data->base); - - /* make another request: request empty reply */ - test_ok = 0; - - req = evhttp_request_new(http_request_empty_done, data->base); - - /* Add the information that we care about */ - evhttp_add_header(evhttp_request_get_output_headers(req), "Empty", "itis"); - - /* We give ownership of the request to the connection */ - if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") == -1) { - tt_abort_msg("Couldn't make request"); - } - - event_base_dispatch(data->base); - - end: - if (evcon) - evhttp_connection_free(evcon); - if (http) - evhttp_free(http); - if (dns_base) - evdns_base_free(dns_base, 0); - regress_clean_dnsserver(); -} - -static void -http_autofree_connection_test(void *arg) -{ - struct basic_test_data *data = arg; - ev_uint16_t port = 0; - struct evhttp_connection *evcon = NULL; - struct evhttp_request *req[2] = { NULL }; - - test_ok = 0; - http = http_setup(&port, data->base, 0); - - evcon = evhttp_connection_base_new(data->base, NULL, "127.0.0.1", port); - tt_assert(evcon); - - /* - * At this point, we want to schedule two request to the HTTP - * server using our make request method. - */ - req[0] = evhttp_request_new(http_request_empty_done, data->base); - req[1] = evhttp_request_new(http_request_empty_done, data->base); - - /* Add the information that we care about */ - evhttp_add_header(evhttp_request_get_output_headers(req[0]), "Host", "somehost"); - evhttp_add_header(evhttp_request_get_output_headers(req[0]), "Connection", "close"); - evhttp_add_header(evhttp_request_get_output_headers(req[0]), "Empty", "itis"); - evhttp_add_header(evhttp_request_get_output_headers(req[1]), "Host", "somehost"); - evhttp_add_header(evhttp_request_get_output_headers(req[1]), "Connection", "close"); - evhttp_add_header(evhttp_request_get_output_headers(req[1]), "Empty", "itis"); - - /* We give ownership of the request to the connection */ - if (evhttp_make_request(evcon, req[0], EVHTTP_REQ_GET, "/test") == -1) { - tt_abort_msg("couldn't make request"); - } - if (evhttp_make_request(evcon, req[1], EVHTTP_REQ_GET, "/test") == -1) { - tt_abort_msg("couldn't make request"); - } - - /* - * Tell libevent to free the connection when the request completes - * We then set the evcon pointer to NULL since we don't want to free it - * when this function ends. - */ - evhttp_connection_free_on_completion(evcon); - evcon = NULL; - - event_base_dispatch(data->base); - - /* at this point, the http server should have no connection */ - tt_assert(TAILQ_FIRST(&http->connections) == NULL); - - end: - if (evcon) - evhttp_connection_free(evcon); - if (http) - evhttp_free(http); -} - -static void -http_request_never_call(struct evhttp_request *req, void *arg) -{ - fprintf(stdout, "FAILED\n"); - exit(1); -} - -static void -http_do_cancel(evutil_socket_t fd, short what, void *arg) -{ - struct evhttp_request *req = arg; - struct timeval tv; - struct event_base *base; - evutil_timerclear(&tv); - tv.tv_sec = 0; - tv.tv_usec = 500 * 1000; - - base = evhttp_connection_get_base(evhttp_request_get_connection(req)); - evhttp_cancel_request(req); - - event_base_loopexit(base, &tv); - - ++test_ok; -} - -static void -http_cancel_test(void *arg) -{ - struct basic_test_data *data = arg; - ev_uint16_t port = 0; - struct evhttp_connection *evcon = NULL; - struct evhttp_request *req = NULL; - struct timeval tv; - - exit_base = data->base; - - test_ok = 0; - - http = http_setup(&port, data->base, 0); - - evcon = evhttp_connection_base_new(data->base, NULL, "127.0.0.1", port); - tt_assert(evcon); - - /* - * At this point, we want to schedule a request to the HTTP - * server using our make request method. - */ - - req = evhttp_request_new(http_request_never_call, NULL); - evhttp_request_set_error_cb(req, http_request_error_cb_with_cancel_); - - /* Add the information that we care about */ - evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); - - /* We give ownership of the request to the connection */ - tt_int_op(evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/delay"), - !=, -1); - - evutil_timerclear(&tv); - tv.tv_sec = 0; - tv.tv_usec = 100 * 1000; - - event_base_once(data->base, -1, EV_TIMEOUT, http_do_cancel, req, &tv); - - event_base_dispatch(data->base); - - tt_int_op(test_ok, ==, 3); - - /* try to make another request over the same connection */ - test_ok = 0; - - req = evhttp_request_new(http_request_done, (void*) BASIC_REQUEST_BODY); - - /* Add the information that we care about */ - evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); - - /* We give ownership of the request to the connection */ - tt_int_op(evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test"), - !=, -1); - - event_base_dispatch(data->base); - - /* make another request: request empty reply */ - test_ok = 0; - - req = evhttp_request_new(http_request_empty_done, data->base); - - /* Add the information that we care about */ - evhttp_add_header(evhttp_request_get_output_headers(req), "Empty", "itis"); - - /* We give ownership of the request to the connection */ - tt_int_op(evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test"), - !=, -1); - - event_base_dispatch(data->base); - - end: - if (evcon) - evhttp_connection_free(evcon); - if (http) - evhttp_free(http); -} - -static void -http_request_no_action_done(struct evhttp_request *req, void *arg) -{ - EVUTIL_ASSERT(exit_base); - event_base_loopexit(exit_base, NULL); -} - -static void -http_request_done(struct evhttp_request *req, void *arg) -{ - const char *what = arg; - - if (evhttp_request_get_response_code(req) != HTTP_OK) { - fprintf(stderr, "FAILED\n"); - exit(1); - } - - if (evhttp_find_header(evhttp_request_get_input_headers(req), "Content-Type") == NULL) { - fprintf(stderr, "FAILED\n"); - exit(1); - } - - if (evbuffer_get_length(evhttp_request_get_input_buffer(req)) != strlen(what)) { - fprintf(stderr, "FAILED\n"); - exit(1); - } - - if (evbuffer_datacmp(evhttp_request_get_input_buffer(req), what) != 0) { - fprintf(stderr, "FAILED\n"); - exit(1); - } - - test_ok = 1; - EVUTIL_ASSERT(exit_base); - event_base_loopexit(exit_base, NULL); -} - -static void -http_request_expect_error(struct evhttp_request *req, void *arg) -{ - if (evhttp_request_get_response_code(req) == HTTP_OK) { - fprintf(stderr, "FAILED\n"); - exit(1); - } - - test_ok = 1; - EVUTIL_ASSERT(arg); - event_base_loopexit(arg, NULL); -} - -/* test virtual hosts */ -static void -http_virtual_host_test(void *arg) -{ - struct basic_test_data *data = arg; - ev_uint16_t port = 0; - struct evhttp_connection *evcon = NULL; - struct evhttp_request *req = NULL; - struct evhttp *second = NULL, *third = NULL; - evutil_socket_t fd; - struct bufferevent *bev; - const char *http_request; - - exit_base = data->base; - - http = http_setup(&port, data->base, 0); - - /* virtual host */ - second = evhttp_new(NULL); - evhttp_set_cb(second, "/funnybunny", http_basic_cb, NULL); - third = evhttp_new(NULL); - evhttp_set_cb(third, "/blackcoffee", http_basic_cb, NULL); - - if (evhttp_add_virtual_host(http, "foo.com", second) == -1) { - tt_abort_msg("Couldn't add vhost"); - } - - if (evhttp_add_virtual_host(http, "bar.*.foo.com", third) == -1) { - tt_abort_msg("Couldn't add wildcarded vhost"); - } - - /* add some aliases to the vhosts */ - tt_assert(evhttp_add_server_alias(second, "manolito.info") == 0); - tt_assert(evhttp_add_server_alias(third, "bonkers.org") == 0); - - evcon = evhttp_connection_base_new(data->base, NULL, "127.0.0.1", port); - tt_assert(evcon); - - /* make a request with a different host and expect an error */ - req = evhttp_request_new(http_request_expect_error, data->base); - - /* Add the information that we care about */ - evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); - - /* We give ownership of the request to the connection */ - if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, - "/funnybunny") == -1) { - tt_abort_msg("Couldn't make request"); - } - - event_base_dispatch(data->base); - - tt_assert(test_ok == 1); - - test_ok = 0; - - /* make a request with the right host and expect a response */ - req = evhttp_request_new(http_request_done, (void*) BASIC_REQUEST_BODY); - - /* Add the information that we care about */ - evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "foo.com"); - - /* We give ownership of the request to the connection */ - if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, - "/funnybunny") == -1) { - fprintf(stdout, "FAILED\n"); - exit(1); - } - - event_base_dispatch(data->base); - - tt_assert(test_ok == 1); - - test_ok = 0; - - /* make a request with the right host and expect a response */ - req = evhttp_request_new(http_request_done, (void*) BASIC_REQUEST_BODY); - - /* Add the information that we care about */ - evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "bar.magic.foo.com"); - - /* We give ownership of the request to the connection */ - if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, - "/blackcoffee") == -1) { - tt_abort_msg("Couldn't make request"); - } - - event_base_dispatch(data->base); - - tt_assert(test_ok == 1) - - test_ok = 0; - - /* make a request with the right host and expect a response */ - req = evhttp_request_new(http_request_done, (void*) BASIC_REQUEST_BODY); - - /* Add the information that we care about */ - evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "manolito.info"); - - /* We give ownership of the request to the connection */ - if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, - "/funnybunny") == -1) { - tt_abort_msg("Couldn't make request"); - } - - event_base_dispatch(data->base); - - tt_assert(test_ok == 1) - - test_ok = 0; - - /* make a request with the right host and expect a response */ - req = evhttp_request_new(http_request_done, (void*) BASIC_REQUEST_BODY); - - /* Add the Host header. This time with the optional port. */ - evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "bonkers.org:8000"); - - /* We give ownership of the request to the connection */ - if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, - "/blackcoffee") == -1) { - tt_abort_msg("Couldn't make request"); - } - - event_base_dispatch(data->base); - - tt_assert(test_ok == 1) - - test_ok = 0; - - /* Now make a raw request with an absolute URI. */ - fd = http_connect("127.0.0.1", port); - - /* Stupid thing to send a request */ - bev = bufferevent_socket_new(data->base, fd, 0); - bufferevent_setcb(bev, http_readcb, http_writecb, - http_errorcb, NULL); - - /* The host in the URI should override the Host: header */ - http_request = - "GET http://manolito.info/funnybunny HTTP/1.1\r\n" - "Host: somehost\r\n" - "Connection: close\r\n" - "\r\n"; - - bufferevent_write(bev, http_request, strlen(http_request)); - - event_base_dispatch(data->base); - - tt_int_op(test_ok, ==, 2); - - bufferevent_free(bev); - evutil_closesocket(fd); - - end: - if (evcon) - evhttp_connection_free(evcon); - if (http) - evhttp_free(http); -} - - -/* test date header and content length */ - -static void -http_request_empty_done(struct evhttp_request *req, void *arg) -{ - if (evhttp_request_get_response_code(req) != HTTP_OK) { - fprintf(stderr, "FAILED\n"); - exit(1); - } - - if (evhttp_find_header(evhttp_request_get_input_headers(req), "Date") == NULL) { - fprintf(stderr, "FAILED\n"); - exit(1); - } - - - if (evhttp_find_header(evhttp_request_get_input_headers(req), "Content-Length") == NULL) { - fprintf(stderr, "FAILED\n"); - exit(1); - } - - if (strcmp(evhttp_find_header(evhttp_request_get_input_headers(req), "Content-Length"), - "0")) { - fprintf(stderr, "FAILED\n"); - exit(1); - } - - if (evbuffer_get_length(evhttp_request_get_input_buffer(req)) != 0) { - fprintf(stderr, "FAILED\n"); - exit(1); - } - - test_ok = 1; - EVUTIL_ASSERT(arg); - event_base_loopexit(arg, NULL); -} - -/* - * HTTP DISPATCHER test - */ - -void -http_dispatcher_cb(struct evhttp_request *req, void *arg) -{ - - struct evbuffer *evb = evbuffer_new(); - event_debug(("%s: called\n", __func__)); - evbuffer_add_printf(evb, "DISPATCHER_TEST"); - - evhttp_send_reply(req, HTTP_OK, "Everything is fine", evb); - - evbuffer_free(evb); -} - -static void -http_dispatcher_test_done(struct evhttp_request *req, void *arg) -{ - struct event_base *base = arg; - const char *what = "DISPATCHER_TEST"; - - if (!req) { - fprintf(stderr, "FAILED\n"); - exit(1); - } - - if (evhttp_request_get_response_code(req) != HTTP_OK) { - fprintf(stderr, "FAILED\n"); - exit(1); - } - - if (evhttp_find_header(evhttp_request_get_input_headers(req), "Content-Type") == NULL) { - fprintf(stderr, "FAILED (content type)\n"); - exit(1); - } - - if (evbuffer_get_length(evhttp_request_get_input_buffer(req)) != strlen(what)) { - fprintf(stderr, "FAILED (length %lu vs %lu)\n", - (unsigned long)evbuffer_get_length(evhttp_request_get_input_buffer(req)), (unsigned long)strlen(what)); - exit(1); - } - - if (evbuffer_datacmp(evhttp_request_get_input_buffer(req), what) != 0) { - fprintf(stderr, "FAILED (data)\n"); - exit(1); - } - - test_ok = 1; - event_base_loopexit(base, NULL); -} - -static void -http_dispatcher_test(void *arg) -{ - struct basic_test_data *data = arg; - ev_uint16_t port = 0; - struct evhttp_connection *evcon = NULL; - struct evhttp_request *req = NULL; - - test_ok = 0; - - http = http_setup(&port, data->base, 0); - - evcon = evhttp_connection_base_new(data->base, NULL, "127.0.0.1", port); - tt_assert(evcon); - - /* 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. - */ - - req = evhttp_request_new(http_dispatcher_test_done, data->base); - tt_assert(req); - - /* Add the information that we care about */ - evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); - - if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/?arg=val") == -1) { - tt_abort_msg("Couldn't make request"); - } - - event_base_dispatch(data->base); - - end: - if (evcon) - evhttp_connection_free(evcon); - if (http) - evhttp_free(http); -} - -/* - * HTTP POST test. - */ - -void http_postrequest_done(struct evhttp_request *, void *); - -#define POST_DATA "Okay. Not really printf" - -static void -http_post_test(void *arg) -{ - struct basic_test_data *data = arg; - ev_uint16_t port = 0; - struct evhttp_connection *evcon = NULL; - struct evhttp_request *req = NULL; - - test_ok = 0; - - http = http_setup(&port, data->base, 0); - - evcon = evhttp_connection_base_new(data->base, NULL, "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(http_postrequest_done, data->base); - tt_assert(req); - - /* Add the information that we care about */ - evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); - evbuffer_add_printf(evhttp_request_get_output_buffer(req), POST_DATA); - - if (evhttp_make_request(evcon, req, EVHTTP_REQ_POST, "/postit") == -1) { - tt_abort_msg("Couldn't make request"); - } - - event_base_dispatch(data->base); - - tt_int_op(test_ok, ==, 1); - - test_ok = 0; - - req = evhttp_request_new(http_postrequest_done, data->base); - tt_assert(req); - - /* Now try with 100-continue. */ - - /* Add the information that we care about */ - 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), POST_DATA); - - if (evhttp_make_request(evcon, req, EVHTTP_REQ_POST, "/postit") == -1) { - tt_abort_msg("Couldn't make request"); - } - - event_base_dispatch(data->base); - - tt_int_op(test_ok, ==, 1); - - evhttp_connection_free(evcon); - evhttp_free(http); - - end: - ; -} - -void -http_post_cb(struct evhttp_request *req, void *arg) -{ - struct evbuffer *evb; - event_debug(("%s: called\n", __func__)); - - /* Yes, we are expecting a post request */ - if (evhttp_request_get_command(req) != EVHTTP_REQ_POST) { - fprintf(stdout, "FAILED (post type)\n"); - exit(1); - } - - if (evbuffer_get_length(evhttp_request_get_input_buffer(req)) != strlen(POST_DATA)) { - fprintf(stdout, "FAILED (length: %lu vs %lu)\n", - (unsigned long) evbuffer_get_length(evhttp_request_get_input_buffer(req)), (unsigned long) strlen(POST_DATA)); - exit(1); - } - - if (evbuffer_datacmp(evhttp_request_get_input_buffer(req), POST_DATA) != 0) { - fprintf(stdout, "FAILED (data)\n"); - fprintf(stdout, "Got :%s\n", evbuffer_pullup(evhttp_request_get_input_buffer(req),-1)); - fprintf(stdout, "Want:%s\n", POST_DATA); - exit(1); - } - - evb = evbuffer_new(); - evbuffer_add_printf(evb, BASIC_REQUEST_BODY); - - evhttp_send_reply(req, HTTP_OK, "Everything is fine", evb); - - evbuffer_free(evb); -} - -void -http_postrequest_done(struct evhttp_request *req, void *arg) -{ - const char *what = BASIC_REQUEST_BODY; - struct event_base *base = arg; - - if (req == NULL) { - fprintf(stderr, "FAILED (timeout)\n"); - exit(1); - } - - if (evhttp_request_get_response_code(req) != HTTP_OK) { - - fprintf(stderr, "FAILED (response code)\n"); - exit(1); - } - - if (evhttp_find_header(evhttp_request_get_input_headers(req), "Content-Type") == NULL) { - fprintf(stderr, "FAILED (content type)\n"); - exit(1); - } - - if (evbuffer_get_length(evhttp_request_get_input_buffer(req)) != strlen(what)) { - fprintf(stderr, "FAILED (length %lu vs %lu)\n", - (unsigned long)evbuffer_get_length(evhttp_request_get_input_buffer(req)), (unsigned long)strlen(what)); - exit(1); - } - - if (evbuffer_datacmp(evhttp_request_get_input_buffer(req), what) != 0) { - fprintf(stderr, "FAILED (data)\n"); - exit(1); - } - - test_ok = 1; - event_base_loopexit(base, NULL); -} - -/* - * HTTP PUT test, basically just like POST, but ... - */ - -void http_putrequest_done(struct evhttp_request *, void *); - -#define PUT_DATA "Hi, I'm some PUT data" - -static void -http_put_test(void *arg) -{ - struct basic_test_data *data = arg; - ev_uint16_t port = 0; - struct evhttp_connection *evcon = NULL; - struct evhttp_request *req = NULL; - - test_ok = 0; - - http = http_setup(&port, data->base, 0); - - evcon = evhttp_connection_base_new(data->base, NULL, "127.0.0.1", port); - tt_assert(evcon); - - /* - * Schedule the HTTP PUT request - */ - - req = evhttp_request_new(http_putrequest_done, data->base); - tt_assert(req); - - /* Add the information that we care about */ - evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "someotherhost"); - evbuffer_add_printf(evhttp_request_get_output_buffer(req), PUT_DATA); - - if (evhttp_make_request(evcon, req, EVHTTP_REQ_PUT, "/putit") == -1) { - tt_abort_msg("Couldn't make request"); - } - - event_base_dispatch(data->base); - - evhttp_connection_free(evcon); - evhttp_free(http); - - tt_int_op(test_ok, ==, 1); - end: - ; -} - -void -http_put_cb(struct evhttp_request *req, void *arg) -{ - struct evbuffer *evb; - event_debug(("%s: called\n", __func__)); - - /* Expecting a PUT request */ - if (evhttp_request_get_command(req) != EVHTTP_REQ_PUT) { - fprintf(stdout, "FAILED (put type)\n"); - exit(1); - } - - if (evbuffer_get_length(evhttp_request_get_input_buffer(req)) != strlen(PUT_DATA)) { - fprintf(stdout, "FAILED (length: %lu vs %lu)\n", - (unsigned long)evbuffer_get_length(evhttp_request_get_input_buffer(req)), (unsigned long)strlen(PUT_DATA)); - exit(1); - } - - if (evbuffer_datacmp(evhttp_request_get_input_buffer(req), PUT_DATA) != 0) { - fprintf(stdout, "FAILED (data)\n"); - fprintf(stdout, "Got :%s\n", evbuffer_pullup(evhttp_request_get_input_buffer(req),-1)); - fprintf(stdout, "Want:%s\n", PUT_DATA); - exit(1); - } - - evb = evbuffer_new(); - evbuffer_add_printf(evb, "That ain't funny"); - - evhttp_send_reply(req, HTTP_OK, "Everything is great", evb); - - evbuffer_free(evb); -} - -void -http_putrequest_done(struct evhttp_request *req, void *arg) -{ - struct event_base *base = arg; - const char *what = "That ain't funny"; - - if (req == NULL) { - fprintf(stderr, "FAILED (timeout)\n"); - exit(1); - } - - if (evhttp_request_get_response_code(req) != HTTP_OK) { - - fprintf(stderr, "FAILED (response code)\n"); - exit(1); - } - - if (evhttp_find_header(evhttp_request_get_input_headers(req), "Content-Type") == NULL) { - fprintf(stderr, "FAILED (content type)\n"); - exit(1); - } - - if (evbuffer_get_length(evhttp_request_get_input_buffer(req)) != strlen(what)) { - fprintf(stderr, "FAILED (length %lu vs %lu)\n", - (unsigned long)evbuffer_get_length(evhttp_request_get_input_buffer(req)), (unsigned long)strlen(what)); - exit(1); - } - - - if (evbuffer_datacmp(evhttp_request_get_input_buffer(req), what) != 0) { - fprintf(stderr, "FAILED (data)\n"); - exit(1); - } - - test_ok = 1; - event_base_loopexit(base, NULL); -} - -static void -http_failure_readcb(struct bufferevent *bev, void *arg) -{ - const char *what = "400 Bad Request"; - if (evbuffer_contains(bufferevent_get_input(bev), what)) { - test_ok = 2; - bufferevent_disable(bev, EV_READ); - event_base_loopexit(arg, NULL); - } -} - -/* - * Testing that the HTTP server can deal with a malformed request. - */ -static void -http_failure_test(void *arg) -{ - struct basic_test_data *data = arg; - struct bufferevent *bev; - evutil_socket_t fd = -1; - const char *http_request; - ev_uint16_t port = 0; - - test_ok = 0; - - http = http_setup(&port, data->base, 0); - - fd = http_connect("127.0.0.1", port); - tt_int_op(fd, >=, 0); - - /* Stupid thing to send a request */ - bev = bufferevent_socket_new(data->base, fd, 0); - bufferevent_setcb(bev, http_failure_readcb, http_writecb, - http_errorcb, data->base); - - http_request = "illegal request\r\n"; - - bufferevent_write(bev, http_request, strlen(http_request)); - - event_base_dispatch(data->base); - - bufferevent_free(bev); - - evhttp_free(http); - - tt_int_op(test_ok, ==, 2); - end: - if (fd >= 0) - evutil_closesocket(fd); -} - -static void -close_detect_done(struct evhttp_request *req, void *arg) -{ - struct timeval tv; - tt_assert(req); - tt_assert(evhttp_request_get_response_code(req) == HTTP_OK); - - test_ok = 1; - - end: - evutil_timerclear(&tv); - tv.tv_usec = 150000; - event_base_loopexit(arg, &tv); -} - -static void -close_detect_launch(evutil_socket_t fd, short what, void *arg) -{ - struct evhttp_connection *evcon = arg; - struct event_base *base = evhttp_connection_get_base(evcon); - struct evhttp_request *req; - - req = evhttp_request_new(close_detect_done, base); - - /* Add the information that we care about */ - evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); - - /* We give ownership of the request to the connection */ - if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") == -1) { - tt_fail_msg("Couldn't make request"); - } -} - -static void -close_detect_cb(struct evhttp_request *req, void *arg) -{ - struct evhttp_connection *evcon = arg; - struct event_base *base = evhttp_connection_get_base(evcon); - struct timeval tv; - - if (req != NULL && evhttp_request_get_response_code(req) != HTTP_OK) { - tt_abort_msg("Failed"); - } - - evutil_timerclear(&tv); - tv.tv_sec = 0; /* longer than the http time out */ - tv.tv_usec = 600000; /* longer than the http time out */ - - /* launch a new request on the persistent connection in .3 seconds */ - event_base_once(base, -1, EV_TIMEOUT, close_detect_launch, evcon, &tv); - end: - ; -} - - -static void -http_close_detection_(struct basic_test_data *data, int with_delay) -{ - ev_uint16_t port = 0; - struct evhttp_connection *evcon = NULL; - struct evhttp_request *req = NULL; - const struct timeval sec_tenth = { 0, 100000 }; - - test_ok = 0; - http = http_setup(&port, data->base, 0); - - /* .1 second timeout */ - evhttp_set_timeout_tv(http, &sec_tenth); - - evcon = evhttp_connection_base_new(data->base, NULL, - "127.0.0.1", port); - tt_assert(evcon); - evhttp_connection_set_timeout_tv(evcon, &sec_tenth); - - - tt_assert(evcon); - delayed_client = evcon; - - /* - * At this point, we want to schedule a request to the HTTP - * server using our make request method. - */ - - req = evhttp_request_new(close_detect_cb, evcon); - - /* Add the information that we care about */ - evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); - - /* We give ownership of the request to the connection */ - if (evhttp_make_request(evcon, - req, EVHTTP_REQ_GET, with_delay ? "/largedelay" : "/test") == -1) { - tt_abort_msg("couldn't make request"); - } - - event_base_dispatch(data->base); - - /* at this point, the http server should have no connection */ - tt_assert(TAILQ_FIRST(&http->connections) == NULL); - - end: - if (evcon) - evhttp_connection_free(evcon); - if (http) - evhttp_free(http); -} -static void -http_close_detection_test(void *arg) -{ - http_close_detection_(arg, 0); -} -static void -http_close_detection_delay_test(void *arg) -{ - http_close_detection_(arg, 1); -} - -static void -http_highport_test(void *arg) -{ - struct basic_test_data *data = arg; - int i = -1; - struct evhttp *myhttp = NULL; - - /* Try a few different ports */ - for (i = 0; i < 50; ++i) { - myhttp = evhttp_new(data->base); - if (evhttp_bind_socket(myhttp, "127.0.0.1", 65535 - i) == 0) { - test_ok = 1; - evhttp_free(myhttp); - return; - } - evhttp_free(myhttp); - } - - tt_fail_msg("Couldn't get a high port"); -} - -static void -http_bad_header_test(void *ptr) -{ - struct evkeyvalq headers; - - TAILQ_INIT(&headers); - - tt_want(evhttp_add_header(&headers, "One", "Two") == 0); - tt_want(evhttp_add_header(&headers, "One", "Two\r\n Three") == 0); - tt_want(evhttp_add_header(&headers, "One\r", "Two") == -1); - tt_want(evhttp_add_header(&headers, "One\n", "Two") == -1); - tt_want(evhttp_add_header(&headers, "One", "Two\r") == -1); - tt_want(evhttp_add_header(&headers, "One", "Two\n") == -1); - - evhttp_clear_headers(&headers); -} - -static int validate_header( - const struct evkeyvalq* headers, - const char *key, const char *value) -{ - const char *real_val = evhttp_find_header(headers, key); - tt_assert(real_val != NULL); - tt_want(strcmp(real_val, value) == 0); -end: - return (0); -} - -static void -http_parse_query_test(void *ptr) -{ - struct evkeyvalq headers; - int r; - - TAILQ_INIT(&headers); - - r = evhttp_parse_query("http://www.test.com/?q=test", &headers); - tt_want(validate_header(&headers, "q", "test") == 0); - tt_int_op(r, ==, 0); - evhttp_clear_headers(&headers); - - r = evhttp_parse_query("http://www.test.com/?q=test&foo=bar", &headers); - tt_want(validate_header(&headers, "q", "test") == 0); - tt_want(validate_header(&headers, "foo", "bar") == 0); - tt_int_op(r, ==, 0); - evhttp_clear_headers(&headers); - - r = evhttp_parse_query("http://www.test.com/?q=test+foo", &headers); - tt_want(validate_header(&headers, "q", "test foo") == 0); - tt_int_op(r, ==, 0); - evhttp_clear_headers(&headers); - - r = evhttp_parse_query("http://www.test.com/?q=test%0Afoo", &headers); - tt_want(validate_header(&headers, "q", "test\nfoo") == 0); - tt_int_op(r, ==, 0); - evhttp_clear_headers(&headers); - - r = evhttp_parse_query("http://www.test.com/?q=test%0Dfoo", &headers); - tt_want(validate_header(&headers, "q", "test\rfoo") == 0); - tt_int_op(r, ==, 0); - evhttp_clear_headers(&headers); - - r = evhttp_parse_query("http://www.test.com/?q=test&&q2", &headers); - tt_int_op(r, ==, -1); - evhttp_clear_headers(&headers); - - r = evhttp_parse_query("http://www.test.com/?q=test+this", &headers); - tt_want(validate_header(&headers, "q", "test this") == 0); - tt_int_op(r, ==, 0); - evhttp_clear_headers(&headers); - - r = evhttp_parse_query("http://www.test.com/?q=test&q2=foo", &headers); - tt_int_op(r, ==, 0); - tt_want(validate_header(&headers, "q", "test") == 0); - tt_want(validate_header(&headers, "q2", "foo") == 0); - evhttp_clear_headers(&headers); - - r = evhttp_parse_query("http://www.test.com/?q&q2=foo", &headers); - tt_int_op(r, ==, -1); - evhttp_clear_headers(&headers); - - r = evhttp_parse_query("http://www.test.com/?q=foo&q2", &headers); - tt_int_op(r, ==, -1); - evhttp_clear_headers(&headers); - - r = evhttp_parse_query("http://www.test.com/?q=foo&q2&q3=x", &headers); - tt_int_op(r, ==, -1); - evhttp_clear_headers(&headers); - - r = evhttp_parse_query("http://www.test.com/?q=&q2=&q3=", &headers); - tt_int_op(r, ==, 0); - tt_want(validate_header(&headers, "q", "") == 0); - tt_want(validate_header(&headers, "q2", "") == 0); - tt_want(validate_header(&headers, "q3", "") == 0); - evhttp_clear_headers(&headers); - -end: - evhttp_clear_headers(&headers); -} - -static void -http_parse_uri_test(void *ptr) -{ - const int nonconform = (ptr != NULL); - const unsigned parse_flags = - nonconform ? EVHTTP_URI_NONCONFORMANT : 0; - struct evhttp_uri *uri = NULL; - char url_tmp[4096]; -#define URI_PARSE(uri) \ - evhttp_uri_parse_with_flags((uri), parse_flags) - -#define TT_URI(want) do { \ - char *ret = evhttp_uri_join(uri, url_tmp, sizeof(url_tmp)); \ - tt_want(ret != NULL); \ - tt_want(ret == url_tmp); \ - if (strcmp(ret,want) != 0) \ - TT_FAIL(("\"%s\" != \"%s\"",ret,want)); \ - } while(0) - - tt_want(evhttp_uri_join(NULL, 0, 0) == NULL); - tt_want(evhttp_uri_join(NULL, url_tmp, 0) == NULL); - tt_want(evhttp_uri_join(NULL, url_tmp, sizeof(url_tmp)) == NULL); - - /* bad URIs: parsing */ -#define BAD(s) do { \ - if (URI_PARSE(s) != NULL) \ - TT_FAIL(("Expected error parsing \"%s\"",s)); \ - } while(0) - /* Nonconformant URIs we can parse: parsing */ -#define NCF(s) do { \ - uri = URI_PARSE(s); \ - if (uri != NULL && !nonconform) { \ - TT_FAIL(("Expected error parsing \"%s\"",s)); \ - } else if (uri == NULL && nonconform) { \ - TT_FAIL(("Couldn't parse nonconformant URI \"%s\"", \ - s)); \ - } \ - if (uri) { \ - tt_want(evhttp_uri_join(uri, url_tmp, \ - sizeof(url_tmp))); \ - evhttp_uri_free(uri); \ - } \ - } while(0) - - NCF("http://www.test.com/ why hello"); - NCF("http://www.test.com/why-hello\x01"); - NCF("http://www.test.com/why-hello?\x01"); - NCF("http://www.test.com/why-hello#\x01"); - BAD("http://www.\x01.test.com/why-hello"); - BAD("http://www.%7test.com/why-hello"); - NCF("http://www.test.com/why-hell%7o"); - BAD("h%3ttp://www.test.com/why-hello"); - NCF("http://www.test.com/why-hello%7"); - NCF("http://www.test.com/why-hell%7o"); - NCF("http://www.test.com/foo?ba%r"); - NCF("http://www.test.com/foo#ba%r"); - BAD("99:99/foo"); - BAD("http://www.test.com:999x/"); - BAD("http://www.test.com:x/"); - BAD("http://[hello-there]/"); - BAD("http://[::1]]/"); - BAD("http://[::1/"); - BAD("http://[foob/"); - BAD("http://[/"); - BAD("http://[ffff:ffff:ffff:ffff:Ffff:ffff:ffff:" - "ffff:ffff:ffff:ffff:ffff:ffff:ffff]/"); - BAD("http://[vX.foo]/"); - BAD("http://[vX.foo]/"); - BAD("http://[v.foo]/"); - BAD("http://[v5.fo%o]/"); - BAD("http://[v5X]/"); - BAD("http://[v5]/"); - BAD("http://[]/"); - BAD("http://f\x01red@www.example.com/"); - BAD("http://f%0red@www.example.com/"); - BAD("http://www.example.com:9999999999999999999999999999999999999/"); - BAD("http://www.example.com:hihi/"); - BAD("://www.example.com/"); - - /* bad URIs: joining */ - uri = evhttp_uri_new(); - tt_want(0==evhttp_uri_set_host(uri, "www.example.com")); - tt_want(evhttp_uri_join(uri, url_tmp, sizeof(url_tmp)) != NULL); - /* not enough space: */ - tt_want(evhttp_uri_join(uri, url_tmp, 3) == NULL); - /* host is set, but path doesn't start with "/": */ - tt_want(0==evhttp_uri_set_path(uri, "hi_mom")); - tt_want(evhttp_uri_join(uri, url_tmp, sizeof(url_tmp)) == NULL); - tt_want(evhttp_uri_join(uri, NULL, sizeof(url_tmp))==NULL); - tt_want(evhttp_uri_join(uri, url_tmp, 0)==NULL); - evhttp_uri_free(uri); - uri = URI_PARSE("mailto:foo@bar"); - tt_want(uri != NULL); - tt_want(evhttp_uri_get_host(uri) == NULL); - tt_want(evhttp_uri_get_userinfo(uri) == NULL); - tt_want(evhttp_uri_get_port(uri) == -1); - tt_want(!strcmp(evhttp_uri_get_scheme(uri), "mailto")); - tt_want(!strcmp(evhttp_uri_get_path(uri), "foo@bar")); - tt_want(evhttp_uri_get_query(uri) == NULL); - tt_want(evhttp_uri_get_fragment(uri) == NULL); - TT_URI("mailto:foo@bar"); - evhttp_uri_free(uri); - - uri = evhttp_uri_new(); - /* Bad URI usage: setting invalid values */ - tt_want(-1 == evhttp_uri_set_scheme(uri,"")); - tt_want(-1 == evhttp_uri_set_scheme(uri,"33")); - tt_want(-1 == evhttp_uri_set_scheme(uri,"hi!")); - tt_want(-1 == evhttp_uri_set_userinfo(uri,"hello@")); - tt_want(-1 == evhttp_uri_set_host(uri,"[1.2.3.4]")); - tt_want(-1 == evhttp_uri_set_host(uri,"[")); - tt_want(-1 == evhttp_uri_set_host(uri,"www.[foo].com")); - tt_want(-1 == evhttp_uri_set_port(uri,-3)); - tt_want(-1 == evhttp_uri_set_path(uri,"hello?world")); - tt_want(-1 == evhttp_uri_set_query(uri,"hello#world")); - tt_want(-1 == evhttp_uri_set_fragment(uri,"hello#world")); - /* Valid URI usage: setting valid values */ - tt_want(0 == evhttp_uri_set_scheme(uri,"http")); - tt_want(0 == evhttp_uri_set_scheme(uri,NULL)); - tt_want(0 == evhttp_uri_set_userinfo(uri,"username:pass")); - tt_want(0 == evhttp_uri_set_userinfo(uri,NULL)); - tt_want(0 == evhttp_uri_set_host(uri,"www.example.com")); - tt_want(0 == evhttp_uri_set_host(uri,"1.2.3.4")); - tt_want(0 == evhttp_uri_set_host(uri,"[1:2:3:4::]")); - tt_want(0 == evhttp_uri_set_host(uri,"[v7.wobblewobble]")); - tt_want(0 == evhttp_uri_set_host(uri,NULL)); - tt_want(0 == evhttp_uri_set_host(uri,"")); - tt_want(0 == evhttp_uri_set_port(uri, -1)); - tt_want(0 == evhttp_uri_set_port(uri, 80)); - tt_want(0 == evhttp_uri_set_port(uri, 65535)); - tt_want(0 == evhttp_uri_set_path(uri, "")); - tt_want(0 == evhttp_uri_set_path(uri, "/documents/public/index.html")); - tt_want(0 == evhttp_uri_set_path(uri, NULL)); - tt_want(0 == evhttp_uri_set_query(uri, "key=val&key2=val2")); - tt_want(0 == evhttp_uri_set_query(uri, "keyvalblarg")); - tt_want(0 == evhttp_uri_set_query(uri, "")); - tt_want(0 == evhttp_uri_set_query(uri, NULL)); - tt_want(0 == evhttp_uri_set_fragment(uri, "")); - tt_want(0 == evhttp_uri_set_fragment(uri, "here?i?am")); - tt_want(0 == evhttp_uri_set_fragment(uri, NULL)); - evhttp_uri_free(uri); - - /* Valid parsing */ - uri = URI_PARSE("http://www.test.com/?q=t%33est"); - tt_want(strcmp(evhttp_uri_get_scheme(uri), "http") == 0); - tt_want(strcmp(evhttp_uri_get_host(uri), "www.test.com") == 0); - tt_want(strcmp(evhttp_uri_get_path(uri), "/") == 0); - tt_want(strcmp(evhttp_uri_get_query(uri), "q=t%33est") == 0); - tt_want(evhttp_uri_get_userinfo(uri) == NULL); - tt_want(evhttp_uri_get_port(uri) == -1); - tt_want(evhttp_uri_get_fragment(uri) == NULL); - TT_URI("http://www.test.com/?q=t%33est"); - evhttp_uri_free(uri); - - uri = URI_PARSE("http://%77ww.test.com"); - tt_want(strcmp(evhttp_uri_get_scheme(uri), "http") == 0); - tt_want(strcmp(evhttp_uri_get_host(uri), "%77ww.test.com") == 0); - tt_want(strcmp(evhttp_uri_get_path(uri), "") == 0); - tt_want(evhttp_uri_get_query(uri) == NULL); - tt_want(evhttp_uri_get_userinfo(uri) == NULL); - tt_want(evhttp_uri_get_port(uri) == -1); - tt_want(evhttp_uri_get_fragment(uri) == NULL); - TT_URI("http://%77ww.test.com"); - evhttp_uri_free(uri); - - uri = URI_PARSE("http://www.test.com?q=test"); - tt_want(strcmp(evhttp_uri_get_scheme(uri), "http") == 0); - tt_want(strcmp(evhttp_uri_get_host(uri), "www.test.com") == 0); - tt_want(strcmp(evhttp_uri_get_path(uri), "") == 0); - tt_want(strcmp(evhttp_uri_get_query(uri), "q=test") == 0); - tt_want(evhttp_uri_get_userinfo(uri) == NULL); - tt_want(evhttp_uri_get_port(uri) == -1); - tt_want(evhttp_uri_get_fragment(uri) == NULL); - TT_URI("http://www.test.com?q=test"); - evhttp_uri_free(uri); - - uri = URI_PARSE("http://www.test.com#fragment"); - tt_want(strcmp(evhttp_uri_get_scheme(uri), "http") == 0); - tt_want(strcmp(evhttp_uri_get_host(uri), "www.test.com") == 0); - tt_want(strcmp(evhttp_uri_get_path(uri), "") == 0); - tt_want(evhttp_uri_get_query(uri) == NULL); - tt_want(evhttp_uri_get_userinfo(uri) == NULL); - tt_want(evhttp_uri_get_port(uri) == -1); - tt_want_str_op(evhttp_uri_get_fragment(uri), ==, "fragment"); - TT_URI("http://www.test.com#fragment"); - evhttp_uri_free(uri); - - uri = URI_PARSE("http://8000/"); - tt_want(strcmp(evhttp_uri_get_scheme(uri), "http") == 0); - tt_want(strcmp(evhttp_uri_get_host(uri), "8000") == 0); - tt_want(strcmp(evhttp_uri_get_path(uri), "/") == 0); - tt_want(evhttp_uri_get_query(uri) == NULL); - tt_want(evhttp_uri_get_userinfo(uri) == NULL); - tt_want(evhttp_uri_get_port(uri) == -1); - tt_want(evhttp_uri_get_fragment(uri) == NULL); - TT_URI("http://8000/"); - evhttp_uri_free(uri); - - uri = URI_PARSE("http://:8000/"); - tt_want(strcmp(evhttp_uri_get_scheme(uri), "http") == 0); - tt_want(strcmp(evhttp_uri_get_host(uri), "") == 0); - tt_want(strcmp(evhttp_uri_get_path(uri), "/") == 0); - tt_want(evhttp_uri_get_query(uri) == NULL); - tt_want(evhttp_uri_get_userinfo(uri) == NULL); - tt_want(evhttp_uri_get_port(uri) == 8000); - tt_want(evhttp_uri_get_fragment(uri) == NULL); - TT_URI("http://:8000/"); - evhttp_uri_free(uri); - - uri = URI_PARSE("http://www.test.com:/"); /* empty port */ - tt_want(strcmp(evhttp_uri_get_scheme(uri), "http") == 0); - tt_want(strcmp(evhttp_uri_get_host(uri), "www.test.com") == 0); - tt_want_str_op(evhttp_uri_get_path(uri), ==, "/"); - tt_want(evhttp_uri_get_query(uri) == NULL); - tt_want(evhttp_uri_get_userinfo(uri) == NULL); - tt_want(evhttp_uri_get_port(uri) == -1); - tt_want(evhttp_uri_get_fragment(uri) == NULL); - TT_URI("http://www.test.com/"); - evhttp_uri_free(uri); - - uri = URI_PARSE("http://www.test.com:"); /* empty port 2 */ - tt_want(strcmp(evhttp_uri_get_scheme(uri), "http") == 0); - tt_want(strcmp(evhttp_uri_get_host(uri), "www.test.com") == 0); - tt_want(strcmp(evhttp_uri_get_path(uri), "") == 0); - tt_want(evhttp_uri_get_query(uri) == NULL); - tt_want(evhttp_uri_get_userinfo(uri) == NULL); - tt_want(evhttp_uri_get_port(uri) == -1); - tt_want(evhttp_uri_get_fragment(uri) == NULL); - TT_URI("http://www.test.com"); - evhttp_uri_free(uri); - - uri = URI_PARSE("ftp://www.test.com/?q=test"); - tt_want(strcmp(evhttp_uri_get_scheme(uri), "ftp") == 0); - tt_want(strcmp(evhttp_uri_get_host(uri), "www.test.com") == 0); - tt_want(strcmp(evhttp_uri_get_path(uri), "/") == 0); - tt_want(strcmp(evhttp_uri_get_query(uri), "q=test") == 0); - tt_want(evhttp_uri_get_userinfo(uri) == NULL); - tt_want(evhttp_uri_get_port(uri) == -1); - tt_want(evhttp_uri_get_fragment(uri) == NULL); - TT_URI("ftp://www.test.com/?q=test"); - evhttp_uri_free(uri); - - uri = URI_PARSE("ftp://[::1]:999/?q=test"); - tt_want(strcmp(evhttp_uri_get_scheme(uri), "ftp") == 0); - tt_want(strcmp(evhttp_uri_get_host(uri), "[::1]") == 0); - tt_want(strcmp(evhttp_uri_get_path(uri), "/") == 0); - tt_want(strcmp(evhttp_uri_get_query(uri), "q=test") == 0); - tt_want(evhttp_uri_get_userinfo(uri) == NULL); - tt_want(evhttp_uri_get_port(uri) == 999); - tt_want(evhttp_uri_get_fragment(uri) == NULL); - TT_URI("ftp://[::1]:999/?q=test"); - evhttp_uri_free(uri); - - uri = URI_PARSE("ftp://[ff00::127.0.0.1]/?q=test"); - tt_want(strcmp(evhttp_uri_get_scheme(uri), "ftp") == 0); - tt_want(strcmp(evhttp_uri_get_host(uri), "[ff00::127.0.0.1]") == 0); - tt_want(strcmp(evhttp_uri_get_path(uri), "/") == 0); - tt_want(strcmp(evhttp_uri_get_query(uri), "q=test") == 0); - tt_want(evhttp_uri_get_userinfo(uri) == NULL); - tt_want(evhttp_uri_get_port(uri) == -1); - tt_want(evhttp_uri_get_fragment(uri) == NULL); - TT_URI("ftp://[ff00::127.0.0.1]/?q=test"); - evhttp_uri_free(uri); - - uri = URI_PARSE("ftp://[v99.not_(any:time)_soon]/?q=test"); - tt_want(strcmp(evhttp_uri_get_scheme(uri), "ftp") == 0); - tt_want(strcmp(evhttp_uri_get_host(uri), "[v99.not_(any:time)_soon]") == 0); - tt_want(strcmp(evhttp_uri_get_path(uri), "/") == 0); - tt_want(strcmp(evhttp_uri_get_query(uri), "q=test") == 0); - tt_want(evhttp_uri_get_userinfo(uri) == NULL); - tt_want(evhttp_uri_get_port(uri) == -1); - tt_want(evhttp_uri_get_fragment(uri) == NULL); - TT_URI("ftp://[v99.not_(any:time)_soon]/?q=test"); - evhttp_uri_free(uri); - - uri = URI_PARSE("scheme://user:pass@foo.com:42/?q=test&s=some+thing#fragment"); - tt_want(strcmp(evhttp_uri_get_scheme(uri), "scheme") == 0); - tt_want(strcmp(evhttp_uri_get_userinfo(uri), "user:pass") == 0); - tt_want(strcmp(evhttp_uri_get_host(uri), "foo.com") == 0); - tt_want(evhttp_uri_get_port(uri) == 42); - tt_want(strcmp(evhttp_uri_get_path(uri), "/") == 0); - tt_want(strcmp(evhttp_uri_get_query(uri), "q=test&s=some+thing") == 0); - tt_want(strcmp(evhttp_uri_get_fragment(uri), "fragment") == 0); - TT_URI("scheme://user:pass@foo.com:42/?q=test&s=some+thing#fragment"); - evhttp_uri_free(uri); - - uri = URI_PARSE("scheme://user@foo.com/#fragment"); - tt_want(strcmp(evhttp_uri_get_scheme(uri), "scheme") == 0); - tt_want(strcmp(evhttp_uri_get_userinfo(uri), "user") == 0); - tt_want(strcmp(evhttp_uri_get_host(uri), "foo.com") == 0); - tt_want(evhttp_uri_get_port(uri) == -1); - tt_want(strcmp(evhttp_uri_get_path(uri), "/") == 0); - tt_want(evhttp_uri_get_query(uri) == NULL); - tt_want(strcmp(evhttp_uri_get_fragment(uri), "fragment") == 0); - TT_URI("scheme://user@foo.com/#fragment"); - evhttp_uri_free(uri); - - uri = URI_PARSE("scheme://%75ser@foo.com/#frag@ment"); - tt_want(strcmp(evhttp_uri_get_scheme(uri), "scheme") == 0); - tt_want(strcmp(evhttp_uri_get_userinfo(uri), "%75ser") == 0); - tt_want(strcmp(evhttp_uri_get_host(uri), "foo.com") == 0); - tt_want(evhttp_uri_get_port(uri) == -1); - tt_want(strcmp(evhttp_uri_get_path(uri), "/") == 0); - tt_want(evhttp_uri_get_query(uri) == NULL); - tt_want(strcmp(evhttp_uri_get_fragment(uri), "frag@ment") == 0); - TT_URI("scheme://%75ser@foo.com/#frag@ment"); - evhttp_uri_free(uri); - - uri = URI_PARSE("file:///some/path/to/the/file"); - tt_want(strcmp(evhttp_uri_get_scheme(uri), "file") == 0); - tt_want(evhttp_uri_get_userinfo(uri) == NULL); - tt_want(strcmp(evhttp_uri_get_host(uri), "") == 0); - tt_want(evhttp_uri_get_port(uri) == -1); - tt_want(strcmp(evhttp_uri_get_path(uri), "/some/path/to/the/file") == 0); - tt_want(evhttp_uri_get_query(uri) == NULL); - tt_want(evhttp_uri_get_fragment(uri) == NULL); - TT_URI("file:///some/path/to/the/file"); - evhttp_uri_free(uri); - - uri = URI_PARSE("///some/path/to/the-file"); - tt_want(uri != NULL); - tt_want(evhttp_uri_get_scheme(uri) == NULL); - tt_want(evhttp_uri_get_userinfo(uri) == NULL); - tt_want(strcmp(evhttp_uri_get_host(uri), "") == 0); - tt_want(evhttp_uri_get_port(uri) == -1); - tt_want(strcmp(evhttp_uri_get_path(uri), "/some/path/to/the-file") == 0); - tt_want(evhttp_uri_get_query(uri) == NULL); - tt_want(evhttp_uri_get_fragment(uri) == NULL); - TT_URI("///some/path/to/the-file"); - evhttp_uri_free(uri); - - uri = URI_PARSE("/s:ome/path/to/the-file?q=99#fred"); - tt_want(uri != NULL); - tt_want(evhttp_uri_get_scheme(uri) == NULL); - tt_want(evhttp_uri_get_userinfo(uri) == NULL); - tt_want(evhttp_uri_get_host(uri) == NULL); - tt_want(evhttp_uri_get_port(uri) == -1); - tt_want(strcmp(evhttp_uri_get_path(uri), "/s:ome/path/to/the-file") == 0); - tt_want(strcmp(evhttp_uri_get_query(uri), "q=99") == 0); - tt_want(strcmp(evhttp_uri_get_fragment(uri), "fred") == 0); - TT_URI("/s:ome/path/to/the-file?q=99#fred"); - evhttp_uri_free(uri); - - uri = URI_PARSE("relative/path/with/co:lon"); - tt_want(uri != NULL); - tt_want(evhttp_uri_get_scheme(uri) == NULL); - tt_want(evhttp_uri_get_userinfo(uri) == NULL); - tt_want(evhttp_uri_get_host(uri) == NULL); - tt_want(evhttp_uri_get_port(uri) == -1); - tt_want(strcmp(evhttp_uri_get_path(uri), "relative/path/with/co:lon") == 0); - tt_want(evhttp_uri_get_query(uri) == NULL); - tt_want(evhttp_uri_get_fragment(uri) == NULL); - TT_URI("relative/path/with/co:lon"); - evhttp_uri_free(uri); - - uri = URI_PARSE("bob?q=99&q2=q?33#fr?ed"); - tt_want(uri != NULL); - tt_want(evhttp_uri_get_scheme(uri) == NULL); - tt_want(evhttp_uri_get_userinfo(uri) == NULL); - tt_want(evhttp_uri_get_host(uri) == NULL); - tt_want(evhttp_uri_get_port(uri) == -1); - tt_want(strcmp(evhttp_uri_get_path(uri), "bob") == 0); - tt_want(strcmp(evhttp_uri_get_query(uri), "q=99&q2=q?33") == 0); - tt_want(strcmp(evhttp_uri_get_fragment(uri), "fr?ed") == 0); - TT_URI("bob?q=99&q2=q?33#fr?ed"); - evhttp_uri_free(uri); - - uri = URI_PARSE("#fr?ed"); - tt_want(uri != NULL); - tt_want(evhttp_uri_get_scheme(uri) == NULL); - tt_want(evhttp_uri_get_userinfo(uri) == NULL); - tt_want(evhttp_uri_get_host(uri) == NULL); - tt_want(evhttp_uri_get_port(uri) == -1); - tt_want(strcmp(evhttp_uri_get_path(uri), "") == 0); - tt_want(evhttp_uri_get_query(uri) == NULL); - tt_want(strcmp(evhttp_uri_get_fragment(uri), "fr?ed") == 0); - TT_URI("#fr?ed"); - evhttp_uri_free(uri); -#undef URI_PARSE -#undef TT_URI -#undef BAD -} - -static void -http_uriencode_test(void *ptr) -{ - char *s=NULL, *s2=NULL; - size_t sz; - int bytes_decoded; - -#define ENC(from,want,plus) do { \ - s = evhttp_uriencode((from), -1, (plus)); \ - tt_assert(s); \ - tt_str_op(s,==,(want)); \ - sz = -1; \ - s2 = evhttp_uridecode((s), (plus), &sz); \ - tt_assert(s2); \ - tt_str_op(s2,==,(from)); \ - tt_int_op(sz,==,strlen(from)); \ - free(s); \ - free(s2); \ - s = s2 = NULL; \ - } while (0) - -#define DEC(from,want,dp) do { \ - s = evhttp_uridecode((from),(dp),&sz); \ - tt_assert(s); \ - tt_str_op(s,==,(want)); \ - tt_int_op(sz,==,strlen(want)); \ - free(s); \ - s = NULL; \ - } while (0) - -#define OLD_DEC(from,want) do { \ - s = evhttp_decode_uri((from)); \ - tt_assert(s); \ - tt_str_op(s,==,(want)); \ - free(s); \ - s = NULL; \ - } while (0) - - - ENC("Hello", "Hello",0); - ENC("99", "99",0); - ENC("", "",0); - ENC( - "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789-.~_", - "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789-.~_",0); - ENC(" ", "%20",0); - ENC(" ", "+",1); - ENC("\xff\xf0\xe0", "%FF%F0%E0",0); - ENC("\x01\x19", "%01%19",1); - ENC("http://www.ietf.org/rfc/rfc3986.txt", - "http%3A%2F%2Fwww.ietf.org%2Frfc%2Frfc3986.txt",1); - - ENC("1+2=3", "1%2B2%3D3",1); - ENC("1+2=3", "1%2B2%3D3",0); - - /* Now try encoding with internal NULs. */ - s = evhttp_uriencode("hello\0world", 11, 0); - tt_assert(s); - tt_str_op(s,==,"hello%00world"); - free(s); - s = NULL; - - /* Now try decoding just part of string. */ - s = malloc(6 + 1 /* NUL byte */); - bytes_decoded = evhttp_decode_uri_internal("hello%20%20", 6, s, 0); - tt_assert(s); - tt_int_op(bytes_decoded,==,6); - tt_str_op(s,==,"hello%"); - free(s); - s = NULL; - - /* Now try out some decoding cases that we don't generate with - * encode_uri: Make sure that malformed stuff doesn't crash... */ - DEC("%%xhello th+ere \xff", - "%%xhello th+ere \xff", 0); - /* Make sure plus decoding works */ - DEC("plus+should%20work+", "plus should work ",1); - /* Try some lowercase hex */ - DEC("%f0%a0%b0", "\xf0\xa0\xb0",1); - - /* Try an internal NUL. */ - sz = 0; - s = evhttp_uridecode("%00%00x%00%00", 1, &sz); - tt_int_op(sz,==,5); - tt_assert(!memcmp(s, "\0\0x\0\0", 5)); - free(s); - s = NULL; - - /* Try with size == NULL */ - sz = 0; - s = evhttp_uridecode("%00%00x%00%00", 1, NULL); - tt_assert(!memcmp(s, "\0\0x\0\0", 5)); - free(s); - s = NULL; - - /* Test out the crazy old behavior of the deprecated - * evhttp_decode_uri */ - OLD_DEC("http://example.com/normal+path/?key=val+with+spaces", - "http://example.com/normal+path/?key=val with spaces"); - -end: - if (s) - free(s); - if (s2) - free(s2); -#undef ENC -#undef DEC -#undef OLD_DEC -} - -static void -http_base_test(void *ptr) -{ - struct event_base *base = NULL; - struct bufferevent *bev; - evutil_socket_t fd; - const char *http_request; - ev_uint16_t port = 0; - - test_ok = 0; - base = event_base_new(); - tt_assert(base); - http = http_setup(&port, base, 0); - - fd = http_connect("127.0.0.1", port); - tt_int_op(fd, >=, 0); - - /* Stupid thing to send a request */ - bev = bufferevent_socket_new(base, fd, 0); - bufferevent_setcb(bev, http_readcb, http_writecb, - http_errorcb, base); - bufferevent_base_set(base, bev); - - http_request = - "GET /test HTTP/1.1\r\n" - "Host: somehost\r\n" - "Connection: close\r\n" - "\r\n"; - - bufferevent_write(bev, http_request, strlen(http_request)); - - event_base_dispatch(base); - - bufferevent_free(bev); - evutil_closesocket(fd); - - evhttp_free(http); - - tt_int_op(test_ok, ==, 2); - -end: - if (base) - event_base_free(base); -} - -/* - * the server is just going to close the connection if it times out during - * reading the headers. - */ - -static void -http_incomplete_readcb(struct bufferevent *bev, void *arg) -{ - test_ok = -1; - event_base_loopexit(exit_base,NULL); -} - -static void -http_incomplete_errorcb(struct bufferevent *bev, short what, void *arg) -{ - /** For ssl */ - if (what & BEV_EVENT_CONNECTED) - return; - - if (what == (BEV_EVENT_READING|BEV_EVENT_EOF)) - test_ok++; - else - test_ok = -2; - event_base_loopexit(exit_base,NULL); -} - -static void -http_incomplete_writecb(struct bufferevent *bev, void *arg) -{ - if (arg != NULL) { - evutil_socket_t fd = *(evutil_socket_t *)arg; - /* terminate the write side to simulate EOF */ - shutdown(fd, SHUT_WR); - } - if (evbuffer_get_length(bufferevent_get_output(bev)) == 0) { - /* enable reading of the reply */ - bufferevent_enable(bev, EV_READ); - test_ok++; - } -} - -static void -http_incomplete_test_(struct basic_test_data *data, int use_timeout, int ssl) -{ - struct bufferevent *bev; - evutil_socket_t fd; - const char *http_request; - ev_uint16_t port = 0; - struct timeval tv_start, tv_end; - - exit_base = data->base; - - test_ok = 0; - - http = http_setup(&port, data->base, ssl ? HTTP_BIND_SSL : 0); - evhttp_set_timeout(http, 1); - - fd = http_connect("127.0.0.1", port); - tt_int_op(fd, >=, 0); - - /* Stupid thing to send a request */ - bev = create_bev(data->base, fd, ssl); - bufferevent_setcb(bev, - http_incomplete_readcb, http_incomplete_writecb, - http_incomplete_errorcb, use_timeout ? NULL : &fd); - - http_request = - "GET /test HTTP/1.1\r\n" - "Host: somehost\r\n"; - - bufferevent_write(bev, http_request, strlen(http_request)); - - evutil_gettimeofday(&tv_start, NULL); - - event_base_dispatch(data->base); - - evutil_gettimeofday(&tv_end, NULL); - evutil_timersub(&tv_end, &tv_start, &tv_end); - - bufferevent_free(bev); - if (use_timeout) { - evutil_closesocket(fd); - fd = -1; - } - - evhttp_free(http); - - if (use_timeout && tv_end.tv_sec >= 3) { - tt_abort_msg("time"); - } else if (!use_timeout && tv_end.tv_sec >= 1) { - /* we should be done immediately */ - tt_abort_msg("time"); - } - - tt_int_op(test_ok, ==, 2); - end: - if (fd >= 0) - evutil_closesocket(fd); -} -static void http_incomplete_test(void *arg) -{ http_incomplete_test_(arg, 0, 0); } -static void http_incomplete_timeout_test(void *arg) -{ http_incomplete_test_(arg, 1, 0); } - - -/* - * the server is going to reply with chunked data. - */ - -static void -http_chunked_readcb(struct bufferevent *bev, void *arg) -{ - /* nothing here */ -} - -static void -http_chunked_errorcb(struct bufferevent *bev, short what, void *arg) -{ - struct evhttp_request *req = NULL; - - /** SSL */ - if (what & BEV_EVENT_CONNECTED) - return; - - if (!test_ok) - goto out; - - test_ok = -1; - - if ((what & BEV_EVENT_EOF) != 0) { - const char *header; - enum message_read_status done; - req = evhttp_request_new(NULL, NULL); - - /* req->kind = EVHTTP_RESPONSE; */ - done = evhttp_parse_firstline_(req, bufferevent_get_input(bev)); - if (done != ALL_DATA_READ) - goto out; - - done = evhttp_parse_headers_(req, bufferevent_get_input(bev)); - if (done != ALL_DATA_READ) - goto out; - - header = evhttp_find_header(evhttp_request_get_input_headers(req), "Transfer-Encoding"); - if (header == NULL || strcmp(header, "chunked")) - goto out; - - header = evhttp_find_header(evhttp_request_get_input_headers(req), "Connection"); - if (header == NULL || strcmp(header, "close")) - goto out; - - header = evbuffer_readln(bufferevent_get_input(bev), NULL, EVBUFFER_EOL_CRLF); - if (header == NULL) - goto out; - /* 13 chars */ - if (strcmp(header, "d")) { - free((void*)header); - goto out; - } - free((void*)header); - - if (strncmp((char *)evbuffer_pullup(bufferevent_get_input(bev), 13), - "This is funny", 13)) - goto out; - - evbuffer_drain(bufferevent_get_input(bev), 13 + 2); - - header = evbuffer_readln(bufferevent_get_input(bev), NULL, EVBUFFER_EOL_CRLF); - if (header == NULL) - goto out; - /* 18 chars */ - if (strcmp(header, "12")) - goto out; - free((char *)header); - - if (strncmp((char *)evbuffer_pullup(bufferevent_get_input(bev), 18), - "but not hilarious.", 18)) - goto out; - - evbuffer_drain(bufferevent_get_input(bev), 18 + 2); - - header = evbuffer_readln(bufferevent_get_input(bev), NULL, EVBUFFER_EOL_CRLF); - if (header == NULL) - goto out; - /* 8 chars */ - if (strcmp(header, "8")) { - free((void*)header); - goto out; - } - free((char *)header); - - if (strncmp((char *)evbuffer_pullup(bufferevent_get_input(bev), 8), - "bwv 1052.", 8)) - goto out; - - evbuffer_drain(bufferevent_get_input(bev), 8 + 2); - - header = evbuffer_readln(bufferevent_get_input(bev), NULL, EVBUFFER_EOL_CRLF); - if (header == NULL) - goto out; - /* 0 chars */ - if (strcmp(header, "0")) { - free((void*)header); - goto out; - } - free((void *)header); - - test_ok = 2; - } - -out: - if (req) - evhttp_request_free(req); - - event_base_loopexit(arg, NULL); -} - -static void -http_chunked_writecb(struct bufferevent *bev, void *arg) -{ - if (evbuffer_get_length(bufferevent_get_output(bev)) == 0) { - /* enable reading of the reply */ - bufferevent_enable(bev, EV_READ); - test_ok++; - } -} - -static void -http_chunked_request_done(struct evhttp_request *req, void *arg) -{ - if (evhttp_request_get_response_code(req) != HTTP_OK) { - fprintf(stderr, "FAILED\n"); - exit(1); - } - - if (evhttp_find_header(evhttp_request_get_input_headers(req), - "Transfer-Encoding") == NULL) { - fprintf(stderr, "FAILED\n"); - exit(1); - } - - if (evbuffer_get_length(evhttp_request_get_input_buffer(req)) != 13 + 18 + 8) { - fprintf(stderr, "FAILED\n"); - exit(1); - } - - if (strncmp((char *)evbuffer_pullup(evhttp_request_get_input_buffer(req), 13 + 18 + 8), - "This is funnybut not hilarious.bwv 1052", - 13 + 18 + 8)) { - fprintf(stderr, "FAILED\n"); - exit(1); - } - - test_ok = 1; - event_base_loopexit(arg, NULL); -} - -static void -http_chunk_out_test_impl(void *arg, int ssl) -{ - struct basic_test_data *data = arg; - struct bufferevent *bev; - evutil_socket_t fd; - const char *http_request; - ev_uint16_t port = 0; - struct timeval tv_start, tv_end; - struct evhttp_connection *evcon = NULL; - struct evhttp_request *req = NULL; - int i; - - exit_base = data->base; - test_ok = 0; - - http = http_setup(&port, data->base, ssl ? HTTP_BIND_SSL : 0); - - fd = http_connect("127.0.0.1", port); - - /* Stupid thing to send a request */ - bev = create_bev(data->base, fd, ssl); - bufferevent_setcb(bev, - http_chunked_readcb, http_chunked_writecb, - http_chunked_errorcb, data->base); - - http_request = - "GET /chunked HTTP/1.1\r\n" - "Host: somehost\r\n" - "Connection: close\r\n" - "\r\n"; - - bufferevent_write(bev, http_request, strlen(http_request)); - - evutil_gettimeofday(&tv_start, NULL); - - event_base_dispatch(data->base); - - bufferevent_free(bev); - - evutil_gettimeofday(&tv_end, NULL); - evutil_timersub(&tv_end, &tv_start, &tv_end); - - tt_int_op(tv_end.tv_sec, <, 1); - - tt_int_op(test_ok, ==, 2); - - /* now try again with the regular connection object */ - bev = create_bev(data->base, -1, ssl); - evcon = evhttp_connection_base_bufferevent_new( - data->base, NULL, bev, "127.0.0.1", port); - tt_assert(evcon); - - /* make two requests to check the keepalive behavior */ - for (i = 0; i < 2; i++) { - test_ok = 0; - req = evhttp_request_new(http_chunked_request_done,data->base); - - /* Add the information that we care about */ - evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); - - /* We give ownership of the request to the connection */ - if (evhttp_make_request(evcon, req, - EVHTTP_REQ_GET, "/chunked") == -1) { - tt_abort_msg("Couldn't make request"); - } - - event_base_dispatch(data->base); - - tt_assert(test_ok == 1); - } - - end: - if (evcon) - evhttp_connection_free(evcon); - if (http) - evhttp_free(http); -} -static void http_chunk_out_test(void *arg) -{ return http_chunk_out_test_impl(arg, 0); } - -static void -http_stream_out_test_impl(void *arg, int ssl) -{ - struct basic_test_data *data = arg; - ev_uint16_t port = 0; - struct evhttp_connection *evcon = NULL; - struct evhttp_request *req = NULL; - struct bufferevent *bev; - - test_ok = 0; - exit_base = data->base; - - http = http_setup(&port, data->base, ssl ? HTTP_BIND_SSL : 0); - - bev = create_bev(data->base, -1, ssl); - evcon = evhttp_connection_base_bufferevent_new( - data->base, NULL, bev, "127.0.0.1", port); - tt_assert(evcon); - - /* - * At this point, we want to schedule a request to the HTTP - * server using our make request method. - */ - - req = evhttp_request_new(http_request_done, - (void *)"This is funnybut not hilarious.bwv 1052"); - - /* Add the information that we care about */ - evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); - - /* We give ownership of the request to the connection */ - if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/streamed") - == -1) { - tt_abort_msg("Couldn't make request"); - } - - event_base_dispatch(data->base); - - end: - if (evcon) - evhttp_connection_free(evcon); - if (http) - evhttp_free(http); -} -static void http_stream_out_test(void *arg) -{ return http_stream_out_test_impl(arg, 0); } - -static void -http_stream_in_chunk(struct evhttp_request *req, void *arg) -{ - struct evbuffer *reply = arg; - - if (evhttp_request_get_response_code(req) != HTTP_OK) { - fprintf(stderr, "FAILED\n"); - exit(1); - } - - evbuffer_add_buffer(reply, evhttp_request_get_input_buffer(req)); -} - -static void -http_stream_in_done(struct evhttp_request *req, void *arg) -{ - if (evbuffer_get_length(evhttp_request_get_input_buffer(req)) != 0) { - fprintf(stderr, "FAILED\n"); - exit(1); - } - - event_base_loopexit(exit_base, NULL); -} - -/** - * Makes a request and reads the response in chunks. - */ -static void -http_stream_in_test_(struct basic_test_data *data, char const *url, - size_t expected_len, char const *expected) -{ - struct evhttp_connection *evcon; - struct evbuffer *reply = evbuffer_new(); - struct evhttp_request *req = NULL; - ev_uint16_t port = 0; - - exit_base = data->base; - http = http_setup(&port, data->base, 0); - - evcon = evhttp_connection_base_new(data->base, NULL,"127.0.0.1", port); - tt_assert(evcon); - - req = evhttp_request_new(http_stream_in_done, reply); - evhttp_request_set_chunked_cb(req, http_stream_in_chunk); - - /* We give ownership of the request to the connection */ - if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, url) == -1) { - tt_abort_msg("Couldn't make request"); - } - - event_base_dispatch(data->base); - - if (evbuffer_get_length(reply) != expected_len) { - TT_DIE(("reply length %lu; expected %lu; FAILED (%s)\n", - (unsigned long)evbuffer_get_length(reply), - (unsigned long)expected_len, - (char*)evbuffer_pullup(reply, -1))); - } - - if (memcmp(evbuffer_pullup(reply, -1), expected, expected_len) != 0) { - tt_abort_msg("Memory mismatch"); - } - - test_ok = 1; - end: - if (reply) - evbuffer_free(reply); - if (evcon) - evhttp_connection_free(evcon); - if (http) - evhttp_free(http); -} - -static void -http_stream_in_test(void *arg) -{ - http_stream_in_test_(arg, "/chunked", 13 + 18 + 8, - "This is funnybut not hilarious.bwv 1052"); - - http_stream_in_test_(arg, "/test", strlen(BASIC_REQUEST_BODY), - BASIC_REQUEST_BODY); -} - -static void -http_stream_in_cancel_chunk(struct evhttp_request *req, void *arg) -{ - tt_int_op(evhttp_request_get_response_code(req), ==, HTTP_OK); - - end: - evhttp_cancel_request(req); - event_base_loopexit(arg, NULL); -} - -static void -http_stream_in_cancel_done(struct evhttp_request *req, void *arg) -{ - /* should never be called */ - tt_fail_msg("In cancel done"); -} - -static void -http_stream_in_cancel_test(void *arg) -{ - struct basic_test_data *data = arg; - struct evhttp_connection *evcon; - struct evhttp_request *req = NULL; - ev_uint16_t port = 0; - - http = http_setup(&port, data->base, 0); - - evcon = evhttp_connection_base_new(data->base, NULL, "127.0.0.1", port); - tt_assert(evcon); - - req = evhttp_request_new(http_stream_in_cancel_done, data->base); - evhttp_request_set_chunked_cb(req, http_stream_in_cancel_chunk); - - /* We give ownership of the request to the connection */ - if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/chunked") == -1) { - tt_abort_msg("Couldn't make request"); - } - - event_base_dispatch(data->base); - - test_ok = 1; - end: - evhttp_connection_free(evcon); - evhttp_free(http); - -} - -static void -http_connection_fail_done(struct evhttp_request *req, void *arg) -{ - struct evhttp_connection *evcon = arg; - struct event_base *base = evhttp_connection_get_base(evcon); - - /* An ENETUNREACH error results in an unrecoverable - * evhttp_connection error (see evhttp_connection_fail_()). The - * connection will be reset, and the user will be notified with a NULL - * req parameter. */ - tt_assert(!req); - - evhttp_connection_free(evcon); - - test_ok = 1; - - end: - event_base_loopexit(base, NULL); -} - -/* Test unrecoverable evhttp_connection errors by generating an ENETUNREACH - * error on connection. */ -static void -http_connection_fail_test_impl(void *arg, int ssl) -{ - struct basic_test_data *data = arg; - ev_uint16_t port = 0; - struct evhttp_connection *evcon = NULL; - struct evhttp_request *req = NULL; - struct bufferevent *bev; - - exit_base = data->base; - test_ok = 0; - - /* auto detect a port */ - http = http_setup(&port, data->base, ssl ? HTTP_BIND_SSL : 0); - evhttp_free(http); - http = NULL; - - bev = create_bev(data->base, -1, ssl); - /* Pick an unroutable address. This administratively scoped multicast - * address should do when working with TCP. */ - evcon = evhttp_connection_base_bufferevent_new( - data->base, NULL, bev, "239.10.20.30", 80); - tt_assert(evcon); - - /* - * At this point, we want to schedule an HTTP GET request - * server using our make request method. - */ - - req = evhttp_request_new(http_connection_fail_done, evcon); - tt_assert(req); - - if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/") == -1) { - tt_abort_msg("Couldn't make request"); - } - - event_base_dispatch(data->base); - - tt_int_op(test_ok, ==, 1); - - end: - ; -} -static void http_connection_fail_test(void *arg) -{ return http_connection_fail_test_impl(arg, 0); } - -static void -http_connection_retry_done(struct evhttp_request *req, void *arg) -{ - tt_assert(req); - tt_int_op(evhttp_request_get_response_code(req), !=, HTTP_OK); - if (evhttp_find_header(evhttp_request_get_input_headers(req), "Content-Type") != NULL) { - tt_abort_msg("(content type)\n"); - } - - tt_uint_op(evbuffer_get_length(evhttp_request_get_input_buffer(req)), ==, 0); - - test_ok = 1; - end: - event_base_loopexit(arg,NULL); -} - -struct http_server -{ - ev_uint16_t port; - int ssl; -}; -static struct event_base *http_make_web_server_base=NULL; -static void -http_make_web_server(evutil_socket_t fd, short what, void *arg) -{ - struct http_server *hs = (struct http_server *)arg; - http = http_setup(&hs->port, http_make_web_server_base, hs->ssl ? HTTP_BIND_SSL : 0); -} - -static void -http_simple_test_impl(void *arg, int ssl, int dirty) -{ - struct basic_test_data *data = arg; - struct evhttp_connection *evcon = NULL; - struct evhttp_request *req = NULL; - struct bufferevent *bev; - struct http_server hs = { .port = 0, .ssl = ssl, }; - - exit_base = data->base; - test_ok = 0; - - http = http_setup(&hs.port, data->base, ssl ? HTTP_BIND_SSL : 0); - - bev = create_bev(data->base, -1, ssl); - evcon = evhttp_connection_base_bufferevent_new( - data->base, NULL, bev, "127.0.0.1", hs.port); - tt_assert(evcon); - evhttp_connection_set_local_address(evcon, "127.0.0.1"); - - 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) { - tt_abort_msg("Couldn't make request"); - } - - event_base_dispatch(data->base); - tt_int_op(test_ok, ==, 1); - - end: - if (evcon) - evhttp_connection_free(evcon); - if (http) - evhttp_free(http); -} -static void http_simple_test(void *arg) -{ return 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) -{ - struct basic_test_data *data = arg; - struct evhttp_connection *evcon = NULL; - struct evhttp_request *req = NULL; - struct timeval tv, tv_start, tv_end; - struct bufferevent *bev; - struct http_server hs = { .port = 0, .ssl = ssl, }; - - exit_base = data->base; - test_ok = 0; - - /* auto detect a port */ - http = http_setup(&hs.port, data->base, ssl ? HTTP_BIND_SSL : 0); - evhttp_free(http); - http = NULL; - - bev = create_bev(data->base, -1, ssl); - evcon = evhttp_connection_base_bufferevent_new(data->base, dns_base, bev, addr, hs.port); - tt_assert(evcon); - if (dns_base) - tt_assert(!evhttp_connection_set_flags(evcon, EVHTTP_CON_REUSE_CONNECTED_ADDR)); - - evhttp_connection_set_timeout(evcon, 1); - /* 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. - */ - - req = evhttp_request_new(http_connection_retry_done, data->base); - tt_assert(req); - - /* Add the information that we care about */ - evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); - - if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, - "/?arg=val") == -1) { - tt_abort_msg("Couldn't make request"); - } - - evutil_gettimeofday(&tv_start, NULL); - event_base_dispatch(data->base); - evutil_gettimeofday(&tv_end, NULL); - evutil_timersub(&tv_end, &tv_start, &tv_end); - tt_int_op(tv_end.tv_sec, <, 1); - - tt_int_op(test_ok, ==, 1); - - /* - * now test the same but with retries - */ - test_ok = 0; - /** Shutdown dns server, to test conn_address reusing */ - if (dns_base) - regress_clean_dnsserver(); - - { - const struct timeval tv_timeout = { 0, 500000 }; - const struct timeval tv_retry = { 0, 500000 }; - evhttp_connection_set_timeout_tv(evcon, &tv_timeout); - evhttp_connection_set_initial_retry_tv(evcon, &tv_retry); - } - evhttp_connection_set_retries(evcon, 1); - - req = evhttp_request_new(http_connection_retry_done, data->base); - tt_assert(req); - - /* Add the information that we care about */ - evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); - - if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, - "/?arg=val") == -1) { - tt_abort_msg("Couldn't make request"); - } - - evutil_gettimeofday(&tv_start, NULL); - event_base_dispatch(data->base); - evutil_gettimeofday(&tv_end, NULL); - - /* fails fast, .5 sec to wait to retry, fails fast again. */ - test_timeval_diff_leq(&tv_start, &tv_end, 500, 200); - - tt_assert(test_ok == 1); - - /* - * now test the same but with retries and give it a web server - * at the end - */ - test_ok = 0; - - evhttp_connection_set_timeout(evcon, 1); - evhttp_connection_set_retries(evcon, 3); - - req = evhttp_request_new(http_dispatcher_test_done, data->base); - tt_assert(req); - - /* Add the information that we care about */ - evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); - - if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, - "/?arg=val") == -1) { - tt_abort_msg("Couldn't make request"); - } - - /* start up a web server .2 seconds after the connection tried - * to send a request - */ - evutil_timerclear(&tv); - tv.tv_usec = 200000; - http_make_web_server_base = data->base; - event_base_once(data->base, -1, EV_TIMEOUT, http_make_web_server, &hs, &tv); - - evutil_gettimeofday(&tv_start, NULL); - event_base_dispatch(data->base); - evutil_gettimeofday(&tv_end, NULL); - /* We'll wait twice as long as we did last time. */ - test_timeval_diff_leq(&tv_start, &tv_end, 1000, 400); - - tt_int_op(test_ok, ==, 1); - - end: - if (evcon) - evhttp_connection_free(evcon); - if (http) - evhttp_free(http); -} - -static void -http_connection_retry_conn_address_test_impl(void *arg, int ssl) -{ - struct basic_test_data *data = arg; - ev_uint16_t portnum = 0; - struct evdns_base *dns_base = NULL; - char address[64]; - - tt_assert(regress_dnsserver(data->base, &portnum, search_table)); - dns_base = evdns_base_new(data->base, 0/* init name servers */); - tt_assert(dns_base); - - /* Add ourself as the only nameserver, and make sure we really are - * the only nameserver. */ - evutil_snprintf(address, sizeof(address), "127.0.0.1:%d", portnum); - evdns_base_nameserver_ip_add(dns_base, address); - - http_connection_retry_test_basic(arg, "localhost", dns_base, ssl); - - end: - if (dns_base) - evdns_base_free(dns_base, 0); - /** 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); } - -static void -http_connection_retry_test_impl(void *arg, int ssl) -{ - return 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); } - -static void -http_primitives(void *ptr) -{ - char *escaped = NULL; - struct evhttp *http = NULL; - - escaped = evhttp_htmlescape("<script>"); - tt_assert(escaped); - tt_str_op(escaped, ==, "<script>"); - free(escaped); - - escaped = evhttp_htmlescape("\"\'&"); - tt_assert(escaped); - tt_str_op(escaped, ==, ""'&"); - - http = evhttp_new(NULL); - tt_assert(http); - tt_int_op(evhttp_set_cb(http, "/test", http_basic_cb, NULL), ==, 0); - tt_int_op(evhttp_set_cb(http, "/test", http_basic_cb, NULL), ==, -1); - tt_int_op(evhttp_del_cb(http, "/test"), ==, 0); - tt_int_op(evhttp_del_cb(http, "/test"), ==, -1); - tt_int_op(evhttp_set_cb(http, "/test", http_basic_cb, NULL), ==, 0); - - end: - if (escaped) - free(escaped); - if (http) - evhttp_free(http); -} - -static void -http_multi_line_header_test(void *arg) -{ - struct basic_test_data *data = arg; - struct bufferevent *bev= NULL; - evutil_socket_t fd = -1; - const char *http_start_request; - ev_uint16_t port = 0; - - test_ok = 0; - - http = http_setup(&port, data->base, 0); - - tt_ptr_op(http, !=, NULL); - - fd = http_connect("127.0.0.1", port); - - tt_int_op(fd, !=, -1); - - /* Stupid thing to send a request */ - bev = bufferevent_socket_new(data->base, fd, 0); - tt_ptr_op(bev, !=, NULL); - bufferevent_setcb(bev, http_readcb, http_writecb, - http_errorcb, data->base); - - http_start_request = - "GET /test HTTP/1.1\r\n" - "Host: somehost\r\n" - "Connection: close\r\n" - "X-Multi-Extra-WS: libevent \r\n" - "\t\t\t2.1 \r\n" - "X-Multi: aaaaaaaa\r\n" - " a\r\n" - "\tEND\r\n" - "X-Last: last\r\n" - "\r\n"; - - bufferevent_write(bev, http_start_request, strlen(http_start_request)); - found_multi = found_multi2 = 0; - - event_base_dispatch(data->base); - - tt_int_op(found_multi, ==, 1); - tt_int_op(found_multi2, ==, 1); - tt_int_op(test_ok, ==, 4); - end: - if (bev) - bufferevent_free(bev); - if (fd >= 0) - evutil_closesocket(fd); - if (http) - evhttp_free(http); -} - -static void -http_request_bad(struct evhttp_request *req, void *arg) -{ - if (req != NULL) { - fprintf(stderr, "FAILED\n"); - exit(1); - } - - test_ok = 1; - event_base_loopexit(arg, NULL); -} - -static void -http_negative_content_length_test(void *arg) -{ - struct basic_test_data *data = arg; - ev_uint16_t port = 0; - struct evhttp_connection *evcon = NULL; - struct evhttp_request *req = NULL; - - test_ok = 0; - - http = http_setup(&port, data->base, 0); - - evcon = evhttp_connection_base_new(data->base, NULL, "127.0.0.1", port); - tt_assert(evcon); - - /* - * At this point, we want to schedule a request to the HTTP - * server using our make request method. - */ - - req = evhttp_request_new(http_request_bad, data->base); - - /* Cause the response to have a negative content-length */ - evhttp_add_header(evhttp_request_get_output_headers(req), "X-Negative", "makeitso"); - - /* We give ownership of the request to the connection */ - if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") == -1) { - tt_abort_msg("Couldn't make request"); - } - - event_base_dispatch(data->base); - - end: - if (evcon) - evhttp_connection_free(evcon); - if (http) - evhttp_free(http); -} - - -static void -http_data_length_constraints_test_done(struct evhttp_request *req, void *arg) -{ - tt_assert(req); - tt_int_op(evhttp_request_get_response_code(req), ==, HTTP_BADREQUEST); -end: - event_base_loopexit(arg, NULL); -} - -static void -http_large_entity_test_done(struct evhttp_request *req, void *arg) -{ - tt_assert(req); - tt_int_op(evhttp_request_get_response_code(req), ==, HTTP_ENTITYTOOLARGE); -end: - event_base_loopexit(arg, NULL); -} - -static void -http_data_length_constraints_test(void *arg) -{ - struct basic_test_data *data = arg; - ev_uint16_t port = 0; - struct evhttp_connection *evcon = NULL; - struct evhttp_request *req = NULL; - char long_str[8192]; - - test_ok = 0; - - http = http_setup(&port, data->base, 0); - - evcon = evhttp_connection_base_new(data->base, NULL, "127.0.0.1", port); - tt_assert(evcon); - - /* 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. - */ - - req = evhttp_request_new(http_data_length_constraints_test_done, data->base); - tt_assert(req); - - memset(long_str, 'a', 8192); - long_str[8191] = '\0'; - /* Add the information that we care about */ - evhttp_set_max_headers_size(http, 8191); - evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost"); - evhttp_add_header(evhttp_request_get_output_headers(req), "Longheader", long_str); - - if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/?arg=val") == -1) { - tt_abort_msg("Couldn't make request"); - } - event_base_dispatch(data->base); - - 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 */ - 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, 8190); - req = evhttp_request_new(http_data_length_constraints_test_done, 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); - if (evhttp_make_request(evcon, req, EVHTTP_REQ_POST, "/") == -1) { - tt_abort_msg("Couldn't make request"); - } - event_base_dispatch(data->base); - - req = evhttp_request_new(http_large_entity_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"); - evbuffer_add_printf(evhttp_request_get_output_buffer(req), "%s", long_str); - if (evhttp_make_request(evcon, req, EVHTTP_REQ_POST, "/") == -1) { - tt_abort_msg("Couldn't make request"); - } - event_base_dispatch(data->base); - - test_ok = 1; - end: - if (evcon) - evhttp_connection_free(evcon); - if (http) - evhttp_free(http); -} - -/* - * Testing client reset of server chunked connections - */ - -struct terminate_state { - struct event_base *base; - struct evhttp_request *req; - struct bufferevent *bev; - evutil_socket_t fd; - int gotclosecb: 1; - int oneshot: 1; -}; - -static void -terminate_chunked_trickle_cb(evutil_socket_t fd, short events, void *arg) -{ - struct terminate_state *state = arg; - struct evbuffer *evb; - - if (!state->req) { - return; - } - - if (evhttp_request_get_connection(state->req) == NULL) { - test_ok = 1; - evhttp_request_free(state->req); - event_base_loopexit(state->base,NULL); - return; - } - - evb = evbuffer_new(); - evbuffer_add_printf(evb, "%p", evb); - evhttp_send_reply_chunk(state->req, evb); - evbuffer_free(evb); - - if (!state->oneshot) { - struct timeval tv; - tv.tv_sec = 0; - tv.tv_usec = 3000; - EVUTIL_ASSERT(state); - EVUTIL_ASSERT(state->base); - event_base_once(state->base, -1, EV_TIMEOUT, terminate_chunked_trickle_cb, arg, &tv); - } -} - -static void -terminate_chunked_close_cb(struct evhttp_connection *evcon, void *arg) -{ - struct terminate_state *state = arg; - state->gotclosecb = 1; - - /** TODO: though we can do this unconditionally */ - if (state->oneshot) { - evhttp_request_free(state->req); - state->req = NULL; - event_base_loopexit(state->base,NULL); - } -} - -static void -terminate_chunked_cb(struct evhttp_request *req, void *arg) -{ - struct terminate_state *state = arg; - struct timeval tv; - - /* we want to know if this connection closes on us */ - evhttp_connection_set_closecb( - evhttp_request_get_connection(req), - terminate_chunked_close_cb, arg); - - state->req = req; - - evhttp_send_reply_start(req, HTTP_OK, "OK"); - - tv.tv_sec = 0; - tv.tv_usec = 3000; - event_base_once(state->base, -1, EV_TIMEOUT, terminate_chunked_trickle_cb, arg, &tv); -} - -static void -terminate_chunked_client(evutil_socket_t fd, short event, void *arg) -{ - struct terminate_state *state = arg; - bufferevent_free(state->bev); - evutil_closesocket(state->fd); -} - -static void -terminate_readcb(struct bufferevent *bev, void *arg) -{ - /* just drop the data */ - evbuffer_drain(bufferevent_get_input(bev), -1); -} - - -static void -http_terminate_chunked_test_impl(void *arg, int oneshot) -{ - struct basic_test_data *data = arg; - struct bufferevent *bev = NULL; - struct timeval tv; - const char *http_request; - ev_uint16_t port = 0; - evutil_socket_t fd = -1; - struct terminate_state terminate_state; - - test_ok = 0; - - http = http_setup(&port, data->base, 0); - evhttp_del_cb(http, "/test"); - tt_assert(evhttp_set_cb(http, "/test", - terminate_chunked_cb, &terminate_state) == 0); - - fd = http_connect("127.0.0.1", port); - - /* Stupid thing to send a request */ - bev = bufferevent_socket_new(data->base, fd, 0); - bufferevent_setcb(bev, terminate_readcb, http_writecb, - http_errorcb, data->base); - - memset(&terminate_state, 0, sizeof(terminate_state)); - terminate_state.base = data->base; - terminate_state.fd = fd; - terminate_state.bev = bev; - terminate_state.gotclosecb = 0; - terminate_state.oneshot = oneshot; - - /* first half of the http request */ - http_request = - "GET /test HTTP/1.1\r\n" - "Host: some\r\n\r\n"; - - bufferevent_write(bev, http_request, strlen(http_request)); - evutil_timerclear(&tv); - tv.tv_usec = 10000; - event_base_once(data->base, -1, EV_TIMEOUT, terminate_chunked_client, &terminate_state, - &tv); - - event_base_dispatch(data->base); - - if (terminate_state.gotclosecb == 0) - test_ok = 0; - - end: - if (fd >= 0) - evutil_closesocket(fd); - if (http) - evhttp_free(http); -} -static void -http_terminate_chunked_test(void *arg) -{ - http_terminate_chunked_test_impl(arg, 0); -} -static void -http_terminate_chunked_oneshot_test(void *arg) -{ - http_terminate_chunked_test_impl(arg, 1); -} - -static struct regress_dns_server_table ipv6_search_table[] = { - { "localhost", "AAAA", "::1", 0, 0 }, - { NULL, NULL, NULL, 0, 0 } -}; - -static void -http_ipv6_for_domain_test_impl(void *arg, int family) -{ - struct basic_test_data *data = arg; - struct evdns_base *dns_base = NULL; - ev_uint16_t portnum = 0; - char address[64]; - - tt_assert(regress_dnsserver(data->base, &portnum, ipv6_search_table)); - - dns_base = evdns_base_new(data->base, 0/* init name servers */); - tt_assert(dns_base); - - /* Add ourself as the only nameserver, and make sure we really are - * the only nameserver. */ - evutil_snprintf(address, sizeof(address), "127.0.0.1:%d", portnum); - evdns_base_nameserver_ip_add(dns_base, address); - - http_connection_test_(arg, 0 /* not persistent */, "localhost", dns_base, - 1 /* ipv6 */, family); - - end: - if (dns_base) - evdns_base_free(dns_base, 0); - regress_clean_dnsserver(); -} -static void -http_ipv6_for_domain_test(void *arg) -{ - http_ipv6_for_domain_test_impl(arg, AF_UNSPEC); -} - -static void -http_request_get_addr_on_close(struct evhttp_connection *evcon, void *arg) -{ - const struct sockaddr *storage; - char addrbuf[128]; - char local[] = "127.0.0.1:"; - - test_ok = 0; - tt_assert(evcon); - - storage = evhttp_connection_get_addr(evcon); - tt_assert(storage); - - evutil_format_sockaddr_port_((struct sockaddr *)storage, addrbuf, sizeof(addrbuf)); - tt_assert(!strncmp(addrbuf, local, sizeof(local) - 1)); - - test_ok = 1; - return; - -end: - test_ok = 0; -} - -static void -http_get_addr_test(void *arg) -{ - struct basic_test_data *data = arg; - ev_uint16_t port = 0; - struct evhttp_connection *evcon = NULL; - struct evhttp_request *req = NULL; - - test_ok = 0; - exit_base = data->base; - - http = http_setup(&port, data->base, 0); - - evcon = evhttp_connection_base_new(data->base, NULL, "127.0.0.1", port); - tt_assert(evcon); - evhttp_connection_set_closecb(evcon, http_request_get_addr_on_close, arg); - - /* - * At this point, we want to schedule a request to the HTTP - * server using our make request method. - */ - - req = evhttp_request_new(http_request_done, (void *)BASIC_REQUEST_BODY); - - /* We give ownership of the request to the connection */ - if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") == -1) { - tt_abort_msg("Couldn't make request"); - } - - event_base_dispatch(data->base); - - http_request_get_addr_on_close(evcon, NULL); - - end: - if (evcon) - evhttp_connection_free(evcon); - if (http) - evhttp_free(http); -} - -static void -http_set_family_test(void *arg) -{ - http_connection_test_(arg, 0, "127.0.0.1", NULL, 0, AF_UNSPEC); -} -static void -http_set_family_ipv4_test(void *arg) -{ - http_connection_test_(arg, 0, "127.0.0.1", NULL, 0, AF_INET); -} -static void -http_set_family_ipv6_test(void *arg) -{ - http_ipv6_for_domain_test_impl(arg, AF_INET6); -} - -static void -http_write_during_read(evutil_socket_t fd, short what, void *arg) -{ - struct bufferevent *bev = arg; - struct timeval tv; - - bufferevent_write(bev, "foobar", strlen("foobar")); - - evutil_timerclear(&tv); - tv.tv_sec = 1; - event_base_loopexit(exit_base, &tv); -} -static void -http_write_during_read_test_impl(void *arg, int ssl) -{ - struct basic_test_data *data = arg; - ev_uint16_t port = 0; - struct bufferevent *bev = NULL; - struct timeval tv; - int fd; - const char *http_request; - - test_ok = 0; - exit_base = data->base; - - http = http_setup(&port, data->base, ssl ? HTTP_BIND_SSL : 0); - - fd = http_connect("127.0.0.1", port); - bev = create_bev(data->base, fd, 0); - bufferevent_setcb(bev, NULL, NULL, NULL, data->base); - bufferevent_disable(bev, EV_READ); - - http_request = - "GET /large HTTP/1.1\r\n" - "Host: somehost\r\n" - "\r\n"; - - bufferevent_write(bev, http_request, strlen(http_request)); - evutil_timerclear(&tv); - tv.tv_usec = 10000; - event_base_once(data->base, -1, EV_TIMEOUT, http_write_during_read, bev, &tv); - - event_base_dispatch(data->base); - - if (bev) - bufferevent_free(bev); - if (http) - evhttp_free(http); -} -static void http_write_during_read_test(void *arg) -{ return http_write_during_read_test_impl(arg, 0); } - -static void -http_request_own_test(void *arg) -{ - struct basic_test_data *data = arg; - ev_uint16_t port = 0; - struct evhttp_connection *evcon = NULL; - struct evhttp_request *req = NULL; - - test_ok = 0; - exit_base = data->base; - - http = http_setup(&port, data->base, 0); - evhttp_free(http); - - evcon = evhttp_connection_base_new(data->base, NULL, "127.0.0.1", port); - tt_assert(evcon); - - req = evhttp_request_new(http_request_no_action_done, NULL); - - if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") == -1) { - tt_abort_msg("Couldn't make request"); - } - evhttp_request_own(req); - - event_base_dispatch(data->base); - - end: - if (evcon) - evhttp_connection_free(evcon); - if (req) - evhttp_request_free(req); - - test_ok = 1; -} - -#define HTTP_LEGACY(name) \ - { #name, run_legacy_test_fn, TT_ISOLATED|TT_LEGACY, &legacy_setup, \ - http_##name##_test } - -#define HTTP(name) \ - { #name, http_##name##_test, TT_ISOLATED, &basic_setup, NULL } -#define HTTPS(name) \ - { "https_" #name, https_##name##_test, TT_ISOLATED, &basic_setup, NULL } - -#ifdef EVENT__HAVE_OPENSSL -static void https_basic_test(void *arg) -{ return http_basic_test_impl(arg, 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) -{ return http_simple_test_impl(arg, 1, 0); } -static void https_simple_dirty_test(void *arg) -{ return 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); } -static void https_connection_retry_test(void *arg) -{ return http_connection_retry_test_impl(arg, 1); } -static void https_chunk_out_test(void *arg) -{ return http_chunk_out_test_impl(arg, 1); } -static void https_stream_out_test(void *arg) -{ return http_stream_out_test_impl(arg, 1); } -static void https_connection_fail_test(void *arg) -{ return 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); } -#endif - -struct testcase_t http_testcases[] = { - { "primitives", http_primitives, 0, NULL, NULL }, - { "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_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 }, - HTTP(basic), - HTTP(simple), - HTTP(cancel), - HTTP(virtual_host), - HTTP(post), - HTTP(put), - HTTP(delete), - HTTP(allowed_methods), - HTTP(failure), - HTTP(connection), - HTTP(persist_connection), - HTTP(autofree_connection), - HTTP(connection_async), - HTTP(close_detection), - HTTP(close_detection_delay), - HTTP(bad_request), - HTTP(incomplete), - HTTP(incomplete_timeout), - HTTP(terminate_chunked), - HTTP(terminate_chunked_oneshot), - HTTP(on_complete), - - HTTP(highport), - HTTP(dispatcher), - HTTP(multi_line_header), - HTTP(negative_content_length), - HTTP(chunk_out), - HTTP(stream_out), - - HTTP(stream_in), - HTTP(stream_in_cancel), - - HTTP(connection_fail), - { "connection_retry", http_connection_retry_test, TT_ISOLATED|TT_OFF_BY_DEFAULT, &basic_setup, NULL }, - { "connection_retry_conn_address", http_connection_retry_conn_address_test, - TT_ISOLATED|TT_OFF_BY_DEFAULT, &basic_setup, NULL }, - - HTTP(data_length_constraints), - - HTTP(ipv6_for_domain), - HTTP(get_addr), - - HTTP(set_family), - HTTP(set_family_ipv4), - HTTP(set_family_ipv6), - - HTTP(write_during_read), - HTTP(request_own), - -#ifdef EVENT__HAVE_OPENSSL - HTTPS(basic), - HTTPS(simple), - HTTPS(simple_dirty), - HTTPS(incomplete), - HTTPS(incomplete_timeout), - { "https_connection_retry", https_connection_retry_test, TT_ISOLATED|TT_OFF_BY_DEFAULT, &basic_setup, NULL }, - { "https_connection_retry_conn_address", https_connection_retry_conn_address_test, - TT_ISOLATED|TT_OFF_BY_DEFAULT, &basic_setup, NULL }, - HTTPS(chunk_out), - HTTPS(stream_out), - HTTPS(connection_fail), - HTTPS(write_during_read), -#endif - - END_OF_TESTCASES -}; - diff --git a/protocols/Telegram/tgl/libevent/test/regress_http.obj b/protocols/Telegram/tgl/libevent/test/regress_http.obj Binary files differdeleted file mode 100644 index 85099a6a04..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress_http.obj +++ /dev/null diff --git a/protocols/Telegram/tgl/libevent/test/regress_iocp.c b/protocols/Telegram/tgl/libevent/test/regress_iocp.c deleted file mode 100644 index 17b385241f..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress_iocp.c +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright (c) 2009-2012 Niels Provos and Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> -#include <string.h> -#include "event2/event.h" -#include "event2/thread.h" -#include "event2/buffer.h" -#include "event2/buffer_compat.h" -#include "event2/bufferevent.h" - -#include <winsock2.h> -#include <ws2tcpip.h> - -#include "regress.h" -#include "tinytest.h" -#include "tinytest_macros.h" - -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#include <winsock2.h> -#undef WIN32_LEAN_AND_MEAN - -#include "iocp-internal.h" -#include "evbuffer-internal.h" -#include "evthread-internal.h" - -/* FIXME remove these ones */ -#include <sys/queue.h> -#include "event2/event_struct.h" -#include "event-internal.h" - -#define MAX_CALLS 16 - -static void *count_lock = NULL, *count_cond = NULL; -static int count = 0; - -static void -count_init(void) -{ - EVTHREAD_ALLOC_LOCK(count_lock, 0); - EVTHREAD_ALLOC_COND(count_cond); - - tt_assert(count_lock); - tt_assert(count_cond); - -end: - ; -} - -static void -count_free(void) -{ - EVTHREAD_FREE_LOCK(count_lock, 0); - EVTHREAD_FREE_COND(count_cond); -} - -static void -count_incr(void) -{ - EVLOCK_LOCK(count_lock, 0); - count++; - EVTHREAD_COND_BROADCAST(count_cond); - EVLOCK_UNLOCK(count_lock, 0); -} - -static int -count_wait_for(int i, int ms) -{ - struct timeval tv; - DWORD elapsed; - int rv = -1; - - EVLOCK_LOCK(count_lock, 0); - while (ms > 0 && count != i) { - tv.tv_sec = 0; - tv.tv_usec = ms * 1000; - elapsed = GetTickCount(); - EVTHREAD_COND_WAIT_TIMED(count_cond, count_lock, &tv); - elapsed = GetTickCount() - elapsed; - ms -= elapsed; - } - if (count == i) - rv = 0; - EVLOCK_UNLOCK(count_lock, 0); - - return rv; -} - -struct dummy_overlapped { - struct event_overlapped eo; - void *lock; - int call_count; - uintptr_t keys[MAX_CALLS]; - ev_ssize_t sizes[MAX_CALLS]; -}; - -static void -dummy_cb(struct event_overlapped *o, uintptr_t key, ev_ssize_t n, int ok) -{ - struct dummy_overlapped *d_o = - EVUTIL_UPCAST(o, struct dummy_overlapped, eo); - - EVLOCK_LOCK(d_o->lock, 0); - if (d_o->call_count < MAX_CALLS) { - d_o->keys[d_o->call_count] = key; - d_o->sizes[d_o->call_count] = n; - } - d_o->call_count++; - EVLOCK_UNLOCK(d_o->lock, 0); - - count_incr(); -} - -static int -pair_is_in(struct dummy_overlapped *o, uintptr_t key, ev_ssize_t n) -{ - int i; - int result = 0; - EVLOCK_LOCK(o->lock, 0); - for (i=0; i < o->call_count; ++i) { - if (o->keys[i] == key && o->sizes[i] == n) { - result = 1; - break; - } - } - EVLOCK_UNLOCK(o->lock, 0); - return result; -} - -static void -test_iocp_port(void *ptr) -{ - struct event_iocp_port *port = NULL; - struct dummy_overlapped o1, o2; - - memset(&o1, 0, sizeof(o1)); - memset(&o2, 0, sizeof(o2)); - - count_init(); - EVTHREAD_ALLOC_LOCK(o1.lock, EVTHREAD_LOCKTYPE_RECURSIVE); - EVTHREAD_ALLOC_LOCK(o2.lock, EVTHREAD_LOCKTYPE_RECURSIVE); - - tt_assert(o1.lock); - tt_assert(o2.lock); - - event_overlapped_init_(&o1.eo, dummy_cb); - event_overlapped_init_(&o2.eo, dummy_cb); - - port = event_iocp_port_launch_(0); - tt_assert(port); - - tt_assert(!event_iocp_activate_overlapped_(port, &o1.eo, 10, 100)); - tt_assert(!event_iocp_activate_overlapped_(port, &o2.eo, 20, 200)); - - tt_assert(!event_iocp_activate_overlapped_(port, &o1.eo, 11, 101)); - tt_assert(!event_iocp_activate_overlapped_(port, &o2.eo, 21, 201)); - - tt_assert(!event_iocp_activate_overlapped_(port, &o1.eo, 12, 102)); - tt_assert(!event_iocp_activate_overlapped_(port, &o2.eo, 22, 202)); - - tt_assert(!event_iocp_activate_overlapped_(port, &o1.eo, 13, 103)); - tt_assert(!event_iocp_activate_overlapped_(port, &o2.eo, 23, 203)); - - tt_int_op(count_wait_for(8, 2000), ==, 0); - - tt_want(!event_iocp_shutdown_(port, 2000)); - - tt_int_op(o1.call_count, ==, 4); - tt_int_op(o2.call_count, ==, 4); - - tt_want(pair_is_in(&o1, 10, 100)); - tt_want(pair_is_in(&o1, 11, 101)); - tt_want(pair_is_in(&o1, 12, 102)); - tt_want(pair_is_in(&o1, 13, 103)); - - tt_want(pair_is_in(&o2, 20, 200)); - tt_want(pair_is_in(&o2, 21, 201)); - tt_want(pair_is_in(&o2, 22, 202)); - tt_want(pair_is_in(&o2, 23, 203)); - -end: - EVTHREAD_FREE_LOCK(o1.lock, EVTHREAD_LOCKTYPE_RECURSIVE); - EVTHREAD_FREE_LOCK(o2.lock, EVTHREAD_LOCKTYPE_RECURSIVE); - count_free(); -} - -static struct evbuffer *rbuf = NULL, *wbuf = NULL; - -static void -read_complete(struct event_overlapped *eo, uintptr_t key, - ev_ssize_t nbytes, int ok) -{ - tt_assert(ok); - evbuffer_commit_read_(rbuf, nbytes); - count_incr(); -end: - ; -} - -static void -write_complete(struct event_overlapped *eo, uintptr_t key, - ev_ssize_t nbytes, int ok) -{ - tt_assert(ok); - evbuffer_commit_write_(wbuf, nbytes); - count_incr(); -end: - ; -} - -static void -test_iocp_evbuffer(void *ptr) -{ - struct event_overlapped rol, wol; - struct basic_test_data *data = ptr; - struct event_iocp_port *port = NULL; - struct evbuffer *buf=NULL; - struct evbuffer_chain *chain; - char junk[1024]; - int i; - - count_init(); - event_overlapped_init_(&rol, read_complete); - event_overlapped_init_(&wol, write_complete); - - for (i = 0; i < (int)sizeof(junk); ++i) - junk[i] = (char)(i); - - rbuf = evbuffer_overlapped_new_(data->pair[0]); - wbuf = evbuffer_overlapped_new_(data->pair[1]); - evbuffer_enable_locking(rbuf, NULL); - evbuffer_enable_locking(wbuf, NULL); - - port = event_iocp_port_launch_(0); - tt_assert(port); - tt_assert(rbuf); - tt_assert(wbuf); - - tt_assert(!event_iocp_port_associate_(port, data->pair[0], 100)); - tt_assert(!event_iocp_port_associate_(port, data->pair[1], 100)); - - for (i=0;i<10;++i) - evbuffer_add(wbuf, junk, sizeof(junk)); - - buf = evbuffer_new(); - tt_assert(buf != NULL); - evbuffer_add(rbuf, junk, sizeof(junk)); - tt_assert(!evbuffer_launch_read_(rbuf, 2048, &rol)); - evbuffer_add_buffer(buf, rbuf); - tt_int_op(evbuffer_get_length(buf), ==, sizeof(junk)); - for (chain = buf->first; chain; chain = chain->next) - tt_int_op(chain->flags & EVBUFFER_MEM_PINNED_ANY, ==, 0); - tt_assert(!evbuffer_get_length(rbuf)); - tt_assert(!evbuffer_launch_write_(wbuf, 512, &wol)); - - tt_int_op(count_wait_for(2, 2000), ==, 0); - - tt_int_op(evbuffer_get_length(rbuf),==,512); - - /* FIXME Actually test some stuff here. */ - - tt_want(!event_iocp_shutdown_(port, 2000)); -end: - count_free(); - evbuffer_free(rbuf); - evbuffer_free(wbuf); - if (buf) evbuffer_free(buf); -} - -static int got_readcb = 0; - -static void -async_readcb(struct bufferevent *bev, void *arg) -{ - /* Disabling read should cause the loop to quit */ - bufferevent_disable(bev, EV_READ); - got_readcb++; -} - -static void -test_iocp_bufferevent_async(void *ptr) -{ - struct basic_test_data *data = ptr; - struct event_iocp_port *port = NULL; - struct bufferevent *bea1=NULL, *bea2=NULL; - char buf[128]; - size_t n; - - event_base_start_iocp_(data->base, 0); - port = event_base_get_iocp_(data->base); - tt_assert(port); - - bea1 = bufferevent_async_new_(data->base, data->pair[0], - BEV_OPT_DEFER_CALLBACKS); - bea2 = bufferevent_async_new_(data->base, data->pair[1], - BEV_OPT_DEFER_CALLBACKS); - tt_assert(bea1); - tt_assert(bea2); - - bufferevent_setcb(bea2, async_readcb, NULL, NULL, NULL); - bufferevent_enable(bea1, EV_WRITE); - bufferevent_enable(bea2, EV_READ); - - bufferevent_write(bea1, "Hello world", strlen("Hello world")+1); - - event_base_dispatch(data->base); - - tt_int_op(got_readcb, ==, 1); - n = bufferevent_read(bea2, buf, sizeof(buf)-1); - buf[n]='\0'; - tt_str_op(buf, ==, "Hello world"); - -end: - bufferevent_free(bea1); - bufferevent_free(bea2); -} - - -struct testcase_t iocp_testcases[] = { - { "port", test_iocp_port, TT_FORK|TT_NEED_THREADS, &basic_setup, NULL }, - { "evbuffer", test_iocp_evbuffer, - TT_FORK|TT_NEED_SOCKETPAIR|TT_NEED_THREADS, - &basic_setup, NULL }, - { "bufferevent_async", test_iocp_bufferevent_async, - TT_FORK|TT_NEED_SOCKETPAIR|TT_NEED_THREADS|TT_NEED_BASE, - &basic_setup, NULL }, - END_OF_TESTCASES -}; diff --git a/protocols/Telegram/tgl/libevent/test/regress_iocp.obj b/protocols/Telegram/tgl/libevent/test/regress_iocp.obj Binary files differdeleted file mode 100644 index 5e2f0d2149..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress_iocp.obj +++ /dev/null diff --git a/protocols/Telegram/tgl/libevent/test/regress_listener.c b/protocols/Telegram/tgl/libevent/test/regress_listener.c deleted file mode 100644 index 4db102df68..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress_listener.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (c) 2009-2012 Niels Provos and Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "util-internal.h" - -#ifdef _WIN32 -#include <winsock2.h> -#include <windows.h> -#endif - -#include <sys/types.h> - -#ifndef _WIN32 -#include <sys/socket.h> -#include <netinet/in.h> -# ifdef _XOPEN_SOURCE_EXTENDED -# include <arpa/inet.h> -# endif -#include <unistd.h> -#endif - -#include <string.h> - -#include "event2/listener.h" -#include "event2/event.h" -#include "event2/util.h" - -#include "regress.h" -#include "tinytest.h" -#include "tinytest_macros.h" - -static void -acceptcb(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_disable(listener); -} - -static void -regress_pick_a_port(void *arg) -{ - struct basic_test_data *data = arg; - struct event_base *base = data->base; - struct evconnlistener *listener1 = NULL, *listener2 = NULL; - struct sockaddr_in sin; - int count1 = 2, count2 = 1; - struct sockaddr_storage ss1, ss2; - struct sockaddr_in *sin1, *sin2; - 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 = -1, fd2 = -1, fd3 = -1; - - if (data->setup_data && strstr((char*)data->setup_data, "ts")) { - flags |= LEV_OPT_THREADSAFE; - } - - 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!" */ - - listener1 = evconnlistener_new_bind(base, acceptcb, &count1, - flags, -1, (struct sockaddr *)&sin, sizeof(sin)); - tt_assert(listener1); - listener2 = evconnlistener_new_bind(base, acceptcb, &count2, - 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(getsockname(evconnlistener_get_fd(listener1), - (struct sockaddr*)&ss1, &slen1) == 0); - tt_assert(getsockname(evconnlistener_get_fd(listener2), - (struct sockaddr*)&ss2, &slen2) == 0); - tt_int_op(ss1.ss_family, ==, AF_INET); - tt_int_op(ss2.ss_family, ==, AF_INET); - - sin1 = (struct sockaddr_in*)&ss1; - sin2 = (struct sockaddr_in*)&ss2; - tt_int_op(ntohl(sin1->sin_addr.s_addr), ==, 0x7f000001); - tt_int_op(ntohl(sin2->sin_addr.s_addr), ==, 0x7f000001); - tt_int_op(sin1->sin_port, !=, sin2->sin_port); - - tt_ptr_op(evconnlistener_get_base(listener1), ==, base); - tt_ptr_op(evconnlistener_get_base(listener2), ==, base); - - fd1 = fd2 = fd3 = -1; - evutil_socket_connect_(&fd1, (struct sockaddr*)&ss1, slen1); - evutil_socket_connect_(&fd2, (struct sockaddr*)&ss1, slen1); - evutil_socket_connect_(&fd3, (struct sockaddr*)&ss2, slen2); - -#ifdef _WIN32 - Sleep(100); /* XXXX this is a stupid stopgap. */ -#endif - event_base_dispatch(base); - - tt_int_op(count1, ==, 0); - tt_int_op(count2, ==, 0); - -end: - if (fd1>=0) - EVUTIL_CLOSESOCKET(fd1); - if (fd2>=0) - EVUTIL_CLOSESOCKET(fd2); - if (fd3>=0) - EVUTIL_CLOSESOCKET(fd3); - if (listener1) - evconnlistener_free(listener1); - if (listener2) - evconnlistener_free(listener2); -} - -static void -errorcb(struct evconnlistener *lis, void *data_) -{ - int *data = data_; - *data = 1000; - evconnlistener_disable(lis); -} - -static void -regress_listener_error(void *arg) -{ - struct basic_test_data *data = arg; - struct event_base *base = data->base; - struct evconnlistener *listener = NULL; - int count = 1; - unsigned int flags = LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE; - - if (data->setup_data && strstr((char*)data->setup_data, "ts")) { - flags |= LEV_OPT_THREADSAFE; - } - - /* send, so that pair[0] will look 'readable'*/ - tt_int_op(send(data->pair[1], "hello", 5, 0), >, 0); - - /* Start a listener with a bogus socket. */ - listener = evconnlistener_new(base, acceptcb, &count, - flags, 0, - data->pair[0]); - tt_assert(listener); - - evconnlistener_set_error_cb(listener, errorcb); - - tt_assert(listener); - - event_base_dispatch(base); - tt_int_op(count,==,1000); /* set by error cb */ - -end: - if (listener) - evconnlistener_free(listener); -} - -struct testcase_t listener_testcases[] = { - - { "randport", regress_pick_a_port, TT_FORK|TT_NEED_BASE, - &basic_setup, NULL}, - - { "randport_ts", regress_pick_a_port, TT_FORK|TT_NEED_BASE, - &basic_setup, (char*)"ts"}, - - { "error", regress_listener_error, - TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR, - &basic_setup, NULL}, - - { "error_ts", regress_listener_error, - TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR, - &basic_setup, (char*)"ts"}, - - END_OF_TESTCASES, -}; - -struct testcase_t listener_iocp_testcases[] = { - { "randport", regress_pick_a_port, - TT_FORK|TT_NEED_BASE|TT_ENABLE_IOCP, - &basic_setup, NULL}, - - { "error", regress_listener_error, - TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR|TT_ENABLE_IOCP, - &basic_setup, NULL}, - - END_OF_TESTCASES, -}; diff --git a/protocols/Telegram/tgl/libevent/test/regress_listener.obj b/protocols/Telegram/tgl/libevent/test/regress_listener.obj Binary files differdeleted file mode 100644 index b05b290d36..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress_listener.obj +++ /dev/null diff --git a/protocols/Telegram/tgl/libevent/test/regress_main.c b/protocols/Telegram/tgl/libevent/test/regress_main.c deleted file mode 100644 index 6d045bb833..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress_main.c +++ /dev/null @@ -1,468 +0,0 @@ -/* - * Copyright (c) 2003-2007 Niels Provos <provos@citi.umich.edu> - * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "util-internal.h" - -#ifdef _WIN32 -#include <winsock2.h> -#include <windows.h> -#include <io.h> -#include <fcntl.h> -#endif - -#if defined(__APPLE__) && defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) -#if (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1060 && \ - __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070) -#define FORK_BREAKS_GCOV -#include <vproc.h> -#endif -#endif - -#include "event2/event-config.h" - -#ifdef EVENT____func__ -#define __func__ EVENT____func__ -#endif - -#if 0 -#include <sys/types.h> -#include <sys/stat.h> -#ifdef EVENT__HAVE_SYS_TIME_H -#include <sys/time.h> -#endif -#include <sys/queue.h> -#include <signal.h> -#include <errno.h> -#endif - -#include <sys/types.h> -#ifdef EVENT__HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif - -#ifndef _WIN32 -#include <sys/socket.h> -#include <sys/wait.h> -#include <signal.h> -#include <unistd.h> -#include <netdb.h> -#endif - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <assert.h> - -#include "event2/util.h" -#include "event2/event.h" -#include "event2/event_compat.h" -#include "event2/dns.h" -#include "event2/dns_compat.h" -#include "event2/thread.h" - -#include "event2/event-config.h" -#include "regress.h" -#include "tinytest.h" -#include "tinytest_macros.h" -#include "../iocp-internal.h" -#include "../event-internal.h" - -struct evutil_weakrand_state test_weakrand_state; - -long -timeval_msec_diff(const struct timeval *start, const struct timeval *end) -{ - long ms = end->tv_sec - start->tv_sec; - ms *= 1000; - ms += ((end->tv_usec - start->tv_usec)+500) / 1000; - return ms; -} - -/* ============================================================ */ -/* Code to wrap up old legacy test cases that used setup() and cleanup(). - * - * Not all of the tests designated "legacy" are ones that used setup() and - * cleanup(), of course. A test is legacy it it uses setup()/cleanup(), OR - * if it wants to find its event base/socketpair in global variables (ugh), - * OR if it wants to communicate success/failure through test_ok. - */ - -/* This is set to true if we're inside a legacy test wrapper. It lets the - setup() and cleanup() functions in regress.c know they're not needed. - */ -int in_legacy_test_wrapper = 0; - -static void dnslogcb(int w, const char *m) -{ - TT_BLATHER(("%s", m)); -} - -/* creates a temporary file with the data in it. If *filename_out gets set, - * the caller should try to unlink it. */ -int -regress_make_tmpfile(const void *data, size_t datalen, char **filename_out) -{ -#ifndef _WIN32 - char tmpfilename[32]; - int fd; - *filename_out = NULL; - strcpy(tmpfilename, "/tmp/eventtmp.XXXXXX"); -#ifdef EVENT__HAVE_UMASK - umask(0077); -#endif - fd = mkstemp(tmpfilename); - if (fd == -1) - return (-1); - if (write(fd, data, datalen) != (int)datalen) { - close(fd); - return (-1); - } - lseek(fd, 0, SEEK_SET); - /* remove it from the file system */ - unlink(tmpfilename); - return (fd); -#else - /* XXXX actually delete the file later */ - char tmpfilepath[MAX_PATH]; - char tmpfilename[MAX_PATH]; - DWORD r, written; - int tries = 16; - HANDLE h; - r = GetTempPathA(MAX_PATH, tmpfilepath); - if (r > MAX_PATH || r == 0) - return (-1); - for (; tries > 0; --tries) { - r = GetTempFileNameA(tmpfilepath, "LIBEVENT", 0, tmpfilename); - if (r == 0) - return (-1); - h = CreateFileA(tmpfilename, GENERIC_READ|GENERIC_WRITE, - 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (h != INVALID_HANDLE_VALUE) - break; - } - if (tries == 0) - return (-1); - written = 0; - *filename_out = strdup(tmpfilename); - WriteFile(h, data, (DWORD)datalen, &written, NULL); - /* Closing the fd returned by this function will indeed close h. */ - return _open_osfhandle((intptr_t)h,_O_RDONLY); -#endif -} - -#ifndef _WIN32 -pid_t -regress_fork(void) -{ - pid_t pid = fork(); -#ifdef FORK_BREAKS_GCOV - vproc_transaction_begin(0); -#endif - return pid; -} -#endif - -static void -ignore_log_cb(int s, const char *msg) -{ -} - -static void * -basic_test_setup(const struct testcase_t *testcase) -{ - struct event_base *base = NULL; - evutil_socket_t spair[2] = { -1, -1 }; - struct basic_test_data *data = NULL; - -#ifndef _WIN32 - if (testcase->flags & TT_ENABLE_IOCP_FLAG) - return (void*)TT_SKIP; -#endif - - if (testcase->flags & TT_NEED_THREADS) { - if (!(testcase->flags & TT_FORK)) - return NULL; -#if defined(EVTHREAD_USE_PTHREADS_IMPLEMENTED) - if (evthread_use_pthreads()) - exit(1); -#elif defined(EVTHREAD_USE_WINDOWS_THREADS_IMPLEMENTED) - if (evthread_use_windows_threads()) - exit(1); -#else - return (void*)TT_SKIP; -#endif - } - - if (testcase->flags & TT_NEED_SOCKETPAIR) { - if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, spair) == -1) { - fprintf(stderr, "%s: socketpair\n", __func__); - exit(1); - } - - if (evutil_make_socket_nonblocking(spair[0]) == -1) { - fprintf(stderr, "fcntl(O_NONBLOCK)"); - exit(1); - } - - if (evutil_make_socket_nonblocking(spair[1]) == -1) { - fprintf(stderr, "fcntl(O_NONBLOCK)"); - exit(1); - } - } - if (testcase->flags & TT_NEED_BASE) { - if (testcase->flags & TT_LEGACY) - base = event_init(); - else - base = event_base_new(); - if (!base) - exit(1); - } - if (testcase->flags & TT_ENABLE_IOCP_FLAG) { - if (event_base_start_iocp_(base, 0)<0) { - event_base_free(base); - return (void*)TT_SKIP; - } - } - - if (testcase->flags & TT_NEED_DNS) { - evdns_set_log_fn(dnslogcb); - if (evdns_init()) - return NULL; /* fast failure */ /*XXX asserts. */ - } - - if (testcase->flags & TT_NO_LOGS) - event_set_log_callback(ignore_log_cb); - - data = calloc(1, sizeof(*data)); - if (!data) - exit(1); - data->base = base; - data->pair[0] = spair[0]; - data->pair[1] = spair[1]; - data->setup_data = testcase->setup_data; - return data; -} - -static int -basic_test_cleanup(const struct testcase_t *testcase, void *ptr) -{ - struct basic_test_data *data = ptr; - - if (testcase->flags & TT_NO_LOGS) - event_set_log_callback(NULL); - - if (testcase->flags & TT_NEED_SOCKETPAIR) { - if (data->pair[0] != -1) - evutil_closesocket(data->pair[0]); - if (data->pair[1] != -1) - evutil_closesocket(data->pair[1]); - } - - if (testcase->flags & TT_NEED_DNS) { - evdns_shutdown(0); - } - - if (testcase->flags & TT_NEED_BASE) { - if (data->base) { - event_base_assert_ok_(data->base); - event_base_free(data->base); - } - } - - if (testcase->flags & TT_FORK) - libevent_global_shutdown(); - - free(data); - - return 1; -} - -const struct testcase_setup_t basic_setup = { - basic_test_setup, basic_test_cleanup -}; - -/* The "data" for a legacy test is just a pointer to the void fn(void) - function implementing the test case. We need to set up some globals, - though, since that's where legacy tests expect to find a socketpair - (sometimes) and a global event_base (sometimes). - */ -static void * -legacy_test_setup(const struct testcase_t *testcase) -{ - struct basic_test_data *data = basic_test_setup(testcase); - if (data == (void*)TT_SKIP || data == NULL) - return data; - global_base = data->base; - pair[0] = data->pair[0]; - pair[1] = data->pair[1]; - data->legacy_test_fn = testcase->setup_data; - return data; -} - -/* This function is the implementation of every legacy test case. It - sets test_ok to 0, invokes the test function, and tells tinytest that - the test failed if the test didn't set test_ok to 1. - */ -void -run_legacy_test_fn(void *ptr) -{ - struct basic_test_data *data = ptr; - test_ok = called = 0; - - in_legacy_test_wrapper = 1; - data->legacy_test_fn(); /* This part actually calls the test */ - in_legacy_test_wrapper = 0; - - if (!test_ok) - tt_abort_msg("Legacy unit test failed"); - -end: - test_ok = 0; -} - -/* This function doesn't have to clean up ptr (which is just a pointer - to the test function), but it may need to close the socketpair or - free the event_base. - */ -static int -legacy_test_cleanup(const struct testcase_t *testcase, void *ptr) -{ - int r = basic_test_cleanup(testcase, ptr); - pair[0] = pair[1] = -1; - global_base = NULL; - return r; -} - -const struct testcase_setup_t legacy_setup = { - legacy_test_setup, legacy_test_cleanup -}; - -/* ============================================================ */ - -#if (!defined(EVENT__HAVE_PTHREADS) && !defined(_WIN32)) || defined(EVENT__DISABLE_THREAD_SUPPORT) -struct testcase_t thread_testcases[] = { - { "basic", NULL, TT_SKIP, NULL, NULL }, - END_OF_TESTCASES -}; -#endif - -struct testgroup_t testgroups[] = { - { "main/", main_testcases }, - { "heap/", minheap_testcases }, - { "et/", edgetriggered_testcases }, - { "finalize/", finalize_testcases }, - { "evbuffer/", evbuffer_testcases }, - { "signal/", signal_testcases }, - { "util/", util_testcases }, - { "bufferevent/", bufferevent_testcases }, - { "http/", http_testcases }, - { "dns/", dns_testcases }, - { "evtag/", evtag_testcases }, - { "rpc/", rpc_testcases }, - { "thread/", thread_testcases }, - { "listener/", listener_testcases }, -#ifdef _WIN32 - { "iocp/", iocp_testcases }, - { "iocp/bufferevent/", bufferevent_iocp_testcases }, - { "iocp/listener/", listener_iocp_testcases }, -#endif -#ifdef EVENT__HAVE_OPENSSL - { "ssl/", ssl_testcases }, -#endif - END_OF_GROUPS -}; - -const char *alltests[] = { "+..", NULL }; -const char *livenettests[] = { - "+util/getaddrinfo_live", - "+dns/gethostby..", - "+dns/resolve_reverse", - NULL -}; -const char *finetimetests[] = { - "+util/monotonic_res_precise", - "+util/monotonic_res_fallback", - "+thread/deferred_cb_skew", - "+http/connection_retry", - "+http/https_connection_retry", - NULL -}; -struct testlist_alias_t testaliases[] = { - { "all", alltests }, - { "live_net", livenettests }, - { "fine_timing", finetimetests }, - END_OF_ALIASES -}; - -int libevent_tests_running_in_debug_mode = 0; - -int -main(int argc, const char **argv) -{ -#ifdef _WIN32 - WORD wVersionRequested; - WSADATA wsaData; - - wVersionRequested = MAKEWORD(2, 2); - - (void) WSAStartup(wVersionRequested, &wsaData); -#endif - -#ifndef _WIN32 - if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) - return 1; -#endif - -#ifdef _WIN32 - tinytest_skip(testgroups, "http/connection_retry"); - tinytest_skip(testgroups, "http/https_connection_retry"); -#endif - -#ifndef EVENT__DISABLE_THREAD_SUPPORT - if (!getenv("EVENT_NO_DEBUG_LOCKS")) - evthread_enable_lock_debugging(); -#endif - - if (getenv("EVENT_DEBUG_MODE")) { - event_enable_debug_mode(); - libevent_tests_running_in_debug_mode = 1; - } - if (getenv("EVENT_DEBUG_LOGGING_ALL")) { - event_enable_debug_logging(EVENT_DBG_ALL); - } - - tinytest_set_aliases(testaliases); - - evutil_weakrand_seed_(&test_weakrand_state, 0); - - if (tinytest_main(argc,argv,testgroups)) - return 1; - - libevent_global_shutdown(); - - return 0; -} - diff --git a/protocols/Telegram/tgl/libevent/test/regress_main.obj b/protocols/Telegram/tgl/libevent/test/regress_main.obj Binary files differdeleted file mode 100644 index 27aaa4eb28..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress_main.obj +++ /dev/null diff --git a/protocols/Telegram/tgl/libevent/test/regress_minheap.c b/protocols/Telegram/tgl/libevent/test/regress_minheap.c deleted file mode 100644 index 05db32e26f..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress_minheap.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2009-2012 Niels Provos and Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "../minheap-internal.h" - -#include <stdlib.h> -#include "event2/event_struct.h" - -#include "tinytest.h" -#include "tinytest_macros.h" -#include "regress.h" - -static void -set_random_timeout(struct event *ev) -{ - ev->ev_timeout.tv_sec = test_weakrand(); - ev->ev_timeout.tv_usec = test_weakrand() & 0xfffff; - ev->ev_timeout_pos.min_heap_idx = -1; -} - -static void -check_heap(struct min_heap *heap) -{ - unsigned i; - for (i = 1; i < heap->n; ++i) { - unsigned parent_idx = (i-1)/2; - tt_want(evutil_timercmp(&heap->p[i]->ev_timeout, - &heap->p[parent_idx]->ev_timeout, >=)); - } -} - -static void -test_heap_randomized(void *ptr) -{ - struct min_heap heap; - struct event *inserted[1024]; - struct event *e, *last_e; - int i; - - min_heap_ctor_(&heap); - - for (i = 0; i < 1024; ++i) { - inserted[i] = malloc(sizeof(struct event)); - set_random_timeout(inserted[i]); - min_heap_push_(&heap, inserted[i]); - } - check_heap(&heap); - - tt_assert(min_heap_size_(&heap) == 1024); - - for (i = 0; i < 512; ++i) { - min_heap_erase_(&heap, inserted[i]); - if (0 == (i % 32)) - check_heap(&heap); - } - tt_assert(min_heap_size_(&heap) == 512); - - last_e = min_heap_pop_(&heap); - while (1) { - e = min_heap_pop_(&heap); - if (!e) - break; - tt_want(evutil_timercmp(&last_e->ev_timeout, - &e->ev_timeout, <=)); - } - tt_assert(min_heap_size_(&heap) == 0); -end: - for (i = 0; i < 1024; ++i) - free(inserted[i]); - - min_heap_dtor_(&heap); -} - -struct testcase_t minheap_testcases[] = { - { "randomized", test_heap_randomized, 0, NULL, NULL }, - END_OF_TESTCASES -}; diff --git a/protocols/Telegram/tgl/libevent/test/regress_minheap.obj b/protocols/Telegram/tgl/libevent/test/regress_minheap.obj Binary files differdeleted file mode 100644 index 0ab530f4fa..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress_minheap.obj +++ /dev/null diff --git a/protocols/Telegram/tgl/libevent/test/regress_rpc.c b/protocols/Telegram/tgl/libevent/test/regress_rpc.c deleted file mode 100644 index 01a058cbb2..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress_rpc.c +++ /dev/null @@ -1,905 +0,0 @@ -/* - * Copyright (c) 2003-2007 Niels Provos <provos@citi.umich.edu> - * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* The old tests here need assertions to work. */ -#undef NDEBUG - -#ifdef _WIN32 -#include <winsock2.h> -#include <windows.h> -#endif - -#include "event2/event-config.h" - -#include <sys/types.h> -#include <sys/stat.h> -#ifdef EVENT__HAVE_SYS_TIME_H -#include <sys/time.h> -#endif -#include <sys/queue.h> -#ifndef _WIN32 -#include <sys/socket.h> -#include <signal.h> -#include <unistd.h> -#include <netdb.h> -#endif -#include <fcntl.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#include "event2/buffer.h" -#include "event2/event.h" -#include "event2/event_compat.h" -#include "event2/http.h" -#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" - -#include "regress.gen.h" - -#include "regress.h" -#include "regress_testutils.h" - -#ifndef NO_PYTHON_EXISTS - -static struct evhttp * -http_setup(ev_uint16_t *pport) -{ - struct evhttp *myhttp; - ev_uint16_t port; - struct evhttp_bound_socket *sock; - - myhttp = evhttp_new(NULL); - if (!myhttp) - event_errx(1, "Could not start web server"); - - /* Try a few different ports */ - sock = evhttp_bind_socket_with_handle(myhttp, "127.0.0.1", 0); - if (!sock) - event_errx(1, "Couldn't open web port"); - - port = regress_get_socket_port(evhttp_bound_socket_get_fd(sock)); - - *pport = port; - return (myhttp); -} - -EVRPC_HEADER(Message, msg, kill) -EVRPC_HEADER(NeverReply, msg, kill) - -EVRPC_GENERATE(Message, msg, kill) -EVRPC_GENERATE(NeverReply, msg, kill) - -static int need_input_hook = 0; -static int need_output_hook = 0; - -static void -MessageCb(EVRPC_STRUCT(Message)* rpc, void *arg) -{ - struct kill* kill_reply = rpc->reply; - - if (need_input_hook) { - struct evhttp_request* req = EVRPC_REQUEST_HTTP(rpc); - const char *header = evhttp_find_header( - req->input_headers, "X-Hook"); - assert(header); - assert(strcmp(header, "input") == 0); - } - - /* we just want to fill in some non-sense */ - EVTAG_ASSIGN(kill_reply, weapon, "dagger"); - EVTAG_ASSIGN(kill_reply, action, "wave around like an idiot"); - - /* no reply to the RPC */ - EVRPC_REQUEST_DONE(rpc); -} - -static EVRPC_STRUCT(NeverReply) *saved_rpc; - -static void -NeverReplyCb(EVRPC_STRUCT(NeverReply)* rpc, void *arg) -{ - test_ok += 1; - saved_rpc = rpc; -} - -static void -rpc_setup(struct evhttp **phttp, ev_uint16_t *pport, struct evrpc_base **pbase) -{ - ev_uint16_t port; - struct evhttp *http = NULL; - struct evrpc_base *base = NULL; - - http = http_setup(&port); - base = evrpc_init(http); - - EVRPC_REGISTER(base, Message, msg, kill, MessageCb, NULL); - EVRPC_REGISTER(base, NeverReply, msg, kill, NeverReplyCb, NULL); - - *phttp = http; - *pport = port; - *pbase = base; - - need_input_hook = 0; - need_output_hook = 0; -} - -static void -rpc_teardown(struct evrpc_base *base) -{ - assert(EVRPC_UNREGISTER(base, Message) == 0); - assert(EVRPC_UNREGISTER(base, NeverReply) == 0); - - evrpc_free(base); -} - -static void -rpc_postrequest_failure(struct evhttp_request *req, void *arg) -{ - if (req->response_code != HTTP_SERVUNAVAIL) { - - fprintf(stderr, "FAILED (response code)\n"); - exit(1); - } - - test_ok = 1; - event_loopexit(NULL); -} - -/* - * Test a malformed payload submitted as an RPC - */ - -static void -rpc_basic_test(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_POST, - "/.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); -} - -static void -rpc_postrequest_done(struct evhttp_request *req, void *arg) -{ - struct kill* kill_reply = NULL; - - if (req->response_code != HTTP_OK) { - fprintf(stderr, "FAILED (response code)\n"); - exit(1); - } - - kill_reply = kill_new(); - - if ((kill_unmarshal(kill_reply, req->input_buffer)) == -1) { - fprintf(stderr, "FAILED (unmarshal)\n"); - exit(1); - } - - kill_free(kill_reply); - - test_ok = 1; - event_loopexit(NULL); -} - -static void -rpc_basic_message(void) -{ - ev_uint16_t port; - struct evhttp *http = NULL; - struct evrpc_base *base = NULL; - struct evhttp_connection *evcon = NULL; - struct evhttp_request *req = NULL; - struct msg *msg; - - 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_done, NULL); - if (req == NULL) { - fprintf(stdout, "FAILED\n"); - exit(1); - } - - /* Add the information that we care about */ - evhttp_add_header(req->output_headers, "Host", "somehost"); - - /* set up the basic message */ - msg = msg_new(); - EVTAG_ASSIGN(msg, from_name, "niels"); - EVTAG_ASSIGN(msg, to_name, "tester"); - msg_marshal(req->output_buffer, msg); - msg_free(msg); - - if (evhttp_make_request(evcon, req, - EVHTTP_REQ_POST, - "/.rpc.Message") == -1) { - fprintf(stdout, "FAILED\n"); - exit(1); - } - - test_ok = 0; - - event_dispatch(); - - evhttp_connection_free(evcon); - - rpc_teardown(base); - -end: - evhttp_free(http); -} - -static struct evrpc_pool * -rpc_pool_with_connection(ev_uint16_t port) -{ - struct evhttp_connection *evcon; - struct evrpc_pool *pool; - - pool = evrpc_pool_new(NULL); - assert(pool != NULL); - - evcon = evhttp_connection_new("127.0.0.1", port); - assert(evcon != NULL); - - evrpc_pool_add_connection(pool, evcon); - - return (pool); -} - -static void -GotKillCb(struct evrpc_status *status, - struct msg *msg, struct kill *kill, void *arg) -{ - char *weapon; - char *action; - - if (need_output_hook) { - struct evhttp_request *req = status->http_req; - const char *header = evhttp_find_header( - req->input_headers, "X-Pool-Hook"); - assert(header); - assert(strcmp(header, "ran") == 0); - } - - if (status->error != EVRPC_STATUS_ERR_NONE) - goto done; - - if (EVTAG_GET(kill, weapon, &weapon) == -1) { - fprintf(stderr, "get weapon\n"); - goto done; - } - if (EVTAG_GET(kill, action, &action) == -1) { - fprintf(stderr, "get action\n"); - goto done; - } - - if (strcmp(weapon, "dagger")) - goto done; - - if (strcmp(action, "wave around like an idiot")) - goto done; - - test_ok += 1; - -done: - event_loopexit(NULL); -} - -static void -GotKillCbTwo(struct evrpc_status *status, - struct msg *msg, struct kill *kill, void *arg) -{ - char *weapon; - char *action; - - if (status->error != EVRPC_STATUS_ERR_NONE) - goto done; - - if (EVTAG_GET(kill, weapon, &weapon) == -1) { - fprintf(stderr, "get weapon\n"); - goto done; - } - if (EVTAG_GET(kill, action, &action) == -1) { - fprintf(stderr, "get action\n"); - goto done; - } - - if (strcmp(weapon, "dagger")) - goto done; - - if (strcmp(action, "wave around like an idiot")) - goto done; - - test_ok += 1; - -done: - if (test_ok == 2) - event_loopexit(NULL); -} - -static int -rpc_hook_add_header(void *ctx, struct evhttp_request *req, - struct evbuffer *evbuf, void *arg) -{ - const char *hook_type = arg; - if (strcmp("input", hook_type) == 0) - evhttp_add_header(req->input_headers, "X-Hook", hook_type); - else - evhttp_add_header(req->output_headers, "X-Hook", hook_type); - - assert(evrpc_hook_get_connection(ctx) != NULL); - - return (EVRPC_CONTINUE); -} - -static int -rpc_hook_add_meta(void *ctx, struct evhttp_request *req, - struct evbuffer *evbuf, void *arg) -{ - evrpc_hook_add_meta(ctx, "meta", "test", 5); - - assert(evrpc_hook_get_connection(ctx) != NULL); - - return (EVRPC_CONTINUE); -} - -static int -rpc_hook_remove_header(void *ctx, struct evhttp_request *req, - struct evbuffer *evbuf, void *arg) -{ - const char *header = evhttp_find_header(req->input_headers, "X-Hook"); - void *data = NULL; - size_t data_len = 0; - - assert(header != NULL); - assert(strcmp(header, arg) == 0); - - evhttp_remove_header(req->input_headers, "X-Hook"); - evhttp_add_header(req->input_headers, "X-Pool-Hook", "ran"); - - assert(evrpc_hook_find_meta(ctx, "meta", &data, &data_len) == 0); - assert(data != NULL); - assert(data_len == 5); - - assert(evrpc_hook_get_connection(ctx) != NULL); - - return (EVRPC_CONTINUE); -} - -static void -rpc_basic_client(void) -{ - ev_uint16_t port; - struct evhttp *http = NULL; - struct evrpc_base *base = NULL; - struct evrpc_pool *pool = NULL; - struct msg *msg = NULL; - struct kill *kill = NULL; - - rpc_setup(&http, &port, &base); - - need_input_hook = 1; - need_output_hook = 1; - - assert(evrpc_add_hook(base, EVRPC_INPUT, rpc_hook_add_header, (void*)"input") - != NULL); - assert(evrpc_add_hook(base, EVRPC_OUTPUT, rpc_hook_add_header, (void*)"output") - != NULL); - - pool = rpc_pool_with_connection(port); - tt_assert(pool); - - assert(evrpc_add_hook(pool, EVRPC_OUTPUT, rpc_hook_add_meta, NULL)); - assert(evrpc_add_hook(pool, EVRPC_INPUT, rpc_hook_remove_header, (void*)"output")); - - /* set up the basic message */ - msg = msg_new(); - tt_assert(msg); - EVTAG_ASSIGN(msg, from_name, "niels"); - EVTAG_ASSIGN(msg, to_name, "tester"); - - kill = kill_new(); - - EVRPC_MAKE_REQUEST(Message, pool, msg, kill, GotKillCb, NULL); - - test_ok = 0; - - event_dispatch(); - - tt_assert(test_ok == 1); - - /* we do it twice to make sure that reuse works correctly */ - kill_clear(kill); - - EVRPC_MAKE_REQUEST(Message, pool, msg, kill, GotKillCb, NULL); - - event_dispatch(); - - tt_assert(test_ok == 2); - - /* we do it trice to make sure other stuff works, too */ - kill_clear(kill); - - { - struct evrpc_request_wrapper *ctx = - EVRPC_MAKE_CTX(Message, msg, kill, - pool, msg, kill, GotKillCb, NULL); - evrpc_make_request(ctx); - } - - event_dispatch(); - - rpc_teardown(base); - - tt_assert(test_ok == 3); - -end: - if (msg) - msg_free(msg); - if (kill) - kill_free(kill); - - if (pool) - evrpc_pool_free(pool); - if (http) - evhttp_free(http); - - need_input_hook = 0; - need_output_hook = 0; -} - -/* - * We are testing that the second requests gets send over the same - * connection after the first RPCs completes. - */ -static void -rpc_basic_queued_client(void) -{ - ev_uint16_t port; - struct evhttp *http = NULL; - struct evrpc_base *base = NULL; - struct evrpc_pool *pool = NULL; - struct msg *msg=NULL; - struct kill *kill_one=NULL, *kill_two=NULL; - - rpc_setup(&http, &port, &base); - - pool = rpc_pool_with_connection(port); - tt_assert(pool); - - /* set up the basic message */ - msg = msg_new(); - tt_assert(msg); - EVTAG_ASSIGN(msg, from_name, "niels"); - EVTAG_ASSIGN(msg, to_name, "tester"); - - kill_one = kill_new(); - kill_two = kill_new(); - - EVRPC_MAKE_REQUEST(Message, pool, msg, kill_one, GotKillCbTwo, NULL); - EVRPC_MAKE_REQUEST(Message, pool, msg, kill_two, GotKillCb, NULL); - - test_ok = 0; - - event_dispatch(); - - rpc_teardown(base); - - tt_assert(test_ok == 2); - -end: - if (msg) - msg_free(msg); - if (kill_one) - kill_free(kill_one); - if (kill_two) - kill_free(kill_two); - - if (pool) - evrpc_pool_free(pool); - if (http) - evhttp_free(http); -} - -static void -GotErrorCb(struct evrpc_status *status, - struct msg *msg, struct kill *kill, void *arg) -{ - if (status->error != EVRPC_STATUS_ERR_TIMEOUT) - goto done; - - /* should never be complete but just to check */ - if (kill_complete(kill) == 0) - goto done; - - test_ok += 1; - -done: - event_loopexit(NULL); -} - -/* we just pause the rpc and continue it in the next callback */ - -struct rpc_hook_ctx_ { - void *vbase; - void *ctx; -}; - -static int hook_pause_cb_called=0; - -static void -rpc_hook_pause_cb(evutil_socket_t fd, short what, void *arg) -{ - struct rpc_hook_ctx_ *ctx = arg; - ++hook_pause_cb_called; - evrpc_resume_request(ctx->vbase, ctx->ctx, EVRPC_CONTINUE); - free(arg); -} - -static int -rpc_hook_pause(void *ctx, struct evhttp_request *req, struct evbuffer *evbuf, - void *arg) -{ - struct rpc_hook_ctx_ *tmp = malloc(sizeof(*tmp)); - struct timeval tv; - - assert(tmp != NULL); - tmp->vbase = arg; - tmp->ctx = ctx; - - memset(&tv, 0, sizeof(tv)); - event_once(-1, EV_TIMEOUT, rpc_hook_pause_cb, tmp, &tv); - return EVRPC_PAUSE; -} - -static void -rpc_basic_client_with_pause(void) -{ - ev_uint16_t port; - struct evhttp *http = NULL; - struct evrpc_base *base = NULL; - struct evrpc_pool *pool = NULL; - struct msg *msg = NULL; - struct kill *kill= NULL; - - rpc_setup(&http, &port, &base); - - assert(evrpc_add_hook(base, EVRPC_INPUT, rpc_hook_pause, base)); - assert(evrpc_add_hook(base, EVRPC_OUTPUT, rpc_hook_pause, base)); - - pool = rpc_pool_with_connection(port); - tt_assert(pool); - assert(evrpc_add_hook(pool, EVRPC_INPUT, rpc_hook_pause, pool)); - assert(evrpc_add_hook(pool, EVRPC_OUTPUT, rpc_hook_pause, pool)); - - /* set up the basic message */ - msg = msg_new(); - tt_assert(msg); - EVTAG_ASSIGN(msg, from_name, "niels"); - EVTAG_ASSIGN(msg, to_name, "tester"); - - kill = kill_new(); - - EVRPC_MAKE_REQUEST(Message, pool, msg, kill, GotKillCb, NULL); - - test_ok = 0; - - event_dispatch(); - - tt_int_op(test_ok, ==, 1); - tt_int_op(hook_pause_cb_called, ==, 4); - -end: - if (base) - rpc_teardown(base); - - if (msg) - msg_free(msg); - if (kill) - kill_free(kill); - - if (pool) - evrpc_pool_free(pool); - if (http) - evhttp_free(http); -} - -static void -rpc_client_timeout(void) -{ - ev_uint16_t port; - struct evhttp *http = NULL; - struct evrpc_base *base = NULL; - struct evrpc_pool *pool = NULL; - struct msg *msg = NULL; - struct kill *kill = NULL; - - rpc_setup(&http, &port, &base); - - pool = rpc_pool_with_connection(port); - tt_assert(pool); - - /* set the timeout to 1 second. */ - evrpc_pool_set_timeout(pool, 1); - - /* set up the basic message */ - msg = msg_new(); - tt_assert(msg); - EVTAG_ASSIGN(msg, from_name, "niels"); - EVTAG_ASSIGN(msg, to_name, "tester"); - - kill = kill_new(); - - EVRPC_MAKE_REQUEST(NeverReply, pool, msg, kill, GotErrorCb, NULL); - - test_ok = 0; - - event_dispatch(); - - /* free the saved RPC structure up */ - EVRPC_REQUEST_DONE(saved_rpc); - - rpc_teardown(base); - - tt_assert(test_ok == 2); - -end: - if (msg) - msg_free(msg); - if (kill) - kill_free(kill); - - if (pool) - evrpc_pool_free(pool); - if (http) - evhttp_free(http); -} - -static void -rpc_test(void) -{ - struct msg *msg = NULL, *msg2 = NULL; - struct kill *attack = NULL; - struct run *run = NULL; - struct evbuffer *tmp = evbuffer_new(); - struct timeval tv_start, tv_end; - ev_uint32_t tag; - int i; - - msg = msg_new(); - - tt_assert(msg); - - EVTAG_ASSIGN(msg, from_name, "niels"); - EVTAG_ASSIGN(msg, to_name, "phoenix"); - - if (EVTAG_GET(msg, attack, &attack) == -1) { - tt_abort_msg("Failed to set kill message."); - } - - EVTAG_ASSIGN(attack, weapon, "feather"); - EVTAG_ASSIGN(attack, action, "tickle"); - for (i = 0; i < 3; ++i) { - if (EVTAG_ARRAY_ADD_VALUE(attack, how_often, i) == NULL) { - tt_abort_msg("Failed to add how_often."); - } - } - - evutil_gettimeofday(&tv_start, NULL); - for (i = 0; i < 1000; ++i) { - run = EVTAG_ARRAY_ADD(msg, run); - if (run == NULL) { - tt_abort_msg("Failed to add run message."); - } - EVTAG_ASSIGN(run, how, "very fast but with some data in it"); - EVTAG_ASSIGN(run, fixed_bytes, - (ev_uint8_t*)"012345678901234567890123"); - - if (EVTAG_ARRAY_ADD_VALUE( - run, notes, "this is my note") == NULL) { - tt_abort_msg("Failed to add note."); - } - if (EVTAG_ARRAY_ADD_VALUE(run, notes, "pps") == NULL) { - tt_abort_msg("Failed to add note"); - } - - EVTAG_ASSIGN(run, large_number, 0xdead0a0bcafebeefLL); - EVTAG_ARRAY_ADD_VALUE(run, other_numbers, 0xdead0a0b); - EVTAG_ARRAY_ADD_VALUE(run, other_numbers, 0xbeefcafe); - } - - if (msg_complete(msg) == -1) - tt_abort_msg("Failed to make complete message."); - - evtag_marshal_msg(tmp, 0xdeaf, msg); - - if (evtag_peek(tmp, &tag) == -1) - tt_abort_msg("Failed to peak tag."); - - if (tag != 0xdeaf) - TT_DIE(("Got incorrect tag: %0x.", (unsigned)tag)); - - msg2 = msg_new(); - if (evtag_unmarshal_msg(tmp, 0xdeaf, msg2) == -1) - tt_abort_msg("Failed to unmarshal message."); - - evutil_gettimeofday(&tv_end, NULL); - evutil_timersub(&tv_end, &tv_start, &tv_end); - TT_BLATHER(("(%.1f us/add) ", - (float)tv_end.tv_sec/(float)i * 1000000.0 + - tv_end.tv_usec / (float)i)); - - if (!EVTAG_HAS(msg2, from_name) || - !EVTAG_HAS(msg2, to_name) || - !EVTAG_HAS(msg2, attack)) { - tt_abort_msg("Missing data structures."); - } - - if (EVTAG_GET(msg2, attack, &attack) == -1) { - tt_abort_msg("Could not get attack."); - } - - if (EVTAG_ARRAY_LEN(msg2, run) != i) { - tt_abort_msg("Wrong number of run messages."); - } - - /* get the very first run message */ - if (EVTAG_ARRAY_GET(msg2, run, 0, &run) == -1) { - tt_abort_msg("Failed to get run msg."); - } else { - /* verify the notes */ - char *note_one, *note_two; - ev_uint64_t large_number; - ev_uint32_t short_number; - - if (EVTAG_ARRAY_LEN(run, notes) != 2) { - tt_abort_msg("Wrong number of note strings."); - } - - if (EVTAG_ARRAY_GET(run, notes, 0, ¬e_one) == -1 || - EVTAG_ARRAY_GET(run, notes, 1, ¬e_two) == -1) { - tt_abort_msg("Could not get note strings."); - } - - if (strcmp(note_one, "this is my note") || - strcmp(note_two, "pps")) { - tt_abort_msg("Incorrect note strings encoded."); - } - - if (EVTAG_GET(run, large_number, &large_number) == -1 || - large_number != 0xdead0a0bcafebeefLL) { - tt_abort_msg("Incorrrect large_number."); - } - - if (EVTAG_ARRAY_LEN(run, other_numbers) != 2) { - tt_abort_msg("Wrong number of other_numbers."); - } - - if (EVTAG_ARRAY_GET( - run, other_numbers, 0, &short_number) == -1) { - tt_abort_msg("Could not get short number."); - } - tt_uint_op(short_number, ==, 0xdead0a0b); - - } - tt_int_op(EVTAG_ARRAY_LEN(attack, how_often), ==, 3); - - for (i = 0; i < 3; ++i) { - ev_uint32_t res; - if (EVTAG_ARRAY_GET(attack, how_often, i, &res) == -1) { - TT_DIE(("Cannot get %dth how_often msg.", i)); - } - if ((int)res != i) { - TT_DIE(("Wrong message encoded %d != %d", i, res)); - } - } - - test_ok = 1; -end: - if (msg) - msg_free(msg); - if (msg2) - msg_free(msg2); - if (tmp) - evbuffer_free(tmp); -} - -#define RPC_LEGACY(name) \ - { #name, run_legacy_test_fn, TT_FORK|TT_NEED_BASE|TT_LEGACY, \ - &legacy_setup, \ - rpc_##name } -#else -/* NO_PYTHON_EXISTS */ - -#define RPC_LEGACY(name) \ - { #name, NULL, TT_SKIP, NULL, NULL } - -#endif - -struct testcase_t rpc_testcases[] = { - RPC_LEGACY(basic_test), - RPC_LEGACY(basic_message), - RPC_LEGACY(basic_client), - RPC_LEGACY(basic_queued_client), - RPC_LEGACY(basic_client_with_pause), - RPC_LEGACY(client_timeout), - RPC_LEGACY(test), - - END_OF_TESTCASES, -}; diff --git a/protocols/Telegram/tgl/libevent/test/regress_rpc.obj b/protocols/Telegram/tgl/libevent/test/regress_rpc.obj Binary files differdeleted file mode 100644 index 6c1d24abcd..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress_rpc.obj +++ /dev/null diff --git a/protocols/Telegram/tgl/libevent/test/regress_ssl.c b/protocols/Telegram/tgl/libevent/test/regress_ssl.c deleted file mode 100644 index a415952a7d..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress_ssl.c +++ /dev/null @@ -1,781 +0,0 @@ -/* - * Copyright (c) 2009-2012 Niels Provos and Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// Get rid of OSX 10.7 and greater deprecation warnings. -#if defined(__APPLE__) && defined(__clang__) -#pragma clang diagnostic ignored "-Wdeprecated-declarations" -#endif - -#ifdef _WIN32 -#include <winsock2.h> -#include <windows.h> -#endif - -#ifndef _WIN32 -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#endif - -#include "event2/util.h" -#include "event2/event.h" -#include "event2/bufferevent_ssl.h" -#include "event2/bufferevent_struct.h" -#include "event2/buffer.h" -#include "event2/listener.h" - -#include "regress.h" -#include "tinytest.h" -#include "tinytest_macros.h" - -#include <openssl/bio.h> -#include <openssl/err.h> -#include <openssl/pem.h> - -#include <string.h> -#ifdef _WIN32 -#include <io.h> -#define read _read -#define write _write -#else -#include <unistd.h> -#endif - -/* A short pre-generated key, to save the cost of doing an RSA key generation - * step during the unit tests. It's only 512 bits long, and it is published - * in this file, so you would have to be very foolish to consider using it in - * your own code. */ -static const char KEY[] = - "-----BEGIN RSA PRIVATE KEY-----\n" - "MIIBOgIBAAJBAKibTEzXjj+sqpipePX1lEk5BNFuL/dDBbw8QCXgaJWikOiKHeJq\n" - "3FQ0OmCnmpkdsPFE4x3ojYmmdgE2i0dJwq0CAwEAAQJAZ08gpUS+qE1IClps/2gG\n" - "AAer6Bc31K2AaiIQvCSQcH440cp062QtWMC3V5sEoWmdLsbAHFH26/9ZHn5zAflp\n" - "gQIhANWOx/UYeR8HD0WREU5kcuSzgzNLwUErHLzxP7U6aojpAiEAyh2H35CjN/P7\n" - "NhcZ4QYw3PeUWpqgJnaE/4i80BSYkSUCIQDLHFhLYLJZ80HwHTADif/ISn9/Ow6b\n" - "p6BWh3DbMar/eQIgBPS6azH5vpp983KXkNv9AL4VZi9ac/b+BeINdzC6GP0CIDmB\n" - "U6GFEQTZ3IfuiVabG5pummdC4DNbcdI+WKrSFNmQ\n" - "-----END RSA PRIVATE KEY-----\n"; - -EVP_PKEY * -ssl_getkey(void) -{ - EVP_PKEY *key; - BIO *bio; - - /* new read-only BIO backed by KEY. */ - bio = BIO_new_mem_buf((char*)KEY, -1); - tt_assert(bio); - - key = PEM_read_bio_PrivateKey(bio,NULL,NULL,NULL); - BIO_free(bio); - tt_assert(key); - - return key; -end: - return NULL; -} - -X509 * -ssl_getcert(void) -{ - /* 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); - - tt_assert(key); - - x509 = X509_new(); - tt_assert(x509); - tt_assert(0 != X509_set_version(x509, 2)); - tt_assert(0 != ASN1_INTEGER_set(X509_get_serialNumber(x509), - (long)now)); - - name = X509_NAME_new(); - tt_assert(name); - nid = OBJ_txt2nid("commonName"); - tt_assert(NID_undef != nid); - tt_assert(0 != X509_NAME_add_entry_by_NID( - name, nid, MBSTRING_ASC, (unsigned char*)"example.com", - -1, -1, 0)); - - X509_set_subject_name(x509, name); - X509_set_issuer_name(x509, name); - - X509_time_adj(X509_get_notBefore(x509), 0, &now); - now += 3600; - X509_time_adj(X509_get_notAfter(x509), 0, &now); - X509_set_pubkey(x509, key); - tt_assert(0 != X509_sign(x509, key, EVP_sha1())); - - return x509; -end: - X509_free(x509); - return NULL; -} - -static int disable_tls_11_and_12 = 0; -static SSL_CTX *the_ssl_ctx = NULL; - -SSL_CTX * -get_ssl_ctx(void) -{ - if (the_ssl_ctx) - return the_ssl_ctx; - the_ssl_ctx = SSL_CTX_new(SSLv23_method()); - if (!the_ssl_ctx) - return NULL; - if (disable_tls_11_and_12) { -#ifdef SSL_OP_NO_TLSv1_2 - SSL_CTX_set_options(the_ssl_ctx, SSL_OP_NO_TLSv1_2); -#endif -#ifdef SSL_OP_NO_TLSv1_1 - SSL_CTX_set_options(the_ssl_ctx, SSL_OP_NO_TLSv1_1); -#endif - } - return the_ssl_ctx; -} - -void -init_ssl(void) -{ - SSL_library_init(); - ERR_load_crypto_strings(); - 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())); - } -} - -/* ==================== - 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, - REGRESS_OPENSSL_FILTER = 2, - REGRESS_OPENSSL_RENEGOTIATE = 4, - REGRESS_OPENSSL_OPEN = 8, - REGRESS_OPENSSL_DIRTY_SHUTDOWN = 16, - REGRESS_OPENSSL_FD = 32, - - REGRESS_OPENSSL_CLIENT = 64, - REGRESS_OPENSSL_SERVER = 128, - - REGRESS_OPENSSL_FREED = 256, - REGRESS_OPENSSL_TIMEOUT = 512, - REGRESS_OPENSSL_SLEEP = 1024, -}; - -static void -bufferevent_openssl_check_fd(struct bufferevent *bev, int filter) -{ - if (filter) { - tt_int_op(bufferevent_getfd(bev), ==, -1); - tt_int_op(bufferevent_setfd(bev, -1), ==, -1); - } else { - tt_int_op(bufferevent_getfd(bev), !=, -1); - tt_int_op(bufferevent_setfd(bev, -1), ==, 0); - } - tt_int_op(bufferevent_getfd(bev), ==, -1); - -end: - ; -} -static void -bufferevent_openssl_check_freed(struct bufferevent *bev) -{ - tt_int_op(event_pending(&bev->ev_read, EVLIST_ALL, NULL), ==, 0); - tt_int_op(event_pending(&bev->ev_write, EVLIST_ALL, NULL), ==, 0); - -end: - ; -} - -static void -respond_to_number(struct bufferevent *bev, void *ctx) -{ - struct evbuffer *b = bufferevent_get_input(bev); - char *line; - int n; - - enum regress_openssl_type type; - type = (enum regress_openssl_type)ctx; - - line = evbuffer_readln(b, NULL, EVBUFFER_EOL_LF); - if (! line) - return; - n = atoi(line); - if (n <= 0) - TT_FAIL(("Bad number: %s", line)); - free(line); - TT_BLATHER(("The number was %d", n)); - if (n == 1001) { - ++test_is_done; - bufferevent_free(bev); /* Should trigger close on other side. */ - return; - } - if ((type & REGRESS_OPENSSL_CLIENT) && n == renegotiate_at) { - SSL_renegotiate(bufferevent_openssl_get_ssl(bev)); - } - ++n; - evbuffer_add_printf(bufferevent_get_output(bev), - "%d\n", n); - TT_BLATHER(("Done reading; now writing.")); - bufferevent_enable(bev, EV_WRITE); - bufferevent_disable(bev, EV_READ); -} - -static void -done_writing_cb(struct bufferevent *bev, void *ctx) -{ - struct evbuffer *b = bufferevent_get_output(bev); - if (evbuffer_get_length(b)) - return; - TT_BLATHER(("Done writing.")); - bufferevent_disable(bev, EV_WRITE); - bufferevent_enable(bev, EV_READ); -} - -static void -eventcb(struct bufferevent *bev, short what, void *ctx) -{ - 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); - peer_cert = SSL_get_peer_certificate(ssl); - if (type & REGRESS_OPENSSL_SERVER) { - tt_assert(peer_cert == NULL); - } else { - tt_assert(peer_cert != NULL); - } - if (stop_when_connected) { - if (--pending_connect_events == 0) - event_base_loopexit(exit_base, NULL); - } - } else if (what & BEV_EVENT_EOF) { - TT_BLATHER(("Got a good EOF")); - ++got_close; - if (type & REGRESS_OPENSSL_FD) { - bufferevent_openssl_check_fd(bev, type & REGRESS_OPENSSL_FILTER); - } - if (type & REGRESS_OPENSSL_FREED) { - bufferevent_openssl_check_freed(bev); - } - bufferevent_free(bev); - } else if (what & BEV_EVENT_ERROR) { - TT_BLATHER(("Got an error.")); - ++got_error; - if (type & REGRESS_OPENSSL_FD) { - bufferevent_openssl_check_fd(bev, type & REGRESS_OPENSSL_FILTER); - } - if (type & REGRESS_OPENSSL_FREED) { - bufferevent_openssl_check_freed(bev); - } - bufferevent_free(bev); - } else if (what & BEV_EVENT_TIMEOUT) { - TT_BLATHER(("Got timeout.")); - ++got_timeout; - if (type & REGRESS_OPENSSL_FD) { - bufferevent_openssl_check_fd(bev, type & REGRESS_OPENSSL_FILTER); - } - if (type & REGRESS_OPENSSL_FREED) { - bufferevent_openssl_check_freed(bev); - } - bufferevent_free(bev); - } -end: - ; -} - -static void -open_ssl_bufevs(struct bufferevent **bev1_out, struct bufferevent **bev2_out, - struct event_base *base, int is_open, int flags, SSL *ssl1, SSL *ssl2, - evutil_socket_t *fd_pair, struct bufferevent **underlying_pair, - enum regress_openssl_type type) -{ - int state1 = is_open ? BUFFEREVENT_SSL_OPEN :BUFFEREVENT_SSL_CONNECTING; - int state2 = is_open ? BUFFEREVENT_SSL_OPEN :BUFFEREVENT_SSL_ACCEPTING; - int dirty_shutdown = type & REGRESS_OPENSSL_DIRTY_SHUTDOWN; - if (fd_pair) { - *bev1_out = bufferevent_openssl_socket_new( - base, fd_pair[0], ssl1, state1, flags); - *bev2_out = bufferevent_openssl_socket_new( - base, fd_pair[1], ssl2, state2, flags); - } else { - *bev1_out = bufferevent_openssl_filter_new( - base, underlying_pair[0], ssl1, state1, flags); - *bev2_out = bufferevent_openssl_filter_new( - base, underlying_pair[1], ssl2, state2, flags); - - } - bufferevent_setcb(*bev1_out, respond_to_number, done_writing_cb, - eventcb, (void*)(REGRESS_OPENSSL_CLIENT | (long)type)); - bufferevent_setcb(*bev2_out, respond_to_number, done_writing_cb, - eventcb, (void*)(REGRESS_OPENSSL_SERVER | (long)type)); - - bufferevent_openssl_set_allow_dirty_shutdown(*bev1_out, dirty_shutdown); - bufferevent_openssl_set_allow_dirty_shutdown(*bev2_out, dirty_shutdown); -} - -static void -regress_bufferevent_openssl(void *arg) -{ - struct basic_test_data *data = 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; - - 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) { - /* 1.0.1 up to 1.0.1c has a bug where TLS1.1 and 1.2 - * can't renegotiate with themselves. Disable. */ - disable_tls_11_and_12 = 1; - } - renegotiate_at = 600; - } - - ssl1 = SSL_new(get_ssl_ctx()); - ssl2 = SSL_new(get_ssl_ctx()); - - SSL_use_certificate(ssl2, cert); - SSL_use_PrivateKey(ssl2, key); - - if (!(type & REGRESS_OPENSSL_OPEN)) - flags |= BEV_OPT_CLOSE_ON_FREE; - - if (!(type & REGRESS_OPENSSL_FILTER)) { - tt_assert(type & REGRESS_OPENSSL_SOCKETPAIR); - fd_pair = data->pair; - } else { - bev_ll[0] = bufferevent_socket_new(data->base, data->pair[0], - BEV_OPT_CLOSE_ON_FREE); - bev_ll[1] = bufferevent_socket_new(data->base, data->pair[1], - BEV_OPT_CLOSE_ON_FREE); - } - - open_ssl_bufevs(&bev1, &bev2, data->base, 0, flags, ssl1, ssl2, - fd_pair, bev_ll, type); - - if (!(type & REGRESS_OPENSSL_FILTER)) { - tt_int_op(bufferevent_getfd(bev1), ==, data->pair[0]); - } else { - tt_ptr_op(bufferevent_get_underlying(bev1), ==, bev_ll[0]); - } - - if (type & REGRESS_OPENSSL_OPEN) { - pending_connect_events = 2; - stop_when_connected = 1; - exit_base = data->base; - event_base_dispatch(data->base); - /* Okay, now the renegotiation is done. Make new - * bufferevents to test opening in BUFFEREVENT_SSL_OPEN */ - flags |= BEV_OPT_CLOSE_ON_FREE; - bufferevent_free(bev1); - bufferevent_free(bev2); - bev1 = bev2 = NULL; - open_ssl_bufevs(&bev1, &bev2, data->base, 1, flags, ssl1, ssl2, - fd_pair, bev_ll, type); - } - - if (!(type & REGRESS_OPENSSL_TIMEOUT)) { - bufferevent_enable(bev1, EV_READ|EV_WRITE); - bufferevent_enable(bev2, EV_READ|EV_WRITE); - - evbuffer_add_printf(bufferevent_get_output(bev1), "1\n"); - - event_base_dispatch(data->base); - - tt_assert(test_is_done == 1); - tt_assert(n_connected == 2); - - /* We don't handle shutdown properly yet */ - if (type & REGRESS_OPENSSL_DIRTY_SHUTDOWN) { - tt_int_op(got_close, ==, 1); - tt_int_op(got_error, ==, 0); - } else { - tt_int_op(got_error, ==, 1); - } - tt_int_op(got_timeout, ==, 0); - } else { - struct timeval t = { 2, 0 }; - - bufferevent_enable(bev1, EV_READ|EV_WRITE); - bufferevent_disable(bev2, EV_READ|EV_WRITE); - - bufferevent_set_timeouts(bev1, &t, &t); - - evbuffer_add_printf(bufferevent_get_output(bev1), "1\n"); - - event_base_dispatch(data->base); - - tt_assert(test_is_done == 0); - tt_assert(n_connected == 0); - - tt_int_op(got_close, ==, 0); - tt_int_op(got_error, ==, 0); - tt_int_op(got_timeout, ==, 1); - } -end: - return; -} - -static void -acceptcb_deferred(evutil_socket_t fd, short events, void *arg) -{ - struct bufferevent *bev = arg; - bufferevent_enable(bev, EV_READ|EV_WRITE); -} -static void -acceptcb(struct evconnlistener *listener, evutil_socket_t fd, - struct sockaddr *addr, int socklen, void *arg) -{ - struct basic_test_data *data = arg; - struct bufferevent *bev; - enum regress_openssl_type type; - SSL *ssl = SSL_new(get_ssl_ctx()); - - type = (enum regress_openssl_type)data->setup_data; - - SSL_use_certificate(ssl, ssl_getcert()); - SSL_use_PrivateKey(ssl, ssl_getkey()); - - bev = bufferevent_openssl_socket_new( - data->base, - fd, - ssl, - BUFFEREVENT_SSL_ACCEPTING, - BEV_OPT_CLOSE_ON_FREE|BEV_OPT_DEFER_CALLBACKS); - - bufferevent_setcb(bev, respond_to_number, NULL, eventcb, - (void*)(REGRESS_OPENSSL_SERVER)); - - if (type & REGRESS_OPENSSL_SLEEP) { - struct timeval when = { 1, 0 }; - event_base_once(data->base, -1, EV_TIMEOUT, - acceptcb_deferred, bev, &when); - bufferevent_disable(bev, EV_READ|EV_WRITE); - } else { - bufferevent_enable(bev, EV_READ|EV_WRITE); - } - - /* Only accept once, then disable ourself. */ - evconnlistener_disable(listener); -} - -struct rwcount -{ - int fd; - size_t read; - size_t write; -}; -static int -bio_rwcount_new(BIO *b) -{ - b->init = 0; - b->num = -1; - b->ptr = NULL; - b->flags = 0; - return 1; -} -static int -bio_rwcount_free(BIO *b) -{ - if (!b) - return 0; - if (b->shutdown) { - b->init = 0; - b->flags = 0; - b->ptr = NULL; - } - return 1; -} -static int -bio_rwcount_read(BIO *b, char *out, int outlen) -{ - struct rwcount *rw = b->ptr; - ev_ssize_t ret = read(rw->fd, out, outlen); - ++rw->read; - if (ret == -1 && errno == EAGAIN) { - BIO_set_retry_read(b); - } - return ret; -} -static int -bio_rwcount_write(BIO *b, const char *in, int inlen) -{ - - struct rwcount *rw = b->ptr; - ev_ssize_t ret = write(rw->fd, in, inlen); - ++rw->write; - if (ret == -1 && errno == EAGAIN) { - BIO_set_retry_write(b); - } - return ret; -} -static long -bio_rwcount_ctrl(BIO *b, int cmd, long num, void *ptr) -{ - long ret = 0; - switch (cmd) { - case BIO_CTRL_GET_CLOSE: - ret = b->shutdown; - break; - case BIO_CTRL_SET_CLOSE: - b->shutdown = (int)num; - break; - case BIO_CTRL_PENDING: - ret = 0; - break; - case BIO_CTRL_WPENDING: - ret = 0; - break; - case BIO_CTRL_DUP: - case BIO_CTRL_FLUSH: - ret = 1; - break; - } - return ret; -} -static int -bio_rwcount_puts(BIO *b, const char *s) -{ - return bio_rwcount_write(b, s, strlen(s)); -} -#define BIO_TYPE_LIBEVENT_RWCOUNT 0xff1 -static BIO_METHOD methods_rwcount = { - BIO_TYPE_LIBEVENT_RWCOUNT, "rwcount", - bio_rwcount_write, - bio_rwcount_read, - bio_rwcount_puts, - NULL /* bio_rwcount_gets */, - bio_rwcount_ctrl, - bio_rwcount_new, - bio_rwcount_free, - NULL /* callback_ctrl */, -}; -static BIO_METHOD * -BIO_s_rwcount(void) -{ - return &methods_rwcount; -} -static BIO * -BIO_new_rwcount(int close_flag) -{ - BIO *result; - if (!(result = BIO_new(BIO_s_rwcount()))) - return NULL; - result->init = 1; - result->ptr = NULL; - result->shutdown = !!close_flag; - return result; -} - -static void -regress_bufferevent_openssl_connect(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; - 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); - - memset(&ss, 0, sizeof(ss)); - slen = sizeof(ss); - - listener = evconnlistener_new_bind(base, acceptcb, data, - 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); - - bev = bufferevent_openssl_socket_new( - data->base, -1, ssl, - BUFFEREVENT_SSL_CONNECTING, - BEV_OPT_CLOSE_ON_FREE|BEV_OPT_DEFER_CALLBACKS); - tt_assert(bev); - - bufferevent_setcb(bev, respond_to_number, NULL, eventcb, - (void*)(REGRESS_OPENSSL_CLIENT)); - - tt_assert(getsockname(evconnlistener_get_fd(listener), - (struct sockaddr*)&ss, &slen) == 0); - tt_assert(slen == sizeof(struct sockaddr_in)); - tt_int_op(((struct sockaddr*)&ss)->sa_family, ==, AF_INET); - - tt_assert(0 == - bufferevent_socket_connect(bev, (struct sockaddr*)&ss, slen)); - /* Possible only when we have fd, since be_openssl can and will overwrite - * bio otherwise before */ - if (type & REGRESS_OPENSSL_SLEEP) { - rw.fd = bufferevent_getfd(bev); - bio = BIO_new_rwcount(0); - tt_assert(bio); - bio->ptr = &rw; - SSL_set_bio(ssl, bio, bio); - } - evbuffer_add_printf(bufferevent_get_output(bev), "1\n"); - bufferevent_enable(bev, EV_READ|EV_WRITE); - - event_base_dispatch(base); - - tt_int_op(rw.read, <=, 100); - tt_int_op(rw.write, <=, 100); -end: - ; -} - -struct testcase_t ssl_testcases[] = { -#define T(a) ((void *)(a)) - { "bufferevent_socketpair", regress_bufferevent_openssl, - TT_ISOLATED, &basic_setup, T(REGRESS_OPENSSL_SOCKETPAIR) }, - { "bufferevent_filter", regress_bufferevent_openssl, - TT_ISOLATED, &basic_setup, T(REGRESS_OPENSSL_FILTER) }, - { "bufferevent_renegotiate_socketpair", regress_bufferevent_openssl, - TT_ISOLATED, &basic_setup, - T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_RENEGOTIATE) }, - { "bufferevent_renegotiate_filter", regress_bufferevent_openssl, - TT_ISOLATED, &basic_setup, - T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_RENEGOTIATE) }, - { "bufferevent_socketpair_startopen", regress_bufferevent_openssl, - TT_ISOLATED, &basic_setup, - T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_OPEN) }, - { "bufferevent_filter_startopen", regress_bufferevent_openssl, - TT_ISOLATED, &basic_setup, - T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_OPEN) }, - - { "bufferevent_socketpair_dirty_shutdown", regress_bufferevent_openssl, - TT_ISOLATED, &basic_setup, - T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_DIRTY_SHUTDOWN) }, - { "bufferevent_filter_dirty_shutdown", regress_bufferevent_openssl, - TT_ISOLATED, &basic_setup, - T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_DIRTY_SHUTDOWN) }, - { "bufferevent_renegotiate_socketpair_dirty_shutdown", - regress_bufferevent_openssl, - TT_ISOLATED, - &basic_setup, - T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_RENEGOTIATE | REGRESS_OPENSSL_DIRTY_SHUTDOWN) }, - { "bufferevent_renegotiate_filter_dirty_shutdown", - regress_bufferevent_openssl, - TT_ISOLATED, - &basic_setup, - T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_RENEGOTIATE | REGRESS_OPENSSL_DIRTY_SHUTDOWN) }, - { "bufferevent_socketpair_startopen_dirty_shutdown", - regress_bufferevent_openssl, - TT_ISOLATED, &basic_setup, - T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_OPEN | REGRESS_OPENSSL_DIRTY_SHUTDOWN) }, - { "bufferevent_filter_startopen_dirty_shutdown", - regress_bufferevent_openssl, - TT_ISOLATED, &basic_setup, - T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_OPEN | REGRESS_OPENSSL_DIRTY_SHUTDOWN) }, - - { "bufferevent_socketpair_fd", regress_bufferevent_openssl, - TT_ISOLATED, &basic_setup, - T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_FD) }, - { "bufferevent_socketpair_freed", regress_bufferevent_openssl, - TT_ISOLATED, &basic_setup, - T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_FREED) }, - { "bufferevent_socketpair_freed_fd", regress_bufferevent_openssl, - TT_ISOLATED, &basic_setup, - T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_FREED | REGRESS_OPENSSL_FD) }, - { "bufferevent_filter_freed_fd", regress_bufferevent_openssl, - TT_ISOLATED, &basic_setup, - T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_FREED | REGRESS_OPENSSL_FD) }, - - { "bufferevent_socketpair_timeout", regress_bufferevent_openssl, - TT_ISOLATED, &basic_setup, - T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_TIMEOUT) }, - { "bufferevent_socketpair_timeout_freed_fd", regress_bufferevent_openssl, - TT_ISOLATED, &basic_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 }, - { "bufferevent_connect_sleep", regress_bufferevent_openssl_connect, - TT_FORK|TT_NEED_BASE, &basic_setup, T(REGRESS_OPENSSL_SLEEP) }, - -#undef T - - END_OF_TESTCASES, -}; diff --git a/protocols/Telegram/tgl/libevent/test/regress_testutils.c b/protocols/Telegram/tgl/libevent/test/regress_testutils.c deleted file mode 100644 index 7554a5413f..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress_testutils.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright (c) 2010-2012 Niels Provos and Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "../util-internal.h" - -#ifdef _WIN32 -#include <winsock2.h> -#include <windows.h> -#include <ws2tcpip.h> -#endif - -#include "event2/event-config.h" - -#include <sys/types.h> -#include <sys/stat.h> -#ifdef EVENT__HAVE_SYS_TIME_H -#include <sys/time.h> -#endif -#include <sys/queue.h> -#ifndef _WIN32 -#include <sys/socket.h> -#include <signal.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <unistd.h> -#endif -#ifdef EVENT__HAVE_NETINET_IN6_H -#include <netinet/in6.h> -#endif -#ifdef HAVE_NETDB_H -#include <netdb.h> -#endif -#include <fcntl.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> - -#include "event2/dns.h" -#include "event2/dns_struct.h" -#include "event2/event.h" -#include "event2/event_compat.h" -#include "event2/util.h" -#include "event2/listener.h" -#include "event2/bufferevent.h" -#include "log-internal.h" -#include "regress.h" -#include "regress_testutils.h" - -/* globals */ -static struct evdns_server_port *dns_port; -evutil_socket_t dns_sock = -1; - -/* Helper: return the port that a socket is bound on, in host order. */ -int -regress_get_socket_port(evutil_socket_t fd) -{ - struct sockaddr_storage ss; - ev_socklen_t socklen = sizeof(ss); - if (getsockname(fd, (struct sockaddr*)&ss, &socklen) != 0) - return -1; - if (ss.ss_family == AF_INET) - return ntohs( ((struct sockaddr_in*)&ss)->sin_port); - else if (ss.ss_family == AF_INET6) - return ntohs( ((struct sockaddr_in6*)&ss)->sin6_port); - else - return -1; -} - -struct evdns_server_port * -regress_get_dnsserver(struct event_base *base, - ev_uint16_t *portnum, - evutil_socket_t *psock, - evdns_request_callback_fn_type cb, - void *arg) -{ - struct evdns_server_port *port = NULL; - evutil_socket_t sock; - struct sockaddr_in my_addr; - - sock = socket(AF_INET, SOCK_DGRAM, 0); - if (sock < 0) { - tt_abort_perror("socket"); - } - - evutil_make_socket_nonblocking(sock); - - memset(&my_addr, 0, sizeof(my_addr)); - my_addr.sin_family = AF_INET; - my_addr.sin_port = htons(*portnum); - my_addr.sin_addr.s_addr = htonl(0x7f000001UL); - if (bind(sock, (struct sockaddr*)&my_addr, sizeof(my_addr)) < 0) { - evutil_closesocket(sock); - tt_abort_perror("bind"); - } - port = evdns_add_server_port_with_base(base, sock, 0, cb, arg); - if (!*portnum) - *portnum = regress_get_socket_port(sock); - if (psock) - *psock = sock; - - return port; -end: - return NULL; -} - -void -regress_clean_dnsserver(void) -{ - if (dns_port) - evdns_close_server_port(dns_port); - if (dns_sock >= 0) - evutil_closesocket(dns_sock); -} - -static void strtolower(char *s) -{ - while (*s) { - *s = EVUTIL_TOLOWER_(*s); - ++s; - } -} -void -regress_dns_server_cb(struct evdns_server_request *req, void *data) -{ - struct regress_dns_server_table *tab = data; - char *question; - - if (req->nquestions != 1) - TT_DIE(("Only handling one question at a time; got %d", - req->nquestions)); - - question = req->questions[0]->name; - - while (tab->q && evutil_ascii_strcasecmp(question, tab->q) && - strcmp("*", tab->q)) - ++tab; - if (tab->q == NULL) - TT_DIE(("Unexpected question: '%s'", question)); - - ++tab->seen; - - if (tab->lower) - strtolower(question); - - if (!strcmp(tab->anstype, "err")) { - int err = atoi(tab->ans); - tt_assert(! evdns_server_request_respond(req, err)); - return; - } else if (!strcmp(tab->anstype, "errsoa")) { - int err = atoi(tab->ans); - char soa_record[] = - "\x04" "dns1" "\x05" "icann" "\x03" "org" "\0" - "\x0a" "hostmaster" "\x05" "icann" "\x03" "org" "\0" - "\x77\xde\x5e\xba" /* serial */ - "\x00\x00\x1c\x20" /* refreshtime = 2h */ - "\x00\x00\x0e\x10" /* retry = 1h */ - "\x00\x12\x75\x00" /* expiration = 14d */ - "\x00\x00\x0e\x10" /* min.ttl = 1h */ - ; - evdns_server_request_add_reply( - req, EVDNS_AUTHORITY_SECTION, - "example.com", EVDNS_TYPE_SOA, EVDNS_CLASS_INET, - 42, sizeof(soa_record) - 1, 0, soa_record); - tt_assert(! evdns_server_request_respond(req, err)); - return; - } else if (!strcmp(tab->anstype, "A")) { - struct in_addr in; - if (!evutil_inet_pton(AF_INET, tab->ans, &in)) { - TT_DIE(("Bad A value %s in table", tab->ans)); - } - evdns_server_request_add_a_reply(req, question, 1, &in.s_addr, - 100); - } else if (!strcmp(tab->anstype, "AAAA")) { - struct in6_addr in6; - if (!evutil_inet_pton(AF_INET6, tab->ans, &in6)) { - TT_DIE(("Bad AAAA value %s in table", tab->ans)); - } - evdns_server_request_add_aaaa_reply(req, - question, 1, &in6.s6_addr, 100); - } else { - TT_DIE(("Weird table entry with type '%s'", tab->anstype)); - } - tt_assert(! evdns_server_request_respond(req, 0)) - return; -end: - tt_want(! evdns_server_request_drop(req)); -} - -int -regress_dnsserver(struct event_base *base, ev_uint16_t *port, - struct regress_dns_server_table *search_table) -{ - dns_port = regress_get_dnsserver(base, port, &dns_sock, - regress_dns_server_cb, search_table); - return dns_port != NULL; -} - -int -regress_get_listener_addr(struct evconnlistener *lev, - struct sockaddr *sa, ev_socklen_t *socklen) -{ - evutil_socket_t s = evconnlistener_get_fd(lev); - if (s <= 0) - return -1; - return getsockname(s, sa, socklen); -} diff --git a/protocols/Telegram/tgl/libevent/test/regress_testutils.h b/protocols/Telegram/tgl/libevent/test/regress_testutils.h deleted file mode 100644 index 040516a585..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress_testutils.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2010-2012 Niels Provos and Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef REGRESS_TESTUTILS_H_INCLUDED_ -#define REGRESS_TESTUTILS_H_INCLUDED_ - -#include "event2/dns.h" - -struct regress_dns_server_table { - const char *q; - const char *anstype; - const char *ans; - int seen; - int lower; -}; - -struct evdns_server_port * -regress_get_dnsserver(struct event_base *base, - ev_uint16_t *portnum, - evutil_socket_t *psock, - evdns_request_callback_fn_type cb, - void *arg); - -/* Helper: return the port that a socket is bound on, in host order. */ -int regress_get_socket_port(evutil_socket_t fd); - -/* used to look up pre-canned responses in a search table */ -void regress_dns_server_cb( - struct evdns_server_request *req, void *data); - -/* globally allocates a dns server that serves from a search table */ -int regress_dnsserver(struct event_base *base, ev_uint16_t *port, - struct regress_dns_server_table *seach_table); - -/* clean up the global dns server resources */ -void regress_clean_dnsserver(void); - -struct evconnlistener; -struct sockaddr; -int regress_get_listener_addr(struct evconnlistener *lev, - struct sockaddr *sa, ev_socklen_t *socklen); - -#endif /* REGRESS_TESTUTILS_H_INCLUDED_ */ - diff --git a/protocols/Telegram/tgl/libevent/test/regress_testutils.obj b/protocols/Telegram/tgl/libevent/test/regress_testutils.obj Binary files differdeleted file mode 100644 index f596a67e4c..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress_testutils.obj +++ /dev/null diff --git a/protocols/Telegram/tgl/libevent/test/regress_thread.c b/protocols/Telegram/tgl/libevent/test/regress_thread.c deleted file mode 100644 index 9ff6a8fa88..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress_thread.c +++ /dev/null @@ -1,590 +0,0 @@ -/* - * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "util-internal.h" - -/* The old tests here need assertions to work. */ -#undef NDEBUG - -#include "event2/event-config.h" - -#include <sys/types.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#ifdef EVENT__HAVE_UNISTD_H -#include <unistd.h> -#endif -#ifdef EVENT__HAVE_SYS_WAIT_H -#include <sys/wait.h> -#endif - -#ifdef EVENT__HAVE_PTHREADS -#include <pthread.h> -#elif defined(_WIN32) -#include <process.h> -#endif -#include <assert.h> -#ifdef EVENT__HAVE_UNISTD_H -#include <unistd.h> -#endif -#include <time.h> - -#include "sys/queue.h" - -#include "event2/event.h" -#include "event2/event_struct.h" -#include "event2/thread.h" -#include "event2/util.h" -#include "evthread-internal.h" -#include "event-internal.h" -#include "defer-internal.h" -#include "regress.h" -#include "tinytest_macros.h" -#include "time-internal.h" -#include "regress_thread.h" - -struct cond_wait { - void *lock; - void *cond; -}; - -static void -wake_all_timeout(evutil_socket_t fd, short what, void *arg) -{ - struct cond_wait *cw = arg; - EVLOCK_LOCK(cw->lock, 0); - EVTHREAD_COND_BROADCAST(cw->cond); - EVLOCK_UNLOCK(cw->lock, 0); - -} - -static void -wake_one_timeout(evutil_socket_t fd, short what, void *arg) -{ - struct cond_wait *cw = arg; - EVLOCK_LOCK(cw->lock, 0); - EVTHREAD_COND_SIGNAL(cw->cond); - EVLOCK_UNLOCK(cw->lock, 0); -} - -#define NUM_THREADS 100 -#define NUM_ITERATIONS 100 -void *count_lock; -static int count; - -static THREAD_FN -basic_thread(void *arg) -{ - struct cond_wait cw; - struct event_base *base = arg; - struct event ev; - int i = 0; - - EVTHREAD_ALLOC_LOCK(cw.lock, 0); - EVTHREAD_ALLOC_COND(cw.cond); - assert(cw.lock); - assert(cw.cond); - - evtimer_assign(&ev, base, wake_all_timeout, &cw); - for (i = 0; i < NUM_ITERATIONS; i++) { - struct timeval tv; - evutil_timerclear(&tv); - tv.tv_sec = 0; - tv.tv_usec = 3000; - - EVLOCK_LOCK(cw.lock, 0); - /* we need to make sure that event does not happen before - * we get to wait on the conditional variable */ - assert(evtimer_add(&ev, &tv) == 0); - - assert(EVTHREAD_COND_WAIT(cw.cond, cw.lock) == 0); - EVLOCK_UNLOCK(cw.lock, 0); - - EVLOCK_LOCK(count_lock, 0); - ++count; - EVLOCK_UNLOCK(count_lock, 0); - } - - /* exit the loop only if all threads fired all timeouts */ - EVLOCK_LOCK(count_lock, 0); - if (count >= NUM_THREADS * NUM_ITERATIONS) - event_base_loopexit(base, NULL); - EVLOCK_UNLOCK(count_lock, 0); - - EVTHREAD_FREE_LOCK(cw.lock, 0); - EVTHREAD_FREE_COND(cw.cond); - - THREAD_RETURN(); -} - -static int notification_fd_used = 0; -#ifndef _WIN32 -static int got_sigchld = 0; -static void -sigchld_cb(evutil_socket_t fd, short event, void *arg) -{ - struct timeval tv; - struct event_base *base = arg; - - got_sigchld++; - tv.tv_usec = 100000; - tv.tv_sec = 0; - event_base_loopexit(base, &tv); -} - - -static void -notify_fd_cb(evutil_socket_t fd, short event, void *arg) -{ - ++notification_fd_used; -} -#endif - -static void -thread_basic(void *arg) -{ - THREAD_T threads[NUM_THREADS]; - struct event ev; - struct timeval tv; - int i; - struct basic_test_data *data = arg; - struct event_base *base = data->base; - - struct event *notification_event = NULL; - struct event *sigchld_event = NULL; - - EVTHREAD_ALLOC_LOCK(count_lock, 0); - tt_assert(count_lock); - - tt_assert(base); - if (evthread_make_base_notifiable(base)<0) { - tt_abort_msg("Couldn't make base notifiable!"); - } - -#ifndef _WIN32 - if (data->setup_data && !strcmp(data->setup_data, "forking")) { - pid_t pid; - int status; - sigchld_event = evsignal_new(base, SIGCHLD, sigchld_cb, base); - /* This piggybacks on the th_notify_fd weirdly, and looks - * inside libevent internals. Not a good idea in non-testing - * code! */ - notification_event = event_new(base, - base->th_notify_fd[0], EV_READ|EV_PERSIST, notify_fd_cb, - NULL); - event_add(sigchld_event, NULL); - event_add(notification_event, NULL); - - if ((pid = fork()) == 0) { - event_del(notification_event); - if (event_reinit(base) < 0) { - TT_FAIL(("reinit")); - exit(1); - } - event_assign(notification_event, base, - base->th_notify_fd[0], EV_READ|EV_PERSIST, - notify_fd_cb, NULL); - event_add(notification_event, NULL); - goto child; - } - - event_base_dispatch(base); - - if (waitpid(pid, &status, 0) == -1) - tt_abort_perror("waitpid"); - TT_BLATHER(("Waitpid okay\n")); - - tt_assert(got_sigchld); - tt_int_op(notification_fd_used, ==, 0); - - goto end; - } - -child: -#endif - for (i = 0; i < NUM_THREADS; ++i) - THREAD_START(threads[i], basic_thread, base); - - evtimer_assign(&ev, base, NULL, NULL); - evutil_timerclear(&tv); - tv.tv_sec = 1000; - event_add(&ev, &tv); - - event_base_dispatch(base); - - for (i = 0; i < NUM_THREADS; ++i) - THREAD_JOIN(threads[i]); - - event_del(&ev); - - tt_int_op(count, ==, NUM_THREADS * NUM_ITERATIONS); - - EVTHREAD_FREE_LOCK(count_lock, 0); - - TT_BLATHER(("notifiations==%d", notification_fd_used)); - -end: - - if (notification_event) - event_free(notification_event); - if (sigchld_event) - event_free(sigchld_event); -} - -#undef NUM_THREADS -#define NUM_THREADS 10 - -struct alerted_record { - struct cond_wait *cond; - struct timeval delay; - struct timeval alerted_at; - int timed_out; -}; - -static THREAD_FN -wait_for_condition(void *arg) -{ - struct alerted_record *rec = arg; - int r; - - EVLOCK_LOCK(rec->cond->lock, 0); - if (rec->delay.tv_sec || rec->delay.tv_usec) { - r = EVTHREAD_COND_WAIT_TIMED(rec->cond->cond, rec->cond->lock, - &rec->delay); - } else { - r = EVTHREAD_COND_WAIT(rec->cond->cond, rec->cond->lock); - } - EVLOCK_UNLOCK(rec->cond->lock, 0); - - evutil_gettimeofday(&rec->alerted_at, NULL); - if (r == 1) - rec->timed_out = 1; - - THREAD_RETURN(); -} - -static void -thread_conditions_simple(void *arg) -{ - struct timeval tv_signal, tv_timeout, tv_broadcast; - struct alerted_record alerted[NUM_THREADS]; - THREAD_T threads[NUM_THREADS]; - struct cond_wait cond; - int i; - struct timeval launched_at; - struct event wake_one; - struct event wake_all; - struct basic_test_data *data = arg; - struct event_base *base = data->base; - int n_timed_out=0, n_signal=0, n_broadcast=0; - - tv_signal.tv_sec = tv_timeout.tv_sec = tv_broadcast.tv_sec = 0; - tv_signal.tv_usec = 30*1000; - tv_timeout.tv_usec = 150*1000; - tv_broadcast.tv_usec = 500*1000; - - EVTHREAD_ALLOC_LOCK(cond.lock, EVTHREAD_LOCKTYPE_RECURSIVE); - EVTHREAD_ALLOC_COND(cond.cond); - tt_assert(cond.lock); - tt_assert(cond.cond); - for (i = 0; i < NUM_THREADS; ++i) { - memset(&alerted[i], 0, sizeof(struct alerted_record)); - alerted[i].cond = &cond; - } - - /* Threads 5 and 6 will be allowed to time out */ - memcpy(&alerted[5].delay, &tv_timeout, sizeof(tv_timeout)); - memcpy(&alerted[6].delay, &tv_timeout, sizeof(tv_timeout)); - - evtimer_assign(&wake_one, base, wake_one_timeout, &cond); - evtimer_assign(&wake_all, base, wake_all_timeout, &cond); - - evutil_gettimeofday(&launched_at, NULL); - - /* Launch the threads... */ - for (i = 0; i < NUM_THREADS; ++i) { - THREAD_START(threads[i], wait_for_condition, &alerted[i]); - } - - /* Start the timers... */ - tt_int_op(event_add(&wake_one, &tv_signal), ==, 0); - tt_int_op(event_add(&wake_all, &tv_broadcast), ==, 0); - - /* And run for a bit... */ - event_base_dispatch(base); - - /* And wait till the threads are done. */ - for (i = 0; i < NUM_THREADS; ++i) - THREAD_JOIN(threads[i]); - - /* Now, let's see what happened. At least one of 5 or 6 should - * have timed out. */ - n_timed_out = alerted[5].timed_out + alerted[6].timed_out; - tt_int_op(n_timed_out, >=, 1); - tt_int_op(n_timed_out, <=, 2); - - for (i = 0; i < NUM_THREADS; ++i) { - const struct timeval *target_delay; - struct timeval target_time, actual_delay; - if (alerted[i].timed_out) { - TT_BLATHER(("%d looks like a timeout\n", i)); - target_delay = &tv_timeout; - tt_assert(i == 5 || i == 6); - } else if (evutil_timerisset(&alerted[i].alerted_at)) { - long diff1,diff2; - evutil_timersub(&alerted[i].alerted_at, - &launched_at, &actual_delay); - diff1 = timeval_msec_diff(&actual_delay, - &tv_signal); - diff2 = timeval_msec_diff(&actual_delay, - &tv_broadcast); - if (labs(diff1) < labs(diff2)) { - TT_BLATHER(("%d looks like a signal\n", i)); - target_delay = &tv_signal; - ++n_signal; - } else { - TT_BLATHER(("%d looks like a broadcast\n", i)); - target_delay = &tv_broadcast; - ++n_broadcast; - } - } else { - TT_FAIL(("Thread %d never got woken", i)); - continue; - } - evutil_timeradd(target_delay, &launched_at, &target_time); - test_timeval_diff_leq(&target_time, &alerted[i].alerted_at, - 0, 50); - } - tt_int_op(n_broadcast + n_signal + n_timed_out, ==, NUM_THREADS); - tt_int_op(n_signal, ==, 1); - -end: - EVTHREAD_FREE_LOCK(cond.lock, EVTHREAD_LOCKTYPE_RECURSIVE); - EVTHREAD_FREE_COND(cond.cond); -} - -#define CB_COUNT 128 -#define QUEUE_THREAD_COUNT 8 - -static void -SLEEP_MS(int ms) -{ - struct timeval tv; - tv.tv_sec = ms/1000; - tv.tv_usec = (ms%1000)*1000; - evutil_usleep_(&tv); -} - -struct deferred_test_data { - struct event_callback cbs[CB_COUNT]; - struct event_base *queue; -}; - -static struct timeval timer_start = {0,0}; -static struct timeval timer_end = {0,0}; -static unsigned callback_count = 0; -static THREAD_T load_threads[QUEUE_THREAD_COUNT]; -static struct deferred_test_data deferred_data[QUEUE_THREAD_COUNT]; - -static void -deferred_callback(struct event_callback *cb, void *arg) -{ - SLEEP_MS(1); - callback_count += 1; -} - -static THREAD_FN -load_deferred_queue(void *arg) -{ - struct deferred_test_data *data = arg; - size_t i; - - for (i = 0; i < CB_COUNT; ++i) { - event_deferred_cb_init_(&data->cbs[i], 0, deferred_callback, - NULL); - event_deferred_cb_schedule_(data->queue, &data->cbs[i]); - SLEEP_MS(1); - } - - THREAD_RETURN(); -} - -static void -timer_callback(evutil_socket_t fd, short what, void *arg) -{ - evutil_gettimeofday(&timer_end, NULL); -} - -static void -start_threads_callback(evutil_socket_t fd, short what, void *arg) -{ - int i; - - for (i = 0; i < QUEUE_THREAD_COUNT; ++i) { - THREAD_START(load_threads[i], load_deferred_queue, - &deferred_data[i]); - } -} - -static void -thread_deferred_cb_skew(void *arg) -{ - struct timeval tv_timer = {1, 0}; - struct event_base *base = NULL; - struct event_config *cfg = NULL; - struct timeval elapsed; - int elapsed_usec; - int i; - - cfg = event_config_new(); - tt_assert(cfg); - event_config_set_max_dispatch_interval(cfg, NULL, 16, 0); - - base = event_base_new_with_config(cfg); - tt_assert(base); - - for (i = 0; i < QUEUE_THREAD_COUNT; ++i) - deferred_data[i].queue = base; - - evutil_gettimeofday(&timer_start, NULL); - event_base_once(base, -1, EV_TIMEOUT, timer_callback, NULL, - &tv_timer); - event_base_once(base, -1, EV_TIMEOUT, start_threads_callback, - NULL, NULL); - event_base_dispatch(base); - - evutil_timersub(&timer_end, &timer_start, &elapsed); - TT_BLATHER(("callback count, %u", callback_count)); - elapsed_usec = - (unsigned)(elapsed.tv_sec*1000000 + elapsed.tv_usec); - TT_BLATHER(("elapsed time, %u usec", elapsed_usec)); - - /* XXX be more intelligent here. just make sure skew is - * within .4 seconds for now. */ - tt_assert(elapsed_usec >= 600000 && elapsed_usec <= 1400000); - -end: - for (i = 0; i < QUEUE_THREAD_COUNT; ++i) - THREAD_JOIN(load_threads[i]); - if (base) - event_base_free(base); - if (cfg) - event_config_free(cfg); -} - -static struct event time_events[5]; -static struct timeval times[5]; -static struct event_base *exit_base = NULL; -static void -note_time_cb(evutil_socket_t fd, short what, void *arg) -{ - evutil_gettimeofday(arg, NULL); - if (arg == ×[4]) { - event_base_loopbreak(exit_base); - } -} -static THREAD_FN -register_events_subthread(void *arg) -{ - struct timeval tv = {0,0}; - SLEEP_MS(100); - event_active(&time_events[0], EV_TIMEOUT, 1); - SLEEP_MS(100); - event_active(&time_events[1], EV_TIMEOUT, 1); - SLEEP_MS(100); - tv.tv_usec = 100*1000; - event_add(&time_events[2], &tv); - tv.tv_usec = 150*1000; - event_add(&time_events[3], &tv); - SLEEP_MS(200); - event_active(&time_events[4], EV_TIMEOUT, 1); - - THREAD_RETURN(); -} - -static void -thread_no_events(void *arg) -{ - THREAD_T thread; - struct basic_test_data *data = arg; - struct timeval starttime, endtime; - int i; - exit_base = data->base; - - memset(times,0,sizeof(times)); - for (i=0;i<5;++i) { - event_assign(&time_events[i], data->base, - -1, 0, note_time_cb, ×[i]); - } - - evutil_gettimeofday(&starttime, NULL); - THREAD_START(thread, register_events_subthread, data->base); - event_base_loop(data->base, EVLOOP_NO_EXIT_ON_EMPTY); - evutil_gettimeofday(&endtime, NULL); - tt_assert(event_base_got_break(data->base)); - THREAD_JOIN(thread); - for (i=0; i<5; ++i) { - struct timeval diff; - double sec; - evutil_timersub(×[i], &starttime, &diff); - sec = diff.tv_sec + diff.tv_usec/1.0e6; - TT_BLATHER(("event %d at %.4f seconds", i, sec)); - } - test_timeval_diff_eq(&starttime, ×[0], 100); - test_timeval_diff_eq(&starttime, ×[1], 200); - test_timeval_diff_eq(&starttime, ×[2], 400); - test_timeval_diff_eq(&starttime, ×[3], 450); - test_timeval_diff_eq(&starttime, ×[4], 500); - test_timeval_diff_eq(&starttime, &endtime, 500); - -end: - ; -} - -#define TEST(name) \ - { #name, thread_##name, TT_FORK|TT_NEED_THREADS|TT_NEED_BASE, \ - &basic_setup, NULL } - -struct testcase_t thread_testcases[] = { - { "basic", thread_basic, TT_FORK|TT_NEED_THREADS|TT_NEED_BASE, - &basic_setup, NULL }, -#ifndef _WIN32 - { "forking", thread_basic, TT_FORK|TT_NEED_THREADS|TT_NEED_BASE, - &basic_setup, (char*)"forking" }, -#endif - TEST(conditions_simple), - { "deferred_cb_skew", thread_deferred_cb_skew, - TT_FORK|TT_NEED_THREADS|TT_OFF_BY_DEFAULT, - &basic_setup, NULL }, -#ifndef _WIN32 - /****** XXX TODO FIXME windows seems to be having some timing trouble, - * looking into it now. / ellzey - ******/ - TEST(no_events), -#endif - END_OF_TESTCASES -}; - diff --git a/protocols/Telegram/tgl/libevent/test/regress_thread.h b/protocols/Telegram/tgl/libevent/test/regress_thread.h deleted file mode 100644 index 831b51e507..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress_thread.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef REGRESS_THREAD_H_INCLUDED_ -#define REGRESS_THREAD_H_INCLUDED_ - -#ifdef EVENT__HAVE_PTHREADS -#define THREAD_T pthread_t -#define THREAD_FN void * -#define THREAD_RETURN() return (NULL) -#define THREAD_START(threadvar, fn, arg) \ - pthread_create(&(threadvar), NULL, fn, arg) -#define THREAD_JOIN(th) pthread_join(th, NULL) -#else -#define THREAD_T HANDLE -#define THREAD_FN unsigned __stdcall -#define THREAD_RETURN() return (0) -#define THREAD_START(threadvar, fn, arg) do { \ - uintptr_t threadhandle = _beginthreadex(NULL,0,fn,(arg),0,NULL); \ - (threadvar) = (HANDLE) threadhandle; \ - } while (0) -#define THREAD_JOIN(th) WaitForSingleObject(th, INFINITE) -#endif - -#endif diff --git a/protocols/Telegram/tgl/libevent/test/regress_thread.obj b/protocols/Telegram/tgl/libevent/test/regress_thread.obj Binary files differdeleted file mode 100644 index 9654fe8ddb..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress_thread.obj +++ /dev/null diff --git a/protocols/Telegram/tgl/libevent/test/regress_util.c b/protocols/Telegram/tgl/libevent/test/regress_util.c deleted file mode 100644 index 60f085bf1d..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress_util.c +++ /dev/null @@ -1,1413 +0,0 @@ -/* - * Copyright (c) 2009-2012 Nick Mathewson and Niels Provos - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "../util-internal.h" - -#ifdef _WIN32 -#include <winsock2.h> -#include <windows.h> -#include <ws2tcpip.h> -#endif - -#include "event2/event-config.h" - -#include <sys/types.h> - -#ifndef _WIN32 -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <unistd.h> -#endif -#ifdef EVENT__HAVE_NETINET_IN6_H -#include <netinet/in6.h> -#endif -#ifdef EVENT__HAVE_SYS_WAIT_H -#include <sys/wait.h> -#endif -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "event2/event.h" -#include "event2/util.h" -#include "../ipv6-internal.h" -#include "../log-internal.h" -#include "../strlcpy-internal.h" -#include "../mm-internal.h" -#include "../time-internal.h" - -#include "regress.h" - -enum entry_status { NORMAL, CANONICAL, BAD }; - -/* This is a big table of results we expect from generating and parsing */ -static struct ipv4_entry { - const char *addr; - ev_uint32_t res; - enum entry_status status; -} ipv4_entries[] = { - { "1.2.3.4", 0x01020304u, CANONICAL }, - { "255.255.255.255", 0xffffffffu, CANONICAL }, - { "256.0.0.0", 0, BAD }, - { "ABC", 0, BAD }, - { "1.2.3.4.5", 0, BAD }, - { "176.192.208.244", 0xb0c0d0f4, CANONICAL }, - { NULL, 0, BAD }, -}; - -static struct ipv6_entry { - const char *addr; - ev_uint32_t res[4]; - enum entry_status status; -} ipv6_entries[] = { - { "::", { 0, 0, 0, 0, }, CANONICAL }, - { "0:0:0:0:0:0:0:0", { 0, 0, 0, 0, }, NORMAL }, - { "::1", { 0, 0, 0, 1, }, CANONICAL }, - { "::1.2.3.4", { 0, 0, 0, 0x01020304, }, CANONICAL }, - { "ffff:1::", { 0xffff0001u, 0, 0, 0, }, CANONICAL }, - { "ffff:0000::", { 0xffff0000u, 0, 0, 0, }, NORMAL }, - { "ffff::1234", { 0xffff0000u, 0, 0, 0x1234, }, CANONICAL }, - { "0102::1.2.3.4", {0x01020000u, 0, 0, 0x01020304u }, NORMAL }, - { "::9:c0a8:1:1", { 0, 0, 0x0009c0a8u, 0x00010001u }, CANONICAL }, - { "::ffff:1.2.3.4", { 0, 0, 0x000ffffu, 0x01020304u }, CANONICAL }, - { "FFFF::", { 0xffff0000u, 0, 0, 0 }, NORMAL }, - { "foobar.", { 0, 0, 0, 0 }, BAD }, - { "foobar", { 0, 0, 0, 0 }, BAD }, - { "fo:obar", { 0, 0, 0, 0 }, BAD }, - { "ffff", { 0, 0, 0, 0 }, BAD }, - { "fffff::", { 0, 0, 0, 0 }, BAD }, - { "fffff::", { 0, 0, 0, 0 }, BAD }, - { "::1.0.1.1000", { 0, 0, 0, 0 }, BAD }, - { "1:2:33333:4::", { 0, 0, 0, 0 }, BAD }, - { "1:2:3:4:5:6:7:8:9", { 0, 0, 0, 0 }, BAD }, - { "1::2::3", { 0, 0, 0, 0 }, BAD }, - { ":::1", { 0, 0, 0, 0 }, BAD }, - { NULL, { 0, 0, 0, 0, }, BAD }, -}; - -static void -regress_ipv4_parse(void *ptr) -{ - int i; - for (i = 0; ipv4_entries[i].addr; ++i) { - char written[128]; - struct ipv4_entry *ent = &ipv4_entries[i]; - struct in_addr in; - int r; - r = evutil_inet_pton(AF_INET, ent->addr, &in); - if (r == 0) { - if (ent->status != BAD) { - TT_FAIL(("%s did not parse, but it's a good address!", - ent->addr)); - } - continue; - } - if (ent->status == BAD) { - TT_FAIL(("%s parsed, but we expected an error", ent->addr)); - continue; - } - if (ntohl(in.s_addr) != ent->res) { - TT_FAIL(("%s parsed to %lx, but we expected %lx", ent->addr, - (unsigned long)ntohl(in.s_addr), - (unsigned long)ent->res)); - continue; - } - if (ent->status == CANONICAL) { - const char *w = evutil_inet_ntop(AF_INET, &in, written, - sizeof(written)); - if (!w) { - TT_FAIL(("Tried to write out %s; got NULL.", ent->addr)); - continue; - } - if (strcmp(written, ent->addr)) { - TT_FAIL(("Tried to write out %s; got %s", - ent->addr, written)); - continue; - } - } - - } - -} - -static void -regress_ipv6_parse(void *ptr) -{ -#ifdef AF_INET6 - int i, j; - - for (i = 0; ipv6_entries[i].addr; ++i) { - char written[128]; - struct ipv6_entry *ent = &ipv6_entries[i]; - struct in6_addr in6; - int r; - r = evutil_inet_pton(AF_INET6, ent->addr, &in6); - if (r == 0) { - if (ent->status != BAD) - TT_FAIL(("%s did not parse, but it's a good address!", - ent->addr)); - continue; - } - if (ent->status == BAD) { - TT_FAIL(("%s parsed, but we expected an error", ent->addr)); - continue; - } - for (j = 0; j < 4; ++j) { - /* Can't use s6_addr32 here; some don't have it. */ - ev_uint32_t u = - ((ev_uint32_t)in6.s6_addr[j*4 ] << 24) | - ((ev_uint32_t)in6.s6_addr[j*4+1] << 16) | - ((ev_uint32_t)in6.s6_addr[j*4+2] << 8) | - ((ev_uint32_t)in6.s6_addr[j*4+3]); - if (u != ent->res[j]) { - TT_FAIL(("%s did not parse as expected.", ent->addr)); - continue; - } - } - if (ent->status == CANONICAL) { - const char *w = evutil_inet_ntop(AF_INET6, &in6, written, - sizeof(written)); - if (!w) { - TT_FAIL(("Tried to write out %s; got NULL.", ent->addr)); - continue; - } - if (strcmp(written, ent->addr)) { - TT_FAIL(("Tried to write out %s; got %s", ent->addr, written)); - continue; - } - } - - } -#else - TT_BLATHER(("Skipping IPv6 address parsing.")); -#endif -} - -static struct sa_port_ent { - const char *parse; - int safamily; - const char *addr; - int port; -} sa_port_ents[] = { - { "[ffff::1]:1000", AF_INET6, "ffff::1", 1000 }, - { "[ffff::1]", AF_INET6, "ffff::1", 0 }, - { "[ffff::1", 0, NULL, 0 }, - { "[ffff::1]:65599", 0, NULL, 0 }, - { "[ffff::1]:0", 0, NULL, 0 }, - { "[ffff::1]:-1", 0, NULL, 0 }, - { "::1", AF_INET6, "::1", 0 }, - { "1:2::1", AF_INET6, "1:2::1", 0 }, - { "192.168.0.1:50", AF_INET, "192.168.0.1", 50 }, - { "1.2.3.4", AF_INET, "1.2.3.4", 0 }, - { NULL, 0, NULL, 0 }, -}; - -static void -regress_sockaddr_port_parse(void *ptr) -{ - struct sockaddr_storage ss; - int i, r; - - for (i = 0; sa_port_ents[i].parse; ++i) { - struct sa_port_ent *ent = &sa_port_ents[i]; - int len = sizeof(ss); - memset(&ss, 0, sizeof(ss)); - r = evutil_parse_sockaddr_port(ent->parse, (struct sockaddr*)&ss, &len); - if (r < 0) { - if (ent->safamily) - TT_FAIL(("Couldn't parse %s!", ent->parse)); - continue; - } else if (! ent->safamily) { - TT_FAIL(("Shouldn't have been able to parse %s!", ent->parse)); - continue; - } - if (ent->safamily == AF_INET) { - struct sockaddr_in sin; - memset(&sin, 0, sizeof(sin)); -#ifdef EVENT__HAVE_STRUCT_SOCKADDR_IN_SIN_LEN - sin.sin_len = sizeof(sin); -#endif - sin.sin_family = AF_INET; - sin.sin_port = htons(ent->port); - r = evutil_inet_pton(AF_INET, ent->addr, &sin.sin_addr); - if (1 != r) { - TT_FAIL(("Couldn't parse ipv4 target %s.", ent->addr)); - } else if (memcmp(&sin, &ss, sizeof(sin))) { - TT_FAIL(("Parse for %s was not as expected.", ent->parse)); - } else if (len != sizeof(sin)) { - TT_FAIL(("Length for %s not as expected.",ent->parse)); - } - } else { - struct sockaddr_in6 sin6; - memset(&sin6, 0, sizeof(sin6)); -#ifdef EVENT__HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN - sin6.sin6_len = sizeof(sin6); -#endif - sin6.sin6_family = AF_INET6; - sin6.sin6_port = htons(ent->port); - r = evutil_inet_pton(AF_INET6, ent->addr, &sin6.sin6_addr); - if (1 != r) { - TT_FAIL(("Couldn't parse ipv6 target %s.", ent->addr)); - } else if (memcmp(&sin6, &ss, sizeof(sin6))) { - TT_FAIL(("Parse for %s was not as expected.", ent->parse)); - } else if (len != sizeof(sin6)) { - TT_FAIL(("Length for %s not as expected.",ent->parse)); - } - } - } -} - - -static void -regress_sockaddr_port_format(void *ptr) -{ - struct sockaddr_storage ss; - int len; - const char *cp; - char cbuf[128]; - int r; - - len = sizeof(ss); - r = evutil_parse_sockaddr_port("192.168.1.1:80", - (struct sockaddr*)&ss, &len); - tt_int_op(r,==,0); - cp = evutil_format_sockaddr_port_( - (struct sockaddr*)&ss, cbuf, sizeof(cbuf)); - tt_ptr_op(cp,==,cbuf); - tt_str_op(cp,==,"192.168.1.1:80"); - - len = sizeof(ss); - r = evutil_parse_sockaddr_port("[ff00::8010]:999", - (struct sockaddr*)&ss, &len); - tt_int_op(r,==,0); - cp = evutil_format_sockaddr_port_( - (struct sockaddr*)&ss, cbuf, sizeof(cbuf)); - tt_ptr_op(cp,==,cbuf); - tt_str_op(cp,==,"[ff00::8010]:999"); - - ss.ss_family=99; - cp = evutil_format_sockaddr_port_( - (struct sockaddr*)&ss, cbuf, sizeof(cbuf)); - tt_ptr_op(cp,==,cbuf); - tt_str_op(cp,==,"<addr with socktype 99>"); -end: - ; -} - -static struct sa_pred_ent { - const char *parse; - - int is_loopback; -} sa_pred_entries[] = { - { "127.0.0.1", 1 }, - { "127.0.3.2", 1 }, - { "128.1.2.3", 0 }, - { "18.0.0.1", 0 }, - { "129.168.1.1", 0 }, - - { "::1", 1 }, - { "::0", 0 }, - { "f::1", 0 }, - { "::501", 0 }, - { NULL, 0 }, - -}; - -static void -test_evutil_sockaddr_predicates(void *ptr) -{ - struct sockaddr_storage ss; - int r, i; - - for (i=0; sa_pred_entries[i].parse; ++i) { - struct sa_pred_ent *ent = &sa_pred_entries[i]; - int len = sizeof(ss); - - r = evutil_parse_sockaddr_port(ent->parse, (struct sockaddr*)&ss, &len); - - if (r<0) { - TT_FAIL(("Couldn't parse %s!", ent->parse)); - continue; - } - - /* sockaddr_is_loopback */ - if (ent->is_loopback != evutil_sockaddr_is_loopback_((struct sockaddr*)&ss)) { - TT_FAIL(("evutil_sockaddr_loopback(%s) not as expected", - ent->parse)); - } - } -} - -static void -test_evutil_strtoll(void *ptr) -{ - const char *s; - char *endptr; - - tt_want(evutil_strtoll("5000000000", NULL, 10) == - ((ev_int64_t)5000000)*1000); - tt_want(evutil_strtoll("-5000000000", NULL, 10) == - ((ev_int64_t)5000000)*-1000); - s = " 99999stuff"; - tt_want(evutil_strtoll(s, &endptr, 10) == (ev_int64_t)99999); - tt_want(endptr == s+6); - tt_want(evutil_strtoll("foo", NULL, 10) == 0); - } - -static void -test_evutil_snprintf(void *ptr) -{ - char buf[16]; - int r; - ev_uint64_t u64 = ((ev_uint64_t)1000000000)*200; - ev_int64_t i64 = -1 * (ev_int64_t) u64; - size_t size = 8000; - ev_ssize_t ssize = -9000; - - r = evutil_snprintf(buf, sizeof(buf), "%d %d", 50, 100); - tt_str_op(buf, ==, "50 100"); - tt_int_op(r, ==, 6); - - r = evutil_snprintf(buf, sizeof(buf), "longish %d", 1234567890); - tt_str_op(buf, ==, "longish 1234567"); - tt_int_op(r, ==, 18); - - r = evutil_snprintf(buf, sizeof(buf), EV_U64_FMT, EV_U64_ARG(u64)); - tt_str_op(buf, ==, "200000000000"); - tt_int_op(r, ==, 12); - - r = evutil_snprintf(buf, sizeof(buf), EV_I64_FMT, EV_I64_ARG(i64)); - tt_str_op(buf, ==, "-200000000000"); - tt_int_op(r, ==, 13); - - r = evutil_snprintf(buf, sizeof(buf), EV_SIZE_FMT" "EV_SSIZE_FMT, - EV_SIZE_ARG(size), EV_SSIZE_ARG(ssize)); - tt_str_op(buf, ==, "8000 -9000"); - tt_int_op(r, ==, 10); - - end: - ; -} - -static void -test_evutil_casecmp(void *ptr) -{ - tt_int_op(evutil_ascii_strcasecmp("ABC", "ABC"), ==, 0); - tt_int_op(evutil_ascii_strcasecmp("ABC", "abc"), ==, 0); - tt_int_op(evutil_ascii_strcasecmp("ABC", "abcd"), <, 0); - tt_int_op(evutil_ascii_strcasecmp("ABC", "abb"), >, 0); - tt_int_op(evutil_ascii_strcasecmp("ABCd", "abc"), >, 0); - - tt_int_op(evutil_ascii_strncasecmp("Libevent", "LibEvEnT", 100), ==, 0); - tt_int_op(evutil_ascii_strncasecmp("Libevent", "LibEvEnT", 4), ==, 0); - tt_int_op(evutil_ascii_strncasecmp("Libevent", "LibEXXXX", 4), ==, 0); - tt_int_op(evutil_ascii_strncasecmp("Libevent", "LibE", 4), ==, 0); - tt_int_op(evutil_ascii_strncasecmp("Libe", "LibEvEnT", 4), ==, 0); - tt_int_op(evutil_ascii_strncasecmp("Lib", "LibEvEnT", 4), <, 0); - tt_int_op(evutil_ascii_strncasecmp("abc", "def", 99), <, 0); - tt_int_op(evutil_ascii_strncasecmp("Z", "qrst", 1), >, 0); -end: - ; -} - -static void -test_evutil_rtrim(void *ptr) -{ -#define TEST_TRIM(s, result) \ - do { \ - if (cp) mm_free(cp); \ - cp = mm_strdup(s); \ - tt_assert(cp); \ - evutil_rtrim_lws_(cp); \ - tt_str_op(cp, ==, result); \ - } while(0) - - char *cp = NULL; - (void) ptr; - - TEST_TRIM("", ""); - TEST_TRIM("a", "a"); - TEST_TRIM("abcdef ghi", "abcdef ghi"); - - TEST_TRIM(" ", ""); - TEST_TRIM(" ", ""); - TEST_TRIM("a ", "a"); - TEST_TRIM("abcdef gH ", "abcdef gH"); - - TEST_TRIM("\t\t", ""); - TEST_TRIM(" \t", ""); - TEST_TRIM("\t", ""); - TEST_TRIM("a \t", "a"); - TEST_TRIM("a\t ", "a"); - TEST_TRIM("a\t", "a"); - TEST_TRIM("abcdef gH \t ", "abcdef gH"); - -end: - if (cp) - mm_free(cp); -} - -static int logsev = 0; -static char *logmsg = NULL; - -static void -logfn(int severity, const char *msg) -{ - logsev = severity; - tt_want(msg); - if (msg) { - if (logmsg) - free(logmsg); - logmsg = strdup(msg); - } -} - -static int fatal_want_severity = 0; -static const char *fatal_want_message = NULL; -static void -fatalfn(int exitcode) -{ - if (logsev != fatal_want_severity || - !logmsg || - strcmp(logmsg, fatal_want_message)) - exit(0); - else - exit(exitcode); -} - -#ifndef _WIN32 -#define CAN_CHECK_ERR -static void -check_error_logging(void (*fn)(void), int wantexitcode, - int wantseverity, const char *wantmsg) -{ - pid_t pid; - int status = 0, exitcode; - fatal_want_severity = wantseverity; - fatal_want_message = wantmsg; - if ((pid = regress_fork()) == 0) { - /* child process */ - fn(); - exit(0); /* should be unreachable. */ - } else { - wait(&status); - exitcode = WEXITSTATUS(status); - tt_int_op(wantexitcode, ==, exitcode); - } -end: - ; -} - -static void -errx_fn(void) -{ - event_errx(2, "Fatal error; too many kumquats (%d)", 5); -} - -static void -err_fn(void) -{ - errno = ENOENT; - event_err(5,"Couldn't open %s", "/very/bad/file"); -} - -static void -sock_err_fn(void) -{ - evutil_socket_t fd = socket(AF_INET, SOCK_STREAM, 0); -#ifdef _WIN32 - EVUTIL_SET_SOCKET_ERROR(WSAEWOULDBLOCK); -#else - errno = EAGAIN; -#endif - event_sock_err(20, fd, "Unhappy socket"); -} -#endif - -static void -test_evutil_log(void *ptr) -{ - evutil_socket_t fd = -1; - char buf[128]; - - event_set_log_callback(logfn); - event_set_fatal_callback(fatalfn); -#define RESET() do { \ - logsev = 0; \ - if (logmsg) free(logmsg); \ - logmsg = NULL; \ - } while (0) -#define LOGEQ(sev,msg) do { \ - tt_int_op(logsev,==,sev); \ - tt_assert(logmsg != NULL); \ - tt_str_op(logmsg,==,msg); \ - } while (0) - -#ifdef CAN_CHECK_ERR - /* We need to disable these tests for now. Previously, the logging - * module didn't enforce the requirement that a fatal callback - * actually exit. Now, it exits no matter what, so if we wan to - * reinstate these tests, we'll need to fork for each one. */ - check_error_logging(errx_fn, 2, EVENT_LOG_ERR, - "Fatal error; too many kumquats (5)"); - RESET(); -#endif - - event_warnx("Far too many %s (%d)", "wombats", 99); - LOGEQ(EVENT_LOG_WARN, "Far too many wombats (99)"); - RESET(); - - event_msgx("Connecting lime to coconut"); - LOGEQ(EVENT_LOG_MSG, "Connecting lime to coconut"); - RESET(); - - event_debug(("A millisecond passed! We should log that!")); -#ifdef USE_DEBUG - LOGEQ(EVENT_LOG_DEBUG, "A millisecond passed! We should log that!"); -#else - tt_int_op(logsev,==,0); - tt_ptr_op(logmsg,==,NULL); -#endif - RESET(); - - /* Try with an errno. */ - errno = ENOENT; - event_warn("Couldn't open %s", "/bad/file"); - evutil_snprintf(buf, sizeof(buf), - "Couldn't open /bad/file: %s",strerror(ENOENT)); - LOGEQ(EVENT_LOG_WARN,buf); - RESET(); - -#ifdef CAN_CHECK_ERR - evutil_snprintf(buf, sizeof(buf), - "Couldn't open /very/bad/file: %s",strerror(ENOENT)); - check_error_logging(err_fn, 5, EVENT_LOG_ERR, buf); - RESET(); -#endif - - /* Try with a socket errno. */ - fd = socket(AF_INET, SOCK_STREAM, 0); -#ifdef _WIN32 - evutil_snprintf(buf, sizeof(buf), - "Unhappy socket: %s", - evutil_socket_error_to_string(WSAEWOULDBLOCK)); - EVUTIL_SET_SOCKET_ERROR(WSAEWOULDBLOCK); -#else - evutil_snprintf(buf, sizeof(buf), - "Unhappy socket: %s", strerror(EAGAIN)); - errno = EAGAIN; -#endif - event_sock_warn(fd, "Unhappy socket"); - LOGEQ(EVENT_LOG_WARN, buf); - RESET(); - -#ifdef CAN_CHECK_ERR - check_error_logging(sock_err_fn, 20, EVENT_LOG_ERR, buf); - RESET(); -#endif - -#undef RESET -#undef LOGEQ -end: - if (logmsg) - free(logmsg); - if (fd >= 0) - evutil_closesocket(fd); -} - -static void -test_evutil_strlcpy(void *arg) -{ - char buf[8]; - - /* Successful case. */ - tt_int_op(5, ==, strlcpy(buf, "Hello", sizeof(buf))); - tt_str_op(buf, ==, "Hello"); - - /* Overflow by a lot. */ - tt_int_op(13, ==, strlcpy(buf, "pentasyllabic", sizeof(buf))); - tt_str_op(buf, ==, "pentasy"); - - /* Overflow by exactly one. */ - tt_int_op(8, ==, strlcpy(buf, "overlong", sizeof(buf))); - tt_str_op(buf, ==, "overlon"); -end: - ; -} - -struct example_struct { - const char *a; - const char *b; - long c; -}; - -static void -test_evutil_upcast(void *arg) -{ - struct example_struct es1; - const char **cp; - es1.a = "World"; - es1.b = "Hello"; - es1.c = -99; - - tt_int_op(evutil_offsetof(struct example_struct, b), ==, sizeof(char*)); - - cp = &es1.b; - tt_ptr_op(EVUTIL_UPCAST(cp, struct example_struct, b), ==, &es1); - -end: - ; -} - -static void -test_evutil_integers(void *arg) -{ - ev_int64_t i64; - ev_uint64_t u64; - ev_int32_t i32; - ev_uint32_t u32; - ev_int16_t i16; - ev_uint16_t u16; - ev_int8_t i8; - ev_uint8_t u8; - - void *ptr; - ev_intptr_t iptr; - ev_uintptr_t uptr; - - ev_ssize_t ssize; - - tt_int_op(sizeof(u64), ==, 8); - tt_int_op(sizeof(i64), ==, 8); - tt_int_op(sizeof(u32), ==, 4); - tt_int_op(sizeof(i32), ==, 4); - tt_int_op(sizeof(u16), ==, 2); - tt_int_op(sizeof(i16), ==, 2); - tt_int_op(sizeof(u8), ==, 1); - tt_int_op(sizeof(i8), ==, 1); - - tt_int_op(sizeof(ev_ssize_t), ==, sizeof(size_t)); - tt_int_op(sizeof(ev_intptr_t), >=, sizeof(void *)); - tt_int_op(sizeof(ev_uintptr_t), ==, sizeof(intptr_t)); - - u64 = 1000000000; - u64 *= 1000000000; - tt_assert(u64 / 1000000000 == 1000000000); - i64 = -1000000000; - i64 *= 1000000000; - tt_assert(i64 / 1000000000 == -1000000000); - - u64 = EV_UINT64_MAX; - i64 = EV_INT64_MAX; - tt_assert(u64 > 0); - tt_assert(i64 > 0); - u64++; -/* i64++; */ - tt_assert(u64 == 0); -/* tt_assert(i64 == EV_INT64_MIN); */ -/* tt_assert(i64 < 0); */ - - u32 = EV_UINT32_MAX; - i32 = EV_INT32_MAX; - tt_assert(u32 > 0); - tt_assert(i32 > 0); - u32++; -/* i32++; */ - tt_assert(u32 == 0); -/* tt_assert(i32 == EV_INT32_MIN); */ -/* tt_assert(i32 < 0); */ - - u16 = EV_UINT16_MAX; - i16 = EV_INT16_MAX; - tt_assert(u16 > 0); - tt_assert(i16 > 0); - u16++; -/* i16++; */ - tt_assert(u16 == 0); -/* tt_assert(i16 == EV_INT16_MIN); */ -/* tt_assert(i16 < 0); */ - - u8 = EV_UINT8_MAX; - i8 = EV_INT8_MAX; - tt_assert(u8 > 0); - tt_assert(i8 > 0); - u8++; -/* i8++;*/ - tt_assert(u8 == 0); -/* tt_assert(i8 == EV_INT8_MIN); */ -/* tt_assert(i8 < 0); */ - -/* - ssize = EV_SSIZE_MAX; - tt_assert(ssize > 0); - ssize++; - tt_assert(ssize < 0); - tt_assert(ssize == EV_SSIZE_MIN); -*/ - - ptr = &ssize; - iptr = (ev_intptr_t)ptr; - uptr = (ev_uintptr_t)ptr; - ptr = (void *)iptr; - tt_assert(ptr == &ssize); - ptr = (void *)uptr; - tt_assert(ptr == &ssize); - - iptr = -1; - tt_assert(iptr < 0); -end: - ; -} - -struct evutil_addrinfo * -ai_find_by_family(struct evutil_addrinfo *ai, int family) -{ - while (ai) { - if (ai->ai_family == family) - return ai; - ai = ai->ai_next; - } - return NULL; -} - -struct evutil_addrinfo * -ai_find_by_protocol(struct evutil_addrinfo *ai, int protocol) -{ - while (ai) { - if (ai->ai_protocol == protocol) - return ai; - ai = ai->ai_next; - } - return NULL; -} - - -int -test_ai_eq_(const struct evutil_addrinfo *ai, const char *sockaddr_port, - int socktype, int protocol, int line) -{ - struct sockaddr_storage ss; - int slen = sizeof(ss); - int gotport; - char buf[128]; - memset(&ss, 0, sizeof(ss)); - if (socktype > 0) - tt_int_op(ai->ai_socktype, ==, socktype); - if (protocol > 0) - tt_int_op(ai->ai_protocol, ==, protocol); - - if (evutil_parse_sockaddr_port( - sockaddr_port, (struct sockaddr*)&ss, &slen)<0) { - TT_FAIL(("Couldn't parse expected address %s on line %d", - sockaddr_port, line)); - return -1; - } - if (ai->ai_family != ss.ss_family) { - TT_FAIL(("Address family %d did not match %d on line %d", - ai->ai_family, ss.ss_family, line)); - return -1; - } - if (ai->ai_addr->sa_family == AF_INET) { - struct sockaddr_in *sin = (struct sockaddr_in*)ai->ai_addr; - evutil_inet_ntop(AF_INET, &sin->sin_addr, buf, sizeof(buf)); - gotport = ntohs(sin->sin_port); - if (ai->ai_addrlen != sizeof(struct sockaddr_in)) { - TT_FAIL(("Addr size mismatch on line %d", line)); - return -1; - } - } else { - struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)ai->ai_addr; - evutil_inet_ntop(AF_INET6, &sin6->sin6_addr, buf, sizeof(buf)); - gotport = ntohs(sin6->sin6_port); - if (ai->ai_addrlen != sizeof(struct sockaddr_in6)) { - TT_FAIL(("Addr size mismatch on line %d", line)); - return -1; - } - } - if (evutil_sockaddr_cmp(ai->ai_addr, (struct sockaddr*)&ss, 1)) { - TT_FAIL(("Wanted %s, got %s:%d on line %d", sockaddr_port, - buf, gotport, line)); - return -1; - } else { - TT_BLATHER(("Wanted %s, got %s:%d on line %d", sockaddr_port, - buf, gotport, line)); - } - return 0; -end: - TT_FAIL(("Test failed on line %d", line)); - return -1; -} - -static void -test_evutil_rand(void *arg) -{ - char buf1[32]; - char buf2[32]; - int counts[256]; - int i, j, k, n=0; - struct evutil_weakrand_state seed = { 12346789U }; - - memset(buf2, 0, sizeof(buf2)); - memset(counts, 0, sizeof(counts)); - - for (k=0;k<32;++k) { - /* Try a few different start and end points; try to catch - * the various misaligned cases of arc4random_buf */ - int startpoint = evutil_weakrand_(&seed) % 4; - int endpoint = 32 - (evutil_weakrand_(&seed) % 4); - - memset(buf2, 0, sizeof(buf2)); - - /* Do 6 runs over buf1, or-ing the result into buf2 each - * time, to make sure we're setting each byte that we mean - * to set. */ - for (i=0;i<8;++i) { - memset(buf1, 0, sizeof(buf1)); - evutil_secure_rng_get_bytes(buf1 + startpoint, - endpoint-startpoint); - n += endpoint - startpoint; - for (j=0; j<32; ++j) { - if (j >= startpoint && j < endpoint) { - buf2[j] |= buf1[j]; - ++counts[(unsigned char)buf1[j]]; - } else { - tt_assert(buf1[j] == 0); - tt_int_op(buf1[j], ==, 0); - - } - } - } - - /* This will give a false positive with P=(256**8)==(2**64) - * for each character. */ - for (j=startpoint;j<endpoint;++j) { - tt_int_op(buf2[j], !=, 0); - } - } - - evutil_weakrand_seed_(&seed, 0); - for (i = 0; i < 10000; ++i) { - ev_int32_t r = evutil_weakrand_range_(&seed, 9999); - tt_int_op(0, <=, r); - tt_int_op(r, <, 9999); - } - - /* for (i=0;i<256;++i) { printf("%3d %2d\n", i, counts[i]); } */ -end: - ; -} - -static void -test_evutil_getaddrinfo(void *arg) -{ - struct evutil_addrinfo *ai = NULL, *a; - struct evutil_addrinfo hints; - int r; - - /* Try using it as a pton. */ - memset(&hints, 0, sizeof(hints)); - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - r = evutil_getaddrinfo("1.2.3.4", "8080", &hints, &ai); - tt_int_op(r, ==, 0); - tt_assert(ai); - tt_ptr_op(ai->ai_next, ==, NULL); /* no ambiguity */ - test_ai_eq(ai, "1.2.3.4:8080", SOCK_STREAM, IPPROTO_TCP); - evutil_freeaddrinfo(ai); - ai = NULL; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = PF_UNSPEC; - hints.ai_protocol = IPPROTO_UDP; - r = evutil_getaddrinfo("1001:b0b::f00f", "4321", &hints, &ai); - tt_int_op(r, ==, 0); - tt_assert(ai); - tt_ptr_op(ai->ai_next, ==, NULL); /* no ambiguity */ - test_ai_eq(ai, "[1001:b0b::f00f]:4321", SOCK_DGRAM, IPPROTO_UDP); - evutil_freeaddrinfo(ai); - ai = NULL; - - /* Try out the behavior of nodename=NULL */ - memset(&hints, 0, sizeof(hints)); - hints.ai_family = PF_INET; - hints.ai_protocol = IPPROTO_TCP; - hints.ai_flags = EVUTIL_AI_PASSIVE; /* as if for bind */ - r = evutil_getaddrinfo(NULL, "9999", &hints, &ai); - tt_int_op(r,==,0); - tt_assert(ai); - tt_ptr_op(ai->ai_next, ==, NULL); - test_ai_eq(ai, "0.0.0.0:9999", SOCK_STREAM, IPPROTO_TCP); - evutil_freeaddrinfo(ai); - ai = NULL; - hints.ai_flags = 0; /* as if for connect */ - r = evutil_getaddrinfo(NULL, "9998", &hints, &ai); - tt_assert(ai); - tt_int_op(r,==,0); - test_ai_eq(ai, "127.0.0.1:9998", SOCK_STREAM, IPPROTO_TCP); - tt_ptr_op(ai->ai_next, ==, NULL); - evutil_freeaddrinfo(ai); - ai = NULL; - - hints.ai_flags = 0; /* as if for connect */ - hints.ai_family = PF_INET6; - r = evutil_getaddrinfo(NULL, "9997", &hints, &ai); - tt_assert(ai); - tt_int_op(r,==,0); - tt_ptr_op(ai->ai_next, ==, NULL); - test_ai_eq(ai, "[::1]:9997", SOCK_STREAM, IPPROTO_TCP); - evutil_freeaddrinfo(ai); - ai = NULL; - - hints.ai_flags = EVUTIL_AI_PASSIVE; /* as if for bind. */ - hints.ai_family = PF_INET6; - r = evutil_getaddrinfo(NULL, "9996", &hints, &ai); - tt_assert(ai); - tt_int_op(r,==,0); - tt_ptr_op(ai->ai_next, ==, NULL); - test_ai_eq(ai, "[::]:9996", SOCK_STREAM, IPPROTO_TCP); - evutil_freeaddrinfo(ai); - ai = NULL; - - /* Now try an unspec one. We should get a v6 and a v4. */ - hints.ai_family = PF_UNSPEC; - r = evutil_getaddrinfo(NULL, "9996", &hints, &ai); - tt_assert(ai); - tt_int_op(r,==,0); - a = ai_find_by_family(ai, PF_INET6); - tt_assert(a); - test_ai_eq(a, "[::]:9996", SOCK_STREAM, IPPROTO_TCP); - a = ai_find_by_family(ai, PF_INET); - tt_assert(a); - test_ai_eq(a, "0.0.0.0:9996", SOCK_STREAM, IPPROTO_TCP); - evutil_freeaddrinfo(ai); - ai = NULL; - - /* Try out AI_NUMERICHOST: successful case. Also try - * multiprotocol. */ - memset(&hints, 0, sizeof(hints)); - hints.ai_family = PF_UNSPEC; - hints.ai_flags = EVUTIL_AI_NUMERICHOST; - r = evutil_getaddrinfo("1.2.3.4", NULL, &hints, &ai); - tt_int_op(r, ==, 0); - a = ai_find_by_protocol(ai, IPPROTO_TCP); - tt_assert(a); - test_ai_eq(a, "1.2.3.4", SOCK_STREAM, IPPROTO_TCP); - a = ai_find_by_protocol(ai, IPPROTO_UDP); - tt_assert(a); - test_ai_eq(a, "1.2.3.4", SOCK_DGRAM, IPPROTO_UDP); - evutil_freeaddrinfo(ai); - ai = NULL; - - /* Try the failing case of AI_NUMERICHOST */ - memset(&hints, 0, sizeof(hints)); - hints.ai_family = PF_UNSPEC; - hints.ai_flags = EVUTIL_AI_NUMERICHOST; - r = evutil_getaddrinfo("www.google.com", "80", &hints, &ai); - tt_int_op(r, ==, EVUTIL_EAI_NONAME); - tt_ptr_op(ai, ==, NULL); - - /* Try symbolic service names wit AI_NUMERICSERV */ - memset(&hints, 0, sizeof(hints)); - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = EVUTIL_AI_NUMERICSERV; - r = evutil_getaddrinfo("1.2.3.4", "http", &hints, &ai); - tt_int_op(r,==,EVUTIL_EAI_NONAME); - - /* Try symbolic service names */ - memset(&hints, 0, sizeof(hints)); - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - r = evutil_getaddrinfo("1.2.3.4", "http", &hints, &ai); - if (r!=0) { - TT_DECLARE("SKIP", ("Symbolic service names seem broken.")); - } else { - tt_assert(ai); - test_ai_eq(ai, "1.2.3.4:80", SOCK_STREAM, IPPROTO_TCP); - evutil_freeaddrinfo(ai); - ai = NULL; - } - -end: - if (ai) - evutil_freeaddrinfo(ai); -} - -static void -test_evutil_getaddrinfo_live(void *arg) -{ - struct evutil_addrinfo *ai = NULL; - struct evutil_addrinfo hints; - - struct sockaddr_in6 *sin6; - struct sockaddr_in *sin; - char buf[128]; - const char *cp; - int r; - - /* Now do some actual lookups. */ - memset(&hints, 0, sizeof(hints)); - hints.ai_family = PF_INET; - hints.ai_protocol = IPPROTO_TCP; - hints.ai_socktype = SOCK_STREAM; - r = evutil_getaddrinfo("www.google.com", "80", &hints, &ai); - if (r != 0) { - TT_DECLARE("SKIP", ("Couldn't resolve www.google.com")); - } else { - tt_assert(ai); - tt_int_op(ai->ai_family, ==, PF_INET); - tt_int_op(ai->ai_protocol, ==, IPPROTO_TCP); - tt_int_op(ai->ai_socktype, ==, SOCK_STREAM); - tt_int_op(ai->ai_addrlen, ==, sizeof(struct sockaddr_in)); - sin = (struct sockaddr_in*)ai->ai_addr; - tt_int_op(sin->sin_family, ==, AF_INET); - tt_int_op(sin->sin_port, ==, htons(80)); - tt_int_op(sin->sin_addr.s_addr, !=, 0xffffffff); - - cp = evutil_inet_ntop(AF_INET, &sin->sin_addr, buf, sizeof(buf)); - TT_BLATHER(("www.google.com resolved to %s", - cp?cp:"<unwriteable>")); - evutil_freeaddrinfo(ai); - ai = NULL; - } - - hints.ai_family = PF_INET6; - r = evutil_getaddrinfo("ipv6.google.com", "80", &hints, &ai); - if (r != 0) { - TT_BLATHER(("Couldn't do an ipv6 lookup for ipv6.google.com")); - } else { - tt_assert(ai); - tt_int_op(ai->ai_family, ==, PF_INET6); - tt_int_op(ai->ai_addrlen, ==, sizeof(struct sockaddr_in6)); - sin6 = (struct sockaddr_in6*)ai->ai_addr; - tt_int_op(sin6->sin6_port, ==, htons(80)); - - cp = evutil_inet_ntop(AF_INET6, &sin6->sin6_addr, buf, - sizeof(buf)); - TT_BLATHER(("ipv6.google.com resolved to %s", - cp?cp:"<unwriteable>")); - } - -end: - if (ai) - evutil_freeaddrinfo(ai); -} - -#ifdef _WIN32 -static void -test_evutil_loadsyslib(void *arg) -{ - HMODULE h=NULL; - - h = evutil_load_windows_system_library_(TEXT("kernel32.dll")); - tt_assert(h); - -end: - if (h) - CloseHandle(h); - -} -#endif - -/** Test mm_malloc(). */ -static void -test_event_malloc(void *arg) -{ - void *p = NULL; - (void)arg; - - /* mm_malloc(0) should simply return NULL. */ -#ifndef EVENT__DISABLE_MM_REPLACEMENT - errno = 0; - p = mm_malloc(0); - tt_assert(p == NULL); - tt_int_op(errno, ==, 0); -#endif - - /* Trivial case. */ - errno = 0; - p = mm_malloc(8); - tt_assert(p != NULL); - tt_int_op(errno, ==, 0); - mm_free(p); - - end: - errno = 0; - return; -} - -static void -test_event_calloc(void *arg) -{ - void *p = NULL; - (void)arg; - -#ifndef EVENT__DISABLE_MM_REPLACEMENT - /* mm_calloc() should simply return NULL - * if either argument is zero. */ - errno = 0; - p = mm_calloc(0, 0); - tt_assert(p == NULL); - tt_int_op(errno, ==, 0); - errno = 0; - p = mm_calloc(0, 1); - tt_assert(p == NULL); - tt_int_op(errno, ==, 0); - errno = 0; - p = mm_calloc(1, 0); - tt_assert(p == NULL); - tt_int_op(errno, ==, 0); -#endif - - /* Trivial case. */ - errno = 0; - p = mm_calloc(8, 8); - tt_assert(p != NULL); - tt_int_op(errno, ==, 0); - mm_free(p); - p = NULL; - - /* mm_calloc() should set errno = ENOMEM and return NULL - * in case of potential overflow. */ - errno = 0; - p = mm_calloc(EV_SIZE_MAX/2, EV_SIZE_MAX/2 + 8); - tt_assert(p == NULL); - tt_int_op(errno, ==, ENOMEM); - - end: - errno = 0; - if (p) - mm_free(p); - - return; -} - -static void -test_event_strdup(void *arg) -{ - void *p = NULL; - (void)arg; - -#ifndef EVENT__DISABLE_MM_REPLACEMENT - /* mm_strdup(NULL) should set errno = EINVAL and return NULL. */ - errno = 0; - p = mm_strdup(NULL); - tt_assert(p == NULL); - tt_int_op(errno, ==, EINVAL); -#endif - - /* Trivial cases. */ - - errno = 0; - p = mm_strdup(""); - tt_assert(p != NULL); - tt_int_op(errno, ==, 0); - tt_str_op(p, ==, ""); - mm_free(p); - - errno = 0; - p = mm_strdup("foo"); - tt_assert(p != NULL); - tt_int_op(errno, ==, 0); - tt_str_op(p, ==, "foo"); - mm_free(p); - - /* XXX - * mm_strdup(str) where str is a string of length EV_SIZE_MAX - * should set errno = ENOMEM and return NULL. */ - - end: - errno = 0; - return; -} - -static void -test_evutil_usleep(void *arg) -{ - struct timeval tv1, tv2, tv3, diff1, diff2; - const struct timeval quarter_sec = {0, 250*1000}; - const struct timeval tenth_sec = {0, 100*1000}; - long usec1, usec2; - - evutil_gettimeofday(&tv1, NULL); - evutil_usleep_(&quarter_sec); - evutil_gettimeofday(&tv2, NULL); - evutil_usleep_(&tenth_sec); - evutil_gettimeofday(&tv3, NULL); - - evutil_timersub(&tv2, &tv1, &diff1); - evutil_timersub(&tv3, &tv2, &diff2); - usec1 = diff1.tv_sec * 1000000 + diff1.tv_usec; - usec2 = diff2.tv_sec * 1000000 + diff2.tv_usec; - - tt_int_op(usec1, >, 200000); - tt_int_op(usec1, <, 300000); - tt_int_op(usec2, >, 80000); - tt_int_op(usec2, <, 120000); - -end: - ; -} - -static void -test_evutil_monotonic_res(void *data_) -{ - /* Basic santity-test for monotonic timers. What we'd really like - * to do is make sure that they can't go backwards even when the - * system clock goes backwards. But we haven't got a good way to - * move the system clock backwards. - */ - struct basic_test_data *data = data_; - struct evutil_monotonic_timer timer; - const int precise = strstr(data->setup_data, "precise") != NULL; - const int fallback = strstr(data->setup_data, "fallback") != NULL; - struct timeval tv[10], delay; - int total_diff = 0; - - int flags = 0, wantres, acceptdiff, i; - if (precise) - flags |= EV_MONOT_PRECISE; - if (fallback) - flags |= EV_MONOT_FALLBACK; - if (precise || fallback) { -#ifdef _WIN32 - wantres = 10*1000; - acceptdiff = 1000; -#else - wantres = 1000; - acceptdiff = 300; -#endif - } else { - wantres = 40*1000; - acceptdiff = 20*1000; - } - - TT_BLATHER(("Precise = %d", precise)); - TT_BLATHER(("Fallback = %d", fallback)); - - /* First, make sure we match up with usleep. */ - - delay.tv_sec = 0; - delay.tv_usec = wantres; - - tt_int_op(evutil_configure_monotonic_time_(&timer, flags), ==, 0); - - for (i = 0; i < 10; ++i) { - evutil_gettime_monotonic_(&timer, &tv[i]); - evutil_usleep_(&delay); - } - - for (i = 0; i < 9; ++i) { - struct timeval diff; - tt_assert(evutil_timercmp(&tv[i], &tv[i+1], <)); - evutil_timersub(&tv[i+1], &tv[i], &diff); - tt_int_op(diff.tv_sec, ==, 0); - total_diff += diff.tv_usec; - TT_BLATHER(("Difference = %d", (int)diff.tv_usec)); - } - tt_int_op(abs(total_diff/9 - wantres), <, acceptdiff); - -end: - ; -} - -static void -test_evutil_monotonic_prc(void *data_) -{ - struct basic_test_data *data = data_; - struct evutil_monotonic_timer timer; - const int precise = strstr(data->setup_data, "precise") != NULL; - const int fallback = strstr(data->setup_data, "fallback") != NULL; - struct timeval tv[10]; - int total_diff = 0; - int i, maxstep = 25*1000,flags=0; - if (precise) - maxstep = 500; - if (precise) - flags |= EV_MONOT_PRECISE; - if (fallback) - flags |= EV_MONOT_FALLBACK; - tt_int_op(evutil_configure_monotonic_time_(&timer, flags), ==, 0); - - /* find out what precision we actually see. */ - - evutil_gettime_monotonic_(&timer, &tv[0]); - for (i = 1; i < 10; ++i) { - do { - evutil_gettime_monotonic_(&timer, &tv[i]); - } while (evutil_timercmp(&tv[i-1], &tv[i], ==)); - } - - total_diff = 0; - for (i = 0; i < 9; ++i) { - struct timeval diff; - tt_assert(evutil_timercmp(&tv[i], &tv[i+1], <)); - evutil_timersub(&tv[i+1], &tv[i], &diff); - tt_int_op(diff.tv_sec, ==, 0); - total_diff += diff.tv_usec; - TT_BLATHER(("Step difference = %d", (int)diff.tv_usec)); - } - TT_BLATHER(("Average step difference = %d", total_diff / 9)); - tt_int_op(total_diff/9, <, maxstep); - -end: - ; -} - -struct testcase_t util_testcases[] = { - { "ipv4_parse", regress_ipv4_parse, 0, NULL, NULL }, - { "ipv6_parse", regress_ipv6_parse, 0, NULL, NULL }, - { "sockaddr_port_parse", regress_sockaddr_port_parse, 0, NULL, NULL }, - { "sockaddr_port_format", regress_sockaddr_port_format, 0, NULL, NULL }, - { "sockaddr_predicates", test_evutil_sockaddr_predicates, 0,NULL,NULL }, - { "evutil_snprintf", test_evutil_snprintf, 0, NULL, NULL }, - { "evutil_strtoll", test_evutil_strtoll, 0, NULL, NULL }, - { "evutil_casecmp", test_evutil_casecmp, 0, NULL, NULL }, - { "evutil_rtrim", test_evutil_rtrim, 0, NULL, NULL }, - { "strlcpy", test_evutil_strlcpy, 0, NULL, NULL }, - { "log", test_evutil_log, TT_FORK, NULL, NULL }, - { "upcast", test_evutil_upcast, 0, NULL, NULL }, - { "integers", test_evutil_integers, 0, NULL, NULL }, - { "rand", test_evutil_rand, TT_FORK, NULL, NULL }, - { "getaddrinfo", test_evutil_getaddrinfo, TT_FORK, NULL, NULL }, - { "getaddrinfo_live", test_evutil_getaddrinfo_live, TT_FORK|TT_OFF_BY_DEFAULT, NULL, NULL }, -#ifdef _WIN32 - { "loadsyslib", test_evutil_loadsyslib, TT_FORK, NULL, NULL }, -#endif - { "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 }, - { "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_fallback", test_evutil_monotonic_prc, 0, &basic_setup, (void*)"fallback" }, - END_OF_TESTCASES, -}; - diff --git a/protocols/Telegram/tgl/libevent/test/regress_util.obj b/protocols/Telegram/tgl/libevent/test/regress_util.obj Binary files differdeleted file mode 100644 index 79a948f2a5..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress_util.obj +++ /dev/null diff --git a/protocols/Telegram/tgl/libevent/test/regress_zlib.c b/protocols/Telegram/tgl/libevent/test/regress_zlib.c deleted file mode 100644 index 8406676932..0000000000 --- a/protocols/Telegram/tgl/libevent/test/regress_zlib.c +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Copyright (c) 2008-2012 Niels Provos and Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* The old tests here need assertions to work. */ -#undef NDEBUG - -#ifdef _WIN32 -#include <winsock2.h> -#include <windows.h> -#endif - -#include "event2/event-config.h" - -#include <sys/types.h> -#ifndef _WIN32 -#include <sys/socket.h> -#include <sys/wait.h> -#include <unistd.h> -#include <netdb.h> -#endif -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <assert.h> -#include <errno.h> - -#include "event2/util.h" -#include "event2/event.h" -#include "event2/event_compat.h" -#include "event2/buffer.h" -#include "event2/bufferevent.h" - -#include "regress.h" -#include "mm-internal.h" - -/* zlib 1.2.4 and 1.2.5 do some "clever" things with macros. Instead of - saying "(defined(FOO) ? FOO : 0)" they like to say "FOO-0", on the theory - that nobody will care if the compile outputs a no-such-identifier warning. - - Sorry, but we like -Werror over here, so I guess we need to define these. - I hope that zlib 1.2.6 doesn't break these too. -*/ -#ifndef _LARGEFILE64_SOURCE -#define _LARGEFILE64_SOURCE 0 -#endif -#ifndef _LFS64_LARGEFILE -#define _LFS64_LARGEFILE 0 -#endif -#ifndef _FILE_OFFSET_BITS -#define _FILE_OFFSET_BITS 0 -#endif -#ifndef off64_t -#define off64_t ev_int64_t -#endif - -#include <zlib.h> - -static int infilter_calls; -static int outfilter_calls; -static int readcb_finished; -static int writecb_finished; -static int errorcb_invoked; - -/* - * Zlib filters - */ - -static void -zlib_deflate_free(void *ctx) -{ - z_streamp p = ctx; - - assert(deflateEnd(p) == Z_OK); - mm_free(p); -} - -static void -zlib_inflate_free(void *ctx) -{ - z_streamp p = ctx; - - assert(inflateEnd(p) == Z_OK); - mm_free(p); -} - -static int -getstate(enum bufferevent_flush_mode state) -{ - switch (state) { - case BEV_FINISHED: - return Z_FINISH; - case BEV_FLUSH: - return Z_SYNC_FLUSH; - case BEV_NORMAL: - default: - return Z_NO_FLUSH; - } -} - -/* - * The input filter is triggered only on new input read from the network. - * That means all input data needs to be consumed or the filter needs to - * initiate its own triggering via a timeout. - */ -static enum bufferevent_filter_result -zlib_input_filter(struct evbuffer *src, struct evbuffer *dst, - ev_ssize_t lim, enum bufferevent_flush_mode state, void *ctx) -{ - struct evbuffer_iovec v_in[1]; - struct evbuffer_iovec v_out[1]; - int nread, nwrite; - int res, n; - - z_streamp p = ctx; - - do { - /* let's do some decompression */ - n = evbuffer_peek(src, -1, NULL, v_in, 1); - if (n) { - p->avail_in = v_in[0].iov_len; - p->next_in = v_in[0].iov_base; - } else { - p->avail_in = 0; - p->next_in = 0; - } - - evbuffer_reserve_space(dst, 4096, v_out, 1); - p->next_out = v_out[0].iov_base; - p->avail_out = v_out[0].iov_len; - - /* we need to flush zlib if we got a flush */ - res = inflate(p, getstate(state)); - - /* let's figure out how much was compressed */ - nread = v_in[0].iov_len - p->avail_in; - nwrite = v_out[0].iov_len - p->avail_out; - - evbuffer_drain(src, nread); - v_out[0].iov_len = nwrite; - evbuffer_commit_space(dst, v_out, 1); - - if (res==Z_BUF_ERROR) { - /* We're out of space, or out of decodeable input. - Only if nwrite == 0 assume the latter. - */ - if (nwrite == 0) - return BEV_NEED_MORE; - } else { - assert(res == Z_OK || res == Z_STREAM_END); - } - - } while (evbuffer_get_length(src) > 0); - - ++infilter_calls; - - return (BEV_OK); -} - -static enum bufferevent_filter_result -zlib_output_filter(struct evbuffer *src, struct evbuffer *dst, - ev_ssize_t lim, enum bufferevent_flush_mode state, void *ctx) -{ - struct evbuffer_iovec v_in[1]; - struct evbuffer_iovec v_out[1]; - int nread, nwrite; - int res, n; - - z_streamp p = ctx; - - do { - /* let's do some compression */ - n = evbuffer_peek(src, -1, NULL, v_in, 1); - if (n) { - p->avail_in = v_in[0].iov_len; - p->next_in = v_in[0].iov_base; - } else { - p->avail_in = 0; - p->next_in = 0; - } - - evbuffer_reserve_space(dst, 4096, v_out, 1); - p->next_out = v_out[0].iov_base; - p->avail_out = v_out[0].iov_len; - - /* we need to flush zlib if we got a flush */ - res = deflate(p, getstate(state)); - - /* let's figure out how much was decompressed */ - nread = v_in[0].iov_len - p->avail_in; - nwrite = v_out[0].iov_len - p->avail_out; - - evbuffer_drain(src, nread); - v_out[0].iov_len = nwrite; - evbuffer_commit_space(dst, v_out, 1); - - if (res==Z_BUF_ERROR) { - /* We're out of space, or out of decodeable input. - Only if nwrite == 0 assume the latter. - */ - if (nwrite == 0) - return BEV_NEED_MORE; - } else { - assert(res == Z_OK || res == Z_STREAM_END); - } - - } while (evbuffer_get_length(src) > 0); - - ++outfilter_calls; - - return (BEV_OK); -} - -/* - * simple bufferevent test (over transparent zlib treatment) - */ - -static void -readcb(struct bufferevent *bev, void *arg) -{ - if (evbuffer_get_length(bufferevent_get_input(bev)) == 8333) { - struct evbuffer *evbuf = evbuffer_new(); - assert(evbuf != NULL); - - /* gratuitous test of bufferevent_read_buffer */ - bufferevent_read_buffer(bev, evbuf); - - bufferevent_disable(bev, EV_READ); - - if (evbuffer_get_length(evbuf) == 8333) { - ++readcb_finished; - } - - evbuffer_free(evbuf); - } -} - -static void -writecb(struct bufferevent *bev, void *arg) -{ - if (evbuffer_get_length(bufferevent_get_output(bev)) == 0) { - ++writecb_finished; - } -} - -static void -errorcb(struct bufferevent *bev, short what, void *arg) -{ - errorcb_invoked = 1; -} - -void -test_bufferevent_zlib(void *arg) -{ - struct bufferevent *bev1=NULL, *bev2=NULL; - char buffer[8333]; - z_stream *z_input, *z_output; - int i, r; - evutil_socket_t pair[2] = {-1, -1}; - (void)arg; - - infilter_calls = outfilter_calls = readcb_finished = writecb_finished - = errorcb_invoked = 0; - - if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) { - tt_abort_perror("socketpair"); - } - - evutil_make_socket_nonblocking(pair[0]); - evutil_make_socket_nonblocking(pair[1]); - - bev1 = bufferevent_socket_new(NULL, pair[0], 0); - bev2 = bufferevent_socket_new(NULL, pair[1], 0); - - z_output = mm_calloc(sizeof(*z_output), 1); - r = deflateInit(z_output, Z_DEFAULT_COMPRESSION); - tt_int_op(r, ==, Z_OK); - z_input = mm_calloc(sizeof(*z_input), 1); - r = inflateInit(z_input); - tt_int_op(r, ==, Z_OK); - - /* initialize filters */ - bev1 = bufferevent_filter_new(bev1, NULL, zlib_output_filter, - BEV_OPT_CLOSE_ON_FREE, zlib_deflate_free, z_output); - bev2 = bufferevent_filter_new(bev2, zlib_input_filter, - NULL, BEV_OPT_CLOSE_ON_FREE, zlib_inflate_free, z_input); - bufferevent_setcb(bev1, readcb, writecb, errorcb, NULL); - bufferevent_setcb(bev2, readcb, writecb, errorcb, NULL); - - bufferevent_disable(bev1, EV_READ); - bufferevent_enable(bev1, EV_WRITE); - - bufferevent_enable(bev2, EV_READ); - - for (i = 0; i < (int)sizeof(buffer); i++) - buffer[i] = i; - - /* break it up into multiple buffer chains */ - bufferevent_write(bev1, buffer, 1800); - bufferevent_write(bev1, buffer + 1800, sizeof(buffer) - 1800); - - /* we are done writing - we need to flush everything */ - bufferevent_flush(bev1, EV_WRITE, BEV_FINISHED); - - event_dispatch(); - - tt_want(infilter_calls); - tt_want(outfilter_calls); - tt_want(readcb_finished); - tt_want(writecb_finished); - tt_want(!errorcb_invoked); - - test_ok = 1; -end: - if (bev1) - bufferevent_free(bev1); - if (bev2) - bufferevent_free(bev2); - - if (pair[0] >= 0) - evutil_closesocket(pair[0]); - if (pair[1] >= 0) - evutil_closesocket(pair[1]); -} diff --git a/protocols/Telegram/tgl/libevent/test/rpcgen_wrapper.sh b/protocols/Telegram/tgl/libevent/test/rpcgen_wrapper.sh deleted file mode 100644 index aaa03031a1..0000000000 --- a/protocols/Telegram/tgl/libevent/test/rpcgen_wrapper.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/bin/sh -# libevent rpcgen_wrapper.sh -# Transforms event_rpcgen.py failure into success for make, only if -# regress.gen.c and regress.gen.h already exist in $srcdir. This -# is needed for "make distcheck" to pass the read-only $srcdir build, -# as with read-only sources fresh from tarball, regress.gen.[ch] will -# be correct in $srcdir but unwritable. This previously triggered -# Makefile.am to create stub regress.gen.c and regress.gen.h in the -# distcheck _build directory, which were then detected as leftover -# files in the build tree after distclean, breaking distcheck. -# Note that regress.gen.[ch] are not in fresh git clones, making -# working Python a requirement for make distcheck of a git tree. - -exit_updated() { -# echo "Updated ${srcdir}/regress.gen.c and ${srcdir}/regress.gen.h" - exit 0 -} - -exit_reuse() { - echo "event_rpcgen.py failed, ${srcdir}/regress.gen.\[ch\] will be reused." >&2 - exit 0 -} - -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 \ - test/regress.gen.h test/regress.gen.c - -case "$?" in - 0) - exit_updated - ;; - *) - test -r ${srcdir}/regress.gen.c -a -r ${srcdir}/regress.gen.h && \ - exit_reuse - exit_failed - ;; -esac diff --git a/protocols/Telegram/tgl/libevent/test/test-changelist.c b/protocols/Telegram/tgl/libevent/test/test-changelist.c deleted file mode 100644 index 6e2466d5a5..0000000000 --- a/protocols/Telegram/tgl/libevent/test/test-changelist.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (c) 2010-2012 Niels Provos and Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "event2/event-config.h" - -#ifdef _WIN32 -#include <winsock2.h> -#include <windows.h> -#else -#include <unistd.h> -#endif -#include <sys/types.h> -#include <sys/stat.h> -#ifdef EVENT__HAVE_SYS_TIME_H -#include <sys/time.h> -#endif - -#ifdef EVENT__HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#include <fcntl.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> - -#include "event2/event.h" -#include "event2/util.h" -#include <time.h> - -struct cpu_usage_timer { -#ifdef _WIN32 - HANDLE thread; - FILETIME usertimeBegin; - FILETIME kerneltimeBegin; -#else - clock_t ticksBegin; -#endif - struct timeval timeBegin; -}; -static void -start_cpu_usage_timer(struct cpu_usage_timer *timer) -{ -#ifdef _WIN32 - int r; - FILETIME createtime, exittime; - timer->thread = GetCurrentThread(); - r = GetThreadTimes(timer->thread, &createtime, &exittime, - &timer->usertimeBegin, &timer->kerneltimeBegin); - if (r==0) printf("GetThreadTimes failed."); -#else - timer->ticksBegin = clock(); -#endif - - evutil_gettimeofday(&timer->timeBegin, NULL); -} -#ifdef _WIN32 -static ev_int64_t -filetime_to_100nsec(const FILETIME *ft) -{ - /* Number of 100-nanosecond units */ - ev_int64_t n = ft->dwHighDateTime; - n <<= 32; - n += ft->dwLowDateTime; - return n; -} -static double -filetime_diff(const FILETIME *ftStart, const FILETIME *ftEnd) -{ - ev_int64_t s, e, diff; - double r; - s = filetime_to_100nsec(ftStart); - e = filetime_to_100nsec(ftEnd); - diff = e - s; - r = (double) diff; - return r / 1.0e7; -} -#endif - -static void -get_cpu_usage(struct cpu_usage_timer *timer, double *secElapsedOut, - double *secUsedOut, double *usageOut) -{ -#ifdef _WIN32 - double usertime_seconds, kerneltime_seconds; - FILETIME createtime, exittime, usertimeEnd, kerneltimeEnd; - int r; -#else - clock_t ticksEnd; -#endif - struct timeval timeEnd, timeDiff; - double secondsPassed, secondsUsed; - -#ifdef _WIN32 - r = GetThreadTimes(timer->thread, &createtime, &exittime, - &usertimeEnd, &kerneltimeEnd); - if (r==0) printf("GetThreadTimes failed."); - usertime_seconds = filetime_diff(&timer->usertimeBegin, &usertimeEnd); - kerneltime_seconds = filetime_diff(&timer->kerneltimeBegin, &kerneltimeEnd); - secondsUsed = kerneltime_seconds + usertime_seconds; -#else - ticksEnd = clock(); - secondsUsed = (ticksEnd - timer->ticksBegin) / (double)CLOCKS_PER_SEC; -#endif - evutil_gettimeofday(&timeEnd, NULL); - evutil_timersub(&timeEnd, &timer->timeBegin, &timeDiff); - secondsPassed = timeDiff.tv_sec + (timeDiff.tv_usec / 1.0e6); - - *secElapsedOut = secondsPassed; - *secUsedOut = secondsUsed; - *usageOut = secondsUsed / secondsPassed; -} - -static void -write_cb(evutil_socket_t fd, short event, void *arg) -{ - printf("write callback. should only see this once\n"); - - /* got what we want remove the event */ - event_del(*(struct event**)arg); - - /* opps changed my mind add it back again */ - event_add(*(struct event**)arg,NULL); - - /* not a good day for decisiveness, I really didn't want it after all */ - event_del(*(struct event**)arg); - -} - -static void -timeout_cb(evutil_socket_t fd, short event, void *arg) -{ - printf("timeout fired, time to end test\n"); - event_del(*(struct event**)arg); - return; -} - -int -main(int argc, char **argv) -{ - struct event* ev; - struct event* timeout; - struct event_base* base; - - evutil_socket_t pair[2]; - struct timeval tv; - struct cpu_usage_timer timer; - - double usage, secPassed, secUsed; - -#ifdef _WIN32 - WORD wVersionRequested; - WSADATA wsaData; - - wVersionRequested = MAKEWORD(2, 2); - - (void) WSAStartup(wVersionRequested, &wsaData); -#endif - if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) - return (1); - - /* Initalize the event library */ - if (!(base = event_base_new())) - return (1); - - /* Initalize a timeout to terminate the test */ - timeout = evtimer_new(base,timeout_cb,&timeout); - /* and watch for writability on one end of the pipe */ - ev = event_new(base,pair[1],EV_WRITE | EV_PERSIST, write_cb, &ev); - - tv.tv_sec = 1; - tv.tv_usec = 500*1000; - - evtimer_add(timeout, &tv); - - event_add(ev, NULL); - - start_cpu_usage_timer(&timer); - - event_base_dispatch(base); - - event_free(ev); - event_free(timeout); - event_base_free(base); - - get_cpu_usage(&timer, &secPassed, &secUsed, &usage); - - /* attempt to calculate our cpu usage over the test should be - virtually nil */ - - printf("usec used=%d, usec passed=%d, cpu usage=%.2f%%\n", - (int)(secUsed*1e6), - (int)(secPassed*1e6), - usage*100); - - if (usage > 50.0) /* way too high */ - return 1; - - return 0; -} - diff --git a/protocols/Telegram/tgl/libevent/test/test-changelist.exe b/protocols/Telegram/tgl/libevent/test/test-changelist.exe Binary files differdeleted file mode 100644 index 2adeacc62f..0000000000 --- a/protocols/Telegram/tgl/libevent/test/test-changelist.exe +++ /dev/null diff --git a/protocols/Telegram/tgl/libevent/test/test-changelist.obj b/protocols/Telegram/tgl/libevent/test/test-changelist.obj Binary files differdeleted file mode 100644 index d5e1a181f6..0000000000 --- a/protocols/Telegram/tgl/libevent/test/test-changelist.obj +++ /dev/null diff --git a/protocols/Telegram/tgl/libevent/test/test-closed.c b/protocols/Telegram/tgl/libevent/test/test-closed.c deleted file mode 100644 index 5b04f354ac..0000000000 --- a/protocols/Telegram/tgl/libevent/test/test-closed.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2002-2007 Niels Provos <provos@citi.umich.edu> - * Copyright (c) 2007-2013 Niels Provos and Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "event2/event-config.h" - -#ifdef _WIN32 -#include <winsock2.h> -#else -#include <unistd.h> -#endif -#include <sys/types.h> -#include <sys/stat.h> -#ifdef EVENT__HAVE_SYS_TIME_H -#include <sys/time.h> -#endif -#ifdef EVENT__HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#include <fcntl.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> - -#include <event.h> -#include <evutil.h> - -#ifdef EVENT____func__ -#define __func__ EVENT____func__ -#endif - -struct timeval timeout = {3, 0}; - -static void -closed_cb(evutil_socket_t fd, short event, void *arg) -{ - if (EV_TIMEOUT & event) { - printf("%s: Timeout!\n", __func__); - exit(1); - } - - if (EV_CLOSED & event) { - printf("%s: detected socket close with success\n", __func__); - return; - } - - printf("%s: unable to detect socket close\n", __func__); - exit(1); -} - -#ifndef SHUT_WR -#define SHUT_WR 1 -#endif - -int -main(int argc, char **argv) -{ - struct event_base *base; - struct event_config *cfg; - struct event *ev; - const char *test = "test string"; - evutil_socket_t pair[2]; - - /* Initialize the library and check if the backend - supports EV_FEATURE_EARLY_CLOSE - */ - cfg = event_config_new(); - event_config_require_features(cfg, EV_FEATURE_EARLY_CLOSE); - base = event_base_new_with_config(cfg); - event_config_free(cfg); - if (!base) { - /* Backend doesn't support EV_FEATURE_EARLY_CLOSE */ - return 0; - } - - /* Create a pair of sockets */ - if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) - return (1); - - /* Send some data on socket 0 and immediately close it */ - if (send(pair[0], test, (int)strlen(test)+1, 0) < 0) - return (1); - shutdown(pair[0], SHUT_WR); - - /* Dispatch */ - ev = event_new(base, pair[1], EV_CLOSED | EV_TIMEOUT, closed_cb, event_self_cbarg()); - event_add(ev, &timeout); - event_base_dispatch(base); - - /* Finalize library */ - event_base_free(base); - return 0; -} - diff --git a/protocols/Telegram/tgl/libevent/test/test-closed.exe b/protocols/Telegram/tgl/libevent/test/test-closed.exe Binary files differdeleted file mode 100644 index 68bd7e1de1..0000000000 --- a/protocols/Telegram/tgl/libevent/test/test-closed.exe +++ /dev/null diff --git a/protocols/Telegram/tgl/libevent/test/test-closed.obj b/protocols/Telegram/tgl/libevent/test/test-closed.obj Binary files differdeleted file mode 100644 index 3894c88833..0000000000 --- a/protocols/Telegram/tgl/libevent/test/test-closed.obj +++ /dev/null diff --git a/protocols/Telegram/tgl/libevent/test/test-dumpevents.c b/protocols/Telegram/tgl/libevent/test/test-dumpevents.c deleted file mode 100644 index 1c272d4c01..0000000000 --- a/protocols/Telegram/tgl/libevent/test/test-dumpevents.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (c) 2012 Niels Provos and Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "util-internal.h" -#include "event2/event-config.h" - -#ifdef _WIN32 -#include <winsock2.h> -#include <windows.h> -#else -#include <unistd.h> -#endif - -#include <stdio.h> -#include <event2/event.h> -#include <signal.h> - -static void -sock_perror(const char *s) -{ -#ifdef _WIN32 - const char *err = evutil_socket_error_to_string(EVUTIL_SOCKET_ERROR()); - fprintf(stderr, "%s: %s\n", s, err); -#else - perror(s); -#endif -} - -static void -callback1(evutil_socket_t fd, short events, void *arg) -{ -} -static void -callback2(evutil_socket_t fd, short events, void *arg) -{ -} - -/* Testing code for event_base_dump_events(). - - Notes that just because we have code to exercise this function, - doesn't mean that *ANYTHING* about the output format is guaranteed to - remain in the future. - */ -int -main(int argc, char **argv) -{ -#define N_EVENTS 13 - int i; - struct event *ev[N_EVENTS]; - evutil_socket_t pair1[2]; - evutil_socket_t pair2[2]; - struct timeval tv_onesec = {1,0}; - struct timeval tv_two5sec = {2,500*1000}; - const struct timeval *tv_onesec_common; - const struct timeval *tv_two5sec_common; - struct event_base *base; - struct timeval now; - -#ifdef _WIN32 - WORD wVersionRequested; - WSADATA wsaData; - - wVersionRequested = MAKEWORD(2, 2); - - WSAStartup(wVersionRequested, &wsaData); -#endif - -#ifdef _WIN32 -#define LOCAL_SOCKETPAIR_AF AF_INET -#else -#define LOCAL_SOCKETPAIR_AF AF_UNIX -#endif - - if (evutil_make_internal_pipe_(pair1) < 0 || - evutil_make_internal_pipe_(pair2) < 0) { - sock_perror("evutil_make_internal_pipe_"); - return 1; - } - - if (!(base = event_base_new())) { - fprintf(stderr,"Couldn't make event_base\n"); - return 2; - } - - tv_onesec_common = event_base_init_common_timeout(base, &tv_onesec); - tv_two5sec_common = event_base_init_common_timeout(base, &tv_two5sec); - - ev[0] = event_new(base, pair1[0], EV_WRITE, callback1, NULL); - ev[1] = event_new(base, pair1[1], EV_READ|EV_PERSIST, callback1, NULL); - ev[2] = event_new(base, pair2[0], EV_WRITE|EV_PERSIST, callback2, NULL); - ev[3] = event_new(base, pair2[1], EV_READ, callback2, NULL); - - /* For timers */ - ev[4] = evtimer_new(base, callback1, NULL); - ev[5] = evtimer_new(base, callback1, NULL); - ev[6] = evtimer_new(base, callback1, NULL); - ev[7] = event_new(base, -1, EV_PERSIST, callback2, NULL); - ev[8] = event_new(base, -1, EV_PERSIST, callback2, NULL); - ev[9] = event_new(base, -1, EV_PERSIST, callback2, NULL); - - /* To activate */ - ev[10] = event_new(base, -1, 0, callback1, NULL); - ev[11] = event_new(base, -1, 0, callback2, NULL); - - /* Signals */ - ev[12] = evsignal_new(base, SIGINT, callback2, NULL); - - event_add(ev[0], NULL); - event_add(ev[1], &tv_onesec); - event_add(ev[2], tv_onesec_common); - event_add(ev[3], tv_two5sec_common); - - event_add(ev[4], tv_onesec_common); - event_add(ev[5], tv_onesec_common); - event_add(ev[6], &tv_onesec); - event_add(ev[7], tv_two5sec_common); - event_add(ev[8], tv_onesec_common); - event_add(ev[9], &tv_two5sec); - - event_active(ev[10], EV_READ, 1); - event_active(ev[11], EV_READ|EV_WRITE|EV_TIMEOUT, 1); - event_active(ev[1], EV_READ, 1); - - event_add(ev[12], NULL); - - evutil_gettimeofday(&now,NULL); - puts("=====expected"); - printf("Now= %ld.%06d\n",(long)now.tv_sec,(int)now.tv_usec); - puts("Inserted:"); - printf(" %p [fd %ld] Write\n",ev[0],(long)pair1[0]); - printf(" %p [fd %ld] Read Persist Timeout=T+1\n",ev[1],(long)pair1[1]); - printf(" %p [fd %ld] Write Persist Timeout=T+1\n",ev[2],(long)pair2[0]); - printf(" %p [fd %ld] Read Timeout=T+2.5\n",ev[3],(long)pair2[1]); - printf(" %p [fd -1] Timeout=T+1\n",ev[4]); - printf(" %p [fd -1] Timeout=T+1\n",ev[5]); - printf(" %p [fd -1] Timeout=T+1\n",ev[6]); - printf(" %p [fd -1] Persist Timeout=T+2.5\n",ev[7]); - printf(" %p [fd -1] Persist Timeout=T+1\n",ev[8]); - printf(" %p [fd -1] Persist Timeout=T+2.5\n",ev[9]); - printf(" %p [sig %d] Signal Persist\n", ev[12], (int)SIGINT); - - puts("Active:"); - printf(" %p [fd -1, priority=0] Read active\n", ev[10]); - printf(" %p [fd -1, priority=0] Read Write Timeout active\n", ev[11]); - printf(" %p [fd %ld, priority=0] Read active\n", ev[1], (long)pair1[1]); - - puts("======received"); - event_base_dump_events(base, stdout); - - for (i = 0; i < N_EVENTS; ++i) { - event_free(ev[i]); - } - event_base_free(base); - - return 0; -} - diff --git a/protocols/Telegram/tgl/libevent/test/test-eof.c b/protocols/Telegram/tgl/libevent/test/test-eof.c deleted file mode 100644 index a9ca5343a2..0000000000 --- a/protocols/Telegram/tgl/libevent/test/test-eof.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2002-2007 Niels Provos <provos@citi.umich.edu> - * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "event2/event-config.h" - -#ifdef _WIN32 -#include <winsock2.h> -#else -#include <unistd.h> -#endif -#include <sys/types.h> -#include <sys/stat.h> -#ifdef EVENT__HAVE_SYS_TIME_H -#include <sys/time.h> -#endif -#ifdef EVENT__HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#include <fcntl.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> - -#include <event.h> -#include <evutil.h> - -#ifdef EVENT____func__ -#define __func__ EVENT____func__ -#endif - -int test_okay = 1; -int called = 0; -struct timeval timeout = {60, 0}; - -static void -read_cb(evutil_socket_t fd, short event, void *arg) -{ - char buf[256]; - int len; - - if (EV_TIMEOUT & event) { - printf("%s: Timeout!\n", __func__); - exit(1); - } - - len = recv(fd, buf, sizeof(buf), 0); - - printf("%s: read %d%s\n", __func__, - len, len ? "" : " - means EOF"); - - if (len) { - if (!called) - event_add(arg, &timeout); - } else if (called == 1) - test_okay = 0; - - called++; -} - -#ifndef SHUT_WR -#define SHUT_WR 1 -#endif - -int -main(int argc, char **argv) -{ - struct event ev; - const char *test = "test string"; - evutil_socket_t pair[2]; - -#ifdef _WIN32 - WORD wVersionRequested; - WSADATA wsaData; - - wVersionRequested = MAKEWORD(2, 2); - - (void) WSAStartup(wVersionRequested, &wsaData); -#endif - - if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) - return (1); - - - if (send(pair[0], test, (int)strlen(test)+1, 0) < 0) - return (1); - shutdown(pair[0], SHUT_WR); - - /* Initalize the event library */ - event_init(); - - /* Initalize one event */ - event_set(&ev, pair[1], EV_READ | EV_TIMEOUT, read_cb, &ev); - - event_add(&ev, &timeout); - - event_dispatch(); - - return (test_okay); -} - diff --git a/protocols/Telegram/tgl/libevent/test/test-eof.exe b/protocols/Telegram/tgl/libevent/test/test-eof.exe Binary files differdeleted file mode 100644 index 0c20f43d91..0000000000 --- a/protocols/Telegram/tgl/libevent/test/test-eof.exe +++ /dev/null diff --git a/protocols/Telegram/tgl/libevent/test/test-eof.obj b/protocols/Telegram/tgl/libevent/test/test-eof.obj Binary files differdeleted file mode 100644 index 05c17400b8..0000000000 --- a/protocols/Telegram/tgl/libevent/test/test-eof.obj +++ /dev/null diff --git a/protocols/Telegram/tgl/libevent/test/test-fdleak.c b/protocols/Telegram/tgl/libevent/test/test-fdleak.c deleted file mode 100644 index 4c4eba25e7..0000000000 --- a/protocols/Telegram/tgl/libevent/test/test-fdleak.c +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright (c) 2012 Ross Lagerwall <rosslagerwall@gmail.com> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "event2/event-config.h" - -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#endif -#include <string.h> -#include <stdlib.h> -#include <errno.h> -#ifdef EVENT__HAVE_SYS_TIME_H -#include <sys/time.h> -#endif -#ifdef EVENT__HAVE_SYS_RESOURCE_H -#include <sys/resource.h> -#endif -#ifdef EVENT__HAVE_NETINET_IN_H -#include <netinet/in.h> -#endif - -#include "event2/event.h" -#include "event2/bufferevent.h" -#include "event2/buffer.h" -#include "event2/listener.h" - -/* Number of requests to make. Setting this too high might result in the machine - running out of ephemeral ports */ -#ifdef _WIN32 -#define MAX_REQUESTS 1000 -#else -#define MAX_REQUESTS 4000 -#endif - -/* Provide storage for the address, both for the server & the clients */ -static struct sockaddr_in saddr; - -/* Number of sucessful requests so far */ -static int num_requests; - -static void start_client(struct event_base *base); - -static void -my_perror(const char *s) -{ - fprintf(stderr, "%s: %s", - s, evutil_socket_error_to_string(EVUTIL_SOCKET_ERROR())); -} - -/* -=============================================== -Server functions -=============================================== -*/ - -/* Read a byte from the client and write it back */ -static void -server_read_cb(struct bufferevent *bev, void *ctx) -{ - while (evbuffer_get_length(bufferevent_get_input(bev))) { - unsigned char tmp; - bufferevent_read(bev, &tmp, 1); - bufferevent_write(bev, &tmp, 1); - } -} - -/* Wait for an EOF and then free the bufferevent */ -static void -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)) { - bufferevent_free(bev); - } -} - -/* Accept a client socket and set it up to for reading & writing */ -static void -listener_accept_cb(struct evconnlistener *listener, evutil_socket_t sock, - struct sockaddr *addr, int len, void *ptr) -{ - struct event_base *base = evconnlistener_get_base(listener); - struct bufferevent *bev = bufferevent_socket_new(base, sock, - BEV_OPT_CLOSE_ON_FREE); - - bufferevent_setcb(bev, server_read_cb, NULL, server_event_cb, NULL); - bufferevent_enable(bev, EV_READ|EV_WRITE); -} - -/* Start the server listening on a random port and start the first client. */ -static void -start_loop(void) -{ - struct event_base *base; - struct evconnlistener *listener; - struct sockaddr_storage ss; - ev_socklen_t socklen = sizeof(ss); - evutil_socket_t fd; - - base = event_base_new(); - if (base == NULL) { - puts("Could not open event base!"); - exit(1); - } - - listener = evconnlistener_new_bind(base, listener_accept_cb, NULL, - LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, - -1, (struct sockaddr *)&saddr, sizeof(saddr)); - if (listener == NULL) { - my_perror("Could not create listener!"); - exit(1); - } - fd = evconnlistener_get_fd(listener); - if (fd < 0) { - puts("Couldn't get fd from listener"); - exit(1); - } - if (getsockname(fd, (struct sockaddr *)&ss, &socklen) < 0) { - my_perror("getsockname()"); - exit(1); - } - memcpy(&saddr, &ss, sizeof(saddr)); - if (saddr.sin_family != AF_INET) { - puts("AF mismatch from getsockname()."); - exit(1); - } - - start_client(base); - - event_base_dispatch(base); -} - -/* -=============================================== -Client functions -=============================================== -*/ - -/* Check that the server sends back the same byte that the client sent. - If MAX_REQUESTS have been reached, exit. Otherwise, start another client. */ -static void -client_read_cb(struct bufferevent *bev, void *ctx) -{ - unsigned char tmp; - struct event_base *base = bufferevent_get_base(bev); - - bufferevent_read(bev, &tmp, 1); - if (tmp != 'A') { - puts("Incorrect data received!"); - exit(2); - } - bufferevent_free(bev); - - num_requests++; - if (num_requests == MAX_REQUESTS) { - event_base_loopbreak(base); - } else { - start_client(base); - } -} - -/* Send a byte to the server. */ -static void -client_event_cb(struct bufferevent *bev, short events, void *ctx) -{ - if (events & BEV_EVENT_CONNECTED) { - unsigned char tmp = 'A'; - bufferevent_write(bev, &tmp, 1); - } else if (events & BEV_EVENT_ERROR) { - puts("Client socket got error!"); - exit(2); - } - - bufferevent_enable(bev, EV_READ); -} - -/* Open a client socket to connect to localhost on sin */ -static void -start_client(struct event_base *base) -{ - struct bufferevent *bev = bufferevent_socket_new(base, -1, - BEV_OPT_CLOSE_ON_FREE); - bufferevent_setcb(bev, client_read_cb, NULL, client_event_cb, NULL); - - if (bufferevent_socket_connect(bev, (struct sockaddr *)&saddr, - sizeof(saddr)) < 0) { - my_perror("Could not connect!"); - bufferevent_free(bev); - exit(2); - } -} - -int -main(int argc, char **argv) -{ -#ifdef EVENT__HAVE_SETRLIMIT - /* Set the fd limit to a low value so that any fd leak is caught without - making many requests. */ - struct rlimit rl; - rl.rlim_cur = rl.rlim_max = 20; - if (setrlimit(RLIMIT_NOFILE, &rl) == -1) { - my_perror("setrlimit"); - exit(3); - } -#endif - -#ifdef _WIN32 - WSADATA WSAData; - WSAStartup(0x101, &WSAData); -#endif - - /* Set up an address, used by both client & server. */ - memset(&saddr, 0, sizeof(saddr)); - saddr.sin_family = AF_INET; - saddr.sin_addr.s_addr = htonl(0x7f000001); - saddr.sin_port = 0; /* Tell the implementation to pick a port. */ - - start_loop(); - - return 0; -} - -/* XXX why does this test cause so much latency sometimes (OSX 10.5)? */ diff --git a/protocols/Telegram/tgl/libevent/test/test-init.c b/protocols/Telegram/tgl/libevent/test/test-init.c deleted file mode 100644 index 92fbc6b146..0000000000 --- a/protocols/Telegram/tgl/libevent/test/test-init.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2003-2007 Niels Provos <provos@citi.umich.edu> - * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "event2/event-config.h" - -#include <sys/types.h> -#include <sys/stat.h> -#ifdef EVENT__HAVE_SYS_TIME_H -#include <sys/time.h> -#endif -#ifdef EVENT__HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#include <fcntl.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#ifndef _WIN32 -#include <unistd.h> -#endif -#include <errno.h> - -#include <event.h> - -int -main(int argc, char **argv) -{ -#ifdef _WIN32 - WORD wVersionRequested; - WSADATA wsaData; - - wVersionRequested = MAKEWORD(2, 2); - - (void) WSAStartup(wVersionRequested, &wsaData); -#endif - - /* Initalize the event library */ - event_init(); - - return (0); -} - diff --git a/protocols/Telegram/tgl/libevent/test/test-init.exe b/protocols/Telegram/tgl/libevent/test/test-init.exe Binary files differdeleted file mode 100644 index c404d2c1a1..0000000000 --- a/protocols/Telegram/tgl/libevent/test/test-init.exe +++ /dev/null diff --git a/protocols/Telegram/tgl/libevent/test/test-init.obj b/protocols/Telegram/tgl/libevent/test/test-init.obj Binary files differdeleted file mode 100644 index 606fcf91d5..0000000000 --- a/protocols/Telegram/tgl/libevent/test/test-init.obj +++ /dev/null diff --git a/protocols/Telegram/tgl/libevent/test/test-ratelim.c b/protocols/Telegram/tgl/libevent/test/test-ratelim.c deleted file mode 100644 index 17babfdcbc..0000000000 --- a/protocols/Telegram/tgl/libevent/test/test-ratelim.c +++ /dev/null @@ -1,601 +0,0 @@ -/* - * Copyright (c) 2009-2012 Niels Provos and Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "../util-internal.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include <math.h> - -#ifdef _WIN32 -#include <winsock2.h> -#include <ws2tcpip.h> -#else -#include <sys/socket.h> -#include <netinet/in.h> -# ifdef _XOPEN_SOURCE_EXTENDED -# include <arpa/inet.h> -# endif -#endif -#include <signal.h> - -#include "event2/bufferevent.h" -#include "event2/buffer.h" -#include "event2/event.h" -#include "event2/util.h" -#include "event2/listener.h" -#include "event2/thread.h" - -static struct evutil_weakrand_state weakrand_state; - -static int cfg_verbose = 0; -static int cfg_help = 0; - -static int cfg_n_connections = 30; -static int cfg_duration = 5; -static int cfg_connlimit = 0; -static int cfg_grouplimit = 0; -static int cfg_tick_msec = 1000; -static int cfg_min_share = -1; -static int cfg_group_drain = 0; - -static int cfg_connlimit_tolerance = -1; -static int cfg_grouplimit_tolerance = -1; -static int cfg_stddev_tolerance = -1; - -#ifdef _WIN32 -static int cfg_enable_iocp = 0; -#endif - -static struct timeval cfg_tick = { 0, 500*1000 }; - -static struct ev_token_bucket_cfg *conn_bucket_cfg = NULL; -static struct ev_token_bucket_cfg *group_bucket_cfg = NULL; -struct bufferevent_rate_limit_group *ratelim_group = NULL; -static double seconds_per_tick = 0.0; - -struct client_state { - size_t queued; - ev_uint64_t received; - -}; -static const struct timeval *ms100_common=NULL; - -/* info from check_bucket_levels_cb */ -static int total_n_bev_checks = 0; -static ev_int64_t total_rbucket_level=0; -static ev_int64_t total_wbucket_level=0; -static ev_int64_t total_max_to_read=0; -static ev_int64_t total_max_to_write=0; -static ev_int64_t max_bucket_level=EV_INT64_MIN; -static ev_int64_t min_bucket_level=EV_INT64_MAX; - -/* from check_group_bucket_levels_cb */ -static int total_n_group_bev_checks = 0; -static ev_int64_t total_group_rbucket_level = 0; -static ev_int64_t total_group_wbucket_level = 0; - -static int n_echo_conns_open = 0; - -/* Info on the open connections */ -struct bufferevent **bevs; -struct client_state *states; -struct bufferevent_rate_limit_group *group = NULL; - -static void check_bucket_levels_cb(evutil_socket_t fd, short events, void *arg); - -static void -loud_writecb(struct bufferevent *bev, void *ctx) -{ - struct client_state *cs = ctx; - struct evbuffer *output = bufferevent_get_output(bev); - char buf[1024]; - int r = evutil_weakrand_(&weakrand_state); - memset(buf, r, sizeof(buf)); - while (evbuffer_get_length(output) < 8192) { - evbuffer_add(output, buf, sizeof(buf)); - cs->queued += sizeof(buf); - } -} - -static void -discard_readcb(struct bufferevent *bev, void *ctx) -{ - struct client_state *cs = ctx; - struct evbuffer *input = bufferevent_get_input(bev); - size_t len = evbuffer_get_length(input); - evbuffer_drain(input, len); - cs->received += len; -} - -static void -write_on_connectedcb(struct bufferevent *bev, short what, void *ctx) -{ - if (what & BEV_EVENT_CONNECTED) { - loud_writecb(bev, ctx); - /* XXXX this shouldn't be needed. */ - bufferevent_enable(bev, EV_READ|EV_WRITE); - } -} - -static void -echo_readcb(struct bufferevent *bev, void *ctx) -{ - struct evbuffer *input = bufferevent_get_input(bev); - struct evbuffer *output = bufferevent_get_output(bev); - - evbuffer_add_buffer(output, input); - if (evbuffer_get_length(output) > 1024000) - bufferevent_disable(bev, EV_READ); -} - -static void -echo_writecb(struct bufferevent *bev, void *ctx) -{ - struct evbuffer *output = bufferevent_get_output(bev); - if (evbuffer_get_length(output) < 512000) - bufferevent_enable(bev, EV_READ); -} - -static void -echo_eventcb(struct bufferevent *bev, short what, void *ctx) -{ - if (what & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) { - --n_echo_conns_open; - bufferevent_free(bev); - } -} - -static void -echo_listenercb(struct evconnlistener *listener, evutil_socket_t newsock, - struct sockaddr *sourceaddr, int socklen, void *ctx) -{ - struct event_base *base = ctx; - int flags = BEV_OPT_CLOSE_ON_FREE|BEV_OPT_THREADSAFE; - struct bufferevent *bev; - - bev = bufferevent_socket_new(base, newsock, flags); - bufferevent_setcb(bev, echo_readcb, echo_writecb, echo_eventcb, NULL); - if (conn_bucket_cfg) { - struct event *check_event = - event_new(base, -1, EV_PERSIST, check_bucket_levels_cb, bev); - bufferevent_set_rate_limit(bev, conn_bucket_cfg); - - assert(bufferevent_get_token_bucket_cfg(bev) != NULL); - event_add(check_event, ms100_common); - } - if (ratelim_group) - bufferevent_add_to_rate_limit_group(bev, ratelim_group); - ++n_echo_conns_open; - bufferevent_enable(bev, EV_READ|EV_WRITE); -} - -/* Called periodically to check up on how full the buckets are */ -static void -check_bucket_levels_cb(evutil_socket_t fd, short events, void *arg) -{ - struct bufferevent *bev = arg; - - ev_ssize_t r = bufferevent_get_read_limit(bev); - ev_ssize_t w = bufferevent_get_write_limit(bev); - ev_ssize_t rm = bufferevent_get_max_to_read(bev); - ev_ssize_t wm = bufferevent_get_max_to_write(bev); - /* XXXX check that no value is above the cofigured burst - * limit */ - total_rbucket_level += r; - total_wbucket_level += w; - total_max_to_read += rm; - total_max_to_write += wm; -#define B(x) \ - if ((x) > max_bucket_level) \ - max_bucket_level = (x); \ - if ((x) < min_bucket_level) \ - min_bucket_level = (x) - B(r); - B(w); -#undef B - - total_n_bev_checks++; - if (total_n_bev_checks >= .8 * ((double)cfg_duration / cfg_tick_msec) * cfg_n_connections) { - event_free(event_base_get_running_event(bufferevent_get_base(bev))); - } -} - -static void -check_group_bucket_levels_cb(evutil_socket_t fd, short events, void *arg) -{ - if (ratelim_group) { - ev_ssize_t r = bufferevent_rate_limit_group_get_read_limit(ratelim_group); - ev_ssize_t w = bufferevent_rate_limit_group_get_write_limit(ratelim_group); - total_group_rbucket_level += r; - total_group_wbucket_level += w; - } - ++total_n_group_bev_checks; -} - -static void -group_drain_cb(evutil_socket_t fd, short events, void *arg) -{ - bufferevent_rate_limit_group_decrement_read(ratelim_group, cfg_group_drain); - bufferevent_rate_limit_group_decrement_write(ratelim_group, cfg_group_drain); -} - -static int -test_ratelimiting(void) -{ - struct event_base *base; - struct sockaddr_in sin; - struct evconnlistener *listener; - - struct sockaddr_storage ss; - ev_socklen_t slen; - - int i; - - struct timeval tv; - - ev_uint64_t total_received; - double total_sq_persec, total_persec; - double variance; - double expected_total_persec = -1.0, expected_avg_persec = -1.0; - int ok = 1; - struct event_config *base_cfg; - struct event *periodic_level_check; - struct event *group_drain_event=NULL; - - 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; /* unspecified port */ - - if (0) - event_enable_debug_mode(); - - base_cfg = event_config_new(); - -#ifdef _WIN32 - if (cfg_enable_iocp) { - evthread_use_windows_threads(); - event_config_set_flag(base_cfg, EVENT_BASE_FLAG_STARTUP_IOCP); - } -#endif - - base = event_base_new_with_config(base_cfg); - event_config_free(base_cfg); - if (! base) { - fprintf(stderr, "Couldn't create event_base"); - return 1; - } - - listener = evconnlistener_new_bind(base, echo_listenercb, base, - LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, -1, - (struct sockaddr *)&sin, sizeof(sin)); - if (! listener) { - fprintf(stderr, "Couldn't create listener"); - return 1; - } - - slen = sizeof(ss); - if (getsockname(evconnlistener_get_fd(listener), (struct sockaddr *)&ss, - &slen) < 0) { - perror("getsockname"); - return 1; - } - - if (cfg_connlimit > 0) { - conn_bucket_cfg = ev_token_bucket_cfg_new( - cfg_connlimit, cfg_connlimit * 4, - cfg_connlimit, cfg_connlimit * 4, - &cfg_tick); - assert(conn_bucket_cfg); - } - - if (cfg_grouplimit > 0) { - group_bucket_cfg = ev_token_bucket_cfg_new( - cfg_grouplimit, cfg_grouplimit * 4, - cfg_grouplimit, cfg_grouplimit * 4, - &cfg_tick); - group = ratelim_group = bufferevent_rate_limit_group_new( - base, group_bucket_cfg); - expected_total_persec = cfg_grouplimit - (cfg_group_drain / seconds_per_tick); - expected_avg_persec = cfg_grouplimit / cfg_n_connections; - if (cfg_connlimit > 0 && expected_avg_persec > cfg_connlimit) - expected_avg_persec = cfg_connlimit; - if (cfg_min_share >= 0) - bufferevent_rate_limit_group_set_min_share( - ratelim_group, cfg_min_share); - } - - if (expected_avg_persec < 0 && cfg_connlimit > 0) - expected_avg_persec = cfg_connlimit; - - if (expected_avg_persec > 0) - expected_avg_persec /= seconds_per_tick; - if (expected_total_persec > 0) - expected_total_persec /= seconds_per_tick; - - bevs = calloc(cfg_n_connections, sizeof(struct bufferevent *)); - states = calloc(cfg_n_connections, sizeof(struct client_state)); - - for (i = 0; i < cfg_n_connections; ++i) { - bevs[i] = bufferevent_socket_new(base, -1, - BEV_OPT_CLOSE_ON_FREE|BEV_OPT_THREADSAFE); - assert(bevs[i]); - bufferevent_setcb(bevs[i], discard_readcb, loud_writecb, - write_on_connectedcb, &states[i]); - bufferevent_enable(bevs[i], EV_READ|EV_WRITE); - bufferevent_socket_connect(bevs[i], (struct sockaddr *)&ss, - slen); - } - - tv.tv_sec = cfg_duration - 1; - tv.tv_usec = 995000; - - event_base_loopexit(base, &tv); - - tv.tv_sec = 0; - tv.tv_usec = 100*1000; - ms100_common = event_base_init_common_timeout(base, &tv); - - periodic_level_check = event_new(base, -1, EV_PERSIST, check_group_bucket_levels_cb, NULL); - event_add(periodic_level_check, ms100_common); - - if (cfg_group_drain && ratelim_group) { - group_drain_event = event_new(base, -1, EV_PERSIST, group_drain_cb, NULL); - event_add(group_drain_event, &cfg_tick); - } - - event_base_dispatch(base); - - ratelim_group = NULL; /* So no more responders get added */ - event_free(periodic_level_check); - if (group_drain_event) - event_del(group_drain_event); - - for (i = 0; i < cfg_n_connections; ++i) { - bufferevent_free(bevs[i]); - } - evconnlistener_free(listener); - - /* Make sure no new echo_conns get added to the group. */ - ratelim_group = NULL; - - /* This should get _everybody_ freed */ - while (n_echo_conns_open) { - printf("waiting for %d conns\n", n_echo_conns_open); - tv.tv_sec = 0; - tv.tv_usec = 300000; - event_base_loopexit(base, &tv); - event_base_dispatch(base); - } - - if (group) - bufferevent_rate_limit_group_free(group); - - if (total_n_bev_checks) { - printf("Average read bucket level: %f\n", - (double)total_rbucket_level/total_n_bev_checks); - printf("Average write bucket level: %f\n", - (double)total_wbucket_level/total_n_bev_checks); - printf("Highest read bucket level: %f\n", - (double)max_bucket_level); - printf("Highest write bucket level: %f\n", - (double)min_bucket_level); - printf("Average max-to-read: %f\n", - ((double)total_max_to_read)/total_n_bev_checks); - printf("Average max-to-write: %f\n", - ((double)total_max_to_write)/total_n_bev_checks); - } - if (total_n_group_bev_checks) { - printf("Average group read bucket level: %f\n", - ((double)total_group_rbucket_level)/total_n_group_bev_checks); - printf("Average group write bucket level: %f\n", - ((double)total_group_wbucket_level)/total_n_group_bev_checks); - } - - total_received = 0; - total_persec = 0.0; - total_sq_persec = 0.0; - for (i=0; i < cfg_n_connections; ++i) { - double persec = states[i].received; - persec /= cfg_duration; - total_received += states[i].received; - total_persec += persec; - total_sq_persec += persec*persec; - printf("%d: %f per second\n", i+1, persec); - } - printf(" total: %f per second\n", - ((double)total_received)/cfg_duration); - if (expected_total_persec > 0) { - double diff = expected_total_persec - - ((double)total_received/cfg_duration); - printf(" [Off by %lf]\n", diff); - if (cfg_grouplimit_tolerance > 0 && - fabs(diff) > cfg_grouplimit_tolerance) { - fprintf(stderr, "Group bandwidth out of bounds\n"); - ok = 0; - } - } - - printf(" average: %f per second\n", - (((double)total_received)/cfg_duration)/cfg_n_connections); - if (expected_avg_persec > 0) { - double diff = expected_avg_persec - (((double)total_received)/cfg_duration)/cfg_n_connections; - printf(" [Off by %lf]\n", diff); - if (cfg_connlimit_tolerance > 0 && - fabs(diff) > cfg_connlimit_tolerance) { - fprintf(stderr, "Connection bandwidth out of bounds\n"); - ok = 0; - } - } - - variance = total_sq_persec/cfg_n_connections - total_persec*total_persec/(cfg_n_connections*cfg_n_connections); - - printf(" stddev: %f per second\n", sqrt(variance)); - if (cfg_stddev_tolerance > 0 && - sqrt(variance) > cfg_stddev_tolerance) { - fprintf(stderr, "Connection variance out of bounds\n"); - ok = 0; - } - - event_base_free(base); - free(bevs); - free(states); - - return ok ? 0 : 1; -} - -static struct option { - const char *name; int *ptr; int min; int isbool; -} options[] = { - { "-v", &cfg_verbose, 0, 1 }, - { "-h", &cfg_help, 0, 1 }, - { "-n", &cfg_n_connections, 1, 0 }, - { "-d", &cfg_duration, 1, 0 }, - { "-c", &cfg_connlimit, 0, 0 }, - { "-g", &cfg_grouplimit, 0, 0 }, - { "-G", &cfg_group_drain, -100000, 0 }, - { "-t", &cfg_tick_msec, 10, 0 }, - { "--min-share", &cfg_min_share, 0, 0 }, - { "--check-connlimit", &cfg_connlimit_tolerance, 0, 0 }, - { "--check-grouplimit", &cfg_grouplimit_tolerance, 0, 0 }, - { "--check-stddev", &cfg_stddev_tolerance, 0, 0 }, -#ifdef _WIN32 - { "--iocp", &cfg_enable_iocp, 0, 1 }, -#endif - { NULL, NULL, -1, 0 }, -}; - -static int -handle_option(int argc, char **argv, int *i, const struct option *opt) -{ - long val; - char *endptr = NULL; - if (opt->isbool) { - *opt->ptr = 1; - return 0; - } - if (*i + 1 == argc) { - fprintf(stderr, "Too few arguments to '%s'\n",argv[*i]); - return -1; - } - val = strtol(argv[*i+1], &endptr, 10); - if (*argv[*i+1] == '\0' || !endptr || *endptr != '\0') { - fprintf(stderr, "Couldn't parse numeric value '%s'\n", - argv[*i+1]); - return -1; - } - if (val < opt->min || val > 0x7fffffff) { - fprintf(stderr, "Value '%s' is out-of-range'\n", - argv[*i+1]); - return -1; - } - *opt->ptr = (int)val; - ++*i; - return 0; -} - -static void -usage(void) -{ - fprintf(stderr, -"test-ratelim [-v] [-n INT] [-d INT] [-c INT] [-g INT] [-t INT]\n\n" -"Pushes bytes through a number of possibly rate-limited connections, and\n" -"displays average throughput.\n\n" -" -n INT: Number of connections to open (default: 30)\n" -" -d INT: Duration of the test in seconds (default: 5 sec)\n"); - fprintf(stderr, -" -c INT: Connection-rate limit applied to each connection in bytes per second\n" -" (default: None.)\n" -" -g INT: Group-rate limit applied to sum of all usage in bytes per second\n" -" (default: None.)\n" -" -G INT: drain INT bytes from the group limit every tick. (default: 0)\n" -" -t INT: Granularity of timing, in milliseconds (default: 1000 msec)\n"); -} - -int -main(int argc, char **argv) -{ - int i,j; - double ratio; - -#ifdef _WIN32 - WORD wVersionRequested = MAKEWORD(2,2); - WSADATA wsaData; - - (void) WSAStartup(wVersionRequested, &wsaData); -#endif - - evutil_weakrand_seed_(&weakrand_state, 0); - -#ifndef _WIN32 - if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) - return 1; -#endif - for (i = 1; i < argc; ++i) { - for (j = 0; options[j].name; ++j) { - if (!strcmp(argv[i],options[j].name)) { - if (handle_option(argc,argv,&i,&options[j])<0) - return 1; - goto again; - } - } - fprintf(stderr, "Unknown option '%s'\n", argv[i]); - usage(); - return 1; - again: - ; - } - if (cfg_help) { - usage(); - return 0; - } - - cfg_tick.tv_sec = cfg_tick_msec / 1000; - cfg_tick.tv_usec = (cfg_tick_msec % 1000)*1000; - - seconds_per_tick = ratio = cfg_tick_msec / 1000.0; - - cfg_connlimit *= ratio; - cfg_grouplimit *= ratio; - - { - struct timeval tv; - evutil_gettimeofday(&tv, NULL); -#ifdef _WIN32 - srand(tv.tv_usec); -#else - srandom(tv.tv_usec); -#endif - } - -#ifndef EVENT__DISABLE_THREAD_SUPPORT - evthread_enable_lock_debugging(); -#endif - - return test_ratelimiting(); -} diff --git a/protocols/Telegram/tgl/libevent/test/test-ratelim.sh b/protocols/Telegram/tgl/libevent/test/test-ratelim.sh deleted file mode 100644 index b5e0ca62a9..0000000000 --- a/protocols/Telegram/tgl/libevent/test/test-ratelim.sh +++ /dev/null @@ -1,88 +0,0 @@ -#!/bin/sh - -FAILED=no - -if test "x$TEST_OUTPUT_FILE" = "x" -then - TEST_OUTPUT_FILE=/dev/null -fi - -# /bin/echo is a little more likely to support -n than sh's builtin echo. -if test -x /bin/echo -then - ECHO=/bin/echo -else - ECHO=echo -fi - -if test "$TEST_OUTPUT_FILE" != "/dev/null" -then - touch "$TEST_OUTPUT_FILE" || exit 1 -fi - -TEST_DIR=. - -T=`echo "$0" | sed -e 's/test-ratelim.sh$//'` -if test -x "$T/test-ratelim" -then - TEST_DIR="$T" -fi - -announce () { - echo $@ - echo $@ >>"$TEST_OUTPUT_FILE" -} - -announce_n () { - $ECHO -n $@ - echo $@ >>"$TEST_OUTPUT_FILE" -} - - -run_tests () { - announce_n " Group limits, no connection limit:" - if $TEST_DIR/test-ratelim -g 30000 -n 30 -t 100 --check-grouplimit 1000 --check-stddev 100 >>"$TEST_OUTPUT_FILE" - then - announce OKAY - else - announce FAILED - FAILED=yes - fi - - announce_n " Connection limit, no group limit:" - if $TEST_DIR/test-ratelim -c 1000 -n 30 -t 100 --check-connlimit 50 --check-stddev 50 >>"$TEST_OUTPUT_FILE" - then - announce OKAY ; - else - announce FAILED ; - FAILED=yes - fi - - announce_n " Connection limit and group limit:" - if $TEST_DIR/test-ratelim -c 1000 -g 30000 -n 30 -t 100 --check-grouplimit 1000 --check-connlimit 50 --check-stddev 50 >>"$TEST_OUTPUT_FILE" - then - announce OKAY ; - else - announce FAILED ; - FAILED=yes - fi - - announce_n " Connection limit and group limit with independent drain:" - if $TEST_DIR/test-ratelim -c 1000 -g 35000 -n 30 -t 100 -G 500 --check-grouplimit 1000 --check-connlimit 50 --check-stddev 50 >>"$TEST_OUTPUT_FILE" - then - announce OKAY ; - else - announce FAILED ; - FAILED=yes - fi - - -} - -announce "Running rate-limiting tests:" - -run_tests - -if test "$FAILED" = "yes"; then - exit 1 -fi diff --git a/protocols/Telegram/tgl/libevent/test/test-time.c b/protocols/Telegram/tgl/libevent/test/test-time.c deleted file mode 100644 index bcc7086df7..0000000000 --- a/protocols/Telegram/tgl/libevent/test/test-time.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2002-2007 Niels Provos <provos@citi.umich.edu> - * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "event2/event-config.h" - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#ifndef _WIN32 -#include <unistd.h> -#include <sys/time.h> -#endif -#include <errno.h> - -#include "event2/event.h" -#include "event2/event_compat.h" -#include "event2/event_struct.h" -#include "util-internal.h" - -int called = 0; - -#define NEVENT 20000 - -struct event *ev[NEVENT]; - -struct evutil_weakrand_state weakrand_state; - -static int -rand_int(int n) -{ - return evutil_weakrand_(&weakrand_state) % n; -} - -static void -time_cb(evutil_socket_t fd, short event, void *arg) -{ - struct timeval tv; - int i, j; - - called++; - - if (called < 10*NEVENT) { - for (i = 0; i < 10; i++) { - j = rand_int(NEVENT); - tv.tv_sec = 0; - tv.tv_usec = rand_int(50000); - if (tv.tv_usec % 2 || called < NEVENT) - evtimer_add(ev[j], &tv); - else - evtimer_del(ev[j]); - } - } -} - -int -main(int argc, char **argv) -{ - struct timeval tv; - int i; -#ifdef _WIN32 - WORD wVersionRequested; - WSADATA wsaData; - - wVersionRequested = MAKEWORD(2, 2); - - (void) WSAStartup(wVersionRequested, &wsaData); -#endif - - evutil_weakrand_seed_(&weakrand_state, 0); - - /* Initalize the event library */ - event_init(); - - for (i = 0; i < NEVENT; i++) { - ev[i] = malloc(sizeof(struct event)); - - /* Initalize one event */ - evtimer_set(ev[i], time_cb, ev[i]); - tv.tv_sec = 0; - tv.tv_usec = rand_int(50000); - evtimer_add(ev[i], &tv); - } - - event_dispatch(); - - - printf("%d, %d\n", called, NEVENT); - return (called < NEVENT); -} - diff --git a/protocols/Telegram/tgl/libevent/test/test-time.exe b/protocols/Telegram/tgl/libevent/test/test-time.exe Binary files differdeleted file mode 100644 index 7cdcfd61ac..0000000000 --- a/protocols/Telegram/tgl/libevent/test/test-time.exe +++ /dev/null diff --git a/protocols/Telegram/tgl/libevent/test/test-time.obj b/protocols/Telegram/tgl/libevent/test/test-time.obj Binary files differdeleted file mode 100644 index c5fa6cbeac..0000000000 --- a/protocols/Telegram/tgl/libevent/test/test-time.obj +++ /dev/null diff --git a/protocols/Telegram/tgl/libevent/test/test-weof.c b/protocols/Telegram/tgl/libevent/test/test-weof.c deleted file mode 100644 index c379f287cb..0000000000 --- a/protocols/Telegram/tgl/libevent/test/test-weof.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2002-2007 Niels Provos <provos@citi.umich.edu> - * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "event2/event-config.h" - -#ifdef _WIN32 -#include <winsock2.h> -#else -#include <unistd.h> -#endif -#include <sys/types.h> -#include <sys/stat.h> -#ifdef EVENT__HAVE_SYS_TIME_H -#include <sys/time.h> -#endif -#ifdef EVENT__HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#include <fcntl.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <signal.h> -#include <errno.h> - -#include "event2/event.h" -#include "event2/event_struct.h" -#include "event2/event_compat.h" -#include "event2/util.h" - -#ifdef EVENT____func__ -#define __func__ EVENT____func__ -#endif - -evutil_socket_t pair[2]; -int test_okay = 1; -int called = 0; - -static void -write_cb(evutil_socket_t fd, short event, void *arg) -{ - const char *test = "test string"; - int len; - - len = send(fd, test, (int)strlen(test) + 1, 0); - - printf("%s: write %d%s\n", __func__, - len, len ? "" : " - means EOF"); - - if (len > 0) { - if (!called) - event_add(arg, NULL); - evutil_closesocket(pair[0]); - } else if (called == 1) - test_okay = 0; - - called++; -} - -int -main(int argc, char **argv) -{ - struct event ev; - -#ifdef _WIN32 - WORD wVersionRequested; - WSADATA wsaData; - - wVersionRequested = MAKEWORD(2, 2); - - (void) WSAStartup(wVersionRequested, &wsaData); -#endif - -#ifndef _WIN32 - if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) - return (1); -#endif - - if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) - return (1); - - /* Initalize the event library */ - event_init(); - - /* Initalize one event */ - event_set(&ev, pair[1], EV_WRITE, write_cb, &ev); - - event_add(&ev, NULL); - - event_dispatch(); - - return (test_okay); -} - diff --git a/protocols/Telegram/tgl/libevent/test/test-weof.exe b/protocols/Telegram/tgl/libevent/test/test-weof.exe Binary files differdeleted file mode 100644 index 1fe6973f46..0000000000 --- a/protocols/Telegram/tgl/libevent/test/test-weof.exe +++ /dev/null diff --git a/protocols/Telegram/tgl/libevent/test/test-weof.obj b/protocols/Telegram/tgl/libevent/test/test-weof.obj Binary files differdeleted file mode 100644 index 5ca123d600..0000000000 --- a/protocols/Telegram/tgl/libevent/test/test-weof.obj +++ /dev/null diff --git a/protocols/Telegram/tgl/libevent/test/test.sh b/protocols/Telegram/tgl/libevent/test/test.sh deleted file mode 100644 index b73c1adced..0000000000 --- a/protocols/Telegram/tgl/libevent/test/test.sh +++ /dev/null @@ -1,160 +0,0 @@ -#!/bin/sh - -BACKENDS="EVPORT KQUEUE EPOLL DEVPOLL POLL SELECT WIN32" -TESTS="test-eof test-closed test-weof test-time test-changelist test-fdleak" -FAILED=no -TEST_OUTPUT_FILE=${TEST_OUTPUT_FILE:-/dev/null} -REGRESS_ARGS=${REGRESS_ARGS:-} - -# /bin/echo is a little more likely to support -n than sh's builtin echo, -# printf is even more likely -if test "`printf %s hello 2>&1`" = "hello" -then - ECHO_N="printf %s" -else - if test -x /bin/echo - then - ECHO_N="/bin/echo -n" - else - ECHO_N="echo -n" - fi -fi - -if test "$TEST_OUTPUT_FILE" != "/dev/null" -then - touch "$TEST_OUTPUT_FILE" || exit 1 -fi - -TEST_DIR=. -TEST_SRC_DIR=. - -T=`echo "$0" | sed -e 's/test.sh$//' | sed -e 's/test-script.sh//' ` -if test -x "$T/test-init" -then - TEST_DIR="$T" -elif test -x "./test/test-init" -then - TEST_DIR="./test" -fi -if test -f "$T/check-dumpevents.py" -then - TEST_SRC_DIR="$T" -elif test -f "./test/check-dumpevents.py" -then - TEST_SRC_DIR="./test" -fi - -setup () { - for i in $BACKENDS; do - eval "EVENT_NO$i=yes; export EVENT_NO$i" - done - unset EVENT_EPOLL_USE_CHANGELIST - unset EVENT_PRECISE_TIMER -} - -announce () { - echo "$@" - echo "$@" >>"$TEST_OUTPUT_FILE" -} - -announce_n () { - $ECHO_N "$@" - echo "$@" >>"$TEST_OUTPUT_FILE" -} - - -run_tests () { - if $TEST_DIR/test-init 2>>"$TEST_OUTPUT_FILE" ; - then - true - else - announce Skipping test - return - fi - for i in $TESTS; do - announce_n " $i: " - if $TEST_DIR/$i >>"$TEST_OUTPUT_FILE" ; - then - announce OKAY ; - else - announce FAILED ; - FAILED=yes - 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" ; - then - announce OKAY ; - else - announce FAILED ; - fi - else - # no python - if $TEST_DIR/test-dumpevents >/dev/null; then - announce "OKAY (output not checked)" ; - else - announce "FAILED (output not checked)" ; - fi - fi - - test -x $TEST_DIR/regress || return - announce_n " regress: " - if test "$TEST_OUTPUT_FILE" = "/dev/null" ; - then - $TEST_DIR/regress --quiet $REGRESS_ARGS - else - $TEST_DIR/regress $REGRESS_ARGS >>"$TEST_OUTPUT_FILE" - fi - if test "$?" = "0" ; - then - announce OKAY ; - else - announce FAILED ; - FAILED=yes - fi - - announce_n " regress_debug: " - if test "$TEST_OUTPUT_FILE" = "/dev/null" ; - then - EVENT_DEBUG_MODE=1 $TEST_DIR/regress --quiet $REGRESS_ARGS - else - EVENT_DEBUG_MODE=1 $TEST_DIR/regress $REGRESS_ARGS >>"$TEST_OUTPUT_FILE" - fi - if test "$?" = "0" ; - then - announce OKAY ; - else - announce FAILED ; - FAILED=yes - fi -} - -do_test() { - setup - announce "$1 $2" - unset EVENT_NO$1 - if test "$2" = "(changelist)" ; then - EVENT_EPOLL_USE_CHANGELIST=yes; export EVENT_EPOLL_USE_CHANGELIST - elif test "$2" = "(timerfd)" ; then - EVENT_PRECISE_TIMER=1; export EVENT_PRECISE_TIMER - elif test "$2" = "(timerfd+changelist)" ; then - EVENT_EPOLL_USE_CHANGELIST=yes; export EVENT_EPOLL_USE_CHANGELIST - EVENT_PRECISE_TIMER=1; export EVENT_PRECISE_TIMER - fi - - run_tests -} - -announce "Running tests:" - -do_test EPOLL "(timerfd)" -do_test EPOLL "(changelist)" -do_test EPOLL "(timerfd+changelist)" -for i in $BACKENDS; do - do_test $i -done - -if test "$FAILED" = "yes"; then - exit 1 -fi diff --git a/protocols/Telegram/tgl/libevent/test/tinytest.c b/protocols/Telegram/tgl/libevent/test/tinytest.c deleted file mode 100644 index 3a8e331055..0000000000 --- a/protocols/Telegram/tgl/libevent/test/tinytest.c +++ /dev/null @@ -1,493 +0,0 @@ -/* tinytest.c -- Copyright 2009-2012 Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifdef TINYTEST_LOCAL -#include "tinytest_local.h" -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -#ifndef NO_FORKING - -#ifdef _WIN32 -#include <windows.h> -#else -#include <sys/types.h> -#include <sys/wait.h> -#include <unistd.h> -#endif - -#if defined(__APPLE__) && defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) -#if (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1060 && \ - __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070) -/* Workaround for a stupid bug in OSX 10.6 */ -#define FORK_BREAKS_GCOV -#include <vproc.h> -#endif -#endif - -#endif /* !NO_FORKING */ - -#ifndef __GNUC__ -#define __attribute__(x) -#endif - -#include "tinytest.h" -#include "tinytest_macros.h" - -#define LONGEST_TEST_NAME 16384 - -static int in_tinytest_main = 0; /**< true if we're in tinytest_main().*/ -static int n_ok = 0; /**< Number of tests that have passed */ -static int n_bad = 0; /**< Number of tests that have failed. */ -static int n_skipped = 0; /**< Number of tests that have been skipped. */ - -static int opt_forked = 0; /**< True iff we're called from inside a win32 fork*/ -static int opt_nofork = 0; /**< Suppress calls to fork() for debugging. */ -static int opt_verbosity = 1; /**< -==quiet,0==terse,1==normal,2==verbose */ -const char *verbosity_flag = ""; - -const struct testlist_alias_t *cfg_aliases=NULL; - -enum outcome { SKIP=2, OK=1, FAIL=0 }; -static enum outcome cur_test_outcome = 0; -const char *cur_test_prefix = NULL; /**< prefix of the current test group */ -/** Name of the current test, if we haven't logged is yet. Used for --quiet */ -const char *cur_test_name = NULL; - -#ifdef _WIN32 -/* Copy of argv[0] for win32. */ -static char commandname[MAX_PATH+1]; -#endif - -static void usage(struct testgroup_t *groups, int list_groups) - __attribute__((noreturn)); -static int process_test_option(struct testgroup_t *groups, const char *test); - -static enum outcome -testcase_run_bare_(const struct testcase_t *testcase) -{ - void *env = NULL; - int outcome; - if (testcase->setup) { - env = testcase->setup->setup_fn(testcase); - if (!env) - return FAIL; - else if (env == (void*)TT_SKIP) - return SKIP; - } - - cur_test_outcome = OK; - testcase->fn(env); - outcome = cur_test_outcome; - - if (testcase->setup) { - if (testcase->setup->cleanup_fn(testcase, env) == 0) - outcome = FAIL; - } - - return outcome; -} - -#define MAGIC_EXITCODE 42 - -#ifndef NO_FORKING - -static enum outcome -testcase_run_forked_(const struct testgroup_t *group, - const struct testcase_t *testcase) -{ -#ifdef _WIN32 - /* Fork? On Win32? How primitive! We'll do what the smart kids do: - we'll invoke our own exe (whose name we recall from the command - line) with a command line that tells it to run just the test we - want, and this time without forking. - - (No, threads aren't an option. The whole point of forking is to - share no state between tests.) - */ - int ok; - char buffer[LONGEST_TEST_NAME+256]; - STARTUPINFOA si; - PROCESS_INFORMATION info; - DWORD exitcode; - - if (!in_tinytest_main) { - printf("\nERROR. On Windows, testcase_run_forked_ must be" - " called from within tinytest_main.\n"); - abort(); - } - if (opt_verbosity>0) - printf("[forking] "); - - snprintf(buffer, sizeof(buffer), "%s --RUNNING-FORKED %s %s%s", - commandname, verbosity_flag, group->prefix, testcase->name); - - memset(&si, 0, sizeof(si)); - memset(&info, 0, sizeof(info)); - si.cb = sizeof(si); - - ok = CreateProcessA(commandname, buffer, NULL, NULL, 0, - 0, NULL, NULL, &si, &info); - if (!ok) { - printf("CreateProcess failed!\n"); - return 0; - } - WaitForSingleObject(info.hProcess, INFINITE); - GetExitCodeProcess(info.hProcess, &exitcode); - CloseHandle(info.hProcess); - CloseHandle(info.hThread); - if (exitcode == 0) - return OK; - else if (exitcode == MAGIC_EXITCODE) - return SKIP; - else - return FAIL; -#else - int outcome_pipe[2]; - pid_t pid; - (void)group; - - if (pipe(outcome_pipe)) - perror("opening pipe"); - - if (opt_verbosity>0) - printf("[forking] "); - pid = fork(); -#ifdef FORK_BREAKS_GCOV - vproc_transaction_begin(0); -#endif - if (!pid) { - /* child. */ - int test_r, write_r; - char b[1]; - close(outcome_pipe[0]); - test_r = testcase_run_bare_(testcase); - assert(0<=(int)test_r && (int)test_r<=2); - b[0] = "NYS"[test_r]; - write_r = (int)write(outcome_pipe[1], b, 1); - if (write_r != 1) { - perror("write outcome to pipe"); - exit(1); - } - exit(0); - return FAIL; /* unreachable */ - } else { - /* parent */ - int status, r; - char b[1]; - /* Close this now, so that if the other side closes it, - * our read fails. */ - close(outcome_pipe[1]); - r = (int)read(outcome_pipe[0], b, 1); - if (r == 0) { - printf("[Lost connection!] "); - return 0; - } else if (r != 1) { - perror("read outcome from pipe"); - } - waitpid(pid, &status, 0); - close(outcome_pipe[0]); - return b[0]=='Y' ? OK : (b[0]=='S' ? SKIP : FAIL); - } -#endif -} - -#endif /* !NO_FORKING */ - -int -testcase_run_one(const struct testgroup_t *group, - const struct testcase_t *testcase) -{ - enum outcome outcome; - - if (testcase->flags & (TT_SKIP|TT_OFF_BY_DEFAULT)) { - if (opt_verbosity>0) - printf("%s%s: %s\n", - group->prefix, testcase->name, - (testcase->flags & TT_SKIP) ? "SKIPPED" : "DISABLED"); - ++n_skipped; - return SKIP; - } - - if (opt_verbosity>0 && !opt_forked) { - printf("%s%s: ", group->prefix, testcase->name); - } else { - if (opt_verbosity==0) printf("."); - cur_test_prefix = group->prefix; - cur_test_name = testcase->name; - } - -#ifndef NO_FORKING - if ((testcase->flags & TT_FORK) && !(opt_forked||opt_nofork)) { - outcome = testcase_run_forked_(group, testcase); - } else { -#else - { -#endif - outcome = testcase_run_bare_(testcase); - } - - 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); - } - - if (opt_forked) { - exit(outcome==OK ? 0 : (outcome==SKIP?MAGIC_EXITCODE : 1)); - return 1; /* unreachable */ - } else { - return (int)outcome; - } -} - -int -tinytest_set_flag_(struct testgroup_t *groups, const char *arg, int set, unsigned long flag) -{ - int i, j; - size_t length = LONGEST_TEST_NAME; - char fullname[LONGEST_TEST_NAME]; - int found=0; - if (strstr(arg, "..")) - length = strstr(arg,"..")-arg; - for (i=0; groups[i].prefix; ++i) { - for (j=0; groups[i].cases[j].name; ++j) { - struct testcase_t *testcase = &groups[i].cases[j]; - snprintf(fullname, sizeof(fullname), "%s%s", - groups[i].prefix, testcase->name); - if (!flag) { /* Hack! */ - printf(" %s", fullname); - if (testcase->flags & TT_OFF_BY_DEFAULT) - puts(" (Off by default)"); - else if (testcase->flags & TT_SKIP) - puts(" (DISABLED)"); - else - puts(""); - } - if (!strncmp(fullname, arg, length)) { - if (set) - testcase->flags |= flag; - else - testcase->flags &= ~flag; - ++found; - } - } - } - return found; -} - -static void -usage(struct testgroup_t *groups, int list_groups) -{ - puts("Options are: [--verbose|--quiet|--terse] [--no-fork]"); - puts(" Specify tests by name, or using a prefix ending with '..'"); - puts(" To skip a test, prefix its name with a colon."); - puts(" To enable a disabled test, prefix its name with a plus."); - puts(" Use --list-tests for a list of tests."); - if (list_groups) { - puts("Known tests are:"); - tinytest_set_flag_(groups, "..", 1, 0); - } - exit(0); -} - -static int -process_test_alias(struct testgroup_t *groups, const char *test) -{ - int i, j, n, r; - for (i=0; cfg_aliases && cfg_aliases[i].name; ++i) { - if (!strcmp(cfg_aliases[i].name, test)) { - n = 0; - for (j = 0; cfg_aliases[i].tests[j]; ++j) { - r = process_test_option(groups, cfg_aliases[i].tests[j]); - if (r<0) - return -1; - n += r; - } - return n; - } - } - printf("No such test alias as @%s!",test); - return -1; -} - -static int -process_test_option(struct testgroup_t *groups, const char *test) -{ - int flag = TT_ENABLED_; - int n = 0; - if (test[0] == '@') { - return process_test_alias(groups, test + 1); - } else if (test[0] == ':') { - ++test; - flag = TT_SKIP; - } else if (test[0] == '+') { - ++test; - ++n; - if (!tinytest_set_flag_(groups, test, 0, TT_OFF_BY_DEFAULT)) { - printf("No such test as %s!\n", test); - return -1; - } - } else { - ++n; - } - if (!tinytest_set_flag_(groups, test, 1, flag)) { - printf("No such test as %s!\n", test); - return -1; - } - return n; -} - -void -tinytest_set_aliases(const struct testlist_alias_t *aliases) -{ - cfg_aliases = aliases; -} - -int -tinytest_main(int c, const char **v, struct testgroup_t *groups) -{ - int i, j, n=0; - -#ifdef _WIN32 - const char *sp = strrchr(v[0], '.'); - const char *extension = ""; - if (!sp || stricmp(sp, ".exe")) - extension = ".exe"; /* Add an exe so CreateProcess will work */ - snprintf(commandname, sizeof(commandname), "%s%s", v[0], extension); - commandname[MAX_PATH]='\0'; -#endif - for (i=1; i<c; ++i) { - if (v[i][0] == '-') { - if (!strcmp(v[i], "--RUNNING-FORKED")) { - opt_forked = 1; - } else if (!strcmp(v[i], "--no-fork")) { - opt_nofork = 1; - } else if (!strcmp(v[i], "--quiet")) { - opt_verbosity = -1; - verbosity_flag = "--quiet"; - } else if (!strcmp(v[i], "--verbose")) { - opt_verbosity = 2; - verbosity_flag = "--verbose"; - } else if (!strcmp(v[i], "--terse")) { - opt_verbosity = 0; - verbosity_flag = "--terse"; - } else if (!strcmp(v[i], "--help")) { - usage(groups, 0); - } else if (!strcmp(v[i], "--list-tests")) { - usage(groups, 1); - } else { - printf("Unknown option %s. Try --help\n",v[i]); - return -1; - } - } else { - int r = process_test_option(groups, v[i]); - if (r<0) - return -1; - n += r; - } - } - if (!n) - tinytest_set_flag_(groups, "..", 1, TT_ENABLED_); - -#ifdef _IONBF - setvbuf(stdout, NULL, _IONBF, 0); -#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]); - - --in_tinytest_main; - - if (opt_verbosity==0) - puts(""); - - if (n_bad) - printf("%d/%d TESTS FAILED. (%d skipped)\n", n_bad, - n_bad+n_ok,n_skipped); - else if (opt_verbosity >= 1) - printf("%d tests ok. (%d skipped)\n", n_ok, n_skipped); - - return (n_bad == 0) ? 0 : 1; -} - -int -tinytest_get_verbosity_(void) -{ - return opt_verbosity; -} - -void -tinytest_set_test_failed_(void) -{ - if (opt_verbosity <= 0 && cur_test_name) { - if (opt_verbosity==0) puts(""); - printf("%s%s: ", cur_test_prefix, cur_test_name); - cur_test_name = NULL; - } - cur_test_outcome = 0; -} - -void -tinytest_set_test_skipped_(void) -{ - if (cur_test_outcome==OK) - cur_test_outcome = SKIP; -} - -char * -tinytest_format_hex_(const void *val_, unsigned long len) -{ - const unsigned char *val = val_; - char *result, *cp; - size_t i; - - if (!val) - return strdup("null"); - if (!(result = malloc(len*2+1))) - return strdup("<allocation failure>"); - cp = result; - for (i=0;i<len;++i) { - *cp++ = "0123456789ABCDEF"[val[i] >> 4]; - *cp++ = "0123456789ABCDEF"[val[i] & 0x0f]; - } - *cp = 0; - return result; -} diff --git a/protocols/Telegram/tgl/libevent/test/tinytest.h b/protocols/Telegram/tgl/libevent/test/tinytest.h deleted file mode 100644 index ed07b26bc0..0000000000 --- a/protocols/Telegram/tgl/libevent/test/tinytest.h +++ /dev/null @@ -1,100 +0,0 @@ -/* tinytest.h -- Copyright 2009-2012 Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TINYTEST_H_INCLUDED_ -#define TINYTEST_H_INCLUDED_ - -/** Flag for a test that needs to run in a subprocess. */ -#define TT_FORK (1<<0) -/** Runtime flag for a test we've decided to skip. */ -#define TT_SKIP (1<<1) -/** Internal runtime flag for a test we've decided to run. */ -#define TT_ENABLED_ (1<<2) -/** Flag for a test that's off by default. */ -#define TT_OFF_BY_DEFAULT (1<<3) -/** If you add your own flags, make them start at this point. */ -#define TT_FIRST_USER_FLAG (1<<4) - -typedef void (*testcase_fn)(void *); - -struct testcase_t; - -/** Functions to initialize/teardown a structure for a testcase. */ -struct testcase_setup_t { - /** Return a new structure for use by a given testcase. */ - void *(*setup_fn)(const struct testcase_t *); - /** Clean/free a structure from setup_fn. Return 1 if ok, 0 on err. */ - int (*cleanup_fn)(const struct testcase_t *, void *); -}; - -/** A single test-case that you can run. */ -struct testcase_t { - const char *name; /**< An identifier for this case. */ - testcase_fn fn; /**< The function to run to implement this case. */ - unsigned long flags; /**< Bitfield of TT_* flags. */ - const struct testcase_setup_t *setup; /**< Optional setup/cleanup fns*/ - void *setup_data; /**< Extra data usable by setup function */ -}; -#define END_OF_TESTCASES { NULL, NULL, 0, NULL, NULL } - -/** A group of tests that are selectable together. */ -struct testgroup_t { - const char *prefix; /**< Prefix to prepend to testnames. */ - struct testcase_t *cases; /** Array, ending with END_OF_TESTCASES */ -}; -#define END_OF_GROUPS { NULL, NULL} - -struct testlist_alias_t { - const char *name; - const char **tests; -}; -#define END_OF_ALIASES { NULL, NULL } - -/** Implementation: called from a test to indicate failure, before logging. */ -void tinytest_set_test_failed_(void); -/** Implementation: called from a test to indicate that we're skipping. */ -void tinytest_set_test_skipped_(void); -/** Implementation: return 0 for quiet, 1 for normal, 2 for loud. */ -int tinytest_get_verbosity_(void); -/** Implementation: Set a flag on tests matching a name; returns number - * of tests that matched. */ -int tinytest_set_flag_(struct testgroup_t *, const char *, int set, unsigned long); -/** Implementation: Put a chunk of memory into hex. */ -char *tinytest_format_hex_(const void *, unsigned long); - -/** Set all tests in 'groups' matching the name 'named' to be skipped. */ -#define tinytest_skip(groups, named) \ - tinytest_set_flag_(groups, named, 1, TT_SKIP) - -/** Run a single testcase in a single group. */ -int testcase_run_one(const struct testgroup_t *,const struct testcase_t *); - -void tinytest_set_aliases(const struct testlist_alias_t *aliases); - -/** Run a set of testcases from an END_OF_GROUPS-terminated array of groups, - as selected from the command line. */ -int tinytest_main(int argc, const char **argv, struct testgroup_t *groups); - -#endif diff --git a/protocols/Telegram/tgl/libevent/test/tinytest.obj b/protocols/Telegram/tgl/libevent/test/tinytest.obj Binary files differdeleted file mode 100644 index f9b5885695..0000000000 --- a/protocols/Telegram/tgl/libevent/test/tinytest.obj +++ /dev/null diff --git a/protocols/Telegram/tgl/libevent/test/tinytest_demo.c b/protocols/Telegram/tgl/libevent/test/tinytest_demo.c deleted file mode 100644 index f6bfd66a1a..0000000000 --- a/protocols/Telegram/tgl/libevent/test/tinytest_demo.c +++ /dev/null @@ -1,262 +0,0 @@ -/* tinytest_demo.c -- Copyright 2009-2012 Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -/* Welcome to the example file for tinytest! I'll show you how to set up - * some simple and not-so-simple testcases. */ - -/* Make sure you include these headers. */ -#include "tinytest.h" -#include "tinytest_macros.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <time.h> -#ifdef _WIN32 -#include <windows.h> -#else -#include <unistd.h> -#endif - -/* ============================================================ */ - -/* First, let's see if strcmp is working. (All your test cases should be - * functions declared to take a single void * as an argument.) */ -void -test_strcmp(void *data) -{ - (void)data; /* This testcase takes no data. */ - - /* Let's make sure the empty string is equal to itself */ - if (strcmp("","")) { - /* This macro tells tinytest to stop the current test - * and go straight to the "end" label. */ - tt_abort_msg("The empty string was not equal to itself"); - } - - /* Pretty often, calling tt_abort_msg to indicate failure is more - heavy-weight than you want. Instead, just say: */ - tt_assert(strcmp("testcase", "testcase") == 0); - - /* Occasionally, you don't want to stop the current testcase just - because a single assertion has failed. In that case, use - tt_want: */ - tt_want(strcmp("tinytest", "testcase") > 0); - - /* You can use the tt_*_op family of macros to compare values and to - fail unless they have the relationship you want. They produce - more useful output than tt_assert, since they display the actual - values of the failing things. - - Fail unless strcmp("abc, "abc") == 0 */ - tt_int_op(strcmp("abc", "abc"), ==, 0); - - /* Fail unless strcmp("abc, "abcd") is less than 0 */ - tt_int_op(strcmp("abc", "abcd"), < , 0); - - /* Incidentally, there's a test_str_op that uses strcmp internally. */ - tt_str_op("abc", <, "abcd"); - - - /* Every test-case function needs to finish with an "end:" - label and (optionally) code to clean up local variables. */ - end: - ; -} - -/* ============================================================ */ - -/* Now let's mess with setup and teardown functions! These are handy if - you have a bunch of tests that all need a similar environment, and you - want to reconstruct that environment freshly for each one. */ - -/* First you declare a type to hold the environment info, and functions to - set it up and tear it down. */ -struct data_buffer { - /* We're just going to have couple of character buffer. Using - setup/teardown functions is probably overkill for this case. - - You could also do file descriptors, complicated handles, temporary - files, etc. */ - char buffer1[512]; - char buffer2[512]; -}; -/* The setup function needs to take a const struct testcase_t and return - void* */ -void * -setup_data_buffer(const struct testcase_t *testcase) -{ - struct data_buffer *db = malloc(sizeof(struct data_buffer)); - - /* If you had a complicated set of setup rules, you might behave - differently here depending on testcase->flags or - testcase->setup_data or even or testcase->name. */ - - /* Returning a NULL here would mean that we couldn't set up for this - test, so we don't need to test db for null. */ - return db; -} -/* The clean function deallocates storage carefully and returns true on - success. */ -int -clean_data_buffer(const struct testcase_t *testcase, void *ptr) -{ - struct data_buffer *db = ptr; - - if (db) { - free(db); - return 1; - } - return 0; -} -/* Finally, declare a testcase_setup_t with these functions. */ -struct testcase_setup_t data_buffer_setup = { - setup_data_buffer, clean_data_buffer -}; - - -/* Now let's write our test. */ -void -test_memcpy(void *ptr) -{ - /* This time, we use the argument. */ - struct data_buffer *db = ptr; - - /* We'll also introduce a local variable that might need cleaning up. */ - char *mem = NULL; - - /* Let's make sure that memcpy does what we'd like. */ - strcpy(db->buffer1, "String 0"); - memcpy(db->buffer2, db->buffer1, sizeof(db->buffer1)); - tt_str_op(db->buffer1, ==, db->buffer2); - - /* This one works if there's an internal NUL. */ - tt_mem_op(db->buffer1, <, db->buffer2, sizeof(db->buffer1)); - - /* Now we've allocated memory that's referenced by a local variable. - The end block of the function will clean it up. */ - mem = strdup("Hello world."); - tt_assert(mem); - - /* Another rather trivial test. */ - tt_str_op(db->buffer1, !=, mem); - - end: - /* This time our end block has something to do. */ - if (mem) - free(mem); -} - -void -test_timeout(void *ptr) -{ - 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 - a bunch of related tests and put them into an array of struct testcase_t. -*/ - -struct testcase_t demo_tests[] = { - /* Here's a really simple test: it has a name you can refer to it - with, and a function to invoke it. */ - { "strcmp", test_strcmp, }, - - /* The second test has a flag, "TT_FORK", to make it run in a - subprocess, and a pointer to the testcase_setup_t that configures - its environment. */ - { "memcpy", test_memcpy, TT_FORK, &data_buffer_setup }, - - /* This flag is off-by-default, since it takes a while to run. You - * can enable it manually by passing +demo/timeout at the command line.*/ - { "timeout", test_timeout, TT_OFF_BY_DEFAULT }, - - /* The array has to end with END_OF_TESTCASES. */ - END_OF_TESTCASES -}; - -/* Next, we make an array of testgroups. This is mandatory. Unlike more - heavy-duty testing frameworks, groups can't nest. */ -struct testgroup_t groups[] = { - - /* Every group has a 'prefix', and an array of tests. That's it. */ - { "demo/", demo_tests }, - - END_OF_GROUPS -}; - -/* We can also define test aliases. These can be used for types of tests that - * cut across groups. */ -const char *alltests[] = { "+..", NULL }; -const char *slowtests[] = { "+demo/timeout", NULL }; -struct testlist_alias_t aliases[] = { - - { "ALL", alltests }, - { "SLOW", slowtests }, - - END_OF_ALIASES -}; - - -int -main(int c, const char **v) -{ - /* Finally, just call tinytest_main(). It lets you specify verbose - or quiet output with --verbose and --quiet. You can list - specific tests: - - tinytest-demo demo/memcpy - - or use a ..-wildcard to select multiple tests with a common - prefix: - - tinytest-demo demo/.. - - If you list no tests, you get them all by default, so that - "tinytest-demo" and "tinytest-demo .." mean the same thing. - - */ - tinytest_set_aliases(aliases); - return tinytest_main(c, v, groups); -} diff --git a/protocols/Telegram/tgl/libevent/test/tinytest_local.h b/protocols/Telegram/tgl/libevent/test/tinytest_local.h deleted file mode 100644 index 87ec2fa67e..0000000000 --- a/protocols/Telegram/tgl/libevent/test/tinytest_local.h +++ /dev/null @@ -1,12 +0,0 @@ - -#include "util-internal.h" -#ifdef _WIN32 -#include <winsock2.h> -#endif - -#include "event2/util.h" - -#ifdef snprintf -#undef snprintf -#endif -#define snprintf evutil_snprintf diff --git a/protocols/Telegram/tgl/libevent/test/tinytest_macros.h b/protocols/Telegram/tgl/libevent/test/tinytest_macros.h deleted file mode 100644 index c3728d1fdd..0000000000 --- a/protocols/Telegram/tgl/libevent/test/tinytest_macros.h +++ /dev/null @@ -1,199 +0,0 @@ -/* tinytest_macros.h -- Copyright 2009-2012 Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TINYTEST_MACROS_H_INCLUDED_ -#define TINYTEST_MACROS_H_INCLUDED_ - -/* Helpers for defining statement-like macros */ -#define TT_STMT_BEGIN do { -#define TT_STMT_END } while (0) - -/* Redefine this if your test functions want to abort with something besides - * "goto end;" */ -#ifndef TT_EXIT_TEST_FUNCTION -#define TT_EXIT_TEST_FUNCTION TT_STMT_BEGIN goto end; TT_STMT_END -#endif - -/* Redefine this if you want to note success/failure in some different way. */ -#ifndef TT_DECLARE -#define TT_DECLARE(prefix, args) \ - TT_STMT_BEGIN \ - printf("\n %s %s:%d: ",prefix,__FILE__,__LINE__); \ - printf args ; \ - TT_STMT_END -#endif - -/* Announce a failure. Args are parenthesized printf args. */ -#define TT_GRIPE(args) TT_DECLARE("FAIL", args) - -/* Announce a non-failure if we're verbose. */ -#define TT_BLATHER(args) \ - TT_STMT_BEGIN \ - if (tinytest_get_verbosity_()>1) TT_DECLARE(" OK", args); \ - TT_STMT_END - -#define TT_DIE(args) \ - TT_STMT_BEGIN \ - tinytest_set_test_failed_(); \ - TT_GRIPE(args); \ - TT_EXIT_TEST_FUNCTION; \ - TT_STMT_END - -#define TT_FAIL(args) \ - TT_STMT_BEGIN \ - tinytest_set_test_failed_(); \ - TT_GRIPE(args); \ - TT_STMT_END - -/* Fail and abort the current test for the reason in msg */ -#define tt_abort_printf(msg) TT_DIE(msg) -#define tt_abort_perror(op) TT_DIE(("%s: %s [%d]",(op),strerror(errno), errno)) -#define tt_abort_msg(msg) TT_DIE(("%s", msg)) -#define tt_abort() TT_DIE(("%s", "(Failed.)")) - -/* Fail but do not abort the current test for the reason in msg. */ -#define tt_failprint_f(msg) TT_FAIL(msg) -#define tt_fail_perror(op) TT_FAIL(("%s: %s [%d]",(op),strerror(errno), errno)) -#define tt_fail_msg(msg) TT_FAIL(("%s", msg)) -#define tt_fail() TT_FAIL(("%s", "(Failed.)")) - -/* End the current test, and indicate we are skipping it. */ -#define tt_skip() \ - TT_STMT_BEGIN \ - tinytest_set_test_skipped_(); \ - TT_EXIT_TEST_FUNCTION; \ - TT_STMT_END - -#define tt_want_(b, msg, fail) \ - TT_STMT_BEGIN \ - if (!(b)) { \ - tinytest_set_test_failed_(); \ - TT_GRIPE(("%s",msg)); \ - fail; \ - } else { \ - TT_BLATHER(("%s",msg)); \ - } \ - TT_STMT_END - -/* Assert b, but do not stop the test if b fails. Log msg on failure. */ -#define tt_want_msg(b, msg) \ - tt_want_(b, msg, ); - -/* Assert b and stop the test if b fails. Log msg on failure. */ -#define tt_assert_msg(b, msg) \ - tt_want_(b, msg, TT_EXIT_TEST_FUNCTION); - -/* Assert b, but do not stop the test if b fails. */ -#define tt_want(b) tt_want_msg( (b), "want("#b")") -/* Assert b, and stop the test if b fails. */ -#define tt_assert(b) tt_assert_msg((b), "assert("#b")") - -#define tt_assert_test_fmt_type(a,b,str_test,type,test,printf_type,printf_fmt, \ - setup_block,cleanup_block,die_on_fail) \ - TT_STMT_BEGIN \ - type val1_ = (a); \ - type val2_ = (b); \ - int tt_status_ = (test); \ - if (!tt_status_ || tinytest_get_verbosity_()>1) { \ - printf_type print_; \ - printf_type print1_; \ - printf_type print2_; \ - type value_ = val1_; \ - setup_block; \ - print1_ = print_; \ - value_ = val2_; \ - setup_block; \ - print2_ = print_; \ - TT_DECLARE(tt_status_?" OK":"FAIL", \ - ("assert(%s): "printf_fmt" vs "printf_fmt, \ - str_test, print1_, print2_)); \ - print_ = print1_; \ - cleanup_block; \ - print_ = print2_; \ - cleanup_block; \ - if (!tt_status_) { \ - tinytest_set_test_failed_(); \ - die_on_fail ; \ - } \ - } \ - TT_STMT_END - -#define tt_assert_test_type(a,b,str_test,type,test,fmt,die_on_fail) \ - tt_assert_test_fmt_type(a,b,str_test,type,test,type,fmt, \ - {print_=value_;},{},die_on_fail) - -#define tt_assert_test_type_opt(a,b,str_test,type,test,fmt,die_on_fail) \ - tt_assert_test_fmt_type(a,b,str_test,type,test,type,fmt, \ - {print_=value_?value_:"<NULL>";},{},die_on_fail) - -/* Helper: assert that a op b, when cast to type. Format the values with - * printf format fmt on failure. */ -#define tt_assert_op_type(a,op,b,type,fmt) \ - tt_assert_test_type(a,b,#a" "#op" "#b,type,(val1_ op val2_),fmt, \ - TT_EXIT_TEST_FUNCTION) - -#define tt_int_op(a,op,b) \ - tt_assert_test_type(a,b,#a" "#op" "#b,long,(val1_ op val2_), \ - "%ld",TT_EXIT_TEST_FUNCTION) - -#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) - -#define tt_ptr_op(a,op,b) \ - tt_assert_test_type(a,b,#a" "#op" "#b,const void*, \ - (val1_ op val2_),"%p",TT_EXIT_TEST_FUNCTION) - -#define tt_str_op(a,op,b) \ - tt_assert_test_type_opt(a,b,#a" "#op" "#b,const char *, \ - (val1_ && val2_ && strcmp(val1_,val2_) op 0),"<%s>", \ - TT_EXIT_TEST_FUNCTION) - -#define tt_mem_op(expr1, op, expr2, len) \ - tt_assert_test_fmt_type(expr1,expr2,#expr1" "#op" "#expr2, \ - const void *, \ - (val1_ && val2_ && memcmp(val1_, val2_, len) op 0), \ - char *, "%s", \ - { print_ = tinytest_format_hex_(value_, (len)); }, \ - { if (print_) free(print_); }, \ - TT_EXIT_TEST_FUNCTION \ - ); - -#define tt_want_int_op(a,op,b) \ - tt_assert_test_type(a,b,#a" "#op" "#b,long,(val1_ op val2_),"%ld",(void)0) - -#define tt_want_uint_op(a,op,b) \ - tt_assert_test_type(a,b,#a" "#op" "#b,unsigned long, \ - (val1_ op val2_),"%lu",(void)0) - -#define tt_want_ptr_op(a,op,b) \ - tt_assert_test_type(a,b,#a" "#op" "#b,const void*, \ - (val1_ op val2_),"%p",(void)0) - -#define tt_want_str_op(a,op,b) \ - tt_assert_test_type(a,b,#a" "#op" "#b,const char *, \ - (strcmp(val1_,val2_) op 0),"<%s>",(void)0) - -#endif |