diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index 037b36625a55c64b75be9a9d1a067ecc5a036d0a..5ba45e747e753f9b9b7e7fbdfb8d2a6d3d0919b9 100644 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -241,10 +241,13 @@ TcpSocketEndpoint::~TcpSocketEndpoint() } void -TcpSocketEndpoint::connect() +TcpSocketEndpoint::connect(const std::chrono::steady_clock::duration& timeout) { - // Blocking method - if (::connect(sock_, addr_, addr_.getLength()) < 0) + int ms = std::chrono::duration_cast<std::chrono::milliseconds>(timeout).count(); + setsockopt(sock_, SOL_SOCKET, SO_RCVTIMEO, (const char *)&ms, sizeof(ms)); + setsockopt(sock_, SOL_SOCKET, SO_SNDTIMEO, (const char *)&ms, sizeof(ms)); + + if ((::connect(sock_, addr_, addr_.getLength())) < 0) throw std::system_error(errno, std::generic_category()); } diff --git a/src/peer_connection.h b/src/peer_connection.h index a650688f10dbb327420dad4e1606a4a0b0d598af..030155beefe741474bb0410108a23297ec1fd5a3 100644 --- a/src/peer_connection.h +++ b/src/peer_connection.h @@ -126,7 +126,7 @@ public: throw std::logic_error("TcpSocketEndpoint::setOnRecv not implemented"); } - void connect(); + void connect(const std::chrono::steady_clock::duration& timeout = {}); private: const IpAddr addr_; diff --git a/src/ringdht/p2p.cpp b/src/ringdht/p2p.cpp index b838cd33c91056cb570e6387587a0744ef1fce4f..e45c8a9d9768217e8dd3a1c892f5395c177d02b1 100644 --- a/src/ringdht/p2p.cpp +++ b/src/ringdht/p2p.cpp @@ -348,7 +348,18 @@ private: RING_DBG() << parent_.account << "[CNX] connecting to TURN relay " << relay_addr.toString(true, true); peer_ep = std::make_unique<TcpSocketEndpoint>(relay_addr); - peer_ep->connect(); // IMPROVE_ME: socket timeout? + try { + peer_ep->connect(SOCK_TIMEOUT); + } catch (const std::logic_error& e) { + // In case of a timeout + RING_WARN() << "TcpSocketEndpoint timeout for addr " << relay_addr.toString(true, true) << ": " << e.what(); + cancel(); + return; + } catch (...) { + RING_WARN() << "TcpSocketEndpoint failure for addr " << relay_addr.toString(true, true); + cancel(); + return; + } break; } catch (std::system_error&) { RING_DBG() << parent_.account << "[CNX] Failed to connect to TURN relay "