channels/chan_iax2: Improve POKE expiration time calculation for lossy networks
authorMatthew Jordan <mjordan@digium.com>
Fri, 10 Apr 2015 12:40:36 +0000 (12:40 +0000)
committerMatthew Jordan <mjordan@digium.com>
Fri, 10 Apr 2015 12:40:36 +0000 (12:40 +0000)
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

index 5e3656f..771f770 100644 (file)
@@ -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 */