[pjsip] possible problem with working in the background on ios

Walker, Brian brian.walker at necect.com
Mon Dec 9 09:18:28 EST 2013

I ran into the same problem. The incoming TCP connections are not marked as VoIP sockets. Each time a new connection is accepted the listening socket is marked as VoIP and not the new connected socket. Marking the listening socket as VoIP has no effect.

I created the attached patch to work around this problem. These changes are in sip_transport_tcp.c and sip_transport_tls.c.  For the long term there may be a better way to handle this in activesock.c but I did not see an easy way to get a pointer to the new pj_activesock_t structure for the new socket.

From: pjsip [pjsip-bounces at lists.pjsip.org] On Behalf Of maciej skolecki [maciej_skolecki at yahoo.com]
Sent: Monday, December 09, 2013 5:38 AM
To: pjsip at lists.pjsip.org
Subject: [pjsip] possible problem with working in the background on ios

Hi All,

I've been trying to get the library working on ios and wanted my voip app to work in the background. Here's what I found:

I've been using Siphon app to talk with a Cisco SIP server. My app opens two TCP sockets to the SIP server. One of the sockets is opened as a client (using connect() ) function, while the other is waiting for incoming connections ( the library calls accept() ).
Now the problem that I discovered is that while the library attaches CFReadStreams to these sockets, doing this for this listening socket looks incorrect. Here's why:

The function pj_ioqueue_poll get's called and notices that there is a read on one of the sockets pending. This causes the ioqueue_dispatch_read_event to be called which in turn calls pj_sock_accept. This function calls the system's accept function internally. In pj_sock_accept, the first argument is the file descriptor of the socket on which accept should be called while the second argument is used to return the new fd obtained from the accept function. After pj_sock_accept returns this new socket fd is available in the accept_op->accept_fd field.
Next the callback is called, on_accept_complete which gets passed both h (i.e pj_ioqueue_key_t) as well as the new socket (as accept_op and *accept_op->accept_fd, second and third arguments). This callback is the function that will do the actuall attaching of CFStreams. Now looking at this function (ioqueue_on_accept_complete defined in activesock.c) we can see that neither the accept_oop or this this new socket fd are used (new_socket is even marked as PJ_UNUSED_ARG) .

Instead all CFStream operations are performed on an pj_activesock_t struct which is created from the user data field stored in the pj_ioqueue_t passed as the first argument. But it still contains the old socket that was passed to accept initially, not the one returned from it. This socket is not the correct one because it is not the one on which the connection was established and iOS cannot detect any incoming data and thus wake the app.

I tried to find if there is another place in the code where the new socket obtained from accept is written to the  pj_activesock_t data that is stored in the  pj_ioqueue_t.user_data field but could not find any.

I would appreciate investigating it and if it is really a bug, fixing it.

best regards,
maciej skolecki
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ios_tcp_background.patch
Type: application/octet-stream
Size: 1488 bytes
Desc: ios_tcp_background.patch
URL: <http://lists.pjsip.org/pipermail/pjsip_lists.pjsip.org/attachments/20131209/ede7ba16/attachment-0001.patch>

More information about the pjsip mailing list