83 lines
1.7 KiB
Go
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)
|
|
}
|