summaryrefslogtreecommitdiffstats
path: root/transport/mesh/mesh.go
diff options
context:
space:
mode:
authorgabrix73 <gabriel1@frozenstar.info>2026-04-10 16:10:48 +0200
committergabrix73 <gabriel1@frozenstar.info>2026-04-10 16:10:48 +0200
commit88375da30ea667ec25c2000874557fcc4785a558 (patch)
tree71364a43230977481c6d3280246aa8bb48562bdc /transport/mesh/mesh.go
downloadkhimera-88375da30ea667ec25c2000874557fcc4785a558.tar.gz
khimera-88375da30ea667ec25c2000874557fcc4785a558.tar.xz
khimera-88375da30ea667ec25c2000874557fcc4785a558.zip
Initial commit: Veilith v0.9 - P2P Encrypted Messenger
Military-grade secure messenger with: - End-to-End Encryption (Noise Protocol XX) - Forward Secrecy (automatic session rotation) - Anti-Traffic Analysis (padding + cover traffic) - Secure Deletion (DOD 5220.22-M) - Tor Integration (embedded with bridge support) - Portable Mode (no installation required) Generated with Claude Code
Diffstat (limited to 'transport/mesh/mesh.go')
-rw-r--r--transport/mesh/mesh.go248
1 files changed, 248 insertions, 0 deletions
diff --git a/transport/mesh/mesh.go b/transport/mesh/mesh.go
new file mode 100644
index 0000000..dbe50e1
--- /dev/null
+++ b/transport/mesh/mesh.go
@@ -0,0 +1,248 @@
+// Package mesh implements peer-to-peer mesh networking
+package mesh
+
+import (
+ "fmt"
+ "net"
+ "sync"
+ "time"
+
+ "veilith/transport"
+)
+
+// MeshTransport implements peer-to-peer mesh networking
+type MeshTransport struct {
+ peers map[string]*Peer // address -> peer
+ mu sync.RWMutex
+ listener net.Listener
+ localAddr string
+ closed bool
+ discoveryInterval time.Duration
+}
+
+// Peer represents a mesh network peer
+type Peer struct {
+ Address string
+ PublicKey string
+ LastSeen time.Time
+ Conn net.Conn
+ IsRelay bool // Can this peer relay messages?
+}
+
+// NewMeshTransport creates a new mesh transport
+func NewMeshTransport() *MeshTransport {
+ return &MeshTransport{
+ peers: make(map[string]*Peer),
+ discoveryInterval: 30 * time.Second,
+ }
+}
+
+// Connect connects to a mesh peer
+func (m *MeshTransport) Connect(address string) (net.Conn, error) {
+ m.mu.Lock()
+ defer m.mu.Unlock()
+
+ if m.closed {
+ return nil, fmt.Errorf("mesh transport is closed")
+ }
+
+ // Check if already connected
+ if peer, exists := m.peers[address]; exists {
+ if peer.Conn != nil {
+ peer.LastSeen = time.Now()
+ return peer.Conn, nil
+ }
+ }
+
+ // Establish new connection
+ conn, err := net.DialTimeout("tcp", address, 10*time.Second)
+ if err != nil {
+ return nil, fmt.Errorf("failed to connect to peer %s: %w", address, err)
+ }
+
+ // Add peer
+ m.peers[address] = &Peer{
+ Address: address,
+ LastSeen: time.Now(),
+ Conn: conn,
+ }
+
+ return conn, nil
+}
+
+// Listen starts listening for mesh connections
+func (m *MeshTransport) Listen(address string) (net.Listener, error) {
+ m.mu.Lock()
+ defer m.mu.Unlock()
+
+ if m.closed {
+ return nil, fmt.Errorf("mesh transport is closed")
+ }
+
+ if m.listener != nil {
+ return nil, fmt.Errorf("already listening on %s", m.localAddr)
+ }
+
+ listener, err := net.Listen("tcp", address)
+ if err != nil {
+ return nil, fmt.Errorf("failed to listen on %s: %w", address, err)
+ }
+
+ m.listener = listener
+ m.localAddr = address
+
+ // Start peer discovery in background
+ go m.startPeerDiscovery()
+
+ return listener, nil
+}
+
+// Type returns the transport type
+func (m *MeshTransport) Type() transport.TransportType {
+ return transport.TransportMesh
+}
+
+// Close closes the mesh transport
+func (m *MeshTransport) Close() error {
+ m.mu.Lock()
+ defer m.mu.Unlock()
+
+ if m.closed {
+ return nil
+ }
+
+ m.closed = true
+
+ // Close listener
+ if m.listener != nil {
+ if err := m.listener.Close(); err != nil {
+ return fmt.Errorf("failed to close listener: %w", err)
+ }
+ m.listener = nil
+ }
+
+ // Close all peer connections
+ for addr, peer := range m.peers {
+ if peer.Conn != nil {
+ peer.Conn.Close()
+ }
+ delete(m.peers, addr)
+ }
+
+ return nil
+}
+
+// AddPeer manually adds a peer to the mesh
+func (m *MeshTransport) AddPeer(address string) error {
+ m.mu.Lock()
+ defer m.mu.Unlock()
+
+ if m.closed {
+ return fmt.Errorf("mesh transport is closed")
+ }
+
+ if _, exists := m.peers[address]; exists {
+ return fmt.Errorf("peer already exists: %s", address)
+ }
+
+ m.peers[address] = &Peer{
+ Address: address,
+ LastSeen: time.Now(),
+ }
+
+ return nil
+}
+
+// RemovePeer removes a peer from the mesh
+func (m *MeshTransport) RemovePeer(address string) error {
+ m.mu.Lock()
+ defer m.mu.Unlock()
+
+ peer, exists := m.peers[address]
+ if !exists {
+ return fmt.Errorf("peer not found: %s", address)
+ }
+
+ if peer.Conn != nil {
+ peer.Conn.Close()
+ }
+
+ delete(m.peers, address)
+ return nil
+}
+
+// GetPeers returns all known peers
+func (m *MeshTransport) GetPeers() []*Peer {
+ m.mu.RLock()
+ defer m.mu.RUnlock()
+
+ peers := make([]*Peer, 0, len(m.peers))
+ for _, peer := range m.peers {
+ peers = append(peers, peer)
+ }
+ return peers
+}
+
+// GetPeerCount returns the number of known peers
+func (m *MeshTransport) GetPeerCount() int {
+ m.mu.RLock()
+ defer m.mu.RUnlock()
+ return len(m.peers)
+}
+
+// startPeerDiscovery periodically discovers new peers
+func (m *MeshTransport) startPeerDiscovery() {
+ ticker := time.NewTicker(m.discoveryInterval)
+ defer ticker.Stop()
+
+ for {
+ select {
+ case <-ticker.C:
+ m.mu.RLock()
+ if m.closed {
+ m.mu.RUnlock()
+ return
+ }
+ m.mu.RUnlock()
+
+ // Clean up stale peers
+ m.cleanupStalePeers(5 * time.Minute)
+
+ // In a real implementation, you would:
+ // 1. Query known peers for their peer lists
+ // 2. Attempt connections to new peers
+ // 3. Exchange routing tables
+ }
+ }
+}
+
+// cleanupStalePeers removes peers that haven't been seen recently
+func (m *MeshTransport) cleanupStalePeers(maxAge time.Duration) {
+ m.mu.Lock()
+ defer m.mu.Unlock()
+
+ now := time.Now()
+ for addr, peer := range m.peers {
+ if now.Sub(peer.LastSeen) > maxAge {
+ if peer.Conn != nil {
+ peer.Conn.Close()
+ }
+ delete(m.peers, addr)
+ }
+ }
+}
+
+// SetDiscoveryInterval sets the peer discovery interval
+func (m *MeshTransport) SetDiscoveryInterval(interval time.Duration) {
+ m.mu.Lock()
+ defer m.mu.Unlock()
+ m.discoveryInterval = interval
+}
+
+// String returns a string representation
+func (m *MeshTransport) String() string {
+ m.mu.RLock()
+ defer m.mu.RUnlock()
+ return fmt.Sprintf("MeshTransport(peers=%d, listening=%s, closed=%v)",
+ len(m.peers), m.localAddr, m.closed)
+}