1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-04-21 13:05:04 -05:00

Support for setting some options like keepalive, oobinline, nodelay, and

SO_REUSEADDR for ot_newlistener().  Also handle remote-initiated
disconnections.

[originally from svn r5388]
This commit is contained in:
Owen Dunn 2005-02-23 21:19:53 +00:00
parent 6d47285462
commit 71e91e2bcc

View File

@ -37,6 +37,8 @@ struct Socket_tag {
int oobinline; int oobinline;
int pending_error; /* in case send() returns error */ int pending_error; /* in case send() returns error */
int listener; int listener;
int nodelay, keepalive;
int privport, port;
struct Socket_tag *next; struct Socket_tag *next;
struct Socket_tag **prev; struct Socket_tag **prev;
}; };
@ -188,8 +190,10 @@ static void ot_tcp_set_frozen(Socket s, int is_frozen);
static const char *ot_tcp_socket_error(Socket s); static const char *ot_tcp_socket_error(Socket s);
static void ot_recv(Actual_Socket s); static void ot_recv(Actual_Socket s);
static void ot_listenaccept(Actual_Socket s); static void ot_listenaccept(Actual_Socket s);
static void ot_setoption(EndpointRef, OTXTILevel, OTXTIName, UInt32);
void ot_poll(void); void ot_poll(void);
Socket ot_register(void *sock, Plug plug) Socket ot_register(void *sock, Plug plug)
{ {
static struct socket_function_table fn_table = { static struct socket_function_table fn_table = {
@ -268,6 +272,8 @@ Socket ot_new(SockAddr addr, int port, int privport, int oobinline,
ret->localhost_only = 0; /* unused, but best init anyway */ ret->localhost_only = 0; /* unused, but best init anyway */
ret->pending_error = 0; ret->pending_error = 0;
ret->oobinline = oobinline; ret->oobinline = oobinline;
ret->nodelay = nodelay;
ret->keepalive = keepalive;
ret->oobpending = FALSE; ret->oobpending = FALSE;
ret->listener = 0; ret->listener = 0;
@ -282,7 +288,15 @@ Socket ot_new(SockAddr addr, int port, int privport, int oobinline,
return (Socket) ret; return (Socket) ret;
} }
/* TODO: oobinline, nodelay, keepalive */ if (ret->oobinline)
ot_setoption(ep, INET_TCP, TCP_OOBINLINE, T_YES);
if (ret->nodelay)
ot_setoption(ep, INET_TCP, TCP_NODELAY, T_YES);
if (ret->keepalive) {
ot_setoption(ep, INET_TCP, TCP_KEEPALIVE, T_YES);
}
/* /*
* Bind to local address. * Bind to local address.
@ -379,7 +393,7 @@ Socket ot_newlistener(char *srcaddr, int port, Plug plug, int local_host_only,
return (Socket) ret; return (Socket) ret;
} }
/* TODO: set SO_REUSEADDR */ ot_setoption(ep, INET_IP, IP_REUSEADDR, T_YES);
OTInitInetAddress(&addr, port, kOTAnyInetAddress); OTInitInetAddress(&addr, port, kOTAnyInetAddress);
/* XXX: pay attention to local_host_only */ /* XXX: pay attention to local_host_only */
@ -533,6 +547,12 @@ void ot_poll(void)
case T_LISTEN: /* Connection attempt */ case T_LISTEN: /* Connection attempt */
ot_listenaccept(s); ot_listenaccept(s);
break; break;
case T_ORDREL: /* Orderly disconnect */
plug_closing(s->plug, NULL, 0, 0);
break;
case T_DISCONNECT: /* Abortive disconnect*/
plug_closing(s->plug, NULL, 0, 0);
break;
} }
} }
} }
@ -582,6 +602,35 @@ void ot_listenaccept(Actual_Socket s)
} }
} }
static void ot_setoption(EndpointRef ep,
OTXTILevel level,
OTXTIName name,
UInt32 value)
{
TOption option;
TOptMgmt request;
TOptMgmt result;
if (name == TCP_KEEPALIVE) {
option.len = sizeof(struct t_kpalive);
option.value[1] = T_UNSPEC;
} else
option.len = kOTFourByteOptionSize;
option.level = level;
option.name = name;
option.status = 0;
option.value[0] = value;
request.opt.buf = (unsigned char *) &option;
request.opt.len = sizeof(option);
request.flags = T_NEGOTIATE;
result.opt.buf = (unsigned char *) &option;
result.opt.maxlen = sizeof(option);
OTOptionManagement(ep, &request, &result);
}
/* /*
* Local Variables: * Local Variables:
* c-file-style: "simon" * c-file-style: "simon"