summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/luatexdir/luasocket/src/inet.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/luasocket/src/inet.c')
-rw-r--r--Build/source/texk/web2c/luatexdir/luasocket/src/inet.c368
1 files changed, 174 insertions, 194 deletions
diff --git a/Build/source/texk/web2c/luatexdir/luasocket/src/inet.c b/Build/source/texk/web2c/luatexdir/luasocket/src/inet.c
index 8bad83e7aa1..f4c84044eb7 100644
--- a/Build/source/texk/web2c/luatexdir/luasocket/src/inet.c
+++ b/Build/source/texk/web2c/luatexdir/luasocket/src/inet.c
@@ -3,66 +3,15 @@
* LuaSocket toolkit
\*=========================================================================*/
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include "lua.h"
#include "lauxlib.h"
+#include "compat.h"
#include "inet.h"
-#if defined(__MINGW32__)
-const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt)
-{
- if (af == AF_INET)
- {
- struct sockaddr_in in;
- memset(&in, 0, sizeof(in));
- in.sin_family = AF_INET;
- memcpy(&in.sin_addr, src, sizeof(struct in_addr));
- getnameinfo((struct sockaddr *)&in, sizeof(struct
-sockaddr_in), dst, cnt, NULL, 0, NI_NUMERICHOST);
- return dst;
- }
- else if (af == AF_INET6)
- {
- struct sockaddr_in6 in;
- memset(&in, 0, sizeof(in));
- in.sin6_family = AF_INET6;
- memcpy(&in.sin6_addr, src, sizeof(struct in_addr6));
- getnameinfo((struct sockaddr *)&in, sizeof(struct
-sockaddr_in6), dst, cnt, NULL, 0, NI_NUMERICHOST);
- return dst;
- }
- return NULL;
-}
-
-int inet_pton(int af, const char *src, void *dst)
-{
- struct addrinfo hints, *res, *ressave;
-
- memset(&hints, 0, sizeof(struct addrinfo));
- hints.ai_family = af;
-
- if (getaddrinfo(src, NULL, &hints, &res) != 0)
- {
- return -1;
- }
-
- ressave = res;
-
- while (res)
- {
- memcpy(dst, res->ai_addr, res->ai_addrlen);
- res = res->ai_next;
- }
-
- freeaddrinfo(ressave);
- return 0;
-}
-
-#endif
-
-
/*=========================================================================*\
* Internal function prototypes.
\*=========================================================================*/
@@ -93,7 +42,7 @@ int inet_open(lua_State *L)
{
lua_pushstring(L, "dns");
lua_newtable(L);
- luaL_openlib(L, NULL, func, 0);
+ luaL_setfuncs(L, func, 0);
lua_settable(L, -3);
return 0;
}
@@ -132,24 +81,22 @@ static int inet_global_tohostname(lua_State *L) {
}
static int inet_global_getnameinfo(lua_State *L) {
+ char hbuf[NI_MAXHOST];
+ char sbuf[NI_MAXSERV];
int i, ret;
- char host[1024];
- char serv[32];
struct addrinfo hints;
struct addrinfo *resolved, *iter;
- const char *node = luaL_optstring(L, 1, NULL);
- const char *service = luaL_optstring(L, 2, NULL);
+ const char *host = luaL_optstring(L, 1, NULL);
+ const char *serv = luaL_optstring(L, 2, NULL);
- if (!(node || service))
- luaL_error(L, "You have to specify a hostname, a service, or both");
+ if (!(host || serv))
+ luaL_error(L, "host and serv cannot be both nil");
memset(&hints, 0, sizeof(hints));
hints.ai_socktype = SOCK_STREAM;
- hints.ai_family = PF_UNSPEC;
+ hints.ai_family = AF_UNSPEC;
- /* getaddrinfo must get a node and a service argument */
- ret = getaddrinfo(node ? node : "127.0.0.1", service ? service : "7",
- &hints, &resolved);
+ ret = getaddrinfo(host, serv, &hints, &resolved);
if (ret != 0) {
lua_pushnil(L);
lua_pushstring(L, socket_gaistrerror(ret));
@@ -158,19 +105,19 @@ static int inet_global_getnameinfo(lua_State *L) {
lua_newtable(L);
for (i = 1, iter = resolved; iter; i++, iter = iter->ai_next) {
- getnameinfo(iter->ai_addr, (socklen_t) iter->ai_addrlen, host,
- node ? (socklen_t) sizeof(host) : 0, serv, service ? (socklen_t) sizeof(serv) : 0, 0);
-
- if (node) {
+ getnameinfo(iter->ai_addr, (socklen_t) iter->ai_addrlen,
+ hbuf, host? (socklen_t) sizeof(hbuf): 0,
+ sbuf, serv? (socklen_t) sizeof(sbuf): 0, 0);
+ if (host) {
lua_pushnumber(L, i);
- lua_pushstring(L, host);
+ lua_pushstring(L, hbuf);
lua_settable(L, -3);
}
}
freeaddrinfo(resolved);
- if (service) {
- lua_pushstring(L, serv);
+ if (serv) {
+ lua_pushstring(L, sbuf);
return 2;
} else {
return 1;
@@ -199,7 +146,7 @@ static int inet_global_toip(lua_State *L)
int inet_optfamily(lua_State* L, int narg, const char* def)
{
static const char* optname[] = { "unspec", "inet", "inet6", NULL };
- static int optvalue[] = { PF_UNSPEC, PF_INET, PF_INET6, 0 };
+ static int optvalue[] = { AF_UNSPEC, AF_INET, AF_INET6, 0 };
return optvalue[luaL_checkoption(L, narg, def, optname)];
}
@@ -220,7 +167,7 @@ static int inet_global_getaddrinfo(lua_State *L)
int i = 1, ret = 0;
memset(&hints, 0, sizeof(hints));
hints.ai_socktype = SOCK_STREAM;
- hints.ai_family = PF_UNSPEC;
+ hints.ai_family = AF_UNSPEC;
ret = getaddrinfo(hostname, NULL, &hints, &resolved);
if (ret != 0) {
lua_pushnil(L);
@@ -229,9 +176,15 @@ static int inet_global_getaddrinfo(lua_State *L)
}
lua_newtable(L);
for (iterator = resolved; iterator; iterator = iterator->ai_next) {
- char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
- getnameinfo(iterator->ai_addr, (socklen_t) iterator->ai_addrlen, hbuf,
- (socklen_t) sizeof(hbuf), sbuf, 0, NI_NUMERICHOST);
+ char hbuf[NI_MAXHOST];
+ ret = getnameinfo(iterator->ai_addr, (socklen_t) iterator->ai_addrlen,
+ hbuf, (socklen_t) sizeof(hbuf), NULL, 0, NI_NUMERICHOST);
+ if (ret){
+ freeaddrinfo(resolved);
+ lua_pushnil(L);
+ lua_pushstring(L, socket_gaistrerror(ret));
+ return 2;
+ }
lua_pushnumber(L, i);
lua_newtable(L);
switch (iterator->ai_family) {
@@ -244,7 +197,17 @@ static int inet_global_getaddrinfo(lua_State *L)
lua_pushliteral(L, "family");
lua_pushliteral(L, "inet6");
lua_settable(L, -3);
- break;;
+ break;
+ case AF_UNSPEC:
+ lua_pushliteral(L, "family");
+ lua_pushliteral(L, "unspec");
+ lua_settable(L, -3);
+ break;
+ default:
+ lua_pushliteral(L, "family");
+ lua_pushliteral(L, "unknown");
+ lua_settable(L, -3);
+ break;
}
lua_pushliteral(L, "addr");
lua_pushstring(L, hbuf);
@@ -256,7 +219,6 @@ static int inet_global_getaddrinfo(lua_State *L)
return 1;
}
-
/*-------------------------------------------------------------------------*\
* Gets the host name
\*-------------------------------------------------------------------------*/
@@ -274,8 +236,6 @@ static int inet_global_gethostname(lua_State *L)
}
}
-
-
/*=========================================================================*\
* Lua methods
\*=========================================================================*/
@@ -284,44 +244,33 @@ static int inet_global_gethostname(lua_State *L)
\*-------------------------------------------------------------------------*/
int inet_meth_getpeername(lua_State *L, p_socket ps, int family)
{
+ int err;
+ struct sockaddr_storage peer;
+ socklen_t peer_len = sizeof(peer);
+ char name[INET6_ADDRSTRLEN];
+ char port[6]; /* 65535 = 5 bytes + 0 to terminate it */
+ if (getpeername(*ps, (SA *) &peer, &peer_len) < 0) {
+ lua_pushnil(L);
+ lua_pushstring(L, socket_strerror(errno));
+ return 2;
+ }
+ err = getnameinfo((struct sockaddr *) &peer, peer_len,
+ name, INET6_ADDRSTRLEN,
+ port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV);
+ if (err) {
+ lua_pushnil(L);
+ lua_pushstring(L, gai_strerror(err));
+ return 2;
+ }
+ lua_pushstring(L, name);
+ lua_pushinteger(L, (int) strtol(port, (char **) NULL, 10));
switch (family) {
- case PF_INET: {
- struct sockaddr_in peer;
- socklen_t peer_len = sizeof(peer);
- char name[INET_ADDRSTRLEN];
- if (getpeername(*ps, (SA *) &peer, &peer_len) < 0) {
- lua_pushnil(L);
- lua_pushstring(L, socket_strerror(errno));
- return 2;
- } else {
- inet_ntop(family, &peer.sin_addr, name, sizeof(name));
- lua_pushstring(L, name);
- lua_pushnumber(L, ntohs(peer.sin_port));
- lua_pushliteral(L, "inet");
- return 3;
- }
- }
- case PF_INET6: {
- struct sockaddr_in6 peer;
- socklen_t peer_len = sizeof(peer);
- char name[INET6_ADDRSTRLEN];
- if (getpeername(*ps, (SA *) &peer, &peer_len) < 0) {
- lua_pushnil(L);
- lua_pushstring(L, socket_strerror(errno));
- return 2;
- } else {
- inet_ntop(family, &peer.sin6_addr, name, sizeof(name));
- lua_pushstring(L, name);
- lua_pushnumber(L, ntohs(peer.sin6_port));
- lua_pushliteral(L, "inet6");
- return 3;
- }
- }
- default:
- lua_pushnil(L);
- lua_pushfstring(L, "unknown family %d", family);
- return 2;
+ case AF_INET: lua_pushliteral(L, "inet"); break;
+ case AF_INET6: lua_pushliteral(L, "inet6"); break;
+ case AF_UNSPEC: lua_pushliteral(L, "unspec"); break;
+ default: lua_pushliteral(L, "unknown"); break;
}
+ return 3;
}
/*-------------------------------------------------------------------------*\
@@ -329,44 +278,32 @@ int inet_meth_getpeername(lua_State *L, p_socket ps, int family)
\*-------------------------------------------------------------------------*/
int inet_meth_getsockname(lua_State *L, p_socket ps, int family)
{
+ int err;
+ struct sockaddr_storage peer;
+ socklen_t peer_len = sizeof(peer);
+ char name[INET6_ADDRSTRLEN];
+ char port[6]; /* 65535 = 5 bytes + 0 to terminate it */
+ if (getsockname(*ps, (SA *) &peer, &peer_len) < 0) {
+ lua_pushnil(L);
+ lua_pushstring(L, socket_strerror(errno));
+ return 2;
+ }
+ err=getnameinfo((struct sockaddr *)&peer, peer_len,
+ name, INET6_ADDRSTRLEN, port, 6, NI_NUMERICHOST | NI_NUMERICSERV);
+ if (err) {
+ lua_pushnil(L);
+ lua_pushstring(L, gai_strerror(err));
+ return 2;
+ }
+ lua_pushstring(L, name);
+ lua_pushstring(L, port);
switch (family) {
- case PF_INET: {
- struct sockaddr_in local;
- socklen_t local_len = sizeof(local);
- char name[INET_ADDRSTRLEN];
- if (getsockname(*ps, (SA *) &local, &local_len) < 0) {
- lua_pushnil(L);
- lua_pushstring(L, socket_strerror(errno));
- return 2;
- } else {
- inet_ntop(family, &local.sin_addr, name, sizeof(name));
- lua_pushstring(L, name);
- lua_pushnumber(L, ntohs(local.sin_port));
- lua_pushliteral(L, "inet");
- return 3;
- }
- }
- case PF_INET6: {
- struct sockaddr_in6 local;
- socklen_t local_len = sizeof(local);
- char name[INET6_ADDRSTRLEN];
- if (getsockname(*ps, (SA *) &local, &local_len) < 0) {
- lua_pushnil(L);
- lua_pushstring(L, socket_strerror(errno));
- return 2;
- } else {
- inet_ntop(family, &local.sin6_addr, name, sizeof(name));
- lua_pushstring(L, name);
- lua_pushnumber(L, ntohs(local.sin6_port));
- lua_pushliteral(L, "inet6");
- return 3;
- }
- }
- default:
- lua_pushnil(L);
- lua_pushfstring(L, "unknown family %d", family);
- return 2;
+ case AF_INET: lua_pushliteral(L, "inet"); break;
+ case AF_INET6: lua_pushliteral(L, "inet6"); break;
+ case AF_UNSPEC: lua_pushliteral(L, "unspec"); break;
+ default: lua_pushliteral(L, "unknown"); break;
}
+ return 3;
}
/*=========================================================================*\
@@ -415,8 +352,13 @@ static void inet_pushresolved(lua_State *L, struct hostent *hp)
/*-------------------------------------------------------------------------*\
* Tries to create a new inet socket
\*-------------------------------------------------------------------------*/
-const char *inet_trycreate(p_socket ps, int family, int type) {
- return socket_strerror(socket_create(ps, family, type, 0));
+const char *inet_trycreate(p_socket ps, int family, int type, int protocol) {
+ const char *err = socket_strerror(socket_create(ps, family, type, protocol));
+ if (err == NULL && family == AF_INET6) {
+ int yes = 1;
+ setsockopt(*ps, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&yes, sizeof(yes));
+ }
+ return err;
}
/*-------------------------------------------------------------------------*\
@@ -425,22 +367,21 @@ const char *inet_trycreate(p_socket ps, int family, int type) {
const char *inet_trydisconnect(p_socket ps, int family, p_timeout tm)
{
switch (family) {
- case PF_INET: {
+ case AF_INET: {
struct sockaddr_in sin;
memset((char *) &sin, 0, sizeof(sin));
sin.sin_family = AF_UNSPEC;
sin.sin_addr.s_addr = INADDR_ANY;
- return socket_strerror(socket_connect(ps, (SA *) &sin,
+ return socket_strerror(socket_connect(ps, (SA *) &sin,
sizeof(sin), tm));
}
- case PF_INET6: {
+ case AF_INET6: {
struct sockaddr_in6 sin6;
- struct in6_addr addrany = IN6ADDR_ANY_INIT;
+ struct in6_addr addrany = IN6ADDR_ANY_INIT;
memset((char *) &sin6, 0, sizeof(sin6));
sin6.sin6_family = AF_UNSPEC;
-fprintf(stderr, "disconnecting\n");
sin6.sin6_addr = addrany;
- return socket_strerror(socket_connect(ps, (SA *) &sin6,
+ return socket_strerror(socket_connect(ps, (SA *) &sin6,
sizeof(sin6), tm));
}
}
@@ -450,11 +391,12 @@ fprintf(stderr, "disconnecting\n");
/*-------------------------------------------------------------------------*\
* Tries to connect to remote address (address, port)
\*-------------------------------------------------------------------------*/
-const char *inet_tryconnect(p_socket ps, const char *address,
+const char *inet_tryconnect(p_socket ps, int *family, const char *address,
const char *serv, p_timeout tm, struct addrinfo *connecthints)
{
struct addrinfo *iterator = NULL, *resolved = NULL;
const char *err = NULL;
+ int current_family = *family;
/* try resolving */
err = socket_gaistrerror(getaddrinfo(address, serv,
connecthints, &resolved));
@@ -464,11 +406,28 @@ const char *inet_tryconnect(p_socket ps, const char *address,
}
for (iterator = resolved; iterator; iterator = iterator->ai_next) {
timeout_markstart(tm);
+ /* create new socket if necessary. if there was no
+ * bind, we need to create one for every new family
+ * that shows up while iterating. if there was a
+ * bind, all families will be the same and we will
+ * not enter this branch. */
+ if (current_family != iterator->ai_family || *ps == SOCKET_INVALID) {
+ socket_destroy(ps);
+ err = inet_trycreate(ps, iterator->ai_family,
+ iterator->ai_socktype, iterator->ai_protocol);
+ if (err) continue;
+ current_family = iterator->ai_family;
+ /* set non-blocking before connect */
+ socket_setnonblocking(ps);
+ }
/* try connecting to remote address */
- err = socket_strerror(socket_connect(ps, (SA *) iterator->ai_addr,
+ err = socket_strerror(socket_connect(ps, (SA *) iterator->ai_addr,
(socklen_t) iterator->ai_addrlen, tm));
- /* if success, break out of loop */
- if (err == NULL) break;
+ /* if success or timeout is zero, break out of loop */
+ if (err == NULL || timeout_iszero(tm)) {
+ *family = current_family;
+ break;
+ }
}
freeaddrinfo(resolved);
/* here, if err is set, we failed */
@@ -478,27 +437,30 @@ const char *inet_tryconnect(p_socket ps, const char *address,
/*-------------------------------------------------------------------------*\
* Tries to accept a socket
\*-------------------------------------------------------------------------*/
-const char *inet_tryaccept(p_socket server, int family, p_socket client, p_timeout tm)
-{
+const char *inet_tryaccept(p_socket server, int family, p_socket client,
+ p_timeout tm) {
socklen_t len;
t_sockaddr_storage addr;
- if (family == PF_INET6) {
- len = sizeof(struct sockaddr_in6);
- } else {
- len = sizeof(struct sockaddr_in);
- }
- return socket_strerror(socket_accept(server, client, (SA *) &addr, &len, tm));
+ switch (family) {
+ case AF_INET6: len = sizeof(struct sockaddr_in6); break;
+ case AF_INET: len = sizeof(struct sockaddr_in); break;
+ default: len = sizeof(addr); break;
+ }
+ return socket_strerror(socket_accept(server, client, (SA *) &addr,
+ &len, tm));
}
/*-------------------------------------------------------------------------*\
* Tries to bind socket to (address, port)
\*-------------------------------------------------------------------------*/
-const char *inet_trybind(p_socket ps, const char *address, const char *serv,
- struct addrinfo *bindhints)
-{
+const char *inet_trybind(p_socket ps, int *family, const char *address,
+ const char *serv, struct addrinfo *bindhints) {
struct addrinfo *iterator = NULL, *resolved = NULL;
const char *err = NULL;
- t_socket sock = *ps;
+ int current_family = *family;
+ /* translate luasocket special values to C */
+ if (strcmp(address, "*") == 0) address = NULL;
+ if (!serv) serv = "0";
/* try resolving */
err = socket_gaistrerror(getaddrinfo(address, serv, bindhints, &resolved));
if (err) {
@@ -507,38 +469,34 @@ const char *inet_trybind(p_socket ps, const char *address, const char *serv,
}
/* iterate over resolved addresses until one is good */
for (iterator = resolved; iterator; iterator = iterator->ai_next) {
- if(sock == SOCKET_INVALID) {
- err = socket_strerror(socket_create(&sock, iterator->ai_family,
- iterator->ai_socktype, iterator->ai_protocol));
- if(err)
- continue;
+ if (current_family != iterator->ai_family || *ps == SOCKET_INVALID) {
+ socket_destroy(ps);
+ err = inet_trycreate(ps, iterator->ai_family,
+ iterator->ai_socktype, iterator->ai_protocol);
+ if (err) continue;
+ current_family = iterator->ai_family;
}
/* try binding to local address */
- err = socket_strerror(socket_bind(&sock,
- (SA *) iterator->ai_addr,
+ err = socket_strerror(socket_bind(ps, (SA *) iterator->ai_addr,
(socklen_t) iterator->ai_addrlen));
-
/* keep trying unless bind succeeded */
- if (err) {
- if(sock != *ps)
- socket_destroy(&sock);
- } else {
- /* remember what we connected to, particularly the family */
- *bindhints = *iterator;
+ if (err == NULL) {
+ *family = current_family;
+ /* set to non-blocking after bind */
+ socket_setnonblocking(ps);
break;
}
}
/* cleanup and return error */
freeaddrinfo(resolved);
- *ps = sock;
+ /* here, if err is set, we failed */
return err;
}
/*-------------------------------------------------------------------------*\
-* Some systems do not provide this so that we provide our own. It's not
-* marvelously fast, but it works just fine.
+* Some systems do not provide these so that we provide our own.
\*-------------------------------------------------------------------------*/
-#ifdef INET_ATON
+#ifdef LUASOCKET_INET_ATON
int inet_aton(const char *cp, struct in_addr *inp)
{
unsigned int a = 0, b = 0, c = 0, d = 0;
@@ -560,4 +518,26 @@ int inet_aton(const char *cp, struct in_addr *inp)
}
#endif
+#ifdef LUASOCKET_INET_PTON
+int inet_pton(int af, const char *src, void *dst)
+{
+ struct addrinfo hints, *res;
+ int ret = 1;
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = af;
+ hints.ai_flags = AI_NUMERICHOST;
+ if (getaddrinfo(src, NULL, &hints, &res) != 0) return -1;
+ if (af == AF_INET) {
+ struct sockaddr_in *in = (struct sockaddr_in *) res->ai_addr;
+ memcpy(dst, &in->sin_addr, sizeof(in->sin_addr));
+ } else if (af == AF_INET6) {
+ struct sockaddr_in6 *in = (struct sockaddr_in6 *) res->ai_addr;
+ memcpy(dst, &in->sin6_addr, sizeof(in->sin6_addr));
+ } else {
+ ret = -1;
+ }
+ freeaddrinfo(res);
+ return ret;
+}
+#endif