mirror of
https://github.com/PeernetOfficial/core.git
synced 2026-07-17 02:47:51 +01:00
Add Sequence field #13 to packet header according to latest Whitepaper 0.7.1
The field is yet to be used.
This commit is contained in:
26
Bootstrap.go
26
Bootstrap.go
@@ -95,14 +95,7 @@ func parseAddress(Address string) (remote *net.UDPAddr, err error) {
|
||||
|
||||
// contact tries to contact the root peer on all networks
|
||||
func (peer *rootPeer) contact() {
|
||||
packets, err := msgEncodeAnnouncement(true, true, nil, nil, nil)
|
||||
if len(packets) == 0 || err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, address := range peer.addresses {
|
||||
sendAllNetworks(peer.publicKey, &PacketRaw{Command: CommandAnnouncement, Payload: packets[0]}, address)
|
||||
}
|
||||
contactArbitraryPeer(peer.publicKey, peer.addresses)
|
||||
}
|
||||
|
||||
// bootstrap connects to the initial set of peers. It will also start the routine for ongoing sending of multicast/broadcast messages.
|
||||
@@ -198,8 +191,9 @@ func autoMulticastBroadcast() {
|
||||
}
|
||||
}
|
||||
|
||||
func contactArbitraryPeer(publicKey *btcec.PublicKey, ip net.IP, port uint16) {
|
||||
// check first if peer is already in the list!
|
||||
// contactArbitraryPeer reaches for the first time to an arbitrary peer.
|
||||
// It does not contact the peer if it is in the peer list, which means that a connection is already established.
|
||||
func contactArbitraryPeer(publicKey *btcec.PublicKey, addresses []*net.UDPAddr) {
|
||||
if peer := PeerlistLookup(publicKey); peer != nil {
|
||||
return
|
||||
}
|
||||
@@ -209,5 +203,15 @@ func contactArbitraryPeer(publicKey *btcec.PublicKey, ip net.IP, port uint16) {
|
||||
return
|
||||
}
|
||||
|
||||
sendAllNetworks(publicKey, &PacketRaw{Command: CommandAnnouncement, Payload: packets[0]}, &net.UDPAddr{IP: ip, Port: int(port)})
|
||||
for _, address := range addresses {
|
||||
sendAllNetworks(publicKey, &PacketRaw{Command: CommandAnnouncement, Payload: packets[0]}, address)
|
||||
}
|
||||
}
|
||||
|
||||
// cmdResponseFindSelf processes FIND_SELF responses
|
||||
func (peer *PeerInfo) cmdResponseFindSelf(msg *MessageResponse, Closest []PeerRecord) {
|
||||
for _, closePeer := range Closest {
|
||||
// Initiate contact. Once a response comes back, the peer is actually added to the list.
|
||||
contactArbitraryPeer(closePeer.PublicKey, []*net.UDPAddr{{IP: closePeer.IP, Port: int(closePeer.Port)}})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ Author: Peter Kleissner
|
||||
package core
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
@@ -14,7 +15,7 @@ import (
|
||||
)
|
||||
|
||||
// respondClosesContactsCount is the number of closest contact to respond.
|
||||
// Each peer record will take 55 bytes. Overhead is 73 + 15 payload header + UA length + 6 + 34 = 128 bytes without UA.
|
||||
// Each peer record will take 55 bytes. Overhead is 77 + 15 payload header + UA length + 6 + 34 = 132 bytes without UA.
|
||||
// It makes sense to stay below 508 bytes (no fragmentation). Reporting back 5 contacts for FIND_SELF requests should do the magic.
|
||||
const respondClosesContactsCount = 5
|
||||
|
||||
@@ -138,6 +139,10 @@ func (peer *PeerInfo) cmdResponse(msg *MessageResponse) {
|
||||
for _, hash2Peer := range msg.Hash2Peers {
|
||||
info := nodesDHT.IRLookup(peer.NodeID, hash2Peer.ID.Hash)
|
||||
if info == nil {
|
||||
// Response to FIND_SELF?
|
||||
if bytes.Equal(info.Key, nodeID) && len(hash2Peer.Closest) > 0 {
|
||||
peer.cmdResponseFindSelf(msg, hash2Peer.Closest)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,16 @@ func (c *Connection) IsLocal() bool {
|
||||
return IsIPLocal(c.Address.IP)
|
||||
}
|
||||
|
||||
// IsIPv4 checks if the connection is using IPv4
|
||||
func (c *Connection) IsIPv4() bool {
|
||||
return IsIPv4(c.Address.IP)
|
||||
}
|
||||
|
||||
// IsIPv6 checks if the connection is using IPv6
|
||||
func (c *Connection) IsIPv6() bool {
|
||||
return IsIPv6(c.Address.IP)
|
||||
}
|
||||
|
||||
// GetConnections returns the list of connections
|
||||
func (peer *PeerInfo) GetConnections(active bool) (connections []*Connection) {
|
||||
peer.RLock()
|
||||
|
||||
@@ -8,8 +8,9 @@ Offset Size Info
|
||||
0 4 Nonce
|
||||
4 1 Protocol version = 0
|
||||
5 1 Command
|
||||
6 2 Size of payload data
|
||||
8 ? Payload
|
||||
6 4 Sequence
|
||||
10 2 Size of payload data
|
||||
12 ? Payload
|
||||
? Randomized garbage
|
||||
? 65 Signature, ECDSA secp256k1 512-bit + 1 header byte
|
||||
|
||||
@@ -34,11 +35,12 @@ import (
|
||||
type PacketRaw struct {
|
||||
Protocol uint8 // Protocol version = 0
|
||||
Command uint8 // 0 = Announcement
|
||||
Sequence uint32 // Sequence number
|
||||
Payload []byte // Payload
|
||||
}
|
||||
|
||||
// The minimum packet size is 8 bytes (minimum header size) + 65 bytes (signature)
|
||||
const packetLengthMin = 8 + signatureSize
|
||||
// The minimum packet size is 12 bytes (minimum header size) + 65 bytes (signature)
|
||||
const packetLengthMin = 12 + signatureSize
|
||||
const signatureSize = 65
|
||||
const maxRandomGarbage = 20
|
||||
|
||||
@@ -69,14 +71,15 @@ func PacketDecrypt(raw []byte, receiverPublicKey *btcec.PublicKey) (packet *Pack
|
||||
|
||||
// copy all fields
|
||||
packet = &PacketRaw{Protocol: bufferDecrypted[0], Command: bufferDecrypted[1]}
|
||||
packet.Sequence = binary.LittleEndian.Uint32(bufferDecrypted[2:6])
|
||||
|
||||
sizePayload := binary.LittleEndian.Uint16(bufferDecrypted[2:4])
|
||||
if int(sizePayload) > len(bufferDecrypted)-4 { // invalid length?
|
||||
sizePayload := binary.LittleEndian.Uint16(bufferDecrypted[6:8])
|
||||
if int(sizePayload) > len(bufferDecrypted)-8 { // invalid length?
|
||||
return nil, nil, errors.New("invalid length field")
|
||||
}
|
||||
if sizePayload > 0 {
|
||||
packet.Payload = make([]byte, int(sizePayload))
|
||||
copy(packet.Payload, bufferDecrypted[4:4+int(sizePayload)])
|
||||
copy(packet.Payload, bufferDecrypted[8:8+int(sizePayload)])
|
||||
}
|
||||
|
||||
return packet, senderPublicKey, nil
|
||||
@@ -96,13 +99,14 @@ func PacketEncrypt(senderPrivateKey *btcec.PrivateKey, receiverPublicKey *btcec.
|
||||
raw[4] = packet.Protocol
|
||||
raw[5] = packet.Command
|
||||
|
||||
binary.LittleEndian.PutUint16(raw[6:8], uint16(len(packet.Payload)))
|
||||
copy(raw[8:], packet.Payload)
|
||||
copy(raw[8+len(packet.Payload):8+len(packet.Payload)+len(garbage)], garbage)
|
||||
binary.LittleEndian.PutUint16(raw[6:10], uint16(packet.Sequence))
|
||||
binary.LittleEndian.PutUint16(raw[10:12], uint16(len(packet.Payload)))
|
||||
copy(raw[12:], packet.Payload)
|
||||
copy(raw[12+len(packet.Payload):12+len(packet.Payload)+len(garbage)], garbage)
|
||||
|
||||
// encrypt it using Salsa20
|
||||
keySalsa := publicKeyToSalsa20Key(receiverPublicKey)
|
||||
salsa20.XORKeyStream(raw[4:8+len(packet.Payload)+len(garbage)], raw[4:8+len(packet.Payload)+len(garbage)], nonce, keySalsa)
|
||||
salsa20.XORKeyStream(raw[4:12+len(packet.Payload)+len(garbage)], raw[4:12+len(packet.Payload)+len(garbage)], nonce, keySalsa)
|
||||
|
||||
// add signature
|
||||
signature, err := btcec.SignCompact(btcec.S256(), senderPrivateKey, hashData(raw[:len(raw)-signatureSize]), true)
|
||||
|
||||
Reference in New Issue
Block a user