Thu Mar 5 08:00:45 CST 2009 Pekka Pessi <first.last@nokia.com>
* nta: added check-based test program check_nta git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@12554 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
20719ebf88
commit
2a0b960efb
|
@ -1 +1 @@
|
|||
Tue Mar 10 14:52:49 CDT 2009
|
||||
Tue Mar 10 14:53:54 CDT 2009
|
||||
|
|
|
@ -16,17 +16,20 @@ INCLUDES = -I$(srcdir)/../ipt -I../ipt \
|
|||
-I$(srcdir)/../tport -I../tport \
|
||||
-I$(srcdir)/../url -I../url \
|
||||
-I$(srcdir)/../features -I../features \
|
||||
-I$(srcdir)/../su -I../su
|
||||
-I$(srcdir)/../su -I../su \
|
||||
-I$(top_srcdir)/s2check \
|
||||
-I$(srcdir)/../stun -I ../stun
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Build targets
|
||||
|
||||
noinst_LTLIBRARIES = libnta.la
|
||||
|
||||
check_PROGRAMS = test_nta_api test_nta portbind
|
||||
check_PROGRAMS = check_nta test_nta_api test_nta portbind
|
||||
dist_noinst_SCRIPTS = run_test_nta_api run_test_nta
|
||||
|
||||
TESTS = run_test_nta_api run_test_nta
|
||||
TESTS = run_check_nta run_test_nta_api run_test_nta
|
||||
|
||||
TESTS_ENVIRONMENT = $(SHELL)
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
|
@ -63,6 +66,19 @@ test_nta_LDFLAGS = -static
|
|||
|
||||
MOSTLYCLEANFILES += .test[0-9]*
|
||||
|
||||
if HAVE_CHECK
|
||||
|
||||
check_nta_SOURCES = check_nta.c check_nta.h \
|
||||
check_nta_api.c \
|
||||
check_nta_client.c
|
||||
|
||||
check_nta_LDADD = ${LDADD} ${top_builddir}/s2check/libs2.a \
|
||||
@CHECK_LIBS@
|
||||
|
||||
else
|
||||
check_nta_SOURCES = $(top_srcdir)/s2check/exit77.c
|
||||
endif
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Install and distribution rules
|
||||
|
||||
|
|
|
@ -0,0 +1,482 @@
|
|||
/*
|
||||
* This file is part of the Sofia-SIP package
|
||||
*
|
||||
* Copyright (C) 2008 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
|
||||
*
|
||||
*/
|
||||
|
||||
/**@CFILE check_nta.c
|
||||
* @brief 2nd test Suite for Sofia SIP Transaction Engine
|
||||
*
|
||||
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
|
||||
*
|
||||
* @date Created: Wed Apr 30 12:48:27 EEST 2008 ppessi
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#undef NDEBUG
|
||||
|
||||
#include "check_nta.h"
|
||||
|
||||
#include "s2dns.h"
|
||||
#include "s2base.h"
|
||||
#include "s2sip.h"
|
||||
|
||||
#include <sofia-sip/sip_header.h>
|
||||
#include <sofia-sip/sip_status.h>
|
||||
#include <sofia-sip/msg_addr.h>
|
||||
#include <sofia-sip/su_log.h>
|
||||
#include <sofia-sip/su_tagarg.h>
|
||||
#include <sofia-sip/su_alloc.h>
|
||||
#include <sofia-sip/su_string.h>
|
||||
#include <sofia-sip/sresolv.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <time.h>
|
||||
|
||||
/* -- Globals -------------------------------------------------------------- */
|
||||
|
||||
struct s2nta *s2;
|
||||
|
||||
/* -- main ----------------------------------------------------------------- */
|
||||
|
||||
static void usage(int exitcode)
|
||||
{
|
||||
fprintf(exitcode ? stderr : stdout,
|
||||
"usage: %s [--xml=logfile] case,...\n", s2_tester);
|
||||
exit(exitcode);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int i, failed = 0, selected = 0;
|
||||
char const *xml = NULL;
|
||||
Suite *suite;
|
||||
SRunner *runner;
|
||||
|
||||
s2_tester = "check_nta";
|
||||
s2_suite("NTA");
|
||||
|
||||
if (getenv("CHECK_NTA_VERBOSE"))
|
||||
s2_start_stop = strtoul(getenv("CHECK_NTA_VERBOSE"), NULL, 10);
|
||||
|
||||
for (i = 1; argv[i]; i++) {
|
||||
if (su_strnmatch(argv[i], "--xml=", strlen("--xml="))) {
|
||||
xml = argv[i] + strlen("--xml=");
|
||||
}
|
||||
else if (su_strmatch(argv[i], "--xml")) {
|
||||
if (!(xml = argv[++i]))
|
||||
usage(2);
|
||||
}
|
||||
else if (su_strmatch(argv[i], "-v")) {
|
||||
s2_start_stop = 1;
|
||||
}
|
||||
else if (su_strmatch(argv[i], "-?") ||
|
||||
su_strmatch(argv[i], "-h") ||
|
||||
su_strmatch(argv[i], "--help"))
|
||||
usage(0);
|
||||
else {
|
||||
s2_select_tests(argv[i]);
|
||||
selected = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!selected)
|
||||
s2_select_tests(getenv("CHECK_NTA_CASES"));
|
||||
|
||||
suite = suite_create("Unit tests for nta (Sofia-SIP Transaction Engine)");
|
||||
|
||||
suite_add_tcase(suite, check_nta_api_1_0());
|
||||
suite_add_tcase(suite, check_nta_client_2_0());
|
||||
suite_add_tcase(suite, check_nta_client_2_1());
|
||||
|
||||
runner = srunner_create(suite);
|
||||
|
||||
if (xml)
|
||||
srunner_set_xml(runner, argv[1]);
|
||||
|
||||
srunner_run_all(runner, CK_ENV);
|
||||
failed = srunner_ntests_failed(runner);
|
||||
srunner_free(runner);
|
||||
|
||||
exit(failed ? EXIT_FAILURE : EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
/* -- NTA callbacks -------------------------------------------------------- */
|
||||
|
||||
struct event *
|
||||
s2_nta_remove_event(struct event *e)
|
||||
{
|
||||
if ((*e->prev = e->next))
|
||||
e->next->prev = e->prev;
|
||||
e->prev = NULL, e->next = NULL;
|
||||
return e;
|
||||
}
|
||||
|
||||
void
|
||||
s2_nta_free_event(struct event *e)
|
||||
{
|
||||
if (e) {
|
||||
if (e->prev) {
|
||||
if ((*e->prev = e->next))
|
||||
e->next->prev = e->prev;
|
||||
}
|
||||
if (e->msg)
|
||||
msg_destroy(e->msg);
|
||||
free(e);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
s2_nta_flush_events(void)
|
||||
{
|
||||
while (s2->events) {
|
||||
s2_nta_free_event(s2->events);
|
||||
}
|
||||
}
|
||||
|
||||
struct event *
|
||||
s2_nta_next_event(void)
|
||||
{
|
||||
for (;;) {
|
||||
if (s2->events)
|
||||
return s2_nta_remove_event(s2->events);
|
||||
su_root_step(s2->root, 1);
|
||||
}
|
||||
}
|
||||
|
||||
struct event *
|
||||
s2_nta_vwait_for(enum wait_for wait_for0,
|
||||
void const *value0,
|
||||
va_list va0)
|
||||
{
|
||||
struct event *e;
|
||||
|
||||
for (;;) {
|
||||
for (e = s2->events; e; e = e->next) {
|
||||
va_list va;
|
||||
enum wait_for wait_for;
|
||||
void const *value;
|
||||
|
||||
va_copy(va, va0);
|
||||
|
||||
for (wait_for = wait_for0, value = value0;
|
||||
wait_for;
|
||||
wait_for = va_arg(va, enum wait_for),
|
||||
value = va_arg(va, void const *)) {
|
||||
switch (wait_for) {
|
||||
case wait_for_amagic:
|
||||
if (value != e->amagic)
|
||||
goto next;
|
||||
break;
|
||||
case wait_for_omagic:
|
||||
if (value != e->omagic)
|
||||
goto next;
|
||||
break;
|
||||
case wait_for_orq:
|
||||
if (value != e->orq)
|
||||
goto next;
|
||||
break;
|
||||
case wait_for_lmagic:
|
||||
if (value != e->lmagic)
|
||||
goto next;
|
||||
break;
|
||||
case wait_for_leg:
|
||||
if (value != e->leg)
|
||||
goto next;
|
||||
break;
|
||||
case wait_for_imagic:
|
||||
if (value != e->imagic)
|
||||
goto next;
|
||||
break;
|
||||
case wait_for_irq:
|
||||
if (value != e->irq)
|
||||
goto next;
|
||||
break;
|
||||
case wait_for_method:
|
||||
if ((sip_method_t)value != e->method)
|
||||
goto next;
|
||||
break;
|
||||
case wait_for_method_name:
|
||||
if (!su_strmatch(value, e->method_name))
|
||||
goto next;
|
||||
break;
|
||||
case wait_for_status:
|
||||
if ((int)value != e->status)
|
||||
goto next;
|
||||
break;
|
||||
case wait_for_phrase:
|
||||
if (!su_casematch(value, e->phrase))
|
||||
goto next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
next:
|
||||
va_end(va);
|
||||
|
||||
if (!wait_for)
|
||||
return s2_nta_remove_event(e);
|
||||
}
|
||||
su_root_step(s2->root, 1);
|
||||
}
|
||||
}
|
||||
|
||||
struct event *
|
||||
s2_nta_wait_for(enum wait_for wait_for,
|
||||
void const *value,
|
||||
...)
|
||||
{
|
||||
struct event *e;
|
||||
va_list va;
|
||||
|
||||
va_start(va, value);
|
||||
e = s2_nta_vwait_for(wait_for, value, va);
|
||||
va_end(va);
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
int
|
||||
s2_nta_check_request(enum wait_for wait_for,
|
||||
void const *value,
|
||||
...)
|
||||
{
|
||||
struct event *e;
|
||||
va_list va;
|
||||
|
||||
va_start(va, value);
|
||||
e = s2_nta_vwait_for(wait_for, value, va);
|
||||
va_end(va);
|
||||
|
||||
s2_nta_free_event(e);
|
||||
return e != NULL;
|
||||
}
|
||||
|
||||
int
|
||||
s2_nta_msg_callback(nta_agent_magic_t *magic,
|
||||
nta_agent_t *nta,
|
||||
msg_t *msg,
|
||||
sip_t *sip)
|
||||
{
|
||||
struct event *e, **prev;
|
||||
|
||||
e = calloc(1, sizeof *e);
|
||||
|
||||
e->amagic = magic;
|
||||
e->msg = msg;
|
||||
e->sip = sip;
|
||||
|
||||
if (sip->sip_request) {
|
||||
e->method = sip->sip_request->rq_method;
|
||||
e->method_name = sip->sip_request->rq_method_name;
|
||||
}
|
||||
else {
|
||||
e->status = sip->sip_status->st_status;
|
||||
e->phrase = sip->sip_status->st_phrase;
|
||||
}
|
||||
|
||||
for (prev = &s2->events; *prev; prev = &(*prev)->next)
|
||||
;
|
||||
*prev = e, e->prev = prev;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
s2_nta_orq_callback(nta_outgoing_magic_t *magic,
|
||||
nta_outgoing_t *orq,
|
||||
sip_t const *sip)
|
||||
{
|
||||
struct event *e, **prev;
|
||||
|
||||
e = calloc(1, sizeof *e);
|
||||
|
||||
e->omagic = magic;
|
||||
e->orq = orq;
|
||||
e->msg = nta_outgoing_getresponse(orq);
|
||||
e->sip = sip_object(e->msg);
|
||||
|
||||
e->status = nta_outgoing_status(orq);
|
||||
e->phrase = sip ? sip->sip_status->st_phrase : "";
|
||||
|
||||
for (prev = &s2->events; *prev; prev = &(*prev)->next)
|
||||
;
|
||||
*prev = e, e->prev = prev;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
s2_nta_leg_callback(nta_leg_magic_t *magic,
|
||||
nta_leg_t *leg,
|
||||
nta_incoming_t *irq,
|
||||
sip_t const *sip)
|
||||
{
|
||||
struct event *e, **prev;
|
||||
|
||||
e = calloc(1, sizeof *e);
|
||||
|
||||
e->lmagic = magic;
|
||||
e->leg = leg;
|
||||
e->irq = irq;
|
||||
|
||||
e->msg = nta_incoming_getrequest(irq);
|
||||
e->sip = sip_object(e->msg);
|
||||
|
||||
e->method = e->sip->sip_request->rq_method;
|
||||
e->method_name = e->sip->sip_request->rq_method_name;
|
||||
|
||||
for (prev = &s2->events; *prev; prev = &(*prev)->next)
|
||||
;
|
||||
*prev = e, e->prev = prev;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
s2_nta_irq_callback(nta_incoming_magic_t *magic,
|
||||
nta_incoming_t *irq,
|
||||
sip_t const *sip)
|
||||
{
|
||||
struct event *e, **prev;
|
||||
|
||||
e = calloc(1, sizeof *e);
|
||||
|
||||
e->imagic = magic;
|
||||
e->irq = irq;
|
||||
e->msg = nta_incoming_getrequest_ackcancel(irq);
|
||||
e->sip = sip_object(e->msg);
|
||||
|
||||
e->method = e->sip ? e->sip->sip_request->rq_method : 0;
|
||||
e->method_name = e->sip ? e->sip->sip_request->rq_method_name : NULL;
|
||||
|
||||
for (prev = &s2->events; *prev; prev = &(*prev)->next)
|
||||
;
|
||||
*prev = e, e->prev = prev;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ====================================================================== */
|
||||
|
||||
SOFIAPUBVAR su_log_t nta_log[];
|
||||
SOFIAPUBVAR su_log_t sresolv_log[];
|
||||
SOFIAPUBVAR su_log_t tport_log[];
|
||||
SOFIAPUBVAR su_log_t su_log_default[];
|
||||
|
||||
void
|
||||
s2_nta_setup_logs(int level)
|
||||
{
|
||||
su_log_soft_set_level(su_log_default, level);
|
||||
su_log_soft_set_level(tport_log, level);
|
||||
su_log_soft_set_level(nta_log, level);
|
||||
su_log_soft_set_level(sresolv_log, level);
|
||||
|
||||
if (getenv("TPORT_LOG") == NULL && getenv("S2_TPORT_LOG") == NULL) {
|
||||
if (s2sip)
|
||||
tport_set_params(s2sip->master, TPTAG_LOG(level > 1), TAG_END());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
s2_nta_setup(char const *label,
|
||||
char const * const *transports,
|
||||
tag_type_t tag, tag_value_t value, ...)
|
||||
{
|
||||
ta_list ta;
|
||||
|
||||
s2_setup(label);
|
||||
s2_nta_setup_logs(0);
|
||||
s2_dns_setup(s2base->root);
|
||||
ta_start(ta, tag, value);
|
||||
s2_sip_setup("example.org", transports, ta_tags(ta));
|
||||
ta_end(ta);
|
||||
assert(s2sip->contact);
|
||||
|
||||
s2_dns_domain("example.org", 1,
|
||||
"s2", 1, s2sip->udp.contact ? s2sip->udp.contact->m_url : NULL,
|
||||
"s2", 1, s2sip->tcp.contact ? s2sip->tcp.contact->m_url : NULL,
|
||||
"s2", 1, s2sip->tls.contact ? s2sip->tls.contact->m_url : NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
nta_agent_t *
|
||||
s2_nta_agent_setup(url_string_t const *bind_url,
|
||||
nta_message_f *callback,
|
||||
nta_agent_magic_t *magic,
|
||||
tag_type_t tag, tag_value_t value, ...)
|
||||
{
|
||||
ta_list ta;
|
||||
|
||||
assert(s2base);
|
||||
|
||||
s2 = su_home_new(sizeof *s2); assert(s2);
|
||||
s2->root = su_root_clone(s2base->root, s2); assert(s2->root);
|
||||
fail_unless(s2->root != NULL);
|
||||
|
||||
ta_start(ta, tag, value);
|
||||
s2->nta =
|
||||
nta_agent_create(s2->root,
|
||||
bind_url ? bind_url : URL_STRING_MAKE("sip:*:*"),
|
||||
callback,
|
||||
magic,
|
||||
/* Use internal DNS server */
|
||||
/* Force sresolv to use localhost and s2dns as DNS server */
|
||||
#if HAVE_WIN32
|
||||
SRESTAG_RESOLV_CONF("NUL"),
|
||||
#else
|
||||
SRESTAG_RESOLV_CONF("/dev/null"),
|
||||
#endif
|
||||
ta_tags(ta));
|
||||
ta_end(ta);
|
||||
|
||||
assert(s2->nta);
|
||||
|
||||
if (callback == NULL)
|
||||
s2->default_leg = nta_leg_tcreate(s2->nta, s2_nta_leg_callback, NULL,
|
||||
NTATAG_NO_DIALOG(1),
|
||||
TAG_END());
|
||||
|
||||
return s2->nta;
|
||||
}
|
||||
|
||||
void s2_nta_teardown(void)
|
||||
{
|
||||
if (s2) {
|
||||
s2_nta_flush_events();
|
||||
|
||||
if (s2->default_leg)
|
||||
nta_leg_destroy(s2->default_leg), s2->default_leg = NULL;
|
||||
nta_agent_destroy(s2->nta), s2->nta = NULL;
|
||||
su_root_destroy(s2->root), s2->root = NULL;
|
||||
su_home_unref(s2->home);
|
||||
s2 = NULL;
|
||||
}
|
||||
|
||||
s2_dns_teardown();
|
||||
s2_sip_teardown();
|
||||
s2_teardown();
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* This file is part of the Sofia-SIP package
|
||||
*
|
||||
* Copyright (C) 2008 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 CHECK_NTA_H
|
||||
#define CHECK_NTA_H
|
||||
|
||||
#include <s2check.h>
|
||||
|
||||
#include <sofia-sip/sip.h>
|
||||
#include <sofia-sip/tport.h>
|
||||
#include <sofia-sip/nta.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "s2sip.h"
|
||||
|
||||
extern struct s2nta {
|
||||
su_home_t home[1];
|
||||
|
||||
nta_agent_t *nta;
|
||||
|
||||
su_root_t *root;
|
||||
|
||||
nta_leg_t *default_leg;
|
||||
|
||||
struct event {
|
||||
struct event *next, **prev;
|
||||
|
||||
nta_agent_magic_t *amagic;
|
||||
|
||||
nta_outgoing_magic_t *omagic;
|
||||
nta_outgoing_t *orq;
|
||||
|
||||
nta_leg_magic_t *lmagic;
|
||||
nta_leg_t *leg;
|
||||
|
||||
nta_incoming_magic_t *imagic;
|
||||
nta_incoming_t *irq;
|
||||
|
||||
sip_method_t method;
|
||||
char const *method_name;
|
||||
|
||||
int status;
|
||||
char const *phrase;
|
||||
|
||||
msg_t *msg;
|
||||
sip_t *sip;
|
||||
} *events;
|
||||
} *s2;
|
||||
|
||||
struct event *s2_nta_remove_event(struct event *e);
|
||||
void s2_nta_free_event(struct event *e);
|
||||
void s2_nta_flush_events(void);
|
||||
struct event *s2_nta_next_event(void);
|
||||
|
||||
enum wait_for {
|
||||
wait_for_amagic = 1,
|
||||
wait_for_omagic,
|
||||
wait_for_orq,
|
||||
wait_for_lmagic,
|
||||
wait_for_leg,
|
||||
wait_for_imagic,
|
||||
wait_for_irq,
|
||||
wait_for_method,
|
||||
wait_for_method_name,
|
||||
wait_for_status,
|
||||
wait_for_phrase
|
||||
};
|
||||
|
||||
struct event *s2_nta_vwait_for(enum wait_for,
|
||||
void const *value,
|
||||
va_list va);
|
||||
|
||||
struct event *s2_nta_wait_for(enum wait_for,
|
||||
void const *value,
|
||||
...);
|
||||
|
||||
int s2_nta_check_for(enum wait_for,
|
||||
void const *value,
|
||||
...);
|
||||
|
||||
int s2_nta_msg_callback(nta_agent_magic_t *magic,
|
||||
nta_agent_t *nta,
|
||||
msg_t *msg,
|
||||
sip_t *sip);
|
||||
int s2_nta_orq_callback(nta_outgoing_magic_t *magic,
|
||||
nta_outgoing_t *orq,
|
||||
sip_t const *sip);
|
||||
int s2_nta_leg_callback(nta_leg_magic_t *magic,
|
||||
nta_leg_t *leg,
|
||||
nta_incoming_t *irq,
|
||||
sip_t const *sip);
|
||||
int s2_nta_irq_callback(nta_incoming_magic_t *magic,
|
||||
nta_incoming_t *irq,
|
||||
sip_t const *sip);
|
||||
|
||||
void s2_nta_setup_logs(int level);
|
||||
void s2_nta_setup(char const *label,
|
||||
char const * const *transports,
|
||||
tag_type_t tag, tag_value_t value, ...);
|
||||
|
||||
nta_agent_t *s2_nta_agent_setup(url_string_t const *bind_url,
|
||||
nta_message_f *callback,
|
||||
nta_agent_magic_t *magic,
|
||||
tag_type_t tag, tag_value_t value, ...);
|
||||
void s2_nta_teardown(void);
|
||||
|
||||
TCase *check_nta_api_1_0(void);
|
||||
TCase *check_nta_client_2_0(void);
|
||||
TCase *check_nta_client_2_1(void);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,268 @@
|
|||
/*
|
||||
* This file is part of the Sofia-SIP package
|
||||
*
|
||||
* Copyright (C) 2008 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
|
||||
*
|
||||
*/
|
||||
|
||||
/**@CFILE check_nta_api.c
|
||||
*
|
||||
* @brief Check-driven tester for NTA API
|
||||
*
|
||||
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
|
||||
*
|
||||
* @copyright (C) 2009 Nokia Corporation.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "check_nta.h"
|
||||
#include "s2base.h"
|
||||
#include "nta_internal.h"
|
||||
|
||||
#include <sofia-sip/nta.h>
|
||||
#include <sofia-sip/sip_status.h>
|
||||
#include <sofia-sip/sip_header.h>
|
||||
#include <sofia-sip/su_tagarg.h>
|
||||
#include <sofia-sip/su_tag_io.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define NONE ((void *)-1)
|
||||
|
||||
static void
|
||||
api_setup(void)
|
||||
{
|
||||
s2_nta_setup("NTA", NULL, TAG_END());
|
||||
}
|
||||
|
||||
static void
|
||||
api_teardown(void)
|
||||
{
|
||||
mark_point();
|
||||
s2_nta_teardown();
|
||||
}
|
||||
|
||||
START_TEST(api_1_0_0)
|
||||
{
|
||||
su_root_t *root = s2base->root;
|
||||
nta_agent_t *nta;
|
||||
su_home_t home[1];
|
||||
su_nanotime_t nano;
|
||||
nta_agent_magic_t *amagic = (void *)(home + 1);
|
||||
nta_outgoing_magic_t *omagic = (void *)(home + 2);
|
||||
msg_t *msg;
|
||||
|
||||
memset(home, 0, sizeof home); home->suh_size = (sizeof home);
|
||||
su_home_init(home);
|
||||
|
||||
fail_unless(nta_agent_create(NULL,
|
||||
(url_string_t *)"sip:*:*",
|
||||
NULL,
|
||||
NULL,
|
||||
TAG_END()) == NULL);
|
||||
|
||||
fail_unless(nta_agent_create(root,
|
||||
(url_string_t *)"http://localhost:*/invalid/bind/url",
|
||||
NULL,
|
||||
NULL,
|
||||
TAG_END()) == NULL);
|
||||
|
||||
fail_unless(nta_agent_create(root,
|
||||
(url_string_t *)"sip:*:*;transport=XXX",
|
||||
NULL,
|
||||
NULL,
|
||||
TAG_END()) == NULL);
|
||||
mark_point();
|
||||
nta = nta_agent_create(root,
|
||||
(url_string_t *)"sip:*:*",
|
||||
NULL,
|
||||
NULL,
|
||||
TAG_END());
|
||||
fail_unless(nta != NULL);
|
||||
|
||||
mark_point();
|
||||
nta_agent_destroy(NULL);
|
||||
mark_point();
|
||||
nta_agent_destroy(nta);
|
||||
|
||||
mark_point();
|
||||
nta = nta_agent_create(root,
|
||||
(url_string_t *)"sip:*:*",
|
||||
s2_nta_msg_callback,
|
||||
amagic,
|
||||
TAG_END());
|
||||
fail_unless(nta != NULL);
|
||||
|
||||
fail_unless(nta_agent_contact(NULL) == NULL);
|
||||
fail_unless(nta_agent_via(NULL) == NULL);
|
||||
fail_if(strcmp(nta_agent_version(nta), nta_agent_version(NULL)));
|
||||
fail_unless(nta_agent_magic(NULL) == NULL);
|
||||
fail_unless(nta_agent_magic(nta) == amagic);
|
||||
fail_unless(nta_agent_add_tport(NULL, NULL, TAG_END()) == -1);
|
||||
fail_unless(nta_agent_newtag(home, "tag=%s", NULL) == NULL);
|
||||
fail_unless(nta_agent_newtag(home, "tag=%s", nta) != NULL);
|
||||
|
||||
fail_unless(nta_msg_create(NULL, 0) == NULL);
|
||||
fail_unless(nta_msg_complete(NULL) == -1);
|
||||
|
||||
fail_unless((msg = nta_msg_create(nta, 0)) != NULL);
|
||||
fail_unless(nta_msg_complete(msg) == -1);
|
||||
fail_unless(
|
||||
nta_msg_request_complete(msg, NULL, SIP_METHOD(FOO), NULL) == -1);
|
||||
fail_unless(nta_is_internal_msg(NULL) == 0);
|
||||
fail_unless(nta_is_internal_msg(msg) == 0);
|
||||
fail_unless(msg_set_flags(msg, NTA_INTERNAL_MSG));
|
||||
fail_unless(nta_is_internal_msg(msg) == 1);
|
||||
mark_point(); msg_destroy(msg); mark_point();
|
||||
|
||||
fail_unless(nta_leg_tcreate(NULL, NULL, NULL, TAG_END()) == NULL);
|
||||
mark_point(); nta_leg_destroy(NULL); mark_point();
|
||||
fail_unless(nta_leg_magic(NULL, NULL) == NULL);
|
||||
mark_point(); nta_leg_bind(NULL, NULL, NULL); mark_point();
|
||||
fail_unless(nta_leg_tag(NULL, "fidsafsa") == NULL);
|
||||
fail_unless(nta_leg_rtag(NULL, "fidsafsa") == NULL);
|
||||
fail_unless(nta_leg_get_tag(NULL) == NULL);
|
||||
fail_unless(nta_leg_client_route(NULL, NULL, NULL) == -1);
|
||||
fail_unless(nta_leg_client_reroute(NULL, NULL, NULL, 0) == -1);
|
||||
fail_unless(nta_leg_server_route(NULL, NULL, NULL) == -1);
|
||||
fail_unless(nta_leg_by_uri(NULL, NULL) == NULL);
|
||||
fail_unless(
|
||||
nta_leg_by_dialog(NULL, NULL, NULL, NULL, NULL, NULL, NULL) == NULL);
|
||||
fail_unless(
|
||||
nta_leg_by_dialog(nta, NULL, NULL, NULL, NULL, NULL, NULL) == NULL);
|
||||
|
||||
fail_unless(nta_leg_make_replaces(NULL, NULL, 1) == NULL);
|
||||
fail_unless(nta_leg_by_replaces(NULL, NULL) == NULL);
|
||||
|
||||
fail_unless(nta_incoming_create(NULL, NULL, NULL, NULL, TAG_END()) == NULL);
|
||||
fail_unless(nta_incoming_create(nta, NULL, NULL, NULL, TAG_END()) == NULL);
|
||||
|
||||
mark_point(); nta_incoming_bind(NULL, NULL, NULL); mark_point();
|
||||
fail_unless(nta_incoming_magic(NULL, NULL) == NULL);
|
||||
|
||||
fail_unless(nta_incoming_find(NULL, NULL, NULL) == NULL);
|
||||
fail_unless(nta_incoming_find(nta, NULL, NULL) == NULL);
|
||||
|
||||
fail_unless(nta_incoming_tag(NULL, NULL) == NULL);
|
||||
fail_unless(nta_incoming_gettag(NULL) == NULL);
|
||||
|
||||
fail_unless(nta_incoming_status(NULL) == 400);
|
||||
fail_unless(nta_incoming_method(NULL) == sip_method_invalid);
|
||||
fail_unless(nta_incoming_method_name(NULL) == NULL);
|
||||
fail_unless(nta_incoming_url(NULL) == NULL);
|
||||
fail_unless(nta_incoming_cseq(NULL) == 0);
|
||||
fail_unless(nta_incoming_received(NULL, &nano) == 0);
|
||||
fail_unless(nano == 0);
|
||||
|
||||
fail_unless(nta_incoming_set_params(NULL, TAG_END()) == -1);
|
||||
|
||||
fail_unless(nta_incoming_getrequest(NULL) == NULL);
|
||||
fail_unless(nta_incoming_getrequest_ackcancel(NULL) == NULL);
|
||||
fail_unless(nta_incoming_getresponse(NULL) == NULL);
|
||||
|
||||
fail_unless(
|
||||
nta_incoming_complete_response(NULL, NULL, 800, "foo", TAG_END()) == -1);
|
||||
|
||||
fail_unless(nta_incoming_treply(NULL, SIP_200_OK, TAG_END()) == -1);
|
||||
fail_unless(nta_incoming_mreply(NULL, NULL) == -1);
|
||||
|
||||
mark_point(); nta_incoming_destroy(NULL); mark_point();
|
||||
|
||||
fail_unless(
|
||||
nta_outgoing_tcreate(NULL, s2_nta_orq_callback, omagic,
|
||||
URL_STRING_MAKE("sip:localhost"),
|
||||
SIP_METHOD_MESSAGE,
|
||||
URL_STRING_MAKE("sip:localhost"),
|
||||
TAG_END()) == NULL);
|
||||
|
||||
fail_unless(
|
||||
nta_outgoing_mcreate(NULL, s2_nta_orq_callback, omagic,
|
||||
URL_STRING_MAKE("sip:localhost"),
|
||||
NULL,
|
||||
TAG_END()) == NULL);
|
||||
|
||||
fail_unless(nta_outgoing_default(NULL, NULL, NULL) == NULL);
|
||||
|
||||
fail_unless(nta_outgoing_bind(NULL, NULL, NULL) == -1);
|
||||
fail_unless(nta_outgoing_magic(NULL, NULL) == NULL);
|
||||
|
||||
fail_unless(nta_outgoing_status(NULL) == 500);
|
||||
fail_unless(nta_outgoing_method(NULL) == sip_method_invalid);
|
||||
fail_unless(nta_outgoing_method_name(NULL) == NULL);
|
||||
fail_unless(nta_outgoing_cseq(NULL) == 0);
|
||||
|
||||
fail_unless(nta_outgoing_delay(NULL) == UINT_MAX);
|
||||
fail_unless(nta_outgoing_request_uri(NULL) == NULL);
|
||||
fail_unless(nta_outgoing_route_uri(NULL) == NULL);
|
||||
|
||||
fail_unless(nta_outgoing_getresponse(NULL) == NULL);
|
||||
fail_unless(nta_outgoing_getrequest(NULL) == NULL);
|
||||
|
||||
fail_unless(nta_outgoing_tagged(NULL, NULL, NULL, NULL, NULL) == NULL);
|
||||
fail_unless(nta_outgoing_cancel(NULL) == -1);
|
||||
fail_unless(nta_outgoing_tcancel(NULL, NULL, NULL, TAG_END()) == NULL);
|
||||
mark_point(); nta_outgoing_destroy(NULL); mark_point();
|
||||
|
||||
fail_unless(nta_outgoing_find(NULL, NULL, NULL, NULL) == NULL);
|
||||
fail_unless(nta_outgoing_find(nta, NULL, NULL, NULL) == NULL);
|
||||
|
||||
fail_unless(nta_outgoing_status(NONE) == 500);
|
||||
fail_unless(nta_outgoing_method(NONE) == sip_method_invalid);
|
||||
fail_unless(nta_outgoing_method_name(NONE) == NULL);
|
||||
fail_unless(nta_outgoing_cseq(NONE) == 0);
|
||||
|
||||
fail_unless(nta_outgoing_delay(NONE) == UINT_MAX);
|
||||
fail_unless(nta_outgoing_request_uri(NONE) == NULL);
|
||||
fail_unless(nta_outgoing_route_uri(NONE) == NULL);
|
||||
|
||||
fail_unless(nta_outgoing_getresponse(NONE) == NULL);
|
||||
fail_unless(nta_outgoing_getrequest(NONE) == NULL);
|
||||
|
||||
fail_unless(nta_outgoing_tagged(NONE, NULL, NULL, NULL, NULL) == NULL);
|
||||
fail_unless(nta_outgoing_cancel(NONE) == -1);
|
||||
fail_unless(nta_outgoing_tcancel(NONE, NULL, NULL, TAG_END()) == NULL);
|
||||
mark_point(); nta_outgoing_destroy(NONE); mark_point();
|
||||
|
||||
fail_unless(nta_reliable_treply(NULL, NULL, NULL, 0, NULL, TAG_END()) == NULL);
|
||||
fail_unless(nta_reliable_mreply(NULL, NULL, NULL, NULL) == NULL);
|
||||
mark_point(); nta_reliable_destroy(NULL); mark_point();
|
||||
|
||||
mark_point(); nta_agent_destroy(nta); mark_point();
|
||||
mark_point(); su_home_deinit(home); mark_point();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
TCase *check_nta_api_1_0(void)
|
||||
{
|
||||
TCase *tc = tcase_create("NTA 1 - API");
|
||||
|
||||
tcase_add_checked_fixture(tc, api_setup, api_teardown);
|
||||
|
||||
tcase_set_timeout(tc, 10);
|
||||
|
||||
tcase_add_test(tc, api_1_0_0);
|
||||
|
||||
return tc;
|
||||
}
|
|
@ -0,0 +1,388 @@
|
|||
/*
|
||||
* This file is part of the Sofia-SIP package
|
||||
*
|
||||
* Copyright (C) 2008 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
|
||||
*
|
||||
*/
|
||||
|
||||
/**@CFILE check_nta_client.c
|
||||
*
|
||||
* @brief Check-driven tester for NTA client transactions
|
||||
*
|
||||
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
|
||||
*
|
||||
* @copyright (C) 2009 Nokia Corporation.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "check_nta.h"
|
||||
#include "s2base.h"
|
||||
#include "s2dns.h"
|
||||
|
||||
#include <sofia-sip/nta.h>
|
||||
#include <sofia-sip/nta_tport.h>
|
||||
#include <sofia-sip/sip_status.h>
|
||||
#include <sofia-sip/sip_header.h>
|
||||
#include <sofia-sip/su_tagarg.h>
|
||||
#include <sofia-sip/su_tag_io.h>
|
||||
#include <sofia-sip/sres_sip.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define NONE ((void *)-1)
|
||||
|
||||
static void
|
||||
client_setup(void)
|
||||
{
|
||||
s2_nta_setup("NTA", NULL, TAG_END());
|
||||
s2_nta_agent_setup(URL_STRING_MAKE("sip:0.0.0.0:*"), NULL, NULL,
|
||||
NTATAG_DEFAULT_PROXY("sip:example.org"),
|
||||
TAG_END());
|
||||
}
|
||||
|
||||
static void
|
||||
client_setup_udp_only_server(void)
|
||||
{
|
||||
char const * const transports[] = { "udp", NULL };
|
||||
|
||||
s2_nta_setup("NTA", transports, TAG_END());
|
||||
s2_nta_agent_setup(URL_STRING_MAKE("sip:0.0.0.0:*"), NULL, NULL,
|
||||
NTATAG_DEFAULT_PROXY(s2sip->contact->m_url),
|
||||
TAG_END());
|
||||
}
|
||||
|
||||
static void
|
||||
client_setup_tcp_only_server(void)
|
||||
{
|
||||
char const * const transports[] = { "tcp", NULL };
|
||||
|
||||
s2_nta_setup("NTA", transports, TAG_END());
|
||||
s2_nta_agent_setup(URL_STRING_MAKE("sip:0.0.0.0:*"), NULL, NULL,
|
||||
NTATAG_DEFAULT_PROXY(s2sip->contact->m_url),
|
||||
TAG_END());
|
||||
}
|
||||
|
||||
static void
|
||||
client_teardown(void)
|
||||
{
|
||||
mark_point();
|
||||
s2_nta_teardown();
|
||||
}
|
||||
|
||||
START_TEST(client_2_0_0)
|
||||
{
|
||||
nta_outgoing_t *orq;
|
||||
struct message *request;
|
||||
struct event *response;
|
||||
|
||||
s2_case("2.0.0", "Send MESSAGE",
|
||||
"Basic non-INVITE transaction with outbound proxy");
|
||||
|
||||
orq = nta_outgoing_tcreate(s2->default_leg,
|
||||
s2_nta_orq_callback, NULL, NULL,
|
||||
SIP_METHOD_MESSAGE,
|
||||
URL_STRING_MAKE("sip:test2.0.example.org"),
|
||||
SIPTAG_FROM_STR("<sip:client@example.net>"),
|
||||
TAG_END());
|
||||
fail_unless(orq != NULL);
|
||||
request = s2_sip_wait_for_request(SIP_METHOD_MESSAGE);
|
||||
fail_unless(request != NULL);
|
||||
s2_sip_respond_to(request, NULL, 200, "2.0.0", TAG_END());
|
||||
response = s2_nta_wait_for(wait_for_orq, orq,
|
||||
wait_for_status, 200,
|
||||
0);
|
||||
s2_sip_free_message(request);
|
||||
s2_nta_free_event(response);
|
||||
nta_outgoing_destroy(orq);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(client_2_0_1)
|
||||
{
|
||||
nta_outgoing_t *orq;
|
||||
struct message *request;
|
||||
struct event *response;
|
||||
|
||||
s2_case("2.0.0", "Send MESSAGE",
|
||||
"Basic non-INVITE transaction with "
|
||||
"numeric per-transaction outbound proxy");
|
||||
|
||||
orq = nta_outgoing_tcreate(s2->default_leg,
|
||||
s2_nta_orq_callback, NULL,
|
||||
(url_string_t *)s2sip->contact->m_url,
|
||||
SIP_METHOD_MESSAGE,
|
||||
URL_STRING_MAKE("sip:test2.0.example.org"),
|
||||
SIPTAG_FROM_STR("<sip:client@example.net>"),
|
||||
TAG_END());
|
||||
fail_unless(orq != NULL);
|
||||
request = s2_sip_wait_for_request(SIP_METHOD_MESSAGE);
|
||||
fail_unless(request != NULL);
|
||||
s2_sip_respond_to(request, NULL, 200, "OK 2.0.1", TAG_END());
|
||||
response = s2_nta_wait_for(wait_for_orq, orq,
|
||||
wait_for_status, 200,
|
||||
0);
|
||||
s2_sip_free_message(request);
|
||||
s2_nta_free_event(response);
|
||||
nta_outgoing_destroy(orq);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(client_2_0_2)
|
||||
{
|
||||
nta_outgoing_t *orq;
|
||||
struct message *request;
|
||||
struct event *response;
|
||||
|
||||
char payload[2048];
|
||||
|
||||
s2_case("2.0.2", "Send MESSAGE",
|
||||
"Basic non-INVITE transaction exceeding "
|
||||
"default path MTU (1300 bytes)");
|
||||
|
||||
memset(payload, 'x', sizeof payload);
|
||||
payload[(sizeof payload) - 1] = '\0';
|
||||
|
||||
orq = nta_outgoing_tcreate(s2->default_leg,
|
||||
s2_nta_orq_callback, NULL, NULL,
|
||||
SIP_METHOD_MESSAGE,
|
||||
URL_STRING_MAKE("sip:test2.0.example.org"),
|
||||
SIPTAG_FROM_STR("<sip:client@example.net>"),
|
||||
SIPTAG_PAYLOAD_STR(payload),
|
||||
TAG_END());
|
||||
fail_unless(orq != NULL);
|
||||
request = s2_sip_wait_for_request(SIP_METHOD_MESSAGE);
|
||||
fail_unless(request != NULL);
|
||||
fail_unless(request->sip->sip_via->v_protocol == sip_transport_tcp);
|
||||
|
||||
s2_sip_respond_to(request, NULL, 200, "OK 2.0.2", TAG_END());
|
||||
response = s2_nta_wait_for(wait_for_orq, orq,
|
||||
wait_for_status, 200,
|
||||
0);
|
||||
s2_nta_free_event(response);
|
||||
nta_outgoing_destroy(orq);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
TCase *check_nta_client_2_0(void)
|
||||
{
|
||||
TCase *tc = tcase_create("NTA 2.0 - Client");
|
||||
|
||||
tcase_add_checked_fixture(tc, client_setup, client_teardown);
|
||||
|
||||
tcase_set_timeout(tc, 2);
|
||||
|
||||
tcase_add_test(tc, client_2_0_0);
|
||||
tcase_add_test(tc, client_2_0_1);
|
||||
tcase_add_test(tc, client_2_0_2);
|
||||
|
||||
return tc;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
START_TEST(client_2_1_0)
|
||||
{
|
||||
nta_outgoing_t *orq;
|
||||
struct message *request;
|
||||
struct event *response;
|
||||
|
||||
char payload[2048];
|
||||
|
||||
s2_case("2.1.0", "Try UDP after trying with TCP",
|
||||
"TCP connect() is refused");
|
||||
|
||||
memset(payload, 'x', sizeof payload);
|
||||
payload[(sizeof payload) - 1] = '\0';
|
||||
|
||||
client_setup_udp_only_server();
|
||||
|
||||
orq = nta_outgoing_tcreate(s2->default_leg,
|
||||
s2_nta_orq_callback, NULL, NULL,
|
||||
SIP_METHOD_MESSAGE,
|
||||
URL_STRING_MAKE("sip:test2.0.example.org"),
|
||||
SIPTAG_FROM_STR("<sip:client@example.net>"),
|
||||
SIPTAG_PAYLOAD_STR(payload),
|
||||
TAG_END());
|
||||
fail_unless(orq != NULL);
|
||||
|
||||
request = s2_sip_wait_for_request(SIP_METHOD_MESSAGE);
|
||||
fail_unless(request != NULL);
|
||||
fail_unless(request->sip->sip_via->v_protocol == sip_transport_udp);
|
||||
s2_sip_respond_to(request, NULL, 200, "OK", TAG_END());
|
||||
s2_sip_free_message(request);
|
||||
|
||||
response = s2_nta_wait_for(wait_for_orq, orq,
|
||||
wait_for_status, 200,
|
||||
0);
|
||||
s2_nta_free_event(response);
|
||||
nta_outgoing_destroy(orq);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
#undef SU_LOG
|
||||
|
||||
#include "tport_internal.h"
|
||||
|
||||
tport_vtable_t hacked_tcp_vtable;
|
||||
|
||||
/* Make TCP connection to 192.168.255.2:9999 */
|
||||
static tport_t *
|
||||
hacked_tcp_connect(tport_primary_t *pri,
|
||||
su_addrinfo_t *ai,
|
||||
tp_name_t const *tpn)
|
||||
{
|
||||
su_addrinfo_t fake_ai[1];
|
||||
su_sockaddr_t fake_addr[1];
|
||||
uint32_t fake_ip = htonl(0xc0a8ff02); /* 192.168.255.2 */
|
||||
|
||||
*fake_ai = *ai;
|
||||
assert(ai->ai_addrlen <= (sizeof fake_addr));
|
||||
fake_ai->ai_addr = memcpy(fake_addr, ai->ai_addr, ai->ai_addrlen);
|
||||
|
||||
fake_ai->ai_family = AF_INET;
|
||||
fake_addr->su_family = AF_INET;
|
||||
memcpy(&fake_addr->su_sin.sin_addr, &fake_ip, sizeof fake_ip);
|
||||
fake_addr->su_sin.sin_port = htons(9999);
|
||||
|
||||
return tport_base_connect(pri, fake_ai, ai, tpn);
|
||||
}
|
||||
|
||||
START_TEST(client_2_1_1)
|
||||
{
|
||||
tport_t *tp;
|
||||
|
||||
nta_outgoing_t *orq;
|
||||
struct message *request;
|
||||
struct event *response;
|
||||
|
||||
char payload[2048];
|
||||
|
||||
s2_case("2.1.1", "Try UDP after trying with TCP",
|
||||
"TCP connect() times out");
|
||||
|
||||
memset(payload, 'x', sizeof payload);
|
||||
payload[(sizeof payload) - 1] = '\0';
|
||||
|
||||
client_setup_udp_only_server();
|
||||
|
||||
hacked_tcp_vtable = tport_tcp_vtable;
|
||||
hacked_tcp_vtable.vtp_connect = hacked_tcp_connect;
|
||||
fail_unless(tport_tcp_vtable.vtp_connect == NULL);
|
||||
|
||||
for (tp = tport_primaries(nta_agent_tports(s2->nta));
|
||||
tp;
|
||||
tp = tport_next(tp)) {
|
||||
if (tport_is_tcp(tp)) {
|
||||
tp->tp_pri->pri_vtable = &hacked_tcp_vtable;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
orq = nta_outgoing_tcreate(s2->default_leg,
|
||||
s2_nta_orq_callback, NULL,
|
||||
NULL,
|
||||
SIP_METHOD_MESSAGE,
|
||||
URL_STRING_MAKE("sip:test2.0.example.org"),
|
||||
SIPTAG_FROM_STR("<sip:client@example.net>"),
|
||||
SIPTAG_PAYLOAD_STR(payload),
|
||||
TAG_END());
|
||||
fail_unless(orq != NULL);
|
||||
|
||||
s2_fast_forward(1, s2->root);
|
||||
s2_fast_forward(1, s2->root);
|
||||
s2_fast_forward(1, s2->root);
|
||||
s2_fast_forward(1, s2->root);
|
||||
s2_fast_forward(1, s2->root);
|
||||
|
||||
request = s2_sip_wait_for_request(SIP_METHOD_MESSAGE);
|
||||
fail_unless(request != NULL);
|
||||
fail_unless(request->sip->sip_via->v_protocol == sip_transport_udp);
|
||||
s2_sip_respond_to(request, NULL, 200, "OK", TAG_END());
|
||||
s2_sip_free_message(request);
|
||||
|
||||
response = s2_nta_wait_for(wait_for_orq, orq,
|
||||
wait_for_status, 200,
|
||||
0);
|
||||
s2_nta_free_event(response);
|
||||
nta_outgoing_destroy(orq);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(client_2_1_2)
|
||||
{
|
||||
nta_outgoing_t *orq;
|
||||
struct message *request;
|
||||
struct event *response;
|
||||
url_t udpurl[1];
|
||||
|
||||
s2_case("2.1.2", "Send MESSAGE",
|
||||
"Non-INVITE transaction to TCP-only server");
|
||||
|
||||
client_setup_tcp_only_server();
|
||||
|
||||
*udpurl = *s2sip->tcp.contact->m_url;
|
||||
udpurl->url_params = "transport=udp";
|
||||
|
||||
/* Create DNS records for both UDP and TCP */
|
||||
s2_dns_domain("udptcp.org", 1,
|
||||
"s2", 1, udpurl,
|
||||
"s2", 1, s2sip->tcp.contact->m_url,
|
||||
NULL);
|
||||
|
||||
orq = nta_outgoing_tcreate(s2->default_leg,
|
||||
s2_nta_orq_callback, NULL,
|
||||
URL_STRING_MAKE("sip:udptcp.org"),
|
||||
SIP_METHOD_MESSAGE,
|
||||
URL_STRING_MAKE("sip:test2.0.example.org"),
|
||||
SIPTAG_FROM_STR("<sip:client@example.net>"),
|
||||
TAG_END());
|
||||
fail_unless(orq != NULL);
|
||||
request = s2_sip_wait_for_request(SIP_METHOD_MESSAGE);
|
||||
fail_unless(request != NULL);
|
||||
s2_sip_respond_to(request, NULL, 200, "2.0.0", TAG_END());
|
||||
s2_sip_free_message(request);
|
||||
response = s2_nta_wait_for(wait_for_orq, orq,
|
||||
wait_for_status, 200,
|
||||
0);
|
||||
s2_nta_free_event(response);
|
||||
nta_outgoing_destroy(orq);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
TCase *check_nta_client_2_1(void)
|
||||
{
|
||||
TCase *tc = tcase_create("NTA 2.1 - Client");
|
||||
|
||||
tcase_add_checked_fixture(tc, NULL, client_teardown);
|
||||
|
||||
tcase_set_timeout(tc, 20);
|
||||
|
||||
tcase_add_test(tc, client_2_1_0);
|
||||
tcase_add_test(tc, client_2_1_1);
|
||||
tcase_add_test(tc, client_2_1_2);
|
||||
|
||||
return tc;
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
#!/bin/sh
|
||||
$VALGRIND exec ./check_nta "$@"
|
Loading…
Reference in New Issue