mirror of
https://github.com/tailscale/tailscale.git
synced 2025-07-31 00:03:47 +00:00
client/local, feature/relayserver, net/udprelay: move session status to its own package
Signed-off-by: Dylan Bargatze <dylan@tailscale.com>
This commit is contained in:
parent
2705d80902
commit
70569bb937
@ -35,7 +35,7 @@ import (
|
||||
"tailscale.com/ipn"
|
||||
"tailscale.com/ipn/ipnstate"
|
||||
"tailscale.com/net/netutil"
|
||||
"tailscale.com/net/udprelay/endpoint"
|
||||
"tailscale.com/net/udprelay/status"
|
||||
"tailscale.com/paths"
|
||||
"tailscale.com/safesocket"
|
||||
"tailscale.com/tailcfg"
|
||||
@ -1641,12 +1641,12 @@ func (lc *Client) DebugSetExpireIn(ctx context.Context, d time.Duration) error {
|
||||
|
||||
// DebugPeerRelaySessions returns debug information about the current peer
|
||||
// relay sessions running through this node.
|
||||
func (lc *Client) DebugPeerRelaySessions(ctx context.Context) ([]endpoint.PeerRelayServerSession, error) {
|
||||
func (lc *Client) DebugPeerRelaySessions(ctx context.Context) ([]status.ServerSession, error) {
|
||||
body, err := lc.send(ctx, "GET", "/localapi/v0/debug-peer-relay-sessions", 200, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error %w: %s", err, body)
|
||||
}
|
||||
return decodeJSON[[]endpoint.PeerRelayServerSession](body)
|
||||
return decodeJSON[[]status.ServerSession](body)
|
||||
}
|
||||
|
||||
// StreamDebugCapture streams a pcap-formatted packet capture.
|
||||
|
@ -19,6 +19,7 @@ import (
|
||||
"tailscale.com/ipn/localapi"
|
||||
"tailscale.com/net/udprelay"
|
||||
"tailscale.com/net/udprelay/endpoint"
|
||||
"tailscale.com/net/udprelay/status"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/key"
|
||||
"tailscale.com/types/logger"
|
||||
@ -120,7 +121,7 @@ type extension struct {
|
||||
type relayServer interface {
|
||||
AllocateEndpoint(discoA key.DiscoPublic, discoB key.DiscoPublic) (endpoint.ServerEndpoint, error)
|
||||
Close() error
|
||||
GetSessions() ([]endpoint.PeerRelayServerSession, error)
|
||||
GetSessions() ([]status.ServerSession, error)
|
||||
}
|
||||
|
||||
// TODO (dylan): doc comments
|
||||
@ -128,7 +129,7 @@ type PeerRelaySessionsReq struct{}
|
||||
|
||||
// TODO (dylan): doc comments
|
||||
type PeerRelaySessionsResp struct {
|
||||
Sessions []endpoint.PeerRelayServerSession
|
||||
Sessions []status.ServerSession
|
||||
Error error
|
||||
}
|
||||
|
||||
|
@ -62,216 +62,3 @@ type ServerEndpoint struct {
|
||||
// bidirectional data flow.
|
||||
SteadyStateLifetime tstime.GoDuration
|
||||
}
|
||||
|
||||
// TODO (dylan): doc comments
|
||||
type PeerRelayServerAllocStatus int
|
||||
|
||||
const (
|
||||
EndpointAllocNotStarted PeerRelayServerAllocStatus = iota
|
||||
// EndpointAllocRequestReceived by the peer relay server from the allocating client
|
||||
EndpointAllocRequestReceived
|
||||
// EndpointAllocated on the peer relay server, but response not yet sent to allocating client
|
||||
EndpointAllocated
|
||||
// EndpointAllocResponseSent from the peer relay server to allocating client
|
||||
EndpointAllocResponseSent
|
||||
|
||||
// TODO (dylan): Should we have a status here for dead allocs that weren't bound before the
|
||||
// BindLifetime timer expired?
|
||||
EndpointAllocExpired
|
||||
)
|
||||
|
||||
func (s PeerRelayServerAllocStatus) String() string {
|
||||
switch s {
|
||||
case EndpointAllocNotStarted:
|
||||
return "alloc not started"
|
||||
case EndpointAllocRequestReceived:
|
||||
return "alloc request received"
|
||||
case EndpointAllocated:
|
||||
return "endpoint allocated"
|
||||
case EndpointAllocResponseSent:
|
||||
return "alloc complete"
|
||||
case EndpointAllocExpired:
|
||||
return "expired"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
// PeerRelayServerBindStatus is the current status of the endpoint binding
|
||||
// handshake between the peer relay server and a SINGLE peer relay client. Both
|
||||
// clients need to bind into an endpoint for a peer relay session to be bound,
|
||||
// so a peer relay server will have two PeerRelayServerBindStatus fields to
|
||||
// track per session.
|
||||
type PeerRelayServerBindStatus int
|
||||
|
||||
// TODO (dylan): doc comments
|
||||
const (
|
||||
EndpointBindNotStarted PeerRelayServerBindStatus = iota
|
||||
EndpointBindRequestReceived
|
||||
EndpointBindChallengeSent
|
||||
EndpointBindAnswerReceived
|
||||
)
|
||||
|
||||
func (s PeerRelayServerBindStatus) String() string {
|
||||
switch s {
|
||||
case EndpointBindNotStarted:
|
||||
return "binding not started"
|
||||
case EndpointBindRequestReceived:
|
||||
return "bind request received"
|
||||
case EndpointBindChallengeSent:
|
||||
return "bind challenge sent"
|
||||
case EndpointBindAnswerReceived:
|
||||
return "bind complete"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
// PeerRelayServerPingStatus is the current status of a SINGLE SIDE of the
|
||||
// bidirectional disco ping exchange between two peer relay clients, as seen by
|
||||
// the peer relay server. As each client will send a disco ping and should
|
||||
// receive a disco pong from the other client in response, a peer relay server
|
||||
// will have two PeerRelayServerPingStatus fields to track per session.
|
||||
type PeerRelayServerPingStatus int
|
||||
|
||||
// TODO (dylan): doc comments
|
||||
const (
|
||||
DiscoPingNotStarted PeerRelayServerPingStatus = iota
|
||||
DiscoPingSeen
|
||||
DiscoPongSeen
|
||||
)
|
||||
|
||||
func (s PeerRelayServerPingStatus) String() string {
|
||||
switch s {
|
||||
case DiscoPingNotStarted:
|
||||
return "ping not started"
|
||||
case DiscoPingSeen:
|
||||
return "disco ping seen"
|
||||
case DiscoPongSeen:
|
||||
return "disco pong seen"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
// TODO (dylan): doc comments
|
||||
type PeerRelayServerStatus int
|
||||
|
||||
// TODO (dylan): doc comments
|
||||
const (
|
||||
AllocatingEndpoint PeerRelayServerStatus = iota
|
||||
BindingEndpoint
|
||||
BidirectionalPinging
|
||||
ServerSessionEstablished
|
||||
)
|
||||
|
||||
func (s PeerRelayServerStatus) String() string {
|
||||
switch s {
|
||||
case AllocatingEndpoint:
|
||||
return "allocating endpoint allocation"
|
||||
case BindingEndpoint:
|
||||
return "binding endpoint"
|
||||
case BidirectionalPinging:
|
||||
return "clients pinging"
|
||||
case ServerSessionEstablished:
|
||||
return "session established"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
// TODO (dylan): doc comments
|
||||
type PeerRelayServerSessionStatus struct {
|
||||
AllocStatus PeerRelayServerAllocStatus
|
||||
ClientBindStatus [2]PeerRelayServerBindStatus
|
||||
ClientPingStatus [2]PeerRelayServerPingStatus
|
||||
ClientPacketsRx [2]uint64
|
||||
ClientPacketsFwd [2]uint64
|
||||
|
||||
OverallStatus PeerRelayServerStatus
|
||||
}
|
||||
|
||||
func NewPeerRelayServerSessionStatus() PeerRelayServerSessionStatus {
|
||||
return PeerRelayServerSessionStatus{
|
||||
AllocStatus: EndpointAllocNotStarted,
|
||||
ClientBindStatus: [2]PeerRelayServerBindStatus{EndpointBindNotStarted, EndpointBindNotStarted},
|
||||
ClientPingStatus: [2]PeerRelayServerPingStatus{DiscoPingNotStarted, DiscoPingNotStarted},
|
||||
OverallStatus: AllocatingEndpoint,
|
||||
}
|
||||
}
|
||||
|
||||
// TODO (dylan): doc comments
|
||||
type PeerRelayClientAllocStatus int
|
||||
|
||||
const (
|
||||
// EndpointAllocRequestSent from the allocating client to the peer relay server via DERP
|
||||
EndpointAllocRequestSent PeerRelayClientAllocStatus = iota
|
||||
// EndpointAllocResponseReceived by the allocating client from the peer relay server via DERP
|
||||
EndpointAllocResponseReceived
|
||||
// CallMeMaybeViaSent from the allocating client to the target client via DERP
|
||||
CallMeMaybeViaSent
|
||||
// CallMeMaybeViaReceived by the target client from the allocating client via DERP
|
||||
CallMeMaybeViaReceived
|
||||
)
|
||||
|
||||
// TODO (dylan): doc comments
|
||||
type PeerRelayClientBindStatus int
|
||||
|
||||
const (
|
||||
// EndpointBindHandshakeSent from this client to the peer relay server
|
||||
EndpointBindHandshakeSent PeerRelayClientBindStatus = iota
|
||||
// EndpointBindChallengeReceived by this client from the peer relay server
|
||||
EndpointBindChallengeReceived
|
||||
// EndpointBindAnswerSent from this client to the peer relay server
|
||||
EndpointBindAnswerSent
|
||||
)
|
||||
|
||||
// TODO (dylan): doc comments
|
||||
type PeerRelayClientPingStatus int
|
||||
|
||||
// TODO (dylan): doc comments
|
||||
const (
|
||||
DiscoPingSent PeerRelayClientPingStatus = iota
|
||||
DiscoPingReceived
|
||||
)
|
||||
|
||||
// TODO (dylan): doc comments
|
||||
type PeerRelayClientStatus int
|
||||
|
||||
// TODO (dylan): doc comments
|
||||
const (
|
||||
EndpointAllocation PeerRelayClientStatus = iota
|
||||
EndpointBinding
|
||||
Pinging
|
||||
ClientSessionEstablished
|
||||
)
|
||||
|
||||
// TODO (dylan): doc comments
|
||||
type PeerRelayClientSessionStatus struct {
|
||||
AllocStatus PeerRelayClientAllocStatus
|
||||
BindStatus PeerRelayClientBindStatus
|
||||
PingStatus PeerRelayClientPingStatus
|
||||
|
||||
OverallStatus PeerRelayClientStatus
|
||||
}
|
||||
|
||||
// TODO (dylan): doc comments
|
||||
type PeerRelaySessionBaseStatus struct {
|
||||
VNI uint32
|
||||
ClientShortDisco [2]string
|
||||
ClientEndpoint [2]netip.AddrPort
|
||||
ServerShortDisco string
|
||||
ServerEndpoint netip.AddrPort
|
||||
}
|
||||
|
||||
// TODO (dylan): doc comments
|
||||
type PeerRelayServerSession struct {
|
||||
Status PeerRelayServerSessionStatus
|
||||
PeerRelaySessionBaseStatus
|
||||
}
|
||||
|
||||
// TODO (dylan): doc comments
|
||||
type PeerRelayClientSession struct {
|
||||
Status PeerRelayClientStatus
|
||||
PeerRelaySessionBaseStatus
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ import (
|
||||
"tailscale.com/net/packet"
|
||||
"tailscale.com/net/stun"
|
||||
"tailscale.com/net/udprelay/endpoint"
|
||||
"tailscale.com/net/udprelay/status"
|
||||
"tailscale.com/tstime"
|
||||
"tailscale.com/types/key"
|
||||
"tailscale.com/types/logger"
|
||||
@ -95,7 +96,7 @@ type serverEndpoint struct {
|
||||
vni uint32
|
||||
allocatedAt time.Time
|
||||
|
||||
status endpoint.PeerRelayServerSessionStatus
|
||||
status status.SessionStatus
|
||||
}
|
||||
|
||||
func (e *serverEndpoint) handleDiscoControlMsg(from netip.AddrPort, senderIndex int, discoMsg disco.Message, conn *net.UDPConn, serverDisco key.DiscoPublic) {
|
||||
@ -137,7 +138,7 @@ func (e *serverEndpoint) handleDiscoControlMsg(from netip.AddrPort, senderIndex
|
||||
e.handshakeAddrPorts[senderIndex] = from
|
||||
// TODO (dylan): assert current e.status.AllocStatus is EndpointAllocated
|
||||
// TODO (dylan): assert e.status.ClientBindStatus[senderIndex] is not already EndpointBindRequestReceived or later
|
||||
e.status.ClientBindStatus[senderIndex] = endpoint.EndpointBindRequestReceived
|
||||
e.status.ClientBindStatus[senderIndex] = status.EndpointBindRequestReceived
|
||||
m := new(disco.BindUDPRelayEndpointChallenge)
|
||||
m.VNI = e.vni
|
||||
m.Generation = discoMsg.Generation
|
||||
@ -155,8 +156,8 @@ func (e *serverEndpoint) handleDiscoControlMsg(from netip.AddrPort, senderIndex
|
||||
box := e.discoSharedSecrets[senderIndex].Seal(m.AppendMarshal(nil))
|
||||
reply = append(reply, box...)
|
||||
conn.WriteMsgUDPAddrPort(reply, nil, from)
|
||||
e.status.ClientBindStatus[senderIndex] = endpoint.EndpointBindChallengeSent
|
||||
e.status.OverallStatus = endpoint.BindingEndpoint
|
||||
e.status.ClientBindStatus[senderIndex] = status.EndpointBindChallengeSent
|
||||
e.status.OverallStatus = status.Binding
|
||||
return
|
||||
case *disco.BindUDPRelayEndpointAnswer:
|
||||
err := validateVNIAndRemoteKey(discoMsg.BindUDPRelayEndpointCommon)
|
||||
@ -176,11 +177,11 @@ func (e *serverEndpoint) handleDiscoControlMsg(from netip.AddrPort, senderIndex
|
||||
e.boundAddrPorts[senderIndex] = from
|
||||
|
||||
// TODO (dylan): assert e.status.AllocStatus is EndpointAllocated
|
||||
// TODO (dylan): assert e.status.ClientBindStatus[senderIndex] is endpoint.EndpointBindChallengeSent
|
||||
// TODO (dylan): assert e.status.ClientBindStatus[senderIndex] is status.EndpointBindChallengeSent
|
||||
// TODO (dylan): assert e.status.ClientBindStatus[senderIndex] is not already EndpointBindAnswerReceived or later
|
||||
e.status.ClientBindStatus[senderIndex] = endpoint.EndpointBindAnswerReceived
|
||||
e.status.ClientBindStatus[senderIndex] = status.EndpointBindAnswerReceived
|
||||
if e.isBound() {
|
||||
e.status.OverallStatus = endpoint.BidirectionalPinging
|
||||
e.status.OverallStatus = status.Pinging
|
||||
}
|
||||
e.lastSeen[senderIndex] = time.Now() // record last seen as bound time
|
||||
return
|
||||
@ -237,10 +238,10 @@ func (e *serverEndpoint) handlePacket(from netip.AddrPort, gh packet.GeneveHeade
|
||||
to = e.boundAddrPorts[1]
|
||||
e.status.ClientPacketsRx[0]++
|
||||
switch e.status.ClientPingStatus[0] {
|
||||
case endpoint.DiscoPingNotStarted:
|
||||
e.status.ClientPingStatus[0] = endpoint.DiscoPingSeen
|
||||
case endpoint.DiscoPingSeen:
|
||||
e.status.ClientPingStatus[0] = endpoint.DiscoPongSeen
|
||||
case status.DiscoPingNotStarted:
|
||||
e.status.ClientPingStatus[0] = status.DiscoPingSeen
|
||||
case status.DiscoPingSeen:
|
||||
e.status.ClientPingStatus[0] = status.DiscoPongSeen
|
||||
default:
|
||||
break
|
||||
}
|
||||
@ -250,10 +251,10 @@ func (e *serverEndpoint) handlePacket(from netip.AddrPort, gh packet.GeneveHeade
|
||||
to = e.boundAddrPorts[0]
|
||||
e.status.ClientPacketsRx[1]++
|
||||
switch e.status.ClientPingStatus[1] {
|
||||
case endpoint.DiscoPingNotStarted:
|
||||
e.status.ClientPingStatus[1] = endpoint.DiscoPingSeen
|
||||
case endpoint.DiscoPingSeen:
|
||||
e.status.ClientPingStatus[1] = endpoint.DiscoPongSeen
|
||||
case status.DiscoPingNotStarted:
|
||||
e.status.ClientPingStatus[1] = status.DiscoPingSeen
|
||||
case status.DiscoPingSeen:
|
||||
e.status.ClientPingStatus[1] = status.DiscoPongSeen
|
||||
default:
|
||||
break
|
||||
}
|
||||
@ -263,8 +264,8 @@ func (e *serverEndpoint) handlePacket(from netip.AddrPort, gh packet.GeneveHeade
|
||||
return
|
||||
}
|
||||
|
||||
if e.status.OverallStatus == endpoint.BidirectionalPinging && e.status.ClientPingStatus[0] == endpoint.DiscoPongSeen && e.status.ClientPingStatus[1] == endpoint.DiscoPongSeen {
|
||||
e.status.OverallStatus = endpoint.ServerSessionEstablished
|
||||
if e.status.OverallStatus == status.Pinging && e.status.ClientPingStatus[0] == status.DiscoPongSeen && e.status.ClientPingStatus[1] == status.DiscoPongSeen {
|
||||
e.status.OverallStatus = status.Established
|
||||
}
|
||||
// Relay the packet towards the other party via the socket associated
|
||||
// with the destination's address family. If source and destination
|
||||
@ -680,13 +681,14 @@ func (s *Server) AllocateEndpoint(discoA, discoB key.DiscoPublic) (endpoint.Serv
|
||||
}
|
||||
|
||||
s.lamportID++
|
||||
status := endpoint.NewPeerRelayServerSessionStatus()
|
||||
status.AllocStatus = endpoint.EndpointAllocRequestReceived
|
||||
st := status.NewSessionStatus()
|
||||
st.AllocStatus = status.EndpointAllocRequestReceived
|
||||
st.OverallStatus = status.Allocating
|
||||
e = &serverEndpoint{
|
||||
discoPubKeys: pair,
|
||||
lamportID: s.lamportID,
|
||||
allocatedAt: time.Now(),
|
||||
status: status,
|
||||
status: st,
|
||||
}
|
||||
e.discoSharedSecrets[0] = s.disco.Shared(e.discoPubKeys.Get()[0])
|
||||
e.discoSharedSecrets[1] = s.disco.Shared(e.discoPubKeys.Get()[1])
|
||||
@ -707,8 +709,9 @@ func (s *Server) AllocateEndpoint(discoA, discoB key.DiscoPublic) (endpoint.Serv
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) GetSessions() ([]endpoint.PeerRelayServerSession, error) {
|
||||
var sessions = make([]endpoint.PeerRelayServerSession, 0)
|
||||
// TODO (dylan): doc comments
|
||||
func (s *Server) GetSessions() ([]status.ServerSession, error) {
|
||||
var sessions = make([]status.ServerSession, 0)
|
||||
for k, v := range s.byDisco {
|
||||
var c1Ep, c2Ep netip.AddrPort
|
||||
|
||||
@ -725,17 +728,15 @@ func (s *Server) GetSessions() ([]endpoint.PeerRelayServerSession, error) {
|
||||
} else if v.handshakeAddrPorts[1].IsValid() {
|
||||
c2Ep = v.handshakeAddrPorts[1]
|
||||
}
|
||||
sessions = append(sessions, endpoint.PeerRelayServerSession{
|
||||
sessions = append(sessions, status.ServerSession{
|
||||
// TODO (dylan): fix overall status
|
||||
Status: v.status,
|
||||
PeerRelaySessionBaseStatus: endpoint.PeerRelaySessionBaseStatus{
|
||||
VNI: v.vni,
|
||||
ClientShortDisco: [2]string{c1Disco, c2Disco},
|
||||
ClientEndpoint: [2]netip.AddrPort{c1Ep, c2Ep},
|
||||
ServerShortDisco: s.discoPublic.ShortString(),
|
||||
// TODO (dylan): disambiguate which addrPort to use here
|
||||
ServerEndpoint: s.addrPorts[0],
|
||||
},
|
||||
Status: v.status,
|
||||
VNI: v.vni,
|
||||
ClientShortDisco: [2]string{c1Disco, c2Disco},
|
||||
ClientEndpoint: [2]netip.AddrPort{c1Ep, c2Ep},
|
||||
ServerShortDisco: s.discoPublic.ShortString(),
|
||||
// TODO (dylan): disambiguate which addrPort to use here
|
||||
ServerEndpoint: s.addrPorts[0],
|
||||
})
|
||||
}
|
||||
return sessions, nil
|
||||
|
184
net/udprelay/status/status.go
Normal file
184
net/udprelay/status/status.go
Normal file
@ -0,0 +1,184 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
// Package status contains types relating to the status of peer relay sessions
|
||||
// between nodes via a peer relay server.
|
||||
package status
|
||||
|
||||
import "net/netip"
|
||||
|
||||
// ServerSession contains status information for a single session between two
|
||||
// peer relay clients relayed via a peer relay server. This is the status as
|
||||
// seen by the peer relay server; each client node may have a different view of
|
||||
// the session's current status.
|
||||
type ServerSession struct {
|
||||
// Status is the current state of the session, as seen by the peer relay
|
||||
// server. It contains the status of each phase of session setup and usage:
|
||||
// endpoint allocation, endpoint binding, disco ping/pong, and active.
|
||||
// TODO (dylan): confirm these statuses/state machines
|
||||
Status SessionStatus
|
||||
// VNI is the Virtual Network Identifier for this peer relay session, which
|
||||
// comes from the Geneve header and is unique to this session.
|
||||
VNI uint32
|
||||
// ClientShortDisco is a string representation of each peer relay client's
|
||||
// disco public key (one string for each of the two clients).
|
||||
// TODO (dylan): can either of these ever be nil?
|
||||
ClientShortDisco [2]string
|
||||
// ClientEndpoint is the [netip.AddrPort] of each peer relay client's
|
||||
// endpoint participating in the session (one endpoint for each of the two
|
||||
// clients).
|
||||
// TODO (dylan): can either of these ever be nil?
|
||||
ClientEndpoint [2]netip.AddrPort
|
||||
// ServerShortDisco is a string representation of the peer relay server's
|
||||
// disco public key.
|
||||
// TODO (dylan): can there be a different disco key per-client?
|
||||
ServerShortDisco string
|
||||
// ServerEndpoint is the [netip.AddrPort] for the peer relay server's
|
||||
// endpoint participating in the session (one endpoint for each of the two
|
||||
// clients).
|
||||
// TODO (dylan): can there be a different endpoint per-client?
|
||||
ServerEndpoint netip.AddrPort
|
||||
}
|
||||
|
||||
// TODO (dylan): doc comments
|
||||
type SessionStatus struct {
|
||||
AllocStatus AllocStatus
|
||||
ClientBindStatus [2]BindStatus
|
||||
ClientPingStatus [2]PingStatus
|
||||
ClientPacketsRx [2]uint64
|
||||
ClientPacketsFwd [2]uint64
|
||||
|
||||
OverallStatus OverallSessionStatus
|
||||
}
|
||||
|
||||
// TODO (dylan): doc comments
|
||||
func NewSessionStatus() SessionStatus {
|
||||
return SessionStatus{
|
||||
AllocStatus: EndpointAllocNotStarted,
|
||||
ClientBindStatus: [2]BindStatus{EndpointBindNotStarted, EndpointBindNotStarted},
|
||||
ClientPingStatus: [2]PingStatus{DiscoPingNotStarted, DiscoPingNotStarted},
|
||||
OverallStatus: Allocating,
|
||||
}
|
||||
}
|
||||
|
||||
// TODO (dylan): doc comments
|
||||
type AllocStatus int
|
||||
|
||||
// TODO (dylan): doc comments
|
||||
const (
|
||||
EndpointAllocNotStarted AllocStatus = iota
|
||||
// EndpointAllocRequestReceived by the peer relay server from the allocating client
|
||||
EndpointAllocRequestReceived
|
||||
// EndpointAllocated on the peer relay server, but response not yet sent to allocating client
|
||||
EndpointAllocated
|
||||
// EndpointAllocResponseSent from the peer relay server to allocating client
|
||||
EndpointAllocResponseSent
|
||||
|
||||
// TODO (dylan): Should we have a status here for dead allocs that weren't bound before the
|
||||
// BindLifetime timer expired?
|
||||
EndpointAllocExpired
|
||||
)
|
||||
|
||||
func (s AllocStatus) String() string {
|
||||
switch s {
|
||||
case EndpointAllocNotStarted:
|
||||
return "alloc not started"
|
||||
case EndpointAllocRequestReceived:
|
||||
return "alloc request received"
|
||||
case EndpointAllocated:
|
||||
return "endpoint allocated"
|
||||
case EndpointAllocResponseSent:
|
||||
return "alloc complete"
|
||||
case EndpointAllocExpired:
|
||||
return "expired"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
// BindStatus is the current status of the endpoint binding handshake between
|
||||
// the peer relay server and a SINGLE peer relay client. Both clients need to
|
||||
// bind into an endpoint for a peer relay session to be bound, so a peer relay
|
||||
// server will have two BindStatus fields to track per session.
|
||||
type BindStatus int
|
||||
|
||||
// TODO (dylan): doc comments
|
||||
const (
|
||||
EndpointBindNotStarted BindStatus = iota
|
||||
EndpointBindRequestReceived
|
||||
EndpointBindChallengeSent
|
||||
EndpointBindAnswerReceived
|
||||
)
|
||||
|
||||
func (s BindStatus) String() string {
|
||||
switch s {
|
||||
case EndpointBindNotStarted:
|
||||
return "binding not started"
|
||||
case EndpointBindRequestReceived:
|
||||
return "bind request received"
|
||||
case EndpointBindChallengeSent:
|
||||
return "bind challenge sent"
|
||||
case EndpointBindAnswerReceived:
|
||||
return "bind complete"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
// PingStatus is the current status of a SINGLE SIDE of the
|
||||
// bidirectional disco ping exchange between two peer relay clients, as seen by
|
||||
// the peer relay server. As each client will send a disco ping and should
|
||||
// receive a disco pong from the other client in response, a peer relay server
|
||||
// will have two PingStatus fields to track per session.
|
||||
type PingStatus int
|
||||
|
||||
// TODO (dylan): doc comments
|
||||
const (
|
||||
DiscoPingNotStarted PingStatus = iota
|
||||
DiscoPingSeen
|
||||
DiscoPongSeen
|
||||
)
|
||||
|
||||
// TODO (dylan): doc comments
|
||||
func (s PingStatus) String() string {
|
||||
switch s {
|
||||
case DiscoPingNotStarted:
|
||||
return "ping not started"
|
||||
case DiscoPingSeen:
|
||||
return "disco ping seen"
|
||||
case DiscoPongSeen:
|
||||
return "disco pong seen"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
// TODO (dylan): doc comments
|
||||
type OverallSessionStatus int
|
||||
|
||||
// TODO (dylan): doc comments
|
||||
const (
|
||||
NotStarted OverallSessionStatus = iota
|
||||
Allocating
|
||||
Binding
|
||||
Pinging
|
||||
Established
|
||||
Idle
|
||||
)
|
||||
|
||||
// String returns a short, human-readable string representation of the current
|
||||
// [OverallSessionStatus].
|
||||
func (s OverallSessionStatus) String() string {
|
||||
switch s {
|
||||
case Allocating:
|
||||
return "allocating endpoint"
|
||||
case Binding:
|
||||
return "binding endpoint"
|
||||
case Pinging:
|
||||
return "clients pinging"
|
||||
case Established:
|
||||
return "session established"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user