81 lines
1.6 KiB
Go
81 lines
1.6 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[peerRoutingData]
|
|
staged peerRoutingData // 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)
|
|
}
|
|
}
|