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 #include <pjsip/sip_transport.h>
21 #include <pjsip/sip_endpoint.h>
22 #include <pjsip/sip_parser.h>
23 #include <pjsip/sip_msg.h>
24 #include <pjsip/sip_private.h>
25 #include <pjsip/sip_errno.h>
26 #include <pjsip/sip_module.h>
27 #include <pj/addr_resolv.h>
28 #include <pj/except.h>
29 #include <pj/os.h>
30 #include <pj/log.h>
31 #include <pj/ioqueue.h>
32 #include <pj/hash.h>
33 #include <pj/string.h>
34 #include <pj/pool.h>
35 #include <pj/assert.h>
36 #include <pj/lock.h>
37 #include <pj/list.h>
38 
39 
40 #define THIS_FILE    "sip_transport.c"
41 
42 #if 0
43 #   define TRACE_(x)	PJ_LOG(5,x)
44 
45 static const char *addr_string(const pj_sockaddr_t *addr)
46 {
47     static char str[PJ_INET6_ADDRSTRLEN];
48     pj_inet_ntop(((const pj_sockaddr*)addr)->addr.sa_family,
49 		 pj_sockaddr_get_addr(addr),
50 		 str, sizeof(str));
51     return str;
52 }
53 static const char* print_tpsel_info(const pjsip_tpselector *sel)
54 {
55     static char tpsel_info_buf[80];
56     if (!sel) return "(null)";
57     if (sel->type==PJSIP_TPSELECTOR_LISTENER)
58 	pj_ansi_snprintf(tpsel_info_buf, sizeof(tpsel_info_buf),
59 			 "listener[%s], reuse=%d", sel->u.listener->obj_name,
60 			 !sel->disable_connection_reuse);
61     else if (sel->type==PJSIP_TPSELECTOR_TRANSPORT)
62 	pj_ansi_snprintf(tpsel_info_buf, sizeof(tpsel_info_buf),
63 			 "transport[%s], reuse=%d", sel->u.transport->info,
64 			 !sel->disable_connection_reuse);
65     else
66 	pj_ansi_snprintf(tpsel_info_buf, sizeof(tpsel_info_buf),
67 			 "unknown[%p], reuse=%d", sel->u.ptr,
68 			 !sel->disable_connection_reuse);
69     return tpsel_info_buf;
70 }
71 #else
72 #   define TRACE_(x)
73 #endif
74 
75 /* Specify the initial size of the transport manager's pool. */
76 #ifndef  TPMGR_POOL_INIT_SIZE
77 #   define TPMGR_POOL_INIT_SIZE	64
78 #endif
79 
80 /* Specify the increment size of the transport manager's pool. */
81 #ifndef TPMGR_POOL_INC_SIZE
82     #define TPMGR_POOL_INC_SIZE	64
83 #endif
84 
85 /* Specify transport entry allocation count. When registering a new transport,
86  * a new entry will be picked from a free list. This setting will determine
87  * the size of the free list size. If all entry is used, then the same number
88  * of entry will be allocated.
89  */
90 #ifndef PJSIP_TRANSPORT_ENTRY_ALLOC_CNT
91 #   define PJSIP_TRANSPORT_ENTRY_ALLOC_CNT  16
92 #endif
93 
94 /* Prototype. */
95 static pj_status_t mod_on_tx_msg(pjsip_tx_data *tdata);
96 
97 /* This module has sole purpose to print transmit data to contigous buffer
98  * before actually transmitted to the wire.
99  */
100 static pjsip_module mod_msg_print =
101 {
102     NULL, NULL,				/* prev and next		    */
103     { "mod-msg-print", 13},		/* Name.			    */
104     -1,					/* Id				    */
105     PJSIP_MOD_PRIORITY_TRANSPORT_LAYER,	/* Priority			    */
106     NULL,				/* load()			    */
107     NULL,				/* start()			    */
108     NULL,				/* stop()			    */
109     NULL,				/* unload()			    */
110     NULL,				/* on_rx_request()		    */
111     NULL,				/* on_rx_response()		    */
112     &mod_on_tx_msg,			/* on_tx_request()		    */
113     &mod_on_tx_msg,			/* on_tx_response()		    */
114     NULL,				/* on_tsx_state()		    */
115 };
116 
117 /* Transport list item */
118 typedef struct transport
119 {
120     PJ_DECL_LIST_MEMBER(struct transport);
121     pj_hash_entry_buf tp_buf;
122     pjsip_transport *tp;
123 } transport;
124 
125 /*
126  * Transport manager.
127  */
128 struct pjsip_tpmgr
129 {
130     pj_hash_table_t *table;
131     pj_lock_t	    *lock;
132     pjsip_endpoint  *endpt;
133     pjsip_tpfactory  factory_list;
134     pj_pool_t	    *pool;
135 #if defined(PJ_DEBUG) && PJ_DEBUG!=0
136     pj_atomic_t	    *tdata_counter;
137 #endif
138     void           (*on_rx_msg)(pjsip_endpoint*, pj_status_t, pjsip_rx_data*);
139     pj_status_t	   (*on_tx_msg)(pjsip_endpoint*, pjsip_tx_data*);
140     pjsip_tp_state_callback tp_state_cb;
141     pjsip_tp_on_rx_dropped_cb tp_drop_data_cb;
142 
143     /* Transmit data list, for transmit data cleanup when transport manager
144      * is destroyed.
145      */
146     pjsip_tx_data    tdata_list;
147 
148     /* List of free transport entry. */
149     transport	     tp_entry_freelist;
150 };
151 
152 
153 /* Transport state listener list type */
154 typedef struct tp_state_listener
155 {
156     PJ_DECL_LIST_MEMBER(struct tp_state_listener);
157 
158     pjsip_tp_state_callback  cb;
159     void *user_data;
160 } tp_state_listener;
161 
162 
163 /*
164  * Transport data.
165  */
166 typedef struct transport_data
167 {
168     /* Transport listeners */
169     tp_state_listener	    st_listeners;
170     tp_state_listener	    st_listeners_empty;
171 } transport_data;
172 
173 
174 /*****************************************************************************
175  *
176  * GENERAL TRANSPORT (NAMES, TYPES, ETC.)
177  *
178  *****************************************************************************/
179 
180 /*
181  * Transport names.
182  */
183 static struct transport_names_t
184 {
185     pjsip_transport_type_e type;	    /* Transport type	    */
186     pj_uint16_t		   port;	    /* Default port number  */
187     pj_str_t		   name;	    /* Id tag		    */
188     const char		  *description;	    /* Longer description   */
189     unsigned		   flag;	    /* Flags		    */
190     char		   name_buf[16];    /* For user's transport */
191 } transport_names[16] =
192 {
193     {
194 	PJSIP_TRANSPORT_UNSPECIFIED,
195 	0,
196 	{"Unspecified", 11},
197 	"Unspecified",
198 	0
199     },
200     {
201 	PJSIP_TRANSPORT_UDP,
202 	5060,
203 	{"UDP", 3},
204 	"UDP transport",
205 	PJSIP_TRANSPORT_DATAGRAM
206     },
207     {
208 	PJSIP_TRANSPORT_TCP,
209 	5060,
210 	{"TCP", 3},
211 	"TCP transport",
212 	PJSIP_TRANSPORT_RELIABLE
213     },
214     {
215 	PJSIP_TRANSPORT_TLS,
216 	5061,
217 	{"TLS", 3},
218 	"TLS transport",
219 	PJSIP_TRANSPORT_RELIABLE | PJSIP_TRANSPORT_SECURE
220     },
221     {
222 	PJSIP_TRANSPORT_DTLS,
223 	5061,
224 	{"DTLS", 4},
225 	"DTLS transport",
226 	PJSIP_TRANSPORT_SECURE
227     },
228     {
229 	PJSIP_TRANSPORT_SCTP,
230 	5060,
231 	{"SCTP", 4},
232 	"SCTP transport",
233 	PJSIP_TRANSPORT_RELIABLE
234     },
235     {
236 	PJSIP_TRANSPORT_LOOP,
237 	15060,
238 	{"LOOP", 4},
239 	"Loopback transport",
240 	PJSIP_TRANSPORT_RELIABLE
241     },
242     {
243 	PJSIP_TRANSPORT_LOOP_DGRAM,
244 	15060,
245 	{"LOOP-DGRAM", 10},
246 	"Loopback datagram transport",
247 	PJSIP_TRANSPORT_DATAGRAM
248     },
249     {
250 	PJSIP_TRANSPORT_UDP6,
251 	5060,
252 	{"UDP", 3},
253 	"UDP IPv6 transport",
254 	PJSIP_TRANSPORT_DATAGRAM
255     },
256     {
257 	PJSIP_TRANSPORT_TCP6,
258 	5060,
259 	{"TCP", 3},
260 	"TCP IPv6 transport",
261 	PJSIP_TRANSPORT_RELIABLE
262     },
263     {
264 	PJSIP_TRANSPORT_TLS6,
265 	5061,
266 	{"TLS", 3},
267 	"TLS IPv6 transport",
268 	PJSIP_TRANSPORT_RELIABLE | PJSIP_TRANSPORT_SECURE
269     },
270     {
271 	PJSIP_TRANSPORT_DTLS6,
272 	5061,
273 	{"DTLS", 4},
274 	"DTLS IPv6 transport",
275 	PJSIP_TRANSPORT_SECURE
276     },
277 };
278 
279 static void tp_state_callback(pjsip_transport *tp,
280 			      pjsip_transport_state state,
281 			      const pjsip_transport_state_info *info);
282 
283 
get_tpname(pjsip_transport_type_e type)284 static struct transport_names_t *get_tpname(pjsip_transport_type_e type)
285 {
286     unsigned i;
287     for (i=0; i<PJ_ARRAY_SIZE(transport_names); ++i) {
288 	if (transport_names[i].type == type)
289 	    return &transport_names[i];
290     }
291     pj_assert(!"Invalid transport type!");
292     return NULL;
293 }
294 
295 
296 
297 /*
298  * Register new transport type to PJSIP.
299  */
pjsip_transport_register_type(unsigned tp_flag,const char * tp_name,int def_port,int * p_tp_type)300 PJ_DEF(pj_status_t) pjsip_transport_register_type( unsigned tp_flag,
301 						   const char *tp_name,
302 						   int def_port,
303 						   int *p_tp_type)
304 {
305     unsigned i;
306     pjsip_transport_type_e parent = 0;
307 
308     PJ_ASSERT_RETURN(tp_flag && tp_name && def_port, PJ_EINVAL);
309     PJ_ASSERT_RETURN(pj_ansi_strlen(tp_name) <
310 			PJ_ARRAY_SIZE(transport_names[0].name_buf),
311 		     PJ_ENAMETOOLONG);
312 
313     for (i=1; i<PJ_ARRAY_SIZE(transport_names); ++i) {
314         if (tp_flag & PJSIP_TRANSPORT_IPV6 &&
315             pj_stricmp2(&transport_names[i].name, tp_name) == 0)
316         {
317 	    parent = transport_names[i].type;
318         }
319 	if (transport_names[i].type == 0)
320 	    break;
321     }
322 
323     if (i == PJ_ARRAY_SIZE(transport_names))
324 	return PJ_ETOOMANY;
325 
326     if (tp_flag & PJSIP_TRANSPORT_IPV6 && parent) {
327         transport_names[i].type = parent | PJSIP_TRANSPORT_IPV6;
328     } else {
329         transport_names[i].type = (pjsip_transport_type_e)i;
330     }
331 
332     transport_names[i].port = (pj_uint16_t)def_port;
333     pj_ansi_strcpy(transport_names[i].name_buf, tp_name);
334     transport_names[i].name = pj_str(transport_names[i].name_buf);
335     transport_names[i].flag = tp_flag;
336 
337     if (p_tp_type)
338 	*p_tp_type = transport_names[i].type;
339 
340     return PJ_SUCCESS;
341 }
342 
343 
344 /*
345  * Get transport type from name.
346  */
pjsip_transport_get_type_from_name(const pj_str_t * name)347 PJ_DEF(pjsip_transport_type_e) pjsip_transport_get_type_from_name(const pj_str_t *name)
348 {
349     unsigned i;
350 
351     if (name->slen == 0)
352 	return PJSIP_TRANSPORT_UNSPECIFIED;
353 
354     /* Get transport type from name. */
355     for (i=0; i<PJ_ARRAY_SIZE(transport_names); ++i) {
356 	if (pj_stricmp(name, &transport_names[i].name) == 0) {
357 	    return transport_names[i].type;
358 	}
359     }
360 
361     pj_assert(!"Invalid transport name");
362     return PJSIP_TRANSPORT_UNSPECIFIED;
363 }
364 
365 
366 /*
367  * Get the transport type for the specified flags.
368  */
pjsip_transport_get_type_from_flag(unsigned flag)369 PJ_DEF(pjsip_transport_type_e) pjsip_transport_get_type_from_flag(unsigned flag)
370 {
371     unsigned i;
372 
373     /* Get the transport type for the specified flags. */
374     for (i=0; i<PJ_ARRAY_SIZE(transport_names); ++i) {
375 	if (transport_names[i].flag == flag) {
376 	    return transport_names[i].type;
377 	}
378     }
379 
380     pj_assert(!"Invalid transport type");
381     return PJSIP_TRANSPORT_UNSPECIFIED;
382 }
383 
384 /*
385  * Get the socket address family of a given transport type.
386  */
pjsip_transport_type_get_af(pjsip_transport_type_e type)387 PJ_DEF(int) pjsip_transport_type_get_af(pjsip_transport_type_e type)
388 {
389     if (type & PJSIP_TRANSPORT_IPV6)
390 	return pj_AF_INET6();
391     else
392 	return pj_AF_INET();
393 }
394 
pjsip_transport_get_flag_from_type(pjsip_transport_type_e type)395 PJ_DEF(unsigned) pjsip_transport_get_flag_from_type(pjsip_transport_type_e type)
396 {
397     /* Return transport flag. */
398     return get_tpname(type)->flag;
399 }
400 
401 /*
402  * Get the default SIP port number for the specified type.
403  */
pjsip_transport_get_default_port_for_type(pjsip_transport_type_e type)404 PJ_DEF(int) pjsip_transport_get_default_port_for_type(pjsip_transport_type_e type)
405 {
406     /* Return the port. */
407     return get_tpname(type)->port;
408 }
409 
410 /*
411  * Get transport name.
412  */
pjsip_transport_get_type_name(pjsip_transport_type_e type)413 PJ_DEF(const char*) pjsip_transport_get_type_name(pjsip_transport_type_e type)
414 {
415     /* Return the name. */
416     return get_tpname(type)->name.ptr;
417 }
418 
419 /*
420  * Get transport description.
421  */
pjsip_transport_get_type_desc(pjsip_transport_type_e type)422 PJ_DEF(const char*) pjsip_transport_get_type_desc(pjsip_transport_type_e type)
423 {
424     /* Return the description. */
425     return get_tpname(type)->description;
426 }
427 
428 
429 /*****************************************************************************
430  *
431  * TRANSPORT SELECTOR
432  *
433  *****************************************************************************/
434 
435 /*
436  * Add transport/listener reference in the selector.
437  */
pjsip_tpselector_add_ref(pjsip_tpselector * sel)438 PJ_DEF(void) pjsip_tpselector_add_ref(pjsip_tpselector *sel)
439 {
440     if (sel->type == PJSIP_TPSELECTOR_TRANSPORT && sel->u.transport != NULL)
441 	pjsip_transport_add_ref(sel->u.transport);
442     else if (sel->type == PJSIP_TPSELECTOR_LISTENER && sel->u.listener != NULL)
443 	; /* Hmm.. looks like we don't have reference counter for listener */
444 }
445 
446 
447 /*
448  * Decrement transport/listener reference in the selector.
449  */
pjsip_tpselector_dec_ref(pjsip_tpselector * sel)450 PJ_DEF(void) pjsip_tpselector_dec_ref(pjsip_tpselector *sel)
451 {
452     if (sel->type == PJSIP_TPSELECTOR_TRANSPORT && sel->u.transport != NULL)
453 	pjsip_transport_dec_ref(sel->u.transport);
454     else if (sel->type == PJSIP_TPSELECTOR_LISTENER && sel->u.listener != NULL)
455 	; /* Hmm.. looks like we don't have reference counter for listener */
456 }
457 
458 
459 /*****************************************************************************
460  *
461  * TRANSMIT DATA BUFFER MANIPULATION.
462  *
463  *****************************************************************************/
464 
465 /*
466  * Create new transmit buffer.
467  */
pjsip_tx_data_create(pjsip_tpmgr * mgr,pjsip_tx_data ** p_tdata)468 PJ_DEF(pj_status_t) pjsip_tx_data_create( pjsip_tpmgr *mgr,
469 					  pjsip_tx_data **p_tdata )
470 {
471     pj_pool_t *pool;
472     pjsip_tx_data *tdata;
473     pj_status_t status;
474 
475     PJ_ASSERT_RETURN(mgr && p_tdata, PJ_EINVAL);
476 
477     pool = pjsip_endpt_create_pool( mgr->endpt, "tdta%p",
478 				    PJSIP_POOL_LEN_TDATA,
479 				    PJSIP_POOL_INC_TDATA );
480     if (!pool)
481 	return PJ_ENOMEM;
482 
483     tdata = PJ_POOL_ZALLOC_T(pool, pjsip_tx_data);
484     tdata->pool = pool;
485     tdata->mgr = mgr;
486     pj_ansi_snprintf(tdata->obj_name, sizeof(tdata->obj_name), "tdta%p", tdata);
487     pj_memcpy(pool->obj_name, tdata->obj_name, sizeof(pool->obj_name));
488 
489     status = pj_atomic_create(tdata->pool, 0, &tdata->ref_cnt);
490     if (status != PJ_SUCCESS) {
491 	pjsip_endpt_release_pool( mgr->endpt, tdata->pool );
492 	return status;
493     }
494 
495     //status = pj_lock_create_simple_mutex(pool, "tdta%p", &tdata->lock);
496     status = pj_lock_create_null_mutex(pool, "tdta%p", &tdata->lock);
497     if (status != PJ_SUCCESS) {
498 	pjsip_endpt_release_pool( mgr->endpt, tdata->pool );
499 	return status;
500     }
501 
502     pj_ioqueue_op_key_init(&tdata->op_key.key, sizeof(tdata->op_key.key));
503     pj_list_init(tdata);
504 
505 #if defined(PJSIP_HAS_TX_DATA_LIST) && PJSIP_HAS_TX_DATA_LIST!=0
506     /* Append this just created tdata to transmit buffer list */
507     pj_lock_acquire(mgr->lock);
508     pj_list_push_back(&mgr->tdata_list, tdata);
509     pj_lock_release(mgr->lock);
510 #endif
511 
512 #if defined(PJ_DEBUG) && PJ_DEBUG!=0
513     pj_atomic_inc( tdata->mgr->tdata_counter );
514 #endif
515 
516     *p_tdata = tdata;
517     return PJ_SUCCESS;
518 }
519 
520 
521 /*
522  * Add reference to tx buffer.
523  */
pjsip_tx_data_add_ref(pjsip_tx_data * tdata)524 PJ_DEF(void) pjsip_tx_data_add_ref( pjsip_tx_data *tdata )
525 {
526     pj_atomic_inc(tdata->ref_cnt);
527 }
528 
tx_data_destroy(pjsip_tx_data * tdata)529 static void tx_data_destroy(pjsip_tx_data *tdata)
530 {
531     PJ_LOG(5,(tdata->obj_name, "Destroying txdata %s",
532 	      pjsip_tx_data_get_info(tdata)));
533     pjsip_tpselector_dec_ref(&tdata->tp_sel);
534 #if defined(PJ_DEBUG) && PJ_DEBUG!=0
535     pj_atomic_dec( tdata->mgr->tdata_counter );
536 #endif
537 
538 #if defined(PJSIP_HAS_TX_DATA_LIST) && PJSIP_HAS_TX_DATA_LIST!=0
539     /* Remove this tdata from transmit buffer list */
540     pj_lock_acquire(tdata->mgr->lock);
541     pj_list_erase(tdata);
542     pj_lock_release(tdata->mgr->lock);
543 #endif
544 
545     pj_atomic_destroy( tdata->ref_cnt );
546     pj_lock_destroy( tdata->lock );
547     pjsip_endpt_release_pool( tdata->mgr->endpt, tdata->pool );
548 }
549 
550 /*
551  * Decrease transport data reference, destroy it when the reference count
552  * reaches zero.
553  */
pjsip_tx_data_dec_ref(pjsip_tx_data * tdata)554 PJ_DEF(pj_status_t) pjsip_tx_data_dec_ref( pjsip_tx_data *tdata )
555 {
556     pj_atomic_value_t ref_cnt;
557 
558     PJ_ASSERT_RETURN(tdata && tdata->ref_cnt, PJ_EINVAL);
559 
560     ref_cnt = pj_atomic_dec_and_get(tdata->ref_cnt);
561     pj_assert( ref_cnt >= 0);
562     if (ref_cnt == 0) {
563 	tx_data_destroy(tdata);
564 	return PJSIP_EBUFDESTROYED;
565     } else {
566 	return PJ_SUCCESS;
567     }
568 }
569 
570 /*
571  * Invalidate the content of the print buffer to force the message to be
572  * re-printed when sent.
573  */
pjsip_tx_data_invalidate_msg(pjsip_tx_data * tdata)574 PJ_DEF(void) pjsip_tx_data_invalidate_msg( pjsip_tx_data *tdata )
575 {
576     tdata->buf.cur = tdata->buf.start;
577     tdata->info = NULL;
578 }
579 
580 /*
581  * Print the SIP message to transmit data buffer's internal buffer.
582  */
pjsip_tx_data_encode(pjsip_tx_data * tdata)583 PJ_DEF(pj_status_t) pjsip_tx_data_encode(pjsip_tx_data *tdata)
584 {
585     /* Allocate buffer if necessary. */
586     if (tdata->buf.start == NULL) {
587 	PJ_USE_EXCEPTION;
588 
589 	PJ_TRY {
590 	    tdata->buf.start = (char*)
591 			       pj_pool_alloc(tdata->pool, PJSIP_MAX_PKT_LEN);
592 	}
593 	PJ_CATCH_ANY {
594 	    return PJ_ENOMEM;
595 	}
596 	PJ_END
597 
598 	tdata->buf.cur = tdata->buf.start;
599 	tdata->buf.end = tdata->buf.start + PJSIP_MAX_PKT_LEN;
600     }
601 
602     /* Do we need to reprint? */
603     if (!pjsip_tx_data_is_valid(tdata)) {
604 	pj_ssize_t size;
605 
606 	size = pjsip_msg_print( tdata->msg, tdata->buf.start,
607 			        tdata->buf.end - tdata->buf.start);
608 	if (size < 0) {
609 	    return PJSIP_EMSGTOOLONG;
610 	}
611 	pj_assert(size != 0);
612 	tdata->buf.cur[size] = '\0';
613 	tdata->buf.cur += size;
614     }
615 
616     return PJ_SUCCESS;
617 }
618 
pjsip_tx_data_is_valid(pjsip_tx_data * tdata)619 PJ_DEF(pj_bool_t) pjsip_tx_data_is_valid( pjsip_tx_data *tdata )
620 {
621     return tdata->buf.cur != tdata->buf.start;
622 }
623 
get_msg_info(pj_pool_t * pool,const char * obj_name,const pjsip_msg * msg)624 static char *get_msg_info(pj_pool_t *pool, const char *obj_name,
625 			  const pjsip_msg *msg)
626 {
627     char info_buf[128], *info;
628     const pjsip_cseq_hdr *cseq;
629     int len;
630 
631     cseq = (const pjsip_cseq_hdr*) pjsip_msg_find_hdr(msg, PJSIP_H_CSEQ, NULL);
632     PJ_ASSERT_RETURN(cseq != NULL, "INVALID MSG");
633 
634     if (msg->type == PJSIP_REQUEST_MSG) {
635 	len = pj_ansi_snprintf(info_buf, sizeof(info_buf),
636 			       "Request msg %.*s/cseq=%d (%s)",
637 			       (int)msg->line.req.method.name.slen,
638 			       msg->line.req.method.name.ptr,
639 			       cseq->cseq, obj_name);
640     } else {
641 	len = pj_ansi_snprintf(info_buf, sizeof(info_buf),
642 			       "Response msg %d/%.*s/cseq=%d (%s)",
643 			       msg->line.status.code,
644 			       (int)cseq->method.name.slen,
645 			       cseq->method.name.ptr,
646 			       cseq->cseq, obj_name);
647     }
648 
649     if (len < 1 || len >= (int)sizeof(info_buf)) {
650 	return (char*)obj_name;
651     }
652 
653     info = (char*) pj_pool_alloc(pool, len+1);
654     pj_memcpy(info, info_buf, len+1);
655 
656     return info;
657 }
658 
pjsip_tx_data_get_info(pjsip_tx_data * tdata)659 PJ_DEF(char*) pjsip_tx_data_get_info( pjsip_tx_data *tdata )
660 {
661     PJ_ASSERT_RETURN(tdata, "NULL");
662 
663     /* tdata->info may be assigned by application so if it exists
664      * just return it.
665      */
666     if (tdata->info)
667 	return tdata->info;
668 
669     if (tdata->msg==NULL)
670 	return "NULL";
671 
672     pj_lock_acquire(tdata->lock);
673     tdata->info = get_msg_info(tdata->pool, tdata->obj_name, tdata->msg);
674     pj_lock_release(tdata->lock);
675 
676     return tdata->info;
677 }
678 
pjsip_tx_data_set_transport(pjsip_tx_data * tdata,const pjsip_tpselector * sel)679 PJ_DEF(pj_status_t) pjsip_tx_data_set_transport(pjsip_tx_data *tdata,
680 						const pjsip_tpselector *sel)
681 {
682     PJ_ASSERT_RETURN(tdata && sel, PJ_EINVAL);
683 
684     pj_lock_acquire(tdata->lock);
685 
686     pjsip_tpselector_dec_ref(&tdata->tp_sel);
687 
688     pj_memcpy(&tdata->tp_sel, sel, sizeof(*sel));
689     pjsip_tpselector_add_ref(&tdata->tp_sel);
690 
691     pj_lock_release(tdata->lock);
692 
693     return PJ_SUCCESS;
694 }
695 
696 /* Clone pjsip_tx_data. */
pjsip_tx_data_clone(const pjsip_tx_data * src,unsigned flags,pjsip_tx_data ** p_tdata)697 PJ_DEF(pj_status_t) pjsip_tx_data_clone(const pjsip_tx_data *src,
698                                         unsigned flags,
699 				  	pjsip_tx_data ** p_tdata)
700 {
701     pjsip_tx_data *dst;
702     const pjsip_hdr *hsrc;
703     pjsip_msg *msg;
704     pj_status_t status;
705 
706     PJ_UNUSED_ARG(flags);
707 
708     status = pjsip_tx_data_create(src->mgr, p_tdata);
709     if (status != PJ_SUCCESS)
710 	return status;
711 
712     dst = *p_tdata;
713 
714     msg = pjsip_msg_create(dst->pool, PJSIP_RESPONSE_MSG);
715     dst->msg = msg;
716     pjsip_tx_data_add_ref(dst);
717 
718     /* Duplicate status line */
719     msg->line.status.code = src->msg->line.status.code;
720     pj_strdup(dst->pool, &msg->line.status.reason,
721 	      &src->msg->line.status.reason);
722 
723     /* Duplicate all headers */
724     hsrc = src->msg->hdr.next;
725     while (hsrc != &src->msg->hdr) {
726 	pjsip_hdr *h = (pjsip_hdr*) pjsip_hdr_clone(dst->pool, hsrc);
727 	pjsip_msg_add_hdr(msg, h);
728 	hsrc = hsrc->next;
729     }
730 
731     /* Duplicate message body */
732     if (src->msg->body)
733 	msg->body = pjsip_msg_body_clone(dst->pool, src->msg->body);
734 
735     /* We shouldn't copy is_pending since it's src's internal state,
736      * indicating that it's currently being sent by the transport.
737      * While the cloned tdata is of course not.
738      */
739     //dst->is_pending = src->is_pending;
740 
741     PJ_LOG(5,(THIS_FILE,
742 	     "Tx data %s cloned",
743 	     pjsip_tx_data_get_info(dst)));
744 
745     return PJ_SUCCESS;
746 }
747 
pjsip_rx_data_get_info(pjsip_rx_data * rdata)748 PJ_DEF(char*) pjsip_rx_data_get_info(pjsip_rx_data *rdata)
749 {
750     char obj_name[PJ_MAX_OBJ_NAME];
751 
752     PJ_ASSERT_RETURN(rdata->msg_info.msg, "INVALID MSG");
753 
754     if (rdata->msg_info.info)
755 	return rdata->msg_info.info;
756 
757     pj_ansi_strcpy(obj_name, "rdata");
758     pj_ansi_snprintf(obj_name+5, sizeof(obj_name)-5, "%p", rdata);
759 
760     rdata->msg_info.info = get_msg_info(rdata->tp_info.pool, obj_name,
761 					rdata->msg_info.msg);
762     return rdata->msg_info.info;
763 }
764 
765 /* Clone pjsip_rx_data. */
pjsip_rx_data_clone(const pjsip_rx_data * src,unsigned flags,pjsip_rx_data ** p_rdata)766 PJ_DEF(pj_status_t) pjsip_rx_data_clone( const pjsip_rx_data *src,
767                                          unsigned flags,
768                                          pjsip_rx_data **p_rdata)
769 {
770     pj_pool_t *pool;
771     pjsip_rx_data *dst;
772     pjsip_hdr *hdr;
773 
774     PJ_ASSERT_RETURN(src && flags==0 && p_rdata, PJ_EINVAL);
775 
776     pool = pj_pool_create(src->tp_info.pool->factory,
777                           "rtd%p",
778                           PJSIP_POOL_RDATA_LEN,
779                           PJSIP_POOL_RDATA_INC,
780                           NULL);
781     if (!pool)
782 	return PJ_ENOMEM;
783 
784     dst = PJ_POOL_ZALLOC_T(pool, pjsip_rx_data);
785 
786     /* Parts of tp_info */
787     dst->tp_info.pool = pool;
788     dst->tp_info.transport = (pjsip_transport*)src->tp_info.transport;
789 
790     /* pkt_info can be memcopied */
791     pj_memcpy(&dst->pkt_info, &src->pkt_info, sizeof(src->pkt_info));
792 
793     /* msg_info needs deep clone */
794     dst->msg_info.msg_buf = dst->pkt_info.packet +
795 			    (src->msg_info.msg_buf - src->pkt_info.packet);
796     dst->msg_info.len = src->msg_info.len;
797     dst->msg_info.msg = pjsip_msg_clone(pool, src->msg_info.msg);
798     pj_list_init(&dst->msg_info.parse_err);
799 
800 #define GET_MSG_HDR2(TYPE, type, var)	\
801 			case PJSIP_H_##TYPE: \
802 			    if (!dst->msg_info.var) { \
803 				dst->msg_info.var = (pjsip_##type##_hdr*)hdr; \
804 			    } \
805 			    break
806 #define GET_MSG_HDR(TYPE, var_type)	GET_MSG_HDR2(TYPE, var_type, var_type)
807 
808     hdr = dst->msg_info.msg->hdr.next;
809     while (hdr != &dst->msg_info.msg->hdr) {
810 	switch (hdr->type) {
811 	GET_MSG_HDR(CALL_ID, cid);
812 	GET_MSG_HDR(FROM, from);
813 	GET_MSG_HDR(TO, to);
814 	GET_MSG_HDR(VIA, via);
815 	GET_MSG_HDR(CSEQ, cseq);
816 	GET_MSG_HDR(MAX_FORWARDS, max_fwd);
817 	GET_MSG_HDR(ROUTE, route);
818 	GET_MSG_HDR2(RECORD_ROUTE, rr, record_route);
819 	GET_MSG_HDR(CONTENT_TYPE, ctype);
820 	GET_MSG_HDR(CONTENT_LENGTH, clen);
821 	GET_MSG_HDR(REQUIRE, require);
822 	GET_MSG_HDR(SUPPORTED, supported);
823 	default:
824 	    break;
825 	}
826 	hdr = hdr->next;
827     }
828 
829 #undef GET_MSG_HDR
830 #undef GET_MSG_HDR2
831 
832     *p_rdata = dst;
833 
834     /* Finally add transport ref */
835     return pjsip_transport_add_ref(dst->tp_info.transport);
836 }
837 
838 /* Free previously cloned pjsip_rx_data. */
pjsip_rx_data_free_cloned(pjsip_rx_data * rdata)839 PJ_DEF(pj_status_t) pjsip_rx_data_free_cloned(pjsip_rx_data *rdata)
840 {
841     PJ_ASSERT_RETURN(rdata, PJ_EINVAL);
842 
843     pjsip_transport_dec_ref(rdata->tp_info.transport);
844     pj_pool_release(rdata->tp_info.pool);
845 
846     return PJ_SUCCESS;
847 }
848 
849 /*****************************************************************************
850  *
851  * TRANSPORT KEY
852  *
853  *****************************************************************************/
854 
855 
856 /*****************************************************************************
857  *
858  * TRANSPORT
859  *
860  *****************************************************************************/
861 
transport_send_callback(pjsip_transport * transport,void * token,pj_ssize_t size)862 static void transport_send_callback(pjsip_transport *transport,
863 				    void *token,
864 				    pj_ssize_t size)
865 {
866     pjsip_tx_data *tdata = (pjsip_tx_data*) token;
867 
868     PJ_UNUSED_ARG(transport);
869 
870     /* Mark pending off so that app can resend/reuse txdata from inside
871      * the callback.
872      */
873     tdata->is_pending = 0;
874 
875     /* Call callback, if any. */
876     if (tdata->cb) {
877 	(*tdata->cb)(tdata->token, tdata, size);
878     }
879 
880     /* Decrement reference count. */
881     pjsip_tx_data_dec_ref(tdata);
882 }
883 
884 /* This function is called by endpoint for on_tx_request() and on_tx_response()
885  * notification.
886  */
mod_on_tx_msg(pjsip_tx_data * tdata)887 static pj_status_t mod_on_tx_msg(pjsip_tx_data *tdata)
888 {
889     return pjsip_tx_data_encode(tdata);
890 }
891 
892 /*
893  * Send a SIP message using the specified transport.
894  */
pjsip_transport_send(pjsip_transport * tr,pjsip_tx_data * tdata,const pj_sockaddr_t * addr,int addr_len,void * token,pjsip_tp_send_callback cb)895 PJ_DEF(pj_status_t) pjsip_transport_send(  pjsip_transport *tr,
896 					   pjsip_tx_data *tdata,
897 					   const pj_sockaddr_t *addr,
898 					   int addr_len,
899 					   void *token,
900 					   pjsip_tp_send_callback cb)
901 {
902     pj_status_t status;
903 
904     PJ_ASSERT_RETURN(tr && tdata && addr, PJ_EINVAL);
905 
906     /* Is it currently being sent? */
907     if (tdata->is_pending) {
908 	pj_assert(!"Invalid operation step!");
909 	PJ_LOG(2,(THIS_FILE, "Unable to send %s: message is pending",
910 			     pjsip_tx_data_get_info(tdata)));
911 	return PJSIP_EPENDINGTX;
912     }
913 
914     /* Add reference to prevent deletion, and to cancel idle timer if
915      * it's running.
916      */
917     pjsip_transport_add_ref(tr);
918 
919     /* Fill in tp_info. */
920     tdata->tp_info.transport = tr;
921     pj_memcpy(&tdata->tp_info.dst_addr, addr, addr_len);
922     tdata->tp_info.dst_addr_len = addr_len;
923 
924     pj_inet_ntop(((pj_sockaddr*)addr)->addr.sa_family,
925 		 pj_sockaddr_get_addr(addr),
926 		 tdata->tp_info.dst_name,
927 		 sizeof(tdata->tp_info.dst_name));
928     tdata->tp_info.dst_port = pj_sockaddr_get_port(addr);
929 
930     /* Distribute to modules.
931      * When the message reach mod_msg_print, the contents of the message will
932      * be "printed" to contiguous buffer.
933      */
934     if (tr->tpmgr->on_tx_msg) {
935 	status = (*tr->tpmgr->on_tx_msg)(tr->endpt, tdata);
936 	if (status != PJ_SUCCESS) {
937 	    pjsip_transport_dec_ref(tr);
938 	    return status;
939 	}
940     }
941 
942     /* Save callback data. */
943     tdata->token = token;
944     tdata->cb = cb;
945 
946     /* Add reference counter. */
947     pjsip_tx_data_add_ref(tdata);
948 
949     /* Mark as pending. */
950     tdata->is_pending = 1;
951 
952     /* Send to transport. */
953     status = (*tr->send_msg)(tr, tdata,  addr, addr_len, (void*)tdata,
954 			     &transport_send_callback);
955 
956     if (status != PJ_EPENDING) {
957 	tdata->is_pending = 0;
958 	pjsip_tx_data_dec_ref(tdata);
959     }
960 
961     pjsip_transport_dec_ref(tr);
962     return status;
963 }
964 
965 
966 /* send_raw() callback */
send_raw_callback(pjsip_transport * transport,void * token,pj_ssize_t size)967 static void send_raw_callback(pjsip_transport *transport,
968 			      void *token,
969 			      pj_ssize_t size)
970 {
971     pjsip_tx_data *tdata = (pjsip_tx_data*) token;
972 
973     /* Mark pending off so that app can resend/reuse txdata from inside
974      * the callback.
975      */
976     tdata->is_pending = 0;
977 
978     /* Call callback, if any. */
979     if (tdata->cb) {
980 	(*tdata->cb)(tdata->token, tdata, size);
981     }
982 
983     /* Decrement tdata reference count. */
984     pjsip_tx_data_dec_ref(tdata);
985 
986     /* Decrement transport reference count */
987     pjsip_transport_dec_ref(transport);
988 }
989 
990 
991 /* Send raw data */
pjsip_tpmgr_send_raw(pjsip_tpmgr * mgr,pjsip_transport_type_e tp_type,const pjsip_tpselector * sel,pjsip_tx_data * tdata,const void * raw_data,pj_size_t data_len,const pj_sockaddr_t * addr,int addr_len,void * token,pjsip_tp_send_callback cb)992 PJ_DEF(pj_status_t) pjsip_tpmgr_send_raw(pjsip_tpmgr *mgr,
993 					 pjsip_transport_type_e tp_type,
994 					 const pjsip_tpselector *sel,
995 					 pjsip_tx_data *tdata,
996 					 const void *raw_data,
997 					 pj_size_t data_len,
998 					 const pj_sockaddr_t *addr,
999 					 int addr_len,
1000 					 void *token,
1001 					 pjsip_tp_send_callback cb)
1002 {
1003     pjsip_transport *tr;
1004     pj_status_t status;
1005 
1006     /* Acquire the transport */
1007     status = pjsip_tpmgr_acquire_transport(mgr, tp_type, addr, addr_len,
1008 					   sel, &tr);
1009     if (status != PJ_SUCCESS)
1010 	return status;
1011 
1012     /* Create transmit data buffer if one is not specified */
1013     if (tdata == NULL) {
1014 	status = pjsip_endpt_create_tdata(tr->endpt, &tdata);
1015 	if (status != PJ_SUCCESS) {
1016 	    pjsip_transport_dec_ref(tr);
1017 	    return status;
1018 	}
1019 
1020 	tdata->info = "raw";
1021 
1022 	/* Add reference counter. */
1023 	pjsip_tx_data_add_ref(tdata);
1024     }
1025 
1026     /* Allocate buffer */
1027     if (tdata->buf.start == NULL ||
1028 	(tdata->buf.end - tdata->buf.start) < (int)data_len)
1029     {
1030 	/* Note: data_len may be zero, so allocate +1 */
1031 	tdata->buf.start = (char*) pj_pool_alloc(tdata->pool, data_len+1);
1032 	tdata->buf.end = tdata->buf.start + data_len + 1;
1033     }
1034 
1035     /* Copy data, if any! (application may send zero len packet) */
1036     if (data_len) {
1037 	pj_memcpy(tdata->buf.start, raw_data, data_len);
1038     }
1039     tdata->buf.cur = tdata->buf.start + data_len;
1040 
1041     /* Save callback data. */
1042     tdata->token = token;
1043     tdata->cb = cb;
1044 
1045     /* Mark as pending. */
1046     tdata->is_pending = 1;
1047 
1048     /* Send to transport */
1049     status = tr->send_msg(tr, tdata, addr, addr_len,
1050 			  tdata, &send_raw_callback);
1051 
1052     if (status != PJ_EPENDING) {
1053 	/* callback will not be called, so destroy tdata now. */
1054 	pjsip_tx_data_dec_ref(tdata);
1055 	pjsip_transport_dec_ref(tr);
1056     }
1057 
1058     return status;
1059 }
1060 
1061 
transport_idle_callback(pj_timer_heap_t * timer_heap,struct pj_timer_entry * entry)1062 static void transport_idle_callback(pj_timer_heap_t *timer_heap,
1063 				    struct pj_timer_entry *entry)
1064 {
1065     pjsip_transport *tp = (pjsip_transport*) entry->user_data;
1066     pj_assert(tp != NULL);
1067 
1068     PJ_UNUSED_ARG(timer_heap);
1069 
1070     if (entry->id == PJ_FALSE)
1071 	return;
1072 
1073     entry->id = PJ_FALSE;
1074 
1075     /* Set is_destroying flag under transport manager mutex to avoid
1076      * race condition with pjsip_tpmgr_acquire_transport2().
1077      */
1078     pj_lock_acquire(tp->tpmgr->lock);
1079     if (pj_atomic_get(tp->ref_cnt) == 0) {
1080 	tp->is_destroying = PJ_TRUE;
1081     } else {
1082 	pj_lock_release(tp->tpmgr->lock);
1083 	return;
1084     }
1085     pj_lock_release(tp->tpmgr->lock);
1086 
1087     pjsip_transport_destroy(tp);
1088 }
1089 
1090 
is_transport_valid(pjsip_transport * tp,pjsip_tpmgr * tpmgr,const pjsip_transport_key * key,int key_len)1091 static pj_bool_t is_transport_valid(pjsip_transport *tp, pjsip_tpmgr *tpmgr,
1092 				    const pjsip_transport_key *key,
1093 				    int key_len)
1094 {
1095     transport *tp_entry;
1096 
1097     tp_entry = (transport *)pj_hash_get(tpmgr->table, key, key_len, NULL);
1098     if (tp_entry != NULL) {
1099 
1100 	transport *tp_iter = tp_entry;
1101 	do {
1102 	    if (tp_iter->tp == tp) {
1103 		return PJ_TRUE;
1104 	    }
1105 	    tp_iter = tp_iter->next;
1106 	} while (tp_iter != tp_entry);
1107     }
1108 
1109     return PJ_FALSE;
1110 }
1111 
1112 /*
1113  * Add ref.
1114  */
pjsip_transport_add_ref(pjsip_transport * tp)1115 PJ_DEF(pj_status_t) pjsip_transport_add_ref( pjsip_transport *tp )
1116 {
1117     pjsip_tpmgr *tpmgr;
1118     pjsip_transport_key key;
1119     int key_len;
1120 
1121     PJ_ASSERT_RETURN(tp != NULL, PJ_EINVAL);
1122 
1123     /* Add ref transport group lock, if any */
1124     if (tp->grp_lock)
1125 	pj_grp_lock_add_ref(tp->grp_lock);
1126 
1127     /* Cache some vars for checking transport validity later */
1128     tpmgr = tp->tpmgr;
1129     key_len = sizeof(tp->key.type) + tp->addr_len;
1130     pj_memcpy(&key, &tp->key, key_len);
1131 
1132     if (pj_atomic_inc_and_get(tp->ref_cnt) == 1) {
1133 	pj_lock_acquire(tpmgr->lock);
1134 	/* Verify again. But first, make sure transport is still valid
1135 	 * (see #1883).
1136 	 */
1137 	if (is_transport_valid(tp, tpmgr, &key, key_len) &&
1138 	    pj_atomic_get(tp->ref_cnt) == 1)
1139 	{
1140 	    if (tp->idle_timer.id != PJ_FALSE) {
1141 		tp->idle_timer.id = PJ_FALSE;
1142 		pjsip_endpt_cancel_timer(tp->tpmgr->endpt, &tp->idle_timer);
1143 	    }
1144 	}
1145 	pj_lock_release(tpmgr->lock);
1146     }
1147 
1148     return PJ_SUCCESS;
1149 }
1150 
1151 /*
1152  * Dec ref.
1153  */
pjsip_transport_dec_ref(pjsip_transport * tp)1154 PJ_DEF(pj_status_t) pjsip_transport_dec_ref( pjsip_transport *tp )
1155 {
1156     pjsip_tpmgr *tpmgr;
1157     pjsip_transport_key key;
1158     int key_len;
1159 
1160     PJ_ASSERT_RETURN(tp != NULL, PJ_EINVAL);
1161     pj_assert(pj_atomic_get(tp->ref_cnt) > 0);
1162 
1163     /* Cache some vars for checking transport validity later */
1164     tpmgr = tp->tpmgr;
1165     key_len = sizeof(tp->key.type) + tp->addr_len;
1166     pj_memcpy(&key, &tp->key, key_len);
1167 
1168     if (pj_atomic_dec_and_get(tp->ref_cnt) == 0) {
1169 	pj_lock_acquire(tpmgr->lock);
1170 	/* Verify again. Do not register timer if the transport is
1171 	 * being destroyed. But first, make sure transport is still valid
1172 	 * (see #1883).
1173 	 */
1174 	if (is_transport_valid(tp, tpmgr, &key, key_len) &&
1175 	    !tp->is_destroying && pj_atomic_get(tp->ref_cnt) == 0)
1176 	{
1177 	    pj_time_val delay;
1178 
1179 	    /* If transport is in graceful shutdown, then this is the
1180 	     * last user who uses the transport. Schedule to destroy the
1181 	     * transport immediately. Otherwise schedule idle timer.
1182 	     */
1183 	    if (tp->is_shutdown) {
1184 		delay.sec = delay.msec = 0;
1185 	    } else {
1186 		delay.sec = (tp->dir==PJSIP_TP_DIR_OUTGOING) ?
1187 				PJSIP_TRANSPORT_IDLE_TIME :
1188 				PJSIP_TRANSPORT_SERVER_IDLE_TIME;
1189 		delay.msec = 0;
1190 	    }
1191 
1192 	    /* Avoid double timer entry scheduling */
1193 	    if (pj_timer_entry_running(&tp->idle_timer))
1194 		pjsip_endpt_cancel_timer(tp->tpmgr->endpt, &tp->idle_timer);
1195 
1196 	    pjsip_endpt_schedule_timer_w_grp_lock(tp->tpmgr->endpt,
1197 						  &tp->idle_timer,
1198 						  &delay,
1199 						  PJ_TRUE,
1200 						  tp->grp_lock);
1201 	}
1202 	pj_lock_release(tpmgr->lock);
1203     }
1204 
1205     /* Dec ref transport group lock, if any */
1206     if (tp->grp_lock) {
1207 	pj_grp_lock_dec_ref(tp->grp_lock);
1208     }
1209 
1210     return PJ_SUCCESS;
1211 }
1212 
1213 
1214 /**
1215  * Register a transport.
1216  */
pjsip_transport_register(pjsip_tpmgr * mgr,pjsip_transport * tp)1217 PJ_DEF(pj_status_t) pjsip_transport_register( pjsip_tpmgr *mgr,
1218 					      pjsip_transport *tp )
1219 {
1220     int key_len;
1221     pj_uint32_t hval;
1222     transport *tp_ref = NULL;
1223     transport *tp_add = NULL;
1224 
1225     /* Init. */
1226     tp->tpmgr = mgr;
1227     pj_bzero(&tp->idle_timer, sizeof(tp->idle_timer));
1228     tp->idle_timer.user_data = tp;
1229     tp->idle_timer.cb = &transport_idle_callback;
1230 
1231     /*
1232      * Register to hash table (see Trac ticket #42).
1233      */
1234     key_len = sizeof(tp->key.type) + tp->addr_len;
1235     pj_lock_acquire(mgr->lock);
1236 
1237     hval = 0;
1238     tp_ref = (transport *)pj_hash_get(mgr->table, &tp->key, key_len, &hval);
1239 
1240     /* Get an empty entry from the freelist. */
1241     if (pj_list_empty(&mgr->tp_entry_freelist)) {
1242 	unsigned i = 0;
1243 
1244 	TRACE_((THIS_FILE, "Transport list is full, allocate new entry"));
1245 	/* Allocate new entry for the freelist. */
1246 	for (; i < PJSIP_TRANSPORT_ENTRY_ALLOC_CNT; ++i) {
1247 	    tp_add = PJ_POOL_ZALLOC_T(mgr->pool, transport);
1248 	    if (!tp_add)
1249 		return PJ_ENOMEM;
1250 	    pj_list_init(tp_add);
1251 	    pj_list_push_back(&mgr->tp_entry_freelist, tp_add);
1252 	}
1253     }
1254     tp_add = mgr->tp_entry_freelist.next;
1255     tp_add->tp = tp;
1256     pj_list_erase(tp_add);
1257 
1258     if (tp_ref) {
1259 	/* There'a already a transport list from the hash table. Add the
1260 	 * new transport to the list.
1261 	 */
1262 	pj_list_push_back(tp_ref, tp_add);
1263 	TRACE_((THIS_FILE, "Remote address already registered, "
1264 			   "appended the transport to the list"));
1265     } else {
1266 	/* Transport list not found, add it to the hash table. */
1267 	pj_hash_set_np(mgr->table, &tp->key, key_len, hval, tp_add->tp_buf,
1268 		       tp_add);
1269 	TRACE_((THIS_FILE, "Remote address not registered, "
1270 			   "added the transport to the hash"));
1271     }
1272 
1273     /* Add ref transport group lock, if any */
1274     if (tp->grp_lock)
1275 	pj_grp_lock_add_ref(tp->grp_lock);
1276 
1277     pj_lock_release(mgr->lock);
1278 
1279     TRACE_((THIS_FILE, "Transport %s registered: type=%s, remote=%s:%d",
1280 	    tp->obj_name,
1281 	    pjsip_transport_get_type_name(tp->key.type),
1282 	    pj_sockaddr_has_addr(&tp->key.rem_addr)?
1283 				addr_string(&tp->key.rem_addr):"",
1284 	    pj_sockaddr_has_addr(&tp->key.rem_addr)?
1285 				pj_sockaddr_get_port(&tp->key.rem_addr):0));
1286 
1287     return PJ_SUCCESS;
1288 }
1289 
1290 /* Force destroy transport (e.g. during transport manager shutdown. */
destroy_transport(pjsip_tpmgr * mgr,pjsip_transport * tp)1291 static pj_status_t destroy_transport( pjsip_tpmgr *mgr,
1292 				      pjsip_transport *tp )
1293 {
1294     int key_len;
1295     pj_uint32_t hval;
1296     void *entry;
1297 
1298     tp->is_destroying = PJ_TRUE;
1299 
1300     TRACE_((THIS_FILE, "Transport %s is being destroyed", tp->obj_name));
1301 
1302     pj_lock_acquire(tp->lock);
1303     pj_lock_acquire(mgr->lock);
1304 
1305     /*
1306      * Unregister timer, if any.
1307      */
1308     //pj_assert(tp->idle_timer.id == PJ_FALSE);
1309     if (tp->idle_timer.id != PJ_FALSE) {
1310 	tp->idle_timer.id = PJ_FALSE;
1311 	pjsip_endpt_cancel_timer(mgr->endpt, &tp->idle_timer);
1312     }
1313 
1314     /*
1315      * Unregister from hash table (see Trac ticket #42).
1316      */
1317     key_len = sizeof(tp->key.type) + tp->addr_len;
1318     hval = 0;
1319     entry = pj_hash_get(mgr->table, &tp->key, key_len, &hval);
1320     if (entry) {
1321 	transport *tp_ref = (transport *)entry;
1322 	transport *tp_iter = tp_ref;
1323 	/* Search the matching entry from the transport list. */
1324 	do {
1325 	    if (tp_iter->tp == tp) {
1326 		transport *tp_next = tp_iter->next;
1327 
1328 		/* Update hash table :
1329 		 * - transport list only contain single element, or
1330 		 * - the entry is the first element of the transport list.
1331 		 */
1332 		if (tp_iter == tp_ref) {
1333 		    pj_hash_set(NULL, mgr->table, &tp->key, key_len, hval,
1334 				NULL);
1335 
1336 		    if (tp_ref->next != tp_ref) {
1337 			/* The transport list has multiple entry. */
1338 			pj_hash_set_np(mgr->table, &tp_next->tp->key, key_len,
1339 				       hval, tp_next->tp_buf, tp_next);
1340 			TRACE_((THIS_FILE, "Hash entry updated after "
1341 					   "transport %d being destroyed",
1342 					   tp->obj_name));
1343 		    } else {
1344 			TRACE_((THIS_FILE, "Hash entry deleted after "
1345 					   "transport %d being destroyed",
1346 					   tp->obj_name));
1347 		    }
1348 		}
1349 
1350 		pj_list_erase(tp_iter);
1351 		/* Put back to the transport freelist. */
1352 		pj_list_push_back(&mgr->tp_entry_freelist, tp_iter);
1353 
1354 		break;
1355 	    }
1356 	    tp_iter = tp_iter->next;
1357 	} while (tp_iter != tp_ref);
1358 
1359 	if (tp_iter->tp != tp) {
1360 	    PJ_LOG(3, (THIS_FILE, "Warning: transport %s being destroyed is "
1361 				  "not registered", tp->obj_name));
1362 	}
1363     } else {
1364 	PJ_LOG(3, (THIS_FILE, "Warning: transport %s being destroyed is "
1365 			      "not found in the hash table", tp->obj_name));
1366     }
1367 
1368     pj_lock_release(mgr->lock);
1369     pj_lock_release(tp->lock);
1370 
1371     /* Dec ref transport group lock, if any */
1372     if (tp->grp_lock) {
1373 	pj_grp_lock_dec_ref(tp->grp_lock);
1374     }
1375 
1376     /* Destroy. */
1377     return tp->destroy(tp);
1378 }
1379 
1380 
1381 /*
1382  * Start graceful shutdown procedure for this transport.
1383  */
pjsip_transport_shutdown(pjsip_transport * tp)1384 PJ_DEF(pj_status_t) pjsip_transport_shutdown(pjsip_transport *tp)
1385 {
1386     return pjsip_transport_shutdown2(tp, PJ_FALSE);
1387 }
1388 
1389 
1390 /*
1391  * Start shutdown procedure for this transport.
1392  */
pjsip_transport_shutdown2(pjsip_transport * tp,pj_bool_t force)1393 PJ_DEF(pj_status_t) pjsip_transport_shutdown2(pjsip_transport *tp,
1394 					      pj_bool_t force)
1395 {
1396     pjsip_tpmgr *mgr;
1397     pj_status_t status;
1398     pjsip_tp_state_callback state_cb;
1399 
1400     PJ_LOG(4, (THIS_FILE, "Transport %s shutting down, force=%d",
1401 			  tp->obj_name, force));
1402 
1403     pj_lock_acquire(tp->lock);
1404 
1405     mgr = tp->tpmgr;
1406     pj_lock_acquire(mgr->lock);
1407 
1408     /* Do nothing if transport is being shutdown/destroyed already */
1409     if (tp->is_shutdown || tp->is_destroying) {
1410 	pj_lock_release(mgr->lock);
1411 	pj_lock_release(tp->lock);
1412 	return PJ_SUCCESS;
1413     }
1414 
1415     status = PJ_SUCCESS;
1416 
1417     /* Instruct transport to shutdown itself */
1418     if (tp->do_shutdown)
1419 	status = tp->do_shutdown(tp);
1420 
1421     if (status == PJ_SUCCESS)
1422 	tp->is_shutdown = PJ_TRUE;
1423 
1424     /* Notify application of transport shutdown */
1425     state_cb = pjsip_tpmgr_get_state_cb(tp->tpmgr);
1426     if (state_cb) {
1427 	pjsip_transport_state_info state_info;
1428 
1429 	pj_bzero(&state_info, sizeof(state_info));
1430 	state_info.status = PJ_ECANCELLED;
1431 	(*state_cb)(tp, (force? PJSIP_TP_STATE_DISCONNECTED:
1432 		    PJSIP_TP_STATE_SHUTDOWN), &state_info);
1433     }
1434 
1435     /* If transport reference count is zero, start timer count-down */
1436     if (pj_atomic_get(tp->ref_cnt) == 0) {
1437 	pjsip_transport_add_ref(tp);
1438 	pjsip_transport_dec_ref(tp);
1439     }
1440 
1441     pj_lock_release(mgr->lock);
1442     pj_lock_release(tp->lock);
1443 
1444     return status;
1445 }
1446 
1447 
1448 /**
1449  * Unregister transport.
1450  */
pjsip_transport_destroy(pjsip_transport * tp)1451 PJ_DEF(pj_status_t) pjsip_transport_destroy( pjsip_transport *tp)
1452 {
1453     pjsip_tp_state_callback state_cb;
1454 
1455     /* Must have no user. */
1456     PJ_ASSERT_RETURN(pj_atomic_get(tp->ref_cnt) == 0, PJSIP_EBUSY);
1457 
1458     /* Notify application of transport destroy */
1459     state_cb = pjsip_tpmgr_get_state_cb(tp->tpmgr);
1460     if (state_cb) {
1461 	pjsip_transport_state_info state_info;
1462 
1463 	pj_bzero(&state_info, sizeof(state_info));
1464         (*state_cb)(tp, PJSIP_TP_STATE_DESTROY, &state_info);
1465     }
1466 
1467     /* Destroy. */
1468     return destroy_transport(tp->tpmgr, tp);
1469 }
1470 
1471 
1472 
1473 /*****************************************************************************
1474  *
1475  * TRANSPORT FACTORY
1476  *
1477  *****************************************************************************/
1478 
1479 
pjsip_tpmgr_register_tpfactory(pjsip_tpmgr * mgr,pjsip_tpfactory * tpf)1480 PJ_DEF(pj_status_t) pjsip_tpmgr_register_tpfactory( pjsip_tpmgr *mgr,
1481 						    pjsip_tpfactory *tpf)
1482 {
1483     pjsip_tpfactory *p;
1484     pj_status_t status;
1485 
1486     pj_lock_acquire(mgr->lock);
1487 
1488     /* Check that no same factory has been registered. */
1489     status = PJ_SUCCESS;
1490     for (p=mgr->factory_list.next; p!=&mgr->factory_list; p=p->next) {
1491 	if (p == tpf) {
1492 	    status = PJ_EEXISTS;
1493 	    break;
1494 	}
1495     }
1496 
1497     if (status != PJ_SUCCESS) {
1498 	pj_lock_release(mgr->lock);
1499 	return status;
1500     }
1501 
1502     pj_list_insert_before(&mgr->factory_list, tpf);
1503 
1504     pj_lock_release(mgr->lock);
1505 
1506     return PJ_SUCCESS;
1507 }
1508 
1509 
1510 /**
1511  * Unregister factory.
1512  */
pjsip_tpmgr_unregister_tpfactory(pjsip_tpmgr * mgr,pjsip_tpfactory * tpf)1513 PJ_DEF(pj_status_t) pjsip_tpmgr_unregister_tpfactory( pjsip_tpmgr *mgr,
1514 						      pjsip_tpfactory *tpf)
1515 {
1516     pj_lock_acquire(mgr->lock);
1517 
1518     pj_assert(pj_list_find_node(&mgr->factory_list, tpf) == tpf);
1519     pj_list_erase(tpf);
1520 
1521     pj_lock_release(mgr->lock);
1522 
1523     return PJ_SUCCESS;
1524 }
1525 
pjsip_tpmgr_fla2_param_default(pjsip_tpmgr_fla2_param * prm)1526 PJ_DECL(void) pjsip_tpmgr_fla2_param_default(pjsip_tpmgr_fla2_param *prm)
1527 {
1528     pj_bzero(prm, sizeof(*prm));
1529 }
1530 
pjsip_tpmgr_is_tpfactory_valid(pjsip_tpmgr * mgr,pjsip_tpfactory * tpf)1531 static pj_bool_t pjsip_tpmgr_is_tpfactory_valid(pjsip_tpmgr *mgr,
1532 						pjsip_tpfactory *tpf)
1533 {
1534     pjsip_tpfactory *p;
1535 
1536     pj_lock_acquire(mgr->lock);
1537     for (p=mgr->factory_list.next; p!=&mgr->factory_list; p=p->next) {
1538 	if (p == tpf) {
1539 	    pj_lock_release(mgr->lock);
1540 	    return PJ_TRUE;
1541 	}
1542     }
1543     pj_lock_release(mgr->lock);
1544 
1545     return PJ_FALSE;
1546 }
1547 
1548 /*****************************************************************************
1549  *
1550  * TRANSPORT MANAGER
1551  *
1552  *****************************************************************************/
1553 
1554 /*
1555  * Create a new transport manager.
1556  */
pjsip_tpmgr_create(pj_pool_t * pool,pjsip_endpoint * endpt,pjsip_rx_callback rx_cb,pjsip_tx_callback tx_cb,pjsip_tpmgr ** p_mgr)1557 PJ_DEF(pj_status_t) pjsip_tpmgr_create( pj_pool_t *pool,
1558 					pjsip_endpoint *endpt,
1559 					pjsip_rx_callback rx_cb,
1560 					pjsip_tx_callback tx_cb,
1561 					pjsip_tpmgr **p_mgr)
1562 {
1563     pjsip_tpmgr *mgr;
1564     pj_status_t status;
1565     unsigned i = 0;
1566     pj_pool_t *mgr_pool;
1567 
1568     PJ_ASSERT_RETURN(pool && endpt && rx_cb && p_mgr, PJ_EINVAL);
1569 
1570     /* Register mod_msg_print module. */
1571     status = pjsip_endpt_register_module(endpt, &mod_msg_print);
1572     if (status != PJ_SUCCESS)
1573 	return status;
1574 
1575     /* Create and initialize transport manager. */
1576     mgr_pool = pjsip_endpt_create_pool(endpt, "tpmgr",
1577 				       TPMGR_POOL_INIT_SIZE,
1578 				       TPMGR_POOL_INC_SIZE);
1579     mgr = PJ_POOL_ZALLOC_T(mgr_pool, pjsip_tpmgr);
1580     mgr->endpt = endpt;
1581     mgr->on_rx_msg = rx_cb;
1582     mgr->on_tx_msg = tx_cb;
1583     mgr->pool = mgr_pool;
1584 
1585     if (!mgr->pool)
1586 	return PJ_ENOMEM;
1587 
1588     pj_list_init(&mgr->factory_list);
1589     pj_list_init(&mgr->tdata_list);
1590     pj_list_init(&mgr->tp_entry_freelist);
1591 
1592     mgr->table = pj_hash_create(mgr->pool, PJSIP_TPMGR_HTABLE_SIZE);
1593     if (!mgr->table)
1594 	return PJ_ENOMEM;
1595 
1596     status = pj_lock_create_recursive_mutex(mgr->pool, "tmgr%p", &mgr->lock);
1597     if (status != PJ_SUCCESS)
1598 	return status;
1599 
1600     for (; i < PJSIP_TRANSPORT_ENTRY_ALLOC_CNT; ++i) {
1601 	transport *tp_add = NULL;
1602 
1603 	tp_add = PJ_POOL_ZALLOC_T(mgr->pool, transport);
1604 	if (!tp_add)
1605 	    return PJ_ENOMEM;
1606 	pj_list_init(tp_add);
1607 	pj_list_push_back(&mgr->tp_entry_freelist, tp_add);
1608     }
1609 
1610 #if defined(PJ_DEBUG) && PJ_DEBUG!=0
1611     status = pj_atomic_create(mgr->pool, 0, &mgr->tdata_counter);
1612     if (status != PJ_SUCCESS) {
1613     	pj_lock_destroy(mgr->lock);
1614     	return status;
1615     }
1616 #endif
1617 
1618     /* Set transport state callback */
1619     pjsip_tpmgr_set_state_cb(mgr, &tp_state_callback);
1620 
1621     PJ_LOG(5, (THIS_FILE, "Transport manager created."));
1622 
1623     *p_mgr = mgr;
1624     return PJ_SUCCESS;
1625 }
1626 
1627 /* Get the interface to send packet to the specified address */
get_net_interface(pjsip_transport_type_e tp_type,const pj_str_t * dst,pj_str_t * itf_str_addr)1628 static pj_status_t get_net_interface(pjsip_transport_type_e tp_type,
1629 				     const pj_str_t *dst,
1630                                      pj_str_t *itf_str_addr)
1631 {
1632     int af;
1633     pj_sockaddr itf_addr;
1634     pj_status_t status = -1;
1635 
1636     af = (tp_type & PJSIP_TRANSPORT_IPV6)? pj_AF_INET6() : pj_AF_INET();
1637 
1638     if (pjsip_cfg()->endpt.resolve_hostname_to_get_interface) {
1639 	status = pj_getipinterface(af, dst, &itf_addr, PJ_TRUE, NULL);
1640     }
1641 
1642     if (status != PJ_SUCCESS) {
1643 	status = pj_getipinterface(af, dst, &itf_addr, PJ_FALSE, NULL);
1644 	if (status != PJ_SUCCESS) {
1645 	    /* If it fails, e.g: on WM6(http://support.microsoft.com/kb/129065),
1646 	     * just fallback using pj_gethostip(), see ticket #1660.
1647 	     */
1648 	    PJ_PERROR(5,(THIS_FILE, status,
1649 			 "Warning: unable to determine local interface, "
1650 			 "fallback to default interface!"));
1651 	    status = pj_gethostip(af, &itf_addr);
1652 	    if (status != PJ_SUCCESS)
1653 		return status;
1654 	}
1655     }
1656 
1657     /* Print address */
1658     pj_sockaddr_print(&itf_addr, itf_str_addr->ptr,
1659 		      PJ_INET6_ADDRSTRLEN, 0);
1660     itf_str_addr->slen = pj_ansi_strlen(itf_str_addr->ptr);
1661 
1662     return PJ_SUCCESS;
1663 }
1664 
1665 /*
1666  * Find out the appropriate local address info (IP address and port) to
1667  * advertise in Contact header based on the remote address to be
1668  * contacted. The local address info would be the address name of the
1669  * transport or listener which will be used to send the request.
1670  *
1671  * In this implementation, it will only select the transport based on
1672  * the transport type in the request.
1673  */
pjsip_tpmgr_find_local_addr2(pjsip_tpmgr * tpmgr,pj_pool_t * pool,pjsip_tpmgr_fla2_param * prm)1674 PJ_DEF(pj_status_t) pjsip_tpmgr_find_local_addr2(pjsip_tpmgr *tpmgr,
1675 						 pj_pool_t *pool,
1676 						 pjsip_tpmgr_fla2_param *prm)
1677 {
1678     char tmp_buf[PJ_INET6_ADDRSTRLEN+10];
1679     pj_str_t tmp_str;
1680     pj_status_t status = PJSIP_EUNSUPTRANSPORT;
1681     unsigned flag;
1682 
1683     /* Sanity checks */
1684     PJ_ASSERT_RETURN(tpmgr && pool && prm, PJ_EINVAL);
1685 
1686     pj_strset(&tmp_str, tmp_buf, 0);
1687     prm->ret_addr.slen = 0;
1688     prm->ret_port = 0;
1689     prm->ret_tp = NULL;
1690 
1691     flag = pjsip_transport_get_flag_from_type(prm->tp_type);
1692 
1693     if (prm->tp_sel && prm->tp_sel->type == PJSIP_TPSELECTOR_TRANSPORT &&
1694 	prm->tp_sel->u.transport)
1695     {
1696 	const pjsip_transport *tp = prm->tp_sel->u.transport;
1697 	if (prm->local_if) {
1698 	    status = get_net_interface((pjsip_transport_type_e)tp->key.type,
1699 				       &prm->dst_host, &tmp_str);
1700 	    if (status != PJ_SUCCESS)
1701 		goto on_return;
1702 	    pj_strdup(pool, &prm->ret_addr, &tmp_str);
1703 	    prm->ret_port = pj_sockaddr_get_port(&tp->local_addr);
1704 	    prm->ret_tp = tp;
1705 	} else {
1706 	    pj_strdup(pool, &prm->ret_addr, &tp->local_name.host);
1707 	    prm->ret_port = (pj_uint16_t)tp->local_name.port;
1708 	}
1709 	status = PJ_SUCCESS;
1710 
1711     } else if (prm->tp_sel && prm->tp_sel->type == PJSIP_TPSELECTOR_LISTENER &&
1712 	       prm->tp_sel->u.listener)
1713     {
1714 	if (prm->local_if) {
1715 	    status = get_net_interface(prm->tp_sel->u.listener->type,
1716 	                               &prm->dst_host, &tmp_str);
1717 	    if (status != PJ_SUCCESS)
1718 		goto on_return;
1719 	    pj_strdup(pool, &prm->ret_addr, &tmp_str);
1720 	} else {
1721 	    pj_strdup(pool, &prm->ret_addr,
1722 		      &prm->tp_sel->u.listener->addr_name.host);
1723 	}
1724 	prm->ret_port = (pj_uint16_t)prm->tp_sel->u.listener->addr_name.port;
1725 	status = PJ_SUCCESS;
1726 
1727     } else if ((flag & PJSIP_TRANSPORT_DATAGRAM) != 0) {
1728 	pj_sockaddr remote;
1729 	int addr_len;
1730 	pjsip_transport *tp;
1731 
1732 	pj_bzero(&remote, sizeof(remote));
1733 	if (prm->tp_type & PJSIP_TRANSPORT_IPV6) {
1734 	    addr_len = sizeof(pj_sockaddr_in6);
1735 	    remote.addr.sa_family = pj_AF_INET6();
1736 	} else {
1737 	    addr_len = sizeof(pj_sockaddr_in);
1738 	    remote.addr.sa_family = pj_AF_INET();
1739 	}
1740 
1741 	status = pjsip_tpmgr_acquire_transport(tpmgr, prm->tp_type, &remote,
1742 					       addr_len, NULL, &tp);
1743 
1744 	if (status == PJ_SUCCESS) {
1745 	    if (prm->local_if) {
1746 		status = get_net_interface((pjsip_transport_type_e)
1747 					   tp->key.type,
1748 					   &prm->dst_host, &tmp_str);
1749 		if (status != PJ_SUCCESS)
1750 		    goto on_return;
1751 		pj_strdup(pool, &prm->ret_addr, &tmp_str);
1752 		prm->ret_port = pj_sockaddr_get_port(&tp->local_addr);
1753 		prm->ret_tp = tp;
1754 	    } else {
1755 		pj_strdup(pool, &prm->ret_addr, &tp->local_name.host);
1756 		prm->ret_port = (pj_uint16_t)tp->local_name.port;
1757 	    }
1758 
1759 	    pjsip_transport_dec_ref(tp);
1760 	}
1761 
1762     } else {
1763 	/* For connection oriented transport, enum the factories */
1764 	pjsip_tpfactory *f;
1765 
1766 	pj_lock_acquire(tpmgr->lock);
1767 
1768 	f = tpmgr->factory_list.next;
1769 	while (f != &tpmgr->factory_list) {
1770 	    if (f->type == prm->tp_type)
1771 		break;
1772 	    f = f->next;
1773 	}
1774 
1775 	if (f != &tpmgr->factory_list) {
1776 	    if (prm->local_if) {
1777 		status = get_net_interface(f->type, &prm->dst_host,
1778 					   &tmp_str);
1779 		if (status == PJ_SUCCESS) {
1780 		    pj_strdup(pool, &prm->ret_addr, &tmp_str);
1781 		} else {
1782 		    /* It could fail "normally" on certain cases, e.g.
1783 		     * when connecting to IPv6 link local address, it
1784 		     * will wail with EINVAL.
1785 		     * In this case, fallback to use the default interface
1786 		     * rather than failing the call.
1787 		     */
1788 		    PJ_PERROR(5,(THIS_FILE, status, "Warning: unable to "
1789 			         "determine local interface"));
1790 		    pj_strdup(pool, &prm->ret_addr, &f->addr_name.host);
1791 		    status = PJ_SUCCESS;
1792 		}
1793 	    } else {
1794 		pj_strdup(pool, &prm->ret_addr, &f->addr_name.host);
1795 	    }
1796 	    prm->ret_port = (pj_uint16_t)f->addr_name.port;
1797 	    status = PJ_SUCCESS;
1798 	}
1799 	pj_lock_release(tpmgr->lock);
1800     }
1801 
1802 on_return:
1803     return status;
1804 }
1805 
pjsip_tpmgr_find_local_addr(pjsip_tpmgr * tpmgr,pj_pool_t * pool,pjsip_transport_type_e type,const pjsip_tpselector * sel,pj_str_t * ip_addr,int * port)1806 PJ_DEF(pj_status_t) pjsip_tpmgr_find_local_addr( pjsip_tpmgr *tpmgr,
1807 						 pj_pool_t *pool,
1808 						 pjsip_transport_type_e type,
1809 						 const pjsip_tpselector *sel,
1810 						 pj_str_t *ip_addr,
1811 						 int *port)
1812 {
1813     pjsip_tpmgr_fla2_param prm;
1814     pj_status_t status;
1815 
1816     pjsip_tpmgr_fla2_param_default(&prm);
1817     prm.tp_type = type;
1818     prm.tp_sel = sel;
1819 
1820     status = pjsip_tpmgr_find_local_addr2(tpmgr, pool, &prm);
1821     if (status != PJ_SUCCESS)
1822 	return status;
1823 
1824     *ip_addr = prm.ret_addr;
1825     *port = prm.ret_port;
1826 
1827     return PJ_SUCCESS;
1828 }
1829 
1830 /*
1831  * Return number of transports currently registered to the transport
1832  * manager.
1833  */
pjsip_tpmgr_get_transport_count(pjsip_tpmgr * mgr)1834 PJ_DEF(unsigned) pjsip_tpmgr_get_transport_count(pjsip_tpmgr *mgr)
1835 {
1836     pj_hash_iterator_t itr_val;
1837     pj_hash_iterator_t *itr;
1838     int nr_of_transports = 0;
1839 
1840     pj_lock_acquire(mgr->lock);
1841 
1842     itr = pj_hash_first(mgr->table, &itr_val);
1843     while (itr) {
1844 	transport *tp_entry = (transport *)pj_hash_this(mgr->table, itr);
1845 	nr_of_transports += pj_list_size(tp_entry);
1846 	itr = pj_hash_next(mgr->table, itr);
1847     }
1848 
1849     pj_lock_release(mgr->lock);
1850 
1851     return nr_of_transports;
1852 }
1853 
1854 /*
1855  * pjsip_tpmgr_destroy()
1856  *
1857  * Destroy transport manager.
1858  */
pjsip_tpmgr_destroy(pjsip_tpmgr * mgr)1859 PJ_DEF(pj_status_t) pjsip_tpmgr_destroy( pjsip_tpmgr *mgr )
1860 {
1861     pj_hash_iterator_t itr_val;
1862     pj_hash_iterator_t *itr;
1863     pjsip_tpfactory *factory;
1864     pjsip_endpoint *endpt = mgr->endpt;
1865 
1866     PJ_LOG(5, (THIS_FILE, "Destroying transport manager"));
1867 
1868     pj_lock_acquire(mgr->lock);
1869 
1870     /*
1871      * Destroy all transports in the hash table.
1872      */
1873     for (itr = pj_hash_first(mgr->table, &itr_val); itr;
1874 	 itr = pj_hash_first(mgr->table, &itr_val))
1875     {
1876 	transport *tp_ref;
1877 	tp_ref = pj_hash_this(mgr->table, itr);
1878 	destroy_transport(mgr, tp_ref->tp);
1879     }
1880 
1881     /*
1882      * Destroy all factories/listeners.
1883      */
1884     factory = mgr->factory_list.next;
1885     while (factory != &mgr->factory_list) {
1886 	pjsip_tpfactory *next = factory->next;
1887 
1888 	factory->destroy(factory);
1889 
1890 	factory = next;
1891     }
1892 
1893     pj_lock_release(mgr->lock);
1894 
1895 #if defined(PJ_DEBUG) && PJ_DEBUG!=0
1896     /* If you encounter assert error on this line, it means there are
1897      * leakings in transmit data (i.e. some transmit data have not been
1898      * destroyed).
1899      */
1900     //pj_assert(pj_atomic_get(mgr->tdata_counter) == 0);
1901     if (pj_atomic_get(mgr->tdata_counter) != 0) {
1902 	PJ_LOG(3,(THIS_FILE, "Warning: %d transmit buffer(s) not freed!",
1903 		  pj_atomic_get(mgr->tdata_counter)));
1904     }
1905 #endif
1906 
1907     /*
1908      * Destroy any dangling transmit buffer.
1909      */
1910     if (!pj_list_empty(&mgr->tdata_list)) {
1911 	pjsip_tx_data *tdata = mgr->tdata_list.next;
1912 	while (tdata != &mgr->tdata_list) {
1913 	    pjsip_tx_data *next = tdata->next;
1914 	    tx_data_destroy(tdata);
1915 	    tdata = next;
1916 	}
1917 	PJ_LOG(3,(THIS_FILE, "Cleaned up dangling transmit buffer(s)."));
1918     }
1919 
1920 #if defined(PJ_DEBUG) && PJ_DEBUG!=0
1921     pj_atomic_destroy(mgr->tdata_counter);
1922 #endif
1923 
1924     pj_lock_destroy(mgr->lock);
1925 
1926     /* Unregister mod_msg_print. */
1927     if (mod_msg_print.id != -1) {
1928 	pjsip_endpt_unregister_module(endpt, &mod_msg_print);
1929     }
1930 
1931     if (mgr->pool) {
1932 	pjsip_endpt_release_pool( mgr->endpt, mgr->pool );
1933     }
1934 
1935     return PJ_SUCCESS;
1936 }
1937 
1938 
1939 /*
1940  * pjsip_tpmgr_receive_packet()
1941  *
1942  * Called by tranports when they receive a new packet.
1943  */
pjsip_tpmgr_receive_packet(pjsip_tpmgr * mgr,pjsip_rx_data * rdata)1944 PJ_DEF(pj_ssize_t) pjsip_tpmgr_receive_packet( pjsip_tpmgr *mgr,
1945 					       pjsip_rx_data *rdata)
1946 {
1947     pjsip_transport *tr = rdata->tp_info.transport;
1948 
1949     char *current_pkt;
1950     pj_size_t remaining_len;
1951     pj_size_t total_processed = 0;
1952 
1953     /* Check size. */
1954     pj_assert(rdata->pkt_info.len > 0);
1955     if (rdata->pkt_info.len <= 0)
1956 	return -1;
1957 
1958     current_pkt = rdata->pkt_info.packet;
1959     remaining_len = rdata->pkt_info.len;
1960 
1961     tr->last_recv_len = rdata->pkt_info.len;
1962     pj_get_timestamp(&tr->last_recv_ts);
1963 
1964     /* Must NULL terminate buffer. This is the requirement of the
1965      * parser etc.
1966      */
1967     current_pkt[remaining_len] = '\0';
1968 
1969     /* Process all message fragments. */
1970     while (remaining_len > 0) {
1971 
1972 	pjsip_msg *msg;
1973 	char *p, *end;
1974 	char saved;
1975 	pj_size_t msg_fragment_size;
1976 
1977 	/* Skip leading newlines as pjsip_find_msg() currently can't
1978 	 * handle leading newlines.
1979 	 */
1980 	for (p=current_pkt, end=p+remaining_len; p!=end; ++p) {
1981 	    if (*p != '\r' && *p != '\n')
1982 		break;
1983 	}
1984 	if (p!=current_pkt) {
1985 	    remaining_len -= (p - current_pkt);
1986 	    total_processed += (p - current_pkt);
1987 
1988 	    /* Notify application about the dropped newlines */
1989 	    if (mgr->tp_drop_data_cb) {
1990 		pjsip_tp_dropped_data dd;
1991 		pj_bzero(&dd, sizeof(dd));
1992 		dd.tp = tr;
1993 		dd.data = current_pkt;
1994 		dd.len = p - current_pkt;
1995 		dd.status = PJ_EIGNORED;
1996 		(*mgr->tp_drop_data_cb)(&dd);
1997 	    }
1998 
1999 	    current_pkt = p;
2000 	    if (remaining_len == 0) {
2001 		return total_processed;
2002 	    }
2003 	}
2004 
2005 	/* Initialize default fragment size. */
2006 	msg_fragment_size = remaining_len;
2007 
2008 	/* Clear and init msg_info in rdata.
2009 	 * Endpoint might inspect the values there when we call the callback
2010 	 * to report some errors.
2011 	 */
2012 	pj_bzero(&rdata->msg_info, sizeof(rdata->msg_info));
2013 	pj_list_init(&rdata->msg_info.parse_err);
2014 	rdata->msg_info.msg_buf = current_pkt;
2015 	rdata->msg_info.len = (int)remaining_len;
2016 
2017 	/* For TCP transport, check if the whole message has been received. */
2018 	if ((tr->flag & PJSIP_TRANSPORT_DATAGRAM) == 0) {
2019 	    pj_status_t msg_status;
2020 	    msg_status = pjsip_find_msg(current_pkt, remaining_len, PJ_FALSE,
2021                                         &msg_fragment_size);
2022 	    if (msg_status != PJ_SUCCESS) {
2023 		if (remaining_len == PJSIP_MAX_PKT_LEN) {
2024 		    mgr->on_rx_msg(mgr->endpt, PJSIP_ERXOVERFLOW, rdata);
2025 
2026 		    /* Notify application about the message overflow */
2027 	    	    if (mgr->tp_drop_data_cb) {
2028 			pjsip_tp_dropped_data dd;
2029 			pj_bzero(&dd, sizeof(dd));
2030 			dd.tp = tr;
2031 			dd.data = current_pkt;
2032 			dd.len = msg_fragment_size;
2033 			dd.status = PJSIP_ERXOVERFLOW;
2034 			(*mgr->tp_drop_data_cb)(&dd);
2035 	    	    }
2036 
2037 		    /* Exhaust all data. */
2038 		    return rdata->pkt_info.len;
2039 		} else {
2040 		    /* Not enough data in packet. */
2041 		    return total_processed;
2042 		}
2043 	    }
2044 	}
2045 
2046 	/* Update msg_info. */
2047 	rdata->msg_info.len = (int)msg_fragment_size;
2048 
2049 	/* Null terminate packet */
2050 	saved = current_pkt[msg_fragment_size];
2051 	current_pkt[msg_fragment_size] = '\0';
2052 
2053 	/* Parse the message. */
2054 	rdata->msg_info.msg = msg =
2055 	    pjsip_parse_rdata( current_pkt, msg_fragment_size, rdata);
2056 
2057 	/* Restore null termination */
2058 	current_pkt[msg_fragment_size] = saved;
2059 
2060 	/* Check for parsing syntax error */
2061 	if (msg==NULL || !pj_list_empty(&rdata->msg_info.parse_err)) {
2062 	    pjsip_parser_err_report *err;
2063 	    char buf[256];
2064 	    pj_str_t tmp;
2065 
2066 	    /* Gather syntax error information */
2067 	    tmp.ptr = buf; tmp.slen = 0;
2068 	    err = rdata->msg_info.parse_err.next;
2069 	    while (err != &rdata->msg_info.parse_err) {
2070 		int len;
2071 		len = pj_ansi_snprintf(tmp.ptr+tmp.slen, sizeof(buf)-tmp.slen,
2072 				       ": %s exception when parsing '%.*s' "
2073 				       "header on line %d col %d",
2074 				       pj_exception_id_name(err->except_code),
2075 				       (int)err->hname.slen, err->hname.ptr,
2076 				       err->line, err->col);
2077 		if (len >= (int)sizeof(buf)-tmp.slen) {
2078 		    len = (int)sizeof(buf)-tmp.slen;
2079 		}
2080 		if (len > 0) {
2081 		    tmp.slen += len;
2082 		}
2083 		err = err->next;
2084 	    }
2085 
2086 	    /* Only print error message if there's error.
2087 	     * Sometimes we receive blank packets (packets with only CRLF)
2088 	     * which were sent to keep NAT bindings.
2089 	     */
2090 	    if (tmp.slen) {
2091 		PJ_LOG(1, (THIS_FILE,
2092 		      "Error processing %d bytes packet from %s %s:%d %.*s:\n"
2093 		      "%.*s\n"
2094 		      "-- end of packet.",
2095 		      msg_fragment_size,
2096 		      rdata->tp_info.transport->type_name,
2097 		      rdata->pkt_info.src_name,
2098 		      rdata->pkt_info.src_port,
2099 		      (int)tmp.slen, tmp.ptr,
2100 		      (int)msg_fragment_size,
2101 		      rdata->msg_info.msg_buf));
2102 	    }
2103 
2104 	    /* Notify application about the dropped data (syntax error) */
2105 	    if (tmp.slen && mgr->tp_drop_data_cb) {
2106 		pjsip_tp_dropped_data dd;
2107 		pj_bzero(&dd, sizeof(dd));
2108 		dd.tp = tr;
2109 		dd.data = current_pkt;
2110 		dd.len = msg_fragment_size;
2111 		dd.status = PJSIP_EINVALIDMSG;
2112 		(*mgr->tp_drop_data_cb)(&dd);
2113 
2114 		if (dd.len > 0 && dd.len < msg_fragment_size)
2115 		    msg_fragment_size = dd.len;
2116 	    }
2117 
2118 	    goto finish_process_fragment;
2119 	}
2120 
2121 	/* Perform basic header checking. */
2122 	if (rdata->msg_info.cid == NULL ||
2123 	    rdata->msg_info.cid->id.slen == 0 ||
2124 	    rdata->msg_info.from == NULL ||
2125 	    rdata->msg_info.to == NULL ||
2126 	    rdata->msg_info.via == NULL ||
2127 	    rdata->msg_info.cseq == NULL)
2128 	{
2129 	    mgr->on_rx_msg(mgr->endpt, PJSIP_EMISSINGHDR, rdata);
2130 
2131 	    /* Notify application about the missing header. */
2132 	    if (mgr->tp_drop_data_cb) {
2133 		pjsip_tp_dropped_data dd;
2134 		pj_bzero(&dd, sizeof(dd));
2135 		dd.tp = tr;
2136 		dd.data = current_pkt;
2137 		dd.len = msg_fragment_size;
2138 		dd.status = PJSIP_EMISSINGHDR;
2139 		(*mgr->tp_drop_data_cb)(&dd);
2140 	    }
2141 	    goto finish_process_fragment;
2142 	}
2143 
2144 	/* For request: */
2145 	if (rdata->msg_info.msg->type == PJSIP_REQUEST_MSG) {
2146 	    /* always add received parameter to the via. */
2147 	    pj_strdup2(rdata->tp_info.pool,
2148 		       &rdata->msg_info.via->recvd_param,
2149 		       rdata->pkt_info.src_name);
2150 
2151 	    /* RFC 3581:
2152 	     * If message contains "rport" param, put the received port there.
2153 	     */
2154 	    if (rdata->msg_info.via->rport_param == 0) {
2155 		rdata->msg_info.via->rport_param = rdata->pkt_info.src_port;
2156 	    }
2157 	} else {
2158 	    /* Drop malformed responses */
2159 	    if (rdata->msg_info.msg->line.status.code < 100 ||
2160 		rdata->msg_info.msg->line.status.code >= 700)
2161 	    {
2162 		mgr->on_rx_msg(mgr->endpt, PJSIP_EINVALIDSTATUS, rdata);
2163 
2164 		/* Notify application about the invalid status. */
2165 		if (mgr->tp_drop_data_cb) {
2166 		    pjsip_tp_dropped_data dd;
2167 		    pj_bzero(&dd, sizeof(dd));
2168 		    dd.tp = tr;
2169 		    dd.data = current_pkt;
2170 		    dd.len = msg_fragment_size;
2171 		    dd.status = PJSIP_EINVALIDSTATUS;
2172 		    (*mgr->tp_drop_data_cb)(&dd);
2173 		}
2174 		goto finish_process_fragment;
2175 	    }
2176 	}
2177 
2178 	/* Drop response message if it has more than one Via.
2179 	*/
2180 	/* This is wrong. Proxy DOES receive responses with multiple
2181 	 * Via headers! Thanks Aldo <acampi at deis.unibo.it> for pointing
2182 	 * this out.
2183 
2184 	if (msg->type == PJSIP_RESPONSE_MSG) {
2185 	    pjsip_hdr *hdr;
2186 	    hdr = (pjsip_hdr*)rdata->msg_info.via->next;
2187 	    if (hdr != &msg->hdr) {
2188 		hdr = pjsip_msg_find_hdr(msg, PJSIP_H_VIA, hdr);
2189 		if (hdr) {
2190 		    mgr->on_rx_msg(mgr->endpt, PJSIP_EMULTIPLEVIA, rdata);
2191 		    goto finish_process_fragment;
2192 		}
2193 	    }
2194 	}
2195 	*/
2196 
2197 	/* Call the transport manager's upstream message callback.
2198 	 */
2199 	mgr->on_rx_msg(mgr->endpt, PJ_SUCCESS, rdata);
2200 
2201 
2202 finish_process_fragment:
2203 	total_processed += msg_fragment_size;
2204 	current_pkt += msg_fragment_size;
2205 	remaining_len -= msg_fragment_size;
2206 
2207     }	/* while (rdata->pkt_info.len > 0) */
2208 
2209 
2210     return total_processed;
2211 }
2212 
2213 
2214 /*
2215  * pjsip_tpmgr_acquire_transport()
2216  *
2217  * Get transport suitable to communicate to remote. Create a new one
2218  * if necessary.
2219  */
pjsip_tpmgr_acquire_transport(pjsip_tpmgr * mgr,pjsip_transport_type_e type,const pj_sockaddr_t * remote,int addr_len,const pjsip_tpselector * sel,pjsip_transport ** tp)2220 PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport(pjsip_tpmgr *mgr,
2221 						  pjsip_transport_type_e type,
2222 						  const pj_sockaddr_t *remote,
2223 						  int addr_len,
2224 						  const pjsip_tpselector *sel,
2225 						  pjsip_transport **tp)
2226 {
2227     return pjsip_tpmgr_acquire_transport2(mgr, type, remote, addr_len, sel,
2228 					  NULL, tp);
2229 }
2230 
2231 
2232 /*
2233  * pjsip_tpmgr_acquire_transport2()
2234  *
2235  * Get transport suitable to communicate to remote. Create a new one
2236  * if necessary.
2237  */
pjsip_tpmgr_acquire_transport2(pjsip_tpmgr * mgr,pjsip_transport_type_e type,const pj_sockaddr_t * remote,int addr_len,const pjsip_tpselector * sel,pjsip_tx_data * tdata,pjsip_transport ** tp)2238 PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,
2239 						   pjsip_transport_type_e type,
2240 						   const pj_sockaddr_t *remote,
2241 						   int addr_len,
2242 						   const pjsip_tpselector *sel,
2243 						   pjsip_tx_data *tdata,
2244 						   pjsip_transport **tp)
2245 {
2246     pjsip_tpfactory *factory;
2247     pj_status_t status;
2248 
2249     TRACE_((THIS_FILE,"Acquiring transport type=%s, sel=%s remote=%s:%d",
2250 		       pjsip_transport_get_type_name(type),
2251 		       print_tpsel_info(sel),
2252 		       addr_string(remote),
2253 		       pj_sockaddr_get_port(remote)));
2254 
2255     pj_lock_acquire(mgr->lock);
2256 
2257     /* If transport is specified, then just use it if it is suitable
2258      * for the destination.
2259      */
2260     if (sel && sel->type == PJSIP_TPSELECTOR_TRANSPORT &&
2261 	sel->u.transport)
2262     {
2263 	pjsip_transport *seltp = sel->u.transport;
2264 
2265 	/* See if the transport is (not) suitable */
2266 	if (seltp->key.type != type) {
2267 	    pj_lock_release(mgr->lock);
2268 	    TRACE_((THIS_FILE, "Transport type in tpsel not matched"));
2269 	    return PJSIP_ETPNOTSUITABLE;
2270 	}
2271 
2272 	/* Make sure the transport is not being destroyed */
2273 	if (seltp->is_destroying) {
2274 	    pj_lock_release(mgr->lock);
2275 	    TRACE_((THIS_FILE,"Transport to be acquired is being destroyed"));
2276 	    return PJ_ENOTFOUND;
2277 	}
2278 
2279 	/* We could also verify that the destination address is reachable
2280 	 * from this transport (i.e. both are equal), but if application
2281 	 * has requested a specific transport to be used, assume that
2282 	 * it knows what to do.
2283 	 *
2284 	 * In other words, I don't think destination verification is a good
2285 	 * idea for now.
2286 	 */
2287 
2288 	/* Transport looks to be suitable to use, so just use it. */
2289 	pjsip_transport_add_ref(seltp);
2290 	pj_lock_release(mgr->lock);
2291 	*tp = seltp;
2292 
2293 	TRACE_((THIS_FILE, "Transport %s acquired", seltp->obj_name));
2294 	return PJ_SUCCESS;
2295 
2296     } else {
2297 
2298 	/*
2299 	 * This is the "normal" flow, where application doesn't specify
2300 	 * specific transport to be used to send message to.
2301 	 * In this case, lookup the transport from the hash table.
2302 	 */
2303 	pjsip_transport_key key;
2304 	int key_len;
2305 	pjsip_transport *tp_ref = NULL;
2306 	transport *tp_entry = NULL;
2307 	unsigned flag = pjsip_transport_get_flag_from_type(type);
2308 
2309 	/* If listener is specified, verify that the listener type matches
2310 	 * the destination type.
2311 	 */
2312 	if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER && sel->u.listener)
2313 	{
2314 	    if (sel->u.listener->type != type) {
2315 		pj_lock_release(mgr->lock);
2316 		TRACE_((THIS_FILE, "Listener type in tpsel not matched"));
2317 		return PJSIP_ETPNOTSUITABLE;
2318 	    }
2319 	}
2320 
2321 	if (!sel || sel->disable_connection_reuse == PJ_FALSE) {
2322 	    pj_bzero(&key, sizeof(key));
2323 	    key_len = sizeof(key.type) + addr_len;
2324 
2325 	    /* First try to get exact destination. */
2326 	    key.type = type;
2327 	    pj_memcpy(&key.rem_addr, remote, addr_len);
2328 
2329 	    tp_entry = (transport *)pj_hash_get(mgr->table, &key, key_len,
2330 						NULL);
2331 	    if (tp_entry) {
2332 		transport *tp_iter = tp_entry;
2333 		do {
2334 		    /* Don't use transport being shutdown/destroyed */
2335 		    if (!tp_iter->tp->is_shutdown &&
2336 			!tp_iter->tp->is_destroying)
2337 		    {
2338 			if ((flag & PJSIP_TRANSPORT_SECURE) && tdata) {
2339 			    /* For secure transport, make sure tdata's
2340 			     * destination host matches the transport's
2341 			     * remote host.
2342 			     */
2343 			    if (pj_stricmp(&tdata->dest_info.name,
2344 				  	   &tp_iter->tp->remote_name.host))
2345 			    {
2346 			    	tp_iter = tp_iter->next;
2347 			    	continue;
2348 			    }
2349 			}
2350 
2351 			if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER &&
2352 			    sel->u.listener)
2353 			{
2354 			    /* Match listener if selector is set */
2355 			    if (tp_iter->tp->factory == sel->u.listener) {
2356 				tp_ref = tp_iter->tp;
2357 				break;
2358 			    }
2359 			} else {
2360 			    tp_ref = tp_iter->tp;
2361 			    break;
2362 			}
2363 		    }
2364 		    tp_iter = tp_iter->next;
2365 		} while (tp_iter != tp_entry);
2366 	    }
2367 	}
2368 
2369 	if (tp_ref == NULL &&
2370 	    (!sel || sel->disable_connection_reuse == PJ_FALSE))
2371 	{
2372 	    const pj_sockaddr *remote_addr = (const pj_sockaddr*)remote;
2373 
2374 
2375 	    /* Ignore address for loop transports. */
2376 	    if (type == PJSIP_TRANSPORT_LOOP ||
2377 		type == PJSIP_TRANSPORT_LOOP_DGRAM)
2378 	    {
2379 		pj_sockaddr *addr = &key.rem_addr;
2380 
2381 		pj_bzero(addr, addr_len);
2382 		key_len = sizeof(key.type) + addr_len;
2383 		tp_entry = (transport *) pj_hash_get(mgr->table, &key,
2384 						     key_len, NULL);
2385 		if (tp_entry) {
2386 		    tp_ref = tp_entry->tp;
2387 		}
2388 	    }
2389 	    /* For datagram transports, try lookup with zero address.
2390 	     */
2391 	    else if (flag & PJSIP_TRANSPORT_DATAGRAM)
2392 	    {
2393 		pj_sockaddr *addr = &key.rem_addr;
2394 
2395 		pj_bzero(addr, addr_len);
2396 		addr->addr.sa_family = remote_addr->addr.sa_family;
2397 
2398 		key_len = sizeof(key.type) + addr_len;
2399 		tp_entry = (transport *) pj_hash_get(mgr->table, &key,
2400 						     key_len, NULL);
2401 		if (tp_entry) {
2402 		    tp_ref = tp_entry->tp;
2403 		}
2404 	    }
2405 	}
2406 
2407 	/* If transport is found and listener is specified, verify listener */
2408 	else if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER &&
2409 		 sel->u.listener && tp_ref->factory != sel->u.listener)
2410 	{
2411 	    tp_ref = NULL;
2412 	    /* This will cause a new transport to be created which will be a
2413 	     * 'duplicate' of the existing transport (same type & remote addr,
2414 	     * but different factory).
2415 	     */
2416 	    TRACE_((THIS_FILE, "Transport found but from different listener"));
2417 	}
2418 
2419 	if (tp_ref!=NULL && !tp_ref->is_shutdown && !tp_ref->is_destroying) {
2420 	    /*
2421 	     * Transport found!
2422 	     */
2423 	    pjsip_transport_add_ref(tp_ref);
2424 	    pj_lock_release(mgr->lock);
2425 	    *tp = tp_ref;
2426 
2427 	    TRACE_((THIS_FILE, "Transport %s acquired", tp_ref->obj_name));
2428 	    return PJ_SUCCESS;
2429 	}
2430 
2431 
2432 	/*
2433 	 * Either transport not found, or we don't want to use the existing
2434 	 * transport (such as in the case of different factory or
2435 	 * if connection reuse is disabled). So we need to create one,
2436 	 * find factory that can create such transport.
2437 	 *
2438 	 * If there's an existing transport, its place in the hash table
2439 	 * will be replaced by this new one. And eventually the existing
2440 	 * transport will still be freed (by application or #1774).
2441 	 */
2442 	if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER && sel->u.listener)
2443 	{
2444 	    /* Application has requested that a specific listener is to
2445 	     * be used.
2446 	     */
2447 
2448 	    /* Verify that the listener type matches the destination type */
2449 	    /* Already checked above. */
2450 	    /*
2451 	    if (sel->u.listener->type != type) {
2452 		pj_lock_release(mgr->lock);
2453 		return PJSIP_ETPNOTSUITABLE;
2454 	    }
2455 	    */
2456 
2457 	    /* We'll use this listener to create transport */
2458 	    factory = sel->u.listener;
2459 
2460 	    /* Verify if listener is still valid */
2461 	    if (!pjsip_tpmgr_is_tpfactory_valid(mgr, factory)) {
2462 		pj_lock_release(mgr->lock);
2463 		PJ_LOG(3,(THIS_FILE, "Specified factory for creating "
2464 				     "transport is not found"));
2465 		return PJ_ENOTFOUND;
2466 	    }
2467 
2468 	} else {
2469 
2470 	    /* Find factory with type matches the destination type */
2471 	    factory = mgr->factory_list.next;
2472 	    while (factory != &mgr->factory_list) {
2473 		if (factory->type == type)
2474 		    break;
2475 		factory = factory->next;
2476 	    }
2477 
2478 	    if (factory == &mgr->factory_list) {
2479 		/* No factory can create the transport! */
2480 		pj_lock_release(mgr->lock);
2481 		TRACE_((THIS_FILE, "No suitable factory was found either"));
2482 		return PJSIP_EUNSUPTRANSPORT;
2483 	    }
2484 	}
2485     }
2486 
2487     TRACE_((THIS_FILE, "Creating new transport from factory"));
2488 
2489     /* Request factory to create transport. */
2490     if (factory->create_transport2) {
2491 	status = factory->create_transport2(factory, mgr, mgr->endpt,
2492 					    (const pj_sockaddr*) remote,
2493 					    addr_len, tdata, tp);
2494     } else {
2495 	status = factory->create_transport(factory, mgr, mgr->endpt,
2496 					   (const pj_sockaddr*) remote,
2497 					   addr_len, tp);
2498     }
2499     if (status == PJ_SUCCESS) {
2500 	PJ_ASSERT_ON_FAIL(tp!=NULL,
2501 	    {pj_lock_release(mgr->lock); return PJ_EBUG;});
2502 	pjsip_transport_add_ref(*tp);
2503 	(*tp)->factory = factory;
2504     }
2505     pj_lock_release(mgr->lock);
2506     return status;
2507 }
2508 
2509 /**
2510  * Dump transport info.
2511  */
pjsip_tpmgr_dump_transports(pjsip_tpmgr * mgr)2512 PJ_DEF(void) pjsip_tpmgr_dump_transports(pjsip_tpmgr *mgr)
2513 {
2514 #if PJ_LOG_MAX_LEVEL >= 3
2515     pj_hash_iterator_t itr_val;
2516     pj_hash_iterator_t *itr;
2517     pjsip_tpfactory *factory;
2518 
2519     pj_lock_acquire(mgr->lock);
2520 
2521 #if defined(PJ_DEBUG) && PJ_DEBUG!=0
2522     PJ_LOG(3,(THIS_FILE, " Outstanding transmit buffers: %d",
2523 	      pj_atomic_get(mgr->tdata_counter)));
2524 #endif
2525 
2526     PJ_LOG(3, (THIS_FILE, " Dumping listeners:"));
2527     factory = mgr->factory_list.next;
2528     while (factory != &mgr->factory_list) {
2529 	PJ_LOG(3, (THIS_FILE, "  %s %s:%.*s:%d",
2530 		   factory->obj_name,
2531 		   factory->type_name,
2532 		   (int)factory->addr_name.host.slen,
2533 		   factory->addr_name.host.ptr,
2534 		   (int)factory->addr_name.port));
2535 	factory = factory->next;
2536     }
2537 
2538     itr = pj_hash_first(mgr->table, &itr_val);
2539     if (itr) {
2540 	PJ_LOG(3, (THIS_FILE, " Dumping transports:"));
2541 
2542 	do {
2543 	    transport *tp_entry = (transport *) pj_hash_this(mgr->table, itr);
2544 	    if (tp_entry) {
2545 		transport *tp_iter = tp_entry;
2546 
2547 		do {
2548 		    pjsip_transport *tp_ref = tp_iter->tp;
2549 
2550 		    PJ_LOG(3, (THIS_FILE, "  %s %s%s%s%s(refcnt=%d%s)",
2551 			       tp_ref->obj_name,
2552 			       tp_ref->info,
2553 			       (tp_ref->factory)?" listener[":"",
2554 			       (tp_ref->factory)?tp_ref->factory->obj_name:"",
2555 			       (tp_ref->factory)?"]":"",
2556 			       pj_atomic_get(tp_ref->ref_cnt),
2557 			       (tp_ref->idle_timer.id ? " [idle]" : "")));
2558 
2559 		    tp_iter = tp_iter->next;
2560 		} while (tp_iter != tp_entry);
2561 	    }
2562 	    itr = pj_hash_next(mgr->table, itr);
2563 	} while (itr);
2564     }
2565 
2566     pj_lock_release(mgr->lock);
2567 #else
2568     PJ_UNUSED_ARG(mgr);
2569 #endif
2570 }
2571 
2572 /**
2573  * Set callback of global transport state notification.
2574  */
pjsip_tpmgr_set_state_cb(pjsip_tpmgr * mgr,pjsip_tp_state_callback cb)2575 PJ_DEF(pj_status_t) pjsip_tpmgr_set_state_cb(pjsip_tpmgr *mgr,
2576 					     pjsip_tp_state_callback cb)
2577 {
2578     PJ_ASSERT_RETURN(mgr, PJ_EINVAL);
2579 
2580     mgr->tp_state_cb = cb;
2581 
2582     return PJ_SUCCESS;
2583 }
2584 
2585 /**
2586  * Get callback of global transport state notification.
2587  */
pjsip_tpmgr_get_state_cb(const pjsip_tpmgr * mgr)2588 PJ_DEF(pjsip_tp_state_callback) pjsip_tpmgr_get_state_cb(
2589 					     const pjsip_tpmgr *mgr)
2590 {
2591     PJ_ASSERT_RETURN(mgr, NULL);
2592 
2593     return mgr->tp_state_cb;
2594 }
2595 
2596 
2597 /**
2598  * Allocate and init transport data.
2599  */
init_tp_data(pjsip_transport * tp)2600 static void init_tp_data(pjsip_transport *tp)
2601 {
2602     transport_data *tp_data;
2603 
2604     pj_assert(tp && !tp->data);
2605 
2606     tp_data = PJ_POOL_ZALLOC_T(tp->pool, transport_data);
2607     pj_list_init(&tp_data->st_listeners);
2608     pj_list_init(&tp_data->st_listeners_empty);
2609     tp->data = tp_data;
2610 }
2611 
2612 
tp_state_callback(pjsip_transport * tp,pjsip_transport_state state,const pjsip_transport_state_info * info)2613 static void tp_state_callback(pjsip_transport *tp,
2614 			      pjsip_transport_state state,
2615 			      const pjsip_transport_state_info *info)
2616 {
2617     transport_data *tp_data;
2618 
2619     pj_lock_acquire(tp->lock);
2620 
2621     tp_data = (transport_data*)tp->data;
2622 
2623     /* Notify the transport state listeners, if any. */
2624     if (!tp_data || pj_list_empty(&tp_data->st_listeners)) {
2625 	goto on_return;
2626     } else {
2627 	pjsip_transport_state_info st_info;
2628 	tp_state_listener *st_listener = tp_data->st_listeners.next;
2629 
2630 	/* As we need to put the user data into the transport state info,
2631 	 * let's use a copy of transport state info.
2632 	 */
2633 	pj_memcpy(&st_info, info, sizeof(st_info));
2634 	while (st_listener != &tp_data->st_listeners) {
2635 	    st_info.user_data = st_listener->user_data;
2636 	    (*st_listener->cb)(tp, state, &st_info);
2637 
2638 	    st_listener = st_listener->next;
2639 	}
2640     }
2641 
2642 on_return:
2643     pj_lock_release(tp->lock);
2644 }
2645 
2646 
2647 /**
2648  * Add a listener to the specified transport for transport state notification.
2649  */
pjsip_transport_add_state_listener(pjsip_transport * tp,pjsip_tp_state_callback cb,void * user_data,pjsip_tp_state_listener_key ** key)2650 PJ_DEF(pj_status_t) pjsip_transport_add_state_listener (
2651 					    pjsip_transport *tp,
2652 					    pjsip_tp_state_callback cb,
2653 					    void *user_data,
2654 					    pjsip_tp_state_listener_key **key)
2655 {
2656     transport_data *tp_data;
2657     tp_state_listener *entry;
2658 
2659     PJ_ASSERT_RETURN(tp && cb && key, PJ_EINVAL);
2660 
2661     if (tp->is_shutdown || tp->is_destroying) {
2662 	*key = NULL;
2663 	return PJ_EINVALIDOP;
2664     }
2665 
2666     pj_lock_acquire(tp->lock);
2667 
2668     /* Init transport data, if it hasn't */
2669     if (!tp->data)
2670 	init_tp_data(tp);
2671 
2672     tp_data = (transport_data*)tp->data;
2673 
2674     /* Init the new listener entry. Use available empty slot, if any,
2675      * otherwise allocate it using the transport pool.
2676      */
2677     if (!pj_list_empty(&tp_data->st_listeners_empty)) {
2678 	entry = tp_data->st_listeners_empty.next;
2679 	pj_list_erase(entry);
2680     } else {
2681 	entry = PJ_POOL_ZALLOC_T(tp->pool, tp_state_listener);
2682     }
2683     entry->cb = cb;
2684     entry->user_data = user_data;
2685 
2686     /* Add the new listener entry to the listeners list */
2687     pj_list_push_back(&tp_data->st_listeners, entry);
2688 
2689     *key = entry;
2690 
2691     pj_lock_release(tp->lock);
2692 
2693     return PJ_SUCCESS;
2694 }
2695 
2696 /**
2697  * Remove a listener from the specified transport for transport state
2698  * notification.
2699  */
pjsip_transport_remove_state_listener(pjsip_transport * tp,pjsip_tp_state_listener_key * key,const void * user_data)2700 PJ_DEF(pj_status_t) pjsip_transport_remove_state_listener (
2701 				    pjsip_transport *tp,
2702 				    pjsip_tp_state_listener_key *key,
2703 				    const void *user_data)
2704 {
2705     transport_data *tp_data;
2706     tp_state_listener *entry;
2707 
2708     PJ_ASSERT_RETURN(tp && key, PJ_EINVAL);
2709 
2710     pj_lock_acquire(tp->lock);
2711 
2712     tp_data = (transport_data*)tp->data;
2713 
2714     /* Transport data is NULL or no registered listener? */
2715     if (!tp_data || pj_list_empty(&tp_data->st_listeners)) {
2716 	pj_lock_release(tp->lock);
2717 	return PJ_ENOTFOUND;
2718     }
2719 
2720     entry = (tp_state_listener*)key;
2721 
2722     /* Validate the user data */
2723     if (entry->user_data != user_data) {
2724 	pj_assert(!"Invalid transport state listener key");
2725 	pj_lock_release(tp->lock);
2726 	return PJ_EBUG;
2727     }
2728 
2729     /* Reset the entry and move it to the empty list */
2730     entry->cb = NULL;
2731     entry->user_data = NULL;
2732     pj_list_erase(entry);
2733     pj_list_push_back(&tp_data->st_listeners_empty, entry);
2734 
2735     pj_lock_release(tp->lock);
2736 
2737     return PJ_SUCCESS;
2738 }
2739 
2740 /*
2741  * Set callback of data dropping.
2742  */
pjsip_tpmgr_set_drop_data_cb(pjsip_tpmgr * mgr,pjsip_tp_on_rx_dropped_cb cb)2743 PJ_DEF(pj_status_t) pjsip_tpmgr_set_drop_data_cb(pjsip_tpmgr *mgr,
2744 						 pjsip_tp_on_rx_dropped_cb cb)
2745 {
2746     PJ_ASSERT_RETURN(mgr, PJ_EINVAL);
2747 
2748     mgr->tp_drop_data_cb = cb;
2749 
2750     return PJ_SUCCESS;
2751 }
2752