summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/luatexdir/luasocket/src/tcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/luasocket/src/tcp.c')
-rw-r--r--Build/source/texk/web2c/luatexdir/luasocket/src/tcp.c170
1 files changed, 73 insertions, 97 deletions
diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/tcp.c b/Build/source/texk/web2c/luatexdir/luasocket/src/tcp.c
index e7334031478..ef9ee6f9c2f 100644
--- a/Build/source/texk/web2c/luatexdir/luasocket/src/tcp.c
+++ b/Build/source/texk/web2c/luatexdir/luasocket/src/tcp.c
@@ -6,6 +6,7 @@
#include "lua.h"
#include "lauxlib.h"
+#include "compat.h"
#include "auxiliar.h"
#include "socket.h"
@@ -17,6 +18,7 @@
* Internal function prototypes
\*=========================================================================*/
static int global_create(lua_State *L);
+static int global_create4(lua_State *L);
static int global_create6(lua_State *L);
static int global_connect(lua_State *L);
static int meth_connect(lua_State *L);
@@ -34,6 +36,7 @@ static int meth_accept(lua_State *L);
static int meth_close(lua_State *L);
static int meth_getoption(lua_State *L);
static int meth_setoption(lua_State *L);
+static int meth_gettimeout(lua_State *L);
static int meth_settimeout(lua_State *L);
static int meth_getfd(lua_State *L);
static int meth_setfd(lua_State *L);
@@ -63,6 +66,7 @@ static luaL_Reg tcp_methods[] = {
{"setpeername", meth_connect},
{"setsockname", meth_bind},
{"settimeout", meth_settimeout},
+ {"gettimeout", meth_gettimeout},
{"shutdown", meth_shutdown},
{NULL, NULL}
};
@@ -71,14 +75,17 @@ static luaL_Reg tcp_methods[] = {
static t_opt optget[] = {
{"keepalive", opt_get_keepalive},
{"reuseaddr", opt_get_reuseaddr},
+ {"reuseport", opt_get_reuseport},
{"tcp-nodelay", opt_get_tcp_nodelay},
{"linger", opt_get_linger},
+ {"error", opt_get_error},
{NULL, NULL}
};
static t_opt optset[] = {
{"keepalive", opt_set_keepalive},
{"reuseaddr", opt_set_reuseaddr},
+ {"reuseport", opt_set_reuseport},
{"tcp-nodelay", opt_set_tcp_nodelay},
{"ipv6-v6only", opt_set_ip6_v6only},
{"linger", opt_set_linger},
@@ -88,6 +95,7 @@ static t_opt optset[] = {
/* functions in library namespace */
static luaL_Reg func[] = {
{"tcp", global_create},
+ {"tcp4", global_create4},
{"tcp6", global_create6},
{"connect", global_connect},
{NULL, NULL}
@@ -99,15 +107,15 @@ static luaL_Reg func[] = {
int tcp_open(lua_State *L)
{
/* create classes */
- auxiliar_newclass(L, "tcp.master", tcp_methods);
- auxiliar_newclass(L, "tcp.client", tcp_methods);
- auxiliar_newclass(L, "tcp.server", tcp_methods);
+ auxiliar_newclass(L, "tcp{master}", tcp_methods);
+ auxiliar_newclass(L, "tcp{client}", tcp_methods);
+ auxiliar_newclass(L, "tcp{server}", tcp_methods);
/* create class groups */
- auxiliar_add2group(L, "tcp.master", "tcp{any}");
- auxiliar_add2group(L, "tcp.client", "tcp{any}");
- auxiliar_add2group(L, "tcp.server", "tcp{any}");
+ auxiliar_add2group(L, "tcp{master}", "tcp{any}");
+ auxiliar_add2group(L, "tcp{client}", "tcp{any}");
+ auxiliar_add2group(L, "tcp{server}", "tcp{any}");
/* define library functions */
- luaL_openlib(L, NULL, func, 0);
+ luaL_setfuncs(L, func, 0);
return 0;
}
@@ -118,22 +126,22 @@ int tcp_open(lua_State *L)
* Just call buffered IO methods
\*-------------------------------------------------------------------------*/
static int meth_send(lua_State *L) {
- p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp.client", 1);
+ p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1);
return buffer_meth_send(L, &tcp->buf);
}
static int meth_receive(lua_State *L) {
- p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp.client", 1);
+ p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1);
return buffer_meth_receive(L, &tcp->buf);
}
static int meth_getstats(lua_State *L) {
- p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp.client", 1);
+ p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1);
return buffer_meth_getstats(L, &tcp->buf);
}
static int meth_setstats(lua_State *L) {
- p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp.client", 1);
+ p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1);
return buffer_meth_setstats(L, &tcp->buf);
}
@@ -183,14 +191,14 @@ static int meth_dirty(lua_State *L)
\*-------------------------------------------------------------------------*/
static int meth_accept(lua_State *L)
{
- p_tcp server = (p_tcp) auxiliar_checkclass(L, "tcp.server", 1);
+ p_tcp server = (p_tcp) auxiliar_checkclass(L, "tcp{server}", 1);
p_timeout tm = timeout_markstart(&server->tm);
t_socket sock;
const char *err = inet_tryaccept(&server->sock, server->family, &sock, tm);
/* if successful, push client socket */
if (err == NULL) {
p_tcp clnt = (p_tcp) lua_newuserdata(L, sizeof(t_tcp));
- auxiliar_setclass(L, "tcp.client", -1);
+ auxiliar_setclass(L, "tcp{client}", -1);
/* initialize structure fields */
memset(clnt, 0, sizeof(t_tcp));
socket_setnonblocking(&sock);
@@ -211,9 +219,8 @@ static int meth_accept(lua_State *L)
/*-------------------------------------------------------------------------*\
* Binds an object to an address
\*-------------------------------------------------------------------------*/
-static int meth_bind(lua_State *L)
-{
- p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp.master", 1);
+static int meth_bind(lua_State *L) {
+ p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{master}", 1);
const char *address = luaL_checkstring(L, 2);
const char *port = luaL_checkstring(L, 3);
const char *err;
@@ -222,8 +229,7 @@ static int meth_bind(lua_State *L)
bindhints.ai_socktype = SOCK_STREAM;
bindhints.ai_family = tcp->family;
bindhints.ai_flags = AI_PASSIVE;
- address = strcmp(address, "*")? address: NULL;
- err = inet_trybind(&tcp->sock, address, port, &bindhints);
+ err = inet_trybind(&tcp->sock, &tcp->family, address, port, &bindhints);
if (err) {
lua_pushnil(L);
lua_pushstring(L, err);
@@ -236,8 +242,7 @@ static int meth_bind(lua_State *L)
/*-------------------------------------------------------------------------*\
* Turns a master tcp object into a client object.
\*-------------------------------------------------------------------------*/
-static int meth_connect(lua_State *L)
-{
+static int meth_connect(lua_State *L) {
p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
const char *address = luaL_checkstring(L, 2);
const char *port = luaL_checkstring(L, 3);
@@ -248,9 +253,10 @@ static int meth_connect(lua_State *L)
/* make sure we try to connect only to the same family */
connecthints.ai_family = tcp->family;
timeout_markstart(&tcp->tm);
- err = inet_tryconnect(&tcp->sock, address, port, &tcp->tm, &connecthints);
+ err = inet_tryconnect(&tcp->sock, &tcp->family, address, port,
+ &tcp->tm, &connecthints);
/* have to set the class even if it failed due to non-blocking connects */
- auxiliar_setclass(L, "tcp.client", 1);
+ auxiliar_setclass(L, "tcp{client}", 1);
if (err) {
lua_pushnil(L);
lua_pushstring(L, err);
@@ -277,9 +283,12 @@ static int meth_close(lua_State *L)
static int meth_getfamily(lua_State *L)
{
p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
- if (tcp->family == PF_INET6) {
+ if (tcp->family == AF_INET6) {
lua_pushliteral(L, "inet6");
return 1;
+ } else if (tcp->family == AF_INET) {
+ lua_pushliteral(L, "inet4");
+ return 1;
} else {
lua_pushliteral(L, "inet4");
return 1;
@@ -291,7 +300,7 @@ static int meth_getfamily(lua_State *L)
\*-------------------------------------------------------------------------*/
static int meth_listen(lua_State *L)
{
- p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp.master", 1);
+ p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{master}", 1);
int backlog = (int) luaL_optnumber(L, 2, 32);
int err = socket_listen(&tcp->sock, backlog);
if (err != IO_DONE) {
@@ -300,7 +309,7 @@ static int meth_listen(lua_State *L)
return 2;
}
/* turn master object into a server object */
- auxiliar_setclass(L, "tcp.server", 1);
+ auxiliar_setclass(L, "tcp{server}", 1);
lua_pushnumber(L, 1);
return 1;
}
@@ -312,7 +321,7 @@ static int meth_shutdown(lua_State *L)
{
/* SHUT_RD, SHUT_WR, SHUT_RDWR have the value 0, 1, 2, so we can use method index directly */
static const char* methods[] = { "receive", "send", "both", NULL };
- p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp.client", 1);
+ p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1);
int how = luaL_checkoption(L, 2, "both", methods);
socket_shutdown(&tcp->sock, how);
lua_pushnumber(L, 1);
@@ -343,6 +352,12 @@ static int meth_settimeout(lua_State *L)
return timeout_meth_settimeout(L, &tcp->tm);
}
+static int meth_gettimeout(lua_State *L)
+{
+ p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
+ return timeout_meth_gettimeout(L, &tcp->tm);
+}
+
/*=========================================================================*\
* Library functions
\*=========================================================================*/
@@ -350,37 +365,36 @@ static int meth_settimeout(lua_State *L)
* Creates a master tcp object
\*-------------------------------------------------------------------------*/
static int tcp_create(lua_State *L, int family) {
- t_socket sock;
- const char *err = inet_trycreate(&sock, family, SOCK_STREAM);
- /* try to allocate a system socket */
- if (!err) {
- /* allocate tcp object */
- p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp));
- memset(tcp, 0, sizeof(t_tcp));
- /* set its type as master object */
- auxiliar_setclass(L, "tcp.master", -1);
- /* initialize remaining structure fields */
- socket_setnonblocking(&sock);
- if (family == PF_INET6) {
- int yes = 1;
- setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY,
- (void *)&yes, sizeof(yes));
+ p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp));
+ memset(tcp, 0, sizeof(t_tcp));
+ /* set its type as master object */
+ auxiliar_setclass(L, "tcp{master}", -1);
+ /* if family is AF_UNSPEC, we leave the socket invalid and
+ * store AF_UNSPEC into family. This will allow it to later be
+ * replaced with an AF_INET6 or AF_INET socket upon first use. */
+ tcp->sock = SOCKET_INVALID;
+ tcp->family = family;
+ io_init(&tcp->io, (p_send) socket_send, (p_recv) socket_recv,
+ (p_error) socket_ioerror, &tcp->sock);
+ timeout_init(&tcp->tm, -1, -1);
+ buffer_init(&tcp->buf, &tcp->io, &tcp->tm);
+ if (family != AF_UNSPEC) {
+ const char *err = inet_trycreate(&tcp->sock, family, SOCK_STREAM, 0);
+ if (err != NULL) {
+ lua_pushnil(L);
+ lua_pushstring(L, err);
+ return 2;
}
- tcp->sock = sock;
- io_init(&tcp->io, (p_send) socket_send, (p_recv) socket_recv,
- (p_error) socket_ioerror, &tcp->sock);
- timeout_init(&tcp->tm, -1, -1);
- buffer_init(&tcp->buf, &tcp->io, &tcp->tm);
- tcp->family = family;
- return 1;
- } else {
- lua_pushnil(L);
- lua_pushstring(L, err);
- return 2;
+ socket_setnonblocking(&tcp->sock);
}
+ return 1;
}
static int global_create(lua_State *L) {
+ return tcp_create(L, AF_UNSPEC);
+}
+
+static int global_create4(lua_State *L) {
return tcp_create(L, AF_INET);
}
@@ -388,46 +402,6 @@ static int global_create6(lua_State *L) {
return tcp_create(L, AF_INET6);
}
-static const char *tryconnect6(const char *remoteaddr, const char *remoteserv,
- struct addrinfo *connecthints, p_tcp tcp) {
- struct addrinfo *iterator = NULL, *resolved = NULL;
- const char *err = NULL;
- /* try resolving */
- err = socket_gaistrerror(getaddrinfo(remoteaddr, remoteserv,
- connecthints, &resolved));
- if (err != NULL) {
- if (resolved) freeaddrinfo(resolved);
- return err;
- }
- /* iterate over all returned addresses trying to connect */
- for (iterator = resolved; iterator; iterator = iterator->ai_next) {
- p_timeout tm = timeout_markstart(&tcp->tm);
- /* create new socket if one wasn't created by the bind stage */
- if (tcp->sock == SOCKET_INVALID) {
- err = socket_strerror(socket_create(&tcp->sock,
- iterator->ai_family, iterator->ai_socktype,
- iterator->ai_protocol));
- if (err != NULL) {
- freeaddrinfo(resolved);
- return err;
- }
- tcp->family = iterator->ai_family;
- /* all sockets initially non-blocking */
- socket_setnonblocking(&tcp->sock);
- }
- /* finally try connecting to remote address */
- err = socket_strerror(socket_connect(&tcp->sock,
- (SA *) iterator->ai_addr,
- (socklen_t) iterator->ai_addrlen, tm));
- /* if success, break out of loop */
- if (err == NULL) break;
- }
-
- freeaddrinfo(resolved);
- /* here, if err is set, we failed */
- return err;
-}
-
static int global_connect(lua_State *L) {
const char *remoteaddr = luaL_checkstring(L, 1);
const char *remoteserv = luaL_checkstring(L, 2);
@@ -444,32 +418,34 @@ static int global_connect(lua_State *L) {
timeout_init(&tcp->tm, -1, -1);
buffer_init(&tcp->buf, &tcp->io, &tcp->tm);
tcp->sock = SOCKET_INVALID;
+ tcp->family = AF_UNSPEC;
/* allow user to pick local address and port */
memset(&bindhints, 0, sizeof(bindhints));
bindhints.ai_socktype = SOCK_STREAM;
bindhints.ai_family = family;
bindhints.ai_flags = AI_PASSIVE;
if (localaddr) {
- err = inet_trybind(&tcp->sock, localaddr, localserv, &bindhints);
+ err = inet_trybind(&tcp->sock, &tcp->family, localaddr,
+ localserv, &bindhints);
if (err) {
lua_pushnil(L);
lua_pushstring(L, err);
return 2;
}
- tcp->family = bindhints.ai_family;
}
/* try to connect to remote address and port */
memset(&connecthints, 0, sizeof(connecthints));
connecthints.ai_socktype = SOCK_STREAM;
/* make sure we try to connect only to the same family */
- connecthints.ai_family = bindhints.ai_family;
- err = tryconnect6(remoteaddr, remoteserv, &connecthints, tcp);
+ connecthints.ai_family = tcp->family;
+ err = inet_tryconnect(&tcp->sock, &tcp->family, remoteaddr, remoteserv,
+ &tcp->tm, &connecthints);
if (err) {
socket_destroy(&tcp->sock);
lua_pushnil(L);
lua_pushstring(L, err);
return 2;
}
- auxiliar_setclass(L, "tcp.client", -1);
+ auxiliar_setclass(L, "tcp{client}", -1);
return 1;
}