diff --git a/net/conn/handshake.go b/net/conn/handshake.go index ab8cea8e3..9a155c5a1 100644 --- a/net/conn/handshake.go +++ b/net/conn/handshake.go @@ -6,9 +6,11 @@ import ( handshake "github.com/jbenet/go-ipfs/net/handshake" hspb "github.com/jbenet/go-ipfs/net/handshake/pb" + u "github.com/jbenet/go-ipfs/util" context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context" proto "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto" + ma "github.com/jbenet/go-multiaddr" ) // Handshake1 exchanges local and remote versions and compares them @@ -65,6 +67,10 @@ func Handshake3(ctx context.Context, c Conn) error { var remoteH, localH *hspb.Handshake3 localH = handshake.Handshake3Msg(lpeer) + + rma := c.RemoteMultiaddr() + localH.ObservedAddr = proto.String(rma.String()) + localB, err := proto.Marshal(localH) if err != nil { return err @@ -101,3 +107,18 @@ func Handshake3(ctx context.Context, c Conn) error { return nil } + +func CheckNAT(obsaddr string) (bool, error) { + oma, err := ma.NewMultiaddr(obsaddr) + if err != nil { + return false, err + } + addrs, err := u.GetLocalAddresses() + if err != nil { + return false, err + } + _ = oma + _ = addrs + + panic("not yet implemented!") +} diff --git a/net/handshake/pb/handshake.pb.go b/net/handshake/pb/handshake.pb.go index 2308297b9..2e641cdf5 100644 --- a/net/handshake/pb/handshake.pb.go +++ b/net/handshake/pb/handshake.pb.go @@ -14,15 +14,11 @@ It has these top-level messages: */ package handshake_pb -import proto "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/gogoprotobuf/proto" -import json "encoding/json" +import proto "code.google.com/p/gogoprotobuf/proto" import math "math" -// discarding unused import mux "github.com/jbenet/go-ipfs/net/mux/mux.pb" - -// Reference proto, json, and math imports to suppress error if they are not otherwise used. +// Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal -var _ = &json.SyntaxError{} var _ = math.Inf // Handshake1 is delivered _before_ the secure channel is initialized @@ -56,8 +52,10 @@ func (m *Handshake1) GetAgentVersion() string { // Handshake3 is delivered _after_ the secure channel is initialized type Handshake3 struct { // listenAddrs are the multiaddrs this node listens for open connections on - ListenAddrs [][]byte `protobuf:"bytes,2,rep,name=listenAddrs" json:"listenAddrs,omitempty"` - XXX_unrecognized []byte `json:"-"` + ListenAddrs [][]byte `protobuf:"bytes,2,rep,name=listenAddrs" json:"listenAddrs,omitempty"` + // we'll have more fields here later. + ObservedAddr *string `protobuf:"bytes,4,opt,name=observedAddr" json:"observedAddr,omitempty"` + XXX_unrecognized []byte `json:"-"` } func (m *Handshake3) Reset() { *m = Handshake3{} } @@ -71,5 +69,12 @@ func (m *Handshake3) GetListenAddrs() [][]byte { return nil } +func (m *Handshake3) GetObservedAddr() string { + if m != nil && m.ObservedAddr != nil { + return *m.ObservedAddr + } + return "" +} + func init() { } diff --git a/net/handshake/pb/handshake.proto b/net/handshake/pb/handshake.proto index 61e773b88..1e795d881 100644 --- a/net/handshake/pb/handshake.proto +++ b/net/handshake/pb/handshake.proto @@ -1,6 +1,6 @@ package handshake.pb; -import "github.com/jbenet/go-ipfs/net/mux/mux.proto"; +//import "github.com/jbenet/go-ipfs/net/mux/mux.proto"; // Handshake1 is delivered _before_ the secure channel is initialized message Handshake1 { @@ -30,4 +30,5 @@ message Handshake3 { // repeated mux.ProtocolID services = 3; // we'll have more fields here later. + optional string observedAddr = 4; } diff --git a/util/util.go b/util/util.go index 9ba3d62f7..0076322e2 100644 --- a/util/util.go +++ b/util/util.go @@ -4,12 +4,16 @@ import ( "errors" "io" "math/rand" + "net" "os" "path/filepath" + "reflect" "strings" "time" ds "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore" + 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" "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/mitchellh/go-homedir" ) @@ -107,3 +111,40 @@ func GetenvBool(name string) bool { v := strings.ToLower(os.Getenv(name)) return v == "true" || v == "t" || v == "1" } + +func IsLoopbackAddr(addr string) bool { + return addr == "/ip4/127.0.0.1" || addr == "/ip6/::1" +} + +func GetLocalAddresses() ([]ma.Multiaddr, error) { + ifaces, err := net.Interfaces() + if err != nil { + return nil, err + } + + var maddrs []ma.Multiaddr + for _, i := range ifaces { + addrs, err := i.Addrs() + if err != nil { + log.Warningf("Skipping addr: %s", err) + continue + } + for _, addr := range addrs { + switch v := addr.(type) { + case *net.IPNet: + maddr, err := manet.FromIP(v.IP) + if err != nil { + log.Errorf("maddr parsing error: %s", err) + continue + } + if IsLoopbackAddr(maddr.String()) { + continue + } + maddrs = append(maddrs, maddr) + default: + log.Errorf("Got '%s' type = '%s'", v, reflect.TypeOf(v)) + } + } + } + return maddrs, nil +}