package peer import ( "log" "net" "net/netip" "sync/atomic" "vppn/m" ) type Router struct { conf m.PeerConfig // Routes used by the peer. conns [MAX_IP]*connHandler routes [MAX_IP]*atomic.Pointer[route] addrs [MAX_IP]*atomic.Pointer[netip.AddrPort] mediatorIP *atomic.Pointer[byte] } func NewRouter(conf m.PeerConfig, conn *net.UDPConn) *Router { r := &Router{ conf: conf, mediatorIP: &atomic.Pointer[byte]{}, } for i := range r.routes { r.routes[i] = &atomic.Pointer[route]{} } _, isServer := netip.AddrFromSlice(conf.PublicIP) sender := newConnSender(conn, conf.PeerIP, STREAM_ROUTING) for i := range r.conns { if byte(i) != conf.PeerIP { r.conns[i] = newConnHandler( isServer, byte(i), r.routes, conf.EncPrivKey, newSafeConnSender(sender)) } } go r.pollHub() if !isServer { go r.manageMediator() } return r } // ---------------------------------------------------------------------------- // Peer Methods // ---------------------------------------------------------------------------- func (rm *Router) GetRoute(ip byte) *route { return rm.routes[ip].Load() } func (rm *Router) GetMediator() *route { if ip := rm.mediatorIP.Load(); ip != nil { return rm.GetRoute(*ip) } return nil } func (r *Router) HandlePacket(src netip.AddrPort, nonce Nonce, data []byte) { if nonce.SourceIP == r.conf.PeerIP { log.Printf("Packet to self...") return } switch nonce.PacketType { case PACKET_TYPE_PING: if len(data) < PING_SIZE { log.Printf("Short ping request: %d", len(data)) return } w := newWrapper[Ping](src, nonce) w.T.Parse(data) r.conns[nonce.SourceIP].HandlePing(w) case PACKET_TYPE_PONG: if len(data) < PONG_SIZE { log.Printf("Short ping response: %d", len(data)) return } w := newWrapper[Pong](src, nonce) w.T.Parse(data) r.conns[nonce.SourceIP].HandlePong(w) default: log.Printf("Unknown routing packet type: %d", nonce.PacketType) } }