Browse Source

Merge pull request #791 from PurpleI2P/openssl

recent changes
pull/63/merge
orignal 8 years ago committed by GitHub
parent
commit
040585bf3d
  1. 4
      Crypto.h
  2. 12
      DaemonLinux.cpp
  3. 4
      Family.cpp
  4. 29
      Gzip.cpp
  5. 30
      I2PControl.cpp
  6. 1
      I2PControl.h
  7. 2
      I2PTunnel.cpp
  8. 2
      I2PTunnel.h
  9. 2
      Makefile.linux
  10. 14
      Makefile.osx
  11. 88
      NTCPSession.cpp
  12. 3
      NTCPSession.h
  13. 8
      NetDb.cpp
  14. 30
      Reseed.cpp
  15. 2
      Reseed.h
  16. 14
      RouterContext.cpp
  17. 13
      RouterInfo.cpp
  18. 90
      SAM.cpp
  19. 9
      SAM.h
  20. 38
      Streaming.cpp
  21. 2
      Streaming.h
  22. 2
      TransitTunnel.h
  23. 7
      Transports.cpp
  24. 40
      android/jni/Android.mk
  25. BIN
      android/res/drawable/itoopie_notification_icon.png
  26. 2
      contrib/.gitignore
  27. 22
      contrib/build_mingw.cmd
  28. 84
      contrib/build_mingw.sh
  29. 2
      contrib/debian/README
  30. 2
      debian/i2pd.init
  31. BIN
      qt/i2pd_qt/android/res/drawable-hdpi/icon.png
  32. BIN
      qt/i2pd_qt/android/res/drawable/itoopie_notification_icon.png
  33. 4
      qt/i2pd_qt/i2pd_qt.pro

4
Crypto.h

@ -325,6 +325,10 @@ inline void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **pri
inline RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey) inline RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey)
{ return pkey->pkey.rsa; } { return pkey->pkey.rsa; }
// ssl
#define TLS_method TLSv1_method
#endif #endif
#endif #endif

12
DaemonLinux.cpp

