refactor: format code and add more constants
Some checks failed
Go Build Multi-Platform / build (amd64, darwin) (push) Failing after 12s
Go Build Multi-Platform / build (amd64, freebsd) (push) Successful in 51s
Go Build Multi-Platform / build (amd64, linux) (push) Successful in 49s
Go Build Multi-Platform / build (arm, freebsd) (push) Successful in 49s
Go Build Multi-Platform / build (amd64, windows) (push) Successful in 57s
Go Build Multi-Platform / build (arm, windows) (push) Failing after 19s
Go Build Multi-Platform / build (arm, linux) (push) Failing after 21s
Go Build Multi-Platform / build (arm64, darwin) (push) Successful in 44s
Go Build Multi-Platform / build (arm64, freebsd) (push) Successful in 48s
Go Build Multi-Platform / build (arm64, linux) (push) Successful in 47s
Go Build Multi-Platform / build (arm64, windows) (push) Successful in 46s
Run Gosec / tests (push) Successful in 45s
Go Build Multi-Platform / Create Release (push) Has been skipped
Go Revive Lint / lint (push) Successful in 9m48s
Go Test Multi-Platform / Test (ubuntu-latest, arm64) (push) Successful in 19m13s
Go Test Multi-Platform / Test (ubuntu-latest, amd64) (push) Successful in 19m19s

This commit is contained in:
2025-12-28 22:27:16 -06:00
parent fda77ba10d
commit a34c211872
23 changed files with 394 additions and 360 deletions

View File

