Esempio n. 1
0
/* _gethostaddr
 * 
 * gets the address of a host passed by name, and fills out a sockaddr
 * structure
 * 
 * Arguments:
 * 	L	lua State
 * 	addr	ip address or hostname
 * 	type	SOCK_STREAM or SOCK_DGRAM
 * 	port	port number for sockaddr
 * 	family	(out) address family (AF_INET or AF_INET6) of address
 * 	protocol	(out) protocol of address
 * 	sa	(out) pointer to struct sockaddr to fill with data.
 * 	slen	(inout)	length of sa, and on return length of data
 * 
 * Returns:
 * 	0 when the lookup succeeded, -1 otherwise
 * 	On success, the arguments family, protocol, sa and slen will have
 * 	been updated with values from the looked up address
 */
static int _gethostaddr(lua_State *L, const char *addr, int type, int port, int *family, int *protocol, struct sockaddr *sa, socklen_t *slen)
{
	struct addrinfo hint, *info =0;
	memset(&hint, 0, sizeof(hint));
	hint.ai_family = AF_UNSPEC;
	hint.ai_socktype = type;
	if (_needsnolookup(addr))
		hint.ai_flags = AI_NUMERICHOST;

	int err = getaddrinfo(addr, 0, &hint, &info);
    if (err != 0) {
		if (info) freeaddrinfo(info);
		return lsocket_error(L, gai_strerror(err));
	} else if (info->ai_family != AF_INET && info->ai_family != AF_INET6) {
		if (info) freeaddrinfo(info);
		return lsocket_error(L, "unknown address family");
	}

	*family = info->ai_family;
    *slen = info->ai_addrlen;
    *protocol = info->ai_protocol;
    memcpy(sa, info->ai_addr, *slen);
    if (*family == AF_INET)
		((struct sockaddr_in*) sa)->sin_port = htons(port);
	else
		((struct sockaddr_in6*) sa)->sin6_port = htons(port);

    freeaddrinfo(info);
    return 0;
}
Esempio n. 2
0
/* ares_aresolver
 * 
 * starts an asynchronous getaddrinfo request
 * 
 * Arguments:
 * 	L	Lua State
 * 
 * Lua Stack:
 * 	1	the name to resolve
 * 
 * Lua Returns:
 * 	+1	true, if the cancel request was sent, nil + error message if an
 *		error occurred.
 */
static int ares_aresolver(lua_State *L)
{
	const char *name = luaL_checkstring(L, 1);
	aResolver *ares = ares_pushaResolver(L);
	struct addrinfo hint;

	memset(&hint, 0, sizeof(hint));
	hint.ai_family = AF_UNSPEC;
	/* reduce the number of duplicate hits, this makes no difference for
	 * the actual dns resolving.
	 */
	hint.ai_protocol = IPPROTO_TCP;
	hint.ai_socktype = SOCK_STREAM;
	if (_needsnolookup(name))
		hint.ai_flags = AI_NUMERICHOST;

	ares->rq = gai_start(name, 0, &hint);
    if (ares->rq == NULL)
		return ares_error(L, strerror(errno));
	return 1;
}
Esempio n. 3
0
/* lsocket_resolve
 * 
 * resolves a name to an address
 * 
 * Arguments:
 * 	L	lua State
 * 
 * Lua Stack:
 * 	1	name of host to resolve
 * 
 * Lua Returns:
 * 	+1	a table of all addresses the argument resolves to. For each address,
 * 		a subtable with the fields family and addr is created.
 */
static int lsocket_resolve(lua_State *L)
{
	const char *name = luaL_checkstring(L, 1);
	char buf[TOSTRING_BUFSIZ];
	struct addrinfo hint, *info =0;
	memset(&hint, 0, sizeof(hint));
	hint.ai_family = AF_UNSPEC;
	if (_needsnolookup(name))
		hint.ai_flags = AI_NUMERICHOST;

	int err = getaddrinfo(name, 0, &hint, &info);
    if (err != 0) {
		if (info) freeaddrinfo(info);
		return lsocket_error(L, gai_strerror(err));
	}

	int i = 1;
	lua_newtable(L);
	while (info) {
		if (info->ai_family == AF_INET || info->ai_family == AF_INET6) {
			lua_newtable(L);
			lua_pushliteral(L, "family");
			lua_pushstring(L, info->ai_family == AF_INET ? LSOCKET_INET : LSOCKET_INET6);
			lua_rawset(L, -3);
			lua_pushliteral(L, "addr");
			lua_pushstring(L, _addr2string(info->ai_addr, buf, TOSTRING_BUFSIZ));
			lua_rawset(L, -3);
			lua_rawseti(L, -2, i++);
			info = info->ai_next;
		}
		/* silently ignore unknown address families */
	}
	
	freeaddrinfo(info);
	return 1;
}