@ -21,10 +21,13 @@ void handle_signal(int sig)
switch (sig) switch (sig)
{ {
case SIGHUP: case SIGHUP:
LogPrint(eLogInfo, "Daemon: Got SIGHUP, reopening logs and tunnel configuration..."); LogPrint(eLogInfo, "Daemon: Got SIGHUP, reopening tunnel configuration...");
i2p::log::Logger().Reopen ();
i2p::client::context.ReloadConfig(); i2p::client::context.ReloadConfig();
break; break;
case SIGUSR1:
LogPrint(eLogInfo, "Daemon: Got SIGUSR1, reopening logs...");
i2p::log::Logger().Reopen ();
break;
case SIGINT: case SIGINT:
if (i2p::context.AcceptsTunnels () && !Daemon.gracefulShutdownInterval) if (i2p::context.AcceptsTunnels () && !Daemon.gracefulShutdownInterval)
{ {
@ -77,7 +80,7 @@ namespace i2p
} }
// point std{in,out,err} descriptors to /dev/null // point std{in,out,err} descriptors to /dev/null
freopen("/dev/null", "r", stdin); freopen("/dev/null", "r", stdin);
freopen("/dev/null", "w", stdout); freopen("/dev/null", "w", stdout);
freopen("/dev/null", "w", stderr); freopen("/dev/null", "w", stderr);
} }
@ -102,7 +105,7 @@ namespace i2p
uint32_t cfsize; i2p::config::GetOption("limits.coresize", cfsize); uint32_t cfsize; i2p::config::GetOption("limits.coresize", cfsize);
if (cfsize) // core file size set if (cfsize) // core file size set
{ {
cfsize *= 1024; cfsize *= 1024;
getrlimit(RLIMIT_CORE, &limit); getrlimit(RLIMIT_CORE, &limit);
if (cfsize <= limit.rlim_max) { if (cfsize <= limit.rlim_max) {
limit.rlim_cur = cfsize; limit.rlim_cur = cfsize;
@ -153,6 +156,7 @@ namespace i2p
sigemptyset(&sa.sa_mask); sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART; sa.sa_flags = SA_RESTART;
sigaction(SIGHUP, &sa, 0); sigaction(SIGHUP, &sa, 0);
sigaction(SIGUSR1, &sa, 0);
sigaction(SIGABRT, &sa, 0); sigaction(SIGABRT, &sa, 0);
sigaction(SIGTERM, &sa, 0); sigaction(SIGTERM, &sa, 0);
sigaction(SIGINT, &sa, 0); sigaction(SIGINT, &sa, 0);

4
Family.cpp

@ -20,7 +20,7 @@ namespace data
void Families::LoadCertificate (const std::string& filename) void Families::LoadCertificate (const std::string& filename)
{ {
SSL_CTX * ctx = SSL_CTX_new (TLSv1_method ()); SSL_CTX * ctx = SSL_CTX_new (TLS_method ());
int ret = SSL_CTX_use_certificate_file (ctx, filename.c_str (), SSL_FILETYPE_PEM); int ret = SSL_CTX_use_certificate_file (ctx, filename.c_str (), SSL_FILETYPE_PEM);
if (ret) if (ret)
{ {
@ -135,7 +135,7 @@ namespace data
{ {
auto filename = i2p::fs::DataDirPath("family", (family + ".key")); auto filename = i2p::fs::DataDirPath("family", (family + ".key"));
std::string sig; std::string sig;
SSL_CTX * ctx = SSL_CTX_new (TLSv1_method ()); SSL_CTX * ctx = SSL_CTX_new (TLS_method ());
int ret = SSL_CTX_use_PrivateKey_file (ctx, filename.c_str (), SSL_FILETYPE_PEM); int ret = SSL_CTX_use_PrivateKey_file (ctx, filename.c_str (), SSL_FILETYPE_PEM);
if (ret) if (ret)
{ {

29
Gzip.cpp

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2016, The PurpleI2P Project * Copyright (c) 2013-2017, The PurpleI2P Project
* *
* This file is part of Purple i2pd project and licensed under BSD3 * This file is part of Purple i2pd project and licensed under BSD3
* *
@ -9,11 +9,13 @@
#include <inttypes.h> #include <inttypes.h>
#include <string.h> /* memset */ #include <string.h> /* memset */
#include <iostream> #include <iostream>
#include "Log.h"
#include "Gzip.h" #include "Gzip.h"
namespace i2p { namespace i2p
namespace data { {
namespace data
{
const size_t GZIP_CHUNK_SIZE = 16384; const size_t GZIP_CHUNK_SIZE = 16384;
GzipInflator::GzipInflator (): m_IsDirty (false) GzipInflator::GzipInflator (): m_IsDirty (false)
@ -36,9 +38,10 @@ namespace data {
m_Inflator.next_out = out; m_Inflator.next_out = out;
m_Inflator.avail_out = outLen; m_Inflator.avail_out = outLen;
int err; int err;
if ((err = inflate (&m_Inflator, Z_NO_FLUSH)) == Z_STREAM_END) { if ((err = inflate (&m_Inflator, Z_NO_FLUSH)) == Z_STREAM_END)
return outLen - m_Inflator.avail_out; return outLen - m_Inflator.avail_out;
} // else
LogPrint (eLogError, "Gzip: Inflate error ", err);
return 0; return 0;
} }
@ -49,17 +52,20 @@ namespace data {
m_Inflator.next_in = const_cast<uint8_t *>(in); m_Inflator.next_in = const_cast<uint8_t *>(in);
m_Inflator.avail_in = inLen; m_Inflator.avail_in = inLen;
int ret; int ret;
do { do
{
m_Inflator.next_out = out; m_Inflator.next_out = out;
m_Inflator.avail_out = GZIP_CHUNK_SIZE; m_Inflator.avail_out = GZIP_CHUNK_SIZE;
ret = inflate (&m_Inflator, Z_NO_FLUSH); ret = inflate (&m_Inflator, Z_NO_FLUSH);
if (ret < 0) { if (ret < 0)
{
inflateEnd (&m_Inflator); inflateEnd (&m_Inflator);
os.setstate(std::ios_base::failbit); os.setstate(std::ios_base::failbit);
break; break;
} }
os.write ((char *)out, GZIP_CHUNK_SIZE - m_Inflator.avail_out); os.write ((char *)out, GZIP_CHUNK_SIZE - m_Inflator.avail_out);
} while (!m_Inflator.avail_out); // more data to read }
while (!m_Inflator.avail_out); // more data to read
delete[] out; delete[] out;
} }
@ -99,9 +105,10 @@ namespace data {
m_Deflator.next_out = out; m_Deflator.next_out = out;
m_Deflator.avail_out = outLen; m_Deflator.avail_out = outLen;
int err; int err;
if ((err = deflate (&m_Deflator, Z_FINISH)) == Z_STREAM_END) { if ((err = deflate (&m_Deflator, Z_FINISH)) == Z_STREAM_END)
return outLen - m_Deflator.avail_out; return outLen - m_Deflator.avail_out;
} /* else */ // else
LogPrint (eLogError, "Gzip: Deflate error ", err);
return 0; return 0;
} }
} // data } // data

30
I2PControl.cpp

@ -25,6 +25,7 @@
#include "Transports.h" #include "Transports.h"
#include "version.h" #include "version.h"
#include "util.h" #include "util.h"
#include "ClientContext.h"
#include "I2PControl.h" #include "I2PControl.h"
namespace i2p namespace i2p
@ -78,6 +79,8 @@ namespace client
m_RouterInfoHandlers["i2p.router.net.bw.outbound.1s"] = &I2PControlService::OutboundBandwidth1S; m_RouterInfoHandlers["i2p.router.net.bw.outbound.1s"] = &I2PControlService::OutboundBandwidth1S;
m_RouterInfoHandlers["i2p.router.net.status"] = &I2PControlService::NetStatusHandler; m_RouterInfoHandlers["i2p.router.net.status"] = &I2PControlService::NetStatusHandler;
m_RouterInfoHandlers["i2p.router.net.tunnels.participating"] = &I2PControlService::TunnelsParticipatingHandler; m_RouterInfoHandlers["i2p.router.net.tunnels.participating"] = &I2PControlService::TunnelsParticipatingHandler;
m_RouterInfoHandlers["i2p.router.net.tunnels.successrate"] =
&I2PControlService::TunnelsSuccessRateHandler;
m_RouterInfoHandlers["i2p.router.net.total.received.bytes"] = &I2PControlService::NetTotalReceivedBytes; m_RouterInfoHandlers["i2p.router.net.total.received.bytes"] = &I2PControlService::NetTotalReceivedBytes;
m_RouterInfoHandlers["i2p.router.net.total.sent.bytes"] = &I2PControlService::NetTotalSentBytes; m_RouterInfoHandlers["i2p.router.net.total.sent.bytes"] = &I2PControlService::NetTotalSentBytes;
@ -187,13 +190,16 @@ namespace client
size_t bytes_transferred, std::shared_ptr<ssl_socket> socket, size_t bytes_transferred, std::shared_ptr<ssl_socket> socket,
std::shared_ptr<I2PControlBuffer> buf) std::shared_ptr<I2PControlBuffer> buf)
{ {
if (ecode) { if (ecode)
{
LogPrint (eLogError, "I2PControl: read error: ", ecode.message ()); LogPrint (eLogError, "I2PControl: read error: ", ecode.message ());
return; return;
} else { }
else
{
bool isHtml = !memcmp (buf->data (), "POST", 4);
try try
{ {
bool isHtml = !memcmp (buf->data (), "POST", 4);
std::stringstream ss; std::stringstream ss;
ss.write (buf->data (), bytes_transferred); ss.write (buf->data (), bytes_transferred);
if (isHtml) if (isHtml)
@ -237,7 +243,9 @@ namespace client
response << "{\"id\":" << id << ",\"result\":{"; response << "{\"id\":" << id << ",\"result\":{";
(this->*(it->second))(pt.get_child ("params"), response); (this->*(it->second))(pt.get_child ("params"), response);
response << "},\"jsonrpc\":\"2.0\"}"; response << "},\"jsonrpc\":\"2.0\"}";
} else { }
else
{
LogPrint (eLogWarning, "I2PControl: unknown method ", method); LogPrint (eLogWarning, "I2PControl: unknown method ", method);
response << "{\"id\":null,\"error\":"; response << "{\"id\":null,\"error\":";
response << "{\"code\":-32601,\"message\":\"Method not found\"},"; response << "{\"code\":-32601,\"message\":\"Method not found\"},";
@ -249,6 +257,11 @@ namespace client
catch (std::exception& ex) catch (std::exception& ex)
{ {
LogPrint (eLogError, "I2PControl: exception when handle request: ", ex.what ()); LogPrint (eLogError, "I2PControl: exception when handle request: ", ex.what ());
std::ostringstream response;
response << "{\"id\":null,\"error\":";
response << "{\"code\":-32700,\"message\":\"" << ex.what () << "\"},";
response << "\"jsonrpc\":\"2.0\"}";
SendResponse (socket, buf, response, isHtml);
} }
catch (...) catch (...)
{ {
@ -391,7 +404,8 @@ namespace client
void I2PControlService::StatusHandler (std::ostringstream& results) void I2PControlService::StatusHandler (std::ostringstream& results)
{ {
InsertParam (results, "i2p.router.status", "???"); // TODO: auto dest = i2p::client::context.GetSharedLocalDestination ();
InsertParam (results, "i2p.router.status", (dest && dest->IsReady ()) ? "1" : "0");
} }
void I2PControlService::NetDbKnownPeersHandler (std::ostringstream& results) void I2PControlService::NetDbKnownPeersHandler (std::ostringstream& results)
@ -415,6 +429,12 @@ namespace client
InsertParam (results, "i2p.router.net.tunnels.participating", transit); InsertParam (results, "i2p.router.net.tunnels.participating", transit);
} }
void I2PControlService::TunnelsSuccessRateHandler (std::ostringstream& results)
{
int rate = i2p::tunnel::tunnels.GetTunnelCreationSuccessRate ();
InsertParam (results, "i2p.router.net.tunnels.successrate", rate);
}
void I2PControlService::InboundBandwidth1S (std::ostringstream& results) void I2PControlService::InboundBandwidth1S (std::ostringstream& results)
{ {
double bw = i2p::transport::transports.GetInBandwidth (); double bw = i2p::transport::transports.GetInBandwidth ();

1
I2PControl.h

@ -81,6 +81,7 @@ namespace client
void NetDbActivePeersHandler (std::ostringstream& results); void NetDbActivePeersHandler (std::ostringstream& results);
void NetStatusHandler (std::ostringstream& results); void NetStatusHandler (std::ostringstream& results);
void TunnelsParticipatingHandler (std::ostringstream& results); void TunnelsParticipatingHandler (std::ostringstream& results);
void TunnelsSuccessRateHandler (std::ostringstream& results);
void InboundBandwidth1S (std::ostringstream& results); void InboundBandwidth1S (std::ostringstream& results);
void OutboundBandwidth1S (std::ostringstream& results); void OutboundBandwidth1S (std::ostringstream& results);
void NetTotalReceivedBytes (std::ostringstream& results); void NetTotalReceivedBytes (std::ostringstream& results);

2
I2PTunnel.cpp

@ -302,7 +302,7 @@ namespace client
if (m_NeedsWebIrc) if (m_NeedsWebIrc)
{ {
m_NeedsWebIrc = false; m_NeedsWebIrc = false;
m_OutPacket << "WEBIRC " << m_WebircPass << " cgiirc " << context.GetAddressBook ().ToAddress (m_From->GetIdentHash ()) << " 127.0.0.1\n"; m_OutPacket << "WEBIRC " << m_WebircPass << " cgiirc " << context.GetAddressBook ().ToAddress (m_From->GetIdentHash ()) << " " << GetSocket ()->local_endpoint ().address () << std::endl;
} }
m_InPacket.clear (); m_InPacket.clear ();

2
I2PTunnel.h

@ -53,6 +53,8 @@ namespace client
void HandleStreamReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleStreamReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred);
void HandleConnect (const boost::system::error_code& ecode); void HandleConnect (const boost::system::error_code& ecode);
std::shared_ptr<const boost::asio::ip::tcp::socket> GetSocket () const { return m_Socket; };
private: private:
uint8_t m_Buffer[I2P_TUNNEL_CONNECTION_BUFFER_SIZE], m_StreamBuffer[I2P_TUNNEL_CONNECTION_BUFFER_SIZE]; uint8_t m_Buffer[I2P_TUNNEL_CONNECTION_BUFFER_SIZE], m_StreamBuffer[I2P_TUNNEL_CONNECTION_BUFFER_SIZE];

2
Makefile.linux

@ -1,5 +1,5 @@
# set defaults instead redefine # set defaults instead redefine
CXXFLAGS ?= -g -Wall -Wextra -Wno-unused-parameter -pedantic CXXFLAGS ?= -g -Wall -Wextra -Wno-unused-parameter -pedantic -Wno-misleading-indentation
INCFLAGS ?= INCFLAGS ?=
## NOTE: The NEEDED_CXXFLAGS are here so that custom CXXFLAGS can be specified at build time ## NOTE: The NEEDED_CXXFLAGS are here so that custom CXXFLAGS can be specified at build time

14
Makefile.osx vendored

@ -1,11 +1,11 @@
CXX = clang++ CXX = clang++
CXXFLAGS = -g -Wall -std=c++11 -DMAC_OSX CXXFLAGS = -Os -Wall -std=c++11 -DMAC_OSX
#CXXFLAGS = -g -O2 -Wall -std=c++11 #CXXFLAGS = -g -O2 -Wall -std=c++11
INCFLAGS = -I/usr/local/include -I/usr/local/ssl/include INCFLAGS = -I/usr/local/include
LDFLAGS = -Wl,-rpath,/usr/local/lib -L/usr/local/lib -L/usr/local/ssl/lib LDFLAGS = -Wl,-rpath,/usr/local/lib -L/usr/local/lib
ifeq ($(USE_STATIC),yes) ifeq ($(USE_STATIC),yes)
LDLIBS = -lz -lcrypto -lssl /usr/local/lib/libboost_system.a /usr/local/lib/libboost_date_time.a /usr/local/lib/libboost_filesystem.a /usr/local/lib/libboost_program_options.a -lpthread LDLIBS = -lz /usr/local/lib/libcrypto.a /usr/local/lib/libssl.a /usr/local/lib/libboost_system.a /usr/local/lib/libboost_date_time.a /usr/local/lib/libboost_filesystem.a /usr/local/lib/libboost_program_options.a -lpthread
else else
LDLIBS = -lz -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread LDLIBS = -lz -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
endif endif
@ -15,11 +15,13 @@ ifeq ($(USE_UPNP),yes)
CXXFLAGS += -DUSE_UPNP CXXFLAGS += -DUSE_UPNP
endif endif
ifeq ($(USE_AESNI),yes) ifeq ($(USE_AESNI),1)
CXXFLAGS += -maes -DAESNI CXXFLAGS += -maes -DAESNI
else
CXXFLAGS += -msse
endif endif
ifeq ($(USE_AVX),yes) ifeq ($(USE_AVX),1)
CXXFLAGS += -mavx CXXFLAGS += -mavx
endif endif

88
NTCPSession.cpp

@ -1,5 +1,6 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <future>
#include "I2PEndian.h" #include "I2PEndian.h"
#include "Base.h" #include "Base.h"
@ -35,12 +36,12 @@ namespace transport
delete m_Establisher; delete m_Establisher;
} }
void NTCPSession::CreateAESKey (uint8_t * pubKey, i2p::crypto::AESKey& key) void NTCPSession::CreateAESKey (uint8_t * pubKey)
{ {
uint8_t sharedKey[256]; uint8_t sharedKey[256];
m_DHKeysPair->Agree (pubKey, sharedKey); m_DHKeysPair->Agree (pubKey, sharedKey); // time consuming operation
uint8_t * aesKey = key; i2p::crypto::AESKey aesKey;
if (sharedKey[0] & 0x80) if (sharedKey[0] & 0x80)
{ {
aesKey[0] = 0; aesKey[0] = 0;
@ -63,6 +64,9 @@ namespace transport
} }
memcpy (aesKey, nonZero, 32); memcpy (aesKey, nonZero, 32);
} }
m_Decryption.SetKey (aesKey);
m_Encryption.SetKey (aesKey);
} }
void NTCPSession::Done () void NTCPSession::Done ()
@ -164,14 +168,24 @@ namespace transport
} }
} }
SendPhase2 (); // TODO: check for number of pending keys
auto s = shared_from_this ();
auto keyCreated = std::async (std::launch::async, [s] ()
{
if (!s->m_DHKeysPair)
s->m_DHKeysPair = transports.GetNextDHKeysPair ();
s->CreateAESKey (s->m_Establisher->phase1.pubKey);
}).share ();
m_Server.GetService ().post ([s, keyCreated]()
{
keyCreated.get ();
s->SendPhase2 ();
});
} }
} }
void NTCPSession::SendPhase2 () void NTCPSession::SendPhase2 ()
{ {
if (!m_DHKeysPair)
m_DHKeysPair = transports.GetNextDHKeysPair ();
const uint8_t * y = m_DHKeysPair->GetPublicKey (); const uint8_t * y = m_DHKeysPair->GetPublicKey ();
memcpy (m_Establisher->phase2.pubKey, y, 256); memcpy (m_Establisher->phase2.pubKey, y, 256);
uint8_t xy[512]; uint8_t xy[512];
@ -182,11 +196,7 @@ namespace transport
memcpy (m_Establisher->phase2.encrypted.timestamp, &tsB, 4); memcpy (m_Establisher->phase2.encrypted.timestamp, &tsB, 4);
RAND_bytes (m_Establisher->phase2.encrypted.filler, 12); RAND_bytes (m_Establisher->phase2.encrypted.filler, 12);
i2p::crypto::AESKey aesKey;
CreateAESKey (m_Establisher->phase1.pubKey, aesKey);
m_Encryption.SetKey (aesKey);
m_Encryption.SetIV (y + 240); m_Encryption.SetIV (y + 240);
m_Decryption.SetKey (aesKey);
m_Decryption.SetIV (m_Establisher->phase1.HXxorHI + 16); m_Decryption.SetIV (m_Establisher->phase1.HXxorHI + 16);
m_Encryption.Encrypt ((uint8_t *)&m_Establisher->phase2.encrypted, sizeof(m_Establisher->phase2.encrypted), (uint8_t *)&m_Establisher->phase2.encrypted); m_Encryption.Encrypt ((uint8_t *)&m_Establisher->phase2.encrypted, sizeof(m_Establisher->phase2.encrypted), (uint8_t *)&m_Establisher->phase2.encrypted);
@ -229,30 +239,42 @@ namespace transport
} }
else else
{ {
i2p::crypto::AESKey aesKey; auto s = shared_from_this ();
CreateAESKey (m_Establisher->phase2.pubKey, aesKey); // create AES key in separate thread
m_Decryption.SetKey (aesKey); auto keyCreated = std::async (std::launch::async, [s] ()
m_Decryption.SetIV (m_Establisher->phase2.pubKey + 240); {
m_Encryption.SetKey (aesKey); s->CreateAESKey (s->m_Establisher->phase2.pubKey);
m_Encryption.SetIV (m_Establisher->phase1.HXxorHI + 16); }).share (); // TODO: use move capture in C++ 14 instead shared_future
// let other operations execute while a key gets created
m_Decryption.Decrypt((uint8_t *)&m_Establisher->phase2.encrypted, sizeof(m_Establisher->phase2.encrypted), (uint8_t *)&m_Establisher->phase2.encrypted); m_Server.GetService ().post ([s, keyCreated]()
// verify {
uint8_t xy[512]; keyCreated.get (); // we might wait if no more pending operations
memcpy (xy, m_DHKeysPair->GetPublicKey (), 256); s->HandlePhase2 ();
memcpy (xy + 256, m_Establisher->phase2.pubKey, 256); });
uint8_t digest[32]; }
SHA256 (xy, 512, digest); }
if (memcmp(m_Establisher->phase2.encrypted.hxy, digest, 32))
{ void NTCPSession::HandlePhase2 ()
LogPrint (eLogError, "NTCP: Phase 2 process error: incorrect hash"); {
transports.ReuseDHKeysPair (m_DHKeysPair); m_Decryption.SetIV (m_Establisher->phase2.pubKey + 240);
m_DHKeysPair = nullptr; m_Encryption.SetIV (m_Establisher->phase1.HXxorHI + 16);
Terminate ();
return ; m_Decryption.Decrypt((uint8_t *)&m_Establisher->phase2.encrypted, sizeof(m_Establisher->phase2.encrypted), (uint8_t *)&m_Establisher->phase2.encrypted);
} // verify
SendPhase3 (); uint8_t xy[512];
memcpy (xy, m_DHKeysPair->GetPublicKey (), 256);
memcpy (xy + 256, m_Establisher->phase2.pubKey, 256);
uint8_t digest[32];
SHA256 (xy, 512, digest);
if (memcmp(m_Establisher->phase2.encrypted.hxy, digest, 32))
{
LogPrint (eLogError, "NTCP: Phase 2 process error: incorrect hash");
transports.ReuseDHKeysPair (m_DHKeysPair);
m_DHKeysPair = nullptr;
Terminate ();
return ;
} }
SendPhase3 ();
} }
void NTCPSession::SendPhase3 () void NTCPSession::SendPhase3 ()

3
NTCPSession.h

@ -67,12 +67,13 @@ namespace transport
void SendTimeSyncMessage (); void SendTimeSyncMessage ();
void SetIsEstablished (bool isEstablished) { m_IsEstablished = isEstablished; } void SetIsEstablished (bool isEstablished) { m_IsEstablished = isEstablished; }
void CreateAESKey (uint8_t * pubKey, i2p::crypto::AESKey& key); void CreateAESKey (uint8_t * pubKey);
// client // client
void SendPhase3 (); void SendPhase3 ();
void HandlePhase1Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandlePhase1Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred);
void HandlePhase2Received (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandlePhase2Received (const boost::system::error_code& ecode, std::size_t bytes_transferred);
void HandlePhase2 ();
void HandlePhase3Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsA); void HandlePhase3Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsA);
void HandlePhase4Received (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsA); void HandlePhase4Received (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsA);

8
NetDb.cpp

@ -583,7 +583,7 @@ namespace data
IdentHash ident (buf + DATABASE_STORE_KEY_OFFSET); IdentHash ident (buf + DATABASE_STORE_KEY_OFFSET);
if (ident.IsZero ()) if (ident.IsZero ())
{ {
LogPrint (eLogError, "NetDb: database store with zero ident, dropped"); LogPrint (eLogDebug, "NetDb: database store with zero ident, dropped");
return; return;
} }
uint32_t replyToken = bufbe32toh (buf + DATABASE_STORE_REPLY_TOKEN_OFFSET); uint32_t replyToken = bufbe32toh (buf + DATABASE_STORE_REPLY_TOKEN_OFFSET);
@ -602,14 +602,14 @@ namespace data
if (outbound) if (outbound)
outbound->SendTunnelDataMsg (buf + offset, tunnelID, deliveryStatus); outbound->SendTunnelDataMsg (buf + offset, tunnelID, deliveryStatus);
else else
LogPrint (eLogError, "NetDb: no outbound tunnels for DatabaseStore reply found"); LogPrint (eLogWarning, "NetDb: no outbound tunnels for DatabaseStore reply found");
} }
offset += 32; offset += 32;
} }
// we must send reply back before this check // we must send reply back before this check
if (ident == i2p::context.GetIdentHash ()) if (ident == i2p::context.GetIdentHash ())
{ {
LogPrint (eLogError, "NetDb: database store with own RouterInfo received, dropped"); LogPrint (eLogDebug, "NetDb: database store with own RouterInfo received, dropped");
return; return;
} }
size_t payloadOffset = offset; size_t payloadOffset = offset;
@ -636,7 +636,7 @@ namespace data
updated = AddRouterInfo (ident, uncompressed, uncompressedSize); updated = AddRouterInfo (ident, uncompressed, uncompressedSize);
else else
{ {
LogPrint (eLogError, "NetDb: decompression failed ", uncompressedSize); LogPrint (eLogInfo, "NetDb: decompression failed ", uncompressedSize);
return; return;
} }
} }

