]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
don't iterate through all dialogs to find and delete old subscribes
authorStefan Schmidt <sst@sil.at>
Fri, 1 Oct 2010 09:42:22 +0000 (09:42 +0000)
committerStefan Schmidt <sst@sil.at>
Fri, 1 Oct 2010 09:42:22 +0000 (09:42 +0000)
On every incoming subscribe there is a iteration through all dialogs to find old subscribes and delete them. This is slow and not RFC conform. This was only needed in 1.2 cause a subscribe was not deleted when a dialog was destroyed, after 1.4 a subscribe get removed when its dialog is destroyed.

(closes issue #17950)
Reported by: schmidts
Tested by: schmidts

Review: https://reviewboard.asterisk.org/r/901/

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

channels/chan_sip.c

index eedac8f0482ed42102b24d9efb6235b1a4a03938..ba8d5250c124329ea40a6a8890b57dbb833bd43d 100644 (file)
@@ -18641,6 +18641,8 @@ static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_
                                handle_response_refer(p, resp, rest, req, seqno);
                        } else if (sipmethod == SIP_SUBSCRIBE) {
                                handle_response_subscribe(p, resp, rest, req, seqno);
+                       } else if (sipmethod == SIP_NOTIFY) {
+                               pvt_set_needdestroy(p, "received 481 response");
                        } else if (sipmethod == SIP_BYE) {
                                /* The other side has no transaction to bye,
                                just assume it's all right then */
@@ -18840,6 +18842,8 @@ static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_
                                handle_response_invite(p, resp, rest, req, seqno);
                        } else if (sipmethod == SIP_BYE) {
                                pvt_set_needdestroy(p, "received 481 response");
+                       } else if (sipmethod == SIP_NOTIFY) {
+                               pvt_set_needdestroy(p, "received 481 response");
                        } else if (sipdebug) {
                                ast_debug(1, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid);
                        }
@@ -21366,7 +21370,6 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req,
        const char *eventheader = get_header(req, "Event");     /* Get Event package name */
        int resubscribe = (p->subscribed != NONE);
        char *temp, *event;
-       struct ao2_iterator i;
 
        if (p->initreq.headers) {       
                /* We already have a dialog */
@@ -21667,7 +21670,6 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req,
                                ao2_unlock(p->relatedpeer);
                        }
                } else {
-                       struct sip_pvt *p_old;
 
                        if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) {
 
@@ -21682,40 +21684,8 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req,
                        append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate));
                        /* hide the 'complete' exten/context in the refer_to field for later display */
                        ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context);
+                       /* Deleted the slow iteration of all sip dialogs to find old subscribes from this peer for exten@context */
 
-                       /* remove any old subscription from this peer for the same exten/context,
-                       as the peer has obviously forgotten about it and it's wasteful to wait
-                       for it to expire and send NOTIFY messages to the peer only to have them
-                       ignored (or generate errors)
-                       */
-                       i = ao2_iterator_init(dialogs, 0);
-                       while ((p_old = ao2_t_iterator_next(&i, "iterate thru dialogs"))) {
-                               if (p_old == p) {
-                                       ao2_t_ref(p_old, -1, "toss dialog ptr from iterator_next before continue");
-                                       continue;
-                               }
-                               if (p_old->initreq.method != SIP_SUBSCRIBE) {
-                                       ao2_t_ref(p_old, -1, "toss dialog ptr from iterator_next before continue");
-                                       continue;
-                               }
-                               if (p_old->subscribed == NONE) {
-                                       ao2_t_ref(p_old, -1, "toss dialog ptr from iterator_next before continue");
-                                       continue;
-                               }
-                               sip_pvt_lock(p_old);
-                               if (!strcmp(p_old->username, p->username)) {
-                                       if (!strcmp(p_old->exten, p->exten) &&
-                                           !strcmp(p_old->context, p->context)) {
-                                               pvt_set_needdestroy(p_old, "replacing subscription");
-                                               sip_pvt_unlock(p_old);
-                                               ao2_t_ref(p_old, -1, "toss dialog ptr from iterator_next before break");
-                                               break;
-                                       }
-                               }
-                               sip_pvt_unlock(p_old);
-                               ao2_t_ref(p_old, -1, "toss dialog ptr from iterator_next");
-                       }
-                       ao2_iterator_destroy(&i);
                }
                if (!p->expiry) {
                        pvt_set_needdestroy(p, "forcing expiration");