From cbef84d30fffaa86611ea5034835e962e28bb296 Mon Sep 17 00:00:00 2001 From: Alan Antonuk Date: Mon, 18 Jun 2012 13:15:41 -0400 Subject: Adding support for IPv6 --- librabbitmq/amqp_socket.c | 77 ++++++++++++++++++++++++++++++---------------- librabbitmq/win32/socket.h | 1 + 2 files changed, 51 insertions(+), 27 deletions(-) diff --git a/librabbitmq/amqp_socket.c b/librabbitmq/amqp_socket.c index 2034f17..e31e242 100644 --- a/librabbitmq/amqp_socket.c +++ b/librabbitmq/amqp_socket.c @@ -45,44 +45,67 @@ int amqp_open_socket(char const *hostname, int portnumber) { - int sockfd, res; - struct sockaddr_in addr; - struct hostent *he; - int one = 1; /* used as a buffer by setsockopt below */ + struct addrinfo hint; + struct addrinfo *address_list; + struct addrinfo *addr; + char portnumber_string[33]; + int sockfd = -1; + int last_error = 0; + int one = 1; /* for setsockopt */ - res = amqp_socket_init(); - if (res) - return res; + if (0 != (last_error = amqp_socket_init())) + return last_error; - he = gethostbyname(hostname); - if (he == NULL) - return -ERROR_GETHOSTBYNAME_FAILED; + memset(&hint, 0, sizeof(hint)); + hint.ai_family = PF_UNSPEC; /* PF_INET or PF_INET6 */ + hint.ai_socktype = SOCK_STREAM; + hint.ai_protocol = IPPROTO_TCP; - addr.sin_family = AF_INET; - addr.sin_port = htons(portnumber); - addr.sin_addr.s_addr = * (uint32_t *) he->h_addr_list[0]; + (void)sprintf(portnumber_string, "%d", portnumber); - sockfd = socket(PF_INET, SOCK_STREAM, 0); - if (sockfd == -1) - return -amqp_socket_error(); + last_error = getaddrinfo(hostname, portnumber_string, &hint, &address_list); -#ifdef DISABLE_SIGPIPE_WITH_SETSOCKOPT - if (0 != amqp_socket_setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &one, - sizeof(one))) + if (last_error != 0) { - return -amqp_socket_error(); + return -ERROR_GETHOSTBYNAME_FAILED; } -#endif - if (amqp_socket_setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &one, - sizeof(one)) < 0 - || connect(sockfd, (struct sockaddr *) &addr, sizeof(addr)) < 0) + for (addr = address_list; addr; addr = addr->ai_next) { - res = -amqp_socket_error(); - amqp_socket_close(sockfd); - return res; + sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); + if (-1 == sockfd) + { + last_error = -amqp_socket_error(); + continue; + } +#if DISABLE_SIGPIPE_WITH_SETSOCKOPT + if (0 != amqp_socket_setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &one, sizeof(one))) + { + last_error = -amqp_socket_error(); + amqp_socket_close(sockfd); + continue; + } +#endif /* DISABLE_SIGPIPE_WITH_SETSOCKOPT */ + if (0 != amqp_socket_setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one)) + || 0 != connect(sockfd, addr->ai_addr, addr->ai_addrlen)) + { + last_error = -amqp_socket_error(); + amqp_socket_close(sockfd); + continue; + } + else + { + last_error = 0; + break; + } } + freeaddrinfo(address_list); + if (last_error != 0) + { + return last_error; + } + return sockfd; } diff --git a/librabbitmq/win32/socket.h b/librabbitmq/win32/socket.h index 3b9c452..bfd717c 100644 --- a/librabbitmq/win32/socket.h +++ b/librabbitmq/win32/socket.h @@ -34,6 +34,7 @@ */ #include +#include /* same as WSABUF */ struct iovec { -- cgit v1.2.1 From 1a70fb073880b2c262c001a7d8a297b55593caaf Mon Sep 17 00:00:00 2001 From: Alan Antonuk Date: Mon, 18 Jun 2012 16:21:37 -0400 Subject: Squash warning: casting SOCKET to int on Win32 --- librabbitmq/amqp_socket.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/librabbitmq/amqp_socket.c b/librabbitmq/amqp_socket.c index e31e242..604e32d 100644 --- a/librabbitmq/amqp_socket.c +++ b/librabbitmq/amqp_socket.c @@ -72,7 +72,11 @@ int amqp_open_socket(char const *hostname, for (addr = address_list; addr; addr = addr->ai_next) { - sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); + /* + This cast is to squash warnings on Win64, see: + http://stackoverflow.com/questions/1953639/is-it-safe-to-cast-socket-to-int-under-win64 + */ + sockfd = (int)socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); if (-1 == sockfd) { last_error = -amqp_socket_error(); -- cgit v1.2.1