This commit is contained in:
Sudo-Ivan
2025-01-01 17:00:11 -06:00
parent 6cdc02346f
commit 0862830431
9 changed files with 673 additions and 125 deletions

View File

@@ -29,14 +29,14 @@ const (
DEBUG_LEVEL = 4 // Default debug level for interface logging
// Add more debug levels
DEBUG_CRITICAL = 1 // Critical errors
DEBUG_ERROR = 2 // Non-critical errors
DEBUG_INFO = 3 // Important information
DEBUG_VERBOSE = 4 // Detailed information
DEBUG_TRACE = 5 // Very detailed tracing
DEBUG_PACKETS = 6 // Packet-level details
DEBUG_ALL = 7 // Everything
// Debug levels
DEBUG_CRITICAL = 1
DEBUG_ERROR = 2
DEBUG_INFO = 3
DEBUG_VERBOSE = 4
DEBUG_TRACE = 5
DEBUG_PACKETS = 6
DEBUG_ALL = 7
)
type Interface interface {
@@ -60,6 +60,7 @@ type Interface interface {
Stop() error
GetMTU() int
GetConn() net.Conn
GetBandwidthAvailable() bool
common.NetworkInterface
}
@@ -126,8 +127,7 @@ func (i *BaseInterface) ProcessIncoming(data []byte) {
func (i *BaseInterface) ProcessOutgoing(data []byte) error {
if !i.Online || i.Detached {
log.Printf("[DEBUG-1] Interface %s: Cannot process outgoing packet - interface offline or detached",
i.Name)
log.Printf("[DEBUG-1] Interface %s: Cannot process outgoing packet - interface offline or detached", i.Name)
return fmt.Errorf("interface offline or detached")
}
@@ -135,8 +135,7 @@ func (i *BaseInterface) ProcessOutgoing(data []byte) error {
i.TxBytes += uint64(len(data))
i.mutex.Unlock()
log.Printf("[DEBUG-%d] Interface %s: Processed outgoing packet of %d bytes, total TX: %d",
DEBUG_LEVEL, i.Name, len(data), i.TxBytes)
log.Printf("[DEBUG-%d] Interface %s: Processed outgoing packet of %d bytes, total TX: %d", DEBUG_LEVEL, i.Name, len(data), i.TxBytes)
return nil
}
@@ -146,7 +145,7 @@ func (i *BaseInterface) SendPathRequest(packet []byte) error {
}
frame := make([]byte, 0, len(packet)+1)
frame = append(frame, 0x01) // Path request type
frame = append(frame, 0x01)
frame = append(frame, packet...)
return i.ProcessOutgoing(frame)
@@ -158,7 +157,7 @@ func (i *BaseInterface) SendLinkPacket(dest []byte, data []byte, timestamp time.
}
frame := make([]byte, 0, len(dest)+len(data)+9)
frame = append(frame, 0x02) // Link packet type
frame = append(frame, 0x02)
frame = append(frame, dest...)
ts := make([]byte, 8)
@@ -190,8 +189,7 @@ func (i *BaseInterface) Enable() {
i.Enabled = true
i.Online = true
log.Printf("[DEBUG-%d] Interface %s: State changed - Enabled: %v->%v, Online: %v->%v",
DEBUG_INFO, i.Name, prevState, i.Enabled, !i.Online, i.Online)
log.Printf("[DEBUG-%d] Interface %s: State changed - Enabled: %v->%v, Online: %v->%v", DEBUG_INFO, i.Name, prevState, i.Enabled, !i.Online, i.Online)
}
func (i *BaseInterface) Disable() {
@@ -239,13 +237,11 @@ func (i *BaseInterface) Stop() error {
}
func (i *BaseInterface) Send(data []byte, address string) error {
log.Printf("[DEBUG-%d] Interface %s: Sending %d bytes to %s",
DEBUG_LEVEL, i.Name, len(data), address)
log.Printf("[DEBUG-%d] Interface %s: Sending %d bytes to %s", DEBUG_LEVEL, i.Name, len(data), address)
err := i.ProcessOutgoing(data)
if err != nil {
log.Printf("[DEBUG-1] Interface %s: Failed to send data: %v",
i.Name, err)
log.Printf("[DEBUG-1] Interface %s: Failed to send data: %v", i.Name, err)
return err
}
@@ -264,21 +260,17 @@ func (i *BaseInterface) GetBandwidthAvailable() bool {
now := time.Now()
timeSinceLastTx := now.Sub(i.lastTx)
// If no recent transmission, bandwidth is available
if timeSinceLastTx > time.Second {
log.Printf("[DEBUG-%d] Interface %s: Bandwidth available (idle for %.2fs)",
DEBUG_VERBOSE, i.Name, timeSinceLastTx.Seconds())
log.Printf("[DEBUG-%d] Interface %s: Bandwidth available (idle for %.2fs)", DEBUG_VERBOSE, i.Name, timeSinceLastTx.Seconds())
return true
}
// Calculate current usage over the last second
bytesPerSec := float64(i.TxBytes) / timeSinceLastTx.Seconds()
currentUsage := bytesPerSec * 8 // Convert to bits
currentUsage := bytesPerSec * 8
maxUsage := float64(i.Bitrate) * PROPAGATION_RATE
available := currentUsage < maxUsage
log.Printf("[DEBUG-%d] Interface %s: Bandwidth stats - Current: %.2f bps, Max: %.2f bps, Usage: %.1f%%, Available: %v",
DEBUG_VERBOSE, i.Name, currentUsage, maxUsage, (currentUsage/maxUsage)*100, available)
log.Printf("[DEBUG-%d] Interface %s: Bandwidth stats - Current: %.2f bps, Max: %.2f bps, Usage: %.1f%%, Available: %v", DEBUG_VERBOSE, i.Name, currentUsage, maxUsage, (currentUsage/maxUsage)*100, available)
return available
}
@@ -290,6 +282,5 @@ func (i *BaseInterface) updateBandwidthStats(bytes uint64) {
i.TxBytes += bytes
i.lastTx = time.Now()
log.Printf("[DEBUG-%d] Interface %s: Updated bandwidth stats - TX bytes: %d, Last TX: %v",
DEBUG_LEVEL, i.Name, i.TxBytes, i.lastTx)
log.Printf("[DEBUG-%d] Interface %s: Updated bandwidth stats - TX bytes: %d, Last TX: %v", DEBUG_LEVEL, i.Name, i.TxBytes, i.lastTx)
}

View File

@@ -4,6 +4,7 @@ import (
"fmt"
"log"
"net"
"runtime"
"sync"
"syscall"
"time"
@@ -50,7 +51,6 @@ type TCPClientInterface struct {
enabled bool
TxBytes uint64
RxBytes uint64
startTime time.Time
lastTx time.Time
lastRx time.Time
}
@@ -103,6 +103,19 @@ func (tc *TCPClientInterface) Start() error {
return err
}
tc.conn = conn
// Set platform-specific timeouts
switch runtime.GOOS {
case "linux":
if err := tc.setTimeoutsLinux(); err != nil {
log.Printf("[DEBUG-2] Failed to set Linux TCP timeouts: %v", err)
}
case "darwin":
if err := tc.setTimeoutsOSX(); err != nil {
log.Printf("[DEBUG-2] Failed to set OSX TCP timeouts: %v", err)
}
}
tc.Online = true
go tc.readLoop()
return nil
@@ -126,31 +139,31 @@ func (tc *TCPClientInterface) readLoop() {
return
}
// Update RX bytes
tc.mutex.Lock()
tc.RxBytes += uint64(n)
tc.mutex.Unlock()
// Update RX bytes for raw received data
tc.UpdateStats(uint64(n), true)
for i := 0; i < n; i++ {
b := buffer[i]
if tc.kissFraming {
// KISS framing logic
if inFrame && b == KISS_FEND {
inFrame = false
tc.handlePacket(dataBuffer)
dataBuffer = dataBuffer[:0]
} else if b == KISS_FEND {
inFrame = true
} else if inFrame {
if b == KISS_FEND {
if inFrame && len(dataBuffer) > 0 {
tc.handlePacket(dataBuffer)
dataBuffer = dataBuffer[:0]
}
inFrame = !inFrame
continue
}
if inFrame {
if b == KISS_FESC {
escape = true
} else {
if escape {
if b == KISS_TFEND {
b = KISS_FEND
}
if b == KISS_TFESC {
} else if b == KISS_TFESC {
b = KISS_FESC
}
escape = false
@@ -160,13 +173,16 @@ func (tc *TCPClientInterface) readLoop() {
}
} else {
// HDLC framing logic
if inFrame && b == HDLC_FLAG {
inFrame = false
tc.handlePacket(dataBuffer)
dataBuffer = dataBuffer[:0]
} else if b == HDLC_FLAG {
inFrame = true
} else if inFrame {
if b == HDLC_FLAG {
if inFrame && len(dataBuffer) > 0 {
tc.handlePacket(dataBuffer)
dataBuffer = dataBuffer[:0]
}
inFrame = !inFrame
continue
}
if inFrame {
if b == HDLC_ESC {
escape = true
} else {
@@ -241,15 +257,8 @@ func (tc *TCPClientInterface) ProcessOutgoing(data []byte) error {
frame = append(frame, HDLC_FLAG)
}
tc.mutex.Lock()
tc.TxBytes += uint64(len(frame))
lastTx := time.Now()
tc.lastTx = lastTx
tc.mutex.Unlock()
log.Printf("[DEBUG-5] Interface %s TX: %d bytes, total: %d, rate: %.2f Kbps",
tc.GetName(), len(frame), tc.TxBytes,
float64(tc.TxBytes*8)/(time.Since(tc.startTime).Seconds()*1000))
// Update TX stats before sending
tc.UpdateStats(uint64(len(frame)), false)
_, err := tc.conn.Write(frame)
return err
@@ -478,6 +487,37 @@ func (tc *TCPClientInterface) GetStats() (tx uint64, rx uint64, lastTx time.Time
return tc.TxBytes, tc.RxBytes, tc.lastTx, tc.lastRx
}
func (tc *TCPClientInterface) setTimeoutsLinux() error {
tcpConn, ok := tc.conn.(*net.TCPConn)
if !ok {
return fmt.Errorf("not a TCP connection")
}
if !tc.i2pTunneled {
if err := tcpConn.SetKeepAlive(true); err != nil {
return err
}
if err := tcpConn.SetKeepAlivePeriod(time.Duration(TCP_PROBE_INTERVAL) * time.Second); err != nil {
return err
}
}
return nil
}
func (tc *TCPClientInterface) setTimeoutsOSX() error {
tcpConn, ok := tc.conn.(*net.TCPConn)
if !ok {
return fmt.Errorf("not a TCP connection")
}
if err := tcpConn.SetKeepAlive(true); err != nil {
return err
}
return nil
}
type TCPServerInterface struct {
BaseInterface
connections map[string]net.Conn
@@ -575,7 +615,31 @@ func (ts *TCPServerInterface) Start() error {
ts.mutex.Lock()
defer ts.mutex.Unlock()
addr := fmt.Sprintf("%s:%d", ts.bindAddr, ts.bindPort)
listener, err := net.Listen("tcp", addr)
if err != nil {
return fmt.Errorf("failed to start TCP server: %w", err)
}
ts.Online = true
// Accept connections in a goroutine
go func() {
for {
conn, err := listener.Accept()
if err != nil {
if !ts.Online {
return // Normal shutdown
}
log.Printf("[DEBUG-2] Error accepting connection: %v", err)
continue
}
// Handle each connection in a separate goroutine
go ts.handleConnection(conn)
}
}()
return nil
}
@@ -598,3 +662,62 @@ func (ts *TCPServerInterface) GetRxBytes() uint64 {
defer ts.mutex.RUnlock()
return ts.RxBytes
}
func (ts *TCPServerInterface) handleConnection(conn net.Conn) {
addr := conn.RemoteAddr().String()
ts.mutex.Lock()
ts.connections[addr] = conn
ts.mutex.Unlock()
defer func() {
ts.mutex.Lock()
delete(ts.connections, addr)
ts.mutex.Unlock()
conn.Close()
}()
buffer := make([]byte, ts.MTU)
for {
n, err := conn.Read(buffer)
if err != nil {
return
}
ts.mutex.Lock()
ts.RxBytes += uint64(n)
ts.mutex.Unlock()
if ts.packetCallback != nil {
ts.packetCallback(buffer[:n], ts)
}
}
}
func (ts *TCPServerInterface) ProcessOutgoing(data []byte) error {
ts.mutex.RLock()
defer ts.mutex.RUnlock()
if !ts.Online {
return fmt.Errorf("interface offline")
}
var frame []byte
if ts.kissFraming {
frame = append([]byte{KISS_FEND}, escapeKISS(data)...)
frame = append(frame, KISS_FEND)
} else {
frame = append([]byte{HDLC_FLAG}, escapeHDLC(data)...)
frame = append(frame, HDLC_FLAG)
}
ts.TxBytes += uint64(len(frame))
for _, conn := range ts.connections {
if _, err := conn.Write(frame); err != nil {
log.Printf("[DEBUG-4] Error writing to connection %s: %v",
conn.RemoteAddr(), err)
}
}
return nil
}