diff options
Diffstat (limited to 'src/i2p.cpp')
-rw-r--r-- | src/i2p.cpp | 46 |
1 files changed, 25 insertions, 21 deletions
diff --git a/src/i2p.cpp b/src/i2p.cpp index 42270deaeb..2ae164633b 100644 --- a/src/i2p.cpp +++ b/src/i2p.cpp @@ -20,6 +20,7 @@ #include <util/system.h> #include <chrono> +#include <memory> #include <stdexcept> #include <string> @@ -115,7 +116,8 @@ namespace sam { Session::Session(const fs::path& private_key_file, const CService& control_host, CThreadInterrupt* interrupt) - : m_private_key_file(private_key_file), m_control_host(control_host), m_interrupt(interrupt) + : m_private_key_file(private_key_file), m_control_host(control_host), m_interrupt(interrupt), + m_control_sock(std::make_unique<Sock>(INVALID_SOCKET)) { } @@ -145,7 +147,9 @@ bool Session::Accept(Connection& conn) try { while (!*m_interrupt) { Sock::Event occurred; - conn.sock.Wait(MAX_WAIT_FOR_IO, Sock::RECV, &occurred); + if (!conn.sock->Wait(MAX_WAIT_FOR_IO, Sock::RECV, &occurred)) { + throw std::runtime_error("wait on socket failed"); + } if ((occurred & Sock::RECV) == 0) { // Timeout, no incoming connections within MAX_WAIT_FOR_IO. @@ -153,7 +157,7 @@ bool Session::Accept(Connection& conn) } const std::string& peer_dest = - conn.sock.RecvUntilTerminator('\n', MAX_WAIT_FOR_IO, *m_interrupt); + conn.sock->RecvUntilTerminator('\n', MAX_WAIT_FOR_IO, *m_interrupt, MAX_MSG_SIZE); conn.peer = CService(DestB64ToAddr(peer_dest), Params().GetDefaultPort()); @@ -171,7 +175,7 @@ bool Session::Connect(const CService& to, Connection& conn, bool& proxy_error) proxy_error = true; std::string session_id; - Sock sock; + std::unique_ptr<Sock> sock; conn.peer = to; try { @@ -184,12 +188,12 @@ bool Session::Connect(const CService& to, Connection& conn, bool& proxy_error) } const Reply& lookup_reply = - SendRequestAndGetReply(sock, strprintf("NAMING LOOKUP NAME=%s", to.ToStringIP())); + SendRequestAndGetReply(*sock, strprintf("NAMING LOOKUP NAME=%s", to.ToStringIP())); const std::string& dest = lookup_reply.Get("VALUE"); const Reply& connect_reply = SendRequestAndGetReply( - sock, strprintf("STREAM CONNECT ID=%s DESTINATION=%s SILENT=false", session_id, dest), + *sock, strprintf("STREAM CONNECT ID=%s DESTINATION=%s SILENT=false", session_id, dest), false); const std::string& result = connect_reply.Get("RESULT"); @@ -252,7 +256,7 @@ Session::Reply Session::SendRequestAndGetReply(const Sock& sock, // signaled. static constexpr auto recv_timeout = 3min; - reply.full = sock.RecvUntilTerminator('\n', recv_timeout, *m_interrupt); + reply.full = sock.RecvUntilTerminator('\n', recv_timeout, *m_interrupt, MAX_MSG_SIZE); for (const auto& kv : spanparsing::Split(reply.full, ' ')) { const auto& pos = std::find(kv.begin(), kv.end(), '='); @@ -271,7 +275,7 @@ Session::Reply Session::SendRequestAndGetReply(const Sock& sock, return reply; } -Sock Session::Hello() const +std::unique_ptr<Sock> Session::Hello() const { auto sock = CreateSock(m_control_host); @@ -279,13 +283,13 @@ Sock Session::Hello() const throw std::runtime_error("Cannot create socket"); } - if (!ConnectSocketDirectly(m_control_host, sock->Get(), nConnectTimeout, true)) { + if (!ConnectSocketDirectly(m_control_host, *sock, nConnectTimeout, true)) { throw std::runtime_error(strprintf("Cannot connect to %s", m_control_host.ToString())); } SendRequestAndGetReply(*sock, "HELLO VERSION MIN=3.1 MAX=3.1"); - return std::move(*sock); + return sock; } void Session::CheckControlSock() @@ -293,7 +297,7 @@ void Session::CheckControlSock() LOCK(m_mutex); std::string errmsg; - if (!m_control_sock.IsConnected(errmsg)) { + if (!m_control_sock->IsConnected(errmsg)) { Log("Control socket error: %s", errmsg); Disconnect(); } @@ -341,26 +345,26 @@ Binary Session::MyDestination() const void Session::CreateIfNotCreatedAlready() { std::string errmsg; - if (m_control_sock.IsConnected(errmsg)) { + if (m_control_sock->IsConnected(errmsg)) { return; } Log("Creating SAM session with %s", m_control_host.ToString()); - Sock sock = Hello(); + auto sock = Hello(); const auto& [read_ok, data] = ReadBinaryFile(m_private_key_file); if (read_ok) { m_private_key.assign(data.begin(), data.end()); } else { - GenerateAndSavePrivateKey(sock); + GenerateAndSavePrivateKey(*sock); } const std::string& session_id = GetRandHash().GetHex().substr(0, 10); // full is an overkill, too verbose in the logs const std::string& private_key_b64 = SwapBase64(EncodeBase64(m_private_key)); - SendRequestAndGetReply(sock, strprintf("SESSION CREATE STYLE=STREAM ID=%s DESTINATION=%s", - session_id, private_key_b64)); + SendRequestAndGetReply(*sock, strprintf("SESSION CREATE STYLE=STREAM ID=%s DESTINATION=%s", + session_id, private_key_b64)); m_my_addr = CService(DestBinToAddr(MyDestination()), Params().GetDefaultPort()); m_session_id = session_id; @@ -370,12 +374,12 @@ void Session::CreateIfNotCreatedAlready() m_my_addr.ToString()); } -Sock Session::StreamAccept() +std::unique_ptr<Sock> Session::StreamAccept() { - Sock sock = Hello(); + auto sock = Hello(); const Reply& reply = SendRequestAndGetReply( - sock, strprintf("STREAM ACCEPT ID=%s SILENT=false", m_session_id), false); + *sock, strprintf("STREAM ACCEPT ID=%s SILENT=false", m_session_id), false); const std::string& result = reply.Get("RESULT"); @@ -393,14 +397,14 @@ Sock Session::StreamAccept() void Session::Disconnect() { - if (m_control_sock.Get() != INVALID_SOCKET) { + if (m_control_sock->Get() != INVALID_SOCKET) { if (m_session_id.empty()) { Log("Destroying incomplete session"); } else { Log("Destroying session %s", m_session_id); } } - m_control_sock.Reset(); + m_control_sock->Reset(); m_session_id.clear(); } } // namespace sam |