diff options
| author | gabrix73 <gabriel1@frozenstar.info> | 2026-04-10 16:10:48 +0200 |
|---|---|---|
| committer | gabrix73 <gabriel1@frozenstar.info> | 2026-04-10 16:10:48 +0200 |
| commit | 88375da30ea667ec25c2000874557fcc4785a558 (patch) | |
| tree | 71364a43230977481c6d3280246aa8bb48562bdc /transport/mesh/mesh.go | |
| download | khimera-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.go | 248 |
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) +} |
