Commit 23e8e32f authored by louiz’'s avatar louiz’

Support IPv6 connections

fix #2522
parent 5507adbe
......@@ -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;
......
......@@ -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
*/
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment