package main import ( "hash" "log/slog" "net" "sync" "time" "github.com/katzenpost/noise" vors "go.stargrave.org/vors/v4/internal" ) var ( Peers = map[byte]*Peer{} PeersM sync.Mutex ) type Stats struct { last time.Time pktsRx int64 pktsTx int64 bads int64 bytesRx uint64 bytesTx uint64 } type Peer struct { name string addr *net.UDPAddr stats *Stats room *Room key []byte mac hash.Hash muted bool sid byte logger *slog.Logger conn *vors.NSConn rxCS, txCS *noise.CipherState rx, tx chan []byte alive chan struct{} aliveOnce sync.Once } func (peer *Peer) Close() { peer.aliveOnce.Do(func() { close(peer.rx) close(peer.tx) close(peer.alive) peer.conn.Conn.Close() }) } func (peer *Peer) Rx() { var err error for buf := range peer.conn.Rx { buf, err = peer.rxCS.Decrypt(buf[:0], nil, buf) if err != nil { peer.logger.Error("rx decrypt", "err", err) break } peer.rx <- buf } peer.Close() } func (peer *Peer) Tx() { var err error for buf := range peer.tx { if peer.txCS == nil { continue } buf, err = peer.txCS.Encrypt(buf[:0], nil, buf) if err != nil { peer.logger.Error("tx encrypt", "err", err) break } if err = peer.conn.Tx(buf); err != nil { peer.logger.Error("tx write", "err", err) break } } peer.Close() }