summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Antonuk <aega@med.umich.edu>2012-06-18 13:15:41 -0400
committerAlan Antonuk <aega@med.umich.edu>2012-06-18 16:23:34 -0400
commitcbef84d30fffaa86611ea5034835e962e28bb296 (patch)
tree48751508cde60ea7cc38f3b1e0fdaaae92c410ee
parent5e2f6de43bb1f9e501e88bccb98ba84876f2129c (diff)
downloadrabbitmq-c-github-ask-cbef84d30fffaa86611ea5034835e962e28bb296.tar.gz
Adding support for IPv6
-rw-r--r--librabbitmq/amqp_socket.c77
-rw-r--r--librabbitmq/win32/socket.h1
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 <winsock2.h>
+#include <WS2tcpip.h>
/* same as WSABUF */
struct iovec {