/ node / addr.go
addr.go
 1  package node
 2  
 3  import (
 4  	"code.dogecoin.org/gossip/codec"
 5  	"code.dogecoin.org/gossip/dnet"
 6  )
 7  
 8  var ChannelNode = dnet.NewTag("Node")
 9  var TagAddress = dnet.NewTag("Addr")
10  
11  const AddrMsgMinSize = 56
12  
13  type AddressMsg struct { // 56 + 4c + 6s
14  	Time    dnet.DogeTime // [4] Current Doge Epoch time when this message is signed
15  	Address []byte        // [16] network byte order (Big-Endian); IPv4-mapped IPv6 address
16  	Port    uint16        // [2] network byte order (Big-Endian)
17  	Owner   []byte        // [32] public key of identity claimed by this node (zeroes if not present)
18  	// [1] number of channels
19  	Channels []dnet.Tag4CC // [4] per service (Chan)
20  	// [1] number of services
21  	Services []Service // [6] per service (ID + Port)
22  }
23  
24  type Service struct {
25  	Tag  dnet.Tag4CC // [4] Service Tag (Big-Endian)
26  	Port uint16      // [2] TCP Port number (Big-Endian)
27  	Data string      // [1+] Service Data (optional)
28  }
29  
30  func (msg AddressMsg) IsValid() bool {
31  	return len(msg.Services) <= 8192 && len(msg.Address) == 16 && len(msg.Owner) == 32
32  }
33  
34  func (msg AddressMsg) Encode() []byte {
35  	if len(msg.Services) > 8192 {
36  		panic("Invalid AddrMsg: more than 8192 services")
37  	}
38  	if len(msg.Address) != 16 {
39  		panic("Invalid Address: must be 16 bytes")
40  	}
41  	if len(msg.Owner) != 32 {
42  		panic("Invalid Owner: must be 32 bytes")
43  	}
44  	e := codec.Encode(AddrMsgMinSize)
45  	e.UInt32le(uint32(msg.Time))
46  	e.Bytes(msg.Address)
47  	e.UInt16be(msg.Port)
48  	e.Bytes(msg.Owner)
49  	e.VarUInt(uint64(len(msg.Channels)))
50  	for n := 0; n < len(msg.Channels); n++ {
51  		e.UInt32be(uint32(msg.Channels[n]))
52  	}
53  	e.VarUInt(uint64(len(msg.Services)))
54  	for n := 0; n < len(msg.Services); n++ {
55  		e.UInt32be(uint32(msg.Services[n].Tag))
56  		e.UInt16be(msg.Services[n].Port)
57  		e.VarString(msg.Services[n].Data)
58  	}
59  	return e.Result()
60  }
61  
62  func DecodeAddrMsg(payload []byte) (msg AddressMsg) {
63  	d := codec.Decode(payload)
64  	msg.Time = dnet.DogeTime(d.UInt32le())
65  	msg.Address = d.Bytes(16)
66  	msg.Port = d.UInt16be()
67  	msg.Owner = d.Bytes(32)
68  	// decode channels
69  	nchannel := d.VarUInt()
70  	if nchannel > 8192 {
71  		panic("Invalid AddrMsg: more than 8192 services")
72  	}
73  	msg.Channels = make([]dnet.Tag4CC, nchannel)
74  	for n := 0; n < int(nchannel); n++ {
75  		msg.Channels[n] = dnet.Tag4CC(d.UInt32be())
76  	}
77  	// decode services
78  	nservice := d.VarUInt()
79  	if nservice > 8192 {
80  		panic("Invalid AddrMsg: more than 8192 services")
81  	}
82  	msg.Services = make([]Service, nservice)
83  	for n := 0; n < int(nservice); n++ {
84  		msg.Services[n].Tag = dnet.Tag4CC(d.UInt32be())
85  		msg.Services[n].Port = d.UInt16be()
86  		msg.Services[n].Data = d.VarString()
87  	}
88  	return
89  }