mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-30 14:06:04 +00:00
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@8406 d0543943-73ff-0310-b7d9-9358b9ac24b2
1044 lines
28 KiB
C
1044 lines
28 KiB
C
/*
|
|
* This file is part of the Sofia-SIP package
|
|
*
|
|
* Copyright (C) 2005 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 test_register.c
|
|
* @brief Test registering, outbound, nat traversal.
|
|
*
|
|
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
|
|
* @author Martti Mela <Martti Mela@nokia.com>
|
|
*
|
|
* @date Created: Wed Aug 17 12:12:12 EEST 2005 ppessi
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include "test_nua.h"
|
|
#include <sofia-sip/su_tag_class.h>
|
|
|
|
#if HAVE_FUNC
|
|
#elif HAVE_FUNCTION
|
|
#define __func__ __FUNCTION__
|
|
#else
|
|
#define __func__ "test_register"
|
|
#endif
|
|
|
|
/* ======================================================================== */
|
|
/* Test REGISTER */
|
|
|
|
int test_clear_registrations(struct context *ctx);
|
|
int test_outbound_cases(struct context *ctx);
|
|
int test_register_a(struct context *ctx);
|
|
int test_register_b(struct context *ctx);
|
|
int test_register_c(struct context *ctx);
|
|
int test_register_refresh(struct context *ctx);
|
|
|
|
int test_register_to_proxy(struct context *ctx)
|
|
{
|
|
return
|
|
test_clear_registrations(ctx) ||
|
|
test_outbound_cases(ctx) ||
|
|
test_register_a(ctx) ||
|
|
test_register_b(ctx) ||
|
|
test_register_c(ctx) ||
|
|
test_register_refresh(ctx);
|
|
}
|
|
|
|
int test_clear_registrations(struct context *ctx)
|
|
{
|
|
BEGIN();
|
|
|
|
struct endpoint *a = &ctx->a, *b = &ctx->b, *c = &ctx->c;
|
|
struct call *a_reg = a->reg, *b_reg = b->reg, *c_reg = c->reg;
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-2.3.0.1: un-REGISTER a\n");
|
|
|
|
TEST_1(a_reg->nh = nua_handle(a->nua, a_reg, TAG_END()));
|
|
UNREGISTER(a, a_reg, a_reg->nh, SIPTAG_TO(a->to),
|
|
SIPTAG_CONTACT_STR("*"),
|
|
TAG_END());
|
|
run_a_until(ctx, -1, until_final_response);
|
|
AUTHENTICATE(a, a_reg, a_reg->nh,
|
|
NUTAG_AUTH("Digest:\"test-proxy\":alice:secret"), TAG_END());
|
|
run_a_until(ctx, -1, until_final_response);
|
|
nua_handle_destroy(a_reg->nh);
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-2.3.0.1: PASSED\n");
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-2.3.0.2: un-REGISTER b\n");
|
|
|
|
TEST_1(b_reg->nh = nua_handle(b->nua, b_reg, TAG_END()));
|
|
UNREGISTER(b, b_reg, b_reg->nh, SIPTAG_TO(b->to),
|
|
SIPTAG_CONTACT_STR("*"),
|
|
TAG_END());
|
|
run_b_until(ctx, -1, until_final_response);
|
|
AUTHENTICATE(b, b_reg, b_reg->nh,
|
|
NUTAG_AUTH("Digest:\"test-proxy\":bob:secret"), TAG_END());
|
|
run_b_until(ctx, -1, until_final_response);
|
|
nua_handle_destroy(b_reg->nh);
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-2.3.0.2: PASSED\n");
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-2.3.0.3: un-REGISTER c\n");
|
|
|
|
TEST_1(c_reg->nh = nua_handle(c->nua, c_reg, TAG_END()));
|
|
UNREGISTER(c, c_reg, c_reg->nh,
|
|
SIPTAG_FROM(c->to), SIPTAG_TO(c->to),
|
|
SIPTAG_CONTACT_STR("*"),
|
|
TAG_END());
|
|
run_c_until(ctx, -1, until_final_response);
|
|
AUTHENTICATE(c, c_reg, c_reg->nh,
|
|
NUTAG_AUTH("Digest:\"test-proxy\":charlie:secret"), TAG_END());
|
|
run_c_until(ctx, -1, until_final_response);
|
|
nua_handle_destroy(c_reg->nh);
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-2.3.0.3: PASSED\n");
|
|
|
|
END();
|
|
}
|
|
|
|
int test_outbound_cases(struct context *ctx)
|
|
{
|
|
BEGIN();
|
|
|
|
#if 0
|
|
|
|
struct endpoint *a = &ctx->a, *x;
|
|
struct call *a_reg = a->reg;
|
|
struct event *e;
|
|
sip_t const *sip;
|
|
sip_contact_t m[1];
|
|
|
|
/* REGISTER test
|
|
|
|
A R
|
|
|------REGISTER----->|
|
|
|<-------401---------|
|
|
|------REGISTER----->|
|
|
|<-------200---------|
|
|
| |
|
|
|
|
*/
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-2.3.1: REGISTER a\n");
|
|
|
|
test_proxy_domain_set_expiration(ctx->a.domain, 5, 5, 10);
|
|
|
|
TEST_1(a_reg->nh = nua_handle(a->nua, a_reg, TAG_END()));
|
|
|
|
sip_contact_init(m);
|
|
m->m_display = "Lissu";
|
|
*m->m_url = *a->contact->m_url;
|
|
m->m_url->url_user = "a";
|
|
m->m_url->url_params = "transport=udp";
|
|
|
|
REGISTER(a, a_reg, a_reg->nh, SIPTAG_TO(a->to),
|
|
NUTAG_OUTBOUND("use-rport no-options-keepalive"),
|
|
SIPTAG_CONTACT(m),
|
|
TAG_END());
|
|
run_a_until(ctx, -1, save_until_final_response);
|
|
|
|
TEST_1(e = a->events->head);
|
|
TEST_E(e->data->e_event, nua_r_register);
|
|
TEST(e->data->e_status, 401);
|
|
TEST_1(sip = sip_object(e->data->e_msg));
|
|
TEST(sip->sip_status->st_status, 401);
|
|
TEST_1(!sip->sip_contact);
|
|
TEST_1(!e->next);
|
|
free_events_in_list(ctx, a->events);
|
|
|
|
AUTHENTICATE(a, a_reg, a_reg->nh,
|
|
NUTAG_AUTH("Digest:\"test-proxy\":alice:secret"), TAG_END());
|
|
run_a_until(ctx, -1, save_until_final_response);
|
|
|
|
TEST_1(e = a->events->head);
|
|
TEST_E(e->data->e_event, nua_r_register);
|
|
TEST(e->data->e_status, 200);
|
|
TEST_1(sip = sip_object(e->data->e_msg));
|
|
TEST_1(sip->sip_contact);
|
|
TEST_S(sip->sip_contact->m_display, "Lissu");
|
|
TEST_S(sip->sip_contact->m_url->url_user, "a");
|
|
TEST_1(strstr(sip->sip_contact->m_url->url_params, "transport=udp"));
|
|
|
|
if (ctx->nat) {
|
|
TEST_1(e = a->specials->head);
|
|
}
|
|
|
|
test_proxy_domain_set_expiration(ctx->a.domain, 600, 3600, 36000);
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-2.3.1: PASSED\n");
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-2.3.4: refresh REGISTER\n");
|
|
|
|
if (!ctx->p) {
|
|
free_events_in_list(ctx, a->events);
|
|
return 0;
|
|
}
|
|
|
|
/* Wait for A to refresh its registrations */
|
|
|
|
/*
|
|
* Avoid race condition: if X has already refreshed registration
|
|
* with expiration time of 3600 seconds, do not wait for new refresh
|
|
*/
|
|
a->next_condition = save_until_final_response;
|
|
|
|
for (x = a; x; x = NULL) {
|
|
for (e = x->events->head; e; e = e->next) {
|
|
if (e->data->e_event == nua_r_register &&
|
|
e->data->e_status == 200 &&
|
|
(sip = sip_object(e->data->e_msg)) &&
|
|
sip->sip_contact &&
|
|
sip->sip_contact->m_expires &&
|
|
strcmp(sip->sip_contact->m_expires, "3600") == 0) {
|
|
x->next_condition = NULL;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
run_a_until(ctx, -1, a->next_condition);
|
|
|
|
for (e = a->events->head; e; e = e->next) {
|
|
TEST_E(e->data->e_event, nua_r_register);
|
|
TEST(e->data->e_status, 200);
|
|
TEST_1(sip = sip_object(e->data->e_msg));
|
|
TEST_1(sip->sip_contact);
|
|
if (!e->next)
|
|
break;
|
|
}
|
|
TEST_1(e);
|
|
TEST_1(sip = sip_object(e->data->e_msg));
|
|
TEST_S(sip->sip_contact->m_expires, "3600");
|
|
TEST_1(!e->next);
|
|
free_events_in_list(ctx, a->events);
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-2.3.4: PASSED\n");
|
|
|
|
TEST_1(0);
|
|
|
|
#endif
|
|
|
|
END();
|
|
}
|
|
|
|
int test_register_a(struct context *ctx)
|
|
{
|
|
BEGIN();
|
|
|
|
struct endpoint *a = &ctx->a;
|
|
struct call *a_reg = a->reg;
|
|
struct event *e;
|
|
sip_t const *sip;
|
|
sip_cseq_t cseq[1];
|
|
|
|
/* REGISTER test
|
|
|
|
A R
|
|
|------REGISTER----->|
|
|
|<-------401---------|
|
|
|------REGISTER----->|
|
|
|<-------200---------|
|
|
| |
|
|
|
|
*/
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-2.3.1: REGISTER a\n");
|
|
|
|
test_proxy_domain_set_expiration(ctx->a.domain, 5, 5, 10);
|
|
|
|
TEST_1(a_reg->nh = nua_handle(a->nua, a_reg, TAG_END()));
|
|
|
|
sip_cseq_init(cseq)->cs_seq = 12;
|
|
cseq->cs_method = sip_method_register;
|
|
cseq->cs_method_name = sip_method_name_register;
|
|
|
|
REGISTER(a, a_reg, a_reg->nh, SIPTAG_TO(a->to),
|
|
NUTAG_OUTBOUND("natify options-keepalive validate"),
|
|
NUTAG_KEEPALIVE(1000),
|
|
NUTAG_M_DISPLAY("A&A"),
|
|
NUTAG_M_USERNAME("a"),
|
|
NUTAG_M_PARAMS("foo=bar"),
|
|
NUTAG_M_FEATURES("q=0.9"),
|
|
SIPTAG_CSEQ(cseq),
|
|
TAG_END());
|
|
run_a_until(ctx, -1, save_until_final_response);
|
|
|
|
TEST_1(e = a->events->head);
|
|
TEST_1(sip = sip_object(e->data->e_msg));
|
|
if (ctx->nat && e->data->e_status == 100) {
|
|
TEST_E(e->data->e_event, nua_r_register);
|
|
TEST(e->data->e_status, 100);
|
|
TEST(sip->sip_status->st_status, 406);
|
|
/* Check that CSeq included in tags is actually used in the request */
|
|
TEST(sip->sip_cseq->cs_seq, 13);
|
|
TEST_1(!sip->sip_contact);
|
|
TEST_1(e = e->next);
|
|
TEST_1(sip = sip_object(e->data->e_msg));
|
|
TEST(sip->sip_cseq->cs_seq, 14);
|
|
}
|
|
else {
|
|
/* Check that CSeq included in tags is actually used in the request */
|
|
TEST(sip->sip_cseq->cs_seq, 13);
|
|
}
|
|
TEST_E(e->data->e_event, nua_r_register);
|
|
TEST(e->data->e_status, 401);
|
|
TEST(sip->sip_status->st_status, 401);
|
|
TEST_1(!sip->sip_contact);
|
|
TEST_1(!e->next);
|
|
free_events_in_list(ctx, a->events);
|
|
|
|
AUTHENTICATE(a, a_reg, a_reg->nh,
|
|
NUTAG_AUTH("Digest:\"test-proxy\":alice:secret"), TAG_END());
|
|
run_a_until(ctx, -1, save_until_final_response);
|
|
|
|
TEST_1(e = a->events->head);
|
|
TEST_E(e->data->e_event, nua_r_register);
|
|
TEST(e->data->e_status, 200);
|
|
TEST_1(sip = sip_object(e->data->e_msg));
|
|
TEST_1(sip->sip_contact);
|
|
{ char const *expect_m_display = "\"A&A\"";
|
|
/* VC does not dig \" with TEST_S() */
|
|
TEST_S(sip->sip_contact->m_display, expect_m_display); }
|
|
TEST_S(sip->sip_contact->m_url->url_user, "a");
|
|
TEST_1(strstr(sip->sip_contact->m_url->url_params, "foo=bar"));
|
|
TEST_S(sip->sip_contact->m_q, "0.9");
|
|
|
|
if (ctx->nat) {
|
|
TEST_1(e = a->specials->head);
|
|
}
|
|
|
|
test_proxy_domain_set_expiration(ctx->a.domain, 600, 3600, 36000);
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-2.3.1: PASSED\n");
|
|
|
|
END();
|
|
}
|
|
|
|
int test_register_b(struct context *ctx)
|
|
{
|
|
BEGIN();
|
|
|
|
struct endpoint *b = &ctx->b;
|
|
struct call *b_reg = b->reg;
|
|
struct event *e;
|
|
sip_t const *sip;
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-2.3.2: REGISTER b\n");
|
|
|
|
test_proxy_domain_set_expiration(ctx->b.domain, 5, 5, 10);
|
|
|
|
TEST_1(b_reg->nh = nua_handle(b->nua, b_reg, TAG_END()));
|
|
|
|
/* Test application-supplied contact */
|
|
{
|
|
sip_contact_t m[1];
|
|
sip_contact_init(m)->m_url[0] = b->contact->m_url[0];
|
|
|
|
m->m_display = "B";
|
|
m->m_url->url_user = "b";
|
|
|
|
/* Include "tcp" transport parameter in Contact */
|
|
if (ctx->p)
|
|
m->m_url->url_params = "transport=tcp";
|
|
|
|
REGISTER(b, b_reg, b_reg->nh, SIPTAG_TO(b->to),
|
|
SIPTAG_CONTACT(m),
|
|
/* Do not include credentials unless challenged */
|
|
NUTAG_AUTH_CACHE(nua_auth_cache_challenged),
|
|
TAG_END());
|
|
}
|
|
run_ab_until(ctx, -1, save_events, -1, save_until_final_response);
|
|
|
|
TEST_1(e = b->events->head);
|
|
TEST_E(e->data->e_event, nua_r_register);
|
|
TEST_1(sip = sip_object(e->data->e_msg));
|
|
TEST(e->data->e_status, 401);
|
|
TEST(sip->sip_status->st_status, 401);
|
|
TEST_1(!sip->sip_contact);
|
|
TEST_1(!e->next);
|
|
free_events_in_list(ctx, b->events);
|
|
|
|
AUTHENTICATE(b, b_reg, b_reg->nh,
|
|
NUTAG_AUTH("Digest:\"test-proxy\":bob:secret"), TAG_END());
|
|
run_ab_until(ctx, -1, save_events, -1, save_until_final_response);
|
|
|
|
TEST_1(e = b->events->head);
|
|
TEST_E(e->data->e_event, nua_r_register);
|
|
TEST(e->data->e_status, 200);
|
|
TEST_1(sip = sip_object(e->data->e_msg));
|
|
TEST_1(sip->sip_contact);
|
|
TEST_S(sip->sip_contact->m_display, "B");
|
|
TEST_S(sip->sip_contact->m_url->url_user, "b");
|
|
free_events_in_list(ctx, b->events);
|
|
|
|
test_proxy_domain_set_expiration(ctx->b.domain, 600, 3600, 36000);
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-2.3.2: PASSED\n");
|
|
|
|
END();
|
|
}
|
|
|
|
int test_register_c(struct context *ctx)
|
|
{
|
|
BEGIN();
|
|
|
|
struct endpoint *c = &ctx->c;
|
|
struct call *c_reg = c->reg;
|
|
struct event *e;
|
|
sip_t const *sip;
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-2.3.3: REGISTER c\n");
|
|
|
|
test_proxy_domain_set_expiration(ctx->c.domain, 600, 3600, 36000);
|
|
test_proxy_domain_set_authorize(ctx->c.domain, "test-proxy-0");
|
|
|
|
TEST_1(c_reg->nh = nua_handle(c->nua, c_reg, TAG_END()));
|
|
|
|
REGISTER(c, c_reg, c_reg->nh, SIPTAG_TO(c->to),
|
|
SIPTAG_FROM(c->to),
|
|
NUTAG_OUTBOUND(NULL),
|
|
NUTAG_M_DISPLAY("C"),
|
|
NUTAG_M_USERNAME("c"),
|
|
NUTAG_M_PARAMS("c=1"),
|
|
NUTAG_M_FEATURES("q=0.987;expires=5"),
|
|
NUTAG_CALLEE_CAPS(1),
|
|
SIPTAG_EXPIRES_STR("5"), /* Test 423 negotiation */
|
|
TAG_END());
|
|
run_abc_until(ctx, -1, save_events, -1, save_events,
|
|
-1, save_until_final_response);
|
|
|
|
TEST_1(e = c->events->head);
|
|
TEST_E(e->data->e_event, nua_r_register);
|
|
TEST_1(sip = sip_object(e->data->e_msg));
|
|
TEST(e->data->e_status, 401);
|
|
TEST(sip->sip_status->st_status, 401);
|
|
TEST_1(!sip->sip_contact);
|
|
TEST_1(!e->next);
|
|
free_events_in_list(ctx, c->events);
|
|
|
|
AUTHENTICATE(c, c_reg, c_reg->nh,
|
|
NUTAG_AUTH("Digest:\"test-proxy-0\":charlie:secret"), TAG_END());
|
|
run_abc_until(ctx, -1, save_events, -1, save_events,
|
|
-1, save_until_final_response);
|
|
|
|
TEST_1(e = c->events->head);
|
|
TEST_E(e->data->e_event, nua_r_register);
|
|
TEST(e->data->e_status, 100);
|
|
TEST_1(sip = sip_object(e->data->e_msg));
|
|
TEST(sip->sip_status->st_status, 423);
|
|
TEST_1(e = e->next);
|
|
if (e->data->e_status == 100 && e->data->e_event == nua_r_register) {
|
|
TEST_1(sip = sip_object(e->data->e_msg));
|
|
TEST(sip->sip_status->st_status, 401);
|
|
TEST_1(e = e->next);
|
|
}
|
|
TEST(e->data->e_status, 200); TEST_E(e->data->e_event, nua_r_register);
|
|
TEST_1(sip = sip_object(e->data->e_msg));
|
|
TEST_1(sip->sip_contact);
|
|
TEST_S(sip->sip_contact->m_display, "C");
|
|
TEST_S(sip->sip_contact->m_url->url_user, "c");
|
|
TEST_1(strstr(sip->sip_contact->m_url->url_params, "c=1"));
|
|
TEST_S(sip->sip_contact->m_q, "0.987");
|
|
TEST_1(msg_header_find_param(sip->sip_contact->m_common, "methods="));
|
|
TEST_1(!e->next);
|
|
free_events_in_list(ctx, c->events);
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-2.3.3: PASSED\n");
|
|
|
|
END();
|
|
}
|
|
|
|
int test_register_refresh(struct context *ctx)
|
|
{
|
|
BEGIN();
|
|
|
|
struct endpoint *a = &ctx->a, *b = &ctx->b, *x;
|
|
struct event *e;
|
|
sip_t const *sip;
|
|
int seen_401;
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-2.3.4: refresh REGISTER\n");
|
|
|
|
if (!ctx->p) {
|
|
free_events_in_list(ctx, a->events);
|
|
free_events_in_list(ctx, b->events);
|
|
return 0;
|
|
}
|
|
|
|
/* Wait for A and B to refresh their registrations */
|
|
|
|
/*
|
|
* Avoid race condition: if X has already refreshed registration
|
|
* with expiration time of 3600 seconds, do not wait for new refresh
|
|
*/
|
|
a->next_condition = save_until_final_response;
|
|
b->next_condition = save_until_final_response;
|
|
|
|
for (x = a; x; x = x == a ? b : NULL) {
|
|
for (e = x->events->head; e; e = e->next) {
|
|
if (e->data->e_event == nua_r_register &&
|
|
e->data->e_status == 200 &&
|
|
(sip = sip_object(e->data->e_msg)) &&
|
|
sip->sip_contact &&
|
|
sip->sip_contact->m_expires &&
|
|
strcmp(sip->sip_contact->m_expires, "3600") == 0) {
|
|
x->next_condition = NULL;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
run_ab_until(ctx, -1, a->next_condition, -1, b->next_condition);
|
|
|
|
for (e = a->events->head; e; e = e->next) {
|
|
TEST_E(e->data->e_event, nua_r_register);
|
|
TEST(e->data->e_status, 200);
|
|
TEST_1(sip = sip_object(e->data->e_msg));
|
|
TEST_1(sip->sip_contact);
|
|
if (!e->next)
|
|
break;
|
|
}
|
|
TEST_1(e);
|
|
TEST_1(sip = sip_object(e->data->e_msg));
|
|
TEST_S(sip->sip_contact->m_expires, "3600");
|
|
TEST_1(!e->next);
|
|
free_events_in_list(ctx, a->events);
|
|
|
|
seen_401 = 0;
|
|
|
|
for (e = b->events->head; e; e = e->next) {
|
|
TEST_E(e->data->e_event, nua_r_register);
|
|
TEST_1(sip = sip_object(e->data->e_msg));
|
|
|
|
if (e->data->e_status == 200) {
|
|
TEST(e->data->e_status, 200);
|
|
TEST_1(seen_401);
|
|
TEST_1(sip->sip_contact);
|
|
}
|
|
else if (sip->sip_status && sip->sip_status->st_status == 401) {
|
|
seen_401 = 1;
|
|
}
|
|
|
|
if (!e->next)
|
|
break;
|
|
}
|
|
TEST_1(e);
|
|
TEST_S(sip->sip_contact->m_expires, "3600");
|
|
TEST_1(!e->next);
|
|
free_events_in_list(ctx, b->events);
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-2.3.4: PASSED\n");
|
|
|
|
if (!ctx->p)
|
|
return 0;
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-2.3.5: re-REGISTER when TCP connection is closed\n");
|
|
|
|
test_proxy_close_tports(ctx->p);
|
|
|
|
run_b_until(ctx, -1, save_until_final_response);
|
|
|
|
TEST_1(e = b->events->head);
|
|
TEST_E(e->data->e_event, nua_r_register);
|
|
if (e->data->e_status == 100)
|
|
TEST_1(e = e->next);
|
|
TEST_1(sip = sip_object(e->data->e_msg));
|
|
TEST_1(sip->sip_contact);
|
|
TEST_S(sip->sip_contact->m_expires, "3600");
|
|
TEST_1(!e->next);
|
|
|
|
free_events_in_list(ctx, b->events);
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-2.3.5: PASSED\n");
|
|
|
|
END();
|
|
}
|
|
|
|
int registrar_299(CONDITION_PARAMS)
|
|
{
|
|
msg_t *request = nua_current_request(nua);
|
|
|
|
save_event_in_list(ctx, event, ep, ep->call);
|
|
|
|
if (event == nua_i_register) {
|
|
RESPOND(ep, call, nh, 299, "YES", NUTAG_WITH(request), TAG_END());
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int test_register_to_c(struct context *ctx)
|
|
{
|
|
BEGIN();
|
|
|
|
struct endpoint *b = &ctx->b, *c = &ctx->c;
|
|
struct call *b_call = b->call, *c_call = c->call;
|
|
struct event *e;
|
|
sip_t const *sip;
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-2.6.1: REGISTER b to c\n");
|
|
|
|
nua_set_params(ctx->c.nua,
|
|
NUTAG_ALLOW("REGISTER"),
|
|
TAG_END());
|
|
run_c_until(ctx, nua_r_set_params, until_final_response);
|
|
|
|
TEST_1(b_call->nh = nua_handle(b->nua, b_call, TAG_END()));
|
|
|
|
REGISTER(b, b_call, b_call->nh,
|
|
NUTAG_REGISTRAR((url_string_t *)c->contact->m_url),
|
|
SIPTAG_TO(b->to),
|
|
NUTAG_OUTBOUND(NULL),
|
|
SIPTAG_CONTACT_STR(NULL),
|
|
TAG_END());
|
|
run_bc_until(ctx, -1, save_until_final_response, -1, registrar_299);
|
|
|
|
TEST_1(e = b->events->head);
|
|
TEST_E(e->data->e_event, nua_r_register);
|
|
TEST(e->data->e_status, 299);
|
|
TEST_1(sip = sip_object(e->data->e_msg));
|
|
TEST_1(!sip->sip_contact);
|
|
|
|
free_events_in_list(ctx, b->events);
|
|
nua_handle_destroy(b_call->nh), b_call->nh = NULL;
|
|
|
|
TEST_1(e = c->events->head);
|
|
TEST_E(e->data->e_event, nua_i_register);
|
|
TEST(e->data->e_status, 100);
|
|
TEST_1(sip = sip_object(e->data->e_msg));
|
|
TEST_1(!sip->sip_contact);
|
|
|
|
free_events_in_list(ctx, c->events);
|
|
nua_handle_destroy(c_call->nh), c_call->nh = NULL;
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-2.6.1: PASSED\n");
|
|
|
|
END();
|
|
}
|
|
|
|
|
|
int test_register(struct context *ctx)
|
|
{
|
|
if (test_register_to_c(ctx))
|
|
return 1;
|
|
|
|
if (ctx->proxy_tests)
|
|
if (test_register_to_proxy(ctx)) return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int test_connectivity(struct context *ctx)
|
|
{
|
|
if (!ctx->proxy_tests)
|
|
return 0; /* No proxy */
|
|
|
|
BEGIN();
|
|
|
|
struct endpoint *a = &ctx->a, *b = &ctx->b, *c = &ctx->c;
|
|
struct call *a_call = a->call, *b_call = b->call, *c_call = c->call;
|
|
struct event *e;
|
|
sip_t const *sip;
|
|
|
|
/* Connectivity test using OPTIONS */
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-2.4.1: OPTIONS from A to B\n");
|
|
|
|
TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
|
|
|
|
OPTIONS(a, a_call, a_call->nh,
|
|
TAG_IF(!ctx->proxy_tests, NUTAG_URL(b->contact->m_url)),
|
|
NUTAG_ALLOW("OPTIONS"),
|
|
TAG_END());
|
|
|
|
run_ab_until(ctx, -1, save_until_final_response, -1, save_until_received);
|
|
|
|
/* Client events: nua_options(), nua_r_options */
|
|
TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_r_options);
|
|
TEST(e->data->e_status, 200);
|
|
TEST_1(sip = sip_object(e->data->e_msg));
|
|
TEST_1(sip->sip_allow); TEST_1(sip->sip_accept); TEST_1(sip->sip_supported);
|
|
/* TEST_1(sip->sip_content_type); */
|
|
/* TEST_1(sip->sip_payload); */
|
|
TEST_1(!e->next);
|
|
|
|
free_events_in_list(ctx, a->events);
|
|
nua_handle_destroy(a_call->nh), a_call->nh = NULL;
|
|
|
|
/* Server events: nua_i_options */
|
|
TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_options);
|
|
TEST(e->data->e_status, 200);
|
|
TEST_1(!e->next);
|
|
|
|
free_events_in_list(ctx, b->events);
|
|
nua_handle_destroy(b_call->nh), b_call->nh = NULL;
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-2.4.1: PASSED\n");
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-2.4.2: OPTIONS from B to C\n");
|
|
|
|
TEST_1(b_call->nh = nua_handle(b->nua, b_call, SIPTAG_TO(c->to), TAG_END()));
|
|
|
|
OPTIONS(b, b_call, b_call->nh,
|
|
TAG_IF(!ctx->proxy_tests, NUTAG_URL(c->contact->m_url)),
|
|
TAG_END());
|
|
|
|
run_abc_until(ctx, -1, NULL,
|
|
-1, save_until_final_response,
|
|
-1, save_until_received);
|
|
|
|
/* Client events: nua_options(), nua_r_options */
|
|
TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_r_options);
|
|
TEST(e->data->e_status, 200);
|
|
TEST_1(sip = sip_object(e->data->e_msg));
|
|
TEST_1(sip->sip_allow); TEST_1(sip->sip_accept); TEST_1(sip->sip_supported);
|
|
/* TEST_1(sip->sip_content_type); */
|
|
/* TEST_1(sip->sip_payload); */
|
|
TEST_1(!e->next);
|
|
|
|
free_events_in_list(ctx, b->events);
|
|
nua_handle_destroy(b_call->nh), b_call->nh = NULL;
|
|
|
|
/* Server events: nua_i_options */
|
|
TEST_1(e = c->events->head); TEST_E(e->data->e_event, nua_i_options);
|
|
TEST(e->data->e_status, 200);
|
|
TEST_1(!e->next);
|
|
|
|
free_events_in_list(ctx, c->events);
|
|
nua_handle_destroy(c_call->nh), c_call->nh = NULL;
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-2.4.2: PASSED\n");
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-2.4.3: OPTIONS from C to A\n");
|
|
|
|
TEST_1(c_call->nh = nua_handle(c->nua, c_call, SIPTAG_TO(a->to), TAG_END()));
|
|
|
|
OPTIONS(c, c_call, c_call->nh,
|
|
SIPTAG_FROM(c->to),
|
|
TAG_IF(!ctx->proxy_tests, NUTAG_URL(a->contact->m_url)),
|
|
TAG_END());
|
|
|
|
if (ctx->proxy_tests) {
|
|
run_abc_until(ctx, -1, NULL, -1, NULL, -1, save_until_final_response);
|
|
|
|
/* Client events: nua_options(), nua_r_options */
|
|
TEST_1(e = c->events->head); TEST_E(e->data->e_event, nua_r_options);
|
|
TEST(e->data->e_status, 407);
|
|
TEST_1(!e->next);
|
|
|
|
free_events_in_list(ctx, c->events);
|
|
|
|
/* Sneakily change the realm */
|
|
|
|
TEST(test_proxy_domain_set_authorize(ctx->c.domain, "test-proxy"), 0);
|
|
|
|
AUTHENTICATE(c, c_call, c_call->nh,
|
|
NUTAG_AUTH("Digest:\"test-proxy-0\":charlie:secret"),
|
|
TAG_END());
|
|
|
|
run_abc_until(ctx, -1, NULL, -1, NULL, -1, save_until_final_response);
|
|
|
|
/* Client events: nua_options(), nua_r_options */
|
|
TEST_1(e = c->events->head); TEST_E(e->data->e_event, nua_r_options);
|
|
TEST(e->data->e_status, 407);
|
|
TEST_1(!e->next);
|
|
|
|
free_events_in_list(ctx, c->events);
|
|
|
|
AUTHENTICATE(c, c_call, c_call->nh,
|
|
NUTAG_AUTH("Digest:\"test-proxy\":charlie:secret"),
|
|
TAG_END());
|
|
}
|
|
|
|
run_abc_until(ctx, -1, save_until_received,
|
|
-1, NULL,
|
|
-1, save_until_final_response);
|
|
|
|
/* Client events: nua_options(), nua_r_options */
|
|
TEST_1(e = c->events->head); TEST_E(e->data->e_event, nua_r_options);
|
|
TEST(e->data->e_status, 200);
|
|
TEST_1(sip = sip_object(e->data->e_msg));
|
|
TEST_1(sip->sip_allow); TEST_1(sip->sip_accept); TEST_1(sip->sip_supported);
|
|
/* TEST_1(sip->sip_content_type); */
|
|
/* TEST_1(sip->sip_payload); */
|
|
TEST_1(!e->next);
|
|
|
|
free_events_in_list(ctx, c->events);
|
|
nua_handle_destroy(c_call->nh), c_call->nh = NULL;
|
|
|
|
/* Server events: nua_i_options */
|
|
TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_options);
|
|
TEST(e->data->e_status, 200);
|
|
TEST_1(!e->next);
|
|
|
|
free_events_in_list(ctx, a->events);
|
|
nua_handle_destroy(a_call->nh), a_call->nh = NULL;
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-2.4.3: PASSED\n");
|
|
|
|
END();
|
|
}
|
|
|
|
int test_nat_timeout(struct context *ctx)
|
|
{
|
|
if (!ctx->proxy_tests || !ctx->nat)
|
|
return 0; /* No proxy */
|
|
|
|
BEGIN();
|
|
|
|
struct endpoint *a = &ctx->a, *b = &ctx->b;
|
|
struct call *a_call = a->call, *b_call = b->call;
|
|
struct event *e;
|
|
sip_t const *sip;
|
|
|
|
/* Test what happens when NAT bindings go away */
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-2.5.1: NAT binding change\n");
|
|
|
|
free_events_in_list(ctx, a->specials);
|
|
|
|
test_nat_flush(ctx->nat); /* Break our connections */
|
|
|
|
/* Run until we get final response to REGISTER */
|
|
run_a_until(ctx, -1, save_until_final_response);
|
|
|
|
TEST_1(e = a->specials->head);
|
|
TEST_E(e->data->e_event, nua_i_outbound);
|
|
TEST(e->data->e_status, 102);
|
|
TEST_S(e->data->e_phrase, "NAT binding changed");
|
|
TEST_1(!e->next);
|
|
|
|
free_events_in_list(ctx, a->specials);
|
|
|
|
TEST_1(e = a->events->head);
|
|
TEST_E(e->data->e_event, nua_r_register);
|
|
TEST(e->data->e_status, 200);
|
|
TEST_1(!e->next);
|
|
|
|
free_events_in_list(ctx, a->events);
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-2.5.1: PASSED\n");
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-2.5.2: OPTIONS from B to A\n");
|
|
|
|
TEST_1(b_call->nh = nua_handle(b->nua, b_call, SIPTAG_TO(a->to), TAG_END()));
|
|
|
|
OPTIONS(b, b_call, b_call->nh, TAG_END());
|
|
|
|
run_ab_until(ctx, -1, save_until_received,
|
|
-1, save_until_final_response);
|
|
|
|
/* Client events: nua_options(), nua_r_options */
|
|
TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_r_options);
|
|
TEST(e->data->e_status, 200);
|
|
TEST_1(sip = sip_object(e->data->e_msg));
|
|
TEST_1(sip->sip_allow); TEST_1(sip->sip_accept); TEST_1(sip->sip_supported);
|
|
/* TEST_1(sip->sip_content_type); */
|
|
/* TEST_1(sip->sip_payload); */
|
|
TEST_1(!e->next);
|
|
|
|
free_events_in_list(ctx, b->events);
|
|
nua_handle_destroy(b_call->nh), b_call->nh = NULL;
|
|
|
|
/* Server events: nua_i_options */
|
|
TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_options);
|
|
TEST(e->data->e_status, 200);
|
|
TEST_1(!e->next);
|
|
|
|
free_events_in_list(ctx, a->events);
|
|
nua_handle_destroy(a_call->nh), a_call->nh = NULL;
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-2.5.2: PASSED\n");
|
|
|
|
END();
|
|
}
|
|
|
|
int test_unregister(struct context *ctx)
|
|
{
|
|
if (!ctx->proxy_tests)
|
|
return 0; /* No proxy */
|
|
|
|
BEGIN();
|
|
|
|
struct endpoint *a = &ctx->a, *b = &ctx->b, *c = &ctx->c;
|
|
struct event *e;
|
|
sip_t const *sip;
|
|
|
|
/* un-REGISTER test
|
|
|
|
A B
|
|
|----un-REGISTER---->|
|
|
|<-------200---------|
|
|
| |
|
|
|
|
*/
|
|
if (print_headings)
|
|
printf("TEST NUA-13.1: un-REGISTER a\n");
|
|
|
|
if (a->reg->nh) {
|
|
free_events_in_list(ctx, a->events);
|
|
UNREGISTER(a, NULL, a->reg->nh, TAG_END());
|
|
run_a_until(ctx, -1, save_until_final_response);
|
|
TEST_1(e = a->events->head);
|
|
TEST_E(e->data->e_event, nua_r_unregister);
|
|
if (e->data->e_status == 100) {
|
|
TEST_1(e = e->next);
|
|
TEST_E(e->data->e_event, nua_r_unregister);
|
|
}
|
|
TEST(e->data->e_status, 200);
|
|
TEST_1(sip = sip_object(e->data->e_msg));
|
|
TEST_1(!sip->sip_contact);
|
|
TEST_1(!e->next);
|
|
free_events_in_list(ctx, a->events);
|
|
nua_handle_destroy(a->reg->nh), a->reg->nh = NULL;
|
|
}
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-13.1: PASSED\n");
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-13.2: un-REGISTER b\n");
|
|
|
|
if (b->reg->nh) {
|
|
free_events_in_list(ctx, b->events);
|
|
UNREGISTER(b, NULL, b->reg->nh, TAG_END());
|
|
run_b_until(ctx, -1, save_until_final_response);
|
|
TEST_1(e = b->events->head);
|
|
TEST_E(e->data->e_event, nua_r_unregister);
|
|
if (e->data->e_status == 100) {
|
|
TEST_1(e = e->next);
|
|
TEST_E(e->data->e_event, nua_r_unregister);
|
|
}
|
|
TEST(e->data->e_status, 200);
|
|
TEST_1(sip = sip_object(e->data->e_msg));
|
|
TEST_1(!sip->sip_contact);
|
|
TEST_1(!e->next);
|
|
free_events_in_list(ctx, b->events);
|
|
nua_handle_destroy(b->reg->nh), b->reg->nh = NULL;
|
|
}
|
|
if (print_headings)
|
|
printf("TEST NUA-13.2: PASSED\n");
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-13.3: un-REGISTER c\n");
|
|
|
|
/* Unregister using another handle */
|
|
free_events_in_list(ctx, c->events);
|
|
TEST_1(c->call->nh = nua_handle(c->nua, c->call, TAG_END()));
|
|
UNREGISTER(c, c->call, c->call->nh, SIPTAG_TO(c->to), SIPTAG_FROM(c->to),
|
|
NUTAG_M_DISPLAY("C"),
|
|
NUTAG_M_USERNAME("c"),
|
|
NUTAG_M_PARAMS("c=1"),
|
|
TAG_END());
|
|
run_c_until(ctx, -1, save_until_final_response);
|
|
|
|
TEST_1(e = c->events->head);
|
|
TEST_E(e->data->e_event, nua_r_unregister);
|
|
TEST_1(sip = sip_object(e->data->e_msg));
|
|
TEST(e->data->e_status, 401);
|
|
TEST(sip->sip_status->st_status, 401);
|
|
TEST_1(!sip->sip_contact);
|
|
TEST_1(!e->next);
|
|
free_events_in_list(ctx, c->events);
|
|
|
|
AUTHENTICATE(c, c->call, c->call->nh,
|
|
NUTAG_AUTH("Digest:\"test-proxy\":charlie:secret"), TAG_END());
|
|
run_c_until(ctx, -1, save_until_final_response);
|
|
|
|
TEST_1(e = c->events->head);
|
|
TEST_E(e->data->e_event, nua_r_unregister);
|
|
TEST(e->data->e_status, 200);
|
|
TEST_1(sip = sip_object(e->data->e_msg));
|
|
TEST_1(!sip->sip_contact);
|
|
TEST_1(!e->next);
|
|
free_events_in_list(ctx, c->events);
|
|
nua_handle_destroy(c->call->nh), c->call->nh = NULL;
|
|
|
|
if (c->reg->nh) {
|
|
UNREGISTER(c, NULL, c->reg->nh, TAG_END());
|
|
run_c_until(ctx, -1, save_until_final_response);
|
|
TEST_1(e = c->events->head);
|
|
TEST_E(e->data->e_event, nua_r_unregister);
|
|
if (e->data->e_status == 100) {
|
|
TEST_1(e = e->next);
|
|
TEST_E(e->data->e_event, nua_r_unregister);
|
|
}
|
|
if (e->data->e_status == 401) {
|
|
TEST_1(!e->next);
|
|
free_events_in_list(ctx, c->events);
|
|
AUTHENTICATE(c, NULL, c->reg->nh,
|
|
NUTAG_AUTH("Digest:\"test-proxy\":charlie:secret"), TAG_END());
|
|
run_c_until(ctx, -1, save_until_final_response);
|
|
TEST_1(e = c->events->head);
|
|
TEST_E(e->data->e_event, nua_r_unregister);
|
|
}
|
|
TEST(e->data->e_status, 200);
|
|
TEST_1(sip = sip_object(e->data->e_msg));
|
|
TEST_1(sip->sip_from->a_url->url_user);
|
|
TEST_1(!sip->sip_contact);
|
|
TEST_1(!e->next);
|
|
free_events_in_list(ctx, c->events);
|
|
nua_handle_destroy(c->reg->nh), c->reg->nh = NULL;
|
|
}
|
|
|
|
if (print_headings)
|
|
printf("TEST NUA-13.3: PASSED\n");
|
|
|
|
END();
|
|
}
|