The SSH sessions under the resolver's relays

The SSH sessions under the relays

A held adapter whose service lives on another host is first asked whether its held waits stand on the SSH session the new connection would ride. Every connection to one service endpoint on a host shares one native session, and that session can stop answering its channels while the host answers a new session at once. When the youngest held wait began after the current session answered, the session itself stands: the resolver opens a new session to the same host in its place, and when it answers the connection rides it, said on stderr as relaying although the adapter holds connections: the session to <host> for <endpoint> stands, … while a new session to <host> answered: new connections ride the new session and the held ones stay on the standing one until their clients leave. When the held waits all began before the current session answered, they ride one already replaced and the connection rides the current session. Only when no new session opens is the connection refused, with the held sentence followed by the session to <host> for <endpoint> stands with them and a new session in its place did not open: <cause>; a held adapter to a service on this host is refused as before. A service that holds its requests on every session costs one new session per refresh interval, since a wait counts as held only after it. The held waits a replaced session keeps carry session_replaced_at in ~/.stado/resolver-waiting.json and in stado resolver status waiting_opens, and the route's blocker ends with the SSH session it rides was replaced at <instant> by a new session to <host> that carries new connections, so it stands only until its client leaves. Such a wait no longer refuses a caller: held_at, the host-channel reading and the in-flight reading skip it, since the route it stood on is carried again.

A host none of whose SSH paths answers costs every connection a whole handshake per path: each one tried the paths again, so a service placed on a host that went away held each client for as long as its paths took to fail. The resolver remembers, per active host, that its last session attempt was refused by every path and why. A connection to that host within the refresh interval the target declares is refused at once with an HTTP 502 whose cause is not tried again: every SSH path of <host> refused <N>s ago, within this resolver's <N>s refresh interval (no registry SSH connection path answered (…)); the first connection after it tries again. The first connection after the interval tries the paths again, and a session that opens forgets the refusal. A pooled session that still answers is used whatever was remembered. Real journey: tests/resolver/unreached.rs (target resolver-unreached).

The resolver does not wait for a connection to arrive before replacing a standing session: a caller that reads the waiting list refuses itself before it connects, so that connection would never come. On every refresh interval it reads its own waits, and for each route held past the interval on a session it has not replaced it opens a new session to the route's host in its place, saying stado resolver service=<name> consumer=<consumer> the session to <host> for <endpoint> stands, … while a new session to <host> answered: … on stderr, or the same prefix followed by the reason no new session opened. This runs in its own loop, so a host that answers no new session never holds the directory refresh.

A relay to another host that fails says on stderr how long it ran and whether the SSH session under it survived: stado resolver adapter service=<name> consumer=<consumer> rejected connection: proxy to <host>:<port> failed: <cause> after <n> ms; the SSH session to "<host>" is still open, so the service end closed this one channel when the service on that host dropped this one connection, or … is closed, so every channel on it failed together when the session died under every channel. The first points at the service on the destination host; the second at the session, which the resolver opens again for the next connection. The real journey kompilator test --manifest-path stado-rs/Cargo.toml --test service-directory-held -- closed_channel:: runs a real SSH server that closes every forwarded channel while its session lives, and reads the first sentence from the resolver's log.

A destination dials SSH's own port unless it names another the way known_hosts writes a server off that port: <user>@[<host>]:<port>. A native session (the resolver's relay and the registry authority read) dials <port> and trusts the host key known_hosts holds for [<host>]:<port>; a command that rides OpenSSH's ssh (the host channel, recovery, reboot, account and bootstrap commands) is given the ssh://<user>@<host>:<port> URI ssh reads. A port that is not a port is refused with SSH destination <destination> names port "<word>", which is not a port. The real test tests/service_directory/held/session/ runs a real SSH server on such a port whose first session carrying a channel stands while every other forwards to a service that answers: a first client's request stands on the resolver's session, and once it has waited past the refresh interval a second client on the same adapter is answered over a new session, the resolver says so, and the held wait carries session_replaced_at in the published list and in resolver status.

Source: this website