pub enum ProxyError {
Show 14 variants
Listener(String),
NotBound,
Transport(TransportError),
Codec(CodecError),
UpstreamConnect(String),
UpstreamSocketUnsupported,
TransportConfigAndProfile {
leg: Leg,
},
TransportProfile {
leg: Leg,
source: TransportProfileError,
},
ShapeRuleUnsupported {
source: UnsupportedMatcherKey,
},
DraftNotCompiled {
draft: DraftVersion,
},
TlsConfig(String),
CertGen(String),
SessionClosed(String),
Shutdown,
}Expand description
Errors from the proxy layer.
Variants§
Listener(String)
Error from the QUIC/WebTransport listener.
NotBound
Something was asked of a proxy’s listener before there was one.
A TransparentProxy binds its
endpoint inside run(), so a
ProxyControl taken beforehand —
which is the usual case, since run() does not return until the
proxy is finished — is live before the endpoint is. This is the
answer during that window, and again after run() has returned and
the endpoint is gone.
Distinct from ProxyError::Listener on purpose: that one means a
listener existed and something about it failed, and the two call for
opposite responses. A caller waiting for a proxy to come up retries
on this and gives up on the other.
Transport(TransportError)
Error from the underlying transport.
Codec(CodecError)
Error decoding a MoQT frame.
UpstreamConnect(String)
Failed to connect to the upstream relay.
UpstreamSocketUnsupported
A socket was supplied for an upstream connection that cannot be made over it.
Distinct from ProxyError::UpstreamConnect because nothing was
attempted: the session refuses to connect at all rather than
connecting over a socket the caller did not supply. Silently
ignoring the socket would let a caller arm loss, delay or a
bandwidth cap on the relay leg, watch a clean run, and conclude the
impairment had no effect — when in fact it never reached the wire.
TransportConfigAndProfile
One leg was given both a raw quinn::TransportConfig and a
TransportProfile.
Refused where the leg is built, rather than merged, and the reason
is a missing trait rather than a policy anyone chose.
quinn::TransportConfig has no Clone and no getter for any field,
so nothing in this crate can take the caller’s config and hand back
a modified copy of it. Code that looked like a merge would in fact
be starting from quinn::TransportConfig::default() and discarding
everything the embedding program configured — and the tests would
stay green while it happened, because every field set in the
profile does arrive. Only the fields set in the config vanish, and
nothing reports that.
A caller who wants both writes the base config and applies the
profile over it with TransportProfile::apply_to(&mut base), then
sets the result as this leg’s transport_config. Where the base has
to be rebuilt for each connection,
TransportInstaller is that
same call behind a trait the leg can hold.
TransportProfile
A leg’s TransportProfile
could not be turned into a quinn::TransportConfig.
The leg is refused rather than opened with quinn’s defaults: a connection that came up anyway would run with parameters nobody chose and report success, and the profile that was ignored is precisely the record of what the run was supposed to be.
Fields
source: TransportProfileErrorWhy the profile could not be honoured.
ShapeRuleUnsupported
A shaping class keys on a field this session’s draft does not carry, so the class could never claim a unit.
Refused before the session dials, rather than left to be discovered from a report during the run. The rule is not merely unlikely to match — on this draft there is no traffic at all that could satisfy it, so a session carrying one would pace nothing the author asked for, count itself as shaping, and finish clean. That is the whole failure this crate exists to make impossible, arrived at through a configuration file rather than a bug.
Distinct from
ShapeError::InertMatcher,
and the distinction is where the answer lives: an empty value set is
a property of the configuration alone, so the constructor rejects it
with no draft in hand; a key the draft does not carry needs a draft
to judge, which only exists once a session is being started.
Fields
source: UnsupportedMatcherKeyThe class, the draft, the stream kind and the key.
DraftNotCompiled
The session is configured for a MoQT draft this build did not compile a codec for.
DraftVersion carries all thirteen variants under every feature
set, so a draft that was never compiled is still a value a
configuration can hold — and
ProxySessionConfig::default().draft holds one of them. On a build
made with a reduced draft set, nothing about such a configuration
looks wrong.
§What the session would do instead
Run, and forward everything uninterpreted. The dispatch enums fall
through to their catch-all arm and answer
CodecError::UnsupportedDraft, which is not an
incomplete-input error, so the object framer takes its terminal
arm, latches BypassReason::DecodeError
and pumps the stream through as bytes. No object reaches a hook, no
shaping class claims anything, no ProxyEvent::Object is emitted —
and the run completes, reports success, and produces a stream of
zeroes that is indistinguishable from a session nothing was sent on.
Control frames fare no better and are quieter still: the control
parser skips a frame it cannot decode and emits nothing at all.
So it is refused where the session starts, beside the shaping admission check and before the relay is dialled, because a byte pump reporting success is precisely what this crate exists to make impossible.
§It names the draft that was resolved, not the one configured
Drafts 15 and later are settled by the client’s ALPN, so the draft a session will actually frame with may not be the one in its configuration. This carries the resolved one, which is the one that is missing.
The fix is a build that carries the draft — the draftNN feature of
this crate, which forwards to both the codec and the client — or a
configuration naming one this build has.
Fields
draft: DraftVersionThe draft this build cannot frame.
TlsConfig(String)
TLS configuration error.
CertGen(String)
Certificate generation error.
SessionClosed(String)
Session was closed.
Shutdown
Proxy is shutting down.
Trait Implementations§
Source§impl Debug for ProxyError
impl Debug for ProxyError
Source§impl Display for ProxyError
impl Display for ProxyError
Source§impl Error for ProxyError
impl Error for ProxyError
Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()