neoneo-go/pkg/network/payload/addr.go

136 lines
3.1 KiB
Go
Raw Normal View History

2018-01-27 15:00:28 +00:00
package payload
import (
2018-01-28 10:12:05 +00:00
"encoding/binary"
2018-01-28 13:59:32 +00:00
"fmt"
2018-01-28 15:18:48 +00:00
"io"
"strconv"
"strings"
2018-01-27 15:00:28 +00:00
)
2018-01-28 13:59:32 +00:00
// Endpoint host + port of a node, compatible with net.Addr.
2018-01-28 10:12:05 +00:00
type Endpoint struct {
IP [16]byte // TODO: make a uint128 type
Port uint16
}
2018-01-28 15:18:48 +00:00
// EndpointFromString returns an Endpoint from the given string.
// For now this only handles the most simple hostport form.
// e.g. 127.0.0.1:3000
// This should be enough to work with for now.
func EndpointFromString(s string) (Endpoint, error) {
hostPort := strings.Split(s, ":")
if len(hostPort) != 2 {
return Endpoint{}, fmt.Errorf("invalid address string: %s", s)
}
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)}, nil
}
2018-01-28 13:59:32 +00:00
// 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)
}
2018-01-27 15:00:28 +00:00
// AddrWithTime payload
type AddrWithTime struct {
2018-01-28 13:59:32 +00:00
// Timestamp the node connected to the network.
2018-01-27 15:00:28 +00:00
Timestamp uint32
Services uint64
2018-01-28 10:12:05 +00:00
Addr Endpoint
2018-01-27 15:00:28 +00:00
}
2018-01-28 15:18:48 +00:00
func NewAddrWithTime(addr Endpoint) *AddrWithTime {
return &AddrWithTime{
Timestamp: 1337,
Services: 1,
Addr: addr,
}
}
// Size implements the payload interface.
2018-01-27 15:00:28 +00:00
func (p *AddrWithTime) Size() uint32 {
2018-01-28 10:12:05 +00:00
return 30
2018-01-27 15:00:28 +00:00
}
2018-01-28 15:18:48 +00:00
// DecodeBinary implements the Payload interface.
func (p *AddrWithTime) DecodeBinary(r io.Reader) error {
err := binary.Read(r, binary.LittleEndian, &p.Timestamp)
err = binary.Read(r, binary.LittleEndian, &p.Services)
err = binary.Read(r, binary.BigEndian, &p.Addr.IP)
err = binary.Read(r, binary.BigEndian, &p.Addr.Port)
return err
2018-01-27 15:00:28 +00:00
}
2018-01-28 15:18:48 +00:00
// EncodeBinary implements the Payload interface.
func (p *AddrWithTime) EncodeBinary(w io.Writer) error {
err := binary.Write(w, binary.LittleEndian, p.Timestamp)
err = binary.Write(w, binary.LittleEndian, p.Services)
err = binary.Write(w, binary.BigEndian, p.Addr.IP)
err = binary.Write(w, binary.BigEndian, p.Addr.Port)
return err
2018-01-28 10:12:05 +00:00
}
2018-01-28 15:18:48 +00:00
// AddressList holds a slice of AddrWithTime.
2018-01-28 10:12:05 +00:00
type AddressList struct {
Addrs []*AddrWithTime
2018-01-27 15:00:28 +00:00
}
2018-01-28 15:18:48 +00:00
// DecodeBinary implements the Payload interface.
func (p *AddressList) DecodeBinary(r io.Reader) error {
2018-01-28 10:12:05 +00:00
var lenList uint8
2018-01-28 15:18:48 +00:00
binary.Read(r, binary.LittleEndian, &lenList)
2018-01-28 10:12:05 +00:00
2018-01-28 15:18:48 +00:00
for i := 0; i < int(4); i++ {
2018-01-28 10:12:05 +00:00
address := &AddrWithTime{}
2018-01-28 15:18:48 +00:00
if err := address.DecodeBinary(r); err != nil {
return err
}
2018-01-28 10:12:05 +00:00
p.Addrs = append(p.Addrs, address)
}
2018-01-27 15:00:28 +00:00
return nil
}
2018-01-28 15:18:48 +00:00
// EncodeBinary implements the Payload interface.
func (p *AddressList) EncodeBinary(w io.Writer) error {
// Write the length of the slice
binary.Write(w, binary.LittleEndian, uint8(len(p.Addrs)))
for _, addr := range p.Addrs {
if err := addr.EncodeBinary(w); err != nil {
return err
}
}
return nil
2018-01-28 10:12:05 +00:00
}
// Size implements the Payloader interface.
func (p *AddressList) Size() uint32 {
return uint32(len(p.Addrs) * 30)
2018-01-27 15:00:28 +00:00
}