From 6d93fd7c8f04fecbcdc28994da8b8357f712463f Mon Sep 17 00:00:00 2001 From: Diego Nehab Date: Sun, 26 May 2013 15:18:13 +0800 Subject: [PATCH] Fix socket.connect Previous implementation was not making sure the socket had the same family as the addr returned by getaddrinfo. So instead of "connection refused", we could get "invalid argument", which was our fault. --- macosx.cmd | 2 +- src/tcp.c | 20 ++++++++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/macosx.cmd b/macosx.cmd index f85141a..46a0709 100644 --- a/macosx.cmd +++ b/macosx.cmd @@ -1 +1 @@ -make DEBUG=DEBUG PLAT=macosx LUAINC_macosx_base=/Users/diego/build/macosx LUAPREFIX_macosx=/Users/diego/build/macosx install-both +make DEBUG=DEBUG PLAT=macosx LUAINC_macosx_base=/Users/diego/build/macosx/include LUAPREFIX_macosx=/Users/diego/build/macosx install-both diff --git a/src/tcp.c b/src/tcp.c index 6734dc0..4b0451f 100644 --- a/src/tcp.c +++ b/src/tcp.c @@ -388,10 +388,20 @@ static int global_create6(lua_State *L) { return tcp_create(L, AF_INET6); } +const char *strfamily(int family) { + switch (family) { + case PF_UNSPEC: return "unspec"; + case PF_INET: return "inet"; + case PF_INET6: return "inet6"; + default: return "invalid"; + } +} + 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; + int i = 0; /* try resolving */ err = socket_gaistrerror(getaddrinfo(remoteaddr, remoteserv, connecthints, &resolved)); @@ -402,8 +412,13 @@ static const char *tryconnect6(const char *remoteaddr, const char *remoteserv, /* 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) { + /* 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 (tcp->family != iterator->ai_family) { + socket_destroy(&tcp->sock); err = socket_strerror(socket_create(&tcp->sock, iterator->ai_family, iterator->ai_socktype, iterator->ai_protocol)); @@ -444,6 +459,7 @@ 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 = PF_UNSPEC; /* allow user to pick local address and port */ memset(&bindhints, 0, sizeof(bindhints)); bindhints.ai_socktype = SOCK_STREAM;