Changeset 4360 for pjproject/trunk/pjnath/src/pjnath/stun_sock.c
- Timestamp:
- Feb 21, 2013 11:26:35 AM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjnath/src/pjnath/stun_sock.c
r4344 r4360 29 29 #include <pj/ip_helper.h> 30 30 #include <pj/log.h> 31 #include <pj/os.h> 31 32 #include <pj/pool.h> 32 33 #include <pj/rand.h> 33 34 35 #if 1 36 # define TRACE_(x) PJ_LOG(5,x) 37 #else 38 # define TRACE_(x) 39 #endif 34 40 35 41 enum { MAX_BIND_RETRY = 100 }; … … 40 46 pj_pool_t *pool; /* Pool */ 41 47 void *user_data; /* Application user data */ 42 48 pj_bool_t is_destroying; /* Destroy already called */ 43 49 int af; /* Address family */ 44 50 pj_stun_config stun_cfg; /* STUN config (ioqueue etc)*/ … … 59 65 pj_uint16_t tsx_id[6]; /* .. to match STUN msg */ 60 66 pj_stun_session *stun_sess; /* STUN session */ 61 67 pj_grp_lock_t *grp_lock; /* Session group lock */ 62 68 }; 63 69 … … 65 71 * Prototypes for static functions 66 72 */ 73 74 /* Destructor for group lock */ 75 static void stun_sock_destructor(void *obj); 67 76 68 77 /* This callback is called by the STUN session to send packet */ … … 203 212 stun_sock->ka_interval = PJ_STUN_KEEP_ALIVE_SEC; 204 213 214 if (cfg && cfg->grp_lock) { 215 stun_sock->grp_lock = cfg->grp_lock; 216 } else { 217 status = pj_grp_lock_create(pool, NULL, &stun_sock->grp_lock); 218 if (status != PJ_SUCCESS) { 219 pj_pool_release(pool); 220 return status; 221 } 222 } 223 224 pj_grp_lock_add_ref(stun_sock->grp_lock); 225 pj_grp_lock_add_handler(stun_sock->grp_lock, pool, stun_sock, 226 &stun_sock_destructor); 227 205 228 /* Create socket and bind socket */ 206 229 status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &stun_sock->sock_fd); … … 253 276 254 277 pj_activesock_cfg_default(&activesock_cfg); 278 activesock_cfg.grp_lock = stun_sock->grp_lock; 255 279 activesock_cfg.async_cnt = cfg->async_cnt; 256 280 activesock_cfg.concurrency = 0; … … 291 315 stun_sock->obj_name, 292 316 &sess_cb, PJ_FALSE, 317 stun_sock->grp_lock, 293 318 &stun_sock->stun_sess); 294 319 if (status != PJ_SUCCESS) … … 333 358 PJ_ASSERT_RETURN(stun_sock && domain && default_port, PJ_EINVAL); 334 359 360 pj_grp_lock_acquire(stun_sock->grp_lock); 361 335 362 /* Check whether the domain contains IP address */ 336 363 stun_sock->srv_addr.addr.sa_family = (pj_uint16_t)stun_sock->af; … … 361 388 362 389 /* Processing will resume when the DNS SRV callback is called */ 363 return status;364 390 365 391 } else { … … 379 405 380 406 /* Start sending Binding request */ 381 return get_mapped_addr(stun_sock); 382 } 383 } 384 385 /* Destroy */ 386 PJ_DEF(pj_status_t) pj_stun_sock_destroy(pj_stun_sock *stun_sock) 387 { 407 status = get_mapped_addr(stun_sock); 408 } 409 410 pj_grp_lock_release(stun_sock->grp_lock); 411 return status; 412 } 413 414 /* Destructor */ 415 static void stun_sock_destructor(void *obj) 416 { 417 pj_stun_sock *stun_sock = (pj_stun_sock*)obj; 418 388 419 if (stun_sock->q) { 389 420 pj_dns_srv_cancel_query(stun_sock->q, PJ_FALSE); … … 391 422 } 392 423 393 if (stun_sock->stun_sess) { 394 pj_stun_session_set_user_data(stun_sock->stun_sess, NULL); 395 } 396 397 /* Destroy the active socket first just in case we'll get 398 * stray callback. 399 */ 400 if (stun_sock->active_sock != NULL) { 401 pj_activesock_t *asock = stun_sock->active_sock; 402 stun_sock->active_sock = NULL; 403 stun_sock->sock_fd = PJ_INVALID_SOCKET; 404 pj_activesock_set_user_data(asock, NULL); 405 pj_activesock_close(asock); 406 } else if (stun_sock->sock_fd != PJ_INVALID_SOCKET) { 407 pj_sock_close(stun_sock->sock_fd); 408 stun_sock->sock_fd = PJ_INVALID_SOCKET; 409 } 410 411 if (stun_sock->ka_timer.id != 0) { 412 pj_timer_heap_cancel(stun_sock->stun_cfg.timer_heap, 413 &stun_sock->ka_timer); 414 stun_sock->ka_timer.id = 0; 415 } 416 424 /* 417 425 if (stun_sock->stun_sess) { 418 426 pj_stun_session_destroy(stun_sock->stun_sess); 419 427 stun_sock->stun_sess = NULL; 420 428 } 429 */ 421 430 422 431 if (stun_sock->pool) { … … 426 435 } 427 436 437 TRACE_(("", "STUN sock %p destroyed", stun_sock)); 438 439 } 440 441 /* Destroy */ 442 PJ_DEF(pj_status_t) pj_stun_sock_destroy(pj_stun_sock *stun_sock) 443 { 444 TRACE_((stun_sock->obj_name, "STUN sock %p request, ref_cnt=%d", 445 stun_sock, pj_grp_lock_get_ref(stun_sock->grp_lock))); 446 447 pj_grp_lock_acquire(stun_sock->grp_lock); 448 if (stun_sock->is_destroying) { 449 /* Destroy already called */ 450 pj_grp_lock_release(stun_sock->grp_lock); 451 return PJ_EINVALIDOP; 452 } 453 454 stun_sock->is_destroying = PJ_TRUE; 455 pj_timer_heap_cancel_if_active(stun_sock->stun_cfg.timer_heap, 456 &stun_sock->ka_timer, 0); 457 458 if (stun_sock->active_sock != NULL) { 459 stun_sock->sock_fd = PJ_INVALID_SOCKET; 460 pj_activesock_close(stun_sock->active_sock); 461 } else if (stun_sock->sock_fd != PJ_INVALID_SOCKET) { 462 pj_sock_close(stun_sock->sock_fd); 463 stun_sock->sock_fd = PJ_INVALID_SOCKET; 464 } 465 466 if (stun_sock->stun_sess) { 467 pj_stun_session_destroy(stun_sock->stun_sess); 468 } 469 pj_grp_lock_dec_ref(stun_sock->grp_lock); 470 pj_grp_lock_release(stun_sock->grp_lock); 428 471 return PJ_SUCCESS; 429 472 } … … 469 512 pj_stun_sock *stun_sock = (pj_stun_sock*) user_data; 470 513 514 pj_grp_lock_acquire(stun_sock->grp_lock); 515 471 516 /* Clear query */ 472 517 stun_sock->q = NULL; … … 475 520 if (status != PJ_SUCCESS) { 476 521 sess_fail(stun_sock, PJ_STUN_SOCK_DNS_OP, status); 522 pj_grp_lock_release(stun_sock->grp_lock); 477 523 return; 478 524 } … … 491 537 /* Start sending Binding request */ 492 538 get_mapped_addr(stun_sock); 539 540 pj_grp_lock_release(stun_sock->grp_lock); 493 541 } 494 542 … … 534 582 PJ_ASSERT_RETURN(stun_sock && info, PJ_EINVAL); 535 583 584 pj_grp_lock_acquire(stun_sock->grp_lock); 585 536 586 /* Copy STUN server address and mapped address */ 537 587 pj_memcpy(&info->srv_addr, &stun_sock->srv_addr, … … 544 594 status = pj_sock_getsockname(stun_sock->sock_fd, &info->bound_addr, 545 595 &addr_len); 546 if (status != PJ_SUCCESS) 596 if (status != PJ_SUCCESS) { 597 pj_grp_lock_release(stun_sock->grp_lock); 547 598 return status; 599 } 548 600 549 601 /* If socket is bound to a specific interface, then only put that … … 561 613 /* Get the default address */ 562 614 status = pj_gethostip(stun_sock->af, &def_addr); 563 if (status != PJ_SUCCESS) 615 if (status != PJ_SUCCESS) { 616 pj_grp_lock_release(stun_sock->grp_lock); 564 617 return status; 618 } 565 619 566 620 pj_sockaddr_set_port(&def_addr, port); … … 570 624 status = pj_enum_ip_interface(stun_sock->af, &info->alias_cnt, 571 625 info->aliases); 572 if (status != PJ_SUCCESS) 626 if (status != PJ_SUCCESS) { 627 pj_grp_lock_release(stun_sock->grp_lock); 573 628 return status; 629 } 574 630 575 631 /* Set the port number for each address. … … 591 647 } 592 648 649 pj_grp_lock_release(stun_sock->grp_lock); 593 650 return PJ_SUCCESS; 594 651 } … … 604 661 { 605 662 pj_ssize_t size; 663 pj_status_t status; 664 606 665 PJ_ASSERT_RETURN(stun_sock && pkt && dst_addr && addr_len, PJ_EINVAL); 607 666 667 pj_grp_lock_acquire(stun_sock->grp_lock); 668 669 if (!stun_sock->active_sock) { 670 /* We have been shutdown, but this callback may still get called 671 * by retransmit timer. 672 */ 673 pj_grp_lock_release(stun_sock->grp_lock); 674 return PJ_EINVALIDOP; 675 } 676 608 677 if (send_key==NULL) 609 678 send_key = &stun_sock->send_key; 610 679 611 680 size = pkt_len; 612 return pj_activesock_sendto(stun_sock->active_sock, send_key, 613 pkt, &size, flag, dst_addr, addr_len); 681 status = pj_activesock_sendto(stun_sock->active_sock, send_key, 682 pkt, &size, flag, dst_addr, addr_len); 683 684 pj_grp_lock_release(stun_sock->grp_lock); 685 return status; 614 686 } 615 687 … … 626 698 627 699 stun_sock = (pj_stun_sock *) pj_stun_session_get_user_data(sess); 628 if (!stun_sock || !stun_sock->active_sock) 700 if (!stun_sock || !stun_sock->active_sock) { 701 /* We have been shutdown, but this callback may still get called 702 * by retransmit timer. 703 */ 629 704 return PJ_EINVALIDOP; 705 } 630 706 631 707 pj_assert(token==INTERNAL_MSG_TOKEN); … … 633 709 634 710 size = pkt_size; 635 return pj_activesock_sendto(stun_sock->active_sock, 711 return pj_activesock_sendto(stun_sock->active_sock, 636 712 &stun_sock->int_send_key, 637 713 pkt, &size, 0, dst_addr, addr_len); … … 727 803 static void start_ka_timer(pj_stun_sock *stun_sock) 728 804 { 729 if (stun_sock->ka_timer.id != 0) { 730 pj_timer_heap_cancel(stun_sock->stun_cfg.timer_heap, 731 &stun_sock->ka_timer); 732 stun_sock->ka_timer.id = 0; 733 } 805 pj_timer_heap_cancel_if_active(stun_sock->stun_cfg.timer_heap, 806 &stun_sock->ka_timer, 0); 734 807 735 808 pj_assert(stun_sock->ka_interval != 0); 736 if (stun_sock->ka_interval > 0 ) {809 if (stun_sock->ka_interval > 0 && !stun_sock->is_destroying) { 737 810 pj_time_val delay; 738 811 … … 740 813 delay.msec = 0; 741 814 742 if (pj_timer_heap_schedule(stun_sock->stun_cfg.timer_heap, 743 &stun_sock->ka_timer, 744 &delay) == PJ_SUCCESS) 745 { 746 stun_sock->ka_timer.id = PJ_TRUE; 747 } 815 pj_timer_heap_schedule_w_grp_lock(stun_sock->stun_cfg.timer_heap, 816 &stun_sock->ka_timer, 817 &delay, PJ_TRUE, 818 stun_sock->grp_lock); 748 819 } 749 820 } … … 757 828 758 829 PJ_UNUSED_ARG(th); 830 pj_grp_lock_acquire(stun_sock->grp_lock); 759 831 760 832 /* Time to send STUN Binding request */ 761 if (get_mapped_addr(stun_sock) != PJ_SUCCESS) 833 if (get_mapped_addr(stun_sock) != PJ_SUCCESS) { 834 pj_grp_lock_release(stun_sock->grp_lock); 762 835 return; 836 } 763 837 764 838 /* Next keep-alive timer will be scheduled once the request 765 839 * is complete. 766 840 */ 841 pj_grp_lock_release(stun_sock->grp_lock); 767 842 } 768 843 … … 788 863 return PJ_TRUE; 789 864 } 865 866 pj_grp_lock_acquire(stun_sock->grp_lock); 790 867 791 868 /* Check that this is STUN message */ … … 824 901 PJ_STUN_IS_DATAGRAM, NULL, NULL, 825 902 src_addr, addr_len); 826 return status!=PJNATH_ESTUNDESTROYED ? PJ_TRUE : PJ_FALSE; 903 904 status = pj_grp_lock_release(stun_sock->grp_lock); 905 906 return status!=PJ_EGONE ? PJ_TRUE : PJ_FALSE; 827 907 828 908 process_app_data: … … 832 912 ret = (*stun_sock->cb.on_rx_data)(stun_sock, data, size, 833 913 src_addr, addr_len); 834 return ret; 835 } 836 837 return PJ_TRUE; 914 status = pj_grp_lock_release(stun_sock->grp_lock); 915 return status!=PJ_EGONE ? PJ_TRUE : PJ_FALSE; 916 } 917 918 status = pj_grp_lock_release(stun_sock->grp_lock); 919 return status!=PJ_EGONE ? PJ_TRUE : PJ_FALSE; 838 920 } 839 921 … … 857 939 if (stun_sock->cb.on_data_sent) { 858 940 pj_bool_t ret; 941 942 pj_grp_lock_acquire(stun_sock->grp_lock); 859 943 860 944 /* If app gives NULL send_key in sendto() function, then give … … 867 951 ret = (*stun_sock->cb.on_data_sent)(stun_sock, send_key, sent); 868 952 953 pj_grp_lock_release(stun_sock->grp_lock); 869 954 return ret; 870 955 }
Note: See TracChangeset
for help on using the changeset viewer.