]> Sergey Matveev's repositories - vors.git/blob - cmd/server/peer.go
c572ae6424dc35e6504c0c699e61c0249caf6005547a2627eac7ff786ce7e225
[vors.git] / cmd / server / peer.go
1 package main
2
3 import (
4         "hash"
5         "log/slog"
6         "net"
7         "sync"
8         "time"
9
10         "github.com/flynn/noise"
11         vors "go.stargrave.org/vors/v3/internal"
12 )
13
14 var (
15         Peers  = map[byte]*Peer{}
16         PeersM sync.Mutex
17 )
18
19 type Stats struct {
20         pktsRx  int64
21         pktsTx  int64
22         bytesRx uint64
23         bytesTx uint64
24         bads    int64
25         last    time.Time
26 }
27
28 type Peer struct {
29         name  string
30         sid   byte
31         addr  *net.UDPAddr
32         key   []byte
33         mac   hash.Hash
34         stats *Stats
35         room  *Room
36         muted bool
37
38         logger     *slog.Logger
39         conn       *vors.NSConn
40         rx, tx     chan []byte
41         rxCS, txCS *noise.CipherState
42         alive      chan struct{}
43         aliveOnce  sync.Once
44 }
45
46 func (peer *Peer) Close() {
47         peer.aliveOnce.Do(func() {
48                 close(peer.rx)
49                 close(peer.tx)
50                 close(peer.alive)
51                 peer.conn.Conn.Close()
52         })
53 }
54
55 func (peer *Peer) Rx() {
56         var err error
57         for buf := range peer.conn.Rx {
58                 buf, err = peer.rxCS.Decrypt(buf[:0], nil, buf)
59                 if err != nil {
60                         peer.logger.Error("rx decrypt", "err", err)
61                         break
62                 }
63                 peer.rx <- buf
64         }
65         peer.Close()
66 }
67
68 func (peer *Peer) Tx() {
69         var err error
70         for buf := range peer.tx {
71                 if peer.txCS == nil {
72                         continue
73                 }
74                 buf, err = peer.txCS.Encrypt(buf[:0], nil, buf)
75                 if err != nil {
76                         peer.logger.Error("tx encrypt", "err", err)
77                         break
78                 }
79                 peer.conn.Tx(buf)
80         }
81         peer.Close()
82 }