PJSIP 1.7 - iOS 4

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Benny, this patch didn't work out of the box for us. After Dmitry fussed with it for most of the day he was able to get it to work (PJ 1.6, iOS 4.0.2). 

So, apply the patch and update replace_udp_sock to match this. We only did light testing, so don't blame us...


#include <pj/sock_qos.h>
static pj_status_t replace_udp_sock(pj_ioqueue_key_t *h)
{
    enum flags {
	HAS_PEER_ADDR = 1,
	HAS_QOS = 2
    };
    pj_sock_t old_sock, new_sock = PJ_INVALID_SOCKET;
    pj_sockaddr local_addr, rem_addr;
    int val, addr_len;
    pj_fd_set_t *fds[3];
    unsigned i, fds_cnt, flags=0;
    pj_qos_params qos_params;
    unsigned msec;
    pj_status_t status;
    pj_sockaddr_in bound_addr;
	int old_port;
	
    pj_lock_acquire(h->ioqueue->lock);

    old_sock = h->fd;

    /* Can only replace UDP socket */
    pj_assert(h->fd_type == pj_SOCK_DGRAM());

    /* Investigate the old socket */
    addr_len = sizeof(local_addr);
    status = pj_sock_getsockname(old_sock, &local_addr, &addr_len);
	
	old_port = local_addr.ipv4.sin_port;
	
    PJ_LOG(4,(THIS_FILE, "Attempting to replace UDP socket %d, bound to %d",
    			old_sock, pj_ntohs(old_port)));

    if (status != PJ_SUCCESS)
	goto on_error;

    addr_len = sizeof(rem_addr);
    status = pj_sock_getpeername(old_sock, &rem_addr, &addr_len);
    if (status == PJ_SUCCESS)
		flags |= HAS_PEER_ADDR;
	
    status = pj_sock_get_qos_params(old_sock, &qos_params);
    if (status == PJ_SUCCESS)
		flags |= HAS_QOS;

    /* We're done with the old socket, close it otherwise we'll get
     * error in bind()
     */
    pj_sock_close(old_sock);

    /* Prepare the new socket */
    status = pj_sock_socket(local_addr.addr.sa_family, PJ_SOCK_DGRAM, 0,
			    &new_sock);
    if (status != PJ_SUCCESS)
	goto on_error;

    /* Even after the socket is closed, we'll still get "Address in use"
     * errors, so force it with SO_REUSEADDR
     */
    val = 1;
    status = pj_sock_setsockopt(new_sock, SOL_SOCKET, SO_REUSEADDR,
				&val, sizeof(val));
    if (status != PJ_SUCCESS)
	goto on_error;

    /* The loop is silly, but what else can we do? */
    for (msec=20; ; msec<1000? msec=msec*2 : 1000) 
	{
		bound_addr.sin_addr.s_addr = PJ_INADDR_ANY;
		status = pj_sock_bind_in(new_sock, pj_ntohl(bound_addr.sin_addr.s_addr), 
								 pj_ntohs(old_port));

		// Original path did this:
		//status = pj_sock_bind(new_sock, &local_addr, addr_len);
	if (status != PJ_STATUS_FROM_OS(EADDRINUSE))
	    break;
	PJ_LOG(4,(THIS_FILE, "Address is still in use, retrying.."));
	pj_thread_sleep(msec);
    }

    if (status != PJ_SUCCESS)
	goto on_error;

    if (flags & HAS_QOS) {
	status = pj_sock_set_qos_params(new_sock, &qos_params);
 	if (status != PJ_SUCCESS)
	    goto on_error;
    }

    if (flags & HAS_PEER_ADDR) {
	status = pj_sock_connect(new_sock, &rem_addr, addr_len);
 	if (status != PJ_SUCCESS)
	    goto on_error;
    }

    /* Set socket to nonblocking. */
    val = 1;
#if defined(PJ_WIN32) && PJ_WIN32!=0 || \
    defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE!=0
    if (ioctlsocket(new_sock, FIONBIO, &val)) {
#else
    if (ioctl(new_sock, FIONBIO, &val)) {
#endif
        status = pj_get_netos_error();
 	goto on_error;
    }

    /* Replace the occurrence of old socket with new socket in the
     * fd sets.
     */
    fds_cnt = 0;
    fds[fds_cnt++] = &h->ioqueue->rfdset;
    fds[fds_cnt++] = &h->ioqueue->wfdset;
#if PJ_HAS_TCP
    fds[fds_cnt++] = &h->ioqueue->xfdset;
#endif

    for (i=0; i<fds_cnt; ++i) {
	if (PJ_FD_ISSET(old_sock, fds[i])) {
	    PJ_FD_CLR(old_sock, fds[i]);
	    PJ_FD_SET(new_sock, fds[i]);
	}
    }

    /* And finally replace the fd in the key */
    h->fd = new_sock;

    PJ_LOG(4,(THIS_FILE, "UDP socket has been replaced successfully!"));

    pj_lock_release(h->ioqueue->lock);

    return PJ_SUCCESS;

on_error:
    if (new_sock != PJ_INVALID_SOCKET)
	pj_sock_close(new_sock);
    PJ_PERROR(1,(THIS_FILE, status, "Error replacing socket"));
    pj_lock_release(h->ioqueue->lock);
    return status;
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.pjsip.org/pipermail/pjsip_lists.pjsip.org/attachments/20100812/3ea35ec8/attachment.html>


[Index of Archives]     [Asterisk Users]     [Asterisk App Development]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [Linux API]
  Powered by Linux