mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-02-08 22:13:48 +01:00
Merge remote-tracking branch 'purple/openssl' into meshnet
This commit is contained in:
commit
43be363542
32 changed files with 486 additions and 382 deletions
|
@ -203,7 +203,7 @@ namespace client
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
AddressBook::AddressBook (): m_Storage(new AddressBookFilesystemStorage), m_IsLoaded (false), m_IsDownloading (false),
|
AddressBook::AddressBook (): m_Storage(nullptr), m_IsLoaded (false), m_IsDownloading (false),
|
||||||
m_DefaultSubscription (nullptr), m_SubscriptionsUpdateTimer (nullptr)
|
m_DefaultSubscription (nullptr), m_SubscriptionsUpdateTimer (nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -215,6 +215,8 @@ namespace client
|
||||||
|
|
||||||
void AddressBook::Start ()
|
void AddressBook::Start ()
|
||||||
{
|
{
|
||||||
|
if (!m_Storage)
|
||||||
|
m_Storage = new AddressBookFilesystemStorage;
|
||||||
m_Storage->Init();
|
m_Storage->Init();
|
||||||
LoadHosts (); /* try storage, then hosts.txt, then download */
|
LoadHosts (); /* try storage, then hosts.txt, then download */
|
||||||
StartSubscriptions ();
|
StartSubscriptions ();
|
||||||
|
|
95
Base.cpp
95
Base.cpp
|
@ -1,4 +1,6 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "Base.h"
|
#include "Base.h"
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
|
@ -283,99 +285,6 @@ namespace data
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
GzipInflator::GzipInflator (): m_IsDirty (false)
|
|
||||||
{
|
|
||||||
memset (&m_Inflator, 0, sizeof (m_Inflator));
|
|
||||||
inflateInit2 (&m_Inflator, MAX_WBITS + 16); // gzip
|
|
||||||
}
|
|
||||||
|
|
||||||
GzipInflator::~GzipInflator ()
|
|
||||||
{
|
|
||||||
inflateEnd (&m_Inflator);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t GzipInflator::Inflate (const uint8_t * in, size_t inLen, uint8_t * out, size_t outLen)
|
|
||||||
{
|
|
||||||
if (m_IsDirty) inflateReset (&m_Inflator);
|
|
||||||
m_IsDirty = true;
|
|
||||||
m_Inflator.next_in = const_cast<uint8_t *>(in);
|
|
||||||
m_Inflator.avail_in = inLen;
|
|
||||||
m_Inflator.next_out = out;
|
|
||||||
m_Inflator.avail_out = outLen;
|
|
||||||
int err;
|
|
||||||
if ((err = inflate (&m_Inflator, Z_NO_FLUSH)) == Z_STREAM_END) {
|
|
||||||
return outLen - m_Inflator.avail_out;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GzipInflator::Inflate (const uint8_t * in, size_t inLen, std::ostream& s)
|
|
||||||
{
|
|
||||||
m_IsDirty = true;
|
|
||||||
uint8_t * out = new uint8_t[GZIP_CHUNK_SIZE];
|
|
||||||
m_Inflator.next_in = const_cast<uint8_t *>(in);
|
|
||||||
m_Inflator.avail_in = inLen;
|
|
||||||
int ret;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
m_Inflator.next_out = out;
|
|
||||||
m_Inflator.avail_out = GZIP_CHUNK_SIZE;
|
|
||||||
ret = inflate (&m_Inflator, Z_NO_FLUSH);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
inflateEnd (&m_Inflator);
|
|
||||||
s.setstate(std::ios_base::failbit);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
s.write ((char *)out, GZIP_CHUNK_SIZE - m_Inflator.avail_out);
|
|
||||||
}
|
|
||||||
while (!m_Inflator.avail_out); // more data to read
|
|
||||||
delete[] out;
|
|
||||||
return ret == Z_STREAM_END || ret < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GzipInflator::Inflate (std::istream& in, std::ostream& out)
|
|
||||||
{
|
|
||||||
uint8_t * buf = new uint8_t[GZIP_CHUNK_SIZE];
|
|
||||||
while (!in.eof ())
|
|
||||||
{
|
|
||||||
in.read ((char *)buf, GZIP_CHUNK_SIZE);
|
|
||||||
Inflate (buf, in.gcount (), out);
|
|
||||||
}
|
|
||||||
delete[] buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
GzipDeflator::GzipDeflator (): m_IsDirty (false)
|
|
||||||
{
|
|
||||||
memset (&m_Deflator, 0, sizeof (m_Deflator));
|
|
||||||
deflateInit2 (&m_Deflator, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 + 16, 8, Z_DEFAULT_STRATEGY); // 15 + 16 sets gzip
|
|
||||||
}
|
|
||||||
|
|
||||||
GzipDeflator::~GzipDeflator ()
|
|
||||||
{
|
|
||||||
deflateEnd (&m_Deflator);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GzipDeflator::SetCompressionLevel (int level)
|
|
||||||
{
|
|
||||||
deflateParams (&m_Deflator, level, Z_DEFAULT_STRATEGY);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t GzipDeflator::Deflate (const uint8_t * in, size_t inLen, uint8_t * out, size_t outLen)
|
|
||||||
{
|
|
||||||
if (m_IsDirty) deflateReset (&m_Deflator);
|
|
||||||
m_IsDirty = true;
|
|
||||||
m_Deflator.next_in = const_cast<uint8_t *>(in);
|
|
||||||
m_Deflator.avail_in = inLen;
|
|
||||||
m_Deflator.next_out = out;
|
|
||||||
m_Deflator.avail_out = outLen;
|
|
||||||
int err;
|
|
||||||
if ((err = deflate (&m_Deflator, Z_FINISH)) == Z_STREAM_END) {
|
|
||||||
return outLen - m_Deflator.avail_out;
|
|
||||||
} /* else */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
117
Base.h
117
Base.h
|
@ -2,15 +2,11 @@
|
||||||
#define BASE_H__
|
#define BASE_H__
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <string.h>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <zlib.h>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p {
|
||||||
{
|
namespace data {
|
||||||
namespace data
|
|
||||||
{
|
|
||||||
size_t ByteStreamToBase64 (const uint8_t * InBuffer, size_t InCount, char * OutBuffer, size_t len);
|
size_t ByteStreamToBase64 (const uint8_t * InBuffer, size_t InCount, char * OutBuffer, size_t len);
|
||||||
size_t Base64ToByteStream (const char * InBuffer, size_t InCount, uint8_t * OutBuffer, size_t len );
|
size_t Base64ToByteStream (const char * InBuffer, size_t InCount, uint8_t * OutBuffer, size_t len );
|
||||||
const char * GetBase32SubstitutionTable ();
|
const char * GetBase32SubstitutionTable ();
|
||||||
|
@ -23,112 +19,7 @@ namespace data
|
||||||
Compute the size for a buffer to contain encoded base64 given that the size of the input is input_size bytes
|
Compute the size for a buffer to contain encoded base64 given that the size of the input is input_size bytes
|
||||||
*/
|
*/
|
||||||
size_t Base64EncodingBufferSize(const size_t input_size);
|
size_t Base64EncodingBufferSize(const size_t input_size);
|
||||||
|
} // data
|
||||||
template<int sz>
|
} // i2p
|
||||||
class Tag
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
Tag (const uint8_t * buf) { memcpy (m_Buf, buf, sz); };
|
|
||||||
Tag (const Tag<sz>& ) = default;
|
|
||||||
#ifndef _WIN32 // FIXME!!! msvs 2013 can't compile it
|
|
||||||
Tag (Tag<sz>&& ) = default;
|
|
||||||
#endif
|
|
||||||
Tag () = default;
|
|
||||||
|
|
||||||
Tag<sz>& operator= (const Tag<sz>& ) = default;
|
|
||||||
#ifndef _WIN32
|
|
||||||
Tag<sz>& operator= (Tag<sz>&& ) = default;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
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 uint64_t * GetLL () const { return ll; };
|
|
||||||
|
|
||||||
bool operator== (const Tag<sz>& other) const { return !memcmp (m_Buf, other.m_Buf, sz); };
|
|
||||||
bool operator< (const Tag<sz>& other) const { return memcmp (m_Buf, other.m_Buf, sz) < 0; };
|
|
||||||
|
|
||||||
bool IsZero () const
|
|
||||||
{
|
|
||||||
for (int i = 0; i < sz/8; i++)
|
|
||||||
if (ll[i]) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string ToBase64 () const
|
|
||||||
{
|
|
||||||
char str[sz*2];
|
|
||||||
int l = i2p::data::ByteStreamToBase64 (m_Buf, sz, str, sz*2);
|
|
||||||
str[l] = 0;
|
|
||||||
return std::string (str);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string ToBase32 () const
|
|
||||||
{
|
|
||||||
char str[sz*2];
|
|
||||||
int l = i2p::data::ByteStreamToBase32 (m_Buf, sz, str, sz*2);
|
|
||||||
str[l] = 0;
|
|
||||||
return std::string (str);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FromBase32 (const std::string& s)
|
|
||||||
{
|
|
||||||
i2p::data::Base32ToByteStream (s.c_str (), s.length (), m_Buf, sz);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FromBase64 (const std::string& s)
|
|
||||||
{
|
|
||||||
i2p::data::Base64ToByteStream (s.c_str (), s.length (), m_Buf, sz);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
union // 8 bytes alignment
|
|
||||||
{
|
|
||||||
uint8_t m_Buf[sz];
|
|
||||||
uint64_t ll[sz/8];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const size_t GZIP_CHUNK_SIZE = 16384;
|
|
||||||
class GzipInflator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
GzipInflator ();
|
|
||||||
~GzipInflator ();
|
|
||||||
|
|
||||||
size_t Inflate (const uint8_t * in, size_t inLen, uint8_t * out, size_t outLen);
|
|
||||||
bool Inflate (const uint8_t * in, size_t inLen, std::ostream& s);
|
|
||||||
// return true when finshed or error, s failbit will be set in case of error
|
|
||||||
void Inflate (std::istream& in, std::ostream& out);
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
z_stream m_Inflator;
|
|
||||||
bool m_IsDirty;
|
|
||||||
};
|
|
||||||
|
|
||||||
class GzipDeflator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
GzipDeflator ();
|
|
||||||
~GzipDeflator ();
|
|
||||||
|
|
||||||
void SetCompressionLevel (int level);
|
|
||||||
size_t Deflate (const uint8_t * in, size_t inLen, uint8_t * out, size_t outLen);
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
z_stream m_Deflator;
|
|
||||||
bool m_IsDirty;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
2
Crypto.h
2
Crypto.h
|
@ -9,7 +9,9 @@
|
||||||
#include <openssl/dsa.h>
|
#include <openssl/dsa.h>
|
||||||
#include <openssl/sha.h>
|
#include <openssl/sha.h>
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
|
|
||||||
#include "Base.h"
|
#include "Base.h"
|
||||||
|
#include "Tag.h"
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
|
|
226
DaemonWin32.cpp
226
DaemonWin32.cpp
|
@ -1,113 +1,115 @@
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include "Config.h"
|
#include <clocale>
|
||||||
#include "Daemon.h"
|
#include "Config.h"
|
||||||
#include "util.h"
|
#include "Daemon.h"
|
||||||
#include "Log.h"
|
#include "util.h"
|
||||||
|
#include "Log.h"
|
||||||
#ifdef _WIN32
|
|
||||||
|
#ifdef _WIN32
|
||||||
#include "Win32/Win32Service.h"
|
|
||||||
#ifdef WIN32_APP
|
#include "Win32/Win32Service.h"
|
||||||
#include "Win32/Win32App.h"
|
#ifdef WIN32_APP
|
||||||
#endif
|
#include "Win32/Win32App.h"
|
||||||
|
#endif
|
||||||
namespace i2p
|
|
||||||
{
|
namespace i2p
|
||||||
namespace util
|
{
|
||||||
{
|
namespace util
|
||||||
bool DaemonWin32::init(int argc, char* argv[])
|
{
|
||||||
{
|
bool DaemonWin32::init(int argc, char* argv[])
|
||||||
setlocale(LC_CTYPE, "");
|
{
|
||||||
SetConsoleCP(1251);
|
setlocale(LC_CTYPE, "");
|
||||||
SetConsoleOutputCP(1251);
|
SetConsoleCP(1251);
|
||||||
|
SetConsoleOutputCP(1251);
|
||||||
if (!Daemon_Singleton::init(argc, argv))
|
setlocale(LC_ALL, "Russian");
|
||||||
return false;
|
|
||||||
|
if (!Daemon_Singleton::init(argc, argv))
|
||||||
std::string serviceControl; i2p::config::GetOption("svcctl", serviceControl);
|
return false;
|
||||||
if (serviceControl == "install")
|
|
||||||
{
|
std::string serviceControl; i2p::config::GetOption("svcctl", serviceControl);
|
||||||
LogPrint(eLogInfo, "WinSVC: installing ", SERVICE_NAME, " as service");
|
if (serviceControl == "install")
|
||||||
InstallService(
|
{
|
||||||
SERVICE_NAME, // Name of service
|
LogPrint(eLogInfo, "WinSVC: installing ", SERVICE_NAME, " as service");
|
||||||
SERVICE_DISPLAY_NAME, // Name to display
|
InstallService(
|
||||||
SERVICE_START_TYPE, // Service start type
|
SERVICE_NAME, // Name of service
|
||||||
SERVICE_DEPENDENCIES, // Dependencies
|
SERVICE_DISPLAY_NAME, // Name to display
|
||||||
SERVICE_ACCOUNT, // Service running account
|
SERVICE_START_TYPE, // Service start type
|
||||||
SERVICE_PASSWORD // Password of the account
|
SERVICE_DEPENDENCIES, // Dependencies
|
||||||
);
|
SERVICE_ACCOUNT, // Service running account
|
||||||
return false;
|
SERVICE_PASSWORD // Password of the account
|
||||||
}
|
);
|
||||||
else if (serviceControl == "remove")
|
return false;
|
||||||
{
|
}
|
||||||
LogPrint(eLogInfo, "WinSVC: uninstalling ", SERVICE_NAME, " service");
|
else if (serviceControl == "remove")
|
||||||
UninstallService(SERVICE_NAME);
|
{
|
||||||
return false;
|
LogPrint(eLogInfo, "WinSVC: uninstalling ", SERVICE_NAME, " service");
|
||||||
}
|
UninstallService(SERVICE_NAME);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (isDaemon)
|
if (isDaemon)
|
||||||
{
|
{
|
||||||
LogPrint(eLogDebug, "Daemon: running as service");
|
LogPrint(eLogDebug, "Daemon: running as service");
|
||||||
I2PService service(SERVICE_NAME);
|
I2PService service(SERVICE_NAME);
|
||||||
if (!I2PService::Run(service))
|
if (!I2PService::Run(service))
|
||||||
{
|
{
|
||||||
LogPrint(eLogError, "Daemon: Service failed to run w/err 0x%08lx\n", GetLastError());
|
LogPrint(eLogError, "Daemon: Service failed to run w/err 0x%08lx\n", GetLastError());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint(eLogDebug, "Daemon: running as user");
|
LogPrint(eLogDebug, "Daemon: running as user");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DaemonWin32::start()
|
bool DaemonWin32::start()
|
||||||
{
|
{
|
||||||
setlocale(LC_CTYPE, "");
|
setlocale(LC_CTYPE, "");
|
||||||
SetConsoleCP(1251);
|
SetConsoleCP(1251);
|
||||||
SetConsoleOutputCP(1251);
|
SetConsoleOutputCP(1251);
|
||||||
setlocale(LC_ALL, "Russian");
|
setlocale(LC_ALL, "Russian");
|
||||||
#ifdef WIN32_APP
|
#ifdef WIN32_APP
|
||||||
if (!i2p::win32::StartWin32App ()) return false;
|
if (!i2p::win32::StartWin32App ()) return false;
|
||||||
|
|
||||||
// override log
|
// override log
|
||||||
i2p::config::SetOption("log", std::string ("file"));
|
i2p::config::SetOption("log", std::string ("file"));
|
||||||
#endif
|
#endif
|
||||||
bool ret = Daemon_Singleton::start();
|
bool ret = Daemon_Singleton::start();
|
||||||
if (ret && i2p::log::Logger().GetLogType() == eLogFile)
|
if (ret && i2p::log::Logger().GetLogType() == eLogFile)
|
||||||
{
|
{
|
||||||
// TODO: find out where this garbage to console comes from
|
// TODO: find out where this garbage to console comes from
|
||||||
SetStdHandle(STD_OUTPUT_HANDLE, INVALID_HANDLE_VALUE);
|
SetStdHandle(STD_OUTPUT_HANDLE, INVALID_HANDLE_VALUE);
|
||||||
SetStdHandle(STD_ERROR_HANDLE, INVALID_HANDLE_VALUE);
|
SetStdHandle(STD_ERROR_HANDLE, INVALID_HANDLE_VALUE);
|
||||||
}
|
}
|
||||||
bool insomnia; i2p::config::GetOption("insomnia", insomnia);
|
bool insomnia; i2p::config::GetOption("insomnia", insomnia);
|
||||||
if (insomnia)
|
if (insomnia)
|
||||||
SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED);
|
SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DaemonWin32::stop()
|
bool DaemonWin32::stop()
|
||||||
{
|
{
|
||||||
#ifdef WIN32_APP
|
#ifdef WIN32_APP
|
||||||
i2p::win32::StopWin32App ();
|
i2p::win32::StopWin32App ();
|
||||||
#endif
|
#endif
|
||||||
return Daemon_Singleton::stop();
|
return Daemon_Singleton::stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DaemonWin32::run ()
|
void DaemonWin32::run ()
|
||||||
{
|
{
|
||||||
#ifdef WIN32_APP
|
#ifdef WIN32_APP
|
||||||
i2p::win32::RunWin32App ();
|
i2p::win32::RunWin32App ();
|
||||||
#else
|
#else
|
||||||
while (running)
|
while (running)
|
||||||
{
|
{
|
||||||
std::this_thread::sleep_for (std::chrono::seconds(1));
|
std::this_thread::sleep_for (std::chrono::seconds(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
37
Garlic.cpp
37
Garlic.cpp
|
@ -7,6 +7,7 @@
|
||||||
#include "I2NPProtocol.h"
|
#include "I2NPProtocol.h"
|
||||||
#include "Tunnel.h"
|
#include "Tunnel.h"
|
||||||
#include "TunnelPool.h"
|
#include "TunnelPool.h"
|
||||||
|
#include "Transports.h"
|
||||||
#include "Timestamp.h"
|
#include "Timestamp.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Garlic.h"
|
#include "Garlic.h"
|
||||||
|
@ -514,26 +515,34 @@ namespace garlic
|
||||||
buf += 32;
|
buf += 32;
|
||||||
uint32_t gwTunnel = bufbe32toh (buf);
|
uint32_t gwTunnel = bufbe32toh (buf);
|
||||||
buf += 4;
|
buf += 4;
|
||||||
std::shared_ptr<i2p::tunnel::OutboundTunnel> tunnel;
|
auto msg = CreateI2NPMessage (buf, GetI2NPMessageLength (buf), from);
|
||||||
if (from && from->GetTunnelPool ())
|
if (from) // received through an inbound tunnel
|
||||||
tunnel = from->GetTunnelPool ()->GetNextOutboundTunnel ();
|
|
||||||
if (!tunnel)
|
|
||||||
{
|
{
|
||||||
tunnel = GetTunnelPool()->GetNextOutboundTunnel();
|
std::shared_ptr<i2p::tunnel::OutboundTunnel> tunnel;
|
||||||
|
if (from->GetTunnelPool ())
|
||||||
|
tunnel = from->GetTunnelPool ()->GetNextOutboundTunnel ();
|
||||||
|
else
|
||||||
|
LogPrint (eLogError, "Garlic: Tunnel pool is not set for inbound tunnel");
|
||||||
|
if (tunnel) // we have send it through an outbound tunnel
|
||||||
|
tunnel->SendTunnelDataMsg (gwHash, gwTunnel, msg);
|
||||||
|
else
|
||||||
|
LogPrint (eLogWarning, "Garlic: No outbound tunnels available for garlic clove");
|
||||||
}
|
}
|
||||||
if (tunnel) // we have send it through an outbound tunnel
|
else // received directly
|
||||||
{
|
i2p::transport::transports.SendMessage (gwHash, i2p::CreateTunnelGatewayMsg (gwTunnel, msg)); // send directly
|
||||||
auto msg = CreateI2NPMessage (buf, GetI2NPMessageLength (buf), from);
|
|
||||||
tunnel->SendTunnelDataMsg (gwHash, gwTunnel, msg);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
LogPrint (eLogWarning, "Garlic: No outbound tunnels available for garlic clove given tunnelID=", gwTunnel);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case eGarlicDeliveryTypeRouter:
|
case eGarlicDeliveryTypeRouter:
|
||||||
LogPrint (eLogWarning, "Garlic: type router not supported");
|
{
|
||||||
|
uint8_t * ident = buf;
|
||||||
buf += 32;
|
buf += 32;
|
||||||
break;
|
if (!from) // received directly
|
||||||
|
i2p::transport::transports.SendMessage (ident,
|
||||||
|
CreateI2NPMessage (buf, GetI2NPMessageLength (buf)));
|
||||||
|
else
|
||||||
|
LogPrint (eLogWarning, "Garlic: type router for inbound tunnels not supported");
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
LogPrint (eLogWarning, "Garlic: unknown delivery type ", (int)deliveryType);
|
LogPrint (eLogWarning, "Garlic: unknown delivery type ", (int)deliveryType);
|
||||||
}
|
}
|
||||||
|
|
108
Gzip.cpp
Normal file
108
Gzip.cpp
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2016, The PurpleI2P Project
|
||||||
|
*
|
||||||
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
|
*
|
||||||
|
* See full license text in LICENSE file at top of project tree
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <string.h> /* memset */
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "Gzip.h"
|
||||||
|
|
||||||
|
namespace i2p {
|
||||||
|
namespace data {
|
||||||
|
const size_t GZIP_CHUNK_SIZE = 16384;
|
||||||
|
|
||||||
|
GzipInflator::GzipInflator (): m_IsDirty (false)
|
||||||
|
{
|
||||||
|
memset (&m_Inflator, 0, sizeof (m_Inflator));
|
||||||
|
inflateInit2 (&m_Inflator, MAX_WBITS + 16); // gzip
|
||||||
|
}
|
||||||
|
|
||||||
|
GzipInflator::~GzipInflator ()
|
||||||
|
{
|
||||||
|
inflateEnd (&m_Inflator);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GzipInflator::Inflate (const uint8_t * in, size_t inLen, uint8_t * out, size_t outLen)
|
||||||
|
{
|
||||||
|
if (m_IsDirty) inflateReset (&m_Inflator);
|
||||||
|
m_IsDirty = true;
|
||||||
|
m_Inflator.next_in = const_cast<uint8_t *>(in);
|
||||||
|
m_Inflator.avail_in = inLen;
|
||||||
|
m_Inflator.next_out = out;
|
||||||
|
m_Inflator.avail_out = outLen;
|
||||||
|
int err;
|
||||||
|
if ((err = inflate (&m_Inflator, Z_NO_FLUSH)) == Z_STREAM_END) {
|
||||||
|
return outLen - m_Inflator.avail_out;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GzipInflator::Inflate (const uint8_t * in, size_t inLen, std::ostream& os)
|
||||||
|
{
|
||||||
|
m_IsDirty = true;
|
||||||
|
uint8_t * out = new uint8_t[GZIP_CHUNK_SIZE];
|
||||||
|
m_Inflator.next_in = const_cast<uint8_t *>(in);
|
||||||
|
m_Inflator.avail_in = inLen;
|
||||||
|
int ret;
|
||||||
|
do {
|
||||||
|
m_Inflator.next_out = out;
|
||||||
|
m_Inflator.avail_out = GZIP_CHUNK_SIZE;
|
||||||
|
ret = inflate (&m_Inflator, Z_NO_FLUSH);
|
||||||
|
if (ret < 0) {
|
||||||
|
inflateEnd (&m_Inflator);
|
||||||
|
os.setstate(std::ios_base::failbit);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
os.write ((char *)out, GZIP_CHUNK_SIZE - m_Inflator.avail_out);
|
||||||
|
} while (!m_Inflator.avail_out); // more data to read
|
||||||
|
delete[] out;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GzipInflator::Inflate (std::istream& in, std::ostream& out)
|
||||||
|
{
|
||||||
|
uint8_t * buf = new uint8_t[GZIP_CHUNK_SIZE];
|
||||||
|
while (!in.eof ())
|
||||||
|
{
|
||||||
|
in.read ((char *) buf, GZIP_CHUNK_SIZE);
|
||||||
|
Inflate (buf, in.gcount (), out);
|
||||||
|
}
|
||||||
|
delete[] buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
GzipDeflator::GzipDeflator (): m_IsDirty (false)
|
||||||
|
{
|
||||||
|
memset (&m_Deflator, 0, sizeof (m_Deflator));
|
||||||
|
deflateInit2 (&m_Deflator, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 + 16, 8, Z_DEFAULT_STRATEGY); // 15 + 16 sets gzip
|
||||||
|
}
|
||||||
|
|
||||||
|
GzipDeflator::~GzipDeflator ()
|
||||||
|
{
|
||||||
|
deflateEnd (&m_Deflator);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GzipDeflator::SetCompressionLevel (int level)
|
||||||
|
{
|
||||||
|
deflateParams (&m_Deflator, level, Z_DEFAULT_STRATEGY);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GzipDeflator::Deflate (const uint8_t * in, size_t inLen, uint8_t * out, size_t outLen)
|
||||||
|
{
|
||||||
|
if (m_IsDirty) deflateReset (&m_Deflator);
|
||||||
|
m_IsDirty = true;
|
||||||
|
m_Deflator.next_in = const_cast<uint8_t *>(in);
|
||||||
|
m_Deflator.avail_in = inLen;
|
||||||
|
m_Deflator.next_out = out;
|
||||||
|
m_Deflator.avail_out = outLen;
|
||||||
|
int err;
|
||||||
|
if ((err = deflate (&m_Deflator, Z_FINISH)) == Z_STREAM_END) {
|
||||||
|
return outLen - m_Deflator.avail_out;
|
||||||
|
} /* else */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} // data
|
||||||
|
} // i2p
|
44
Gzip.h
Normal file
44
Gzip.h
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
#ifndef GZIP_H__
|
||||||
|
#define GZIP_H__
|
||||||
|
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
|
namespace i2p {
|
||||||
|
namespace data {
|
||||||
|
class GzipInflator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
GzipInflator ();
|
||||||
|
~GzipInflator ();
|
||||||
|
|
||||||
|
size_t Inflate (const uint8_t * in, size_t inLen, uint8_t * out, size_t outLen);
|
||||||
|
/** @note @a os failbit will be set in case of error */
|
||||||
|
void Inflate (const uint8_t * in, size_t inLen, std::ostream& os);
|
||||||
|
void Inflate (std::istream& in, std::ostream& out);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
z_stream m_Inflator;
|
||||||
|
bool m_IsDirty;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GzipDeflator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
GzipDeflator ();
|
||||||
|
~GzipDeflator ();
|
||||||
|
|
||||||
|
void SetCompressionLevel (int level);
|
||||||
|
size_t Deflate (const uint8_t * in, size_t inLen, uint8_t * out, size_t outLen);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
z_stream m_Deflator;
|
||||||
|
bool m_IsDirty;
|
||||||
|
};
|
||||||
|
} // data
|
||||||
|
} // i2p
|
||||||
|
|
||||||
|
#endif /* GZIP_H__ */
|
|
@ -82,13 +82,13 @@ namespace proxy {
|
||||||
void HTTPReqHandler::AsyncSockRead()
|
void HTTPReqHandler::AsyncSockRead()
|
||||||
{
|
{
|
||||||
LogPrint(eLogDebug, "HTTPProxy: async sock read");
|
LogPrint(eLogDebug, "HTTPProxy: async sock read");
|
||||||
if(m_sock) {
|
if (!m_sock) {
|
||||||
m_sock->async_receive(boost::asio::buffer(m_http_buff, http_buffer_size),
|
|
||||||
std::bind(&HTTPReqHandler::HandleSockRecv, shared_from_this(),
|
|
||||||
std::placeholders::_1, std::placeholders::_2));
|
|
||||||
} else {
|
|
||||||
LogPrint(eLogError, "HTTPProxy: no socket for read");
|
LogPrint(eLogError, "HTTPProxy: no socket for read");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
m_sock->async_receive(boost::asio::buffer(m_http_buff, http_buffer_size),
|
||||||
|
std::bind(&HTTPReqHandler::HandleSockRecv, shared_from_this(),
|
||||||
|
std::placeholders::_1, std::placeholders::_2));
|
||||||
}
|
}
|
||||||
|
|
||||||
void HTTPReqHandler::Terminate() {
|
void HTTPReqHandler::Terminate() {
|
||||||
|
@ -335,20 +335,18 @@ namespace proxy {
|
||||||
|
|
||||||
void HTTPReqHandler::HandleStreamRequestComplete (std::shared_ptr<i2p::stream::Stream> stream)
|
void HTTPReqHandler::HandleStreamRequestComplete (std::shared_ptr<i2p::stream::Stream> stream)
|
||||||
{
|
{
|
||||||
if (stream)
|
if (!stream) {
|
||||||
{
|
|
||||||
if (Kill()) return;
|
|
||||||
LogPrint (eLogInfo, "HTTPProxy: New I2PTunnel connection");
|
|
||||||
auto connection = std::make_shared<i2p::client::I2PTunnelConnection>(GetOwner(), m_sock, stream);
|
|
||||||
GetOwner()->AddHandler (connection);
|
|
||||||
connection->I2PConnect (reinterpret_cast<const uint8_t*>(m_request.data()), m_request.size());
|
|
||||||
Done(shared_from_this());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LogPrint (eLogError, "HTTPProxy: error when creating the stream, check the previous warnings for more info");
|
LogPrint (eLogError, "HTTPProxy: error when creating the stream, check the previous warnings for more info");
|
||||||
HTTPRequestFailed("error when creating the stream, check logs");
|
HTTPRequestFailed("error when creating the stream, check logs");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
if (Kill())
|
||||||
|
return;
|
||||||
|
LogPrint (eLogDebug, "HTTPProxy: New I2PTunnel connection");
|
||||||
|
auto connection = std::make_shared<i2p::client::I2PTunnelConnection>(GetOwner(), m_sock, stream);
|
||||||
|
GetOwner()->AddHandler (connection);
|
||||||
|
connection->I2PConnect (reinterpret_cast<const uint8_t*>(m_request.data()), m_request.size());
|
||||||
|
Done (shared_from_this());
|
||||||
}
|
}
|
||||||
|
|
||||||
HTTPProxy::HTTPProxy(const std::string& address, int port, std::shared_ptr<i2p::client::ClientDestination> localDestination):
|
HTTPProxy::HTTPProxy(const std::string& address, int port, std::shared_ptr<i2p::client::ClientDestination> localDestination):
|
||||||
|
|
|
@ -126,8 +126,12 @@ namespace http {
|
||||||
s <<
|
s <<
|
||||||
"<!DOCTYPE html>\r\n"
|
"<!DOCTYPE html>\r\n"
|
||||||
"<html lang=\"en\">\r\n" /* TODO: Add support for locale */
|
"<html lang=\"en\">\r\n" /* TODO: Add support for locale */
|
||||||
" <head>\r\n"
|
" <head>\r\n" /* TODO: Find something to parse html/template system. This is horrible. */
|
||||||
" <meta charset=\"UTF-8\">\r\n" /* TODO: Find something to parse html/template system. This is horrible. */
|
#if (!defined(WIN32))
|
||||||
|
" <meta charset=\"UTF-8\">\r\n"
|
||||||
|
#else
|
||||||
|
" <meta charset=\"windows-1251\">\r\n"
|
||||||
|
#endif
|
||||||
" <link rel=\"shortcut icon\" href=\"" << itoopieFavicon << "\">\r\n"
|
" <link rel=\"shortcut icon\" href=\"" << itoopieFavicon << "\">\r\n"
|
||||||
" <title>Purple I2P " VERSION " Webconsole</title>\r\n"
|
" <title>Purple I2P " VERSION " Webconsole</title>\r\n"
|
||||||
<< cssStyles <<
|
<< cssStyles <<
|
||||||
|
|
1
Makefile
1
Makefile
|
@ -12,6 +12,7 @@ include filelist.mk
|
||||||
USE_AESNI := yes
|
USE_AESNI := yes
|
||||||
USE_STATIC := no
|
USE_STATIC := no
|
||||||
USE_MESHNET := yes
|
USE_MESHNET := yes
|
||||||
|
USE_UPNP := no
|
||||||
|
|
||||||
ifeq ($(UNAME),Darwin)
|
ifeq ($(UNAME),Darwin)
|
||||||
DAEMON_SRC += DaemonLinux.cpp
|
DAEMON_SRC += DaemonLinux.cpp
|
||||||
|
|
|
@ -8,7 +8,7 @@ INCFLAGS = -I${SSLROOT}/include -I${BOOSTROOT}/include
|
||||||
LDFLAGS = -L${SSLROOT}/lib -L${BOOSTROOT}/lib
|
LDFLAGS = -L${SSLROOT}/lib -L${BOOSTROOT}/lib
|
||||||
LDLIBS = -lz -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
|
LDLIBS = -lz -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
|
||||||
|
|
||||||
ifeq ($(USE_UPNP),1)
|
ifeq ($(USE_UPNP),yes)
|
||||||
LDFLAGS += -ldl
|
LDFLAGS += -ldl
|
||||||
CXXFLAGS += -DUSE_UPNP
|
CXXFLAGS += -DUSE_UPNP
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -43,7 +43,7 @@ else
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# UPNP Support (miniupnpc 1.5 or 1.6)
|
# UPNP Support (miniupnpc 1.5 or 1.6)
|
||||||
ifeq ($(USE_UPNP),1)
|
ifeq ($(USE_UPNP),yes)
|
||||||
LDFLAGS += -lminiupnpc
|
LDFLAGS += -lminiupnpc
|
||||||
CXXFLAGS += -DUSE_UPNP
|
CXXFLAGS += -DUSE_UPNP
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -9,7 +9,7 @@ LDFLAGS = -Wl,-rpath,/usr/local/lib \
|
||||||
-L/usr/local/lib
|
-L/usr/local/lib
|
||||||
|
|
||||||
# UPNP Support
|
# UPNP Support
|
||||||
ifeq ($(USE_UPNP),1)
|
ifeq ($(USE_UPNP),yes)
|
||||||
CXXFLAGS += -DUSE_UPNP -DMINIUPNP_STATICLIB
|
CXXFLAGS += -DUSE_UPNP -DMINIUPNP_STATICLIB
|
||||||
LDLIBS = -Wl,-Bstatic -lminiupnpc
|
LDLIBS = -Wl,-Bstatic -lminiupnpc
|
||||||
endif
|
endif
|
||||||
|
@ -37,7 +37,7 @@ ifeq ($(USE_WIN32_APP), yes)
|
||||||
DAEMON_OBJS += $(patsubst %.rc,obj/%.o,$(DAEMON_RC))
|
DAEMON_OBJS += $(patsubst %.rc,obj/%.o,$(DAEMON_RC))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(USE_AESNI),1)
|
ifeq ($(USE_AESNI),yes)
|
||||||
CPU_FLAGS = -maes -DAESNI
|
CPU_FLAGS = -maes -DAESNI
|
||||||
else
|
else
|
||||||
CPU_FLAGS = -msse
|
CPU_FLAGS = -msse
|
||||||
|
|
|
@ -5,7 +5,7 @@ INCFLAGS = -I/usr/local/include -I/usr/local/ssl/include
|
||||||
LDFLAGS = -Wl,-rpath,/usr/local/lib -L/usr/local/lib -L/usr/local/ssl/lib
|
LDFLAGS = -Wl,-rpath,/usr/local/lib -L/usr/local/lib -L/usr/local/ssl/lib
|
||||||
LDLIBS = -lz -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
|
LDLIBS = -lz -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
|
||||||
|
|
||||||
ifeq ($(USE_UPNP),1)
|
ifeq ($(USE_UPNP),yes)
|
||||||
LDFLAGS += -ldl
|
LDFLAGS += -ldl
|
||||||
CXXFLAGS += -DUSE_UPNP
|
CXXFLAGS += -DUSE_UPNP
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <zlib.h>
|
|
||||||
#include "I2PEndian.h"
|
#include "I2PEndian.h"
|
||||||
#include "Base.h"
|
#include "Base.h"
|
||||||
#include "Crypto.h"
|
#include "Crypto.h"
|
||||||
|
@ -430,7 +430,7 @@ namespace transport
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogPrint (eLogInfo, "NTCP: Server session from ", m_Socket.remote_endpoint (), " connected");
|
LogPrint (eLogDebug, "NTCP: Server session from ", m_Socket.remote_endpoint (), " connected");
|
||||||
m_Server.AddNTCPSession (shared_from_this ());
|
m_Server.AddNTCPSession (shared_from_this ());
|
||||||
|
|
||||||
Connected ();
|
Connected ();
|
||||||
|
@ -942,7 +942,7 @@ namespace transport
|
||||||
{
|
{
|
||||||
if (ecode)
|
if (ecode)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "NTCP: Connect error: ", ecode.message ());
|
LogPrint (eLogError, "NTCP: Can't connect to ", conn->GetSocket ().remote_endpoint (), ": ", ecode.message ());
|
||||||
if (ecode != boost::asio::error::operation_aborted)
|
if (ecode != boost::asio::error::operation_aborted)
|
||||||
i2p::data::netdb.SetUnreachable (conn->GetRemoteIdentity ()->GetIdentHash (), true);
|
i2p::data::netdb.SetUnreachable (conn->GetRemoteIdentity ()->GetIdentHash (), true);
|
||||||
conn->Terminate ();
|
conn->Terminate ();
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
#include <zlib.h>
|
|
||||||
#include "I2PEndian.h"
|
#include "I2PEndian.h"
|
||||||
#include "Base.h"
|
#include "Base.h"
|
||||||
#include "Crypto.h"
|
#include "Crypto.h"
|
||||||
|
@ -671,7 +671,7 @@ namespace data
|
||||||
|
|
||||||
if (!replyMsg)
|
if (!replyMsg)
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "NetDb: Requested ", key, " not found. ", numExcluded, " excluded");
|
LogPrint (eLogWarning, "NetDb: Requested ", key, " not found, ", numExcluded, " peers excluded");
|
||||||
// find or cleate response
|
// find or cleate response
|
||||||
std::vector<IdentHash> closestFloodfills;
|
std::vector<IdentHash> closestFloodfills;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
2
NetDb.h
2
NetDb.h
|
@ -8,7 +8,9 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#include "Base.h"
|
#include "Base.h"
|
||||||
|
#include "Gzip.h"
|
||||||
#include "FS.h"
|
#include "FS.h"
|
||||||
#include "Queue.h"
|
#include "Queue.h"
|
||||||
#include "I2NPProtocol.h"
|
#include "I2NPProtocol.h"
|
||||||
|
|
8
SSU.cpp
8
SSU.cpp
|
@ -253,7 +253,7 @@ namespace transport
|
||||||
session = std::make_shared<SSUSession> (*this, packet->from);
|
session = std::make_shared<SSUSession> (*this, packet->from);
|
||||||
session->WaitForConnect ();
|
session->WaitForConnect ();
|
||||||
(*sessions)[packet->from] = session;
|
(*sessions)[packet->from] = session;
|
||||||
LogPrint (eLogInfo, "SSU: new session from ", packet->from.address ().to_string (), ":", packet->from.port (), " created");
|
LogPrint (eLogDebug, "SSU: new session from ", packet->from.address ().to_string (), ":", packet->from.port (), " created");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
session->ProcessNextMessage (packet->buf, packet->len, packet->from);
|
session->ProcessNextMessage (packet->buf, packet->len, packet->from);
|
||||||
|
@ -334,7 +334,7 @@ namespace transport
|
||||||
auto session = std::make_shared<SSUSession> (*this, remoteEndpoint, router, peerTest);
|
auto session = std::make_shared<SSUSession> (*this, remoteEndpoint, router, peerTest);
|
||||||
sessions[remoteEndpoint] = session;
|
sessions[remoteEndpoint] = session;
|
||||||
// connect
|
// connect
|
||||||
LogPrint (eLogInfo, "SSU: Creating new session to [", i2p::data::GetIdentHashAbbreviation (router->GetIdentHash ()), "] ",
|
LogPrint (eLogDebug, "SSU: Creating new session to [", i2p::data::GetIdentHashAbbreviation (router->GetIdentHash ()), "] ",
|
||||||
remoteEndpoint.address ().to_string (), ":", remoteEndpoint.port ());
|
remoteEndpoint.address ().to_string (), ":", remoteEndpoint.port ());
|
||||||
session->Connect ();
|
session->Connect ();
|
||||||
}
|
}
|
||||||
|
@ -386,10 +386,10 @@ namespace transport
|
||||||
}
|
}
|
||||||
|
|
||||||
if (introducerSession) // session found
|
if (introducerSession) // session found
|
||||||
LogPrint (eLogInfo, "SSU: Session to introducer already exists");
|
LogPrint (eLogWarning, "SSU: Session to introducer already exists");
|
||||||
else // create new
|
else // create new
|
||||||
{
|
{
|
||||||
LogPrint (eLogInfo, "SSU: Creating new session to introducer");
|
LogPrint (eLogDebug, "SSU: Creating new session to introducer ", introducer->iHost);
|
||||||
boost::asio::ip::udp::endpoint introducerEndpoint (introducer->iHost, introducer->iPort);
|
boost::asio::ip::udp::endpoint introducerEndpoint (introducer->iHost, introducer->iPort);
|
||||||
introducerSession = std::make_shared<SSUSession> (*this, introducerEndpoint, router);
|
introducerSession = std::make_shared<SSUSession> (*this, introducerEndpoint, router);
|
||||||
m_Sessions[introducerEndpoint] = introducerSession;
|
m_Sessions[introducerEndpoint] = introducerSession;
|
||||||
|
|
|
@ -241,7 +241,7 @@ namespace transport
|
||||||
if (!msg->IsExpired ())
|
if (!msg->IsExpired ())
|
||||||
m_Handler.PutNextMessage (msg);
|
m_Handler.PutNextMessage (msg);
|
||||||
else
|
else
|
||||||
LogPrint (eLogInfo, "SSU: message expired");
|
LogPrint (eLogDebug, "SSU: message expired");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogWarning, "SSU: Message ", msgID, " already received");
|
LogPrint (eLogWarning, "SSU: Message ", msgID, " already received");
|
||||||
|
|
|
@ -814,7 +814,7 @@ namespace transport
|
||||||
if (!ecode)
|
if (!ecode)
|
||||||
{
|
{
|
||||||
// timeout expired
|
// timeout expired
|
||||||
LogPrint (eLogWarning, "SSU: session was not established after ", SSU_CONNECT_TIMEOUT, " seconds");
|
LogPrint (eLogWarning, "SSU: session with ", m_RemoteEndpoint, " was not established after ", SSU_CONNECT_TIMEOUT, " seconds");
|
||||||
Failed ();
|
Failed ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -891,7 +891,7 @@ namespace transport
|
||||||
{
|
{
|
||||||
if (ecode != boost::asio::error::operation_aborted)
|
if (ecode != boost::asio::error::operation_aborted)
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "SSU: no activity for ", SSU_TERMINATION_TIMEOUT, " seconds");
|
LogPrint (eLogWarning, "SSU: no activity with ", m_RemoteEndpoint, " for ", SSU_TERMINATION_TIMEOUT, " seconds");
|
||||||
Failed ();
|
Failed ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
82
Tag.h
Normal file
82
Tag.h
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
#ifndef TAG_H__
|
||||||
|
#define TAG_H__
|
||||||
|
|
||||||
|
#include <string.h> /* memcpy */
|
||||||
|
|
||||||
|
#include "Base.h"
|
||||||
|
|
||||||
|
namespace i2p {
|
||||||
|
namespace data {
|
||||||
|
template<int sz>
|
||||||
|
class Tag
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
Tag (const uint8_t * buf) { memcpy (m_Buf, buf, sz); };
|
||||||
|
Tag (const Tag<sz>& ) = default;
|
||||||
|
#ifndef _WIN32 // FIXME!!! msvs 2013 can't compile it
|
||||||
|
Tag (Tag<sz>&& ) = default;
|
||||||
|
#endif
|
||||||
|
Tag () = default;
|
||||||
|
|
||||||
|
Tag<sz>& operator= (const Tag<sz>& ) = default;
|
||||||
|
#ifndef _WIN32
|
||||||
|
Tag<sz>& operator= (Tag<sz>&& ) = default;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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 uint64_t * GetLL () const { return ll; };
|
||||||
|
|
||||||
|
bool operator== (const Tag<sz>& other) const { return !memcmp (m_Buf, other.m_Buf, sz); };
|
||||||
|
bool operator< (const Tag<sz>& other) const { return memcmp (m_Buf, other.m_Buf, sz) < 0; };
|
||||||
|
|
||||||
|
bool IsZero () const
|
||||||
|
{
|
||||||
|
for (int i = 0; i < sz/8; i++)
|
||||||
|
if (ll[i]) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ToBase64 () const
|
||||||
|
{
|
||||||
|
char str[sz*2];
|
||||||
|
int l = i2p::data::ByteStreamToBase64 (m_Buf, sz, str, sz*2);
|
||||||
|
str[l] = 0;
|
||||||
|
return std::string (str);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ToBase32 () const
|
||||||
|
{
|
||||||
|
char str[sz*2];
|
||||||
|
int l = i2p::data::ByteStreamToBase32 (m_Buf, sz, str, sz*2);
|
||||||
|
str[l] = 0;
|
||||||
|
return std::string (str);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FromBase32 (const std::string& s)
|
||||||
|
{
|
||||||
|
i2p::data::Base32ToByteStream (s.c_str (), s.length (), m_Buf, sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FromBase64 (const std::string& s)
|
||||||
|
{
|
||||||
|
i2p::data::Base64ToByteStream (s.c_str (), s.length (), m_Buf, sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
union // 8 bytes alignment
|
||||||
|
{
|
||||||
|
uint8_t m_Buf[sz];
|
||||||
|
uint64_t ll[sz/8];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} // data
|
||||||
|
} // i2p
|
||||||
|
|
||||||
|
#endif /* TAG_H__ */
|
|
@ -92,7 +92,7 @@ namespace tunnel
|
||||||
{
|
{
|
||||||
if (isEndpoint)
|
if (isEndpoint)
|
||||||
{
|
{
|
||||||
LogPrint (eLogInfo, "TransitTunnel: endpoint ", receiveTunnelID, " created");
|
LogPrint (eLogDebug, "TransitTunnel: endpoint ", receiveTunnelID, " created");
|
||||||
return std::make_shared<TransitTunnelEndpoint> (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey);
|
return std::make_shared<TransitTunnelEndpoint> (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey);
|
||||||
}
|
}
|
||||||
else if (isGateway)
|
else if (isGateway)
|
||||||
|
@ -102,7 +102,7 @@ namespace tunnel
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogPrint (eLogInfo, "TransitTunnel: ", receiveTunnelID, "->", nextTunnelID, " created");
|
LogPrint (eLogDebug, "TransitTunnel: ", receiveTunnelID, "->", nextTunnelID, " created");
|
||||||
return std::make_shared<TransitTunnelParticipant> (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey);
|
return std::make_shared<TransitTunnelParticipant> (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ set (LIBI2PD_SRC
|
||||||
"${CMAKE_SOURCE_DIR}/Config.cpp"
|
"${CMAKE_SOURCE_DIR}/Config.cpp"
|
||||||
"${CMAKE_SOURCE_DIR}/Crypto.cpp"
|
"${CMAKE_SOURCE_DIR}/Crypto.cpp"
|
||||||
"${CMAKE_SOURCE_DIR}/Garlic.cpp"
|
"${CMAKE_SOURCE_DIR}/Garlic.cpp"
|
||||||
|
"${CMAKE_SOURCE_DIR}/Gzip.cpp"
|
||||||
"${CMAKE_SOURCE_DIR}/I2NPProtocol.cpp"
|
"${CMAKE_SOURCE_DIR}/I2NPProtocol.cpp"
|
||||||
"${CMAKE_SOURCE_DIR}/Identity.cpp"
|
"${CMAKE_SOURCE_DIR}/Identity.cpp"
|
||||||
"${CMAKE_SOURCE_DIR}/LeaseSet.cpp"
|
"${CMAKE_SOURCE_DIR}/LeaseSet.cpp"
|
||||||
|
|
1
debian/control
vendored
1
debian/control
vendored
|
@ -8,6 +8,7 @@ Build-Depends: debhelper (>= 9.0.0), dpkg-dev (>= 1.16.1~),
|
||||||
libboost-date-time-dev,
|
libboost-date-time-dev,
|
||||||
libboost-filesystem-dev,
|
libboost-filesystem-dev,
|
||||||
libboost-program-options-dev,
|
libboost-program-options-dev,
|
||||||
|
libminiupnpc-dev,
|
||||||
libssl-dev
|
libssl-dev
|
||||||
Standards-Version: 3.9.3
|
Standards-Version: 3.9.3
|
||||||
Homepage: https://github.com/PurpleI2P/i2pd
|
Homepage: https://github.com/PurpleI2P/i2pd
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
diff --git a/Makefile b/Makefile
|
diff --git a/Makefile b/Makefile
|
||||||
index 2e86fd8..c1037af 100644
|
index fe8ae7e..fc8abda 100644
|
||||||
--- a/Makefile
|
--- a/Makefile
|
||||||
+++ b/Makefile
|
+++ b/Makefile
|
||||||
@@ -9,7 +9,7 @@ DEPS := obj/make.dep
|
@@ -9,9 +9,9 @@ DEPS := obj/make.dep
|
||||||
|
|
||||||
include filelist.mk
|
include filelist.mk
|
||||||
|
|
||||||
-USE_AESNI := yes
|
-USE_AESNI := yes
|
||||||
+USE_AESNI := no
|
+USE_AESNI := no
|
||||||
USE_STATIC := no
|
USE_STATIC := no
|
||||||
|
-USE_UPNP := no
|
||||||
|
+USE_UPNP := yes
|
||||||
|
|
||||||
ifeq ($(UNAME),Darwin)
|
ifeq ($(UNAME),Darwin)
|
||||||
|
DAEMON_SRC += DaemonLinux.cpp
|
2
debian/patches/series
vendored
2
debian/patches/series
vendored
|
@ -1 +1 @@
|
||||||
0001-disable-aesni-by-default.patch
|
01-tune-build-opts.patch
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
LIB_SRC = \
|
LIB_SRC = \
|
||||||
Crypto.cpp Datagram.cpp Garlic.cpp I2NPProtocol.cpp LeaseSet.cpp \
|
Gzip.cpp Crypto.cpp Datagram.cpp Garlic.cpp I2NPProtocol.cpp LeaseSet.cpp \
|
||||||
Log.cpp NTCPSession.cpp NetDb.cpp NetDbRequests.cpp Profiling.cpp \
|
Log.cpp NTCPSession.cpp NetDb.cpp NetDbRequests.cpp Profiling.cpp \
|
||||||
Reseed.cpp RouterContext.cpp RouterInfo.cpp Signature.cpp SSU.cpp \
|
Reseed.cpp RouterContext.cpp RouterInfo.cpp Signature.cpp SSU.cpp \
|
||||||
SSUSession.cpp SSUData.cpp Streaming.cpp Identity.cpp TransitTunnel.cpp \
|
SSUSession.cpp SSUData.cpp Streaming.cpp Identity.cpp TransitTunnel.cpp \
|
||||||
|
|
|
@ -36,7 +36,7 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \
|
||||||
../../RouterInfo.cpp ../../SAM.cpp ../../Signature.cpp ../../SOCKS.cpp ../../SSU.cpp \
|
../../RouterInfo.cpp ../../SAM.cpp ../../Signature.cpp ../../SOCKS.cpp ../../SSU.cpp \
|
||||||
../../SSUData.cpp ../../SSUSession.cpp ../../Streaming.cpp ../../TransitTunnel.cpp \
|
../../SSUData.cpp ../../SSUSession.cpp ../../Streaming.cpp ../../TransitTunnel.cpp \
|
||||||
../../Transports.cpp ../../Tunnel.cpp ../../TunnelEndpoint.cpp ../../TunnelGateway.cpp \
|
../../Transports.cpp ../../Tunnel.cpp ../../TunnelEndpoint.cpp ../../TunnelGateway.cpp \
|
||||||
../../TunnelPool.cpp ../../UPnP.cpp ../../util.cpp ../../i2pd.cpp
|
../../TunnelPool.cpp ../../UPnP.cpp ../../util.cpp ../../Gzip.cpp ../../i2pd.cpp
|
||||||
|
|
||||||
HEADERS += DaemonQT.h mainwindow.h \
|
HEADERS += DaemonQT.h mainwindow.h \
|
||||||
../../HTTPServer.h ../../I2PControl.h ../../UPnP.h ../../Daemon.h ../../Config.h \
|
../../HTTPServer.h ../../I2PControl.h ../../UPnP.h ../../Daemon.h ../../Config.h \
|
||||||
|
@ -50,7 +50,7 @@ HEADERS += DaemonQT.h mainwindow.h \
|
||||||
../../Streaming.h ../../Timestamp.h ../../TransitTunnel.h ../../Transports.h \
|
../../Streaming.h ../../Timestamp.h ../../TransitTunnel.h ../../Transports.h \
|
||||||
../../TransportSession.h ../../Tunnel.h ../../TunnelBase.h ../../TunnelConfig.h \
|
../../TransportSession.h ../../Tunnel.h ../../TunnelBase.h ../../TunnelConfig.h \
|
||||||
../../TunnelEndpoint.h ../../TunnelGateway.h ../../TunnelPool.h ../../UPnP.h \
|
../../TunnelEndpoint.h ../../TunnelGateway.h ../../TunnelPool.h ../../UPnP.h \
|
||||||
../../util.h ../../version.h
|
../../util.h ../../version.h ..//../Gzip.h ../../Tag.h
|
||||||
|
|
||||||
FORMS += mainwindow.ui
|
FORMS += mainwindow.ui
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
CXXFLAGS += -Wall -Wextra -pedantic -O0 -g -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1
|
CXXFLAGS += -Wall -Wextra -pedantic -O0 -g -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1
|
||||||
|
|
||||||
TESTS = test-http-url test-http-req test-http-res test-http-url_decode \
|
TESTS = test-http-url test-http-req test-http-res test-http-url_decode \
|
||||||
test-http-merge_chunked
|
test-http-merge_chunked test-base-64
|
||||||
|
|
||||||
all: $(TESTS) run
|
all: $(TESTS) run
|
||||||
|
|
||||||
test-http-%: test-http-%.cpp ../HTTP.cpp
|
test-http-%: ../HTTP.cpp test-http-%.cpp
|
||||||
|
$(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^
|
||||||
|
|
||||||
|
test-base-%: ../Base.cpp test-base-%.cpp
|
||||||
$(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^
|
$(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^
|
||||||
|
|
||||||
run: $(TESTS)
|
run: $(TESTS)
|
||||||
|
|
45
tests/test-base-64.cpp
Normal file
45
tests/test-base-64.cpp
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
#include <cassert>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "../Base.h"
|
||||||
|
|
||||||
|
using namespace i2p::data;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
const char *in = "test";
|
||||||
|
size_t in_len = strlen(in);
|
||||||
|
char out[16];
|
||||||
|
|
||||||
|
/* bytes -> b64 */
|
||||||
|
assert(ByteStreamToBase64(NULL, 0, NULL, 0) == 0);
|
||||||
|
assert(ByteStreamToBase64(NULL, 0, out, sizeof(out)) == 0);
|
||||||
|
|
||||||
|
assert(Base64EncodingBufferSize(2) == 4);
|
||||||
|
assert(Base64EncodingBufferSize(4) == 8);
|
||||||
|
assert(Base64EncodingBufferSize(6) == 8);
|
||||||
|
assert(Base64EncodingBufferSize(7) == 12);
|
||||||
|
assert(Base64EncodingBufferSize(9) == 12);
|
||||||
|
assert(Base64EncodingBufferSize(10) == 16);
|
||||||
|
assert(Base64EncodingBufferSize(12) == 16);
|
||||||
|
assert(Base64EncodingBufferSize(13) == 20);
|
||||||
|
|
||||||
|
assert(ByteStreamToBase64((uint8_t *) in, in_len, out, sizeof(out)) == 8);
|
||||||
|
assert(memcmp(out, "dGVzdA==", 8) == 0);
|
||||||
|
|
||||||
|
/* b64 -> bytes */
|
||||||
|
assert(Base64ToByteStream(NULL, 0, NULL, 0) == 0);
|
||||||
|
assert(Base64ToByteStream(NULL, 0, (uint8_t *) out, sizeof(out)) == 0);
|
||||||
|
|
||||||
|
in = "dGVzdA=="; /* valid b64 */
|
||||||
|
assert(Base64ToByteStream(in, strlen(in), (uint8_t *) out, sizeof(out)) == 4);
|
||||||
|
assert(memcmp(out, "test", 4) == 0);
|
||||||
|
|
||||||
|
in = "dGVzdA="; /* invalid b64 : not padded */
|
||||||
|
assert(Base64ToByteStream(in, strlen(in), (uint8_t *) out, sizeof(out)) == 0);
|
||||||
|
|
||||||
|
in = "dG/z.A=="; /* invalid b64 : char not from alphabet */
|
||||||
|
// assert(Base64ToByteStream(in, strlen(in), (uint8_t *) out, sizeof(out)) == 0);
|
||||||
|
// ^^^ fails, current implementation not checks acceptable symbols
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -22,7 +22,6 @@ int main() {
|
||||||
assert(req->version == "HTTP/1.0");
|
assert(req->version == "HTTP/1.0");
|
||||||
assert(req->method == "GET");
|
assert(req->method == "GET");
|
||||||
assert(req->uri == "/");
|
assert(req->uri == "/");
|
||||||
assert(req->host == "inr.i2p");
|
|
||||||
assert(req->headers.size() == 3);
|
assert(req->headers.size() == 3);
|
||||||
assert(req->headers.count("Host") == 1);
|
assert(req->headers.count("Host") == 1);
|
||||||
assert(req->headers.count("Accept") == 1);
|
assert(req->headers.count("Accept") == 1);
|
||||||
|
@ -42,7 +41,6 @@ int main() {
|
||||||
assert(req->version == "HTTP/1.0");
|
assert(req->version == "HTTP/1.0");
|
||||||
assert(req->method == "GET");
|
assert(req->method == "GET");
|
||||||
assert(req->uri == "/");
|
assert(req->uri == "/");
|
||||||
assert(req->host == "");
|
|
||||||
assert(req->headers.size() == 0);
|
assert(req->headers.size() == 0);
|
||||||
delete req;
|
delete req;
|
||||||
|
|
||||||
|
@ -52,7 +50,7 @@ int main() {
|
||||||
"\r\n";
|
"\r\n";
|
||||||
len = strlen(buf);
|
len = strlen(buf);
|
||||||
req = new HTTPReq;
|
req = new HTTPReq;
|
||||||
assert((ret = req->parse(buf, len)) == -1); /* no host header */
|
assert((ret = req->parse(buf, len)) > 0);
|
||||||
delete req;
|
delete req;
|
||||||
|
|
||||||
/* test: parsing incomplete request */
|
/* test: parsing incomplete request */
|
||||||
|
@ -76,7 +74,6 @@ int main() {
|
||||||
assert((ret = req->parse(buf, len)) == len); /* no host header */
|
assert((ret = req->parse(buf, len)) == len); /* no host header */
|
||||||
assert(req->method == "GET");
|
assert(req->method == "GET");
|
||||||
assert(req->uri == "http://inr.i2p");
|
assert(req->uri == "http://inr.i2p");
|
||||||
assert(req->host == "stats.i2p");
|
|
||||||
assert(req->headers.size() == 3);
|
assert(req->headers.size() == 3);
|
||||||
assert(req->headers.count("Host") == 1);
|
assert(req->headers.count("Host") == 1);
|
||||||
assert(req->headers.count("Accept") == 1);
|
assert(req->headers.count("Accept") == 1);
|
||||||
|
|
Loading…
Add table
Reference in a new issue