network: add getaddr message handling

Respond with known good addresses.
This commit is contained in:
Roman Khimov 2019-09-13 20:38:34 +03:00
parent b2530a4c93
commit b9ff4d929c
3 changed files with 34 additions and 5 deletions

View file

@ -62,6 +62,14 @@ type AddressList struct {
Addrs []*AddressAndTime Addrs []*AddressAndTime
} }
// NewAddressList creates a list for n AddressAndTime elements.
func NewAddressList(n int) *AddressList {
alist := AddressList{
Addrs: make([]*AddressAndTime, n),
}
return &alist
}
// DecodeBinary implements the Payload interface. // DecodeBinary implements the Payload interface.
func (p *AddressList) DecodeBinary(r io.Reader) error { func (p *AddressList) DecodeBinary(r io.Reader) error {
br := util.BinReader{R: r} br := util.BinReader{R: r}

View file

@ -35,7 +35,7 @@ func TestEncodeDecodeAddress(t *testing.T) {
func TestEncodeDecodeAddressList(t *testing.T) { func TestEncodeDecodeAddressList(t *testing.T) {
var lenList uint8 = 4 var lenList uint8 = 4
addrList := &AddressList{make([]*AddressAndTime, lenList)} addrList := NewAddressList(int(lenList))
for i := 0; i < int(lenList); i++ { for i := 0; i < int(lenList); i++ {
e, _ := net.ResolveTCPAddr("tcp", 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

@ -4,6 +4,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"math/rand" "math/rand"
"net"
"sync" "sync"
"time" "time"
@ -19,6 +20,7 @@ const (
minPeers = 5 minPeers = 5
maxPeers = 20 maxPeers = 20
maxBlockBatch = 200 maxBlockBatch = 200
maxAddrsToSend = 200
minPoolCount = 30 minPoolCount = 30
) )
@ -294,6 +296,22 @@ func (s *Server) handleAddrCmd(p Peer, addrs *payload.AddressList) error {
return nil return nil
} }
// handleGetAddrCmd sends to the peer some good addresses that we know of.
func (s *Server) handleGetAddrCmd(p Peer) error {
addrs := s.discovery.GoodPeers()
if len(addrs) > maxAddrsToSend {
addrs = addrs[:maxAddrsToSend]
}
alist := payload.NewAddressList(len(addrs))
ts := time.Now()
for i, addr := range addrs {
// we know it's a good address, so it can't fail
netaddr, _ := net.ResolveTCPAddr("tcp", addr)
alist.Addrs[i] = payload.NewAddressAndTime(netaddr, ts)
}
return p.WriteMsg(NewMessage(s.Net, CMDAddr, alist))
}
// requestHeaders will send a getheaders message to the peer. // requestHeaders will send a getheaders message to the peer.
// The peer will respond with headers op to a count of 2000. // The peer will respond with headers op to a count of 2000.
func (s *Server) requestHeaders(p Peer) error { func (s *Server) requestHeaders(p Peer) error {
@ -338,6 +356,9 @@ func (s *Server) handleMessage(peer Peer, msg *Message) error {
case CMDAddr: case CMDAddr:
addrs := msg.Payload.(*payload.AddressList) addrs := msg.Payload.(*payload.AddressList)
return s.handleAddrCmd(peer, addrs) return s.handleAddrCmd(peer, addrs)
case CMDGetAddr:
// it has no payload
return s.handleGetAddrCmd(peer)
case CMDHeaders: case CMDHeaders:
headers := msg.Payload.(*payload.Headers) headers := msg.Payload.(*payload.Headers)
go s.handleHeadersCmd(peer, headers) go s.handleHeadersCmd(peer, headers)