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