Browse Source

Merge branch 'master' into websocks

pull/771/head
Jeff Becker 8 years ago
parent
commit
86d5cbc355
  1. 6
      AddressBook.cpp
  2. 18
      ChangeLog
  3. 11
      ClientContext.cpp
  4. 4
      ClientContext.h
  5. 5
      Config.cpp
  6. 24
      Crypto.cpp
  7. 16
      Crypto.h
  8. 8
      DaemonLinux.cpp
  9. 11
      Datagram.cpp
  10. 2
      Datagram.h
  11. 6
      Destination.cpp
  12. 3
      Destination.h
  13. 3
      Garlic.cpp
  14. 10
      HTTPServer.cpp
  15. 78
      I2PTunnel.cpp
  16. 17
      I2PTunnel.h
  17. 2
      Log.cpp
  18. 9
      Makefile
  19. 2
      Makefile.linux
  20. 55
      Profiling.cpp
  21. 7
      Profiling.h
  22. 1
      Reseed.cpp
  23. 2
      RouterInfo.h
  24. 62
      SAM.cpp
  25. 14
      SSU.cpp
  26. 5
      SSU.h
  27. 6
      SSUData.cpp
  28. 47
      SSUSession.cpp
  29. 3
      SSUSession.h
  30. 23
      Streaming.cpp
  31. 2
      Streaming.h
  32. 61
      Transports.cpp
  33. 8
      Transports.h
  34. 3
      TunnelConfig.h
  35. 17
      TunnelGateway.cpp
  36. 2
      Win32/installer.iss
  37. 2
      android/AndroidManifest.xml
  38. 32
      contrib/certificates/reseed/cheezybudz_at_mail.i2p.crt
  39. 33
      contrib/certificates/reseed/hottuna_at_mail.i2p.crt
  40. 34
      contrib/certificates/reseed/j_at_torontocrypto.org.crt
  41. 19
      contrib/certificates/ssl/download.xxlspeed.com.crt
  42. 23
      contrib/certificates/ssl/i2p.mooo.com.crt
  43. 27
      contrib/certificates/ssl/i2pseed.zarrenspry.info.crt
  44. 23
      contrib/certificates/ssl/netdb.i2p2.no.crt
  45. 24
      contrib/certificates/ssl/reseed.i2p-projekt.de.crt
  46. 33
      contrib/certificates/ssl/reseed.i2p.vzaws.com.crt
  47. 33
      contrib/certificates/ssl/uk.reseed.i2p2.no.crt
  48. 20
      contrib/certificates/ssl/us.reseed.i2p2.no.crt
  49. 17
      contrib/certificates/ssl/user.mx24.eu.crt
  50. 6
      debian/changelog
  51. 16
      debian/patches/01-tune-build-opts.patch
  52. 2
      qt/i2pd_qt/android/AndroidManifest.xml
  53. 17
      util.cpp
  54. 4
      version.h

6
AddressBook.cpp

@ -636,7 +636,11 @@ namespace client
if (address.length () > 0) if (address.length () > 0)
{ {
// TODO: verify from // TODO: verify from
m_Addresses[address] = buf + 8; i2p::data::IdentHash hash(buf + 8);
if (!hash.IsZero ())
m_Addresses[address] = hash;
else
LogPrint (eLogInfo, "AddressBook: Lookup response: ", address, " not found");
} }
} }

18
ChangeLog

@ -1,6 +1,24 @@
# for this file format description, # for this file format description,
# see https://github.com/olivierlacan/keep-a-changelog # see https://github.com/olivierlacan/keep-a-changelog
## [2.11.0] - 2016-12-18
### Added
- Websockets support
- Reseed through a floodfill
- Tunnel configuration for HTTP and SOCKS proxy
- Zero-hops tunnels for destinations
- Multiple acceptors for SAM
### Changed
- Reseed servers list
- DHT uses AVX if applicable
- New logo
- LeaseSet lookups
### Fixed
- HTTP Proxy connection reset for Windows
- Crash upon SAM session termination
- Can't connect to a destination for a longer time after restart
- Mass packet loss for UDP tunnels
## [2.10.2] - 2016-12-04 ## [2.10.2] - 2016-12-04
### Fixed ### Fixed
- Fixes UPnP discovery bug, producing excessive CPU usage - Fixes UPnP discovery bug, producing excessive CPU usage

11
ClientContext.cpp

@ -493,7 +493,8 @@ namespace client
i2p::data::SigningKeyType sigType = section.second.get (I2P_SERVER_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256); i2p::data::SigningKeyType sigType = section.second.get (I2P_SERVER_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256);
uint32_t maxConns = section.second.get(i2p::stream::I2CP_PARAM_STREAMING_MAX_CONNS_PER_MIN, i2p::stream::DEFAULT_MAX_CONNS_PER_MIN); uint32_t maxConns = section.second.get(i2p::stream::I2CP_PARAM_STREAMING_MAX_CONNS_PER_MIN, i2p::stream::DEFAULT_MAX_CONNS_PER_MIN);
std::string address = section.second.get<std::string> (I2P_SERVER_TUNNEL_ADDRESS, "127.0.0.1"); std::string address = section.second.get<std::string> (I2P_SERVER_TUNNEL_ADDRESS, "127.0.0.1");
bool mapToLoopback = section.second.get(I2P_SERVER_TUNNEL_MAPTOLOOPBACK, true);
// I2CP // I2CP
std::map<std::string, std::string> options; std::map<std::string, std::string> options;
ReadI2CPOptions (section, options); ReadI2CPOptions (section, options);
@ -512,6 +513,10 @@ namespace client
auto localAddress = boost::asio::ip::address::from_string(address); auto localAddress = boost::asio::ip::address::from_string(address);
boost::asio::ip::udp::endpoint endpoint(boost::asio::ip::address::from_string(host), port); boost::asio::ip::udp::endpoint endpoint(boost::asio::ip::address::from_string(host), port);
I2PUDPServerTunnel * serverTunnel = new I2PUDPServerTunnel(name, localDestination, localAddress, endpoint, port); I2PUDPServerTunnel * serverTunnel = new I2PUDPServerTunnel(name, localDestination, localAddress, endpoint, port);
if(!mapToLoopback) {
LogPrint(eLogInfo, "Clients: disabling loopback address mapping");
}
serverTunnel->SetMapToLoopback(mapToLoopback);
std::lock_guard<std::mutex> lock(m_ForwardsMutex); std::lock_guard<std::mutex> lock(m_ForwardsMutex);
if(m_ServerForwards.insert( if(m_ServerForwards.insert(
std::make_pair( std::make_pair(
@ -538,7 +543,9 @@ namespace client
LogPrint(eLogInfo, "Clients: Set Max Conns To ", maxConns); LogPrint(eLogInfo, "Clients: Set Max Conns To ", maxConns);
serverTunnel->SetMaxConnsPerMinute(maxConns); serverTunnel->SetMaxConnsPerMinute(maxConns);
if(!mapToLoopback)
LogPrint(eLogInfo, "Clients: disabling loopback address mapping");
serverTunnel->SetMapToLoopback(mapToLoopback);
if (accessList.length () > 0) if (accessList.length () > 0)
{ {

4
ClientContext.h

@ -42,7 +42,8 @@ namespace client
const char I2P_SERVER_TUNNEL_GZIP[] = "gzip"; const char I2P_SERVER_TUNNEL_GZIP[] = "gzip";
const char I2P_SERVER_TUNNEL_WEBIRC_PASSWORD[] = "webircpassword"; const char I2P_SERVER_TUNNEL_WEBIRC_PASSWORD[] = "webircpassword";
const char I2P_SERVER_TUNNEL_ADDRESS[] = "address"; const char I2P_SERVER_TUNNEL_ADDRESS[] = "address";
const char I2P_SERVER_TUNNEL_MAPTOLOOPBACK[] = "maploopback";
class ClientContext class ClientContext
{ {
public: public:
@ -113,6 +114,7 @@ namespace client
const decltype(m_ClientForwards)& GetClientForwards () const { return m_ClientForwards; } const decltype(m_ClientForwards)& GetClientForwards () const { return m_ClientForwards; }
const decltype(m_ServerForwards)& GetServerForwards () const { return m_ServerForwards; } const decltype(m_ServerForwards)& GetServerForwards () const { return m_ServerForwards; }
const i2p::proxy::HTTPProxy * GetHttpProxy () const { return m_HttpProxy; } const i2p::proxy::HTTPProxy * GetHttpProxy () const { return m_HttpProxy; }
const i2p::proxy::SOCKSProxy * GetSocksProxy () const { return m_SocksProxy; }
}; };
extern ClientContext context; extern ClientContext context;

5
Config.cpp

@ -171,13 +171,14 @@ namespace config {
"https://reseed.i2p-projekt.de/," "https://reseed.i2p-projekt.de/,"
"https://i2p.mooo.com/netDb/," "https://i2p.mooo.com/netDb/,"
"https://netdb.i2p2.no/," "https://netdb.i2p2.no/,"
"https://us.reseed.i2p2.no:444/," // "https://us.reseed.i2p2.no:444/," // mamoth's shit
// "https://uk.reseed.i2p2.no:444/," // mamoth's shit // "https://uk.reseed.i2p2.no:444/," // mamoth's shit
"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://download.xxlspeed.com/," "https://download.xxlspeed.com/,"
"https://reseed-ru.lngserv.ru/," "https://reseed-ru.lngserv.ru/,"
"https://reseed.atomike.ninja/" "https://reseed.atomike.ninja/,"
"https://reseed.memcpy.io/"
), "Reseed URLs, separated by comma") ), "Reseed URLs, separated by comma")
; ;

24
Crypto.cpp

@ -272,10 +272,9 @@ namespace crypto
} }
// ElGamal // ElGamal
void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, bool zeroPadding)
ElGamalEncryption::ElGamalEncryption (const uint8_t * key)
{ {
ctx = BN_CTX_new (); BN_CTX * ctx = BN_CTX_new ();
// select random k // select random k
BIGNUM * k = BN_new (); BIGNUM * k = BN_new ();
#if defined(__x86_64__) #if defined(__x86_64__)
@ -284,6 +283,7 @@ namespace crypto
BN_rand (k, ELGAMAL_SHORT_EXPONENT_NUM_BITS, -1, 1); // short exponent of 226 bits BN_rand (k, ELGAMAL_SHORT_EXPONENT_NUM_BITS, -1, 1); // short exponent of 226 bits
#endif #endif
// calculate a // calculate a
BIGNUM * a;
if (g_ElggTable) if (g_ElggTable)
a = ElggPow (k, g_ElggTable, ctx); a = ElggPow (k, g_ElggTable, ctx);
else else
@ -295,21 +295,10 @@ namespace crypto
BIGNUM * y = BN_new (); BIGNUM * y = BN_new ();
BN_bin2bn (key, 256, y); BN_bin2bn (key, 256, y);
// calculate b1 // calculate b1
b1 = BN_new (); BIGNUM * b1 = BN_new ();
BN_mod_exp (b1, y, k, elgp, ctx); BN_mod_exp (b1, y, k, elgp, ctx);
BN_free (y); BN_free (y);
BN_free (k); BN_free (k);
}
ElGamalEncryption::~ElGamalEncryption ()
{
BN_CTX_free (ctx);
BN_free (a);
BN_free (b1);
}
void ElGamalEncryption::Encrypt (const uint8_t * data, uint8_t * encrypted, bool zeroPadding) const
{
// create m // create m
uint8_t m[255]; uint8_t m[255];
m[0] = 0xFF; m[0] = 0xFF;
@ -319,6 +308,7 @@ namespace crypto
BIGNUM * b = BN_new (); BIGNUM * b = BN_new ();
BN_bin2bn (m, 255, b); BN_bin2bn (m, 255, b);
BN_mod_mul (b, b1, b, elgp, ctx); BN_mod_mul (b, b1, b, elgp, ctx);
BN_free (b1);
// copy a and b // copy a and b
if (zeroPadding) if (zeroPadding)
{ {
@ -333,8 +323,10 @@ namespace crypto
bn2buf (b, encrypted + 256, 256); bn2buf (b, encrypted + 256, 256);
} }
BN_free (b); BN_free (b);
BN_free (a);
BN_CTX_free (ctx);
} }
bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted,
uint8_t * data, bool zeroPadding) uint8_t * data, bool zeroPadding)
{ {

16
Crypto.h

@ -47,21 +47,7 @@ namespace crypto
}; };
// ElGamal // ElGamal
class ElGamalEncryption void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, bool zeroPadding = false);
{
public:
ElGamalEncryption (const uint8_t * key);
~ElGamalEncryption ();
void Encrypt (const uint8_t * data, uint8_t * encrypted, bool zeroPadding = false) const;
private:
BN_CTX * ctx;
BIGNUM * a, * b1;
};
bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, uint8_t * data, bool zeroPadding = false); bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, uint8_t * data, bool zeroPadding = false);
void GenerateElGamalKeyPair (uint8_t * priv, uint8_t * pub); void GenerateElGamalKeyPair (uint8_t * priv, uint8_t * pub);

8
DaemonLinux.cpp

@ -76,12 +76,10 @@ namespace i2p
return false; return false;
} }
#if !defined(__OpenBSD__)
// point std{in,out,err} descriptors to /dev/null // point std{in,out,err} descriptors to /dev/null
stdin = freopen("/dev/null", "r", stdin); freopen("/dev/null", "r", stdin);
stdout = freopen("/dev/null", "w", stdout); freopen("/dev/null", "w", stdout);
stderr = freopen("/dev/null", "w", stderr); freopen("/dev/null", "w", stderr);
#endif
} }
// set proc limits // set proc limits

11
Datagram.cpp

