diff -d -u -r1.1.1.3 chan_sip.c --- channels/chan_sip.c 23 Apr 2008 14:24:27 -0000 1.1.1.3 +++ channels/chan_sip.c 18 Nov 2008 16:28:30 -0000 @@ -795,6 +796,7 @@ #define SIP_PAGE2_RFC2833_COMPENSATE (1 << 25) /*!< 25: ???? */ #define SIP_PAGE2_BUGGY_MWI (1 << 26) /*!< 26: Buggy CISCO MWI fix */ #define SIP_PAGE2_OUTGOING_CALL (1 << 27) /*!< 27: Is this an outgoing call? */ +#define SIP_PAGE2_GOT_OK_FOR_INVITE (1 << 31) /*!< 31: Got OK for INVITE? */ #define SIP_PAGE2_FLAGS_TO_COPY \ (SIP_PAGE2_ALLOWSUBSCRIBE | SIP_PAGE2_ALLOWOVERLAP | SIP_PAGE2_VIDEOSUPPORT | \ @@ -12266,6 +12306,7 @@ } if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->owner) { + ast_set_flag(&p->flags[1], SIP_PAGE2_GOT_OK_FOR_INVITE); if (!reinvite) { ast_queue_control(p->owner, AST_CONTROL_ANSWER); } else { /* RE-invite */ @@ -13763,6 +13805,20 @@ /* Check if this is a loop */ if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->owner->_state != AST_STATE_UP)) { + /* Loop mis-detection prevention hack: Is this a re-INVITE that came too early for us, + * i.e., after we got the OK but before the dialing thread read the ANSWER control + * frame? If this situation is detected, we fake that the re-INVITE request packet was + * never received and hope that the channel is UP when the packet is retransmitted by + * the other side. WARNING: it is untested what happens if the other side does not + * retransmit the request. + */ + if (ast_test_flag(&p->flags[1], SIP_PAGE2_GOT_OK_FOR_INVITE)) { + ast_log(LOG_WARNING, "Ignoring re-INVITE on %s to prevent loop mis-detection (got OK but channel is not UP yet).\n", p->owner->name); + /* Do not send anything back but decrement the incoming sequence counter, + * otherweise the retransmitted re-INVITE will be ignored. */ + --p->icseq; + return 0; + } /* This is a call to ourself. Send ourselves an error code and stop processing immediately, as SIP really has no good mechanism for being able to call yourself */