30
Reseed.cpp

@ -83,10 +83,24 @@ namespace data
} }
} }
int Reseeder::ProcessZIPFile (const char * filename)
{
std::ifstream s(filename, std::ifstream::binary);
if (s.is_open ())
{
s.seekg (0, std::ios::end);
auto len = s.tellg ();
s.seekg (0, std::ios::beg);
return ProcessZIPStream (s, len);
}
else
{
LogPrint (eLogError, "Reseed: Can't open file ", filename);
return 0;
}
}
const char SU3_MAGIC_NUMBER[]="I2Psu3"; const char SU3_MAGIC_NUMBER[]="I2Psu3";
const uint32_t ZIP_HEADER_SIGNATURE = 0x04034B50;
const uint32_t ZIP_CENTRAL_DIRECTORY_HEADER_SIGNATURE = 0x02014B50;
const uint16_t ZIP_BIT_FLAG_DATA_DESCRIPTOR = 0x0008;
int Reseeder::ProcessSU3Stream (std::istream& s) int Reseeder::ProcessSU3Stream (std::istream& s)
{ {
char magicNumber[7]; char magicNumber[7];
@ -194,6 +208,14 @@ namespace data
} }
// handle content // handle content
return ProcessZIPStream (s, contentLength);
}
const uint32_t ZIP_HEADER_SIGNATURE = 0x04034B50;
const uint32_t ZIP_CENTRAL_DIRECTORY_HEADER_SIGNATURE = 0x02014B50;
const uint16_t ZIP_BIT_FLAG_DATA_DESCRIPTOR = 0x0008;
int Reseeder::ProcessZIPStream (std::istream& s, uint64_t contentLength)
{
int numFiles = 0; int numFiles = 0;
size_t contentPos = s.tellg (); size_t contentPos = s.tellg ();
while (!s.eof ()) while (!s.eof ())
@ -362,7 +384,7 @@ namespace data
void Reseeder::LoadCertificate (const std::string& filename) void Reseeder::LoadCertificate (const std::string& filename)
{ {
SSL_CTX * ctx = SSL_CTX_new (TLSv1_method ()); SSL_CTX * ctx = SSL_CTX_new (TLS_method ());
int ret = SSL_CTX_use_certificate_file (ctx, filename.c_str (), SSL_FILETYPE_PEM); int ret = SSL_CTX_use_certificate_file (ctx, filename.c_str (), SSL_FILETYPE_PEM);
if (ret) if (ret)
{ {

2
Reseed.h

@ -31,7 +31,9 @@ namespace data
int ReseedFromSU3 (const std::string& url); int ReseedFromSU3 (const std::string& url);
int ProcessSU3File (const char * filename); int ProcessSU3File (const char * filename);
int ProcessZIPFile (const char * filename);
int ProcessSU3Stream (std::istream& s); int ProcessSU3Stream (std::istream& s);
int ProcessZIPStream (std::istream& s, uint64_t contentLength);
bool FindZipDataDescriptor (std::istream& s); bool FindZipDataDescriptor (std::istream& s);

14
RouterContext.cpp

@ -205,7 +205,7 @@ namespace i2p
void RouterContext::SetBandwidth (char L) { void RouterContext::SetBandwidth (char L) {
uint16_t limit = 0; uint16_t limit = 0;
enum { low, high, extra } type = high; enum { low, high, extra, unlim } type = high;
/* detect parameters */ /* detect parameters */
switch (L) switch (L)
{ {
@ -215,7 +215,7 @@ namespace i2p
case i2p::data::CAPS_FLAG_HIGH_BANDWIDTH2 : limit = 128; type = high; break; case i2p::data::CAPS_FLAG_HIGH_BANDWIDTH2 : limit = 128; type = high; break;
case i2p::data::CAPS_FLAG_HIGH_BANDWIDTH3 : limit = 256; type = high; break; case i2p::data::CAPS_FLAG_HIGH_BANDWIDTH3 : limit = 256; type = high; break;
case i2p::data::CAPS_FLAG_EXTRA_BANDWIDTH1 : limit = 2048; type = extra; break; case i2p::data::CAPS_FLAG_EXTRA_BANDWIDTH1 : limit = 2048; type = extra; break;
case i2p::data::CAPS_FLAG_EXTRA_BANDWIDTH2 : limit = 9999; type = extra; break; case i2p::data::CAPS_FLAG_EXTRA_BANDWIDTH2 : limit = 9999; type = unlim; break;
default: default:
limit = 48; type = low; limit = 48; type = low;
} }
@ -226,7 +226,8 @@ namespace i2p
switch (type) switch (type)
{ {
case low : /* not set */; break; case low : /* not set */; break;
case extra : caps |= i2p::data::RouterInfo::eExtraBandwidth; // no break here case extra : caps |= i2p::data::RouterInfo::eExtraBandwidth; break; // 'P'
case unlim : caps |= i2p::data::RouterInfo::eExtraBandwidth; // no break here, extra + high means 'X'
case high : caps |= i2p::data::RouterInfo::eHighBandwidth; break; case high : caps |= i2p::data::RouterInfo::eHighBandwidth; break;
} }
m_RouterInfo.SetCaps (caps); m_RouterInfo.SetCaps (caps);
@ -253,7 +254,12 @@ namespace i2p
void RouterContext::SetUnreachable () void RouterContext::SetUnreachable ()
{ {
// set caps // set caps
m_RouterInfo.SetCaps (i2p::data::RouterInfo::eUnreachable | i2p::data::RouterInfo::eSSUTesting); // LU, B uint8_t caps = m_RouterInfo.GetCaps ();
caps &= ~i2p::data::RouterInfo::eReachable;
caps |= i2p::data::RouterInfo::eUnreachable;
caps &= ~i2p::data::RouterInfo::eFloodfill; // can't be floodfill
caps &= ~i2p::data::RouterInfo::eSSUIntroducer; // can't be introducer
m_RouterInfo.SetCaps (caps);
// remove NTCP address // remove NTCP address
auto& addresses = m_RouterInfo.GetAddresses (); auto& addresses = m_RouterInfo.GetAddresses ();
for (auto it = addresses.begin (); it != addresses.end (); ++it) for (auto it = addresses.begin (); it != addresses.end (); ++it)

13
RouterInfo.cpp

@ -376,14 +376,21 @@ namespace data
std::string caps; std::string caps;
if (m_Caps & eFloodfill) if (m_Caps & eFloodfill)
{ {
if (m_Caps & eExtraBandwidth) caps += CAPS_FLAG_EXTRA_BANDWIDTH1; // 'P' if (m_Caps & eExtraBandwidth) caps += (m_Caps & eHighBandwidth) ?
CAPS_FLAG_EXTRA_BANDWIDTH2 : // 'X'
CAPS_FLAG_EXTRA_BANDWIDTH1; // 'P'
caps += CAPS_FLAG_HIGH_BANDWIDTH3; // 'O' caps += CAPS_FLAG_HIGH_BANDWIDTH3; // 'O'
caps += CAPS_FLAG_FLOODFILL; // floodfill caps += CAPS_FLAG_FLOODFILL; // floodfill
} }
else else
{ {
if (m_Caps & eExtraBandwidth) caps += CAPS_FLAG_EXTRA_BANDWIDTH1; // 'P' if (m_Caps & eExtraBandwidth)
caps += (m_Caps & eHighBandwidth) ? CAPS_FLAG_HIGH_BANDWIDTH3 /* 'O' */: CAPS_FLAG_LOW_BANDWIDTH2 /* 'L' */; // bandwidth {
caps += (m_Caps & eHighBandwidth) ? CAPS_FLAG_EXTRA_BANDWIDTH2 /* 'X' */ : CAPS_FLAG_EXTRA_BANDWIDTH1; /*'P' */
caps += CAPS_FLAG_HIGH_BANDWIDTH3; // 'O'
}
else
caps += (m_Caps & eHighBandwidth) ? CAPS_FLAG_HIGH_BANDWIDTH3 /* 'O' */: CAPS_FLAG_LOW_BANDWIDTH2 /* 'L' */; // bandwidth
} }
if (m_Caps & eHidden) caps += CAPS_FLAG_HIDDEN; // hidden if (m_Caps & eHidden) caps += CAPS_FLAG_HIDDEN; // hidden
if (m_Caps & eReachable) caps += CAPS_FLAG_REACHABLE; // reachable if (m_Caps & eReachable) caps += CAPS_FLAG_REACHABLE; // reachable

90
SAM.cpp

@ -121,7 +121,7 @@ namespace client
size_t l = snprintf (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_HANDSHAKE_REPLY, version.c_str ()); size_t l = snprintf (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_HANDSHAKE_REPLY, version.c_str ());
#endif #endif
boost::asio::async_write (m_Socket, boost::asio::buffer (m_Buffer, l), boost::asio::transfer_all (), boost::asio::async_write (m_Socket, boost::asio::buffer (m_Buffer, l), boost::asio::transfer_all (),
std::bind(&SAMSocket::HandleHandshakeReplySent, shared_from_this (), std::bind(&SAMSocket::HandleHandshakeReplySent, shared_from_this (),
std::placeholders::_1, std::placeholders::_2)); std::placeholders::_1, std::placeholders::_2));
} }
else else
@ -252,6 +252,7 @@ namespace client
Terminate (); Terminate ();
} }
} }
else else
{ {
LogPrint (eLogWarning, "SAM: incomplete message ", bytes_transferred); LogPrint (eLogWarning, "SAM: incomplete message ", bytes_transferred);
@ -278,6 +279,29 @@ namespace client
return; return;
} }
std::shared_ptr<boost::asio::ip::udp::endpoint> forward = nullptr;
if (style == SAM_VALUE_DATAGRAM && params.find(SAM_VALUE_HOST) != params.end() && params.find(SAM_VALUE_PORT) != params.end())
{
// udp forward selected
boost::system::error_code e;
// TODO: support hostnames in udp forward
auto addr = boost::asio::ip::address::from_string(params[SAM_VALUE_HOST], e);
if (e)
{
// not an ip address
SendI2PError("Invalid IP Address in HOST");
return;
}
auto port = std::stoi(params[SAM_VALUE_PORT]);
if (port == -1)
{
SendI2PError("Invalid port");
return;
}
forward = std::make_shared<boost::asio::ip::udp::endpoint>(addr, port);
}
// create destination // create destination
m_Session = m_Owner.CreateSession (id, destination == SAM_VALUE_TRANSIENT ? "" : destination, &params); m_Session = m_Owner.CreateSession (id, destination == SAM_VALUE_TRANSIENT ? "" : destination, &params);
if (m_Session) if (m_Session)
@ -285,6 +309,7 @@ namespace client
m_SocketType = eSAMSocketTypeSession; m_SocketType = eSAMSocketTypeSession;
if (style == SAM_VALUE_DATAGRAM) if (style == SAM_VALUE_DATAGRAM)
{ {
m_Session->UDPEndpoint = forward;
auto dest = m_Session->localDestination->CreateDatagramDestination (); auto dest = m_Session->localDestination->CreateDatagramDestination ();
dest->SetReceiver (std::bind (&SAMSocket::HandleI2PDatagramReceive, shared_from_this (), dest->SetReceiver (std::bind (&SAMSocket::HandleI2PDatagramReceive, shared_from_this (),
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5)); std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5));
@ -491,7 +516,18 @@ namespace client
} }
} }
void SAMSocket::HandleNamingLookupLeaseSetRequestComplete (std::shared_ptr<i2p::data::LeaseSet> leaseSet, i2p::data::IdentHash ident) void SAMSocket::SendI2PError(const std::string & msg)
{
LogPrint (eLogError, "SAM: i2p error ", msg);
#ifdef _MSC_VER
size_t len = sprintf_s (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_SESSION_STATUS_I2P_ERROR, msg.c_str());
#else
size_t len = snprintf (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_SESSION_STATUS_I2P_ERROR, msg.c_str());
#endif
SendMessageReply (m_Buffer, len, true);
}
void SAMSocket::HandleNamingLookupLeaseSetRequestComplete (std::shared_ptr<i2p::data::LeaseSet> leaseSet, i2p::data::IdentHash ident)
{ {
if (leaseSet) if (leaseSet)
{ {
@ -692,23 +728,45 @@ namespace client
{ {
LogPrint (eLogDebug, "SAM: datagram received ", len); LogPrint (eLogDebug, "SAM: datagram received ", len);
auto base64 = from.ToBase64 (); auto base64 = from.ToBase64 ();
auto ep = m_Session->UDPEndpoint;
if (ep)
{
// udp forward enabled
size_t bsz = base64.size();
size_t sz = bsz + 1 + len;
// build datagram body
uint8_t * data = new uint8_t[sz];
// Destination
memcpy(data, base64.c_str(), bsz);
// linefeed
data[bsz] = '\n';
// Payload
memcpy(data+bsz+1, buf, len);
// send to remote endpoint
m_Owner.SendTo(data, sz, ep);
delete [] data;
}
else
{
#ifdef _MSC_VER #ifdef _MSC_VER
size_t l = sprintf_s ((char *)m_StreamBuffer, SAM_SOCKET_BUFFER_SIZE, SAM_DATAGRAM_RECEIVED, base64.c_str (), (long unsigned int)len); size_t l = sprintf_s ((char *)m_StreamBuffer, SAM_SOCKET_BUFFER_SIZE, SAM_DATAGRAM_RECEIVED, base64.c_str (), (long unsigned int)len);
#else #else
size_t l = snprintf ((char *)m_StreamBuffer, SAM_SOCKET_BUFFER_SIZE, SAM_DATAGRAM_RECEIVED, base64.c_str (), (long unsigned int)len); size_t l = snprintf ((char *)m_StreamBuffer, SAM_SOCKET_BUFFER_SIZE, SAM_DATAGRAM_RECEIVED, base64.c_str (), (long unsigned int)len);
#endif #endif
if (len < SAM_SOCKET_BUFFER_SIZE - l) if (len < SAM_SOCKET_BUFFER_SIZE - l)
{ {
memcpy (m_StreamBuffer + l, buf, len); memcpy (m_StreamBuffer + l, buf, len);
boost::asio::async_write (m_Socket, boost::asio::buffer (m_StreamBuffer, len + l), boost::asio::async_write (m_Socket, boost::asio::buffer (m_StreamBuffer, len + l),
std::bind (&SAMSocket::HandleWriteI2PData, shared_from_this (), std::placeholders::_1)); std::bind (&SAMSocket::HandleWriteI2PData, shared_from_this (), std::placeholders::_1));
}
else
LogPrint (eLogWarning, "SAM: received datagram size ", len," exceeds buffer");
} }
else
LogPrint (eLogWarning, "SAM: received datagram size ", len," exceeds buffer");
} }
SAMSession::SAMSession (std::shared_ptr<ClientDestination> dest): SAMSession::SAMSession (std::shared_ptr<ClientDestination> dest):
localDestination (dest) localDestination (dest),
UDPEndpoint(nullptr)
{ {
} }
@ -873,6 +931,14 @@ namespace client
return nullptr; return nullptr;
} }
void SAMBridge::SendTo(const uint8_t * buf, size_t len, std::shared_ptr<boost::asio::ip::udp::endpoint> remote)
{
if(remote)
{
m_DatagramSocket.send_to(boost::asio::buffer(buf, len), *remote);
}
}
void SAMBridge::ReceiveDatagram () void SAMBridge::ReceiveDatagram ()
{ {
m_DatagramSocket.async_receive_from ( m_DatagramSocket.async_receive_from (

9
SAM.h

@ -29,6 +29,7 @@ namespace client
const char SAM_SESSION_CREATE_DUPLICATED_ID[] = "SESSION STATUS RESULT=DUPLICATED_ID\n"; const char SAM_SESSION_CREATE_DUPLICATED_ID[] = "SESSION STATUS RESULT=DUPLICATED_ID\n";
const char SAM_SESSION_CREATE_DUPLICATED_DEST[] = "SESSION STATUS RESULT=DUPLICATED_DEST\n"; const char SAM_SESSION_CREATE_DUPLICATED_DEST[] = "SESSION STATUS RESULT=DUPLICATED_DEST\n";
const char SAM_SESSION_STATUS_INVALID_KEY[] = "SESSION STATUS RESULT=INVALID_KEY\n"; const char SAM_SESSION_STATUS_INVALID_KEY[] = "SESSION STATUS RESULT=INVALID_KEY\n";
const char SAM_SESSION_STATUS_I2P_ERROR[] = "SESSION STATUS RESULT=I2P_ERROR MESSAGE=%s\n";
const char SAM_STREAM_CONNECT[] = "STREAM CONNECT"; const char SAM_STREAM_CONNECT[] = "STREAM CONNECT";
const char SAM_STREAM_STATUS_OK[] = "STREAM STATUS RESULT=OK\n"; const char SAM_STREAM_STATUS_OK[] = "STREAM STATUS RESULT=OK\n";
const char SAM_STREAM_STATUS_INVALID_ID[] = "STREAM STATUS RESULT=INVALID_ID\n"; const char SAM_STREAM_STATUS_INVALID_ID[] = "STREAM STATUS RESULT=INVALID_ID\n";
@ -59,6 +60,8 @@ namespace client
const char SAM_VALUE_RAW[] = "RAW"; const char SAM_VALUE_RAW[] = "RAW";
const char SAM_VALUE_TRUE[] = "true"; const char SAM_VALUE_TRUE[] = "true";
const char SAM_VALUE_FALSE[] = "false"; const char SAM_VALUE_FALSE[] = "false";
const char SAM_VALUE_HOST[] = "HOST";
const char SAM_VALUE_PORT[] = "PORT";
enum SAMSocketType enum SAMSocketType
{ {
@ -106,6 +109,7 @@ namespace client
void ProcessStreamAccept (char * buf, size_t len); void ProcessStreamAccept (char * buf, size_t len);
void ProcessDestGenerate (); void ProcessDestGenerate ();
void ProcessNamingLookup (char * buf, size_t len); void ProcessNamingLookup (char * buf, size_t len);
void SendI2PError(const std::string & msg);
size_t ProcessDatagramSend (char * buf, size_t len, const char * data); // from SAM 1.0 size_t ProcessDatagramSend (char * buf, size_t len, const char * data); // from SAM 1.0
void ExtractParams (char * buf, std::map<std::string, std::string>& params); void ExtractParams (char * buf, std::map<std::string, std::string>& params);
@ -135,6 +139,7 @@ namespace client
{ {
std::shared_ptr<ClientDestination> localDestination; std::shared_ptr<ClientDestination> localDestination;
std::list<std::shared_ptr<SAMSocket> > m_Sockets; std::list<std::shared_ptr<SAMSocket> > m_Sockets;
std::shared_ptr<boost::asio::ip::udp::endpoint> UDPEndpoint;
std::mutex m_SocketsMutex; std::mutex m_SocketsMutex;
/** safely add a socket to this session */ /** safely add a socket to this session */
@ -181,6 +186,9 @@ namespace client
void CloseSession (const std::string& id); void CloseSession (const std::string& id);
std::shared_ptr<SAMSession> FindSession (const std::string& id) const; std::shared_ptr<SAMSession> FindSession (const std::string& id) const;
/** send raw data to remote endpoint from our UDP Socket */
void SendTo(const uint8_t * buf, size_t len, std::shared_ptr<boost::asio::ip::udp::endpoint> remote);
private: private:
void Run (); void Run ();
@ -212,4 +220,3 @@ namespace client
} }
#endif #endif

38
Streaming.cpp

@ -36,21 +36,7 @@ namespace stream
Stream::~Stream () Stream::~Stream ()
{ {
while (!m_ReceiveQueue.empty ()) CleanUp ();
{
auto packet = m_ReceiveQueue.front ();
m_ReceiveQueue.pop ();
m_LocalDestination.DeletePacket (packet);
}
for (auto it: m_SentPackets)
m_LocalDestination.DeletePacket (it);
m_SentPackets.clear ();
for (auto it: m_SavedPackets)
m_LocalDestination.DeletePacket (it);
m_SavedPackets.clear ();
LogPrint (eLogDebug, "Streaming: Stream deleted"); LogPrint (eLogDebug, "Streaming: Stream deleted");
} }
@ -65,9 +51,29 @@ namespace stream
m_SendHandler = nullptr; m_SendHandler = nullptr;
handler (boost::asio::error::make_error_code (boost::asio::error::operation_aborted)); handler (boost::asio::error::make_error_code (boost::asio::error::operation_aborted));
} }
//CleanUp (); /* Need to recheck - broke working on windows */
m_LocalDestination.DeleteStream (shared_from_this ()); m_LocalDestination.DeleteStream (shared_from_this ());
} }
void Stream::CleanUp ()
{
m_SendBuffer.str ("");
while (!m_ReceiveQueue.empty ())
{
auto packet = m_ReceiveQueue.front ();
m_ReceiveQueue.pop ();
m_LocalDestination.DeletePacket (packet);
}
for (auto it: m_SentPackets)
m_LocalDestination.DeletePacket (it);
m_SentPackets.clear ();
for (auto it: m_SavedPackets)
m_LocalDestination.DeletePacket (it);
m_SavedPackets.clear ();
}
void Stream::HandleNextPacket (Packet * packet) void Stream::HandleNextPacket (Packet * packet)
{ {
m_NumReceivedBytes += packet->GetLength (); m_NumReceivedBytes += packet->GetLength ();
@ -889,7 +895,7 @@ namespace stream
it->second->HandleNextPacket (packet); it->second->HandleNextPacket (packet);
else else
{ {
LogPrint (eLogError, "Streaming: Unknown stream sSID=", sendStreamID); LogPrint (eLogInfo, "Streaming: Unknown stream sSID=", sendStreamID);
DeletePacket (packet); DeletePacket (packet);
} }
} }

2
Streaming.h

@ -158,6 +158,8 @@ namespace stream
private: private:
void CleanUp ();
void SendBuffer (); void SendBuffer ();
void SendQuickAck (); void SendQuickAck ();
void SendClose (); void SendClose ();

2
TransitTunnel.h

@ -85,6 +85,8 @@ namespace tunnel
TransitTunnel (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey), TransitTunnel (receiveTunnelID, nextIdent, nextTunnelID, layerKey, ivKey),
m_Endpoint (false) {}; // transit endpoint is always outbound m_Endpoint (false) {}; // transit endpoint is always outbound
void Cleanup () { m_Endpoint.Cleanup (); }
void HandleTunnelDataMsg (std::shared_ptr<const i2p::I2NPMessage> tunnelMsg); void HandleTunnelDataMsg (std::shared_ptr<const i2p::I2NPMessage> tunnelMsg);
size_t GetNumTransmittedBytes () const { return m_Endpoint.GetNumReceivedBytes (); } size_t GetNumTransmittedBytes () const { return m_Endpoint.GetNumReceivedBytes (); }

7
Transports.cpp

@ -101,8 +101,9 @@ namespace transport
void DHKeysPairSupplier::Return (std::shared_ptr<i2p::crypto::DHKeys> pair) void DHKeysPairSupplier::Return (std::shared_ptr<i2p::crypto::DHKeys> pair)
{ {
std::unique_lock<std::mutex> l(m_AcquiredMutex); std::unique_lock<std::mutex>l(m_AcquiredMutex);
m_Queue.push (pair); if ((int)m_Queue.size () < 2*m_QueueSize)
m_Queue.push (pair);
} }
Transports transports; Transports transports;
@ -417,7 +418,7 @@ namespace transport
} }
else else
{ {
LogPrint (eLogError, "Transports: RouterInfo not found, Failed to send messages"); LogPrint (eLogWarning, "Transports: RouterInfo not found, Failed to send messages");
std::unique_lock<std::mutex> l(m_PeersMutex); std::unique_lock<std::mutex> l(m_PeersMutex);
m_Peers.erase (it); m_Peers.erase (it);
} }

40
android/jni/Android.mk

@ -4,10 +4,10 @@ LOCAL_MODULE := i2pd
LOCAL_CPP_FEATURES := rtti exceptions LOCAL_CPP_FEATURES := rtti exceptions
LOCAL_C_INCLUDES += $(IFADDRS_PATH) ../.. LOCAL_C_INCLUDES += $(IFADDRS_PATH) ../..
LOCAL_STATIC_LIBRARIES := \ LOCAL_STATIC_LIBRARIES := \
boost_system-gcc-mt-1_53 \ boost_system \
boost_date_time-gcc-mt-1_53 \ boost_date_time \
boost_filesystem-gcc-mt-1_53 \ boost_filesystem \
boost_program_options-gcc-mt-1_53 \ boost_program_options \
crypto ssl \ crypto ssl \
miniupnpc miniupnpc
LOCAL_LDLIBS := -lz LOCAL_LDLIBS := -lz
@ -68,44 +68,44 @@ include $(BUILD_SHARED_LIBRARY)
LOCAL_PATH := $(call my-dir) LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS) include $(CLEAR_VARS)
LOCAL_MODULE := boost_system-gcc-mt-1_53 LOCAL_MODULE := boost_system
LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_53_0/$(TARGET_ARCH_ABI)/lib/libboost_system-gcc-mt-1_53.a LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_62_0/$(TARGET_ARCH_ABI)/lib/libboost_system.a
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_53_0/include LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_62_0/include
include $(PREBUILT_STATIC_LIBRARY) include $(PREBUILT_STATIC_LIBRARY)
LOCAL_PATH := $(call my-dir) LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS) include $(CLEAR_VARS)
LOCAL_MODULE := boost_date_time-gcc-mt-1_53 LOCAL_MODULE := boost_date_time
LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_53_0/$(TARGET_ARCH_ABI)/lib/libboost_date_time-gcc-mt-1_53.a LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_62_0/$(TARGET_ARCH_ABI)/lib/libboost_date_time.a
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_53_0/include LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_62_0/include
include $(PREBUILT_STATIC_LIBRARY) include $(PREBUILT_STATIC_LIBRARY)
LOCAL_PATH := $(call my-dir) LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS) include $(CLEAR_VARS)
LOCAL_MODULE := boost_filesystem-gcc-mt-1_53 LOCAL_MODULE := boost_filesystem
LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_53_0/$(TARGET_ARCH_ABI)/lib/libboost_filesystem-gcc-mt-1_53.a LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_62_0/$(TARGET_ARCH_ABI)/lib/libboost_filesystem.a
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_53_0/include LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_62_0/include
include $(PREBUILT_STATIC_LIBRARY) include $(PREBUILT_STATIC_LIBRARY)
LOCAL_PATH := $(call my-dir) LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS) include $(CLEAR_VARS)
LOCAL_MODULE := boost_program_options-gcc-mt-1_53 LOCAL_MODULE := boost_program_options
LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_53_0/$(TARGET_ARCH_ABI)/lib/libboost_program_options-gcc-mt-1_53.a LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_62_0/$(TARGET_ARCH_ABI)/lib/libboost_program_options.a
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_53_0/include LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_62_0/include
include $(PREBUILT_STATIC_LIBRARY) include $(PREBUILT_STATIC_LIBRARY)
LOCAL_PATH := $(call my-dir) LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS) include $(CLEAR_VARS)
LOCAL_MODULE := crypto LOCAL_MODULE := crypto
LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.0.2/$(TARGET_ARCH_ABI)/lib/libcrypto.a LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.0/$(TARGET_ARCH_ABI)/lib/libcrypto.a
LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.0.2/include LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.0/include
include $(PREBUILT_STATIC_LIBRARY) include $(PREBUILT_STATIC_LIBRARY)
LOCAL_PATH := $(call my-dir) LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS) include $(CLEAR_VARS)
LOCAL_MODULE := ssl LOCAL_MODULE := ssl
LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.0.2/$(TARGET_ARCH_ABI)/lib/libssl.a LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.0/$(TARGET_ARCH_ABI)/lib/libssl.a
LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.0.2/include LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.0/include
LOCAL_STATIC_LIBRARIES := crypto LOCAL_STATIC_LIBRARIES := crypto
include $(PREBUILT_STATIC_LIBRARY) include $(PREBUILT_STATIC_LIBRARY)

