Changeset 1021 for pjproject/trunk/pjlib-util/src/pjlib-util/stun_session.c
- Timestamp:
- Mar 1, 2007 12:08:27 AM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjlib-util/src/pjlib-util/stun_session.c
r1008 r1021 24 24 pj_stun_endpoint *endpt; 25 25 pj_pool_t *pool; 26 pj_mutex_t *mutex; 26 27 pj_stun_session_cb cb; 27 28 void *user_data; … … 48 49 49 50 #if PJ_LOG_MAX_LEVEL >= 4 50 # define LOG_ERR_(sess, title, rc) 51 # define LOG_ERR_(sess, title, rc) stun_perror(sess, title, rc) 51 52 static void stun_perror(pj_stun_session *sess, const char *title, 52 53 pj_status_t status) … … 60 61 61 62 #else 62 # define ERR_(sess, title, rc)63 # define LOG_ERR_(sess, title, rc) 63 64 #endif 64 65 … … 116 117 117 118 static pj_status_t create_tdata(pj_stun_session *sess, 118 unsigned msg_type,119 119 void *user_data, 120 120 pj_stun_tx_data **p_tdata) 121 121 { 122 122 pj_pool_t *pool; 123 pj_status_t status;124 123 pj_stun_tx_data *tdata; 125 124 … … 134 133 tdata->user_data = user_data; 135 134 135 *p_tdata = tdata; 136 137 return PJ_SUCCESS; 138 } 139 140 static pj_status_t create_request_tdata(pj_stun_session *sess, 141 unsigned msg_type, 142 void *user_data, 143 pj_stun_tx_data **p_tdata) 144 { 145 pj_status_t status; 146 pj_stun_tx_data *tdata; 147 148 status = create_tdata(sess, user_data, &tdata); 149 if (status != PJ_SUCCESS) 150 return status; 151 136 152 /* Create STUN message */ 137 status = pj_stun_msg_create( pool, msg_type, PJ_STUN_MAGIC,153 status = pj_stun_msg_create(tdata->pool, msg_type, PJ_STUN_MAGIC, 138 154 NULL, &tdata->msg); 139 155 if (status != PJ_SUCCESS) { 140 pj_pool_release(pool); 141 return status; 142 } 143 144 /* If this is a request, then copy the request's transaction ID 145 * as the transaction key. 146 */ 147 if (PJ_STUN_IS_REQUEST(msg_type)) { 148 pj_assert(sizeof(tdata->client_key)==sizeof(tdata->msg->hdr.tsx_id)); 149 pj_memcpy(tdata->client_key, tdata->msg->hdr.tsx_id, 150 sizeof(tdata->msg->hdr.tsx_id)); 151 } 156 pj_pool_release(tdata->pool); 157 return status; 158 } 159 160 /* copy the request's transaction ID as the transaction key. */ 161 pj_assert(sizeof(tdata->client_key)==sizeof(tdata->msg->hdr.tsx_id)); 162 pj_memcpy(tdata->client_key, tdata->msg->hdr.tsx_id, 163 sizeof(tdata->msg->hdr.tsx_id)); 152 164 153 165 *p_tdata = tdata; … … 167 179 } 168 180 169 static pj_status_t session_apply_req(pj_stun_session *sess, 181 /* 182 * Destroy the transmit data. 183 */ 184 PJ_DEF(void) pj_stun_msg_destroy_tdata( pj_stun_session *sess, 185 pj_stun_tx_data *tdata) 186 { 187 PJ_UNUSED_ARG(sess); 188 destroy_tdata(tdata); 189 } 190 191 static pj_status_t apply_msg_options(pj_stun_session *sess, 170 192 pj_pool_t *pool, 171 193 unsigned options, 172 pj_stun_msg *msg) 194 pj_stun_msg *msg, 195 pj_str_t **p_passwd) 173 196 { 174 197 pj_status_t status; … … 182 205 pj_stun_generic_string_attr *arealm; 183 206 207 *p_passwd = &sess->l_password; 208 184 209 /* Create and add USERNAME attribute */ 185 status = pj_stun_generic_string_attr_create( sess->pool,210 status = pj_stun_generic_string_attr_create(pool, 186 211 PJ_STUN_ATTR_USERNAME, 187 212 &sess->l_username, … … 193 218 194 219 /* Add REALM only when long term credential is used */ 195 status = pj_stun_generic_string_attr_create( sess->pool,220 status = pj_stun_generic_string_attr_create(pool, 196 221 PJ_STUN_ATTR_REALM, 197 222 &sess->l_realm, … … 203 228 204 229 /* Add MESSAGE-INTEGRITY attribute */ 205 status = pj_stun_msg_integrity_attr_create( sess->pool, &amsgi);230 status = pj_stun_msg_integrity_attr_create(pool, &amsgi); 206 231 PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 207 232 208 233 status = pj_stun_msg_add_attr(msg, &amsgi->hdr); 209 234 PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 210 211 PJ_TODO(COMPUTE_MESSAGE_INTEGRITY1);212 235 213 236 } else if (options & PJ_STUN_USE_SHORT_TERM_CRED) { … … 215 238 pj_stun_msg_integrity_attr *amsgi; 216 239 240 *p_passwd = &sess->s_password; 241 217 242 /* Create and add USERNAME attribute */ 218 status = pj_stun_generic_string_attr_create( sess->pool,243 status = pj_stun_generic_string_attr_create(pool, 219 244 PJ_STUN_ATTR_USERNAME, 220 245 &sess->s_username, … … 226 251 227 252 /* Add MESSAGE-INTEGRITY attribute */ 228 status = pj_stun_msg_integrity_attr_create( sess->pool, &amsgi);253 status = pj_stun_msg_integrity_attr_create(pool, &amsgi); 229 254 PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 230 255 … … 232 257 PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 233 258 234 PJ_TODO(COMPUTE_MESSAGE_INTEGRITY2); 259 } else { 260 *p_passwd = NULL; 235 261 } 236 262 … … 239 265 pj_stun_fingerprint_attr *af; 240 266 241 status = pj_stun_generic_uint_attr_create( sess->pool,267 status = pj_stun_generic_uint_attr_create(pool, 242 268 PJ_STUN_ATTR_FINGERPRINT, 243 269 0, &af); … … 260 286 tdata = (pj_stun_tx_data*) pj_stun_client_tsx_get_data(tsx); 261 287 262 switch (PJ_STUN_GET_METHOD(tdata->msg->hdr.type)) { 263 case PJ_STUN_BINDING_METHOD: 264 tdata->sess->cb.on_bind_response(tdata->sess, status, tdata, response); 265 break; 266 case PJ_STUN_ALLOCATE_METHOD: 267 tdata->sess->cb.on_allocate_response(tdata->sess, status, 268 tdata, response); 269 break; 270 case PJ_STUN_SET_ACTIVE_DESTINATION_METHOD: 271 tdata->sess->cb.on_set_active_destination_response(tdata->sess, status, 272 tdata, response); 273 break; 274 case PJ_STUN_CONNECT_METHOD: 275 tdata->sess->cb.on_connect_response(tdata->sess, status, tdata, 276 response); 277 break; 278 default: 279 pj_assert(!"Unknown method"); 280 break; 288 if (tdata->sess->cb.on_request_complete) { 289 (*tdata->sess->cb.on_request_complete)(tdata->sess, status, tdata, 290 response); 281 291 } 282 292 } … … 290 300 tdata = (pj_stun_tx_data*) pj_stun_client_tsx_get_data(tsx); 291 301 292 return tdata->sess->cb.on_send_msg(tdata , stun_pkt, pkt_size,293 tdata-> addr_len, tdata->dst_addr);302 return tdata->sess->cb.on_send_msg(tdata->sess, stun_pkt, pkt_size, 303 tdata->dst_addr, tdata->addr_len); 294 304 } 295 305 … … 303 313 pj_pool_t *pool; 304 314 pj_stun_session *sess; 315 pj_status_t status; 305 316 306 317 PJ_ASSERT_RETURN(endpt && cb && p_sess, PJ_EINVAL); 318 319 if (name==NULL) 320 name = "sess%p"; 307 321 308 322 pool = pj_pool_create(endpt->pf, name, 4000, 4000, NULL); … … 316 330 pj_list_init(&sess->pending_request_list); 317 331 332 status = pj_mutex_create_recursive(pool, name, &sess->mutex); 333 if (status != PJ_SUCCESS) { 334 pj_pool_release(pool); 335 return status; 336 } 337 318 338 *p_sess = sess; 319 339 320 PJ_TODO(MUTEX_PROTECTION);321 322 340 return PJ_SUCCESS; 323 341 } … … 327 345 PJ_ASSERT_RETURN(sess, PJ_EINVAL); 328 346 347 pj_mutex_destroy(sess->mutex); 329 348 pj_pool_release(sess->pool); 330 349 … … 337 356 { 338 357 PJ_ASSERT_RETURN(sess, PJ_EINVAL); 358 pj_mutex_lock(sess->mutex); 339 359 sess->user_data = user_data; 360 pj_mutex_unlock(sess->mutex); 340 361 return PJ_SUCCESS; 341 362 } … … 356 377 357 378 PJ_ASSERT_RETURN(sess, PJ_EINVAL); 379 380 pj_mutex_lock(sess->mutex); 358 381 pj_strdup_with_null(sess->pool, &sess->l_realm, realm ? realm : &nil); 359 382 pj_strdup_with_null(sess->pool, &sess->l_username, user ? user : &nil); 360 383 pj_strdup_with_null(sess->pool, &sess->l_password, passwd ? passwd : &nil); 384 pj_mutex_unlock(sess->mutex); 361 385 362 386 return PJ_SUCCESS; … … 372 396 373 397 PJ_ASSERT_RETURN(sess, PJ_EINVAL); 398 399 pj_mutex_lock(sess->mutex); 374 400 pj_strdup_with_null(sess->pool, &sess->s_username, user ? user : &nil); 375 401 pj_strdup_with_null(sess->pool, &sess->s_password, passwd ? passwd : &nil); 402 pj_mutex_unlock(sess->mutex); 376 403 377 404 return PJ_SUCCESS; … … 387 414 PJ_ASSERT_RETURN(sess && p_tdata, PJ_EINVAL); 388 415 389 status = create_tdata(sess, PJ_STUN_BINDING_REQUEST, NULL, &tdata); 416 status = create_request_tdata(sess, PJ_STUN_BINDING_REQUEST, NULL, 417 &tdata); 390 418 if (status != PJ_SUCCESS) 391 419 return status; … … 398 426 pj_stun_tx_data **p_tdata) 399 427 { 428 PJ_UNUSED_ARG(sess); 429 PJ_UNUSED_ARG(p_tdata); 400 430 PJ_ASSERT_RETURN(PJ_FALSE, PJ_ENOTSUP); 401 431 } … … 406 436 pj_stun_tx_data **p_tdata) 407 437 { 438 PJ_UNUSED_ARG(sess); 439 PJ_UNUSED_ARG(p_tdata); 408 440 PJ_ASSERT_RETURN(PJ_FALSE, PJ_ENOTSUP); 409 441 } … … 412 444 pj_stun_tx_data **p_tdata) 413 445 { 446 PJ_UNUSED_ARG(sess); 447 PJ_UNUSED_ARG(p_tdata); 414 448 PJ_ASSERT_RETURN(PJ_FALSE, PJ_ENOTSUP); 415 449 } … … 419 453 pj_stun_tx_data **p_tdata) 420 454 { 455 PJ_UNUSED_ARG(sess); 456 PJ_UNUSED_ARG(p_tdata); 421 457 PJ_ASSERT_RETURN(PJ_FALSE, PJ_ENOTSUP); 422 458 } … … 425 461 pj_stun_tx_data **p_tdata) 426 462 { 463 PJ_UNUSED_ARG(sess); 464 PJ_UNUSED_ARG(p_tdata); 427 465 PJ_ASSERT_RETURN(PJ_FALSE, PJ_ENOTSUP); 428 466 } … … 431 469 pj_stun_tx_data **p_tdata) 432 470 { 471 PJ_UNUSED_ARG(sess); 472 PJ_UNUSED_ARG(p_tdata); 433 473 PJ_ASSERT_RETURN(PJ_FALSE, PJ_ENOTSUP); 434 474 } 475 476 477 /* 478 * Create a STUN response message. 479 */ 480 PJ_DEF(pj_status_t) pj_stun_session_create_response( pj_stun_session *sess, 481 const pj_stun_msg *req, 482 unsigned err_code, 483 const pj_str_t *err_msg, 484 pj_stun_tx_data **p_tdata) 485 { 486 pj_status_t status; 487 pj_stun_tx_data *tdata; 488 489 status = create_tdata(sess, NULL, &tdata); 490 if (status != PJ_SUCCESS) 491 return status; 492 493 /* Create STUN response message */ 494 status = pj_stun_msg_create_response(tdata->pool, req, err_code, err_msg, 495 &tdata->msg); 496 if (status != PJ_SUCCESS) { 497 pj_pool_release(tdata->pool); 498 return status; 499 } 500 501 /* copy the request's transaction ID as the transaction key. */ 502 pj_assert(sizeof(tdata->client_key)==sizeof(req->hdr.tsx_id)); 503 pj_memcpy(tdata->client_key, req->hdr.tsx_id, sizeof(req->hdr.tsx_id)); 504 505 *p_tdata = tdata; 506 507 return PJ_SUCCESS; 508 } 509 510 511 /* Print outgoing message to log */ 512 static void dump_tx_msg(pj_stun_session *sess, const pj_stun_msg *msg, 513 unsigned pkt_size, const pj_sockaddr_t *addr) 514 { 515 const char *dst_name; 516 int dst_port; 517 const pj_sockaddr *dst = (const pj_sockaddr*)addr; 518 char buf[512]; 519 520 if (dst->sa_family == PJ_AF_INET) { 521 const pj_sockaddr_in *dst4 = (const pj_sockaddr_in*)dst; 522 dst_name = pj_inet_ntoa(dst4->sin_addr); 523 dst_port = pj_ntohs(dst4->sin_port); 524 } else if (dst->sa_family == PJ_AF_INET6) { 525 const pj_sockaddr_in6 *dst6 = (const pj_sockaddr_in6*)dst; 526 dst_name = "IPv6"; 527 dst_port = pj_ntohs(dst6->sin6_port); 528 } else { 529 LOG_ERR_(sess, "Invalid address family", PJ_EINVAL); 530 return; 531 } 532 533 PJ_LOG(5,(SNAME(sess), 534 "TX %d bytes STUN message to %s:%d:\n" 535 "--- begin STUN message ---\n" 536 "%s" 537 "--- end of STUN message ---\n", 538 pkt_size, dst_name, dst_port, 539 pj_stun_msg_dump(msg, buf, sizeof(buf), NULL))); 540 541 } 542 435 543 436 544 PJ_DEF(pj_status_t) pj_stun_session_send_msg( pj_stun_session *sess, 437 545 unsigned options, 546 const pj_sockaddr_t *server, 438 547 unsigned addr_len, 439 const pj_sockaddr_t *server,440 548 pj_stun_tx_data *tdata) 441 549 { 550 pj_str_t *password; 442 551 pj_status_t status; 443 552 … … 448 557 tdata->pkt = pj_pool_alloc(tdata->pool, tdata->max_len); 449 558 450 if (PJ_LOG_MAX_LEVEL >= 5) { 451 char *buf = (char*) tdata->pkt; 452 const char *dst_name; 453 int dst_port; 454 const pj_sockaddr *dst = (const pj_sockaddr*)server; 455 456 if (dst->sa_family == PJ_AF_INET) { 457 const pj_sockaddr_in *dst4 = (const pj_sockaddr_in*)dst; 458 dst_name = pj_inet_ntoa(dst4->sin_addr); 459 dst_port = pj_ntohs(dst4->sin_port); 460 } else if (dst->sa_family == PJ_AF_INET6) { 461 const pj_sockaddr_in6 *dst6 = (const pj_sockaddr_in6*)dst; 462 dst_name = "IPv6"; 463 dst_port = pj_ntohs(dst6->sin6_port); 464 } else { 465 LOG_ERR_(sess, "Invalid address family", PJ_EINVAL); 466 return PJ_EINVAL; 467 } 468 469 PJ_LOG(5,(SNAME(sess), 470 "Sending STUN message to %s:%d:\n" 471 "--- begin STUN message ---\n" 472 "%s" 473 "--- end of STUN message ---\n", 474 dst_name, dst_port, 475 pj_stun_msg_dump(tdata->msg, buf, tdata->max_len, NULL))); 476 } 559 /* Start locking the session now */ 560 pj_mutex_lock(sess->mutex); 477 561 478 562 /* Apply options */ 479 status = session_apply_req(sess, tdata->pool, options, tdata->msg); 563 status = apply_msg_options(sess, tdata->pool, options, 564 tdata->msg, &password); 480 565 if (status != PJ_SUCCESS) { 566 pj_stun_msg_destroy_tdata(sess, tdata); 567 pj_mutex_unlock(sess->mutex); 481 568 LOG_ERR_(sess, "Error applying options", status); 482 destroy_tdata(tdata);483 569 return status; 484 570 } … … 488 574 0, NULL, &tdata->pkt_size); 489 575 if (status != PJ_SUCCESS) { 576 pj_stun_msg_destroy_tdata(sess, tdata); 577 pj_mutex_unlock(sess->mutex); 490 578 LOG_ERR_(sess, "STUN encode() error", status); 491 destroy_tdata(tdata); 492 return status; 493 } 579 return status; 580 } 581 582 /* Dump packet */ 583 dump_tx_msg(sess, tdata->msg, tdata->pkt_size, server); 494 584 495 585 /* If this is a STUN request message, then send the request with … … 512 602 tdata->pkt, tdata->pkt_size); 513 603 if (status != PJ_SUCCESS && status != PJ_EPENDING) { 604 pj_stun_msg_destroy_tdata(sess, tdata); 605 pj_mutex_unlock(sess->mutex); 514 606 LOG_ERR_(sess, "Error sending STUN request", status); 515 destroy_tdata(tdata);516 607 return status; 517 608 } … … 522 613 } else { 523 614 /* Otherwise for non-request message, send directly to transport. */ 524 status = sess->cb.on_send_msg( tdata, tdata->pkt, tdata->pkt_size,525 addr_len, server);615 status = sess->cb.on_send_msg(sess, tdata->pkt, tdata->pkt_size, 616 server, addr_len); 526 617 527 618 if (status != PJ_SUCCESS && status != PJ_EPENDING) { 528 619 LOG_ERR_(sess, "Error sending STUN request", status); 529 destroy_tdata(tdata);530 return status;531 620 } 532 } 533 534 621 622 /* Destroy */ 623 pj_stun_msg_destroy_tdata(sess, tdata); 624 } 625 626 627 pj_mutex_unlock(sess->mutex); 535 628 return status; 629 } 630 631 632 /* Handle incoming response */ 633 static pj_status_t on_incoming_response(pj_stun_session *sess, 634 pj_stun_msg *msg) 635 { 636 pj_stun_tx_data *tdata; 637 pj_status_t status; 638 639 /* Lookup pending client transaction */ 640 tdata = tsx_lookup(sess, msg); 641 if (tdata == NULL) { 642 LOG_ERR_(sess, "STUN error finding transaction", PJ_ENOTFOUND); 643 return PJ_ENOTFOUND; 644 } 645 646 /* Pass the response to the transaction. 647 * If the message is accepted, transaction callback will be called, 648 * and this will call the session callback too. 649 */ 650 status = pj_stun_client_tsx_on_rx_msg(tdata->client_tsx, msg); 651 if (status != PJ_SUCCESS) { 652 return status; 653 } 654 655 /* If transaction has completed, destroy the transmit data. 656 * This will remove the transaction from the pending list too. 657 */ 658 if (pj_stun_client_tsx_is_complete(tdata->client_tsx)) { 659 pj_stun_msg_destroy_tdata(sess, tdata); 660 tdata = NULL; 661 } 662 663 return PJ_SUCCESS; 664 } 665 666 667 /* Send response */ 668 static pj_status_t send_response(pj_stun_session *sess, unsigned options, 669 pj_pool_t *pool, pj_stun_msg *response, 670 const pj_sockaddr_t *addr, unsigned addr_len) 671 { 672 pj_uint8_t *out_pkt; 673 unsigned out_max_len, out_len; 674 pj_str_t *passwd; 675 pj_status_t status; 676 677 /* Alloc packet buffer */ 678 out_max_len = PJ_STUN_MAX_PKT_LEN; 679 out_pkt = pj_pool_alloc(pool, out_max_len); 680 681 /* Apply options */ 682 apply_msg_options(sess, pool, options, response, &passwd); 683 684 /* Encode */ 685 status = pj_stun_msg_encode(response, out_pkt, out_max_len, 0, 686 passwd, &out_len); 687 if (status != PJ_SUCCESS) { 688 LOG_ERR_(sess, "Error encoding message", status); 689 return status; 690 } 691 692 /* Print log */ 693 dump_tx_msg(sess, response, out_len, addr); 694 695 /* Send packet */ 696 status = sess->cb.on_send_msg(sess, out_pkt, out_len, addr, addr_len); 697 698 return status; 699 } 700 701 /* Handle incoming request */ 702 static pj_status_t on_incoming_request(pj_stun_session *sess, 703 pj_pool_t *tmp_pool, 704 const pj_uint8_t *in_pkt, 705 unsigned in_pkt_len, 706 const pj_stun_msg *msg, 707 const pj_sockaddr_t *src_addr, 708 unsigned src_addr_len) 709 { 710 pj_status_t status; 711 712 /* Distribute to handler, or respond with Bad Request */ 713 if (sess->cb.on_rx_request) { 714 status = (*sess->cb.on_rx_request)(sess, in_pkt, in_pkt_len, msg, 715 src_addr, src_addr_len); 716 } else { 717 pj_stun_msg *response = NULL; 718 719 status = pj_stun_msg_create_response(tmp_pool, msg, 720 PJ_STUN_STATUS_BAD_REQUEST, NULL, 721 &response); 722 if (status == PJ_SUCCESS && response) { 723 status = send_response(sess, 0, tmp_pool, response, 724 src_addr, src_addr_len); 725 } 726 } 727 728 return status; 729 } 730 731 732 /* Handle incoming indication */ 733 static pj_status_t on_incoming_indication(pj_stun_session *sess, 734 pj_pool_t *tmp_pool, 735 const pj_uint8_t *in_pkt, 736 unsigned in_pkt_len, 737 const pj_stun_msg *msg, 738 const pj_sockaddr_t *src_addr, 739 unsigned src_addr_len) 740 { 741 PJ_UNUSED_ARG(tmp_pool); 742 743 /* Distribute to handler */ 744 if (sess->cb.on_rx_indication) { 745 return (*sess->cb.on_rx_indication)(sess, in_pkt, in_pkt_len, msg, 746 src_addr, src_addr_len); 747 } else { 748 return PJ_SUCCESS; 749 } 536 750 } 537 751 … … 540 754 const void *packet, 541 755 pj_size_t pkt_size, 542 unsigned *parsed_len) 756 unsigned options, 757 unsigned *parsed_len, 758 const pj_sockaddr_t *src_addr, 759 unsigned src_addr_len) 543 760 { 544 761 pj_stun_msg *msg, *response; … … 555 772 /* Try to parse the message */ 556 773 status = pj_stun_msg_decode(tmp_pool, (const pj_uint8_t*)packet, 557 pkt_size, 0, &msg, parsed_len,558 & response);774 pkt_size, options, 775 &msg, parsed_len, &response); 559 776 if (status != PJ_SUCCESS) { 560 777 LOG_ERR_(sess, "STUN msg_decode() error", status); 561 778 if (response) { 562 PJ_TODO(SEND_RESPONSE); 779 send_response(sess, 0, tmp_pool, response, 780 src_addr, src_addr_len); 563 781 } 564 782 pj_pool_release(tmp_pool); … … 568 786 dump = pj_pool_alloc(tmp_pool, PJ_STUN_MAX_PKT_LEN); 569 787 570 PJ_LOG(4,(SNAME(sess), 788 PJ_LOG(4,(SNAME(sess), 571 789 "RX STUN message:\n" 572 "--- begin STUN message --- "790 "--- begin STUN message ---\n" 573 791 "%s" 574 792 "--- end of STUN message ---\n", 575 793 pj_stun_msg_dump(msg, dump, PJ_STUN_MAX_PKT_LEN, NULL))); 576 794 795 pj_mutex_lock(sess->mutex); 577 796 578 797 if (PJ_STUN_IS_RESPONSE(msg->hdr.type) || 579 798 PJ_STUN_IS_ERROR_RESPONSE(msg->hdr.type)) 580 799 { 581 pj_stun_tx_data *tdata; 582 583 /* Lookup pending client transaction */ 584 tdata = tsx_lookup(sess, msg); 585 if (tdata == NULL) { 586 LOG_ERR_(sess, "STUN error finding transaction", PJ_ENOTFOUND); 587 pj_pool_release(tmp_pool); 588 return PJ_ENOTFOUND; 589 } 590 591 /* Pass the response to the transaction. 592 * If the message is accepted, transaction callback will be called, 593 * and this will call the session callback too. 594 */ 595 status = pj_stun_client_tsx_on_rx_msg(tdata->client_tsx, msg); 596 if (status != PJ_SUCCESS) { 597 pj_pool_release(tmp_pool); 598 return status; 599 } 600 601 /* If transaction has completed, destroy the transmit data. 602 * This will remove the transaction from the pending list too. 603 */ 604 if (pj_stun_client_tsx_is_complete(tdata->client_tsx)) { 605 destroy_tdata(tdata); 606 tdata = NULL; 607 } 608 609 pj_pool_release(tmp_pool); 610 return PJ_SUCCESS; 800 status = on_incoming_response(sess, msg); 611 801 612 802 } else if (PJ_STUN_IS_REQUEST(msg->hdr.type)) { 613 803 614 PJ_TODO(HANDLE_INCOMING_STUN_REQUEST); 804 status = on_incoming_request(sess, tmp_pool, packet, pkt_size, msg, 805 src_addr, src_addr_len); 615 806 616 807 } else if (PJ_STUN_IS_INDICATION(msg->hdr.type)) { 617 808 618 PJ_TODO(HANDLE_INCOMING_STUN_INDICATION); 809 status = on_incoming_indication(sess, tmp_pool, packet, pkt_size, 810 msg, src_addr, src_addr_len); 619 811 620 812 } else { 621 813 pj_assert(!"Unexpected!"); 622 } 814 status = PJ_EBUG; 815 } 816 817 pj_mutex_unlock(sess->mutex); 623 818 624 819 pj_pool_release(tmp_pool); 625 return PJ_ENOTSUP; 626 } 627 820 return status; 821 } 822 823
Note: See TracChangeset
for help on using the changeset viewer.