blob: 3594aff0c1eaf12a50b040028f2d71376e7a0d8a [file] [log] [blame]
Benny Prijonoe93e2872006-06-28 16:46:49 +00001/* $Id$ */
2/*
Benny Prijono32177c02008-06-20 22:44:47 +00003 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
Benny Prijonoe93e2872006-06-28 16:46:49 +00004 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include "test.h"
21#include <pjsip.h>
22#include <pjlib.h>
23
24#define THIS_FILE "transport_tcp_test.c"
25
26
27/*
28 * TCP transport test.
29 */
Benny Prijono3569c0d2007-04-06 10:29:20 +000030#if PJ_HAS_TCP
Benny Prijonoe93e2872006-06-28 16:46:49 +000031int transport_tcp_test(void)
32{
33 enum { SEND_RECV_LOOP = 8 };
34 pjsip_tpfactory *tpfactory;
35 pjsip_transport *tcp;
36 pj_sockaddr_in rem_addr;
37 pj_status_t status;
Benny Prijonoe85bc412006-07-29 20:29:24 +000038 char url[PJSIP_MAX_URL_SIZE];
Benny Prijono7db431e2006-07-23 14:38:49 +000039 int rtt[SEND_RECV_LOOP], min_rtt;
Benny Prijonoe93e2872006-06-28 16:46:49 +000040 int i, pkt_lost;
41
42 /* Start TCP listener on arbitrary port. */
43 status = pjsip_tcp_transport_start(endpt, NULL, 1, &tpfactory);
44 if (status != PJ_SUCCESS) {
45 app_perror(" Error: unable to start TCP transport", status);
46 return -10;
47 }
48
49
50 /* Get the listener address */
51 status = pj_sockaddr_in_init(&rem_addr, &tpfactory->addr_name.host,
52 (pj_uint16_t)tpfactory->addr_name.port);
53 if (status != PJ_SUCCESS) {
54 app_perror(" Error: possibly invalid TCP address name", status);
55 return -14;
56 }
57
58 pj_ansi_sprintf(url, "sip:alice@%s:%d;transport=tcp",
59 pj_inet_ntoa(rem_addr.sin_addr),
60 pj_ntohs(rem_addr.sin_port));
61
62
63 /* Acquire one TCP transport. */
64 status = pjsip_endpt_acquire_transport(endpt, PJSIP_TRANSPORT_TCP,
65 &rem_addr, sizeof(rem_addr),
Benny Prijonodf2b71e2007-01-20 19:17:47 +000066 NULL, &tcp);
Benny Prijonoe93e2872006-06-28 16:46:49 +000067 if (status != PJ_SUCCESS || tcp == NULL) {
68 app_perror(" Error: unable to acquire TCP transport", status);
69 return -17;
70 }
71
72 /* After pjsip_endpt_acquire_transport, TCP transport must have
73 * reference counter 1.
74 */
75 if (pj_atomic_get(tcp->ref_cnt) != 1)
76 return -20;
77
78 /* Test basic transport attributes */
79 status = generic_transport_test(tcp);
80 if (status != PJ_SUCCESS)
81 return status;
82
83
84 /* Check again that reference counter is 1. */
85 if (pj_atomic_get(tcp->ref_cnt) != 1)
86 return -70;
87
88 /* Basic transport's send/receive loopback test. */
89 for (i=0; i<SEND_RECV_LOOP; ++i) {
90 status = transport_send_recv_test(PJSIP_TRANSPORT_TCP, tcp, url, &rtt[i]);
91
92 if (status != 0) {
93 pjsip_transport_dec_ref(tcp);
94 flush_events(500);
95 return -72;
96 }
97 }
98
99 min_rtt = 0xFFFFFFF;
100 for (i=0; i<SEND_RECV_LOOP; ++i)
101 if (rtt[i] < min_rtt) min_rtt = rtt[i];
102
103 report_ival("tcp-rtt-usec", min_rtt, "usec",
104 "Best TCP transport round trip time, in microseconds "
105 "(time from sending request until response is received. "
106 "Tests were performed on local machine only, and after "
107 "TCP socket has been established by previous test)");
108
109
110 /* Multi-threaded round-trip test. */
111 status = transport_rt_test(PJSIP_TRANSPORT_TCP, tcp, url, &pkt_lost);
112 if (status != 0) {
113 pjsip_transport_dec_ref(tcp);
114 return status;
115 }
116
117 if (pkt_lost != 0)
118 PJ_LOG(3,(THIS_FILE, " note: %d packet(s) was lost", pkt_lost));
119
120 /* Check again that reference counter is still 1. */
121 if (pj_atomic_get(tcp->ref_cnt) != 1)
122 return -80;
123
124 /* Destroy this transport. */
125 pjsip_transport_dec_ref(tcp);
126
127 /* Force destroy this transport. */
128 status = pjsip_transport_destroy(tcp);
129 if (status != PJ_SUCCESS)
130 return -90;
131
132 /* Unregister factory */
133 status = pjsip_tpmgr_unregister_tpfactory(pjsip_endpt_get_tpmgr(endpt),
134 tpfactory);
135 if (status != PJ_SUCCESS)
136 return -95;
137
138 /* Flush events. */
139 PJ_LOG(3,(THIS_FILE, " Flushing events, 1 second..."));
140 flush_events(1000);
141
142 /* Done */
143 return 0;
144}
Benny Prijono3569c0d2007-04-06 10:29:20 +0000145#else /* PJ_HAS_TCP */
146int transport_tcp_test(void)
147{
148 return 0;
149}
150#endif /* PJ_HAS_TCP */