mirror of
https://github.com/PurpleI2P/i2pd
synced 2024-11-10 16:10:33 +03:00
commit
7419f992e7
28
Crypto.cpp
28
Crypto.cpp
@ -227,10 +227,8 @@ namespace crypto
|
||||
DHKeys::DHKeys (): m_IsUpdated (true)
|
||||
{
|
||||
m_DH = DH_new ();
|
||||
m_DH->p = BN_dup (elgp);
|
||||
m_DH->g = BN_dup (elgg);
|
||||
m_DH->priv_key = NULL;
|
||||
m_DH->pub_key = NULL;
|
||||
DH_set0_pqg (m_DH, BN_dup (elgp), NULL, BN_dup (elgg));
|
||||
DH_set0_key (m_DH, NULL, NULL);
|
||||
}
|
||||
|
||||
DHKeys::~DHKeys ()
|
||||
@ -240,27 +238,31 @@ namespace crypto
|
||||
|
||||
void DHKeys::GenerateKeys (uint8_t * priv, uint8_t * pub)
|
||||
{
|
||||
if (m_DH->priv_key) { BN_free (m_DH->priv_key); m_DH->priv_key = NULL; };
|
||||
if (m_DH->pub_key) { BN_free (m_DH->pub_key); m_DH->pub_key = NULL; };
|
||||
BIGNUM * priv_key = NULL, * pub_key = NULL;
|
||||
#if !defined(__x86_64__) // use short exponent for non x64
|
||||
m_DH->priv_key = BN_new ();
|
||||
BN_rand (m_DH->priv_key, ELGAMAL_SHORT_EXPONENT_NUM_BITS, 0, 1);
|
||||
priv_key = BN_new ();
|
||||
BN_rand (priv_key, ELGAMAL_SHORT_EXPONENT_NUM_BITS, 0, 1);
|
||||
#endif
|
||||
if (g_ElggTable)
|
||||
{
|
||||
#if defined(__x86_64__)
|
||||
m_DH->priv_key = BN_new ();
|
||||
BN_rand (m_DH->priv_key, ELGAMAL_FULL_EXPONENT_NUM_BITS, 0, 1);
|
||||
priv_key = BN_new ();
|
||||
BN_rand (priv_key, ELGAMAL_FULL_EXPONENT_NUM_BITS, 0, 1);
|
||||
#endif
|
||||
auto ctx = BN_CTX_new ();
|
||||
m_DH->pub_key = ElggPow (m_DH->priv_key, g_ElggTable, ctx);
|
||||
pub_key = ElggPow (priv_key, g_ElggTable, ctx);
|
||||
DH_set0_key (m_DH, pub_key, priv_key);
|
||||
BN_CTX_free (ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
DH_set0_key (m_DH, NULL, priv_key);
|
||||
DH_generate_key (m_DH);
|
||||
DH_get0_key (m_DH, (const BIGNUM **)&pub_key, (const BIGNUM **)&priv_key);
|
||||
}
|
||||
|
||||
if (priv) bn2buf (m_DH->priv_key, priv, 256);
|
||||
if (pub) bn2buf (m_DH->pub_key, pub, 256);
|
||||
if (priv) bn2buf (priv_key, priv, 256);
|
||||
if (pub) bn2buf (pub_key, pub, 256);
|
||||
m_IsUpdated = true;
|
||||
}
|
||||
|
||||
|
11
Crypto.h
11
Crypto.h
@ -301,6 +301,17 @@ inline int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
|
||||
inline void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
|
||||
{ *n = r->n; *e = r->e; *d = r->d; }
|
||||
|
||||
inline int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
|
||||
{ dh->p = p; dh->q = q; dh->g = g; return 1; }
|
||||
inline int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
|
||||
{
|
||||
if (dh->pub_key) BN_free (dh->pub_key);
|
||||
if (dh->priv_key) BN_free (dh->priv_key);
|
||||
dh->pub_key = pub_key; dh->priv_key = priv_key; return 1;
|
||||
}
|
||||
inline void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key)
|
||||
{ *pub_key = dh->pub_key; *priv_key = dh->priv_key; }
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
@ -277,19 +277,20 @@ namespace client
|
||||
LogPrint (eLogInfo, "Destination: Reply token is ignored for DatabaseStore");
|
||||
offset += 36;
|
||||
}
|
||||
i2p::data::IdentHash key (buf + DATABASE_STORE_KEY_OFFSET);
|
||||
std::shared_ptr<i2p::data::LeaseSet> leaseSet;
|
||||
if (buf[DATABASE_STORE_TYPE_OFFSET] == 1) // LeaseSet
|
||||
{
|
||||
LogPrint (eLogDebug, "Destination: Remote LeaseSet");
|
||||
std::lock_guard<std::mutex> lock(m_RemoteLeaseSetsMutex);
|
||||
auto it = m_RemoteLeaseSets.find (buf + DATABASE_STORE_KEY_OFFSET);
|
||||
auto it = m_RemoteLeaseSets.find (key);
|
||||
if (it != m_RemoteLeaseSets.end ())
|
||||
{
|
||||
leaseSet = it->second;
|
||||
if (leaseSet->IsNewer (buf + offset, len - offset))
|
||||
{
|
||||
leaseSet->Update (buf + offset, len - offset);
|
||||
if (leaseSet->IsValid ())
|
||||
if (leaseSet->IsValid () && leaseSet->GetIdentHash () == key)
|
||||
LogPrint (eLogDebug, "Destination: Remote LeaseSet updated");
|
||||
else
|
||||
{
|
||||
@ -304,12 +305,12 @@ namespace client
|
||||
else
|
||||
{
|
||||
leaseSet = std::make_shared<i2p::data::LeaseSet> (buf + offset, len - offset);
|
||||
if (leaseSet->IsValid ())
|
||||
if (leaseSet->IsValid () && leaseSet->GetIdentHash () == key)
|
||||
{
|
||||
if (leaseSet->GetIdentHash () != GetIdentHash ())
|
||||
{
|
||||
LogPrint (eLogDebug, "Destination: New remote LeaseSet added");
|
||||
m_RemoteLeaseSets[buf + DATABASE_STORE_KEY_OFFSET] = leaseSet;
|
||||
m_RemoteLeaseSets[key] = leaseSet;
|
||||
}
|
||||
else
|
||||
LogPrint (eLogDebug, "Destination: Own remote LeaseSet dropped");
|
||||
@ -324,7 +325,7 @@ namespace client
|
||||
else
|
||||
LogPrint (eLogError, "Destination: Unexpected client's DatabaseStore type ", buf[DATABASE_STORE_TYPE_OFFSET], ", dropped");
|
||||
|
||||
auto it1 = m_LeaseSetRequests.find (buf + DATABASE_STORE_KEY_OFFSET);
|
||||
auto it1 = m_LeaseSetRequests.find (key);
|
||||
if (it1 != m_LeaseSetRequests.end ())
|
||||
{
|
||||
it1->second->requestTimeoutTimer.cancel ();
|
||||
|
2
Makefile
2
Makefile
@ -94,7 +94,7 @@ strip: $(I2PD) $(SHLIB_CLIENT) $(SHLIB)
|
||||
strip $^
|
||||
|
||||
LATEST_TAG=$(shell git describe --tags --abbrev=0 openssl)
|
||||
BRANCH=$(shell git branch --no-color | cut -c 3-)
|
||||
BRANCH=$(shell git rev-parse --abbrev-ref HEAD)
|
||||
dist:
|
||||
git archive --format=tar.gz -9 --worktree-attributes \
|
||||
--prefix=i2pd_$(LATEST_TAG)/ $(LATEST_TAG) -o i2pd_$(LATEST_TAG).tar.gz
|
||||
|
@ -1111,7 +1111,7 @@ namespace transport
|
||||
RAND_bytes ((uint8_t *)&nonce, 4);
|
||||
if (!nonce) nonce = 1;
|
||||
m_IsPeerTest = false;
|
||||
m_Server.NewPeerTest (nonce, ePeerTestParticipantAlice1);
|
||||
m_Server.NewPeerTest (nonce, ePeerTestParticipantAlice1, shared_from_this ());
|
||||
SendPeerTest (nonce, boost::asio::ip::address(), 0, address->key, false, false); // address and port always zero for Alice
|
||||
}
|
||||
|
||||
|
@ -48,19 +48,29 @@ namespace transport
|
||||
{
|
||||
while (m_IsRunning)
|
||||
{
|
||||
int num;
|
||||
while ((num = m_QueueSize - m_Queue.size ()) > 0)
|
||||
int num, total = 0;
|
||||
while ((num = m_QueueSize - (int)m_Queue.size ()) > 0 && total < 20)
|
||||
{
|
||||
CreateDHKeysPairs (num);
|
||||
total += num;
|
||||
}
|
||||
if (total >= 20)
|
||||
{
|
||||
LogPrint (eLogWarning, "Transports: ", total, " DH keys generated at the time");
|
||||
std::this_thread::sleep_for (std::chrono::seconds(1)); // take a break
|
||||
}
|
||||
else
|
||||
{
|
||||
std::unique_lock<std::mutex> l(m_AcquiredMutex);
|
||||
m_Acquired.wait (l); // wait for element gets aquired
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DHKeysPairSupplier::CreateDHKeysPairs (int num)
|
||||
{
|
||||
if (num > 0)
|
||||
{
|
||||
i2p::crypto::DHKeys dh;
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
auto pair = std::make_shared<i2p::crypto::DHKeys> ();
|
||||
|
@ -117,7 +117,7 @@ namespace tunnel
|
||||
m.nextFragmentNum = 1;
|
||||
auto ret = m_IncompleteMessages.insert (std::pair<uint32_t, TunnelMessageBlockEx>(msgID, m));
|
||||
if (ret.second)
|
||||
HandleOutOfSequenceFragment (msgID, ret.first->second);
|
||||
HandleOutOfSequenceFragments (msgID, ret.first->second);
|
||||
else
|
||||
LogPrint (eLogError, "TunnelMessage: Incomplete message ", msgID, " already exists");
|
||||
}
|
||||
@ -168,7 +168,7 @@ namespace tunnel
|
||||
else
|
||||
{
|
||||
msg.nextFragmentNum++;
|
||||
HandleOutOfSequenceFragment (msgID, msg);
|
||||
HandleOutOfSequenceFragments (msgID, msg);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -192,19 +192,31 @@ namespace tunnel
|
||||
|
||||
void TunnelEndpoint::AddOutOfSequenceFragment (uint32_t msgID, uint8_t fragmentNum, bool isLastFragment, std::shared_ptr<I2NPMessage> data)
|
||||
{
|
||||
auto it = m_OutOfSequenceFragments.find (msgID);
|
||||
if (it == m_OutOfSequenceFragments.end ())
|
||||
m_OutOfSequenceFragments.insert (std::pair<uint32_t, Fragment> (msgID, {fragmentNum, isLastFragment, data}));
|
||||
if (!m_OutOfSequenceFragments.insert ({{msgID, fragmentNum}, {fragmentNum, isLastFragment, data}}).second)
|
||||
LogPrint (eLogInfo, "TunnelMessage: duplicate out-of-sequence fragment ", fragmentNum, " of message ", msgID);
|
||||
}
|
||||
|
||||
void TunnelEndpoint::HandleOutOfSequenceFragment (uint32_t msgID, TunnelMessageBlockEx& msg)
|
||||
void TunnelEndpoint::HandleOutOfSequenceFragments (uint32_t msgID, TunnelMessageBlockEx& msg)
|
||||
{
|
||||
auto it = m_OutOfSequenceFragments.find (msgID);
|
||||
while (ConcatNextOutOfSequenceFragment (msgID, msg))
|
||||
{
|
||||
if (!msg.nextFragmentNum) // message complete
|
||||
{
|
||||
HandleNextMessage (msg);
|
||||
m_IncompleteMessages.erase (msgID);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool TunnelEndpoint::ConcatNextOutOfSequenceFragment (uint32_t msgID, TunnelMessageBlockEx& msg)
|
||||
{
|
||||
auto it = m_OutOfSequenceFragments.find ({msgID, msg.nextFragmentNum});
|
||||
if (it != m_OutOfSequenceFragments.end ())
|
||||
{
|
||||
if (it->second.fragmentNum == msg.nextFragmentNum)
|
||||
{
|
||||
LogPrint (eLogWarning, "TunnelMessage: Out-of-sequence fragment ", (int)it->second.fragmentNum, " of message ", msgID, " found");
|
||||
LogPrint (eLogDebug, "TunnelMessage: Out-of-sequence fragment ", (int)it->second.fragmentNum, " of message ", msgID, " found");
|
||||
size_t size = it->second.data->GetLength ();
|
||||
if (msg.data->len + size > msg.data->maxLen)
|
||||
{
|
||||
@ -214,18 +226,19 @@ namespace tunnel
|
||||
msg.data = newMsg;
|
||||
}
|
||||
if (msg.data->Concat (it->second.data->GetBuffer (), size) < size) // concatenate out-of-sync fragment
|
||||
LogPrint (eLogError, "Tunnel endpoint I2NP buffer overflow ", msg.data->maxLen);
|
||||
LogPrint (eLogError, "TunnelMessage: Tunnel endpoint I2NP buffer overflow ", msg.data->maxLen);
|
||||
if (it->second.isLastFragment)
|
||||
{
|
||||
// message complete
|
||||
HandleNextMessage (msg);
|
||||
m_IncompleteMessages.erase (msgID);
|
||||
}
|
||||
msg.nextFragmentNum = 0;
|
||||
else
|
||||
msg.nextFragmentNum++;
|
||||
m_OutOfSequenceFragments.erase (it);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
LogPrint (eLogError, "Tunnel message: next fragment ", (int)it->second.fragmentNum, " of message ", msgID, " mismatch. ", (int)msg.nextFragmentNum, " expected");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void TunnelEndpoint::HandleNextMessage (const TunnelMessageBlock& msg)
|
||||
|
@ -39,12 +39,13 @@ namespace tunnel
|
||||
void HandleNextMessage (const TunnelMessageBlock& msg);
|
||||
|
||||
void AddOutOfSequenceFragment (uint32_t msgID, uint8_t fragmentNum, bool isLastFragment, std::shared_ptr<I2NPMessage> data);
|
||||
void HandleOutOfSequenceFragment (uint32_t msgID, TunnelMessageBlockEx& msg);
|
||||
bool ConcatNextOutOfSequenceFragment (uint32_t msgID, TunnelMessageBlockEx& msg); // true if something added
|
||||
void HandleOutOfSequenceFragments (uint32_t msgID, TunnelMessageBlockEx& msg);
|
||||
|
||||
private:
|
||||
|
||||
std::map<uint32_t, TunnelMessageBlockEx> m_IncompleteMessages;
|
||||
std::map<uint32_t, Fragment> m_OutOfSequenceFragments;
|
||||
std::map<std::pair<uint32_t, uint8_t>, Fragment> m_OutOfSequenceFragments; // (msgID, fragment#)->fragment
|
||||
bool m_IsInbound;
|
||||
size_t m_NumReceivedBytes;
|
||||
};
|
||||
|
@ -1,9 +1,11 @@
|
||||
#define I2Pd_AppName "i2pd"
|
||||
#define I2Pd_ver "2.10.0"
|
||||
#define I2Pd_ver "2.10.1"
|
||||
#define I2Pd_Publisher "PurpleI2P"
|
||||
|
||||
[Setup]
|
||||
AppName={#I2Pd_AppName}
|
||||
AppVersion={#I2Pd_ver}
|
||||
AppPublisher={#I2Pd_Publisher}
|
||||
DefaultDirName={pf}\I2Pd
|
||||
DefaultGroupName=I2Pd
|
||||
UninstallDisplayIcon={app}\I2Pd.exe
|
||||
@ -14,19 +16,25 @@ InternalCompressLevel=ultra64
|
||||
Compression=lzma/ultra64
|
||||
SolidCompression=true
|
||||
ArchitecturesInstallIn64BitMode=x64
|
||||
AppVerName={#I2Pd_AppName}
|
||||
ExtraDiskSpaceRequired=15
|
||||
AppID={{621A23E0-3CF4-4BD6-97BC-4835EA5206A2}
|
||||
AppPublisherURL=http://i2pd.website/
|
||||
AppSupportURL=https://github.com/PurpleI2P/i2pd/issues
|
||||
AppUpdatesURL=https://github.com/PurpleI2P/i2pd/releases
|
||||
|
||||
[Files]
|
||||
Source: "..\i2pd_x86.exe"; DestDir: "{app}"; DestName: "i2pd.exe"; Flags: ignoreversion; Check: not IsWin64
|
||||
Source: "..\i2pd_x64.exe"; DestDir: "{app}"; DestName: "i2pd.exe"; Flags: ignoreversion; Check: IsWin64
|
||||
Source: "..\README.md"; DestDir: "{app}"; DestName: "Readme.txt"; Flags: onlyifdoesntexist
|
||||
Source: "..\docs\i2pd.conf"; DestDir: "{userappdata}\i2pd"; Flags: onlyifdoesntexist
|
||||
Source: "..\docs\subscriptions.txt"; DestDir: "{userappdata}\i2pd"; Flags: onlyifdoesntexist
|
||||
Source: "..\docs\tunnels.conf"; DestDir: "{userappdata}\i2pd"; Flags: onlyifdoesntexist
|
||||
Source: "..\contrib\*"; DestDir: "{userappdata}\i2pd"; Flags: onlyifdoesntexist recursesubdirs createallsubdirs
|
||||
Source: ..\i2pd_x86.exe; DestDir: {app}; DestName: i2pd.exe; Flags: ignoreversion; Check: not IsWin64
|
||||
Source: ..\i2pd_x64.exe; DestDir: {app}; DestName: i2pd.exe; Flags: ignoreversion; Check: IsWin64
|
||||
Source: ..\README.md; DestDir: {app}; DestName: Readme.txt; Flags: onlyifdoesntexist
|
||||
Source: ..\docs\i2pd.conf; DestDir: {userappdata}\i2pd; Flags: onlyifdoesntexist
|
||||
Source: ..\docs\subscriptions.txt; DestDir: {userappdata}\i2pd; Flags: onlyifdoesntexist
|
||||
Source: ..\docs\tunnels.conf; DestDir: {userappdata}\i2pd; Flags: onlyifdoesntexist
|
||||
Source: ..\contrib\certificates\*; DestDir: {userappdata}\i2pd\certificates; Flags: onlyifdoesntexist recursesubdirs createallsubdirs
|
||||
|
||||
[Icons]
|
||||
Name: "{group}\I2Pd"; Filename: "{app}\i2pd.exe"
|
||||
Name: "{group}\Readme"; Filename: "{app}\Readme.txt"
|
||||
Name: {group}\I2Pd; Filename: {app}\i2pd.exe
|
||||
Name: {group}\Readme; Filename: {app}\Readme.txt
|
||||
|
||||
[UninstallDelete]
|
||||
Type: filesandordirs; Name: {app}\*
|
||||
Type: filesandordirs; Name: {app}
|
||||
|
@ -2,7 +2,7 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.purplei2p.i2pd"
|
||||
android:versionCode="1"
|
||||
android:versionName="2.10.0">
|
||||
android:versionName="2.10.1">
|
||||
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="24"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
|
@ -10,6 +10,47 @@ i2pd can be used for:
|
||||
|
||||
and many more.
|
||||
|
||||
## Starting, stopping and reloading configuration
|
||||
|
||||
After you have built i2pd from source, just run a binary:
|
||||
|
||||
./i2pd
|
||||
|
||||
To display all available options:
|
||||
|
||||
./i2pd --help
|
||||
|
||||
i2pd can be controlled with signals. Process ID by default is written to file `~/.i2pd/i2pd.pid` or `/var/run/i2pd/i2pd.pid`.
|
||||
You can use `kill` utility to send signals like this:
|
||||
|
||||
kill -TERM $( cat /var/run/i2pd/i2pd.pid )
|
||||
|
||||
i2pd supports the following signals:
|
||||
|
||||
TERM - Graceful shutdown. i2pd will wait for 10 minutes and stop. Send second TERM signal to shutdown i2pd immediately.
|
||||
HUP - Reload configuration files.
|
||||
|
||||
|
||||
### systemd unit
|
||||
|
||||
Some binary Linux packages have a systemd control unit, so it is possible to managage i2pd with it.
|
||||
|
||||
Start/stop i2pd:
|
||||
|
||||
sudo systemctl start i2pd.service
|
||||
sudo systemctl stop i2pd.service
|
||||
|
||||
Enable/disable i2pd to be started on bootup:
|
||||
|
||||
sudo systemctl enable i2pd.service
|
||||
sudo systemctl disable i2pd.service
|
||||
|
||||
|
||||
## Configuring i2pd
|
||||
|
||||
See [configuration page](i2pd.readthedocs.io/page/configuration.html).
|
||||
|
||||
|
||||
## Browsing and hosting websites
|
||||
|
||||
### Browse anonymous websites
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
#define I2PD_VERSION_MAJOR 2
|
||||
#define I2PD_VERSION_MINOR 10
|
||||
#define I2PD_VERSION_MICRO 0
|
||||
#define I2PD_VERSION_MICRO 1
|
||||
#define I2PD_VERSION_PATCH 0
|
||||
#define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO)
|
||||
#define VERSION I2PD_VERSION
|
||||
|
Loading…
Reference in New Issue
Block a user