summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorent Le Coz <louiz@louiz.org>2014-05-27 01:05:51 +0200
committerFlorent Le Coz <louiz@louiz.org>2014-05-27 01:06:45 +0200
commit23e8e32f84c8d7f8bb947a1ab484a81890b40371 (patch)
treed9ecdba5afc9ea0b2986ea5b6ac8b62488250954
parent5507adbe9473f4b41e52d16498f14850773e5e45 (diff)
downloadbiboumi-23e8e32f84c8d7f8bb947a1ab484a81890b40371.tar.gz
biboumi-23e8e32f84c8d7f8bb947a1ab484a81890b40371.tar.bz2
biboumi-23e8e32f84c8d7f8bb947a1ab484a81890b40371.tar.xz
biboumi-23e8e32f84c8d7f8bb947a1ab484a81890b40371.zip
Support IPv6 connections
fix #2522
-rw-r--r--src/network/socket_handler.cpp20
-rw-r--r--src/network/socket_handler.hpp5
2 files changed, 18 insertions, 7 deletions
diff --git a/src/network/socket_handler.cpp b/src/network/socket_handler.cpp
index a9e0c5e..3d79290 100644
--- a/src/network/socket_handler.cpp
+++ b/src/network/socket_handler.cpp
@@ -28,12 +28,11 @@ SocketHandler::SocketHandler(std::shared_ptr<Poller> poller):
connected(false),
connecting(false)
{
- this->init_socket();
}
-void SocketHandler::init_socket()
+void SocketHandler::init_socket(const struct addrinfo* rp)
{
- if ((this->socket = ::socket(AF_INET, SOCK_STREAM, 0)) == -1)
+ if ((this->socket = ::socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol)) == -1)
throw std::runtime_error("Could not create socket");
int optval = 1;
if (::setsockopt(this->socket, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval)) == -1)
@@ -64,7 +63,7 @@ void SocketHandler::connect(const std::string& address, const std::string& port)
struct addrinfo hints;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_flags = 0;
- hints.ai_family = AF_INET;
+ hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = 0;
@@ -99,10 +98,19 @@ void SocketHandler::connect(const std::string& address, const std::string& port)
addr_res->ai_addr = &this->ai_addr;
addr_res->ai_addrlen = this->ai_addrlen;
}
- this->connecting = true;
for (struct addrinfo* rp = addr_res; rp; rp = rp->ai_next)
{
+ if (!this->connecting)
+ {
+ try {
+ this->init_socket(rp);
+ }
+ catch (const std::runtime_error& error) {
+ log_error("Failed to init socket: " << error.what());
+ break;
+ }
+ }
if (::connect(this->socket, rp->ai_addr, rp->ai_addrlen) == 0
|| errno == EISCONN)
{
@@ -116,6 +124,8 @@ void SocketHandler::connect(const std::string& address, const std::string& port)
else if (errno == EINPROGRESS || errno == EALREADY)
{ // retry this process later, when the socket
// is ready to be written on.
+ this->connecting = true;
+ this->poller->add_socket_handler(this);
this->poller->watch_send_events(this);
// Save the addrinfo structure, to use it on the next call
this->ai_addrlen = rp->ai_addrlen;
diff --git a/src/network/socket_handler.hpp b/src/network/socket_handler.hpp
index 1e31dcd..e6a36bf 100644
--- a/src/network/socket_handler.hpp
+++ b/src/network/socket_handler.hpp
@@ -26,9 +26,10 @@ public:
explicit SocketHandler(std::shared_ptr<Poller> poller);
virtual ~SocketHandler() {}
/**
- * (re-)Initialize the socket
+ * Initialize the socket with the parameters contained in the given
+ * addrinfo structure.
*/
- void init_socket();
+ void init_socket(const struct addrinfo* rp);
/**
* Connect to the remote server, and call on_connected() if this succeeds
*/