diff options
author | schmitds <schmitds@f38db490-d61c-443f-a65b-d21fe96a405b> | 2010-10-01 09:42:22 +0000 |
---|---|---|
committer | schmitds <schmitds@f38db490-d61c-443f-a65b-d21fe96a405b> | 2010-10-01 09:42:22 +0000 |
commit | 071ccecedff60f9a5cdc531666dc28cd98fc4b32 (patch) | |
tree | 0c46f433bd3efb9ad6b8cc41c76107142d936b7d | |
parent | dbe3ccd213efadb238a1f48f8b04c53b5505ff33 (diff) |
don't iterate through all dialogs to find and delete old subscribes
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: http://svn.digium.com/svn/asterisk/branches/1.8@289622 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r-- | channels/chan_sip.c | 41 |
1 files changed, 5 insertions, 36 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 5e612c052..f2b29897b 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -19754,6 +19754,8 @@ static void handle_response(struct sip_pvt *p, int resp, const char *rest, struc handle_response_invite(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 */ @@ -19953,6 +19955,8 @@ static void handle_response(struct sip_pvt *p, int resp, const char *rest, struc 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); } @@ -23011,7 +23015,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 */ @@ -23327,8 +23330,6 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req, ao2_unlock(p->relatedpeer); } } else if (p->subscribed != CALL_COMPLETION) { - struct sip_pvt *p_old; - if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) { ast_log(LOG_NOTICE, "Got SUBSCRIBE for extension %s@%s from %s, but there is no hint for that extension.\n", p->exten, p->context, ast_sockaddr_stringify(&p->sa)); @@ -23342,40 +23343,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"); |