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

Improve socket error handling so that a socket error isn't an

automatic fatalbox(). Instead, the error is passed to the receiver
routine, which can decide just how fatal the problem really is.

[originally from svn r894]
This commit is contained in:
Simon Tatham 2001-01-24 10:11:18 +00:00
parent 3082f7e8be
commit 89505459e3
7 changed files with 52 additions and 6 deletions

View File

@ -8,10 +8,6 @@
* send data without having to worry about blocking. The stuff
* behind the abstraction takes care of selects and nonblocking
* writes and all that sort of painful gubbins.
*
* If urgent data comes in on a socket, the back end will read and
* discard up to the urgent pointer, then read the urgent byte and
* send _that_ to the receiver function with `urgent' set.
*/
#ifndef PUTTY_NETWORK_H
@ -19,6 +15,24 @@
typedef struct Socket_tag *Socket;
typedef struct SockAddr_tag *SockAddr;
/*
* This is the function a client must register with each socket, to
* receive data coming in on that socket. The parameter `urgent'
* decides the meaning of `data' and `len':
*
* - urgent==0. `data' points to `len' bytes of perfectly ordinary
* data.
*
* - urgent==1. `data' points to `len' bytes of data, which were
* read from before an Urgent pointer.
*
* - urgent==2. `data' points to `len' bytes of data, the first of
* which was the one at the Urgent mark.
*
* - urgent==3. An error has occurred on the socket. `data' points
* to an error string, and `len' points to an error code.
*/
typedef int (*sk_receiver_t)(Socket s, int urgent, char *data, int len);
void sk_init(void); /* called once at program startup */

5
raw.c
View File

@ -25,6 +25,11 @@ static void c_write (char *buf, int len) {
}
static int raw_receive (Socket s, int urgent, char *data, int len) {
if (urgent==3) {
/* A socket error has occurred. */
connection_fatal(data);
len = 0;
}
if (!len) {
/* Connection has closed. */
sk_close(s);

View File

@ -25,6 +25,11 @@ static void c_write (char *buf, int len) {
}
static int rlogin_receive (Socket s, int urgent, char *data, int len) {
if (urgent==3) {
/* A socket error has occurred. */
connection_fatal(data);
len = 0;
}
if (!len) {
/* Connection has closed. */
sk_close(s);

5
ssh.c
View File

@ -1148,6 +1148,11 @@ static void ssh_gotdata(unsigned char *data, int datalen)
}
static int ssh_receive(Socket skt, int urgent, char *data, int len) {
if (urgent==3) {
/* A socket error has occurred. */
connection_fatal(data);
len = 0;
}
if (!len) {
/* Connection has closed. */
ssh_state = SSH_STATE_CLOSED;

View File

@ -461,6 +461,11 @@ static void do_telnet_read (char *buf, int len) {
}
static int telnet_receive(Socket s, int urgent, char *data, int len) {
if (urgent==3) {
/* A socket error has occurred. */
connection_fatal(data);
len = 0;
}
if (!len) {
/* Connection has closed. */
sk_close(s);

View File

@ -569,7 +569,11 @@ int select_result(WPARAM wParam, LPARAM lParam) {
return 1; /* boggle */
if ((err = WSAGETSELECTERROR(lParam)) != 0) {
fatalbox(winsock_error_string(err));
/*
* An error has occurred on this socket. Pass it to the
* receiver function.
*/
return s->receiver(s, 3, winsock_error_string(err), err);
}
noise_ultralight(lParam);
@ -584,7 +588,7 @@ int select_result(WPARAM wParam, LPARAM lParam) {
}
}
if (ret < 0) {
fatalbox(winsock_error_string(err));
return s->receiver(s, 3, winsock_error_string(err), err);
} else {
int type = s->in_oob ? 2 : 0;
s->in_oob = FALSE;

View File

@ -106,6 +106,14 @@ static int x11_verify(char *proto, unsigned char *data, int dlen) {
static int x11_receive (Socket s, int urgent, char *data, int len) {
struct X11Private *pr = (struct X11Private *)sk_get_private_ptr(s);
if (urgent==3) {
/*
* A socket error has occurred. We have no way to
* communicate this down the forwarded connection, so we'll
* just treat it like a proper close.
*/
len = 0;
}
if (!len) {
/* Connection has closed. */
sshfwd_close(pr->c);