changes from PR
Jeromy committed
Nov 3, 2014 at 01:45 UTC
402fdd2db9ded7ef5811b6e8a7f57dfd22b433f5
5 files changed
+39
-8
net/conn/dial.go
-5
@@ -8,7 +8,6 @@ import (
8
manet "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net"
9
10
peer "github.com/jbenet/go-ipfs/peer"
11
- "github.com/jbenet/go-ipfs/util"
11
)
12
13
// Dial connects to a particular peer, over a given network
@@ -24,10 +23,6 @@ func (d *Dialer) Dial(ctx context.Context, network string, remote peer.Peer) (Co
23
return nil, fmt.Errorf("No remote address for network %s", network)
24
}
25
27
- if util.IsLoopbackAddr(raddr.String()) {
28
- return nil, fmt.Errorf("Attempted to connect to loopback address: %s", raddr)
29
- }
30
-
26
remote, err := d.Peerstore.Add(remote)
27
if err != nil {
28
log.Errorf("Error putting peer into peerstore: %s", remote)
net/conn/handshake.go
+13
-3
@@ -106,18 +106,28 @@ func Handshake3(ctx context.Context, c Conn) error {
106
return err
107
}
108
109
- nat, err := CheckNAT(remoteH.GetObservedAddr())
109
+ // If we are behind a NAT, inform the user that certain things might not work yet
110
+ nat, err := checkNAT(remoteH.GetObservedAddr())
111
if err != nil {
112
log.Errorf("Error in NAT detection: %s", err)
113
}
114
if nat {
114
- log.Warning("We are probably behind a NAT!")
115
+ msg := `Remote peer observed our address to be: %s
116
+ The local addresses are: %s
117
+ Thus, connection is going through NAT, and other connections may fail.
118
+
119
+ IPFS NAT traversal is still under development. Please bug us on github or irc to fix this.
120
+ Baby steps: http://jbenet.static.s3.amazonaws.com/271dfcf/baby-steps.gif
121
+ `
122
+ addrs, _ := u.GetLocalAddresses()
123
+ log.Warning(fmt.Sprintf(msg, remoteH.GetObservedAddr(), addrs))
124
}
125
126
return nil
127
}
128
120
-func CheckNAT(obsaddr string) (bool, error) {
129
+// checkNAT returns whether or not we might be behind a NAT
130
+func checkNAT(obsaddr string) (bool, error) {
131
oma, err := ma.NewMultiaddr(obsaddr)
132
if err != nil {
133
return false, err
net/handshake/pb/handshake.proto
+4
@@ -30,5 +30,9 @@ message Handshake3 {
30
// repeated mux.ProtocolID services = 3;
31
32
// we'll have more fields here later.
33
+
34
+ // oservedAddr is the multiaddr of the remote endpoint that the local node perceives
35
+ // this is useful information to convey to the other side, as it helps the remote endpoint
36
+ // determine whether its connection to the local peer goes through NAT.
37
optional string observedAddr = 4;
38
}
net/swarm/swarm.go
+11
@@ -3,6 +3,7 @@ package swarm
3
import (
4
"errors"
5
"fmt"
6
+ "strings"
7
"sync"
8
9
conn "github.com/jbenet/go-ipfs/net/conn"
@@ -127,6 +128,16 @@ func (s *Swarm) Dial(peer peer.Peer) (conn.Conn, error) {
128
Peerstore: s.peers,
129
}
130
131
+ // If we are attempting to connect to a loopback addr, fail out early
132
+ raddr := peer.NetAddress("tcp")
133
+ if raddr == nil {
134
+ return nil, fmt.Errorf("No remote address for network tcp")
135
+ }
136
+
137
+ if strings.HasPrefix(raddr.String(), "/ip4/0.0.0.0") {
138
+ return nil, fmt.Errorf("Attempted to connect to loopback address: %s", raddr)
139
+ }
140
+
141
c, err = d.Dial(s.Context(), "tcp", peer)
142
if err != nil {
143
return nil, err
util/util.go
+11
@@ -112,6 +112,8 @@ func GetenvBool(name string) bool {
112
return v == "true" || v == "t" || v == "1"
113
}
114
115
+// IsLoopbackAddr returns whether or not the ip portion of the passed in multiaddr
116
+// string is a loopback address
117
func IsLoopbackAddr(addr string) bool {
118
loops := []string{"/ip4/127.0.0.1", "/ip6/::1", "/ip4/0.0.0.0"}
119
for _, loop := range loops {
@@ -122,7 +124,10 @@ func IsLoopbackAddr(addr string) bool {
124
return false
125
}
126
127
+// GetLocalAddresses returns a list of ip addresses associated with
128
+// the local machine
129
func GetLocalAddresses() ([]ma.Multiaddr, error) {
130
+ // Enumerate interfaces on this machine
131
ifaces, err := net.Interfaces()
132
if err != nil {
133
return nil, err
@@ -135,19 +140,25 @@ func GetLocalAddresses() ([]ma.Multiaddr, error) {
140
log.Warningf("Skipping addr: %s", err)
141
continue
142
}
143
+ // Check each address and convert to a multiaddr
144
for _, addr := range addrs {
145
switch v := addr.(type) {
146
case *net.IPNet:
147
+
148
+ // Build multiaddr
149
maddr, err := manet.FromIP(v.IP)
150
if err != nil {
151
log.Errorf("maddr parsing error: %s", err)
152
continue
153
}
154
+
155
+ // Dont list loopback addresses
156
if IsLoopbackAddr(maddr.String()) {
157
continue
158
}
159
maddrs = append(maddrs, maddr)
160
default:
161
+ // Not sure if any other types will show up here
162
log.Errorf("Got '%s' type = '%s'", v, reflect.TypeOf(v))
163
}
164
}