1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-04-10 07:38:06 -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 pending_error; /* in case send() returns error */
int listener;
int nodelay, keepalive;
int privport, port;
struct Socket_tag *next;
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 void ot_recv(Actual_Socket s);
static void ot_listenaccept(Actual_Socket s);
static void ot_setoption(EndpointRef, OTXTILevel, OTXTIName, UInt32);
void ot_poll(void);
Socket ot_register(void *sock, Plug plug)
{
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->pending_error = 0;
ret->oobinline = oobinline;
ret->nodelay = nodelay;
ret->keepalive = keepalive;
ret->oobpending = FALSE;
ret->listener = 0;
@ -282,7 +288,15 @@ Socket ot_new(SockAddr addr, int port, int privport, int oobinline,
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.
@ -379,7 +393,7 @@ Socket ot_newlistener(char *srcaddr, int port, Plug plug, int local_host_only,
return (Socket) ret;
}
/* TODO: set SO_REUSEADDR */
ot_setoption(ep, INET_IP, IP_REUSEADDR, T_YES);
OTInitInetAddress(&addr, port, kOTAnyInetAddress);
/* XXX: pay attention to local_host_only */
@ -533,6 +547,12 @@ void ot_poll(void)
case T_LISTEN: /* Connection attempt */
ot_listenaccept(s);
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;
}
}
}
@ -581,7 +601,36 @@ void ot_listenaccept(Actual_Socket s)
OTCloseProvider(ep);
}
}
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:
* c-file-style: "simon"