summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Antonuk <alan.antonuk@gmail.com>2012-06-18 16:31:22 -0700
committerAlan Antonuk <alan.antonuk@gmail.com>2012-06-18 16:31:22 -0700
commit83c5c6a20b912460980e8f2da1b86e8e49df0694 (patch)
tree55bbb695a0075a3fdb1d0be6a0b9b4f4d3e14417
parent5e2f6de43bb1f9e501e88bccb98ba84876f2129c (diff)
parent1a70fb073880b2c262c001a7d8a297b55593caaf (diff)
downloadrabbitmq-c-github-ask-83c5c6a20b912460980e8f2da1b86e8e49df0694.tar.gz
Merge pull request #26 from alanxz/ipv6_support
IPv6 Support
-rw-r--r--librabbitmq/amqp_socket.c81
-rw-r--r--librabbitmq/win32/socket.h1
2 files changed, 55 insertions, 27 deletions
diff --git a/librabbitmq/amqp_socket.c b/librabbitmq/amqp_socket.c
index 2034f17..604e32d 100644
--- a/librabbitmq/amqp_socket.c
+++ b/librabbitmq/amqp_socket.c
@@ -45,44 +45,71 @@
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;
+ /*
+ 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();
+ 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 <winsock2.h>
+#include <WS2tcpip.h>
/* same as WSABUF */
struct iovec {