From b3081eb9813dfcf260321bd67bd48a6eacdc3963 Mon Sep 17 00:00:00 2001 From: iczero <iczero4@gmail.com> Date: Wed, 26 Feb 2020 01:54:45 -0500 Subject: [PATCH] Prefer routes with lowest rtt --- src/subnet.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/src/subnet.c b/src/subnet.c index fe7d23efb..99c2bed43 100644 --- a/src/subnet.c +++ b/src/subnet.c @@ -263,17 +263,39 @@ subnet_t *lookup_subnet_ipv4(const ipv4_t *address) { // Search all subnets for a matching one + int last_rtt = INT_MAX; // current smallest rtt seen + for splay_each(subnet_t, p, &subnet_tree) { if(!p || p->type != SUBNET_IPV4) { continue; } if(!maskcmp(address, &p->net.ipv4.address, p->net.ipv4.prefixlength)) { - r = p; - - if(!p->owner || p->owner->status.reachable) { + if(!p->owner) { + // this is a broadcast subnet + r = p; break; } + + if(p->owner->status.reachable) { + int rtt = INT_MAX - 1; // use INT_MAX - 1 as rtt for nodes not directly reachable + + if(p->owner->udp_ping_rtt != -1) { + rtt = p->owner->udp_ping_rtt; + } else if(p->owner == myself) { + // we have this subnet, don't route it somewhere else + r = p; + break; + } + + if(rtt < last_rtt) { + r = p; + last_rtt = rtt; + } + } + } else if(r) { + // no more matching subnets + break; } } @@ -297,17 +319,39 @@ subnet_t *lookup_subnet_ipv6(const ipv6_t *address) { // Search all subnets for a matching one + int last_rtt = INT_MAX; // current smallest rtt seen + for splay_each(subnet_t, p, &subnet_tree) { if(!p || p->type != SUBNET_IPV6) { continue; } if(!maskcmp(address, &p->net.ipv6.address, p->net.ipv6.prefixlength)) { - r = p; - - if(!p->owner || p->owner->status.reachable) { + if(!p->owner) { + // this is a broadcast subnet + r = p; break; } + + if(p->owner->status.reachable) { + int rtt = INT_MAX - 1; // use INT_MAX - 1 as rtt for nodes not directly reachable + + if(p->owner->udp_ping_rtt != -1) { + rtt = p->owner->udp_ping_rtt; + } else if(p->owner == myself) { + // we have this subnet, don't route it somewhere else + r = p; + break; + } + + if(rtt < last_rtt) { + r = p; + last_rtt = rtt; + } + } + } else if(r) { + // no more matching subnets + break; } }