📄 test_tport.c
字号:
/* * This file is part of the Sofia-SIP package * * Copyright (C) 2006 Nokia Corporation. * * Contact: Pekka Pessi <pekka.pessi@nokia.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * *//**@CFILE tport_test.c * * Test functions for transports * * @internal * * @author Pekka Pessi <Pekka.Pessi@nokia.com> * * @date Created: Wed Apr 3 11:25:13 2002 ppessi *//* always assert()s */#undef NDEBUG#include "config.h"#include <stddef.h>#include <stdlib.h>#include <string.h>#include <limits.h>#include <stdio.h>#include <assert.h>typedef struct tp_test_s tp_test_t;#define TP_STACK_T tp_test_t#define TP_CLIENT_T struct called #include <sofia-sip/su_wait.h>#include <sofia-sip/su_md5.h>#include "tport_internal.h" /* Get SU_DEBUG_*() */#include "test_class.h"#include "test_protos.h"#include "sofia-sip/msg.h"#include "sofia-sip/msg_mclass.h"#include "sofia-sip/msg_addr.h"#if HAVE_SIGCOMP#include <sigcomp.h>#endif#include <sofia-sip/base64.h>#include <sofia-sip/su_log.h>#include "sofia-sip/tport.h"struct tp_test_s { su_home_t tt_home[1]; int tt_flags; su_root_t *tt_root; msg_mclass_t *tt_mclass; tport_t *tt_srv_tports; tport_t *tt_tports; tport_t *tt_rtport; tp_name_t tt_udp_name[1]; tp_name_t tt_udp_comp[1]; tp_name_t tt_tcp_name[1]; tp_name_t tt_tcp_comp[1]; tp_name_t tt_sctp_name[1]; tp_name_t tt_sctp_comp[1]; tp_name_t tt_tls_name[1]; tp_name_t tt_tls_comp[1];#if HAVE_SIGCOMP struct sigcomp_state_handler *state_handler; struct sigcomp_algorithm const *algorithm; struct sigcomp_compartment *master_cc;#define IF_SIGCOMP_TPTAG_COMPARTMENT(cc) TAG_IF(cc, TPTAG_COMPARTMENT(cc)),#else#define IF_SIGCOMP_TPTAG_COMPARTMENT(cc)#endif int tt_status; int tt_received; msg_t *tt_rmsg; uint8_t tt_digest[SU_MD5_DIGEST_SIZE]; su_addrinfo_t const *tt_tcp_addr; tport_t *tt_tcp;};int tstflags;#define TSTFLAGS tstflags#include <sofia-sip/tstdef.h>char const name[] = "tport_test";SOFIAPUBVAR su_log_t tport_log[];static int name_test(tp_test_t *tt){ tp_name_t tpn[1]; su_home_t home[1] = { SU_HOME_INIT(home) }; su_sockaddr_t su[1]; BEGIN(); memset(su, 0, sizeof su); su->su_port = htons(5060); su->su_family = AF_INET; TEST(tport_convert_addr(home, tpn, "tcp", "localhost", su), 0); su->su_family = AF_INET; TEST(tport_convert_addr(home, tpn, "tcp", "localhost", su), 0);#if SU_HAVE_IN6 su->su_family = AF_INET6; TEST(tport_convert_addr(home, tpn, "tcp", "localhost", su), 0);#endif END();}/* Count number of transports in chain */staticint count_tports(tport_t *tp){ int n = 0; for (tp = tport_primaries(tp); tp; tp = tport_next(tp)) n++; return n;}static int check_msg(tp_test_t *tt, msg_t *msg, char const *ident){ msg_test_t *tst; msg_payload_t *pl; usize_t i, len; BEGIN(); TEST_1(tst = msg_test_public(msg)); TEST_1(pl = tst->msg_payload); if (ident) { if (!tst->msg_content_location || strcmp(ident, tst->msg_content_location->g_string)) return 1; } len = pl->pl_len; for (i = 0; i < len; i++) { if (pl->pl_data[i] != (char) (i % 240)) break; } if (pl) return i != len; END();}static int test_create_md5(tp_test_t *tt, msg_t *msg){ msg_test_t *tst; msg_payload_t *pl; su_md5_t md5[1]; BEGIN(); TEST_1(tst = msg_test_public(msg)); TEST_1(pl = tst->msg_payload); su_md5_init(md5); su_md5_update(md5, pl->pl_data, pl->pl_len); su_md5_digest(md5, tt->tt_digest); END();}static int test_check_md5(tp_test_t *tt, msg_t *msg){ msg_test_t *tst; msg_payload_t *pl; su_md5_t md5[1]; uint8_t digest[SU_MD5_DIGEST_SIZE]; BEGIN(); TEST_1(tst = msg_test_public(msg)); TEST_1(pl = tst->msg_payload); su_md5_init(md5); su_md5_update(md5, pl->pl_data, pl->pl_len); su_md5_digest(md5, digest); TEST(memcmp(digest, tt->tt_digest, sizeof digest), 0); END();}static int test_msg_md5(tp_test_t *tt, msg_t *msg){ msg_test_t *tst; BEGIN(); TEST_1(tst = msg_test_public(msg)); if (tst->msg_content_md5) { su_md5_t md5sum[1]; uint8_t digest[SU_MD5_DIGEST_SIZE]; char b64[BASE64_SIZE(SU_MD5_DIGEST_SIZE) + 1]; msg_payload_t *pl =tst->msg_payload; su_md5_init(md5sum); su_md5_update(md5sum, pl->pl_data, pl->pl_len); su_md5_digest(md5sum, digest); base64_e(b64, sizeof(b64), digest, sizeof(digest)); if (strcmp(b64, tst->msg_content_md5->g_string)) { ; } TEST_S(b64, tst->msg_content_md5->g_string); } else { TEST_1(tst->msg_content_md5); } END();}#define TPORT_TEST_VERSION MSG_TEST_VERSION_CURRENTstatic int new_test_msg(tp_test_t *tt, msg_t **retval, char const *ident, int N, int len){ msg_t *msg; msg_test_t *tst; su_home_t *home; msg_request_t *rq; msg_unknown_t *u; msg_content_location_t *cl; msg_content_md5_t *md5; msg_content_length_t *l; msg_separator_t *sep; msg_payload_t payload[1]; msg_header_t *h; int i; su_md5_t md5sum[1]; uint8_t digest[SU_MD5_DIGEST_SIZE]; char b64[BASE64_SIZE(SU_MD5_DIGEST_SIZE) + 1]; BEGIN(); TEST_1(msg = msg_create(tt->tt_mclass, 0)); TEST_1(tst = msg_test_public(msg)); TEST_1(home = msg_home(msg)); TEST_SIZE(msg_maxsize(msg, 1024 + N * len), 0); TEST_1(rq = msg_request_make(home, "DO im:foo@faa " TPORT_TEST_VERSION)); TEST(msg_header_insert(msg, (void *)tst, (msg_header_t *)rq), 0); TEST_1(u = msg_unknown_make(home, "Foo: faa")); TEST(msg_header_insert(msg, (void *)tst, (msg_header_t *)u), 0); TEST_1(u = msg_unknown_make(home, "Foo: faa")); TEST(msg_header_insert(msg, (void *)tst, (msg_header_t *)u), 0); if (ident) { TEST_1(cl = msg_content_location_make(home, ident)); TEST(msg_header_insert(msg, (void *)tst, (msg_header_t *)cl), 0); } msg_payload_init(payload); payload->pl_len = len; TEST_1(payload->pl_data = su_zalloc(home, payload->pl_len)); for (i = 0; i < len; i++) { payload->pl_data[i] = (char) (i % 240); } su_md5_init(md5sum); for (i = 0; i < N; i++) { h = msg_header_dup(home, (msg_header_t*)payload); TEST_1(h); TEST(msg_header_insert(msg, (void *)tst, h), 0); su_md5_update(md5sum, payload->pl_data, payload->pl_len); } TEST_1(l = msg_content_length_format(home, MOD_ZU, (size_t)(N * payload->pl_len))); TEST(msg_header_insert(msg, (void *)tst, (msg_header_t *)l), 0); su_md5_digest(md5sum, digest); base64_e(b64, sizeof(b64), digest, sizeof(digest)); TEST_1(md5 = msg_content_md5_make(home, b64)); TEST(msg_header_insert(msg, (void *)tst, (msg_header_t *)md5), 0); TEST_1(sep = msg_separator_create(home)); TEST(msg_header_insert(msg, (void *)tst, (msg_header_t *)sep), 0); TEST(msg_serialize(msg, (void *)tst), 0); *retval = msg; END();}staticstruct sigcomp_compartment *test_sigcomp_compartment(tp_test_t *tt, tport_t *tp, tp_name_t const *tpn);static void tp_test_recv(tp_test_t *tt, tport_t *tp, msg_t *msg, tp_magic_t *magic, su_time_t now){ tp_name_t frm[1]; if (tport_delivered_from(tp, msg, frm) != -1 && frm->tpn_comp) { struct sigcomp_compartment *cc = test_sigcomp_compartment(tt, tp, frm); tport_sigcomp_accept(tp, cc, msg); } tt->tt_status = 1; tt->tt_received++; if (msg_has_error(msg)) { tt->tt_status = -1; tt->tt_rtport = tp; } else if (test_msg_md5(tt, msg)) msg_destroy(msg); else if (tt->tt_rmsg) msg_destroy(msg); else { tt->tt_rmsg = msg; tt->tt_rtport = tp; }}static void tp_test_error(tp_test_t *tt, tport_t *tp, int errcode, char const *remote){ tt->tt_status = -1; fprintf(stderr, "tp_test_error(%p): error %d (%s) from %s\n", (void *)tp, errcode, su_strerror(errcode), remote ? remote : "<unknown destination>");}msg_t *tp_test_msg(tp_test_t *tt, int flags, char const data[], usize_t size, tport_t const *tp, tp_client_t *tpc){ msg_t *msg = msg_create(tt->tt_mclass, flags); msg_maxsize(msg, 2 * 1024 * 1024); return msg;}staticstruct sigcomp_compartment *test_sigcomp_compartment(tp_test_t *tt, tport_t *tp, tp_name_t const *tpn){ struct sigcomp_compartment *cc = NULL;#if HAVE_SIGCOMP char name[256]; int namesize; namesize = snprintf(name, sizeof name, "TEST_%s/%s:%s", tpn->tpn_proto, tpn->tpn_host, tpn->tpn_port); if (namesize <= 0 || namesize >= sizeof name) return NULL; cc = sigcomp_compartment_access(tt->state_handler, 0, name, namesize, NULL, 0); if (cc == NULL) { cc = sigcomp_compartment_create(tt->algorithm, tt->state_handler, 0, name, namesize, NULL, 0); sigcomp_compartment_option(cc, "dms=32768"); }#endif return cc;}/* Accept/reject early SigComp message */int test_sigcomp_accept(tp_stack_t *tt, tport_t *tp, msg_t *msg){ struct sigcomp_compartment *cc = NULL; cc = test_sigcomp_compartment(tt, tp, tport_name(tp)); if (cc) tport_sigcomp_assign(tp, cc); return tport_sigcomp_accept(tp, cc, msg);}tp_stack_class_t const tp_test_class[1] = {{ /* tpac_size */ sizeof(tp_test_class), /* tpac_recv */ tp_test_recv, /* tpac_error */ tp_test_error, /* tpac_alloc */ tp_test_msg, }};static int init_test(tp_test_t *tt){ tp_name_t myname[1] = {{ "*", "*", "*", "*", "sigcomp" }};#if HAVE_SCTP char const * transports[] = { "udp", "tcp", "sctp", NULL };#else char const * transports[] = { "udp", "tcp", NULL };#endif tp_name_t const *tpn; tport_t *tp; unsigned idle; BEGIN(); int mask = AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST;#ifdef AI_ALL mask |= AI_ALL;#endif#ifdef AI_V4MAPPED_CFG mask |= AI_V4MAPPED_CFG;#endif#ifdef AI_ADDRCONFIG mask |= AI_ADDRCONFIG;#endif#ifdef AI_V4MAPPED mask |= AI_V4MAPPED;#endif /* Test that we have no common flags with underlying getaddrinfo() */ TEST(mask & TP_AI_MASK, 0); TEST_1(tt->tt_root = su_root_create(NULL)); myname->tpn_host = "127.0.0.1"; myname->tpn_ident = "client"; /* Create message class */ TEST_1(tt->tt_mclass = msg_mclass_clone(msg_test_mclass, 0, 0)); /* Try to insert Content-Length header (expecting failure) */ TEST(msg_mclass_insert(tt->tt_mclass, msg_content_length_href), -1);#if HAVE_SIGCOMP TEST_1(tt->state_handler = sigcomp_state_handler_create()); TEST_1(tt->algorithm = sigcomp_algorithm_by_name(getenv("SIGCOMP_ALGORITHM"))); TEST_1(tt->master_cc = sigcomp_compartment_create(tt->algorithm, tt->state_handler, 0, "", 0, NULL, 0)); TEST(sigcomp_compartment_option(tt->master_cc, "stateless"), 1);#endif /* Create client transport */ TEST_1(tt->tt_tports = tport_tcreate(tt, tp_test_class, tt->tt_root, IF_SIGCOMP_TPTAG_COMPARTMENT(tt->master_cc) TAG_END())); /* Bind client transports */ TEST(tport_tbind(tt->tt_tports, myname, transports, TPTAG_SERVER(0), TAG_END()), 0); if (getenv("TPORT_TEST_HOST")) myname->tpn_host = getenv("TPORT_TEST_HOST"); else myname->tpn_host = "*"; if (getenv("TPORT_TEST_PORT")) myname->tpn_port = getenv("TPORT_TEST_PORT"); myname->tpn_ident = "server"; /* Create server transport */ TEST_1(tt->tt_srv_tports = tport_tcreate(tt, tp_test_class, tt->tt_root, IF_SIGCOMP_TPTAG_COMPARTMENT(tt->master_cc) TAG_END())); /* Bind server transports */ TEST(tport_tbind(tt->tt_srv_tports, myname, transports, TPTAG_SERVER(1), TAG_END()), 0); /* Check that the master transport has idle parameter */ TEST(tport_get_params(tt->tt_srv_tports, TPTAG_IDLE_REF(idle), TAG_END()), 1); for (tp = tport_primaries(tt->tt_srv_tports); tp; tp = tport_next(tp)) TEST_S(tport_name(tp)->tpn_ident, "server"); { su_sockaddr_t su[1]; socklen_t sulen; int s; int i, before, after; char port[8]; tp_name_t rname[1];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -