proxy

package
v0.0.0-...-88c6f0b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 25, 2026 License: GPL-3.0 Imports: 44 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// ConnectionTestURL answers 204 with no body; requesting it through the
	// tunnel measures the full data path without downloading anything.
	ConnectionTestURL     = "https://www.google.com/generate_204"
	ConnectionTestTimeout = 15 * time.Second
)
View Source
const (
	// FailureNoNetwork: this device has no working network (no route, or
	// names do not resolve).
	FailureNoNetwork = "no_network"
	// FailureUnreachable: Mozilla's servers did not answer or the
	// connection was cut (timeouts, resets, failed TLS handshakes), as on
	// a network that blocks them.
	FailureUnreachable = "unreachable"
	// FailureRefused: a Mozilla proxy server refused the tunnel.
	FailureRefused = "refused"
	// FailureLocationRefused: the server of a location the user chose
	// kept refusing the tunnel (CONNECT 403 or 407) with a proxy pass
	// fetched after the first refusal: Mozilla does not let this account
	// use this location (LocationRefusedError).
	FailureLocationRefused = "location_refused"
	// FailureSignIn: the account must sign in again.
	FailureSignIn = "sign_in"
	// FailureQuota: the account's monthly data is used up.
	FailureQuota = "quota"
	// FailureNotEntitled: Mozilla does not let the account use the VPN.
	FailureNotEntitled = "not_entitled"
	// FailureRegion: Mozilla refuses requests from this region (HTTP 451).
	FailureRegion = "region"
	// FailureServer: Mozilla's service answered with a server error.
	FailureServer = "server"
	// FailureNoAccount: no account can be used now.
	FailureNoAccount = "no_account"
	// FailureTestSite: the tunnel opened, but the test site failed.
	FailureTestSite = "test_site"
	// FailureOther: anything else; the error text says what.
	FailureOther = "other"
)

Failure codes say why a connection through Mozilla failed, so the apps can tell the user in their language what is wrong instead of always blaming the internet; the error text stays for the details. The status view's wake_error_code and the connection test's error_code carry them.

View Source
const (
	// NoticePort is a CONNECT to a port Mozilla's proxy refuses; Detail is
	// the port.
	NoticePort = "port"
	// NoticeCommand is a SOCKS command other than CONNECT, such as UDP
	// ASSOCIATE; Detail names it.
	NoticeCommand = "command"
	// NoticeLoop is this program's own connections coming back to its
	// proxy as a client's (loopWatch); Detail is empty.
	NoticeLoop = "loop"
)

Notice kinds.

View Source
const (
	// StatusSleeping: the proxy listens but holds no upstream session or
	// pass (not connected yet, or asleep after proxy.idle_sleep).
	StatusSleeping = "sleeping"
	// StatusClosed: the proxy stopped.
	StatusClosed = "closed"
)

Status-file reasons written without a controller.

View Source
const (

	// APIRequestTimeout bounds a single control plane API call (FxA,
	// Guardian, Remote Settings); the shared client adds its own safety
	// timeout on top, and FxA calls extend it while solving the Fastly
	// anti-bot challenge.
	APIRequestTimeout = 15 * time.Second
)
View Source
const (
	AccountSkipped accountOutcome
)
View Source
const DNSPort = "53"

DNSPort is DNS's port, which Mozilla's proxy does not connect to. A client's DNS sent through the proxy over TCP (PassWall2's remote DNS, v2rayN's and Clash's DNS through a SOCKS outbound) is therefore answered here: each query goes, as it is, to DNS over HTTPS through Mozilla, and the answer comes back to the client (RoutedOpener).

View Source
const FastestCountry = "fastest"

FastestCountry is the proxy.country value that picks the location with the lowest measured latency at every engine start.

View Source
const (
	PassRenewTimeout = 2 * time.Minute
)
View Source
const (
	// PingTarget is reached through every location; Google answers close to
	// every exit, so the time mostly reflects the path to that exit.
	PingTarget = "www.google.com:443"
)
View Source
const UpstreamPortsText = "80, 443, 8080, and 8443"

UpstreamPortsText lists upstreamPorts for messages.

Variables

