summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamian Ivereigh <damo@launtel.net.au>2015-06-11 23:18:48 +1000
committerDamian Ivereigh <damo@launtel.net.au>2015-06-12 23:54:56 +1000
commit3f57f3f8ec63752ccd1d87d7c6737f64043cb8a9 (patch)
tree6727e31456ebc88fc7ee997d60d36b7d59530e6d
parent006930ee51919ee47abe0f7c7a8469cff0d31e9f (diff)
chan_sip.c: Update dialog fromtag after request with auth
If a client sends and INVITE which is 401 rejected, then subsequently sends a new INVITE with the auth info and uses a different fromtag from the first INVITE, Asterisk will accept the new INVITE as part of the original dialog - match_req_to_dialog() specifically ignores the fromtag. However it does not update the stored dialog with the new fromtag. This results in Asterisk being unable to match future packets that are part of this dialog (such as the ACK to the OK or the OK to the BYE), and the call is dropped. This problem was originally found when using an NEC-i SV8100-GE (NEC SIP Card). * After a successful match of a packet to the dialog, if the packet is not a SIP_RESPONSE, authentication is present and the fromtags are different, the stored fromtag is updated with the one from the recent INVITE. ASTERISK-25154 #close Reported by: Damian Ivereigh Tested by: Damian Ivereigh Change-Id: I5c16cf3b409e5ef9f2b2fe974b6bd2a45a6aa17e
-rw-r--r--channels/chan_sip.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 5be0200ed..ff0067dcd 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -9240,6 +9240,15 @@ static struct sip_pvt *__find_call(struct sip_request *req, struct ast_sockaddr
switch (found) {
case SIP_REQ_MATCH:
+ sip_pvt_lock(sip_pvt_ptr);
+ if (args.method != SIP_RESPONSE && args.authentication_present
+ && strcmp(args.fromtag, sip_pvt_ptr->theirtag)) {
+ /* If we have a request that uses athentication and the fromtag is
+ * different from that in the original call dialog, update the
+ * fromtag in the saved call dialog */
+ ast_string_field_set(sip_pvt_ptr, theirtag, args.fromtag);
+ }
+ sip_pvt_unlock(sip_pvt_ptr);
ao2_iterator_destroy(iterator);
dialog_unref(fork_pvt, "unref fork_pvt");
free_via(via);