--- /dev/null
+From 9c6108ca392d5e0392e7fb5d2ffde85e3c44ce55 Mon Sep 17 00:00:00 2001
+From: George Joseph <gjoseph@digium.com>
+Date: Wed, 9 Oct 2019 07:50:32 -0600
+Subject: [PATCH 31/31] transport regression fix
+
+---
+ pjsip/src/pjsip/sip_transport.c | 73 +++++++++++++++++++++++++++------
+ 1 file changed, 61 insertions(+), 12 deletions(-)
+
+diff --git a/pjsip/src/pjsip/sip_transport.c b/pjsip/src/pjsip/sip_transport.c
+index 65ac823d4..da6b70e50 100644
+--- a/pjsip/src/pjsip/sip_transport.c
++++ b/pjsip/src/pjsip/sip_transport.c
+@@ -50,6 +50,24 @@ static const char *addr_string(const pj_sockaddr_t *addr)
+ str, sizeof(str));
+ return str;
+ }
++static const char* print_tpsel_info(const pjsip_tpselector *sel)
++{
++ static char tpsel_info_buf[80];
++ if (!sel) return "(null)";
++ if (sel->type==PJSIP_TPSELECTOR_LISTENER)
++ pj_ansi_snprintf(tpsel_info_buf, sizeof(tpsel_info_buf),
++ "listener[%s], reuse=%d", sel->u.listener->obj_name,
++ !sel->disable_connection_reuse);
++ else if (sel->type==PJSIP_TPSELECTOR_TRANSPORT)
++ pj_ansi_snprintf(tpsel_info_buf, sizeof(tpsel_info_buf),
++ "transport[%s], reuse=%d", sel->u.transport->info,
++ !sel->disable_connection_reuse);
++ else
++ pj_ansi_snprintf(tpsel_info_buf, sizeof(tpsel_info_buf),
++ "unknown[%p], reuse=%d", sel->u.ptr,
++ !sel->disable_connection_reuse);
++ return tpsel_info_buf;
++}
+ #else
+ # define TRACE_(x)
+ #endif
+@@ -1210,10 +1228,14 @@ PJ_DEF(pj_status_t) pjsip_transport_register( pjsip_tpmgr *mgr,
+ * new transport to the list.
+ */
+ pj_list_push_back(tp_ref, tp_add);
++ TRACE_((THIS_FILE, "Remote address already registered, "
++ "appended the transport to the list"));
+ } else {
+ /* Transport list not found, add it to the hash table. */
+ pj_hash_set_np(mgr->table, &tp->key, key_len, hval, tp_add->tp_buf,
+ tp_add);
++ TRACE_((THIS_FILE, "Remote address not registered, "
++ "added the transport to the hash"));
+ }
+
+ /* Add ref transport group lock, if any */
+@@ -1283,6 +1305,13 @@ static pj_status_t destroy_transport( pjsip_tpmgr *mgr,
+ /* The transport list has multiple entry. */
+ pj_hash_set_np(mgr->table, &tp_next->tp->key, key_len,
+ hval, tp_next->tp_buf, tp_next);
++ TRACE_((THIS_FILE, "Hash entry updated after "
++ "transport %d being destroyed",
++ tp->obj_name));
++ } else {
++ TRACE_((THIS_FILE, "Hash entry deleted after "
++ "transport %d being destroyed",
++ tp->obj_name));
+ }
+ }
+
+@@ -1294,6 +1323,14 @@ static pj_status_t destroy_transport( pjsip_tpmgr *mgr,
+ }
+ tp_iter = tp_iter->next;
+ } while (tp_iter != tp_ref);
++
++ if (tp_iter->tp != tp) {
++ PJ_LOG(3, (THIS_FILE, "Warning: transport %s being destroyed is "
++ "not registered", tp->obj_name));
++ }
++ } else {
++ PJ_LOG(3, (THIS_FILE, "Warning: transport %s being destroyed is "
++ "not found in the hash table", tp->obj_name));
+ }
+
+ pj_lock_release(mgr->lock);
+@@ -2159,6 +2196,7 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport(pjsip_tpmgr *mgr,
+ NULL, tp);
+ }
+
++
+ /*
+ * pjsip_tpmgr_acquire_transport2()
+ *
+@@ -2176,8 +2214,9 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,
+ pjsip_tpfactory *factory;
+ pj_status_t status;
+
+- TRACE_((THIS_FILE,"Acquiring transport type=%s, remote=%s:%d",
++ TRACE_((THIS_FILE,"Acquiring transport type=%s, sel=%s remote=%s:%d",
+ pjsip_transport_get_type_name(type),
++ print_tpsel_info(sel),
+ addr_string(remote),
+ pj_sockaddr_get_port(remote)));
+
+@@ -2194,6 +2233,7 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,
+ /* See if the transport is (not) suitable */
+ if (seltp->key.type != type) {
+ pj_lock_release(mgr->lock);
++ TRACE_((THIS_FILE, "Transport type in tpsel not matched"));
+ return PJSIP_ETPNOTSUITABLE;
+ }
+
+@@ -2234,6 +2274,7 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,
+ {
+ if (sel->u.listener->type != type) {
+ pj_lock_release(mgr->lock);
++ TRACE_((THIS_FILE, "Listener type in tpsel not matched"));
+ return PJSIP_ETPNOTSUITABLE;
+ }
+ }
+@@ -2249,21 +2290,25 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,
+ tp_entry = (transport *)pj_hash_get(mgr->table, &key, key_len,
+ NULL);
+ if (tp_entry) {
+- if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER) {
+- transport *tp_iter = tp_entry;
+- do {
++ transport *tp_iter = tp_entry;
++ do {
++ /* Don't use transport being shutdown */
++ if (!tp_iter->tp->is_shutdown) {
+ if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER &&
+- sel->u.listener &&
+- tp_iter->tp->factory == sel->u.listener)
++ sel->u.listener)
+ {
++ /* Match listener if selector is set */
++ if (tp_iter->tp->factory == sel->u.listener) {
++ tp_ref = tp_iter->tp;
++ break;
++ }
++ } else {
+ tp_ref = tp_iter->tp;
+ break;
+ }
+- tp_iter = tp_iter->next;
+- } while (tp_iter != tp_entry);
+- } else {
+- tp_ref = tp_entry->tp;
+- }
++ }
++ tp_iter = tp_iter->next;
++ } while (tp_iter != tp_entry);
+ }
+ }
+
+@@ -2276,7 +2321,7 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,
+
+ /* Ignore address for loop transports. */
+ if (type == PJSIP_TRANSPORT_LOOP ||
+- type == PJSIP_TRANSPORT_LOOP_DGRAM)
++ type == PJSIP_TRANSPORT_LOOP_DGRAM)
+ {
+ pj_sockaddr *addr = &key.rem_addr;
+
+@@ -2315,6 +2360,7 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,
+ * 'duplicate' of the existing transport (same type & remote addr,
+ * but different factory).
+ */
++ TRACE_((THIS_FILE, "Transport found but from different listener"));
+ }
+
+ if (tp_ref!=NULL && !tp_ref->is_shutdown) {
+@@ -2347,10 +2393,13 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,
+ */
+
+ /* Verify that the listener type matches the destination type */
++ /* Already checked above. */
++ /*
+ if (sel->u.listener->type != type) {
+ pj_lock_release(mgr->lock);
+ return PJSIP_ETPNOTSUITABLE;
+ }
++ */
+
+ /* We'll use this listener to create transport */
+ factory = sel->u.listener;
+--
+2.21.0
+
+++ /dev/null
-From a720f3ffd538d3baef6f8daf78d9d320a4a5c0a0 Mon Sep 17 00:00:00 2001
-From: George Joseph <gjoseph@digium.com>
-Date: Tue, 24 Sep 2019 06:45:59 -0600
-Subject: [PATCH 33/33] Revert "Close #1019: Support for multiple listeners."
-
-This reverts commit 142dd0e96edad15b6b9554636043b5255d5d8adf.
----
- pjsip/include/pjsip/sip_config.h | 10 +-
- pjsip/src/pjsip/sip_transport.c | 318 ++++++++++-----------------
- pjsip/src/pjsip/sip_transport_loop.c | 2 +-
- pjsip/src/test/test.c | 3 -
- pjsip/src/test/transport_tcp_test.c | 193 ++++------------
- pjsip/src/test/transport_udp_test.c | 148 +++++--------
- 6 files changed, 215 insertions(+), 459 deletions(-)
-
-diff --git a/pjsip/include/pjsip/sip_config.h b/pjsip/include/pjsip/sip_config.h
-index 585aa722c..904df24e1 100644
---- a/pjsip/include/pjsip/sip_config.h
-+++ b/pjsip/include/pjsip/sip_config.h
-@@ -433,7 +433,7 @@ PJ_INLINE(pjsip_cfg_t*) pjsip_cfg(void)
- * This option can also be controlled at run-time by the
- * \a accept_multiple_sdp_answers setting in pjsip_cfg_t.
- *
-- * Default is PJ_TRUE.
-+ * Default is PJ_FALSE.
- */
- #ifndef PJSIP_ACCEPT_MULTIPLE_SDP_ANSWERS
- # define PJSIP_ACCEPT_MULTIPLE_SDP_ANSWERS PJ_TRUE
-@@ -692,7 +692,7 @@ PJ_INLINE(pjsip_cfg_t*) pjsip_cfg(void)
- * will be used as the default value for the "reuse_addr" field in the
- * pjsip_tcp_transport_cfg structure.
- *
-- * Default is 0 on Windows and 1 on non-Windows.
-+ * Default is FALSE on Windows and TRUE on non-Windows.
- *
- * @see PJSIP_TLS_TRANSPORT_REUSEADDR
- */
-@@ -718,7 +718,7 @@ PJ_INLINE(pjsip_cfg_t*) pjsip_cfg(void)
- * pj_getipinterface()/pj_gethostip(), but the address will not be
- * able to accept connections.
- *
-- * Default is 0 (listener will be created).
-+ * Default is FALSE (listener will be created).
- */
- #ifndef PJSIP_TCP_TRANSPORT_DONT_CREATE_LISTENER
- # define PJSIP_TCP_TRANSPORT_DONT_CREATE_LISTENER 0
-@@ -738,7 +738,7 @@ PJ_INLINE(pjsip_cfg_t*) pjsip_cfg(void)
- * pj_getipinterface()/pj_gethostip(), but the address will not be
- * able to accept connections.
- *
-- * Default is 0 (listener will be created).
-+ * Default is FALSE (listener will be created).
- */
- #ifndef PJSIP_TLS_TRANSPORT_DONT_CREATE_LISTENER
- # define PJSIP_TLS_TRANSPORT_DONT_CREATE_LISTENER 0
-@@ -881,7 +881,7 @@ PJ_INLINE(pjsip_cfg_t*) pjsip_cfg(void)
- /**
- * Specify whether TLS listener should use SO_REUSEADDR option.
- *
-- * Default is 0 on Windows and 1 on non-Windows.
-+ * Default is FALSE on Windows and TRUE on non-Windows.
- *
- * @see PJSIP_TCP_TRANSPORT_REUSEADDR
- */
-diff --git a/pjsip/src/pjsip/sip_transport.c b/pjsip/src/pjsip/sip_transport.c
-index d63823a98..54e8be380 100644
---- a/pjsip/src/pjsip/sip_transport.c
-+++ b/pjsip/src/pjsip/sip_transport.c
-@@ -54,25 +54,6 @@ static const char *addr_string(const pj_sockaddr_t *addr)
- # define TRACE_(x)
- #endif
-
--/* Specify the initial size of the transport manager's pool. */
--#ifndef TPMGR_POOL_INIT_SIZE
--# define TPMGR_POOL_INIT_SIZE 64
--#endif
--
--/* Specify the increment size of the transport manager's pool. */
--#ifndef TPMGR_POOL_INC_SIZE
-- #define TPMGR_POOL_INC_SIZE 64
--#endif
--
--/* Specify transport entry allocation count. When registering a new transport,
-- * a new entry will be picked from a free list. This setting will determine
-- * the size of the free list size. If all entry is used, then the same number
-- * of entry will be allocated.
-- */
--#ifndef PJSIP_TRANSPORT_ENTRY_ALLOC_CNT
--# define PJSIP_TRANSPORT_ENTRY_ALLOC_CNT 16
--#endif
--
- /* Prototype. */
- static pj_status_t mod_on_tx_msg(pjsip_tx_data *tdata);
-
-@@ -100,7 +81,6 @@ static pjsip_module mod_msg_print =
- typedef struct transport
- {
- PJ_DECL_LIST_MEMBER(struct transport);
-- pj_hash_entry_buf tp_buf;
- pjsip_transport *tp;
- } transport;
-
-@@ -113,7 +93,6 @@ struct pjsip_tpmgr
- pj_lock_t *lock;
- pjsip_endpoint *endpt;
- pjsip_tpfactory factory_list;
-- pj_pool_t *pool;
- #if defined(PJ_DEBUG) && PJ_DEBUG!=0
- pj_atomic_t *tdata_counter;
- #endif
-@@ -126,9 +105,12 @@ struct pjsip_tpmgr
- * is destroyed.
- */
- pjsip_tx_data tdata_list;
--
-- /* List of free transport entry. */
-- transport tp_entry_freelist;
-+
-+ /* List of transports which are NOT stored in the hash table, so
-+ * that it can be properly cleaned up when transport manager
-+ * is destroyed.
-+ */
-+ transport tp_list;
- };
-
-
-@@ -1042,18 +1024,18 @@ static pj_bool_t is_transport_valid(pjsip_transport *tp, pjsip_tpmgr *tpmgr,
- const pjsip_transport_key *key,
- int key_len)
- {
-- transport *tp_entry;
-+ transport *tp_iter;
-
-- tp_entry = (transport *)pj_hash_get(tpmgr->table, key, key_len, NULL);
-- if (tp_entry != NULL) {
-+ if (pj_hash_get(tpmgr->table, key, key_len, NULL) == (void*)tp) {
-+ return PJ_TRUE;
-+ }
-
-- transport *tp_iter = tp_entry;
-- do {
-- if (tp_iter->tp == tp) {
-- return PJ_TRUE;
-- }
-- tp_iter = tp_iter->next;
-- } while (tp_iter != tp_entry);
-+ tp_iter = tpmgr->tp_list.next;
-+ while (tp_iter != &tpmgr->tp_list) {
-+ if (tp_iter->tp == tp) {
-+ return PJ_TRUE;
-+ }
-+ tp_iter = tp_iter->next;
- }
-
- return PJ_FALSE;
-@@ -1153,9 +1135,8 @@ PJ_DEF(pj_status_t) pjsip_transport_dec_ref( pjsip_transport *tp )
- }
-
- /* Dec ref transport group lock, if any */
-- if (tp->grp_lock) {
-+ if (tp->grp_lock)
- pj_grp_lock_dec_ref(tp->grp_lock);
-- }
-
- return PJ_SUCCESS;
- }
-@@ -1169,8 +1150,7 @@ PJ_DEF(pj_status_t) pjsip_transport_register( pjsip_tpmgr *mgr,
- {
- int key_len;
- pj_uint32_t hval;
-- transport *tp_ref = NULL;
-- transport *tp_add = NULL;
-+ void *entry;
-
- /* Init. */
- tp->tpmgr = mgr;
-@@ -1178,43 +1158,31 @@ PJ_DEF(pj_status_t) pjsip_transport_register( pjsip_tpmgr *mgr,
- tp->idle_timer.user_data = tp;
- tp->idle_timer.cb = &transport_idle_callback;
-
-- /*
-+ /*
- * Register to hash table (see Trac ticket #42).
- */
- key_len = sizeof(tp->key.type) + tp->addr_len;
- pj_lock_acquire(mgr->lock);
-
-+ /* If entry already occupied, unregister previous entry */
- hval = 0;
-- tp_ref = (transport *)pj_hash_get(mgr->table, &tp->key, key_len, &hval);
--
-- /* Get an empty entry from the freelist. */
-- if (pj_list_empty(&mgr->tp_entry_freelist)) {
-- unsigned i = 0;
--
-- TRACE_((THIS_FILE, "Transport list is full, allocate new entry"));
-- /* Allocate new entry for the freelist. */
-- for (; i < PJSIP_TRANSPORT_ENTRY_ALLOC_CNT; ++i) {
-- tp_add = PJ_POOL_ZALLOC_T(mgr->pool, transport);
-- if (!tp_add)
-- return PJ_ENOMEM;
-- pj_list_init(tp_add);
-- pj_list_push_back(&mgr->tp_entry_freelist, tp_add);
-- }
-+ entry = pj_hash_get(mgr->table, &tp->key, key_len, &hval);
-+ if (entry != NULL) {
-+ transport *tp_ref;
-+
-+ tp_ref = PJ_POOL_ZALLOC_T(((pjsip_transport *)entry)->pool, transport);
-+
-+ /*
-+ * Add transport to the list before removing it from the hash table.
-+ * See ticket #1774 for more details.
-+ */
-+ tp_ref->tp = (pjsip_transport *)entry;
-+ pj_list_push_back(&mgr->tp_list, tp_ref);
-+ pj_hash_set(NULL, mgr->table, &tp->key, key_len, hval, NULL);
- }
-- tp_add = mgr->tp_entry_freelist.next;
-- tp_add->tp = tp;
-- pj_list_erase(tp_add);
-
-- if (tp_ref) {
-- /* There'a already a transport list from the hash table. Add the
-- * new transport to the list.
-- */
-- pj_list_push_back(tp_ref, tp_add);
-- } else {
-- /* Transport list not found, add it to the hash table. */
-- pj_hash_set_np(mgr->table, &tp->key, key_len, hval, tp_add->tp_buf,
-- tp_add);
-- }
-+ /* Register new entry */
-+ pj_hash_set(tp->pool, mgr->table, &tp->key, key_len, hval, tp);
-
- /* Add ref transport group lock, if any */
- if (tp->grp_lock)
-@@ -1261,46 +1229,26 @@ static pj_status_t destroy_transport( pjsip_tpmgr *mgr,
- key_len = sizeof(tp->key.type) + tp->addr_len;
- hval = 0;
- entry = pj_hash_get(mgr->table, &tp->key, key_len, &hval);
-- if (entry) {
-- transport *tp_ref = (transport *)entry;
-- transport *tp_iter = tp_ref;
-- /* Search the matching entry from the transport list. */
-- do {
-- if (tp_iter->tp == tp) {
-- transport *tp_next = tp_iter->next;
--
-- /* Update hash table :
-- * - transport list only contain single element, or
-- * - the entry is the first element of the transport list.
-- */
-- if (tp_iter == tp_ref) {
-- pj_hash_set(NULL, mgr->table, &tp->key, key_len, hval,
-- NULL);
--
-- if (tp_ref->next != tp_ref) {
-- /* The transport list has multiple entry. */
-- pj_hash_set_np(mgr->table, &tp_next->tp->key, key_len,
-- hval, tp_next->tp_buf, tp_next);
-- }
-- }
--
-- pj_list_erase(tp_iter);
-- /* Put back to the transport freelist. */
-- pj_list_push_back(&mgr->tp_entry_freelist, tp_iter);
--
-- break;
-- }
-- tp_iter = tp_iter->next;
-- } while (tp_iter != tp_ref);
-+ if (entry == (void*)tp) {
-+ pj_hash_set(NULL, mgr->table, &tp->key, key_len, hval, NULL);
-+ } else {
-+ /* If not found in hash table, remove from the tranport list. */
-+ transport *tp_iter = mgr->tp_list.next;
-+ while (tp_iter != &mgr->tp_list) {
-+ if (tp_iter->tp == tp) {
-+ pj_list_erase(tp_iter);
-+ break;
-+ }
-+ tp_iter = tp_iter->next;
-+ }
- }
-
- pj_lock_release(mgr->lock);
- pj_lock_release(tp->lock);
-
- /* Dec ref transport group lock, if any */
-- if (tp->grp_lock) {
-+ if (tp->grp_lock)
- pj_grp_lock_dec_ref(tp->grp_lock);
-- }
-
- /* Destroy. */
- return tp->destroy(tp);
-@@ -1414,9 +1362,13 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_register_tpfactory( pjsip_tpmgr *mgr,
-
- pj_lock_acquire(mgr->lock);
-
-- /* Check that no same factory has been registered. */
-+ /* Check that no factory with the same type has been registered. */
- status = PJ_SUCCESS;
- for (p=mgr->factory_list.next; p!=&mgr->factory_list; p=p->next) {
-+ if (p->type == tpf->type) {
-+ status = PJSIP_ETYPEEXISTS;
-+ break;
-+ }
- if (p == tpf) {
- status = PJ_EEXISTS;
- break;
-@@ -1491,8 +1443,6 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_create( pj_pool_t *pool,
- {
- pjsip_tpmgr *mgr;
- pj_status_t status;
-- unsigned i = 0;
-- pj_pool_t *mgr_pool;
-
- PJ_ASSERT_RETURN(pool && endpt && rx_cb && p_mgr, PJ_EINVAL);
-
-@@ -1502,42 +1452,24 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_create( pj_pool_t *pool,
- return status;
-
- /* Create and initialize transport manager. */
-- mgr_pool = pjsip_endpt_create_pool(endpt, "tpmgr",
-- TPMGR_POOL_INIT_SIZE,
-- TPMGR_POOL_INC_SIZE);
-- mgr = PJ_POOL_ZALLOC_T(mgr_pool, pjsip_tpmgr);
-+ mgr = PJ_POOL_ZALLOC_T(pool, pjsip_tpmgr);
- mgr->endpt = endpt;
- mgr->on_rx_msg = rx_cb;
- mgr->on_tx_msg = tx_cb;
-- mgr->pool = mgr_pool;
--
-- if (!mgr->pool)
-- return PJ_ENOMEM;
--
- pj_list_init(&mgr->factory_list);
- pj_list_init(&mgr->tdata_list);
-- pj_list_init(&mgr->tp_entry_freelist);
-+ pj_list_init(&mgr->tp_list);
-
-- mgr->table = pj_hash_create(mgr->pool, PJSIP_TPMGR_HTABLE_SIZE);
-+ mgr->table = pj_hash_create(pool, PJSIP_TPMGR_HTABLE_SIZE);
- if (!mgr->table)
- return PJ_ENOMEM;
-
-- status = pj_lock_create_recursive_mutex(mgr->pool, "tmgr%p", &mgr->lock);
-+ status = pj_lock_create_recursive_mutex(pool, "tmgr%p", &mgr->lock);
- if (status != PJ_SUCCESS)
- return status;
-
-- for (; i < PJSIP_TRANSPORT_ENTRY_ALLOC_CNT; ++i) {
-- transport *tp_add = NULL;
--
-- tp_add = PJ_POOL_ZALLOC_T(mgr->pool, transport);
-- if (!tp_add)
-- return PJ_ENOMEM;
-- pj_list_init(tp_add);
-- pj_list_push_back(&mgr->tp_entry_freelist, tp_add);
-- }
--
- #if defined(PJ_DEBUG) && PJ_DEBUG!=0
-- status = pj_atomic_create(mgr->pool, 0, &mgr->tdata_counter);
-+ status = pj_atomic_create(pool, 0, &mgr->tdata_counter);
- if (status != PJ_SUCCESS) {
- pj_lock_destroy(mgr->lock);
- return status;
-@@ -1765,16 +1697,15 @@ PJ_DEF(unsigned) pjsip_tpmgr_get_transport_count(pjsip_tpmgr *mgr)
- pj_hash_iterator_t itr_val;
- pj_hash_iterator_t *itr;
- int nr_of_transports = 0;
--
-+
- pj_lock_acquire(mgr->lock);
--
-+
- itr = pj_hash_first(mgr->table, &itr_val);
- while (itr) {
-- transport *tp_entry = (transport *)pj_hash_this(mgr->table, itr);
-- nr_of_transports += pj_list_size(tp_entry);
-+ nr_of_transports++;
- itr = pj_hash_next(mgr->table, itr);
- }
--
-+
- pj_lock_release(mgr->lock);
-
- return nr_of_transports;
-@@ -1791,7 +1722,7 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_destroy( pjsip_tpmgr *mgr )
- pj_hash_iterator_t *itr;
- pjsip_tpfactory *factory;
- pjsip_endpoint *endpt = mgr->endpt;
--
-+
- PJ_LOG(5, (THIS_FILE, "Destroying transport manager"));
-
- pj_lock_acquire(mgr->lock);
-@@ -1799,21 +1730,39 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_destroy( pjsip_tpmgr *mgr )
- /*
- * Destroy all transports in the hash table.
- */
-- for (itr = pj_hash_first(mgr->table, &itr_val); itr;
-- itr = pj_hash_first(mgr->table, &itr_val))
-- {
-- transport *tp_ref;
-- tp_ref = pj_hash_this(mgr->table, itr);
-- destroy_transport(mgr, tp_ref->tp);
-+ itr = pj_hash_first(mgr->table, &itr_val);
-+ while (itr != NULL) {
-+ pj_hash_iterator_t *next;
-+ pjsip_transport *transport;
-+
-+ transport = (pjsip_transport*) pj_hash_this(mgr->table, itr);
-+
-+ next = pj_hash_next(mgr->table, itr);
-+
-+ destroy_transport(mgr, transport);
-+
-+ itr = next;
- }
-
-+ /*
-+ * Destroy transports in the list.
-+ */
-+ if (!pj_list_empty(&mgr->tp_list)) {
-+ transport *tp_iter = mgr->tp_list.next;
-+ while (tp_iter != &mgr->tp_list) {
-+ transport *next = tp_iter->next;
-+ destroy_transport(mgr, tp_iter->tp);
-+ tp_iter = next;
-+ }
-+ }
-+
- /*
- * Destroy all factories/listeners.
- */
- factory = mgr->factory_list.next;
- while (factory != &mgr->factory_list) {
- pjsip_tpfactory *next = factory->next;
--
-+
- factory->destroy(factory);
-
- factory = next;
-@@ -1857,10 +1806,6 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_destroy( pjsip_tpmgr *mgr )
- pjsip_endpt_unregister_module(endpt, &mod_msg_print);
- }
-
-- if (mgr->pool) {
-- pjsip_endpt_release_pool( mgr->endpt, mgr->pool );
-- }
--
- return PJ_SUCCESS;
- }
-
-@@ -2221,9 +2166,7 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,
- */
- pjsip_transport_key key;
- int key_len;
-- pjsip_transport *tp_ref = NULL;
-- transport *tp_entry = NULL;
--
-+ pjsip_transport *transport = NULL;
-
- /* If listener is specified, verify that the listener type matches
- * the destination type.
-@@ -2244,28 +2187,11 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,
- key.type = type;
- pj_memcpy(&key.rem_addr, remote, addr_len);
-
-- tp_entry = (transport *)pj_hash_get(mgr->table, &key, key_len,
-- NULL);
-- if (tp_entry) {
-- if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER) {
-- transport *tp_iter = tp_entry;
-- do {
-- if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER &&
-- sel->u.listener &&
-- tp_iter->tp->factory == sel->u.listener)
-- {
-- tp_ref = tp_iter->tp;
-- break;
-- }
-- tp_iter = tp_iter->next;
-- } while (tp_iter != tp_entry);
-- } else {
-- tp_ref = tp_entry->tp;
-- }
-- }
-+ transport = (pjsip_transport*)
-+ pj_hash_get(mgr->table, &key, key_len, NULL);
- }
-
-- if (tp_ref == NULL &&
-+ if (transport == NULL &&
- (!sel || sel->disable_connection_reuse == PJ_FALSE))
- {
- unsigned flag = pjsip_transport_get_flag_from_type(type);
-@@ -2280,11 +2206,8 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,
-
- pj_bzero(addr, addr_len);
- key_len = sizeof(key.type) + addr_len;
-- tp_entry = (transport *) pj_hash_get(mgr->table, &key,
-- key_len, NULL);
-- if (tp_entry) {
-- tp_ref = tp_entry->tp;
-- }
-+ transport = (pjsip_transport*)
-+ pj_hash_get(mgr->table, &key, key_len, NULL);
- }
- /* For datagram transports, try lookup with zero address.
- */
-@@ -2296,34 +2219,31 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,
- addr->addr.sa_family = remote_addr->addr.sa_family;
-
- key_len = sizeof(key.type) + addr_len;
-- tp_entry = (transport *) pj_hash_get(mgr->table, &key,
-- key_len, NULL);
-- if (tp_entry) {
-- tp_ref = tp_entry->tp;
-- }
-+ transport = (pjsip_transport*)
-+ pj_hash_get(mgr->table, &key, key_len, NULL);
- }
- }
-
- /* If transport is found and listener is specified, verify listener */
- else if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER &&
-- sel->u.listener && tp_ref->factory != sel->u.listener)
-+ sel->u.listener && transport->factory != sel->u.listener)
- {
-- tp_ref = NULL;
-+ transport = NULL;
- /* This will cause a new transport to be created which will be a
- * 'duplicate' of the existing transport (same type & remote addr,
- * but different factory).
- */
- }
-
-- if (tp_ref!=NULL && !tp_ref->is_shutdown) {
-+ if (transport!=NULL && !transport->is_shutdown) {
- /*
- * Transport found!
- */
-- pjsip_transport_add_ref(tp_ref);
-+ pjsip_transport_add_ref(transport);
- pj_lock_release(mgr->lock);
-- *tp = tp_ref;
-+ *tp = transport;
-
-- TRACE_((THIS_FILE, "Transport %s acquired", tp_ref->obj_name));
-+ TRACE_((THIS_FILE, "Transport %s acquired", transport->obj_name));
- return PJ_SUCCESS;
- }
-
-@@ -2385,15 +2305,15 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,
- /* Request factory to create transport. */
- if (factory->create_transport2) {
- status = factory->create_transport2(factory, mgr, mgr->endpt,
-- (const pj_sockaddr*) remote,
-+ (const pj_sockaddr*) remote,
- addr_len, tdata, tp);
- } else {
- status = factory->create_transport(factory, mgr, mgr->endpt,
-- (const pj_sockaddr*) remote,
-+ (const pj_sockaddr*) remote,
- addr_len, tp);
- }
- if (status == PJ_SUCCESS) {
-- PJ_ASSERT_ON_FAIL(tp!=NULL,
-+ PJ_ASSERT_ON_FAIL(tp!=NULL,
- {pj_lock_release(mgr->lock); return PJ_EBUG;});
- pjsip_transport_add_ref(*tp);
- (*tp)->factory = factory;
-@@ -2436,25 +2356,15 @@ PJ_DEF(void) pjsip_tpmgr_dump_transports(pjsip_tpmgr *mgr)
- PJ_LOG(3, (THIS_FILE, " Dumping transports:"));
-
- do {
-- transport *tp_entry = (transport *) pj_hash_this(mgr->table, itr);
-- if (tp_entry) {
-- transport *tp_iter = tp_entry;
--
-- do {
-- pjsip_transport *tp_ref = tp_iter->tp;
--
-- PJ_LOG(3, (THIS_FILE, " %s %s%s%s%s(refcnt=%d%s)",
-- tp_ref->obj_name,
-- tp_ref->info,
-- (tp_ref->factory)?" listener[":"",
-- (tp_ref->factory)?tp_ref->factory->obj_name:"",
-- (tp_ref->factory)?"]":"",
-- pj_atomic_get(tp_ref->ref_cnt),
-- (tp_ref->idle_timer.id ? " [idle]" : "")));
--
-- tp_iter = tp_iter->next;
-- } while (tp_iter != tp_entry);
-- }
-+ pjsip_transport *t = (pjsip_transport*)
-+ pj_hash_this(mgr->table, itr);
-+
-+ PJ_LOG(3, (THIS_FILE, " %s %s (refcnt=%d%s)",
-+ t->obj_name,
-+ t->info,
-+ pj_atomic_get(t->ref_cnt),
-+ (t->idle_timer.id ? " [idle]" : "")));
-+
- itr = pj_hash_next(mgr->table, itr);
- } while (itr);
- }
-diff --git a/pjsip/src/pjsip/sip_transport_loop.c b/pjsip/src/pjsip/sip_transport_loop.c
-index 24e1a5f69..5cbe26a97 100644
---- a/pjsip/src/pjsip/sip_transport_loop.c
-+++ b/pjsip/src/pjsip/sip_transport_loop.c
-@@ -376,7 +376,7 @@ PJ_DEF(pj_status_t) pjsip_loop_start( pjsip_endpoint *endpt,
- if (status != PJ_SUCCESS)
- goto on_error;
- loop->base.key.type = PJSIP_TRANSPORT_LOOP_DGRAM;
-- loop->base.key.rem_addr.addr.sa_family = pj_AF_INET();
-+ //loop->base.key.rem_addr.sa_family = pj_AF_INET();
- loop->base.type_name = "LOOP-DGRAM";
- loop->base.info = "LOOP-DGRAM";
- loop->base.flag = PJSIP_TRANSPORT_DATAGRAM;
-diff --git a/pjsip/src/test/test.c b/pjsip/src/test/test.c
-index 3898d45ff..0361e6178 100644
---- a/pjsip/src/test/test.c
-+++ b/pjsip/src/test/test.c
-@@ -379,9 +379,6 @@ int test_main(void)
- on_return:
- flush_events(500);
-
-- /* Show additional info on the log. e.g: not released memory pool. */
-- pj_log_set_level(4);
--
- /* Dumping memory pool usage */
- PJ_LOG(3,(THIS_FILE, "Peak memory size=%u MB",
- caching_pool.peak_used_size / 1000000));
-diff --git a/pjsip/src/test/transport_tcp_test.c b/pjsip/src/test/transport_tcp_test.c
-index b10455664..3ff5f8ff4 100644
---- a/pjsip/src/test/transport_tcp_test.c
-+++ b/pjsip/src/test/transport_tcp_test.c
-@@ -29,154 +29,64 @@
- * TCP transport test.
- */
- #if PJ_HAS_TCP
--
--static pj_status_t multi_listener_test(pjsip_tpfactory *factory[],
-- unsigned num_factory,
-- pjsip_transport *tp[],
-- unsigned *num_tp)
-+int transport_tcp_test(void)
- {
-- pj_status_t status;
-- unsigned i = 0;
-- pj_str_t s;
-+ enum { SEND_RECV_LOOP = 8 };
-+ pjsip_tpfactory *tpfactory;
- pjsip_transport *tcp;
-- pjsip_tpfactory *tpfactory = NULL;
- pj_sockaddr_in rem_addr;
-- pjsip_tpselector tp_sel;
-- unsigned ntp = 0;
--
-- for (;i<num_factory;++i)
-- {
-- /* Start TCP listener on arbitrary port. */
-- status = pjsip_tcp_transport_start(endpt, NULL, 1, &tpfactory);
-- if (status != PJ_SUCCESS) {
-- app_perror(" Error: unable to start TCP transport", status);
-- return -10;
-- }
-+ pj_status_t status;
-+ char url[PJSIP_MAX_URL_SIZE];
-+ char addr[PJ_INET_ADDRSTRLEN];
-+ int rtt[SEND_RECV_LOOP], min_rtt;
-+ int i, pkt_lost;
-
-- factory[i] = tpfactory;
-+ /* Start TCP listener on arbitrary port. */
-+ status = pjsip_tcp_transport_start(endpt, NULL, 1, &tpfactory);
-+ if (status != PJ_SUCCESS) {
-+ app_perror(" Error: unable to start TCP transport", status);
-+ return -10;
- }
-
-- /* Get the last listener address */
-+
-+ /* Get the listener address */
- status = pj_sockaddr_in_init(&rem_addr, &tpfactory->addr_name.host,
- (pj_uint16_t)tpfactory->addr_name.port);
- if (status != PJ_SUCCESS) {
- app_perror(" Error: possibly invalid TCP address name", status);
-- return -11;
-+ return -14;
- }
-
-- /* Acquire transport without selector. */
-- status = pjsip_endpt_acquire_transport(endpt, PJSIP_TRANSPORT_TCP,
-- &rem_addr, sizeof(rem_addr),
-- NULL, &tcp);
-- if (status != PJ_SUCCESS || tcp == NULL) {
-- app_perror(" Error: unable to acquire TCP transport", status);
-- return -12;
-- }
-- tp[ntp++] = tcp;
-+ pj_ansi_sprintf(url, "sip:alice@%s:%d;transport=tcp",
-+ pj_inet_ntop2(pj_AF_INET(), &rem_addr.sin_addr, addr,
-+ sizeof(addr)),
-+ pj_ntohs(rem_addr.sin_port));
-
-- /* After pjsip_endpt_acquire_transport, TCP transport must have
-- * reference counter 1.
-- */
-- if (pj_atomic_get(tcp->ref_cnt) != 1)
-- return -13;
-
-- /* Acquire with the same remote address, should return the same tp. */
-- status = pjsip_endpt_acquire_transport(endpt, PJSIP_TRANSPORT_TCP,
-+ /* Acquire one TCP transport. */
-+ status = pjsip_endpt_acquire_transport(endpt, PJSIP_TRANSPORT_TCP,
- &rem_addr, sizeof(rem_addr),
- NULL, &tcp);
- if (status != PJ_SUCCESS || tcp == NULL) {
- app_perror(" Error: unable to acquire TCP transport", status);
-- return -14;
-- }
--
-- /* Should return existing transport. */
-- if (tp[ntp-1] != tcp) {
-- return -15;
-+ return -17;
- }
-
-- /* Using the same TCP transport, it must have reference counter 2.
-+ /* After pjsip_endpt_acquire_transport, TCP transport must have
-+ * reference counter 1.
- */
-- if (pj_atomic_get(tcp->ref_cnt) != 2)
-- return -16;
--
-- /* Decrease the reference. */
-- pjsip_transport_dec_ref(tcp);
-+ if (pj_atomic_get(tcp->ref_cnt) != 1)
-+ return -20;
-
- /* Test basic transport attributes */
- status = generic_transport_test(tcp);
- if (status != PJ_SUCCESS)
- return status;
-
-+
- /* Check again that reference counter is 1. */
- if (pj_atomic_get(tcp->ref_cnt) != 1)
-- return -17;
--
-- /* Acquire transport test with selector. */
-- pj_bzero(&tp_sel, sizeof(tp_sel));
-- tp_sel.type = PJSIP_TPSELECTOR_LISTENER;
-- tp_sel.u.listener = factory[num_factory/2];
-- pj_sockaddr_in_init(&rem_addr, pj_cstr(&s, "1.1.1.1"), 80);
-- status = pjsip_endpt_acquire_transport(endpt, PJSIP_TRANSPORT_TCP,
-- &rem_addr, sizeof(rem_addr),
-- &tp_sel, &tcp);
-- if (status != PJ_SUCCESS) {
-- app_perror(" Error: unable to acquire TCP transport", status);
-- return -18;
-- }
--
-- /* The transport should have the same factory set on the selector. */
-- if (tcp->factory != factory[num_factory/2])
-- return -19;
--
-- /* The transport should be newly created. */
-- for (i = 0; i < ntp; ++i) {
-- if (tp[i] == tcp) {
-- break;
-- }
-- }
-- if (i != ntp)
-- return -20;
--
-- tp[ntp++] = tcp;
--
-- for (i = 0; i<ntp; ++i) {
-- if (pj_atomic_get(tp[i]->ref_cnt) != 1)
-- return -21;
-- }
-- *num_tp = ntp;
--
-- return PJ_SUCCESS;
--}
--
--int transport_tcp_test(void)
--{
-- enum { SEND_RECV_LOOP = 8 };
-- enum { NUM_LISTENER = 4 };
-- enum { NUM_TP = 8 };
-- pjsip_tpfactory *tpfactory[NUM_LISTENER];
-- pjsip_transport *tcp[NUM_TP];
-- pj_sockaddr_in rem_addr;
-- pj_status_t status;
-- char url[PJSIP_MAX_URL_SIZE];
-- char addr[PJ_INET_ADDRSTRLEN];
-- int rtt[SEND_RECV_LOOP], min_rtt;
-- int pkt_lost;
-- unsigned i;
-- unsigned num_listener = NUM_LISTENER;
-- unsigned num_tp = NUM_TP;
--
-- status = multi_listener_test(tpfactory, num_listener, tcp, &num_tp);
-- if (status != PJ_SUCCESS)
-- return status;
--
-- /* Get the last listener address */
-- status = pj_sockaddr_in_init(&rem_addr, &tpfactory[0]->addr_name.host,
-- (pj_uint16_t)tpfactory[0]->addr_name.port);
--
-- pj_ansi_sprintf(url, "sip:alice@%s:%d;transport=tcp",
-- pj_inet_ntop2(pj_AF_INET(), &rem_addr.sin_addr, addr,
-- sizeof(addr)),
-- pj_ntohs(rem_addr.sin_port));
-+ return -40;
-
- /* Load test */
- if (transport_load_test(url) != 0)
-@@ -184,13 +94,10 @@ int transport_tcp_test(void)
-
- /* Basic transport's send/receive loopback test. */
- for (i=0; i<SEND_RECV_LOOP; ++i) {
-- status = transport_send_recv_test(PJSIP_TRANSPORT_TCP, tcp[0], url,
-- &rtt[i]);
-+ status = transport_send_recv_test(PJSIP_TRANSPORT_TCP, tcp, url, &rtt[i]);
-
- if (status != 0) {
-- for (i = 0; i < num_tp ; ++i) {
-- pjsip_transport_dec_ref(tcp[i]);
-- }
-+ pjsip_transport_dec_ref(tcp);
- flush_events(500);
- return -72;
- }
-@@ -208,11 +115,9 @@ int transport_tcp_test(void)
-
-
- /* Multi-threaded round-trip test. */
-- status = transport_rt_test(PJSIP_TRANSPORT_TCP, tcp[0], url, &pkt_lost);
-+ status = transport_rt_test(PJSIP_TRANSPORT_TCP, tcp, url, &pkt_lost);
- if (status != 0) {
-- for (i = 0; i < num_tp ; ++i) {
-- pjsip_transport_dec_ref(tcp[i]);
-- }
-+ pjsip_transport_dec_ref(tcp);
- return status;
- }
-
-@@ -220,28 +125,22 @@ int transport_tcp_test(void)
- PJ_LOG(3,(THIS_FILE, " note: %d packet(s) was lost", pkt_lost));
-
- /* Check again that reference counter is still 1. */
-- for (i = 0; i < num_tp; ++i) {
-- if (pj_atomic_get(tcp[i]->ref_cnt) != 1)
-- return -80;
-- }
-+ if (pj_atomic_get(tcp->ref_cnt) != 1)
-+ return -80;
-
-- for (i = 0; i < num_tp; ++i) {
-- /* Destroy this transport. */
-- pjsip_transport_dec_ref(tcp[i]);
-+ /* Destroy this transport. */
-+ pjsip_transport_dec_ref(tcp);
-
-- /* Force destroy this transport. */
-- status = pjsip_transport_destroy(tcp[i]);
-- if (status != PJ_SUCCESS)
-- return -90;
-- }
-+ /* Force destroy this transport. */
-+ status = pjsip_transport_destroy(tcp);
-+ if (status != PJ_SUCCESS)
-+ return -90;
-
-- for (i = 0; i < num_listener; ++i) {
-- /* Unregister factory */
-- status = pjsip_tpmgr_unregister_tpfactory(pjsip_endpt_get_tpmgr(endpt),
-- tpfactory[i]);
-- if (status != PJ_SUCCESS)
-- return -95;
-- }
-+ /* Unregister factory */
-+ status = pjsip_tpmgr_unregister_tpfactory(pjsip_endpt_get_tpmgr(endpt),
-+ tpfactory);
-+ if (status != PJ_SUCCESS)
-+ return -95;
-
- /* Flush events. */
- PJ_LOG(3,(THIS_FILE, " Flushing events, 1 second..."));
-diff --git a/pjsip/src/test/transport_udp_test.c b/pjsip/src/test/transport_udp_test.c
-index 579c7f071..bc0831a38 100644
---- a/pjsip/src/test/transport_udp_test.c
-+++ b/pjsip/src/test/transport_udp_test.c
-@@ -24,88 +24,6 @@
-
- #define THIS_FILE "transport_udp_test.c"
-
--static pj_status_t multi_transport_test(pjsip_transport *tp[], unsigned num_tp)
--{
-- pj_status_t status;
-- pj_uint16_t i = 0;
-- pj_str_t s;
-- pjsip_transport *udp_tp;
-- pj_sockaddr_in rem_addr;
-- pjsip_tpselector tp_sel;
--
-- for (;i<num_tp;++i)
-- {
-- pj_sockaddr_in addr;
--
-- pj_sockaddr_in_init(&addr, NULL, TEST_UDP_PORT+i);
--
-- /* Start UDP transport. */
-- status = pjsip_udp_transport_start( endpt, &addr, NULL, 1, &udp_tp);
-- if (status != PJ_SUCCESS) {
-- app_perror(" Error: unable to start UDP transport", status);
-- return -110;
-- }
--
-- /* UDP transport must have initial reference counter set to 1. */
-- if (pj_atomic_get(udp_tp->ref_cnt) != 1)
-- return -120;
--
-- /* Test basic transport attributes */
-- status = generic_transport_test(udp_tp);
-- if (status != PJ_SUCCESS)
-- return status;
--
-- tp[i] = udp_tp;
-- }
--
-- for (i = 0; i < num_tp; ++i) {
-- udp_tp = tp[i];
-- if (pj_atomic_get(udp_tp->ref_cnt) != 1)
-- return -130;
-- }
--
-- /* Acquire transport test without selector. */
-- pj_sockaddr_in_init(&rem_addr, pj_cstr(&s, "1.1.1.1"), 80);
-- status = pjsip_endpt_acquire_transport(endpt, PJSIP_TRANSPORT_UDP,
-- &rem_addr, sizeof(rem_addr),
-- NULL, &udp_tp);
-- if (status != PJ_SUCCESS)
-- return -140;
--
-- for (i = 0; i < num_tp; ++i) {
-- if (udp_tp == tp[i]) {
-- break;
-- }
-- }
-- if (i == num_tp)
-- return -150;
--
-- pjsip_transport_dec_ref(udp_tp);
--
-- if (pj_atomic_get(udp_tp->ref_cnt) != 1)
-- return -160;
--
-- /* Acquire transport test with selector. */
-- pj_bzero(&tp_sel, sizeof(tp_sel));
-- tp_sel.type = PJSIP_TPSELECTOR_TRANSPORT;
-- tp_sel.u.transport = tp[num_tp-1];
-- pj_sockaddr_in_init(&rem_addr, pj_cstr(&s, "1.1.1.1"), 80);
-- status = pjsip_endpt_acquire_transport(endpt, PJSIP_TRANSPORT_UDP,
-- &rem_addr, sizeof(rem_addr),
-- &tp_sel, &udp_tp);
-- if (status != PJ_SUCCESS)
-- return -170;
--
-- if (udp_tp != tp[num_tp-1])
-- return -180;
--
-- pjsip_transport_dec_ref(udp_tp);
--
-- if (pj_atomic_get(udp_tp->ref_cnt) != 1)
-- return -190;
--
-- return PJ_SUCCESS;
--}
-
- /*
- * UDP transport test.
-@@ -113,22 +31,56 @@ static pj_status_t multi_transport_test(pjsip_transport *tp[], unsigned num_tp)
- int transport_udp_test(void)
- {
- enum { SEND_RECV_LOOP = 8 };
-- enum { NUM_TP = 4 };
-- pjsip_transport *tp[NUM_TP], *udp_tp;
-- pj_sockaddr_in rem_addr;
-+ pjsip_transport *udp_tp, *tp;
-+ pj_sockaddr_in addr, rem_addr;
- pj_str_t s;
- pj_status_t status;
- int rtt[SEND_RECV_LOOP], min_rtt;
- int i, pkt_lost;
-
-- status = multi_transport_test(&tp[0], NUM_TP);
-+ pj_sockaddr_in_init(&addr, NULL, TEST_UDP_PORT);
-+
-+ /* Start UDP transport. */
-+ status = pjsip_udp_transport_start( endpt, &addr, NULL, 1, &udp_tp);
-+ if (status != PJ_SUCCESS) {
-+ app_perror(" Error: unable to start UDP transport", status);
-+ return -10;
-+ }
-+
-+ /* UDP transport must have initial reference counter set to 1. */
-+ if (pj_atomic_get(udp_tp->ref_cnt) != 1)
-+ return -20;
-+
-+ /* Test basic transport attributes */
-+ status = generic_transport_test(udp_tp);
- if (status != PJ_SUCCESS)
- return status;
-
-+ /* Test that transport manager is returning the correct
-+ * transport.
-+ */
-+ pj_sockaddr_in_init(&rem_addr, pj_cstr(&s, "1.1.1.1"), 80);
-+ status = pjsip_endpt_acquire_transport(endpt, PJSIP_TRANSPORT_UDP,
-+ &rem_addr, sizeof(rem_addr),
-+ NULL, &tp);
-+ if (status != PJ_SUCCESS)
-+ return -50;
-+ if (tp != udp_tp)
-+ return -60;
-+
-+ /* pjsip_endpt_acquire_transport() adds reference, so we need
-+ * to decrement it.
-+ */
-+ pjsip_transport_dec_ref(tp);
-+
-+ /* Check again that reference counter is 1. */
-+ if (pj_atomic_get(udp_tp->ref_cnt) != 1)
-+ return -70;
-+
- /* Basic transport's send/receive loopback test. */
- pj_sockaddr_in_init(&rem_addr, pj_cstr(&s, "127.0.0.1"), TEST_UDP_PORT);
- for (i=0; i<SEND_RECV_LOOP; ++i) {
-- status = transport_send_recv_test(PJSIP_TRANSPORT_UDP, tp[0],
-+ status = transport_send_recv_test(PJSIP_TRANSPORT_UDP, tp,
- "sip:alice@127.0.0.1:"TEST_UDP_PORT_STR,
- &rtt[i]);
- if (status != 0)
-@@ -146,7 +98,7 @@ int transport_udp_test(void)
-
-
- /* Multi-threaded round-trip test. */
-- status = transport_rt_test(PJSIP_TRANSPORT_UDP, tp[0],
-+ status = transport_rt_test(PJSIP_TRANSPORT_UDP, tp,
- "sip:alice@127.0.0.1:"TEST_UDP_PORT_STR,
- &pkt_lost);
- if (status != 0)
-@@ -155,19 +107,17 @@ int transport_udp_test(void)
- if (pkt_lost != 0)
- PJ_LOG(3,(THIS_FILE, " note: %d packet(s) was lost", pkt_lost));
-
-- for (i = 0; i < NUM_TP; ++i) {
-- udp_tp = tp[i];
-+ /* Check again that reference counter is 1. */
-+ if (pj_atomic_get(udp_tp->ref_cnt) != 1)
-+ return -80;
-
-- /* Check again that reference counter is 1. */
-- if (pj_atomic_get(udp_tp->ref_cnt) != 1)
-- return -80;
-+ /* Destroy this transport. */
-+ pjsip_transport_dec_ref(udp_tp);
-
-- /* Destroy this transport. */
-- pjsip_transport_dec_ref(udp_tp);
-- status = pjsip_transport_destroy(udp_tp);
-- if (status != PJ_SUCCESS)
-- return -90;
-- }
-+ /* Force destroy this transport. */
-+ status = pjsip_transport_destroy(udp_tp);
-+ if (status != PJ_SUCCESS)
-+ return -90;
-
- /* Flush events. */
- PJ_LOG(3,(THIS_FILE, " Flushing events, 1 second..."));
---
-2.21.0
-