2009-01-02 20:46:12 +00:00
|
|
|
/*
|
2012-02-10 17:29:53 -05:00
|
|
|
* Copyright (c) 2009-2012 Nick Mathewson and Niels Provos
|
2009-01-02 20:46:12 +00:00
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
2018-10-28 19:30:34 +03:00
|
|
|
|
|
|
|
/** For event_debug() usage/coverage */
|
|
|
|
#define EVENT_VISIBILITY_WANT_DLLIMPORT
|
|
|
|
|
2012-01-24 16:08:00 -05:00
|
|
|
#include "../util-internal.h"
|
|
|
|
|
2011-05-25 19:50:56 -04:00
|
|
|
#ifdef _WIN32
|
2009-01-02 20:46:12 +00:00
|
|
|
#include <winsock2.h>
|
|
|
|
#include <windows.h>
|
2009-01-13 21:39:32 +00:00
|
|
|
#include <ws2tcpip.h>
|
2009-01-02 20:46:12 +00:00
|
|
|
#endif
|
|
|
|
|
2010-07-07 16:45:03 -04:00
|
|
|
#include "event2/event-config.h"
|
2009-11-06 21:46:57 +00:00
|
|
|
|
2009-11-17 02:40:14 +00:00
|
|
|
#include <sys/types.h>
|
|
|
|
|
2011-05-25 19:50:56 -04:00
|
|
|
#ifndef _WIN32
|
2009-01-02 20:46:12 +00:00
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <netinet/in.h>
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
#include <unistd.h>
|
2019-10-18 21:11:37 +08:00
|
|
|
#include <sys/un.h>
|
2009-01-02 20:46:12 +00:00
|
|
|
#endif
|
2012-02-29 15:07:31 -05:00
|
|
|
#ifdef EVENT__HAVE_NETINET_IN6_H
|
2009-01-02 20:46:12 +00:00
|
|
|
#include <netinet/in6.h>
|
|
|
|
#endif
|
2012-02-29 15:07:31 -05:00
|
|
|
#ifdef EVENT__HAVE_SYS_WAIT_H
|
2010-05-14 14:30:09 -04:00
|
|
|
#include <sys/wait.h>
|
|
|
|
#endif
|
2019-10-18 21:11:37 +08:00
|
|
|
#ifdef EVENT__HAVE_AFUNIX_H
|
|
|
|
#include <afunix.h>
|
|
|
|
#endif
|
2009-04-23 00:21:23 +00:00
|
|
|
#include <signal.h>
|
2009-01-02 20:46:12 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
2009-10-26 19:59:51 +00:00
|
|
|
#include "event2/event.h"
|
2009-01-02 20:46:12 +00:00
|
|
|
#include "event2/util.h"
|
2009-01-02 21:21:58 +00:00
|
|
|
#include "../ipv6-internal.h"
|
2009-10-26 19:59:51 +00:00
|
|
|
#include "../log-internal.h"
|
2009-10-29 16:35:09 +00:00
|
|
|
#include "../strlcpy-internal.h"
|
Add argument checks to some memory functions in `event.c'.
Add a zero check to the function `event_mm_malloc_',
i.e. simply return NULL if the sz argument is zero.
On failure, set errno to ENOMEM and return NULL.
Add a zero check to the function `event_mm_calloc_',
i.e. simply return NULL if either argument is zero.
Also add an unsigned integer multiplication check, and if an integer
overflow would occur, set errno to ENOMEM and return NULL.
On failure, set errno to ENOMEM and return NULL.
Add a NULL check to the function `event_mm_strdup_',
i.e. set errno to EINVAL and return NULL.
Also add an unsigned integer addition check, and if an integer
overflow would occur, set errno to ENOMEM and return NULL.
If a memory allocation error occurs, again set errno to ENOMEM
and return NULL.
Add unit tests to `test/regress_util.c'.
2011-10-14 17:16:03 -04:00
|
|
|
#include "../mm-internal.h"
|
2012-04-20 12:27:12 -04:00
|
|
|
#include "../time-internal.h"
|
2009-01-02 20:46:12 +00:00
|
|
|
|
2009-01-29 23:19:57 +00:00
|
|
|
#include "regress.h"
|
2009-01-02 20:46:12 +00:00
|
|
|
|
|
|
|
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 },
|
2009-01-31 19:32:20 +00:00
|
|
|
{ "::1.2.3.4", { 0, 0, 0, 0x01020304, }, CANONICAL },
|
2009-01-02 20:46:12 +00:00
|
|
|
{ "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 },
|
2010-02-18 17:41:15 -05:00
|
|
|
{ "::1.0.1.1000", { 0, 0, 0, 0 }, BAD },
|
2009-01-02 20:46:12 +00:00
|
|
|
{ "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
|
2009-01-29 23:19:57 +00:00
|
|
|
regress_ipv4_parse(void *ptr)
|
2009-01-02 20:46:12 +00:00
|
|
|
{
|
|
|
|
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) {
|
2009-01-29 23:19:57 +00:00
|
|
|
TT_FAIL(("%s did not parse, but it's a good address!",
|
|
|
|
ent->addr));
|
2009-01-02 20:46:12 +00:00
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (ent->status == BAD) {
|
2009-01-29 23:19:57 +00:00
|
|
|
TT_FAIL(("%s parsed, but we expected an error", ent->addr));
|
2009-01-02 20:46:12 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (ntohl(in.s_addr) != ent->res) {
|
2009-01-29 23:19:57 +00:00
|
|
|
TT_FAIL(("%s parsed to %lx, but we expected %lx", ent->addr,
|
|
|
|
(unsigned long)ntohl(in.s_addr),
|
|
|
|
(unsigned long)ent->res));
|
2009-01-02 20:46:12 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (ent->status == CANONICAL) {
|
|
|
|
const char *w = evutil_inet_ntop(AF_INET, &in, written,
|
|
|
|
sizeof(written));
|
|
|
|
if (!w) {
|
2009-01-29 23:19:57 +00:00
|
|
|
TT_FAIL(("Tried to write out %s; got NULL.", ent->addr));
|
2009-01-02 20:46:12 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (strcmp(written, ent->addr)) {
|
2009-01-29 23:19:57 +00:00
|
|
|
TT_FAIL(("Tried to write out %s; got %s",
|
|
|
|
ent->addr, written));
|
2009-01-02 20:46:12 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2009-01-29 23:19:57 +00:00
|
|
|
|
2009-01-02 20:46:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2009-01-29 23:19:57 +00:00
|
|
|
regress_ipv6_parse(void *ptr)
|
2009-01-02 20:46:12 +00:00
|
|
|
{
|
|
|
|
#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) {
|
2009-01-29 23:19:57 +00:00
|
|
|
if (ent->status != BAD)
|
|
|
|
TT_FAIL(("%s did not parse, but it's a good address!",
|
|
|
|
ent->addr));
|
2009-01-02 20:46:12 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (ent->status == BAD) {
|
2009-01-29 23:19:57 +00:00
|
|
|
TT_FAIL(("%s parsed, but we expected an error", ent->addr));
|
2009-01-02 20:46:12 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
for (j = 0; j < 4; ++j) {
|
|
|
|
/* Can't use s6_addr32 here; some don't have it. */
|
|
|
|
ev_uint32_t u =
|
2014-03-18 11:35:50 -04:00
|
|
|
((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]);
|
2009-01-02 20:46:12 +00:00
|
|
|
if (u != ent->res[j]) {
|
2009-01-29 23:19:57 +00:00
|
|
|
TT_FAIL(("%s did not parse as expected.", ent->addr));
|
2009-01-02 20:46:12 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (ent->status == CANONICAL) {
|
|
|
|
const char *w = evutil_inet_ntop(AF_INET6, &in6, written,
|
|
|
|
sizeof(written));
|
|
|
|
if (!w) {
|
2009-01-29 23:19:57 +00:00
|
|
|
TT_FAIL(("Tried to write out %s; got NULL.", ent->addr));
|
2009-01-02 20:46:12 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (strcmp(written, ent->addr)) {
|
2009-01-29 23:19:57 +00:00
|
|
|
TT_FAIL(("Tried to write out %s; got %s", ent->addr, written));
|
2009-01-02 20:46:12 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
#else
|
2009-01-29 23:19:57 +00:00
|
|
|
TT_BLATHER(("Skipping IPv6 address parsing."));
|
2009-01-02 20:46:12 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2019-10-29 15:48:53 +01:00
|
|
|
static struct ipv6_entry_scope {
|
|
|
|
const char *addr;
|
|
|
|
ev_uint32_t res[4];
|
|
|
|
unsigned scope;
|
|
|
|
enum entry_status status;
|
|
|
|
} ipv6_entries_scope[] = {
|
|
|
|
{ "2001:DB8::", { 0x20010db8, 0, 0 }, 0, NORMAL },
|
|
|
|
{ "2001:DB8::%0", { 0x20010db8, 0, 0, 0 }, 0, NORMAL },
|
|
|
|
{ "2001:DB8::%1", { 0x20010db8, 0, 0, 0 }, 1, NORMAL },
|
|
|
|
{ "foobar.", { 0, 0, 0, 0 }, 0, BAD },
|
|
|
|
{ "2001:DB8::%does-not-exist", { 0, 0, 0, 0 }, 0, BAD },
|
|
|
|
{ NULL, { 0, 0, 0, 0, }, 0, BAD },
|
|
|
|
};
|
|
|
|
static void
|
|
|
|
regress_ipv6_parse_scope(void *ptr)
|
|
|
|
{
|
|
|
|
#ifdef AF_INET6
|
|
|
|
int i, j;
|
|
|
|
unsigned if_scope;
|
|
|
|
|
|
|
|
for (i = 0; ipv6_entries_scope[i].addr; ++i) {
|
|
|
|
struct ipv6_entry_scope *ent = &ipv6_entries_scope[i];
|
|
|
|
struct in6_addr in6;
|
|
|
|
int r;
|
|
|
|
r = evutil_inet_pton_scope(AF_INET6, ent->addr, &in6,
|
|
|
|
&if_scope);
|
|
|
|
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 (if_scope != ent->scope) {
|
|
|
|
TT_FAIL(("%s did not parse as expected.", ent->addr));
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
TT_BLATHER(("Skipping IPv6 address parsing."));
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-01-02 20:46:26 +00:00
|
|
|
static struct sa_port_ent {
|
|
|
|
const char *parse;
|
2010-11-22 16:40:31 -07:00
|
|
|
int safamily;
|
2009-01-02 20:46:26 +00:00
|
|
|
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 },
|
2009-07-30 17:00:46 +00:00
|
|
|
{ "[ffff::1]:65599", 0, NULL, 0 },
|
|
|
|
{ "[ffff::1]:0", 0, NULL, 0 },
|
|
|
|
{ "[ffff::1]:-1", 0, NULL, 0 },
|
2009-01-02 20:46:26 +00:00
|
|
|
{ "::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
|
2009-01-29 23:19:57 +00:00
|
|
|
regress_sockaddr_port_parse(void *ptr)
|
2009-01-02 20:46:26 +00:00
|
|
|
{
|
|
|
|
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];
|
2010-02-18 17:41:15 -05:00
|
|
|
int len = sizeof(ss);
|
2009-01-02 20:46:26 +00:00
|
|
|
memset(&ss, 0, sizeof(ss));
|
2009-02-11 17:23:32 +00:00
|
|
|
r = evutil_parse_sockaddr_port(ent->parse, (struct sockaddr*)&ss, &len);
|
2009-01-02 20:46:26 +00:00
|
|
|
if (r < 0) {
|
2010-11-22 16:40:31 -07:00
|
|
|
if (ent->safamily)
|
2009-01-29 23:19:57 +00:00
|
|
|
TT_FAIL(("Couldn't parse %s!", ent->parse));
|
2009-01-02 20:46:26 +00:00
|
|
|
continue;
|
2010-11-22 16:40:31 -07:00
|
|
|
} else if (! ent->safamily) {
|
2009-01-29 23:19:57 +00:00
|
|
|
TT_FAIL(("Shouldn't have been able to parse %s!", ent->parse));
|
2009-01-02 20:46:26 +00:00
|
|
|
continue;
|
|
|
|
}
|
2010-11-22 16:40:31 -07:00
|
|
|
if (ent->safamily == AF_INET) {
|
2009-01-02 20:46:26 +00:00
|
|
|
struct sockaddr_in sin;
|
|
|
|
memset(&sin, 0, sizeof(sin));
|
2012-02-29 15:07:31 -05:00
|
|
|
#ifdef EVENT__HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
|
2009-01-02 20:46:26 +00:00
|
|
|
sin.sin_len = sizeof(sin);
|
2009-01-02 21:21:58 +00:00
|
|
|
#endif
|
2009-01-02 20:46:26 +00:00
|
|
|
sin.sin_family = AF_INET;
|
|
|
|
sin.sin_port = htons(ent->port);
|
|
|
|
r = evutil_inet_pton(AF_INET, ent->addr, &sin.sin_addr);
|
2010-02-18 17:41:15 -05:00
|
|
|
if (1 != r) {
|
2009-01-29 23:19:57 +00:00
|
|
|
TT_FAIL(("Couldn't parse ipv4 target %s.", ent->addr));
|
2009-01-02 20:46:26 +00:00
|
|
|
} else if (memcmp(&sin, &ss, sizeof(sin))) {
|
2009-01-29 23:19:57 +00:00
|
|
|
TT_FAIL(("Parse for %s was not as expected.", ent->parse));
|
2009-02-11 17:23:32 +00:00
|
|
|
} else if (len != sizeof(sin)) {
|
2010-02-18 17:41:15 -05:00
|
|
|
TT_FAIL(("Length for %s not as expected.",ent->parse));
|
|
|
|
}
|
2009-01-02 20:46:26 +00:00
|
|
|
} else {
|
|
|
|
struct sockaddr_in6 sin6;
|
|
|
|
memset(&sin6, 0, sizeof(sin6));
|
2012-02-29 15:07:31 -05:00
|
|
|
#ifdef EVENT__HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
|
2009-01-02 20:46:26 +00:00
|
|
|
sin6.sin6_len = sizeof(sin6);
|
2009-01-02 21:21:58 +00:00
|
|
|
#endif
|
2009-01-02 20:46:26 +00:00
|
|
|
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) {
|
2009-01-29 23:19:57 +00:00
|
|
|
TT_FAIL(("Couldn't parse ipv6 target %s.", ent->addr));
|
2009-01-02 20:46:26 +00:00
|
|
|
} else if (memcmp(&sin6, &ss, sizeof(sin6))) {
|
2009-01-29 23:19:57 +00:00
|
|
|
TT_FAIL(("Parse for %s was not as expected.", ent->parse));
|
2009-02-11 17:23:32 +00:00
|
|
|
} else if (len != sizeof(sin6)) {
|
2010-02-18 17:41:15 -05:00
|
|
|
TT_FAIL(("Length for %s not as expected.",ent->parse));
|
2009-01-02 20:46:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-01-02 20:46:12 +00:00
|
|
|
|
2010-04-23 14:42:25 -04:00
|
|
|
|
|
|
|
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);
|
2012-02-29 15:07:33 -05:00
|
|
|
cp = evutil_format_sockaddr_port_(
|
2010-04-23 14:42:25 -04:00
|
|
|
(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);
|
2012-02-29 15:07:33 -05:00
|
|
|
cp = evutil_format_sockaddr_port_(
|
2010-04-23 14:42:25 -04:00
|
|
|
(struct sockaddr*)&ss, cbuf, sizeof(cbuf));
|
|
|
|
tt_ptr_op(cp,==,cbuf);
|
|
|
|
tt_str_op(cp,==,"[ff00::8010]:999");
|
|
|
|
|
|
|
|
ss.ss_family=99;
|
2012-02-29 15:07:33 -05:00
|
|
|
cp = evutil_format_sockaddr_port_(
|
2010-04-23 14:42:25 -04:00
|
|
|
(struct sockaddr*)&ss, cbuf, sizeof(cbuf));
|
|
|
|
tt_ptr_op(cp,==,cbuf);
|
|
|
|
tt_str_op(cp,==,"<addr with socktype 99>");
|
|
|
|
end:
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
2010-01-20 12:56:54 -05:00
|
|
|
static struct sa_pred_ent {
|
|
|
|
const char *parse;
|
|
|
|
|
|
|
|
int is_loopback;
|
|
|
|
} sa_pred_entries[] = {
|
2010-02-18 17:41:15 -05:00
|
|
|
{ "127.0.0.1", 1 },
|
|
|
|
{ "127.0.3.2", 1 },
|
|
|
|
{ "128.1.2.3", 0 },
|
|
|
|
{ "18.0.0.1", 0 },
|
2010-01-20 12:56:54 -05:00
|
|
|
{ "129.168.1.1", 0 },
|
|
|
|
|
2010-02-18 17:41:15 -05:00
|
|
|
{ "::1", 1 },
|
|
|
|
{ "::0", 0 },
|
|
|
|
{ "f::1", 0 },
|
|
|
|
{ "::501", 0 },
|
|
|
|
{ NULL, 0 },
|
2010-01-20 12:56:54 -05:00
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
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];
|
2010-02-18 17:41:15 -05:00
|
|
|
int len = sizeof(ss);
|
2010-01-20 12:56:54 -05:00
|
|
|
|
|
|
|
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 */
|
2012-02-29 15:07:33 -05:00
|
|
|
if (ent->is_loopback != evutil_sockaddr_is_loopback_((struct sockaddr*)&ss)) {
|
2010-01-20 12:56:54 -05:00
|
|
|
TT_FAIL(("evutil_sockaddr_loopback(%s) not as expected",
|
|
|
|
ent->parse));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-01-30 17:43:59 +00:00
|
|
|
static void
|
|
|
|
test_evutil_strtoll(void *ptr)
|
|
|
|
{
|
2010-02-18 17:41:15 -05:00
|
|
|
const char *s;
|
|
|
|
char *endptr;
|
2009-01-30 17:43:59 +00:00
|
|
|
|
2010-02-18 17:41:15 -05:00
|
|
|
tt_want(evutil_strtoll("5000000000", NULL, 10) ==
|
2009-01-30 17:43:59 +00:00
|
|
|
((ev_int64_t)5000000)*1000);
|
2010-02-18 17:41:15 -05:00
|
|
|
tt_want(evutil_strtoll("-5000000000", NULL, 10) ==
|
2009-01-30 17:43:59 +00:00
|
|
|
((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;
|
2011-06-08 17:18:03 -04:00
|
|
|
ev_uint64_t u64 = ((ev_uint64_t)1000000000)*200;
|
2011-07-05 14:55:09 -04:00
|
|
|
ev_int64_t i64 = -1 * (ev_int64_t) u64;
|
2011-06-08 17:18:03 -04:00
|
|
|
size_t size = 8000;
|
|
|
|
ev_ssize_t ssize = -9000;
|
|
|
|
|
2009-01-30 17:43:59 +00:00
|
|
|
r = evutil_snprintf(buf, sizeof(buf), "%d %d", 50, 100);
|
2010-02-18 17:41:15 -05:00
|
|
|
tt_str_op(buf, ==, "50 100");
|
|
|
|
tt_int_op(r, ==, 6);
|
2009-01-30 17:43:59 +00:00
|
|
|
|
|
|
|
r = evutil_snprintf(buf, sizeof(buf), "longish %d", 1234567890);
|
2010-02-18 17:41:15 -05:00
|
|
|
tt_str_op(buf, ==, "longish 1234567");
|
|
|
|
tt_int_op(r, ==, 18);
|
2009-01-30 17:43:59 +00:00
|
|
|
|
2011-06-08 17:18:03 -04:00
|
|
|
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);
|
|
|
|
|
2009-01-30 17:43:59 +00:00
|
|
|
end:
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
2009-07-20 14:55:07 +00:00
|
|
|
static void
|
|
|
|
test_evutil_casecmp(void *ptr)
|
|
|
|
{
|
2009-07-28 19:41:57 +00:00
|
|
|
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);
|
2009-07-20 14:55:07 +00:00
|
|
|
|
2009-07-28 19:41:57 +00:00
|
|
|
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);
|
2009-07-20 14:55:07 +00:00
|
|
|
end:
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
2012-11-16 11:13:29 -05:00
|
|
|
static void
|
|
|
|
test_evutil_rtrim(void *ptr)
|
|
|
|
{
|
|
|
|
#define TEST_TRIM(s, result) \
|
|
|
|
do { \
|
|
|
|
if (cp) mm_free(cp); \
|
2012-11-18 01:40:33 -05:00
|
|
|
cp = mm_strdup(s); \
|
2013-08-06 19:42:20 -04:00
|
|
|
tt_assert(cp); \
|
2012-11-16 11:29:34 -05:00
|
|
|
evutil_rtrim_lws_(cp); \
|
2012-11-18 01:40:33 -05:00
|
|
|
tt_str_op(cp, ==, result); \
|
2012-11-16 11:13:29 -05:00
|
|
|
} 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");
|
|
|
|
|
2012-11-16 11:29:34 -05:00
|
|
|
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");
|
|
|
|
|
2012-11-16 11:13:29 -05:00
|
|
|
end:
|
|
|
|
if (cp)
|
|
|
|
mm_free(cp);
|
|
|
|
}
|
|
|
|
|
2009-10-26 19:59:51 +00:00
|
|
|
static int logsev = 0;
|
|
|
|
static char *logmsg = NULL;
|
|
|
|
|
|
|
|
static void
|
|
|
|
logfn(int severity, const char *msg)
|
|
|
|
{
|
|
|
|
logsev = severity;
|
|
|
|
tt_want(msg);
|
2010-09-07 10:28:15 -04:00
|
|
|
if (msg) {
|
|
|
|
if (logmsg)
|
|
|
|
free(logmsg);
|
2009-10-26 19:59:51 +00:00
|
|
|
logmsg = strdup(msg);
|
2010-09-07 10:28:15 -04:00
|
|
|
}
|
2009-10-26 19:59:51 +00:00
|
|
|
}
|
|
|
|
|
2010-05-13 10:57:30 -04:00
|
|
|
static int fatal_want_severity = 0;
|
|
|
|
static const char *fatal_want_message = NULL;
|
2009-10-26 19:59:51 +00:00
|
|
|
static void
|
2010-05-13 10:57:30 -04:00
|
|
|
fatalfn(int exitcode)
|
2009-10-26 19:59:51 +00:00
|
|
|
{
|
2010-05-13 10:57:30 -04:00
|
|
|
if (logsev != fatal_want_severity ||
|
|
|
|
!logmsg ||
|
|
|
|
strcmp(logmsg, fatal_want_message))
|
|
|
|
exit(0);
|
|
|
|
else
|
|
|
|
exit(exitcode);
|
2009-10-26 19:59:51 +00:00
|
|
|
}
|
|
|
|
|
2011-05-25 19:50:56 -04:00
|
|
|
#ifndef _WIN32
|
2010-05-13 10:57:30 -04:00
|
|
|
#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;
|
2012-04-11 21:33:27 -04:00
|
|
|
if ((pid = regress_fork()) == 0) {
|
2010-05-13 10:57:30 -04:00
|
|
|
/* 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);
|
2011-05-25 19:50:56 -04:00
|
|
|
#ifdef _WIN32
|
2010-05-13 10:57:30 -04:00
|
|
|
EVUTIL_SET_SOCKET_ERROR(WSAEWOULDBLOCK);
|
|
|
|
#else
|
|
|
|
errno = EAGAIN;
|
|
|
|
#endif
|
|
|
|
event_sock_err(20, fd, "Unhappy socket");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-10-26 19:59:51 +00:00
|
|
|
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 { \
|
2010-05-13 10:57:30 -04:00
|
|
|
logsev = 0; \
|
2009-10-26 19:59:51 +00:00
|
|
|
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)
|
|
|
|
|
2010-05-13 10:57:30 -04:00
|
|
|
#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. */
|
2012-02-29 15:07:32 -05:00
|
|
|
check_error_logging(errx_fn, 2, EVENT_LOG_ERR,
|
2010-05-13 10:57:30 -04:00
|
|
|
"Fatal error; too many kumquats (5)");
|
2009-10-26 19:59:51 +00:00
|
|
|
RESET();
|
2010-05-13 10:57:30 -04:00
|
|
|
#endif
|
2009-10-26 19:59:51 +00:00
|
|
|
|
|
|
|
event_warnx("Far too many %s (%d)", "wombats", 99);
|
2012-02-29 15:07:32 -05:00
|
|
|
LOGEQ(EVENT_LOG_WARN, "Far too many wombats (99)");
|
2009-10-26 19:59:51 +00:00
|
|
|
RESET();
|
|
|
|
|
|
|
|
event_msgx("Connecting lime to coconut");
|
2012-02-29 15:07:32 -05:00
|
|
|
LOGEQ(EVENT_LOG_MSG, "Connecting lime to coconut");
|
2009-10-26 19:59:51 +00:00
|
|
|
RESET();
|
|
|
|
|
2010-08-06 16:36:23 -04:00
|
|
|
event_debug(("A millisecond passed! We should log that!"));
|
2009-10-26 19:59:51 +00:00
|
|
|
#ifdef USE_DEBUG
|
2012-02-29 15:07:32 -05:00
|
|
|
LOGEQ(EVENT_LOG_DEBUG, "A millisecond passed! We should log that!");
|
2009-10-26 19:59:51 +00:00
|
|
|
#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));
|
2012-02-29 15:07:32 -05:00
|
|
|
LOGEQ(EVENT_LOG_WARN,buf);
|
2009-10-26 19:59:51 +00:00
|
|
|
RESET();
|
|
|
|
|
2010-05-13 10:57:30 -04:00
|
|
|
#ifdef CAN_CHECK_ERR
|
2009-10-26 19:59:51 +00:00
|
|
|
evutil_snprintf(buf, sizeof(buf),
|
|
|
|
"Couldn't open /very/bad/file: %s",strerror(ENOENT));
|
2012-02-29 15:07:32 -05:00
|
|
|
check_error_logging(err_fn, 5, EVENT_LOG_ERR, buf);
|
2009-10-26 19:59:51 +00:00
|
|
|
RESET();
|
2010-05-13 10:57:30 -04:00
|
|
|
#endif
|
2009-10-26 19:59:51 +00:00
|
|
|
|
|
|
|
/* Try with a socket errno. */
|
|
|
|
fd = socket(AF_INET, SOCK_STREAM, 0);
|
2011-05-25 19:50:56 -04:00
|
|
|
#ifdef _WIN32
|
2009-10-26 19:59:51 +00:00
|
|
|
evutil_snprintf(buf, sizeof(buf),
|
2009-10-27 18:25:19 +00:00
|
|
|
"Unhappy socket: %s",
|
|
|
|
evutil_socket_error_to_string(WSAEWOULDBLOCK));
|
|
|
|
EVUTIL_SET_SOCKET_ERROR(WSAEWOULDBLOCK);
|
2009-10-26 19:59:51 +00:00
|
|
|
#else
|
|
|
|
evutil_snprintf(buf, sizeof(buf),
|
|
|
|
"Unhappy socket: %s", strerror(EAGAIN));
|
|
|
|
errno = EAGAIN;
|
|
|
|
#endif
|
|
|
|
event_sock_warn(fd, "Unhappy socket");
|
2012-02-29 15:07:32 -05:00
|
|
|
LOGEQ(EVENT_LOG_WARN, buf);
|
2009-10-26 19:59:51 +00:00
|
|
|
RESET();
|
|
|
|
|
2010-05-13 10:57:30 -04:00
|
|
|
#ifdef CAN_CHECK_ERR
|
2012-02-29 15:07:32 -05:00
|
|
|
check_error_logging(sock_err_fn, 20, EVENT_LOG_ERR, buf);
|
2009-10-26 19:59:51 +00:00
|
|
|
RESET();
|
2010-05-13 10:57:30 -04:00
|
|
|
#endif
|
2009-10-26 19:59:51 +00:00
|
|
|
|
|
|
|
#undef RESET
|
|
|
|
#undef LOGEQ
|
|
|
|
end:
|
|
|
|
if (logmsg)
|
|
|
|
free(logmsg);
|
|
|
|
if (fd >= 0)
|
2010-04-14 15:42:57 -04:00
|
|
|
evutil_closesocket(fd);
|
2009-10-26 19:59:51 +00:00
|
|
|
}
|
|
|
|
|
2009-10-29 16:35:09 +00:00
|
|
|
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:
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
2009-11-02 19:30:25 +00:00
|
|
|
struct example_struct {
|
2010-10-27 17:31:52 -04:00
|
|
|
const char *a;
|
2009-11-02 19:30:25 +00:00
|
|
|
const char *b;
|
|
|
|
long c;
|
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_evutil_upcast(void *arg)
|
|
|
|
{
|
|
|
|
struct example_struct es1;
|
|
|
|
const char **cp;
|
2010-10-27 17:31:52 -04:00
|
|
|
es1.a = "World";
|
2009-11-02 19:30:25 +00:00
|
|
|
es1.b = "Hello";
|
|
|
|
es1.c = -99;
|
|
|
|
|
2010-10-27 17:31:52 -04:00
|
|
|
tt_int_op(evutil_offsetof(struct example_struct, b), ==, sizeof(char*));
|
2009-11-02 19:30:25 +00:00
|
|
|
|
|
|
|
cp = &es1.b;
|
|
|
|
tt_ptr_op(EVUTIL_UPCAST(cp, struct example_struct, b), ==, &es1);
|
|
|
|
|
|
|
|
end:
|
|
|
|
;
|
2010-02-03 17:01:45 -05:00
|
|
|
}
|
2009-11-02 19:30:25 +00:00
|
|
|
|
2010-02-03 17:01:45 -05:00
|
|
|
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++;
|
2014-03-18 12:35:39 -04:00
|
|
|
/* i64++; */
|
2010-02-03 17:01:45 -05:00
|
|
|
tt_assert(u64 == 0);
|
2014-03-18 12:35:39 -04:00
|
|
|
/* tt_assert(i64 == EV_INT64_MIN); */
|
|
|
|
/* tt_assert(i64 < 0); */
|
2010-02-03 17:01:45 -05:00
|
|
|
|
|
|
|
u32 = EV_UINT32_MAX;
|
|
|
|
i32 = EV_INT32_MAX;
|
|
|
|
tt_assert(u32 > 0);
|
|
|
|
tt_assert(i32 > 0);
|
|
|
|
u32++;
|
2014-03-18 12:35:39 -04:00
|
|
|
/* i32++; */
|
2010-02-03 17:01:45 -05:00
|
|
|
tt_assert(u32 == 0);
|
2014-03-18 12:35:39 -04:00
|
|
|
/* tt_assert(i32 == EV_INT32_MIN); */
|
|
|
|
/* tt_assert(i32 < 0); */
|
2010-02-03 17:01:45 -05:00
|
|
|
|
|
|
|
u16 = EV_UINT16_MAX;
|
|
|
|
i16 = EV_INT16_MAX;
|
|
|
|
tt_assert(u16 > 0);
|
|
|
|
tt_assert(i16 > 0);
|
|
|
|
u16++;
|
2014-03-18 12:35:39 -04:00
|
|
|
/* i16++; */
|
2010-02-03 17:01:45 -05:00
|
|
|
tt_assert(u16 == 0);
|
2014-03-18 12:35:39 -04:00
|
|
|
/* tt_assert(i16 == EV_INT16_MIN); */
|
|
|
|
/* tt_assert(i16 < 0); */
|
2010-02-03 17:01:45 -05:00
|
|
|
|
|
|
|
u8 = EV_UINT8_MAX;
|
|
|
|
i8 = EV_INT8_MAX;
|
|
|
|
tt_assert(u8 > 0);
|
|
|
|
tt_assert(i8 > 0);
|
|
|
|
u8++;
|
2014-03-18 12:35:39 -04:00
|
|
|
/* i8++;*/
|
2010-02-03 17:01:45 -05:00
|
|
|
tt_assert(u8 == 0);
|
2014-03-18 12:35:39 -04:00
|
|
|
/* tt_assert(i8 == EV_INT8_MIN); */
|
|
|
|
/* tt_assert(i8 < 0); */
|
2010-02-03 17:01:45 -05:00
|
|
|
|
2014-03-18 12:35:39 -04:00
|
|
|
/*
|
2010-02-03 17:01:45 -05:00
|
|
|
ssize = EV_SSIZE_MAX;
|
|
|
|
tt_assert(ssize > 0);
|
|
|
|
ssize++;
|
|
|
|
tt_assert(ssize < 0);
|
|
|
|
tt_assert(ssize == EV_SSIZE_MIN);
|
2014-03-18 12:35:39 -04:00
|
|
|
*/
|
2010-02-03 17:01:45 -05:00
|
|
|
|
|
|
|
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:
|
|
|
|
;
|
2009-11-02 19:30:25 +00:00
|
|
|
}
|
2009-10-29 16:35:09 +00:00
|
|
|
|
2009-11-16 22:25:46 +00:00
|
|
|
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
|
2012-02-29 15:07:32 -05:00
|
|
|
test_ai_eq_(const struct evutil_addrinfo *ai, const char *sockaddr_port,
|
2009-11-16 22:25:46 +00:00
|
|
|
int socktype, int protocol, int line)
|
2009-11-03 20:40:48 +00:00
|
|
|
{
|
|
|
|
struct sockaddr_storage ss;
|
2010-02-18 17:41:15 -05:00
|
|
|
int slen = sizeof(ss);
|
2009-11-16 22:25:46 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2010-02-18 01:43:37 -05:00
|
|
|
static void
|
|
|
|
test_evutil_rand(void *arg)
|
|
|
|
{
|
|
|
|
char buf1[32];
|
|
|
|
char buf2[32];
|
|
|
|
int counts[256];
|
2022-07-12 09:54:14 +03:00
|
|
|
int i, j, k;
|
2012-04-09 11:30:46 -04:00
|
|
|
struct evutil_weakrand_state seed = { 12346789U };
|
2010-02-18 01:43:37 -05:00
|
|
|
|
|
|
|
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 */
|
2012-04-09 10:46:32 -04:00
|
|
|
int startpoint = evutil_weakrand_(&seed) % 4;
|
|
|
|
int endpoint = 32 - (evutil_weakrand_(&seed) % 4);
|
2010-02-18 01:43:37 -05:00
|
|
|
|
|
|
|
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);
|
|
|
|
for (j=0; j<32; ++j) {
|
|
|
|
if (j >= startpoint && j < endpoint) {
|
|
|
|
buf2[j] |= buf1[j];
|
|
|
|
++counts[(unsigned char)buf1[j]];
|
|
|
|
} else {
|
2010-08-23 11:48:46 -04:00
|
|
|
tt_assert(buf1[j] == 0);
|
2010-02-18 01:43:37 -05:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-09 11:30:46 -04:00
|
|
|
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);
|
|
|
|
}
|
2010-02-18 01:43:37 -05:00
|
|
|
end:
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
2020-06-25 08:45:34 +03:00
|
|
|
static void
|
|
|
|
test_EVUTIL_IS_(void *arg)
|
|
|
|
{
|
|
|
|
tt_int_op(EVUTIL_ISDIGIT_('0'), ==, 1);
|
|
|
|
tt_int_op(EVUTIL_ISDIGIT_('a'), ==, 0);
|
|
|
|
tt_int_op(EVUTIL_ISDIGIT_('\xff'), ==, 0);
|
|
|
|
end:
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
2009-11-16 22:25:46 +00:00
|
|
|
static void
|
|
|
|
test_evutil_getaddrinfo(void *arg)
|
|
|
|
{
|
|
|
|
struct evutil_addrinfo *ai = NULL, *a;
|
|
|
|
struct evutil_addrinfo hints;
|
2009-11-03 20:40:48 +00:00
|
|
|
int r;
|
|
|
|
|
2021-11-01 10:01:06 -07:00
|
|
|
/* Try NULL hint (win32 bug) */
|
|
|
|
hints.ai_family = PF_UNSPEC;
|
|
|
|
hints.ai_socktype = SOCK_STREAM;
|
|
|
|
r = evutil_getaddrinfo("www.google.com", NULL, NULL, &ai);
|
|
|
|
tt_int_op(r, ==, 0);
|
|
|
|
tt_assert(ai);
|
|
|
|
evutil_freeaddrinfo(ai);
|
|
|
|
ai = NULL;
|
|
|
|
|
2009-11-16 22:25:46 +00:00
|
|
|
/* 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);
|
2022-08-13 20:48:00 +02:00
|
|
|
if (r != EVUTIL_EAI_SERVICE && r != EVUTIL_EAI_NONAME)
|
|
|
|
tt_fail_msg("error is neither EAI_SERVICE nor EAI_NONAME\n");
|
2012-11-01 17:38:34 -04:00
|
|
|
tt_ptr_op(ai, ==, NULL);
|
2009-11-16 22:25:46 +00:00
|
|
|
|
|
|
|
/* 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) {
|
2010-08-05 15:51:16 -04:00
|
|
|
TT_DECLARE("SKIP", ("Symbolic service names seem broken."));
|
2009-11-16 22:25:46 +00:00
|
|
|
} else {
|
|
|
|
tt_assert(ai);
|
|
|
|
test_ai_eq(ai, "1.2.3.4:80", SOCK_STREAM, IPPROTO_TCP);
|
|
|
|
evutil_freeaddrinfo(ai);
|
|
|
|
ai = NULL;
|
2009-11-03 20:40:48 +00:00
|
|
|
}
|
2009-11-16 22:25:46 +00:00
|
|
|
|
2012-06-28 13:18:28 -04:00
|
|
|
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;
|
|
|
|
|
2009-11-16 22:25:46 +00:00
|
|
|
/* 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) {
|
2010-08-05 15:51:16 -04:00
|
|
|
TT_DECLARE("SKIP", ("Couldn't resolve www.google.com"));
|
2009-11-16 22:25:46 +00:00
|
|
|
} 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;
|
2009-11-03 20:40:48 +00:00
|
|
|
}
|
|
|
|
|
2009-11-16 22:25:46 +00:00
|
|
|
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>"));
|
|
|
|
}
|
2009-11-03 20:40:48 +00:00
|
|
|
|
|
|
|
end:
|
2009-11-16 22:25:46 +00:00
|
|
|
if (ai)
|
|
|
|
evutil_freeaddrinfo(ai);
|
2009-11-03 20:40:48 +00:00
|
|
|
}
|
|
|
|
|
2020-06-26 10:35:44 +03:00
|
|
|
static void
|
|
|
|
test_evutil_getaddrinfo_AI_ADDRCONFIG(void *arg)
|
|
|
|
{
|
|
|
|
struct evutil_addrinfo *ai = NULL;
|
|
|
|
struct evutil_addrinfo hints;
|
|
|
|
int r;
|
|
|
|
|
|
|
|
memset(&hints, 0, sizeof(hints));
|
|
|
|
hints.ai_family = AF_UNSPEC;
|
|
|
|
hints.ai_socktype = SOCK_STREAM;
|
|
|
|
hints.ai_flags = EVUTIL_AI_PASSIVE|EVUTIL_AI_ADDRCONFIG;
|
|
|
|
|
|
|
|
/* IPv4 */
|
|
|
|
r = evutil_getaddrinfo("127.0.0.1", "80", &hints, &ai);
|
|
|
|
tt_int_op(r, ==, 0);
|
|
|
|
tt_assert(ai);
|
|
|
|
tt_ptr_op(ai->ai_next, ==, NULL);
|
|
|
|
test_ai_eq(ai, "127.0.0.1:80", SOCK_STREAM, IPPROTO_TCP);
|
|
|
|
evutil_freeaddrinfo(ai);
|
|
|
|
ai = NULL;
|
|
|
|
|
|
|
|
/* IPv6 */
|
|
|
|
r = evutil_getaddrinfo("::1", "80", &hints, &ai);
|
|
|
|
tt_int_op(r, ==, 0);
|
|
|
|
tt_assert(ai);
|
|
|
|
tt_ptr_op(ai->ai_next, ==, NULL);
|
|
|
|
test_ai_eq(ai, "[::1]:80", SOCK_STREAM, IPPROTO_TCP);
|
|
|
|
evutil_freeaddrinfo(ai);
|
|
|
|
ai = NULL;
|
|
|
|
|
|
|
|
end:
|
|
|
|
if (ai)
|
|
|
|
evutil_freeaddrinfo(ai);
|
|
|
|
}
|
|
|
|
|
2011-05-25 19:50:56 -04:00
|
|
|
#ifdef _WIN32
|
2010-09-27 15:12:55 -04:00
|
|
|
static void
|
|
|
|
test_evutil_loadsyslib(void *arg)
|
|
|
|
{
|
2014-08-29 14:28:09 -04:00
|
|
|
HMODULE h=NULL;
|
2010-09-27 15:12:55 -04:00
|
|
|
|
2012-02-29 15:07:33 -05:00
|
|
|
h = evutil_load_windows_system_library_(TEXT("kernel32.dll"));
|
2010-09-27 15:12:55 -04:00
|
|
|
tt_assert(h);
|
|
|
|
|
|
|
|
end:
|
|
|
|
if (h)
|
|
|
|
CloseHandle(h);
|
|
|
|
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
Add argument checks to some memory functions in `event.c'.
Add a zero check to the function `event_mm_malloc_',
i.e. simply return NULL if the sz argument is zero.
On failure, set errno to ENOMEM and return NULL.
Add a zero check to the function `event_mm_calloc_',
i.e. simply return NULL if either argument is zero.
Also add an unsigned integer multiplication check, and if an integer
overflow would occur, set errno to ENOMEM and return NULL.
On failure, set errno to ENOMEM and return NULL.
Add a NULL check to the function `event_mm_strdup_',
i.e. set errno to EINVAL and return NULL.
Also add an unsigned integer addition check, and if an integer
overflow would occur, set errno to ENOMEM and return NULL.
If a memory allocation error occurs, again set errno to ENOMEM
and return NULL.
Add unit tests to `test/regress_util.c'.
2011-10-14 17:16:03 -04:00
|
|
|
/** Test mm_malloc(). */
|
|
|
|
static void
|
|
|
|
test_event_malloc(void *arg)
|
|
|
|
{
|
|
|
|
void *p = NULL;
|
|
|
|
(void)arg;
|
|
|
|
|
|
|
|
/* mm_malloc(0) should simply return NULL. */
|
2012-04-03 14:54:39 -04:00
|
|
|
#ifndef EVENT__DISABLE_MM_REPLACEMENT
|
Add argument checks to some memory functions in `event.c'.
Add a zero check to the function `event_mm_malloc_',
i.e. simply return NULL if the sz argument is zero.
On failure, set errno to ENOMEM and return NULL.
Add a zero check to the function `event_mm_calloc_',
i.e. simply return NULL if either argument is zero.
Also add an unsigned integer multiplication check, and if an integer
overflow would occur, set errno to ENOMEM and return NULL.
On failure, set errno to ENOMEM and return NULL.
Add a NULL check to the function `event_mm_strdup_',
i.e. set errno to EINVAL and return NULL.
Also add an unsigned integer addition check, and if an integer
overflow would occur, set errno to ENOMEM and return NULL.
If a memory allocation error occurs, again set errno to ENOMEM
and return NULL.
Add unit tests to `test/regress_util.c'.
2011-10-14 17:16:03 -04:00
|
|
|
errno = 0;
|
|
|
|
p = mm_malloc(0);
|
|
|
|
tt_assert(p == NULL);
|
|
|
|
tt_int_op(errno, ==, 0);
|
2012-04-03 14:54:39 -04:00
|
|
|
#endif
|
Add argument checks to some memory functions in `event.c'.
Add a zero check to the function `event_mm_malloc_',
i.e. simply return NULL if the sz argument is zero.
On failure, set errno to ENOMEM and return NULL.
Add a zero check to the function `event_mm_calloc_',
i.e. simply return NULL if either argument is zero.
Also add an unsigned integer multiplication check, and if an integer
overflow would occur, set errno to ENOMEM and return NULL.
On failure, set errno to ENOMEM and return NULL.
Add a NULL check to the function `event_mm_strdup_',
i.e. set errno to EINVAL and return NULL.
Also add an unsigned integer addition check, and if an integer
overflow would occur, set errno to ENOMEM and return NULL.
If a memory allocation error occurs, again set errno to ENOMEM
and return NULL.
Add unit tests to `test/regress_util.c'.
2011-10-14 17:16:03 -04:00
|
|
|
|
|
|
|
/* 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;
|
|
|
|
|
2012-04-03 14:54:39 -04:00
|
|
|
#ifndef EVENT__DISABLE_MM_REPLACEMENT
|
Add argument checks to some memory functions in `event.c'.
Add a zero check to the function `event_mm_malloc_',
i.e. simply return NULL if the sz argument is zero.
On failure, set errno to ENOMEM and return NULL.
Add a zero check to the function `event_mm_calloc_',
i.e. simply return NULL if either argument is zero.
Also add an unsigned integer multiplication check, and if an integer
overflow would occur, set errno to ENOMEM and return NULL.
On failure, set errno to ENOMEM and return NULL.
Add a NULL check to the function `event_mm_strdup_',
i.e. set errno to EINVAL and return NULL.
Also add an unsigned integer addition check, and if an integer
overflow would occur, set errno to ENOMEM and return NULL.
If a memory allocation error occurs, again set errno to ENOMEM
and return NULL.
Add unit tests to `test/regress_util.c'.
2011-10-14 17:16:03 -04:00
|
|
|
/* 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);
|
2012-04-03 14:54:39 -04:00
|
|
|
#endif
|
Add argument checks to some memory functions in `event.c'.
Add a zero check to the function `event_mm_malloc_',
i.e. simply return NULL if the sz argument is zero.
On failure, set errno to ENOMEM and return NULL.
Add a zero check to the function `event_mm_calloc_',
i.e. simply return NULL if either argument is zero.
Also add an unsigned integer multiplication check, and if an integer
overflow would occur, set errno to ENOMEM and return NULL.
On failure, set errno to ENOMEM and return NULL.
Add a NULL check to the function `event_mm_strdup_',
i.e. set errno to EINVAL and return NULL.
Also add an unsigned integer addition check, and if an integer
overflow would occur, set errno to ENOMEM and return NULL.
If a memory allocation error occurs, again set errno to ENOMEM
and return NULL.
Add unit tests to `test/regress_util.c'.
2011-10-14 17:16:03 -04:00
|
|
|
|
|
|
|
/* Trivial case. */
|
|
|
|
errno = 0;
|
|
|
|
p = mm_calloc(8, 8);
|
|
|
|
tt_assert(p != NULL);
|
|
|
|
tt_int_op(errno, ==, 0);
|
|
|
|
mm_free(p);
|
2012-07-26 10:11:00 -04:00
|
|
|
p = NULL;
|
Add argument checks to some memory functions in `event.c'.
Add a zero check to the function `event_mm_malloc_',
i.e. simply return NULL if the sz argument is zero.
On failure, set errno to ENOMEM and return NULL.
Add a zero check to the function `event_mm_calloc_',
i.e. simply return NULL if either argument is zero.
Also add an unsigned integer multiplication check, and if an integer
overflow would occur, set errno to ENOMEM and return NULL.
On failure, set errno to ENOMEM and return NULL.
Add a NULL check to the function `event_mm_strdup_',
i.e. set errno to EINVAL and return NULL.
Also add an unsigned integer addition check, and if an integer
overflow would occur, set errno to ENOMEM and return NULL.
If a memory allocation error occurs, again set errno to ENOMEM
and return NULL.
Add unit tests to `test/regress_util.c'.
2011-10-14 17:16:03 -04:00
|
|
|
|
|
|
|
/* mm_calloc() should set errno = ENOMEM and return NULL
|
|
|
|
* in case of potential overflow. */
|
|
|
|
errno = 0;
|
2022-07-09 17:14:12 +03:00
|
|
|
#if defined(__clang__)
|
|
|
|
#elif defined(__GNUC__)
|
|
|
|
#pragma GCC diagnostic push
|
|
|
|
#pragma GCC diagnostic ignored "-Walloc-size-larger-than="
|
|
|
|
#endif
|
|
|
|
p = mm_calloc(EV_SIZE_MAX, EV_SIZE_MAX);
|
|
|
|
#if defined(__clang__)
|
|
|
|
#elif defined(__GNUC__)
|
|
|
|
#pragma GCC diagnostic pop
|
|
|
|
#endif
|
Add argument checks to some memory functions in `event.c'.
Add a zero check to the function `event_mm_malloc_',
i.e. simply return NULL if the sz argument is zero.
On failure, set errno to ENOMEM and return NULL.
Add a zero check to the function `event_mm_calloc_',
i.e. simply return NULL if either argument is zero.
Also add an unsigned integer multiplication check, and if an integer
overflow would occur, set errno to ENOMEM and return NULL.
On failure, set errno to ENOMEM and return NULL.
Add a NULL check to the function `event_mm_strdup_',
i.e. set errno to EINVAL and return NULL.
Also add an unsigned integer addition check, and if an integer
overflow would occur, set errno to ENOMEM and return NULL.
If a memory allocation error occurs, again set errno to ENOMEM
and return NULL.
Add unit tests to `test/regress_util.c'.
2011-10-14 17:16:03 -04:00
|
|
|
tt_assert(p == NULL);
|
|
|
|
tt_int_op(errno, ==, ENOMEM);
|
|
|
|
|
|
|
|
end:
|
|
|
|
errno = 0;
|
2012-07-26 10:11:00 -04:00
|
|
|
if (p)
|
|
|
|
mm_free(p);
|
|
|
|
|
Add argument checks to some memory functions in `event.c'.
Add a zero check to the function `event_mm_malloc_',
i.e. simply return NULL if the sz argument is zero.
On failure, set errno to ENOMEM and return NULL.
Add a zero check to the function `event_mm_calloc_',
i.e. simply return NULL if either argument is zero.
Also add an unsigned integer multiplication check, and if an integer
overflow would occur, set errno to ENOMEM and return NULL.
On failure, set errno to ENOMEM and return NULL.
Add a NULL check to the function `event_mm_strdup_',
i.e. set errno to EINVAL and return NULL.
Also add an unsigned integer addition check, and if an integer
overflow would occur, set errno to ENOMEM and return NULL.
If a memory allocation error occurs, again set errno to ENOMEM
and return NULL.
Add unit tests to `test/regress_util.c'.
2011-10-14 17:16:03 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_event_strdup(void *arg)
|
|
|
|
{
|
|
|
|
void *p = NULL;
|
|
|
|
(void)arg;
|
|
|
|
|
2012-04-03 14:54:39 -04:00
|
|
|
#ifndef EVENT__DISABLE_MM_REPLACEMENT
|
Add argument checks to some memory functions in `event.c'.
Add a zero check to the function `event_mm_malloc_',
i.e. simply return NULL if the sz argument is zero.
On failure, set errno to ENOMEM and return NULL.
Add a zero check to the function `event_mm_calloc_',
i.e. simply return NULL if either argument is zero.
Also add an unsigned integer multiplication check, and if an integer
overflow would occur, set errno to ENOMEM and return NULL.
On failure, set errno to ENOMEM and return NULL.
Add a NULL check to the function `event_mm_strdup_',
i.e. set errno to EINVAL and return NULL.
Also add an unsigned integer addition check, and if an integer
overflow would occur, set errno to ENOMEM and return NULL.
If a memory allocation error occurs, again set errno to ENOMEM
and return NULL.
Add unit tests to `test/regress_util.c'.
2011-10-14 17:16:03 -04:00
|
|
|
/* 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);
|
2012-04-03 14:54:39 -04:00
|
|
|
#endif
|
Add argument checks to some memory functions in `event.c'.
Add a zero check to the function `event_mm_malloc_',
i.e. simply return NULL if the sz argument is zero.
On failure, set errno to ENOMEM and return NULL.
Add a zero check to the function `event_mm_calloc_',
i.e. simply return NULL if either argument is zero.
Also add an unsigned integer multiplication check, and if an integer
overflow would occur, set errno to ENOMEM and return NULL.
On failure, set errno to ENOMEM and return NULL.
Add a NULL check to the function `event_mm_strdup_',
i.e. set errno to EINVAL and return NULL.
Also add an unsigned integer addition check, and if an integer
overflow would occur, set errno to ENOMEM and return NULL.
If a memory allocation error occurs, again set errno to ENOMEM
and return NULL.
Add unit tests to `test/regress_util.c'.
2011-10-14 17:16:03 -04:00
|
|
|
|
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
|
2012-01-24 11:42:26 -05:00
|
|
|
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);
|
2012-02-29 15:07:33 -05:00
|
|
|
evutil_usleep_(&quarter_sec);
|
2012-01-24 11:42:26 -05:00
|
|
|
evutil_gettimeofday(&tv2, NULL);
|
2012-02-29 15:07:33 -05:00
|
|
|
evutil_usleep_(&tenth_sec);
|
2012-01-24 11:42:26 -05:00
|
|
|
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:
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
2012-04-26 11:56:59 -04:00
|
|
|
static void
|
2012-06-29 12:47:51 -04:00
|
|
|
test_evutil_monotonic_res(void *data_)
|
2012-04-26 11:56:59 -04:00
|
|
|
{
|
|
|
|
/* 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;
|
|
|
|
|
2012-06-29 12:47:51 -04:00
|
|
|
int flags = 0, wantres, acceptdiff, i;
|
2012-04-26 11:56:59 -04:00
|
|
|
if (precise)
|
|
|
|
flags |= EV_MONOT_PRECISE;
|
|
|
|
if (fallback)
|
|
|
|
flags |= EV_MONOT_FALLBACK;
|
|
|
|
if (precise || fallback) {
|
|
|
|
#ifdef _WIN32
|
|
|
|
wantres = 10*1000;
|
|
|
|
acceptdiff = 1000;
|
|
|
|
#else
|
2012-06-28 12:57:58 -04:00
|
|
|
wantres = 1000;
|
|
|
|
acceptdiff = 300;
|
2012-04-26 11:56:59 -04:00
|
|
|
#endif
|
|
|
|
} else {
|
|
|
|
wantres = 40*1000;
|
|
|
|
acceptdiff = 20*1000;
|
|
|
|
}
|
|
|
|
|
|
|
|
TT_BLATHER(("Precise = %d", precise));
|
|
|
|
TT_BLATHER(("Fallback = %d", fallback));
|
|
|
|
|
2012-04-26 14:35:18 -04:00
|
|
|
/* First, make sure we match up with usleep. */
|
|
|
|
|
2012-04-26 11:56:59 -04:00
|
|
|
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));
|
|
|
|
}
|
2012-04-26 14:35:18 -04:00
|
|
|
tt_int_op(abs(total_diff/9 - wantres), <, acceptdiff);
|
|
|
|
|
2012-06-29 12:47:51 -04:00
|
|
|
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. */
|
2012-04-26 14:35:18 -04:00
|
|
|
|
|
|
|
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);
|
2012-04-26 11:56:59 -04:00
|
|
|
|
|
|
|
end:
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
2016-12-16 14:49:59 +09:00
|
|
|
static void
|
2016-12-22 14:55:33 +03:00
|
|
|
create_tm_from_unix_epoch(struct tm *cur_p, const time_t t)
|
|
|
|
{
|
2016-12-16 14:49:59 +09:00
|
|
|
#ifdef _WIN32
|
2016-12-22 14:55:33 +03:00
|
|
|
struct tm *tmp = gmtime(&t);
|
|
|
|
if (!tmp) {
|
|
|
|
fprintf(stderr, "gmtime: %s (%i)", strerror(errno), (int)t);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
*cur_p = *tmp;
|
2016-12-16 14:49:59 +09:00
|
|
|
#else
|
|
|
|
gmtime_r(&t, cur_p);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct date_rfc1123_case {
|
|
|
|
time_t t;
|
|
|
|
char date[30];
|
|
|
|
} date_rfc1123_cases[] = {
|
|
|
|
{ 0, "Thu, 01 Jan 1970 00:00:00 GMT"} /* UNIX time of zero */,
|
|
|
|
{ 946684799, "Fri, 31 Dec 1999 23:59:59 GMT"} /* the last moment of the 20th century */,
|
|
|
|
{ 946684800, "Sat, 01 Jan 2000 00:00:00 GMT"} /* the first moment of the 21st century */,
|
|
|
|
{ 981072000, "Fri, 02 Feb 2001 00:00:00 GMT"},
|
|
|
|
{ 1015113600, "Sun, 03 Mar 2002 00:00:00 GMT"},
|
|
|
|
{ 1049414400, "Fri, 04 Apr 2003 00:00:00 GMT"},
|
|
|
|
{ 1083715200, "Wed, 05 May 2004 00:00:00 GMT"},
|
|
|
|
{ 1118016000, "Mon, 06 Jun 2005 00:00:00 GMT"},
|
|
|
|
{ 1152230400, "Fri, 07 Jul 2006 00:00:00 GMT"},
|
|
|
|
{ 1186531200, "Wed, 08 Aug 2007 00:00:00 GMT"},
|
|
|
|
{ 1220918400, "Tue, 09 Sep 2008 00:00:00 GMT"},
|
|
|
|
{ 1255132800, "Sat, 10 Oct 2009 00:00:00 GMT"},
|
|
|
|
{ 1289433600, "Thu, 11 Nov 2010 00:00:00 GMT"},
|
|
|
|
{ 1323648000, "Mon, 12 Dec 2011 00:00:00 GMT"},
|
2016-12-22 14:55:33 +03:00
|
|
|
#ifndef _WIN32
|
2017-09-01 15:50:36 -07:00
|
|
|
#if EVENT__SIZEOF_TIME_T > 4
|
2016-12-22 14:55:33 +03:00
|
|
|
/** In win32 case we have max "23:59:59 January 18, 2038, UTC" for time32 */
|
2016-12-16 14:49:59 +09:00
|
|
|
{ 4294967296, "Sun, 07 Feb 2106 06:28:16 GMT"} /* 2^32 */,
|
2016-12-22 14:55:33 +03:00
|
|
|
/** In win32 case we have max "23:59:59, December 31, 3000, UTC" for time64 */
|
2016-12-16 14:49:59 +09:00
|
|
|
{253402300799, "Fri, 31 Dec 9999 23:59:59 GMT"} /* long long future no one can imagine */,
|
2017-09-01 15:50:36 -07:00
|
|
|
#endif /* time_t != 32bit */
|
2016-12-16 14:49:59 +09:00
|
|
|
{ 1456704000, "Mon, 29 Feb 2016 00:00:00 GMT"} /* leap year */,
|
2016-12-22 14:55:33 +03:00
|
|
|
#endif
|
2016-12-16 14:49:59 +09:00
|
|
|
{ 1435708800, "Wed, 01 Jul 2015 00:00:00 GMT"} /* leap second */,
|
|
|
|
{ 1481866376, "Fri, 16 Dec 2016 05:32:56 GMT"} /* the time this test case is generated */,
|
|
|
|
{0, ""} /* end of test cases. */
|
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_evutil_date_rfc1123(void *arg)
|
|
|
|
{
|
|
|
|
struct tm query;
|
|
|
|
char result[30];
|
2016-12-19 10:22:51 +03:00
|
|
|
size_t i = 0;
|
2016-12-16 14:49:59 +09:00
|
|
|
|
|
|
|
/* Checks if too small buffers are safely accepted. */
|
|
|
|
{
|
|
|
|
create_tm_from_unix_epoch(&query, 0);
|
|
|
|
evutil_date_rfc1123(result, 8, &query);
|
|
|
|
tt_str_op(result, ==, "Thu, 01");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Checks for testcases. */
|
2016-12-19 10:22:51 +03:00
|
|
|
for (i = 0; ; i++) {
|
2016-12-16 14:49:59 +09:00
|
|
|
struct date_rfc1123_case c = date_rfc1123_cases[i];
|
|
|
|
|
|
|
|
if (strlen(c.date) == 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
create_tm_from_unix_epoch(&query, c.t);
|
|
|
|
evutil_date_rfc1123(result, sizeof(result), &query);
|
|
|
|
tt_str_op(result, ==, c.date);
|
|
|
|
}
|
|
|
|
|
|
|
|
end:
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
2018-10-25 00:25:48 +03:00
|
|
|
static void
|
|
|
|
test_evutil_v4addr_is_local(void *arg)
|
|
|
|
{
|
|
|
|
struct sockaddr_in sin;
|
|
|
|
sin.sin_family = AF_INET;
|
|
|
|
|
|
|
|
/* we use evutil_inet_pton() here to fill in network-byte order */
|
|
|
|
#define LOCAL(str, yes) do { \
|
|
|
|
tt_int_op(evutil_inet_pton(AF_INET, str, &sin.sin_addr), ==, 1); \
|
|
|
|
tt_int_op(evutil_v4addr_is_local_(&sin.sin_addr), ==, yes); \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
/** any */
|
|
|
|
sin.sin_addr.s_addr = INADDR_ANY;
|
|
|
|
tt_int_op(evutil_v4addr_is_local_(&sin.sin_addr), ==, 1);
|
|
|
|
|
|
|
|
/** loopback */
|
|
|
|
sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
|
|
|
tt_int_op(evutil_v4addr_is_local_(&sin.sin_addr), ==, 1);
|
|
|
|
LOCAL("127.0.0.1", 1);
|
|
|
|
LOCAL("127.255.255.255", 1);
|
|
|
|
LOCAL("121.0.0.1", 0);
|
|
|
|
|
|
|
|
/** link-local */
|
|
|
|
LOCAL("169.254.0.1", 1);
|
|
|
|
LOCAL("169.254.255.255", 1);
|
|
|
|
LOCAL("170.0.0.0", 0);
|
|
|
|
|
|
|
|
/** Multicast */
|
|
|
|
LOCAL("224.0.0.0", 1);
|
|
|
|
LOCAL("239.255.255.255", 1);
|
|
|
|
LOCAL("240.0.0.0", 0);
|
|
|
|
end:
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_evutil_v6addr_is_local(void *arg)
|
|
|
|
{
|
|
|
|
struct sockaddr_in6 sin6;
|
|
|
|
struct in6_addr anyaddr = IN6ADDR_ANY_INIT;
|
|
|
|
struct in6_addr loopback = IN6ADDR_LOOPBACK_INIT;
|
|
|
|
|
|
|
|
sin6.sin6_family = AF_INET6;
|
|
|
|
#define LOCAL6(str, yes) do { \
|
|
|
|
tt_int_op(evutil_inet_pton(AF_INET6, str, &sin6.sin6_addr), ==, 1);\
|
|
|
|
tt_int_op(evutil_v6addr_is_local_(&sin6.sin6_addr), ==, yes); \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
/** any */
|
|
|
|
tt_int_op(evutil_v6addr_is_local_(&anyaddr), ==, 1);
|
|
|
|
LOCAL6("::0", 1);
|
|
|
|
|
|
|
|
/** loopback */
|
|
|
|
tt_int_op(evutil_v6addr_is_local_(&loopback), ==, 1);
|
|
|
|
LOCAL6("::1", 1);
|
|
|
|
|
|
|
|
/** IPV4 mapped */
|
|
|
|
LOCAL6("::ffff:0:0", 1);
|
|
|
|
/** IPv4 translated */
|
|
|
|
LOCAL6("::ffff:0:0:0", 1);
|
|
|
|
/** IPv4/IPv6 translation */
|
|
|
|
LOCAL6("64:ff9b::", 0);
|
|
|
|
/** Link-local */
|
|
|
|
LOCAL6("fe80::", 1);
|
|
|
|
/** Multicast */
|
|
|
|
LOCAL6("ff00::", 1);
|
|
|
|
/** Unspecified */
|
|
|
|
LOCAL6("::", 1);
|
|
|
|
|
|
|
|
/** Global Internet */
|
|
|
|
LOCAL6("2001::", 0);
|
|
|
|
LOCAL6("2001:4860:4802:32::1b", 0);
|
|
|
|
end:
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
2019-10-18 21:11:37 +08:00
|
|
|
static void
|
|
|
|
socketpair_init(evutil_socket_t fd[2])
|
|
|
|
{
|
|
|
|
fd[0] = -1;
|
|
|
|
fd[1] = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
socketpair_close(evutil_socket_t fd[2])
|
|
|
|
{
|
|
|
|
if (fd[0] != -1)
|
|
|
|
evutil_closesocket(fd[0]);
|
|
|
|
if (fd[1] != -1)
|
|
|
|
evutil_closesocket(fd[1]);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_evutil_socketpair_create(void *arg)
|
|
|
|
{
|
|
|
|
evutil_socket_t fd[2];
|
|
|
|
|
|
|
|
#define SOCKETPAIR_CHECK_CLOSE(fd) do {\
|
|
|
|
tt_int_op(fd[0], > , 0); \
|
|
|
|
tt_int_op(fd[1], > , 0); \
|
|
|
|
socketpair_close(fd); \
|
|
|
|
} while(0)
|
|
|
|
|
|
|
|
socketpair_init(fd);
|
|
|
|
tt_int_op(evutil_socketpair(AF_UNSPEC, SOCK_STREAM, 0, fd), == , -1);
|
|
|
|
tt_int_op(evutil_socketpair(AF_INET6, SOCK_STREAM, 0, fd), == , -1);
|
|
|
|
tt_int_op(evutil_socketpair(AF_INET, SOCK_RAW, 0, fd), == , -1);
|
|
|
|
tt_int_op(evutil_socketpair(AF_INET, SOCK_STREAM, 1, fd), == , -1);
|
|
|
|
|
|
|
|
#ifndef _WIN32
|
|
|
|
tt_int_op(evutil_socketpair(AF_INET, SOCK_STREAM, 0, fd), == , -1);
|
|
|
|
tt_int_op(evutil_socketpair(AF_INET, SOCK_DGRAM, 0, fd), == , -1);
|
|
|
|
socketpair_init(fd);
|
|
|
|
tt_int_op(evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, fd), == , 0);
|
|
|
|
SOCKETPAIR_CHECK_CLOSE(fd);
|
|
|
|
socketpair_init(fd);
|
|
|
|
tt_int_op(evutil_socketpair(AF_UNIX, SOCK_DGRAM, 0, fd), == , 0);
|
|
|
|
SOCKETPAIR_CHECK_CLOSE(fd);
|
|
|
|
#else
|
|
|
|
tt_int_op(evutil_socketpair(AF_INET, SOCK_DGRAM, 0, fd), == , -1);
|
|
|
|
tt_int_op(evutil_socketpair(AF_UNIX, SOCK_DGRAM, 0, fd), == , -1);
|
|
|
|
socketpair_init(fd);
|
|
|
|
tt_int_op(evutil_socketpair(AF_INET, SOCK_STREAM, 0, fd), == , 0);
|
|
|
|
SOCKETPAIR_CHECK_CLOSE(fd);
|
|
|
|
socketpair_init(fd);
|
|
|
|
tt_int_op(evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, fd), == , 0);
|
|
|
|
SOCKETPAIR_CHECK_CLOSE(fd);
|
|
|
|
#endif
|
|
|
|
end:
|
|
|
|
socketpair_close(fd);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
static void
|
|
|
|
test_evutil_win_socketpair(void *arg)
|
|
|
|
{
|
|
|
|
struct basic_test_data *data = arg;
|
|
|
|
const int inet = strstr(data->setup_data, "inet") != NULL;
|
|
|
|
int family = inet ? AF_INET : AF_UNIX;
|
|
|
|
evutil_socket_t fd[2] = { -1, -1 };
|
|
|
|
int r;
|
|
|
|
int type;
|
|
|
|
ev_socklen_t typelen;
|
|
|
|
int unix_sock_works = 0;
|
|
|
|
const char *msg = "test string";
|
|
|
|
char buf[64] = { 0 };
|
|
|
|
|
|
|
|
if (!inet)
|
|
|
|
tt_str_op(data->setup_data, ==, "unix");
|
|
|
|
|
|
|
|
#ifdef EVENT__HAVE_AFUNIX_H
|
|
|
|
if (evutil_check_working_afunix_())
|
|
|
|
unix_sock_works = 1;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
tt_int_op(evutil_socketpair(family, SOCK_STREAM, 0, fd), == , 0);
|
|
|
|
tt_int_op(fd[0], > , 0);
|
|
|
|
tt_int_op(fd[1], > , 0);
|
|
|
|
|
|
|
|
typelen = sizeof(type);
|
|
|
|
r = getsockopt(fd[0], SOL_SOCKET, SO_TYPE, (void *)&type, &typelen);
|
|
|
|
tt_assert(r == 0);
|
|
|
|
tt_int_op(type, == , SOCK_STREAM);
|
|
|
|
|
|
|
|
#define CHK_LOCALADDR(a, s, f) do { \
|
|
|
|
ev_socklen_t socklen = sizeof(a); \
|
|
|
|
memset(&a, 0, socklen); \
|
|
|
|
tt_assert(getsockname(s, (struct sockaddr *)&a, &socklen) == 0); \
|
|
|
|
tt_int_op(((struct sockaddr *)&a)->sa_family, == , f); \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
if (!unix_sock_works) {
|
|
|
|
struct sockaddr_in c, a;
|
|
|
|
CHK_LOCALADDR(c, fd[0], AF_INET);
|
|
|
|
CHK_LOCALADDR(a, fd[1], AF_INET);
|
|
|
|
tt_int_op(c.sin_addr.s_addr, == , htonl(INADDR_LOOPBACK));
|
|
|
|
tt_int_op(a.sin_addr.s_addr, == , htonl(INADDR_LOOPBACK));
|
|
|
|
}
|
|
|
|
#if defined(EVENT__HAVE_AFUNIX_H)
|
|
|
|
else {
|
|
|
|
struct sockaddr_un c, a;
|
|
|
|
CHK_LOCALADDR(c, fd[0], AF_UNIX);
|
|
|
|
CHK_LOCALADDR(a, fd[1], AF_UNIX);
|
|
|
|
tt_assert(strlen(a.sun_path) > 0);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
r = send(fd[0], msg, (int)strlen(msg), 0);
|
|
|
|
tt_int_op(r, > , 0);
|
|
|
|
tt_int_op(recv(fd[1], buf, sizeof(buf), 0), >= , 0);
|
|
|
|
tt_str_op(buf, == , msg);
|
|
|
|
memset(buf, 0, sizeof(buf));
|
|
|
|
tt_int_op(send(fd[1], msg, (int)strlen(msg), 0), > , 0);
|
|
|
|
tt_int_op(recv(fd[0], buf, sizeof(buf), 0), >= , 0);
|
|
|
|
tt_str_op(buf, == , msg);
|
|
|
|
|
|
|
|
shutdown(fd[0], EVUTIL_SHUT_WR);
|
|
|
|
tt_int_op(send(fd[0], msg, (int)strlen(msg) + 1, 0), == , -1);
|
|
|
|
shutdown(fd[0], EVUTIL_SHUT_RD);
|
|
|
|
tt_int_op(recv(fd[0], buf, sizeof(buf), 0), == , -1);
|
|
|
|
shutdown(fd[1], EVUTIL_SHUT_BOTH);
|
|
|
|
tt_int_op(send(fd[1], msg, (int)strlen(msg) + 1, 0), == , -1);
|
|
|
|
|
|
|
|
end:
|
|
|
|
socketpair_close(fd);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef EVENT__HAVE_AFUNIX_H
|
|
|
|
static int
|
|
|
|
get_windows_build()
|
|
|
|
{
|
|
|
|
HKEY temp;
|
|
|
|
unsigned char value[8] = { 0 };
|
|
|
|
long long long_temp = 8;
|
|
|
|
int r = -1;
|
|
|
|
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,
|
|
|
|
"Software\\Microsoft\\Windows NT\\CurrentVersion",
|
|
|
|
0, KEY_READ, &temp) == ERROR_SUCCESS) {
|
|
|
|
if (RegQueryValueExA(temp, "CurrentBuildNumber", 0, NULL,
|
|
|
|
value, (LPDWORD)&long_temp) == ERROR_SUCCESS)
|
|
|
|
r = atoi((char*)value);
|
|
|
|
|
|
|
|
RegCloseKey(temp);
|
|
|
|
}
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_evutil_check_working_afunix(void *arg)
|
|
|
|
{
|
|
|
|
/* Minimum build number that supports Unix domain sockets on Windows */
|
|
|
|
#define MIN_BUILD_NUM 17063
|
|
|
|
int build;
|
|
|
|
int r;
|
|
|
|
|
|
|
|
build = get_windows_build();
|
|
|
|
tt_assert(build > 0);
|
|
|
|
r = evutil_check_working_afunix_();
|
|
|
|
if (build >= MIN_BUILD_NUM)
|
|
|
|
tt_int_op(r, == , 1);
|
|
|
|
else
|
|
|
|
tt_int_op(r, == , 0);
|
|
|
|
end:
|
|
|
|
;
|
|
|
|
}
|
|
|
|
#endif // EVENT__HAVE_AFUNIX_H
|
|
|
|
#endif // _WIN32
|
|
|
|
|
2009-01-29 23:19:57 +00:00
|
|
|
struct testcase_t util_testcases[] = {
|
|
|
|
{ "ipv4_parse", regress_ipv4_parse, 0, NULL, NULL },
|
|
|
|
{ "ipv6_parse", regress_ipv6_parse, 0, NULL, NULL },
|
2019-10-29 15:48:53 +01:00
|
|
|
{ "ipv6_parse_scope", regress_ipv6_parse_scope, 0, NULL, NULL },
|
2009-01-29 23:19:57 +00:00
|
|
|
{ "sockaddr_port_parse", regress_sockaddr_port_parse, 0, NULL, NULL },
|
2010-04-23 14:42:25 -04:00
|
|
|
{ "sockaddr_port_format", regress_sockaddr_port_format, 0, NULL, NULL },
|
2010-01-20 12:56:54 -05:00
|
|
|
{ "sockaddr_predicates", test_evutil_sockaddr_predicates, 0,NULL,NULL },
|
2009-01-30 17:43:59 +00:00
|
|
|
{ "evutil_snprintf", test_evutil_snprintf, 0, NULL, NULL },
|
|
|
|
{ "evutil_strtoll", test_evutil_strtoll, 0, NULL, NULL },
|
2009-07-20 14:55:07 +00:00
|
|
|
{ "evutil_casecmp", test_evutil_casecmp, 0, NULL, NULL },
|
2012-11-16 11:13:29 -05:00
|
|
|
{ "evutil_rtrim", test_evutil_rtrim, 0, NULL, NULL },
|
2009-10-29 16:35:09 +00:00
|
|
|
{ "strlcpy", test_evutil_strlcpy, 0, NULL, NULL },
|
2009-10-26 19:59:51 +00:00
|
|
|
{ "log", test_evutil_log, TT_FORK, NULL, NULL },
|
2009-11-02 19:30:25 +00:00
|
|
|
{ "upcast", test_evutil_upcast, 0, NULL, NULL },
|
2010-02-03 17:01:45 -05:00
|
|
|
{ "integers", test_evutil_integers, 0, NULL, NULL },
|
2010-02-18 01:43:37 -05:00
|
|
|
{ "rand", test_evutil_rand, TT_FORK, NULL, NULL },
|
2020-06-25 08:45:34 +03:00
|
|
|
{ "EVUTIL_IS_", test_EVUTIL_IS_, 0, NULL, NULL },
|
2009-11-16 22:25:46 +00:00
|
|
|
{ "getaddrinfo", test_evutil_getaddrinfo, TT_FORK, NULL, NULL },
|
2012-06-28 13:18:28 -04:00
|
|
|
{ "getaddrinfo_live", test_evutil_getaddrinfo_live, TT_FORK|TT_OFF_BY_DEFAULT, NULL, NULL },
|
2020-06-26 10:35:44 +03:00
|
|
|
{ "getaddrinfo_AI_ADDRCONFIG", test_evutil_getaddrinfo_AI_ADDRCONFIG, TT_FORK|TT_OFF_BY_DEFAULT, NULL, NULL },
|
2011-05-25 19:50:56 -04:00
|
|
|
#ifdef _WIN32
|
2010-09-27 15:12:55 -04:00
|
|
|
{ "loadsyslib", test_evutil_loadsyslib, TT_FORK, NULL, NULL },
|
|
|
|
#endif
|
Add argument checks to some memory functions in `event.c'.
Add a zero check to the function `event_mm_malloc_',
i.e. simply return NULL if the sz argument is zero.
On failure, set errno to ENOMEM and return NULL.
Add a zero check to the function `event_mm_calloc_',
i.e. simply return NULL if either argument is zero.
Also add an unsigned integer multiplication check, and if an integer
overflow would occur, set errno to ENOMEM and return NULL.
On failure, set errno to ENOMEM and return NULL.
Add a NULL check to the function `event_mm_strdup_',
i.e. set errno to EINVAL and return NULL.
Also add an unsigned integer addition check, and if an integer
overflow would occur, set errno to ENOMEM and return NULL.
If a memory allocation error occurs, again set errno to ENOMEM
and return NULL.
Add unit tests to `test/regress_util.c'.
2011-10-14 17:16:03 -04:00
|
|
|
{ "mm_malloc", test_event_malloc, 0, NULL, NULL },
|
|
|
|
{ "mm_calloc", test_event_calloc, 0, NULL, NULL },
|
|
|
|
{ "mm_strdup", test_event_strdup, 0, NULL, NULL },
|
2018-11-20 11:46:44 +03:00
|
|
|
{ "usleep", test_evutil_usleep, TT_RETRIABLE, NULL, NULL },
|
2012-06-29 12:47:51 -04:00
|
|
|
{ "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" },
|
2021-09-19 12:21:39 +03:00
|
|
|
{ "monotonic_prc", test_evutil_monotonic_prc, TT_RETRIABLE, &basic_setup, (void*)"" },
|
2018-11-20 11:46:44 +03:00
|
|
|
{ "monotonic_prc_precise", test_evutil_monotonic_prc, TT_RETRIABLE, &basic_setup, (void*)"precise" },
|
2021-09-19 00:57:31 +03:00
|
|
|
{ "monotonic_prc_fallback", test_evutil_monotonic_prc, TT_RETRIABLE, &basic_setup, (void*)"fallback" },
|
2016-12-16 14:49:59 +09:00
|
|
|
{ "date_rfc1123", test_evutil_date_rfc1123, 0, NULL, NULL },
|
2018-10-25 00:25:48 +03:00
|
|
|
{ "evutil_v4addr_is_local", test_evutil_v4addr_is_local, 0, NULL, NULL },
|
|
|
|
{ "evutil_v6addr_is_local", test_evutil_v6addr_is_local, 0, NULL, NULL },
|
2019-10-18 21:11:37 +08:00
|
|
|
{ "socketpair_create", test_evutil_socketpair_create, 0, NULL, NULL },
|
|
|
|
#ifdef _WIN32
|
|
|
|
{ "socketpair_inet", test_evutil_win_socketpair, 0, &basic_setup, (void*)"inet" },
|
|
|
|
{ "socketpair_unix", test_evutil_win_socketpair, 0, &basic_setup, (void*)"unix" },
|
|
|
|
#ifdef EVENT__HAVE_AFUNIX_H
|
|
|
|
{ "check_working_afunix", test_evutil_check_working_afunix, 0, NULL, NULL },
|
|
|
|
#endif
|
|
|
|
#endif
|
2009-01-29 23:19:57 +00:00
|
|
|
END_OF_TESTCASES,
|
|
|
|
};
|
|
|
|
|