diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 2f9e0958ec7714eb9f0f15e57b60210207d13a84..87226a6d789f1e590fb435ea5c5400faac71741b 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -10799,12 +10799,40 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req, ast_set_flag(p, SIP_NEEDDESTROY); return 0; } else { + struct sip_pvt *p_old; + transmit_response(p, "200 OK", req); transmit_state_notify(p, firststate, 1, 1); /* Send first notification */ append_history(p, "Subscribestatus", ast_extension_state2str(firststate)); + + /* 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) + */ + ast_mutex_lock(&iflock); + for (p_old = iflist; p_old; p_old = p_old->next) { + if (p_old == p) + continue; + if (p_old->initreq.method != SIP_SUBSCRIBE) + continue; + if (p_old->subscribed == NONE) + continue; + ast_mutex_lock(&p_old->lock); + if (!strcmp(p_old->username, p->username)) { + if (!strcmp(p_old->exten, p->exten) && + !strcmp(p_old->context, p->context)) { + ast_set_flag(p_old, SIP_NEEDDESTROY); + ast_mutex_unlock(&p_old->lock); + break; + } + } + ast_mutex_unlock(&p_old->lock); + } + ast_mutex_unlock(&iflock); } if (!p->expiry) - ast_set_flag(p, SIP_NEEDDESTROY); + ast_set_flag(p, SIP_NEEDDESTROY); } return 1; }