From f7f9668364b8efd5deba43905d725ad663044371 Mon Sep 17 00:00:00 2001 From: Alex Towle Date: Fri, 11 Sep 2020 14:03:03 -0500 Subject: [PATCH 1/3] Fixed bug for inbound connections gated by the deprecated filter option --- options_filter.go | 4 +- options_test.go | 103 ++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 101 insertions(+), 6 deletions(-) diff --git a/options_filter.go b/options_filter.go index c8be5ea2a4..20c2f1da60 100644 --- a/options_filter.go +++ b/options_filter.go @@ -23,8 +23,8 @@ func (f *filtersConnectionGater) InterceptPeerDial(p peer.ID) (allow bool) { return true } -func (f *filtersConnectionGater) InterceptAccept(_ network.ConnMultiaddrs) (allow bool) { - return true +func (f *filtersConnectionGater) InterceptAccept(connAddr network.ConnMultiaddrs) (allow bool) { + return !(*ma.Filters)(f).AddrBlocked(connAddr.RemoteMultiaddr()) } func (f *filtersConnectionGater) InterceptSecured(_ network.Direction, _ peer.ID, _ network.ConnMultiaddrs) (allow bool) { diff --git a/options_test.go b/options_test.go index 4c899aa081..7fe26119d9 100644 --- a/options_test.go +++ b/options_test.go @@ -2,6 +2,7 @@ package libp2p import ( "context" + "fmt" "net" "testing" "time" @@ -13,16 +14,16 @@ import ( "github.com/stretchr/testify/require" ) -func TestDeprecatedFiltersOptions(t *testing.T) { +func TestDeprecatedFiltersOptionsOutbound(t *testing.T) { require := require.New(t) f := ma.NewFilters() _, ipnet, _ := net.ParseCIDR("127.0.0.0/24") f.AddFilter(*ipnet, ma.ActionDeny) - host, err := New(context.TODO(), Filters(f)) + host0, err := New(context.TODO(), Filters(f)) require.NoError(err) - require.NotNil(host) + require.NotNil(host0) ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) defer cancel() @@ -31,11 +32,47 @@ func TestDeprecatedFiltersOptions(t *testing.T) { addr, _ := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/0/p2p/" + id.Pretty()) ai, _ := peer.AddrInfoFromP2pAddr(addr) - err = host.Connect(ctx, *ai) + err = host0.Connect(ctx, *ai) require.Error(err) require.Contains(err.Error(), "no good addresses") } +func TestDeprecatedFiltersOptionsInbound(t *testing.T) { + require := require.New(t) + + host0, err := New(context.TODO()) + require.NoError(err) + require.NotNil(host0) + + f := ma.NewFilters() + var ipNet net.IPNet + for _, addr := range host0.Addrs() { + ipNet, err = ipNetFromMaddr(addr) + if err == nil { + require.NotNil(t, ipNet) + f.AddFilter(ipNet, ma.ActionDeny) + } + } + + host1, err := New(context.TODO(), Filters(f)) + require.NoError(err) + require.NotNil(host1) + + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) + defer cancel() + + peerInfo := peer.AddrInfo{ + ID: host1.ID(), + Addrs: host1.Addrs(), + } + addrs, err := peer.AddrInfoToP2pAddrs(&peerInfo) + ai, err := peer.AddrInfoFromP2pAddr(addrs[0]) + require.NoError(err) + + err = host0.Connect(ctx, *ai) + require.Error(err) +} + func TestDeprecatedFiltersAndAddressesOptions(t *testing.T) { require := require.New(t) @@ -70,3 +107,61 @@ func TestCannotSetFiltersAndConnGater(t *testing.T) { require.Error(err) require.Contains(err.Error(), "cannot configure multiple connection gaters") } + +/// NOTE(jalextowle): This was taken directly from https://github.com/0x-mesh/p2p/banner/banner.go +func ipNetFromMaddr(maddr ma.Multiaddr) (ipNet net.IPNet, err error) { + ip, err := ipFromMaddr(maddr) + if err != nil { + return net.IPNet{}, err + } + mask := getAllMaskForIP(ip) + return net.IPNet{ + IP: ip, + Mask: mask, + }, nil +} + +/// NOTE(jalextowle): This was taken directly from https://github.com/0x-mesh/p2p/banner/banner.go +func ipFromMaddr(maddr ma.Multiaddr) (net.IP, error) { + var ( + ip net.IP + found bool + ) + + ma.ForEach(maddr, func(c ma.Component) bool { + switch c.Protocol().Code { + case ma.P_IP6ZONE: + return true + case ma.P_IP6, ma.P_IP4: + found = true + ip = net.IP(c.RawValue()) + return false + default: + return false + } + }) + + if !found { + return net.IP{}, fmt.Errorf("could not parse IP address from multiaddress: %s", maddr) + } + return ip, nil +} + +/// NOTE(jalextowle): This was taken directly from https://github.com/0x-mesh/p2p/banner/banner.go +var ( + ipv4AllMask = net.IPMask{255, 255, 255, 255} + ipv6AllMask = net.IPMask{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255} +) + +/// NOTE(jalextowle): This was taken directly from https://github.com/0x-mesh/p2p/banner/banner.go +// getAllMaskForIP returns an IPMask that will match all IP addresses. The size +// of the mask depends on whether the given IP address is an IPv4 or an IPv6 +// address. +func getAllMaskForIP(ip net.IP) net.IPMask { + if ip.To4() != nil { + // This is an ipv4 address. Return 4 byte mask. + return ipv4AllMask + } + // Assume ipv6 address. Return 16 byte mask. + return ipv6AllMask +} From f1de846d2b840a3619d533c415837753c56b1906 Mon Sep 17 00:00:00 2001 From: Alex Towle Date: Mon, 14 Sep 2020 16:31:57 -0500 Subject: [PATCH 2/3] Addressed review feedback --- options_test.go | 89 +++++++++++-------------------------------------- 1 file changed, 19 insertions(+), 70 deletions(-) diff --git a/options_test.go b/options_test.go index 7fe26119d9..ba8c0cbfba 100644 --- a/options_test.go +++ b/options_test.go @@ -2,7 +2,6 @@ package libp2p import ( "context" - "fmt" "net" "testing" "time" @@ -11,6 +10,7 @@ import ( "github.com/libp2p/go-libp2p-core/test" ma "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr/net" "github.com/stretchr/testify/require" ) @@ -37,6 +37,11 @@ func TestDeprecatedFiltersOptionsOutbound(t *testing.T) { require.Contains(err.Error(), "no good addresses") } +var ( + ip4FullMask = net.IPMask{255, 255, 255, 255} + ip6FullMask = net.IPMask{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255} +) + func TestDeprecatedFiltersOptionsInbound(t *testing.T) { require := require.New(t) @@ -45,15 +50,21 @@ func TestDeprecatedFiltersOptionsInbound(t *testing.T) { require.NotNil(host0) f := ma.NewFilters() - var ipNet net.IPNet for _, addr := range host0.Addrs() { - ipNet, err = ipNetFromMaddr(addr) - if err == nil { - require.NotNil(t, ipNet) - f.AddFilter(ipNet, ma.ActionDeny) + ip, err := manet.ToIP(addr) + require.NoError(err) + require.NotNil(t, ip) + + var mask net.IPMask + if ip.To4() != nil { + mask = ip4FullMask + } else { + mask = ip6FullMask } - } + ipnet := net.IPNet{IP: ip, Mask: mask} + f.AddFilter(ipnet, ma.ActionDeny) + } host1, err := New(context.TODO(), Filters(f)) require.NoError(err) require.NotNil(host1) @@ -65,11 +76,7 @@ func TestDeprecatedFiltersOptionsInbound(t *testing.T) { ID: host1.ID(), Addrs: host1.Addrs(), } - addrs, err := peer.AddrInfoToP2pAddrs(&peerInfo) - ai, err := peer.AddrInfoFromP2pAddr(addrs[0]) - require.NoError(err) - - err = host0.Connect(ctx, *ai) + err = host0.Connect(ctx, peerInfo) require.Error(err) } @@ -107,61 +114,3 @@ func TestCannotSetFiltersAndConnGater(t *testing.T) { require.Error(err) require.Contains(err.Error(), "cannot configure multiple connection gaters") } - -/// NOTE(jalextowle): This was taken directly from https://github.com/0x-mesh/p2p/banner/banner.go -func ipNetFromMaddr(maddr ma.Multiaddr) (ipNet net.IPNet, err error) { - ip, err := ipFromMaddr(maddr) - if err != nil { - return net.IPNet{}, err - } - mask := getAllMaskForIP(ip) - return net.IPNet{ - IP: ip, - Mask: mask, - }, nil -} - -/// NOTE(jalextowle): This was taken directly from https://github.com/0x-mesh/p2p/banner/banner.go -func ipFromMaddr(maddr ma.Multiaddr) (net.IP, error) { - var ( - ip net.IP - found bool - ) - - ma.ForEach(maddr, func(c ma.Component) bool { - switch c.Protocol().Code { - case ma.P_IP6ZONE: - return true - case ma.P_IP6, ma.P_IP4: - found = true - ip = net.IP(c.RawValue()) - return false - default: - return false - } - }) - - if !found { - return net.IP{}, fmt.Errorf("could not parse IP address from multiaddress: %s", maddr) - } - return ip, nil -} - -/// NOTE(jalextowle): This was taken directly from https://github.com/0x-mesh/p2p/banner/banner.go -var ( - ipv4AllMask = net.IPMask{255, 255, 255, 255} - ipv6AllMask = net.IPMask{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255} -) - -/// NOTE(jalextowle): This was taken directly from https://github.com/0x-mesh/p2p/banner/banner.go -// getAllMaskForIP returns an IPMask that will match all IP addresses. The size -// of the mask depends on whether the given IP address is an IPv4 or an IPv6 -// address. -func getAllMaskForIP(ip net.IP) net.IPMask { - if ip.To4() != nil { - // This is an ipv4 address. Return 4 byte mask. - return ipv4AllMask - } - // Assume ipv6 address. Return 16 byte mask. - return ipv6AllMask -} From 33340b1c3e8fb74531b3b90a37c06265c7f0e192 Mon Sep 17 00:00:00 2001 From: Alex Towle Date: Tue, 15 Sep 2020 09:55:32 -0500 Subject: [PATCH 3/3] Added filtering for "InterceptSecured" --- options_filter.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/options_filter.go b/options_filter.go index 20c2f1da60..c6b8175d8e 100644 --- a/options_filter.go +++ b/options_filter.go @@ -27,8 +27,8 @@ func (f *filtersConnectionGater) InterceptAccept(connAddr network.ConnMultiaddrs return !(*ma.Filters)(f).AddrBlocked(connAddr.RemoteMultiaddr()) } -func (f *filtersConnectionGater) InterceptSecured(_ network.Direction, _ peer.ID, _ network.ConnMultiaddrs) (allow bool) { - return true +func (f *filtersConnectionGater) InterceptSecured(_ network.Direction, _ peer.ID, connAddr network.ConnMultiaddrs) (allow bool) { + return !(*ma.Filters)(f).AddrBlocked(connAddr.RemoteMultiaddr()) } func (f *filtersConnectionGater) InterceptUpgraded(_ network.Conn) (allow bool, reason control.DisconnectReason) {