@ -168,7 +168,8 @@ namespace datagram
const i2p::data::IdentHash & remoteIdent) : const i2p::data::IdentHash & remoteIdent) :
m_LocalDestination(localDestination), m_LocalDestination(localDestination),
m_RemoteIdent(remoteIdent), m_RemoteIdent(remoteIdent),
m_SendQueueTimer(localDestination->GetService()) m_SendQueueTimer(localDestination->GetService()),
m_RequestingLS(false)
{ {
m_LastUse = i2p::util::GetMillisecondsSinceEpoch (); m_LastUse = i2p::util::GetMillisecondsSinceEpoch ();
ScheduleFlushSendQueue(); ScheduleFlushSendQueue();
@ -221,7 +222,10 @@ namespace datagram
} }
if(!m_RemoteLeaseSet) { if(!m_RemoteLeaseSet) {
// no remote lease set // no remote lease set
m_LocalDestination->RequestDestination(m_RemoteIdent, std::bind(&DatagramSession::HandleLeaseSetUpdated, this, std::placeholders::_1)); if(!m_RequestingLS) {
m_RequestingLS = true;
m_LocalDestination->RequestDestination(m_RemoteIdent, std::bind(&DatagramSession::HandleLeaseSetUpdated, this, std::placeholders::_1));
}
return nullptr; return nullptr;
} }
m_RoutingSession = m_LocalDestination->GetRoutingSession(m_RemoteLeaseSet, true); m_RoutingSession = m_LocalDestination->GetRoutingSession(m_RemoteLeaseSet, true);
@ -290,6 +294,7 @@ namespace datagram
void DatagramSession::HandleLeaseSetUpdated(std::shared_ptr<i2p::data::LeaseSet> ls) void DatagramSession::HandleLeaseSetUpdated(std::shared_ptr<i2p::data::LeaseSet> ls)
{ {
m_RequestingLS = false;
if(!ls) return; if(!ls) return;
// only update lease set if found and newer than previous lease set // only update lease set if found and newer than previous lease set
uint64_t oldExpire = 0; uint64_t oldExpire = 0;
@ -310,7 +315,7 @@ namespace datagram
std::vector<i2p::tunnel::TunnelMessageBlock> send; std::vector<i2p::tunnel::TunnelMessageBlock> send;
auto routingPath = GetSharedRoutingPath(); auto routingPath = GetSharedRoutingPath();
// if we don't have a routing path we will drop all queued messages // if we don't have a routing path we will drop all queued messages
if(routingPath) if(routingPath && routingPath->outboundTunnel && routingPath->remoteLease)
{ {
for (const auto & msg : m_SendQueue) for (const auto & msg : m_SendQueue)
{ {

2
Datagram.h

@ -88,7 +88,7 @@ namespace datagram
boost::asio::deadline_timer m_SendQueueTimer; boost::asio::deadline_timer m_SendQueueTimer;
std::vector<std::shared_ptr<I2NPMessage> > m_SendQueue; std::vector<std::shared_ptr<I2NPMessage> > m_SendQueue;
uint64_t m_LastUse; uint64_t m_LastUse;
bool m_RequestingLS;
}; };
const size_t MAX_DATAGRAM_SIZE = 32768; const size_t MAX_DATAGRAM_SIZE = 32768;

6
Destination.cpp

@ -844,6 +844,12 @@ namespace client
return false; return false;
} }
void ClientDestination::AcceptOnce (const i2p::stream::StreamingDestination::Acceptor& acceptor)
{
if (m_StreamingDestination)
m_StreamingDestination->AcceptOnce (acceptor);
}
std::shared_ptr<i2p::stream::StreamingDestination> ClientDestination::CreateStreamingDestination (int port, bool gzip) std::shared_ptr<i2p::stream::StreamingDestination> ClientDestination::CreateStreamingDestination (int port, bool gzip)
{ {
auto dest = std::make_shared<i2p::stream::StreamingDestination> (GetSharedFromThis (), port, gzip); auto dest = std::make_shared<i2p::stream::StreamingDestination> (GetSharedFromThis (), port, gzip);

3
Destination.h

@ -186,7 +186,8 @@ namespace client
void AcceptStreams (const i2p::stream::StreamingDestination::Acceptor& acceptor); void AcceptStreams (const i2p::stream::StreamingDestination::Acceptor& acceptor);
void StopAcceptingStreams (); void StopAcceptingStreams ();
bool IsAcceptingStreams () const; bool IsAcceptingStreams () const;
void AcceptOnce (const i2p::stream::StreamingDestination::Acceptor& acceptor);
// datagram // datagram
i2p::datagram::DatagramDestination * GetDatagramDestination () const { return m_DatagramDestination; }; i2p::datagram::DatagramDestination * GetDatagramDestination () const { return m_DatagramDestination; };
i2p::datagram::DatagramDestination * CreateDatagramDestination (); i2p::datagram::DatagramDestination * CreateDatagramDestination ();

3
Garlic.cpp

@ -187,8 +187,7 @@ namespace garlic
RAND_bytes (elGamal.preIV, 32); // Pre-IV RAND_bytes (elGamal.preIV, 32); // Pre-IV
uint8_t iv[32]; // IV is first 16 bytes uint8_t iv[32]; // IV is first 16 bytes
SHA256(elGamal.preIV, 32, iv); SHA256(elGamal.preIV, 32, iv);
i2p::crypto::ElGamalEncryption elGamalEncryption (m_Destination->GetEncryptionPublicKey ()); i2p::crypto::ElGamalEncrypt (m_Destination->GetEncryptionPublicKey (), (uint8_t *)&elGamal, buf, true);
elGamalEncryption.Encrypt ((uint8_t *)&elGamal, buf, true);
m_Encryption.SetIV (iv); m_Encryption.SetIV (iv);
buf += 514; buf += 514;
len += 514; len += 514;

10
HTTPServer.cpp

@ -604,6 +604,15 @@ namespace http {
s << i2p::client::context.GetAddressBook ().ToAddress(ident); s << i2p::client::context.GetAddressBook ().ToAddress(ident);
s << "<br>\r\n"<< std::endl; s << "<br>\r\n"<< std::endl;
} }
auto socksProxy = i2p::client::context.GetSocksProxy ();
if (socksProxy)
{
auto& ident = socksProxy->GetLocalDestination ()->GetIdentHash();
s << "<a href=\"/?page=" << HTTP_PAGE_LOCAL_DESTINATION << "&b32=" << ident.ToBase32 () << "\">";
s << "SOCKS Proxy" << "</a> &#8656; ";
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
s << "<br>\r\n"<< std::endl;
}
s << "<br>\r\n<b>Server Tunnels:</b><br>\r\n<br>\r\n"; s << "<br>\r\n<b>Server Tunnels:</b><br>\r\n<br>\r\n";
for (auto& it: i2p::client::context.GetServerTunnels ()) for (auto& it: i2p::client::context.GetServerTunnels ())
{ {
@ -775,6 +784,7 @@ namespace http {
{ {
uint32_t token; uint32_t token;
RAND_bytes ((uint8_t *)&token, 4); RAND_bytes ((uint8_t *)&token, 4);
token &= 0x7FFFFFFF; // clear first bit
auto ts = i2p::util::GetSecondsSinceEpoch (); auto ts = i2p::util::GetSecondsSinceEpoch ();
for (auto it = m_Tokens.begin (); it != m_Tokens.end (); ) for (auto it = m_Tokens.begin (); it != m_Tokens.end (); )
{ {

78
I2PTunnel.cpp

@ -58,25 +58,39 @@ namespace client
StreamReceive (); StreamReceive ();
Receive (); Receive ();
} }
void I2PTunnelConnection::Connect () static boost::asio::ip::address GetLoopbackAddressFor(const i2p::data::IdentHash & addr)
{
boost::asio::ip::address_v4::bytes_type bytes;
const uint8_t * ident = addr;
bytes[0] = 127;
memcpy (bytes.data ()+1, ident, 3);
boost::asio::ip::address ourIP = boost::asio::ip::address_v4 (bytes);
return ourIP;
}
static void MapToLoopback(const std::shared_ptr<boost::asio::ip::tcp::socket> & sock, const i2p::data::IdentHash & addr)
{
// bind to 127.x.x.x address
// where x.x.x are first three bytes from ident
auto ourIP = GetLoopbackAddressFor(addr);
sock->bind (boost::asio::ip::tcp::endpoint (ourIP, 0));
}
void I2PTunnelConnection::Connect (bool mapToLoopback)
{ {
I2PTunnelSetSocketOptions(m_Socket); I2PTunnelSetSocketOptions(m_Socket);
if (m_Socket) { if (m_Socket) {
#ifdef __linux__
// bind to 127.x.x.x address
// where x.x.x are first three bytes from ident
#ifdef __linux__
if (m_RemoteEndpoint.address ().is_v4 () && if (m_RemoteEndpoint.address ().is_v4 () &&
m_RemoteEndpoint.address ().to_v4 ().to_bytes ()[0] == 127) m_RemoteEndpoint.address ().to_v4 ().to_bytes ()[0] == 127 && mapToLoopback)
{ {
m_Socket->open (boost::asio::ip::tcp::v4 ()); m_Socket->open (boost::asio::ip::tcp::v4 ());
boost::asio::ip::address_v4::bytes_type bytes; auto ident = m_Stream->GetRemoteIdentity()->GetIdentHash();
const uint8_t * ident = m_Stream->GetRemoteIdentity ()->GetIdentHash (); MapToLoopback(m_Socket, ident);
bytes[0] = 127;
memcpy (bytes.data ()+1, ident, 3);
boost::asio::ip::address ourIP = boost::asio::ip::address_v4 (bytes);
m_Socket->bind (boost::asio::ip::tcp::endpoint (ourIP, 0));
} }
#endif #endif
m_Socket->async_connect (m_RemoteEndpoint, std::bind (&I2PTunnelConnection::HandleConnect, m_Socket->async_connect (m_RemoteEndpoint, std::bind (&I2PTunnelConnection::HandleConnect,
@ -177,7 +191,7 @@ namespace client
{ {
if (bytes_transferred > 0) if (bytes_transferred > 0)
Write (m_StreamBuffer, bytes_transferred); // postpone termination Write (m_StreamBuffer, bytes_transferred); // postpone termination
else if (ecode == boost::asio::error::timed_out && m_Stream->IsOpen ()) else if (ecode == boost::asio::error::timed_out && m_Stream && m_Stream->IsOpen ())
StreamReceive (); StreamReceive ();
else else
Terminate (); Terminate ();
@ -212,7 +226,9 @@ namespace client
// send destination first like received from I2P // send destination first like received from I2P
std::string dest = m_Stream->GetRemoteIdentity ()->ToBase64 (); std::string dest = m_Stream->GetRemoteIdentity ()->ToBase64 ();
dest += "\n"; dest += "\n";
memcpy (m_StreamBuffer, dest.c_str (), dest.size ()); if(sizeof(m_StreamBuffer) >= dest.size()) {
memcpy (m_StreamBuffer, dest.c_str (), dest.size ());
}
HandleStreamReceive (boost::system::error_code (), dest.size ()); HandleStreamReceive (boost::system::error_code (), dest.size ());
} }
Receive (); Receive ();
@ -415,7 +431,7 @@ namespace client
I2PServerTunnel::I2PServerTunnel (const std::string& name, const std::string& address, I2PServerTunnel::I2PServerTunnel (const std::string& name, const std::string& address,
int port, std::shared_ptr<ClientDestination> localDestination, int inport, bool gzip): int port, std::shared_ptr<ClientDestination> localDestination, int inport, bool gzip):
I2PService (localDestination), m_Name (name), m_Address (address), m_Port (port), m_IsAccessList (false) I2PService (localDestination), m_MapToLoopback(true), m_Name (name), m_Address (address), m_Port (port), m_IsAccessList (false)
{ {
m_PortDestination = localDestination->CreateStreamingDestination (inport > 0 ? inport : port, gzip); m_PortDestination = localDestination->CreateStreamingDestination (inport > 0 ? inport : port, gzip);
} }
@ -500,7 +516,7 @@ namespace client
{ {
auto conn = std::make_shared<I2PTunnelConnection> (this, stream, std::make_shared<boost::asio::ip::tcp::socket> (GetService ()), GetEndpoint ()); auto conn = std::make_shared<I2PTunnelConnection> (this, stream, std::make_shared<boost::asio::ip::tcp::socket> (GetService ()), GetEndpoint ());
AddHandler (conn); AddHandler (conn);
conn->Connect (); conn->Connect (m_MapToLoopback);
} }
I2PServerTunnelHTTP::I2PServerTunnelHTTP (const std::string& name, const std::string& address, I2PServerTunnelHTTP::I2PServerTunnelHTTP (const std::string& name, const std::string& address,
@ -540,7 +556,6 @@ namespace client
auto session = ObtainUDPSession(from, toPort, fromPort); auto session = ObtainUDPSession(from, toPort, fromPort);
session->IPSocket.send_to(boost::asio::buffer(buf, len), m_RemoteEndpoint); session->IPSocket.send_to(boost::asio::buffer(buf, len), m_RemoteEndpoint);
session->LastActivity = i2p::util::GetMillisecondsSinceEpoch(); session->LastActivity = i2p::util::GetMillisecondsSinceEpoch();
} }
void I2PUDPServerTunnel::ExpireStale(const uint64_t delta) { void I2PUDPServerTunnel::ExpireStale(const uint64_t delta) {
@ -568,7 +583,7 @@ namespace client
} }
} }
std::shared_ptr<UDPSession> I2PUDPServerTunnel::ObtainUDPSession(const i2p::data::IdentityEx& from, uint16_t localPort, uint16_t remotePort) UDPSessionPtr I2PUDPServerTunnel::ObtainUDPSession(const i2p::data::IdentityEx& from, uint16_t localPort, uint16_t remotePort)
{ {
auto ih = from.GetIdentHash(); auto ih = from.GetIdentHash();
for (auto & s : m_Sessions ) for (auto & s : m_Sessions )
@ -580,8 +595,15 @@ namespace client
return s; return s;
} }
} }
/** create new udp session */ boost::asio::ip::address addr;
boost::asio::ip::udp::endpoint ep(m_LocalAddress, 0); /** create new udp session */
if(m_LocalAddress.is_loopback() && m_MapToLoopback) {
auto ident = from.GetIdentHash();
addr = GetLoopbackAddressFor(ident);
} else {
addr = m_LocalAddress;
}
boost::asio::ip::udp::endpoint ep(addr, 0);
m_Sessions.push_back(std::make_shared<UDPSession>(ep, m_LocalDest, m_RemoteEndpoint, &ih, localPort, remotePort)); m_Sessions.push_back(std::make_shared<UDPSession>(ep, m_LocalDest, m_RemoteEndpoint, &ih, localPort, remotePort));
auto & back = m_Sessions.back(); auto & back = m_Sessions.back();
return back; return back;
@ -626,6 +648,7 @@ namespace client
I2PUDPServerTunnel::I2PUDPServerTunnel(const std::string & name, std::shared_ptr<i2p::client::ClientDestination> localDestination, I2PUDPServerTunnel::I2PUDPServerTunnel(const std::string & name, std::shared_ptr<i2p::client::ClientDestination> localDestination,
boost::asio::ip::address localAddress, boost::asio::ip::udp::endpoint forwardTo, uint16_t port) : boost::asio::ip::address localAddress, boost::asio::ip::udp::endpoint forwardTo, uint16_t port) :
m_MapToLoopback(true),
m_Name(name), m_Name(name),
m_LocalAddress(localAddress), m_LocalAddress(localAddress),
m_RemoteEndpoint(forwardTo) m_RemoteEndpoint(forwardTo)
@ -652,7 +675,8 @@ namespace client
{ {
std::vector<std::shared_ptr<DatagramSessionInfo> > sessions; std::vector<std::shared_ptr<DatagramSessionInfo> > sessions;
std::lock_guard<std::mutex> lock(m_SessionsMutex); std::lock_guard<std::mutex> lock(m_SessionsMutex);
for (auto & s : m_Sessions )
for ( UDPSessionPtr s : m_Sessions )
{ {
if (!s->m_Destination) continue; if (!s->m_Destination) continue;
auto info = s->m_Destination->GetInfoForRemote(s->Identity); auto info = s->m_Destination->GetInfoForRemote(s->Identity);
@ -687,7 +711,7 @@ namespace client
dgram->SetReceiver(std::bind(&I2PUDPClientTunnel::HandleRecvFromI2P, this, dgram->SetReceiver(std::bind(&I2PUDPClientTunnel::HandleRecvFromI2P, this,
std::placeholders::_1, std::placeholders::_2, std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3, std::placeholders::_4, std::placeholders::_3, std::placeholders::_4,
std::placeholders::_5)); std::placeholders::_5));
} }
@ -739,10 +763,9 @@ namespace client
void I2PUDPClientTunnel::TryResolving() { void I2PUDPClientTunnel::TryResolving() {
LogPrint(eLogInfo, "UDP Tunnel: Trying to resolve ", m_RemoteDest); LogPrint(eLogInfo, "UDP Tunnel: Trying to resolve ", m_RemoteDest);
m_RemoteIdent = new i2p::data::IdentHash; i2p::data::IdentHash * h = new i2p::data::IdentHash;
m_RemoteIdent->Fill(0);
while(!context.GetAddressBook().GetIdentHash(m_RemoteDest, *m_RemoteIdent) && !m_cancel_resolve) while(!context.GetAddressBook().GetIdentHash(m_RemoteDest, *h) && !m_cancel_resolve)
{ {
LogPrint(eLogWarning, "UDP Tunnel: failed to lookup ", m_RemoteDest); LogPrint(eLogWarning, "UDP Tunnel: failed to lookup ", m_RemoteDest);
std::this_thread::sleep_for(std::chrono::seconds(1)); std::this_thread::sleep_for(std::chrono::seconds(1));
@ -752,6 +775,7 @@ namespace client
LogPrint(eLogError, "UDP Tunnel: lookup of ", m_RemoteDest, " was cancelled"); LogPrint(eLogError, "UDP Tunnel: lookup of ", m_RemoteDest, " was cancelled");
return; return;
} }
m_RemoteIdent = h;
LogPrint(eLogInfo, "UDP Tunnel: resolved ", m_RemoteDest, " to ", m_RemoteIdent->ToBase32()); LogPrint(eLogInfo, "UDP Tunnel: resolved ", m_RemoteDest, " to ", m_RemoteIdent->ToBase32());
} }
@ -766,8 +790,6 @@ namespace client
// found convo // found convo
if (len > 0) { if (len > 0) {
LogPrint(eLogDebug, "UDP Client: got ", len, "B from ", from.GetIdentHash().ToBase32()); LogPrint(eLogDebug, "UDP Client: got ", len, "B from ", from.GetIdentHash().ToBase32());
uint8_t sendbuf[len];
memcpy(sendbuf, buf, len);
m_LocalSocket.send_to(boost::asio::buffer(buf, len), itr->second.first); m_LocalSocket.send_to(boost::asio::buffer(buf, len), itr->second.first);
// mark convo as active // mark convo as active
itr->second.second = i2p::util::GetMillisecondsSinceEpoch(); itr->second.second = i2p::util::GetMillisecondsSinceEpoch();
@ -789,7 +811,7 @@ namespace client
if(m_LocalSocket.is_open()) if(m_LocalSocket.is_open())
m_LocalSocket.close(); m_LocalSocket.close();
m_cancel_resolve = true; m_cancel_resolve = true;
if(m_ResolveThread) if(m_ResolveThread)

17
I2PTunnel.h

@ -18,7 +18,7 @@ namespace i2p
{ {
namespace client namespace client
{ {
const size_t I2P_TUNNEL_CONNECTION_BUFFER_SIZE = 8192; const size_t I2P_TUNNEL_CONNECTION_BUFFER_SIZE = 65536;
const int I2P_TUNNEL_CONNECTION_MAX_IDLE = 3600; // in seconds const int I2P_TUNNEL_CONNECTION_MAX_IDLE = 3600; // in seconds
const int I2P_TUNNEL_DESTINATION_REQUEST_TIMEOUT = 10; // in seconds const int I2P_TUNNEL_DESTINATION_REQUEST_TIMEOUT = 10; // in seconds
// for HTTP tunnels // for HTTP tunnels
@ -38,7 +38,7 @@ namespace client
const boost::asio::ip::tcp::endpoint& target, bool quiet = true); // from I2P const boost::asio::ip::tcp::endpoint& target, bool quiet = true); // from I2P
~I2PTunnelConnection (); ~I2PTunnelConnection ();
void I2PConnect (const uint8_t * msg = nullptr, size_t len = 0); void I2PConnect (const uint8_t * msg = nullptr, size_t len = 0);
void Connect (); void Connect (bool mapToLoopback = true);
protected: protected:
@ -182,6 +182,8 @@ namespace client
/** how long has this converstation been idle in ms */ /** how long has this converstation been idle in ms */
uint64_t idle; uint64_t idle;
}; };
typedef std::shared_ptr<UDPSession> UDPSessionPtr;
/** server side udp tunnel, many i2p inbound to 1 ip outbound */ /** server side udp tunnel, many i2p inbound to 1 ip outbound */
class I2PUDPServerTunnel class I2PUDPServerTunnel
@ -199,17 +201,20 @@ namespace client
std::vector<std::shared_ptr<DatagramSessionInfo> > GetSessions(); std::vector<std::shared_ptr<DatagramSessionInfo> > GetSessions();
std::shared_ptr<ClientDestination> GetLocalDestination () const { return m_LocalDest; } std::shared_ptr<ClientDestination> GetLocalDestination () const { return m_LocalDest; }
void SetMapToLoopback(bool mapToLoopback = true) { m_MapToLoopback = mapToLoopback; }
private: private:
void HandleRecvFromI2P(const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len); void HandleRecvFromI2P(const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
std::shared_ptr<UDPSession> ObtainUDPSession(const i2p::data::IdentityEx& from, uint16_t localPort, uint16_t remotePort); UDPSessionPtr ObtainUDPSession(const i2p::data::IdentityEx& from, uint16_t localPort, uint16_t remotePort);
private: private:
bool m_MapToLoopback;
const std::string m_Name; const std::string m_Name;
boost::asio::ip::address m_LocalAddress; boost::asio::ip::address m_LocalAddress;
boost::asio::ip::udp::endpoint m_RemoteEndpoint; boost::asio::ip::udp::endpoint m_RemoteEndpoint;
std::mutex m_SessionsMutex; std::mutex m_SessionsMutex;
std::vector<std::shared_ptr<UDPSession> > m_Sessions; std::vector<UDPSessionPtr> m_Sessions;
std::shared_ptr<i2p::client::ClientDestination> m_LocalDest; std::shared_ptr<i2p::client::ClientDestination> m_LocalDest;
}; };
@ -262,6 +267,8 @@ namespace client
void SetAccessList (const std::set<i2p::data::IdentHash>& accessList); void SetAccessList (const std::set<i2p::data::IdentHash>& accessList);
void SetMapToLoopback(bool mapToLoopback) { m_MapToLoopback = mapToLoopback; }
const std::string& GetAddress() const { return m_Address; } const std::string& GetAddress() const { return m_Address; }
int GetPort () const { return m_Port; }; int GetPort () const { return m_Port; };
uint16_t GetLocalPort () const { return m_PortDestination->GetLocalPort (); }; uint16_t GetLocalPort () const { return m_PortDestination->GetLocalPort (); };
@ -281,7 +288,7 @@ namespace client
virtual void CreateI2PConnection (std::shared_ptr<i2p::stream::Stream> stream); virtual void CreateI2PConnection (std::shared_ptr<i2p::stream::Stream> stream);
private: private:
bool m_MapToLoopback;
std::string m_Name, m_Address; std::string m_Name, m_Address;
int m_Port; int m_Port;
boost::asio::ip::tcp::endpoint m_Endpoint; boost::asio::ip::tcp::endpoint m_Endpoint;

2
Log.cpp

@ -72,7 +72,6 @@ namespace log {
{ {
if (!m_IsRunning) if (!m_IsRunning)
{ {
Reopen ();
m_IsRunning = true; m_IsRunning = true;
m_Thread = new std::thread (std::bind (&Log::Run, this)); m_Thread = new std::thread (std::bind (&Log::Run, this));
} }
@ -162,6 +161,7 @@ namespace log {
void Log::Run () void Log::Run ()
{ {
Reopen ();
while (m_IsRunning) while (m_IsRunning)
{ {
std::shared_ptr<LogMsg> msg; std::shared_ptr<LogMsg> msg;

9
Makefile

@ -9,10 +9,11 @@ DEPS := obj/make.dep
include filelist.mk include filelist.mk
USE_AESNI := yes USE_AESNI := yes
USE_STATIC := no USE_AVX := yes
USE_MESHNET := no USE_STATIC := no
USE_UPNP := no USE_MESHNET := no
USE_UPNP := no
ifeq ($(WEBSOCKETS),1) ifeq ($(WEBSOCKETS),1)
NEEDED_CXXFLAGS += -DWITH_EVENTS NEEDED_CXXFLAGS += -DWITH_EVENTS

2
Makefile.linux

@ -65,7 +65,9 @@ endif
endif endif
endif endif
ifeq ($(USE_AVX),yes)
#check if AVX supported by CPU #check if AVX supported by CPU
ifneq ($(shell $(GREP) -c avx /proc/cpuinfo),0) ifneq ($(shell $(GREP) -c avx /proc/cpuinfo),0)
CPU_FLAGS += -mavx CPU_FLAGS += -mavx
endif endif
endif

55
Profiling.cpp

@ -12,8 +12,8 @@ namespace data
{ {
i2p::fs::HashedStorage m_ProfilesStorage("peerProfiles", "p", "profile-", "txt"); i2p::fs::HashedStorage m_ProfilesStorage("peerProfiles", "p", "profile-", "txt");
RouterProfile::RouterProfile (const IdentHash& identHash): RouterProfile::RouterProfile ():
m_IdentHash (identHash), m_LastUpdateTime (boost::posix_time::second_clock::local_time()), m_LastUpdateTime (boost::posix_time::second_clock::local_time()),
m_NumTunnelsAgreed (0), m_NumTunnelsDeclined (0), m_NumTunnelsNonReplied (0), m_NumTunnelsAgreed (0), m_NumTunnelsDeclined (0), m_NumTunnelsNonReplied (0),
m_NumTimesTaken (0), m_NumTimesRejected (0) m_NumTimesTaken (0), m_NumTimesRejected (0)
{ {
@ -29,7 +29,7 @@ namespace data
m_LastUpdateTime = GetTime (); m_LastUpdateTime = GetTime ();
} }
void RouterProfile::Save () void RouterProfile::Save (const IdentHash& identHash)
{ {
// fill sections // fill sections
boost::property_tree::ptree participation; boost::property_tree::ptree participation;
@ -46,7 +46,7 @@ namespace data
pt.put_child (PEER_PROFILE_SECTION_USAGE, usage); pt.put_child (PEER_PROFILE_SECTION_USAGE, usage);
// save to file // save to file
std::string ident = m_IdentHash.ToBase64 (); std::string ident = identHash.ToBase64 ();
std::string path = m_ProfilesStorage.Path(ident); std::string path = m_ProfilesStorage.Path(ident);
try { try {
@ -57,51 +57,64 @@ namespace data
} }
} }
void RouterProfile::Load () void RouterProfile::Load (const IdentHash& identHash)
{ {
std::string ident = m_IdentHash.ToBase64 (); std::string ident = identHash.ToBase64 ();
std::string path = m_ProfilesStorage.Path(ident); std::string path = m_ProfilesStorage.Path(ident);
boost::property_tree::ptree pt; boost::property_tree::ptree pt;
if (!i2p::fs::Exists(path)) { if (!i2p::fs::Exists(path))
{
LogPrint(eLogWarning, "Profiling: no profile yet for ", ident); LogPrint(eLogWarning, "Profiling: no profile yet for ", ident);
return; return;
} }
try { try
{
boost::property_tree::read_ini (path, pt); boost::property_tree::read_ini (path, pt);
} catch (std::exception& ex) { } catch (std::exception& ex)
{
/* boost exception verbose enough */ /* boost exception verbose enough */
LogPrint (eLogError, "Profiling: ", ex.what ()); LogPrint (eLogError, "Profiling: ", ex.what ());
return; return;
} }
try { try
{
auto t = pt.get (PEER_PROFILE_LAST_UPDATE_TIME, ""); auto t = pt.get (PEER_PROFILE_LAST_UPDATE_TIME, "");
if (t.length () > 0) if (t.length () > 0)
m_LastUpdateTime = boost::posix_time::time_from_string (t); m_LastUpdateTime = boost::posix_time::time_from_string (t);
if ((GetTime () - m_LastUpdateTime).hours () < PEER_PROFILE_EXPIRATION_TIMEOUT) { if ((GetTime () - m_LastUpdateTime).hours () < PEER_PROFILE_EXPIRATION_TIMEOUT)
try { {
try
{
// read participations // read participations
auto participations = pt.get_child (PEER_PROFILE_SECTION_PARTICIPATION); auto participations = pt.get_child (PEER_PROFILE_SECTION_PARTICIPATION);
m_NumTunnelsAgreed = participations.get (PEER_PROFILE_PARTICIPATION_AGREED, 0); m_NumTunnelsAgreed = participations.get (PEER_PROFILE_PARTICIPATION_AGREED, 0);
m_NumTunnelsDeclined = participations.get (PEER_PROFILE_PARTICIPATION_DECLINED, 0); m_NumTunnelsDeclined = participations.get (PEER_PROFILE_PARTICIPATION_DECLINED, 0);
m_NumTunnelsNonReplied = participations.get (PEER_PROFILE_PARTICIPATION_NON_REPLIED, 0); m_NumTunnelsNonReplied = participations.get (PEER_PROFILE_PARTICIPATION_NON_REPLIED, 0);
} catch (boost::property_tree::ptree_bad_path& ex) { }
catch (boost::property_tree::ptree_bad_path& ex)
{
LogPrint (eLogWarning, "Profiling: Missing section ", PEER_PROFILE_SECTION_PARTICIPATION, " in profile for ", ident); LogPrint (eLogWarning, "Profiling: Missing section ", PEER_PROFILE_SECTION_PARTICIPATION, " in profile for ", ident);
} }
try { try
{
// read usage // read usage
auto usage = pt.get_child (PEER_PROFILE_SECTION_USAGE); auto usage = pt.get_child (PEER_PROFILE_SECTION_USAGE);
m_NumTimesTaken = usage.get (PEER_PROFILE_USAGE_TAKEN, 0); m_NumTimesTaken = usage.get (PEER_PROFILE_USAGE_TAKEN, 0);
m_NumTimesRejected = usage.get (PEER_PROFILE_USAGE_REJECTED, 0); m_NumTimesRejected = usage.get (PEER_PROFILE_USAGE_REJECTED, 0);
} catch (boost::property_tree::ptree_bad_path& ex) { }
catch (boost::property_tree::ptree_bad_path& ex)
{
LogPrint (eLogWarning, "Missing section ", PEER_PROFILE_SECTION_USAGE, " in profile for ", ident); LogPrint (eLogWarning, "Missing section ", PEER_PROFILE_SECTION_USAGE, " in profile for ", ident);
} }
} else { }
*this = RouterProfile (m_IdentHash); else
} *this = RouterProfile ();
} catch (std::exception& ex) { }
catch (std::exception& ex)
{
LogPrint (eLogError, "Profiling: Can't read profile ", ident, " :", ex.what ()); LogPrint (eLogError, "Profiling: Can't read profile ", ident, " :", ex.what ());
} }
} }
@ -149,8 +162,8 @@ namespace data
std::shared_ptr<RouterProfile> GetRouterProfile (const IdentHash& identHash) std::shared_ptr<RouterProfile> GetRouterProfile (const IdentHash& identHash)
{ {
auto profile = std::make_shared<RouterProfile> (identHash); auto profile = std::make_shared<RouterProfile> ();
profile->Load (); // if possible profile->Load (identHash); // if possible
return profile; return profile;
} }

7
Profiling.h

@ -26,11 +26,11 @@ namespace data
{ {
public: public:
RouterProfile (const IdentHash& identHash); RouterProfile ();
RouterProfile& operator= (const RouterProfile& ) = default; RouterProfile& operator= (const RouterProfile& ) = default;
void Save (); void Save (const IdentHash& identHash);
void Load (); void Load (const IdentHash& identHash);
bool IsBad (); bool IsBad ();
@ -48,7 +48,6 @@ namespace data
private: private:
IdentHash m_IdentHash;
boost::posix_time::ptime m_LastUpdateTime; boost::posix_time::ptime m_LastUpdateTime;
// participation // participation
uint32_t m_NumTunnelsAgreed; uint32_t m_NumTunnelsAgreed;

1
Reseed.cpp

@ -444,6 +444,7 @@ namespace data
s.lowest_layer().connect (*it, ecode); s.lowest_layer().connect (*it, ecode);
if (!ecode) if (!ecode)
{ {
SSL_set_tlsext_host_name(s.native_handle(), url.host.c_str ());
s.handshake (boost::asio::ssl::stream_base::client, ecode); s.handshake (boost::asio::ssl::stream_base::client, ecode);
if (!ecode) if (!ecode)
{ {

2
RouterInfo.h

@ -168,7 +168,7 @@ namespace data
bool SaveToFile (const std::string& fullPath); bool SaveToFile (const std::string& fullPath);
std::shared_ptr<RouterProfile> GetProfile () const; std::shared_ptr<RouterProfile> GetProfile () const;
void SaveProfile () { if (m_Profile) m_Profile->Save (); }; void SaveProfile () { if (m_Profile) m_Profile->Save (GetIdentHash ()); };
void Update (const uint8_t * buf, int len); void Update (const uint8_t * buf, int len);
void DeleteBuffer () { delete[] m_Buffer; m_Buffer = nullptr; }; void DeleteBuffer () { delete[] m_Buffer; m_Buffer = nullptr; };

62
SAM.cpp

@ -108,10 +108,10 @@ namespace client
separator++; separator++;
std::map<std::string, std::string> params; std::map<std::string, std::string> params;
ExtractParams (separator, params); ExtractParams (separator, params);
auto it = params.find (SAM_PARAM_MAX); //auto it = params.find (SAM_PARAM_MAX);
// TODO: check MIN as well // TODO: check MIN as well
if (it != params.end ()) //if (it != params.end ())
version = it->second; // version = it->second;
} }
if (version[0] == '3') // we support v3 (3.0 and 3.1) only if (version[0] == '3') // we support v3 (3.0 and 3.1) only
{ {
@ -400,16 +400,12 @@ namespace client
m_ID = id; m_ID = id;
m_Session = m_Owner.FindSession (id); m_Session = m_Owner.FindSession (id);
if (m_Session) if (m_Session)
{ {
m_SocketType = eSAMSocketTypeAcceptor;
m_Session->AddSocket (shared_from_this ());
if (!m_Session->localDestination->IsAcceptingStreams ()) if (!m_Session->localDestination->IsAcceptingStreams ())
{ m_Session->localDestination->AcceptOnce (std::bind (&SAMSocket::HandleI2PAccept, shared_from_this (), std::placeholders::_1));
m_SocketType = eSAMSocketTypeAcceptor; SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false);
m_Session->AddSocket (shared_from_this ());
m_Session->localDestination->AcceptStreams (std::bind (&SAMSocket::HandleI2PAccept, shared_from_this (), std::placeholders::_1));
SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false);
}
else
SendMessageReply (SAM_STREAM_STATUS_I2P_ERROR, strlen(SAM_STREAM_STATUS_I2P_ERROR), true);
} }
else else
SendMessageReply (SAM_STREAM_STATUS_INVALID_ID, strlen(SAM_STREAM_STATUS_INVALID_ID), true); SendMessageReply (SAM_STREAM_STATUS_INVALID_ID, strlen(SAM_STREAM_STATUS_INVALID_ID), true);
@ -468,21 +464,21 @@ namespace client
std::string& name = params[SAM_PARAM_NAME]; std::string& name = params[SAM_PARAM_NAME];
std::shared_ptr<const i2p::data::IdentityEx> identity; std::shared_ptr<const i2p::data::IdentityEx> identity;
i2p::data::IdentHash ident; i2p::data::IdentHash ident;
auto dest = m_Session == nullptr ? context.GetSharedLocalDestination() : m_Session->localDestination;
if (name == "ME") if (name == "ME")
SendNamingLookupReply (m_Session->localDestination->GetIdentity ()); SendNamingLookupReply (dest->GetIdentity ());
else if ((identity = context.GetAddressBook ().GetAddress (name)) != nullptr) else if ((identity = context.GetAddressBook ().GetAddress (name)) != nullptr)
SendNamingLookupReply (identity); SendNamingLookupReply (identity);
else if (m_Session && m_Session->localDestination && else if (context.GetAddressBook ().GetIdentHash (name, ident))
context.GetAddressBook ().GetIdentHash (name, ident))
{ {
auto leaseSet = m_Session->localDestination->FindLeaseSet (ident); auto leaseSet = dest->FindLeaseSet (ident);
if (leaseSet) if (leaseSet)
SendNamingLookupReply (leaseSet->GetIdentity ()); SendNamingLookupReply (leaseSet->GetIdentity ());
else else
m_Session->localDestination->RequestDestination (ident, dest->RequestDestination (ident,
std::bind (&SAMSocket::HandleNamingLookupLeaseSetRequestComplete, std::bind (&SAMSocket::HandleNamingLookupLeaseSetRequestComplete,
shared_from_this (), std::placeholders::_1, ident)); shared_from_this (), std::placeholders::_1, ident));
} }
else else
{ {
LogPrint (eLogError, "SAM: naming failed, unknown address ", name); LogPrint (eLogError, "SAM: naming failed, unknown address ", name);
@ -577,8 +573,8 @@ namespace client
{ {
if (!ecode) if (!ecode)
s->Receive (); s->Receive ();
else else
s->Terminate (); s->m_Owner.GetService ().post ([s] { s->Terminate (); });
}); });
} }
} }
@ -622,10 +618,16 @@ namespace client
boost::asio::async_write (m_Socket, boost::asio::buffer (m_StreamBuffer, bytes_transferred), boost::asio::async_write (m_Socket, boost::asio::buffer (m_StreamBuffer, bytes_transferred),
std::bind (&SAMSocket::HandleWriteI2PData, shared_from_this (), std::placeholders::_1)); // postpone termination std::bind (&SAMSocket::HandleWriteI2PData, shared_from_this (), std::placeholders::_1)); // postpone termination
else else
Terminate (); {
auto s = shared_from_this ();
m_Owner.GetService ().post ([s] { s->Terminate (); });
}
} }
else else
Terminate (); {
auto s = shared_from_this ();
m_Owner.GetService ().post ([s] { s->Terminate (); });
}
} }
else else
{ {
@ -651,12 +653,20 @@ namespace client
if (stream) if (stream)
{ {
LogPrint (eLogDebug, "SAM: incoming I2P connection for session ", m_ID); LogPrint (eLogDebug, "SAM: incoming I2P connection for session ", m_ID);
m_SocketType = eSAMSocketTypeStream;
m_Stream = stream; m_Stream = stream;
context.GetAddressBook ().InsertAddress (stream->GetRemoteIdentity ()); context.GetAddressBook ().InsertAddress (stream->GetRemoteIdentity ());
auto session = m_Owner.FindSession (m_ID); auto session = m_Owner.FindSession (m_ID);
if (session) if (session)
session->localDestination->StopAcceptingStreams (); {
m_SocketType = eSAMSocketTypeStream; // find more pending acceptors
for (auto it: session->ListSockets ())
if (it->m_SocketType == eSAMSocketTypeAcceptor)
{
session->localDestination->AcceptOnce (std::bind (&SAMSocket::HandleI2PAccept, it, std::placeholders::_1));
break;
}
}
if (!m_IsSilent) if (!m_IsSilent)
{ {
// get remote peer address // get remote peer address

14
SSU.cpp

@ -154,16 +154,26 @@ namespace transport
} }
} }
void SSUServer::AddRelay (uint32_t tag, const boost::asio::ip::udp::endpoint& relay) void SSUServer::AddRelay (uint32_t tag, std::shared_ptr<SSUSession> relay)
{ {
m_Relays[tag] = relay; m_Relays[tag] = relay;
} }
void SSUServer::RemoveRelay (uint32_t tag)
{
m_Relays.erase (tag);
}
std::shared_ptr<SSUSession> SSUServer::FindRelaySession (uint32_t tag) std::shared_ptr<SSUSession> SSUServer::FindRelaySession (uint32_t tag)
{ {
auto it = m_Relays.find (tag); auto it = m_Relays.find (tag);
if (it != m_Relays.end ()) if (it != m_Relays.end ())
return FindSession (it->second); {
if (it->second->GetState () == eSessionStateEstablished)
return it->second;
else
m_Relays.erase (it);
}
return nullptr; return nullptr;
} }

5
SSU.h

@ -57,7 +57,8 @@ namespace transport
boost::asio::io_service& GetServiceV6 () { return m_ServiceV6; }; boost::asio::io_service& GetServiceV6 () { return m_ServiceV6; };
const boost::asio::ip::udp::endpoint& GetEndpoint () const { return m_Endpoint; }; const boost::asio::ip::udp::endpoint& GetEndpoint () const { return m_Endpoint; };
void Send (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& to); void Send (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& to);
void AddRelay (uint32_t tag, const boost::asio::ip::udp::endpoint& relay); void AddRelay (uint32_t tag, std::shared_ptr<SSUSession> relay);
void RemoveRelay (uint32_t tag);
std::shared_ptr<SSUSession> FindRelaySession (uint32_t tag); std::shared_ptr<SSUSession> FindRelaySession (uint32_t tag);
void NewPeerTest (uint32_t nonce, PeerTestParticipant role, std::shared_ptr<SSUSession> session = nullptr); void NewPeerTest (uint32_t nonce, PeerTestParticipant role, std::shared_ptr<SSUSession> session = nullptr);
@ -119,7 +120,7 @@ namespace transport
m_TerminationTimer, m_TerminationTimerV6; m_TerminationTimer, m_TerminationTimerV6;
std::list<boost::asio::ip::udp::endpoint> m_Introducers; // introducers we are connected to std::list<boost::asio::ip::udp::endpoint> m_Introducers; // introducers we are connected to
std::map<boost::asio::ip::udp::endpoint, std::shared_ptr<SSUSession> > m_Sessions, m_SessionsV6; std::map<boost::asio::ip::udp::endpoint, std::shared_ptr<SSUSession> > m_Sessions, m_SessionsV6;
std::map<uint32_t, boost::asio::ip::udp::endpoint> m_Relays; // we are introducer std::map<uint32_t, std::shared_ptr<SSUSession> > m_Relays; // we are introducer
std::map<uint32_t, PeerTest> m_PeerTests; // nonce -> creation time in milliseconds std::map<uint32_t, PeerTest> m_PeerTests; // nonce -> creation time in milliseconds
public: public:

6
SSUData.cpp

@ -371,7 +371,7 @@ namespace transport
void SSUData::SendMsgAck (uint32_t msgID) void SSUData::SendMsgAck (uint32_t msgID)
{ {
uint8_t buf[48 + 18]; // actual length is 44 = 37 + 7 but pad it to multiple of 16 uint8_t * buf = new uint8_t[48 + 18]; // actual length is 44 = 37 + 7 but pad it to multiple of 16
uint8_t * payload = buf + sizeof (SSUHeader); uint8_t * payload = buf + sizeof (SSUHeader);
*payload = DATA_FLAG_EXPLICIT_ACKS_INCLUDED; // flag *payload = DATA_FLAG_EXPLICIT_ACKS_INCLUDED; // flag
payload++; payload++;
@ -384,6 +384,7 @@ namespace transport
// encrypt message with session key // encrypt message with session key
m_Session.FillHeaderAndEncrypt (PAYLOAD_TYPE_DATA, buf, 48); m_Session.FillHeaderAndEncrypt (PAYLOAD_TYPE_DATA, buf, 48);
m_Session.Send (buf, 48); m_Session.Send (buf, 48);
delete [] buf;
} }
void SSUData::SendFragmentAck (uint32_t msgID, int fragmentNum) void SSUData::SendFragmentAck (uint32_t msgID, int fragmentNum)
@ -393,7 +394,7 @@ namespace transport
LogPrint (eLogWarning, "SSU: Fragment number ", fragmentNum, " exceeds 64"); LogPrint (eLogWarning, "SSU: Fragment number ", fragmentNum, " exceeds 64");
return; return;
} }
uint8_t buf[64 + 18]; uint8_t * buf = new uint8_t[64 + 18];
uint8_t * payload = buf + sizeof (SSUHeader); uint8_t * payload = buf + sizeof (SSUHeader);
*payload = DATA_FLAG_ACK_BITFIELDS_INCLUDED; // flag *payload = DATA_FLAG_ACK_BITFIELDS_INCLUDED; // flag
payload++; payload++;
@ -413,6 +414,7 @@ namespace transport
// encrypt message with session key // encrypt message with session key
m_Session.FillHeaderAndEncrypt (PAYLOAD_TYPE_DATA, buf, len); m_Session.FillHeaderAndEncrypt (PAYLOAD_TYPE_DATA, buf, len);
m_Session.Send (buf, len); m_Session.Send (buf, len);
delete [] buf;
} }
void SSUData::ScheduleResend() void SSUData::ScheduleResend()

47
SSUSession.cpp

@ -16,7 +16,7 @@ namespace transport
TransportSession (router, SSU_TERMINATION_TIMEOUT), TransportSession (router, SSU_TERMINATION_TIMEOUT),
m_Server (server), m_RemoteEndpoint (remoteEndpoint), m_ConnectTimer (GetService ()), m_Server (server), m_RemoteEndpoint (remoteEndpoint), m_ConnectTimer (GetService ()),
m_IsPeerTest (peerTest),m_State (eSessionStateUnknown), m_IsSessionKey (false), m_IsPeerTest (peerTest),m_State (eSessionStateUnknown), m_IsSessionKey (false),
m_RelayTag (0),m_Data (*this), m_IsDataReceived (false) m_RelayTag (0), m_SentRelayTag (0), m_Data (*this), m_IsDataReceived (false)
{ {
if (router) if (router)
{ {
@ -350,7 +350,7 @@ namespace transport
void SSUSession::SendSessionRequest () void SSUSession::SendSessionRequest ()
{ {
uint8_t buf[320 + 18]; // 304 bytes for ipv4, 320 for ipv6 uint8_t * buf = new uint8_t[320 + 18]; // 304 bytes for ipv4, 320 for ipv6
uint8_t * payload = buf + sizeof (SSUHeader); uint8_t * payload = buf + sizeof (SSUHeader);
uint8_t flag = 0; uint8_t flag = 0;
// fill extended options, 3 bytes extended options don't change message size // fill extended options, 3 bytes extended options don't change message size
@ -381,6 +381,7 @@ namespace transport
RAND_bytes (iv, 16); // random iv RAND_bytes (iv, 16); // random iv
FillHeaderAndEncrypt (PAYLOAD_TYPE_SESSION_REQUEST, buf, isV4 ? 304 : 320, m_IntroKey, iv, m_IntroKey, flag); FillHeaderAndEncrypt (PAYLOAD_TYPE_SESSION_REQUEST, buf, isV4 ? 304 : 320, m_IntroKey, iv, m_IntroKey, flag);
m_Server.Send (buf, isV4 ? 304 : 320, m_RemoteEndpoint); m_Server.Send (buf, isV4 ? 304 : 320, m_RemoteEndpoint);
delete [] buf;
} }
void SSUSession::SendRelayRequest (const i2p::data::RouterInfo::Introducer& introducer, uint32_t nonce) void SSUSession::SendRelayRequest (const i2p::data::RouterInfo::Introducer& introducer, uint32_t nonce)
@ -392,7 +393,7 @@ namespace transport
return; return;
} }
uint8_t buf[96 + 18]; uint8_t * buf = new uint8_t[96 + 18];
uint8_t * payload = buf + sizeof (SSUHeader); uint8_t * payload = buf + sizeof (SSUHeader);
htobe32buf (payload, introducer.iTag); htobe32buf (payload, introducer.iTag);
payload += 4; payload += 4;
@ -413,6 +414,7 @@ namespace transport
else else
FillHeaderAndEncrypt (PAYLOAD_TYPE_RELAY_REQUEST, buf, 96, introducer.iKey, iv, introducer.iKey); FillHeaderAndEncrypt (PAYLOAD_TYPE_RELAY_REQUEST, buf, 96, introducer.iKey, iv, introducer.iKey);
m_Server.Send (buf, 96, m_RemoteEndpoint); m_Server.Send (buf, 96, m_RemoteEndpoint);
delete [] buf;
} }
void SSUSession::SendSessionCreated (const uint8_t * x, bool sendRelayTag) void SSUSession::SendSessionCreated (const uint8_t * x, bool sendRelayTag)
@ -427,7 +429,7 @@ namespace transport
SignedData s; // x,y, remote IP, remote port, our IP, our port, relayTag, signed on time SignedData s; // x,y, remote IP, remote port, our IP, our port, relayTag, signed on time
s.Insert (x, 256); // x s.Insert (x, 256); // x
uint8_t buf[384 + 18]; uint8_t * buf = new uint8_t[384 + 18];
uint8_t * payload = buf + sizeof (SSUHeader); uint8_t * payload = buf + sizeof (SSUHeader);
memcpy (payload, m_DHKeysPair->GetPublicKey (), 256); memcpy (payload, m_DHKeysPair->GetPublicKey (), 256);
s.Insert (payload, 256); // y s.Insert (payload, 256); // y
@ -458,14 +460,13 @@ namespace transport
else else
s.Insert (address->host.to_v6 ().to_bytes ().data (), 16); // our IP V6 s.Insert (address->host.to_v6 ().to_bytes ().data (), 16); // our IP V6
s.Insert<uint16_t> (htobe16 (address->port)); // our port s.Insert<uint16_t> (htobe16 (address->port)); // our port
uint32_t relayTag = 0;
if (sendRelayTag && i2p::context.GetRouterInfo ().IsIntroducer () && !IsV6 ()) if (sendRelayTag && i2p::context.GetRouterInfo ().IsIntroducer () && !IsV6 ())
{ {
RAND_bytes((uint8_t *)&relayTag, 4); RAND_bytes((uint8_t *)&m_SentRelayTag, 4);
if (!relayTag) relayTag = 1; if (!m_SentRelayTag) m_SentRelayTag = 1;
m_Server.AddRelay (relayTag, m_RemoteEndpoint); m_Server.AddRelay (m_SentRelayTag, shared_from_this ());
} }
htobe32buf (payload, relayTag); htobe32buf (payload, m_SentRelayTag);
payload += 4; // relay tag payload += 4; // relay tag
htobe32buf (payload, i2p::util::GetSecondsSinceEpoch ()); // signed on time htobe32buf (payload, i2p::util::GetSecondsSinceEpoch ()); // signed on time
payload += 4; payload += 4;
@ -491,11 +492,12 @@ namespace transport
// encrypt message with intro key // encrypt message with intro key
FillHeaderAndEncrypt (PAYLOAD_TYPE_SESSION_CREATED, buf, msgLen, m_IntroKey, iv, m_IntroKey); FillHeaderAndEncrypt (PAYLOAD_TYPE_SESSION_CREATED, buf, msgLen, m_IntroKey, iv, m_IntroKey);
Send (buf, msgLen); Send (buf, msgLen);
delete [] buf;
} }
void SSUSession::SendSessionConfirmed (const uint8_t * y, const uint8_t * ourAddress, size_t ourAddressLen) void SSUSession::SendSessionConfirmed (const uint8_t * y, const uint8_t * ourAddress, size_t ourAddressLen)
{ {
uint8_t buf[512 + 18]; uint8_t * buf = new uint8_t[512 + 18];
uint8_t * payload = buf + sizeof (SSUHeader); uint8_t * payload = buf + sizeof (SSUHeader);
*payload = 1; // 1 fragment *payload = 1; // 1 fragment
payload++; // info payload++; // info
@ -534,6 +536,7 @@ namespace transport
// encrypt message with session key // encrypt message with session key
FillHeaderAndEncrypt (PAYLOAD_TYPE_SESSION_CONFIRMED, buf, msgLen, m_SessionKey, iv, m_MacKey); FillHeaderAndEncrypt (PAYLOAD_TYPE_SESSION_CONFIRMED, buf, msgLen, m_SessionKey, iv, m_MacKey);
Send (buf, msgLen); Send (buf, msgLen);
delete [] buf;
} }
void SSUSession::ProcessRelayRequest (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& from) void SSUSession::ProcessRelayRequest (const uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& from)
@ -561,14 +564,14 @@ namespace transport
void SSUSession::SendRelayResponse (uint32_t nonce, const boost::asio::ip::udp::endpoint& from, void SSUSession::SendRelayResponse (uint32_t nonce, const boost::asio::ip::udp::endpoint& from,
const uint8_t * introKey, const boost::asio::ip::udp::endpoint& to) const uint8_t * introKey, const boost::asio::ip::udp::endpoint& to)
{ {
uint8_t buf[80 + 18]; // 64 Alice's ipv4 and 80 Alice's ipv6
uint8_t * payload = buf + sizeof (SSUHeader);
// Charlie's address always v4 // Charlie's address always v4
if (!to.address ().is_v4 ()) if (!to.address ().is_v4 ())
{ {
LogPrint (eLogWarning, "SSU: Charlie's IP must be v4"); LogPrint (eLogWarning, "SSU: Charlie's IP must be v4");
return; return;
} }
uint8_t * buf = new uint8_t[80 + 18]; // 64 Alice's ipv4 and 80 Alice's ipv6
uint8_t * payload = buf + sizeof (SSUHeader);
*payload = 4; *payload = 4;
payload++; // size payload++; // size
htobe32buf (payload, to.address ().to_v4 ().to_ulong ()); // Charlie's IP htobe32buf (payload, to.address ().to_v4 ().to_ulong ()); // Charlie's IP
@ -610,6 +613,7 @@ namespace transport
m_Server.Send (buf, isV4 ? 64 : 80, from); m_Server.Send (buf, isV4 ? 64 : 80, from);
} }
LogPrint (eLogDebug, "SSU: relay response sent"); LogPrint (eLogDebug, "SSU: relay response sent");
delete [] buf;
} }
void SSUSession::SendRelayIntro (std::shared_ptr<SSUSession> session, const boost::asio::ip::udp::endpoint& from) void SSUSession::SendRelayIntro (std::shared_ptr<SSUSession> session, const boost::asio::ip::udp::endpoint& from)
@ -621,7 +625,7 @@ namespace transport
LogPrint (eLogWarning, "SSU: Alice's IP must be v4"); LogPrint (eLogWarning, "SSU: Alice's IP must be v4");
return; return;
} }
uint8_t buf[48 + 18]; uint8_t * buf = new uint8_t[48 + 18];
uint8_t * payload = buf + sizeof (SSUHeader); uint8_t * payload = buf + sizeof (SSUHeader);
*payload = 4; *payload = 4;
payload++; // size payload++; // size
@ -635,6 +639,7 @@ namespace transport
FillHeaderAndEncrypt (PAYLOAD_TYPE_RELAY_INTRO, buf, 48, session->m_SessionKey, iv, session->m_MacKey); FillHeaderAndEncrypt (PAYLOAD_TYPE_RELAY_INTRO, buf, 48, session->m_SessionKey, iv, session->m_MacKey);
m_Server.Send (buf, 48, session->m_RemoteEndpoint); m_Server.Send (buf, 48, session->m_RemoteEndpoint);
LogPrint (eLogDebug, "SSU: relay intro sent"); LogPrint (eLogDebug, "SSU: relay intro sent");
delete [] buf;
} }
void SSUSession::ProcessRelayResponse (const uint8_t * buf, size_t len) void SSUSession::ProcessRelayResponse (const uint8_t * buf, size_t len)
@ -870,6 +875,8 @@ namespace transport
transports.PeerDisconnected (shared_from_this ()); transports.PeerDisconnected (shared_from_this ());
m_Data.Stop (); m_Data.Stop ();
m_ConnectTimer.cancel (); m_ConnectTimer.cancel ();
if (m_SentRelayTag)
m_Server.RemoveRelay (m_SentRelayTag); // relay tag is not valid anymore
} }
void SSUSession::Done () void SSUSession::Done ()
@ -1038,7 +1045,7 @@ namespace transport
// toAddress is true for Alice<->Chalie communications only // toAddress is true for Alice<->Chalie communications only
// sendAddress is false if message comes from Alice // sendAddress is false if message comes from Alice
{ {
uint8_t buf[80 + 18]; uint8_t * buf = new uint8_t[80 + 18];
uint8_t iv[16]; uint8_t iv[16];
uint8_t * payload = buf + sizeof (SSUHeader); uint8_t * payload = buf + sizeof (SSUHeader);
htobe32buf (payload, nonce); htobe32buf (payload, nonce);
@ -1094,7 +1101,8 @@ namespace transport
// encrypt message with session key // encrypt message with session key
FillHeaderAndEncrypt (PAYLOAD_TYPE_PEER_TEST, buf, 80); FillHeaderAndEncrypt (PAYLOAD_TYPE_PEER_TEST, buf, 80);
Send (buf, 80); Send (buf, 80);
} }
delete [] buf;
} }
void SSUSession::SendPeerTest () void SSUSession::SendPeerTest ()
@ -1119,7 +1127,7 @@ namespace transport
{ {
if (m_State == eSessionStateEstablished) if (m_State == eSessionStateEstablished)
{ {
uint8_t buf[48 + 18]; uint8_t * buf = new uint8_t[48 + 18];
uint8_t * payload = buf + sizeof (SSUHeader); uint8_t * payload = buf + sizeof (SSUHeader);
*payload = 0; // flags *payload = 0; // flags
payload++; payload++;
@ -1129,6 +1137,7 @@ namespace transport
Send (buf, 48); Send (buf, 48);
LogPrint (eLogDebug, "SSU: keep-alive sent"); LogPrint (eLogDebug, "SSU: keep-alive sent");
m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch (); m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch ();
delete [] buf;
} }
} }
@ -1136,7 +1145,7 @@ namespace transport
{ {
if (m_IsSessionKey) if (m_IsSessionKey)
{ {
uint8_t buf[48 + 18]; uint8_t * buf = new uint8_t[48 + 18];
// encrypt message with session key // encrypt message with session key
FillHeaderAndEncrypt (PAYLOAD_TYPE_SESSION_DESTROYED, buf, 48); FillHeaderAndEncrypt (PAYLOAD_TYPE_SESSION_DESTROYED, buf, 48);
try try
@ -1148,12 +1157,13 @@ namespace transport
LogPrint (eLogWarning, "SSU: exception while sending session destoroyed: ", ex.what ()); LogPrint (eLogWarning, "SSU: exception while sending session destoroyed: ", ex.what ());
} }
LogPrint (eLogDebug, "SSU: session destroyed sent"); LogPrint (eLogDebug, "SSU: session destroyed sent");
delete [] buf;
} }
} }
void SSUSession::Send (uint8_t type, const uint8_t * payload, size_t len) void SSUSession::Send (uint8_t type, const uint8_t * payload, size_t len)
{ {
uint8_t buf[SSU_MTU_V4 + 18]; uint8_t * buf = new uint8_t[SSU_MTU_V4 + 18];
size_t msgSize = len + sizeof (SSUHeader); size_t msgSize = len + sizeof (SSUHeader);
size_t paddingSize = msgSize & 0x0F; // %16 size_t paddingSize = msgSize & 0x0F; // %16
if (paddingSize > 0) msgSize += (16 - paddingSize); if (paddingSize > 0) msgSize += (16 - paddingSize);
@ -1166,6 +1176,7 @@ namespace transport
// encrypt message with session key // encrypt message with session key
FillHeaderAndEncrypt (type, buf, msgSize); FillHeaderAndEncrypt (type, buf, msgSize);
Send (buf, msgSize); Send (buf, msgSize);
delete [] buf;
} }
void SSUSession::Send (const uint8_t * buf, size_t size) void SSUSession::Send (const uint8_t * buf, size_t size)

3
SSUSession.h

@ -141,7 +141,8 @@ namespace transport
bool m_IsPeerTest; bool m_IsPeerTest;
SessionState m_State; SessionState m_State;
bool m_IsSessionKey; bool m_IsSessionKey;
uint32_t m_RelayTag; uint32_t m_RelayTag; // received from peer
uint32_t m_SentRelayTag; // sent by us
i2p::crypto::CBCEncryption m_SessionKeyEncryption; i2p::crypto::CBCEncryption m_SessionKeyEncryption;
i2p::crypto::CBCDecryption m_SessionKeyDecryption; i2p::crypto::CBCDecryption m_SessionKeyDecryption;
i2p::crypto::AESKey m_SessionKey; i2p::crypto::AESKey m_SessionKey;

23
Streaming.cpp

@ -1037,6 +1037,29 @@ namespace stream
m_Acceptor = nullptr; m_Acceptor = nullptr;
} }
void StreamingDestination::AcceptOnce (const Acceptor& acceptor)
{
m_Owner->GetService ().post([acceptor, this](void)
{
if (!m_PendingIncomingStreams.empty ())
{
acceptor (m_PendingIncomingStreams.front ());
m_PendingIncomingStreams.pop_front ();
if (m_PendingIncomingStreams.empty ())
m_PendingIncomingTimer.cancel ();
}
else // we must save old acceptor and set it back
{
auto oldAcceptor = m_Acceptor;
m_Acceptor = [acceptor, oldAcceptor, this](std::shared_ptr<Stream> stream)
{
acceptor (stream);
m_Acceptor = oldAcceptor;
};
}
});
}
void StreamingDestination::HandlePendingIncomingTimer (const boost::system::error_code& ecode) void StreamingDestination::HandlePendingIncomingTimer (const boost::system::error_code& ecode)
{ {
if (ecode != boost::asio::error::operation_aborted) if (ecode != boost::asio::error::operation_aborted)

2
Streaming.h

@ -223,6 +223,8 @@ namespace stream
void SetAcceptor (const Acceptor& acceptor); void SetAcceptor (const Acceptor& acceptor);
void ResetAcceptor (); void ResetAcceptor ();
bool IsAcceptorSet () const { return m_Acceptor != nullptr; }; bool IsAcceptorSet () const { return m_Acceptor != nullptr; };
void AcceptOnce (const Acceptor& acceptor);
std::shared_ptr<i2p::client::ClientDestination> GetOwner () const { return m_Owner; }; std::shared_ptr<i2p::client::ClientDestination> GetOwner () const { return m_Owner; };
void SetOwner (std::shared_ptr<i2p::client::ClientDestination> owner) { m_Owner = owner; }; void SetOwner (std::shared_ptr<i2p::client::ClientDestination> owner) { m_Owner = owner; };
uint16_t GetLocalPort () const { return m_LocalPort; }; uint16_t GetLocalPort () const { return m_LocalPort; };

61
Transports.cpp

@ -108,8 +108,8 @@ namespace transport
Transports transports; Transports transports;
Transports::Transports (): Transports::Transports ():
m_IsOnline (true), m_IsRunning (false), m_Thread (nullptr), m_Work (m_Service), m_IsOnline (true), m_IsRunning (false), m_Thread (nullptr), m_Service (nullptr),
m_PeerCleanupTimer (m_Service), m_PeerTestTimer (m_Service), m_Work (nullptr), m_PeerCleanupTimer (nullptr), m_PeerTestTimer (nullptr),
m_NTCPServer (nullptr), m_SSUServer (nullptr), m_DHKeysPairSupplier (5), // 5 pre-generated keys m_NTCPServer (nullptr), m_SSUServer (nullptr), m_DHKeysPairSupplier (5), // 5 pre-generated keys
m_TotalSentBytes(0), m_TotalReceivedBytes(0), m_InBandwidth (0), m_OutBandwidth (0), m_TotalSentBytes(0), m_TotalReceivedBytes(0), m_InBandwidth (0), m_OutBandwidth (0),
m_LastInBandwidthUpdateBytes (0), m_LastOutBandwidthUpdateBytes (0), m_LastBandwidthUpdateTime (0) m_LastInBandwidthUpdateBytes (0), m_LastOutBandwidthUpdateBytes (0), m_LastBandwidthUpdateTime (0)
@ -119,10 +119,25 @@ namespace transport
Transports::~Transports () Transports::~Transports ()
{ {
Stop (); Stop ();
if (m_Service)
{
delete m_PeerCleanupTimer; m_PeerCleanupTimer = nullptr;
delete m_PeerTestTimer; m_PeerTestTimer = nullptr;
delete m_Work; m_Work = nullptr;
delete m_Service; m_Service = nullptr;
}
} }
void Transports::Start (bool enableNTCP, bool enableSSU) void Transports::Start (bool enableNTCP, bool enableSSU)
{ {
if (!m_Service)
{
m_Service = new boost::asio::io_service ();
m_Work = new boost::asio::io_service::work (*m_Service);
m_PeerCleanupTimer = new boost::asio::deadline_timer (*m_Service);
m_PeerTestTimer = new boost::asio::deadline_timer (*m_Service);
}
m_DHKeysPairSupplier.Start (); m_DHKeysPairSupplier.Start ();
m_IsRunning = true; m_IsRunning = true;
m_Thread = new std::thread (std::bind (&Transports::Run, this)); m_Thread = new std::thread (std::bind (&Transports::Run, this));
@ -167,16 +182,16 @@ namespace transport
LogPrint (eLogError, "Transports: SSU server already exists"); LogPrint (eLogError, "Transports: SSU server already exists");
} }
} }
m_PeerCleanupTimer.expires_from_now (boost::posix_time::seconds(5*SESSION_CREATION_TIMEOUT)); m_PeerCleanupTimer->expires_from_now (boost::posix_time::seconds(5*SESSION_CREATION_TIMEOUT));
m_PeerCleanupTimer.async_wait (std::bind (&Transports::HandlePeerCleanupTimer, this, std::placeholders::_1)); m_PeerCleanupTimer->async_wait (std::bind (&Transports::HandlePeerCleanupTimer, this, std::placeholders::_1));
m_PeerTestTimer.expires_from_now (boost::posix_time::minutes(PEER_TEST_INTERVAL)); m_PeerTestTimer->expires_from_now (boost::posix_time::minutes(PEER_TEST_INTERVAL));
m_PeerTestTimer.async_wait (std::bind (&Transports::HandlePeerTestTimer, this, std::placeholders::_1)); m_PeerTestTimer->async_wait (std::bind (&Transports::HandlePeerTestTimer, this, std::placeholders::_1));
} }
void Transports::Stop () void Transports::Stop ()
{ {
m_PeerCleanupTimer.cancel (); if (m_PeerCleanupTimer) m_PeerCleanupTimer->cancel ();
m_PeerTestTimer.cancel (); if (m_PeerTestTimer) m_PeerTestTimer->cancel ();
m_Peers.clear (); m_Peers.clear ();
if (m_SSUServer) if (m_SSUServer)
{ {
@ -193,7 +208,7 @@ namespace transport
m_DHKeysPairSupplier.Stop (); m_DHKeysPairSupplier.Stop ();
m_IsRunning = false; m_IsRunning = false;
m_Service.stop (); if (m_Service) m_Service->stop ();
if (m_Thread) if (m_Thread)
{ {
m_Thread->join (); m_Thread->join ();
@ -204,11 +219,11 @@ namespace transport
void Transports::Run () void Transports::Run ()
{ {
while (m_IsRunning) while (m_IsRunning && m_Service)
{ {
try try
{ {
m_Service.run (); m_Service->run ();
} }
catch (std::exception& ex) catch (std::exception& ex)
{ {
@ -251,7 +266,7 @@ namespace transport
#ifdef WITH_EVENTS #ifdef WITH_EVENTS
QueueIntEvent("transport.send", ident.ToBase64(), msgs.size()); QueueIntEvent("transport.send", ident.ToBase64(), msgs.size());
#endif #endif
m_Service.post (std::bind (&Transports::PostMessages, this, ident, msgs)); m_Service->post (std::bind (&Transports::PostMessages, this, ident, msgs));
} }
void Transports::PostMessages (i2p::data::IdentHash ident, std::vector<std::shared_ptr<i2p::I2NPMessage> > msgs) void Transports::PostMessages (i2p::data::IdentHash ident, std::vector<std::shared_ptr<i2p::I2NPMessage> > msgs)
@ -386,7 +401,7 @@ namespace transport
void Transports::RequestComplete (std::shared_ptr<const i2p::data::RouterInfo> r, const i2p::data::IdentHash& ident) void Transports::RequestComplete (std::shared_ptr<const i2p::data::RouterInfo> r, const i2p::data::IdentHash& ident)
{ {
m_Service.post (std::bind (&Transports::HandleRequestComplete, this, r, ident)); m_Service->post (std::bind (&Transports::HandleRequestComplete, this, r, ident));
} }
void Transports::HandleRequestComplete (std::shared_ptr<const i2p::data::RouterInfo> r, i2p::data::IdentHash ident) void Transports::HandleRequestComplete (std::shared_ptr<const i2p::data::RouterInfo> r, i2p::data::IdentHash ident)
@ -411,7 +426,7 @@ namespace transport
void Transports::NTCPResolve (const std::string& addr, const i2p::data::IdentHash& ident) void Transports::NTCPResolve (const std::string& addr, const i2p::data::IdentHash& ident)
{ {
auto resolver = std::make_shared<boost::asio::ip::tcp::resolver>(m_Service); auto resolver = std::make_shared<boost::asio::ip::tcp::resolver>(*m_Service);
resolver->async_resolve (boost::asio::ip::tcp::resolver::query (addr, ""), resolver->async_resolve (boost::asio::ip::tcp::resolver::query (addr, ""),
std::bind (&Transports::HandleNTCPResolve, this, std::bind (&Transports::HandleNTCPResolve, this,
std::placeholders::_1, std::placeholders::_2, ident, resolver)); std::placeholders::_1, std::placeholders::_2, ident, resolver));
@ -454,7 +469,7 @@ namespace transport
void Transports::SSUResolve (const std::string& addr, const i2p::data::IdentHash& ident) void Transports::SSUResolve (const std::string& addr, const i2p::data::IdentHash& ident)
{ {
auto resolver = std::make_shared<boost::asio::ip::tcp::resolver>(m_Service); auto resolver = std::make_shared<boost::asio::ip::tcp::resolver>(*m_Service);
resolver->async_resolve (boost::asio::ip::tcp::resolver::query (addr, ""), resolver->async_resolve (boost::asio::ip::tcp::resolver::query (addr, ""),
std::bind (&Transports::HandleSSUResolve, this, std::bind (&Transports::HandleSSUResolve, this,
std::placeholders::_1, std::placeholders::_2, ident, resolver)); std::placeholders::_1, std::placeholders::_2, ident, resolver));
@ -497,7 +512,7 @@ namespace transport
void Transports::CloseSession (std::shared_ptr<const i2p::data::RouterInfo> router) void Transports::CloseSession (std::shared_ptr<const i2p::data::RouterInfo> router)
{ {
if (!router) return; if (!router) return;
m_Service.post (std::bind (&Transports::PostCloseSession, this, router)); m_Service->post (std::bind (&Transports::PostCloseSession, this, router));
} }
void Transports::PostCloseSession (std::shared_ptr<const i2p::data::RouterInfo> router) void Transports::PostCloseSession (std::shared_ptr<const i2p::data::RouterInfo> router)
@ -584,7 +599,7 @@ namespace transport
void Transports::PeerConnected (std::shared_ptr<TransportSession> session) void Transports::PeerConnected (std::shared_ptr<TransportSession> session)
{ {
m_Service.post([session, this]() m_Service->post([session, this]()
{ {
auto remoteIdentity = session->GetRemoteIdentity (); auto remoteIdentity = session->GetRemoteIdentity ();
if (!remoteIdentity) return; if (!remoteIdentity) return;
@ -632,7 +647,7 @@ namespace transport
void Transports::PeerDisconnected (std::shared_ptr<TransportSession> session) void Transports::PeerDisconnected (std::shared_ptr<TransportSession> session)
{ {
m_Service.post([session, this]() m_Service->post([session, this]()
{ {
auto remoteIdentity = session->GetRemoteIdentity (); auto remoteIdentity = session->GetRemoteIdentity ();
if (!remoteIdentity) return; if (!remoteIdentity) return;
@ -679,7 +694,7 @@ namespace transport
if (profile) if (profile)
{ {
profile->TunnelNonReplied(); profile->TunnelNonReplied();
profile->Save(); profile->Save(it->first);
} }
std::unique_lock<std::mutex> l(m_PeersMutex); std::unique_lock<std::mutex> l(m_PeersMutex);
it = m_Peers.erase (it); it = m_Peers.erase (it);
@ -690,8 +705,8 @@ namespace transport
UpdateBandwidth (); // TODO: use separate timer(s) for it UpdateBandwidth (); // TODO: use separate timer(s) for it
if (i2p::context.GetStatus () == eRouterStatusTesting) // if still testing, repeat peer test if (i2p::context.GetStatus () == eRouterStatusTesting) // if still testing, repeat peer test
DetectExternalIP (); DetectExternalIP ();
m_PeerCleanupTimer.expires_from_now (boost::posix_time::seconds(5*SESSION_CREATION_TIMEOUT)); m_PeerCleanupTimer->expires_from_now (boost::posix_time::seconds(5*SESSION_CREATION_TIMEOUT));
m_PeerCleanupTimer.async_wait (std::bind (&Transports::HandlePeerCleanupTimer, this, std::placeholders::_1)); m_PeerCleanupTimer->async_wait (std::bind (&Transports::HandlePeerCleanupTimer, this, std::placeholders::_1));
} }
} }
@ -700,8 +715,8 @@ namespace transport
if (ecode != boost::asio::error::operation_aborted) if (ecode != boost::asio::error::operation_aborted)
{ {
PeerTest (); PeerTest ();
m_PeerTestTimer.expires_from_now (boost::posix_time::minutes(PEER_TEST_INTERVAL)); m_PeerTestTimer->expires_from_now (boost::posix_time::minutes(PEER_TEST_INTERVAL));
m_PeerTestTimer.async_wait (std::bind (&Transports::HandlePeerTestTimer, this, std::placeholders::_1)); m_PeerTestTimer->async_wait (std::bind (&Transports::HandlePeerTestTimer, this, std::placeholders::_1));
} }
} }

8
Transports.h

@ -84,7 +84,7 @@ namespace transport
bool IsOnline() const { return m_IsOnline; }; bool IsOnline() const { return m_IsOnline; };
void SetOnline (bool online) { m_IsOnline = online; }; void SetOnline (bool online) { m_IsOnline = online; };
boost::asio::io_service& GetService () { return m_Service; }; boost::asio::io_service& GetService () { return *m_Service; };
std::shared_ptr<i2p::crypto::DHKeys> GetNextDHKeysPair (); std::shared_ptr<i2p::crypto::DHKeys> GetNextDHKeysPair ();
void ReuseDHKeysPair (std::shared_ptr<i2p::crypto::DHKeys> pair); void ReuseDHKeysPair (std::shared_ptr<i2p::crypto::DHKeys> pair);
@ -144,9 +144,9 @@ namespace transport
bool m_IsOnline, m_IsRunning; bool m_IsOnline, m_IsRunning;
std::thread * m_Thread; std::thread * m_Thread;
boost::asio::io_service m_Service; boost::asio::io_service * m_Service;
boost::asio::io_service::work m_Work; boost::asio::io_service::work * m_Work;
boost::asio::deadline_timer m_PeerCleanupTimer, m_PeerTestTimer; boost::asio::deadline_timer * m_PeerCleanupTimer, * m_PeerTestTimer;
NTCPServer * m_NTCPServer; NTCPServer * m_NTCPServer;
SSUServer * m_SSUServer; SSUServer * m_SSUServer;

3
TunnelConfig.h

@ -101,8 +101,7 @@ namespace tunnel
htobe32buf (clearText + BUILD_REQUEST_RECORD_REQUEST_TIME_OFFSET, i2p::util::GetHoursSinceEpoch ()); htobe32buf (clearText + BUILD_REQUEST_RECORD_REQUEST_TIME_OFFSET, i2p::util::GetHoursSinceEpoch ());
htobe32buf (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET, replyMsgID); htobe32buf (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET, replyMsgID);
RAND_bytes (clearText + BUILD_REQUEST_RECORD_PADDING_OFFSET, BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE - BUILD_REQUEST_RECORD_PADDING_OFFSET); RAND_bytes (clearText + BUILD_REQUEST_RECORD_PADDING_OFFSET, BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE - BUILD_REQUEST_RECORD_PADDING_OFFSET);
i2p::crypto::ElGamalEncryption elGamalEncryption (ident->GetEncryptionPublicKey ()); i2p::crypto::ElGamalEncrypt (ident->GetEncryptionPublicKey (), clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET);
elGamalEncryption.Encrypt (clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET);
memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16);
} }
}; };

17
TunnelGateway.cpp

@ -20,6 +20,7 @@ namespace tunnel
TunnelGatewayBuffer::~TunnelGatewayBuffer () TunnelGatewayBuffer::~TunnelGatewayBuffer ()
{ {
ClearTunnelDataMsgs ();
} }
void TunnelGatewayBuffer::PutI2NPMsg (const TunnelMessageBlock& block) void TunnelGatewayBuffer::PutI2NPMsg (const TunnelMessageBlock& block)
@ -48,7 +49,7 @@ namespace tunnel
di[0] = block.deliveryType << 5; // set delivery type di[0] = block.deliveryType << 5; // set delivery type
// create fragments // create fragments
std::shared_ptr<I2NPMessage> msg = block.data; const std::shared_ptr<I2NPMessage> & msg = block.data;
size_t fullMsgLen = diLen + msg->GetLength () + 2; // delivery instructions + payload + 2 bytes length size_t fullMsgLen = diLen + msg->GetLength () + 2; // delivery instructions + payload + 2 bytes length
if (fullMsgLen <= m_RemainingSize) if (fullMsgLen <= m_RemainingSize)
{ {
@ -115,9 +116,13 @@ namespace tunnel
m_CurrentTunnelDataMsg->len += s+7; m_CurrentTunnelDataMsg->len += s+7;
if (isLastFragment) if (isLastFragment)
{ {
m_RemainingSize -= s+7; if(m_RemainingSize < (s+7)) {
if (!m_RemainingSize) LogPrint (eLogError, "TunnelGateway: remaining size overflow: ", m_RemainingSize, " < ", s+7);
CompleteCurrentTunnelDataMessage (); } else {
m_RemainingSize -= s+7;
if (m_RemainingSize == 0)
CompleteCurrentTunnelDataMessage ();
}
} }
else else
CompleteCurrentTunnelDataMessage (); CompleteCurrentTunnelDataMessage ();
@ -138,10 +143,12 @@ namespace tunnel
void TunnelGatewayBuffer::ClearTunnelDataMsgs () void TunnelGatewayBuffer::ClearTunnelDataMsgs ()
{ {
m_TunnelDataMsgs.clear (); m_TunnelDataMsgs.clear ();
m_CurrentTunnelDataMsg = nullptr;
} }
void TunnelGatewayBuffer::CreateCurrentTunnelDataMessage () void TunnelGatewayBuffer::CreateCurrentTunnelDataMessage ()
{ {
m_CurrentTunnelDataMsg = nullptr;
m_CurrentTunnelDataMsg = NewI2NPShortMessage (); m_CurrentTunnelDataMsg = NewI2NPShortMessage ();
m_CurrentTunnelDataMsg->Align (12); m_CurrentTunnelDataMsg->Align (12);
// we reserve space for padding // we reserve space for padding
@ -196,7 +203,7 @@ namespace tunnel
void TunnelGateway::SendBuffer () void TunnelGateway::SendBuffer ()
{ {
m_Buffer.CompleteCurrentTunnelDataMessage (); m_Buffer.CompleteCurrentTunnelDataMessage ();
auto tunnelMsgs = m_Buffer.GetTunnelDataMsgs (); const auto & tunnelMsgs = m_Buffer.GetTunnelDataMsgs ();
for (auto& tunnelMsg : tunnelMsgs) for (auto& tunnelMsg : tunnelMsgs)
{ {
m_Tunnel->EncryptTunnelMsg (tunnelMsg, tunnelMsg); m_Tunnel->EncryptTunnelMsg (tunnelMsg, tunnelMsg);

2
Win32/installer.iss

@ -1,5 +1,5 @@
#define I2Pd_AppName "i2pd" #define I2Pd_AppName "i2pd"
#define I2Pd_ver "2.10.2" #define I2Pd_ver "2.11.0"
#define I2Pd_Publisher "PurpleI2P" #define I2Pd_Publisher "PurpleI2P"
[Setup] [Setup]

2
android/AndroidManifest.xml

@ -2,7 +2,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.purplei2p.i2pd" package="org.purplei2p.i2pd"
android:versionCode="1" android:versionCode="1"
android:versionName="2.10.2"> android:versionName="2.11.0">
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="24"/> <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="24"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>

32
contrib/certificates/reseed/cheezybudz_at_mail.i2p.crt

@ -1,32 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIFhTCCA22gAwIBAgIEeCJXkjANBgkqhkiG9w0BAQ0FADBzMQswCQYDVQQGEwJY
WDELMAkGA1UECBMCWFgxCzAJBgNVBAcTAlhYMR4wHAYDVQQKExVJMlAgQW5vbnlt
b3VzIE5ldHdvcmsxDDAKBgNVBAsTA0kyUDEcMBoGA1UEAwwTY2hlZXp5YnVkekBt
YWlsLmkycDAeFw0xNDEyMTYyMTU3MTZaFw0yNDEyMTUyMTU3MTZaMHMxCzAJBgNV
BAYTAlhYMQswCQYDVQQIEwJYWDELMAkGA1UEBxMCWFgxHjAcBgNVBAoTFUkyUCBB
bm9ueW1vdXMgTmV0d29yazEMMAoGA1UECxMDSTJQMRwwGgYDVQQDDBNjaGVlenli
dWR6QG1haWwuaTJwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAgLkj
Jsp8pjRi5N/JHHz+MXisgbI9G0vpd3yDhHvae3oF87iiQbxflcdcoH0l5RZL0cAn
w4amhqoOk2qhf+NSAEkiPWhk7CzPBRwDExEM/gmHYLWXbfnoHGaEls9ORGuDlDmN
hCFJVrxaZocIOi/7gZ4A+tC8wq+1aoe0Yhr381OW59w9AdUAWjBWibO3V59dEklL
7HqfOc2v7AMKDLJWgPekj8ZbqA9lRxHM6Djtjz4d9QXeQa8j3xLXTX1QbkvJBBX1
9Rzi/Nzv622lzoZ/Z/61jW7Bz+h9aJ6qp4on9K4ygUw/VduTOH/1ryQmw87x4MFQ
Z/Y86lOl7XZxBjtpYpGQW/5LmBe2BCfWgIYe9N5ionNgAe5TNEIDngP9AvJmcTyF
KcGgOgXQO9EeHEdgf4nC6RbGrb2sBtRjWJv5nOhHRG9tpwYkw/Zc5ZNHOymYpPMg
wce3me+1psJFt+gXhDcvxpRgTZpXfz91K/nKt3+szcYFluqhJLi6nL1TmXQVn51X
lGD1bcy1VUof+uKyb223JX5rm9WQ48GzUfy5cK4o+khEo0RLb21FwG5iJwVzhtoN
xQS1TO6pwLn8Si1ePRwntzlOm8DPIwdUkPBQNJ9DDkcdVia2GgbVM6LH8lrukekq
soYfwmOTsFRkGo04ujDI/IeMrl3zmJphyQkGx18CAwEAAaMhMB8wHQYDVR0OBBYE
FJ2MHeHnfCpEuYvC/9eK2ML9ne2eMA0GCSqGSIb3DQEBDQUAA4ICAQA3XUS7Zw1i
RJWPSu2oLzV7oTtIW5po2Gd5BL3oU6BvlK1zLw/z/soF/LopeHQudBYxYckyv4MG
gTNS9fcKkVdhNyLI/R2S0nQ/VFhTzuvq8HnnTOpvopA/cXTQlgrhGB2ajIZMYsXe
lei0V5H23etXTbYZWK6/IgoALk5vowde9lpJEIBhupIafqFg0tAo4LX07/eNxDOp
nXrShsYhHNaRhglS+0Gqj1UK0WvgMJxQKJm/VLi7jx8vfRkqXs/b76XT+VMQuUJd
l5llQwpOicQhX/ZTAO+iWrDaO7mz/ZDweLxnfWd3m2JwDJlE9K5l98zdcve96NRZ
ePnK8vBoAPQ9iHhwFSC5GpirK1KmT/BDLjqEF3H/HgPdPWSh97AUFpBryEIdZk1q
Czi9DCvwHNpbpI20Fo48+2N7sbvq4onZZqx5V0SjTj/9bHSSDwG9ok1JqWoZmRvo
p4MIywAJowlvPNc++jSHT3R7segeNUi/UdYCmm70j1av+0aEknmvPtF6atsHJ22X
5OMBhiPi1pudFWFJFWk4WOjrK/juwHHfHNgFVyziva4q6wPKrPno0gO5pCpfRUld
QAoSPgo8LAB3dugt5Xfsuone2GhLi1SLQlWFJWHswd/ypWa0FB+xn6Edkc1noOWY
06dwfEP/gTCAnSplLyrFWxnyHManBxq/bQ==
-----END CERTIFICATE-----

33
contrib/certificates/reseed/hottuna_at_mail.i2p.crt

@ -0,0 +1,33 @@
-----BEGIN CERTIFICATE-----
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
-----END CERTIFICATE-----

34
contrib/certificates/reseed/j_at_torontocrypto.org.crt

@ -1,34 +0,0 @@
-----BEGIN CERTIFICATE-----
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
-----END CERTIFICATE-----

19
contrib/certificates/ssl/download.xxlspeed.com.crt

@ -1,19 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIDLDCCArKgAwIBAgIJAMOgj4vE9qpcMAoGCCqGSM49BAMEMIHTMQswCQYDVQQG
EwJERTEeMBwGA1UECAwVZG93bmxvYWQueHhsc3BlZWQuY29tMR4wHAYDVQQHDBVk
b3dubG9hZC54eGxzcGVlZC5jb20xHjAcBgNVBAoMFWRvd25sb2FkLnh4bHNwZWVk
LmNvbTEeMBwGA1UECwwVZG93bmxvYWQueHhsc3BlZWQuY29tMR4wHAYDVQQDDBVk
b3dubG9hZC54eGxzcGVlZC5jb20xJDAiBgkqhkiG9w0BCQEWFWRvd25sb2FkLnh4
bHNwZWVkLmNvbTAeFw0xNTEyMzAxMTI4NDJaFw0yMTA2MjExMTI4NDJaMIHTMQsw
CQYDVQQGEwJERTEeMBwGA1UECAwVZG93bmxvYWQueHhsc3BlZWQuY29tMR4wHAYD
VQQHDBVkb3dubG9hZC54eGxzcGVlZC5jb20xHjAcBgNVBAoMFWRvd25sb2FkLnh4
bHNwZWVkLmNvbTEeMBwGA1UECwwVZG93bmxvYWQueHhsc3BlZWQuY29tMR4wHAYD
VQQDDBVkb3dubG9hZC54eGxzcGVlZC5jb20xJDAiBgkqhkiG9w0BCQEWFWRvd25s
b2FkLnh4bHNwZWVkLmNvbTB2MBAGByqGSM49AgEGBSuBBAAiA2IABFObW+pRshVD
gvMPvGdPGji2DAfdvkl3gvpyiQ0PUqxuTxwtBlwBo6cz2cMnkKdActuvE/VOTRG5
/z7CcvG7b0+qgrHDffg7C2wWlAN0dSjuoV2Av7VoN1vEU96TCtheSqNQME4wHQYD
VR0OBBYEFPbEZH9oidjadUfvsnsh23b1jZnVMB8GA1UdIwQYMBaAFPbEZH9oidja
dUfvsnsh23b1jZnVMAwGA1UdEwQFMAMBAf8wCgYIKoZIzj0EAwQDaAAwZQIwT1py
AV2hLFL/5ZgwmybdaCBBUsj3cGYroXb/Z2BHLDYmH8enK0DhhWyPdN1a7eCsAjEA
oQRU7lhXrisckjA2911Q5mA8y2sFAN/PDPrUeU9PI5vDF/ezTi20zULMOqbU1uRz
-----END CERTIFICATE-----

23
contrib/certificates/ssl/i2p.mooo.com.crt

@ -1,23 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIDvTCCAqWgAwIBAgIJAOeW0ejPrHimMA0GCSqGSIb3DQEBCwUAMHUxCzAJBgNV
BAYTAlVTMQ0wCwYDVQQIDARub25lMQ0wCwYDVQQHDARub25lMQ0wCwYDVQQKDARu
b25lMQ0wCwYDVQQLDARub25lMRUwEwYDVQQDDAxpMnAubW9vby5jb20xEzARBgkq
hkiG9w0BCQEWBG5vbmUwHhcNMTUwMjA4MTczMzA5WhcNMTkwMzE5MTczMzA5WjB1
MQswCQYDVQQGEwJVUzENMAsGA1UECAwEbm9uZTENMAsGA1UEBwwEbm9uZTENMAsG
A1UECgwEbm9uZTENMAsGA1UECwwEbm9uZTEVMBMGA1UEAwwMaTJwLm1vb28uY29t
MRMwEQYJKoZIhvcNAQkBFgRub25lMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAqxej7oRl9GOb8benIBCENrJXoow1iWhI9M+2nU0SaonrCDql5M2YMlwd
HzYUWtFbRjz2NinjB0fgFq9cfzHfr1Sc8k/OeGg1jvNfqt8wWo9tryQNjiHtDQUZ
6lQ5T13I+lj0CBasowgbApKQfrYjvaeuTaVYTfP8IVA60hoUQ+sy9JN+Unsx3/0Y
PLLd98+bT27qYuBNRB1g/ifUTd9Wosj2PevGBlCxYDaUjmCG4Q8kcQr87KvM6RTu
3AV61s/Wyy1j2YemlGG/ZhJ44YnlVMSu1vTjt9HInVf3lRRx/+RzbQO3lqeVC8LC
Bq3KbSlfJVx4vHslfHwBFw9A4rmD1QIDAQABo1AwTjAdBgNVHQ4EFgQUsSUvX0ED
yivB67iksVwZ+b8vLtQwHwYDVR0jBBgwFoAUsSUvX0EDyivB67iksVwZ+b8vLtQw
DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAde4wts7Q8TylFEc38ftJ
2f285fFIR7P1SSbBcHPK2eBwLEg0zJyFrCeiHuEpPrn+d5GqL2zOskjfcESGmDBT
aFajj8jPBJj/AmpkdWJG6a1YKro5tu9wrlenGwHOHu2/Cl0IJvafxrOs2x4G+2Nl
5Hcw/FIy8mK7eIch4pACfi0zNMZ6KMCKfX9bxPrQo78WdBfVjbrIBlgyOQJ5NJEF
JlWvS7Butv7eERi4I2huN5VRJSCFzjbuO+tjP3I8IB6WgdBmTeqq8ObtXRgahBuD
ZmkvqVSfIzK5JN4GjO8FOdCBomuwm9A92kgmAptwQwAHM9qCDJpH8L07/7poxlGb
iA==
-----END CERTIFICATE-----

27
contrib/certificates/ssl/i2pseed.zarrenspry.info.crt

@ -1,27 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIEkzCCA3ugAwIBAgIJAKsW7idQxp0aMA0GCSqGSIb3DQEBCwUAMIHfMQswCQYD
VQQGEwJVSzEgMB4GA1UECAwXaTJwc2VlZC56YXJyZW5zcHJ5LmluZm8xIDAeBgNV
BAcMF2kycHNlZWQuemFycmVuc3ByeS5pbmZvMSAwHgYDVQQKDBdpMnBzZWVkLnph
cnJlbnNwcnkuaW5mbzEgMB4GA1UECwwXaTJwc2VlZC56YXJyZW5zcHJ5LmluZm8x
IDAeBgNVBAMMF2kycHNlZWQuemFycmVuc3ByeS5pbmZvMSYwJAYJKoZIhvcNAQkB
FhdpMnBzZWVkLnphcnJlbnNwcnkuaW5mbzAeFw0xNDEyMjgxOTI3MDdaFw0xOTAy
MDUxOTI3MDdaMIHfMQswCQYDVQQGEwJVSzEgMB4GA1UECAwXaTJwc2VlZC56YXJy
ZW5zcHJ5LmluZm8xIDAeBgNVBAcMF2kycHNlZWQuemFycmVuc3ByeS5pbmZvMSAw
HgYDVQQKDBdpMnBzZWVkLnphcnJlbnNwcnkuaW5mbzEgMB4GA1UECwwXaTJwc2Vl
ZC56YXJyZW5zcHJ5LmluZm8xIDAeBgNVBAMMF2kycHNlZWQuemFycmVuc3ByeS5p
bmZvMSYwJAYJKoZIhvcNAQkBFhdpMnBzZWVkLnphcnJlbnNwcnkuaW5mbzCCASIw
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANrEncHwS+7R0Ti/jZa2Ex7ujglV
huYO59nLxeAOpEQwn6V41X5+L0hmhM0zuYavuP1jzKfF/Cn0CG1PqkGbEnXrTOGf
4gMj2wy/UVVFXaPQwldi+CEiNo6nI5S+T/upg5VK6M5/ahYbfIbX5xF27QNPV5qW
RnM0VK4gIQkFFtpiI0dFcEU9VYe+cg7a4Jvxc5LzqaIBZHWMX6alPfBT70LkYiiQ
76IRw5oBmqZjfIdiudRhFkezMkDomKSgLR2/0HJbekq2WeLXJLMPM1rdpCYldBEi
t6Zng9uAJa1mA6Al4RhO1aQEPj9Vo5h+Vj6FHJAJJcb+YW6wLKBkJVGLF4UCAwEA
AaNQME4wHQYDVR0OBBYEFL538Fr1l/9YQgG+iZvJUuOzAaVaMB8GA1UdIwQYMBaA
FL538Fr1l/9YQgG+iZvJUuOzAaVaMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEL
BQADggEBAKq7KEnR0V43PsA5D23Lhawy5W/BDs4RO3LkYSxi+zR4EAMC8RhafrmG
6IZVp+ykplZtFK3Kkw1osakcvmHRLoPCXPWLibXtWMEpmH4GhWJKf5Ct1kY0VkEE
ALP7vCtjDm5l6WBaNOZYv25wwg5wgjyhzfJtLxzyRRPOjUuv0M3FFwJEAauzoo+4
nle91IHNcWPIq1kgWUwWBHpLgZ2RpSOZS9MBOCkjHwQhoebhpgwSPgUHvBJ7FoLb
AeAdwpgPdIQ9gZEZEPfCPfG/Qp60yLAhkT2CF7F1h47VYe8LGBDbd1HGpSwjulq/
lnvV4zDIoKhbQhUpxwgHo79nxcgddOA=
-----END CERTIFICATE-----

23
contrib/certificates/ssl/netdb.i2p2.no.crt

@ -1,23 +0,0 @@
-----BEGIN CERTIFICATE-----
MIID1TCCAr2gAwIBAgIJAOd9wIt+w/I5MA0GCSqGSIb3DQEBCwUAMIGAMQswCQYD
VQQGEwJOTzENMAsGA1UECAwET3NsbzENMAsGA1UEBwwET3NsbzEMMAoGA1UECgwD
STJQMQwwCgYDVQQLDANJMlAxFjAUBgNVBAMMDW5ldGRiLmkycDIubm8xHzAdBgkq
hkiG9w0BCQEWEG1lZWhAaTJwbWFpbC5vcmcwHhcNMTQxMjA2MjM1OTM1WhcNMjAw
NTI4MjM1OTM1WjCBgDELMAkGA1UEBhMCTk8xDTALBgNVBAgMBE9zbG8xDTALBgNV
BAcMBE9zbG8xDDAKBgNVBAoMA0kyUDEMMAoGA1UECwwDSTJQMRYwFAYDVQQDDA1u
ZXRkYi5pMnAyLm5vMR8wHQYJKoZIhvcNAQkBFhBtZWVoQGkycG1haWwub3JnMIIB
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmtRtAALMImh0G0X+AtMpJNBa
HduNkg5t+0juitKRboXXAp5k7yN9qnimlBxlAicNb+QubcDuL+WV91NKz43dd6Xp
SAewqMFRPUAki8uYzoh+hQEfzyd3NmadUKquYZsYwomhHnraOmLZLbxD6ED3FEwl
hGBJwYnhyMZUCgB5+DEEHg8RdLz+H0bMrwz3e7/0lMtH6lM1lIHz0KBULWLp7Om0
sk3rmmhPUIXqfoY8X3vClI74o0KcslMVaF4rt3lAHdoi3lwA6Qbdqq9nC9rPWHUS
USQQ/MKsNfDTGsHkbW2l0VgNvJkw92DwHTXSJrsEqgkdV/B1hHxCKgL44c/CbwID
AQABo1AwTjAdBgNVHQ4EFgQUCkebDZE05yKMbXORa6gO+aLdCscwHwYDVR0jBBgw
FoAUCkebDZE05yKMbXORa6gO+aLdCscwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0B
AQsFAAOCAQEAfHO0g5M//X5xDIuXGCeqQMUrF3r1N45a+0kqo2b/rd9USueNGrJl
KE7MfDgShy2d4strZ1m0M4StW0RlUUZ4V4FYwzcknF6VXbOQK3BTrAeOwuxsrHoT
abrMZ36ABYur5WakOYtPyQ5oXFUAIpGBe9LH7q3XLegSOfftvc2xdJ+VK0n4MEfY
GfaRGMNW/pxGYLWvao3soOJMtp6cQ5KIYGuX92DMon/UgPBqEygeUj7aIqjhRss0
b0dUZQyHccAG+e5NeTF2ifHCEh2rZY18VGxPL7KLrCQigu5lif1TTv5CDO5rKrHl
TuTOsnooMxUH4ThIVI9cxXk6bzRMehLghA==
-----END CERTIFICATE-----

24
contrib/certificates/ssl/reseed.i2p-projekt.de.crt

@ -1,24 +0,0 @@
-----BEGIN CERTIFICATE-----
MIID7TCCAtWgAwIBAgIJAOHakoadaLRiMA0GCSqGSIb3DQEBBQUAMIGMMQswCQYD
VQQGEwJBVDEQMA4GA1UECAwHQXVzdHJpYTENMAsGA1UEBwwER3JhejEMMAoGA1UE
CgwDSTJQMQ8wDQYDVQQLDAZSZXNlZWQxHjAcBgNVBAMMFXJlc2VlZC5pMnAtcHJv
amVrdC5kZTEdMBsGCSqGSIb3DQEJARYOcmVzZWVkQGkycDIuZGUwHhcNMTQwNTEw
MTAxOTM3WhcNMjQwNTA3MTAxOTM3WjCBjDELMAkGA1UEBhMCQVQxEDAOBgNVBAgM
B0F1c3RyaWExDTALBgNVBAcMBEdyYXoxDDAKBgNVBAoMA0kyUDEPMA0GA1UECwwG
UmVzZWVkMR4wHAYDVQQDDBVyZXNlZWQuaTJwLXByb2pla3QuZGUxHTAbBgkqhkiG
9w0BCQEWDnJlc2VlZEBpMnAyLmRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEA8t5igIeAUZVX9k/A2gudRWVfToIV4yvlxmnH9UTJ8DTkWfHGbY9MmW2+
b0ZdvIZDcgg1nvcLEKqCDQnIp3wLGdM8fdVSXqxA1dLyHdk6IrGVqb60qpGENeIc
EHiUeB1g0KqP4kLcj2sNlo+Vupjnu7qS8v0/LfZ3fq2m4vtx8dYnvo+JIzGL9K0f
/DOil8QIcdTZupzMbXd6P936Blm/1RdbW/uKROOuuYE38NwYOUCq2/Nd+T86S5DD
9wQBjy0U+9nNayWf6BOSuP6m2mxx/pA1CvKRq7CzI0Gqjo2Msd+i0dTL2WIO2JDp
5uykZ0GabRW3UrMEuyrzzK6U2RZ1dQIDAQABo1AwTjAdBgNVHQ4EFgQUIejD2MMl
6PpcCernYd3ku3sEWfswHwYDVR0jBBgwFoAUIejD2MMl6PpcCernYd3ku3sEWfsw
DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAupUg3ZTBSE7iRebjcZ+y
zgnRaClmgrv8Mpa1/weTuXKhJZ65k6+G5mplI5hN/crKi/3b6oyfRrYhgdTdb0rD
2CbrhBkPGGlubhkjkxWjAhibzU6Kt3a7WOjykGnslpCZhwS/hiVB7ZE2JGdphFld
aJTKt12CytyP3GyIQyyX7O2t92dk8cW4tlxRVpaPNr59lk0V50qpvNmNyhxv3yDz
taop/etfjHStq1YrltHWH0d4Dxy8ubb7nV19uvPcE0+MrR2xm7jvOBfGjAf1bQ7Z
rk7RMHio4xWFJZO7TSzL5/8EH2jX6ZqpH+hZ6sV8TmzuRWsPkm0doXWr+HBZ/gMt
5w==
-----END CERTIFICATE-----

33
contrib/certificates/ssl/reseed.i2p.vzaws.com.crt

@ -1,33 +0,0 @@
-----BEGIN CERTIFICATE-----
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
-----END CERTIFICATE-----

33
contrib/certificates/ssl/uk.reseed.i2p2.no.crt

@ -1,33 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIFsTCCA5mgAwIBAgIJANgzPow6thRuMA0GCSqGSIb3DQEBBQUAMG8xCzAJBgNV
BAYTAk5PMQ0wCwYDVQQIDARPc2xvMQswCQYDVQQHDAJVSzETMBEGA1UECgwKSTJQ
IFJlc2VlZDETMBEGA1UECwwKSTJQIFJlc2VlZDEaMBgGA1UEAwwRdWsucmVzZWVk
LmkycDIubm8wHhcNMTQwNjI4MjA0OTA3WhcNMjQwNjI1MjA0OTA3WjBvMQswCQYD
VQQGEwJOTzENMAsGA1UECAwET3NsbzELMAkGA1UEBwwCVUsxEzARBgNVBAoMCkky
UCBSZXNlZWQxEzARBgNVBAsMCkkyUCBSZXNlZWQxGjAYBgNVBAMMEXVrLnJlc2Vl
ZC5pMnAyLm5vMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxlVlXWn5
Ham6ZqM6FkH6ZoXeXbncY/PnF669mCPcrPH56V2xZXwpeCXHWfu7YiHuhXXZSmzP
zwRrawHZTJulHt4e6j27JnDuEj69gmFpyi4B1djQ0kav0aJeagwCPG2do/UD7Cbr
4nITkU4CifLe47IUW/2K/EBI6bZGsRIDHJ3A+fAQmLnvehEkpvLN+cvtkpJOtZYx
6WvbwLsirkISnaio4//UY8M4poIu9mSG5pvNLagn9uoRPUSuj8jDEysB1Nmh12Zu
gFnt2XcxQB9/0krB5GnDTodrgfsz/UPbk44l4kFmQoLv5ACFndH69RKftogisauj
VVUrqCL3l9TcNsx8GLqZkeWhCwdZycZFjBhK01zihTYPEiU2HXfCNWhzLqxrM2Hh
r1ci+56fyNdn/ssO4o3hrGaWPDiayiHlEGEJxaG/ueKX2c3c0UJKkIGBPTEcdBjW
q42n/7EhY/ISaieQXPRK+gVm18I1OlGUH5FEYELO20bL88J8pr/bYuJyJnC8fiMP
YzKZuiVhey6dPr0zZgNDHyRbOlZqQllzKd1wbzbE4xqdUZfBWYwtRpdOJKDw4eoi
M69TwPQFfudeiudnMcR1gN37OkxS7UTEdsYIB5urgLb6qQD+tYFsxpcVPkedJw62
3TobhZjucaEZWzePd4u9faT9mQBXBAgY6VcCAwEAAaNQME4wHQYDVR0OBBYEFDTN
QRqhzaLc6XX2gFg26K//e0+8MB8GA1UdIwQYMBaAFDTNQRqhzaLc6XX2gFg26K//
e0+8MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggIBACcJ99Z45ghglvL3
/yMnx6IkOSneEm2/ADQoOabBQSC2grRAMBescKUiqpgbpBFalIPbPJUVrlH9tXYB
izNhqWETBY2tNy7AEHcJcCsAFuC2gOhaFH7FLgPA8V5IJmZ+McjB8REyowcN+CP4
GDY8s5/yr9S3HpKLD80UV18UX/j5m4b6I1w61QceMOSt6ahTtlnyvNBonFW94L1c
RmkdbhxYWn2eeUas62Q/+9bjr24E0weDKqopa3bbO7MWJ3mKkS4rua42j8GG3Q3q
UWPGh4zm+2+Ncjmz0Ho73RyYDDcp9IjwlAEv+NW86rz/5Pdkhoy+SzQwFYAwNgaQ
FRKb6ltpslxmu3tUdZ7Ydrj6MBGQyH2gRVm9qByro7WGI4UsyzsjP009Iu6dbhdC
2ddTGMisXF3dOmdRWh8dlggmW6gV4iaVgZkzLtrc9S0SK66utKMVXa4EUTm6XogX
F5ImPnVzIMo2qF2pP31aGDzKqJF3GNjGj+xHRVau5whz0a4ESY6V14PLTEL4Vc/H
J9uLCySifvqN+jzs5iY2QvNXjg2zPaTJbnjxxpYQJVSQHX6SyRcszhChqQzxnbyo
+S19BRclqzufRq6pp6VcOiID0BB7qPcrUHM9h1ingMXcZZlGBgHew9cY7tb5TAox
o+aTNc4k/7E543FVbs40dpOD2Fcr
-----END CERTIFICATE-----

20
contrib/certificates/ssl/us.reseed.i2p2.no.crt

@ -1,20 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIDUDCCAjgCCQCkTcCJMdZV7zANBgkqhkiG9w0BAQUFADBqMQswCQYDVQQGEwJO
TzENMAsGA1UECAwET3NsbzENMAsGA1UEBwwET3NsbzENMAsGA1UECgwET3NsbzES
MBAGA1UECwwJTm9yZGNsb3VkMRowGAYDVQQDDBF1cy5yZXNlZWQuaTJwMi5ubzAe
Fw0xNDA2MjcyMjQxMjFaFw0yNDA2MjQyMjQxMjFaMGoxCzAJBgNVBAYTAk5PMQ0w
CwYDVQQIDARPc2xvMQ0wCwYDVQQHDARPc2xvMQ0wCwYDVQQKDARPc2xvMRIwEAYD
VQQLDAlOb3JkY2xvdWQxGjAYBgNVBAMMEXVzLnJlc2VlZC5pMnAyLm5vMIIBIjAN
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAomVoBEc53jzy3xGMfgRaKyX6MaGG
KAmwu0uMTX6bVzGjy56JMMq3luoxOrpvgrNZF52lu7i36Tejo0HM75AHoea1es55
DNLmrlDeqzlBU2WibOnizbB8G+tlMEbx8eAGAWk/Wv/vH8CAKmxjImslmbajzZC2
LEH7inp3J5T2sVV7zmXeL9OEPKNyohbu6Mrno2IAlEOr8cu+lWAaFWzpknnR1gBX
NkB/8+7vK5Fq4MT7B0qnXPxmaWDbUOepPPni8u+2L9+qt19vZH4/6KNuH7xd7JLz
FfIdol6jy2cBQyAK7cVKWDHNk7ceB4Dl0mjBDbBIRTtLK+rfdnVmfWn8aQIDAQAB
MA0GCSqGSIb3DQEBBQUAA4IBAQCQH4QJMp5xneh2ah7fiuVdtKbiv6QNunRz7nb/
mWYyqmBX7EHL8jOG5qmPELDgDt58HmnaYMo05nEJb9JhAoviEDXSYw0s6eN4n4nc
MKqgR/HLLSiXPwT+Wi1MI57OYim5AFTUCYTSaWFUT+dZKYb0QPE1XjGpQXi3ppsJ
3TJG71tOzJmZT6vRPmdTHJO70v6ZEhr5w4SiGx07gNmcgO8WRyb5ajOwSHiGKrj6
UsuRNhtCyZaAEmelR9mfKBR1J2Nb+9jTz6mJtpT82WY3bst6mFk+A+mMWBQy7Hjt
gpdSDBCcFx9if+AKINGLgFvFKV2q8UzbfXms19NsVt9Hu7W3
-----END CERTIFICATE-----

17
contrib/certificates/ssl/user.mx24.eu.crt

@ -1,17 +0,0 @@
-----BEGIN CERTIFICATE-----
MIICwDCCAkagAwIBAgIJAKXCoCBjd/C0MAoGCCqGSM49BAMEMIGdMQswCQYDVQQG
EwJERTEVMBMGA1UECAwMdXNlci5teDI0LmV1MRUwEwYDVQQHDAx1c2VyLm14MjQu
ZXUxFTATBgNVBAoMDHVzZXIubXgyNC5ldTEVMBMGA1UECwwMdXNlci5teDI0LmV1
MRUwEwYDVQQDDAx1c2VyLm14MjQuZXUxGzAZBgkqhkiG9w0BCQEWDHVzZXIubXgy
NC5ldTAeFw0xNTA5MDMxNjMyNDVaFw0yMTAyMjMxNjMyNDVaMIGdMQswCQYDVQQG
EwJERTEVMBMGA1UECAwMdXNlci5teDI0LmV1MRUwEwYDVQQHDAx1c2VyLm14MjQu
ZXUxFTATBgNVBAoMDHVzZXIubXgyNC5ldTEVMBMGA1UECwwMdXNlci5teDI0LmV1
MRUwEwYDVQQDDAx1c2VyLm14MjQuZXUxGzAZBgkqhkiG9w0BCQEWDHVzZXIubXgy
NC5ldTB2MBAGByqGSM49AgEGBSuBBAAiA2IABPlKs5fYTqVhIOMiR6U9U4TimxS3
P5NBDVzeeIAgbw5KBC8UImScZVt9g4V1wQe5kPs7TxA2BfanAPZ+ekQiRRvMVQxD
bSlRYupEWhq5BrJI6Lq/HDc7VJe9UUWffWKUoKNQME4wHQYDVR0OBBYEFBGJ0Yr+
PZXnrk5RafQEALUpAU6ZMB8GA1UdIwQYMBaAFBGJ0Yr+PZXnrk5RafQEALUpAU6Z
MAwGA1UdEwQFMAMBAf8wCgYIKoZIzj0EAwQDaAAwZQIxAPcovePHMCosrAQNzS5i
VDUiyPNLOxHyRBm79yKXGl13LxysB6OK+2M7t8j8E/udBwIwXVVjxN6aSgXYTJ7d
p+Hg/2CuBMwf41/ENRcYQA+oGS9bU6A+7U9KJ1xTWWoqsUEs
-----END CERTIFICATE-----

6
debian/changelog vendored

@ -1,3 +1,9 @@
i2pd (2.11.0-1) unstable; urgency=low
* updated to version 2.11.0/0.9.28
-- orignal <orignal@i2pmail.org> Sun, 18 Dec 2016 21:01:30 +0000
i2pd (2.10.2-1) unstable; urgency=low i2pd (2.10.2-1) unstable; urgency=low
* updated to version 2.10.2 * updated to version 2.10.2

16
debian/patches/01-tune-build-opts.patch vendored

@ -1,16 +1,18 @@
diff --git a/Makefile b/Makefile diff --git a/Makefile b/Makefile
index b6fc795..abc3ace 100644 index bdadfe0..2f71eec 100644
--- a/Makefile --- a/Makefile
+++ b/Makefile +++ b/Makefile
@@ -9,10 +9,10 @@ DEPS := obj/make.dep @@ -9,10 +9,10 @@ DEPS := obj/make.dep
include filelist.mk include filelist.mk
-USE_AESNI := yes -USE_AESNI := yes
+USE_AESNI := no +USE_AESNI := no
USE_STATIC := no -USE_AVX := yes
USE_MESHNET := no +USE_AVX := no
USE_UPNP := no USE_STATIC := no
USE_MESHNET := no
USE_UPNP := no
ifeq ($(WEBSOCKETS),1) ifeq ($(WEBSOCKETS),1)
NEEDED_CXXFLAGS += -DWITH_EVENTS

2
qt/i2pd_qt/android/AndroidManifest.xml

@ -1,5 +1,5 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<manifest package="org.purplei2p.i2pd" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="2.8.0" android:versionCode="2" android:installLocation="auto"> <manifest package="org.purplei2p.i2pd" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="2.11.0" android:versionCode="2" android:installLocation="auto">
<uses-sdk android:minSdkVersion="11" android:targetSdkVersion="23"/> <uses-sdk android:minSdkVersion="11" android:targetSdkVersion="23"/>
<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/> <supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
<!-- <application android:hardwareAccelerated="true" --> <!-- <application android:hardwareAccelerated="true" -->

17
util.cpp

@ -275,14 +275,15 @@ namespace net
if (cur_ifname == ifname && cur->ifa_addr && cur->ifa_addr->sa_family == af) if (cur_ifname == ifname && cur->ifa_addr && cur->ifa_addr->sa_family == af)
{ {
// match // match
char * addr = new char[INET6_ADDRSTRLEN]; char * addr = new char[INET6_ADDRSTRLEN];
bzero(addr, INET6_ADDRSTRLEN); bzero(addr, INET6_ADDRSTRLEN);
if(af == AF_INET) if(af == AF_INET)
inet_ntop(af, &((sockaddr_in *)cur->ifa_addr)->sin_addr, addr, INET6_ADDRSTRLEN); inet_ntop(af, &((sockaddr_in *)cur->ifa_addr)->sin_addr, addr, INET6_ADDRSTRLEN);
else else
inet_ntop(af, &((sockaddr_in6 *)cur->ifa_addr)->sin6_addr, addr, INET6_ADDRSTRLEN); inet_ntop(af, &((sockaddr_in6 *)cur->ifa_addr)->sin6_addr, addr, INET6_ADDRSTRLEN);
freeifaddrs(addrs); freeifaddrs(addrs);
std::string cur_ifaddr(addr); std::string cur_ifaddr(addr);
delete[] addr;
return boost::asio::ip::address::from_string(cur_ifaddr); return boost::asio::ip::address::from_string(cur_ifaddr);
} }
cur = cur->ifa_next; cur = cur->ifa_next;

4
version.h

@ -7,8 +7,8 @@
#define MAKE_VERSION(a,b,c) STRINGIZE(a) "." STRINGIZE(b) "." STRINGIZE(c) #define MAKE_VERSION(a,b,c) STRINGIZE(a) "." STRINGIZE(b) "." STRINGIZE(c)
#define I2PD_VERSION_MAJOR 2 #define I2PD_VERSION_MAJOR 2
#define I2PD_VERSION_MINOR 10 #define I2PD_VERSION_MINOR 11
#define I2PD_VERSION_MICRO 2 #define I2PD_VERSION_MICRO 0
#define I2PD_VERSION_PATCH 0 #define I2PD_VERSION_PATCH 0
#define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO) #define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO)
#define VERSION I2PD_VERSION #define VERSION I2PD_VERSION

Loading…
Cancel
Save