Changeset 5737 for pjproject/trunk/pjlib/src/pj/ioqueue_select.c
- Timestamp:
- Feb 15, 2018 1:57:11 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjlib/src/pj/ioqueue_select.c
r5680 r5737 728 728 PJ_LOG(4,(THIS_FILE, "Attempting to replace UDP socket %d", old_sock)); 729 729 730 /* Investigate the old socket */ 731 addr_len = sizeof(local_addr); 732 status = pj_sock_getsockname(old_sock, &local_addr, &addr_len); 730 for (msec=20; (msec<1000 && status != PJ_SUCCESS) ; 731 msec<1000? msec=msec*2 : 1000) 732 { 733 if (msec > 20) { 734 PJ_LOG(4,(THIS_FILE, "Retry to replace UDP socket %d", old_sock)); 735 pj_thread_sleep(msec); 736 } 737 738 /* Investigate the old socket */ 739 addr_len = sizeof(local_addr); 740 status = pj_sock_getsockname(old_sock, &local_addr, &addr_len); 741 if (status != PJ_SUCCESS) { 742 PJ_LOG(5,(THIS_FILE, "Error get socket name %d", status)); 743 continue; 744 } 745 746 addr_len = sizeof(rem_addr); 747 status = pj_sock_getpeername(old_sock, &rem_addr, &addr_len); 748 if (status != PJ_SUCCESS) { 749 PJ_LOG(5,(THIS_FILE, "Error get peer name %d", status)); 750 } else { 751 flags |= HAS_PEER_ADDR; 752 } 753 754 status = pj_sock_get_qos_params(old_sock, &qos_params); 755 if (status == PJ_STATUS_FROM_OS(EBADF) || 756 status == PJ_STATUS_FROM_OS(EINVAL)) 757 { 758 PJ_LOG(5,(THIS_FILE, "Error get qos param %d", status)); 759 continue; 760 } 761 762 if (status != PJ_SUCCESS) { 763 PJ_LOG(5,(THIS_FILE, "Error get qos param %d", status)); 764 } else { 765 flags |= HAS_QOS; 766 } 767 768 /* We're done with the old socket, close it otherwise we'll get 769 * error in bind() 770 */ 771 status = pj_sock_close(old_sock); 772 if (status != PJ_SUCCESS) { 773 PJ_LOG(5,(THIS_FILE, "Error closing socket %d", status)); 774 } 775 776 /* Prepare the new socket */ 777 status = pj_sock_socket(local_addr.addr.sa_family, PJ_SOCK_DGRAM, 0, 778 &new_sock); 779 if (status != PJ_SUCCESS) { 780 PJ_LOG(5,(THIS_FILE, "Error create socket %d", status)); 781 continue; 782 } 783 784 /* Even after the socket is closed, we'll still get "Address in use" 785 * errors, so force it with SO_REUSEADDR 786 */ 787 val = 1; 788 status = pj_sock_setsockopt(new_sock, SOL_SOCKET, SO_REUSEADDR, 789 &val, sizeof(val)); 790 if (status == PJ_STATUS_FROM_OS(EBADF) || 791 status == PJ_STATUS_FROM_OS(EINVAL)) 792 { 793 PJ_LOG(5,(THIS_FILE, "Error set socket option %d", 794 status)); 795 continue; 796 } 797 798 /* The loop is silly, but what else can we do? */ 799 addr_len = pj_sockaddr_get_len(&local_addr); 800 for (msec=20; msec<1000 ; msec<1000? msec=msec*2 : 1000) { 801 status = pj_sock_bind(new_sock, &local_addr, addr_len); 802 if (status != PJ_STATUS_FROM_OS(EADDRINUSE)) 803 break; 804 PJ_LOG(4,(THIS_FILE, "Address is still in use, retrying..")); 805 pj_thread_sleep(msec); 806 } 807 808 if (status != PJ_SUCCESS) 809 continue; 810 811 if (flags & HAS_QOS) { 812 status = pj_sock_set_qos_params(new_sock, &qos_params); 813 if (status == PJ_STATUS_FROM_OS(EINVAL)) { 814 PJ_LOG(5,(THIS_FILE, "Error set qos param %d", status)); 815 continue; 816 } 817 } 818 819 if (flags & HAS_PEER_ADDR) { 820 status = pj_sock_connect(new_sock, &rem_addr, addr_len); 821 if (status != PJ_SUCCESS) { 822 PJ_LOG(5,(THIS_FILE, "Error connect socket %d", status)); 823 continue; 824 } 825 } 826 } 827 733 828 if (status != PJ_SUCCESS) 734 829 goto on_error; 735 830 736 addr_len = sizeof(rem_addr);737 status = pj_sock_getpeername(old_sock, &rem_addr, &addr_len);738 if (status == PJ_SUCCESS)739 flags |= HAS_PEER_ADDR;740 741 status = pj_sock_get_qos_params(old_sock, &qos_params);742 if (status == PJ_SUCCESS)743 flags |= HAS_QOS;744 745 /* We're done with the old socket, close it otherwise we'll get746 * error in bind()747 */748 pj_sock_close(old_sock);749 750 /* Prepare the new socket */751 status = pj_sock_socket(local_addr.addr.sa_family, PJ_SOCK_DGRAM, 0,752 &new_sock);753 if (status != PJ_SUCCESS)754 goto on_error;755 756 /* Even after the socket is closed, we'll still get "Address in use"757 * errors, so force it with SO_REUSEADDR758 */759 val = 1;760 status = pj_sock_setsockopt(new_sock, SOL_SOCKET, SO_REUSEADDR,761 &val, sizeof(val));762 if (status != PJ_SUCCESS)763 goto on_error;764 765 /* The loop is silly, but what else can we do? */766 addr_len = pj_sockaddr_get_len(&local_addr);767 for (msec=20; ; msec<1000? msec=msec*2 : 1000) {768 status = pj_sock_bind(new_sock, &local_addr, addr_len);769 if (status != PJ_STATUS_FROM_OS(EADDRINUSE))770 break;771 PJ_LOG(4,(THIS_FILE, "Address is still in use, retrying.."));772 pj_thread_sleep(msec);773 }774 775 if (status != PJ_SUCCESS)776 goto on_error;777 778 if (flags & HAS_QOS) {779 status = pj_sock_set_qos_params(new_sock, &qos_params);780 if (status != PJ_SUCCESS)781 goto on_error;782 }783 784 if (flags & HAS_PEER_ADDR) {785 status = pj_sock_connect(new_sock, &rem_addr, addr_len);786 if (status != PJ_SUCCESS)787 goto on_error;788 }789 790 831 /* Set socket to nonblocking. */ 791 832 val = 1; … … 830 871 if (new_sock != PJ_INVALID_SOCKET) 831 872 pj_sock_close(new_sock); 832 PJ_PERROR(1,(THIS_FILE, status, "Error replacing socket "));873 PJ_PERROR(1,(THIS_FILE, status, "Error replacing socket [%d]", status)); 833 874 pj_lock_release(h->ioqueue->lock); 834 return status;875 return PJ_ESOCKETSTOP; 835 876 } 836 877 #endif
Note: See TracChangeset
for help on using the changeset viewer.