aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDiego Nehab <diego@impa.br>2013-05-26 15:18:13 +0800
committerDiego Nehab <diego@impa.br>2013-05-26 15:18:13 +0800
commit6d93fd7c8f04fecbcdc28994da8b8357f712463f (patch)
treee7e3d8ef480f1d78ae704ae9373159989dbba1c2 /src
parent22107bb9fcb3eef565b93fb00d8f2cc8849ba08e (diff)
downloadluasocket-6d93fd7c8f04fecbcdc28994da8b8357f712463f.tar.gz
luasocket-6d93fd7c8f04fecbcdc28994da8b8357f712463f.tar.bz2
luasocket-6d93fd7c8f04fecbcdc28994da8b8357f712463f.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/tcp.c20
1 files changed, 18 insertions, 2 deletions
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) {
388 return tcp_create(L, AF_INET6); 388 return tcp_create(L, AF_INET6);
389} 389}
390 390
391const char *strfamily(int family) {
392 switch (family) {
393 case PF_UNSPEC: return "unspec";
394 case PF_INET: return "inet";
395 case PF_INET6: return "inet6";
396 default: return "invalid";
397 }
398}
399
391static const char *tryconnect6(const char *remoteaddr, const char *remoteserv, 400static const char *tryconnect6(const char *remoteaddr, const char *remoteserv,
392 struct addrinfo *connecthints, p_tcp tcp) { 401 struct addrinfo *connecthints, p_tcp tcp) {
393 struct addrinfo *iterator = NULL, *resolved = NULL; 402 struct addrinfo *iterator = NULL, *resolved = NULL;
394 const char *err = NULL; 403 const char *err = NULL;
404 int i = 0;
395 /* try resolving */ 405 /* try resolving */
396 err = socket_gaistrerror(getaddrinfo(remoteaddr, remoteserv, 406 err = socket_gaistrerror(getaddrinfo(remoteaddr, remoteserv,
397 connecthints, &resolved)); 407 connecthints, &resolved));
@@ -402,8 +412,13 @@ static const char *tryconnect6(const char *remoteaddr, const char *remoteserv,
402 /* iterate over all returned addresses trying to connect */ 412 /* iterate over all returned addresses trying to connect */
403 for (iterator = resolved; iterator; iterator = iterator->ai_next) { 413 for (iterator = resolved; iterator; iterator = iterator->ai_next) {
404 p_timeout tm = timeout_markstart(&tcp->tm); 414 p_timeout tm = timeout_markstart(&tcp->tm);
405 /* create new socket if one wasn't created by the bind stage */ 415 /* create new socket if necessary. if there was no
406 if (tcp->sock == SOCKET_INVALID) { 416 * bind, we need to create one for every new family
417 * that shows up while iterating. if there was a
418 * bind, all families will be the same and we will
419 * not enter this branch. */
420 if (tcp->family != iterator->ai_family) {
421 socket_destroy(&tcp->sock);
407 err = socket_strerror(socket_create(&tcp->sock, 422 err = socket_strerror(socket_create(&tcp->sock,
408 iterator->ai_family, iterator->ai_socktype, 423 iterator->ai_family, iterator->ai_socktype,
409 iterator->ai_protocol)); 424 iterator->ai_protocol));
@@ -444,6 +459,7 @@ static int global_connect(lua_State *L) {
444 timeout_init(&tcp->tm, -1, -1); 459 timeout_init(&tcp->tm, -1, -1);
445 buffer_init(&tcp->buf, &tcp->io, &tcp->tm); 460 buffer_init(&tcp->buf, &tcp->io, &tcp->tm);
446 tcp->sock = SOCKET_INVALID; 461 tcp->sock = SOCKET_INVALID;
462 tcp->family = PF_UNSPEC;
447 /* allow user to pick local address and port */ 463 /* allow user to pick local address and port */
448 memset(&bindhints, 0, sizeof(bindhints)); 464 memset(&bindhints, 0, sizeof(bindhints));
449 bindhints.ai_socktype = SOCK_STREAM; 465 bindhints.ai_socktype = SOCK_STREAM;