From 2e1e95d48368a210b97ee6c8c68c5e8eba15fd82 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 10 Jun 2016 15:12:50 -0400 Subject: [PATCH 1/9] pass URL params --- HTTPProxy.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/HTTPProxy.cpp b/HTTPProxy.cpp index 056e3170..153e61f7 100644 --- a/HTTPProxy.cpp +++ b/HTTPProxy.cpp @@ -122,6 +122,7 @@ namespace proxy m_address = url.host; m_port = url.port; m_path = url.path; + if (url.query.length () > 0) m_path += "?" + url.query; if (!m_port) m_port = 80; LogPrint(eLogDebug, "HTTPProxy: server: ", m_address, ", port: ", m_port, ", path: ", m_path); } From 44556b7f5e8e626c21f8ac5076e55760798d10d4 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 10 Jun 2016 15:25:30 -0400 Subject: [PATCH 2/9] correct string size for mapping --- I2CP.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/I2CP.cpp b/I2CP.cpp index 71188ec8..4842bf2d 100644 --- a/I2CP.cpp +++ b/I2CP.cpp @@ -277,7 +277,7 @@ namespace client while (offset < len) { std::string param = ExtractString (buf + offset, len - offset); - offset += param.length (); + offset += param.length () + 1; if (buf[offset] != '=') { LogPrint (eLogWarning, "I2CP: Unexpected character ", buf[offset], " instead '=' after ", param); @@ -286,7 +286,7 @@ namespace client offset++; std::string value = ExtractString (buf + offset, len - offset); - offset += value.length (); + offset += value.length () + 1; if (buf[offset] != ';') { LogPrint (eLogWarning, "I2CP: Unexpected character ", buf[offset], " instead ';' after ", value); From f4d8c3304abf47b851c706948337d75ab80b3747 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 10 Jun 2016 18:43:35 -0400 Subject: [PATCH 3/9] execute lookup wothout session --- I2CP.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/I2CP.cpp b/I2CP.cpp index 4842bf2d..68809817 100644 --- a/I2CP.cpp +++ b/I2CP.cpp @@ -449,7 +449,7 @@ namespace client void I2CPSession::HostLookupMessageHandler (const uint8_t * buf, size_t len) { uint16_t sessionID = bufbe16toh (buf); - if (sessionID == m_SessionID) + if (sessionID == m_SessionID || sessionID == 0xFFFF) // -1 means without session { uint32_t requestID = bufbe32toh (buf + 2); //uint32_t timeout = bufbe32toh (buf + 6); @@ -476,15 +476,17 @@ namespace client return; } - if (m_Destination) + std::shared_ptr destination = m_Destination; + if(!destination) destination = i2p::client::context.GetSharedLocalDestination (); + if (destination) { - auto ls = m_Destination->FindLeaseSet (ident); + auto ls = destination->FindLeaseSet (ident); if (ls) SendHostReplyMessage (requestID, ls->GetIdentity ()); else { auto s = shared_from_this (); - m_Destination->RequestDestination (ident, + destination->RequestDestination (ident, [s, requestID](std::shared_ptr leaseSet) { s->SendHostReplyMessage (requestID, leaseSet ? leaseSet->GetIdentity () : nullptr); From bf8db7725f6e3c7e1ec337563ab948197f92ee28 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 10 Jun 2016 22:13:20 -0400 Subject: [PATCH 4/9] set -1 as default session id --- I2CP.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/I2CP.cpp b/I2CP.cpp index 68809817..044fd7a3 100644 --- a/I2CP.cpp +++ b/I2CP.cpp @@ -117,7 +117,7 @@ namespace client I2CPSession::I2CPSession (I2CPServer& owner, std::shared_ptr socket): m_Owner (owner), m_Socket (socket), m_NextMessage (nullptr), m_NextMessageLen (0), m_NextMessageOffset (0), - m_SessionID (0), m_MessageID (0), m_IsSendAccepted (true) + m_SessionID (0xFFFF), m_MessageID (0), m_IsSendAccepted (true) { } From 88f52c490295c1ca703ce4b8bf6203ecf7b74e7c Mon Sep 17 00:00:00 2001 From: Osipov Kirill Date: Sat, 11 Jun 2016 11:20:20 +0300 Subject: [PATCH 5/9] Remove unused assigning (success is assinged anyway) --- AddressBook.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/AddressBook.cpp b/AddressBook.cpp index 0dbb42d7..5e7510a5 100644 --- a/AddressBook.cpp +++ b/AddressBook.cpp @@ -744,7 +744,6 @@ namespace client LogPrint (eLogInfo, "Addressbook: received ", m_Link, " ETag: ", m_Etag, " Last-Modified: ", m_LastModified); if (!response.eof () && !response.fail ()) { - success = true; if (!isChunked) success = ProcessResponse (response, isGzip); else From ae6877ce2fb7e496c2cc96deacc767c192b57eef Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 12 Jun 2016 08:22:55 -0400 Subject: [PATCH 6/9] handle incomplete message header --- I2CP.cpp | 83 ++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 62 insertions(+), 21 deletions(-) diff --git a/I2CP.cpp b/I2CP.cpp index 044fd7a3..dab7f9b0 100644 --- a/I2CP.cpp +++ b/I2CP.cpp @@ -167,24 +167,59 @@ namespace client size_t offset = 0; // from m_Buffer if (m_NextMessage) { - if (m_NextMessageOffset + bytes_transferred < m_NextMessageLen) + if (!m_NextMessageLen) // we didn't receive header yet { - memcpy (m_NextMessage + m_NextMessageOffset, m_Buffer, bytes_transferred); - m_NextMessageOffset += bytes_transferred; - offset = bytes_transferred; + if (m_NextMessageOffset + bytes_transferred < I2CP_HEADER_SIZE) + { + // still no complete header + memcpy (m_NextMessage + m_NextMessageOffset, m_Buffer, bytes_transferred); + m_NextMessageOffset += bytes_transferred; + offset = bytes_transferred; + } + else + { + // we know message length now + offset = I2CP_HEADER_SIZE - m_NextMessageOffset; + memcpy (m_NextMessage + m_NextMessageOffset, m_Buffer, offset); + m_NextMessageLen = bufbe32toh (m_NextMessage + I2CP_HEADER_LENGTH_OFFSET) + I2CP_HEADER_SIZE; + m_NextMessageOffset = I2CP_HEADER_SIZE; + } + } + + if (offset < bytes_transferred) + { + auto msgRemainingLen = m_NextMessageLen - m_NextMessageOffset; + auto bufRemainingLen = bytes_transferred - offset; + if (bufRemainingLen < msgRemainingLen) + { + memcpy (m_NextMessage + m_NextMessageOffset, m_Buffer + offset, bufRemainingLen); + m_NextMessageOffset += bufRemainingLen; + offset += bufRemainingLen; + } + else + { + // m_NextMessage complete + offset += msgRemainingLen; + memcpy (m_NextMessage + m_NextMessageOffset, m_Buffer + offset, msgRemainingLen); + HandleNextMessage (m_NextMessage); + delete[] m_NextMessage; + m_NextMessage = nullptr; + } } - else - { - // m_NextMessage complete - offset = m_NextMessageLen - m_NextMessageOffset; - memcpy (m_NextMessage + m_NextMessageOffset, m_Buffer, offset); - HandleNextMessage (m_NextMessage); - delete[] m_NextMessage; - m_NextMessage = nullptr; - } } + // process the rest while (offset < bytes_transferred) { + if (bytes_transferred - offset < I2CP_HEADER_SIZE) + { + // we don't have message header yet + m_NextMessage = new uint8_t[0xFFFF]; // allocate 64K + m_NextMessageLen = 0; // we must set message length later + m_NextMessageOffset = bytes_transferred - offset; + memcpy (m_NextMessage, m_Buffer + offset, m_NextMessageOffset); // just copy it + break; + } + auto msgLen = bufbe32toh (m_Buffer + offset + I2CP_HEADER_LENGTH_OFFSET) + I2CP_HEADER_SIZE; if (msgLen > 0xFFFF) // 64K { @@ -236,14 +271,20 @@ namespace client void I2CPSession::SendI2CPMessage (uint8_t type, const uint8_t * payload, size_t len) { - auto l = len + I2CP_HEADER_SIZE; - uint8_t * buf = new uint8_t[l]; - htobe32buf (buf + I2CP_HEADER_LENGTH_OFFSET, len); - buf[I2CP_HEADER_TYPE_OFFSET] = type; - memcpy (buf + I2CP_HEADER_SIZE, payload, len); - boost::asio::async_write (*m_Socket, boost::asio::buffer (buf, l), boost::asio::transfer_all (), - std::bind(&I2CPSession::HandleI2CPMessageSent, shared_from_this (), - std::placeholders::_1, std::placeholders::_2, buf)); + auto socket = m_Socket; + if (socket) + { + auto l = len + I2CP_HEADER_SIZE; + uint8_t * buf = new uint8_t[l]; + htobe32buf (buf + I2CP_HEADER_LENGTH_OFFSET, len); + buf[I2CP_HEADER_TYPE_OFFSET] = type; + memcpy (buf + I2CP_HEADER_SIZE, payload, len); + boost::asio::async_write (*socket, boost::asio::buffer (buf, l), boost::asio::transfer_all (), + std::bind(&I2CPSession::HandleI2CPMessageSent, shared_from_this (), + std::placeholders::_1, std::placeholders::_2, buf)); + } + else + LogPrint (eLogError, "I2CP: Can't write to the socket"); } void I2CPSession::HandleI2CPMessageSent (const boost::system::error_code& ecode, std::size_t bytes_transferred, const uint8_t * buf) From e795de5562309f7f2bd9dec4e6b0dee7d5ad9b07 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Mon, 13 Jun 2016 07:48:20 -0400 Subject: [PATCH 7/9] fix 500 response in http proxy --- HTTPProxy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HTTPProxy.cpp b/HTTPProxy.cpp index 153e61f7..48fa0ae6 100644 --- a/HTTPProxy.cpp +++ b/HTTPProxy.cpp @@ -93,7 +93,7 @@ namespace proxy //TODO: handle this apropriately void HTTPProxyHandler::HTTPRequestFailed(/*HTTPProxyHandler::errTypes error*/) { - static std::string response = "HTTP/1.0 500 Internal Server Error\r\nContent-type: text/html\r\nContent-length: 0\r\n"; + static std::string response = "HTTP/1.0 500 Internal Server Error\r\nContent-type: text/html\r\nContent-length: 0\r\n\r\n"; boost::asio::async_write(*m_sock, boost::asio::buffer(response,response.size()), std::bind(&HTTPProxyHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1)); } From fb94d6ae2b6419fe761728744ce1179409304d58 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 13 Jun 2016 13:20:21 -0400 Subject: [PATCH 8/9] read header and payload separately --- I2CP.cpp | 137 +++++++++++++++++++------------------------------------ I2CP.h | 12 +++-- 2 files changed, 53 insertions(+), 96 deletions(-) diff --git a/I2CP.cpp b/I2CP.cpp index dab7f9b0..f506a312 100644 --- a/I2CP.cpp +++ b/I2CP.cpp @@ -115,15 +115,14 @@ namespace client } I2CPSession::I2CPSession (I2CPServer& owner, std::shared_ptr socket): - m_Owner (owner), m_Socket (socket), - m_NextMessage (nullptr), m_NextMessageLen (0), m_NextMessageOffset (0), + m_Owner (owner), m_Socket (socket), m_Payload (nullptr), m_SessionID (0xFFFF), m_MessageID (0), m_IsSendAccepted (true) { } I2CPSession::~I2CPSession () { - delete[] m_NextMessage; + delete[] m_Payload; } void I2CPSession::Start () @@ -141,117 +140,72 @@ namespace client if (m_Socket) { auto s = shared_from_this (); - m_Socket->async_read_some (boost::asio::buffer (m_Buffer, 1), + m_Socket->async_read_some (boost::asio::buffer (m_Header, 1), [s](const boost::system::error_code& ecode, std::size_t bytes_transferred) { - if (!ecode && bytes_transferred > 0 && s->m_Buffer[0] == I2CP_PROTOCOL_BYTE) - s->Receive (); + if (!ecode && bytes_transferred > 0 && s->m_Header[0] == I2CP_PROTOCOL_BYTE) + s->ReceiveHeader (); else s->Terminate (); }); } } - void I2CPSession::Receive () + void I2CPSession::ReceiveHeader () { - m_Socket->async_read_some (boost::asio::buffer (m_Buffer, I2CP_SESSION_BUFFER_SIZE), - std::bind (&I2CPSession::HandleReceived, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); + boost::asio::async_read (*m_Socket, boost::asio::buffer (m_Header, I2CP_HEADER_SIZE), + boost::asio::transfer_all (), + std::bind (&I2CPSession::HandleReceivedHeader, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); } - void I2CPSession::HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred) + void I2CPSession::HandleReceivedHeader (const boost::system::error_code& ecode, std::size_t bytes_transferred) { if (ecode) Terminate (); else { - size_t offset = 0; // from m_Buffer - if (m_NextMessage) + m_PayloadLen = bufbe32toh (m_Header + I2CP_HEADER_LENGTH_OFFSET); + if (m_PayloadLen > 0) { - if (!m_NextMessageLen) // we didn't receive header yet - { - if (m_NextMessageOffset + bytes_transferred < I2CP_HEADER_SIZE) - { - // still no complete header - memcpy (m_NextMessage + m_NextMessageOffset, m_Buffer, bytes_transferred); - m_NextMessageOffset += bytes_transferred; - offset = bytes_transferred; - } - else - { - // we know message length now - offset = I2CP_HEADER_SIZE - m_NextMessageOffset; - memcpy (m_NextMessage + m_NextMessageOffset, m_Buffer, offset); - m_NextMessageLen = bufbe32toh (m_NextMessage + I2CP_HEADER_LENGTH_OFFSET) + I2CP_HEADER_SIZE; - m_NextMessageOffset = I2CP_HEADER_SIZE; - } - } - - if (offset < bytes_transferred) - { - auto msgRemainingLen = m_NextMessageLen - m_NextMessageOffset; - auto bufRemainingLen = bytes_transferred - offset; - if (bufRemainingLen < msgRemainingLen) - { - memcpy (m_NextMessage + m_NextMessageOffset, m_Buffer + offset, bufRemainingLen); - m_NextMessageOffset += bufRemainingLen; - offset += bufRemainingLen; - } - else - { - // m_NextMessage complete - offset += msgRemainingLen; - memcpy (m_NextMessage + m_NextMessageOffset, m_Buffer + offset, msgRemainingLen); - HandleNextMessage (m_NextMessage); - delete[] m_NextMessage; - m_NextMessage = nullptr; - } - } - } - // process the rest - while (offset < bytes_transferred) + m_Payload = new uint8_t[m_PayloadLen]; + ReceivePayload (); + } + else // no following payload { - if (bytes_transferred - offset < I2CP_HEADER_SIZE) - { - // we don't have message header yet - m_NextMessage = new uint8_t[0xFFFF]; // allocate 64K - m_NextMessageLen = 0; // we must set message length later - m_NextMessageOffset = bytes_transferred - offset; - memcpy (m_NextMessage, m_Buffer + offset, m_NextMessageOffset); // just copy it - break; - } - - auto msgLen = bufbe32toh (m_Buffer + offset + I2CP_HEADER_LENGTH_OFFSET) + I2CP_HEADER_SIZE; - if (msgLen > 0xFFFF) // 64K - { - LogPrint (eLogError, "I2CP: message length ", msgLen, " exceeds 64K. Terminated"); - Terminate (); - return; - } - if (msgLen <= bytes_transferred - offset) - { - HandleNextMessage (m_Buffer + offset); - offset += msgLen; - } - else - { - m_NextMessageLen = msgLen; - m_NextMessageOffset = bytes_transferred - offset; - m_NextMessage = new uint8_t[m_NextMessageLen]; - memcpy (m_NextMessage, m_Buffer + offset, m_NextMessageOffset); - offset = bytes_transferred; - } - } - Receive (); + HandleMessage (); + ReceiveHeader (); // next message + } } } - void I2CPSession::HandleNextMessage (const uint8_t * buf) + void I2CPSession::ReceivePayload () { - auto handler = m_Owner.GetMessagesHandlers ()[buf[I2CP_HEADER_TYPE_OFFSET]]; - if (handler) - (this->*handler)(buf + I2CP_HEADER_SIZE, bufbe32toh (buf + I2CP_HEADER_LENGTH_OFFSET)); + boost::asio::async_read (*m_Socket, boost::asio::buffer (m_Payload, m_PayloadLen), + boost::asio::transfer_all (), + std::bind (&I2CPSession::HandleReceivedPayload, shared_from_this (), std::placeholders::_1, std::placeholders::_2)); + } + + void I2CPSession::HandleReceivedPayload (const boost::system::error_code& ecode, std::size_t bytes_transferred) + { + if (ecode) + Terminate (); else - LogPrint (eLogError, "I2CP: Unknown I2CP messsage ", (int)buf[I2CP_HEADER_TYPE_OFFSET]); + { + HandleMessage (); + delete[] m_Payload; + m_Payload = nullptr; + m_PayloadLen = 0; + ReceiveHeader (); // next message + } + } + + void I2CPSession::HandleMessage () + { + auto handler = m_Owner.GetMessagesHandlers ()[m_Header[I2CP_HEADER_TYPE_OFFSET]]; + if (handler) + (this->*handler)(m_Payload, m_PayloadLen); + else + LogPrint (eLogError, "I2CP: Unknown I2CP messsage ", (int)m_Header[I2CP_HEADER_TYPE_OFFSET]); } void I2CPSession::Terminate () @@ -267,6 +221,7 @@ namespace client m_Socket = nullptr; } m_Owner.RemoveSession (GetSessionID ()); + LogPrint (eLogDebug, "I2CP: session ", m_SessionID, " terminated"); } void I2CPSession::SendI2CPMessage (uint8_t type, const uint8_t * payload, size_t len) diff --git a/I2CP.h b/I2CP.h index f77607ba..6fc0e846 100644 --- a/I2CP.h +++ b/I2CP.h @@ -126,9 +126,11 @@ namespace client private: void ReadProtocolByte (); - void Receive (); - void HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred); - void HandleNextMessage (const uint8_t * buf); + void ReceiveHeader (); + void HandleReceivedHeader (const boost::system::error_code& ecode, std::size_t bytes_transferred); + void ReceivePayload (); + void HandleReceivedPayload (const boost::system::error_code& ecode, std::size_t bytes_transferred); + void HandleMessage (); void Terminate (); void HandleI2CPMessageSent (const boost::system::error_code& ecode, std::size_t bytes_transferred, const uint8_t * buf); @@ -143,8 +145,8 @@ namespace client I2CPServer& m_Owner; std::shared_ptr m_Socket; - uint8_t m_Buffer[I2CP_SESSION_BUFFER_SIZE], * m_NextMessage; - size_t m_NextMessageLen, m_NextMessageOffset; + uint8_t m_Header[I2CP_HEADER_SIZE], * m_Payload; + size_t m_PayloadLen; std::shared_ptr m_Destination; uint16_t m_SessionID; From b8eef181b93b9c7d2e266d47a7782b45b7aba442 Mon Sep 17 00:00:00 2001 From: Andrey Tikhomirov Date: Tue, 14 Jun 2016 11:25:51 +0300 Subject: [PATCH 9/9] Fix html attributes --- HTTPServer.cpp | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index 7b7b8bcc..a48536a7 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -127,7 +127,7 @@ namespace http { "\r\n" /* TODO: Add support for locale */ " \r\n" " \r\n" /* TODO: Find something to parse html/template system. This is horrible. */ - " \r\n" + " \r\n" " Purple I2P " VERSION " Webconsole\r\n" << cssStyles << "\r\n"; @@ -136,15 +136,15 @@ namespace http { "
i2pd webconsole
\r\n" "
\r\n" "
\r\n" - " Main page
\r\n
\r\n" - " Router commands
\r\n" - " Local destinations
\r\n" - " Tunnels
\r\n" - " Transit tunnels
\r\n" - " Transports
\r\n" - " I2P tunnels
\r\n" - " Jump services
\r\n" - " SAM sessions
\r\n" + " Main page
\r\n
\r\n" + " Router commands
\r\n" + " Local destinations
\r\n" + " Tunnels
\r\n" + " Transit tunnels
\r\n" + " Transports
\r\n" + " I2P tunnels
\r\n" + " Jump services
\r\n" + " SAM sessions
\r\n" "
\r\n" "
"; } @@ -236,9 +236,9 @@ namespace http { void ShowJumpServices (std::stringstream& s, const std::string& address) { - s << "
"; + s << ""; s << ""; - s << ""; + s << ""; s << ""; s << "

\r\n"; s << "Jump services for " << address << "\r\n