mirror of
https://github.com/PurpleI2P/i2pd
synced 2024-11-10 16:10:33 +03:00
commit
d4f5871e74
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,6 +113,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;
|
||||||
|
@ -170,13 +170,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
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
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);
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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 ();
|
||||||
|
@ -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;
|
||||||
|
@ -494,8 +494,9 @@ namespace http {
|
|||||||
auto ntcpServer = i2p::transport::transports.GetNTCPServer ();
|
auto ntcpServer = i2p::transport::transports.GetNTCPServer ();
|
||||||
if (ntcpServer)
|
if (ntcpServer)
|
||||||
{
|
{
|
||||||
s << "<b>NTCP</b><br>\r\n";
|
auto sessions = ntcpServer->GetNTCPSessions ();
|
||||||
for (const auto& it: ntcpServer->GetNTCPSessions ())
|
s << "<b>NTCP</b> ( " << (int) sessions.size() << " )<br>\r\n";
|
||||||
|
for (const auto& it: sessions )
|
||||||
{
|
{
|
||||||
if (it.second && it.second->IsEstablished ())
|
if (it.second && it.second->IsEstablished ())
|
||||||
{
|
{
|
||||||
@ -512,8 +513,9 @@ namespace http {
|
|||||||
auto ssuServer = i2p::transport::transports.GetSSUServer ();
|
auto ssuServer = i2p::transport::transports.GetSSUServer ();
|
||||||
if (ssuServer)
|
if (ssuServer)
|
||||||
{
|
{
|
||||||
s << "<br>\r\n<b>SSU</b><br>\r\n";
|
auto sessions = ssuServer->GetSessions ();
|
||||||
for (const auto& it: ssuServer->GetSessions ())
|
s << "<br>\r\n<b>SSU</b> ( " << (int) sessions.size() << " )<br>\r\n";
|
||||||
|
for (const auto& it: sessions)
|
||||||
{
|
{
|
||||||
auto endpoint = it.second->GetRemoteEndpoint ();
|
auto endpoint = it.second->GetRemoteEndpoint ();
|
||||||
if (it.second->IsOutgoing ()) s << " ⇒ ";
|
if (it.second->IsOutgoing ()) s << " ⇒ ";
|
||||||
@ -604,6 +606,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> ⇐ ";
|
||||||
|
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 ())
|
||||||
{
|
{
|
||||||
@ -704,20 +715,22 @@ namespace http {
|
|||||||
}
|
}
|
||||||
/* method #2: 'Authorization' header sent */
|
/* method #2: 'Authorization' header sent */
|
||||||
if (req.headers.count("Authorization") > 0) {
|
if (req.headers.count("Authorization") > 0) {
|
||||||
|
bool result = false;
|
||||||
std::string provided = req.headers.find("Authorization")->second;
|
std::string provided = req.headers.find("Authorization")->second;
|
||||||
std::string expected = user + ":" + pass;
|
std::string expected = user + ":" + pass;
|
||||||
char b64_creds[64];
|
size_t b64_sz = i2p::data::Base64EncodingBufferSize(expected.length()) + 1;
|
||||||
|
char * b64_creds = new char[b64_sz];
|
||||||
std::size_t len = 0;
|
std::size_t len = 0;
|
||||||
len = i2p::data::ByteStreamToBase64((unsigned char *)expected.c_str(), expected.length(), b64_creds, sizeof(b64_creds));
|
len = i2p::data::ByteStreamToBase64((unsigned char *)expected.c_str(), expected.length(), b64_creds, b64_sz);
|
||||||
/* if we decoded properly then check credentials */
|
/* if we decoded properly then check credentials */
|
||||||
if(len) {
|
if(len) {
|
||||||
b64_creds[len] = '\0';
|
b64_creds[len] = '\0';
|
||||||
expected = "Basic ";
|
expected = "Basic ";
|
||||||
expected += b64_creds;
|
expected += b64_creds;
|
||||||
return expected == provided;
|
result = expected == provided;
|
||||||
}
|
}
|
||||||
/** we decoded wrong so it's not a correct login credential */
|
delete [] b64_creds;
|
||||||
return false;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogPrint(eLogWarning, "HTTPServer: auth failure from ", m_Socket->remote_endpoint().address ());
|
LogPrint(eLogWarning, "HTTPServer: auth failure from ", m_Socket->remote_endpoint().address ());
|
||||||
@ -775,6 +788,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 (); )
|
||||||
{
|
{
|
||||||
|
@ -92,7 +92,8 @@ namespace client
|
|||||||
m_Stream->Close ();
|
m_Stream->Close ();
|
||||||
m_Stream.reset ();
|
m_Stream.reset ();
|
||||||
}
|
}
|
||||||
m_Socket->shutdown(boost::asio::ip::tcp::socket::shutdown_send); // avoid RST
|
boost::system::error_code ec;
|
||||||
|
m_Socket->shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec); // avoid RST
|
||||||
m_Socket->close ();
|
m_Socket->close ();
|
||||||
|
|
||||||
Done(shared_from_this ());
|
Done(shared_from_this ());
|
||||||
|
2
Log.cpp
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;
|
||||||
|
@ -116,16 +116,10 @@ namespace transport
|
|||||||
|
|
||||||
void NTCPSession::ServerLogin ()
|
void NTCPSession::ServerLogin ()
|
||||||
{
|
{
|
||||||
boost::system::error_code ec;
|
// receive Phase1
|
||||||
auto ep = m_Socket.remote_endpoint(ec);
|
boost::asio::async_read (m_Socket, boost::asio::buffer(&m_Establisher->phase1, sizeof (NTCPPhase1)), boost::asio::transfer_all (),
|
||||||
if (!ec)
|
std::bind(&NTCPSession::HandlePhase1Received, shared_from_this (),
|
||||||
{
|
std::placeholders::_1, std::placeholders::_2));
|
||||||
m_ConnectedFrom = ep.address ();
|
|
||||||
// receive Phase1
|
|
||||||
boost::asio::async_read (m_Socket, boost::asio::buffer(&m_Establisher->phase1, sizeof (NTCPPhase1)), boost::asio::transfer_all (),
|
|
||||||
std::bind(&NTCPSession::HandlePhase1Received, shared_from_this (),
|
|
||||||
std::placeholders::_1, std::placeholders::_2));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NTCPSession::HandlePhase1Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred)
|
void NTCPSession::HandlePhase1Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred)
|
||||||
@ -502,8 +496,6 @@ namespace transport
|
|||||||
if (ecode) {
|
if (ecode) {
|
||||||
if (ecode != boost::asio::error::operation_aborted)
|
if (ecode != boost::asio::error::operation_aborted)
|
||||||
LogPrint (eLogDebug, "NTCP: Read error: ", ecode.message ());
|
LogPrint (eLogDebug, "NTCP: Read error: ", ecode.message ());
|
||||||
if (!m_NumReceivedBytes)
|
|
||||||
m_Server.Ban (m_ConnectedFrom);
|
|
||||||
//if (ecode != boost::asio::error::operation_aborted)
|
//if (ecode != boost::asio::error::operation_aborted)
|
||||||
Terminate ();
|
Terminate ();
|
||||||
}
|
}
|
||||||
@ -890,18 +882,6 @@ namespace transport
|
|||||||
if (!ec)
|
if (!ec)
|
||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "NTCP: Connected from ", ep);
|
LogPrint (eLogDebug, "NTCP: Connected from ", ep);
|
||||||
auto it = m_BanList.find (ep.address ());
|
|
||||||
if (it != m_BanList.end ())
|
|
||||||
{
|
|
||||||
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
|
||||||
if (ts < it->second)
|
|
||||||
{
|
|
||||||
LogPrint (eLogWarning, "NTCP: ", ep.address (), " is banned for ", it->second - ts, " more seconds");
|
|
||||||
conn = nullptr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m_BanList.erase (it);
|
|
||||||
}
|
|
||||||
if (conn)
|
if (conn)
|
||||||
conn->ServerLogin ();
|
conn->ServerLogin ();
|
||||||
}
|
}
|
||||||
@ -927,18 +907,6 @@ namespace transport
|
|||||||
if (!ec)
|
if (!ec)
|
||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "NTCP: Connected from ", ep);
|
LogPrint (eLogDebug, "NTCP: Connected from ", ep);
|
||||||
auto it = m_BanList.find (ep.address ());
|
|
||||||
if (it != m_BanList.end ())
|
|
||||||
{
|
|
||||||
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
|
||||||
if (ts < it->second)
|
|
||||||
{
|
|
||||||
LogPrint (eLogWarning, "NTCP: ", ep.address (), " is banned for ", it->second - ts, " more seconds");
|
|
||||||
conn = nullptr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m_BanList.erase (it);
|
|
||||||
}
|
|
||||||
if (conn)
|
if (conn)
|
||||||
conn->ServerLogin ();
|
conn->ServerLogin ();
|
||||||
}
|
}
|
||||||
@ -996,13 +964,6 @@ namespace transport
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NTCPServer::Ban (const boost::asio::ip::address& addr)
|
|
||||||
{
|
|
||||||
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
|
||||||
m_BanList[addr] = ts + NTCP_BAN_EXPIRATION_TIMEOUT;
|
|
||||||
LogPrint (eLogWarning, "NTCP: ", addr, " has been banned for ", NTCP_BAN_EXPIRATION_TIMEOUT, " seconds");
|
|
||||||
}
|
|
||||||
|
|
||||||
void NTCPServer::ScheduleTermination ()
|
void NTCPServer::ScheduleTermination ()
|
||||||
{
|
{
|
||||||
m_TerminationTimer.expires_from_now (boost::posix_time::seconds(NTCP_TERMINATION_CHECK_TIMEOUT));
|
m_TerminationTimer.expires_from_now (boost::posix_time::seconds(NTCP_TERMINATION_CHECK_TIMEOUT));
|
||||||
|
@ -122,8 +122,6 @@ namespace transport
|
|||||||
|
|
||||||
bool m_IsSending;
|
bool m_IsSending;
|
||||||
std::vector<std::shared_ptr<I2NPMessage> > m_SendQueue;
|
std::vector<std::shared_ptr<I2NPMessage> > m_SendQueue;
|
||||||
|
|
||||||
boost::asio::ip::address m_ConnectedFrom; // for ban
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: move to NTCP.h/.cpp
|
// TODO: move to NTCP.h/.cpp
|
||||||
@ -145,8 +143,7 @@ namespace transport
|
|||||||
bool IsBoundV4() const { return m_NTCPAcceptor != nullptr; };
|
bool IsBoundV4() const { return m_NTCPAcceptor != nullptr; };
|
||||||
bool IsBoundV6() const { return m_NTCPV6Acceptor != nullptr; };
|
bool IsBoundV6() const { return m_NTCPV6Acceptor != nullptr; };
|
||||||
|
|
||||||
boost::asio::io_service& GetService () { return m_Service; };
|
boost::asio::io_service& GetService () { return m_Service; };
|
||||||
void Ban (const boost::asio::ip::address& addr);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -169,7 +166,6 @@ namespace transport
|
|||||||
boost::asio::deadline_timer m_TerminationTimer;
|
boost::asio::deadline_timer m_TerminationTimer;
|
||||||
boost::asio::ip::tcp::acceptor * m_NTCPAcceptor, * m_NTCPV6Acceptor;
|
boost::asio::ip::tcp::acceptor * m_NTCPAcceptor, * m_NTCPV6Acceptor;
|
||||||
std::map<i2p::data::IdentHash, std::shared_ptr<NTCPSession> > m_NTCPSessions; // access from m_Thread only
|
std::map<i2p::data::IdentHash, std::shared_ptr<NTCPSession> > m_NTCPSessions; // access from m_Thread only
|
||||||
std::map<boost::asio::ip::address, uint32_t> m_BanList; // IP -> ban expiration time in seconds
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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; };
|
||||||
|
107
SAM.cpp
107
SAM.cpp
@ -54,7 +54,11 @@ namespace client
|
|||||||
case eSAMSocketTypeAcceptor:
|
case eSAMSocketTypeAcceptor:
|
||||||
{
|
{
|
||||||
if (m_Session)
|
if (m_Session)
|
||||||
|
{
|
||||||
m_Session->DelSocket (shared_from_this ());
|
m_Session->DelSocket (shared_from_this ());
|
||||||
|
if (m_Session->localDestination)
|
||||||
|
m_Session->localDestination->StopAcceptingStreams ();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -285,11 +289,6 @@ namespace client
|
|||||||
dest->SetReceiver (std::bind (&SAMSocket::HandleI2PDatagramReceive, shared_from_this (),
|
dest->SetReceiver (std::bind (&SAMSocket::HandleI2PDatagramReceive, shared_from_this (),
|
||||||
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5));
|
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5));
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// start accepting streams because we're not a datagram session
|
|
||||||
m_Session->localDestination->AcceptStreams (std::bind (&SAMSession::AcceptI2P, m_Session, std::placeholders::_1));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_Session->localDestination->IsReady ())
|
if (m_Session->localDestination->IsReady ())
|
||||||
SendSessionCreateReplyOk ();
|
SendSessionCreateReplyOk ();
|
||||||
@ -401,26 +400,17 @@ 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_SocketType = eSAMSocketTypeAcceptor;
|
||||||
m_Session->AddSocket (shared_from_this ());
|
m_Session->AddSocket (shared_from_this ());
|
||||||
|
if (!m_Session->localDestination->IsAcceptingStreams ())
|
||||||
|
m_Session->localDestination->AcceptOnce (std::bind (&SAMSocket::HandleI2PAccept, shared_from_this (), std::placeholders::_1));
|
||||||
SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false);
|
SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false);
|
||||||
}
|
}
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SAMSocket::Accept(std::shared_ptr<i2p::stream::Stream> stream)
|
|
||||||
{
|
|
||||||
if(stream) {
|
|
||||||
m_SocketType = eSAMSocketTypeStream;
|
|
||||||
HandleI2PAccept(stream);
|
|
||||||
} else {
|
|
||||||
SendMessageReply (SAM_STREAM_STATUS_I2P_ERROR, strlen(SAM_STREAM_STATUS_I2P_ERROR), true);
|
|
||||||
auto s = shared_from_this ();
|
|
||||||
m_Owner.GetService ().post ([s] { s->Terminate (); });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
size_t SAMSocket::ProcessDatagramSend (char * buf, size_t len, const char * data)
|
size_t SAMSocket::ProcessDatagramSend (char * buf, size_t len, const char * data)
|
||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "SAM: datagram send: ", buf, " ", len);
|
LogPrint (eLogDebug, "SAM: datagram send: ", buf, " ", len);
|
||||||
@ -663,8 +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);
|
||||||
|
if (session)
|
||||||
|
{
|
||||||
|
// 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
|
||||||
@ -706,76 +708,26 @@ namespace client
|
|||||||
}
|
}
|
||||||
|
|
||||||
SAMSession::SAMSession (std::shared_ptr<ClientDestination> dest):
|
SAMSession::SAMSession (std::shared_ptr<ClientDestination> dest):
|
||||||
localDestination (dest),
|
localDestination (dest)
|
||||||
m_BacklogPumper(dest->GetService())
|
|
||||||
{
|
{
|
||||||
PumpBacklog();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SAMSession::AcceptI2P(std::shared_ptr<i2p::stream::Stream> stream)
|
SAMSession::~SAMSession ()
|
||||||
{
|
{
|
||||||
if(!stream) return; // fail
|
CloseStreams();
|
||||||
std::unique_lock<std::mutex> lock(m_SocketsMutex);
|
i2p::client::context.DeleteLocalDestination (localDestination);
|
||||||
if(m_Backlog.size() > SAM_MAX_ACCEPT_BACKLOG) {
|
|
||||||
stream->Close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_Backlog.push_back(stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SAMSession::PumpBacklog()
|
|
||||||
{
|
|
||||||
// pump backlog every 100ms
|
|
||||||
boost::posix_time::milliseconds dlt(100);
|
|
||||||
m_BacklogPumper.expires_from_now(dlt);
|
|
||||||
m_BacklogPumper.async_wait(std::bind(&SAMSession::HandlePumpBacklog, this, std::placeholders::_1));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<SAMSocket> SAMSession::FindAcceptor()
|
|
||||||
{
|
|
||||||
for (auto & sock : m_Sockets) {
|
|
||||||
auto t = sock->GetSocketType();
|
|
||||||
if(t == eSAMSocketTypeAcceptor) {
|
|
||||||
return sock;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SAMSession::HandlePumpBacklog(const boost::system::error_code & ec)
|
|
||||||
{
|
|
||||||
if(ec) return;
|
|
||||||
{
|
|
||||||
std::unique_lock<std::mutex> lock(m_SocketsMutex);
|
|
||||||
auto itr = m_Backlog.begin();
|
|
||||||
while(itr != m_Backlog.end()) {
|
|
||||||
auto sock = FindAcceptor();
|
|
||||||
if (sock) {
|
|
||||||
sock->Accept(*itr);
|
|
||||||
itr = m_Backlog.erase(itr);
|
|
||||||
} else {
|
|
||||||
++itr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PumpBacklog();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SAMSession::CloseStreams ()
|
void SAMSession::CloseStreams ()
|
||||||
{
|
{
|
||||||
m_BacklogPumper.cancel();
|
{
|
||||||
localDestination->GetService().post([&] () {
|
|
||||||
std::lock_guard<std::mutex> lock(m_SocketsMutex);
|
std::lock_guard<std::mutex> lock(m_SocketsMutex);
|
||||||
for (auto& sock : m_Sockets) {
|
for (auto& sock : m_Sockets) {
|
||||||
sock->CloseStream();
|
sock->CloseStream();
|
||||||
}
|
}
|
||||||
for(auto & stream : m_Backlog) {
|
}
|
||||||
stream->Close();
|
// XXX: should this be done inside locked parts?
|
||||||
}
|
m_Sockets.clear();
|
||||||
m_Sockets.clear();
|
|
||||||
m_Backlog.clear();
|
|
||||||
i2p::client::context.DeleteLocalDestination (localDestination);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SAMBridge::SAMBridge (const std::string& address, int port):
|
SAMBridge::SAMBridge (const std::string& address, int port):
|
||||||
@ -886,9 +838,8 @@ namespace client
|
|||||||
auto session = std::make_shared<SAMSession>(localDestination);
|
auto session = std::make_shared<SAMSession>(localDestination);
|
||||||
std::unique_lock<std::mutex> l(m_SessionsMutex);
|
std::unique_lock<std::mutex> l(m_SessionsMutex);
|
||||||
auto ret = m_Sessions.insert (std::make_pair(id, session));
|
auto ret = m_Sessions.insert (std::make_pair(id, session));
|
||||||
if (!ret.second) {
|
if (!ret.second)
|
||||||
LogPrint (eLogWarning, "SAM: Session ", id, " already exists");
|
LogPrint (eLogWarning, "SAM: Session ", id, " already exists");
|
||||||
}
|
|
||||||
return ret.first->second;
|
return ret.first->second;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
19
SAM.h
19
SAM.h
@ -20,8 +20,7 @@ namespace client
|
|||||||
{
|
{
|
||||||
const size_t SAM_SOCKET_BUFFER_SIZE = 8192;
|
const size_t SAM_SOCKET_BUFFER_SIZE = 8192;
|
||||||
const int SAM_SOCKET_CONNECTION_MAX_IDLE = 3600; // in seconds
|
const int SAM_SOCKET_CONNECTION_MAX_IDLE = 3600; // in seconds
|
||||||
const int SAM_SESSION_READINESS_CHECK_INTERVAL = 20; // in seconds
|
const int SAM_SESSION_READINESS_CHECK_INTERVAL = 20; // in seconds
|
||||||
const int SAM_MAX_ACCEPT_BACKLOG = 50;
|
|
||||||
const char SAM_HANDSHAKE[] = "HELLO VERSION";
|
const char SAM_HANDSHAKE[] = "HELLO VERSION";
|
||||||
const char SAM_HANDSHAKE_REPLY[] = "HELLO REPLY RESULT=OK VERSION=%s\n";
|
const char SAM_HANDSHAKE_REPLY[] = "HELLO REPLY RESULT=OK VERSION=%s\n";
|
||||||
const char SAM_HANDSHAKE_I2P_ERROR[] = "HELLO REPLY RESULT=I2P_ERROR\n";
|
const char SAM_HANDSHAKE_I2P_ERROR[] = "HELLO REPLY RESULT=I2P_ERROR\n";
|
||||||
@ -85,8 +84,6 @@ namespace client
|
|||||||
void SetSocketType (SAMSocketType socketType) { m_SocketType = socketType; };
|
void SetSocketType (SAMSocketType socketType) { m_SocketType = socketType; };
|
||||||
SAMSocketType GetSocketType () const { return m_SocketType; };
|
SAMSocketType GetSocketType () const { return m_SocketType; };
|
||||||
|
|
||||||
void Accept(std::shared_ptr<i2p::stream::Stream> stream);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void Terminate ();
|
void Terminate ();
|
||||||
@ -137,8 +134,6 @@ namespace client
|
|||||||
struct SAMSession
|
struct SAMSession
|
||||||
{
|
{
|
||||||
std::shared_ptr<ClientDestination> localDestination;
|
std::shared_ptr<ClientDestination> localDestination;
|
||||||
boost::asio::deadline_timer m_BacklogPumper;
|
|
||||||
std::list<std::shared_ptr<i2p::stream::Stream> > m_Backlog;
|
|
||||||
std::list<std::shared_ptr<SAMSocket> > m_Sockets;
|
std::list<std::shared_ptr<SAMSocket> > m_Sockets;
|
||||||
std::mutex m_SocketsMutex;
|
std::mutex m_SocketsMutex;
|
||||||
|
|
||||||
@ -163,15 +158,9 @@ namespace client
|
|||||||
}
|
}
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
SAMSession (std::shared_ptr<ClientDestination> dest);
|
SAMSession (std::shared_ptr<ClientDestination> dest);
|
||||||
|
~SAMSession ();
|
||||||
void AcceptI2P(std::shared_ptr<i2p::stream::Stream> stream);
|
|
||||||
|
|
||||||
std::shared_ptr<SAMSocket> FindAcceptor();
|
|
||||||
|
|
||||||
void PumpBacklog();
|
|
||||||
void HandlePumpBacklog(const boost::system::error_code & ec);
|
|
||||||
|
|
||||||
void CloseStreams ();
|
void CloseStreams ();
|
||||||
};
|
};
|
||||||
|
14
SSU.cpp
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
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:
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
@ -458,14 +458,12 @@ 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);
|
|
||||||
}
|
}
|
||||||
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;
|
||||||
@ -870,6 +868,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 ()
|
||||||
@ -886,6 +886,8 @@ namespace transport
|
|||||||
transports.PeerConnected (shared_from_this ());
|
transports.PeerConnected (shared_from_this ());
|
||||||
if (m_IsPeerTest)
|
if (m_IsPeerTest)
|
||||||
SendPeerTest ();
|
SendPeerTest ();
|
||||||
|
if (m_SentRelayTag)
|
||||||
|
m_Server.AddRelay (m_SentRelayTag, shared_from_this ());
|
||||||
m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch ();
|
m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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)
|
||||||
|
@ -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; };
|
||||||
|
@ -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
|
||||||
EmitEvent({{"type" , "transport.sendmsg"}, {"ident", ident.ToBase64()}, {"number", std::to_string(msgs.size())}});
|
EmitEvent({{"type" , "transport.sendmsg"}, {"ident", ident.ToBase64()}, {"number", std::to_string(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)
|
||||||
@ -369,7 +384,7 @@ namespace transport
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LogPrint (eLogError, "Transports: No NTCP or SSU addresses available");
|
LogPrint (eLogInfo, "Transports: No NTCP or SSU addresses available");
|
||||||
peer.Done ();
|
peer.Done ();
|
||||||
std::unique_lock<std::mutex> l(m_PeersMutex);
|
std::unique_lock<std::mutex> l(m_PeersMutex);
|
||||||
m_Peers.erase (ident);
|
m_Peers.erase (ident);
|
||||||
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
31
Tunnel.cpp
31
Tunnel.cpp
@ -19,36 +19,11 @@
|
|||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
namespace tunnel
|
namespace tunnel
|
||||||
{
|
{
|
||||||
|
|
||||||
void TunnelLatency::AddSample(Sample s)
|
|
||||||
{
|
|
||||||
std::unique_lock<std::mutex> l(m_access);
|
|
||||||
m_samples.push_back(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TunnelLatency::HasSamples() const
|
|
||||||
{
|
|
||||||
std::unique_lock<std::mutex> l(m_access);
|
|
||||||
return m_samples.size() > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
TunnelLatency::Latency TunnelLatency::GetMeanLatency() const
|
|
||||||
{
|
|
||||||
std::unique_lock<std::mutex> lock(m_access);
|
|
||||||
if (m_samples.size() > 0) {
|
|
||||||
Latency l = 0;
|
|
||||||
for(auto s : m_samples)
|
|
||||||
l += s;
|
|
||||||
return l / m_samples.size();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Tunnel::Tunnel (std::shared_ptr<const TunnelConfig> config):
|
Tunnel::Tunnel (std::shared_ptr<const TunnelConfig> config):
|
||||||
TunnelBase (config->GetTunnelID (), config->GetNextTunnelID (), config->GetNextIdentHash ()),
|
TunnelBase (config->GetTunnelID (), config->GetNextTunnelID (), config->GetNextIdentHash ()),
|
||||||
m_Config (config), m_Pool (nullptr), m_State (eTunnelStatePending), m_IsRecreated (false)
|
m_Config (config), m_Pool (nullptr), m_State (eTunnelStatePending), m_IsRecreated (false),
|
||||||
|
m_Latency (0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
31
Tunnel.h
31
Tunnel.h
@ -78,21 +78,6 @@ namespace tunnel
|
|||||||
eTunnelStateFailed,
|
eTunnelStateFailed,
|
||||||
eTunnelStateExpiring
|
eTunnelStateExpiring
|
||||||
};
|
};
|
||||||
|
|
||||||
/** @brief for storing latency history */
|
|
||||||
struct TunnelLatency
|
|
||||||
{
|
|
||||||
typedef uint64_t Sample;
|
|
||||||
typedef uint64_t Latency;
|
|
||||||
|
|
||||||
|
|
||||||
void AddSample(Sample s);
|
|
||||||
bool HasSamples() const;
|
|
||||||
Latency GetMeanLatency() const;
|
|
||||||
|
|
||||||
std::vector<Sample> m_samples;
|
|
||||||
mutable std::mutex m_access;
|
|
||||||
};
|
|
||||||
|
|
||||||
class OutboundTunnel;
|
class OutboundTunnel;
|
||||||
class InboundTunnel;
|
class InboundTunnel;
|
||||||
@ -133,14 +118,14 @@ namespace tunnel
|
|||||||
void SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg);
|
void SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg);
|
||||||
void EncryptTunnelMsg (std::shared_ptr<const I2NPMessage> in, std::shared_ptr<I2NPMessage> out);
|
void EncryptTunnelMsg (std::shared_ptr<const I2NPMessage> in, std::shared_ptr<I2NPMessage> out);
|
||||||
|
|
||||||
/** @brief add latency sample */
|
/** @brief add latency sample */
|
||||||
void AddLatencySample(const uint64_t ms) { m_Latency.AddSample(ms); }
|
void AddLatencySample(const uint64_t ms) { m_Latency = (m_Latency + ms) >> 1; }
|
||||||
/** @brief get this tunnel's estimated latency */
|
/** @brief get this tunnel's estimated latency */
|
||||||
uint64_t GetMeanLatency() const { return m_Latency.GetMeanLatency(); }
|
uint64_t GetMeanLatency() const { return m_Latency; }
|
||||||
/** @breif return true if this tunnel's latency fits in range [lowerbound, upperbound] */
|
/** @breif return true if this tunnel's latency fits in range [lowerbound, upperbound] */
|
||||||
bool LatencyFitsRange(uint64_t lowerbound, uint64_t upperbound) const;
|
bool LatencyFitsRange(uint64_t lowerbound, uint64_t upperbound) const;
|
||||||
|
|
||||||
bool LatencyIsKnown() const { return m_Latency.HasSamples(); }
|
bool LatencyIsKnown() const { return m_Latency > 0; }
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void PrintHops (std::stringstream& s) const;
|
void PrintHops (std::stringstream& s) const;
|
||||||
@ -152,7 +137,7 @@ namespace tunnel
|
|||||||
std::shared_ptr<TunnelPool> m_Pool; // pool, tunnel belongs to, or null
|
std::shared_ptr<TunnelPool> m_Pool; // pool, tunnel belongs to, or null
|
||||||
TunnelState m_State;
|
TunnelState m_State;
|
||||||
bool m_IsRecreated;
|
bool m_IsRecreated;
|
||||||
TunnelLatency m_Latency;
|
uint64_t m_Latency; // in milliseconds
|
||||||
};
|
};
|
||||||
|
|
||||||
class OutboundTunnel: public Tunnel
|
class OutboundTunnel: public Tunnel
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -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);
|
||||||
|
@ -11,4 +11,4 @@
|
|||||||
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
|
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
|
||||||
|
|
||||||
# Project target.
|
# Project target.
|
||||||
target=android-24
|
target=android-25
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 36 KiB |
Binary file not shown.
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 36 KiB |
@ -1,32 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
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
|
|
||||||
06dwfEP/gTCAnSplLyrFWxnyHManBxq/bQ==
|
|
||||||
-----END CERTIFICATE-----
|
|
33
contrib/certificates/reseed/hottuna_at_mail.i2p.crt
Normal file
33
contrib/certificates/reseed/hottuna_at_mail.i2p.crt
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
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
|
||||||
|
-----END CERTIFICATE-----
|
@ -1,34 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
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
|
|
||||||
-----END CERTIFICATE-----
|
|
@ -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-----
|
|
@ -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-----
|
|
@ -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-----
|
|
@ -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-----
|
|
@ -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-----
|
|
@ -1,33 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
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
|
|
||||||
-----END CERTIFICATE-----
|
|
@ -1,33 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
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
|
|
||||||
o+aTNc4k/7E543FVbs40dpOD2Fcr
|
|
||||||
-----END CERTIFICATE-----
|
|
@ -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-----
|
|
@ -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-----
|
|
3
qt/i2pd_qt/README.md
Normal file
3
qt/i2pd_qt/README.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Build Requirements
|
||||||
|
|
||||||
|
* Qt 5 is necessary (because Qt4 lacks QtWidgets/ folder)
|
17
util.cpp
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;
|
||||||
|
Loading…
Reference in New Issue
Block a user