1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/chromium/src/third_party/libevent/test/regress_testutils.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,220 @@ 1.4 +/* 1.5 + * Copyright (c) 2010-2012 Niels Provos and Nick Mathewson 1.6 + * 1.7 + * Redistribution and use in source and binary forms, with or without 1.8 + * modification, are permitted provided that the following conditions 1.9 + * are met: 1.10 + * 1. Redistributions of source code must retain the above copyright 1.11 + * notice, this list of conditions and the following disclaimer. 1.12 + * 2. Redistributions in binary form must reproduce the above copyright 1.13 + * notice, this list of conditions and the following disclaimer in the 1.14 + * documentation and/or other materials provided with the distribution. 1.15 + * 3. The name of the author may not be used to endorse or promote products 1.16 + * derived from this software without specific prior written permission. 1.17 + * 1.18 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1.19 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1.20 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1.21 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 1.22 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 1.23 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.24 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.25 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.26 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 1.27 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.28 + */ 1.29 + 1.30 +#ifdef WIN32 1.31 +#include <winsock2.h> 1.32 +#include <windows.h> 1.33 +#include <ws2tcpip.h> 1.34 +#endif 1.35 + 1.36 +#include "event2/event-config.h" 1.37 + 1.38 +#include <sys/types.h> 1.39 +#include <sys/stat.h> 1.40 +#ifdef _EVENT_HAVE_SYS_TIME_H 1.41 +#include <sys/time.h> 1.42 +#endif 1.43 +#include <sys/queue.h> 1.44 +#ifndef WIN32 1.45 +#include <sys/socket.h> 1.46 +#include <signal.h> 1.47 +#include <netinet/in.h> 1.48 +#include <arpa/inet.h> 1.49 +#include <unistd.h> 1.50 +#endif 1.51 +#ifdef _EVENT_HAVE_NETINET_IN6_H 1.52 +#include <netinet/in6.h> 1.53 +#endif 1.54 +#ifdef HAVE_NETDB_H 1.55 +#include <netdb.h> 1.56 +#endif 1.57 +#include <fcntl.h> 1.58 +#include <stdlib.h> 1.59 +#include <stdio.h> 1.60 +#include <string.h> 1.61 +#include <errno.h> 1.62 + 1.63 +#include "event2/dns.h" 1.64 +#include "event2/dns_struct.h" 1.65 +#include "event2/event.h" 1.66 +#include "event2/event_compat.h" 1.67 +#include "event2/util.h" 1.68 +#include "event2/listener.h" 1.69 +#include "event2/bufferevent.h" 1.70 +#include "log-internal.h" 1.71 +#include "regress.h" 1.72 +#include "regress_testutils.h" 1.73 + 1.74 +#include "../util-internal.h" 1.75 + 1.76 +/* globals */ 1.77 +static struct evdns_server_port *dns_port; 1.78 +evutil_socket_t dns_sock = -1; 1.79 + 1.80 +/* Helper: return the port that a socket is bound on, in host order. */ 1.81 +int 1.82 +regress_get_socket_port(evutil_socket_t fd) 1.83 +{ 1.84 + struct sockaddr_storage ss; 1.85 + ev_socklen_t socklen = sizeof(ss); 1.86 + if (getsockname(fd, (struct sockaddr*)&ss, &socklen) != 0) 1.87 + return -1; 1.88 + if (ss.ss_family == AF_INET) 1.89 + return ntohs( ((struct sockaddr_in*)&ss)->sin_port); 1.90 + else if (ss.ss_family == AF_INET6) 1.91 + return ntohs( ((struct sockaddr_in6*)&ss)->sin6_port); 1.92 + else 1.93 + return -1; 1.94 +} 1.95 + 1.96 +struct evdns_server_port * 1.97 +regress_get_dnsserver(struct event_base *base, 1.98 + ev_uint16_t *portnum, 1.99 + evutil_socket_t *psock, 1.100 + evdns_request_callback_fn_type cb, 1.101 + void *arg) 1.102 +{ 1.103 + struct evdns_server_port *port = NULL; 1.104 + evutil_socket_t sock; 1.105 + struct sockaddr_in my_addr; 1.106 + 1.107 + sock = socket(AF_INET, SOCK_DGRAM, 0); 1.108 + if (sock < 0) { 1.109 + tt_abort_perror("socket"); 1.110 + } 1.111 + 1.112 + evutil_make_socket_nonblocking(sock); 1.113 + 1.114 + memset(&my_addr, 0, sizeof(my_addr)); 1.115 + my_addr.sin_family = AF_INET; 1.116 + my_addr.sin_port = htons(*portnum); 1.117 + my_addr.sin_addr.s_addr = htonl(0x7f000001UL); 1.118 + if (bind(sock, (struct sockaddr*)&my_addr, sizeof(my_addr)) < 0) { 1.119 + evutil_closesocket(sock); 1.120 + tt_abort_perror("bind"); 1.121 + } 1.122 + port = evdns_add_server_port_with_base(base, sock, 0, cb, arg); 1.123 + if (!*portnum) 1.124 + *portnum = regress_get_socket_port(sock); 1.125 + if (psock) 1.126 + *psock = sock; 1.127 + 1.128 + return port; 1.129 +end: 1.130 + return NULL; 1.131 +} 1.132 + 1.133 +void 1.134 +regress_clean_dnsserver(void) 1.135 +{ 1.136 + if (dns_port) 1.137 + evdns_close_server_port(dns_port); 1.138 + if (dns_sock >= 0) 1.139 + evutil_closesocket(dns_sock); 1.140 +} 1.141 + 1.142 +void 1.143 +regress_dns_server_cb(struct evdns_server_request *req, void *data) 1.144 +{ 1.145 + struct regress_dns_server_table *tab = data; 1.146 + const char *question; 1.147 + 1.148 + if (req->nquestions != 1) 1.149 + TT_DIE(("Only handling one question at a time; got %d", 1.150 + req->nquestions)); 1.151 + 1.152 + question = req->questions[0]->name; 1.153 + 1.154 + while (tab->q && evutil_ascii_strcasecmp(question, tab->q) && 1.155 + strcmp("*", tab->q)) 1.156 + ++tab; 1.157 + if (tab->q == NULL) 1.158 + TT_DIE(("Unexpected question: '%s'", question)); 1.159 + 1.160 + ++tab->seen; 1.161 + 1.162 + if (!strcmp(tab->anstype, "err")) { 1.163 + int err = atoi(tab->ans); 1.164 + tt_assert(! evdns_server_request_respond(req, err)); 1.165 + return; 1.166 + } else if (!strcmp(tab->anstype, "errsoa")) { 1.167 + int err = atoi(tab->ans); 1.168 + char soa_record[] = 1.169 + "\x04" "dns1" "\x05" "icann" "\x03" "org" "\0" 1.170 + "\x0a" "hostmaster" "\x05" "icann" "\x03" "org" "\0" 1.171 + "\x77\xde\x5e\xba" /* serial */ 1.172 + "\x00\x00\x1c\x20" /* refreshtime = 2h */ 1.173 + "\x00\x00\x0e\x10" /* retry = 1h */ 1.174 + "\x00\x12\x75\x00" /* expiration = 14d */ 1.175 + "\x00\x00\x0e\x10" /* min.ttl = 1h */ 1.176 + ; 1.177 + evdns_server_request_add_reply( 1.178 + req, EVDNS_AUTHORITY_SECTION, 1.179 + "example.com", EVDNS_TYPE_SOA, EVDNS_CLASS_INET, 1.180 + 42, sizeof(soa_record) - 1, 0, soa_record); 1.181 + tt_assert(! evdns_server_request_respond(req, err)); 1.182 + return; 1.183 + } else if (!strcmp(tab->anstype, "A")) { 1.184 + struct in_addr in; 1.185 + if (!evutil_inet_pton(AF_INET, tab->ans, &in)) { 1.186 + TT_DIE(("Bad A value %s in table", tab->ans)); 1.187 + } 1.188 + evdns_server_request_add_a_reply(req, question, 1, &in.s_addr, 1.189 + 100); 1.190 + } else if (!strcmp(tab->anstype, "AAAA")) { 1.191 + struct in6_addr in6; 1.192 + if (!evutil_inet_pton(AF_INET6, tab->ans, &in6)) { 1.193 + TT_DIE(("Bad AAAA value %s in table", tab->ans)); 1.194 + } 1.195 + evdns_server_request_add_aaaa_reply(req, 1.196 + question, 1, &in6.s6_addr, 100); 1.197 + } else { 1.198 + TT_DIE(("Weird table entry with type '%s'", tab->anstype)); 1.199 + } 1.200 + tt_assert(! evdns_server_request_respond(req, 0)) 1.201 + return; 1.202 +end: 1.203 + tt_want(! evdns_server_request_drop(req)); 1.204 +} 1.205 + 1.206 +int 1.207 +regress_dnsserver(struct event_base *base, ev_uint16_t *port, 1.208 + struct regress_dns_server_table *search_table) 1.209 +{ 1.210 + dns_port = regress_get_dnsserver(base, port, &dns_sock, 1.211 + regress_dns_server_cb, search_table); 1.212 + return dns_port != NULL; 1.213 +} 1.214 + 1.215 +int 1.216 +regress_get_listener_addr(struct evconnlistener *lev, 1.217 + struct sockaddr *sa, ev_socklen_t *socklen) 1.218 +{ 1.219 + evutil_socket_t s = evconnlistener_get_fd(lev); 1.220 + if (s <= 0) 1.221 + return -1; 1.222 + return getsockname(s, sa, socklen); 1.223 +}