mirror of
https://github.com/PurpleI2P/i2pd
synced 2024-11-10 08:00:38 +03:00
commit
bfff125cc5
9
Base.cpp
9
Base.cpp
@ -190,6 +190,13 @@ namespace data
|
||||
return outCount;
|
||||
}
|
||||
|
||||
size_t Base64EncodingBufferSize (const size_t input_size)
|
||||
{
|
||||
auto d = div (input_size, 3);
|
||||
if (d.rem) d.quot++;
|
||||
return 4*d.quot;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* iT64
|
||||
@ -327,7 +334,7 @@ namespace data
|
||||
LogPrint (eLogError, "Compression error ", err);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
5
Base.h
5
Base.h
@ -17,6 +17,11 @@ 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
|
||||
*/
|
||||
size_t Base64EncodingBufferSize(const size_t input_size);
|
||||
|
||||
template<int sz>
|
||||
class Tag
|
||||
{
|
||||
|
2
Crypto.h
2
Crypto.h
@ -70,7 +70,7 @@ namespace crypto
|
||||
|
||||
void operator^=(const ChipherBlock& other) // XOR
|
||||
{
|
||||
#if defined(__x86_64__) // for Intel x64
|
||||
#if defined(__x86_64__) || defined(__SSE__) // for Intel x84 or with SSE
|
||||
__asm__
|
||||
(
|
||||
"movups (%[buf]), %%xmm0 \n"
|
||||
|
@ -17,9 +17,9 @@ void handle_signal(int sig)
|
||||
switch (sig)
|
||||
{
|
||||
case SIGHUP:
|
||||
LogPrint(eLogInfo, "Daemon: Got SIGHUP, doing nothing");
|
||||
// TODO:
|
||||
break;
|
||||
LogPrint(eLogInfo, "Daemon: Got SIGHUP, reopening log...");
|
||||
ReopenLogFile ();
|
||||
break;
|
||||
case SIGABRT:
|
||||
case SIGTERM:
|
||||
case SIGINT:
|
||||
|
@ -187,16 +187,17 @@ namespace client
|
||||
auto it = m_RemoteLeaseSets.find (ident);
|
||||
if (it != m_RemoteLeaseSets.end ())
|
||||
{
|
||||
if (it->second->HasNonExpiredLeases ())
|
||||
if (!it->second->IsExpired ())
|
||||
return it->second;
|
||||
else
|
||||
LogPrint (eLogWarning, "Destination: All leases of remote LeaseSet expired");
|
||||
LogPrint (eLogWarning, "Destination: remote LeaseSet expired");
|
||||
}
|
||||
else
|
||||
{
|
||||
auto ls = i2p::data::netdb.FindLeaseSet (ident);
|
||||
if (ls)
|
||||
{
|
||||
ls->PopulateLeases (); // since we don't store them in netdb
|
||||
m_RemoteLeaseSets[ident] = ls;
|
||||
return ls;
|
||||
}
|
||||
@ -664,7 +665,7 @@ namespace client
|
||||
{
|
||||
if (ecode != boost::asio::error::operation_aborted)
|
||||
{
|
||||
CleanupRoutingSessions ();
|
||||
CleanupExpiredTags ();
|
||||
CleanupRemoteLeaseSets ();
|
||||
m_CleanupTimer.expires_from_now (boost::posix_time::minutes (DESTINATION_CLEANUP_TIMEOUT));
|
||||
m_CleanupTimer.async_wait (std::bind (&ClientDestination::HandleCleanupTimer,
|
||||
@ -674,9 +675,10 @@ namespace client
|
||||
|
||||
void ClientDestination::CleanupRemoteLeaseSets ()
|
||||
{
|
||||
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
|
||||
for (auto it = m_RemoteLeaseSets.begin (); it != m_RemoteLeaseSets.end ();)
|
||||
{
|
||||
if (!it->second->HasNonExpiredLeases ()) // all leases expired
|
||||
if (ts > it->second->GetExpirationTime ()) // leaseset expired
|
||||
{
|
||||
LogPrint (eLogWarning, "Destination: Remote LeaseSet ", it->second->GetIdentHash ().ToBase64 (), " expired");
|
||||
it = m_RemoteLeaseSets.erase (it);
|
||||
|
@ -72,7 +72,7 @@ namespace client
|
||||
bool IsRunning () const { return m_IsRunning; };
|
||||
boost::asio::io_service& GetService () { return m_Service; };
|
||||
std::shared_ptr<i2p::tunnel::TunnelPool> GetTunnelPool () { return m_Pool; };
|
||||
bool IsReady () const { return m_LeaseSet && m_LeaseSet->HasNonExpiredLeases () && m_Pool->GetOutboundTunnels ().size () > 0; };
|
||||
bool IsReady () const { return m_LeaseSet && !m_LeaseSet->IsExpired () && m_Pool->GetOutboundTunnels ().size () > 0; };
|
||||
std::shared_ptr<const i2p::data::LeaseSet> FindLeaseSet (const i2p::data::IdentHash& ident);
|
||||
bool RequestDestination (const i2p::data::IdentHash& dest, RequestComplete requestComplete = nullptr);
|
||||
void CancelDestinationRequest (const i2p::data::IdentHash& dest);
|
||||
|
41
Garlic.cpp
41
Garlic.cpp
@ -409,28 +409,6 @@ namespace garlic
|
||||
else
|
||||
LogPrint (eLogError, "Garlic: Failed to decrypt message");
|
||||
}
|
||||
|
||||
// cleanup expired tags
|
||||
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
||||
if (ts > m_LastTagsCleanupTime + INCOMING_TAGS_EXPIRATION_TIMEOUT)
|
||||
{
|
||||
if (m_LastTagsCleanupTime)
|
||||
{
|
||||
int numExpiredTags = 0;
|
||||
for (auto it = m_Tags.begin (); it != m_Tags.end ();)
|
||||
{
|
||||
if (ts > it->first.creationTime + INCOMING_TAGS_EXPIRATION_TIMEOUT)
|
||||
{
|
||||
numExpiredTags++;
|
||||
it = m_Tags.erase (it);
|
||||
}
|
||||
else
|
||||
it++;
|
||||
}
|
||||
LogPrint (eLogDebug, "Garlic: ", numExpiredTags, " tags expired for ", GetIdentHash().ToBase64 ());
|
||||
}
|
||||
m_LastTagsCleanupTime = ts;
|
||||
}
|
||||
}
|
||||
|
||||
void GarlicDestination::HandleAESBlock (uint8_t * buf, size_t len, std::shared_ptr<i2p::crypto::CBCDecryption> decryption,
|
||||
@ -570,8 +548,25 @@ namespace garlic
|
||||
return session;
|
||||
}
|
||||
|
||||
void GarlicDestination::CleanupRoutingSessions ()
|
||||
void GarlicDestination::CleanupExpiredTags ()
|
||||
{
|
||||
// incoming
|
||||
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
||||
int numExpiredTags = 0;
|
||||
for (auto it = m_Tags.begin (); it != m_Tags.end ();)
|
||||
{
|
||||
if (ts > it->first.creationTime + INCOMING_TAGS_EXPIRATION_TIMEOUT)
|
||||
{
|
||||
numExpiredTags++;
|
||||
it = m_Tags.erase (it);
|
||||
}
|
||||
else
|
||||
it++;
|
||||
}
|
||||
if (numExpiredTags > 0)
|
||||
LogPrint (eLogDebug, "Garlic: ", numExpiredTags, " tags expired for ", GetIdentHash().ToBase64 ());
|
||||
|
||||
// outgoing
|
||||
std::unique_lock<std::mutex> l(m_SessionsMutex);
|
||||
for (auto it = m_Sessions.begin (); it != m_Sessions.end ();)
|
||||
{
|
||||
|
8
Garlic.h
8
Garlic.h
@ -119,18 +119,19 @@ namespace garlic
|
||||
// for HTTP only
|
||||
size_t GetNumOutgoingTags () const { return m_SessionTags.size (); };
|
||||
};
|
||||
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 GarlicDestination: public i2p::data::LocalDestination
|
||||
{
|
||||
public:
|
||||
|
||||
GarlicDestination (): m_NumTags (32), m_LastTagsCleanupTime (0) {}; // 32 tags by default
|
||||
GarlicDestination (): m_NumTags (32) {}; // 32 tags by default
|
||||
~GarlicDestination ();
|
||||
|
||||
void SetNumTags (int numTags) { m_NumTags = numTags; };
|
||||
std::shared_ptr<GarlicRoutingSession> GetRoutingSession (std::shared_ptr<const i2p::data::RoutingDestination> destination, bool attachLeaseSet);
|
||||
void CleanupRoutingSessions ();
|
||||
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);
|
||||
@ -166,7 +167,6 @@ namespace garlic
|
||||
std::map<i2p::data::IdentHash, GarlicRoutingSessionPtr> m_Sessions;
|
||||
// incoming
|
||||
std::map<SessionTag, std::shared_ptr<i2p::crypto::CBCDecryption>> m_Tags;
|
||||
uint32_t m_LastTagsCleanupTime;
|
||||
// DeliveryStatus
|
||||
std::map<uint32_t, GarlicRoutingSessionPtr> m_DeliveryStatusSessions; // msgID -> session
|
||||
|
||||
|
@ -793,7 +793,7 @@ namespace util
|
||||
}
|
||||
|
||||
auto leaseSet = i2p::client::context.GetSharedLocalDestination ()->FindLeaseSet (destination);
|
||||
if (leaseSet && leaseSet->HasNonExpiredLeases ())
|
||||
if (leaseSet && !leaseSet->IsExpired ())
|
||||
SendToDestination (leaseSet, port, buf, len);
|
||||
else
|
||||
{
|
||||
@ -812,7 +812,7 @@ namespace util
|
||||
if (ecode != boost::asio::error::operation_aborted)
|
||||
{
|
||||
auto leaseSet = i2p::client::context.GetSharedLocalDestination ()->FindLeaseSet (destination);
|
||||
if (leaseSet && leaseSet->HasNonExpiredLeases ())
|
||||
if (leaseSet && !leaseSet->IsExpired ())
|
||||
SendToDestination (leaseSet, port, buf, len);
|
||||
else
|
||||
// still no LeaseSet
|
||||
|
29
Identity.cpp
29
Identity.cpp
@ -22,6 +22,10 @@ namespace data
|
||||
|
||||
size_t Identity::FromBuffer (const uint8_t * buf, size_t len)
|
||||
{
|
||||
if ( len < DEFAULT_IDENTITY_SIZE ) {
|
||||
// buffer too small, don't overflow
|
||||
return 0;
|
||||
}
|
||||
memcpy (publicKey, buf, DEFAULT_IDENTITY_SIZE);
|
||||
return DEFAULT_IDENTITY_SIZE;
|
||||
}
|
||||
@ -228,26 +232,35 @@ namespace data
|
||||
}
|
||||
|
||||
size_t IdentityEx::ToBuffer (uint8_t * buf, size_t len) const
|
||||
{
|
||||
{
|
||||
const size_t fullLen = GetFullLen();
|
||||
if (fullLen > len) {
|
||||
// buffer is too small and may overflow somewhere else
|
||||
return 0;
|
||||
}
|
||||
memcpy (buf, &m_StandardIdentity, DEFAULT_IDENTITY_SIZE);
|
||||
if (m_ExtendedLen > 0 && m_ExtendedBuffer)
|
||||
memcpy (buf + DEFAULT_IDENTITY_SIZE, m_ExtendedBuffer, m_ExtendedLen);
|
||||
return GetFullLen ();
|
||||
return fullLen;
|
||||
}
|
||||
|
||||
size_t IdentityEx::FromBase64(const std::string& s)
|
||||
{
|
||||
uint8_t buf[1024];
|
||||
auto len = Base64ToByteStream (s.c_str(), s.length(), buf, 1024);
|
||||
const size_t slen = s.length();
|
||||
const size_t bufLen = Base64EncodingBufferSize(slen);
|
||||
uint8_t buf[bufLen];
|
||||
const size_t len = Base64ToByteStream (s.c_str(), slen, buf, bufLen);
|
||||
return FromBuffer (buf, len);
|
||||
}
|
||||
|
||||
std::string IdentityEx::ToBase64 () const
|
||||
{
|
||||
uint8_t buf[1024];
|
||||
char str[1536];
|
||||
size_t l = ToBuffer (buf, 1024);
|
||||
size_t l1 = i2p::data::ByteStreamToBase64 (buf, l, str, 1536);
|
||||
const size_t bufLen = GetFullLen();
|
||||
const size_t strLen = Base64EncodingBufferSize(bufLen);
|
||||
uint8_t buf[bufLen];
|
||||
char str[strLen];
|
||||
size_t l = ToBuffer (buf, bufLen);
|
||||
size_t l1 = i2p::data::ByteStreamToBase64 (buf, l, str, strLen);
|
||||
str[l1] = 0;
|
||||
return std::string (str);
|
||||
}
|
||||
|
49
LeaseSet.cpp
49
LeaseSet.cpp
@ -12,8 +12,8 @@ namespace i2p
|
||||
namespace data
|
||||
{
|
||||
|
||||
LeaseSet::LeaseSet (const uint8_t * buf, size_t len):
|
||||
m_IsValid (true)
|
||||
LeaseSet::LeaseSet (const uint8_t * buf, size_t len, bool storeLeases):
|
||||
m_IsValid (true), m_StoreLeases (storeLeases), m_ExpirationTime (0)
|
||||
{
|
||||
m_Buffer = new uint8_t[len];
|
||||
memcpy (m_Buffer, buf, len);
|
||||
@ -22,7 +22,7 @@ namespace data
|
||||
}
|
||||
|
||||
LeaseSet::LeaseSet (std::shared_ptr<const i2p::tunnel::TunnelPool> pool):
|
||||
m_IsValid (true)
|
||||
m_IsValid (true), m_StoreLeases (true), m_ExpirationTime (0)
|
||||
{
|
||||
if (!pool) return;
|
||||
// header
|
||||
@ -55,6 +55,7 @@ namespace data
|
||||
uint64_t ts = it->GetCreationTime () + i2p::tunnel::TUNNEL_EXPIRATION_TIMEOUT - i2p::tunnel::TUNNEL_EXPIRATION_THRESHOLD; // 1 minute before expiration
|
||||
ts *= 1000; // in milliseconds
|
||||
ts += rand () % 6; // + random milliseconds 0-5
|
||||
if (ts > m_ExpirationTime) m_ExpirationTime = ts;
|
||||
htobe64buf (m_Buffer + m_BufferLen, ts);
|
||||
m_BufferLen += 8; // end date
|
||||
}
|
||||
@ -79,7 +80,14 @@ namespace data
|
||||
m_BufferLen = len;
|
||||
ReadFromBuffer (false);
|
||||
}
|
||||
|
||||
|
||||
void LeaseSet::PopulateLeases ()
|
||||
{
|
||||
m_StoreLeases = true;
|
||||
m_Leases.clear ();
|
||||
ReadFromBuffer (false);
|
||||
}
|
||||
|
||||
void LeaseSet::ReadFromBuffer (bool readIdentity)
|
||||
{
|
||||
if (readIdentity || !m_Identity)
|
||||
@ -105,6 +113,7 @@ namespace data
|
||||
}
|
||||
|
||||
// process leases
|
||||
m_ExpirationTime = 0;
|
||||
const uint8_t * leases = m_Buffer + size;
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
@ -113,16 +122,20 @@ namespace data
|
||||
leases += 32; // gateway
|
||||
lease.tunnelID = bufbe32toh (leases);
|
||||
leases += 4; // tunnel ID
|
||||
lease.endDate = bufbe64toh (leases);
|
||||
lease.endDate = bufbe64toh (leases);
|
||||
leases += 8; // end date
|
||||
m_Leases.push_back (lease);
|
||||
|
||||
// check if lease's gateway is in our netDb
|
||||
if (!netdb.FindRouter (lease.tunnelGateway))
|
||||
{
|
||||
// if not found request it
|
||||
LogPrint (eLogInfo, "LeaseSet: Lease's tunnel gateway not found, requesting");
|
||||
netdb.RequestDestination (lease.tunnelGateway);
|
||||
if (lease.endDate > m_ExpirationTime)
|
||||
m_ExpirationTime = lease.endDate;
|
||||
if (m_StoreLeases)
|
||||
{
|
||||
m_Leases.push_back (lease);
|
||||
// check if lease's gateway is in our netDb
|
||||
if (!netdb.FindRouter (lease.tunnelGateway))
|
||||
{
|
||||
// if not found request it
|
||||
LogPrint (eLogInfo, "LeaseSet: Lease's tunnel gateway not found, requesting");
|
||||
netdb.RequestDestination (lease.tunnelGateway);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -150,19 +163,17 @@ namespace data
|
||||
}
|
||||
|
||||
bool LeaseSet::HasExpiredLeases () const
|
||||
{
|
||||
{
|
||||
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
|
||||
for (auto& it: m_Leases)
|
||||
if (ts >= it.endDate) return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool LeaseSet::HasNonExpiredLeases () const
|
||||
bool LeaseSet::IsExpired () const
|
||||
{
|
||||
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
|
||||
for (auto& it: m_Leases)
|
||||
if (ts < it.endDate) return true;
|
||||
return false;
|
||||
return ts > m_ExpirationTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,10 +37,11 @@ namespace data
|
||||
{
|
||||
public:
|
||||
|
||||
LeaseSet (const uint8_t * buf, size_t len);
|
||||
LeaseSet (const uint8_t * buf, size_t len, bool storeLeases = true);
|
||||
LeaseSet (std::shared_ptr<const i2p::tunnel::TunnelPool> pool);
|
||||
~LeaseSet () { delete[] m_Buffer; };
|
||||
void Update (const uint8_t * buf, size_t len);
|
||||
void PopulateLeases (); /// from buffer
|
||||
std::shared_ptr<const IdentityEx> GetIdentity () const { return m_Identity; };
|
||||
|
||||
const uint8_t * GetBuffer () const { return m_Buffer; };
|
||||
@ -52,7 +53,8 @@ namespace data
|
||||
const std::vector<Lease>& GetLeases () const { return m_Leases; };
|
||||
const std::vector<Lease> GetNonExpiredLeases (bool withThreshold = true) const;
|
||||
bool HasExpiredLeases () const;
|
||||
bool HasNonExpiredLeases () const;
|
||||
bool IsExpired () const;
|
||||
uint64_t GetExpirationTime () const { return m_ExpirationTime; };
|
||||
const uint8_t * GetEncryptionPublicKey () const { return m_EncryptionKey; };
|
||||
bool IsDestination () const { return true; };
|
||||
|
||||
@ -62,8 +64,9 @@ namespace data
|
||||
|
||||
private:
|
||||
|
||||
bool m_IsValid;
|
||||
bool m_IsValid, m_StoreLeases; // we don't need to store leases for floodfill
|
||||
std::vector<Lease> m_Leases;
|
||||
uint64_t m_ExpirationTime; // in milliseconds
|
||||
std::shared_ptr<const IdentityEx> m_Identity;
|
||||
uint8_t m_EncryptionKey[256];
|
||||
uint8_t * m_Buffer;
|
||||
|
23
Log.cpp
23
Log.cpp
@ -13,7 +13,8 @@ static const char * g_LogLevelStr[eNumLogLevels] =
|
||||
|
||||
void LogMsg::Process()
|
||||
{
|
||||
auto& output = (log && log->GetLogStream ()) ? *log->GetLogStream () : std::cerr;
|
||||
auto stream = log ? log->GetLogStream () : nullptr;
|
||||
auto& output = stream ? *stream : std::cout;
|
||||
if (log)
|
||||
output << log->GetTimestamp ();
|
||||
else
|
||||
@ -45,16 +46,25 @@ void Log::Flush ()
|
||||
|
||||
void Log::SetLogFile (const std::string& fullFilePath)
|
||||
{
|
||||
auto logFile = new std::ofstream (fullFilePath, std::ofstream::out | std::ofstream::binary | std::ofstream::trunc);
|
||||
m_FullFilePath = fullFilePath;
|
||||
auto logFile = std::make_shared<std::ofstream> (fullFilePath, std::ofstream::out | std::ofstream::binary | std::ofstream::trunc);
|
||||
if (logFile->is_open ())
|
||||
{
|
||||
SetLogStream (logFile);
|
||||
LogPrint(eLogInfo, "Log: will send messages to ", fullFilePath);
|
||||
}
|
||||
else
|
||||
delete logFile;
|
||||
}
|
||||
|
||||
void Log::ReopenLogFile ()
|
||||
{
|
||||
if (m_FullFilePath.length () > 0)
|
||||
{
|
||||
SetLogFile (m_FullFilePath);
|
||||
LogPrint(eLogInfo, "Log: file ", m_FullFilePath, " reopen");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Log::SetLogLevel (const std::string& level)
|
||||
{
|
||||
if (level == "error") { m_MinLevel = eLogError; }
|
||||
@ -65,11 +75,10 @@ void Log::SetLogLevel (const std::string& level)
|
||||
LogPrint(eLogError, "Log: Unknown loglevel: ", level);
|
||||
return;
|
||||
}
|
||||
LogPrint(eLogInfo, "Log: min messages level set to ", level);
|
||||
LogPrint(eLogInfo, "Log: min msg level set to ", level);
|
||||
}
|
||||
|
||||
void Log::SetLogStream (std::ostream * logStream)
|
||||
void Log::SetLogStream (std::shared_ptr<std::ostream> logStream)
|
||||
{
|
||||
if (m_LogStream) delete m_LogStream;
|
||||
m_LogStream = logStream;
|
||||
}
|
||||
|
21
Log.h
21
Log.h
@ -7,6 +7,7 @@
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include "Queue.h"
|
||||
|
||||
enum LogLevel
|
||||
@ -34,13 +35,14 @@ class Log: public i2p::util::MsgQueue<LogMsg>
|
||||
{
|
||||
public:
|
||||
|
||||
Log (): m_LogStream (nullptr) { SetOnEmpty (std::bind (&Log::Flush, this)); };
|
||||
~Log () { delete m_LogStream; };
|
||||
Log () { SetOnEmpty (std::bind (&Log::Flush, this)); };
|
||||
~Log () {};
|
||||
|
||||
void SetLogFile (const std::string& fullFilePath);
|
||||
void ReopenLogFile ();
|
||||
void SetLogLevel (const std::string& level);
|
||||
void SetLogStream (std::ostream * logStream);
|
||||
std::ostream * GetLogStream () const { return m_LogStream; };
|
||||
void SetLogStream (std::shared_ptr<std::ostream> logStream);
|
||||
std::shared_ptr<std::ostream> GetLogStream () const { return m_LogStream; };
|
||||
const std::string& GetTimestamp ();
|
||||
LogLevel GetLogLevel () { return m_MinLevel; };
|
||||
|
||||
@ -50,7 +52,8 @@ class Log: public i2p::util::MsgQueue<LogMsg>
|
||||
|
||||
private:
|
||||
|
||||
std::ostream * m_LogStream;
|
||||
std::string m_FullFilePath; // empty if stream
|
||||
std::shared_ptr<std::ostream> m_LogStream;
|
||||
enum LogLevel m_MinLevel;
|
||||
std::string m_Timestamp;
|
||||
#if (__GNUC__ == 4) && (__GNUC_MINOR__ <= 6) && !defined(__clang__) // gcc 4.6
|
||||
@ -73,7 +76,7 @@ inline void StartLog (const std::string& fullFilePath)
|
||||
}
|
||||
}
|
||||
|
||||
inline void StartLog (std::ostream * s)
|
||||
inline void StartLog (std::shared_ptr<std::ostream> s)
|
||||
{
|
||||
if (!g_Log)
|
||||
{
|
||||
@ -101,6 +104,12 @@ inline void SetLogLevel (const std::string& level)
|
||||
g_Log->SetLogLevel(level);
|
||||
}
|
||||
|
||||
inline void ReopenLogFile ()
|
||||
{
|
||||
if (g_Log)
|
||||
g_Log->ReopenLogFile ();
|
||||
}
|
||||
|
||||
template<typename TValue>
|
||||
void LogPrint (std::stringstream& s, TValue arg)
|
||||
{
|
||||
|
@ -8,4 +8,6 @@ LDLIBS = -Wl,-Bstatic -lboost_system$(BOOST_SUFFIX) -Wl,-Bstatic -lboost_date_ti
|
||||
|
||||
ifeq ($(USE_AESNI),1)
|
||||
CPU_FLAGS = -maes -DAESNI
|
||||
else
|
||||
CPU_FLAGS = -msse
|
||||
endif
|
||||
|
@ -134,6 +134,7 @@ namespace transport
|
||||
|
||||
void NTCPSession::HandlePhase1Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred)
|
||||
{
|
||||
(void) bytes_transferred;
|
||||
if (ecode)
|
||||
{
|
||||
LogPrint (eLogInfo, "NTCP: couldn't send Phase 1 message: ", ecode.message ());
|
||||
@ -150,6 +151,7 @@ namespace transport
|
||||
|
||||
void NTCPSession::HandlePhase1Received (const boost::system::error_code& ecode, std::size_t bytes_transferred)
|
||||
{
|
||||
(void) bytes_transferred;
|
||||
if (ecode)
|
||||
{
|
||||
LogPrint (eLogInfo, "NTCP: phase 1 read error: ", ecode.message ());
|
||||
@ -205,6 +207,7 @@ namespace transport
|
||||
|
||||
void NTCPSession::HandlePhase2Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsB)
|
||||
{
|
||||
(void) bytes_transferred;
|
||||
if (ecode)
|
||||
{
|
||||
LogPrint (eLogInfo, "NTCP: Couldn't send Phase 2 message: ", ecode.message ());
|
||||
@ -221,6 +224,7 @@ namespace transport
|
||||
|
||||
void NTCPSession::HandlePhase2Received (const boost::system::error_code& ecode, std::size_t bytes_transferred)
|
||||
{
|
||||
(void) bytes_transferred;
|
||||
if (ecode)
|
||||
{
|
||||
LogPrint (eLogInfo, "NTCP: Phase 2 read error: ", ecode.message (), ". Wrong ident assumed");
|
||||
@ -277,7 +281,8 @@ namespace transport
|
||||
if (paddingSize > 0)
|
||||
{
|
||||
paddingSize = 16 - paddingSize;
|
||||
// TODO: fill padding with random data
|
||||
// fill padding with random data
|
||||
RAND_bytes(buf, paddingSize);
|
||||
buf += paddingSize;
|
||||
len += paddingSize;
|
||||
}
|
||||
@ -297,6 +302,7 @@ namespace transport
|
||||
|
||||
void NTCPSession::HandlePhase3Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsA)
|
||||
{
|
||||
(void) bytes_transferred;
|
||||
if (ecode)
|
||||
{
|
||||
LogPrint (eLogInfo, "NTCP: Couldn't send Phase 3 message: ", ecode.message ());
|
||||
@ -420,6 +426,7 @@ namespace transport
|
||||
|
||||
void NTCPSession::HandlePhase4Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred)
|
||||
{
|
||||
(void) bytes_transferred;
|
||||
if (ecode)
|
||||
{
|
||||
LogPrint (eLogWarning, "NTCP: Couldn't send Phase 4 message: ", ecode.message ());
|
||||
@ -645,8 +652,11 @@ namespace transport
|
||||
}
|
||||
int rem = (len + 6) & 0x0F; // %16
|
||||
int padding = 0;
|
||||
if (rem > 0) padding = 16 - rem;
|
||||
// TODO: fill padding
|
||||
if (rem > 0) {
|
||||
padding = 16 - rem;
|
||||
// fill with random padding
|
||||
RAND_bytes(sendBuffer + len + 2, padding);
|
||||
}
|
||||
htobe32buf (sendBuffer + len + 2 + padding, adler32 (adler32 (0, Z_NULL, 0), sendBuffer, len + 2+ padding));
|
||||
|
||||
int l = len + padding + 6;
|
||||
@ -667,6 +677,7 @@ namespace transport
|
||||
|
||||
void NTCPSession::HandleSent (const boost::system::error_code& ecode, std::size_t bytes_transferred, std::vector<std::shared_ptr<I2NPMessage> > msgs)
|
||||
{
|
||||
(void) msgs;
|
||||
m_IsSending = false;
|
||||
if (ecode)
|
||||
{
|
||||
|
@ -206,7 +206,7 @@ namespace data
|
||||
}
|
||||
else
|
||||
{
|
||||
auto leaseSet = std::make_shared<LeaseSet> (buf, len);
|
||||
auto leaseSet = std::make_shared<LeaseSet> (buf, len, false); // we don't need leases in netdb
|
||||
if (leaseSet->IsValid ())
|
||||
{
|
||||
LogPrint (eLogInfo, "NetDb: LeaseSet added: ", ident.ToBase64());
|
||||
@ -316,7 +316,8 @@ namespace data
|
||||
const std::string& fullPath = it1->path();
|
||||
#endif
|
||||
auto r = std::make_shared<RouterInfo>(fullPath);
|
||||
if (!r->IsUnreachable () && (!r->UsesIntroducer () || ts < r->GetTimestamp () + 3600*1000LL)) // 1 hour
|
||||
if (r->GetRouterIdentity () && !r->IsUnreachable () &&
|
||||
(!r->UsesIntroducer () || ts < r->GetTimestamp () + 3600*1000LL)) // 1 hour
|
||||
{
|
||||
r->DeleteBuffer ();
|
||||
r->ClearProperties (); // properties are not used for regular routers
|
||||
@ -980,9 +981,10 @@ namespace data
|
||||
|
||||
void NetDb::ManageLeaseSets ()
|
||||
{
|
||||
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
|
||||
for (auto it = m_LeaseSets.begin (); it != m_LeaseSets.end ();)
|
||||
{
|
||||
if (!it->second->HasNonExpiredLeases ()) // all leases expired
|
||||
if (ts > it->second->GetExpirationTime ())
|
||||
{
|
||||
LogPrint (eLogWarning, "NetDb: LeaseSet ", it->second->GetIdentHash ().ToBase64 (), " expired");
|
||||
it = m_LeaseSets.erase (it);
|
||||
|
@ -208,6 +208,11 @@ namespace data
|
||||
uint16_t fileNameLength, extraFieldLength;
|
||||
s.read ((char *)&fileNameLength, 2);
|
||||
fileNameLength = le16toh (fileNameLength);
|
||||
if ( fileNameLength > 255 ) {
|
||||
// too big
|
||||
LogPrint(eLogError, "Reseed: SU3 fileNameLength too large: ", fileNameLength);
|
||||
return numFiles;
|
||||
}
|
||||
s.read ((char *)&extraFieldLength, 2);
|
||||
extraFieldLength = le16toh (extraFieldLength);
|
||||
char localFileName[255];
|
||||
|
13
SAM.cpp
13
SAM.cpp
@ -631,10 +631,15 @@ namespace client
|
||||
m_SocketType = eSAMSocketTypeStream;
|
||||
if (!m_IsSilent)
|
||||
{
|
||||
// send remote peer address
|
||||
uint8_t ident[1024];
|
||||
size_t l = stream->GetRemoteIdentity ()->ToBuffer (ident, 1024);
|
||||
size_t l1 = i2p::data::ByteStreamToBase64 (ident, l, (char *)m_StreamBuffer, SAM_SOCKET_BUFFER_SIZE);
|
||||
// get remote peer address
|
||||
auto ident_ptr = stream->GetRemoteIdentity();
|
||||
const size_t ident_len = ident_ptr->GetFullLen();
|
||||
uint8_t* ident = new uint8_t[ident_len];
|
||||
|
||||
// send remote peer address as base64
|
||||
const size_t l = ident_ptr->ToBuffer (ident, ident_len);
|
||||
const size_t l1 = i2p::data::ByteStreamToBase64 (ident, l, (char *)m_StreamBuffer, SAM_SOCKET_BUFFER_SIZE);
|
||||
delete[] ident;
|
||||
m_StreamBuffer[l1] = '\n';
|
||||
HandleI2PReceive (boost::system::error_code (), l1 +1); // we send identity like it has been received from stream
|
||||
}
|
||||
|
2
api.cpp
2
api.cpp
@ -31,7 +31,7 @@ namespace api
|
||||
i2p::crypto::TerminateCrypto ();
|
||||
}
|
||||
|
||||
void StartI2P (std::ostream * logStream)
|
||||
void StartI2P (std::shared_ptr<std::ostream> logStream)
|
||||
{
|
||||
if (logStream)
|
||||
StartLog (logStream);
|
||||
|
2
api.h
2
api.h
@ -14,7 +14,7 @@ namespace api
|
||||
// initialization start and stop
|
||||
void InitI2P (int argc, char* argv[], const char * appName);
|
||||
void TerminateI2P ();
|
||||
void StartI2P (std::ostream * logStream = nullptr);
|
||||
void StartI2P (std::shared_ptr<std::ostream> logStream = nullptr);
|
||||
// write system log to logStream, if not specified to <appName>.log in application's folder
|
||||
void StopI2P ();
|
||||
void RunPeerTest (); // should be called after UPnP
|
||||
|
@ -20,11 +20,15 @@ development location for the sake of convenience. Adjust paths
|
||||
accordingly if it is not the case. Note that msys uses unix-alike
|
||||
paths like /c/dev/ for C:\dev\.
|
||||
|
||||
|
||||
|
||||
msys2
|
||||
-----
|
||||
|
||||
### x86 (32-bit architecture)
|
||||
|
||||
Get install file msys2-i686-20150916.exe from https://msys2.github.io.
|
||||
open MSys2Shell (from Start menu).
|
||||
open MSYS2 Shell (from Start menu).
|
||||
Install all prerequisites and download i2pd source:
|
||||
|
||||
```bash
|
||||
@ -37,14 +41,23 @@ export PATH=/mingw32/bin:/usr/bin # we need compiler on PATH which is usually he
|
||||
make
|
||||
```
|
||||
|
||||
If your processor has
|
||||
[AES instruction set](https://en.wikipedia.org/wiki/AES_instruction_set),
|
||||
you use `make USE_AESNI=1`. No check is done however, it
|
||||
will compile, but it might crash with `Illegal instruction` if not supported.
|
||||
|
||||
You should be able to run ./i2pd . If you need to start from the new
|
||||
shell, consider starting *MinGW-w64 Win32 Shell* instead of *MSYS2 Shell* as
|
||||
it adds`/minw32/bin` to the PATH.
|
||||
### x64 (64-bit architecture)
|
||||
|
||||
Get install file msys2-x86_64-20150916.exe from https://msys2.github.io.
|
||||
open MSYS2 Shell (from Start menu).
|
||||
Install all prerequisites and download i2pd source:
|
||||
|
||||
```bash
|
||||
pacman -S mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-gcc git make
|
||||
mkdir -p /c/dev/i2pd
|
||||
cd /c/dev/i2pd
|
||||
git clone https://github.com/PurpleI2P/i2pd.git
|
||||
cd i2pd
|
||||
export PATH=/mingw64/bin:/usr/bin # we need compiler on PATH which is usually heavily cluttered on Windows
|
||||
make
|
||||
```
|
||||
|
||||
|
||||
### Caveats
|
||||
|
||||
@ -63,6 +76,19 @@ home page, otherwise you might end up with DLLs incompatibility
|
||||
problems.
|
||||
|
||||
|
||||
### AES-NI
|
||||
|
||||
If your processor has
|
||||
[AES instruction set](https://en.wikipedia.org/wiki/AES_instruction_set),
|
||||
you use `make USE_AESNI=1`. No check is done however, it
|
||||
will compile, but it might crash with `Illegal instruction` if not supported.
|
||||
|
||||
You should be able to run ./i2pd . If you need to start from the new
|
||||
shell, consider starting *MinGW-w64 Win32 Shell* instead of *MSYS2 Shell* as
|
||||
it adds`/minw32/bin` to the PATH.
|
||||
|
||||
|
||||
|
||||
Using Visual Studio
|
||||
-------------------
|
||||
|
||||
@ -77,7 +103,7 @@ Requirements for building:
|
||||
* Strawberry Perl or ActiveState Perl, do NOT try msys2 perl, it won't work
|
||||
|
||||
|
||||
## Building Boost
|
||||
### Building Boost
|
||||
|
||||
Open a Command Prompt (there is no need to start Visual Studio command
|
||||
prompt to build Boost) and run the following:
|
||||
@ -98,8 +124,8 @@ only and static linking, and/or you are out of space/time, you might
|
||||
consider `--build-type=minimal`. Take a look at
|
||||
[appveyor.yml](../appveyor.yml) for details on how test builds are done.
|
||||
|
||||
Building OpenSSL
|
||||
-----------------
|
||||
|
||||
### Building OpenSSL
|
||||
|
||||
Download OpenSSL, e.g. with git
|
||||
|
||||
@ -123,8 +149,8 @@ maintaining multiple versions, e.g. 64 bit and/or
|
||||
static/shared. Consult `C:\Program Files
|
||||
(x86)\CMake\share\cmake-3.3\Modules\FindOpenSSL.cmake` for details.
|
||||
|
||||
Get miniupnpc
|
||||
-------------
|
||||
|
||||
### Get miniupnpc
|
||||
|
||||
If you are behind a UPnP enabled router and don't feel like manually
|
||||
configuring port forwarding, you should consider using
|
||||
@ -139,8 +165,7 @@ Note that you might need to build DLL yourself for 64-bit systems
|
||||
using msys2 as 64-bit DLLs are not provided by the project.
|
||||
|
||||
|
||||
Creating Visual Studio project
|
||||
------------------------------
|
||||
### Creating Visual Studio project
|
||||
|
||||
Start CMake GUI, navigate to i2pd directory, choose building directory, e.g. ./out, and configure options.
|
||||
|
||||
@ -155,8 +180,8 @@ cmake ..\build -G "Visual Studio 12 2013" -DWITH_UPNP=ON -DWITH_PCH=ON -DCMAKE_I
|
||||
|
||||
WITH_UPNP will stay off, if necessary files are not found.
|
||||
|
||||
Building i2pd
|
||||
-------------
|
||||
|
||||
### Building i2pd
|
||||
|
||||
You can open generated solution/project with Visual Studio and build
|
||||
from there, alternatively you can use `cmake --build . --config Release --target install` or
|
||||
|
Loading…
Reference in New Issue
Block a user