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()} req.Marshal(d.buf[:PING_SIZE]) d.sender.send(PACKET_TYPE_PING, d.buf[:PING_SIZE], route, nil) d.pingTimer.Reset(pingInterval) } func (d *connData) sendPong(w wrapper[Ping]) { route := d.route.Load() pong := Pong{ SentAt: w.T.SentAt, RecvdAt: time.Now().UnixMilli(), } pong.Marshal(d.buf[:PONG_SIZE]) d.sender.send(PACKET_TYPE_PONG, d.buf[:PONG_SIZE], route, nil) }