]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
chan_sip: Reject calls without prior SDP on 200 OK
authorJonathan Rose <jrose@digium.com>
Wed, 11 Sep 2013 19:56:48 +0000 (19:56 +0000)
committerJonathan Rose <jrose@digium.com>
Wed, 11 Sep 2013 19:56:48 +0000 (19:56 +0000)
If we receive a 200 OK without SDP, we will now check to see if
the remote address has been established for that channel's RTP
session and if the to tag for that channel has changed from
the most recent to tag in a response less than 200.
If either a change has been made since the last to-tag was
received or the remote address is unset, then we will drop
the call.

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

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

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

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

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

index bec53b776de66de51fca49af0be0335621551832..4210322c6a7f06587a0398fb9d5d31f93234b864 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] */