mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-07-01 18:24:36 +02:00
Reformat code
This commit is contained in:
parent
3ddb370718
commit
55534ea002
140 changed files with 46068 additions and 48277 deletions
File diff suppressed because it is too large
Load diff
|
@ -23,149 +23,189 @@
|
|||
#include "Destination.h"
|
||||
#include "LeaseSet.h"
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
namespace client
|
||||
{
|
||||
const int INITIAL_SUBSCRIPTION_UPDATE_TIMEOUT = 3; // in minutes
|
||||
const int INITIAL_SUBSCRIPTION_RETRY_TIMEOUT = 1; // in minutes
|
||||
const int CONTINIOUS_SUBSCRIPTION_UPDATE_TIMEOUT = 720; // in minutes (12 hours)
|
||||
const int CONTINIOUS_SUBSCRIPTION_RETRY_TIMEOUT = 5; // in minutes
|
||||
const int CONTINIOUS_SUBSCRIPTION_MAX_NUM_RETRIES = 10; // then update timeout
|
||||
const int SUBSCRIPTION_REQUEST_TIMEOUT = 120; //in second
|
||||
namespace i2p {
|
||||
namespace client {
|
||||
const int INITIAL_SUBSCRIPTION_UPDATE_TIMEOUT = 3; // in minutes
|
||||
const int INITIAL_SUBSCRIPTION_RETRY_TIMEOUT = 1; // in minutes
|
||||
const int CONTINIOUS_SUBSCRIPTION_UPDATE_TIMEOUT = 720; // in minutes (12 hours)
|
||||
const int CONTINIOUS_SUBSCRIPTION_RETRY_TIMEOUT = 5; // in minutes
|
||||
const int CONTINIOUS_SUBSCRIPTION_MAX_NUM_RETRIES = 10; // then update timeout
|
||||
const int SUBSCRIPTION_REQUEST_TIMEOUT = 120; //in second
|
||||
|
||||
const uint16_t ADDRESS_RESOLVER_DATAGRAM_PORT = 53;
|
||||
const uint16_t ADDRESS_RESPONSE_DATAGRAM_PORT = 54;
|
||||
const uint16_t ADDRESS_RESOLVER_DATAGRAM_PORT = 53;
|
||||
const uint16_t ADDRESS_RESPONSE_DATAGRAM_PORT = 54;
|
||||
|
||||
const size_t B33_ADDRESS_THRESHOLD = 52; // characters
|
||||
const size_t B33_ADDRESS_THRESHOLD = 52; // characters
|
||||
|
||||
struct Address
|
||||
{
|
||||
enum { eAddressIndentHash, eAddressBlindedPublicKey, eAddressInvalid } addressType;
|
||||
i2p::data::IdentHash identHash;
|
||||
std::shared_ptr<i2p::data::BlindedPublicKey> blindedPublicKey;
|
||||
struct Address {
|
||||
enum {
|
||||
eAddressIndentHash, eAddressBlindedPublicKey, eAddressInvalid
|
||||
} addressType;
|
||||
i2p::data::IdentHash identHash;
|
||||
std::shared_ptr <i2p::data::BlindedPublicKey> blindedPublicKey;
|
||||
|
||||
Address (const std::string& b32);
|
||||
Address (const i2p::data::IdentHash& hash);
|
||||
bool IsIdentHash () const { return addressType == eAddressIndentHash; };
|
||||
bool IsValid () const { return addressType != eAddressInvalid; };
|
||||
};
|
||||
Address(const std::string &b32);
|
||||
|
||||
inline std::string GetB32Address(const i2p::data::IdentHash& ident) { return ident.ToBase32().append(".b32.i2p"); }
|
||||
Address(const i2p::data::IdentHash &hash);
|
||||
|
||||
class AddressBookStorage // interface for storage
|
||||
{
|
||||
public:
|
||||
bool IsIdentHash() const { return addressType == eAddressIndentHash; };
|
||||
|
||||
virtual ~AddressBookStorage () {};
|
||||
virtual std::shared_ptr<const i2p::data::IdentityEx> GetAddress (const i2p::data::IdentHash& ident) const = 0;
|
||||
virtual void AddAddress (std::shared_ptr<const i2p::data::IdentityEx> address) = 0;
|
||||
virtual void RemoveAddress (const i2p::data::IdentHash& ident) = 0;
|
||||
bool IsValid() const { return addressType != eAddressInvalid; };
|
||||
};
|
||||
|
||||
virtual bool Init () = 0;
|
||||
virtual int Load (std::map<std::string, std::shared_ptr<Address> >& addresses) = 0;
|
||||
virtual int LoadLocal (std::map<std::string, std::shared_ptr<Address> >& addresses) = 0;
|
||||
virtual int Save (const std::map<std::string, std::shared_ptr<Address> >& addresses) = 0;
|
||||
inline std::string GetB32Address(const i2p::data::IdentHash &ident) {
|
||||
return ident.ToBase32().append(".b32.i2p");
|
||||
}
|
||||
|
||||
virtual void SaveEtag (const i2p::data::IdentHash& subscription, const std::string& etag, const std::string& lastModified) = 0;
|
||||
virtual bool GetEtag (const i2p::data::IdentHash& subscription, std::string& etag, std::string& lastModified) = 0;
|
||||
virtual void ResetEtags () = 0;
|
||||
};
|
||||
class AddressBookStorage // interface for storage
|
||||
{
|
||||
public:
|
||||
|
||||
class AddressBookSubscription;
|
||||
class AddressResolver;
|
||||
class AddressBook
|
||||
{
|
||||
public:
|
||||
virtual ~AddressBookStorage() {};
|
||||
|
||||
AddressBook ();
|
||||
~AddressBook ();
|
||||
void Start ();
|
||||
void StartResolvers ();
|
||||
void Stop ();
|
||||
std::shared_ptr<const Address> GetAddress (const std::string& address);
|
||||
std::shared_ptr<const i2p::data::IdentityEx> GetFullAddress (const std::string& address);
|
||||
std::shared_ptr<const Address> FindAddress (const std::string& address);
|
||||
void LookupAddress (const std::string& address);
|
||||
void InsertAddress (const std::string& address, const std::string& jump); // for jump links
|
||||
void InsertFullAddress (std::shared_ptr<const i2p::data::IdentityEx> address);
|
||||
virtual std::shared_ptr<const i2p::data::IdentityEx>
|
||||
GetAddress(const i2p::data::IdentHash &ident) const = 0;
|
||||
|
||||
bool LoadHostsFromStream (std::istream& f, bool is_update);
|
||||
void DownloadComplete (bool success, const i2p::data::IdentHash& subscription, const std::string& etag, const std::string& lastModified);
|
||||
//This method returns the ".b32.i2p" address
|
||||
std::string ToAddress(const i2p::data::IdentHash& ident) { return GetB32Address(ident); }
|
||||
std::string ToAddress(std::shared_ptr<const i2p::data::IdentityEx> ident) { return ToAddress(ident->GetIdentHash ()); }
|
||||
virtual void AddAddress(std::shared_ptr<const i2p::data::IdentityEx> address) = 0;
|
||||
|
||||
bool GetEtag (const i2p::data::IdentHash& subscription, std::string& etag, std::string& lastModified);
|
||||
virtual void RemoveAddress(const i2p::data::IdentHash &ident) = 0;
|
||||
|
||||
private:
|
||||
virtual bool Init() = 0;
|
||||
|
||||
void StartSubscriptions ();
|
||||
void StopSubscriptions ();
|
||||
virtual int Load(std::map <std::string, std::shared_ptr<Address>> &addresses) = 0;
|
||||
|
||||
void LoadHosts ();
|
||||
void LoadSubscriptions ();
|
||||
void LoadLocal ();
|
||||
virtual int LoadLocal(std::map <std::string, std::shared_ptr<Address>> &addresses) = 0;
|
||||
|
||||
void HandleSubscriptionsUpdateTimer (const boost::system::error_code& ecode);
|
||||
virtual int Save(const std::map <std::string, std::shared_ptr<Address>> &addresses) = 0;
|
||||
|
||||
void StartLookups ();
|
||||
void StopLookups ();
|
||||
void HandleLookupResponse (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
|
||||
virtual void SaveEtag(const i2p::data::IdentHash &subscription, const std::string &etag,
|
||||
const std::string &lastModified) = 0;
|
||||
|
||||
private:
|
||||
virtual bool
|
||||
GetEtag(const i2p::data::IdentHash &subscription, std::string &etag, std::string &lastModified) = 0;
|
||||
|
||||
std::mutex m_AddressBookMutex;
|
||||
std::map<std::string, std::shared_ptr<Address> > m_Addresses;
|
||||
std::map<i2p::data::IdentHash, std::shared_ptr<AddressResolver> > m_Resolvers; // local destination->resolver
|
||||
std::mutex m_LookupsMutex;
|
||||
std::map<uint32_t, std::string> m_Lookups; // nonce -> address
|
||||
AddressBookStorage * m_Storage;
|
||||
volatile bool m_IsLoaded, m_IsDownloading;
|
||||
int m_NumRetries;
|
||||
std::vector<std::shared_ptr<AddressBookSubscription> > m_Subscriptions;
|
||||
std::shared_ptr<AddressBookSubscription> m_DefaultSubscription; // in case if we don't know any addresses yet
|
||||
boost::asio::deadline_timer * m_SubscriptionsUpdateTimer;
|
||||
bool m_IsEnabled;
|
||||
};
|
||||
virtual void ResetEtags() = 0;
|
||||
};
|
||||
|
||||
class AddressBookSubscription
|
||||
{
|
||||
public:
|
||||
class AddressBookSubscription;
|
||||
|
||||
AddressBookSubscription (AddressBook& book, const std::string& link);
|
||||
void CheckUpdates ();
|
||||
class AddressResolver;
|
||||
|
||||
private:
|
||||
class AddressBook {
|
||||
public:
|
||||
|
||||
bool MakeRequest ();
|
||||
AddressBook();
|
||||
|
||||
private:
|
||||
~AddressBook();
|
||||
|
||||
AddressBook& m_Book;
|
||||
std::string m_Link, m_Etag, m_LastModified;
|
||||
i2p::data::IdentHash m_Ident;
|
||||
// m_Etag must be surrounded by ""
|
||||
};
|
||||
void Start();
|
||||
|
||||
class AddressResolver
|
||||
{
|
||||
public:
|
||||
void StartResolvers();
|
||||
|
||||
AddressResolver (std::shared_ptr<ClientDestination> destination);
|
||||
~AddressResolver ();
|
||||
void AddAddress (const std::string& name, const i2p::data::IdentHash& ident);
|
||||
void Stop();
|
||||
|
||||
private:
|
||||
std::shared_ptr<const Address> GetAddress(const std::string &address);
|
||||
|
||||
void HandleRequest (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
|
||||
std::shared_ptr<const i2p::data::IdentityEx> GetFullAddress(const std::string &address);
|
||||
|
||||
private:
|
||||
std::shared_ptr<const Address> FindAddress(const std::string &address);
|
||||
|
||||
std::shared_ptr<ClientDestination> m_LocalDestination;
|
||||
std::map<std::string, i2p::data::IdentHash> m_LocalAddresses;
|
||||
};
|
||||
}
|
||||
void LookupAddress(const std::string &address);
|
||||
|
||||
void InsertAddress(const std::string &address, const std::string &jump); // for jump links
|
||||
void InsertFullAddress(std::shared_ptr<const i2p::data::IdentityEx> address);
|
||||
|
||||
bool LoadHostsFromStream(std::istream &f, bool is_update);
|
||||
|
||||
void DownloadComplete(bool success, const i2p::data::IdentHash &subscription, const std::string &etag,
|
||||
const std::string &lastModified);
|
||||
|
||||
//This method returns the ".b32.i2p" address
|
||||
std::string ToAddress(const i2p::data::IdentHash &ident) { return GetB32Address(ident); }
|
||||
|
||||
std::string ToAddress(std::shared_ptr<const i2p::data::IdentityEx> ident) {
|
||||
return ToAddress(ident->GetIdentHash());
|
||||
}
|
||||
|
||||
bool GetEtag(const i2p::data::IdentHash &subscription, std::string &etag, std::string &lastModified);
|
||||
|
||||
private:
|
||||
|
||||
void StartSubscriptions();
|
||||
|
||||
void StopSubscriptions();
|
||||
|
||||
void LoadHosts();
|
||||
|
||||
void LoadSubscriptions();
|
||||
|
||||
void LoadLocal();
|
||||
|
||||
void HandleSubscriptionsUpdateTimer(const boost::system::error_code &ecode);
|
||||
|
||||
void StartLookups();
|
||||
|
||||
void StopLookups();
|
||||
|
||||
void HandleLookupResponse(const i2p::data::IdentityEx &from, uint16_t fromPort, uint16_t toPort,
|
||||
const uint8_t *buf, size_t len);
|
||||
|
||||
private:
|
||||
|
||||
std::mutex m_AddressBookMutex;
|
||||
std::map <std::string, std::shared_ptr<Address>> m_Addresses;
|
||||
std::map <i2p::data::IdentHash, std::shared_ptr<AddressResolver>> m_Resolvers; // local destination->resolver
|
||||
std::mutex m_LookupsMutex;
|
||||
std::map <uint32_t, std::string> m_Lookups; // nonce -> address
|
||||
AddressBookStorage *m_Storage;
|
||||
volatile bool m_IsLoaded, m_IsDownloading;
|
||||
int m_NumRetries;
|
||||
std::vector <std::shared_ptr<AddressBookSubscription>> m_Subscriptions;
|
||||
std::shared_ptr <AddressBookSubscription> m_DefaultSubscription; // in case if we don't know any addresses yet
|
||||
boost::asio::deadline_timer *m_SubscriptionsUpdateTimer;
|
||||
bool m_IsEnabled;
|
||||
};
|
||||
|
||||
class AddressBookSubscription {
|
||||
public:
|
||||
|
||||
AddressBookSubscription(AddressBook &book, const std::string &link);
|
||||
|
||||
void CheckUpdates();
|
||||
|
||||
private:
|
||||
|
||||
bool MakeRequest();
|
||||
|
||||
private:
|
||||
|
||||
AddressBook &m_Book;
|
||||
std::string m_Link, m_Etag, m_LastModified;
|
||||
i2p::data::IdentHash m_Ident;
|
||||
// m_Etag must be surrounded by ""
|
||||
};
|
||||
|
||||
class AddressResolver {
|
||||
public:
|
||||
|
||||
AddressResolver(std::shared_ptr <ClientDestination> destination);
|
||||
|
||||
~AddressResolver();
|
||||
|
||||
void AddAddress(const std::string &name, const i2p::data::IdentHash &ident);
|
||||
|
||||
private:
|
||||
|
||||
void
|
||||
HandleRequest(const i2p::data::IdentityEx &from, uint16_t fromPort, uint16_t toPort, const uint8_t *buf,
|
||||
size_t len);
|
||||
|
||||
private:
|
||||
|
||||
std::shared_ptr <ClientDestination> m_LocalDestination;
|
||||
std::map <std::string, i2p::data::IdentHash> m_LocalAddresses;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -21,263 +21,326 @@
|
|||
#include "Identity.h"
|
||||
#include "LeaseSet.h"
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
namespace client
|
||||
{
|
||||
const size_t BOB_COMMAND_BUFFER_SIZE = 1024;
|
||||
const char BOB_COMMAND_ZAP[] = "zap";
|
||||
const char BOB_COMMAND_QUIT[] = "quit";
|
||||
const char BOB_COMMAND_START[] = "start";
|
||||
const char BOB_COMMAND_STOP[] = "stop";
|
||||
const char BOB_COMMAND_SETNICK[] = "setnick";
|
||||
const char BOB_COMMAND_GETNICK[] = "getnick";
|
||||
const char BOB_COMMAND_NEWKEYS[] = "newkeys";
|
||||
const char BOB_COMMAND_GETKEYS[] = "getkeys";
|
||||
const char BOB_COMMAND_SETKEYS[] = "setkeys";
|
||||
const char BOB_COMMAND_GETDEST[] = "getdest";
|
||||
const char BOB_COMMAND_OUTHOST[] = "outhost";
|
||||
const char BOB_COMMAND_OUTPORT[] = "outport";
|
||||
const char BOB_COMMAND_INHOST[] = "inhost";
|
||||
const char BOB_COMMAND_INPORT[] = "inport";
|
||||
const char BOB_COMMAND_QUIET[] = "quiet";
|
||||
const char BOB_COMMAND_LOOKUP[] = "lookup";
|
||||
const char BOB_COMMAND_LOOKUP_LOCAL[] = "lookuplocal";
|
||||
const char BOB_COMMAND_CLEAR[] = "clear";
|
||||
const char BOB_COMMAND_LIST[] = "list";
|
||||
const char BOB_COMMAND_OPTION[] = "option";
|
||||
const char BOB_COMMAND_STATUS[] = "status";
|
||||
const char BOB_COMMAND_HELP[] = "help";
|
||||
namespace i2p {
|
||||
namespace client {
|
||||
const size_t BOB_COMMAND_BUFFER_SIZE = 1024;
|
||||
const char BOB_COMMAND_ZAP[] = "zap";
|
||||
const char BOB_COMMAND_QUIT[] = "quit";
|
||||
const char BOB_COMMAND_START[] = "start";
|
||||
const char BOB_COMMAND_STOP[] = "stop";
|
||||
const char BOB_COMMAND_SETNICK[] = "setnick";
|
||||
const char BOB_COMMAND_GETNICK[] = "getnick";
|
||||
const char BOB_COMMAND_NEWKEYS[] = "newkeys";
|
||||
const char BOB_COMMAND_GETKEYS[] = "getkeys";
|
||||
const char BOB_COMMAND_SETKEYS[] = "setkeys";
|
||||
const char BOB_COMMAND_GETDEST[] = "getdest";
|
||||
const char BOB_COMMAND_OUTHOST[] = "outhost";
|
||||
const char BOB_COMMAND_OUTPORT[] = "outport";
|
||||
const char BOB_COMMAND_INHOST[] = "inhost";
|
||||
const char BOB_COMMAND_INPORT[] = "inport";
|
||||
const char BOB_COMMAND_QUIET[] = "quiet";
|
||||
const char BOB_COMMAND_LOOKUP[] = "lookup";
|
||||
const char BOB_COMMAND_LOOKUP_LOCAL[] = "lookuplocal";
|
||||
const char BOB_COMMAND_CLEAR[] = "clear";
|
||||
const char BOB_COMMAND_LIST[] = "list";
|
||||
const char BOB_COMMAND_OPTION[] = "option";
|
||||
const char BOB_COMMAND_STATUS[] = "status";
|
||||
const char BOB_COMMAND_HELP[] = "help";
|
||||
|
||||
const char BOB_HELP_ZAP[] = "zap - Shuts down BOB.";
|
||||
const char BOB_HELP_QUIT[] = "quit - Quits this session with BOB.";
|
||||
const char BOB_HELP_START[] = "start - Starts the current nicknamed tunnel.";
|
||||
const char BOB_HELP_STOP[] = "stop - Stops the current nicknamed tunnel.";
|
||||
const char BOB_HELP_SETNICK[] = "setnick <NICKNAME> - Creates a new nickname.";
|
||||
const char BOB_HELP_GETNICK[] = "getnick <TUNNELNAME> - Sets the nickname from the database.";
|
||||
const char BOB_HELP_NEWKEYS[] = "newkeys - Generate a new keypair for the current nickname.";
|
||||
const char BOB_HELP_GETKEYS[] = "getkeys - Return the keypair for the current nickname.";
|
||||
const char BOB_HELP_SETKEYS[] = "setkeys <BASE64_KEYPAIR> - Sets the keypair for the current nickname.";
|
||||
const char BOB_HELP_GETDEST[] = "getdest - Return the destination for the current nickname.";
|
||||
const char BOB_HELP_OUTHOST[] = "outhost <HOSTNAME|IP> - Set the outhound hostname or IP.";
|
||||
const char BOB_HELP_OUTPORT[] = "outport <PORT_NUMBER> - Set the outbound port that nickname contacts.";
|
||||
const char BOB_HELP_INHOST[] = "inhost <HOSTNAME|IP> - Set the inbound hostname or IP.";
|
||||
const char BOB_HELP_INPORT[] = "inport <PORT_NUMBER> - Set the inbound port number nickname listens on.";
|
||||
const char BOB_HELP_QUIET[] = "quiet <True|False> - Whether to send the incoming destination.";
|
||||
const char BOB_HELP_LOOKUP[] = "lookup <I2P_HOSTNAME> - Look up an I2P hostname.";
|
||||
const char BOB_HELP_CLEAR[] = "clear - Clear the current nickname out of the list.";
|
||||
const char BOB_HELP_LIST[] = "list - List all tunnels.";
|
||||
const char BOB_HELP_OPTION[] = "option <KEY>=<VALUE> - Set an option. NOTE: Don't use any spaces.";
|
||||
const char BOB_HELP_STATUS[] = "status <NICKNAME> - Display status of a nicknamed tunnel.";
|
||||
const char BOB_HELP_HELP [] = "help <COMMAND> - Get help on a command.";
|
||||
const char BOB_HELP_ZAP[] = "zap - Shuts down BOB.";
|
||||
const char BOB_HELP_QUIT[] = "quit - Quits this session with BOB.";
|
||||
const char BOB_HELP_START[] = "start - Starts the current nicknamed tunnel.";
|
||||
const char BOB_HELP_STOP[] = "stop - Stops the current nicknamed tunnel.";
|
||||
const char BOB_HELP_SETNICK[] = "setnick <NICKNAME> - Creates a new nickname.";
|
||||
const char BOB_HELP_GETNICK[] = "getnick <TUNNELNAME> - Sets the nickname from the database.";
|
||||
const char BOB_HELP_NEWKEYS[] = "newkeys - Generate a new keypair for the current nickname.";
|
||||
const char BOB_HELP_GETKEYS[] = "getkeys - Return the keypair for the current nickname.";
|
||||
const char BOB_HELP_SETKEYS[] = "setkeys <BASE64_KEYPAIR> - Sets the keypair for the current nickname.";
|
||||
const char BOB_HELP_GETDEST[] = "getdest - Return the destination for the current nickname.";
|
||||
const char BOB_HELP_OUTHOST[] = "outhost <HOSTNAME|IP> - Set the outhound hostname or IP.";
|
||||
const char BOB_HELP_OUTPORT[] = "outport <PORT_NUMBER> - Set the outbound port that nickname contacts.";
|
||||
const char BOB_HELP_INHOST[] = "inhost <HOSTNAME|IP> - Set the inbound hostname or IP.";
|
||||
const char BOB_HELP_INPORT[] = "inport <PORT_NUMBER> - Set the inbound port number nickname listens on.";
|
||||
const char BOB_HELP_QUIET[] = "quiet <True|False> - Whether to send the incoming destination.";
|
||||
const char BOB_HELP_LOOKUP[] = "lookup <I2P_HOSTNAME> - Look up an I2P hostname.";
|
||||
const char BOB_HELP_CLEAR[] = "clear - Clear the current nickname out of the list.";
|
||||
const char BOB_HELP_LIST[] = "list - List all tunnels.";
|
||||
const char BOB_HELP_OPTION[] = "option <KEY>=<VALUE> - Set an option. NOTE: Don't use any spaces.";
|
||||
const char BOB_HELP_STATUS[] = "status <NICKNAME> - Display status of a nicknamed tunnel.";
|
||||
const char BOB_HELP_HELP[] = "help <COMMAND> - Get help on a command.";
|
||||
|
||||
class BOBI2PTunnel: public I2PService
|
||||
{
|
||||
public:
|
||||
class BOBI2PTunnel : public I2PService {
|
||||
public:
|
||||
|
||||
BOBI2PTunnel (std::shared_ptr<ClientDestination> localDestination):
|
||||
I2PService (localDestination) {};
|
||||
BOBI2PTunnel(std::shared_ptr <ClientDestination> localDestination) :
|
||||
I2PService(localDestination) {};
|
||||
|
||||
virtual void Start () {};
|
||||
virtual void Stop () {};
|
||||
};
|
||||
virtual void Start() {};
|
||||
|
||||
class BOBI2PInboundTunnel: public BOBI2PTunnel
|
||||
{
|
||||
struct AddressReceiver
|
||||
{
|
||||
std::shared_ptr<boost::asio::ip::tcp::socket> socket;
|
||||
char buffer[BOB_COMMAND_BUFFER_SIZE + 1]; // for destination base64 address
|
||||
uint8_t * data; // pointer to buffer
|
||||
size_t dataLen, bufferOffset;
|
||||
virtual void Stop() {};
|
||||
};
|
||||
|
||||
AddressReceiver (): data (nullptr), dataLen (0), bufferOffset (0) {};
|
||||
};
|
||||
class BOBI2PInboundTunnel : public BOBI2PTunnel {
|
||||
struct AddressReceiver {
|
||||
std::shared_ptr <boost::asio::ip::tcp::socket> socket;
|
||||
char buffer[BOB_COMMAND_BUFFER_SIZE + 1]; // for destination base64 address
|
||||
uint8_t *data; // pointer to buffer
|
||||
size_t dataLen, bufferOffset;
|
||||
|
||||
public:
|
||||
AddressReceiver() : data(nullptr), dataLen(0), bufferOffset(0) {};
|
||||
};
|
||||
|
||||
BOBI2PInboundTunnel (const boost::asio::ip::tcp::endpoint& ep, std::shared_ptr<ClientDestination> localDestination);
|
||||
~BOBI2PInboundTunnel ();
|
||||
public:
|
||||
|
||||
void Start ();
|
||||
void Stop ();
|
||||
BOBI2PInboundTunnel(const boost::asio::ip::tcp::endpoint &ep,
|
||||
std::shared_ptr <ClientDestination> localDestination);
|
||||
|
||||
private:
|
||||
~BOBI2PInboundTunnel();
|
||||
|
||||
void Accept ();
|
||||
void HandleAccept (const boost::system::error_code& ecode, std::shared_ptr<AddressReceiver> receiver);
|
||||
void Start();
|
||||
|
||||
void ReceiveAddress (std::shared_ptr<AddressReceiver> receiver);
|
||||
void HandleReceivedAddress (const boost::system::error_code& ecode, std::size_t bytes_transferred,
|
||||
std::shared_ptr<AddressReceiver> receiver);
|
||||
void Stop();
|
||||
|
||||
void HandleDestinationRequestComplete (std::shared_ptr<i2p::data::LeaseSet> leaseSet, std::shared_ptr<AddressReceiver> receiver);
|
||||
private:
|
||||
|
||||
void CreateConnection (std::shared_ptr<AddressReceiver> receiver, std::shared_ptr<const i2p::data::LeaseSet> leaseSet);
|
||||
void Accept();
|
||||
|
||||
private:
|
||||
void HandleAccept(const boost::system::error_code &ecode, std::shared_ptr <AddressReceiver> receiver);
|
||||
|
||||
boost::asio::ip::tcp::acceptor m_Acceptor;
|
||||
};
|
||||
void ReceiveAddress(std::shared_ptr <AddressReceiver> receiver);
|
||||
|
||||
class BOBI2POutboundTunnel: public BOBI2PTunnel
|
||||
{
|
||||
public:
|
||||
void HandleReceivedAddress(const boost::system::error_code &ecode, std::size_t bytes_transferred,
|
||||
std::shared_ptr <AddressReceiver> receiver);
|
||||
|
||||
BOBI2POutboundTunnel (const std::string& outhost, int port, std::shared_ptr<ClientDestination> localDestination, bool quiet);
|
||||
void HandleDestinationRequestComplete(std::shared_ptr <i2p::data::LeaseSet> leaseSet,
|
||||
std::shared_ptr <AddressReceiver> receiver);
|
||||
|
||||
void Start ();
|
||||
void Stop ();
|
||||
void CreateConnection(std::shared_ptr <AddressReceiver> receiver,
|
||||
std::shared_ptr<const i2p::data::LeaseSet> leaseSet);
|
||||
|
||||
void SetQuiet () { m_IsQuiet = true; };
|
||||
private:
|
||||
|
||||
private:
|
||||
boost::asio::ip::tcp::acceptor m_Acceptor;
|
||||
};
|
||||
|
||||
void Accept ();
|
||||
void HandleAccept (std::shared_ptr<i2p::stream::Stream> stream);
|
||||
class BOBI2POutboundTunnel : public BOBI2PTunnel {
|
||||
public:
|
||||
|
||||
private:
|
||||
BOBI2POutboundTunnel(const std::string &outhost, int port,
|
||||
std::shared_ptr <ClientDestination> localDestination, bool quiet);
|
||||
|
||||
boost::asio::ip::tcp::endpoint m_Endpoint;
|
||||
bool m_IsQuiet;
|
||||
};
|
||||
void Start();
|
||||
|
||||
void Stop();
|
||||
|
||||
void SetQuiet() { m_IsQuiet = true; };
|
||||
|
||||
private:
|
||||
|
||||
void Accept();
|
||||
|
||||
void HandleAccept(std::shared_ptr <i2p::stream::Stream> stream);
|
||||
|
||||
private:
|
||||
|
||||
boost::asio::ip::tcp::endpoint m_Endpoint;
|
||||
bool m_IsQuiet;
|
||||
};
|
||||
|
||||
|
||||
class BOBDestination
|
||||
{
|
||||
public:
|
||||
class BOBDestination {
|
||||
public:
|
||||
|
||||
BOBDestination (std::shared_ptr<ClientDestination> localDestination,
|
||||
const std::string &nickname, const std::string &inhost, const std::string &outhost,
|
||||
const int inport, const int outport, const bool quiet);
|
||||
~BOBDestination ();
|
||||
BOBDestination(std::shared_ptr <ClientDestination> localDestination,
|
||||
const std::string &nickname, const std::string &inhost, const std::string &outhost,
|
||||
const int inport, const int outport, const bool quiet);
|
||||
|
||||
void Start ();
|
||||
void Stop ();
|
||||
void StopTunnels ();
|
||||
void CreateInboundTunnel (int port, const std::string& inhost);
|
||||
void CreateOutboundTunnel (const std::string& outhost, int port, bool quiet);
|
||||
const std::string& GetNickname() const { return m_Nickname; }
|
||||
const std::string& GetInHost() const { return m_InHost; }
|
||||
const std::string& GetOutHost() const { return m_OutHost; }
|
||||
int GetInPort() const { return m_InPort; }
|
||||
int GetOutPort() const { return m_OutPort; }
|
||||
bool GetQuiet() const { return m_Quiet; }
|
||||
bool IsRunning() const { return m_IsRunning; }
|
||||
const i2p::data::PrivateKeys& GetKeys () const { return m_LocalDestination->GetPrivateKeys (); };
|
||||
std::shared_ptr<ClientDestination> GetLocalDestination () const { return m_LocalDestination; };
|
||||
~BOBDestination();
|
||||
|
||||
private:
|
||||
void Start();
|
||||
|
||||
std::shared_ptr<ClientDestination> m_LocalDestination;
|
||||
BOBI2POutboundTunnel * m_OutboundTunnel;
|
||||
BOBI2PInboundTunnel * m_InboundTunnel;
|
||||
void Stop();
|
||||
|
||||
std::string m_Nickname;
|
||||
std::string m_InHost, m_OutHost;
|
||||
int m_InPort, m_OutPort;
|
||||
bool m_Quiet;
|
||||
bool m_IsRunning;
|
||||
};
|
||||
void StopTunnels();
|
||||
|
||||
class BOBCommandChannel;
|
||||
class BOBCommandSession: public std::enable_shared_from_this<BOBCommandSession>
|
||||
{
|
||||
public:
|
||||
void CreateInboundTunnel(int port, const std::string &inhost);
|
||||
|
||||
BOBCommandSession (BOBCommandChannel& owner);
|
||||
~BOBCommandSession ();
|
||||
void Terminate ();
|
||||
void CreateOutboundTunnel(const std::string &outhost, int port, bool quiet);
|
||||
|
||||
boost::asio::ip::tcp::socket& GetSocket () { return m_Socket; };
|
||||
void SendVersion ();
|
||||
const std::string &GetNickname() const { return m_Nickname; }
|
||||
|
||||
// command handlers
|
||||
void ZapCommandHandler (const char * operand, size_t len);
|
||||
void QuitCommandHandler (const char * operand, size_t len);
|
||||
void StartCommandHandler (const char * operand, size_t len);
|
||||
void StopCommandHandler (const char * operand, size_t len);
|
||||
void SetNickCommandHandler (const char * operand, size_t len);
|
||||
void GetNickCommandHandler (const char * operand, size_t len);
|
||||
void NewkeysCommandHandler (const char * operand, size_t len);
|
||||
void SetkeysCommandHandler (const char * operand, size_t len);
|
||||
void GetkeysCommandHandler (const char * operand, size_t len);
|
||||
void GetdestCommandHandler (const char * operand, size_t len);
|
||||
void OuthostCommandHandler (const char * operand, size_t len);
|
||||
void OutportCommandHandler (const char * operand, size_t len);
|
||||
void InhostCommandHandler (const char * operand, size_t len);
|
||||
void InportCommandHandler (const char * operand, size_t len);
|
||||
void QuietCommandHandler (const char * operand, size_t len);
|
||||
void LookupCommandHandler (const char * operand, size_t len);
|
||||
void LookupLocalCommandHandler (const char * operand, size_t len);
|
||||
void ClearCommandHandler (const char * operand, size_t len);
|
||||
void ListCommandHandler (const char * operand, size_t len);
|
||||
void OptionCommandHandler (const char * operand, size_t len);
|
||||
void StatusCommandHandler (const char * operand, size_t len);
|
||||
void HelpCommandHandler (const char * operand, size_t len);
|
||||
const std::string &GetInHost() const { return m_InHost; }
|
||||
|
||||
private:
|
||||
const std::string &GetOutHost() const { return m_OutHost; }
|
||||
|
||||
void Receive ();
|
||||
void HandleReceivedLine(const boost::system::error_code& ecode, std::size_t bytes_transferred);
|
||||
void HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred);
|
||||
int GetInPort() const { return m_InPort; }
|
||||
|
||||
void Send ();
|
||||
void HandleSent (const boost::system::error_code& ecode, std::size_t bytes_transferred);
|
||||
void SendReplyOK (const char * msg = nullptr);
|
||||
void SendReplyError (const char * msg);
|
||||
void SendRaw (const char * data);
|
||||
int GetOutPort() const { return m_OutPort; }
|
||||
|
||||
void BuildStatusLine(bool currentTunnel, BOBDestination *destination, std::string &out);
|
||||
bool GetQuiet() const { return m_Quiet; }
|
||||
|
||||
private:
|
||||
bool IsRunning() const { return m_IsRunning; }
|
||||
|
||||
BOBCommandChannel& m_Owner;
|
||||
boost::asio::ip::tcp::socket m_Socket;
|
||||
boost::asio::streambuf m_ReceiveBuffer, m_SendBuffer;
|
||||
bool m_IsOpen, m_IsQuiet, m_IsActive;
|
||||
std::string m_Nickname, m_InHost, m_OutHost;
|
||||
int m_InPort, m_OutPort;
|
||||
i2p::data::PrivateKeys m_Keys;
|
||||
std::map<std::string, std::string> m_Options;
|
||||
BOBDestination * m_CurrentDestination;
|
||||
};
|
||||
typedef void (BOBCommandSession::*BOBCommandHandler)(const char * operand, size_t len);
|
||||
const i2p::data::PrivateKeys &GetKeys() const { return m_LocalDestination->GetPrivateKeys(); };
|
||||
|
||||
class BOBCommandChannel: private i2p::util::RunnableService
|
||||
{
|
||||
public:
|
||||
std::shared_ptr <ClientDestination> GetLocalDestination() const { return m_LocalDestination; };
|
||||
|
||||
BOBCommandChannel (const std::string& address, int port);
|
||||
~BOBCommandChannel ();
|
||||
private:
|
||||
|
||||
void Start ();
|
||||
void Stop ();
|
||||
std::shared_ptr <ClientDestination> m_LocalDestination;
|
||||
BOBI2POutboundTunnel *m_OutboundTunnel;
|
||||
BOBI2PInboundTunnel *m_InboundTunnel;
|
||||
|
||||
boost::asio::io_service& GetService () { return GetIOService (); };
|
||||
void AddDestination (const std::string& name, BOBDestination * dest);
|
||||
void DeleteDestination (const std::string& name);
|
||||
BOBDestination * FindDestination (const std::string& name);
|
||||
std::string m_Nickname;
|
||||
std::string m_InHost, m_OutHost;
|
||||
int m_InPort, m_OutPort;
|
||||
bool m_Quiet;
|
||||
bool m_IsRunning;
|
||||
};
|
||||
|
||||
private:
|
||||
class BOBCommandChannel;
|
||||
|
||||
void Accept ();
|
||||
void HandleAccept(const boost::system::error_code& ecode, std::shared_ptr<BOBCommandSession> session);
|
||||
class BOBCommandSession : public std::enable_shared_from_this<BOBCommandSession> {
|
||||
public:
|
||||
|
||||
private:
|
||||
BOBCommandSession(BOBCommandChannel &owner);
|
||||
|
||||
boost::asio::ip::tcp::acceptor m_Acceptor;
|
||||
std::map<std::string, BOBDestination *> m_Destinations;
|
||||
std::map<std::string, BOBCommandHandler> m_CommandHandlers;
|
||||
std::map<std::string, std::string> m_HelpStrings;
|
||||
~BOBCommandSession();
|
||||
|
||||
public:
|
||||
void Terminate();
|
||||
|
||||
const decltype(m_CommandHandlers)& GetCommandHandlers () const { return m_CommandHandlers; };
|
||||
const decltype(m_HelpStrings)& GetHelpStrings () const { return m_HelpStrings; };
|
||||
const decltype(m_Destinations)& GetDestinations () const { return m_Destinations; };
|
||||
};
|
||||
}
|
||||
boost::asio::ip::tcp::socket &GetSocket() { return m_Socket; };
|
||||
|
||||
void SendVersion();
|
||||
|
||||
// command handlers
|
||||
void ZapCommandHandler(const char *operand, size_t len);
|
||||
|
||||
void QuitCommandHandler(const char *operand, size_t len);
|
||||
|
||||
void StartCommandHandler(const char *operand, size_t len);
|
||||
|
||||
void StopCommandHandler(const char *operand, size_t len);
|
||||
|
||||
void SetNickCommandHandler(const char *operand, size_t len);
|
||||
|
||||
void GetNickCommandHandler(const char *operand, size_t len);
|
||||
|
||||
void NewkeysCommandHandler(const char *operand, size_t len);
|
||||
|
||||
void SetkeysCommandHandler(const char *operand, size_t len);
|
||||
|
||||
void GetkeysCommandHandler(const char *operand, size_t len);
|
||||
|
||||
void GetdestCommandHandler(const char *operand, size_t len);
|
||||
|
||||
void OuthostCommandHandler(const char *operand, size_t len);
|
||||
|
||||
void OutportCommandHandler(const char *operand, size_t len);
|
||||
|
||||
void InhostCommandHandler(const char *operand, size_t len);
|
||||
|
||||
void InportCommandHandler(const char *operand, size_t len);
|
||||
|
||||
void QuietCommandHandler(const char *operand, size_t len);
|
||||
|
||||
void LookupCommandHandler(const char *operand, size_t len);
|
||||
|
||||
void LookupLocalCommandHandler(const char *operand, size_t len);
|
||||
|
||||
void ClearCommandHandler(const char *operand, size_t len);
|
||||
|
||||
void ListCommandHandler(const char *operand, size_t len);
|
||||
|
||||
void OptionCommandHandler(const char *operand, size_t len);
|
||||
|
||||
void StatusCommandHandler(const char *operand, size_t len);
|
||||
|
||||
void HelpCommandHandler(const char *operand, size_t len);
|
||||
|
||||
private:
|
||||
|
||||
void Receive();
|
||||
|
||||
void HandleReceivedLine(const boost::system::error_code &ecode, std::size_t bytes_transferred);
|
||||
|
||||
void HandleReceived(const boost::system::error_code &ecode, std::size_t bytes_transferred);
|
||||
|
||||
void Send();
|
||||
|
||||
void HandleSent(const boost::system::error_code &ecode, std::size_t bytes_transferred);
|
||||
|
||||
void SendReplyOK(const char *msg = nullptr);
|
||||
|
||||
void SendReplyError(const char *msg);
|
||||
|
||||
void SendRaw(const char *data);
|
||||
|
||||
void BuildStatusLine(bool currentTunnel, BOBDestination *destination, std::string &out);
|
||||
|
||||
private:
|
||||
|
||||
BOBCommandChannel &m_Owner;
|
||||
boost::asio::ip::tcp::socket m_Socket;
|
||||
boost::asio::streambuf m_ReceiveBuffer, m_SendBuffer;
|
||||
bool m_IsOpen, m_IsQuiet, m_IsActive;
|
||||
std::string m_Nickname, m_InHost, m_OutHost;
|
||||
int m_InPort, m_OutPort;
|
||||
i2p::data::PrivateKeys m_Keys;
|
||||
std::map <std::string, std::string> m_Options;
|
||||
BOBDestination *m_CurrentDestination;
|
||||
};
|
||||
|
||||
typedef void (BOBCommandSession::*BOBCommandHandler)(const char *operand, size_t len);
|
||||
|
||||
class BOBCommandChannel : private i2p::util::RunnableService {
|
||||
public:
|
||||
|
||||
BOBCommandChannel(const std::string &address, int port);
|
||||
|
||||
~BOBCommandChannel();
|
||||
|
||||
void Start();
|
||||
|
||||
void Stop();
|
||||
|
||||
boost::asio::io_service &GetService() { return GetIOService(); };
|
||||
|
||||
void AddDestination(const std::string &name, BOBDestination *dest);
|
||||
|
||||
void DeleteDestination(const std::string &name);
|
||||
|
||||
BOBDestination *FindDestination(const std::string &name);
|
||||
|
||||
private:
|
||||
|
||||
void Accept();
|
||||
|
||||
void HandleAccept(const boost::system::error_code &ecode, std::shared_ptr <BOBCommandSession> session);
|
||||
|
||||
private:
|
||||
|
||||
boost::asio::ip::tcp::acceptor m_Acceptor;
|
||||
std::map<std::string, BOBDestination *> m_Destinations;
|
||||
std::map <std::string, BOBCommandHandler> m_CommandHandlers;
|
||||
std::map <std::string, std::string> m_HelpStrings;
|
||||
|
||||
public:
|
||||
|
||||
const decltype(m_CommandHandlers)
|
||||
&
|
||||
|
||||
GetCommandHandlers() const { return m_CommandHandlers; };
|
||||
const decltype(m_HelpStrings)
|
||||
&
|
||||
|
||||
GetHelpStrings() const { return m_HelpStrings; };
|
||||
const decltype(m_Destinations)
|
||||
&
|
||||
|
||||
GetDestinations() const { return m_Destinations; };
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -24,154 +24,197 @@
|
|||
#include "AddressBook.h"
|
||||
#include "I18N_langs.h"
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
namespace client
|
||||
{
|
||||
const char I2P_TUNNELS_SECTION_TYPE[] = "type";
|
||||
const char I2P_TUNNELS_SECTION_TYPE_CLIENT[] = "client";
|
||||
const char I2P_TUNNELS_SECTION_TYPE_SERVER[] = "server";
|
||||
const char I2P_TUNNELS_SECTION_TYPE_HTTP[] = "http";
|
||||
const char I2P_TUNNELS_SECTION_TYPE_IRC[] = "irc";
|
||||
const char I2P_TUNNELS_SECTION_TYPE_UDPCLIENT[] = "udpclient";
|
||||
const char I2P_TUNNELS_SECTION_TYPE_UDPSERVER[] = "udpserver";
|
||||
const char I2P_TUNNELS_SECTION_TYPE_SOCKS[] = "socks";
|
||||
const char I2P_TUNNELS_SECTION_TYPE_WEBSOCKS[] = "websocks";
|
||||
const char I2P_TUNNELS_SECTION_TYPE_HTTPPROXY[] = "httpproxy";
|
||||
const char I2P_CLIENT_TUNNEL_PORT[] = "port";
|
||||
const char I2P_CLIENT_TUNNEL_ADDRESS[] = "address";
|
||||
const char I2P_CLIENT_TUNNEL_DESTINATION[] = "destination";
|
||||
const char I2P_CLIENT_TUNNEL_KEYS[] = "keys";
|
||||
const char I2P_CLIENT_TUNNEL_GZIP[] = "gzip";
|
||||
const char I2P_CLIENT_TUNNEL_SIGNATURE_TYPE[] = "signaturetype";
|
||||
const char I2P_CLIENT_TUNNEL_CRYPTO_TYPE[] = "cryptotype";
|
||||
const char I2P_CLIENT_TUNNEL_DESTINATION_PORT[] = "destinationport";
|
||||
const char I2P_CLIENT_TUNNEL_MATCH_TUNNELS[] = "matchtunnels";
|
||||
const char I2P_CLIENT_TUNNEL_CONNECT_TIMEOUT[] = "connecttimeout";
|
||||
const char I2P_CLIENT_TUNNEL_KEEP_ALIVE_INTERVAL[] = "keepaliveinterval";
|
||||
const char I2P_SERVER_TUNNEL_HOST[] = "host";
|
||||
const char I2P_SERVER_TUNNEL_HOST_OVERRIDE[] = "hostoverride";
|
||||
const char I2P_SERVER_TUNNEL_PORT[] = "port";
|
||||
const char I2P_SERVER_TUNNEL_KEYS[] = "keys";
|
||||
const char I2P_SERVER_TUNNEL_SIGNATURE_TYPE[] = "signaturetype";
|
||||
const char I2P_SERVER_TUNNEL_INPORT[] = "inport";
|
||||
const char I2P_SERVER_TUNNEL_ACCESS_LIST[] = "accesslist";
|
||||
const char I2P_SERVER_TUNNEL_WHITE_LIST[] = "whitelist";
|
||||
const char I2P_SERVER_TUNNEL_GZIP[] = "gzip";
|
||||
const char I2P_SERVER_TUNNEL_WEBIRC_PASSWORD[] = "webircpassword";
|
||||
const char I2P_SERVER_TUNNEL_ADDRESS[] = "address";
|
||||
const char I2P_SERVER_TUNNEL_ENABLE_UNIQUE_LOCAL[] = "enableuniquelocal";
|
||||
namespace i2p {
|
||||
namespace client {
|
||||
const char I2P_TUNNELS_SECTION_TYPE[] = "type";
|
||||
const char I2P_TUNNELS_SECTION_TYPE_CLIENT[] = "client";
|
||||
const char I2P_TUNNELS_SECTION_TYPE_SERVER[] = "server";
|
||||
const char I2P_TUNNELS_SECTION_TYPE_HTTP[] = "http";
|
||||
const char I2P_TUNNELS_SECTION_TYPE_IRC[] = "irc";
|
||||
const char I2P_TUNNELS_SECTION_TYPE_UDPCLIENT[] = "udpclient";
|
||||
const char I2P_TUNNELS_SECTION_TYPE_UDPSERVER[] = "udpserver";
|
||||
const char I2P_TUNNELS_SECTION_TYPE_SOCKS[] = "socks";
|
||||
const char I2P_TUNNELS_SECTION_TYPE_WEBSOCKS[] = "websocks";
|
||||
const char I2P_TUNNELS_SECTION_TYPE_HTTPPROXY[] = "httpproxy";
|
||||
const char I2P_CLIENT_TUNNEL_PORT[] = "port";
|
||||
const char I2P_CLIENT_TUNNEL_ADDRESS[] = "address";
|
||||
const char I2P_CLIENT_TUNNEL_DESTINATION[] = "destination";
|
||||
const char I2P_CLIENT_TUNNEL_KEYS[] = "keys";
|
||||
const char I2P_CLIENT_TUNNEL_GZIP[] = "gzip";
|
||||
const char I2P_CLIENT_TUNNEL_SIGNATURE_TYPE[] = "signaturetype";
|
||||
const char I2P_CLIENT_TUNNEL_CRYPTO_TYPE[] = "cryptotype";
|
||||
const char I2P_CLIENT_TUNNEL_DESTINATION_PORT[] = "destinationport";
|
||||
const char I2P_CLIENT_TUNNEL_MATCH_TUNNELS[] = "matchtunnels";
|
||||
const char I2P_CLIENT_TUNNEL_CONNECT_TIMEOUT[] = "connecttimeout";
|
||||
const char I2P_CLIENT_TUNNEL_KEEP_ALIVE_INTERVAL[] = "keepaliveinterval";
|
||||
const char I2P_SERVER_TUNNEL_HOST[] = "host";
|
||||
const char I2P_SERVER_TUNNEL_HOST_OVERRIDE[] = "hostoverride";
|
||||
const char I2P_SERVER_TUNNEL_PORT[] = "port";
|
||||
const char I2P_SERVER_TUNNEL_KEYS[] = "keys";
|
||||
const char I2P_SERVER_TUNNEL_SIGNATURE_TYPE[] = "signaturetype";
|
||||
const char I2P_SERVER_TUNNEL_INPORT[] = "inport";
|
||||
const char I2P_SERVER_TUNNEL_ACCESS_LIST[] = "accesslist";
|
||||
const char I2P_SERVER_TUNNEL_WHITE_LIST[] = "whitelist";
|
||||
const char I2P_SERVER_TUNNEL_GZIP[] = "gzip";
|
||||
const char I2P_SERVER_TUNNEL_WEBIRC_PASSWORD[] = "webircpassword";
|
||||
const char I2P_SERVER_TUNNEL_ADDRESS[] = "address";
|
||||
const char I2P_SERVER_TUNNEL_ENABLE_UNIQUE_LOCAL[] = "enableuniquelocal";
|
||||
|
||||
|
||||
class ClientContext
|
||||
{
|
||||
public:
|
||||
class ClientContext {
|
||||
public:
|
||||
|
||||
ClientContext ();
|
||||
~ClientContext ();
|
||||
ClientContext();
|
||||
|
||||
void Start ();
|
||||
void Stop ();
|
||||
~ClientContext();
|
||||
|
||||
void ReloadConfig ();
|
||||
void Start();
|
||||
|
||||
std::shared_ptr<ClientDestination> GetSharedLocalDestination () const { return m_SharedLocalDestination; };
|
||||
std::shared_ptr<ClientDestination> CreateNewLocalDestination (bool isPublic = false, // transient
|
||||
i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519,
|
||||
i2p::data::CryptoKeyType cryptoType = i2p::data::CRYPTO_KEY_TYPE_ELGAMAL,
|
||||
const std::map<std::string, std::string> * params = nullptr); // used by SAM only
|
||||
std::shared_ptr<ClientDestination> CreateNewLocalDestination (boost::asio::io_service& service,
|
||||
bool isPublic = false, i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519,
|
||||
i2p::data::CryptoKeyType cryptoType = i2p::data::CRYPTO_KEY_TYPE_ELGAMAL,
|
||||
const std::map<std::string, std::string> * params = nullptr); // same as previous but on external io_service
|
||||
std::shared_ptr<ClientDestination> CreateNewLocalDestination (const i2p::data::PrivateKeys& keys, bool isPublic = true,
|
||||
const std::map<std::string, std::string> * params = nullptr);
|
||||
std::shared_ptr<ClientDestination> CreateNewLocalDestination (boost::asio::io_service& service,
|
||||
const i2p::data::PrivateKeys& keys, bool isPublic = true,
|
||||
const std::map<std::string, std::string> * params = nullptr); // same as previous but on external io_service
|
||||
std::shared_ptr<ClientDestination> CreateNewMatchedTunnelDestination(const i2p::data::PrivateKeys &keys,
|
||||
const std::string & name, const std::map<std::string, std::string> * params = nullptr);
|
||||
void DeleteLocalDestination (std::shared_ptr<ClientDestination> destination);
|
||||
std::shared_ptr<ClientDestination> FindLocalDestination (const i2p::data::IdentHash& destination) const;
|
||||
bool LoadPrivateKeys (i2p::data::PrivateKeys& keys, const std::string& filename,
|
||||
i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519,
|
||||
i2p::data::CryptoKeyType cryptoType = i2p::data::CRYPTO_KEY_TYPE_ELGAMAL);
|
||||
void Stop();
|
||||
|
||||
AddressBook& GetAddressBook () { return m_AddressBook; };
|
||||
const BOBCommandChannel * GetBOBCommandChannel () const { return m_BOBCommandChannel; };
|
||||
const SAMBridge * GetSAMBridge () const { return m_SamBridge; };
|
||||
const I2CPServer * GetI2CPServer () const { return m_I2CPServer; };
|
||||
void ReloadConfig();
|
||||
|
||||
std::vector<std::shared_ptr<DatagramSessionInfo> > GetForwardInfosFor(const i2p::data::IdentHash & destination);
|
||||
std::shared_ptr <ClientDestination> GetSharedLocalDestination() const { return m_SharedLocalDestination; };
|
||||
|
||||
// i18n
|
||||
std::shared_ptr<const i2p::i18n::Locale> GetLanguage () { return m_Language; };
|
||||
void SetLanguage (const std::shared_ptr<const i2p::i18n::Locale> language) { m_Language = language; };
|
||||
std::shared_ptr <ClientDestination> CreateNewLocalDestination(bool isPublic = false, // transient
|
||||
i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519,
|
||||
i2p::data::CryptoKeyType cryptoType = i2p::data::CRYPTO_KEY_TYPE_ELGAMAL,
|
||||
const std::map <std::string, std::string> *params = nullptr); // used by SAM only
|
||||
std::shared_ptr <ClientDestination> CreateNewLocalDestination(boost::asio::io_service &service,
|
||||
bool isPublic = false,
|
||||
i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519,
|
||||
i2p::data::CryptoKeyType cryptoType = i2p::data::CRYPTO_KEY_TYPE_ELGAMAL,
|
||||
const std::map <std::string, std::string> *params = nullptr); // same as previous but on external io_service
|
||||
std::shared_ptr <ClientDestination>
|
||||
CreateNewLocalDestination(const i2p::data::PrivateKeys &keys, bool isPublic = true,
|
||||
const std::map <std::string, std::string> *params = nullptr);
|
||||
|
||||
private:
|
||||
std::shared_ptr <ClientDestination> CreateNewLocalDestination(boost::asio::io_service &service,
|
||||
const i2p::data::PrivateKeys &keys,
|
||||
bool isPublic = true,
|
||||
const std::map <std::string, std::string> *params = nullptr); // same as previous but on external io_service
|
||||
std::shared_ptr <ClientDestination> CreateNewMatchedTunnelDestination(const i2p::data::PrivateKeys &keys,
|
||||
const std::string &name,
|
||||
const std::map <std::string, std::string> *params = nullptr);
|
||||
|
||||
void ReadTunnels ();
|
||||
void ReadTunnels (const std::string& tunConf, int& numClientTunnels, int& numServerTunnels);
|
||||
void ReadHttpProxy ();
|
||||
void ReadSocksProxy ();
|
||||
template<typename Section, typename Type>
|
||||
std::string GetI2CPOption (const Section& section, const std::string& name, const Type& value) const;
|
||||
template<typename Section>
|
||||
std::string GetI2CPStringOption (const Section& section, const std::string& name, const std::string& value) const; // GetI2CPOption with string default value
|
||||
template<typename Section>
|
||||
void ReadI2CPOptionsGroup (const Section& section, const std::string& group, std::map<std::string, std::string>& options) const;
|
||||
template<typename Section>
|
||||
void ReadI2CPOptions (const Section& section, bool isServer, std::map<std::string, std::string>& options) const; // for tunnels
|
||||
void ReadI2CPOptionsFromConfig (const std::string& prefix, std::map<std::string, std::string>& options) const; // for HTTP and SOCKS proxy
|
||||
void DeleteLocalDestination(std::shared_ptr <ClientDestination> destination);
|
||||
|
||||
void CleanupUDP(const boost::system::error_code & ecode);
|
||||
void ScheduleCleanupUDP();
|
||||
std::shared_ptr <ClientDestination> FindLocalDestination(const i2p::data::IdentHash &destination) const;
|
||||
|
||||
void VisitTunnels (bool clean);
|
||||
bool LoadPrivateKeys(i2p::data::PrivateKeys &keys, const std::string &filename,
|
||||
i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519,
|
||||
i2p::data::CryptoKeyType cryptoType = i2p::data::CRYPTO_KEY_TYPE_ELGAMAL);
|
||||
|
||||
void CreateNewSharedLocalDestination ();
|
||||
void AddLocalDestination (std::shared_ptr<ClientDestination> localDestination);
|
||||
AddressBook &GetAddressBook() { return m_AddressBook; };
|
||||
|
||||
private:
|
||||
const BOBCommandChannel *GetBOBCommandChannel() const { return m_BOBCommandChannel; };
|
||||
|
||||
std::mutex m_DestinationsMutex;
|
||||
std::map<i2p::data::IdentHash, std::shared_ptr<ClientDestination> > m_Destinations;
|
||||
std::shared_ptr<ClientDestination> m_SharedLocalDestination;
|
||||
const SAMBridge *GetSAMBridge() const { return m_SamBridge; };
|
||||
|
||||
AddressBook m_AddressBook;
|
||||
const I2CPServer *GetI2CPServer() const { return m_I2CPServer; };
|
||||
|
||||
i2p::proxy::HTTPProxy * m_HttpProxy;
|
||||
i2p::proxy::SOCKSProxy * m_SocksProxy;
|
||||
std::map<boost::asio::ip::tcp::endpoint, std::shared_ptr<I2PService> > m_ClientTunnels; // local endpoint -> tunnel
|
||||
std::map<std::pair<i2p::data::IdentHash, int>, std::shared_ptr<I2PServerTunnel> > m_ServerTunnels; // <destination,port> -> tunnel
|
||||
std::vector <std::shared_ptr<DatagramSessionInfo>>
|
||||
GetForwardInfosFor(const i2p::data::IdentHash &destination);
|
||||
|
||||
std::mutex m_ForwardsMutex;
|
||||
std::map<boost::asio::ip::udp::endpoint, std::shared_ptr<I2PUDPClientTunnel> > m_ClientForwards; // local endpoint -> udp tunnel
|
||||
std::map<std::pair<i2p::data::IdentHash, int>, std::shared_ptr<I2PUDPServerTunnel> > m_ServerForwards; // <destination,port> -> udp tunnel
|
||||
// i18n
|
||||
std::shared_ptr<const i2p::i18n::Locale> GetLanguage() { return m_Language; };
|
||||
|
||||
SAMBridge * m_SamBridge;
|
||||
BOBCommandChannel * m_BOBCommandChannel;
|
||||
I2CPServer * m_I2CPServer;
|
||||
void SetLanguage(const std::shared_ptr<const i2p::i18n::Locale> language) { m_Language = language; };
|
||||
|
||||
std::unique_ptr<boost::asio::deadline_timer> m_CleanupUDPTimer;
|
||||
private:
|
||||
|
||||
// i18n
|
||||
std::shared_ptr<const i2p::i18n::Locale> m_Language;
|
||||
void ReadTunnels();
|
||||
|
||||
public:
|
||||
void ReadTunnels(const std::string &tunConf, int &numClientTunnels, int &numServerTunnels);
|
||||
|
||||
// for HTTP
|
||||
const decltype(m_Destinations)& GetDestinations () const { return m_Destinations; };
|
||||
const decltype(m_ClientTunnels)& GetClientTunnels () const { return m_ClientTunnels; };
|
||||
const decltype(m_ServerTunnels)& GetServerTunnels () const { return m_ServerTunnels; };
|
||||
const decltype(m_ClientForwards)& GetClientForwards () const { return m_ClientForwards; }
|
||||
const decltype(m_ServerForwards)& GetServerForwards () const { return m_ServerForwards; }
|
||||
const i2p::proxy::HTTPProxy * GetHttpProxy () const { return m_HttpProxy; }
|
||||
const i2p::proxy::SOCKSProxy * GetSocksProxy () const { return m_SocksProxy; }
|
||||
};
|
||||
void ReadHttpProxy();
|
||||
|
||||
extern ClientContext context;
|
||||
}
|
||||
void ReadSocksProxy();
|
||||
|
||||
template<typename Section, typename Type>
|
||||
std::string GetI2CPOption(const Section §ion, const std::string &name, const Type &value) const;
|
||||
|
||||
template<typename Section>
|
||||
std::string GetI2CPStringOption(const Section §ion, const std::string &name,
|
||||
const std::string &value) const; // GetI2CPOption with string default value
|
||||
template<typename Section>
|
||||
void ReadI2CPOptionsGroup(const Section §ion, const std::string &group,
|
||||
std::map <std::string, std::string> &options) const;
|
||||
|
||||
template<typename Section>
|
||||
void ReadI2CPOptions(const Section §ion, bool isServer,
|
||||
std::map <std::string, std::string> &options) const; // for tunnels
|
||||
void ReadI2CPOptionsFromConfig(const std::string &prefix,
|
||||
std::map <std::string, std::string> &options) const; // for HTTP and SOCKS proxy
|
||||
|
||||
void CleanupUDP(const boost::system::error_code &ecode);
|
||||
|
||||
void ScheduleCleanupUDP();
|
||||
|
||||
void VisitTunnels(bool clean);
|
||||
|
||||
void CreateNewSharedLocalDestination();
|
||||
|
||||
void AddLocalDestination(std::shared_ptr <ClientDestination> localDestination);
|
||||
|
||||
private:
|
||||
|
||||
std::mutex m_DestinationsMutex;
|
||||
std::map <i2p::data::IdentHash, std::shared_ptr<ClientDestination>> m_Destinations;
|
||||
std::shared_ptr <ClientDestination> m_SharedLocalDestination;
|
||||
|
||||
AddressBook m_AddressBook;
|
||||
|
||||
i2p::proxy::HTTPProxy *m_HttpProxy;
|
||||
i2p::proxy::SOCKSProxy *m_SocksProxy;
|
||||
std::map <boost::asio::ip::tcp::endpoint, std::shared_ptr<I2PService>> m_ClientTunnels; // local endpoint -> tunnel
|
||||
std::map <std::pair<i2p::data::IdentHash, int>, std::shared_ptr<I2PServerTunnel>> m_ServerTunnels; // <destination,port> -> tunnel
|
||||
|
||||
std::mutex m_ForwardsMutex;
|
||||
std::map <boost::asio::ip::udp::endpoint, std::shared_ptr<I2PUDPClientTunnel>> m_ClientForwards; // local endpoint -> udp tunnel
|
||||
std::map <std::pair<i2p::data::IdentHash, int>, std::shared_ptr<I2PUDPServerTunnel>> m_ServerForwards; // <destination,port> -> udp tunnel
|
||||
|
||||
SAMBridge *m_SamBridge;
|
||||
BOBCommandChannel *m_BOBCommandChannel;
|
||||
I2CPServer *m_I2CPServer;
|
||||
|
||||
std::unique_ptr <boost::asio::deadline_timer> m_CleanupUDPTimer;
|
||||
|
||||
// i18n
|
||||
std::shared_ptr<const i2p::i18n::Locale> m_Language;
|
||||
|
||||
public:
|
||||
|
||||
// for HTTP
|
||||
const decltype(m_Destinations)
|
||||
&
|
||||
|
||||
GetDestinations() const { return m_Destinations; };
|
||||
const decltype(m_ClientTunnels)
|
||||
&
|
||||
|
||||
GetClientTunnels() const { return m_ClientTunnels; };
|
||||
const decltype(m_ServerTunnels)
|
||||
&
|
||||
|
||||
GetServerTunnels() const { return m_ServerTunnels; };
|
||||
const decltype(m_ClientForwards)
|
||||
&
|
||||
|
||||
GetClientForwards() const { return m_ClientForwards; }
|
||||
|
||||
const decltype(m_ServerForwards)
|
||||
&
|
||||
|
||||
GetServerForwards() const { return m_ServerForwards; }
|
||||
|
||||
const i2p::proxy::HTTPProxy *GetHttpProxy() const { return m_HttpProxy; }
|
||||
|
||||
const i2p::proxy::SOCKSProxy *GetSocksProxy() const { return m_SocksProxy; }
|
||||
};
|
||||
|
||||
extern ClientContext context;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -10,32 +10,38 @@
|
|||
#define HTTP_PROXY_H__
|
||||
|
||||
namespace i2p {
|
||||
namespace proxy {
|
||||
class HTTPProxy: public i2p::client::TCPIPAcceptor
|
||||
{
|
||||
public:
|
||||
namespace proxy {
|
||||
class HTTPProxy : public i2p::client::TCPIPAcceptor {
|
||||
public:
|
||||
|
||||
HTTPProxy(const std::string& name, const std::string& address, int port, const std::string & outproxy, bool addresshelper, std::shared_ptr<i2p::client::ClientDestination> localDestination);
|
||||
HTTPProxy(const std::string& name, const std::string& address, int port, std::shared_ptr<i2p::client::ClientDestination> localDestination = nullptr) :
|
||||
HTTPProxy(name, address, port, "", true, localDestination) {} ;
|
||||
~HTTPProxy() {};
|
||||
HTTPProxy(const std::string &name, const std::string &address, int port, const std::string &outproxy,
|
||||
bool addresshelper, std::shared_ptr <i2p::client::ClientDestination> localDestination);
|
||||
|
||||
std::string GetOutproxyURL() const { return m_OutproxyUrl; }
|
||||
bool GetHelperSupport() { return m_Addresshelper; }
|
||||
HTTPProxy(const std::string &name, const std::string &address, int port,
|
||||
std::shared_ptr <i2p::client::ClientDestination> localDestination = nullptr) :
|
||||
HTTPProxy(name, address, port, "", true, localDestination) {};
|
||||
|
||||
protected:
|
||||
~HTTPProxy() {};
|
||||
|
||||
// Implements TCPIPAcceptor
|
||||
std::shared_ptr<i2p::client::I2PServiceHandler> CreateHandler(std::shared_ptr<boost::asio::ip::tcp::socket> socket);
|
||||
const char* GetName() { return m_Name.c_str (); }
|
||||
std::string GetOutproxyURL() const { return m_OutproxyUrl; }
|
||||
|
||||
private:
|
||||
bool GetHelperSupport() { return m_Addresshelper; }
|
||||
|
||||
std::string m_Name;
|
||||
std::string m_OutproxyUrl;
|
||||
bool m_Addresshelper;
|
||||
};
|
||||
} // http
|
||||
protected:
|
||||
|
||||
// Implements TCPIPAcceptor
|
||||
std::shared_ptr <i2p::client::I2PServiceHandler>
|
||||
CreateHandler(std::shared_ptr <boost::asio::ip::tcp::socket> socket);
|
||||
|
||||
const char *GetName() { return m_Name.c_str(); }
|
||||
|
||||
private:
|
||||
|
||||
std::string m_Name;
|
||||
std::string m_OutproxyUrl;
|
||||
bool m_Addresshelper;
|
||||
};
|
||||
} // http
|
||||
} // i2p
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -19,233 +19,281 @@
|
|||
#include "Destination.h"
|
||||
#include "Streaming.h"
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
namespace client
|
||||
{
|
||||
const uint8_t I2CP_PROTOCOL_BYTE = 0x2A;
|
||||
const size_t I2CP_SESSION_BUFFER_SIZE = 4096;
|
||||
const size_t I2CP_MAX_MESSAGE_LENGTH = 65535;
|
||||
const size_t I2CP_MAX_SEND_QUEUE_SIZE = 1024*1024; // in bytes, 1M
|
||||
const int I2CP_LEASESET_CREATION_TIMEOUT = 10; // in seconds
|
||||
namespace i2p {
|
||||
namespace client {
|
||||
const uint8_t I2CP_PROTOCOL_BYTE = 0x2A;
|
||||
const size_t I2CP_SESSION_BUFFER_SIZE = 4096;
|
||||
const size_t I2CP_MAX_MESSAGE_LENGTH = 65535;
|
||||
const size_t I2CP_MAX_SEND_QUEUE_SIZE = 1024 * 1024; // in bytes, 1M
|
||||
const int I2CP_LEASESET_CREATION_TIMEOUT = 10; // in seconds
|
||||
|
||||
const size_t I2CP_HEADER_LENGTH_OFFSET = 0;
|
||||
const size_t I2CP_HEADER_TYPE_OFFSET = I2CP_HEADER_LENGTH_OFFSET + 4;
|
||||
const size_t I2CP_HEADER_SIZE = I2CP_HEADER_TYPE_OFFSET + 1;
|
||||
const size_t I2CP_HEADER_LENGTH_OFFSET = 0;
|
||||
const size_t I2CP_HEADER_TYPE_OFFSET = I2CP_HEADER_LENGTH_OFFSET + 4;
|
||||
const size_t I2CP_HEADER_SIZE = I2CP_HEADER_TYPE_OFFSET + 1;
|
||||
|
||||
const uint8_t I2CP_GET_DATE_MESSAGE = 32;
|
||||
const uint8_t I2CP_SET_DATE_MESSAGE = 33;
|
||||
const uint8_t I2CP_CREATE_SESSION_MESSAGE = 1;
|
||||
const uint8_t I2CP_RECONFIGURE_SESSION_MESSAGE = 2;
|
||||
const uint8_t I2CP_SESSION_STATUS_MESSAGE = 20;
|
||||
const uint8_t I2CP_DESTROY_SESSION_MESSAGE = 3;
|
||||
const uint8_t I2CP_REQUEST_VARIABLE_LEASESET_MESSAGE = 37;
|
||||
const uint8_t I2CP_CREATE_LEASESET_MESSAGE = 4;
|
||||
const uint8_t I2CP_CREATE_LEASESET2_MESSAGE = 41;
|
||||
const uint8_t I2CP_SEND_MESSAGE_MESSAGE = 5;
|
||||
const uint8_t I2CP_SEND_MESSAGE_EXPIRES_MESSAGE = 36;
|
||||
const uint8_t I2CP_MESSAGE_PAYLOAD_MESSAGE = 31;
|
||||
const uint8_t I2CP_MESSAGE_STATUS_MESSAGE = 22;
|
||||
const uint8_t I2CP_HOST_LOOKUP_MESSAGE = 38;
|
||||
const uint8_t I2CP_HOST_REPLY_MESSAGE = 39;
|
||||
const uint8_t I2CP_DEST_LOOKUP_MESSAGE = 34;
|
||||
const uint8_t I2CP_DEST_REPLY_MESSAGE = 35;
|
||||
const uint8_t I2CP_GET_BANDWIDTH_LIMITS_MESSAGE = 8;
|
||||
const uint8_t I2CP_BANDWIDTH_LIMITS_MESSAGE = 23;
|
||||
const uint8_t I2CP_GET_DATE_MESSAGE = 32;
|
||||
const uint8_t I2CP_SET_DATE_MESSAGE = 33;
|
||||
const uint8_t I2CP_CREATE_SESSION_MESSAGE = 1;
|
||||
const uint8_t I2CP_RECONFIGURE_SESSION_MESSAGE = 2;
|
||||
const uint8_t I2CP_SESSION_STATUS_MESSAGE = 20;
|
||||
const uint8_t I2CP_DESTROY_SESSION_MESSAGE = 3;
|
||||
const uint8_t I2CP_REQUEST_VARIABLE_LEASESET_MESSAGE = 37;
|
||||
const uint8_t I2CP_CREATE_LEASESET_MESSAGE = 4;
|
||||
const uint8_t I2CP_CREATE_LEASESET2_MESSAGE = 41;
|
||||
const uint8_t I2CP_SEND_MESSAGE_MESSAGE = 5;
|
||||
const uint8_t I2CP_SEND_MESSAGE_EXPIRES_MESSAGE = 36;
|
||||
const uint8_t I2CP_MESSAGE_PAYLOAD_MESSAGE = 31;
|
||||
const uint8_t I2CP_MESSAGE_STATUS_MESSAGE = 22;
|
||||
const uint8_t I2CP_HOST_LOOKUP_MESSAGE = 38;
|
||||
const uint8_t I2CP_HOST_REPLY_MESSAGE = 39;
|
||||
const uint8_t I2CP_DEST_LOOKUP_MESSAGE = 34;
|
||||
const uint8_t I2CP_DEST_REPLY_MESSAGE = 35;
|
||||
const uint8_t I2CP_GET_BANDWIDTH_LIMITS_MESSAGE = 8;
|
||||
const uint8_t I2CP_BANDWIDTH_LIMITS_MESSAGE = 23;
|
||||
|
||||
enum I2CPMessageStatus
|
||||
{
|
||||
eI2CPMessageStatusAccepted = 1,
|
||||
eI2CPMessageStatusGuaranteedSuccess = 4,
|
||||
eI2CPMessageStatusGuaranteedFailure = 5,
|
||||
eI2CPMessageStatusNoLeaseSet = 21
|
||||
};
|
||||
enum I2CPMessageStatus {
|
||||
eI2CPMessageStatusAccepted = 1,
|
||||
eI2CPMessageStatusGuaranteedSuccess = 4,
|
||||
eI2CPMessageStatusGuaranteedFailure = 5,
|
||||
eI2CPMessageStatusNoLeaseSet = 21
|
||||
};
|
||||
|
||||
enum I2CPSessionStatus
|
||||
{
|
||||
eI2CPSessionStatusDestroyed = 0,
|
||||
eI2CPSessionStatusCreated = 1,
|
||||
eI2CPSessionStatusUpdated = 2,
|
||||
eI2CPSessionStatusInvalid = 3,
|
||||
eI2CPSessionStatusRefused = 4
|
||||
};
|
||||
enum I2CPSessionStatus {
|
||||
eI2CPSessionStatusDestroyed = 0,
|
||||
eI2CPSessionStatusCreated = 1,
|
||||
eI2CPSessionStatusUpdated = 2,
|
||||
eI2CPSessionStatusInvalid = 3,
|
||||
eI2CPSessionStatusRefused = 4
|
||||
};
|
||||
|
||||
// params
|
||||
const char I2CP_PARAM_MESSAGE_RELIABILITY[] = "i2cp.messageReliability";
|
||||
// params
|
||||
const char I2CP_PARAM_MESSAGE_RELIABILITY[] = "i2cp.messageReliability";
|
||||
|
||||
class I2CPSession;
|
||||
class I2CPDestination: public LeaseSetDestination
|
||||
{
|
||||
public:
|
||||
class I2CPSession;
|
||||
|
||||
I2CPDestination (boost::asio::io_service& service, std::shared_ptr<I2CPSession> owner,
|
||||
std::shared_ptr<const i2p::data::IdentityEx> identity, bool isPublic, const std::map<std::string, std::string>& params);
|
||||
~I2CPDestination () {};
|
||||
class I2CPDestination : public LeaseSetDestination {
|
||||
public:
|
||||
|
||||
void Stop ();
|
||||
I2CPDestination(boost::asio::io_service &service, std::shared_ptr <I2CPSession> owner,
|
||||
std::shared_ptr<const i2p::data::IdentityEx> identity, bool isPublic,
|
||||
const std::map <std::string, std::string> ¶ms);
|
||||
|
||||
void SetEncryptionPrivateKey (const uint8_t * key);
|
||||
void SetEncryptionType (i2p::data::CryptoKeyType keyType) { m_EncryptionKeyType = keyType; };
|
||||
void SetECIESx25519EncryptionPrivateKey (const uint8_t * key);
|
||||
void LeaseSetCreated (const uint8_t * buf, size_t len); // called from I2CPSession
|
||||
void LeaseSet2Created (uint8_t storeType, const uint8_t * buf, size_t len); // called from I2CPSession
|
||||
void SendMsgTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash& ident, uint32_t nonce); // called from I2CPSession
|
||||
~I2CPDestination() {};
|
||||
|
||||
// implements LocalDestination
|
||||
bool Decrypt (const uint8_t * encrypted, uint8_t * data, i2p::data::CryptoKeyType preferredCrypto) const;
|
||||
bool SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const;
|
||||
const uint8_t * GetEncryptionPublicKey (i2p::data::CryptoKeyType keyType) const; // for 4 only
|
||||
std::shared_ptr<const i2p::data::IdentityEx> GetIdentity () const { return m_Identity; };
|
||||
void Stop();
|
||||
|
||||
protected:
|
||||
void SetEncryptionPrivateKey(const uint8_t *key);
|
||||
|
||||
// I2CP
|
||||
void HandleDataMessage (const uint8_t * buf, size_t len);
|
||||
void CreateNewLeaseSet (const std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> >& tunnels);
|
||||
void SetEncryptionType(i2p::data::CryptoKeyType keyType) { m_EncryptionKeyType = keyType; };
|
||||
|
||||
private:
|
||||
void SetECIESx25519EncryptionPrivateKey(const uint8_t *key);
|
||||
|
||||
std::shared_ptr<I2CPDestination> GetSharedFromThis ()
|
||||
{ return std::static_pointer_cast<I2CPDestination>(shared_from_this ()); }
|
||||
bool SendMsg (std::shared_ptr<I2NPMessage> msg, std::shared_ptr<const i2p::data::LeaseSet> remote);
|
||||
void LeaseSetCreated(const uint8_t *buf, size_t len); // called from I2CPSession
|
||||
void LeaseSet2Created(uint8_t storeType, const uint8_t *buf, size_t len); // called from I2CPSession
|
||||
void SendMsgTo(const uint8_t *payload, size_t len, const i2p::data::IdentHash &ident,
|
||||
uint32_t nonce); // called from I2CPSession
|
||||
|
||||
void PostCreateNewLeaseSet (std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> > tunnels);
|
||||
// implements LocalDestination
|
||||
bool Decrypt(const uint8_t *encrypted, uint8_t *data, i2p::data::CryptoKeyType preferredCrypto) const;
|
||||
|
||||
private:
|
||||
bool SupportsEncryptionType(i2p::data::CryptoKeyType keyType) const;
|
||||
|
||||
std::shared_ptr<I2CPSession> m_Owner;
|
||||
std::shared_ptr<const i2p::data::IdentityEx> m_Identity;
|
||||
i2p::data::CryptoKeyType m_EncryptionKeyType;
|
||||
std::shared_ptr<i2p::crypto::CryptoKeyDecryptor> m_Decryptor; // standard
|
||||
std::shared_ptr<i2p::crypto::ECIESX25519AEADRatchetDecryptor> m_ECIESx25519Decryptor;
|
||||
uint8_t m_ECIESx25519PrivateKey[32];
|
||||
uint64_t m_LeaseSetExpirationTime;
|
||||
bool m_IsCreatingLeaseSet;
|
||||
boost::asio::deadline_timer m_LeaseSetCreationTimer;
|
||||
i2p::util::MemoryPoolMt<I2NPMessageBuffer<I2NP_MAX_MESSAGE_SIZE> > m_I2NPMsgsPool;
|
||||
};
|
||||
const uint8_t *GetEncryptionPublicKey(i2p::data::CryptoKeyType keyType) const; // for 4 only
|
||||
std::shared_ptr<const i2p::data::IdentityEx> GetIdentity() const { return m_Identity; };
|
||||
|
||||
class RunnableI2CPDestination: private i2p::util::RunnableService, public I2CPDestination
|
||||
{
|
||||
public:
|
||||
protected:
|
||||
|
||||
RunnableI2CPDestination (std::shared_ptr<I2CPSession> owner, std::shared_ptr<const i2p::data::IdentityEx> identity,
|
||||
bool isPublic, const std::map<std::string, std::string>& params);
|
||||
~RunnableI2CPDestination ();
|
||||
// I2CP
|
||||
void HandleDataMessage(const uint8_t *buf, size_t len);
|
||||
|
||||
void Start ();
|
||||
void Stop ();
|
||||
};
|
||||
void CreateNewLeaseSet(const std::vector <std::shared_ptr<i2p::tunnel::InboundTunnel>> &tunnels);
|
||||
|
||||
class I2CPServer;
|
||||
class I2CPSession: public std::enable_shared_from_this<I2CPSession>
|
||||
{
|
||||
public:
|
||||
private:
|
||||
|
||||
I2CPSession (I2CPServer& owner, std::shared_ptr<boost::asio::ip::tcp::socket> socket);
|
||||
std::shared_ptr <I2CPDestination> GetSharedFromThis() {
|
||||
return std::static_pointer_cast<I2CPDestination>(shared_from_this());
|
||||
}
|
||||
|
||||
~I2CPSession ();
|
||||
bool SendMsg(std::shared_ptr <I2NPMessage> msg, std::shared_ptr<const i2p::data::LeaseSet> remote);
|
||||
|
||||
void Start ();
|
||||
void Stop ();
|
||||
uint16_t GetSessionID () const { return m_SessionID; };
|
||||
std::shared_ptr<const I2CPDestination> GetDestination () const { return m_Destination; };
|
||||
void PostCreateNewLeaseSet(std::vector <std::shared_ptr<i2p::tunnel::InboundTunnel>> tunnels);
|
||||
|
||||
// called from I2CPDestination
|
||||
void SendI2CPMessage (uint8_t type, const uint8_t * payload, size_t len);
|
||||
void SendMessagePayloadMessage (const uint8_t * payload, size_t len);
|
||||
void SendMessageStatusMessage (uint32_t nonce, I2CPMessageStatus status);
|
||||
private:
|
||||
|
||||
// message handlers
|
||||
void GetDateMessageHandler (const uint8_t * buf, size_t len);
|
||||
void CreateSessionMessageHandler (const uint8_t * buf, size_t len);
|
||||
void DestroySessionMessageHandler (const uint8_t * buf, size_t len);
|
||||
void ReconfigureSessionMessageHandler (const uint8_t * buf, size_t len);
|
||||
void CreateLeaseSetMessageHandler (const uint8_t * buf, size_t len);
|
||||
void CreateLeaseSet2MessageHandler (const uint8_t * buf, size_t len);
|
||||
void SendMessageMessageHandler (const uint8_t * buf, size_t len);
|
||||
void SendMessageExpiresMessageHandler (const uint8_t * buf, size_t len);
|
||||
void HostLookupMessageHandler (const uint8_t * buf, size_t len);
|
||||
void DestLookupMessageHandler (const uint8_t * buf, size_t len);
|
||||
void GetBandwidthLimitsMessageHandler (const uint8_t * buf, size_t len);
|
||||
std::shared_ptr <I2CPSession> m_Owner;
|
||||
std::shared_ptr<const i2p::data::IdentityEx> m_Identity;
|
||||
i2p::data::CryptoKeyType m_EncryptionKeyType;
|
||||
std::shared_ptr <i2p::crypto::CryptoKeyDecryptor> m_Decryptor; // standard
|
||||
std::shared_ptr <i2p::crypto::ECIESX25519AEADRatchetDecryptor> m_ECIESx25519Decryptor;
|
||||
uint8_t m_ECIESx25519PrivateKey[32];
|
||||
uint64_t m_LeaseSetExpirationTime;
|
||||
bool m_IsCreatingLeaseSet;
|
||||
boost::asio::deadline_timer m_LeaseSetCreationTimer;
|
||||
i2p::util::MemoryPoolMt<I2NPMessageBuffer < I2NP_MAX_MESSAGE_SIZE> >
|
||||
m_I2NPMsgsPool;
|
||||
};
|
||||
|
||||
private:
|
||||
class RunnableI2CPDestination : private i2p::util::RunnableService, public I2CPDestination {
|
||||
public:
|
||||
|
||||
void ReadProtocolByte ();
|
||||
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 ();
|
||||
RunnableI2CPDestination(std::shared_ptr <I2CPSession> owner,
|
||||
std::shared_ptr<const i2p::data::IdentityEx> identity,
|
||||
bool isPublic, const std::map <std::string, std::string> ¶ms);
|
||||
|
||||
void HandleI2CPMessageSent (const boost::system::error_code& ecode, std::size_t bytes_transferred);
|
||||
~RunnableI2CPDestination();
|
||||
|
||||
std::string ExtractString (const uint8_t * buf, size_t len);
|
||||
size_t PutString (uint8_t * buf, size_t len, const std::string& str);
|
||||
void ExtractMapping (const uint8_t * buf, size_t len, std::map<std::string, std::string>& mapping);
|
||||
void SendSessionStatusMessage (I2CPSessionStatus status);
|
||||
void SendHostReplyMessage (uint32_t requestID, std::shared_ptr<const i2p::data::IdentityEx> identity);
|
||||
void Start();
|
||||
|
||||
private:
|
||||
void Stop();
|
||||
};
|
||||
|
||||
I2CPServer& m_Owner;
|
||||
std::shared_ptr<boost::asio::ip::tcp::socket> m_Socket;
|
||||
uint8_t m_Header[I2CP_HEADER_SIZE], m_Payload[I2CP_MAX_MESSAGE_LENGTH];
|
||||
size_t m_PayloadLen;
|
||||
class I2CPServer;
|
||||
|
||||
std::shared_ptr<I2CPDestination> m_Destination;
|
||||
uint16_t m_SessionID;
|
||||
uint32_t m_MessageID;
|
||||
bool m_IsSendAccepted;
|
||||
class I2CPSession : public std::enable_shared_from_this<I2CPSession> {
|
||||
public:
|
||||
|
||||
// to client
|
||||
bool m_IsSending;
|
||||
uint8_t m_SendBuffer[I2CP_MAX_MESSAGE_LENGTH];
|
||||
i2p::stream::SendBufferQueue m_SendQueue;
|
||||
};
|
||||
typedef void (I2CPSession::*I2CPMessageHandler)(const uint8_t * buf, size_t len);
|
||||
I2CPSession(I2CPServer &owner, std::shared_ptr <boost::asio::ip::tcp::socket> socket);
|
||||
|
||||
class I2CPServer: private i2p::util::RunnableService
|
||||
{
|
||||
public:
|
||||
~I2CPSession();
|
||||
|
||||
I2CPServer (const std::string& interface, int port, bool isSingleThread);
|
||||
~I2CPServer ();
|
||||
void Start();
|
||||
|
||||
void Start ();
|
||||
void Stop ();
|
||||
boost::asio::io_service& GetService () { return GetIOService (); };
|
||||
bool IsSingleThread () const { return m_IsSingleThread; };
|
||||
void Stop();
|
||||
|
||||
bool InsertSession (std::shared_ptr<I2CPSession> session);
|
||||
void RemoveSession (uint16_t sessionID);
|
||||
std::shared_ptr<I2CPSession> FindSessionByIdentHash (const i2p::data::IdentHash& ident) const;
|
||||
uint16_t GetSessionID() const { return m_SessionID; };
|
||||
|
||||
private:
|
||||
std::shared_ptr<const I2CPDestination> GetDestination() const { return m_Destination; };
|
||||
|
||||
void Run ();
|
||||
// called from I2CPDestination
|
||||
void SendI2CPMessage(uint8_t type, const uint8_t *payload, size_t len);
|
||||
|
||||
void Accept ();
|
||||
void SendMessagePayloadMessage(const uint8_t *payload, size_t len);
|
||||
|
||||
void HandleAccept(const boost::system::error_code& ecode, std::shared_ptr<boost::asio::ip::tcp::socket> socket);
|
||||
void SendMessageStatusMessage(uint32_t nonce, I2CPMessageStatus status);
|
||||
|
||||
private:
|
||||
// message handlers
|
||||
void GetDateMessageHandler(const uint8_t *buf, size_t len);
|
||||
|
||||
bool m_IsSingleThread;
|
||||
I2CPMessageHandler m_MessagesHandlers[256];
|
||||
std::map<uint16_t, std::shared_ptr<I2CPSession> > m_Sessions;
|
||||
void CreateSessionMessageHandler(const uint8_t *buf, size_t len);
|
||||
|
||||
boost::asio::ip::tcp::acceptor m_Acceptor;
|
||||
void DestroySessionMessageHandler(const uint8_t *buf, size_t len);
|
||||
|
||||
public:
|
||||
void ReconfigureSessionMessageHandler(const uint8_t *buf, size_t len);
|
||||
|
||||
const decltype(m_MessagesHandlers)& GetMessagesHandlers () const { return m_MessagesHandlers; };
|
||||
void CreateLeaseSetMessageHandler(const uint8_t *buf, size_t len);
|
||||
|
||||
// for HTTP
|
||||
const decltype(m_Sessions)& GetSessions () const { return m_Sessions; };
|
||||
};
|
||||
}
|
||||
void CreateLeaseSet2MessageHandler(const uint8_t *buf, size_t len);
|
||||
|
||||
void SendMessageMessageHandler(const uint8_t *buf, size_t len);
|
||||
|
||||
void SendMessageExpiresMessageHandler(const uint8_t *buf, size_t len);
|
||||
|
||||
void HostLookupMessageHandler(const uint8_t *buf, size_t len);
|
||||
|
||||
void DestLookupMessageHandler(const uint8_t *buf, size_t len);
|
||||
|
||||
void GetBandwidthLimitsMessageHandler(const uint8_t *buf, size_t len);
|
||||
|
||||
private:
|
||||
|
||||
void ReadProtocolByte();
|
||||
|
||||
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);
|
||||
|
||||
std::string ExtractString(const uint8_t *buf, size_t len);
|
||||
|
||||
size_t PutString(uint8_t *buf, size_t len, const std::string &str);
|
||||
|
||||
void ExtractMapping(const uint8_t *buf, size_t len, std::map <std::string, std::string> &mapping);
|
||||
|
||||
void SendSessionStatusMessage(I2CPSessionStatus status);
|
||||
|
||||
void SendHostReplyMessage(uint32_t requestID, std::shared_ptr<const i2p::data::IdentityEx> identity);
|
||||
|
||||
private:
|
||||
|
||||
I2CPServer &m_Owner;
|
||||
std::shared_ptr <boost::asio::ip::tcp::socket> m_Socket;
|
||||
uint8_t m_Header[I2CP_HEADER_SIZE], m_Payload[I2CP_MAX_MESSAGE_LENGTH];
|
||||
size_t m_PayloadLen;
|
||||
|
||||
std::shared_ptr <I2CPDestination> m_Destination;
|
||||
uint16_t m_SessionID;
|
||||
uint32_t m_MessageID;
|
||||
bool m_IsSendAccepted;
|
||||
|
||||
// to client
|
||||
bool m_IsSending;
|
||||
uint8_t m_SendBuffer[I2CP_MAX_MESSAGE_LENGTH];
|
||||
i2p::stream::SendBufferQueue m_SendQueue;
|
||||
};
|
||||
|
||||
typedef void (I2CPSession::*I2CPMessageHandler)(const uint8_t *buf, size_t len);
|
||||
|
||||
class I2CPServer : private i2p::util::RunnableService {
|
||||
public:
|
||||
|
||||
I2CPServer(const std::string &interface, int port, bool isSingleThread);
|
||||
|
||||
~I2CPServer();
|
||||
|
||||
void Start();
|
||||
|
||||
void Stop();
|
||||
|
||||
boost::asio::io_service &GetService() { return GetIOService(); };
|
||||
|
||||
bool IsSingleThread() const { return m_IsSingleThread; };
|
||||
|
||||
bool InsertSession(std::shared_ptr <I2CPSession> session);
|
||||
|
||||
void RemoveSession(uint16_t sessionID);
|
||||
|
||||
std::shared_ptr <I2CPSession> FindSessionByIdentHash(const i2p::data::IdentHash &ident) const;
|
||||
|
||||
private:
|
||||
|
||||
void Run();
|
||||
|
||||
void Accept();
|
||||
|
||||
void
|
||||
HandleAccept(const boost::system::error_code &ecode, std::shared_ptr <boost::asio::ip::tcp::socket> socket);
|
||||
|
||||
private:
|
||||
|
||||
bool m_IsSingleThread;
|
||||
I2CPMessageHandler m_MessagesHandlers[256];
|
||||
std::map <uint16_t, std::shared_ptr<I2CPSession>> m_Sessions;
|
||||
|
||||
boost::asio::ip::tcp::acceptor m_Acceptor;
|
||||
|
||||
public:
|
||||
|
||||
const decltype(m_MessagesHandlers)
|
||||
&
|
||||
|
||||
GetMessagesHandlers() const { return m_MessagesHandlers; };
|
||||
|
||||
// for HTTP
|
||||
const decltype(m_Sessions)
|
||||
&
|
||||
|
||||
GetSessions() const { return m_Sessions; };
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -12,331 +12,280 @@
|
|||
#include "I2PService.h"
|
||||
#include <boost/asio/error.hpp>
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
namespace client
|
||||
{
|
||||
static const i2p::data::SigningKeyType I2P_SERVICE_DEFAULT_KEY_TYPE = i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519;
|
||||
namespace i2p {
|
||||
namespace client {
|
||||
static const i2p::data::SigningKeyType I2P_SERVICE_DEFAULT_KEY_TYPE = i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519;
|
||||
|
||||
I2PService::I2PService (std::shared_ptr<ClientDestination> localDestination):
|
||||
m_LocalDestination (localDestination ? localDestination :
|
||||
i2p::client::context.CreateNewLocalDestination (false, I2P_SERVICE_DEFAULT_KEY_TYPE)),
|
||||
m_ReadyTimer(m_LocalDestination->GetService()),
|
||||
m_ReadyTimerTriggered(false),
|
||||
m_ConnectTimeout(0),
|
||||
isUpdated (true)
|
||||
{
|
||||
m_LocalDestination->Acquire ();
|
||||
}
|
||||
I2PService::I2PService(std::shared_ptr <ClientDestination> localDestination) :
|
||||
m_LocalDestination(localDestination ? localDestination :
|
||||
i2p::client::context.CreateNewLocalDestination(false, I2P_SERVICE_DEFAULT_KEY_TYPE)),
|
||||
m_ReadyTimer(m_LocalDestination->GetService()),
|
||||
m_ReadyTimerTriggered(false),
|
||||
m_ConnectTimeout(0),
|
||||
isUpdated(true) {
|
||||
m_LocalDestination->Acquire();
|
||||
}
|
||||
|
||||
I2PService::I2PService (i2p::data::SigningKeyType kt):
|
||||
m_LocalDestination (i2p::client::context.CreateNewLocalDestination (false, kt)),
|
||||
m_ReadyTimer(m_LocalDestination->GetService()),
|
||||
m_ConnectTimeout(0),
|
||||
isUpdated (true)
|
||||
{
|
||||
m_LocalDestination->Acquire ();
|
||||
}
|
||||
I2PService::I2PService(i2p::data::SigningKeyType kt) :
|
||||
m_LocalDestination(i2p::client::context.CreateNewLocalDestination(false, kt)),
|
||||
m_ReadyTimer(m_LocalDestination->GetService()),
|
||||
m_ConnectTimeout(0),
|
||||
isUpdated(true) {
|
||||
m_LocalDestination->Acquire();
|
||||
}
|
||||
|
||||
I2PService::~I2PService ()
|
||||
{
|
||||
ClearHandlers ();
|
||||
if (m_LocalDestination) m_LocalDestination->Release ();
|
||||
}
|
||||
I2PService::~I2PService() {
|
||||
ClearHandlers();
|
||||
if (m_LocalDestination) m_LocalDestination->Release();
|
||||
}
|
||||
|
||||
void I2PService::ClearHandlers ()
|
||||
{
|
||||
if(m_ConnectTimeout)
|
||||
m_ReadyTimer.cancel();
|
||||
std::unique_lock<std::mutex> l(m_HandlersMutex);
|
||||
for (auto it: m_Handlers)
|
||||
it->Terminate ();
|
||||
m_Handlers.clear();
|
||||
}
|
||||
void I2PService::ClearHandlers() {
|
||||
if (m_ConnectTimeout)
|
||||
m_ReadyTimer.cancel();
|
||||
std::unique_lock <std::mutex> l(m_HandlersMutex);
|
||||
for (auto it: m_Handlers)
|
||||
it->Terminate();
|
||||
m_Handlers.clear();
|
||||
}
|
||||
|
||||
void I2PService::SetConnectTimeout(uint32_t timeout)
|
||||
{
|
||||
m_ConnectTimeout = timeout;
|
||||
}
|
||||
void I2PService::SetConnectTimeout(uint32_t timeout) {
|
||||
m_ConnectTimeout = timeout;
|
||||
}
|
||||
|
||||
void I2PService::AddReadyCallback(ReadyCallback cb)
|
||||
{
|
||||
uint32_t now = i2p::util::GetSecondsSinceEpoch();
|
||||
uint32_t tm = (m_ConnectTimeout) ? now + m_ConnectTimeout : NEVER_TIMES_OUT;
|
||||
void I2PService::AddReadyCallback(ReadyCallback cb) {
|
||||
uint32_t now = i2p::util::GetSecondsSinceEpoch();
|
||||
uint32_t tm = (m_ConnectTimeout) ? now + m_ConnectTimeout : NEVER_TIMES_OUT;
|
||||
|
||||
LogPrint(eLogDebug, "I2PService::AddReadyCallback() ", tm, " ", now);
|
||||
m_ReadyCallbacks.push_back({cb, tm});
|
||||
if (!m_ReadyTimerTriggered) TriggerReadyCheckTimer();
|
||||
}
|
||||
LogPrint(eLogDebug, "I2PService::AddReadyCallback() ", tm, " ", now);
|
||||
m_ReadyCallbacks.push_back({cb, tm});
|
||||
if (!m_ReadyTimerTriggered) TriggerReadyCheckTimer();
|
||||
}
|
||||
|
||||
void I2PService::TriggerReadyCheckTimer()
|
||||
{
|
||||
m_ReadyTimer.expires_from_now(boost::posix_time::seconds (1));
|
||||
m_ReadyTimer.async_wait(std::bind(&I2PService::HandleReadyCheckTimer, shared_from_this (), std::placeholders::_1));
|
||||
m_ReadyTimerTriggered = true;
|
||||
void I2PService::TriggerReadyCheckTimer() {
|
||||
m_ReadyTimer.expires_from_now(boost::posix_time::seconds(1));
|
||||
m_ReadyTimer.async_wait(
|
||||
std::bind(&I2PService::HandleReadyCheckTimer, shared_from_this(), std::placeholders::_1));
|
||||
m_ReadyTimerTriggered = true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void I2PService::HandleReadyCheckTimer(const boost::system::error_code &ec)
|
||||
{
|
||||
if(ec || m_LocalDestination->IsReady())
|
||||
{
|
||||
for(auto & itr : m_ReadyCallbacks)
|
||||
itr.first(ec);
|
||||
m_ReadyCallbacks.clear();
|
||||
}
|
||||
else if(!m_LocalDestination->IsReady())
|
||||
{
|
||||
// expire timed out requests
|
||||
uint32_t now = i2p::util::GetSecondsSinceEpoch ();
|
||||
auto itr = m_ReadyCallbacks.begin();
|
||||
while(itr != m_ReadyCallbacks.end())
|
||||
{
|
||||
if(itr->second != NEVER_TIMES_OUT && now >= itr->second)
|
||||
{
|
||||
itr->first(boost::asio::error::timed_out);
|
||||
itr = m_ReadyCallbacks.erase(itr);
|
||||
}
|
||||
else
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
if(!ec && m_ReadyCallbacks.size())
|
||||
TriggerReadyCheckTimer();
|
||||
else
|
||||
m_ReadyTimerTriggered = false;
|
||||
}
|
||||
void I2PService::HandleReadyCheckTimer(const boost::system::error_code &ec) {
|
||||
if (ec || m_LocalDestination->IsReady()) {
|
||||
for (auto &itr: m_ReadyCallbacks)
|
||||
itr.first(ec);
|
||||
m_ReadyCallbacks.clear();
|
||||
} else if (!m_LocalDestination->IsReady()) {
|
||||
// expire timed out requests
|
||||
uint32_t now = i2p::util::GetSecondsSinceEpoch();
|
||||
auto itr = m_ReadyCallbacks.begin();
|
||||
while (itr != m_ReadyCallbacks.end()) {
|
||||
if (itr->second != NEVER_TIMES_OUT && now >= itr->second) {
|
||||
itr->first(boost::asio::error::timed_out);
|
||||
itr = m_ReadyCallbacks.erase(itr);
|
||||
} else
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
if (!ec && m_ReadyCallbacks.size())
|
||||
TriggerReadyCheckTimer();
|
||||
else
|
||||
m_ReadyTimerTriggered = false;
|
||||
}
|
||||
|
||||
void I2PService::CreateStream (StreamRequestComplete streamRequestComplete, const std::string& dest, int port) {
|
||||
assert(streamRequestComplete);
|
||||
auto address = i2p::client::context.GetAddressBook ().GetAddress (dest);
|
||||
if (address)
|
||||
CreateStream(streamRequestComplete, address, port);
|
||||
else
|
||||
{
|
||||
LogPrint (eLogWarning, "I2PService: Remote destination not found: ", dest);
|
||||
streamRequestComplete (nullptr);
|
||||
}
|
||||
}
|
||||
void I2PService::CreateStream(StreamRequestComplete streamRequestComplete, const std::string &dest, int port) {
|
||||
assert(streamRequestComplete);
|
||||
auto address = i2p::client::context.GetAddressBook().GetAddress(dest);
|
||||
if (address)
|
||||
CreateStream(streamRequestComplete, address, port);
|
||||
else {
|
||||
LogPrint(eLogWarning, "I2PService: Remote destination not found: ", dest);
|
||||
streamRequestComplete(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void I2PService::CreateStream(StreamRequestComplete streamRequestComplete, std::shared_ptr<const Address> address, int port)
|
||||
{
|
||||
if(m_ConnectTimeout && !m_LocalDestination->IsReady())
|
||||
{
|
||||
AddReadyCallback([this, streamRequestComplete, address, port] (const boost::system::error_code & ec)
|
||||
{
|
||||
if(ec)
|
||||
{
|
||||
LogPrint(eLogWarning, "I2PService::CreateStream() ", ec.message());
|
||||
streamRequestComplete(nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (address->IsIdentHash ())
|
||||
this->m_LocalDestination->CreateStream(streamRequestComplete, address->identHash, port);
|
||||
else
|
||||
this->m_LocalDestination->CreateStream (streamRequestComplete, address->blindedPublicKey, port);
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
if (address->IsIdentHash ())
|
||||
m_LocalDestination->CreateStream (streamRequestComplete, address->identHash, port);
|
||||
else
|
||||
m_LocalDestination->CreateStream (streamRequestComplete, address->blindedPublicKey, port);
|
||||
}
|
||||
}
|
||||
void
|
||||
I2PService::CreateStream(StreamRequestComplete streamRequestComplete, std::shared_ptr<const Address> address,
|
||||
int port) {
|
||||
if (m_ConnectTimeout && !m_LocalDestination->IsReady()) {
|
||||
AddReadyCallback([this, streamRequestComplete, address, port](const boost::system::error_code &ec) {
|
||||
if (ec) {
|
||||
LogPrint(eLogWarning, "I2PService::CreateStream() ", ec.message());
|
||||
streamRequestComplete(nullptr);
|
||||
} else {
|
||||
if (address->IsIdentHash())
|
||||
this->m_LocalDestination->CreateStream(streamRequestComplete, address->identHash, port);
|
||||
else
|
||||
this->m_LocalDestination->CreateStream(streamRequestComplete, address->blindedPublicKey,
|
||||
port);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (address->IsIdentHash())
|
||||
m_LocalDestination->CreateStream(streamRequestComplete, address->identHash, port);
|
||||
else
|
||||
m_LocalDestination->CreateStream(streamRequestComplete, address->blindedPublicKey, port);
|
||||
}
|
||||
}
|
||||
|
||||
TCPIPPipe::TCPIPPipe(I2PService * owner, std::shared_ptr<boost::asio::ip::tcp::socket> upstream, std::shared_ptr<boost::asio::ip::tcp::socket> downstream) : I2PServiceHandler(owner), m_up(upstream), m_down(downstream)
|
||||
{
|
||||
boost::asio::socket_base::receive_buffer_size option(TCP_IP_PIPE_BUFFER_SIZE);
|
||||
upstream->set_option(option);
|
||||
downstream->set_option(option);
|
||||
}
|
||||
TCPIPPipe::TCPIPPipe(I2PService *owner, std::shared_ptr <boost::asio::ip::tcp::socket> upstream,
|
||||
std::shared_ptr <boost::asio::ip::tcp::socket> downstream) : I2PServiceHandler(owner),
|
||||
m_up(upstream),
|
||||
m_down(downstream) {
|
||||
boost::asio::socket_base::receive_buffer_size option(TCP_IP_PIPE_BUFFER_SIZE);
|
||||
upstream->set_option(option);
|
||||
downstream->set_option(option);
|
||||
}
|
||||
|
||||
TCPIPPipe::~TCPIPPipe()
|
||||
{
|
||||
Terminate();
|
||||
}
|
||||
TCPIPPipe::~TCPIPPipe() {
|
||||
Terminate();
|
||||
}
|
||||
|
||||
void TCPIPPipe::Start()
|
||||
{
|
||||
AsyncReceiveUpstream();
|
||||
AsyncReceiveDownstream();
|
||||
}
|
||||
void TCPIPPipe::Start() {
|
||||
AsyncReceiveUpstream();
|
||||
AsyncReceiveDownstream();
|
||||
}
|
||||
|
||||
void TCPIPPipe::Terminate()
|
||||
{
|
||||
if(Kill()) return;
|
||||
if (m_up)
|
||||
{
|
||||
if (m_up->is_open())
|
||||
m_up->close();
|
||||
m_up = nullptr;
|
||||
}
|
||||
if (m_down)
|
||||
{
|
||||
if (m_down->is_open())
|
||||
m_down->close();
|
||||
m_down = nullptr;
|
||||
}
|
||||
Done(shared_from_this());
|
||||
}
|
||||
void TCPIPPipe::Terminate() {
|
||||
if (Kill()) return;
|
||||
if (m_up) {
|
||||
if (m_up->is_open())
|
||||
m_up->close();
|
||||
m_up = nullptr;
|
||||
}
|
||||
if (m_down) {
|
||||
if (m_down->is_open())
|
||||
m_down->close();
|
||||
m_down = nullptr;
|
||||
}
|
||||
Done(shared_from_this());
|
||||
}
|
||||
|
||||
void TCPIPPipe::AsyncReceiveUpstream()
|
||||
{
|
||||
if (m_up)
|
||||
{
|
||||
m_up->async_read_some(boost::asio::buffer(m_upstream_to_down_buf, TCP_IP_PIPE_BUFFER_SIZE),
|
||||
std::bind(&TCPIPPipe::HandleUpstreamReceived, shared_from_this(),
|
||||
std::placeholders::_1, std::placeholders::_2));
|
||||
}
|
||||
else
|
||||
LogPrint(eLogError, "TCPIPPipe: Upstream receive: No socket");
|
||||
}
|
||||
void TCPIPPipe::AsyncReceiveUpstream() {
|
||||
if (m_up) {
|
||||
m_up->async_read_some(boost::asio::buffer(m_upstream_to_down_buf, TCP_IP_PIPE_BUFFER_SIZE),
|
||||
std::bind(&TCPIPPipe::HandleUpstreamReceived, shared_from_this(),
|
||||
std::placeholders::_1, std::placeholders::_2));
|
||||
} else
|
||||
LogPrint(eLogError, "TCPIPPipe: Upstream receive: No socket");
|
||||
}
|
||||
|
||||
void TCPIPPipe::AsyncReceiveDownstream()
|
||||
{
|
||||
if (m_down) {
|
||||
m_down->async_read_some(boost::asio::buffer(m_downstream_to_up_buf, TCP_IP_PIPE_BUFFER_SIZE),
|
||||
std::bind(&TCPIPPipe::HandleDownstreamReceived, shared_from_this(),
|
||||
std::placeholders::_1, std::placeholders::_2));
|
||||
}
|
||||
else
|
||||
LogPrint(eLogError, "TCPIPPipe: Downstream receive: No socket");
|
||||
}
|
||||
void TCPIPPipe::AsyncReceiveDownstream() {
|
||||
if (m_down) {
|
||||
m_down->async_read_some(boost::asio::buffer(m_downstream_to_up_buf, TCP_IP_PIPE_BUFFER_SIZE),
|
||||
std::bind(&TCPIPPipe::HandleDownstreamReceived, shared_from_this(),
|
||||
std::placeholders::_1, std::placeholders::_2));
|
||||
} else
|
||||
LogPrint(eLogError, "TCPIPPipe: Downstream receive: No socket");
|
||||
}
|
||||
|
||||
void TCPIPPipe::UpstreamWrite(size_t len)
|
||||
{
|
||||
if (m_up)
|
||||
{
|
||||
LogPrint(eLogDebug, "TCPIPPipe: Upstream: ", (int) len, " bytes written");
|
||||
boost::asio::async_write(*m_up, boost::asio::buffer(m_upstream_buf, len),
|
||||
boost::asio::transfer_all(),
|
||||
std::bind(&TCPIPPipe::HandleUpstreamWrite,
|
||||
shared_from_this(),
|
||||
std::placeholders::_1));
|
||||
}
|
||||
else
|
||||
LogPrint(eLogError, "TCPIPPipe: Upstream write: no socket");
|
||||
}
|
||||
void TCPIPPipe::UpstreamWrite(size_t len) {
|
||||
if (m_up) {
|
||||
LogPrint(eLogDebug, "TCPIPPipe: Upstream: ", (int) len, " bytes written");
|
||||
boost::asio::async_write(*m_up, boost::asio::buffer(m_upstream_buf, len),
|
||||
boost::asio::transfer_all(),
|
||||
std::bind(&TCPIPPipe::HandleUpstreamWrite,
|
||||
shared_from_this(),
|
||||
std::placeholders::_1));
|
||||
} else
|
||||
LogPrint(eLogError, "TCPIPPipe: Upstream write: no socket");
|
||||
}
|
||||
|
||||
void TCPIPPipe::DownstreamWrite(size_t len)
|
||||
{
|
||||
if (m_down)
|
||||
{
|
||||
LogPrint(eLogDebug, "TCPIPPipe: Downstream: ", (int) len, " bytes written");
|
||||
boost::asio::async_write(*m_down, boost::asio::buffer(m_downstream_buf, len),
|
||||
boost::asio::transfer_all(),
|
||||
std::bind(&TCPIPPipe::HandleDownstreamWrite,
|
||||
shared_from_this(),
|
||||
std::placeholders::_1));
|
||||
}
|
||||
else
|
||||
LogPrint(eLogError, "TCPIPPipe: Downstream write: No socket");
|
||||
}
|
||||
void TCPIPPipe::DownstreamWrite(size_t len) {
|
||||
if (m_down) {
|
||||
LogPrint(eLogDebug, "TCPIPPipe: Downstream: ", (int) len, " bytes written");
|
||||
boost::asio::async_write(*m_down, boost::asio::buffer(m_downstream_buf, len),
|
||||
boost::asio::transfer_all(),
|
||||
std::bind(&TCPIPPipe::HandleDownstreamWrite,
|
||||
shared_from_this(),
|
||||
std::placeholders::_1));
|
||||
} else
|
||||
LogPrint(eLogError, "TCPIPPipe: Downstream write: No socket");
|
||||
}
|
||||
|
||||
|
||||
void TCPIPPipe::HandleDownstreamReceived(const boost::system::error_code & ecode, std::size_t bytes_transfered)
|
||||
{
|
||||
LogPrint(eLogDebug, "TCPIPPipe: Downstream: ", (int) bytes_transfered, " bytes received");
|
||||
if (ecode)
|
||||
{
|
||||
LogPrint(eLogError, "TCPIPPipe: Downstream read error:" , ecode.message());
|
||||
if (ecode != boost::asio::error::operation_aborted)
|
||||
Terminate();
|
||||
} else {
|
||||
if (bytes_transfered > 0 )
|
||||
memcpy(m_upstream_buf, m_downstream_to_up_buf, bytes_transfered);
|
||||
UpstreamWrite(bytes_transfered);
|
||||
}
|
||||
}
|
||||
void TCPIPPipe::HandleDownstreamReceived(const boost::system::error_code &ecode, std::size_t bytes_transfered) {
|
||||
LogPrint(eLogDebug, "TCPIPPipe: Downstream: ", (int) bytes_transfered, " bytes received");
|
||||
if (ecode) {
|
||||
LogPrint(eLogError, "TCPIPPipe: Downstream read error:", ecode.message());
|
||||
if (ecode != boost::asio::error::operation_aborted)
|
||||
Terminate();
|
||||
} else {
|
||||
if (bytes_transfered > 0)
|
||||
memcpy(m_upstream_buf, m_downstream_to_up_buf, bytes_transfered);
|
||||
UpstreamWrite(bytes_transfered);
|
||||
}
|
||||
}
|
||||
|
||||
void TCPIPPipe::HandleDownstreamWrite(const boost::system::error_code & ecode) {
|
||||
if (ecode)
|
||||
{
|
||||
LogPrint(eLogError, "TCPIPPipe: Downstream write error:" , ecode.message());
|
||||
if (ecode != boost::asio::error::operation_aborted)
|
||||
Terminate();
|
||||
}
|
||||
else
|
||||
AsyncReceiveUpstream();
|
||||
}
|
||||
void TCPIPPipe::HandleDownstreamWrite(const boost::system::error_code &ecode) {
|
||||
if (ecode) {
|
||||
LogPrint(eLogError, "TCPIPPipe: Downstream write error:", ecode.message());
|
||||
if (ecode != boost::asio::error::operation_aborted)
|
||||
Terminate();
|
||||
} else
|
||||
AsyncReceiveUpstream();
|
||||
}
|
||||
|
||||
void TCPIPPipe::HandleUpstreamWrite(const boost::system::error_code & ecode) {
|
||||
if (ecode)
|
||||
{
|
||||
LogPrint(eLogError, "TCPIPPipe: Upstream write error:" , ecode.message());
|
||||
if (ecode != boost::asio::error::operation_aborted)
|
||||
Terminate();
|
||||
}
|
||||
else
|
||||
AsyncReceiveDownstream();
|
||||
}
|
||||
void TCPIPPipe::HandleUpstreamWrite(const boost::system::error_code &ecode) {
|
||||
if (ecode) {
|
||||
LogPrint(eLogError, "TCPIPPipe: Upstream write error:", ecode.message());
|
||||
if (ecode != boost::asio::error::operation_aborted)
|
||||
Terminate();
|
||||
} else
|
||||
AsyncReceiveDownstream();
|
||||
}
|
||||
|
||||
void TCPIPPipe::HandleUpstreamReceived(const boost::system::error_code & ecode, std::size_t bytes_transfered)
|
||||
{
|
||||
LogPrint(eLogDebug, "TCPIPPipe: Upstream ", (int)bytes_transfered, " bytes received");
|
||||
if (ecode)
|
||||
{
|
||||
LogPrint(eLogError, "TCPIPPipe: Upstream read error:" , ecode.message());
|
||||
if (ecode != boost::asio::error::operation_aborted)
|
||||
Terminate();
|
||||
} else {
|
||||
if (bytes_transfered > 0 )
|
||||
memcpy(m_downstream_buf, m_upstream_to_down_buf, bytes_transfered);
|
||||
DownstreamWrite(bytes_transfered);
|
||||
}
|
||||
}
|
||||
void TCPIPPipe::HandleUpstreamReceived(const boost::system::error_code &ecode, std::size_t bytes_transfered) {
|
||||
LogPrint(eLogDebug, "TCPIPPipe: Upstream ", (int) bytes_transfered, " bytes received");
|
||||
if (ecode) {
|
||||
LogPrint(eLogError, "TCPIPPipe: Upstream read error:", ecode.message());
|
||||
if (ecode != boost::asio::error::operation_aborted)
|
||||
Terminate();
|
||||
} else {
|
||||
if (bytes_transfered > 0)
|
||||
memcpy(m_downstream_buf, m_upstream_to_down_buf, bytes_transfered);
|
||||
DownstreamWrite(bytes_transfered);
|
||||
}
|
||||
}
|
||||
|
||||
void TCPIPAcceptor::Start ()
|
||||
{
|
||||
m_Acceptor.reset (new boost::asio::ip::tcp::acceptor (GetService (), m_LocalEndpoint));
|
||||
// update the local end point in case port has been set zero and got updated now
|
||||
m_LocalEndpoint = m_Acceptor->local_endpoint();
|
||||
m_Acceptor->listen ();
|
||||
Accept ();
|
||||
}
|
||||
void TCPIPAcceptor::Start() {
|
||||
m_Acceptor.reset(new boost::asio::ip::tcp::acceptor(GetService(), m_LocalEndpoint));
|
||||
// update the local end point in case port has been set zero and got updated now
|
||||
m_LocalEndpoint = m_Acceptor->local_endpoint();
|
||||
m_Acceptor->listen();
|
||||
Accept();
|
||||
}
|
||||
|
||||
void TCPIPAcceptor::Stop ()
|
||||
{
|
||||
if (m_Acceptor)
|
||||
{
|
||||
m_Acceptor->close();
|
||||
m_Acceptor.reset (nullptr);
|
||||
}
|
||||
m_Timer.cancel ();
|
||||
ClearHandlers();
|
||||
}
|
||||
void TCPIPAcceptor::Stop() {
|
||||
if (m_Acceptor) {
|
||||
m_Acceptor->close();
|
||||
m_Acceptor.reset(nullptr);
|
||||
}
|
||||
m_Timer.cancel();
|
||||
ClearHandlers();
|
||||
}
|
||||
|
||||
void TCPIPAcceptor::Accept ()
|
||||
{
|
||||
auto newSocket = std::make_shared<boost::asio::ip::tcp::socket> (GetService ());
|
||||
m_Acceptor->async_accept (*newSocket, std::bind (&TCPIPAcceptor::HandleAccept, this,
|
||||
std::placeholders::_1, newSocket));
|
||||
}
|
||||
void TCPIPAcceptor::Accept() {
|
||||
auto newSocket = std::make_shared<boost::asio::ip::tcp::socket>(GetService());
|
||||
m_Acceptor->async_accept(*newSocket, std::bind(&TCPIPAcceptor::HandleAccept, this,
|
||||
std::placeholders::_1, newSocket));
|
||||
}
|
||||
|
||||
void TCPIPAcceptor::HandleAccept (const boost::system::error_code& ecode, std::shared_ptr<boost::asio::ip::tcp::socket> socket)
|
||||
{
|
||||
if (!ecode)
|
||||
{
|
||||
LogPrint(eLogDebug, "I2PService: ", GetName(), " accepted");
|
||||
auto handler = CreateHandler(socket);
|
||||
if (handler)
|
||||
{
|
||||
AddHandler(handler);
|
||||
handler->Handle();
|
||||
}
|
||||
else
|
||||
socket->close();
|
||||
Accept();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ecode != boost::asio::error::operation_aborted)
|
||||
LogPrint (eLogError, "I2PService: ", GetName(), " closing socket on accept because: ", ecode.message ());
|
||||
}
|
||||
}
|
||||
}
|
||||
void TCPIPAcceptor::HandleAccept(const boost::system::error_code &ecode,
|
||||
std::shared_ptr <boost::asio::ip::tcp::socket> socket) {
|
||||
if (!ecode) {
|
||||
LogPrint(eLogDebug, "I2PService: ", GetName(), " accepted");
|
||||
auto handler = CreateHandler(socket);
|
||||
if (handler) {
|
||||
AddHandler(handler);
|
||||
handler->Handle();
|
||||
} else
|
||||
socket->close();
|
||||
Accept();
|
||||
} else {
|
||||
if (ecode != boost::asio::error::operation_aborted)
|
||||
LogPrint(eLogError, "I2PService: ", GetName(), " closing socket on accept because: ",
|
||||
ecode.message());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,174 +18,202 @@
|
|||
#include "Identity.h"
|
||||
#include "AddressBook.h"
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
namespace client
|
||||
{
|
||||
class I2PServiceHandler;
|
||||
class I2PService : public std::enable_shared_from_this<I2PService>
|
||||
{
|
||||
public:
|
||||
namespace i2p {
|
||||
namespace client {
|
||||
class I2PServiceHandler;
|
||||
|
||||
typedef std::function<void(const boost::system::error_code &)> ReadyCallback;
|
||||
class I2PService : public std::enable_shared_from_this<I2PService> {
|
||||
public:
|
||||
|
||||
public:
|
||||
typedef std::function<void(const boost::system::error_code &)> ReadyCallback;
|
||||
|
||||
I2PService (std::shared_ptr<ClientDestination> localDestination = nullptr);
|
||||
I2PService (i2p::data::SigningKeyType kt);
|
||||
virtual ~I2PService ();
|
||||
public:
|
||||
|
||||
inline void AddHandler (std::shared_ptr<I2PServiceHandler> conn)
|
||||
{
|
||||
std::unique_lock<std::mutex> l(m_HandlersMutex);
|
||||
m_Handlers.insert(conn);
|
||||
}
|
||||
inline void RemoveHandler (std::shared_ptr<I2PServiceHandler> conn)
|
||||
{
|
||||
std::unique_lock<std::mutex> l(m_HandlersMutex);
|
||||
m_Handlers.erase(conn);
|
||||
}
|
||||
void ClearHandlers ();
|
||||
I2PService(std::shared_ptr <ClientDestination> localDestination = nullptr);
|
||||
|
||||
void SetConnectTimeout(uint32_t timeout);
|
||||
I2PService(i2p::data::SigningKeyType kt);
|
||||
|
||||
void AddReadyCallback(ReadyCallback cb);
|
||||
virtual ~I2PService();
|
||||
|
||||
inline std::shared_ptr<ClientDestination> GetLocalDestination () { return m_LocalDestination; }
|
||||
inline std::shared_ptr<const ClientDestination> GetLocalDestination () const { return m_LocalDestination; }
|
||||
inline void SetLocalDestination (std::shared_ptr<ClientDestination> dest)
|
||||
{
|
||||
if (m_LocalDestination) m_LocalDestination->Release ();
|
||||
if (dest) dest->Acquire ();
|
||||
m_LocalDestination = dest;
|
||||
}
|
||||
void CreateStream (StreamRequestComplete streamRequestComplete, const std::string& dest, int port = 0);
|
||||
void CreateStream(StreamRequestComplete complete, std::shared_ptr<const Address> address, int port);
|
||||
inline boost::asio::io_service& GetService () { return m_LocalDestination->GetService (); }
|
||||
inline void AddHandler(std::shared_ptr <I2PServiceHandler> conn) {
|
||||
std::unique_lock <std::mutex> l(m_HandlersMutex);
|
||||
m_Handlers.insert(conn);
|
||||
}
|
||||
|
||||
virtual void Start () = 0;
|
||||
virtual void Stop () = 0;
|
||||
inline void RemoveHandler(std::shared_ptr <I2PServiceHandler> conn) {
|
||||
std::unique_lock <std::mutex> l(m_HandlersMutex);
|
||||
m_Handlers.erase(conn);
|
||||
}
|
||||
|
||||
virtual const char* GetName() { return "Generic I2P Service"; }
|
||||
void ClearHandlers();
|
||||
|
||||
private:
|
||||
void SetConnectTimeout(uint32_t timeout);
|
||||
|
||||
void TriggerReadyCheckTimer();
|
||||
void HandleReadyCheckTimer(const boost::system::error_code & ec);
|
||||
void AddReadyCallback(ReadyCallback cb);
|
||||
|
||||
private:
|
||||
inline std::shared_ptr <ClientDestination> GetLocalDestination() { return m_LocalDestination; }
|
||||
|
||||
std::shared_ptr<ClientDestination> m_LocalDestination;
|
||||
std::unordered_set<std::shared_ptr<I2PServiceHandler> > m_Handlers;
|
||||
std::mutex m_HandlersMutex;
|
||||
std::vector<std::pair<ReadyCallback, uint32_t> > m_ReadyCallbacks;
|
||||
boost::asio::deadline_timer m_ReadyTimer;
|
||||
bool m_ReadyTimerTriggered;
|
||||
uint32_t m_ConnectTimeout;
|
||||
inline std::shared_ptr<const ClientDestination> GetLocalDestination() const { return m_LocalDestination; }
|
||||
|
||||
const size_t NEVER_TIMES_OUT = 0;
|
||||
inline void SetLocalDestination(std::shared_ptr <ClientDestination> dest) {
|
||||
if (m_LocalDestination) m_LocalDestination->Release();
|
||||
if (dest) dest->Acquire();
|
||||
m_LocalDestination = dest;
|
||||
}
|
||||
|
||||
public:
|
||||
void CreateStream(StreamRequestComplete streamRequestComplete, const std::string &dest, int port = 0);
|
||||
|
||||
bool isUpdated; // transient, used during reload only
|
||||
};
|
||||
void CreateStream(StreamRequestComplete complete, std::shared_ptr<const Address> address, int port);
|
||||
|
||||
/*Simple interface for I2PHandlers, allows detection of finalization amongst other things */
|
||||
class I2PServiceHandler
|
||||
{
|
||||
public:
|
||||
inline boost::asio::io_service &GetService() { return m_LocalDestination->GetService(); }
|
||||
|
||||
I2PServiceHandler(I2PService * parent) : m_Service(parent), m_Dead(false) { }
|
||||
virtual ~I2PServiceHandler() { }
|
||||
//If you override this make sure you call it from the children
|
||||
virtual void Handle() {}; //Start handling the socket
|
||||
virtual void Start() = 0;
|
||||
|
||||
void Terminate () { Kill (); };
|
||||
virtual void Stop() = 0;
|
||||
|
||||
protected:
|
||||
virtual const char *GetName() { return "Generic I2P Service"; }
|
||||
|
||||
// Call when terminating or handing over to avoid race conditions
|
||||
inline bool Kill () { return m_Dead.exchange(true); }
|
||||
// Call to know if the handler is dead
|
||||
inline bool Dead () { return m_Dead; }
|
||||
// Call when done to clean up (make sure Kill is called first)
|
||||
inline void Done (std::shared_ptr<I2PServiceHandler> me) { if(m_Service) m_Service->RemoveHandler(me); }
|
||||
// Call to talk with the owner
|
||||
inline I2PService * GetOwner() { return m_Service; }
|
||||
private:
|
||||
|
||||
private:
|
||||
void TriggerReadyCheckTimer();
|
||||
|
||||
I2PService *m_Service;
|
||||
std::atomic<bool> m_Dead; //To avoid cleaning up multiple times
|
||||
};
|
||||
void HandleReadyCheckTimer(const boost::system::error_code &ec);
|
||||
|
||||
const size_t TCP_IP_PIPE_BUFFER_SIZE = 8192 * 8;
|
||||
private:
|
||||
|
||||
// bidirectional pipe for 2 tcp/ip sockets
|
||||
class TCPIPPipe: public I2PServiceHandler, public std::enable_shared_from_this<TCPIPPipe>
|
||||
{
|
||||
public:
|
||||
std::shared_ptr <ClientDestination> m_LocalDestination;
|
||||
std::unordered_set <std::shared_ptr<I2PServiceHandler>> m_Handlers;
|
||||
std::mutex m_HandlersMutex;
|
||||
std::vector <std::pair<ReadyCallback, uint32_t>> m_ReadyCallbacks;
|
||||
boost::asio::deadline_timer m_ReadyTimer;
|
||||
bool m_ReadyTimerTriggered;
|
||||
uint32_t m_ConnectTimeout;
|
||||
|
||||
TCPIPPipe(I2PService * owner, std::shared_ptr<boost::asio::ip::tcp::socket> upstream, std::shared_ptr<boost::asio::ip::tcp::socket> downstream);
|
||||
~TCPIPPipe();
|
||||
void Start();
|
||||
const size_t NEVER_TIMES_OUT = 0;
|
||||
|
||||
protected:
|
||||
public:
|
||||
|
||||
void Terminate();
|
||||
void AsyncReceiveUpstream();
|
||||
void AsyncReceiveDownstream();
|
||||
void HandleUpstreamReceived(const boost::system::error_code & ecode, std::size_t bytes_transferred);
|
||||
void HandleDownstreamReceived(const boost::system::error_code & ecode, std::size_t bytes_transferred);
|
||||
void HandleUpstreamWrite(const boost::system::error_code & ecode);
|
||||
void HandleDownstreamWrite(const boost::system::error_code & ecode);
|
||||
void UpstreamWrite(size_t len);
|
||||
void DownstreamWrite(size_t len);
|
||||
bool isUpdated; // transient, used during reload only
|
||||
};
|
||||
|
||||
private:
|
||||
/*Simple interface for I2PHandlers, allows detection of finalization amongst other things */
|
||||
class I2PServiceHandler {
|
||||
public:
|
||||
|
||||
uint8_t m_upstream_to_down_buf[TCP_IP_PIPE_BUFFER_SIZE], m_downstream_to_up_buf[TCP_IP_PIPE_BUFFER_SIZE];
|
||||
uint8_t m_upstream_buf[TCP_IP_PIPE_BUFFER_SIZE], m_downstream_buf[TCP_IP_PIPE_BUFFER_SIZE];
|
||||
std::shared_ptr<boost::asio::ip::tcp::socket> m_up, m_down;
|
||||
};
|
||||
I2PServiceHandler(I2PService *parent) : m_Service(parent), m_Dead(false) {}
|
||||
|
||||
/* TODO: support IPv6 too */
|
||||
//This is a service that listens for connections on the IP network and interacts with I2P
|
||||
class TCPIPAcceptor: public I2PService
|
||||
{
|
||||
public:
|
||||
virtual ~I2PServiceHandler() {}
|
||||
|
||||
TCPIPAcceptor (const std::string& address, int port, std::shared_ptr<ClientDestination> localDestination = nullptr) :
|
||||
I2PService(localDestination),
|
||||
m_LocalEndpoint (boost::asio::ip::address::from_string(address), port),
|
||||
m_Timer (GetService ()) {}
|
||||
TCPIPAcceptor (const std::string& address, int port, i2p::data::SigningKeyType kt) :
|
||||
I2PService(kt),
|
||||
m_LocalEndpoint (boost::asio::ip::address::from_string(address), port),
|
||||
m_Timer (GetService ()) {}
|
||||
virtual ~TCPIPAcceptor () { TCPIPAcceptor::Stop(); }
|
||||
//If you override this make sure you call it from the children
|
||||
void Start ();
|
||||
//If you override this make sure you call it from the children
|
||||
void Stop ();
|
||||
//If you override this make sure you call it from the children
|
||||
virtual void Handle() {}; //Start handling the socket
|
||||
|
||||
const boost::asio::ip::tcp::endpoint& GetLocalEndpoint () const { return m_LocalEndpoint; };
|
||||
void Terminate() { Kill(); };
|
||||
|
||||
virtual const char* GetName() { return "Generic TCP/IP accepting daemon"; }
|
||||
protected:
|
||||
|
||||
protected:
|
||||
// Call when terminating or handing over to avoid race conditions
|
||||
inline bool Kill() { return m_Dead.exchange(true); }
|
||||
|
||||
virtual std::shared_ptr<I2PServiceHandler> CreateHandler(std::shared_ptr<boost::asio::ip::tcp::socket> socket) = 0;
|
||||
// Call to know if the handler is dead
|
||||
inline bool Dead() { return m_Dead; }
|
||||
|
||||
private:
|
||||
// Call when done to clean up (make sure Kill is called first)
|
||||
inline void Done(std::shared_ptr <I2PServiceHandler> me) { if (m_Service) m_Service->RemoveHandler(me); }
|
||||
|
||||
void Accept();
|
||||
void HandleAccept(const boost::system::error_code& ecode, std::shared_ptr<boost::asio::ip::tcp::socket> socket);
|
||||
boost::asio::ip::tcp::endpoint m_LocalEndpoint;
|
||||
std::unique_ptr<boost::asio::ip::tcp::acceptor> m_Acceptor;
|
||||
boost::asio::deadline_timer m_Timer;
|
||||
};
|
||||
}
|
||||
// Call to talk with the owner
|
||||
inline I2PService *GetOwner() { return m_Service; }
|
||||
|
||||
private:
|
||||
|
||||
I2PService *m_Service;
|
||||
std::atomic<bool> m_Dead; //To avoid cleaning up multiple times
|
||||
};
|
||||
|
||||
const size_t TCP_IP_PIPE_BUFFER_SIZE = 8192 * 8;
|
||||
|
||||
// bidirectional pipe for 2 tcp/ip sockets
|
||||
class TCPIPPipe : public I2PServiceHandler, public std::enable_shared_from_this<TCPIPPipe> {
|
||||
public:
|
||||
|
||||
TCPIPPipe(I2PService *owner, std::shared_ptr <boost::asio::ip::tcp::socket> upstream,
|
||||
std::shared_ptr <boost::asio::ip::tcp::socket> downstream);
|
||||
|
||||
~TCPIPPipe();
|
||||
|
||||
void Start();
|
||||
|
||||
protected:
|
||||
|
||||
void Terminate();
|
||||
|
||||
void AsyncReceiveUpstream();
|
||||
|
||||
void AsyncReceiveDownstream();
|
||||
|
||||
void HandleUpstreamReceived(const boost::system::error_code &ecode, std::size_t bytes_transferred);
|
||||
|
||||
void HandleDownstreamReceived(const boost::system::error_code &ecode, std::size_t bytes_transferred);
|
||||
|
||||
void HandleUpstreamWrite(const boost::system::error_code &ecode);
|
||||
|
||||
void HandleDownstreamWrite(const boost::system::error_code &ecode);
|
||||
|
||||
void UpstreamWrite(size_t len);
|
||||
|
||||
void DownstreamWrite(size_t len);
|
||||
|
||||
private:
|
||||
|
||||
uint8_t m_upstream_to_down_buf[TCP_IP_PIPE_BUFFER_SIZE], m_downstream_to_up_buf[TCP_IP_PIPE_BUFFER_SIZE];
|
||||
uint8_t m_upstream_buf[TCP_IP_PIPE_BUFFER_SIZE], m_downstream_buf[TCP_IP_PIPE_BUFFER_SIZE];
|
||||
std::shared_ptr <boost::asio::ip::tcp::socket> m_up, m_down;
|
||||
};
|
||||
|
||||
/* TODO: support IPv6 too */
|
||||
//This is a service that listens for connections on the IP network and interacts with I2P
|
||||
class TCPIPAcceptor : public I2PService {
|
||||
public:
|
||||
|
||||
TCPIPAcceptor(const std::string &address, int port,
|
||||
std::shared_ptr <ClientDestination> localDestination = nullptr) :
|
||||
I2PService(localDestination),
|
||||
m_LocalEndpoint(boost::asio::ip::address::from_string(address), port),
|
||||
m_Timer(GetService()) {}
|
||||
|
||||
TCPIPAcceptor(const std::string &address, int port, i2p::data::SigningKeyType kt) :
|
||||
I2PService(kt),
|
||||
m_LocalEndpoint(boost::asio::ip::address::from_string(address), port),
|
||||
m_Timer(GetService()) {}
|
||||
|
||||
virtual ~TCPIPAcceptor() { TCPIPAcceptor::Stop(); }
|
||||
|
||||
//If you override this make sure you call it from the children
|
||||
void Start();
|
||||
|
||||
//If you override this make sure you call it from the children
|
||||
void Stop();
|
||||
|
||||
const boost::asio::ip::tcp::endpoint &GetLocalEndpoint() const { return m_LocalEndpoint; };
|
||||
|
||||
virtual const char *GetName() { return "Generic TCP/IP accepting daemon"; }
|
||||
|
||||
protected:
|
||||
|
||||
virtual std::shared_ptr <I2PServiceHandler>
|
||||
CreateHandler(std::shared_ptr <boost::asio::ip::tcp::socket> socket) = 0;
|
||||
|
||||
private:
|
||||
|
||||
void Accept();
|
||||
|
||||
void
|
||||
HandleAccept(const boost::system::error_code &ecode, std::shared_ptr <boost::asio::ip::tcp::socket> socket);
|
||||
|
||||
boost::asio::ip::tcp::endpoint m_LocalEndpoint;
|
||||
std::unique_ptr <boost::asio::ip::tcp::acceptor> m_Acceptor;
|
||||
boost::asio::deadline_timer m_Timer;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -23,390 +23,425 @@
|
|||
#include "I2PService.h"
|
||||
#include "AddressBook.h"
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
namespace client
|
||||
{
|
||||
const size_t I2P_TUNNEL_CONNECTION_BUFFER_SIZE = 65536;
|
||||
const int I2P_TUNNEL_CONNECTION_MAX_IDLE = 3600; // in seconds
|
||||
const int I2P_TUNNEL_DESTINATION_REQUEST_TIMEOUT = 10; // in seconds
|
||||
// for HTTP tunnels
|
||||
const char X_I2P_DEST_HASH[] = "X-I2P-DestHash"; // hash in base64
|
||||
const char X_I2P_DEST_B64[] = "X-I2P-DestB64"; // full address in base64
|
||||
const char X_I2P_DEST_B32[] = "X-I2P-DestB32"; // .b32.i2p address
|
||||
const int I2P_TUNNEL_HTTP_MAX_HEADER_SIZE = 8192;
|
||||
|
||||
class I2PTunnelConnection: public I2PServiceHandler, public std::enable_shared_from_this<I2PTunnelConnection>
|
||||
{
|
||||
public:
|
||||
|
||||
I2PTunnelConnection (I2PService * owner, std::shared_ptr<boost::asio::ip::tcp::socket> socket,
|
||||
std::shared_ptr<const i2p::data::LeaseSet> leaseSet, int port = 0); // to I2P
|
||||
I2PTunnelConnection (I2PService * owner, std::shared_ptr<boost::asio::ip::tcp::socket> socket,
|
||||
std::shared_ptr<i2p::stream::Stream> stream); // to I2P using simplified API
|
||||
I2PTunnelConnection (I2PService * owner, std::shared_ptr<i2p::stream::Stream> stream, std::shared_ptr<boost::asio::ip::tcp::socket> socket,
|
||||
const boost::asio::ip::tcp::endpoint& target, bool quiet = true); // from I2P
|
||||
~I2PTunnelConnection ();
|
||||
void I2PConnect (const uint8_t * msg = nullptr, size_t len = 0);
|
||||
void Connect (bool isUniqueLocal = true);
|
||||
void Connect (const boost::asio::ip::address& localAddress);
|
||||
namespace i2p {
|
||||
namespace client {
|
||||
const size_t I2P_TUNNEL_CONNECTION_BUFFER_SIZE = 65536;
|
||||
const int I2P_TUNNEL_CONNECTION_MAX_IDLE = 3600; // in seconds
|
||||
const int I2P_TUNNEL_DESTINATION_REQUEST_TIMEOUT = 10; // in seconds
|
||||
// for HTTP tunnels
|
||||
const char X_I2P_DEST_HASH[] = "X-I2P-DestHash"; // hash in base64
|
||||
const char X_I2P_DEST_B64[] = "X-I2P-DestB64"; // full address in base64
|
||||
const char X_I2P_DEST_B32[] = "X-I2P-DestB32"; // .b32.i2p address
|
||||
const int I2P_TUNNEL_HTTP_MAX_HEADER_SIZE = 8192;
|
||||
|
||||
protected:
|
||||
class I2PTunnelConnection : public I2PServiceHandler, public std::enable_shared_from_this<I2PTunnelConnection> {
|
||||
public:
|
||||
|
||||
void Terminate ();
|
||||
I2PTunnelConnection(I2PService *owner, std::shared_ptr <boost::asio::ip::tcp::socket> socket,
|
||||
std::shared_ptr<const i2p::data::LeaseSet> leaseSet, int port = 0); // to I2P
|
||||
I2PTunnelConnection(I2PService *owner, std::shared_ptr <boost::asio::ip::tcp::socket> socket,
|
||||
std::shared_ptr <i2p::stream::Stream> stream); // to I2P using simplified API
|
||||
I2PTunnelConnection(I2PService *owner, std::shared_ptr <i2p::stream::Stream> stream,
|
||||
std::shared_ptr <boost::asio::ip::tcp::socket> socket,
|
||||
const boost::asio::ip::tcp::endpoint &target, bool quiet = true); // from I2P
|
||||
~I2PTunnelConnection();
|
||||
|
||||
void Receive ();
|
||||
void HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred);
|
||||
virtual void Write (const uint8_t * buf, size_t len); // can be overloaded
|
||||
void HandleWrite (const boost::system::error_code& ecode);
|
||||
virtual void WriteToStream (const uint8_t * buf, size_t len); // can be overloaded
|
||||
void I2PConnect(const uint8_t *msg = nullptr, size_t len = 0);
|
||||
|
||||
void StreamReceive ();
|
||||
void HandleStreamReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred);
|
||||
void HandleConnect (const boost::system::error_code& ecode);
|
||||
void Connect(bool isUniqueLocal = true);
|
||||
|
||||
std::shared_ptr<const boost::asio::ip::tcp::socket> GetSocket () const { return m_Socket; };
|
||||
void Connect(const boost::asio::ip::address &localAddress);
|
||||
|
||||
private:
|
||||
protected:
|
||||
|
||||
uint8_t m_Buffer[I2P_TUNNEL_CONNECTION_BUFFER_SIZE], m_StreamBuffer[I2P_TUNNEL_CONNECTION_BUFFER_SIZE];
|
||||
std::shared_ptr<boost::asio::ip::tcp::socket> m_Socket;
|
||||
std::shared_ptr<i2p::stream::Stream> m_Stream;
|
||||
boost::asio::ip::tcp::endpoint m_RemoteEndpoint;
|
||||
bool m_IsQuiet; // don't send destination
|
||||
};
|
||||
void Terminate();
|
||||
|
||||
class I2PClientTunnelConnectionHTTP: public I2PTunnelConnection
|
||||
{
|
||||
public:
|
||||
void Receive();
|
||||
|
||||
I2PClientTunnelConnectionHTTP (I2PService * owner, std::shared_ptr<boost::asio::ip::tcp::socket> socket,
|
||||
std::shared_ptr<i2p::stream::Stream> stream):
|
||||
I2PTunnelConnection (owner, socket, stream), m_HeaderSent (false),
|
||||
m_ConnectionSent (false), m_ProxyConnectionSent (false) {};
|
||||
void HandleReceived(const boost::system::error_code &ecode, std::size_t bytes_transferred);
|
||||
|
||||
protected:
|
||||
virtual void Write(const uint8_t *buf, size_t len); // can be overloaded
|
||||
void HandleWrite(const boost::system::error_code &ecode);
|
||||
|
||||
void Write (const uint8_t * buf, size_t len);
|
||||
virtual void WriteToStream(const uint8_t *buf, size_t len); // can be overloaded
|
||||
|
||||
private:
|
||||
void StreamReceive();
|
||||
|
||||
std::stringstream m_InHeader, m_OutHeader;
|
||||
bool m_HeaderSent, m_ConnectionSent, m_ProxyConnectionSent;
|
||||
};
|
||||
void HandleStreamReceive(const boost::system::error_code &ecode, std::size_t bytes_transferred);
|
||||
|
||||
class I2PServerTunnelConnectionHTTP: public I2PTunnelConnection
|
||||
{
|
||||
public:
|
||||
void HandleConnect(const boost::system::error_code &ecode);
|
||||
|
||||
I2PServerTunnelConnectionHTTP (I2PService * owner, std::shared_ptr<i2p::stream::Stream> stream,
|
||||
std::shared_ptr<boost::asio::ip::tcp::socket> socket,
|
||||
const boost::asio::ip::tcp::endpoint& target, const std::string& host);
|
||||
std::shared_ptr<const boost::asio::ip::tcp::socket> GetSocket() const { return m_Socket; };
|
||||
|
||||
protected:
|
||||
private:
|
||||
|
||||
void Write (const uint8_t * buf, size_t len);
|
||||
void WriteToStream (const uint8_t * buf, size_t len);
|
||||
uint8_t m_Buffer[I2P_TUNNEL_CONNECTION_BUFFER_SIZE], m_StreamBuffer[I2P_TUNNEL_CONNECTION_BUFFER_SIZE];
|
||||
std::shared_ptr <boost::asio::ip::tcp::socket> m_Socket;
|
||||
std::shared_ptr <i2p::stream::Stream> m_Stream;
|
||||
boost::asio::ip::tcp::endpoint m_RemoteEndpoint;
|
||||
bool m_IsQuiet; // don't send destination
|
||||
};
|
||||
|
||||
private:
|
||||
class I2PClientTunnelConnectionHTTP : public I2PTunnelConnection {
|
||||
public:
|
||||
|
||||
std::string m_Host;
|
||||
std::stringstream m_InHeader, m_OutHeader;
|
||||
bool m_HeaderSent, m_ResponseHeaderSent;
|
||||
std::shared_ptr<const i2p::data::IdentityEx> m_From;
|
||||
};
|
||||
|
||||
class I2PTunnelConnectionIRC: public I2PTunnelConnection
|
||||
{
|
||||
public:
|
||||
|
||||
I2PTunnelConnectionIRC (I2PService * owner, std::shared_ptr<i2p::stream::Stream> stream,
|
||||
std::shared_ptr<boost::asio::ip::tcp::socket> socket,
|
||||
const boost::asio::ip::tcp::endpoint& target, const std::string& m_WebircPass);
|
||||
|
||||
protected:
|
||||
|
||||
void Write (const uint8_t * buf, size_t len);
|
||||
|
||||
private:
|
||||
|
||||
std::shared_ptr<const i2p::data::IdentityEx> m_From;
|
||||
std::stringstream m_OutPacket, m_InPacket;
|
||||
bool m_NeedsWebIrc;
|
||||
std::string m_WebircPass;
|
||||
};
|
||||
I2PClientTunnelConnectionHTTP(I2PService *owner, std::shared_ptr <boost::asio::ip::tcp::socket> socket,
|
||||
std::shared_ptr <i2p::stream::Stream> stream) :
|
||||
I2PTunnelConnection(owner, socket, stream), m_HeaderSent(false),
|
||||
m_ConnectionSent(false), m_ProxyConnectionSent(false) {};
|
||||
|
||||
protected:
|
||||
|
||||
class I2PClientTunnel: public TCPIPAcceptor
|
||||
{
|
||||
protected:
|
||||
void Write(const uint8_t *buf, size_t len);
|
||||
|
||||
// Implements TCPIPAcceptor
|
||||
std::shared_ptr<I2PServiceHandler> CreateHandler(std::shared_ptr<boost::asio::ip::tcp::socket> socket);
|
||||
private:
|
||||
|
||||
public:
|
||||
std::stringstream m_InHeader, m_OutHeader;
|
||||
bool m_HeaderSent, m_ConnectionSent, m_ProxyConnectionSent;
|
||||
};
|
||||
|
||||
I2PClientTunnel (const std::string& name, const std::string& destination,
|
||||
const std::string& address, int port, std::shared_ptr<ClientDestination> localDestination, int destinationPort = 0);
|
||||
~I2PClientTunnel () {}
|
||||
class I2PServerTunnelConnectionHTTP : public I2PTunnelConnection {
|
||||
public:
|
||||
|
||||
void Start ();
|
||||
void Stop ();
|
||||
I2PServerTunnelConnectionHTTP(I2PService *owner, std::shared_ptr <i2p::stream::Stream> stream,
|
||||
std::shared_ptr <boost::asio::ip::tcp::socket> socket,
|
||||
const boost::asio::ip::tcp::endpoint &target, const std::string &host);
|
||||
|
||||
const char* GetName() { return m_Name.c_str (); }
|
||||
void SetKeepAliveInterval (uint32_t keepAliveInterval);
|
||||
protected:
|
||||
|
||||
private:
|
||||
void Write(const uint8_t *buf, size_t len);
|
||||
|
||||
std::shared_ptr<const Address> GetAddress ();
|
||||
void WriteToStream(const uint8_t *buf, size_t len);
|
||||
|
||||
void ScheduleKeepAliveTimer ();
|
||||
void HandleKeepAliveTimer (const boost::system::error_code& ecode);
|
||||
private:
|
||||
|
||||
private:
|
||||
std::string m_Host;
|
||||
std::stringstream m_InHeader, m_OutHeader;
|
||||
bool m_HeaderSent, m_ResponseHeaderSent;
|
||||
std::shared_ptr<const i2p::data::IdentityEx> m_From;
|
||||
};
|
||||
|
||||
std::string m_Name, m_Destination;
|
||||
std::shared_ptr<const Address> m_Address;
|
||||
int m_DestinationPort;
|
||||
uint32_t m_KeepAliveInterval;
|
||||
std::unique_ptr<boost::asio::deadline_timer> m_KeepAliveTimer;
|
||||
};
|
||||
class I2PTunnelConnectionIRC : public I2PTunnelConnection {
|
||||
public:
|
||||
|
||||
I2PTunnelConnectionIRC(I2PService *owner, std::shared_ptr <i2p::stream::Stream> stream,
|
||||
std::shared_ptr <boost::asio::ip::tcp::socket> socket,
|
||||
const boost::asio::ip::tcp::endpoint &target, const std::string &m_WebircPass);
|
||||
|
||||
/** 2 minute timeout for udp sessions */
|
||||
const uint64_t I2P_UDP_SESSION_TIMEOUT = 1000 * 60 * 2;
|
||||
const uint64_t I2P_UDP_REPLIABLE_DATAGRAM_INTERVAL = 100; // in milliseconds
|
||||
protected:
|
||||
|
||||
/** max size for i2p udp */
|
||||
const size_t I2P_UDP_MAX_MTU = 64*1024;
|
||||
void Write(const uint8_t *buf, size_t len);
|
||||
|
||||
struct UDPSession
|
||||
{
|
||||
i2p::datagram::DatagramDestination * m_Destination;
|
||||
boost::asio::ip::udp::socket IPSocket;
|
||||
i2p::data::IdentHash Identity;
|
||||
boost::asio::ip::udp::endpoint FromEndpoint;
|
||||
boost::asio::ip::udp::endpoint SendEndpoint;
|
||||
uint64_t LastActivity;
|
||||
private:
|
||||
|
||||
uint16_t LocalPort;
|
||||
uint16_t RemotePort;
|
||||
|
||||
uint8_t m_Buffer[I2P_UDP_MAX_MTU];
|
||||
std::shared_ptr<const i2p::data::IdentityEx> m_From;
|
||||
std::stringstream m_OutPacket, m_InPacket;
|
||||
bool m_NeedsWebIrc;
|
||||
std::string m_WebircPass;
|
||||
};
|
||||
|
||||
UDPSession(boost::asio::ip::udp::endpoint localEndpoint,
|
||||
const std::shared_ptr<i2p::client::ClientDestination> & localDestination,
|
||||
boost::asio::ip::udp::endpoint remote, const i2p::data::IdentHash * ident,
|
||||
uint16_t ourPort, uint16_t theirPort);
|
||||
void HandleReceived(const boost::system::error_code & ecode, std::size_t len);
|
||||
void Receive();
|
||||
};
|
||||
|
||||
class I2PClientTunnel : public TCPIPAcceptor {
|
||||
protected:
|
||||
|
||||
/** read only info about a datagram session */
|
||||
struct DatagramSessionInfo
|
||||
{
|
||||
/** the name of this forward */
|
||||
std::string Name;
|
||||
/** ident hash of local destination */
|
||||
std::shared_ptr<const i2p::data::IdentHash> LocalIdent;
|
||||
/** ident hash of remote destination */
|
||||
std::shared_ptr<const i2p::data::IdentHash> RemoteIdent;
|
||||
/** ident hash of IBGW in use currently in this session or nullptr if none is set */
|
||||
std::shared_ptr<const i2p::data::IdentHash> CurrentIBGW;
|
||||
/** ident hash of OBEP in use for this session or nullptr if none is set */
|
||||
std::shared_ptr<const i2p::data::IdentHash> CurrentOBEP;
|
||||
/** i2p router's udp endpoint */
|
||||
boost::asio::ip::udp::endpoint LocalEndpoint;
|
||||
/** client's udp endpoint */
|
||||
boost::asio::ip::udp::endpoint RemoteEndpoint;
|
||||
/** how long has this converstation been idle in ms */
|
||||
uint64_t idle;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<UDPSession> UDPSessionPtr;
|
||||
|
||||
/** server side udp tunnel, many i2p inbound to 1 ip outbound */
|
||||
class I2PUDPServerTunnel
|
||||
{
|
||||
public:
|
||||
|
||||
I2PUDPServerTunnel (const std::string & name,
|
||||
std::shared_ptr<i2p::client::ClientDestination> localDestination,
|
||||
boost::asio::ip::address localAddress,
|
||||
boost::asio::ip::udp::endpoint forwardTo, uint16_t port, bool gzip);
|
||||
~I2PUDPServerTunnel ();
|
||||
|
||||
/** expire stale udp conversations */
|
||||
void ExpireStale (const uint64_t delta=I2P_UDP_SESSION_TIMEOUT);
|
||||
void Start ();
|
||||
void Stop ();
|
||||
const char * GetName () const { return m_Name.c_str(); }
|
||||
std::vector<std::shared_ptr<DatagramSessionInfo> > GetSessions ();
|
||||
std::shared_ptr<ClientDestination> GetLocalDestination () const { return m_LocalDest; }
|
||||
|
||||
void SetUniqueLocal (bool isUniqueLocal = true) { m_IsUniqueLocal = isUniqueLocal; }
|
||||
|
||||
private:
|
||||
|
||||
void HandleRecvFromI2P (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
|
||||
void HandleRecvFromI2PRaw (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
|
||||
UDPSessionPtr ObtainUDPSession (const i2p::data::IdentityEx& from, uint16_t localPort, uint16_t remotePort);
|
||||
|
||||
private:
|
||||
|
||||
bool m_IsUniqueLocal;
|
||||
const std::string m_Name;
|
||||
boost::asio::ip::address m_LocalAddress;
|
||||
boost::asio::ip::udp::endpoint m_RemoteEndpoint;
|
||||
std::mutex m_SessionsMutex;
|
||||
std::vector<UDPSessionPtr> m_Sessions;
|
||||
std::shared_ptr<i2p::client::ClientDestination> m_LocalDest;
|
||||
UDPSessionPtr m_LastSession;
|
||||
bool m_Gzip;
|
||||
|
||||
public:
|
||||
|
||||
bool isUpdated; // transient, used during reload only
|
||||
};
|
||||
|
||||
class I2PUDPClientTunnel
|
||||
{
|
||||
public:
|
||||
|
||||
I2PUDPClientTunnel (const std::string & name, const std::string &remoteDest,
|
||||
boost::asio::ip::udp::endpoint localEndpoint, std::shared_ptr<i2p::client::ClientDestination> localDestination,
|
||||
uint16_t remotePort, bool gzip);
|
||||
~I2PUDPClientTunnel ();
|
||||
|
||||
void Start ();
|
||||
void Stop ();
|
||||
const char * GetName () const { return m_Name.c_str(); }
|
||||
std::vector<std::shared_ptr<DatagramSessionInfo> > GetSessions ();
|
||||
|
||||
bool IsLocalDestination (const i2p::data::IdentHash & destination) const { return destination == m_LocalDest->GetIdentHash(); }
|
||||
|
||||
std::shared_ptr<ClientDestination> GetLocalDestination () const { return m_LocalDest; }
|
||||
inline void SetLocalDestination (std::shared_ptr<ClientDestination> dest)
|
||||
{
|
||||
if (m_LocalDest) m_LocalDest->Release ();
|
||||
if (dest) dest->Acquire ();
|
||||
m_LocalDest = dest;
|
||||
}
|
||||
|
||||
void ExpireStale (const uint64_t delta=I2P_UDP_SESSION_TIMEOUT);
|
||||
|
||||
private:
|
||||
|
||||
typedef std::pair<boost::asio::ip::udp::endpoint, uint64_t> UDPConvo;
|
||||
void RecvFromLocal ();
|
||||
void HandleRecvFromLocal (const boost::system::error_code & e, std::size_t transferred);
|
||||
void HandleRecvFromI2P (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
|
||||
void HandleRecvFromI2PRaw (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
|
||||
void TryResolving ();
|
||||
|
||||
private:
|
||||
|
||||
const std::string m_Name;
|
||||
std::mutex m_SessionsMutex;
|
||||
std::unordered_map<uint16_t, std::shared_ptr<UDPConvo> > m_Sessions; // maps i2p port -> local udp convo
|
||||
const std::string m_RemoteDest;
|
||||
std::shared_ptr<i2p::client::ClientDestination> m_LocalDest;
|
||||
const boost::asio::ip::udp::endpoint m_LocalEndpoint;
|
||||
i2p::data::IdentHash * m_RemoteIdent;
|
||||
std::thread * m_ResolveThread;
|
||||
std::unique_ptr<boost::asio::ip::udp::socket> m_LocalSocket;
|
||||
boost::asio::ip::udp::endpoint m_RecvEndpoint;
|
||||
uint8_t m_RecvBuff[I2P_UDP_MAX_MTU];
|
||||
uint16_t RemotePort, m_LastPort;
|
||||
bool m_cancel_resolve;
|
||||
bool m_Gzip;
|
||||
std::shared_ptr<UDPConvo> m_LastSession;
|
||||
// Implements TCPIPAcceptor
|
||||
std::shared_ptr <I2PServiceHandler> CreateHandler(std::shared_ptr <boost::asio::ip::tcp::socket> socket);
|
||||
|
||||
public:
|
||||
public:
|
||||
|
||||
bool isUpdated; // transient, used during reload only
|
||||
};
|
||||
I2PClientTunnel(const std::string &name, const std::string &destination,
|
||||
const std::string &address, int port, std::shared_ptr <ClientDestination> localDestination,
|
||||
int destinationPort = 0);
|
||||
|
||||
class I2PServerTunnel: public I2PService
|
||||
{
|
||||
public:
|
||||
~I2PClientTunnel() {}
|
||||
|
||||
I2PServerTunnel (const std::string& name, const std::string& address, int port,
|
||||
std::shared_ptr<ClientDestination> localDestination, int inport = 0, bool gzip = true);
|
||||
void Start();
|
||||
|
||||
void Start ();
|
||||
void Stop ();
|
||||
void Stop();
|
||||
|
||||
void SetAccessList (const std::set<i2p::data::IdentHash>& accessList);
|
||||
const char *GetName() { return m_Name.c_str(); }
|
||||
|
||||
void SetUniqueLocal (bool isUniqueLocal) { m_IsUniqueLocal = isUniqueLocal; }
|
||||
bool IsUniqueLocal () const { return m_IsUniqueLocal; }
|
||||
void SetKeepAliveInterval(uint32_t keepAliveInterval);
|
||||
|
||||
void SetLocalAddress (const std::string& localAddress);
|
||||
private:
|
||||
|
||||
const std::string& GetAddress() const { return m_Address; }
|
||||
int GetPort () const { return m_Port; };
|
||||
uint16_t GetLocalPort () const { return m_PortDestination->GetLocalPort (); };
|
||||
const boost::asio::ip::tcp::endpoint& GetEndpoint () const { return m_Endpoint; }
|
||||
std::shared_ptr<const Address> GetAddress();
|
||||
|
||||
const char* GetName() { return m_Name.c_str (); }
|
||||
void ScheduleKeepAliveTimer();
|
||||
|
||||
private:
|
||||
void HandleKeepAliveTimer(const boost::system::error_code &ecode);
|
||||
|
||||
void HandleResolve (const boost::system::error_code& ecode, boost::asio::ip::tcp::resolver::iterator it,
|
||||
std::shared_ptr<boost::asio::ip::tcp::resolver> resolver);
|
||||
private:
|
||||
|
||||
void Accept ();
|
||||
void HandleAccept (std::shared_ptr<i2p::stream::Stream> stream);
|
||||
virtual std::shared_ptr<I2PTunnelConnection> CreateI2PConnection (std::shared_ptr<i2p::stream::Stream> stream);
|
||||
std::string m_Name, m_Destination;
|
||||
std::shared_ptr<const Address> m_Address;
|
||||
int m_DestinationPort;
|
||||
uint32_t m_KeepAliveInterval;
|
||||
std::unique_ptr <boost::asio::deadline_timer> m_KeepAliveTimer;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
bool m_IsUniqueLocal;
|
||||
std::string m_Name, m_Address;
|
||||
int m_Port;
|
||||
boost::asio::ip::tcp::endpoint m_Endpoint;
|
||||
std::shared_ptr<i2p::stream::StreamingDestination> m_PortDestination;
|
||||
std::set<i2p::data::IdentHash> m_AccessList;
|
||||
bool m_IsAccessList;
|
||||
std::unique_ptr<boost::asio::ip::address> m_LocalAddress;
|
||||
};
|
||||
/** 2 minute timeout for udp sessions */
|
||||
const uint64_t I2P_UDP_SESSION_TIMEOUT = 1000 * 60 * 2;
|
||||
const uint64_t I2P_UDP_REPLIABLE_DATAGRAM_INTERVAL = 100; // in milliseconds
|
||||
|
||||
class I2PServerTunnelHTTP: public I2PServerTunnel
|
||||
{
|
||||
public:
|
||||
/** max size for i2p udp */
|
||||
const size_t I2P_UDP_MAX_MTU = 64 * 1024;
|
||||
|
||||
I2PServerTunnelHTTP (const std::string& name, const std::string& address, int port,
|
||||
std::shared_ptr<ClientDestination> localDestination, const std::string& host,
|
||||
int inport = 0, bool gzip = true);
|
||||
struct UDPSession {
|
||||
i2p::datagram::DatagramDestination *m_Destination;
|
||||
boost::asio::ip::udp::socket IPSocket;
|
||||
i2p::data::IdentHash Identity;
|
||||
boost::asio::ip::udp::endpoint FromEndpoint;
|
||||
boost::asio::ip::udp::endpoint SendEndpoint;
|
||||
uint64_t LastActivity;
|
||||
|
||||
private:
|
||||
uint16_t LocalPort;
|
||||
uint16_t RemotePort;
|
||||
|
||||
std::shared_ptr<I2PTunnelConnection> CreateI2PConnection (std::shared_ptr<i2p::stream::Stream> stream);
|
||||
uint8_t m_Buffer[I2P_UDP_MAX_MTU];
|
||||
|
||||
private:
|
||||
UDPSession(boost::asio::ip::udp::endpoint localEndpoint,
|
||||
const std::shared_ptr <i2p::client::ClientDestination> &localDestination,
|
||||
boost::asio::ip::udp::endpoint remote, const i2p::data::IdentHash *ident,
|
||||
uint16_t ourPort, uint16_t theirPort);
|
||||
|
||||
std::string m_Host;
|
||||
};
|
||||
void HandleReceived(const boost::system::error_code &ecode, std::size_t len);
|
||||
|
||||
class I2PServerTunnelIRC: public I2PServerTunnel
|
||||
{
|
||||
public:
|
||||
void Receive();
|
||||
};
|
||||
|
||||
I2PServerTunnelIRC (const std::string& name, const std::string& address, int port,
|
||||
std::shared_ptr<ClientDestination> localDestination, const std::string& webircpass,
|
||||
int inport = 0, bool gzip = true);
|
||||
|
||||
private:
|
||||
/** read only info about a datagram session */
|
||||
struct DatagramSessionInfo {
|
||||
/** the name of this forward */
|
||||
std::string Name;
|
||||
/** ident hash of local destination */
|
||||
std::shared_ptr<const i2p::data::IdentHash> LocalIdent;
|
||||
/** ident hash of remote destination */
|
||||
std::shared_ptr<const i2p::data::IdentHash> RemoteIdent;
|
||||
/** ident hash of IBGW in use currently in this session or nullptr if none is set */
|
||||
std::shared_ptr<const i2p::data::IdentHash> CurrentIBGW;
|
||||
/** ident hash of OBEP in use for this session or nullptr if none is set */
|
||||
std::shared_ptr<const i2p::data::IdentHash> CurrentOBEP;
|
||||
/** i2p router's udp endpoint */
|
||||
boost::asio::ip::udp::endpoint LocalEndpoint;
|
||||
/** client's udp endpoint */
|
||||
boost::asio::ip::udp::endpoint RemoteEndpoint;
|
||||
/** how long has this converstation been idle in ms */
|
||||
uint64_t idle;
|
||||
};
|
||||
|
||||
std::shared_ptr<I2PTunnelConnection> CreateI2PConnection (std::shared_ptr<i2p::stream::Stream> stream);
|
||||
typedef std::shared_ptr <UDPSession> UDPSessionPtr;
|
||||
|
||||
private:
|
||||
/** server side udp tunnel, many i2p inbound to 1 ip outbound */
|
||||
class I2PUDPServerTunnel {
|
||||
public:
|
||||
|
||||
std::string m_WebircPass;
|
||||
};
|
||||
}
|
||||
I2PUDPServerTunnel(const std::string &name,
|
||||
std::shared_ptr <i2p::client::ClientDestination> localDestination,
|
||||
boost::asio::ip::address localAddress,
|
||||
boost::asio::ip::udp::endpoint forwardTo, uint16_t port, bool gzip);
|
||||
|
||||
~I2PUDPServerTunnel();
|
||||
|
||||
/** expire stale udp conversations */
|
||||
void ExpireStale(const uint64_t delta = I2P_UDP_SESSION_TIMEOUT);
|
||||
|
||||
void Start();
|
||||
|
||||
void Stop();
|
||||
|
||||
const char *GetName() const { return m_Name.c_str(); }
|
||||
|
||||
std::vector <std::shared_ptr<DatagramSessionInfo>> GetSessions();
|
||||
|
||||
std::shared_ptr <ClientDestination> GetLocalDestination() const { return m_LocalDest; }
|
||||
|
||||
void SetUniqueLocal(bool isUniqueLocal = true) { m_IsUniqueLocal = isUniqueLocal; }
|
||||
|
||||
private:
|
||||
|
||||
void
|
||||
HandleRecvFromI2P(const i2p::data::IdentityEx &from, uint16_t fromPort, uint16_t toPort, const uint8_t *buf,
|
||||
size_t len);
|
||||
|
||||
void HandleRecvFromI2PRaw(uint16_t fromPort, uint16_t toPort, const uint8_t *buf, size_t len);
|
||||
|
||||
UDPSessionPtr ObtainUDPSession(const i2p::data::IdentityEx &from, uint16_t localPort, uint16_t remotePort);
|
||||
|
||||
private:
|
||||
|
||||
bool m_IsUniqueLocal;
|
||||
const std::string m_Name;
|
||||
boost::asio::ip::address m_LocalAddress;
|
||||
boost::asio::ip::udp::endpoint m_RemoteEndpoint;
|
||||
std::mutex m_SessionsMutex;
|
||||
std::vector <UDPSessionPtr> m_Sessions;
|
||||
std::shared_ptr <i2p::client::ClientDestination> m_LocalDest;
|
||||
UDPSessionPtr m_LastSession;
|
||||
bool m_Gzip;
|
||||
|
||||
public:
|
||||
|
||||
bool isUpdated; // transient, used during reload only
|
||||
};
|
||||
|
||||
class I2PUDPClientTunnel {
|
||||
public:
|
||||
|
||||
I2PUDPClientTunnel(const std::string &name, const std::string &remoteDest,
|
||||
boost::asio::ip::udp::endpoint localEndpoint,
|
||||
std::shared_ptr <i2p::client::ClientDestination> localDestination,
|
||||
uint16_t remotePort, bool gzip);
|
||||
|
||||
~I2PUDPClientTunnel();
|
||||
|
||||
void Start();
|
||||
|
||||
void Stop();
|
||||
|
||||
const char *GetName() const { return m_Name.c_str(); }
|
||||
|
||||
std::vector <std::shared_ptr<DatagramSessionInfo>> GetSessions();
|
||||
|
||||
bool IsLocalDestination(const i2p::data::IdentHash &destination) const {
|
||||
return destination == m_LocalDest->GetIdentHash();
|
||||
}
|
||||
|
||||
std::shared_ptr <ClientDestination> GetLocalDestination() const { return m_LocalDest; }
|
||||
|
||||
inline void SetLocalDestination(std::shared_ptr <ClientDestination> dest) {
|
||||
if (m_LocalDest) m_LocalDest->Release();
|
||||
if (dest) dest->Acquire();
|
||||
m_LocalDest = dest;
|
||||
}
|
||||
|
||||
void ExpireStale(const uint64_t delta = I2P_UDP_SESSION_TIMEOUT);
|
||||
|
||||
private:
|
||||
|
||||
typedef std::pair <boost::asio::ip::udp::endpoint, uint64_t> UDPConvo;
|
||||
|
||||
void RecvFromLocal();
|
||||
|
||||
void HandleRecvFromLocal(const boost::system::error_code &e, std::size_t transferred);
|
||||
|
||||
void
|
||||
HandleRecvFromI2P(const i2p::data::IdentityEx &from, uint16_t fromPort, uint16_t toPort, const uint8_t *buf,
|
||||
size_t len);
|
||||
|
||||
void HandleRecvFromI2PRaw(uint16_t fromPort, uint16_t toPort, const uint8_t *buf, size_t len);
|
||||
|
||||
void TryResolving();
|
||||
|
||||
private:
|
||||
|
||||
const std::string m_Name;
|
||||
std::mutex m_SessionsMutex;
|
||||
std::unordered_map <uint16_t, std::shared_ptr<UDPConvo>> m_Sessions; // maps i2p port -> local udp convo
|
||||
const std::string m_RemoteDest;
|
||||
std::shared_ptr <i2p::client::ClientDestination> m_LocalDest;
|
||||
const boost::asio::ip::udp::endpoint m_LocalEndpoint;
|
||||
i2p::data::IdentHash *m_RemoteIdent;
|
||||
std::thread *m_ResolveThread;
|
||||
std::unique_ptr <boost::asio::ip::udp::socket> m_LocalSocket;
|
||||
boost::asio::ip::udp::endpoint m_RecvEndpoint;
|
||||
uint8_t m_RecvBuff[I2P_UDP_MAX_MTU];
|
||||
uint16_t RemotePort, m_LastPort;
|
||||
bool m_cancel_resolve;
|
||||
bool m_Gzip;
|
||||
std::shared_ptr <UDPConvo> m_LastSession;
|
||||
|
||||
public:
|
||||
|
||||
bool isUpdated; // transient, used during reload only
|
||||
};
|
||||
|
||||
class I2PServerTunnel : public I2PService {
|
||||
public:
|
||||
|
||||
I2PServerTunnel(const std::string &name, const std::string &address, int port,
|
||||
std::shared_ptr <ClientDestination> localDestination, int inport = 0, bool gzip = true);
|
||||
|
||||
void Start();
|
||||
|
||||
void Stop();
|
||||
|
||||
void SetAccessList(const std::set <i2p::data::IdentHash> &accessList);
|
||||
|
||||
void SetUniqueLocal(bool isUniqueLocal) { m_IsUniqueLocal = isUniqueLocal; }
|
||||
|
||||
bool IsUniqueLocal() const { return m_IsUniqueLocal; }
|
||||
|
||||
void SetLocalAddress(const std::string &localAddress);
|
||||
|
||||
const std::string &GetAddress() const { return m_Address; }
|
||||
|
||||
int GetPort() const { return m_Port; };
|
||||
|
||||
uint16_t GetLocalPort() const { return m_PortDestination->GetLocalPort(); };
|
||||
|
||||
const boost::asio::ip::tcp::endpoint &GetEndpoint() const { return m_Endpoint; }
|
||||
|
||||
const char *GetName() { return m_Name.c_str(); }
|
||||
|
||||
private:
|
||||
|
||||
void HandleResolve(const boost::system::error_code &ecode, boost::asio::ip::tcp::resolver::iterator it,
|
||||
std::shared_ptr <boost::asio::ip::tcp::resolver> resolver);
|
||||
|
||||
void Accept();
|
||||
|
||||
void HandleAccept(std::shared_ptr <i2p::stream::Stream> stream);
|
||||
|
||||
virtual std::shared_ptr <I2PTunnelConnection>
|
||||
CreateI2PConnection(std::shared_ptr <i2p::stream::Stream> stream);
|
||||
|
||||
private:
|
||||
|
||||
bool m_IsUniqueLocal;
|
||||
std::string m_Name, m_Address;
|
||||
int m_Port;
|
||||
boost::asio::ip::tcp::endpoint m_Endpoint;
|
||||
std::shared_ptr <i2p::stream::StreamingDestination> m_PortDestination;
|
||||
std::set <i2p::data::IdentHash> m_AccessList;
|
||||
bool m_IsAccessList;
|
||||
std::unique_ptr <boost::asio::ip::address> m_LocalAddress;
|
||||
};
|
||||
|
||||
class I2PServerTunnelHTTP : public I2PServerTunnel {
|
||||
public:
|
||||
|
||||
I2PServerTunnelHTTP(const std::string &name, const std::string &address, int port,
|
||||
std::shared_ptr <ClientDestination> localDestination, const std::string &host,
|
||||
int inport = 0, bool gzip = true);
|
||||
|
||||
private:
|
||||
|
||||
std::shared_ptr <I2PTunnelConnection> CreateI2PConnection(std::shared_ptr <i2p::stream::Stream> stream);
|
||||
|
||||
private:
|
||||
|
||||
std::string m_Host;
|
||||
};
|
||||
|
||||
class I2PServerTunnelIRC : public I2PServerTunnel {
|
||||
public:
|
||||
|
||||
I2PServerTunnelIRC(const std::string &name, const std::string &address, int port,
|
||||
std::shared_ptr <ClientDestination> localDestination, const std::string &webircpass,
|
||||
int inport = 0, bool gzip = true);
|
||||
|
||||
private:
|
||||
|
||||
std::shared_ptr <I2PTunnelConnection> CreateI2PConnection(std::shared_ptr <i2p::stream::Stream> stream);
|
||||
|
||||
private:
|
||||
|
||||
std::string m_WebircPass;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -11,97 +11,86 @@
|
|||
#include "ClientContext.h"
|
||||
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
namespace client
|
||||
{
|
||||
MatchedTunnelDestination::MatchedTunnelDestination(const i2p::data::PrivateKeys & keys, const std::string & remoteName, const std::map<std::string, std::string> * params)
|
||||
: RunnableClientDestination(keys, false, params),
|
||||
m_RemoteName(remoteName) {}
|
||||
namespace i2p {
|
||||
namespace client {
|
||||
MatchedTunnelDestination::MatchedTunnelDestination(const i2p::data::PrivateKeys &keys,
|
||||
const std::string &remoteName,
|
||||
const std::map <std::string, std::string> *params)
|
||||
: RunnableClientDestination(keys, false, params),
|
||||
m_RemoteName(remoteName) {}
|
||||
|
||||
|
||||
void MatchedTunnelDestination::ResolveCurrentLeaseSet()
|
||||
{
|
||||
auto addr = i2p::client::context.GetAddressBook().GetAddress (m_RemoteName);
|
||||
if(addr && addr->IsIdentHash ())
|
||||
{
|
||||
m_RemoteIdent = addr->identHash;
|
||||
auto ls = FindLeaseSet(m_RemoteIdent);
|
||||
if(ls)
|
||||
HandleFoundCurrentLeaseSet(ls);
|
||||
else
|
||||
RequestDestination(m_RemoteIdent, std::bind(&MatchedTunnelDestination::HandleFoundCurrentLeaseSet, this, std::placeholders::_1));
|
||||
}
|
||||
else
|
||||
LogPrint(eLogWarning, "Destination: Failed to resolve ", m_RemoteName);
|
||||
}
|
||||
void MatchedTunnelDestination::ResolveCurrentLeaseSet() {
|
||||
auto addr = i2p::client::context.GetAddressBook().GetAddress(m_RemoteName);
|
||||
if (addr && addr->IsIdentHash()) {
|
||||
m_RemoteIdent = addr->identHash;
|
||||
auto ls = FindLeaseSet(m_RemoteIdent);
|
||||
if (ls)
|
||||
HandleFoundCurrentLeaseSet(ls);
|
||||
else
|
||||
RequestDestination(m_RemoteIdent,
|
||||
std::bind(&MatchedTunnelDestination::HandleFoundCurrentLeaseSet, this,
|
||||
std::placeholders::_1));
|
||||
} else
|
||||
LogPrint(eLogWarning, "Destination: Failed to resolve ", m_RemoteName);
|
||||
}
|
||||
|
||||
void MatchedTunnelDestination::HandleFoundCurrentLeaseSet(std::shared_ptr<const i2p::data::LeaseSet> ls)
|
||||
{
|
||||
if(ls)
|
||||
{
|
||||
LogPrint(eLogDebug, "Destination: Resolved remote lease set for ", m_RemoteName);
|
||||
m_RemoteLeaseSet = ls;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ResolveTimer->expires_from_now(boost::posix_time::seconds(1));
|
||||
m_ResolveTimer->async_wait([&](const boost::system::error_code & ec) {
|
||||
if(!ec) ResolveCurrentLeaseSet();
|
||||
});
|
||||
}
|
||||
}
|
||||
void MatchedTunnelDestination::HandleFoundCurrentLeaseSet(std::shared_ptr<const i2p::data::LeaseSet> ls) {
|
||||
if (ls) {
|
||||
LogPrint(eLogDebug, "Destination: Resolved remote lease set for ", m_RemoteName);
|
||||
m_RemoteLeaseSet = ls;
|
||||
} else {
|
||||
m_ResolveTimer->expires_from_now(boost::posix_time::seconds(1));
|
||||
m_ResolveTimer->async_wait([&](const boost::system::error_code &ec) {
|
||||
if (!ec) ResolveCurrentLeaseSet();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MatchedTunnelDestination::Start()
|
||||
{
|
||||
ClientDestination::Start();
|
||||
m_ResolveTimer = std::make_shared<boost::asio::deadline_timer>(GetService());
|
||||
GetTunnelPool()->SetCustomPeerSelector(this);
|
||||
ResolveCurrentLeaseSet();
|
||||
}
|
||||
void MatchedTunnelDestination::Start() {
|
||||
ClientDestination::Start();
|
||||
m_ResolveTimer = std::make_shared<boost::asio::deadline_timer>(GetService());
|
||||
GetTunnelPool()->SetCustomPeerSelector(this);
|
||||
ResolveCurrentLeaseSet();
|
||||
}
|
||||
|
||||
void MatchedTunnelDestination::Stop()
|
||||
{
|
||||
ClientDestination::Stop();
|
||||
if(m_ResolveTimer)
|
||||
m_ResolveTimer->cancel();
|
||||
}
|
||||
void MatchedTunnelDestination::Stop() {
|
||||
ClientDestination::Stop();
|
||||
if (m_ResolveTimer)
|
||||
m_ResolveTimer->cancel();
|
||||
}
|
||||
|
||||
|
||||
bool MatchedTunnelDestination::SelectPeers(i2p::tunnel::Path & path, int hops, bool inbound)
|
||||
{
|
||||
auto pool = GetTunnelPool();
|
||||
if(!i2p::tunnel::StandardSelectPeers(path, hops, inbound,
|
||||
std::bind(&i2p::tunnel::TunnelPool::SelectNextHop, pool, std::placeholders::_1, std::placeholders::_2)))
|
||||
return false;
|
||||
// more here for outbound tunnels
|
||||
if(!inbound && m_RemoteLeaseSet)
|
||||
{
|
||||
if(m_RemoteLeaseSet->IsExpired())
|
||||
ResolveCurrentLeaseSet();
|
||||
if(m_RemoteLeaseSet && !m_RemoteLeaseSet->IsExpired())
|
||||
{
|
||||
// remote lease set is good
|
||||
auto leases = m_RemoteLeaseSet->GetNonExpiredLeases();
|
||||
// pick lease
|
||||
std::shared_ptr<i2p::data::RouterInfo> obep;
|
||||
while(!obep && leases.size() > 0)
|
||||
{
|
||||
auto idx = rand() % leases.size();
|
||||
auto lease = leases[idx];
|
||||
obep = i2p::data::netdb.FindRouter(lease->tunnelGateway);
|
||||
leases.erase(leases.begin()+idx);
|
||||
}
|
||||
if(obep)
|
||||
{
|
||||
path.Add (obep);
|
||||
LogPrint(eLogDebug, "Destination: Found OBEP matching IBGW");
|
||||
} else
|
||||
LogPrint(eLogWarning, "Destination: Could not find proper IBGW for matched outbound tunnel");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
bool MatchedTunnelDestination::SelectPeers(i2p::tunnel::Path &path, int hops, bool inbound) {
|
||||
auto pool = GetTunnelPool();
|
||||
if (!i2p::tunnel::StandardSelectPeers(path, hops, inbound,
|
||||
std::bind(&i2p::tunnel::TunnelPool::SelectNextHop, pool,
|
||||
std::placeholders::_1, std::placeholders::_2)))
|
||||
return false;
|
||||
// more here for outbound tunnels
|
||||
if (!inbound && m_RemoteLeaseSet) {
|
||||
if (m_RemoteLeaseSet->IsExpired())
|
||||
ResolveCurrentLeaseSet();
|
||||
if (m_RemoteLeaseSet && !m_RemoteLeaseSet->IsExpired()) {
|
||||
// remote lease set is good
|
||||
auto leases = m_RemoteLeaseSet->GetNonExpiredLeases();
|
||||
// pick lease
|
||||
std::shared_ptr <i2p::data::RouterInfo> obep;
|
||||
while (!obep && leases.size() > 0) {
|
||||
auto idx = rand() % leases.size();
|
||||
auto lease = leases[idx];
|
||||
obep = i2p::data::netdb.FindRouter(lease->tunnelGateway);
|
||||
leases.erase(leases.begin() + idx);
|
||||
}
|
||||
if (obep) {
|
||||
path.Add(obep);
|
||||
LogPrint(eLogDebug, "Destination: Found OBEP matching IBGW");
|
||||
} else
|
||||
LogPrint(eLogWarning, "Destination: Could not find proper IBGW for matched outbound tunnel");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,40 +8,41 @@
|
|||
|
||||
#ifndef MATCHED_DESTINATION_H_
|
||||
#define MATCHED_DESTINATION_H_
|
||||
|
||||
#include "Destination.h"
|
||||
#include <string>
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
namespace client
|
||||
{
|
||||
/**
|
||||
* client tunnel that uses same OBEP as IBGW of each remote lease for a remote destination
|
||||
*/
|
||||
class MatchedTunnelDestination : public RunnableClientDestination, public i2p::tunnel::ITunnelPeerSelector
|
||||
{
|
||||
public:
|
||||
namespace i2p {
|
||||
namespace client {
|
||||
/**
|
||||
* client tunnel that uses same OBEP as IBGW of each remote lease for a remote destination
|
||||
*/
|
||||
class MatchedTunnelDestination : public RunnableClientDestination, public i2p::tunnel::ITunnelPeerSelector {
|
||||
public:
|
||||
|
||||
MatchedTunnelDestination(const i2p::data::PrivateKeys& keys, const std::string & remoteName,
|
||||
const std::map<std::string, std::string> * params = nullptr);
|
||||
void Start();
|
||||
void Stop();
|
||||
MatchedTunnelDestination(const i2p::data::PrivateKeys &keys, const std::string &remoteName,
|
||||
const std::map <std::string, std::string> *params = nullptr);
|
||||
|
||||
bool SelectPeers(i2p::tunnel::Path & peers, int hops, bool inbound);
|
||||
void Start();
|
||||
|
||||
private:
|
||||
void Stop();
|
||||
|
||||
void ResolveCurrentLeaseSet();
|
||||
void HandleFoundCurrentLeaseSet(std::shared_ptr<const i2p::data::LeaseSet> ls);
|
||||
bool SelectPeers(i2p::tunnel::Path &peers, int hops, bool inbound);
|
||||
|
||||
private:
|
||||
private:
|
||||
|
||||
std::string m_RemoteName;
|
||||
i2p::data::IdentHash m_RemoteIdent;
|
||||
std::shared_ptr<const i2p::data::LeaseSet> m_RemoteLeaseSet;
|
||||
std::shared_ptr<boost::asio::deadline_timer> m_ResolveTimer;
|
||||
};
|
||||
}
|
||||
void ResolveCurrentLeaseSet();
|
||||
|
||||
void HandleFoundCurrentLeaseSet(std::shared_ptr<const i2p::data::LeaseSet> ls);
|
||||
|
||||
private:
|
||||
|
||||
std::string m_RemoteName;
|
||||
i2p::data::IdentHash m_RemoteIdent;
|
||||
std::shared_ptr<const i2p::data::LeaseSet> m_RemoteLeaseSet;
|
||||
std::shared_ptr <boost::asio::deadline_timer> m_ResolveTimer;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -24,265 +24,318 @@
|
|||
#include "Streaming.h"
|
||||
#include "Destination.h"
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
namespace client
|
||||
{
|
||||
const size_t SAM_SOCKET_BUFFER_SIZE = 8192;
|
||||
const int SAM_SOCKET_CONNECTION_MAX_IDLE = 3600; // in seconds
|
||||
const int SAM_SESSION_READINESS_CHECK_INTERVAL = 20; // in seconds
|
||||
const char SAM_HANDSHAKE[] = "HELLO VERSION";
|
||||
const char SAM_HANDSHAKE_REPLY[] = "HELLO REPLY RESULT=OK VERSION=%s\n";
|
||||
const char SAM_HANDSHAKE_NOVERSION[] = "HELLO REPLY RESULT=NOVERSION\n";
|
||||
const char SAM_HANDSHAKE_I2P_ERROR[] = "HELLO REPLY RESULT=I2P_ERROR\n";
|
||||
const char SAM_SESSION_CREATE[] = "SESSION CREATE";
|
||||
const char SAM_SESSION_CREATE_REPLY_OK[] = "SESSION STATUS RESULT=OK DESTINATION=%s\n";
|
||||
const char SAM_SESSION_CREATE_DUPLICATED_ID[] = "SESSION STATUS RESULT=DUPLICATED_ID\n";
|
||||
const char SAM_SESSION_CREATE_DUPLICATED_DEST[] = "SESSION STATUS RESULT=DUPLICATED_DEST\n";
|
||||
const char SAM_SESSION_CREATE_INVALID_ID[] = "SESSION STATUS RESULT=INVALID_ID\n";
|
||||
const char SAM_SESSION_STATUS_INVALID_KEY[] = "SESSION STATUS RESULT=INVALID_KEY\n";
|
||||
const char SAM_SESSION_STATUS_I2P_ERROR[] = "SESSION STATUS RESULT=I2P_ERROR MESSAGE=\"%s\"\n";
|
||||
const char SAM_SESSION_ADD[] = "SESSION ADD";
|
||||
const char SAM_SESSION_REMOVE[] = "SESSION REMOVE";
|
||||
const char SAM_STREAM_CONNECT[] = "STREAM CONNECT";
|
||||
const char SAM_STREAM_STATUS_OK[] = "STREAM STATUS RESULT=OK\n";
|
||||
const char SAM_STREAM_STATUS_INVALID_ID[] = "STREAM STATUS RESULT=INVALID_ID\n";
|
||||
const char SAM_STREAM_STATUS_INVALID_KEY[] = "STREAM STATUS RESULT=INVALID_KEY\n";
|
||||
const char SAM_STREAM_STATUS_CANT_REACH_PEER[] = "STREAM STATUS RESULT=CANT_REACH_PEER\n";
|
||||
const char SAM_STREAM_STATUS_I2P_ERROR[] = "STREAM STATUS RESULT=I2P_ERROR\n";
|
||||
const char SAM_STREAM_ACCEPT[] = "STREAM ACCEPT";
|
||||
const char SAM_STREAM_FORWARD[] = "STREAM FORWARD";
|
||||
const char SAM_DATAGRAM_SEND[] = "DATAGRAM SEND";
|
||||
const char SAM_RAW_SEND[] = "RAW SEND";
|
||||
const char SAM_DEST_GENERATE[] = "DEST GENERATE";
|
||||
const char SAM_DEST_REPLY[] = "DEST REPLY PUB=%s PRIV=%s\n";
|
||||
const char SAM_DEST_REPLY_I2P_ERROR[] = "DEST REPLY RESULT=I2P_ERROR\n";
|
||||
const char SAM_NAMING_LOOKUP[] = "NAMING LOOKUP";
|
||||
const char SAM_NAMING_REPLY[] = "NAMING REPLY RESULT=OK NAME=%s VALUE=%s\n";
|
||||
const char SAM_DATAGRAM_RECEIVED[] = "DATAGRAM RECEIVED DESTINATION=%s SIZE=%lu\n";
|
||||
const char SAM_RAW_RECEIVED[] = "RAW RECEIVED SIZE=%lu\n";
|
||||
const char SAM_NAMING_REPLY_INVALID_KEY[] = "NAMING REPLY RESULT=INVALID_KEY NAME=%s\n";
|
||||
const char SAM_NAMING_REPLY_KEY_NOT_FOUND[] = "NAMING REPLY RESULT=KEY_NOT_FOUND NAME=%s\n";
|
||||
const char SAM_PARAM_MIN[] = "MIN";
|
||||
const char SAM_PARAM_MAX[] = "MAX";
|
||||
const char SAM_PARAM_STYLE[] = "STYLE";
|
||||
const char SAM_PARAM_ID[] = "ID";
|
||||
const char SAM_PARAM_SILENT[] = "SILENT";
|
||||
const char SAM_PARAM_DESTINATION[] = "DESTINATION";
|
||||
const char SAM_PARAM_NAME[] = "NAME";
|
||||
const char SAM_PARAM_SIGNATURE_TYPE[] = "SIGNATURE_TYPE";
|
||||
const char SAM_PARAM_CRYPTO_TYPE[] = "CRYPTO_TYPE";
|
||||
const char SAM_PARAM_SIZE[] = "SIZE";
|
||||
const char SAM_PARAM_HOST[] = "HOST";
|
||||
const char SAM_PARAM_PORT[] = "PORT";
|
||||
const char SAM_PARAM_FROM_PORT[] = "FROM_PORT";
|
||||
const char SAM_VALUE_TRANSIENT[] = "TRANSIENT";
|
||||
const char SAM_VALUE_STREAM[] = "STREAM";
|
||||
const char SAM_VALUE_DATAGRAM[] = "DATAGRAM";
|
||||
const char SAM_VALUE_RAW[] = "RAW";
|
||||
const char SAM_VALUE_MASTER[] = "MASTER";
|
||||
const char SAM_VALUE_TRUE[] = "true";
|
||||
const char SAM_VALUE_FALSE[] = "false";
|
||||
namespace i2p {
|
||||
namespace client {
|
||||
const size_t SAM_SOCKET_BUFFER_SIZE = 8192;
|
||||
const int SAM_SOCKET_CONNECTION_MAX_IDLE = 3600; // in seconds
|
||||
const int SAM_SESSION_READINESS_CHECK_INTERVAL = 20; // in seconds
|
||||
const char SAM_HANDSHAKE[] = "HELLO VERSION";
|
||||
const char SAM_HANDSHAKE_REPLY[] = "HELLO REPLY RESULT=OK VERSION=%s\n";
|
||||
const char SAM_HANDSHAKE_NOVERSION[] = "HELLO REPLY RESULT=NOVERSION\n";
|
||||
const char SAM_HANDSHAKE_I2P_ERROR[] = "HELLO REPLY RESULT=I2P_ERROR\n";
|
||||
const char SAM_SESSION_CREATE[] = "SESSION CREATE";
|
||||
const char SAM_SESSION_CREATE_REPLY_OK[] = "SESSION STATUS RESULT=OK DESTINATION=%s\n";
|
||||
const char SAM_SESSION_CREATE_DUPLICATED_ID[] = "SESSION STATUS RESULT=DUPLICATED_ID\n";
|
||||
const char SAM_SESSION_CREATE_DUPLICATED_DEST[] = "SESSION STATUS RESULT=DUPLICATED_DEST\n";
|
||||
const char SAM_SESSION_CREATE_INVALID_ID[] = "SESSION STATUS RESULT=INVALID_ID\n";
|
||||
const char SAM_SESSION_STATUS_INVALID_KEY[] = "SESSION STATUS RESULT=INVALID_KEY\n";
|
||||
const char SAM_SESSION_STATUS_I2P_ERROR[] = "SESSION STATUS RESULT=I2P_ERROR MESSAGE=\"%s\"\n";
|
||||
const char SAM_SESSION_ADD[] = "SESSION ADD";
|
||||
const char SAM_SESSION_REMOVE[] = "SESSION REMOVE";
|
||||
const char SAM_STREAM_CONNECT[] = "STREAM CONNECT";
|
||||
const char SAM_STREAM_STATUS_OK[] = "STREAM STATUS RESULT=OK\n";
|
||||
const char SAM_STREAM_STATUS_INVALID_ID[] = "STREAM STATUS RESULT=INVALID_ID\n";
|
||||
const char SAM_STREAM_STATUS_INVALID_KEY[] = "STREAM STATUS RESULT=INVALID_KEY\n";
|
||||
const char SAM_STREAM_STATUS_CANT_REACH_PEER[] = "STREAM STATUS RESULT=CANT_REACH_PEER\n";
|
||||
const char SAM_STREAM_STATUS_I2P_ERROR[] = "STREAM STATUS RESULT=I2P_ERROR\n";
|
||||
const char SAM_STREAM_ACCEPT[] = "STREAM ACCEPT";
|
||||
const char SAM_STREAM_FORWARD[] = "STREAM FORWARD";
|
||||
const char SAM_DATAGRAM_SEND[] = "DATAGRAM SEND";
|
||||
const char SAM_RAW_SEND[] = "RAW SEND";
|
||||
const char SAM_DEST_GENERATE[] = "DEST GENERATE";
|
||||
const char SAM_DEST_REPLY[] = "DEST REPLY PUB=%s PRIV=%s\n";
|
||||
const char SAM_DEST_REPLY_I2P_ERROR[] = "DEST REPLY RESULT=I2P_ERROR\n";
|
||||
const char SAM_NAMING_LOOKUP[] = "NAMING LOOKUP";
|
||||
const char SAM_NAMING_REPLY[] = "NAMING REPLY RESULT=OK NAME=%s VALUE=%s\n";
|
||||
const char SAM_DATAGRAM_RECEIVED[] = "DATAGRAM RECEIVED DESTINATION=%s SIZE=%lu\n";
|
||||
const char SAM_RAW_RECEIVED[] = "RAW RECEIVED SIZE=%lu\n";
|
||||
const char SAM_NAMING_REPLY_INVALID_KEY[] = "NAMING REPLY RESULT=INVALID_KEY NAME=%s\n";
|
||||
const char SAM_NAMING_REPLY_KEY_NOT_FOUND[] = "NAMING REPLY RESULT=KEY_NOT_FOUND NAME=%s\n";
|
||||
const char SAM_PARAM_MIN[] = "MIN";
|
||||
const char SAM_PARAM_MAX[] = "MAX";
|
||||
const char SAM_PARAM_STYLE[] = "STYLE";
|
||||
const char SAM_PARAM_ID[] = "ID";
|
||||
const char SAM_PARAM_SILENT[] = "SILENT";
|
||||
const char SAM_PARAM_DESTINATION[] = "DESTINATION";
|
||||
const char SAM_PARAM_NAME[] = "NAME";
|
||||
const char SAM_PARAM_SIGNATURE_TYPE[] = "SIGNATURE_TYPE";
|
||||
const char SAM_PARAM_CRYPTO_TYPE[] = "CRYPTO_TYPE";
|
||||
const char SAM_PARAM_SIZE[] = "SIZE";
|
||||
const char SAM_PARAM_HOST[] = "HOST";
|
||||
const char SAM_PARAM_PORT[] = "PORT";
|
||||
const char SAM_PARAM_FROM_PORT[] = "FROM_PORT";
|
||||
const char SAM_VALUE_TRANSIENT[] = "TRANSIENT";
|
||||
const char SAM_VALUE_STREAM[] = "STREAM";
|
||||
const char SAM_VALUE_DATAGRAM[] = "DATAGRAM";
|
||||
const char SAM_VALUE_RAW[] = "RAW";
|
||||
const char SAM_VALUE_MASTER[] = "MASTER";
|
||||
const char SAM_VALUE_TRUE[] = "true";
|
||||
const char SAM_VALUE_FALSE[] = "false";
|
||||
|
||||
enum SAMSocketType
|
||||
{
|
||||
eSAMSocketTypeUnknown,
|
||||
eSAMSocketTypeSession,
|
||||
eSAMSocketTypeStream,
|
||||
eSAMSocketTypeAcceptor,
|
||||
eSAMSocketTypeForward,
|
||||
eSAMSocketTypeTerminated
|
||||
};
|
||||
enum SAMSocketType {
|
||||
eSAMSocketTypeUnknown,
|
||||
eSAMSocketTypeSession,
|
||||
eSAMSocketTypeStream,
|
||||
eSAMSocketTypeAcceptor,
|
||||
eSAMSocketTypeForward,
|
||||
eSAMSocketTypeTerminated
|
||||
};
|
||||
|
||||
class SAMBridge;
|
||||
struct SAMSession;
|
||||
class SAMSocket: public std::enable_shared_from_this<SAMSocket>
|
||||
{
|
||||
public:
|
||||
class SAMBridge;
|
||||
|
||||
typedef boost::asio::ip::tcp::socket Socket_t;
|
||||
SAMSocket (SAMBridge& owner);
|
||||
~SAMSocket ();
|
||||
struct SAMSession;
|
||||
|
||||
Socket_t& GetSocket () { return m_Socket; };
|
||||
void ReceiveHandshake ();
|
||||
void SetSocketType (SAMSocketType socketType) { m_SocketType = socketType; };
|
||||
SAMSocketType GetSocketType () const { return m_SocketType; };
|
||||
class SAMSocket : public std::enable_shared_from_this<SAMSocket> {
|
||||
public:
|
||||
|
||||
void Terminate (const char* reason);
|
||||
typedef boost::asio::ip::tcp::socket Socket_t;
|
||||
|
||||
bool IsSession(const std::string & id) const;
|
||||
SAMSocket(SAMBridge &owner);
|
||||
|
||||
private:
|
||||
~SAMSocket();
|
||||
|
||||
void TerminateClose() { Terminate(nullptr); }
|
||||
Socket_t &GetSocket() { return m_Socket; };
|
||||
|
||||
void HandleHandshakeReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred);
|
||||
void HandleHandshakeReplySent (const boost::system::error_code& ecode, std::size_t bytes_transferred);
|
||||
void HandleMessage (const boost::system::error_code& ecode, std::size_t bytes_transferred);
|
||||
void SendMessageReply (const char * msg, size_t len, bool close);
|
||||
void HandleMessageReplySent (const boost::system::error_code& ecode, std::size_t bytes_transferred, bool close);
|
||||
void Receive ();
|
||||
void HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred);
|
||||
void ReceiveHandshake();
|
||||
|
||||
void I2PReceive ();
|
||||
void HandleI2PReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred);
|
||||
void HandleI2PAccept (std::shared_ptr<i2p::stream::Stream> stream);
|
||||
void HandleI2PForward (std::shared_ptr<i2p::stream::Stream> stream, boost::asio::ip::tcp::endpoint ep);
|
||||
void HandleWriteI2PData (const boost::system::error_code& ecode, size_t sz);
|
||||
void HandleI2PDatagramReceive (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
|
||||
void HandleI2PRawDatagramReceive (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
|
||||
void SetSocketType(SAMSocketType socketType) { m_SocketType = socketType; };
|
||||
|
||||
void ProcessSessionCreate (char * buf, size_t len);
|
||||
void ProcessStreamConnect (char * buf, size_t len, size_t rem);
|
||||
void ProcessStreamAccept (char * buf, size_t len);
|
||||
void ProcessStreamForward (char * buf, size_t len);
|
||||
void ProcessDestGenerate (char * buf, size_t len);
|
||||
void ProcessNamingLookup (char * buf, size_t len);
|
||||
void ProcessSessionAdd (char * buf, size_t len);
|
||||
void ProcessSessionRemove (char * buf, size_t len);
|
||||
void SendI2PError(const std::string & msg);
|
||||
size_t ProcessDatagramSend (char * buf, size_t len, const char * data); // from SAM 1.0
|
||||
void ExtractParams (char * buf, std::map<std::string, std::string>& params);
|
||||
SAMSocketType GetSocketType() const { return m_SocketType; };
|
||||
|
||||
void Connect (std::shared_ptr<const i2p::data::LeaseSet> remote, std::shared_ptr<SAMSession> session = nullptr);
|
||||
void HandleConnectLeaseSetRequestComplete (std::shared_ptr<i2p::data::LeaseSet> leaseSet);
|
||||
void SendNamingLookupReply (const std::string& name, std::shared_ptr<const i2p::data::IdentityEx> identity);
|
||||
void HandleNamingLookupLeaseSetRequestComplete (std::shared_ptr<i2p::data::LeaseSet> leaseSet, std::string name);
|
||||
void HandleSessionReadinessCheckTimer (const boost::system::error_code& ecode);
|
||||
void SendSessionCreateReplyOk ();
|
||||
void Terminate(const char *reason);
|
||||
|
||||
void WriteI2PData(size_t sz);
|
||||
void WriteI2PDataImmediate(uint8_t * ptr, size_t sz);
|
||||
bool IsSession(const std::string &id) const;
|
||||
|
||||
void HandleWriteI2PDataImmediate(const boost::system::error_code & ec, uint8_t * buff);
|
||||
void HandleStreamSend(const boost::system::error_code & ec);
|
||||
private:
|
||||
|
||||
private:
|
||||
void TerminateClose() { Terminate(nullptr); }
|
||||
|
||||
SAMBridge& m_Owner;
|
||||
Socket_t m_Socket;
|
||||
boost::asio::deadline_timer m_Timer;
|
||||
char m_Buffer[SAM_SOCKET_BUFFER_SIZE + 1];
|
||||
size_t m_BufferOffset;
|
||||
uint8_t m_StreamBuffer[SAM_SOCKET_BUFFER_SIZE];
|
||||
SAMSocketType m_SocketType;
|
||||
std::string m_ID; // nickname
|
||||
bool m_IsSilent;
|
||||
bool m_IsAccepting; // for eSAMSocketTypeAcceptor only
|
||||
std::shared_ptr<i2p::stream::Stream> m_Stream;
|
||||
};
|
||||
void HandleHandshakeReceived(const boost::system::error_code &ecode, std::size_t bytes_transferred);
|
||||
|
||||
enum SAMSessionType
|
||||
{
|
||||
eSAMSessionTypeUnknown,
|
||||
eSAMSessionTypeStream,
|
||||
eSAMSessionTypeDatagram,
|
||||
eSAMSessionTypeRaw,
|
||||
eSAMSessionTypeMaster
|
||||
};
|
||||
void HandleHandshakeReplySent(const boost::system::error_code &ecode, std::size_t bytes_transferred);
|
||||
|
||||
struct SAMSession
|
||||
{
|
||||
SAMBridge & m_Bridge;
|
||||
std::string Name;
|
||||
SAMSessionType Type;
|
||||
std::shared_ptr<boost::asio::ip::udp::endpoint> UDPEndpoint; // TODO: move
|
||||
void HandleMessage(const boost::system::error_code &ecode, std::size_t bytes_transferred);
|
||||
|
||||
SAMSession (SAMBridge & parent, const std::string & name, SAMSessionType type);
|
||||
virtual ~SAMSession () {};
|
||||
void SendMessageReply(const char *msg, size_t len, bool close);
|
||||
|
||||
virtual std::shared_ptr<ClientDestination> GetLocalDestination () = 0;
|
||||
virtual void StopLocalDestination () = 0;
|
||||
virtual void Close () { CloseStreams (); };
|
||||
void
|
||||
HandleMessageReplySent(const boost::system::error_code &ecode, std::size_t bytes_transferred, bool close);
|
||||
|
||||
void CloseStreams ();
|
||||
};
|
||||
void Receive();
|
||||
|
||||
struct SAMSingleSession: public SAMSession
|
||||
{
|
||||
std::shared_ptr<ClientDestination> localDestination;
|
||||
void HandleReceived(const boost::system::error_code &ecode, std::size_t bytes_transferred);
|
||||
|
||||
SAMSingleSession (SAMBridge & parent, const std::string & name, SAMSessionType type, std::shared_ptr<ClientDestination> dest);
|
||||
~SAMSingleSession ();
|
||||
void I2PReceive();
|
||||
|
||||
std::shared_ptr<ClientDestination> GetLocalDestination () { return localDestination; };
|
||||
void StopLocalDestination ();
|
||||
};
|
||||
void HandleI2PReceive(const boost::system::error_code &ecode, std::size_t bytes_transferred);
|
||||
|
||||
struct SAMMasterSession: public SAMSingleSession
|
||||
{
|
||||
std::set<std::string> subsessions;
|
||||
SAMMasterSession (SAMBridge & parent, const std::string & name, std::shared_ptr<ClientDestination> dest):
|
||||
SAMSingleSession (parent, name, eSAMSessionTypeMaster, dest) {};
|
||||
void Close ();
|
||||
};
|
||||
void HandleI2PAccept(std::shared_ptr <i2p::stream::Stream> stream);
|
||||
|
||||
struct SAMSubSession: public SAMSession
|
||||
{
|
||||
std::shared_ptr<SAMMasterSession> masterSession;
|
||||
int inPort;
|
||||
void HandleI2PForward(std::shared_ptr <i2p::stream::Stream> stream, boost::asio::ip::tcp::endpoint ep);
|
||||
|
||||
SAMSubSession (std::shared_ptr<SAMMasterSession> master, const std::string& name, SAMSessionType type, int port);
|
||||
// implements SAMSession
|
||||
std::shared_ptr<ClientDestination> GetLocalDestination ();
|
||||
void StopLocalDestination ();
|
||||
};
|
||||
void HandleWriteI2PData(const boost::system::error_code &ecode, size_t sz);
|
||||
|
||||
class SAMBridge: private i2p::util::RunnableService
|
||||
{
|
||||
public:
|
||||
void HandleI2PDatagramReceive(const i2p::data::IdentityEx &from, uint16_t fromPort, uint16_t toPort,
|
||||
const uint8_t *buf, size_t len);
|
||||
|
||||
SAMBridge (const std::string& address, int port, bool singleThread);
|
||||
~SAMBridge ();
|
||||
void HandleI2PRawDatagramReceive(uint16_t fromPort, uint16_t toPort, const uint8_t *buf, size_t len);
|
||||
|
||||
void Start ();
|
||||
void Stop ();
|
||||
void ProcessSessionCreate(char *buf, size_t len);
|
||||
|
||||
boost::asio::io_service& GetService () { return GetIOService (); };
|
||||
std::shared_ptr<SAMSession> CreateSession (const std::string& id, SAMSessionType type, const std::string& destination, // empty string means transient
|
||||
const std::map<std::string, std::string> * params);
|
||||
bool AddSession (std::shared_ptr<SAMSession> session);
|
||||
void CloseSession (const std::string& id);
|
||||
std::shared_ptr<SAMSession> FindSession (const std::string& id) const;
|
||||
void ProcessStreamConnect(char *buf, size_t len, size_t rem);
|
||||
|
||||
std::list<std::shared_ptr<SAMSocket> > ListSockets(const std::string & id) const;
|
||||
void ProcessStreamAccept(char *buf, size_t len);
|
||||
|
||||
/** send raw data to remote endpoint from our UDP Socket */
|
||||
void SendTo (const std::vector<boost::asio::const_buffer>& bufs, const boost::asio::ip::udp::endpoint& ep);
|
||||
void ProcessStreamForward(char *buf, size_t len);
|
||||
|
||||
void AddSocket(std::shared_ptr<SAMSocket> socket);
|
||||
void RemoveSocket(const std::shared_ptr<SAMSocket> & socket);
|
||||
void ProcessDestGenerate(char *buf, size_t len);
|
||||
|
||||
bool ResolveSignatureType (const std::string& name, i2p::data::SigningKeyType& type) const;
|
||||
void ProcessNamingLookup(char *buf, size_t len);
|
||||
|
||||
private:
|
||||
void ProcessSessionAdd(char *buf, size_t len);
|
||||
|
||||
void Accept ();
|
||||
void HandleAccept(const boost::system::error_code& ecode, std::shared_ptr<SAMSocket> socket);
|
||||
void ProcessSessionRemove(char *buf, size_t len);
|
||||
|
||||
void ReceiveDatagram ();
|
||||
void HandleReceivedDatagram (const boost::system::error_code& ecode, std::size_t bytes_transferred);
|
||||
void SendI2PError(const std::string &msg);
|
||||
|
||||
private:
|
||||
size_t ProcessDatagramSend(char *buf, size_t len, const char *data); // from SAM 1.0
|
||||
void ExtractParams(char *buf, std::map <std::string, std::string> ¶ms);
|
||||
|
||||
bool m_IsSingleThread;
|
||||
boost::asio::ip::tcp::acceptor m_Acceptor;
|
||||
boost::asio::ip::udp::endpoint m_DatagramEndpoint, m_SenderEndpoint;
|
||||
boost::asio::ip::udp::socket m_DatagramSocket;
|
||||
mutable std::mutex m_SessionsMutex;
|
||||
std::map<std::string, std::shared_ptr<SAMSession> > m_Sessions;
|
||||
mutable std::mutex m_OpenSocketsMutex;
|
||||
std::list<std::shared_ptr<SAMSocket> > m_OpenSockets;
|
||||
uint8_t m_DatagramReceiveBuffer[i2p::datagram::MAX_DATAGRAM_SIZE+1];
|
||||
std::map<std::string, i2p::data::SigningKeyType> m_SignatureTypes;
|
||||
void
|
||||
Connect(std::shared_ptr<const i2p::data::LeaseSet> remote, std::shared_ptr <SAMSession> session = nullptr);
|
||||
|
||||
public:
|
||||
void HandleConnectLeaseSetRequestComplete(std::shared_ptr <i2p::data::LeaseSet> leaseSet);
|
||||
|
||||
// for HTTP
|
||||
const decltype(m_Sessions)& GetSessions () const { return m_Sessions; };
|
||||
};
|
||||
}
|
||||
void SendNamingLookupReply(const std::string &name, std::shared_ptr<const i2p::data::IdentityEx> identity);
|
||||
|
||||
void
|
||||
HandleNamingLookupLeaseSetRequestComplete(std::shared_ptr <i2p::data::LeaseSet> leaseSet, std::string name);
|
||||
|
||||
void HandleSessionReadinessCheckTimer(const boost::system::error_code &ecode);
|
||||
|
||||
void SendSessionCreateReplyOk();
|
||||
|
||||
void WriteI2PData(size_t sz);
|
||||
|
||||
void WriteI2PDataImmediate(uint8_t *ptr, size_t sz);
|
||||
|
||||
void HandleWriteI2PDataImmediate(const boost::system::error_code &ec, uint8_t *buff);
|
||||
|
||||
void HandleStreamSend(const boost::system::error_code &ec);
|
||||
|
||||
private:
|
||||
|
||||
SAMBridge &m_Owner;
|
||||
Socket_t m_Socket;
|
||||
boost::asio::deadline_timer m_Timer;
|
||||
char m_Buffer[SAM_SOCKET_BUFFER_SIZE + 1];
|
||||
size_t m_BufferOffset;
|
||||
uint8_t m_StreamBuffer[SAM_SOCKET_BUFFER_SIZE];
|
||||
SAMSocketType m_SocketType;
|
||||
std::string m_ID; // nickname
|
||||
bool m_IsSilent;
|
||||
bool m_IsAccepting; // for eSAMSocketTypeAcceptor only
|
||||
std::shared_ptr <i2p::stream::Stream> m_Stream;
|
||||
};
|
||||
|
||||
enum SAMSessionType {
|
||||
eSAMSessionTypeUnknown,
|
||||
eSAMSessionTypeStream,
|
||||
eSAMSessionTypeDatagram,
|
||||
eSAMSessionTypeRaw,
|
||||
eSAMSessionTypeMaster
|
||||
};
|
||||
|
||||
struct SAMSession {
|
||||
SAMBridge &m_Bridge;
|
||||
std::string Name;
|
||||
SAMSessionType Type;
|
||||
std::shared_ptr <boost::asio::ip::udp::endpoint> UDPEndpoint; // TODO: move
|
||||
|
||||
SAMSession(SAMBridge &parent, const std::string &name, SAMSessionType type);
|
||||
|
||||
virtual ~SAMSession() {};
|
||||
|
||||
virtual std::shared_ptr <ClientDestination> GetLocalDestination() = 0;
|
||||
|
||||
virtual void StopLocalDestination() = 0;
|
||||
|
||||
virtual void Close() { CloseStreams(); };
|
||||
|
||||
void CloseStreams();
|
||||
};
|
||||
|
||||
struct SAMSingleSession : public SAMSession {
|
||||
std::shared_ptr <ClientDestination> localDestination;
|
||||
|
||||
SAMSingleSession(SAMBridge &parent, const std::string &name, SAMSessionType type,
|
||||
std::shared_ptr <ClientDestination> dest);
|
||||
|
||||
~SAMSingleSession();
|
||||
|
||||
std::shared_ptr <ClientDestination> GetLocalDestination() { return localDestination; };
|
||||
|
||||
void StopLocalDestination();
|
||||
};
|
||||
|
||||
struct SAMMasterSession : public SAMSingleSession {
|
||||
std::set <std::string> subsessions;
|
||||
|
||||
SAMMasterSession(SAMBridge &parent, const std::string &name, std::shared_ptr <ClientDestination> dest) :
|
||||
SAMSingleSession(parent, name, eSAMSessionTypeMaster, dest) {};
|
||||
|
||||
void Close();
|
||||
};
|
||||
|
||||
struct SAMSubSession : public SAMSession {
|
||||
std::shared_ptr <SAMMasterSession> masterSession;
|
||||
int inPort;
|
||||
|
||||
SAMSubSession(std::shared_ptr <SAMMasterSession> master, const std::string &name, SAMSessionType type,
|
||||
int port);
|
||||
|
||||
// implements SAMSession
|
||||
std::shared_ptr <ClientDestination> GetLocalDestination();
|
||||
|
||||
void StopLocalDestination();
|
||||
};
|
||||
|
||||
class SAMBridge : private i2p::util::RunnableService {
|
||||
public:
|
||||
|
||||
SAMBridge(const std::string &address, int port, bool singleThread);
|
||||
|
||||
~SAMBridge();
|
||||
|
||||
void Start();
|
||||
|
||||
void Stop();
|
||||
|
||||
boost::asio::io_service &GetService() { return GetIOService(); };
|
||||
|
||||
std::shared_ptr <SAMSession> CreateSession(const std::string &id, SAMSessionType type,
|
||||
const std::string &destination, // empty string means transient
|
||||
const std::map <std::string, std::string> *params);
|
||||
|
||||
bool AddSession(std::shared_ptr <SAMSession> session);
|
||||
|
||||
void CloseSession(const std::string &id);
|
||||
|
||||
std::shared_ptr <SAMSession> FindSession(const std::string &id) const;
|
||||
|
||||
std::list <std::shared_ptr<SAMSocket>> ListSockets(const std::string &id) const;
|
||||
|
||||
/** send raw data to remote endpoint from our UDP Socket */
|
||||
void SendTo(const std::vector <boost::asio::const_buffer> &bufs, const boost::asio::ip::udp::endpoint &ep);
|
||||
|
||||
void AddSocket(std::shared_ptr <SAMSocket> socket);
|
||||
|
||||
void RemoveSocket(const std::shared_ptr <SAMSocket> &socket);
|
||||
|
||||
bool ResolveSignatureType(const std::string &name, i2p::data::SigningKeyType &type) const;
|
||||
|
||||
private:
|
||||
|
||||
void Accept();
|
||||
|
||||
void HandleAccept(const boost::system::error_code &ecode, std::shared_ptr <SAMSocket> socket);
|
||||
|
||||
void ReceiveDatagram();
|
||||
|
||||
void HandleReceivedDatagram(const boost::system::error_code &ecode, std::size_t bytes_transferred);
|
||||
|
||||
private:
|
||||
|
||||
bool m_IsSingleThread;
|
||||
boost::asio::ip::tcp::acceptor m_Acceptor;
|
||||
boost::asio::ip::udp::endpoint m_DatagramEndpoint, m_SenderEndpoint;
|
||||
boost::asio::ip::udp::socket m_DatagramSocket;
|
||||
mutable std::mutex m_SessionsMutex;
|
||||
std::map <std::string, std::shared_ptr<SAMSession>> m_Sessions;
|
||||
mutable std::mutex m_OpenSocketsMutex;
|
||||
std::list <std::shared_ptr<SAMSocket>> m_OpenSockets;
|
||||
uint8_t m_DatagramReceiveBuffer[i2p::datagram::MAX_DATAGRAM_SIZE + 1];
|
||||
std::map <std::string, i2p::data::SigningKeyType> m_SignatureTypes;
|
||||
|
||||
public:
|
||||
|
||||
// for HTTP
|
||||
const decltype(m_Sessions)
|
||||
&
|
||||
|
||||
GetSessions() const { return m_Sessions; };
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -15,35 +15,36 @@
|
|||
#include <mutex>
|
||||
#include "I2PService.h"
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
namespace proxy
|
||||
{
|
||||
class SOCKSServer: public i2p::client::TCPIPAcceptor
|
||||
{
|
||||
public:
|
||||
namespace i2p {
|
||||
namespace proxy {
|
||||
class SOCKSServer : public i2p::client::TCPIPAcceptor {
|
||||
public:
|
||||
|
||||
SOCKSServer(const std::string& name, const std::string& address, int port, bool outEnable, const std::string& outAddress, uint16_t outPort,
|
||||
std::shared_ptr<i2p::client::ClientDestination> localDestination = nullptr);
|
||||
~SOCKSServer() {};
|
||||
SOCKSServer(const std::string &name, const std::string &address, int port, bool outEnable,
|
||||
const std::string &outAddress, uint16_t outPort,
|
||||
std::shared_ptr <i2p::client::ClientDestination> localDestination = nullptr);
|
||||
|
||||
void SetUpstreamProxy(const std::string & addr, const uint16_t port);
|
||||
~SOCKSServer() {};
|
||||
|
||||
protected:
|
||||
void SetUpstreamProxy(const std::string &addr, const uint16_t port);
|
||||
|
||||
// Implements TCPIPAcceptor
|
||||
std::shared_ptr<i2p::client::I2PServiceHandler> CreateHandler(std::shared_ptr<boost::asio::ip::tcp::socket> socket);
|
||||
const char* GetName() { return m_Name.c_str (); }
|
||||
protected:
|
||||
|
||||
private:
|
||||
// Implements TCPIPAcceptor
|
||||
std::shared_ptr <i2p::client::I2PServiceHandler>
|
||||
CreateHandler(std::shared_ptr <boost::asio::ip::tcp::socket> socket);
|
||||
|
||||
std::string m_Name;
|
||||
std::string m_UpstreamProxyAddress;
|
||||
uint16_t m_UpstreamProxyPort;
|
||||
bool m_UseUpstreamProxy;
|
||||
};
|
||||
const char *GetName() { return m_Name.c_str(); }
|
||||
|
||||
typedef SOCKSServer SOCKSProxy;
|
||||
}
|
||||
private:
|
||||
|
||||
std::string m_Name;
|
||||
std::string m_UpstreamProxyAddress;
|
||||
uint16_t m_UpstreamProxyPort;
|
||||
bool m_UseUpstreamProxy;
|
||||
};
|
||||
|
||||
typedef SOCKSServer SOCKSProxy;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue