mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-27 02:02:26 +00:00
Yet another attempt at OOB handling in the network abstraction. This
version allows you to specify, per socket, which sockets receive OOB data in-line (so that you know what was before the mark and what was after) and which receive it out of line (so it's really a one-byte out-of-band facility rather than discard-to-mark). This reflects the fact that rlogin appears to make more sense in the latter mode, and telnet in the former. This patch makes rlogin work right for me. [originally from svn r921]
This commit is contained in:
parent
1e2b9ced01
commit
60585cff9c
@ -40,7 +40,8 @@ void sk_init(void); /* called once at program startup */
|
|||||||
SockAddr sk_namelookup(char *host, char **canonicalname);
|
SockAddr sk_namelookup(char *host, char **canonicalname);
|
||||||
void sk_addr_free(SockAddr addr);
|
void sk_addr_free(SockAddr addr);
|
||||||
|
|
||||||
Socket sk_new(SockAddr addr, int port, int privport, sk_receiver_t receiver);
|
Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
|
||||||
|
sk_receiver_t receiver);
|
||||||
void sk_close(Socket s);
|
void sk_close(Socket s);
|
||||||
void sk_write(Socket s, char *buf, int len);
|
void sk_write(Socket s, char *buf, int len);
|
||||||
void sk_write_oob(Socket s, char *buf, int len);
|
void sk_write_oob(Socket s, char *buf, int len);
|
||||||
|
2
raw.c
2
raw.c
@ -66,7 +66,7 @@ static char *raw_init (char *host, int port, char **realhost) {
|
|||||||
/*
|
/*
|
||||||
* Open socket.
|
* Open socket.
|
||||||
*/
|
*/
|
||||||
s = sk_new(addr, port, 0, raw_receive);
|
s = sk_new(addr, port, 0, 1, raw_receive);
|
||||||
if ( (err = sk_socket_error(s)) )
|
if ( (err = sk_socket_error(s)) )
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
2
rlogin.c
2
rlogin.c
@ -92,7 +92,7 @@ static char *rlogin_init (char *host, int port, char **realhost) {
|
|||||||
/*
|
/*
|
||||||
* Open socket.
|
* Open socket.
|
||||||
*/
|
*/
|
||||||
s = sk_new(addr, port, 1, rlogin_receive);
|
s = sk_new(addr, port, 1, 0, rlogin_receive);
|
||||||
if ( (err = sk_socket_error(s)) )
|
if ( (err = sk_socket_error(s)) )
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
2
ssh.c
2
ssh.c
@ -1219,7 +1219,7 @@ static char *connect_to_host(char *host, int port, char **realhost)
|
|||||||
/*
|
/*
|
||||||
* Open socket.
|
* Open socket.
|
||||||
*/
|
*/
|
||||||
s = sk_new(addr, port, 0, ssh_receive);
|
s = sk_new(addr, port, 0, 1, ssh_receive);
|
||||||
if ( (err = sk_socket_error(s)) )
|
if ( (err = sk_socket_error(s)) )
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
2
telnet.c
2
telnet.c
@ -507,7 +507,7 @@ static char *telnet_init (char *host, int port, char **realhost) {
|
|||||||
/*
|
/*
|
||||||
* Open socket.
|
* Open socket.
|
||||||
*/
|
*/
|
||||||
s = sk_new(addr, port, 0, telnet_receive);
|
s = sk_new(addr, port, 0, 1, telnet_receive);
|
||||||
if ( (err = sk_socket_error(s)) )
|
if ( (err = sk_socket_error(s)) )
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
51
winnet.c
51
winnet.c
@ -63,6 +63,7 @@ struct Socket_tag {
|
|||||||
struct buffer *head, *tail;
|
struct buffer *head, *tail;
|
||||||
int writable;
|
int writable;
|
||||||
int sending_oob;
|
int sending_oob;
|
||||||
|
int oobinline;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SockAddr_tag {
|
struct SockAddr_tag {
|
||||||
@ -288,7 +289,8 @@ void sk_addr_free(SockAddr addr) {
|
|||||||
sfree(addr);
|
sfree(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
Socket sk_new(SockAddr addr, int port, int privport, sk_receiver_t receiver) {
|
Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
|
||||||
|
sk_receiver_t receiver) {
|
||||||
SOCKET s;
|
SOCKET s;
|
||||||
#ifdef IPV6
|
#ifdef IPV6
|
||||||
SOCKADDR_IN6 a6;
|
SOCKADDR_IN6 a6;
|
||||||
@ -321,7 +323,9 @@ Socket sk_new(SockAddr addr, int port, int privport, sk_receiver_t receiver) {
|
|||||||
ret->error = winsock_error_string(err);
|
ret->error = winsock_error_string(err);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
{
|
|
||||||
|
ret->oobinline = oobinline;
|
||||||
|
if (oobinline) {
|
||||||
BOOL b = TRUE;
|
BOOL b = TRUE;
|
||||||
setsockopt (s, SOL_SOCKET, SO_OOBINLINE, (void *)&b, sizeof(b));
|
setsockopt (s, SOL_SOCKET, SO_OOBINLINE, (void *)&b, sizeof(b));
|
||||||
}
|
}
|
||||||
@ -583,13 +587,27 @@ int select_result(WPARAM wParam, LPARAM lParam) {
|
|||||||
|
|
||||||
switch (WSAGETSELECTEVENT(lParam)) {
|
switch (WSAGETSELECTEVENT(lParam)) {
|
||||||
case FD_READ:
|
case FD_READ:
|
||||||
atmark = 1;
|
/*
|
||||||
/* Some WinSock wrappers don't support this call, so we
|
* We have received data on the socket. For an oobinline
|
||||||
* deliberately don't check the return value. If the call
|
* socket, this might be data _before_ an urgent pointer,
|
||||||
* fails and does nothing, we will get back atmark==1,
|
* in which case we send it to the back end with type==1
|
||||||
* which is good enough to keep going at least. */
|
* (data prior to urgent).
|
||||||
ioctlsocket(s->s, SIOCATMARK, &atmark);
|
*/
|
||||||
|
if (s->oobinline) {
|
||||||
|
atmark = 1;
|
||||||
|
ioctlsocket(s->s, SIOCATMARK, &atmark);
|
||||||
|
/*
|
||||||
|
* Avoid checking the return value from ioctlsocket(),
|
||||||
|
* on the grounds that some WinSock wrappers don't
|
||||||
|
* support it. If it does nothing, we get atmark==1,
|
||||||
|
* which is equivalent to `no OOB pending', so the
|
||||||
|
* effect will be to non-OOB-ify any OOB data.
|
||||||
|
*/
|
||||||
|
} else
|
||||||
|
atmark = 1;
|
||||||
|
|
||||||
ret = recv(s->s, buf, sizeof(buf), 0);
|
ret = recv(s->s, buf, sizeof(buf), 0);
|
||||||
|
noise_ultralight(ret);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
err = WSAGetLastError();
|
err = WSAGetLastError();
|
||||||
if (err == WSAEWOULDBLOCK) {
|
if (err == WSAEWOULDBLOCK) {
|
||||||
@ -599,19 +617,16 @@ int select_result(WPARAM wParam, LPARAM lParam) {
|
|||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return s->receiver(s, 3, winsock_error_string(err), err);
|
return s->receiver(s, 3, winsock_error_string(err), err);
|
||||||
} else {
|
} else {
|
||||||
int type = 0;
|
return s->receiver(s, atmark ? 0 : 1, buf, ret);
|
||||||
if (atmark==0) {
|
|
||||||
ioctlsocket(s->s, SIOCATMARK, &atmark);
|
|
||||||
if(atmark) type = 2; else type = 1;
|
|
||||||
}
|
|
||||||
return s->receiver(s, type, buf, ret);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FD_OOB:
|
case FD_OOB:
|
||||||
/*
|
/*
|
||||||
* Read all data up to the OOB marker, and send it to the
|
* This will only happen on a non-oobinline socket. It
|
||||||
* receiver with urgent==1 (OOB pending).
|
* indicates that we can immediately perform an OOB read
|
||||||
*/
|
* and get back OOB data, which we will send to the back
|
||||||
|
* end with type==2 (urgent data).
|
||||||
|
*/
|
||||||
ret = recv(s->s, buf, sizeof(buf), MSG_OOB);
|
ret = recv(s->s, buf, sizeof(buf), MSG_OOB);
|
||||||
noise_ultralight(ret);
|
noise_ultralight(ret);
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
|
2
x11fwd.c
2
x11fwd.c
@ -163,7 +163,7 @@ char *x11_init (Socket *s, char *display, void *c) {
|
|||||||
/*
|
/*
|
||||||
* Open socket.
|
* Open socket.
|
||||||
*/
|
*/
|
||||||
*s = sk_new(addr, port, 0, x11_receive);
|
*s = sk_new(addr, port, 0, 1, x11_receive);
|
||||||
if ( (err = sk_socket_error(*s)) )
|
if ( (err = sk_socket_error(*s)) )
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user