1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 17:38:00 +00:00

Packet protocol layers: new 'final_output' method.

This is called just before closing the connection, and gives every PPL
one last chance to output anything to the user that it might have
buffered.

No functional change: all implementations so far are trivial, except
that the transport layer passes the call on to its higher
layer (because otherwise nothing would do so).

(cherry picked from commit d6e6919f69)
This commit is contained in:
Simon Tatham 2023-04-29 11:35:20 +01:00
parent 7e8be5a204
commit 44272b5355
10 changed files with 36 additions and 0 deletions

View File

@ -742,6 +742,10 @@ size_t ssh_ppl_default_queued_data_size(PacketProtocolLayer *ppl)
return ppl->out_pq->pqb.total_size;
}
void ssh_ppl_default_final_output(PacketProtocolLayer *ppl)
{
}
static void ssh_ppl_prompts_callback(void *ctx)
{
ssh_ppl_process_queue((PacketProtocolLayer *)ctx);

View File

@ -40,6 +40,7 @@ static const PacketProtocolLayerVtable ssh1_connection_vtable = {
.special_cmd = ssh1_connection_special_cmd,
.reconfigure = ssh1_connection_reconfigure,
.queued_data_size = ssh_ppl_default_queued_data_size,
.final_output = ssh_ppl_default_final_output,
.name = NULL, /* no layer names in SSH-1 */
};

View File

@ -27,6 +27,7 @@ static const PacketProtocolLayerVtable ssh2_connection_vtable = {
.special_cmd = ssh2_connection_special_cmd,
.reconfigure = ssh2_connection_reconfigure,
.queued_data_size = ssh_ppl_default_queued_data_size,
.final_output = ssh_ppl_default_final_output,
.name = "ssh-connection",
};

View File

@ -61,6 +61,7 @@ static const PacketProtocolLayerVtable ssh1_login_server_vtable = {
.special_cmd = ssh1_login_server_special_cmd,
.reconfigure = ssh1_login_server_reconfigure,
.queued_data_size = ssh_ppl_default_queued_data_size,
.final_output = ssh_ppl_default_final_output,
.name = NULL, /* no layer names in SSH-1 */
};

View File

@ -81,6 +81,7 @@ static const PacketProtocolLayerVtable ssh1_login_vtable = {
.special_cmd = ssh1_login_special_cmd,
.reconfigure = ssh1_login_reconfigure,
.queued_data_size = ssh_ppl_default_queued_data_size,
.final_output = ssh_ppl_default_final_output,
.name = NULL, /* no layer names in SSH-1 */
};

View File

@ -19,6 +19,7 @@ struct PacketProtocolLayerVtable {
PacketProtocolLayer *ppl, SessionSpecialCode code, int arg);
void (*reconfigure)(PacketProtocolLayer *ppl, Conf *conf);
size_t (*queued_data_size)(PacketProtocolLayer *ppl);
void (*final_output)(PacketProtocolLayer *ppl);
/* Protocol-level name of this layer. */
const char *name;
@ -68,6 +69,8 @@ static inline void ssh_ppl_reconfigure(PacketProtocolLayer *ppl, Conf *conf)
{ ppl->vt->reconfigure(ppl, conf); }
static inline size_t ssh_ppl_queued_data_size(PacketProtocolLayer *ppl)
{ return ppl->vt->queued_data_size(ppl); }
static inline void ssh_ppl_final_output(PacketProtocolLayer *ppl)
{ ppl->vt->final_output(ppl); }
static inline InteractionReadySeat ppl_get_iseat(PacketProtocolLayer *ppl)
{ return interactor_announce(ppl->interactor); }
@ -93,6 +96,9 @@ void ssh_ppl_replace(PacketProtocolLayer *old, PacketProtocolLayer *new);
* has other things to take into account as well. */
size_t ssh_ppl_default_queued_data_size(PacketProtocolLayer *ppl);
/* Default implementation of final_output which outputs nothing. */
void ssh_ppl_default_final_output(PacketProtocolLayer *ppl);
PacketProtocolLayer *ssh1_login_new(
Conf *conf, const char *host, int port,
PacketProtocolLayer *successor_layer);

View File

@ -474,6 +474,8 @@ void ssh_remote_error(Ssh *ssh, const char *fmt, ...)
if (ssh->base_layer || !ssh->session_started) {
GET_FORMATTED_MSG;
ssh_ppl_final_output(ssh->base_layer);
/* Error messages sent by the remote don't count as clean exits */
ssh->exitcode = 128;
@ -492,6 +494,8 @@ void ssh_remote_eof(Ssh *ssh, const char *fmt, ...)
if (ssh->base_layer || !ssh->session_started) {
GET_FORMATTED_MSG;
ssh_ppl_final_output(ssh->base_layer);
/* EOF from the remote, if we were expecting it, does count as
* a clean exit */
ssh->exitcode = 0;
@ -515,6 +519,8 @@ void ssh_proto_error(Ssh *ssh, const char *fmt, ...)
if (ssh->base_layer || !ssh->session_started) {
GET_FORMATTED_MSG;
ssh_ppl_final_output(ssh->base_layer);
ssh->exitcode = 128;
ssh_bpp_queue_disconnect(ssh->bpp, msg,
@ -532,6 +538,8 @@ void ssh_sw_abort(Ssh *ssh, const char *fmt, ...)
if (ssh->base_layer || !ssh->session_started) {
GET_FORMATTED_MSG;
ssh_ppl_final_output(ssh->base_layer);
ssh->exitcode = 128;
ssh_initiate_connection_close(ssh);
@ -549,6 +557,8 @@ void ssh_user_close(Ssh *ssh, const char *fmt, ...)
if (ssh->base_layer || !ssh->session_started) {
GET_FORMATTED_MSG;
ssh_ppl_final_output(ssh->base_layer);
/* Closing the connection due to user action, even if the
* action is the user aborting during authentication prompts,
* does count as a clean exit - except that this is also how

View File

@ -80,6 +80,7 @@ static size_t ssh2_transport_queued_data_size(PacketProtocolLayer *ppl);
static void ssh2_transport_set_max_data_size(struct ssh2_transport_state *s);
static unsigned long sanitise_rekey_time(int rekey_time, unsigned long def);
static void ssh2_transport_higher_layer_packet_callback(void *context);
static void ssh2_transport_final_output(PacketProtocolLayer *ppl);
static const PacketProtocolLayerVtable ssh2_transport_vtable = {
.free = ssh2_transport_free,
@ -88,6 +89,7 @@ static const PacketProtocolLayerVtable ssh2_transport_vtable = {
.special_cmd = ssh2_transport_special_cmd,
.reconfigure = ssh2_transport_reconfigure,
.queued_data_size = ssh2_transport_queued_data_size,
.final_output = ssh2_transport_final_output,
.name = NULL, /* no protocol name for this layer */
};
@ -2406,3 +2408,11 @@ static size_t ssh2_transport_queued_data_size(PacketProtocolLayer *ppl)
return (ssh_ppl_default_queued_data_size(ppl) +
ssh_ppl_queued_data_size(s->higher_layer));
}
static void ssh2_transport_final_output(PacketProtocolLayer *ppl)
{
struct ssh2_transport_state *s =
container_of(ppl, struct ssh2_transport_state, ppl);
ssh_ppl_final_output(s->higher_layer);
}

View File

@ -140,6 +140,7 @@ static const PacketProtocolLayerVtable ssh2_userauth_vtable = {
.special_cmd = ssh2_userauth_special_cmd,
.reconfigure = ssh2_userauth_reconfigure,
.queued_data_size = ssh_ppl_default_queued_data_size,
.final_output = ssh_ppl_default_final_output,
.name = "ssh-userauth",
};

View File

@ -42,6 +42,7 @@ static const PacketProtocolLayerVtable ssh2_userauth_server_vtable = {
.free = ssh2_userauth_server_free,
.process_queue = ssh2_userauth_server_process_queue,
.queued_data_size = ssh_ppl_default_queued_data_size,
.final_output = ssh_ppl_default_final_output,
.name = "ssh-userauth",
/* other methods are NULL */
};