0.3.2
This commit is contained in:
@@ -1,9 +1,8 @@
|
||||
package packet
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -38,6 +37,7 @@ const (
|
||||
HopsField = 0xFF
|
||||
)
|
||||
|
||||
// Packet represents a network packet in the Reticulum protocol
|
||||
type Packet struct {
|
||||
Header [2]byte
|
||||
Addresses []byte
|
||||
@@ -45,48 +45,10 @@ type Packet struct {
|
||||
Data []byte
|
||||
AccessCode []byte
|
||||
RandomBlob []byte
|
||||
Timestamp time.Time
|
||||
}
|
||||
|
||||
func NewAnnouncePacket(destHash []byte, publicKey []byte, appData []byte) (*Packet, error) {
|
||||
p := &Packet{
|
||||
Header: [2]byte{0, 0}, // Start with 0 hops
|
||||
Addresses: make([]byte, AddressSize),
|
||||
Data: make([]byte, 0, MaxDataSize),
|
||||
}
|
||||
|
||||
// Set header flags for announce packet
|
||||
p.Header[0] |= HeaderTypeFlag // Single address
|
||||
p.Header[0] |= (PropagationBroadcast << 3) & PropagationFlags // Broadcast
|
||||
p.Header[0] |= (DestinationSingle << 1) & DestinationFlags // Single destination
|
||||
p.Header[0] |= PacketTypeAnnounce & PacketTypeFlags // Announce type
|
||||
|
||||
// Set destination hash
|
||||
if len(destHash) != AddressSize {
|
||||
return nil, errors.New("invalid destination hash size")
|
||||
}
|
||||
copy(p.Addresses, destHash)
|
||||
|
||||
// Build announce data
|
||||
// Public key
|
||||
p.Data = append(p.Data, publicKey...)
|
||||
|
||||
// App data length and content
|
||||
appDataLen := make([]byte, 2)
|
||||
binary.BigEndian.PutUint16(appDataLen, uint16(len(appData)))
|
||||
p.Data = append(p.Data, appDataLen...)
|
||||
p.Data = append(p.Data, appData...)
|
||||
|
||||
// Add random blob
|
||||
randomBlob := make([]byte, RandomBlobSize)
|
||||
if _, err := rand.Read(randomBlob); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.RandomBlob = randomBlob
|
||||
p.Data = append(p.Data, randomBlob...)
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// NewPacket creates a new packet with the specified parameters
|
||||
func NewPacket(packetType byte, flags byte, hops byte, destKey []byte, data []byte) (*Packet, error) {
|
||||
if len(destKey) != AddressSize {
|
||||
return nil, errors.New("invalid destination key length")
|
||||
@@ -96,6 +58,7 @@ func NewPacket(packetType byte, flags byte, hops byte, destKey []byte, data []by
|
||||
Header: [2]byte{flags, hops},
|
||||
Addresses: make([]byte, AddressSize),
|
||||
Data: data,
|
||||
Timestamp: time.Now(),
|
||||
}
|
||||
|
||||
// Set packet type in flags
|
||||
@@ -107,38 +70,7 @@ func NewPacket(packetType byte, flags byte, hops byte, destKey []byte, data []by
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func (p *Packet) SetAccessCode(code []byte) {
|
||||
p.AccessCode = code
|
||||
p.Header[0] |= IFACFlag
|
||||
}
|
||||
|
||||
func (p *Packet) SetContext(context byte) {
|
||||
p.Context = context
|
||||
p.Header[0] |= ContextFlag
|
||||
}
|
||||
|
||||
func (p *Packet) SetData(data []byte) error {
|
||||
if len(data) > MaxDataSize {
|
||||
return errors.New("data exceeds maximum allowed size")
|
||||
}
|
||||
p.Data = data
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Packet) SetAddress(index int, address []byte) error {
|
||||
if len(address) != AddressSize {
|
||||
return errors.New("invalid address size")
|
||||
}
|
||||
|
||||
offset := index * AddressSize
|
||||
if offset+AddressSize > len(p.Addresses) {
|
||||
return errors.New("address index out of range")
|
||||
}
|
||||
|
||||
copy(p.Addresses[offset:], address)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Serialize converts the packet into a byte slice
|
||||
func (p *Packet) Serialize() ([]byte, error) {
|
||||
totalSize := HeaderSize + len(p.Addresses) + ContextSize + len(p.Data)
|
||||
if p.AccessCode != nil {
|
||||
@@ -172,46 +104,13 @@ func (p *Packet) Serialize() ([]byte, error) {
|
||||
return buffer, nil
|
||||
}
|
||||
|
||||
func ParsePacket(data []byte) (*Packet, error) {
|
||||
if len(data) < HeaderSize {
|
||||
return nil, errors.New("packet data too short")
|
||||
}
|
||||
|
||||
p := &Packet{
|
||||
Header: [2]byte{data[0], data[1]},
|
||||
}
|
||||
|
||||
offset := HeaderSize
|
||||
|
||||
// Handle access code if present
|
||||
if p.Header[0]&IFACFlag != 0 {
|
||||
// Access code handling would go here
|
||||
// For now, we'll assume no access code
|
||||
return nil, errors.New("access code handling not implemented")
|
||||
}
|
||||
|
||||
// Determine address size based on header type
|
||||
addrLen := AddressSize
|
||||
if p.Header[0]&HeaderTypeFlag != 0 {
|
||||
addrLen = 2 * AddressSize
|
||||
}
|
||||
|
||||
if len(data[offset:]) < addrLen+ContextSize {
|
||||
return nil, errors.New("packet data too short for addresses and context")
|
||||
}
|
||||
|
||||
// Copy addresses
|
||||
p.Addresses = make([]byte, addrLen)
|
||||
copy(p.Addresses, data[offset:offset+addrLen])
|
||||
offset += addrLen
|
||||
|
||||
// Copy context
|
||||
p.Context = data[offset]
|
||||
offset++
|
||||
|
||||
// Copy remaining data
|
||||
p.Data = make([]byte, len(data)-offset)
|
||||
copy(p.Data, data[offset:])
|
||||
|
||||
return p, nil
|
||||
type AnnouncePacket struct {
|
||||
Header [2]byte
|
||||
DestHash []byte
|
||||
PublicKey []byte
|
||||
AppData []byte
|
||||
RandomBlob []byte
|
||||
Signature []byte
|
||||
HopCount byte
|
||||
Timestamp time.Time
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user