diff --git a/HTTPServer.cpp b/HTTPServer.cpp
index a66a394f..5dd349dd 100644
--- a/HTTPServer.cpp
+++ b/HTTPServer.cpp
@@ -332,6 +332,7 @@ namespace util
void HTTPConnection::HandleDestinationRequest (const std::string& address, const std::string& method, const std::string& data, const std::string& uri)
{
+ const i2p::data::LeaseSet * leaseSet = nullptr;
i2p::data::IdentHash destination;
std::string fullAddress;
if (address.find(".b32.i2p") != std::string::npos)
@@ -360,17 +361,29 @@ namespace util
}
else
{
- if (i2p::data::Base32ToByteStream(address.c_str(), address.length(), (uint8_t *)destination, 32) != 32)
+ if (address == "local")
{
- LogPrint("Invalid Base32 address ", address);
- SendReply("" + itoopieImage + "
Invalid Base32 address", 400);
- return;
+ // TODO: remove later
+ fullAddress = "local.i2p";
+ auto destination = i2p::stream::GetSharedLocalDestination ();
+ leaseSet = destination->GetLeaseSet ();
+ EepAccept (destination);
}
- fullAddress = address + ".b32.i2p";
+ else
+ {
+ if (i2p::data::Base32ToByteStream(address.c_str(), address.length(), (uint8_t *)destination, 32) != 32)
+ {
+ LogPrint("Invalid Base32 address ", address);
+ SendReply("" + itoopieImage + "
Invalid Base32 address", 400);
+ return;
+ }
+ fullAddress = address + ".b32.i2p";
+ }
}
}
- auto leaseSet = i2p::data::netdb.FindLeaseSet (destination);
+ if (!leaseSet)
+ leaseSet = i2p::data::netdb.FindLeaseSet (destination);
if (!leaseSet || !leaseSet->HasNonExpiredLeases ())
{
i2p::data::netdb.Subscribe(destination);
@@ -495,6 +508,47 @@ namespace util
new HTTPConnection (m_NewSocket);
}
+// eepSite. TODO: move away
+
+ void HTTPConnection::EepAccept (i2p::stream::StreamingDestination * destination)
+ {
+ if (destination)
+ destination->SetAcceptor (std::bind (&HTTPConnection::HandleEepAccept, this, std::placeholders::_1));
+ }
+
+ void HTTPConnection::HandleEepAccept (i2p::stream::Stream * stream)
+ {
+ if (stream)
+ {
+ auto conn = new EepSiteDummyConnection (stream);
+ conn->AsyncStreamReceive ();
+ }
+ }
+
+ void EepSiteDummyConnection::AsyncStreamReceive ()
+ {
+ if (m_Stream)
+ m_Stream->AsyncReceive (boost::asio::buffer (m_StreamBuffer, 8192),
+ boost::bind (&EepSiteDummyConnection::HandleStreamReceive, this,
+ boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred),
+ 60); // 60 seconds timeout
+ }
+
+ void EepSiteDummyConnection::HandleStreamReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred)
+ {
+ if (ecode)
+ {
+ LogPrint ("eepSite error: ", ecode.message ());
+ DeleteStream (m_Stream);
+ }
+ else
+ {
+ std::string response ("HTTP/1.0 200 OK\r\n");
+ m_Stream->Send ((uint8_t *)response.c_str (), response.length (), 30);
+ }
+ delete this;
+ }
+
}
}
diff --git a/HTTPServer.h b/HTTPServer.h
index 39c61070..bef69bdf 100644
--- a/HTTPServer.h
+++ b/HTTPServer.h
@@ -59,6 +59,10 @@ namespace util
void FillContent (std::stringstream& s);
std::string ExtractAddress ();
+ // for eepsite
+ void EepAccept (i2p::stream::StreamingDestination * destination);
+ void HandleEepAccept (i2p::stream::Stream * stream);
+
protected:
boost::asio::ip::tcp::socket * m_Socket;
@@ -94,7 +98,7 @@ namespace util
void Run ();
void Accept ();
void HandleAccept(const boost::system::error_code& ecode);
-
+
private:
std::thread * m_Thread;
@@ -106,6 +110,24 @@ namespace util
protected:
virtual void CreateConnection(boost::asio::ip::tcp::socket * m_NewSocket);
};
+
+ // TODO: move away
+ class EepSiteDummyConnection
+ {
+ public:
+
+ EepSiteDummyConnection (i2p::stream::Stream * stream): m_Stream (stream) {};
+ void AsyncStreamReceive ();
+
+ private:
+
+ void HandleStreamReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred);
+
+ private:
+
+ i2p::stream::Stream * m_Stream;
+ char m_StreamBuffer[8192];
+ };
}
}
diff --git a/Streaming.cpp b/Streaming.cpp
index e4ce6d5e..c12c4f53 100644
--- a/Streaming.cpp
+++ b/Streaming.cpp
@@ -127,8 +127,9 @@ namespace stream
if (!m_RemoteLeaseSet)
{
i2p::data::Identity * identity = (i2p::data::Identity *)optionData;
+ LogPrint ("Incoming stream from ", identity->Hash ().ToBase64 ());
m_RemoteLeaseSet = i2p::data::netdb.FindLeaseSet (identity->Hash ());
- if (!m_RemoteLeaseSet)
+ if (!m_RemoteLeaseSet)
LogPrint ("LeaseSet ", identity->Hash ().ToBase64 (), " not found");
}
optionData += sizeof (i2p::data::Identity);
@@ -410,6 +411,8 @@ namespace stream
else // new incoming stream
{
auto incomingStream = CreateNewIncomingStream ();
+ if (m_Acceptor != nullptr)
+ m_Acceptor (incomingStream);
incomingStream->HandleNextPacket (packet);
}
}
@@ -438,6 +441,11 @@ namespace stream
}
I2NPMessage * StreamingDestination::GetLeaseSetMsg ()
+ {
+ return CreateDatabaseStoreMsg (GetLeaseSet ());
+ }
+
+ const i2p::data::LeaseSet * StreamingDestination::GetLeaseSet ()
{
if (!m_Pool) return nullptr;
if (!m_LeaseSet || m_LeaseSet->HasExpiredLeases ())
@@ -450,9 +458,9 @@ namespace stream
for (auto it: m_Streams)
it.second->SetLeaseSetUpdated ();
}
- return CreateDatabaseStoreMsg (m_LeaseSet);
+ return m_LeaseSet;
}
-
+
void StreamingDestination::Sign (const uint8_t * buf, int len, uint8_t * signature) const
{
CryptoPP::DSA::Signer signer (m_SigningPrivateKey);
@@ -524,15 +532,20 @@ namespace stream
if (!m_SharedLocalDestination) return nullptr;
return m_SharedLocalDestination->CreateNewOutgoingStream (remote);
}
-
- void StreamingDestinations::DeleteClientStream (Stream * stream)
- {
- if (m_SharedLocalDestination)
- m_SharedLocalDestination->DeleteStream (stream);
- else
- delete stream;
- }
+ void StreamingDestinations::DeleteStream (Stream * stream)
+ {
+ if (stream)
+ {
+ m_Service.post (
+ [=](void)
+ {
+ stream->GetLocalDestination ()->DeleteStream (stream);
+ }
+ );
+ }
+ }
+
void StreamingDestinations::HandleNextPacket (i2p::data::IdentHash destination, Packet * packet)
{
m_Service.post (boost::bind (&StreamingDestinations::PostNextPacket, this, destination, packet));
@@ -557,7 +570,7 @@ namespace stream
void DeleteStream (Stream * stream)
{
- destinations.DeleteClientStream (stream);
+ destinations.DeleteStream (stream);
}
void StartStreaming ()
@@ -569,6 +582,11 @@ namespace stream
{
destinations.Stop ();
}
+
+ StreamingDestination * GetSharedLocalDestination ()
+ {
+ return destinations.GetSharedLocalDestination ();
+ }
void HandleDataMessage (i2p::data::IdentHash destination, const uint8_t * buf, size_t len)
{
diff --git a/Streaming.h b/Streaming.h
index 39b15ced..a348c641 100644
--- a/Streaming.h
+++ b/Streaming.h
@@ -7,6 +7,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -78,6 +79,7 @@ namespace stream
const i2p::data::LeaseSet * GetRemoteLeaseSet () const { return m_RemoteLeaseSet; };
bool IsOpen () const { return m_IsOpen; };
bool IsEstablished () const { return m_SendStreamID; };
+ StreamingDestination * GetLocalDestination () { return m_LocalDestination; };
void HandleNextPacket (Packet * packet);
size_t Send (const uint8_t * buf, size_t len, int timeout); // timeout in seconds
@@ -127,10 +129,12 @@ namespace stream
const i2p::data::PrivateKeys& GetKeys () const { return m_Keys; };
I2NPMessage * GetLeaseSetMsg ();
+ const i2p::data::LeaseSet * GetLeaseSet ();
i2p::tunnel::TunnelPool * GetTunnelPool () const { return m_Pool; };
Stream * CreateNewOutgoingStream (const i2p::data::LeaseSet& remote);
- void DeleteStream (Stream * stream);
+ void DeleteStream (Stream * stream);
+ void SetAcceptor (const std::function& acceptor) { m_Acceptor = acceptor; };
void HandleNextPacket (Packet * packet);
// implements LocalDestination
@@ -156,6 +160,7 @@ namespace stream
i2p::data::LeaseSet * m_LeaseSet;
CryptoPP::DSA::PrivateKey m_SigningPrivateKey;
+ std::function m_Acceptor;
};
class StreamingDestinations
@@ -172,7 +177,8 @@ namespace stream
void HandleNextPacket (i2p::data::IdentHash destination, Packet * packet);
Stream * CreateClientStream (const i2p::data::LeaseSet& remote);
- void DeleteClientStream (Stream * stream);
+ void DeleteStream (Stream * stream);
+ StreamingDestination * GetSharedLocalDestination () const { return m_SharedLocalDestination; };
private:
@@ -195,6 +201,7 @@ namespace stream
void DeleteStream (Stream * stream);
void StartStreaming ();
void StopStreaming ();
+ StreamingDestination * GetSharedLocalDestination ();
// assuming data is I2CP message
void HandleDataMessage (i2p::data::IdentHash destination, const uint8_t * buf, size_t len);