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;
};
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 = {
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;
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.
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 */
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;
}
}
}
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"