freeswitch/libs/sofia-sip/libsofia-sip-ua/sresolv/test_sresolv.c
Michael Jerris b7bc5240f0 Fri Jan 23 11:13:41 CST 2009 Pekka Pessi <first.last@nokia.com>
* sresolv: caching SRES_RECORD_ERR in case a CNAME is returned, too
  
  Tracing the CNAMEs when doing cache lookups.



git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@11844 d0543943-73ff-0310-b7d9-9358b9ac24b2
2009-02-11 17:12:33 +00:00

2129 lines
56 KiB
C

/*
* This file is part of the Sofia-SIP package
*
* Copyright (C) 2006 Nokia Corporation.
*
* Contact: Pekka Pessi <pekka.pessi@nokia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
/**@internal
*
* @CFILE test_sresolv.c Test module for sresolv
*
* @author Mikko Haataja
* @author Pekka Pessi <Pekka.Pessi@nokia.com>.
*
*/
#include "config.h"
#if HAVE_STDINT_H
#include <stdint.h>
#elif HAVE_INTTYPES_H
#include <inttypes.h>
#else
#if defined(_WIN32)
typedef unsigned _int8 uint8_t;
typedef unsigned _int16 uint16_t;
typedef unsigned _int32 uint32_t;
#endif
#endif
#if HAVE_FCNTL_H
#include <fcntl.h>
#endif
#if HAVE_NETINET_IN_H
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#endif
#if HAVE_WINSOCK2_H
#include <winsock2.h>
#include <ws2tcpip.h>
#endif
#include <sofia-resolv/sres.h>
#include <sofia-resolv/sres_async.h>
#include <sofia-resolv/sres_record.h>
#include <sofia-sip/su_alloc.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#define TSTFLAGS tstflags
#include <sofia-sip/tstdef.h>
#if HAVE_POLL
#include <poll.h>
#elif HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#if HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#if HAVE_ALARM
#include <unistd.h>
#include <signal.h>
#endif
#include <sofia-sip/su_log.h>
extern su_log_t sresolv_log[];
char const name[] = "test_sresolv";
struct sres_context_s
{
su_home_t home[1];
sres_resolver_t *resolver;
sres_query_t *query;
sres_record_t **result;
int timeout;
sres_socket_t sink;
int sinkidx;
char const *sinkconf;
int ready;
int n_sockets;
sres_socket_t sockets[SRES_MAX_NAMESERVERS];
#if HAVE_POLL
struct pollfd fds[SRES_MAX_NAMESERVERS];
#endif
};
static void test_answer(sres_context_t *ctx, sres_query_t *query,
sres_record_t **answer);
static void test_answer_multi(sres_context_t *ctx, sres_query_t *query,
sres_record_t **answer);
static int tstflags = 0;
#if HAVE_WINSOCK2_H
/* Posix send() */
su_inline
ssize_t sres_send(sres_socket_t s, void *b, size_t length, int flags)
{
if (length > INT_MAX)
length = INT_MAX;
return (ssize_t)send(s, b, (int)length, flags);
}
su_inline
ssize_t sres_sendto(sres_socket_t s, void *b, size_t length, int flags,
struct sockaddr const *sa, socklen_t salen)
{
if (length > INT_MAX)
length = INT_MAX;
return (ssize_t)sendto(s, b, (int)length, flags, (void *)sa, (int)salen);
}
/* Posix recvfrom() */
su_inline
ssize_t sres_recvfrom(sres_socket_t s, void *buffer, size_t length, int flags,
struct sockaddr *from, socklen_t *fromlen)
{
int retval, ilen;
if (fromlen)
ilen = *fromlen;
if (length > INT_MAX)
length = INT_MAX;
retval = recvfrom(s, buffer, (int)length, flags,
(void *)from, fromlen ? &ilen : NULL);
if (fromlen)
*fromlen = ilen;
return (ssize_t)retval;
}
static sres_socket_t sres_socket(int af, int socktype, int protocol)
{
return socket(af, socktype, protocol);
}
su_inline
int sres_close(sres_socket_t s)
{
return closesocket(s);
}
#if !defined(IPPROTO_IPV6)
#if HAVE_SIN6
#include <tpipv6.h>
#else
#if !defined(__MINGW32__)
struct sockaddr_storage {
short ss_family;
char ss_pad[126];
};
#endif
#endif
#endif
SOFIAPUBFUN int su_inet_pton(int af, char const *src, void *dst);
SOFIAPUBFUN const char *su_inet_ntop(int af, void const *src,
char *dst, size_t size);
#else
#define sres_send(s,b,len,flags) send((s),(b),(len),(flags))
#define sres_sendto(s,b,len,flags,a,alen) \
sendto((s),(b),(len),(flags),(a),(alen))
#define sres_recvfrom(s,b,len,flags,a,alen) \
recvfrom((s),(b),(len),(flags),(a),(alen))
#define sres_close(s) close((s))
#define SOCKET_ERROR (-1)
#define INVALID_SOCKET ((sres_socket_t)-1)
#define sres_socket(x,y,z) socket((x),(y),(z))
#define su_inet_pton inet_pton
#define su_inet_ntop inet_ntop
#endif
#if 1
#if HAVE_POLL && 0
static
int setblocking(sres_socket_t s, int blocking)
{
unsigned mode = fcntl(s, F_GETFL, 0);
if (mode < 0)
return -1;
if (blocking)
mode &= ~(O_NDELAY | O_NONBLOCK);
else
mode |= O_NDELAY | O_NONBLOCK;
return fcntl(s, F_SETFL, mode);
}
/** Test few assumptions about sockets */
static
int test_socket(sres_context_t *ctx)
{
int af;
sres_socket_t s1, s2, s3, s4;
struct sockaddr_storage a[1];
struct sockaddr_storage a1[1], a2[1], a3[1], a4[1];
struct sockaddr_in *sin = (void *)a;
struct sockaddr_in *sin3 = (void *)a3, *sin4 = (void *)a4;
struct sockaddr *sa = (void *)a;
struct sockaddr *sa3 = (void *)a3, *sa4 = (void *)a4;
socklen_t alen, a1len, a2len, a3len, a4len;
char buf[16];
BEGIN();
af = AF_INET;
for (;;) {
TEST_1((s1 = sres_socket(af, SOCK_DGRAM, 0)) != INVALID_SOCKET);
TEST_1((s2 = sres_socket(af, SOCK_DGRAM, 0)) != INVALID_SOCKET);
TEST_1((s3 = sres_socket(af, SOCK_DGRAM, 0)) != INVALID_SOCKET);
TEST_1((s4 = sres_socket(af, SOCK_DGRAM, 0)) != INVALID_SOCKET);
TEST_1(setblocking(s1, 0) == 0);
TEST_1(setblocking(s2, 0) == 0);
TEST_1(setblocking(s3, 0) == 0);
TEST_1(setblocking(s4, 0) == 0);
memset(a, 0, sizeof a);
memset(a1, 0, sizeof a1);
memset(a2, 0, sizeof a2);
memset(a3, 0, sizeof a3);
memset(a4, 0, sizeof a4);
#if HAVE_SA_LEN
a1->ss_len = a2->ss_len = a3->ss_len = a4->ss_len = sizeof a1;
#endif
a1->ss_family = a2->ss_family = a3->ss_family = a4->ss_family = af;
if (af == AF_INET)
a1len = a2len = a3len = a4len = sizeof (struct sockaddr_in);
else
a1len = a2len = a3len = a4len = sizeof (struct sockaddr_in6);
if (af == AF_INET) {
TEST_1(su_inet_pton(af, "127.0.0.1", &sin3->sin_addr) > 0);
TEST_1(su_inet_pton(af, "127.0.0.1", &sin4->sin_addr) > 0);
} else {
}
TEST(bind(s3, (struct sockaddr *)a3, a3len), 0);
TEST(bind(s4, (struct sockaddr *)a4, a4len), 0);
alen = sizeof a;
TEST(getsockname(s3, (struct sockaddr *)a, &alen), 0);
sin3->sin_port = sin->sin_port;
memset(sin->sin_zero, 0, sizeof sin->sin_zero);
TEST(alen, a3len); TEST_M(a, a3, a3len);
alen = sizeof a;
TEST(getsockname(s4, (struct sockaddr *)a, &alen), 0);
sin4->sin_port = sin->sin_port;
memset(sin->sin_zero, 0, sizeof sin->sin_zero);
TEST(alen, a4len); TEST_M(a, a4, a4len);
TEST(connect(s1, sa3, a3len), 0);
TEST(getsockname(s1, (struct sockaddr *)a1, &a1len), 0);
TEST(connect(s2, sa4, a4len), 0);
TEST(getsockname(s2, (struct sockaddr *)a2, &a2len), 0);
TEST(sres_sendto(s1, "foo", 3, 0, sa4, a4len), 3);
TEST(sres_recvfrom(s4, buf, sizeof buf, 0, sa, &alen), 3);
TEST(sres_sendto(s4, "bar", 3, 0, sa, alen), 3);
TEST(sres_recvfrom(s2, buf, sizeof buf, 0, sa, &alen), -1);
TEST(sres_recvfrom(s1, buf, sizeof buf, 0, sa, &alen), 3);
sres_close(s1), sres_close(s2), sres_close(s3), sres_close(s4);
break;
}
END();
}
#endif
static unsigned offset;
#define TEST_RUN(ctx) \
{ sres_free_answers(ctx->resolver, ctx->result); ctx->result = NULL; \
ctx->query = NULL; run(ctx); TEST_1(ctx->query); }
static
int poll_sockets(sres_context_t *ctx)
{
int i, n, events;
n = ctx->n_sockets;
events = poll(ctx->fds, ctx->n_sockets, ctx->timeout ? 50 : 500);
if (!events)
return events;
for (i = 0; i < n; i++) {
if (ctx->fds[i].revents & POLLERR)
sres_resolver_error(ctx->resolver, ctx->fds[i].fd);
if (ctx->fds[i].revents & POLLIN)
sres_resolver_receive(ctx->resolver, ctx->fds[i].fd);
}
return events;
}
#define BREAK(ctx) (ctx->ready = 1)
static void run(sres_context_t *ctx)
{
for (ctx->ready = 0; !ctx->ready; ) {
poll_sockets(ctx);
if (ctx->timeout) {
ctx->timeout <<= 1;
offset += ctx->timeout;
}
/* No harm is done (except wasted CPU) if timer is called more often */
sres_resolver_timer(ctx->resolver, -1);
}
}
int test_soa(sres_context_t *ctx)
{
sres_resolver_t *res = ctx->resolver;
sres_record_t **result;
const sres_soa_record_t *rr_soa;
char const *domain = "example.com";
BEGIN();
TEST_1(sres_query(res, test_answer, ctx, sres_type_soa, domain));
TEST_RUN(ctx);
TEST_1(sres_query(res, test_answer, ctx, sres_type_soa, domain));
TEST_RUN(ctx);
TEST_1(result = sres_cached_answers(res, sres_type_soa, domain));
TEST_1(result != NULL);
TEST_1(result[0] != NULL);
rr_soa = result[0]->sr_soa;
TEST(rr_soa->soa_record->r_type, sres_type_soa);
TEST(rr_soa->soa_record->r_class, sres_class_in);
TEST_S(rr_soa->soa_mname, "ns.example.com.");
TEST_S(rr_soa->soa_rname, "root.example.com.");
TEST(rr_soa->soa_serial, 2002042901);
TEST(rr_soa->soa_refresh, 7200);
TEST(rr_soa->soa_retry, 600);
TEST(rr_soa->soa_expire, 36000000);
TEST(rr_soa->soa_minimum, 60);
sres_free_answers(res, result);
END();
}
int test_naptr(sres_context_t *ctx)
{
sres_resolver_t *res = ctx->resolver;
sres_record_t **result;
const sres_naptr_record_t *rr;
char const *domain = "example.com";
int i;
BEGIN();
TEST_1(sres_query(res, test_answer, ctx, sres_type_naptr, domain));
TEST_RUN(ctx);
TEST_1(result = ctx->result);
TEST_1(result[0]);
for (i = 0; result[i] != NULL; i++) {
rr = (sres_naptr_record_t *) result[i]->sr_naptr;
switch(rr->na_order) {
case 20:
TEST(rr->na_record->r_type, sres_type_naptr);
TEST(rr->na_record->r_class, sres_class_in);
TEST(rr->na_record->r_ttl, 60);
TEST(rr->na_order, 20);
TEST(rr->na_prefer, 50);
TEST_S(rr->na_flags, "s");
TEST_S(rr->na_services, "SIPS+D2T");
TEST_S(rr->na_regexp, "");
TEST_S(rr->na_replace, "_sips._tcp.example.com.");
break;
case 40:
TEST(rr->na_record->r_type, sres_type_naptr);
TEST(rr->na_record->r_class, sres_class_in);
TEST(rr->na_record->r_ttl, 60);
TEST(rr->na_order, 40);
TEST(rr->na_prefer, 15);
TEST_S(rr->na_flags, "s");
TEST_S(rr->na_services, "SIP+D2U");
TEST_S(rr->na_regexp, "");
TEST_S(rr->na_replace, "_sip._udp.example.com.");
break;
case 50:
TEST(rr->na_record->r_type, sres_type_naptr);
TEST(rr->na_record->r_class, sres_class_in);
TEST(rr->na_record->r_ttl, 60);
TEST(rr->na_order, 50);
TEST(rr->na_prefer, 15);
TEST_S(rr->na_flags, "u");
TEST_S(rr->na_services, "TEST+D2U");
TEST_S(rr->na_regexp, "/(tst:([^@]+@))?example.com$/\\1operator.com/i");
TEST_S(rr->na_replace, ".");
break;
case 80:
TEST(rr->na_record->r_type, sres_type_naptr);
TEST(rr->na_record->r_class, sres_class_in);
TEST(rr->na_record->r_ttl, 60);
TEST(rr->na_order, 80);
TEST(rr->na_prefer, 25);
TEST_S(rr->na_flags, "s");
TEST_S(rr->na_services, "SIP+D2T");
TEST_S(rr->na_regexp, "");
TEST_S(rr->na_replace, "_sip._tcp.example.com.");
break;
default:
TEST_1(0);
}
}
sres_free_answers(res, ctx->result), ctx->result = NULL;
END();
}
char const longname[1026] =
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.";
char name2048[2049] =
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
"gggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg"
"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
"gggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg"
"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
"gggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg"
"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
"gggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg"
"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh";
int test_a(sres_context_t *ctx)
{
sres_resolver_t *res = ctx->resolver;
sres_query_t *query;
sres_record_t **result;
const sres_a_record_t *rr_a;
char const *domain = "sip00.example.com";
char name1025[1026] =
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
".";
BEGIN();
TEST_1(!sres_query(res, test_answer, ctx, sres_type_a, name1025));
name1025[1024] = '\0';
TEST_1(!sres_query(res, test_answer, ctx, sres_type_a, name1025));
name1025[1023] = '\0';
TEST_1(!sres_query(res, test_answer, ctx, sres_type_a, name1025));
TEST_1(!sres_query(res, test_answer, ctx, sres_type_a, name2048));
query = sres_query(res, test_answer, ctx, sres_type_a, longname);
TEST_1(query);
sres_query_bind(query, NULL, NULL);
TEST_1(sres_query(res, test_answer, ctx, sres_type_a, domain));
TEST_RUN(ctx);
TEST_1(result = ctx->result);
TEST_1(result[0]);
TEST(result[0]->sr_record->r_status, 0);
TEST_1(rr_a = result[0]->sr_a);
TEST(rr_a->a_record->r_type, sres_type_a);
TEST(rr_a->a_record->r_class, sres_class_in);
TEST(rr_a->a_record->r_ttl, 60);
TEST_S(inet_ntoa(rr_a->a_addr), "194.2.188.133");
sres_free_answers(res, ctx->result), ctx->result = NULL;
TEST_1(result = sres_cached_answers(res, sres_type_a, domain));
TEST(result[0]->sr_record->r_status, 0);
TEST_1(rr_a = result[0]->sr_a);
TEST(rr_a->a_record->r_type, sres_type_a);
TEST(rr_a->a_record->r_class, sres_class_in);
TEST(rr_a->a_record->r_ttl, 60);
TEST_S(inet_ntoa(rr_a->a_addr), "194.2.188.133");
sres_free_answers(res, result);
/* Try sub-queries */
TEST_1(sres_search(res, test_answer, ctx, sres_type_a, "sip00"));
TEST_RUN(ctx);
TEST_1(result = ctx->result);
for (;*result; result++)
if (result[0]->sr_a->a_record->r_type == sres_type_a)
break;
TEST(result[0]->sr_record->r_status, 0);
TEST_1(rr_a = result[0]->sr_a);
TEST(rr_a->a_record->r_type, sres_type_a);
TEST(rr_a->a_record->r_class, sres_class_in);
TEST(rr_a->a_record->r_ttl, 60);
TEST_S(inet_ntoa(rr_a->a_addr), "194.2.188.133");
sres_free_answers(res, ctx->result), ctx->result = NULL;
/* Try missing domain */
TEST_1(sres_query(res, test_answer, ctx, sres_type_a,
"no-sip.example.com"));
TEST_RUN(ctx);
TEST_1(result = ctx->result);
TEST(result[0]->sr_record->r_status, SRES_NAME_ERR);
TEST_1(rr_a = result[0]->sr_a);
TEST(rr_a->a_record->r_type, sres_type_a);
TEST(rr_a->a_record->r_class, sres_class_in);
/* Error gets TTL from example.com SOA record minimum time */
TEST(rr_a->a_record->r_ttl, 60);
sres_free_answers(res, ctx->result), ctx->result = NULL;
/* Try domain without A record =>
we should get a record with SRES_RECORD_ERR */
TEST_1(sres_query(res, test_answer, ctx, sres_type_a,
"aaaa.example.com"));
TEST_RUN(ctx);
TEST_1(result = ctx->result);
TEST(result[0]->sr_record->r_status, SRES_RECORD_ERR);
TEST_1(rr_a = result[0]->sr_a);
TEST(rr_a->a_record->r_type, sres_type_a);
TEST(rr_a->a_record->r_class, sres_class_in);
/* Error gets TTL from example.com SOA record minimum time */
TEST(rr_a->a_record->r_ttl, 60);
sres_free_answers(res, ctx->result), ctx->result = NULL;
/* Cached search */
TEST_1(result = sres_search_cached_answers(res, sres_type_a, "sip00"));
TEST_1(rr_a = result[0]->sr_a);
TEST(rr_a->a_record->r_status, 0);
TEST_S(rr_a->a_record->r_name, "sip00.example.com.");
TEST(rr_a->a_record->r_type, sres_type_a);
TEST(rr_a->a_record->r_class, sres_class_in);
TEST(rr_a->a_record->r_ttl, 60);
TEST_S(inet_ntoa(rr_a->a_addr), "194.2.188.133");
if (result[1]) {
TEST(result[1]->sr_a->a_record->r_type, sres_type_a);
}
sres_free_answers(res, result), result = NULL;
/* Cached search */
TEST_1(result = sres_cached_answers(res, sres_type_a, "no-sip.example.com"));
TEST_1(rr_a = result[0]->sr_a);
TEST(rr_a->a_record->r_status, SRES_NAME_ERR);
TEST(rr_a->a_record->r_type, sres_type_a);
TEST(rr_a->a_record->r_class, sres_class_in);
sres_free_answers(res, result), result = NULL;
END();
}
#if HAVE_SIN6
int test_a6(sres_context_t *ctx)
{
sres_resolver_t *res = ctx->resolver;
sres_record_t **result;
const sres_a6_record_t *rr_a6;
char buf[50] = {0};
char const *domain = "oldns.example.com";
BEGIN();
TEST_1(sres_query(res, test_answer, ctx, sres_type_a6, domain));
TEST_RUN(ctx);
TEST_1(result = ctx->result);
TEST_1(result[0]);
rr_a6 = result[0]->sr_a6;
TEST(rr_a6->a6_record->r_type, sres_type_a6);
TEST(rr_a6->a6_record->r_class, sres_class_in);
TEST(rr_a6->a6_record->r_ttl, 60);
TEST(rr_a6->a6_prelen, 0);
TEST_S(su_inet_ntop(AF_INET6, &rr_a6->a6_suffix, buf, sizeof(buf)),
"3ffe:1200:3012:c000:210:a4ff:fe8d:6a46");
TEST_P(rr_a6->a6_prename, NULL);
sres_free_answers(res, ctx->result), ctx->result = NULL;
TEST_1(result = sres_cached_answers(res, sres_type_a6, domain));
TEST_1(rr_a6 = result[0]->sr_a6);
TEST(rr_a6->a6_record->r_type, sres_type_a6);
TEST(rr_a6->a6_record->r_class, sres_class_in);
TEST(rr_a6->a6_record->r_ttl, 60);
TEST(rr_a6->a6_prelen, 0);
TEST_S(su_inet_ntop(AF_INET6, &rr_a6->a6_suffix, buf, sizeof(buf)),
"3ffe:1200:3012:c000:210:a4ff:fe8d:6a46");
TEST_P(rr_a6->a6_prename, NULL);
sres_free_answers(res, result), result = NULL;
END();
}
int test_a6_prefix(sres_context_t *ctx)
{
sres_resolver_t *res = ctx->resolver;
sres_record_t **result;
const sres_a6_record_t *rr_a6;
char buf[50] = {0};
char const *domain = "a6.example.com";
BEGIN();
TEST_1(sres_query(res, test_answer, ctx, sres_type_a6, domain));
TEST_RUN(ctx);
TEST_1(result = ctx->result);
TEST_1(rr_a6 = result[0]->sr_a6);
TEST(rr_a6->a6_record->r_type, sres_type_a6);
TEST(rr_a6->a6_record->r_class, sres_class_in);
TEST(rr_a6->a6_record->r_ttl, 60);
TEST(rr_a6->a6_prelen, 64);
TEST_S(su_inet_ntop(AF_INET6, &rr_a6->a6_suffix, buf, sizeof(buf)),
"::a08:20ff:fe7d:e7ac");
TEST_S(rr_a6->a6_prename, "mynet.example.com.");
sres_free_answers(res, ctx->result), ctx->result = NULL;
/* Check parsing of special case: no prefix */
TEST_1(sres_query(res, test_answer, ctx, sres_type_a6, "full.example.com"));
TEST_RUN(ctx);
TEST_1(result = ctx->result);
TEST_1(rr_a6 = result[0]->sr_a6);
TEST(rr_a6->a6_record->r_type, sres_type_a6);
TEST(rr_a6->a6_record->r_class, sres_class_in);
TEST(rr_a6->a6_record->r_ttl, 60);
TEST(rr_a6->a6_prelen, 0);
TEST_S(su_inet_ntop(AF_INET6, &rr_a6->a6_suffix, buf, sizeof(buf)),
"3ff0:12:3012:c006:a08:20ff:fe7d:e7ac");
TEST_P(rr_a6->a6_prename, NULL);
sres_free_answers(res, ctx->result), ctx->result = NULL;
/* Check parsing of special case: no suffix */
TEST_1(sres_query(res, test_answer, ctx, sres_type_a6, "alias6.example.com"));
TEST_RUN(ctx);
TEST_1(result = ctx->result);
TEST_1(rr_a6 = result[0]->sr_a6);
TEST(rr_a6->a6_record->r_type, sres_type_a6);
TEST(rr_a6->a6_record->r_class, sres_class_in);
TEST(rr_a6->a6_record->r_ttl, 60);
TEST(rr_a6->a6_prelen, 128);
TEST_S(su_inet_ntop(AF_INET6, &rr_a6->a6_suffix, buf, sizeof(buf)), "::");
TEST_S(rr_a6->a6_prename, "a6.example.com.");
sres_free_answers(res, ctx->result), ctx->result = NULL;
TEST_1(result = sres_cached_answers(res, sres_type_a6, domain));
TEST_1(rr_a6 = result[0]->sr_a6);
TEST(rr_a6->a6_record->r_type, sres_type_a6);
TEST(rr_a6->a6_record->r_class, sres_class_in);
TEST(rr_a6->a6_record->r_ttl, 60);
TEST(rr_a6->a6_prelen, 64);
TEST_S(su_inet_ntop(AF_INET6, &rr_a6->a6_suffix, buf, sizeof(buf)),
"::a08:20ff:fe7d:e7ac");
TEST_S(rr_a6->a6_prename, "mynet.example.com.");
sres_free_answers(res, result), result = NULL;
END();
}
int test_aaaa(sres_context_t *ctx)
{
sres_resolver_t *res = ctx->resolver;
sres_record_t **result;
const sres_aaaa_record_t *rr_aaaa;
char buf[50] = {0};
char const *domain = "sip03.example.com";
BEGIN();
TEST_1(sres_query(res, test_answer, ctx, sres_type_aaaa, domain));
TEST_RUN(ctx);
TEST_1(result = ctx->result);
TEST_1(rr_aaaa = result[0]->sr_aaaa);
TEST(rr_aaaa->aaaa_record->r_type, sres_type_aaaa);
TEST(rr_aaaa->aaaa_record->r_class, sres_class_in);
TEST(rr_aaaa->aaaa_record->r_ttl, 60);
TEST_S(su_inet_ntop(AF_INET6, &rr_aaaa->aaaa_addr, buf, sizeof(buf)),
"3ffe:1200:3012:c000:206:5bff:fe55:4630");
sres_free_answers(res, ctx->result), ctx->result = NULL;
TEST_1(result = sres_cached_answers(res, sres_type_aaaa, domain));
TEST_1(rr_aaaa = result[0]->sr_aaaa);
TEST(rr_aaaa->aaaa_record->r_type, sres_type_aaaa);
TEST(rr_aaaa->aaaa_record->r_class, sres_class_in);
TEST(rr_aaaa->aaaa_record->r_ttl, 60);
TEST_S(su_inet_ntop(AF_INET6, &rr_aaaa->aaaa_addr, buf, sizeof(buf)),
"3ffe:1200:3012:c000:206:5bff:fe55:4630");
sres_free_answers(res, result), result = NULL;
END();
}
#endif /* HAVE_SIN6 */
int test_srv(sres_context_t *ctx)
{
sres_resolver_t *res = ctx->resolver;
sres_record_t **result;
const sres_srv_record_t *rr;
char const *domain = "_sips._tcp.example.com";
int i;
BEGIN();
TEST_1(sres_query(res, test_answer, ctx, sres_type_srv, domain));
TEST_RUN(ctx);
TEST_1(result = ctx->result);
for (i = 0; result[i] != NULL; i++) {
TEST_1(rr = (sres_srv_record_t *) result[i]->sr_srv);
switch(rr->srv_priority) {
case 3:
TEST(rr->srv_record->r_type, sres_type_srv);
TEST(rr->srv_record->r_class, sres_class_in);
TEST(rr->srv_record->r_ttl, 60);
TEST(rr->srv_weight, 100);
TEST(rr->srv_port, 5061);
TEST_S(rr->srv_target, "sip00.example.com.");
break;
case 4:
TEST(rr->srv_record->r_type, sres_type_srv);
TEST(rr->srv_record->r_class, sres_class_in);
TEST(rr->srv_record->r_ttl, 60);
TEST(rr->srv_weight, 50);
TEST(rr->srv_port, 5050);
TEST_S(rr->srv_target, "sip02.example.com.");
break;
case 5:
TEST(rr->srv_record->r_type, sres_type_srv);
TEST(rr->srv_record->r_class, sres_class_in);
TEST(rr->srv_record->r_ttl, 60);
TEST(rr->srv_weight, 10);
TEST(rr->srv_port, 5060);
TEST_S(rr->srv_target, "sip01.example.com.");
break;
default:
TEST_1(0);
}
}
sres_free_answers(res, ctx->result), ctx->result = NULL;
TEST_1(result = sres_cached_answers(res, sres_type_srv, domain));
for (i = 0; result[i] != NULL; i++) {
TEST_1(rr = (sres_srv_record_t *) result[i]->sr_srv);
switch(rr->srv_priority) {
case 3:
TEST(rr->srv_record->r_type, sres_type_srv);
TEST(rr->srv_record->r_class, sres_class_in);
TEST(rr->srv_record->r_ttl, 60);
TEST(rr->srv_weight, 100);
TEST(rr->srv_port, 5061);
TEST_S(rr->srv_target, "sip00.example.com.");
break;
case 4:
TEST(rr->srv_record->r_type, sres_type_srv);
TEST(rr->srv_record->r_class, sres_class_in);
TEST(rr->srv_record->r_ttl, 60);
TEST(rr->srv_weight, 50);
TEST(rr->srv_port, 5050);
TEST_S(rr->srv_target, "sip02.example.com.");
break;
case 5:
TEST(rr->srv_record->r_type, sres_type_srv);
TEST(rr->srv_record->r_class, sres_class_in);
TEST(rr->srv_record->r_ttl, 60);
TEST(rr->srv_weight, 10);
TEST(rr->srv_port, 5060);
TEST_S(rr->srv_target, "sip01.example.com.");
break;
default:
TEST_1(0);
}
}
sres_free_answers(res, result), result = NULL;
END();
}
int test_cname(sres_context_t *ctx)
{
sres_resolver_t *res = ctx->resolver;
sres_record_t **result, *sr;
const sres_cname_record_t *cn;
char const *domain = "sip.example.com";
BEGIN();
TEST_1(sres_query(res, test_answer, ctx, sres_type_naptr, domain));
TEST_RUN(ctx);
TEST_1(result = ctx->result);
TEST_1(sr = result[0]);
TEST_1(sr->sr_record->r_status == SRES_RECORD_ERR);
TEST_1(cn = result[1]->sr_cname);
TEST(cn->cn_record->r_class, sres_class_in);
TEST(cn->cn_record->r_type, sres_type_cname);
TEST(cn->cn_record->r_ttl, 60);
TEST_S(cn->cn_cname, "sip00.example.com.");
sres_free_answers(res, ctx->result), ctx->result = NULL;
TEST_1(result = sres_cached_answers(res, sres_type_naptr, domain));
TEST_1(sr = result[0]);
TEST_1(sr->sr_record->r_status == SRES_RECORD_ERR);
TEST_1(cn = result[1]->sr_cname);
TEST(cn->cn_record->r_class, sres_class_in);
TEST(cn->cn_record->r_type, sres_type_cname);
TEST(cn->cn_record->r_ttl, 60);
TEST_S(cn->cn_cname, "sip00.example.com.");
sres_free_answers(res, result), ctx->result = NULL;
TEST_1(result = sres_cached_answers(res, sres_qtype_any, domain));
TEST_1(cn = result[0]->sr_cname);
TEST(cn->cn_record->r_class, sres_class_in);
TEST(cn->cn_record->r_type, sres_type_cname);
TEST(cn->cn_record->r_ttl, 60);
TEST_S(cn->cn_cname, "sip00.example.com.");
/* We might have A record, or then not */
sres_free_answers(res, result), ctx->result = NULL;
TEST_1(sres_query(res, test_answer, ctx, sres_type_a, domain));
TEST_RUN(ctx);
TEST_1(result = ctx->result);
TEST_1(cn = result[0]->sr_cname);
TEST(cn->cn_record->r_class, sres_class_in);
TEST(cn->cn_record->r_type, sres_type_cname);
TEST(cn->cn_record->r_ttl, 60);
TEST_S(cn->cn_cname, "sip00.example.com.");
TEST_1(sr = result[1]);
TEST(sr->sr_record->r_class, sres_class_in);
TEST(sr->sr_record->r_type, sres_type_a);
sres_free_answers(res, ctx->result), ctx->result = NULL;
TEST_1(result = sres_cached_answers(res, sres_type_a, domain));
TEST_1(cn = result[0]->sr_cname);
TEST(cn->cn_record->r_class, sres_class_in);
TEST(cn->cn_record->r_type, sres_type_cname);
TEST(cn->cn_record->r_ttl, 60);
TEST_S(cn->cn_cname, "sip00.example.com.");
TEST_1(sr = result[1]);
TEST(sr->sr_record->r_class, sres_class_in);
TEST(sr->sr_record->r_type, sres_type_a);
sres_free_answers(res, result);
domain = "cloop.example.com";
TEST_1(sres_query(res, test_answer, ctx, sres_type_a, domain));
TEST_RUN(ctx);
TEST_1(result = ctx->result);
TEST_1(sr = result[0]);
TEST_1(sr->sr_record->r_status == SRES_RECORD_ERR);
TEST_1(cn = result[1]->sr_cname);
TEST(cn->cn_record->r_class, sres_class_in);
TEST(cn->cn_record->r_type, sres_type_cname);
TEST(cn->cn_record->r_ttl, 60);
TEST_S(cn->cn_cname, "cloop0.example.com.");
TEST_1(cn = result[2]->sr_cname);
TEST(cn->cn_record->r_class, sres_class_in);
TEST(cn->cn_record->r_type, sres_type_cname);
TEST(cn->cn_record->r_ttl, 60);
TEST_S(cn->cn_cname, "cloop1.example.com.");
TEST_1(cn = result[3]->sr_cname);
TEST(cn->cn_record->r_class, sres_class_in);
TEST(cn->cn_record->r_type, sres_type_cname);
TEST(cn->cn_record->r_ttl, 60);
TEST_S(cn->cn_cname, "cloop2.example.com.");
TEST_1(cn = result[4]->sr_cname);
TEST(cn->cn_record->r_class, sres_class_in);
TEST(cn->cn_record->r_type, sres_type_cname);
TEST(cn->cn_record->r_ttl, 60);
TEST_S(cn->cn_cname, "cloop0.example.com.");
TEST_1(result[5] == NULL);
sres_free_answers(res, ctx->result), ctx->result = NULL;
TEST_1(result = sres_cached_answers(res, sres_type_a, domain));
TEST_1(sr = result[0]);
TEST_1(sr->sr_record->r_status == SRES_RECORD_ERR);
TEST_1(cn = result[1]->sr_cname);
TEST(cn->cn_record->r_class, sres_class_in);
TEST(cn->cn_record->r_type, sres_type_cname);
TEST(cn->cn_record->r_ttl, 60);
TEST_S(cn->cn_cname, "cloop0.example.com.");
TEST_1(cn = result[2]->sr_cname);
TEST(cn->cn_record->r_class, sres_class_in);
TEST(cn->cn_record->r_type, sres_type_cname);
TEST(cn->cn_record->r_ttl, 60);
TEST_S(cn->cn_cname, "cloop1.example.com.");
TEST_1(cn = result[3]->sr_cname);
TEST(cn->cn_record->r_class, sres_class_in);
TEST(cn->cn_record->r_type, sres_type_cname);
TEST(cn->cn_record->r_ttl, 60);
TEST_S(cn->cn_cname, "cloop2.example.com.");
TEST_1(cn = result[4]->sr_cname);
TEST(cn->cn_record->r_class, sres_class_in);
TEST(cn->cn_record->r_type, sres_type_cname);
TEST(cn->cn_record->r_ttl, 60);
TEST_S(cn->cn_cname, "cloop0.example.com.");
TEST_1(result[5] == NULL);
sres_free_answers(res, result);
END();
}
int test_ptr_ipv4(sres_context_t *ctx)
{
sres_resolver_t *res = ctx->resolver;
sres_record_t **result;
const sres_ptr_record_t *rr;
char const *domain = "1.0.0.127.in-addr.arpa";
BEGIN();
TEST_1(sres_query(res, test_answer, ctx, sres_type_ptr, domain));
TEST_RUN(ctx);
result = ctx->result;
TEST_1(result != NULL);
TEST_1(result[0] != NULL);
rr = result[0]->sr_ptr;
TEST_1(rr != NULL);
TEST(rr->ptr_record->r_class, sres_class_in);
TEST(rr->ptr_record->r_type, sres_type_ptr);
TEST_S(rr->ptr_domain, "localhost.");
END();
}
int test_ptr_ipv4_sockaddr(sres_context_t *ctx)
{
sres_resolver_t *res = ctx->resolver;
sres_record_t **result;
sres_query_t *query;
const sres_ptr_record_t *rr;
struct sockaddr_in sin = {0};
su_inet_pton(AF_INET, "127.0.0.1", &sin.sin_addr);
sin.sin_family = AF_INET;
BEGIN();
query = sres_query_sockaddr(res, test_answer, ctx,
sres_qtype_any, (struct sockaddr*)&sin);
TEST_1(query != NULL);
TEST_RUN(ctx);
result = ctx->result;
TEST_1(result != NULL);
TEST_1(result[0] != NULL);
rr = result[0]->sr_ptr;
TEST_1(rr != NULL);
TEST(rr->ptr_record->r_type, sres_type_ptr);
TEST(rr->ptr_record->r_class, sres_class_in);
TEST_S(rr->ptr_domain, "localhost.");
END();
}
#if HAVE_SIN6
int test_ptr_ipv6(sres_context_t *ctx)
{
sres_resolver_t *res = ctx->resolver;
sres_record_t **result;
const sres_ptr_record_t *rr;
char const *domain =
"c.a.7.e.d.7.e.f.f.f.0.2.8.0.a.0.0.0.0.c.2.1.0.3.0.0.2.1.e.f.f.3.ip6.int";
BEGIN();
TEST_1(sres_query(res, test_answer, ctx, sres_type_ptr, domain));
TEST_RUN(ctx);
result = ctx->result;
TEST_1(result != NULL);
TEST_1(result[0] != NULL);
rr = result[0]->sr_ptr;
TEST_1(rr != NULL);
TEST(rr->ptr_record->r_type, sres_type_ptr);
TEST(rr->ptr_record->r_class, sres_class_in);
TEST_S(rr->ptr_domain, "sip01.example.com.");
END();
}
int test_ptr_ipv6_sockaddr(sres_context_t *ctx)
{
sres_resolver_t *res = ctx->resolver;
sres_record_t **result;
const sres_ptr_record_t *rr;
struct sockaddr_in6 sin6 = {0};
BEGIN();
su_inet_pton(AF_INET6, "3ffe:1200:3012:c000:0a08:20ff:fe7d:e7ac",
&sin6.sin6_addr);
sin6.sin6_family = AF_INET6;
ctx->query =
sres_query_sockaddr(res, test_answer, ctx,
sres_type_ptr, (struct sockaddr*)&sin6);
TEST_1(ctx->query != NULL);
TEST_RUN(ctx);
result = ctx->result;
TEST_1(result != NULL);
TEST_1(result[0] != NULL);
rr = result[0]->sr_ptr;
TEST_1(rr != NULL);
TEST(rr->ptr_record->r_type, sres_type_ptr);
TEST(rr->ptr_record->r_class, sres_class_in);
TEST_S(rr->ptr_domain, "sip01.example.com.");
END();
}
#endif /* HAVE_SIN6 */
/* Test sres_cached_answers(), sres_sort_answers(), sres_free_answers() */
int test_cache(sres_context_t *ctx)
{
sres_resolver_t *res = ctx->resolver;
int ok = 0;
sres_record_t *sort_array[3];
sres_record_t **result;
sres_query_t *query;
const sres_record_t *rr = NULL;
const sres_a6_record_t *rr_a6;
const sres_aaaa_record_t *rr_aaaa;
const sres_cname_record_t *rr_cname;
const sres_ptr_record_t *rr_ptr;
#if HAVE_SIN6
struct sockaddr_in6 sin6 = {0};
#endif
char const *domain;
char buf[50] = {0};
int i, j;
BEGIN();
sres_query(res, test_answer_multi, ctx,
sres_qtype_any, "example.com");
sres_query(res, test_answer_multi, ctx,
sres_qtype_any, "_sips._tcp.example.com");
sres_query(res, test_answer_multi, ctx,
sres_qtype_any, "sip.example.com");
sres_query(res, test_answer_multi, ctx,
sres_qtype_any, "subnet.example.com");
#if HAVE_SIN6
sres_query(res, test_answer_multi, ctx,
sres_type_aaaa, "mgw02.example.com");
su_inet_pton(AF_INET6,
"3ffe:1200:3012:c000:0a08:20ff:fe7d:e7ac",
&sin6.sin6_addr);
sin6.sin6_family = AF_INET6;
query = sres_query_sockaddr(res, test_answer_multi, ctx,
sres_qtype_any, (struct sockaddr *)&sin6);
TEST_1(query != NULL);
#endif
TEST_RUN(ctx);
/* For a chance, a fully qualified domain name with final "." */
domain = "example.com.";
result = sres_cached_answers(res,
sres_qtype_any,
domain);
TEST_1(result != NULL);
for (i = 0; result[i] != NULL; i++) {
rr = result[i];
if (rr->sr_record->r_type == sres_type_naptr) {
const sres_naptr_record_t *rr_naptr = rr->sr_naptr;
switch(rr_naptr->na_order) {
case 20:
TEST(rr_naptr->na_record->r_type, sres_type_naptr);
TEST(rr_naptr->na_record->r_class, sres_class_in);
TEST(rr_naptr->na_record->r_ttl, 60);
TEST(rr_naptr->na_order, 20);
TEST(rr_naptr->na_prefer, 50);
TEST_S(rr_naptr->na_flags, "s");
TEST_S(rr_naptr->na_services, "SIPS+D2T");
TEST_S(rr_naptr->na_regexp, "");
TEST_S(rr_naptr->na_replace, "_sips._tcp.example.com.");
ok |= 1;
break;
case 40:
TEST(rr_naptr->na_record->r_type, sres_type_naptr);
TEST(rr_naptr->na_record->r_class, sres_class_in);
TEST(rr_naptr->na_record->r_ttl, 60);
TEST(rr_naptr->na_order, 40);
TEST(rr_naptr->na_prefer, 15);
TEST_S(rr_naptr->na_flags, "s");
TEST_S(rr_naptr->na_services, "SIP+D2U");
TEST_S(rr_naptr->na_regexp, "");
TEST_S(rr_naptr->na_replace, "_sip._udp.example.com.");
ok |= 2;
break;
case 50:
TEST(rr_naptr->na_record->r_type, sres_type_naptr);
TEST(rr_naptr->na_record->r_class, sres_class_in);
TEST(rr_naptr->na_record->r_ttl, 60);
TEST(rr_naptr->na_order, 50);
TEST(rr_naptr->na_prefer, 15);
TEST_S(rr_naptr->na_flags, "u");
TEST_S(rr_naptr->na_services, "TEST+D2U");
TEST_S(rr_naptr->na_regexp,
"/(tst:([^@]+@))?example.com$/\\1operator.com/i");
TEST_S(rr_naptr->na_replace, ".");
break;
case 80:
TEST(rr_naptr->na_record->r_type, sres_type_naptr);
TEST(rr_naptr->na_record->r_class, sres_class_in);
TEST(rr_naptr->na_record->r_ttl, 60);
TEST(rr_naptr->na_order, 80);
TEST(rr_naptr->na_prefer, 25);
TEST_S(rr_naptr->na_flags, "s");
TEST_S(rr_naptr->na_services, "SIP+D2T");
TEST_S(rr_naptr->na_regexp, "");
TEST_S(rr_naptr->na_replace, "_sip._tcp.example.com.");
ok |= 4;
break;
default:
TEST_1(0);
}
}
}
TEST(ok, 7);
/* Reverse order before sorting */
for (j = 0; j < --i; j++) {
sres_record_t *swap = result[j];
result[j] = result[i];
result[i] = swap;
}
/* Test sorting */
sres_sort_answers(res, result);
/* Sort all records with themselves */
for (i = 0; result[i]; i++) {
sort_array[0] = result[i], sort_array[1] = result[i], sort_array[2] = NULL;
sres_sort_answers(res, sort_array);
}
/* Test free */
for (i = 0; result[i]; i++) {
sres_free_answer(res, result[i]);
result[i] = NULL;
}
/* Test sres_free_answers() */
sres_free_answers(res, result);
result = sres_cached_answers(res,
sres_qtype_any,
"_sips._tcp.example.com");
TEST_1(result != NULL);
ok = 0;
for (i = 0; result[i] != NULL; i++) {
sres_srv_record_t *rr_srv = result[i]->sr_srv;
TEST(rr_srv->srv_record->r_type, sres_type_srv);
switch(rr_srv->srv_priority) {
case 3:
TEST(rr_srv->srv_record->r_type, sres_type_srv);
TEST(rr_srv->srv_record->r_class, sres_class_in);
TEST(rr_srv->srv_record->r_ttl, 60);
TEST(rr_srv->srv_weight, 100);
TEST(rr_srv->srv_port, 5061);
TEST_S(rr_srv->srv_target, "sip00.example.com.");
ok |= 1;
break;
case 4:
TEST(rr_srv->srv_record->r_type, sres_type_srv);
TEST(rr_srv->srv_record->r_class, sres_class_in);
TEST(rr_srv->srv_record->r_ttl, 60);
TEST(rr_srv->srv_weight, 50);
TEST(rr_srv->srv_port, 5050);
TEST_S(rr_srv->srv_target, "sip02.example.com.");
ok |= 2;
break;
case 5:
TEST(rr_srv->srv_record->r_type, sres_type_srv);
TEST(rr_srv->srv_record->r_class, sres_class_in);
TEST(rr_srv->srv_record->r_ttl, 60);
TEST(rr_srv->srv_weight, 10);
TEST(rr_srv->srv_port, 5060);
TEST_S(rr_srv->srv_target, "sip01.example.com.");
ok |= 4;
break;
default:
TEST_1(0);
}
}
TEST(ok, 7);
/* Reverse order before sorting */
for (j = 0; j < --i; j++) {
sres_record_t *swap = result[j];
result[j] = result[i];
result[i] = swap;
}
sres_sort_answers(res, result);
sres_free_answers(res, result);
domain = "sip.example.com";
result = sres_cached_answers(res,
sres_qtype_any,
domain);
TEST_1(result != NULL);
TEST_1(result[0] != NULL);
rr_cname = result[0]->sr_cname;
TEST(rr_cname->cn_record->r_type, sres_type_cname);
TEST(rr_cname->cn_record->r_class, sres_class_in);
TEST(rr_cname->cn_record->r_ttl, 60);
TEST_S(rr_cname->cn_cname, "sip00.example.com.");
sres_free_answers(res, result);
#if HAVE_SIN6
domain = "subnet.example.com";
result = sres_cached_answers(res,
sres_qtype_any,
domain);
TEST_1(result != NULL);
TEST_1(result[0] != NULL);
rr_a6 = result[0]->sr_a6;
TEST(rr_a6->a6_record->r_type, sres_type_a6);
TEST(rr_a6->a6_record->r_class, sres_class_in);
TEST(rr_a6->a6_record->r_ttl, 60);
TEST(rr_a6->a6_prelen, 0);
TEST_S(su_inet_ntop(AF_INET6, &rr_a6->a6_suffix, buf, sizeof(buf)), "3ff0::");
TEST_P(rr_a6->a6_prename, NULL);
sres_free_answers(res, result);
domain = "mgw02.example.com";
TEST_1(result = sres_cached_answers(res, sres_type_aaaa, domain));
TEST_1(rr_aaaa = result[0]->sr_aaaa);
TEST(rr_aaaa->aaaa_record->r_type, sres_type_aaaa);
TEST(rr_aaaa->aaaa_record->r_class, sres_class_in);
TEST(rr_aaaa->aaaa_record->r_ttl, 60);
TEST_S(su_inet_ntop(AF_INET6, &rr_aaaa->aaaa_addr, buf, sizeof(buf)),
"3ffe:1200:3012:c000:206:5bff:fe55:462f");
sres_free_answers(res, result);
result = sres_cached_answers_sockaddr(res,
sres_type_ptr,
(struct sockaddr *)&sin6);
TEST_1(result != NULL);
rr_ptr = result[0]->sr_ptr;
TEST_1(rr_ptr != NULL);
TEST(rr_ptr->ptr_record->r_type, sres_type_ptr);
TEST(rr_ptr->ptr_record->r_class, sres_class_in);
TEST_S(rr_ptr->ptr_domain, "sip01.example.com.");
sres_free_answers(res, result);
#endif /* HAVE_SIN6 */
END();
}
#if HAVE_SIN6
int test_query_one_type(sres_context_t *ctx)
{
sres_resolver_t *res = ctx->resolver;
sres_record_t **result;
const sres_aaaa_record_t *rr_aaaa;
char buf[50] = {0};
BEGIN();
TEST_1(sres_query(res, test_answer, ctx,
sres_type_aaaa, "mgw02.example.com"));
TEST_RUN(ctx);
TEST_1(result = ctx->result);
TEST_1(result[0] != NULL);
TEST_1(rr_aaaa = result[0]->sr_aaaa);
TEST(rr_aaaa->aaaa_record->r_type, sres_type_aaaa);
TEST(rr_aaaa->aaaa_record->r_class, sres_class_in);
TEST(rr_aaaa->aaaa_record->r_ttl, 60);
TEST_S(su_inet_ntop(AF_INET6, &rr_aaaa->aaaa_addr, buf, sizeof(buf)),
"3ffe:1200:3012:c000:206:5bff:fe55:462f");
TEST_P(result[1], NULL);
END();
}
#endif /* HAVE_SIN6*/
#ifdef _WIN32
#include <fcntl.h>
#endif
int sink_make(sres_context_t *ctx)
{
char *tmpdir = getenv("TMPDIR");
char *template;
int fd;
sres_socket_t sink;
struct sockaddr_in sin[1];
socklen_t sinsize = sizeof sin;
FILE *f;
BEGIN();
sink = socket(AF_INET, SOCK_DGRAM, 0); TEST_1(sink != INVALID_SOCKET);
TEST(getsockname(sink, (struct sockaddr *)sin, &sinsize), 0);
sin->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
TEST(bind(sink, (struct sockaddr *)sin, sinsize), 0);
TEST(getsockname(sink, (struct sockaddr *)sin, &sinsize), 0);
ctx->sink = sink;
template = su_sprintf(ctx->home, "%s/test_sresolv.XXXXXX",
tmpdir ? tmpdir : "/tmp");
TEST_1(template);
#ifndef _WIN32
fd = mkstemp(template); TEST_1(fd != -1);
#else
fd = open(template, O_WRONLY); TEST_1(fd != -1);
#endif
f = fdopen(fd, "w"); TEST_1(f);
fprintf(f,
"domain example.com\n"
"search foo.bar.com\n"
"port %u\n",
ntohs(sin->sin_port));
fclose(f);
ctx->sinkconf = template;
END();
}
#if 0
int recv_sink(su_root_magic_t *rm, su_wait_t *w, sres_context_t *ctx)
{
union {
char bytes[8192];
unsigned short shorts[4096];
} buffer[1];
su_wait_events(w, ctx->sink);
recv(ctx->sink, buffer->bytes, sizeof buffer, 0);
return 0;
}
int sink_init(sres_context_t *ctx)
{
su_wait_t w[1];
BEGIN();
TEST(su_wait_create(w, ctx->sink, SU_WAIT_IN), 0);
ctx->sinkidx = su_root_register(ctx->root, w, recv_sink, ctx, 0);
TEST_1(ctx->sinkidx != 0);
END();
}
int sink_deinit(sres_context_t *ctx)
{
BEGIN();
if (ctx->sinkidx)
su_root_deregister(ctx->root, ctx->sinkidx);
ctx->sinkidx = 0;
sres_close(ctx->sink), ctx->sink = INVALID_SOCKET;
END();
}
#endif
int test_timeout(sres_context_t *ctx)
{
sres_resolver_t *res = ctx->resolver;
sres_record_t **result;
/* const sres_soa_record_t *rr_soa; */
char const *domain = "test";
BEGIN();
sres_query(res, test_answer, ctx, sres_type_a, domain);
ctx->timeout = 1;
TEST_RUN(ctx);
ctx->timeout = 0;
TEST_P(ctx->result, NULL);
result = sres_cached_answers(res, sres_type_a, domain);
#if 0 /* Currently, we do not create error records */
TEST_1(result); TEST_1(result[0] != NULL);
rr_soa = result[0]->sr_soa;
TEST(rr_soa->soa_record->r_type, sres_type_soa);
TEST(rr_soa->soa_record->r_class, sres_class_in);
TEST_S(rr_soa->soa_record->r_name, "example.com.");
TEST(rr_soa->soa_record->r_status, SRES_TIMEOUT_ERR);
sres_free_answers(res, result);
#else
TEST_1(result == NULL);
#endif
END();
}
static void test_answer(sres_context_t *ctx,
sres_query_t *q,
sres_record_t **answer)
{
ctx->query = q;
if (ctx->result)
sres_free_answers(ctx->resolver, ctx->result);
ctx->result = answer;
BREAK(ctx);
}
static void test_answer_multi(sres_context_t *ctx,
sres_query_t *q,
sres_record_t **answer)
{
static int count = 0;
ctx->query = q;
count++;
sres_free_answers(ctx->resolver, answer);
if (count == 6)
BREAK(ctx);
}
#include <sys/time.h>
/* Fake time() implementation, used by sresolv library */
time_t time(time_t *tp)
{
struct timeval tv[1];
#ifndef _WIN32
gettimeofday(tv, NULL);
#else
return 0;
#endif
if (tp)
*tp = tv->tv_sec + offset;
return tv->tv_sec + offset;
}
int test_expiration(sres_context_t *ctx)
{
sres_resolver_t *res = ctx->resolver;
sres_record_t **result;
char const *domain = "example.com";
BEGIN();
offset = 3600; /* Time suddenly proceeds by an hour.. */
sres_resolver_timer(res, -1);
result = sres_cached_answers(res, sres_qtype_any, domain);
TEST_P(result, NULL); /* the cache should be empty after 15 secs */
END();
}
#define is_hexdigit(c) ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f'))
#define hex(c) ((c >= '0' && c <= '9') ? (c - '0') : (c - 'a' + 10))
/* Convert lowercase hex to binary */
static
void *hex2bin(char const *test_name,
char const *hex1, char const *hex2, size_t *binsize)
{
char output[2048];
char *bin;
char const *b;
size_t j;
if (hex1 == NULL || binsize == NULL)
return NULL;
for (b = hex1, j = 0; b;) {
while (b[0]) {
if (is_hexdigit(b[0])) {
if (!is_hexdigit(b[1])) {
fprintf(stderr, "%s: hex2bin: invalid hex '%c'\n", test_name, b[1]);
exit(2);
}
output[j++] = (hex(b[0]) << 4) | hex(b[1]);
if (j == sizeof(output)) {
fprintf(stderr, "%s:%u: hex2bin: buffer too small\n",
__FILE__, __LINE__);
exit(2);
}
b++;
} else if (b[0] != ' ') {
fprintf(stderr, "%s: hex2bin: invalid nonhex '%c'\n", test_name,
b[0]);
exit(2);
}
b++;
}
b = hex2, hex2 = NULL;
}
bin = malloc(j);
if (bin == NULL)
perror("malloc"), exit(2);
return memcpy(bin, output, *binsize = j);
}
static char const hextest[] =
" 34 44 85 80 00 01 00 04 "
"00 01 00 08 07 65 78 61 6d 70 6c 65 03 63 6f 6d "
"00 00 23 00 01 c0 0c 00 23 00 01 00 00 00 3c 00 "
"26 00 28 00 0f 01 73 07 53 49 50 2b 44 32 55 00 "
"04 5f 73 69 70 04 5f 75 64 70 07 65 78 61 6d 70 "
"6c 65 03 63 6f 6d 00 c0 42 00 23 00 01 00 00 00 "
"3c 00 3e 00 32 00 0f 01 75 08 54 45 53 54 2b 44 "
"32 55 2d 2f 28 74 73 74 3a 28 5b 5e 40 5d 2b 40 "
"29 29 3f 65 78 61 6d 70 6c 65 2e 63 6f 6d 24 2f "
"5c 31 6f 70 65 72 61 74 6f 72 2e 63 6f 6d 2f 69 "
"00 c0 42 00 23 00 01 00 00 00 3c 00 26 00 50 00 "
"19 01 73 07 53 49 50 2b 44 32 54 00 04 5f 73 69 "
"70 04 5f 74 63 70 07 65 78 61 6d 70 6c 65 03 63 "
"6f 6d 00 c0 be 00 23 00 01 00 00 00 3c 00 28 00 "
"14 00 32 01 73 08 53 49 50 53 2b 44 32 54 00 05 "
"5f 73 69 70 73 04 5f 74 63 70 07 65 78 61 6d 70 "
"6c 65 03 63 6f 6d 00 c0 f2 00 02 00 01 00 00 00 "
"3c 00 05 02 6e 73 c0 f2 05 73 69 70 30 30 c0 f2 "
"00 01 00 01 00 00 00 3c 00 04 c2 02 bc 85 c1 10 "
"00 1c 00 01 00 00 00 3c 00 10 3f f0 00 10 30 12 "
"c0 00 02 c0 95 ff fe e2 4b 78 05 73 69 70 30 32 "
"c0 f2 00 01 00 01 00 00 00 3c 00 04 c2 02 bc 87 "
"c1 42 00 1c 00 01 00 00 00 3c 00 10 3f fe 12 00 "
"30 12 c0 06 02 06 5b ff fe 55 46 2f 05 73 69 70 "
"30 31 c0 f2 00 01 00 01 00 00 00 3c 00 04 c2 02 "
"bc 86 c1 74 00 1c 00 01 00 00 00 3c 00 10 3f f0 "
"00 12 30 12 c0 06 0a 08 20 ff fe 7d e7 ac c1 0b "
"00 01 00 01 00 00 00 3c 00 04 c2 02 bc 85 c1 0b "
"00 26 00 01 00 00 00 3c 00 11 00 3f fe 12 00 30 "
"12 c0 00 02 10 a4 ff fe 8d 6a 46 ";
int test_net(sres_context_t *ctx)
{
sres_resolver_t *res = ctx->resolver;
sres_query_t *q = NULL;
sres_socket_t c = ctx->sink;
struct sockaddr_storage ss[1];
struct sockaddr *sa = (void *)ss;
socklen_t salen = sizeof ss;
char *bin;
size_t i, binlen;
ssize_t n;
char const *domain = "example.com";
char query[512];
BEGIN();
TEST_1(ctx->sink != INVALID_SOCKET && ctx->sink != (sres_socket_t)0);
/* Prepare for test_answer() callback */
sres_free_answers(ctx->resolver, ctx->result);
ctx->result = NULL;
ctx->query = NULL;
/* Get canned response */
TEST_1(bin = hex2bin(__func__, hextest, NULL, &binlen));
/* Send responses with one erroneus byte */
for (i = 1; i < binlen; i++) {
if (!q) {
/* We got an error => make new query */
TEST_1(q = sres_query(res, test_answer, ctx, /* Send query */
sres_type_naptr, domain));
TEST_1((n = sres_recvfrom(c, query, sizeof query, 0, sa, &salen)) != -1);
memcpy(bin, query, 2); /* Copy ID */
}
if (i != 1)
bin[i] ^= 0xff;
else
bin[3] ^= SRES_FORMAT_ERR; /* format error -> EDNS0 failure */
n = sres_sendto(c, bin, binlen, 0, sa, salen);
if (i != 1)
bin[i] ^= 0xff;
else
bin[3] ^= SRES_FORMAT_ERR;
if (n == -1)
perror("sendto");
while (!poll_sockets(ctx))
;
if (ctx->query)
q = NULL;
}
/* Send runt responses */
for (i = 1; i <= binlen; i++) {
if (!q) {
/* We got an error => make new query */
TEST_1(q = sres_query(res, test_answer, ctx, /* Send query */
sres_type_naptr, domain));
TEST_1((n = sres_recvfrom(c, query, sizeof query, 0, sa, &salen)) != -1);
memcpy(bin, query, 2); /* Copy ID */
}
n = sres_sendto(c, bin, i, 0, sa, salen);
if (n == -1)
perror("sendto");
while (!poll_sockets(ctx))
;
if (ctx->query)
q = NULL;
}
free(bin);
END();
}
static
int test_init(sres_context_t *ctx, char const *conf_file)
{
BEGIN();
sres_resolver_t *res;
int i, n;
ctx->query = NULL, ctx->result = NULL;
TEST_1(ctx->resolver = res = sres_resolver_new(conf_file));
TEST(su_home_threadsafe((su_home_t *)ctx->resolver), 0);
n = sres_resolver_sockets(res, NULL, 0);
ctx->n_sockets = n;
TEST_1(n < SRES_MAX_NAMESERVERS);
TEST(sres_resolver_sockets(res, ctx->sockets, n), n);
for (i = 0; i < n; i++) {
ctx->fds[i].fd = ctx->sockets[i];
ctx->fds[i].events = POLLIN | POLLERR;
}
TEST_P(sres_resolver_ref(ctx->resolver), ctx->resolver);
sres_resolver_unref(ctx->resolver);
END();
}
static
int test_deinit(sres_context_t *ctx)
{
offset += 2 * 36000000;
sres_resolver_timer(ctx->resolver, -1); /* Zap everything */
sres_free_answers(ctx->resolver, ctx->result); ctx->result = NULL;
su_free(ctx->home, (void *)ctx->sinkconf); ctx->sinkconf = NULL;
sres_resolver_unref(ctx->resolver); ctx->resolver = NULL;
offset = 0;
memset(ctx, 0, sizeof ctx);
ctx->home->suh_size = sizeof ctx;
return 0;
}
static
int test_conf_errors(sres_context_t *ctx, char const *conf_file)
{
sres_resolver_t *res;
sres_socket_t socket;
int n;
BEGIN();
TEST_1(res = sres_resolver_new(conf_file));
n = sres_resolver_sockets(res, NULL, 0);
TEST_1(n > 0);
TEST(sres_resolver_sockets(res, &socket, 1), n);
#if !__linux
/* We fail this test in most systems */
/* conf_file looks like this:
--8<--8<--8<--8<--8<--8<--8<--8<--8<--8<--8<--8<--
nameserver 0.0.0.2
nameserver 1.1.1.1.1
search example.com
port $port
-->8-->8-->8-->8-->8-->8-->8-->8-->8-->8-->8-->8--
*/
printf("%s:%u: %s test should be updated\n",
__FILE__, __LINE__, __func__);
#else
TEST_P(sres_query(res, test_answer, ctx, sres_type_a, "example.com"), NULL);
#endif
sres_resolver_unref(res);
END();
}
void
fill_stack(void)
{
int i,array[32768];
for (i = 0; i < 32768; i++)
array[i] = i ^ 0xdeadbeef;
}
#if HAVE_ALARM
static RETSIGTYPE sig_alarm(int s)
{
fprintf(stderr, "%s: FAIL! test timeout!\n", name);
exit(1);
}
#endif
void usage(int exitcode)
{
fprintf(stderr,
"usage: %s OPTIONS [-] [conf-file] [error-conf-file]\n"
"\twhere OPTIONS are\n"
"\t -v be verbose\n"
"\t -a abort on error\n"
"\t -l level\n",
name);
exit(exitcode);
}
int main(int argc, char **argv)
{
int i;
int error = 0;
int o_attach = 0, o_alarm = 1;
sres_context_t ctx[1] = {{{SU_HOME_INIT(ctx)}}};
for (i = 1; argv[i]; i++) {
if (argv[i][0] != '-')
break;
else if (strcmp(argv[i], "-") == 0) {
i++; break;
}
else if (strcmp(argv[i], "-v") == 0)
tstflags |= tst_verbatim;
else if (strcmp(argv[i], "-a") == 0)
tstflags |= tst_abort;
else if (strcmp(argv[i], "--no-alarm") == 0) {
o_alarm = 0;
}
else if (strcmp(argv[i], "--attach") == 0) {
o_attach = 1;
}
else if (strncmp(argv[i], "-l", 2) == 0) {
int level = 3;
char *rest = NULL;
if (argv[i][2])
level = strtol(argv[i] + 2, &rest, 10);
else if (argv[i + 1])
level = strtol(argv[i + 1], &rest, 10), i++;
else
level = 3, rest = "";
if (rest == NULL || *rest)
usage(1);
su_log_set_level(sresolv_log, level);
} else
usage(1);
}
if (o_attach) {
char buf[8], *line;
fprintf(stderr, "test_sresolv: started with pid %u"
" (press enter to continue)\n", getpid());
line = fgets(buf, sizeof buf, stdin); (void) line;
}
#if HAVE_ALARM
else if (o_alarm) {
alarm(60);
signal(SIGALRM, sig_alarm);
}
#endif
if (!(TSTFLAGS & tst_verbatim)) {
su_log_soft_set_level(sresolv_log, 0);
}
#if 0
if (sink_make(ctx) == 0)
{
error |= test_init(ctx, ctx->sinkconf);
error |= sink_init(ctx);
error |= test_net(ctx);
error |= test_timeout(ctx);
error |= sink_deinit(ctx);
error |= test_deinit(ctx);
}
#endif
offset = 0;
if (argv[i]) {
/* These tests are run with (local) nameserver,
*/
int initerror = test_init(ctx, argv[i]);
if (!initerror) {
error |= test_a(ctx);
error |= test_soa(ctx);
error |= test_naptr(ctx);
#if HAVE_SIN6
error |= test_a6(ctx);
error |= test_a6_prefix(ctx);
error |= test_aaaa(ctx);
#endif
error |= test_srv(ctx);
error |= test_cname(ctx);
error |= test_ptr_ipv4(ctx);
error |= test_ptr_ipv4_sockaddr(ctx);
#if HAVE_SIN6
error |= test_ptr_ipv6(ctx);
error |= test_ptr_ipv6_sockaddr(ctx);
#endif
error |= test_cache(ctx);
#if HAVE_SIN6
error |= test_query_one_type(ctx);
#endif
error |= test_expiration(ctx);
}
error |= test_deinit(ctx) | initerror;
if (argv[i + 1]) {
error |= test_conf_errors(ctx, argv[i + 1]);
}
}
return error;
}
#else /* HAVE_POLL */
int main(int argc, char **argv)
{
printf("*** Test not supported without POLL API ***\n");
return 0;
}
#endif /* HAVE_POLL */