package main import "encoding/json" const ( ProtocolVersion = 1 DeviceKind = "native" SecretPrefix = "dpn_" MaxWSFramePayload = 256 * 1024 MaxInboundMessage = 256 * 1024 MaxResultMessage = 3 * 1024 * 1024 DefaultReconnectMin = 1 DefaultReconnectMax = 60 DefaultPingSeconds = 20 DefaultMaxBodyBytes = 2 * 1024 * 1024 DefaultJobTimeout = 25 MaxJobTimeout = 60 HelloTimeoutSeconds = 10 TicketTimeoutSeconds = 15 MissedPingsBeforeDead = 3 UsageIntervalSeconds = 60 MaxRedirects = 5 MaxRequestHeaders = 32 MaxResponseHeaders = 64 MaxHeaderValueBytes = 1024 MaxIDBytes = 64 MaxURLChars = 2048 MaxConcurrentCeiling = 8 MaxTunnelsCeiling = 8 TunnelChunkBytes = 32 * 1024 TunnelQueueDepth = 64 TunnelIdleSeconds = 60 TunnelLifetimeSeconds = 300 TunnelDialSeconds = 10 MaxDonorMBPerDay = 20 * 1024 StableSessionSeconds = 30 FastRetryMillis = 1500 SuspendedReason = "suspended" SuspendedMinSeconds = 60 SuspendedMaxSeconds = 24 * 60 * 60 SuspendedDefaultSeconds = 300 SuspendedJitterSeconds = 30 ) const ( RefuseHost = "host_not_allowed" RefusePort = "port_not_allowed" RefuseAddress = "address_not_public" RefuseRedirect = "redirect_not_allowed" RefuseMethod = "method_not_allowed" RefuseBandwidth = "bandwidth_exhausted" RefuseConcurrency = "concurrency_exceeded" RefuseHours = "outside_hours" RefuseBattery = "on_battery" RefuseTimeout = "timeout" RefuseBadURL = "bad_url" FailFetch = "fetch_failed" FailDNS = "dns_failed" ) const ( CloseNormal = 1000 CloseGoingAway = 1001 CloseProtocolError = 1002 CloseUnsupported = 1003 CloseInvalidPayload = 1007 ClosePolicy = 1008 CloseTooLarge = 1009 CloseTryAgain = 1013 CloseRetryOwner = 4013 CloseCapacity = 4029 CloseProtocol = 4400 CloseKicked = 4403 ) var FatalReasons = map[string]bool{ "revoked": true, "kill_switch": true, "no_consent": true, "no_account": true, "deletion_pending": true, "account_inactive": true, "not_adult": true, "not_enabled": true, "replaced": true, "device": true, } var BakedDestinations = []Destination{ {Suffix: "reddit.com", Adapter: "reddit", Methods: []string{"GET"}, Ports: []int{80, 443}, Modes: []string{"tunnel", "fetch"}}, {Suffix: "redd.it", Adapter: "reddit", Methods: []string{"GET"}, Ports: []int{80, 443}, Modes: []string{"tunnel", "fetch"}}, } var AllowedPorts = []int{80, 443} type Destination struct { Suffix string `json:"suffix"` Adapter string `json:"adapter"` Methods []string `json:"methods"` Ports []int `json:"ports"` Modes []string `json:"modes"` MaxRPS float64 `json:"max_rps"` } type ServerLimits struct { MaxBodyBytes int `json:"max_body_bytes"` MaxConcurrentPerNode int `json:"max_concurrent_per_node"` MaxDonorMBPerDay int `json:"max_donor_mb_per_day"` PingSeconds int `json:"ping_seconds"` ReconnectMinSeconds int `json:"reconnect_min_seconds"` ReconnectMaxSeconds int `json:"reconnect_max_seconds"` JobTimeoutSeconds int `json:"job_timeout_seconds"` MaxFrameBytes int `json:"max_frame_bytes"` } type ServerSettings struct { Enabled bool `json:"enabled"` BandwidthMBDay int `json:"bandwidth_mb_day"` MaxConcurrent int `json:"max_concurrent"` ActiveFrom string `json:"active_from"` ActiveTo string `json:"active_to"` Timezone string `json:"timezone"` PauseOnBattery bool `json:"pause_on_battery"` } type Frame struct { Type string `json:"type"` JobID string `json:"job_id"` Method string `json:"method"` URL string `json:"url"` Headers map[string]any `json:"headers"` Timeout int `json:"timeout"` ConnID string `json:"conn_id"` Host string `json:"host"` Port int `json:"port"` B64 string `json:"b64"` Reason string `json:"reason"` Until string `json:"until"` DeviceLabel string `json:"device_label"` DeviceUID string `json:"device_uid"` Limits *ServerLimits `json:"limits"` Destinations []Destination `json:"destinations"` Settings *ServerSettings `json:"settings"` } func decodeFrame(raw []byte) (Frame, error) { var frame Frame if err := json.Unmarshal(raw, &frame); err != nil { return frame, err } return frame, nil }