Add support for connecting to IPv6 hosts
This commit is contained in:
parent
5874d47f55
commit
594f826aa1
5 changed files with 86 additions and 59 deletions
52
src/tcp.c
52
src/tcp.c
|
@ -1,10 +1,10 @@
|
|||
/*=========================================================================*\
|
||||
* TCP object
|
||||
* TCP object
|
||||
* LuaSocket toolkit
|
||||
*
|
||||
* RCS ID: $Id: tcp.c,v 1.42 2009/05/27 09:31:35 diego Exp $
|
||||
\*=========================================================================*/
|
||||
#include <string.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
|
@ -97,7 +97,7 @@ int tcp_open(lua_State *L)
|
|||
auxiliar_add2group(L, "tcp{client}", "tcp{any}");
|
||||
auxiliar_add2group(L, "tcp{server}", "tcp{any}");
|
||||
/* define library functions */
|
||||
luaL_openlib(L, NULL, func, 0);
|
||||
luaL_openlib(L, NULL, func, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -150,7 +150,7 @@ static int meth_getfd(lua_State *L)
|
|||
static int meth_setfd(lua_State *L)
|
||||
{
|
||||
p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
|
||||
tcp->sock = (t_socket) luaL_checknumber(L, 2);
|
||||
tcp->sock = (t_socket) luaL_checknumber(L, 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -162,8 +162,8 @@ static int meth_dirty(lua_State *L)
|
|||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Waits for and returns a client object attempting connection to the
|
||||
* server object
|
||||
* Waits for and returns a client object attempting connection to the
|
||||
* server object
|
||||
\*-------------------------------------------------------------------------*/
|
||||
static int meth_accept(lua_State *L)
|
||||
{
|
||||
|
@ -178,20 +178,20 @@ static int meth_accept(lua_State *L)
|
|||
/* initialize structure fields */
|
||||
socket_setnonblocking(&sock);
|
||||
clnt->sock = sock;
|
||||
io_init(&clnt->io, (p_send) socket_send, (p_recv) socket_recv,
|
||||
io_init(&clnt->io, (p_send) socket_send, (p_recv) socket_recv,
|
||||
(p_error) socket_ioerror, &clnt->sock);
|
||||
timeout_init(&clnt->tm, -1, -1);
|
||||
buffer_init(&clnt->buf, &clnt->io, &clnt->tm);
|
||||
return 1;
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, socket_strerror(err));
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Binds an object to an address
|
||||
* Binds an object to an address
|
||||
\*-------------------------------------------------------------------------*/
|
||||
static int meth_bind(lua_State *L)
|
||||
{
|
||||
|
@ -219,12 +219,18 @@ static int meth_bind(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);
|
||||
unsigned short port = (unsigned short) luaL_checknumber(L, 3);
|
||||
p_timeout tm = timeout_markstart(&tcp->tm);
|
||||
const char *err = inet_tryconnect(&tcp->sock, address, port, tm);
|
||||
const char *port = luaL_checkstring(L, 3);
|
||||
struct addrinfo connecthints;
|
||||
const char *err;
|
||||
memset(&connecthints, 0, sizeof(connecthints));
|
||||
connecthints.ai_socktype = SOCK_STREAM;
|
||||
/* make sure we try to connect only to the same family */
|
||||
connecthints.ai_family = tcp->domain;
|
||||
timeout_markstart(&tcp->tm);
|
||||
err = inet_tryconnect(&tcp->sock, 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);
|
||||
if (err) {
|
||||
|
@ -237,7 +243,7 @@ static int meth_connect(lua_State *L)
|
|||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Closes socket used by object
|
||||
* Closes socket used by object
|
||||
\*-------------------------------------------------------------------------*/
|
||||
static int meth_close(lua_State *L)
|
||||
{
|
||||
|
@ -322,7 +328,7 @@ static int meth_settimeout(lua_State *L)
|
|||
* Library functions
|
||||
\*=========================================================================*/
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Creates a master tcp object
|
||||
* Creates a master tcp object
|
||||
\*-------------------------------------------------------------------------*/
|
||||
static int tcp_create(lua_State *L, int domain) {
|
||||
t_socket sock;
|
||||
|
@ -341,7 +347,7 @@ static int tcp_create(lua_State *L, int domain) {
|
|||
(void *)&yes, sizeof(yes));
|
||||
}
|
||||
tcp->sock = sock;
|
||||
io_init(&tcp->io, (p_send) socket_send, (p_recv) socket_recv,
|
||||
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);
|
||||
|
@ -367,19 +373,19 @@ static const char *tryconnect6(const char *remoteaddr, const char *remoteserv,
|
|||
struct addrinfo *iterator = NULL, *resolved = NULL;
|
||||
const char *err = NULL;
|
||||
/* try resolving */
|
||||
err = socket_gaistrerror(getaddrinfo(remoteaddr, remoteserv,
|
||||
err = socket_gaistrerror(getaddrinfo(remoteaddr, remoteserv,
|
||||
connecthints, &resolved));
|
||||
if (err != NULL) {
|
||||
if (resolved) freeaddrinfo(resolved);
|
||||
return err;
|
||||
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,
|
||||
err = socket_strerror(socket_create(&tcp->sock,
|
||||
iterator->ai_family, iterator->ai_socktype,
|
||||
iterator->ai_protocol));
|
||||
if (err != NULL) {
|
||||
freeaddrinfo(resolved);
|
||||
|
@ -389,7 +395,7 @@ static const char *tryconnect6(const char *remoteaddr, const char *remoteserv,
|
|||
socket_setnonblocking(&tcp->sock);
|
||||
}
|
||||
/* finally try connecting to remote address */
|
||||
err = socket_strerror(socket_connect(&tcp->sock,
|
||||
err = socket_strerror(socket_connect(&tcp->sock,
|
||||
(SA *) iterator->ai_addr,
|
||||
iterator->ai_addrlen, tm));
|
||||
/* if success, break out of loop */
|
||||
|
@ -410,7 +416,7 @@ static int global_connect6(lua_State *L) {
|
|||
struct addrinfo bindhints, connecthints;
|
||||
const char *err = NULL;
|
||||
/* initialize tcp structure */
|
||||
io_init(&tcp->io, (p_send) socket_send, (p_recv) socket_recv,
|
||||
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);
|
||||
|
@ -432,7 +438,7 @@ static int global_connect6(lua_State *L) {
|
|||
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;
|
||||
connecthints.ai_family = bindhints.ai_family;
|
||||
err = tryconnect6(remoteaddr, remoteserv, &connecthints, tcp);
|
||||
if (err) {
|
||||
socket_destroy(&tcp->sock);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue