Skip to main content

TcpConnect

Trait TcpConnect 

Source
pub trait TcpConnect {
    type Stream: Read + Write + Unpin;

    const APPLIES: TcpOptsSupport = TcpOptsSupport::NONE;
    const SUPPORTS_UNIX: bool = false;

    // Required method
    fn connect(
        &self,
        addr: SocketAddr,
        opts: &TcpOpts,
    ) -> impl Future<Output = Result<Self::Stream>>;

    // Provided method
    fn connect_unix(
        &self,
        path: &Path,
    ) -> impl Future<Output = Result<Self::Stream>> { ... }
}

Provided Associated Constants§

Source

const APPLIES: TcpOptsSupport = TcpOptsSupport::NONE

Which TcpOpts fields this runtime actually applies.

§Why the default is NONE and not ALL

A default is a claim made by silence, and it must never be stronger than the truth — the rule written down on CancelSupport::None and learned from RedirectSupport::Transparent. ALL would make a backend that forgot the line claim it applies every option; NONE makes it understate itself, so the worst case is one refused connect too many rather than an option dropped on the floor without a trace.

Source

const SUPPORTS_UNIX: bool = false

Whether connect_unix does anything.

APPLIES’ shape, and defaulted the same way and for the same reason: a claim made by silence must never be stronger than the truth. A runtime that says nothing here refuses the setting, where one that over-claimed would fail every connect at the socket instead of at the call that asked.

It is a const rather than something the connect discovers, because the answer is a property of the runtime and the target and a caller should learn it at configuration rather than on the wire — which is what lets hclient_native::Native::unix_socket refuse.

Required Associated Types§

Required Methods§

Source

fn connect( &self, addr: SocketAddr, opts: &TcpOpts, ) -> impl Future<Output = Result<Self::Stream>>

§The options are not optional

A runtime that cannot apply an option the caller set must fail this callTcpOpts::reject_unsupported is the shared way to do it, and the error it builds names the option. Ignoring it is not an available answer: connect returns io::Result<Self::Stream> and nothing else, so an option quietly dropped here is dropped without a trace anywhere in the stack.

On platforms with file descriptors the whole set is applied outside the runtime, on a socket2::Socket, and the runtime only adopts the finished socket (TcpAdoptStd) — which is why both shipped runtimes declare TcpOptsSupport::ALL and never have to refuse anything.

Provided Methods§

Source

fn connect_unix( &self, path: &Path, ) -> impl Future<Output = Result<Self::Stream>>

Connect to a Unix-domain socket at path.

§Why it is here rather than on a seam of its own

Because a seam of its own could not be reached. Native’s IO type is Self::Stream, so a second trait would have to produce the same associated type — at which point it is this trait with an extra method — and putting R: UnixConnect on Native would tax every runtime that has no file descriptors. The fn-pointer trick that keeps Spawn off Native’s signature does not work here: spawn returns () where this returns a future, and boxing it would drop auto traits (spec amendment C1).

So it is a defaulted method on the seam that already exists — TlsConnect::reports_alpn’s shape, applies_ech‘s and TlsIdentity::presents_client_certs’: a constant defaulted to the understating value, read by the layer above to decide whether to ask.

§No TcpOpts

Not an omission: every field of TcpOpts is a TCP or IP socket option, and AF_UNIX has none of them — no Nagle, no keepalive, no source address, no interface. A parameter that could only ever be ignored is worse than no parameter.

The default is a refusal rather than a panic, and the error carries std::io::ErrorKind::Unsupported so a caller who reached it through some path that skipped SUPPORTS_UNIX still gets an answer rather than an abort.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§