mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-11 21:47:52 +00:00
commit
40456ebaae
10
.gitignore
vendored
10
.gitignore
vendored
@ -14,7 +14,7 @@ netDb
|
|||||||
autom4te.cache
|
autom4te.cache
|
||||||
.deps
|
.deps
|
||||||
stamp-h1
|
stamp-h1
|
||||||
Makefile
|
#Makefile
|
||||||
config.h
|
config.h
|
||||||
config.h.in~
|
config.h.in~
|
||||||
config.log
|
config.log
|
||||||
@ -238,3 +238,11 @@ pip-log.txt
|
|||||||
# Sphinx
|
# Sphinx
|
||||||
docs/_build
|
docs/_build
|
||||||
/androidIdea/
|
/androidIdea/
|
||||||
|
|
||||||
|
|
||||||
|
# emacs files
|
||||||
|
*~
|
||||||
|
*\#*
|
||||||
|
|
||||||
|
# gdb files
|
||||||
|
.gdb_history
|
@ -6,6 +6,7 @@
|
|||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
#include "Base.h"
|
#include "Base.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "Identity.h"
|
#include "Identity.h"
|
||||||
@ -15,6 +16,7 @@
|
|||||||
#include "NetDb.h"
|
#include "NetDb.h"
|
||||||
#include "ClientContext.h"
|
#include "ClientContext.h"
|
||||||
#include "AddressBook.h"
|
#include "AddressBook.h"
|
||||||
|
#include "Config.h"
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
@ -404,9 +406,21 @@ namespace client
|
|||||||
m_Subscriptions.push_back (std::make_shared<AddressBookSubscription> (*this, s));
|
m_Subscriptions.push_back (std::make_shared<AddressBookSubscription> (*this, s));
|
||||||
}
|
}
|
||||||
LogPrint (eLogInfo, "Addressbook: ", m_Subscriptions.size (), " subscriptions urls loaded");
|
LogPrint (eLogInfo, "Addressbook: ", m_Subscriptions.size (), " subscriptions urls loaded");
|
||||||
|
LogPrint (eLogWarning, "Addressbook: subscriptions.txt usage is deprecated, use config file instead");
|
||||||
}
|
}
|
||||||
else
|
else if (!i2p::config::IsDefault("addressbook.subscriptions"))
|
||||||
LogPrint (eLogWarning, "Addressbook: subscriptions.txt not found in datadir");
|
{
|
||||||
|
// using config file items
|
||||||
|
std::string subscriptionURLs; i2p::config::GetOption("addressbook.subscriptions", subscriptionURLs);
|
||||||
|
std::vector<std::string> subsList;
|
||||||
|
boost::split(subsList, subscriptionURLs, boost::is_any_of(","), boost::token_compress_on);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < subsList.size (); i++)
|
||||||
|
{
|
||||||
|
m_Subscriptions.push_back (std::make_shared<AddressBookSubscription> (*this, subsList[i]));
|
||||||
|
}
|
||||||
|
LogPrint (eLogInfo, "Addressbook: ", m_Subscriptions.size (), " subscriptions urls loaded");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "Addressbook: subscriptions already loaded");
|
LogPrint (eLogError, "Addressbook: subscriptions already loaded");
|
||||||
@ -511,10 +525,11 @@ namespace client
|
|||||||
{
|
{
|
||||||
if (!m_IsLoaded)
|
if (!m_IsLoaded)
|
||||||
{
|
{
|
||||||
// download it from http://i2p-projekt.i2p/hosts.txt
|
// download it from default subscription
|
||||||
LogPrint (eLogInfo, "Addressbook: trying to download it from default subscription.");
|
LogPrint (eLogInfo, "Addressbook: trying to download it from default subscription.");
|
||||||
|
std::string defaultSubURL; i2p::config::GetOption("addressbook.defaulturl", defaultSubURL);
|
||||||
if (!m_DefaultSubscription)
|
if (!m_DefaultSubscription)
|
||||||
m_DefaultSubscription = std::make_shared<AddressBookSubscription>(*this, DEFAULT_SUBSCRIPTION_ADDRESS);
|
m_DefaultSubscription = std::make_shared<AddressBookSubscription>(*this, defaultSubURL);
|
||||||
m_IsDownloading = true;
|
m_IsDownloading = true;
|
||||||
std::thread load_hosts(std::bind (&AddressBookSubscription::CheckUpdates, m_DefaultSubscription));
|
std::thread load_hosts(std::bind (&AddressBookSubscription::CheckUpdates, m_DefaultSubscription));
|
||||||
load_hosts.detach(); // TODO: use join
|
load_hosts.detach(); // TODO: use join
|
||||||
|
@ -18,11 +18,6 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
namespace client
|
namespace client
|
||||||
{
|
{
|
||||||
#ifdef MESHNET
|
|
||||||
const char DEFAULT_SUBSCRIPTION_ADDRESS[] = "http://i42ofzetmgicvui5sshinfckpijix2udewbam4sjo6x5fbukltia.b32.i2p/hosts.txt";
|
|
||||||
#else
|
|
||||||
const char DEFAULT_SUBSCRIPTION_ADDRESS[] = "http://joajgazyztfssty4w2on5oaqksz6tqoxbduy553y34mf4byv6gpq.b32.i2p/export/alive-hosts.txt";
|
|
||||||
#endif
|
|
||||||
const int INITIAL_SUBSCRIPTION_UPDATE_TIMEOUT = 3; // in minutes
|
const int INITIAL_SUBSCRIPTION_UPDATE_TIMEOUT = 3; // in minutes
|
||||||
const int INITIAL_SUBSCRIPTION_RETRY_TIMEOUT = 1; // in minutes
|
const int INITIAL_SUBSCRIPTION_RETRY_TIMEOUT = 1; // in minutes
|
||||||
const int CONTINIOUS_SUBSCRIPTION_UPDATE_TIMEOUT = 720; // in minutes (12 hours)
|
const int CONTINIOUS_SUBSCRIPTION_UPDATE_TIMEOUT = 720; // in minutes (12 hours)
|
||||||
|
20
BOB.cpp
20
BOB.cpp
@ -437,7 +437,10 @@ namespace client
|
|||||||
void BOBCommandSession::GetkeysCommandHandler (const char * operand, size_t len)
|
void BOBCommandSession::GetkeysCommandHandler (const char * operand, size_t len)
|
||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "BOB: getkeys");
|
LogPrint (eLogDebug, "BOB: getkeys");
|
||||||
SendReplyOK (m_Keys.ToBase64 ().c_str ());
|
if (m_Keys.GetPublic ()) // keys are set ?
|
||||||
|
SendReplyOK (m_Keys.ToBase64 ().c_str ());
|
||||||
|
else
|
||||||
|
SendReplyError ("keys are not set");
|
||||||
}
|
}
|
||||||
|
|
||||||
void BOBCommandSession::GetdestCommandHandler (const char * operand, size_t len)
|
void BOBCommandSession::GetdestCommandHandler (const char * operand, size_t len)
|
||||||
@ -501,12 +504,12 @@ namespace client
|
|||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "BOB: lookup ", operand);
|
LogPrint (eLogDebug, "BOB: lookup ", operand);
|
||||||
i2p::data::IdentHash ident;
|
i2p::data::IdentHash ident;
|
||||||
if (!context.GetAddressBook ().GetIdentHash (operand, ident) || !m_CurrentDestination)
|
if (!context.GetAddressBook ().GetIdentHash (operand, ident))
|
||||||
{
|
{
|
||||||
SendReplyError ("Address Not found");
|
SendReplyError ("Address Not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto localDestination = m_CurrentDestination->GetLocalDestination ();
|
auto localDestination = m_CurrentDestination ? m_CurrentDestination->GetLocalDestination () : i2p::client::context.GetSharedLocalDestination ();
|
||||||
auto leaseSet = localDestination->FindLeaseSet (ident);
|
auto leaseSet = localDestination->FindLeaseSet (ident);
|
||||||
if (leaseSet)
|
if (leaseSet)
|
||||||
SendReplyOK (leaseSet->GetIdentity ()->ToBase64 ().c_str ());
|
SendReplyOK (leaseSet->GetIdentity ()->ToBase64 ().c_str ());
|
||||||
@ -568,10 +571,15 @@ namespace client
|
|||||||
{
|
{
|
||||||
std::stringstream s;
|
std::stringstream s;
|
||||||
s << "DATA"; s << " NICKNAME: "; s << m_Nickname;
|
s << "DATA"; s << " NICKNAME: "; s << m_Nickname;
|
||||||
if (m_CurrentDestination->GetLocalDestination ()->IsReady ())
|
if (m_CurrentDestination)
|
||||||
s << " STARTING: false RUNNING: true STOPPING: false";
|
{
|
||||||
|
if (m_CurrentDestination->GetLocalDestination ()->IsReady ())
|
||||||
|
s << " STARTING: false RUNNING: true STOPPING: false";
|
||||||
|
else
|
||||||
|
s << " STARTING: true RUNNING: false STOPPING: false";
|
||||||
|
}
|
||||||
else
|
else
|
||||||
s << " STARTING: true RUNNING: false STOPPING: false";
|
s << " STARTING: false RUNNING: false STOPPING: false";
|
||||||
s << " KEYS: true"; s << " QUIET: "; s << (m_IsQuiet ? "true":"false");
|
s << " KEYS: true"; s << " QUIET: "; s << (m_IsQuiet ? "true":"false");
|
||||||
if (m_InPort)
|
if (m_InPort)
|
||||||
{
|
{
|
||||||
|
15
Config.cpp
15
Config.cpp
@ -49,6 +49,7 @@ namespace config {
|
|||||||
("port", value<uint16_t>()->default_value(0), "Port to listen for incoming connections (default: auto)")
|
("port", value<uint16_t>()->default_value(0), "Port to listen for incoming connections (default: auto)")
|
||||||
("ipv4", value<bool>()->zero_tokens()->default_value(true), "Enable communication through ipv4")
|
("ipv4", value<bool>()->zero_tokens()->default_value(true), "Enable communication through ipv4")
|
||||||
("ipv6", value<bool>()->zero_tokens()->default_value(false), "Enable communication through ipv6")
|
("ipv6", value<bool>()->zero_tokens()->default_value(false), "Enable communication through ipv6")
|
||||||
|
("netid", value<int>()->default_value(I2PD_NET_ID), "Specify NetID. Main I2P is 2")
|
||||||
("daemon", value<bool>()->zero_tokens()->default_value(false), "Router will go to background after start")
|
("daemon", value<bool>()->zero_tokens()->default_value(false), "Router will go to background after start")
|
||||||
("service", value<bool>()->zero_tokens()->default_value(false), "Router will use system folders like '/var/lib/i2pd'")
|
("service", value<bool>()->zero_tokens()->default_value(false), "Router will use system folders like '/var/lib/i2pd'")
|
||||||
("notransit", value<bool>()->zero_tokens()->default_value(false), "Router will not accept transit tunnels at startup")
|
("notransit", value<bool>()->zero_tokens()->default_value(false), "Router will not accept transit tunnels at startup")
|
||||||
@ -150,6 +151,7 @@ namespace config {
|
|||||||
|
|
||||||
options_description reseed("Reseed options");
|
options_description reseed("Reseed options");
|
||||||
reseed.add_options()
|
reseed.add_options()
|
||||||
|
("reseed.verify", value<bool>()->default_value(false), "Verify .su3 signature")
|
||||||
("reseed.file", value<std::string>()->default_value(""), "Path to .su3 file")
|
("reseed.file", value<std::string>()->default_value(""), "Path to .su3 file")
|
||||||
#ifdef MESHNET
|
#ifdef MESHNET
|
||||||
("reseed.urls", value<std::string>()->default_value("https://reseed.i2p.rocks:8443/"), "Reseed URLs, separated by comma")
|
("reseed.urls", value<std::string>()->default_value("https://reseed.i2p.rocks:8443/"), "Reseed URLs, separated by comma")
|
||||||
@ -163,13 +165,21 @@ namespace config {
|
|||||||
"https://i2p.manas.ca:8443/,"
|
"https://i2p.manas.ca:8443/,"
|
||||||
"https://i2p-0.manas.ca:8443/,"
|
"https://i2p-0.manas.ca:8443/,"
|
||||||
"https://reseed.i2p.vzaws.com:8443/,"
|
"https://reseed.i2p.vzaws.com:8443/,"
|
||||||
"https://user.mx24.eu/,"
|
|
||||||
"https://download.xxlspeed.com/,"
|
"https://download.xxlspeed.com/,"
|
||||||
"https://reseed-ru.lngserv.ru/"
|
"https://reseed-ru.lngserv.ru/,"
|
||||||
|
"https://reseed.atomike.ninja/"
|
||||||
), "Reseed URLs, separated by comma")
|
), "Reseed URLs, separated by comma")
|
||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
|
|
||||||
|
options_description addressbook("AddressBook options");
|
||||||
|
addressbook.add_options()
|
||||||
|
("addressbook.defaulturl", value<std::string>()->default_value(
|
||||||
|
"http://joajgazyztfssty4w2on5oaqksz6tqoxbduy553y34mf4byv6gpq.b32.i2p/export/alive-hosts.txt"
|
||||||
|
), "AddressBook subscription URL for initial setup")
|
||||||
|
("addressbook.subscriptions", value<std::string>()->default_value(""),
|
||||||
|
"AddressBook subscriptions URLs, separated by comma");
|
||||||
|
|
||||||
options_description trust("Trust options");
|
options_description trust("Trust options");
|
||||||
trust.add_options()
|
trust.add_options()
|
||||||
("trust.enabled", value<bool>()->default_value(false), "enable explicit trust options")
|
("trust.enabled", value<bool>()->default_value(false), "enable explicit trust options")
|
||||||
@ -189,6 +199,7 @@ namespace config {
|
|||||||
.add(upnp)
|
.add(upnp)
|
||||||
.add(precomputation)
|
.add(precomputation)
|
||||||
.add(reseed)
|
.add(reseed)
|
||||||
|
.add(addressbook)
|
||||||
.add(trust)
|
.add(trust)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
29
Datagram.cpp
29
Datagram.cpp
@ -12,8 +12,10 @@ namespace i2p
|
|||||||
namespace datagram
|
namespace datagram
|
||||||
{
|
{
|
||||||
DatagramDestination::DatagramDestination (std::shared_ptr<i2p::client::ClientDestination> owner):
|
DatagramDestination::DatagramDestination (std::shared_ptr<i2p::client::ClientDestination> owner):
|
||||||
m_Owner (owner.get()), m_Receiver (nullptr)
|
m_Owner (owner.get()),
|
||||||
|
m_Receiver (nullptr)
|
||||||
{
|
{
|
||||||
|
m_Identity.FromBase64 (owner->GetIdentity()->ToBase64());
|
||||||
}
|
}
|
||||||
|
|
||||||
DatagramDestination::~DatagramDestination ()
|
DatagramDestination::~DatagramDestination ()
|
||||||
@ -24,16 +26,16 @@ namespace datagram
|
|||||||
void DatagramDestination::SendDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash& ident, uint16_t fromPort, uint16_t toPort)
|
void DatagramDestination::SendDatagramTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash& ident, uint16_t fromPort, uint16_t toPort)
|
||||||
{
|
{
|
||||||
auto owner = m_Owner;
|
auto owner = m_Owner;
|
||||||
auto i = owner->GetIdentity();
|
std::vector<uint8_t> v(MAX_DATAGRAM_SIZE);
|
||||||
uint8_t buf[MAX_DATAGRAM_SIZE];
|
uint8_t * buf = v.data();
|
||||||
auto identityLen = i->ToBuffer (buf, MAX_DATAGRAM_SIZE);
|
auto identityLen = m_Identity.ToBuffer (buf, MAX_DATAGRAM_SIZE);
|
||||||
uint8_t * signature = buf + identityLen;
|
uint8_t * signature = buf + identityLen;
|
||||||
auto signatureLen = i->GetSignatureLen ();
|
auto signatureLen = m_Identity.GetSignatureLen ();
|
||||||
uint8_t * buf1 = signature + signatureLen;
|
uint8_t * buf1 = signature + signatureLen;
|
||||||
size_t headerLen = identityLen + signatureLen;
|
size_t headerLen = identityLen + signatureLen;
|
||||||
|
|
||||||
memcpy (buf1, payload, len);
|
memcpy (buf1, payload, len);
|
||||||
if (i->GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1)
|
if (m_Identity.GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1)
|
||||||
{
|
{
|
||||||
uint8_t hash[32];
|
uint8_t hash[32];
|
||||||
SHA256(buf1, len, hash);
|
SHA256(buf1, len, hash);
|
||||||
@ -48,7 +50,7 @@ namespace datagram
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DatagramDestination::HandleDatagram (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len)
|
void DatagramDestination::HandleDatagram (uint16_t fromPort, uint16_t toPort,uint8_t * const &buf, size_t len)
|
||||||
{
|
{
|
||||||
i2p::data::IdentityEx identity;
|
i2p::data::IdentityEx identity;
|
||||||
size_t identityLen = identity.FromBuffer (buf, len);
|
size_t identityLen = identity.FromBuffer (buf, len);
|
||||||
@ -121,7 +123,7 @@ namespace datagram
|
|||||||
if (m_Sessions.empty ()) return;
|
if (m_Sessions.empty ()) return;
|
||||||
auto now = i2p::util::GetMillisecondsSinceEpoch();
|
auto now = i2p::util::GetMillisecondsSinceEpoch();
|
||||||
LogPrint(eLogDebug, "DatagramDestination: clean up sessions");
|
LogPrint(eLogDebug, "DatagramDestination: clean up sessions");
|
||||||
std::lock_guard<std::mutex> lock(m_SessionsMutex);
|
std::unique_lock<std::mutex> lock(m_SessionsMutex);
|
||||||
// for each session ...
|
// for each session ...
|
||||||
for (auto it = m_Sessions.begin (); it != m_Sessions.end (); )
|
for (auto it = m_Sessions.begin (); it != m_Sessions.end (); )
|
||||||
{
|
{
|
||||||
@ -270,13 +272,16 @@ namespace datagram
|
|||||||
|
|
||||||
bool DatagramSession::ShouldUpdateRoutingPath() const
|
bool DatagramSession::ShouldUpdateRoutingPath() const
|
||||||
{
|
{
|
||||||
|
bool dead = m_RoutingSession == nullptr || m_RoutingSession->GetSharedRoutingPath () == nullptr;
|
||||||
auto now = i2p::util::GetMillisecondsSinceEpoch ();
|
auto now = i2p::util::GetMillisecondsSinceEpoch ();
|
||||||
// we need to rotate paths becuase the routing path is too old
|
// we need to rotate paths becuase the routing path is too old
|
||||||
if (now - m_LastPathChange >= DATAGRAM_SESSION_PATH_SWITCH_INTERVAL) return true;
|
// if (now - m_LastPathChange >= DATAGRAM_SESSION_PATH_SWITCH_INTERVAL) return true;
|
||||||
|
// too fast switching paths
|
||||||
|
if (now - m_LastPathChange < DATAGRAM_SESSION_PATH_MIN_LIFETIME ) return false;
|
||||||
// our path looks dead so we need to rotate paths
|
// our path looks dead so we need to rotate paths
|
||||||
if (now - m_LastSuccess >= DATAGRAM_SESSION_PATH_TIMEOUT) return true;
|
if (now - m_LastSuccess >= DATAGRAM_SESSION_PATH_TIMEOUT) return !dead;
|
||||||
// if we have a routing session and routing path we don't need to switch paths
|
// if we have a routing session and routing path we don't need to switch paths
|
||||||
return m_RoutingSession != nullptr && m_RoutingSession->GetSharedRoutingPath () != nullptr;
|
return dead;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -291,7 +296,7 @@ namespace datagram
|
|||||||
if(currentLease) // if we have a lease return true if it's about to expire otherwise return false
|
if(currentLease) // if we have a lease return true if it's about to expire otherwise return false
|
||||||
return currentLease->ExpiresWithin( DATAGRAM_SESSION_LEASE_HANDOVER_WINDOW, DATAGRAM_SESSION_LEASE_HANDOVER_FUDGE );
|
return currentLease->ExpiresWithin( DATAGRAM_SESSION_LEASE_HANDOVER_WINDOW, DATAGRAM_SESSION_LEASE_HANDOVER_FUDGE );
|
||||||
// we have no current lease, we should switch
|
// we have no current lease, we should switch
|
||||||
return true;
|
return currentLease == nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<i2p::garlic::GarlicRoutingPath> DatagramSession::GetNextRoutingPath()
|
std::shared_ptr<i2p::garlic::GarlicRoutingPath> DatagramSession::GetNextRoutingPath()
|
||||||
|
10
Datagram.h
10
Datagram.h
@ -22,14 +22,15 @@ namespace datagram
|
|||||||
// milliseconds for max session idle time
|
// milliseconds for max session idle time
|
||||||
const uint64_t DATAGRAM_SESSION_MAX_IDLE = 10 * 60 * 1000;
|
const uint64_t DATAGRAM_SESSION_MAX_IDLE = 10 * 60 * 1000;
|
||||||
// milliseconds for how long we try sticking to a dead routing path before trying to switch
|
// milliseconds for how long we try sticking to a dead routing path before trying to switch
|
||||||
const uint64_t DATAGRAM_SESSION_PATH_TIMEOUT = 5000;
|
const uint64_t DATAGRAM_SESSION_PATH_TIMEOUT = 10 * 1000;
|
||||||
// milliseconds interval a routing path is used before switching
|
// milliseconds interval a routing path is used before switching
|
||||||
const uint64_t DATAGRAM_SESSION_PATH_SWITCH_INTERVAL = 60 * 1000;
|
const uint64_t DATAGRAM_SESSION_PATH_SWITCH_INTERVAL = 20 * 60 * 1000;
|
||||||
// milliseconds before lease expire should we try switching leases
|
// milliseconds before lease expire should we try switching leases
|
||||||
const uint64_t DATAGRAM_SESSION_LEASE_HANDOVER_WINDOW = 10 * 1000;
|
const uint64_t DATAGRAM_SESSION_LEASE_HANDOVER_WINDOW = 10 * 1000;
|
||||||
// milliseconds fudge factor for leases handover
|
// milliseconds fudge factor for leases handover
|
||||||
const uint64_t DATAGRAM_SESSION_LEASE_HANDOVER_FUDGE = 1000;
|
const uint64_t DATAGRAM_SESSION_LEASE_HANDOVER_FUDGE = 1000;
|
||||||
|
// milliseconds minimum time between path switches
|
||||||
|
const uint64_t DATAGRAM_SESSION_PATH_MIN_LIFETIME = 5 * 1000;
|
||||||
|
|
||||||
class DatagramSession
|
class DatagramSession
|
||||||
{
|
{
|
||||||
@ -133,13 +134,14 @@ namespace datagram
|
|||||||
|
|
||||||
std::shared_ptr<I2NPMessage> CreateDataMessage (const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort);
|
std::shared_ptr<I2NPMessage> CreateDataMessage (const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort);
|
||||||
|
|
||||||
void HandleDatagram (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
|
void HandleDatagram (uint16_t fromPort, uint16_t toPort, uint8_t *const& buf, size_t len);
|
||||||
|
|
||||||
/** find a receiver by port, if none by port is found try default receiever, otherwise returns nullptr */
|
/** find a receiver by port, if none by port is found try default receiever, otherwise returns nullptr */
|
||||||
Receiver FindReceiver(uint16_t port);
|
Receiver FindReceiver(uint16_t port);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
i2p::client::ClientDestination * m_Owner;
|
i2p::client::ClientDestination * m_Owner;
|
||||||
|
i2p::data::IdentityEx m_Identity;
|
||||||
Receiver m_Receiver; // default
|
Receiver m_Receiver; // default
|
||||||
std::mutex m_SessionsMutex;
|
std::mutex m_SessionsMutex;
|
||||||
std::map<i2p::data::IdentHash, std::shared_ptr<DatagramSession> > m_Sessions;
|
std::map<i2p::data::IdentHash, std::shared_ptr<DatagramSession> > m_Sessions;
|
||||||
|
@ -171,28 +171,35 @@ namespace client
|
|||||||
|
|
||||||
std::shared_ptr<const i2p::data::LeaseSet> LeaseSetDestination::FindLeaseSet (const i2p::data::IdentHash& ident)
|
std::shared_ptr<const i2p::data::LeaseSet> LeaseSetDestination::FindLeaseSet (const i2p::data::IdentHash& ident)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(m_RemoteLeaseSetsMutex);
|
std::shared_ptr<i2p::data::LeaseSet> remoteLS;
|
||||||
auto it = m_RemoteLeaseSets.find (ident);
|
|
||||||
if (it != m_RemoteLeaseSets.end ())
|
|
||||||
{
|
{
|
||||||
if (!it->second->IsExpired ())
|
std::lock_guard<std::mutex> lock(m_RemoteLeaseSetsMutex);
|
||||||
|
auto it = m_RemoteLeaseSets.find (ident);
|
||||||
|
if (it != m_RemoteLeaseSets.end ())
|
||||||
|
remoteLS = it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remoteLS)
|
||||||
|
{
|
||||||
|
if (!remoteLS->IsExpired ())
|
||||||
{
|
{
|
||||||
if (it->second->ExpiresSoon())
|
if (remoteLS->ExpiresSoon())
|
||||||
{
|
{
|
||||||
LogPrint(eLogDebug, "Destination: Lease Set expires soon, updating before expire");
|
LogPrint(eLogDebug, "Destination: Lease Set expires soon, updating before expire");
|
||||||
// update now before expiration for smooth handover
|
// update now before expiration for smooth handover
|
||||||
RequestDestination(ident, [this, ident] (std::shared_ptr<i2p::data::LeaseSet> ls) {
|
auto s = shared_from_this ();
|
||||||
|
RequestDestination(ident, [s, ident] (std::shared_ptr<i2p::data::LeaseSet> ls) {
|
||||||
if(ls && !ls->IsExpired())
|
if(ls && !ls->IsExpired())
|
||||||
{
|
{
|
||||||
ls->PopulateLeases();
|
ls->PopulateLeases();
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> _lock(m_RemoteLeaseSetsMutex);
|
std::lock_guard<std::mutex> _lock(s->m_RemoteLeaseSetsMutex);
|
||||||
m_RemoteLeaseSets[ident] = ls;
|
s->m_RemoteLeaseSets[ident] = ls;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return it->second;
|
return remoteLS;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogWarning, "Destination: remote LeaseSet expired");
|
LogPrint (eLogWarning, "Destination: remote LeaseSet expired");
|
||||||
@ -203,10 +210,8 @@ namespace client
|
|||||||
if (ls && !ls->IsExpired ())
|
if (ls && !ls->IsExpired ())
|
||||||
{
|
{
|
||||||
ls->PopulateLeases (); // since we don't store them in netdb
|
ls->PopulateLeases (); // since we don't store them in netdb
|
||||||
{
|
std::lock_guard<std::mutex> _lock(m_RemoteLeaseSetsMutex);
|
||||||
std::lock_guard<std::mutex> lock(m_RemoteLeaseSetsMutex);
|
m_RemoteLeaseSets[ident] = ls;
|
||||||
m_RemoteLeaseSets[ident] = ls;
|
|
||||||
}
|
|
||||||
return ls;
|
return ls;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
11
I2CP.cpp
11
I2CP.cpp
@ -66,12 +66,19 @@ namespace client
|
|||||||
memcpy (buf + 4, payload, len);
|
memcpy (buf + 4, payload, len);
|
||||||
msg->len += len + 4;
|
msg->len += len + 4;
|
||||||
msg->FillI2NPMessageHeader (eI2NPData);
|
msg->FillI2NPMessageHeader (eI2NPData);
|
||||||
|
auto s = GetSharedFromThis ();
|
||||||
auto remote = FindLeaseSet (ident);
|
auto remote = FindLeaseSet (ident);
|
||||||
if (remote)
|
if (remote)
|
||||||
GetService ().post (std::bind (&I2CPDestination::SendMsg, GetSharedFromThis (), msg, remote));
|
{
|
||||||
|
GetService ().post (
|
||||||
|
[s, msg, remote, nonce]()
|
||||||
|
{
|
||||||
|
bool sent = s->SendMsg (msg, remote);
|
||||||
|
s->m_Owner->SendMessageStatusMessage (nonce, sent ? eI2CPMessageStatusGuaranteedSuccess : eI2CPMessageStatusGuaranteedFailure);
|
||||||
|
});
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto s = GetSharedFromThis ();
|
|
||||||
RequestDestination (ident,
|
RequestDestination (ident,
|
||||||
[s, msg, nonce](std::shared_ptr<i2p::data::LeaseSet> ls)
|
[s, msg, nonce](std::shared_ptr<i2p::data::LeaseSet> ls)
|
||||||
{
|
{
|
||||||
|
@ -102,7 +102,7 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
RAND_bytes ((uint8_t *)&msgID, 4);
|
RAND_bytes ((uint8_t *)&msgID, 4);
|
||||||
htobe32buf (buf + DELIVERY_STATUS_MSGID_OFFSET, msgID);
|
htobe32buf (buf + DELIVERY_STATUS_MSGID_OFFSET, msgID);
|
||||||
htobe64buf (buf + DELIVERY_STATUS_TIMESTAMP_OFFSET, I2PD_NET_ID);
|
htobe64buf (buf + DELIVERY_STATUS_TIMESTAMP_OFFSET, i2p::context.GetNetID ());
|
||||||
}
|
}
|
||||||
m->len += DELIVERY_STATUS_SIZE;
|
m->len += DELIVERY_STATUS_SIZE;
|
||||||
m->FillI2NPMessageHeader (eI2NPDeliveryStatus);
|
m->FillI2NPMessageHeader (eI2NPDeliveryStatus);
|
||||||
|
@ -559,23 +559,23 @@ namespace client
|
|||||||
}
|
}
|
||||||
/** create new udp session */
|
/** create new udp session */
|
||||||
boost::asio::ip::udp::endpoint ep(m_LocalAddress, 0);
|
boost::asio::ip::udp::endpoint ep(m_LocalAddress, 0);
|
||||||
m_Sessions.push_back(new UDPSession(ep, m_LocalDest, m_RemoteEndpoint, ih, localPort, remotePort));
|
m_Sessions.push_back(new UDPSession(ep, m_LocalDest, m_RemoteEndpoint, &ih, localPort, remotePort));
|
||||||
return m_Sessions.back();
|
return m_Sessions.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
UDPSession::UDPSession(boost::asio::ip::udp::endpoint localEndpoint,
|
UDPSession::UDPSession(boost::asio::ip::udp::endpoint localEndpoint,
|
||||||
const std::shared_ptr<i2p::client::ClientDestination> & localDestination,
|
const std::shared_ptr<i2p::client::ClientDestination> & localDestination,
|
||||||
boost::asio::ip::udp::endpoint endpoint, const i2p::data::IdentHash to,
|
boost::asio::ip::udp::endpoint endpoint, const i2p::data::IdentHash * to,
|
||||||
uint16_t ourPort, uint16_t theirPort) :
|
uint16_t ourPort, uint16_t theirPort) :
|
||||||
m_Destination(localDestination->GetDatagramDestination()),
|
m_Destination(localDestination->GetDatagramDestination()),
|
||||||
m_Service(localDestination->GetService()),
|
m_Service(localDestination->GetService()),
|
||||||
IPSocket(localDestination->GetService(), localEndpoint),
|
IPSocket(localDestination->GetService(), localEndpoint),
|
||||||
Identity(to),
|
|
||||||
SendEndpoint(endpoint),
|
SendEndpoint(endpoint),
|
||||||
LastActivity(i2p::util::GetMillisecondsSinceEpoch()),
|
LastActivity(i2p::util::GetMillisecondsSinceEpoch()),
|
||||||
LocalPort(ourPort),
|
LocalPort(ourPort),
|
||||||
RemotePort(theirPort)
|
RemotePort(theirPort)
|
||||||
{
|
{
|
||||||
|
memcpy(Identity, to->data(), 32);
|
||||||
Receive();
|
Receive();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -592,13 +592,7 @@ namespace client
|
|||||||
{
|
{
|
||||||
LogPrint(eLogDebug, "UDPSession: forward ", len, "B from ", FromEndpoint);
|
LogPrint(eLogDebug, "UDPSession: forward ", len, "B from ", FromEndpoint);
|
||||||
LastActivity = i2p::util::GetMillisecondsSinceEpoch();
|
LastActivity = i2p::util::GetMillisecondsSinceEpoch();
|
||||||
uint8_t * data = new uint8_t[len];
|
m_Destination->SendDatagramTo(m_Buffer, len, Identity, 0, 0);
|
||||||
memcpy(data, m_Buffer, len);
|
|
||||||
m_Service.post([&,len, data] () {
|
|
||||||
m_Destination->SendDatagramTo(data, len, Identity, 0, 0);
|
|
||||||
delete [] data;
|
|
||||||
});
|
|
||||||
|
|
||||||
Receive();
|
Receive();
|
||||||
} else {
|
} else {
|
||||||
LogPrint(eLogError, "UDPSession: ", ecode.message());
|
LogPrint(eLogError, "UDPSession: ", ecode.message());
|
||||||
@ -727,7 +721,7 @@ namespace client
|
|||||||
if(m_Session) delete m_Session;
|
if(m_Session) delete m_Session;
|
||||||
|
|
||||||
boost::asio::ip::udp::endpoint ep(boost::asio::ip::address::from_string("127.0.0.1"), 0);
|
boost::asio::ip::udp::endpoint ep(boost::asio::ip::address::from_string("127.0.0.1"), 0);
|
||||||
m_Session = new UDPSession(m_LocalEndpoint, m_LocalDest, ep, *m_RemoteIdent, LocalPort, RemotePort);
|
m_Session = new UDPSession(m_LocalEndpoint, m_LocalDest, ep, m_RemoteIdent, LocalPort, RemotePort);
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2PUDPClientTunnel::HandleRecvFromI2P(const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len)
|
void I2PUDPClientTunnel::HandleRecvFromI2P(const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len)
|
||||||
|
@ -155,7 +155,7 @@ namespace client
|
|||||||
|
|
||||||
UDPSession(boost::asio::ip::udp::endpoint localEndpoint,
|
UDPSession(boost::asio::ip::udp::endpoint localEndpoint,
|
||||||
const std::shared_ptr<i2p::client::ClientDestination> & localDestination,
|
const std::shared_ptr<i2p::client::ClientDestination> & localDestination,
|
||||||
boost::asio::ip::udp::endpoint remote, const i2p::data::IdentHash ident,
|
boost::asio::ip::udp::endpoint remote, const i2p::data::IdentHash * ident,
|
||||||
uint16_t ourPort, uint16_t theirPort);
|
uint16_t ourPort, uint16_t theirPort);
|
||||||
void HandleReceived(const boost::system::error_code & ecode, std::size_t len);
|
void HandleReceived(const boost::system::error_code & ecode, std::size_t len);
|
||||||
void Receive();
|
void Receive();
|
||||||
|
31
Identity.cpp
31
Identity.cpp
@ -35,11 +35,12 @@ namespace data
|
|||||||
}
|
}
|
||||||
|
|
||||||
IdentityEx::IdentityEx ():
|
IdentityEx::IdentityEx ():
|
||||||
m_ExtendedLen (0), m_ExtendedBuffer (nullptr)
|
m_IsVerifierCreated (false), m_ExtendedLen (0), m_ExtendedBuffer (nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
IdentityEx::IdentityEx(const uint8_t * publicKey, const uint8_t * signingKey, SigningKeyType type)
|
IdentityEx::IdentityEx(const uint8_t * publicKey, const uint8_t * signingKey, SigningKeyType type):
|
||||||
|
m_IsVerifierCreated (false)
|
||||||
{
|
{
|
||||||
memcpy (m_StandardIdentity.publicKey, publicKey, sizeof (m_StandardIdentity.publicKey));
|
memcpy (m_StandardIdentity.publicKey, publicKey, sizeof (m_StandardIdentity.publicKey));
|
||||||
if (type != SIGNING_KEY_TYPE_DSA_SHA1)
|
if (type != SIGNING_KEY_TYPE_DSA_SHA1)
|
||||||
@ -135,19 +136,19 @@ namespace data
|
|||||||
}
|
}
|
||||||
|
|
||||||
IdentityEx::IdentityEx (const uint8_t * buf, size_t len):
|
IdentityEx::IdentityEx (const uint8_t * buf, size_t len):
|
||||||
m_ExtendedLen (0), m_ExtendedBuffer (nullptr)
|
m_IsVerifierCreated (false), m_ExtendedLen (0), m_ExtendedBuffer (nullptr)
|
||||||
{
|
{
|
||||||
FromBuffer (buf, len);
|
FromBuffer (buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
IdentityEx::IdentityEx (const IdentityEx& other):
|
IdentityEx::IdentityEx (const IdentityEx& other):
|
||||||
m_ExtendedLen (0), m_ExtendedBuffer (nullptr)
|
m_IsVerifierCreated (false), m_ExtendedLen (0), m_ExtendedBuffer (nullptr)
|
||||||
{
|
{
|
||||||
*this = other;
|
*this = other;
|
||||||
}
|
}
|
||||||
|
|
||||||
IdentityEx::IdentityEx (const Identity& standard):
|
IdentityEx::IdentityEx (const Identity& standard):
|
||||||
m_ExtendedLen (0), m_ExtendedBuffer (nullptr)
|
m_IsVerifierCreated (false), m_ExtendedLen (0), m_ExtendedBuffer (nullptr)
|
||||||
{
|
{
|
||||||
*this = standard;
|
*this = standard;
|
||||||
}
|
}
|
||||||
@ -173,6 +174,7 @@ namespace data
|
|||||||
m_ExtendedBuffer = nullptr;
|
m_ExtendedBuffer = nullptr;
|
||||||
|
|
||||||
m_Verifier = nullptr;
|
m_Verifier = nullptr;
|
||||||
|
m_IsVerifierCreated = false;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -187,6 +189,7 @@ namespace data
|
|||||||
m_ExtendedLen = 0;
|
m_ExtendedLen = 0;
|
||||||
|
|
||||||
m_Verifier = nullptr;
|
m_Verifier = nullptr;
|
||||||
|
m_IsVerifierCreated = false;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -373,8 +376,17 @@ namespace data
|
|||||||
|
|
||||||
void IdentityEx::UpdateVerifier (i2p::crypto::Verifier * verifier) const
|
void IdentityEx::UpdateVerifier (i2p::crypto::Verifier * verifier) const
|
||||||
{
|
{
|
||||||
if (!m_Verifier || !verifier)
|
if (!m_Verifier)
|
||||||
m_Verifier.reset (verifier);
|
{
|
||||||
|
auto created = m_IsVerifierCreated.exchange (true);
|
||||||
|
if (!created)
|
||||||
|
m_Verifier.reset (verifier);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delete verifier;
|
||||||
|
while (!m_Verifier) ; // spin lock
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
delete verifier;
|
delete verifier;
|
||||||
}
|
}
|
||||||
@ -382,6 +394,7 @@ namespace data
|
|||||||
void IdentityEx::DropVerifier () const
|
void IdentityEx::DropVerifier () const
|
||||||
{
|
{
|
||||||
// TODO: potential race condition with Verify
|
// TODO: potential race condition with Verify
|
||||||
|
m_IsVerifierCreated = false;
|
||||||
m_Verifier = nullptr;
|
m_Verifier = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -457,8 +470,8 @@ namespace data
|
|||||||
void PrivateKeys::Sign (const uint8_t * buf, int len, uint8_t * signature) const
|
void PrivateKeys::Sign (const uint8_t * buf, int len, uint8_t * signature) const
|
||||||
{
|
{
|
||||||
if (!m_Signer)
|
if (!m_Signer)
|
||||||
CreateSigner();
|
CreateSigner();
|
||||||
m_Signer->Sign (buf, len, signature);
|
m_Signer->Sign (buf, len, signature);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrivateKeys::CreateSigner () const
|
void PrivateKeys::CreateSigner () const
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <atomic>
|
||||||
#include "Base.h"
|
#include "Base.h"
|
||||||
#include "Signature.h"
|
#include "Signature.h"
|
||||||
|
|
||||||
@ -104,6 +105,7 @@ namespace data
|
|||||||
Identity m_StandardIdentity;
|
Identity m_StandardIdentity;
|
||||||
IdentHash m_IdentHash;
|
IdentHash m_IdentHash;
|
||||||
mutable std::unique_ptr<i2p::crypto::Verifier> m_Verifier;
|
mutable std::unique_ptr<i2p::crypto::Verifier> m_Verifier;
|
||||||
|
mutable std::atomic_bool m_IsVerifierCreated; // make sure we don't create twice
|
||||||
size_t m_ExtendedLen;
|
size_t m_ExtendedLen;
|
||||||
uint8_t * m_ExtendedBuffer;
|
uint8_t * m_ExtendedBuffer;
|
||||||
};
|
};
|
||||||
|
@ -37,11 +37,17 @@ ifeq ($(USE_WIN32_APP), yes)
|
|||||||
DAEMON_OBJS += $(patsubst %.rc,obj/%.o,$(DAEMON_RC))
|
DAEMON_OBJS += $(patsubst %.rc,obj/%.o,$(DAEMON_RC))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# don't change following line to ifeq ($(USE_AESNI),yes) !!!
|
||||||
ifeq ($(USE_AESNI),1)
|
ifeq ($(USE_AESNI),1)
|
||||||
CPU_FLAGS = -maes -DAESNI
|
CPU_FLAGS = -maes -DAESNI
|
||||||
else
|
else
|
||||||
CPU_FLAGS = -msse
|
CPU_FLAGS = -msse
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(USE_ASLR),yes)
|
||||||
|
LDFLAGS += -Wl,--nxcompat -Wl,--high-entropy-va \
|
||||||
|
-Wl,--dynamicbase,--export-all-symbols
|
||||||
|
endif
|
||||||
|
|
||||||
obj/%.o : %.rc
|
obj/%.o : %.rc
|
||||||
$(WINDRES) -i $< -o $@
|
$(WINDRES) -i $< -o $@
|
||||||
|
19
README.md
19
README.md
@ -1,21 +1,26 @@
|
|||||||
i2pd
|
i2pd
|
||||||
====
|
====
|
||||||
|
|
||||||
i2pd is a full-featured C++ implementation of
|
i2pd (I2P Daemon) is a full-featured C++ implementation of I2P client.
|
||||||
[I2P](https://geti2p.net/en/about/intro) client.
|
|
||||||
|
|
||||||
I2P (Invisible Internet Project) is anonymous network which works on top of
|
I2P (Invisible Internet Protocol) is a universal anonymous network layer.
|
||||||
public Internet. Privacy and anonymity are achieved by strong encryption and
|
All communications over I2P are anonymous and end-to-end encrypted, participants
|
||||||
bouncing your traffic through thousands of I2P nodes all around the world.
|
don't reveal their real IP addresses.
|
||||||
|
|
||||||
We are building network which helps people to communicate and share information
|
I2P client is a software used for building and using anonymous I2P
|
||||||
|
networks. Such networks are commonly used for anonymous peer-to-peer
|
||||||
|
applications (filesharing, cryptocurrencies) and anonymous client-server
|
||||||
|
applications (websites, instant messengers, chat-servers).
|
||||||
|
|
||||||
|
I2P allows people from all around the world to communicate and share information
|
||||||
without restrictions.
|
without restrictions.
|
||||||
|
|
||||||
* [Website](http://i2pd.website)
|
* [Website](http://i2pd.website)
|
||||||
* [Documentation](https://i2pd.readthedocs.io/en/latest/)
|
* [Documentation](https://i2pd.readthedocs.io/en/latest/)
|
||||||
* [Wiki](https://github.com/PurpleI2P/i2pd/wiki)
|
* [Wiki](https://github.com/PurpleI2P/i2pd/wiki)
|
||||||
* [Tickets/Issues](https://github.com/PurpleI2P/i2pd/issues)
|
* [Tickets/Issues](https://github.com/PurpleI2P/i2pd/issues)
|
||||||
* [Twitter](https://twitter.com/i2porignal)
|
* [Specifications](https://geti2p.net/spec)
|
||||||
|
* [Twitter](https://twitter.com/hashtag/i2pd)
|
||||||
|
|
||||||
Installing
|
Installing
|
||||||
----------
|
----------
|
||||||
|
88
Reseed.cpp
88
Reseed.cpp
@ -131,51 +131,63 @@ namespace data
|
|||||||
s.read (signerID, signerIDLength); // signerID
|
s.read (signerID, signerIDLength); // signerID
|
||||||
signerID[signerIDLength] = 0;
|
signerID[signerIDLength] = 0;
|
||||||
|
|
||||||
//try to verify signature
|
bool verify; i2p::config::GetOption("reseed.verify", verify);
|
||||||
auto it = m_SigningKeys.find (signerID);
|
if (verify)
|
||||||
if (it != m_SigningKeys.end ())
|
|
||||||
{
|
{
|
||||||
// TODO: implement all signature types
|
//try to verify signature
|
||||||
if (signatureType == SIGNING_KEY_TYPE_RSA_SHA512_4096)
|
auto it = m_SigningKeys.find (signerID);
|
||||||
|
if (it != m_SigningKeys.end ())
|
||||||
{
|
{
|
||||||
size_t pos = s.tellg ();
|
// TODO: implement all signature types
|
||||||
size_t tbsLen = pos + contentLength;
|
if (signatureType == SIGNING_KEY_TYPE_RSA_SHA512_4096)
|
||||||
uint8_t * tbs = new uint8_t[tbsLen];
|
|
||||||
s.seekg (0, std::ios::beg);
|
|
||||||
s.read ((char *)tbs, tbsLen);
|
|
||||||
uint8_t * signature = new uint8_t[signatureLength];
|
|
||||||
s.read ((char *)signature, signatureLength);
|
|
||||||
// RSA-raw
|
|
||||||
{
|
{
|
||||||
// calculate digest
|
size_t pos = s.tellg ();
|
||||||
uint8_t digest[64];
|
size_t tbsLen = pos + contentLength;
|
||||||
SHA512 (tbs, tbsLen, digest);
|
uint8_t * tbs = new uint8_t[tbsLen];
|
||||||
// encrypt signature
|
s.seekg (0, std::ios::beg);
|
||||||
BN_CTX * bnctx = BN_CTX_new ();
|
s.read ((char *)tbs, tbsLen);
|
||||||
BIGNUM * s = BN_new (), * n = BN_new ();
|
uint8_t * signature = new uint8_t[signatureLength];
|
||||||
BN_bin2bn (signature, signatureLength, s);
|
s.read ((char *)signature, signatureLength);
|
||||||
BN_bin2bn (it->second, i2p::crypto::RSASHA5124096_KEY_LENGTH, n);
|
// RSA-raw
|
||||||
BN_mod_exp (s, s, i2p::crypto::GetRSAE (), n, bnctx); // s = s^e mod n
|
{
|
||||||
uint8_t * enSigBuf = new uint8_t[signatureLength];
|
// calculate digest
|
||||||
i2p::crypto::bn2buf (s, enSigBuf, signatureLength);
|
uint8_t digest[64];
|
||||||
// digest is right aligned
|
SHA512 (tbs, tbsLen, digest);
|
||||||
// we can't use RSA_verify due wrong padding in SU3
|
// encrypt signature
|
||||||
if (memcmp (enSigBuf + (signatureLength - 64), digest, 64))
|
BN_CTX * bnctx = BN_CTX_new ();
|
||||||
LogPrint (eLogWarning, "Reseed: SU3 signature verification failed");
|
BIGNUM * s = BN_new (), * n = BN_new ();
|
||||||
delete[] enSigBuf;
|
BN_bin2bn (signature, signatureLength, s);
|
||||||
BN_free (s); BN_free (n);
|
BN_bin2bn (it->second, i2p::crypto::RSASHA5124096_KEY_LENGTH, n);
|
||||||
BN_CTX_free (bnctx);
|
BN_mod_exp (s, s, i2p::crypto::GetRSAE (), n, bnctx); // s = s^e mod n
|
||||||
}
|
uint8_t * enSigBuf = new uint8_t[signatureLength];
|
||||||
|
i2p::crypto::bn2buf (s, enSigBuf, signatureLength);
|
||||||
|
// digest is right aligned
|
||||||
|
// we can't use RSA_verify due wrong padding in SU3
|
||||||
|
if (memcmp (enSigBuf + (signatureLength - 64), digest, 64))
|
||||||
|
LogPrint (eLogWarning, "Reseed: SU3 signature verification failed");
|
||||||
|
else
|
||||||
|
verify = false; // verified
|
||||||
|
delete[] enSigBuf;
|
||||||
|
BN_free (s); BN_free (n);
|
||||||
|
BN_CTX_free (bnctx);
|
||||||
|
}
|
||||||
|
|
||||||
delete[] signature;
|
delete[] signature;
|
||||||
delete[] tbs;
|
delete[] tbs;
|
||||||
s.seekg (pos, std::ios::beg);
|
s.seekg (pos, std::ios::beg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LogPrint (eLogWarning, "Reseed: Signature type ", signatureType, " is not supported");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogWarning, "Reseed: Signature type ", signatureType, " is not supported");
|
LogPrint (eLogWarning, "Reseed: Certificate for ", signerID, " not loaded");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verify) // not verified
|
||||||
|
{
|
||||||
|
LogPrint (eLogError, "Reseed: SU3 verification failed");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
LogPrint (eLogWarning, "Reseed: Certificate for ", signerID, " not loaded");
|
|
||||||
|
|
||||||
// handle content
|
// handle content
|
||||||
int numFiles = 0;
|
int numFiles = 0;
|
||||||
|
@ -18,7 +18,8 @@ namespace i2p
|
|||||||
|
|
||||||
RouterContext::RouterContext ():
|
RouterContext::RouterContext ():
|
||||||
m_LastUpdateTime (0), m_AcceptsTunnels (true), m_IsFloodfill (false),
|
m_LastUpdateTime (0), m_AcceptsTunnels (true), m_IsFloodfill (false),
|
||||||
m_StartupTime (0), m_Status (eRouterStatusOK), m_Error (eRouterErrorNone)
|
m_StartupTime (0), m_Status (eRouterStatusOK), m_Error (eRouterErrorNone),
|
||||||
|
m_NetID (I2PD_NET_ID)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +77,8 @@ namespace i2p
|
|||||||
}
|
}
|
||||||
routerInfo.SetCaps (i2p::data::RouterInfo::eReachable |
|
routerInfo.SetCaps (i2p::data::RouterInfo::eReachable |
|
||||||
i2p::data::RouterInfo::eSSUTesting | i2p::data::RouterInfo::eSSUIntroducer); // LR, BC
|
i2p::data::RouterInfo::eSSUTesting | i2p::data::RouterInfo::eSSUIntroducer); // LR, BC
|
||||||
routerInfo.SetProperty ("netId", std::to_string (I2PD_NET_ID));
|
i2p::config::GetOption("netid", m_NetID);
|
||||||
|
routerInfo.SetProperty ("netId", std::to_string (m_NetID));
|
||||||
routerInfo.SetProperty ("router.version", I2P_VERSION);
|
routerInfo.SetProperty ("router.version", I2P_VERSION);
|
||||||
routerInfo.CreateBuffer (m_Keys);
|
routerInfo.CreateBuffer (m_Keys);
|
||||||
m_RouterInfo.SetRouterIdentity (GetIdentity ());
|
m_RouterInfo.SetRouterIdentity (GetIdentity ());
|
||||||
|
@ -58,6 +58,8 @@ namespace i2p
|
|||||||
void SetStatus (RouterStatus status);
|
void SetStatus (RouterStatus status);
|
||||||
RouterError GetError () const { return m_Error; };
|
RouterError GetError () const { return m_Error; };
|
||||||
void SetError (RouterError error) { m_Status = eRouterStatusError; m_Error = error; };
|
void SetError (RouterError error) { m_Status = eRouterStatusError; m_Error = error; };
|
||||||
|
int GetNetID () const { return m_NetID; };
|
||||||
|
void SetNetID (int netID) { m_NetID = netID; };
|
||||||
|
|
||||||
void UpdatePort (int port); // called from Daemon
|
void UpdatePort (int port); // called from Daemon
|
||||||
void UpdateAddress (const boost::asio::ip::address& host); // called from SSU or Daemon
|
void UpdateAddress (const boost::asio::ip::address& host); // called from SSU or Daemon
|
||||||
@ -117,6 +119,7 @@ namespace i2p
|
|||||||
uint32_t m_BandwidthLimit; // allowed bandwidth
|
uint32_t m_BandwidthLimit; // allowed bandwidth
|
||||||
RouterStatus m_Status;
|
RouterStatus m_Status;
|
||||||
RouterError m_Error;
|
RouterError m_Error;
|
||||||
|
int m_NetID;
|
||||||
std::mutex m_GarlicMutex;
|
std::mutex m_GarlicMutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "Timestamp.h"
|
#include "Timestamp.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "NetDb.h"
|
#include "NetDb.h"
|
||||||
|
#include "RouterContext.h"
|
||||||
#include "RouterInfo.h"
|
#include "RouterInfo.h"
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
@ -286,7 +287,7 @@ namespace data
|
|||||||
if (!strcmp (key, "caps"))
|
if (!strcmp (key, "caps"))
|
||||||
ExtractCaps (value);
|
ExtractCaps (value);
|
||||||
// check netId
|
// check netId
|
||||||
else if (!strcmp (key, ROUTER_INFO_PROPERTY_NETID) && atoi (value) != I2PD_NET_ID)
|
else if (!strcmp (key, ROUTER_INFO_PROPERTY_NETID) && atoi (value) != i2p::context.GetNetID ())
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "RouterInfo: Unexpected ", ROUTER_INFO_PROPERTY_NETID, "=", value);
|
LogPrint (eLogError, "RouterInfo: Unexpected ", ROUTER_INFO_PROPERTY_NETID, "=", value);
|
||||||
m_IsUnreachable = true;
|
m_IsUnreachable = true;
|
||||||
@ -771,7 +772,11 @@ namespace data
|
|||||||
|
|
||||||
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetAddress (TransportStyle s, bool v4only, bool v6only) const
|
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetAddress (TransportStyle s, bool v4only, bool v6only) const
|
||||||
{
|
{
|
||||||
|
#if (BOOST_VERSION >= 105300)
|
||||||
|
auto addresses = boost::atomic_load (&m_Addresses);
|
||||||
|
#else
|
||||||
auto addresses = m_Addresses;
|
auto addresses = m_Addresses;
|
||||||
|
#endif
|
||||||
for (const auto& address : *addresses)
|
for (const auto& address : *addresses)
|
||||||
{
|
{
|
||||||
if (address->transportStyle == s)
|
if (address->transportStyle == s)
|
||||||
|
137
Tag.h
137
Tag.h
@ -1,3 +1,6 @@
|
|||||||
|
#ifndef TAG_H__
|
||||||
|
#define TAG_H__
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2016, The PurpleI2P Project
|
* Copyright (c) 2013-2016, The PurpleI2P Project
|
||||||
*
|
*
|
||||||
@ -6,92 +9,80 @@
|
|||||||
* See full license text in LICENSE file at top of project tree
|
* See full license text in LICENSE file at top of project tree
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TAG_H__
|
#include <boost/static_assert.hpp>
|
||||||
#define TAG_H__
|
#include <string.h>
|
||||||
|
|
||||||
#include <string.h> /* memcpy */
|
|
||||||
|
|
||||||
#include "Base.h"
|
#include "Base.h"
|
||||||
|
|
||||||
namespace i2p {
|
namespace i2p {
|
||||||
namespace data {
|
namespace data {
|
||||||
template<int sz>
|
|
||||||
class Tag
|
template<size_t sz>
|
||||||
|
class Tag
|
||||||
|
{
|
||||||
|
BOOST_STATIC_ASSERT_MSG(sz % 8 == 0, "Tag size must be multiple of 8 bytes");
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Tag () = default;
|
||||||
|
Tag (const uint8_t * buf) { memcpy (m_Buf, buf, sz); }
|
||||||
|
|
||||||
|
bool operator== (const Tag& other) const { return !memcmp (m_Buf, other.m_Buf, sz); }
|
||||||
|
bool operator< (const Tag& other) const { return memcmp (m_Buf, other.m_Buf, sz) < 0; }
|
||||||
|
|
||||||
|
uint8_t * operator()() { return m_Buf; }
|
||||||
|
const uint8_t * operator()() const { return m_Buf; }
|
||||||
|
|
||||||
|
operator uint8_t * () { return m_Buf; }
|
||||||
|
operator const uint8_t * () const { return m_Buf; }
|
||||||
|
|
||||||
|
const uint8_t * data() const { return m_Buf; }
|
||||||
|
const uint64_t * GetLL () const { return ll; }
|
||||||
|
|
||||||
|
bool IsZero () const
|
||||||
{
|
{
|
||||||
public:
|
for (size_t i = 0; i < sz/8; ++i)
|
||||||
|
if (ll[i]) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
Tag (const uint8_t * buf) { memcpy (m_Buf, buf, sz); };
|
void Fill(uint8_t c)
|
||||||
Tag (const Tag<sz>& ) = default;
|
{
|
||||||
#ifndef _WIN32 // FIXME!!! msvs 2013 can't compile it
|
memset(m_Buf, c, sz);
|
||||||
Tag (Tag<sz>&& ) = default;
|
}
|
||||||
#endif
|
|
||||||
Tag () = default;
|
|
||||||
|
|
||||||
Tag<sz>& operator= (const Tag<sz>& ) = default;
|
std::string ToBase64 () const
|
||||||
#ifndef _WIN32
|
{
|
||||||
Tag<sz>& operator= (Tag<sz>&& ) = default;
|
char str[sz*2];
|
||||||
#endif
|
size_t l = i2p::data::ByteStreamToBase64 (m_Buf, sz, str, sz*2);
|
||||||
|
return std::string (str, str + l);
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t * operator()() { return m_Buf; };
|
std::string ToBase32 () const
|
||||||
const uint8_t * operator()() const { return m_Buf; };
|
{
|
||||||
|
char str[sz*2];
|
||||||
|
size_t l = i2p::data::ByteStreamToBase32 (m_Buf, sz, str, sz*2);
|
||||||
|
return std::string (str, str + l);
|
||||||
|
}
|
||||||
|
|
||||||
operator uint8_t * () { return m_Buf; };
|
void FromBase32 (const std::string& s)
|
||||||
operator const uint8_t * () const { return m_Buf; };
|
{
|
||||||
|
i2p::data::Base32ToByteStream (s.c_str (), s.length (), m_Buf, sz);
|
||||||
|
}
|
||||||
|
|
||||||
const uint64_t * GetLL () const { return ll; };
|
void FromBase64 (const std::string& s)
|
||||||
|
{
|
||||||
|
i2p::data::Base64ToByteStream (s.c_str (), s.length (), m_Buf, sz);
|
||||||
|
}
|
||||||
|
|
||||||
bool operator== (const Tag<sz>& other) const { return !memcmp (m_Buf, other.m_Buf, sz); };
|
private:
|
||||||
bool operator< (const Tag<sz>& other) const { return memcmp (m_Buf, other.m_Buf, sz) < 0; };
|
|
||||||
|
|
||||||
bool IsZero () const
|
union // 8 bytes aligned
|
||||||
{
|
{
|
||||||
for (int i = 0; i < sz/8; i++)
|
uint8_t m_Buf[sz];
|
||||||
if (ll[i]) return false;
|
uint64_t ll[sz/8];
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint8_t * data() const { return m_Buf; }
|
|
||||||
|
|
||||||
/** fill with a value */
|
|
||||||
void Fill(uint8_t c)
|
|
||||||
{
|
|
||||||
memset(m_Buf, c, sz);
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
} // data
|
||||||
} // i2p
|
} // i2p
|
||||||
|
|
||||||
|
@ -142,9 +142,9 @@ install:
|
|||||||
- if not defined msvc (
|
- if not defined msvc (
|
||||||
C:\msys64\usr\bin\bash -lc "pacman --needed --noconfirm -Sy bash pacman pacman-mirrors msys2-runtime msys2-runtime-devel cmake"
|
C:\msys64\usr\bin\bash -lc "pacman --needed --noconfirm -Sy bash pacman pacman-mirrors msys2-runtime msys2-runtime-devel cmake"
|
||||||
&& if "%x64%" == "1" (
|
&& if "%x64%" == "1" (
|
||||||
C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-x86_64-openssl mingw-w64-x86_64-boost mingw-w64-x86_64-miniupnpc"
|
C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-x86_64-openssl mingw-w64-x86_64-boost mingw-w64-x86_64-miniupnpc mingw-w64-x86_64-extra-cmake-modules"
|
||||||
) else (
|
) else (
|
||||||
C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-openssl mingw-w64-i686-boost mingw-w64-i686-miniupnpc"
|
C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-openssl mingw-w64-i686-boost mingw-w64-i686-miniupnpc mingw-w64-i686-extra-cmake-modules"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
cache:
|
cache:
|
||||||
|
@ -16,7 +16,8 @@ option(WITH_UPNP "Include support for UPnP client" OFF)
|
|||||||
option(WITH_PCH "Use precompiled header" OFF)
|
option(WITH_PCH "Use precompiled header" OFF)
|
||||||
option(WITH_GUI "Include GUI (currently MS Windows only)" ON)
|
option(WITH_GUI "Include GUI (currently MS Windows only)" ON)
|
||||||
option(WITH_MESHNET "Build for cjdns test network" OFF)
|
option(WITH_MESHNET "Build for cjdns test network" OFF)
|
||||||
option(WITH_ADDRSANITIZER "Build with address sanitizer (linux only)" OFF)
|
option(WITH_ADDRSANITIZER "Build with address sanitizer unix only" OFF)
|
||||||
|
option(WITH_THREADSANITIZER "Build with thread sanitizer unix only" OFF)
|
||||||
|
|
||||||
# paths
|
# paths
|
||||||
set ( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules" )
|
set ( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules" )
|
||||||
@ -190,10 +191,22 @@ if (WITH_ADDRSANITIZER)
|
|||||||
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer" )
|
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer" )
|
||||||
set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address" )
|
set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address" )
|
||||||
else ()
|
else ()
|
||||||
error ("MSVC does not support address sanitizer option")
|
message( SEND_ERROR "MSVC does not support address sanitizer option")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (WITH_THREADSANITIZER)
|
||||||
|
if (WITH_ADDRSANITIZER)
|
||||||
|
message( FATAL_ERROR "thread sanitizer option cannot be combined with address sanitizer")
|
||||||
|
elseif (NOT MSVC)
|
||||||
|
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread" )
|
||||||
|
set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=thread" )
|
||||||
|
else ()
|
||||||
|
message( SEND_ERROR "MSVC does not support address sanitizer option")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
# libraries
|
# libraries
|
||||||
# TODO: once CMake 3.1+ becomes mainstream, see e.g. http://stackoverflow.com/a/29871891/673826
|
# TODO: once CMake 3.1+ becomes mainstream, see e.g. http://stackoverflow.com/a/29871891/673826
|
||||||
# use imported Threads::Threads instead
|
# use imported Threads::Threads instead
|
||||||
@ -347,6 +360,7 @@ message(STATUS " UPnP : ${WITH_UPNP}")
|
|||||||
message(STATUS " PCH : ${WITH_PCH}")
|
message(STATUS " PCH : ${WITH_PCH}")
|
||||||
message(STATUS " MESHNET : ${WITH_MESHNET}")
|
message(STATUS " MESHNET : ${WITH_MESHNET}")
|
||||||
message(STATUS " ADDRSANITIZER : ${WITH_ADDRSANITIZER}")
|
message(STATUS " ADDRSANITIZER : ${WITH_ADDRSANITIZER}")
|
||||||
|
message(STATUS " THEADSANITIZER : ${WITH_THREADSANITIZER}")
|
||||||
message(STATUS "---------------------------------------")
|
message(STATUS "---------------------------------------")
|
||||||
|
|
||||||
#Handle paths nicely
|
#Handle paths nicely
|
||||||
|
34
contrib/certificates/reseed/atomike_at_mail.i2p.crt
Normal file
34
contrib/certificates/reseed/atomike_at_mail.i2p.crt
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIF5TCCA82gAwIBAgIRANFIiHpTaRY2Z30TQOiuqFcwDQYJKoZIhvcNAQELBQAw
|
||||||
|
cDELMAkGA1UEBhMCWFgxCzAJBgNVBAcTAlhYMQswCQYDVQQJEwJYWDEeMBwGA1UE
|
||||||
|
ChMVSTJQIEFub255bW91cyBOZXR3b3JrMQwwCgYDVQQLEwNJMlAxGTAXBgNVBAMM
|
||||||
|
EGF0b21pa2VAbWFpbC5pMnAwHhcNMTYwODAyMTQyNDEyWhcNMjYwODAyMTQyNDEy
|
||||||
|
WjBwMQswCQYDVQQGEwJYWDELMAkGA1UEBxMCWFgxCzAJBgNVBAkTAlhYMR4wHAYD
|
||||||
|
VQQKExVJMlAgQW5vbnltb3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEZMBcGA1UE
|
||||||
|
AwwQYXRvbWlrZUBtYWlsLmkycDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC
|
||||||
|
ggIBAMLRmxclaAvm405JLHNNiniUi0aZaBoLJ+afwn2LGfTDUhTD5Y8lW6V9o90n
|
||||||
|
eTNOCaiid7bWpVBkA1M4gZ9TdUnP0POa99jXZbj4PHFRl1l8k4Ap12PUO3hgwtH7
|
||||||
|
7j7j+UPaIuE2y+U7hJbmyQ0v7r8yjGWSTtSqs+exNhyr4Mh7DvacZySZ+oqQdXYA
|
||||||
|
vnfDpBX1dKlN1Nb4XloG0uE1OK1YfJoC+p+v8qXjKagIdZgThdmsWcQ82EGI+Q9u
|
||||||
|
VfrE4m3CNwJy0X86wMNYqHej88wBHnJMmTm+cZtFLVmZsRqnuLAQL1wrfCbGSltR
|
||||||
|
zhVQHTysLwMz9+llTXtzMf+R2kcEAYWiPc5IRVU+LvkN/610r5fuHW+OcQ9ZgRVn
|
||||||
|
PMqlv5PDG2ZxdIOAQQsOd7fH0r5q3MhqlVstVE45Rl33uA+M7wjJK2cvnOoSioxp
|
||||||
|
szn2GIZliXQXo4dJczgfN2U4PLBGRBGmrB1R2S1YsG6CrSJuMCX14VKJP69Nfm8a
|
||||||
|
EDA5GKNke+ZpXCszPLaNMB70LVFQc9FmMhsOgLIIoJBgd61uMgokMJJMLaWN0RaK
|
||||||
|
w1ZduxYGUmg2T2pi/clIkVzZmlcHKViUn0sMcKD+ibEPOvQIB/3HPEEt6iIkanc/
|
||||||
|
da5IFzikkaykt/Tu6o8rreeEu65HkIxFaCHegSXLHSyxj00BAgMBAAGjejB4MA4G
|
||||||
|
A1UdDwEB/wQEAwIChDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDwYD
|
||||||
|
VR0TAQH/BAUwAwEB/zAZBgNVHQ4EEgQQYXRvbWlrZUBtYWlsLmkycDAbBgNVHSME
|
||||||
|
FDASgBBhdG9taWtlQG1haWwuaTJwMA0GCSqGSIb3DQEBCwUAA4ICAQAA0MdWfN/N
|
||||||
|
1q5CdJqDyw4JQwzdYkA27Wr02qIcmwnqjcCEDPl4uDTyqN9gbEpJ48AcsdXRa6GE
|
||||||
|
lLh/qJ67I6YDe63LuhndzRULNgxGHVMGS8kBJIssQehb2rOFnbUTp0gMR+0QpXXe
|
||||||
|
omase4kL90c9uuYX1vXaO/ADssY2/QX49prwJO+UY/jGhcX4YheFI/teA85u6Qko
|
||||||
|
ero437Shqhl0kbdK+eBkOFf9a7mGxpMT73KE1jFS6433W4fFOkybQ1dcS0qStaUM
|
||||||
|
3qKC0EQCbAl1seAp3AGuG46swHZB0rZ1WCKVAr5yqCWSWMYO+fL6FosNg9z/VDVh
|
||||||
|
g6FFfoGrv19yaVFa9AvQsk1ATZ+bwtHProNx2Xet9pnAI30dT16+C5wCctoR6RVf
|
||||||
|
iOHl6CGqadjOycbMDVvOfJhypNDgWW3gBaCfXiAocJTLpR7hKNZ2bnvcP2xyXH1j
|
||||||
|
Qz/kiMJoZ3+TV1yC/x/maAHsUIQHqqd6ZRj7x5MgJq0UBdITo2ZQVfXYI0ZGIeNm
|
||||||
|
fMu+P5448+NdpASa9QoqS8kPFeUaHJMzMFHBKhrr8lTJeZ82hKBXt5jD3Tbef5Ck
|
||||||
|
n5auKu2D0IjvrzsdIpNMQAhuBPT06TW/LzN/MvardZcaLcBmcutefw6Z7RsedHvj
|
||||||
|
cGpnw4a2u9sHZIUNHzoGq32+7UWXsBI5Ow==
|
||||||
|
-----END CERTIFICATE-----
|
@ -87,7 +87,19 @@ 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
|
shell, consider starting *MinGW-w64 Win32 Shell* instead of *MSYS2 Shell* as
|
||||||
it adds`/minw32/bin` to the PATH.
|
it adds`/minw32/bin` to the PATH.
|
||||||
|
|
||||||
|
### UPnP
|
||||||
|
You can install it through the MSYS2
|
||||||
|
and build with USE_UPNP key.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pacman -S mingw-w64-i686-miniupnpc
|
||||||
|
make USE_UPNP=yes
|
||||||
|
```
|
||||||
|
or
|
||||||
|
```bash
|
||||||
|
pacman -S mingw-w64-x86_64-miniupnpc
|
||||||
|
make USE_UPNP=yes
|
||||||
|
```
|
||||||
|
|
||||||
Using Visual Studio
|
Using Visual Studio
|
||||||
-------------------
|
-------------------
|
||||||
@ -161,19 +173,6 @@ support for this. Unpack client source code in a sibling folder,
|
|||||||
e.g. C:\dev\miniupnpc . You may want to remove version number from
|
e.g. C:\dev\miniupnpc . You may want to remove version number from
|
||||||
folder name included in downloaded archive.
|
folder name included in downloaded archive.
|
||||||
|
|
||||||
You can also install it through the MSYS2
|
|
||||||
and build with USE_UPNP key.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pacman -S mingw-w64-i686-miniupnpc
|
|
||||||
make USE_UPNP=yes
|
|
||||||
```
|
|
||||||
or
|
|
||||||
```bash
|
|
||||||
pacman -S mingw-x86_64-miniupnpc
|
|
||||||
make USE_UPNP=yes
|
|
||||||
```
|
|
||||||
|
|
||||||
### 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.
|
||||||
|
@ -25,6 +25,7 @@ If you are upgrading your very old router (< 2.3.0) see also [this](config_opts_
|
|||||||
* --floodfill - Router will be floodfill. false by default
|
* --floodfill - Router will be floodfill. false by default
|
||||||
* --bandwidth= - Bandwidth limit: integer in KBps or letters: L (32), O (256), P (2048), X (>9000)
|
* --bandwidth= - Bandwidth limit: integer in KBps or letters: L (32), O (256), P (2048), X (>9000)
|
||||||
* --family= - Name of a family, router belongs to
|
* --family= - Name of a family, router belongs to
|
||||||
|
* --netid= - Network ID, router belongs to. Main I2P is 2.
|
||||||
|
|
||||||
Windows-specific options:
|
Windows-specific options:
|
||||||
|
|
||||||
@ -72,8 +73,11 @@ All options below still possible in cmdline, but better write it in config file:
|
|||||||
* --upnp.name= - Name i2pd appears in UPnP forwardings list. I2Pd by default
|
* --upnp.name= - Name i2pd appears in UPnP forwardings list. I2Pd by default
|
||||||
|
|
||||||
* --precomputation.elgamal= - Use ElGamal precomputated tables. false for x64 and true for other platforms by default
|
* --precomputation.elgamal= - Use ElGamal precomputated tables. false for x64 and true for other platforms by default
|
||||||
* --reseed.file - Full path to SU3 file to reseed from
|
* --reseed.verify= - Request SU3 signature verification
|
||||||
* --reseed.urls - Reseed URLs, separated by comma
|
* --reseed.file= - Full path to SU3 file to reseed from
|
||||||
|
* --reseed.urls= - Reseed URLs, separated by comma
|
||||||
|
* --addressbook.defaulturl= - AddressBook subscription URL for initial setup
|
||||||
|
* --addressbook.subscriptions= - AddressBook subscriptions URLs, separated by comma
|
||||||
|
|
||||||
* --limits.transittunnels= - Override maximum number of transit tunnels. 2500 by default
|
* --limits.transittunnels= - Override maximum number of transit tunnels. 2500 by default
|
||||||
|
|
||||||
|
@ -92,8 +92,18 @@ ipv6 = false
|
|||||||
# name = I2Pd
|
# name = I2Pd
|
||||||
|
|
||||||
[reseed]
|
[reseed]
|
||||||
## Path to reseed .su3 file (if )
|
## URLs to request reseed data from, separated by comma
|
||||||
# file =
|
## Default: "mainline" I2P Network reseeds
|
||||||
|
# urls = https://reseed.i2p-projekt.de/,https://i2p.mooo.com/netDb/,https://netdb.i2p2.no/
|
||||||
|
## Path to reseed data file (.su3) for manual reseeding
|
||||||
|
# file = /path/to/i2pseeds.su3
|
||||||
|
|
||||||
|
[addressbook]
|
||||||
|
## AddressBook subscription URL for initial setup
|
||||||
|
## Default: inr.i2p at "mainline" I2P Network
|
||||||
|
# defaulturl = http://joajgazyztfssty4w2on5oaqksz6tqoxbduy553y34mf4byv6gpq.b32.i2p/export/alive-hosts.txt
|
||||||
|
## Optional subscriptions URLs, separated by comma
|
||||||
|
# subscriptions = http://inr.i2p/export/alive-hosts.txt,http://stats.i2p/cgi-bin/newhosts.txt,http://rus.i2p/hosts.txt
|
||||||
|
|
||||||
[http]
|
[http]
|
||||||
## Uncomment and set to 'false' to disable Web Console
|
## Uncomment and set to 'false' to disable Web Console
|
||||||
|
@ -32,7 +32,9 @@ Contents:
|
|||||||
build_requirements
|
build_requirements
|
||||||
build_notes_unix
|
build_notes_unix
|
||||||
build_notes_windows
|
build_notes_windows
|
||||||
|
build_notes_cross
|
||||||
build_notes_android
|
build_notes_android
|
||||||
|
build_notes_ios
|
||||||
configuration
|
configuration
|
||||||
family
|
family
|
||||||
usage
|
usage
|
||||||
|
Loading…
Reference in New Issue
Block a user