Changeset 879 for pjproject/trunk/pjsip/src/pjsip/sip_transport.c
- Timestamp:
- Jan 12, 2007 6:37:35 AM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/src/pjsip/sip_transport.c
r866 r879 260 260 } 261 261 262 263 /***************************************************************************** 264 * 265 * TRANSPORT SELECTOR 266 * 267 *****************************************************************************/ 268 269 /* 270 * Add transport/listener reference in the selector. 271 */ 272 PJ_DEF(void) pjsip_tpselector_add_ref(pjsip_tpselector *sel) 273 { 274 if (sel->type == PJSIP_TPSELECTOR_TRANSPORT && sel->u.transport != NULL) 275 pjsip_transport_add_ref(sel->u.transport); 276 else if (sel->type == PJSIP_TPSELECTOR_LISTENER && sel->u.listener != NULL) 277 ; /* Hmm.. looks like we don't have reference counter for listener */ 278 } 279 280 281 /* 282 * Decrement transport/listener reference in the selector. 283 */ 284 PJ_DEF(void) pjsip_tpselector_dec_ref(pjsip_tpselector *sel) 285 { 286 if (sel->type == PJSIP_TPSELECTOR_TRANSPORT && sel->u.transport != NULL) 287 pjsip_transport_dec_ref(sel->u.transport); 288 else if (sel->type == PJSIP_TPSELECTOR_LISTENER && sel->u.listener != NULL) 289 ; /* Hmm.. looks like we don't have reference counter for listener */ 290 } 291 292 262 293 /***************************************************************************** 263 294 * … … 331 362 PJ_LOG(5,(tdata->obj_name, "Destroying txdata %s", 332 363 pjsip_tx_data_get_info(tdata))); 364 pjsip_tpselector_dec_ref(&tdata->tp_sel); 333 365 #if defined(PJ_DEBUG) && PJ_DEBUG!=0 334 366 pj_atomic_dec( tdata->mgr->tdata_counter ); … … 408 440 return tdata->info; 409 441 } 442 443 PJ_DEF(pj_status_t) pjsip_tx_data_set_transport(pjsip_tx_data *tdata, 444 const pjsip_tpselector *sel) 445 { 446 PJ_ASSERT_RETURN(tdata && sel, PJ_EINVAL); 447 448 pj_lock_acquire(tdata->lock); 449 450 pjsip_tpselector_dec_ref(&tdata->tp_sel); 451 452 pj_memcpy(&tdata->tp_sel, sel, sizeof(*sel)); 453 pjsip_tpselector_add_ref(&tdata->tp_sel); 454 455 pj_lock_release(tdata->lock); 456 457 return PJ_SUCCESS; 458 } 459 410 460 411 461 PJ_DEF(char*) pjsip_rx_data_get_info(pjsip_rx_data *rdata) … … 912 962 pj_sockaddr_in_init(&remote, NULL, 0); 913 963 status = pjsip_tpmgr_acquire_transport(tpmgr, type, &remote, 914 sizeof(remote), &tp);964 sizeof(remote), NULL, &tp); 915 965 916 966 if (status == PJ_SUCCESS) { … … 1201 1251 const pj_sockaddr_t *remote, 1202 1252 int addr_len, 1253 const pjsip_tpselector *sel, 1203 1254 pjsip_transport **tp) 1204 1255 { 1205 struct transport_key key;1206 int key_len;1207 pjsip_transport *transport;1208 1256 pjsip_tpfactory *factory; 1209 1257 pj_status_t status; … … 1216 1264 pj_lock_acquire(mgr->lock); 1217 1265 1218 key_len = sizeof(key.type) + addr_len; 1219 1220 /* First try to get exact destination. */ 1221 key.type = type; 1222 pj_memcpy(&key.addr, remote, addr_len); 1223 1224 transport = pj_hash_get(mgr->table, &key, key_len, NULL); 1225 if (transport == NULL) { 1226 unsigned flag = pjsip_transport_get_flag_from_type(type); 1227 const pj_sockaddr *remote_addr = (const pj_sockaddr*)remote; 1228 1229 /* Ignore address for loop transports. */ 1230 if (type == PJSIP_TRANSPORT_LOOP || 1231 type == PJSIP_TRANSPORT_LOOP_DGRAM) 1232 { 1233 pj_sockaddr_in *addr = (pj_sockaddr_in*)&key.addr; 1234 1235 pj_bzero(addr, sizeof(pj_sockaddr_in)); 1236 key_len = sizeof(key.type) + sizeof(pj_sockaddr_in); 1237 transport = pj_hash_get(mgr->table, &key, key_len, NULL); 1238 } 1239 /* For datagram INET transports, try lookup with zero address. 1266 /* If transport is specified, then just use it if it is suitable 1267 * for the destination. 1268 */ 1269 if (sel && sel->type == PJSIP_TPSELECTOR_TRANSPORT && 1270 sel->u.transport) 1271 { 1272 pjsip_transport *seltp = sel->u.transport; 1273 1274 /* See if the transport is (not) suitable */ 1275 if (seltp->key.type != type) { 1276 pj_lock_release(mgr->lock); 1277 return PJSIP_ETPNOTSUITABLE; 1278 } 1279 1280 /* We could also verify that the destination address is reachable 1281 * from this transport (i.e. both are equal), but if application 1282 * has requested a specific transport to be used, assume that 1283 * it knows what to do. 1284 * 1285 * In other words, I don't think destination verification is a good 1286 * idea for now. 1240 1287 */ 1241 else if ((flag & PJSIP_TRANSPORT_DATAGRAM) && 1242 (remote_addr->sa_family == PJ_AF_INET)) 1243 { 1244 pj_sockaddr_in *addr = (pj_sockaddr_in*)&key.addr; 1245 1246 pj_bzero(addr, sizeof(pj_sockaddr_in)); 1247 addr->sin_family = PJ_AF_INET; 1248 1249 key_len = sizeof(key.type) + sizeof(pj_sockaddr_in); 1250 transport = pj_hash_get(mgr->table, &key, key_len, NULL); 1251 } 1252 } 1288 1289 /* Transport looks to be suitable to use, so just use it. */ 1290 pjsip_transport_add_ref(seltp); 1291 pj_lock_release(mgr->lock); 1292 *tp = seltp; 1293 1294 TRACE_((THIS_FILE, "Transport %s acquired", seltp->obj_name)); 1295 return PJ_SUCCESS; 1296 1297 1298 } else if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER && 1299 sel->u.listener) 1300 { 1301 /* Application has requested that a specific listener is to 1302 * be used. In this case, skip transport hash table lookup. 1303 */ 1304 1305 /* Verify that the listener type matches the destination type */ 1306 if (sel->u.listener->type != type) { 1307 pj_lock_release(mgr->lock); 1308 return PJSIP_ETPNOTSUITABLE; 1309 } 1310 1311 /* We'll use this listener to create transport */ 1312 factory = sel->u.listener; 1313 1314 } else { 1315 1316 /* 1317 * This is the "normal" flow, where application doesn't specify 1318 * specific transport/listener to be used to send message to. 1319 * In this case, lookup the transport from the hash table. 1320 */ 1321 struct transport_key key; 1322 int key_len; 1323 pjsip_transport *transport; 1324 1325 key_len = sizeof(key.type) + addr_len; 1326 1327 /* First try to get exact destination. */ 1328 key.type = type; 1329 pj_memcpy(&key.addr, remote, addr_len); 1330 1331 transport = pj_hash_get(mgr->table, &key, key_len, NULL); 1332 if (transport == NULL) { 1333 unsigned flag = pjsip_transport_get_flag_from_type(type); 1334 const pj_sockaddr *remote_addr = (const pj_sockaddr*)remote; 1335 1336 /* Ignore address for loop transports. */ 1337 if (type == PJSIP_TRANSPORT_LOOP || 1338 type == PJSIP_TRANSPORT_LOOP_DGRAM) 1339 { 1340 pj_sockaddr_in *addr = (pj_sockaddr_in*)&key.addr; 1341 1342 pj_bzero(addr, sizeof(pj_sockaddr_in)); 1343 key_len = sizeof(key.type) + sizeof(pj_sockaddr_in); 1344 transport = pj_hash_get(mgr->table, &key, key_len, NULL); 1345 } 1346 /* For datagram INET transports, try lookup with zero address. 1347 */ 1348 else if ((flag & PJSIP_TRANSPORT_DATAGRAM) && 1349 (remote_addr->sa_family == PJ_AF_INET)) 1350 { 1351 pj_sockaddr_in *addr = (pj_sockaddr_in*)&key.addr; 1352 1353 pj_bzero(addr, sizeof(pj_sockaddr_in)); 1354 addr->sin_family = PJ_AF_INET; 1355 1356 key_len = sizeof(key.type) + sizeof(pj_sockaddr_in); 1357 transport = pj_hash_get(mgr->table, &key, key_len, NULL); 1358 } 1359 } 1360 1361 if (transport!=NULL && !transport->is_shutdown) { 1362 /* 1363 * Transport found! 1364 */ 1365 pjsip_transport_add_ref(transport); 1366 pj_lock_release(mgr->lock); 1367 *tp = transport; 1368 1369 TRACE_((THIS_FILE, "Transport %s acquired", transport->obj_name)); 1370 return PJ_SUCCESS; 1371 } 1372 1373 /* 1374 * Transport not found! 1375 * Find factory that can create such transport. 1376 */ 1377 factory = mgr->factory_list.next; 1378 while (factory != &mgr->factory_list) { 1379 if (factory->type == type) 1380 break; 1381 factory = factory->next; 1382 } 1383 1384 if (factory == &mgr->factory_list) { 1385 /* No factory can create the transport! */ 1386 pj_lock_release(mgr->lock); 1387 TRACE_((THIS_FILE, "No suitable factory was found either")); 1388 return PJSIP_EUNSUPTRANSPORT; 1389 } 1390 1391 } 1392 1253 1393 1254 if (transport!=NULL && !transport->is_shutdown) { 1255 /* 1256 * Transport found! 1257 */ 1258 pjsip_transport_add_ref(transport); 1259 pj_lock_release(mgr->lock); 1260 *tp = transport; 1261 1262 TRACE_((THIS_FILE, "Transport %s acquired", transport->obj_name)); 1263 return PJ_SUCCESS; 1264 } 1265 1266 /* 1267 * Transport not found! 1268 * Find factory that can create such transport. 1269 */ 1270 factory = mgr->factory_list.next; 1271 while (factory != &mgr->factory_list) { 1272 if (factory->type == type) 1273 break; 1274 factory = factory->next; 1275 } 1276 1277 if (factory == &mgr->factory_list) { 1278 /* No factory can create the transport! */ 1279 pj_lock_release(mgr->lock); 1280 TRACE_((THIS_FILE, "No suitable factory was found either")); 1281 return PJSIP_EUNSUPTRANSPORT; 1282 } 1283 1284 TRACE_((THIS_FILE, "%s, creating new one from factory", 1285 (transport?"Transport is shutdown":"No transport found"))); 1394 TRACE_((THIS_FILE, "Creating new transport from factory")); 1286 1395 1287 1396 /* Request factory to create transport. */
Note: See TracChangeset
for help on using the changeset viewer.