update packet creation
This commit is contained in:
@@ -62,7 +62,6 @@ type Reticulum struct {
|
||||
}
|
||||
|
||||
type announceRecord struct {
|
||||
// All fields were unused, so entire struct can be removed
|
||||
}
|
||||
|
||||
func NewReticulum(cfg *common.ReticulumConfig) (*Reticulum, error) {
|
||||
@@ -70,6 +69,14 @@ func NewReticulum(cfg *common.ReticulumConfig) (*Reticulum, error) {
|
||||
cfg = config.DefaultConfig()
|
||||
}
|
||||
|
||||
// Set default app name and aspect if not provided
|
||||
if cfg.AppName == "" {
|
||||
cfg.AppName = "Go Client"
|
||||
}
|
||||
if cfg.AppAspect == "" {
|
||||
cfg.AppAspect = "node"
|
||||
}
|
||||
|
||||
if err := initializeDirectories(); err != nil {
|
||||
return nil, fmt.Errorf("failed to initialize directories: %v", err)
|
||||
}
|
||||
@@ -269,6 +276,7 @@ func main() {
|
||||
[]byte("HELLO WORLD"),
|
||||
nil,
|
||||
false,
|
||||
r.config,
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create announce: %v", err)
|
||||
@@ -424,24 +432,27 @@ func (r *Reticulum) Start() error {
|
||||
debugLog(3, "Interface %s started successfully", iface.GetName())
|
||||
}
|
||||
|
||||
// Create initial announce packet
|
||||
announceData := []byte("Reticulum-Go")
|
||||
announcePacket := transport.CreateAnnouncePacket(
|
||||
r.identity.Hash(),
|
||||
// Create initial announce
|
||||
initialAnnounce, err := announce.NewAnnounce(
|
||||
r.identity,
|
||||
announceData,
|
||||
0,
|
||||
[]byte("Reticulum-Go"),
|
||||
nil, // ratchetID
|
||||
false, // pathResponse
|
||||
r.config,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create announce: %v", err)
|
||||
}
|
||||
|
||||
// Wait briefly for interfaces to initialize
|
||||
time.Sleep(2 * time.Second)
|
||||
|
||||
// Send initial announces on all enabled interfaces
|
||||
// Send initial announces
|
||||
for _, iface := range r.interfaces {
|
||||
if netIface, ok := iface.(common.NetworkInterface); ok {
|
||||
if netIface.IsEnabled() && netIface.IsOnline() {
|
||||
debugLog(2, "Sending initial announce on interface %s", netIface.GetName())
|
||||
if err := netIface.Send(announcePacket, ""); err != nil {
|
||||
if err := initialAnnounce.Propagate([]common.NetworkInterface{netIface}); err != nil {
|
||||
debugLog(1, "Failed to send initial announce on interface %s: %v", netIface.GetName(), err)
|
||||
}
|
||||
}
|
||||
@@ -458,19 +469,24 @@ func (r *Reticulum) Start() error {
|
||||
announceCount++
|
||||
debugLog(3, "Starting periodic announce cycle #%d", announceCount)
|
||||
|
||||
// Create fresh announce packet for each cycle
|
||||
announcePacket := transport.CreateAnnouncePacket(
|
||||
r.identity.Hash(),
|
||||
// Create fresh announce for each cycle
|
||||
periodicAnnounce, err := announce.NewAnnounce(
|
||||
r.identity,
|
||||
announceData,
|
||||
0,
|
||||
[]byte("Reticulum-Go"),
|
||||
nil, // ratchetID
|
||||
false, // pathResponse
|
||||
r.config,
|
||||
)
|
||||
if err != nil {
|
||||
debugLog(1, "Failed to create periodic announce: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
for _, iface := range r.interfaces {
|
||||
if netIface, ok := iface.(common.NetworkInterface); ok {
|
||||
if netIface.IsEnabled() && netIface.IsOnline() {
|
||||
debugLog(2, "Sending periodic announce on interface %s", netIface.GetName())
|
||||
if err := netIface.Send(announcePacket, ""); err != nil {
|
||||
if err := periodicAnnounce.Propagate([]common.NetworkInterface{netIface}); err != nil {
|
||||
debugLog(1, "Failed to send periodic announce on interface %s: %v", netIface.GetName(), err)
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@ type Announce struct {
|
||||
destinationHash []byte
|
||||
identity *identity.Identity
|
||||
appData []byte
|
||||
config *common.ReticulumConfig
|
||||
hops uint8
|
||||
timestamp int64
|
||||
signature []byte
|
||||
@@ -71,7 +72,7 @@ type Announce struct {
|
||||
hash []byte
|
||||
}
|
||||
|
||||
func New(dest *identity.Identity, appData []byte, pathResponse bool) (*Announce, error) {
|
||||
func New(dest *identity.Identity, appData []byte, pathResponse bool, config *common.ReticulumConfig) (*Announce, error) {
|
||||
if dest == nil {
|
||||
return nil, errors.New("destination identity required")
|
||||
}
|
||||
@@ -80,6 +81,7 @@ func New(dest *identity.Identity, appData []byte, pathResponse bool) (*Announce,
|
||||
mutex: &sync.RWMutex{},
|
||||
identity: dest,
|
||||
appData: appData,
|
||||
config: config,
|
||||
hops: 0,
|
||||
timestamp: time.Now().Unix(),
|
||||
pathResponse: pathResponse,
|
||||
@@ -284,14 +286,14 @@ func CreateHeader(ifacFlag byte, headerType byte, contextFlag byte, propType byt
|
||||
|
||||
func (a *Announce) CreatePacket() []byte {
|
||||
log.Printf("[DEBUG-7] Creating announce packet")
|
||||
|
||||
|
||||
headerByte := byte(
|
||||
(IFAC_NONE) |
|
||||
(HEADER_TYPE_1 << 6) |
|
||||
(0 << 5) |
|
||||
(PROP_TYPE_BROADCAST << 4) |
|
||||
(DEST_TYPE_SINGLE << 2) |
|
||||
PACKET_TYPE_ANNOUNCE,
|
||||
(IFAC_NONE) |
|
||||
(HEADER_TYPE_1 << 6) |
|
||||
(0 << 5) |
|
||||
(PROP_TYPE_BROADCAST << 4) |
|
||||
(DEST_TYPE_SINGLE << 2) |
|
||||
PACKET_TYPE_ANNOUNCE,
|
||||
)
|
||||
|
||||
log.Printf("[DEBUG-7] Created header byte: %02x, hops: %d", headerByte, a.hops)
|
||||
@@ -301,29 +303,31 @@ func (a *Announce) CreatePacket() []byte {
|
||||
log.Printf("[DEBUG-7] Adding destination hash (16 bytes): %x", a.destinationHash)
|
||||
packet = append(packet, a.destinationHash...)
|
||||
|
||||
// Split public key into encryption and signing keys (32 bytes each)
|
||||
// Get full public key and split into encryption and signing keys
|
||||
pubKey := a.identity.GetPublicKey()
|
||||
encKey := pubKey[:32]
|
||||
signKey := pubKey[32:]
|
||||
|
||||
encKey := pubKey[:32] // x25519 public key for encryption
|
||||
signKey := pubKey[32:] // Ed25519 public key for signing
|
||||
|
||||
// Add encryption key (32 bytes)
|
||||
log.Printf("[DEBUG-7] Adding encryption key (32 bytes): %x", encKey)
|
||||
packet = append(packet, encKey...)
|
||||
|
||||
|
||||
// Add signing key (32 bytes)
|
||||
log.Printf("[DEBUG-7] Adding signing key (32 bytes): %x", signKey)
|
||||
packet = append(packet, signKey...)
|
||||
|
||||
// Add name hash (10 bytes)
|
||||
nameHash := a.identity.GetNameHash()
|
||||
log.Printf("[DEBUG-7] Adding name hash (10 bytes): %x", nameHash)
|
||||
packet = append(packet, nameHash...)
|
||||
// Add name hash (10 bytes) - SHA256 hash of full name truncated to 10 bytes
|
||||
nameHash := sha256.Sum256([]byte(fmt.Sprintf("%s.%s", a.config.AppName, a.config.AppAspect)))
|
||||
log.Printf("[DEBUG-7] Adding name hash (10 bytes): %x", nameHash[:10])
|
||||
packet = append(packet, nameHash[:10]...)
|
||||
|
||||
// Add random hash (5 random + 5 timestamp bytes = 10 bytes)
|
||||
randomHash := make([]byte, 5)
|
||||
rand.Read(randomHash)
|
||||
randomBytes := make([]byte, 5)
|
||||
rand.Read(randomBytes)
|
||||
timeBytes := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(timeBytes, uint64(time.Now().Unix()))
|
||||
log.Printf("[DEBUG-7] Adding random hash (10 bytes): %x%x", randomHash, timeBytes[:5])
|
||||
packet = append(packet, randomHash...)
|
||||
log.Printf("[DEBUG-7] Adding random hash (10 bytes): %x%x", randomBytes, timeBytes[:5])
|
||||
packet = append(packet, randomBytes...)
|
||||
packet = append(packet, timeBytes[:5]...)
|
||||
|
||||
// Add ratchet if present (32 bytes)
|
||||
@@ -332,12 +336,23 @@ func (a *Announce) CreatePacket() []byte {
|
||||
packet = append(packet, a.ratchetID...)
|
||||
}
|
||||
|
||||
// Add app data
|
||||
log.Printf("[DEBUG-7] Adding app data (%d bytes): %x", len(a.appData), a.appData)
|
||||
packet = append(packet, a.appData...)
|
||||
// Create msgpack array for app data
|
||||
appData := []byte{
|
||||
0x92, // msgpack array of 2 elements
|
||||
0xc4, // bin 8 format for byte array
|
||||
}
|
||||
|
||||
// Add signature (64 bytes)
|
||||
signData := append(a.destinationHash, a.appData...)
|
||||
// Add name bytes
|
||||
nameBytes := []byte(fmt.Sprintf("%s.%s", a.config.AppName, a.config.AppAspect))
|
||||
appData = append(appData, byte(len(nameBytes))) // length prefix
|
||||
appData = append(appData, nameBytes...) // name bytes
|
||||
appData = append(appData, 0x00) // ticket value = 0
|
||||
|
||||
// Add app data to packet
|
||||
packet = append(packet, appData...)
|
||||
|
||||
// Create signature
|
||||
signData := append(a.destinationHash, appData...)
|
||||
if a.ratchetID != nil {
|
||||
signData = append(signData, a.ratchetID...)
|
||||
}
|
||||
@@ -346,7 +361,6 @@ func (a *Announce) CreatePacket() []byte {
|
||||
packet = append(packet, signature...)
|
||||
|
||||
log.Printf("[DEBUG-7] Final packet size: %d bytes", len(packet))
|
||||
a.packet = packet
|
||||
return packet
|
||||
}
|
||||
|
||||
@@ -380,8 +394,8 @@ func NewAnnouncePacket(pubKey []byte, appData []byte, announceID []byte) *Announ
|
||||
}
|
||||
|
||||
// NewAnnounce creates a new announce packet for a destination
|
||||
func NewAnnounce(identity *identity.Identity, appData []byte, ratchetID []byte, pathResponse bool) (*Announce, error) {
|
||||
log.Printf("[DEBUG-7] Creating new announce: appDataLen=%d, hasRatchet=%v, pathResponse=%v",
|
||||
func NewAnnounce(identity *identity.Identity, appData []byte, ratchetID []byte, pathResponse bool, config *common.ReticulumConfig) (*Announce, error) {
|
||||
log.Printf("[DEBUG-7] Creating new announce: appDataLen=%d, hasRatchet=%v, pathResponse=%v",
|
||||
len(appData), ratchetID != nil, pathResponse)
|
||||
|
||||
if identity == nil {
|
||||
@@ -389,6 +403,10 @@ func NewAnnounce(identity *identity.Identity, appData []byte, ratchetID []byte,
|
||||
return nil, errors.New("identity cannot be nil")
|
||||
}
|
||||
|
||||
if config == nil {
|
||||
return nil, errors.New("config cannot be nil")
|
||||
}
|
||||
|
||||
destHash := identity.Hash()
|
||||
log.Printf("[DEBUG-7] Generated destination hash: %x", destHash)
|
||||
|
||||
@@ -401,15 +419,16 @@ func NewAnnounce(identity *identity.Identity, appData []byte, ratchetID []byte,
|
||||
hops: 0,
|
||||
mutex: &sync.RWMutex{},
|
||||
handlers: make([]AnnounceHandler, 0),
|
||||
config: config,
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG-7] Created announce object: destHash=%x, hops=%d",
|
||||
log.Printf("[DEBUG-7] Created announce object: destHash=%x, hops=%d",
|
||||
a.destinationHash, a.hops)
|
||||
|
||||
// Create initial packet
|
||||
packet := a.CreatePacket()
|
||||
a.packet = packet
|
||||
|
||||
|
||||
// Generate hash
|
||||
hash := a.Hash()
|
||||
log.Printf("[DEBUG-7] Generated announce hash: %x", hash)
|
||||
|
||||
@@ -50,6 +50,8 @@ type ReticulumConfig struct {
|
||||
PanicOnInterfaceErr bool
|
||||
LogLevel int
|
||||
Interfaces map[string]*InterfaceConfig
|
||||
AppName string
|
||||
AppAspect string
|
||||
}
|
||||
|
||||
// NewReticulumConfig creates a new ReticulumConfig with default values
|
||||
@@ -75,3 +77,17 @@ func (c *ReticulumConfig) Validate() error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func DefaultConfig() *ReticulumConfig {
|
||||
return &ReticulumConfig{
|
||||
EnableTransport: true,
|
||||
ShareInstance: false,
|
||||
SharedInstancePort: DEFAULT_SHARED_INSTANCE_PORT,
|
||||
InstanceControlPort: DEFAULT_INSTANCE_CONTROL_PORT,
|
||||
PanicOnInterfaceErr: false,
|
||||
LogLevel: DEFAULT_LOG_LEVEL,
|
||||
Interfaces: make(map[string]*InterfaceConfig),
|
||||
AppName: "Go Client",
|
||||
AppAspect: "node",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
package transport
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"math/rand"
|
||||
mathrand "math/rand"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -120,6 +121,9 @@ type Path struct {
|
||||
HopCount byte
|
||||
}
|
||||
|
||||
var randSource = mathrand.NewSource(time.Now().UnixNano())
|
||||
var rng = mathrand.New(randSource)
|
||||
|
||||
func NewTransport(cfg *common.ReticulumConfig) *Transport {
|
||||
t := &Transport{
|
||||
interfaces: make(map[string]common.NetworkInterface),
|
||||
@@ -441,7 +445,7 @@ func (t *Transport) HandleAnnounce(data []byte, sourceIface common.NetworkInterf
|
||||
}
|
||||
|
||||
// Add random delay before retransmission (0-2 seconds)
|
||||
delay := time.Duration(rand.Float64() * 2 * float64(time.Second))
|
||||
delay := time.Duration(rng.Float64() * 2 * float64(time.Second))
|
||||
time.Sleep(delay)
|
||||
|
||||
// Check bandwidth allocation for announces
|
||||
@@ -734,7 +738,7 @@ func (t *Transport) handleAnnouncePacket(data []byte, iface common.NetworkInterf
|
||||
}
|
||||
|
||||
// Add random delay before retransmission (0-2 seconds)
|
||||
delay := time.Duration(rand.Float64() * 2 * float64(time.Second))
|
||||
delay := time.Duration(rng.Float64() * 2 * float64(time.Second))
|
||||
time.Sleep(delay)
|
||||
|
||||
// Check bandwidth allocation for announces
|
||||
@@ -1035,39 +1039,65 @@ func (l *Link) GetStatus() int {
|
||||
return l.status
|
||||
}
|
||||
|
||||
func CreateAnnouncePacket(destHash []byte, identity *identity.Identity, appData []byte, hops byte) []byte {
|
||||
packet := make([]byte, 0, 256)
|
||||
|
||||
// Header byte construction according to RNS spec
|
||||
func CreateAnnouncePacket(destHash []byte, identity *identity.Identity, appData []byte, hops byte, config *common.ReticulumConfig) []byte {
|
||||
log.Printf("[DEBUG-7] Creating announce packet")
|
||||
|
||||
headerByte := byte(
|
||||
(0 << 7) | // Interface flag (IFAC_NONE)
|
||||
(0 << 6) | // Header type (HEADER_TYPE_1)
|
||||
(0 << 5) | // Context flag
|
||||
(1 << 4) | // Propagation type (BROADCAST)
|
||||
(0 << 2) | // Destination type (SINGLE)
|
||||
PACKET_TYPE_ANNOUNCE, // Packet type (0x01)
|
||||
(0 << 7) | // Interface flag (IFAC_NONE)
|
||||
(0 << 6) | // Header type (HEADER_TYPE_1)
|
||||
(0 << 5) | // Context flag
|
||||
(1 << 4) | // Propagation type (BROADCAST)
|
||||
(0 << 2) | // Destination type (SINGLE)
|
||||
PACKET_TYPE_ANNOUNCE, // Packet type (0x01)
|
||||
)
|
||||
|
||||
// Add header and hops
|
||||
packet = append(packet, headerByte, hops)
|
||||
|
||||
// Add destination hash (16 bytes)
|
||||
|
||||
log.Printf("[DEBUG-7] Created header byte: %02x, hops: %d", headerByte, hops)
|
||||
packet := []byte{headerByte, hops}
|
||||
|
||||
log.Printf("[DEBUG-7] Adding destination hash (16 bytes): %x", destHash)
|
||||
packet = append(packet, destHash...)
|
||||
|
||||
// Add full public key (64 bytes - both encryption and signing keys)
|
||||
fullPubKey := identity.GetPublicKey() // This should return full 64-byte key
|
||||
packet = append(packet, fullPubKey...)
|
||||
|
||||
// Add app data with length prefix
|
||||
appDataLen := make([]byte, 2)
|
||||
binary.BigEndian.PutUint16(appDataLen, uint16(len(appData)))
|
||||
packet = append(packet, appDataLen...)
|
||||
packet = append(packet, appData...)
|
||||
|
||||
// Sign the announce
|
||||
signData := append(destHash, appData...)
|
||||
|
||||
pubKey := identity.GetPublicKey()
|
||||
encKey := pubKey[:32]
|
||||
signKey := pubKey[32:]
|
||||
|
||||
log.Printf("[DEBUG-7] Adding encryption key (32 bytes): %x", encKey)
|
||||
packet = append(packet, encKey...)
|
||||
|
||||
log.Printf("[DEBUG-7] Adding signing key (32 bytes): %x", signKey)
|
||||
packet = append(packet, signKey...)
|
||||
|
||||
nameHash := sha256.Sum256([]byte(fmt.Sprintf("%s.%s", config.AppName, config.AppAspect)))
|
||||
log.Printf("[DEBUG-7] Adding name hash (10 bytes): %x", nameHash[:10])
|
||||
packet = append(packet, nameHash[:10]...)
|
||||
|
||||
randomBytes := make([]byte, 5)
|
||||
rand.Read(randomBytes)
|
||||
timeBytes := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(timeBytes, uint64(time.Now().Unix()))
|
||||
log.Printf("[DEBUG-7] Adding random hash (10 bytes): %x%x", randomBytes, timeBytes[:5])
|
||||
packet = append(packet, randomBytes...)
|
||||
packet = append(packet, timeBytes[:5]...)
|
||||
|
||||
nameBytes := []byte(fmt.Sprintf("%s.%s", config.AppName, config.AppAspect))
|
||||
appDataMsg := []byte{
|
||||
0x92, // msgpack array of 2 elements
|
||||
0xc4, // bin 8 format for byte array
|
||||
byte(len(nameBytes)), // length prefix
|
||||
}
|
||||
appDataMsg = append(appDataMsg, nameBytes...)
|
||||
appDataMsg = append(appDataMsg, 0x00)
|
||||
|
||||
signData := append(destHash, appDataMsg...)
|
||||
signature := identity.Sign(signData)
|
||||
log.Printf("[DEBUG-7] Adding signature (64 bytes): %x", signature)
|
||||
packet = append(packet, signature...)
|
||||
|
||||
packet = append(packet, appDataMsg...)
|
||||
log.Printf("[DEBUG-7] Final packet size: %d bytes", len(packet))
|
||||
|
||||
announceHash := sha256.Sum256(packet)
|
||||
log.Printf("[DEBUG-7] Generated announce hash: %x", announceHash)
|
||||
|
||||
return packet
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user