X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=mac%2Fotnet.c;h=d5271e706517aab5d506672252ea1d62ccc8e648;hb=d83cd2f79bba111660262af0827296cb76e17040;hp=6bdad5026ca68b820c381441e44b02130817870d;hpb=54d45f602c072cb27cd3f61f37cb55af181038e6;p=PuTTY.git diff --git a/mac/otnet.c b/mac/otnet.c index 6bdad502..d5271e70 100644 --- a/mac/otnet.c +++ b/mac/otnet.c @@ -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"