BIN
android/res/drawable/itoopie_notification_icon.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

2
contrib/.gitignore vendored

@ -0,0 +1,2 @@
i2pd*.zip
build*.log

22
contrib/build_mingw.cmd

@ -0,0 +1,22 @@
@echo off
title ‘¡®àª  i2pd
set "WD=C:\msys64"
set CHERE_INVOKING=enabled_from_arguments
set MSYSCON=mintty.exe
echo ‘¡®àª  i2pd ¤«ï win32. <EFBFBD> ¦¬¨â¥ Enter ¯®á«¥ ®ª®­ç ­¨ï ª®¬¯¨«ï樨...
set "MSYSTEM=MINGW32"
set "CONTITLE=MinGW x32"
start "%CONTITLE%" /WAIT C:\msys64\usr\bin\mintty.exe -i /msys2.ico /usr/bin/bash --login build_mingw.sh
pause
echo ‘¡®àª  i2pd ¤«ï win64. <EFBFBD> ¦¬¨â¥ Enter ¯®á«¥ ®ª®­ç ­¨ï ª®¬¯¨«ï樨...
set "MSYSTEM=MINGW64"
set "CONTITLE=MinGW x64"
start "%CONTITLE%" /WAIT C:\msys64\usr\bin\mintty.exe -i /msys2.ico /usr/bin/bash --login build_mingw.sh
pause
echo ‘¡®àª  § ¢¥à襭 ...
pause
exit /b 0

