Skip to main content

PortSpecification

Enum PortSpecification 

Source
pub enum PortSpecification {
    One {
        port: u16,
    },
    Range {
        range: PortRange,
    },
    All {
        all_ports: AllPorts,
    },
}
Expand description

PortSpecification, the model’s tagged union: one port, a range, or all of them.

A union rather than the single-field struct this was, and the change is a defect fix rather than completeness for its own sake. Session::connect_headers(port) and connect_subprotocols(port) exist to reach another port on the same VM, and they were built over a token the control plane had minted with allowedPorts: [{port: 9000}] — so they returned a correct-looking port header behind a credential that did not authorize it. Measured 2026-08-15 on one VM with a listener on 8080, varying only the mint:

allowedPortsGET :8080 through the endpoint
[{port: 9000}]403 Access to port denied
[{port: 9000}, {port: 8080}]200, the guest answered
[{allPorts: {}}]200
[{range: {startPort: 8000, endPort: 9100}}]200

One variable, four outcomes, so the token’s scope is the whole of it. On the WebSocket path the same rejection is close code 1006 with no reason, which is why this was invisible to a client-side test: the strings were right and the credential behind them was not.

#[serde(untagged)] because the wire form is the member name as the key — {"port": 9000}, {"range": {..}}, {"allPorts": {}} — not a discriminator field, and serde’s default enum representation would emit {"Port": 9000}. Each variant names its own key through rename.

Variants§

§

One

Exactly one port. What a session built for the agent port asks for.

Fields

§port: u16
§

Range

An inclusive range. Both members are required by the model.

Fields

§

All

Every port on the VM.

Deliberately not what this client mints by default. A token good for every port is one whose leak is worth more, and the ports a caller actually needs are knowable: the agent port plus whatever it asked for. Present because the model has it and a caller building a general proxy needs it, reached only through an explicit scope.

Fields

§all_ports: AllPorts

Implementations§

Source§

impl PortSpecification

Source

pub fn port(port: u16) -> Self

One port.

Source

pub fn range(start: u16, end: u16) -> Self

An inclusive range of ports.

Source

pub fn all() -> Self

Every port. See PortSpecification::All for why this is not a default.

Trait Implementations§

Source§

impl Clone for PortSpecification

Source§

fn clone(&self) -> PortSpecification

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for PortSpecification

Source§

impl Debug for PortSpecification

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Serialize for PortSpecification

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> AsOut<T> for T
where T: Copy,

Source§

fn as_out(&mut self) -> Out<'_, T>

Returns an out reference to self.
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<Unshared, Shared> IntoShared<Shared> for Unshared
where Shared: FromUnshared<Unshared>,

Source§

fn into_shared(self) -> Shared

Creates a shared type from an unshared type.
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more