mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-02-02 02:54:01 +01:00
fix code syle(spaces->tabs, tabulations)
Signed-off-by: R4SAS <r4sas@i2pmail.org>
This commit is contained in:
parent
9633c247f0
commit
7a5146ea74
|
@ -26,48 +26,48 @@
|
||||||
|
|
||||||
class I2PService
|
class I2PService
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
I2PService(PSTR pszServiceName,
|
I2PService(PSTR pszServiceName,
|
||||||
BOOL fCanStop = TRUE,
|
BOOL fCanStop = TRUE,
|
||||||
BOOL fCanShutdown = TRUE,
|
BOOL fCanShutdown = TRUE,
|
||||||
BOOL fCanPauseContinue = FALSE);
|
BOOL fCanPauseContinue = FALSE);
|
||||||
|
|
||||||
virtual ~I2PService(void);
|
virtual ~I2PService(void);
|
||||||
|
|
||||||
static BOOL isService();
|
static BOOL isService();
|
||||||
static BOOL Run(I2PService &service);
|
static BOOL Run(I2PService &service);
|
||||||
void Stop();
|
void Stop();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual void OnStart(DWORD dwArgc, PSTR *pszArgv);
|
virtual void OnStart(DWORD dwArgc, PSTR *pszArgv);
|
||||||
virtual void OnStop();
|
virtual void OnStop();
|
||||||
virtual void OnPause();
|
virtual void OnPause();
|
||||||
virtual void OnContinue();
|
virtual void OnContinue();
|
||||||
virtual void OnShutdown();
|
virtual void OnShutdown();
|
||||||
void SetServiceStatus(DWORD dwCurrentState,
|
void SetServiceStatus(DWORD dwCurrentState,
|
||||||
DWORD dwWin32ExitCode = NO_ERROR,
|
DWORD dwWin32ExitCode = NO_ERROR,
|
||||||
DWORD dwWaitHint = 0);
|
DWORD dwWaitHint = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static void WINAPI ServiceMain(DWORD dwArgc, LPSTR *lpszArgv);
|
static void WINAPI ServiceMain(DWORD dwArgc, LPSTR *lpszArgv);
|
||||||
static void WINAPI ServiceCtrlHandler(DWORD dwCtrl);
|
static void WINAPI ServiceCtrlHandler(DWORD dwCtrl);
|
||||||
void WorkerThread();
|
void WorkerThread();
|
||||||
void Start(DWORD dwArgc, PSTR *pszArgv);
|
void Start(DWORD dwArgc, PSTR *pszArgv);
|
||||||
void Pause();
|
void Pause();
|
||||||
void Continue();
|
void Continue();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
static I2PService* s_service;
|
static I2PService* s_service;
|
||||||
PSTR m_name;
|
PSTR m_name;
|
||||||
SERVICE_STATUS m_status;
|
SERVICE_STATUS m_status;
|
||||||
SERVICE_STATUS_HANDLE m_statusHandle;
|
SERVICE_STATUS_HANDLE m_statusHandle;
|
||||||
|
|
||||||
BOOL m_fStopping;
|
BOOL m_fStopping;
|
||||||
HANDLE m_hStoppedEvent;
|
HANDLE m_hStoppedEvent;
|
||||||
|
|
||||||
std::thread* _worker;
|
std::thread* _worker;
|
||||||
};
|
};
|
||||||
|
|
||||||
void InstallService(
|
void InstallService(
|
||||||
|
@ -77,7 +77,7 @@ void InstallService(
|
||||||
PCSTR pszDependencies,
|
PCSTR pszDependencies,
|
||||||
PCSTR pszAccount,
|
PCSTR pszAccount,
|
||||||
PCSTR pszPassword
|
PCSTR pszPassword
|
||||||
);
|
);
|
||||||
|
|
||||||
void UninstallService(PCSTR pszServiceName);
|
void UninstallService(PCSTR pszServiceName);
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
//{{NO_DEPENDENCIES}}
|
//{{NO_DEPENDENCIES}}
|
||||||
#define MAINICON 101
|
#define MAINICON 101
|
||||||
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
#ifdef APSTUDIO_INVOKED
|
||||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||||
#define _APS_NEXT_RESOURCE_VALUE 102
|
#define _APS_NEXT_RESOURCE_VALUE 102
|
||||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||||
#define _APS_NEXT_SYMED_VALUE 101
|
#define _APS_NEXT_SYMED_VALUE 101
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -127,8 +127,8 @@ namespace i2p
|
||||||
i2p::context.SetNetID (netID);
|
i2p::context.SetNetID (netID);
|
||||||
i2p::context.Init ();
|
i2p::context.Init ();
|
||||||
|
|
||||||
bool ipv6; i2p::config::GetOption("ipv6", ipv6);
|
bool ipv6; i2p::config::GetOption("ipv6", ipv6);
|
||||||
bool ipv4; i2p::config::GetOption("ipv4", ipv4);
|
bool ipv4; i2p::config::GetOption("ipv4", ipv4);
|
||||||
#ifdef MESHNET
|
#ifdef MESHNET
|
||||||
// manual override for meshnet
|
// manual override for meshnet
|
||||||
ipv4 = false;
|
ipv4 = false;
|
||||||
|
@ -143,7 +143,7 @@ namespace i2p
|
||||||
i2p::context.SetSupportsV6 (ipv6);
|
i2p::context.SetSupportsV6 (ipv6);
|
||||||
i2p::context.SetSupportsV4 (ipv4);
|
i2p::context.SetSupportsV4 (ipv4);
|
||||||
|
|
||||||
bool ntcp; i2p::config::GetOption("ntcp", ntcp);
|
bool ntcp; i2p::config::GetOption("ntcp", ntcp);
|
||||||
i2p::context.PublishNTCPAddress (ntcp, !ipv6);
|
i2p::context.PublishNTCPAddress (ntcp, !ipv6);
|
||||||
bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
|
bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
|
||||||
if (ntcp2)
|
if (ntcp2)
|
||||||
|
@ -172,10 +172,13 @@ namespace i2p
|
||||||
SetMaxNumTransitTunnels (transitTunnels);
|
SetMaxNumTransitTunnels (transitTunnels);
|
||||||
|
|
||||||
bool isFloodfill; i2p::config::GetOption("floodfill", isFloodfill);
|
bool isFloodfill; i2p::config::GetOption("floodfill", isFloodfill);
|
||||||
if (isFloodfill) {
|
if (isFloodfill)
|
||||||
|
{
|
||||||
LogPrint(eLogInfo, "Daemon: router will be floodfill");
|
LogPrint(eLogInfo, "Daemon: router will be floodfill");
|
||||||
i2p::context.SetFloodfill (true);
|
i2p::context.SetFloodfill (true);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
i2p::context.SetFloodfill (false);
|
i2p::context.SetFloodfill (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,7 +246,8 @@ namespace i2p
|
||||||
i2p::transport::transports.RestrictRoutesToFamilies(fams);
|
i2p::transport::transports.RestrictRoutesToFamilies(fams);
|
||||||
restricted = fams.size() > 0;
|
restricted = fams.size() > 0;
|
||||||
}
|
}
|
||||||
if (routers.length() > 0) {
|
if (routers.length() > 0)
|
||||||
|
{
|
||||||
std::set<i2p::data::IdentHash> idents;
|
std::set<i2p::data::IdentHash> idents;
|
||||||
size_t pos = 0, comma;
|
size_t pos = 0, comma;
|
||||||
do
|
do
|
||||||
|
@ -279,7 +283,8 @@ namespace i2p
|
||||||
i2p::data::netdb.Start();
|
i2p::data::netdb.Start();
|
||||||
|
|
||||||
bool upnp; i2p::config::GetOption("upnp.enabled", upnp);
|
bool upnp; i2p::config::GetOption("upnp.enabled", upnp);
|
||||||
if (upnp) {
|
if (upnp)
|
||||||
|
{
|
||||||
d.UPnP = std::unique_ptr<i2p::transport::UPnP>(new i2p::transport::UPnP);
|
d.UPnP = std::unique_ptr<i2p::transport::UPnP>(new i2p::transport::UPnP);
|
||||||
d.UPnP->Start ();
|
d.UPnP->Start ();
|
||||||
}
|
}
|
||||||
|
@ -292,7 +297,7 @@ namespace i2p
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ntcp; i2p::config::GetOption("ntcp", ntcp);
|
bool ntcp; i2p::config::GetOption("ntcp", ntcp);
|
||||||
bool ssu; i2p::config::GetOption("ssu", ssu);
|
bool ssu; i2p::config::GetOption("ssu", ssu);
|
||||||
LogPrint(eLogInfo, "Daemon: starting Transports");
|
LogPrint(eLogInfo, "Daemon: starting Transports");
|
||||||
if(!ssu) LogPrint(eLogInfo, "Daemon: ssu disabled");
|
if(!ssu) LogPrint(eLogInfo, "Daemon: ssu disabled");
|
||||||
if(!ntcp) LogPrint(eLogInfo, "Daemon: ntcp disabled");
|
if(!ntcp) LogPrint(eLogInfo, "Daemon: ntcp disabled");
|
||||||
|
@ -310,7 +315,8 @@ namespace i2p
|
||||||
}
|
}
|
||||||
|
|
||||||
bool http; i2p::config::GetOption("http.enabled", http);
|
bool http; i2p::config::GetOption("http.enabled", http);
|
||||||
if (http) {
|
if (http)
|
||||||
|
{
|
||||||
std::string httpAddr; i2p::config::GetOption("http.address", httpAddr);
|
std::string httpAddr; i2p::config::GetOption("http.address", httpAddr);
|
||||||
uint16_t httpPort; i2p::config::GetOption("http.port", httpPort);
|
uint16_t httpPort; i2p::config::GetOption("http.port", httpPort);
|
||||||
LogPrint(eLogInfo, "Daemon: starting webconsole at ", httpAddr, ":", httpPort);
|
LogPrint(eLogInfo, "Daemon: starting webconsole at ", httpAddr, ":", httpPort);
|
||||||
|
@ -326,7 +332,6 @@ namespace i2p
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LogPrint(eLogInfo, "Daemon: starting Tunnels");
|
LogPrint(eLogInfo, "Daemon: starting Tunnels");
|
||||||
i2p::tunnel::tunnels.Start();
|
i2p::tunnel::tunnels.Start();
|
||||||
|
|
||||||
|
|
|
@ -13,9 +13,10 @@ namespace util
|
||||||
class Daemon_Singleton
|
class Daemon_Singleton
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual bool init(int argc, char* argv[], std::shared_ptr<std::ostream> logstream);
|
|
||||||
virtual bool init(int argc, char* argv[]);
|
virtual bool init(int argc, char* argv[], std::shared_ptr<std::ostream> logstream);
|
||||||
virtual bool start();
|
virtual bool init(int argc, char* argv[]);
|
||||||
|
virtual bool start();
|
||||||
virtual bool stop();
|
virtual bool stop();
|
||||||
virtual void run () {};
|
virtual void run () {};
|
||||||
|
|
||||||
|
@ -23,6 +24,7 @@ namespace util
|
||||||
bool running;
|
bool running;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
Daemon_Singleton();
|
Daemon_Singleton();
|
||||||
virtual ~Daemon_Singleton();
|
virtual ~Daemon_Singleton();
|
||||||
|
|
||||||
|
@ -39,6 +41,7 @@ namespace util
|
||||||
class DaemonQT: public i2p::util::Daemon_Singleton
|
class DaemonQT: public i2p::util::Daemon_Singleton
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static DaemonQT& Instance()
|
static DaemonQT& Instance()
|
||||||
{
|
{
|
||||||
static DaemonQT instance;
|
static DaemonQT instance;
|
||||||
|
@ -51,6 +54,7 @@ namespace util
|
||||||
class DaemonWin32 : public Daemon_Singleton
|
class DaemonWin32 : public Daemon_Singleton
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static DaemonWin32& Instance()
|
static DaemonWin32& Instance()
|
||||||
{
|
{
|
||||||
static DaemonWin32 instance;
|
static DaemonWin32 instance;
|
||||||
|
@ -72,6 +76,7 @@ namespace util
|
||||||
class DaemonAndroid: public i2p::util::Daemon_Singleton
|
class DaemonAndroid: public i2p::util::Daemon_Singleton
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static DaemonAndroid& Instance()
|
static DaemonAndroid& Instance()
|
||||||
{
|
{
|
||||||
static DaemonAndroid instance;
|
static DaemonAndroid instance;
|
||||||
|
@ -83,6 +88,7 @@ namespace util
|
||||||
class DaemonLinux : public Daemon_Singleton
|
class DaemonLinux : public Daemon_Singleton
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static DaemonLinux& Instance()
|
static DaemonLinux& Instance()
|
||||||
{
|
{
|
||||||
static DaemonLinux instance;
|
static DaemonLinux instance;
|
||||||
|
@ -94,10 +100,12 @@ namespace util
|
||||||
void run ();
|
void run ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::string pidfile;
|
std::string pidfile;
|
||||||
int pidFH;
|
int pidFH;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
int gracefulShutdownInterval; // in seconds
|
int gracefulShutdownInterval; // in seconds
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -892,8 +892,8 @@ namespace http {
|
||||||
void HTTPConnection::Receive ()
|
void HTTPConnection::Receive ()
|
||||||
{
|
{
|
||||||
m_Socket->async_read_some (boost::asio::buffer (m_Buffer, HTTP_CONNECTION_BUFFER_SIZE),
|
m_Socket->async_read_some (boost::asio::buffer (m_Buffer, HTTP_CONNECTION_BUFFER_SIZE),
|
||||||
std::bind(&HTTPConnection::HandleReceive, shared_from_this (),
|
std::bind(&HTTPConnection::HandleReceive, shared_from_this (),
|
||||||
std::placeholders::_1, std::placeholders::_2));
|
std::placeholders::_1, std::placeholders::_2));
|
||||||
}
|
}
|
||||||
|
|
||||||
void HTTPConnection::HandleReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred)
|
void HTTPConnection::HandleReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred)
|
||||||
|
|
|
@ -79,17 +79,17 @@ namespace http
|
||||||
std::string m_Hostname;
|
std::string m_Hostname;
|
||||||
};
|
};
|
||||||
|
|
||||||
//all the below functions are also used by Qt GUI, see mainwindow.cpp -> getStatusPageHtml
|
//all the below functions are also used by Qt GUI, see mainwindow.cpp -> getStatusPageHtml
|
||||||
enum OutputFormatEnum { forWebConsole, forQtUi };
|
enum OutputFormatEnum { forWebConsole, forQtUi };
|
||||||
void ShowStatus (std::stringstream& s, bool includeHiddenContent, OutputFormatEnum outputFormat);
|
void ShowStatus (std::stringstream& s, bool includeHiddenContent, OutputFormatEnum outputFormat);
|
||||||
void ShowLocalDestinations (std::stringstream& s);
|
void ShowLocalDestinations (std::stringstream& s);
|
||||||
void ShowLeasesSets(std::stringstream& s);
|
void ShowLeasesSets(std::stringstream& s);
|
||||||
void ShowTunnels (std::stringstream& s);
|
void ShowTunnels (std::stringstream& s);
|
||||||
void ShowTransitTunnels (std::stringstream& s);
|
void ShowTransitTunnels (std::stringstream& s);
|
||||||
void ShowTransports (std::stringstream& s);
|
void ShowTransports (std::stringstream& s);
|
||||||
void ShowSAMSessions (std::stringstream& s);
|
void ShowSAMSessions (std::stringstream& s);
|
||||||
void ShowI2PTunnels (std::stringstream& s);
|
void ShowI2PTunnels (std::stringstream& s);
|
||||||
void ShowLocalDestination (std::stringstream& s, const std::string& b32, uint32_t token);
|
void ShowLocalDestination (std::stringstream& s, const std::string& b32, uint32_t token);
|
||||||
} // http
|
} // http
|
||||||
} // i2p
|
} // i2p
|
||||||
|
|
||||||
|
|
|
@ -59,29 +59,28 @@ namespace client
|
||||||
m_SSLContext.use_private_key_file (i2pcp_key, boost::asio::ssl::context::pem);
|
m_SSLContext.use_private_key_file (i2pcp_key, boost::asio::ssl::context::pem);
|
||||||
|
|
||||||
// handlers
|
// handlers
|
||||||
m_MethodHandlers["Authenticate"] = &I2PControlService::AuthenticateHandler;
|
m_MethodHandlers["Authenticate"] = &I2PControlService::AuthenticateHandler;
|
||||||
m_MethodHandlers["Echo"] = &I2PControlService::EchoHandler;
|
m_MethodHandlers["Echo"] = &I2PControlService::EchoHandler;
|
||||||
m_MethodHandlers["I2PControl"] = &I2PControlService::I2PControlHandler;
|
m_MethodHandlers["I2PControl"] = &I2PControlService::I2PControlHandler;
|
||||||
m_MethodHandlers["RouterInfo"] = &I2PControlService::RouterInfoHandler;
|
m_MethodHandlers["RouterInfo"] = &I2PControlService::RouterInfoHandler;
|
||||||
m_MethodHandlers["RouterManager"] = &I2PControlService::RouterManagerHandler;
|
m_MethodHandlers["RouterManager"] = &I2PControlService::RouterManagerHandler;
|
||||||
m_MethodHandlers["NetworkSetting"] = &I2PControlService::NetworkSettingHandler;
|
m_MethodHandlers["NetworkSetting"] = &I2PControlService::NetworkSettingHandler;
|
||||||
m_MethodHandlers["ClientServicesInfo"] = &I2PControlService::ClientServicesInfoHandler;
|
m_MethodHandlers["ClientServicesInfo"] = &I2PControlService::ClientServicesInfoHandler;
|
||||||
|
|
||||||
// I2PControl
|
// I2PControl
|
||||||
m_I2PControlHandlers["i2pcontrol.password"] = &I2PControlService::PasswordHandler;
|
m_I2PControlHandlers["i2pcontrol.password"] = &I2PControlService::PasswordHandler;
|
||||||
|
|
||||||
// RouterInfo
|
// RouterInfo
|
||||||
m_RouterInfoHandlers["i2p.router.uptime"] = &I2PControlService::UptimeHandler;
|
m_RouterInfoHandlers["i2p.router.uptime"] = &I2PControlService::UptimeHandler;
|
||||||
m_RouterInfoHandlers["i2p.router.version"] = &I2PControlService::VersionHandler;
|
m_RouterInfoHandlers["i2p.router.version"] = &I2PControlService::VersionHandler;
|
||||||
m_RouterInfoHandlers["i2p.router.status"] = &I2PControlService::StatusHandler;
|
m_RouterInfoHandlers["i2p.router.status"] = &I2PControlService::StatusHandler;
|
||||||
m_RouterInfoHandlers["i2p.router.netdb.knownpeers"] = &I2PControlService::NetDbKnownPeersHandler;
|
m_RouterInfoHandlers["i2p.router.netdb.knownpeers"] = &I2PControlService::NetDbKnownPeersHandler;
|
||||||
m_RouterInfoHandlers["i2p.router.netdb.activepeers"] = &I2PControlService::NetDbActivePeersHandler;
|
m_RouterInfoHandlers["i2p.router.netdb.activepeers"] = &I2PControlService::NetDbActivePeersHandler;
|
||||||
m_RouterInfoHandlers["i2p.router.net.bw.inbound.1s"] = &I2PControlService::InboundBandwidth1S;
|
m_RouterInfoHandlers["i2p.router.net.bw.inbound.1s"] = &I2PControlService::InboundBandwidth1S;
|
||||||
m_RouterInfoHandlers["i2p.router.net.bw.outbound.1s"] = &I2PControlService::OutboundBandwidth1S;
|
m_RouterInfoHandlers["i2p.router.net.bw.outbound.1s"] = &I2PControlService::OutboundBandwidth1S;
|
||||||
m_RouterInfoHandlers["i2p.router.net.status"] = &I2PControlService::NetStatusHandler;
|
m_RouterInfoHandlers["i2p.router.net.status"] = &I2PControlService::NetStatusHandler;
|
||||||
m_RouterInfoHandlers["i2p.router.net.tunnels.participating"] = &I2PControlService::TunnelsParticipatingHandler;
|
m_RouterInfoHandlers["i2p.router.net.tunnels.participating"] = &I2PControlService::TunnelsParticipatingHandler;
|
||||||
m_RouterInfoHandlers["i2p.router.net.tunnels.successrate"] =
|
m_RouterInfoHandlers["i2p.router.net.tunnels.successrate"] = &I2PControlService::TunnelsSuccessRateHandler;
|
||||||
&I2PControlService::TunnelsSuccessRateHandler;
|
|
||||||
m_RouterInfoHandlers["i2p.router.net.total.received.bytes"] = &I2PControlService::NetTotalReceivedBytes;
|
m_RouterInfoHandlers["i2p.router.net.total.received.bytes"] = &I2PControlService::NetTotalReceivedBytes;
|
||||||
m_RouterInfoHandlers["i2p.router.net.total.sent.bytes"] = &I2PControlService::NetTotalSentBytes;
|
m_RouterInfoHandlers["i2p.router.net.total.sent.bytes"] = &I2PControlService::NetTotalSentBytes;
|
||||||
|
|
||||||
|
@ -97,10 +96,10 @@ namespace client
|
||||||
// ClientServicesInfo
|
// ClientServicesInfo
|
||||||
m_ClientServicesInfoHandlers["I2PTunnel"] = &I2PControlService::I2PTunnelInfoHandler;
|
m_ClientServicesInfoHandlers["I2PTunnel"] = &I2PControlService::I2PTunnelInfoHandler;
|
||||||
m_ClientServicesInfoHandlers["HTTPProxy"] = &I2PControlService::HTTPProxyInfoHandler;
|
m_ClientServicesInfoHandlers["HTTPProxy"] = &I2PControlService::HTTPProxyInfoHandler;
|
||||||
m_ClientServicesInfoHandlers["SOCKS"] = &I2PControlService::SOCKSInfoHandler;
|
m_ClientServicesInfoHandlers["SOCKS"] = &I2PControlService::SOCKSInfoHandler;
|
||||||
m_ClientServicesInfoHandlers["SAM"] = &I2PControlService::SAMInfoHandler;
|
m_ClientServicesInfoHandlers["SAM"] = &I2PControlService::SAMInfoHandler;
|
||||||
m_ClientServicesInfoHandlers["BOB"] = &I2PControlService::BOBInfoHandler;
|
m_ClientServicesInfoHandlers["BOB"] = &I2PControlService::BOBInfoHandler;
|
||||||
m_ClientServicesInfoHandlers["I2CP"] = &I2PControlService::I2CPInfoHandler;
|
m_ClientServicesInfoHandlers["I2CP"] = &I2PControlService::I2CPInfoHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
I2PControlService::~I2PControlService ()
|
I2PControlService::~I2PControlService ()
|
||||||
|
@ -500,7 +499,7 @@ namespace client
|
||||||
m_ShutdownTimer.expires_from_now (boost::posix_time::seconds(1)); // 1 second to make sure response has been sent
|
m_ShutdownTimer.expires_from_now (boost::posix_time::seconds(1)); // 1 second to make sure response has been sent
|
||||||
m_ShutdownTimer.async_wait (
|
m_ShutdownTimer.async_wait (
|
||||||
[](const boost::system::error_code& ecode)
|
[](const boost::system::error_code& ecode)
|
||||||
{
|
{
|
||||||
Daemon.running = 0;
|
Daemon.running = 0;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -514,7 +513,7 @@ namespace client
|
||||||
m_ShutdownTimer.expires_from_now (boost::posix_time::seconds(timeout + 1)); // + 1 second
|
m_ShutdownTimer.expires_from_now (boost::posix_time::seconds(timeout + 1)); // + 1 second
|
||||||
m_ShutdownTimer.async_wait (
|
m_ShutdownTimer.async_wait (
|
||||||
[](const boost::system::error_code& ecode)
|
[](const boost::system::error_code& ecode)
|
||||||
{
|
{
|
||||||
Daemon.running = 0;
|
Daemon.running = 0;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ namespace client
|
||||||
class I2PControlService
|
class I2PControlService
|
||||||
{
|
{
|
||||||
typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ssl_socket;
|
typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ssl_socket;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
I2PControlService (const std::string& address, int port);
|
I2PControlService (const std::string& address, int port);
|
||||||
|
|
|
@ -80,10 +80,10 @@ namespace transport
|
||||||
void UPnP::Discover ()
|
void UPnP::Discover ()
|
||||||
{
|
{
|
||||||
bool isError;
|
bool isError;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
#if ((MINIUPNPC_API_VERSION >= 8) || defined (UPNPDISCOVER_SUCCESS))
|
#if ((MINIUPNPC_API_VERSION >= 8) || defined (UPNPDISCOVER_SUCCESS))
|
||||||
err = UPNPDISCOVER_SUCCESS;
|
err = UPNPDISCOVER_SUCCESS;
|
||||||
|
|
||||||
#if (MINIUPNPC_API_VERSION >= 14)
|
#if (MINIUPNPC_API_VERSION >= 14)
|
||||||
m_Devlist = upnpDiscover (UPNP_RESPONSE_TIMEOUT, NULL, NULL, 0, 0, 2, &err);
|
m_Devlist = upnpDiscover (UPNP_RESPONSE_TIMEOUT, NULL, NULL, 0, 0, 2, &err);
|
||||||
|
@ -92,9 +92,9 @@ namespace transport
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
isError = err != UPNPDISCOVER_SUCCESS;
|
isError = err != UPNPDISCOVER_SUCCESS;
|
||||||
#else // MINIUPNPC_API_VERSION >= 8
|
#else // MINIUPNPC_API_VERSION >= 8
|
||||||
err = 0;
|
err = 0;
|
||||||
m_Devlist = upnpDiscover (UPNP_RESPONSE_TIMEOUT, NULL, NULL, 0);
|
m_Devlist = upnpDiscover (UPNP_RESPONSE_TIMEOUT, NULL, NULL, 0);
|
||||||
isError = m_Devlist == NULL;
|
isError = m_Devlist == NULL;
|
||||||
#endif // MINIUPNPC_API_VERSION >= 8
|
#endif // MINIUPNPC_API_VERSION >= 8
|
||||||
{
|
{
|
||||||
|
@ -105,15 +105,15 @@ namespace transport
|
||||||
|
|
||||||
if (isError)
|
if (isError)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "UPnP: unable to discover Internet Gateway Devices: error ", err);
|
LogPrint (eLogError, "UPnP: unable to discover Internet Gateway Devices: error ", err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = UPNP_GetValidIGD (m_Devlist, &m_upnpUrls, &m_upnpData, m_NetworkAddr, sizeof (m_NetworkAddr));
|
err = UPNP_GetValidIGD (m_Devlist, &m_upnpUrls, &m_upnpData, m_NetworkAddr, sizeof (m_NetworkAddr));
|
||||||
m_upnpUrlsInitialized=err!=0;
|
m_upnpUrlsInitialized = err != 0;
|
||||||
if (err == UPNP_IGD_VALID_CONNECTED)
|
if (err == UPNP_IGD_VALID_CONNECTED)
|
||||||
{
|
{
|
||||||
err = UPNP_GetExternalIPAddress (m_upnpUrls.controlURL, m_upnpData.first.servicetype, m_externalIPAddress);
|
err = UPNP_GetExternalIPAddress (m_upnpUrls.controlURL, m_upnpData.first.servicetype, m_externalIPAddress);
|
||||||
if(err != UPNPCOMMAND_SUCCESS)
|
if(err != UPNPCOMMAND_SUCCESS)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "UPnP: unable to get external address: error ", err);
|
LogPrint (eLogError, "UPnP: unable to get external address: error ", err);
|
||||||
|
@ -124,14 +124,14 @@ namespace transport
|
||||||
LogPrint (eLogError, "UPnP: found Internet Gateway Device ", m_upnpUrls.controlURL);
|
LogPrint (eLogError, "UPnP: found Internet Gateway Device ", m_upnpUrls.controlURL);
|
||||||
if (!m_externalIPAddress[0])
|
if (!m_externalIPAddress[0])
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "UPnP: found Internet Gateway Device doesn't know our external address");
|
LogPrint (eLogError, "UPnP: found Internet Gateway Device doesn't know our external address");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "UPnP: unable to find valid Internet Gateway Device: error ", err);
|
LogPrint (eLogError, "UPnP: unable to find valid Internet Gateway Device: error ", err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,7 +182,7 @@ namespace transport
|
||||||
err = CheckMapping (strPort.c_str (), strType.c_str ());
|
err = CheckMapping (strPort.c_str (), strType.c_str ());
|
||||||
if (err != UPNPCOMMAND_SUCCESS) // if mapping not found
|
if (err != UPNPCOMMAND_SUCCESS) // if mapping not found
|
||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "UPnP: possibly port ", strPort, " is not forwarded: return code ", err);
|
LogPrint (eLogDebug, "UPnP: possibly port ", strPort, " is not forwarded: return code ", err);
|
||||||
|
|
||||||
#if ((MINIUPNPC_API_VERSION >= 8) || defined (UPNPDISCOVER_SUCCESS))
|
#if ((MINIUPNPC_API_VERSION >= 8) || defined (UPNPDISCOVER_SUCCESS))
|
||||||
err = UPNP_AddPortMapping (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strPort.c_str (), m_NetworkAddr, strDesc.c_str (), strType.c_str (), NULL, NULL);
|
err = UPNP_AddPortMapping (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strPort.c_str (), m_NetworkAddr, strDesc.c_str (), strType.c_str (), NULL, NULL);
|
||||||
|
@ -202,7 +202,7 @@ namespace transport
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "UPnP: external forward from ", m_NetworkAddr, ":", strPort, " exists on current Internet Gateway Device");
|
LogPrint (eLogDebug, "UPnP: external forward from ", m_NetworkAddr, ":", strPort, " exists on current Internet Gateway Device");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -219,14 +219,14 @@ namespace transport
|
||||||
|
|
||||||
void UPnP::CloseMapping (std::shared_ptr<i2p::data::RouterInfo::Address> address)
|
void UPnP::CloseMapping (std::shared_ptr<i2p::data::RouterInfo::Address> address)
|
||||||
{
|
{
|
||||||
if(!m_upnpUrlsInitialized) {
|
if(!m_upnpUrlsInitialized) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::string strType (GetProto (address)), strPort (std::to_string (address->port));
|
std::string strType (GetProto (address)), strPort (std::to_string (address->port));
|
||||||
int err = UPNPCOMMAND_SUCCESS;
|
int err = UPNPCOMMAND_SUCCESS;
|
||||||
|
|
||||||
err = CheckMapping (strPort.c_str (), strType.c_str ());
|
err = CheckMapping (strPort.c_str (), strType.c_str ());
|
||||||
if (err == UPNPCOMMAND_SUCCESS)
|
if (err == UPNPCOMMAND_SUCCESS)
|
||||||
{
|
{
|
||||||
err = UPNP_DeletePortMapping (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strType.c_str (), NULL);
|
err = UPNP_DeletePortMapping (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strType.c_str (), NULL);
|
||||||
LogPrint (eLogError, "UPnP: DeletePortMapping() returned : ", err);
|
LogPrint (eLogError, "UPnP: DeletePortMapping() returned : ", err);
|
||||||
|
@ -237,11 +237,11 @@ namespace transport
|
||||||
{
|
{
|
||||||
freeUPNPDevlist (m_Devlist);
|
freeUPNPDevlist (m_Devlist);
|
||||||
m_Devlist = 0;
|
m_Devlist = 0;
|
||||||
if(m_upnpUrlsInitialized){
|
if(m_upnpUrlsInitialized){
|
||||||
FreeUPNPUrls (&m_upnpUrls);
|
FreeUPNPUrls (&m_upnpUrls);
|
||||||
m_upnpUrlsInitialized=false;
|
m_upnpUrlsInitialized=false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string UPnP::GetProto (std::shared_ptr<i2p::data::RouterInfo::Address> address)
|
std::string UPnP::GetProto (std::shared_ptr<i2p::data::RouterInfo::Address> address)
|
||||||
{
|
{
|
||||||
|
|
|
@ -33,41 +33,41 @@ namespace transport
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
UPnP ();
|
UPnP ();
|
||||||
~UPnP ();
|
~UPnP ();
|
||||||
void Close ();
|
void Close ();
|
||||||
|
|
||||||
void Start ();
|
void Start ();
|
||||||
void Stop ();
|
void Stop ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void Discover ();
|
void Discover ();
|
||||||
int CheckMapping (const char* port, const char* type);
|
int CheckMapping (const char* port, const char* type);
|
||||||
void PortMapping ();
|
void PortMapping ();
|
||||||
void TryPortMapping (std::shared_ptr<i2p::data::RouterInfo::Address> address);
|
void TryPortMapping (std::shared_ptr<i2p::data::RouterInfo::Address> address);
|
||||||
void CloseMapping ();
|
void CloseMapping ();
|
||||||
void CloseMapping (std::shared_ptr<i2p::data::RouterInfo::Address> address);
|
void CloseMapping (std::shared_ptr<i2p::data::RouterInfo::Address> address);
|
||||||
|
|
||||||
void Run ();
|
void Run ();
|
||||||
std::string GetProto (std::shared_ptr<i2p::data::RouterInfo::Address> address);
|
std::string GetProto (std::shared_ptr<i2p::data::RouterInfo::Address> address);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool m_IsRunning;
|
bool m_IsRunning;
|
||||||
std::unique_ptr<std::thread> m_Thread;
|
std::unique_ptr<std::thread> m_Thread;
|
||||||
std::condition_variable m_Started;
|
std::condition_variable m_Started;
|
||||||
std::mutex m_StartedMutex;
|
std::mutex m_StartedMutex;
|
||||||
boost::asio::io_service m_Service;
|
boost::asio::io_service m_Service;
|
||||||
boost::asio::deadline_timer m_Timer;
|
boost::asio::deadline_timer m_Timer;
|
||||||
bool m_upnpUrlsInitialized=false;
|
bool m_upnpUrlsInitialized = false;
|
||||||
struct UPNPUrls m_upnpUrls;
|
struct UPNPUrls m_upnpUrls;
|
||||||
struct IGDdatas m_upnpData;
|
struct IGDdatas m_upnpData;
|
||||||
|
|
||||||
// For miniupnpc
|
// For miniupnpc
|
||||||
struct UPNPDev * m_Devlist = 0;
|
struct UPNPDev * m_Devlist = 0;
|
||||||
char m_NetworkAddr[64];
|
char m_NetworkAddr[64];
|
||||||
char m_externalIPAddress[40];
|
char m_externalIPAddress[40];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,10 +79,10 @@ namespace transport {
|
||||||
class UPnP {
|
class UPnP {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
UPnP () {};
|
UPnP () {};
|
||||||
~UPnP () {};
|
~UPnP () {};
|
||||||
void Start () { LogPrint(eLogWarning, "UPnP: this module was disabled at compile-time"); }
|
void Start () { LogPrint(eLogWarning, "UPnP: this module was disabled at compile-time"); }
|
||||||
void Stop () {};
|
void Stop () {};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,5 +196,4 @@ namespace i2p
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
#include "Daemon.h"
|
#include "Daemon.h"
|
||||||
|
|
||||||
#if defined(QT_GUI_LIB)
|
#if defined(QT_GUI_LIB)
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
namespace qt
|
namespace qt
|
||||||
|
@ -10,11 +9,11 @@ namespace qt
|
||||||
int RunQT (int argc, char* argv[]);
|
int RunQT (int argc, char* argv[]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main( int argc, char* argv[] )
|
int main( int argc, char* argv[] )
|
||||||
{
|
{
|
||||||
return i2p::qt::RunQT (argc, argv);
|
return i2p::qt::RunQT (argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
int main( int argc, char* argv[] )
|
int main( int argc, char* argv[] )
|
||||||
{
|
{
|
||||||
|
|
212
libi2pd/Base.cpp
212
libi2pd/Base.cpp
|
@ -7,7 +7,8 @@ namespace i2p
|
||||||
{
|
{
|
||||||
namespace data
|
namespace data
|
||||||
{
|
{
|
||||||
static const char T32[32] = {
|
static const char T32[32] =
|
||||||
|
{
|
||||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
|
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
|
||||||
'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
|
'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
|
||||||
'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
|
'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
|
||||||
|
@ -29,15 +30,16 @@ namespace data
|
||||||
* Direct Substitution Table
|
* Direct Substitution Table
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const char T64[64] = {
|
static const char T64[64] =
|
||||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
|
{
|
||||||
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
|
||||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
|
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||||
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
|
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
|
||||||
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
|
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||||
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
|
||||||
'w', 'x', 'y', 'z', '0', '1', '2', '3',
|
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||||
'4', '5', '6', '7', '8', '9', '-', '~'
|
'w', 'x', 'y', 'z', '0', '1', '2', '3',
|
||||||
|
'4', '5', '6', '7', '8', '9', '-', '~'
|
||||||
};
|
};
|
||||||
|
|
||||||
const char * GetBase64SubstitutionTable ()
|
const char * GetBase64SubstitutionTable ()
|
||||||
|
@ -67,14 +69,12 @@ namespace data
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
size_t /* Number of bytes in the encoded buffer */
|
size_t ByteStreamToBase64 ( /* Number of bytes in the encoded buffer */
|
||||||
ByteStreamToBase64 (
|
const uint8_t * InBuffer, /* Input buffer, binary data */
|
||||||
const uint8_t * InBuffer, /* Input buffer, binary data */
|
size_t InCount, /* Number of bytes in the input buffer */
|
||||||
size_t InCount, /* Number of bytes in the input buffer */
|
char * OutBuffer, /* output buffer */
|
||||||
char * OutBuffer, /* output buffer */
|
size_t len /* length of output buffer */
|
||||||
size_t len /* length of output buffer */
|
|
||||||
)
|
)
|
||||||
|
|
||||||
{
|
{
|
||||||
unsigned char * ps;
|
unsigned char * ps;
|
||||||
unsigned char * pd;
|
unsigned char * pd;
|
||||||
|
@ -83,55 +83,60 @@ namespace data
|
||||||
int i;
|
int i;
|
||||||
int n;
|
int n;
|
||||||
int m;
|
int m;
|
||||||
size_t outCount;
|
size_t outCount;
|
||||||
|
|
||||||
ps = (unsigned char *)InBuffer;
|
ps = (unsigned char *)InBuffer;
|
||||||
n = InCount/3;
|
n = InCount / 3;
|
||||||
m = InCount%3;
|
m = InCount % 3;
|
||||||
if (!m)
|
if (!m)
|
||||||
outCount = 4*n;
|
outCount = 4 * n;
|
||||||
else
|
else
|
||||||
outCount = 4*(n+1);
|
outCount = 4 * (n + 1);
|
||||||
|
|
||||||
if (outCount > len) return 0;
|
if (outCount > len) return 0;
|
||||||
|
|
||||||
pd = (unsigned char *)OutBuffer;
|
pd = (unsigned char *)OutBuffer;
|
||||||
for ( i = 0; i<n; i++ ){
|
for ( i = 0; i < n; i++ )
|
||||||
acc_1 = *ps++;
|
{
|
||||||
acc_2 = (acc_1<<4)&0x30;
|
acc_1 = *ps++;
|
||||||
acc_1 >>= 2; /* base64 digit #1 */
|
acc_2 = (acc_1 << 4) & 0x30;
|
||||||
*pd++ = T64[acc_1];
|
acc_1 >>= 2; /* base64 digit #1 */
|
||||||
acc_1 = *ps++;
|
*pd++ = T64[acc_1];
|
||||||
acc_2 |= acc_1 >> 4; /* base64 digit #2 */
|
acc_1 = *ps++;
|
||||||
*pd++ = T64[acc_2];
|
acc_2 |= acc_1 >> 4; /* base64 digit #2 */
|
||||||
acc_1 &= 0x0f;
|
*pd++ = T64[acc_2];
|
||||||
acc_1 <<=2;
|
acc_1 &= 0x0f;
|
||||||
acc_2 = *ps++;
|
acc_1 <<= 2;
|
||||||
acc_1 |= acc_2>>6; /* base64 digit #3 */
|
acc_2 = *ps++;
|
||||||
*pd++ = T64[acc_1];
|
acc_1 |= acc_2 >> 6; /* base64 digit #3 */
|
||||||
acc_2 &= 0x3f; /* base64 digit #4 */
|
*pd++ = T64[acc_1];
|
||||||
*pd++ = T64[acc_2];
|
acc_2 &= 0x3f; /* base64 digit #4 */
|
||||||
|
*pd++ = T64[acc_2];
|
||||||
}
|
}
|
||||||
if ( m == 1 ){
|
if ( m == 1 )
|
||||||
acc_1 = *ps++;
|
{
|
||||||
acc_2 = (acc_1<<4)&0x3f; /* base64 digit #2 */
|
acc_1 = *ps++;
|
||||||
acc_1 >>= 2; /* base64 digit #1 */
|
acc_2 = (acc_1 << 4) & 0x3f; /* base64 digit #2 */
|
||||||
*pd++ = T64[acc_1];
|
acc_1 >>= 2; /* base64 digit #1 */
|
||||||
*pd++ = T64[acc_2];
|
*pd++ = T64[acc_1];
|
||||||
*pd++ = P64;
|
*pd++ = T64[acc_2];
|
||||||
*pd++ = P64;
|
*pd++ = P64;
|
||||||
|
*pd++ = P64;
|
||||||
|
|
||||||
}
|
}
|
||||||
else if ( m == 2 ){
|
else if ( m == 2 )
|
||||||
acc_1 = *ps++;
|
{
|
||||||
acc_2 = (acc_1<<4)&0x3f;
|
acc_1 = *ps++;
|
||||||
acc_1 >>= 2; /* base64 digit #1 */
|
acc_2 = (acc_1 << 4) & 0x3f;
|
||||||
*pd++ = T64[acc_1];
|
acc_1 >>= 2; /* base64 digit #1 */
|
||||||
acc_1 = *ps++;
|
*pd++ = T64[acc_1];
|
||||||
acc_2 |= acc_1 >> 4; /* base64 digit #2 */
|
acc_1 = *ps++;
|
||||||
*pd++ = T64[acc_2];
|
acc_2 |= acc_1 >> 4; /* base64 digit #2 */
|
||||||
acc_1 &= 0x0f;
|
*pd++ = T64[acc_2];
|
||||||
acc_1 <<=2; /* base64 digit #3 */
|
acc_1 &= 0x0f;
|
||||||
*pd++ = T64[acc_1];
|
acc_1 <<= 2; /* base64 digit #3 */
|
||||||
*pd++ = P64;
|
*pd++ = T64[acc_1];
|
||||||
|
*pd++ = P64;
|
||||||
}
|
}
|
||||||
|
|
||||||
return outCount;
|
return outCount;
|
||||||
|
@ -147,12 +152,11 @@ namespace data
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
size_t /* Number of output bytes */
|
size_t Base64ToByteStream ( /* Number of output bytes */
|
||||||
Base64ToByteStream (
|
const char * InBuffer, /* BASE64 encoded buffer */
|
||||||
const char * InBuffer, /* BASE64 encoded buffer */
|
size_t InCount, /* Number of input bytes */
|
||||||
size_t InCount, /* Number of input bytes */
|
uint8_t * OutBuffer, /* output buffer length */
|
||||||
uint8_t * OutBuffer, /* output buffer length */
|
size_t len /* length of output buffer */
|
||||||
size_t len /* length of output buffer */
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
unsigned char * ps;
|
unsigned char * ps;
|
||||||
|
@ -162,42 +166,52 @@ namespace data
|
||||||
int i;
|
int i;
|
||||||
int n;
|
int n;
|
||||||
int m;
|
int m;
|
||||||
size_t outCount;
|
size_t outCount;
|
||||||
|
|
||||||
|
if (isFirstTime)
|
||||||
|
iT64Build();
|
||||||
|
|
||||||
|
n = InCount / 4;
|
||||||
|
m = InCount % 4;
|
||||||
|
|
||||||
if (isFirstTime) iT64Build();
|
|
||||||
n = InCount/4;
|
|
||||||
m = InCount%4;
|
|
||||||
if (InCount && !m)
|
if (InCount && !m)
|
||||||
outCount = 3*n;
|
outCount = 3 * n;
|
||||||
else {
|
else
|
||||||
outCount = 0;
|
{
|
||||||
return 0;
|
outCount = 0;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ps = (unsigned char *)(InBuffer + InCount - 1);
|
ps = (unsigned char *)(InBuffer + InCount - 1);
|
||||||
while ( *ps-- == P64 ) outCount--;
|
while ( *ps-- == P64 )
|
||||||
|
outCount--;
|
||||||
ps = (unsigned char *)InBuffer;
|
ps = (unsigned char *)InBuffer;
|
||||||
|
|
||||||
if (outCount > len) return -1;
|
if (outCount > len)
|
||||||
|
return -1;
|
||||||
|
|
||||||
pd = OutBuffer;
|
pd = OutBuffer;
|
||||||
auto endOfOutBuffer = OutBuffer + outCount;
|
auto endOfOutBuffer = OutBuffer + outCount;
|
||||||
for ( i = 0; i < n; i++ ){
|
for ( i = 0; i < n; i++ )
|
||||||
acc_1 = iT64[*ps++];
|
{
|
||||||
acc_2 = iT64[*ps++];
|
acc_1 = iT64[*ps++];
|
||||||
acc_1 <<= 2;
|
acc_2 = iT64[*ps++];
|
||||||
acc_1 |= acc_2>>4;
|
acc_1 <<= 2;
|
||||||
*pd++ = acc_1;
|
acc_1 |= acc_2 >> 4;
|
||||||
if (pd >= endOfOutBuffer) break;
|
*pd++ = acc_1;
|
||||||
|
if (pd >= endOfOutBuffer)
|
||||||
|
break;
|
||||||
|
|
||||||
acc_2 <<= 4;
|
acc_2 <<= 4;
|
||||||
acc_1 = iT64[*ps++];
|
acc_1 = iT64[*ps++];
|
||||||
acc_2 |= acc_1 >> 2;
|
acc_2 |= acc_1 >> 2;
|
||||||
*pd++ = acc_2;
|
*pd++ = acc_2;
|
||||||
if (pd >= endOfOutBuffer) break;
|
if (pd >= endOfOutBuffer)
|
||||||
|
break;
|
||||||
|
|
||||||
acc_2 = iT64[*ps++];
|
acc_2 = iT64[*ps++];
|
||||||
acc_2 |= acc_1 << 6;
|
acc_2 |= acc_1 << 6;
|
||||||
*pd++ = acc_2;
|
*pd++ = acc_2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return outCount;
|
return outCount;
|
||||||
|
@ -206,20 +220,25 @@ namespace data
|
||||||
size_t Base64EncodingBufferSize (const size_t input_size)
|
size_t Base64EncodingBufferSize (const size_t input_size)
|
||||||
{
|
{
|
||||||
auto d = div (input_size, 3);
|
auto d = div (input_size, 3);
|
||||||
if (d.rem) d.quot++;
|
if (d.rem)
|
||||||
return 4*d.quot;
|
d.quot++;
|
||||||
|
|
||||||
|
return 4 * d.quot;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ToBase64Standard (const std::string& in)
|
std::string ToBase64Standard (const std::string& in)
|
||||||
{
|
{
|
||||||
auto len = Base64EncodingBufferSize (in.length ());
|
auto len = Base64EncodingBufferSize (in.length ());
|
||||||
char * str = new char[len+1];
|
char * str = new char[len + 1];
|
||||||
auto l = ByteStreamToBase64 ((const uint8_t *)in.c_str (), in.length (), str, len);
|
auto l = ByteStreamToBase64 ((const uint8_t *)in.c_str (), in.length (), str, len);
|
||||||
str[l] = 0;
|
str[l] = 0;
|
||||||
// replace '-' by '+' and '~' by '/'
|
// replace '-' by '+' and '~' by '/'
|
||||||
for (size_t i = 0; i < l; i++)
|
for (size_t i = 0; i < l; i++)
|
||||||
if (str[i] == '-') str[i] = '+';
|
if (str[i] == '-')
|
||||||
else if (str[i] == '~') str[i] = '/';
|
str[i] = '+';
|
||||||
|
else if (str[i] == '~')
|
||||||
|
str[i] = '/';
|
||||||
|
|
||||||
std::string s(str);
|
std::string s(str);
|
||||||
delete[] str;
|
delete[] str;
|
||||||
return s;
|
return s;
|
||||||
|
@ -236,10 +255,10 @@ namespace data
|
||||||
|
|
||||||
static void iT64Build()
|
static void iT64Build()
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
isFirstTime = 0;
|
isFirstTime = 0;
|
||||||
for ( i=0; i<256; i++ ) iT64[i] = -1;
|
for ( i = 0; i < 256; i++ ) iT64[i] = -1;
|
||||||
for ( i=0; i<64; i++ ) iT64[(int)T64[i]] = i;
|
for ( i = 0; i < 64; i++ ) iT64[(int)T64[i]] = i;
|
||||||
iT64[(int)P64] = 0;
|
iT64[(int)P64] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,4 +321,3 @@ namespace data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,9 +15,9 @@ namespace data {
|
||||||
size_t Base32ToByteStream (const char * inBuf, size_t len, uint8_t * outBuf, size_t outLen);
|
size_t Base32ToByteStream (const char * inBuf, size_t len, uint8_t * outBuf, size_t outLen);
|
||||||
size_t ByteStreamToBase32 (const uint8_t * InBuf, size_t len, char * outBuf, size_t outLen);
|
size_t ByteStreamToBase32 (const uint8_t * InBuf, size_t len, char * outBuf, size_t outLen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Compute the size for a buffer to contain encoded base64 given that the size of the input is input_size bytes
|
Compute the size for a buffer to contain encoded base64 given that the size of the input is input_size bytes
|
||||||
*/
|
*/
|
||||||
size_t Base64EncodingBufferSize(const size_t input_size);
|
size_t Base64EncodingBufferSize(const size_t input_size);
|
||||||
|
|
||||||
std::string ToBase64Standard (const std::string& in); // using standard table, for Proxy-Authorization
|
std::string ToBase64Standard (const std::string& in); // using standard table, for Proxy-Authorization
|
||||||
|
|
|
@ -314,4 +314,3 @@ namespace data
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,10 +5,10 @@ namespace i2p
|
||||||
{
|
{
|
||||||
namespace cpu
|
namespace cpu
|
||||||
{
|
{
|
||||||
extern bool aesni;
|
extern bool aesni;
|
||||||
extern bool avx;
|
extern bool avx;
|
||||||
|
|
||||||
void Detect();
|
void Detect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,34 +21,34 @@ namespace chacha
|
||||||
{
|
{
|
||||||
void u32t8le(uint32_t v, uint8_t * p)
|
void u32t8le(uint32_t v, uint8_t * p)
|
||||||
{
|
{
|
||||||
p[0] = v & 0xff;
|
p[0] = v & 0xff;
|
||||||
p[1] = (v >> 8) & 0xff;
|
p[1] = (v >> 8) & 0xff;
|
||||||
p[2] = (v >> 16) & 0xff;
|
p[2] = (v >> 16) & 0xff;
|
||||||
p[3] = (v >> 24) & 0xff;
|
p[3] = (v >> 24) & 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t u8t32le(const uint8_t * p)
|
uint32_t u8t32le(const uint8_t * p)
|
||||||
{
|
{
|
||||||
uint32_t value = p[3];
|
uint32_t value = p[3];
|
||||||
|
|
||||||
value = (value << 8) | p[2];
|
value = (value << 8) | p[2];
|
||||||
value = (value << 8) | p[1];
|
value = (value << 8) | p[1];
|
||||||
value = (value << 8) | p[0];
|
value = (value << 8) | p[0];
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t rotl32(uint32_t x, int n)
|
uint32_t rotl32(uint32_t x, int n)
|
||||||
{
|
{
|
||||||
return x << n | (x >> (-n & 31));
|
return x << n | (x >> (-n & 31));
|
||||||
}
|
}
|
||||||
|
|
||||||
void quarterround(uint32_t *x, int a, int b, int c, int d)
|
void quarterround(uint32_t *x, int a, int b, int c, int d)
|
||||||
{
|
{
|
||||||
x[a] += x[b]; x[d] = rotl32(x[d] ^ x[a], 16);
|
x[a] += x[b]; x[d] = rotl32(x[d] ^ x[a], 16);
|
||||||
x[c] += x[d]; x[b] = rotl32(x[b] ^ x[c], 12);
|
x[c] += x[d]; x[b] = rotl32(x[b] ^ x[c], 12);
|
||||||
x[a] += x[b]; x[d] = rotl32(x[d] ^ x[a], 8);
|
x[a] += x[b]; x[d] = rotl32(x[d] ^ x[a], 8);
|
||||||
x[c] += x[d]; x[b] = rotl32(x[b] ^ x[c], 7);
|
x[c] += x[d]; x[b] = rotl32(x[b] ^ x[c], 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,24 +61,23 @@ void Chacha20Block::operator << (const Chacha20State & st)
|
||||||
|
|
||||||
void block (Chacha20State &input, int rounds)
|
void block (Chacha20State &input, int rounds)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
Chacha20State x;
|
Chacha20State x;
|
||||||
x.Copy(input);
|
x.Copy(input);
|
||||||
|
|
||||||
for (i = rounds; i > 0; i -= 2)
|
|
||||||
{
|
|
||||||
quarterround(x.data, 0, 4, 8, 12);
|
|
||||||
quarterround(x.data, 1, 5, 9, 13);
|
|
||||||
quarterround(x.data, 2, 6, 10, 14);
|
|
||||||
quarterround(x.data, 3, 7, 11, 15);
|
|
||||||
quarterround(x.data, 0, 5, 10, 15);
|
|
||||||
quarterround(x.data, 1, 6, 11, 12);
|
|
||||||
quarterround(x.data, 2, 7, 8, 13);
|
|
||||||
quarterround(x.data, 3, 4, 9, 14);
|
|
||||||
}
|
|
||||||
x += input;
|
|
||||||
input.block << x;
|
|
||||||
|
|
||||||
|
for (i = rounds; i > 0; i -= 2)
|
||||||
|
{
|
||||||
|
quarterround(x.data, 0, 4, 8, 12);
|
||||||
|
quarterround(x.data, 1, 5, 9, 13);
|
||||||
|
quarterround(x.data, 2, 6, 10, 14);
|
||||||
|
quarterround(x.data, 3, 7, 11, 15);
|
||||||
|
quarterround(x.data, 0, 5, 10, 15);
|
||||||
|
quarterround(x.data, 1, 6, 11, 12);
|
||||||
|
quarterround(x.data, 2, 7, 8, 13);
|
||||||
|
quarterround(x.data, 3, 4, 9, 14);
|
||||||
|
}
|
||||||
|
x += input;
|
||||||
|
input.block << x;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Chacha20Init (Chacha20State& state, const uint8_t * nonce, const uint8_t * key, uint32_t counter)
|
void Chacha20Init (Chacha20State& state, const uint8_t * nonce, const uint8_t * key, uint32_t counter)
|
||||||
|
@ -88,11 +87,11 @@ void Chacha20Init (Chacha20State& state, const uint8_t * nonce, const uint8_t *
|
||||||
state.data[2] = 0x79622d32;
|
state.data[2] = 0x79622d32;
|
||||||
state.data[3] = 0x6b206574;
|
state.data[3] = 0x6b206574;
|
||||||
for (size_t i = 0; i < 8; i++)
|
for (size_t i = 0; i < 8; i++)
|
||||||
state.data[4 + i] = chacha::u8t32le(key + i * 4);
|
state.data[4 + i] = chacha::u8t32le(key + i * 4);
|
||||||
|
|
||||||
state.data[12] = htole32 (counter);
|
state.data[12] = htole32 (counter);
|
||||||
for (size_t i = 0; i < 3; i++)
|
for (size_t i = 0; i < 3; i++)
|
||||||
state.data[13 + i] = chacha::u8t32le(nonce + i * 4);
|
state.data[13 + i] = chacha::u8t32le(nonce + i * 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Chacha20SetCounter (Chacha20State& state, uint32_t counter)
|
void Chacha20SetCounter (Chacha20State& state, uint32_t counter)
|
||||||
|
@ -117,22 +116,22 @@ void Chacha20Encrypt (Chacha20State& state, uint8_t * buf, size_t sz)
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < sz; i += chacha::blocksize)
|
for (size_t i = 0; i < sz; i += chacha::blocksize)
|
||||||
{
|
{
|
||||||
chacha::block(state, chacha::rounds);
|
chacha::block(state, chacha::rounds);
|
||||||
state.data[12]++;
|
state.data[12]++;
|
||||||
for (size_t j = i; j < i + chacha::blocksize; j++)
|
for (size_t j = i; j < i + chacha::blocksize; j++)
|
||||||
{
|
{
|
||||||
if (j >= sz)
|
if (j >= sz)
|
||||||
{
|
{
|
||||||
state.offset = j & 0x3F; // % 64
|
state.offset = j & 0x3F; // % 64
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
buf[j] ^= state.block.data[j - i];
|
buf[j] ^= state.block.data[j - i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace chacha
|
} // namespace chacha
|
||||||
|
} // namespace crypto
|
||||||
|
} // namespace i2p
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,8 @@ namespace i2p
|
||||||
{
|
{
|
||||||
namespace crypto
|
namespace crypto
|
||||||
{
|
{
|
||||||
const std::size_t CHACHA20_KEY_BYTES = 32;
|
const std::size_t CHACHA20_KEY_BYTES = 32;
|
||||||
const std::size_t CHACHA20_NOUNCE_BYTES = 12;
|
const std::size_t CHACHA20_NOUNCE_BYTES = 12;
|
||||||
|
|
||||||
namespace chacha
|
namespace chacha
|
||||||
{
|
{
|
||||||
|
@ -32,12 +32,12 @@ namespace chacha
|
||||||
struct Chacha20State;
|
struct Chacha20State;
|
||||||
struct Chacha20Block
|
struct Chacha20Block
|
||||||
{
|
{
|
||||||
Chacha20Block () {};
|
Chacha20Block () {};
|
||||||
Chacha20Block (Chacha20Block &&) = delete;
|
Chacha20Block (Chacha20Block &&) = delete;
|
||||||
|
|
||||||
uint8_t data[blocksize];
|
uint8_t data[blocksize];
|
||||||
|
|
||||||
void operator << (const Chacha20State & st);
|
void operator << (const Chacha20State & st);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Chacha20State
|
struct Chacha20State
|
||||||
|
@ -54,7 +54,7 @@ namespace chacha
|
||||||
|
|
||||||
void Copy(const Chacha20State & other)
|
void Copy(const Chacha20State & other)
|
||||||
{
|
{
|
||||||
memcpy(data, other.data, sizeof(uint32_t) * 16);
|
memcpy(data, other.data, sizeof(uint32_t) * 16);
|
||||||
}
|
}
|
||||||
uint32_t data[16];
|
uint32_t data[16];
|
||||||
Chacha20Block block;
|
Chacha20Block block;
|
||||||
|
@ -64,9 +64,9 @@ namespace chacha
|
||||||
void Chacha20Init (Chacha20State& state, const uint8_t * nonce, const uint8_t * key, uint32_t counter);
|
void Chacha20Init (Chacha20State& state, const uint8_t * nonce, const uint8_t * key, uint32_t counter);
|
||||||
void Chacha20SetCounter (Chacha20State& state, uint32_t counter);
|
void Chacha20SetCounter (Chacha20State& state, uint32_t counter);
|
||||||
void Chacha20Encrypt (Chacha20State& state, uint8_t * buf, size_t sz); // encrypt buf in place
|
void Chacha20Encrypt (Chacha20State& state, uint8_t * buf, size_t sz); // encrypt buf in place
|
||||||
}
|
} // namespace chacha
|
||||||
}
|
} // namespace crypto
|
||||||
}
|
} // namespace i2p
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
|
@ -242,7 +242,7 @@ namespace config {
|
||||||
"1.pool.ntp.org,"
|
"1.pool.ntp.org,"
|
||||||
"2.pool.ntp.org,"
|
"2.pool.ntp.org,"
|
||||||
"3.pool.ntp.org"
|
"3.pool.ntp.org"
|
||||||
), "Comma separated list of NTCP servers")
|
), "Comma separated list of NTCP servers")
|
||||||
("nettime.ntpsyncinterval", value<int>()->default_value(72), "NTP sync interval in hours (default: 72)")
|
("nettime.ntpsyncinterval", value<int>()->default_value(72), "NTP sync interval in hours (default: 72)")
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
169
libi2pd/Config.h
169
libi2pd/Config.h
|
@ -18,98 +18,101 @@
|
||||||
|
|
||||||
namespace i2p {
|
namespace i2p {
|
||||||
namespace config {
|
namespace config {
|
||||||
extern boost::program_options::variables_map m_Options;
|
extern boost::program_options::variables_map m_Options;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialize list of acceptable parameters
|
* @brief Initialize list of acceptable parameters
|
||||||
*
|
*
|
||||||
* Should be called before any Parse* functions.
|
* Should be called before any Parse* functions.
|
||||||
*/
|
*/
|
||||||
void Init();
|
void Init();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Parse cmdline parameters, and show help if requested
|
* @brief Parse cmdline parameters, and show help if requested
|
||||||
* @param argc Cmdline arguments count, should be passed from main().
|
* @param argc Cmdline arguments count, should be passed from main().
|
||||||
* @param argv Cmdline parameters array, should be passed from main()
|
* @param argv Cmdline parameters array, should be passed from main()
|
||||||
*
|
*
|
||||||
* If --help is given in parameters, shows its list with description
|
* If --help is given in parameters, shows its list with description
|
||||||
* and terminates the program with exitcode 0.
|
* and terminates the program with exitcode 0.
|
||||||
*
|
*
|
||||||
* In case of parameter misuse boost throws an exception.
|
* In case of parameter misuse boost throws an exception.
|
||||||
* We internally handle type boost::program_options::unknown_option,
|
* We internally handle type boost::program_options::unknown_option,
|
||||||
* and then terminate the program with exitcode 1.
|
* and then terminate the program with exitcode 1.
|
||||||
*
|
*
|
||||||
* Other exceptions will be passed to higher level.
|
* Other exceptions will be passed to higher level.
|
||||||
*/
|
*/
|
||||||
void ParseCmdline(int argc, char* argv[], bool ignoreUnknown = false);
|
void ParseCmdline(int argc, char* argv[], bool ignoreUnknown = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Load and parse given config file
|
* @brief Load and parse given config file
|
||||||
* @param path Path to config file
|
* @param path Path to config file
|
||||||
*
|
*
|
||||||
* If error occurred when opening file path is points to,
|
* If error occurred when opening file path is points to,
|
||||||
* we show the error message and terminate program.
|
* we show the error message and terminate program.
|
||||||
*
|
*
|
||||||
* In case of parameter misuse boost throws an exception.
|
* In case of parameter misuse boost throws an exception.
|
||||||
* We internally handle type boost::program_options::unknown_option,
|
* We internally handle type boost::program_options::unknown_option,
|
||||||
* and then terminate program with exitcode 1.
|
* and then terminate program with exitcode 1.
|
||||||
*
|
*
|
||||||
* Other exceptions will be passed to higher level.
|
* Other exceptions will be passed to higher level.
|
||||||
*/
|
*/
|
||||||
void ParseConfig(const std::string& path);
|
void ParseConfig(const std::string& path);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Used to combine options from cmdline, config and default values
|
* @brief Used to combine options from cmdline, config and default values
|
||||||
*/
|
*/
|
||||||
void Finalize();
|
void Finalize();
|
||||||
|
|
||||||
/* @brief Accessor to parameters by name
|
/**
|
||||||
* @param name Name of the requested parameter
|
* @brief Accessor to parameters by name
|
||||||
* @param value Variable where to store option
|
* @param name Name of the requested parameter
|
||||||
* @return this function returns false if parameter not found
|
* @param value Variable where to store option
|
||||||
*
|
* @return this function returns false if parameter not found
|
||||||
* Example: uint16_t port; GetOption("sam.port", port);
|
*
|
||||||
*/
|
* Example: uint16_t port; GetOption("sam.port", port);
|
||||||
template<typename T>
|
*/
|
||||||
bool GetOption(const char *name, T& value) {
|
template<typename T>
|
||||||
if (!m_Options.count(name))
|
bool GetOption(const char *name, T& value)
|
||||||
return false;
|
{
|
||||||
value = m_Options[name].as<T>();
|
if (!m_Options.count(name))
|
||||||
return true;
|
return false;
|
||||||
}
|
value = m_Options[name].as<T>();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool GetOption(const std::string& name, T& value)
|
bool GetOption(const std::string& name, T& value)
|
||||||
{
|
{
|
||||||
return GetOption (name.c_str (), value);
|
return GetOption (name.c_str (), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetOptionAsAny(const char *name, boost::any& value);
|
bool GetOptionAsAny(const char *name, boost::any& value);
|
||||||
bool GetOptionAsAny(const std::string& name, boost::any& value);
|
bool GetOptionAsAny(const std::string& name, boost::any& value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set value of given parameter
|
* @brief Set value of given parameter
|
||||||
* @param name Name of settable parameter
|
* @param name Name of settable parameter
|
||||||
* @param value New parameter value
|
* @param value New parameter value
|
||||||
* @return true if value set up successful, false otherwise
|
* @return true if value set up successful, false otherwise
|
||||||
*
|
*
|
||||||
* Example: uint16_t port = 2827; SetOption("bob.port", port);
|
* Example: uint16_t port = 2827; SetOption("bob.port", port);
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool SetOption(const char *name, const T& value) {
|
bool SetOption(const char *name, const T& value)
|
||||||
if (!m_Options.count(name))
|
{
|
||||||
return false;
|
if (!m_Options.count(name))
|
||||||
m_Options.at(name).value() = value;
|
return false;
|
||||||
notify(m_Options);
|
m_Options.at(name).value() = value;
|
||||||
return true;
|
notify(m_Options);
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Check is value explicitly given or default
|
* @brief Check is value explicitly given or default
|
||||||
* @param name Name of checked parameter
|
* @param name Name of checked parameter
|
||||||
* @return true if value set to default, false otherwise
|
* @return true if value set to default, false otherwise
|
||||||
*/
|
*/
|
||||||
bool IsDefault(const char *name);
|
bool IsDefault(const char *name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -681,12 +681,12 @@ namespace crypto
|
||||||
|
|
||||||
// AES
|
// AES
|
||||||
#ifdef __AES__
|
#ifdef __AES__
|
||||||
#ifdef ARM64AES
|
#ifdef ARM64AES
|
||||||
void init_aesenc(void){
|
void init_aesenc(void){
|
||||||
// TODO: Implementation
|
// TODO: Implementation
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define KeyExpansion256(round0,round1) \
|
#define KeyExpansion256(round0,round1) \
|
||||||
"pshufd $0xff, %%xmm2, %%xmm2 \n" \
|
"pshufd $0xff, %%xmm2, %%xmm2 \n" \
|
||||||
|
@ -884,7 +884,6 @@ namespace crypto
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CBCEncryption::Encrypt (int numBlocks, const ChipherBlock * in, ChipherBlock * out)
|
void CBCEncryption::Encrypt (int numBlocks, const ChipherBlock * in, ChipherBlock * out)
|
||||||
{
|
{
|
||||||
#ifdef __AES__
|
#ifdef __AES__
|
||||||
|
@ -1364,4 +1363,3 @@ namespace crypto
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,13 +28,13 @@
|
||||||
#else
|
#else
|
||||||
# define LEGACY_OPENSSL 0
|
# define LEGACY_OPENSSL 0
|
||||||
# if (OPENSSL_VERSION_NUMBER >= 0x010101000) // 1.1.1
|
# if (OPENSSL_VERSION_NUMBER >= 0x010101000) // 1.1.1
|
||||||
# define OPENSSL_HKDF 1
|
# define OPENSSL_HKDF 1
|
||||||
# define OPENSSL_EDDSA 1
|
# define OPENSSL_EDDSA 1
|
||||||
# define OPENSSL_X25519 1
|
# define OPENSSL_X25519 1
|
||||||
# define OPENSSL_SIPHASH 1
|
# define OPENSSL_SIPHASH 1
|
||||||
# endif
|
# endif
|
||||||
# if !defined OPENSSL_NO_CHACHA && !defined OPENSSL_NO_POLY1305 // some builds might not include them
|
# if !defined OPENSSL_NO_CHACHA && !defined OPENSSL_NO_POLY1305 // some builds might not include them
|
||||||
# define OPENSSL_AEAD_CHACHA20_POLY1305 1
|
# define OPENSSL_AEAD_CHACHA20_POLY1305 1
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -178,4 +178,3 @@ namespace crypto
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,7 +126,7 @@ namespace crypto
|
||||||
ECIESX25519AEADRatchetEncryptor (const uint8_t * pub);
|
ECIESX25519AEADRatchetEncryptor (const uint8_t * pub);
|
||||||
~ECIESX25519AEADRatchetEncryptor () {};
|
~ECIESX25519AEADRatchetEncryptor () {};
|
||||||
void Encrypt (const uint8_t *, uint8_t * pub, BN_CTX *, bool);
|
void Encrypt (const uint8_t *, uint8_t * pub, BN_CTX *, bool);
|
||||||
// copies m_PublicKey to pub
|
// copies m_PublicKey to pub
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -153,4 +153,3 @@ namespace crypto
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -77,5 +77,4 @@ namespace worker
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -114,16 +114,15 @@ namespace datagram
|
||||||
LogPrint (eLogWarning, "Datagram: decompression failed");
|
LogPrint (eLogWarning, "Datagram: decompression failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> DatagramDestination::CreateDataMessage (
|
std::shared_ptr<I2NPMessage> DatagramDestination::CreateDataMessage (
|
||||||
const std::vector<std::pair<const uint8_t *, size_t> >& payloads,
|
const std::vector<std::pair<const uint8_t *, size_t> >& payloads,
|
||||||
uint16_t fromPort, uint16_t toPort, bool isRaw, bool checksum)
|
uint16_t fromPort, uint16_t toPort, bool isRaw, bool checksum)
|
||||||
{
|
{
|
||||||
auto msg = NewI2NPMessage ();
|
auto msg = NewI2NPMessage ();
|
||||||
uint8_t * buf = msg->GetPayload ();
|
uint8_t * buf = msg->GetPayload ();
|
||||||
buf += 4; // reserve for length
|
buf += 4; // reserve for length
|
||||||
size_t size = m_Gzip ? m_Deflator.Deflate (payloads, buf, msg->maxLen - msg->len) :
|
size_t size = m_Gzip ? m_Deflator.Deflate (payloads, buf, msg->maxLen - msg->len) :
|
||||||
i2p::data::GzipNoCompression (payloads, buf, msg->maxLen - msg->len);
|
i2p::data::GzipNoCompression (payloads, buf, msg->maxLen - msg->len);
|
||||||
if (size)
|
if (size)
|
||||||
{
|
{
|
||||||
htobe32buf (msg->GetPayload (), size); // length
|
htobe32buf (msg->GetPayload (), size); // length
|
||||||
|
@ -186,7 +185,7 @@ namespace datagram
|
||||||
}
|
}
|
||||||
|
|
||||||
DatagramSession::DatagramSession(std::shared_ptr<i2p::client::ClientDestination> localDestination,
|
DatagramSession::DatagramSession(std::shared_ptr<i2p::client::ClientDestination> localDestination,
|
||||||
const i2p::data::IdentHash & remoteIdent) :
|
const i2p::data::IdentHash & remoteIdent) :
|
||||||
m_LocalDestination(localDestination),
|
m_LocalDestination(localDestination),
|
||||||
m_RemoteIdent(remoteIdent),
|
m_RemoteIdent(remoteIdent),
|
||||||
m_SendQueueTimer(localDestination->GetService()),
|
m_SendQueueTimer(localDestination->GetService()),
|
||||||
|
@ -384,4 +383,3 @@ namespace datagram
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,25 +32,27 @@ namespace datagram
|
||||||
const uint64_t DATAGRAM_SESSION_LEASE_HANDOVER_FUDGE = 1000;
|
const uint64_t DATAGRAM_SESSION_LEASE_HANDOVER_FUDGE = 1000;
|
||||||
// milliseconds minimum time between path switches
|
// milliseconds minimum time between path switches
|
||||||
const uint64_t DATAGRAM_SESSION_PATH_MIN_LIFETIME = 5 * 1000;
|
const uint64_t DATAGRAM_SESSION_PATH_MIN_LIFETIME = 5 * 1000;
|
||||||
// max 64 messages buffered in send queue for each datagram session
|
// max 64 messages buffered in send queue for each datagram session
|
||||||
const size_t DATAGRAM_SEND_QUEUE_MAX_SIZE = 64;
|
const size_t DATAGRAM_SEND_QUEUE_MAX_SIZE = 64;
|
||||||
|
|
||||||
class DatagramSession : public std::enable_shared_from_this<DatagramSession>
|
class DatagramSession : public std::enable_shared_from_this<DatagramSession>
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
DatagramSession(std::shared_ptr<i2p::client::ClientDestination> localDestination, const i2p::data::IdentHash & remoteIdent);
|
|
||||||
|
|
||||||
void Start ();
|
public:
|
||||||
void Stop ();
|
|
||||||
|
DatagramSession(std::shared_ptr<i2p::client::ClientDestination> localDestination, const i2p::data::IdentHash & remoteIdent);
|
||||||
|
|
||||||
|
void Start ();
|
||||||
|
void Stop ();
|
||||||
|
|
||||||
|
|
||||||
/** @brief ack the garlic routing path */
|
/** @brief ack the garlic routing path */
|
||||||
void Ack();
|
void Ack();
|
||||||
|
|
||||||
/** send an i2np message to remote endpoint for this session */
|
/** send an i2np message to remote endpoint for this session */
|
||||||
void SendMsg(std::shared_ptr<I2NPMessage> msg);
|
void SendMsg(std::shared_ptr<I2NPMessage> msg);
|
||||||
/** get the last time in milliseconds for when we used this datagram session */
|
/** get the last time in milliseconds for when we used this datagram session */
|
||||||
uint64_t LastActivity() const { return m_LastUse; }
|
uint64_t LastActivity() const { return m_LastUse; }
|
||||||
|
|
||||||
bool IsRatchets () const { return m_RoutingSession && m_RoutingSession->IsRatchets (); }
|
bool IsRatchets () const { return m_RoutingSession && m_RoutingSession->IsRatchets (); }
|
||||||
|
|
||||||
|
@ -60,40 +62,41 @@ namespace datagram
|
||||||
std::shared_ptr<const i2p::data::IdentHash> OBEP;
|
std::shared_ptr<const i2p::data::IdentHash> OBEP;
|
||||||
const uint64_t activity;
|
const uint64_t activity;
|
||||||
|
|
||||||
Info() : IBGW(nullptr), OBEP(nullptr), activity(0) {}
|
Info() : IBGW(nullptr), OBEP(nullptr), activity(0) {}
|
||||||
Info(const uint8_t * ibgw, const uint8_t * obep, const uint64_t a) :
|
Info(const uint8_t * ibgw, const uint8_t * obep, const uint64_t a) :
|
||||||
activity(a) {
|
activity(a) {
|
||||||
if(ibgw) IBGW = std::make_shared<i2p::data::IdentHash>(ibgw);
|
if(ibgw) IBGW = std::make_shared<i2p::data::IdentHash>(ibgw);
|
||||||
else IBGW = nullptr;
|
else IBGW = nullptr;
|
||||||
if(obep) OBEP = std::make_shared<i2p::data::IdentHash>(obep);
|
if(obep) OBEP = std::make_shared<i2p::data::IdentHash>(obep);
|
||||||
else OBEP = nullptr;
|
else OBEP = nullptr;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Info GetSessionInfo() const;
|
Info GetSessionInfo() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void FlushSendQueue();
|
void FlushSendQueue();
|
||||||
void ScheduleFlushSendQueue();
|
void ScheduleFlushSendQueue();
|
||||||
|
|
||||||
void HandleSend(std::shared_ptr<I2NPMessage> msg);
|
void HandleSend(std::shared_ptr<I2NPMessage> msg);
|
||||||
|
|
||||||
std::shared_ptr<i2p::garlic::GarlicRoutingPath> GetSharedRoutingPath();
|
std::shared_ptr<i2p::garlic::GarlicRoutingPath> GetSharedRoutingPath();
|
||||||
|
|
||||||
void HandleLeaseSetUpdated(std::shared_ptr<i2p::data::LeaseSet> ls);
|
void HandleLeaseSetUpdated(std::shared_ptr<i2p::data::LeaseSet> ls);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<i2p::client::ClientDestination> m_LocalDestination;
|
|
||||||
i2p::data::IdentHash m_RemoteIdent;
|
std::shared_ptr<i2p::client::ClientDestination> m_LocalDestination;
|
||||||
std::shared_ptr<const i2p::data::LeaseSet> m_RemoteLeaseSet;
|
i2p::data::IdentHash m_RemoteIdent;
|
||||||
std::shared_ptr<i2p::garlic::GarlicRoutingSession> m_RoutingSession;
|
std::shared_ptr<const i2p::data::LeaseSet> m_RemoteLeaseSet;
|
||||||
std::shared_ptr<const i2p::data::Lease> m_CurrentRemoteLease;
|
std::shared_ptr<i2p::garlic::GarlicRoutingSession> m_RoutingSession;
|
||||||
std::shared_ptr<i2p::tunnel::OutboundTunnel> m_CurrentOutboundTunnel;
|
std::shared_ptr<const i2p::data::Lease> m_CurrentRemoteLease;
|
||||||
boost::asio::deadline_timer m_SendQueueTimer;
|
std::shared_ptr<i2p::tunnel::OutboundTunnel> m_CurrentOutboundTunnel;
|
||||||
std::vector<std::shared_ptr<I2NPMessage> > m_SendQueue;
|
boost::asio::deadline_timer m_SendQueueTimer;
|
||||||
uint64_t m_LastUse;
|
std::vector<std::shared_ptr<I2NPMessage> > m_SendQueue;
|
||||||
bool m_RequestingLS;
|
uint64_t m_LastUse;
|
||||||
|
bool m_RequestingLS;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::shared_ptr<DatagramSession> DatagramSession_ptr;
|
typedef std::shared_ptr<DatagramSession> DatagramSession_ptr;
|
||||||
|
@ -104,11 +107,9 @@ namespace datagram
|
||||||
typedef std::function<void (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len)> Receiver;
|
typedef std::function<void (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len)> Receiver;
|
||||||
typedef std::function<void (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len)> RawReceiver;
|
typedef std::function<void (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len)> RawReceiver;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
DatagramDestination (std::shared_ptr<i2p::client::ClientDestination> owner, bool gzip);
|
||||||
DatagramDestination (std::shared_ptr<i2p::client::ClientDestination> owner, bool gzip);
|
|
||||||
~DatagramDestination ();
|
~DatagramDestination ();
|
||||||
|
|
||||||
void SendDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash & ident, uint16_t fromPort = 0, uint16_t toPort = 0);
|
void SendDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash & ident, uint16_t fromPort = 0, uint16_t toPort = 0);
|
||||||
|
@ -131,7 +132,7 @@ namespace datagram
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::shared_ptr<DatagramSession> ObtainSession(const i2p::data::IdentHash & ident);
|
std::shared_ptr<DatagramSession> ObtainSession(const i2p::data::IdentHash & ident);
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> CreateDataMessage (const std::vector<std::pair<const uint8_t *, size_t> >& payloads,
|
std::shared_ptr<I2NPMessage> CreateDataMessage (const std::vector<std::pair<const uint8_t *, size_t> >& payloads,
|
||||||
uint16_t fromPort, uint16_t toPort, bool isRaw = false, bool checksum = true);
|
uint16_t fromPort, uint16_t toPort, bool isRaw = false, bool checksum = true);
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace i2p
|
||||||
namespace client
|
namespace client
|
||||||
{
|
{
|
||||||
LeaseSetDestination::LeaseSetDestination (boost::asio::io_service& service,
|
LeaseSetDestination::LeaseSetDestination (boost::asio::io_service& service,
|
||||||
bool isPublic, const std::map<std::string, std::string> * params):
|
bool isPublic, const std::map<std::string, std::string> * params):
|
||||||
m_Service (service), m_IsPublic (isPublic), m_PublishReplyToken (0),
|
m_Service (service), m_IsPublic (isPublic), m_PublishReplyToken (0),
|
||||||
m_LastSubmissionTime (0), m_PublishConfirmationTimer (m_Service),
|
m_LastSubmissionTime (0), m_PublishConfirmationTimer (m_Service),
|
||||||
m_PublishVerificationTimer (m_Service), m_PublishDelayTimer (m_Service), m_CleanupTimer (m_Service),
|
m_PublishVerificationTimer (m_Service), m_PublishDelayTimer (m_Service), m_CleanupTimer (m_Service),
|
||||||
|
@ -160,7 +160,6 @@ namespace client
|
||||||
|
|
||||||
bool LeaseSetDestination::Reconfigure(std::map<std::string, std::string> params)
|
bool LeaseSetDestination::Reconfigure(std::map<std::string, std::string> params)
|
||||||
{
|
{
|
||||||
|
|
||||||
auto itr = params.find("i2cp.dontPublishLeaseSet");
|
auto itr = params.find("i2cp.dontPublishLeaseSet");
|
||||||
if (itr != params.end())
|
if (itr != params.end())
|
||||||
{
|
{
|
||||||
|
@ -565,12 +564,12 @@ namespace client
|
||||||
m_PublishReplyToken = 0;
|
m_PublishReplyToken = 0;
|
||||||
if (GetIdentity ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ELGAMAL)
|
if (GetIdentity ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ELGAMAL)
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "Destination: Publish confirmation was not received in ", PUBLISH_CONFIRMATION_TIMEOUT, " seconds, will try again");
|
LogPrint (eLogWarning, "Destination: Publish confirmation was not received in ", PUBLISH_CONFIRMATION_TIMEOUT, " seconds, will try again");
|
||||||
Publish ();
|
Publish ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "Destination: Publish confirmation was not received in ", PUBLISH_CONFIRMATION_TIMEOUT, " seconds from Java floodfill for crypto type ", (int)GetIdentity ()->GetCryptoKeyType ());
|
LogPrint (eLogWarning, "Destination: Publish confirmation was not received in ", PUBLISH_CONFIRMATION_TIMEOUT, " seconds from Java floodfill for crypto type ", (int)GetIdentity ()->GetCryptoKeyType ());
|
||||||
// Java floodfill never sends confirmation back for unknown crypto type
|
// Java floodfill never sends confirmation back for unknown crypto type
|
||||||
// assume it successive and try to verify
|
// assume it successive and try to verify
|
||||||
m_PublishVerificationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_VERIFICATION_TIMEOUT));
|
m_PublishVerificationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_VERIFICATION_TIMEOUT));
|
||||||
|
@ -720,7 +719,7 @@ namespace client
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LeaseSetDestination::SendLeaseSetRequest (const i2p::data::IdentHash& dest,
|
bool LeaseSetDestination::SendLeaseSetRequest (const i2p::data::IdentHash& dest,
|
||||||
std::shared_ptr<const i2p::data::RouterInfo> nextFloodfill, std::shared_ptr<LeaseSetRequest> request)
|
std::shared_ptr<const i2p::data::RouterInfo> nextFloodfill, std::shared_ptr<LeaseSetRequest> request)
|
||||||
{
|
{
|
||||||
if (!request->replyTunnel || !request->replyTunnel->IsEstablished ())
|
if (!request->replyTunnel || !request->replyTunnel->IsEstablished ())
|
||||||
request->replyTunnel = m_Pool->GetNextInboundTunnel ();
|
request->replyTunnel = m_Pool->GetNextInboundTunnel ();
|
||||||
|
@ -783,7 +782,7 @@ namespace client
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "Destination: ", dest.ToBase64 (), " was not found within ", MAX_LEASESET_REQUEST_TIMEOUT, " seconds");
|
LogPrint (eLogWarning, "Destination: ", dest.ToBase64 (), " was not found within ", MAX_LEASESET_REQUEST_TIMEOUT, " seconds");
|
||||||
done = true;
|
done = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -829,7 +828,7 @@ namespace client
|
||||||
i2p::data::CryptoKeyType LeaseSetDestination::GetPreferredCryptoType () const
|
i2p::data::CryptoKeyType LeaseSetDestination::GetPreferredCryptoType () const
|
||||||
{
|
{
|
||||||
if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET))
|
if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET))
|
||||||
return i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET;
|
return i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET;
|
||||||
return i2p::data::CRYPTO_KEY_TYPE_ELGAMAL;
|
return i2p::data::CRYPTO_KEY_TYPE_ELGAMAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -846,7 +845,7 @@ namespace client
|
||||||
// extract encryption type params for LS2
|
// extract encryption type params for LS2
|
||||||
std::set<i2p::data::CryptoKeyType> encryptionKeyTypes;
|
std::set<i2p::data::CryptoKeyType> encryptionKeyTypes;
|
||||||
if ((GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2 ||
|
if ((GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2 ||
|
||||||
GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) && params)
|
GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2) && params)
|
||||||
{
|
{
|
||||||
auto it = params->find (I2CP_PARAM_LEASESET_ENCRYPTION_TYPE);
|
auto it = params->find (I2CP_PARAM_LEASESET_ENCRYPTION_TYPE);
|
||||||
if (it != params->end ())
|
if (it != params->end ())
|
||||||
|
@ -1105,7 +1104,7 @@ namespace client
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
i2p::datagram::DatagramDestination * ClientDestination::CreateDatagramDestination (bool gzip)
|
i2p::datagram::DatagramDestination * ClientDestination::CreateDatagramDestination (bool gzip)
|
||||||
{
|
{
|
||||||
if (m_DatagramDestination == nullptr)
|
if (m_DatagramDestination == nullptr)
|
||||||
m_DatagramDestination = new i2p::datagram::DatagramDestination (GetSharedFromThis (), gzip);
|
m_DatagramDestination = new i2p::datagram::DatagramDestination (GetSharedFromThis (), gzip);
|
||||||
|
@ -1147,7 +1146,7 @@ namespace client
|
||||||
// TODO:: persist crypto key type
|
// TODO:: persist crypto key type
|
||||||
std::ofstream f1 (path, std::ofstream::binary | std::ofstream::out);
|
std::ofstream f1 (path, std::ofstream::binary | std::ofstream::out);
|
||||||
if (f1) {
|
if (f1) {
|
||||||
f1.write ((char *)keys->pub, 256);
|
f1.write ((char *)keys->pub, 256);
|
||||||
f1.write ((char *)keys->priv, 256);
|
f1.write ((char *)keys->priv, 256);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,7 +94,6 @@ namespace client
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
LeaseSetDestination (boost::asio::io_service& service, bool isPublic, const std::map<std::string, std::string> * params = nullptr);
|
LeaseSetDestination (boost::asio::io_service& service, bool isPublic, const std::map<std::string, std::string> * params = nullptr);
|
||||||
|
@ -112,7 +111,7 @@ namespace client
|
||||||
bool IsReady () const { return m_LeaseSet && !m_LeaseSet->IsExpired () && m_Pool->GetOutboundTunnels ().size () > 0; };
|
bool IsReady () const { return m_LeaseSet && !m_LeaseSet->IsExpired () && m_Pool->GetOutboundTunnels ().size () > 0; };
|
||||||
std::shared_ptr<i2p::data::LeaseSet> FindLeaseSet (const i2p::data::IdentHash& ident);
|
std::shared_ptr<i2p::data::LeaseSet> FindLeaseSet (const i2p::data::IdentHash& ident);
|
||||||
bool RequestDestination (const i2p::data::IdentHash& dest, RequestComplete requestComplete = nullptr);
|
bool RequestDestination (const i2p::data::IdentHash& dest, RequestComplete requestComplete = nullptr);
|
||||||
bool RequestDestinationWithEncryptedLeaseSet (std::shared_ptr<const i2p::data::BlindedPublicKey> dest, RequestComplete requestComplete = nullptr);
|
bool RequestDestinationWithEncryptedLeaseSet (std::shared_ptr<const i2p::data::BlindedPublicKey> dest, RequestComplete requestComplete = nullptr);
|
||||||
void CancelDestinationRequest (const i2p::data::IdentHash& dest, bool notify = true);
|
void CancelDestinationRequest (const i2p::data::IdentHash& dest, bool notify = true);
|
||||||
void CancelDestinationRequestWithEncryptedLeaseSet (std::shared_ptr<const i2p::data::BlindedPublicKey> dest, bool notify = true);
|
void CancelDestinationRequestWithEncryptedLeaseSet (std::shared_ptr<const i2p::data::BlindedPublicKey> dest, bool notify = true);
|
||||||
|
|
||||||
|
@ -155,7 +154,7 @@ namespace client
|
||||||
void HandleDeliveryStatusMessage (uint32_t msgID);
|
void HandleDeliveryStatusMessage (uint32_t msgID);
|
||||||
|
|
||||||
void RequestLeaseSet (const i2p::data::IdentHash& dest, RequestComplete requestComplete, std::shared_ptr<const i2p::data::BlindedPublicKey> requestedBlindedKey = nullptr);
|
void RequestLeaseSet (const i2p::data::IdentHash& dest, RequestComplete requestComplete, std::shared_ptr<const i2p::data::BlindedPublicKey> requestedBlindedKey = nullptr);
|
||||||
bool SendLeaseSetRequest (const i2p::data::IdentHash& dest, std::shared_ptr<const i2p::data::RouterInfo> nextFloodfill, std::shared_ptr<LeaseSetRequest> request);
|
bool SendLeaseSetRequest (const i2p::data::IdentHash& dest, std::shared_ptr<const i2p::data::RouterInfo> nextFloodfill, std::shared_ptr<LeaseSetRequest> request);
|
||||||
void HandleRequestTimoutTimer (const boost::system::error_code& ecode, const i2p::data::IdentHash& dest);
|
void HandleRequestTimoutTimer (const boost::system::error_code& ecode, const i2p::data::IdentHash& dest);
|
||||||
void HandleCleanupTimer (const boost::system::error_code& ecode);
|
void HandleCleanupTimer (const boost::system::error_code& ecode);
|
||||||
void CleanupRemoteLeaseSets ();
|
void CleanupRemoteLeaseSets ();
|
||||||
|
@ -235,8 +234,8 @@ namespace client
|
||||||
int GetStreamingAckDelay () const { return m_StreamingAckDelay; }
|
int GetStreamingAckDelay () const { return m_StreamingAckDelay; }
|
||||||
|
|
||||||
// datagram
|
// datagram
|
||||||
i2p::datagram::DatagramDestination * GetDatagramDestination () const { return m_DatagramDestination; };
|
i2p::datagram::DatagramDestination * GetDatagramDestination () const { return m_DatagramDestination; };
|
||||||
i2p::datagram::DatagramDestination * CreateDatagramDestination (bool gzip = true);
|
i2p::datagram::DatagramDestination * CreateDatagramDestination (bool gzip = true);
|
||||||
|
|
||||||
// implements LocalDestination
|
// implements LocalDestination
|
||||||
bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const;
|
bool Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, i2p::data::CryptoKeyType preferredCrypto) const;
|
||||||
|
|
|
@ -15,36 +15,36 @@ namespace i2p
|
||||||
namespace garlic
|
namespace garlic
|
||||||
{
|
{
|
||||||
|
|
||||||
void RatchetTagSet::DHInitialize (const uint8_t * rootKey, const uint8_t * k)
|
void RatchetTagSet::DHInitialize (const uint8_t * rootKey, const uint8_t * k)
|
||||||
{
|
{
|
||||||
// DH_INITIALIZE(rootKey, k)
|
// DH_INITIALIZE(rootKey, k)
|
||||||
uint8_t keydata[64];
|
uint8_t keydata[64];
|
||||||
i2p::crypto::HKDF (rootKey, k, 32, "KDFDHRatchetStep", keydata); // keydata = HKDF(rootKey, k, "KDFDHRatchetStep", 64)
|
i2p::crypto::HKDF (rootKey, k, 32, "KDFDHRatchetStep", keydata); // keydata = HKDF(rootKey, k, "KDFDHRatchetStep", 64)
|
||||||
memcpy (m_NextRootKey, keydata, 32); // nextRootKey = keydata[0:31]
|
memcpy (m_NextRootKey, keydata, 32); // nextRootKey = keydata[0:31]
|
||||||
i2p::crypto::HKDF (keydata + 32, nullptr, 0, "TagAndKeyGenKeys", m_KeyData.buf);
|
i2p::crypto::HKDF (keydata + 32, nullptr, 0, "TagAndKeyGenKeys", m_KeyData.buf);
|
||||||
// [sessTag_ck, symmKey_ck] = HKDF(keydata[32:63], ZEROLEN, "TagAndKeyGenKeys", 64)
|
// [sessTag_ck, symmKey_ck] = HKDF(keydata[32:63], ZEROLEN, "TagAndKeyGenKeys", 64)
|
||||||
memcpy (m_SymmKeyCK, m_KeyData.buf + 32, 32);
|
memcpy (m_SymmKeyCK, m_KeyData.buf + 32, 32);
|
||||||
m_NextSymmKeyIndex = 0;
|
m_NextSymmKeyIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RatchetTagSet::NextSessionTagRatchet ()
|
void RatchetTagSet::NextSessionTagRatchet ()
|
||||||
{
|
{
|
||||||
i2p::crypto::HKDF (m_KeyData.GetSessTagCK (), nullptr, 0, "STInitialization", m_KeyData.buf); // [sessTag_ck, sesstag_constant] = HKDF(sessTag_ck, ZEROLEN, "STInitialization", 64)
|
i2p::crypto::HKDF (m_KeyData.GetSessTagCK (), nullptr, 0, "STInitialization", m_KeyData.buf); // [sessTag_ck, sesstag_constant] = HKDF(sessTag_ck, ZEROLEN, "STInitialization", 64)
|
||||||
memcpy (m_SessTagConstant, m_KeyData.GetSessTagConstant (), 32);
|
memcpy (m_SessTagConstant, m_KeyData.GetSessTagConstant (), 32);
|
||||||
m_NextIndex = 0;
|
m_NextIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t RatchetTagSet::GetNextSessionTag ()
|
uint64_t RatchetTagSet::GetNextSessionTag ()
|
||||||
{
|
{
|
||||||
i2p::crypto::HKDF (m_KeyData.GetSessTagCK (), m_SessTagConstant, 32, "SessionTagKeyGen", m_KeyData.buf); // [sessTag_ck, tag] = HKDF(sessTag_chainkey, SESSTAG_CONSTANT, "SessionTagKeyGen", 64)
|
i2p::crypto::HKDF (m_KeyData.GetSessTagCK (), m_SessTagConstant, 32, "SessionTagKeyGen", m_KeyData.buf); // [sessTag_ck, tag] = HKDF(sessTag_chainkey, SESSTAG_CONSTANT, "SessionTagKeyGen", 64)
|
||||||
m_NextIndex++;
|
m_NextIndex++;
|
||||||
if (m_NextIndex >= 65535)
|
if (m_NextIndex >= 65535)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "Garlic: Tagset ", GetTagSetID (), " is empty");
|
LogPrint (eLogError, "Garlic: Tagset ", GetTagSetID (), " is empty");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return m_KeyData.GetTag ();
|
return m_KeyData.GetTag ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RatchetTagSet::GetSymmKey (int index, uint8_t * key)
|
void RatchetTagSet::GetSymmKey (int index, uint8_t * key)
|
||||||
{
|
{
|
||||||
|
@ -85,15 +85,15 @@ namespace garlic
|
||||||
m_ExpirationTimestamp = i2p::util::GetSecondsSinceEpoch () + ECIESX25519_PREVIOUS_TAGSET_EXPIRATION_TIMEOUT;
|
m_ExpirationTimestamp = i2p::util::GetSecondsSinceEpoch () + ECIESX25519_PREVIOUS_TAGSET_EXPIRATION_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
ECIESX25519AEADRatchetSession::ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSet):
|
ECIESX25519AEADRatchetSession::ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSet):
|
||||||
GarlicRoutingSession (owner, attachLeaseSet)
|
GarlicRoutingSession (owner, attachLeaseSet)
|
||||||
{
|
{
|
||||||
ResetKeys ();
|
ResetKeys ();
|
||||||
}
|
}
|
||||||
|
|
||||||
ECIESX25519AEADRatchetSession::~ECIESX25519AEADRatchetSession ()
|
ECIESX25519AEADRatchetSession::~ECIESX25519AEADRatchetSession ()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void ECIESX25519AEADRatchetSession::ResetKeys ()
|
void ECIESX25519AEADRatchetSession::ResetKeys ()
|
||||||
{
|
{
|
||||||
|
@ -111,14 +111,14 @@ namespace garlic
|
||||||
memcpy (m_H, hh, 32);
|
memcpy (m_H, hh, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ECIESX25519AEADRatchetSession::MixHash (const uint8_t * buf, size_t len)
|
void ECIESX25519AEADRatchetSession::MixHash (const uint8_t * buf, size_t len)
|
||||||
{
|
{
|
||||||
SHA256_CTX ctx;
|
SHA256_CTX ctx;
|
||||||
SHA256_Init (&ctx);
|
SHA256_Init (&ctx);
|
||||||
SHA256_Update (&ctx, m_H, 32);
|
SHA256_Update (&ctx, m_H, 32);
|
||||||
SHA256_Update (&ctx, buf, len);
|
SHA256_Update (&ctx, buf, len);
|
||||||
SHA256_Final (m_H, &ctx);
|
SHA256_Final (m_H, &ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ECIESX25519AEADRatchetSession::CreateNonce (uint64_t seqn, uint8_t * nonce)
|
void ECIESX25519AEADRatchetSession::CreateNonce (uint64_t seqn, uint8_t * nonce)
|
||||||
{
|
{
|
||||||
|
@ -126,48 +126,48 @@ namespace garlic
|
||||||
htole64buf (nonce + 4, seqn);
|
htole64buf (nonce + 4, seqn);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ECIESX25519AEADRatchetSession::GenerateEphemeralKeysAndEncode (uint8_t * buf)
|
bool ECIESX25519AEADRatchetSession::GenerateEphemeralKeysAndEncode (uint8_t * buf)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 10; i++)
|
for (int i = 0; i < 10; i++)
|
||||||
{
|
{
|
||||||
m_EphemeralKeys.GenerateKeys ();
|
m_EphemeralKeys.GenerateKeys ();
|
||||||
if (i2p::crypto::GetElligator ()->Encode (m_EphemeralKeys.GetPublicKey (), buf))
|
if (i2p::crypto::GetElligator ()->Encode (m_EphemeralKeys.GetPublicKey (), buf))
|
||||||
return true; // success
|
return true; // success
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<RatchetTagSet> ECIESX25519AEADRatchetSession::CreateNewSessionTagset ()
|
std::shared_ptr<RatchetTagSet> ECIESX25519AEADRatchetSession::CreateNewSessionTagset ()
|
||||||
{
|
{
|
||||||
uint8_t tagsetKey[32];
|
uint8_t tagsetKey[32];
|
||||||
i2p::crypto::HKDF (m_CK, nullptr, 0, "SessionReplyTags", tagsetKey, 32); // tagsetKey = HKDF(chainKey, ZEROLEN, "SessionReplyTags", 32)
|
i2p::crypto::HKDF (m_CK, nullptr, 0, "SessionReplyTags", tagsetKey, 32); // tagsetKey = HKDF(chainKey, ZEROLEN, "SessionReplyTags", 32)
|
||||||
// Session Tag Ratchet
|
// Session Tag Ratchet
|
||||||
auto tagsetNsr = std::make_shared<RatchetTagSet>(shared_from_this ());
|
auto tagsetNsr = std::make_shared<RatchetTagSet>(shared_from_this ());
|
||||||
tagsetNsr->DHInitialize (m_CK, tagsetKey); // tagset_nsr = DH_INITIALIZE(chainKey, tagsetKey)
|
tagsetNsr->DHInitialize (m_CK, tagsetKey); // tagset_nsr = DH_INITIALIZE(chainKey, tagsetKey)
|
||||||
tagsetNsr->NextSessionTagRatchet ();
|
tagsetNsr->NextSessionTagRatchet ();
|
||||||
return tagsetNsr;
|
return tagsetNsr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ECIESX25519AEADRatchetSession::HandleNewIncomingSession (const uint8_t * buf, size_t len)
|
bool ECIESX25519AEADRatchetSession::HandleNewIncomingSession (const uint8_t * buf, size_t len)
|
||||||
{
|
{
|
||||||
if (!GetOwner ()) return false;
|
if (!GetOwner ()) return false;
|
||||||
// we are Bob
|
// we are Bob
|
||||||
// KDF1
|
// KDF1
|
||||||
MixHash (GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET), 32); // h = SHA256(h || bpk)
|
MixHash (GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET), 32); // h = SHA256(h || bpk)
|
||||||
|
|
||||||
if (!i2p::crypto::GetElligator ()->Decode (buf, m_Aepk))
|
if (!i2p::crypto::GetElligator ()->Decode (buf, m_Aepk))
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "Garlic: Can't decode elligator");
|
LogPrint (eLogError, "Garlic: Can't decode elligator");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
buf += 32; len -= 32;
|
buf += 32; len -= 32;
|
||||||
MixHash (m_Aepk, 32); // h = SHA256(h || aepk)
|
MixHash (m_Aepk, 32); // h = SHA256(h || aepk)
|
||||||
|
|
||||||
uint8_t sharedSecret[32];
|
uint8_t sharedSecret[32];
|
||||||
GetOwner ()->Decrypt (m_Aepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519(bsk, aepk)
|
GetOwner ()->Decrypt (m_Aepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519(bsk, aepk)
|
||||||
i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64)
|
i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64)
|
||||||
|
|
||||||
// decrypt flags/static
|
// decrypt flags/static
|
||||||
uint8_t nonce[12], fs[32];
|
uint8_t nonce[12], fs[32];
|
||||||
CreateNonce (0, nonce);
|
CreateNonce (0, nonce);
|
||||||
if (!i2p::crypto::AEADChaCha20Poly1305 (buf, 32, m_H, 32, m_CK + 32, nonce, fs, 32, false)) // decrypt
|
if (!i2p::crypto::AEADChaCha20Poly1305 (buf, 32, m_H, 32, m_CK + 32, nonce, fs, 32, false)) // decrypt
|
||||||
|
@ -183,7 +183,7 @@ namespace garlic
|
||||||
if (isStatic)
|
if (isStatic)
|
||||||
{
|
{
|
||||||
// static key, fs is apk
|
// static key, fs is apk
|
||||||
memcpy (m_RemoteStaticKey, fs, 32);
|
memcpy (m_RemoteStaticKey, fs, 32);
|
||||||
GetOwner ()->Decrypt (fs, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519(bsk, apk)
|
GetOwner ()->Decrypt (fs, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519(bsk, apk)
|
||||||
i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64)
|
i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64)
|
||||||
}
|
}
|
||||||
|
@ -198,17 +198,17 @@ namespace garlic
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (isStatic) MixHash (buf, len); // h = SHA256(h || ciphertext)
|
if (isStatic) MixHash (buf, len); // h = SHA256(h || ciphertext)
|
||||||
m_State = eSessionStateNewSessionReceived;
|
m_State = eSessionStateNewSessionReceived;
|
||||||
GetOwner ()->AddECIESx25519Session (m_RemoteStaticKey, shared_from_this ());
|
GetOwner ()->AddECIESx25519Session (m_RemoteStaticKey, shared_from_this ());
|
||||||
|
|
||||||
HandlePayload (payload.data (), len - 16, nullptr, 0);
|
HandlePayload (payload.data (), len - 16, nullptr, 0);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ECIESX25519AEADRatchetSession::HandlePayload (const uint8_t * buf, size_t len, const std::shared_ptr<RatchetTagSet>& receiveTagset, int index)
|
void ECIESX25519AEADRatchetSession::HandlePayload (const uint8_t * buf, size_t len, const std::shared_ptr<RatchetTagSet>& receiveTagset, int index)
|
||||||
{
|
{
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
while (offset < len)
|
while (offset < len)
|
||||||
{
|
{
|
||||||
uint8_t blk = buf[offset];
|
uint8_t blk = buf[offset];
|
||||||
|
@ -269,7 +269,7 @@ namespace garlic
|
||||||
}
|
}
|
||||||
offset += size;
|
offset += size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ECIESX25519AEADRatchetSession::HandleNextKey (const uint8_t * buf, size_t len, const std::shared_ptr<RatchetTagSet>& receiveTagset)
|
void ECIESX25519AEADRatchetSession::HandleNextKey (const uint8_t * buf, size_t len, const std::shared_ptr<RatchetTagSet>& receiveTagset)
|
||||||
{
|
{
|
||||||
|
@ -279,7 +279,7 @@ namespace garlic
|
||||||
if (!m_SendForwardKey || !m_NextSendRatchet) return;
|
if (!m_SendForwardKey || !m_NextSendRatchet) return;
|
||||||
uint16_t keyID = bufbe16toh (buf); buf += 2; // keyID
|
uint16_t keyID = bufbe16toh (buf); buf += 2; // keyID
|
||||||
if (((!m_NextSendRatchet->newKey || !m_NextSendRatchet->keyID) && keyID == m_NextSendRatchet->keyID) ||
|
if (((!m_NextSendRatchet->newKey || !m_NextSendRatchet->keyID) && keyID == m_NextSendRatchet->keyID) ||
|
||||||
(m_NextSendRatchet->newKey && keyID == m_NextSendRatchet->keyID -1))
|
(m_NextSendRatchet->newKey && keyID == m_NextSendRatchet->keyID -1))
|
||||||
{
|
{
|
||||||
if (flag & ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG)
|
if (flag & ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG)
|
||||||
memcpy (m_NextSendRatchet->remote, buf, 32);
|
memcpy (m_NextSendRatchet->remote, buf, 32);
|
||||||
|
@ -359,36 +359,36 @@ namespace garlic
|
||||||
LogPrint (eLogDebug, "Garlic: new send ratchet ", m_NextSendRatchet->newKey ? "new" : "old", " key ", m_NextSendRatchet->keyID, " created");
|
LogPrint (eLogDebug, "Garlic: new send ratchet ", m_NextSendRatchet->newKey ? "new" : "old", " key ", m_NextSendRatchet->keyID, " created");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ECIESX25519AEADRatchetSession::NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen)
|
bool ECIESX25519AEADRatchetSession::NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen)
|
||||||
{
|
{
|
||||||
ResetKeys ();
|
ResetKeys ();
|
||||||
// we are Alice, bpk is m_RemoteStaticKey
|
// we are Alice, bpk is m_RemoteStaticKey
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
if (!GenerateEphemeralKeysAndEncode (out + offset))
|
if (!GenerateEphemeralKeysAndEncode (out + offset))
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "Garlic: Can't encode elligator");
|
LogPrint (eLogError, "Garlic: Can't encode elligator");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
offset += 32;
|
offset += 32;
|
||||||
|
|
||||||
// KDF1
|
// KDF1
|
||||||
MixHash (m_RemoteStaticKey, 32); // h = SHA256(h || bpk)
|
MixHash (m_RemoteStaticKey, 32); // h = SHA256(h || bpk)
|
||||||
MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || aepk)
|
MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || aepk)
|
||||||
uint8_t sharedSecret[32];
|
uint8_t sharedSecret[32];
|
||||||
m_EphemeralKeys.Agree (m_RemoteStaticKey, sharedSecret); // x25519(aesk, bpk)
|
m_EphemeralKeys.Agree (m_RemoteStaticKey, sharedSecret); // x25519(aesk, bpk)
|
||||||
i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64)
|
i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64)
|
||||||
// encrypt static key section
|
// encrypt static key section
|
||||||
uint8_t nonce[12];
|
uint8_t nonce[12];
|
||||||
CreateNonce (0, nonce);
|
CreateNonce (0, nonce);
|
||||||
if (!i2p::crypto::AEADChaCha20Poly1305 (GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET), 32, m_H, 32, m_CK + 32, nonce, out + offset, 48, true)) // encrypt
|
if (!i2p::crypto::AEADChaCha20Poly1305 (GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET), 32, m_H, 32, m_CK + 32, nonce, out + offset, 48, true)) // encrypt
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "Garlic: Static section AEAD encryption failed ");
|
LogPrint (eLogWarning, "Garlic: Static section AEAD encryption failed ");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
MixHash (out + offset, 48); // h = SHA256(h || ciphertext)
|
MixHash (out + offset, 48); // h = SHA256(h || ciphertext)
|
||||||
offset += 48;
|
offset += 48;
|
||||||
// KDF2
|
// KDF2
|
||||||
GetOwner ()->Decrypt (m_RemoteStaticKey, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519 (ask, bpk)
|
GetOwner ()->Decrypt (m_RemoteStaticKey, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519 (ask, bpk)
|
||||||
i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64)
|
i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64)
|
||||||
// encrypt payload
|
// encrypt payload
|
||||||
if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_CK + 32, nonce, out + offset, len + 16, true)) // encrypt
|
if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_CK + 32, nonce, out + offset, len + 16, true)) // encrypt
|
||||||
|
@ -399,80 +399,80 @@ namespace garlic
|
||||||
MixHash (out + offset, len + 16); // h = SHA256(h || ciphertext)
|
MixHash (out + offset, len + 16); // h = SHA256(h || ciphertext)
|
||||||
|
|
||||||
m_State = eSessionStateNewSessionSent;
|
m_State = eSessionStateNewSessionSent;
|
||||||
if (GetOwner ())
|
if (GetOwner ())
|
||||||
GenerateMoreReceiveTags (CreateNewSessionTagset (), ECIESX25519_NSR_NUM_GENERATED_TAGS);
|
GenerateMoreReceiveTags (CreateNewSessionTagset (), ECIESX25519_NSR_NUM_GENERATED_TAGS);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ECIESX25519AEADRatchetSession::NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen)
|
bool ECIESX25519AEADRatchetSession::NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen)
|
||||||
{
|
{
|
||||||
// we are Bob
|
// we are Bob
|
||||||
m_NSRTagset = CreateNewSessionTagset ();
|
m_NSRTagset = CreateNewSessionTagset ();
|
||||||
uint64_t tag = m_NSRTagset->GetNextSessionTag ();
|
uint64_t tag = m_NSRTagset->GetNextSessionTag ();
|
||||||
|
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
memcpy (out + offset, &tag, 8);
|
memcpy (out + offset, &tag, 8);
|
||||||
offset += 8;
|
offset += 8;
|
||||||
if (!GenerateEphemeralKeysAndEncode (out + offset)) // bepk
|
if (!GenerateEphemeralKeysAndEncode (out + offset)) // bepk
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "Garlic: Can't encode elligator");
|
LogPrint (eLogError, "Garlic: Can't encode elligator");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
memcpy (m_NSREncodedKey, out + offset, 56); // for possible next NSR
|
memcpy (m_NSREncodedKey, out + offset, 56); // for possible next NSR
|
||||||
memcpy (m_NSRH, m_H, 32);
|
memcpy (m_NSRH, m_H, 32);
|
||||||
offset += 32;
|
offset += 32;
|
||||||
// KDF for Reply Key Section
|
// KDF for Reply Key Section
|
||||||
MixHash ((const uint8_t *)&tag, 8); // h = SHA256(h || tag)
|
MixHash ((const uint8_t *)&tag, 8); // h = SHA256(h || tag)
|
||||||
MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || bepk)
|
MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || bepk)
|
||||||
uint8_t sharedSecret[32];
|
uint8_t sharedSecret[32];
|
||||||
m_EphemeralKeys.Agree (m_Aepk, sharedSecret); // sharedSecret = x25519(besk, aepk)
|
m_EphemeralKeys.Agree (m_Aepk, sharedSecret); // sharedSecret = x25519(besk, aepk)
|
||||||
i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK, 32); // chainKey = HKDF(chainKey, sharedSecret, "", 32)
|
i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK, 32); // chainKey = HKDF(chainKey, sharedSecret, "", 32)
|
||||||
m_EphemeralKeys.Agree (m_RemoteStaticKey, sharedSecret); // sharedSecret = x25519(besk, apk)
|
m_EphemeralKeys.Agree (m_RemoteStaticKey, sharedSecret); // sharedSecret = x25519(besk, apk)
|
||||||
i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64)
|
i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64)
|
||||||
uint8_t nonce[12];
|
uint8_t nonce[12];
|
||||||
CreateNonce (0, nonce);
|
CreateNonce (0, nonce);
|
||||||
// calulate hash for zero length
|
// calculate hash for zero length
|
||||||
if (!i2p::crypto::AEADChaCha20Poly1305 (nonce /* can be anything */, 0, m_H, 32, m_CK + 32, nonce, out + offset, 16, true)) // encrypt, ciphertext = ENCRYPT(k, n, ZEROLEN, ad)
|
if (!i2p::crypto::AEADChaCha20Poly1305 (nonce /* can be anything */, 0, m_H, 32, m_CK + 32, nonce, out + offset, 16, true)) // encrypt, ciphertext = ENCRYPT(k, n, ZEROLEN, ad)
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "Garlic: Reply key section AEAD encryption failed");
|
LogPrint (eLogWarning, "Garlic: Reply key section AEAD encryption failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
MixHash (out + offset, 16); // h = SHA256(h || ciphertext)
|
MixHash (out + offset, 16); // h = SHA256(h || ciphertext)
|
||||||
offset += 16;
|
offset += 16;
|
||||||
// KDF for payload
|
// KDF for payload
|
||||||
uint8_t keydata[64];
|
uint8_t keydata[64];
|
||||||
i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64)
|
i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64)
|
||||||
// k_ab = keydata[0:31], k_ba = keydata[32:63]
|
// k_ab = keydata[0:31], k_ba = keydata[32:63]
|
||||||
auto receiveTagset = std::make_shared<RatchetTagSet>(shared_from_this ());
|
auto receiveTagset = std::make_shared<RatchetTagSet>(shared_from_this ());
|
||||||
receiveTagset->DHInitialize (m_CK, keydata); // tagset_ab = DH_INITIALIZE(chainKey, k_ab)
|
receiveTagset->DHInitialize (m_CK, keydata); // tagset_ab = DH_INITIALIZE(chainKey, k_ab)
|
||||||
receiveTagset->NextSessionTagRatchet ();
|
receiveTagset->NextSessionTagRatchet ();
|
||||||
m_SendTagset = std::make_shared<RatchetTagSet>(shared_from_this ());
|
m_SendTagset = std::make_shared<RatchetTagSet>(shared_from_this ());
|
||||||
m_SendTagset->DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba)
|
m_SendTagset->DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba)
|
||||||
m_SendTagset->NextSessionTagRatchet ();
|
m_SendTagset->NextSessionTagRatchet ();
|
||||||
GenerateMoreReceiveTags (receiveTagset, ECIESX25519_MIN_NUM_GENERATED_TAGS);
|
GenerateMoreReceiveTags (receiveTagset, ECIESX25519_MIN_NUM_GENERATED_TAGS);
|
||||||
i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", m_NSRKey, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32)
|
i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", m_NSRKey, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32)
|
||||||
// encrypt payload
|
// encrypt payload
|
||||||
if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_NSRKey, nonce, out + offset, len + 16, true)) // encrypt
|
if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_NSRKey, nonce, out + offset, len + 16, true)) // encrypt
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "Garlic: NSR payload section AEAD encryption failed");
|
LogPrint (eLogWarning, "Garlic: NSR payload section AEAD encryption failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_State = eSessionStateNewSessionReplySent;
|
m_State = eSessionStateNewSessionReplySent;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ECIESX25519AEADRatchetSession::NextNewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen)
|
bool ECIESX25519AEADRatchetSession::NextNewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen)
|
||||||
{
|
{
|
||||||
// we are Bob and sent NSR already
|
// we are Bob and sent NSR already
|
||||||
uint64_t tag = m_NSRTagset->GetNextSessionTag (); // next tag
|
uint64_t tag = m_NSRTagset->GetNextSessionTag (); // next tag
|
||||||
memcpy (out, &tag, 8);
|
memcpy (out, &tag, 8);
|
||||||
memcpy (out + 8, m_NSREncodedKey, 32);
|
memcpy (out + 8, m_NSREncodedKey, 32);
|
||||||
// recalculte h with new tag
|
// recalculate h with new tag
|
||||||
memcpy (m_H, m_NSRH, 32);
|
memcpy (m_H, m_NSRH, 32);
|
||||||
MixHash ((const uint8_t *)&tag, 8); // h = SHA256(h || tag)
|
MixHash ((const uint8_t *)&tag, 8); // h = SHA256(h || tag)
|
||||||
MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || bepk)
|
MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || bepk)
|
||||||
uint8_t nonce[12];
|
uint8_t nonce[12];
|
||||||
CreateNonce (0, nonce);
|
CreateNonce (0, nonce);
|
||||||
if (!i2p::crypto::AEADChaCha20Poly1305 (nonce /* can be anything */, 0, m_H, 32, m_CK + 32, nonce, out + 40, 16, true)) // encrypt, ciphertext = ENCRYPT(k, n, ZEROLEN, ad)
|
if (!i2p::crypto::AEADChaCha20Poly1305 (nonce /* can be anything */, 0, m_H, 32, m_CK + 32, nonce, out + 40, 16, true)) // encrypt, ciphertext = ENCRYPT(k, n, ZEROLEN, ad)
|
||||||
|
@ -482,7 +482,7 @@ namespace garlic
|
||||||
}
|
}
|
||||||
MixHash (out + 40, 16); // h = SHA256(h || ciphertext)
|
MixHash (out + 40, 16); // h = SHA256(h || ciphertext)
|
||||||
// encrypt payload
|
// encrypt payload
|
||||||
if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_NSRKey, nonce, out + 56, len + 16, true)) // encrypt
|
if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_NSRKey, nonce, out + 56, len + 16, true)) // encrypt
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "Garlic: Next NSR payload section AEAD encryption failed");
|
LogPrint (eLogWarning, "Garlic: Next NSR payload section AEAD encryption failed");
|
||||||
return false;
|
return false;
|
||||||
|
@ -490,36 +490,36 @@ namespace garlic
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ECIESX25519AEADRatchetSession::HandleNewOutgoingSessionReply (uint8_t * buf, size_t len)
|
bool ECIESX25519AEADRatchetSession::HandleNewOutgoingSessionReply (uint8_t * buf, size_t len)
|
||||||
{
|
{
|
||||||
// we are Alice
|
// we are Alice
|
||||||
LogPrint (eLogDebug, "Garlic: reply received");
|
LogPrint (eLogDebug, "Garlic: reply received");
|
||||||
const uint8_t * tag = buf;
|
const uint8_t * tag = buf;
|
||||||
buf += 8; len -= 8; // tag
|
buf += 8; len -= 8; // tag
|
||||||
uint8_t bepk[32]; // Bob's ephemeral key
|
uint8_t bepk[32]; // Bob's ephemeral key
|
||||||
if (!i2p::crypto::GetElligator ()->Decode (buf, bepk))
|
if (!i2p::crypto::GetElligator ()->Decode (buf, bepk))
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "Garlic: Can't decode elligator");
|
LogPrint (eLogError, "Garlic: Can't decode elligator");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
buf += 32; len -= 32;
|
buf += 32; len -= 32;
|
||||||
// KDF for Reply Key Section
|
// KDF for Reply Key Section
|
||||||
uint8_t h[32]; memcpy (h, m_H, 32); // save m_H
|
uint8_t h[32]; memcpy (h, m_H, 32); // save m_H
|
||||||
MixHash (tag, 8); // h = SHA256(h || tag)
|
MixHash (tag, 8); // h = SHA256(h || tag)
|
||||||
MixHash (bepk, 32); // h = SHA256(h || bepk)
|
MixHash (bepk, 32); // h = SHA256(h || bepk)
|
||||||
uint8_t sharedSecret[32];
|
uint8_t sharedSecret[32];
|
||||||
if (m_State == eSessionStateNewSessionSent)
|
if (m_State == eSessionStateNewSessionSent)
|
||||||
{
|
{
|
||||||
// only fist time, we assume ephemeral keys the same
|
// only fist time, we assume ephemeral keys the same
|
||||||
m_EphemeralKeys.Agree (bepk, sharedSecret); // sharedSecret = x25519(aesk, bepk)
|
m_EphemeralKeys.Agree (bepk, sharedSecret); // sharedSecret = x25519(aesk, bepk)
|
||||||
i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK, 32); // chainKey = HKDF(chainKey, sharedSecret, "", 32)
|
i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK, 32); // chainKey = HKDF(chainKey, sharedSecret, "", 32)
|
||||||
GetOwner ()->Decrypt (bepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519 (ask, bepk)
|
GetOwner ()->Decrypt (bepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519 (ask, bepk)
|
||||||
i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64)
|
i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64)
|
||||||
}
|
}
|
||||||
uint8_t nonce[12];
|
uint8_t nonce[12];
|
||||||
CreateNonce (0, nonce);
|
CreateNonce (0, nonce);
|
||||||
// calulate hash for zero length
|
// calculate hash for zero length
|
||||||
if (!i2p::crypto::AEADChaCha20Poly1305 (buf, 0, m_H, 32, m_CK + 32, nonce, sharedSecret/* can be anyting */, 0, false)) // decrypt, DECRYPT(k, n, ZEROLEN, ad) verification only
|
if (!i2p::crypto::AEADChaCha20Poly1305 (buf, 0, m_H, 32, m_CK + 32, nonce, sharedSecret/* can be anything */, 0, false)) // decrypt, DECRYPT(k, n, ZEROLEN, ad) verification only
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "Garlic: Reply key section AEAD decryption failed");
|
LogPrint (eLogWarning, "Garlic: Reply key section AEAD decryption failed");
|
||||||
return false;
|
return false;
|
||||||
|
@ -527,22 +527,22 @@ namespace garlic
|
||||||
MixHash (buf, 16); // h = SHA256(h || ciphertext)
|
MixHash (buf, 16); // h = SHA256(h || ciphertext)
|
||||||
buf += 16; len -= 16;
|
buf += 16; len -= 16;
|
||||||
// KDF for payload
|
// KDF for payload
|
||||||
uint8_t keydata[64];
|
uint8_t keydata[64];
|
||||||
i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64)
|
i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64)
|
||||||
if (m_State == eSessionStateNewSessionSent)
|
if (m_State == eSessionStateNewSessionSent)
|
||||||
{
|
{
|
||||||
// k_ab = keydata[0:31], k_ba = keydata[32:63]
|
// k_ab = keydata[0:31], k_ba = keydata[32:63]
|
||||||
m_SendTagset = std::make_shared<RatchetTagSet>(shared_from_this ());
|
m_SendTagset = std::make_shared<RatchetTagSet>(shared_from_this ());
|
||||||
m_SendTagset->DHInitialize (m_CK, keydata); // tagset_ab = DH_INITIALIZE(chainKey, k_ab)
|
m_SendTagset->DHInitialize (m_CK, keydata); // tagset_ab = DH_INITIALIZE(chainKey, k_ab)
|
||||||
m_SendTagset->NextSessionTagRatchet ();
|
m_SendTagset->NextSessionTagRatchet ();
|
||||||
auto receiveTagset = std::make_shared<RatchetTagSet>(shared_from_this ());
|
auto receiveTagset = std::make_shared<RatchetTagSet>(shared_from_this ());
|
||||||
receiveTagset->DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba)
|
receiveTagset->DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba)
|
||||||
receiveTagset->NextSessionTagRatchet ();
|
receiveTagset->NextSessionTagRatchet ();
|
||||||
GenerateMoreReceiveTags (receiveTagset, ECIESX25519_MIN_NUM_GENERATED_TAGS);
|
GenerateMoreReceiveTags (receiveTagset, ECIESX25519_MIN_NUM_GENERATED_TAGS);
|
||||||
}
|
}
|
||||||
i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", keydata, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32)
|
i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", keydata, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32)
|
||||||
// decrypt payload
|
// decrypt payload
|
||||||
if (!i2p::crypto::AEADChaCha20Poly1305 (buf, len - 16, m_H, 32, keydata, nonce, buf, len - 16, false)) // decrypt
|
if (!i2p::crypto::AEADChaCha20Poly1305 (buf, len - 16, m_H, 32, keydata, nonce, buf, len - 16, false)) // decrypt
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "Garlic: Payload section AEAD decryption failed");
|
LogPrint (eLogWarning, "Garlic: Payload section AEAD decryption failed");
|
||||||
return false;
|
return false;
|
||||||
|
@ -560,8 +560,8 @@ namespace garlic
|
||||||
SetLeaseSetUpdateStatus (eLeaseSetUpToDate);
|
SetLeaseSetUpdateStatus (eLeaseSetUpToDate);
|
||||||
SetLeaseSetUpdateMsgID (0);
|
SetLeaseSetUpdateMsgID (0);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ECIESX25519AEADRatchetSession::NewExistingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen)
|
bool ECIESX25519AEADRatchetSession::NewExistingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen)
|
||||||
{
|
{
|
||||||
|
@ -637,61 +637,61 @@ namespace garlic
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> ECIESX25519AEADRatchetSession::WrapSingleMessage (std::shared_ptr<const I2NPMessage> msg)
|
std::shared_ptr<I2NPMessage> ECIESX25519AEADRatchetSession::WrapSingleMessage (std::shared_ptr<const I2NPMessage> msg)
|
||||||
{
|
{
|
||||||
auto payload = CreatePayload (msg, m_State != eSessionStateEstablished);
|
auto payload = CreatePayload (msg, m_State != eSessionStateEstablished);
|
||||||
size_t len = payload.size ();
|
size_t len = payload.size ();
|
||||||
if (!len) return nullptr;
|
if (!len) return nullptr;
|
||||||
auto m = NewI2NPMessage (len + 100); // 96 + 4
|
auto m = NewI2NPMessage (len + 100); // 96 + 4
|
||||||
m->Align (12); // in order to get buf aligned to 16 (12 + 4)
|
m->Align (12); // in order to get buf aligned to 16 (12 + 4)
|
||||||
uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length
|
uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length
|
||||||
|
|
||||||
switch (m_State)
|
switch (m_State)
|
||||||
{
|
{
|
||||||
case eSessionStateEstablished:
|
case eSessionStateEstablished:
|
||||||
if (!NewExistingSessionMessage (payload.data (), payload.size (), buf, m->maxLen))
|
if (!NewExistingSessionMessage (payload.data (), payload.size (), buf, m->maxLen))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
len += 24;
|
len += 24;
|
||||||
break;
|
break;
|
||||||
case eSessionStateNew:
|
case eSessionStateNew:
|
||||||
if (!NewOutgoingSessionMessage (payload.data (), payload.size (), buf, m->maxLen))
|
if (!NewOutgoingSessionMessage (payload.data (), payload.size (), buf, m->maxLen))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
len += 96;
|
len += 96;
|
||||||
break;
|
break;
|
||||||
case eSessionStateNewSessionReceived:
|
case eSessionStateNewSessionReceived:
|
||||||
if (!NewSessionReplyMessage (payload.data (), payload.size (), buf, m->maxLen))
|
if (!NewSessionReplyMessage (payload.data (), payload.size (), buf, m->maxLen))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
len += 72;
|
len += 72;
|
||||||
break;
|
break;
|
||||||
case eSessionStateNewSessionReplySent:
|
case eSessionStateNewSessionReplySent:
|
||||||
if (!NextNewSessionReplyMessage (payload.data (), payload.size (), buf, m->maxLen))
|
if (!NextNewSessionReplyMessage (payload.data (), payload.size (), buf, m->maxLen))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
len += 72;
|
len += 72;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
htobe32buf (m->GetPayload (), len);
|
htobe32buf (m->GetPayload (), len);
|
||||||
m->len += len + 4;
|
m->len += len + 4;
|
||||||
m->FillI2NPMessageHeader (eI2NPGarlic);
|
m->FillI2NPMessageHeader (eI2NPGarlic);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint8_t> ECIESX25519AEADRatchetSession::CreatePayload (std::shared_ptr<const I2NPMessage> msg, bool first)
|
std::vector<uint8_t> ECIESX25519AEADRatchetSession::CreatePayload (std::shared_ptr<const I2NPMessage> msg, bool first)
|
||||||
{
|
{
|
||||||
uint64_t ts = i2p::util::GetMillisecondsSinceEpoch ();
|
uint64_t ts = i2p::util::GetMillisecondsSinceEpoch ();
|
||||||
size_t payloadLen = 0;
|
size_t payloadLen = 0;
|
||||||
if (first) payloadLen += 7;// datatime
|
if (first) payloadLen += 7;// datatime
|
||||||
if (msg && m_Destination)
|
if (msg && m_Destination)
|
||||||
payloadLen += msg->GetPayloadLength () + 13 + 32;
|
payloadLen += msg->GetPayloadLength () + 13 + 32;
|
||||||
auto leaseSet = (GetLeaseSetUpdateStatus () == eLeaseSetUpdated ||
|
auto leaseSet = (GetLeaseSetUpdateStatus () == eLeaseSetUpdated ||
|
||||||
(GetLeaseSetUpdateStatus () == eLeaseSetSubmitted &&
|
(GetLeaseSetUpdateStatus () == eLeaseSetSubmitted &&
|
||||||
ts > GetLeaseSetSubmissionTime () + LEASET_CONFIRMATION_TIMEOUT)) ?
|
ts > GetLeaseSetSubmissionTime () + LEASET_CONFIRMATION_TIMEOUT)) ?
|
||||||
GetOwner ()->GetLeaseSet () : nullptr;
|
GetOwner ()->GetLeaseSet () : nullptr;
|
||||||
if (leaseSet)
|
if (leaseSet)
|
||||||
{
|
{
|
||||||
payloadLen += leaseSet->GetBufferLen () + DATABASE_STORE_HEADER_SIZE + 13;
|
payloadLen += leaseSet->GetBufferLen () + DATABASE_STORE_HEADER_SIZE + 13;
|
||||||
if (!first)
|
if (!first)
|
||||||
{
|
{
|
||||||
// ack request
|
// ack request
|
||||||
|
@ -730,19 +730,19 @@ namespace garlic
|
||||||
payloadLen += paddingSize + 3;
|
payloadLen += paddingSize + 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::vector<uint8_t> v(payloadLen);
|
std::vector<uint8_t> v(payloadLen);
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
// DateTime
|
// DateTime
|
||||||
if (first)
|
if (first)
|
||||||
{
|
{
|
||||||
v[offset] = eECIESx25519BlkDateTime; offset++;
|
v[offset] = eECIESx25519BlkDateTime; offset++;
|
||||||
htobe16buf (v.data () + offset, 4); offset += 2;
|
htobe16buf (v.data () + offset, 4); offset += 2;
|
||||||
htobe32buf (v.data () + offset, ts/1000); offset += 4; // in seconds
|
htobe32buf (v.data () + offset, ts/1000); offset += 4; // in seconds
|
||||||
}
|
}
|
||||||
// LeaseSet
|
// LeaseSet
|
||||||
if (leaseSet)
|
if (leaseSet)
|
||||||
{
|
{
|
||||||
offset += CreateLeaseSetClove (leaseSet, ts, v.data () + offset, payloadLen - offset);
|
offset += CreateLeaseSetClove (leaseSet, ts, v.data () + offset, payloadLen - offset);
|
||||||
if (!first)
|
if (!first)
|
||||||
{
|
{
|
||||||
// ack request
|
// ack request
|
||||||
|
@ -752,13 +752,13 @@ namespace garlic
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// msg
|
// msg
|
||||||
if (msg && m_Destination)
|
if (msg && m_Destination)
|
||||||
offset += CreateGarlicClove (msg, v.data () + offset, payloadLen - offset, true);
|
offset += CreateGarlicClove (msg, v.data () + offset, payloadLen - offset, true);
|
||||||
// ack
|
// ack
|
||||||
if (m_AckRequests.size () > 0)
|
if (m_AckRequests.size () > 0)
|
||||||
{
|
{
|
||||||
v[offset] = eECIESx25519BlkAck; offset++;
|
v[offset] = eECIESx25519BlkAck; offset++;
|
||||||
htobe16buf (v.data () + offset, m_AckRequests.size ()*4); offset += 2;
|
htobe16buf (v.data () + offset, m_AckRequests.size () * 4); offset += 2;
|
||||||
for (auto& it: m_AckRequests)
|
for (auto& it: m_AckRequests)
|
||||||
{
|
{
|
||||||
htobe16buf (v.data () + offset, it.first); offset += 2;
|
htobe16buf (v.data () + offset, it.first); offset += 2;
|
||||||
|
@ -801,24 +801,24 @@ namespace garlic
|
||||||
offset += 32; // public key
|
offset += 32; // public key
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// padding
|
// padding
|
||||||
if (paddingSize)
|
if (paddingSize)
|
||||||
{
|
{
|
||||||
v[offset] = eECIESx25519BlkPadding; offset++;
|
v[offset] = eECIESx25519BlkPadding; offset++;
|
||||||
htobe16buf (v.data () + offset, paddingSize); offset += 2;
|
htobe16buf (v.data () + offset, paddingSize); offset += 2;
|
||||||
memset (v.data () + offset, 0, paddingSize); offset += paddingSize;
|
memset (v.data () + offset, 0, paddingSize); offset += paddingSize;
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ECIESX25519AEADRatchetSession::CreateGarlicClove (std::shared_ptr<const I2NPMessage> msg, uint8_t * buf, size_t len, bool isDestination)
|
size_t ECIESX25519AEADRatchetSession::CreateGarlicClove (std::shared_ptr<const I2NPMessage> msg, uint8_t * buf, size_t len, bool isDestination)
|
||||||
{
|
{
|
||||||
if (!msg) return 0;
|
if (!msg) return 0;
|
||||||
uint16_t cloveSize = msg->GetPayloadLength () + 9 + 1;
|
uint16_t cloveSize = msg->GetPayloadLength () + 9 + 1;
|
||||||
if (isDestination) cloveSize += 32;
|
if (isDestination) cloveSize += 32;
|
||||||
if ((int)len < cloveSize + 3) return 0;
|
if ((int)len < cloveSize + 3) return 0;
|
||||||
buf[0] = eECIESx25519BlkGalicClove; // clove type
|
buf[0] = eECIESx25519BlkGalicClove; // clove type
|
||||||
htobe16buf (buf + 1, cloveSize); // size
|
htobe16buf (buf + 1, cloveSize); // size
|
||||||
buf += 3;
|
buf += 3;
|
||||||
if (isDestination)
|
if (isDestination)
|
||||||
{
|
{
|
||||||
|
@ -828,15 +828,15 @@ namespace garlic
|
||||||
else
|
else
|
||||||
*buf = 0;
|
*buf = 0;
|
||||||
buf++; // flag and delivery instructions
|
buf++; // flag and delivery instructions
|
||||||
*buf = msg->GetTypeID (); // I2NP msg type
|
*buf = msg->GetTypeID (); // I2NP msg type
|
||||||
htobe32buf (buf + 1, msg->GetMsgID ()); // msgID
|
htobe32buf (buf + 1, msg->GetMsgID ()); // msgID
|
||||||
htobe32buf (buf + 5, msg->GetExpiration ()/1000); // expiration in seconds
|
htobe32buf (buf + 5, msg->GetExpiration () / 1000); // expiration in seconds
|
||||||
memcpy (buf + 9, msg->GetPayload (), msg->GetPayloadLength ());
|
memcpy (buf + 9, msg->GetPayload (), msg->GetPayloadLength ());
|
||||||
return cloveSize + 3;
|
return cloveSize + 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ECIESX25519AEADRatchetSession::CreateLeaseSetClove (std::shared_ptr<const i2p::data::LocalLeaseSet> ls, uint64_t ts, uint8_t * buf, size_t len)
|
size_t ECIESX25519AEADRatchetSession::CreateLeaseSetClove (std::shared_ptr<const i2p::data::LocalLeaseSet> ls, uint64_t ts, uint8_t * buf, size_t len)
|
||||||
{
|
{
|
||||||
if (!ls || ls->GetStoreType () != i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2)
|
if (!ls || ls->GetStoreType () != i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "Garlic: Incorrect LeasetSet type to send");
|
LogPrint (eLogError, "Garlic: Incorrect LeasetSet type to send");
|
||||||
|
@ -845,7 +845,7 @@ namespace garlic
|
||||||
uint16_t cloveSize = 1 + 9 + DATABASE_STORE_HEADER_SIZE + ls->GetBufferLen (); // to local
|
uint16_t cloveSize = 1 + 9 + DATABASE_STORE_HEADER_SIZE + ls->GetBufferLen (); // to local
|
||||||
if ((int)len < cloveSize + 3) return 0;
|
if ((int)len < cloveSize + 3) return 0;
|
||||||
buf[0] = eECIESx25519BlkGalicClove; // clove type
|
buf[0] = eECIESx25519BlkGalicClove; // clove type
|
||||||
htobe16buf (buf + 1, cloveSize); // size
|
htobe16buf (buf + 1, cloveSize); // size
|
||||||
buf += 3;
|
buf += 3;
|
||||||
*buf = 0; buf++; // flag and delivery instructions
|
*buf = 0; buf++; // flag and delivery instructions
|
||||||
*buf = eI2NPDatabaseStore; buf++; // I2NP msg type
|
*buf = eI2NPDatabaseStore; buf++; // I2NP msg type
|
||||||
|
@ -885,14 +885,14 @@ namespace garlic
|
||||||
auto payload = buf + offset;
|
auto payload = buf + offset;
|
||||||
uint16_t cloveSize = msg->GetPayloadLength () + 9 + 1;
|
uint16_t cloveSize = msg->GetPayloadLength () + 9 + 1;
|
||||||
size_t len = cloveSize + 3;
|
size_t len = cloveSize + 3;
|
||||||
payload[0] = eECIESx25519BlkGalicClove; // clove type
|
payload[0] = eECIESx25519BlkGalicClove; // clove type
|
||||||
htobe16buf (payload + 1, cloveSize); // size
|
htobe16buf (payload + 1, cloveSize); // size
|
||||||
payload += 3;
|
payload += 3;
|
||||||
*payload = 0; payload++; // flag and delivery instructions
|
*payload = 0; payload++; // flag and delivery instructions
|
||||||
*payload = msg->GetTypeID (); // I2NP msg type
|
*payload = msg->GetTypeID (); // I2NP msg type
|
||||||
htobe32buf (payload + 1, msg->GetMsgID ()); // msgID
|
htobe32buf (payload + 1, msg->GetMsgID ()); // msgID
|
||||||
htobe32buf (payload + 5, msg->GetExpiration ()/1000); // expiration in seconds
|
htobe32buf (payload + 5, msg->GetExpiration () / 1000); // expiration in seconds
|
||||||
memcpy (payload + 9, msg->GetPayload (), msg->GetPayloadLength ());
|
memcpy (payload + 9, msg->GetPayload (), msg->GetPayloadLength ());
|
||||||
|
|
||||||
if (!i2p::crypto::AEADChaCha20Poly1305 (buf + offset, len, buf, 8, key, nonce, buf + offset, len + 16, true)) // encrypt
|
if (!i2p::crypto::AEADChaCha20Poly1305 (buf + offset, len, buf, 8, key, nonce, buf + offset, len + 16, true)) // encrypt
|
||||||
{
|
{
|
||||||
|
@ -909,5 +909,3 @@ namespace garlic
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,19 +26,19 @@ namespace garlic
|
||||||
const int ECIESX25519_MAX_NUM_GENERATED_TAGS = 160;
|
const int ECIESX25519_MAX_NUM_GENERATED_TAGS = 160;
|
||||||
const int ECIESX25519_NSR_NUM_GENERATED_TAGS = 12;
|
const int ECIESX25519_NSR_NUM_GENERATED_TAGS = 12;
|
||||||
|
|
||||||
const size_t ECIESX25519_OPTIMAL_PAYLOAD_SIZE = 1912; // 1912 = 1956 /* to fit 2 tunnel messages */
|
const size_t ECIESX25519_OPTIMAL_PAYLOAD_SIZE = 1912; // 1912 = 1956 /* to fit 2 tunnel messages */
|
||||||
// - 16 /* I2NP header */ - 16 /* poly hash */ - 8 /* tag */ - 4 /* garlic length */
|
// - 16 /* I2NP header */ - 16 /* poly hash */ - 8 /* tag */ - 4 /* garlic length */
|
||||||
|
|
||||||
class ECIESX25519AEADRatchetSession;
|
class ECIESX25519AEADRatchetSession;
|
||||||
class RatchetTagSet
|
class RatchetTagSet
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
RatchetTagSet (std::shared_ptr<ECIESX25519AEADRatchetSession> session): m_Session (session) {};
|
RatchetTagSet (std::shared_ptr<ECIESX25519AEADRatchetSession> session): m_Session (session) {};
|
||||||
|
|
||||||
void DHInitialize (const uint8_t * rootKey, const uint8_t * k);
|
void DHInitialize (const uint8_t * rootKey, const uint8_t * k);
|
||||||
void NextSessionTagRatchet ();
|
void NextSessionTagRatchet ();
|
||||||
uint64_t GetNextSessionTag ();
|
uint64_t GetNextSessionTag ();
|
||||||
const uint8_t * GetNextRootKey () const { return m_NextRootKey; };
|
const uint8_t * GetNextRootKey () const { return m_NextRootKey; };
|
||||||
int GetNextIndex () const { return m_NextIndex; };
|
int GetNextIndex () const { return m_NextIndex; };
|
||||||
void GetSymmKey (int index, uint8_t * key);
|
void GetSymmKey (int index, uint8_t * key);
|
||||||
|
@ -52,51 +52,51 @@ namespace garlic
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
uint64_t ll[8];
|
uint64_t ll[8];
|
||||||
uint8_t buf[64];
|
uint8_t buf[64];
|
||||||
|
|
||||||
const uint8_t * GetSessTagCK () const { return buf; }; // sessTag_chainKey = keydata[0:31]
|
const uint8_t * GetSessTagCK () const { return buf; }; // sessTag_chainKey = keydata[0:31]
|
||||||
const uint8_t * GetSessTagConstant () const { return buf + 32; }; // SESSTAG_CONSTANT = keydata[32:63]
|
const uint8_t * GetSessTagConstant () const { return buf + 32; }; // SESSTAG_CONSTANT = keydata[32:63]
|
||||||
uint64_t GetTag () const { return ll[4]; }; // tag = keydata[32:39]
|
uint64_t GetTag () const { return ll[4]; }; // tag = keydata[32:39]
|
||||||
|
|
||||||
} m_KeyData;
|
} m_KeyData;
|
||||||
uint8_t m_SessTagConstant[32], m_SymmKeyCK[32], m_CurrentSymmKeyCK[64], m_NextRootKey[32];
|
uint8_t m_SessTagConstant[32], m_SymmKeyCK[32], m_CurrentSymmKeyCK[64], m_NextRootKey[32];
|
||||||
int m_NextIndex, m_NextSymmKeyIndex;
|
int m_NextIndex, m_NextSymmKeyIndex;
|
||||||
std::unordered_map<int, i2p::data::Tag<32> > m_ItermediateSymmKeys;
|
std::unordered_map<int, i2p::data::Tag<32> > m_ItermediateSymmKeys;
|
||||||
std::weak_ptr<ECIESX25519AEADRatchetSession> m_Session;
|
std::weak_ptr<ECIESX25519AEADRatchetSession> m_Session;
|
||||||
int m_TagSetID = 0;
|
int m_TagSetID = 0;
|
||||||
uint64_t m_ExpirationTimestamp = 0;
|
uint64_t m_ExpirationTimestamp = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ECIESx25519BlockType
|
enum ECIESx25519BlockType
|
||||||
{
|
{
|
||||||
eECIESx25519BlkDateTime = 0,
|
eECIESx25519BlkDateTime = 0,
|
||||||
eECIESx25519BlkSessionID = 1,
|
eECIESx25519BlkSessionID = 1,
|
||||||
eECIESx25519BlkTermination = 4,
|
eECIESx25519BlkTermination = 4,
|
||||||
eECIESx25519BlkOptions = 5,
|
eECIESx25519BlkOptions = 5,
|
||||||
eECIESx25519BlkNextKey = 7,
|
eECIESx25519BlkNextKey = 7,
|
||||||
eECIESx25519BlkAck = 8,
|
eECIESx25519BlkAck = 8,
|
||||||
eECIESx25519BlkAckRequest = 9,
|
eECIESx25519BlkAckRequest = 9,
|
||||||
eECIESx25519BlkGalicClove = 11,
|
eECIESx25519BlkGalicClove = 11,
|
||||||
eECIESx25519BlkPadding = 254
|
eECIESx25519BlkPadding = 254
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG = 0x01;
|
const uint8_t ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG = 0x01;
|
||||||
const uint8_t ECIESX25519_NEXT_KEY_REVERSE_KEY_FLAG = 0x02;
|
const uint8_t ECIESX25519_NEXT_KEY_REVERSE_KEY_FLAG = 0x02;
|
||||||
const uint8_t ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG = 0x04;
|
const uint8_t ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG = 0x04;
|
||||||
|
|
||||||
class ECIESX25519AEADRatchetSession: public GarlicRoutingSession, public std::enable_shared_from_this<ECIESX25519AEADRatchetSession>
|
class ECIESX25519AEADRatchetSession: public GarlicRoutingSession, public std::enable_shared_from_this<ECIESX25519AEADRatchetSession>
|
||||||
{
|
{
|
||||||
enum SessionState
|
enum SessionState
|
||||||
{
|
{
|
||||||
eSessionStateNew =0,
|
eSessionStateNew = 0,
|
||||||
eSessionStateNewSessionReceived,
|
eSessionStateNewSessionReceived,
|
||||||
eSessionStateNewSessionSent,
|
eSessionStateNewSessionSent,
|
||||||
eSessionStateNewSessionReplySent,
|
eSessionStateNewSessionReplySent,
|
||||||
eSessionStateEstablished
|
eSessionStateEstablished
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DHRatchet
|
struct DHRatchet
|
||||||
{
|
{
|
||||||
|
@ -106,15 +106,15 @@ namespace garlic
|
||||||
bool newKey = true;
|
bool newKey = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSet);
|
ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSet);
|
||||||
~ECIESX25519AEADRatchetSession ();
|
~ECIESX25519AEADRatchetSession ();
|
||||||
|
|
||||||
bool HandleNextMessage (uint8_t * buf, size_t len, std::shared_ptr<RatchetTagSet> receiveTagset, int index = 0);
|
bool HandleNextMessage (uint8_t * buf, size_t len, std::shared_ptr<RatchetTagSet> receiveTagset, int index = 0);
|
||||||
std::shared_ptr<I2NPMessage> WrapSingleMessage (std::shared_ptr<const I2NPMessage> msg);
|
std::shared_ptr<I2NPMessage> WrapSingleMessage (std::shared_ptr<const I2NPMessage> msg);
|
||||||
|
|
||||||
const uint8_t * GetRemoteStaticKey () const { return m_RemoteStaticKey; }
|
const uint8_t * GetRemoteStaticKey () const { return m_RemoteStaticKey; }
|
||||||
void SetRemoteStaticKey (const uint8_t * key) { memcpy (m_RemoteStaticKey, key, 32); }
|
void SetRemoteStaticKey (const uint8_t * key) { memcpy (m_RemoteStaticKey, key, 32); }
|
||||||
|
|
||||||
void SetDestination (const i2p::data::IdentHash& dest) // TODO:
|
void SetDestination (const i2p::data::IdentHash& dest) // TODO:
|
||||||
|
@ -127,41 +127,41 @@ namespace garlic
|
||||||
|
|
||||||
bool IsRatchets () const { return true; };
|
bool IsRatchets () const { return true; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void ResetKeys ();
|
void ResetKeys ();
|
||||||
void MixHash (const uint8_t * buf, size_t len);
|
void MixHash (const uint8_t * buf, size_t len);
|
||||||
void CreateNonce (uint64_t seqn, uint8_t * nonce);
|
void CreateNonce (uint64_t seqn, uint8_t * nonce);
|
||||||
bool GenerateEphemeralKeysAndEncode (uint8_t * buf); // buf is 32 bytes
|
bool GenerateEphemeralKeysAndEncode (uint8_t * buf); // buf is 32 bytes
|
||||||
std::shared_ptr<RatchetTagSet> CreateNewSessionTagset ();
|
std::shared_ptr<RatchetTagSet> CreateNewSessionTagset ();
|
||||||
|
|
||||||
bool HandleNewIncomingSession (const uint8_t * buf, size_t len);
|
bool HandleNewIncomingSession (const uint8_t * buf, size_t len);
|
||||||
bool HandleNewOutgoingSessionReply (uint8_t * buf, size_t len);
|
bool HandleNewOutgoingSessionReply (uint8_t * buf, size_t len);
|
||||||
bool HandleExistingSessionMessage (uint8_t * buf, size_t len, std::shared_ptr<RatchetTagSet> receiveTagset, int index);
|
bool HandleExistingSessionMessage (uint8_t * buf, size_t len, std::shared_ptr<RatchetTagSet> receiveTagset, int index);
|
||||||
void HandlePayload (const uint8_t * buf, size_t len, const std::shared_ptr<RatchetTagSet>& receiveTagset, int index);
|
void HandlePayload (const uint8_t * buf, size_t len, const std::shared_ptr<RatchetTagSet>& receiveTagset, int index);
|
||||||
void HandleNextKey (const uint8_t * buf, size_t len, const std::shared_ptr<RatchetTagSet>& receiveTagset);
|
void HandleNextKey (const uint8_t * buf, size_t len, const std::shared_ptr<RatchetTagSet>& receiveTagset);
|
||||||
|
|
||||||
bool NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen);
|
bool NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen);
|
||||||
bool NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen);
|
bool NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen);
|
||||||
bool NextNewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen);
|
bool NextNewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen);
|
||||||
bool NewExistingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen);
|
bool NewExistingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen);
|
||||||
|
|
||||||
std::vector<uint8_t> CreatePayload (std::shared_ptr<const I2NPMessage> msg, bool first);
|
std::vector<uint8_t> CreatePayload (std::shared_ptr<const I2NPMessage> msg, bool first);
|
||||||
size_t CreateGarlicClove (std::shared_ptr<const I2NPMessage> msg, uint8_t * buf, size_t len, bool isDestination = false);
|
size_t CreateGarlicClove (std::shared_ptr<const I2NPMessage> msg, uint8_t * buf, size_t len, bool isDestination = false);
|
||||||
size_t CreateLeaseSetClove (std::shared_ptr<const i2p::data::LocalLeaseSet> ls, uint64_t ts, uint8_t * buf, size_t len);
|
size_t CreateLeaseSetClove (std::shared_ptr<const i2p::data::LocalLeaseSet> ls, uint64_t ts, uint8_t * buf, size_t len);
|
||||||
|
|
||||||
void GenerateMoreReceiveTags (std::shared_ptr<RatchetTagSet> receiveTagset, int numTags);
|
void GenerateMoreReceiveTags (std::shared_ptr<RatchetTagSet> receiveTagset, int numTags);
|
||||||
void NewNextSendRatchet ();
|
void NewNextSendRatchet ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
uint8_t m_H[32], m_CK[64] /* [chainkey, key] */, m_RemoteStaticKey[32];
|
uint8_t m_H[32], m_CK[64] /* [chainkey, key] */, m_RemoteStaticKey[32];
|
||||||
uint8_t m_Aepk[32]; // Alice's ephemeral keys, for incoming only
|
uint8_t m_Aepk[32]; // Alice's ephemeral keys, for incoming only
|
||||||
uint8_t m_NSREncodedKey[32], m_NSRH[32], m_NSRKey[32]; // new session reply, for incoming only
|
uint8_t m_NSREncodedKey[32], m_NSRH[32], m_NSRKey[32]; // new session reply, for incoming only
|
||||||
i2p::crypto::X25519Keys m_EphemeralKeys;
|
i2p::crypto::X25519Keys m_EphemeralKeys;
|
||||||
SessionState m_State = eSessionStateNew;
|
SessionState m_State = eSessionStateNew;
|
||||||
uint64_t m_LastActivityTimestamp = 0; // incoming
|
uint64_t m_LastActivityTimestamp = 0; // incoming
|
||||||
std::shared_ptr<RatchetTagSet> m_SendTagset, m_NSRTagset;
|
std::shared_ptr<RatchetTagSet> m_SendTagset, m_NSRTagset;
|
||||||
std::unique_ptr<i2p::data::IdentHash> m_Destination;// TODO: might not need it
|
std::unique_ptr<i2p::data::IdentHash> m_Destination;// TODO: might not need it
|
||||||
std::list<std::pair<uint16_t, int> > m_AckRequests; // (tagsetid, index)
|
std::list<std::pair<uint16_t, int> > m_AckRequests; // (tagsetid, index)
|
||||||
bool m_SendReverseKey = false, m_SendForwardKey = false;
|
bool m_SendReverseKey = false, m_SendForwardKey = false;
|
||||||
|
@ -175,7 +175,7 @@ namespace garlic
|
||||||
{
|
{
|
||||||
return m_Destination ? *m_Destination : i2p::data::IdentHash ();
|
return m_Destination ? *m_Destination : i2p::data::IdentHash ();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> WrapECIESX25519AEADRatchetMessage (std::shared_ptr<const I2NPMessage> msg, const uint8_t * key, uint64_t tag);
|
std::shared_ptr<I2NPMessage> WrapECIESX25519AEADRatchetMessage (std::shared_ptr<const I2NPMessage> msg, const uint8_t * key, uint64_t tag);
|
||||||
}
|
}
|
||||||
|
|
|
@ -597,4 +597,3 @@ namespace crypto
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,6 +128,4 @@ namespace crypto
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ namespace crypto
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Elligator2::Encode (const uint8_t * key, uint8_t * encoded, bool highY, bool random) const
|
bool Elligator2::Encode (const uint8_t * key, uint8_t * encoded, bool highY, bool random) const
|
||||||
{
|
{
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
BN_CTX * ctx = BN_CTX_new ();
|
BN_CTX * ctx = BN_CTX_new ();
|
||||||
BN_CTX_start (ctx);
|
BN_CTX_start (ctx);
|
||||||
|
@ -63,11 +63,11 @@ namespace crypto
|
||||||
|
|
||||||
if (Legendre (uxxA, ctx) != -1)
|
if (Legendre (uxxA, ctx) != -1)
|
||||||
{
|
{
|
||||||
uint8_t randByte = 0; // random highest bits and high y
|
uint8_t randByte = 0; // random highest bits and high y
|
||||||
if (random)
|
if (random)
|
||||||
{
|
{
|
||||||
RAND_bytes (&randByte, 1);
|
RAND_bytes (&randByte, 1);
|
||||||
highY = randByte & 0x01;
|
highY = randByte & 0x01;
|
||||||
}
|
}
|
||||||
|
|
||||||
BIGNUM * r = BN_CTX_get (ctx);
|
BIGNUM * r = BN_CTX_get (ctx);
|
||||||
|
@ -87,7 +87,7 @@ namespace crypto
|
||||||
bn2buf (r, encoded, 32);
|
bn2buf (r, encoded, 32);
|
||||||
|
|
||||||
if (random)
|
if (random)
|
||||||
encoded[0] |= (randByte & 0xC0); // copy two highest bits from randByte
|
encoded[0] |= (randByte & 0xC0); // copy two highest bits from randByte
|
||||||
for (size_t i = 0; i < 16; i++) // To Little Endian
|
for (size_t i = 0; i < 16; i++) // To Little Endian
|
||||||
{
|
{
|
||||||
uint8_t tmp = encoded[i];
|
uint8_t tmp = encoded[i];
|
||||||
|
@ -115,7 +115,7 @@ namespace crypto
|
||||||
encoded1[i] = encoded[31 - i];
|
encoded1[i] = encoded[31 - i];
|
||||||
encoded1[31 - i] = encoded[i];
|
encoded1[31 - i] = encoded[i];
|
||||||
}
|
}
|
||||||
encoded1[0] &= 0x3F; // drop two highest bits
|
encoded1[0] &= 0x3F; // drop two highest bits
|
||||||
|
|
||||||
BIGNUM * r = BN_CTX_get (ctx); BN_bin2bn (encoded1, 32, r);
|
BIGNUM * r = BN_CTX_get (ctx); BN_bin2bn (encoded1, 32, r);
|
||||||
|
|
||||||
|
@ -184,7 +184,7 @@ namespace crypto
|
||||||
BN_mod_exp (r, a, p12, p, ctx); // r = a^((p-1)/2) mod p
|
BN_mod_exp (r, a, p12, p, ctx); // r = a^((p-1)/2) mod p
|
||||||
if (BN_is_word(r, 1))
|
if (BN_is_word(r, 1))
|
||||||
return 1;
|
return 1;
|
||||||
else if (BN_is_zero(r))
|
else if (BN_is_zero(r))
|
||||||
return 0;
|
return 0;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -204,4 +204,3 @@ namespace crypto
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,5 +35,3 @@ namespace crypto
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
221
libi2pd/FS.h
221
libi2pd/FS.h
|
@ -17,133 +17,136 @@
|
||||||
|
|
||||||
namespace i2p {
|
namespace i2p {
|
||||||
namespace fs {
|
namespace fs {
|
||||||
extern std::string dirSep;
|
extern std::string dirSep;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Class to work with NetDb & Router profiles
|
* @brief Class to work with NetDb & Router profiles
|
||||||
*
|
*
|
||||||
* Usage:
|
* Usage:
|
||||||
*
|
*
|
||||||
* const char alphabet[8] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
|
* const char alphabet[8] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
|
||||||
* auto h = HashedStorage("name", "y", "z-", ".txt");
|
* auto h = HashedStorage("name", "y", "z-", ".txt");
|
||||||
* h.SetPlace("/tmp/hs-test");
|
* h.SetPlace("/tmp/hs-test");
|
||||||
* h.GetName() -> gives "name"
|
* h.GetName() -> gives "name"
|
||||||
* h.GetRoot() -> gives "/tmp/hs-test/name"
|
* h.GetRoot() -> gives "/tmp/hs-test/name"
|
||||||
* h.Init(alphabet, 8); <- creates needed dirs, 8 is size of alphabet
|
* h.Init(alphabet, 8); <- creates needed dirs, 8 is size of alphabet
|
||||||
* h.Path("abcd"); <- returns /tmp/hs-test/name/ya/z-abcd.txt
|
* h.Path("abcd"); <- returns /tmp/hs-test/name/ya/z-abcd.txt
|
||||||
* h.Remove("abcd"); <- removes /tmp/hs-test/name/ya/z-abcd.txt, if it exists
|
* h.Remove("abcd"); <- removes /tmp/hs-test/name/ya/z-abcd.txt, if it exists
|
||||||
* std::vector<std::string> files;
|
* std::vector<std::string> files;
|
||||||
* h.Traverse(files); <- finds all files in storage and saves in given vector
|
* h.Traverse(files); <- finds all files in storage and saves in given vector
|
||||||
*/
|
*/
|
||||||
class HashedStorage {
|
class HashedStorage
|
||||||
protected:
|
{
|
||||||
std::string root; /**< path to storage with it's name included */
|
protected:
|
||||||
std::string name; /**< name of the storage */
|
|
||||||
std::string prefix1; /**< hashed directory prefix */
|
|
||||||
std::string prefix2; /**< prefix of file in storage */
|
|
||||||
std::string suffix; /**< suffix of file in storage (extension) */
|
|
||||||
|
|
||||||
public:
|
std::string root; /**< path to storage with it's name included */
|
||||||
typedef std::function<void(const std::string &)> FilenameVisitor;
|
std::string name; /**< name of the storage */
|
||||||
HashedStorage(const char *n, const char *p1, const char *p2, const char *s):
|
std::string prefix1; /**< hashed directory prefix */
|
||||||
name(n), prefix1(p1), prefix2(p2), suffix(s) {};
|
std::string prefix2; /**< prefix of file in storage */
|
||||||
|
std::string suffix; /**< suffix of file in storage (extension) */
|
||||||
|
|
||||||
/** create subdirs in storage */
|
public:
|
||||||
bool Init(const char* chars, size_t cnt);
|
|
||||||
const std::string & GetRoot() const { return root; }
|
|
||||||
const std::string & GetName() const { return name; }
|
|
||||||
/** set directory where to place storage directory */
|
|
||||||
void SetPlace(const std::string & path);
|
|
||||||
/** path to file with given ident */
|
|
||||||
std::string Path(const std::string & ident) const;
|
|
||||||
/** remove file by ident */
|
|
||||||
void Remove(const std::string & ident);
|
|
||||||
/** find all files in storage and store list in provided vector */
|
|
||||||
void Traverse(std::vector<std::string> & files);
|
|
||||||
/** visit every file in this storage with a visitor */
|
|
||||||
void Iterate(FilenameVisitor v);
|
|
||||||
};
|
|
||||||
|
|
||||||
/** @brief Returns current application name, default 'i2pd' */
|
typedef std::function<void(const std::string &)> FilenameVisitor;
|
||||||
|
HashedStorage(const char *n, const char *p1, const char *p2, const char *s):
|
||||||
|
name(n), prefix1(p1), prefix2(p2), suffix(s) {};
|
||||||
|
|
||||||
|
/** create subdirs in storage */
|
||||||
|
bool Init(const char* chars, size_t cnt);
|
||||||
|
const std::string & GetRoot() const { return root; }
|
||||||
|
const std::string & GetName() const { return name; }
|
||||||
|
/** set directory where to place storage directory */
|
||||||
|
void SetPlace(const std::string & path);
|
||||||
|
/** path to file with given ident */
|
||||||
|
std::string Path(const std::string & ident) const;
|
||||||
|
/** remove file by ident */
|
||||||
|
void Remove(const std::string & ident);
|
||||||
|
/** find all files in storage and store list in provided vector */
|
||||||
|
void Traverse(std::vector<std::string> & files);
|
||||||
|
/** visit every file in this storage with a visitor */
|
||||||
|
void Iterate(FilenameVisitor v);
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @brief Returns current application name, default 'i2pd' */
|
||||||
const std::string & GetAppName ();
|
const std::string & GetAppName ();
|
||||||
/** @brief Set application name, affects autodetection of datadir */
|
/** @brief Set application name, affects autodetection of datadir */
|
||||||
void SetAppName (const std::string& name);
|
void SetAppName (const std::string& name);
|
||||||
|
|
||||||
/** @brief Returns datadir path */
|
/** @brief Returns datadir path */
|
||||||
const std::string & GetDataDir();
|
const std::string & GetDataDir();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set datadir either from cmdline option or using autodetection
|
* @brief Set datadir either from cmdline option or using autodetection
|
||||||
* @param cmdline_param Value of cmdline parameter --datadir=<something>
|
* @param cmdline_param Value of cmdline parameter --datadir=<something>
|
||||||
* @param isService Value of cmdline parameter --service
|
* @param isService Value of cmdline parameter --service
|
||||||
*
|
*
|
||||||
* Examples of autodetected paths:
|
* Examples of autodetected paths:
|
||||||
*
|
*
|
||||||
* Windows < Vista: C:\Documents and Settings\Username\Application Data\i2pd\
|
* Windows < Vista: C:\Documents and Settings\Username\Application Data\i2pd\
|
||||||
* Windows >= Vista: C:\Users\Username\AppData\Roaming\i2pd\
|
* Windows >= Vista: C:\Users\Username\AppData\Roaming\i2pd\
|
||||||
* Mac: /Library/Application Support/i2pd/ or ~/Library/Application Support/i2pd/
|
* Mac: /Library/Application Support/i2pd/ or ~/Library/Application Support/i2pd/
|
||||||
* Unix: /var/lib/i2pd/ (system=1) >> ~/.i2pd/ or /tmp/i2pd/
|
* Unix: /var/lib/i2pd/ (system=1) >> ~/.i2pd/ or /tmp/i2pd/
|
||||||
*/
|
*/
|
||||||
void DetectDataDir(const std::string & cmdline_datadir, bool isService = false);
|
void DetectDataDir(const std::string & cmdline_datadir, bool isService = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create subdirectories inside datadir
|
* @brief Create subdirectories inside datadir
|
||||||
*/
|
*/
|
||||||
bool Init();
|
bool Init();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get list of files in directory
|
* @brief Get list of files in directory
|
||||||
* @param path Path to directory
|
* @param path Path to directory
|
||||||
* @param files Vector to store found files
|
* @param files Vector to store found files
|
||||||
* @return true on success and false if directory not exists
|
* @return true on success and false if directory not exists
|
||||||
*/
|
*/
|
||||||
bool ReadDir(const std::string & path, std::vector<std::string> & files);
|
bool ReadDir(const std::string & path, std::vector<std::string> & files);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Remove file with given path
|
* @brief Remove file with given path
|
||||||
* @param path Absolute path to file
|
* @param path Absolute path to file
|
||||||
* @return true on success, false if file not exists, throws exception on error
|
* @return true on success, false if file not exists, throws exception on error
|
||||||
*/
|
*/
|
||||||
bool Remove(const std::string & path);
|
bool Remove(const std::string & path);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Check existence of file
|
* @brief Check existence of file
|
||||||
* @param path Absolute path to file
|
* @param path Absolute path to file
|
||||||
* @return true if file exists, false otherwise
|
* @return true if file exists, false otherwise
|
||||||
*/
|
*/
|
||||||
bool Exists(const std::string & path);
|
bool Exists(const std::string & path);
|
||||||
|
|
||||||
uint32_t GetLastUpdateTime (const std::string & path); // seconds since epoch
|
uint32_t GetLastUpdateTime (const std::string & path); // seconds since epoch
|
||||||
|
|
||||||
bool CreateDirectory (const std::string& path);
|
bool CreateDirectory (const std::string& path);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void _ExpandPath(std::stringstream & path, T c) {
|
void _ExpandPath(std::stringstream & path, T c) {
|
||||||
path << i2p::fs::dirSep << c;
|
path << i2p::fs::dirSep << c;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename ... Other>
|
template<typename T, typename ... Other>
|
||||||
void _ExpandPath(std::stringstream & path, T c, Other ... other) {
|
void _ExpandPath(std::stringstream & path, T c, Other ... other) {
|
||||||
_ExpandPath(path, c);
|
_ExpandPath(path, c);
|
||||||
_ExpandPath(path, other ...);
|
_ExpandPath(path, other ...);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get path relative to datadir
|
* @brief Get path relative to datadir
|
||||||
*
|
*
|
||||||
* Examples (with datadir = "/tmp/i2pd"):
|
* Examples (with datadir = "/tmp/i2pd"):
|
||||||
*
|
*
|
||||||
* i2p::fs::Path("test") -> '/tmp/i2pd/test'
|
* i2p::fs::Path("test") -> '/tmp/i2pd/test'
|
||||||
* i2p::fs::Path("test", "file.txt") -> '/tmp/i2pd/test/file.txt'
|
* i2p::fs::Path("test", "file.txt") -> '/tmp/i2pd/test/file.txt'
|
||||||
*/
|
*/
|
||||||
template<typename ... Other>
|
template<typename ... Other>
|
||||||
std::string DataDirPath(Other ... components) {
|
std::string DataDirPath(Other ... components) {
|
||||||
std::stringstream s("");
|
std::stringstream s("");
|
||||||
s << i2p::fs::GetDataDir();
|
s << i2p::fs::GetDataDir();
|
||||||
_ExpandPath(s, components ...);
|
_ExpandPath(s, components ...);
|
||||||
|
|
||||||
return s.str();
|
return s.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Storage, typename... Filename>
|
template<typename Storage, typename... Filename>
|
||||||
std::string StorageRootPath (const Storage& storage, Filename... filenames)
|
std::string StorageRootPath (const Storage& storage, Filename... filenames)
|
||||||
|
|
|
@ -179,4 +179,3 @@ namespace data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,9 +38,9 @@ namespace garlic
|
||||||
if (!m_SharedRoutingPath) return nullptr;
|
if (!m_SharedRoutingPath) return nullptr;
|
||||||
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
||||||
if (m_SharedRoutingPath->numTimesUsed >= ROUTING_PATH_MAX_NUM_TIMES_USED ||
|
if (m_SharedRoutingPath->numTimesUsed >= ROUTING_PATH_MAX_NUM_TIMES_USED ||
|
||||||
!m_SharedRoutingPath->outboundTunnel->IsEstablished () ||
|
!m_SharedRoutingPath->outboundTunnel->IsEstablished () ||
|
||||||
ts*1000LL > m_SharedRoutingPath->remoteLease->endDate ||
|
ts*1000LL > m_SharedRoutingPath->remoteLease->endDate ||
|
||||||
ts > m_SharedRoutingPath->updateTime + ROUTING_PATH_EXPIRATION_TIMEOUT)
|
ts > m_SharedRoutingPath->updateTime + ROUTING_PATH_EXPIRATION_TIMEOUT)
|
||||||
m_SharedRoutingPath = nullptr;
|
m_SharedRoutingPath = nullptr;
|
||||||
if (m_SharedRoutingPath) m_SharedRoutingPath->numTimesUsed++;
|
if (m_SharedRoutingPath) m_SharedRoutingPath->numTimesUsed++;
|
||||||
return m_SharedRoutingPath;
|
return m_SharedRoutingPath;
|
||||||
|
@ -96,10 +96,10 @@ namespace garlic
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
ElGamalAESSession::ElGamalAESSession (GarlicDestination * owner,
|
ElGamalAESSession::ElGamalAESSession (GarlicDestination * owner,
|
||||||
std::shared_ptr<const i2p::data::RoutingDestination> destination, int numTags, bool attachLeaseSet):
|
std::shared_ptr<const i2p::data::RoutingDestination> destination, int numTags, bool attachLeaseSet):
|
||||||
GarlicRoutingSession (owner, attachLeaseSet),
|
GarlicRoutingSession (owner, attachLeaseSet),
|
||||||
m_Destination (destination), m_NumTags (numTags)
|
m_Destination (destination), m_NumTags (numTags)
|
||||||
{
|
{
|
||||||
// create new session tags and session key
|
// create new session tags and session key
|
||||||
RAND_bytes (m_SessionKey, 32);
|
RAND_bytes (m_SessionKey, 32);
|
||||||
|
@ -115,7 +115,7 @@ namespace garlic
|
||||||
m_SessionTags.back ().creationTime = i2p::util::GetSecondsSinceEpoch ();
|
m_SessionTags.back ().creationTime = i2p::util::GetSecondsSinceEpoch ();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> ElGamalAESSession::WrapSingleMessage (std::shared_ptr<const I2NPMessage> msg)
|
std::shared_ptr<I2NPMessage> ElGamalAESSession::WrapSingleMessage (std::shared_ptr<const I2NPMessage> msg)
|
||||||
{
|
{
|
||||||
auto m = NewI2NPMessage ();
|
auto m = NewI2NPMessage ();
|
||||||
m->Align (12); // in order to get buf aligned to 16 (12 + 4)
|
m->Align (12); // in order to get buf aligned to 16 (12 + 4)
|
||||||
|
@ -181,7 +181,7 @@ namespace garlic
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ElGamalAESSession::CreateAESBlock (uint8_t * buf, std::shared_ptr<const I2NPMessage> msg)
|
size_t ElGamalAESSession::CreateAESBlock (uint8_t * buf, std::shared_ptr<const I2NPMessage> msg)
|
||||||
{
|
{
|
||||||
size_t blockSize = 0;
|
size_t blockSize = 0;
|
||||||
bool createNewTags = GetOwner () && m_NumTags && ((int)m_SessionTags.size () <= m_NumTags*2/3);
|
bool createNewTags = GetOwner () && m_NumTags && ((int)m_SessionTags.size () <= m_NumTags*2/3);
|
||||||
|
@ -353,7 +353,7 @@ namespace garlic
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
ElGamalAESSession::UnconfirmedTags * ElGamalAESSession::GenerateSessionTags ()
|
ElGamalAESSession::UnconfirmedTags * ElGamalAESSession::GenerateSessionTags ()
|
||||||
{
|
{
|
||||||
auto tags = new UnconfirmedTags (m_NumTags);
|
auto tags = new UnconfirmedTags (m_NumTags);
|
||||||
tags->tagsCreationTime = i2p::util::GetSecondsSinceEpoch ();
|
tags->tagsCreationTime = i2p::util::GetSecondsSinceEpoch ();
|
||||||
|
@ -525,7 +525,7 @@ namespace garlic
|
||||||
// otherwise ECIESx25519
|
// otherwise ECIESx25519
|
||||||
auto session = std::make_shared<ECIESX25519AEADRatchetSession> (this, false); // incoming
|
auto session = std::make_shared<ECIESX25519AEADRatchetSession> (this, false); // incoming
|
||||||
if (!session->HandleNextMessage (buf, length, nullptr, 0))
|
if (!session->HandleNextMessage (buf, length, nullptr, 0))
|
||||||
LogPrint (eLogError, "Garlic: can't handle ECIES-X25519-AEAD-Ratchet message");
|
LogPrint (eLogError, "Garlic: can't handle ECIES-X25519-AEAD-Ratchet message");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "Garlic: Failed to decrypt message");
|
LogPrint (eLogError, "Garlic: Failed to decrypt message");
|
||||||
|
@ -703,41 +703,41 @@ namespace garlic
|
||||||
std::shared_ptr<GarlicRoutingSession> GarlicDestination::GetRoutingSession (
|
std::shared_ptr<GarlicRoutingSession> GarlicDestination::GetRoutingSession (
|
||||||
std::shared_ptr<const i2p::data::RoutingDestination> destination, bool attachLeaseSet)
|
std::shared_ptr<const i2p::data::RoutingDestination> destination, bool attachLeaseSet)
|
||||||
{
|
{
|
||||||
if (destination->GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET &&
|
if (destination->GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET &&
|
||||||
SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET))
|
SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET))
|
||||||
{
|
{
|
||||||
ECIESX25519AEADRatchetSessionPtr session;
|
ECIESX25519AEADRatchetSessionPtr session;
|
||||||
uint8_t staticKey[32];
|
uint8_t staticKey[32];
|
||||||
destination->Encrypt (nullptr, staticKey, nullptr); // we are supposed to get static key
|
destination->Encrypt (nullptr, staticKey, nullptr); // we are supposed to get static key
|
||||||
auto it = m_ECIESx25519Sessions.find (staticKey);
|
auto it = m_ECIESx25519Sessions.find (staticKey);
|
||||||
if (it != m_ECIESx25519Sessions.end ())
|
if (it != m_ECIESx25519Sessions.end ())
|
||||||
session = it->second;
|
session = it->second;
|
||||||
if (!session)
|
if (!session)
|
||||||
{
|
{
|
||||||
session = std::make_shared<ECIESX25519AEADRatchetSession> (this, true);
|
session = std::make_shared<ECIESX25519AEADRatchetSession> (this, true);
|
||||||
session->SetRemoteStaticKey (staticKey);
|
session->SetRemoteStaticKey (staticKey);
|
||||||
}
|
}
|
||||||
session->SetDestination (destination->GetIdentHash ()); // TODO: remove
|
session->SetDestination (destination->GetIdentHash ()); // TODO: remove
|
||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ElGamalAESSessionPtr session;
|
ElGamalAESSessionPtr session;
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(m_SessionsMutex);
|
std::unique_lock<std::mutex> l(m_SessionsMutex);
|
||||||
auto it = m_Sessions.find (destination->GetIdentHash ());
|
auto it = m_Sessions.find (destination->GetIdentHash ());
|
||||||
if (it != m_Sessions.end ())
|
if (it != m_Sessions.end ())
|
||||||
session = it->second;
|
session = it->second;
|
||||||
}
|
}
|
||||||
if (!session)
|
if (!session)
|
||||||
{
|
{
|
||||||
session = std::make_shared<ElGamalAESSession> (this, destination,
|
session = std::make_shared<ElGamalAESSession> (this, destination,
|
||||||
attachLeaseSet ? m_NumTags : 4, attachLeaseSet); // specified num tags for connections and 4 for LS requests
|
attachLeaseSet ? m_NumTags : 4, attachLeaseSet); // specified num tags for connections and 4 for LS requests
|
||||||
std::unique_lock<std::mutex> l(m_SessionsMutex);
|
std::unique_lock<std::mutex> l(m_SessionsMutex);
|
||||||
m_Sessions[destination->GetIdentHash ()] = session;
|
m_Sessions[destination->GetIdentHash ()] = session;
|
||||||
}
|
}
|
||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GarlicDestination::CleanupExpiredTags ()
|
void GarlicDestination::CleanupExpiredTags ()
|
||||||
|
@ -925,20 +925,20 @@ namespace garlic
|
||||||
std::vector<std::string> files;
|
std::vector<std::string> files;
|
||||||
i2p::fs::ReadDir (i2p::fs::DataDirPath("tags"), files);
|
i2p::fs::ReadDir (i2p::fs::DataDirPath("tags"), files);
|
||||||
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
||||||
for (auto it: files)
|
for (auto it: files)
|
||||||
if (ts >= i2p::fs::GetLastUpdateTime (it) + INCOMING_TAGS_EXPIRATION_TIMEOUT)
|
if (ts >= i2p::fs::GetLastUpdateTime (it) + INCOMING_TAGS_EXPIRATION_TIMEOUT)
|
||||||
i2p::fs::Remove (it);
|
i2p::fs::Remove (it);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GarlicDestination::HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len)
|
void GarlicDestination::HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len)
|
||||||
{
|
{
|
||||||
const uint8_t * buf1 = buf;
|
const uint8_t * buf1 = buf;
|
||||||
uint8_t flag = buf[0]; buf++; // flag
|
uint8_t flag = buf[0]; buf++; // flag
|
||||||
GarlicDeliveryType deliveryType = (GarlicDeliveryType)((flag >> 5) & 0x03);
|
GarlicDeliveryType deliveryType = (GarlicDeliveryType)((flag >> 5) & 0x03);
|
||||||
switch (deliveryType)
|
switch (deliveryType)
|
||||||
{
|
{
|
||||||
case eGarlicDeliveryTypeDestination:
|
case eGarlicDeliveryTypeDestination:
|
||||||
LogPrint (eLogDebug, "Garlic: type destination");
|
LogPrint (eLogDebug, "Garlic: type destination");
|
||||||
buf += 32; // TODO: check destination
|
buf += 32; // TODO: check destination
|
||||||
#if (__cplusplus >= 201703L) // C++ 17 or higher
|
#if (__cplusplus >= 201703L) // C++ 17 or higher
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
|
@ -946,7 +946,7 @@ namespace garlic
|
||||||
// no break here
|
// no break here
|
||||||
case eGarlicDeliveryTypeLocal:
|
case eGarlicDeliveryTypeLocal:
|
||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "Garlic: type local");
|
LogPrint (eLogDebug, "Garlic: type local");
|
||||||
I2NPMessageType typeID = (I2NPMessageType)(buf[0]); buf++; // typeid
|
I2NPMessageType typeID = (I2NPMessageType)(buf[0]); buf++; // typeid
|
||||||
buf += (4 + 4); // msgID + expiration
|
buf += (4 + 4); // msgID + expiration
|
||||||
ptrdiff_t offset = buf - buf1;
|
ptrdiff_t offset = buf - buf1;
|
||||||
|
@ -957,8 +957,8 @@ namespace garlic
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case eGarlicDeliveryTypeTunnel:
|
case eGarlicDeliveryTypeTunnel:
|
||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "Garlic: type tunnel");
|
LogPrint (eLogDebug, "Garlic: type tunnel");
|
||||||
// gwHash and gwTunnel sequence is reverted
|
// gwHash and gwTunnel sequence is reverted
|
||||||
const uint8_t * gwHash = buf;
|
const uint8_t * gwHash = buf;
|
||||||
buf += 32;
|
buf += 32;
|
||||||
|
@ -969,32 +969,32 @@ namespace garlic
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
uint32_t gwTunnel = bufbe32toh (buf); buf += 4;
|
uint32_t gwTunnel = bufbe32toh (buf); buf += 4;
|
||||||
I2NPMessageType typeID = (I2NPMessageType)(buf[0]); buf++; // typeid
|
I2NPMessageType typeID = (I2NPMessageType)(buf[0]); buf++; // typeid
|
||||||
buf += (4 + 4); // msgID + expiration
|
buf += (4 + 4); // msgID + expiration
|
||||||
offset += 13;
|
offset += 13;
|
||||||
if (GetTunnelPool ())
|
if (GetTunnelPool ())
|
||||||
{
|
{
|
||||||
auto tunnel = GetTunnelPool ()->GetNextOutboundTunnel ();
|
auto tunnel = GetTunnelPool ()->GetNextOutboundTunnel ();
|
||||||
if (tunnel)
|
if (tunnel)
|
||||||
tunnel->SendTunnelDataMsg (gwHash, gwTunnel, CreateI2NPMessage (typeID, buf, len - offset));
|
tunnel->SendTunnelDataMsg (gwHash, gwTunnel, CreateI2NPMessage (typeID, buf, len - offset));
|
||||||
else
|
else
|
||||||
LogPrint (eLogWarning, "Garlic: No outbound tunnels available for garlic clove");
|
LogPrint (eLogWarning, "Garlic: No outbound tunnels available for garlic clove");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "Garlic: Tunnel pool is not set for inbound tunnel");
|
LogPrint (eLogError, "Garlic: Tunnel pool is not set for inbound tunnel");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
LogPrint (eLogWarning, "Garlic: unexpected delivery type ", (int)deliveryType);
|
LogPrint (eLogWarning, "Garlic: unexpected delivery type ", (int)deliveryType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GarlicDestination::AddECIESx25519SessionNextTag (RatchetTagSetPtr tagset)
|
void GarlicDestination::AddECIESx25519SessionNextTag (RatchetTagSetPtr tagset)
|
||||||
{
|
{
|
||||||
auto index = tagset->GetNextIndex ();
|
auto index = tagset->GetNextIndex ();
|
||||||
uint64_t tag = tagset->GetNextSessionTag ();
|
uint64_t tag = tagset->GetNextSessionTag ();
|
||||||
m_ECIESx25519Tags.emplace (tag, ECIESX25519AEADRatchetIndexTagset{index, tagset, i2p::util::GetSecondsSinceEpoch ()});
|
m_ECIESx25519Tags.emplace (tag, ECIESX25519AEADRatchetIndexTagset{index, tagset, i2p::util::GetSecondsSinceEpoch ()});
|
||||||
}
|
}
|
||||||
|
|
||||||
void GarlicDestination::AddECIESx25519Session (const uint8_t * staticKey, ECIESX25519AEADRatchetSessionPtr session)
|
void GarlicDestination::AddECIESx25519Session (const uint8_t * staticKey, ECIESX25519AEADRatchetSessionPtr session)
|
||||||
{
|
{
|
||||||
|
|
|
@ -87,7 +87,7 @@ namespace garlic
|
||||||
class GarlicDestination;
|
class GarlicDestination;
|
||||||
class GarlicRoutingSession
|
class GarlicRoutingSession
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
enum LeaseSetUpdateStatus
|
enum LeaseSetUpdateStatus
|
||||||
{
|
{
|
||||||
|
@ -103,7 +103,7 @@ namespace garlic
|
||||||
GarlicRoutingSession ();
|
GarlicRoutingSession ();
|
||||||
virtual ~GarlicRoutingSession ();
|
virtual ~GarlicRoutingSession ();
|
||||||
virtual std::shared_ptr<I2NPMessage> WrapSingleMessage (std::shared_ptr<const I2NPMessage> msg) = 0;
|
virtual std::shared_ptr<I2NPMessage> WrapSingleMessage (std::shared_ptr<const I2NPMessage> msg) = 0;
|
||||||
virtual bool CleanupUnconfirmedTags () { return false; }; // for I2CP, override in ElGamalAESSession
|
virtual bool CleanupUnconfirmedTags () { return false; }; // for I2CP, override in ElGamalAESSession
|
||||||
virtual bool MessageConfirmed (uint32_t msgID);
|
virtual bool MessageConfirmed (uint32_t msgID);
|
||||||
virtual bool IsRatchets () const { return false; };
|
virtual bool IsRatchets () const { return false; };
|
||||||
|
|
||||||
|
@ -122,13 +122,13 @@ namespace garlic
|
||||||
GarlicDestination * GetOwner () const { return m_Owner; }
|
GarlicDestination * GetOwner () const { return m_Owner; }
|
||||||
void SetOwner (GarlicDestination * owner) { m_Owner = owner; }
|
void SetOwner (GarlicDestination * owner) { m_Owner = owner; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
LeaseSetUpdateStatus GetLeaseSetUpdateStatus () const { return m_LeaseSetUpdateStatus; }
|
LeaseSetUpdateStatus GetLeaseSetUpdateStatus () const { return m_LeaseSetUpdateStatus; }
|
||||||
void SetLeaseSetUpdateStatus (LeaseSetUpdateStatus status) { m_LeaseSetUpdateStatus = status; }
|
void SetLeaseSetUpdateStatus (LeaseSetUpdateStatus status) { m_LeaseSetUpdateStatus = status; }
|
||||||
uint32_t GetLeaseSetUpdateMsgID () const { return m_LeaseSetUpdateMsgID; }
|
uint32_t GetLeaseSetUpdateMsgID () const { return m_LeaseSetUpdateMsgID; }
|
||||||
void SetLeaseSetUpdateMsgID (uint32_t msgID) { m_LeaseSetUpdateMsgID = msgID; }
|
void SetLeaseSetUpdateMsgID (uint32_t msgID) { m_LeaseSetUpdateMsgID = msgID; }
|
||||||
void SetLeaseSetSubmissionTime (uint64_t ts) { m_LeaseSetSubmissionTime = ts; }
|
void SetLeaseSetSubmissionTime (uint64_t ts) { m_LeaseSetSubmissionTime = ts; }
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> CreateEncryptedDeliveryStatusMsg (uint32_t msgID);
|
std::shared_ptr<I2NPMessage> CreateEncryptedDeliveryStatusMsg (uint32_t msgID);
|
||||||
|
|
||||||
|
@ -143,38 +143,39 @@ namespace garlic
|
||||||
std::shared_ptr<GarlicRoutingPath> m_SharedRoutingPath;
|
std::shared_ptr<GarlicRoutingPath> m_SharedRoutingPath;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// for HTTP only
|
// for HTTP only
|
||||||
virtual size_t GetNumOutgoingTags () const { return 0; };
|
virtual size_t GetNumOutgoingTags () const { return 0; };
|
||||||
};
|
};
|
||||||
//using GarlicRoutingSessionPtr = std::shared_ptr<GarlicRoutingSession>;
|
//using GarlicRoutingSessionPtr = std::shared_ptr<GarlicRoutingSession>;
|
||||||
typedef std::shared_ptr<GarlicRoutingSession> GarlicRoutingSessionPtr; // TODO: replace to using after switch to 4.8
|
typedef std::shared_ptr<GarlicRoutingSession> GarlicRoutingSessionPtr; // TODO: replace to using after switch to 4.8
|
||||||
|
|
||||||
class ElGamalAESSession: public GarlicRoutingSession, public std::enable_shared_from_this<ElGamalAESSession>
|
class ElGamalAESSession: public GarlicRoutingSession, public std::enable_shared_from_this<ElGamalAESSession>
|
||||||
{
|
{
|
||||||
struct UnconfirmedTags
|
struct UnconfirmedTags
|
||||||
{
|
{
|
||||||
UnconfirmedTags (int n): numTags (n), tagsCreationTime (0) { sessionTags = new SessionTag[numTags]; };
|
UnconfirmedTags (int n): numTags (n), tagsCreationTime (0) { sessionTags = new SessionTag[numTags]; };
|
||||||
~UnconfirmedTags () { delete[] sessionTags; };
|
~UnconfirmedTags () { delete[] sessionTags; };
|
||||||
uint32_t msgID;
|
uint32_t msgID;
|
||||||
int numTags;
|
int numTags;
|
||||||
SessionTag * sessionTags;
|
SessionTag * sessionTags;
|
||||||
uint32_t tagsCreationTime;
|
uint32_t tagsCreationTime;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ElGamalAESSession (GarlicDestination * owner, std::shared_ptr<const i2p::data::RoutingDestination> destination,
|
ElGamalAESSession (GarlicDestination * owner, std::shared_ptr<const i2p::data::RoutingDestination> destination,
|
||||||
int numTags, bool attachLeaseSet);
|
int numTags, bool attachLeaseSet);
|
||||||
ElGamalAESSession (const uint8_t * sessionKey, const SessionTag& sessionTag); // one time encryption
|
ElGamalAESSession (const uint8_t * sessionKey, const SessionTag& sessionTag); // one time encryption
|
||||||
~ElGamalAESSession () {};
|
~ElGamalAESSession () {};
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> WrapSingleMessage (std::shared_ptr<const I2NPMessage> msg);
|
std::shared_ptr<I2NPMessage> WrapSingleMessage (std::shared_ptr<const I2NPMessage> msg);
|
||||||
|
|
||||||
bool MessageConfirmed (uint32_t msgID);
|
bool MessageConfirmed (uint32_t msgID);
|
||||||
bool CleanupExpiredTags (); // returns true if something left
|
bool CleanupExpiredTags (); // returns true if something left
|
||||||
bool CleanupUnconfirmedTags (); // returns true if something has been deleted
|
bool CleanupUnconfirmedTags (); // returns true if something has been deleted
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
size_t CreateAESBlock (uint8_t * buf, std::shared_ptr<const I2NPMessage> msg);
|
size_t CreateAESBlock (uint8_t * buf, std::shared_ptr<const I2NPMessage> msg);
|
||||||
size_t CreateGarlicPayload (uint8_t * payload, std::shared_ptr<const I2NPMessage> msg, UnconfirmedTags * newTags);
|
size_t CreateGarlicPayload (uint8_t * payload, std::shared_ptr<const I2NPMessage> msg, UnconfirmedTags * newTags);
|
||||||
|
@ -184,25 +185,26 @@ namespace garlic
|
||||||
void TagsConfirmed (uint32_t msgID);
|
void TagsConfirmed (uint32_t msgID);
|
||||||
UnconfirmedTags * GenerateSessionTags ();
|
UnconfirmedTags * GenerateSessionTags ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::shared_ptr<const i2p::data::RoutingDestination> m_Destination;
|
std::shared_ptr<const i2p::data::RoutingDestination> m_Destination;
|
||||||
|
|
||||||
i2p::crypto::AESKey m_SessionKey;
|
i2p::crypto::AESKey m_SessionKey;
|
||||||
std::list<SessionTag> m_SessionTags;
|
std::list<SessionTag> m_SessionTags;
|
||||||
int m_NumTags;
|
int m_NumTags;
|
||||||
std::map<uint32_t, std::unique_ptr<UnconfirmedTags> > m_UnconfirmedTagsMsgs; // msgID->tags
|
std::map<uint32_t, std::unique_ptr<UnconfirmedTags> > m_UnconfirmedTagsMsgs; // msgID->tags
|
||||||
|
|
||||||
i2p::crypto::CBCEncryption m_Encryption;
|
i2p::crypto::CBCEncryption m_Encryption;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
public:
|
|
||||||
// for HTTP only
|
// for HTTP only
|
||||||
size_t GetNumOutgoingTags () const { return m_SessionTags.size (); };
|
size_t GetNumOutgoingTags () const { return m_SessionTags.size (); };
|
||||||
};
|
};
|
||||||
typedef std::shared_ptr<ElGamalAESSession> ElGamalAESSessionPtr;
|
typedef std::shared_ptr<ElGamalAESSession> ElGamalAESSessionPtr;
|
||||||
|
|
||||||
class ECIESX25519AEADRatchetSession;
|
class ECIESX25519AEADRatchetSession;
|
||||||
typedef std::shared_ptr<ECIESX25519AEADRatchetSession> ECIESX25519AEADRatchetSessionPtr;
|
typedef std::shared_ptr<ECIESX25519AEADRatchetSession> ECIESX25519AEADRatchetSessionPtr;
|
||||||
class RatchetTagSet;
|
class RatchetTagSet;
|
||||||
typedef std::shared_ptr<RatchetTagSet> RatchetTagSetPtr;
|
typedef std::shared_ptr<RatchetTagSet> RatchetTagSetPtr;
|
||||||
struct ECIESX25519AEADRatchetIndexTagset
|
struct ECIESX25519AEADRatchetIndexTagset
|
||||||
|
@ -226,12 +228,12 @@ namespace garlic
|
||||||
void CleanupExpiredTags ();
|
void CleanupExpiredTags ();
|
||||||
void RemoveDeliveryStatusSession (uint32_t msgID);
|
void RemoveDeliveryStatusSession (uint32_t msgID);
|
||||||
std::shared_ptr<I2NPMessage> WrapMessage (std::shared_ptr<const i2p::data::RoutingDestination> destination,
|
std::shared_ptr<I2NPMessage> WrapMessage (std::shared_ptr<const i2p::data::RoutingDestination> destination,
|
||||||
std::shared_ptr<I2NPMessage> msg, bool attachLeaseSet = false);
|
std::shared_ptr<I2NPMessage> msg, bool attachLeaseSet = false);
|
||||||
|
|
||||||
void AddSessionKey (const uint8_t * key, const uint8_t * tag); // one tag
|
void AddSessionKey (const uint8_t * key, const uint8_t * tag); // one tag
|
||||||
virtual bool SubmitSessionKey (const uint8_t * key, const uint8_t * tag); // from different thread
|
virtual bool SubmitSessionKey (const uint8_t * key, const uint8_t * tag); // from different thread
|
||||||
void DeliveryStatusSent (GarlicRoutingSessionPtr session, uint32_t msgID);
|
void DeliveryStatusSent (GarlicRoutingSessionPtr session, uint32_t msgID);
|
||||||
void AddECIESx25519SessionNextTag (RatchetTagSetPtr tagset);
|
void AddECIESx25519SessionNextTag (RatchetTagSetPtr tagset);
|
||||||
void AddECIESx25519Session (const uint8_t * staticKey, ECIESX25519AEADRatchetSessionPtr session);
|
void AddECIESx25519Session (const uint8_t * staticKey, ECIESX25519AEADRatchetSessionPtr session);
|
||||||
void RemoveECIESx25519Session (const uint8_t * staticKey);
|
void RemoveECIESx25519Session (const uint8_t * staticKey);
|
||||||
void HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len);
|
void HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len);
|
||||||
|
@ -266,10 +268,10 @@ namespace garlic
|
||||||
int m_NumTags;
|
int m_NumTags;
|
||||||
std::mutex m_SessionsMutex;
|
std::mutex m_SessionsMutex;
|
||||||
std::unordered_map<i2p::data::IdentHash, ElGamalAESSessionPtr> m_Sessions;
|
std::unordered_map<i2p::data::IdentHash, ElGamalAESSessionPtr> m_Sessions;
|
||||||
std::unordered_map<i2p::data::Tag<32>, ECIESX25519AEADRatchetSessionPtr> m_ECIESx25519Sessions; // static key -> session
|
std::unordered_map<i2p::data::Tag<32>, ECIESX25519AEADRatchetSessionPtr> m_ECIESx25519Sessions; // static key -> session
|
||||||
// incoming
|
// incoming
|
||||||
std::unordered_map<SessionTag, std::shared_ptr<AESDecryption>, std::hash<i2p::data::Tag<32> > > m_Tags;
|
std::unordered_map<SessionTag, std::shared_ptr<AESDecryption>, std::hash<i2p::data::Tag<32> > > m_Tags;
|
||||||
std::unordered_map<uint64_t, ECIESX25519AEADRatchetIndexTagset> m_ECIESx25519Tags; // session tag -> session
|
std::unordered_map<uint64_t, ECIESX25519AEADRatchetIndexTagset> m_ECIESx25519Tags; // session tag -> session
|
||||||
// DeliveryStatus
|
// DeliveryStatus
|
||||||
std::mutex m_DeliveryStatusSessionsMutex;
|
std::mutex m_DeliveryStatusSessionsMutex;
|
||||||
std::unordered_map<uint32_t, GarlicRoutingSessionPtr> m_DeliveryStatusSessions; // msgID -> session
|
std::unordered_map<uint32_t, GarlicRoutingSessionPtr> m_DeliveryStatusSessions; // msgID -> session
|
||||||
|
|
|
@ -13,11 +13,11 @@ namespace crypto
|
||||||
|
|
||||||
enum GOSTR3410ParamSet
|
enum GOSTR3410ParamSet
|
||||||
{
|
{
|
||||||
eGOSTR3410CryptoProA = 0, // 1.2.643.2.2.35.1
|
eGOSTR3410CryptoProA = 0, // 1.2.643.2.2.35.1
|
||||||
// XchA = A, XchB = C
|
// XchA = A, XchB = C
|
||||||
//eGOSTR3410CryptoProXchA, // 1.2.643.2.2.36.0
|
//eGOSTR3410CryptoProXchA, // 1.2.643.2.2.36.0
|
||||||
//eGOSTR3410CryptoProXchB, // 1.2.643.2.2.36.1
|
//eGOSTR3410CryptoProXchB, // 1.2.643.2.2.36.1
|
||||||
eGOSTR3410TC26A512, // 1.2.643.7.1.2.1.2.1
|
eGOSTR3410TC26A512, // 1.2.643.7.1.2.1.2.1
|
||||||
eGOSTR3410NumParamSets
|
eGOSTR3410NumParamSets
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,6 @@ namespace data
|
||||||
|
|
||||||
size_t GzipNoCompression (const uint8_t * in, uint16_t inLen, uint8_t * out, size_t outLen); // for < 64K
|
size_t GzipNoCompression (const uint8_t * in, uint16_t inLen, uint8_t * out, size_t outLen); // for < 64K
|
||||||
size_t GzipNoCompression (const std::vector<std::pair<const uint8_t *, size_t> >& bufs, uint8_t * out, size_t outLen); // for total size < 64K
|
size_t GzipNoCompression (const std::vector<std::pair<const uint8_t *, size_t> >& bufs, uint8_t * out, size_t outLen); // for total size < 64K
|
||||||
|
|
||||||
} // data
|
} // data
|
||||||
} // i2p
|
} // i2p
|
||||||
|
|
||||||
|
|
|
@ -180,7 +180,7 @@ namespace i2p
|
||||||
// excluded
|
// excluded
|
||||||
if (cnt > 512)
|
if (cnt > 512)
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "I2NP: Too many peers to exclude ", cnt, " for DatabaseLookup");
|
LogPrint (eLogWarning, "I2NP: Too many peers to exclude ", cnt, " for DatabaseLookup");
|
||||||
cnt = 0;
|
cnt = 0;
|
||||||
}
|
}
|
||||||
htobe16buf (buf, cnt);
|
htobe16buf (buf, cnt);
|
||||||
|
@ -205,7 +205,7 @@ namespace i2p
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> CreateDatabaseSearchReply (const i2p::data::IdentHash& ident,
|
std::shared_ptr<I2NPMessage> CreateDatabaseSearchReply (const i2p::data::IdentHash& ident,
|
||||||
std::vector<i2p::data::IdentHash> routers)
|
std::vector<i2p::data::IdentHash> routers)
|
||||||
{
|
{
|
||||||
auto m = NewI2NPShortMessage ();
|
auto m = NewI2NPShortMessage ();
|
||||||
uint8_t * buf = m->GetPayload ();
|
uint8_t * buf = m->GetPayload ();
|
||||||
|
@ -268,7 +268,7 @@ namespace i2p
|
||||||
auto m = NewI2NPShortMessage ();
|
auto m = NewI2NPShortMessage ();
|
||||||
uint8_t * payload = m->GetPayload ();
|
uint8_t * payload = m->GetPayload ();
|
||||||
memcpy (payload + DATABASE_STORE_KEY_OFFSET, storeHash, 32);
|
memcpy (payload + DATABASE_STORE_KEY_OFFSET, storeHash, 32);
|
||||||
payload[DATABASE_STORE_TYPE_OFFSET] = leaseSet->GetStoreType (); // 1 for LeaseSet
|
payload[DATABASE_STORE_TYPE_OFFSET] = leaseSet->GetStoreType (); // 1 for LeaseSet
|
||||||
htobe32buf (payload + DATABASE_STORE_REPLY_TOKEN_OFFSET, 0);
|
htobe32buf (payload + DATABASE_STORE_REPLY_TOKEN_OFFSET, 0);
|
||||||
size_t size = DATABASE_STORE_HEADER_SIZE;
|
size_t size = DATABASE_STORE_HEADER_SIZE;
|
||||||
memcpy (payload + size, leaseSet->GetBuffer (), leaseSet->GetBufferLen ());
|
memcpy (payload + size, leaseSet->GetBuffer (), leaseSet->GetBufferLen ());
|
||||||
|
@ -278,7 +278,7 @@ namespace i2p
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> CreateDatabaseStoreMsg (std::shared_ptr<const i2p::data::LocalLeaseSet> leaseSet, uint32_t replyToken, std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel)
|
std::shared_ptr<I2NPMessage> CreateDatabaseStoreMsg (std::shared_ptr<const i2p::data::LocalLeaseSet> leaseSet, uint32_t replyToken, std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel)
|
||||||
{
|
{
|
||||||
if (!leaseSet) return nullptr;
|
if (!leaseSet) return nullptr;
|
||||||
auto m = NewI2NPShortMessage ();
|
auto m = NewI2NPShortMessage ();
|
||||||
|
@ -347,11 +347,11 @@ namespace i2p
|
||||||
auto transitTunnel = i2p::tunnel::CreateTransitTunnel (
|
auto transitTunnel = i2p::tunnel::CreateTransitTunnel (
|
||||||
bufbe32toh (clearText + BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET),
|
bufbe32toh (clearText + BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET),
|
||||||
clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
||||||
bufbe32toh (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET),
|
bufbe32toh (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET),
|
||||||
clearText + BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET,
|
clearText + BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET,
|
||||||
clearText + BUILD_REQUEST_RECORD_IV_KEY_OFFSET,
|
clearText + BUILD_REQUEST_RECORD_IV_KEY_OFFSET,
|
||||||
clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] & 0x80,
|
clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] & 0x80,
|
||||||
clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET ] & 0x40);
|
clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET ] & 0x40);
|
||||||
i2p::tunnel::tunnels.AddTransitTunnel (transitTunnel);
|
i2p::tunnel::tunnels.AddTransitTunnel (transitTunnel);
|
||||||
record[BUILD_RESPONSE_RECORD_RET_OFFSET] = 0;
|
record[BUILD_RESPONSE_RECORD_RET_OFFSET] = 0;
|
||||||
}
|
}
|
||||||
|
@ -386,7 +386,7 @@ namespace i2p
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto tunnel = i2p::tunnel::tunnels.GetPendingInboundTunnel (replyMsgID);
|
auto tunnel = i2p::tunnel::tunnels.GetPendingInboundTunnel (replyMsgID);
|
||||||
if (tunnel)
|
if (tunnel)
|
||||||
{
|
{
|
||||||
// endpoint of inbound tunnel
|
// endpoint of inbound tunnel
|
||||||
|
@ -414,7 +414,7 @@ namespace i2p
|
||||||
transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
||||||
CreateTunnelGatewayMsg (bufbe32toh (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET),
|
CreateTunnelGatewayMsg (bufbe32toh (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET),
|
||||||
eI2NPVariableTunnelBuildReply, buf, len,
|
eI2NPVariableTunnelBuildReply, buf, len,
|
||||||
bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET)));
|
bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
||||||
|
@ -440,7 +440,7 @@ namespace i2p
|
||||||
transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
||||||
CreateTunnelGatewayMsg (bufbe32toh (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET),
|
CreateTunnelGatewayMsg (bufbe32toh (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET),
|
||||||
eI2NPTunnelBuildReply, buf, len,
|
eI2NPTunnelBuildReply, buf, len,
|
||||||
bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET)));
|
bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
||||||
|
@ -592,13 +592,13 @@ namespace i2p
|
||||||
switch (typeID)
|
switch (typeID)
|
||||||
{
|
{
|
||||||
case eI2NPVariableTunnelBuild:
|
case eI2NPVariableTunnelBuild:
|
||||||
HandleVariableTunnelBuildMsg (msgID, buf, size);
|
HandleVariableTunnelBuildMsg (msgID, buf, size);
|
||||||
break;
|
break;
|
||||||
case eI2NPVariableTunnelBuildReply:
|
case eI2NPVariableTunnelBuildReply:
|
||||||
HandleVariableTunnelBuildReplyMsg (msgID, buf, size);
|
HandleVariableTunnelBuildReplyMsg (msgID, buf, size);
|
||||||
break;
|
break;
|
||||||
case eI2NPTunnelBuild:
|
case eI2NPTunnelBuild:
|
||||||
HandleTunnelBuildMsg (buf, size);
|
HandleTunnelBuildMsg (buf, size);
|
||||||
break;
|
break;
|
||||||
case eI2NPTunnelBuildReply:
|
case eI2NPTunnelBuildReply:
|
||||||
// TODO:
|
// TODO:
|
||||||
|
@ -667,7 +667,7 @@ namespace i2p
|
||||||
Flush ();
|
Flush ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2NPMessagesHandler::PutNextMessage (std::shared_ptr<I2NPMessage> msg)
|
void I2NPMessagesHandler::PutNextMessage (std::shared_ptr<I2NPMessage> msg)
|
||||||
{
|
{
|
||||||
if (msg)
|
if (msg)
|
||||||
{
|
{
|
||||||
|
|
|
@ -148,7 +148,7 @@ namespace data
|
||||||
const uint8_t * GetSigningPrivateKey () const { return m_SigningPrivateKey; };
|
const uint8_t * GetSigningPrivateKey () const { return m_SigningPrivateKey; };
|
||||||
size_t GetSignatureLen () const; // might not match identity
|
size_t GetSignatureLen () const; // might not match identity
|
||||||
bool IsOfflineSignature () const { return m_TransientSignatureLen > 0; };
|
bool IsOfflineSignature () const { return m_TransientSignatureLen > 0; };
|
||||||
uint8_t * GetPadding();
|
uint8_t * GetPadding();
|
||||||
void RecalculateIdentHash(uint8_t * buf=nullptr) { m_Public->RecalculateIdentHash(buf); }
|
void RecalculateIdentHash(uint8_t * buf=nullptr) { m_Public->RecalculateIdentHash(buf); }
|
||||||
void Sign (const uint8_t * buf, int len, uint8_t * signature) const;
|
void Sign (const uint8_t * buf, int len, uint8_t * signature) const;
|
||||||
|
|
||||||
|
@ -204,7 +204,7 @@ namespace data
|
||||||
IdentHash CreateRoutingKey (const IdentHash& ident);
|
IdentHash CreateRoutingKey (const IdentHash& ident);
|
||||||
XORMetric operator^(const IdentHash& key1, const IdentHash& key2);
|
XORMetric operator^(const IdentHash& key1, const IdentHash& key2);
|
||||||
|
|
||||||
// destination for delivery instuctions
|
// destination for delivery instructions
|
||||||
class RoutingDestination
|
class RoutingDestination
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -235,5 +235,4 @@ namespace data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -12,7 +12,6 @@ namespace i2p
|
||||||
{
|
{
|
||||||
namespace data
|
namespace data
|
||||||
{
|
{
|
||||||
|
|
||||||
LeaseSet::LeaseSet (bool storeLeases):
|
LeaseSet::LeaseSet (bool storeLeases):
|
||||||
m_IsValid (false), m_StoreLeases (storeLeases), m_ExpirationTime (0), m_EncryptionKey (nullptr),
|
m_IsValid (false), m_StoreLeases (storeLeases), m_ExpirationTime (0), m_EncryptionKey (nullptr),
|
||||||
m_Buffer (nullptr), m_BufferLen (0)
|
m_Buffer (nullptr), m_BufferLen (0)
|
||||||
|
@ -191,10 +190,10 @@ namespace data
|
||||||
return m_ExpirationTime - now <= dlt;
|
return m_ExpirationTime - now <= dlt;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<std::shared_ptr<const Lease> > LeaseSet::GetNonExpiredLeases (bool withThreshold) const
|
const std::vector<std::shared_ptr<const Lease> > LeaseSet::GetNonExpiredLeases (bool withThreshold) const
|
||||||
{
|
{
|
||||||
return GetNonExpiredLeasesExcluding( [] (const Lease & l) -> bool { return false; }, withThreshold);
|
return GetNonExpiredLeasesExcluding( [] (const Lease & l) -> bool { return false; }, withThreshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<std::shared_ptr<const Lease> > LeaseSet::GetNonExpiredLeasesExcluding (LeaseInspectFunc exclude, bool withThreshold) const
|
const std::vector<std::shared_ptr<const Lease> > LeaseSet::GetNonExpiredLeasesExcluding (LeaseInspectFunc exclude, bool withThreshold) const
|
||||||
{
|
{
|
||||||
|
@ -423,7 +422,7 @@ namespace data
|
||||||
if (offset + 40 >= len) return 0;
|
if (offset + 40 >= len) return 0;
|
||||||
offset += 32; // hash
|
offset += 32; // hash
|
||||||
offset += 3; // flags
|
offset += 3; // flags
|
||||||
offset += 1; // cost
|
offset += 1; // cost
|
||||||
offset += 4; // expires
|
offset += 4; // expires
|
||||||
}
|
}
|
||||||
// revocations
|
// revocations
|
||||||
|
@ -771,8 +770,7 @@ namespace data
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalLeaseSet2::LocalLeaseSet2 (uint8_t storeType, const i2p::data::PrivateKeys& keys,
|
LocalLeaseSet2::LocalLeaseSet2 (uint8_t storeType, const i2p::data::PrivateKeys& keys,
|
||||||
const KeySections& encryptionKeys,
|
const KeySections& encryptionKeys, std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> > tunnels,
|
||||||
std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> > tunnels,
|
|
||||||
bool isPublic, bool isPublishedEncrypted):
|
bool isPublic, bool isPublishedEncrypted):
|
||||||
LocalLeaseSet (keys.GetPublic (), nullptr, 0)
|
LocalLeaseSet (keys.GetPublic (), nullptr, 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -48,7 +48,7 @@ namespace data
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::function<bool(const Lease & l)> LeaseInspectFunc;
|
typedef std::function<bool(const Lease & l)> LeaseInspectFunc;
|
||||||
|
|
||||||
const size_t MAX_LS_BUFFER_SIZE = 3072;
|
const size_t MAX_LS_BUFFER_SIZE = 3072;
|
||||||
const size_t LEASE_SIZE = 44; // 32 + 4 + 8
|
const size_t LEASE_SIZE = 44; // 32 + 4 + 8
|
||||||
|
@ -70,7 +70,7 @@ namespace data
|
||||||
size_t GetBufferLen () const { return m_BufferLen; };
|
size_t GetBufferLen () const { return m_BufferLen; };
|
||||||
bool IsValid () const { return m_IsValid; };
|
bool IsValid () const { return m_IsValid; };
|
||||||
const std::vector<std::shared_ptr<const Lease> > GetNonExpiredLeases (bool withThreshold = true) const;
|
const std::vector<std::shared_ptr<const Lease> > GetNonExpiredLeases (bool withThreshold = true) const;
|
||||||
const std::vector<std::shared_ptr<const Lease> > GetNonExpiredLeasesExcluding (LeaseInspectFunc exclude, bool withThreshold = true) const;
|
const std::vector<std::shared_ptr<const Lease> > GetNonExpiredLeasesExcluding (LeaseInspectFunc exclude, bool withThreshold = true) const;
|
||||||
bool HasExpiredLeases () const;
|
bool HasExpiredLeases () const;
|
||||||
bool IsExpired () const;
|
bool IsExpired () const;
|
||||||
bool IsEmpty () const { return m_Leases.empty (); };
|
bool IsEmpty () const { return m_Leases.empty (); };
|
||||||
|
@ -97,7 +97,7 @@ namespace data
|
||||||
// called from LeaseSet2
|
// called from LeaseSet2
|
||||||
LeaseSet (bool storeLeases);
|
LeaseSet (bool storeLeases);
|
||||||
void SetBuffer (const uint8_t * buf, size_t len);
|
void SetBuffer (const uint8_t * buf, size_t len);
|
||||||
void SetBufferLen (size_t len);
|
void SetBufferLen (size_t len);
|
||||||
void SetIdentity (std::shared_ptr<const IdentityEx> identity) { m_Identity = identity; };
|
void SetIdentity (std::shared_ptr<const IdentityEx> identity) { m_Identity = identity; };
|
||||||
void SetExpirationTime (uint64_t t) { m_ExpirationTime = t; };
|
void SetExpirationTime (uint64_t t) { m_ExpirationTime = t; };
|
||||||
void SetIsValid (bool isValid) { m_IsValid = isValid; };
|
void SetIsValid (bool isValid) { m_IsValid = isValid; };
|
||||||
|
@ -245,7 +245,8 @@ namespace data
|
||||||
const KeySections& encryptionKeys,
|
const KeySections& encryptionKeys,
|
||||||
std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> > tunnels,
|
std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> > tunnels,
|
||||||
bool isPublic, bool isPublishedEncrypted = false);
|
bool isPublic, bool isPublishedEncrypted = false);
|
||||||
LocalLeaseSet2 (uint8_t storeType, std::shared_ptr<const IdentityEx> identity, const uint8_t * buf, size_t len); // from I2CP
|
|
||||||
|
LocalLeaseSet2 (uint8_t storeType, std::shared_ptr<const IdentityEx> identity, const uint8_t * buf, size_t len); // from I2CP
|
||||||
|
|
||||||
virtual ~LocalLeaseSet2 () { delete[] m_Buffer; };
|
virtual ~LocalLeaseSet2 () { delete[] m_Buffer; };
|
||||||
|
|
||||||
|
|
|
@ -29,35 +29,35 @@ struct BigEndian;
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct LittleEndian
|
struct LittleEndian
|
||||||
{
|
{
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
unsigned char bytes[sizeof(T)];
|
unsigned char bytes[sizeof(T)];
|
||||||
T raw_value;
|
T raw_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
LittleEndian(T t = T())
|
LittleEndian(T t = T())
|
||||||
{
|
{
|
||||||
operator =(t);
|
operator =(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
LittleEndian(const LittleEndian<T> & t)
|
LittleEndian(const LittleEndian<T> & t)
|
||||||
{
|
{
|
||||||
raw_value = t.raw_value;
|
raw_value = t.raw_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
LittleEndian(const BigEndian<T> & t)
|
LittleEndian(const BigEndian<T> & t)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < sizeof(T); i++)
|
for (unsigned i = 0; i < sizeof(T); i++)
|
||||||
bytes[i] = t.bytes[sizeof(T)-1-i];
|
bytes[i] = t.bytes[sizeof(T)-1-i];
|
||||||
}
|
}
|
||||||
|
|
||||||
operator const T() const
|
operator const T() const
|
||||||
{
|
{
|
||||||
T t = T();
|
T t = T();
|
||||||
for (unsigned i = 0; i < sizeof(T); i++)
|
for (unsigned i = 0; i < sizeof(T); i++)
|
||||||
t |= T(bytes[i]) << (i << 3);
|
t |= T(bytes[i]) << (i << 3);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
const T operator = (const T t)
|
const T operator = (const T t)
|
||||||
{
|
{
|
||||||
|
@ -66,68 +66,68 @@ struct LittleEndian
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
// operators
|
// operators
|
||||||
|
|
||||||
const T operator += (const T t)
|
const T operator += (const T t)
|
||||||
{
|
{
|
||||||
return (*this = *this + t);
|
return (*this = *this + t);
|
||||||
}
|
}
|
||||||
|
|
||||||
const T operator -= (const T t)
|
const T operator -= (const T t)
|
||||||
{
|
{
|
||||||
return (*this = *this - t);
|
return (*this = *this - t);
|
||||||
}
|
}
|
||||||
|
|
||||||
const T operator *= (const T t)
|
const T operator *= (const T t)
|
||||||
{
|
{
|
||||||
return (*this = *this * t);
|
return (*this = *this * t);
|
||||||
}
|
}
|
||||||
|
|
||||||
const T operator /= (const T t)
|
const T operator /= (const T t)
|
||||||
{
|
{
|
||||||
return (*this = *this / t);
|
return (*this = *this / t);
|
||||||
}
|
}
|
||||||
|
|
||||||
const T operator %= (const T t)
|
const T operator %= (const T t)
|
||||||
{
|
{
|
||||||
return (*this = *this % t);
|
return (*this = *this % t);
|
||||||
}
|
}
|
||||||
|
|
||||||
LittleEndian<T> operator ++ (int)
|
LittleEndian<T> operator ++ (int)
|
||||||
{
|
{
|
||||||
LittleEndian<T> tmp(*this);
|
LittleEndian<T> tmp(*this);
|
||||||
operator ++ ();
|
operator ++ ();
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
LittleEndian<T> & operator ++ ()
|
LittleEndian<T> & operator ++ ()
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < sizeof(T); i++)
|
for (unsigned i = 0; i < sizeof(T); i++)
|
||||||
{
|
{
|
||||||
++bytes[i];
|
++bytes[i];
|
||||||
if (bytes[i] != 0)
|
if (bytes[i] != 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return (*this);
|
return (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
LittleEndian<T> operator -- (int)
|
LittleEndian<T> operator -- (int)
|
||||||
{
|
{
|
||||||
LittleEndian<T> tmp(*this);
|
LittleEndian<T> tmp(*this);
|
||||||
operator -- ();
|
operator -- ();
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
LittleEndian<T> & operator -- ()
|
LittleEndian<T> & operator -- ()
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < sizeof(T); i++)
|
for (unsigned i = 0; i < sizeof(T); i++)
|
||||||
{
|
{
|
||||||
--bytes[i];
|
--bytes[i];
|
||||||
if (bytes[i] != (T)(-1))
|
if (bytes[i] != (T)(-1))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return (*this);
|
return (*this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
@ -137,105 +137,105 @@ struct LittleEndian
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct BigEndian
|
struct BigEndian
|
||||||
{
|
{
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
unsigned char bytes[sizeof(T)];
|
unsigned char bytes[sizeof(T)];
|
||||||
T raw_value;
|
T raw_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
BigEndian(T t = T())
|
BigEndian(T t = T())
|
||||||
{
|
{
|
||||||
operator =(t);
|
operator =(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
BigEndian(const BigEndian<T> & t)
|
BigEndian(const BigEndian<T> & t)
|
||||||
{
|
{
|
||||||
raw_value = t.raw_value;
|
raw_value = t.raw_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
BigEndian(const LittleEndian<T> & t)
|
BigEndian(const LittleEndian<T> & t)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < sizeof(T); i++)
|
for (unsigned i = 0; i < sizeof(T); i++)
|
||||||
bytes[i] = t.bytes[sizeof(T)-1-i];
|
bytes[i] = t.bytes[sizeof(T)-1-i];
|
||||||
}
|
}
|
||||||
|
|
||||||
operator const T() const
|
operator const T() const
|
||||||
{
|
{
|
||||||
T t = T();
|
T t = T();
|
||||||
for (unsigned i = 0; i < sizeof(T); i++)
|
for (unsigned i = 0; i < sizeof(T); i++)
|
||||||
t |= T(bytes[sizeof(T) - 1 - i]) << (i << 3);
|
t |= T(bytes[sizeof(T) - 1 - i]) << (i << 3);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
const T operator = (const T t)
|
const T operator = (const T t)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < sizeof(T); i++)
|
for (unsigned i = 0; i < sizeof(T); i++)
|
||||||
bytes[sizeof(T) - 1 - i] = t >> (i << 3);
|
bytes[sizeof(T) - 1 - i] = t >> (i << 3);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
// operators
|
// operators
|
||||||
|
|
||||||
const T operator += (const T t)
|
const T operator += (const T t)
|
||||||
{
|
{
|
||||||
return (*this = *this + t);
|
return (*this = *this + t);
|
||||||
}
|
}
|
||||||
|
|
||||||
const T operator -= (const T t)
|
const T operator -= (const T t)
|
||||||
{
|
{
|
||||||
return (*this = *this - t);
|
return (*this = *this - t);
|
||||||
}
|
}
|
||||||
|
|
||||||
const T operator *= (const T t)
|
const T operator *= (const T t)
|
||||||
{
|
{
|
||||||
return (*this = *this * t);
|
return (*this = *this * t);
|
||||||
}
|
}
|
||||||
|
|
||||||
const T operator /= (const T t)
|
const T operator /= (const T t)
|
||||||
{
|
{
|
||||||
return (*this = *this / t);
|
return (*this = *this / t);
|
||||||
}
|
}
|
||||||
|
|
||||||
const T operator %= (const T t)
|
const T operator %= (const T t)
|
||||||
{
|
{
|
||||||
return (*this = *this % t);
|
return (*this = *this % t);
|
||||||
}
|
}
|
||||||
|
|
||||||
BigEndian<T> operator ++ (int)
|
BigEndian<T> operator ++ (int)
|
||||||
{
|
{
|
||||||
BigEndian<T> tmp(*this);
|
BigEndian<T> tmp(*this);
|
||||||
operator ++ ();
|
operator ++ ();
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
BigEndian<T> & operator ++ ()
|
BigEndian<T> & operator ++ ()
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < sizeof(T); i++)
|
for (unsigned i = 0; i < sizeof(T); i++)
|
||||||
{
|
{
|
||||||
++bytes[sizeof(T) - 1 - i];
|
++bytes[sizeof(T) - 1 - i];
|
||||||
if (bytes[sizeof(T) - 1 - i] != 0)
|
if (bytes[sizeof(T) - 1 - i] != 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return (*this);
|
return (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
BigEndian<T> operator -- (int)
|
BigEndian<T> operator -- (int)
|
||||||
{
|
{
|
||||||
BigEndian<T> tmp(*this);
|
BigEndian<T> tmp(*this);
|
||||||
operator -- ();
|
operator -- ();
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
BigEndian<T> & operator -- ()
|
BigEndian<T> & operator -- ()
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < sizeof(T); i++)
|
for (unsigned i = 0; i < sizeof(T); i++)
|
||||||
{
|
{
|
||||||
--bytes[sizeof(T) - 1 - i];
|
--bytes[sizeof(T) - 1 - i];
|
||||||
if (bytes[sizeof(T) - 1 - i] != (T)(-1))
|
if (bytes[sizeof(T) - 1 - i] != (T)(-1))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return (*this);
|
return (*this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
|
|
@ -110,18 +110,18 @@ namespace log {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string str_tolower(std::string s) {
|
std::string str_tolower(std::string s) {
|
||||||
std::transform(s.begin(), s.end(), s.begin(),
|
std::transform(s.begin(), s.end(), s.begin(),
|
||||||
// static_cast<int(*)(int)>(std::tolower) // wrong
|
// static_cast<int(*)(int)>(std::tolower) // wrong
|
||||||
// [](int c){ return std::tolower(c); } // wrong
|
// [](int c){ return std::tolower(c); } // wrong
|
||||||
// [](char c){ return std::tolower(c); } // wrong
|
// [](char c){ return std::tolower(c); } // wrong
|
||||||
[](unsigned char c){ return std::tolower(c); } // correct
|
[](unsigned char c){ return std::tolower(c); } // correct
|
||||||
);
|
);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Log::SetLogLevel (const std::string& level_) {
|
void Log::SetLogLevel (const std::string& level_) {
|
||||||
std::string level=str_tolower(level_);
|
std::string level=str_tolower(level_);
|
||||||
if (level == "none") { m_MinLevel = eLogNone; }
|
if (level == "none") { m_MinLevel = eLogNone; }
|
||||||
else if (level == "error") { m_MinLevel = eLogError; }
|
else if (level == "error") { m_MinLevel = eLogError; }
|
||||||
else if (level == "warn") { m_MinLevel = eLogWarning; }
|
else if (level == "warn") { m_MinLevel = eLogWarning; }
|
||||||
|
|
|
@ -157,7 +157,7 @@ namespace log {
|
||||||
ThrowFunction GetThrowFunction ();
|
ThrowFunction GetThrowFunction ();
|
||||||
void SetThrowFunction (ThrowFunction f);
|
void SetThrowFunction (ThrowFunction f);
|
||||||
} // log
|
} // log
|
||||||
}
|
} // i2p
|
||||||
|
|
||||||
/** internal usage only -- folding args array to single string */
|
/** internal usage only -- folding args array to single string */
|
||||||
template<typename TValue>
|
template<typename TValue>
|
||||||
|
|
|
@ -114,7 +114,7 @@ namespace transport
|
||||||
|
|
||||||
void NTCP2Establisher::KDF2Bob ()
|
void NTCP2Establisher::KDF2Bob ()
|
||||||
{
|
{
|
||||||
KeyDerivationFunction2 (m_SessionRequestBuffer, m_SessionRequestBufferLen, GetPub ());
|
KeyDerivationFunction2 (m_SessionRequestBuffer, m_SessionRequestBufferLen, GetPub ());
|
||||||
}
|
}
|
||||||
|
|
||||||
void NTCP2Establisher::KDF3Alice ()
|
void NTCP2Establisher::KDF3Alice ()
|
||||||
|
@ -1200,7 +1200,7 @@ namespace transport
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogPrint (eLogInfo, "NTCP2: Start listening v6 TCP port ", address->port);
|
LogPrint (eLogInfo, "NTCP2: Start listening v4 TCP port ", address->port);
|
||||||
auto conn = std::make_shared<NTCP2Session>(*this);
|
auto conn = std::make_shared<NTCP2Session>(*this);
|
||||||
m_NTCP2Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCP2Server::HandleAccept, this, conn, std::placeholders::_1));
|
m_NTCP2Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCP2Server::HandleAccept, this, conn, std::placeholders::_1));
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,7 +126,6 @@ namespace transport
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
NTCP2Session (NTCP2Server& server, std::shared_ptr<const i2p::data::RouterInfo> in_RemoteRouter = nullptr);
|
NTCP2Session (NTCP2Server& server, std::shared_ptr<const i2p::data::RouterInfo> in_RemoteRouter = nullptr);
|
||||||
~NTCP2Session ();
|
~NTCP2Session ();
|
||||||
void Terminate ();
|
void Terminate ();
|
||||||
|
|
|
@ -468,7 +468,7 @@ namespace transport
|
||||||
LogPrint (eLogError, "NTCP: Phase 4 read error: ", ecode.message (), ". Check your clock");
|
LogPrint (eLogError, "NTCP: Phase 4 read error: ", ecode.message (), ". Check your clock");
|
||||||
if (ecode != boost::asio::error::operation_aborted)
|
if (ecode != boost::asio::error::operation_aborted)
|
||||||
{
|
{
|
||||||
// this router doesn't like us
|
// this router doesn't like us
|
||||||
i2p::data::netdb.SetUnreachable (GetRemoteIdentity ()->GetIdentHash (), true);
|
i2p::data::netdb.SetUnreachable (GetRemoteIdentity ()->GetIdentHash (), true);
|
||||||
Terminate ();
|
Terminate ();
|
||||||
}
|
}
|
||||||
|
@ -736,13 +736,11 @@ namespace transport
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void NTCPSession::SendTimeSyncMessage ()
|
void NTCPSession::SendTimeSyncMessage ()
|
||||||
{
|
{
|
||||||
Send (nullptr);
|
Send (nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void NTCPSession::SendI2NPMessages (const std::vector<std::shared_ptr<I2NPMessage> >& msgs)
|
void NTCPSession::SendI2NPMessages (const std::vector<std::shared_ptr<I2NPMessage> >& msgs)
|
||||||
{
|
{
|
||||||
m_Server.GetService ().post (std::bind (&NTCPSession::PostI2NPMessages, shared_from_this (), msgs));
|
m_Server.GetService ().post (std::bind (&NTCPSession::PostI2NPMessages, shared_from_this (), msgs));
|
||||||
|
@ -904,7 +902,6 @@ namespace transport
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void NTCPServer::Run ()
|
void NTCPServer::Run ()
|
||||||
{
|
{
|
||||||
while (m_IsRunning)
|
while (m_IsRunning)
|
||||||
|
|
|
@ -390,7 +390,7 @@ namespace data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Reseeder->Bootstrap ();
|
m_Reseeder->Bootstrap ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetDb::ReseedFromFloodfill(const RouterInfo & ri, int numRouters, int numFloodfills)
|
void NetDb::ReseedFromFloodfill(const RouterInfo & ri, int numRouters, int numFloodfills)
|
||||||
|
@ -537,7 +537,7 @@ namespace data
|
||||||
bool checkForExpiration = total > NETDB_MIN_ROUTERS && uptime > 600; // 10 minutes
|
bool checkForExpiration = total > NETDB_MIN_ROUTERS && uptime > 600; // 10 minutes
|
||||||
if (checkForExpiration && uptime > 3600) // 1 hour
|
if (checkForExpiration && uptime > 3600) // 1 hour
|
||||||
expirationTimeout = i2p::context.IsFloodfill () ? NETDB_FLOODFILL_EXPIRATION_TIMEOUT*1000LL :
|
expirationTimeout = i2p::context.IsFloodfill () ? NETDB_FLOODFILL_EXPIRATION_TIMEOUT*1000LL :
|
||||||
NETDB_MIN_EXPIRATION_TIMEOUT*1000LL + (NETDB_MAX_EXPIRATION_TIMEOUT - NETDB_MIN_EXPIRATION_TIMEOUT)*1000LL*NETDB_MIN_ROUTERS/total;
|
NETDB_MIN_EXPIRATION_TIMEOUT*1000LL + (NETDB_MAX_EXPIRATION_TIMEOUT - NETDB_MIN_EXPIRATION_TIMEOUT)*1000LL*NETDB_MIN_ROUTERS/total;
|
||||||
|
|
||||||
for (auto& it: m_RouterInfos)
|
for (auto& it: m_RouterInfos)
|
||||||
{
|
{
|
||||||
|
@ -555,7 +555,7 @@ namespace data
|
||||||
// find & mark expired routers
|
// find & mark expired routers
|
||||||
if (it.second->UsesIntroducer ())
|
if (it.second->UsesIntroducer ())
|
||||||
{
|
{
|
||||||
if (ts > it.second->GetTimestamp () + NETDB_INTRODUCEE_EXPIRATION_TIMEOUT*1000LL)
|
if (ts > it.second->GetTimestamp () + NETDB_INTRODUCEE_EXPIRATION_TIMEOUT*1000LL)
|
||||||
// RouterInfo expires after 1 hour if uses introducer
|
// RouterInfo expires after 1 hour if uses introducer
|
||||||
it.second->SetUnreachable (true);
|
it.second->SetUnreachable (true);
|
||||||
}
|
}
|
||||||
|
@ -873,7 +873,7 @@ namespace data
|
||||||
std::shared_ptr<I2NPMessage> replyMsg;
|
std::shared_ptr<I2NPMessage> replyMsg;
|
||||||
if (lookupType == DATABASE_LOOKUP_TYPE_EXPLORATORY_LOOKUP)
|
if (lookupType == DATABASE_LOOKUP_TYPE_EXPLORATORY_LOOKUP)
|
||||||
{
|
{
|
||||||
LogPrint (eLogInfo, "NetDb: exploratory close to ", key, " ", numExcluded, " excluded");
|
LogPrint (eLogInfo, "NetDb: exploratory close to ", key, " ", numExcluded, " excluded");
|
||||||
std::set<IdentHash> excludedRouters;
|
std::set<IdentHash> excludedRouters;
|
||||||
for (int i = 0; i < numExcluded; i++)
|
for (int i = 0; i < numExcluded; i++)
|
||||||
{
|
{
|
||||||
|
@ -894,7 +894,7 @@ namespace data
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (lookupType == DATABASE_LOOKUP_TYPE_ROUTERINFO_LOOKUP ||
|
if (lookupType == DATABASE_LOOKUP_TYPE_ROUTERINFO_LOOKUP ||
|
||||||
lookupType == DATABASE_LOOKUP_TYPE_NORMAL_LOOKUP)
|
lookupType == DATABASE_LOOKUP_TYPE_NORMAL_LOOKUP)
|
||||||
{
|
{
|
||||||
auto router = FindRouter (ident);
|
auto router = FindRouter (ident);
|
||||||
|
@ -907,7 +907,7 @@ namespace data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!replyMsg && (lookupType == DATABASE_LOOKUP_TYPE_LEASESET_LOOKUP ||
|
if (!replyMsg && (lookupType == DATABASE_LOOKUP_TYPE_LEASESET_LOOKUP ||
|
||||||
lookupType == DATABASE_LOOKUP_TYPE_NORMAL_LOOKUP))
|
lookupType == DATABASE_LOOKUP_TYPE_NORMAL_LOOKUP))
|
||||||
{
|
{
|
||||||
auto leaseSet = FindLeaseSet (ident);
|
auto leaseSet = FindLeaseSet (ident);
|
||||||
|
|
|
@ -28,12 +28,12 @@ namespace i2p
|
||||||
namespace data
|
namespace data
|
||||||
{
|
{
|
||||||
const int NETDB_MIN_ROUTERS = 90;
|
const int NETDB_MIN_ROUTERS = 90;
|
||||||
const int NETDB_FLOODFILL_EXPIRATION_TIMEOUT = 60*60; // 1 hour, in seconds
|
const int NETDB_FLOODFILL_EXPIRATION_TIMEOUT = 60 * 60; // 1 hour, in seconds
|
||||||
const int NETDB_INTRODUCEE_EXPIRATION_TIMEOUT = 65*60;
|
const int NETDB_INTRODUCEE_EXPIRATION_TIMEOUT = 65 * 60;
|
||||||
const int NETDB_MIN_EXPIRATION_TIMEOUT = 90*60; // 1.5 hours
|
const int NETDB_MIN_EXPIRATION_TIMEOUT = 90 * 60; // 1.5 hours
|
||||||
const int NETDB_MAX_EXPIRATION_TIMEOUT = 27*60*60; // 27 hours
|
const int NETDB_MAX_EXPIRATION_TIMEOUT = 27 * 60 * 60; // 27 hours
|
||||||
const int NETDB_PUBLISH_INTERVAL = 60*40;
|
const int NETDB_PUBLISH_INTERVAL = 60 * 40;
|
||||||
const int NETDB_MIN_HIGHBANDWIDTH_VERSION = MAKE_VERSION_NUMBER(0,9,36); // 0.9.36
|
const int NETDB_MIN_HIGHBANDWIDTH_VERSION = MAKE_VERSION_NUMBER(0, 9, 36); // 0.9.36
|
||||||
|
|
||||||
/** function for visiting a leaseset stored in a floodfill */
|
/** function for visiting a leaseset stored in a floodfill */
|
||||||
typedef std::function<void(const IdentHash, std::shared_ptr<LeaseSet>)> LeaseSetVisitor;
|
typedef std::function<void(const IdentHash, std::shared_ptr<LeaseSet>)> LeaseSetVisitor;
|
||||||
|
@ -63,7 +63,7 @@ namespace data
|
||||||
std::shared_ptr<RouterProfile> FindRouterProfile (const IdentHash& ident) const;
|
std::shared_ptr<RouterProfile> FindRouterProfile (const IdentHash& ident) const;
|
||||||
|
|
||||||
void RequestDestination (const IdentHash& destination, RequestedDestination::RequestComplete requestComplete = nullptr);
|
void RequestDestination (const IdentHash& destination, RequestedDestination::RequestComplete requestComplete = nullptr);
|
||||||
void RequestDestinationFrom (const IdentHash& destination, const IdentHash & from, bool exploritory, RequestedDestination::RequestComplete requestComplete = nullptr);
|
void RequestDestinationFrom (const IdentHash& destination, const IdentHash & from, bool exploritory, RequestedDestination::RequestComplete requestComplete = nullptr);
|
||||||
|
|
||||||
void HandleDatabaseStoreMsg (std::shared_ptr<const I2NPMessage> msg);
|
void HandleDatabaseStoreMsg (std::shared_ptr<const I2NPMessage> msg);
|
||||||
void HandleDatabaseSearchReplyMsg (std::shared_ptr<const I2NPMessage> msg);
|
void HandleDatabaseSearchReplyMsg (std::shared_ptr<const I2NPMessage> msg);
|
||||||
|
@ -80,13 +80,13 @@ namespace data
|
||||||
std::vector<IdentHash> GetClosestFloodfills (const IdentHash& destination, size_t num,
|
std::vector<IdentHash> GetClosestFloodfills (const IdentHash& destination, size_t num,
|
||||||
std::set<IdentHash>& excluded, bool closeThanUsOnly = false) const;
|
std::set<IdentHash>& excluded, bool closeThanUsOnly = false) const;
|
||||||
std::shared_ptr<const RouterInfo> GetClosestNonFloodfill (const IdentHash& destination, const std::set<IdentHash>& excluded) const;
|
std::shared_ptr<const RouterInfo> GetClosestNonFloodfill (const IdentHash& destination, const std::set<IdentHash>& excluded) const;
|
||||||
std::shared_ptr<const RouterInfo> GetRandomRouterInFamily(const std::string & fam) const;
|
std::shared_ptr<const RouterInfo> GetRandomRouterInFamily(const std::string & fam) const;
|
||||||
void SetUnreachable (const IdentHash& ident, bool unreachable);
|
void SetUnreachable (const IdentHash& ident, bool unreachable);
|
||||||
|
|
||||||
void PostI2NPMsg (std::shared_ptr<const I2NPMessage> msg);
|
void PostI2NPMsg (std::shared_ptr<const I2NPMessage> msg);
|
||||||
|
|
||||||
/** set hidden mode, aka don't publish our RI to netdb and don't explore */
|
/** set hidden mode, aka don't publish our RI to netdb and don't explore */
|
||||||
void SetHidden(bool hide);
|
void SetHidden(bool hide);
|
||||||
|
|
||||||
void Reseed ();
|
void Reseed ();
|
||||||
Families& GetFamilies () { return m_Families; };
|
Families& GetFamilies () { return m_Families; };
|
||||||
|
@ -119,12 +119,13 @@ namespace data
|
||||||
void ManageLeaseSets ();
|
void ManageLeaseSets ();
|
||||||
void ManageRequests ();
|
void ManageRequests ();
|
||||||
|
|
||||||
void ReseedFromFloodfill(const RouterInfo & ri, int numRouters=40, int numFloodfills=20);
|
void ReseedFromFloodfill(const RouterInfo & ri, int numRouters = 40, int numFloodfills = 20);
|
||||||
|
|
||||||
std::shared_ptr<const RouterInfo> AddRouterInfo (const uint8_t * buf, int len, bool& updated);
|
std::shared_ptr<const RouterInfo> AddRouterInfo (const uint8_t * buf, int len, bool& updated);
|
||||||
std::shared_ptr<const RouterInfo> AddRouterInfo (const IdentHash& ident, const uint8_t * buf, int len, bool& updated);
|
std::shared_ptr<const RouterInfo> AddRouterInfo (const IdentHash& ident, const uint8_t * buf, int len, bool& updated);
|
||||||
template<typename Filter>
|
|
||||||
std::shared_ptr<const RouterInfo> GetRandomRouter (Filter filter) const;
|
template<typename Filter>
|
||||||
|
std::shared_ptr<const RouterInfo> GetRandomRouter (Filter filter) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -150,12 +151,12 @@ namespace data
|
||||||
|
|
||||||
bool m_PersistProfiles;
|
bool m_PersistProfiles;
|
||||||
|
|
||||||
/** router info we are bootstrapping from or nullptr if we are not currently doing that*/
|
/** router info we are bootstrapping from or nullptr if we are not currently doing that*/
|
||||||
std::shared_ptr<RouterInfo> m_FloodfillBootstrap;
|
std::shared_ptr<RouterInfo> m_FloodfillBootstrap;
|
||||||
|
|
||||||
|
|
||||||
/** true if in hidden mode */
|
/** true if in hidden mode */
|
||||||
bool m_HiddenMode;
|
bool m_HiddenMode;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern NetDb netdb;
|
extern NetDb netdb;
|
||||||
|
|
|
@ -14,8 +14,8 @@ namespace data
|
||||||
std::shared_ptr<I2NPMessage> msg;
|
std::shared_ptr<I2NPMessage> msg;
|
||||||
if(replyTunnel)
|
if(replyTunnel)
|
||||||
msg = i2p::CreateRouterInfoDatabaseLookupMsg (m_Destination,
|
msg = i2p::CreateRouterInfoDatabaseLookupMsg (m_Destination,
|
||||||
replyTunnel->GetNextIdentHash (), replyTunnel->GetNextTunnelID (), m_IsExploratory,
|
replyTunnel->GetNextIdentHash (), replyTunnel->GetNextTunnelID (), m_IsExploratory,
|
||||||
&m_ExcludedPeers);
|
&m_ExcludedPeers);
|
||||||
else
|
else
|
||||||
msg = i2p::CreateRouterInfoDatabaseLookupMsg(m_Destination, i2p::context.GetIdentHash(), 0, m_IsExploratory, &m_ExcludedPeers);
|
msg = i2p::CreateRouterInfoDatabaseLookupMsg(m_Destination, i2p::context.GetIdentHash(), 0, m_IsExploratory, &m_ExcludedPeers);
|
||||||
if(router)
|
if(router)
|
||||||
|
@ -158,4 +158,3 @@ namespace data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,4 +66,3 @@ namespace data
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@ namespace i2p
|
||||||
{
|
{
|
||||||
namespace crypto
|
namespace crypto
|
||||||
{
|
{
|
||||||
|
|
||||||
void Poly1305HMAC(uint64_t * out, const uint64_t * key, const uint8_t * buf, std::size_t sz)
|
void Poly1305HMAC(uint64_t * out, const uint64_t * key, const uint8_t * buf, std::size_t sz)
|
||||||
{
|
{
|
||||||
Poly1305 p(key);
|
Poly1305 p(key);
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
/**
|
/**
|
||||||
This code is licensed under the MCGSI Public License
|
* This code is licensed under the MCGSI Public License
|
||||||
Copyright 2018 Jeff Becker
|
* Copyright 2018 Jeff Becker
|
||||||
|
*
|
||||||
Kovri go write your own code
|
* Kovri go write your own code
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
#ifndef LIBI2PD_POLY1305_H
|
#ifndef LIBI2PD_POLY1305_H
|
||||||
#define LIBI2PD_POLY1305_H
|
#define LIBI2PD_POLY1305_H
|
||||||
|
@ -24,7 +24,6 @@ namespace crypto
|
||||||
|
|
||||||
namespace poly1305
|
namespace poly1305
|
||||||
{
|
{
|
||||||
|
|
||||||
struct LongBlock
|
struct LongBlock
|
||||||
{
|
{
|
||||||
unsigned long data[17];
|
unsigned long data[17];
|
||||||
|
@ -252,8 +251,8 @@ namespace crypto
|
||||||
poly1305::LongBlock m_HR;
|
poly1305::LongBlock m_HR;
|
||||||
uint8_t m_Final;
|
uint8_t m_Final;
|
||||||
};
|
};
|
||||||
|
|
||||||
void Poly1305HMAC(uint64_t * out, const uint64_t * key, const uint8_t * buf, std::size_t sz);
|
void Poly1305HMAC(uint64_t * out, const uint64_t * key, const uint8_t * buf, std::size_t sz);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -32,73 +32,76 @@ namespace data
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief tries to bootstrap into I2P network (from local files and servers, with respect of options)
|
/**
|
||||||
*/
|
@brief tries to bootstrap into I2P network (from local files and servers, with respect of options)
|
||||||
void Reseeder::Bootstrap ()
|
*/
|
||||||
{
|
void Reseeder::Bootstrap ()
|
||||||
std::string su3FileName; i2p::config::GetOption("reseed.file", su3FileName);
|
{
|
||||||
std::string zipFileName; i2p::config::GetOption("reseed.zipfile", zipFileName);
|
std::string su3FileName; i2p::config::GetOption("reseed.file", su3FileName);
|
||||||
|
std::string zipFileName; i2p::config::GetOption("reseed.zipfile", zipFileName);
|
||||||
|
|
||||||
if (su3FileName.length() > 0) // bootstrap from SU3 file or URL
|
if (su3FileName.length() > 0) // bootstrap from SU3 file or URL
|
||||||
{
|
{
|
||||||
int num;
|
int num;
|
||||||
if (su3FileName.length() > 8 && su3FileName.substr(0, 8) == "https://")
|
if (su3FileName.length() > 8 && su3FileName.substr(0, 8) == "https://")
|
||||||
{
|
{
|
||||||
num = ReseedFromSU3Url (su3FileName); // from https URL
|
num = ReseedFromSU3Url (su3FileName); // from https URL
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
num = ProcessSU3File (su3FileName.c_str ());
|
num = ProcessSU3File (su3FileName.c_str ());
|
||||||
}
|
}
|
||||||
if (num == 0)
|
if (num == 0)
|
||||||
LogPrint (eLogWarning, "Reseed: failed to reseed from ", su3FileName);
|
LogPrint (eLogWarning, "Reseed: failed to reseed from ", su3FileName);
|
||||||
}
|
}
|
||||||
else if (zipFileName.length() > 0) // bootstrap from ZIP file
|
else if (zipFileName.length() > 0) // bootstrap from ZIP file
|
||||||
{
|
{
|
||||||
int num = ProcessZIPFile (zipFileName.c_str ());
|
int num = ProcessZIPFile (zipFileName.c_str ());
|
||||||
if (num == 0)
|
if (num == 0)
|
||||||
LogPrint (eLogWarning, "Reseed: failed to reseed from ", zipFileName);
|
LogPrint (eLogWarning, "Reseed: failed to reseed from ", zipFileName);
|
||||||
}
|
}
|
||||||
else // bootstrap from reseed servers
|
else // bootstrap from reseed servers
|
||||||
{
|
{
|
||||||
int num = ReseedFromServers ();
|
int num = ReseedFromServers ();
|
||||||
if (num == 0)
|
if (num == 0)
|
||||||
LogPrint (eLogWarning, "Reseed: failed to reseed from servers");
|
LogPrint (eLogWarning, "Reseed: failed to reseed from servers");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief bootstrap from random server, retry 10 times
|
/**
|
||||||
* @return number of entries added to netDb
|
* @brief bootstrap from random server, retry 10 times
|
||||||
*/
|
* @return number of entries added to netDb
|
||||||
|
*/
|
||||||
int Reseeder::ReseedFromServers ()
|
int Reseeder::ReseedFromServers ()
|
||||||
{
|
{
|
||||||
std::string reseedURLs; i2p::config::GetOption("reseed.urls", reseedURLs);
|
std::string reseedURLs; i2p::config::GetOption("reseed.urls", reseedURLs);
|
||||||
std::vector<std::string> httpsReseedHostList;
|
std::vector<std::string> httpsReseedHostList;
|
||||||
boost::split(httpsReseedHostList, reseedURLs, boost::is_any_of(","), boost::token_compress_on);
|
boost::split(httpsReseedHostList, reseedURLs, boost::is_any_of(","), boost::token_compress_on);
|
||||||
|
|
||||||
if (reseedURLs.length () == 0)
|
if (reseedURLs.length () == 0)
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "Reseed: No reseed servers specified");
|
LogPrint (eLogWarning, "Reseed: No reseed servers specified");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int reseedRetries = 0;
|
int reseedRetries = 0;
|
||||||
while (reseedRetries < 10)
|
while (reseedRetries < 10)
|
||||||
{
|
{
|
||||||
auto ind = rand () % httpsReseedHostList.size ();
|
auto ind = rand () % httpsReseedHostList.size ();
|
||||||
std::string reseedUrl = httpsReseedHostList[ind] + "i2pseeds.su3";
|
std::string reseedUrl = httpsReseedHostList[ind] + "i2pseeds.su3";
|
||||||
auto num = ReseedFromSU3Url (reseedUrl);
|
auto num = ReseedFromSU3Url (reseedUrl);
|
||||||
if (num > 0) return num; // success
|
if (num > 0) return num; // success
|
||||||
reseedRetries++;
|
reseedRetries++;
|
||||||
}
|
}
|
||||||
LogPrint (eLogWarning, "Reseed: failed to reseed from servers after 10 attempts");
|
LogPrint (eLogWarning, "Reseed: failed to reseed from servers after 10 attempts");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief bootstrap from HTTPS URL with SU3 file
|
/**
|
||||||
* @param url
|
* @brief bootstrap from HTTPS URL with SU3 file
|
||||||
* @return number of entries added to netDb
|
* @param url
|
||||||
*/
|
* @return number of entries added to netDb
|
||||||
|
*/
|
||||||
int Reseeder::ReseedFromSU3Url (const std::string& url)
|
int Reseeder::ReseedFromSU3Url (const std::string& url)
|
||||||
{
|
{
|
||||||
LogPrint (eLogInfo, "Reseed: Downloading SU3 from ", url);
|
LogPrint (eLogInfo, "Reseed: Downloading SU3 from ", url);
|
||||||
|
@ -702,4 +705,3 @@ namespace data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace data
|
||||||
|
|
||||||
Reseeder();
|
Reseeder();
|
||||||
~Reseeder();
|
~Reseeder();
|
||||||
void Bootstrap ();
|
void Bootstrap ();
|
||||||
int ReseedFromServers ();
|
int ReseedFromServers ();
|
||||||
int ReseedFromSU3Url (const std::string& url);
|
int ReseedFromSU3Url (const std::string& url);
|
||||||
int ProcessSU3File (const char * filename);
|
int ProcessSU3File (const char * filename);
|
||||||
|
|
|
@ -339,9 +339,9 @@ namespace i2p
|
||||||
case low : /* not set */; break;
|
case low : /* not set */; break;
|
||||||
case extra : caps |= i2p::data::RouterInfo::eExtraBandwidth; break; // 'P'
|
case extra : caps |= i2p::data::RouterInfo::eExtraBandwidth; break; // 'P'
|
||||||
case unlim : caps |= i2p::data::RouterInfo::eExtraBandwidth;
|
case unlim : caps |= i2p::data::RouterInfo::eExtraBandwidth;
|
||||||
#if (__cplusplus >= 201703L) // C++ 17 or higher
|
#if (__cplusplus >= 201703L) // C++ 17 or higher
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
#endif
|
#endif
|
||||||
// no break here, extra + high means 'X'
|
// no break here, extra + high means 'X'
|
||||||
case high : caps |= i2p::data::RouterInfo::eHighBandwidth; break;
|
case high : caps |= i2p::data::RouterInfo::eHighBandwidth; break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,7 +173,6 @@ namespace data
|
||||||
LogPrint (eLogError, "RouterInfo: malformed message");
|
LogPrint (eLogError, "RouterInfo: malformed message");
|
||||||
m_IsUnreachable = true;
|
m_IsUnreachable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterInfo::ReadFromStream (std::istream& s)
|
void RouterInfo::ReadFromStream (std::istream& s)
|
||||||
|
@ -384,9 +383,10 @@ namespace data
|
||||||
SetUnreachable (true);
|
SetUnreachable (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RouterInfo::IsFamily(const std::string & fam) const {
|
bool RouterInfo::IsFamily(const std::string & fam) const
|
||||||
return m_Family == fam;
|
{
|
||||||
}
|
return m_Family == fam;
|
||||||
|
}
|
||||||
|
|
||||||
void RouterInfo::ExtractCaps (const char * value)
|
void RouterInfo::ExtractCaps (const char * value)
|
||||||
{
|
{
|
||||||
|
@ -854,7 +854,7 @@ namespace data
|
||||||
m_SupportedTransports |= eNTCPV6 | eSSUV6 | eNTCP2V6;
|
m_SupportedTransports |= eNTCPV6 | eSSUV6 | eNTCP2V6;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterInfo::EnableV4 ()
|
void RouterInfo::EnableV4 ()
|
||||||
{
|
{
|
||||||
if (!IsV4 ())
|
if (!IsV4 ())
|
||||||
m_SupportedTransports |= eNTCPV4 | eSSUV4 | eNTCP2V4;
|
m_SupportedTransports |= eNTCPV4 | eSSUV4 | eNTCP2V4;
|
||||||
|
@ -877,7 +877,7 @@ namespace data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterInfo::DisableV4 ()
|
void RouterInfo::DisableV4 ()
|
||||||
{
|
{
|
||||||
if (IsV4 ())
|
if (IsV4 ())
|
||||||
{
|
{
|
||||||
|
|
|
@ -203,8 +203,8 @@ namespace data
|
||||||
void DeleteBuffer () { delete[] m_Buffer; m_Buffer = nullptr; };
|
void DeleteBuffer () { delete[] m_Buffer; m_Buffer = nullptr; };
|
||||||
bool IsNewer (const uint8_t * buf, size_t len) const;
|
bool IsNewer (const uint8_t * buf, size_t len) const;
|
||||||
|
|
||||||
/** return true if we are in a router family and the signature is valid */
|
/** return true if we are in a router family and the signature is valid */
|
||||||
bool IsFamily(const std::string & fam) const;
|
bool IsFamily(const std::string & fam) const;
|
||||||
|
|
||||||
// implements RoutingDestination
|
// implements RoutingDestination
|
||||||
std::shared_ptr<const IdentityEx> GetIdentity () const { return m_RouterIdentity; };
|
std::shared_ptr<const IdentityEx> GetIdentity () const { return m_RouterIdentity; };
|
||||||
|
|
|
@ -826,4 +826,3 @@ namespace transport
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ namespace transport
|
||||||
public:
|
public:
|
||||||
|
|
||||||
SSUServer (int port);
|
SSUServer (int port);
|
||||||
SSUServer (const boost::asio::ip::address & addr, int port); // ipv6 only constructor
|
SSUServer (const boost::asio::ip::address & addr, int port); // ipv6 only constructor
|
||||||
~SSUServer ();
|
~SSUServer ();
|
||||||
void Start ();
|
void Start ();
|
||||||
void Stop ();
|
void Stop ();
|
||||||
|
@ -135,4 +135,3 @@ namespace transport
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -496,7 +496,7 @@ namespace transport
|
||||||
}
|
}
|
||||||
// decay
|
// decay
|
||||||
if (m_ReceivedMessages.size () > MAX_NUM_RECEIVED_MESSAGES ||
|
if (m_ReceivedMessages.size () > MAX_NUM_RECEIVED_MESSAGES ||
|
||||||
i2p::util::GetSecondsSinceEpoch () > m_LastMessageReceivedTime + DECAY_INTERVAL)
|
i2p::util::GetSecondsSinceEpoch () > m_LastMessageReceivedTime + DECAY_INTERVAL)
|
||||||
m_ReceivedMessages.clear ();
|
m_ReceivedMessages.clear ();
|
||||||
|
|
||||||
ScheduleIncompleteMessagesCleanup ();
|
ScheduleIncompleteMessagesCleanup ();
|
||||||
|
@ -504,4 +504,3 @@ namespace transport
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,4 +128,3 @@ namespace transport
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -336,7 +336,7 @@ namespace transport
|
||||||
m_SignedData->Insert (payload, 4); // insert Alice's signed on time
|
m_SignedData->Insert (payload, 4); // insert Alice's signed on time
|
||||||
payload += 4; // signed-on time
|
payload += 4; // signed-on time
|
||||||
size_t paddingSize = (payload - buf) + m_RemoteIdentity->GetSignatureLen ();
|
size_t paddingSize = (payload - buf) + m_RemoteIdentity->GetSignatureLen ();
|
||||||
paddingSize &= 0x0F; // %16
|
paddingSize &= 0x0F; // %16
|
||||||
if (paddingSize > 0) paddingSize = 16 - paddingSize;
|
if (paddingSize > 0) paddingSize = 16 - paddingSize;
|
||||||
payload += paddingSize;
|
payload += paddingSize;
|
||||||
// verify signature
|
// verify signature
|
||||||
|
@ -1206,4 +1206,3 @@ namespace transport
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,7 @@ namespace transport
|
||||||
void SendI2NPMessages (const std::vector<std::shared_ptr<I2NPMessage> >& msgs);
|
void SendI2NPMessages (const std::vector<std::shared_ptr<I2NPMessage> >& msgs);
|
||||||
void SendPeerTest (); // Alice
|
void SendPeerTest (); // Alice
|
||||||
|
|
||||||
SessionState GetState () const { return m_State; };
|
SessionState GetState () const { return m_State; };
|
||||||
size_t GetNumSentBytes () const { return m_NumSentBytes; };
|
size_t GetNumSentBytes () const { return m_NumSentBytes; };
|
||||||
size_t GetNumReceivedBytes () const { return m_NumReceivedBytes; };
|
size_t GetNumReceivedBytes () const { return m_NumReceivedBytes; };
|
||||||
|
|
||||||
|
@ -158,10 +158,7 @@ namespace transport
|
||||||
std::unique_ptr<SignedData> m_SignedData; // we need it for SessionConfirmed only
|
std::unique_ptr<SignedData> m_SignedData; // we need it for SessionConfirmed only
|
||||||
std::map<uint32_t, std::shared_ptr<const i2p::data::RouterInfo> > m_RelayRequests; // nonce->Charlie
|
std::map<uint32_t, std::shared_ptr<const i2p::data::RouterInfo> > m_RelayRequests; // nonce->Charlie
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -135,5 +135,3 @@ namespace crypto
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -527,4 +527,3 @@ namespace crypto
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
/**
|
/**
|
||||||
This code is licensed under the MCGSI Public License
|
* This code is licensed under the MCGSI Public License
|
||||||
Copyright 2018 Jeff Becker
|
* Copyright 2018 Jeff Becker
|
||||||
|
*
|
||||||
Kovri go write your own code
|
* Kovri go write your own code
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
#ifndef SIPHASH_H
|
#ifndef SIPHASH_H
|
||||||
#define SIPHASH_H
|
#define SIPHASH_H
|
||||||
|
@ -16,138 +16,138 @@ namespace i2p
|
||||||
{
|
{
|
||||||
namespace crypto
|
namespace crypto
|
||||||
{
|
{
|
||||||
namespace siphash
|
namespace siphash
|
||||||
{
|
{
|
||||||
constexpr int crounds = 2;
|
constexpr int crounds = 2;
|
||||||
constexpr int drounds = 4;
|
constexpr int drounds = 4;
|
||||||
|
|
||||||
inline uint64_t rotl(const uint64_t & x, int b)
|
inline uint64_t rotl(const uint64_t & x, int b)
|
||||||
{
|
{
|
||||||
uint64_t ret = x << b;
|
uint64_t ret = x << b;
|
||||||
ret |= x >> (64 - b);
|
ret |= x >> (64 - b);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void u32to8le(const uint32_t & v, uint8_t * p)
|
inline void u32to8le(const uint32_t & v, uint8_t * p)
|
||||||
{
|
{
|
||||||
p[0] = (uint8_t) v;
|
p[0] = (uint8_t) v;
|
||||||
p[1] = (uint8_t) (v >> 8);
|
p[1] = (uint8_t) (v >> 8);
|
||||||
p[2] = (uint8_t) (v >> 16);
|
p[2] = (uint8_t) (v >> 16);
|
||||||
p[3] = (uint8_t) (v >> 24);
|
p[3] = (uint8_t) (v >> 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void u64to8le(const uint64_t & v, uint8_t * p)
|
inline void u64to8le(const uint64_t & v, uint8_t * p)
|
||||||
{
|
{
|
||||||
p[0] = v & 0xff;
|
p[0] = v & 0xff;
|
||||||
p[1] = (v >> 8) & 0xff;
|
p[1] = (v >> 8) & 0xff;
|
||||||
p[2] = (v >> 16) & 0xff;
|
p[2] = (v >> 16) & 0xff;
|
||||||
p[3] = (v >> 24) & 0xff;
|
p[3] = (v >> 24) & 0xff;
|
||||||
p[4] = (v >> 32) & 0xff;
|
p[4] = (v >> 32) & 0xff;
|
||||||
p[5] = (v >> 40) & 0xff;
|
p[5] = (v >> 40) & 0xff;
|
||||||
p[6] = (v >> 48) & 0xff;
|
p[6] = (v >> 48) & 0xff;
|
||||||
p[7] = (v >> 56) & 0xff;
|
p[7] = (v >> 56) & 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint64_t u8to64le(const uint8_t * p)
|
inline uint64_t u8to64le(const uint8_t * p)
|
||||||
{
|
{
|
||||||
uint64_t i = 0;
|
uint64_t i = 0;
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
while(idx < 8)
|
while(idx < 8)
|
||||||
{
|
{
|
||||||
i |= ((uint64_t) p[idx]) << (idx * 8);
|
i |= ((uint64_t) p[idx]) << (idx * 8);
|
||||||
++idx;
|
++idx;
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void round(uint64_t & _v0, uint64_t & _v1, uint64_t & _v2, uint64_t & _v3)
|
inline void round(uint64_t & _v0, uint64_t & _v1, uint64_t & _v2, uint64_t & _v3)
|
||||||
{
|
{
|
||||||
_v0 += _v1;
|
_v0 += _v1;
|
||||||
_v1 = rotl(_v1, 13);
|
_v1 = rotl(_v1, 13);
|
||||||
_v1 ^= _v0;
|
_v1 ^= _v0;
|
||||||
_v0 = rotl(_v0, 32);
|
_v0 = rotl(_v0, 32);
|
||||||
_v2 += _v3;
|
_v2 += _v3;
|
||||||
_v3 = rotl(_v3, 16);
|
_v3 = rotl(_v3, 16);
|
||||||
_v3 ^= _v2;
|
_v3 ^= _v2;
|
||||||
_v0 += _v3;
|
_v0 += _v3;
|
||||||
_v3 = rotl(_v3, 21);
|
_v3 = rotl(_v3, 21);
|
||||||
_v3 ^= _v0;
|
_v3 ^= _v0;
|
||||||
_v2 += _v1;
|
_v2 += _v1;
|
||||||
_v1 = rotl(_v1, 17);
|
_v1 = rotl(_v1, 17);
|
||||||
_v1 ^= _v2;
|
_v1 ^= _v2;
|
||||||
_v2 = rotl(_v2, 32);
|
_v2 = rotl(_v2, 32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** hashsz must be 8 or 16 */
|
/** hashsz must be 8 or 16 */
|
||||||
template<std::size_t hashsz>
|
template<std::size_t hashsz>
|
||||||
inline void Siphash(uint8_t * h, const uint8_t * buf, std::size_t bufsz, const uint8_t * key)
|
inline void Siphash(uint8_t * h, const uint8_t * buf, std::size_t bufsz, const uint8_t * key)
|
||||||
{
|
{
|
||||||
uint64_t v0 = 0x736f6d6570736575ULL;
|
uint64_t v0 = 0x736f6d6570736575ULL;
|
||||||
uint64_t v1 = 0x646f72616e646f6dULL;
|
uint64_t v1 = 0x646f72616e646f6dULL;
|
||||||
uint64_t v2 = 0x6c7967656e657261ULL;
|
uint64_t v2 = 0x6c7967656e657261ULL;
|
||||||
uint64_t v3 = 0x7465646279746573ULL;
|
uint64_t v3 = 0x7465646279746573ULL;
|
||||||
const uint64_t k0 = siphash::u8to64le(key);
|
const uint64_t k0 = siphash::u8to64le(key);
|
||||||
const uint64_t k1 = siphash::u8to64le(key + 8);
|
const uint64_t k1 = siphash::u8to64le(key + 8);
|
||||||
uint64_t msg;
|
uint64_t msg;
|
||||||
int i;
|
int i;
|
||||||
const uint8_t * end = buf + bufsz - (bufsz % sizeof(uint64_t));
|
const uint8_t * end = buf + bufsz - (bufsz % sizeof(uint64_t));
|
||||||
auto left = bufsz & 7;
|
auto left = bufsz & 7;
|
||||||
uint64_t b = ((uint64_t)bufsz) << 56;
|
uint64_t b = ((uint64_t)bufsz) << 56;
|
||||||
v3 ^= k1;
|
v3 ^= k1;
|
||||||
v2 ^= k0;
|
v2 ^= k0;
|
||||||
v1 ^= k1;
|
v1 ^= k1;
|
||||||
v0 ^= k0;
|
v0 ^= k0;
|
||||||
|
|
||||||
if(hashsz == 16) v1 ^= 0xee;
|
if(hashsz == 16) v1 ^= 0xee;
|
||||||
|
|
||||||
while(buf != end)
|
while(buf != end)
|
||||||
{
|
{
|
||||||
msg = siphash::u8to64le(buf);
|
msg = siphash::u8to64le(buf);
|
||||||
v3 ^= msg;
|
v3 ^= msg;
|
||||||
for(i = 0; i < siphash::crounds; ++i)
|
for(i = 0; i < siphash::crounds; ++i)
|
||||||
siphash::round(v0, v1, v2, v3);
|
siphash::round(v0, v1, v2, v3);
|
||||||
|
|
||||||
v0 ^= msg;
|
v0 ^= msg;
|
||||||
buf += 8;
|
buf += 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
while(left)
|
while(left)
|
||||||
{
|
{
|
||||||
--left;
|
--left;
|
||||||
b |= ((uint64_t)(buf[left])) << (left * 8);
|
b |= ((uint64_t)(buf[left])) << (left * 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
v3 ^= b;
|
v3 ^= b;
|
||||||
|
|
||||||
for(i = 0; i < siphash::crounds; ++i)
|
for(i = 0; i < siphash::crounds; ++i)
|
||||||
siphash::round(v0, v1, v2, v3);
|
siphash::round(v0, v1, v2, v3);
|
||||||
|
|
||||||
v0 ^= b;
|
v0 ^= b;
|
||||||
|
|
||||||
|
|
||||||
if(hashsz == 16)
|
if(hashsz == 16)
|
||||||
v2 ^= 0xee;
|
v2 ^= 0xee;
|
||||||
else
|
else
|
||||||
v2 ^= 0xff;
|
v2 ^= 0xff;
|
||||||
|
|
||||||
for(i = 0; i < siphash::drounds; ++i)
|
for(i = 0; i < siphash::drounds; ++i)
|
||||||
siphash::round(v0, v1, v2, v3);
|
siphash::round(v0, v1, v2, v3);
|
||||||
|
|
||||||
b = v0 ^ v1 ^ v2 ^ v3;
|
b = v0 ^ v1 ^ v2 ^ v3;
|
||||||
|
|
||||||
siphash::u64to8le(b, h);
|
siphash::u64to8le(b, h);
|
||||||
|
|
||||||
if(hashsz == 8) return;
|
if(hashsz == 8) return;
|
||||||
|
|
||||||
v1 ^= 0xdd;
|
v1 ^= 0xdd;
|
||||||
|
|
||||||
for (i = 0; i < siphash::drounds; ++i)
|
for (i = 0; i < siphash::drounds; ++i)
|
||||||
siphash::round(v0, v1, v2, v3);
|
siphash::round(v0, v1, v2, v3);
|
||||||
|
|
||||||
b = v0 ^ v1 ^ v2 ^ v3;
|
b = v0 ^ v1 ^ v2 ^ v3;
|
||||||
siphash::u64to8le(b, h + 8);
|
siphash::u64to8le(b, h + 8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace stream
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// partially
|
// partially
|
||||||
rem = len - offset;
|
rem = len - offset;
|
||||||
memcpy (buf + offset, nextBuffer->GetRemaningBuffer (), len - offset);
|
memcpy (buf + offset, nextBuffer->GetRemaningBuffer (), len - offset);
|
||||||
nextBuffer->offset += (len - offset);
|
nextBuffer->offset += (len - offset);
|
||||||
offset = len; // break
|
offset = len; // break
|
||||||
|
@ -60,7 +60,7 @@ namespace stream
|
||||||
m_SendStreamID (0), m_SequenceNumber (0), m_LastReceivedSequenceNumber (-1),
|
m_SendStreamID (0), m_SequenceNumber (0), m_LastReceivedSequenceNumber (-1),
|
||||||
m_Status (eStreamStatusNew), m_IsAckSendScheduled (false), m_LocalDestination (local),
|
m_Status (eStreamStatusNew), m_IsAckSendScheduled (false), m_LocalDestination (local),
|
||||||
m_RemoteLeaseSet (remote), m_ReceiveTimer (m_Service), m_ResendTimer (m_Service),
|
m_RemoteLeaseSet (remote), m_ReceiveTimer (m_Service), m_ResendTimer (m_Service),
|
||||||
m_AckSendTimer (m_Service), m_NumSentBytes (0), m_NumReceivedBytes (0), m_Port (port),
|
m_AckSendTimer (m_Service), m_NumSentBytes (0), m_NumReceivedBytes (0), m_Port (port),
|
||||||
m_WindowSize (MIN_WINDOW_SIZE), m_RTT (INITIAL_RTT), m_RTO (INITIAL_RTO),
|
m_WindowSize (MIN_WINDOW_SIZE), m_RTT (INITIAL_RTT), m_RTO (INITIAL_RTO),
|
||||||
m_AckDelay (local.GetOwner ()->GetStreamingAckDelay ()),
|
m_AckDelay (local.GetOwner ()->GetStreamingAckDelay ()),
|
||||||
m_LastWindowSizeIncreaseTime (0), m_NumResendAttempts (0), m_MTU (STREAMING_MTU)
|
m_LastWindowSizeIncreaseTime (0), m_NumResendAttempts (0), m_MTU (STREAMING_MTU)
|
||||||
|
@ -73,7 +73,7 @@ namespace stream
|
||||||
m_Service (service), m_SendStreamID (0), m_SequenceNumber (0), m_LastReceivedSequenceNumber (-1),
|
m_Service (service), m_SendStreamID (0), m_SequenceNumber (0), m_LastReceivedSequenceNumber (-1),
|
||||||
m_Status (eStreamStatusNew), m_IsAckSendScheduled (false), m_LocalDestination (local),
|
m_Status (eStreamStatusNew), m_IsAckSendScheduled (false), m_LocalDestination (local),
|
||||||
m_ReceiveTimer (m_Service), m_ResendTimer (m_Service), m_AckSendTimer (m_Service),
|
m_ReceiveTimer (m_Service), m_ResendTimer (m_Service), m_AckSendTimer (m_Service),
|
||||||
m_NumSentBytes (0), m_NumReceivedBytes (0), m_Port (0), m_WindowSize (MIN_WINDOW_SIZE),
|
m_NumSentBytes (0), m_NumReceivedBytes (0), m_Port (0), m_WindowSize (MIN_WINDOW_SIZE),
|
||||||
m_RTT (INITIAL_RTT), m_RTO (INITIAL_RTO), m_AckDelay (local.GetOwner ()->GetStreamingAckDelay ()),
|
m_RTT (INITIAL_RTT), m_RTO (INITIAL_RTO), m_AckDelay (local.GetOwner ()->GetStreamingAckDelay ()),
|
||||||
m_LastWindowSizeIncreaseTime (0), m_NumResendAttempts (0), m_MTU (STREAMING_MTU)
|
m_LastWindowSizeIncreaseTime (0), m_NumResendAttempts (0), m_MTU (STREAMING_MTU)
|
||||||
{
|
{
|
||||||
|
@ -269,7 +269,7 @@ namespace stream
|
||||||
m_RemoteIdentity = std::make_shared<i2p::data::IdentityEx>(optionData, optionSize);
|
m_RemoteIdentity = std::make_shared<i2p::data::IdentityEx>(optionData, optionSize);
|
||||||
if (m_RemoteIdentity->IsRSA ())
|
if (m_RemoteIdentity->IsRSA ())
|
||||||
{
|
{
|
||||||
LogPrint (eLogInfo, "Streaming: Incoming stream from RSA destination ", m_RemoteIdentity->GetIdentHash ().ToBase64 (), " Discarded");
|
LogPrint (eLogInfo, "Streaming: Incoming stream from RSA destination ", m_RemoteIdentity->GetIdentHash ().ToBase64 (), " Discarded");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
optionData += m_RemoteIdentity->GetFullLen ();
|
optionData += m_RemoteIdentity->GetFullLen ();
|
||||||
|
@ -435,7 +435,7 @@ namespace stream
|
||||||
m_SendBuffer.Add (buf, len, handler);
|
m_SendBuffer.Add (buf, len, handler);
|
||||||
}
|
}
|
||||||
else if (handler)
|
else if (handler)
|
||||||
handler(boost::system::error_code ());
|
handler(boost::system::error_code ());
|
||||||
m_Service.post (std::bind (&Stream::SendBuffer, shared_from_this ()));
|
m_Service.post (std::bind (&Stream::SendBuffer, shared_from_this ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -471,7 +471,7 @@ namespace stream
|
||||||
size++; // resend delay
|
size++; // resend delay
|
||||||
if (m_Status == eStreamStatusNew)
|
if (m_Status == eStreamStatusNew)
|
||||||
{
|
{
|
||||||
// initial packet
|
// initial packet
|
||||||
m_Status = eStreamStatusOpen;
|
m_Status = eStreamStatusOpen;
|
||||||
if (!m_RemoteLeaseSet) m_RemoteLeaseSet = m_LocalDestination.GetOwner ()->FindLeaseSet (m_RemoteIdentity->GetIdentHash ());;
|
if (!m_RemoteLeaseSet) m_RemoteLeaseSet = m_LocalDestination.GetOwner ()->FindLeaseSet (m_RemoteIdentity->GetIdentHash ());;
|
||||||
if (m_RemoteLeaseSet)
|
if (m_RemoteLeaseSet)
|
||||||
|
@ -654,7 +654,7 @@ namespace stream
|
||||||
size += 4; // receiveStreamID
|
size += 4; // receiveStreamID
|
||||||
htobe32buf (packet + size, m_SequenceNumber++);
|
htobe32buf (packet + size, m_SequenceNumber++);
|
||||||
size += 4; // sequenceNum
|
size += 4; // sequenceNum
|
||||||
htobe32buf (packet + size, m_LastReceivedSequenceNumber >= 0 ? m_LastReceivedSequenceNumber : 0);
|
htobe32buf (packet + size, m_LastReceivedSequenceNumber >= 0 ? m_LastReceivedSequenceNumber : 0);
|
||||||
size += 4; // ack Through
|
size += 4; // ack Through
|
||||||
packet[size] = 0;
|
packet[size] = 0;
|
||||||
size++; // NACK count
|
size++; // NACK count
|
||||||
|
@ -748,7 +748,7 @@ namespace stream
|
||||||
|
|
||||||
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
|
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
|
||||||
if (!m_CurrentRemoteLease || !m_CurrentRemoteLease->endDate || // excluded from LeaseSet
|
if (!m_CurrentRemoteLease || !m_CurrentRemoteLease->endDate || // excluded from LeaseSet
|
||||||
ts >= m_CurrentRemoteLease->endDate - i2p::data::LEASE_ENDDATE_THRESHOLD)
|
ts >= m_CurrentRemoteLease->endDate - i2p::data::LEASE_ENDDATE_THRESHOLD)
|
||||||
UpdateCurrentRemoteLease (true);
|
UpdateCurrentRemoteLease (true);
|
||||||
if (m_CurrentRemoteLease && ts < m_CurrentRemoteLease->endDate + i2p::data::LEASE_ENDDATE_THRESHOLD)
|
if (m_CurrentRemoteLease && ts < m_CurrentRemoteLease->endDate + i2p::data::LEASE_ENDDATE_THRESHOLD)
|
||||||
{
|
{
|
||||||
|
@ -785,7 +785,7 @@ namespace stream
|
||||||
if (ts > m_RoutingSession->GetLeaseSetSubmissionTime () + i2p::garlic::LEASET_CONFIRMATION_TIMEOUT)
|
if (ts > m_RoutingSession->GetLeaseSetSubmissionTime () + i2p::garlic::LEASET_CONFIRMATION_TIMEOUT)
|
||||||
{
|
{
|
||||||
// LeaseSet was not confirmed, should try other tunnels
|
// LeaseSet was not confirmed, should try other tunnels
|
||||||
LogPrint (eLogWarning, "Streaming: LeaseSet was not confirmed in ", i2p::garlic::LEASET_CONFIRMATION_TIMEOUT, " milliseconds. Trying to resubmit");
|
LogPrint (eLogWarning, "Streaming: LeaseSet was not confirmed in ", i2p::garlic::LEASET_CONFIRMATION_TIMEOUT, " milliseconds. Trying to resubmit");
|
||||||
m_RoutingSession->SetSharedRoutingPath (nullptr);
|
m_RoutingSession->SetSharedRoutingPath (nullptr);
|
||||||
m_CurrentOutboundTunnel = nullptr;
|
m_CurrentOutboundTunnel = nullptr;
|
||||||
m_CurrentRemoteLease = nullptr;
|
m_CurrentRemoteLease = nullptr;
|
||||||
|
@ -1164,7 +1164,7 @@ namespace stream
|
||||||
m_Owner->GetService ().post([acceptor, this](void)
|
m_Owner->GetService ().post([acceptor, this](void)
|
||||||
{
|
{
|
||||||
if (!m_PendingIncomingStreams.empty ())
|
if (!m_PendingIncomingStreams.empty ())
|
||||||
{
|
{
|
||||||
acceptor (m_PendingIncomingStreams.front ());
|
acceptor (m_PendingIncomingStreams.front ());
|
||||||
m_PendingIncomingStreams.pop_front ();
|
m_PendingIncomingStreams.pop_front ();
|
||||||
if (m_PendingIncomingStreams.empty ())
|
if (m_PendingIncomingStreams.empty ())
|
||||||
|
|
142
libi2pd/Tag.h
142
libi2pd/Tag.h
|
@ -16,93 +16,91 @@
|
||||||
|
|
||||||
namespace i2p {
|
namespace i2p {
|
||||||
namespace data {
|
namespace data {
|
||||||
|
template<size_t sz>
|
||||||
template<size_t sz>
|
class Tag
|
||||||
class Tag
|
|
||||||
{
|
|
||||||
BOOST_STATIC_ASSERT_MSG(sz % 8 == 0, "Tag size must be multiple of 8 bytes");
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
Tag () = default;
|
|
||||||
Tag (const uint8_t * buf) { memcpy (m_Buf, buf, sz); }
|
|
||||||
|
|
||||||
bool operator== (const Tag& other) const { return !memcmp (m_Buf, other.m_Buf, sz); }
|
|
||||||
bool operator!= (const Tag& other) const { return !(*this == other); }
|
|
||||||
bool operator< (const Tag& other) const { return memcmp (m_Buf, other.m_Buf, sz) < 0; }
|
|
||||||
|
|
||||||
uint8_t * operator()() { return m_Buf; }
|
|
||||||
const uint8_t * operator()() const { return m_Buf; }
|
|
||||||
|
|
||||||
operator uint8_t * () { return m_Buf; }
|
|
||||||
operator const uint8_t * () const { return m_Buf; }
|
|
||||||
|
|
||||||
const uint8_t * data() const { return m_Buf; }
|
|
||||||
const uint64_t * GetLL () const { return ll; }
|
|
||||||
|
|
||||||
bool IsZero () const
|
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < sz/8; ++i)
|
BOOST_STATIC_ASSERT_MSG(sz % 8 == 0, "Tag size must be multiple of 8 bytes");
|
||||||
if (ll[i]) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Fill(uint8_t c)
|
public:
|
||||||
{
|
|
||||||
memset(m_Buf, c, sz);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Randomize()
|
Tag () = default;
|
||||||
{
|
Tag (const uint8_t * buf) { memcpy (m_Buf, buf, sz); }
|
||||||
RAND_bytes(m_Buf, sz);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string ToBase64 () const
|
bool operator== (const Tag& other) const { return !memcmp (m_Buf, other.m_Buf, sz); }
|
||||||
{
|
bool operator!= (const Tag& other) const { return !(*this == other); }
|
||||||
char str[sz*2];
|
bool operator< (const Tag& other) const { return memcmp (m_Buf, other.m_Buf, sz) < 0; }
|
||||||
size_t l = i2p::data::ByteStreamToBase64 (m_Buf, sz, str, sz*2);
|
|
||||||
return std::string (str, str + l);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string ToBase32 () const
|
uint8_t * operator()() { return m_Buf; }
|
||||||
{
|
const uint8_t * operator()() const { return m_Buf; }
|
||||||
char str[sz*2];
|
|
||||||
size_t l = i2p::data::ByteStreamToBase32 (m_Buf, sz, str, sz*2);
|
|
||||||
return std::string (str, str + l);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t FromBase32 (const std::string& s)
|
operator uint8_t * () { return m_Buf; }
|
||||||
{
|
operator const uint8_t * () const { return m_Buf; }
|
||||||
return i2p::data::Base32ToByteStream (s.c_str (), s.length (), m_Buf, sz);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t FromBase64 (const std::string& s)
|
const uint8_t * data() const { return m_Buf; }
|
||||||
{
|
const uint64_t * GetLL () const { return ll; }
|
||||||
return i2p::data::Base64ToByteStream (s.c_str (), s.length (), m_Buf, sz);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
bool IsZero () const
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < sz/8; ++i)
|
||||||
|
if (ll[i]) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
union // 8 bytes aligned
|
void Fill(uint8_t c)
|
||||||
{
|
{
|
||||||
uint8_t m_Buf[sz];
|
memset(m_Buf, c, sz);
|
||||||
uint64_t ll[sz/8];
|
}
|
||||||
|
|
||||||
|
void Randomize()
|
||||||
|
{
|
||||||
|
RAND_bytes(m_Buf, sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ToBase64 () const
|
||||||
|
{
|
||||||
|
char str[sz*2];
|
||||||
|
size_t l = i2p::data::ByteStreamToBase64 (m_Buf, sz, str, sz*2);
|
||||||
|
return std::string (str, str + l);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ToBase32 () const
|
||||||
|
{
|
||||||
|
char str[sz*2];
|
||||||
|
size_t l = i2p::data::ByteStreamToBase32 (m_Buf, sz, str, sz*2);
|
||||||
|
return std::string (str, str + l);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t FromBase32 (const std::string& s)
|
||||||
|
{
|
||||||
|
return i2p::data::Base32ToByteStream (s.c_str (), s.length (), m_Buf, sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t FromBase64 (const std::string& s)
|
||||||
|
{
|
||||||
|
return i2p::data::Base64ToByteStream (s.c_str (), s.length (), m_Buf, sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
union // 8 bytes aligned
|
||||||
|
{
|
||||||
|
uint8_t m_Buf[sz];
|
||||||
|
uint64_t ll[sz/8];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
} // data
|
} // data
|
||||||
} // i2p
|
} // i2p
|
||||||
|
|
||||||
namespace std
|
namespace std
|
||||||
{
|
{
|
||||||
// hash for std::unordered_map
|
// hash for std::unordered_map
|
||||||
template<size_t sz> struct hash<i2p::data::Tag<sz> >
|
template<size_t sz> struct hash<i2p::data::Tag<sz> >
|
||||||
{
|
{
|
||||||
size_t operator()(const i2p::data::Tag<sz>& s) const
|
size_t operator()(const i2p::data::Tag<sz>& s) const
|
||||||
{
|
{
|
||||||
return s.GetLL ()[0];
|
return s.GetLL ()[0];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* TAG_H__ */
|
#endif /* TAG_H__ */
|
||||||
|
|
|
@ -24,26 +24,26 @@ namespace util
|
||||||
static uint64_t GetLocalMillisecondsSinceEpoch ()
|
static uint64_t GetLocalMillisecondsSinceEpoch ()
|
||||||
{
|
{
|
||||||
return std::chrono::duration_cast<std::chrono::milliseconds>(
|
return std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||||
std::chrono::system_clock::now().time_since_epoch()).count ();
|
std::chrono::system_clock::now().time_since_epoch()).count ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t GetLocalHoursSinceEpoch ()
|
static uint32_t GetLocalHoursSinceEpoch ()
|
||||||
{
|
{
|
||||||
return std::chrono::duration_cast<std::chrono::hours>(
|
return std::chrono::duration_cast<std::chrono::hours>(
|
||||||
std::chrono::system_clock::now().time_since_epoch()).count ();
|
std::chrono::system_clock::now().time_since_epoch()).count ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t GetLocalSecondsSinceEpoch ()
|
static uint64_t GetLocalSecondsSinceEpoch ()
|
||||||
{
|
{
|
||||||
return std::chrono::duration_cast<std::chrono::seconds>(
|
return std::chrono::duration_cast<std::chrono::seconds>(
|
||||||
std::chrono::system_clock::now().time_since_epoch()).count ();
|
std::chrono::system_clock::now().time_since_epoch()).count ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int64_t g_TimeOffset = 0; // in seconds
|
static int64_t g_TimeOffset = 0; // in seconds
|
||||||
|
|
||||||
static void SyncTimeWithNTP (const std::string& address)
|
static void SyncTimeWithNTP (const std::string& address)
|
||||||
{
|
{
|
||||||
LogPrint (eLogInfo, "Timestamp: NTP request to ", address);
|
LogPrint (eLogInfo, "Timestamp: NTP request to ", address);
|
||||||
boost::asio::io_service service;
|
boost::asio::io_service service;
|
||||||
boost::asio::ip::udp::resolver::query query (boost::asio::ip::udp::v4 (), address, "ntp");
|
boost::asio::ip::udp::resolver::query query (boost::asio::ip::udp::v4 (), address, "ntp");
|
||||||
boost::system::error_code ec;
|
boost::system::error_code ec;
|
||||||
|
@ -200,4 +200,3 @@ namespace util
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ namespace util
|
||||||
~NTPTimeSync ();
|
~NTPTimeSync ();
|
||||||
|
|
||||||
void Start ();
|
void Start ();
|
||||||
void Stop ();
|
void Stop ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ namespace util
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool m_IsRunning;
|
bool m_IsRunning;
|
||||||
std::unique_ptr<std::thread> m_Thread;
|
std::unique_ptr<std::thread> m_Thread;
|
||||||
boost::asio::io_service m_Service;
|
boost::asio::io_service m_Service;
|
||||||
boost::asio::deadline_timer m_Timer;
|
boost::asio::deadline_timer m_Timer;
|
||||||
int m_SyncInterval;
|
int m_SyncInterval;
|
||||||
|
@ -46,4 +46,3 @@ namespace util
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace i2p
|
||||||
namespace tunnel
|
namespace tunnel
|
||||||
{
|
{
|
||||||
TransitTunnel::TransitTunnel (uint32_t receiveTunnelID,
|
TransitTunnel::TransitTunnel (uint32_t receiveTunnelID,
|
||||||
const uint8_t * nextIdent, uint32_t nextTunnelID,
|
const uint8_t * nextIdent, uint32_t nextTunnelID,
|
||||||
const uint8_t * layerKey,const uint8_t * ivKey):
|
const uint8_t * layerKey,const uint8_t * ivKey):
|
||||||
TunnelBase (receiveTunnelID, nextTunnelID, nextIdent)
|
TunnelBase (receiveTunnelID, nextTunnelID, nextIdent)
|
||||||
{
|
{
|
||||||
|
@ -88,7 +88,7 @@ namespace tunnel
|
||||||
|
|
||||||
std::shared_ptr<TransitTunnel> CreateTransitTunnel (uint32_t receiveTunnelID,
|
std::shared_ptr<TransitTunnel> CreateTransitTunnel (uint32_t receiveTunnelID,
|
||||||
const uint8_t * nextIdent, uint32_t nextTunnelID,
|
const uint8_t * nextIdent, uint32_t nextTunnelID,
|
||||||
const uint8_t * layerKey,const uint8_t * ivKey,
|
const uint8_t * layerKey,const uint8_t * ivKey,
|
||||||
bool isGateway, bool isEndpoint)
|
bool isGateway, bool isEndpoint)
|
||||||
{
|
{
|
||||||
if (isEndpoint)
|
if (isEndpoint)
|
||||||
|
|
|
@ -390,7 +390,7 @@ namespace transport
|
||||||
{
|
{
|
||||||
auto r = netdb.FindRouter (ident);
|
auto r = netdb.FindRouter (ident);
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> l(m_PeersMutex);
|
std::unique_lock<std::mutex> l(m_PeersMutex);
|
||||||
it = m_Peers.insert (std::pair<i2p::data::IdentHash, Peer>(ident, { 0, r, {},
|
it = m_Peers.insert (std::pair<i2p::data::IdentHash, Peer>(ident, { 0, r, {},
|
||||||
i2p::util::GetSecondsSinceEpoch (), {} })).first;
|
i2p::util::GetSecondsSinceEpoch (), {} })).first;
|
||||||
}
|
}
|
||||||
|
@ -553,13 +553,13 @@ namespace transport
|
||||||
{
|
{
|
||||||
auto router = i2p::data::netdb.GetRandomPeerTestRouter (isv4); // v4 only if v4
|
auto router = i2p::data::netdb.GetRandomPeerTestRouter (isv4); // v4 only if v4
|
||||||
if (router)
|
if (router)
|
||||||
m_SSUServer->CreateSession (router, true, isv4); // peer test
|
m_SSUServer->CreateSession (router, true, isv4); // peer test
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// if not peer test capable routers found pick any
|
// if not peer test capable routers found pick any
|
||||||
router = i2p::data::netdb.GetRandomRouter ();
|
router = i2p::data::netdb.GetRandomRouter ();
|
||||||
if (router && router->IsSSU ())
|
if (router && router->IsSSU ())
|
||||||
m_SSUServer->CreateSession (router); // no peer test
|
m_SSUServer->CreateSession (router); // no peer test
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i2p::context.SupportsV6 ())
|
if (i2p::context.SupportsV6 ())
|
||||||
|
@ -713,7 +713,7 @@ namespace transport
|
||||||
{
|
{
|
||||||
profile->TunnelNonReplied();
|
profile->TunnelNonReplied();
|
||||||
}
|
}
|
||||||
std::unique_lock<std::mutex> l(m_PeersMutex);
|
std::unique_lock<std::mutex> l(m_PeersMutex);
|
||||||
it = m_Peers.erase (it);
|
it = m_Peers.erase (it);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -103,7 +103,7 @@ namespace transport
|
||||||
uint64_t GetTotalReceivedBytes () const { return m_TotalReceivedBytes; };
|
uint64_t GetTotalReceivedBytes () const { return m_TotalReceivedBytes; };
|
||||||
uint64_t GetTotalTransitTransmittedBytes () const { return m_TotalTransitTransmittedBytes; }
|
uint64_t GetTotalTransitTransmittedBytes () const { return m_TotalTransitTransmittedBytes; }
|
||||||
void UpdateTotalTransitTransmittedBytes (uint32_t add) { m_TotalTransitTransmittedBytes += add; };
|
void UpdateTotalTransitTransmittedBytes (uint32_t add) { m_TotalTransitTransmittedBytes += add; };
|
||||||
uint32_t GetInBandwidth () const { return m_InBandwidth; };
|
uint32_t GetInBandwidth () const { return m_InBandwidth; };
|
||||||
uint32_t GetOutBandwidth () const { return m_OutBandwidth; };
|
uint32_t GetOutBandwidth () const { return m_OutBandwidth; };
|
||||||
uint32_t GetTransitBandwidth () const { return m_TransitBandwidth; };
|
uint32_t GetTransitBandwidth () const { return m_TransitBandwidth; };
|
||||||
bool IsBandwidthExceeded () const;
|
bool IsBandwidthExceeded () const;
|
||||||
|
@ -111,16 +111,16 @@ namespace transport
|
||||||
size_t GetNumPeers () const { return m_Peers.size (); };
|
size_t GetNumPeers () const { return m_Peers.size (); };
|
||||||
std::shared_ptr<const i2p::data::RouterInfo> GetRandomPeer () const;
|
std::shared_ptr<const i2p::data::RouterInfo> GetRandomPeer () const;
|
||||||
|
|
||||||
/** get a trusted first hop for restricted routes */
|
/** get a trusted first hop for restricted routes */
|
||||||
std::shared_ptr<const i2p::data::RouterInfo> GetRestrictedPeer() const;
|
std::shared_ptr<const i2p::data::RouterInfo> GetRestrictedPeer() const;
|
||||||
/** do we want to use restricted routes? */
|
/** do we want to use restricted routes? */
|
||||||
bool RoutesRestricted() const;
|
bool RoutesRestricted() const;
|
||||||
/** restrict routes to use only these router families for first hops */
|
/** restrict routes to use only these router families for first hops */
|
||||||
void RestrictRoutesToFamilies(std::set<std::string> families);
|
void RestrictRoutesToFamilies(std::set<std::string> families);
|
||||||
/** restrict routes to use only these routers for first hops */
|
/** restrict routes to use only these routers for first hops */
|
||||||
void RestrictRoutesToRouters(std::set<i2p::data::IdentHash> routers);
|
void RestrictRoutesToRouters(std::set<i2p::data::IdentHash> routers);
|
||||||
|
|
||||||
bool IsRestrictedPeer(const i2p::data::IdentHash & ident) const;
|
bool IsRestrictedPeer(const i2p::data::IdentHash & ident) const;
|
||||||
|
|
||||||
void PeerTest ();
|
void PeerTest ();
|
||||||
|
|
||||||
|
|
|
@ -64,8 +64,7 @@ namespace tunnel
|
||||||
m.hash = i2p::data::IdentHash (fragment);
|
m.hash = i2p::data::IdentHash (fragment);
|
||||||
fragment += 32; // to hash
|
fragment += 32; // to hash
|
||||||
break;
|
break;
|
||||||
default:
|
default: ;
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isFragmented = flag & 0x08;
|
bool isFragmented = flag & 0x08;
|
||||||
|
|
|
@ -172,7 +172,7 @@ namespace tunnel
|
||||||
SHA256(payload, size+16, hash);
|
SHA256(payload, size+16, hash);
|
||||||
memcpy (buf+20, hash, 4); // checksum
|
memcpy (buf+20, hash, 4); // checksum
|
||||||
payload[-1] = 0; // zero
|
payload[-1] = 0; // zero
|
||||||
ptrdiff_t paddingSize = payload - buf - 25; // 25 = 24 + 1
|
ptrdiff_t paddingSize = payload - buf - 25; // 25 = 24 + 1
|
||||||
if (paddingSize > 0)
|
if (paddingSize > 0)
|
||||||
{
|
{
|
||||||
// non-zero padding
|
// non-zero padding
|
||||||
|
@ -219,4 +219,3 @@ namespace tunnel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,6 @@ namespace i2p
|
||||||
{
|
{
|
||||||
namespace tunnel
|
namespace tunnel
|
||||||
{
|
{
|
||||||
|
|
||||||
TunnelPool::TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels, int numOutboundTunnels):
|
TunnelPool::TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels, int numOutboundTunnels):
|
||||||
m_NumInboundHops (numInboundHops), m_NumOutboundHops (numOutboundHops),
|
m_NumInboundHops (numInboundHops), m_NumOutboundHops (numOutboundHops),
|
||||||
m_NumInboundTunnels (numInboundTunnels), m_NumOutboundTunnels (numOutboundTunnels), m_IsActive (true),
|
m_NumInboundTunnels (numInboundTunnels), m_NumOutboundTunnels (numOutboundTunnels), m_IsActive (true),
|
||||||
|
@ -67,7 +66,8 @@ namespace tunnel
|
||||||
m_Tests.clear ();
|
m_Tests.clear ();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TunnelPool::Reconfigure(int inHops, int outHops, int inQuant, int outQuant) {
|
bool TunnelPool::Reconfigure(int inHops, int outHops, int inQuant, int outQuant)
|
||||||
|
{
|
||||||
if( inHops >= 0 && outHops >= 0 && inQuant > 0 && outQuant > 0)
|
if( inHops >= 0 && outHops >= 0 && inQuant > 0 && outQuant > 0)
|
||||||
{
|
{
|
||||||
m_NumInboundHops = inHops;
|
m_NumInboundHops = inHops;
|
||||||
|
@ -180,8 +180,8 @@ namespace tunnel
|
||||||
{
|
{
|
||||||
if (it->IsEstablished () && it != excluded)
|
if (it->IsEstablished () && it != excluded)
|
||||||
{
|
{
|
||||||
tunnel = it;
|
tunnel = it;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if (i > ind && tunnel) break;
|
if (i > ind && tunnel) break;
|
||||||
}
|
}
|
||||||
|
@ -411,7 +411,7 @@ namespace tunnel
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(m_CustomPeerSelectorMutex);
|
std::lock_guard<std::mutex> lock(m_CustomPeerSelectorMutex);
|
||||||
if (m_CustomPeerSelector)
|
if (m_CustomPeerSelector)
|
||||||
return m_CustomPeerSelector->SelectPeers(peers, numHops, isInbound);
|
return m_CustomPeerSelector->SelectPeers(peers, numHops, isInbound);
|
||||||
}
|
}
|
||||||
// explicit peers in use
|
// explicit peers in use
|
||||||
if (m_ExplicitPeers) return SelectExplicitPeers (peers, isInbound);
|
if (m_ExplicitPeers) return SelectExplicitPeers (peers, isInbound);
|
||||||
|
|
|
@ -80,18 +80,18 @@ namespace tunnel
|
||||||
void UnsetCustomPeerSelector();
|
void UnsetCustomPeerSelector();
|
||||||
bool HasCustomPeerSelector();
|
bool HasCustomPeerSelector();
|
||||||
|
|
||||||
/** @brief make this tunnel pool yield tunnels that fit latency range [min, max] */
|
/** @brief make this tunnel pool yield tunnels that fit latency range [min, max] */
|
||||||
void RequireLatency(uint64_t min, uint64_t max) { m_MinLatency = min; m_MaxLatency = max; }
|
void RequireLatency(uint64_t min, uint64_t max) { m_MinLatency = min; m_MaxLatency = max; }
|
||||||
|
|
||||||
/** @brief return true if this tunnel pool has a latency requirement */
|
/** @brief return true if this tunnel pool has a latency requirement */
|
||||||
bool HasLatencyRequirement() const { return m_MinLatency > 0 && m_MaxLatency > 0; }
|
bool HasLatencyRequirement() const { return m_MinLatency > 0 && m_MaxLatency > 0; }
|
||||||
|
|
||||||
/** @brief get the lowest latency tunnel in this tunnel pool regardless of latency requirements */
|
/** @brief get the lowest latency tunnel in this tunnel pool regardless of latency requirements */
|
||||||
std::shared_ptr<InboundTunnel> GetLowestLatencyInboundTunnel(std::shared_ptr<InboundTunnel> exclude=nullptr) const;
|
std::shared_ptr<InboundTunnel> GetLowestLatencyInboundTunnel(std::shared_ptr<InboundTunnel> exclude = nullptr) const;
|
||||||
std::shared_ptr<OutboundTunnel> GetLowestLatencyOutboundTunnel(std::shared_ptr<OutboundTunnel> exclude=nullptr) const;
|
std::shared_ptr<OutboundTunnel> GetLowestLatencyOutboundTunnel(std::shared_ptr<OutboundTunnel> exclude = nullptr) const;
|
||||||
|
|
||||||
// for overriding tunnel peer selection
|
// for overriding tunnel peer selection
|
||||||
std::shared_ptr<const i2p::data::RouterInfo> SelectNextHop (std::shared_ptr<const i2p::data::RouterInfo> prevHop) const;
|
std::shared_ptr<const i2p::data::RouterInfo> SelectNextHop (std::shared_ptr<const i2p::data::RouterInfo> prevHop) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -118,8 +118,8 @@ namespace tunnel
|
||||||
std::mutex m_CustomPeerSelectorMutex;
|
std::mutex m_CustomPeerSelectorMutex;
|
||||||
ITunnelPeerSelector * m_CustomPeerSelector;
|
ITunnelPeerSelector * m_CustomPeerSelector;
|
||||||
|
|
||||||
uint64_t m_MinLatency=0; // if > 0 this tunnel pool will try building tunnels with minimum latency by ms
|
uint64_t m_MinLatency = 0; // if > 0 this tunnel pool will try building tunnels with minimum latency by ms
|
||||||
uint64_t m_MaxLatency=0; // if > 0 this tunnel pool will try building tunnels with maximum latency by ms
|
uint64_t m_MaxLatency = 0; // if > 0 this tunnel pool will try building tunnels with maximum latency by ms
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -31,8 +31,8 @@ namespace api
|
||||||
bool precomputation; i2p::config::GetOption("precomputation.elgamal", precomputation);
|
bool precomputation; i2p::config::GetOption("precomputation.elgamal", precomputation);
|
||||||
i2p::crypto::InitCrypto (precomputation);
|
i2p::crypto::InitCrypto (precomputation);
|
||||||
|
|
||||||
int netID; i2p::config::GetOption("netid", netID);
|
int netID; i2p::config::GetOption("netid", netID);
|
||||||
i2p::context.SetNetID (netID);
|
i2p::context.SetNetID (netID);
|
||||||
|
|
||||||
i2p::context.Init ();
|
i2p::context.Init ();
|
||||||
}
|
}
|
||||||
|
@ -133,4 +133,3 @@ namespace api
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,4 +35,3 @@ namespace api
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -101,21 +101,21 @@ namespace net
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
bool IsWindowsXPorLater()
|
bool IsWindowsXPorLater()
|
||||||
{
|
{
|
||||||
static bool isRequested = false;
|
static bool isRequested = false;
|
||||||
static bool isXP = false;
|
static bool isXP = false;
|
||||||
if (!isRequested)
|
if (!isRequested)
|
||||||
{
|
{
|
||||||
// request
|
// request
|
||||||
OSVERSIONINFO osvi;
|
OSVERSIONINFO osvi;
|
||||||
|
|
||||||
ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
|
ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
|
||||||
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
||||||
GetVersionEx(&osvi);
|
GetVersionEx(&osvi);
|
||||||
|
|
||||||
isXP = osvi.dwMajorVersion <= 5;
|
isXP = osvi.dwMajorVersion <= 5;
|
||||||
isRequested = true;
|
isRequested = true;
|
||||||
}
|
}
|
||||||
return isXP;
|
return isXP;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetMTUWindowsIpv4(sockaddr_in inputAddress, int fallback)
|
int GetMTUWindowsIpv4(sockaddr_in inputAddress, int fallback)
|
||||||
|
@ -246,22 +246,24 @@ namespace net
|
||||||
std::string localAddressUniversal = localAddress.to_string();
|
std::string localAddressUniversal = localAddress.to_string();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef int (* IPN)(int af, const char *src, void *dst);
|
typedef int (* IPN)(int af, const char *src, void *dst);
|
||||||
IPN inetpton = (IPN)GetProcAddress (GetModuleHandle ("ws2_32.dll"), "InetPton");
|
IPN inetpton = (IPN)GetProcAddress (GetModuleHandle ("ws2_32.dll"), "InetPton");
|
||||||
if (!inetpton) inetpton = inet_pton_xp; // use own implementation if not found
|
if (!inetpton) inetpton = inet_pton_xp; // use own implementation if not found
|
||||||
|
|
||||||
if(localAddress.is_v4())
|
if(localAddress.is_v4())
|
||||||
{
|
{
|
||||||
sockaddr_in inputAddress;
|
sockaddr_in inputAddress;
|
||||||
inetpton(AF_INET, localAddressUniversal.c_str(), &(inputAddress.sin_addr));
|
inetpton(AF_INET, localAddressUniversal.c_str(), &(inputAddress.sin_addr));
|
||||||
return GetMTUWindowsIpv4(inputAddress, fallback);
|
return GetMTUWindowsIpv4(inputAddress, fallback);
|
||||||
}
|
}
|
||||||
else if(localAddress.is_v6())
|
else if(localAddress.is_v6())
|
||||||
{
|
{
|
||||||
sockaddr_in6 inputAddress;
|
sockaddr_in6 inputAddress;
|
||||||
inetpton(AF_INET6, localAddressUniversal.c_str(), &(inputAddress.sin6_addr));
|
inetpton(AF_INET6, localAddressUniversal.c_str(), &(inputAddress.sin6_addr));
|
||||||
return GetMTUWindowsIpv6(inputAddress, fallback);
|
return GetMTUWindowsIpv6(inputAddress, fallback);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
LogPrint(eLogError, "NetIface: GetMTU(): address family is not supported");
|
LogPrint(eLogError, "NetIface: GetMTU(): address family is not supported");
|
||||||
return fallback;
|
return fallback;
|
||||||
}
|
}
|
||||||
|
@ -355,7 +357,7 @@ namespace net
|
||||||
if (cur_ifname == ifname && cur->ifa_addr && cur->ifa_addr->sa_family == af)
|
if (cur_ifname == ifname && cur->ifa_addr && cur->ifa_addr->sa_family == af)
|
||||||
{
|
{
|
||||||
// match
|
// match
|
||||||
char addr[INET6_ADDRSTRLEN];
|
char addr[INET6_ADDRSTRLEN];
|
||||||
memset (addr, 0, INET6_ADDRSTRLEN);
|
memset (addr, 0, INET6_ADDRSTRLEN);
|
||||||
if(af == AF_INET)
|
if(af == AF_INET)
|
||||||
inet_ntop(af, &((sockaddr_in *)cur->ifa_addr)->sin_addr, addr, INET6_ADDRSTRLEN);
|
inet_ntop(af, &((sockaddr_in *)cur->ifa_addr)->sin_addr, addr, INET6_ADDRSTRLEN);
|
||||||
|
@ -379,7 +381,6 @@ namespace net
|
||||||
LogPrint(eLogWarning, "NetIface: cannot find ipv4 address for interface ", ifname);
|
LogPrint(eLogWarning, "NetIface: cannot find ipv4 address for interface ", ifname);
|
||||||
}
|
}
|
||||||
return boost::asio::ip::address::from_string(fallback);
|
return boost::asio::ip::address::from_string(fallback);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -487,18 +487,18 @@ namespace client
|
||||||
LogPrint (eLogWarning, "Addressbook: subscriptions.txt usage is deprecated, use config file instead");
|
LogPrint (eLogWarning, "Addressbook: subscriptions.txt usage is deprecated, use config file instead");
|
||||||
}
|
}
|
||||||
else if (!i2p::config::IsDefault("addressbook.subscriptions"))
|
else if (!i2p::config::IsDefault("addressbook.subscriptions"))
|
||||||
{
|
{
|
||||||
// using config file items
|
// using config file items
|
||||||
std::string subscriptionURLs; i2p::config::GetOption("addressbook.subscriptions", subscriptionURLs);
|
std::string subscriptionURLs; i2p::config::GetOption("addressbook.subscriptions", subscriptionURLs);
|
||||||
std::vector<std::string> subsList;
|
std::vector<std::string> subsList;
|
||||||
boost::split(subsList, subscriptionURLs, boost::is_any_of(","), boost::token_compress_on);
|
boost::split(subsList, subscriptionURLs, boost::is_any_of(","), boost::token_compress_on);
|
||||||
|
|
||||||
for (size_t i = 0; i < subsList.size (); i++)
|
for (size_t i = 0; i < subsList.size (); i++)
|
||||||
{
|
{
|
||||||
m_Subscriptions.push_back (std::make_shared<AddressBookSubscription> (*this, subsList[i]));
|
m_Subscriptions.push_back (std::make_shared<AddressBookSubscription> (*this, subsList[i]));
|
||||||
}
|
}
|
||||||
LogPrint (eLogInfo, "Addressbook: ", m_Subscriptions.size (), " subscriptions urls loaded");
|
LogPrint (eLogInfo, "Addressbook: ", m_Subscriptions.size (), " subscriptions urls loaded");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "Addressbook: subscriptions already loaded");
|
LogPrint (eLogError, "Addressbook: subscriptions already loaded");
|
||||||
|
@ -515,7 +515,7 @@ namespace client
|
||||||
if (dot != std::string::npos)
|
if (dot != std::string::npos)
|
||||||
{
|
{
|
||||||
auto domain = it.first.substr (dot + 1);
|
auto domain = it.first.substr (dot + 1);
|
||||||
auto it1 = m_Addresses.find (domain); // find domain in our addressbook
|
auto it1 = m_Addresses.find (domain); // find domain in our addressbook
|
||||||
if (it1 != m_Addresses.end () && it1->second->IsIdentHash ())
|
if (it1 != m_Addresses.end () && it1->second->IsIdentHash ())
|
||||||
{
|
{
|
||||||
auto dest = context.FindLocalDestination (it1->second->identHash);
|
auto dest = context.FindLocalDestination (it1->second->identHash);
|
||||||
|
@ -610,7 +610,7 @@ namespace client
|
||||||
{
|
{
|
||||||
// download it from default subscription
|
// download it from default subscription
|
||||||
LogPrint (eLogInfo, "Addressbook: trying to download it from default subscription.");
|
LogPrint (eLogInfo, "Addressbook: trying to download it from default subscription.");
|
||||||
std::string defaultSubURL; i2p::config::GetOption("addressbook.defaulturl", defaultSubURL);
|
std::string defaultSubURL; i2p::config::GetOption("addressbook.defaulturl", defaultSubURL);
|
||||||
if (!m_DefaultSubscription)
|
if (!m_DefaultSubscription)
|
||||||
m_DefaultSubscription = std::make_shared<AddressBookSubscription>(*this, defaultSubURL);
|
m_DefaultSubscription = std::make_shared<AddressBookSubscription>(*this, defaultSubURL);
|
||||||
m_IsDownloading = true;
|
m_IsDownloading = true;
|
||||||
|
@ -802,7 +802,7 @@ namespace client
|
||||||
/* convert url to relative */
|
/* convert url to relative */
|
||||||
url.schema = "";
|
url.schema = "";
|
||||||
url.host = "";
|
url.host = "";
|
||||||
req.uri = url.to_string();
|
req.uri = url.to_string();
|
||||||
auto stream = i2p::client::context.GetSharedLocalDestination ()->CreateStream (leaseSet, dest_port);
|
auto stream = i2p::client::context.GetSharedLocalDestination ()->CreateStream (leaseSet, dest_port);
|
||||||
std::string request = req.to_string();
|
std::string request = req.to_string();
|
||||||
stream->Send ((const uint8_t *) request.data(), request.length());
|
stream->Send ((const uint8_t *) request.data(), request.length());
|
||||||
|
@ -920,7 +920,7 @@ namespace client
|
||||||
{
|
{
|
||||||
auto datagram = m_LocalDestination->GetDatagramDestination ();
|
auto datagram = m_LocalDestination->GetDatagramDestination ();
|
||||||
if (datagram)
|
if (datagram)
|
||||||
datagram->ResetReceiver (ADDRESS_RESOLVER_DATAGRAM_PORT);
|
datagram->ResetReceiver (ADDRESS_RESOLVER_DATAGRAM_PORT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -160,5 +160,3 @@ namespace client
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -50,10 +50,10 @@ namespace client
|
||||||
void BOBI2PInboundTunnel::ReceiveAddress (std::shared_ptr<AddressReceiver> receiver)
|
void BOBI2PInboundTunnel::ReceiveAddress (std::shared_ptr<AddressReceiver> receiver)
|
||||||
{
|
{
|
||||||
receiver->socket->async_read_some (boost::asio::buffer(
|
receiver->socket->async_read_some (boost::asio::buffer(
|
||||||
receiver->buffer + receiver->bufferOffset,
|
receiver->buffer + receiver->bufferOffset,
|
||||||
BOB_COMMAND_BUFFER_SIZE - receiver->bufferOffset),
|
BOB_COMMAND_BUFFER_SIZE - receiver->bufferOffset),
|
||||||
std::bind(&BOBI2PInboundTunnel::HandleReceivedAddress, this,
|
std::bind(&BOBI2PInboundTunnel::HandleReceivedAddress, this,
|
||||||
std::placeholders::_1, std::placeholders::_2, receiver));
|
std::placeholders::_1, std::placeholders::_2, receiver));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BOBI2PInboundTunnel::HandleReceivedAddress (const boost::system::error_code& ecode, std::size_t bytes_transferred,
|
void BOBI2PInboundTunnel::HandleReceivedAddress (const boost::system::error_code& ecode, std::size_t bytes_transferred,
|
||||||
|
@ -437,7 +437,7 @@ namespace client
|
||||||
if (!m_CurrentDestination)
|
if (!m_CurrentDestination)
|
||||||
{
|
{
|
||||||
m_CurrentDestination = new BOBDestination (i2p::client::context.CreateNewLocalDestination (m_Keys, true, &m_Options), // deleted in clear command
|
m_CurrentDestination = new BOBDestination (i2p::client::context.CreateNewLocalDestination (m_Keys, true, &m_Options), // deleted in clear command
|
||||||
m_Nickname, m_InHost, m_OutHost, m_InPort, m_OutPort, m_IsQuiet);
|
m_Nickname, m_InHost, m_OutHost, m_InPort, m_OutPort, m_IsQuiet);
|
||||||
m_Owner.AddDestination (m_Nickname, m_CurrentDestination);
|
m_Owner.AddDestination (m_Nickname, m_CurrentDestination);
|
||||||
}
|
}
|
||||||
if (m_InPort)
|
if (m_InPort)
|
||||||
|
@ -624,14 +624,13 @@ namespace client
|
||||||
}
|
}
|
||||||
// trying to request
|
// trying to request
|
||||||
auto s = shared_from_this ();
|
auto s = shared_from_this ();
|
||||||
auto requstCallback =
|
auto requstCallback = [s](std::shared_ptr<i2p::data::LeaseSet> ls)
|
||||||
[s](std::shared_ptr<i2p::data::LeaseSet> ls)
|
{
|
||||||
{
|
if (ls)
|
||||||
if (ls)
|
s->SendReplyOK (ls->GetIdentity ()->ToBase64 ().c_str ());
|
||||||
s->SendReplyOK (ls->GetIdentity ()->ToBase64 ().c_str ());
|
else
|
||||||
else
|
s->SendReplyError ("LeaseSet Not found");
|
||||||
s->SendReplyError ("LeaseSet Not found");
|
};
|
||||||
};
|
|
||||||
if (addr->IsIdentHash ())
|
if (addr->IsIdentHash ())
|
||||||
localDestination->RequestDestination (addr->identHash, requstCallback);
|
localDestination->RequestDestination (addr->identHash, requstCallback);
|
||||||
else
|
else
|
||||||
|
@ -856,8 +855,7 @@ namespace client
|
||||||
session->SendVersion ();
|
session->SendVersion ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "BOB: accept error: ", ecode.message ());
|
LogPrint (eLogError, "BOB: accept error: ", ecode.message ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,15 +75,15 @@ namespace client
|
||||||
|
|
||||||
class BOBI2PInboundTunnel: public BOBI2PTunnel
|
class BOBI2PInboundTunnel: public BOBI2PTunnel
|
||||||
{
|
{
|
||||||
struct AddressReceiver
|
struct AddressReceiver
|
||||||
{
|
{
|
||||||
std::shared_ptr<boost::asio::ip::tcp::socket> socket;
|
std::shared_ptr<boost::asio::ip::tcp::socket> socket;
|
||||||
char buffer[BOB_COMMAND_BUFFER_SIZE + 1]; // for destination base64 address
|
char buffer[BOB_COMMAND_BUFFER_SIZE + 1]; // for destination base64 address
|
||||||
uint8_t * data; // pointer to buffer
|
uint8_t * data; // pointer to buffer
|
||||||
size_t dataLen, bufferOffset;
|
size_t dataLen, bufferOffset;
|
||||||
|
|
||||||
AddressReceiver (): data (nullptr), dataLen (0), bufferOffset (0) {};
|
AddressReceiver (): data (nullptr), dataLen (0), bufferOffset (0) {};
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@ namespace client
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
BOBI2POutboundTunnel (const std::string& outhost, int port, std::shared_ptr<ClientDestination> localDestination, bool quiet);
|
BOBI2POutboundTunnel (const std::string& outhost, int port, std::shared_ptr<ClientDestination> localDestination, bool quiet);
|
||||||
|
|
||||||
void Start ();
|
void Start ();
|
||||||
void Stop ();
|
void Stop ();
|
||||||
|
@ -222,7 +222,7 @@ namespace client
|
||||||
|
|
||||||
BOBCommandChannel& m_Owner;
|
BOBCommandChannel& m_Owner;
|
||||||
boost::asio::ip::tcp::socket m_Socket;
|
boost::asio::ip::tcp::socket m_Socket;
|
||||||
boost::asio::streambuf m_ReceiveBuffer, m_SendBuffer;
|
boost::asio::streambuf m_ReceiveBuffer, m_SendBuffer;
|
||||||
bool m_IsOpen, m_IsQuiet, m_IsActive;
|
bool m_IsOpen, m_IsQuiet, m_IsActive;
|
||||||
std::string m_Nickname, m_InHost, m_OutHost;
|
std::string m_Nickname, m_InHost, m_OutHost;
|
||||||
int m_InPort, m_OutPort;
|
int m_InPort, m_OutPort;
|
||||||
|
@ -269,4 +269,3 @@ namespace client
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ namespace client
|
||||||
{
|
{
|
||||||
std::string samAddr; i2p::config::GetOption("sam.address", samAddr);
|
std::string samAddr; i2p::config::GetOption("sam.address", samAddr);
|
||||||
uint16_t samPort; i2p::config::GetOption("sam.port", samPort);
|
uint16_t samPort; i2p::config::GetOption("sam.port", samPort);
|
||||||
bool singleThread; i2p::config::GetOption("sam.singlethread", singleThread);
|
bool singleThread; i2p::config::GetOption("sam.singlethread", singleThread);
|
||||||
LogPrint(eLogInfo, "Clients: starting SAM bridge at ", samAddr, ":", samPort);
|
LogPrint(eLogInfo, "Clients: starting SAM bridge at ", samAddr, ":", samPort);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -407,13 +407,13 @@ namespace client
|
||||||
template<typename Section, typename Type>
|
template<typename Section, typename Type>
|
||||||
std::string ClientContext::GetI2CPOption (const Section& section, const std::string& name, const Type& value) const
|
std::string ClientContext::GetI2CPOption (const Section& section, const std::string& name, const Type& value) const
|
||||||
{
|
{
|
||||||
return section.second.get (boost::property_tree::ptree::path_type (name, '/'), std::to_string (value));
|
return section.second.get (boost::property_tree::ptree::path_type (name, '/'), std::to_string (value));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Section>
|
template<typename Section>
|
||||||
std::string ClientContext::GetI2CPStringOption (const Section& section, const std::string& name, const std::string& value) const
|
std::string ClientContext::GetI2CPStringOption (const Section& section, const std::string& name, const std::string& value) const
|
||||||
{
|
{
|
||||||
return section.second.get (boost::property_tree::ptree::path_type (name, '/'), value);
|
return section.second.get (boost::property_tree::ptree::path_type (name, '/'), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Section>
|
template<typename Section>
|
||||||
|
@ -429,7 +429,7 @@ namespace client
|
||||||
template<typename Section>
|
template<typename Section>
|
||||||
void ClientContext::ReadI2CPOptions (const Section& section, std::map<std::string, std::string>& options) const
|
void ClientContext::ReadI2CPOptions (const Section& section, std::map<std::string, std::string>& options) const
|
||||||
{
|
{
|
||||||
options[I2CP_PARAM_INBOUND_TUNNEL_LENGTH] = GetI2CPOption (section, I2CP_PARAM_INBOUND_TUNNEL_LENGTH, DEFAULT_INBOUND_TUNNEL_LENGTH);
|
options[I2CP_PARAM_INBOUND_TUNNEL_LENGTH] = GetI2CPOption (section, I2CP_PARAM_INBOUND_TUNNEL_LENGTH, DEFAULT_INBOUND_TUNNEL_LENGTH);
|
||||||
options[I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH] = GetI2CPOption (section, I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH, DEFAULT_OUTBOUND_TUNNEL_LENGTH);
|
options[I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH] = GetI2CPOption (section, I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH, DEFAULT_OUTBOUND_TUNNEL_LENGTH);
|
||||||
options[I2CP_PARAM_INBOUND_TUNNELS_QUANTITY] = GetI2CPOption (section, I2CP_PARAM_INBOUND_TUNNELS_QUANTITY, DEFAULT_INBOUND_TUNNELS_QUANTITY);
|
options[I2CP_PARAM_INBOUND_TUNNELS_QUANTITY] = GetI2CPOption (section, I2CP_PARAM_INBOUND_TUNNELS_QUANTITY, DEFAULT_INBOUND_TUNNELS_QUANTITY);
|
||||||
options[I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY] = GetI2CPOption (section, I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY, DEFAULT_OUTBOUND_TUNNELS_QUANTITY);
|
options[I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY] = GetI2CPOption (section, I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY, DEFAULT_OUTBOUND_TUNNELS_QUANTITY);
|
||||||
|
@ -528,10 +528,10 @@ namespace client
|
||||||
{
|
{
|
||||||
std::string type = section.second.get<std::string> (I2P_TUNNELS_SECTION_TYPE);
|
std::string type = section.second.get<std::string> (I2P_TUNNELS_SECTION_TYPE);
|
||||||
if (type == I2P_TUNNELS_SECTION_TYPE_CLIENT
|
if (type == I2P_TUNNELS_SECTION_TYPE_CLIENT
|
||||||
|| type == I2P_TUNNELS_SECTION_TYPE_SOCKS
|
|| type == I2P_TUNNELS_SECTION_TYPE_SOCKS
|
||||||
|| type == I2P_TUNNELS_SECTION_TYPE_WEBSOCKS
|
|| type == I2P_TUNNELS_SECTION_TYPE_WEBSOCKS
|
||||||
|| type == I2P_TUNNELS_SECTION_TYPE_HTTPPROXY
|
|| type == I2P_TUNNELS_SECTION_TYPE_HTTPPROXY
|
||||||
|| type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT)
|
|| type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT)
|
||||||
{
|
{
|
||||||
// mandatory params
|
// mandatory params
|
||||||
std::string dest;
|
std::string dest;
|
||||||
|
@ -640,9 +640,9 @@ namespace client
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == I2P_TUNNELS_SECTION_TYPE_SERVER
|
else if (type == I2P_TUNNELS_SECTION_TYPE_SERVER
|
||||||
|| type == I2P_TUNNELS_SECTION_TYPE_HTTP
|
|| type == I2P_TUNNELS_SECTION_TYPE_HTTP
|
||||||
|| type == I2P_TUNNELS_SECTION_TYPE_IRC
|
|| type == I2P_TUNNELS_SECTION_TYPE_IRC
|
||||||
|| type == I2P_TUNNELS_SECTION_TYPE_UDPSERVER)
|
|| type == I2P_TUNNELS_SECTION_TYPE_UDPSERVER)
|
||||||
{
|
{
|
||||||
// mandatory params
|
// mandatory params
|
||||||
std::string host = section.second.get<std::string> (I2P_SERVER_TUNNEL_HOST);
|
std::string host = section.second.get<std::string> (I2P_SERVER_TUNNEL_HOST);
|
||||||
|
@ -699,7 +699,7 @@ namespace client
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<I2PServerTunnel> serverTunnel;
|
std::shared_ptr<I2PServerTunnel> serverTunnel;
|
||||||
if (type == I2P_TUNNELS_SECTION_TYPE_HTTP)
|
if (type == I2P_TUNNELS_SECTION_TYPE_HTTP)
|
||||||
serverTunnel = std::make_shared<I2PServerTunnelHTTP> (name, host, port, localDestination, hostOverride, inPort, gzip);
|
serverTunnel = std::make_shared<I2PServerTunnelHTTP> (name, host, port, localDestination, hostOverride, inPort, gzip);
|
||||||
else if (type == I2P_TUNNELS_SECTION_TYPE_IRC)
|
else if (type == I2P_TUNNELS_SECTION_TYPE_IRC)
|
||||||
|
@ -745,7 +745,7 @@ namespace client
|
||||||
ins.first->second->SetLocalDestination (serverTunnel->GetLocalDestination ());
|
ins.first->second->SetLocalDestination (serverTunnel->GetLocalDestination ());
|
||||||
}
|
}
|
||||||
ins.first->second->isUpdated = true;
|
ins.first->second->isUpdated = true;
|
||||||
LogPrint (eLogInfo, "Clients: I2P server tunnel for destination/port ", m_AddressBook.ToAddress(localDestination->GetIdentHash ()), "/", inPort, " already exists");
|
LogPrint (eLogInfo, "Clients: I2P server tunnel for destination/port ", m_AddressBook.ToAddress(localDestination->GetIdentHash ()), "/", inPort, " already exists");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -769,9 +769,9 @@ namespace client
|
||||||
std::string httpProxyKeys; i2p::config::GetOption("httpproxy.keys", httpProxyKeys);
|
std::string httpProxyKeys; i2p::config::GetOption("httpproxy.keys", httpProxyKeys);
|
||||||
std::string httpProxyAddr; i2p::config::GetOption("httpproxy.address", httpProxyAddr);
|
std::string httpProxyAddr; i2p::config::GetOption("httpproxy.address", httpProxyAddr);
|
||||||
uint16_t httpProxyPort; i2p::config::GetOption("httpproxy.port", httpProxyPort);
|
uint16_t httpProxyPort; i2p::config::GetOption("httpproxy.port", httpProxyPort);
|
||||||
i2p::data::SigningKeyType sigType; i2p::config::GetOption("httpproxy.signaturetype", sigType);
|
|
||||||
std::string httpOutProxyURL; i2p::config::GetOption("httpproxy.outproxy", httpOutProxyURL);
|
std::string httpOutProxyURL; i2p::config::GetOption("httpproxy.outproxy", httpOutProxyURL);
|
||||||
bool httpAddresshelper; i2p::config::GetOption("httpproxy.addresshelper", httpAddresshelper);
|
bool httpAddresshelper; i2p::config::GetOption("httpproxy.addresshelper", httpAddresshelper);
|
||||||
|
i2p::data::SigningKeyType sigType; i2p::config::GetOption("httpproxy.signaturetype", sigType);
|
||||||
LogPrint(eLogInfo, "Clients: starting HTTP Proxy at ", httpProxyAddr, ":", httpProxyPort);
|
LogPrint(eLogInfo, "Clients: starting HTTP Proxy at ", httpProxyAddr, ":", httpProxyPort);
|
||||||
if (httpProxyKeys.length () > 0)
|
if (httpProxyKeys.length () > 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -78,7 +78,8 @@ namespace client
|
||||||
std::shared_ptr<ClientDestination> CreateNewLocalDestination (boost::asio::io_service& service,
|
std::shared_ptr<ClientDestination> CreateNewLocalDestination (boost::asio::io_service& service,
|
||||||
const i2p::data::PrivateKeys& keys, bool isPublic = true,
|
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
|
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);
|
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);
|
void DeleteLocalDestination (std::shared_ptr<ClientDestination> destination);
|
||||||
std::shared_ptr<ClientDestination> FindLocalDestination (const i2p::data::IdentHash& destination) const;
|
std::shared_ptr<ClientDestination> FindLocalDestination (const i2p::data::IdentHash& destination) const;
|
||||||
bool LoadPrivateKeys (i2p::data::PrivateKeys& keys, const std::string& filename,
|
bool LoadPrivateKeys (i2p::data::PrivateKeys& keys, const std::string& filename,
|
||||||
|
@ -141,6 +142,7 @@ namespace client
|
||||||
std::unique_ptr<boost::asio::deadline_timer> m_CleanupUDPTimer;
|
std::unique_ptr<boost::asio::deadline_timer> m_CleanupUDPTimer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// for HTTP
|
// for HTTP
|
||||||
const decltype(m_Destinations)& GetDestinations () const { return m_Destinations; };
|
const decltype(m_Destinations)& GetDestinations () const { return m_Destinations; };
|
||||||
const decltype(m_ClientTunnels)& GetClientTunnels () const { return m_ClientTunnels; };
|
const decltype(m_ClientTunnels)& GetClientTunnels () const { return m_ClientTunnels; };
|
||||||
|
|
|
@ -191,7 +191,7 @@ namespace proxy {
|
||||||
res.body = ss.str();
|
res.body = ss.str();
|
||||||
std::string response = res.to_string();
|
std::string response = res.to_string();
|
||||||
boost::asio::async_write(*m_sock, boost::asio::buffer(response), boost::asio::transfer_all(),
|
boost::asio::async_write(*m_sock, boost::asio::buffer(response), boost::asio::transfer_all(),
|
||||||
std::bind(&HTTPReqHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1));
|
std::bind(&HTTPReqHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HTTPReqHandler::ExtractAddressHelper(i2p::http::URL & url, std::string & b64, bool & confirm)
|
bool HTTPReqHandler::ExtractAddressHelper(i2p::http::URL & url, std::string & b64, bool & confirm)
|
||||||
|
@ -406,7 +406,7 @@ namespace proxy {
|
||||||
void HTTPReqHandler::ForwardToUpstreamProxy()
|
void HTTPReqHandler::ForwardToUpstreamProxy()
|
||||||
{
|
{
|
||||||
LogPrint(eLogDebug, "HTTPProxy: forward to upstream");
|
LogPrint(eLogDebug, "HTTPProxy: forward to upstream");
|
||||||
// build http requset
|
// build http request
|
||||||
|
|
||||||
m_ClientRequestURL = m_RequestURL;
|
m_ClientRequestURL = m_RequestURL;
|
||||||
LogPrint(eLogDebug, "HTTPProxy: ", m_ClientRequestURL.host);
|
LogPrint(eLogDebug, "HTTPProxy: ", m_ClientRequestURL.host);
|
||||||
|
@ -458,7 +458,7 @@ namespace proxy {
|
||||||
if (!m_ProxyURL.port) m_ProxyURL.port = 9050; // default to tor default if not specified
|
if (!m_ProxyURL.port) m_ProxyURL.port = 9050; // default to tor default if not specified
|
||||||
boost::asio::ip::tcp::resolver::query q(m_ProxyURL.host, std::to_string(m_ProxyURL.port));
|
boost::asio::ip::tcp::resolver::query q(m_ProxyURL.host, std::to_string(m_ProxyURL.port));
|
||||||
m_proxy_resolver.async_resolve(q, std::bind(&HTTPReqHandler::HandleUpstreamProxyResolved, this, std::placeholders::_1, std::placeholders::_2, [&](boost::asio::ip::tcp::endpoint ep) {
|
m_proxy_resolver.async_resolve(q, std::bind(&HTTPReqHandler::HandleUpstreamProxyResolved, this, std::placeholders::_1, std::placeholders::_2, [&](boost::asio::ip::tcp::endpoint ep) {
|
||||||
m_proxysock->async_connect(ep, std::bind(&HTTPReqHandler::HandleUpstreamSocksProxyConnect, this, std::placeholders::_1));
|
m_proxysock->async_connect(ep, std::bind(&HTTPReqHandler::HandleUpstreamSocksProxyConnect, this, std::placeholders::_1));
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -562,14 +562,16 @@ namespace proxy {
|
||||||
if(m_ClientRequest.method == "CONNECT") {
|
if(m_ClientRequest.method == "CONNECT") {
|
||||||
m_ClientResponse.code = 200;
|
m_ClientResponse.code = 200;
|
||||||
m_send_buf = m_ClientResponse.to_string();
|
m_send_buf = m_ClientResponse.to_string();
|
||||||
boost::asio::async_write(*m_sock, boost::asio::buffer(m_send_buf), boost::asio::transfer_all(), [&] (const boost::system::error_code & ec, std::size_t transferred) {
|
boost::asio::async_write(*m_sock, boost::asio::buffer(m_send_buf), boost::asio::transfer_all(), [&] (const boost::system::error_code & ec, std::size_t transferred)
|
||||||
|
{
|
||||||
if(ec) GenericProxyError("socks proxy error", ec.message().c_str());
|
if(ec) GenericProxyError("socks proxy error", ec.message().c_str());
|
||||||
else HandoverToUpstreamProxy();
|
else HandoverToUpstreamProxy();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
m_send_buf = m_ClientRequestBuffer.str();
|
m_send_buf = m_ClientRequestBuffer.str();
|
||||||
LogPrint(eLogDebug, "HTTPProxy: send ", m_send_buf.size(), " bytes");
|
LogPrint(eLogDebug, "HTTPProxy: send ", m_send_buf.size(), " bytes");
|
||||||
boost::asio::async_write(*m_proxysock, boost::asio::buffer(m_send_buf), boost::asio::transfer_all(), [&](const boost::system::error_code & ec, std::size_t transferred) {
|
boost::asio::async_write(*m_proxysock, boost::asio::buffer(m_send_buf), boost::asio::transfer_all(), [&](const boost::system::error_code & ec, std::size_t transferred)
|
||||||
|
{
|
||||||
if(ec) GenericProxyError("failed to send request to upstream", ec.message().c_str());
|
if(ec) GenericProxyError("failed to send request to upstream", ec.message().c_str());
|
||||||
else HandoverToUpstreamProxy();
|
else HandoverToUpstreamProxy();
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,6 +6,7 @@ namespace proxy {
|
||||||
class HTTPProxy: public i2p::client::TCPIPAcceptor
|
class HTTPProxy: public i2p::client::TCPIPAcceptor
|
||||||
{
|
{
|
||||||
public:
|
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, 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(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(name, address, port, "", true, localDestination) {} ;
|
||||||
|
@ -15,11 +16,13 @@ namespace proxy {
|
||||||
bool GetHelperSupport() { return m_Addresshelper; }
|
bool GetHelperSupport() { return m_Addresshelper; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Implements TCPIPAcceptor
|
// Implements TCPIPAcceptor
|
||||||
std::shared_ptr<i2p::client::I2PServiceHandler> CreateHandler(std::shared_ptr<boost::asio::ip::tcp::socket> socket);
|
std::shared_ptr<i2p::client::I2PServiceHandler> CreateHandler(std::shared_ptr<boost::asio::ip::tcp::socket> socket);
|
||||||
const char* GetName() { return m_Name.c_str (); }
|
const char* GetName() { return m_Name.c_str (); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::string m_Name;
|
std::string m_Name;
|
||||||
std::string m_OutproxyUrl;
|
std::string m_OutproxyUrl;
|
||||||
bool m_Addresshelper;
|
bool m_Addresshelper;
|
||||||
|
|
|
@ -221,7 +221,7 @@ namespace client
|
||||||
auto s = shared_from_this ();
|
auto s = shared_from_this ();
|
||||||
m_Socket->async_read_some (boost::asio::buffer (m_Header, 1),
|
m_Socket->async_read_some (boost::asio::buffer (m_Header, 1),
|
||||||
[s](const boost::system::error_code& ecode, std::size_t bytes_transferred)
|
[s](const boost::system::error_code& ecode, std::size_t bytes_transferred)
|
||||||
{
|
{
|
||||||
if (!ecode && bytes_transferred > 0 && s->m_Header[0] == I2CP_PROTOCOL_BYTE)
|
if (!ecode && bytes_transferred > 0 && s->m_Header[0] == I2CP_PROTOCOL_BYTE)
|
||||||
s->ReceiveHeader ();
|
s->ReceiveHeader ();
|
||||||
else
|
else
|
||||||
|
@ -323,7 +323,7 @@ namespace client
|
||||||
memcpy (buf + I2CP_HEADER_SIZE, payload, len);
|
memcpy (buf + I2CP_HEADER_SIZE, payload, len);
|
||||||
boost::asio::async_write (*socket, boost::asio::buffer (buf, l), boost::asio::transfer_all (),
|
boost::asio::async_write (*socket, boost::asio::buffer (buf, l), boost::asio::transfer_all (),
|
||||||
std::bind(&I2CPSession::HandleI2CPMessageSent, shared_from_this (),
|
std::bind(&I2CPSession::HandleI2CPMessageSent, shared_from_this (),
|
||||||
std::placeholders::_1, std::placeholders::_2, buf));
|
std::placeholders::_1, std::placeholders::_2, buf));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "I2CP: Can't write to the socket");
|
LogPrint (eLogError, "I2CP: Can't write to the socket");
|
||||||
|
@ -779,14 +779,14 @@ namespace client
|
||||||
memcpy (buf + I2CP_HEADER_SIZE + 10, payload, len);
|
memcpy (buf + I2CP_HEADER_SIZE + 10, payload, len);
|
||||||
boost::asio::async_write (*m_Socket, boost::asio::buffer (buf, l), boost::asio::transfer_all (),
|
boost::asio::async_write (*m_Socket, boost::asio::buffer (buf, l), boost::asio::transfer_all (),
|
||||||
std::bind(&I2CPSession::HandleI2CPMessageSent, shared_from_this (),
|
std::bind(&I2CPSession::HandleI2CPMessageSent, shared_from_this (),
|
||||||
std::placeholders::_1, std::placeholders::_2, buf));
|
std::placeholders::_1, std::placeholders::_2, buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
I2CPServer::I2CPServer (const std::string& interface, int port):
|
I2CPServer::I2CPServer (const std::string& interface, int port):
|
||||||
m_IsRunning (false), m_Thread (nullptr),
|
m_IsRunning (false), m_Thread (nullptr),
|
||||||
m_Acceptor (m_Service,
|
m_Acceptor (m_Service,
|
||||||
#ifdef ANDROID
|
#ifdef ANDROID
|
||||||
I2CPSession::proto::endpoint(std::string (1, '\0') + interface)) // leading 0 for abstract address
|
I2CPSession::proto::endpoint(std::string (1, '\0') + interface)) // leading 0 for abstract address
|
||||||
#else
|
#else
|
||||||
I2CPSession::proto::endpoint(boost::asio::ip::address::from_string(interface), port))
|
I2CPSession::proto::endpoint(boost::asio::ip::address::from_string(interface), port))
|
||||||
#endif
|
#endif
|
||||||
|
@ -899,4 +899,3 @@ namespace client
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -220,4 +220,3 @@ namespace client
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -115,14 +115,16 @@ namespace client
|
||||||
{
|
{
|
||||||
if(m_ConnectTimeout && !m_LocalDestination->IsReady())
|
if(m_ConnectTimeout && !m_LocalDestination->IsReady())
|
||||||
{
|
{
|
||||||
AddReadyCallback([this, streamRequestComplete, address, port] (const boost::system::error_code & ec) {
|
AddReadyCallback([this, streamRequestComplete, address, port] (const boost::system::error_code & ec)
|
||||||
|
{
|
||||||
if(ec)
|
if(ec)
|
||||||
{
|
{
|
||||||
LogPrint(eLogWarning, "I2PService::CreateStream() ", ec.message());
|
LogPrint(eLogWarning, "I2PService::CreateStream() ", ec.message());
|
||||||
streamRequestComplete(nullptr);
|
streamRequestComplete(nullptr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ if (address->IsIdentHash ())
|
{
|
||||||
|
if (address->IsIdentHash ())
|
||||||
this->m_LocalDestination->CreateStream(streamRequestComplete, address->identHash, port);
|
this->m_LocalDestination->CreateStream(streamRequestComplete, address->identHash, port);
|
||||||
else
|
else
|
||||||
this->m_LocalDestination->CreateStream (streamRequestComplete, address->blindedPublicKey, port);
|
this->m_LocalDestination->CreateStream (streamRequestComplete, address->blindedPublicKey, port);
|
||||||
|
@ -180,7 +182,7 @@ namespace client
|
||||||
{
|
{
|
||||||
m_up->async_read_some(boost::asio::buffer(m_upstream_to_down_buf, TCP_IP_PIPE_BUFFER_SIZE),
|
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::bind(&TCPIPPipe::HandleUpstreamReceived, shared_from_this(),
|
||||||
std::placeholders::_1, std::placeholders::_2));
|
std::placeholders::_1, std::placeholders::_2));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint(eLogError, "TCPIPPipe: upstream receive: no socket");
|
LogPrint(eLogError, "TCPIPPipe: upstream receive: no socket");
|
||||||
|
@ -191,7 +193,7 @@ namespace client
|
||||||
if (m_down) {
|
if (m_down) {
|
||||||
m_down->async_read_some(boost::asio::buffer(m_downstream_to_up_buf, TCP_IP_PIPE_BUFFER_SIZE),
|
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::bind(&TCPIPPipe::HandleDownstreamReceived, shared_from_this(),
|
||||||
std::placeholders::_1, std::placeholders::_2));
|
std::placeholders::_1, std::placeholders::_2));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint(eLogError, "TCPIPPipe: downstream receive: no socket");
|
LogPrint(eLogError, "TCPIPPipe: downstream receive: no socket");
|
||||||
|
@ -205,8 +207,8 @@ namespace client
|
||||||
boost::asio::async_write(*m_up, boost::asio::buffer(m_upstream_buf, len),
|
boost::asio::async_write(*m_up, boost::asio::buffer(m_upstream_buf, len),
|
||||||
boost::asio::transfer_all(),
|
boost::asio::transfer_all(),
|
||||||
std::bind(&TCPIPPipe::HandleUpstreamWrite,
|
std::bind(&TCPIPPipe::HandleUpstreamWrite,
|
||||||
shared_from_this(),
|
shared_from_this(),
|
||||||
std::placeholders::_1));
|
std::placeholders::_1));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint(eLogError, "TCPIPPipe: upstream write: no socket");
|
LogPrint(eLogError, "TCPIPPipe: upstream write: no socket");
|
||||||
|
@ -220,8 +222,8 @@ namespace client
|
||||||
boost::asio::async_write(*m_down, boost::asio::buffer(m_downstream_buf, len),
|
boost::asio::async_write(*m_down, boost::asio::buffer(m_downstream_buf, len),
|
||||||
boost::asio::transfer_all(),
|
boost::asio::transfer_all(),
|
||||||
std::bind(&TCPIPPipe::HandleDownstreamWrite,
|
std::bind(&TCPIPPipe::HandleDownstreamWrite,
|
||||||
shared_from_this(),
|
shared_from_this(),
|
||||||
std::placeholders::_1));
|
std::placeholders::_1));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint(eLogError, "TCPIPPipe: downstream write: no socket");
|
LogPrint(eLogError, "TCPIPPipe: downstream write: no socket");
|
||||||
|
|
|
@ -18,10 +18,12 @@ namespace client
|
||||||
class I2PService : public std::enable_shared_from_this<I2PService>
|
class I2PService : public std::enable_shared_from_this<I2PService>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef std::function<void(const boost::system::error_code &)> ReadyCallback;
|
typedef std::function<void(const boost::system::error_code &)> ReadyCallback;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
I2PService (std::shared_ptr<ClientDestination> localDestination = nullptr);
|
|
||||||
|
I2PService (std::shared_ptr<ClientDestination> localDestination = nullptr);
|
||||||
I2PService (i2p::data::SigningKeyType kt);
|
I2PService (i2p::data::SigningKeyType kt);
|
||||||
virtual ~I2PService ();
|
virtual ~I2PService ();
|
||||||
|
|
||||||
|
@ -42,7 +44,7 @@ namespace client
|
||||||
void AddReadyCallback(ReadyCallback cb);
|
void AddReadyCallback(ReadyCallback cb);
|
||||||
|
|
||||||
inline std::shared_ptr<ClientDestination> GetLocalDestination () { return m_LocalDestination; }
|
inline std::shared_ptr<ClientDestination> GetLocalDestination () { return m_LocalDestination; }
|
||||||
inline std::shared_ptr<const ClientDestination> GetLocalDestination () const { return m_LocalDestination; }
|
inline std::shared_ptr<const ClientDestination> GetLocalDestination () const { return m_LocalDestination; }
|
||||||
inline void SetLocalDestination (std::shared_ptr<ClientDestination> dest)
|
inline void SetLocalDestination (std::shared_ptr<ClientDestination> dest)
|
||||||
{
|
{
|
||||||
if (m_LocalDestination) m_LocalDestination->Release ();
|
if (m_LocalDestination) m_LocalDestination->Release ();
|
||||||
|
@ -59,21 +61,24 @@ namespace client
|
||||||
virtual const char* GetName() { return "Generic I2P Service"; }
|
virtual const char* GetName() { return "Generic I2P Service"; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void TriggerReadyCheckTimer();
|
void TriggerReadyCheckTimer();
|
||||||
void HandleReadyCheckTimer(const boost::system::error_code & ec);
|
void HandleReadyCheckTimer(const boost::system::error_code & ec);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::shared_ptr<ClientDestination> m_LocalDestination;
|
std::shared_ptr<ClientDestination> m_LocalDestination;
|
||||||
std::unordered_set<std::shared_ptr<I2PServiceHandler> > m_Handlers;
|
std::unordered_set<std::shared_ptr<I2PServiceHandler> > m_Handlers;
|
||||||
std::mutex m_HandlersMutex;
|
std::mutex m_HandlersMutex;
|
||||||
std::vector<std::pair<ReadyCallback, uint32_t> > m_ReadyCallbacks;
|
std::vector<std::pair<ReadyCallback, uint32_t> > m_ReadyCallbacks;
|
||||||
boost::asio::deadline_timer m_ReadyTimer;
|
boost::asio::deadline_timer m_ReadyTimer;
|
||||||
bool m_ReadyTimerTriggered;
|
bool m_ReadyTimerTriggered;
|
||||||
uint32_t m_ConnectTimeout;
|
uint32_t m_ConnectTimeout;
|
||||||
|
|
||||||
const size_t NEVER_TIMES_OUT = 0;
|
const size_t NEVER_TIMES_OUT = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
bool isUpdated; // transient, used during reload only
|
bool isUpdated; // transient, used during reload only
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -81,6 +86,7 @@ namespace client
|
||||||
class I2PServiceHandler
|
class I2PServiceHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
I2PServiceHandler(I2PService * parent) : m_Service(parent), m_Dead(false) { }
|
I2PServiceHandler(I2PService * parent) : m_Service(parent), m_Dead(false) { }
|
||||||
virtual ~I2PServiceHandler() { }
|
virtual ~I2PServiceHandler() { }
|
||||||
//If you override this make sure you call it from the children
|
//If you override this make sure you call it from the children
|
||||||
|
@ -89,6 +95,7 @@ namespace client
|
||||||
void Terminate () { Kill (); };
|
void Terminate () { Kill (); };
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Call when terminating or handing over to avoid race conditions
|
// Call when terminating or handing over to avoid race conditions
|
||||||
inline bool Kill () { return m_Dead.exchange(true); }
|
inline bool Kill () { return m_Dead.exchange(true); }
|
||||||
// Call to know if the handler is dead
|
// Call to know if the handler is dead
|
||||||
|
@ -99,6 +106,7 @@ namespace client
|
||||||
inline I2PService * GetOwner() { return m_Service; }
|
inline I2PService * GetOwner() { return m_Service; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
I2PService *m_Service;
|
I2PService *m_Service;
|
||||||
std::atomic<bool> m_Dead; //To avoid cleaning up multiple times
|
std::atomic<bool> m_Dead; //To avoid cleaning up multiple times
|
||||||
};
|
};
|
||||||
|
@ -109,11 +117,13 @@ namespace client
|
||||||
class TCPIPPipe: public I2PServiceHandler, public std::enable_shared_from_this<TCPIPPipe>
|
class TCPIPPipe: public I2PServiceHandler, public std::enable_shared_from_this<TCPIPPipe>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
TCPIPPipe(I2PService * owner, std::shared_ptr<boost::asio::ip::tcp::socket> upstream, std::shared_ptr<boost::asio::ip::tcp::socket> downstream);
|
TCPIPPipe(I2PService * owner, std::shared_ptr<boost::asio::ip::tcp::socket> upstream, std::shared_ptr<boost::asio::ip::tcp::socket> downstream);
|
||||||
~TCPIPPipe();
|
~TCPIPPipe();
|
||||||
void Start();
|
void Start();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void Terminate();
|
void Terminate();
|
||||||
void AsyncReceiveUpstream();
|
void AsyncReceiveUpstream();
|
||||||
void AsyncReceiveDownstream();
|
void AsyncReceiveDownstream();
|
||||||
|
@ -125,6 +135,7 @@ namespace client
|
||||||
void DownstreamWrite(size_t len);
|
void DownstreamWrite(size_t len);
|
||||||
|
|
||||||
private:
|
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_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];
|
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;
|
std::shared_ptr<boost::asio::ip::tcp::socket> m_up, m_down;
|
||||||
|
@ -135,6 +146,7 @@ namespace client
|
||||||
class TCPIPAcceptor: public I2PService
|
class TCPIPAcceptor: public I2PService
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
TCPIPAcceptor (const std::string& address, int port, std::shared_ptr<ClientDestination> localDestination = nullptr) :
|
TCPIPAcceptor (const std::string& address, int port, std::shared_ptr<ClientDestination> localDestination = nullptr) :
|
||||||
I2PService(localDestination),
|
I2PService(localDestination),
|
||||||
m_LocalEndpoint (boost::asio::ip::address::from_string(address), port),
|
m_LocalEndpoint (boost::asio::ip::address::from_string(address), port),
|
||||||
|
@ -149,14 +161,16 @@ namespace client
|
||||||
//If you override this make sure you call it from the children
|
//If you override this make sure you call it from the children
|
||||||
void Stop ();
|
void Stop ();
|
||||||
|
|
||||||
const boost::asio::ip::tcp::endpoint& GetLocalEndpoint () const { return m_LocalEndpoint; };
|
const boost::asio::ip::tcp::endpoint& GetLocalEndpoint () const { return m_LocalEndpoint; };
|
||||||
|
|
||||||
virtual const char* GetName() { return "Generic TCP/IP accepting daemon"; }
|
virtual const char* GetName() { return "Generic TCP/IP accepting daemon"; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual std::shared_ptr<I2PServiceHandler> CreateHandler(std::shared_ptr<boost::asio::ip::tcp::socket> socket) = 0;
|
virtual std::shared_ptr<I2PServiceHandler> CreateHandler(std::shared_ptr<boost::asio::ip::tcp::socket> socket) = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void Accept();
|
void Accept();
|
||||||
void HandleAccept(const boost::system::error_code& ecode, std::shared_ptr<boost::asio::ip::tcp::socket> socket);
|
void HandleAccept(const boost::system::error_code& ecode, std::shared_ptr<boost::asio::ip::tcp::socket> socket);
|
||||||
boost::asio::ip::tcp::endpoint m_LocalEndpoint;
|
boost::asio::ip::tcp::endpoint m_LocalEndpoint;
|
||||||
|
|
|
@ -168,7 +168,7 @@ namespace client
|
||||||
{
|
{
|
||||||
m_Stream->AsyncReceive (boost::asio::buffer (m_StreamBuffer, I2P_TUNNEL_CONNECTION_BUFFER_SIZE),
|
m_Stream->AsyncReceive (boost::asio::buffer (m_StreamBuffer, I2P_TUNNEL_CONNECTION_BUFFER_SIZE),
|
||||||
std::bind (&I2PTunnelConnection::HandleStreamReceive, shared_from_this (),
|
std::bind (&I2PTunnelConnection::HandleStreamReceive, shared_from_this (),
|
||||||
std::placeholders::_1, std::placeholders::_2),
|
std::placeholders::_1, std::placeholders::_2),
|
||||||
I2P_TUNNEL_CONNECTION_MAX_IDLE);
|
I2P_TUNNEL_CONNECTION_MAX_IDLE);
|
||||||
}
|
}
|
||||||
else // closed by peer
|
else // closed by peer
|
||||||
|
@ -281,7 +281,7 @@ namespace client
|
||||||
if (endOfHeader)
|
if (endOfHeader)
|
||||||
{
|
{
|
||||||
if (!m_ConnectionSent) m_OutHeader << "Connection: close\r\n";
|
if (!m_ConnectionSent) m_OutHeader << "Connection: close\r\n";
|
||||||
if (!m_ProxyConnectionSent) m_OutHeader << "Proxy-Connection: close\r\n";
|
if (!m_ProxyConnectionSent) m_OutHeader << "Proxy-Connection: close\r\n";
|
||||||
m_OutHeader << "\r\n"; // end of header
|
m_OutHeader << "\r\n"; // end of header
|
||||||
m_OutHeader << m_InHeader.str ().substr (m_InHeader.tellg ()); // data right after header
|
m_OutHeader << m_InHeader.str ().substr (m_InHeader.tellg ()); // data right after header
|
||||||
m_InHeader.str ("");
|
m_InHeader.str ("");
|
||||||
|
@ -477,7 +477,7 @@ namespace client
|
||||||
{
|
{
|
||||||
auto address = GetAddress ();
|
auto address = GetAddress ();
|
||||||
if (address)
|
if (address)
|
||||||
return std::make_shared<I2PClientTunnelHandler>(this, address, m_DestinationPort, socket);
|
return std::make_shared<I2PClientTunnelHandler>(this, address, m_DestinationPort, socket);
|
||||||
else
|
else
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ namespace client
|
||||||
class I2PTunnelConnection: public I2PServiceHandler, public std::enable_shared_from_this<I2PTunnelConnection>
|
class I2PTunnelConnection: public I2PServiceHandler, public std::enable_shared_from_this<I2PTunnelConnection>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
I2PTunnelConnection (I2PService * owner, std::shared_ptr<boost::asio::ip::tcp::socket> socket,
|
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
|
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,
|
I2PTunnelConnection (I2PService * owner, std::shared_ptr<boost::asio::ip::tcp::socket> socket,
|
||||||
|
@ -41,6 +42,7 @@ namespace client
|
||||||
void Connect (bool isUniqueLocal = true);
|
void Connect (bool isUniqueLocal = true);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void Terminate ();
|
void Terminate ();
|
||||||
|
|
||||||
void Receive ();
|
void Receive ();
|
||||||
|
@ -55,6 +57,7 @@ namespace client
|
||||||
std::shared_ptr<const boost::asio::ip::tcp::socket> GetSocket () const { return m_Socket; };
|
std::shared_ptr<const boost::asio::ip::tcp::socket> GetSocket () const { return m_Socket; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
uint8_t m_Buffer[I2P_TUNNEL_CONNECTION_BUFFER_SIZE], m_StreamBuffer[I2P_TUNNEL_CONNECTION_BUFFER_SIZE];
|
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<boost::asio::ip::tcp::socket> m_Socket;
|
||||||
std::shared_ptr<i2p::stream::Stream> m_Stream;
|
std::shared_ptr<i2p::stream::Stream> m_Stream;
|
||||||
|
@ -65,15 +68,18 @@ namespace client
|
||||||
class I2PClientTunnelConnectionHTTP: public I2PTunnelConnection
|
class I2PClientTunnelConnectionHTTP: public I2PTunnelConnection
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
I2PClientTunnelConnectionHTTP (I2PService * owner, std::shared_ptr<boost::asio::ip::tcp::socket> socket,
|
I2PClientTunnelConnectionHTTP (I2PService * owner, std::shared_ptr<boost::asio::ip::tcp::socket> socket,
|
||||||
std::shared_ptr<i2p::stream::Stream> stream):
|
std::shared_ptr<i2p::stream::Stream> stream):
|
||||||
I2PTunnelConnection (owner, socket, stream), m_HeaderSent (false),
|
I2PTunnelConnection (owner, socket, stream), m_HeaderSent (false),
|
||||||
m_ConnectionSent (false), m_ProxyConnectionSent (false) {};
|
m_ConnectionSent (false), m_ProxyConnectionSent (false) {};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void Write (const uint8_t * buf, size_t len);
|
void Write (const uint8_t * buf, size_t len);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::stringstream m_InHeader, m_OutHeader;
|
std::stringstream m_InHeader, m_OutHeader;
|
||||||
bool m_HeaderSent, m_ConnectionSent, m_ProxyConnectionSent;
|
bool m_HeaderSent, m_ConnectionSent, m_ProxyConnectionSent;
|
||||||
};
|
};
|
||||||
|
@ -81,14 +87,17 @@ namespace client
|
||||||
class I2PServerTunnelConnectionHTTP: public I2PTunnelConnection
|
class I2PServerTunnelConnectionHTTP: public I2PTunnelConnection
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
I2PServerTunnelConnectionHTTP (I2PService * owner, std::shared_ptr<i2p::stream::Stream> stream,
|
I2PServerTunnelConnectionHTTP (I2PService * owner, std::shared_ptr<i2p::stream::Stream> stream,
|
||||||
std::shared_ptr<boost::asio::ip::tcp::socket> socket,
|
std::shared_ptr<boost::asio::ip::tcp::socket> socket,
|
||||||
const boost::asio::ip::tcp::endpoint& target, const std::string& host);
|
const boost::asio::ip::tcp::endpoint& target, const std::string& host);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void Write (const uint8_t * buf, size_t len);
|
void Write (const uint8_t * buf, size_t len);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::string m_Host;
|
std::string m_Host;
|
||||||
std::stringstream m_InHeader, m_OutHeader;
|
std::stringstream m_InHeader, m_OutHeader;
|
||||||
bool m_HeaderSent;
|
bool m_HeaderSent;
|
||||||
|
@ -98,14 +107,17 @@ namespace client
|
||||||
class I2PTunnelConnectionIRC: public I2PTunnelConnection
|
class I2PTunnelConnectionIRC: public I2PTunnelConnection
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
I2PTunnelConnectionIRC (I2PService * owner, std::shared_ptr<i2p::stream::Stream> stream,
|
I2PTunnelConnectionIRC (I2PService * owner, std::shared_ptr<i2p::stream::Stream> stream,
|
||||||
std::shared_ptr<boost::asio::ip::tcp::socket> socket,
|
std::shared_ptr<boost::asio::ip::tcp::socket> socket,
|
||||||
const boost::asio::ip::tcp::endpoint& target, const std::string& m_WebircPass);
|
const boost::asio::ip::tcp::endpoint& target, const std::string& m_WebircPass);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void Write (const uint8_t * buf, size_t len);
|
void Write (const uint8_t * buf, size_t len);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::shared_ptr<const i2p::data::IdentityEx> m_From;
|
std::shared_ptr<const i2p::data::IdentityEx> m_From;
|
||||||
std::stringstream m_OutPacket, m_InPacket;
|
std::stringstream m_OutPacket, m_InPacket;
|
||||||
bool m_NeedsWebIrc;
|
bool m_NeedsWebIrc;
|
||||||
|
@ -116,10 +128,12 @@ namespace client
|
||||||
class I2PClientTunnel: public TCPIPAcceptor
|
class I2PClientTunnel: public TCPIPAcceptor
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Implements TCPIPAcceptor
|
// Implements TCPIPAcceptor
|
||||||
std::shared_ptr<I2PServiceHandler> CreateHandler(std::shared_ptr<boost::asio::ip::tcp::socket> socket);
|
std::shared_ptr<I2PServiceHandler> CreateHandler(std::shared_ptr<boost::asio::ip::tcp::socket> socket);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
I2PClientTunnel (const std::string& name, const std::string& destination,
|
I2PClientTunnel (const std::string& name, const std::string& destination,
|
||||||
const std::string& address, int port, std::shared_ptr<ClientDestination> localDestination, int destinationPort = 0);
|
const std::string& address, int port, std::shared_ptr<ClientDestination> localDestination, int destinationPort = 0);
|
||||||
~I2PClientTunnel () {}
|
~I2PClientTunnel () {}
|
||||||
|
@ -130,9 +144,11 @@ namespace client
|
||||||
const char* GetName() { return m_Name.c_str (); }
|
const char* GetName() { return m_Name.c_str (); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::shared_ptr<const Address> GetAddress ();
|
std::shared_ptr<const Address> GetAddress ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::string m_Name, m_Destination;
|
std::string m_Name, m_Destination;
|
||||||
std::shared_ptr<const Address> m_Address;
|
std::shared_ptr<const Address> m_Address;
|
||||||
int m_DestinationPort;
|
int m_DestinationPort;
|
||||||
|
@ -160,9 +176,9 @@ namespace client
|
||||||
uint8_t m_Buffer[I2P_UDP_MAX_MTU];
|
uint8_t m_Buffer[I2P_UDP_MAX_MTU];
|
||||||
|
|
||||||
UDPSession(boost::asio::ip::udp::endpoint localEndpoint,
|
UDPSession(boost::asio::ip::udp::endpoint localEndpoint,
|
||||||
const std::shared_ptr<i2p::client::ClientDestination> & localDestination,
|
const std::shared_ptr<i2p::client::ClientDestination> & localDestination,
|
||||||
boost::asio::ip::udp::endpoint remote, const i2p::data::IdentHash * ident,
|
boost::asio::ip::udp::endpoint remote, const i2p::data::IdentHash * ident,
|
||||||
uint16_t ourPort, uint16_t theirPort);
|
uint16_t ourPort, uint16_t theirPort);
|
||||||
void HandleReceived(const boost::system::error_code & ecode, std::size_t len);
|
void HandleReceived(const boost::system::error_code & ecode, std::size_t len);
|
||||||
void Receive();
|
void Receive();
|
||||||
};
|
};
|
||||||
|
@ -195,6 +211,7 @@ namespace client
|
||||||
class I2PUDPServerTunnel
|
class I2PUDPServerTunnel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
I2PUDPServerTunnel(const std::string & name,
|
I2PUDPServerTunnel(const std::string & name,
|
||||||
std::shared_ptr<i2p::client::ClientDestination> localDestination,
|
std::shared_ptr<i2p::client::ClientDestination> localDestination,
|
||||||
boost::asio::ip::address localAddress,
|
boost::asio::ip::address localAddress,
|
||||||
|
@ -210,10 +227,12 @@ namespace client
|
||||||
void SetUniqueLocal(bool isUniqueLocal = true) { m_IsUniqueLocal = isUniqueLocal; }
|
void SetUniqueLocal(bool isUniqueLocal = true) { m_IsUniqueLocal = isUniqueLocal; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void HandleRecvFromI2P(const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
|
void HandleRecvFromI2P(const i2p::data::IdentityEx& from, 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);
|
UDPSessionPtr ObtainUDPSession(const i2p::data::IdentityEx& from, uint16_t localPort, uint16_t remotePort);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool m_IsUniqueLocal;
|
bool m_IsUniqueLocal;
|
||||||
const std::string m_Name;
|
const std::string m_Name;
|
||||||
boost::asio::ip::address m_LocalAddress;
|
boost::asio::ip::address m_LocalAddress;
|
||||||
|
@ -226,6 +245,7 @@ namespace client
|
||||||
class I2PUDPClientTunnel
|
class I2PUDPClientTunnel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
I2PUDPClientTunnel(const std::string & name, const std::string &remoteDest,
|
I2PUDPClientTunnel(const std::string & name, const std::string &remoteDest,
|
||||||
boost::asio::ip::udp::endpoint localEndpoint, std::shared_ptr<i2p::client::ClientDestination> localDestination,
|
boost::asio::ip::udp::endpoint localEndpoint, std::shared_ptr<i2p::client::ClientDestination> localDestination,
|
||||||
uint16_t remotePort, bool gzip);
|
uint16_t remotePort, bool gzip);
|
||||||
|
@ -240,6 +260,7 @@ namespace client
|
||||||
void ExpireStale(const uint64_t delta=I2P_UDP_SESSION_TIMEOUT);
|
void ExpireStale(const uint64_t delta=I2P_UDP_SESSION_TIMEOUT);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
typedef std::pair<boost::asio::ip::udp::endpoint, uint64_t> UDPConvo;
|
typedef std::pair<boost::asio::ip::udp::endpoint, uint64_t> UDPConvo;
|
||||||
void RecvFromLocal();
|
void RecvFromLocal();
|
||||||
void HandleRecvFromLocal(const boost::system::error_code & e, std::size_t transferred);
|
void HandleRecvFromLocal(const boost::system::error_code & e, std::size_t transferred);
|
||||||
|
@ -263,6 +284,7 @@ namespace client
|
||||||
class I2PServerTunnel: public I2PService
|
class I2PServerTunnel: public I2PService
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
I2PServerTunnel (const std::string& name, const std::string& address, int port,
|
I2PServerTunnel (const std::string& name, const std::string& address, int port,
|
||||||
std::shared_ptr<ClientDestination> localDestination, int inport = 0, bool gzip = true);
|
std::shared_ptr<ClientDestination> localDestination, int inport = 0, bool gzip = true);
|
||||||
|
|
||||||
|
@ -282,6 +304,7 @@ namespace client
|
||||||
const char* GetName() { return m_Name.c_str (); }
|
const char* GetName() { return m_Name.c_str (); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void HandleResolve (const boost::system::error_code& ecode, boost::asio::ip::tcp::resolver::iterator it,
|
void HandleResolve (const boost::system::error_code& ecode, boost::asio::ip::tcp::resolver::iterator it,
|
||||||
std::shared_ptr<boost::asio::ip::tcp::resolver> resolver);
|
std::shared_ptr<boost::asio::ip::tcp::resolver> resolver);
|
||||||
|
|
||||||
|
@ -290,6 +313,7 @@ namespace client
|
||||||
virtual std::shared_ptr<I2PTunnelConnection> CreateI2PConnection (std::shared_ptr<i2p::stream::Stream> stream);
|
virtual std::shared_ptr<I2PTunnelConnection> CreateI2PConnection (std::shared_ptr<i2p::stream::Stream> stream);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool m_IsUniqueLocal;
|
bool m_IsUniqueLocal;
|
||||||
std::string m_Name, m_Address;
|
std::string m_Name, m_Address;
|
||||||
int m_Port;
|
int m_Port;
|
||||||
|
@ -302,28 +326,34 @@ namespace client
|
||||||
class I2PServerTunnelHTTP: public I2PServerTunnel
|
class I2PServerTunnelHTTP: public I2PServerTunnel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
I2PServerTunnelHTTP (const std::string& name, const std::string& address, int port,
|
I2PServerTunnelHTTP (const std::string& name, const std::string& address, int port,
|
||||||
std::shared_ptr<ClientDestination> localDestination, const std::string& host,
|
std::shared_ptr<ClientDestination> localDestination, const std::string& host,
|
||||||
int inport = 0, bool gzip = true);
|
int inport = 0, bool gzip = true);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::shared_ptr<I2PTunnelConnection> CreateI2PConnection (std::shared_ptr<i2p::stream::Stream> stream);
|
std::shared_ptr<I2PTunnelConnection> CreateI2PConnection (std::shared_ptr<i2p::stream::Stream> stream);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::string m_Host;
|
std::string m_Host;
|
||||||
};
|
};
|
||||||
|
|
||||||
class I2PServerTunnelIRC: public I2PServerTunnel
|
class I2PServerTunnelIRC: public I2PServerTunnel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
I2PServerTunnelIRC (const std::string& name, const std::string& address, int port,
|
I2PServerTunnelIRC (const std::string& name, const std::string& address, int port,
|
||||||
std::shared_ptr<ClientDestination> localDestination, const std::string& webircpass,
|
std::shared_ptr<ClientDestination> localDestination, const std::string& webircpass,
|
||||||
int inport = 0, bool gzip = true);
|
int inport = 0, bool gzip = true);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::shared_ptr<I2PTunnelConnection> CreateI2PConnection (std::shared_ptr<i2p::stream::Stream> stream);
|
std::shared_ptr<I2PTunnelConnection> CreateI2PConnection (std::shared_ptr<i2p::stream::Stream> stream);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::string m_WebircPass;
|
std::string m_WebircPass;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ namespace client
|
||||||
{
|
{
|
||||||
m_ResolveTimer->expires_from_now(boost::posix_time::seconds(1));
|
m_ResolveTimer->expires_from_now(boost::posix_time::seconds(1));
|
||||||
m_ResolveTimer->async_wait([&](const boost::system::error_code & ec) {
|
m_ResolveTimer->async_wait([&](const boost::system::error_code & ec) {
|
||||||
if(!ec) ResolveCurrentLeaseSet();
|
if(!ec) ResolveCurrentLeaseSet();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue