Browse Source

I2CP configuration

pull/509/merge
orignal 9 years ago
parent
commit
025eec1782
  1. 26
      ClientContext.cpp
  2. 8
      Config.cpp
  3. 98
      I2CP.cpp
  4. 23
      I2CP.h

26
ClientContext.cpp

@ -114,6 +114,24 @@ namespace client
} }
} }
// I2CP
bool i2cp; i2p::config::GetOption("i2cp.enabled", i2cp);
if (i2cp)
{
std::string i2cpAddr; i2p::config::GetOption("i2cp.address", i2cpAddr);
uint16_t i2cpPort; i2p::config::GetOption("i2cp.port", i2cpPort);
LogPrint(eLogInfo, "Clients: starting I2CP at ", i2cpAddr, ":", i2cpPort);
try
{
m_I2CPServer = new I2CPServer (i2cpAddr, i2cpPort);
m_I2CPServer->Start ();
}
catch (std::exception& e)
{
LogPrint(eLogError, "Clients: Exception in I2CP: ", e.what());
}
}
m_AddressBook.StartResolvers (); m_AddressBook.StartResolvers ();
} }
@ -165,6 +183,14 @@ namespace client
m_BOBCommandChannel = nullptr; m_BOBCommandChannel = nullptr;
} }
if (m_I2CPServer)
{
LogPrint(eLogInfo, "Clients: stopping I2CP");
m_I2CPServer->Stop ();
delete m_I2CPServer;
m_I2CPServer = nullptr;
}
LogPrint(eLogInfo, "Clients: stopping AddressBook"); LogPrint(eLogInfo, "Clients: stopping AddressBook");
m_AddressBook.Stop (); m_AddressBook.Stop ();
for (auto it: m_Destinations) for (auto it: m_Destinations)

8
Config.cpp

