Commit c8594db0 authored by Steven Allen's avatar Steven Allen

try to pick the best NAT when multiple NATs are discovered

parent 943d7b39
......@@ -8,6 +8,8 @@ import (
"math/rand"
"net"
"time"
"github.com/jackpal/gateway"
)
var ErrNoExternalAddress = errors.New("no external address")
......@@ -88,11 +90,37 @@ func DiscoverNATs(ctx context.Context) <-chan NAT {
func DiscoverGateway() (NAT, error) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
nat := <-DiscoverNATs(ctx)
if nat == nil {
var nats []NAT
for nat := range DiscoverNATs(ctx) {
nats = append(nats, nat)
}
switch len(nats) {
case 0:
return nil, ErrNoNATFound
case 1:
return nats[0], nil
}
gw, _ := gateway.DiscoverGateway()
bestNAT := nats[0]
natGw, _ := bestNAT.GetDeviceAddress()
bestNATIsGw := gw != nil && natGw.Equal(gw)
// 1. Prefer gateways discovered _last_. This is an OK heuristic for
// discovering the most-upstream (furthest) NAT.
// 2. Prefer gateways that actually match our known gateway address.
// Some relays like to claim to be NATs even if they aren't.
for _, nat := range nats[1:] {
natGw, _ := nat.GetDeviceAddress()
natIsGw := gw != nil && natGw.Equal(gw)
if bestNATIsGw && !natIsGw {
continue
}
bestNATIsGw = natIsGw
bestNAT = nat
}
return nat, nil
return bestNAT, nil
}
func randomPort() int {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment