[pjsip] PJSIP Bug on iOS, Error 488 when answering call

Dusan Klinec dusan.klinec at gmail.com
Tue Sep 8 19:07:19 EDT 2015


Hello,

I would like to report a bug I am encountering and to contribute a patch
fixing it.

* Bug description: When answering a call on iOS, it gives error 488 (Not
Acceptable Here).

* Bug reproducibility: 100%

* Environment:
 - The latest stable PJSIP version, 2.4.5.
 - iOS 8.4.1.
 - PJSIP configured to use STUN, ICE, TURN.
 - #define PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT 1

* How to reproduce: Call from device A to device B. When device B starts
ringing, wait until display goes off so the running application is switched
to background after a while. Then unlock device B and try answering the
call. Error 488 is returned on device B, call fails.

* Relevant log:

17:01:43.099 utsx0x128ac32e  .....STUN client transaction created
17:01:43.099 utsx0x128ac32e  .....STUN sending message (transmit count=1)
17:01:43.099 udprel0x12804f  ......socket send(): Destination address
required
17:01:43.099 utsx0x128ac32e  ......STUN error sending message: Destination
address required
17:01:43.099 stun_session.c  .....tdata 0x128ac30a8 destroy request,
force=0, tsx=0x128ac32ec
17:01:43.099 utsx0x128ac32e  .....STUN transaction 0x128ac32ec schedule
destroy
17:01:43.099 udprel0x12804f  .....Error sending STUN request: Destination
address required
17:01:43.099        icetp00  ....Destroying ICE session 0x1281b1828
17:01:43.099 stuse0x1281320  ....STUN session 0x128132428 destroy request,
ref_cnt=25
17:01:43.099 stuse0x1280c50  ....STUN session 0x1280c5428 destroy request,
ref_cnt=24
17:01:43.099        icetp00  ....ICE restart failed (status=120039)!
17:01:43.099  pjsua_media.c  ....pjmedia_transport_media_start() failed for
call_id 2 media 0: Destination address required
* Hypothesis: TURN socket is somehow broken (iOS takes it over / background
suspend?) after a while of ringing (180) in the background mode. It needs
to be replaced with replace_udp_sock() but TURN socket uses
only pj_activesock_send(), without recovery call replace_udp_sock(), (no
destination address) so the sending fails.

* Proposed fix: When this specific issue occurs, (Destination address
required, code 120039 or equivalently PJ_STATUS_FROM_OS(EDESTADDRREQ)),
another call to pj_activesock_sendto() is made with specified destination
address, in turn_on_send_pkt() in file turn_sock.c
The proposed fix worked for me and fixed my problem. The bug happened quite
often to me as user usually has device locked and answers a call after few
seconds after first ringing.

If only call to the pj_activesock_sendto() is made in the
turn_on_send_pkt(), error is returned for already connected (working) TURN
sockets. Thus I decided to call pj_activesock_sendto() only in the specific
case of this error. This is the simplest working solution I came up with.

I hope this helps to somebody struggling with the same problem as I did.

Patch is at the bottom of this mail (patching against PJSIP-2.4.5 stable).

Cheers.

Dusan Klinec (ph4r05)


Index: pjproject/sources/pjnath/src/pjnath/turn_sock.c
===================================================================
--- pjproject.orig/sources/pjnath/src/pjnath/turn_sock.c
+++ pjproject/sources/pjnath/src/pjnath/turn_sock.c
@@ -675,8 +675,20 @@ static pj_status_t turn_on_send_pkt(pj_t

     status = pj_activesock_send(turn_sock->active_sock,
&turn_sock->send_key,
  pkt, &len, 0);
+
+    // Is status indicating Destination required iOS bug? Error
EDESTADDRREQ, Destination address required.
+    if (status == PJ_STATUS_FROM_OS(39)){
+        show_err(turn_sock, "socket send()", status);
+        PJ_LOG(4, (turn_sock->obj_name, "Socket does not work, status %d.
Trying with destination address", status));
+
+        // On fail try to send with destination, may be iOS bug with
closed socket.
+        status = pj_activesock_sendto(turn_sock->active_sock,
&turn_sock->send_key,
+                                      pkt, &len, 0, dst_addr,
dst_addr_len);
+    }
+
     if (status != PJ_SUCCESS && status != PJ_EPENDING) {
  show_err(turn_sock, "socket send()", status);
+        PJ_LOG(4, (turn_sock->obj_name, "Socket does not work, status %d",
status));
     }

     return status;
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.pjsip.org/pipermail/pjsip_lists.pjsip.org/attachments/20150909/59d148e3/attachment.html>


More information about the pjsip mailing list