mirror of
https://github.com/sigcn/pg.git
synced 2025-10-29 03:23:33 +08:00
106 lines
1.9 KiB
Go
106 lines
1.9 KiB
Go
package disco
|
|
|
|
import (
|
|
"errors"
|
|
"log/slog"
|
|
"math/rand"
|
|
"net"
|
|
"time"
|
|
|
|
"github.com/rkonfj/peerguard/peer"
|
|
"github.com/rkonfj/peerguard/secure"
|
|
)
|
|
|
|
var (
|
|
ErrUseOfClosedConnection error = errors.New("use of closed network connection")
|
|
)
|
|
|
|
const (
|
|
OP_PEER_DISCO = 1
|
|
OP_PEER_CONFIRM = 2
|
|
OP_PEER_DELETE = 3
|
|
OP_PEER_HEALTHCHECK = 10
|
|
)
|
|
|
|
type PeerContext struct {
|
|
States map[string]*PeerState
|
|
CreateTime time.Time
|
|
}
|
|
|
|
func (peer *PeerContext) IPv4Ready() bool {
|
|
for _, state := range peer.States {
|
|
if state.Addr.IP.To4() != nil && time.Since(state.LastActiveTime) <= 20*time.Second {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (peer *PeerContext) Ready() bool {
|
|
for _, state := range peer.States {
|
|
if time.Since(state.LastActiveTime) <= 20*time.Second {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (peer *PeerContext) Select() *net.UDPAddr {
|
|
addrs := make([]*net.UDPAddr, 0, len(peer.States))
|
|
for _, state := range peer.States {
|
|
if time.Since(state.LastActiveTime) <= 20*time.Second {
|
|
addrs = append(addrs, state.Addr)
|
|
}
|
|
}
|
|
return addrs[rand.Intn(len(addrs))]
|
|
}
|
|
|
|
type PeerState struct {
|
|
Addr *net.UDPAddr
|
|
LastActiveTime time.Time
|
|
}
|
|
|
|
type PeerOP struct {
|
|
Op int
|
|
Addr *net.UDPAddr
|
|
PeerID peer.PeerID
|
|
}
|
|
|
|
type STUNSession struct {
|
|
PeerID peer.PeerID
|
|
CTime time.Time
|
|
}
|
|
|
|
type Datagram struct {
|
|
PeerID peer.PeerID
|
|
Data []byte
|
|
}
|
|
|
|
func (d *Datagram) TryDecrypt(aesCBC *secure.AESCBC) []byte {
|
|
b, err := aesCBC.Decrypt(d.Data, d.PeerID)
|
|
if err != nil {
|
|
slog.Debug("Datagram decrypt error", "err", err)
|
|
return d.Data
|
|
}
|
|
return b
|
|
}
|
|
|
|
func (d *Datagram) TryEncrypt(aesCBC *secure.AESCBC) []byte {
|
|
b, err := aesCBC.Encrypt(d.Data, d.PeerID)
|
|
if err != nil {
|
|
slog.Debug("Datagram encrypt error", "err", err)
|
|
return d.Data
|
|
}
|
|
return b
|
|
}
|
|
|
|
type PeerFindEvent struct {
|
|
PeerID peer.PeerID
|
|
Metadata peer.Metadata
|
|
}
|
|
|
|
type PeerUDPAddrEvent struct {
|
|
PeerID peer.PeerID
|
|
Addr *net.UDPAddr
|
|
}
|