From 80c443bea4cfb0d028b8cd501f38713732655e68 Mon Sep 17 00:00:00 2001 From: Matthew Jordan <mjordan@digium.com> Date: Fri, 10 Apr 2015 12:40:36 +0000 Subject: [PATCH] channels/chan_iax2: Improve POKE expiration time calculation for lossy networks POKE is used to check for peer availability; however, in networks with packet loss, the current calculations may result in POKE expiration times that are too short. This patch alters the expiration/retry time logic to take into account the last known qualify round trip time, as opposed to always using a static value for each peer. Review: https://reviewboard.asterisk.org/r/4536 ASTERISK-22352 #close Reported by: Frederic Van Espen ASTERISK-24894 #close Reported by: Y Ateya patches: poke_noanswer_duration.diff submitted by Y Ateya (License 6693) ........ Merged revisions 434564 from http://svn.asterisk.org/svn/asterisk/branches/11 ........ Merged revisions 434565 from http://svn.asterisk.org/svn/asterisk/branches/13 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@434566 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- channels/chan_iax2.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index 5e3656f0db..771f7706d7 100644 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -12302,6 +12302,7 @@ static int iax2_poke_peer_cb(void *obj, void *arg, int flags) static int iax2_poke_peer(struct iax2_peer *peer, int heldcall) { int callno; + int poke_timeout; if (!peer->maxms || (ast_sockaddr_isnull(&peer->addr) && !peer->dnsmgr)) { /* IF we have no IP without dnsmgr, or this isn't to be monitored, return @@ -12337,12 +12338,24 @@ static int iax2_poke_peer(struct iax2_peer *peer, int heldcall) } } + if (peer->lastms < 0){ + /* If the host is already unreachable then use time less than the unreachable + * interval. 5/6 is arbitrary multiplier to get value less than + * peer->pokefreqnotok. Value less than peer->pokefreqnotok is used to expire + * current POKE before starting new POKE (which is scheduled after + * peer->pokefreqnotok). */ + poke_timeout = peer->pokefreqnotok * 5 / 6; + } else { + /* If the host is reachable, use timeout large enough to allow for multiple + * POKE retries. Limit this value to less than peer->pokefreqok. 5/6 is arbitrary + * multiplier to get value less than peer->pokefreqok. Value less than + * peer->pokefreqok is used to expire current POKE before starting new POKE + * (which is scheduled after peer->pokefreqok). */ + poke_timeout = MIN(MAX_RETRY_TIME * 2 + peer->maxms, peer->pokefreqok * 5 / 6); + } + /* Queue up a new task to handle no reply */ - /* If the host is already unreachable then use the unreachable interval instead */ - if (peer->lastms < 0) - peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer)); - else - peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer)); + peer->pokeexpire = iax2_sched_add(sched, poke_timeout, iax2_poke_noanswer, peer_ref(peer)); if (peer->pokeexpire == -1) peer_unref(peer); @@ -12356,7 +12369,7 @@ static int iax2_poke_peer(struct iax2_peer *peer, int heldcall) }; /* Speed up retransmission times for this qualify call */ - iaxs[callno]->pingtime = peer->maxms / 4 + 1; + iaxs[callno]->pingtime = peer->maxms / 8; iaxs[callno]->peerpoke = peer; add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ -- GitLab