vppn/node/peer-super.go
2024-12-23 06:05:50 +01:00

96 lines
2.0 KiB
Go

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)
}