Changeset 106 for pjproject/trunk/pjsip/src/pjsip/sip_endpoint.c
- Timestamp:
- Dec 30, 2005 11:50:15 PM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/src/pjsip/sip_endpoint.c
r105 r106 57 57 pj_str_t name; 58 58 59 /** Transaction table. */60 pj_hash_table_t *tsx_table;61 62 /** Mutex for transaction table. */63 pj_mutex_t *tsx_table_mutex;64 65 59 /** Timer heap. */ 66 60 pj_timer_heap_t *timer_heap; … … 75 69 pjsip_resolver_t *resolver; 76 70 77 /** Number of modules registered. */78 pj_ uint32_t mod_count;71 /** Modules lock. */ 72 pj_rwmutex_t *mod_mutex; 79 73 80 74 /** Modules. */ 81 75 pjsip_module *modules[PJSIP_MAX_MODULE]; 76 77 /** Module list, sorted by priority. */ 78 pjsip_module module_list; 82 79 83 80 /** Number of supported methods. */ … … 128 125 129 126 /* 130 * Initialize modules. 131 */ 132 static pj_status_t init_modules( pjsip_endpoint *endpt ) 127 * Register new module to the endpoint. 128 * The endpoint will then call the load and start function in the module to 129 * properly initialize the module, and assign a unique module ID for the 130 * module. 131 */ 132 PJ_DEF(pj_status_t) pjsip_endpt_register_module( pjsip_endpoint *endpt, 133 pjsip_module *mod ) 134 { 135 pj_status_t status = PJ_SUCCESS; 136 pjsip_module *m; 137 int i; 138 139 pj_rwmutex_lock_write(endpt->mod_mutex); 140 141 /* Make sure that this module has not been registered. */ 142 PJ_ASSERT_ON_FAIL( pj_list_find_node(&endpt->module_list, mod) == NULL, 143 {status = PJ_EEXISTS; goto on_return;}); 144 145 /* Find unused ID for this module. */ 146 for (i=0; i<PJ_ARRAY_SIZE(endpt->modules); ++i) { 147 if (endpt->modules[i] == NULL) 148 break; 149 } 150 if (i == PJ_ARRAY_SIZE(endpt->modules)) { 151 pj_assert(!"Too many modules registered!"); 152 status = PJ_ETOOMANY; 153 goto on_return; 154 } 155 156 /* Assign the ID. */ 157 mod->id = i; 158 159 /* Try to load the module. */ 160 if (mod->load) { 161 status = (*mod->load)(endpt); 162 if (status != PJ_SUCCESS) 163 goto on_return; 164 } 165 166 /* Try to start the module. */ 167 if (mod->start) { 168 status = (*mod->start)(); 169 if (status != PJ_SUCCESS) 170 goto on_return; 171 } 172 173 /* Save the module. */ 174 endpt->modules[i] = mod; 175 176 /* Put in the module list, sorted by priority. */ 177 m = endpt->module_list.next; 178 while (m != &endpt->module_list) { 179 if (m->priority > mod->priority) 180 break; 181 m = m->next; 182 } 183 pj_list_insert_before(m, mod); 184 185 /* Done. */ 186 PJ_TODO(BUILD_ALLOW_HEADER_BASED_ON_MODULES_SUPPORTED_METHODS); 187 188 on_return: 189 pj_rwmutex_unlock_write(endpt->mod_mutex); 190 return status; 191 } 192 193 /* 194 * Unregister a module from the endpoint. 195 * The endpoint will then call the stop and unload function in the module to 196 * properly shutdown the module. 197 */ 198 PJ_DEF(pj_status_t) pjsip_endpt_unregister_module( pjsip_endpoint *endpt, 199 pjsip_module *mod ) 133 200 { 134 201 pj_status_t status; 135 unsigned i; 136 //pj_str_t str_COMMA = { ", ", 2 }; 137 extern pjsip_module aux_tsx_module; 138 139 PJ_LOG(5, (THIS_FILE, "init_modules()")); 140 141 /* Load static modules. */ 142 endpt->mod_count = PJSIP_MAX_MODULE; 143 status = register_static_modules( &endpt->mod_count, endpt->modules ); 144 if (status != 0) { 145 return status; 146 } 147 148 /* Add mini aux module. */ 149 endpt->modules[endpt->mod_count++] = &aux_tsx_module; 150 151 /* Load dynamic modules. */ 152 // Not supported yet! 153 154 /* Sort modules on the priority. */ 155 for (i=endpt->mod_count-1; i>0; --i) { 156 pj_uint32_t max = 0; 157 unsigned j; 158 for (j=1; j<=i; ++j) { 159 if (endpt->modules[j]->priority > endpt->modules[max]->priority) 160 max = j; 161 } 162 if (max != i) { 163 pjsip_module *temp = endpt->modules[max]; 164 endpt->modules[max] = endpt->modules[i]; 165 endpt->modules[i] = temp; 166 } 167 } 168 169 /* Initialize each module. */ 170 for (i=0; i < endpt->mod_count; ++i) { 171 int j; 172 173 pjsip_module *mod = endpt->modules[i]; 174 if (mod->init_module) { 175 status = mod->init_module(endpt, mod, i); 176 if (status != 0) { 177 return status; 178 } 179 } 180 181 /* Collect all supported methods from modules. */ 182 for (j=0; j<mod->method_cnt; ++j) { 183 unsigned k; 184 for (k=0; k<endpt->method_cnt; ++k) { 185 if (pjsip_method_cmp(mod->methods[j], endpt->methods[k]) == 0) 186 break; 187 } 188 if (k == endpt->method_cnt) { 189 if (endpt->method_cnt < MAX_METHODS) { 190 endpt->methods[endpt->method_cnt++] = mod->methods[j]; 191 } else { 192 PJ_LOG(1,(THIS_FILE, "Too many methods")); 193 return -1; 194 } 195 } 196 } 197 } 198 199 /* Create Allow header. */ 200 endpt->allow_hdr = pjsip_allow_hdr_create( endpt->pool ); 201 endpt->allow_hdr->count = endpt->method_cnt; 202 for (i=0; i<endpt->method_cnt; ++i) { 203 endpt->allow_hdr->values[i] = endpt->methods[i]->name; 204 } 205 206 /* Start each module. */ 207 for (i=0; i < endpt->mod_count; ++i) { 208 pjsip_module *mod = endpt->modules[i]; 209 if (mod->start_module) { 210 status = mod->start_module(mod); 211 if (status != 0) { 212 return status; 213 } 214 } 215 } 202 203 pj_rwmutex_lock_write(endpt->mod_mutex); 204 205 /* Make sure the module exists in the list. */ 206 PJ_ASSERT_ON_FAIL( pj_list_find_node(&endpt->module_list, mod) == mod, 207 {status = PJ_ENOTFOUND;goto on_return;} ); 208 209 /* Make sure the module exists in the array. */ 210 PJ_ASSERT_ON_FAIL( mod->id>=0 && mod->id<PJ_ARRAY_SIZE(endpt->modules) && 211 endpt->modules[mod->id] == mod, 212 {status = PJ_ENOTFOUND; goto on_return;}); 213 214 /* Try to stop the module. */ 215 if (mod->stop) { 216 status = (*mod->stop)(); 217 if (status != PJ_SUCCESS) goto on_return; 218 } 219 220 /* Try to unload the module. */ 221 if (mod->unload) { 222 status = (*mod->unload)(); 223 if (status != PJ_SUCCESS) goto on_return; 224 } 225 226 /* Remove module from array. */ 227 endpt->modules[mod->id] = NULL; 228 229 /* Remove module from list. */ 230 pj_list_erase(mod); 216 231 217 232 /* Done. */ 218 return 0; 219 } 220 221 /* 222 * Unregister the transaction from the hash table, and destroy the resources 223 * from the transaction. 224 */ 225 PJ_DEF(void) pjsip_endpt_destroy_tsx( pjsip_endpoint *endpt, 226 pjsip_transaction *tsx) 227 { 228 PJ_LOG(5, (THIS_FILE, "pjsip_endpt_destroy_tsx(%s)", tsx->obj_name)); 229 230 pj_assert(tsx->state == PJSIP_TSX_STATE_DESTROYED); 231 232 /* No need to lock transaction. 233 * This function typically is called from the transaction callback, which 234 * means that transaction mutex is being held. 235 */ 236 pj_assert( pj_mutex_is_locked(tsx->mutex) ); 237 238 /* Lock endpoint. */ 239 pj_mutex_lock( endpt->tsx_table_mutex ); 240 241 /* Unregister from the hash table. */ 242 pj_hash_set( NULL, endpt->tsx_table, tsx->transaction_key.ptr, 243 tsx->transaction_key.slen, NULL); 244 245 /* Unlock endpoint mutex. */ 246 pj_mutex_unlock( endpt->tsx_table_mutex ); 247 248 /* Destroy transaction mutex. */ 249 pj_mutex_destroy( tsx->mutex ); 250 251 /* Release the pool for the transaction. */ 252 pj_pool_release(tsx->pool); 253 254 PJ_LOG(4, (THIS_FILE, "tsx%p destroyed", tsx)); 255 } 256 257 258 /* 259 * Receive transaction events from transactions and dispatch them to the 260 * modules. 261 */ 262 static void endpt_do_event( pjsip_endpoint *endpt, pjsip_event *evt) 263 { 264 unsigned i; 265 266 /* Dispatch event to modules. */ 267 for (i=0; i<endpt->mod_count; ++i) { 268 pjsip_module *mod = endpt->modules[i]; 269 if (mod && mod->tsx_handler) { 270 mod->tsx_handler( mod, evt ); 271 } 272 } 273 274 /* Destroy transaction if it is terminated. */ 275 if (evt->type == PJSIP_EVENT_TSX_STATE && 276 evt->body.tsx_state.tsx->state == PJSIP_TSX_STATE_DESTROYED) 277 { 278 /* No need to lock mutex. Mutex is locked inside the destroy function */ 279 pjsip_endpt_destroy_tsx( endpt, evt->body.tsx_state.tsx ); 280 } 281 } 282 283 /* 284 * Receive transaction events from transactions and put in the event queue 285 * to be processed later. 286 */ 287 void pjsip_endpt_send_tsx_event( pjsip_endpoint *endpt, pjsip_event *evt ) 288 { 289 // Need to protect this with try/catch? 290 endpt_do_event(endpt, evt); 233 status = PJ_SUCCESS; 234 235 PJ_TODO(REMOVE_METHODS_FROM_ALLOW_HEADER_WHEN_MODULE_IS_UNREGISTERED); 236 237 on_return: 238 pj_rwmutex_unlock_write(endpt->mod_mutex); 239 return status; 291 240 } 292 241 … … 376 325 377 326 /* Create endpoint. */ 378 endpt = pj_pool_ calloc(pool, 1, sizeof(*endpt));327 endpt = pj_pool_zalloc(pool, sizeof(*endpt)); 379 328 endpt->pool = pool; 380 329 endpt->pf = pf; 330 331 /* Init modules list. */ 332 pj_list_init(&endpt->module_list); 333 334 /* Create R/W mutex for module manipulation. */ 335 status = pj_rwmutex_create(endpt->pool, "ept%p", &endpt->mod_mutex); 336 if (status != PJ_SUCCESS) 337 goto on_error; 381 338 382 339 /* Init parser. */ … … 400 357 } 401 358 402 /* Create mutex for the transaction table. */403 status = pj_mutex_create_recursive( endpt->pool, "mtbl%p",404 &endpt->tsx_table_mutex);405 if (status != PJ_SUCCESS) {406 goto on_error;407 }408 409 /* Create hash table for transaction. */410 endpt->tsx_table = pj_hash_create( endpt->pool, PJSIP_MAX_TSX_COUNT );411 if (!endpt->tsx_table) {412 status = PJ_ENOMEM;413 goto on_error;414 }415 416 359 /* Create timer heap to manage all timers within this endpoint. */ 417 360 status = pj_timer_heap_create( endpt->pool, PJSIP_MAX_TIMER_COUNT, … … 453 396 } 454 397 455 /* Initialize TLS ID for transaction lock. */456 status = pj_thread_local_alloc(&pjsip_tsx_lock_tls_id);457 if (status != PJ_SUCCESS) {458 goto on_error;459 }460 pj_thread_local_set(pjsip_tsx_lock_tls_id, NULL);461 462 398 /* Initialize request headers. */ 463 399 pj_list_init(&endpt->req_hdr); … … 471 407 pj_list_insert_before( &endpt->req_hdr, mf_hdr); 472 408 473 /* Load and init modules. */474 status = init_modules(endpt);475 if (status != PJ_SUCCESS) {476 PJ_LOG(4, (THIS_FILE, "pjsip_endpt_init(): error in init_modules()"));477 return status;478 }479 480 409 /* Done. */ 481 410 *p_endpt = endpt; … … 491 420 endpt->mutex = NULL; 492 421 } 493 if (endpt-> tsx_table_mutex) {494 pj_ mutex_destroy(endpt->tsx_table_mutex);495 endpt-> tsx_table_mutex = NULL;422 if (endpt->mod_mutex) { 423 pj_rwmutex_destroy(endpt->mod_mutex); 424 endpt->mod_mutex = NULL; 496 425 } 497 426 pj_pool_release( endpt->pool ); … … 513 442 /* Delete endpoint mutex. */ 514 443 pj_mutex_destroy(endpt->mutex); 515 516 /* Delete transaction table mutex. */517 pj_mutex_destroy(endpt->tsx_table_mutex);518 444 519 445 /* Finally destroy pool. */ … … 625 551 626 552 /* 627 * Create a new transaction.628 * Endpoint must then initialize the new transaction as either UAS or UAC, and629 * register it to the hash table.630 */631 PJ_DEF(pj_status_t) pjsip_endpt_create_tsx(pjsip_endpoint *endpt,632 pjsip_transaction **p_tsx)633 {634 pj_pool_t *pool;635 636 PJ_ASSERT_RETURN(endpt && p_tsx, PJ_EINVAL);637 638 PJ_LOG(5, (THIS_FILE, "pjsip_endpt_create_tsx()"));639 640 /* Request one pool for the transaction. Mutex is locked there. */641 pool = pjsip_endpt_create_pool(endpt, "ptsx%p",642 PJSIP_POOL_LEN_TSX, PJSIP_POOL_INC_TSX);643 if (pool == NULL) {644 return PJ_ENOMEM;645 }646 647 /* Create the transaction. */648 return pjsip_tsx_create(pool, endpt, p_tsx);649 }650 651 /*652 * Register the transaction to the endpoint.653 * This will put the transaction to the transaction hash table. Before calling654 * this function, the transaction must be INITIALIZED as either UAS or UAC, so655 * that the transaction key is built.656 */657 PJ_DEF(void) pjsip_endpt_register_tsx( pjsip_endpoint *endpt,658 pjsip_transaction *tsx)659 {660 PJ_LOG(5, (THIS_FILE, "pjsip_endpt_register_tsx(%s)", tsx->obj_name));661 662 pj_assert(tsx->transaction_key.slen != 0);663 //pj_assert(tsx->state != PJSIP_TSX_STATE_NULL);664 665 /* Lock hash table mutex. */666 pj_mutex_lock(endpt->tsx_table_mutex);667 668 /* Register the transaction to the hash table. */669 pj_hash_set( tsx->pool, endpt->tsx_table, tsx->transaction_key.ptr,670 tsx->transaction_key.slen, tsx);671 672 /* Unlock mutex. */673 pj_mutex_unlock(endpt->tsx_table_mutex);674 }675 676 /*677 * Find transaction by the key.678 */679 PJ_DEF(pjsip_transaction*) pjsip_endpt_find_tsx( pjsip_endpoint *endpt,680 const pj_str_t *key )681 {682 pjsip_transaction *tsx;683 684 PJ_LOG(5, (THIS_FILE, "pjsip_endpt_find_tsx()"));685 686 /* Start lock mutex in the endpoint. */687 pj_mutex_lock(endpt->tsx_table_mutex);688 689 /* Find the transaction in the hash table. */690 tsx = pj_hash_get( endpt->tsx_table, key->ptr, key->slen );691 692 /* Unlock mutex. */693 pj_mutex_unlock(endpt->tsx_table_mutex);694 695 return tsx;696 }697 698 /*699 * Create key.700 */701 static void rdata_create_key( pjsip_rx_data *rdata)702 {703 pjsip_role_e role;704 if (rdata->msg_info.msg->type == PJSIP_REQUEST_MSG) {705 role = PJSIP_ROLE_UAS;706 } else {707 role = PJSIP_ROLE_UAC;708 }709 pjsip_tsx_create_key(rdata->tp_info.pool, &rdata->endpt_info.key, role,710 &rdata->msg_info.cseq->method, rdata);711 }712 713 /*714 553 * This is the callback that is called by the transport manager when it 715 554 * receives a message from the network. … … 720 559 { 721 560 pjsip_msg *msg = rdata->msg_info.msg; 722 pjsip_transaction *tsx;723 pj_bool_t a_new_transaction_just_been_created = PJ_FALSE;724 561 725 562 PJ_LOG(5, (THIS_FILE, "endpt_transport_callback(rdata=%p)", rdata)); 726 563 727 564 if (status != PJ_SUCCESS) { 728 const char *src_addr = rdata->pkt_info.src_name;729 int port = rdata->pkt_info.src_port;730 565 PJSIP_ENDPT_LOG_ERROR((endpt, "transport", status, 731 " Src.addr=%s:%d, packet:--\n"566 "Error processing packet from %s:%d, packet:--\n" 732 567 "%s\n" 733 "-- end of packet. Error", 734 src_addr, port, rdata->msg_info.msg_buf)); 568 "-- end of packet.", 569 rdata->pkt_info.src_name, 570 rdata->pkt_info.src_port, 571 rdata->msg_info.msg_buf)); 735 572 return; 736 573 } … … 741 578 */ 742 579 if (msg->type == PJSIP_RESPONSE_MSG) { 743 const pj_str_t * addr_addr;580 const pj_str_t *local_addr; 744 581 int port = rdata->msg_info.via->sent_by.port; 745 582 pj_bool_t mismatch = PJ_FALSE; … … 749 586 port = pjsip_transport_get_default_port_for_type(type); 750 587 } 751 addr_addr = &rdata->tp_info.transport->local_name.host;752 if (pj_strcmp(&rdata->msg_info.via->sent_by.host, addr_addr) != 0)588 local_addr = &rdata->tp_info.transport->local_name.host; 589 if (pj_strcmp(&rdata->msg_info.via->sent_by.host, local_addr) != 0) 753 590 mismatch = PJ_TRUE; 754 591 else if (port != rdata->tp_info.transport->local_name.port) { … … 760 597 * both the port in sent-by and rport. We try to be lenient here! 761 598 */ 762 if (rdata->msg_info.via->rport_param != rdata->tp_info.transport->local_name.port) 599 if (rdata->msg_info.via->rport_param != 600 rdata->tp_info.transport->local_name.port) 763 601 mismatch = PJ_TRUE; 764 602 else { 765 PJ_LOG(4,(THIS_FILE, "Response %p has mismatch port in sent-by" 766 " but the rport parameter is correct", 767 rdata)); 603 PJ_LOG(4,(THIS_FILE, "Response %p from %s has mismatch port in " 604 "sent-by but the rport parameter is " 605 "correct", 606 rdata, rdata->pkt_info.src_name)); 768 607 } 769 608 } 770 609 771 610 if (mismatch) { 772 pjsip_event e; 773 774 PJSIP_EVENT_INIT_DISCARD_MSG(e, rdata, PJSIP_EINVALIDVIA); 775 endpt_do_event( endpt, &e ); 611 PJ_TODO(ENDPT_REPORT_WHEN_DROPPING_MESSAGE); 612 PJ_LOG(4,(THIS_FILE, "Dropping response from %s:%d because sent-by" 613 " is mismatch", 614 rdata->pkt_info.src_name, 615 rdata->pkt_info.src_port)); 776 616 return; 777 617 } 778 } 779 780 /* Create key for transaction lookup. */ 781 rdata_create_key( rdata); 782 783 /* Find the transaction for the received message. */ 784 PJ_LOG(5, (THIS_FILE, "finding tsx with key=%.*s", 785 rdata->endpt_info.key.slen, rdata->endpt_info.key.ptr)); 786 787 /* Start lock mutex in the endpoint. */ 788 pj_mutex_lock(endpt->tsx_table_mutex); 789 790 /* Find the transaction in the hash table. */ 791 tsx = pj_hash_get( endpt->tsx_table, rdata->endpt_info.key.ptr, rdata->endpt_info.key.slen ); 792 793 /* Unlock mutex. */ 794 pj_mutex_unlock(endpt->tsx_table_mutex); 795 796 /* If the transaction is not found... */ 797 if (tsx == NULL || tsx->state == PJSIP_TSX_STATE_TERMINATED) { 798 799 /* 800 * For response message, discard the message, except if the response is 801 * an 2xx class response to INVITE, which in this case it must be 802 * passed to TU to be acked. 803 */ 804 if (msg->type == PJSIP_RESPONSE_MSG) { 805 806 /* Inform TU about the 200 message, only if it's INVITE. */ 807 if (PJSIP_IS_STATUS_IN_CLASS(msg->line.status.code, 200) && 808 rdata->msg_info.cseq->method.id == PJSIP_INVITE_METHOD) 809 { 810 pjsip_event e; 811 812 /* Should not happen for UA. Tsx theoritically lives until 813 * all responses are absorbed. 814 */ 815 pj_assert(0); 816 817 PJSIP_EVENT_INIT_RX_200_MSG(e, rdata); 818 endpt_do_event( endpt, &e ); 819 820 } else { 821 /* Just discard the response, inform TU. */ 822 pjsip_event e; 823 824 PJSIP_EVENT_INIT_DISCARD_MSG(e, rdata, 825 PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_CALL_TSX_DOES_NOT_EXIST)); 826 endpt_do_event( endpt, &e ); 827 } 828 829 /* 830 * For non-ACK request message, create a new transaction. 831 */ 832 } else if (rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD) { 833 834 pj_status_t status; 835 836 /* Create transaction, mutex is locked there. */ 837 status = pjsip_endpt_create_tsx(endpt, &tsx); 838 if (status != PJ_SUCCESS) { 839 PJSIP_ENDPT_LOG_ERROR((endpt, THIS_FILE, status, 840 "Unable to create transaction")); 841 return; 842 } 843 844 /* Initialize transaction as UAS. */ 845 pjsip_tsx_init_uas( tsx, rdata ); 846 847 /* Register transaction, mutex is locked there. */ 848 pjsip_endpt_register_tsx( endpt, tsx ); 849 850 a_new_transaction_just_been_created = PJ_TRUE; 618 } 619 620 621 /* Distribute to modules. */ 622 pj_rwmutex_lock_read(endpt->mod_mutex); 623 624 if (msg->type == PJSIP_REQUEST_MSG) { 625 pjsip_module *mod; 626 pj_bool_t handled = PJ_FALSE; 627 628 mod = endpt->module_list.next; 629 while (mod != &endpt->module_list) { 630 if (mod->on_rx_request) 631 handled = (*mod->on_rx_request)(rdata); 632 if (handled) 633 break; 634 mod = mod->next; 851 635 } 852 } 853 854 /* If transaction is found (or newly created), pass the message. 855 * Otherwise if it's an ACK request, pass directly to TU. 856 */ 857 if (tsx && tsx->state != PJSIP_TSX_STATE_TERMINATED) { 858 /* Dispatch message to transaction. */ 859 pjsip_tsx_on_rx_msg( tsx, rdata ); 860 861 } else if (rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD) { 862 /* 863 * This is an ACK message, but the INVITE transaction could not 864 * be found (possibly because the branch parameter in Via in ACK msg 865 * is different than the branch in original INVITE). This happens with 866 * SER! 867 */ 868 pjsip_event event; 869 870 PJSIP_EVENT_INIT_RX_ACK_MSG(event,rdata); 871 endpt_do_event( endpt, &event ); 872 } 873 874 /* 875 * If a new request message has just been receieved, but no modules 876 * seem to be able to handle the request message, then terminate the 877 * transaction. 878 * 879 * Ideally for cases like "unsupported method", we should be able to 880 * answer the request statelessly. But we can not do that since the 881 * endpoint shoule be able to be used as both user agent and proxy stack, 882 * and a proxy stack should be able to handle arbitrary methods. 883 */ 884 if (a_new_transaction_just_been_created && tsx->status_code < 100) { 885 /* Certainly no modules has sent any response message. 886 * Check that any modules has attached a module data. 887 */ 888 int i; 889 for (i=0; i<PJSIP_MAX_MODULE; ++i) { 890 if (tsx->module_data[i] != NULL) { 636 637 /* No module is able to handle the request. */ 638 if (!handled) { 639 PJ_TODO(ENDPT_RESPOND_UNHANDLED_REQUEST); 640 PJ_LOG(4,(THIS_FILE, "Request from %s:%d was dropped/unhandled by" 641 " any modules")); 642 } 643 644 } else { 645 pjsip_module *mod; 646 pj_bool_t handled = PJ_FALSE; 647 648 mod = endpt->module_list.next; 649 while (mod != &endpt->module_list) { 650 if (mod->on_rx_response) 651 handled = (*mod->on_rx_response)(rdata); 652 if (handled) 891 653 break; 892 }654 mod = mod->next; 893 655 } 894 if (i == PJSIP_MAX_MODULE) { 895 /* No modules have attached itself to the transaction. 896 * Terminate the transaction with 501/Not Implemented. 897 */ 898 pjsip_tx_data *tdata; 899 pj_status_t status; 900 901 if (tsx->method.id == PJSIP_OPTIONS_METHOD) { 902 status = pjsip_endpt_create_response(endpt, rdata, 200, 903 &tdata); 904 } else { 905 status = pjsip_endpt_create_response(endpt, rdata, 906 PJSIP_SC_METHOD_NOT_ALLOWED, 907 &tdata); 908 } 909 910 if (status != PJ_SUCCESS) { 911 PJSIP_ENDPT_LOG_ERROR((endpt, THIS_FILE, status, 912 "Unable to create response")); 913 return; 914 } 915 916 if (endpt->allow_hdr) { 917 pjsip_msg_add_hdr( tdata->msg, 918 pjsip_hdr_shallow_clone(tdata->pool, endpt->allow_hdr)); 919 } 920 pjsip_tsx_on_tx_msg( tsx, tdata ); 921 922 } else { 923 /* 924 * If a module has registered itself in the transaction but it 925 * hasn't responded the request, chances are the module wouldn't 926 * respond to the request at all. We terminate the request here 927 * with 500/Internal Server Error, to be safe. 928 */ 929 pjsip_tx_data *tdata; 930 pj_status_t status; 931 932 status = pjsip_endpt_create_response(endpt, rdata, 500, &tdata); 933 if (status != PJ_SUCCESS) { 934 PJSIP_ENDPT_LOG_ERROR((endpt, THIS_FILE, status, 935 "Unable to create response")); 936 return; 937 } 938 939 pjsip_tsx_on_tx_msg(tsx, tdata); 656 657 if (!handled) { 658 PJ_LOG(4,(THIS_FILE, "Response from %s:%d was dropped/unhandled by" 659 " any modules")); 940 660 } 941 661 } 662 663 pj_rwmutex_unlock_read(endpt->mod_mutex); 942 664 } 943 665 … … 984 706 * Find/create transport. 985 707 */ 986 PJ_DEF(pj_status_t) pjsip_endpt_a lloc_transport(pjsip_endpoint *endpt,708 PJ_DEF(pj_status_t) pjsip_endpt_acquire_transport(pjsip_endpoint *endpt, 987 709 pjsip_transport_type_e type, 988 const pj_sockaddr *remote,710 const pj_sockaddr_t *remote, 989 711 int addr_len, 990 pjsip_transport ** p_transport)991 { 992 PJ_LOG(5, (THIS_FILE, "pjsip_endpt_a lloc_transport()"));993 return pjsip_tpmgr_a lloc_transport(endpt->transport_mgr, type,994 remote, addr_len, p_transport);712 pjsip_transport **transport) 713 { 714 PJ_LOG(5, (THIS_FILE, "pjsip_endpt_acquire_transport()")); 715 return pjsip_tpmgr_acquire_transport(endpt->transport_mgr, type, 716 remote, addr_len, transport); 995 717 } 996 718 … … 1050 772 { 1051 773 #if PJ_LOG_MAX_LEVEL >= 3 1052 unsigned count;1053 1054 774 PJ_LOG(5, (THIS_FILE, "pjsip_endpt_dump()")); 1055 775 … … 1066 786 pj_pool_get_capacity(endpt->pool), 1067 787 pj_pool_get_used_size(endpt->pool))); 1068 1069 /* Transaction tables. */1070 count = pj_hash_count(endpt->tsx_table);1071 PJ_LOG(3, (THIS_FILE, " Number of transactions: %u", count));1072 1073 if (count && detail) {1074 pj_hash_iterator_t it_val;1075 pj_hash_iterator_t *it;1076 pj_time_val now;1077 1078 PJ_LOG(3, (THIS_FILE, " Dumping transaction tables:"));1079 1080 pj_gettimeofday(&now);1081 it = pj_hash_first(endpt->tsx_table, &it_val);1082 1083 while (it != NULL) {1084 int timeout_diff;1085 1086 /* Get the transaction. No need to lock transaction's mutex1087 * since we already hold endpoint mutex, so that no transactions1088 * will be deleted.1089 */1090 pjsip_transaction *tsx = pj_hash_this(endpt->tsx_table, it);1091 1092 const char *role = (tsx->role == PJSIP_ROLE_UAS ? "UAS" : "UAC");1093 1094 if (tsx->timeout_timer._timer_id != -1) {1095 if (tsx->timeout_timer._timer_value.sec > now.sec) {1096 timeout_diff = tsx->timeout_timer._timer_value.sec - now.sec;1097 } else {1098 timeout_diff = now.sec - tsx->timeout_timer._timer_value.sec;1099 timeout_diff = 0 - timeout_diff;1100 }1101 } else {1102 timeout_diff = -1;1103 }1104 1105 PJ_LOG(3, (THIS_FILE, " %s %s %10.*s %.9u %s t=%ds",1106 tsx->obj_name, role,1107 tsx->method.name.slen, tsx->method.name.ptr,1108 tsx->cseq,1109 pjsip_tsx_state_str(tsx->state),1110 timeout_diff));1111 1112 it = pj_hash_next(endpt->tsx_table, it);1113 }1114 }1115 788 1116 789 /* Transports.
Note: See TracChangeset
for help on using the changeset viewer.