Changeset 6002
- Timestamp:
- May 23, 2019 5:21:59 PM (5 years ago)
- Location:
- pjproject/trunk/pjsip
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/include/pjsip/sip_config.h
r5869 r6002 434 434 * \a accept_multiple_sdp_answers setting in pjsip_cfg_t. 435 435 * 436 * Default is PJ_ FALSE.436 * Default is PJ_TRUE. 437 437 */ 438 438 #ifndef PJSIP_ACCEPT_MULTIPLE_SDP_ANSWERS … … 693 693 * pjsip_tcp_transport_cfg structure. 694 694 * 695 * Default is FALSE on Windows and TRUEon non-Windows.695 * Default is 0 on Windows and 1 on non-Windows. 696 696 * 697 697 * @see PJSIP_TLS_TRANSPORT_REUSEADDR … … 719 719 * able to accept connections. 720 720 * 721 * Default is FALSE(listener will be created).721 * Default is 0 (listener will be created). 722 722 */ 723 723 #ifndef PJSIP_TCP_TRANSPORT_DONT_CREATE_LISTENER … … 739 739 * able to accept connections. 740 740 * 741 * Default is FALSE(listener will be created).741 * Default is 0 (listener will be created). 742 742 */ 743 743 #ifndef PJSIP_TLS_TRANSPORT_DONT_CREATE_LISTENER … … 882 882 * Specify whether TLS listener should use SO_REUSEADDR option. 883 883 * 884 * Default is FALSE on Windows and TRUEon non-Windows.884 * Default is 0 on Windows and 1 on non-Windows. 885 885 * 886 886 * @see PJSIP_TCP_TRANSPORT_REUSEADDR -
pjproject/trunk/pjsip/src/pjsip/sip_transport.c
r5984 r6002 55 55 #endif 56 56 57 /* Specify the initial size of the transport manager's pool. */ 58 #ifndef TPMGR_POOL_INIT_SIZE 59 # define TPMGR_POOL_INIT_SIZE 64 60 #endif 61 62 /* Specify the increment size of the transport manager's pool. */ 63 #ifndef TPMGR_POOL_INC_SIZE 64 #define TPMGR_POOL_INC_SIZE 64 65 #endif 66 67 /* Specify transport entry allocation count. When registering a new transport, 68 * a new entry will be picked from a free list. This setting will determine 69 * the size of the free list size. If all entry is used, then the same number 70 * of entry will be allocated. 71 */ 72 #ifndef PJSIP_TRANSPORT_ENTRY_ALLOC_CNT 73 # define PJSIP_TRANSPORT_ENTRY_ALLOC_CNT 16 74 #endif 75 57 76 /* Prototype. */ 58 77 static pj_status_t mod_on_tx_msg(pjsip_tx_data *tdata); … … 82 101 { 83 102 PJ_DECL_LIST_MEMBER(struct transport); 103 pj_hash_entry_buf tp_buf; 84 104 pjsip_transport *tp; 85 105 } transport; … … 94 114 pjsip_endpoint *endpt; 95 115 pjsip_tpfactory factory_list; 116 pj_pool_t *pool; 96 117 #if defined(PJ_DEBUG) && PJ_DEBUG!=0 97 118 pj_atomic_t *tdata_counter; … … 106 127 */ 107 128 pjsip_tx_data tdata_list; 108 109 /* List of transports which are NOT stored in the hash table, so 110 * that it can be properly cleaned up when transport manager 111 * is destroyed. 112 */ 113 transport tp_list; 129 130 /* List of free transport entry. */ 131 transport tp_entry_freelist; 114 132 }; 115 133 … … 1025 1043 int key_len) 1026 1044 { 1027 transport *tp_ iter;1028 1029 if (pj_hash_get(tpmgr->table, key, key_len, NULL) == (void*)tp) {1030 return PJ_TRUE;1031 } 1032 1033 tp_iter = tpmgr->tp_list.next; 1034 while (tp_iter != &tpmgr->tp_list) {1035 if (tp_iter->tp == tp) { 1036 return PJ_TRUE; 1037 } 1038 tp_iter = tp_iter->next;1045 transport *tp_entry; 1046 1047 tp_entry = (transport *)pj_hash_get(tpmgr->table, key, key_len, NULL); 1048 if (tp_entry != NULL) { 1049 1050 transport *tp_iter = tp_entry; 1051 do { 1052 if (tp_iter->tp == tp) { 1053 return PJ_TRUE; 1054 } 1055 tp_iter = tp_iter->next; 1056 } while (tp_iter != tp_entry); 1039 1057 } 1040 1058 … … 1136 1154 1137 1155 /* Dec ref transport group lock, if any */ 1138 if (tp->grp_lock) 1156 if (tp->grp_lock) { 1139 1157 pj_grp_lock_dec_ref(tp->grp_lock); 1158 } 1140 1159 1141 1160 return PJ_SUCCESS; … … 1151 1170 int key_len; 1152 1171 pj_uint32_t hval; 1153 void *entry; 1172 transport *tp_ref = NULL; 1173 transport *tp_add = NULL; 1154 1174 1155 1175 /* Init. */ … … 1159 1179 tp->idle_timer.cb = &transport_idle_callback; 1160 1180 1161 /* 1181 /* 1162 1182 * Register to hash table (see Trac ticket #42). 1163 1183 */ … … 1165 1185 pj_lock_acquire(mgr->lock); 1166 1186 1167 /* If entry already occupied, unregister previous entry */1168 1187 hval = 0; 1169 entry = pj_hash_get(mgr->table, &tp->key, key_len, &hval); 1170 if (entry != NULL) { 1171 transport *tp_ref; 1172 1173 tp_ref = PJ_POOL_ZALLOC_T(((pjsip_transport *)entry)->pool, transport); 1174 1175 /* 1176 * Add transport to the list before removing it from the hash table. 1177 * See ticket #1774 for more details. 1178 */ 1179 tp_ref->tp = (pjsip_transport *)entry; 1180 pj_list_push_back(&mgr->tp_list, tp_ref); 1181 pj_hash_set(NULL, mgr->table, &tp->key, key_len, hval, NULL); 1182 } 1183 1184 /* Register new entry */ 1185 pj_hash_set(tp->pool, mgr->table, &tp->key, key_len, hval, tp); 1188 tp_ref = (transport *)pj_hash_get(mgr->table, &tp->key, key_len, &hval); 1189 1190 /* Get an empty entry from the freelist. */ 1191 if (pj_list_empty(&mgr->tp_entry_freelist)) { 1192 unsigned i = 0; 1193 1194 TRACE_((THIS_FILE, "Transport list is full, allocate new entry")); 1195 /* Allocate new entry for the freelist. */ 1196 for (; i < PJSIP_TRANSPORT_ENTRY_ALLOC_CNT; ++i) { 1197 tp_add = PJ_POOL_ZALLOC_T(mgr->pool, transport); 1198 if (!tp_add) 1199 return PJ_ENOMEM; 1200 pj_list_init(tp_add); 1201 pj_list_push_back(&mgr->tp_entry_freelist, tp_add); 1202 } 1203 } 1204 tp_add = mgr->tp_entry_freelist.next; 1205 tp_add->tp = tp; 1206 pj_list_erase(tp_add); 1207 1208 if (tp_ref) { 1209 /* There'a already a transport list from the hash table. Add the 1210 * new transport to the list. 1211 */ 1212 pj_list_push_back(tp_ref, tp_add); 1213 } else { 1214 /* Transport list not found, add it to the hash table. */ 1215 pj_hash_set_np(mgr->table, &tp->key, key_len, hval, tp_add->tp_buf, 1216 tp_add); 1217 } 1186 1218 1187 1219 /* Add ref transport group lock, if any */ … … 1230 1262 hval = 0; 1231 1263 entry = pj_hash_get(mgr->table, &tp->key, key_len, &hval); 1232 if (entry == (void*)tp) { 1233 pj_hash_set(NULL, mgr->table, &tp->key, key_len, hval, NULL); 1234 } else { 1235 /* If not found in hash table, remove from the tranport list. */ 1236 transport *tp_iter = mgr->tp_list.next; 1237 while (tp_iter != &mgr->tp_list) { 1238 if (tp_iter->tp == tp) { 1239 pj_list_erase(tp_iter); 1240 break; 1241 } 1242 tp_iter = tp_iter->next; 1243 } 1264 if (entry) { 1265 transport *tp_ref = (transport *)entry; 1266 transport *tp_iter = tp_ref; 1267 /* Search the matching entry from the transport list. */ 1268 do { 1269 if (tp_iter->tp == tp) { 1270 transport *tp_next = tp_iter->next; 1271 1272 /* Update hash table : 1273 * - transport list only contain single element, or 1274 * - the entry is the first element of the transport list. 1275 */ 1276 if (tp_iter == tp_ref) { 1277 pj_hash_set(NULL, mgr->table, &tp->key, key_len, hval, 1278 NULL); 1279 1280 if (tp_ref->next != tp_ref) { 1281 /* The transport list has multiple entry. */ 1282 pj_hash_set_np(mgr->table, &tp_next->tp->key, key_len, 1283 hval, tp_next->tp_buf, tp_next); 1284 } 1285 } 1286 1287 pj_list_erase(tp_iter); 1288 /* Put back to the transport freelist. */ 1289 pj_list_push_back(&mgr->tp_entry_freelist, tp_iter); 1290 1291 break; 1292 } 1293 tp_iter = tp_iter->next; 1294 } while (tp_iter != tp_ref); 1244 1295 } 1245 1296 … … 1248 1299 1249 1300 /* Dec ref transport group lock, if any */ 1250 if (tp->grp_lock) 1301 if (tp->grp_lock) { 1251 1302 pj_grp_lock_dec_ref(tp->grp_lock); 1303 } 1252 1304 1253 1305 /* Destroy. */ … … 1363 1415 pj_lock_acquire(mgr->lock); 1364 1416 1365 /* Check that no factory with the same typehas been registered. */1417 /* Check that no same factory has been registered. */ 1366 1418 status = PJ_SUCCESS; 1367 1419 for (p=mgr->factory_list.next; p!=&mgr->factory_list; p=p->next) { 1368 if (p->type == tpf->type) {1369 status = PJSIP_ETYPEEXISTS;1370 break;1371 }1372 1420 if (p == tpf) { 1373 1421 status = PJ_EEXISTS; … … 1444 1492 pjsip_tpmgr *mgr; 1445 1493 pj_status_t status; 1494 unsigned i = 0; 1495 pj_pool_t *mgr_pool; 1446 1496 1447 1497 PJ_ASSERT_RETURN(pool && endpt && rx_cb && p_mgr, PJ_EINVAL); … … 1453 1503 1454 1504 /* Create and initialize transport manager. */ 1455 mgr = PJ_POOL_ZALLOC_T(pool, pjsip_tpmgr); 1505 mgr_pool = pjsip_endpt_create_pool(endpt, "tpmgr", 1506 TPMGR_POOL_INIT_SIZE, 1507 TPMGR_POOL_INC_SIZE); 1508 mgr = PJ_POOL_ZALLOC_T(mgr_pool, pjsip_tpmgr); 1456 1509 mgr->endpt = endpt; 1457 1510 mgr->on_rx_msg = rx_cb; 1458 1511 mgr->on_tx_msg = tx_cb; 1512 mgr->pool = mgr_pool; 1513 1514 if (!mgr->pool) 1515 return PJ_ENOMEM; 1516 1459 1517 pj_list_init(&mgr->factory_list); 1460 1518 pj_list_init(&mgr->tdata_list); 1461 pj_list_init(&mgr->tp_ list);1462 1463 mgr->table = pj_hash_create( pool, PJSIP_TPMGR_HTABLE_SIZE);1519 pj_list_init(&mgr->tp_entry_freelist); 1520 1521 mgr->table = pj_hash_create(mgr->pool, PJSIP_TPMGR_HTABLE_SIZE); 1464 1522 if (!mgr->table) 1465 1523 return PJ_ENOMEM; 1466 1524 1467 status = pj_lock_create_recursive_mutex( pool, "tmgr%p", &mgr->lock);1525 status = pj_lock_create_recursive_mutex(mgr->pool, "tmgr%p", &mgr->lock); 1468 1526 if (status != PJ_SUCCESS) 1469 1527 return status; 1470 1528 1529 for (; i < PJSIP_TRANSPORT_ENTRY_ALLOC_CNT; ++i) { 1530 transport *tp_add = NULL; 1531 1532 tp_add = PJ_POOL_ZALLOC_T(mgr->pool, transport); 1533 if (!tp_add) 1534 return PJ_ENOMEM; 1535 pj_list_init(tp_add); 1536 pj_list_push_back(&mgr->tp_entry_freelist, tp_add); 1537 } 1538 1471 1539 #if defined(PJ_DEBUG) && PJ_DEBUG!=0 1472 status = pj_atomic_create( pool, 0, &mgr->tdata_counter);1540 status = pj_atomic_create(mgr->pool, 0, &mgr->tdata_counter); 1473 1541 if (status != PJ_SUCCESS) { 1474 1542 pj_lock_destroy(mgr->lock); … … 1698 1766 pj_hash_iterator_t *itr; 1699 1767 int nr_of_transports = 0; 1700 1768 1701 1769 pj_lock_acquire(mgr->lock); 1702 1770 1703 1771 itr = pj_hash_first(mgr->table, &itr_val); 1704 1772 while (itr) { 1705 nr_of_transports++; 1773 transport *tp_entry = (transport *)pj_hash_this(mgr->table, itr); 1774 nr_of_transports += pj_list_size(tp_entry); 1706 1775 itr = pj_hash_next(mgr->table, itr); 1707 1776 } 1708 1777 1709 1778 pj_lock_release(mgr->lock); 1710 1779 … … 1723 1792 pjsip_tpfactory *factory; 1724 1793 pjsip_endpoint *endpt = mgr->endpt; 1725 1794 1726 1795 PJ_LOG(5, (THIS_FILE, "Destroying transport manager")); 1727 1796 … … 1731 1800 * Destroy all transports in the hash table. 1732 1801 */ 1733 itr = pj_hash_first(mgr->table, &itr_val); 1734 while (itr != NULL) { 1735 pj_hash_iterator_t *next; 1736 pjsip_transport *transport; 1737 1738 transport = (pjsip_transport*) pj_hash_this(mgr->table, itr); 1739 1740 next = pj_hash_next(mgr->table, itr); 1741 1742 destroy_transport(mgr, transport); 1743 1744 itr = next; 1745 } 1746 1747 /* 1748 * Destroy transports in the list. 1749 */ 1750 if (!pj_list_empty(&mgr->tp_list)) { 1751 transport *tp_iter = mgr->tp_list.next; 1752 while (tp_iter != &mgr->tp_list) { 1753 transport *next = tp_iter->next; 1754 destroy_transport(mgr, tp_iter->tp); 1755 tp_iter = next; 1756 } 1757 } 1758 1802 for (itr = pj_hash_first(mgr->table, &itr_val); itr; 1803 itr = pj_hash_first(mgr->table, &itr_val)) 1804 { 1805 transport *tp_ref; 1806 tp_ref = pj_hash_this(mgr->table, itr); 1807 destroy_transport(mgr, tp_ref->tp); 1808 } 1809 1759 1810 /* 1760 1811 * Destroy all factories/listeners. … … 1763 1814 while (factory != &mgr->factory_list) { 1764 1815 pjsip_tpfactory *next = factory->next; 1765 1816 1766 1817 factory->destroy(factory); 1767 1818 … … 1805 1856 if (mod_msg_print.id != -1) { 1806 1857 pjsip_endpt_unregister_module(endpt, &mod_msg_print); 1858 } 1859 1860 if (mgr->pool) { 1861 pjsip_endpt_release_pool( mgr->endpt, mgr->pool ); 1807 1862 } 1808 1863 … … 2167 2222 pjsip_transport_key key; 2168 2223 int key_len; 2169 pjsip_transport *transport = NULL; 2224 pjsip_transport *tp_ref = NULL; 2225 transport *tp_entry = NULL; 2226 2170 2227 2171 2228 /* If listener is specified, verify that the listener type matches … … 2188 2245 pj_memcpy(&key.rem_addr, remote, addr_len); 2189 2246 2190 transport = (pjsip_transport*) 2191 pj_hash_get(mgr->table, &key, key_len, NULL); 2192 } 2193 2194 if (transport == NULL && 2247 tp_entry = (transport *)pj_hash_get(mgr->table, &key, key_len, 2248 NULL); 2249 if (tp_entry) { 2250 if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER) { 2251 transport *tp_iter = tp_entry; 2252 do { 2253 if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER && 2254 sel->u.listener && 2255 tp_iter->tp->factory == sel->u.listener) 2256 { 2257 tp_ref = tp_iter->tp; 2258 break; 2259 } 2260 tp_iter = tp_iter->next; 2261 } while (tp_iter != tp_entry); 2262 } else { 2263 tp_ref = tp_entry->tp; 2264 } 2265 } 2266 } 2267 2268 if (tp_ref == NULL && 2195 2269 (!sel || sel->disable_connection_reuse == PJ_FALSE)) 2196 2270 { … … 2207 2281 pj_bzero(addr, addr_len); 2208 2282 key_len = sizeof(key.type) + addr_len; 2209 transport = (pjsip_transport*) 2210 pj_hash_get(mgr->table, &key, key_len, NULL); 2283 tp_entry = (transport *) pj_hash_get(mgr->table, &key, 2284 key_len, NULL); 2285 if (tp_entry) { 2286 tp_ref = tp_entry->tp; 2287 } 2211 2288 } 2212 2289 /* For datagram transports, try lookup with zero address. … … 2220 2297 2221 2298 key_len = sizeof(key.type) + addr_len; 2222 transport = (pjsip_transport*) 2223 pj_hash_get(mgr->table, &key, key_len, NULL); 2299 tp_entry = (transport *) pj_hash_get(mgr->table, &key, 2300 key_len, NULL); 2301 if (tp_entry) { 2302 tp_ref = tp_entry->tp; 2303 } 2224 2304 } 2225 2305 } … … 2227 2307 /* If transport is found and listener is specified, verify listener */ 2228 2308 else if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER && 2229 sel->u.listener && t ransport->factory != sel->u.listener)2309 sel->u.listener && tp_ref->factory != sel->u.listener) 2230 2310 { 2231 t ransport= NULL;2311 tp_ref = NULL; 2232 2312 /* This will cause a new transport to be created which will be a 2233 2313 * 'duplicate' of the existing transport (same type & remote addr, … … 2236 2316 } 2237 2317 2238 if (t ransport!=NULL && !transport->is_shutdown) {2318 if (tp_ref!=NULL && !tp_ref->is_shutdown) { 2239 2319 /* 2240 2320 * Transport found! 2241 2321 */ 2242 pjsip_transport_add_ref(t ransport);2322 pjsip_transport_add_ref(tp_ref); 2243 2323 pj_lock_release(mgr->lock); 2244 *tp = t ransport;2245 2246 TRACE_((THIS_FILE, "Transport %s acquired", t ransport->obj_name));2324 *tp = tp_ref; 2325 2326 TRACE_((THIS_FILE, "Transport %s acquired", tp_ref->obj_name)); 2247 2327 return PJ_SUCCESS; 2248 2328 } … … 2306 2386 if (factory->create_transport2) { 2307 2387 status = factory->create_transport2(factory, mgr, mgr->endpt, 2308 (const pj_sockaddr*) remote, 2388 (const pj_sockaddr*) remote, 2309 2389 addr_len, tdata, tp); 2310 2390 } else { 2311 2391 status = factory->create_transport(factory, mgr, mgr->endpt, 2312 (const pj_sockaddr*) remote, 2392 (const pj_sockaddr*) remote, 2313 2393 addr_len, tp); 2314 2394 } 2315 2395 if (status == PJ_SUCCESS) { 2316 PJ_ASSERT_ON_FAIL(tp!=NULL, 2396 PJ_ASSERT_ON_FAIL(tp!=NULL, 2317 2397 {pj_lock_release(mgr->lock); return PJ_EBUG;}); 2318 2398 pjsip_transport_add_ref(*tp); … … 2357 2437 2358 2438 do { 2359 pjsip_transport *t = (pjsip_transport*) 2360 pj_hash_this(mgr->table, itr); 2361 2362 PJ_LOG(3, (THIS_FILE, " %s %s (refcnt=%d%s)", 2363 t->obj_name, 2364 t->info, 2365 pj_atomic_get(t->ref_cnt), 2366 (t->idle_timer.id ? " [idle]" : ""))); 2367 2439 transport *tp_entry = (transport *) pj_hash_this(mgr->table, itr); 2440 if (tp_entry) { 2441 transport *tp_iter = tp_entry; 2442 2443 do { 2444 pjsip_transport *tp_ref = tp_iter->tp; 2445 2446 PJ_LOG(3, (THIS_FILE, " %s %s%s%s%s(refcnt=%d%s)", 2447 tp_ref->obj_name, 2448 tp_ref->info, 2449 (tp_ref->factory)?" listener[":"", 2450 (tp_ref->factory)?tp_ref->factory->obj_name:"", 2451 (tp_ref->factory)?"]":"", 2452 pj_atomic_get(tp_ref->ref_cnt), 2453 (tp_ref->idle_timer.id ? " [idle]" : ""))); 2454 2455 tp_iter = tp_iter->next; 2456 } while (tp_iter != tp_entry); 2457 } 2368 2458 itr = pj_hash_next(mgr->table, itr); 2369 2459 } while (itr); -
pjproject/trunk/pjsip/src/pjsip/sip_transport_loop.c
r5535 r6002 377 377 goto on_error; 378 378 loop->base.key.type = PJSIP_TRANSPORT_LOOP_DGRAM; 379 //loop->base.key.rem_addr.sa_family = pj_AF_INET();379 loop->base.key.rem_addr.addr.sa_family = pj_AF_INET(); 380 380 loop->base.type_name = "LOOP-DGRAM"; 381 381 loop->base.info = "LOOP-DGRAM"; -
pjproject/trunk/pjsip/src/test/test.c
r4420 r6002 380 380 flush_events(500); 381 381 382 /* Show additional info on the log. e.g: not released memory pool. */ 383 pj_log_set_level(4); 384 382 385 /* Dumping memory pool usage */ 383 386 PJ_LOG(3,(THIS_FILE, "Peak memory size=%u MB", -
pjproject/trunk/pjsip/src/test/transport_tcp_test.c
r5311 r6002 30 30 */ 31 31 #if PJ_HAS_TCP 32 33 static pj_status_t multi_listener_test(pjsip_tpfactory *factory[], 34 unsigned num_factory, 35 pjsip_transport *tp[], 36 unsigned *num_tp) 37 { 38 pj_status_t status; 39 unsigned i = 0; 40 pj_str_t s; 41 pjsip_transport *tcp; 42 pjsip_tpfactory *tpfactory = NULL; 43 pj_sockaddr_in rem_addr; 44 pjsip_tpselector tp_sel; 45 unsigned ntp = 0; 46 47 for (;i<num_factory;++i) 48 { 49 /* Start TCP listener on arbitrary port. */ 50 status = pjsip_tcp_transport_start(endpt, NULL, 1, &tpfactory); 51 if (status != PJ_SUCCESS) { 52 app_perror(" Error: unable to start TCP transport", status); 53 return -10; 54 } 55 56 factory[i] = tpfactory; 57 } 58 59 /* Get the last listener address */ 60 status = pj_sockaddr_in_init(&rem_addr, &tpfactory->addr_name.host, 61 (pj_uint16_t)tpfactory->addr_name.port); 62 if (status != PJ_SUCCESS) { 63 app_perror(" Error: possibly invalid TCP address name", status); 64 return -11; 65 } 66 67 /* Acquire transport without selector. */ 68 status = pjsip_endpt_acquire_transport(endpt, PJSIP_TRANSPORT_TCP, 69 &rem_addr, sizeof(rem_addr), 70 NULL, &tcp); 71 if (status != PJ_SUCCESS || tcp == NULL) { 72 app_perror(" Error: unable to acquire TCP transport", status); 73 return -12; 74 } 75 tp[ntp++] = tcp; 76 77 /* After pjsip_endpt_acquire_transport, TCP transport must have 78 * reference counter 1. 79 */ 80 if (pj_atomic_get(tcp->ref_cnt) != 1) 81 return -13; 82 83 /* Acquire with the same remote address, should return the same tp. */ 84 status = pjsip_endpt_acquire_transport(endpt, PJSIP_TRANSPORT_TCP, 85 &rem_addr, sizeof(rem_addr), 86 NULL, &tcp); 87 if (status != PJ_SUCCESS || tcp == NULL) { 88 app_perror(" Error: unable to acquire TCP transport", status); 89 return -14; 90 } 91 92 /* Should return existing transport. */ 93 if (tp[ntp-1] != tcp) { 94 return -15; 95 } 96 97 /* Using the same TCP transport, it must have reference counter 2. 98 */ 99 if (pj_atomic_get(tcp->ref_cnt) != 2) 100 return -16; 101 102 /* Decrease the reference. */ 103 pjsip_transport_dec_ref(tcp); 104 105 /* Test basic transport attributes */ 106 status = generic_transport_test(tcp); 107 if (status != PJ_SUCCESS) 108 return status; 109 110 /* Check again that reference counter is 1. */ 111 if (pj_atomic_get(tcp->ref_cnt) != 1) 112 return -17; 113 114 /* Acquire transport test with selector. */ 115 pj_bzero(&tp_sel, sizeof(tp_sel)); 116 tp_sel.type = PJSIP_TPSELECTOR_LISTENER; 117 tp_sel.u.listener = factory[num_factory/2]; 118 pj_sockaddr_in_init(&rem_addr, pj_cstr(&s, "1.1.1.1"), 80); 119 status = pjsip_endpt_acquire_transport(endpt, PJSIP_TRANSPORT_TCP, 120 &rem_addr, sizeof(rem_addr), 121 &tp_sel, &tcp); 122 if (status != PJ_SUCCESS) { 123 app_perror(" Error: unable to acquire TCP transport", status); 124 return -18; 125 } 126 127 /* The transport should have the same factory set on the selector. */ 128 if (tcp->factory != factory[num_factory/2]) 129 return -19; 130 131 /* The transport should be newly created. */ 132 for (i = 0; i < ntp; ++i) { 133 if (tp[i] == tcp) { 134 break; 135 } 136 } 137 if (i != ntp) 138 return -20; 139 140 tp[ntp++] = tcp; 141 142 for (i = 0; i<ntp; ++i) { 143 if (pj_atomic_get(tp[i]->ref_cnt) != 1) 144 return -21; 145 } 146 *num_tp = ntp; 147 148 return PJ_SUCCESS; 149 } 150 32 151 int transport_tcp_test(void) 33 152 { 34 153 enum { SEND_RECV_LOOP = 8 }; 35 pjsip_tpfactory *tpfactory; 36 pjsip_transport *tcp; 154 enum { NUM_LISTENER = 4 }; 155 enum { NUM_TP = 8 }; 156 pjsip_tpfactory *tpfactory[NUM_LISTENER]; 157 pjsip_transport *tcp[NUM_TP]; 37 158 pj_sockaddr_in rem_addr; 38 159 pj_status_t status; … … 40 161 char addr[PJ_INET_ADDRSTRLEN]; 41 162 int rtt[SEND_RECV_LOOP], min_rtt; 42 int i, pkt_lost; 43 44 /* Start TCP listener on arbitrary port. */ 45 status = pjsip_tcp_transport_start(endpt, NULL, 1, &tpfactory); 46 if (status != PJ_SUCCESS) { 47 app_perror(" Error: unable to start TCP transport", status); 48 return -10; 49 } 50 51 52 /* Get the listener address */ 53 status = pj_sockaddr_in_init(&rem_addr, &tpfactory->addr_name.host, 54 (pj_uint16_t)tpfactory->addr_name.port); 55 if (status != PJ_SUCCESS) { 56 app_perror(" Error: possibly invalid TCP address name", status); 57 return -14; 58 } 163 int pkt_lost; 164 unsigned i; 165 unsigned num_listener = NUM_LISTENER; 166 unsigned num_tp = NUM_TP; 167 168 status = multi_listener_test(tpfactory, num_listener, tcp, &num_tp); 169 if (status != PJ_SUCCESS) 170 return status; 171 172 /* Get the last listener address */ 173 status = pj_sockaddr_in_init(&rem_addr, &tpfactory[0]->addr_name.host, 174 (pj_uint16_t)tpfactory[0]->addr_name.port); 59 175 60 176 pj_ansi_sprintf(url, "sip:alice@%s:%d;transport=tcp", 61 177 pj_inet_ntop2(pj_AF_INET(), &rem_addr.sin_addr, addr, 62 178 sizeof(addr)), 63 179 pj_ntohs(rem_addr.sin_port)); 64 65 66 /* Acquire one TCP transport. */67 status = pjsip_endpt_acquire_transport(endpt, PJSIP_TRANSPORT_TCP,68 &rem_addr, sizeof(rem_addr),69 NULL, &tcp);70 if (status != PJ_SUCCESS || tcp == NULL) {71 app_perror(" Error: unable to acquire TCP transport", status);72 return -17;73 }74 75 /* After pjsip_endpt_acquire_transport, TCP transport must have76 * reference counter 1.77 */78 if (pj_atomic_get(tcp->ref_cnt) != 1)79 return -20;80 81 /* Test basic transport attributes */82 status = generic_transport_test(tcp);83 if (status != PJ_SUCCESS)84 return status;85 86 87 /* Check again that reference counter is 1. */88 if (pj_atomic_get(tcp->ref_cnt) != 1)89 return -40;90 180 91 181 /* Load test */ … … 95 185 /* Basic transport's send/receive loopback test. */ 96 186 for (i=0; i<SEND_RECV_LOOP; ++i) { 97 status = transport_send_recv_test(PJSIP_TRANSPORT_TCP, tcp, url, &rtt[i]); 187 status = transport_send_recv_test(PJSIP_TRANSPORT_TCP, tcp[0], url, 188 &rtt[i]); 98 189 99 190 if (status != 0) { 100 pjsip_transport_dec_ref(tcp); 191 for (i = 0; i < num_tp ; ++i) { 192 pjsip_transport_dec_ref(tcp[i]); 193 } 101 194 flush_events(500); 102 195 return -72; … … 116 209 117 210 /* Multi-threaded round-trip test. */ 118 status = transport_rt_test(PJSIP_TRANSPORT_TCP, tcp , url, &pkt_lost);211 status = transport_rt_test(PJSIP_TRANSPORT_TCP, tcp[0], url, &pkt_lost); 119 212 if (status != 0) { 120 pjsip_transport_dec_ref(tcp); 213 for (i = 0; i < num_tp ; ++i) { 214 pjsip_transport_dec_ref(tcp[i]); 215 } 121 216 return status; 122 217 } … … 126 221 127 222 /* Check again that reference counter is still 1. */ 128 if (pj_atomic_get(tcp->ref_cnt) != 1) 129 return -80; 130 131 /* Destroy this transport. */ 132 pjsip_transport_dec_ref(tcp); 133 134 /* Force destroy this transport. */ 135 status = pjsip_transport_destroy(tcp); 136 if (status != PJ_SUCCESS) 137 return -90; 138 139 /* Unregister factory */ 140 status = pjsip_tpmgr_unregister_tpfactory(pjsip_endpt_get_tpmgr(endpt), 141 tpfactory); 142 if (status != PJ_SUCCESS) 143 return -95; 223 for (i = 0; i < num_tp; ++i) { 224 if (pj_atomic_get(tcp[i]->ref_cnt) != 1) 225 return -80; 226 } 227 228 for (i = 0; i < num_tp; ++i) { 229 /* Destroy this transport. */ 230 pjsip_transport_dec_ref(tcp[i]); 231 232 /* Force destroy this transport. */ 233 status = pjsip_transport_destroy(tcp[i]); 234 if (status != PJ_SUCCESS) 235 return -90; 236 } 237 238 for (i = 0; i < num_listener; ++i) { 239 /* Unregister factory */ 240 status = pjsip_tpmgr_unregister_tpfactory(pjsip_endpt_get_tpmgr(endpt), 241 tpfactory[i]); 242 if (status != PJ_SUCCESS) 243 return -95; 244 } 144 245 145 246 /* Flush events. */ -
pjproject/trunk/pjsip/src/test/transport_udp_test.c
r3553 r6002 25 25 #define THIS_FILE "transport_udp_test.c" 26 26 27 static pj_status_t multi_transport_test(pjsip_transport *tp[], unsigned num_tp) 28 { 29 pj_status_t status; 30 pj_uint16_t i = 0; 31 pj_str_t s; 32 pjsip_transport *udp_tp; 33 pj_sockaddr_in rem_addr; 34 pjsip_tpselector tp_sel; 35 36 for (;i<num_tp;++i) 37 { 38 pj_sockaddr_in addr; 39 40 pj_sockaddr_in_init(&addr, NULL, TEST_UDP_PORT+i); 41 42 /* Start UDP transport. */ 43 status = pjsip_udp_transport_start( endpt, &addr, NULL, 1, &udp_tp); 44 if (status != PJ_SUCCESS) { 45 app_perror(" Error: unable to start UDP transport", status); 46 return -110; 47 } 48 49 /* UDP transport must have initial reference counter set to 1. */ 50 if (pj_atomic_get(udp_tp->ref_cnt) != 1) 51 return -120; 52 53 /* Test basic transport attributes */ 54 status = generic_transport_test(udp_tp); 55 if (status != PJ_SUCCESS) 56 return status; 57 58 tp[i] = udp_tp; 59 } 60 61 for (i = 0; i < num_tp; ++i) { 62 udp_tp = tp[i]; 63 if (pj_atomic_get(udp_tp->ref_cnt) != 1) 64 return -130; 65 } 66 67 /* Acquire transport test without selector. */ 68 pj_sockaddr_in_init(&rem_addr, pj_cstr(&s, "1.1.1.1"), 80); 69 status = pjsip_endpt_acquire_transport(endpt, PJSIP_TRANSPORT_UDP, 70 &rem_addr, sizeof(rem_addr), 71 NULL, &udp_tp); 72 if (status != PJ_SUCCESS) 73 return -140; 74 75 for (i = 0; i < num_tp; ++i) { 76 if (udp_tp == tp[i]) { 77 break; 78 } 79 } 80 if (i == num_tp) 81 return -150; 82 83 pjsip_transport_dec_ref(udp_tp); 84 85 if (pj_atomic_get(udp_tp->ref_cnt) != 1) 86 return -160; 87 88 /* Acquire transport test with selector. */ 89 pj_bzero(&tp_sel, sizeof(tp_sel)); 90 tp_sel.type = PJSIP_TPSELECTOR_TRANSPORT; 91 tp_sel.u.transport = tp[num_tp-1]; 92 pj_sockaddr_in_init(&rem_addr, pj_cstr(&s, "1.1.1.1"), 80); 93 status = pjsip_endpt_acquire_transport(endpt, PJSIP_TRANSPORT_UDP, 94 &rem_addr, sizeof(rem_addr), 95 &tp_sel, &udp_tp); 96 if (status != PJ_SUCCESS) 97 return -170; 98 99 if (udp_tp != tp[num_tp-1]) 100 return -180; 101 102 pjsip_transport_dec_ref(udp_tp); 103 104 if (pj_atomic_get(udp_tp->ref_cnt) != 1) 105 return -190; 106 107 return PJ_SUCCESS; 108 } 27 109 28 110 /* … … 32 114 { 33 115 enum { SEND_RECV_LOOP = 8 }; 34 pjsip_transport *udp_tp, *tp; 35 pj_sockaddr_in addr, rem_addr; 116 enum { NUM_TP = 4 }; 117 pjsip_transport *tp[NUM_TP], *udp_tp; 118 pj_sockaddr_in rem_addr; 36 119 pj_str_t s; 37 120 pj_status_t status; … … 39 122 int i, pkt_lost; 40 123 41 pj_sockaddr_in_init(&addr, NULL, TEST_UDP_PORT); 42 43 /* Start UDP transport. */ 44 status = pjsip_udp_transport_start( endpt, &addr, NULL, 1, &udp_tp); 45 if (status != PJ_SUCCESS) { 46 app_perror(" Error: unable to start UDP transport", status); 47 return -10; 48 } 49 50 /* UDP transport must have initial reference counter set to 1. */ 51 if (pj_atomic_get(udp_tp->ref_cnt) != 1) 52 return -20; 53 54 /* Test basic transport attributes */ 55 status = generic_transport_test(udp_tp); 124 status = multi_transport_test(&tp[0], NUM_TP); 56 125 if (status != PJ_SUCCESS) 57 126 return status; 58 59 /* Test that transport manager is returning the correct60 * transport.61 */62 pj_sockaddr_in_init(&rem_addr, pj_cstr(&s, "1.1.1.1"), 80);63 status = pjsip_endpt_acquire_transport(endpt, PJSIP_TRANSPORT_UDP,64 &rem_addr, sizeof(rem_addr),65 NULL, &tp);66 if (status != PJ_SUCCESS)67 return -50;68 if (tp != udp_tp)69 return -60;70 71 /* pjsip_endpt_acquire_transport() adds reference, so we need72 * to decrement it.73 */74 pjsip_transport_dec_ref(tp);75 76 /* Check again that reference counter is 1. */77 if (pj_atomic_get(udp_tp->ref_cnt) != 1)78 return -70;79 127 80 128 /* Basic transport's send/receive loopback test. */ 81 129 pj_sockaddr_in_init(&rem_addr, pj_cstr(&s, "127.0.0.1"), TEST_UDP_PORT); 82 130 for (i=0; i<SEND_RECV_LOOP; ++i) { 83 status = transport_send_recv_test(PJSIP_TRANSPORT_UDP, tp ,131 status = transport_send_recv_test(PJSIP_TRANSPORT_UDP, tp[0], 84 132 "sip:alice@127.0.0.1:"TEST_UDP_PORT_STR, 85 133 &rtt[i]); … … 99 147 100 148 /* Multi-threaded round-trip test. */ 101 status = transport_rt_test(PJSIP_TRANSPORT_UDP, tp ,149 status = transport_rt_test(PJSIP_TRANSPORT_UDP, tp[0], 102 150 "sip:alice@127.0.0.1:"TEST_UDP_PORT_STR, 103 151 &pkt_lost); … … 108 156 PJ_LOG(3,(THIS_FILE, " note: %d packet(s) was lost", pkt_lost)); 109 157 110 /* Check again that reference counter is 1. */ 111 if (pj_atomic_get(udp_tp->ref_cnt) != 1) 112 return -80; 158 for (i = 0; i < NUM_TP; ++i) { 159 udp_tp = tp[i]; 113 160 114 /* Destroy this transport. */ 115 pjsip_transport_dec_ref(udp_tp); 161 /* Check again that reference counter is 1. */ 162 if (pj_atomic_get(udp_tp->ref_cnt) != 1) 163 return -80; 116 164 117 /* Force destroy this transport. */ 118 status = pjsip_transport_destroy(udp_tp); 119 if (status != PJ_SUCCESS) 120 return -90; 165 /* Destroy this transport. */ 166 pjsip_transport_dec_ref(udp_tp); 167 status = pjsip_transport_destroy(udp_tp); 168 if (status != PJ_SUCCESS) 169 return -90; 170 } 121 171 122 172 /* Flush events. */
Note: See TracChangeset
for help on using the changeset viewer.