84
contrib/build_mingw.sh

@ -0,0 +1,84 @@
#!/bin/sh
# Определяем архитектуру.
if [ $MSYSTEM == MINGW64 ]; then
export arch="win64"
elif [ $MSYSTEM == MINGW32 ]; then
export arch="win32"
else
echo "Не могу понять, какая у вас архитектура, используемая для сборки.";
echo "Вы точно запустили скрипт в оболочке MSYS2 MinGW [64/32]-bit ?";
echo "Обычно её можно запустить выполнив c:\msys64\mingw64.exe или c:\msys64\mingw32.exe";
exit 1;
fi;
# Задаём переменной contrib текущий путь и переходим на уровень выше.
export contrib=$PWD
cd ..
# Очистка от предыдущей сборки (на всякий случай =) ).
make clean >> /dev/null
# Обновляем репозиторий, и получаем хеш последнего коммита.
echo "Получаем обновления из репозитория.";
git pull
if [ "$?" != 0 ]; then
echo "Не удалось обновить локальный репозиторий.";
echo "Вы точно запустили скрипт в папке репозитория?";
exit 1;
fi;
export commit=$(git rev-parse --verify HEAD | cut -c -7)
if [ -z commit ]; then
echo "Не удалось получить хеш последнего коммита.";
echo "Вы точно запустили скрипт в папке репозитория?";
exit 1;
fi;
# Получаем версию приложения
export version=$(grep -E "I2PD_VERSION_(MAJOR|MINOR|MICRO)\ " version.h | grep -oE '[^ ]+$' | tr '\n' '.'|head -c -1)
# Получаем количество ядер, и уменьшаем количество потоков на 1 от количества ядер (если их больше чем 1).
if [ $NUMBER_OF_PROCESSORS -ge 2 ]; then
export threads=$(( $NUMBER_OF_PROCESSORS - 1 ))
else
export threads=$NUMBER_OF_PROCESSORS
fi;
echo "Собираем i2pd ${version} (коммит ${commit}) для ${arch}.";
# Собираем приложение с разными параметрами, и архивируем в zip архивы.
make USE_UPNP=yes USE_AVX=1 USE_AESNI=1 -j ${threads} > ${contrib}/build_avx_aesni.log 2>&1
if [ "$?" != 0 ]; then
echo "Сборка не удалась. Смотрите в build_avx_aesni.log";
exit 1;
fi;
zip -9 ${contrib}/i2pd_${version}_${commit}_${arch}_mingw_avx_aesni.zip i2pd.exe >> /dev/null
make clean >> /dev/null
make USE_UPNP=yes USE_AVX=1 -j ${threads} > ${contrib}/build_avx.log 2>&1
if [ "$?" != 0 ]; then
echo "Сборка не удалась. Смотрите в build_avx.log.";
exit 1;
fi;
zip -9 ${contrib}/i2pd_${version}_${commit}_${arch}_mingw_avx.zip i2pd.exe >> /dev/null
make clean >> /dev/null
make USE_UPNP=yes USE_AESNI=1 -j ${threads} > ${contrib}/build_aesni.log 2>&1
if [ "$?" != 0 ]; then
echo "Сборка не удалась. Смотрите в build_aesni.log";
exit 1;
fi;
zip -9 ${contrib}/i2pd_${version}_${commit}_${arch}_mingw_aesni.zip i2pd.exe >> /dev/null
make clean >> /dev/null
make USE_UPNP=yes -j ${threads} > ${contrib}/build.log 2>&1
if [ "$?" != 0 ]; then
echo "Сборка не удалась. Смотрите в build.log";
exit 1;
fi;
zip -9 ${contrib}/i2pd_${version}_${commit}_${arch}_mingw.zip i2pd.exe >> /dev/null
make clean >> /dev/null
echo "Сборка i2pd ${version} для ${arch} завершена.";
exit 0;

