package node import ( "fmt" "log" "sync/atomic" "vppn/m" ) type peerSuper struct { // The purpose of this state machine is to manage this published data. published *atomic.Pointer[peerRouteInfo] staged peerRouteInfo // Local copy of shared data. See publish(). // The other remote peers. peers *remotePeers // Immutable data. localIP byte localPub bool remoteIP byte privKey []byte conn *connWriter // For sending to peer. counter *uint64 // Mutable peer data. peer *m.Peer remotePub bool // Incoming events. peerUpdates chan *m.Peer controlPackets chan controlPacket // Buffers buf []byte encBuf []byte } type stateFunc func() stateFunc func (s *peerSuper) Run() { state := s.noPeer for { state = state() } } // ---------------------------------------------------------------------------- func (s *peerSuper) logf(msg string, args ...any) { log.Printf(fmt.Sprintf("[%03d] ", s.remoteIP)+msg, args...) } // ---------------------------------------------------------------------------- func (s *peerSuper) publish() { data := s.staged s.published.Store(&data) } // ---------------------------------------------------------------------------- func (s *peerSuper) sendControlPacket(pkt interface{ Marshal([]byte) []byte }) { buf := pkt.Marshal(s.buf) h := header{ StreamID: controlStreamID, Counter: atomic.AddUint64(s.counter, 1), SourceIP: s.localIP, DestIP: s.remoteIP, } buf = s.staged.controlCipher.Encrypt(h, buf, s.encBuf) if s.staged.relayIP != 0 { s.peers[s.staged.relayIP].RelayTo(s.remoteIP, buf) } else { s.conn.WriteTo(buf, s.staged.remoteAddr) } } // ---------------------------------------------------------------------------- func (s *peerSuper) sendControlPacketDirect(pkt interface{ Marshal([]byte) []byte }) { buf := pkt.Marshal(s.buf) h := header{ StreamID: controlStreamID, Counter: atomic.AddUint64(s.counter, 1), SourceIP: s.localIP, DestIP: s.remoteIP, } buf = s.staged.controlCipher.Encrypt(h, buf, s.encBuf) s.conn.WriteTo(buf, s.staged.remoteAddr) }