update and format

This commit is contained in:
Sudo-Ivan
2025-01-01 00:58:37 -06:00
parent a2499e4a15
commit ae40d2879c
8 changed files with 154 additions and 90 deletions

View File

@@ -15,10 +15,10 @@ import (
"github.com/Sudo-Ivan/reticulum-go/pkg/buffer" "github.com/Sudo-Ivan/reticulum-go/pkg/buffer"
"github.com/Sudo-Ivan/reticulum-go/pkg/channel" "github.com/Sudo-Ivan/reticulum-go/pkg/channel"
"github.com/Sudo-Ivan/reticulum-go/pkg/common" "github.com/Sudo-Ivan/reticulum-go/pkg/common"
"github.com/Sudo-Ivan/reticulum-go/pkg/identity"
"github.com/Sudo-Ivan/reticulum-go/pkg/interfaces" "github.com/Sudo-Ivan/reticulum-go/pkg/interfaces"
"github.com/Sudo-Ivan/reticulum-go/pkg/packet" "github.com/Sudo-Ivan/reticulum-go/pkg/packet"
"github.com/Sudo-Ivan/reticulum-go/pkg/transport" "github.com/Sudo-Ivan/reticulum-go/pkg/transport"
"github.com/Sudo-Ivan/reticulum-go/pkg/identity"
) )
var ( var (
@@ -184,7 +184,17 @@ func main() {
log.Fatalf("Failed to create announce: %v", err) log.Fatalf("Failed to create announce: %v", err)
} }
// Propagate announce to all interfaces periodically // Send initial announce immediately
for _, iface := range r.interfaces {
if netIface, ok := iface.(common.NetworkInterface); ok {
debugLog(2, "Sending initial announce on interface %s", netIface.GetName())
if err := announce.Propagate([]common.NetworkInterface{netIface}); err != nil {
debugLog(1, "Failed to propagate initial announce: %v", err)
}
}
}
// Then start periodic announces
go func() { go func() {
ticker := time.NewTicker(5 * time.Minute) ticker := time.NewTicker(5 * time.Minute)
defer ticker.Stop() defer ticker.Stop()
@@ -391,11 +401,14 @@ func (r *Reticulum) Stop() error {
} }
func (r *Reticulum) handleAnnounce(data []byte, iface common.NetworkInterface) { func (r *Reticulum) handleAnnounce(data []byte, iface common.NetworkInterface) {
debugLog(2, "Received announce packet on interface %s (%d bytes)", iface.GetName(), len(data))
a := &announce.Announce{} a := &announce.Announce{}
if err := a.HandleAnnounce(data); err != nil { if err := a.HandleAnnounce(data); err != nil {
debugLog(1, "Error handling announce: %v", err) debugLog(1, "Error handling announce: %v", err)
return return
} }
debugLog(3, "Successfully parsed announce packet")
// Add random delay before propagation (0-2 seconds) // Add random delay before propagation (0-2 seconds)
delay := time.Duration(rand.Float64() * 2 * float64(time.Second)) delay := time.Duration(rand.Float64() * 2 * float64(time.Second))
@@ -421,11 +434,13 @@ func (r *Reticulum) handleAnnounce(data []byte, iface common.NetworkInterface) {
} }
// Check if interface has bandwidth available for announces // Check if interface has bandwidth available for announces
if err := a.Propagate([]common.NetworkInterface{otherIface}); err != nil { if netIface, ok := otherIface.(common.NetworkInterface); ok {
if err := a.Propagate([]common.NetworkInterface{netIface}); err != nil {
debugLog(1, "Error propagating announce: %v", err) debugLog(1, "Error propagating announce: %v", err)
} }
} }
} }
}
type AnnounceHandler struct { type AnnounceHandler struct {
aspectFilter []string aspectFilter []string

View File

@@ -5,7 +5,7 @@ import (
"crypto/sha256" "crypto/sha256"
"encoding/binary" "encoding/binary"
"errors" "errors"
"log" "fmt"
"sync" "sync"
"time" "time"
@@ -106,27 +106,25 @@ func New(dest *identity.Identity, appData []byte, pathResponse bool) (*Announce,
} }
func (a *Announce) Propagate(interfaces []common.NetworkInterface) error { func (a *Announce) Propagate(interfaces []common.NetworkInterface) error {
packet := a.CreatePacket() a.mutex.RLock()
defer a.mutex.RUnlock()
// Enhanced logging // Use cached packet if available, otherwise create new one
log.Printf("Creating announce packet:") var packet []byte
log.Printf(" Destination Hash: %x", a.destinationHash) if a.packet != nil {
log.Printf(" Identity Public Key: %x", a.identity.GetPublicKey()) packet = a.packet
log.Printf(" App Data: %s", string(a.appData)) } else {
log.Printf(" Signature: %x", a.signature) packet = a.CreatePacket()
log.Printf(" Total Packet Size: %d bytes", len(packet)) a.packet = packet
log.Printf(" Raw Packet: %x", packet) }
// Propagate to interfaces
for _, iface := range interfaces { for _, iface := range interfaces {
log.Printf("Propagating on interface %s:", iface.GetName()) if !iface.IsEnabled() || !iface.GetBandwidthAvailable() {
log.Printf(" Interface Type: %d", iface.GetType()) continue
log.Printf(" MTU: %d bytes", iface.GetMTU()) }
if err := iface.Send(packet, ""); err != nil { if err := iface.Send(packet, ""); err != nil {
log.Printf(" Failed to propagate: %v", err) return fmt.Errorf("failed to propagate on interface %s: %w", iface.GetName(), err)
} else {
log.Printf(" Successfully propagated")
} }
} }

View File

@@ -1,10 +1,10 @@
package common package common
import ( import (
"encoding/binary"
"net" "net"
"sync" "sync"
"time" "time"
"encoding/binary"
) )
// NetworkInterface defines the interface for all network communication methods // NetworkInterface defines the interface for all network communication methods
@@ -28,6 +28,7 @@ type NetworkInterface interface {
IsEnabled() bool IsEnabled() bool
IsOnline() bool IsOnline() bool
IsDetached() bool IsDetached() bool
GetBandwidthAvailable() bool
// Packet handling // Packet handling
ProcessIncoming([]byte) ProcessIncoming([]byte)
@@ -55,6 +56,7 @@ type BaseInterface struct {
TxBytes uint64 TxBytes uint64
RxBytes uint64 RxBytes uint64
lastTx time.Time
Mutex sync.RWMutex Mutex sync.RWMutex
Owner interface{} Owner interface{}
@@ -70,6 +72,7 @@ func NewBaseInterface(name string, ifaceType InterfaceType, enabled bool) BaseIn
Enabled: enabled, Enabled: enabled,
MTU: DEFAULT_MTU, MTU: DEFAULT_MTU,
Bitrate: BITRATE_MINIMUM, Bitrate: BITRATE_MINIMUM,
lastTx: time.Now(),
} }
} }
@@ -188,3 +191,21 @@ func (i *BaseInterface) SendLinkPacket(dest []byte, data []byte, timestamp time.
return i.Send(packet, "") return i.Send(packet, "")
} }
func (i *BaseInterface) GetBandwidthAvailable() bool {
i.Mutex.RLock()
defer i.Mutex.RUnlock()
// If no transmission in last second, bandwidth is available
if time.Since(i.lastTx) > time.Second {
return true
}
// Calculate current bandwidth usage
bytesPerSec := float64(i.TxBytes) / time.Since(i.lastTx).Seconds()
currentUsage := bytesPerSec * 8 // Convert to bits/sec
// Check if usage is below threshold (2% of total bitrate)
maxUsage := float64(i.Bitrate) * 0.02 // 2% propagation rate
return currentUsage < maxUsage
}

View File

@@ -11,7 +11,7 @@ import (
) )
const ( const (
BITRATE_MINIMUM = 5 // Minimum required bitrate in bits/sec BITRATE_MINIMUM = 1200 // Minimum bitrate in bits/second
MODE_FULL = 0x01 MODE_FULL = 0x01
// Interface modes // Interface modes
@@ -23,6 +23,8 @@ const (
// Interface types // Interface types
TYPE_UDP = 0x01 TYPE_UDP = 0x01
TYPE_TCP = 0x02 TYPE_TCP = 0x02
PROPAGATION_RATE = 0.02 // 2% of interface bandwidth
) )
type Interface interface { type Interface interface {
@@ -46,6 +48,7 @@ type Interface interface {
Stop() error Stop() error
GetMTU() int GetMTU() int
GetConn() net.Conn GetConn() net.Conn
common.NetworkInterface
} }
type BaseInterface struct { type BaseInterface struct {
@@ -61,6 +64,7 @@ type BaseInterface struct {
Bitrate int64 Bitrate int64
TxBytes uint64 TxBytes uint64
RxBytes uint64 RxBytes uint64
lastTx time.Time
mutex sync.RWMutex mutex sync.RWMutex
packetCallback common.PacketCallback packetCallback common.PacketCallback
@@ -78,6 +82,7 @@ func NewBaseInterface(name string, ifType common.InterfaceType, enabled bool) Ba
OUT: false, OUT: false,
MTU: common.DEFAULT_MTU, MTU: common.DEFAULT_MTU,
Bitrate: BITRATE_MINIMUM, Bitrate: BITRATE_MINIMUM,
lastTx: time.Now(),
} }
} }
@@ -197,7 +202,6 @@ func (i *BaseInterface) IsDetached() bool {
return i.Detached return i.Detached
} }
// Default implementations that should be overridden by specific interfaces
func (i *BaseInterface) Start() error { func (i *BaseInterface) Start() error {
return nil return nil
} }
@@ -213,3 +217,29 @@ func (i *BaseInterface) Send(data []byte, address string) error {
func (i *BaseInterface) GetConn() net.Conn { func (i *BaseInterface) GetConn() net.Conn {
return nil return nil
} }
func (i *BaseInterface) GetBandwidthAvailable() bool {
i.mutex.RLock()
defer i.mutex.RUnlock()
// If no transmission in last second, bandwidth is available
if time.Since(i.lastTx) > time.Second {
return true
}
// Calculate current bandwidth usage
bytesPerSec := float64(i.TxBytes) / time.Since(i.lastTx).Seconds()
currentUsage := bytesPerSec * 8 // Convert to bits/sec
// Check if usage is below threshold
maxUsage := float64(i.Bitrate) * PROPAGATION_RATE
return currentUsage < maxUsage
}
func (i *BaseInterface) updateBandwidthStats(bytes uint64) {
i.mutex.Lock()
defer i.mutex.Unlock()
i.TxBytes += bytes
i.lastTx = time.Now()
}