]> Sergey Matveev's repositories - vors.git/blob - cmd/server/peer.go
Prepare for next version
[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
37         logger     *slog.Logger
38         conn       net.Conn
39         rx, tx     chan []byte
40         rxCS, txCS *noise.CipherState
41         alive      chan struct{}
42         aliveOnce  sync.Once
43 }
44
45 func (peer *Peer) Close() {
46         peer.aliveOnce.Do(func() {
47                 close(peer.rx)
48                 close(peer.tx)
49                 close(peer.alive)
50                 peer.conn.Close()
51         })
52 }
53
54 func (peer *Peer) Rx() {
55         for {
56                 buf, err := vors.PktRead(peer.conn)
57                 if err != nil {
58                         peer.logger.Error("rx", "err", err)
59                         break
60                 }
61                 buf, err = peer.rxCS.Decrypt(buf[:0], nil, buf)
62                 if err != nil {
63                         peer.logger.Error("rx decrypt", "err", err)
64                         break
65                 }
66                 peer.rx <- buf
67         }
68         peer.Close()
69 }
70
71 func (peer *Peer) Tx() {
72         for buf := range peer.tx {
73                 if peer.txCS == nil {
74                         continue
75                 }
76                 buf, err := peer.txCS.Encrypt(buf[:0], nil, buf)
77                 if err != nil {
78                         peer.logger.Error("tx encrypt", "err", err)
79                         break
80                 }
81                 err = vors.PktWrite(peer.conn, buf)
82                 if err != nil {
83                         peer.logger.Error("tx", "err", err)
84                         break
85                 }
86         }
87         peer.Close()
88 }