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