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