📄 test_sresolv.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>#endifchar 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_inlineint 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#endifSOFIAPUBFUN 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 && 0staticint 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 */staticint 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();}#endifstatic 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); }staticint 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."
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -