diff --git a/addrs.go b/addrs.go new file mode 100644 index 0000000000000000000000000000000000000000..ed510f26264af8c6c337a58b09e8992d09f70c78 --- /dev/null +++ b/addrs.go @@ -0,0 +1,35 @@ +package swarm + +import ( + mafilter "github.com/libp2p/go-maddr-filter" + mamask "github.com/whyrusleeping/multiaddr-filter" +) + +// http://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml +var lowTimeoutFilters = mafilter.NewFilters() + +func init() { + for _, p := range []string{ + "/ip4/10.0.0.0/ipcidr/8", + "/ip4/100.64.0.0/ipcidr/10", + "/ip4/169.254.0.0/ipcidr/16", + "/ip4/172.16.0.0/ipcidr/12", + "/ip4/192.0.0.0/ipcidr/24", + "/ip4/192.0.0.0/ipcidr/29", + "/ip4/192.0.0.8/ipcidr/32", + "/ip4/192.0.0.170/ipcidr/32", + "/ip4/192.0.0.171/ipcidr/32", + "/ip4/192.0.2.0/ipcidr/24", + "/ip4/192.168.0.0/ipcidr/16", + "/ip4/198.18.0.0/ipcidr/15", + "/ip4/198.51.100.0/ipcidr/24", + "/ip4/203.0.113.0/ipcidr/24", + "/ip4/240.0.0.0/ipcidr/4", + } { + f, err := mamask.NewMask(p) + if err != nil { + panic("error in lowTimeoutFilters init: " + err.Error()) + } + lowTimeoutFilters.AddDialFilter(f) + } +} diff --git a/limiter.go b/limiter.go index 3d3437b95f8c35cc9831984b42fb64e8b39fa88c..a740e27efd29f8f53031c69a0b2373781687f65f 100644 --- a/limiter.go +++ b/limiter.go @@ -3,6 +3,7 @@ package swarm import ( "context" "sync" + "time" addrutil "github.com/libp2p/go-addr-util" peer "github.com/libp2p/go-libp2p-peer" @@ -33,6 +34,15 @@ func (dj *dialJob) cancelled() bool { } } +func (dj *dialJob) dialTimeout() time.Duration { + timeout := DialTimeout + if lowTimeoutFilters.AddrBlocked(dj.addr) { + timeout = DialTimeoutLocal + } + + return timeout +} + type dialLimiter struct { rllock sync.Mutex fdConsuming int @@ -162,7 +172,10 @@ func (dl *dialLimiter) executeDial(j *dialJob) { return } - con, err := dl.dialFunc(j.ctx, j.peer, j.addr) + dctx, cancel := context.WithTimeout(j.ctx, j.dialTimeout()) + defer cancel() + + con, err := dl.dialFunc(dctx, j.peer, j.addr) select { case j.resp <- dialResult{Conn: con, Addr: j.addr, Err: err}: case <-j.ctx.Done(): diff --git a/swarm.go b/swarm.go index dbf81613f9811452e44d472f01b58b971b841768..002abd2d9f1fe4edc0a31042e39ed5695371f33a 100644 --- a/swarm.go +++ b/swarm.go @@ -22,9 +22,15 @@ import ( ) // DialTimeout is the maximum duration a Dial is allowed to take. +// This includes the time spent waiting in dial limiter, between dialing the raw +// network connection, protocol selection as well the handshake, if applicable. +var DialTimeout = 60 * time.Second + +// DialTimeoutLocal is the maximum duration a Dial to local network address +// is allowed to take. // This includes the time between dialing the raw network connection, // protocol selection as well the handshake, if applicable. -var DialTimeout = 60 * time.Second +var DialTimeoutLocal = 5 * time.Second var log = logging.Logger("swarm2")