mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-23 22:07:16 +01:00
commit
d7a06dc7a9
|
@ -744,7 +744,6 @@ namespace client
|
||||||
LogPrint (eLogInfo, "Addressbook: received ", m_Link, " ETag: ", m_Etag, " Last-Modified: ", m_LastModified);
|
LogPrint (eLogInfo, "Addressbook: received ", m_Link, " ETag: ", m_Etag, " Last-Modified: ", m_LastModified);
|
||||||
if (!response.eof () && !response.fail ())
|
if (!response.eof () && !response.fail ())
|
||||||
{
|
{
|
||||||
success = true;
|
|
||||||
if (!isChunked)
|
if (!isChunked)
|
||||||
success = ProcessResponse (response, isGzip);
|
success = ProcessResponse (response, isGzip);
|
||||||
else
|
else
|
||||||
|
|
|
@ -93,7 +93,7 @@ namespace proxy
|
||||||
//TODO: handle this apropriately
|
//TODO: handle this apropriately
|
||||||
void HTTPProxyHandler::HTTPRequestFailed(/*HTTPProxyHandler::errTypes error*/)
|
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()),
|
boost::asio::async_write(*m_sock, boost::asio::buffer(response,response.size()),
|
||||||
std::bind(&HTTPProxyHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1));
|
std::bind(&HTTPProxyHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1));
|
||||||
}
|
}
|
||||||
|
@ -122,6 +122,7 @@ namespace proxy
|
||||||
m_address = url.host;
|
m_address = url.host;
|
||||||
m_port = url.port;
|
m_port = url.port;
|
||||||
m_path = url.path;
|
m_path = url.path;
|
||||||
|
if (url.query.length () > 0) m_path += "?" + url.query;
|
||||||
if (!m_port) m_port = 80;
|
if (!m_port) m_port = 80;
|
||||||
LogPrint(eLogDebug, "HTTPProxy: server: ", m_address, ", port: ", m_port, ", path: ", m_path);
|
LogPrint(eLogDebug, "HTTPProxy: server: ", m_address, ", port: ", m_port, ", path: ", m_path);
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,7 +127,7 @@ namespace http {
|
||||||
"<html lang=\"en\">\r\n" /* TODO: Add support for locale */
|
"<html lang=\"en\">\r\n" /* TODO: Add support for locale */
|
||||||
" <head>\r\n"
|
" <head>\r\n"
|
||||||
" <meta charset=\"UTF-8\">\r\n" /* TODO: Find something to parse html/template system. This is horrible. */
|
" <meta charset=\"UTF-8\">\r\n" /* TODO: Find something to parse html/template system. This is horrible. */
|
||||||
" <link rel='shortcut icon' href='" << itoopieFavicon << "'>\r\n"
|
" <link rel=\"shortcut icon\" href=\"" << itoopieFavicon << "\">\r\n"
|
||||||
" <title>Purple I2P " VERSION " Webconsole</title>\r\n"
|
" <title>Purple I2P " VERSION " Webconsole</title>\r\n"
|
||||||
<< cssStyles <<
|
<< cssStyles <<
|
||||||
"</head>\r\n";
|
"</head>\r\n";
|
||||||
|
@ -136,15 +136,15 @@ namespace http {
|
||||||
"<div class=header><b>i2pd</b> webconsole</div>\r\n"
|
"<div class=header><b>i2pd</b> webconsole</div>\r\n"
|
||||||
"<div class=wrapper>\r\n"
|
"<div class=wrapper>\r\n"
|
||||||
"<div class=left>\r\n"
|
"<div class=left>\r\n"
|
||||||
" <a href=/>Main page</a><br>\r\n<br>\r\n"
|
" <a href=\"/\">Main page</a><br>\r\n<br>\r\n"
|
||||||
" <a href=/?page=" << HTTP_PAGE_COMMANDS << ">Router commands</a><br>\r\n"
|
" <a href=\"/?page=" << HTTP_PAGE_COMMANDS << "\">Router commands</a><br>\r\n"
|
||||||
" <a href=/?page=" << HTTP_PAGE_LOCAL_DESTINATIONS << ">Local destinations</a><br>\r\n"
|
" <a href=\"/?page=" << HTTP_PAGE_LOCAL_DESTINATIONS << "\">Local destinations</a><br>\r\n"
|
||||||
" <a href=/?page=" << HTTP_PAGE_TUNNELS << ">Tunnels</a><br>\r\n"
|
" <a href=\"/?page=" << HTTP_PAGE_TUNNELS << "\">Tunnels</a><br>\r\n"
|
||||||
" <a href=/?page=" << HTTP_PAGE_TRANSIT_TUNNELS << ">Transit tunnels</a><br>\r\n"
|
" <a href=\"/?page=" << HTTP_PAGE_TRANSIT_TUNNELS << "\">Transit tunnels</a><br>\r\n"
|
||||||
" <a href=/?page=" << HTTP_PAGE_TRANSPORTS << ">Transports</a><br>\r\n"
|
" <a href=\"/?page=" << HTTP_PAGE_TRANSPORTS << "\">Transports</a><br>\r\n"
|
||||||
" <a href=/?page=" << HTTP_PAGE_I2P_TUNNELS << ">I2P tunnels</a><br>\r\n"
|
" <a href=\"/?page=" << HTTP_PAGE_I2P_TUNNELS << "\">I2P tunnels</a><br>\r\n"
|
||||||
" <a href=/?page=" << HTTP_PAGE_JUMPSERVICES << ">Jump services</a><br>\r\n"
|
" <a href=\"/?page=" << HTTP_PAGE_JUMPSERVICES << "\">Jump services</a><br>\r\n"
|
||||||
" <a href=/?page=" << HTTP_PAGE_SAM_SESSIONS << ">SAM sessions</a><br>\r\n"
|
" <a href=\"/?page=" << HTTP_PAGE_SAM_SESSIONS << "\">SAM sessions</a><br>\r\n"
|
||||||
"</div>\r\n"
|
"</div>\r\n"
|
||||||
"<div class=right>";
|
"<div class=right>";
|
||||||
}
|
}
|
||||||
|
@ -236,9 +236,9 @@ namespace http {
|
||||||
|
|
||||||
void ShowJumpServices (std::stringstream& s, const std::string& address)
|
void ShowJumpServices (std::stringstream& s, const std::string& address)
|
||||||
{
|
{
|
||||||
s << "<form type=\"GET\" action=\"/\">";
|
s << "<form method=\"get\" action=\"/\">";
|
||||||
s << "<input type=\"hidden\" name=\"page\" value=\"jumpservices\">";
|
s << "<input type=\"hidden\" name=\"page\" value=\"jumpservices\">";
|
||||||
s << "<input type=\"text\" name=\"address\" value=\"" << address << "\">";
|
s << "<input type=\"text\" name=\"address\" value=\"" << address << "\">";
|
||||||
s << "<input type=\"submit\" value=\"Update\">";
|
s << "<input type=\"submit\" value=\"Update\">";
|
||||||
s << "</form><br>\r\n";
|
s << "</form><br>\r\n";
|
||||||
s << "<b>Jump services for " << address << "</b>\r\n<ul>\r\n";
|
s << "<b>Jump services for " << address << "</b>\r\n<ul>\r\n";
|
||||||
|
@ -254,7 +254,7 @@ namespace http {
|
||||||
for (auto& it: i2p::client::context.GetDestinations ())
|
for (auto& it: i2p::client::context.GetDestinations ())
|
||||||
{
|
{
|
||||||
auto ident = it.second->GetIdentHash ();;
|
auto ident = it.second->GetIdentHash ();;
|
||||||
s << "<a href=/?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << ">";
|
s << "<a href=\"/?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
||||||
s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "</a><br>\r\n" << std::endl;
|
s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "</a><br>\r\n" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -358,21 +358,21 @@ namespace http {
|
||||||
{
|
{
|
||||||
/* commands */
|
/* commands */
|
||||||
s << "<b>Router Commands</b><br>\r\n";
|
s << "<b>Router Commands</b><br>\r\n";
|
||||||
s << " <a href=/?cmd=" << HTTP_COMMAND_RUN_PEER_TEST << ">Run peer test</a><br>\r\n";
|
s << " <a href=\"/?cmd=" << HTTP_COMMAND_RUN_PEER_TEST << "\">Run peer test</a><br>\r\n";
|
||||||
//s << " <a href=/?cmd=" << HTTP_COMMAND_RELOAD_CONFIG << ">Reload config</a><br>\r\n";
|
//s << " <a href=\"/?cmd=" << HTTP_COMMAND_RELOAD_CONFIG << "\">Reload config</a><br>\r\n";
|
||||||
if (i2p::context.AcceptsTunnels ())
|
if (i2p::context.AcceptsTunnels ())
|
||||||
s << " <a href=/?cmd=" << HTTP_COMMAND_STOP_ACCEPTING_TUNNELS << ">Stop accepting tunnels</a><br>\r\n";
|
s << " <a href=\"/?cmd=" << HTTP_COMMAND_STOP_ACCEPTING_TUNNELS << "\">Stop accepting tunnels</a><br>\r\n";
|
||||||
else
|
else
|
||||||
s << " <a href=/?cmd=" << HTTP_COMMAND_START_ACCEPTING_TUNNELS << ">Start accepting tunnels</a><br>\r\n";
|
s << " <a href=\"/?cmd=" << HTTP_COMMAND_START_ACCEPTING_TUNNELS << "\">Start accepting tunnels</a><br>\r\n";
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
if (Daemon.gracefullShutdownInterval) {
|
if (Daemon.gracefullShutdownInterval) {
|
||||||
s << " <a href=/?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << ">Cancel gracefull shutdown (";
|
s << " <a href=\"/?cmd=" << HTTP_COMMAND_SHUTDOWN_CANCEL << "\">Cancel gracefull shutdown (";
|
||||||
s << Daemon.gracefullShutdownInterval;
|
s << Daemon.gracefullShutdownInterval;
|
||||||
s << " seconds remains)</a><br>\r\n";
|
s << " seconds remains)</a><br>\r\n";
|
||||||
} else {
|
} else {
|
||||||
s << " <a href=/?cmd=" << HTTP_COMMAND_SHUTDOWN_START << ">Start gracefull shutdown</a><br>\r\n";
|
s << " <a href=\"/?cmd=" << HTTP_COMMAND_SHUTDOWN_START << "\">Start gracefull shutdown</a><br>\r\n";
|
||||||
}
|
}
|
||||||
s << " <a href=/?cmd=" << HTTP_COMMAND_SHUTDOWN_NOW << ">Force shutdown</a><br>\r\n";
|
s << " <a href=\"/?cmd=" << HTTP_COMMAND_SHUTDOWN_NOW << "\">Force shutdown</a><br>\r\n";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -450,7 +450,7 @@ namespace http {
|
||||||
s << "<b>SAM Sessions:</b><br>\r\n<br>\r\n";
|
s << "<b>SAM Sessions:</b><br>\r\n<br>\r\n";
|
||||||
for (auto& it: sam->GetSessions ())
|
for (auto& it: sam->GetSessions ())
|
||||||
{
|
{
|
||||||
s << "<a href=/?page=" << HTTP_PAGE_SAM_SESSION << "&sam_id=" << it.first << ">";
|
s << "<a href=\"/?page=" << HTTP_PAGE_SAM_SESSION << "&sam_id=" << it.first << "\">";
|
||||||
s << it.first << "</a><br>\r\n" << std::endl;
|
s << it.first << "</a><br>\r\n" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -469,7 +469,7 @@ namespace http {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto& ident = session->localDestination->GetIdentHash();
|
auto& ident = session->localDestination->GetIdentHash();
|
||||||
s << "<a href=/?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << ">";
|
s << "<a href=\"/?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
||||||
s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "</a><br>\r\n";
|
s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "</a><br>\r\n";
|
||||||
s << "<br>\r\n";
|
s << "<br>\r\n";
|
||||||
s << "<b>Streams:</b><br>\r\n";
|
s << "<b>Streams:</b><br>\r\n";
|
||||||
|
@ -493,7 +493,7 @@ namespace http {
|
||||||
for (auto& it: i2p::client::context.GetClientTunnels ())
|
for (auto& it: i2p::client::context.GetClientTunnels ())
|
||||||
{
|
{
|
||||||
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
||||||
s << "<a href=/?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << ">";
|
s << "<a href=\"/?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
||||||
s << it.second->GetName () << "</a> ⇐ ";
|
s << it.second->GetName () << "</a> ⇐ ";
|
||||||
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
||||||
s << "<br>\r\n"<< std::endl;
|
s << "<br>\r\n"<< std::endl;
|
||||||
|
@ -502,7 +502,7 @@ namespace http {
|
||||||
for (auto& it: i2p::client::context.GetServerTunnels ())
|
for (auto& it: i2p::client::context.GetServerTunnels ())
|
||||||
{
|
{
|
||||||
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
|
||||||
s << "<a href=/?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << ">";
|
s << "<a href=\"/?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
|
||||||
s << it.second->GetName () << "</a> ⇒ ";
|
s << it.second->GetName () << "</a> ⇒ ";
|
||||||
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
|
||||||
s << ":" << it.second->GetLocalPort ();
|
s << ":" << it.second->GetLocalPort ();
|
||||||
|
|
136
I2CP.cpp
136
I2CP.cpp
|
@ -115,15 +115,14 @@ namespace client
|
||||||
}
|
}
|
||||||
|
|
||||||
I2CPSession::I2CPSession (I2CPServer& owner, std::shared_ptr<boost::asio::ip::tcp::socket> socket):
|
I2CPSession::I2CPSession (I2CPServer& owner, std::shared_ptr<boost::asio::ip::tcp::socket> socket):
|
||||||
m_Owner (owner), m_Socket (socket),
|
m_Owner (owner), m_Socket (socket), m_Payload (nullptr),
|
||||||
m_NextMessage (nullptr), m_NextMessageLen (0), m_NextMessageOffset (0),
|
m_SessionID (0xFFFF), m_MessageID (0), m_IsSendAccepted (true)
|
||||||
m_SessionID (0), m_MessageID (0), m_IsSendAccepted (true)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
I2CPSession::~I2CPSession ()
|
I2CPSession::~I2CPSession ()
|
||||||
{
|
{
|
||||||
delete[] m_NextMessage;
|
delete[] m_Payload;
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2CPSession::Start ()
|
void I2CPSession::Start ()
|
||||||
|
@ -141,82 +140,72 @@ namespace client
|
||||||
if (m_Socket)
|
if (m_Socket)
|
||||||
{
|
{
|
||||||
auto s = shared_from_this ();
|
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)
|
[s](const boost::system::error_code& ecode, std::size_t bytes_transferred)
|
||||||
{
|
{
|
||||||
if (!ecode && bytes_transferred > 0 && s->m_Buffer[0] == I2CP_PROTOCOL_BYTE)
|
if (!ecode && bytes_transferred > 0 && s->m_Header[0] == I2CP_PROTOCOL_BYTE)
|
||||||
s->Receive ();
|
s->ReceiveHeader ();
|
||||||
else
|
else
|
||||||
s->Terminate ();
|
s->Terminate ();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2CPSession::Receive ()
|
void I2CPSession::ReceiveHeader ()
|
||||||
{
|
{
|
||||||
m_Socket->async_read_some (boost::asio::buffer (m_Buffer, I2CP_SESSION_BUFFER_SIZE),
|
boost::asio::async_read (*m_Socket, boost::asio::buffer (m_Header, I2CP_HEADER_SIZE),
|
||||||
std::bind (&I2CPSession::HandleReceived, shared_from_this (), std::placeholders::_1, std::placeholders::_2));
|
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)
|
if (ecode)
|
||||||
Terminate ();
|
Terminate ();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
size_t offset = 0; // from m_Buffer
|
m_PayloadLen = bufbe32toh (m_Header + I2CP_HEADER_LENGTH_OFFSET);
|
||||||
if (m_NextMessage)
|
if (m_PayloadLen > 0)
|
||||||
{
|
{
|
||||||
if (m_NextMessageOffset + bytes_transferred < m_NextMessageLen)
|
m_Payload = new uint8_t[m_PayloadLen];
|
||||||
{
|
ReceivePayload ();
|
||||||
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)
|
else // no following payload
|
||||||
{
|
{
|
||||||
auto msgLen = bufbe32toh (m_Buffer + offset + I2CP_HEADER_LENGTH_OFFSET) + I2CP_HEADER_SIZE;
|
HandleMessage ();
|
||||||
if (msgLen > 0xFFFF) // 64K
|
ReceiveHeader (); // next message
|
||||||
{
|
|
||||||
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 ();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2CPSession::HandleNextMessage (const uint8_t * buf)
|
void I2CPSession::ReceivePayload ()
|
||||||
{
|
{
|
||||||
auto handler = m_Owner.GetMessagesHandlers ()[buf[I2CP_HEADER_TYPE_OFFSET]];
|
boost::asio::async_read (*m_Socket, boost::asio::buffer (m_Payload, m_PayloadLen),
|
||||||
if (handler)
|
boost::asio::transfer_all (),
|
||||||
(this->*handler)(buf + I2CP_HEADER_SIZE, bufbe32toh (buf + I2CP_HEADER_LENGTH_OFFSET));
|
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
|
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 ()
|
void I2CPSession::Terminate ()
|
||||||
|
@ -232,18 +221,25 @@ namespace client
|
||||||
m_Socket = nullptr;
|
m_Socket = nullptr;
|
||||||
}
|
}
|
||||||
m_Owner.RemoveSession (GetSessionID ());
|
m_Owner.RemoveSession (GetSessionID ());
|
||||||
|
LogPrint (eLogDebug, "I2CP: session ", m_SessionID, " terminated");
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2CPSession::SendI2CPMessage (uint8_t type, const uint8_t * payload, size_t len)
|
void I2CPSession::SendI2CPMessage (uint8_t type, const uint8_t * payload, size_t len)
|
||||||
{
|
{
|
||||||
auto l = len + I2CP_HEADER_SIZE;
|
auto socket = m_Socket;
|
||||||
uint8_t * buf = new uint8_t[l];
|
if (socket)
|
||||||
htobe32buf (buf + I2CP_HEADER_LENGTH_OFFSET, len);
|
{
|
||||||
buf[I2CP_HEADER_TYPE_OFFSET] = type;
|
auto l = len + I2CP_HEADER_SIZE;
|
||||||
memcpy (buf + I2CP_HEADER_SIZE, payload, len);
|
uint8_t * buf = new uint8_t[l];
|
||||||
boost::asio::async_write (*m_Socket, boost::asio::buffer (buf, l), boost::asio::transfer_all (),
|
htobe32buf (buf + I2CP_HEADER_LENGTH_OFFSET, len);
|
||||||
std::bind(&I2CPSession::HandleI2CPMessageSent, shared_from_this (),
|
buf[I2CP_HEADER_TYPE_OFFSET] = type;
|
||||||
std::placeholders::_1, std::placeholders::_2, buf));
|
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)
|
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)
|
while (offset < len)
|
||||||
{
|
{
|
||||||
std::string param = ExtractString (buf + offset, len - offset);
|
std::string param = ExtractString (buf + offset, len - offset);
|
||||||
offset += param.length ();
|
offset += param.length () + 1;
|
||||||
if (buf[offset] != '=')
|
if (buf[offset] != '=')
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "I2CP: Unexpected character ", buf[offset], " instead '=' after ", param);
|
LogPrint (eLogWarning, "I2CP: Unexpected character ", buf[offset], " instead '=' after ", param);
|
||||||
|
@ -286,7 +282,7 @@ namespace client
|
||||||
offset++;
|
offset++;
|
||||||
|
|
||||||
std::string value = ExtractString (buf + offset, len - offset);
|
std::string value = ExtractString (buf + offset, len - offset);
|
||||||
offset += value.length ();
|
offset += value.length () + 1;
|
||||||
if (buf[offset] != ';')
|
if (buf[offset] != ';')
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "I2CP: Unexpected character ", buf[offset], " instead ';' after ", value);
|
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)
|
void I2CPSession::HostLookupMessageHandler (const uint8_t * buf, size_t len)
|
||||||
{
|
{
|
||||||
uint16_t sessionID = bufbe16toh (buf);
|
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 requestID = bufbe32toh (buf + 2);
|
||||||
//uint32_t timeout = bufbe32toh (buf + 6);
|
//uint32_t timeout = bufbe32toh (buf + 6);
|
||||||
|
@ -476,15 +472,17 @@ namespace client
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_Destination)
|
std::shared_ptr<LeaseSetDestination> 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)
|
if (ls)
|
||||||
SendHostReplyMessage (requestID, ls->GetIdentity ());
|
SendHostReplyMessage (requestID, ls->GetIdentity ());
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto s = shared_from_this ();
|
auto s = shared_from_this ();
|
||||||
m_Destination->RequestDestination (ident,
|
destination->RequestDestination (ident,
|
||||||
[s, requestID](std::shared_ptr<i2p::data::LeaseSet> leaseSet)
|
[s, requestID](std::shared_ptr<i2p::data::LeaseSet> leaseSet)
|
||||||
{
|
{
|
||||||
s->SendHostReplyMessage (requestID, leaseSet ? leaseSet->GetIdentity () : nullptr);
|
s->SendHostReplyMessage (requestID, leaseSet ? leaseSet->GetIdentity () : nullptr);
|
||||||
|
|
12
I2CP.h
12
I2CP.h
|
@ -126,9 +126,11 @@ namespace client
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void ReadProtocolByte ();
|
void ReadProtocolByte ();
|
||||||
void Receive ();
|
void ReceiveHeader ();
|
||||||
void HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred);
|
void HandleReceivedHeader (const boost::system::error_code& ecode, std::size_t bytes_transferred);
|
||||||
void HandleNextMessage (const uint8_t * buf);
|
void ReceivePayload ();
|
||||||
|
void HandleReceivedPayload (const boost::system::error_code& ecode, std::size_t bytes_transferred);
|
||||||
|
void HandleMessage ();
|
||||||
void Terminate ();
|
void Terminate ();
|
||||||
|
|
||||||
void HandleI2CPMessageSent (const boost::system::error_code& ecode, std::size_t bytes_transferred, const uint8_t * buf);
|
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;
|
I2CPServer& m_Owner;
|
||||||
std::shared_ptr<boost::asio::ip::tcp::socket> m_Socket;
|
std::shared_ptr<boost::asio::ip::tcp::socket> m_Socket;
|
||||||
uint8_t m_Buffer[I2CP_SESSION_BUFFER_SIZE], * m_NextMessage;
|
uint8_t m_Header[I2CP_HEADER_SIZE], * m_Payload;
|
||||||
size_t m_NextMessageLen, m_NextMessageOffset;
|
size_t m_PayloadLen;
|
||||||
|
|
||||||
std::shared_ptr<I2CPDestination> m_Destination;
|
std::shared_ptr<I2CPDestination> m_Destination;
|
||||||
uint16_t m_SessionID;
|
uint16_t m_SessionID;
|
||||||
|
|
Loading…
Reference in a new issue