2006-12-21 06:30:28 +00:00
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
*/
|
|
|
|
|
|
|
|
#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
|
|
|
|
|
|
|
|
#include <sofia-sip/su_wait.h>
|
|
|
|
#include <sofia-sip/su_md5.h>
|
|
|
|
|
|
|
|
#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];
|
|
|
|
};
|
|
|
|
|
|
|
|
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 */
|
|
|
|
static
|
|
|
|
int 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_CURRENT
|
|
|
|
|
|
|
|
static 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();
|
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
struct 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 (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",
|
2007-04-15 02:03:41 +00:00
|
|
|
(void *)tp, errcode, su_strerror(errcode),
|
2006-12-21 06:30:28 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
struct 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_NETINET_SCTP_H
|
|
|
|
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);
|
|
|
|
|
2007-05-08 19:14:10 +00:00
|
|
|
/* Check that the master transport has idle parameter */
|
2006-12-21 06:30:28 +00:00
|
|
|
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];
|
|
|
|
|
|
|
|
*rname = *myname;
|
|
|
|
|
2007-05-08 19:14:10 +00:00
|
|
|
/* Check that we cannot bind to an already used socket */
|
|
|
|
|
2006-12-21 06:30:28 +00:00
|
|
|
memset(su, 0, sulen = sizeof(su->su_sin));
|
|
|
|
s = su_socket(su->su_family = AF_INET, SOCK_STREAM, 0); TEST_1(s != -1);
|
|
|
|
TEST_1(bind(s, &su->su_sa, sulen) != -1);
|
|
|
|
TEST_1(listen(s, 5) != -1);
|
|
|
|
TEST_1(getsockname(s, &su->su_sa, &sulen) != -1);
|
|
|
|
|
|
|
|
sprintf(port, "%u", ntohs(su->su_port));
|
|
|
|
|
|
|
|
rname->tpn_port = port;
|
|
|
|
rname->tpn_ident = "failure";
|
|
|
|
|
|
|
|
before = count_tports(tt->tt_srv_tports);
|
|
|
|
|
2007-05-08 19:14:10 +00:00
|
|
|
/* Bind server transports to an reserved port - this should fail */
|
2006-12-21 06:30:28 +00:00
|
|
|
TEST(tport_tbind(tt->tt_srv_tports, rname, transports,
|
|
|
|
TPTAG_SERVER(1),
|
|
|
|
TAG_END()),
|
|
|
|
-1);
|
|
|
|
|
|
|
|
after = count_tports(tt->tt_srv_tports);
|
|
|
|
|
2007-05-08 19:14:10 +00:00
|
|
|
/* Check that no new primary transports has been added by failed call */
|
2006-12-21 06:30:28 +00:00
|
|
|
TEST(before, after);
|
|
|
|
|
2007-05-08 19:14:10 +00:00
|
|
|
/* Add new transports to an ephemeral port with new identity */
|
|
|
|
|
2006-12-21 06:30:28 +00:00
|
|
|
for (tp = tport_primaries(tt->tt_srv_tports); tp; tp = tport_next(tp))
|
|
|
|
TEST_S(tport_name(tp)->tpn_ident, "server");
|
|
|
|
|
|
|
|
rname->tpn_port = "*";
|
|
|
|
rname->tpn_ident = "server2";
|
|
|
|
|
|
|
|
/* Bind server transports to another port */
|
|
|
|
TEST(tport_tbind(tt->tt_srv_tports, rname, transports,
|
|
|
|
TPTAG_SERVER(1),
|
|
|
|
TAG_END()),
|
|
|
|
0);
|
|
|
|
|
2007-05-08 19:14:10 +00:00
|
|
|
/* Check that new transports are after old ones. */
|
|
|
|
for (i = 0, tp = tport_primaries(tt->tt_srv_tports);
|
|
|
|
i < before;
|
|
|
|
i++, tp = tport_next(tp))
|
2006-12-21 06:30:28 +00:00
|
|
|
TEST_S(tport_name(tp)->tpn_ident, "server");
|
|
|
|
|
|
|
|
for (; tp; tp = tport_next(tp))
|
|
|
|
TEST_S(tport_name(tp)->tpn_ident, "server2");
|
|
|
|
}
|
|
|
|
|
|
|
|
#if HAVE_TLS
|
|
|
|
{
|
|
|
|
tp_name_t tlsname[1] = {{ "tls", "*", "*", "*", NULL }};
|
|
|
|
char const * transports[] = { "tls", NULL };
|
|
|
|
|
|
|
|
char const *srcdir = getenv("srcdir");
|
|
|
|
|
|
|
|
if (srcdir == NULL)
|
|
|
|
srcdir = ".";
|
|
|
|
|
|
|
|
tlsname->tpn_host = myname->tpn_host;
|
|
|
|
tlsname->tpn_ident = "server";
|
|
|
|
|
|
|
|
/* Bind client transports */
|
|
|
|
TEST(tport_tbind(tt->tt_tports, tlsname, transports,
|
|
|
|
TPTAG_SERVER(0),
|
|
|
|
TPTAG_CERTIFICATE(srcdir),
|
|
|
|
TAG_END()),
|
|
|
|
0);
|
|
|
|
|
|
|
|
/* Bind tls server transport */
|
|
|
|
TEST(tport_tbind(tt->tt_srv_tports, tlsname, transports,
|
|
|
|
TPTAG_SERVER(1),
|
|
|
|
TPTAG_CERTIFICATE(srcdir),
|
|
|
|
TAG_END()),
|
|
|
|
0);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
for (tp = tport_primaries(tt->tt_srv_tports); tp; tp = tport_next(tp)) {
|
|
|
|
TEST_1(tpn = tport_name(tp));
|
|
|
|
|
|
|
|
if (1 || tt->tt_flags & tst_verbatim) {
|
|
|
|
char const *host = tpn->tpn_host != tpn->tpn_canon ? tpn->tpn_host : "";
|
|
|
|
printf("bound transport to %s/%s:%s%s%s%s%s\n",
|
|
|
|
tpn->tpn_proto, tpn->tpn_canon, tpn->tpn_port,
|
|
|
|
host[0] ? ";maddr=" : "", host,
|
|
|
|
tpn->tpn_comp ? ";comp=" : "",
|
|
|
|
tpn->tpn_comp ? tpn->tpn_comp : "");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Ignore server2 tports for now */
|
|
|
|
if (strcmp(tpn->tpn_ident, "server"))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (strcmp(tpn->tpn_proto, "udp") == 0) {
|
|
|
|
*tt->tt_udp_name = *tpn;
|
|
|
|
tt->tt_udp_name->tpn_comp = NULL;
|
|
|
|
tt->tt_udp_name->tpn_ident = NULL;
|
|
|
|
*tt->tt_udp_comp = *tpn;
|
|
|
|
tt->tt_udp_comp->tpn_ident = NULL;
|
|
|
|
}
|
|
|
|
else if (strcmp(tpn->tpn_proto, "tcp") == 0) {
|
|
|
|
*tt->tt_tcp_name = *tpn;
|
|
|
|
tt->tt_tcp_name->tpn_comp = NULL;
|
|
|
|
tt->tt_tcp_name->tpn_ident = NULL;
|
|
|
|
*tt->tt_tcp_comp = *tpn;
|
|
|
|
tt->tt_tcp_comp->tpn_ident = NULL;
|
|
|
|
}
|
|
|
|
else if (strcmp(tpn->tpn_proto, "sctp") == 0) {
|
|
|
|
*tt->tt_sctp_name = *tpn;
|
|
|
|
tt->tt_sctp_name->tpn_ident = NULL;
|
|
|
|
}
|
|
|
|
else if (strcmp(tpn->tpn_proto, "tls") == 0) {
|
|
|
|
*tt->tt_tls_name = *tpn;
|
|
|
|
tt->tt_tls_name->tpn_ident = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
END();
|
|
|
|
}
|
|
|
|
|
|
|
|
char const payload[] =
|
|
|
|
"Some data\n"
|
|
|
|
"More data\n";
|
|
|
|
|
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
int
|
|
|
|
tport_test_run(tp_test_t *tt, unsigned timeout)
|
|
|
|
{
|
|
|
|
time_t now = time(NULL);
|
|
|
|
|
|
|
|
tt->tt_status = 0;
|
|
|
|
|
|
|
|
msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
|
|
|
|
tt->tt_rtport = NULL;
|
|
|
|
|
|
|
|
while (!tt->tt_status) {
|
|
|
|
if (tt->tt_flags & tst_verbatim) {
|
|
|
|
fputs(".", stdout); fflush(stdout);
|
|
|
|
}
|
|
|
|
su_root_step(tt->tt_root, 500L);
|
|
|
|
|
|
|
|
if (!getenv("TPORT_TEST_DEBUG") &&
|
|
|
|
time(NULL) > (time_t)(now + timeout))
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return tt->tt_status;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int udp_test(tp_test_t *tt)
|
|
|
|
{
|
|
|
|
tport_t *tp;
|
|
|
|
msg_t *msg;
|
|
|
|
msg_test_t *tst;
|
|
|
|
su_home_t *home;
|
|
|
|
msg_request_t *rq;
|
|
|
|
msg_unknown_t *u;
|
|
|
|
msg_content_length_t *l;
|
|
|
|
msg_content_md5_t *md5;
|
|
|
|
msg_separator_t *sep;
|
|
|
|
msg_payload_t *pl;
|
|
|
|
|
|
|
|
BEGIN();
|
|
|
|
|
|
|
|
TEST_1(msg = msg_create(tt->tt_mclass, 0));
|
|
|
|
TEST_1(tst = msg_test_public(msg));
|
|
|
|
TEST_1(home = msg_home(msg));
|
|
|
|
|
|
|
|
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(pl = msg_payload_make(home, payload));
|
|
|
|
TEST(msg_header_insert(msg, (void *)tst, (msg_header_t *)pl), 0);
|
|
|
|
|
|
|
|
TEST_1(l = msg_content_length_format(home, MOD_ZU, (size_t)pl->pl_len));
|
|
|
|
TEST(msg_header_insert(msg, (void *)tst, (msg_header_t *)l), 0);
|
|
|
|
|
|
|
|
TEST_1(md5 = msg_content_md5_make(home, "R6nitdrtJFpxYzrPaSXfrA=="));
|
|
|
|
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);
|
|
|
|
|
|
|
|
TEST_1(tp = tport_tsend(tt->tt_tports, msg, tt->tt_udp_name, TAG_END()));
|
|
|
|
|
|
|
|
TEST_S(tport_name(tp)->tpn_ident, "client");
|
|
|
|
|
|
|
|
TEST(tport_test_run(tt, 5), 1);
|
|
|
|
|
|
|
|
msg_destroy(msg);
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
tp_name_t tpn[1] = {{ NULL }};
|
|
|
|
|
|
|
|
TEST_1(msg = tt->tt_rmsg); tt->tt_rmsg = NULL;
|
|
|
|
|
|
|
|
TEST_1(home = msg_home(msg));
|
|
|
|
|
|
|
|
TEST_1(tport_convert_addr(home, tpn, "udp", NULL, msg_addr(msg)) == 0);
|
|
|
|
|
|
|
|
tpn->tpn_comp = tport_name(tt->tt_rtport)->tpn_comp;
|
|
|
|
|
|
|
|
/* reply */
|
|
|
|
TEST_1(tport_tsend(tt->tt_rtport, msg, tpn, TAG_END()) != NULL);
|
|
|
|
|
|
|
|
msg_destroy(msg);
|
|
|
|
|
|
|
|
TEST(tport_test_run(tt, 5), 1);
|
|
|
|
|
|
|
|
msg_destroy(msg);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
|
|
|
|
|
|
|
|
END();
|
|
|
|
}
|
|
|
|
|
|
|
|
static int tcp_test(tp_test_t *tt)
|
|
|
|
{
|
2007-04-19 19:17:12 +00:00
|
|
|
BEGIN();
|
|
|
|
|
|
|
|
#ifndef WIN32 /* Windows seems to be buffering too much */
|
|
|
|
|
2006-12-21 06:30:28 +00:00
|
|
|
msg_t *msg = NULL;
|
|
|
|
int i;
|
|
|
|
tport_t *tp, *tp0;
|
|
|
|
char ident[16];
|
|
|
|
|
|
|
|
/* Create a large message, just to force queueing in sending end */
|
|
|
|
TEST(new_test_msg(tt, &msg, "tcp-0", 1, 16 * 64 * 1024), 0);
|
|
|
|
test_create_md5(tt, msg);
|
|
|
|
TEST_1(tp = tport_tsend(tt->tt_tports, msg, tt->tt_tcp_name, TAG_END()));
|
|
|
|
TEST_S(tport_name(tp)->tpn_ident, "client");
|
|
|
|
tp0 = tport_incref(tp);
|
|
|
|
msg_destroy(msg);
|
|
|
|
|
|
|
|
/* Fill up the queue */
|
|
|
|
for (i = 1; i < TPORT_QUEUESIZE; i++) {
|
|
|
|
snprintf(ident, sizeof ident, "tcp-%u", i);
|
|
|
|
|
|
|
|
TEST(new_test_msg(tt, &msg, ident, 1, 64 * 1024), 0);
|
|
|
|
TEST_1(tp = tport_tsend(tt->tt_tports, msg, tt->tt_tcp_name, TAG_END()));
|
|
|
|
TEST_S(tport_name(tp)->tpn_ident, "client");
|
|
|
|
TEST_P(tport_incref(tp), tp0); tport_decref(&tp);
|
|
|
|
msg_destroy(msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* This overflows the queue */
|
|
|
|
TEST(new_test_msg(tt, &msg, "tcp-overflow", 1, 1024), 0);
|
|
|
|
TEST_1(!tport_tsend(tt->tt_tports, msg, tt->tt_tcp_name, TAG_END()));
|
|
|
|
msg_destroy(msg);
|
|
|
|
|
|
|
|
tt->tt_received = 0;
|
|
|
|
|
|
|
|
TEST(tport_test_run(tt, 60), 1);
|
|
|
|
TEST_1(!check_msg(tt, tt->tt_rmsg, "tcp-0"));
|
|
|
|
test_check_md5(tt, tt->tt_rmsg);
|
|
|
|
msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
|
|
|
|
|
|
|
|
if (tt->tt_received < TPORT_QUEUESIZE) { /* We have not received it all */
|
|
|
|
snprintf(ident, sizeof ident, "tcp-%u", tt->tt_received);
|
|
|
|
TEST(tport_test_run(tt, 5), 1);
|
|
|
|
TEST_1(!check_msg(tt, tt->tt_rmsg, ident));
|
|
|
|
msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* This uses a new connection */
|
|
|
|
TEST_1(!new_test_msg(tt, &msg, "tcp-no-reuse", 1, 1024));
|
|
|
|
TEST_1(tp = tport_tsend(tt->tt_tports, msg, tt->tt_tcp_name,
|
|
|
|
TPTAG_REUSE(0), TAG_END()));
|
|
|
|
TEST_S(tport_name(tp)->tpn_ident, "client");
|
|
|
|
TEST_1(tport_incref(tp) != tp0); tport_decref(&tp);
|
|
|
|
msg_destroy(msg);
|
|
|
|
|
|
|
|
/* This uses the old connection */
|
|
|
|
TEST_1(!new_test_msg(tt, &msg, "tcp-reuse", 1, 1024));
|
|
|
|
TEST_1(tp = tport_tsend(tt->tt_tports, msg, tt->tt_tcp_name,
|
|
|
|
TPTAG_REUSE(1), TAG_END()));
|
|
|
|
TEST_S(tport_name(tp)->tpn_ident, "client");
|
|
|
|
TEST_1(tport_incref(tp) == tp0); tport_decref(&tp);
|
|
|
|
msg_destroy(msg);
|
|
|
|
|
|
|
|
/* Receive every message from queue */
|
|
|
|
while (tt->tt_received < TPORT_QUEUESIZE + 2) {
|
|
|
|
TEST(tport_test_run(tt, 5), 1);
|
|
|
|
/* Validate message */
|
|
|
|
TEST_1(!check_msg(tt, tt->tt_rmsg, NULL));
|
|
|
|
msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Try to send a single message */
|
|
|
|
TEST_1(!new_test_msg(tt, &msg, "tcp-last", 1, 1024));
|
|
|
|
TEST_1(tp = tport_tsend(tt->tt_tports, msg, tt->tt_tcp_name, TAG_END()));
|
|
|
|
TEST_S(tport_name(tp)->tpn_ident, "client");
|
|
|
|
TEST_P(tport_incref(tp), tp0); tport_decref(&tp);
|
|
|
|
msg_destroy(msg);
|
|
|
|
|
|
|
|
TEST(tport_test_run(tt, 5), 1);
|
|
|
|
|
|
|
|
TEST_1(!check_msg(tt, tt->tt_rmsg, "tcp-last"));
|
|
|
|
msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
|
|
|
|
|
|
|
|
tport_decref(&tp0);
|
|
|
|
|
2007-04-19 19:17:12 +00:00
|
|
|
#endif
|
|
|
|
|
2006-12-21 06:30:28 +00:00
|
|
|
END();
|
|
|
|
}
|
|
|
|
|
|
|
|
static int reuse_test(tp_test_t *tt)
|
|
|
|
{
|
|
|
|
msg_t *msg = NULL;
|
|
|
|
int i, reuse = -1;
|
|
|
|
tport_t *tp, *tp0, *tp1;
|
|
|
|
tp_name_t tpn[1];
|
|
|
|
|
|
|
|
BEGIN();
|
|
|
|
|
|
|
|
/* Flush existing connections */
|
|
|
|
*tpn = *tt->tt_tcp_name;
|
|
|
|
tpn->tpn_port = "*";
|
|
|
|
TEST_1(tp = tport_by_name(tt->tt_tports, tpn));
|
|
|
|
TEST_1(tport_is_primary(tp));
|
|
|
|
TEST(tport_flush(tp), 0);
|
|
|
|
|
|
|
|
for (i = 0; i < 10; i++)
|
|
|
|
su_root_step(tt->tt_root, 10L);
|
|
|
|
|
|
|
|
TEST(tport_set_params(tp, TPTAG_REUSE(0), TAG_END()), 1);
|
|
|
|
|
|
|
|
/* Send two messages */
|
|
|
|
TEST(new_test_msg(tt, &msg, "reuse-1", 1, 1024), 0);
|
|
|
|
TEST_1(tp = tport_tsend(tt->tt_tports, msg, tt->tt_tcp_name, TAG_END()));
|
|
|
|
TEST_S(tport_name(tp)->tpn_ident, "client");
|
|
|
|
TEST_1(tp0 = tport_incref(tp));
|
|
|
|
TEST(tport_get_params(tp, TPTAG_REUSE_REF(reuse), TAG_END()), 1);
|
|
|
|
TEST(reuse, 0);
|
|
|
|
msg_destroy(msg), msg = NULL;
|
|
|
|
|
|
|
|
TEST(new_test_msg(tt, &msg, "reuse-2", 1, 1024), 0);
|
|
|
|
TEST_1(tp = tport_tsend(tt->tt_tports, msg, tt->tt_tcp_name, TAG_END()));
|
|
|
|
TEST_S(tport_name(tp)->tpn_ident, "client");
|
|
|
|
TEST_1(tp1 = tport_incref(tp)); TEST_1(tp0 != tp1);
|
|
|
|
TEST(tport_get_params(tp, TPTAG_REUSE_REF(reuse), TAG_END()), 1);
|
|
|
|
TEST(reuse, 0);
|
|
|
|
msg_destroy(msg), msg = NULL;
|
|
|
|
|
|
|
|
/* Receive every message from queue */
|
|
|
|
for (tt->tt_received = 0;
|
|
|
|
tt->tt_received < 2;) {
|
|
|
|
TEST(tport_test_run(tt, 5), 1);
|
|
|
|
msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Enable reuse on single connection */
|
|
|
|
TEST(tport_set_params(tp1, TPTAG_REUSE(1), TAG_END()), 1);
|
|
|
|
TEST(new_test_msg(tt, &msg, "reuse-3", 1, 1024), 0);
|
|
|
|
TEST_1(tp = tport_tsend(tt->tt_tports, msg, tt->tt_tcp_name,
|
|
|
|
TPTAG_REUSE(1),
|
|
|
|
TAG_END()));
|
|
|
|
TEST_S(tport_name(tp)->tpn_ident, "client");
|
|
|
|
TEST_1(tp1 == tp);
|
|
|
|
TEST(tport_get_params(tp, TPTAG_REUSE_REF(reuse), TAG_END()), 1);
|
|
|
|
TEST(reuse, 1);
|
|
|
|
msg_destroy(msg), msg = NULL;
|
|
|
|
|
|
|
|
TEST(tport_test_run(tt, 5), 1);
|
|
|
|
msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
|
|
|
|
|
|
|
|
TEST_1(tp = tport_by_name(tt->tt_tports, tpn));
|
|
|
|
TEST_1(tport_is_primary(tp));
|
|
|
|
TEST(tport_set_params(tp, TPTAG_REUSE(1), TAG_END()), 1);
|
|
|
|
|
|
|
|
/* Send a single message with different connection */
|
|
|
|
TEST_1(!new_test_msg(tt, &msg, "fresh-1", 1, 1024));
|
|
|
|
TEST_1(tp = tport_tsend(tt->tt_tports, msg, tt->tt_tcp_name,
|
|
|
|
TPTAG_FRESH(1),
|
|
|
|
TPTAG_REUSE(1),
|
|
|
|
TAG_END()));
|
|
|
|
TEST_S(tport_name(tp)->tpn_ident, "client");
|
|
|
|
TEST_1(tport_incref(tp) != tp1); tport_decref(&tp);
|
|
|
|
msg_destroy(msg);
|
|
|
|
|
|
|
|
TEST(tport_test_run(tt, 5), 1);
|
|
|
|
|
|
|
|
TEST_1(!check_msg(tt, tt->tt_rmsg, "fresh-1"));
|
|
|
|
msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
|
|
|
|
|
|
|
|
TEST_1(tport_shutdown(tp0, 2) >= 0);
|
|
|
|
TEST_1(tport_shutdown(tp1, 2) >= 0);
|
|
|
|
TEST_1(tport_shutdown(tp0, 1) >= 0);
|
|
|
|
|
|
|
|
TEST(tport_shutdown(NULL, 0), -1);
|
|
|
|
|
|
|
|
tport_decref(&tp0);
|
|
|
|
tport_decref(&tp1);
|
|
|
|
|
|
|
|
END();
|
|
|
|
}
|
|
|
|
|
|
|
|
static int sctp_test(tp_test_t *tt)
|
|
|
|
{
|
|
|
|
BEGIN();
|
|
|
|
|
|
|
|
msg_t *msg = NULL;
|
|
|
|
int i, n;
|
|
|
|
tport_t *tp;
|
|
|
|
char buffer[32];
|
|
|
|
|
|
|
|
if (!tt->tt_sctp_name->tpn_proto)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* Just a small and nice message first */
|
|
|
|
TEST_1(!new_test_msg(tt, &msg, "sctp-small", 1, 1024));
|
|
|
|
test_create_md5(tt, msg);
|
|
|
|
TEST_1(tp = tport_tsend(tt->tt_tports, msg, tt->tt_sctp_name, TAG_END()));
|
|
|
|
TEST_S(tport_name(tp)->tpn_ident, "client");
|
|
|
|
msg_destroy(msg);
|
|
|
|
|
|
|
|
TEST(tport_test_run(tt, 5), 1);
|
|
|
|
|
|
|
|
TEST_1(!check_msg(tt, tt->tt_rmsg, NULL));
|
|
|
|
test_check_md5(tt, tt->tt_rmsg);
|
|
|
|
msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
|
|
|
|
|
|
|
|
if (1)
|
|
|
|
return 0; /* SCTP does not work reliably. Really. */
|
|
|
|
|
|
|
|
/* Create large messages, just to force queueing in sending end */
|
|
|
|
for (n = 0; !tport_queuelen(tp); n++) {
|
|
|
|
snprintf(buffer, sizeof buffer, "cid:sctp-%u", n);
|
|
|
|
TEST_1(!new_test_msg(tt, &msg, buffer, 1, 32000));
|
|
|
|
test_create_md5(tt, msg);
|
|
|
|
TEST_1(tport_tsend(tp, msg, tt->tt_sctp_name, TAG_END()));
|
|
|
|
TEST_S(tport_name(tp)->tpn_ident, "client");
|
|
|
|
msg_destroy(msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Fill up the queue */
|
|
|
|
for (i = 1; i < TPORT_QUEUESIZE; i++) {
|
|
|
|
snprintf(buffer, sizeof buffer, "cid:sctp-%u", n + i);
|
|
|
|
TEST_1(!new_test_msg(tt, &msg, buffer, 1, 1024));
|
|
|
|
TEST_1(tport_tsend(tp, msg, tt->tt_sctp_name, TAG_END()));
|
|
|
|
msg_destroy(msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* This overflows the queue */
|
|
|
|
snprintf(buffer, sizeof buffer, "cid:sctp-%u", n + i);
|
|
|
|
TEST_1(!new_test_msg(tt, &msg, buffer, 1, 1024));
|
|
|
|
TEST_1(!tport_tsend(tt->tt_tports, msg, tt->tt_sctp_name, TAG_END()));
|
|
|
|
msg_destroy(msg);
|
|
|
|
|
|
|
|
TEST(tport_test_run(tt, 5), 1);
|
|
|
|
|
|
|
|
TEST_1(!check_msg(tt, tt->tt_rmsg, NULL));
|
|
|
|
test_check_md5(tt, tt->tt_rmsg);
|
|
|
|
msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
|
|
|
|
|
|
|
|
/* This uses a new connection */
|
|
|
|
TEST_1(!new_test_msg(tt, &msg, "cid-sctp-new", 1, 1024));
|
|
|
|
TEST_1(tport_tsend(tt->tt_tports, msg, tt->tt_sctp_name,
|
|
|
|
TPTAG_REUSE(0), TAG_END()));
|
|
|
|
msg_destroy(msg);
|
|
|
|
|
|
|
|
/* Receive every message from queue */
|
|
|
|
for (tt->tt_received = 0; tt->tt_received < TPORT_QUEUESIZE + n;) {
|
|
|
|
TEST(tport_test_run(tt, 10), 1);
|
|
|
|
/* Validate message */
|
|
|
|
TEST_1(!check_msg(tt, tt->tt_rmsg, NULL));
|
|
|
|
msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Try to send a single message */
|
|
|
|
TEST_1(!new_test_msg(tt, &msg, "cid:sctp-final", 1, 1024));
|
|
|
|
TEST_1(tport_tsend(tt->tt_tports, msg, tt->tt_sctp_name, TAG_END()));
|
|
|
|
msg_destroy(msg);
|
|
|
|
|
|
|
|
TEST(tport_test_run(tt, 10), 1);
|
|
|
|
|
|
|
|
TEST_1(!check_msg(tt, tt->tt_rmsg, NULL));
|
|
|
|
msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
|
|
|
|
|
|
|
|
END();
|
|
|
|
}
|
|
|
|
|
|
|
|
static int tls_test(tp_test_t *tt)
|
|
|
|
{
|
|
|
|
BEGIN();
|
|
|
|
|
|
|
|
#if HAVE_TLS
|
|
|
|
tp_name_t const *dst = tt->tt_tls_name;
|
|
|
|
msg_t *msg = NULL;
|
|
|
|
int i;
|
|
|
|
char ident[16];
|
|
|
|
|
|
|
|
TEST_S(dst->tpn_proto, "tls");
|
|
|
|
|
|
|
|
tt->tt_received = 0;
|
|
|
|
|
|
|
|
/* Create a large message, just to force queueing in sending end */
|
|
|
|
TEST_1(!new_test_msg(tt, &msg, "tls-0", 16, 64 * 1024));
|
|
|
|
test_create_md5(tt, msg);
|
|
|
|
TEST_1(tport_tsend(tt->tt_tports, msg, dst, TAG_END()));
|
|
|
|
msg_destroy(msg);
|
|
|
|
|
|
|
|
/* Fill up the queue */
|
|
|
|
for (i = 1; i < TPORT_QUEUESIZE; i++) {
|
|
|
|
snprintf(ident, sizeof ident, "tls-%u", i);
|
|
|
|
|
|
|
|
TEST_1(!new_test_msg(tt, &msg, ident, 2, 512));
|
|
|
|
TEST_1(tport_tsend(tt->tt_tports, msg, dst, TAG_END()));
|
|
|
|
msg_destroy(msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* This overflows the queue */
|
|
|
|
TEST_1(!new_test_msg(tt, &msg, "tls-overflow", 1, 1024));
|
|
|
|
TEST_1(!tport_tsend(tt->tt_tports, msg, dst, TAG_END()));
|
|
|
|
msg_destroy(msg);
|
|
|
|
|
|
|
|
TEST(tport_test_run(tt, 60), 1);
|
|
|
|
|
|
|
|
msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
|
|
|
|
|
|
|
|
/* This uses a new connection */
|
|
|
|
TEST_1(!new_test_msg(tt, &msg, "tls-no-reuse", 1, 1024));
|
|
|
|
TEST_1(tport_tsend(tt->tt_tports, msg, dst,
|
|
|
|
TPTAG_REUSE(0), TAG_END()));
|
|
|
|
msg_destroy(msg);
|
|
|
|
|
|
|
|
/* Receive every message from queue */
|
|
|
|
while (tt->tt_received < TPORT_QUEUESIZE + 1) {
|
|
|
|
TEST(tport_test_run(tt, 5), 1);
|
|
|
|
/* Validate message */
|
|
|
|
msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Try to send a single message */
|
|
|
|
TEST_1(!new_test_msg(tt, &msg, "tls-last", 1, 1024));
|
|
|
|
TEST_1(tport_tsend(tt->tt_tports, msg, dst, TAG_END()));
|
|
|
|
msg_destroy(msg);
|
|
|
|
|
|
|
|
TEST(tport_test_run(tt, 5), 1);
|
|
|
|
|
|
|
|
TEST_1(!check_msg(tt, tt->tt_rmsg, "tls-last"));
|
|
|
|
msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
END();
|
|
|
|
}
|
|
|
|
|
|
|
|
static int sigcomp_test(tp_test_t *tt)
|
|
|
|
{
|
|
|
|
BEGIN();
|
|
|
|
|
|
|
|
#if HAVE_SIGCOMP
|
|
|
|
su_home_t *home;
|
|
|
|
tp_name_t tpn[1] = {{ NULL }};
|
|
|
|
struct sigcomp_compartment *cc;
|
|
|
|
|
|
|
|
if (tt->tt_udp_comp->tpn_comp) {
|
|
|
|
msg_t *msg = NULL;
|
|
|
|
|
|
|
|
TEST_1(cc = test_sigcomp_compartment(tt, tt->tt_tports, tt->tt_udp_comp));
|
|
|
|
|
|
|
|
TEST_1(!new_test_msg(tt, &msg, "udp-sigcomp", 1, 1200));
|
|
|
|
test_create_md5(tt, msg);
|
|
|
|
TEST_1(tport_tsend(tt->tt_tports,
|
|
|
|
msg,
|
|
|
|
tt->tt_udp_comp,
|
|
|
|
TPTAG_COMPARTMENT(cc),
|
|
|
|
TAG_END()));
|
|
|
|
msg_destroy(msg);
|
|
|
|
|
|
|
|
TEST(tport_test_run(tt, 5), 1);
|
|
|
|
|
|
|
|
TEST_1(!check_msg(tt, tt->tt_rmsg, NULL));
|
|
|
|
|
|
|
|
test_check_md5(tt, tt->tt_rmsg);
|
|
|
|
|
|
|
|
TEST_1(msg = tt->tt_rmsg); tt->tt_rmsg = NULL;
|
|
|
|
|
|
|
|
TEST_1(home = msg_home(msg));
|
|
|
|
|
|
|
|
TEST_1(tport_convert_addr(home, tpn, "udp", NULL, msg_addr(msg)) == 0);
|
|
|
|
|
|
|
|
tpn->tpn_comp = tport_name(tt->tt_rtport)->tpn_comp;
|
|
|
|
|
|
|
|
/* reply */
|
|
|
|
TEST_1(cc = test_sigcomp_compartment(tt, tt->tt_tports, tpn));
|
|
|
|
TEST_1(tport_tsend(tt->tt_rtport, msg, tpn,
|
|
|
|
TPTAG_COMPARTMENT(cc),
|
|
|
|
TAG_END()) != NULL);
|
|
|
|
|
|
|
|
msg_destroy(msg);
|
|
|
|
|
|
|
|
TEST(tport_test_run(tt, 5), 1);
|
|
|
|
|
|
|
|
TEST_1(!check_msg(tt, tt->tt_rmsg, NULL));
|
|
|
|
test_check_md5(tt, tt->tt_rmsg);
|
|
|
|
msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (tt->tt_tcp_comp->tpn_comp) {
|
|
|
|
tport_t *tp;
|
|
|
|
msg_t *msg = NULL;
|
|
|
|
|
|
|
|
*tpn = *tt->tt_tcp_comp;
|
|
|
|
|
|
|
|
TEST_1(!new_test_msg(tt, &msg, "tcp-sigcomp", 1, 1500));
|
|
|
|
test_create_md5(tt, msg);
|
|
|
|
|
|
|
|
tport_log->log_level = 9;
|
|
|
|
|
|
|
|
TEST_1(cc = test_sigcomp_compartment(tt, tt->tt_tports, tpn));
|
|
|
|
TEST_1(tp = tport_tsend(tt->tt_tports,
|
|
|
|
msg,
|
|
|
|
tpn,
|
|
|
|
TPTAG_COMPARTMENT(cc),
|
|
|
|
TAG_END()));
|
|
|
|
TEST_1(tport_incref(tp)); tport_decref(&tp);
|
|
|
|
msg_destroy(msg);
|
|
|
|
|
|
|
|
TEST(tport_test_run(tt, 5), 1);
|
|
|
|
|
|
|
|
TEST_1(!check_msg(tt, tt->tt_rmsg, "tcp-sigcomp"));
|
|
|
|
test_check_md5(tt, tt->tt_rmsg);
|
|
|
|
msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
|
|
|
|
|
|
|
|
TEST_1(!new_test_msg(tt, &msg, "tcp-sigcomp-2", 1, 3000));
|
|
|
|
test_create_md5(tt, msg);
|
|
|
|
TEST_1(tp = tport_tsend(tt->tt_tports,
|
|
|
|
msg,
|
|
|
|
tt->tt_tcp_comp,
|
|
|
|
TPTAG_COMPARTMENT(cc),
|
|
|
|
TAG_END()));
|
|
|
|
TEST_1(tport_incref(tp)); tport_decref(&tp);
|
|
|
|
msg_destroy(msg);
|
|
|
|
|
|
|
|
TEST(tport_test_run(tt, 5), 1);
|
|
|
|
|
|
|
|
TEST_1(!check_msg(tt, tt->tt_rmsg, "tcp-sigcomp-2"));
|
|
|
|
test_check_md5(tt, tt->tt_rmsg);
|
|
|
|
|
|
|
|
msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
|
|
|
|
|
|
|
|
TEST_1(!new_test_msg(tt, &msg, "tcp-sigcomp-3", 1, 45500));
|
|
|
|
test_create_md5(tt, msg);
|
|
|
|
TEST_1(tp = tport_tsend(tt->tt_tports,
|
|
|
|
msg,
|
|
|
|
tt->tt_tcp_comp,
|
|
|
|
TPTAG_COMPARTMENT(cc),
|
|
|
|
TAG_END()));
|
|
|
|
TEST_1(tport_incref(tp));
|
|
|
|
msg_destroy(msg);
|
|
|
|
|
|
|
|
TEST(tport_test_run(tt, 5), 1);
|
|
|
|
|
|
|
|
tport_decref(&tp);
|
|
|
|
TEST_1(!check_msg(tt, tt->tt_rmsg, "tcp-sigcomp-3"));
|
|
|
|
test_check_md5(tt, tt->tt_rmsg);
|
|
|
|
msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
|
|
|
|
|
|
|
|
{
|
|
|
|
tp_name_t tpn[1];
|
|
|
|
tport_t *ctp, *rtp;
|
|
|
|
|
|
|
|
*tpn = *tt->tt_tcp_comp; tpn->tpn_comp = NULL;
|
|
|
|
|
|
|
|
TEST_1(!new_test_msg(tt, &msg, "tcp-sigcomp-4", 1, 1000));
|
|
|
|
test_create_md5(tt, msg);
|
|
|
|
TEST_1(tp = tport_tsend(tt->tt_tports,
|
|
|
|
msg,
|
|
|
|
tpn,
|
|
|
|
TPTAG_COMPARTMENT(cc),
|
|
|
|
TPTAG_FRESH(1),
|
|
|
|
TAG_END()));
|
|
|
|
TEST_1(ctp = tport_incref(tp));
|
|
|
|
msg_destroy(msg);
|
|
|
|
|
|
|
|
TEST(tport_test_run(tt, 5), 1);
|
|
|
|
|
|
|
|
TEST_1(!check_msg(tt, tt->tt_rmsg, "tcp-sigcomp-4"));
|
|
|
|
test_check_md5(tt, tt->tt_rmsg);
|
|
|
|
TEST_1((msg_addrinfo(tt->tt_rmsg)->ai_flags & TP_AI_COMPRESSED) == 0);
|
|
|
|
msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
|
|
|
|
TEST_1(rtp = tport_incref(tt->tt_rtport));
|
|
|
|
|
|
|
|
TEST_1(!new_test_msg(tt, &msg, "tcp-sigcomp-5", 1, 1000));
|
|
|
|
test_create_md5(tt, msg);
|
|
|
|
{
|
|
|
|
/* Mess with internal data structures in order to
|
|
|
|
force tport to use SigComp on this connection */
|
|
|
|
tp_name_t *tpn = (tp_name_t *)tport_name(rtp);
|
|
|
|
tpn->tpn_comp = "sigcomp";
|
|
|
|
}
|
|
|
|
TEST_1(tp = tport_tsend(rtp,
|
|
|
|
msg,
|
|
|
|
tt->tt_tcp_comp,
|
|
|
|
TPTAG_COMPARTMENT(cc),
|
|
|
|
TAG_END()));
|
|
|
|
TEST_1(tport_incref(tp));
|
|
|
|
msg_destroy(msg);
|
|
|
|
|
|
|
|
TEST(tp, rtp);
|
|
|
|
|
|
|
|
TEST(tport_test_run(tt, 5), 1);
|
|
|
|
|
|
|
|
tport_decref(&tp);
|
|
|
|
TEST_1(!check_msg(tt, tt->tt_rmsg, "tcp-sigcomp-5"));
|
|
|
|
test_check_md5(tt, tt->tt_rmsg);
|
|
|
|
TEST_1((msg_addrinfo(tt->tt_rmsg)->ai_flags & TP_AI_COMPRESSED) != 0);
|
|
|
|
msg_destroy(tt->tt_rmsg), tt->tt_rmsg = NULL;
|
|
|
|
TEST(ctp, tt->tt_rtport);
|
|
|
|
tport_decref(&ctp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
END();
|
|
|
|
}
|
|
|
|
|
|
|
|
#if HAVE_SOFIA_STUN
|
|
|
|
|
|
|
|
#include <sofia-sip/stun_tag.h>
|
|
|
|
|
|
|
|
static int stun_test(tp_test_t *tt)
|
|
|
|
{
|
|
|
|
BEGIN();
|
|
|
|
|
|
|
|
tport_t *mr;
|
|
|
|
tp_name_t tpn[1] = {{ "*", "*", "*", "*", NULL }};
|
|
|
|
#if HAVE_NETINET_SCTP_H
|
|
|
|
char const * transports[] = { "udp", "tcp", "sctp", NULL };
|
|
|
|
#else
|
|
|
|
char const * transports[] = { "udp", "tcp", NULL };
|
|
|
|
#endif
|
|
|
|
|
|
|
|
TEST_1(mr = tport_tcreate(tt, tp_test_class, tt->tt_root, TAG_END()));
|
|
|
|
|
|
|
|
TEST(tport_tbind(tt->tt_tports, tpn, transports, TPTAG_SERVER(1),
|
|
|
|
STUNTAG_SERVER("999.999.999.999"),
|
|
|
|
TAG_END()), -1);
|
|
|
|
|
|
|
|
tport_destroy(mr);
|
|
|
|
|
|
|
|
END();
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
static int stun_test(tp_test_t *tt)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static int deinit_test(tp_test_t *tt)
|
|
|
|
{
|
|
|
|
BEGIN();
|
|
|
|
|
|
|
|
/* Destroy client transports */
|
|
|
|
tport_destroy(tt->tt_tports), tt->tt_tports = NULL;
|
|
|
|
|
|
|
|
/* Destroy server transports */
|
|
|
|
tport_destroy(tt->tt_srv_tports), tt->tt_srv_tports = NULL;
|
|
|
|
|
|
|
|
#if HAVE_SIGCOMP
|
|
|
|
sigcomp_state_handler_free(tt->state_handler); tt->state_handler = NULL;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
END();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Test tport_tags filter */
|
|
|
|
static int filter_test(tp_test_t *tt)
|
|
|
|
{
|
|
|
|
tagi_t *lst, *result;
|
|
|
|
|
|
|
|
su_home_t home[1] = { SU_HOME_INIT(home) };
|
|
|
|
|
|
|
|
BEGIN();
|
|
|
|
|
|
|
|
lst = tl_list(TSTTAG_HEADER_STR("X: Y"),
|
|
|
|
TAG_SKIP(2),
|
|
|
|
TPTAG_IDENT("foo"),
|
|
|
|
TSTTAG_HEADER_STR("X: Y"),
|
|
|
|
TPTAG_IDENT("bar"),
|
|
|
|
TAG_NULL());
|
|
|
|
|
|
|
|
TEST_1(lst);
|
|
|
|
|
|
|
|
result = tl_afilter(home, tport_tags, lst);
|
|
|
|
|
|
|
|
TEST_1(result);
|
|
|
|
TEST_P(result[0].t_tag, tptag_ident);
|
|
|
|
TEST_P(result[1].t_tag, tptag_ident);
|
|
|
|
|
|
|
|
free(lst);
|
|
|
|
su_home_deinit(home);
|
|
|
|
|
|
|
|
END();
|
|
|
|
}
|
|
|
|
|
2007-04-15 02:03:41 +00:00
|
|
|
void usage(int exitcode)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "usage: %s [-v] [-a]\n", name);
|
|
|
|
exit(exitcode);
|
|
|
|
}
|
|
|
|
|
2006-12-21 06:30:28 +00:00
|
|
|
int main(int argc, char *argv[])
|
|
|
|
{
|
|
|
|
int flags = 0; /* XXX */
|
|
|
|
int retval = 0;
|
|
|
|
int i;
|
|
|
|
tp_test_t tt[1] = {{{ SU_HOME_INIT(tt) }}};
|
|
|
|
|
|
|
|
for (i = 1; argv[i]; i++) {
|
2007-04-15 02:03:41 +00:00
|
|
|
if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbatim") == 0)
|
2006-12-21 06:30:28 +00:00
|
|
|
tstflags |= tst_verbatim;
|
2007-04-15 02:03:41 +00:00
|
|
|
else if (strcmp(argv[i], "-a") == 0 || strcmp(argv[i], "--abort") == 0)
|
|
|
|
tstflags |= tst_abort;
|
2006-12-21 06:30:28 +00:00
|
|
|
else
|
2007-04-15 02:03:41 +00:00
|
|
|
usage(1);
|
2006-12-21 06:30:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Use log */
|
|
|
|
if (flags & tst_verbatim)
|
|
|
|
tport_log->log_default = 9;
|
|
|
|
else
|
|
|
|
tport_log->log_default = 1;
|
|
|
|
|
|
|
|
su_init();
|
|
|
|
|
|
|
|
retval |= name_test(tt); fflush(stdout);
|
|
|
|
retval |= filter_test(tt); fflush(stdout);
|
|
|
|
|
|
|
|
retval |= init_test(tt); fflush(stdout);
|
|
|
|
if (retval == 0) {
|
|
|
|
retval |= sigcomp_test(tt); fflush(stdout);
|
|
|
|
retval |= sctp_test(tt); fflush(stdout);
|
|
|
|
retval |= udp_test(tt); fflush(stdout);
|
|
|
|
retval |= tcp_test(tt); fflush(stdout);
|
|
|
|
retval |= reuse_test(tt); fflush(stdout);
|
|
|
|
retval |= tls_test(tt); fflush(stdout);
|
|
|
|
if (0) /* Not yet working... */
|
|
|
|
retval |= stun_test(tt); fflush(stdout);
|
|
|
|
retval |= deinit_test(tt); fflush(stdout);
|
|
|
|
}
|
|
|
|
|
|
|
|
su_deinit();
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|