From d5d41741ccdeee4432595fea1305714bea5e44ae Mon Sep 17 00:00:00 2001 From: Matthew Jordan Date: Tue, 31 Jul 2012 21:20:59 +0000 Subject: Schedule pokes of registered SIP peers within a given timespan after SIP reload With a large number of SIP peers registered, performing a SIP reload causes a flood of SIP OPTIONS request packets. These are immediately sent out, and, as responses come back, can cause peers to be flagged as 'lagged' due to handling of the many response messages. This fix prevents this "packet storm" and schedules the pokes for a random time. That time varies between 1 ms and the peer's qualify time, or, if the qualify time is unknown, the global qualifyfreq setting. The committed patch has some very small modifications to the patch schmidts wrote for the review. (closes issue ASTERISK-19154) Reported by: Nicolo Mazzon patches: issue19154.patch license #6034 uploaded by schmidts Review: https://reviewboard.asterisk.org/r/1652 ........ Merged revisions 370666 from http://svn.asterisk.org/svn/asterisk/branches/1.8 ........ Merged revisions 370672 from http://svn.asterisk.org/svn/asterisk/branches/10 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@370677 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- channels/chan_sip.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 367aeee8e..8773ae8e7 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -15041,14 +15041,14 @@ static void reg_source_db(struct sip_peer *peer) peer->name, peer->username, ast_sockaddr_stringify_host(&sa), expire); ast_sockaddr_copy(&peer->addr, &sa); - if (sipsock < 0) { - /* SIP isn't up yet, so schedule a poke only, pretty soon */ - AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, ast_random() % 5000 + 1, sip_poke_peer_s, peer, + if (peer->maxms) { + /* Don't poke peer immediately, just schedule it within qualifyfreq */ + AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, + ast_random() % ((peer->qualifyfreq) ? peer->qualifyfreq : global_qualifyfreq) + 1, + sip_poke_peer_s, peer, sip_unref_peer(_data, "removing poke peer ref"), sip_unref_peer(peer, "removing poke peer ref"), sip_ref_peer(peer, "adding poke peer ref")); - } else { - sip_poke_peer(peer, 0); } AST_SCHED_REPLACE_UNREF(peer->expire, sched, (expire + 10) * 1000, expire_register, peer, sip_unref_peer(_data, "remove registration ref"), @@ -31886,16 +31886,19 @@ static void sip_poke_all_peers(void) i = ao2_iterator_init(peers, 0); while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) { ao2_lock(peer); - if (num == global_qualify_peers) { - ms += global_qualify_gap; - num = 0; - } else { - num++; + /* Don't schedule poking on a peer without qualify */ + if (peer->maxms) { + if (num == global_qualify_peers) { + ms += global_qualify_gap; + num = 0; + } else { + num++; + } + AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, ms, sip_poke_peer_s, peer, + sip_unref_peer(_data, "removing poke peer ref"), + sip_unref_peer(peer, "removing poke peer ref"), + sip_ref_peer(peer, "adding poke peer ref")); } - AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, ms, sip_poke_peer_s, peer, - sip_unref_peer(_data, "removing poke peer ref"), - sip_unref_peer(peer, "removing poke peer ref"), - sip_ref_peer(peer, "adding poke peer ref")); ao2_unlock(peer); sip_unref_peer(peer, "toss iterator peer ptr"); } -- cgit v1.2.3