mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-22 13:27:17 +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
|
||||
{
|
||||
public:
|
||||
public:
|
||||
|
||||
I2PService(PSTR pszServiceName,
|
||||
BOOL fCanStop = TRUE,
|
||||
BOOL fCanShutdown = TRUE,
|
||||
BOOL fCanPauseContinue = FALSE);
|
||||
I2PService(PSTR pszServiceName,
|
||||
BOOL fCanStop = TRUE,
|
||||
BOOL fCanShutdown = TRUE,
|
||||
BOOL fCanPauseContinue = FALSE);
|
||||
|
||||
virtual ~I2PService(void);
|
||||
virtual ~I2PService(void);
|
||||
|
||||
static BOOL isService();
|
||||
static BOOL Run(I2PService &service);
|
||||
void Stop();
|
||||
static BOOL isService();
|
||||
static BOOL Run(I2PService &service);
|
||||
void Stop();
|
||||
|
||||
protected:
|
||||
protected:
|
||||
|
||||
virtual void OnStart(DWORD dwArgc, PSTR *pszArgv);
|
||||
virtual void OnStop();
|
||||
virtual void OnPause();
|
||||
virtual void OnContinue();
|
||||
virtual void OnShutdown();
|
||||
void SetServiceStatus(DWORD dwCurrentState,
|
||||
DWORD dwWin32ExitCode = NO_ERROR,
|
||||
DWORD dwWaitHint = 0);
|
||||
virtual void OnStart(DWORD dwArgc, PSTR *pszArgv);
|
||||
virtual void OnStop();
|
||||
virtual void OnPause();
|
||||
virtual void OnContinue();
|
||||
virtual void OnShutdown();
|
||||
void SetServiceStatus(DWORD dwCurrentState,
|
||||
DWORD dwWin32ExitCode = NO_ERROR,
|
||||
DWORD dwWaitHint = 0);
|
||||
|
||||
private:
|
||||
private:
|
||||
|
||||
static void WINAPI ServiceMain(DWORD dwArgc, LPSTR *lpszArgv);
|
||||
static void WINAPI ServiceCtrlHandler(DWORD dwCtrl);
|
||||
void WorkerThread();
|
||||
void Start(DWORD dwArgc, PSTR *pszArgv);
|
||||
void Pause();
|
||||
void Continue();
|
||||
void Shutdown();
|
||||
static I2PService* s_service;
|
||||
PSTR m_name;
|
||||
SERVICE_STATUS m_status;
|
||||
SERVICE_STATUS_HANDLE m_statusHandle;
|
||||
static void WINAPI ServiceMain(DWORD dwArgc, LPSTR *lpszArgv);
|
||||
static void WINAPI ServiceCtrlHandler(DWORD dwCtrl);
|
||||
void WorkerThread();
|
||||
void Start(DWORD dwArgc, PSTR *pszArgv);
|
||||
void Pause();
|
||||
void Continue();
|
||||
void Shutdown();
|
||||
static I2PService* s_service;
|
||||
PSTR m_name;
|
||||
SERVICE_STATUS m_status;
|
||||
SERVICE_STATUS_HANDLE m_statusHandle;
|
||||
|
||||
BOOL m_fStopping;
|
||||
HANDLE m_hStoppedEvent;
|
||||
BOOL m_fStopping;
|
||||
HANDLE m_hStoppedEvent;
|
||||
|
||||
std::thread* _worker;
|
||||
std::thread* _worker;
|
||||
};
|
||||
|
||||
void InstallService(
|
||||
|
@ -77,7 +77,7 @@ void InstallService(
|
|||
PCSTR pszDependencies,
|
||||
PCSTR pszAccount,
|
||||
PCSTR pszPassword
|
||||
);
|
||||
);
|
||||
|
||||
void UninstallService(PCSTR pszServiceName);
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
//{{NO_DEPENDENCIES}}
|
||||
#define MAINICON 101
|
||||
#define MAINICON 101
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 102
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#define _APS_NEXT_RESOURCE_VALUE 102
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -127,8 +127,8 @@ namespace i2p
|
|||
i2p::context.SetNetID (netID);
|
||||
i2p::context.Init ();
|
||||
|
||||
bool ipv6; i2p::config::GetOption("ipv6", ipv6);
|
||||
bool ipv4; i2p::config::GetOption("ipv4", ipv4);
|
||||
bool ipv6; i2p::config::GetOption("ipv6", ipv6);
|
||||
bool ipv4; i2p::config::GetOption("ipv4", ipv4);
|
||||
#ifdef MESHNET
|
||||
// manual override for meshnet
|
||||
ipv4 = false;
|
||||
|
@ -143,7 +143,7 @@ namespace i2p
|
|||
i2p::context.SetSupportsV6 (ipv6);
|
||||
i2p::context.SetSupportsV4 (ipv4);
|
||||
|
||||
bool ntcp; i2p::config::GetOption("ntcp", ntcp);
|
||||
bool ntcp; i2p::config::GetOption("ntcp", ntcp);
|
||||
i2p::context.PublishNTCPAddress (ntcp, !ipv6);
|
||||
bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
|
||||
if (ntcp2)
|
||||
|
@ -172,10 +172,13 @@ namespace i2p
|
|||
SetMaxNumTransitTunnels (transitTunnels);
|
||||
|
||||
bool isFloodfill; i2p::config::GetOption("floodfill", isFloodfill);
|
||||
if (isFloodfill) {
|
||||
if (isFloodfill)
|
||||
{
|
||||
LogPrint(eLogInfo, "Daemon: router will be floodfill");
|
||||
i2p::context.SetFloodfill (true);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
i2p::context.SetFloodfill (false);
|
||||
}
|
||||
|
||||
|
@ -243,7 +246,8 @@ namespace i2p
|
|||
i2p::transport::transports.RestrictRoutesToFamilies(fams);
|
||||
restricted = fams.size() > 0;
|
||||
}
|
||||
if (routers.length() > 0) {
|
||||
if (routers.length() > 0)
|
||||
{
|
||||
std::set<i2p::data::IdentHash> idents;
|
||||
size_t pos = 0, comma;
|
||||
do
|
||||
|
@ -279,7 +283,8 @@ namespace i2p
|
|||
i2p::data::netdb.Start();
|
||||
|
||||
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->Start ();
|
||||
}
|
||||
|
@ -292,7 +297,7 @@ namespace i2p
|
|||
}
|
||||
|
||||
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");
|
||||
if(!ssu) LogPrint(eLogInfo, "Daemon: ssu disabled");
|
||||
if(!ntcp) LogPrint(eLogInfo, "Daemon: ntcp disabled");
|
||||
|
@ -310,7 +315,8 @@ namespace i2p
|
|||
}
|
||||
|
||||
bool http; i2p::config::GetOption("http.enabled", http);
|
||||
if (http) {
|
||||
if (http)
|
||||
{
|
||||
std::string httpAddr; i2p::config::GetOption("http.address", httpAddr);
|
||||
uint16_t httpPort; i2p::config::GetOption("http.port", httpPort);
|
||||
LogPrint(eLogInfo, "Daemon: starting webconsole at ", httpAddr, ":", httpPort);
|
||||
|
@ -326,7 +332,6 @@ namespace i2p
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
LogPrint(eLogInfo, "Daemon: starting Tunnels");
|
||||
i2p::tunnel::tunnels.Start();
|
||||
|
||||
|
|
|
@ -13,9 +13,10 @@ namespace util
|
|||
class Daemon_Singleton
|
||||
{
|
||||
public:
|
||||
virtual bool init(int argc, char* argv[], std::shared_ptr<std::ostream> logstream);
|
||||
virtual bool init(int argc, char* argv[]);
|
||||
virtual bool start();
|
||||
|
||||
virtual bool init(int argc, char* argv[], std::shared_ptr<std::ostream> logstream);
|
||||
virtual bool init(int argc, char* argv[]);
|
||||
virtual bool start();
|
||||
virtual bool stop();
|
||||
virtual void run () {};
|
||||
|
||||
|
@ -23,6 +24,7 @@ namespace util
|
|||
bool running;
|
||||
|
||||
protected:
|
||||
|
||||
Daemon_Singleton();
|
||||
virtual ~Daemon_Singleton();
|
||||
|
||||
|
@ -39,6 +41,7 @@ namespace util
|
|||
class DaemonQT: public i2p::util::Daemon_Singleton
|
||||
{
|
||||
public:
|
||||
|
||||
static DaemonQT& Instance()
|
||||
{
|
||||
static DaemonQT instance;
|
||||
|
@ -51,6 +54,7 @@ namespace util
|
|||
class DaemonWin32 : public Daemon_Singleton
|
||||
{
|
||||
public:
|
||||
|
||||
static DaemonWin32& Instance()
|
||||
{
|
||||
static DaemonWin32 instance;
|
||||
|
@ -72,6 +76,7 @@ namespace util
|
|||
class DaemonAndroid: public i2p::util::Daemon_Singleton
|
||||
{
|
||||
public:
|
||||
|
||||
static DaemonAndroid& Instance()
|
||||
{
|
||||
static DaemonAndroid instance;
|
||||
|
@ -83,6 +88,7 @@ namespace util
|
|||
class DaemonLinux : public Daemon_Singleton
|
||||
{
|
||||
public:
|
||||
|
||||
static DaemonLinux& Instance()
|
||||
{
|
||||
static DaemonLinux instance;
|
||||
|
@ -94,10 +100,12 @@ namespace util
|
|||
void run ();
|
||||
|
||||
private:
|
||||
|
||||
std::string pidfile;
|
||||
int pidFH;
|
||||
|
||||
public:
|
||||
|
||||
int gracefulShutdownInterval; // in seconds
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -892,8 +892,8 @@ namespace http {
|
|||
void HTTPConnection::Receive ()
|
||||
{
|
||||
m_Socket->async_read_some (boost::asio::buffer (m_Buffer, HTTP_CONNECTION_BUFFER_SIZE),
|
||||
std::bind(&HTTPConnection::HandleReceive, shared_from_this (),
|
||||
std::placeholders::_1, std::placeholders::_2));
|
||||
std::bind(&HTTPConnection::HandleReceive, shared_from_this (),
|
||||
std::placeholders::_1, std::placeholders::_2));
|
||||
}
|
||||
|
||||
void HTTPConnection::HandleReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred)
|
||||
|
|
|
@ -79,17 +79,17 @@ namespace http
|
|||
std::string m_Hostname;
|
||||
};
|
||||
|
||||
//all the below functions are also used by Qt GUI, see mainwindow.cpp -> getStatusPageHtml
|
||||
enum OutputFormatEnum { forWebConsole, forQtUi };
|
||||
void ShowStatus (std::stringstream& s, bool includeHiddenContent, OutputFormatEnum outputFormat);
|
||||
void ShowLocalDestinations (std::stringstream& s);
|
||||
void ShowLeasesSets(std::stringstream& s);
|
||||
void ShowTunnels (std::stringstream& s);
|
||||
void ShowTransitTunnels (std::stringstream& s);
|
||||
void ShowTransports (std::stringstream& s);
|
||||
void ShowSAMSessions (std::stringstream& s);
|
||||
void ShowI2PTunnels (std::stringstream& s);
|
||||
void ShowLocalDestination (std::stringstream& s, const std::string& b32, uint32_t token);
|
||||
//all the below functions are also used by Qt GUI, see mainwindow.cpp -> getStatusPageHtml
|
||||
enum OutputFormatEnum { forWebConsole, forQtUi };
|
||||
void ShowStatus (std::stringstream& s, bool includeHiddenContent, OutputFormatEnum outputFormat);
|
||||
void ShowLocalDestinations (std::stringstream& s);
|
||||
void ShowLeasesSets(std::stringstream& s);
|
||||
void ShowTunnels (std::stringstream& s);
|
||||
void ShowTransitTunnels (std::stringstream& s);
|
||||
void ShowTransports (std::stringstream& s);
|
||||
void ShowSAMSessions (std::stringstream& s);
|
||||
void ShowI2PTunnels (std::stringstream& s);
|
||||
void ShowLocalDestination (std::stringstream& s, const std::string& b32, uint32_t token);
|
||||
} // http
|
||||
} // i2p
|
||||
|
||||
|
|
|
@ -59,29 +59,28 @@ namespace client
|
|||
m_SSLContext.use_private_key_file (i2pcp_key, boost::asio::ssl::context::pem);
|
||||
|
||||
// handlers
|
||||
m_MethodHandlers["Authenticate"] = &I2PControlService::AuthenticateHandler;
|
||||
m_MethodHandlers["Echo"] = &I2PControlService::EchoHandler;
|
||||
m_MethodHandlers["I2PControl"] = &I2PControlService::I2PControlHandler;
|
||||
m_MethodHandlers["RouterInfo"] = &I2PControlService::RouterInfoHandler;
|
||||
m_MethodHandlers["RouterManager"] = &I2PControlService::RouterManagerHandler;
|
||||
m_MethodHandlers["NetworkSetting"] = &I2PControlService::NetworkSettingHandler;
|
||||
m_MethodHandlers["ClientServicesInfo"] = &I2PControlService::ClientServicesInfoHandler;
|
||||
m_MethodHandlers["Authenticate"] = &I2PControlService::AuthenticateHandler;
|
||||
m_MethodHandlers["Echo"] = &I2PControlService::EchoHandler;
|
||||
m_MethodHandlers["I2PControl"] = &I2PControlService::I2PControlHandler;
|
||||
m_MethodHandlers["RouterInfo"] = &I2PControlService::RouterInfoHandler;
|
||||
m_MethodHandlers["RouterManager"] = &I2PControlService::RouterManagerHandler;
|
||||
m_MethodHandlers["NetworkSetting"] = &I2PControlService::NetworkSettingHandler;
|
||||
m_MethodHandlers["ClientServicesInfo"] = &I2PControlService::ClientServicesInfoHandler;
|
||||
|
||||
// I2PControl
|
||||
m_I2PControlHandlers["i2pcontrol.password"] = &I2PControlService::PasswordHandler;
|
||||
|
||||
// RouterInfo
|
||||
m_RouterInfoHandlers["i2p.router.uptime"] = &I2PControlService::UptimeHandler;
|
||||
m_RouterInfoHandlers["i2p.router.version"] = &I2PControlService::VersionHandler;
|
||||
m_RouterInfoHandlers["i2p.router.status"] = &I2PControlService::StatusHandler;
|
||||
m_RouterInfoHandlers["i2p.router.netdb.knownpeers"] = &I2PControlService::NetDbKnownPeersHandler;
|
||||
m_RouterInfoHandlers["i2p.router.netdb.activepeers"] = &I2PControlService::NetDbActivePeersHandler;
|
||||
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.status"] = &I2PControlService::NetStatusHandler;
|
||||
m_RouterInfoHandlers["i2p.router.uptime"] = &I2PControlService::UptimeHandler;
|
||||
m_RouterInfoHandlers["i2p.router.version"] = &I2PControlService::VersionHandler;
|
||||
m_RouterInfoHandlers["i2p.router.status"] = &I2PControlService::StatusHandler;
|
||||
m_RouterInfoHandlers["i2p.router.netdb.knownpeers"] = &I2PControlService::NetDbKnownPeersHandler;
|
||||
m_RouterInfoHandlers["i2p.router.netdb.activepeers"] = &I2PControlService::NetDbActivePeersHandler;
|
||||
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.status"] = &I2PControlService::NetStatusHandler;
|
||||
m_RouterInfoHandlers["i2p.router.net.tunnels.participating"] = &I2PControlService::TunnelsParticipatingHandler;
|
||||
m_RouterInfoHandlers["i2p.router.net.tunnels.successrate"] =
|
||||
&I2PControlService::TunnelsSuccessRateHandler;
|
||||
m_RouterInfoHandlers["i2p.router.net.tunnels.successrate"] = &I2PControlService::TunnelsSuccessRateHandler;
|
||||
m_RouterInfoHandlers["i2p.router.net.total.received.bytes"] = &I2PControlService::NetTotalReceivedBytes;
|
||||
m_RouterInfoHandlers["i2p.router.net.total.sent.bytes"] = &I2PControlService::NetTotalSentBytes;
|
||||
|
||||
|
@ -97,10 +96,10 @@ namespace client
|
|||
// ClientServicesInfo
|
||||
m_ClientServicesInfoHandlers["I2PTunnel"] = &I2PControlService::I2PTunnelInfoHandler;
|
||||
m_ClientServicesInfoHandlers["HTTPProxy"] = &I2PControlService::HTTPProxyInfoHandler;
|
||||
m_ClientServicesInfoHandlers["SOCKS"] = &I2PControlService::SOCKSInfoHandler;
|
||||
m_ClientServicesInfoHandlers["SAM"] = &I2PControlService::SAMInfoHandler;
|
||||
m_ClientServicesInfoHandlers["BOB"] = &I2PControlService::BOBInfoHandler;
|
||||
m_ClientServicesInfoHandlers["I2CP"] = &I2PControlService::I2CPInfoHandler;
|
||||
m_ClientServicesInfoHandlers["SOCKS"] = &I2PControlService::SOCKSInfoHandler;
|
||||
m_ClientServicesInfoHandlers["SAM"] = &I2PControlService::SAMInfoHandler;
|
||||
m_ClientServicesInfoHandlers["BOB"] = &I2PControlService::BOBInfoHandler;
|
||||
m_ClientServicesInfoHandlers["I2CP"] = &I2PControlService::I2CPInfoHandler;
|
||||
}
|
||||
|
||||
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.async_wait (
|
||||
[](const boost::system::error_code& ecode)
|
||||
{
|
||||
{
|
||||
Daemon.running = 0;
|
||||
});
|
||||
}
|
||||
|
@ -514,7 +513,7 @@ namespace client
|
|||
m_ShutdownTimer.expires_from_now (boost::posix_time::seconds(timeout + 1)); // + 1 second
|
||||
m_ShutdownTimer.async_wait (
|
||||
[](const boost::system::error_code& ecode)
|
||||
{
|
||||
{
|
||||
Daemon.running = 0;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ namespace client
|
|||
class I2PControlService
|
||||
{
|
||||
typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ssl_socket;
|
||||
|
||||
public:
|
||||
|
||||
I2PControlService (const std::string& address, int port);
|
||||
|
|
|
@ -80,10 +80,10 @@ namespace transport
|
|||
void UPnP::Discover ()
|
||||
{
|
||||
bool isError;
|
||||
int err;
|
||||
int err;
|
||||
|
||||
#if ((MINIUPNPC_API_VERSION >= 8) || defined (UPNPDISCOVER_SUCCESS))
|
||||
err = UPNPDISCOVER_SUCCESS;
|
||||
err = UPNPDISCOVER_SUCCESS;
|
||||
|
||||
#if (MINIUPNPC_API_VERSION >= 14)
|
||||
m_Devlist = upnpDiscover (UPNP_RESPONSE_TIMEOUT, NULL, NULL, 0, 0, 2, &err);
|
||||
|
@ -92,9 +92,9 @@ namespace transport
|
|||
#endif
|
||||
|
||||
isError = err != UPNPDISCOVER_SUCCESS;
|
||||
#else // MINIUPNPC_API_VERSION >= 8
|
||||
err = 0;
|
||||
m_Devlist = upnpDiscover (UPNP_RESPONSE_TIMEOUT, NULL, NULL, 0);
|
||||
#else // MINIUPNPC_API_VERSION >= 8
|
||||
err = 0;
|
||||
m_Devlist = upnpDiscover (UPNP_RESPONSE_TIMEOUT, NULL, NULL, 0);
|
||||
isError = m_Devlist == NULL;
|
||||
#endif // MINIUPNPC_API_VERSION >= 8
|
||||
{
|
||||
|
@ -105,15 +105,15 @@ namespace transport
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -182,7 +182,7 @@ namespace transport
|
|||
err = CheckMapping (strPort.c_str (), strType.c_str ());
|
||||
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))
|
||||
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
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -219,14 +219,14 @@ namespace transport
|
|||
|
||||
void UPnP::CloseMapping (std::shared_ptr<i2p::data::RouterInfo::Address> address)
|
||||
{
|
||||
if(!m_upnpUrlsInitialized) {
|
||||
return;
|
||||
}
|
||||
if(!m_upnpUrlsInitialized) {
|
||||
return;
|
||||
}
|
||||
std::string strType (GetProto (address)), strPort (std::to_string (address->port));
|
||||
int err = UPNPCOMMAND_SUCCESS;
|
||||
|
||||
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);
|
||||
LogPrint (eLogError, "UPnP: DeletePortMapping() returned : ", err);
|
||||
|
@ -237,11 +237,11 @@ namespace transport
|
|||
{
|
||||
freeUPNPDevlist (m_Devlist);
|
||||
m_Devlist = 0;
|
||||
if(m_upnpUrlsInitialized){
|
||||
FreeUPNPUrls (&m_upnpUrls);
|
||||
m_upnpUrlsInitialized=false;
|
||||
}
|
||||
}
|
||||
if(m_upnpUrlsInitialized){
|
||||
FreeUPNPUrls (&m_upnpUrls);
|
||||
m_upnpUrlsInitialized=false;
|
||||
}
|
||||
}
|
||||
|
||||
std::string UPnP::GetProto (std::shared_ptr<i2p::data::RouterInfo::Address> address)
|
||||
{
|
||||
|
|
|
@ -33,41 +33,41 @@ namespace transport
|
|||
{
|
||||
public:
|
||||
|
||||
UPnP ();
|
||||
~UPnP ();
|
||||
void Close ();
|
||||
UPnP ();
|
||||
~UPnP ();
|
||||
void Close ();
|
||||
|
||||
void Start ();
|
||||
void Stop ();
|
||||
void Start ();
|
||||
void Stop ();
|
||||
|
||||
private:
|
||||
|
||||
void Discover ();
|
||||
int CheckMapping (const char* port, const char* type);
|
||||
void PortMapping ();
|
||||
void TryPortMapping (std::shared_ptr<i2p::data::RouterInfo::Address> address);
|
||||
void CloseMapping ();
|
||||
void CloseMapping (std::shared_ptr<i2p::data::RouterInfo::Address> address);
|
||||
void Discover ();
|
||||
int CheckMapping (const char* port, const char* type);
|
||||
void PortMapping ();
|
||||
void TryPortMapping (std::shared_ptr<i2p::data::RouterInfo::Address> address);
|
||||
void CloseMapping ();
|
||||
void CloseMapping (std::shared_ptr<i2p::data::RouterInfo::Address> address);
|
||||
|
||||
void Run ();
|
||||
std::string GetProto (std::shared_ptr<i2p::data::RouterInfo::Address> address);
|
||||
void Run ();
|
||||
std::string GetProto (std::shared_ptr<i2p::data::RouterInfo::Address> address);
|
||||
|
||||
private:
|
||||
|
||||
bool m_IsRunning;
|
||||
std::unique_ptr<std::thread> m_Thread;
|
||||
std::condition_variable m_Started;
|
||||
std::mutex m_StartedMutex;
|
||||
boost::asio::io_service m_Service;
|
||||
boost::asio::deadline_timer m_Timer;
|
||||
bool m_upnpUrlsInitialized=false;
|
||||
struct UPNPUrls m_upnpUrls;
|
||||
struct IGDdatas m_upnpData;
|
||||
bool m_IsRunning;
|
||||
std::unique_ptr<std::thread> m_Thread;
|
||||
std::condition_variable m_Started;
|
||||
std::mutex m_StartedMutex;
|
||||
boost::asio::io_service m_Service;
|
||||
boost::asio::deadline_timer m_Timer;
|
||||
bool m_upnpUrlsInitialized = false;
|
||||
struct UPNPUrls m_upnpUrls;
|
||||
struct IGDdatas m_upnpData;
|
||||
|
||||
// For miniupnpc
|
||||
struct UPNPDev * m_Devlist = 0;
|
||||
char m_NetworkAddr[64];
|
||||
char m_externalIPAddress[40];
|
||||
// For miniupnpc
|
||||
struct UPNPDev * m_Devlist = 0;
|
||||
char m_NetworkAddr[64];
|
||||
char m_externalIPAddress[40];
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -79,10 +79,10 @@ namespace transport {
|
|||
class UPnP {
|
||||
public:
|
||||
|
||||
UPnP () {};
|
||||
~UPnP () {};
|
||||
void Start () { LogPrint(eLogWarning, "UPnP: this module was disabled at compile-time"); }
|
||||
void Stop () {};
|
||||
UPnP () {};
|
||||
~UPnP () {};
|
||||
void Start () { LogPrint(eLogWarning, "UPnP: this module was disabled at compile-time"); }
|
||||
void Stop () {};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -196,5 +196,4 @@ namespace i2p
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#include "Daemon.h"
|
||||
|
||||
#if defined(QT_GUI_LIB)
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
namespace qt
|
||||
|
@ -10,11 +9,11 @@ namespace qt
|
|||
int RunQT (int argc, char* argv[]);
|
||||
}
|
||||
}
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
return i2p::qt::RunQT (argc, argv);
|
||||
}
|
||||
|
||||
#else
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
|
|
212
libi2pd/Base.cpp
212
libi2pd/Base.cpp
|
@ -7,7 +7,8 @@ namespace i2p
|
|||
{
|
||||
namespace data
|
||||
{
|
||||
static const char T32[32] = {
|
||||
static const char T32[32] =
|
||||
{
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
|
||||
'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
|
||||
'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
|
||||
|
@ -29,15 +30,16 @@ namespace data
|
|||
* Direct Substitution Table
|
||||
*/
|
||||
|
||||
static const char T64[64] = {
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
|
||||
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
|
||||
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
|
||||
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||
'w', 'x', 'y', 'z', '0', '1', '2', '3',
|
||||
'4', '5', '6', '7', '8', '9', '-', '~'
|
||||
static const char T64[64] =
|
||||
{
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
|
||||
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
|
||||
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
|
||||
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||
'w', 'x', 'y', 'z', '0', '1', '2', '3',
|
||||
'4', '5', '6', '7', '8', '9', '-', '~'
|
||||
};
|
||||
|
||||
const char * GetBase64SubstitutionTable ()
|
||||
|
@ -67,14 +69,12 @@ namespace data
|
|||
*
|
||||
*/
|
||||
|
||||
size_t /* Number of bytes in the encoded buffer */
|
||||
ByteStreamToBase64 (
|
||||
const uint8_t * InBuffer, /* Input buffer, binary data */
|
||||
size_t InCount, /* Number of bytes in the input buffer */
|
||||
char * OutBuffer, /* output buffer */
|
||||
size_t len /* length of output buffer */
|
||||
size_t ByteStreamToBase64 ( /* Number of bytes in the encoded buffer */
|
||||
const uint8_t * InBuffer, /* Input buffer, binary data */
|
||||
size_t InCount, /* Number of bytes in the input buffer */
|
||||
char * OutBuffer, /* output buffer */
|
||||
size_t len /* length of output buffer */
|
||||
)
|
||||
|
||||
{
|
||||
unsigned char * ps;
|
||||
unsigned char * pd;
|
||||
|
@ -83,55 +83,60 @@ namespace data
|
|||
int i;
|
||||
int n;
|
||||
int m;
|
||||
size_t outCount;
|
||||
size_t outCount;
|
||||
|
||||
ps = (unsigned char *)InBuffer;
|
||||
n = InCount/3;
|
||||
m = InCount%3;
|
||||
n = InCount / 3;
|
||||
m = InCount % 3;
|
||||
if (!m)
|
||||
outCount = 4*n;
|
||||
outCount = 4 * n;
|
||||
else
|
||||
outCount = 4*(n+1);
|
||||
outCount = 4 * (n + 1);
|
||||
|
||||
if (outCount > len) return 0;
|
||||
|
||||
pd = (unsigned char *)OutBuffer;
|
||||
for ( i = 0; i<n; i++ ){
|
||||
acc_1 = *ps++;
|
||||
acc_2 = (acc_1<<4)&0x30;
|
||||
acc_1 >>= 2; /* base64 digit #1 */
|
||||
*pd++ = T64[acc_1];
|
||||
acc_1 = *ps++;
|
||||
acc_2 |= acc_1 >> 4; /* base64 digit #2 */
|
||||
*pd++ = T64[acc_2];
|
||||
acc_1 &= 0x0f;
|
||||
acc_1 <<=2;
|
||||
acc_2 = *ps++;
|
||||
acc_1 |= acc_2>>6; /* base64 digit #3 */
|
||||
*pd++ = T64[acc_1];
|
||||
acc_2 &= 0x3f; /* base64 digit #4 */
|
||||
*pd++ = T64[acc_2];
|
||||
for ( i = 0; i < n; i++ )
|
||||
{
|
||||
acc_1 = *ps++;
|
||||
acc_2 = (acc_1 << 4) & 0x30;
|
||||
acc_1 >>= 2; /* base64 digit #1 */
|
||||
*pd++ = T64[acc_1];
|
||||
acc_1 = *ps++;
|
||||
acc_2 |= acc_1 >> 4; /* base64 digit #2 */
|
||||
*pd++ = T64[acc_2];
|
||||
acc_1 &= 0x0f;
|
||||
acc_1 <<= 2;
|
||||
acc_2 = *ps++;
|
||||
acc_1 |= acc_2 >> 6; /* base64 digit #3 */
|
||||
*pd++ = T64[acc_1];
|
||||
acc_2 &= 0x3f; /* base64 digit #4 */
|
||||
*pd++ = T64[acc_2];
|
||||
}
|
||||
if ( m == 1 ){
|
||||
acc_1 = *ps++;
|
||||
acc_2 = (acc_1<<4)&0x3f; /* base64 digit #2 */
|
||||
acc_1 >>= 2; /* base64 digit #1 */
|
||||
*pd++ = T64[acc_1];
|
||||
*pd++ = T64[acc_2];
|
||||
*pd++ = P64;
|
||||
*pd++ = P64;
|
||||
if ( m == 1 )
|
||||
{
|
||||
acc_1 = *ps++;
|
||||
acc_2 = (acc_1 << 4) & 0x3f; /* base64 digit #2 */
|
||||
acc_1 >>= 2; /* base64 digit #1 */
|
||||
*pd++ = T64[acc_1];
|
||||
*pd++ = T64[acc_2];
|
||||
*pd++ = P64;
|
||||
*pd++ = P64;
|
||||
|
||||
}
|
||||
else if ( m == 2 ){
|
||||
acc_1 = *ps++;
|
||||
acc_2 = (acc_1<<4)&0x3f;
|
||||
acc_1 >>= 2; /* base64 digit #1 */
|
||||
*pd++ = T64[acc_1];
|
||||
acc_1 = *ps++;
|
||||
acc_2 |= acc_1 >> 4; /* base64 digit #2 */
|
||||
*pd++ = T64[acc_2];
|
||||
acc_1 &= 0x0f;
|
||||
acc_1 <<=2; /* base64 digit #3 */
|
||||
*pd++ = T64[acc_1];
|
||||
*pd++ = P64;
|
||||
else if ( m == 2 )
|
||||
{
|
||||
acc_1 = *ps++;
|
||||
acc_2 = (acc_1 << 4) & 0x3f;
|
||||
acc_1 >>= 2; /* base64 digit #1 */
|
||||
*pd++ = T64[acc_1];
|
||||
acc_1 = *ps++;
|
||||
acc_2 |= acc_1 >> 4; /* base64 digit #2 */
|
||||
*pd++ = T64[acc_2];
|
||||
acc_1 &= 0x0f;
|
||||
acc_1 <<= 2; /* base64 digit #3 */
|
||||
*pd++ = T64[acc_1];
|
||||
*pd++ = P64;
|
||||
}
|
||||
|
||||
return outCount;
|
||||
|
@ -147,12 +152,11 @@ namespace data
|
|||
*
|
||||
*/
|
||||
|
||||
size_t /* Number of output bytes */
|
||||
Base64ToByteStream (
|
||||
const char * InBuffer, /* BASE64 encoded buffer */
|
||||
size_t InCount, /* Number of input bytes */
|
||||
uint8_t * OutBuffer, /* output buffer length */
|
||||
size_t len /* length of output buffer */
|
||||
size_t Base64ToByteStream ( /* Number of output bytes */
|
||||
const char * InBuffer, /* BASE64 encoded buffer */
|
||||
size_t InCount, /* Number of input bytes */
|
||||
uint8_t * OutBuffer, /* output buffer length */
|
||||
size_t len /* length of output buffer */
|
||||
)
|
||||
{
|
||||
unsigned char * ps;
|
||||
|
@ -162,42 +166,52 @@ namespace data
|
|||
int i;
|
||||
int n;
|
||||
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)
|
||||
outCount = 3*n;
|
||||
else {
|
||||
outCount = 0;
|
||||
return 0;
|
||||
outCount = 3 * n;
|
||||
else
|
||||
{
|
||||
outCount = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ps = (unsigned char *)(InBuffer + InCount - 1);
|
||||
while ( *ps-- == P64 ) outCount--;
|
||||
while ( *ps-- == P64 )
|
||||
outCount--;
|
||||
ps = (unsigned char *)InBuffer;
|
||||
|
||||
if (outCount > len) return -1;
|
||||
if (outCount > len)
|
||||
return -1;
|
||||
|
||||
pd = OutBuffer;
|
||||
auto endOfOutBuffer = OutBuffer + outCount;
|
||||
for ( i = 0; i < n; i++ ){
|
||||
acc_1 = iT64[*ps++];
|
||||
acc_2 = iT64[*ps++];
|
||||
acc_1 <<= 2;
|
||||
acc_1 |= acc_2>>4;
|
||||
*pd++ = acc_1;
|
||||
if (pd >= endOfOutBuffer) break;
|
||||
for ( i = 0; i < n; i++ )
|
||||
{
|
||||
acc_1 = iT64[*ps++];
|
||||
acc_2 = iT64[*ps++];
|
||||
acc_1 <<= 2;
|
||||
acc_1 |= acc_2 >> 4;
|
||||
*pd++ = acc_1;
|
||||
if (pd >= endOfOutBuffer)
|
||||
break;
|
||||
|
||||
acc_2 <<= 4;
|
||||
acc_1 = iT64[*ps++];
|
||||
acc_2 |= acc_1 >> 2;
|
||||
*pd++ = acc_2;
|
||||
if (pd >= endOfOutBuffer) break;
|
||||
acc_2 <<= 4;
|
||||
acc_1 = iT64[*ps++];
|
||||
acc_2 |= acc_1 >> 2;
|
||||
*pd++ = acc_2;
|
||||
if (pd >= endOfOutBuffer)
|
||||
break;
|
||||
|
||||
acc_2 = iT64[*ps++];
|
||||
acc_2 |= acc_1 << 6;
|
||||
*pd++ = acc_2;
|
||||
acc_2 = iT64[*ps++];
|
||||
acc_2 |= acc_1 << 6;
|
||||
*pd++ = acc_2;
|
||||
}
|
||||
|
||||
return outCount;
|
||||
|
@ -206,20 +220,25 @@ namespace data
|
|||
size_t Base64EncodingBufferSize (const size_t input_size)
|
||||
{
|
||||
auto d = div (input_size, 3);
|
||||
if (d.rem) d.quot++;
|
||||
return 4*d.quot;
|
||||
if (d.rem)
|
||||
d.quot++;
|
||||
|
||||
return 4 * d.quot;
|
||||
}
|
||||
|
||||
std::string ToBase64Standard (const std::string& in)
|
||||
{
|
||||
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);
|
||||
str[l] = 0;
|
||||
// replace '-' by '+' and '~' by '/'
|
||||
for (size_t i = 0; i < l; i++)
|
||||
if (str[i] == '-') str[i] = '+';
|
||||
else if (str[i] == '~') str[i] = '/';
|
||||
if (str[i] == '-')
|
||||
str[i] = '+';
|
||||
else if (str[i] == '~')
|
||||
str[i] = '/';
|
||||
|
||||
std::string s(str);
|
||||
delete[] str;
|
||||
return s;
|
||||
|
@ -236,10 +255,10 @@ namespace data
|
|||
|
||||
static void iT64Build()
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
isFirstTime = 0;
|
||||
for ( i=0; i<256; i++ ) iT64[i] = -1;
|
||||
for ( i=0; i<64; i++ ) iT64[(int)T64[i]] = i;
|
||||
for ( i = 0; i < 256; i++ ) iT64[i] = -1;
|
||||
for ( i = 0; i < 64; i++ ) iT64[(int)T64[i]] = i;
|
||||
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 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);
|
||||
|
||||
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
|
||||
{
|
||||
extern bool aesni;
|
||||
extern bool avx;
|
||||
extern bool aesni;
|
||||
extern bool avx;
|
||||
|
||||
void Detect();
|
||||
void Detect();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,34 +21,34 @@ namespace chacha
|
|||
{
|
||||
void u32t8le(uint32_t v, uint8_t * p)
|
||||
{
|
||||
p[0] = v & 0xff;
|
||||
p[1] = (v >> 8) & 0xff;
|
||||
p[2] = (v >> 16) & 0xff;
|
||||
p[3] = (v >> 24) & 0xff;
|
||||
p[0] = v & 0xff;
|
||||
p[1] = (v >> 8) & 0xff;
|
||||
p[2] = (v >> 16) & 0xff;
|
||||
p[3] = (v >> 24) & 0xff;
|
||||
}
|
||||
|
||||
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[1];
|
||||
value = (value << 8) | p[0];
|
||||
value = (value << 8) | p[2];
|
||||
value = (value << 8) | p[1];
|
||||
value = (value << 8) | p[0];
|
||||
|
||||
return value;
|
||||
return value;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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[a] += x[b]; x[d] = rotl32(x[d] ^ x[a], 8);
|
||||
x[c] += x[d]; x[b] = rotl32(x[b] ^ x[c], 7);
|
||||
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[a] += x[b]; x[d] = rotl32(x[d] ^ x[a], 8);
|
||||
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)
|
||||
{
|
||||
int i;
|
||||
Chacha20State x;
|
||||
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;
|
||||
int i;
|
||||
Chacha20State x;
|
||||
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;
|
||||
}
|
||||
|
||||
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[3] = 0x6b206574;
|
||||
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);
|
||||
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)
|
||||
|
@ -117,22 +116,22 @@ void Chacha20Encrypt (Chacha20State& state, uint8_t * buf, size_t sz)
|
|||
}
|
||||
for (size_t i = 0; i < sz; i += chacha::blocksize)
|
||||
{
|
||||
chacha::block(state, chacha::rounds);
|
||||
state.data[12]++;
|
||||
for (size_t j = i; j < i + chacha::blocksize; j++)
|
||||
{
|
||||
if (j >= sz)
|
||||
chacha::block(state, chacha::rounds);
|
||||
state.data[12]++;
|
||||
for (size_t j = i; j < i + chacha::blocksize; j++)
|
||||
{
|
||||
if (j >= sz)
|
||||
{
|
||||
state.offset = j & 0x3F; // % 64
|
||||
break;
|
||||
}
|
||||
buf[j] ^= state.block.data[j - i];
|
||||
}
|
||||
buf[j] ^= state.block.data[j - i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace chacha
|
||||
} // namespace crypto
|
||||
} // namespace i2p
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -21,8 +21,8 @@ namespace i2p
|
|||
{
|
||||
namespace crypto
|
||||
{
|
||||
const std::size_t CHACHA20_KEY_BYTES = 32;
|
||||
const std::size_t CHACHA20_NOUNCE_BYTES = 12;
|
||||
const std::size_t CHACHA20_KEY_BYTES = 32;
|
||||
const std::size_t CHACHA20_NOUNCE_BYTES = 12;
|
||||
|
||||
namespace chacha
|
||||
{
|
||||
|
@ -32,12 +32,12 @@ namespace chacha
|
|||
struct Chacha20State;
|
||||
struct Chacha20Block
|
||||
{
|
||||
Chacha20Block () {};
|
||||
Chacha20Block (Chacha20Block &&) = delete;
|
||||
Chacha20Block () {};
|
||||
Chacha20Block (Chacha20Block &&) = delete;
|
||||
|
||||
uint8_t data[blocksize];
|
||||
uint8_t data[blocksize];
|
||||
|
||||
void operator << (const Chacha20State & st);
|
||||
void operator << (const Chacha20State & st);
|
||||
};
|
||||
|
||||
struct Chacha20State
|
||||
|
@ -54,7 +54,7 @@ namespace chacha
|
|||
|
||||
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];
|
||||
Chacha20Block block;
|
||||
|
@ -64,9 +64,9 @@ namespace chacha
|
|||
void Chacha20Init (Chacha20State& state, const uint8_t * nonce, const uint8_t * key, uint32_t counter);
|
||||
void Chacha20SetCounter (Chacha20State& state, uint32_t counter);
|
||||
void Chacha20Encrypt (Chacha20State& state, uint8_t * buf, size_t sz); // encrypt buf in place
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} // namespace chacha
|
||||
} // namespace crypto
|
||||
} // namespace i2p
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -242,7 +242,7 @@ namespace config {
|
|||
"1.pool.ntp.org,"
|
||||
"2.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)")
|
||||
;
|
||||
|
||||
|
|
169
libi2pd/Config.h
169
libi2pd/Config.h
|
@ -18,98 +18,101 @@
|
|||
|
||||
namespace i2p {
|
||||
namespace config {
|
||||
extern boost::program_options::variables_map m_Options;
|
||||
extern boost::program_options::variables_map m_Options;
|
||||
|
||||
/**
|
||||
* @brief Initialize list of acceptable parameters
|
||||
*
|
||||
* Should be called before any Parse* functions.
|
||||
*/
|
||||
void Init();
|
||||
/**
|
||||
* @brief Initialize list of acceptable parameters
|
||||
*
|
||||
* Should be called before any Parse* functions.
|
||||
*/
|
||||
void Init();
|
||||
|
||||
/**
|
||||
* @brief Parse cmdline parameters, and show help if requested
|
||||
* @param argc Cmdline arguments count, 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
|
||||
* and terminates the program with exitcode 0.
|
||||
*
|
||||
* In case of parameter misuse boost throws an exception.
|
||||
* We internally handle type boost::program_options::unknown_option,
|
||||
* and then terminate the program with exitcode 1.
|
||||
*
|
||||
* Other exceptions will be passed to higher level.
|
||||
*/
|
||||
void ParseCmdline(int argc, char* argv[], bool ignoreUnknown = false);
|
||||
/**
|
||||
* @brief Parse cmdline parameters, and show help if requested
|
||||
* @param argc Cmdline arguments count, 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
|
||||
* and terminates the program with exitcode 0.
|
||||
*
|
||||
* In case of parameter misuse boost throws an exception.
|
||||
* We internally handle type boost::program_options::unknown_option,
|
||||
* and then terminate the program with exitcode 1.
|
||||
*
|
||||
* Other exceptions will be passed to higher level.
|
||||
*/
|
||||
void ParseCmdline(int argc, char* argv[], bool ignoreUnknown = false);
|
||||
|
||||
/**
|
||||
* @brief Load and parse given config file
|
||||
* @param path Path to config file
|
||||
*
|
||||
* If error occurred when opening file path is points to,
|
||||
* we show the error message and terminate program.
|
||||
*
|
||||
* In case of parameter misuse boost throws an exception.
|
||||
* We internally handle type boost::program_options::unknown_option,
|
||||
* and then terminate program with exitcode 1.
|
||||
*
|
||||
* Other exceptions will be passed to higher level.
|
||||
*/
|
||||
void ParseConfig(const std::string& path);
|
||||
/**
|
||||
* @brief Load and parse given config file
|
||||
* @param path Path to config file
|
||||
*
|
||||
* If error occurred when opening file path is points to,
|
||||
* we show the error message and terminate program.
|
||||
*
|
||||
* In case of parameter misuse boost throws an exception.
|
||||
* We internally handle type boost::program_options::unknown_option,
|
||||
* and then terminate program with exitcode 1.
|
||||
*
|
||||
* Other exceptions will be passed to higher level.
|
||||
*/
|
||||
void ParseConfig(const std::string& path);
|
||||
|
||||
/**
|
||||
* @brief Used to combine options from cmdline, config and default values
|
||||
*/
|
||||
void Finalize();
|
||||
/**
|
||||
* @brief Used to combine options from cmdline, config and default values
|
||||
*/
|
||||
void Finalize();
|
||||
|
||||
/* @brief Accessor to parameters by name
|
||||
* @param name Name of the requested parameter
|
||||
* @param value Variable where to store option
|
||||
* @return this function returns false if parameter not found
|
||||
*
|
||||
* Example: uint16_t port; GetOption("sam.port", port);
|
||||
*/
|
||||
template<typename T>
|
||||
bool GetOption(const char *name, T& value) {
|
||||
if (!m_Options.count(name))
|
||||
return false;
|
||||
value = m_Options[name].as<T>();
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* @brief Accessor to parameters by name
|
||||
* @param name Name of the requested parameter
|
||||
* @param value Variable where to store option
|
||||
* @return this function returns false if parameter not found
|
||||
*
|
||||
* Example: uint16_t port; GetOption("sam.port", port);
|
||||
*/
|
||||
template<typename T>
|
||||
bool GetOption(const char *name, T& value)
|
||||
{
|
||||
if (!m_Options.count(name))
|
||||
return false;
|
||||
value = m_Options[name].as<T>();
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool GetOption(const std::string& name, T& value)
|
||||
{
|
||||
return GetOption (name.c_str (), value);
|
||||
}
|
||||
template<typename T>
|
||||
bool GetOption(const std::string& name, T& value)
|
||||
{
|
||||
return GetOption (name.c_str (), value);
|
||||
}
|
||||
|
||||
bool GetOptionAsAny(const char *name, boost::any& value);
|
||||
bool GetOptionAsAny(const std::string& name, boost::any& value);
|
||||
bool GetOptionAsAny(const char *name, boost::any& value);
|
||||
bool GetOptionAsAny(const std::string& name, boost::any& value);
|
||||
|
||||
/**
|
||||
* @brief Set value of given parameter
|
||||
* @param name Name of settable parameter
|
||||
* @param value New parameter value
|
||||
* @return true if value set up successful, false otherwise
|
||||
*
|
||||
* Example: uint16_t port = 2827; SetOption("bob.port", port);
|
||||
*/
|
||||
template<typename T>
|
||||
bool SetOption(const char *name, const T& value) {
|
||||
if (!m_Options.count(name))
|
||||
return false;
|
||||
m_Options.at(name).value() = value;
|
||||
notify(m_Options);
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* @brief Set value of given parameter
|
||||
* @param name Name of settable parameter
|
||||
* @param value New parameter value
|
||||
* @return true if value set up successful, false otherwise
|
||||
*
|
||||
* Example: uint16_t port = 2827; SetOption("bob.port", port);
|
||||
*/
|
||||
template<typename T>
|
||||
bool SetOption(const char *name, const T& value)
|
||||
{
|
||||
if (!m_Options.count(name))
|
||||
return false;
|
||||
m_Options.at(name).value() = value;
|
||||
notify(m_Options);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check is value explicitly given or default
|
||||
* @param name Name of checked parameter
|
||||
* @return true if value set to default, false otherwise
|
||||
*/
|
||||
bool IsDefault(const char *name);
|
||||
/**
|
||||
* @brief Check is value explicitly given or default
|
||||
* @param name Name of checked parameter
|
||||
* @return true if value set to default, false otherwise
|
||||
*/
|
||||
bool IsDefault(const char *name);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -681,12 +681,12 @@ namespace crypto
|
|||
|
||||
// AES
|
||||
#ifdef __AES__
|
||||
#ifdef ARM64AES
|
||||
void init_aesenc(void){
|
||||
#ifdef ARM64AES
|
||||
void init_aesenc(void){
|
||||
// TODO: Implementation
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define KeyExpansion256(round0,round1) \
|
||||
"pshufd $0xff, %%xmm2, %%xmm2 \n" \
|
||||
|
@ -884,7 +884,6 @@ namespace crypto
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void CBCEncryption::Encrypt (int numBlocks, const ChipherBlock * in, ChipherBlock * out)
|
||||
{
|
||||
#ifdef __AES__
|
||||
|
@ -1364,4 +1363,3 @@ namespace crypto
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,13 +28,13 @@
|
|||
#else
|
||||
# define LEGACY_OPENSSL 0
|
||||
# if (OPENSSL_VERSION_NUMBER >= 0x010101000) // 1.1.1
|
||||
# define OPENSSL_HKDF 1
|
||||
# define OPENSSL_EDDSA 1
|
||||
# define OPENSSL_X25519 1
|
||||
# define OPENSSL_SIPHASH 1
|
||||
# define OPENSSL_HKDF 1
|
||||
# define OPENSSL_EDDSA 1
|
||||
# define OPENSSL_X25519 1
|
||||
# define OPENSSL_SIPHASH 1
|
||||
# endif
|
||||
# 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
|
||||
|
||||
|
|
|
@ -178,4 +178,3 @@ namespace crypto
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -126,7 +126,7 @@ namespace crypto
|
|||
ECIESX25519AEADRatchetEncryptor (const uint8_t * pub);
|
||||
~ECIESX25519AEADRatchetEncryptor () {};
|
||||
void Encrypt (const uint8_t *, uint8_t * pub, BN_CTX *, bool);
|
||||
// copies m_PublicKey to pub
|
||||
// copies m_PublicKey to pub
|
||||
|
||||
private:
|
||||
|
||||
|
@ -153,4 +153,3 @@ namespace crypto
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -77,5 +77,4 @@ namespace worker
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -114,16 +114,15 @@ namespace datagram
|
|||
LogPrint (eLogWarning, "Datagram: decompression failed");
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<I2NPMessage> DatagramDestination::CreateDataMessage (
|
||||
const std::vector<std::pair<const uint8_t *, size_t> >& payloads,
|
||||
uint16_t fromPort, uint16_t toPort, bool isRaw, bool checksum)
|
||||
const std::vector<std::pair<const uint8_t *, size_t> >& payloads,
|
||||
uint16_t fromPort, uint16_t toPort, bool isRaw, bool checksum)
|
||||
{
|
||||
auto msg = NewI2NPMessage ();
|
||||
uint8_t * buf = msg->GetPayload ();
|
||||
buf += 4; // reserve for length
|
||||
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)
|
||||
{
|
||||
htobe32buf (msg->GetPayload (), size); // length
|
||||
|
@ -186,7 +185,7 @@ namespace datagram
|
|||
}
|
||||
|
||||
DatagramSession::DatagramSession(std::shared_ptr<i2p::client::ClientDestination> localDestination,
|
||||
const i2p::data::IdentHash & remoteIdent) :
|
||||
const i2p::data::IdentHash & remoteIdent) :
|
||||
m_LocalDestination(localDestination),
|
||||
m_RemoteIdent(remoteIdent),
|
||||
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;
|
||||
// milliseconds minimum time between path switches
|
||||
const uint64_t DATAGRAM_SESSION_PATH_MIN_LIFETIME = 5 * 1000;
|
||||
// max 64 messages buffered in send queue for each datagram session
|
||||
const size_t DATAGRAM_SEND_QUEUE_MAX_SIZE = 64;
|
||||
// max 64 messages buffered in send queue for each datagram session
|
||||
const size_t DATAGRAM_SEND_QUEUE_MAX_SIZE = 64;
|
||||
|
||||
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 ();
|
||||
void Stop ();
|
||||
public:
|
||||
|
||||
DatagramSession(std::shared_ptr<i2p::client::ClientDestination> localDestination, const i2p::data::IdentHash & remoteIdent);
|
||||
|
||||
void Start ();
|
||||
void Stop ();
|
||||
|
||||
|
||||
/** @brief ack the garlic routing path */
|
||||
void Ack();
|
||||
/** @brief ack the garlic routing path */
|
||||
void Ack();
|
||||
|
||||
/** send an i2np message to remote endpoint for this session */
|
||||
void SendMsg(std::shared_ptr<I2NPMessage> msg);
|
||||
/** get the last time in milliseconds for when we used this datagram session */
|
||||
uint64_t LastActivity() const { return m_LastUse; }
|
||||
/** send an i2np message to remote endpoint for this session */
|
||||
void SendMsg(std::shared_ptr<I2NPMessage> msg);
|
||||
/** get the last time in milliseconds for when we used this datagram session */
|
||||
uint64_t LastActivity() const { return m_LastUse; }
|
||||
|
||||
bool IsRatchets () const { return m_RoutingSession && m_RoutingSession->IsRatchets (); }
|
||||
|
||||
|
@ -60,40 +62,41 @@ namespace datagram
|
|||
std::shared_ptr<const i2p::data::IdentHash> OBEP;
|
||||
const uint64_t activity;
|
||||
|
||||
Info() : IBGW(nullptr), OBEP(nullptr), activity(0) {}
|
||||
Info(const uint8_t * ibgw, const uint8_t * obep, const uint64_t a) :
|
||||
activity(a) {
|
||||
if(ibgw) IBGW = std::make_shared<i2p::data::IdentHash>(ibgw);
|
||||
else IBGW = nullptr;
|
||||
if(obep) OBEP = std::make_shared<i2p::data::IdentHash>(obep);
|
||||
else OBEP = nullptr;
|
||||
}
|
||||
};
|
||||
Info() : IBGW(nullptr), OBEP(nullptr), activity(0) {}
|
||||
Info(const uint8_t * ibgw, const uint8_t * obep, const uint64_t a) :
|
||||
activity(a) {
|
||||
if(ibgw) IBGW = std::make_shared<i2p::data::IdentHash>(ibgw);
|
||||
else IBGW = nullptr;
|
||||
if(obep) OBEP = std::make_shared<i2p::data::IdentHash>(obep);
|
||||
else OBEP = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
Info GetSessionInfo() const;
|
||||
Info GetSessionInfo() const;
|
||||
|
||||
private:
|
||||
private:
|
||||
|
||||
void FlushSendQueue();
|
||||
void ScheduleFlushSendQueue();
|
||||
void FlushSendQueue();
|
||||
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:
|
||||
std::shared_ptr<i2p::client::ClientDestination> m_LocalDestination;
|
||||
i2p::data::IdentHash m_RemoteIdent;
|
||||
std::shared_ptr<const i2p::data::LeaseSet> m_RemoteLeaseSet;
|
||||
std::shared_ptr<i2p::garlic::GarlicRoutingSession> m_RoutingSession;
|
||||
std::shared_ptr<const i2p::data::Lease> m_CurrentRemoteLease;
|
||||
std::shared_ptr<i2p::tunnel::OutboundTunnel> m_CurrentOutboundTunnel;
|
||||
boost::asio::deadline_timer m_SendQueueTimer;
|
||||
std::vector<std::shared_ptr<I2NPMessage> > m_SendQueue;
|
||||
uint64_t m_LastUse;
|
||||
bool m_RequestingLS;
|
||||
private:
|
||||
|
||||
std::shared_ptr<i2p::client::ClientDestination> m_LocalDestination;
|
||||
i2p::data::IdentHash m_RemoteIdent;
|
||||
std::shared_ptr<const i2p::data::LeaseSet> m_RemoteLeaseSet;
|
||||
std::shared_ptr<i2p::garlic::GarlicRoutingSession> m_RoutingSession;
|
||||
std::shared_ptr<const i2p::data::Lease> m_CurrentRemoteLease;
|
||||
std::shared_ptr<i2p::tunnel::OutboundTunnel> m_CurrentOutboundTunnel;
|
||||
boost::asio::deadline_timer m_SendQueueTimer;
|
||||
std::vector<std::shared_ptr<I2NPMessage> > m_SendQueue;
|
||||
uint64_t m_LastUse;
|
||||
bool m_RequestingLS;
|
||||
};
|
||||
|
||||
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 (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len)> RawReceiver;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
||||
DatagramDestination (std::shared_ptr<i2p::client::ClientDestination> owner, bool gzip);
|
||||
DatagramDestination (std::shared_ptr<i2p::client::ClientDestination> owner, bool gzip);
|
||||
~DatagramDestination ();
|
||||
|
||||
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:
|
||||
|
||||
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,
|
||||
uint16_t fromPort, uint16_t toPort, bool isRaw = false, bool checksum = true);
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace i2p
|
|||
namespace client
|
||||
{
|
||||
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_LastSubmissionTime (0), m_PublishConfirmationTimer (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)
|
||||
{
|
||||
|
||||
auto itr = params.find("i2cp.dontPublishLeaseSet");
|
||||
if (itr != params.end())
|
||||
{
|
||||
|
@ -565,12 +564,12 @@ namespace client
|
|||
m_PublishReplyToken = 0;
|
||||
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 ();
|
||||
}
|
||||
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
|
||||
// assume it successive and try to verify
|
||||
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,
|
||||
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 ())
|
||||
request->replyTunnel = m_Pool->GetNextInboundTunnel ();
|
||||
|
@ -783,7 +782,7 @@ namespace client
|
|||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -829,7 +828,7 @@ namespace client
|
|||
i2p::data::CryptoKeyType LeaseSetDestination::GetPreferredCryptoType () const
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -846,7 +845,7 @@ namespace client
|
|||
// extract encryption type params for LS2
|
||||
std::set<i2p::data::CryptoKeyType> encryptionKeyTypes;
|
||||
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);
|
||||
if (it != params->end ())
|
||||
|
@ -1105,7 +1104,7 @@ namespace client
|
|||
return dest;
|
||||
}
|
||||
|
||||
i2p::datagram::DatagramDestination * ClientDestination::CreateDatagramDestination (bool gzip)
|
||||
i2p::datagram::DatagramDestination * ClientDestination::CreateDatagramDestination (bool gzip)
|
||||
{
|
||||
if (m_DatagramDestination == nullptr)
|
||||
m_DatagramDestination = new i2p::datagram::DatagramDestination (GetSharedFromThis (), gzip);
|
||||
|
@ -1147,7 +1146,7 @@ namespace client
|
|||
// TODO:: persist crypto key type
|
||||
std::ofstream f1 (path, std::ofstream::binary | std::ofstream::out);
|
||||
if (f1) {
|
||||
f1.write ((char *)keys->pub, 256);
|
||||
f1.write ((char *)keys->pub, 256);
|
||||
f1.write ((char *)keys->priv, 256);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -94,7 +94,6 @@ namespace client
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
|
||||
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; };
|
||||
std::shared_ptr<i2p::data::LeaseSet> FindLeaseSet (const i2p::data::IdentHash& ident);
|
||||
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 CancelDestinationRequestWithEncryptedLeaseSet (std::shared_ptr<const i2p::data::BlindedPublicKey> dest, bool notify = true);
|
||||
|
||||
|
@ -155,7 +154,7 @@ namespace client
|
|||
void HandleDeliveryStatusMessage (uint32_t msgID);
|
||||
|
||||
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 HandleCleanupTimer (const boost::system::error_code& ecode);
|
||||
void CleanupRemoteLeaseSets ();
|
||||
|
@ -235,8 +234,8 @@ namespace client
|
|||
int GetStreamingAckDelay () const { return m_StreamingAckDelay; }
|
||||
|
||||
// datagram
|
||||
i2p::datagram::DatagramDestination * GetDatagramDestination () const { return m_DatagramDestination; };
|
||||
i2p::datagram::DatagramDestination * CreateDatagramDestination (bool gzip = true);
|
||||
i2p::datagram::DatagramDestination * GetDatagramDestination () const { return m_DatagramDestination; };
|
||||
i2p::datagram::DatagramDestination * CreateDatagramDestination (bool gzip = true);
|
||||
|
||||
// implements LocalDestination
|
||||
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
|
||||
{
|
||||
|
||||
void RatchetTagSet::DHInitialize (const uint8_t * rootKey, const uint8_t * k)
|
||||
{
|
||||
// DH_INITIALIZE(rootKey, k)
|
||||
uint8_t keydata[64];
|
||||
i2p::crypto::HKDF (rootKey, k, 32, "KDFDHRatchetStep", keydata); // keydata = HKDF(rootKey, k, "KDFDHRatchetStep", 64)
|
||||
memcpy (m_NextRootKey, keydata, 32); // nextRootKey = keydata[0:31]
|
||||
i2p::crypto::HKDF (keydata + 32, nullptr, 0, "TagAndKeyGenKeys", m_KeyData.buf);
|
||||
// [sessTag_ck, symmKey_ck] = HKDF(keydata[32:63], ZEROLEN, "TagAndKeyGenKeys", 64)
|
||||
void RatchetTagSet::DHInitialize (const uint8_t * rootKey, const uint8_t * k)
|
||||
{
|
||||
// DH_INITIALIZE(rootKey, k)
|
||||
uint8_t keydata[64];
|
||||
i2p::crypto::HKDF (rootKey, k, 32, "KDFDHRatchetStep", keydata); // keydata = HKDF(rootKey, k, "KDFDHRatchetStep", 64)
|
||||
memcpy (m_NextRootKey, keydata, 32); // nextRootKey = keydata[0:31]
|
||||
i2p::crypto::HKDF (keydata + 32, nullptr, 0, "TagAndKeyGenKeys", m_KeyData.buf);
|
||||
// [sessTag_ck, symmKey_ck] = HKDF(keydata[32:63], ZEROLEN, "TagAndKeyGenKeys", 64)
|
||||
memcpy (m_SymmKeyCK, m_KeyData.buf + 32, 32);
|
||||
m_NextSymmKeyIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
memcpy (m_SessTagConstant, m_KeyData.GetSessTagConstant (), 32);
|
||||
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)
|
||||
memcpy (m_SessTagConstant, m_KeyData.GetSessTagConstant (), 32);
|
||||
m_NextIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
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)
|
||||
m_NextIndex++;
|
||||
if (m_NextIndex >= 65535)
|
||||
{
|
||||
LogPrint (eLogError, "Garlic: Tagset ", GetTagSetID (), " is empty");
|
||||
return 0;
|
||||
}
|
||||
return m_KeyData.GetTag ();
|
||||
}
|
||||
return m_KeyData.GetTag ();
|
||||
}
|
||||
|
||||
void RatchetTagSet::GetSymmKey (int index, uint8_t * key)
|
||||
{
|
||||
|
@ -85,15 +85,15 @@ namespace garlic
|
|||
m_ExpirationTimestamp = i2p::util::GetSecondsSinceEpoch () + ECIESX25519_PREVIOUS_TAGSET_EXPIRATION_TIMEOUT;
|
||||
}
|
||||
|
||||
ECIESX25519AEADRatchetSession::ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSet):
|
||||
GarlicRoutingSession (owner, attachLeaseSet)
|
||||
{
|
||||
ResetKeys ();
|
||||
}
|
||||
ECIESX25519AEADRatchetSession::ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSet):
|
||||
GarlicRoutingSession (owner, attachLeaseSet)
|
||||
{
|
||||
ResetKeys ();
|
||||
}
|
||||
|
||||
ECIESX25519AEADRatchetSession::~ECIESX25519AEADRatchetSession ()
|
||||
{
|
||||
}
|
||||
ECIESX25519AEADRatchetSession::~ECIESX25519AEADRatchetSession ()
|
||||
{
|
||||
}
|
||||
|
||||
void ECIESX25519AEADRatchetSession::ResetKeys ()
|
||||
{
|
||||
|
@ -111,14 +111,14 @@ namespace garlic
|
|||
memcpy (m_H, hh, 32);
|
||||
}
|
||||
|
||||
void ECIESX25519AEADRatchetSession::MixHash (const uint8_t * buf, size_t len)
|
||||
{
|
||||
SHA256_CTX ctx;
|
||||
void ECIESX25519AEADRatchetSession::MixHash (const uint8_t * buf, size_t len)
|
||||
{
|
||||
SHA256_CTX ctx;
|
||||
SHA256_Init (&ctx);
|
||||
SHA256_Update (&ctx, m_H, 32);
|
||||
SHA256_Update (&ctx, buf, len);
|
||||
SHA256_Final (m_H, &ctx);
|
||||
}
|
||||
}
|
||||
|
||||
void ECIESX25519AEADRatchetSession::CreateNonce (uint64_t seqn, uint8_t * nonce)
|
||||
{
|
||||
|
@ -126,48 +126,48 @@ namespace garlic
|
|||
htole64buf (nonce + 4, seqn);
|
||||
}
|
||||
|
||||
bool ECIESX25519AEADRatchetSession::GenerateEphemeralKeysAndEncode (uint8_t * buf)
|
||||
{
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
m_EphemeralKeys.GenerateKeys ();
|
||||
if (i2p::crypto::GetElligator ()->Encode (m_EphemeralKeys.GetPublicKey (), buf))
|
||||
return true; // success
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool ECIESX25519AEADRatchetSession::GenerateEphemeralKeysAndEncode (uint8_t * buf)
|
||||
{
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
m_EphemeralKeys.GenerateKeys ();
|
||||
if (i2p::crypto::GetElligator ()->Encode (m_EphemeralKeys.GetPublicKey (), buf))
|
||||
return true; // success
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::shared_ptr<RatchetTagSet> ECIESX25519AEADRatchetSession::CreateNewSessionTagset ()
|
||||
{
|
||||
uint8_t tagsetKey[32];
|
||||
i2p::crypto::HKDF (m_CK, nullptr, 0, "SessionReplyTags", tagsetKey, 32); // tagsetKey = HKDF(chainKey, ZEROLEN, "SessionReplyTags", 32)
|
||||
// Session Tag Ratchet
|
||||
auto tagsetNsr = std::make_shared<RatchetTagSet>(shared_from_this ());
|
||||
tagsetNsr->DHInitialize (m_CK, tagsetKey); // tagset_nsr = DH_INITIALIZE(chainKey, tagsetKey)
|
||||
tagsetNsr->NextSessionTagRatchet ();
|
||||
return tagsetNsr;
|
||||
}
|
||||
std::shared_ptr<RatchetTagSet> ECIESX25519AEADRatchetSession::CreateNewSessionTagset ()
|
||||
{
|
||||
uint8_t tagsetKey[32];
|
||||
i2p::crypto::HKDF (m_CK, nullptr, 0, "SessionReplyTags", tagsetKey, 32); // tagsetKey = HKDF(chainKey, ZEROLEN, "SessionReplyTags", 32)
|
||||
// Session Tag Ratchet
|
||||
auto tagsetNsr = std::make_shared<RatchetTagSet>(shared_from_this ());
|
||||
tagsetNsr->DHInitialize (m_CK, tagsetKey); // tagset_nsr = DH_INITIALIZE(chainKey, tagsetKey)
|
||||
tagsetNsr->NextSessionTagRatchet ();
|
||||
return tagsetNsr;
|
||||
}
|
||||
|
||||
bool ECIESX25519AEADRatchetSession::HandleNewIncomingSession (const uint8_t * buf, size_t len)
|
||||
{
|
||||
if (!GetOwner ()) return false;
|
||||
// we are Bob
|
||||
// KDF1
|
||||
MixHash (GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET), 32); // h = SHA256(h || bpk)
|
||||
bool ECIESX25519AEADRatchetSession::HandleNewIncomingSession (const uint8_t * buf, size_t len)
|
||||
{
|
||||
if (!GetOwner ()) return false;
|
||||
// we are Bob
|
||||
// KDF1
|
||||
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))
|
||||
{
|
||||
LogPrint (eLogError, "Garlic: Can't decode elligator");
|
||||
return false;
|
||||
}
|
||||
buf += 32; len -= 32;
|
||||
MixHash (m_Aepk, 32); // h = SHA256(h || aepk)
|
||||
buf += 32; len -= 32;
|
||||
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)
|
||||
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];
|
||||
CreateNonce (0, nonce);
|
||||
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)
|
||||
{
|
||||
// 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)
|
||||
i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64)
|
||||
}
|
||||
|
@ -198,17 +198,17 @@ namespace garlic
|
|||
return false;
|
||||
}
|
||||
if (isStatic) MixHash (buf, len); // h = SHA256(h || ciphertext)
|
||||
m_State = eSessionStateNewSessionReceived;
|
||||
m_State = eSessionStateNewSessionReceived;
|
||||
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)
|
||||
{
|
||||
size_t offset = 0;
|
||||
void ECIESX25519AEADRatchetSession::HandlePayload (const uint8_t * buf, size_t len, const std::shared_ptr<RatchetTagSet>& receiveTagset, int index)
|
||||
{
|
||||
size_t offset = 0;
|
||||
while (offset < len)
|
||||
{
|
||||
uint8_t blk = buf[offset];
|
||||
|
@ -269,7 +269,7 @@ namespace garlic
|
|||
}
|
||||
offset += size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
uint16_t keyID = bufbe16toh (buf); buf += 2; // 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)
|
||||
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");
|
||||
}
|
||||
|
||||
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 ();
|
||||
// we are Alice, bpk is m_RemoteStaticKey
|
||||
size_t offset = 0;
|
||||
if (!GenerateEphemeralKeysAndEncode (out + offset))
|
||||
// we are Alice, bpk is m_RemoteStaticKey
|
||||
size_t offset = 0;
|
||||
if (!GenerateEphemeralKeysAndEncode (out + offset))
|
||||
{
|
||||
LogPrint (eLogError, "Garlic: Can't encode elligator");
|
||||
return false;
|
||||
}
|
||||
offset += 32;
|
||||
offset += 32;
|
||||
|
||||
// KDF1
|
||||
MixHash (m_RemoteStaticKey, 32); // h = SHA256(h || bpk)
|
||||
MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || aepk)
|
||||
uint8_t sharedSecret[32];
|
||||
// KDF1
|
||||
MixHash (m_RemoteStaticKey, 32); // h = SHA256(h || bpk)
|
||||
MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || aepk)
|
||||
uint8_t sharedSecret[32];
|
||||
m_EphemeralKeys.Agree (m_RemoteStaticKey, sharedSecret); // x25519(aesk, bpk)
|
||||
i2p::crypto::HKDF (m_CK, sharedSecret, 32, "", m_CK); // [chainKey, key] = HKDF(chainKey, sharedSecret, "", 64)
|
||||
// encrypt static key section
|
||||
uint8_t nonce[12];
|
||||
// encrypt static key section
|
||||
uint8_t nonce[12];
|
||||
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
|
||||
{
|
||||
LogPrint (eLogWarning, "Garlic: Static section AEAD encryption failed ");
|
||||
return false;
|
||||
}
|
||||
MixHash (out + offset, 48); // h = SHA256(h || ciphertext)
|
||||
offset += 48;
|
||||
// KDF2
|
||||
GetOwner ()->Decrypt (m_RemoteStaticKey, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET); // x25519 (ask, bpk)
|
||||
MixHash (out + offset, 48); // h = SHA256(h || ciphertext)
|
||||
offset += 48;
|
||||
// KDF2
|
||||
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)
|
||||
// encrypt payload
|
||||
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)
|
||||
|
||||
m_State = eSessionStateNewSessionSent;
|
||||
if (GetOwner ())
|
||||
if (GetOwner ())
|
||||
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)
|
||||
{
|
||||
// we are Bob
|
||||
bool ECIESX25519AEADRatchetSession::NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen)
|
||||
{
|
||||
// we are Bob
|
||||
m_NSRTagset = CreateNewSessionTagset ();
|
||||
uint64_t tag = m_NSRTagset->GetNextSessionTag ();
|
||||
uint64_t tag = m_NSRTagset->GetNextSessionTag ();
|
||||
|
||||
size_t offset = 0;
|
||||
memcpy (out + offset, &tag, 8);
|
||||
offset += 8;
|
||||
if (!GenerateEphemeralKeysAndEncode (out + offset)) // bepk
|
||||
size_t offset = 0;
|
||||
memcpy (out + offset, &tag, 8);
|
||||
offset += 8;
|
||||
if (!GenerateEphemeralKeysAndEncode (out + offset)) // bepk
|
||||
{
|
||||
LogPrint (eLogError, "Garlic: Can't encode elligator");
|
||||
return false;
|
||||
}
|
||||
memcpy (m_NSREncodedKey, out + offset, 56); // for possible next NSR
|
||||
memcpy (m_NSRH, m_H, 32);
|
||||
offset += 32;
|
||||
// KDF for Reply Key Section
|
||||
MixHash ((const uint8_t *)&tag, 8); // h = SHA256(h || tag)
|
||||
MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || bepk)
|
||||
uint8_t sharedSecret[32];
|
||||
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)
|
||||
offset += 32;
|
||||
// KDF for Reply Key Section
|
||||
MixHash ((const uint8_t *)&tag, 8); // h = SHA256(h || tag)
|
||||
MixHash (m_EphemeralKeys.GetPublicKey (), 32); // h = SHA256(h || bepk)
|
||||
uint8_t sharedSecret[32];
|
||||
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)
|
||||
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];
|
||||
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)
|
||||
{
|
||||
LogPrint (eLogWarning, "Garlic: Reply key section AEAD encryption failed");
|
||||
return false;
|
||||
}
|
||||
MixHash (out + offset, 16); // h = SHA256(h || ciphertext)
|
||||
offset += 16;
|
||||
// KDF for payload
|
||||
uint8_t keydata[64];
|
||||
i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64)
|
||||
MixHash (out + offset, 16); // h = SHA256(h || ciphertext)
|
||||
offset += 16;
|
||||
// KDF for payload
|
||||
uint8_t keydata[64];
|
||||
i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64)
|
||||
// k_ab = keydata[0:31], k_ba = keydata[32:63]
|
||||
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 ();
|
||||
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 ();
|
||||
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)
|
||||
// encrypt payload
|
||||
if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_NSRKey, nonce, out + offset, len + 16, true)) // encrypt
|
||||
i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", m_NSRKey, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32)
|
||||
// encrypt payload
|
||||
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");
|
||||
return false;
|
||||
}
|
||||
m_State = eSessionStateNewSessionReplySent;
|
||||
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ECIESX25519AEADRatchetSession::NextNewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen)
|
||||
{
|
||||
// we are Bob and sent NSR already
|
||||
uint64_t tag = m_NSRTagset->GetNextSessionTag (); // next tag
|
||||
memcpy (out, &tag, 8);
|
||||
{
|
||||
// we are Bob and sent NSR already
|
||||
uint64_t tag = m_NSRTagset->GetNextSessionTag (); // next tag
|
||||
memcpy (out, &tag, 8);
|
||||
memcpy (out + 8, m_NSREncodedKey, 32);
|
||||
// recalculte h with new tag
|
||||
// recalculate h with new tag
|
||||
memcpy (m_H, m_NSRH, 32);
|
||||
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];
|
||||
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)
|
||||
|
@ -482,7 +482,7 @@ namespace garlic
|
|||
}
|
||||
MixHash (out + 40, 16); // h = SHA256(h || ciphertext)
|
||||
// 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");
|
||||
return false;
|
||||
|
@ -490,36 +490,36 @@ namespace garlic
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ECIESX25519AEADRatchetSession::HandleNewOutgoingSessionReply (uint8_t * buf, size_t len)
|
||||
{
|
||||
bool ECIESX25519AEADRatchetSession::HandleNewOutgoingSessionReply (uint8_t * buf, size_t len)
|
||||
{
|
||||
// we are Alice
|
||||
LogPrint (eLogDebug, "Garlic: reply received");
|
||||
const uint8_t * tag = buf;
|
||||
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))
|
||||
{
|
||||
LogPrint (eLogError, "Garlic: Can't decode elligator");
|
||||
return false;
|
||||
}
|
||||
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
|
||||
MixHash (tag, 8); // h = SHA256(h || tag)
|
||||
MixHash (bepk, 32); // h = SHA256(h || bepk)
|
||||
MixHash (tag, 8); // h = SHA256(h || tag)
|
||||
MixHash (bepk, 32); // h = SHA256(h || bepk)
|
||||
uint8_t sharedSecret[32];
|
||||
if (m_State == eSessionStateNewSessionSent)
|
||||
{
|
||||
// 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)
|
||||
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)
|
||||
}
|
||||
uint8_t nonce[12];
|
||||
CreateNonce (0, nonce);
|
||||
// calulate 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
|
||||
// calculate hash for zero length
|
||||
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");
|
||||
return false;
|
||||
|
@ -527,22 +527,22 @@ namespace garlic
|
|||
MixHash (buf, 16); // h = SHA256(h || ciphertext)
|
||||
buf += 16; len -= 16;
|
||||
// KDF for payload
|
||||
uint8_t keydata[64];
|
||||
i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64)
|
||||
uint8_t keydata[64];
|
||||
i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64)
|
||||
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->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 ();
|
||||
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 ();
|
||||
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
|
||||
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");
|
||||
return false;
|
||||
|
@ -560,8 +560,8 @@ namespace garlic
|
|||
SetLeaseSetUpdateStatus (eLeaseSetUpToDate);
|
||||
SetLeaseSetUpdateMsgID (0);
|
||||
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ECIESX25519AEADRatchetSession::NewExistingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen)
|
||||
{
|
||||
|
@ -637,61 +637,61 @@ namespace garlic
|
|||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<I2NPMessage> ECIESX25519AEADRatchetSession::WrapSingleMessage (std::shared_ptr<const I2NPMessage> msg)
|
||||
{
|
||||
auto payload = CreatePayload (msg, m_State != eSessionStateEstablished);
|
||||
size_t len = payload.size ();
|
||||
std::shared_ptr<I2NPMessage> ECIESX25519AEADRatchetSession::WrapSingleMessage (std::shared_ptr<const I2NPMessage> msg)
|
||||
{
|
||||
auto payload = CreatePayload (msg, m_State != eSessionStateEstablished);
|
||||
size_t len = payload.size ();
|
||||
if (!len) return nullptr;
|
||||
auto m = NewI2NPMessage (len + 100); // 96 + 4
|
||||
m->Align (12); // in order to get buf aligned to 16 (12 + 4)
|
||||
uint8_t * buf = m->GetPayload () + 4; // 4 bytes for length
|
||||
|
||||
switch (m_State)
|
||||
{
|
||||
switch (m_State)
|
||||
{
|
||||
case eSessionStateEstablished:
|
||||
if (!NewExistingSessionMessage (payload.data (), payload.size (), buf, m->maxLen))
|
||||
return nullptr;
|
||||
len += 24;
|
||||
break;
|
||||
case eSessionStateNew:
|
||||
if (!NewOutgoingSessionMessage (payload.data (), payload.size (), buf, m->maxLen))
|
||||
return nullptr;
|
||||
len += 96;
|
||||
break;
|
||||
case eSessionStateNewSessionReceived:
|
||||
if (!NewSessionReplyMessage (payload.data (), payload.size (), buf, m->maxLen))
|
||||
return nullptr;
|
||||
len += 72;
|
||||
break;
|
||||
case eSessionStateNew:
|
||||
if (!NewOutgoingSessionMessage (payload.data (), payload.size (), buf, m->maxLen))
|
||||
return nullptr;
|
||||
len += 96;
|
||||
break;
|
||||
case eSessionStateNewSessionReceived:
|
||||
if (!NewSessionReplyMessage (payload.data (), payload.size (), buf, m->maxLen))
|
||||
return nullptr;
|
||||
len += 72;
|
||||
break;
|
||||
case eSessionStateNewSessionReplySent:
|
||||
if (!NextNewSessionReplyMessage (payload.data (), payload.size (), buf, m->maxLen))
|
||||
return nullptr;
|
||||
len += 72;
|
||||
return nullptr;
|
||||
len += 72;
|
||||
break;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
htobe32buf (m->GetPayload (), len);
|
||||
htobe32buf (m->GetPayload (), len);
|
||||
m->len += len + 4;
|
||||
m->FillI2NPMessageHeader (eI2NPGarlic);
|
||||
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 ();
|
||||
size_t payloadLen = 0;
|
||||
size_t payloadLen = 0;
|
||||
if (first) payloadLen += 7;// datatime
|
||||
if (msg && m_Destination)
|
||||
payloadLen += msg->GetPayloadLength () + 13 + 32;
|
||||
if (msg && m_Destination)
|
||||
payloadLen += msg->GetPayloadLength () + 13 + 32;
|
||||
auto leaseSet = (GetLeaseSetUpdateStatus () == eLeaseSetUpdated ||
|
||||
(GetLeaseSetUpdateStatus () == eLeaseSetSubmitted &&
|
||||
ts > GetLeaseSetSubmissionTime () + LEASET_CONFIRMATION_TIMEOUT)) ?
|
||||
ts > GetLeaseSetSubmissionTime () + LEASET_CONFIRMATION_TIMEOUT)) ?
|
||||
GetOwner ()->GetLeaseSet () : nullptr;
|
||||
if (leaseSet)
|
||||
{
|
||||
payloadLen += leaseSet->GetBufferLen () + DATABASE_STORE_HEADER_SIZE + 13;
|
||||
payloadLen += leaseSet->GetBufferLen () + DATABASE_STORE_HEADER_SIZE + 13;
|
||||
if (!first)
|
||||
{
|
||||
// ack request
|
||||
|
@ -730,19 +730,19 @@ namespace garlic
|
|||
payloadLen += paddingSize + 3;
|
||||
}
|
||||
}
|
||||
std::vector<uint8_t> v(payloadLen);
|
||||
size_t offset = 0;
|
||||
// DateTime
|
||||
std::vector<uint8_t> v(payloadLen);
|
||||
size_t offset = 0;
|
||||
// DateTime
|
||||
if (first)
|
||||
{
|
||||
v[offset] = eECIESx25519BlkDateTime; offset++;
|
||||
htobe16buf (v.data () + offset, 4); offset += 2;
|
||||
htobe32buf (v.data () + offset, ts/1000); offset += 4; // in seconds
|
||||
v[offset] = eECIESx25519BlkDateTime; offset++;
|
||||
htobe16buf (v.data () + offset, 4); offset += 2;
|
||||
htobe32buf (v.data () + offset, ts/1000); offset += 4; // in seconds
|
||||
}
|
||||
// LeaseSet
|
||||
if (leaseSet)
|
||||
// LeaseSet
|
||||
if (leaseSet)
|
||||
{
|
||||
offset += CreateLeaseSetClove (leaseSet, ts, v.data () + offset, payloadLen - offset);
|
||||
offset += CreateLeaseSetClove (leaseSet, ts, v.data () + offset, payloadLen - offset);
|
||||
if (!first)
|
||||
{
|
||||
// ack request
|
||||
|
@ -752,13 +752,13 @@ namespace garlic
|
|||
}
|
||||
}
|
||||
// msg
|
||||
if (msg && m_Destination)
|
||||
offset += CreateGarlicClove (msg, v.data () + offset, payloadLen - offset, true);
|
||||
if (msg && m_Destination)
|
||||
offset += CreateGarlicClove (msg, v.data () + offset, payloadLen - offset, true);
|
||||
// ack
|
||||
if (m_AckRequests.size () > 0)
|
||||
{
|
||||
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)
|
||||
{
|
||||
htobe16buf (v.data () + offset, it.first); offset += 2;
|
||||
|
@ -801,24 +801,24 @@ namespace garlic
|
|||
offset += 32; // public key
|
||||
}
|
||||
}
|
||||
// padding
|
||||
// padding
|
||||
if (paddingSize)
|
||||
{
|
||||
v[offset] = eECIESx25519BlkPadding; offset++;
|
||||
htobe16buf (v.data () + offset, paddingSize); offset += 2;
|
||||
memset (v.data () + offset, 0, paddingSize); offset += paddingSize;
|
||||
v[offset] = eECIESx25519BlkPadding; offset++;
|
||||
htobe16buf (v.data () + offset, paddingSize); offset += 2;
|
||||
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)
|
||||
{
|
||||
if (!msg) return 0;
|
||||
uint16_t cloveSize = msg->GetPayloadLength () + 9 + 1;
|
||||
size_t ECIESX25519AEADRatchetSession::CreateGarlicClove (std::shared_ptr<const I2NPMessage> msg, uint8_t * buf, size_t len, bool isDestination)
|
||||
{
|
||||
if (!msg) return 0;
|
||||
uint16_t cloveSize = msg->GetPayloadLength () + 9 + 1;
|
||||
if (isDestination) cloveSize += 32;
|
||||
if ((int)len < cloveSize + 3) return 0;
|
||||
buf[0] = eECIESx25519BlkGalicClove; // clove type
|
||||
htobe16buf (buf + 1, cloveSize); // size
|
||||
if ((int)len < cloveSize + 3) return 0;
|
||||
buf[0] = eECIESx25519BlkGalicClove; // clove type
|
||||
htobe16buf (buf + 1, cloveSize); // size
|
||||
buf += 3;
|
||||
if (isDestination)
|
||||
{
|
||||
|
@ -828,15 +828,15 @@ namespace garlic
|
|||
else
|
||||
*buf = 0;
|
||||
buf++; // flag and delivery instructions
|
||||
*buf = msg->GetTypeID (); // I2NP msg type
|
||||
htobe32buf (buf + 1, msg->GetMsgID ()); // msgID
|
||||
htobe32buf (buf + 5, msg->GetExpiration ()/1000); // expiration in seconds
|
||||
memcpy (buf + 9, msg->GetPayload (), msg->GetPayloadLength ());
|
||||
return cloveSize + 3;
|
||||
}
|
||||
*buf = msg->GetTypeID (); // I2NP msg type
|
||||
htobe32buf (buf + 1, msg->GetMsgID ()); // msgID
|
||||
htobe32buf (buf + 5, msg->GetExpiration () / 1000); // expiration in seconds
|
||||
memcpy (buf + 9, msg->GetPayload (), msg->GetPayloadLength ());
|
||||
return cloveSize + 3;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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
|
||||
if ((int)len < cloveSize + 3) return 0;
|
||||
buf[0] = eECIESx25519BlkGalicClove; // clove type
|
||||
htobe16buf (buf + 1, cloveSize); // size
|
||||
htobe16buf (buf + 1, cloveSize); // size
|
||||
buf += 3;
|
||||
*buf = 0; buf++; // flag and delivery instructions
|
||||
*buf = eI2NPDatabaseStore; buf++; // I2NP msg type
|
||||
|
@ -885,14 +885,14 @@ namespace garlic
|
|||
auto payload = buf + offset;
|
||||
uint16_t cloveSize = msg->GetPayloadLength () + 9 + 1;
|
||||
size_t len = cloveSize + 3;
|
||||
payload[0] = eECIESx25519BlkGalicClove; // clove type
|
||||
htobe16buf (payload + 1, cloveSize); // size
|
||||
payload[0] = eECIESx25519BlkGalicClove; // clove type
|
||||
htobe16buf (payload + 1, cloveSize); // size
|
||||
payload += 3;
|
||||
*payload = 0; payload++; // flag and delivery instructions
|
||||
*payload = msg->GetTypeID (); // I2NP msg type
|
||||
htobe32buf (payload + 1, msg->GetMsgID ()); // msgID
|
||||
htobe32buf (payload + 5, msg->GetExpiration ()/1000); // expiration in seconds
|
||||
memcpy (payload + 9, msg->GetPayload (), msg->GetPayloadLength ());
|
||||
*payload = 0; payload++; // flag and delivery instructions
|
||||
*payload = msg->GetTypeID (); // I2NP msg type
|
||||
htobe32buf (payload + 1, msg->GetMsgID ()); // msgID
|
||||
htobe32buf (payload + 5, msg->GetExpiration () / 1000); // expiration in seconds
|
||||
memcpy (payload + 9, msg->GetPayload (), msg->GetPayloadLength ());
|
||||
|
||||
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_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 */
|
||||
|
||||
class ECIESX25519AEADRatchetSession;
|
||||
class RatchetTagSet
|
||||
{
|
||||
public:
|
||||
class RatchetTagSet
|
||||
{
|
||||
public:
|
||||
|
||||
RatchetTagSet (std::shared_ptr<ECIESX25519AEADRatchetSession> session): m_Session (session) {};
|
||||
|
||||
void DHInitialize (const uint8_t * rootKey, const uint8_t * k);
|
||||
void NextSessionTagRatchet ();
|
||||
uint64_t GetNextSessionTag ();
|
||||
void DHInitialize (const uint8_t * rootKey, const uint8_t * k);
|
||||
void NextSessionTagRatchet ();
|
||||
uint64_t GetNextSessionTag ();
|
||||
const uint8_t * GetNextRootKey () const { return m_NextRootKey; };
|
||||
int GetNextIndex () const { return m_NextIndex; };
|
||||
void GetSymmKey (int index, uint8_t * key);
|
||||
|
@ -52,51 +52,51 @@ namespace garlic
|
|||
|
||||
private:
|
||||
|
||||
union
|
||||
{
|
||||
uint64_t ll[8];
|
||||
uint8_t buf[64];
|
||||
union
|
||||
{
|
||||
uint64_t ll[8];
|
||||
uint8_t buf[64];
|
||||
|
||||
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]
|
||||
uint64_t GetTag () const { return ll[4]; }; // tag = keydata[32:39]
|
||||
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]
|
||||
uint64_t GetTag () const { return ll[4]; }; // tag = keydata[32:39]
|
||||
|
||||
} m_KeyData;
|
||||
uint8_t m_SessTagConstant[32], m_SymmKeyCK[32], m_CurrentSymmKeyCK[64], m_NextRootKey[32];
|
||||
int m_NextIndex, m_NextSymmKeyIndex;
|
||||
std::unordered_map<int, i2p::data::Tag<32> > m_ItermediateSymmKeys;
|
||||
std::weak_ptr<ECIESX25519AEADRatchetSession> m_Session;
|
||||
int m_TagSetID = 0;
|
||||
uint64_t m_ExpirationTimestamp = 0;
|
||||
};
|
||||
} m_KeyData;
|
||||
uint8_t m_SessTagConstant[32], m_SymmKeyCK[32], m_CurrentSymmKeyCK[64], m_NextRootKey[32];
|
||||
int m_NextIndex, m_NextSymmKeyIndex;
|
||||
std::unordered_map<int, i2p::data::Tag<32> > m_ItermediateSymmKeys;
|
||||
std::weak_ptr<ECIESX25519AEADRatchetSession> m_Session;
|
||||
int m_TagSetID = 0;
|
||||
uint64_t m_ExpirationTimestamp = 0;
|
||||
};
|
||||
|
||||
enum ECIESx25519BlockType
|
||||
enum ECIESx25519BlockType
|
||||
{
|
||||
eECIESx25519BlkDateTime = 0,
|
||||
eECIESx25519BlkSessionID = 1,
|
||||
eECIESx25519BlkDateTime = 0,
|
||||
eECIESx25519BlkSessionID = 1,
|
||||
eECIESx25519BlkTermination = 4,
|
||||
eECIESx25519BlkOptions = 5,
|
||||
eECIESx25519BlkNextKey = 7,
|
||||
eECIESx25519BlkAck = 8,
|
||||
eECIESx25519BlkAckRequest = 9,
|
||||
eECIESx25519BlkGalicClove = 11,
|
||||
eECIESx25519BlkPadding = 254
|
||||
eECIESx25519BlkOptions = 5,
|
||||
eECIESx25519BlkNextKey = 7,
|
||||
eECIESx25519BlkAck = 8,
|
||||
eECIESx25519BlkAckRequest = 9,
|
||||
eECIESx25519BlkGalicClove = 11,
|
||||
eECIESx25519BlkPadding = 254
|
||||
};
|
||||
|
||||
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_REQUEST_REVERSE_KEY_FLAG = 0x04;
|
||||
|
||||
class ECIESX25519AEADRatchetSession: public GarlicRoutingSession, public std::enable_shared_from_this<ECIESX25519AEADRatchetSession>
|
||||
{
|
||||
enum SessionState
|
||||
{
|
||||
eSessionStateNew =0,
|
||||
eSessionStateNewSessionReceived,
|
||||
class ECIESX25519AEADRatchetSession: public GarlicRoutingSession, public std::enable_shared_from_this<ECIESX25519AEADRatchetSession>
|
||||
{
|
||||
enum SessionState
|
||||
{
|
||||
eSessionStateNew = 0,
|
||||
eSessionStateNewSessionReceived,
|
||||
eSessionStateNewSessionSent,
|
||||
eSessionStateNewSessionReplySent,
|
||||
eSessionStateEstablished
|
||||
};
|
||||
};
|
||||
|
||||
struct DHRatchet
|
||||
{
|
||||
|
@ -106,15 +106,15 @@ namespace garlic
|
|||
bool newKey = true;
|
||||
};
|
||||
|
||||
public:
|
||||
public:
|
||||
|
||||
ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSet);
|
||||
~ECIESX25519AEADRatchetSession ();
|
||||
ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSet);
|
||||
~ECIESX25519AEADRatchetSession ();
|
||||
|
||||
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 SetDestination (const i2p::data::IdentHash& dest) // TODO:
|
||||
|
@ -127,41 +127,41 @@ namespace garlic
|
|||
|
||||
bool IsRatchets () const { return true; };
|
||||
|
||||
private:
|
||||
private:
|
||||
|
||||
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);
|
||||
bool GenerateEphemeralKeysAndEncode (uint8_t * buf); // buf is 32 bytes
|
||||
bool GenerateEphemeralKeysAndEncode (uint8_t * buf); // buf is 32 bytes
|
||||
std::shared_ptr<RatchetTagSet> CreateNewSessionTagset ();
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
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 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 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);
|
||||
|
||||
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);
|
||||
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 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 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_NSREncodedKey[32], m_NSRH[32], m_NSRKey[32]; // new session reply, for incoming only
|
||||
i2p::crypto::X25519Keys m_EphemeralKeys;
|
||||
SessionState m_State = eSessionStateNew;
|
||||
i2p::crypto::X25519Keys m_EphemeralKeys;
|
||||
SessionState m_State = eSessionStateNew;
|
||||
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::list<std::pair<uint16_t, int> > m_AckRequests; // (tagsetid, index)
|
||||
bool m_SendReverseKey = false, m_SendForwardKey = false;
|
||||
|
@ -175,7 +175,7 @@ namespace garlic
|
|||
{
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -597,4 +597,3 @@ namespace crypto
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -128,6 +128,4 @@ namespace crypto
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace crypto
|
|||
}
|
||||
|
||||
bool Elligator2::Encode (const uint8_t * key, uint8_t * encoded, bool highY, bool random) const
|
||||
{
|
||||
{
|
||||
bool ret = true;
|
||||
BN_CTX * ctx = BN_CTX_new ();
|
||||
BN_CTX_start (ctx);
|
||||
|
@ -63,11 +63,11 @@ namespace crypto
|
|||
|
||||
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)
|
||||
{
|
||||
RAND_bytes (&randByte, 1);
|
||||
highY = randByte & 0x01;
|
||||
RAND_bytes (&randByte, 1);
|
||||
highY = randByte & 0x01;
|
||||
}
|
||||
|
||||
BIGNUM * r = BN_CTX_get (ctx);
|
||||
|
@ -87,7 +87,7 @@ namespace crypto
|
|||
bn2buf (r, encoded, 32);
|
||||
|
||||
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
|
||||
{
|
||||
uint8_t tmp = encoded[i];
|
||||
|
@ -115,7 +115,7 @@ namespace crypto
|
|||
encoded1[i] = encoded[31 - 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);
|
||||
|
||||
|
@ -184,7 +184,7 @@ namespace crypto
|
|||
BN_mod_exp (r, a, p12, p, ctx); // r = a^((p-1)/2) mod p
|
||||
if (BN_is_word(r, 1))
|
||||
return 1;
|
||||
else if (BN_is_zero(r))
|
||||
else if (BN_is_zero(r))
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
@ -204,4 +204,3 @@ namespace crypto
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,5 +35,3 @@ namespace crypto
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
221
libi2pd/FS.h
221
libi2pd/FS.h
|
@ -17,133 +17,136 @@
|
|||
|
||||
namespace i2p {
|
||||
namespace fs {
|
||||
extern std::string dirSep;
|
||||
extern std::string dirSep;
|
||||
|
||||
/**
|
||||
* @brief Class to work with NetDb & Router profiles
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* const char alphabet[8] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
|
||||
* auto h = HashedStorage("name", "y", "z-", ".txt");
|
||||
* h.SetPlace("/tmp/hs-test");
|
||||
* h.GetName() -> gives "name"
|
||||
* h.GetRoot() -> gives "/tmp/hs-test/name"
|
||||
* 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.Remove("abcd"); <- removes /tmp/hs-test/name/ya/z-abcd.txt, if it exists
|
||||
* std::vector<std::string> files;
|
||||
* h.Traverse(files); <- finds all files in storage and saves in given vector
|
||||
*/
|
||||
class HashedStorage {
|
||||
protected:
|
||||
std::string root; /**< path to storage with it's name included */
|
||||
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) */
|
||||
/**
|
||||
* @brief Class to work with NetDb & Router profiles
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* const char alphabet[8] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
|
||||
* auto h = HashedStorage("name", "y", "z-", ".txt");
|
||||
* h.SetPlace("/tmp/hs-test");
|
||||
* h.GetName() -> gives "name"
|
||||
* h.GetRoot() -> gives "/tmp/hs-test/name"
|
||||
* 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.Remove("abcd"); <- removes /tmp/hs-test/name/ya/z-abcd.txt, if it exists
|
||||
* std::vector<std::string> files;
|
||||
* h.Traverse(files); <- finds all files in storage and saves in given vector
|
||||
*/
|
||||
class HashedStorage
|
||||
{
|
||||
protected:
|
||||
|
||||
public:
|
||||
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) {};
|
||||
std::string root; /**< path to storage with it's name included */
|
||||
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) */
|
||||
|
||||
/** 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);
|
||||
};
|
||||
public:
|
||||
|
||||
/** @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 ();
|
||||
/** @brief Set application name, affects autodetection of datadir */
|
||||
/** @brief Set application name, affects autodetection of datadir */
|
||||
void SetAppName (const std::string& name);
|
||||
|
||||
/** @brief Returns datadir path */
|
||||
const std::string & GetDataDir();
|
||||
/** @brief Returns datadir path */
|
||||
const std::string & GetDataDir();
|
||||
|
||||
/**
|
||||
* @brief Set datadir either from cmdline option or using autodetection
|
||||
* @param cmdline_param Value of cmdline parameter --datadir=<something>
|
||||
* @param isService Value of cmdline parameter --service
|
||||
*
|
||||
* Examples of autodetected paths:
|
||||
*
|
||||
* Windows < Vista: C:\Documents and Settings\Username\Application Data\i2pd\
|
||||
* Windows >= Vista: C:\Users\Username\AppData\Roaming\i2pd\
|
||||
* Mac: /Library/Application Support/i2pd/ or ~/Library/Application Support/i2pd/
|
||||
* Unix: /var/lib/i2pd/ (system=1) >> ~/.i2pd/ or /tmp/i2pd/
|
||||
*/
|
||||
void DetectDataDir(const std::string & cmdline_datadir, bool isService = false);
|
||||
/**
|
||||
* @brief Set datadir either from cmdline option or using autodetection
|
||||
* @param cmdline_param Value of cmdline parameter --datadir=<something>
|
||||
* @param isService Value of cmdline parameter --service
|
||||
*
|
||||
* Examples of autodetected paths:
|
||||
*
|
||||
* Windows < Vista: C:\Documents and Settings\Username\Application Data\i2pd\
|
||||
* Windows >= Vista: C:\Users\Username\AppData\Roaming\i2pd\
|
||||
* Mac: /Library/Application Support/i2pd/ or ~/Library/Application Support/i2pd/
|
||||
* Unix: /var/lib/i2pd/ (system=1) >> ~/.i2pd/ or /tmp/i2pd/
|
||||
*/
|
||||
void DetectDataDir(const std::string & cmdline_datadir, bool isService = false);
|
||||
|
||||
/**
|
||||
* @brief Create subdirectories inside datadir
|
||||
*/
|
||||
bool Init();
|
||||
/**
|
||||
* @brief Create subdirectories inside datadir
|
||||
*/
|
||||
bool Init();
|
||||
|
||||
/**
|
||||
* @brief Get list of files in directory
|
||||
* @param path Path to directory
|
||||
* @param files Vector to store found files
|
||||
* @return true on success and false if directory not exists
|
||||
*/
|
||||
bool ReadDir(const std::string & path, std::vector<std::string> & files);
|
||||
/**
|
||||
* @brief Get list of files in directory
|
||||
* @param path Path to directory
|
||||
* @param files Vector to store found files
|
||||
* @return true on success and false if directory not exists
|
||||
*/
|
||||
bool ReadDir(const std::string & path, std::vector<std::string> & files);
|
||||
|
||||
/**
|
||||
* @brief Remove file with given path
|
||||
* @param path Absolute path to file
|
||||
* @return true on success, false if file not exists, throws exception on error
|
||||
*/
|
||||
bool Remove(const std::string & path);
|
||||
/**
|
||||
* @brief Remove file with given path
|
||||
* @param path Absolute path to file
|
||||
* @return true on success, false if file not exists, throws exception on error
|
||||
*/
|
||||
bool Remove(const std::string & path);
|
||||
|
||||
/**
|
||||
* @brief Check existence of file
|
||||
* @param path Absolute path to file
|
||||
* @return true if file exists, false otherwise
|
||||
*/
|
||||
bool Exists(const std::string & path);
|
||||
/**
|
||||
* @brief Check existence of file
|
||||
* @param path Absolute path to file
|
||||
* @return true if file exists, false otherwise
|
||||
*/
|
||||
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>
|
||||
void _ExpandPath(std::stringstream & path, T c) {
|
||||
path << i2p::fs::dirSep << c;
|
||||
}
|
||||
template<typename T>
|
||||
void _ExpandPath(std::stringstream & path, T c) {
|
||||
path << i2p::fs::dirSep << c;
|
||||
}
|
||||
|
||||
template<typename T, typename ... Other>
|
||||
void _ExpandPath(std::stringstream & path, T c, Other ... other) {
|
||||
_ExpandPath(path, c);
|
||||
_ExpandPath(path, other ...);
|
||||
}
|
||||
template<typename T, typename ... Other>
|
||||
void _ExpandPath(std::stringstream & path, T c, Other ... other) {
|
||||
_ExpandPath(path, c);
|
||||
_ExpandPath(path, other ...);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get path relative to datadir
|
||||
*
|
||||
* Examples (with datadir = "/tmp/i2pd"):
|
||||
*
|
||||
* i2p::fs::Path("test") -> '/tmp/i2pd/test'
|
||||
* i2p::fs::Path("test", "file.txt") -> '/tmp/i2pd/test/file.txt'
|
||||
*/
|
||||
template<typename ... Other>
|
||||
std::string DataDirPath(Other ... components) {
|
||||
std::stringstream s("");
|
||||
s << i2p::fs::GetDataDir();
|
||||
_ExpandPath(s, components ...);
|
||||
/**
|
||||
* @brief Get path relative to datadir
|
||||
*
|
||||
* Examples (with datadir = "/tmp/i2pd"):
|
||||
*
|
||||
* i2p::fs::Path("test") -> '/tmp/i2pd/test'
|
||||
* i2p::fs::Path("test", "file.txt") -> '/tmp/i2pd/test/file.txt'
|
||||
*/
|
||||
template<typename ... Other>
|
||||
std::string DataDirPath(Other ... components) {
|
||||
std::stringstream s("");
|
||||
s << i2p::fs::GetDataDir();
|
||||
_ExpandPath(s, components ...);
|
||||
|
||||
return s.str();
|
||||
}
|
||||
return s.str();
|
||||
}
|
||||
|
||||
template<typename Storage, typename... Filename>
|
||||
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;
|
||||
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
||||
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 > m_SharedRoutingPath->updateTime + ROUTING_PATH_EXPIRATION_TIMEOUT)
|
||||
ts > m_SharedRoutingPath->updateTime + ROUTING_PATH_EXPIRATION_TIMEOUT)
|
||||
m_SharedRoutingPath = nullptr;
|
||||
if (m_SharedRoutingPath) m_SharedRoutingPath->numTimesUsed++;
|
||||
return m_SharedRoutingPath;
|
||||
|
@ -96,10 +96,10 @@ namespace garlic
|
|||
return msg;
|
||||
}
|
||||
|
||||
ElGamalAESSession::ElGamalAESSession (GarlicDestination * owner,
|
||||
std::shared_ptr<const i2p::data::RoutingDestination> destination, int numTags, bool attachLeaseSet):
|
||||
GarlicRoutingSession (owner, attachLeaseSet),
|
||||
m_Destination (destination), m_NumTags (numTags)
|
||||
ElGamalAESSession::ElGamalAESSession (GarlicDestination * owner,
|
||||
std::shared_ptr<const i2p::data::RoutingDestination> destination, int numTags, bool attachLeaseSet):
|
||||
GarlicRoutingSession (owner, attachLeaseSet),
|
||||
m_Destination (destination), m_NumTags (numTags)
|
||||
{
|
||||
// create new session tags and session key
|
||||
RAND_bytes (m_SessionKey, 32);
|
||||
|
@ -115,7 +115,7 @@ namespace garlic
|
|||
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 ();
|
||||
m->Align (12); // in order to get buf aligned to 16 (12 + 4)
|
||||
|
@ -181,7 +181,7 @@ namespace garlic
|
|||
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;
|
||||
bool createNewTags = GetOwner () && m_NumTags && ((int)m_SessionTags.size () <= m_NumTags*2/3);
|
||||
|
@ -353,7 +353,7 @@ namespace garlic
|
|||
return size;
|
||||
}
|
||||
|
||||
ElGamalAESSession::UnconfirmedTags * ElGamalAESSession::GenerateSessionTags ()
|
||||
ElGamalAESSession::UnconfirmedTags * ElGamalAESSession::GenerateSessionTags ()
|
||||
{
|
||||
auto tags = new UnconfirmedTags (m_NumTags);
|
||||
tags->tagsCreationTime = i2p::util::GetSecondsSinceEpoch ();
|
||||
|
@ -525,7 +525,7 @@ namespace garlic
|
|||
// otherwise ECIESx25519
|
||||
auto session = std::make_shared<ECIESX25519AEADRatchetSession> (this, false); // incoming
|
||||
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
|
||||
LogPrint (eLogError, "Garlic: Failed to decrypt message");
|
||||
|
@ -703,41 +703,41 @@ namespace garlic
|
|||
std::shared_ptr<GarlicRoutingSession> GarlicDestination::GetRoutingSession (
|
||||
std::shared_ptr<const i2p::data::RoutingDestination> destination, bool attachLeaseSet)
|
||||
{
|
||||
if (destination->GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET &&
|
||||
SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET))
|
||||
{
|
||||
ECIESX25519AEADRatchetSessionPtr session;
|
||||
uint8_t staticKey[32];
|
||||
destination->Encrypt (nullptr, staticKey, nullptr); // we are supposed to get static key
|
||||
auto it = m_ECIESx25519Sessions.find (staticKey);
|
||||
if (destination->GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET &&
|
||||
SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET))
|
||||
{
|
||||
ECIESX25519AEADRatchetSessionPtr session;
|
||||
uint8_t staticKey[32];
|
||||
destination->Encrypt (nullptr, staticKey, nullptr); // we are supposed to get static key
|
||||
auto it = m_ECIESx25519Sessions.find (staticKey);
|
||||
if (it != m_ECIESx25519Sessions.end ())
|
||||
session = it->second;
|
||||
if (!session)
|
||||
session = it->second;
|
||||
if (!session)
|
||||
{
|
||||
session = std::make_shared<ECIESX25519AEADRatchetSession> (this, true);
|
||||
session->SetRemoteStaticKey (staticKey);
|
||||
}
|
||||
session->SetDestination (destination->GetIdentHash ()); // TODO: remove
|
||||
return session;
|
||||
}
|
||||
else
|
||||
{
|
||||
ElGamalAESSessionPtr session;
|
||||
{
|
||||
std::unique_lock<std::mutex> l(m_SessionsMutex);
|
||||
auto it = m_Sessions.find (destination->GetIdentHash ());
|
||||
if (it != m_Sessions.end ())
|
||||
session = it->second;
|
||||
}
|
||||
if (!session)
|
||||
{
|
||||
session = std::make_shared<ElGamalAESSession> (this, destination,
|
||||
attachLeaseSet ? m_NumTags : 4, attachLeaseSet); // specified num tags for connections and 4 for LS requests
|
||||
std::unique_lock<std::mutex> l(m_SessionsMutex);
|
||||
m_Sessions[destination->GetIdentHash ()] = session;
|
||||
}
|
||||
return session;
|
||||
}
|
||||
return session;
|
||||
}
|
||||
else
|
||||
{
|
||||
ElGamalAESSessionPtr session;
|
||||
{
|
||||
std::unique_lock<std::mutex> l(m_SessionsMutex);
|
||||
auto it = m_Sessions.find (destination->GetIdentHash ());
|
||||
if (it != m_Sessions.end ())
|
||||
session = it->second;
|
||||
}
|
||||
if (!session)
|
||||
{
|
||||
session = std::make_shared<ElGamalAESSession> (this, destination,
|
||||
attachLeaseSet ? m_NumTags : 4, attachLeaseSet); // specified num tags for connections and 4 for LS requests
|
||||
std::unique_lock<std::mutex> l(m_SessionsMutex);
|
||||
m_Sessions[destination->GetIdentHash ()] = session;
|
||||
}
|
||||
return session;
|
||||
}
|
||||
}
|
||||
|
||||
void GarlicDestination::CleanupExpiredTags ()
|
||||
|
@ -925,20 +925,20 @@ namespace garlic
|
|||
std::vector<std::string> files;
|
||||
i2p::fs::ReadDir (i2p::fs::DataDirPath("tags"), files);
|
||||
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
||||
for (auto it: files)
|
||||
for (auto it: files)
|
||||
if (ts >= i2p::fs::GetLastUpdateTime (it) + INCOMING_TAGS_EXPIRATION_TIMEOUT)
|
||||
i2p::fs::Remove (it);
|
||||
}
|
||||
|
||||
void GarlicDestination::HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len)
|
||||
{
|
||||
const uint8_t * buf1 = buf;
|
||||
void GarlicDestination::HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len)
|
||||
{
|
||||
const uint8_t * buf1 = buf;
|
||||
uint8_t flag = buf[0]; buf++; // flag
|
||||
GarlicDeliveryType deliveryType = (GarlicDeliveryType)((flag >> 5) & 0x03);
|
||||
switch (deliveryType)
|
||||
{
|
||||
case eGarlicDeliveryTypeDestination:
|
||||
LogPrint (eLogDebug, "Garlic: type destination");
|
||||
LogPrint (eLogDebug, "Garlic: type destination");
|
||||
buf += 32; // TODO: check destination
|
||||
#if (__cplusplus >= 201703L) // C++ 17 or higher
|
||||
[[fallthrough]];
|
||||
|
@ -946,7 +946,7 @@ namespace garlic
|
|||
// no break here
|
||||
case eGarlicDeliveryTypeLocal:
|
||||
{
|
||||
LogPrint (eLogDebug, "Garlic: type local");
|
||||
LogPrint (eLogDebug, "Garlic: type local");
|
||||
I2NPMessageType typeID = (I2NPMessageType)(buf[0]); buf++; // typeid
|
||||
buf += (4 + 4); // msgID + expiration
|
||||
ptrdiff_t offset = buf - buf1;
|
||||
|
@ -957,8 +957,8 @@ namespace garlic
|
|||
break;
|
||||
}
|
||||
case eGarlicDeliveryTypeTunnel:
|
||||
{
|
||||
LogPrint (eLogDebug, "Garlic: type tunnel");
|
||||
{
|
||||
LogPrint (eLogDebug, "Garlic: type tunnel");
|
||||
// gwHash and gwTunnel sequence is reverted
|
||||
const uint8_t * gwHash = buf;
|
||||
buf += 32;
|
||||
|
@ -969,32 +969,32 @@ namespace garlic
|
|||
break;
|
||||
}
|
||||
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
|
||||
offset += 13;
|
||||
offset += 13;
|
||||
if (GetTunnelPool ())
|
||||
{
|
||||
auto tunnel = GetTunnelPool ()->GetNextOutboundTunnel ();
|
||||
if (tunnel)
|
||||
tunnel->SendTunnelDataMsg (gwHash, gwTunnel, CreateI2NPMessage (typeID, buf, len - offset));
|
||||
{
|
||||
auto tunnel = GetTunnelPool ()->GetNextOutboundTunnel ();
|
||||
if (tunnel)
|
||||
tunnel->SendTunnelDataMsg (gwHash, gwTunnel, CreateI2NPMessage (typeID, buf, len - offset));
|
||||
else
|
||||
LogPrint (eLogWarning, "Garlic: No outbound tunnels available for garlic clove");
|
||||
}
|
||||
LogPrint (eLogWarning, "Garlic: No outbound tunnels available for garlic clove");
|
||||
}
|
||||
else
|
||||
LogPrint (eLogError, "Garlic: Tunnel pool is not set for inbound tunnel");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LogPrint (eLogWarning, "Garlic: unexpected delivery type ", (int)deliveryType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GarlicDestination::AddECIESx25519SessionNextTag (RatchetTagSetPtr tagset)
|
||||
{
|
||||
void GarlicDestination::AddECIESx25519SessionNextTag (RatchetTagSetPtr tagset)
|
||||
{
|
||||
auto index = tagset->GetNextIndex ();
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -87,7 +87,7 @@ namespace garlic
|
|||
class GarlicDestination;
|
||||
class GarlicRoutingSession
|
||||
{
|
||||
protected:
|
||||
protected:
|
||||
|
||||
enum LeaseSetUpdateStatus
|
||||
{
|
||||
|
@ -103,7 +103,7 @@ namespace garlic
|
|||
GarlicRoutingSession ();
|
||||
virtual ~GarlicRoutingSession ();
|
||||
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 IsRatchets () const { return false; };
|
||||
|
||||
|
@ -122,13 +122,13 @@ namespace garlic
|
|||
GarlicDestination * GetOwner () const { return m_Owner; }
|
||||
void SetOwner (GarlicDestination * owner) { m_Owner = owner; }
|
||||
|
||||
protected:
|
||||
protected:
|
||||
|
||||
LeaseSetUpdateStatus GetLeaseSetUpdateStatus () const { return m_LeaseSetUpdateStatus; }
|
||||
void SetLeaseSetUpdateStatus (LeaseSetUpdateStatus status) { m_LeaseSetUpdateStatus = status; }
|
||||
uint32_t GetLeaseSetUpdateMsgID () const { return m_LeaseSetUpdateMsgID; }
|
||||
void SetLeaseSetUpdateMsgID (uint32_t msgID) { m_LeaseSetUpdateMsgID = msgID; }
|
||||
void SetLeaseSetSubmissionTime (uint64_t ts) { m_LeaseSetSubmissionTime = ts; }
|
||||
LeaseSetUpdateStatus GetLeaseSetUpdateStatus () const { return m_LeaseSetUpdateStatus; }
|
||||
void SetLeaseSetUpdateStatus (LeaseSetUpdateStatus status) { m_LeaseSetUpdateStatus = status; }
|
||||
uint32_t GetLeaseSetUpdateMsgID () const { return m_LeaseSetUpdateMsgID; }
|
||||
void SetLeaseSetUpdateMsgID (uint32_t msgID) { m_LeaseSetUpdateMsgID = msgID; }
|
||||
void SetLeaseSetSubmissionTime (uint64_t ts) { m_LeaseSetSubmissionTime = ts; }
|
||||
|
||||
std::shared_ptr<I2NPMessage> CreateEncryptedDeliveryStatusMsg (uint32_t msgID);
|
||||
|
||||
|
@ -143,38 +143,39 @@ namespace garlic
|
|||
std::shared_ptr<GarlicRoutingPath> m_SharedRoutingPath;
|
||||
|
||||
public:
|
||||
|
||||
// for HTTP only
|
||||
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
|
||||
|
||||
class ElGamalAESSession: public GarlicRoutingSession, public std::enable_shared_from_this<ElGamalAESSession>
|
||||
{
|
||||
struct UnconfirmedTags
|
||||
{
|
||||
UnconfirmedTags (int n): numTags (n), tagsCreationTime (0) { sessionTags = new SessionTag[numTags]; };
|
||||
~UnconfirmedTags () { delete[] sessionTags; };
|
||||
uint32_t msgID;
|
||||
int numTags;
|
||||
SessionTag * sessionTags;
|
||||
uint32_t tagsCreationTime;
|
||||
};
|
||||
class ElGamalAESSession: public GarlicRoutingSession, public std::enable_shared_from_this<ElGamalAESSession>
|
||||
{
|
||||
struct UnconfirmedTags
|
||||
{
|
||||
UnconfirmedTags (int n): numTags (n), tagsCreationTime (0) { sessionTags = new SessionTag[numTags]; };
|
||||
~UnconfirmedTags () { delete[] sessionTags; };
|
||||
uint32_t msgID;
|
||||
int numTags;
|
||||
SessionTag * sessionTags;
|
||||
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);
|
||||
ElGamalAESSession (const uint8_t * sessionKey, const SessionTag& sessionTag); // one time encryption
|
||||
~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 CleanupUnconfirmedTags (); // returns true if something has been deleted
|
||||
|
||||
private:
|
||||
private:
|
||||
|
||||
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);
|
||||
|
@ -184,25 +185,26 @@ namespace garlic
|
|||
void TagsConfirmed (uint32_t msgID);
|
||||
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;
|
||||
int m_NumTags;
|
||||
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
|
||||
size_t GetNumOutgoingTags () const { return m_SessionTags.size (); };
|
||||
};
|
||||
};
|
||||
typedef std::shared_ptr<ElGamalAESSession> ElGamalAESSessionPtr;
|
||||
|
||||
class ECIESX25519AEADRatchetSession;
|
||||
typedef std::shared_ptr<ECIESX25519AEADRatchetSession> ECIESX25519AEADRatchetSessionPtr;
|
||||
class ECIESX25519AEADRatchetSession;
|
||||
typedef std::shared_ptr<ECIESX25519AEADRatchetSession> ECIESX25519AEADRatchetSessionPtr;
|
||||
class RatchetTagSet;
|
||||
typedef std::shared_ptr<RatchetTagSet> RatchetTagSetPtr;
|
||||
struct ECIESX25519AEADRatchetIndexTagset
|
||||
|
@ -226,12 +228,12 @@ namespace garlic
|
|||
void CleanupExpiredTags ();
|
||||
void RemoveDeliveryStatusSession (uint32_t msgID);
|
||||
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
|
||||
virtual bool SubmitSessionKey (const uint8_t * key, const uint8_t * tag); // from different thread
|
||||
void DeliveryStatusSent (GarlicRoutingSessionPtr session, uint32_t msgID);
|
||||
void AddECIESx25519SessionNextTag (RatchetTagSetPtr tagset);
|
||||
void AddECIESx25519SessionNextTag (RatchetTagSetPtr tagset);
|
||||
void AddECIESx25519Session (const uint8_t * staticKey, ECIESX25519AEADRatchetSessionPtr session);
|
||||
void RemoveECIESx25519Session (const uint8_t * staticKey);
|
||||
void HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len);
|
||||
|
@ -266,10 +268,10 @@ namespace garlic
|
|||
int m_NumTags;
|
||||
std::mutex m_SessionsMutex;
|
||||
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
|
||||
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
|
||||
std::mutex m_DeliveryStatusSessionsMutex;
|
||||
std::unordered_map<uint32_t, GarlicRoutingSessionPtr> m_DeliveryStatusSessions; // msgID -> session
|
||||
|
|
|
@ -13,11 +13,11 @@ namespace crypto
|
|||
|
||||
enum GOSTR3410ParamSet
|
||||
{
|
||||
eGOSTR3410CryptoProA = 0, // 1.2.643.2.2.35.1
|
||||
eGOSTR3410CryptoProA = 0, // 1.2.643.2.2.35.1
|
||||
// XchA = A, XchB = C
|
||||
//eGOSTR3410CryptoProXchA, // 1.2.643.2.2.36.0
|
||||
//eGOSTR3410CryptoProXchB, // 1.2.643.2.2.36.1
|
||||
eGOSTR3410TC26A512, // 1.2.643.7.1.2.1.2.1
|
||||
//eGOSTR3410CryptoProXchA, // 1.2.643.2.2.36.0
|
||||
//eGOSTR3410CryptoProXchB, // 1.2.643.2.2.36.1
|
||||
eGOSTR3410TC26A512, // 1.2.643.7.1.2.1.2.1
|
||||
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 std::vector<std::pair<const uint8_t *, size_t> >& bufs, uint8_t * out, size_t outLen); // for total size < 64K
|
||||
|
||||
} // data
|
||||
} // i2p
|
||||
|
||||
|
|
|
@ -180,7 +180,7 @@ namespace i2p
|
|||
// excluded
|
||||
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;
|
||||
}
|
||||
htobe16buf (buf, cnt);
|
||||
|
@ -205,7 +205,7 @@ namespace i2p
|
|||
}
|
||||
|
||||
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 ();
|
||||
uint8_t * buf = m->GetPayload ();
|
||||
|
@ -268,7 +268,7 @@ namespace i2p
|
|||
auto m = NewI2NPShortMessage ();
|
||||
uint8_t * payload = m->GetPayload ();
|
||||
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);
|
||||
size_t size = DATABASE_STORE_HEADER_SIZE;
|
||||
memcpy (payload + size, leaseSet->GetBuffer (), leaseSet->GetBufferLen ());
|
||||
|
@ -278,7 +278,7 @@ namespace i2p
|
|||
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;
|
||||
auto m = NewI2NPShortMessage ();
|
||||
|
@ -347,11 +347,11 @@ namespace i2p
|
|||
auto transitTunnel = i2p::tunnel::CreateTransitTunnel (
|
||||
bufbe32toh (clearText + BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_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_IV_KEY_OFFSET,
|
||||
clearText + BUILD_REQUEST_RECORD_IV_KEY_OFFSET,
|
||||
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);
|
||||
record[BUILD_RESPONSE_RECORD_RET_OFFSET] = 0;
|
||||
}
|
||||
|
@ -386,7 +386,7 @@ namespace i2p
|
|||
return;
|
||||
}
|
||||
|
||||
auto tunnel = i2p::tunnel::tunnels.GetPendingInboundTunnel (replyMsgID);
|
||||
auto tunnel = i2p::tunnel::tunnels.GetPendingInboundTunnel (replyMsgID);
|
||||
if (tunnel)
|
||||
{
|
||||
// endpoint of inbound tunnel
|
||||
|
@ -414,7 +414,7 @@ namespace i2p
|
|||
transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
||||
CreateTunnelGatewayMsg (bufbe32toh (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET),
|
||||
eI2NPVariableTunnelBuildReply, buf, len,
|
||||
bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET)));
|
||||
bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET)));
|
||||
}
|
||||
else
|
||||
transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
||||
|
@ -440,7 +440,7 @@ namespace i2p
|
|||
transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
||||
CreateTunnelGatewayMsg (bufbe32toh (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET),
|
||||
eI2NPTunnelBuildReply, buf, len,
|
||||
bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET)));
|
||||
bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET)));
|
||||
}
|
||||
else
|
||||
transports.SendMessage (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
||||
|
@ -592,13 +592,13 @@ namespace i2p
|
|||
switch (typeID)
|
||||
{
|
||||
case eI2NPVariableTunnelBuild:
|
||||
HandleVariableTunnelBuildMsg (msgID, buf, size);
|
||||
HandleVariableTunnelBuildMsg (msgID, buf, size);
|
||||
break;
|
||||
case eI2NPVariableTunnelBuildReply:
|
||||
HandleVariableTunnelBuildReplyMsg (msgID, buf, size);
|
||||
break;
|
||||
case eI2NPTunnelBuild:
|
||||
HandleTunnelBuildMsg (buf, size);
|
||||
HandleTunnelBuildMsg (buf, size);
|
||||
break;
|
||||
case eI2NPTunnelBuildReply:
|
||||
// TODO:
|
||||
|
@ -667,7 +667,7 @@ namespace i2p
|
|||
Flush ();
|
||||
}
|
||||
|
||||
void I2NPMessagesHandler::PutNextMessage (std::shared_ptr<I2NPMessage> msg)
|
||||
void I2NPMessagesHandler::PutNextMessage (std::shared_ptr<I2NPMessage> msg)
|
||||
{
|
||||
if (msg)
|
||||
{
|
||||
|
|
|
@ -148,7 +148,7 @@ namespace data
|
|||
const uint8_t * GetSigningPrivateKey () const { return m_SigningPrivateKey; };
|
||||
size_t GetSignatureLen () const; // might not match identity
|
||||
bool IsOfflineSignature () const { return m_TransientSignatureLen > 0; };
|
||||
uint8_t * GetPadding();
|
||||
uint8_t * GetPadding();
|
||||
void RecalculateIdentHash(uint8_t * buf=nullptr) { m_Public->RecalculateIdentHash(buf); }
|
||||
void Sign (const uint8_t * buf, int len, uint8_t * signature) const;
|
||||
|
||||
|
@ -204,7 +204,7 @@ namespace data
|
|||
IdentHash CreateRoutingKey (const IdentHash& ident);
|
||||
XORMetric operator^(const IdentHash& key1, const IdentHash& key2);
|
||||
|
||||
// destination for delivery instuctions
|
||||
// destination for delivery instructions
|
||||
class RoutingDestination
|
||||
{
|
||||
public:
|
||||
|
@ -235,5 +235,4 @@ namespace data
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -12,7 +12,6 @@ namespace i2p
|
|||
{
|
||||
namespace data
|
||||
{
|
||||
|
||||
LeaseSet::LeaseSet (bool storeLeases):
|
||||
m_IsValid (false), m_StoreLeases (storeLeases), m_ExpirationTime (0), m_EncryptionKey (nullptr),
|
||||
m_Buffer (nullptr), m_BufferLen (0)
|
||||
|
@ -191,10 +190,10 @@ namespace data
|
|||
return m_ExpirationTime - now <= dlt;
|
||||
}
|
||||
|
||||
const std::vector<std::shared_ptr<const Lease> > LeaseSet::GetNonExpiredLeases (bool withThreshold) const
|
||||
{
|
||||
return GetNonExpiredLeasesExcluding( [] (const Lease & l) -> bool { return false; }, withThreshold);
|
||||
}
|
||||
const std::vector<std::shared_ptr<const Lease> > LeaseSet::GetNonExpiredLeases (bool withThreshold) const
|
||||
{
|
||||
return GetNonExpiredLeasesExcluding( [] (const Lease & l) -> bool { return false; }, withThreshold);
|
||||
}
|
||||
|
||||
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;
|
||||
offset += 32; // hash
|
||||
offset += 3; // flags
|
||||
offset += 1; // cost
|
||||
offset += 1; // cost
|
||||
offset += 4; // expires
|
||||
}
|
||||
// revocations
|
||||
|
@ -771,8 +770,7 @@ namespace data
|
|||
}
|
||||
|
||||
LocalLeaseSet2::LocalLeaseSet2 (uint8_t storeType, const i2p::data::PrivateKeys& keys,
|
||||
const KeySections& encryptionKeys,
|
||||
std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> > tunnels,
|
||||
const KeySections& encryptionKeys, std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> > tunnels,
|
||||
bool isPublic, bool isPublishedEncrypted):
|
||||
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 LEASE_SIZE = 44; // 32 + 4 + 8
|
||||
|
@ -70,7 +70,7 @@ namespace data
|
|||
size_t GetBufferLen () const { return m_BufferLen; };
|
||||
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> > 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 IsExpired () const;
|
||||
bool IsEmpty () const { return m_Leases.empty (); };
|
||||
|
@ -97,7 +97,7 @@ namespace data
|
|||
// called from LeaseSet2
|
||||
LeaseSet (bool storeLeases);
|
||||
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 SetExpirationTime (uint64_t t) { m_ExpirationTime = t; };
|
||||
void SetIsValid (bool isValid) { m_IsValid = isValid; };
|
||||
|
@ -245,7 +245,8 @@ namespace data
|
|||
const KeySections& encryptionKeys,
|
||||
std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> > tunnels,
|
||||
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; };
|
||||
|
||||
|
|
|
@ -29,35 +29,35 @@ struct BigEndian;
|
|||
template<typename T>
|
||||
struct LittleEndian
|
||||
{
|
||||
union
|
||||
{
|
||||
unsigned char bytes[sizeof(T)];
|
||||
T raw_value;
|
||||
};
|
||||
union
|
||||
{
|
||||
unsigned char bytes[sizeof(T)];
|
||||
T raw_value;
|
||||
};
|
||||
|
||||
LittleEndian(T t = T())
|
||||
{
|
||||
operator =(t);
|
||||
}
|
||||
LittleEndian(T t = T())
|
||||
{
|
||||
operator =(t);
|
||||
}
|
||||
|
||||
LittleEndian(const LittleEndian<T> & t)
|
||||
{
|
||||
raw_value = t.raw_value;
|
||||
}
|
||||
LittleEndian(const LittleEndian<T> & t)
|
||||
{
|
||||
raw_value = t.raw_value;
|
||||
}
|
||||
|
||||
LittleEndian(const BigEndian<T> & t)
|
||||
{
|
||||
for (unsigned i = 0; i < sizeof(T); i++)
|
||||
bytes[i] = t.bytes[sizeof(T)-1-i];
|
||||
}
|
||||
LittleEndian(const BigEndian<T> & t)
|
||||
{
|
||||
for (unsigned i = 0; i < sizeof(T); i++)
|
||||
bytes[i] = t.bytes[sizeof(T)-1-i];
|
||||
}
|
||||
|
||||
operator const T() const
|
||||
{
|
||||
T t = T();
|
||||
for (unsigned i = 0; i < sizeof(T); i++)
|
||||
t |= T(bytes[i]) << (i << 3);
|
||||
return t;
|
||||
}
|
||||
operator const T() const
|
||||
{
|
||||
T t = T();
|
||||
for (unsigned i = 0; i < sizeof(T); i++)
|
||||
t |= T(bytes[i]) << (i << 3);
|
||||
return t;
|
||||
}
|
||||
|
||||
const T operator = (const T t)
|
||||
{
|
||||
|
@ -66,68 +66,68 @@ struct LittleEndian
|
|||
return t;
|
||||
}
|
||||
|
||||
// operators
|
||||
// operators
|
||||
|
||||
const T operator += (const T t)
|
||||
{
|
||||
return (*this = *this + t);
|
||||
}
|
||||
const T operator += (const T t)
|
||||
{
|
||||
return (*this = *this + t);
|
||||
}
|
||||
|
||||
const T operator -= (const T t)
|
||||
{
|
||||
return (*this = *this - t);
|
||||
}
|
||||
const T operator -= (const T t)
|
||||
{
|
||||
return (*this = *this - t);
|
||||
}
|
||||
|
||||
const T operator *= (const T t)
|
||||
{
|
||||
return (*this = *this * t);
|
||||
}
|
||||
const T operator *= (const T t)
|
||||
{
|
||||
return (*this = *this * t);
|
||||
}
|
||||
|
||||
const T operator /= (const T t)
|
||||
{
|
||||
return (*this = *this / t);
|
||||
}
|
||||
const T operator /= (const T t)
|
||||
{
|
||||
return (*this = *this / t);
|
||||
}
|
||||
|
||||
const T operator %= (const T t)
|
||||
{
|
||||
return (*this = *this % t);
|
||||
}
|
||||
const T operator %= (const T t)
|
||||
{
|
||||
return (*this = *this % t);
|
||||
}
|
||||
|
||||
LittleEndian<T> operator ++ (int)
|
||||
{
|
||||
LittleEndian<T> tmp(*this);
|
||||
operator ++ ();
|
||||
return tmp;
|
||||
}
|
||||
LittleEndian<T> operator ++ (int)
|
||||
{
|
||||
LittleEndian<T> tmp(*this);
|
||||
operator ++ ();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
LittleEndian<T> & operator ++ ()
|
||||
{
|
||||
for (unsigned i = 0; i < sizeof(T); i++)
|
||||
{
|
||||
++bytes[i];
|
||||
if (bytes[i] != 0)
|
||||
break;
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
LittleEndian<T> & operator ++ ()
|
||||
{
|
||||
for (unsigned i = 0; i < sizeof(T); i++)
|
||||
{
|
||||
++bytes[i];
|
||||
if (bytes[i] != 0)
|
||||
break;
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
||||
LittleEndian<T> operator -- (int)
|
||||
{
|
||||
LittleEndian<T> tmp(*this);
|
||||
operator -- ();
|
||||
return tmp;
|
||||
}
|
||||
LittleEndian<T> operator -- (int)
|
||||
{
|
||||
LittleEndian<T> tmp(*this);
|
||||
operator -- ();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
LittleEndian<T> & operator -- ()
|
||||
{
|
||||
for (unsigned i = 0; i < sizeof(T); i++)
|
||||
{
|
||||
--bytes[i];
|
||||
if (bytes[i] != (T)(-1))
|
||||
break;
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
LittleEndian<T> & operator -- ()
|
||||
{
|
||||
for (unsigned i = 0; i < sizeof(T); i++)
|
||||
{
|
||||
--bytes[i];
|
||||
if (bytes[i] != (T)(-1))
|
||||
break;
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
|
@ -137,105 +137,105 @@ struct LittleEndian
|
|||
template<typename T>
|
||||
struct BigEndian
|
||||
{
|
||||
union
|
||||
{
|
||||
unsigned char bytes[sizeof(T)];
|
||||
T raw_value;
|
||||
};
|
||||
union
|
||||
{
|
||||
unsigned char bytes[sizeof(T)];
|
||||
T raw_value;
|
||||
};
|
||||
|
||||
BigEndian(T t = T())
|
||||
{
|
||||
operator =(t);
|
||||
}
|
||||
BigEndian(T t = T())
|
||||
{
|
||||
operator =(t);
|
||||
}
|
||||
|
||||
BigEndian(const BigEndian<T> & t)
|
||||
{
|
||||
raw_value = t.raw_value;
|
||||
}
|
||||
BigEndian(const BigEndian<T> & t)
|
||||
{
|
||||
raw_value = t.raw_value;
|
||||
}
|
||||
|
||||
BigEndian(const LittleEndian<T> & t)
|
||||
{
|
||||
for (unsigned i = 0; i < sizeof(T); i++)
|
||||
bytes[i] = t.bytes[sizeof(T)-1-i];
|
||||
}
|
||||
BigEndian(const LittleEndian<T> & t)
|
||||
{
|
||||
for (unsigned i = 0; i < sizeof(T); i++)
|
||||
bytes[i] = t.bytes[sizeof(T)-1-i];
|
||||
}
|
||||
|
||||
operator const T() const
|
||||
{
|
||||
T t = T();
|
||||
for (unsigned i = 0; i < sizeof(T); i++)
|
||||
t |= T(bytes[sizeof(T) - 1 - i]) << (i << 3);
|
||||
return t;
|
||||
}
|
||||
operator const T() const
|
||||
{
|
||||
T t = T();
|
||||
for (unsigned i = 0; i < sizeof(T); i++)
|
||||
t |= T(bytes[sizeof(T) - 1 - i]) << (i << 3);
|
||||
return t;
|
||||
}
|
||||
|
||||
const T operator = (const T t)
|
||||
{
|
||||
for (unsigned i = 0; i < sizeof(T); i++)
|
||||
bytes[sizeof(T) - 1 - i] = t >> (i << 3);
|
||||
return t;
|
||||
}
|
||||
const T operator = (const T t)
|
||||
{
|
||||
for (unsigned i = 0; i < sizeof(T); i++)
|
||||
bytes[sizeof(T) - 1 - i] = t >> (i << 3);
|
||||
return t;
|
||||
}
|
||||
|
||||
// operators
|
||||
// operators
|
||||
|
||||
const T operator += (const T t)
|
||||
{
|
||||
return (*this = *this + t);
|
||||
}
|
||||
const T operator += (const T t)
|
||||
{
|
||||
return (*this = *this + t);
|
||||
}
|
||||
|
||||
const T operator -= (const T t)
|
||||
{
|
||||
return (*this = *this - t);
|
||||
}
|
||||
const T operator -= (const T t)
|
||||
{
|
||||
return (*this = *this - t);
|
||||
}
|
||||
|
||||
const T operator *= (const T t)
|
||||
{
|
||||
return (*this = *this * t);
|
||||
}
|
||||
const T operator *= (const T t)
|
||||
{
|
||||
return (*this = *this * t);
|
||||
}
|
||||
|
||||
const T operator /= (const T t)
|
||||
{
|
||||
return (*this = *this / t);
|
||||
}
|
||||
const T operator /= (const T t)
|
||||
{
|
||||
return (*this = *this / t);
|
||||
}
|
||||
|
||||
const T operator %= (const T t)
|
||||
{
|
||||
return (*this = *this % t);
|
||||
}
|
||||
const T operator %= (const T t)
|
||||
{
|
||||
return (*this = *this % t);
|
||||
}
|
||||
|
||||
BigEndian<T> operator ++ (int)
|
||||
{
|
||||
BigEndian<T> tmp(*this);
|
||||
operator ++ ();
|
||||
return tmp;
|
||||
}
|
||||
BigEndian<T> operator ++ (int)
|
||||
{
|
||||
BigEndian<T> tmp(*this);
|
||||
operator ++ ();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
BigEndian<T> & operator ++ ()
|
||||
{
|
||||
for (unsigned i = 0; i < sizeof(T); i++)
|
||||
{
|
||||
++bytes[sizeof(T) - 1 - i];
|
||||
if (bytes[sizeof(T) - 1 - i] != 0)
|
||||
break;
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
BigEndian<T> & operator ++ ()
|
||||
{
|
||||
for (unsigned i = 0; i < sizeof(T); i++)
|
||||
{
|
||||
++bytes[sizeof(T) - 1 - i];
|
||||
if (bytes[sizeof(T) - 1 - i] != 0)
|
||||
break;
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
||||
BigEndian<T> operator -- (int)
|
||||
{
|
||||
BigEndian<T> tmp(*this);
|
||||
operator -- ();
|
||||
return tmp;
|
||||
}
|
||||
BigEndian<T> operator -- (int)
|
||||
{
|
||||
BigEndian<T> tmp(*this);
|
||||
operator -- ();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
BigEndian<T> & operator -- ()
|
||||
{
|
||||
for (unsigned i = 0; i < sizeof(T); i++)
|
||||
{
|
||||
--bytes[sizeof(T) - 1 - i];
|
||||
if (bytes[sizeof(T) - 1 - i] != (T)(-1))
|
||||
break;
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
BigEndian<T> & operator -- ()
|
||||
{
|
||||
for (unsigned i = 0; i < sizeof(T); i++)
|
||||
{
|
||||
--bytes[sizeof(T) - 1 - i];
|
||||
if (bytes[sizeof(T) - 1 - i] != (T)(-1))
|
||||
break;
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
|
|
|
@ -110,18 +110,18 @@ namespace log {
|
|||
}
|
||||
}
|
||||
|
||||
std::string str_tolower(std::string s) {
|
||||
std::transform(s.begin(), s.end(), s.begin(),
|
||||
// static_cast<int(*)(int)>(std::tolower) // wrong
|
||||
// [](int c){ return std::tolower(c); } // wrong
|
||||
// [](char c){ return std::tolower(c); } // wrong
|
||||
[](unsigned char c){ return std::tolower(c); } // correct
|
||||
);
|
||||
return s;
|
||||
}
|
||||
std::string str_tolower(std::string s) {
|
||||
std::transform(s.begin(), s.end(), s.begin(),
|
||||
// static_cast<int(*)(int)>(std::tolower) // wrong
|
||||
// [](int c){ return std::tolower(c); } // wrong
|
||||
// [](char c){ return std::tolower(c); } // wrong
|
||||
[](unsigned char c){ return std::tolower(c); } // correct
|
||||
);
|
||||
return s;
|
||||
}
|
||||
|
||||
void Log::SetLogLevel (const std::string& level_) {
|
||||
std::string level=str_tolower(level_);
|
||||
void Log::SetLogLevel (const std::string& level_) {
|
||||
std::string level=str_tolower(level_);
|
||||
if (level == "none") { m_MinLevel = eLogNone; }
|
||||
else if (level == "error") { m_MinLevel = eLogError; }
|
||||
else if (level == "warn") { m_MinLevel = eLogWarning; }
|
||||
|
|
|
@ -157,7 +157,7 @@ namespace log {
|
|||
ThrowFunction GetThrowFunction ();
|
||||
void SetThrowFunction (ThrowFunction f);
|
||||
} // log
|
||||
}
|
||||
} // i2p
|
||||
|
||||
/** internal usage only -- folding args array to single string */
|
||||
template<typename TValue>
|
||||
|
|
|
@ -114,7 +114,7 @@ namespace transport
|
|||
|
||||
void NTCP2Establisher::KDF2Bob ()
|
||||
{
|
||||
KeyDerivationFunction2 (m_SessionRequestBuffer, m_SessionRequestBufferLen, GetPub ());
|
||||
KeyDerivationFunction2 (m_SessionRequestBuffer, m_SessionRequestBufferLen, GetPub ());
|
||||
}
|
||||
|
||||
void NTCP2Establisher::KDF3Alice ()
|
||||
|
@ -1200,7 +1200,7 @@ namespace transport
|
|||
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);
|
||||
m_NTCP2Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCP2Server::HandleAccept, this, conn, std::placeholders::_1));
|
||||
}
|
||||
|
|
|
@ -126,7 +126,6 @@ namespace transport
|
|||
{
|
||||
public:
|
||||
|
||||
|
||||
NTCP2Session (NTCP2Server& server, std::shared_ptr<const i2p::data::RouterInfo> in_RemoteRouter = nullptr);
|
||||
~NTCP2Session ();
|
||||
void Terminate ();
|
||||
|
|
|
@ -468,7 +468,7 @@ namespace transport
|
|||
LogPrint (eLogError, "NTCP: Phase 4 read error: ", ecode.message (), ". Check your clock");
|
||||
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);
|
||||
Terminate ();
|
||||
}
|
||||
|
@ -736,13 +736,11 @@ namespace transport
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void NTCPSession::SendTimeSyncMessage ()
|
||||
{
|
||||
Send (nullptr);
|
||||
}
|
||||
|
||||
|
||||
void NTCPSession::SendI2NPMessages (const std::vector<std::shared_ptr<I2NPMessage> >& msgs)
|
||||
{
|
||||
m_Server.GetService ().post (std::bind (&NTCPSession::PostI2NPMessages, shared_from_this (), msgs));
|
||||
|
@ -904,7 +902,6 @@ namespace transport
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void NTCPServer::Run ()
|
||||
{
|
||||
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)
|
||||
|
@ -537,7 +537,7 @@ namespace data
|
|||
bool checkForExpiration = total > NETDB_MIN_ROUTERS && uptime > 600; // 10 minutes
|
||||
if (checkForExpiration && uptime > 3600) // 1 hour
|
||||
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)
|
||||
{
|
||||
|
@ -555,7 +555,7 @@ namespace data
|
|||
// find & mark expired routers
|
||||
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
|
||||
it.second->SetUnreachable (true);
|
||||
}
|
||||
|
@ -873,7 +873,7 @@ namespace data
|
|||
std::shared_ptr<I2NPMessage> replyMsg;
|
||||
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;
|
||||
for (int i = 0; i < numExcluded; i++)
|
||||
{
|
||||
|
@ -894,7 +894,7 @@ namespace data
|
|||
}
|
||||
else
|
||||
{
|
||||
if (lookupType == DATABASE_LOOKUP_TYPE_ROUTERINFO_LOOKUP ||
|
||||
if (lookupType == DATABASE_LOOKUP_TYPE_ROUTERINFO_LOOKUP ||
|
||||
lookupType == DATABASE_LOOKUP_TYPE_NORMAL_LOOKUP)
|
||||
{
|
||||
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))
|
||||
{
|
||||
auto leaseSet = FindLeaseSet (ident);
|
||||
|
|
|
@ -28,12 +28,12 @@ namespace i2p
|
|||
namespace data
|
||||
{
|
||||
const int NETDB_MIN_ROUTERS = 90;
|
||||
const int NETDB_FLOODFILL_EXPIRATION_TIMEOUT = 60*60; // 1 hour, in seconds
|
||||
const int NETDB_INTRODUCEE_EXPIRATION_TIMEOUT = 65*60;
|
||||
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_PUBLISH_INTERVAL = 60*40;
|
||||
const int NETDB_MIN_HIGHBANDWIDTH_VERSION = MAKE_VERSION_NUMBER(0,9,36); // 0.9.36
|
||||
const int NETDB_FLOODFILL_EXPIRATION_TIMEOUT = 60 * 60; // 1 hour, in seconds
|
||||
const int NETDB_INTRODUCEE_EXPIRATION_TIMEOUT = 65 * 60;
|
||||
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_PUBLISH_INTERVAL = 60 * 40;
|
||||
const int NETDB_MIN_HIGHBANDWIDTH_VERSION = MAKE_VERSION_NUMBER(0, 9, 36); // 0.9.36
|
||||
|
||||
/** function for visiting a leaseset stored in a floodfill */
|
||||
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;
|
||||
|
||||
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 HandleDatabaseSearchReplyMsg (std::shared_ptr<const I2NPMessage> msg);
|
||||
|
@ -80,13 +80,13 @@ namespace data
|
|||
std::vector<IdentHash> GetClosestFloodfills (const IdentHash& destination, size_t num,
|
||||
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> 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 PostI2NPMsg (std::shared_ptr<const I2NPMessage> msg);
|
||||
|
||||
/** set hidden mode, aka don't publish our RI to netdb and don't explore */
|
||||
void SetHidden(bool hide);
|
||||
/** set hidden mode, aka don't publish our RI to netdb and don't explore */
|
||||
void SetHidden(bool hide);
|
||||
|
||||
void Reseed ();
|
||||
Families& GetFamilies () { return m_Families; };
|
||||
|
@ -119,12 +119,13 @@ namespace data
|
|||
void ManageLeaseSets ();
|
||||
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 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:
|
||||
|
||||
|
@ -150,12 +151,12 @@ namespace data
|
|||
|
||||
bool m_PersistProfiles;
|
||||
|
||||
/** router info we are bootstrapping from or nullptr if we are not currently doing that*/
|
||||
std::shared_ptr<RouterInfo> m_FloodfillBootstrap;
|
||||
/** router info we are bootstrapping from or nullptr if we are not currently doing that*/
|
||||
std::shared_ptr<RouterInfo> m_FloodfillBootstrap;
|
||||
|
||||
|
||||
/** true if in hidden mode */
|
||||
bool m_HiddenMode;
|
||||
/** true if in hidden mode */
|
||||
bool m_HiddenMode;
|
||||
};
|
||||
|
||||
extern NetDb netdb;
|
||||
|
|
|
@ -14,8 +14,8 @@ namespace data
|
|||
std::shared_ptr<I2NPMessage> msg;
|
||||
if(replyTunnel)
|
||||
msg = i2p::CreateRouterInfoDatabaseLookupMsg (m_Destination,
|
||||
replyTunnel->GetNextIdentHash (), replyTunnel->GetNextTunnelID (), m_IsExploratory,
|
||||
&m_ExcludedPeers);
|
||||
replyTunnel->GetNextIdentHash (), replyTunnel->GetNextTunnelID (), m_IsExploratory,
|
||||
&m_ExcludedPeers);
|
||||
else
|
||||
msg = i2p::CreateRouterInfoDatabaseLookupMsg(m_Destination, i2p::context.GetIdentHash(), 0, m_IsExploratory, &m_ExcludedPeers);
|
||||
if(router)
|
||||
|
@ -158,4 +158,3 @@ namespace data
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -66,4 +66,3 @@ namespace data
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@ namespace i2p
|
|||
{
|
||||
namespace crypto
|
||||
{
|
||||
|
||||
void Poly1305HMAC(uint64_t * out, const uint64_t * key, const uint8_t * buf, std::size_t sz)
|
||||
{
|
||||
Poly1305 p(key);
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/**
|
||||
This code is licensed under the MCGSI Public License
|
||||
Copyright 2018 Jeff Becker
|
||||
|
||||
Kovri go write your own code
|
||||
|
||||
* This code is licensed under the MCGSI Public License
|
||||
* Copyright 2018 Jeff Becker
|
||||
*
|
||||
* Kovri go write your own code
|
||||
*
|
||||
*/
|
||||
#ifndef LIBI2PD_POLY1305_H
|
||||
#define LIBI2PD_POLY1305_H
|
||||
|
@ -24,7 +24,6 @@ namespace crypto
|
|||
|
||||
namespace poly1305
|
||||
{
|
||||
|
||||
struct LongBlock
|
||||
{
|
||||
unsigned long data[17];
|
||||
|
@ -252,8 +251,8 @@ namespace crypto
|
|||
poly1305::LongBlock m_HR;
|
||||
uint8_t m_Final;
|
||||
};
|
||||
|
||||
void Poly1305HMAC(uint64_t * out, const uint64_t * key, const uint8_t * buf, std::size_t sz);
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -32,73 +32,76 @@ namespace data
|
|||
{
|
||||
}
|
||||
|
||||
/** @brief tries to bootstrap into I2P network (from local files and servers, with respect of options)
|
||||
*/
|
||||
void Reseeder::Bootstrap ()
|
||||
{
|
||||
std::string su3FileName; i2p::config::GetOption("reseed.file", su3FileName);
|
||||
std::string zipFileName; i2p::config::GetOption("reseed.zipfile", zipFileName);
|
||||
/**
|
||||
@brief tries to bootstrap into I2P network (from local files and servers, with respect of options)
|
||||
*/
|
||||
void Reseeder::Bootstrap ()
|
||||
{
|
||||
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
|
||||
{
|
||||
int num;
|
||||
if (su3FileName.length() > 8 && su3FileName.substr(0, 8) == "https://")
|
||||
{
|
||||
num = ReseedFromSU3Url (su3FileName); // from https URL
|
||||
}
|
||||
else
|
||||
{
|
||||
num = ProcessSU3File (su3FileName.c_str ());
|
||||
}
|
||||
if (num == 0)
|
||||
LogPrint (eLogWarning, "Reseed: failed to reseed from ", su3FileName);
|
||||
}
|
||||
else if (zipFileName.length() > 0) // bootstrap from ZIP file
|
||||
{
|
||||
int num = ProcessZIPFile (zipFileName.c_str ());
|
||||
if (num == 0)
|
||||
LogPrint (eLogWarning, "Reseed: failed to reseed from ", zipFileName);
|
||||
}
|
||||
else // bootstrap from reseed servers
|
||||
{
|
||||
int num = ReseedFromServers ();
|
||||
if (num == 0)
|
||||
LogPrint (eLogWarning, "Reseed: failed to reseed from servers");
|
||||
}
|
||||
}
|
||||
if (su3FileName.length() > 0) // bootstrap from SU3 file or URL
|
||||
{
|
||||
int num;
|
||||
if (su3FileName.length() > 8 && su3FileName.substr(0, 8) == "https://")
|
||||
{
|
||||
num = ReseedFromSU3Url (su3FileName); // from https URL
|
||||
}
|
||||
else
|
||||
{
|
||||
num = ProcessSU3File (su3FileName.c_str ());
|
||||
}
|
||||
if (num == 0)
|
||||
LogPrint (eLogWarning, "Reseed: failed to reseed from ", su3FileName);
|
||||
}
|
||||
else if (zipFileName.length() > 0) // bootstrap from ZIP file
|
||||
{
|
||||
int num = ProcessZIPFile (zipFileName.c_str ());
|
||||
if (num == 0)
|
||||
LogPrint (eLogWarning, "Reseed: failed to reseed from ", zipFileName);
|
||||
}
|
||||
else // bootstrap from reseed servers
|
||||
{
|
||||
int num = ReseedFromServers ();
|
||||
if (num == 0)
|
||||
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 ()
|
||||
{
|
||||
std::string reseedURLs; i2p::config::GetOption("reseed.urls", reseedURLs);
|
||||
std::vector<std::string> httpsReseedHostList;
|
||||
boost::split(httpsReseedHostList, reseedURLs, boost::is_any_of(","), boost::token_compress_on);
|
||||
std::vector<std::string> httpsReseedHostList;
|
||||
boost::split(httpsReseedHostList, reseedURLs, boost::is_any_of(","), boost::token_compress_on);
|
||||
|
||||
if (reseedURLs.length () == 0)
|
||||
{
|
||||
LogPrint (eLogWarning, "Reseed: No reseed servers specified");
|
||||
return 0;
|
||||
}
|
||||
if (reseedURLs.length () == 0)
|
||||
{
|
||||
LogPrint (eLogWarning, "Reseed: No reseed servers specified");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int reseedRetries = 0;
|
||||
while (reseedRetries < 10)
|
||||
{
|
||||
auto ind = rand () % httpsReseedHostList.size ();
|
||||
std::string reseedUrl = httpsReseedHostList[ind] + "i2pseeds.su3";
|
||||
auto num = ReseedFromSU3Url (reseedUrl);
|
||||
if (num > 0) return num; // success
|
||||
reseedRetries++;
|
||||
}
|
||||
LogPrint (eLogWarning, "Reseed: failed to reseed from servers after 10 attempts");
|
||||
return 0;
|
||||
int reseedRetries = 0;
|
||||
while (reseedRetries < 10)
|
||||
{
|
||||
auto ind = rand () % httpsReseedHostList.size ();
|
||||
std::string reseedUrl = httpsReseedHostList[ind] + "i2pseeds.su3";
|
||||
auto num = ReseedFromSU3Url (reseedUrl);
|
||||
if (num > 0) return num; // success
|
||||
reseedRetries++;
|
||||
}
|
||||
LogPrint (eLogWarning, "Reseed: failed to reseed from servers after 10 attempts");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** @brief bootstrap from HTTPS URL with SU3 file
|
||||
* @param url
|
||||
* @return number of entries added to netDb
|
||||
*/
|
||||
/**
|
||||
* @brief bootstrap from HTTPS URL with SU3 file
|
||||
* @param url
|
||||
* @return number of entries added to netDb
|
||||
*/
|
||||
int Reseeder::ReseedFromSU3Url (const std::string& url)
|
||||
{
|
||||
LogPrint (eLogInfo, "Reseed: Downloading SU3 from ", url);
|
||||
|
@ -702,4 +705,3 @@ namespace data
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace data
|
|||
|
||||
Reseeder();
|
||||
~Reseeder();
|
||||
void Bootstrap ();
|
||||
void Bootstrap ();
|
||||
int ReseedFromServers ();
|
||||
int ReseedFromSU3Url (const std::string& url);
|
||||
int ProcessSU3File (const char * filename);
|
||||
|
|
|
@ -339,9 +339,9 @@ namespace i2p
|
|||
case low : /* not set */; break;
|
||||
case extra : caps |= i2p::data::RouterInfo::eExtraBandwidth; break; // 'P'
|
||||
case unlim : caps |= i2p::data::RouterInfo::eExtraBandwidth;
|
||||
#if (__cplusplus >= 201703L) // C++ 17 or higher
|
||||
#if (__cplusplus >= 201703L) // C++ 17 or higher
|
||||
[[fallthrough]];
|
||||
#endif
|
||||
#endif
|
||||
// no break here, extra + high means 'X'
|
||||
case high : caps |= i2p::data::RouterInfo::eHighBandwidth; break;
|
||||
}
|
||||
|
|
|
@ -173,7 +173,6 @@ namespace data
|
|||
LogPrint (eLogError, "RouterInfo: malformed message");
|
||||
m_IsUnreachable = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void RouterInfo::ReadFromStream (std::istream& s)
|
||||
|
@ -384,9 +383,10 @@ namespace data
|
|||
SetUnreachable (true);
|
||||
}
|
||||
|
||||
bool RouterInfo::IsFamily(const std::string & fam) const {
|
||||
return m_Family == fam;
|
||||
}
|
||||
bool RouterInfo::IsFamily(const std::string & fam) const
|
||||
{
|
||||
return m_Family == fam;
|
||||
}
|
||||
|
||||
void RouterInfo::ExtractCaps (const char * value)
|
||||
{
|
||||
|
@ -854,7 +854,7 @@ namespace data
|
|||
m_SupportedTransports |= eNTCPV6 | eSSUV6 | eNTCP2V6;
|
||||
}
|
||||
|
||||
void RouterInfo::EnableV4 ()
|
||||
void RouterInfo::EnableV4 ()
|
||||
{
|
||||
if (!IsV4 ())
|
||||
m_SupportedTransports |= eNTCPV4 | eSSUV4 | eNTCP2V4;
|
||||
|
@ -877,7 +877,7 @@ namespace data
|
|||
}
|
||||
}
|
||||
|
||||
void RouterInfo::DisableV4 ()
|
||||
void RouterInfo::DisableV4 ()
|
||||
{
|
||||
if (IsV4 ())
|
||||
{
|
||||
|
|
|
@ -203,8 +203,8 @@ namespace data
|
|||
void DeleteBuffer () { delete[] m_Buffer; m_Buffer = nullptr; };
|
||||
bool IsNewer (const uint8_t * buf, size_t len) const;
|
||||
|
||||
/** return true if we are in a router family and the signature is valid */
|
||||
bool IsFamily(const std::string & fam) const;
|
||||
/** return true if we are in a router family and the signature is valid */
|
||||
bool IsFamily(const std::string & fam) const;
|
||||
|
||||
// implements RoutingDestination
|
||||
std::shared_ptr<const IdentityEx> GetIdentity () const { return m_RouterIdentity; };
|
||||
|
|
|
@ -826,4 +826,3 @@ namespace transport
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace transport
|
|||
public:
|
||||
|
||||
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 ();
|
||||
void Start ();
|
||||
void Stop ();
|
||||
|
@ -135,4 +135,3 @@ namespace transport
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -496,7 +496,7 @@ namespace transport
|
|||
}
|
||||
// decay
|
||||
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 ();
|
||||
|
||||
ScheduleIncompleteMessagesCleanup ();
|
||||
|
@ -504,4 +504,3 @@ namespace transport
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -128,4 +128,3 @@ namespace transport
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -336,7 +336,7 @@ namespace transport
|
|||
m_SignedData->Insert (payload, 4); // insert Alice's signed on time
|
||||
payload += 4; // signed-on time
|
||||
size_t paddingSize = (payload - buf) + m_RemoteIdentity->GetSignatureLen ();
|
||||
paddingSize &= 0x0F; // %16
|
||||
paddingSize &= 0x0F; // %16
|
||||
if (paddingSize > 0) paddingSize = 16 - paddingSize;
|
||||
payload += paddingSize;
|
||||
// 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 SendPeerTest (); // Alice
|
||||
|
||||
SessionState GetState () const { return m_State; };
|
||||
SessionState GetState () const { return m_State; };
|
||||
size_t GetNumSentBytes () const { return m_NumSentBytes; };
|
||||
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::map<uint32_t, std::shared_ptr<const i2p::data::RouterInfo> > m_RelayRequests; // nonce->Charlie
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -135,5 +135,3 @@ namespace crypto
|
|||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -527,4 +527,3 @@ namespace crypto
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/**
|
||||
This code is licensed under the MCGSI Public License
|
||||
Copyright 2018 Jeff Becker
|
||||
|
||||
Kovri go write your own code
|
||||
|
||||
* This code is licensed under the MCGSI Public License
|
||||
* Copyright 2018 Jeff Becker
|
||||
*
|
||||
* Kovri go write your own code
|
||||
*
|
||||
*/
|
||||
#ifndef SIPHASH_H
|
||||
#define SIPHASH_H
|
||||
|
@ -16,138 +16,138 @@ namespace i2p
|
|||
{
|
||||
namespace crypto
|
||||
{
|
||||
namespace siphash
|
||||
{
|
||||
constexpr int crounds = 2;
|
||||
constexpr int drounds = 4;
|
||||
namespace siphash
|
||||
{
|
||||
constexpr int crounds = 2;
|
||||
constexpr int drounds = 4;
|
||||
|
||||
inline uint64_t rotl(const uint64_t & x, int b)
|
||||
{
|
||||
uint64_t ret = x << b;
|
||||
ret |= x >> (64 - b);
|
||||
return ret;
|
||||
}
|
||||
inline uint64_t rotl(const uint64_t & x, int b)
|
||||
{
|
||||
uint64_t ret = x << b;
|
||||
ret |= x >> (64 - b);
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline void u32to8le(const uint32_t & v, uint8_t * p)
|
||||
{
|
||||
p[0] = (uint8_t) v;
|
||||
p[1] = (uint8_t) (v >> 8);
|
||||
p[2] = (uint8_t) (v >> 16);
|
||||
p[3] = (uint8_t) (v >> 24);
|
||||
}
|
||||
inline void u32to8le(const uint32_t & v, uint8_t * p)
|
||||
{
|
||||
p[0] = (uint8_t) v;
|
||||
p[1] = (uint8_t) (v >> 8);
|
||||
p[2] = (uint8_t) (v >> 16);
|
||||
p[3] = (uint8_t) (v >> 24);
|
||||
}
|
||||
|
||||
inline void u64to8le(const uint64_t & v, uint8_t * p)
|
||||
{
|
||||
p[0] = v & 0xff;
|
||||
p[1] = (v >> 8) & 0xff;
|
||||
p[2] = (v >> 16) & 0xff;
|
||||
p[3] = (v >> 24) & 0xff;
|
||||
p[4] = (v >> 32) & 0xff;
|
||||
p[5] = (v >> 40) & 0xff;
|
||||
p[6] = (v >> 48) & 0xff;
|
||||
p[7] = (v >> 56) & 0xff;
|
||||
}
|
||||
inline void u64to8le(const uint64_t & v, uint8_t * p)
|
||||
{
|
||||
p[0] = v & 0xff;
|
||||
p[1] = (v >> 8) & 0xff;
|
||||
p[2] = (v >> 16) & 0xff;
|
||||
p[3] = (v >> 24) & 0xff;
|
||||
p[4] = (v >> 32) & 0xff;
|
||||
p[5] = (v >> 40) & 0xff;
|
||||
p[6] = (v >> 48) & 0xff;
|
||||
p[7] = (v >> 56) & 0xff;
|
||||
}
|
||||
|
||||
inline uint64_t u8to64le(const uint8_t * p)
|
||||
{
|
||||
uint64_t i = 0;
|
||||
int idx = 0;
|
||||
while(idx < 8)
|
||||
{
|
||||
i |= ((uint64_t) p[idx]) << (idx * 8);
|
||||
++idx;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
inline uint64_t u8to64le(const uint8_t * p)
|
||||
{
|
||||
uint64_t i = 0;
|
||||
int idx = 0;
|
||||
while(idx < 8)
|
||||
{
|
||||
i |= ((uint64_t) p[idx]) << (idx * 8);
|
||||
++idx;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
inline void round(uint64_t & _v0, uint64_t & _v1, uint64_t & _v2, uint64_t & _v3)
|
||||
{
|
||||
_v0 += _v1;
|
||||
_v1 = rotl(_v1, 13);
|
||||
_v1 ^= _v0;
|
||||
_v0 = rotl(_v0, 32);
|
||||
_v2 += _v3;
|
||||
_v3 = rotl(_v3, 16);
|
||||
_v3 ^= _v2;
|
||||
_v0 += _v3;
|
||||
_v3 = rotl(_v3, 21);
|
||||
_v3 ^= _v0;
|
||||
_v2 += _v1;
|
||||
_v1 = rotl(_v1, 17);
|
||||
_v1 ^= _v2;
|
||||
_v2 = rotl(_v2, 32);
|
||||
}
|
||||
}
|
||||
inline void round(uint64_t & _v0, uint64_t & _v1, uint64_t & _v2, uint64_t & _v3)
|
||||
{
|
||||
_v0 += _v1;
|
||||
_v1 = rotl(_v1, 13);
|
||||
_v1 ^= _v0;
|
||||
_v0 = rotl(_v0, 32);
|
||||
_v2 += _v3;
|
||||
_v3 = rotl(_v3, 16);
|
||||
_v3 ^= _v2;
|
||||
_v0 += _v3;
|
||||
_v3 = rotl(_v3, 21);
|
||||
_v3 ^= _v0;
|
||||
_v2 += _v1;
|
||||
_v1 = rotl(_v1, 17);
|
||||
_v1 ^= _v2;
|
||||
_v2 = rotl(_v2, 32);
|
||||
}
|
||||
}
|
||||
|
||||
/** hashsz must be 8 or 16 */
|
||||
template<std::size_t hashsz>
|
||||
inline void Siphash(uint8_t * h, const uint8_t * buf, std::size_t bufsz, const uint8_t * key)
|
||||
{
|
||||
uint64_t v0 = 0x736f6d6570736575ULL;
|
||||
uint64_t v1 = 0x646f72616e646f6dULL;
|
||||
uint64_t v2 = 0x6c7967656e657261ULL;
|
||||
uint64_t v3 = 0x7465646279746573ULL;
|
||||
const uint64_t k0 = siphash::u8to64le(key);
|
||||
const uint64_t k1 = siphash::u8to64le(key + 8);
|
||||
uint64_t msg;
|
||||
int i;
|
||||
const uint8_t * end = buf + bufsz - (bufsz % sizeof(uint64_t));
|
||||
auto left = bufsz & 7;
|
||||
uint64_t b = ((uint64_t)bufsz) << 56;
|
||||
v3 ^= k1;
|
||||
v2 ^= k0;
|
||||
v1 ^= k1;
|
||||
v0 ^= k0;
|
||||
/** hashsz must be 8 or 16 */
|
||||
template<std::size_t hashsz>
|
||||
inline void Siphash(uint8_t * h, const uint8_t * buf, std::size_t bufsz, const uint8_t * key)
|
||||
{
|
||||
uint64_t v0 = 0x736f6d6570736575ULL;
|
||||
uint64_t v1 = 0x646f72616e646f6dULL;
|
||||
uint64_t v2 = 0x6c7967656e657261ULL;
|
||||
uint64_t v3 = 0x7465646279746573ULL;
|
||||
const uint64_t k0 = siphash::u8to64le(key);
|
||||
const uint64_t k1 = siphash::u8to64le(key + 8);
|
||||
uint64_t msg;
|
||||
int i;
|
||||
const uint8_t * end = buf + bufsz - (bufsz % sizeof(uint64_t));
|
||||
auto left = bufsz & 7;
|
||||
uint64_t b = ((uint64_t)bufsz) << 56;
|
||||
v3 ^= k1;
|
||||
v2 ^= k0;
|
||||
v1 ^= k1;
|
||||
v0 ^= k0;
|
||||
|
||||
if(hashsz == 16) v1 ^= 0xee;
|
||||
if(hashsz == 16) v1 ^= 0xee;
|
||||
|
||||
while(buf != end)
|
||||
{
|
||||
msg = siphash::u8to64le(buf);
|
||||
v3 ^= msg;
|
||||
for(i = 0; i < siphash::crounds; ++i)
|
||||
siphash::round(v0, v1, v2, v3);
|
||||
while(buf != end)
|
||||
{
|
||||
msg = siphash::u8to64le(buf);
|
||||
v3 ^= msg;
|
||||
for(i = 0; i < siphash::crounds; ++i)
|
||||
siphash::round(v0, v1, v2, v3);
|
||||
|
||||
v0 ^= msg;
|
||||
buf += 8;
|
||||
}
|
||||
v0 ^= msg;
|
||||
buf += 8;
|
||||
}
|
||||
|
||||
while(left)
|
||||
{
|
||||
--left;
|
||||
b |= ((uint64_t)(buf[left])) << (left * 8);
|
||||
}
|
||||
while(left)
|
||||
{
|
||||
--left;
|
||||
b |= ((uint64_t)(buf[left])) << (left * 8);
|
||||
}
|
||||
|
||||
v3 ^= b;
|
||||
v3 ^= b;
|
||||
|
||||
for(i = 0; i < siphash::crounds; ++i)
|
||||
siphash::round(v0, v1, v2, v3);
|
||||
for(i = 0; i < siphash::crounds; ++i)
|
||||
siphash::round(v0, v1, v2, v3);
|
||||
|
||||
v0 ^= b;
|
||||
v0 ^= b;
|
||||
|
||||
|
||||
if(hashsz == 16)
|
||||
v2 ^= 0xee;
|
||||
else
|
||||
v2 ^= 0xff;
|
||||
if(hashsz == 16)
|
||||
v2 ^= 0xee;
|
||||
else
|
||||
v2 ^= 0xff;
|
||||
|
||||
for(i = 0; i < siphash::drounds; ++i)
|
||||
siphash::round(v0, v1, v2, v3);
|
||||
for(i = 0; i < siphash::drounds; ++i)
|
||||
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)
|
||||
siphash::round(v0, v1, v2, v3);
|
||||
for (i = 0; i < siphash::drounds; ++i)
|
||||
siphash::round(v0, v1, v2, v3);
|
||||
|
||||
b = v0 ^ v1 ^ v2 ^ v3;
|
||||
siphash::u64to8le(b, h + 8);
|
||||
}
|
||||
b = v0 ^ v1 ^ v2 ^ v3;
|
||||
siphash::u64to8le(b, h + 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace stream
|
|||
else
|
||||
{
|
||||
// partially
|
||||
rem = len - offset;
|
||||
rem = len - offset;
|
||||
memcpy (buf + offset, nextBuffer->GetRemaningBuffer (), len - offset);
|
||||
nextBuffer->offset += (len - offset);
|
||||
offset = len; // break
|
||||
|
@ -60,7 +60,7 @@ namespace stream
|
|||
m_SendStreamID (0), m_SequenceNumber (0), m_LastReceivedSequenceNumber (-1),
|
||||
m_Status (eStreamStatusNew), m_IsAckSendScheduled (false), m_LocalDestination (local),
|
||||
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_AckDelay (local.GetOwner ()->GetStreamingAckDelay ()),
|
||||
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_Status (eStreamStatusNew), m_IsAckSendScheduled (false), m_LocalDestination (local),
|
||||
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_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);
|
||||
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;
|
||||
}
|
||||
optionData += m_RemoteIdentity->GetFullLen ();
|
||||
|
@ -435,7 +435,7 @@ namespace stream
|
|||
m_SendBuffer.Add (buf, len, handler);
|
||||
}
|
||||
else if (handler)
|
||||
handler(boost::system::error_code ());
|
||||
handler(boost::system::error_code ());
|
||||
m_Service.post (std::bind (&Stream::SendBuffer, shared_from_this ()));
|
||||
}
|
||||
|
||||
|
@ -471,7 +471,7 @@ namespace stream
|
|||
size++; // resend delay
|
||||
if (m_Status == eStreamStatusNew)
|
||||
{
|
||||
// initial packet
|
||||
// initial packet
|
||||
m_Status = eStreamStatusOpen;
|
||||
if (!m_RemoteLeaseSet) m_RemoteLeaseSet = m_LocalDestination.GetOwner ()->FindLeaseSet (m_RemoteIdentity->GetIdentHash ());;
|
||||
if (m_RemoteLeaseSet)
|
||||
|
@ -654,7 +654,7 @@ namespace stream
|
|||
size += 4; // receiveStreamID
|
||||
htobe32buf (packet + size, m_SequenceNumber++);
|
||||
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
|
||||
packet[size] = 0;
|
||||
size++; // NACK count
|
||||
|
@ -748,7 +748,7 @@ namespace stream
|
|||
|
||||
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
|
||||
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);
|
||||
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)
|
||||
{
|
||||
// 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_CurrentOutboundTunnel = nullptr;
|
||||
m_CurrentRemoteLease = nullptr;
|
||||
|
@ -1164,7 +1164,7 @@ namespace stream
|
|||
m_Owner->GetService ().post([acceptor, this](void)
|
||||
{
|
||||
if (!m_PendingIncomingStreams.empty ())
|
||||
{
|
||||
{
|
||||
acceptor (m_PendingIncomingStreams.front ());
|
||||
m_PendingIncomingStreams.pop_front ();
|
||||
if (m_PendingIncomingStreams.empty ())
|
||||
|
|
142
libi2pd/Tag.h
142
libi2pd/Tag.h
|
@ -16,93 +16,91 @@
|
|||
|
||||
namespace i2p {
|
||||
namespace data {
|
||||
|
||||
template<size_t sz>
|
||||
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
|
||||
template<size_t sz>
|
||||
class Tag
|
||||
{
|
||||
for (size_t i = 0; i < sz/8; ++i)
|
||||
if (ll[i]) return false;
|
||||
return true;
|
||||
}
|
||||
BOOST_STATIC_ASSERT_MSG(sz % 8 == 0, "Tag size must be multiple of 8 bytes");
|
||||
|
||||
void Fill(uint8_t c)
|
||||
{
|
||||
memset(m_Buf, c, sz);
|
||||
}
|
||||
public:
|
||||
|
||||
void Randomize()
|
||||
{
|
||||
RAND_bytes(m_Buf, sz);
|
||||
}
|
||||
Tag () = default;
|
||||
Tag (const uint8_t * buf) { memcpy (m_Buf, 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);
|
||||
}
|
||||
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; }
|
||||
|
||||
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);
|
||||
}
|
||||
uint8_t * operator()() { return m_Buf; }
|
||||
const uint8_t * operator()() const { return m_Buf; }
|
||||
|
||||
size_t FromBase32 (const std::string& s)
|
||||
{
|
||||
return i2p::data::Base32ToByteStream (s.c_str (), s.length (), m_Buf, sz);
|
||||
}
|
||||
operator uint8_t * () { return m_Buf; }
|
||||
operator const uint8_t * () const { return m_Buf; }
|
||||
|
||||
size_t FromBase64 (const std::string& s)
|
||||
{
|
||||
return i2p::data::Base64ToByteStream (s.c_str (), s.length (), m_Buf, sz);
|
||||
}
|
||||
const uint8_t * data() const { return m_Buf; }
|
||||
const uint64_t * GetLL () const { return ll; }
|
||||
|
||||
private:
|
||||
bool IsZero () const
|
||||
{
|
||||
for (size_t i = 0; i < sz/8; ++i)
|
||||
if (ll[i]) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
union // 8 bytes aligned
|
||||
{
|
||||
uint8_t m_Buf[sz];
|
||||
uint64_t ll[sz/8];
|
||||
void Fill(uint8_t c)
|
||||
{
|
||||
memset(m_Buf, c, sz);
|
||||
}
|
||||
|
||||
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
|
||||
} // i2p
|
||||
|
||||
namespace std
|
||||
{
|
||||
// hash for std::unordered_map
|
||||
template<size_t sz> struct hash<i2p::data::Tag<sz> >
|
||||
{
|
||||
size_t operator()(const i2p::data::Tag<sz>& s) const
|
||||
{
|
||||
return s.GetLL ()[0];
|
||||
}
|
||||
};
|
||||
// hash for std::unordered_map
|
||||
template<size_t sz> struct hash<i2p::data::Tag<sz> >
|
||||
{
|
||||
size_t operator()(const i2p::data::Tag<sz>& s) const
|
||||
{
|
||||
return s.GetLL ()[0];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* TAG_H__ */
|
||||
|
|
|
@ -24,26 +24,26 @@ namespace util
|
|||
static uint64_t GetLocalMillisecondsSinceEpoch ()
|
||||
{
|
||||
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 ()
|
||||
{
|
||||
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 ()
|
||||
{
|
||||
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 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::ip::udp::resolver::query query (boost::asio::ip::udp::v4 (), address, "ntp");
|
||||
boost::system::error_code ec;
|
||||
|
@ -200,4 +200,3 @@ namespace util
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace util
|
|||
~NTPTimeSync ();
|
||||
|
||||
void Start ();
|
||||
void Stop ();
|
||||
void Stop ();
|
||||
|
||||
private:
|
||||
|
||||
|
@ -36,7 +36,7 @@ namespace util
|
|||
private:
|
||||
|
||||
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::deadline_timer m_Timer;
|
||||
int m_SyncInterval;
|
||||
|
@ -46,4 +46,3 @@ namespace util
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace i2p
|
|||
namespace tunnel
|
||||
{
|
||||
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):
|
||||
TunnelBase (receiveTunnelID, nextTunnelID, nextIdent)
|
||||
{
|
||||
|
@ -88,7 +88,7 @@ namespace tunnel
|
|||
|
||||
std::shared_ptr<TransitTunnel> CreateTransitTunnel (uint32_t receiveTunnelID,
|
||||
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)
|
||||
{
|
||||
if (isEndpoint)
|
||||
|
|
|
@ -390,7 +390,7 @@ namespace transport
|
|||
{
|
||||
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, {},
|
||||
i2p::util::GetSecondsSinceEpoch (), {} })).first;
|
||||
}
|
||||
|
@ -553,13 +553,13 @@ namespace transport
|
|||
{
|
||||
auto router = i2p::data::netdb.GetRandomPeerTestRouter (isv4); // v4 only if v4
|
||||
if (router)
|
||||
m_SSUServer->CreateSession (router, true, isv4); // peer test
|
||||
m_SSUServer->CreateSession (router, true, isv4); // peer test
|
||||
else
|
||||
{
|
||||
// if not peer test capable routers found pick any
|
||||
router = i2p::data::netdb.GetRandomRouter ();
|
||||
if (router && router->IsSSU ())
|
||||
m_SSUServer->CreateSession (router); // no peer test
|
||||
m_SSUServer->CreateSession (router); // no peer test
|
||||
}
|
||||
}
|
||||
if (i2p::context.SupportsV6 ())
|
||||
|
@ -713,7 +713,7 @@ namespace transport
|
|||
{
|
||||
profile->TunnelNonReplied();
|
||||
}
|
||||
std::unique_lock<std::mutex> l(m_PeersMutex);
|
||||
std::unique_lock<std::mutex> l(m_PeersMutex);
|
||||
it = m_Peers.erase (it);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -103,7 +103,7 @@ namespace transport
|
|||
uint64_t GetTotalReceivedBytes () const { return m_TotalReceivedBytes; };
|
||||
uint64_t GetTotalTransitTransmittedBytes () const { return m_TotalTransitTransmittedBytes; }
|
||||
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 GetTransitBandwidth () const { return m_TransitBandwidth; };
|
||||
bool IsBandwidthExceeded () const;
|
||||
|
@ -111,16 +111,16 @@ namespace transport
|
|||
size_t GetNumPeers () const { return m_Peers.size (); };
|
||||
std::shared_ptr<const i2p::data::RouterInfo> GetRandomPeer () const;
|
||||
|
||||
/** get a trusted first hop for restricted routes */
|
||||
std::shared_ptr<const i2p::data::RouterInfo> GetRestrictedPeer() const;
|
||||
/** do we want to use restricted routes? */
|
||||
bool RoutesRestricted() const;
|
||||
/** restrict routes to use only these router families for first hops */
|
||||
void RestrictRoutesToFamilies(std::set<std::string> families);
|
||||
/** restrict routes to use only these routers for first hops */
|
||||
void RestrictRoutesToRouters(std::set<i2p::data::IdentHash> routers);
|
||||
/** get a trusted first hop for restricted routes */
|
||||
std::shared_ptr<const i2p::data::RouterInfo> GetRestrictedPeer() const;
|
||||
/** do we want to use restricted routes? */
|
||||
bool RoutesRestricted() const;
|
||||
/** restrict routes to use only these router families for first hops */
|
||||
void RestrictRoutesToFamilies(std::set<std::string> families);
|
||||
/** restrict routes to use only these routers for first hops */
|
||||
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 ();
|
||||
|
||||
|
|
|
@ -64,8 +64,7 @@ namespace tunnel
|
|||
m.hash = i2p::data::IdentHash (fragment);
|
||||
fragment += 32; // to hash
|
||||
break;
|
||||
default:
|
||||
;
|
||||
default: ;
|
||||
}
|
||||
|
||||
bool isFragmented = flag & 0x08;
|
||||
|
|
|
@ -172,7 +172,7 @@ namespace tunnel
|
|||
SHA256(payload, size+16, hash);
|
||||
memcpy (buf+20, hash, 4); // checksum
|
||||
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)
|
||||
{
|
||||
// non-zero padding
|
||||
|
@ -219,4 +219,3 @@ namespace tunnel
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@ namespace i2p
|
|||
{
|
||||
namespace tunnel
|
||||
{
|
||||
|
||||
TunnelPool::TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels, int numOutboundTunnels):
|
||||
m_NumInboundHops (numInboundHops), m_NumOutboundHops (numOutboundHops),
|
||||
m_NumInboundTunnels (numInboundTunnels), m_NumOutboundTunnels (numOutboundTunnels), m_IsActive (true),
|
||||
|
@ -67,7 +66,8 @@ namespace tunnel
|
|||
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)
|
||||
{
|
||||
m_NumInboundHops = inHops;
|
||||
|
@ -180,8 +180,8 @@ namespace tunnel
|
|||
{
|
||||
if (it->IsEstablished () && it != excluded)
|
||||
{
|
||||
tunnel = it;
|
||||
i++;
|
||||
tunnel = it;
|
||||
i++;
|
||||
}
|
||||
if (i > ind && tunnel) break;
|
||||
}
|
||||
|
@ -411,7 +411,7 @@ namespace tunnel
|
|||
{
|
||||
std::lock_guard<std::mutex> lock(m_CustomPeerSelectorMutex);
|
||||
if (m_CustomPeerSelector)
|
||||
return m_CustomPeerSelector->SelectPeers(peers, numHops, isInbound);
|
||||
return m_CustomPeerSelector->SelectPeers(peers, numHops, isInbound);
|
||||
}
|
||||
// explicit peers in use
|
||||
if (m_ExplicitPeers) return SelectExplicitPeers (peers, isInbound);
|
||||
|
|
|
@ -80,18 +80,18 @@ namespace tunnel
|
|||
void UnsetCustomPeerSelector();
|
||||
bool HasCustomPeerSelector();
|
||||
|
||||
/** @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; }
|
||||
/** @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; }
|
||||
|
||||
/** @brief return true if this tunnel pool has a latency requirement */
|
||||
bool HasLatencyRequirement() const { return m_MinLatency > 0 && m_MaxLatency > 0; }
|
||||
/** @brief return true if this tunnel pool has a latency requirement */
|
||||
bool HasLatencyRequirement() const { return m_MinLatency > 0 && m_MaxLatency > 0; }
|
||||
|
||||
/** @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<OutboundTunnel> GetLowestLatencyOutboundTunnel(std::shared_ptr<OutboundTunnel> exclude=nullptr) const;
|
||||
/** @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<OutboundTunnel> GetLowestLatencyOutboundTunnel(std::shared_ptr<OutboundTunnel> exclude = nullptr) const;
|
||||
|
||||
// for overriding tunnel peer selection
|
||||
std::shared_ptr<const i2p::data::RouterInfo> SelectNextHop (std::shared_ptr<const i2p::data::RouterInfo> prevHop) const;
|
||||
// for overriding tunnel peer selection
|
||||
std::shared_ptr<const i2p::data::RouterInfo> SelectNextHop (std::shared_ptr<const i2p::data::RouterInfo> prevHop) const;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -118,8 +118,8 @@ namespace tunnel
|
|||
std::mutex m_CustomPeerSelectorMutex;
|
||||
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_MaxLatency=0; // if > 0 this tunnel pool will try building tunnels with maximum 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
|
||||
|
||||
public:
|
||||
|
||||
|
|
|
@ -31,8 +31,8 @@ namespace api
|
|||
bool precomputation; i2p::config::GetOption("precomputation.elgamal", precomputation);
|
||||
i2p::crypto::InitCrypto (precomputation);
|
||||
|
||||
int netID; i2p::config::GetOption("netid", netID);
|
||||
i2p::context.SetNetID (netID);
|
||||
int netID; i2p::config::GetOption("netid", netID);
|
||||
i2p::context.SetNetID (netID);
|
||||
|
||||
i2p::context.Init ();
|
||||
}
|
||||
|
@ -133,4 +133,3 @@ namespace api
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,4 +35,3 @@ namespace api
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -101,21 +101,21 @@ namespace net
|
|||
#ifdef WIN32
|
||||
bool IsWindowsXPorLater()
|
||||
{
|
||||
static bool isRequested = false;
|
||||
static bool isXP = false;
|
||||
if (!isRequested)
|
||||
{
|
||||
// request
|
||||
OSVERSIONINFO osvi;
|
||||
static bool isRequested = false;
|
||||
static bool isXP = false;
|
||||
if (!isRequested)
|
||||
{
|
||||
// request
|
||||
OSVERSIONINFO osvi;
|
||||
|
||||
ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
|
||||
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
||||
GetVersionEx(&osvi);
|
||||
ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
|
||||
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
||||
GetVersionEx(&osvi);
|
||||
|
||||
isXP = osvi.dwMajorVersion <= 5;
|
||||
isRequested = true;
|
||||
}
|
||||
return isXP;
|
||||
isXP = osvi.dwMajorVersion <= 5;
|
||||
isRequested = true;
|
||||
}
|
||||
return isXP;
|
||||
}
|
||||
|
||||
int GetMTUWindowsIpv4(sockaddr_in inputAddress, int fallback)
|
||||
|
@ -246,22 +246,24 @@ namespace net
|
|||
std::string localAddressUniversal = localAddress.to_string();
|
||||
#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");
|
||||
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())
|
||||
{
|
||||
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);
|
||||
}
|
||||
else if(localAddress.is_v6())
|
||||
{
|
||||
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);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
LogPrint(eLogError, "NetIface: GetMTU(): address family is not supported");
|
||||
return fallback;
|
||||
}
|
||||
|
@ -355,7 +357,7 @@ namespace net
|
|||
if (cur_ifname == ifname && cur->ifa_addr && cur->ifa_addr->sa_family == af)
|
||||
{
|
||||
// match
|
||||
char addr[INET6_ADDRSTRLEN];
|
||||
char addr[INET6_ADDRSTRLEN];
|
||||
memset (addr, 0, INET6_ADDRSTRLEN);
|
||||
if(af == AF_INET)
|
||||
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);
|
||||
}
|
||||
return boost::asio::ip::address::from_string(fallback);
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -487,18 +487,18 @@ namespace client
|
|||
LogPrint (eLogWarning, "Addressbook: subscriptions.txt usage is deprecated, use config file instead");
|
||||
}
|
||||
else if (!i2p::config::IsDefault("addressbook.subscriptions"))
|
||||
{
|
||||
// using config file items
|
||||
std::string subscriptionURLs; i2p::config::GetOption("addressbook.subscriptions", subscriptionURLs);
|
||||
std::vector<std::string> subsList;
|
||||
boost::split(subsList, subscriptionURLs, boost::is_any_of(","), boost::token_compress_on);
|
||||
{
|
||||
// using config file items
|
||||
std::string subscriptionURLs; i2p::config::GetOption("addressbook.subscriptions", subscriptionURLs);
|
||||
std::vector<std::string> subsList;
|
||||
boost::split(subsList, subscriptionURLs, boost::is_any_of(","), boost::token_compress_on);
|
||||
|
||||
for (size_t i = 0; i < subsList.size (); i++)
|
||||
{
|
||||
m_Subscriptions.push_back (std::make_shared<AddressBookSubscription> (*this, subsList[i]));
|
||||
}
|
||||
LogPrint (eLogInfo, "Addressbook: ", m_Subscriptions.size (), " subscriptions urls loaded");
|
||||
}
|
||||
for (size_t i = 0; i < subsList.size (); i++)
|
||||
{
|
||||
m_Subscriptions.push_back (std::make_shared<AddressBookSubscription> (*this, subsList[i]));
|
||||
}
|
||||
LogPrint (eLogInfo, "Addressbook: ", m_Subscriptions.size (), " subscriptions urls loaded");
|
||||
}
|
||||
}
|
||||
else
|
||||
LogPrint (eLogError, "Addressbook: subscriptions already loaded");
|
||||
|
@ -515,7 +515,7 @@ namespace client
|
|||
if (dot != std::string::npos)
|
||||
{
|
||||
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 ())
|
||||
{
|
||||
auto dest = context.FindLocalDestination (it1->second->identHash);
|
||||
|
@ -610,7 +610,7 @@ namespace client
|
|||
{
|
||||
// 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)
|
||||
m_DefaultSubscription = std::make_shared<AddressBookSubscription>(*this, defaultSubURL);
|
||||
m_IsDownloading = true;
|
||||
|
@ -802,7 +802,7 @@ namespace client
|
|||
/* convert url to relative */
|
||||
url.schema = "";
|
||||
url.host = "";
|
||||
req.uri = url.to_string();
|
||||
req.uri = url.to_string();
|
||||
auto stream = i2p::client::context.GetSharedLocalDestination ()->CreateStream (leaseSet, dest_port);
|
||||
std::string request = req.to_string();
|
||||
stream->Send ((const uint8_t *) request.data(), request.length());
|
||||
|
@ -920,7 +920,7 @@ namespace client
|
|||
{
|
||||
auto datagram = m_LocalDestination->GetDatagramDestination ();
|
||||
if (datagram)
|
||||
datagram->ResetReceiver (ADDRESS_RESOLVER_DATAGRAM_PORT);
|
||||
datagram->ResetReceiver (ADDRESS_RESOLVER_DATAGRAM_PORT);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -160,5 +160,3 @@ namespace client
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -50,10 +50,10 @@ namespace client
|
|||
void BOBI2PInboundTunnel::ReceiveAddress (std::shared_ptr<AddressReceiver> receiver)
|
||||
{
|
||||
receiver->socket->async_read_some (boost::asio::buffer(
|
||||
receiver->buffer + receiver->bufferOffset,
|
||||
BOB_COMMAND_BUFFER_SIZE - receiver->bufferOffset),
|
||||
receiver->buffer + receiver->bufferOffset,
|
||||
BOB_COMMAND_BUFFER_SIZE - receiver->bufferOffset),
|
||||
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,
|
||||
|
@ -437,7 +437,7 @@ namespace client
|
|||
if (!m_CurrentDestination)
|
||||
{
|
||||
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);
|
||||
}
|
||||
if (m_InPort)
|
||||
|
@ -624,14 +624,13 @@ namespace client
|
|||
}
|
||||
// trying to request
|
||||
auto s = shared_from_this ();
|
||||
auto requstCallback =
|
||||
[s](std::shared_ptr<i2p::data::LeaseSet> ls)
|
||||
{
|
||||
if (ls)
|
||||
s->SendReplyOK (ls->GetIdentity ()->ToBase64 ().c_str ());
|
||||
else
|
||||
s->SendReplyError ("LeaseSet Not found");
|
||||
};
|
||||
auto requstCallback = [s](std::shared_ptr<i2p::data::LeaseSet> ls)
|
||||
{
|
||||
if (ls)
|
||||
s->SendReplyOK (ls->GetIdentity ()->ToBase64 ().c_str ());
|
||||
else
|
||||
s->SendReplyError ("LeaseSet Not found");
|
||||
};
|
||||
if (addr->IsIdentHash ())
|
||||
localDestination->RequestDestination (addr->identHash, requstCallback);
|
||||
else
|
||||
|
@ -856,8 +855,7 @@ namespace client
|
|||
session->SendVersion ();
|
||||
}
|
||||
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
|
||||
{
|
||||
struct AddressReceiver
|
||||
{
|
||||
std::shared_ptr<boost::asio::ip::tcp::socket> socket;
|
||||
char buffer[BOB_COMMAND_BUFFER_SIZE + 1]; // for destination base64 address
|
||||
uint8_t * data; // pointer to buffer
|
||||
size_t dataLen, bufferOffset;
|
||||
struct AddressReceiver
|
||||
{
|
||||
std::shared_ptr<boost::asio::ip::tcp::socket> socket;
|
||||
char buffer[BOB_COMMAND_BUFFER_SIZE + 1]; // for destination base64 address
|
||||
uint8_t * data; // pointer to buffer
|
||||
size_t dataLen, bufferOffset;
|
||||
|
||||
AddressReceiver (): data (nullptr), dataLen (0), bufferOffset (0) {};
|
||||
};
|
||||
AddressReceiver (): data (nullptr), dataLen (0), bufferOffset (0) {};
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
|
@ -115,7 +115,7 @@ namespace client
|
|||
{
|
||||
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 Stop ();
|
||||
|
@ -222,7 +222,7 @@ namespace client
|
|||
|
||||
BOBCommandChannel& m_Owner;
|
||||
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;
|
||||
std::string m_Nickname, m_InHost, m_OutHost;
|
||||
int m_InPort, m_OutPort;
|
||||
|
@ -269,4 +269,3 @@ namespace client
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ namespace client
|
|||
{
|
||||
std::string samAddr; i2p::config::GetOption("sam.address", samAddr);
|
||||
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);
|
||||
try
|
||||
{
|
||||
|
@ -407,13 +407,13 @@ namespace client
|
|||
template<typename Section, typename Type>
|
||||
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>
|
||||
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>
|
||||
|
@ -429,7 +429,7 @@ namespace client
|
|||
template<typename Section>
|
||||
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_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);
|
||||
|
@ -528,10 +528,10 @@ namespace client
|
|||
{
|
||||
std::string type = section.second.get<std::string> (I2P_TUNNELS_SECTION_TYPE);
|
||||
if (type == I2P_TUNNELS_SECTION_TYPE_CLIENT
|
||||
|| type == I2P_TUNNELS_SECTION_TYPE_SOCKS
|
||||
|| type == I2P_TUNNELS_SECTION_TYPE_WEBSOCKS
|
||||
|| type == I2P_TUNNELS_SECTION_TYPE_HTTPPROXY
|
||||
|| type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT)
|
||||
|| type == I2P_TUNNELS_SECTION_TYPE_SOCKS
|
||||
|| type == I2P_TUNNELS_SECTION_TYPE_WEBSOCKS
|
||||
|| type == I2P_TUNNELS_SECTION_TYPE_HTTPPROXY
|
||||
|| type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT)
|
||||
{
|
||||
// mandatory params
|
||||
std::string dest;
|
||||
|
@ -640,9 +640,9 @@ namespace client
|
|||
}
|
||||
}
|
||||
else if (type == I2P_TUNNELS_SECTION_TYPE_SERVER
|
||||
|| type == I2P_TUNNELS_SECTION_TYPE_HTTP
|
||||
|| type == I2P_TUNNELS_SECTION_TYPE_IRC
|
||||
|| type == I2P_TUNNELS_SECTION_TYPE_UDPSERVER)
|
||||
|| type == I2P_TUNNELS_SECTION_TYPE_HTTP
|
||||
|| type == I2P_TUNNELS_SECTION_TYPE_IRC
|
||||
|| type == I2P_TUNNELS_SECTION_TYPE_UDPSERVER)
|
||||
{
|
||||
// mandatory params
|
||||
std::string host = section.second.get<std::string> (I2P_SERVER_TUNNEL_HOST);
|
||||
|
@ -699,7 +699,7 @@ namespace client
|
|||
continue;
|
||||
}
|
||||
|
||||
std::shared_ptr<I2PServerTunnel> serverTunnel;
|
||||
std::shared_ptr<I2PServerTunnel> serverTunnel;
|
||||
if (type == I2P_TUNNELS_SECTION_TYPE_HTTP)
|
||||
serverTunnel = std::make_shared<I2PServerTunnelHTTP> (name, host, port, localDestination, hostOverride, inPort, gzip);
|
||||
else if (type == I2P_TUNNELS_SECTION_TYPE_IRC)
|
||||
|
@ -745,7 +745,7 @@ namespace client
|
|||
ins.first->second->SetLocalDestination (serverTunnel->GetLocalDestination ());
|
||||
}
|
||||
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 httpProxyAddr; i2p::config::GetOption("httpproxy.address", httpProxyAddr);
|
||||
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);
|
||||
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);
|
||||
if (httpProxyKeys.length () > 0)
|
||||
{
|
||||
|
|
|
@ -78,7 +78,8 @@ namespace client
|
|||
std::shared_ptr<ClientDestination> CreateNewLocalDestination (boost::asio::io_service& service,
|
||||
const i2p::data::PrivateKeys& keys, bool isPublic = true,
|
||||
const std::map<std::string, std::string> * params = nullptr); // same as previous but on external io_service
|
||||
std::shared_ptr<ClientDestination> CreateNewMatchedTunnelDestination(const i2p::data::PrivateKeys &keys, const std::string & name, const std::map<std::string, std::string> * params = nullptr);
|
||||
std::shared_ptr<ClientDestination> CreateNewMatchedTunnelDestination(const i2p::data::PrivateKeys &keys,
|
||||
const std::string & name, const std::map<std::string, std::string> * params = nullptr);
|
||||
void DeleteLocalDestination (std::shared_ptr<ClientDestination> destination);
|
||||
std::shared_ptr<ClientDestination> FindLocalDestination (const i2p::data::IdentHash& destination) const;
|
||||
bool LoadPrivateKeys (i2p::data::PrivateKeys& keys, const std::string& filename,
|
||||
|
@ -141,6 +142,7 @@ namespace client
|
|||
std::unique_ptr<boost::asio::deadline_timer> m_CleanupUDPTimer;
|
||||
|
||||
public:
|
||||
|
||||
// for HTTP
|
||||
const decltype(m_Destinations)& GetDestinations () const { return m_Destinations; };
|
||||
const decltype(m_ClientTunnels)& GetClientTunnels () const { return m_ClientTunnels; };
|
||||
|
|
|
@ -191,7 +191,7 @@ namespace proxy {
|
|||
res.body = ss.str();
|
||||
std::string response = res.to_string();
|
||||
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)
|
||||
|
@ -406,7 +406,7 @@ namespace proxy {
|
|||
void HTTPReqHandler::ForwardToUpstreamProxy()
|
||||
{
|
||||
LogPrint(eLogDebug, "HTTPProxy: forward to upstream");
|
||||
// build http requset
|
||||
// build http request
|
||||
|
||||
m_ClientRequestURL = m_RequestURL;
|
||||
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
|
||||
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_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
|
||||
|
@ -562,14 +562,16 @@ namespace proxy {
|
|||
if(m_ClientRequest.method == "CONNECT") {
|
||||
m_ClientResponse.code = 200;
|
||||
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());
|
||||
else HandoverToUpstreamProxy();
|
||||
});
|
||||
} else {
|
||||
m_send_buf = m_ClientRequestBuffer.str();
|
||||
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());
|
||||
else HandoverToUpstreamProxy();
|
||||
});
|
||||
|
|
|
@ -6,6 +6,7 @@ namespace proxy {
|
|||
class HTTPProxy: public i2p::client::TCPIPAcceptor
|
||||
{
|
||||
public:
|
||||
|
||||
HTTPProxy(const std::string& name, const std::string& address, int port, const std::string & outproxy, bool addresshelper, std::shared_ptr<i2p::client::ClientDestination> localDestination);
|
||||
HTTPProxy(const std::string& name, const std::string& address, int port, std::shared_ptr<i2p::client::ClientDestination> localDestination = nullptr) :
|
||||
HTTPProxy(name, address, port, "", true, localDestination) {} ;
|
||||
|
@ -15,11 +16,13 @@ namespace proxy {
|
|||
bool GetHelperSupport() { return m_Addresshelper; }
|
||||
|
||||
protected:
|
||||
|
||||
// Implements TCPIPAcceptor
|
||||
std::shared_ptr<i2p::client::I2PServiceHandler> CreateHandler(std::shared_ptr<boost::asio::ip::tcp::socket> socket);
|
||||
const char* GetName() { return m_Name.c_str (); }
|
||||
|
||||
private:
|
||||
|
||||
std::string m_Name;
|
||||
std::string m_OutproxyUrl;
|
||||
bool m_Addresshelper;
|
||||
|
|
|
@ -221,7 +221,7 @@ namespace client
|
|||
auto s = shared_from_this ();
|
||||
m_Socket->async_read_some (boost::asio::buffer (m_Header, 1),
|
||||
[s](const boost::system::error_code& ecode, std::size_t bytes_transferred)
|
||||
{
|
||||
{
|
||||
if (!ecode && bytes_transferred > 0 && s->m_Header[0] == I2CP_PROTOCOL_BYTE)
|
||||
s->ReceiveHeader ();
|
||||
else
|
||||
|
@ -323,7 +323,7 @@ namespace client
|
|||
memcpy (buf + I2CP_HEADER_SIZE, payload, len);
|
||||
boost::asio::async_write (*socket, boost::asio::buffer (buf, l), boost::asio::transfer_all (),
|
||||
std::bind(&I2CPSession::HandleI2CPMessageSent, shared_from_this (),
|
||||
std::placeholders::_1, std::placeholders::_2, buf));
|
||||
std::placeholders::_1, std::placeholders::_2, buf));
|
||||
}
|
||||
else
|
||||
LogPrint (eLogError, "I2CP: Can't write to the socket");
|
||||
|
@ -779,14 +779,14 @@ namespace client
|
|||
memcpy (buf + I2CP_HEADER_SIZE + 10, payload, len);
|
||||
boost::asio::async_write (*m_Socket, boost::asio::buffer (buf, l), boost::asio::transfer_all (),
|
||||
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):
|
||||
m_IsRunning (false), m_Thread (nullptr),
|
||||
m_Acceptor (m_Service,
|
||||
#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
|
||||
I2CPSession::proto::endpoint(boost::asio::ip::address::from_string(interface), port))
|
||||
#endif
|
||||
|
@ -899,4 +899,3 @@ namespace client
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -220,4 +220,3 @@ namespace client
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -115,14 +115,16 @@ namespace client
|
|||
{
|
||||
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)
|
||||
{
|
||||
LogPrint(eLogWarning, "I2PService::CreateStream() ", ec.message());
|
||||
streamRequestComplete(nullptr);
|
||||
}
|
||||
else
|
||||
{ if (address->IsIdentHash ())
|
||||
{
|
||||
if (address->IsIdentHash ())
|
||||
this->m_LocalDestination->CreateStream(streamRequestComplete, address->identHash, port);
|
||||
else
|
||||
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),
|
||||
std::bind(&TCPIPPipe::HandleUpstreamReceived, shared_from_this(),
|
||||
std::placeholders::_1, std::placeholders::_2));
|
||||
std::placeholders::_1, std::placeholders::_2));
|
||||
}
|
||||
else
|
||||
LogPrint(eLogError, "TCPIPPipe: upstream receive: no socket");
|
||||
|
@ -191,7 +193,7 @@ namespace client
|
|||
if (m_down) {
|
||||
m_down->async_read_some(boost::asio::buffer(m_downstream_to_up_buf, TCP_IP_PIPE_BUFFER_SIZE),
|
||||
std::bind(&TCPIPPipe::HandleDownstreamReceived, shared_from_this(),
|
||||
std::placeholders::_1, std::placeholders::_2));
|
||||
std::placeholders::_1, std::placeholders::_2));
|
||||
}
|
||||
else
|
||||
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::transfer_all(),
|
||||
std::bind(&TCPIPPipe::HandleUpstreamWrite,
|
||||
shared_from_this(),
|
||||
std::placeholders::_1));
|
||||
shared_from_this(),
|
||||
std::placeholders::_1));
|
||||
}
|
||||
else
|
||||
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::transfer_all(),
|
||||
std::bind(&TCPIPPipe::HandleDownstreamWrite,
|
||||
shared_from_this(),
|
||||
std::placeholders::_1));
|
||||
shared_from_this(),
|
||||
std::placeholders::_1));
|
||||
}
|
||||
else
|
||||
LogPrint(eLogError, "TCPIPPipe: downstream write: no socket");
|
||||
|
|
|
@ -18,10 +18,12 @@ namespace client
|
|||
class I2PService : public std::enable_shared_from_this<I2PService>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef std::function<void(const boost::system::error_code &)> ReadyCallback;
|
||||
|
||||
public:
|
||||
I2PService (std::shared_ptr<ClientDestination> localDestination = nullptr);
|
||||
|
||||
I2PService (std::shared_ptr<ClientDestination> localDestination = nullptr);
|
||||
I2PService (i2p::data::SigningKeyType kt);
|
||||
virtual ~I2PService ();
|
||||
|
||||
|
@ -42,7 +44,7 @@ namespace client
|
|||
void AddReadyCallback(ReadyCallback cb);
|
||||
|
||||
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)
|
||||
{
|
||||
if (m_LocalDestination) m_LocalDestination->Release ();
|
||||
|
@ -59,21 +61,24 @@ namespace client
|
|||
virtual const char* GetName() { return "Generic I2P Service"; }
|
||||
|
||||
private:
|
||||
|
||||
void TriggerReadyCheckTimer();
|
||||
void HandleReadyCheckTimer(const boost::system::error_code & ec);
|
||||
|
||||
private:
|
||||
|
||||
std::shared_ptr<ClientDestination> m_LocalDestination;
|
||||
std::unordered_set<std::shared_ptr<I2PServiceHandler> > m_Handlers;
|
||||
std::mutex m_HandlersMutex;
|
||||
std::vector<std::pair<ReadyCallback, uint32_t> > m_ReadyCallbacks;
|
||||
boost::asio::deadline_timer m_ReadyTimer;
|
||||
bool m_ReadyTimerTriggered;
|
||||
bool m_ReadyTimerTriggered;
|
||||
uint32_t m_ConnectTimeout;
|
||||
|
||||
const size_t NEVER_TIMES_OUT = 0;
|
||||
const size_t NEVER_TIMES_OUT = 0;
|
||||
|
||||
public:
|
||||
|
||||
bool isUpdated; // transient, used during reload only
|
||||
};
|
||||
|
||||
|
@ -81,6 +86,7 @@ namespace client
|
|||
class I2PServiceHandler
|
||||
{
|
||||
public:
|
||||
|
||||
I2PServiceHandler(I2PService * parent) : m_Service(parent), m_Dead(false) { }
|
||||
virtual ~I2PServiceHandler() { }
|
||||
//If you override this make sure you call it from the children
|
||||
|
@ -89,6 +95,7 @@ namespace client
|
|||
void Terminate () { Kill (); };
|
||||
|
||||
protected:
|
||||
|
||||
// Call when terminating or handing over to avoid race conditions
|
||||
inline bool Kill () { return m_Dead.exchange(true); }
|
||||
// Call to know if the handler is dead
|
||||
|
@ -99,6 +106,7 @@ namespace client
|
|||
inline I2PService * GetOwner() { return m_Service; }
|
||||
|
||||
private:
|
||||
|
||||
I2PService *m_Service;
|
||||
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>
|
||||
{
|
||||
public:
|
||||
|
||||
TCPIPPipe(I2PService * owner, std::shared_ptr<boost::asio::ip::tcp::socket> upstream, std::shared_ptr<boost::asio::ip::tcp::socket> downstream);
|
||||
~TCPIPPipe();
|
||||
void Start();
|
||||
|
||||
protected:
|
||||
|
||||
void Terminate();
|
||||
void AsyncReceiveUpstream();
|
||||
void AsyncReceiveDownstream();
|
||||
|
@ -125,6 +135,7 @@ namespace client
|
|||
void DownstreamWrite(size_t len);
|
||||
|
||||
private:
|
||||
|
||||
uint8_t m_upstream_to_down_buf[TCP_IP_PIPE_BUFFER_SIZE], m_downstream_to_up_buf[TCP_IP_PIPE_BUFFER_SIZE];
|
||||
uint8_t m_upstream_buf[TCP_IP_PIPE_BUFFER_SIZE], m_downstream_buf[TCP_IP_PIPE_BUFFER_SIZE];
|
||||
std::shared_ptr<boost::asio::ip::tcp::socket> m_up, m_down;
|
||||
|
@ -135,6 +146,7 @@ namespace client
|
|||
class TCPIPAcceptor: public I2PService
|
||||
{
|
||||
public:
|
||||
|
||||
TCPIPAcceptor (const std::string& address, int port, std::shared_ptr<ClientDestination> localDestination = nullptr) :
|
||||
I2PService(localDestination),
|
||||
m_LocalEndpoint (boost::asio::ip::address::from_string(address), port),
|
||||
|
@ -149,14 +161,16 @@ namespace client
|
|||
//If you override this make sure you call it from the children
|
||||
void Stop ();
|
||||
|
||||
const boost::asio::ip::tcp::endpoint& GetLocalEndpoint () const { return m_LocalEndpoint; };
|
||||
const boost::asio::ip::tcp::endpoint& GetLocalEndpoint () const { return m_LocalEndpoint; };
|
||||
|
||||
virtual const char* GetName() { return "Generic TCP/IP accepting daemon"; }
|
||||
|
||||
protected:
|
||||
|
||||
virtual std::shared_ptr<I2PServiceHandler> CreateHandler(std::shared_ptr<boost::asio::ip::tcp::socket> socket) = 0;
|
||||
|
||||
private:
|
||||
|
||||
void Accept();
|
||||
void HandleAccept(const boost::system::error_code& ecode, std::shared_ptr<boost::asio::ip::tcp::socket> socket);
|
||||
boost::asio::ip::tcp::endpoint m_LocalEndpoint;
|
||||
|
|
|
@ -168,7 +168,7 @@ namespace client
|
|||
{
|
||||
m_Stream->AsyncReceive (boost::asio::buffer (m_StreamBuffer, I2P_TUNNEL_CONNECTION_BUFFER_SIZE),
|
||||
std::bind (&I2PTunnelConnection::HandleStreamReceive, shared_from_this (),
|
||||
std::placeholders::_1, std::placeholders::_2),
|
||||
std::placeholders::_1, std::placeholders::_2),
|
||||
I2P_TUNNEL_CONNECTION_MAX_IDLE);
|
||||
}
|
||||
else // closed by peer
|
||||
|
@ -281,7 +281,7 @@ namespace client
|
|||
if (endOfHeader)
|
||||
{
|
||||
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 << m_InHeader.str ().substr (m_InHeader.tellg ()); // data right after header
|
||||
m_InHeader.str ("");
|
||||
|
@ -477,7 +477,7 @@ namespace client
|
|||
{
|
||||
auto address = GetAddress ();
|
||||
if (address)
|
||||
return std::make_shared<I2PClientTunnelHandler>(this, address, m_DestinationPort, socket);
|
||||
return std::make_shared<I2PClientTunnelHandler>(this, address, m_DestinationPort, socket);
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ namespace client
|
|||
class I2PTunnelConnection: public I2PServiceHandler, public std::enable_shared_from_this<I2PTunnelConnection>
|
||||
{
|
||||
public:
|
||||
|
||||
I2PTunnelConnection (I2PService * owner, std::shared_ptr<boost::asio::ip::tcp::socket> socket,
|
||||
std::shared_ptr<const i2p::data::LeaseSet> leaseSet, int port = 0); // to I2P
|
||||
I2PTunnelConnection (I2PService * owner, std::shared_ptr<boost::asio::ip::tcp::socket> socket,
|
||||
|
@ -41,6 +42,7 @@ namespace client
|
|||
void Connect (bool isUniqueLocal = true);
|
||||
|
||||
protected:
|
||||
|
||||
void Terminate ();
|
||||
|
||||
void Receive ();
|
||||
|
@ -55,6 +57,7 @@ namespace client
|
|||
std::shared_ptr<const boost::asio::ip::tcp::socket> GetSocket () const { return m_Socket; };
|
||||
|
||||
private:
|
||||
|
||||
uint8_t m_Buffer[I2P_TUNNEL_CONNECTION_BUFFER_SIZE], m_StreamBuffer[I2P_TUNNEL_CONNECTION_BUFFER_SIZE];
|
||||
std::shared_ptr<boost::asio::ip::tcp::socket> m_Socket;
|
||||
std::shared_ptr<i2p::stream::Stream> m_Stream;
|
||||
|
@ -65,15 +68,18 @@ namespace client
|
|||
class I2PClientTunnelConnectionHTTP: public I2PTunnelConnection
|
||||
{
|
||||
public:
|
||||
|
||||
I2PClientTunnelConnectionHTTP (I2PService * owner, std::shared_ptr<boost::asio::ip::tcp::socket> socket,
|
||||
std::shared_ptr<i2p::stream::Stream> stream):
|
||||
I2PTunnelConnection (owner, socket, stream), m_HeaderSent (false),
|
||||
m_ConnectionSent (false), m_ProxyConnectionSent (false) {};
|
||||
|
||||
protected:
|
||||
|
||||
void Write (const uint8_t * buf, size_t len);
|
||||
|
||||
private:
|
||||
|
||||
std::stringstream m_InHeader, m_OutHeader;
|
||||
bool m_HeaderSent, m_ConnectionSent, m_ProxyConnectionSent;
|
||||
};
|
||||
|
@ -81,14 +87,17 @@ namespace client
|
|||
class I2PServerTunnelConnectionHTTP: public I2PTunnelConnection
|
||||
{
|
||||
public:
|
||||
|
||||
I2PServerTunnelConnectionHTTP (I2PService * owner, std::shared_ptr<i2p::stream::Stream> stream,
|
||||
std::shared_ptr<boost::asio::ip::tcp::socket> socket,
|
||||
const boost::asio::ip::tcp::endpoint& target, const std::string& host);
|
||||
|
||||
protected:
|
||||
|
||||
void Write (const uint8_t * buf, size_t len);
|
||||
|
||||
private:
|
||||
|
||||
std::string m_Host;
|
||||
std::stringstream m_InHeader, m_OutHeader;
|
||||
bool m_HeaderSent;
|
||||
|
@ -98,14 +107,17 @@ namespace client
|
|||
class I2PTunnelConnectionIRC: public I2PTunnelConnection
|
||||
{
|
||||
public:
|
||||
|
||||
I2PTunnelConnectionIRC (I2PService * owner, std::shared_ptr<i2p::stream::Stream> stream,
|
||||
std::shared_ptr<boost::asio::ip::tcp::socket> socket,
|
||||
const boost::asio::ip::tcp::endpoint& target, const std::string& m_WebircPass);
|
||||
|
||||
protected:
|
||||
|
||||
void Write (const uint8_t * buf, size_t len);
|
||||
|
||||
private:
|
||||
|
||||
std::shared_ptr<const i2p::data::IdentityEx> m_From;
|
||||
std::stringstream m_OutPacket, m_InPacket;
|
||||
bool m_NeedsWebIrc;
|
||||
|
@ -116,10 +128,12 @@ namespace client
|
|||
class I2PClientTunnel: public TCPIPAcceptor
|
||||
{
|
||||
protected:
|
||||
|
||||
// Implements TCPIPAcceptor
|
||||
std::shared_ptr<I2PServiceHandler> CreateHandler(std::shared_ptr<boost::asio::ip::tcp::socket> socket);
|
||||
|
||||
public:
|
||||
|
||||
I2PClientTunnel (const std::string& name, const std::string& destination,
|
||||
const std::string& address, int port, std::shared_ptr<ClientDestination> localDestination, int destinationPort = 0);
|
||||
~I2PClientTunnel () {}
|
||||
|
@ -130,9 +144,11 @@ namespace client
|
|||
const char* GetName() { return m_Name.c_str (); }
|
||||
|
||||
private:
|
||||
|
||||
std::shared_ptr<const Address> GetAddress ();
|
||||
|
||||
private:
|
||||
|
||||
std::string m_Name, m_Destination;
|
||||
std::shared_ptr<const Address> m_Address;
|
||||
int m_DestinationPort;
|
||||
|
@ -160,9 +176,9 @@ namespace client
|
|||
uint8_t m_Buffer[I2P_UDP_MAX_MTU];
|
||||
|
||||
UDPSession(boost::asio::ip::udp::endpoint localEndpoint,
|
||||
const std::shared_ptr<i2p::client::ClientDestination> & localDestination,
|
||||
boost::asio::ip::udp::endpoint remote, const i2p::data::IdentHash * ident,
|
||||
uint16_t ourPort, uint16_t theirPort);
|
||||
const std::shared_ptr<i2p::client::ClientDestination> & localDestination,
|
||||
boost::asio::ip::udp::endpoint remote, const i2p::data::IdentHash * ident,
|
||||
uint16_t ourPort, uint16_t theirPort);
|
||||
void HandleReceived(const boost::system::error_code & ecode, std::size_t len);
|
||||
void Receive();
|
||||
};
|
||||
|
@ -195,6 +211,7 @@ namespace client
|
|||
class I2PUDPServerTunnel
|
||||
{
|
||||
public:
|
||||
|
||||
I2PUDPServerTunnel(const std::string & name,
|
||||
std::shared_ptr<i2p::client::ClientDestination> localDestination,
|
||||
boost::asio::ip::address localAddress,
|
||||
|
@ -210,10 +227,12 @@ namespace client
|
|||
void SetUniqueLocal(bool isUniqueLocal = true) { m_IsUniqueLocal = isUniqueLocal; }
|
||||
|
||||
private:
|
||||
|
||||
void HandleRecvFromI2P(const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
|
||||
UDPSessionPtr ObtainUDPSession(const i2p::data::IdentityEx& from, uint16_t localPort, uint16_t remotePort);
|
||||
|
||||
private:
|
||||
|
||||
bool m_IsUniqueLocal;
|
||||
const std::string m_Name;
|
||||
boost::asio::ip::address m_LocalAddress;
|
||||
|
@ -226,6 +245,7 @@ namespace client
|
|||
class I2PUDPClientTunnel
|
||||
{
|
||||
public:
|
||||
|
||||
I2PUDPClientTunnel(const std::string & name, const std::string &remoteDest,
|
||||
boost::asio::ip::udp::endpoint localEndpoint, std::shared_ptr<i2p::client::ClientDestination> localDestination,
|
||||
uint16_t remotePort, bool gzip);
|
||||
|
@ -240,6 +260,7 @@ namespace client
|
|||
void ExpireStale(const uint64_t delta=I2P_UDP_SESSION_TIMEOUT);
|
||||
|
||||
private:
|
||||
|
||||
typedef std::pair<boost::asio::ip::udp::endpoint, uint64_t> UDPConvo;
|
||||
void RecvFromLocal();
|
||||
void HandleRecvFromLocal(const boost::system::error_code & e, std::size_t transferred);
|
||||
|
@ -263,6 +284,7 @@ namespace client
|
|||
class I2PServerTunnel: public I2PService
|
||||
{
|
||||
public:
|
||||
|
||||
I2PServerTunnel (const std::string& name, const std::string& address, int port,
|
||||
std::shared_ptr<ClientDestination> localDestination, int inport = 0, bool gzip = true);
|
||||
|
||||
|
@ -282,6 +304,7 @@ namespace client
|
|||
const char* GetName() { return m_Name.c_str (); }
|
||||
|
||||
private:
|
||||
|
||||
void HandleResolve (const boost::system::error_code& ecode, boost::asio::ip::tcp::resolver::iterator it,
|
||||
std::shared_ptr<boost::asio::ip::tcp::resolver> resolver);
|
||||
|
||||
|
@ -290,6 +313,7 @@ namespace client
|
|||
virtual std::shared_ptr<I2PTunnelConnection> CreateI2PConnection (std::shared_ptr<i2p::stream::Stream> stream);
|
||||
|
||||
private:
|
||||
|
||||
bool m_IsUniqueLocal;
|
||||
std::string m_Name, m_Address;
|
||||
int m_Port;
|
||||
|
@ -302,28 +326,34 @@ namespace client
|
|||
class I2PServerTunnelHTTP: public I2PServerTunnel
|
||||
{
|
||||
public:
|
||||
|
||||
I2PServerTunnelHTTP (const std::string& name, const std::string& address, int port,
|
||||
std::shared_ptr<ClientDestination> localDestination, const std::string& host,
|
||||
int inport = 0, bool gzip = true);
|
||||
|
||||
private:
|
||||
|
||||
std::shared_ptr<I2PTunnelConnection> CreateI2PConnection (std::shared_ptr<i2p::stream::Stream> stream);
|
||||
|
||||
private:
|
||||
|
||||
std::string m_Host;
|
||||
};
|
||||
|
||||
class I2PServerTunnelIRC: public I2PServerTunnel
|
||||
{
|
||||
public:
|
||||
|
||||
I2PServerTunnelIRC (const std::string& name, const std::string& address, int port,
|
||||
std::shared_ptr<ClientDestination> localDestination, const std::string& webircpass,
|
||||
int inport = 0, bool gzip = true);
|
||||
|
||||
private:
|
||||
|
||||
std::shared_ptr<I2PTunnelConnection> CreateI2PConnection (std::shared_ptr<i2p::stream::Stream> stream);
|
||||
|
||||
private:
|
||||
|
||||
std::string m_WebircPass;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace client
|
|||
{
|
||||
m_ResolveTimer->expires_from_now(boost::posix_time::seconds(1));
|
||||
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