[Home]

Summary:ASTERISK-08362: SIP bug in handling invitestate
Reporter:Luigi Rizzo (rizzo)Labels:
Date Opened:2006-12-16 05:18:08.000-0600Date Closed:2006-12-27 10:13:18.000-0600
Priority:MinorRegression?No
Status:Closed/CompleteComponents:Core/General
Versions:Frequency of
Occurrence
Related
Issues:
Environment:Attachments:
Description:When making an outgoing call, i noticed that even if the caller
hangs up before the callee answers, asterisk does not sent a CANCEL.
It took a bit to reproduce it, but now i know that it happens when
the callee sends back a 401 requesting from credentials.

Here is a sip history that shows the problem:
Example: two asterisk A and B, this is the history as seen from A:

   1. NewChan         Channel SIP/prova-0842e014 - from .....

A makes a call to B by sending an INVITE
   2. TxReqRel        INVITE / 102 INVITE - -UNKNOWN-

B requests credentials to A
   3. Rx              SIP/2.0 / 102 INVITE / 401 Unauthorized

A acks the 401
   4. TxReq           ACK / 102 ACK - -UNKNOWN-
       ---> here is the bug: the ack is send by transmit_request()
       which has
               if (sipmethod == SIP_ACK)
                       p->invitestate = INV_CONFIRMED;
       and this prevents sip_hangup(), later, from sending

from now on the attempt to call evolves
   5. AuthResp        Auth response sent for 558 in realm asterisk - nc 1
   6. TxReqRel        INVITE / 103 INVITE - -UNKNOWN-
   7. Rx              SIP/2.0 / 103 INVITE / 100 Trying
   8. Rx              SIP/2.0 / 103 INVITE / 180 Ringing
   9. SchedDestroy    32000 ms

here A hangs up, but because p->invitestate is wrong, the
CANCEL is not sent.

I believe that 1) the change of invitestate to
INV_CONFIRMED should go somewhere else, e.g. on the reception
of the '200 OK' reply to the INVITE, and 2) when the INVITE
is resent with auth info, invitestate should be reset to INV_CALLING.

I believe the

****** ADDITIONAL INFORMATION ******

This trivial patch (in asterisk/team/rizzo/astobj2/channels/chan_sip.c)
fixes the problem.

-- team/rizzo/astobj2/channels/chan_sip.c       2006/12/12 15:52:33     48411
+++ team/rizzo/astobj2/channels/chan_sip.c      2006/12/12 22:37:08     48418
@@ -7869,7 +7869,7 @@
{
       struct sip_request resp;

-       if (sipmethod == SIP_ACK)
+       if (0 && sipmethod == SIP_ACK)
               p->invitestate = INV_CONFIRMED;

       reqprep(&resp, p, sipmethod, seqno, newbranch);
@@ -12335,6 +12335,7 @@
               /* Then we AUTH */
               ast_string_field_free(p, theirtag);     /* forget their old tag, so we don't match tags when getting
+response */
               if (!req_ignore(req)) {
+                       p->invitestate = INV_CALLING;   /* XXX reset state */
                       if (p->authtries == MAX_AUTHTRIES || do_proxy_auth(p, req, resp, SIP_INVITE, 1)) {
                               ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n",
+get_header(&p->initreq, "From"));
                               set_destroy(p);

Comments:By: Olle Johansson (oej) 2006-12-27 10:07:33.000-0600

When we send the second INVITE, we should move Invitestate back really. That must be a better fix.

By: Olle Johansson (oej) 2006-12-27 10:12:52.000-0600

Added a fix to 1.4 rev 48977. Thanks.