package node import ( "encoding/json" "flag" "fmt" "io" "log" "net" "net/http" "net/netip" "os" "runtime/debug" "vppn/m" ) func panicHandler() { if r := recover(); r != nil { log.Fatalf("\n %v\n\nstacktrace from panic: %s\n", r, string(debug.Stack())) } } func Main() { defer panicHandler() var ( netName string initURL string listenIP string port int ) flag.StringVar(&netName, "name", "", "[REQUIRED] The network name.") flag.StringVar(&initURL, "init-url", "", "Initializes peer from the hub URL.") flag.StringVar(&listenIP, "listen-ip", "", "IP address to listen on.") flag.IntVar(&port, "port", 0, "Port to listen on.") flag.Parse() if netName == "" { flag.Usage() os.Exit(1) } if initURL != "" { mainInit(netName, initURL) return } main(netName, listenIP, uint16(port)) } func mainInit(netName, initURL string) { if _, err := loadPeerConfig(netName); err == nil { log.Fatalf("Network is already initialized.") } resp, err := http.Get(initURL) if err != nil { log.Fatalf("Failed to fetch data from hub: %v", err) } defer resp.Body.Close() data, err := io.ReadAll(resp.Body) if err != nil { log.Fatalf("Failed to read response body: %v", err) } peerConfig := m.PeerConfig{} if err := json.Unmarshal(data, &peerConfig); err != nil { log.Fatalf("Failed to parse configuration: %v", err) } if err := storePeerConfig(netName, peerConfig); err != nil { log.Fatalf("Failed to store configuration: %v", err) } log.Print("Initialization successful.") } // ---------------------------------------------------------------------------- func main(netName, listenIP string, port uint16) { conf, err := loadPeerConfig(netName) if err != nil { log.Fatalf("Failed to load configuration: %v", err) } port = determinePort(conf.Port, port) iface, err := openInterface(conf.Network, conf.PeerIP, netName) if err != nil { log.Fatalf("Failed to open interface: %v", err) } myAddr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", listenIP, port)) if err != nil { log.Fatalf("Failed to resolve UDP address: %v", err) } conn, err := net.ListenUDP("udp", myAddr) if err != nil { log.Fatalf("Failed to open UDP port: %v", err) } connWriter := newConnWriter2(conn) ifWriter := newIFWriter(iface) peers := remotePeers{} for i := range peers { peers[i] = newRemotePeer(conf, byte(i), ifWriter, connWriter) } go newHubPoller(netName, conf, peers).Run() go readFromConn(conn, peers) readFromIFace(iface, peers) } // ---------------------------------------------------------------------------- func determinePort(confPort, portFromCommandLine uint16) uint16 { if portFromCommandLine != 0 { return portFromCommandLine } if confPort != 0 { return confPort } return 456 } // ---------------------------------------------------------------------------- func readFromConn(conn *net.UDPConn, peers remotePeers) { defer panicHandler() var ( remoteAddr netip.AddrPort n int err error buf = make([]byte, bufferSize) data []byte h xHeader ) for { n, remoteAddr, err = conn.ReadFromUDPAddrPort(buf[:bufferSize]) if err != nil { log.Fatalf("Failed to read from UDP port: %v", err) } data = buf[:n] if n < headerSize { continue // Packet it soo short. } h.Parse(data) peers[h.SourceIP].HandlePacket(remoteAddr, h, data) } } // ---------------------------------------------------------------------------- func readFromIFace(iface io.ReadWriteCloser, peers remotePeers) { var ( buf = make([]byte, bufferSize) packet []byte remoteIP byte err error ) for { packet, remoteIP, err = readNextPacket(iface, buf) if err != nil { log.Fatalf("Failed to read from interface: %v", err) } peers[remoteIP].SendData(packet) } }