Browse Source

swarm addr checks

pull/2/head
Juan Batiz-Benet 10 years ago
parent
commit
f3f1f058f9
  1. 69
      net/swarm/addr.go
  2. 97
      net/swarm/addr_test.go
  3. 9
      net/swarm/swarm_listen.go
  4. 2
      test/util/util.go

69
net/swarm/addr.go

@ -9,6 +9,75 @@ import (
manet "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net"
)
// SupportedTransportStrings is the list of supported transports for the swarm.
// These are strings of encapsulated multiaddr protocols. E.g.:
// /ip4/tcp
var SupportedTransportStrings = []string{
"/ip4/tcp",
"/ip6/tcp",
// "/ip4/udp/utp", disabled because the lib is broken
// "/ip6/udp/utp", disabled because the lib is broken
// "/ip4/udp/udt", disabled because the lib doesnt work on arm
// "/ip6/udp/udt", disabled because the lib doesnt work on arm
}
// SupportedTransportProtocols is the list of supported transports for the swarm.
// These are []ma.Protocol lists. Populated at runtime from SupportedTransportStrings
var SupportedTransportProtocols = [][]ma.Protocol{}
func init() {
// initialize SupportedTransportProtocols
transports := make([][]ma.Protocol, len(SupportedTransportStrings))
for _, s := range SupportedTransportStrings {
t, err := ma.ProtocolsWithString(s)
if err != nil {
panic(err) // important to fix this in the codebase
}
transports = append(transports, t)
}
SupportedTransportProtocols = transports
}
// FilterAddrs is a filter that removes certain addresses
// from a list. the addresses removed are those known NOT
// to work with swarm. Namely, addresses with UTP.
func FilterAddrs(a []ma.Multiaddr) []ma.Multiaddr {
b := make([]ma.Multiaddr, 0, len(a))
for _, addr := range a {
if AddrUsable(addr) {
b = append(b, addr)
}
}
return b
}
// AddrUsable returns whether the swarm can use this addr.
func AddrUsable(a ma.Multiaddr) bool {
// test the address protocol list is in SupportedTransportProtocols
matches := func(a, b []ma.Protocol) bool {
if len(a) != len(b) {
return false
}
for i := range a {
if a[i].Code != b[i].Code {
return false
}
}
return true
}
transport := a.Protocols()
for _, supported := range SupportedTransportProtocols {
if matches(supported, transport) {
return true
}
}
return false
}
// ListenAddresses returns a list of addresses at which this swarm listens.
func (s *Swarm) ListenAddresses() []ma.Multiaddr {
listeners := s.swarm.Listeners()

97
net/swarm/addr_test.go

@ -0,0 +1,97 @@
package swarm
import (
"testing"
peer "github.com/jbenet/go-ipfs/p2p/peer"
testutil "github.com/jbenet/go-ipfs/util/testutil"
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
)
func TestFilterAddrs(t *testing.T) {
m := func(s string) ma.Multiaddr {
maddr, err := ma.NewMultiaddr(s)
if err != nil {
t.Fatal(err)
}
return maddr
}
bad := []ma.Multiaddr{
m("/ip4/1.2.3.4/udp/1234"), // unreliable
m("/ip4/1.2.3.4/udp/1234/sctp/1234"), // not in manet
m("/ip4/1.2.3.4/udp/1234/utp"), // utp is broken
m("/ip4/1.2.3.4/udp/1234/udt"), // udt is broken on arm
}
good := []ma.Multiaddr{
m("/ip4/127.0.0.1/tcp/1234"),
m("/ip6/::1/tcp/1234"),
}
goodAndBad := append(good, bad...)
// test filters
for _, a := range bad {
if AddrUsable(a) {
t.Errorf("addr %s should be unusable", a)
}
}
for _, a := range good {
if !AddrUsable(a) {
t.Errorf("addr %s should be usable", a)
}
}
subtestAddrsEqual(t, FilterAddrs(bad), []ma.Multiaddr{})
subtestAddrsEqual(t, FilterAddrs(good), good)
subtestAddrsEqual(t, FilterAddrs(goodAndBad), good)
// now test it with swarm
id, err := testutil.RandPeerID()
if err != nil {
t.Fatal(err)
}
ps := peer.NewPeerstore()
ctx := context.Background()
if _, err := NewNetwork(ctx, bad, id, ps); err == nil {
t.Fatal("should have failed to create swarm")
}
if _, err := NewNetwork(ctx, good, id, ps); err != nil {
t.Fatal("should have succeeded in creating swarm", err)
}
if _, err := NewNetwork(ctx, goodAndBad, id, ps); err == nil {
t.Fatal("should have failed to create swarm")
}
}
func subtestAddrsEqual(t *testing.T, a, b []ma.Multiaddr) {
if len(a) != len(b) {
t.Error(t)
}
in := func(addr ma.Multiaddr, l []ma.Multiaddr) bool {
for _, addr2 := range l {
if addr.Equal(addr2) {
return true
}
}
return false
}
for _, aa := range a {
if !in(aa, b) {
t.Errorf("%s not in %s", aa, b)
}
}
}

9
net/swarm/swarm_listen.go

@ -1,6 +1,8 @@
package swarm
import (
"fmt"
conn "github.com/jbenet/go-ipfs/p2p/net/conn"
lgbl "github.com/jbenet/go-ipfs/util/eventlog/loggables"
@ -12,6 +14,13 @@ import (
// Open listeners for each network the swarm should listen on
func (s *Swarm) listen(addrs []ma.Multiaddr) error {
for _, addr := range addrs {
if !AddrUsable(addr) {
return fmt.Errorf("cannot use addr: %s", addr)
}
}
retErr := multierr.New()
// listen on every address

2
test/util/util.go

@ -36,3 +36,5 @@ func GenHostSwarm(t *testing.T, ctx context.Context) *bhost.BasicHost {
n := GenSwarmNetwork(t, ctx)
return bhost.New(n)
}
var RandPeerID = tu.RandPeerID

Loading…
Cancel
Save