From 79e1ec6fc18adb89bbec4b3d62f00a62376f8517 Mon Sep 17 00:00:00 2001 From: Jonathan Rose Date: Wed, 11 Sep 2013 19:39:36 +0000 Subject: [PATCH] chan_sip: Reject calls without prior SDP on 200 OK 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 git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@398835 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- channels/chan_sip.c | 13 +++++++++++++ channels/sip/include/sip.h | 1 + 2 files changed, 14 insertions(+) diff --git a/channels/chan_sip.c b/channels/chan_sip.c index cd7c70e03c..612b9dc239 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -20907,6 +20907,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) { @@ -21762,7 +21771,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. diff --git a/channels/sip/include/sip.h b/channels/sip/include/sip.h index 75730e60e0..ec9984616a 100644 --- a/channels/sip/include/sip.h +++ b/channels/sip/include/sip.h @@ -967,6 +967,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] */