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