@ -178,6 +178,13 @@ namespace config {
("bob.port", value<uint16_t>()->default_value(2827), "BOB listen port") ("bob.port", value<uint16_t>()->default_value(2827), "BOB listen port")
; ;
options_description i2cp("I2CP options");
bob.add_options()
("i2cp.enabled", value<bool>()->default_value(false), "Enable or disable I2CP")
("i2cp.address", value<std::string>()->default_value("127.0.0.1"), "I2CP listen address")
("i2cp.port", value<uint16_t>()->default_value(7654), "I2CP listen port")
;
options_description i2pcontrol("I2PControl options"); options_description i2pcontrol("I2PControl options");
i2pcontrol.add_options() i2pcontrol.add_options()
("i2pcontrol.enabled", value<bool>()->default_value(false), "Enable or disable I2P Control Protocol") ("i2pcontrol.enabled", value<bool>()->default_value(false), "Enable or disable I2P Control Protocol")
@ -207,6 +214,7 @@ namespace config {
.add(socksproxy) .add(socksproxy)
.add(sam) .add(sam)
.add(bob) .add(bob)
.add(i2cp)
.add(i2pcontrol) .add(i2pcontrol)
.add(precomputation) .add(precomputation)
; ;

98
I2CP.cpp

@ -61,9 +61,9 @@ 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_NextMessage (nullptr), m_NextMessageLen (0), m_NextMessageOffset (0), m_NextMessage (nullptr), m_NextMessageLen (0), m_NextMessageOffset (0)
m_SessionID (0)
{ {
RAND_bytes ((uint8_t *)&m_SessionID, 2);
ReadProtocolByte (); ReadProtocolByte ();
} }
@ -72,6 +72,10 @@ namespace client
delete[] m_NextMessage; delete[] m_NextMessage;
} }
void I2CPSession::Close ()
{
}
void I2CPSession::ReadProtocolByte () void I2CPSession::ReadProtocolByte ()
{ {
if (m_Socket) if (m_Socket)
@ -148,6 +152,12 @@ namespace client
void I2CPSession::Terminate () void I2CPSession::Terminate ()
{ {
if (m_Destination)
{
m_Destination->Stop ();
m_Destination = nullptr;
}
m_Owner.RemoveSession (GetSessionID ());
} }
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)
@ -212,7 +222,7 @@ namespace client
if (identity->Verify (buf, offset, buf + offset)) // signature if (identity->Verify (buf, offset, buf + offset)) // signature
{ {
m_Destination = std::make_shared<I2CPDestination>(*this, identity, false); m_Destination = std::make_shared<I2CPDestination>(*this, identity, false);
RAND_bytes ((uint8_t *)&m_SessionID, 2); m_Destination->Start ();
SendSessionStatusMessage (1); // created SendSessionStatusMessage (1); // created
} }
else else
@ -264,7 +274,9 @@ namespace client
LogPrint (eLogError, "I2CP: unexpected sessionID ", sessionID); LogPrint (eLogError, "I2CP: unexpected sessionID ", sessionID);
} }
I2CPServer::I2CPServer (const std::string& interface, int port) I2CPServer::I2CPServer (const std::string& interface, int port):
m_IsRunning (false), m_Thread (nullptr),
m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(interface), port))
{ {
memset (m_MessagesHandlers, 0, sizeof (m_MessagesHandlers)); memset (m_MessagesHandlers, 0, sizeof (m_MessagesHandlers));
m_MessagesHandlers[I2CP_GET_DATE_MESSAGE] = &I2CPSession::GetDateMessageHandler; m_MessagesHandlers[I2CP_GET_DATE_MESSAGE] = &I2CPSession::GetDateMessageHandler;
@ -272,6 +284,84 @@ namespace client
m_MessagesHandlers[I2CP_CREATE_LEASESET_MESSAGE] = &I2CPSession::CreateLeaseSetMessageHandler; m_MessagesHandlers[I2CP_CREATE_LEASESET_MESSAGE] = &I2CPSession::CreateLeaseSetMessageHandler;
m_MessagesHandlers[I2CP_SEND_MESSAGE_MESSAGE] = &I2CPSession::SendMessageMessageHandler; m_MessagesHandlers[I2CP_SEND_MESSAGE_MESSAGE] = &I2CPSession::SendMessageMessageHandler;
} }
I2CPServer::~I2CPServer ()
{
if (m_IsRunning)
Stop ();
}
void I2CPServer::Start ()
{
Accept ();
m_IsRunning = true;
m_Thread = new std::thread (std::bind (&I2CPServer::Run, this));
}
void I2CPServer::Stop ()
{
m_IsRunning = false;
m_Acceptor.cancel ();
for (auto it: m_Sessions)
it.second->Close ();
m_Sessions.clear ();
m_Service.stop ();
if (m_Thread)
{
m_Thread->join ();
delete m_Thread;
m_Thread = nullptr;
}
}
void I2CPServer::Run ()
{
while (m_IsRunning)
{
try
{
m_Service.run ();
}
catch (std::exception& ex)
{
LogPrint (eLogError, "I2CP: runtime exception: ", ex.what ());
}
}
}
void I2CPServer::Accept ()
{
auto newSocket = std::make_shared<boost::asio::ip::tcp::socket> (m_Service);
m_Acceptor.async_accept (*newSocket, std::bind (&I2CPServer::HandleAccept, this,
std::placeholders::_1, newSocket));
}
void I2CPServer::HandleAccept(const boost::system::error_code& ecode, std::shared_ptr<boost::asio::ip::tcp::socket> socket)
{
if (!ecode && socket)
{
boost::system::error_code ec;
auto ep = socket->remote_endpoint (ec);
if (!ec)
{
LogPrint (eLogDebug, "I2CP: new connection from ", ep);
auto session = std::make_shared<I2CPSession>(*this, socket);
m_Sessions[session->GetSessionID ()] = session;
}
else
LogPrint (eLogError, "I2CP: incoming connection error ", ec.message ());
}
else
LogPrint (eLogError, "I2CP: accept error: ", ecode.message ());
if (ecode != boost::asio::error::operation_aborted)
Accept ();
}
void I2CPServer::RemoveSession (uint16_t sessionID)
{
m_Sessions.erase (sessionID);
}
} }
} }

23
I2CP.h

@ -12,6 +12,8 @@
#include <inttypes.h> #include <inttypes.h>
#include <string> #include <string>
#include <memory> #include <memory>
#include <thread>
#include <map>
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include "Destination.h" #include "Destination.h"
@ -72,6 +74,7 @@ namespace client
~I2CPSession (); ~I2CPSession ();
uint16_t GetSessionID () const { return m_SessionID; }; uint16_t GetSessionID () const { return m_SessionID; };
void Close ();
void SendI2CPMessage (uint8_t type, const uint8_t * payload, size_t len); void SendI2CPMessage (uint8_t type, const uint8_t * payload, size_t len);
// message handlers // message handlers
@ -111,10 +114,30 @@ namespace client
public: public:
I2CPServer (const std::string& interface, int port); I2CPServer (const std::string& interface, int port);
~I2CPServer ();
void Start ();
void Stop ();
boost::asio::io_service& GetService () { return m_Service; };
void RemoveSession (uint16_t sessionID);
private:
void Run ();
void Accept ();
void HandleAccept(const boost::system::error_code& ecode, std::shared_ptr<boost::asio::ip::tcp::socket> socket);
private: private:
I2CPMessageHandler m_MessagesHandlers[256]; I2CPMessageHandler m_MessagesHandlers[256];
std::map<uint16_t, std::shared_ptr<I2CPSession> > m_Sessions;
bool m_IsRunning;
std::thread * m_Thread;
boost::asio::io_service m_Service;
boost::asio::ip::tcp::acceptor m_Acceptor;
public: public:

Loading…
Cancel
Save