diff options
author | Florent Le Coz <louiz@louiz.org> | 2014-05-27 01:05:51 +0200 |
---|---|---|
committer | Florent Le Coz <louiz@louiz.org> | 2014-05-27 01:06:45 +0200 |
commit | 23e8e32f84c8d7f8bb947a1ab484a81890b40371 (patch) | |
tree | d9ecdba5afc9ea0b2986ea5b6ac8b62488250954 /src/network | |
parent | 5507adbe9473f4b41e52d16498f14850773e5e45 (diff) | |
download | biboumi-23e8e32f84c8d7f8bb947a1ab484a81890b40371.tar.gz biboumi-23e8e32f84c8d7f8bb947a1ab484a81890b40371.tar.bz2 biboumi-23e8e32f84c8d7f8bb947a1ab484a81890b40371.tar.xz biboumi-23e8e32f84c8d7f8bb947a1ab484a81890b40371.zip |
Support IPv6 connections
fix #2522
Diffstat (limited to 'src/network')
-rw-r--r-- | src/network/socket_handler.cpp | 20 | ||||
-rw-r--r-- | src/network/socket_handler.hpp | 5 |
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 */ |