vppn/peer/conndata.go
2024-12-14 07:38:06 +01:00

83 lines
1.7 KiB
Go

package peer
import (
"net/netip"
"sync/atomic"
"time"
"vppn/m"
)
const (
pingInterval = time.Second * 8
timeoutInterval = 32 * time.Second
)
type connData struct {
// Shared data.
routes [MAX_IP]*atomic.Pointer[route]
route *atomic.Pointer[route]
// Peer data.
server bool // Never changes.
peerIP byte // Never changes.
encPrivKey []byte // Never changes.
peer *m.Peer // From hub.
encSharedKey []byte // From hub + private key.
publicAddr netip.AddrPort // From hub.
// Connection establishment and maintenance.
pingTimer *time.Timer
timeoutTimer *time.Timer
// Routing data.
addr netip.AddrPort
useMediator bool
up bool
// For sending.
buf []byte
sender *safeConnSender
}
func (d *connData) Route() *route {
return &route{
PeerIP: d.peerIP,
Up: d.up,
Mediator: d.peer.Mediator,
EncSharedKey: d.encSharedKey,
Addr: d.addr,
useMediator: d.useMediator,
}
}
func (d *connData) HandlePeerUpdate(state connState, update peerUpdate) connState {
if d.peer != nil && update.Peer != nil && d.peer.Version == update.Peer.Version {
return state
}
if d.peer == nil && update.Peer == nil {
return state
}
return newStateFromPeerUpdate(update, d)
}
func (d *connData) HandleSendPing() {
route := d.route.Load()
req := Ping{SentAt: time.Now().UnixMilli()}
d.buf = req.Marshal(d.buf)
d.sender.send(PACKET_TYPE_PING, d.buf, route, nil)
d.pingTimer.Reset(pingInterval)
}
func (d *connData) sendPong(w wrapper) {
ping := w.Packet.(*Ping)
route := d.route.Load()
pong := Pong{
SentAt: ping.SentAt,
RecvdAt: time.Now().UnixMilli(),
}
d.buf = pong.Marshal(d.buf)
d.sender.send(PACKET_TYPE_PONG, d.buf, route, nil)
}