@@ -13,13 +13,13 @@ import (
) )
type Manager struct { type Manager struct {
basePath string basePath string
ratchetsPath string ratchetsPath string
identitiesPath string identitiesPath string
destinationTable string destinationTable string
knownDestinations string knownDestinations string
transportIdentity string transportIdentity string
mutex sync.RWMutex mutex sync.RWMutex
} }
type RatchetData struct { type RatchetData struct {
@@ -34,14 +34,14 @@ func NewManager() (*Manager, error) {
} }
basePath := filepath.Join(homeDir, ".reticulum-go", "storage") basePath := filepath.Join(homeDir, ".reticulum-go", "storage")
m := &Manager{ m := &Manager{
basePath: basePath, basePath: basePath,
ratchetsPath: filepath.Join(basePath, "ratchets"), ratchetsPath: filepath.Join(basePath, "ratchets"),
identitiesPath: filepath.Join(basePath, "identities"), identitiesPath: filepath.Join(basePath, "identities"),
destinationTable: filepath.Join(basePath, "destination_table"), destinationTable: filepath.Join(basePath, "destination_table"),
knownDestinations: filepath.Join(basePath, "known_destinations"), knownDestinations: filepath.Join(basePath, "known_destinations"),
transportIdentity: filepath.Join(basePath, "transport_identity"), transportIdentity: filepath.Join(basePath, "transport_identity"),
} }
if err := m.initializeDirectories(); err != nil { if err := m.initializeDirectories(); err != nil {
@@ -76,7 +76,7 @@ func (m *Manager) SaveRatchet(identityHash []byte, ratchetKey []byte) error {
hexHash := hex.EncodeToString(identityHash) hexHash := hex.EncodeToString(identityHash)
ratchetDir := filepath.Join(m.ratchetsPath, hexHash) ratchetDir := filepath.Join(m.ratchetsPath, hexHash)
if err := os.MkdirAll(ratchetDir, 0700); err != nil { if err := os.MkdirAll(ratchetDir, 0700); err != nil {
return fmt.Errorf("failed to create ratchet directory: %w", err) return fmt.Errorf("failed to create ratchet directory: %w", err)
} }
@@ -186,4 +186,3 @@ func (m *Manager) GetDestinationTablePath() string {
func (m *Manager) GetKnownDestinationsPath() string { func (m *Manager) GetKnownDestinationsPath() string {
return m.knownDestinations return m.knownDestinations
} }

View File

@@ -87,17 +87,17 @@ func New(dest *identity.Identity, destinationHash []byte, destinationName string
} }
a := &Announce{ a := &Announce{
mutex: &sync.RWMutex{}, mutex: &sync.RWMutex{},
identity: dest, identity: dest,
destinationHash: destinationHash, destinationHash: destinationHash,
destinationName: destinationName, destinationName: destinationName,
appData: appData, appData: appData,
config: config, config: config,
hops: 0, hops: 0,
timestamp: time.Now().Unix(), timestamp: time.Now().Unix(),
pathResponse: pathResponse, pathResponse: pathResponse,
retries: 0, retries: 0,
handlers: make([]AnnounceHandler, 0), handlers: make([]AnnounceHandler, 0),
} }
// Get current ratchet ID if enabled // Get current ratchet ID if enabled
@@ -365,7 +365,7 @@ func (a *Announce) CreatePacket() []byte {
copy(ratchetData, ratchetPub) copy(ratchetData, ratchetPub)
} }
} }
// Determine context flag based on whether ratchet exists // Determine context flag based on whether ratchet exists
contextFlag := byte(0) contextFlag := byte(0)
if len(ratchetData) > 0 { if len(ratchetData) > 0 {

View File

@@ -114,7 +114,7 @@ func (r *RawChannelReader) Read(p []byte) (n int, err error) {
} }
func (r *RawChannelReader) HandleMessage(msg channel.MessageBase) bool { // #nosec G115 func (r *RawChannelReader) HandleMessage(msg channel.MessageBase) bool { // #nosec G115
if streamMsg, ok := msg.(*StreamDataMessage); ok && streamMsg.StreamID == uint16(r.streamID) { if streamMsg, ok := msg.(*StreamDataMessage); ok && streamMsg.StreamID == uint16(r.streamID) {
r.mutex.Lock() r.mutex.Lock()
defer r.mutex.Unlock() defer r.mutex.Unlock()

View File

@@ -226,7 +226,7 @@ func (c *Channel) HandleInbound(data []byte) error {
msgType := uint16(data[0])<<8 | uint16(data[1]) msgType := uint16(data[0])<<8 | uint16(data[1])
sequence := uint16(data[2])<<8 | uint16(data[3]) sequence := uint16(data[2])<<8 | uint16(data[3])
length := uint16(data[4])<<8 | uint16(data[5]) length := uint16(data[4])<<8 | uint16(data[5])
if len(data) < 6+int(length) { if len(data) < 6+int(length) {
return errors.New("channel packet incomplete") return errors.New("channel packet incomplete")
} }
@@ -239,9 +239,9 @@ func (c *Channel) HandleInbound(data []byte) error {
for _, handler := range c.messageHandlers { for _, handler := range c.messageHandlers {
if handler != nil { if handler != nil {
msg := &GenericMessage{ msg := &GenericMessage{
Type: msgType, Type: msgType,
Data: msgData, Data: msgData,
Seq: sequence, Seq: sequence,
} }
if handler(msg) { if handler(msg) {
break break

View File

@@ -58,4 +58,40 @@ const (
STALE_TIME = 720 STALE_TIME = 720
PATH_REQUEST_TTL = 300 PATH_REQUEST_TTL = 300
ANNOUNCE_TIMEOUT = 15 ANNOUNCE_TIMEOUT = 15
// Common Numeric Constants
ZERO = 0
ONE = 1
TWO = 2
THREE = 3
FOUR = 4
FIVE = 5
SIX = 6
SEVEN = 7
EIGHT = 8
FIFTEEN = 15
// Common Size Constants
SIZE_16 = 16
SIZE_32 = 32
SIZE_64 = 64
SIXTY_SEVEN = 67
// Common Hex Constants
HEX_0x03 = 0x03
HEX_0xFF = 0xFF
// Common Float Constants
FLOAT_ZERO = 0.0
FLOAT_0_001 = 0.001
FLOAT_0_025 = 0.025
FLOAT_0_1 = 0.1
FLOAT_1_75 = 1.75
FLOAT_5_0 = 5.0
FLOAT_1E9 = 1e9
// Common String Constants
STR_LINK_ID = "link_id"
STR_BYTES = "bytes"
STR_FMT_HEX = "0x%02x"
) )

View File

@@ -86,7 +86,6 @@ func TestAES256CBC_InvalidKeySize(t *testing.T) {
} }
} }
func TestDecryptAES256CBCErrorCases(t *testing.T) { func TestDecryptAES256CBCErrorCases(t *testing.T) {
key, err := GenerateAES256Key() key, err := GenerateAES256Key()
if err != nil { if err != nil {

View File

@@ -18,8 +18,8 @@ const (
) )
var ( var (
debugLevel = flag.Int("debug", 3, "debug level (1-7)") debugLevel = flag.Int("debug", 3, "debug level (1-7)")
logger *slog.Logger logger *slog.Logger
initialized bool initialized bool
) )
@@ -113,4 +113,3 @@ func SetDebugLevel(level int) {
func GetDebugLevel() int { func GetDebugLevel() int {
return *debugLevel return *debugLevel
} }

View File

@@ -240,7 +240,7 @@ func (i *Identity) String() string {
func Recall(hash []byte) (*Identity, error) { func Recall(hash []byte) (*Identity, error) {
hashStr := hex.EncodeToString(hash) hashStr := hex.EncodeToString(hash)
if data, exists := knownDestinations[hashStr]; exists { if data, exists := knownDestinations[hashStr]; exists {
// data is [packet, destHash, identity, appData] // data is [packet, destHash, identity, appData]
if len(data) >= 3 { if len(data) >= 3 {
@@ -249,7 +249,7 @@ func Recall(hash []byte) (*Identity, error) {
} }
} }
} }
return nil, fmt.Errorf("identity not found for hash %x", hash) return nil, fmt.Errorf("identity not found for hash %x", hash)
} }
@@ -523,7 +523,7 @@ func FromFile(path string) (*Identity, error) {
ratchetExpiry: make(map[string]int64), ratchetExpiry: make(map[string]int64),
mutex: &sync.RWMutex{}, mutex: &sync.RWMutex{},
} }
if err := ident.loadPrivateKey(privateKey, signingSeed); err != nil { if err := ident.loadPrivateKey(privateKey, signingSeed); err != nil {
return nil, fmt.Errorf("failed to load private key: %w", err) return nil, fmt.Errorf("failed to load private key: %w", err)
} }
@@ -547,7 +547,7 @@ func LoadOrCreateTransportIdentity() (*Identity, error) {
} }
transportIdentityPath := fmt.Sprintf("%s/transport_identity", storagePath) transportIdentityPath := fmt.Sprintf("%s/transport_identity", storagePath)
if ident, err := FromFile(transportIdentityPath); err == nil { if ident, err := FromFile(transportIdentityPath); err == nil {
debug.Log(debug.DEBUG_INFO, "Loaded transport identity from storage") debug.Log(debug.DEBUG_INFO, "Loaded transport identity from storage")
return ident, nil return ident, nil
@@ -610,7 +610,7 @@ func (i *Identity) saveRatchets(path string) error {
} }
debug.Log(debug.DEBUG_PACKETS, "Saving ratchets", "count", len(i.ratchets), "path", path) debug.Log(debug.DEBUG_PACKETS, "Saving ratchets", "count", len(i.ratchets), "path", path)
// Convert ratchets to list format for msgpack // Convert ratchets to list format for msgpack
ratchetList := make([][]byte, 0, len(i.ratchets)) ratchetList := make([][]byte, 0, len(i.ratchets))
for _, ratchet := range i.ratchets { for _, ratchet := range i.ratchets {
@@ -750,7 +750,7 @@ func (i *Identity) loadRatchets(path string) error {
signature, hasSignature := persistedData["signature"] signature, hasSignature := persistedData["signature"]
packedRatchets, hasRatchets := persistedData["ratchets"] packedRatchets, hasRatchets := persistedData["ratchets"]
if !hasSignature || !hasRatchets { if !hasSignature || !hasRatchets {
return fmt.Errorf("invalid ratchet file format: missing signature or ratchets") return fmt.Errorf("invalid ratchet file format: missing signature or ratchets")
} }

View File

@@ -23,42 +23,42 @@ const (
ANNOUNCE_INTERVAL = 1600 * time.Millisecond ANNOUNCE_INTERVAL = 1600 * time.Millisecond
PEER_JOB_INTERVAL = 4 * time.Second PEER_JOB_INTERVAL = 4 * time.Second
MCAST_ECHO_TIMEOUT = 6500 * time.Millisecond MCAST_ECHO_TIMEOUT = 6500 * time.Millisecond
SCOPE_LINK = "2" SCOPE_LINK = "2"
SCOPE_ADMIN = "4" SCOPE_ADMIN = "4"
SCOPE_SITE = "5" SCOPE_SITE = "5"
SCOPE_ORGANISATION = "8" SCOPE_ORGANISATION = "8"
SCOPE_GLOBAL = "e" SCOPE_GLOBAL = "e"
MCAST_ADDR_TYPE_PERMANENT = "0" MCAST_ADDR_TYPE_PERMANENT = "0"
MCAST_ADDR_TYPE_TEMPORARY = "1" MCAST_ADDR_TYPE_TEMPORARY = "1"
) )
type AutoInterface struct { type AutoInterface struct {
BaseInterface BaseInterface
groupID []byte groupID []byte
groupHash []byte groupHash []byte
discoveryPort int discoveryPort int
dataPort int dataPort int
discoveryScope string discoveryScope string
multicastAddrType string multicastAddrType string
mcastDiscoveryAddr string mcastDiscoveryAddr string
ifacNetname string ifacNetname string
peers map[string]*Peer peers map[string]*Peer
linkLocalAddrs []string linkLocalAddrs []string
adoptedInterfaces map[string]*AdoptedInterface adoptedInterfaces map[string]*AdoptedInterface
interfaceServers map[string]*net.UDPConn interfaceServers map[string]*net.UDPConn
discoveryServers map[string]*net.UDPConn discoveryServers map[string]*net.UDPConn
multicastEchoes map[string]time.Time multicastEchoes map[string]time.Time
timedOutInterfaces map[string]time.Time timedOutInterfaces map[string]time.Time
allowedInterfaces []string allowedInterfaces []string
ignoredInterfaces []string ignoredInterfaces []string
mutex sync.RWMutex mutex sync.RWMutex
outboundConn *net.UDPConn outboundConn *net.UDPConn
announceInterval time.Duration announceInterval time.Duration
peerJobInterval time.Duration peerJobInterval time.Duration
peeringTimeout time.Duration peeringTimeout time.Duration
mcastEchoTimeout time.Duration mcastEchoTimeout time.Duration
} }
type AdoptedInterface struct { type AdoptedInterface struct {
@@ -97,7 +97,7 @@ func NewAutoInterface(name string, config *common.InterfaceConfig) (*AutoInterfa
} }
groupHash := sha256.Sum256([]byte(groupID)) groupHash := sha256.Sum256([]byte(groupID))
ifacNetname := hex.EncodeToString(groupHash[:])[:16] ifacNetname := hex.EncodeToString(groupHash[:])[:16]
mcastAddr := fmt.Sprintf("ff%s%s::%s", discoveryScope, multicastAddrType, ifacNetname) mcastAddr := fmt.Sprintf("ff%s%s::%s", discoveryScope, multicastAddrType, ifacNetname)
@@ -114,27 +114,27 @@ func NewAutoInterface(name string, config *common.InterfaceConfig) (*AutoInterfa
MTU: HW_MTU, MTU: HW_MTU,
Bitrate: BITRATE_GUESS, Bitrate: BITRATE_GUESS,
}, },
groupID: []byte(groupID), groupID: []byte(groupID),
groupHash: groupHash[:], groupHash: groupHash[:],
discoveryPort: discoveryPort, discoveryPort: discoveryPort,
dataPort: dataPort, dataPort: dataPort,
discoveryScope: discoveryScope, discoveryScope: discoveryScope,
multicastAddrType: multicastAddrType, multicastAddrType: multicastAddrType,
mcastDiscoveryAddr: mcastAddr, mcastDiscoveryAddr: mcastAddr,
ifacNetname: ifacNetname, ifacNetname: ifacNetname,
peers: make(map[string]*Peer), peers: make(map[string]*Peer),
linkLocalAddrs: make([]string, 0), linkLocalAddrs: make([]string, 0),
adoptedInterfaces: make(map[string]*AdoptedInterface), adoptedInterfaces: make(map[string]*AdoptedInterface),
interfaceServers: make(map[string]*net.UDPConn), interfaceServers: make(map[string]*net.UDPConn),
discoveryServers: make(map[string]*net.UDPConn), discoveryServers: make(map[string]*net.UDPConn),
multicastEchoes: make(map[string]time.Time), multicastEchoes: make(map[string]time.Time),
timedOutInterfaces: make(map[string]time.Time), timedOutInterfaces: make(map[string]time.Time),
allowedInterfaces: make([]string, 0), allowedInterfaces: make([]string, 0),
ignoredInterfaces: make([]string, 0), ignoredInterfaces: make([]string, 0),
announceInterval: ANNOUNCE_INTERVAL, announceInterval: ANNOUNCE_INTERVAL,
peerJobInterval: PEER_JOB_INTERVAL, peerJobInterval: PEER_JOB_INTERVAL,
peeringTimeout: PEERING_TIMEOUT, peeringTimeout: PEERING_TIMEOUT,
mcastEchoTimeout: MCAST_ECHO_TIMEOUT, mcastEchoTimeout: MCAST_ECHO_TIMEOUT,
} }
debug.Log(debug.DEBUG_INFO, "AutoInterface configured", "name", name, "group", groupID, "mcast_addr", mcastAddr) debug.Log(debug.DEBUG_INFO, "AutoInterface configured", "name", name, "group", groupID, "mcast_addr", mcastAddr)
@@ -202,26 +202,26 @@ func (ai *AutoInterface) Start() error {
go ai.peerJobs() go ai.peerJobs()
go ai.announceLoop() go ai.announceLoop()
debug.Log(debug.DEBUG_INFO, "AutoInterface started", "adopted", len(ai.adoptedInterfaces)) debug.Log(debug.DEBUG_INFO, "AutoInterface started", "adopted", len(ai.adoptedInterfaces))
return nil return nil
} }
func (ai *AutoInterface) shouldIgnoreInterface(name string) bool { func (ai *AutoInterface) shouldIgnoreInterface(name string) bool {
ignoreList := []string{"lo", "lo0", "tun0", "awdl0", "llw0", "en5", "dummy0"} ignoreList := []string{"lo", "lo0", "tun0", "awdl0", "llw0", "en5", "dummy0"}
for _, ignored := range ai.ignoredInterfaces { for _, ignored := range ai.ignoredInterfaces {
if name == ignored { if name == ignored {
return true return true
} }
} }
for _, ignored := range ignoreList { for _, ignored := range ignoreList {
if name == ignored { if name == ignored {
return true return true
} }
} }
return false return false
} }
@@ -394,7 +394,7 @@ func (ai *AutoInterface) handlePeerAnnounce(addr *net.UDPAddr, ifaceName string)
} }
peerKey := peerIP + "%" + ifaceName peerKey := peerIP + "%" + ifaceName
if peer, exists := ai.peers[peerKey]; exists { if peer, exists := ai.peers[peerKey]; exists {
peer.lastHeard = time.Now() peer.lastHeard = time.Now()
debug.Log(debug.DEBUG_TRACE, "Updated peer", "peer", peerIP, "interface", ifaceName) debug.Log(debug.DEBUG_TRACE, "Updated peer", "peer", peerIP, "interface", ifaceName)

View File

@@ -21,18 +21,18 @@ const (
KISS_TFEND = 0xDC KISS_TFEND = 0xDC
KISS_TFESC = 0xDD KISS_TFESC = 0xDD
DEFAULT_MTU = 1064 DEFAULT_MTU = 1064
BITRATE_GUESS_VAL = 10 * 1000 * 1000 BITRATE_GUESS_VAL = 10 * 1000 * 1000
RECONNECT_WAIT = 5 RECONNECT_WAIT = 5
INITIAL_TIMEOUT = 5 INITIAL_TIMEOUT = 5
INITIAL_BACKOFF = time.Second INITIAL_BACKOFF = time.Second
MAX_BACKOFF = time.Minute * 5 MAX_BACKOFF = time.Minute * 5
TCP_USER_TIMEOUT_SEC = 24 TCP_USER_TIMEOUT_SEC = 24
TCP_PROBE_AFTER_SEC = 5 TCP_PROBE_AFTER_SEC = 5
TCP_PROBE_INTERVAL_SEC = 2 TCP_PROBE_INTERVAL_SEC = 2
TCP_PROBES_COUNT = 12 TCP_PROBES_COUNT = 12
I2P_USER_TIMEOUT_SEC = 45 I2P_USER_TIMEOUT_SEC = 45
I2P_PROBE_AFTER_SEC = 10 I2P_PROBE_AFTER_SEC = 10
I2P_PROBE_INTERVAL_SEC = 9 I2P_PROBE_INTERVAL_SEC = 9
@@ -201,7 +201,7 @@ func (tc *TCPClientInterface) handlePacket(data []byte) {
// Send implements the interface Send method for TCP interface // Send implements the interface Send method for TCP interface
func (tc *TCPClientInterface) Send(data []byte, address string) error { func (tc *TCPClientInterface) Send(data []byte, address string) error {
debug.Log(debug.DEBUG_ALL, "TCP interface sending bytes", "name", tc.Name, "bytes", len(data)) debug.Log(debug.DEBUG_ALL, "TCP interface sending bytes", "name", tc.Name, "bytes", len(data))
if !tc.IsEnabled() || !tc.IsOnline() { if !tc.IsEnabled() || !tc.IsOnline() {
return fmt.Errorf("TCP interface %s is not online", tc.Name) return fmt.Errorf("TCP interface %s is not online", tc.Name)
} }
@@ -434,7 +434,6 @@ func (tc *TCPClientInterface) GetStats() (tx uint64, rx uint64, lastTx time.Time
return tc.TxBytes, tc.RxBytes, tc.lastTx, tc.lastRx return tc.TxBytes, tc.RxBytes, tc.lastTx, tc.lastRx
} }
type TCPServerInterface struct { type TCPServerInterface struct {
BaseInterface BaseInterface
connections map[string]net.Conn connections map[string]net.Conn

View File

@@ -1,3 +1,4 @@
//go:build darwin
// +build darwin // +build darwin
package interfaces package interfaces
@@ -28,19 +29,19 @@ func (tc *TCPClientInterface) setTimeoutsOSX() error {
var sockoptErr error var sockoptErr error
err = rawConn.Control(func(fd uintptr) { err = rawConn.Control(func(fd uintptr) {
const TCP_KEEPALIVE = 0x10 const TCP_KEEPALIVE = 0x10
var probeAfter int var probeAfter int
if tc.i2pTunneled { if tc.i2pTunneled {
probeAfter = I2P_PROBE_AFTER_SEC probeAfter = I2P_PROBE_AFTER_SEC
} else { } else {
probeAfter = TCP_PROBE_AFTER_SEC probeAfter = TCP_PROBE_AFTER_SEC
} }
if err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, 1); err != nil { if err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, 1); err != nil {
sockoptErr = fmt.Errorf("failed to enable SO_KEEPALIVE: %v", err) sockoptErr = fmt.Errorf("failed to enable SO_KEEPALIVE: %v", err)
return return
} }
if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, TCP_KEEPALIVE, probeAfter); err != nil { if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, TCP_KEEPALIVE, probeAfter); err != nil {
debug.Log(debug.DEBUG_VERBOSE, "Failed to set TCP_KEEPALIVE", "error", err) debug.Log(debug.DEBUG_VERBOSE, "Failed to set TCP_KEEPALIVE", "error", err)
} }
@@ -56,4 +57,3 @@ func (tc *TCPClientInterface) setTimeoutsOSX() error {
debug.Log(debug.DEBUG_VERBOSE, "TCP keepalive configured (OSX)", "i2p", tc.i2pTunneled) debug.Log(debug.DEBUG_VERBOSE, "TCP keepalive configured (OSX)", "i2p", tc.i2pTunneled)
return nil return nil
} }

View File

@@ -1,3 +1,4 @@
//go:build freebsd
// +build freebsd // +build freebsd
package interfaces package interfaces
@@ -24,7 +25,7 @@ func (tc *TCPClientInterface) setTimeoutsLinux() error {
if tc.i2pTunneled { if tc.i2pTunneled {
keepalivePeriod = I2P_PROBE_INTERVAL_SEC * time.Second keepalivePeriod = I2P_PROBE_INTERVAL_SEC * time.Second
} }
if err := tcpConn.SetKeepAlivePeriod(keepalivePeriod); err != nil { if err := tcpConn.SetKeepAlivePeriod(keepalivePeriod); err != nil {
debug.Log(debug.DEBUG_VERBOSE, "Failed to set keepalive period", "error", err) debug.Log(debug.DEBUG_VERBOSE, "Failed to set keepalive period", "error", err)
} }
@@ -36,4 +37,3 @@ func (tc *TCPClientInterface) setTimeoutsLinux() error {
func (tc *TCPClientInterface) setTimeoutsOSX() error { func (tc *TCPClientInterface) setTimeoutsOSX() error {
return tc.setTimeoutsLinux() return tc.setTimeoutsLinux()
} }

View File

@@ -1,3 +1,4 @@
//go:build linux
// +build linux // +build linux
package interfaces package interfaces
@@ -26,7 +27,7 @@ func (tc *TCPClientInterface) setTimeoutsLinux() error {
var sockoptErr error var sockoptErr error
err = rawConn.Control(func(fd uintptr) { err = rawConn.Control(func(fd uintptr) {
var userTimeout, probeAfter, probeInterval, probeCount int var userTimeout, probeAfter, probeInterval, probeCount int
if tc.i2pTunneled { if tc.i2pTunneled {
userTimeout = I2P_USER_TIMEOUT_SEC * 1000 userTimeout = I2P_USER_TIMEOUT_SEC * 1000
probeAfter = I2P_PROBE_AFTER_SEC probeAfter = I2P_PROBE_AFTER_SEC
@@ -42,20 +43,20 @@ func (tc *TCPClientInterface) setTimeoutsLinux() error {
if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, 18, userTimeout); err != nil { if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, 18, userTimeout); err != nil {
debug.Log(debug.DEBUG_VERBOSE, "Failed to set TCP_USER_TIMEOUT", "error", err) debug.Log(debug.DEBUG_VERBOSE, "Failed to set TCP_USER_TIMEOUT", "error", err)
} }
if err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, 1); err != nil { if err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, 1); err != nil {
sockoptErr = fmt.Errorf("failed to enable SO_KEEPALIVE: %v", err) sockoptErr = fmt.Errorf("failed to enable SO_KEEPALIVE: %v", err)
return return
} }
if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, 4, probeAfter); err != nil { if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, 4, probeAfter); err != nil {
debug.Log(debug.DEBUG_VERBOSE, "Failed to set TCP_KEEPIDLE", "error", err) debug.Log(debug.DEBUG_VERBOSE, "Failed to set TCP_KEEPIDLE", "error", err)
} }
if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, 5, probeInterval); err != nil { if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, 5, probeInterval); err != nil {
debug.Log(debug.DEBUG_VERBOSE, "Failed to set TCP_KEEPINTVL", "error", err) debug.Log(debug.DEBUG_VERBOSE, "Failed to set TCP_KEEPINTVL", "error", err)
} }
if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, 6, probeCount); err != nil { if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, 6, probeCount); err != nil {
debug.Log(debug.DEBUG_VERBOSE, "Failed to set TCP_KEEPCNT", "error", err) debug.Log(debug.DEBUG_VERBOSE, "Failed to set TCP_KEEPCNT", "error", err)
} }
@@ -79,7 +80,7 @@ func (tc *TCPClientInterface) setTimeoutsOSX() error {
func platformGetRTT(fd uintptr) time.Duration { func platformGetRTT(fd uintptr) time.Duration {
var info syscall.TCPInfo var info syscall.TCPInfo
infoLen := uint32(unsafe.Sizeof(info)) infoLen := uint32(unsafe.Sizeof(info))
// TCP_INFO is 11 on Linux // TCP_INFO is 11 on Linux
// #nosec G103 // #nosec G103
_, _, errno := syscall.Syscall6( _, _, errno := syscall.Syscall6(
@@ -91,10 +92,10 @@ func platformGetRTT(fd uintptr) time.Duration {
uintptr(unsafe.Pointer(&infoLen)), uintptr(unsafe.Pointer(&infoLen)),
0, 0,
) )
if errno != 0 { if errno != 0 {
return 0 return 0
} }
return time.Duration(info.Rtt) * time.Microsecond return time.Duration(info.Rtt) * time.Microsecond
} }

View File

@@ -1,3 +1,4 @@
//go:build netbsd
// +build netbsd // +build netbsd
package interfaces package interfaces
@@ -24,7 +25,7 @@ func (tc *TCPClientInterface) setTimeoutsLinux() error {
if tc.i2pTunneled { if tc.i2pTunneled {
keepalivePeriod = I2P_PROBE_INTERVAL_SEC * time.Second keepalivePeriod = I2P_PROBE_INTERVAL_SEC * time.Second
} }
if err := tcpConn.SetKeepAlivePeriod(keepalivePeriod); err != nil { if err := tcpConn.SetKeepAlivePeriod(keepalivePeriod); err != nil {
debug.Log(debug.DEBUG_VERBOSE, "Failed to set keepalive period", "error", err) debug.Log(debug.DEBUG_VERBOSE, "Failed to set keepalive period", "error", err)
} }
@@ -36,4 +37,3 @@ func (tc *TCPClientInterface) setTimeoutsLinux() error {
func (tc *TCPClientInterface) setTimeoutsOSX() error { func (tc *TCPClientInterface) setTimeoutsOSX() error {
return tc.setTimeoutsLinux() return tc.setTimeoutsLinux()
} }

View File

@@ -1,3 +1,4 @@
//go:build openbsd
// +build openbsd // +build openbsd
package interfaces package interfaces
@@ -24,7 +25,7 @@ func (tc *TCPClientInterface) setTimeoutsLinux() error {
if tc.i2pTunneled { if tc.i2pTunneled {
keepalivePeriod = I2P_PROBE_INTERVAL_SEC * time.Second keepalivePeriod = I2P_PROBE_INTERVAL_SEC * time.Second
} }
if err := tcpConn.SetKeepAlivePeriod(keepalivePeriod); err != nil { if err := tcpConn.SetKeepAlivePeriod(keepalivePeriod); err != nil {
debug.Log(debug.DEBUG_VERBOSE, "Failed to set keepalive period", "error", err) debug.Log(debug.DEBUG_VERBOSE, "Failed to set keepalive period", "error", err)
} }
@@ -36,4 +37,3 @@ func (tc *TCPClientInterface) setTimeoutsLinux() error {
func (tc *TCPClientInterface) setTimeoutsOSX() error { func (tc *TCPClientInterface) setTimeoutsOSX() error {
return tc.setTimeoutsLinux() return tc.setTimeoutsLinux()
} }

View File

@@ -30,7 +30,7 @@ func (tc *TCPClientInterface) setTimeoutsWindows() error {
if tc.i2pTunneled { if tc.i2pTunneled {
keepalivePeriod = I2P_PROBE_INTERVAL_SEC * time.Second keepalivePeriod = I2P_PROBE_INTERVAL_SEC * time.Second
} }
if err := tcpConn.SetKeepAlivePeriod(keepalivePeriod); err != nil { if err := tcpConn.SetKeepAlivePeriod(keepalivePeriod); err != nil {
debug.Log(debug.DEBUG_VERBOSE, "Failed to set keepalive period", "error", err) debug.Log(debug.DEBUG_VERBOSE, "Failed to set keepalive period", "error", err)
} }
@@ -38,5 +38,3 @@ func (tc *TCPClientInterface) setTimeoutsWindows() error {
debug.Log(debug.DEBUG_VERBOSE, "TCP keepalive configured (Windows)", "i2p", tc.i2pTunneled) debug.Log(debug.DEBUG_VERBOSE, "TCP keepalive configured (Windows)", "i2p", tc.i2pTunneled)
return nil return nil
} }

View File

@@ -38,7 +38,7 @@ func NewUDPInterface(name string, addr string, target string, enabled bool) (*UD
targetAddr: targetAddr, targetAddr: targetAddr,
readBuffer: make([]byte, 1064), readBuffer: make([]byte, 1064),
} }
ui.MTU = 1064 ui.MTU = 1064
return ui, nil return ui, nil
@@ -183,7 +183,7 @@ func (ui *UDPInterface) Start() error {
return err return err
} }
ui.conn = conn ui.conn = conn
// Enable broadcast mode if we have a target address // Enable broadcast mode if we have a target address
if ui.targetAddr != nil { if ui.targetAddr != nil {
// Get the raw connection file descriptor to set SO_BROADCAST // Get the raw connection file descriptor to set SO_BROADCAST
@@ -194,12 +194,12 @@ func (ui *UDPInterface) Start() error {
debug.Log(debug.DEBUG_ERROR, "Failed to set write buffer size", "error", err) debug.Log(debug.DEBUG_ERROR, "Failed to set write buffer size", "error", err)
} }
} }
ui.Online = true ui.Online = true
// Start the read loop in a goroutine // Start the read loop in a goroutine
go ui.readLoop() go ui.readLoop()
return nil return nil
} }
@@ -218,7 +218,7 @@ func (ui *UDPInterface) readLoop() {
ui.mutex.Lock() ui.mutex.Lock()
// #nosec G115 - Network read sizes are always positive and within safe range // #nosec G115 - Network read sizes are always positive and within safe range
ui.RxBytes += uint64(n) ui.RxBytes += uint64(n)
// Auto-discover target address from first packet if not set // Auto-discover target address from first packet if not set
if ui.targetAddr == nil { if ui.targetAddr == nil {
debug.Log(debug.DEBUG_ALL, "UDP interface discovered peer", "name", ui.Name, "peer", remoteAddr.String()) debug.Log(debug.DEBUG_ALL, "UDP interface discovered peer", "name", ui.Name, "peer", remoteAddr.String())

View File

@@ -13,23 +13,23 @@ import (
func TestEphemeralKeyGeneration(t *testing.T) { func TestEphemeralKeyGeneration(t *testing.T) {
link := &Link{} link := &Link{}
if err := link.generateEphemeralKeys(); err != nil { if err := link.generateEphemeralKeys(); err != nil {
t.Fatalf("Failed to generate ephemeral keys: %v", err) t.Fatalf("Failed to generate ephemeral keys: %v", err)
} }
if len(link.prv) != KEYSIZE { if len(link.prv) != KEYSIZE {
t.Errorf("Expected private key length %d, got %d", KEYSIZE, len(link.prv)) t.Errorf("Expected private key length %d, got %d", KEYSIZE, len(link.prv))
} }
if len(link.pub) != KEYSIZE { if len(link.pub) != KEYSIZE {
t.Errorf("Expected public key length %d, got %d", KEYSIZE, len(link.pub)) t.Errorf("Expected public key length %d, got %d", KEYSIZE, len(link.pub))
} }
if len(link.sigPriv) != 64 { if len(link.sigPriv) != 64 {
t.Errorf("Expected signing private key length 64, got %d", len(link.sigPriv)) t.Errorf("Expected signing private key length 64, got %d", len(link.sigPriv))
} }
if len(link.sigPub) != 32 { if len(link.sigPub) != 32 {
t.Errorf("Expected signing public key length 32, got %d", len(link.sigPub)) t.Errorf("Expected signing public key length 32, got %d", len(link.sigPub))
} }
@@ -38,18 +38,18 @@ func TestEphemeralKeyGeneration(t *testing.T) {
func TestSignallingBytes(t *testing.T) { func TestSignallingBytes(t *testing.T) {
mtu := 500 mtu := 500
mode := byte(MODE_AES256_CBC) mode := byte(MODE_AES256_CBC)
bytes := signallingBytes(mtu, mode) bytes := signallingBytes(mtu, mode)
if len(bytes) != LINK_MTU_SIZE { if len(bytes) != LINK_MTU_SIZE {
t.Errorf("Expected signalling bytes length %d, got %d", LINK_MTU_SIZE, len(bytes)) t.Errorf("Expected signalling bytes length %d, got %d", LINK_MTU_SIZE, len(bytes))
} }
extractedMTU := (int(bytes[0]&0x1F) << 16) | (int(bytes[1]) << 8) | int(bytes[2]) extractedMTU := (int(bytes[0]&0x1F) << 16) | (int(bytes[1]) << 8) | int(bytes[2])
if extractedMTU != mtu { if extractedMTU != mtu {
t.Errorf("Expected MTU %d, got %d", mtu, extractedMTU) t.Errorf("Expected MTU %d, got %d", mtu, extractedMTU)
} }
extractedMode := (bytes[0] & MODE_BYTEMASK) >> 5 extractedMode := (bytes[0] & MODE_BYTEMASK) >> 5
if extractedMode != mode { if extractedMode != mode {
t.Errorf("Expected mode %d, got %d", mode, extractedMode) t.Errorf("Expected mode %d, got %d", mode, extractedMode)
@@ -106,55 +106,55 @@ func TestLinkIDGeneration(t *testing.T) {
} }
linkID := linkIDFromPacket(pkt) linkID := linkIDFromPacket(pkt)
if len(linkID) != 16 { if len(linkID) != 16 {
t.Errorf("Expected link ID length 16, got %d", len(linkID)) t.Errorf("Expected link ID length 16, got %d", len(linkID))
} }
t.Logf("Generated link ID: %x", linkID) t.Logf("Generated link ID: %x", linkID)
} }
func TestHandshake(t *testing.T) { func TestHandshake(t *testing.T) {
link1 := &Link{} link1 := &Link{}
link2 := &Link{} link2 := &Link{}
if err := link1.generateEphemeralKeys(); err != nil { if err := link1.generateEphemeralKeys(); err != nil {
t.Fatalf("Failed to generate keys for link1: %v", err) t.Fatalf("Failed to generate keys for link1: %v", err)
} }
if err := link2.generateEphemeralKeys(); err != nil { if err := link2.generateEphemeralKeys(); err != nil {
t.Fatalf("Failed to generate keys for link2: %v", err) t.Fatalf("Failed to generate keys for link2: %v", err)
} }
link1.peerPub = link2.pub link1.peerPub = link2.pub
link2.peerPub = link1.pub link2.peerPub = link1.pub
link1.linkID = []byte("test-link-id-abc") link1.linkID = []byte("test-link-id-abc")
link2.linkID = []byte("test-link-id-abc") link2.linkID = []byte("test-link-id-abc")
link1.mode = MODE_AES256_CBC link1.mode = MODE_AES256_CBC
link2.mode = MODE_AES256_CBC link2.mode = MODE_AES256_CBC
if err := link1.performHandshake(); err != nil { if err := link1.performHandshake(); err != nil {
t.Fatalf("Link1 handshake failed: %v", err) t.Fatalf("Link1 handshake failed: %v", err)
} }
if err := link2.performHandshake(); err != nil { if err := link2.performHandshake(); err != nil {
t.Fatalf("Link2 handshake failed: %v", err) t.Fatalf("Link2 handshake failed: %v", err)
} }
if string(link1.sharedKey) != string(link2.sharedKey) { if string(link1.sharedKey) != string(link2.sharedKey) {
t.Error("Shared keys do not match") t.Error("Shared keys do not match")
} }
if string(link1.derivedKey) != string(link2.derivedKey) { if string(link1.derivedKey) != string(link2.derivedKey) {
t.Error("Derived keys do not match") t.Error("Derived keys do not match")
} }
if link1.status != STATUS_HANDSHAKE { if link1.status != STATUS_HANDSHAKE {
t.Errorf("Expected link1 status HANDSHAKE, got %d", link1.status) t.Errorf("Expected link1 status HANDSHAKE, got %d", link1.status)
} }
if link2.status != STATUS_HANDSHAKE { if link2.status != STATUS_HANDSHAKE {
t.Errorf("Expected link2 status HANDSHAKE, got %d", link2.status) t.Errorf("Expected link2 status HANDSHAKE, got %d", link2.status)
} }
@@ -224,9 +224,9 @@ func TestLinkEstablishment(t *testing.T) {
responderLink.peerSigPub = linkRequestPkt.Data[KEYSIZE:ECPUBSIZE] responderLink.peerSigPub = linkRequestPkt.Data[KEYSIZE:ECPUBSIZE]
responderLink.linkID = linkIDFromPacket(linkRequestPkt) responderLink.linkID = linkIDFromPacket(linkRequestPkt)
responderLink.initiator = false responderLink.initiator = false
t.Logf("Responder link ID=%x (len=%d)", responderLink.linkID, len(responderLink.linkID)) t.Logf("Responder link ID=%x (len=%d)", responderLink.linkID, len(responderLink.linkID))
if len(responderLink.linkID) == 0 { if len(responderLink.linkID) == 0 {
t.Fatal("Responder link ID is empty!") t.Fatal("Responder link ID is empty!")
} }
@@ -362,4 +362,3 @@ func TestLinkProofValidation(t *testing.T) {
t.Logf("Derived key length: %d", len(initiatorLink.derivedKey)) t.Logf("Derived key length: %d", len(initiatorLink.derivedKey))
t.Logf("RTT: %.3f seconds", initiatorLink.rtt) t.Logf("RTT: %.3f seconds", initiatorLink.rtt)
} }

View File

@@ -64,6 +64,11 @@ const (
WATCHDOG_MIN_SLEEP = 0.025 WATCHDOG_MIN_SLEEP = 0.025
WATCHDOG_INTERVAL = 0.1 WATCHDOG_INTERVAL = 0.1
DEST_TYPE_LINK = 0x03
MIN_REQUEST_DATA_LEN = 3
MIN_RESPONSE_DATA_LEN = 2
) )
func init() { func init() {
@@ -229,10 +234,10 @@ func (l *Link) Identify(id *identity.Identity) error {
p := &packet.Packet{ p := &packet.Packet{
HeaderType: packet.HeaderType1, HeaderType: packet.HeaderType1,
PacketType: packet.PacketTypeData, PacketType: packet.PacketTypeData,
TransportType: 0, TransportType: common.ZERO,
Context: packet.ContextLinkIdentify, Context: packet.ContextLinkIdentify,
ContextFlag: packet.FlagUnset, ContextFlag: packet.FlagUnset,
Hops: 0, Hops: common.ZERO,
DestinationType: l.destination.GetType(), DestinationType: l.destination.GetType(),
DestinationHash: l.destination.GetHash(), DestinationHash: l.destination.GetHash(),
Data: id.GetPublicKey(), Data: id.GetPublicKey(),
@@ -258,25 +263,25 @@ func (l *Link) HandleIdentification(data []byte) error {
pubKey := data[:ed25519.PublicKeySize] pubKey := data[:ed25519.PublicKeySize]
signature := data[ed25519.PublicKeySize:] signature := data[ed25519.PublicKeySize:]
debug.Log(debug.DEBUG_VERBOSE, "Processing identification from public key", "public_key", fmt.Sprintf("%x", pubKey[:8])) debug.Log(debug.DEBUG_VERBOSE, "Processing identification from public key", "public_key", fmt.Sprintf("%x", pubKey[:common.EIGHT]))
remoteIdentity := identity.FromPublicKey(pubKey) remoteIdentity := identity.FromPublicKey(pubKey)
if remoteIdentity == nil { if remoteIdentity == nil {
debug.Log(debug.DEBUG_INFO, "Invalid remote identity from public key", "public_key", fmt.Sprintf("%x", pubKey[:8])) debug.Log(debug.DEBUG_INFO, "Invalid remote identity from public key", "public_key", fmt.Sprintf("%x", pubKey[:common.EIGHT]))
return errors.New("invalid remote identity") return errors.New("invalid remote identity")
} }
signData := append(l.linkID, pubKey...) signData := append(l.linkID, pubKey...)
if !remoteIdentity.Verify(signData, signature) { if !remoteIdentity.Verify(signData, signature) {
debug.Log(debug.DEBUG_INFO, "Invalid signature from remote identity", "public_key", fmt.Sprintf("%x", pubKey[:8])) debug.Log(debug.DEBUG_INFO, "Invalid signature from remote identity", "public_key", fmt.Sprintf("%x", pubKey[:common.EIGHT]))
return errors.New("invalid signature") return errors.New("invalid signature")
} }
debug.Log(debug.DEBUG_VERBOSE, "Remote identity verified successfully", "public_key", fmt.Sprintf("%x", pubKey[:8])) debug.Log(debug.DEBUG_VERBOSE, "Remote identity verified successfully", "public_key", fmt.Sprintf("%x", pubKey[:common.EIGHT]))
l.remoteIdentity = remoteIdentity l.remoteIdentity = remoteIdentity
if l.identifiedCallback != nil { if l.identifiedCallback != nil {
debug.Log(debug.DEBUG_VERBOSE, "Executing identified callback for remote identity", "public_key", fmt.Sprintf("%x", pubKey[:8])) debug.Log(debug.DEBUG_VERBOSE, "Executing identified callback for remote identity", "public_key", fmt.Sprintf("%x", pubKey[:common.EIGHT]))
l.identifiedCallback(l, remoteIdentity) l.identifiedCallback(l, remoteIdentity)
} }
@@ -308,11 +313,11 @@ func (l *Link) Request(path string, data []byte, timeout time.Duration) (*Reques
reqPkt := &packet.Packet{ reqPkt := &packet.Packet{
HeaderType: packet.HeaderType1, HeaderType: packet.HeaderType1,
PacketType: packet.PacketTypeData, PacketType: packet.PacketTypeData,
TransportType: 0, TransportType: common.ZERO,
Context: packet.ContextRequest, Context: packet.ContextRequest,
ContextFlag: packet.FlagUnset, ContextFlag: packet.FlagUnset,
Hops: 0, Hops: common.ZERO,
DestinationType: 0x03, DestinationType: DEST_TYPE_LINK,
DestinationHash: l.linkID, DestinationHash: l.linkID,
Data: packedRequest, Data: packedRequest,
CreateReceipt: false, CreateReceipt: false,
@@ -395,7 +400,7 @@ func (r *RequestReceipt) GetResponseTime() float64 {
r.mutex.RLock() r.mutex.RLock()
defer r.mutex.RUnlock() defer r.mutex.RUnlock()
if r.receivedAt.IsZero() { if r.receivedAt.IsZero() {
return 0 return common.FLOAT_ZERO
} }
return r.receivedAt.Sub(r.sentAt).Seconds() return r.receivedAt.Sub(r.sentAt).Seconds()
} }
@@ -455,7 +460,7 @@ func (l *Link) GetRSSI() float64 {
l.mutex.RLock() l.mutex.RLock()
defer l.mutex.RUnlock() defer l.mutex.RUnlock()
if !l.trackPhyStats { if !l.trackPhyStats {
return 0 return common.FLOAT_ZERO
} }
return l.rssi return l.rssi
} }
@@ -464,7 +469,7 @@ func (l *Link) GetSNR() float64 {
l.mutex.RLock() l.mutex.RLock()
defer l.mutex.RUnlock() defer l.mutex.RUnlock()
if !l.trackPhyStats { if !l.trackPhyStats {
return 0 return common.FLOAT_ZERO
} }
return l.snr return l.snr
} }
@@ -473,7 +478,7 @@ func (l *Link) GetQ() float64 {
l.mutex.RLock() l.mutex.RLock()
defer l.mutex.RUnlock() defer l.mutex.RUnlock()
if !l.trackPhyStats { if !l.trackPhyStats {
return 0 return common.FLOAT_ZERO
} }
return l.q return l.q
} }
@@ -488,7 +493,7 @@ func (l *Link) GetAge() float64 {
l.mutex.RLock() l.mutex.RLock()
defer l.mutex.RUnlock() defer l.mutex.RUnlock()
if l.establishedAt.IsZero() { if l.establishedAt.IsZero() {
return 0 return common.FLOAT_ZERO
} }
return time.Since(l.establishedAt).Seconds() return time.Since(l.establishedAt).Seconds()
} }
@@ -497,7 +502,7 @@ func (l *Link) NoInboundFor() float64 {
l.mutex.RLock() l.mutex.RLock()
defer l.mutex.RUnlock() defer l.mutex.RUnlock()
if l.lastInbound.IsZero() { if l.lastInbound.IsZero() {
return 0 return common.FLOAT_ZERO
} }
return time.Since(l.lastInbound).Seconds() return time.Since(l.lastInbound).Seconds()
} }
@@ -506,7 +511,7 @@ func (l *Link) NoOutboundFor() float64 {
l.mutex.RLock() l.mutex.RLock()
defer l.mutex.RUnlock() defer l.mutex.RUnlock()
if l.lastOutbound.IsZero() { if l.lastOutbound.IsZero() {
return 0 return common.FLOAT_ZERO
} }
return time.Since(l.lastOutbound).Seconds() return time.Since(l.lastOutbound).Seconds()
} }
@@ -519,7 +524,7 @@ func (l *Link) NoDataFor() float64 {
lastData = l.lastDataSent lastData = l.lastDataSent
} }
if lastData.IsZero() { if lastData.IsZero() {
return 0 return common.FLOAT_ZERO
} }
return time.Since(lastData).Seconds() return time.Since(lastData).Seconds()
} }
@@ -532,7 +537,7 @@ func (l *Link) InactiveFor() float64 {
lastActivity = l.lastOutbound lastActivity = l.lastOutbound
} }
if lastActivity.IsZero() { if lastActivity.IsZero() {
return 0 return common.FLOAT_ZERO
} }
return time.Since(lastActivity).Seconds() return time.Since(lastActivity).Seconds()
} }
@@ -621,10 +626,10 @@ func (l *Link) SendPacket(data []byte) error {
p := &packet.Packet{ p := &packet.Packet{
HeaderType: packet.HeaderType1, HeaderType: packet.HeaderType1,
PacketType: packet.PacketTypeData, PacketType: packet.PacketTypeData,
TransportType: 0, TransportType: common.ZERO,
Context: packet.ContextNone, Context: packet.ContextNone,
ContextFlag: packet.FlagUnset, ContextFlag: packet.FlagUnset,
Hops: 0, Hops: common.ZERO,
DestinationType: l.destination.GetType(), DestinationType: l.destination.GetType(),
DestinationHash: l.destination.GetHash(), DestinationHash: l.destination.GetHash(),
Data: encrypted, Data: encrypted,
@@ -707,16 +712,16 @@ func (l *Link) handleDataPacket(pkt *packet.Packet) error {
case packet.ContextLinkIdentify: case packet.ContextLinkIdentify:
return l.HandleIdentification(plaintext) return l.HandleIdentification(plaintext)
case packet.ContextKeepalive: case packet.ContextKeepalive:
if !l.initiator && len(plaintext) == 1 && plaintext[0] == 0xFF { if !l.initiator && len(plaintext) == common.ONE && plaintext[common.ZERO] == common.HEX_0xFF {
keepaliveResp := []byte{0xFE} keepaliveResp := []byte{0xFE}
keepalivePkt := &packet.Packet{ keepalivePkt := &packet.Packet{
HeaderType: packet.HeaderType1, HeaderType: packet.HeaderType1,
PacketType: packet.PacketTypeData, PacketType: packet.PacketTypeData,
TransportType: 0, TransportType: common.ZERO,
Context: packet.ContextKeepalive, Context: packet.ContextKeepalive,
ContextFlag: packet.FlagUnset, ContextFlag: packet.FlagUnset,
Hops: 0, Hops: common.ZERO,
DestinationType: 0x03, DestinationType: DEST_TYPE_LINK,
DestinationHash: l.linkID, DestinationHash: l.linkID,
Data: keepaliveResp, Data: keepaliveResp,
CreateReceipt: false, CreateReceipt: false,
@@ -860,11 +865,11 @@ func (l *Link) rejectResource(resourceHash []byte) error {
rejectPkt := &packet.Packet{ rejectPkt := &packet.Packet{
HeaderType: packet.HeaderType1, HeaderType: packet.HeaderType1,
PacketType: packet.PacketTypeData, PacketType: packet.PacketTypeData,
TransportType: 0, TransportType: common.ZERO,
Context: packet.ContextResourceRCL, Context: packet.ContextResourceRCL,
ContextFlag: packet.FlagUnset, ContextFlag: packet.FlagUnset,
Hops: 0, Hops: common.ZERO,
DestinationType: 0x03, DestinationType: DEST_TYPE_LINK,
DestinationHash: l.linkID, DestinationHash: l.linkID,
Data: resourceHash, Data: resourceHash,
CreateReceipt: false, CreateReceipt: false,
@@ -904,7 +909,7 @@ func (l *Link) sendResourceAdvertisement(res *resource.Resource) error {
return errors.New("failed to create resource advertisement") return errors.New("failed to create resource advertisement")
} }
advData, err := adv.Pack(0) advData, err := adv.Pack(common.ZERO)
if err != nil { if err != nil {
return fmt.Errorf("failed to pack advertisement: %w", err) return fmt.Errorf("failed to pack advertisement: %w", err)
} }
@@ -917,11 +922,11 @@ func (l *Link) sendResourceAdvertisement(res *resource.Resource) error {
advPkt := &packet.Packet{ advPkt := &packet.Packet{
HeaderType: packet.HeaderType1, HeaderType: packet.HeaderType1,
PacketType: packet.PacketTypeData, PacketType: packet.PacketTypeData,
TransportType: 0, TransportType: common.ZERO,
Context: packet.ContextResourceAdv, Context: packet.ContextResourceAdv,
ContextFlag: packet.FlagUnset, ContextFlag: packet.FlagUnset,
Hops: 0, Hops: common.ZERO,
DestinationType: 0x03, DestinationType: DEST_TYPE_LINK,
DestinationHash: l.linkID, DestinationHash: l.linkID,
Data: encrypted, Data: encrypted,
CreateReceipt: false, CreateReceipt: false,
@@ -1005,13 +1010,13 @@ func (l *Link) handleRequest(plaintext []byte, pkt *packet.Packet) error {
return fmt.Errorf("failed to unpack request: %w", err) return fmt.Errorf("failed to unpack request: %w", err)
} }
if len(requestData) < 3 { if len(requestData) < MIN_REQUEST_DATA_LEN {
return errors.New("invalid request format") return errors.New("invalid request format")
} }
requestedAt := time.Unix(int64(requestData[0].(int64)), 0) requestedAt := time.Unix(int64(requestData[common.ZERO].(int64)), common.ZERO)
pathHash := requestData[1].([]byte) pathHash := requestData[common.ONE].([]byte)
requestPayload := requestData[2].([]byte) requestPayload := requestData[common.TWO].([]byte)
requestID := identity.TruncatedHash(plaintext) requestID := identity.TruncatedHash(plaintext)
@@ -1034,12 +1039,12 @@ func (l *Link) handleResponse(plaintext []byte) error {
return fmt.Errorf("failed to unpack response: %w", err) return fmt.Errorf("failed to unpack response: %w", err)
} }
if len(responseData) < 2 { if len(responseData) < MIN_RESPONSE_DATA_LEN {
return errors.New("invalid response format") return errors.New("invalid response format")
} }
requestID := responseData[0].([]byte) requestID := responseData[common.ZERO].([]byte)
responsePayload := responseData[1].([]byte) responsePayload := responseData[common.ONE].([]byte)
l.requestMutex.Lock() l.requestMutex.Lock()
for i, req := range l.pendingRequests { for i, req := range l.pendingRequests {
@@ -1079,11 +1084,11 @@ func (l *Link) sendResponse(requestID []byte, response interface{}) error {
respPkt := &packet.Packet{ respPkt := &packet.Packet{
HeaderType: packet.HeaderType1, HeaderType: packet.HeaderType1,
PacketType: packet.PacketTypeData, PacketType: packet.PacketTypeData,
TransportType: 0, TransportType: common.ZERO,
Context: packet.ContextResponse, Context: packet.ContextResponse,
ContextFlag: packet.FlagUnset, ContextFlag: packet.FlagUnset,
Hops: 0, Hops: common.ZERO,
DestinationType: 0x03, DestinationType: DEST_TYPE_LINK,
DestinationHash: l.linkID, DestinationHash: l.linkID,
Data: encrypted, Data: encrypted,
CreateReceipt: false, CreateReceipt: false,
@@ -1110,8 +1115,8 @@ func (l *Link) handleRTTPacket(pkt *packet.Packet) error {
} }
var rtt float64 var rtt float64
if len(plaintext) >= 8 { if len(plaintext) >= common.EIGHT {
rtt = float64(binary.BigEndian.Uint64(plaintext[:8])) / 1e9 rtt = float64(binary.BigEndian.Uint64(plaintext[:common.EIGHT])) / common.FLOAT_1E9
} }
l.rtt = max(measuredRTT, rtt) l.rtt = max(measuredRTT, rtt)
@@ -1140,9 +1145,9 @@ func (l *Link) updateKeepalive() {
return return
} }
keepaliveMaxRTT := 1.75 keepaliveMaxRTT := common.FLOAT_1_75
keepaliveMax := float64(KEEPALIVE) keepaliveMax := float64(KEEPALIVE)
keepaliveMin := 5.0 keepaliveMin := common.FLOAT_5_0
calculatedKeepalive := l.rtt * (keepaliveMax / keepaliveMaxRTT) calculatedKeepalive := l.rtt * (keepaliveMax / keepaliveMaxRTT)
if calculatedKeepalive > keepaliveMax { if calculatedKeepalive > keepaliveMax {
@@ -1153,7 +1158,7 @@ func (l *Link) updateKeepalive() {
} }
l.keepalive = time.Duration(calculatedKeepalive * float64(time.Second)) l.keepalive = time.Duration(calculatedKeepalive * float64(time.Second))
l.staleTime = time.Duration(float64(l.keepalive) * 2.0) l.staleTime = time.Duration(float64(l.keepalive) * float64(common.TWO))
} }
func (l *Link) handleLinkProof(pkt *packet.Packet) error { func (l *Link) handleLinkProof(pkt *packet.Packet) error {
@@ -1284,11 +1289,11 @@ func (l *Link) Send(data []byte) interface{} {
pkt := &packet.Packet{ pkt := &packet.Packet{
HeaderType: packet.HeaderType1, HeaderType: packet.HeaderType1,
PacketType: packet.PacketTypeData, PacketType: packet.PacketTypeData,
TransportType: 0, TransportType: common.ZERO,
Context: packet.ContextChannel, Context: packet.ContextChannel,
ContextFlag: packet.FlagUnset, ContextFlag: packet.FlagUnset,
Hops: 0, Hops: common.ZERO,
DestinationType: 0x03, DestinationType: DEST_TYPE_LINK,
DestinationHash: l.linkID, DestinationHash: l.linkID,
Data: data, Data: data,
CreateReceipt: false, CreateReceipt: false,
@@ -1464,33 +1469,33 @@ func (l *Link) decodePacket(data []byte) {
} }
packetType := data[0] packetType := data[0]
debug.Log(debug.DEBUG_ALL, "Packet Analysis", "size", len(data), "type", fmt.Sprintf("0x%02x", packetType)) debug.Log(debug.DEBUG_ALL, "Packet Analysis", "size", len(data), "type", fmt.Sprintf(common.STR_FMT_HEX, packetType))
switch packetType { switch packetType {
case packet.PacketTypeData: case packet.PacketTypeData:
debug.Log(debug.DEBUG_ALL, "Type Description: Data Packet", "payload_size", len(data)-1) debug.Log(debug.DEBUG_ALL, "Type Description: Data Packet", "payload_size", len(data)-common.ONE)
case packet.PacketTypeLinkReq: case packet.PacketTypeLinkReq:
debug.Log(debug.DEBUG_ALL, "Type Description: Link Management", "link_id", fmt.Sprintf("%x", data[1:33])) debug.Log(debug.DEBUG_ALL, "Type Description: Link Management", common.STR_LINK_ID, fmt.Sprintf("%x", data[common.ONE:common.SIZE_32+common.ONE]))
case packet.PacketTypeAnnounce: case packet.PacketTypeAnnounce:
debug.Log(debug.DEBUG_ALL, "Received announce packet", "bytes", len(data)) debug.Log(debug.DEBUG_ALL, "Received announce packet", common.STR_BYTES, len(data))
if len(data) < packet.MinAnnounceSize { if len(data) < packet.MinAnnounceSize {
debug.Log(debug.DEBUG_INFO, "Announce packet too short", "bytes", len(data)) debug.Log(debug.DEBUG_INFO, "Announce packet too short", "bytes", len(data))
return return
} }
destHash := data[2:18] destHash := data[common.TWO : common.SIZE_16+common.TWO]
encKey := data[18:50] encKey := data[common.SIZE_16+common.TWO : common.SIZE_32+common.SIZE_16+common.TWO]
signKey := data[50:82] signKey := data[common.SIZE_32+common.SIZE_16+common.TWO : common.SIZE_32*common.TWO+common.SIZE_16+common.TWO]
nameHash := data[82:92] nameHash := data[common.SIZE_32*common.TWO+common.SIZE_16+common.TWO : common.SIZE_32*common.TWO+common.SIZE_16+common.TWO+common.EIGHT+common.TWO]
randomHash := data[92:102] randomHash := data[common.SIZE_32*common.TWO+common.SIZE_16+common.TWO+common.EIGHT+common.TWO : common.SIZE_32*common.TWO+common.SIZE_16+common.TWO+common.EIGHT*common.TWO+common.TWO]
signature := data[102:166] signature := data[common.SIZE_32*common.TWO+common.SIZE_16+common.TWO+common.EIGHT*common.TWO+common.TWO : common.SIZE_64+common.SIZE_32*common.TWO+common.SIZE_16+common.TWO+common.EIGHT*common.TWO+common.TWO]
appData := data[166:] appData := data[common.SIZE_64+common.SIZE_32*common.TWO+common.SIZE_16+common.TWO+common.EIGHT*common.TWO+common.TWO:]
pubKey := append(encKey, signKey...) pubKey := append(encKey, signKey...)
validationData := make([]byte, 0, 164) validationData := make([]byte, common.ZERO, common.SIZE_32*common.FIVE+common.FOUR)
validationData = append(validationData, destHash...) validationData = append(validationData, destHash...)
validationData = append(validationData, encKey...) validationData = append(validationData, encKey...)
validationData = append(validationData, signKey...) validationData = append(validationData, signKey...)
@@ -1498,18 +1503,18 @@ func (l *Link) decodePacket(data []byte) {
validationData = append(validationData, randomHash...) validationData = append(validationData, randomHash...)
if identity.ValidateAnnounce(validationData, destHash, pubKey, signature, appData) { if identity.ValidateAnnounce(validationData, destHash, pubKey, signature, appData) {
debug.Log(debug.DEBUG_VERBOSE, "Valid announce from", "public_key", fmt.Sprintf("%x", pubKey[:8])) debug.Log(debug.DEBUG_VERBOSE, "Valid announce from", "public_key", fmt.Sprintf("%x", pubKey[:common.EIGHT]))
if err := l.transport.HandleAnnounce(destHash, l.networkInterface); err != nil { if err := l.transport.HandleAnnounce(destHash, l.networkInterface); err != nil {
debug.Log(debug.DEBUG_INFO, "Failed to handle announce", "error", err) debug.Log(debug.DEBUG_INFO, "Failed to handle announce", "error", err)
} }
} else { } else {
debug.Log(debug.DEBUG_INFO, "Invalid announce signature from", "public_key", fmt.Sprintf("%x", pubKey[:8])) debug.Log(debug.DEBUG_INFO, "Invalid announce signature from", "public_key", fmt.Sprintf("%x", pubKey[:common.EIGHT]))
} }
case packet.PacketTypeProof: case packet.PacketTypeProof:
debug.Log(debug.DEBUG_ALL, "Type Description: RNS Discovery") debug.Log(debug.DEBUG_ALL, "Type Description: RNS Discovery")
if len(data) > 17 { if len(data) > common.SIZE_16+common.ONE {
searchHash := data[1:17] searchHash := data[common.ONE : common.SIZE_16+common.ONE]
debug.Log(debug.DEBUG_ALL, "Searching for Hash", "search_hash", fmt.Sprintf("%x", searchHash)) debug.Log(debug.DEBUG_ALL, "Searching for Hash", "search_hash", fmt.Sprintf("%x", searchHash))
if id, err := resolver.ResolveIdentity(hex.EncodeToString(searchHash)); err == nil { if id, err := resolver.ResolveIdentity(hex.EncodeToString(searchHash)); err == nil {
@@ -1535,12 +1540,12 @@ func (l *Link) watchdog() {
for l.status != STATUS_CLOSED { for l.status != STATUS_CLOSED {
l.mutex.Lock() l.mutex.Lock()
if l.watchdogLock { if l.watchdogLock {
rttWait := 0.025 rttWait := common.FLOAT_0_025
if l.rtt > 0 { if l.rtt > common.FLOAT_ZERO {
rttWait = l.rtt rttWait = l.rtt
} }
if rttWait < 0.025 { if rttWait < common.FLOAT_0_025 {
rttWait = 0.025 rttWait = common.FLOAT_0_025
} }
l.mutex.Unlock() l.mutex.Unlock()
time.Sleep(time.Duration(rttWait * float64(time.Second))) time.Sleep(time.Duration(rttWait * float64(time.Second)))
@@ -1559,7 +1564,7 @@ func (l *Link) watchdog() {
if l.closedCallback != nil { if l.closedCallback != nil {
l.closedCallback(l) l.closedCallback(l)
} }
sleepTime = 0.001 sleepTime = common.FLOAT_0_001
} }
} else if l.status == STATUS_HANDSHAKE { } else if l.status == STATUS_HANDSHAKE {
nextCheck := l.requestTime.Add(l.establishmentTimeout) nextCheck := l.requestTime.Add(l.establishmentTimeout)
@@ -1607,20 +1612,21 @@ func (l *Link) watchdog() {
sleepTime = time.Until(nextKeepalive).Seconds() sleepTime = time.Until(nextKeepalive).Seconds()
} }
} else if l.status == STATUS_STALE { } else if l.status == STATUS_STALE {
sleepTime = 0.001 sleepTime = common.FLOAT_0_001
_ = l.sendTeardownPacket() // #nosec G104 - best effort teardown _ = l.sendTeardownPacket() // #nosec G104 - best effort teardown
l.status = STATUS_CLOSED l.status = STATUS_CLOSED
l.teardownReason = STATUS_FAILED l.teardownReason = STATUS_FAILED
if l.closedCallback != nil { if l.closedCallback != nil {
l.closedCallback(l) l.closedCallback(l)
} }
sleepTime = common.FLOAT_0_001
} }
if sleepTime <= 0 { if sleepTime <= common.FLOAT_ZERO {
sleepTime = 0.1 sleepTime = common.FLOAT_0_1
} }
if sleepTime > 5.0 { if sleepTime > common.FLOAT_5_0 {
sleepTime = 5.0 sleepTime = common.FLOAT_5_0
} }
l.mutex.Unlock() l.mutex.Unlock()
@@ -1634,11 +1640,11 @@ func (l *Link) sendKeepalive() error {
keepalivePkt := &packet.Packet{ keepalivePkt := &packet.Packet{
HeaderType: packet.HeaderType1, HeaderType: packet.HeaderType1,
PacketType: packet.PacketTypeData, PacketType: packet.PacketTypeData,
TransportType: 0, TransportType: common.ZERO,
Context: packet.ContextKeepalive, Context: packet.ContextKeepalive,
ContextFlag: packet.FlagUnset, ContextFlag: packet.FlagUnset,
Hops: 0, Hops: common.ZERO,
DestinationType: 0x03, DestinationType: DEST_TYPE_LINK,
DestinationHash: l.linkID, DestinationHash: l.linkID,
Data: keepaliveData, Data: keepaliveData,
CreateReceipt: false, CreateReceipt: false,
@@ -1659,11 +1665,11 @@ func (l *Link) sendTeardownPacket() error {
teardownPkt := &packet.Packet{ teardownPkt := &packet.Packet{
HeaderType: packet.HeaderType1, HeaderType: packet.HeaderType1,
PacketType: packet.PacketTypeData, PacketType: packet.PacketTypeData,
TransportType: 0, TransportType: common.ZERO,
Context: packet.ContextLinkClose, Context: packet.ContextLinkClose,
ContextFlag: packet.FlagUnset, ContextFlag: packet.FlagUnset,
Hops: 0, Hops: common.ZERO,
DestinationType: 0x03, DestinationType: DEST_TYPE_LINK,
DestinationHash: l.linkID, DestinationHash: l.linkID,
Data: l.linkID, Data: l.linkID,
CreateReceipt: false, CreateReceipt: false,
@@ -1711,10 +1717,10 @@ func (l *Link) generateEphemeralKeys() error {
func signallingBytes(mtu int, mode byte) []byte { func signallingBytes(mtu int, mode byte) []byte {
bytes := make([]byte, LINK_MTU_SIZE) bytes := make([]byte, LINK_MTU_SIZE)
bytes[0] = byte((mtu >> 16) & 0xFF) bytes[common.ZERO] = byte((mtu >> common.SIZE_16) & common.HEX_0xFF)
bytes[1] = byte((mtu >> 8) & 0xFF) bytes[common.ONE] = byte((mtu >> common.EIGHT) & common.HEX_0xFF)
bytes[2] = byte(mtu & 0xFF) bytes[common.TWO] = byte(mtu & common.HEX_0xFF)
bytes[0] |= (mode << 5) bytes[common.ZERO] |= (mode << common.FIVE)
return bytes return bytes
} }
@@ -1724,7 +1730,7 @@ func (l *Link) SendLinkRequest() error {
} }
l.mode = MODE_DEFAULT l.mode = MODE_DEFAULT
l.mtu = 500 l.mtu = common.DEFAULT_MTU / common.THREE
l.updateMDU() l.updateMDU()
signalling := signallingBytes(l.mtu, l.mode) signalling := signallingBytes(l.mtu, l.mode)
@@ -1736,10 +1742,10 @@ func (l *Link) SendLinkRequest() error {
pkt := &packet.Packet{ pkt := &packet.Packet{
HeaderType: packet.HeaderType1, HeaderType: packet.HeaderType1,
PacketType: packet.PacketTypeLinkReq, PacketType: packet.PacketTypeLinkReq,
TransportType: 0, TransportType: common.ZERO,
Context: packet.ContextNone, Context: packet.ContextNone,
ContextFlag: packet.FlagUnset, ContextFlag: packet.FlagUnset,
Hops: 0, Hops: common.ZERO,
DestinationType: l.destination.GetType(), DestinationType: l.destination.GetType(),
DestinationHash: l.destination.GetHash(), DestinationHash: l.destination.GetHash(),
Data: requestData, Data: requestData,
@@ -1764,18 +1770,18 @@ func (l *Link) SendLinkRequest() error {
} }
func linkIDFromPacket(pkt *packet.Packet) []byte { func linkIDFromPacket(pkt *packet.Packet) []byte {
hashablePart := make([]byte, 0, 1+16+1+ECPUBSIZE) hashablePart := make([]byte, common.ZERO, common.ONE+common.SIZE_16+common.ONE+ECPUBSIZE)
hashablePart = append(hashablePart, pkt.Raw[0]) hashablePart = append(hashablePart, pkt.Raw[common.ZERO])
if pkt.HeaderType == packet.HeaderType2 { if pkt.HeaderType == packet.HeaderType2 {
startIndex := 18 startIndex := common.SIZE_16 + common.TWO
endIndex := startIndex + 16 + 1 + ECPUBSIZE endIndex := startIndex + common.SIZE_16 + common.ONE + ECPUBSIZE
if len(pkt.Raw) >= endIndex { if len(pkt.Raw) >= endIndex {
hashablePart = append(hashablePart, pkt.Raw[startIndex:endIndex]...) hashablePart = append(hashablePart, pkt.Raw[startIndex:endIndex]...)
} }
} else { } else {
startIndex := 2 startIndex := common.TWO
endIndex := startIndex + 16 + 1 + ECPUBSIZE endIndex := startIndex + common.SIZE_16 + common.ONE + ECPUBSIZE
if len(pkt.Raw) >= endIndex { if len(pkt.Raw) >= endIndex {
hashablePart = append(hashablePart, pkt.Raw[startIndex:endIndex]...) hashablePart = append(hashablePart, pkt.Raw[startIndex:endIndex]...)
} }
@@ -1788,7 +1794,7 @@ func (l *Link) HandleLinkRequest(pkt *packet.Packet, ownerIdentity *identity.Ide
return errors.New("link request data too short") return errors.New("link request data too short")
} }
peerPub := pkt.Data[0:KEYSIZE] peerPub := pkt.Data[common.ZERO:KEYSIZE]
peerSigPub := pkt.Data[KEYSIZE:ECPUBSIZE] peerSigPub := pkt.Data[KEYSIZE:ECPUBSIZE]
l.peerPub = peerPub l.peerPub = peerPub
@@ -1802,7 +1808,7 @@ func (l *Link) HandleLinkRequest(pkt *packet.Packet, ownerIdentity *identity.Ide
l.mode = (mtuBytes[0] & MODE_BYTEMASK) >> 5 l.mode = (mtuBytes[0] & MODE_BYTEMASK) >> 5
debug.Log(debug.DEBUG_VERBOSE, "Link request includes MTU", "mtu", l.mtu, "mode", l.mode) debug.Log(debug.DEBUG_VERBOSE, "Link request includes MTU", "mtu", l.mtu, "mode", l.mode)
} else { } else {
l.mtu = 500 l.mtu = common.DEFAULT_MTU / common.THREE
l.mode = MODE_DEFAULT l.mode = MODE_DEFAULT
} }
@@ -1834,14 +1840,14 @@ func (l *Link) HandleLinkRequest(pkt *packet.Packet, ownerIdentity *identity.Ide
} }
func (l *Link) updateMDU() { func (l *Link) updateMDU() {
headerMaxSize := 64 headerMaxSize := common.SIZE_64
ifacMinSize := 4 ifacMinSize := common.FOUR
tokenOverhead := 16 tokenOverhead := common.SIZE_16
aesBlockSize := 16 aesBlockSize := common.SIZE_16
l.mdu = int(float64(l.mtu-headerMaxSize-ifacMinSize-tokenOverhead)/float64(aesBlockSize))*aesBlockSize - 1 l.mdu = int(float64(l.mtu-headerMaxSize-ifacMinSize-tokenOverhead)/float64(aesBlockSize))*aesBlockSize - common.ONE
if l.mdu < 0 { if l.mdu < common.ZERO {
l.mdu = 100 l.mdu = common.DEFAULT_MTU / common.FIFTEEN
} }
} }
@@ -1891,7 +1897,7 @@ func (l *Link) sendLinkProof(ownerIdentity *identity.Identity) error {
return err return err
} }
debug.Log(debug.DEBUG_ERROR, "Link proof packet created", "dest_hash", fmt.Sprintf("%x", proofPkt.DestinationHash), "packet_type", fmt.Sprintf("0x%02x", proofPkt.PacketType)) debug.Log(debug.DEBUG_ERROR, "Link proof packet created", "dest_hash", fmt.Sprintf("%x", proofPkt.DestinationHash), "packet_type", fmt.Sprintf(common.STR_FMT_HEX, proofPkt.PacketType))
// For responder links (not initiator), send proof directly through the receiving interface // For responder links (not initiator), send proof directly through the receiving interface
if !l.initiator && l.networkInterface != nil { if !l.initiator && l.networkInterface != nil {
@@ -1940,11 +1946,11 @@ func (l *Link) GenerateLinkProof(ownerIdentity *identity.Identity) (*packet.Pack
proofPkt := &packet.Packet{ proofPkt := &packet.Packet{
HeaderType: packet.HeaderType1, HeaderType: packet.HeaderType1,
PacketType: packet.PacketTypeProof, PacketType: packet.PacketTypeProof,
TransportType: 0, TransportType: common.ZERO,
Context: packet.ContextLRProof, Context: packet.ContextLRProof,
ContextFlag: packet.FlagUnset, ContextFlag: packet.FlagUnset,
Hops: 0, Hops: common.ZERO,
DestinationType: 0x03, DestinationType: DEST_TYPE_LINK,
DestinationHash: l.linkID, DestinationHash: l.linkID,
Data: proofData, Data: proofData,
CreateReceipt: false, CreateReceipt: false,
@@ -1967,14 +1973,14 @@ func (l *Link) ValidateLinkProof(pkt *packet.Packet) error {
return errors.New("link proof data too short") return errors.New("link proof data too short")
} }
signature := pkt.Data[0 : identity.SIGLENGTH/8] signature := pkt.Data[common.ZERO : identity.SIGLENGTH/common.EIGHT]
peerPub := pkt.Data[identity.SIGLENGTH/8 : identity.SIGLENGTH/8+KEYSIZE] peerPub := pkt.Data[identity.SIGLENGTH/common.EIGHT : identity.SIGLENGTH/common.EIGHT+KEYSIZE]
signalling := []byte{0, 0, 0} signalling := []byte{common.ZERO, common.ZERO, common.ZERO}
if len(pkt.Data) >= identity.SIGLENGTH/8+KEYSIZE+LINK_MTU_SIZE { if len(pkt.Data) >= identity.SIGLENGTH/8+KEYSIZE+LINK_MTU_SIZE {
signalling = pkt.Data[identity.SIGLENGTH/8+KEYSIZE : identity.SIGLENGTH/8+KEYSIZE+LINK_MTU_SIZE] signalling = pkt.Data[identity.SIGLENGTH/8+KEYSIZE : identity.SIGLENGTH/8+KEYSIZE+LINK_MTU_SIZE]
mtu := (int(signalling[0]&0x1F) << 16) | (int(signalling[1]) << 8) | int(signalling[2]) mtu := (int(signalling[common.ZERO]&0x1F) << common.SIZE_16) | (int(signalling[common.ONE]) << common.EIGHT) | int(signalling[common.TWO])
mode := (signalling[0] & MODE_BYTEMASK) >> 5 mode := (signalling[common.ZERO] & MODE_BYTEMASK) >> common.FIVE
l.mtu = mtu l.mtu = mtu
l.mode = mode l.mode = mode
debug.Log(debug.DEBUG_VERBOSE, "Link proof includes MTU", "mtu", mtu, "mode", mode) debug.Log(debug.DEBUG_VERBOSE, "Link proof includes MTU", "mtu", mtu, "mode", mode)
@@ -2018,15 +2024,15 @@ func (l *Link) ValidateLinkProof(pkt *packet.Packet) error {
} }
rttData := make([]byte, 8) rttData := make([]byte, 8)
binary.BigEndian.PutUint64(rttData, uint64(l.rtt*1e9)) binary.BigEndian.PutUint64(rttData, uint64(l.rtt*common.FLOAT_1E9))
rttPkt := &packet.Packet{ rttPkt := &packet.Packet{
HeaderType: packet.HeaderType1, HeaderType: packet.HeaderType1,
PacketType: packet.PacketTypeData, PacketType: packet.PacketTypeData,
TransportType: 0, TransportType: common.ZERO,
Context: packet.ContextLRRTT, Context: packet.ContextLRRTT,
ContextFlag: packet.FlagUnset, ContextFlag: packet.FlagUnset,
Hops: 0, Hops: common.ZERO,
DestinationType: 0x03, DestinationType: DEST_TYPE_LINK,
DestinationHash: l.linkID, DestinationHash: l.linkID,
Data: rttData, Data: rttData,
CreateReceipt: false, CreateReceipt: false,

View File

@@ -87,7 +87,7 @@ type Packet struct {
Addresses []byte Addresses []byte
Link interface{} Link interface{}
receipt *PacketReceipt receipt *PacketReceipt
} }
@@ -143,7 +143,7 @@ func (p *Packet) Pack() error {
debug.Log(debug.DEBUG_TRACE, "Created packet header", "flags", fmt.Sprintf("%08b", flags), "hops", p.Hops) debug.Log(debug.DEBUG_TRACE, "Created packet header", "flags", fmt.Sprintf("%08b", flags), "hops", p.Hops)
header = append(header, p.DestinationHash...) header = append(header, p.DestinationHash...)
if p.HeaderType == HeaderType2 { if p.HeaderType == HeaderType2 {
if p.TransportID == nil { if p.TransportID == nil {
return errors.New("transport ID required for header type 2") return errors.New("transport ID required for header type 2")
@@ -189,8 +189,8 @@ func (p *Packet) Unpack() error {
if len(p.Raw) < 2*dstLen+3 { if len(p.Raw) < 2*dstLen+3 {
return errors.New("packet too short for header type 2") return errors.New("packet too short for header type 2")
} }
p.DestinationHash = p.Raw[2 : dstLen+2] // Destination hash first p.DestinationHash = p.Raw[2 : dstLen+2] // Destination hash first
p.TransportID = p.Raw[dstLen+2 : 2*dstLen+2] // Transport ID second p.TransportID = p.Raw[dstLen+2 : 2*dstLen+2] // Transport ID second
p.Context = p.Raw[2*dstLen+2] p.Context = p.Raw[2*dstLen+2]
p.Data = p.Raw[2*dstLen+3:] p.Data = p.Raw[2*dstLen+3:]
} else { } else {

View File

@@ -32,14 +32,14 @@ type PacketReceipt struct {
timeout time.Duration timeout time.Duration
concludedAt time.Time concludedAt time.Time
proofPacket *Packet proofPacket *Packet
deliveryCallback func(*PacketReceipt) deliveryCallback func(*PacketReceipt)
timeoutCallback func(*PacketReceipt) timeoutCallback func(*PacketReceipt)
link interface{} link interface{}
destinationHash []byte destinationHash []byte
destinationIdent *identity.Identity destinationIdent *identity.Identity
timeoutCheckDone chan bool timeoutCheckDone chan bool
} }
func NewPacketReceipt(pkt *Packet) *PacketReceipt { func NewPacketReceipt(pkt *Packet) *PacketReceipt {
@@ -57,18 +57,18 @@ func NewPacketReceipt(pkt *Packet) *PacketReceipt {
} }
go receipt.timeoutWatchdog() go receipt.timeoutWatchdog()
debug.Log(debug.DEBUG_PACKETS, "Created packet receipt", "hash", fmt.Sprintf("%x", receipt.truncatedHash)) debug.Log(debug.DEBUG_PACKETS, "Created packet receipt", "hash", fmt.Sprintf("%x", receipt.truncatedHash))
return receipt return receipt
} }
func calculateTimeout(pkt *Packet) time.Duration { func calculateTimeout(pkt *Packet) time.Duration {
baseTimeout := 15 * time.Second baseTimeout := 15 * time.Second
if pkt.Hops > 0 { if pkt.Hops > 0 {
baseTimeout += time.Duration(pkt.Hops) * (3 * time.Second) baseTimeout += time.Duration(pkt.Hops) * (3 * time.Second)
} }
return baseTimeout return baseTimeout
} }
@@ -107,11 +107,11 @@ func (pr *PacketReceipt) ValidateLinkProof(proof []byte, link interface{}, proof
if len(proof) == EXPL_LENGTH { if len(proof) == EXPL_LENGTH {
proofHash := proof[:identity.HASHLENGTH/8] proofHash := proof[:identity.HASHLENGTH/8]
signature := proof[identity.HASHLENGTH/8 : identity.HASHLENGTH/8+identity.SIGLENGTH/8] signature := proof[identity.HASHLENGTH/8 : identity.HASHLENGTH/8+identity.SIGLENGTH/8]
pr.mutex.RLock() pr.mutex.RLock()
hashMatch := string(proofHash) == string(pr.hash) hashMatch := string(proofHash) == string(pr.hash)
pr.mutex.RUnlock() pr.mutex.RUnlock()
if !hashMatch { if !hashMatch {
return false return false
} }
@@ -136,7 +136,7 @@ func (pr *PacketReceipt) ValidateLinkProof(proof []byte, link interface{}, proof
} else if len(proof) == IMPL_LENGTH { } else if len(proof) == IMPL_LENGTH {
debug.Log(debug.DEBUG_TRACE, "Implicit link proof not yet implemented") debug.Log(debug.DEBUG_TRACE, "Implicit link proof not yet implemented")
} }
return false return false
} }
@@ -144,14 +144,14 @@ func (pr *PacketReceipt) ValidateProof(proof []byte, proofPacket *Packet) bool {
if len(proof) == EXPL_LENGTH { if len(proof) == EXPL_LENGTH {
proofHash := proof[:identity.HASHLENGTH/8] proofHash := proof[:identity.HASHLENGTH/8]
signature := proof[identity.HASHLENGTH/8 : identity.HASHLENGTH/8+identity.SIGLENGTH/8] signature := proof[identity.HASHLENGTH/8 : identity.HASHLENGTH/8+identity.SIGLENGTH/8]
pr.mutex.RLock() pr.mutex.RLock()
hashMatch := string(proofHash) == string(pr.hash) hashMatch := string(proofHash) == string(pr.hash)
ident := pr.destinationIdent ident := pr.destinationIdent
pr.mutex.RUnlock() pr.mutex.RUnlock()
debug.Log(debug.DEBUG_PACKETS, "Explicit proof validation", "len", len(proof), "hashMatch", hashMatch, "hasIdent", ident != nil) debug.Log(debug.DEBUG_PACKETS, "Explicit proof validation", "len", len(proof), "hashMatch", hashMatch, "hasIdent", ident != nil)
if !hashMatch { if !hashMatch {
debug.Log(debug.DEBUG_PACKETS, "Proof hash mismatch") debug.Log(debug.DEBUG_PACKETS, "Proof hash mismatch")
return false return false
@@ -182,7 +182,7 @@ func (pr *PacketReceipt) ValidateProof(proof []byte, proofPacket *Packet) bool {
} }
} else if len(proof) == IMPL_LENGTH { } else if len(proof) == IMPL_LENGTH {
signature := proof[:identity.SIGLENGTH/8] signature := proof[:identity.SIGLENGTH/8]
pr.mutex.RLock() pr.mutex.RLock()
ident := pr.destinationIdent ident := pr.destinationIdent
pr.mutex.RUnlock() pr.mutex.RUnlock()
@@ -209,7 +209,7 @@ func (pr *PacketReceipt) ValidateProof(proof []byte, proofPacket *Packet) bool {
return true return true
} }
} }
return false return false
} }
@@ -217,11 +217,11 @@ func (pr *PacketReceipt) validateLinkSignature(signature []byte, link interface{
type linkValidator interface { type linkValidator interface {
Validate(signature, message []byte) bool Validate(signature, message []byte) bool
} }
if validator, ok := link.(linkValidator); ok { if validator, ok := link.(linkValidator); ok {
return validator.Validate(signature, pr.hash) return validator.Validate(signature, pr.hash)
} }
debug.Log(debug.DEBUG_TRACE, "Link does not implement Validate method") debug.Log(debug.DEBUG_TRACE, "Link does not implement Validate method")
return false return false
} }
@@ -229,46 +229,46 @@ func (pr *PacketReceipt) validateLinkSignature(signature []byte, link interface{
func (pr *PacketReceipt) GetRTT() time.Duration { func (pr *PacketReceipt) GetRTT() time.Duration {
pr.mutex.RLock() pr.mutex.RLock()
defer pr.mutex.RUnlock() defer pr.mutex.RUnlock()
if pr.concludedAt.IsZero() { if pr.concludedAt.IsZero() {
return 0 return 0
} }
return pr.concludedAt.Sub(pr.sentAt) return pr.concludedAt.Sub(pr.sentAt)
} }
func (pr *PacketReceipt) IsTimedOut() bool { func (pr *PacketReceipt) IsTimedOut() bool {
pr.mutex.RLock() pr.mutex.RLock()
defer pr.mutex.RUnlock() defer pr.mutex.RUnlock()
return time.Since(pr.sentAt) > pr.timeout return time.Since(pr.sentAt) > pr.timeout
} }
func (pr *PacketReceipt) checkTimeout() { func (pr *PacketReceipt) checkTimeout() {
pr.mutex.Lock() pr.mutex.Lock()
if pr.status != RECEIPT_SENT { if pr.status != RECEIPT_SENT {
pr.mutex.Unlock() pr.mutex.Unlock()
return return
} }
if !pr.IsTimedOut() { if !pr.IsTimedOut() {
pr.mutex.Unlock() pr.mutex.Unlock()
return return
} }
if pr.timeout < 0 { if pr.timeout < 0 {
pr.status = RECEIPT_CULLED pr.status = RECEIPT_CULLED
} else { } else {
pr.status = RECEIPT_FAILED pr.status = RECEIPT_FAILED
} }
pr.concludedAt = time.Now() pr.concludedAt = time.Now()
callback := pr.timeoutCallback callback := pr.timeoutCallback
pr.mutex.Unlock() pr.mutex.Unlock()
debug.Log(debug.DEBUG_VERBOSE, "Packet receipt timed out", "hash", fmt.Sprintf("%x", pr.truncatedHash)) debug.Log(debug.DEBUG_VERBOSE, "Packet receipt timed out", "hash", fmt.Sprintf("%x", pr.truncatedHash))
if callback != nil { if callback != nil {
go callback(pr) go callback(pr)
} }
@@ -282,11 +282,11 @@ func (pr *PacketReceipt) timeoutWatchdog() {
select { select {
case <-ticker.C: case <-ticker.C:
pr.checkTimeout() pr.checkTimeout()
pr.mutex.RLock() pr.mutex.RLock()
status := pr.status status := pr.status
pr.mutex.RUnlock() pr.mutex.RUnlock()
if status != RECEIPT_SENT { if status != RECEIPT_SENT {
return return
} }
@@ -329,15 +329,14 @@ func (pr *PacketReceipt) SetLink(link interface{}) {
func (pr *PacketReceipt) Cancel() { func (pr *PacketReceipt) Cancel() {
pr.mutex.Lock() pr.mutex.Lock()
defer pr.mutex.Unlock() defer pr.mutex.Unlock()
if pr.status == RECEIPT_SENT { if pr.status == RECEIPT_SENT {
pr.status = RECEIPT_CULLED pr.status = RECEIPT_CULLED
pr.concludedAt = time.Now() pr.concludedAt = time.Now()
} }
select { select {
case pr.timeoutCheckDone <- true: case pr.timeoutCheckDone <- true:
default: default:
} }
} }

View File

@@ -115,13 +115,13 @@ func TestPacketReceiptProofValidation(t *testing.T) {
packetHash := pkt.GetHash() packetHash := pkt.GetHash()
t.Logf("Packet hash: %x", packetHash) t.Logf("Packet hash: %x", packetHash)
signature := testIdent.Sign(packetHash) signature := testIdent.Sign(packetHash)
t.Logf("PacketHash length: %d", len(packetHash)) t.Logf("PacketHash length: %d", len(packetHash))
t.Logf("Signature length: %d", len(signature)) t.Logf("Signature length: %d", len(signature))
t.Logf("EXPL_LENGTH constant: %d", EXPL_LENGTH) t.Logf("EXPL_LENGTH constant: %d", EXPL_LENGTH)
if testIdent.Verify(packetHash, signature) { if testIdent.Verify(packetHash, signature) {
t.Log("Direct verification succeeded") t.Log("Direct verification succeeded")
} else { } else {
@@ -207,4 +207,3 @@ func TestPacketReceiptCallbacks(t *testing.T) {
t.Error("Delivery callback was not called") t.Error("Delivery callback was not called")
} }
} }

View File

@@ -162,13 +162,13 @@ func NewTransport(cfg *common.ReticulumConfig) *Transport {
interfaces: make(map[string]common.NetworkInterface), interfaces: make(map[string]common.NetworkInterface),
paths: make(map[string]*common.Path), paths: make(map[string]*common.Path),
seenAnnounces: make(map[string]bool), seenAnnounces: make(map[string]bool),
announceRate: rate.NewLimiter(PROPAGATION_RATE, 1), announceRate: rate.NewLimiter(PROPAGATION_RATE, common.ONE),
mutex: sync.RWMutex{}, mutex: sync.RWMutex{},
config: cfg, config: cfg,
links: make(map[string]LinkInterface), links: make(map[string]LinkInterface),
destinations: make(map[string]interface{}), destinations: make(map[string]interface{}),
pathfinder: pathfinder.NewPathFinder(), pathfinder: pathfinder.NewPathFinder(),
receipts: make([]*packet.PacketReceipt, 0), receipts: make([]*packet.PacketReceipt, common.ZERO),
receiptsMutex: sync.RWMutex{}, receiptsMutex: sync.RWMutex{},
pathRequests: make(map[string]time.Time), pathRequests: make(map[string]time.Time),
pathStates: make(map[string]byte), pathStates: make(map[string]byte),
@@ -189,7 +189,7 @@ func NewTransport(cfg *common.ReticulumConfig) *Transport {
} }
func (t *Transport) startMaintenanceJobs() { func (t *Transport) startMaintenanceJobs() {
ticker := time.NewTicker(5 * time.Second) ticker := time.NewTicker(common.FIVE * time.Second)
defer ticker.Stop() defer ticker.Stop()
for range ticker.C { for range ticker.C {
@@ -211,7 +211,7 @@ func (t *Transport) cleanupExpiredPaths() {
if now.Sub(path.LastUpdated) > pathExpiry { if now.Sub(path.LastUpdated) > pathExpiry {
delete(t.paths, destHash) delete(t.paths, destHash)
delete(t.pathStates, destHash) delete(t.pathStates, destHash)
debug.Log(debug.DEBUG_VERBOSE, "Expired path", "dest_hash", fmt.Sprintf("%x", destHash[:8])) debug.Log(debug.DEBUG_VERBOSE, "Expired path", "dest_hash", fmt.Sprintf("%x", destHash[:common.EIGHT]))
} }
} }
} }
@@ -224,7 +224,7 @@ func (t *Transport) cleanupExpiredDiscoveryRequests() {
for destHash, req := range t.discoveryPathRequests { for destHash, req := range t.discoveryPathRequests {
if now.After(req.Timeout) { if now.After(req.Timeout) {
delete(t.discoveryPathRequests, destHash) delete(t.discoveryPathRequests, destHash)
debug.Log(debug.DEBUG_VERBOSE, "Expired discovery path request", "dest_hash", fmt.Sprintf("%x", destHash[:8])) debug.Log(debug.DEBUG_VERBOSE, "Expired discovery path request", "dest_hash", fmt.Sprintf("%x", destHash[:common.EIGHT]))
} }
} }
} }
@@ -238,7 +238,7 @@ func (t *Transport) cleanupExpiredAnnounces() {
for destHash, entry := range t.announceTable { for destHash, entry := range t.announceTable {
if entry != nil && time.Since(entry.CreatedAt) > announceExpiry { if entry != nil && time.Since(entry.CreatedAt) > announceExpiry {
delete(t.announceTable, destHash) delete(t.announceTable, destHash)
debug.Log(debug.DEBUG_VERBOSE, "Expired announce entry", "dest_hash", fmt.Sprintf("%x", destHash[:8])) debug.Log(debug.DEBUG_VERBOSE, "Expired announce entry", "dest_hash", fmt.Sprintf("%x", destHash[:common.EIGHT]))
} }
} }
@@ -253,7 +253,7 @@ func (t *Transport) cleanupExpiredReceipts() {
t.receiptsMutex.Lock() t.receiptsMutex.Lock()
defer t.receiptsMutex.Unlock() defer t.receiptsMutex.Unlock()
validReceipts := make([]*packet.PacketReceipt, 0) validReceipts := make([]*packet.PacketReceipt, common.ZERO)
for _, receipt := range t.receipts { for _, receipt := range t.receipts {
if receipt != nil && !receipt.IsTimedOut() { if receipt != nil && !receipt.IsTimedOut() {
status := receipt.GetStatus() status := receipt.GetStatus()
@@ -452,7 +452,7 @@ func (l *Link) Send(data []byte) interface{} {
Timestamp: time.Now(), Timestamp: time.Now(),
} }
if l.rtt == 0 { if l.rtt == common.FLOAT_ZERO {
l.rtt = l.InactiveFor() l.rtt = l.InactiveFor()
} }
@@ -594,9 +594,9 @@ func (t *Transport) HandleAnnounce(data []byte, sourceIface common.NetworkInterf
debug.Log(debug.DEBUG_ALL, "Transport handling announce", "bytes", len(data), "source", sourceIface.GetName()) debug.Log(debug.DEBUG_ALL, "Transport handling announce", "bytes", len(data), "source", sourceIface.GetName())
// Parse announce fields according to RNS spec // Parse announce fields according to RNS spec
destHash := data[1:33] destHash := data[common.ONE:common.SIZE_32+common.ONE]
identity := data[33:49] identity := data[common.SIZE_32+common.ONE:common.SIZE_16+common.SIZE_32+common.ONE]
appData := data[49:] appData := data[common.SIZE_16+common.SIZE_32+common.ONE:]
// Generate announce hash to check for duplicates // Generate announce hash to check for duplicates
announceHash := sha256.Sum256(data) announceHash := sha256.Sum256(data)
@@ -605,15 +605,15 @@ func (t *Transport) HandleAnnounce(data []byte, sourceIface common.NetworkInterf
t.mutex.Lock() t.mutex.Lock()
if _, seen := t.seenAnnounces[hashStr]; seen { if _, seen := t.seenAnnounces[hashStr]; seen {
t.mutex.Unlock() t.mutex.Unlock()
debug.Log(debug.DEBUG_ALL, "Ignoring duplicate announce", "hash", fmt.Sprintf("%x", announceHash[:8])) debug.Log(debug.DEBUG_ALL, "Ignoring duplicate announce", "hash", fmt.Sprintf("%x", announceHash[:common.EIGHT]))
return nil return nil
} }
t.seenAnnounces[hashStr] = true t.seenAnnounces[hashStr] = true
t.mutex.Unlock() t.mutex.Unlock()
// Don't forward if max hops reached // Don't forward if max hops reached
if data[0] >= MAX_HOPS { if data[common.ZERO] >= MAX_HOPS {
debug.Log(debug.DEBUG_ALL, "Announce exceeded max hops", "hops", data[0]) debug.Log(debug.DEBUG_ALL, "Announce exceeded max hops", "hops", data[common.ZERO])
return nil return nil
} }
@@ -798,23 +798,23 @@ func SendAnnounce(packet []byte) error {
} }
func (t *Transport) HandlePacket(data []byte, iface common.NetworkInterface) { func (t *Transport) HandlePacket(data []byte, iface common.NetworkInterface) {
if len(data) < 2 { if len(data) < common.TWO {
debug.Log(debug.DEBUG_INFO, "Dropping packet: insufficient length", "bytes", len(data)) debug.Log(debug.DEBUG_INFO, "Dropping packet: insufficient length", common.STR_BYTES, len(data))
return return
} }
headerByte := data[0] headerByte := data[common.ZERO]
packetType := headerByte & 0x03 packetType := headerByte & common.HEX_0x03
headerType := (headerByte & 0x40) >> 6 headerType := (headerByte & 0x40) >> common.SIX
contextFlag := (headerByte & 0x20) >> 5 contextFlag := (headerByte & 0x20) >> common.FIVE
propType := (headerByte & 0x10) >> 4 propType := (headerByte & 0x10) >> common.FOUR
destType := (headerByte & 0x0C) >> 2 destType := (headerByte & 0x0C) >> common.TWO
debug.Log(debug.DEBUG_INFO, "TRANSPORT: Packet received", "type", fmt.Sprintf("0x%02x", packetType), "header", headerType, "context", contextFlag, "propType", propType, "destType", destType, "size", len(data)) debug.Log(debug.DEBUG_INFO, "TRANSPORT: Packet received", "type", fmt.Sprintf(common.STR_FMT_HEX, packetType), "header", headerType, "context", contextFlag, "propType", propType, "destType", destType, "size", len(data))
debug.Log(debug.DEBUG_TRACE, "Interface and raw header", "name", iface.GetName(), "header", fmt.Sprintf("0x%02x", headerByte)) debug.Log(debug.DEBUG_TRACE, "Interface and raw header", "name", iface.GetName(), "header", fmt.Sprintf(common.STR_FMT_HEX, headerByte))
if len(data) == 67 { if len(data) == common.SIXTY_SEVEN {
debug.Log(debug.DEBUG_ERROR, "67-byte packet detected", "header", fmt.Sprintf("0x%02x", headerByte), "packet_type_bits", fmt.Sprintf("0x%02x", packetType), "first_32_bytes", fmt.Sprintf("%x", data[:32])) debug.Log(debug.DEBUG_ERROR, "67-byte packet detected", "header", fmt.Sprintf(common.STR_FMT_HEX, headerByte), "packet_type_bits", fmt.Sprintf(common.STR_FMT_HEX, packetType), "first_32_bytes", fmt.Sprintf("%x", data[:common.SIZE_32]))
} }
if tcpIface, ok := iface.(*interfaces.TCPClientInterface); ok { if tcpIface, ok := iface.(*interfaces.TCPClientInterface); ok {
@@ -830,66 +830,66 @@ func (t *Transport) HandlePacket(data []byte, iface common.NetworkInterface) {
} }
case PACKET_TYPE_LINK: case PACKET_TYPE_LINK:
debug.Log(debug.DEBUG_ERROR, "Processing link packet (type=0x02)", "packet_size", len(data)) debug.Log(debug.DEBUG_ERROR, "Processing link packet (type=0x02)", "packet_size", len(data))
t.handleLinkPacket(data[1:], iface, PACKET_TYPE_LINK) t.handleLinkPacket(data[common.ONE:], iface, PACKET_TYPE_LINK)
case packet.PacketTypeProof: case packet.PacketTypeProof:
debug.Log(debug.DEBUG_VERBOSE, "Processing proof packet") debug.Log(debug.DEBUG_VERBOSE, "Processing proof packet")
fullData := append([]byte{packet.PacketTypeProof}, data[1:]...) fullData := append([]byte{packet.PacketTypeProof}, data[common.ONE:]...)
pkt := &packet.Packet{Raw: fullData} pkt := &packet.Packet{Raw: fullData}
if err := pkt.Unpack(); err != nil { if err := pkt.Unpack(); err != nil {
debug.Log(debug.DEBUG_INFO, "Failed to unpack proof packet", "error", err) debug.Log(debug.DEBUG_INFO, "Failed to unpack proof packet", "error", err)
return return
} }
t.handleProofPacket(pkt, iface) t.handleProofPacket(pkt, iface)
case 0x00: case common.ZERO:
// Data packets addressed to link destinations carry link traffic // Data packets addressed to link destinations carry link traffic
if destType == DEST_TYPE_LINK { if destType == DEST_TYPE_LINK {
debug.Log(debug.DEBUG_ERROR, "Processing link data packet (dest_type=3)", "packet_size", len(data)) debug.Log(debug.DEBUG_ERROR, "Processing link data packet (dest_type=3)", "packet_size", len(data))
t.handleLinkPacket(data[1:], iface, 0x00) t.handleLinkPacket(data[common.ONE:], iface, common.ZERO)
} else { } else {
debug.Log(debug.DEBUG_ERROR, "Processing data packet (type 0x00)", "packet_size", len(data), "dest_type", destType, "header_type", headerType) debug.Log(debug.DEBUG_ERROR, "Processing data packet (type 0x00)", "packet_size", len(data), "dest_type", destType, "header_type", headerType)
t.handleTransportPacket(data[1:], iface) t.handleTransportPacket(data[common.ONE:], iface)
} }
default: default:
debug.Log(debug.DEBUG_INFO, "Unknown packet type", "type", fmt.Sprintf("0x%02x", packetType), "source", iface.GetName()) debug.Log(debug.DEBUG_INFO, "Unknown packet type", "type", fmt.Sprintf(common.STR_FMT_HEX, packetType), "source", iface.GetName())
} }
} }
func (t *Transport) handleAnnouncePacket(data []byte, iface common.NetworkInterface) error { func (t *Transport) handleAnnouncePacket(data []byte, iface common.NetworkInterface) error {
debug.Log(debug.DEBUG_INFO, "Processing announce packet", "length", len(data)) debug.Log(debug.DEBUG_INFO, "Processing announce packet", "length", len(data))
if len(data) < 2 { if len(data) < common.TWO {
return fmt.Errorf("packet too small for header") return fmt.Errorf("packet too small for header")
} }
// Parse header bytes according to RNS spec // Parse header bytes according to RNS spec
headerByte1 := data[0] headerByte1 := data[common.ZERO]
hopCount := data[1] hopCount := data[common.ONE]
// Extract header fields // Extract header fields
ifacFlag := (headerByte1 & 0x80) >> 7 // IFAC flag in highest bit ifacFlag := (headerByte1 & 0x80) >> common.SEVEN // IFAC flag in highest bit
headerType := (headerByte1 & 0x40) >> 6 // Header type in next bit headerType := (headerByte1 & 0x40) >> common.SIX // Header type in next bit
contextFlag := (headerByte1 & 0x20) >> 5 // Context flag contextFlag := (headerByte1 & 0x20) >> common.FIVE // Context flag
propType := (headerByte1 & 0x10) >> 4 // Propagation type propType := (headerByte1 & 0x10) >> common.FOUR // Propagation type
destType := (headerByte1 & 0x0C) >> 2 // Destination type in next 2 bits destType := (headerByte1 & 0x0C) >> common.TWO // Destination type in next 2 bits
packetType := headerByte1 & 0x03 // Packet type in lowest 2 bits packetType := headerByte1 & common.HEX_0x03 // Packet type in lowest 2 bits
debug.Log(debug.DEBUG_TRACE, "Announce header", "ifac", ifacFlag, "headerType", headerType, "context", contextFlag, "propType", propType, "destType", destType, "packetType", packetType) debug.Log(debug.DEBUG_TRACE, "Announce header", "ifac", ifacFlag, "headerType", headerType, "context", contextFlag, "propType", propType, "destType", destType, "packetType", packetType)
// Skip IFAC code if present // Skip IFAC code if present
startIdx := 2 startIdx := common.TWO
if ifacFlag == 1 { if ifacFlag == common.ONE {
startIdx++ // For now assume 1 byte IFAC code startIdx++ // For now assume 1 byte IFAC code
} }
// Announce packets use HEADER_TYPE_1 (single address field) // Announce packets use HEADER_TYPE_1 (single address field)
// Calculate address field size // Calculate address field size
addrSize := 16 // Always 16 bytes for HEADER_TYPE_1 addrSize := common.SIZE_16 // Always 16 bytes for HEADER_TYPE_1
if headerType == 1 { if headerType == common.ONE {
// HEADER_TYPE_2 has two address fields // HEADER_TYPE_2 has two address fields
addrSize = 32 addrSize = common.SIZE_32
} }
// Validate minimum packet size // Validate minimum packet size
minSize := startIdx + addrSize + 1 // Header + address(es) + context minSize := startIdx + addrSize + common.ONE // Header + address(es) + context
if len(data) < minSize { if len(data) < minSize {
return fmt.Errorf("packet too small: %d bytes", len(data)) return fmt.Errorf("packet too small: %d bytes", len(data))
} }