Files
rdp-proxy/agents/rap-node-agent/internal/mesh/contracts.go
T

304 lines
13 KiB
Go

package mesh
import (
"encoding/json"
"errors"
"time"
)
const ProtocolVersion = "mesh-control-v1"
var (
ErrClusterMismatch = errors.New("mesh peer cluster mismatch")
ErrNodeMismatch = errors.New("mesh peer node mismatch")
ErrForwardDisabled = errors.New("production payload forwarding is disabled by mesh production gate")
ErrForwardRuntimeUnavailable = errors.New("production mesh forwarding runtime is unavailable for this route or stage")
ErrForwardPeerUnavailable = errors.New("production mesh next peer is unavailable")
ErrForwardEnvelopeInvalid = errors.New("production mesh envelope is invalid")
ErrForwardObservationFailed = errors.New("production mesh envelope observation failed")
ErrForwardDeliveryFailed = errors.New("production mesh envelope delivery failed")
ErrMeshRuntimeDisabled = errors.New("mesh synthetic runtime is disabled")
ErrUnsupportedSyntheticMessage = errors.New("unsupported synthetic mesh message")
ErrRouteIDRequired = errors.New("mesh synthetic route id is required")
ErrRouteNotFound = errors.New("mesh synthetic route not found")
ErrInvalidRoutePath = errors.New("mesh synthetic route path is invalid")
ErrRouteExpired = errors.New("mesh synthetic route is expired")
ErrTTLExhausted = errors.New("mesh synthetic route ttl exhausted")
ErrLoopDetected = errors.New("mesh synthetic route loop detected")
ErrUnauthorizedChannel = errors.New("mesh synthetic channel is not authorized")
ErrSyntheticPeerUnavailable = errors.New("mesh synthetic next peer is unavailable")
ErrNoHealthySyntheticRoute = errors.New("mesh synthetic no healthy route available")
ErrSyntheticRelayQueueFull = errors.New("mesh synthetic relay queue is full")
ErrSyntheticRelayQueueEmpty = errors.New("mesh synthetic relay queue is empty")
ErrSyntheticPayloadTooLarge = errors.New("mesh synthetic payload is too large")
ErrSyntheticOrganizationMismatch = errors.New("mesh synthetic organization mismatch")
ErrUnsupportedSyntheticService = errors.New("unsupported synthetic test service")
ErrSyntheticRequestInvalid = errors.New("mesh synthetic request is invalid")
)
const (
SyntheticMessageProbe = "fabric.probe"
SyntheticMessageProbeAck = "fabric.probe_ack"
SyntheticMessageRouteHealth = "fabric.route_health"
SyntheticMessageRouteHealthAck = "fabric.route_health_ack"
SyntheticMessageTelemetry = "fabric.telemetry"
SyntheticMessageTestService = "fabric.test_service"
SyntheticMessageTestServiceAck = "fabric.test_service_ack"
SyntheticTestServiceType = "synthetic.echo"
SyntheticDefaultTestOrganizationID = "org-test"
SyntheticDefaultMaxTestPayloadBytes = 4096
SyntheticChannelFabricControl = "fabric_control"
SyntheticChannelRouteControl = "route_control"
SyntheticChannelTelemetry = "telemetry"
SyntheticRouteStateUnknown = "unknown"
SyntheticRouteStateHealthy = "healthy"
SyntheticRouteStateDegraded = "degraded"
SyntheticRouteStateFailed = "failed"
ProductionChannelFabricControl = "fabric_control"
ProductionMessageFabricControl = "fabric.control"
ProductionChannelVPNPacket = "vpn_packet"
ProductionMessageVPNPacketBatch = "vpn.packet_batch"
FabricServiceClassVPNPackets = "vpn_packets"
FabricServiceClassRemoteWorkspace = "remote_workspace"
FabricServiceChannelBulk = "bulk"
FabricServiceChannelControl = "control"
FabricServiceChannelInteractive = "interactive"
FabricServiceChannelReliable = "reliable"
FabricServiceChannelDroppable = "droppable"
MaxProductionEnvelopePayloadBytes = 4096
MaxProductionVPNPacketPayloadBytes = 256 * 1024
MaxProductionEnvelopeFutureSkew = time.Minute
ProductionForwardQUICStreamID = 1
WebIngressForwardQUICStreamID = 2
FabricControlForwardQUICStreamID = 3
SyntheticForwardQUICStreamID = 1001
)
type PeerIdentity struct {
ClusterID string `json:"cluster_id"`
NodeID string `json:"node_id"`
}
type SyntheticRoute struct {
RouteID string `json:"route_id"`
ClusterID string `json:"cluster_id"`
SourceNodeID string `json:"source_node_id"`
DestinationNodeID string `json:"destination_node_id"`
Hops []string `json:"hops"`
AllowedChannels []string `json:"allowed_channels"`
ExpiresAt time.Time `json:"expires_at"`
MaxTTL int `json:"max_ttl"`
MaxHops int `json:"max_hops"`
RouteVersion string `json:"route_version,omitempty"`
PolicyVersion string `json:"policy_version,omitempty"`
PeerDirectoryVersion string `json:"peer_directory_version,omitempty"`
}
type SyntheticEnvelope struct {
ProtocolVersion string `json:"protocol_version"`
RouteID string `json:"route_id"`
ClusterID string `json:"cluster_id"`
From PeerIdentity `json:"from"`
To PeerIdentity `json:"to"`
Channel string `json:"channel"`
MessageType string `json:"message_type"`
TTL int `json:"ttl"`
HopCount int `json:"hop_count"`
Visited []string `json:"visited"`
Sequence uint64 `json:"sequence"`
SentAt time.Time `json:"sent_at"`
Payload json.RawMessage `json:"payload,omitempty"`
}
type SyntheticProbePayload struct {
ProbeID string `json:"probe_id"`
SentAt time.Time `json:"sent_at"`
}
type SyntheticProbeAckPayload struct {
ProbeID string `json:"probe_id"`
Path []string `json:"path"`
AcceptedAt time.Time `json:"accepted_at"`
}
type SyntheticRouteObservation struct {
RouteID string `json:"route_id"`
State string `json:"state"`
LastSuccessAt time.Time `json:"last_success_at,omitempty"`
LastFailureAt time.Time `json:"last_failure_at,omitempty"`
LastFailureReason string `json:"last_failure_reason,omitempty"`
SuccessCount uint64 `json:"success_count"`
FailureCount uint64 `json:"failure_count"`
LastLatencyMs int64 `json:"last_latency_ms,omitempty"`
RouteVersion string `json:"route_version,omitempty"`
PolicyVersion string `json:"policy_version,omitempty"`
PeerDirectoryVersion string `json:"peer_directory_version,omitempty"`
}
type SyntheticRouteHealthResult struct {
RequestedRouteID string `json:"requested_route_id"`
SelectedRouteID string `json:"selected_route_id"`
FallbackUsed bool `json:"fallback_used"`
Ack SyntheticEnvelope `json:"ack"`
Observation SyntheticRouteObservation `json:"observation"`
}
type SyntheticTestServiceRequest struct {
RequestID string `json:"request_id"`
OrganizationID string `json:"organization_id"`
ServiceType string `json:"service_type"`
Payload string `json:"payload"`
SentAt time.Time `json:"sent_at"`
}
type SyntheticTestServiceResponse struct {
RequestID string `json:"request_id"`
OrganizationID string `json:"organization_id"`
ServiceType string `json:"service_type"`
EchoPayload string `json:"echo_payload"`
Path []string `json:"path"`
AcceptedAt time.Time `json:"accepted_at"`
}
type SyntheticTestServiceResult struct {
RequestedRouteID string `json:"requested_route_id"`
SelectedRouteID string `json:"selected_route_id"`
FallbackUsed bool `json:"fallback_used"`
Ack SyntheticEnvelope `json:"ack"`
Response SyntheticTestServiceResponse `json:"response"`
Observation SyntheticRouteObservation `json:"observation"`
}
type SyntheticRouteCacheVersion struct {
RouteVersion string `json:"route_version,omitempty"`
PolicyVersion string `json:"policy_version,omitempty"`
PeerDirectoryVersion string `json:"peer_directory_version,omitempty"`
}
type SyntheticRelayQueuePolicy struct {
Channel string `json:"channel"`
Capacity int `json:"capacity"`
Droppable bool `json:"droppable"`
}
type SyntheticRelayEnqueueResult struct {
Channel string `json:"channel"`
QueueDepth int `json:"queue_depth"`
QueueCapacity int `json:"queue_capacity"`
Dropped bool `json:"dropped"`
DroppedSequence uint64 `json:"dropped_sequence,omitempty"`
AcceptedSequence uint64 `json:"accepted_sequence"`
}
type SyntheticRelayQueueMetrics struct {
Enqueued uint64 `json:"enqueued"`
Dequeued uint64 `json:"dequeued"`
Dropped uint64 `json:"dropped"`
Rejected uint64 `json:"rejected"`
LastRejectReason string `json:"last_reject_reason,omitempty"`
QueueDepths map[string]int `json:"queue_depths"`
}
type HealthMessage struct {
ProtocolVersion string `json:"protocol_version"`
From PeerIdentity `json:"from"`
To PeerIdentity `json:"to"`
ObservedAt time.Time `json:"observed_at"`
LinkStatus string `json:"link_status"`
LatencyMs *int `json:"latency_ms,omitempty"`
QualityScore *int `json:"quality_score,omitempty"`
}
type HealthAck struct {
ProtocolVersion string `json:"protocol_version"`
Accepted bool `json:"accepted"`
By PeerIdentity `json:"by"`
}
type ProductionEnvelope struct {
FabricProtocolVersion string `json:"fabric_protocol_version"`
MessageID string `json:"message_id"`
RouteID string `json:"route_id"`
ClusterID string `json:"cluster_id"`
SourceNodeID string `json:"source_node_id"`
DestinationNodeID string `json:"destination_node_id"`
CurrentHopNodeID string `json:"current_hop_node_id"`
NextHopNodeID string `json:"next_hop_node_id"`
RoutePath []string `json:"route_path,omitempty"`
VisitedNodeIDs []string `json:"visited_node_ids,omitempty"`
ChannelClass string `json:"channel_class"`
MessageType string `json:"message_type"`
TTL int `json:"ttl"`
HopCount int `json:"hop_count"`
CreatedAt time.Time `json:"created_at"`
ExpiresAt time.Time `json:"expires_at"`
PayloadLength int `json:"payload_length"`
PayloadHash string `json:"payload_hash"`
Payload json.RawMessage `json:"payload,omitempty"`
}
type ProductionEnvelopeObservation struct {
MessageID string `json:"message_id"`
RouteID string `json:"route_id"`
ClusterID string `json:"cluster_id"`
SourceNodeID string `json:"source_node_id"`
DestinationNodeID string `json:"destination_node_id"`
CurrentHopNodeID string `json:"current_hop_node_id"`
NextHopNodeID string `json:"next_hop_node_id"`
RoutePath []string `json:"route_path,omitempty"`
VisitedNodeIDs []string `json:"visited_node_ids,omitempty"`
ChannelClass string `json:"channel_class"`
MessageType string `json:"message_type"`
TTL int `json:"ttl"`
HopCount int `json:"hop_count"`
PayloadLength int `json:"payload_length"`
PayloadHash string `json:"payload_hash"`
ObservedAt time.Time `json:"observed_at"`
}
type ProductionForwardResult struct {
Accepted bool `json:"accepted"`
Delivered bool `json:"delivered"`
Forwarded bool `json:"forwarded"`
By PeerIdentity `json:"by"`
MessageID string `json:"message_id"`
RouteID string `json:"route_id"`
NextNodeID string `json:"next_node_id,omitempty"`
}
type ProductionForwardLogEntry struct {
Event string `json:"event"`
RouteID string `json:"route_id,omitempty"`
MessageID string `json:"message_id,omitempty"`
ClusterID string `json:"cluster_id,omitempty"`
LocalNodeID string `json:"local_node_id,omitempty"`
SourceNodeID string `json:"source_node_id,omitempty"`
DestinationNodeID string `json:"destination_node_id,omitempty"`
CurrentHopNodeID string `json:"current_hop_node_id,omitempty"`
NextHopNodeID string `json:"next_hop_node_id,omitempty"`
ChannelClass string `json:"channel_class,omitempty"`
MessageType string `json:"message_type,omitempty"`
Reason string `json:"reason,omitempty"`
StatusCode int `json:"status_code,omitempty"`
TTL int `json:"ttl,omitempty"`
HopCount int `json:"hop_count,omitempty"`
RoutePathLength int `json:"route_path_length,omitempty"`
VisitedCount int `json:"visited_count,omitempty"`
PayloadLength int `json:"payload_length,omitempty"`
OccurredAt time.Time `json:"occurred_at"`
}
func ValidatePeer(local PeerIdentity, remote PeerIdentity) error {
if local.ClusterID == "" || remote.ClusterID == "" || local.ClusterID != remote.ClusterID {
return ErrClusterMismatch
}
if remote.NodeID == "" {
return ErrNodeMismatch
}
return nil
}