mirror of https://github.com/libp2p/go-libp2p.git
Marten Seemann
5 years ago
7 changed files with 165 additions and 99 deletions
@ -1,8 +1,9 @@ |
|||
// +build !linux
|
|||
// +build !windows
|
|||
|
|||
package libp2pquic |
|||
|
|||
import "github.com/vishvananda/netlink/nl" |
|||
|
|||
// nl.SupportedNlFamilies is the default netlink families used by the netlink package
|
|||
// SupportedNlFamilies is the default netlink families used by the netlink package
|
|||
var SupportedNlFamilies = nl.SupportedNlFamilies |
|||
|
@ -0,0 +1,42 @@ |
|||
// +build linux
|
|||
|
|||
package libp2pquic |
|||
|
|||
import ( |
|||
"net" |
|||
|
|||
. "github.com/onsi/ginkgo" |
|||
. "github.com/onsi/gomega" |
|||
) |
|||
|
|||
var _ = Describe("Reuse (on Linux)", func() { |
|||
var reuse *reuse |
|||
|
|||
BeforeEach(func() { |
|||
var err error |
|||
reuse, err = newReuse() |
|||
Expect(err).ToNot(HaveOccurred()) |
|||
}) |
|||
|
|||
Context("creating and reusing connections", func() { |
|||
AfterEach(func() { closeAllConns(reuse) }) |
|||
|
|||
It("reuses a connection it created for listening on a specific interface", func() { |
|||
raddr, err := net.ResolveUDPAddr("udp4", "1.1.1.1:1234") |
|||
Expect(err).ToNot(HaveOccurred()) |
|||
ips, err := reuse.getSourceIPs("udp4", raddr) |
|||
Expect(err).ToNot(HaveOccurred()) |
|||
Expect(ips).ToNot(BeEmpty()) |
|||
// listen
|
|||
addr, err := net.ResolveUDPAddr("udp4", ips[0].String()+":0") |
|||
Expect(err).ToNot(HaveOccurred()) |
|||
lconn, err := reuse.Listen("udp4", addr) |
|||
Expect(err).ToNot(HaveOccurred()) |
|||
Expect(lconn.GetCount()).To(Equal(1)) |
|||
// dial
|
|||
conn, err := reuse.Dial("udp4", raddr) |
|||
Expect(err).ToNot(HaveOccurred()) |
|||
Expect(conn.GetCount()).To(Equal(2)) |
|||
}) |
|||
}) |
|||
}) |
@ -0,0 +1,66 @@ |
|||
// +build !windows
|
|||
|
|||
package libp2pquic |
|||
|
|||
import ( |
|||
"net" |
|||
|
|||
"github.com/vishvananda/netlink" |
|||
) |
|||
|
|||
type reuse struct { |
|||
reuseBase |
|||
|
|||
handle *netlink.Handle // Only set on Linux. nil on other systems.
|
|||
} |
|||
|
|||
func newReuse() (*reuse, error) { |
|||
handle, err := netlink.NewHandle(SupportedNlFamilies...) |
|||
if err == netlink.ErrNotImplemented { |
|||
handle = nil |
|||
} else if err != nil { |
|||
return nil, err |
|||
} |
|||
return &reuse{ |
|||
reuseBase: newReuseBase(), |
|||
handle: handle, |
|||
}, nil |
|||
} |
|||
|
|||
// Get the source IP that the kernel would use for dialing.
|
|||
// This only works on Linux.
|
|||
// On other systems, this returns an empty slice of IP addresses.
|
|||
func (r *reuse) getSourceIPs(network string, raddr *net.UDPAddr) ([]net.IP, error) { |
|||
if r.handle == nil { |
|||
return nil, nil |
|||
} |
|||
|
|||
routes, err := r.handle.RouteGet(raddr.IP) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
ips := make([]net.IP, 0, len(routes)) |
|||
for _, route := range routes { |
|||
ips = append(ips, route.Src) |
|||
} |
|||
return ips, nil |
|||
} |
|||
|
|||
func (r *reuse) Dial(network string, raddr *net.UDPAddr) (*reuseConn, error) { |
|||
ips, err := r.getSourceIPs(network, raddr) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
|
|||
r.mutex.Lock() |
|||
defer r.mutex.Unlock() |
|||
|
|||
conn, err := r.dialLocked(network, raddr, ips) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
conn.IncreaseCount() |
|||
r.maybeStartGarbageCollector() |
|||
return conn, nil |
|||
} |
@ -0,0 +1,26 @@ |
|||
// +build windows
|
|||
|
|||
package libp2pquic |
|||
|
|||
import "net" |
|||
|
|||
type reuse struct { |
|||
reuseBase |
|||
} |
|||
|
|||
func newReuse() (*reuse, error) { |
|||
return &reuse{reuseBase: newReuseBase()}, nil |
|||
} |
|||
|
|||
func (r *reuse) Dial(network string, raddr *net.UDPAddr) (*reuseConn, error) { |
|||
r.mutex.Lock() |
|||
defer r.mutex.Unlock() |
|||
|
|||
conn, err := r.dialLocked(network, raddr, nil) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
conn.IncreaseCount() |
|||
r.maybeStartGarbageCollector() |
|||
return conn, nil |
|||
} |
Loading…
Reference in new issue