Changeset 109 for pjproject/trunk/pjsip/src/pjsip/sip_transport.c
- Timestamp:
- Jan 7, 2006 6:44:25 PM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/src/pjsip/sip_transport.c
r107 r109 23 23 #include <pjsip/sip_private.h> 24 24 #include <pjsip/sip_errno.h> 25 #include <pjsip/sip_module.h> 25 26 #include <pj/os.h> 26 27 #include <pj/log.h> … … 33 34 34 35 35 #define THIS_FILE "transport" 36 #define THIS_FILE "sip_transport.c" 37 38 /* Prototype. */ 39 static pj_status_t mod_on_tx_msg(pjsip_tx_data *tdata); 40 41 /* This module has sole purpose to print transmit data to contigous buffer 42 * before actually transmitted to the wire. 43 */ 44 static pjsip_module mod_msg_print = 45 { 46 NULL, NULL, /* prev and next */ 47 { "mod-msg-print", 13}, /* Name. */ 48 -1, /* Id */ 49 PJSIP_MOD_PRIORITY_TRANSPORT_LAYER, /* Priority */ 50 NULL, /* User data. */ 51 0, /* Number of methods supported (=0). */ 52 { 0 }, /* Array of methods (none) */ 53 NULL, /* load() */ 54 NULL, /* start() */ 55 NULL, /* stop() */ 56 NULL, /* unload() */ 57 NULL, /* on_rx_request() */ 58 NULL, /* on_rx_response() */ 59 &mod_on_tx_msg, /* on_tx_request() */ 60 &mod_on_tx_msg, /* on_tx_response() */ 61 NULL, /* on_tsx_state() */ 62 }; 36 63 37 64 /* … … 47 74 pj_atomic_t *tdata_counter; 48 75 #endif 49 void (*msg_cb)(pjsip_endpoint*, pj_status_t, pjsip_rx_data*); 76 void (*on_rx_msg)(pjsip_endpoint*, pj_status_t, pjsip_rx_data*); 77 pj_status_t (*on_tx_msg)(pjsip_endpoint*, pjsip_tx_data*); 50 78 }; 51 79 … … 67 95 } transport_names[] = 68 96 { 69 { PJSIP_TRANSPORT_UNSPECIFIED, 0, { NULL, 0}, 0},97 { PJSIP_TRANSPORT_UNSPECIFIED, 0, {"Unspecified", 11}, 0}, 70 98 { PJSIP_TRANSPORT_UDP, 5060, {"UDP", 3}, PJSIP_TRANSPORT_DATAGRAM}, 71 99 { PJSIP_TRANSPORT_TCP, 5060, {"TCP", 3}, PJSIP_TRANSPORT_RELIABLE}, … … 91 119 PJSIP_TRANSPORT_UDP, PJSIP_TRANSPORT_UNSPECIFIED); 92 120 121 if (name->slen == 0) 122 return PJSIP_TRANSPORT_UNSPECIFIED; 123 93 124 /* Get transport type from name. */ 94 125 for (i=0; i<PJ_ARRAY_SIZE(transport_names); ++i) { … … 163 194 } 164 195 196 /* 197 * Get transport name. 198 */ 199 PJ_DEF(const char*) pjsip_transport_get_type_name(pjsip_transport_type_e type) 200 { 201 /* Sanity check. 202 * Check that transport_names[] are indexed on transport type. 203 */ 204 PJ_ASSERT_RETURN(transport_names[PJSIP_TRANSPORT_UDP].type == 205 PJSIP_TRANSPORT_UDP, "Unknown"); 206 207 /* Check that argument is valid. */ 208 PJ_ASSERT_RETURN(type < PJ_ARRAY_SIZE(transport_names), "Unknown"); 209 210 /* Return the port. */ 211 return transport_names[type].name.ptr; 212 } 165 213 166 214 /***************************************************************************** … … 181 229 182 230 PJ_ASSERT_RETURN(mgr && p_tdata, PJ_EINVAL); 183 184 PJ_LOG(5, ("", "pjsip_tx_data_create"));185 231 186 232 pool = pjsip_endpt_create_pool( mgr->endpt, "tdta%p", … … 235 281 pj_assert( pj_atomic_get(tdata->ref_cnt) > 0); 236 282 if (pj_atomic_dec_and_get(tdata->ref_cnt) <= 0) { 237 PJ_LOG(5,(tdata->obj_name, "destroying txdata")); 283 PJ_LOG(5,(tdata->obj_name, "Destroying txdata %s", 284 pjsip_tx_data_get_info(tdata))); 238 285 #if defined(PJ_DEBUG) && PJ_DEBUG!=0 239 286 pj_atomic_dec( tdata->mgr->tdata_counter ); … … 255 302 { 256 303 tdata->buf.cur = tdata->buf.start; 304 tdata->info = NULL; 257 305 } 258 306 … … 262 310 } 263 311 264 312 static char *get_msg_info(pj_pool_t *pool, const char *obj_name, 313 const pjsip_msg *msg) 314 { 315 char info_buf[128], *info; 316 const pjsip_cseq_hdr *cseq; 317 int len; 318 319 cseq = pjsip_msg_find_hdr(msg, PJSIP_H_CSEQ, NULL); 320 PJ_ASSERT_RETURN(cseq != NULL, "INVALID MSG"); 321 322 if (msg->type == PJSIP_REQUEST_MSG) { 323 len = pj_snprintf(info_buf, sizeof(info_buf), 324 "Request msg %.*s/cseq=%d (%s)", 325 msg->line.req.method.name.slen, 326 msg->line.req.method.name.ptr, 327 cseq->cseq, obj_name); 328 } else { 329 len = pj_snprintf(info_buf, sizeof(info_buf), 330 "Response msg %d/%.*s/cseq=%d (%s)", 331 msg->line.status.code, 332 cseq->method.name.slen, 333 cseq->method.name.ptr, 334 cseq->cseq, obj_name); 335 } 336 337 if (len < 1 || len >= sizeof(info_buf)) { 338 return (char*)obj_name; 339 } 340 341 info = pj_pool_alloc(pool, len+1); 342 pj_memcpy(info, info_buf, len+1); 343 344 return info; 345 } 346 347 PJ_DEF(char*) pjsip_tx_data_get_info( pjsip_tx_data *tdata ) 348 { 349 350 PJ_ASSERT_RETURN(tdata && tdata->msg, "INVALID MSG"); 351 352 if (tdata->info) 353 return tdata->info; 354 355 pj_lock_acquire(tdata->lock); 356 tdata->info = get_msg_info(tdata->pool, tdata->obj_name, tdata->msg); 357 pj_lock_release(tdata->lock); 358 359 return tdata->info; 360 } 361 362 PJ_DEF(char*) pjsip_rx_data_get_info(pjsip_rx_data *rdata) 363 { 364 char obj_name[16]; 365 366 PJ_ASSERT_RETURN(rdata->msg_info.msg, "INVALID MSG"); 367 368 if (rdata->msg_info.info) 369 return rdata->msg_info.info; 370 371 pj_native_strcpy(obj_name, "rdata"); 372 pj_sprintf(obj_name+5, "%p", rdata); 373 374 rdata->msg_info.info = get_msg_info(rdata->tp_info.pool, obj_name, 375 rdata->msg_info.msg); 376 return rdata->msg_info.info; 377 } 265 378 266 379 /***************************************************************************** … … 297 410 /* Decrement reference count. */ 298 411 pjsip_tx_data_dec_ref(tdata); 412 } 413 414 /* This function is called by endpoint for on_tx_request() and on_tx_response() 415 * notification. 416 */ 417 static pj_status_t mod_on_tx_msg(pjsip_tx_data *tdata) 418 { 419 /* Allocate buffer if necessary. */ 420 if (tdata->buf.start == NULL) { 421 tdata->buf.start = pj_pool_alloc( tdata->pool, PJSIP_MAX_PKT_LEN); 422 tdata->buf.cur = tdata->buf.start; 423 tdata->buf.end = tdata->buf.start + PJSIP_MAX_PKT_LEN; 424 } 425 426 /* Do we need to reprint? */ 427 if (!pjsip_tx_data_is_valid(tdata)) { 428 pj_ssize_t size; 429 430 size = pjsip_msg_print( tdata->msg, tdata->buf.start, 431 tdata->buf.end - tdata->buf.start); 432 if (size < 0) { 433 return PJSIP_EMSGTOOLONG; 434 } 435 pj_assert(size != 0); 436 tdata->buf.cur += size; 437 tdata->buf.cur[size] = '\0'; 438 } 439 440 return PJ_SUCCESS; 299 441 } 300 442 … … 321 463 } 322 464 323 /* Allocate buffer if necessary. */ 324 if (tdata->buf.start == NULL) { 325 tdata->buf.start = pj_pool_alloc( tdata->pool, PJSIP_MAX_PKT_LEN); 326 tdata->buf.cur = tdata->buf.start; 327 tdata->buf.end = tdata->buf.start + PJSIP_MAX_PKT_LEN; 328 } 329 330 /* Do we need to reprint? */ 331 if (!pjsip_tx_data_is_valid(tdata)) { 332 pj_ssize_t size; 333 334 size = pjsip_msg_print( tdata->msg, tdata->buf.start, 335 tdata->buf.end - tdata->buf.start); 336 if (size < 0) { 337 return PJSIP_EMSGTOOLONG; 338 } 339 pj_assert(size != 0); 340 tdata->buf.cur += size; 341 tdata->buf.cur[size] = '\0'; 465 /* Fill in tp_info. */ 466 tdata->tp_info.transport = tr; 467 pj_memcpy(&tdata->tp_info.dst_addr, addr, addr_len); 468 tdata->tp_info.dst_addr_len = addr_len; 469 if (addr->sa_family == PJ_AF_INET) { 470 const char *str_addr; 471 str_addr = pj_inet_ntoa(((pj_sockaddr_in*)addr)->sin_addr); 472 pj_native_strcpy(tdata->tp_info.dst_name, str_addr); 473 tdata->tp_info.dst_port = pj_ntohs(((pj_sockaddr_in*)addr)->sin_port); 474 } else { 475 pj_native_strcpy(tdata->tp_info.dst_name, "<unknown>"); 476 tdata->tp_info.dst_port = 0; 477 } 478 479 /* Distribute to modules. 480 * When the message reach mod_msg_print, the contents of the message will 481 * be "printed" to contiguous buffer. 482 */ 483 if (tr->tpmgr->on_tx_msg) { 484 status = (*tr->tpmgr->on_tx_msg)(tr->endpt, tdata); 485 if (status != PJ_SUCCESS) 486 return status; 342 487 } 343 488 … … 450 595 } 451 596 452 453 /** 454 * Unregister transport. 455 */ 456 PJ_DEF(pj_status_t) pjsip_transport_unregister( pjsip_tpmgr *mgr, 457 pjsip_transport *tp) 597 /* Force destroy transport (e.g. during transport manager shutdown. */ 598 static pj_status_t destroy_transport( pjsip_tpmgr *mgr, 599 pjsip_transport *tp ) 458 600 { 459 601 int key_len; 460 461 /* Must have no user. */462 PJ_ASSERT_RETURN(pj_atomic_get(tp->ref_cnt) == 0, PJSIP_EBUSY);463 602 464 603 pj_lock_acquire(tp->lock); … … 484 623 /* Destroy. */ 485 624 return tp->destroy(tp); 625 } 626 627 /** 628 * Unregister transport. 629 */ 630 PJ_DEF(pj_status_t) pjsip_transport_unregister( pjsip_tpmgr *mgr, 631 pjsip_transport *tp) 632 { 633 /* Must have no user. */ 634 PJ_ASSERT_RETURN(pj_atomic_get(tp->ref_cnt) == 0, PJSIP_EBUSY); 635 636 /* Destroy. */ 637 return destroy_transport(mgr, tp); 486 638 } 487 639 … … 557 709 PJ_DEF(pj_status_t) pjsip_tpmgr_create( pj_pool_t *pool, 558 710 pjsip_endpoint *endpt, 559 void (*cb)(pjsip_endpoint*, 560 pj_status_t, 561 pjsip_rx_data *), 711 void (*rx_cb)(pjsip_endpoint*, 712 pj_status_t, 713 pjsip_rx_data *), 714 pj_status_t (*tx_cb)(pjsip_endpoint*, 715 pjsip_tx_data*), 562 716 pjsip_tpmgr **p_mgr) 563 717 { … … 565 719 pj_status_t status; 566 720 567 PJ_ASSERT_RETURN(pool && endpt && cb && p_mgr, PJ_EINVAL); 568 569 PJ_LOG(5, (THIS_FILE, "pjsip_tpmgr_create()")); 570 721 PJ_ASSERT_RETURN(pool && endpt && rx_cb && p_mgr, PJ_EINVAL); 722 723 /* Register mod_msg_print module. */ 724 status = pjsip_endpt_register_module(endpt, &mod_msg_print); 725 if (status != PJ_SUCCESS) 726 return status; 727 728 /* Create and initialize transport manager. */ 571 729 mgr = pj_pool_zalloc(pool, sizeof(*mgr)); 572 730 mgr->endpt = endpt; 573 mgr->msg_cb = cb; 731 mgr->on_rx_msg = rx_cb; 732 mgr->on_tx_msg = tx_cb; 574 733 pj_list_init(&mgr->factory_list); 575 734 … … 588 747 #endif 589 748 749 PJ_LOG(5, (THIS_FILE, "Transport manager created.")); 750 590 751 *p_mgr = mgr; 591 752 return PJ_SUCCESS; … … 601 762 pj_hash_iterator_t itr_val; 602 763 pj_hash_iterator_t *itr; 764 pjsip_endpoint *endpt = mgr->endpt; 603 765 604 PJ_LOG(5, (THIS_FILE, "pjsip_tpmgr_destroy()")); 605 606 #if defined(PJ_DEBUG) && PJ_DEBUG!=0 607 pj_assert(pj_atomic_get(mgr->tdata_counter) == 0); 608 #endif 766 PJ_LOG(5, (THIS_FILE, "Destroying transport manager")); 609 767 610 768 pj_lock_acquire(mgr->lock); … … 619 777 next = pj_hash_next(mgr->table, itr); 620 778 621 pj_atomic_set(transport->ref_cnt, 0); 622 pjsip_transport_unregister(mgr, transport); 779 destroy_transport(mgr, transport); 623 780 624 781 itr = next; … … 627 784 pj_lock_release(mgr->lock); 628 785 pj_lock_destroy(mgr->lock); 786 787 /* Unregister mod_msg_print. */ 788 if (mod_msg_print.id != -1) { 789 pjsip_endpt_unregister_module(endpt, &mod_msg_print); 790 } 791 792 #if defined(PJ_DEBUG) && PJ_DEBUG!=0 793 /* If you encounter assert error on this line, it means there are 794 * leakings in transmit data (i.e. some transmit data have not been 795 * destroyed). 796 */ 797 pj_assert(pj_atomic_get(mgr->tdata_counter) == 0); 798 #endif 629 799 630 800 return PJ_SUCCESS; … … 686 856 if (msg_status != PJ_SUCCESS) { 687 857 if (remaining_len == PJSIP_MAX_PKT_LEN) { 688 mgr-> msg_cb(mgr->endpt, PJSIP_ERXOVERFLOW, rdata);858 mgr->on_rx_msg(mgr->endpt, PJSIP_ERXOVERFLOW, rdata); 689 859 /* Exhaust all data. */ 690 860 return rdata->pkt_info.len; … … 703 873 pjsip_parse_rdata( current_pkt, msg_fragment_size, rdata); 704 874 if (msg == NULL) { 705 mgr-> msg_cb(mgr->endpt, PJSIP_EINVALIDMSG, rdata);875 mgr->on_rx_msg(mgr->endpt, PJSIP_EINVALIDMSG, rdata); 706 876 goto finish_process_fragment; 707 877 } … … 714 884 rdata->msg_info.cseq == NULL) 715 885 { 716 mgr-> msg_cb(mgr->endpt, PJSIP_EMISSINGHDR, rdata);886 mgr->on_rx_msg(mgr->endpt, PJSIP_EMISSINGHDR, rdata); 717 887 goto finish_process_fragment; 718 888 } … … 738 908 hdr = pjsip_msg_find_hdr(msg, PJSIP_H_VIA, hdr); 739 909 if (hdr) { 740 mgr-> msg_cb(mgr->endpt, PJSIP_EMULTIPLEVIA, rdata);910 mgr->on_rx_msg(mgr->endpt, PJSIP_EMULTIPLEVIA, rdata); 741 911 goto finish_process_fragment; 742 912 } … … 746 916 /* Call the transport manager's upstream message callback. 747 917 */ 748 mgr-> msg_cb(mgr->endpt, PJ_SUCCESS, rdata);918 mgr->on_rx_msg(mgr->endpt, PJ_SUCCESS, rdata); 749 919 750 920 … … 796 966 const pj_sockaddr *remote_addr = (const pj_sockaddr*)remote; 797 967 798 /* For datagram transports, try lookup with zero address. 799 */ 800 if ( (flag & PJSIP_TRANSPORT_DATAGRAM) && 801 (remote_addr->sa_family == PJ_AF_INET)) 968 /* Ignore address for loop transports. */ 969 if (type == PJSIP_TRANSPORT_LOOP || 970 type == PJSIP_TRANSPORT_LOOP_DGRAM) 802 971 { 803 972 pj_sockaddr_in *addr = (pj_sockaddr_in*)&key.addr; 804 973 805 974 pj_memset(addr, 0, sizeof(pj_sockaddr_in)); 975 key_len = sizeof(key.type) + sizeof(pj_sockaddr_in); 976 transport = pj_hash_get(mgr->table, &key, key_len); 977 } 978 /* For datagram INET transports, try lookup with zero address. 979 */ 980 else if ((flag & PJSIP_TRANSPORT_DATAGRAM) && 981 (remote_addr->sa_family == PJ_AF_INET)) 982 { 983 pj_sockaddr_in *addr = (pj_sockaddr_in*)&key.addr; 984 985 pj_memset(addr, 0, sizeof(pj_sockaddr_in)); 806 986 addr->sin_family = PJ_AF_INET; 807 addr->sin_addr.s_addr = 0;808 addr->sin_port = 0;809 987 810 988 key_len = sizeof(key.type) + sizeof(pj_sockaddr_in);
Note: See TracChangeset
for help on using the changeset viewer.