Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
go-libp2p
Commits
63145110
Commit
63145110
authored
Jan 12, 2015
by
Juan Batiz-Benet
Browse files
p2p/net/swarm: do not usre link local addrs
parent
bb1d3d7d
Changes
9
Show whitespace changes
Inline
Side-by-side
net/conn/dial.go
View file @
63145110
...
...
@@ -22,7 +22,7 @@ func (d *Dialer) String() string {
// Example: d.DialAddr(ctx, peer.Addresses()[0], peer)
func
(
d
*
Dialer
)
Dial
(
ctx
context
.
Context
,
raddr
ma
.
Multiaddr
,
remote
peer
.
ID
)
(
Conn
,
error
)
{
network
,
_
,
err
:=
manet
.
DialArgs
(
raddr
)
_
,
_
,
err
:=
manet
.
DialArgs
(
raddr
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -31,17 +31,20 @@ func (d *Dialer) Dial(ctx context.Context, raddr ma.Multiaddr, remote peer.ID) (
return
nil
,
debugerror
.
Errorf
(
"Attempted to connect to zero address: %s"
,
raddr
)
}
var
laddr
ma
.
Multiaddr
if
len
(
d
.
LocalAddrs
)
>
0
{
// laddr := MultiaddrNetMatch(raddr, d.LocalAddrs)
laddr
=
NetAddress
(
network
,
d
.
LocalAddrs
)
if
laddr
==
nil
{
return
nil
,
debugerror
.
Errorf
(
"No local address for network %s"
,
network
)
}
laddrs
:=
manet
.
AddrMatch
(
raddr
,
d
.
LocalAddrs
)
if
len
(
laddrs
)
<
1
{
return
nil
,
debugerror
.
Errorf
(
"No local address matches %s %s"
,
raddr
,
d
.
LocalAddrs
)
}
// TODO pick with a good heuristic
// we use a random one for now to prevent bad addresses from making nodes unreachable
// with a random selection, multiple tries may work.
// laddr := laddrs[rand.Intn(len(laddrs))]
// TODO: try to get reusing addr/ports to work.
// d.Dialer.LocalAddr = laddr
}
log
.
Debugf
(
"%s dialing %s %s"
,
d
.
LocalPeer
,
remote
,
raddr
)
maconn
,
err
:=
d
.
Dialer
.
Dial
(
raddr
)
...
...
@@ -116,15 +119,3 @@ func MultiaddrNetMatch(tgt ma.Multiaddr, srcs []ma.Multiaddr) ma.Multiaddr {
}
return
nil
}
// NetAddress returns the first Multiaddr found for a given network.
func
NetAddress
(
n
string
,
addrs
[]
ma
.
Multiaddr
)
ma
.
Multiaddr
{
for
_
,
a
:=
range
addrs
{
for
_
,
p
:=
range
a
.
Protocols
()
{
if
p
.
Name
==
n
{
return
a
}
}
}
return
nil
}
net/conn/listen.go
View file @
63145110
...
...
@@ -102,11 +102,7 @@ func (l *listener) Addr() net.Addr {
// If there is an error converting from net.Addr to ma.Multiaddr,
// the return value will be nil.
func
(
l
*
listener
)
Multiaddr
()
ma
.
Multiaddr
{
maddr
,
err
:=
manet
.
FromNetAddr
(
l
.
Addr
())
if
err
!=
nil
{
return
nil
// error
}
return
maddr
return
l
.
Listener
.
Multiaddr
()
}
// LocalPeer is the identity of the local Peer.
...
...
@@ -140,7 +136,7 @@ func Listen(ctx context.Context, addr ma.Multiaddr, local peer.ID, sk ic.PrivKey
}
l
.
cg
.
SetTeardown
(
l
.
teardown
)
log
.
Infof
(
"swarm l
isten
ing
on %s"
,
l
.
Multiaddr
())
log
.
Debugf
(
"Conn L
isten
er
on %s"
,
l
.
Multiaddr
())
log
.
Event
(
ctx
,
"swarmListen"
,
l
)
return
l
,
nil
}
net/swarm/addr.go
→
net/swarm/addr
/addr
.go
View file @
63145110
package
swarm
package
addrutil
import
(
conn
"github.com/jbenet/go-ipfs/p2p/net/conn"
"fmt"
eventlog
"github.com/jbenet/go-ipfs/util/eventlog"
context
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
...
...
@@ -9,6 +10,8 @@ import (
manet
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net"
)
var
log
=
eventlog
.
Logger
(
"p2p/net/swarm/addr"
)
// SupportedTransportStrings is the list of supported transports for the swarm.
// These are strings of encapsulated multiaddr protocols. E.g.:
// /ip4/tcp
...
...
@@ -40,28 +43,53 @@ func init() {
// 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.
// to work with
our network
. 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
)
{
if
AddrUsable
(
addr
,
false
)
{
b
=
append
(
b
,
addr
)
}
}
return
b
}
// AddrUsable returns whether the swarm can use this addr.
func
AddrUsable
(
a
ma
.
Multiaddr
)
bool
{
// AddrOverNonLocalIP returns whether the addr uses a non-local ip link
func
AddrOverNonLocalIP
(
a
ma
.
Multiaddr
)
bool
{
split
:=
ma
.
Split
(
a
)
if
len
(
split
)
<
1
{
return
false
}
if
manet
.
IsIP6LinkLocal
(
split
[
0
])
{
return
false
}
return
true
}
// AddrUsable returns whether our network can use this addr.
// We only use the transports in SupportedTransportStrings,
// and we do not link local addresses. Loopback is ok
// as we need to be able to connect to multiple ipfs nodes
// in the same machine.
func
AddrUsable
(
a
ma
.
Multiaddr
,
partial
bool
)
bool
{
if
!
AddrOverNonLocalIP
(
a
)
{
return
false
}
// test the address protocol list is in SupportedTransportProtocols
matches
:=
func
(
supported
,
test
[]
ma
.
Protocol
)
bool
{
if
len
(
test
)
>
len
(
supported
)
{
return
false
}
matches
:=
func
(
a
,
b
[]
ma
.
Protocol
)
bool
{
if
len
(
a
)
!=
len
(
b
)
{
// when partial, it's ok if test < supported.
if
!
partial
&&
len
(
supported
)
!=
len
(
test
)
{
return
false
}
for
i
:=
range
a
{
if
a
[
i
]
.
Code
!=
b
[
i
]
.
Code
{
for
i
:=
range
test
{
if
supported
[
i
]
.
Code
!=
test
[
i
]
.
Code
{
return
false
}
}
...
...
@@ -78,53 +106,63 @@ func AddrUsable(a ma.Multiaddr) bool {
return
false
}
// ListenAddresses returns a list of addresses at which this swarm listens.
func
(
s
*
Swarm
)
ListenAddresses
()
[]
ma
.
Multiaddr
{
listeners
:=
s
.
swarm
.
Listeners
()
addrs
:=
make
([]
ma
.
Multiaddr
,
0
,
len
(
listeners
))
for
_
,
l
:=
range
listeners
{
if
l2
,
ok
:=
l
.
NetListener
()
.
(
conn
.
Listener
);
ok
{
addrs
=
append
(
addrs
,
l2
.
Multiaddr
())
// ResolveUnspecifiedAddress expands an unspecified ip addresses (/ip4/0.0.0.0, /ip6/::) to
// use the known local interfaces. If ifaceAddr is nil, we request interface addresses
// from the network stack. (this is so you can provide a cached value if resolving many addrs)
func
ResolveUnspecifiedAddress
(
resolve
ma
.
Multiaddr
,
ifaceAddrs
[]
ma
.
Multiaddr
)
([]
ma
.
Multiaddr
,
error
)
{
// split address into its components
split
:=
ma
.
Split
(
resolve
)
// if first component (ip) is not unspecified, use it as is.
if
!
manet
.
IsIPUnspecified
(
split
[
0
])
{
return
[]
ma
.
Multiaddr
{
resolve
},
nil
}
out
:=
make
([]
ma
.
Multiaddr
,
0
,
len
(
ifaceAddrs
))
for
_
,
ia
:=
range
ifaceAddrs
{
// must match the first protocol to be resolve.
if
ia
.
Protocols
()[
0
]
.
Code
!=
resolve
.
Protocols
()[
0
]
.
Code
{
continue
}
return
addrs
}
// InterfaceListenAddresses returns a list of addresses at which this swarm
// listens. It expands "any interface" addresses (/ip4/0.0.0.0, /ip6/::) to
// use the known local interfaces.
func
InterfaceListenAddresses
(
s
*
Swarm
)
([]
ma
.
Multiaddr
,
error
)
{
return
resolveUnspecifiedAddresses
(
s
.
ListenAddresses
())
split
[
0
]
=
ia
joined
:=
ma
.
Join
(
split
...
)
out
=
append
(
out
,
joined
)
log
.
Debug
(
"adding resolved addr:"
,
resolve
,
joined
,
out
)
}
if
len
(
out
)
<
1
{
return
nil
,
fmt
.
Errorf
(
"failed to resolve: %s"
,
resolve
)
}
return
out
,
nil
}
//
r
esolveUnspecifiedAddresses expands unspecified ip addresses (/ip4/0.0.0.0, /ip6/::) to
//
R
esolveUnspecifiedAddresses expands unspecified ip addresses (/ip4/0.0.0.0, /ip6/::) to
// use the known local interfaces.
func
resolveUnspecifiedAddresses
(
unspecifiedAddrs
[]
ma
.
Multiaddr
)
([]
ma
.
Multiaddr
,
error
)
{
var
outputAddrs
[]
ma
.
Multiaddr
func
ResolveUnspecifiedAddresses
(
unspecAddrs
,
ifaceAddrs
[]
ma
.
Multiaddr
)
([]
ma
.
Multiaddr
,
error
)
{
// todo optimize: only fetch these if we have a "any" addr.
ifaceAddrs
,
err
:=
interfaceAddresses
()
if
len
(
ifaceAddrs
)
<
1
{
var
err
error
ifaceAddrs
,
err
=
InterfaceAddresses
()
if
err
!=
nil
{
return
nil
,
err
}
for
_
,
a
:=
range
unspecifiedAddrs
{
// split address into its components
split
:=
ma
.
Split
(
a
)
// if first component (ip) is not unspecified, use it as is.
if
!
manet
.
IsIPUnspecified
(
split
[
0
])
{
outputAddrs
=
append
(
outputAddrs
,
a
)
continue
// log.Debug("InterfaceAddresses:", ifaceAddrs)
}
// unspecified? add one address per interface.
for
_
,
ia
:=
range
ifaceAddrs
{
split
[
0
]
=
ia
joined
:=
ma
.
Join
(
split
...
)
outputAddrs
=
append
(
outputAddrs
,
joined
)
var
outputAddrs
[]
ma
.
Multiaddr
for
_
,
a
:=
range
unspecAddrs
{
// unspecified?
resolved
,
err
:=
ResolveUnspecifiedAddress
(
a
,
ifaceAddrs
)
if
err
!=
nil
{
continue
// optimistic. if we cant resolve anything, we'll know at the bottom.
}
// log.Debug("resolved:", a, resolved)
outputAddrs
=
append
(
outputAddrs
,
resolved
...
)
}
if
len
(
outputAddrs
)
<
1
{
return
nil
,
fmt
.
Errorf
(
"failed to specify addrs: %s"
,
unspecAddrs
)
}
log
.
Event
(
context
.
TODO
(),
"interfaceListenAddresses"
,
func
()
eventlog
.
Loggable
{
...
...
@@ -134,30 +172,38 @@ func resolveUnspecifiedAddresses(unspecifiedAddrs []ma.Multiaddr) ([]ma.Multiadd
}
return
eventlog
.
Metadata
{
"addresses"
:
addrs
}
}())
log
.
Debug
(
"InterfaceListenAddresses:"
,
outputAddrs
)
log
.
Debug
(
"ResolveUnspecifiedAddresses:"
,
unspecAddrs
,
ifaceAddrs
,
outputAddrs
)
return
outputAddrs
,
nil
}
// interfaceAddresses returns a list of addresses associated with local machine
func
interfaceAddresses
()
([]
ma
.
Multiaddr
,
error
)
{
// InterfaceAddresses returns a list of addresses associated with local machine
// Note: we do not return link local addresses. IP loopback is ok, because we
// may be connecting to other nodes in the same machine.
func
InterfaceAddresses
()
([]
ma
.
Multiaddr
,
error
)
{
maddrs
,
err
:=
manet
.
InterfaceMultiaddrs
()
if
err
!=
nil
{
return
nil
,
err
}
log
.
Debug
(
"InterfaceAddresses: from manet:"
,
maddrs
)
var
nonLoopback
[]
ma
.
Multiaddr
var
out
[]
ma
.
Multiaddr
for
_
,
a
:=
range
maddrs
{
if
!
manet
.
IsIPLoopback
(
a
)
{
nonLoopback
=
append
(
nonLoopback
,
a
)
if
!
AddrUsable
(
a
,
true
)
{
// partial
// log.Debug("InterfaceAddresses: skipping unusable:", a)
continue
}
out
=
append
(
out
,
a
)
}
return
nonLoopback
,
nil
log
.
Debug
(
"InterfaceAddresses: usable:"
,
out
)
return
out
,
nil
}
//
a
ddrInList returns whether or not an address is part of a list.
//
A
ddrInList returns whether or not an address is part of a list.
// this is useful to check if NAT is happening (or other bugs?)
func
a
ddrInList
(
addr
ma
.
Multiaddr
,
list
[]
ma
.
Multiaddr
)
bool
{
func
A
ddrInList
(
addr
ma
.
Multiaddr
,
list
[]
ma
.
Multiaddr
)
bool
{
for
_
,
addr2
:=
range
list
{
if
addr
.
Equal
(
addr2
)
{
return
true
...
...
@@ -166,20 +212,39 @@ func addrInList(addr ma.Multiaddr, list []ma.Multiaddr) bool {
return
false
}
// checkNATWarning checks if our observed addresses differ. if so,
// informs the user that certain things might not work yet
func
checkNATWarning
(
s
*
Swarm
,
observed
ma
.
Multiaddr
,
expected
ma
.
Multiaddr
)
{
if
observed
.
Equal
(
expected
)
{
return
// AddrIsShareableOnWAN returns whether the given address should be shareable on the
// wide area network (wide internet).
func
AddrIsShareableOnWAN
(
addr
ma
.
Multiaddr
)
bool
{
s
:=
ma
.
Split
(
addr
)
if
len
(
s
)
<
1
{
return
false
}
a
:=
s
[
0
]
if
manet
.
IsIPLoopback
(
a
)
||
manet
.
IsIP6LinkLocal
(
a
)
||
manet
.
IsIPUnspecified
(
a
)
{
return
false
}
return
manet
.
IsThinWaist
(
a
)
}
listen
,
err
:=
InterfaceListenAddresses
(
s
)
if
err
!=
nil
{
log
.
Errorf
(
"Error retrieving swarm.InterfaceListenAddresses: %s"
,
err
)
// WANShareableAddrs filters addresses based on whether they're shareable on WAN
func
WANShareableAddrs
(
inp
[]
ma
.
Multiaddr
)
[]
ma
.
Multiaddr
{
out
:=
make
([]
ma
.
Multiaddr
,
0
,
len
(
inp
))
for
_
,
a
:=
range
inp
{
if
AddrIsShareableOnWAN
(
a
)
{
out
=
append
(
out
,
a
)
}
}
return
out
}
// CheckNATWarning checks if our observed addresses differ. if so,
// informs the user that certain things might not work yet
func
CheckNATWarning
(
observed
,
expected
ma
.
Multiaddr
,
listen
[]
ma
.
Multiaddr
)
{
if
observed
.
Equal
(
expected
)
{
return
}
if
!
a
ddrInList
(
observed
,
listen
)
{
// probably a nat
if
!
A
ddrInList
(
observed
,
listen
)
{
// probably a nat
log
.
Warningf
(
natWarning
,
observed
,
listen
)
}
}
...
...
net/swarm/addr/addr_test.go
0 → 100644
View file @
63145110
package
addrutil
import
(
"testing"
ma
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
manet
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net"
)
func
newMultiaddr
(
t
*
testing
.
T
,
s
string
)
ma
.
Multiaddr
{
maddr
,
err
:=
ma
.
NewMultiaddr
(
s
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
return
maddr
}
func
TestFilterAddrs
(
t
*
testing
.
T
)
{
bad
:=
[]
ma
.
Multiaddr
{
newMultiaddr
(
t
,
"/ip4/1.2.3.4/udp/1234"
),
// unreliable
newMultiaddr
(
t
,
"/ip4/1.2.3.4/udp/1234/sctp/1234"
),
// not in manet
newMultiaddr
(
t
,
"/ip4/1.2.3.4/udp/1234/utp"
),
// utp is broken
newMultiaddr
(
t
,
"/ip4/1.2.3.4/udp/1234/udt"
),
// udt is broken on arm
newMultiaddr
(
t
,
"/ip6/fe80::1/tcp/1234"
),
// link local
newMultiaddr
(
t
,
"/ip6/fe80::100/tcp/1234"
),
// link local
}
good
:=
[]
ma
.
Multiaddr
{
newMultiaddr
(
t
,
"/ip4/127.0.0.1/tcp/1234"
),
newMultiaddr
(
t
,
"/ip6/::1/tcp/1234"
),
}
goodAndBad
:=
append
(
good
,
bad
...
)
// test filters
for
_
,
a
:=
range
bad
{
if
AddrUsable
(
a
,
false
)
{
t
.
Errorf
(
"addr %s should be unusable"
,
a
)
}
if
AddrUsable
(
a
,
true
)
{
t
.
Errorf
(
"addr %s should be unusable"
,
a
)
}
}
for
_
,
a
:=
range
good
{
if
!
AddrUsable
(
a
,
false
)
{
t
.
Errorf
(
"addr %s should be usable"
,
a
)
}
if
!
AddrUsable
(
a
,
true
)
{
t
.
Errorf
(
"addr %s should be usable"
,
a
)
}
}
subtestAddrsEqual
(
t
,
FilterAddrs
(
bad
),
[]
ma
.
Multiaddr
{})
subtestAddrsEqual
(
t
,
FilterAddrs
(
good
),
good
)
subtestAddrsEqual
(
t
,
FilterAddrs
(
goodAndBad
),
good
)
}
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
)
}
}
}
func
TestInterfaceAddrs
(
t
*
testing
.
T
)
{
addrs
,
err
:=
InterfaceAddresses
()
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
len
(
addrs
)
<
1
{
t
.
Error
(
"no addresses"
)
}
for
_
,
a
:=
range
addrs
{
if
manet
.
IsIP6LinkLocal
(
a
)
{
t
.
Error
(
"should not return ip link local addresses"
,
a
)
}
}
if
len
(
addrs
)
<
1
{
t
.
Error
(
"no good interface addrs"
)
}
}
func
TestResolvingAddrs
(
t
*
testing
.
T
)
{
unspec
:=
[]
ma
.
Multiaddr
{
newMultiaddr
(
t
,
"/ip4/0.0.0.0/tcp/1234"
),
newMultiaddr
(
t
,
"/ip4/1.2.3.4/tcp/1234"
),
newMultiaddr
(
t
,
"/ip6/::/tcp/1234"
),
newMultiaddr
(
t
,
"/ip6/::100/tcp/1234"
),
}
iface
:=
[]
ma
.
Multiaddr
{
newMultiaddr
(
t
,
"/ip4/127.0.0.1"
),
newMultiaddr
(
t
,
"/ip4/10.20.30.40"
),
newMultiaddr
(
t
,
"/ip6/::1"
),
newMultiaddr
(
t
,
"/ip6/::f"
),
}
spec
:=
[]
ma
.
Multiaddr
{
newMultiaddr
(
t
,
"/ip4/127.0.0.1/tcp/1234"
),
newMultiaddr
(
t
,
"/ip4/10.20.30.40/tcp/1234"
),
newMultiaddr
(
t
,
"/ip4/1.2.3.4/tcp/1234"
),
newMultiaddr
(
t
,
"/ip6/::1/tcp/1234"
),
newMultiaddr
(
t
,
"/ip6/::f/tcp/1234"
),
newMultiaddr
(
t
,
"/ip6/::100/tcp/1234"
),
}
actual
,
err
:=
ResolveUnspecifiedAddresses
(
unspec
,
iface
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
for
i
,
a
:=
range
actual
{
if
!
a
.
Equal
(
spec
[
i
])
{
t
.
Error
(
a
,
" != "
,
spec
[
i
])
}
}
ip4u
:=
[]
ma
.
Multiaddr
{
newMultiaddr
(
t
,
"/ip4/0.0.0.0"
)}
ip4i
:=
[]
ma
.
Multiaddr
{
newMultiaddr
(
t
,
"/ip4/1.2.3.4"
)}
ip6u
:=
[]
ma
.
Multiaddr
{
newMultiaddr
(
t
,
"/ip6/::"
)}
ip6i
:=
[]
ma
.
Multiaddr
{
newMultiaddr
(
t
,
"/ip6/::1"
)}
if
_
,
err
:=
ResolveUnspecifiedAddress
(
ip4u
[
0
],
ip6i
);
err
==
nil
{
t
.
Fatal
(
"should have failed"
)
}
if
_
,
err
:=
ResolveUnspecifiedAddress
(
ip6u
[
0
],
ip4i
);
err
==
nil
{
t
.
Fatal
(
"should have failed"
)
}
if
_
,
err
:=
ResolveUnspecifiedAddresses
(
ip6u
,
ip4i
);
err
==
nil
{
t
.
Fatal
(
"should have failed"
)
}
if
_
,
err
:=
ResolveUnspecifiedAddresses
(
ip4u
,
ip6i
);
err
==
nil
{
t
.
Fatal
(
"should have failed"
)
}
}
func
TestWANShareable
(
t
*
testing
.
T
)
{
wanok
:=
[]
ma
.
Multiaddr
{
newMultiaddr
(
t
,
"/ip4/1.2.3.4/tcp/1234"
),
newMultiaddr
(
t
,
"/ip6/abcd::1/tcp/1234"
),
}
wanbad
:=
[]
ma
.
Multiaddr
{
newMultiaddr
(
t
,
"/ip4/127.0.0.1/tcp/1234"
),
newMultiaddr
(
t
,
"/ip4/0.0.0.0/tcp/1234"
),
newMultiaddr
(
t
,
"/ip6/::1/tcp/1234"
),
newMultiaddr
(
t
,
"/ip6/::/tcp/1234"
),
newMultiaddr
(
t
,
"/ip6/fe80::1/tcp/1234"
),
newMultiaddr
(
t
,
"/ip6/fe80::/tcp/1234"
),
}
for
_
,
a
:=
range
wanok
{
if
!
AddrIsShareableOnWAN
(
a
)
{
t
.
Error
(
"should be true"
,
a
)
}
}
for
_
,
a
:=
range
wanbad
{
if
AddrIsShareableOnWAN
(
a
)
{
t
.
Error
(
"should be false"
,
a
)
}
}
wanok2
:=
WANShareableAddrs
(
wanok
)
if
len
(
wanok
)
!=
len
(
wanok2
)
{
t
.
Error
(
"should be the same"
)
}
wanbad2
:=
WANShareableAddrs
(
wanbad
)
if
len
(
wanbad2
)
!=
0
{
t
.
Error
(
"should be zero"
)
}
}
net/swarm/swarm.go
View file @
63145110
...
...
@@ -3,7 +3,10 @@
package
swarm
import
(
"fmt"
inet
"github.com/jbenet/go-ipfs/p2p/net"
addrutil
"github.com/jbenet/go-ipfs/p2p/net/swarm/addr"
peer
"github.com/jbenet/go-ipfs/p2p/peer"
eventlog
"github.com/jbenet/go-ipfs/util/eventlog"
...
...
@@ -37,6 +40,14 @@ type Swarm struct {
func
NewSwarm
(
ctx
context
.
Context
,
listenAddrs
[]
ma
.
Multiaddr
,
local
peer
.
ID
,
peers
peer
.
Peerstore
)
(
*
Swarm
,
error
)
{
if
len
(
listenAddrs
)
>
0
{
filtered
:=
addrutil
.
FilterAddrs
(
listenAddrs
)
if
len
(
filtered
)
<
1
{
return
nil
,
fmt
.
Errorf
(
"swarm cannot use any addr in: %s"
,
listenAddrs
)
}
listenAddrs
=
filtered
}
s
:=
&
Swarm
{
swarm
:
ps
.
NewSwarm
(
PSTransport
),
local
:
local
,
...
...
net/swarm/swarm_addr.go
0 → 100644
View file @
63145110
package
swarm
import
(
conn
"github.com/jbenet/go-ipfs/p2p/net/conn"
addrutil
"github.com/jbenet/go-ipfs/p2p/net/swarm/addr"
ma
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
)
// ListenAddresses returns a list of addresses at which this swarm listens.
func
(
s
*
Swarm
)
ListenAddresses
()
[]
ma
.
Multiaddr
{
listeners
:=
s
.
swarm
.
Listeners
()
addrs
:=
make
([]
ma
.
Multiaddr
,
0
,
len
(
listeners
))
for
_
,
l
:=
range
listeners
{
if
l2
,
ok
:=
l
.
NetListener
()
.
(
conn
.
Listener
);
ok
{
addrs
=
append
(
addrs
,
l2
.
Multiaddr
())
}
}
return
addrs
}
// InterfaceListenAddresses returns a list of addresses at which this swarm
// listens. It expands "any interface" addresses (/ip4/0.0.0.0, /ip6/::) to
// use the known local interfaces.
func
InterfaceListenAddresses
(
s
*
Swarm
)
([]
ma
.
Multiaddr
,
error
)
{
return
addrutil
.
ResolveUnspecifiedAddresses
(
s
.
ListenAddresses
(),
nil
)
}
// checkNATWarning checks if our observed addresses differ. if so,
// informs the user that certain things might not work yet
func
checkNATWarning
(
s
*
Swarm
,
observed
ma
.
Multiaddr
,
expected
ma
.
Multiaddr
)
{
listen
,
err
:=
InterfaceListenAddresses
(
s
)
if
err
!=
nil
{
log
.
Errorf
(
"Error retrieving swarm.InterfaceListenAddresses: %s"
,
err
)
return
}
addrutil
.
CheckNATWarning
(
observed
,
expected
,
listen
)
}
net/swarm/addr_test.go
→
net/swarm/
swarm_
addr_test.go
View file @
63145110
...
...
@@ -3,6 +3,7 @@ package swarm
import
(
"testing"
addrutil
"github.com/jbenet/go-ipfs/p2p/net/swarm/addr"
peer
"github.com/jbenet/go-ipfs/p2p/peer"
testutil
"github.com/jbenet/go-ipfs/util/testutil"
...
...
@@ -25,6 +26,8 @@ func TestFilterAddrs(t *testing.T) {
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
m
(
"/ip6/fe80::1/tcp/1234"
),
// link local
m
(
"/ip6/fe80::100/tcp/1234"
),
// link local
}
good
:=
[]
ma
.
Multiaddr
{
...
...
@@ -37,20 +40,20 @@ func TestFilterAddrs(t *testing.T) {
// test filters
for
_
,
a
:=
range
bad
{
if
AddrUsable
(
a
)
{
if
addrutil
.
AddrUsable
(
a
,
true
)
{
t
.
Errorf
(
"addr %s should be unusable"
,
a
)
}
}
for
_
,
a
:=
range
good
{
if
!
AddrUsable
(
a
)
{
if
!
addrutil
.
AddrUsable
(
a
,
true
)
{
t
.
Errorf
(
"addr %s should be usable"
,
a
)
}
}
subtestAddrsEqual
(
t
,
FilterAddrs
(
bad
),
[]
ma
.
Multiaddr
{})
subtestAddrsEqual
(
t
,
FilterAddrs
(
good
),
good
)
subtestAddrsEqual
(
t
,
FilterAddrs
(
goodAndBad
),
good
)
subtestAddrsEqual
(
t
,
addrutil
.
FilterAddrs
(
bad
),
[]
ma
.
Multiaddr
{})
subtestAddrsEqual
(
t
,
addrutil
.
FilterAddrs
(
good
),
good
)
subtestAddrsEqual
(
t
,
addrutil
.
FilterAddrs
(
goodAndBad
),
good
)
// now test it with swarm
...
...
@@ -95,3 +98,29 @@ func subtestAddrsEqual(t *testing.T, a, b []ma.Multiaddr) {
}
}
}
func
TestDialBadAddrs
(
t
*
testing
.
T
)
{
m
:=
func
(
s
string
)
ma
.
Multiaddr
{
maddr
,
err
:=
ma
.
NewMultiaddr
(
s
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
return
maddr
}
ctx
:=
context
.
Background
()
s
:=
makeSwarms
(
ctx
,
t
,
1
)[
0
]
test
:=
func
(
a
ma
.
Multiaddr
)
{
p
:=
testutil
.
RandPeerIDFatal
(
t
)
s
.
peers
.
AddAddress
(
p
,
a
)
if
_
,
err
:=
s
.
Dial
(
ctx
,
p
);
err
==
nil
{
t
.
Error
(
"swarm should not dial: %s"
,
m
)
}
}
test
(
m
(
"/ip6/fe80::1"
))
// link local
test
(
m
(
"/ip6/fe80::100"
))
// link local
test
(
m
(
"/ip4/127.0.0.1/udp/1234/utp"
))
// utp
}
net/swarm/swarm_dial.go
View file @
63145110
...
...
@@ -5,6 +5,7 @@ import (
"fmt"
conn
"github.com/jbenet/go-ipfs/p2p/net/conn"
addrutil
"github.com/jbenet/go-ipfs/p2p/net/swarm/addr"
peer
"github.com/jbenet/go-ipfs/p2p/peer"
lgbl
"github.com/jbenet/go-ipfs/util/eventlog/loggables"
...
...
@@ -38,6 +39,8 @@ func (s *Swarm) Dial(ctx context.Context, p peer.ID) (*Conn, error) {
}
remoteAddrs
:=
s
.
peers
.
Addresses
(
p
)
// make sure we can use the addresses.
remoteAddrs
=
addrutil
.
FilterAddrs
(
remoteAddrs
)
if
len
(
remoteAddrs
)
==
0
{
return
nil
,
errors
.
New
(
"peer has no addresses"
)
}
...
...
@@ -67,6 +70,9 @@ func (s *Swarm) Dial(ctx context.Context, p peer.ID) (*Conn, error) {
if
err
!=
nil
{
return
nil
,
err
}
if
connC
==
nil
{
err
=
fmt
.
Errorf
(
"failed to dial %s"
,
p
)
}
// ok try to setup the new connection.
swarmC
,
err
:=
dialConnSetup
(
ctx
,
s
,
connC
)
...
...
net/swarm/swarm_listen.go
View file @
63145110
...
...
@@ -4,6 +4,7 @@ import (
"fmt"
conn
"github.com/jbenet/go-ipfs/p2p/net/conn"
addrutil
"github.com/jbenet/go-ipfs/p2p/net/swarm/addr"
lgbl
"github.com/jbenet/go-ipfs/util/eventlog/loggables"
context
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
...
...
@@ -16,7 +17,7 @@ import (
func
(
s
*
Swarm
)
listen
(
addrs
[]
ma
.
Multiaddr
)
error
{
for
_
,
addr
:=
range
addrs
{
if
!
AddrUsable
(
addr
)
{
if
!
addrutil
.
AddrUsable
(
addr
,
true
)
{
return
fmt
.
Errorf
(
"cannot use addr: %s"
,
addr
)
}
}
...
...
@@ -59,10 +60,12 @@ func (s *Swarm) setupListener(maddr ma.Multiaddr) error {
// may be fine for sk to be nil, just log a warning.
log
.
Warning
(
"Listener not given PrivateKey, so WILL NOT SECURE conns."
)
}
log
.
Infof
(
"Swarm Listening at %s"
,
maddr
)
list
,
err
:=
conn
.
Listen
(
s
.
cg
.
Context
(),
maddr
,
s
.
local
,
sk
)
if
err
!=
nil
{
return
err
}
log
.
Infof
(
"Swarm Listening at %s"
,
s
.
ListenAddresses
())
// AddListener to the peerstream Listener. this will begin accepting connections
// and streams!
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment