forked from Mirrors/freeswitch
Tue Feb 10 07:17:20 CST 2009 Pekka Pessi <first.last@nokia.com>
* check_nua: moved s2_fast_forward() to s2 library git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@11879 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
8d3480b06a
commit
0c141d9b81
@ -52,7 +52,10 @@ check_nua_SOURCES = check_nua.c check_nua.h \
|
|||||||
check_etsi.c check_simple.c \
|
check_etsi.c check_simple.c \
|
||||||
test_s2.h test_s2.c
|
test_s2.h test_s2.c
|
||||||
|
|
||||||
check_nua_LDADD = $(nua_libs) @CHECK_LIBS@
|
check_nua_LDADD = $(nua_libs) ${top_builddir}/s2check/libs2.a \
|
||||||
|
@CHECK_LIBS@
|
||||||
|
|
||||||
|
check_nua_CFLAGS = $(CFLAGS) -I$(top_srcdir)/s2check
|
||||||
|
|
||||||
nua_libs = libnua.la \
|
nua_libs = libnua.la \
|
||||||
../iptsec/libiptsec.la \
|
../iptsec/libiptsec.la \
|
||||||
|
@ -244,22 +244,22 @@ START_TEST(SIP_CC_OE_CE_TI_008)
|
|||||||
fail_unless(s2_check_callstate(nua_callstate_terminated));
|
fail_unless(s2_check_callstate(nua_callstate_terminated));
|
||||||
fail_unless(s2_check_request(SIP_METHOD_ACK));
|
fail_unless(s2_check_request(SIP_METHOD_ACK));
|
||||||
|
|
||||||
s2_fast_forward(5);
|
s2_fast_forward(5, s2->root);;
|
||||||
|
|
||||||
s2_respond_to(invite, d1, SIP_404_NOT_FOUND, TAG_END());
|
s2_respond_to(invite, d1, SIP_404_NOT_FOUND, TAG_END());
|
||||||
fail_unless(s2_check_request(SIP_METHOD_ACK));
|
fail_unless(s2_check_request(SIP_METHOD_ACK));
|
||||||
|
|
||||||
s2_fast_forward(5);
|
s2_fast_forward(5, s2->root);;
|
||||||
|
|
||||||
s2_respond_to(invite, d1, SIP_404_NOT_FOUND, TAG_END());
|
s2_respond_to(invite, d1, SIP_404_NOT_FOUND, TAG_END());
|
||||||
fail_unless(s2_check_request(SIP_METHOD_ACK));
|
fail_unless(s2_check_request(SIP_METHOD_ACK));
|
||||||
|
|
||||||
s2_fast_forward(21);
|
s2_fast_forward(21, s2->root);;
|
||||||
|
|
||||||
s2_respond_to(invite, d1, SIP_404_NOT_FOUND, TAG_END());
|
s2_respond_to(invite, d1, SIP_404_NOT_FOUND, TAG_END());
|
||||||
fail_unless(s2_check_request(SIP_METHOD_ACK));
|
fail_unless(s2_check_request(SIP_METHOD_ACK));
|
||||||
|
|
||||||
s2_fast_forward(1);
|
s2_fast_forward(1, s2->root);;
|
||||||
|
|
||||||
s2_respond_to(invite, d1, SIP_404_NOT_FOUND, TAG_END());
|
s2_respond_to(invite, d1, SIP_404_NOT_FOUND, TAG_END());
|
||||||
s2_free_message(invite);
|
s2_free_message(invite);
|
||||||
@ -294,19 +294,19 @@ START_TEST(SIP_CC_OE_CE_TI_011_012)
|
|||||||
fail_unless(s2_check_callstate(nua_callstate_ready));
|
fail_unless(s2_check_callstate(nua_callstate_ready));
|
||||||
fail_unless(s2_check_request(SIP_METHOD_ACK));
|
fail_unless(s2_check_request(SIP_METHOD_ACK));
|
||||||
|
|
||||||
s2_fast_forward(5);
|
s2_fast_forward(5, s2->root);;
|
||||||
respond_with_sdp(invite, d1, SIP_200_OK, TAG_END());
|
respond_with_sdp(invite, d1, SIP_200_OK, TAG_END());
|
||||||
fail_unless(s2_check_request(SIP_METHOD_ACK));
|
fail_unless(s2_check_request(SIP_METHOD_ACK));
|
||||||
|
|
||||||
s2_fast_forward(5);
|
s2_fast_forward(5, s2->root);;
|
||||||
respond_with_sdp(invite, d1, SIP_200_OK, TAG_END());
|
respond_with_sdp(invite, d1, SIP_200_OK, TAG_END());
|
||||||
fail_unless(s2_check_request(SIP_METHOD_ACK));
|
fail_unless(s2_check_request(SIP_METHOD_ACK));
|
||||||
|
|
||||||
s2_fast_forward(21);
|
s2_fast_forward(21, s2->root);;
|
||||||
respond_with_sdp(invite, d1, SIP_200_OK, TAG_END());
|
respond_with_sdp(invite, d1, SIP_200_OK, TAG_END());
|
||||||
fail_unless(s2_check_request(SIP_METHOD_ACK));
|
fail_unless(s2_check_request(SIP_METHOD_ACK));
|
||||||
|
|
||||||
s2_fast_forward(1);
|
s2_fast_forward(1, s2->root);;
|
||||||
respond_with_sdp(invite, d1, SIP_200_OK, TAG_END());
|
respond_with_sdp(invite, d1, SIP_200_OK, TAG_END());
|
||||||
s2_free_message(invite);
|
s2_free_message(invite);
|
||||||
fail_if(s2_check_request_timeout(SIP_METHOD_ACK, 500));
|
fail_if(s2_check_request_timeout(SIP_METHOD_ACK, 500));
|
||||||
|
@ -335,7 +335,7 @@ START_TEST(register_1_2_2_2)
|
|||||||
s2_free_message(m);
|
s2_free_message(m);
|
||||||
|
|
||||||
su_root_step(s2->root, 20); su_root_step(s2->root, 20);
|
su_root_step(s2->root, 20); su_root_step(s2->root, 20);
|
||||||
s2_fast_forward(120); /* Default keepalive interval */
|
s2_fast_forward(120, s2->root);; /* Default keepalive interval */
|
||||||
mark_point();
|
mark_point();
|
||||||
|
|
||||||
m = s2_wait_for_request(SIP_METHOD_OPTIONS);
|
m = s2_wait_for_request(SIP_METHOD_OPTIONS);
|
||||||
@ -346,7 +346,7 @@ START_TEST(register_1_2_2_2)
|
|||||||
s2_free_message(m);
|
s2_free_message(m);
|
||||||
|
|
||||||
su_root_step(s2->root, 20); su_root_step(s2->root, 20);
|
su_root_step(s2->root, 20); su_root_step(s2->root, 20);
|
||||||
s2_fast_forward(120); /* Default keepalive interval */
|
s2_fast_forward(120, s2->root);; /* Default keepalive interval */
|
||||||
mark_point();
|
mark_point();
|
||||||
|
|
||||||
receive_natted = "received=4.255.255.10";
|
receive_natted = "received=4.255.255.10";
|
||||||
@ -400,7 +400,7 @@ START_TEST(register_1_2_2_3)
|
|||||||
|
|
||||||
receive_natted = "received=4.255.255.10";
|
receive_natted = "received=4.255.255.10";
|
||||||
|
|
||||||
s2_fast_forward(3600);
|
s2_fast_forward(3600, s2->root);;
|
||||||
mark_point();
|
mark_point();
|
||||||
|
|
||||||
m = s2_wait_for_request(SIP_METHOD_REGISTER);
|
m = s2_wait_for_request(SIP_METHOD_REGISTER);
|
||||||
@ -637,7 +637,7 @@ START_TEST(register_1_3_3_1)
|
|||||||
if (!tport_is_udp(m->tport)) /* Drop UDP */
|
if (!tport_is_udp(m->tport)) /* Drop UDP */
|
||||||
break;
|
break;
|
||||||
s2_free_message(m);
|
s2_free_message(m);
|
||||||
s2_fast_forward(4);
|
s2_fast_forward(4, s2->root);;
|
||||||
}
|
}
|
||||||
|
|
||||||
tcp = tport_ref(m->tport);
|
tcp = tport_ref(m->tport);
|
||||||
@ -695,7 +695,7 @@ START_TEST(register_1_3_3_1)
|
|||||||
su_root_step(s2->root, 5);
|
su_root_step(s2->root, 5);
|
||||||
su_root_step(s2->root, 5);
|
su_root_step(s2->root, 5);
|
||||||
su_root_step(s2->root, 5);
|
su_root_step(s2->root, 5);
|
||||||
s2_fast_forward(5);
|
s2_fast_forward(5, s2->root);;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1054,11 +1054,11 @@ START_TEST(call_2_3_1)
|
|||||||
SIPTAG_REQUIRE_STR("timer"),
|
SIPTAG_REQUIRE_STR("timer"),
|
||||||
TAG_END());
|
TAG_END());
|
||||||
|
|
||||||
s2_fast_forward(300);
|
s2_fast_forward(300, s2->root);;
|
||||||
ack = invite_timer_round(nh, "300;refresher=uac", rr);
|
ack = invite_timer_round(nh, "300;refresher=uac", rr);
|
||||||
fail_if(ack->sip->sip_route &&
|
fail_if(ack->sip->sip_route &&
|
||||||
su_strmatch(ack->sip->sip_route->r_url->url_user, "record"));
|
su_strmatch(ack->sip->sip_route->r_url->url_user, "record"));
|
||||||
s2_fast_forward(300);
|
s2_fast_forward(300, s2->root);;
|
||||||
invite_timer_round(nh, "300;refresher=uac", NULL);
|
invite_timer_round(nh, "300;refresher=uac", NULL);
|
||||||
|
|
||||||
bye_by_nua(nh, TAG_END());
|
bye_by_nua(nh, TAG_END());
|
||||||
@ -1082,9 +1082,9 @@ START_TEST(call_2_3_2)
|
|||||||
SIPTAG_REQUIRE_STR("timer"),
|
SIPTAG_REQUIRE_STR("timer"),
|
||||||
TAG_END());
|
TAG_END());
|
||||||
|
|
||||||
s2_fast_forward(300);
|
s2_fast_forward(300, s2->root);;
|
||||||
invite_timer_round(nh, "300", NULL);
|
invite_timer_round(nh, "300", NULL);
|
||||||
s2_fast_forward(300);
|
s2_fast_forward(300, s2->root);;
|
||||||
invite_timer_round(nh, "300", NULL);
|
invite_timer_round(nh, "300", NULL);
|
||||||
|
|
||||||
bye_by_nua(nh, TAG_END());
|
bye_by_nua(nh, TAG_END());
|
||||||
@ -1551,7 +1551,7 @@ START_TEST(call_2_6_2)
|
|||||||
/* We get nua_r_invite with 100 trying (and 500 in sip->sip_status) */
|
/* We get nua_r_invite with 100 trying (and 500 in sip->sip_status) */
|
||||||
fail_unless(s2_check_event(nua_r_invite, 100));
|
fail_unless(s2_check_event(nua_r_invite, 100));
|
||||||
|
|
||||||
s2_fast_forward(10);
|
s2_fast_forward(10, s2->root);;
|
||||||
|
|
||||||
fail_unless(s2_check_callstate(nua_callstate_calling));
|
fail_unless(s2_check_callstate(nua_callstate_calling));
|
||||||
|
|
||||||
@ -1605,7 +1605,7 @@ START_TEST(call_2_6_3)
|
|||||||
fail_unless(s2_check_event(nua_i_ack, 200));
|
fail_unless(s2_check_event(nua_i_ack, 200));
|
||||||
fail_unless(s2_check_callstate(nua_callstate_ready));
|
fail_unless(s2_check_callstate(nua_callstate_ready));
|
||||||
|
|
||||||
s2_fast_forward(10);
|
s2_fast_forward(10, s2->root);;
|
||||||
|
|
||||||
nua_set_hparams(nh, NUTAG_REFRESH_WITHOUT_SDP(1), TAG_END());
|
nua_set_hparams(nh, NUTAG_REFRESH_WITHOUT_SDP(1), TAG_END());
|
||||||
fail_unless(s2_check_event(nua_r_set_params, 200));
|
fail_unless(s2_check_event(nua_r_set_params, 200));
|
||||||
@ -1752,7 +1752,7 @@ START_TEST(call_3_1_2)
|
|||||||
if (i == 3)
|
if (i == 3)
|
||||||
break;
|
break;
|
||||||
fail_unless(s2_check_event(nua_r_invite, 100));
|
fail_unless(s2_check_event(nua_r_invite, 100));
|
||||||
s2_fast_forward(5);
|
s2_fast_forward(5, s2->root);;
|
||||||
}
|
}
|
||||||
|
|
||||||
fail_unless(s2_check_event(nua_r_invite, 500));
|
fail_unless(s2_check_event(nua_r_invite, 500));
|
||||||
@ -1822,7 +1822,7 @@ START_TEST(call_3_2_2)
|
|||||||
if (i == 3)
|
if (i == 3)
|
||||||
break;
|
break;
|
||||||
fail_unless(s2_check_event(nua_r_invite, 100));
|
fail_unless(s2_check_event(nua_r_invite, 100));
|
||||||
s2_fast_forward(5);
|
s2_fast_forward(5, s2->root);;
|
||||||
}
|
}
|
||||||
|
|
||||||
fail_unless(s2_check_event(nua_r_invite, 500));
|
fail_unless(s2_check_event(nua_r_invite, 500));
|
||||||
@ -2344,7 +2344,7 @@ START_TEST(bye_4_2_1)
|
|||||||
SIPTAG_REQUIRE_STR("timer"),
|
SIPTAG_REQUIRE_STR("timer"),
|
||||||
TAG_END());
|
TAG_END());
|
||||||
|
|
||||||
s2_fast_forward(300);
|
s2_fast_forward(300, s2->root);;
|
||||||
invite_timer_round(nh, "300", NULL);
|
invite_timer_round(nh, "300", NULL);
|
||||||
|
|
||||||
nua_bye(nh, TAG_END());
|
nua_bye(nh, TAG_END());
|
||||||
@ -2357,7 +2357,7 @@ START_TEST(bye_4_2_1)
|
|||||||
s2_free_message(bye);
|
s2_free_message(bye);
|
||||||
fail_unless(s2_check_event(nua_r_bye, 407));
|
fail_unless(s2_check_event(nua_r_bye, 407));
|
||||||
|
|
||||||
s2_fast_forward(300);
|
s2_fast_forward(300, s2->root);;
|
||||||
|
|
||||||
nua_authenticate(nh, NUTAG_AUTH("Digest:\"s2test\":abc:abc"), TAG_END());
|
nua_authenticate(nh, NUTAG_AUTH("Digest:\"s2test\":abc:abc"), TAG_END());
|
||||||
bye = s2_wait_for_request(SIP_METHOD_BYE);
|
bye = s2_wait_for_request(SIP_METHOD_BYE);
|
||||||
@ -2388,10 +2388,10 @@ START_TEST(bye_4_2_2)
|
|||||||
SIPTAG_REQUIRE_STR("timer"),
|
SIPTAG_REQUIRE_STR("timer"),
|
||||||
TAG_END());
|
TAG_END());
|
||||||
|
|
||||||
s2_fast_forward(300);
|
s2_fast_forward(300, s2->root);;
|
||||||
invite_timer_round(nh, "300", NULL);
|
invite_timer_round(nh, "300", NULL);
|
||||||
|
|
||||||
s2_fast_forward(140);
|
s2_fast_forward(140, s2->root);;
|
||||||
|
|
||||||
nua_bye(nh, TAG_END());
|
nua_bye(nh, TAG_END());
|
||||||
|
|
||||||
@ -2403,7 +2403,7 @@ START_TEST(bye_4_2_2)
|
|||||||
s2_free_message(bye);
|
s2_free_message(bye);
|
||||||
fail_unless(s2_check_event(nua_r_bye, 407));
|
fail_unless(s2_check_event(nua_r_bye, 407));
|
||||||
|
|
||||||
s2_fast_forward(160);
|
s2_fast_forward(160, s2->root);;
|
||||||
|
|
||||||
nua_authenticate(nh, NUTAG_AUTH(s2_auth_credentials), TAG_END());
|
nua_authenticate(nh, NUTAG_AUTH(s2_auth_credentials), TAG_END());
|
||||||
bye = s2_wait_for_request(SIP_METHOD_BYE);
|
bye = s2_wait_for_request(SIP_METHOD_BYE);
|
||||||
|
@ -290,7 +290,7 @@ START_TEST(subscribe_6_1_2)
|
|||||||
s2_free_event(notify);
|
s2_free_event(notify);
|
||||||
|
|
||||||
/* Wait for refresh */
|
/* Wait for refresh */
|
||||||
s2_fast_forward(600);
|
s2_fast_forward(600, s2->root);;
|
||||||
subscribe = s2_wait_for_request(SIP_METHOD_SUBSCRIBE);
|
subscribe = s2_wait_for_request(SIP_METHOD_SUBSCRIBE);
|
||||||
s2_respond_to(subscribe, dialog, SIP_200_OK,
|
s2_respond_to(subscribe, dialog, SIP_200_OK,
|
||||||
SIPTAG_EXPIRES_STR("600"),
|
SIPTAG_EXPIRES_STR("600"),
|
||||||
@ -377,7 +377,7 @@ START_TEST(subscribe_6_1_4)
|
|||||||
|
|
||||||
su_home_unref((void *)dialog), dialog = su_home_new(sizeof *dialog); fail_if(!dialog);
|
su_home_unref((void *)dialog), dialog = su_home_new(sizeof *dialog); fail_if(!dialog);
|
||||||
|
|
||||||
s2_fast_forward(5);
|
s2_fast_forward(5, s2->root);;
|
||||||
/* nua re-establishes the subscription */
|
/* nua re-establishes the subscription */
|
||||||
notify = subscription_by_nua(nh, nua_substate_embryonic, TAG_END());
|
notify = subscription_by_nua(nh, nua_substate_embryonic, TAG_END());
|
||||||
s2_free_event(notify);
|
s2_free_event(notify);
|
||||||
@ -460,7 +460,7 @@ START_TEST(fetch_6_2_3)
|
|||||||
fail_unless(s2_check_substate(event, nua_substate_embryonic));
|
fail_unless(s2_check_substate(event, nua_substate_embryonic));
|
||||||
s2_free_event(event);
|
s2_free_event(event);
|
||||||
|
|
||||||
s2_fast_forward(600);
|
s2_fast_forward(600, s2->root);;
|
||||||
|
|
||||||
event = s2_wait_for_event(nua_i_notify, 408); fail_if(!event);
|
event = s2_wait_for_event(nua_i_notify, 408); fail_if(!event);
|
||||||
fail_unless(s2_check_substate(event, nua_substate_terminated));
|
fail_unless(s2_check_substate(event, nua_substate_terminated));
|
||||||
|
@ -108,27 +108,6 @@ char const s2_auth3_credentials[] = "Digest:\"s2test3\":abc:abc";
|
|||||||
|
|
||||||
int s2_nua_thread = 0;
|
int s2_nua_thread = 0;
|
||||||
|
|
||||||
/* -- Delay scenarios --------------------------------------------------- */
|
|
||||||
|
|
||||||
static unsigned long time_offset;
|
|
||||||
|
|
||||||
extern void (*_su_time)(su_time_t *tv);
|
|
||||||
|
|
||||||
static void _su_time_fast_forwarder(su_time_t *tv)
|
|
||||||
{
|
|
||||||
tv->tv_sec += time_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
void s2_fast_forward(unsigned long seconds)
|
|
||||||
{
|
|
||||||
if (_su_time == NULL)
|
|
||||||
_su_time = _su_time_fast_forwarder;
|
|
||||||
|
|
||||||
time_offset += seconds;
|
|
||||||
|
|
||||||
su_root_step(s2->root, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -- NUA events -------------------------------------------------------- */
|
/* -- NUA events -------------------------------------------------------- */
|
||||||
|
|
||||||
struct event *s2_remove_event(struct event *e)
|
struct event *s2_remove_event(struct event *e)
|
||||||
|
@ -32,6 +32,8 @@
|
|||||||
#include <sofia-sip/tport.h>
|
#include <sofia-sip/tport.h>
|
||||||
#include <sofia-sip/nua.h>
|
#include <sofia-sip/nua.h>
|
||||||
|
|
||||||
|
#include "s2util.h"
|
||||||
|
|
||||||
struct tester
|
struct tester
|
||||||
{
|
{
|
||||||
su_home_t home[1];
|
su_home_t home[1];
|
||||||
@ -119,8 +121,6 @@ extern char const s2_auth3_credentials[];
|
|||||||
|
|
||||||
extern int s2_nua_thread;
|
extern int s2_nua_thread;
|
||||||
|
|
||||||
void s2_fast_forward(unsigned long seconds);
|
|
||||||
|
|
||||||
void s2_case(char const *tag,
|
void s2_case(char const *tag,
|
||||||
char const *title,
|
char const *title,
|
||||||
char const *description);
|
char const *description);
|
||||||
|
636
libs/sofia-sip/s2check/s2dns.c
Normal file
636
libs/sofia-sip/s2check/s2dns.c
Normal file
@ -0,0 +1,636 @@
|
|||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
/* S2 DNS server */
|
||||||
|
|
||||||
|
#include <sofia-sip/sresolv.h>
|
||||||
|
#include <sofia-resolv/sres_record.h>
|
||||||
|
#include <sofia-sip/url.h>
|
||||||
|
|
||||||
|
#include "s2dns.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
extern uint16_t _sres_default_port; /* Ugly hack */
|
||||||
|
|
||||||
|
static struct s2dns {
|
||||||
|
su_root_t *root;
|
||||||
|
su_socket_t socket;
|
||||||
|
su_wait_t wait[1];
|
||||||
|
int reg;
|
||||||
|
} s2dns;
|
||||||
|
|
||||||
|
static
|
||||||
|
struct s2_dns_response {
|
||||||
|
struct s2_dns_response *next;
|
||||||
|
uint16_t qlen, dlen;
|
||||||
|
struct m_header {
|
||||||
|
/* Header defined in RFC 1035 section 4.1.1 (page 26) */
|
||||||
|
uint16_t mh_id; /* Query ID */
|
||||||
|
uint16_t mh_flags; /* Flags */
|
||||||
|
uint16_t mh_qdcount; /* Question record count */
|
||||||
|
uint16_t mh_ancount; /* Answer record count */
|
||||||
|
uint16_t mh_nscount; /* Authority records count */
|
||||||
|
uint16_t mh_arcount; /* Additional records count */
|
||||||
|
} header[1];
|
||||||
|
uint8_t data[1500];
|
||||||
|
} *zonedata;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
FLAGS_QR = (1 << 15),
|
||||||
|
FLAGS_QUERY = (0 << 11),
|
||||||
|
FLAGS_IQUERY = (1 << 11),
|
||||||
|
FLAGS_STATUS = (2 << 11),
|
||||||
|
FLAGS_OPCODE = (15 << 11), /* mask */
|
||||||
|
FLAGS_AA = (1 << 10), /* */
|
||||||
|
FLAGS_TC = (1 << 9),
|
||||||
|
FLAGS_RD = (1 << 8),
|
||||||
|
FLAGS_RA = (1 << 7),
|
||||||
|
|
||||||
|
FLAGS_RCODE = (15 << 0), /* mask of return code */
|
||||||
|
|
||||||
|
FLAGS_OK = 0, /* No error condition. */
|
||||||
|
FLAGS_FORMAT_ERR = 1, /* Server could not interpret query. */
|
||||||
|
FLAGS_SERVER_ERR = 2, /* Server error. */
|
||||||
|
FLAGS_NAME_ERR = 3, /* No domain name. */
|
||||||
|
FLAGS_UNIMPL_ERR = 4, /* Not implemented. */
|
||||||
|
FLAGS_AUTH_ERR = 5, /* Refused */
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32_t s2_dns_ttl = 3600;
|
||||||
|
|
||||||
|
static int s2_dns_query(su_root_magic_t *magic,
|
||||||
|
su_wait_t *w,
|
||||||
|
su_wakeup_arg_t *arg);
|
||||||
|
|
||||||
|
void s2_dns_setup(su_root_t *root)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
su_socket_t socket;
|
||||||
|
su_wait_t *wait;
|
||||||
|
su_sockaddr_t su[1];
|
||||||
|
socklen_t sulen = sizeof su->su_sin;
|
||||||
|
|
||||||
|
assert(root);
|
||||||
|
|
||||||
|
memset(su, 0, sulen);
|
||||||
|
su->su_len = sulen;
|
||||||
|
su->su_family = AF_INET;
|
||||||
|
|
||||||
|
/* su->su_port = htons(1053); */
|
||||||
|
|
||||||
|
socket = su_socket(su->su_family, SOCK_DGRAM, 0);
|
||||||
|
|
||||||
|
n = bind(socket, &su->su_sa, sulen); assert(n == 0);
|
||||||
|
n = getsockname(socket, &su->su_sa, &sulen); assert(n == 0);
|
||||||
|
|
||||||
|
_sres_default_port = ntohs(su->su_port);
|
||||||
|
|
||||||
|
s2dns.root = root;
|
||||||
|
wait = s2dns.wait;
|
||||||
|
n = su_wait_create(wait, socket, SU_WAIT_IN); assert(n == 0);
|
||||||
|
s2dns.reg = su_root_register(root, wait, s2_dns_query, NULL, 0);
|
||||||
|
assert(s2dns.reg > 0);
|
||||||
|
s2dns.socket = socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
void s2_dns_teardown(void)
|
||||||
|
{
|
||||||
|
struct s2_dns_response *r, *next;
|
||||||
|
su_root_deregister(s2dns.root, s2dns.reg), s2dns.reg = -1;
|
||||||
|
su_close(s2dns.socket), s2dns.socket = -1;
|
||||||
|
s2dns.root = NULL;
|
||||||
|
|
||||||
|
for (r = zonedata, zonedata = NULL; r; r = next) {
|
||||||
|
next = r->next;
|
||||||
|
free(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
s2_dns_query(su_root_magic_t *magic,
|
||||||
|
su_wait_t *w,
|
||||||
|
su_wakeup_arg_t *arg)
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
struct m_header header[1];
|
||||||
|
uint8_t buffer[1500];
|
||||||
|
} request;
|
||||||
|
ssize_t len;
|
||||||
|
|
||||||
|
su_socket_t socket;
|
||||||
|
su_sockaddr_t su[1];
|
||||||
|
socklen_t sulen = sizeof su;
|
||||||
|
uint16_t flags;
|
||||||
|
struct s2_dns_response *r;
|
||||||
|
size_t const hlen = sizeof r->header;
|
||||||
|
|
||||||
|
(void)arg;
|
||||||
|
|
||||||
|
socket = s2dns.socket;
|
||||||
|
|
||||||
|
len = su_recvfrom(socket, request.buffer, sizeof request.buffer, 0,
|
||||||
|
&su->su_sa, &sulen);
|
||||||
|
|
||||||
|
flags = ntohs(request.header->mh_flags);
|
||||||
|
|
||||||
|
if (len < (ssize_t)hlen)
|
||||||
|
return 0;
|
||||||
|
if ((flags & FLAGS_QR) == FLAGS_QR)
|
||||||
|
return 0;
|
||||||
|
if ((flags & FLAGS_RCODE) != FLAGS_OK)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ((flags & FLAGS_OPCODE) != FLAGS_QUERY
|
||||||
|
|| ntohs(request.header->mh_qdcount) != 1) {
|
||||||
|
flags |= FLAGS_QR | FLAGS_UNIMPL_ERR;
|
||||||
|
request.header->mh_flags = htons(flags);
|
||||||
|
su_sendto(socket, request.buffer, len, 0, &su->su_sa, sulen);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (r = zonedata; r; r = r->next) {
|
||||||
|
if (memcmp(r->data, request.buffer + hlen, r->qlen) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r) {
|
||||||
|
flags |= FLAGS_QR | FLAGS_AA | FLAGS_OK;
|
||||||
|
request.header->mh_flags = htons(flags);
|
||||||
|
request.header->mh_ancount = htons(r->header->mh_ancount);
|
||||||
|
request.header->mh_nscount = htons(r->header->mh_nscount);
|
||||||
|
request.header->mh_arcount = htons(r->header->mh_arcount);
|
||||||
|
memcpy(request.buffer + hlen + r->qlen,
|
||||||
|
r->data + r->qlen,
|
||||||
|
r->dlen - r->qlen);
|
||||||
|
len = hlen + r->dlen;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
flags |= FLAGS_QR | FLAGS_AA | FLAGS_NAME_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
request.header->mh_flags = htons(flags);
|
||||||
|
su_sendto(socket, request.buffer, len, 0, &su->su_sa, sulen);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char const *default_domain;
|
||||||
|
|
||||||
|
/* Set default domain */
|
||||||
|
char const *
|
||||||
|
s2_dns_default(char const *domain)
|
||||||
|
{
|
||||||
|
assert(domain == NULL || strlen(domain));
|
||||||
|
assert(domain == NULL || domain[strlen(domain) - 1] == '.');
|
||||||
|
return default_domain = domain;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void put_uint16(struct s2_dns_response *m, uint16_t h)
|
||||||
|
{
|
||||||
|
uint8_t *p = m->data + m->dlen;
|
||||||
|
|
||||||
|
assert(m->dlen + (sizeof h) < sizeof m->data);
|
||||||
|
p[0] = h >> 8; p[1] = h;
|
||||||
|
m->dlen += (sizeof h);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void put_uint32(struct s2_dns_response *m, uint32_t w)
|
||||||
|
{
|
||||||
|
uint8_t *p = m->data + m->dlen;
|
||||||
|
|
||||||
|
assert(m->dlen + (sizeof w) < sizeof m->data);
|
||||||
|
p[0] = w >> 24; p[1] = w >> 16; p[2] = w >> 8; p[3] = w;
|
||||||
|
m->dlen += (sizeof w);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void put_domain(struct s2_dns_response *m, char const *domain)
|
||||||
|
{
|
||||||
|
char const *label;
|
||||||
|
size_t llen;
|
||||||
|
|
||||||
|
if (domain && domain[0] == 0)
|
||||||
|
domain = default_domain;
|
||||||
|
|
||||||
|
/* Copy domain into query label at a time */
|
||||||
|
for (label = domain; label && label[0]; label += llen) {
|
||||||
|
assert(!(label[0] == '.' && label[1] != '\0'));
|
||||||
|
llen = strcspn(label, ".");
|
||||||
|
assert(llen < 64);
|
||||||
|
assert(m->dlen + llen + 1 < sizeof m->data);
|
||||||
|
m->data[m->dlen++] = (uint8_t)llen;
|
||||||
|
if (llen == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
memcpy(m->data + m->dlen, label, llen);
|
||||||
|
m->dlen += (uint16_t)llen;
|
||||||
|
|
||||||
|
if (label[llen] == '\0') {
|
||||||
|
if (default_domain) {
|
||||||
|
label = default_domain, llen = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (label[llen + 1])
|
||||||
|
llen++;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(m->dlen < sizeof m->data);
|
||||||
|
m->data[m->dlen++] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
static void put_string(struct s2_dns_response *m, char const *string)
|
||||||
|
{
|
||||||
|
uint8_t *p = m->data + m->dlen;
|
||||||
|
size_t len = strlen(string);
|
||||||
|
|
||||||
|
assert(len <= 255);
|
||||||
|
assert(m->dlen + len + 1 < sizeof m->data);
|
||||||
|
|
||||||
|
*p++ = (uint8_t)len;
|
||||||
|
memcpy(p, string, len);
|
||||||
|
m->dlen += len + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint16_t put_len_at(struct s2_dns_response *m)
|
||||||
|
{
|
||||||
|
uint16_t at = m->dlen;
|
||||||
|
assert(m->dlen + sizeof(at) < sizeof m->data);
|
||||||
|
memset(m->data + m->dlen, 0, sizeof(at));
|
||||||
|
m->dlen += sizeof(at);
|
||||||
|
return at;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void put_len(struct s2_dns_response *m, uint16_t start)
|
||||||
|
{
|
||||||
|
uint8_t *p = m->data + start;
|
||||||
|
uint16_t len = m->dlen - (start + 2);
|
||||||
|
p[0] = len >> 8; p[1] = len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void put_data(struct s2_dns_response *m, void const *data, uint16_t len)
|
||||||
|
{
|
||||||
|
assert(m->dlen + len < sizeof m->data);
|
||||||
|
memcpy(m->data + m->dlen, data, len);
|
||||||
|
m->dlen += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void put_query(struct s2_dns_response *m, char const *domain,
|
||||||
|
uint16_t qtype)
|
||||||
|
{
|
||||||
|
assert(m->header->mh_qdcount == 0);
|
||||||
|
put_domain(m, domain), put_uint16(m, qtype), put_uint16(m, sres_class_in);
|
||||||
|
m->header->mh_qdcount++;
|
||||||
|
m->qlen = m->dlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void put_a_record(struct s2_dns_response *m,
|
||||||
|
char const *domain,
|
||||||
|
struct in_addr addr)
|
||||||
|
{
|
||||||
|
uint16_t start;
|
||||||
|
|
||||||
|
put_domain(m, domain);
|
||||||
|
put_uint16(m, sres_type_a);
|
||||||
|
put_uint16(m, sres_class_in);
|
||||||
|
put_uint32(m, s2_dns_ttl);
|
||||||
|
start = put_len_at(m);
|
||||||
|
|
||||||
|
put_data(m, &addr, sizeof addr);
|
||||||
|
put_len(m, start);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void put_aaaa_record(struct s2_dns_response *m,
|
||||||
|
char const *domain,
|
||||||
|
struct in6_addr addr)
|
||||||
|
{
|
||||||
|
uint16_t start;
|
||||||
|
|
||||||
|
put_domain(m, domain);
|
||||||
|
put_uint16(m, sres_type_aaaa);
|
||||||
|
put_uint16(m, sres_class_in);
|
||||||
|
put_uint32(m, s2_dns_ttl);
|
||||||
|
start = put_len_at(m);
|
||||||
|
|
||||||
|
put_data(m, &addr, sizeof addr);
|
||||||
|
put_len(m, start);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void put_cname_record(struct s2_dns_response *m,
|
||||||
|
char const *domain,
|
||||||
|
char const *cname)
|
||||||
|
{
|
||||||
|
uint16_t start;
|
||||||
|
|
||||||
|
put_domain(m, domain);
|
||||||
|
put_uint16(m, sres_type_cname);
|
||||||
|
put_uint16(m, sres_class_in);
|
||||||
|
put_uint32(m, s2_dns_ttl);
|
||||||
|
start = put_len_at(m);
|
||||||
|
|
||||||
|
put_data(m, (void *)cname, strlen(cname));
|
||||||
|
put_len(m, start);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void put_srv_record(struct s2_dns_response *m,
|
||||||
|
char const *domain,
|
||||||
|
uint16_t prio, uint16_t weight,
|
||||||
|
uint16_t port, char const *target)
|
||||||
|
{
|
||||||
|
uint16_t start;
|
||||||
|
put_domain(m, domain);
|
||||||
|
put_uint16(m, sres_type_srv);
|
||||||
|
put_uint16(m, sres_class_in);
|
||||||
|
put_uint32(m, s2_dns_ttl);
|
||||||
|
start = put_len_at(m);
|
||||||
|
|
||||||
|
put_uint16(m, prio);
|
||||||
|
put_uint16(m, weight);
|
||||||
|
put_uint16(m, port);
|
||||||
|
put_domain(m, target);
|
||||||
|
put_len(m, start);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void put_naptr_record(struct s2_dns_response *m,
|
||||||
|
char const *domain,
|
||||||
|
uint16_t order, uint16_t preference,
|
||||||
|
char const *flags,
|
||||||
|
char const *services,
|
||||||
|
char const *regexp,
|
||||||
|
char const *replace)
|
||||||
|
{
|
||||||
|
uint16_t start;
|
||||||
|
put_domain(m, domain);
|
||||||
|
put_uint16(m, sres_type_naptr);
|
||||||
|
put_uint16(m, sres_class_in);
|
||||||
|
put_uint32(m, s2_dns_ttl);
|
||||||
|
start = put_len_at(m);
|
||||||
|
|
||||||
|
put_uint16(m, order);
|
||||||
|
put_uint16(m, preference);
|
||||||
|
put_string(m, flags);
|
||||||
|
put_string(m, services);
|
||||||
|
put_string(m, regexp);
|
||||||
|
put_domain(m, replace);
|
||||||
|
put_len(m, start);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void put_srv_record_from_uri(struct s2_dns_response *m,
|
||||||
|
char const *base,
|
||||||
|
uint16_t prio, uint16_t weight,
|
||||||
|
url_t const *uri, char const *server)
|
||||||
|
{
|
||||||
|
char domain[1024] = "none";
|
||||||
|
char const *service = url_port(uri);
|
||||||
|
uint16_t port;
|
||||||
|
|
||||||
|
if (uri->url_type == url_sips) {
|
||||||
|
strcpy(domain, "_sips._tcp.");
|
||||||
|
}
|
||||||
|
else if (uri->url_type == url_sip) {
|
||||||
|
if (url_has_param(uri, "transport=udp")) {
|
||||||
|
strcpy(domain, "_sip._udp.");
|
||||||
|
}
|
||||||
|
else if (url_has_param(uri, "transport=tcp")) {
|
||||||
|
strcpy(domain, "_sip._tcp.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(strcmp(domain, "none"));
|
||||||
|
|
||||||
|
strcat(domain, base);
|
||||||
|
|
||||||
|
if (m->header->mh_qdcount == 0)
|
||||||
|
put_query(m, domain, sres_type_srv);
|
||||||
|
|
||||||
|
port = (uint16_t)strtoul(service, NULL, 10);
|
||||||
|
|
||||||
|
put_srv_record(m, domain, prio, weight, port, server);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void s2_add_to_zone(struct s2_dns_response *_r)
|
||||||
|
{
|
||||||
|
size_t size = offsetof(struct s2_dns_response, data[_r->dlen]);
|
||||||
|
struct s2_dns_response *r = malloc(size); assert(r);
|
||||||
|
|
||||||
|
memcpy(r, _r, size);
|
||||||
|
r->next = zonedata;
|
||||||
|
zonedata = r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void make_server(char *server, char const *prefix, char const *domain)
|
||||||
|
{
|
||||||
|
strcpy(server, prefix);
|
||||||
|
|
||||||
|
if (strlen(server) == 0 || server[strlen(server) - 1] != '.') {
|
||||||
|
strcat(server, ".");
|
||||||
|
strcat(server, domain);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Set up DNS domain */
|
||||||
|
void s2_dns_domain(char const *domain, int use_naptr,
|
||||||
|
/* char *prefix, int priority, url_t const *uri, */
|
||||||
|
...)
|
||||||
|
{
|
||||||
|
struct s2_dns_response m[1];
|
||||||
|
|
||||||
|
char server[1024], target[1024];
|
||||||
|
|
||||||
|
va_list va0, va;
|
||||||
|
char const *prefix; int priority; url_t const *uri;
|
||||||
|
struct in_addr localhost;
|
||||||
|
|
||||||
|
assert(s2dns.reg != 0);
|
||||||
|
|
||||||
|
su_inet_pton(AF_INET, "127.0.0.1", &localhost);
|
||||||
|
|
||||||
|
va_start(va0, use_naptr);
|
||||||
|
|
||||||
|
if (use_naptr) {
|
||||||
|
memset(m, 0, sizeof m);
|
||||||
|
put_query(m, domain, sres_type_naptr);
|
||||||
|
|
||||||
|
va_copy(va, va0);
|
||||||
|
|
||||||
|
for (;(prefix = va_arg(va, char *));) {
|
||||||
|
char *services = NULL;
|
||||||
|
|
||||||
|
priority = va_arg(va, int);
|
||||||
|
uri = va_arg(va, url_t *); assert(uri);
|
||||||
|
|
||||||
|
if (uri->url_type == url_sips) {
|
||||||
|
services = "SIPS+D2T";
|
||||||
|
strcpy(target, "_sips._tcp.");
|
||||||
|
}
|
||||||
|
else if (uri->url_type == url_sip) {
|
||||||
|
if (url_has_param(uri, "transport=udp")) {
|
||||||
|
services = "SIP+D2U";
|
||||||
|
strcpy(target, "_sip._udp.");
|
||||||
|
}
|
||||||
|
else if (url_has_param(uri, "transport=tcp")) {
|
||||||
|
services = "SIP+D2T";
|
||||||
|
strcpy(target, "_sip._tcp.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
strcat(target, domain);
|
||||||
|
assert(services);
|
||||||
|
put_naptr_record(m, domain, 1, priority, "s", services, "", target);
|
||||||
|
m->header->mh_ancount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(va);
|
||||||
|
va_copy(va, va0);
|
||||||
|
|
||||||
|
for (;(prefix = va_arg(va, char *));) {
|
||||||
|
priority = va_arg(va, int);
|
||||||
|
uri = va_arg(va, url_t *); assert(uri);
|
||||||
|
|
||||||
|
make_server(server, prefix, domain);
|
||||||
|
|
||||||
|
put_srv_record_from_uri(m, domain, priority, 10, uri, server);
|
||||||
|
m->header->mh_arcount++;
|
||||||
|
|
||||||
|
put_a_record(m, server, localhost);
|
||||||
|
m->header->mh_arcount++;
|
||||||
|
}
|
||||||
|
va_end(va);
|
||||||
|
|
||||||
|
s2_add_to_zone(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add SRV records */
|
||||||
|
va_copy(va, va0);
|
||||||
|
for (;(prefix = va_arg(va, char *));) {
|
||||||
|
priority = va_arg(va, int);
|
||||||
|
uri = va_arg(va, url_t *); assert(uri);
|
||||||
|
|
||||||
|
make_server(server, prefix, domain);
|
||||||
|
|
||||||
|
memset(m, 0, sizeof m);
|
||||||
|
put_srv_record_from_uri(m, domain, priority, 10, uri, server);
|
||||||
|
m->header->mh_ancount++;
|
||||||
|
|
||||||
|
strcpy(server, prefix); strcat(server, domain);
|
||||||
|
|
||||||
|
put_a_record(m, server, localhost);
|
||||||
|
m->header->mh_arcount++;
|
||||||
|
|
||||||
|
s2_add_to_zone(m);
|
||||||
|
}
|
||||||
|
va_end(va);
|
||||||
|
|
||||||
|
/* Add A records */
|
||||||
|
va_copy(va, va0);
|
||||||
|
for (;(prefix = va_arg(va, char *));) {
|
||||||
|
(void)va_arg(va, int);
|
||||||
|
(void)va_arg(va, url_t *);
|
||||||
|
|
||||||
|
memset(m, 0, sizeof m);
|
||||||
|
make_server(server, prefix, domain);
|
||||||
|
|
||||||
|
put_query(m, server, sres_type_a);
|
||||||
|
put_a_record(m, server, localhost);
|
||||||
|
m->header->mh_ancount++;
|
||||||
|
|
||||||
|
s2_add_to_zone(m);
|
||||||
|
}
|
||||||
|
va_end(va);
|
||||||
|
|
||||||
|
va_end(va0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Insert DNS record */
|
||||||
|
void s2_dns_record(
|
||||||
|
char const *qdomain, unsigned qtype,
|
||||||
|
/* unsigned atype, domain, */
|
||||||
|
...)
|
||||||
|
{
|
||||||
|
struct s2_dns_response m[1];
|
||||||
|
char const *domain;
|
||||||
|
va_list va;
|
||||||
|
unsigned atype;
|
||||||
|
unsigned ancount = 0, arcount = 0;
|
||||||
|
|
||||||
|
memset(m, 0, (sizeof m));
|
||||||
|
|
||||||
|
va_start(va, qtype);
|
||||||
|
|
||||||
|
put_query(m, qdomain, qtype);
|
||||||
|
|
||||||
|
for (domain = va_arg(va, char const *); domain; domain = va_arg(va, char const *)) {
|
||||||
|
if (!domain[0])
|
||||||
|
domain = qdomain;
|
||||||
|
|
||||||
|
if (strcmp(domain, "@") == 0)
|
||||||
|
domain = default_domain;
|
||||||
|
|
||||||
|
atype = va_arg(va, unsigned);
|
||||||
|
|
||||||
|
if (atype == qtype)
|
||||||
|
ancount++;
|
||||||
|
else
|
||||||
|
arcount++;
|
||||||
|
|
||||||
|
switch(atype) {
|
||||||
|
case sres_type_naptr:
|
||||||
|
{
|
||||||
|
unsigned order = va_arg(va, unsigned);
|
||||||
|
unsigned priority = va_arg(va, unsigned);
|
||||||
|
char const *flags = va_arg(va, char const *);
|
||||||
|
char const *services = va_arg(va, char const *);
|
||||||
|
char const *regexp = va_arg(va, char const *);
|
||||||
|
char const *target = va_arg(va, char const *);
|
||||||
|
|
||||||
|
put_naptr_record(m, domain, order, priority,
|
||||||
|
flags, services, regexp, target);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case sres_type_srv:
|
||||||
|
{
|
||||||
|
unsigned priority = va_arg(va, unsigned);
|
||||||
|
unsigned weight = va_arg(va, unsigned);
|
||||||
|
unsigned port = va_arg(va, unsigned);
|
||||||
|
char const *target = va_arg(va, char const *);
|
||||||
|
|
||||||
|
put_srv_record(m, domain, priority, weight, port, target);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case sres_type_aaaa:
|
||||||
|
#if SU_HAVE_IN6
|
||||||
|
{
|
||||||
|
char const *address = va_arg(va, char const *); /* target */
|
||||||
|
struct in6_addr aaaa;
|
||||||
|
|
||||||
|
inet_pton(AF_INET6, address, &aaaa);
|
||||||
|
|
||||||
|
put_aaaa_record(m, domain, aaaa);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case sres_type_a:
|
||||||
|
{
|
||||||
|
char const *address = va_arg(va, char const *); /* target */
|
||||||
|
struct in_addr a;
|
||||||
|
|
||||||
|
inet_pton(AF_INET, address, &a);
|
||||||
|
|
||||||
|
put_a_record(m, domain, a);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case sres_type_cname:
|
||||||
|
put_cname_record(m, domain, va_arg(va, char const *));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m->header->mh_ancount = ancount;
|
||||||
|
m->header->mh_arcount = arcount;
|
||||||
|
|
||||||
|
s2_add_to_zone(m);
|
||||||
|
|
||||||
|
va_end(va);
|
||||||
|
}
|
||||||
|
|
57
libs/sofia-sip/s2check/s2dns.h
Normal file
57
libs/sofia-sip/s2check/s2dns.h
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Sofia-SIP package
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 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
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef S2DNS_H
|
||||||
|
/** Defined when <s2dns.h> has been included. */
|
||||||
|
#define S2DNS_H
|
||||||
|
|
||||||
|
/**@internal @file s2dns.h
|
||||||
|
*
|
||||||
|
* @brief Internal DNS server for testing
|
||||||
|
*
|
||||||
|
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sofia-sip/su_wait.h>
|
||||||
|
|
||||||
|
SOFIA_BEGIN_DECLS
|
||||||
|
|
||||||
|
void s2_dns_setup(su_root_t *root);
|
||||||
|
void s2_dns_teardown(void);
|
||||||
|
|
||||||
|
char const *s2_dns_default(char const *domain);
|
||||||
|
|
||||||
|
extern uint32_t s2_dns_ttl;
|
||||||
|
|
||||||
|
void s2_dns_domain(char const *domain, int use_naptr,
|
||||||
|
/* char *prefix, int priority, url_t const *uri, */
|
||||||
|
...);
|
||||||
|
|
||||||
|
void s2_dns_record(char const *domain, unsigned qtype,
|
||||||
|
/* unsigned atype, domain, */
|
||||||
|
...);
|
||||||
|
|
||||||
|
SOFIA_END_DECLS
|
||||||
|
|
||||||
|
#endif /* S2DNS_H */
|
51
libs/sofia-sip/s2check/s2time.c
Normal file
51
libs/sofia-sip/s2check/s2time.c
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Sofia-SIP package
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 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
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "s2util.h"
|
||||||
|
|
||||||
|
/* -- Delay scenarios --------------------------------------------------- */
|
||||||
|
|
||||||
|
static unsigned long time_offset;
|
||||||
|
|
||||||
|
extern void (*_su_time)(su_time_t *tv);
|
||||||
|
|
||||||
|
static void _su_time_fast_forwarder(su_time_t *tv)
|
||||||
|
{
|
||||||
|
tv->tv_sec += time_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void s2_fast_forward(unsigned long seconds,
|
||||||
|
su_root_t *root)
|
||||||
|
{
|
||||||
|
if (_su_time == NULL)
|
||||||
|
_su_time = _su_time_fast_forwarder;
|
||||||
|
|
||||||
|
time_offset += seconds;
|
||||||
|
|
||||||
|
if (root)
|
||||||
|
su_root_step(root, 0);
|
||||||
|
}
|
||||||
|
|
44
libs/sofia-sip/s2check/s2util.h
Normal file
44
libs/sofia-sip/s2check/s2util.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Sofia-SIP package
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 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
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef S2UTIL_H
|
||||||
|
/** Defined when <s2util.h> has been included. */
|
||||||
|
#define S2UTIL_H
|
||||||
|
|
||||||
|
/**@internal @file s2util.h
|
||||||
|
*
|
||||||
|
* @brief Miscellaneous testing utilities
|
||||||
|
*
|
||||||
|
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sofia-sip/su_wait.h>
|
||||||
|
|
||||||
|
SOFIA_BEGIN_DECLS
|
||||||
|
|
||||||
|
void s2_fast_forward(unsigned long seconds, su_root_t *root);
|
||||||
|
|
||||||
|
SOFIA_END_DECLS
|
||||||
|
|
||||||
|
#endif /* S2UTIL_H */
|
Loading…
Reference in New Issue
Block a user