]> Sergey Matveev's repositories - vors.git/blob - cmd/server/peer.go
Show bad packets counter
[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 type Stats struct {
14         pktsRx  int64
15         pktsTx  int64
16         bytesRx uint64
17         bytesTx uint64
18         bads    int64
19         last    time.Time
20         alive   chan struct{}
21 }
22
23 type Peer struct {
24         name  string
25         sid   byte
26         addr  *net.UDPAddr
27         key   []byte
28         stats *Stats
29
30         logger     *slog.Logger
31         conn       net.Conn
32         rx, tx     chan []byte
33         rxCS, txCS *noise.CipherState
34         alive      chan struct{}
35         aliveOnce  sync.Once
36 }
37
38 func (peer *Peer) Close() {
39         peer.aliveOnce.Do(func() {
40                 close(peer.rx)
41                 close(peer.tx)
42                 close(peer.alive)
43                 peer.conn.Close()
44         })
45 }
46
47 func (peer *Peer) Rx() {
48         for {
49                 buf, err := vors.PktRead(peer.conn)
50                 if err != nil {
51                         peer.logger.Error("rx", "err", err)
52                         break
53                 }
54                 buf, err = peer.rxCS.Decrypt(buf[:0], nil, buf)
55                 if err != nil {
56                         peer.logger.Error("rx decrypt", "err", err)
57                         break
58                 }
59                 peer.rx <- buf
60         }
61         peer.Close()
62 }
63
64 func (peer *Peer) Tx() {
65         for buf := range peer.tx {
66                 if peer.txCS == nil {
67                         continue
68                 }
69                 buf, err := peer.txCS.Encrypt(buf[:0], nil, buf)
70                 if err != nil {
71                         peer.logger.Error("tx encrypt", "err", err)
72                         break
73                 }
74                 err = vors.PktWrite(peer.conn, buf)
75                 if err != nil {
76                         peer.logger.Error("tx", "err", err)
77                         break
78                 }
79         }
80         peer.Close()
81 }