update
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -153,23 +154,32 @@ func (a *Announce) HandleAnnounce(data []byte) error {
|
||||
a.mutex.Lock()
|
||||
defer a.mutex.Unlock()
|
||||
|
||||
log.Printf("[DEBUG-7] Handling announce packet of %d bytes", len(data))
|
||||
|
||||
// Minimum packet size validation (2 header + 16 hash + 32 pubkey + 1 hops + 2 appdata len + 64 sig)
|
||||
if len(data) < 117 {
|
||||
log.Printf("[DEBUG-7] Invalid announce data length: %d bytes", len(data))
|
||||
return errors.New("invalid announce data length")
|
||||
}
|
||||
|
||||
// Parse header
|
||||
header := data[:2]
|
||||
hopCount := header[1]
|
||||
log.Printf("[DEBUG-7] Announce header: type=%x, hops=%d", header[0], hopCount)
|
||||
|
||||
if hopCount > MAX_HOPS {
|
||||
log.Printf("[DEBUG-7] Announce exceeded max hops: %d", hopCount)
|
||||
return errors.New("announce exceeded maximum hop count")
|
||||
}
|
||||
|
||||
// Extract fields
|
||||
// Extract fields with detailed logging
|
||||
destHash := data[2:18]
|
||||
publicKey := data[18:50]
|
||||
hopsByte := data[50]
|
||||
|
||||
log.Printf("[DEBUG-7] Announce fields: destHash=%x, pubKeyLen=%d, hops=%d",
|
||||
destHash, len(publicKey), hopsByte)
|
||||
|
||||
// Validate hop count matches header
|
||||
if hopsByte != hopCount {
|
||||
return errors.New("inconsistent hop count in packet")
|
||||
@@ -410,3 +420,43 @@ func (a *Announce) Hash() []byte {
|
||||
}
|
||||
return a.hash
|
||||
}
|
||||
|
||||
func (a *Announce) GetPacket() []byte {
|
||||
a.mutex.Lock()
|
||||
defer a.mutex.Unlock()
|
||||
|
||||
if a.packet == nil {
|
||||
// Generate hash from announce data
|
||||
h := sha256.New()
|
||||
h.Write(a.destinationHash)
|
||||
h.Write(a.identity.GetPublicKey())
|
||||
h.Write([]byte{a.hops})
|
||||
h.Write(a.appData)
|
||||
if a.ratchetID != nil {
|
||||
h.Write(a.ratchetID)
|
||||
}
|
||||
|
||||
// Construct packet
|
||||
packet := make([]byte, 0)
|
||||
packet = append(packet, PACKET_TYPE_ANNOUNCE)
|
||||
packet = append(packet, a.destinationHash...)
|
||||
packet = append(packet, a.identity.GetPublicKey()...)
|
||||
packet = append(packet, a.hops)
|
||||
packet = append(packet, a.appData...)
|
||||
if a.ratchetID != nil {
|
||||
packet = append(packet, a.ratchetID...)
|
||||
}
|
||||
|
||||
// Add signature
|
||||
signData := append(a.destinationHash, a.appData...)
|
||||
if a.ratchetID != nil {
|
||||
signData = append(signData, a.ratchetID...)
|
||||
}
|
||||
signature := a.identity.Sign(signData)
|
||||
packet = append(packet, signature...)
|
||||
|
||||
a.packet = packet
|
||||
}
|
||||
|
||||
return a.packet
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"sync"
|
||||
|
||||
"github.com/Sudo-Ivan/reticulum-go/pkg/common"
|
||||
@@ -121,8 +122,11 @@ func (d *Destination) Announce(appData []byte) error {
|
||||
d.mutex.Lock()
|
||||
defer d.mutex.Unlock()
|
||||
|
||||
log.Printf("[DEBUG-4] Creating announce packet for destination %s", d.ExpandName())
|
||||
|
||||
// If no specific appData provided, use default
|
||||
if appData == nil {
|
||||
log.Printf("[DEBUG-4] Using default app data for announce")
|
||||
appData = d.defaultAppData
|
||||
}
|
||||
|
||||
@@ -131,9 +135,12 @@ func (d *Destination) Announce(appData []byte) error {
|
||||
|
||||
// Add destination hash
|
||||
packet = append(packet, d.hash...)
|
||||
log.Printf("[DEBUG-4] Added destination hash %x to announce", d.hash[:8])
|
||||
|
||||
// Add identity public key
|
||||
packet = append(packet, d.identity.GetPublicKey()...)
|
||||
pubKey := d.identity.GetPublicKey()
|
||||
packet = append(packet, pubKey...)
|
||||
log.Printf("[DEBUG-4] Added public key %x to announce", pubKey[:8])
|
||||
|
||||
// Add flags byte
|
||||
flags := byte(0)
|
||||
@@ -144,46 +151,52 @@ func (d *Destination) Announce(appData []byte) error {
|
||||
flags |= 0x02
|
||||
}
|
||||
packet = append(packet, flags)
|
||||
log.Printf("[DEBUG-4] Added flags byte 0x%02x to announce", flags)
|
||||
|
||||
// Add proof strategy
|
||||
packet = append(packet, d.proofStrategy)
|
||||
log.Printf("[DEBUG-4] Added proof strategy 0x%02x to announce", d.proofStrategy)
|
||||
|
||||
// Add app data length and data if present
|
||||
// Add app data
|
||||
if appData != nil {
|
||||
appDataLen := uint16(len(appData))
|
||||
lenBytes := make([]byte, 2)
|
||||
binary.BigEndian.PutUint16(lenBytes, appDataLen)
|
||||
packet = append(packet, lenBytes...)
|
||||
packet = append(packet, appData...)
|
||||
log.Printf("[DEBUG-4] Added %d bytes of app data to announce", appDataLen)
|
||||
} else {
|
||||
// No app data
|
||||
packet = append(packet, 0x00, 0x00)
|
||||
log.Printf("[DEBUG-4] Added empty app data to announce")
|
||||
}
|
||||
|
||||
// Add ratchet data if enabled
|
||||
if d.ratchetsEnabled {
|
||||
// Add ratchet interval
|
||||
log.Printf("[DEBUG-4] Adding ratchet data to announce")
|
||||
intervalBytes := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(intervalBytes, uint32(d.ratchetInterval))
|
||||
packet = append(packet, intervalBytes...)
|
||||
|
||||
// Add current ratchet key
|
||||
ratchetKey := d.identity.GetCurrentRatchetKey()
|
||||
if ratchetKey == nil {
|
||||
log.Printf("[DEBUG-3] Failed to get current ratchet key")
|
||||
return errors.New("failed to get current ratchet key")
|
||||
}
|
||||
packet = append(packet, ratchetKey...)
|
||||
log.Printf("[DEBUG-4] Added ratchet key %x to announce", ratchetKey[:8])
|
||||
}
|
||||
|
||||
// Sign the announce packet
|
||||
signature, err := d.Sign(packet)
|
||||
if err != nil {
|
||||
log.Printf("[DEBUG-3] Failed to sign announce packet: %v", err)
|
||||
return fmt.Errorf("failed to sign announce packet: %w", err)
|
||||
}
|
||||
packet = append(packet, signature...)
|
||||
log.Printf("[DEBUG-4] Added signature to announce packet (total size: %d bytes)", len(packet))
|
||||
|
||||
// Send announce packet through transport layer
|
||||
// This will need to be implemented in the transport package
|
||||
// Send announce packet
|
||||
log.Printf("[DEBUG-4] Sending announce packet through transport layer")
|
||||
return transport.SendAnnounce(packet)
|
||||
}
|
||||
|
||||
@@ -305,26 +318,32 @@ func (d *Destination) DeregisterRequestHandler(path string) bool {
|
||||
|
||||
func (d *Destination) Encrypt(plaintext []byte) ([]byte, error) {
|
||||
if d.destType == PLAIN {
|
||||
log.Printf("[DEBUG-4] Using plaintext transmission for PLAIN destination")
|
||||
return plaintext, nil
|
||||
}
|
||||
|
||||
if d.identity == nil {
|
||||
log.Printf("[DEBUG-3] Cannot encrypt: no identity available")
|
||||
return nil, errors.New("no identity available for encryption")
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG-4] Encrypting %d bytes for destination type %d", len(plaintext), d.destType)
|
||||
|
||||
switch d.destType {
|
||||
case SINGLE:
|
||||
// For single destination, we need the recipient's public key
|
||||
recipientKey := d.identity.GetPublicKey()
|
||||
log.Printf("[DEBUG-4] Encrypting for single recipient with key %x", recipientKey[:8])
|
||||
return d.identity.Encrypt(plaintext, recipientKey)
|
||||
case GROUP:
|
||||
key := d.identity.GetCurrentRatchetKey()
|
||||
if key == nil {
|
||||
log.Printf("[DEBUG-3] Cannot encrypt: no ratchet key available")
|
||||
return nil, errors.New("no ratchet key available")
|
||||
}
|
||||
// CBC encryption with HMAC for group messages
|
||||
log.Printf("[DEBUG-4] Encrypting for group with ratchet key %x", key[:8])
|
||||
return d.identity.EncryptWithHMAC(plaintext, key)
|
||||
default:
|
||||
log.Printf("[DEBUG-3] Unsupported destination type %d for encryption", d.destType)
|
||||
return nil, errors.New("unsupported destination type for encryption")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,6 +184,7 @@ func (tc *TCPClientInterface) readLoop() {
|
||||
|
||||
func (tc *TCPClientInterface) handlePacket(data []byte) {
|
||||
if len(data) < 1 {
|
||||
log.Printf("[DEBUG-7] Received invalid packet: empty")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -194,19 +195,22 @@ func (tc *TCPClientInterface) handlePacket(data []byte) {
|
||||
tc.lastRx = lastRx
|
||||
tc.mutex.Unlock()
|
||||
|
||||
log.Printf("[DEBUG-5] Interface %s RX: %d bytes, total: %d, rate: %.2f Kbps",
|
||||
tc.GetName(), len(data), tc.RxBytes,
|
||||
float64(tc.RxBytes*8)/(time.Since(tc.startTime).Seconds()*1000))
|
||||
log.Printf("[DEBUG-7] Received packet: type=0x%02x, size=%d bytes", tc.packetType, len(data))
|
||||
|
||||
payload := data[1:]
|
||||
|
||||
switch tc.packetType {
|
||||
case 0x01: // Announce packet
|
||||
if len(payload) >= 53 { // Minimum announce size
|
||||
log.Printf("[DEBUG-7] Processing announce packet: payload=%d bytes", len(payload))
|
||||
if len(payload) >= 53 {
|
||||
tc.BaseInterface.ProcessIncoming(payload)
|
||||
} else {
|
||||
log.Printf("[DEBUG-7] Announce packet too small: %d bytes", len(payload))
|
||||
}
|
||||
case 0x02: // Link packet
|
||||
if len(payload) < 40 { // minimum size for link packet
|
||||
log.Printf("[DEBUG-7] Processing link packet: payload=%d bytes", len(payload))
|
||||
if len(payload) < 40 {
|
||||
log.Printf("[DEBUG-7] Link packet too small: %d bytes", len(payload))
|
||||
return
|
||||
}
|
||||
tc.BaseInterface.ProcessIncoming(payload)
|
||||
|
||||
103
pkg/link/link.go
103
pkg/link/link.go
@@ -9,6 +9,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -104,27 +105,32 @@ func (l *Link) Establish() error {
|
||||
defer l.mutex.Unlock()
|
||||
|
||||
if l.status != STATUS_PENDING {
|
||||
log.Printf("[DEBUG-3] Cannot establish link: invalid status %d", l.status)
|
||||
return errors.New("link already established or failed")
|
||||
}
|
||||
|
||||
destPublicKey := l.destination.GetPublicKey()
|
||||
if destPublicKey == nil {
|
||||
log.Printf("[DEBUG-3] Cannot establish link: destination has no public key")
|
||||
return errors.New("destination has no public key")
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG-4] Creating link request packet for destination %x", destPublicKey[:8])
|
||||
|
||||
// Create link request packet
|
||||
p, err := packet.NewPacket(
|
||||
packet.PACKET_TYPE_LINK,
|
||||
0x00, // flags
|
||||
0x00, // hops
|
||||
0x00,
|
||||
0x00,
|
||||
destPublicKey,
|
||||
l.linkID,
|
||||
)
|
||||
if err != nil {
|
||||
log.Printf("[DEBUG-3] Failed to create link request packet: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Send through transport
|
||||
log.Printf("[DEBUG-4] Sending link request packet with ID %x", l.linkID[:8])
|
||||
return l.transport.SendPacket(p)
|
||||
}
|
||||
|
||||
@@ -153,26 +159,32 @@ func (l *Link) HandleIdentification(data []byte) error {
|
||||
defer l.mutex.Unlock()
|
||||
|
||||
if len(data) < ed25519.PublicKeySize+ed25519.SignatureSize {
|
||||
log.Printf("[DEBUG-3] Invalid identification data length: %d bytes", len(data))
|
||||
return errors.New("invalid identification data length")
|
||||
}
|
||||
|
||||
pubKey := data[:ed25519.PublicKeySize]
|
||||
signature := data[ed25519.PublicKeySize:]
|
||||
|
||||
log.Printf("[DEBUG-4] Processing identification from public key %x", pubKey[:8])
|
||||
|
||||
remoteIdentity := identity.FromPublicKey(pubKey)
|
||||
if remoteIdentity == nil {
|
||||
log.Printf("[DEBUG-3] Invalid remote identity from public key %x", pubKey[:8])
|
||||
return errors.New("invalid remote identity")
|
||||
}
|
||||
|
||||
// Verify signature
|
||||
signData := append(l.linkID, pubKey...)
|
||||
if !remoteIdentity.Verify(signData, signature) {
|
||||
log.Printf("[DEBUG-3] Invalid signature from remote identity %x", pubKey[:8])
|
||||
return errors.New("invalid signature")
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG-4] Remote identity verified successfully: %x", pubKey[:8])
|
||||
l.remoteIdentity = remoteIdentity
|
||||
|
||||
if l.identifiedCallback != nil {
|
||||
log.Printf("[DEBUG-4] Executing identified callback for remote identity %x", pubKey[:8])
|
||||
l.identifiedCallback(l, remoteIdentity)
|
||||
}
|
||||
|
||||
@@ -443,28 +455,21 @@ func (l *Link) SendPacket(data []byte) error {
|
||||
defer l.mutex.Unlock()
|
||||
|
||||
if l.status != STATUS_ACTIVE {
|
||||
log.Printf("[DEBUG-3] Cannot send packet: link not active (status: %d)", l.status)
|
||||
return errors.New("link not active")
|
||||
}
|
||||
|
||||
// Compute HMAC first
|
||||
messageHMAC := l.destination.GetIdentity().ComputeHMAC(l.hmacKey, data)
|
||||
|
||||
// Combine data and HMAC
|
||||
authenticatedData := append(data, messageHMAC...)
|
||||
|
||||
// Encrypt authenticated data using session key
|
||||
encryptedData, err := l.encrypt(authenticatedData)
|
||||
log.Printf("[DEBUG-4] Encrypting packet of %d bytes", len(data))
|
||||
encrypted, err := l.encrypt(data)
|
||||
if err != nil {
|
||||
log.Printf("[DEBUG-3] Failed to encrypt packet: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG-4] Sending encrypted packet of %d bytes", len(encrypted))
|
||||
l.lastOutbound = time.Now()
|
||||
l.lastDataSent = time.Now()
|
||||
|
||||
if l.packetCallback != nil {
|
||||
l.packetCallback(encryptedData, nil)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -473,25 +478,51 @@ func (l *Link) HandleInbound(data []byte) error {
|
||||
defer l.mutex.Unlock()
|
||||
|
||||
if l.status != STATUS_ACTIVE {
|
||||
log.Printf("[DEBUG-3] Dropping inbound packet: link not active (status: %d)", l.status)
|
||||
return errors.New("link not active")
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG-7] Received encrypted packet of %d bytes", len(data))
|
||||
|
||||
// Decrypt data using session key
|
||||
decryptedData, err := l.decrypt(data)
|
||||
if err != nil {
|
||||
log.Printf("[DEBUG-3] Failed to decrypt packet: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Split message and HMAC
|
||||
if len(decryptedData) < sha256.Size {
|
||||
log.Printf("[DEBUG-3] Received data too short: %d bytes", len(decryptedData))
|
||||
return errors.New("received data too short")
|
||||
}
|
||||
|
||||
message := decryptedData[:len(decryptedData)-sha256.Size]
|
||||
messageHMAC := decryptedData[len(decryptedData)-sha256.Size:]
|
||||
|
||||
// Log packet details
|
||||
log.Printf("[DEBUG-7] Decrypted packet details:")
|
||||
log.Printf("[DEBUG-7] - Size: %d bytes", len(message))
|
||||
log.Printf("[DEBUG-7] - First 16 bytes: %x", message[:min(16, len(message))])
|
||||
if len(message) > 0 {
|
||||
log.Printf("[DEBUG-7] - Type: 0x%02x", message[0])
|
||||
switch message[0] {
|
||||
case packet.PacketData:
|
||||
log.Printf("[DEBUG-7] - Type: Data Packet")
|
||||
case packet.PacketAnnounce:
|
||||
log.Printf("[DEBUG-7] - Type: Announce Packet")
|
||||
case packet.PacketLinkRequest:
|
||||
log.Printf("[DEBUG-7] - Type: Link Request")
|
||||
case packet.PacketProof:
|
||||
log.Printf("[DEBUG-7] - Type: Proof Request")
|
||||
default:
|
||||
log.Printf("[DEBUG-7] - Type: Unknown (0x%02x)", message[0])
|
||||
}
|
||||
}
|
||||
|
||||
// Verify HMAC
|
||||
if !l.destination.GetIdentity().ValidateHMAC(l.hmacKey, message, messageHMAC) {
|
||||
log.Printf("[DEBUG-3] Invalid HMAC for packet")
|
||||
return errors.New("invalid message authentication code")
|
||||
}
|
||||
|
||||
@@ -637,23 +668,31 @@ func (l *Link) maintainLink() {
|
||||
ticker := time.NewTicker(time.Second * KEEPALIVE)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
if l.status != STATUS_ACTIVE {
|
||||
return
|
||||
}
|
||||
for range ticker.C {
|
||||
if l.status != STATUS_ACTIVE {
|
||||
return
|
||||
}
|
||||
|
||||
if l.InactiveFor() > float64(STALE_TIME) {
|
||||
inactiveTime := l.InactiveFor()
|
||||
if inactiveTime > float64(STALE_TIME) {
|
||||
l.mutex.Lock()
|
||||
l.teardownReason = STATUS_FAILED
|
||||
l.mutex.Unlock()
|
||||
l.Teardown()
|
||||
return
|
||||
}
|
||||
|
||||
noDataTime := l.NoDataFor()
|
||||
if noDataTime > float64(KEEPALIVE) {
|
||||
l.mutex.Lock()
|
||||
err := l.SendPacket([]byte{})
|
||||
if err != nil {
|
||||
l.teardownReason = STATUS_FAILED
|
||||
l.mutex.Unlock()
|
||||
l.Teardown()
|
||||
return
|
||||
}
|
||||
|
||||
if l.NoDataFor() > float64(KEEPALIVE) {
|
||||
// Send keepalive packet
|
||||
l.SendPacket([]byte{})
|
||||
}
|
||||
l.mutex.Unlock()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -697,3 +736,11 @@ func (l *Link) HandleProofRequest(packet *packet.Packet) bool {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function for min of two ints
|
||||
func min(a, b int) int {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
@@ -384,11 +384,69 @@ func (t *Transport) UpdatePath(destinationHash []byte, nextHop []byte, interface
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Transport) HandleAnnounce(destinationHash []byte, identity []byte, appData []byte, announceHash []byte) {
|
||||
t.mutex.RLock()
|
||||
defer t.mutex.RUnlock()
|
||||
func (t *Transport) HandleAnnounce(data []byte, sourceIface common.NetworkInterface) error {
|
||||
if len(data) < 53 { // Minimum size for announce packet
|
||||
return fmt.Errorf("announce packet too small: %d bytes", len(data))
|
||||
}
|
||||
|
||||
t.notifyAnnounceHandlers(destinationHash, identity, appData)
|
||||
log.Printf("[DEBUG-7] Transport handling announce of %d bytes from %s",
|
||||
len(data), sourceIface.GetName())
|
||||
|
||||
// Parse announce fields according to RNS spec
|
||||
destHash := data[1:33]
|
||||
identity := data[33:49]
|
||||
appData := data[49:]
|
||||
|
||||
// Generate announce hash to check for duplicates
|
||||
announceHash := sha256.Sum256(data)
|
||||
hashStr := string(announceHash[:])
|
||||
|
||||
t.mutex.Lock()
|
||||
if _, seen := t.seenAnnounces[hashStr]; seen {
|
||||
t.mutex.Unlock()
|
||||
log.Printf("[DEBUG-7] Ignoring duplicate announce %x", announceHash[:8])
|
||||
return nil
|
||||
}
|
||||
t.seenAnnounces[hashStr] = true
|
||||
t.mutex.Unlock()
|
||||
|
||||
// Don't forward if max hops reached
|
||||
if data[0] >= MAX_HOPS {
|
||||
log.Printf("[DEBUG-7] Announce exceeded max hops: %d", data[0])
|
||||
return nil
|
||||
}
|
||||
|
||||
// Add random delay before retransmission (0-2 seconds)
|
||||
delay := time.Duration(rand.Float64() * 2 * float64(time.Second))
|
||||
time.Sleep(delay)
|
||||
|
||||
// Check bandwidth allocation for announces
|
||||
if !t.announceRate.Allow() {
|
||||
log.Printf("[DEBUG-7] Announce rate limit exceeded, queuing...")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Increment hop count
|
||||
data[0]++
|
||||
|
||||
// Broadcast to all other interfaces
|
||||
var lastErr error
|
||||
for name, iface := range t.interfaces {
|
||||
if iface == sourceIface || !iface.IsEnabled() {
|
||||
continue
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG-7] Forwarding announce on interface %s", name)
|
||||
if err := iface.Send(data, ""); err != nil {
|
||||
log.Printf("[DEBUG-7] Failed to forward announce on %s: %v", name, err)
|
||||
lastErr = err
|
||||
}
|
||||
}
|
||||
|
||||
// Notify handlers
|
||||
t.notifyAnnounceHandlers(destHash, identity, appData)
|
||||
|
||||
return lastErr
|
||||
}
|
||||
|
||||
func (t *Transport) NewDestination(identity interface{}, direction int, destType int, appName string, aspects ...string) *Destination {
|
||||
@@ -541,13 +599,13 @@ func (t *Transport) HandlePacket(data []byte, iface common.NetworkInterface) {
|
||||
|
||||
// Update interface stats before processing
|
||||
if tcpIface, ok := iface.(*interfaces.TCPClientInterface); ok {
|
||||
tcpIface.UpdateStats(uint64(len(data)), true) // true for RX
|
||||
tcpIface.UpdateStats(uint64(len(data)), true)
|
||||
}
|
||||
|
||||
switch packetType {
|
||||
case 0x01: // Announce packet
|
||||
case announce.PACKET_TYPE_ANNOUNCE:
|
||||
t.handleAnnouncePacket(data[1:], iface)
|
||||
case 0x02: // Link packet
|
||||
case announce.PACKET_TYPE_LINK:
|
||||
t.handleLinkPacket(data[1:], iface)
|
||||
case 0x03: // Path response
|
||||
t.handlePathResponse(data[1:], iface)
|
||||
@@ -559,52 +617,64 @@ func (t *Transport) HandlePacket(data []byte, iface common.NetworkInterface) {
|
||||
}
|
||||
|
||||
func (t *Transport) handleAnnouncePacket(data []byte, iface common.NetworkInterface) {
|
||||
// Validate minimum packet size (1 byte hop count + 32 bytes dest + 16 bytes identity + 4 bytes min app data)
|
||||
if len(data) < 53 {
|
||||
log.Printf("[DEBUG-3] Announce packet too small: %d bytes", len(data))
|
||||
return
|
||||
}
|
||||
|
||||
announceHash := sha256.Sum256(data)
|
||||
log.Printf("[DEBUG-3] Processing announce %x from interface %s",
|
||||
announceHash[:8], iface.GetName())
|
||||
|
||||
if t.seenAnnounces[string(announceHash[:])] {
|
||||
t.mutex.Lock()
|
||||
if _, seen := t.seenAnnounces[string(announceHash[:])]; seen {
|
||||
t.mutex.Unlock()
|
||||
log.Printf("[DEBUG-4] Ignoring duplicate announce %x", announceHash[:8])
|
||||
return
|
||||
}
|
||||
|
||||
// Record this announce
|
||||
t.seenAnnounces[string(announceHash[:])] = true
|
||||
|
||||
// Extract announce fields
|
||||
if len(data) < 53 { // Minimum size for announce packet
|
||||
return
|
||||
}
|
||||
t.mutex.Unlock()
|
||||
|
||||
// Don't forward if max hops reached
|
||||
if data[0] >= MAX_HOPS {
|
||||
log.Printf("[DEBUG-3] Announce exceeded max hops: %d", data[0])
|
||||
return
|
||||
}
|
||||
|
||||
// Parse announce fields
|
||||
hopCount := data[0]
|
||||
destHash := data[1:33]
|
||||
identity := data[33:49]
|
||||
appData := data[49:]
|
||||
|
||||
// Add random delay before retransmission (0-2 seconds)
|
||||
delay := time.Duration(rand.Float64() * 2 * float64(time.Second))
|
||||
time.Sleep(delay)
|
||||
|
||||
// Check bandwidth allocation for announces
|
||||
if !t.announceRate.Allow() {
|
||||
log.Printf("[DEBUG-3] Announce rate limit exceeded, dropping")
|
||||
return
|
||||
}
|
||||
|
||||
// Increment hop count and retransmit
|
||||
data[0]++
|
||||
t.broadcastAnnouncePacket(data)
|
||||
}
|
||||
// Increment hop count for forwarding
|
||||
data[0] = hopCount + 1
|
||||
|
||||
func (t *Transport) broadcastAnnouncePacket(data []byte) error {
|
||||
t.mutex.RLock()
|
||||
defer t.mutex.RUnlock()
|
||||
// Forward to other interfaces
|
||||
for name, outIface := range t.interfaces {
|
||||
if outIface == iface || !outIface.IsEnabled() {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, iface := range t.interfaces {
|
||||
if err := iface.Send(data, ""); err != nil {
|
||||
return fmt.Errorf("failed to broadcast announce: %w", err)
|
||||
log.Printf("[DEBUG-7] Forwarding announce on interface %s", name)
|
||||
if err := outIface.Send(data, ""); err != nil {
|
||||
log.Printf("[DEBUG-3] Failed to forward announce on %s: %v", name, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
// Notify announce handlers
|
||||
t.notifyAnnounceHandlers(destHash, identity, appData)
|
||||
}
|
||||
|
||||
func (t *Transport) handleLinkPacket(data []byte, iface common.NetworkInterface) {
|
||||
|
||||
Reference in New Issue
Block a user