From f18261cd3d75671888ac916e370e2856a4919f13 Mon Sep 17 00:00:00 2001
From: Wolfgang Welz <welzwo@gmail.com>
Date: Wed, 18 Dec 2019 12:34:18 +0100
Subject: [PATCH] Fix wrong fromAddr

---
 packages/gossip/manager_test.go               | 17 ++++++-
 packages/gossip/transport/handshake.go        | 15 +++----
 .../gossip/transport/proto/handshake.pb.go    | 41 +++++++----------
 .../gossip/transport/proto/handshake.proto    |  6 +--
 packages/gossip/transport/transport.go        | 44 ++++++++++---------
 packages/gossip/transport/transport_test.go   | 17 +++++--
 6 files changed, 75 insertions(+), 65 deletions(-)

diff --git a/packages/gossip/manager_test.go b/packages/gossip/manager_test.go
index ea9ca56b..df9e8333 100644
--- a/packages/gossip/manager_test.go
+++ b/packages/gossip/manager_test.go
@@ -2,6 +2,7 @@ package gossip
 
 import (
 	"log"
+	"net"
 	"sync"
 	"testing"
 	"time"
@@ -56,12 +57,26 @@ func getTestTransaction([]byte) ([]byte, error) {
 	return testTxData, nil
 }
 
+func getTCPAddress(t require.TestingT) string {
+	laddr, err := net.ResolveTCPAddr("tcp", "localhost:0")
+	require.NoError(t, err)
+	lis, err := net.ListenTCP("tcp", laddr)
+	require.NoError(t, err)
+
+	addr := lis.Addr().String()
+	require.NoError(t, lis.Close())
+
+	return addr
+}
+
 func newTest(t require.TestingT, name string) (*Manager, func(), *peer.Peer) {
 	l := logger.Named(name)
 	db := peer.NewMemoryDB(l.Named("db"))
 	local, err := peer.NewLocal("peering", name, db)
 	require.NoError(t, err)
-	require.NoError(t, local.UpdateService(service.GossipKey, "tcp", "localhost:0"))
+
+	// enable TCP gossipping
+	require.NoError(t, local.UpdateService(service.GossipKey, "tcp", getTCPAddress(t)))
 
 	trans, err := transport.Listen(local, l)
 	require.NoError(t, err)
diff --git a/packages/gossip/transport/handshake.go b/packages/gossip/transport/handshake.go
index a33b3329..3489a9d6 100644
--- a/packages/gossip/transport/handshake.go
+++ b/packages/gossip/transport/handshake.go
@@ -19,10 +19,9 @@ func isExpired(ts int64) bool {
 	return time.Since(time.Unix(ts, 0)) >= handshakeExpiration
 }
 
-func newHandshakeRequest(fromAddr string, toAddr string) ([]byte, error) {
+func newHandshakeRequest(toAddr string) ([]byte, error) {
 	m := &pb.HandshakeRequest{
 		Version:   versionNum,
-		From:      fromAddr,
 		To:        toAddr,
 		Timestamp: time.Now().Unix(),
 	}
@@ -36,7 +35,7 @@ func newHandshakeResponse(reqData []byte) ([]byte, error) {
 	return proto.Marshal(m)
 }
 
-func (t *TCP) validateHandshakeRequest(reqData []byte, fromAddr string) bool {
+func (t *TCP) validateHandshakeRequest(reqData []byte) bool {
 	m := new(pb.HandshakeRequest)
 	if err := proto.Unmarshal(reqData, m); err != nil {
 		t.log.Debugw("invalid handshake",
@@ -47,18 +46,14 @@ func (t *TCP) validateHandshakeRequest(reqData []byte, fromAddr string) bool {
 	if m.GetVersion() != versionNum {
 		t.log.Debugw("invalid handshake",
 			"version", m.GetVersion(),
+			"want", versionNum,
 		)
 		return false
 	}
-	if m.GetFrom() != fromAddr {
-		t.log.Debugw("invalid handshake",
-			"from", m.GetFrom(),
-		)
-		return false
-	}
-	if m.GetTo() != t.pubAddr {
+	if m.GetTo() != t.publicAddr.String() {
 		t.log.Debugw("invalid handshake",
 			"to", m.GetTo(),
+			"want", t.publicAddr.String(),
 		)
 		return false
 	}
diff --git a/packages/gossip/transport/proto/handshake.pb.go b/packages/gossip/transport/proto/handshake.pb.go
index c7f36887..da559c81 100644
--- a/packages/gossip/transport/proto/handshake.pb.go
+++ b/packages/gossip/transport/proto/handshake.pb.go
@@ -23,12 +23,10 @@ const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
 type HandshakeRequest struct {
 	// protocol version number
 	Version uint32 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"`
-	// string form of the sender address (e.g. "192.0.2.1:25", "[2001:db8::1]:80")
-	From string `protobuf:"bytes,2,opt,name=from,proto3" json:"from,omitempty"`
 	// string form of the recipient address
-	To string `protobuf:"bytes,3,opt,name=to,proto3" json:"to,omitempty"`
+	To string `protobuf:"bytes,2,opt,name=to,proto3" json:"to,omitempty"`
 	// unix time
-	Timestamp            int64    `protobuf:"varint,4,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
+	Timestamp            int64    `protobuf:"varint,3,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
 	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 	XXX_unrecognized     []byte   `json:"-"`
 	XXX_sizecache        int32    `json:"-"`
@@ -66,13 +64,6 @@ func (m *HandshakeRequest) GetVersion() uint32 {
 	return 0
 }
 
-func (m *HandshakeRequest) GetFrom() string {
-	if m != nil {
-		return m.From
-	}
-	return ""
-}
-
 func (m *HandshakeRequest) GetTo() string {
 	if m != nil {
 		return m.To
@@ -135,18 +126,18 @@ func init() {
 func init() { proto.RegisterFile("transport/proto/handshake.proto", fileDescriptor_d7101ffe19b05443) }
 
 var fileDescriptor_d7101ffe19b05443 = []byte{
-	// 203 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x5c, 0x8f, 0x3f, 0x4b, 0x04, 0x31,
-	0x10, 0xc5, 0xb9, 0x3f, 0x7a, 0xde, 0xa0, 0xa2, 0xa9, 0x22, 0x08, 0xca, 0x55, 0x82, 0xb8, 0x29,
-	0xfc, 0x06, 0x56, 0x57, 0xa7, 0xb4, 0x91, 0xec, 0x3a, 0x6e, 0x82, 0x26, 0x93, 0xcd, 0x64, 0xfd,
-	0xfc, 0x0e, 0x81, 0x45, 0xb1, 0x7a, 0xef, 0xf7, 0x0b, 0xe4, 0x25, 0x70, 0x57, 0x8b, 0x4b, 0x9c,
-	0xa9, 0x54, 0x93, 0x0b, 0x55, 0x32, 0xde, 0xa5, 0x77, 0xf6, 0xee, 0x13, 0xbb, 0xc6, 0xea, 0xa4,
-	0xc5, 0x21, 0xc1, 0xd5, 0x71, 0x39, 0xb1, 0x38, 0xcd, 0xc8, 0x55, 0x69, 0xd8, 0x7d, 0x63, 0xe1,
-	0x40, 0x49, 0xaf, 0xee, 0x57, 0x0f, 0x17, 0x76, 0x41, 0xa5, 0x60, 0xfb, 0x51, 0x28, 0xea, 0xb5,
-	0xe8, 0xbd, 0x6d, 0x5d, 0x5d, 0xc2, 0xba, 0x92, 0xde, 0x34, 0x23, 0x4d, 0xdd, 0xc2, 0xbe, 0x86,
-	0x28, 0xf7, 0xb8, 0x98, 0xf5, 0x56, 0xf4, 0xc6, 0xfe, 0x8a, 0x43, 0x07, 0xd7, 0x7f, 0xf6, 0xe4,
-	0x81, 0x89, 0x51, 0xdd, 0xc0, 0x59, 0xc1, 0xe9, 0xcd, 0x3b, 0xf6, 0x6d, 0xf1, 0xdc, 0xee, 0x84,
-	0x8f, 0x82, 0x2f, 0x4f, 0xaf, 0x8f, 0x63, 0xa8, 0x7e, 0xee, 0xbb, 0x81, 0xa2, 0x19, 0x5c, 0x26,
-	0x66, 0xfc, 0x42, 0x33, 0x4a, 0x86, 0x6c, 0xfe, 0xfd, 0xb2, 0x3f, 0x6d, 0xf1, 0xfc, 0x13, 0x00,
-	0x00, 0xff, 0xff, 0x51, 0xe0, 0x08, 0xd0, 0xff, 0x00, 0x00, 0x00,
+	// 206 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x5c, 0x8f, 0x31, 0x4b, 0x83, 0x31,
+	0x10, 0x86, 0x69, 0x8b, 0xd6, 0x06, 0x15, 0xcd, 0xf4, 0x09, 0x82, 0xd2, 0xc9, 0xe9, 0xcb, 0xe0,
+	0x0f, 0x10, 0x9d, 0x3a, 0x67, 0xec, 0x22, 0xd7, 0xf6, 0x48, 0x42, 0x4d, 0x2e, 0xcd, 0x5d, 0xfd,
+	0xfd, 0x9e, 0x81, 0xa2, 0x74, 0x7a, 0xdf, 0xe7, 0x09, 0x79, 0x49, 0xcc, 0x93, 0x34, 0x28, 0x5c,
+	0xa9, 0x89, 0xab, 0x8d, 0x84, 0x5c, 0x84, 0xb2, 0xe3, 0x08, 0x7b, 0x1c, 0x3b, 0xdb, 0x8b, 0x1e,
+	0xcb, 0xb5, 0xb9, 0x5b, 0x9d, 0x4e, 0x3c, 0x1e, 0x8e, 0xc8, 0x62, 0x07, 0x33, 0xff, 0xc6, 0xc6,
+	0x89, 0xca, 0x30, 0x79, 0x9e, 0xbc, 0xdc, 0xf8, 0x13, 0xda, 0x5b, 0x33, 0x15, 0x1a, 0xa6, 0x2a,
+	0x17, 0x5e, 0x9b, 0x7d, 0x34, 0x0b, 0x49, 0x59, 0xef, 0x40, 0xae, 0xc3, 0x4c, 0xf5, 0xcc, 0xff,
+	0x89, 0xe5, 0x68, 0xee, 0xff, 0x6d, 0xeb, 0x63, 0x0a, 0xa3, 0x7d, 0x30, 0x57, 0x0d, 0x0f, 0x9f,
+	0x11, 0x38, 0xf6, 0xf5, 0x6b, 0x3f, 0x57, 0x5e, 0x29, 0x7e, 0xbc, 0xaf, 0xdf, 0x42, 0x92, 0x78,
+	0xdc, 0x8c, 0x5b, 0xca, 0x2e, 0x91, 0xc0, 0x17, 0xee, 0x02, 0x36, 0x17, 0x88, 0x63, 0xca, 0x59,
+	0x5b, 0x85, 0xed, 0x1e, 0x02, 0xf2, 0xaf, 0xe2, 0x54, 0xdd, 0xd9, 0x2f, 0x37, 0x97, 0x3d, 0x5e,
+	0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0x51, 0x6a, 0x20, 0xf4, 0xff, 0x00, 0x00, 0x00,
 }
diff --git a/packages/gossip/transport/proto/handshake.proto b/packages/gossip/transport/proto/handshake.proto
index 68537177..c2242c27 100644
--- a/packages/gossip/transport/proto/handshake.proto
+++ b/packages/gossip/transport/proto/handshake.proto
@@ -7,12 +7,10 @@ package proto;
 message HandshakeRequest {
   // protocol version number
   uint32 version = 1;
-  // string form of the sender address (e.g. "192.0.2.1:25", "[2001:db8::1]:80")
-  string from = 2;
   // string form of the recipient address
-  string to = 3;
+  string to = 2;
   // unix time
-  int64 timestamp = 4;
+  int64 timestamp = 3;
 }
 
 message HandshakeResponse {
diff --git a/packages/gossip/transport/transport.go b/packages/gossip/transport/transport.go
index 61690e0f..e379f001 100644
--- a/packages/gossip/transport/transport.go
+++ b/packages/gossip/transport/transport.go
@@ -40,10 +40,10 @@ const (
 
 // TCP establishes verified incoming and outgoing TCP connections to other peers.
 type TCP struct {
-	local    *peer.Local
-	pubAddr  string
-	listener *net.TCPListener
-	log      *zap.SugaredLogger
+	local      *peer.Local
+	publicAddr net.Addr
+	listener   *net.TCPListener
+	log        *zap.SugaredLogger
 
 	addAcceptMatcher chan *acceptMatcher
 	acceptReceived   chan accept
@@ -81,27 +81,32 @@ func Listen(local *peer.Local, log *zap.SugaredLogger) (*TCP, error) {
 		closing:          make(chan struct{}),
 	}
 
-	gossipAddr := local.Services().Get(service.GossipKey)
-	if gossipAddr == nil {
+	t.publicAddr = local.Services().Get(service.GossipKey)
+	if t.publicAddr == nil {
 		return nil, ErrNoGossip
 	}
-
-	t.pubAddr = gossipAddr.String()
-
-	host, port, _ := net.SplitHostPort(gossipAddr.String())
-	if host != "127.0.0.1" {
-		host = "0.0.0.0"
-	}
-
-	tcpAddr, err := net.ResolveTCPAddr(gossipAddr.Network(), host+":"+port)
+	tcpAddr, err := net.ResolveTCPAddr(t.publicAddr.Network(), t.publicAddr.String())
 	if err != nil {
 		return nil, err
 	}
-	listener, err := net.ListenTCP(gossipAddr.Network(), tcpAddr)
+	// if the ip is an external ip, set it to zero
+	if tcpAddr.IP.IsGlobalUnicast() {
+		if len(tcpAddr.IP) == net.IPv4len {
+			tcpAddr.IP = net.IPv4zero
+		} else if len(tcpAddr.IP) == net.IPv6len {
+			tcpAddr.IP = net.IPv6zero
+		}
+	}
+
+	listener, err := net.ListenTCP(t.publicAddr.Network(), tcpAddr)
 	if err != nil {
 		return nil, err
 	}
 	t.listener = listener
+	t.log.Debugw("listening started",
+		"network", listener.Addr().Network(),
+		"address", listener.Addr().String(),
+	)
 
 	t.wg.Add(2)
 	go t.run()
@@ -303,10 +308,7 @@ func (t *TCP) listenLoop() {
 }
 
 func (t *TCP) doHandshake(key peer.PublicKey, remoteAddr string, conn net.Conn) error {
-	_, connPort, _ := net.SplitHostPort(conn.LocalAddr().String())
-	from, _, _ := net.SplitHostPort(t.pubAddr)
-
-	reqData, err := newHandshakeRequest(from+":"+connPort, remoteAddr)
+	reqData, err := newHandshakeRequest(remoteAddr)
 	if err != nil {
 		return err
 	}
@@ -377,7 +379,7 @@ func (t *TCP) readHandshakeRequest(conn net.Conn) (peer.PublicKey, []byte, error
 		return nil, nil, err
 	}
 
-	if !t.validateHandshakeRequest(pkt.GetData(), conn.RemoteAddr().String()) {
+	if !t.validateHandshakeRequest(pkt.GetData()) {
 		return nil, nil, ErrInvalidHandshake
 	}
 
diff --git a/packages/gossip/transport/transport_test.go b/packages/gossip/transport/transport_test.go
index 51b64b81..7c1fecf6 100644
--- a/packages/gossip/transport/transport_test.go
+++ b/packages/gossip/transport/transport_test.go
@@ -26,6 +26,18 @@ func init() {
 	logger = l.Sugar()
 }
 
+func getTCPAddress(t require.TestingT) string {
+	laddr, err := net.ResolveTCPAddr("tcp", "localhost:0")
+	require.NoError(t, err)
+	lis, err := net.ListenTCP("tcp", laddr)
+	require.NoError(t, err)
+
+	addr := lis.Addr().String()
+	require.NoError(t, lis.Close())
+
+	return addr
+}
+
 func newTest(t require.TestingT, name string) (*TCP, func()) {
 	l := logger.Named(name)
 	db := peer.NewMemoryDB(l.Named("db"))
@@ -33,14 +45,11 @@ func newTest(t require.TestingT, name string) (*TCP, func()) {
 	require.NoError(t, err)
 
 	// enable TCP gossipping
-	require.NoError(t, local.UpdateService(service.GossipKey, "tcp", "localhost:0"))
+	require.NoError(t, local.UpdateService(service.GossipKey, "tcp", getTCPAddress(t)))
 
 	trans, err := Listen(local, l)
 	require.NoError(t, err)
 
-	// update the service with the actual address
-	require.NoError(t, local.UpdateService(service.GossipKey, trans.LocalAddr().Network(), trans.LocalAddr().String()))
-
 	teardown := func() {
 		trans.Close()
 		db.Close()
-- 
GitLab