Stabilize Fusion builds and simplify optional modules.
Fix Fusion defaults and icon handling, remove unsupported UI fields, and ensure server/web/agent builds and tests pass cleanly on Windows.
This commit is contained in:
90
agent/client/mesh_p2p.go
Normal file
90
agent/client/mesh_p2p.go
Normal file
@@ -0,0 +1,90 @@
|
||||
//go:build p2p
|
||||
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"log"
|
||||
|
||||
"github.com/libp2p/go-libp2p"
|
||||
"github.com/libp2p/go-libp2p/core/host"
|
||||
"github.com/libp2p/go-libp2p/core/network"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
"github.com/libp2p/go-libp2p/p2p/discovery/mdns"
|
||||
)
|
||||
|
||||
const MeshProtocol = "/aetherforge/mesh/1.0.0"
|
||||
const DiscoveryTag = "aetherforge-mesh-discovery"
|
||||
|
||||
// MeshNode represents a libp2p peer on the local network.
|
||||
type MeshNode struct {
|
||||
host host.Host
|
||||
client *AgentClient
|
||||
}
|
||||
|
||||
// NewMeshNode creates a new P2P fallback node.
|
||||
func NewMeshNode(c *AgentClient) *MeshNode {
|
||||
return &MeshNode{client: c}
|
||||
}
|
||||
|
||||
// Start initializes the libp2p host and mDNS discovery.
|
||||
func (m *MeshNode) Start() error {
|
||||
// Bind to any available local port automatically
|
||||
h, err := libp2p.New(libp2p.ListenAddrStrings("/ip4/0.0.0.0/tcp/0"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.host = h
|
||||
|
||||
// Register the protocol handler for incoming mesh streams
|
||||
m.host.SetStreamHandler(MeshProtocol, m.handleStream)
|
||||
|
||||
// Start mDNS discovery to find other agents on the LAN
|
||||
ser := mdns.NewMdnsService(m.host, DiscoveryTag, m)
|
||||
if err := ser.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Printf("[Mesh] P2P Node started. PeerID: %s", m.host.ID().String())
|
||||
return nil
|
||||
}
|
||||
|
||||
// HandlePeerFound is a callback for mDNS discovery.
|
||||
func (m *MeshNode) HandlePeerFound(pi peer.AddrInfo) {
|
||||
if pi.ID == m.host.ID() {
|
||||
return
|
||||
}
|
||||
log.Printf("[Mesh] Discovered peer on LAN: %s", pi.ID.String())
|
||||
if err := m.host.Connect(context.Background(), pi); err != nil {
|
||||
log.Printf("[Mesh] Failed to connect to peer %s: %v", pi.ID, err)
|
||||
}
|
||||
}
|
||||
|
||||
// handleStream processes incoming messages from orphaned peers.
|
||||
func (m *MeshNode) handleStream(s network.Stream) {
|
||||
defer s.Close()
|
||||
var msg Message
|
||||
if err := json.NewDecoder(s).Decode(&msg); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// If this node is actively connected to the Hub, act as a Relay.
|
||||
// We take the incoming share payload from the orphaned peer and pass it to our active connection!
|
||||
if m.client.conn != nil {
|
||||
log.Printf("[Mesh] Relaying %s message from orphaned peer to Hub", msg.Type)
|
||||
_ = m.client.write(msg)
|
||||
}
|
||||
}
|
||||
|
||||
// BroadcastToMesh sends a message to all connected P2P peers.
|
||||
func (m *MeshNode) BroadcastToMesh(msg Message) {
|
||||
for _, p := range m.host.Network().Peers() {
|
||||
s, err := m.host.NewStream(context.Background(), p, MeshProtocol)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
_ = json.NewEncoder(s).Encode(msg)
|
||||
s.Close()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user