forked from TrueCloudLab/neoneo-go
handle address list message.
This commit is contained in:
parent
1eab73d560
commit
1821ff1a0e
4 changed files with 54 additions and 17 deletions
|
@ -3,16 +3,30 @@ package payload
|
|||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Endpoint host + port of a node.
|
||||
// Endpoint host + port of a node, compatible with net.Addr.
|
||||
type Endpoint struct {
|
||||
IP [16]byte // TODO: make a uint128 type
|
||||
Port uint16
|
||||
}
|
||||
|
||||
// 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] = byte(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)
|
||||
}
|
||||
|
||||
// AddrWithTime payload
|
||||
type AddrWithTime struct {
|
||||
// Timestamp the node connected to the network.
|
||||
Timestamp uint32
|
||||
Services uint64
|
||||
Addr Endpoint
|
||||
|
|
|
@ -7,7 +7,8 @@ import (
|
|||
|
||||
// Peer represents a remote node, backed by TCP transport.
|
||||
type Peer struct {
|
||||
// underlaying TCP connection
|
||||
id uint32
|
||||
// underlying TCP connection
|
||||
conn net.Conn
|
||||
// channel to coordinate message writes back to the connection.
|
||||
send chan *Message
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"net"
|
||||
"os"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/anthdm/neo-go/pkg/network/payload"
|
||||
|
@ -23,7 +24,7 @@ const (
|
|||
|
||||
var (
|
||||
// rpcLogger used for debugging RPC messages between nodes.
|
||||
rpcLogger = log.New(os.Stdout, "RPC :: ", 0)
|
||||
rpcLogger = log.New(os.Stdout, "", 0)
|
||||
)
|
||||
|
||||
type messageTuple struct {
|
||||
|
@ -35,6 +36,8 @@ type messageTuple struct {
|
|||
type Server struct {
|
||||
logger *log.Logger
|
||||
|
||||
mtx sync.RWMutex
|
||||
|
||||
// id of the server
|
||||
id uint32
|
||||
|
||||
|
@ -171,7 +174,7 @@ func (s *Server) loop() {
|
|||
// TODO: unregister peers on error.
|
||||
// processMessage processes the received message from a remote node.
|
||||
func (s *Server) processMessage(msg *Message, peer *Peer) error {
|
||||
rpcLogger.Printf("IN :: %s :: %+v", msg.commandType(), msg.Payload)
|
||||
rpcLogger.Printf("[NODE %d] :: IN :: %s :: %+v", peer.id, msg.commandType(), msg.Payload)
|
||||
|
||||
switch msg.commandType() {
|
||||
case cmdVersion:
|
||||
|
@ -216,6 +219,7 @@ func (s *Server) handleVersionCmd(v *payload.Version, peer *Peer) error {
|
|||
// we respond with a verack, we successfully received peer's version
|
||||
// at this point.
|
||||
peer.verack = true
|
||||
peer.id = v.Nonce
|
||||
verackMsg := newMessage(s.net, cmdVerack, nil)
|
||||
peer.send <- verackMsg
|
||||
|
||||
|
@ -224,13 +228,29 @@ func (s *Server) handleVersionCmd(v *payload.Version, peer *Peer) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// When the remote node reveals its known peers we try to connect to all of them.
|
||||
func (s *Server) handleAddrCmd(addrList *payload.AddressList, peer *Peer) error {
|
||||
for _, addr := range addrList.Addrs {
|
||||
fmt.Println(addr)
|
||||
if !s.addrAlreadyConnected(addr.Addr) {
|
||||
go connectToRemoteNode(s, addr.Addr.String())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Server) addrAlreadyConnected(addr net.Addr) bool {
|
||||
// TODO: check for race conditions
|
||||
//s.mtx.RLock()
|
||||
//defer s.mtx.RUnlock()
|
||||
|
||||
for peer := range s.peers {
|
||||
if peer.conn.RemoteAddr().String() == addr.String() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// After receiving the "getaddr" the server needs to respond with an "addr" message.
|
||||
// providing information about the other nodes in the network.
|
||||
// e.g. this server's connected peers.
|
||||
|
|
|
@ -2,7 +2,6 @@ package network
|
|||
|
||||
import (
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
)
|
||||
|
||||
|
@ -21,19 +20,22 @@ func listenTCP(s *Server, port string) error {
|
|||
}
|
||||
}
|
||||
|
||||
func connectToRemoteNode(s *Server, address string) {
|
||||
conn, err := net.Dial("tcp", address)
|
||||
if err != nil {
|
||||
s.logger.Printf("failed to connects to remote node %s", address)
|
||||
if conn != nil {
|
||||
conn.Close()
|
||||
}
|
||||
return
|
||||
}
|
||||
s.logger.Printf("connected to %s", conn.RemoteAddr())
|
||||
go handleConnection(s, conn, false)
|
||||
}
|
||||
|
||||
func connectToSeeds(s *Server, addrs []string) {
|
||||
for _, addr := range addrs {
|
||||
go func(addr string) {
|
||||
conn, err := net.Dial("tcp", addr)
|
||||
if err != nil {
|
||||
log.Printf("failed to connect to remote node %s: %s", addr, err)
|
||||
if conn != nil {
|
||||
conn.Close()
|
||||
}
|
||||
return
|
||||
}
|
||||
go handleConnection(s, conn, false)
|
||||
}(addr)
|
||||
go connectToRemoteNode(s, addr)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue