PJSIP 1.7 - iOS 4

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

 



I see that the only change you made is to replace pj_sock_bind() with
pj_sock_bind_in(), which will break IPv6 compatibility. Apart from
that the two calls are the same, so I don't quite understand why the
original one didn't work.

Best regards,
?Benny

On Fri, Aug 13, 2010 at 4:23 AM, Darald Trinka <dtrinka at gmail.com> wrote:
> 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;
> }
> _______________________________________________
> Visit our blog: http://blog.pjsip.org
>
> pjsip mailing list
> pjsip at lists.pjsip.org
> http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org
>
>



[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