Merge pull request #380 from nspcc-dev/drop-endpoint-fix-321

util: drop Endpoint structure, fix #321
This commit is contained in:
Roman Khimov 2019-09-09 19:39:49 +03:00 committed by GitHub
commit 33bb371f9b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 50 additions and 85 deletions

View file

@ -2,6 +2,7 @@ package network
import ( import (
"math/rand" "math/rand"
"net"
"testing" "testing"
"time" "time"
@ -111,22 +112,23 @@ func (t localTransport) Close() {}
var defaultMessageHandler = func(t *testing.T, msg *Message) {} var defaultMessageHandler = func(t *testing.T, msg *Message) {}
type localPeer struct { type localPeer struct {
endpoint util.Endpoint netaddr net.TCPAddr
version *payload.Version version *payload.Version
t *testing.T t *testing.T
messageHandler func(t *testing.T, msg *Message) messageHandler func(t *testing.T, msg *Message)
} }
func newLocalPeer(t *testing.T) *localPeer { func newLocalPeer(t *testing.T) *localPeer {
naddr, _ := net.ResolveTCPAddr("tcp", "0.0.0.0:0")
return &localPeer{ return &localPeer{
t: t, t: t,
endpoint: util.NewEndpoint("0.0.0.0:0"), netaddr: *naddr,
messageHandler: defaultMessageHandler, messageHandler: defaultMessageHandler,
} }
} }
func (p *localPeer) Endpoint() util.Endpoint { func (p *localPeer) NetAddr() *net.TCPAddr {
return p.endpoint return &p.netaddr
} }
func (p *localPeer) Disconnect(err error) {} func (p *localPeer) Disconnect(err error) {}
func (p *localPeer) WriteMsg(msg *Message) error { func (p *localPeer) WriteMsg(msg *Message) error {

View file

@ -2,6 +2,7 @@ package payload
import ( import (
"io" "io"
"net"
"time" "time"
"github.com/CityOfZion/neo-go/pkg/util" "github.com/CityOfZion/neo-go/pkg/util"
@ -11,16 +12,19 @@ import (
type AddressAndTime struct { type AddressAndTime struct {
Timestamp uint32 Timestamp uint32
Services uint64 Services uint64
Endpoint util.Endpoint IP [16]byte
Port uint16
} }
// NewAddressAndTime creates a new AddressAndTime object. // NewAddressAndTime creates a new AddressAndTime object.
func NewAddressAndTime(e util.Endpoint, t time.Time) *AddressAndTime { func NewAddressAndTime(e *net.TCPAddr, t time.Time) *AddressAndTime {
return &AddressAndTime{ aat := AddressAndTime{
Timestamp: uint32(t.UTC().Unix()), Timestamp: uint32(t.UTC().Unix()),
Services: 1, Services: 1,
Endpoint: e, Port: uint16(e.Port),
} }
copy(aat.IP[:], e.IP)
return &aat
} }
// DecodeBinary implements the Payload interface. // DecodeBinary implements the Payload interface.
@ -28,8 +32,8 @@ func (p *AddressAndTime) DecodeBinary(r io.Reader) error {
br := util.BinReader{R: r} br := util.BinReader{R: r}
br.ReadLE(&p.Timestamp) br.ReadLE(&p.Timestamp)
br.ReadLE(&p.Services) br.ReadLE(&p.Services)
br.ReadBE(&p.Endpoint.IP) br.ReadBE(&p.IP)
br.ReadBE(&p.Endpoint.Port) br.ReadBE(&p.Port)
return br.Err return br.Err
} }
@ -38,8 +42,8 @@ func (p *AddressAndTime) EncodeBinary(w io.Writer) error {
bw := util.BinWriter{W: w} bw := util.BinWriter{W: w}
bw.WriteLE(p.Timestamp) bw.WriteLE(p.Timestamp)
bw.WriteLE(p.Services) bw.WriteLE(p.Services)
bw.WriteBE(p.Endpoint.IP) bw.WriteBE(p.IP)
bw.WriteBE(p.Endpoint.Port) bw.WriteBE(p.Port)
return bw.Err return bw.Err
} }

View file

@ -3,23 +3,26 @@ package payload
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"net"
"testing" "testing"
"time" "time"
"github.com/CityOfZion/neo-go/pkg/util"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func TestEncodeDecodeAddress(t *testing.T) { func TestEncodeDecodeAddress(t *testing.T) {
var ( var (
e = util.NewEndpoint("127.0.0.1:2000") e, _ = net.ResolveTCPAddr("tcp", "127.0.0.1:2000")
ts = time.Now() ts = time.Now()
addr = NewAddressAndTime(e, ts) addr = NewAddressAndTime(e, ts)
buf = new(bytes.Buffer) buf = new(bytes.Buffer)
) )
assert.Equal(t, ts.UTC().Unix(), int64(addr.Timestamp)) assert.Equal(t, ts.UTC().Unix(), int64(addr.Timestamp))
assert.Equal(t, e, addr.Endpoint) aatip := make(net.IP, 16)
copy(aatip, addr.IP[:])
assert.Equal(t, e.IP, aatip)
assert.Equal(t, e.Port, int(addr.Port))
err := addr.EncodeBinary(buf) err := addr.EncodeBinary(buf)
assert.Nil(t, err) assert.Nil(t, err)
@ -34,7 +37,7 @@ func TestEncodeDecodeAddressList(t *testing.T) {
var lenList uint8 = 4 var lenList uint8 = 4
addrList := &AddressList{make([]*AddressAndTime, lenList)} addrList := &AddressList{make([]*AddressAndTime, lenList)}
for i := 0; i < int(lenList); i++ { for i := 0; i < int(lenList); i++ {
e := util.NewEndpoint(fmt.Sprintf("127.0.0.1:200%d", i)) e, _ := net.ResolveTCPAddr("tcp", fmt.Sprintf("127.0.0.1:200%d", i))
addrList.Addrs[i] = NewAddressAndTime(e, time.Now()) addrList.Addrs[i] = NewAddressAndTime(e, time.Now())
} }

View file

@ -1,13 +1,14 @@
package network package network
import ( import (
"net"
"github.com/CityOfZion/neo-go/pkg/network/payload" "github.com/CityOfZion/neo-go/pkg/network/payload"
"github.com/CityOfZion/neo-go/pkg/util"
) )
// Peer represents a network node neo-go is connected to. // Peer represents a network node neo-go is connected to.
type Peer interface { type Peer interface {
Endpoint() util.Endpoint NetAddr() *net.TCPAddr
Disconnect(error) Disconnect(error)
WriteMsg(msg *Message) error WriteMsg(msg *Message) error
Done() chan error Done() chan error

View file

@ -133,17 +133,17 @@ func (s *Server) run() {
// When a new peer is connected we send out our version immediately. // When a new peer is connected we send out our version immediately.
if err := s.sendVersion(p); err != nil { if err := s.sendVersion(p); err != nil {
log.WithFields(log.Fields{ log.WithFields(log.Fields{
"endpoint": p.Endpoint(), "addr": p.NetAddr(),
}).Error(err) }).Error(err)
} }
s.peers[p] = true s.peers[p] = true
log.WithFields(log.Fields{ log.WithFields(log.Fields{
"endpoint": p.Endpoint(), "addr": p.NetAddr(),
}).Info("new peer connected") }).Info("new peer connected")
case drop := <-s.unregister: case drop := <-s.unregister:
delete(s.peers, drop.peer) delete(s.peers, drop.peer)
log.WithFields(log.Fields{ log.WithFields(log.Fields{
"endpoint": drop.peer.Endpoint(), "addr": drop.peer.NetAddr(),
"reason": drop.reason, "reason": drop.reason,
"peerCount": s.PeerCount(), "peerCount": s.PeerCount(),
}).Warn("peer disconnected") }).Warn("peer disconnected")
@ -168,7 +168,7 @@ func (s *Server) PeerCount() int {
// every ProtoTickInterval with the peer. // every ProtoTickInterval with the peer.
func (s *Server) startProtocol(p Peer) { func (s *Server) startProtocol(p Peer) {
log.WithFields(log.Fields{ log.WithFields(log.Fields{
"endpoint": p.Endpoint(), "addr": p.NetAddr(),
"userAgent": string(p.Version().UserAgent), "userAgent": string(p.Version().UserAgent),
"startHeight": p.Version().StartHeight, "startHeight": p.Version().StartHeight,
"id": p.Version().Nonce, "id": p.Version().Nonce,
@ -207,7 +207,7 @@ func (s *Server) sendVersion(p Peer) error {
// When a peer sends out his version we reply with verack after validating // When a peer sends out his version we reply with verack after validating
// the version. // the version.
func (s *Server) handleVersionCmd(p Peer, version *payload.Version) error { func (s *Server) handleVersionCmd(p Peer, version *payload.Version) error {
if p.Endpoint().Port != version.Port { if p.NetAddr().Port != int(version.Port) {
return errPortMismatch return errPortMismatch
} }
if s.id == version.Nonce { if s.id == version.Nonce {

View file

@ -1,10 +1,10 @@
package network package network
import ( import (
"net"
"testing" "testing"
"github.com/CityOfZion/neo-go/pkg/network/payload" "github.com/CityOfZion/neo-go/pkg/network/payload"
"github.com/CityOfZion/neo-go/pkg/util"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -39,7 +39,8 @@ func TestVerackAfterHandleVersionCmd(t *testing.T) {
s = newTestServer() s = newTestServer()
p = newLocalPeer(t) p = newLocalPeer(t)
) )
p.endpoint = util.NewEndpoint("0.0.0.0:3000") na, _ := net.ResolveTCPAddr("tcp", "0.0.0.0:3000")
p.netaddr = *na
// Should have a verack // Should have a verack
p.messageHandler = func(t *testing.T, msg *Message) { p.messageHandler = func(t *testing.T, msg *Message) {
@ -62,7 +63,8 @@ func TestServerNotSendsVerack(t *testing.T) {
s.id = 1 s.id = 1
go s.run() go s.run()
p.endpoint = util.NewEndpoint("0.0.0.0:3000") na, _ := net.ResolveTCPAddr("tcp", "0.0.0.0:3000")
p.netaddr = *na
s.register <- p s.register <- p
// Port should mismatch // Port should mismatch

View file

@ -5,15 +5,14 @@ import (
"sync" "sync"
"github.com/CityOfZion/neo-go/pkg/network/payload" "github.com/CityOfZion/neo-go/pkg/network/payload"
"github.com/CityOfZion/neo-go/pkg/util"
) )
// TCPPeer represents a connected remote node in the // TCPPeer represents a connected remote node in the
// network over TCP. // network over TCP.
type TCPPeer struct { type TCPPeer struct {
// underlying TCP connection. // underlying TCP connection.
conn net.Conn conn net.Conn
endpoint util.Endpoint addr net.TCPAddr
// The version of the peer. // The version of the peer.
version *payload.Version version *payload.Version
@ -25,10 +24,13 @@ type TCPPeer struct {
// NewTCPPeer returns a TCPPeer structure based on the given connection. // NewTCPPeer returns a TCPPeer structure based on the given connection.
func NewTCPPeer(conn net.Conn) *TCPPeer { func NewTCPPeer(conn net.Conn) *TCPPeer {
raddr := conn.RemoteAddr()
// can't fail because raddr is a real connection
tcpaddr, _ := net.ResolveTCPAddr(raddr.Network(), raddr.String())
return &TCPPeer{ return &TCPPeer{
conn: conn, conn: conn,
done: make(chan error, 1), done: make(chan error, 1),
endpoint: util.NewEndpoint(conn.RemoteAddr().String()), addr: *tcpaddr,
} }
} }
@ -43,9 +45,9 @@ func (p *TCPPeer) WriteMsg(msg *Message) error {
} }
} }
// Endpoint implements the Peer interface. // NetAddr implements the Peer interface.
func (p *TCPPeer) Endpoint() util.Endpoint { func (p *TCPPeer) NetAddr() *net.TCPAddr {
return p.endpoint return &p.addr
} }
// Done implements the Peer interface and notifies // Done implements the Peer interface and notifies

View file

@ -180,7 +180,7 @@ Methods:
} }
for addr := range s.coreServer.Peers() { for addr := range s.coreServer.Peers() {
peers.AddPeer("connected", addr.Endpoint().String()) peers.AddPeer("connected", addr.NetAddr().String())
} }
results = peers results = peers

View file

@ -1,49 +0,0 @@
package util
import (
"fmt"
"strconv"
"strings"
)
// Endpoint host + port of a node, compatible with net.Addr.
type Endpoint struct {
IP [16]byte // TODO: make a uint128 type
Port uint16
}
// NewEndpoint creates an Endpoint from the given string.
func NewEndpoint(s string) (e Endpoint) {
hostPort := strings.Split(s, ":")
if len(hostPort) != 2 {
return e
}
host := hostPort[0]
port := hostPort[1]
ch := strings.Split(host, ".")
buf := [16]byte{}
var n int
for i := 0; i < len(ch); i++ {
n = 12 + i
nn, _ := strconv.Atoi(ch[i])
buf[n] = byte(nn)
}
p, _ := strconv.Atoi(port)
return Endpoint{buf, uint16(p)}
}
// Network implements the net.Addr interface.
func (e Endpoint) Network() string { return "tcp" }
// String implements the net.Addr interface.
func (e Endpoint) String() string {
b := make([]uint8, 4)
for i := 0; i < 4; i++ {
b[i] = e.IP[len(e.IP)-4+i]
}
return fmt.Sprintf("%d.%d.%d.%d:%d", b[0], b[1], b[2], b[3], e.Port)
}