Skip to content
This repository has been archived by the owner on May 26, 2022. It is now read-only.

Commit

Permalink
reuse the same router until we change listeners
Browse files Browse the repository at this point in the history
Technically, someone can set net.ipv4.ip_nonlocal_bind=1 to bind to
non-existent IP addresses, but I'm comfortable making this change and
seeing if anyone complains. I highly doubt it'll have any impact.

If it doesn't work out, we have other options (e.g., catch the "invalid
route" error and try again).

fixes #238
  • Loading branch information
Stebalien committed Oct 28, 2021
1 parent 2e302b1 commit 2a1fb10
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 1 deletion.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ go 1.16

require (
github.com/golang/mock v1.6.0
github.com/google/gopacket v1.1.17
github.com/ipfs/go-log v1.0.4
github.com/klauspost/compress v1.11.7
github.com/libp2p/go-libp2p-core v0.10.0
Expand Down
24 changes: 23 additions & 1 deletion reuse.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"sync"
"time"

"github.com/google/gopacket/routing"
"github.com/libp2p/go-netroute"
)

Expand Down Expand Up @@ -54,6 +55,7 @@ type reuse struct {
closeChan chan struct{}
gcStopChan chan struct{}

routes routing.Router
unicast map[string] /* IP.String() */ map[int] /* port */ *reuseConn
// global contains connections that are listening on 0.0.0.0 / ::
global map[int]*reuseConn
Expand Down Expand Up @@ -108,6 +110,15 @@ func (r *reuse) gc() {
}
if len(conns) == 0 {
delete(r.unicast, ukey)
// If we've dropped all connections with a unicast binding,
// assume our routes may have changed.
if len(r.unicast) == 0 {
r.routes = nil
} else {
// Ignore the error, there's nothing we can do about
// it.
r.routes, _ = netroute.New()
}
}
}
r.mutex.Unlock()
Expand All @@ -117,7 +128,15 @@ func (r *reuse) gc() {

func (r *reuse) Dial(network string, raddr *net.UDPAddr) (*reuseConn, error) {
var ip *net.IP
if router, err := netroute.New(); err == nil {

// Only bother looking up the source address if we actually _have_ non 0.0.0.0 listeners.
// Otherwise, save some time.

r.mutex.Lock()
router := r.routes
r.mutex.Unlock()

if router != nil {
_, _, src, err := router.Route(raddr.IP)
if err == nil && !src.IsUnspecified() {
ip = &src
Expand Down Expand Up @@ -194,6 +213,9 @@ func (r *reuse) Listen(network string, laddr *net.UDPAddr) (*reuseConn, error) {
// Deal with listen on a unicast address
if _, ok := r.unicast[localAddr.IP.String()]; !ok {
r.unicast[localAddr.IP.String()] = make(map[int]*reuseConn)
// Assume the system's routes may have changed if we're adding a new listener.
// Ignore the error, there's nothing we can do.
r.routes, _ = netroute.New()
}

// The kernel already checked that the laddr is not already listen
Expand Down

0 comments on commit 2a1fb10

Please sign in to comment.