Changeset 879 for pjproject/trunk
- Timestamp:
- Jan 12, 2007 6:37:35 AM (18 years ago)
- Location:
- pjproject/trunk/pjsip
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/include/pjsip-ua/sip_regc.h
r843 r879 27 27 #include <pjsip/sip_types.h> 28 28 #include <pjsip/sip_auth.h> 29 #include <pjsip/sip_transport.h> 29 30 30 31 … … 199 200 const pjsip_route_hdr*route_set); 200 201 202 203 /** 204 * Lock/bind client registration to a specific transport/listener. 205 * This is optional, as normally transport will be selected automatically 206 * based on the destination of requests upon resolver completion. 207 * When the client registration is explicitly bound to the specific 208 * transport/listener, all UAC transactions originated by the client 209 * registration will use the specified transport/listener when sending 210 * outgoing requests. 211 * 212 * Note that this doesn't affect the Contact header set for this client 213 * registration. Application must manually update the Contact header if 214 * necessary, to adjust the address according to the transport being 215 * selected. 216 * 217 * @param regc The client registration instance. 218 * @param sel Transport selector containing the specification of 219 * transport or listener to be used by this session 220 * to send requests. 221 * 222 * @return PJ_SUCCESS on success, or the appropriate error code. 223 */ 224 PJ_DECL(pj_status_t) pjsip_regc_set_transport(pjsip_regc *regc, 225 const pjsip_tpselector *sel); 226 227 201 228 /** 202 229 * Add headers to be added to outgoing REGISTER requests. -
pjproject/trunk/pjsip/include/pjsip/sip_dialog.h
r729 r879 29 29 #include <pjsip/sip_auth.h> 30 30 #include <pjsip/sip_errno.h> 31 #include <pjsip/sip_transport.h> 31 32 #include <pj/sock.h> 32 33 #include <pj/assert.h> … … 135 136 int tsx_count; /**< Number of pending transactions. */ 136 137 138 /** Transport selector. */ 139 pjsip_tpselector tp_sel; 140 137 141 /* Dialog usages. */ 138 142 unsigned usage_cnt; /**< Number of registered usages. */ … … 225 229 226 230 /** 231 * Lock/bind dialog to a specific transport/listener. This is optional, 232 * as normally transport will be selected automatically based on the 233 * destination of requests upon resolver completion. When the dialog is 234 * explicitly bound to the specific transport/listener, all UAC transactions 235 * originated by this dialog will use the specified transport/listener 236 * when sending outgoing requests. 237 * 238 * Note that this doesn't affect the Contact header generated by this 239 * dialog. Application must manually update the Contact header if 240 * necessary, to adjust the address according to the transport being 241 * selected. 242 * 243 * @param dlg The dialog instance. 244 * @param sel Transport selector containing the specification of 245 * transport or listener to be used by this dialog 246 * to send requests. 247 * 248 * @return PJ_SUCCESS on success, or the appropriate error code. 249 */ 250 PJ_DECL(pj_status_t) pjsip_dlg_set_transport(pjsip_dialog *dlg, 251 const pjsip_tpselector *sel); 252 253 254 /** 227 255 * Create a new (forked) dialog on receipt on forked response in rdata. 228 256 * The new dialog will be created from original_dlg, except that it will have -
pjproject/trunk/pjsip/include/pjsip/sip_endpoint.h
r797 r879 353 353 /** 354 354 * Find a SIP transport suitable for sending SIP message to the specified 355 * address. This function will complete asynchronously when the transport is 356 * ready (for example, when TCP socket is connected), and when it completes, 357 * the callback will be called with the status of the operation. 358 * 359 * @see pjsip_transport_get 355 * address. If transport selector ("sel") is set, then the function will 356 * check if the transport selected is suitable to send requests to the 357 * specified address. 358 * 359 * @see pjsip_tpmgr_acquire_transport 360 * 361 * @param endpt The SIP endpoint instance. 362 * @param type The type of transport to be acquired. 363 * @param remote The remote address to send message to. 364 * @param addr_len Length of the remote address. 365 * @param sel Optional pointer to transport selector instance which is 366 * used to find explicit transport, if required. 367 * @param p_tp Pointer to receive the transport instance, if one is found. 368 * 369 * @return PJ_SUCCESS on success, or the appropriate error code. 360 370 */ 361 371 PJ_DECL(pj_status_t) … … 364 374 const pj_sockaddr_t *remote, 365 375 int addr_len, 366 pjsip_transport **p_transport); 376 const pjsip_tpselector *sel, 377 pjsip_transport **p_tp); 367 378 368 379 -
pjproject/trunk/pjsip/include/pjsip/sip_errno.h
r871 r879 215 215 */ 216 216 #define PJSIP_EBUFDESTROYED (PJSIP_ERRNO_START_PJSIP + 63) /* 171063 */ 217 /** 218 * @hideinitializer 219 * Unsuitable transport selected. This error occurs when application 220 * has explicitly requested to use a particular transport/listener, 221 * but the selected transport is not suitable to send request to 222 * the specified destination. 223 */ 224 #define PJSIP_ETPNOTSUITABLE (PJSIP_ERRNO_START_PJSIP + 64) /* 171064 */ 217 225 218 226 -
pjproject/trunk/pjsip/include/pjsip/sip_transaction.h
r622 r879 27 27 #include <pjsip/sip_msg.h> 28 28 #include <pjsip/sip_util.h> 29 #include <pjsip/sip_transport.h> 29 30 #include <pj/timer.h> 30 31 … … 97 98 pj_uint32_t hashed_key; /**< Key's hashed value. */ 98 99 pj_str_t branch; /**< The branch Id. */ 100 pjsip_tpselector tp_sel; /**< Transport selector. */ 99 101 100 102 /* … … 215 217 216 218 /** 219 * Lock/bind transaction to a specific transport/listener. This is optional, 220 * as normally transport will be selected automatically based on the 221 * destination of the request upon resolver completion. Also it's only valid 222 * for UAC transaction (to send outgoing request), since for UAS the 223 * transport will be selected according to rules about handling incoming 224 * request (most likely it will use the transport where the request is 225 * coming from if ";rport" parameter is present in Via header). 226 * 227 * @param tsx The UAC transaction. 228 * @param sel Transport selector containing the specification of 229 * transport or listener to be used by this transaction 230 * to send requests. 231 * 232 * @return PJ_SUCCESS on success, or the appropriate error code. 233 */ 234 PJ_DECL(pj_status_t) pjsip_tsx_set_transport(pjsip_transaction *tsx, 235 const pjsip_tpselector *sel); 236 237 238 /** 217 239 * Call this function to manually feed a message to the transaction. 218 240 * For UAS transaction, application MUST call this function after -
pjproject/trunk/pjsip/include/pjsip/sip_transport.h
r742 r879 55 55 * 56 56 *****************************************************************************/ 57 58 /* 59 * Forward declaration for transport factory (since it is referenced by 60 * the transport factory itself). 61 */ 62 typedef struct pjsip_tpfactory pjsip_tpfactory; 63 57 64 58 65 /** … … 157 164 158 165 166 167 /***************************************************************************** 168 * 169 * TRANSPORT SELECTOR. 170 * 171 *****************************************************************************/ 172 173 /** 174 * This structure describes the type of data in pjsip_tpselector. 175 */ 176 typedef enum pjsip_tpselector_type 177 { 178 /** Transport is not specified. */ 179 PJSIP_TPSELECTOR_NONE, 180 181 /** Use the specific transport to send request. */ 182 PJSIP_TPSELECTOR_TRANSPORT, 183 184 /** Use the specific listener to send request. */ 185 PJSIP_TPSELECTOR_LISTENER, 186 187 } pjsip_tpselector_type; 188 189 190 /** 191 * This structure describes the transport/listener preference to be used 192 * when sending outgoing requests. 193 * 194 * Normally transport will be selected automatically according to rules about 195 * sending requests. But some applications (such as proxies or B2BUAs) may 196 * want to explicitly use specific transport to send requests, for example 197 * when they want to make sure that outgoing request should go from a specific 198 * network interface. 199 * 200 * The pjsip_tpselector structure is used for that purpose, i.e. to allow 201 * application specificly request that a particular transport/listener 202 * should be used to send request. This structure is used when calling 203 * pjsip_tsx_set_transport() and pjsip_dlg_set_transport(). 204 */ 205 typedef struct pjsip_tpselector 206 { 207 /** The type of data in the union */ 208 pjsip_tpselector_type type; 209 210 /** Union representing the transport/listener criteria to be used. */ 211 union { 212 pjsip_transport *transport; 213 pjsip_tpfactory *listener; 214 } u; 215 216 } pjsip_tpselector; 217 218 219 /** 220 * Add transport/listener reference in the selector to prevent the specified 221 * transport/listener from being destroyed while application still has 222 * reference to it. 223 * 224 * @param sel The transport selector. 225 */ 226 PJ_DECL(void) pjsip_tpselector_add_ref(pjsip_tpselector *sel); 227 228 229 /** 230 * Decrement transport/listener reference in the selector. 231 * @param sel The transport selector 232 */ 233 PJ_DECL(void) pjsip_tpselector_dec_ref(pjsip_tpselector *sel); 234 235 159 236 /***************************************************************************** 160 237 * … … 432 509 int dst_port; /**< Destination port. */ 433 510 } tp_info; 511 512 /** 513 * Transport selector, to specify which transport to be used. 514 * The value here must be set with pjsip_tx_data_set_transport(), 515 * to allow reference counter to be set properly. 516 */ 517 pjsip_tpselector tp_sel; 518 434 519 }; 435 520 … … 499 584 */ 500 585 PJ_DECL(char*) pjsip_tx_data_get_info( pjsip_tx_data *tdata ); 586 587 /** 588 * Set the explicit transport to be used when sending this transmit data. 589 * Application should not need to call this function, but rather use 590 * pjsip_tsx_set_transport() and pjsip_dlg_set_transport() instead (which 591 * will call this function). 592 * 593 * @param tdata The transmit buffer. 594 * @param sel Transport selector. 595 * 596 * @return PJ_SUCCESS on success. 597 */ 598 PJ_DECL(pj_status_t) pjsip_tx_data_set_transport(pjsip_tx_data *tdata, 599 const pjsip_tpselector *sel); 501 600 502 601 … … 707 806 *****************************************************************************/ 708 807 709 /*710 * Forward declaration for transport factory (since it is referenced by711 * the transport factory itself).712 */713 typedef struct pjsip_tpfactory pjsip_tpfactory;714 715 808 716 809 /** … … 860 953 * Find transport to be used to send message to remote destination. If no 861 954 * suitable transport is found, a new one will be created. 955 * 956 * This is an internal function since normally application doesn't have access 957 * to transport manager. Application should use pjsip_endpt_acquire_transport() 958 * instead. 959 * 960 * @param mgr The transport manager instance. 961 * @param type The type of transport to be acquired. 962 * @param remote The remote address to send message to. 963 * @param addr_len Length of the remote address. 964 * @param sel Optional pointer to transport selector instance which is 965 * used to find explicit transport, if required. 966 * @param tp Pointer to receive the transport instance, if one is found. 967 * 968 * @return PJ_SUCCESS on success, or the appropriate error code. 862 969 */ 863 970 PJ_DECL(pj_status_t) pjsip_tpmgr_acquire_transport(pjsip_tpmgr *mgr, … … 865 972 const pj_sockaddr_t *remote, 866 973 int addr_len, 974 const pjsip_tpselector *sel, 867 975 pjsip_transport **tp); 868 976 -
pjproject/trunk/pjsip/src/pjsip-ua/sip_reg.c
r843 r879 77 77 pj_time_val next_reg; 78 78 pj_timer_entry timer; 79 80 /* Transport selector */ 81 pjsip_tpselector tp_sel; 79 82 }; 80 83 … … 125 128 regc->cb = NULL; 126 129 } else { 130 pjsip_tpselector_dec_ref(®c->tp_sel); 127 131 pjsip_endpt_release_pool(regc->endpt, regc->pool); 128 132 } … … 310 314 return PJ_SUCCESS; 311 315 } 316 317 318 /* 319 * Bind client registration to a specific transport/listener. 320 */ 321 PJ_DEF(pj_status_t) pjsip_regc_set_transport( pjsip_regc *regc, 322 const pjsip_tpselector *sel) 323 { 324 PJ_ASSERT_RETURN(regc && sel, PJ_EINVAL); 325 326 pjsip_tpselector_dec_ref(®c->tp_sel); 327 pj_memcpy(®c->tp_sel, sel, sizeof(*sel)); 328 pjsip_tpselector_add_ref(®c->tp_sel); 329 330 return PJ_SUCCESS; 331 } 332 312 333 313 334 PJ_DEF(pj_status_t) pjsip_regc_add_headers( pjsip_regc *regc, -
pjproject/trunk/pjsip/src/pjsip/sip_dialog.c
r797 r879 507 507 508 508 /* 509 * Bind dialog to a specific transport/listener. 510 */ 511 PJ_DEF(pj_status_t) pjsip_dlg_set_transport( pjsip_dialog *dlg, 512 const pjsip_tpselector *sel) 513 { 514 /* Validate */ 515 PJ_ASSERT_RETURN(dlg && sel, PJ_EINVAL); 516 517 /* Start locking the dialog. */ 518 pjsip_dlg_inc_lock(dlg); 519 520 /* Decrement reference counter of previous transport selector */ 521 pjsip_tpselector_dec_ref(&dlg->tp_sel); 522 523 /* Copy transport selector structure .*/ 524 pj_memcpy(&dlg->tp_sel, sel, sizeof(*sel)); 525 526 /* Increment reference counter */ 527 pjsip_tpselector_add_ref(&dlg->tp_sel); 528 529 /* Unlock dialog. */ 530 pjsip_dlg_dec_lock(dlg); 531 532 return PJ_SUCCESS; 533 } 534 535 536 /* 509 537 * Create forked dialog from a response. 510 538 */ … … 1066 1094 goto on_error; 1067 1095 1096 /* Set transport selector */ 1097 status = pjsip_tsx_set_transport(tsx, &dlg->tp_sel); 1098 pj_assert(status == PJ_SUCCESS); 1099 1068 1100 /* Attach this dialog to the transaction, so that user agent 1069 1101 * will dispatch events to this dialog. … … 1087 1119 1088 1120 } else { 1121 /* Set transport selector */ 1122 pjsip_tx_data_set_transport(tdata, &dlg->tp_sel); 1123 1124 /* Send request */ 1089 1125 status = pjsip_endpt_send_request_stateless(dlg->endpt, tdata, 1090 1126 NULL, NULL); -
pjproject/trunk/pjsip/src/pjsip/sip_endpoint.c
r839 r879 1044 1044 const pj_sockaddr_t *remote, 1045 1045 int addr_len, 1046 const pjsip_tpselector *sel, 1046 1047 pjsip_transport **transport) 1047 1048 { 1048 1049 return pjsip_tpmgr_acquire_transport(endpt->transport_mgr, type, 1049 remote, addr_len, transport);1050 remote, addr_len, sel, transport); 1050 1051 } 1051 1052 -
pjproject/trunk/pjsip/src/pjsip/sip_transaction.c
r839 r879 932 932 tsx->transport = NULL; 933 933 } 934 /* Decrement reference counter in transport selector */ 935 pjsip_tpselector_dec_ref(&tsx->tp_sel); 936 934 937 /* Free last transmitted message. */ 935 938 if (tsx->last_tx) { … … 1364 1367 1365 1368 /* 1369 * Bind transaction to a specific transport/listener. 1370 */ 1371 PJ_DEF(pj_status_t) pjsip_tsx_set_transport(pjsip_transaction *tsx, 1372 const pjsip_tpselector *sel) 1373 { 1374 struct tsx_lock_data lck; 1375 1376 /* Must be UAC transaction */ 1377 PJ_ASSERT_RETURN(tsx && sel && tsx->role == PJSIP_ROLE_UAC, PJ_EINVAL); 1378 1379 /* Start locking the transaction. */ 1380 lock_tsx(tsx, &lck); 1381 1382 /* Decrement reference counter of previous transport selector */ 1383 pjsip_tpselector_dec_ref(&tsx->tp_sel); 1384 1385 /* Copy transport selector structure .*/ 1386 pj_memcpy(&tsx->tp_sel, sel, sizeof(*sel)); 1387 1388 /* Increment reference counter */ 1389 pjsip_tpselector_add_ref(&tsx->tp_sel); 1390 1391 /* Unlock transaction. */ 1392 unlock_tsx(tsx, &lck); 1393 1394 return PJ_SUCCESS; 1395 } 1396 1397 1398 /* 1366 1399 * Set transaction status code and reason. 1367 1400 */ … … 1424 1457 /* Dispatch to transaction. */ 1425 1458 lock_tsx(tsx, &lck); 1459 1460 /* Set transport selector to tdata */ 1461 pjsip_tx_data_set_transport(tdata, &tsx->tp_sel); 1462 1463 /* Dispatch to state handler */ 1426 1464 status = (*tsx->state_handler)(tsx, &event); 1465 1427 1466 unlock_tsx(tsx, &lck); 1428 1467 1429 /* Will always decrement tdata reference counter1430 * ( consistent with other send functions.1468 /* Only decrement reference counter when it returns success. 1469 * (This is the specification from the .PDF design document). 1431 1470 */ 1432 1471 if (status == PJ_SUCCESS) { -
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. */ -
pjproject/trunk/pjsip/src/pjsip/sip_util.c
r797 r879 838 838 cur_addr, 839 839 cur_addr_len, 840 &tdata->tp_sel, 840 841 &stateless_data->cur_transport); 841 842 if (status != PJ_SUCCESS) { … … 1112 1113 &addr->entry[0].addr, 1113 1114 addr->entry[0].addr_len, 1115 &send_state->tdata->tp_sel, 1114 1116 &send_state->cur_transport); 1115 1117 if (status != PJ_SUCCESS) {
Note: See TracChangeset
for help on using the changeset viewer.