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

gate QUIC connections via new ConnectionGater #152

Merged
merged 6 commits into from
May 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 67 additions & 11 deletions conn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,54 @@ import (
"io/ioutil"
mrand "math/rand"
"net"
"sync"
"sync/atomic"
"time"

"github.com/libp2p/go-libp2p-core/control"
ic "github.com/libp2p/go-libp2p-core/crypto"
"github.com/libp2p/go-libp2p-core/network"
"github.com/libp2p/go-libp2p-core/peer"
tpt "github.com/libp2p/go-libp2p-core/transport"
filter "github.com/libp2p/go-maddr-filter"

quicproxy "github.com/lucas-clemente/quic-go/integrationtests/tools/proxy"
ma "github.com/multiformats/go-multiaddr"
manet "github.com/multiformats/go-multiaddr-net"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

type mockGater struct {
lk sync.Mutex
acceptAll bool
blockedPeer peer.ID
}

func (c *mockGater) InterceptAccept(addrs network.ConnMultiaddrs) bool {
c.lk.Lock()
defer c.lk.Unlock()
return c.acceptAll || !manet.IsIPLoopback(addrs.RemoteMultiaddr())
}

func (c *mockGater) InterceptPeerDial(p peer.ID) (allow bool) {
return true
}

func (c *mockGater) InterceptAddrDial(peer.ID, ma.Multiaddr) (allow bool) {
return true
}

func (c *mockGater) InterceptSecured(_ network.Direction, p peer.ID, _ network.ConnMultiaddrs) (allow bool) {
c.lk.Lock()
defer c.lk.Unlock()
return !(p == c.blockedPeer)
}

func (c *mockGater) InterceptUpgraded(network.Conn) (allow bool, reason control.DisconnectReason) {
return true, 0
}

var _ = Describe("Connection", func() {
var (
serverKey, clientKey ic.PrivKey
Expand Down Expand Up @@ -165,18 +199,13 @@ var _ = Describe("Connection", func() {
Eventually(done).Should(BeClosed())
})

It("filters addresses", func() {
filters := filter.NewFilters()
ipNet := net.IPNet{
IP: net.IPv4(127, 0, 0, 1),
Mask: net.IPv4Mask(255, 255, 255, 255),
}
filters.AddFilter(ipNet, filter.ActionDeny)
It("gates accepted connections", func() {
testMA, err := ma.NewMultiaddr("/ip4/127.0.0.1/udp/1234/quic")
Expect(err).ToNot(HaveOccurred())
Expect(filters.AddrBlocked(testMA)).To(BeTrue())
cg := &mockGater{}
Expect(cg.InterceptAccept(&connAddrs{rmAddr: testMA})).To(BeFalse())

serverTransport, err := NewTransport(serverKey, nil, filters)
serverTransport, err := NewTransport(serverKey, nil, cg)
Expect(err).ToNot(HaveOccurred())
ln := runServer(serverTransport, "/ip4/127.0.0.1/udp/0/quic")
defer ln.Close()
Expand All @@ -192,7 +221,34 @@ var _ = Describe("Connection", func() {

// now allow the address and make sure the connection goes through
clientTransport.(*transport).clientConfig.HandshakeTimeout = 2 * time.Second
filters.AddFilter(ipNet, filter.ActionAccept)
cg.lk.Lock()
cg.acceptAll = true
cg.lk.Unlock()
conn, err := clientTransport.Dial(context.Background(), ln.Multiaddr(), serverID)
Expect(err).ToNot(HaveOccurred())
conn.Close()
})

It("gates secured connections", func() {
serverTransport, err := NewTransport(serverKey, nil, nil)
Expect(err).ToNot(HaveOccurred())
ln := runServer(serverTransport, "/ip4/127.0.0.1/udp/0/quic")
defer ln.Close()

cg := &mockGater{acceptAll: true, blockedPeer: serverID}
clientTransport, err := NewTransport(clientKey, nil, cg)
Expect(err).ToNot(HaveOccurred())

// make sure that connection attempts fails
clientTransport.(*transport).clientConfig.HandshakeTimeout = 250 * time.Millisecond
_, err = clientTransport.Dial(context.Background(), ln.Multiaddr(), serverID)
Expect(err).To(HaveOccurred())

// now allow the peerId and make sure the connection goes through
clientTransport.(*transport).clientConfig.HandshakeTimeout = 2 * time.Second
cg.lk.Lock()
cg.blockedPeer = "none"
cg.lk.Unlock()
conn, err := clientTransport.Dial(context.Background(), ln.Multiaddr(), serverID)
Expect(err).ToNot(HaveOccurred())
conn.Close()
Expand Down
36 changes: 30 additions & 6 deletions filtered_conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,38 @@ package libp2pquic
import (
"net"

filter "github.com/libp2p/go-maddr-filter"
"github.com/libp2p/go-libp2p-core/connmgr"

ma "github.com/multiformats/go-multiaddr"
)

type connAddrs struct {
lmAddr ma.Multiaddr
rmAddr ma.Multiaddr
}

func (c *connAddrs) LocalMultiaddr() ma.Multiaddr {
return c.lmAddr
}

func (c *connAddrs) RemoteMultiaddr() ma.Multiaddr {
return c.rmAddr
}

type filteredConn struct {
net.PacketConn

filters *filter.Filters
lmAddr ma.Multiaddr
gater connmgr.ConnectionGater
}

func newFilteredConn(c net.PacketConn, filters *filter.Filters) net.PacketConn {
return &filteredConn{PacketConn: c, filters: filters}
func newFilteredConn(c net.PacketConn, gater connmgr.ConnectionGater) net.PacketConn {
lmAddr, err := toQuicMultiaddr(c.LocalAddr())
if err != nil {
panic(err)
}

return &filteredConn{PacketConn: c, gater: gater, lmAddr: lmAddr}
}

func (c *filteredConn) ReadFrom(b []byte) (n int, addr net.Addr, rerr error) {
Expand All @@ -23,11 +44,14 @@ func (c *filteredConn) ReadFrom(b []byte) (n int, addr net.Addr, rerr error) {
if n < 1 || b[0]&0x80 == 0 {
return
}
maddr, err := toQuicMultiaddr(addr)
rmAddr, err := toQuicMultiaddr(addr)
if err != nil {
panic(err)
}
if !c.filters.AddrBlocked(maddr) {

connAddrs := &connAddrs{lmAddr: c.lmAddr, rmAddr: rmAddr}

if c.gater.InterceptAccept(connAddrs) {
return
}
raulk marked this conversation as resolved.
Show resolved Hide resolved
}
Expand Down
5 changes: 2 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@ go 1.13

require (
github.com/ipfs/go-log v1.0.4
github.com/libp2p/go-libp2p-core v0.5.3
github.com/libp2p/go-libp2p-core v0.5.6
github.com/libp2p/go-libp2p-tls v0.1.3
github.com/libp2p/go-maddr-filter v0.0.5
github.com/libp2p/go-netroute v0.1.2
github.com/lucas-clemente/quic-go v0.15.7
github.com/minio/sha256-simd v0.1.1
github.com/multiformats/go-multiaddr v0.2.1
github.com/multiformats/go-multiaddr v0.2.2
github.com/multiformats/go-multiaddr-fmt v0.1.0
github.com/multiformats/go-multiaddr-net v0.1.5
github.com/onsi/ginkgo v1.12.0
Expand Down
13 changes: 6 additions & 7 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -110,17 +110,15 @@ github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoR
github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8=
github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs=
github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco=
github.com/libp2p/go-libp2p-core v0.5.3 h1:b9W3w7AZR2n/YJhG8d0qPFGhGhCWKIvPuJgp4hhc4MM=
github.com/libp2p/go-libp2p-core v0.5.3/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y=
github.com/libp2p/go-libp2p-core v0.5.6 h1:IxFH4PmtLlLdPf4fF/i129SnK/C+/v8WEX644MxhC48=
github.com/libp2p/go-libp2p-core v0.5.6/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo=
github.com/libp2p/go-libp2p-tls v0.1.3 h1:twKMhMu44jQO+HgQK9X8NHO5HkeJu2QbhLzLJpa8oNM=
github.com/libp2p/go-libp2p-tls v0.1.3/go.mod h1:wZfuewxOndz5RTnCAxFliGjvYSDA40sKitV4c50uI1M=
github.com/libp2p/go-maddr-filter v0.0.5 h1:CW3AgbMO6vUvT4kf87y4N+0P8KUl2aqLYhrGyDUbLSg=
github.com/libp2p/go-maddr-filter v0.0.5/go.mod h1:Jk+36PMfIqCJhAnaASRH83bdAvfDRp/w6ENFaC9bG+M=
github.com/libp2p/go-msgio v0.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ=
github.com/libp2p/go-netroute v0.1.2 h1:UHhB35chwgvcRI392znJA3RCBtZ3MpE3ahNCN5MR4Xg=
github.com/libp2p/go-netroute v0.1.2/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk=
github.com/libp2p/go-openssl v0.0.4 h1:d27YZvLoTyMhIN4njrkr8zMDOM4lfpHIp6A+TK9fovg=
github.com/libp2p/go-openssl v0.0.4/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc=
github.com/libp2p/go-openssl v0.0.5 h1:pQkejVhF0xp08D4CQUcw8t+BFJeXowja6RVcb5p++EA=
github.com/libp2p/go-openssl v0.0.5/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc=
github.com/libp2p/go-sockaddr v0.0.2 h1:tCuXfpA9rq7llM/v834RKc/Xvovy/AqM9kHvTV/jY/Q=
github.com/libp2p/go-sockaddr v0.0.2/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k=
github.com/lucas-clemente/quic-go v0.15.7 h1:Pu7To5/G9JoP1mwlrcIvfV8ByPBlCzif3MCl8+1W83I=
Expand All @@ -147,11 +145,12 @@ github.com/mr-tron/base58 v1.1.3 h1:v+sk57XuaCKGXpWtVBX8YJzO7hMGx4Aajh4TQbdEFdc=
github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI=
github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA=
github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44=
github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44=
github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo=
github.com/multiformats/go-multiaddr v0.2.1 h1:SgG/cw5vqyB5QQe5FPe2TqggU9WtrA9X4nZw7LlVqOI=
github.com/multiformats/go-multiaddr v0.2.1/go.mod h1:s/Apk6IyxfvMjDafnhJgJ3/46z7tZ04iMk5wP4QMGGE=
github.com/multiformats/go-multiaddr v0.2.2 h1:XZLDTszBIJe6m0zF6ITBrEcZR73OPUhCBBS9rYAuUzI=
github.com/multiformats/go-multiaddr v0.2.2/go.mod h1:NtfXiOtHvghW9KojvtySjH5y0u0xW5UouOmQQrn6a3Y=
github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E=
github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo=
github.com/multiformats/go-multiaddr-net v0.1.5 h1:QoRKvu0xHN1FCFJcMQLbG/yQE2z441L5urvG3+qyz7g=
Expand Down
10 changes: 10 additions & 0 deletions listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ package libp2pquic
import (
"context"
"crypto/tls"
"fmt"
"net"

ic "github.com/libp2p/go-libp2p-core/crypto"
n "github.com/libp2p/go-libp2p-core/network"
"github.com/libp2p/go-libp2p-core/peer"
tpt "github.com/libp2p/go-libp2p-core/transport"

p2ptls "github.com/libp2p/go-libp2p-tls"

quic "github.com/lucas-clemente/quic-go"
Expand Down Expand Up @@ -79,6 +82,7 @@ func (l *listener) setupConn(sess quic.Session) (tpt.CapableConn, error) {
if err != nil {
return nil, err
}

remotePeerID, err := peer.IDFromPublicKey(remotePubKey)
if err != nil {
return nil, err
Expand All @@ -87,6 +91,12 @@ func (l *listener) setupConn(sess quic.Session) (tpt.CapableConn, error) {
if err != nil {
return nil, err
}

connaddrs := &connAddrs{lmAddr: l.localMultiaddr, rmAddr: remoteMultiaddr}
if l.transport.gater != nil && !l.transport.gater.InterceptSecured(n.DirInbound, remotePeerID, connaddrs) {
return nil, fmt.Errorf("secured connection gated")
}

return &conn{
sess: sess,
transport: l.transport,
Expand Down
19 changes: 10 additions & 9 deletions reuse.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import (
"sync"
"time"

filter "github.com/libp2p/go-maddr-filter"
"github.com/libp2p/go-libp2p-core/connmgr"

"github.com/libp2p/go-netroute"
)

Expand All @@ -23,9 +24,9 @@ type reuseConn struct {
unusedSince time.Time
}

func newReuseConn(conn net.PacketConn, filters *filter.Filters) *reuseConn {
if filters != nil {
conn = newFilteredConn(conn, filters)
func newReuseConn(conn net.PacketConn, gater connmgr.ConnectionGater) *reuseConn {
if gater != nil {
conn = newFilteredConn(conn, gater)
}
return &reuseConn{PacketConn: conn}
}
Expand Down Expand Up @@ -55,7 +56,7 @@ func (c *reuseConn) ShouldGarbageCollect(now time.Time) bool {
type reuse struct {
mutex sync.Mutex

filters *filter.Filters
gater connmgr.ConnectionGater

garbageCollectorRunning bool

Expand All @@ -64,9 +65,9 @@ type reuse struct {
global map[int]*reuseConn
}

func newReuse(filters *filter.Filters) *reuse {
func newReuse(gater connmgr.ConnectionGater) *reuse {
return &reuse{
filters: filters,
gater: gater,
unicast: make(map[string]map[int]*reuseConn),
global: make(map[int]*reuseConn),
}
Expand Down Expand Up @@ -168,7 +169,7 @@ func (r *reuse) dialLocked(network string, raddr *net.UDPAddr, source *net.IP) (
if err != nil {
return nil, err
}
rconn := newReuseConn(conn, r.filters)
rconn := newReuseConn(conn, r.gater)
r.global[conn.LocalAddr().(*net.UDPAddr).Port] = rconn
return rconn, nil
}
Expand All @@ -180,7 +181,7 @@ func (r *reuse) Listen(network string, laddr *net.UDPAddr) (*reuseConn, error) {
}
localAddr := conn.LocalAddr().(*net.UDPAddr)

rconn := newReuseConn(conn, r.filters)
rconn := newReuseConn(conn, r.gater)
rconn.IncreaseCount()

r.mutex.Lock()
Expand Down
Loading