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
diff --git a/HTTPProxy.cpp b/HTTPProxy.cpp
index 056e3170..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));
}
@@ -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);
}
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 {
"\r\n"
"\r\n"
"
\r\n"
"
";
}
@@ -236,9 +236,9 @@ namespace http {
void ShowJumpServices (std::stringstream& s, const std::string& address)
{
- s << "
\r\n";
s << "
Jump services for " << address << "\r\n
\r\n";
@@ -254,7 +254,7 @@ namespace http {
for (auto& it: i2p::client::context.GetDestinations ())
{
auto ident = it.second->GetIdentHash ();;
- s << "";
+ s << "";
s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "
\r\n" << std::endl;
}
}
@@ -358,21 +358,21 @@ namespace http {
{
/* commands */
s << "Router Commands
\r\n";
- s << " Run peer test
\r\n";
- //s << " Reload config
\r\n";
+ s << " Run peer test
\r\n";
+ //s << " Reload config
\r\n";
if (i2p::context.AcceptsTunnels ())
- s << " Stop accepting tunnels
\r\n";
+ s << " Stop accepting tunnels
\r\n";
else
- s << " Start accepting tunnels
\r\n";
+ s << " Start accepting tunnels
\r\n";
#ifndef WIN32
if (Daemon.gracefullShutdownInterval) {
- s << " Cancel gracefull shutdown (";
+ s << " Cancel gracefull shutdown (";
s << Daemon.gracefullShutdownInterval;
s << " seconds remains)
\r\n";
} else {
- s << " Start gracefull shutdown
\r\n";
+ s << " Start gracefull shutdown
\r\n";
}
- s << " Force shutdown
\r\n";
+ s << " Force shutdown
\r\n";
#endif
}
@@ -450,7 +450,7 @@ namespace http {
s << "SAM Sessions:
\r\n
\r\n";
for (auto& it: sam->GetSessions ())
{
- s << "";
+ s << "";
s << it.first << "
\r\n" << std::endl;
}
}
@@ -469,7 +469,7 @@ namespace http {
return;
}
auto& ident = session->localDestination->GetIdentHash();
- s << "";
+ s << "";
s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "
\r\n";
s << "
\r\n";
s << "Streams:
\r\n";
@@ -493,7 +493,7 @@ namespace http {
for (auto& it: i2p::client::context.GetClientTunnels ())
{
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
- s << "";
+ s << "";
s << it.second->GetName () << " ⇐ ";
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
s << "
\r\n"<< std::endl;
@@ -502,7 +502,7 @@ namespace http {
for (auto& it: i2p::client::context.GetServerTunnels ())
{
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
- s << "";
+ s << "";
s << it.second->GetName () << " ⇒ ";
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
s << ":" << it.second->GetLocalPort ();
diff --git a/I2CP.cpp b/I2CP.cpp
index 71188ec8..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_SessionID (0), m_MessageID (0), m_IsSendAccepted (true)
+ 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,82 +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_NextMessageOffset + bytes_transferred < m_NextMessageLen)
- {
- memcpy (m_NextMessage + m_NextMessageOffset, m_Buffer, bytes_transferred);
- m_NextMessageOffset += bytes_transferred;
- offset = bytes_transferred;
- }
- 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;
- }
- }
- while (offset < bytes_transferred)
+ m_Payload = new uint8_t[m_PayloadLen];
+ ReceivePayload ();
+ }
+ else // no following payload
{
- 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 ()
@@ -232,18 +221,25 @@ 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)
{
- 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)
@@ -277,7 +273,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 +282,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);
@@ -449,7 +445,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 +472,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);
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;