View Source
var DeviceRegistration = func() *atomic.Bool { var b atomic.Bool; b.Store(true); return &b }()

DeviceRegistration enables the connected-services device record; tests turn it off so no background request outlives their mock transport.

View Source
var ErrBlockedByRule = errors.New("refused by a routing rule")

ErrBlockedByRule is a connection refused by a routing rule.

View Source
var ErrNoNetwork = &net.OpError{Op: "dial", Err: &os.SyscallError{Syscall: "connect", Err: noNetworkErrnos[0]}}

ErrNoNetwork: the device reported that no network is connected.

View Source
var (
	ErrNoUsableSession = errors.New("no usable upstream proxy session")
)
View Source
var ErrThisMachine = fmt.Errorf("%w: the proxy does not connect to this machine itself", ErrBlockedByRule)

ErrThisMachine is a direct connection from another device to this machine itself, which the proxy refuses whatever the rules say (refuseThisMachine).

View Source
var (
	// GuardianRetryInitialDelay and guardianRetryBudget bound the retries
	// of a transient ProxyPass fetch failure, matching Firefox (500 ms
	// doubling backoff inside a 30 s budget). Tests may shorten them.
	GuardianRetryInitialDelay = 500 * time.Millisecond
)

Functions

func AccountUsage

func AccountUsage(u *guardian.ProxyUsage) accounts.Usage

func Carried

func Carried(host, port string) bool

Carried reports whether a connection to host:port can go through Mozilla's proxy: one of its ports, or GitHub's SSH (throughMozilla).

func ExitProbeHost

func ExitProbeHost(rawURL string) string

func FailureCode

func FailureCode(err error) string

FailureCode classifies err, a failure to reach a site through Mozilla, into one of the Failure codes; "" for nil.

func FreshRuntimeAuth

func FreshRuntimeAuth(ctx context.Context, auth *runtimeAuth) (*runtimeAuth, error)

FreshRuntimeAuth returns auth when its access token is still valid and a refreshed auth otherwise.

func GuardianFailureHint

func GuardianFailureHint(err error) string

GuardianFailureHint explains Guardian failures that retrying cannot fix.

func LastingWakeFailure

func LastingWakeFailure(err error, now time.Time) bool

LastingWakeFailure reports a failure whose WakeRetryDelay holds for connection tests too: retrying it before then cannot succeed.

func LogPassTimeCorrection

func LogPassTimeCorrection(pass *guardian.ProxyPassInfo)

func NormalizeURL

func NormalizeURL(raw string) (*url.URL, error)

func PortAllowed

func PortAllowed(port string) bool

PortAllowed reports whether Mozilla's proxy connects to port.

func RenewalRetryDelay

func RenewalRetryDelay(err error, now time.Time) time.Duration

RenewalRetryDelay decides when a failed renewal is attempted again. Failures that retrying cannot fix soon back off for a long time instead of polling Guardian every proxyPassRetryDelay; a spent quota waits for its announced reset.

func SOCKSCredentials

func SOCKSCredentials(username, password string) *socksCredentials

func SaveSelection

func SaveSelection(path string, candidate Candidate) error

func ServeSOCKS

func ServeSOCKS(ln net.Listener, server *SOCKSServer)

ServeSOCKS accepts clients until the listener is closed, backing off on transient accept errors.

func SessionReplaced

func SessionReplaced(text string) bool