2
contrib/debian/README vendored

@ -1,2 +1,2 @@
This forder contain systemd unit files. This forder contain systemd unit files.
To use systemd daemon control, place files from this directory to debian folder. To use systemd daemon control, place files from this directory to debian folder before building package.

2
debian/i2pd.init vendored

@ -53,7 +53,7 @@ do_start()
|| return 1 || return 1
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --chuid "$USER" -- \ start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --chuid "$USER" -- \
--service --daemon --log=file --logfile=$LOGFILE --conf=$I2PCONF --tunconf=$TUNCONF \ --service --daemon --log=file --logfile=$LOGFILE --conf=$I2PCONF --tunconf=$TUNCONF \
$DAEMON_OPTS > /dev/null 2>&1 \ --pidfile=$PIDFILE $DAEMON_OPTS > /dev/null 2>&1 \
|| return 2 || return 2
return $? return $?
} }

BIN
qt/i2pd_qt/android/res/drawable-hdpi/icon.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 36 KiB

BIN
qt/i2pd_qt/android/res/drawable/itoopie_notification_icon.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

4
qt/i2pd_qt/i2pd_qt.pro

@ -36,7 +36,7 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \
../../SSUData.cpp ../../SSUSession.cpp ../../Streaming.cpp ../../TransitTunnel.cpp \ ../../SSUData.cpp ../../SSUSession.cpp ../../Streaming.cpp ../../TransitTunnel.cpp \
../../Transports.cpp ../../Tunnel.cpp ../../TunnelEndpoint.cpp ../../TunnelGateway.cpp \ ../../Transports.cpp ../../Tunnel.cpp ../../TunnelEndpoint.cpp ../../TunnelGateway.cpp \
../../TunnelPool.cpp ../../UPnP.cpp ../../Gzip.cpp ../../Timestamp.cpp ../../util.cpp \ ../../TunnelPool.cpp ../../UPnP.cpp ../../Gzip.cpp ../../Timestamp.cpp ../../util.cpp \
../../Event.cpp ../../BloomFiler.cpp ../../i2pd.cpp ../../Event.cpp ../../BloomFilter.cpp ../../WebSocks.cpp ../../i2pd.cpp
HEADERS += DaemonQT.h mainwindow.h \ HEADERS += DaemonQT.h mainwindow.h \
../../HTTPServer.h ../../I2PControl.h ../../UPnP.h ../../Daemon.h ../../Config.h \ ../../HTTPServer.h ../../I2PControl.h ../../UPnP.h ../../Daemon.h ../../Config.h \
@ -51,7 +51,7 @@ HEADERS += DaemonQT.h mainwindow.h \
../../TransportSession.h ../../Tunnel.h ../../TunnelBase.h ../../TunnelConfig.h \ ../../TransportSession.h ../../Tunnel.h ../../TunnelBase.h ../../TunnelConfig.h \
../../TunnelEndpoint.h ../../TunnelGateway.h ../../TunnelPool.h ../../UPnP.h \ ../../TunnelEndpoint.h ../../TunnelGateway.h ../../TunnelPool.h ../../UPnP.h \
../../util.h ../../version.h ../../Gzip.h ../../Tag.h \ ../../util.h ../../version.h ../../Gzip.h ../../Tag.h \
../../BloomFiler.h ../../Event.h ../../BloomFilter.h ../../Event.h ../../WebSocks.h
FORMS += mainwindow.ui FORMS += mainwindow.ui

Loading…
Cancel
Save