📄 test_nta.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 * *//**@internal * @CFILE test_nta.c * * Test functions for NTA. * * @author Pekka Pessi <Pekka.Pessi@nokia.com> * * @date Created: Tue Aug 21 15:18:26 2001 ppessi */#include "config.h"typedef struct agent_t agent_t;#define SU_ROOT_MAGIC_T agent_t#include <sofia-sip/su_wait.h>#include <msg_internal.h>#define NTA_AGENT_MAGIC_T agent_t#define NTA_LEG_MAGIC_T agent_t#define NTA_OUTGOING_MAGIC_T agent_t#define NTA_INCOMING_MAGIC_T agent_t#define NTA_RELIABLE_MAGIC_T agent_t#include "sofia-sip/nta.h"#include "nta_internal.h"#include <sofia-sip/sip_header.h>#include <sofia-sip/sip_tag.h>#include <sofia-sip/sip_status.h>#include <sofia-sip/tport.h>#include <sofia-sip/htable.h>#include <sofia-sip/sresolv.h>#include <sofia-sip/su_log.h>#include <sofia-sip/sofia_features.h>#include <sofia-sip/string0.h>#include <stddef.h>#include <stdlib.h>#include <string.h>#include <limits.h>#include <stdio.h>#include <assert.h>#include <unistd.h>SOFIAPUBVAR su_log_t nta_log[];SOFIAPUBVAR su_log_t tport_log[];int tstflags = 0;#define TSTFLAGS tstflags#include <sofia-sip/tstdef.h>#if HAVE_FUNC#elif HAVE_FUNCTION#define __func__ __FUNCTION__#else#define __func__ name#endif#define NONE ((void *)-1)struct sigcomp_compartment;char const name[] = "test_nta";struct agent_t { su_home_t ag_home[1]; int ag_flags; su_root_t *ag_root; msg_mclass_t *ag_mclass; nta_agent_t *ag_agent; url_string_t *ag_obp; /**< Outbound proxy. */ nta_leg_t *ag_server_leg; /**< Leg for sip:%@% */ nta_leg_t *ag_default_leg; /**< Leg for rest */ unsigned ag_drop; nta_outgoing_t *ag_orq; int ag_status; char const *ag_comp; struct sigcomp_compartment *ag_client_compartment; /* Server side */ int ag_response; /**< What we answer by default */ nta_incoming_t *ag_irq; struct sigcomp_compartment *ag_server_compartment; char const *ag_m; sip_contact_t const *ag_contact; sip_from_t *ag_alice; sip_to_t *ag_bob; sip_contact_t *ag_m_alice; sip_contact_t *ag_m_bob; sip_contact_t *ag_aliases; nta_leg_t *ag_alice_leg; nta_leg_t *ag_bob_leg; msg_t *ag_request; nta_leg_t *ag_expect_leg; nta_leg_t *ag_latest_leg; nta_leg_t *ag_call_leg; nta_leg_t *ag_tag_remote; /**< If this is set, outgoing_callback() * tags it with the tag from remote. */ int ag_tag_status; /**< Which response established dialog */ msg_param_t ag_call_tag; /**< Tag used to establish dialog */ nta_reliable_t *ag_reliable; sip_via_t *ag_out_via; /**< Outgoing via */ sip_via_t *ag_in_via; /**< Incoming via */ sip_content_type_t *ag_content_type; sip_payload_t *ag_payload; msg_t *ag_probe_msg; /* Dummy servers */ char const *ag_sink_port; int ag_sink_socket; int ag_down_socket;};static int test_init(agent_t *ag, char const *resolv_conf);static int test_deinit(agent_t *ag);static int test_routing(agent_t *ag);static int test_tports(agent_t *ag);static int test_resolv(agent_t *ag, char const *resolv_conf);static int test_dialog(agent_t *ag);static int test_call(agent_t *ag);static int test_prack(agent_t *ag);static int test_fix_467(agent_t *ag);static int test_for_ack(agent_t *ag, nta_incoming_t *irq, sip_t const *sip);static int test_for_ack_or_timeout(agent_t *ag, nta_incoming_t *irq, sip_t const *sip);int agent_callback(agent_t *ag, nta_agent_t *nta, msg_t *msg, sip_t *sip){ if (tstflags & tst_verbatim) { if (sip->sip_request) { printf("%s: %s: %s " URL_PRINT_FORMAT " %s\n", name, __func__, sip->sip_request->rq_method_name, URL_PRINT_ARGS(sip->sip_request->rq_url), sip->sip_request->rq_version); } else { printf("%s: %s: %s %03d %s\n", name, __func__, sip->sip_status->st_version, sip->sip_status->st_status, sip->sip_status->st_phrase); } } msg_destroy(msg); return 0;}staticvoid leg_match(agent_t *ag, nta_leg_t *leg, int always, char const *func){ char const *match = "unknown leg"; if (!always && (tstflags & tst_verbatim) != tst_verbatim) return; if (leg == ag->ag_default_leg) match = "ag_default_leg"; else if (leg == ag->ag_server_leg) match = "ag_server_leg"; else if (leg == ag->ag_alice_leg) match = "ag_alice_leg"; else if (leg == ag->ag_bob_leg) match = "ag_bob_leg"; printf("%s: %s: %smatched with %s\n", name, func, always ? "mis" : "", match);}staticvoid leg_zap(agent_t *ag, nta_leg_t *leg){ if (leg == ag->ag_default_leg) ag->ag_default_leg = NULL; else if (leg == ag->ag_server_leg) ag->ag_server_leg = NULL; else if (leg == ag->ag_alice_leg) ag->ag_alice_leg = NULL; else if (leg == ag->ag_bob_leg) ag->ag_bob_leg = NULL; else printf("%s:%u: %s: did not exist\n", __FILE__, __LINE__, __func__); nta_leg_destroy(leg);}int leg_callback_200(agent_t *ag, nta_leg_t *leg, nta_incoming_t *irq, sip_t const *sip){ BEGIN(); if (tstflags & tst_verbatim) { printf("%s: %s: %s " URL_PRINT_FORMAT " %s\n", name, __func__, sip->sip_request->rq_method_name, URL_PRINT_ARGS(sip->sip_request->rq_url), sip->sip_request->rq_version); } TEST_1(sip->sip_content_length); TEST_1(sip->sip_via); TEST_1(sip->sip_from && sip->sip_from->a_tag); if (ag->ag_in_via == NULL) ag->ag_in_via = sip_via_dup(ag->ag_home, sip->sip_via); if (ag->ag_request == NULL) ag->ag_request = nta_incoming_getrequest(irq); ag->ag_latest_leg = leg; if (ag->ag_expect_leg && leg != ag->ag_expect_leg) { leg_match(ag, leg, 1, __func__); return 500; } leg_match(ag, leg, 0, __func__); if (sip->sip_request->rq_method == sip_method_bye) { leg_zap(ag, leg); } return 200; END();}int leg_callback_500(agent_t *ag, nta_leg_t *leg, nta_incoming_t *irq, sip_t const *sip){ if (tstflags & tst_verbatim) { printf("%s: %s: %s " URL_PRINT_FORMAT " %s\n", name, __func__, sip->sip_request->rq_method_name, URL_PRINT_ARGS(sip->sip_request->rq_url), sip->sip_request->rq_version); } return 500;}int new_leg_callback_200(agent_t *ag, nta_leg_t *leg, nta_incoming_t *irq, sip_t const *sip){ BEGIN(); if (tstflags & tst_verbatim) { printf("%s: %s: %s " URL_PRINT_FORMAT " %s\n", name, __func__, sip->sip_request->rq_method_name, URL_PRINT_ARGS(sip->sip_request->rq_url), sip->sip_request->rq_version); } TEST_1(sip->sip_content_length); TEST_1(sip->sip_via); TEST_1(sip->sip_from && sip->sip_from->a_tag); ag->ag_latest_leg = leg; if (ag->ag_expect_leg && leg != ag->ag_expect_leg) { leg_match(ag, leg, 1, __func__); return 500; } leg_match(ag, leg, 0, __func__); ag->ag_bob_leg = nta_leg_tcreate(ag->ag_agent, leg_callback_200, ag, URLTAG_URL(sip->sip_request->rq_url), SIPTAG_CALL_ID(sip->sip_call_id), SIPTAG_FROM(sip->sip_to), SIPTAG_TO(sip->sip_from), TAG_END()); TEST_1(ag->ag_bob_leg); TEST_1(nta_leg_tag(ag->ag_bob_leg, NULL)); TEST_1(nta_leg_get_tag(ag->ag_bob_leg)); TEST_1(nta_incoming_tag(irq, nta_leg_get_tag(ag->ag_bob_leg))); return 200; END();}int outgoing_callback(agent_t *ag, nta_outgoing_t *orq, sip_t const *sip){ BEGIN(); int status = sip->sip_status->st_status; if (tstflags & tst_verbatim) { printf("%s: %s: %s %03d %s\n", name, __func__, sip->sip_status->st_version, sip->sip_status->st_status, sip->sip_status->st_phrase); } TEST(orq, ag->ag_orq); ag->ag_status = status; if (status < 200) return 0; if (ag->ag_comp) { nta_compartment_decref(&ag->ag_client_compartment); ag->ag_client_compartment = nta_outgoing_compartment(orq); } if (ag->ag_out_via == NULL) ag->ag_out_via = sip_via_dup(ag->ag_home, sip->sip_via); if (ag->ag_tag_remote) { TEST_S(nta_leg_rtag(ag->ag_tag_remote, sip->sip_to->a_tag), sip->sip_to->a_tag); ag->ag_tag_remote = NULL; } TEST_1(sip->sip_to && sip->sip_to->a_tag); nta_outgoing_destroy(orq); ag->ag_orq = NULL; return 0; END();}staticint test_magic_branch(agent_t *ag, sip_t const *sip) { BEGIN(); if (sip) { TEST_1(sip->sip_via); TEST_S(sip->sip_via->v_branch, "MagicalBranch"); } END();}staticint magic_callback(agent_t *ag, nta_outgoing_t *orq, sip_t const *sip){ test_magic_branch(ag, sip); return outgoing_callback(ag, orq, sip);}void nta_test_run(agent_t *ag){ for (ag->ag_status = 0; ag->ag_status < 200;) { if (tstflags & tst_verbatim) { fputs(".", stdout); fflush(stdout); } su_root_step(ag->ag_root, 500L); }}#include <sofia-sip/msg_mclass.h>int test_init(agent_t *ag, char const *resolv_conf){ char const *contact = "sip:*:*;comp=sigcomp"; su_sockaddr_t su; socklen_t sulen; int s, af, sulen0; BEGIN(); TEST_1(ag->ag_root = su_root_create(ag)); TEST_1(ag->ag_mclass = msg_mclass_clone(sip_default_mclass(), 0, 0));#if SU_HAVE_IN6 if (str0cmp(getenv("ipv6"), "true") == 0) { contact = "sip:[::]:*;comp=sigcomp"; af = AF_INET6, sulen0 = sizeof (struct sockaddr_in6); } else { af = AF_INET, sulen0 = sizeof (struct sockaddr_in); contact = "sip:0.0.0.0:*;comp=sigcomp"; }#else af = AF_INET, sulen0 = sizeof (struct sockaddr_in); contact = "sip:0.0.0.0:*;comp=sigcomp";#endif if (ag->ag_m) contact = ag->ag_m; else if (getenv("SIPCONTACT")) contact = getenv("SIPCONTACT"); /* Sink server */ s = socket(af, SOCK_DGRAM, 0); TEST_1(s != -1); memset(&su, 0, sulen = sulen0); su.su_family = af; if (getenv("sink")) { su.su_port = htons(atoi(getenv("sink"))); } TEST_1(bind(s, &su.su_sa, sulen) < 0 ? (perror("bind"), 0) : 1); TEST_1(getsockname(s, &su.su_sa, &sulen) == 0); ag->ag_sink_port = su_sprintf(ag->ag_home, "%u", ntohs(su.su_sin.sin_port)); ag->ag_sink_socket = s; /* Down server */ s = socket(af, SOCK_STREAM, 0); TEST_1(s != -1); memset(&su, 0, sulen = sulen0); su.su_family = af; if (getenv("down")) { su.su_port = htons(atoi(getenv("down"))); } TEST_1(bind(s, &su.su_sa, sulen) < 0 ? (perror("bind"), 0) : 1); ag->ag_down_socket = s; /* Create agent */ TEST_1(ag->ag_agent = nta_agent_create(ag->ag_root, (url_string_t *)contact, NULL, NULL, NTATAG_MCLASS(ag->ag_mclass), NTATAG_USE_TIMESTAMP(1), SRESTAG_RESOLV_CONF(resolv_conf), NTATAG_USE_NAPTR(0), NTATAG_USE_SRV(0), NTATAG_PRELOAD(2048), TAG_END())); /* Create a default leg */ TEST_1(ag->ag_default_leg = nta_leg_tcreate(ag->ag_agent, leg_callback_200, ag, NTATAG_NO_DIALOG(1), TAG_END())); { /* Initialize our headers */ sip_from_t from[1]; sip_to_t to[1]; sip_contact_t m[1];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -