]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
chan_sip: Reject calls on 200 OKs if no SDP has been received
authorJonathan Rose <jrose@digium.com>
Fri, 27 Sep 2013 17:34:39 +0000 (17:34 +0000)
committerJonathan Rose <jrose@digium.com>
Fri, 27 Sep 2013 17:34:39 +0000 (17:34 +0000)
When Asterisk receives a 200 OK in response to an invite, that peer should have
sent an SDP at some point by then. If the channel has never received an SDP,
media won't have been set and the remote address won't be known. Endpoints in
general should not be doing this. This patch makes it so that Asterisk will
simply hang up a call if it sends a 200 OK at this point. So far this odd
behavior for endpoints has only been observed in tests which involved manually
created SIP transactions in SIPp.

(closes issue ASTERISK-22424)
Reported by: Jonathan Rose
Review: https://reviewboard.asterisk.org/r/2827/
........

Merged revisions 399939 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........

Merged revisions 399962 from http://svn.asterisk.org/svn/asterisk/branches/11

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/12@399976 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_sip.c
channels/sip/include/sip.h

index aaae83c6f864dfb679ea18dc3a2a10ac9723cabe..17083c6a0fc23936c3c2ffded718040a393bc871 100644 (file)
@@ -23250,6 +23250,15 @@ static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest
                                        ast_set_flag(&p->flags[0], SIP_PENDINGBYE);
                                }
                        ast_rtp_instance_activate(p->rtp);
+               } else if (!reinvite) {
+                       struct ast_sockaddr remote_address = {{0,}};
+
+                       ast_rtp_instance_get_remote_address(p->rtp, &remote_address);
+                       if (ast_sockaddr_isnull(&remote_address) || (!ast_strlen_zero(p->theirprovtag) && strcmp(p->theirtag, p->theirprovtag))) {
+                               ast_log(LOG_WARNING, "Received response: \"200 OK\" from '%s' without SDP\n", p->relatedpeer->name);
+                               ast_set_flag(&p->flags[0], SIP_PENDINGBYE);
+                               ast_rtp_instance_activate(p->rtp);
+                       }
                }
 
                if (!req->ignore && p->owner) {
@@ -24200,7 +24209,11 @@ static void handle_response(struct sip_pvt *p, int resp, const char *rest, struc
 
                gettag(req, "To", tag, sizeof(tag));
                ast_string_field_set(p, theirtag, tag);
+       } else {
+               /* Store theirtag to track for changes when 200 responses to invites are received without SDP */
+               ast_string_field_set(p, theirprovtag, p->theirtag);
        }
+
        /* This needs to be configurable on a channel/peer level,
           not mandatory for all communication. Sadly enough, NAT implementations
           are not so stable so we can always rely on these headers.
index c0704ec79f29076b2f726a7f360970af3e49700e..342c87b364ccb27864f550828d2d263e792c4034 100644 (file)
@@ -1019,6 +1019,7 @@ struct sip_pvt {
                AST_STRING_FIELD(rdnis);        /*!< Referring DNIS */
                AST_STRING_FIELD(redircause);   /*!< Referring cause */
                AST_STRING_FIELD(theirtag);     /*!< Their tag */
+               AST_STRING_FIELD(theirprovtag); /*!< Provisional their tag, used when evaluating responses to invites */
                AST_STRING_FIELD(tag);          /*!< Our tag for this session */
                AST_STRING_FIELD(username);     /*!< [user] name */
                AST_STRING_FIELD(peername);     /*!< [peer] name, not set if [user] */