SessionReplaced reports an error text of a request whose upstream session was closed under it because another replaced it (Go's HTTP/2 client says "client connection force closed").

func SetUpstreamRoots

func SetUpstreamRoots(pool *x509.CertPool)

SetUpstreamRoots makes upstream sessions trust only pool (nil restores the system roots). It exists for tests in other packages that run a local upstream fixture.

func TunnelMeter

func TunnelMeter(token string) pingMeter

TunnelMeter measures through a fresh HTTP/2 session per location, using the given proxy pass. Only the CONNECT round trips are timed.

func WakeRetryDelay

func WakeRetryDelay(err error, failures int, now time.Time) time.Duration

WakeRetryDelay is how long client connections wait after the failures-th failed attempt in a row to connect a sleeping proxy to Mozilla before they may cause another (a Guardian request each). It is RenewalRetryDelay for failures that retrying soon cannot fix (sign in again, a spent quota, a refused region, Retry-After); others wait 10 s, doubling with each failure up to 2 min.

func WriteIdleStatus

func WriteIdleStatus(path, reason string) error

WriteIdleStatus writes a status file for a proxy without an upstream session: no pass, not accepting, with reason (StatusSleeping or StatusClosed).

Types

type AccountPool

type AccountPool struct {
	// contains filtered or unexported fields
}

AccountPool connects the stored accounts to ProxyPass acquisition: it asks the manager for the account to use, loads and refreshes its credentials, and records every outcome (quota, rejection, sign-in requirement) so the manager can fail over to the next account.

func NewAccountPool

func NewAccountPool(store *accounts.Store, mgr *accounts.Manager) *AccountPool

func (*AccountPool) AcquirePass

func (p *AccountPool) AcquirePass(ctx context.Context, endpoint string) (*runtimeAuth, *guardian.ProxyPassInfo, error)

AcquirePass returns a usable ProxyPass from the active account or, when that account cannot supply one, from the next usable account in priority order. Failures that affect every account alike (network, Guardian outage, region refusal) are returned without trying other accounts. An account set aside at the switch threshold goes on with the pass it supplied when no other account supplies one after all.

func (*AccountPool) ActiveName

func (p *AccountPool) ActiveName() string

ActiveName returns the display name of the active account.

func (*AccountPool) AuthFor

func (p *AccountPool) AuthFor(acc accounts.Account) (*runtimeAuth, error)

AuthFor returns the cached or stored credentials of an account.

func (*AccountPool) EnsureDevice

func (p *AccountPool) EnsureDevice(ctx context.Context, id string)

EnsureDevice registers this program as "Firefox's built-in VPN" in the account's connected services, once per refresh token.

func (*AccountPool) EnsureDevices

func (p *AccountPool) EnsureDevices(ctx context.Context)

EnsureDevices registers every account that has no device record yet.

func (*AccountPool) Forget

func (p *AccountPool) Forget(id string)

func (*AccountPool) Record

func (p *AccountPool) Record(acc accounts.Account, pass *guardian.ProxyPassInfo, err error) accountOutcome

Record stores the quota state and status that the pass request revealed and classifies the outcome.

func (*AccountPool) RecoverRevoked

func (p *AccountPool) RecoverRevoked(ctx context.Context, acc accounts.Account, cause error)

RecoverRevoked signs an account whose tokens Mozilla refused in again at once, before its access token expires. When that needs the user (no stored password, a confirmation code, a refused password), the account is marked for "Sign in again", except while it is the only account the proxy can use: its access token keeps working until it expires, and the renewal then marks it.

func (*AccountPool) Relogin

func (p *AccountPool) Relogin(ctx context.Context, acc accounts.Account, cause error) (*runtimeAuth, error)

Relogin signs in again with the account's stored password when its tokens stopped working and cannot be renewed. It works when Mozilla does not ask to confirm the sign-in; otherwise the account waits for "Sign in again" in the dashboard, which then only asks for the code. Without a stored password it returns cause.

type Candidate

type Candidate struct {
	Addr        string
	CountryName string
	CountryCode string
	CityName    string
	CityCode    string
}

func ConnectCandidates

func ConnectCandidates(countries []serverlist.Country) []Candidate

func FilterTargets

func FilterTargets(targets []Candidate, codes []string) []Candidate

FilterTargets keeps the targets whose country code is in codes.

func LocationCandidates

func LocationCandidates(countries []serverlist.Country, countryFilter string) []Candidate

LocationCandidates lists, in server-list order, the servers of the location countryFilter selects (locationMatcher): the servers that ServerFailover moves the upstream among. It is empty when the filter selects nothing.

func PersistedSelection

func PersistedSelection(path, countryFilter string) (Candidate, bool)

PersistedSelection returns the saved choice when it suits countryFilter, reading only the file: no server list and no log line. The status shows it before the proxy first connects to Mozilla, which selects for real.

func PingTargets

func PingTargets(countries []serverlist.Country) []Candidate

PingTargets returns one candidate per location, in server-list order.

func ResolveWithStateAndCountry

func ResolveWithStateAndCountry(proxyFlag, countryFilter string, countries []serverlist.Country, stateFile string, avoided func(addr string) bool) (Candidate, bool, error)

ResolveWithStateAndCountry selects the upstream: proxyFlag when set, else the persisted choice in stateFile when it suits countryFilter and is still a list entry, else a server of the location (selectProxyCandidate). avoided (nil: none) reports servers that failed recently (ServerFailover.Avoided): a persisted one is replaced, and selection skips them while the location has another.

func (Candidate) CityCodeOrUnknown

func (p Candidate) CityCodeOrUnknown() string

func (Candidate) CityNameOrUnknown

func (p Candidate) CityNameOrUnknown() string

func (Candidate) CountryCodeOrUnknown

func (p Candidate) CountryCodeOrUnknown() string

func (Candidate) CountryNameOrUnknown

func (p Candidate) CountryNameOrUnknown() string

func (Candidate) IsRecommended

func (p Candidate) IsRecommended() bool

IsRecommended reports whether the candidate belongs to the recommended (anycast) location rather than a specific country.

type ConnectionTestResult

type ConnectionTestResult struct {
	At    time.Time `json:"at"`
	OK    bool      `json:"ok"`
	Error string    `json:"error,omitempty"`
	// ErrorCode is the Failure code of Error.
	ErrorCode  string `json:"error_code,omitempty"`
	Target     string `json:"target"`
	HTTPStatus int    `json:"http_status,omitempty"`
	// The stages follow each other: opening the tunnel, the TLS handshake,
	// then waiting for the response (ResponseMS). FirstByteMS counts from
	// the start, so it includes the stages before it.
	TunnelMS    int64  `json:"tunnel_ms"`
	TLSMS       int64  `json:"tls_ms"`
	ResponseMS  int64  `json:"response_ms"`
	FirstByteMS int64  `json:"first_byte_ms"`
	TotalMS     int64  `json:"total_ms"`
	ExitIPv4    string `json:"exit_ipv4,omitempty"`
	ExitIPv6    string `json:"exit_ipv6,omitempty"`
	ExitCountry string `json:"exit_country,omitempty"`
	ExitCity    string `json:"exit_city,omitempty"`
	ExitNetwork string `json:"exit_network,omitempty"`
	ExitError   string `json:"exit_error,omitempty"`
}

ConnectionTestResult is the outcome of a test request sent through the tunnel. ICMP ping cannot cross the CONNECT proxy, so the test measures the stages of an HTTPS request instead.

func RunConnectionTest

func RunConnectionTest(opener tunnelOpener, target string, exitTimeout, timeout time.Duration) ConnectionTestResult

RunConnectionTest requests ConnectionTestURL through opener and then finds the public IP and its place, waiting exitTimeout for each service (0 skips that check).

func (ConnectionTestResult) Exit

Exit returns the public IP part of the result.

type Controller

type Controller struct {
	// OnSessionRebuilt, when set, runs after a failed upstream session was
	// replaced by a new one.
	OnSessionRebuilt func()
	// OnServerSwitched, when set, runs (renewMu held) after the failover
	// moved the upstream to another server of the location.
	OnServerSwitched func(Candidate)
	// contains filtered or unexported fields
}

func NewController

func NewController(cfg ControllerConfig) (*Controller, error)

func (*Controller) Close

func (c *Controller) Close() error

func (*Controller) CurrentStatus

func (c *Controller) CurrentStatus(reason string) RuntimeStatus

func (*Controller) CurrentToken

func (c *Controller) CurrentToken() string

CurrentToken returns the proxy pass of the current session.

func (*Controller) HTTPClient

func (c *Controller) HTTPClient(timeout time.Duration) *http.Client

HTTPClient sends the program's own requests, such as list downloads, through the proxy's tunnels.

func (*Controller) OpenTunnel

func (c *Controller) OpenTunnel(authority string) (net.Conn, error)

func (*Controller) OpenTunnelForClient

func (c *Controller) OpenTunnelForClient(authority, clientKey string) (net.Conn, error)

func (*Controller) Reconnect

func (c *Controller) Reconnect() error

Reconnect opens a new upstream session with the current pass and makes it current, closing the old one: after a network change the old session's connection belongs to a network that is gone, and finding that out request by request takes time. No new pass is needed.

func (*Controller) RetryNow

func (c *Controller) RetryNow()

RetryNow forgets the waits that failures left behind (the spacing of rebuilds, and a pass renewal that failed for want of a network or an answer), so the next tunnel tries at once: the network came back, or the user is looking.

func (*Controller) RunQuotaMonitorLoop

func (c *Controller) RunQuotaMonitorLoop()

RunQuotaMonitorLoop reads the quota when heavy traffic brings the active account near its switch point (noteTraffic), so the next account takes over without waiting for the pass renewal, which reads it otherwise.

func (*Controller) RunRenewalLoop

func (c *Controller) RunRenewalLoop()

func (*Controller) SwitchAccountNow

func (c *Controller) SwitchAccountNow() error

SwitchAccountNow obtains a pass from the account the account pool now prefers (after a manual activation, removal, or disable) and applies it to the current upstream session without waiting for the next renewal.

type ControllerConfig

type ControllerConfig struct {
	Guardian   string
	ProxyURL   *url.URL
	Timeout    time.Duration
	Auth       *runtimeAuth
	Pass       *guardian.ProxyPassInfo
	UseH3      bool
	Sessions   int
	StatusFile string
	Accounts   *AccountPool // optional; multi-account mode with threshold failover
	// ChosenLocation is set when the user chose the location (a country,
	// not the recommended location or the fastest one): a refusal that a
	// new pass does not cure is then reported as LocationRefusedError.
	ChosenLocation bool
	// Server is the server ProxyURL points to, with its location data.
	Server Candidate
	// Location lists the servers of the selected location
	// (LocationCandidates), and Failover moves the upstream among them
	// when Server keeps failing. Both are unset for a server set by hand.
	Location []Candidate
	Failover *ServerFailover
}

type ExchangeFunc

type ExchangeFunc func(ctx context.Context, query []byte) ([]byte, error)

ExchangeFunc sends a DNS query in wire format and returns the answer.

type ExitProbeResult

type ExitProbeResult struct {
	IPv4        string
	IPv6        string
	CountryCode string
	City        string
	Network     string
	ASN         int
	Latency     time.Duration
	ProbeHost   string
}

ExitProbeResult is the public address the traffic leaves Mozilla's network from: what websites see. An exit without IPv6 has no IPv6 address. City, Network (the ISP or organization), and ASN are empty when the services do not report them.

func VerifyExit

func VerifyExit(opener tunnelOpener, timeout time.Duration) (ExitProbeResult, error)

VerifyExit finds the public IPv4 and IPv6 address of the exit through opener, both at once; timeout applies to each service asked. It fails only when neither family answers.

func (ExitProbeResult) IP

func (r ExitProbeResult) IP() string

IP returns the IPv4 address, or the IPv6 address without one.

func (ExitProbeResult) Place

func (r ExitProbeResult) Place() string

Place describes the exit for people: the country code, then the city and network when known, such as "NL, Amsterdam, Example Hosting".

type LocationPing

type LocationPing struct {
	Code        string `json:"code"`
	Name        string `json:"name"`
	City        string `json:"city,omitempty"`
	Server      string `json:"server"`
	Recommended bool   `json:"recommended"`
	PingMS      int64  `json:"ping_ms,omitempty"`
	Error       string `json:"error,omitempty"`
}

LocationPing is the latency of one location: the time a CONNECT to PingTarget takes through that location's proxy, on an already established session (best of pingAttempts).

Every location's server is on Fastly's anycast network, so the handshake with the server reaches the same nearby Fastly edge for every location and says nothing about the location. A CONNECT travels on to the exit and back, which is the delay applications see.

func FastestLocation

func FastestLocation(results []LocationPing) (LocationPing, bool)

FastestLocation picks the reachable location with the lowest latency, from every location in the server list, including those it marks locked. A location that failed the measurement is never picked.

func MergePings

func MergePings(old, measured []LocationPing) []LocationPing

MergePings replaces the measured locations in old and keeps the rest.

func PingLocations

func PingLocations(ctx context.Context, targets []Candidate, meter pingMeter) []LocationPing

PingLocations measures every target concurrently and returns the results sorted by latency, failed locations last.

func (LocationPing) OK

func (p LocationPing) OK() bool

type LocationRefusedError

type LocationRefusedError struct {
	Err error
}

LocationRefusedError is a CONNECT refusal (403 or 407) by the server of a location the user chose, with a proxy pass fetched after the first refusal: a new pass did not help, so Mozilla most likely does not let this account use the location.

func (*LocationRefusedError) Error

func (e *LocationRefusedError) Error() string

func (*LocationRefusedError) Redacted

func (e *LocationRefusedError) Redacted() string

Redacted is the error without the response body, for logs that are not verbose.

func (*LocationRefusedError) Unwrap

func (e *LocationRefusedError) Unwrap() error

type Notice

type Notice struct {
	Kind   string    `json:"kind"`
	Detail string    `json:"detail"`
	Hosts  []string  `json:"hosts,omitempty"`
	Count  int       `json:"count"`
	Last   time.Time `json:"last"`
	// contains filtered or unexported fields
}

Notice is a kind of request this proxy cannot serve because of a limit of Mozilla's proxy or of this program, so the dashboard can explain it. Hosts are the latest distinct destinations (names or addresses), newest first; they stay in memory for the dashboard and never reach the log unless logging is verbose.

type Notices

type Notices struct {
	// contains filtered or unexported fields
}

Notices collects notices, one entry per kind and detail. The zero value is ready; a nil *Notices records nothing.

func (*Notices) Since

func (n *Notices) Since(t time.Time) []Notice

Since returns the notices last seen after t, newest first.

type ReloginError

type ReloginError struct {
	Reason  string
	RetryAt time.Time
	// Code and Detail say the same for the apps (accounts.Why).
	Code   string
	Detail string
	// contains filtered or unexported fields
}

ReloginError explains why an automatic sign-in could not replace the account's tokens. Without RetryAt the user has to act (it reads as fxa.ErrReauthRequired); with RetryAt the account sits out until then and the sign-in is tried again.

func (*ReloginError) Error

func (e *ReloginError) Error() string

func (*ReloginError) Unwrap

func (e *ReloginError) Unwrap() error

type RouteCounts

type RouteCounts struct {
	Proxy   int64 `json:"proxy"`
	Direct  int64 `json:"direct"`
	Blocked int64 `json:"blocked"`
}

RouteCounts counts connections by route since the proxy started.

type RoutedOpener

type RoutedOpener struct {
	// contains filtered or unexported fields
}

RoutedOpener opens each tunnel through Mozilla's proxy, directly through the local network, or not at all, as its router decides. Without a router everything goes through the proxy. The router can be replaced while connections are open.

func NewRoutedOpener

func NewRoutedOpener(upstream tunnelOpener) *RoutedOpener

NewRoutedOpener routes the tunnels of upstream; Close stops its speed sampling.

func (*RoutedOpener) Close

func (o *RoutedOpener) Close()

Close stops measuring the speed.

func (*RoutedOpener) Counts

func (o *RoutedOpener) Counts() RouteCounts

Counts returns the connections by route so far.

func (*RoutedOpener) Lookup

func (o *RoutedOpener) Lookup(ctx context.Context, host string) ([]netip.Addr, error)

Lookup resolves host the way the router's IP rules see it: through Mozilla.

func (*RoutedOpener) OpenTunnel

func (o *RoutedOpener) OpenTunnel(authority string) (net.Conn, error)

func (*RoutedOpener) OpenTunnelForClient

func (o *RoutedOpener) OpenTunnelForClient(authority, clientKey string) (net.Conn, error)

OpenTunnelForClient keeps the client affinity of the upstream pool.

func (*RoutedOpener) SetRouter

func (o *RoutedOpener) SetRouter(r *routing.Router)

SetRouter installs r; nil sends everything through the proxy.

func (*RoutedOpener) Traffic

func (o *RoutedOpener) Traffic() Traffic

Traffic returns the bytes and speed so far.

type RuntimeStatus

type RuntimeStatus struct {
	UpdatedAt          string `json:"updated_at"`
	PID                int    `json:"pid"`
	ProxyPassExpiresAt string `json:"proxy_pass_expires_at"`
	SecondsUntilExpiry int64  `json:"seconds_until_expiry"`
	Accepting          bool   `json:"accepting"`
	Reason             string `json:"reason"`
	// ActiveAccount names the account supplying the ProxyPass in
	// multi-account mode.
	ActiveAccount string `json:"active_account,omitempty"`
	// LastError is a stable failure code of the last renewal attempt
	// (e.g. reauth_required, region_unavailable); empty after success.
	LastError     string `json:"last_error,omitempty"`
	NextAttemptAt string `json:"next_attempt_at,omitempty"`
	// Quota fields are omitted when Guardian sent no valid quota headers.
	QuotaUnlimited      bool   `json:"quota_unlimited,omitempty"`
	QuotaLimitBytes     *int64 `json:"quota_limit_bytes,omitempty"`
	QuotaRemainingBytes *int64 `json:"quota_remaining_bytes,omitempty"`
	QuotaResetAt        string `json:"quota_reset_at,omitempty"`
}

type SOCKSServer

type SOCKSServer struct {
	// Auth, when set, requires username/password authentication.
	Auth *socksCredentials
	// Notices, when set, collects requests refused because of a limit, for
	// the dashboard.
	Notices *Notices
	// Allow, when set, refuses at once a target (host, port) it rejects,
	// without trying it: the TUN mode's rule for the ports Mozilla's proxy
	// does not carry.
	Allow func(host, port string) bool
	// contains filtered or unexported fields
}

func NewSOCKSServer

func NewSOCKSServer(upstream tunnelOpener, handshakeTimeout, idleTimeout time.Duration, maxConns int) *SOCKSServer

func (*SOCKSServer) ServeConn

func (s *SOCKSServer) ServeConn(conn net.Conn)

ServeConn serves one client, as ServeSOCKS serves each it accepts.

type ServerFailover

type ServerFailover struct {
	// contains filtered or unexported fields
}

ServerFailover moves the upstream to another server of the chosen location when one server keeps failing: after serverFailoverStrikes failures in a row to establish or keep a session on it (serverFault decides which failures are the server's), the server is avoided for serverAvoidTime and another server of the same city, else of the location's next city, is used and saved as the persisted choice. When every other server of the location is avoided, the upstream stays where it is and the usual retries go on; the location never changes.

One per daemon: it outlives controllers and engines, so the wakes and the controllers of one location share the strikes and the avoided servers. A nil ServerFailover does nothing (a server set by hand).

func NewServerFailover

func NewServerFailover(selectionFile string) *ServerFailover

NewServerFailover returns a failover that saves new choices in selectionFile.

func (*ServerFailover) Avoided

func (f *ServerFailover) Avoided(addr string) bool

Avoided reports whether the server at addr failed recently and is skipped by selection.

func (*ServerFailover) Failed

func (f *ServerFailover) Failed(location []Candidate, server Candidate, err error) (next Candidate, ok bool)

Failed counts err against server, one of location's servers, when the server is to blame (serverFault). At its serverFailoverStrikes-th failure in a row the server is avoided for serverAvoidTime and Failed returns the server to use instead (nextServer), saved as the persisted choice. ok is false otherwise, also when every other server of the location is avoided: the caller then stays on server.

func (*ServerFailover) Worked

func (f *ServerFailover) Worked(addr string)

Worked forgets the strikes of the server at addr: a tunnel opened through it.

type Traffic

type Traffic struct {
	Up         int64 `json:"up"`
	Down       int64 `json:"down"`
	DirectUp   int64 `json:"direct_up"`
	DirectDown int64 `json:"direct_down"`
	UpRate     int64 `json:"up_rate"`
	DownRate   int64 `json:"down_rate"`
}

Traffic is what the proxy's clients sent and received since the proxy started, through Mozilla and directly (routing), and the current speed of both together in bytes per second.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL