mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 17:38:00 +00:00
Non-SSH network backends: handle PLUGLOG_CONNECT_SUCCESS.
All four of the other network-protocol backends (Raw, Telnet, rlogin and SUPDUP) now have a 'socket_connected' flag, which starts off false and is set to true when (if) their Socket signals that the connection attempt has succeeded. This field is used to tell backend_socket_log whether the session has started yet (hence, whether it should still be logging messages from the proxy). This replaces various ad-hoc answers to that question in each backend, which were the best I could do when sockets didn't notify connection success. Now they do, we can do it properly. Also, the new flag controls the answer to each backend's sendok() method, which makes them all satisfy a new policy rule: no backend shall return true from sendok() while its network connection attempt is still ongoing. (Rationale: the network connection attempt may in future involve a proxy implementation interacting with the user via the terminal, and it can't do that if the backend is already consuming all the terminal input.)
This commit is contained in:
parent
6b1154cc5b
commit
0b099b6a6f
@ -17,7 +17,7 @@ struct Raw {
|
|||||||
size_t bufsize;
|
size_t bufsize;
|
||||||
Seat *seat;
|
Seat *seat;
|
||||||
LogContext *logctx;
|
LogContext *logctx;
|
||||||
bool sent_console_eof, sent_socket_eof, session_started;
|
bool sent_console_eof, sent_socket_eof, socket_connected;
|
||||||
|
|
||||||
Conf *conf;
|
Conf *conf;
|
||||||
|
|
||||||
@ -37,8 +37,10 @@ static void raw_log(Plug *plug, PlugLogType type, SockAddr *addr, int port,
|
|||||||
const char *error_msg, int error_code)
|
const char *error_msg, int error_code)
|
||||||
{
|
{
|
||||||
Raw *raw = container_of(plug, Raw, plug);
|
Raw *raw = container_of(plug, Raw, plug);
|
||||||
backend_socket_log(raw->seat, raw->logctx, type, addr, port,
|
backend_socket_log(raw->seat, raw->logctx, type, addr, port, error_msg,
|
||||||
error_msg, error_code, raw->conf, raw->session_started);
|
error_code, raw->conf, raw->socket_connected);
|
||||||
|
if (type == PLUGLOG_CONNECT_SUCCESS)
|
||||||
|
raw->socket_connected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void raw_check_close(Raw *raw)
|
static void raw_check_close(Raw *raw)
|
||||||
@ -95,9 +97,6 @@ static void raw_receive(Plug *plug, int urgent, const char *data, size_t len)
|
|||||||
{
|
{
|
||||||
Raw *raw = container_of(plug, Raw, plug);
|
Raw *raw = container_of(plug, Raw, plug);
|
||||||
c_write(raw, data, len);
|
c_write(raw, data, len);
|
||||||
/* We count 'session start', for proxy logging purposes, as being
|
|
||||||
* when data is received from the network and printed. */
|
|
||||||
raw->session_started = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void raw_sent(Plug *plug, size_t bufsize)
|
static void raw_sent(Plug *plug, size_t bufsize)
|
||||||
@ -144,7 +143,7 @@ static char *raw_init(const BackendVtable *vt, Seat *seat,
|
|||||||
*backend_handle = &raw->backend;
|
*backend_handle = &raw->backend;
|
||||||
raw->sent_console_eof = raw->sent_socket_eof = false;
|
raw->sent_console_eof = raw->sent_socket_eof = false;
|
||||||
raw->bufsize = 0;
|
raw->bufsize = 0;
|
||||||
raw->session_started = false;
|
raw->socket_connected = false;
|
||||||
raw->conf = conf_copy(conf);
|
raw->conf = conf_copy(conf);
|
||||||
|
|
||||||
raw->seat = seat;
|
raw->seat = seat;
|
||||||
@ -267,7 +266,8 @@ static bool raw_connected(Backend *be)
|
|||||||
|
|
||||||
static bool raw_sendok(Backend *be)
|
static bool raw_sendok(Backend *be)
|
||||||
{
|
{
|
||||||
return true;
|
Raw *raw = container_of(be, Raw, backend);
|
||||||
|
return raw->socket_connected;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void raw_unthrottle(Backend *be, size_t backlog)
|
static void raw_unthrottle(Backend *be, size_t backlog)
|
||||||
|
@ -16,6 +16,7 @@ struct Rlogin {
|
|||||||
Socket *s;
|
Socket *s;
|
||||||
bool closed_on_socket_error;
|
bool closed_on_socket_error;
|
||||||
int bufsize;
|
int bufsize;
|
||||||
|
bool socket_connected;
|
||||||
bool firstbyte;
|
bool firstbyte;
|
||||||
bool cansize;
|
bool cansize;
|
||||||
int term_width, term_height;
|
int term_width, term_height;
|
||||||
@ -43,7 +44,9 @@ static void rlogin_log(Plug *plug, PlugLogType type, SockAddr *addr, int port,
|
|||||||
Rlogin *rlogin = container_of(plug, Rlogin, plug);
|
Rlogin *rlogin = container_of(plug, Rlogin, plug);
|
||||||
backend_socket_log(rlogin->seat, rlogin->logctx, type, addr, port,
|
backend_socket_log(rlogin->seat, rlogin->logctx, type, addr, port,
|
||||||
error_msg, error_code,
|
error_msg, error_code,
|
||||||
rlogin->conf, !rlogin->firstbyte);
|
rlogin->conf, rlogin->socket_connected);
|
||||||
|
if (type == PLUGLOG_CONNECT_SUCCESS)
|
||||||
|
rlogin->socket_connected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rlogin_closing(Plug *plug, const char *error_msg, int error_code,
|
static void rlogin_closing(Plug *plug, const char *error_msg, int error_code,
|
||||||
@ -176,6 +179,7 @@ static char *rlogin_init(const BackendVtable *vt, Seat *seat,
|
|||||||
rlogin->logctx = logctx;
|
rlogin->logctx = logctx;
|
||||||
rlogin->term_width = conf_get_int(conf, CONF_width);
|
rlogin->term_width = conf_get_int(conf, CONF_width);
|
||||||
rlogin->term_height = conf_get_int(conf, CONF_height);
|
rlogin->term_height = conf_get_int(conf, CONF_height);
|
||||||
|
rlogin->socket_connected = false;
|
||||||
rlogin->firstbyte = true;
|
rlogin->firstbyte = true;
|
||||||
rlogin->cansize = false;
|
rlogin->cansize = false;
|
||||||
rlogin->prompt = NULL;
|
rlogin->prompt = NULL;
|
||||||
@ -364,8 +368,8 @@ static bool rlogin_connected(Backend *be)
|
|||||||
|
|
||||||
static bool rlogin_sendok(Backend *be)
|
static bool rlogin_sendok(Backend *be)
|
||||||
{
|
{
|
||||||
/* Rlogin *rlogin = container_of(be, Rlogin, backend); */
|
Rlogin *rlogin = container_of(be, Rlogin, backend);
|
||||||
return true;
|
return rlogin->socket_connected;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rlogin_unthrottle(Backend *be, size_t backlog)
|
static void rlogin_unthrottle(Backend *be, size_t backlog)
|
||||||
|
@ -66,6 +66,7 @@ typedef struct supdup_tag Supdup;
|
|||||||
struct supdup_tag
|
struct supdup_tag
|
||||||
{
|
{
|
||||||
Socket *s;
|
Socket *s;
|
||||||
|
bool socket_connected;
|
||||||
bool closed_on_socket_error;
|
bool closed_on_socket_error;
|
||||||
|
|
||||||
Seat *seat;
|
Seat *seat;
|
||||||
@ -561,7 +562,9 @@ static void supdup_log(Plug *plug, PlugLogType type, SockAddr *addr, int port,
|
|||||||
Supdup *supdup = container_of(plug, Supdup, plug);
|
Supdup *supdup = container_of(plug, Supdup, plug);
|
||||||
backend_socket_log(supdup->seat, supdup->logctx, type, addr, port,
|
backend_socket_log(supdup->seat, supdup->logctx, type, addr, port,
|
||||||
error_msg, error_code,
|
error_msg, error_code,
|
||||||
supdup->conf, supdup->state != CONNECTING);
|
supdup->conf, supdup->socket_connected);
|
||||||
|
if (type == PLUGLOG_CONNECT_SUCCESS)
|
||||||
|
supdup->socket_connected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void supdup_closing(Plug *plug, const char *error_msg, int error_code,
|
static void supdup_closing(Plug *plug, const char *error_msg, int error_code,
|
||||||
@ -662,6 +665,7 @@ static char *supdup_init(const BackendVtable *x, Seat *seat,
|
|||||||
supdup->logctx = logctx;
|
supdup->logctx = logctx;
|
||||||
supdup->conf = conf_copy(conf);
|
supdup->conf = conf_copy(conf);
|
||||||
supdup->s = NULL;
|
supdup->s = NULL;
|
||||||
|
supdup->socket_connected = false;
|
||||||
supdup->closed_on_socket_error = false;
|
supdup->closed_on_socket_error = false;
|
||||||
supdup->seat = seat;
|
supdup->seat = seat;
|
||||||
supdup->term_width = conf_get_int(supdup->conf, CONF_width);
|
supdup->term_width = conf_get_int(supdup->conf, CONF_width);
|
||||||
@ -861,7 +865,8 @@ static bool supdup_connected(Backend *be)
|
|||||||
|
|
||||||
static bool supdup_sendok(Backend *be)
|
static bool supdup_sendok(Backend *be)
|
||||||
{
|
{
|
||||||
return 1;
|
Supdup *supdup = container_of(be, Supdup, backend);
|
||||||
|
return supdup->socket_connected;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void supdup_unthrottle(Backend *be, size_t backlog)
|
static void supdup_unthrottle(Backend *be, size_t backlog)
|
||||||
|
@ -171,6 +171,7 @@ static const struct Opt *const opts[] = {
|
|||||||
typedef struct Telnet Telnet;
|
typedef struct Telnet Telnet;
|
||||||
struct Telnet {
|
struct Telnet {
|
||||||
Socket *s;
|
Socket *s;
|
||||||
|
bool socket_connected;
|
||||||
bool closed_on_socket_error;
|
bool closed_on_socket_error;
|
||||||
|
|
||||||
Seat *seat;
|
Seat *seat;
|
||||||
@ -186,7 +187,6 @@ struct Telnet {
|
|||||||
bool in_synch;
|
bool in_synch;
|
||||||
int sb_opt;
|
int sb_opt;
|
||||||
strbuf *sb_buf;
|
strbuf *sb_buf;
|
||||||
bool session_started;
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
TOP_LEVEL, SEENIAC, SEENWILL, SEENWONT, SEENDO, SEENDONT,
|
TOP_LEVEL, SEENIAC, SEENWILL, SEENWONT, SEENDO, SEENDONT,
|
||||||
@ -619,7 +619,9 @@ static void telnet_log(Plug *plug, PlugLogType type, SockAddr *addr, int port,
|
|||||||
Telnet *telnet = container_of(plug, Telnet, plug);
|
Telnet *telnet = container_of(plug, Telnet, plug);
|
||||||
backend_socket_log(telnet->seat, telnet->logctx, type, addr, port,
|
backend_socket_log(telnet->seat, telnet->logctx, type, addr, port,
|
||||||
error_msg, error_code, telnet->conf,
|
error_msg, error_code, telnet->conf,
|
||||||
telnet->session_started);
|
telnet->socket_connected);
|
||||||
|
if (type == PLUGLOG_CONNECT_SUCCESS)
|
||||||
|
telnet->socket_connected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void telnet_closing(Plug *plug, const char *error_msg, int error_code,
|
static void telnet_closing(Plug *plug, const char *error_msg, int error_code,
|
||||||
@ -654,7 +656,6 @@ static void telnet_receive(
|
|||||||
Telnet *telnet = container_of(plug, Telnet, plug);
|
Telnet *telnet = container_of(plug, Telnet, plug);
|
||||||
if (urgent)
|
if (urgent)
|
||||||
telnet->in_synch = true;
|
telnet->in_synch = true;
|
||||||
telnet->session_started = true;
|
|
||||||
do_telnet_read(telnet, data, len);
|
do_telnet_read(telnet, data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -699,6 +700,7 @@ static char *telnet_init(const BackendVtable *vt, Seat *seat,
|
|||||||
telnet->backend.vt = vt;
|
telnet->backend.vt = vt;
|
||||||
telnet->conf = conf_copy(conf);
|
telnet->conf = conf_copy(conf);
|
||||||
telnet->s = NULL;
|
telnet->s = NULL;
|
||||||
|
telnet->socket_connected = false;
|
||||||
telnet->closed_on_socket_error = false;
|
telnet->closed_on_socket_error = false;
|
||||||
telnet->echoing = true;
|
telnet->echoing = true;
|
||||||
telnet->editing = true;
|
telnet->editing = true;
|
||||||
@ -711,7 +713,6 @@ static char *telnet_init(const BackendVtable *vt, Seat *seat,
|
|||||||
telnet->state = TOP_LEVEL;
|
telnet->state = TOP_LEVEL;
|
||||||
telnet->ldisc = NULL;
|
telnet->ldisc = NULL;
|
||||||
telnet->pinger = NULL;
|
telnet->pinger = NULL;
|
||||||
telnet->session_started = true;
|
|
||||||
*backend_handle = &telnet->backend;
|
*backend_handle = &telnet->backend;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1001,8 +1002,8 @@ static bool telnet_connected(Backend *be)
|
|||||||
|
|
||||||
static bool telnet_sendok(Backend *be)
|
static bool telnet_sendok(Backend *be)
|
||||||
{
|
{
|
||||||
/* Telnet *telnet = container_of(be, Telnet, backend); */
|
Telnet *telnet = container_of(be, Telnet, backend);
|
||||||
return true;
|
return telnet->socket_connected;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void telnet_unthrottle(Backend *be, size_t backlog)
|
static void telnet_unthrottle(Backend *be, size_t backlog)
|
||||||
|
9
putty.h
9
putty.h
@ -648,7 +648,14 @@ struct BackendVtable {
|
|||||||
int (*exitcode) (Backend *be);
|
int (*exitcode) (Backend *be);
|
||||||
/* If back->sendok() returns false, the backend doesn't currently
|
/* If back->sendok() returns false, the backend doesn't currently
|
||||||
* want input data, so the frontend should avoid acquiring any if
|
* want input data, so the frontend should avoid acquiring any if
|
||||||
* possible (passing back-pressure on to its sender). */
|
* possible (passing back-pressure on to its sender).
|
||||||
|
*
|
||||||
|
* Policy rule: no backend shall return true from sendok() while
|
||||||
|
* its network connection attempt is still ongoing. This ensures
|
||||||
|
* that if making the network connection involves a proxy type
|
||||||
|
* which wants to interact with the user via the terminal, the
|
||||||
|
* proxy implementation and the backend itself won't fight over
|
||||||
|
* who gets the terminal input. */
|
||||||
bool (*sendok) (Backend *be);
|
bool (*sendok) (Backend *be);
|
||||||
bool (*ldisc_option_state) (Backend *be, int);
|
bool (*ldisc_option_state) (Backend *be, int);
|
||||||
void (*provide_ldisc) (Backend *be, Ldisc *ldisc);
|
void (*provide_ldisc) (Backend *be, Ldisc *ldisc);
|
||||||
|
Loading…
Reference in New Issue
Block a user