mirror of
https://github.com/PeernetOfficial/core.git
synced 2026-07-19 11:37:51 +01:00
Add byte to Announcement/Response to inform about sender's feature support. According to Whitepaper 0.7.
This commit is contained in:
@@ -127,30 +127,32 @@ type MessageResponse struct {
|
||||
|
||||
// ---- message decoding ----
|
||||
|
||||
// Minimum length of Announcement payload header without User Agent
|
||||
const announcementPayloadHeaderSize = 16
|
||||
|
||||
// msgDecodeAnnouncement decodes the incoming announcement message. Returns nil if invalid.
|
||||
func msgDecodeAnnouncement(msg *MessageRaw) (result *MessageAnnouncement, err error) {
|
||||
result = &MessageAnnouncement{
|
||||
MessageRaw: msg,
|
||||
}
|
||||
|
||||
// validate minimum payload size: 15 bytes
|
||||
if len(msg.Payload) < 15 {
|
||||
if len(msg.Payload) < announcementPayloadHeaderSize {
|
||||
return nil, errors.New("announcement: invalid minimum length")
|
||||
}
|
||||
|
||||
result.Protocol = msg.Payload[0] & 0x0F // Protocol version support is stored in the first 4 bits
|
||||
result.Features = msg.Payload[0] >> 4 // Feature support, high 4 bits
|
||||
result.Actions = msg.Payload[1]
|
||||
result.BlockchainHeight = binary.LittleEndian.Uint32(msg.Payload[2:6])
|
||||
result.BlockchainVersion = binary.LittleEndian.Uint64(msg.Payload[6:14])
|
||||
result.Features = msg.Payload[1] // Feature support
|
||||
result.Actions = msg.Payload[2]
|
||||
result.BlockchainHeight = binary.LittleEndian.Uint32(msg.Payload[3:7])
|
||||
result.BlockchainVersion = binary.LittleEndian.Uint64(msg.Payload[7:15])
|
||||
|
||||
userAgentLength := int(msg.Payload[14])
|
||||
userAgentLength := int(msg.Payload[15])
|
||||
if userAgentLength > 0 {
|
||||
if userAgentLength > len(msg.Payload)-15 { // 15 = length of announcement message without user agent
|
||||
if userAgentLength > len(msg.Payload)-announcementPayloadHeaderSize {
|
||||
return nil, errors.New("announcement: user agent overflow")
|
||||
}
|
||||
|
||||
userAgentB := msg.Payload[15 : 15+userAgentLength]
|
||||
userAgentB := msg.Payload[announcementPayloadHeaderSize : announcementPayloadHeaderSize+userAgentLength]
|
||||
if !utf8.Valid(userAgentB) {
|
||||
return nil, errors.New("announcement: user agent invalid encoding")
|
||||
}
|
||||
@@ -158,7 +160,7 @@ func msgDecodeAnnouncement(msg *MessageRaw) (result *MessageAnnouncement, err er
|
||||
result.UserAgent = string(userAgentB)
|
||||
}
|
||||
|
||||
data := msg.Payload[15+userAgentLength:]
|
||||
data := msg.Payload[announcementPayloadHeaderSize+userAgentLength:]
|
||||
|
||||
// FIND_PEER
|
||||
if result.Actions&(1<<ActionFindPeer) > 0 {
|
||||
@@ -252,26 +254,25 @@ func msgDecodeResponse(msg *MessageRaw) (result *MessageResponse, err error) {
|
||||
MessageRaw: msg,
|
||||
}
|
||||
|
||||
// validate minimum payload size: 15 + 6 bytes
|
||||
if len(msg.Payload) < 15+6 {
|
||||
if len(msg.Payload) < announcementPayloadHeaderSize+6 {
|
||||
return nil, errors.New("response: invalid minimum length")
|
||||
}
|
||||
|
||||
result.Protocol = msg.Payload[0] & 0x0F // Protocol version support is stored in the first 4 bits
|
||||
result.Features = msg.Payload[0] >> 4 // Feature support, high 4 bits
|
||||
result.Actions = msg.Payload[1]
|
||||
result.BlockchainHeight = binary.LittleEndian.Uint32(msg.Payload[2:6])
|
||||
result.BlockchainVersion = binary.LittleEndian.Uint64(msg.Payload[6:14])
|
||||
result.Features = msg.Payload[1] // Feature support
|
||||
result.Actions = msg.Payload[2]
|
||||
result.BlockchainHeight = binary.LittleEndian.Uint32(msg.Payload[3:7])
|
||||
result.BlockchainVersion = binary.LittleEndian.Uint64(msg.Payload[7:15])
|
||||
|
||||
userAgentLength := int(msg.Payload[14])
|
||||
read := 15
|
||||
userAgentLength := int(msg.Payload[15])
|
||||
read := announcementPayloadHeaderSize
|
||||
|
||||
if userAgentLength > 0 {
|
||||
if userAgentLength > len(msg.Payload)-15 { // 15 = length of announcement message without user agent
|
||||
if userAgentLength > len(msg.Payload)-announcementPayloadHeaderSize {
|
||||
return nil, errors.New("response: user agent overflow")
|
||||
}
|
||||
|
||||
userAgentB := msg.Payload[15 : 15+userAgentLength]
|
||||
userAgentB := msg.Payload[announcementPayloadHeaderSize : announcementPayloadHeaderSize+userAgentLength]
|
||||
if !utf8.Valid(userAgentB) {
|
||||
return nil, errors.New("response: user agent invalid encoding")
|
||||
}
|
||||
@@ -434,12 +435,13 @@ func msgEncodeAnnouncement(sendUA, findSelf bool, findPeer []KeyHash, findValue
|
||||
createPacketLoop:
|
||||
for {
|
||||
raw := make([]byte, 64*1024) // max UDP packet size
|
||||
packetSize := 15
|
||||
packetSize := announcementPayloadHeaderSize
|
||||
|
||||
raw[0] = byte(ProtocolVersion + FeatureSupport<<4) // Protocol and Features
|
||||
//raw[1] = Actions // Action bit array
|
||||
binary.LittleEndian.PutUint32(raw[2:6], BlockchainHeight)
|
||||
binary.LittleEndian.PutUint64(raw[6:14], BlockchainVersion)
|
||||
raw[0] = byte(ProtocolVersion) // Protocol
|
||||
raw[1] = byte(FeatureSupport) // Feature support
|
||||
//raw[2] = Actions // Action bit array
|
||||
binary.LittleEndian.PutUint32(raw[3:7], BlockchainHeight)
|
||||
binary.LittleEndian.PutUint64(raw[7:15], BlockchainVersion)
|
||||
|
||||
// only on initial announcement the User Agent must be provided according to the protocol spec
|
||||
if sendUA {
|
||||
@@ -448,14 +450,14 @@ createPacketLoop:
|
||||
}
|
||||
userAgentB := []byte(UserAgent)
|
||||
|
||||
raw[14] = byte(len(userAgentB))
|
||||
copy(raw[15:15+len(userAgentB)], userAgentB)
|
||||
raw[15] = byte(len(userAgentB))
|
||||
copy(raw[announcementPayloadHeaderSize:announcementPayloadHeaderSize+len(userAgentB)], userAgentB)
|
||||
packetSize += len(userAgentB)
|
||||
}
|
||||
|
||||
// FIND_SELF
|
||||
if findSelf {
|
||||
raw[1] |= 1 << ActionFindSelf
|
||||
raw[2] |= 1 << ActionFindSelf
|
||||
}
|
||||
|
||||
// FIND_PEER
|
||||
@@ -466,7 +468,7 @@ createPacketLoop:
|
||||
continue createPacketLoop
|
||||
}
|
||||
|
||||
raw[1] |= 1 << ActionFindPeer
|
||||
raw[2] |= 1 << ActionFindPeer
|
||||
index := packetSize
|
||||
packetSize += 2
|
||||
|
||||
@@ -494,7 +496,7 @@ createPacketLoop:
|
||||
continue createPacketLoop
|
||||
}
|
||||
|
||||
raw[1] |= 1 << ActionFindValue
|
||||
raw[2] |= 1 << ActionFindValue
|
||||
index := packetSize
|
||||
packetSize += 2
|
||||
|
||||
@@ -522,7 +524,7 @@ createPacketLoop:
|
||||
continue createPacketLoop
|
||||
}
|
||||
|
||||
raw[1] |= 1 << ActionInfoStore
|
||||
raw[2] |= 1 << ActionInfoStore
|
||||
index := packetSize
|
||||
packetSize += 2
|
||||
|
||||
@@ -555,7 +557,7 @@ createPacketLoop:
|
||||
}
|
||||
|
||||
// EmbeddedFileSizeMax is the maximum size of embedded files in response messages. Any file exceeding that must be shared via regular file transfer.
|
||||
const EmbeddedFileSizeMax = udpMaxPacketSize - packetLengthMin - 15 - 2 - 35 // 15 = payload header size
|
||||
const EmbeddedFileSizeMax = udpMaxPacketSize - packetLengthMin - announcementPayloadHeaderSize - 2 - 35
|
||||
|
||||
// msgEncodeResponse encodes a response message
|
||||
// hash2Peers will be modified.
|
||||
@@ -569,12 +571,13 @@ func msgEncodeResponse(sendUA bool, hash2Peers []Hash2Peer, filesEmbed []Embedde
|
||||
createPacketLoop:
|
||||
for {
|
||||
raw := make([]byte, 64*1024) // max UDP packet size
|
||||
packetSize := 15
|
||||
packetSize := announcementPayloadHeaderSize
|
||||
|
||||
raw[0] = byte(ProtocolVersion + FeatureSupport<<4) // Protocol and Features
|
||||
//raw[1] = Actions // Action bit array
|
||||
binary.LittleEndian.PutUint32(raw[2:6], BlockchainHeight)
|
||||
binary.LittleEndian.PutUint64(raw[6:14], BlockchainVersion)
|
||||
raw[0] = byte(ProtocolVersion) // Protocol
|
||||
raw[1] = byte(FeatureSupport) // Feature support
|
||||
//raw[2] = Actions // Action bit array
|
||||
binary.LittleEndian.PutUint32(raw[3:7], BlockchainHeight)
|
||||
binary.LittleEndian.PutUint64(raw[7:15], BlockchainVersion)
|
||||
|
||||
// only on initial response the User Agent must be provided according to the protocol spec
|
||||
if sendUA {
|
||||
@@ -583,8 +586,8 @@ createPacketLoop:
|
||||
}
|
||||
userAgentB := []byte(UserAgent)
|
||||
|
||||
raw[14] = byte(len(userAgentB))
|
||||
copy(raw[15:15+len(userAgentB)], userAgentB)
|
||||
raw[15] = byte(len(userAgentB))
|
||||
copy(raw[announcementPayloadHeaderSize:announcementPayloadHeaderSize+len(userAgentB)], userAgentB)
|
||||
packetSize += len(userAgentB)
|
||||
}
|
||||
|
||||
@@ -663,8 +666,6 @@ createPacketLoop:
|
||||
continue createPacketLoop
|
||||
}
|
||||
|
||||
raw[1] |= 1 << ActionInfoStore
|
||||
|
||||
for n, file := range filesEmbed {
|
||||
if isPacketSizeExceed(packetSize, 34+len(file.Data)) { // check if minimum length is available in packet
|
||||
packetsRaw = append(packetsRaw, raw[:packetSize])
|
||||
|
||||
Reference in New Issue
Block a user