mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-04-28 19:57:48 +02:00
Logging: finish capitalization fixups
This commit is contained in:
parent
cc1e8e3dcf
commit
789a31e16d
23 changed files with 700 additions and 700 deletions
|
@ -389,7 +389,7 @@ namespace util
|
|||
LogPrint(eLogInfo, "Daemon: Transports started");
|
||||
else
|
||||
{
|
||||
LogPrint(eLogError, "Daemon: Failed to start transports");
|
||||
LogPrint(eLogError, "Daemon: Failed to start Transports");
|
||||
/** shut down netdb right away */
|
||||
i2p::transport::transports.Stop();
|
||||
i2p::data::netdb.Stop();
|
||||
|
@ -400,7 +400,7 @@ namespace util
|
|||
if (http) {
|
||||
std::string httpAddr; i2p::config::GetOption("http.address", httpAddr);
|
||||
uint16_t httpPort; i2p::config::GetOption("http.port", httpPort);
|
||||
LogPrint(eLogInfo, "Daemon: Starting webconsole at ", httpAddr, ":", httpPort);
|
||||
LogPrint(eLogInfo, "Daemon: Starting Webconsole at ", httpAddr, ":", httpPort);
|
||||
try
|
||||
{
|
||||
d.httpServer = std::unique_ptr<i2p::http::HTTPServer>(new i2p::http::HTTPServer(httpAddr, httpPort));
|
||||
|
@ -408,16 +408,16 @@ namespace util
|
|||
}
|
||||
catch (std::exception& ex)
|
||||
{
|
||||
LogPrint (eLogError, "Daemon: Failed to start webconsole: ", ex.what ());
|
||||
LogPrint (eLogError, "Daemon: Failed to start Webconsole: ", ex.what ());
|
||||
ThrowFatal ("Unable to start webconsole at ", httpAddr, ":", httpPort, ": ", ex.what ());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LogPrint(eLogInfo, "Daemon: Starting tunnels");
|
||||
LogPrint(eLogInfo, "Daemon: Starting Tunnels");
|
||||
i2p::tunnel::tunnels.Start();
|
||||
|
||||
LogPrint(eLogInfo, "Daemon: Starting client");
|
||||
LogPrint(eLogInfo, "Daemon: Starting Client");
|
||||
i2p::client::context.Start ();
|
||||
|
||||
// I2P Control Protocol
|
||||
|
@ -443,9 +443,9 @@ namespace util
|
|||
bool Daemon_Singleton::stop()
|
||||
{
|
||||
LogPrint(eLogInfo, "Daemon: Shutting down");
|
||||
LogPrint(eLogInfo, "Daemon: Stopping client");
|
||||
LogPrint(eLogInfo, "Daemon: Stopping Client");
|
||||
i2p::client::context.Stop();
|
||||
LogPrint(eLogInfo, "Daemon: Stopping tunnels");
|
||||
LogPrint(eLogInfo, "Daemon: Stopping Tunnels");
|
||||
i2p::tunnel::tunnels.Stop();
|
||||
|
||||
if (d.UPnP)
|
||||
|
@ -460,7 +460,7 @@ namespace util
|
|||
d.m_NTPSync = nullptr;
|
||||
}
|
||||
|
||||
LogPrint(eLogInfo, "Daemon: Stopping transports");
|
||||
LogPrint(eLogInfo, "Daemon: Stopping Transports");
|
||||
i2p::transport::transports.Stop();
|
||||
LogPrint(eLogInfo, "Daemon: Stopping NetDB");
|
||||
i2p::data::netdb.Stop();
|
||||
|
|
|
@ -461,7 +461,7 @@ namespace http {
|
|||
if (level == "none" || level == "error" || level == "warn" || level == "info" || level == "debug")
|
||||
i2p::log::Logger().SetLogLevel(level);
|
||||
else {
|
||||
LogPrint(eLogError, "HTTPServer: unknown loglevel set attempted");
|
||||
LogPrint(eLogError, "HTTPServer: Unknown loglevel set attempted");
|
||||
return;
|
||||
}
|
||||
i2p::log::Logger().Reopen ();
|
||||
|
@ -1765,7 +1765,7 @@ namespace http {
|
|||
if (expected == provided) return true;
|
||||
}
|
||||
|
||||
LogPrint(eLogWarning, "HTTPServer: auth failure from ", m_Socket->remote_endpoint().address ());
|
||||
LogPrint(eLogWarning, "HTTPServer: Auth failure from ", m_Socket->remote_endpoint().address ());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1775,7 +1775,7 @@ namespace http {
|
|||
std::string content;
|
||||
HTTPRes res;
|
||||
|
||||
LogPrint(eLogDebug, "HTTPServer: request: ", req.uri);
|
||||
LogPrint(eLogDebug, "HTTPServer: Request: ", req.uri);
|
||||
|
||||
if (needAuth && !CheckAuth(req)) {
|
||||
res.code = 401;
|
||||
|
@ -2146,7 +2146,7 @@ namespace http {
|
|||
pass[i] = alnum[random[i] % (sizeof(alnum) - 1)];
|
||||
}
|
||||
i2p::config::SetOption("http.pass", pass);
|
||||
LogPrint(eLogInfo, "HTTPServer: password set to ", pass);
|
||||
LogPrint(eLogInfo, "HTTPServer: Password set to ", pass);
|
||||
}
|
||||
|
||||
m_IsRunning = true;
|
||||
|
@ -2199,7 +2199,7 @@ namespace http {
|
|||
if (ecode)
|
||||
{
|
||||
if(newSocket) newSocket->close();
|
||||
LogPrint(eLogError, "HTTP Server: error handling accept ", ecode.message());
|
||||
LogPrint(eLogError, "HTTP Server: Error handling accept ", ecode.message());
|
||||
if(ecode != boost::asio::error::operation_aborted)
|
||||
Accept();
|
||||
return;
|
||||
|
|
|
@ -122,7 +122,7 @@ namespace data
|
|||
break;
|
||||
}
|
||||
default:
|
||||
LogPrint (eLogError, "Blinding: signature type ", (int)sigType, " is not ECDSA");
|
||||
LogPrint (eLogError, "Blinding: Signature type ", (int)sigType, " is not ECDSA");
|
||||
}
|
||||
if (group)
|
||||
{
|
||||
|
@ -156,7 +156,7 @@ namespace data
|
|||
size_t l = i2p::data::Base32ToByteStream (b33.c_str (), b33.length (), addr, 40);
|
||||
if (l < 32)
|
||||
{
|
||||
LogPrint (eLogError, "Blinding: malformed b33 ", b33);
|
||||
LogPrint (eLogError, "Blinding: Malformed b33 ", b33);
|
||||
return;
|
||||
}
|
||||
uint32_t checksum = crc32 (0, addr + 3, l - 3);
|
||||
|
@ -186,10 +186,10 @@ namespace data
|
|||
memcpy (m_PublicKey.data (), addr + offset, len);
|
||||
}
|
||||
else
|
||||
LogPrint (eLogError, "Blinding: public key in b33 address is too short for signature type ", (int)m_SigType);
|
||||
LogPrint (eLogError, "Blinding: Public key in b33 address is too short for signature type ", (int)m_SigType);
|
||||
}
|
||||
else
|
||||
LogPrint (eLogError, "Blinding: unknown signature type ", (int)m_SigType, " in b33");
|
||||
LogPrint (eLogError, "Blinding: Unknown signature type ", (int)m_SigType, " in b33");
|
||||
}
|
||||
|
||||
std::string BlindedPublicKey::ToB33 () const
|
||||
|
@ -256,7 +256,7 @@ namespace data
|
|||
publicKeyLength = i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH;
|
||||
break;
|
||||
default:
|
||||
LogPrint (eLogError, "Blinding: can't blind signature type ", (int)m_SigType);
|
||||
LogPrint (eLogError, "Blinding: Can't blind signature type ", (int)m_SigType);
|
||||
}
|
||||
return publicKeyLength;
|
||||
}
|
||||
|
@ -272,21 +272,21 @@ namespace data
|
|||
case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA384_P384:
|
||||
case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA512_P521:
|
||||
publicKeyLength = BlindECDSA (m_SigType, priv, seed, BlindEncodedPrivateKeyECDSA, blindedPriv, blindedPub);
|
||||
break;
|
||||
break;
|
||||
case i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519:
|
||||
i2p::crypto::GetEd25519 ()->BlindPrivateKey (priv, seed, blindedPriv, blindedPub);
|
||||
publicKeyLength = i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH;
|
||||
break;
|
||||
case i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519:
|
||||
case i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519:
|
||||
{
|
||||
uint8_t exp[64];
|
||||
i2p::crypto::Ed25519::ExpandPrivateKey (priv, exp);
|
||||
uint8_t exp[64];
|
||||
i2p::crypto::Ed25519::ExpandPrivateKey (priv, exp);
|
||||
i2p::crypto::GetEd25519 ()->BlindPrivateKey (exp, seed, blindedPriv, blindedPub);
|
||||
publicKeyLength = i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH;
|
||||
publicKeyLength = i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH;
|
||||
break;
|
||||
}
|
||||
}
|
||||
default:
|
||||
LogPrint (eLogError, "Blinding: can't blind signature type ", (int)m_SigType);
|
||||
LogPrint (eLogError, "Blinding: Can't blind signature type ", (int)m_SigType);
|
||||
}
|
||||
return publicKeyLength;
|
||||
}
|
||||
|
@ -324,7 +324,7 @@ namespace data
|
|||
SHA256_Final ((uint8_t *)hash, &ctx);
|
||||
}
|
||||
else
|
||||
LogPrint (eLogError, "Blinding: blinded key type ", (int)m_BlindedSigType, " is not supported");
|
||||
LogPrint (eLogError, "Blinding: Blinded key type ", (int)m_BlindedSigType, " is not supported");
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ namespace client
|
|||
it = params->find (I2CP_PARAM_TAGS_TO_SEND);
|
||||
if (it != params->end ())
|
||||
numTags = std::stoi(it->second);
|
||||
LogPrint (eLogInfo, "Destination: parameters for tunnel set to: ", inQty, " inbound (", inLen, " hops), ", outQty, " outbound (", outLen, " hops), ", numTags, " tags");
|
||||
LogPrint (eLogInfo, "Destination: Parameters for tunnel set to: ", inQty, " inbound (", inLen, " hops), ", outQty, " outbound (", outLen, " hops), ", numTags, " tags");
|
||||
it = params->find (I2CP_PARAM_RATCHET_INBOUND_TAGS);
|
||||
if (it != params->end ())
|
||||
SetNumRatchetInboundTags (std::stoi(it->second));
|
||||
|
@ -89,7 +89,7 @@ namespace client
|
|||
bool dontpublish = false;
|
||||
i2p::config::GetOption (it->second, dontpublish);
|
||||
m_IsPublic = !dontpublish;
|
||||
}
|
||||
}
|
||||
it = params->find (I2CP_PARAM_LEASESET_TYPE);
|
||||
if (it != params->end ())
|
||||
m_LeaseSetType = std::stoi(it->second);
|
||||
|
@ -112,7 +112,7 @@ namespace client
|
|||
m_LeaseSetPrivKey.reset (new i2p::data::Tag<32>());
|
||||
if (m_LeaseSetPrivKey->FromBase64 (it->second) != 32)
|
||||
{
|
||||
LogPrint(eLogError, "Destination: invalid value i2cp.leaseSetPrivKey ", it->second);
|
||||
LogPrint(eLogError, "Destination: Invalid value i2cp.leaseSetPrivKey ", it->second);
|
||||
m_LeaseSetPrivKey.reset (nullptr);
|
||||
}
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ namespace client
|
|||
}
|
||||
catch (std::exception & ex)
|
||||
{
|
||||
LogPrint(eLogError, "Destination: unable to parse parameters for destination: ", ex.what());
|
||||
LogPrint(eLogError, "Destination: Unable to parse parameters for destination: ", ex.what());
|
||||
}
|
||||
SetNumTags (numTags);
|
||||
m_Pool = i2p::tunnel::tunnels.CreateTunnelPool (inLen, outLen, inQty, outQty);
|
||||
|
@ -136,7 +136,7 @@ namespace client
|
|||
auto minlatency = std::stoi(itr->second);
|
||||
if ( minlatency > 0 && maxlatency > 0 ) {
|
||||
// set tunnel pool latency
|
||||
LogPrint(eLogInfo, "Destination: requiring tunnel latency [", minlatency, "ms, ", maxlatency, "ms]");
|
||||
LogPrint(eLogInfo, "Destination: Requiring tunnel latency [", minlatency, "ms, ", maxlatency, "ms]");
|
||||
m_Pool->RequireLatency(minlatency, maxlatency);
|
||||
}
|
||||
}
|
||||
|
@ -251,7 +251,7 @@ namespace client
|
|||
}
|
||||
else
|
||||
{
|
||||
LogPrint (eLogWarning, "Destination: remote LeaseSet expired");
|
||||
LogPrint (eLogWarning, "Destination: Remote LeaseSet expired");
|
||||
std::lock_guard<std::mutex> lock(m_RemoteLeaseSetsMutex);
|
||||
m_RemoteLeaseSets.erase (ident);
|
||||
return nullptr;
|
||||
|
@ -367,8 +367,8 @@ namespace client
|
|||
HandleDatabaseSearchReplyMessage (payload, len);
|
||||
break;
|
||||
case eI2NPShortTunnelBuildReply: // might come as garlic encrypted
|
||||
i2p::HandleI2NPMessage (CreateI2NPMessage (typeID, payload, len, msgID));
|
||||
break;
|
||||
i2p::HandleI2NPMessage (CreateI2NPMessage (typeID, payload, len, msgID));
|
||||
break;
|
||||
default:
|
||||
LogPrint (eLogWarning, "Destination: Unexpected I2NP message type ", typeID);
|
||||
return false;
|
||||
|
@ -395,7 +395,7 @@ namespace client
|
|||
LogPrint (eLogDebug, "Destination: Remote LeaseSet");
|
||||
std::lock_guard<std::mutex> lock(m_RemoteLeaseSetsMutex);
|
||||
auto it = m_RemoteLeaseSets.find (key);
|
||||
if (it != m_RemoteLeaseSets.end () &&
|
||||
if (it != m_RemoteLeaseSets.end () &&
|
||||
it->second->GetStoreType () == buf[DATABASE_STORE_TYPE_OFFSET]) // update only if same type
|
||||
{
|
||||
leaseSet = it->second;
|
||||
|
@ -487,7 +487,7 @@ namespace client
|
|||
i2p::data::IdentHash peerHash (buf + 33 + i*32);
|
||||
if (!request->excluded.count (peerHash) && !i2p::data::netdb.FindRouter (peerHash))
|
||||
{
|
||||
LogPrint (eLogInfo, "Destination: Found new floodfill, request it");
|
||||
LogPrint (eLogInfo, "Destination: Found new floodfill, request it");
|
||||
i2p::data::netdb.RequestDestination (peerHash, nullptr, false); // through exploratory
|
||||
}
|
||||
}
|
||||
|
@ -767,11 +767,11 @@ namespace client
|
|||
uint8_t replyKey[32], replyTag[32];
|
||||
RAND_bytes (replyKey, 32); // random session key
|
||||
RAND_bytes (replyTag, isECIES ? 8 : 32); // random session tag
|
||||
if (isECIES)
|
||||
if (isECIES)
|
||||
AddECIESx25519Key (replyKey, replyTag);
|
||||
else
|
||||
else
|
||||
AddSessionKey (replyKey, replyTag);
|
||||
auto msg = WrapMessageForRouter (nextFloodfill, CreateLeaseSetDatabaseLookupMsg (dest,
|
||||
auto msg = WrapMessageForRouter (nextFloodfill, CreateLeaseSetDatabaseLookupMsg (dest,
|
||||
request->excluded, request->replyTunnel, replyKey, replyTag, isECIES));
|
||||
request->outboundTunnel->SendTunnelDataMsg (
|
||||
{
|
||||
|
@ -866,8 +866,8 @@ namespace client
|
|||
|
||||
ClientDestination::ClientDestination (boost::asio::io_service& service, const i2p::data::PrivateKeys& keys,
|
||||
bool isPublic, const std::map<std::string, std::string> * params):
|
||||
LeaseSetDestination (service, isPublic, params),
|
||||
m_Keys (keys), m_StreamingAckDelay (DEFAULT_INITIAL_ACK_DELAY),
|
||||
LeaseSetDestination (service, isPublic, params),
|
||||
m_Keys (keys), m_StreamingAckDelay (DEFAULT_INITIAL_ACK_DELAY),
|
||||
m_IsStreamingAnswerPings (DEFAULT_ANSWER_PINGS),
|
||||
m_DatagramDestination (nullptr), m_RefCounter (0),
|
||||
m_ReadyChecker(service)
|
||||
|
@ -916,11 +916,11 @@ namespace client
|
|||
encryptionKey->GenerateKeys ();
|
||||
encryptionKey->CreateDecryptor ();
|
||||
if (it == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)
|
||||
{
|
||||
{
|
||||
m_ECIESx25519EncryptionKey.reset (encryptionKey);
|
||||
if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_LEASESET)
|
||||
SetLeaseSetType (i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2); // Rathets must use LeaseSet2
|
||||
}
|
||||
SetLeaseSetType (i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2); // Rathets must use LeaseSet2
|
||||
}
|
||||
else
|
||||
m_StandardEncryptionKey.reset (encryptionKey);
|
||||
}
|
||||
|
@ -939,7 +939,7 @@ namespace client
|
|||
it = params->find (I2CP_PARAM_STREAMING_ANSWER_PINGS);
|
||||
if (it != params->end ())
|
||||
i2p::config::GetOption (it->second, m_IsStreamingAnswerPings);
|
||||
|
||||
|
||||
if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_ENCRYPTED_LEASESET2)
|
||||
{
|
||||
// authentication for encrypted LeaseSet
|
||||
|
@ -966,7 +966,7 @@ namespace client
|
|||
}
|
||||
catch (std::exception & ex)
|
||||
{
|
||||
LogPrint(eLogError, "Destination: unable to parse parameters for destination: ", ex.what());
|
||||
LogPrint(eLogError, "Destination: Unable to parse parameters for destination: ", ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1050,7 +1050,7 @@ namespace client
|
|||
{
|
||||
if (!streamRequestComplete)
|
||||
{
|
||||
LogPrint (eLogError, "Destination: request callback is not specified in CreateStream");
|
||||
LogPrint (eLogError, "Destination: Request callback is not specified in CreateStream");
|
||||
return;
|
||||
}
|
||||
auto leaseSet = FindLeaseSet (dest);
|
||||
|
@ -1074,7 +1074,7 @@ namespace client
|
|||
{
|
||||
if (!streamRequestComplete)
|
||||
{
|
||||
LogPrint (eLogError, "Destination: request callback is not specified in CreateStream");
|
||||
LogPrint (eLogError, "Destination: Request callback is not specified in CreateStream");
|
||||
return;
|
||||
}
|
||||
auto s = GetSharedFromThis ();
|
||||
|
@ -1153,18 +1153,18 @@ namespace client
|
|||
auto ret = it->second;
|
||||
m_StreamingDestinationsByPorts.erase (it);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
i2p::datagram::DatagramDestination * ClientDestination::CreateDatagramDestination (bool gzip)
|
||||
{
|
||||
if (m_DatagramDestination == nullptr)
|
||||
m_DatagramDestination = new i2p::datagram::DatagramDestination (GetSharedFromThis (), gzip);
|
||||
return m_DatagramDestination;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<const i2p::stream::Stream> > ClientDestination::GetAllStreams () const
|
||||
{
|
||||
std::vector<std::shared_ptr<const i2p::stream::Stream> > ret;
|
||||
|
@ -1253,7 +1253,7 @@ namespace client
|
|||
if (m_StandardEncryptionKey && m_StandardEncryptionKey->decryptor)
|
||||
return m_StandardEncryptionKey->decryptor->Decrypt (encrypted, data, ctx, true);
|
||||
else
|
||||
LogPrint (eLogError, "Destinations: decryptor is not set");
|
||||
LogPrint (eLogError, "Destinations: Decryptor is not set");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -90,24 +90,24 @@ namespace garlic
|
|||
}
|
||||
|
||||
void RatchetTagSet::DeleteSymmKey (int index)
|
||||
{
|
||||
{
|
||||
m_ItermediateSymmKeys.erase (index);
|
||||
}
|
||||
|
||||
|
||||
void ReceiveRatchetTagSet::Expire ()
|
||||
{
|
||||
if (!m_ExpirationTimestamp)
|
||||
m_ExpirationTimestamp = i2p::util::GetSecondsSinceEpoch () + ECIESX25519_PREVIOUS_TAGSET_EXPIRATION_TIMEOUT;
|
||||
}
|
||||
|
||||
bool ReceiveRatchetTagSet::IsExpired (uint64_t ts) const
|
||||
{
|
||||
return m_ExpirationTimestamp && ts > m_ExpirationTimestamp;
|
||||
}
|
||||
|
||||
bool ReceiveRatchetTagSet::IsIndexExpired (int index) const
|
||||
{
|
||||
return index < m_TrimBehindIndex;
|
||||
bool ReceiveRatchetTagSet::IsExpired (uint64_t ts) const
|
||||
{
|
||||
return m_ExpirationTimestamp && ts > m_ExpirationTimestamp;
|
||||
}
|
||||
|
||||
bool ReceiveRatchetTagSet::IsIndexExpired (int index) const
|
||||
{
|
||||
return index < m_TrimBehindIndex;
|
||||
}
|
||||
|
||||
bool ReceiveRatchetTagSet::HandleNextMessage (uint8_t * buf, size_t len, int index)
|
||||
|
@ -115,21 +115,21 @@ namespace garlic
|
|||
auto session = GetSession ();
|
||||
if (!session) return false;
|
||||
return session->HandleNextMessage (buf, len, shared_from_this (), index);
|
||||
}
|
||||
}
|
||||
|
||||
SymmetricKeyTagSet::SymmetricKeyTagSet (GarlicDestination * destination, const uint8_t * key):
|
||||
ReceiveRatchetTagSet (nullptr), m_Destination (destination)
|
||||
{
|
||||
memcpy (m_Key, key, 32);
|
||||
Expire ();
|
||||
ReceiveRatchetTagSet (nullptr), m_Destination (destination)
|
||||
{
|
||||
memcpy (m_Key, key, 32);
|
||||
Expire ();
|
||||
}
|
||||
|
||||
|
||||
bool SymmetricKeyTagSet::HandleNextMessage (uint8_t * buf, size_t len, int index)
|
||||
{
|
||||
if (len < 24) return false;
|
||||
uint8_t nonce[12];
|
||||
memset (nonce, 0, 12); // n = 0
|
||||
size_t offset = 8; // first 8 bytes is reply tag used as AD
|
||||
size_t offset = 8; // first 8 bytes is reply tag used as AD
|
||||
len -= 16; // poly1305
|
||||
if (!i2p::crypto::AEADChaCha20Poly1305 (buf + offset, len - offset, buf, 8, m_Key, nonce, buf + offset, len - offset, false)) // decrypt
|
||||
{
|
||||
|
@ -137,33 +137,33 @@ namespace garlic
|
|||
return false;
|
||||
}
|
||||
// we assume 1 I2NP block with delivery type local
|
||||
if (offset + 3 > len)
|
||||
{
|
||||
if (offset + 3 > len)
|
||||
{
|
||||
LogPrint (eLogWarning, "Garlic: Symmetric key tagset is too short ", len);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (buf[offset] != eECIESx25519BlkGalicClove)
|
||||
{
|
||||
LogPrint (eLogWarning, "Garlic: Symmetric key tagset unexpected block ", (int)buf[offset]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
offset++;
|
||||
auto size = bufbe16toh (buf + offset);
|
||||
offset += 2;
|
||||
if (offset + size > len)
|
||||
if (offset + size > len)
|
||||
{
|
||||
LogPrint (eLogWarning, "Garlic: Symmetric key tagset block is too long ", size);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (m_Destination)
|
||||
m_Destination->HandleECIESx25519GarlicClove (buf + offset, size);
|
||||
m_Destination->HandleECIESx25519GarlicClove (buf + offset, size);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ECIESX25519AEADRatchetSession::ECIESX25519AEADRatchetSession (GarlicDestination * owner, bool attachLeaseSetNS):
|
||||
GarlicRoutingSession (owner, true)
|
||||
{
|
||||
if (!attachLeaseSetNS) SetLeaseSetUpdateStatus (eLeaseSetUpToDate);
|
||||
if (!attachLeaseSetNS) SetLeaseSetUpdateStatus (eLeaseSetUpToDate);
|
||||
RAND_bytes (m_PaddingSizes, 32); m_NextPaddingSize = 0;
|
||||
}
|
||||
|
||||
|
@ -181,11 +181,11 @@ namespace garlic
|
|||
{
|
||||
bool ineligible = false;
|
||||
while (!ineligible)
|
||||
{
|
||||
{
|
||||
m_EphemeralKeys = i2p::transport::transports.GetNextX25519KeysPair ();
|
||||
ineligible = m_EphemeralKeys->IsElligatorIneligible ();
|
||||
if (!ineligible) // we haven't tried it yet
|
||||
{
|
||||
{
|
||||
if (i2p::crypto::GetElligator ()->Encode (m_EphemeralKeys->GetPublicKey (), buf))
|
||||
return true; // success
|
||||
// otherwise return back
|
||||
|
@ -194,7 +194,7 @@ namespace garlic
|
|||
}
|
||||
else
|
||||
i2p::transport::transports.ReuseX25519KeysPair (m_EphemeralKeys);
|
||||
}
|
||||
}
|
||||
// we still didn't find elligator eligible pair
|
||||
for (int i = 0; i < 25; i++)
|
||||
{
|
||||
|
@ -208,7 +208,7 @@ namespace garlic
|
|||
// let NTCP2 use it
|
||||
m_EphemeralKeys->SetElligatorIneligible ();
|
||||
i2p::transport::transports.ReuseX25519KeysPair (m_EphemeralKeys);
|
||||
}
|
||||
}
|
||||
}
|
||||
LogPrint (eLogError, "Garlic: Can't generate elligator eligible x25519 keys");
|
||||
return false;
|
||||
|
@ -229,7 +229,7 @@ namespace garlic
|
|||
// we are Bob
|
||||
// KDF1
|
||||
i2p::crypto::InitNoiseIKState (GetNoiseState (), GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)); // bpk
|
||||
|
||||
|
||||
if (!i2p::crypto::GetElligator ()->Decode (buf, m_Aepk))
|
||||
{
|
||||
LogPrint (eLogError, "Garlic: Can't decode elligator");
|
||||
|
@ -243,7 +243,7 @@ namespace garlic
|
|||
{
|
||||
LogPrint (eLogWarning, "Garlic: Incorrect Alice ephemeral key");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
MixKey (sharedSecret);
|
||||
|
||||
// decrypt flags/static
|
||||
|
@ -267,7 +267,7 @@ namespace garlic
|
|||
{
|
||||
LogPrint (eLogWarning, "Garlic: Incorrect Alice static key");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
MixKey (sharedSecret);
|
||||
}
|
||||
else // all zeros flags
|
||||
|
@ -280,13 +280,13 @@ namespace garlic
|
|||
LogPrint (eLogWarning, "Garlic: Payload section AEAD verification failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
m_State = eSessionStateNewSessionReceived;
|
||||
if (isStatic)
|
||||
{
|
||||
if (isStatic)
|
||||
{
|
||||
MixHash (buf, len); // h = SHA256(h || ciphertext)
|
||||
GetOwner ()->AddECIESx25519Session (m_RemoteStaticKey, shared_from_this ());
|
||||
}
|
||||
}
|
||||
HandlePayload (payload.data (), len - 16, nullptr, 0);
|
||||
|
||||
return true;
|
||||
|
@ -381,7 +381,7 @@ namespace garlic
|
|||
newTagset->NextSessionTagRatchet ();
|
||||
m_SendTagset = newTagset;
|
||||
m_SendForwardKey = false;
|
||||
LogPrint (eLogDebug, "Garlic: next send tagset ", newTagset->GetTagSetID (), " created");
|
||||
LogPrint (eLogDebug, "Garlic: Next send tagset ", newTagset->GetTagSetID (), " created");
|
||||
}
|
||||
else
|
||||
LogPrint (eLogDebug, "Garlic: Unexpected next key ", keyID);
|
||||
|
@ -424,7 +424,7 @@ namespace garlic
|
|||
GenerateMoreReceiveTags (newTagset, (GetOwner () && GetOwner ()->GetNumRatchetInboundTags () > 0) ?
|
||||
GetOwner ()->GetNumRatchetInboundTags () : ECIESX25519_MAX_NUM_GENERATED_TAGS);
|
||||
receiveTagset->Expire ();
|
||||
LogPrint (eLogDebug, "Garlic: next receive tagset ", tagsetID, " created");
|
||||
LogPrint (eLogDebug, "Garlic: Next receive tagset ", tagsetID, " created");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -446,7 +446,7 @@ namespace garlic
|
|||
m_NextSendRatchet->key = i2p::transport::transports.GetNextX25519KeysPair ();
|
||||
|
||||
m_SendForwardKey = true;
|
||||
LogPrint (eLogDebug, "Garlic: new send ratchet ", m_NextSendRatchet->newKey ? "new" : "old", " key ", m_NextSendRatchet->keyID, " created");
|
||||
LogPrint (eLogDebug, "Garlic: New send ratchet ", m_NextSendRatchet->newKey ? "new" : "old", " key ", m_NextSendRatchet->keyID, " created");
|
||||
}
|
||||
|
||||
bool ECIESX25519AEADRatchetSession::NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen, bool isStatic)
|
||||
|
@ -468,7 +468,7 @@ namespace garlic
|
|||
{
|
||||
LogPrint (eLogWarning, "Garlic: Incorrect Bob static key");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
MixKey (sharedSecret);
|
||||
// encrypt flags/static key section
|
||||
uint8_t nonce[12];
|
||||
|
@ -478,7 +478,7 @@ namespace garlic
|
|||
fs = GetOwner ()->GetEncryptionPublicKey (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD);
|
||||
else
|
||||
{
|
||||
memset (out + offset, 0, 32); // all zeros flags section
|
||||
memset (out + offset, 0, 32); // all zeros flags section
|
||||
fs = out + offset;
|
||||
}
|
||||
if (!i2p::crypto::AEADChaCha20Poly1305 (fs, 32, m_H, 32, m_CK + 32, nonce, out + offset, 48, true)) // encrypt
|
||||
|
@ -486,14 +486,14 @@ namespace garlic
|
|||
LogPrint (eLogWarning, "Garlic: Flags/static section AEAD encryption failed ");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
MixHash (out + offset, 48); // h = SHA256(h || ciphertext)
|
||||
offset += 48;
|
||||
// KDF2
|
||||
if (isStatic)
|
||||
{
|
||||
{
|
||||
GetOwner ()->Decrypt (m_RemoteStaticKey, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // x25519 (ask, bpk)
|
||||
MixKey (sharedSecret);
|
||||
MixKey (sharedSecret);
|
||||
}
|
||||
else
|
||||
CreateNonce (1, nonce);
|
||||
|
@ -503,10 +503,10 @@ namespace garlic
|
|||
LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
m_State = eSessionStateNewSessionSent;
|
||||
if (isStatic)
|
||||
{
|
||||
{
|
||||
MixHash (out + offset, len + 16); // h = SHA256(h || ciphertext)
|
||||
if (GetOwner ())
|
||||
{
|
||||
|
@ -514,11 +514,11 @@ namespace garlic
|
|||
InitNewSessionTagset (tagsetNsr);
|
||||
tagsetNsr->Expire (); // let non-replied session expire
|
||||
GenerateMoreReceiveTags (tagsetNsr, ECIESX25519_NSR_NUM_GENERATED_TAGS);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool ECIESX25519AEADRatchetSession::NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen)
|
||||
{
|
||||
// we are Bob
|
||||
|
@ -545,13 +545,13 @@ namespace garlic
|
|||
{
|
||||
LogPrint (eLogWarning, "Garlic: Incorrect Alice ephemeral key");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
MixKey (sharedSecret);
|
||||
if (!m_EphemeralKeys->Agree (m_RemoteStaticKey, sharedSecret)) // sharedSecret = x25519(besk, apk)
|
||||
{
|
||||
LogPrint (eLogWarning, "Garlic: Incorrect Alice static key");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
MixKey (sharedSecret);
|
||||
uint8_t nonce[12];
|
||||
CreateNonce (0, nonce);
|
||||
|
@ -584,10 +584,10 @@ namespace garlic
|
|||
}
|
||||
m_State = eSessionStateNewSessionReplySent;
|
||||
m_SessionCreatedTimestamp = i2p::util::GetSecondsSinceEpoch ();
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool ECIESX25519AEADRatchetSession::NextNewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen)
|
||||
{
|
||||
// we are Bob and sent NSR already
|
||||
|
@ -618,7 +618,7 @@ namespace garlic
|
|||
bool ECIESX25519AEADRatchetSession::HandleNewOutgoingSessionReply (uint8_t * buf, size_t len)
|
||||
{
|
||||
// we are Alice
|
||||
LogPrint (eLogDebug, "Garlic: reply received");
|
||||
LogPrint (eLogDebug, "Garlic: Reply received");
|
||||
const uint8_t * tag = buf;
|
||||
buf += 8; len -= 8; // tag
|
||||
uint8_t bepk[32]; // Bob's ephemeral key
|
||||
|
@ -637,7 +637,7 @@ namespace garlic
|
|||
{
|
||||
LogPrint (eLogWarning, "Garlic: Incorrect Bob ephemeral key");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
MixKey (sharedSecret);
|
||||
GetOwner ()->Decrypt (bepk, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // x25519 (ask, bepk)
|
||||
MixKey (sharedSecret);
|
||||
|
@ -700,11 +700,11 @@ namespace garlic
|
|||
uint64_t tag = m_SendTagset->GetNextSessionTag ();
|
||||
if (!tag)
|
||||
{
|
||||
LogPrint (eLogError, "Garlic: can't create new ECIES-X25519-AEAD-Ratchet tag for send tagset");
|
||||
LogPrint (eLogError, "Garlic: Can't create new ECIES-X25519-AEAD-Ratchet tag for send tagset");
|
||||
if (GetOwner ())
|
||||
GetOwner ()->RemoveECIESx25519Session (m_RemoteStaticKey);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
memcpy (out, &tag, 8);
|
||||
// ad = The session tag, 8 bytes
|
||||
// ciphertext = ENCRYPT(k, n, payload, ad)
|
||||
|
@ -736,7 +736,7 @@ namespace garlic
|
|||
}
|
||||
HandlePayload (payload, len - 16, receiveTagset, index);
|
||||
if (GetOwner ())
|
||||
{
|
||||
{
|
||||
int moreTags = 0;
|
||||
if (GetOwner ()->GetNumRatchetInboundTags () > 0) // override in settings?
|
||||
{
|
||||
|
@ -745,17 +745,17 @@ namespace garlic
|
|||
index -= GetOwner ()->GetNumRatchetInboundTags (); // trim behind
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
moreTags = ECIESX25519_MIN_NUM_GENERATED_TAGS + (index >> 2); // N/4
|
||||
if (moreTags > ECIESX25519_MAX_NUM_GENERATED_TAGS) moreTags = ECIESX25519_MAX_NUM_GENERATED_TAGS;
|
||||
moreTags -= (receiveTagset->GetNextIndex () - index);
|
||||
index -= ECIESX25519_MAX_NUM_GENERATED_TAGS; // trim behind
|
||||
}
|
||||
}
|
||||
if (moreTags > 0)
|
||||
GenerateMoreReceiveTags (receiveTagset, moreTags);
|
||||
if (index > 0)
|
||||
receiveTagset->SetTrimBehind (index);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -774,13 +774,13 @@ namespace garlic
|
|||
#endif
|
||||
case eSessionStateEstablished:
|
||||
if (receiveTagset->IsNS ())
|
||||
{
|
||||
// our of sequence NSR
|
||||
{
|
||||
// our of sequence NSR
|
||||
LogPrint (eLogDebug, "Garlic: check for out of order NSR with index ", index);
|
||||
if (receiveTagset->GetNextIndex () - index < ECIESX25519_NSR_NUM_GENERATED_TAGS/2)
|
||||
GenerateMoreReceiveTags (receiveTagset, ECIESX25519_NSR_NUM_GENERATED_TAGS);
|
||||
return HandleNewOutgoingSessionReply (buf, len);
|
||||
}
|
||||
}
|
||||
else
|
||||
return HandleExistingSessionMessage (buf, len, receiveTagset, index);
|
||||
case eSessionStateNew:
|
||||
|
@ -792,7 +792,7 @@ namespace garlic
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<I2NPMessage> ECIESX25519AEADRatchetSession::WrapSingleMessage (std::shared_ptr<const I2NPMessage> msg)
|
||||
{
|
||||
uint8_t * payload = GetOwner ()->GetPayloadBuffer ();
|
||||
|
@ -829,7 +829,7 @@ namespace garlic
|
|||
if (!NewOutgoingSessionMessage (payload, len, buf, m->maxLen, false))
|
||||
return nullptr;
|
||||
len += 96;
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -844,18 +844,18 @@ namespace garlic
|
|||
{
|
||||
m_State = eSessionStateOneTime;
|
||||
return WrapSingleMessage (msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
size_t ECIESX25519AEADRatchetSession::CreatePayload (std::shared_ptr<const I2NPMessage> msg, bool first, uint8_t * payload)
|
||||
{
|
||||
uint64_t ts = i2p::util::GetMillisecondsSinceEpoch ();
|
||||
size_t payloadLen = 0;
|
||||
if (first) payloadLen += 7;// datatime
|
||||
if (msg)
|
||||
{
|
||||
{
|
||||
payloadLen += msg->GetPayloadLength () + 13;
|
||||
if (m_Destination) payloadLen += 32;
|
||||
}
|
||||
}
|
||||
if (GetLeaseSetUpdateStatus () == eLeaseSetSubmitted && ts > GetLeaseSetSubmissionTime () + LEASET_CONFIRMATION_TIMEOUT)
|
||||
{
|
||||
// resubmit non-confirmed LeaseSet
|
||||
|
@ -896,9 +896,9 @@ namespace garlic
|
|||
paddingSize = m_PaddingSizes[m_NextPaddingSize++] & 0x0F; // 0 - 15
|
||||
if (m_NextPaddingSize >= 32)
|
||||
{
|
||||
RAND_bytes (m_PaddingSizes, 32);
|
||||
RAND_bytes (m_PaddingSizes, 32);
|
||||
m_NextPaddingSize = 0;
|
||||
}
|
||||
}
|
||||
if (delta > 3)
|
||||
{
|
||||
delta -= 3;
|
||||
|
@ -912,9 +912,9 @@ namespace garlic
|
|||
{
|
||||
if (payloadLen > I2NP_MAX_MESSAGE_SIZE)
|
||||
{
|
||||
LogPrint (eLogError, "Garlic: payload length ", payloadLen, " is too long");
|
||||
LogPrint (eLogError, "Garlic: Payload length ", payloadLen, " is too long");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
m_LastSentTimestamp = ts;
|
||||
size_t offset = 0;
|
||||
// DateTime
|
||||
|
@ -993,7 +993,7 @@ namespace garlic
|
|||
htobe16buf (payload + offset, paddingSize); offset += 2;
|
||||
memset (payload + offset, 0, paddingSize); offset += paddingSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
return payloadLen;
|
||||
}
|
||||
|
||||
|
@ -1050,17 +1050,17 @@ namespace garlic
|
|||
void ECIESX25519AEADRatchetSession::GenerateMoreReceiveTags (std::shared_ptr<ReceiveRatchetTagSet> receiveTagset, int numTags)
|
||||
{
|
||||
if (GetOwner ())
|
||||
{
|
||||
{
|
||||
for (int i = 0; i < numTags; i++)
|
||||
{
|
||||
{
|
||||
auto tag = GetOwner ()->AddECIESx25519SessionNextTag (receiveTagset);
|
||||
if (!tag)
|
||||
{
|
||||
LogPrint (eLogError, "Garlic: can't create new ECIES-X25519-AEAD-Ratchet tag for receive tagset");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ECIESX25519AEADRatchetSession::CheckExpired (uint64_t ts)
|
||||
|
@ -1073,9 +1073,9 @@ namespace garlic
|
|||
RouterIncomingRatchetSession::RouterIncomingRatchetSession (const i2p::crypto::NoiseSymmetricState& initState):
|
||||
ECIESX25519AEADRatchetSession (&i2p::context, false)
|
||||
{
|
||||
SetLeaseSetUpdateStatus (eLeaseSetDoNotSend);
|
||||
SetLeaseSetUpdateStatus (eLeaseSetDoNotSend);
|
||||
SetNoiseState (initState);
|
||||
}
|
||||
}
|
||||
|
||||
bool RouterIncomingRatchetSession::HandleNextMessage (const uint8_t * buf, size_t len)
|
||||
{
|
||||
|
@ -1088,12 +1088,12 @@ namespace garlic
|
|||
{
|
||||
LogPrint (eLogWarning, "Garlic: Incorrect N ephemeral public key");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
m_CurrentNoiseState.MixKey (sharedSecret);
|
||||
buf += 32; len -= 32;
|
||||
buf += 32; len -= 32;
|
||||
uint8_t nonce[12];
|
||||
CreateNonce (0, nonce);
|
||||
std::vector<uint8_t> payload (len - 16);
|
||||
std::vector<uint8_t> payload (len - 16);
|
||||
if (!i2p::crypto::AEADChaCha20Poly1305 (buf, len - 16, m_CurrentNoiseState.m_H, 32,
|
||||
m_CurrentNoiseState.m_CK + 32, nonce, payload.data (), len - 16, false)) // decrypt
|
||||
{
|
||||
|
@ -1102,20 +1102,20 @@ namespace garlic
|
|||
}
|
||||
HandlePayload (payload.data (), len - 16, nullptr, 0);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static size_t CreateGarlicPayload (std::shared_ptr<const I2NPMessage> msg, uint8_t * payload,
|
||||
static size_t CreateGarlicPayload (std::shared_ptr<const I2NPMessage> msg, uint8_t * payload,
|
||||
bool datetime, size_t optimalSize)
|
||||
{
|
||||
size_t len = 0;
|
||||
if (datetime)
|
||||
{
|
||||
{
|
||||
// DateTime
|
||||
payload[0] = eECIESx25519BlkDateTime;
|
||||
payload[0] = eECIESx25519BlkDateTime;
|
||||
htobe16buf (payload + 1, 4);
|
||||
htobe32buf (payload + 3, i2p::util::GetSecondsSinceEpoch ());
|
||||
htobe32buf (payload + 3, i2p::util::GetSecondsSinceEpoch ());
|
||||
len = 7;
|
||||
}
|
||||
}
|
||||
// I2NP
|
||||
payload += len;
|
||||
uint16_t cloveSize = msg->GetPayloadLength () + 10;
|
||||
|
@ -1139,14 +1139,14 @@ namespace garlic
|
|||
delta -= 3;
|
||||
if (paddingSize > delta) paddingSize %= delta;
|
||||
}
|
||||
payload[0] = eECIESx25519BlkPadding;
|
||||
htobe16buf (payload + 1, paddingSize);
|
||||
payload[0] = eECIESx25519BlkPadding;
|
||||
htobe16buf (payload + 1, paddingSize);
|
||||
if (paddingSize) memset (payload + 3, 0, paddingSize);
|
||||
len += paddingSize + 3;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::shared_ptr<I2NPMessage> WrapECIESX25519Message (std::shared_ptr<const I2NPMessage> msg, const uint8_t * key, uint64_t tag)
|
||||
{
|
||||
auto m = NewI2NPMessage ();
|
||||
|
@ -1188,8 +1188,8 @@ namespace garlic
|
|||
{
|
||||
LogPrint (eLogWarning, "Garlic: Incorrect Bob static key");
|
||||
return nullptr;
|
||||
}
|
||||
noiseState.MixKey (sharedSecret);
|
||||
}
|
||||
noiseState.MixKey (sharedSecret);
|
||||
auto payload = buf + offset;
|
||||
size_t len = CreateGarlicPayload (msg, payload, true, 900); // 1003 - 32 eph key - 16 Poly1305 hash - 16 I2NP header - 4 garlic length - 35 router tunnel delivery
|
||||
uint8_t nonce[12];
|
||||
|
@ -1205,6 +1205,6 @@ namespace garlic
|
|||
m->len += offset + 4;
|
||||
m->FillI2NPMessageHeader (eI2NPGarlic);
|
||||
return m;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -456,7 +456,7 @@ namespace garlic
|
|||
{
|
||||
it.second->Terminate ();
|
||||
it.second->SetOwner (nullptr);
|
||||
}
|
||||
}
|
||||
m_ECIESx25519Sessions.clear ();
|
||||
m_ECIESx25519Tags.clear ();
|
||||
}
|
||||
|
@ -474,14 +474,14 @@ namespace garlic
|
|||
uint64_t t;
|
||||
memcpy (&t, tag, 8);
|
||||
AddECIESx25519Key (key, t);
|
||||
}
|
||||
}
|
||||
|
||||
void GarlicDestination::AddECIESx25519Key (const uint8_t * key, uint64_t tag)
|
||||
{
|
||||
auto tagset = std::make_shared<SymmetricKeyTagSet>(this, key);
|
||||
m_ECIESx25519Tags.emplace (tag, ECIESX25519AEADRatchetIndexTagset{0, tagset});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool GarlicDestination::SubmitSessionKey (const uint8_t * key, const uint8_t * tag)
|
||||
{
|
||||
AddSessionKey (key, tag);
|
||||
|
@ -502,10 +502,10 @@ namespace garlic
|
|||
|
||||
bool found = false;
|
||||
if (SupportsEncryptionType (i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD))
|
||||
// try ECIESx25519 tag
|
||||
// try ECIESx25519 tag
|
||||
found = HandleECIESx25519TagMessage (buf, length);
|
||||
if (!found)
|
||||
{
|
||||
{
|
||||
auto it = !mod ? m_Tags.find (SessionTag(buf)) : m_Tags.end (); // AES block is multiple of 16
|
||||
// AES tag might be used even if encryption type is not ElGamal/AES
|
||||
if (it != m_Tags.end ()) // try AES tag
|
||||
|
@ -546,7 +546,7 @@ namespace garlic
|
|||
auto session = std::make_shared<ECIESX25519AEADRatchetSession> (this, false); // incoming
|
||||
if (!session->HandleNextMessage (buf, length, nullptr, 0))
|
||||
{
|
||||
// try to gererate more tags for last tagset
|
||||
// try to gererate more tags for last tagset
|
||||
if (m_LastTagset && (m_LastTagset->GetNextIndex () - m_LastTagset->GetTrimBehind () < 3*ECIESX25519_MAX_NUM_GENERATED_TAGS))
|
||||
{
|
||||
uint64_t missingTag; memcpy (&missingTag, buf, 8);
|
||||
|
@ -559,24 +559,24 @@ namespace garlic
|
|||
{
|
||||
LogPrint (eLogError, "Garlic: can't create new ECIES-X25519-AEAD-Ratchet tag for last tagset");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (nextTag == missingTag)
|
||||
{
|
||||
LogPrint (eLogDebug, "Garlic: Missing ECIES-X25519-AEAD-Ratchet tag was generated");
|
||||
if (m_LastTagset->HandleNextMessage (buf, length, m_ECIESx25519Tags[nextTag].index))
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found) m_LastTagset = nullptr;
|
||||
}
|
||||
if (!found)
|
||||
LogPrint (eLogError, "Garlic: can't handle ECIES-X25519-AEAD-Ratchet message");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
LogPrint (eLogError, "Garlic: Failed to decrypt message");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -589,14 +589,14 @@ namespace garlic
|
|||
{
|
||||
if (it->second.tagset->HandleNextMessage (buf, len, it->second.index))
|
||||
m_LastTagset = it->second.tagset;
|
||||
else
|
||||
LogPrint (eLogError, "Garlic: can't handle ECIES-X25519-AEAD-Ratchet message");
|
||||
else
|
||||
LogPrint (eLogError, "Garlic: Can't handle ECIES-X25519-AEAD-Ratchet message");
|
||||
m_ECIESx25519Tags.erase (it);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void GarlicDestination::HandleAESBlock (uint8_t * buf, size_t len, std::shared_ptr<AESDecryption> decryption,
|
||||
std::shared_ptr<i2p::tunnel::InboundTunnel> from)
|
||||
{
|
||||
|
@ -633,7 +633,7 @@ namespace garlic
|
|||
SHA256 (buf, payloadSize, digest);
|
||||
if (memcmp (payloadHash, digest, 32)) // payload hash doesn't match
|
||||
{
|
||||
LogPrint (eLogError, "Garlic: wrong payload hash");
|
||||
LogPrint (eLogError, "Garlic: Wrong payload hash");
|
||||
return;
|
||||
}
|
||||
HandleGarlicPayload (buf, payloadSize, from);
|
||||
|
@ -643,7 +643,7 @@ namespace garlic
|
|||
{
|
||||
if (len < 1)
|
||||
{
|
||||
LogPrint (eLogError, "Garlic: payload is too short");
|
||||
LogPrint (eLogError, "Garlic: Payload is too short");
|
||||
return;
|
||||
}
|
||||
int numCloves = buf[0];
|
||||
|
@ -658,7 +658,7 @@ namespace garlic
|
|||
if (flag & 0x80) // encrypted?
|
||||
{
|
||||
// TODO: implement
|
||||
LogPrint (eLogWarning, "Garlic: clove encrypted");
|
||||
LogPrint (eLogWarning, "Garlic: Clove encrypted");
|
||||
buf += 32;
|
||||
}
|
||||
ptrdiff_t offset = buf - buf1;
|
||||
|
@ -666,35 +666,35 @@ namespace garlic
|
|||
switch (deliveryType)
|
||||
{
|
||||
case eGarlicDeliveryTypeLocal:
|
||||
LogPrint (eLogDebug, "Garlic: type local");
|
||||
LogPrint (eLogDebug, "Garlic: Type local");
|
||||
if (offset > (int)len)
|
||||
{
|
||||
LogPrint (eLogError, "Garlic: message is too short");
|
||||
LogPrint (eLogError, "Garlic: Message is too short");
|
||||
break;
|
||||
}
|
||||
HandleI2NPMessage (buf, len - offset);
|
||||
break;
|
||||
case eGarlicDeliveryTypeDestination:
|
||||
LogPrint (eLogDebug, "Garlic: type destination");
|
||||
LogPrint (eLogDebug, "Garlic: Type destination");
|
||||
buf += 32; // destination. check it later or for multiple destinations
|
||||
offset = buf - buf1;
|
||||
if (offset > (int)len)
|
||||
{
|
||||
LogPrint (eLogError, "Garlic: message is too short");
|
||||
LogPrint (eLogError, "Garlic: Message is too short");
|
||||
break;
|
||||
}
|
||||
HandleI2NPMessage (buf, len - offset);
|
||||
break;
|
||||
case eGarlicDeliveryTypeTunnel:
|
||||
{
|
||||
LogPrint (eLogDebug, "Garlic: type tunnel");
|
||||
LogPrint (eLogDebug, "Garlic: Type tunnel");
|
||||
// gwHash and gwTunnel sequence is reverted
|
||||
uint8_t * gwHash = buf;
|
||||
buf += 32;
|
||||
offset = buf - buf1;
|
||||
if (offset + 4 > (int)len)
|
||||
{
|
||||
LogPrint (eLogError, "Garlic: message is too short");
|
||||
LogPrint (eLogError, "Garlic: Message is too short");
|
||||
break;
|
||||
}
|
||||
uint32_t gwTunnel = bufbe32toh (buf);
|
||||
|
@ -725,22 +725,22 @@ namespace garlic
|
|||
{
|
||||
if (offset > (int)len)
|
||||
{
|
||||
LogPrint (eLogError, "Garlic: message is too short");
|
||||
LogPrint (eLogError, "Garlic: Message is too short");
|
||||
break;
|
||||
}
|
||||
i2p::transport::transports.SendMessage (ident,
|
||||
CreateI2NPMessage (buf, GetI2NPMessageLength (buf, len - offset)));
|
||||
}
|
||||
else
|
||||
LogPrint (eLogWarning, "Garlic: type router for inbound tunnels not supported");
|
||||
LogPrint (eLogWarning, "Garlic: Type router for inbound tunnels not supported");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LogPrint (eLogWarning, "Garlic: unknown delivery type ", (int)deliveryType);
|
||||
LogPrint (eLogWarning, "Garlic: Unknown delivery type ", (int)deliveryType);
|
||||
}
|
||||
if (offset > (int)len)
|
||||
{
|
||||
LogPrint (eLogError, "Garlic: message is too short");
|
||||
LogPrint (eLogError, "Garlic: Message is too short");
|
||||
break;
|
||||
}
|
||||
buf += GetI2NPMessageLength (buf, len - offset); // I2NP
|
||||
|
@ -750,7 +750,7 @@ namespace garlic
|
|||
offset = buf - buf1;
|
||||
if (offset > (int)len)
|
||||
{
|
||||
LogPrint (eLogError, "Garlic: clove is too long");
|
||||
LogPrint (eLogError, "Garlic: Clove is too long");
|
||||
break;
|
||||
}
|
||||
len -= offset;
|
||||
|
@ -763,10 +763,10 @@ namespace garlic
|
|||
if (router->GetEncryptionType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)
|
||||
return WrapECIESX25519MessageForRouter (msg, router->GetIdentity ()->GetEncryptionPublicKey ());
|
||||
else
|
||||
{
|
||||
{
|
||||
auto session = GetRoutingSession (router, false);
|
||||
return session->WrapSingleMessage (msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<GarlicRoutingSession> GarlicDestination::GetRoutingSession (
|
||||
|
@ -780,14 +780,14 @@ namespace garlic
|
|||
destination->Encrypt (nullptr, staticKey, nullptr); // we are supposed to get static key
|
||||
auto it = m_ECIESx25519Sessions.find (staticKey);
|
||||
if (it != m_ECIESx25519Sessions.end ())
|
||||
{
|
||||
{
|
||||
session = it->second;
|
||||
if (session->IsInactive (i2p::util::GetSecondsSinceEpoch ()))
|
||||
{
|
||||
LogPrint (eLogDebug, "Garlic: session restarted");
|
||||
LogPrint (eLogDebug, "Garlic: Session restarted");
|
||||
session = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!session)
|
||||
{
|
||||
session = std::make_shared<ECIESX25519AEADRatchetSession> (this, true);
|
||||
|
@ -883,18 +883,18 @@ namespace garlic
|
|||
it->second.tagset->DeleteSymmKey (it->second.index);
|
||||
it = m_ECIESx25519Tags.erase (it);
|
||||
numExpiredTags++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto session = it->second.tagset->GetSession ();
|
||||
if (!session || session->IsTerminated())
|
||||
{
|
||||
{
|
||||
it = m_ECIESx25519Tags.erase (it);
|
||||
numExpiredTags++;
|
||||
}
|
||||
}
|
||||
else
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (numExpiredTags > 0)
|
||||
LogPrint (eLogDebug, "Garlic: ", numExpiredTags, " ECIESx25519 tags expired for ", GetIdentHash().ToBase64 ());
|
||||
|
@ -1034,7 +1034,7 @@ namespace garlic
|
|||
switch (deliveryType)
|
||||
{
|
||||
case eGarlicDeliveryTypeDestination:
|
||||
LogPrint (eLogDebug, "Garlic: type destination");
|
||||
LogPrint (eLogDebug, "Garlic: Type destination");
|
||||
buf += 32; // TODO: check destination
|
||||
#if (__cplusplus >= 201703L) // C++ 17 or higher
|
||||
[[fallthrough]];
|
||||
|
@ -1042,7 +1042,7 @@ namespace garlic
|
|||
// no break here
|
||||
case eGarlicDeliveryTypeLocal:
|
||||
{
|
||||
LogPrint (eLogDebug, "Garlic: type local");
|
||||
LogPrint (eLogDebug, "Garlic: Type local");
|
||||
I2NPMessageType typeID = (I2NPMessageType)(buf[0]); buf++; // typeid
|
||||
int32_t msgID = bufbe32toh (buf); buf += 4; // msgID
|
||||
buf += 4; // expiration
|
||||
|
@ -1050,19 +1050,19 @@ namespace garlic
|
|||
if (offset <= (int)len)
|
||||
HandleCloveI2NPMessage (typeID, buf, len - offset, msgID);
|
||||
else
|
||||
LogPrint (eLogError, "Garlic: clove is too long");
|
||||
LogPrint (eLogError, "Garlic: Clove is too long");
|
||||
break;
|
||||
}
|
||||
case eGarlicDeliveryTypeTunnel:
|
||||
{
|
||||
LogPrint (eLogDebug, "Garlic: type tunnel");
|
||||
LogPrint (eLogDebug, "Garlic: Type tunnel");
|
||||
// gwHash and gwTunnel sequence is reverted
|
||||
const uint8_t * gwHash = buf;
|
||||
buf += 32;
|
||||
ptrdiff_t offset = buf - buf1;
|
||||
if (offset + 13 > (int)len)
|
||||
{
|
||||
LogPrint (eLogError, "Garlic: message is too short");
|
||||
LogPrint (eLogError, "Garlic: Message is too short");
|
||||
break;
|
||||
}
|
||||
uint32_t gwTunnel = bufbe32toh (buf); buf += 4;
|
||||
|
@ -1083,7 +1083,7 @@ namespace garlic
|
|||
break;
|
||||
}
|
||||
default:
|
||||
LogPrint (eLogWarning, "Garlic: unexpected delivery type ", (int)deliveryType);
|
||||
LogPrint (eLogWarning, "Garlic: Unexpected delivery type ", (int)deliveryType);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1103,10 +1103,10 @@ namespace garlic
|
|||
if (it != m_ECIESx25519Sessions.end ())
|
||||
{
|
||||
if (it->second->CanBeRestarted (i2p::util::GetSecondsSinceEpoch ()))
|
||||
{
|
||||
{
|
||||
it->second->Terminate (); // detach
|
||||
m_ECIESx25519Sessions.erase (it);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogPrint (eLogInfo, "Garlic: ECIESx25519 session with static key ", staticKeyTag.ToBase64 (), " already exists");
|
||||
|
@ -1131,6 +1131,6 @@ namespace garlic
|
|||
if (!m_PayloadBuffer)
|
||||
m_PayloadBuffer = new uint8_t[I2NP_MAX_MESSAGE_SIZE];
|
||||
return m_PayloadBuffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace i2p
|
|||
{
|
||||
I2NPMessage * msg = nullptr;
|
||||
if (endpoint)
|
||||
{
|
||||
{
|
||||
// should fit two tunnel message + tunnel gateway header, enough for one garlic encrypted streaming packet
|
||||
msg = new I2NPMessageBuffer<2*i2p::tunnel::TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE + TUNNEL_GATEWAY_HEADER_SIZE + 28>(); // reserved for alignment and NTCP 16 + 6 + 6
|
||||
msg->Align (6);
|
||||
|
@ -50,7 +50,7 @@ namespace i2p
|
|||
{
|
||||
msg = new I2NPMessageBuffer<i2p::tunnel::TUNNEL_DATA_MSG_SIZE + I2NP_HEADER_SIZE + 34>(); // reserved for alignment and NTCP 16 + 6 + 12
|
||||
msg->Align (12);
|
||||
}
|
||||
}
|
||||
return std::shared_ptr<I2NPMessage>(msg);
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,7 @@ namespace i2p
|
|||
{
|
||||
auto msg = NewI2NPMessage (len);
|
||||
if (msg->Concat (buf, len) < len)
|
||||
LogPrint (eLogError, "I2NP: message length ", len, " exceeds max length ", msg->maxLen);
|
||||
LogPrint (eLogError, "I2NP: Message length ", len, " exceeds max length ", msg->maxLen);
|
||||
msg->FillI2NPMessageHeader (msgType, replyMsgID);
|
||||
return msg;
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ namespace i2p
|
|||
msg->from = from;
|
||||
}
|
||||
else
|
||||
LogPrint (eLogError, "I2NP: message length ", len, " exceeds max length");
|
||||
LogPrint (eLogError, "I2NP: Message length ", len, " exceeds max length");
|
||||
return msg;
|
||||
}
|
||||
|
||||
|
@ -183,7 +183,7 @@ namespace i2p
|
|||
|
||||
std::shared_ptr<I2NPMessage> CreateLeaseSetDatabaseLookupMsg (const i2p::data::IdentHash& dest,
|
||||
const std::set<i2p::data::IdentHash>& excludedFloodfills,
|
||||
std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel, const uint8_t * replyKey,
|
||||
std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel, const uint8_t * replyKey,
|
||||
const uint8_t * replyTag, bool replyECIES)
|
||||
{
|
||||
int cnt = excludedFloodfills.size ();
|
||||
|
@ -222,12 +222,12 @@ namespace i2p
|
|||
{
|
||||
memcpy (buf + 33, replyTag, 8); // 8 bytes tag
|
||||
buf += 41;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy (buf + 33, replyTag, 32); // 32 bytes tag
|
||||
buf += 65;
|
||||
}
|
||||
}
|
||||
|
||||
m->len += (buf - m->GetPayload ());
|
||||
m->FillI2NPMessageHeader (eI2NPDatabaseLookup);
|
||||
|
@ -256,7 +256,7 @@ namespace i2p
|
|||
return m;
|
||||
}
|
||||
|
||||
std::shared_ptr<I2NPMessage> CreateDatabaseStoreMsg (std::shared_ptr<const i2p::data::RouterInfo> router,
|
||||
std::shared_ptr<I2NPMessage> CreateDatabaseStoreMsg (std::shared_ptr<const i2p::data::RouterInfo> router,
|
||||
uint32_t replyToken, std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel)
|
||||
{
|
||||
if (!router) // we send own RouterInfo
|
||||
|
@ -267,7 +267,7 @@ namespace i2p
|
|||
LogPrint (eLogError, "I2NP: Invalid RouterInfo buffer for DatabaseStore");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
auto m = NewI2NPShortMessage ();
|
||||
uint8_t * payload = m->GetPayload ();
|
||||
|
||||
|
@ -285,12 +285,12 @@ namespace i2p
|
|||
buf += 32; // reply tunnel gateway
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
memset (buf, 0, 4); // zero tunnelID means direct reply
|
||||
buf += 4;
|
||||
memcpy (buf, context.GetIdentHash (), 32);
|
||||
buf += 32;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t * sizePtr = buf;
|
||||
|
@ -303,7 +303,7 @@ namespace i2p
|
|||
{
|
||||
i2p::data::GzipDeflator deflator;
|
||||
size = deflator.Deflate (router->GetBuffer (), router->GetBufferLen (), buf, m->maxLen -m->len);
|
||||
}
|
||||
}
|
||||
if (size)
|
||||
{
|
||||
htobe16buf (sizePtr, size); // size
|
||||
|
@ -398,7 +398,7 @@ namespace i2p
|
|||
!i2p::transport::transports.IsBandwidthExceeded () &&
|
||||
!i2p::transport::transports.IsTransitBandwidthExceeded ())
|
||||
{
|
||||
auto transitTunnel = isECIES ?
|
||||
auto transitTunnel = isECIES ?
|
||||
i2p::tunnel::CreateTransitTunnel (
|
||||
bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET),
|
||||
clearText + ECIES_BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
||||
|
@ -423,46 +423,46 @@ namespace i2p
|
|||
if (isECIES)
|
||||
{
|
||||
memset (record + ECIES_BUILD_RESPONSE_RECORD_OPTIONS_OFFSET, 0, 2); // no options
|
||||
record[ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET] = retCode;
|
||||
}
|
||||
record[ECIES_BUILD_RESPONSE_RECORD_RET_OFFSET] = retCode;
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
record[BUILD_RESPONSE_RECORD_RET_OFFSET] = retCode;
|
||||
SHA256 (record + BUILD_RESPONSE_RECORD_PADDING_OFFSET, BUILD_RESPONSE_RECORD_PADDING_SIZE + 1, // + 1 byte of ret
|
||||
record + BUILD_RESPONSE_RECORD_HASH_OFFSET);
|
||||
}
|
||||
}
|
||||
// encrypt reply
|
||||
i2p::crypto::CBCEncryption encryption;
|
||||
for (int j = 0; j < num; j++)
|
||||
{
|
||||
uint8_t * reply = records + j*TUNNEL_BUILD_RECORD_SIZE;
|
||||
if (isECIES)
|
||||
{
|
||||
{
|
||||
if (j == i)
|
||||
{
|
||||
uint8_t nonce[12];
|
||||
memset (nonce, 0, 12);
|
||||
auto& noiseState = i2p::context.GetCurrentNoiseState ();
|
||||
if (!i2p::crypto::AEADChaCha20Poly1305 (reply, TUNNEL_BUILD_RECORD_SIZE - 16,
|
||||
if (!i2p::crypto::AEADChaCha20Poly1305 (reply, TUNNEL_BUILD_RECORD_SIZE - 16,
|
||||
noiseState.m_H, 32, noiseState.m_CK, nonce, reply, TUNNEL_BUILD_RECORD_SIZE, true)) // encrypt
|
||||
{
|
||||
LogPrint (eLogWarning, "I2NP: Reply AEAD encryption failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
encryption.SetKey (clearText + ECIES_BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET);
|
||||
encryption.SetIV (clearText + ECIES_BUILD_REQUEST_RECORD_REPLY_IV_OFFSET);
|
||||
encryption.SetIV (clearText + ECIES_BUILD_REQUEST_RECORD_REPLY_IV_OFFSET);
|
||||
encryption.Encrypt(reply, TUNNEL_BUILD_RECORD_SIZE, reply);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
encryption.SetKey (clearText + BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET);
|
||||
encryption.SetIV (clearText + BUILD_REQUEST_RECORD_REPLY_IV_OFFSET);
|
||||
encryption.SetIV (clearText + BUILD_REQUEST_RECORD_REPLY_IV_OFFSET);
|
||||
encryption.Encrypt(reply, TUNNEL_BUILD_RECORD_SIZE, reply);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -519,7 +519,7 @@ namespace i2p
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
uint8_t clearText[BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE];
|
||||
if (HandleBuildRequestRecords (num, buf + 1, clearText))
|
||||
{
|
||||
|
@ -536,7 +536,7 @@ namespace i2p
|
|||
CreateI2NPMessage (eI2NPVariableTunnelBuild, buf, len,
|
||||
bufbe32toh (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -546,7 +546,7 @@ namespace i2p
|
|||
{
|
||||
LogPrint (eLogWarning, "I2NP: TunnelBuild is too old for ECIES router");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (len < NUM_TUNNEL_BUILD_RECORDS*TUNNEL_BUILD_RECORD_SIZE)
|
||||
{
|
||||
LogPrint (eLogError, "I2NP: TunnelBuild message is too short ", len);
|
||||
|
@ -607,7 +607,7 @@ namespace i2p
|
|||
{
|
||||
LogPrint (eLogWarning, "I2NP: ShortTunnelBuild can be handled by ECIES router only");
|
||||
return;
|
||||
}
|
||||
}
|
||||
int num = buf[0];
|
||||
LogPrint (eLogDebug, "I2NP: ShortTunnelBuild ", num, " records");
|
||||
if (len < num*SHORT_TUNNEL_BUILD_RECORD_SIZE + 1)
|
||||
|
@ -640,8 +640,8 @@ namespace i2p
|
|||
{
|
||||
LogPrint (eLogDebug, "I2NP: Short request record ", i, " is ours");
|
||||
uint8_t clearText[SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE];
|
||||
if (!i2p::context.DecryptTunnelShortRequestRecord (record + SHORT_REQUEST_RECORD_ENCRYPTED_OFFSET, clearText))
|
||||
{
|
||||
if (!i2p::context.DecryptTunnelShortRequestRecord (record + SHORT_REQUEST_RECORD_ENCRYPTED_OFFSET, clearText))
|
||||
{
|
||||
LogPrint (eLogWarning, "I2NP: Can't decrypt short request record ", i);
|
||||
return;
|
||||
}
|
||||
|
@ -649,19 +649,19 @@ namespace i2p
|
|||
{
|
||||
LogPrint (eLogWarning, "I2NP: Unknown layer encryption type ", clearText[SHORT_REQUEST_RECORD_LAYER_ENCRYPTION_TYPE], " in short request record");
|
||||
return;
|
||||
}
|
||||
}
|
||||
auto& noiseState = i2p::context.GetCurrentNoiseState ();
|
||||
uint8_t replyKey[32], layerKey[32], ivKey[32];
|
||||
uint8_t replyKey[32], layerKey[32], ivKey[32];
|
||||
i2p::crypto::HKDF (noiseState.m_CK, nullptr, 0, "SMTunnelReplyKey", noiseState.m_CK);
|
||||
memcpy (replyKey, noiseState.m_CK + 32, 32);
|
||||
i2p::crypto::HKDF (noiseState.m_CK, nullptr, 0, "SMTunnelLayerKey", noiseState.m_CK);
|
||||
i2p::crypto::HKDF (noiseState.m_CK, nullptr, 0, "SMTunnelLayerKey", noiseState.m_CK);
|
||||
memcpy (layerKey, noiseState.m_CK + 32, 32);
|
||||
bool isEndpoint = clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG;
|
||||
if (isEndpoint)
|
||||
{
|
||||
i2p::crypto::HKDF (noiseState.m_CK, nullptr, 0, "TunnelLayerIVKey", noiseState.m_CK);
|
||||
memcpy (ivKey, noiseState.m_CK + 32, 32);
|
||||
}
|
||||
}
|
||||
else
|
||||
memcpy (ivKey, noiseState.m_CK , 32);
|
||||
|
||||
|
@ -673,7 +673,7 @@ namespace i2p
|
|||
i2p::transport::transports.IsTransitBandwidthExceeded ())
|
||||
retCode = 30;
|
||||
if (!retCode)
|
||||
{
|
||||
{
|
||||
// create new transit tunnel
|
||||
auto transitTunnel = i2p::tunnel::CreateTransitTunnel (
|
||||
bufbe32toh (clearText + SHORT_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET),
|
||||
|
@ -684,46 +684,46 @@ namespace i2p
|
|||
clearText[SHORT_REQUEST_RECORD_FLAG_OFFSET] & TUNNEL_BUILD_RECORD_ENDPOINT_FLAG);
|
||||
i2p::tunnel::tunnels.AddTransitTunnel (transitTunnel);
|
||||
}
|
||||
|
||||
|
||||
// encrypt reply
|
||||
uint8_t nonce[12];
|
||||
memset (nonce, 0, 12);
|
||||
uint8_t * reply = buf + 1;
|
||||
for (int j = 0; j < num; j++)
|
||||
{
|
||||
{
|
||||
nonce[4] = j; // nonce is record #
|
||||
if (j == i)
|
||||
{
|
||||
memset (reply + SHORT_RESPONSE_RECORD_OPTIONS_OFFSET, 0, 2); // no options
|
||||
reply[SHORT_RESPONSE_RECORD_RET_OFFSET] = retCode;
|
||||
if (!i2p::crypto::AEADChaCha20Poly1305 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE - 16,
|
||||
reply[SHORT_RESPONSE_RECORD_RET_OFFSET] = retCode;
|
||||
if (!i2p::crypto::AEADChaCha20Poly1305 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE - 16,
|
||||
noiseState.m_H, 32, replyKey, nonce, reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, true)) // encrypt
|
||||
{
|
||||
LogPrint (eLogWarning, "I2NP: Short reply AEAD encryption failed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
i2p::crypto::ChaCha20 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, replyKey, nonce, reply);
|
||||
reply += SHORT_TUNNEL_BUILD_RECORD_SIZE;
|
||||
i2p::crypto::ChaCha20 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, replyKey, nonce, reply);
|
||||
reply += SHORT_TUNNEL_BUILD_RECORD_SIZE;
|
||||
}
|
||||
// send reply
|
||||
if (isEndpoint)
|
||||
{
|
||||
{
|
||||
auto replyMsg = NewI2NPShortMessage ();
|
||||
replyMsg->Concat (buf, len);
|
||||
replyMsg->FillI2NPMessageHeader (eI2NPShortTunnelBuildReply, bufbe32toh (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET));
|
||||
if (memcmp ((const uint8_t *)i2p::context.GetIdentHash (),
|
||||
if (memcmp ((const uint8_t *)i2p::context.GetIdentHash (),
|
||||
clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, 32)) // reply IBGW is not local?
|
||||
{
|
||||
i2p::crypto::HKDF (noiseState.m_CK, nullptr, 0, "RGarlicKeyAndTag", noiseState.m_CK);
|
||||
i2p::crypto::HKDF (noiseState.m_CK, nullptr, 0, "RGarlicKeyAndTag", noiseState.m_CK);
|
||||
uint64_t tag;
|
||||
memcpy (&tag, noiseState.m_CK, 8);
|
||||
// we send it to reply tunnel
|
||||
transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
||||
CreateTunnelGatewayMsg (bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET),
|
||||
i2p::garlic::WrapECIESX25519Message (replyMsg, noiseState.m_CK + 32, tag)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// IBGW is local
|
||||
|
@ -733,18 +733,18 @@ namespace i2p
|
|||
tunnel->SendTunnelDataMsg (replyMsg);
|
||||
else
|
||||
LogPrint (eLogWarning, "I2NP: Tunnel ", tunnelID, " not found for short tunnel build reply");
|
||||
}
|
||||
}
|
||||
else
|
||||
}
|
||||
}
|
||||
else
|
||||
transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
||||
CreateI2NPMessage (eI2NPShortTunnelBuild, buf, len,
|
||||
bufbe32toh (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
record += SHORT_TUNNEL_BUILD_RECORD_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<I2NPMessage> CreateTunnelDataMsg (const uint8_t * buf)
|
||||
{
|
||||
auto msg = NewI2NPTunnelMessage (false);
|
||||
|
@ -778,7 +778,7 @@ namespace i2p
|
|||
htobe16buf (payload + TUNNEL_GATEWAY_HEADER_LENGTH_OFFSET, len);
|
||||
msg->len += TUNNEL_GATEWAY_HEADER_SIZE;
|
||||
if (msg->Concat (buf, len) < len)
|
||||
LogPrint (eLogError, "I2NP: tunnel gateway buffer overflow ", msg->maxLen);
|
||||
LogPrint (eLogError, "I2NP: Tunnel gateway buffer overflow ", msg->maxLen);
|
||||
msg->FillI2NPMessageHeader (eI2NPTunnelGateway);
|
||||
return msg;
|
||||
}
|
||||
|
@ -809,7 +809,7 @@ namespace i2p
|
|||
msg->offset += gatewayMsgOffset;
|
||||
msg->len += gatewayMsgOffset;
|
||||
if (msg->Concat (buf, len) < len)
|
||||
LogPrint (eLogError, "I2NP: tunnel gateway buffer overflow ", msg->maxLen);
|
||||
LogPrint (eLogError, "I2NP: Tunnel gateway buffer overflow ", msg->maxLen);
|
||||
msg->FillI2NPMessageHeader (msgType, replyMsgID); // create content message
|
||||
len = msg->GetLength ();
|
||||
msg->offset -= gatewayMsgOffset;
|
||||
|
@ -824,13 +824,13 @@ namespace i2p
|
|||
{
|
||||
if (len < I2NP_HEADER_SIZE_OFFSET + 2)
|
||||
{
|
||||
LogPrint (eLogError, "I2NP: message length ", len, " is smaller than header");
|
||||
LogPrint (eLogError, "I2NP: Message length ", len, " is smaller than header");
|
||||
return len;
|
||||
}
|
||||
auto l = bufbe16toh (msg + I2NP_HEADER_SIZE_OFFSET) + I2NP_HEADER_SIZE;
|
||||
if (l > len)
|
||||
{
|
||||
LogPrint (eLogError, "I2NP: message length ", l, " exceeds buffer length ", len);
|
||||
LogPrint (eLogError, "I2NP: Message length ", l, " exceeds buffer length ", len);
|
||||
l = len;
|
||||
}
|
||||
return l;
|
||||
|
@ -840,18 +840,18 @@ namespace i2p
|
|||
{
|
||||
if (len < I2NP_HEADER_SIZE)
|
||||
{
|
||||
LogPrint (eLogError, "I2NP: message length ", len, " is smaller than header");
|
||||
LogPrint (eLogError, "I2NP: Message length ", len, " is smaller than header");
|
||||
return;
|
||||
}
|
||||
uint8_t typeID = msg[I2NP_HEADER_TYPEID_OFFSET];
|
||||
uint32_t msgID = bufbe32toh (msg + I2NP_HEADER_MSGID_OFFSET);
|
||||
LogPrint (eLogDebug, "I2NP: msg received len=", len,", type=", (int)typeID, ", msgID=", (unsigned int)msgID);
|
||||
LogPrint (eLogDebug, "I2NP: Message received len=", len,", type=", (int)typeID, ", msgID=", (unsigned int)msgID);
|
||||
uint8_t * buf = msg + I2NP_HEADER_SIZE;
|
||||
auto size = bufbe16toh (msg + I2NP_HEADER_SIZE_OFFSET);
|
||||
len -= I2NP_HEADER_SIZE;
|
||||
if (size > len)
|
||||
{
|
||||
LogPrint (eLogError, "I2NP: payload size ", size, " exceeds buffer length ", len);
|
||||
LogPrint (eLogError, "I2NP: Payload size ", size, " exceeds buffer length ", len);
|
||||
size = len;
|
||||
}
|
||||
switch (typeID)
|
||||
|
@ -861,13 +861,13 @@ namespace i2p
|
|||
break;
|
||||
case eI2NPShortTunnelBuild:
|
||||
HandleShortTunnelBuildMsg (msgID, buf, size);
|
||||
break;
|
||||
break;
|
||||
case eI2NPVariableTunnelBuildReply:
|
||||
HandleTunnelBuildReplyMsg (msgID, buf, size, false);
|
||||
break;
|
||||
case eI2NPShortTunnelBuildReply:
|
||||
HandleTunnelBuildReplyMsg (msgID, buf, size, true);
|
||||
break;
|
||||
break;
|
||||
case eI2NPTunnelBuild:
|
||||
HandleTunnelBuildMsg (buf, size);
|
||||
break;
|
||||
|
@ -924,8 +924,8 @@ namespace i2p
|
|||
case eI2NPVariableTunnelBuildReply:
|
||||
case eI2NPTunnelBuild:
|
||||
case eI2NPTunnelBuildReply:
|
||||
case eI2NPShortTunnelBuild:
|
||||
case eI2NPShortTunnelBuildReply:
|
||||
case eI2NPShortTunnelBuild:
|
||||
case eI2NPShortTunnelBuildReply:
|
||||
// forward to tunnel thread
|
||||
i2p::tunnel::tunnels.PostTunnelData (msg);
|
||||
break;
|
||||
|
|
|
@ -52,9 +52,9 @@ namespace data
|
|||
{
|
||||
memcpy (m_StandardIdentity.publicKey, publicKey, 32);
|
||||
RAND_bytes (m_StandardIdentity.publicKey + 32, 224);
|
||||
}
|
||||
else
|
||||
memcpy (m_StandardIdentity.publicKey, publicKey, 256);
|
||||
}
|
||||
else
|
||||
memcpy (m_StandardIdentity.publicKey, publicKey, 256);
|
||||
if (type != SIGNING_KEY_TYPE_DSA_SHA1)
|
||||
{
|
||||
size_t excessLen = 0;
|
||||
|
@ -217,7 +217,7 @@ namespace data
|
|||
{
|
||||
if (len < DEFAULT_IDENTITY_SIZE)
|
||||
{
|
||||
LogPrint (eLogError, "Identity: buffer length ", len, " is too small");
|
||||
LogPrint (eLogError, "Identity: Buffer length ", len, " is too small");
|
||||
return 0;
|
||||
}
|
||||
memcpy (&m_StandardIdentity, buf, DEFAULT_IDENTITY_SIZE);
|
||||
|
@ -488,7 +488,7 @@ namespace data
|
|||
size_t ret = m_Public->FromBuffer (buf, len);
|
||||
auto cryptoKeyLen = GetPrivateKeyLen ();
|
||||
if (!ret || ret + cryptoKeyLen > len) return 0; // overflow
|
||||
memcpy (m_PrivateKey, buf + ret, cryptoKeyLen);
|
||||
memcpy (m_PrivateKey, buf + ret, cryptoKeyLen);
|
||||
ret += cryptoKeyLen;
|
||||
size_t signingPrivateKeySize = m_Public->GetSigningPrivateKeyLen ();
|
||||
if(signingPrivateKeySize + ret > len || signingPrivateKeySize > 128) return 0; // overflow
|
||||
|
@ -662,9 +662,9 @@ namespace data
|
|||
size_t PrivateKeys::GetPrivateKeyLen () const
|
||||
{
|
||||
// private key length always 256, but type 4
|
||||
return (m_Public->GetCryptoKeyType () == CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) ? 32 : 256;
|
||||
}
|
||||
|
||||
return (m_Public->GetCryptoKeyType () == CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) ? 32 : 256;
|
||||
}
|
||||
|
||||
uint8_t * PrivateKeys::GetPadding()
|
||||
{
|
||||
if(m_Public->GetSigningKeyType () == SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519)
|
||||
|
@ -689,7 +689,7 @@ namespace data
|
|||
break;
|
||||
case CRYPTO_KEY_TYPE_ECIES_X25519_AEAD:
|
||||
return std::make_shared<i2p::crypto::ECIESX25519AEADRatchetDecryptor>(key);
|
||||
break;
|
||||
break;
|
||||
case CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC:
|
||||
case CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC_TEST:
|
||||
return std::make_shared<i2p::crypto::ECIESP256Decryptor>(key);
|
||||
|
|
|
@ -77,23 +77,23 @@ namespace data
|
|||
LogPrint (eLogError, "LeaseSet: ", size, " exceeds buffer size ", m_BufferLen);
|
||||
m_IsValid = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
uint8_t num = m_Buffer[size];
|
||||
size++; // num
|
||||
LogPrint (eLogDebug, "LeaseSet: read num=", (int)num);
|
||||
if (!num || num > MAX_NUM_LEASES)
|
||||
{
|
||||
LogPrint (eLogError, "LeaseSet: incorrect number of leases", (int)num);
|
||||
LogPrint (eLogError, "LeaseSet: Incorrect number of leases", (int)num);
|
||||
m_IsValid = false;
|
||||
return;
|
||||
}
|
||||
if (size + num*LEASE_SIZE > m_BufferLen)
|
||||
{
|
||||
if (size + num*LEASE_SIZE > m_BufferLen)
|
||||
{
|
||||
LogPrint (eLogError, "LeaseSet: ", size, " exceeds buffer size ", m_BufferLen);
|
||||
m_IsValid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
UpdateLeasesBegin ();
|
||||
// process leases
|
||||
m_ExpirationTime = 0;
|
||||
|
@ -112,7 +112,7 @@ namespace data
|
|||
}
|
||||
if (!m_ExpirationTime)
|
||||
{
|
||||
LogPrint (eLogWarning, "LeaseSet: all leases are expired. Dropped");
|
||||
LogPrint (eLogWarning, "LeaseSet: All leases have expired, dropping");
|
||||
m_IsValid = false;
|
||||
return;
|
||||
}
|
||||
|
@ -121,16 +121,16 @@ namespace data
|
|||
|
||||
// verify
|
||||
if (verifySignature)
|
||||
{
|
||||
{
|
||||
auto signedSize = leases - m_Buffer;
|
||||
if (signedSize + m_Identity->GetSignatureLen () > m_BufferLen)
|
||||
{
|
||||
LogPrint (eLogError, "LeaseSet: Signature exceeds buffer size ", m_BufferLen);
|
||||
m_IsValid = false;
|
||||
}
|
||||
}
|
||||
else if (!m_Identity->Verify (m_Buffer, signedSize, leases))
|
||||
{
|
||||
LogPrint (eLogWarning, "LeaseSet: verification failed");
|
||||
LogPrint (eLogWarning, "LeaseSet: Verification failed");
|
||||
m_IsValid = false;
|
||||
}
|
||||
}
|
||||
|
@ -274,7 +274,7 @@ namespace data
|
|||
{
|
||||
if (len <= m_BufferLen) m_BufferLen = len;
|
||||
else
|
||||
LogPrint (eLogError, "LeaseSet2: actual buffer size ", len , " exceeds full buffer size ", m_BufferLen);
|
||||
LogPrint (eLogError, "LeaseSet2: Actual buffer size ", len , " exceeds full buffer size ", m_BufferLen);
|
||||
}
|
||||
|
||||
LeaseSet2::LeaseSet2 (uint8_t storeType, const uint8_t * buf, size_t len, bool storeLeases, CryptoKeyType preferredCrypto):
|
||||
|
@ -331,7 +331,7 @@ namespace data
|
|||
m_TransientVerifier = ProcessOfflineSignature (identity, buf, len, offset);
|
||||
if (!m_TransientVerifier)
|
||||
{
|
||||
LogPrint (eLogError, "LeaseSet2: offline signature failed");
|
||||
LogPrint (eLogError, "LeaseSet2: Offline signature failed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -378,7 +378,7 @@ namespace data
|
|||
bool verified = verifier->Verify (buf - 1, signatureOffset + 1, buf + signatureOffset);
|
||||
const_cast<uint8_t *>(buf)[-1] = c;
|
||||
if (!verified)
|
||||
LogPrint (eLogWarning, "LeaseSet2: verification failed");
|
||||
LogPrint (eLogWarning, "LeaseSet2: Verification failed");
|
||||
return verified;
|
||||
}
|
||||
|
||||
|
@ -489,7 +489,7 @@ namespace data
|
|||
m_TransientVerifier = ProcessOfflineSignature (blindedVerifier, buf, len, offset);
|
||||
if (!m_TransientVerifier)
|
||||
{
|
||||
LogPrint (eLogError, "LeaseSet2: offline signature failed");
|
||||
LogPrint (eLogError, "LeaseSet2: Offline signature failed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -515,7 +515,7 @@ namespace data
|
|||
key->GetBlindedKey (date, blinded.data ());
|
||||
if (memcmp (blindedPublicKey, blinded.data (), blindedKeyLen))
|
||||
{
|
||||
LogPrint (eLogError, "LeaseSet2: blinded public key doesn't match");
|
||||
LogPrint (eLogError, "LeaseSet2: Blinded public key doesn't match");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -569,7 +569,7 @@ namespace data
|
|||
ReadFromBuffer (innerPlainText.data () + 1, lenInnerPlaintext - 1);
|
||||
}
|
||||
else
|
||||
LogPrint (eLogError, "LeaseSet2: unexpected LeaseSet type ", (int)innerPlainText[0], " inside encrypted LeaseSet");
|
||||
LogPrint (eLogError, "LeaseSet2: Unexpected LeaseSet type ", (int)innerPlainText[0], " inside encrypted LeaseSet");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -653,7 +653,7 @@ namespace data
|
|||
LogPrint (eLogError, "LeaseSet2: Can't calculate authCookie: psk_i is not provided");
|
||||
}
|
||||
else
|
||||
LogPrint (eLogError, "LeaseSet2: unknown client auth type ", (int)flag);
|
||||
LogPrint (eLogError, "LeaseSet2: Unknown client auth type ", (int)flag);
|
||||
}
|
||||
return offset - 1;
|
||||
}
|
||||
|
@ -768,7 +768,7 @@ namespace data
|
|||
size_t size = ident.GetFullLen ();
|
||||
if (size > sz)
|
||||
{
|
||||
LogPrint (eLogError, "LeaseSet: identity length ", size, " exceeds buffer size ", sz);
|
||||
LogPrint (eLogError, "LeaseSet: Identity length ", size, " exceeds buffer size ", sz);
|
||||
return false;
|
||||
}
|
||||
// encryption key
|
||||
|
@ -779,7 +779,7 @@ namespace data
|
|||
++size;
|
||||
if (!numLeases || numLeases > MAX_NUM_LEASES)
|
||||
{
|
||||
LogPrint (eLogError, "LeaseSet: incorrect number of leases", (int)numLeases);
|
||||
LogPrint (eLogError, "LeaseSet: Incorrect number of leases", (int)numLeases);
|
||||
return false;
|
||||
}
|
||||
const uint8_t * leases = ptr + size;
|
||||
|
@ -863,17 +863,17 @@ namespace data
|
|||
}
|
||||
// update expiration
|
||||
if (expirationTime)
|
||||
{
|
||||
{
|
||||
SetExpirationTime (expirationTime*1000LL);
|
||||
auto expires = (int)expirationTime - timestamp;
|
||||
htobe16buf (expiresBuf, expires > 0 ? expires : 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// no tunnels or withdraw
|
||||
SetExpirationTime (timestamp*1000LL);
|
||||
memset (expiresBuf, 0, 2); // expires immeditely
|
||||
}
|
||||
}
|
||||
// sign
|
||||
keys.Sign (m_Buffer, offset, m_Buffer + offset); // LS + leading store type
|
||||
}
|
||||
|
@ -979,7 +979,7 @@ namespace data
|
|||
m_StoreHash = blindedKey->GetStoreHash ();
|
||||
}
|
||||
else
|
||||
LogPrint (eLogError, "LeaseSet2: couldn't extract inner layer");
|
||||
LogPrint (eLogError, "LeaseSet2: Couldn't extract inner layer");
|
||||
}
|
||||
|
||||
void LocalEncryptedLeaseSet2::CreateClientAuthData (const uint8_t * subcredential, int authType, std::shared_ptr<std::vector<AuthPublicKey> > authKeys, const uint8_t * authCookie, uint8_t * authData) const
|
||||
|
|
|
@ -129,10 +129,10 @@ namespace log {
|
|||
else if (level == "info") { m_MinLevel = eLogInfo; }
|
||||
else if (level == "debug") { m_MinLevel = eLogDebug; }
|
||||
else {
|
||||
LogPrint(eLogError, "Log: unknown loglevel: ", level);
|
||||
LogPrint(eLogError, "Log: Unknown loglevel: ", level);
|
||||
return;
|
||||
}
|
||||
LogPrint(eLogInfo, "Log: min messages level set to ", level);
|
||||
LogPrint(eLogInfo, "Log: Logging level set to ", level);
|
||||
}
|
||||
|
||||
const char * Log::TimeAsString(std::time_t t) {
|
||||
|
@ -212,7 +212,7 @@ namespace log {
|
|||
m_LogStream = os;
|
||||
return;
|
||||
}
|
||||
LogPrint(eLogError, "Log: can't open file ", path);
|
||||
LogPrint(eLogError, "Log: Can't open file ", path);
|
||||
}
|
||||
|
||||
void Log::SendTo (std::shared_ptr<std::ostream> os) {
|
||||
|
|
|
@ -71,7 +71,7 @@ namespace data
|
|||
m_RouterInfos.emplace (i2p::context.GetIdentHash (), i2p::context.GetSharedRouterInfo ());
|
||||
if (i2p::context.IsFloodfill ())
|
||||
m_Floodfills.push_back (i2p::context.GetSharedRouterInfo ());
|
||||
|
||||
|
||||
i2p::config::GetOption("persist.profiles", m_PersistProfiles);
|
||||
|
||||
m_IsRunning = true;
|
||||
|
@ -146,7 +146,7 @@ namespace data
|
|||
}
|
||||
if (!m_IsRunning) break;
|
||||
if (!i2p::transport::transports.IsOnline ()) continue; // don't manage netdb when offline
|
||||
|
||||
|
||||
uint64_t ts = i2p::util::GetSecondsSinceEpoch ();
|
||||
if (ts - lastManageRequest >= 15) // manage requests every 15 seconds
|
||||
{
|
||||
|
@ -168,8 +168,8 @@ namespace data
|
|||
lastDestinationCleanup = ts;
|
||||
}
|
||||
|
||||
// publish
|
||||
if (!m_HiddenMode && i2p::transport::transports.IsOnline ())
|
||||
// publish
|
||||
if (!m_HiddenMode && i2p::transport::transports.IsOnline ())
|
||||
{
|
||||
bool publish = false;
|
||||
if (m_PublishReplyToken)
|
||||
|
@ -177,15 +177,15 @@ namespace data
|
|||
// next publishing attempt
|
||||
if (ts - lastPublish >= NETDB_PUBLISH_CONFIRMATION_TIMEOUT) publish = true;
|
||||
}
|
||||
else if (i2p::context.GetLastUpdateTime () > lastPublish ||
|
||||
ts - lastPublish >= NETDB_PUBLISH_INTERVAL)
|
||||
{
|
||||
else if (i2p::context.GetLastUpdateTime () > lastPublish ||
|
||||
ts - lastPublish >= NETDB_PUBLISH_INTERVAL)
|
||||
{
|
||||
// new publish
|
||||
m_PublishExcluded.clear ();
|
||||
if (i2p::context.IsFloodfill ())
|
||||
m_PublishExcluded.insert (i2p::context.GetIdentHash ()); // do publish to ourselves
|
||||
publish = true;
|
||||
}
|
||||
}
|
||||
if (publish) // update timestamp and publish
|
||||
{
|
||||
i2p::context.UpdateTimestamp (ts);
|
||||
|
@ -288,7 +288,7 @@ namespace data
|
|||
if (inserted)
|
||||
{
|
||||
LogPrint (eLogInfo, "NetDb: RouterInfo added: ", ident.ToBase64());
|
||||
if (r->IsFloodfill () && r->IsEligibleFloodfill ())
|
||||
if (r->IsFloodfill () && r->IsEligibleFloodfill ())
|
||||
{
|
||||
std::unique_lock<std::mutex> l(m_FloodfillsMutex);
|
||||
m_Floodfills.push_back (r);
|
||||
|
@ -341,7 +341,7 @@ namespace data
|
|||
updated = true;
|
||||
}
|
||||
else
|
||||
LogPrint (eLogError, "NetDb: new LeaseSet validation failed: ", ident.ToBase32());
|
||||
LogPrint (eLogError, "NetDb: New LeaseSet validation failed: ", ident.ToBase32());
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
|
@ -371,7 +371,7 @@ namespace data
|
|||
}
|
||||
}
|
||||
else
|
||||
LogPrint (eLogError, "NetDb: new LeaseSet2 validation failed: ", ident.ToBase32());
|
||||
LogPrint (eLogError, "NetDb: New LeaseSet2 validation failed: ", ident.ToBase32());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -428,7 +428,7 @@ namespace data
|
|||
int riLen = ri->GetBufferLen();
|
||||
if(!i2p::data::netdb.AddRouterInfo(riData, riLen)) {
|
||||
// bad router info
|
||||
LogPrint(eLogError, "NetDb: bad router info");
|
||||
LogPrint(eLogError, "NetDb: Bad RouterInfo");
|
||||
return;
|
||||
}
|
||||
m_FloodfillBootstrap = ri;
|
||||
|
@ -443,7 +443,7 @@ namespace data
|
|||
|
||||
void NetDb::ReseedFromFloodfill(const RouterInfo & ri, int numRouters, int numFloodfills)
|
||||
{
|
||||
LogPrint(eLogInfo, "NetDB: reseeding from floodfill ", ri.GetIdentHashBase64());
|
||||
LogPrint(eLogInfo, "NetDB: Reseeding from floodfill ", ri.GetIdentHashBase64());
|
||||
std::vector<std::shared_ptr<i2p::I2NPMessage> > requests;
|
||||
|
||||
i2p::data::IdentHash ourIdent = i2p::context.GetIdentHash();
|
||||
|
@ -474,14 +474,14 @@ namespace data
|
|||
{
|
||||
auto r = std::make_shared<RouterInfo>(path);
|
||||
if (r->GetRouterIdentity () && !r->IsUnreachable () && r->HasValidAddresses ())
|
||||
{
|
||||
{
|
||||
r->DeleteBuffer ();
|
||||
r->ClearProperties (); // properties are not used for regular routers
|
||||
if (m_RouterInfos.emplace (r->GetIdentHash (), r).second)
|
||||
{
|
||||
{
|
||||
if (r->IsFloodfill () && r->IsEligibleFloodfill ())
|
||||
m_Floodfills.push_back (r);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -588,7 +588,7 @@ namespace data
|
|||
expirationTimeout = i2p::context.IsFloodfill () ? NETDB_FLOODFILL_EXPIRATION_TIMEOUT*1000LL :
|
||||
NETDB_MIN_EXPIRATION_TIMEOUT*1000LL + (NETDB_MAX_EXPIRATION_TIMEOUT - NETDB_MIN_EXPIRATION_TIMEOUT)*1000LL*NETDB_MIN_ROUTERS/total;
|
||||
|
||||
auto own = i2p::context.GetSharedRouterInfo ();
|
||||
auto own = i2p::context.GetSharedRouterInfo ();
|
||||
for (auto& it: m_RouterInfos)
|
||||
{
|
||||
if (it.second == own) continue; // skip own
|
||||
|
@ -604,8 +604,8 @@ namespace data
|
|||
continue;
|
||||
}
|
||||
// make router reachable back if too few routers
|
||||
if (it.second->IsUnreachable () && total - deletedCount < NETDB_MIN_ROUTERS)
|
||||
it.second->SetUnreachable (false);
|
||||
if (it.second->IsUnreachable () && total - deletedCount < NETDB_MIN_ROUTERS)
|
||||
it.second->SetUnreachable (false);
|
||||
// find & mark expired routers
|
||||
if (!it.second->IsReachable () && it.second->IsSSU (false))
|
||||
{
|
||||
|
@ -621,15 +621,15 @@ namespace data
|
|||
// delete RI file
|
||||
m_Storage.Remove(ident);
|
||||
deletedCount++;
|
||||
if (total - deletedCount < NETDB_MIN_ROUTERS) checkForExpiration = false;
|
||||
if (total - deletedCount < NETDB_MIN_ROUTERS) checkForExpiration = false;
|
||||
}
|
||||
} // m_RouterInfos iteration
|
||||
|
||||
if (updatedCount > 0)
|
||||
LogPrint (eLogInfo, "NetDb: saved ", updatedCount, " new/updated routers");
|
||||
LogPrint (eLogInfo, "NetDb: Saved ", updatedCount, " new/updated routers");
|
||||
if (deletedCount > 0)
|
||||
{
|
||||
LogPrint (eLogInfo, "NetDb: deleting ", deletedCount, " unreachable routers");
|
||||
LogPrint (eLogInfo, "NetDb: Deleting ", deletedCount, " unreachable routers");
|
||||
// clean up RouterInfos table
|
||||
{
|
||||
std::unique_lock<std::mutex> l(m_RouterInfosMutex);
|
||||
|
@ -661,7 +661,7 @@ namespace data
|
|||
auto dest = m_Requests.CreateRequest (destination, false, requestComplete); // non-exploratory
|
||||
if (!dest)
|
||||
{
|
||||
LogPrint (eLogWarning, "NetDb: destination ", destination.ToBase64(), " is requested already");
|
||||
LogPrint (eLogWarning, "NetDb: Destination ", destination.ToBase64(), " has already been requested");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -669,7 +669,7 @@ namespace data
|
|||
if (floodfill)
|
||||
{
|
||||
if (direct && !floodfill->IsReachableFrom (i2p::context.GetRouterInfo ()) &&
|
||||
!i2p::transport::transports.IsConnected (floodfill->GetIdentHash ()))
|
||||
!i2p::transport::transports.IsConnected (floodfill->GetIdentHash ()))
|
||||
direct = false; // floodfill can't be reached directly
|
||||
if (direct)
|
||||
transports.SendMessage (floodfill->GetIdentHash (), dest->CreateRequestMessage (floodfill->GetIdentHash ()));
|
||||
|
@ -683,10 +683,10 @@ namespace data
|
|||
else
|
||||
{
|
||||
LogPrint (eLogError, "NetDb: ", destination.ToBase64(), " destination requested, but no tunnels found");
|
||||
m_Requests.RequestComplete (destination, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
m_Requests.RequestComplete (destination, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogPrint (eLogError, "NetDb: ", destination.ToBase64(), " destination requested, but no floodfills found");
|
||||
|
@ -727,7 +727,7 @@ namespace data
|
|||
IdentHash ident (buf + DATABASE_STORE_KEY_OFFSET);
|
||||
if (ident.IsZero ())
|
||||
{
|
||||
LogPrint (eLogDebug, "NetDb: database store with zero ident, dropped");
|
||||
LogPrint (eLogDebug, "NetDb: Database store with zero ident, dropped");
|
||||
return;
|
||||
}
|
||||
uint32_t replyToken = bufbe32toh (buf + DATABASE_STORE_REPLY_TOKEN_OFFSET);
|
||||
|
@ -746,14 +746,14 @@ namespace data
|
|||
if (outbound)
|
||||
outbound->SendTunnelDataMsg (buf + offset, tunnelID, deliveryStatus);
|
||||
else
|
||||
LogPrint (eLogWarning, "NetDb: no outbound tunnels for DatabaseStore reply found");
|
||||
LogPrint (eLogWarning, "NetDb: No outbound tunnels for DatabaseStore reply found");
|
||||
}
|
||||
offset += 32;
|
||||
}
|
||||
// we must send reply back before this check
|
||||
if (ident == i2p::context.GetIdentHash ())
|
||||
{
|
||||
LogPrint (eLogDebug, "NetDb: database store with own RouterInfo received, dropped");
|
||||
LogPrint (eLogDebug, "NetDb: Database store with own RouterInfo received, dropped");
|
||||
return;
|
||||
}
|
||||
size_t payloadOffset = offset;
|
||||
|
@ -766,24 +766,24 @@ namespace data
|
|||
{
|
||||
if (storeType == NETDB_STORE_TYPE_LEASESET) // 1
|
||||
{
|
||||
LogPrint (eLogDebug, "NetDb: store request: LeaseSet for ", ident.ToBase32());
|
||||
LogPrint (eLogDebug, "NetDb: Store request: LeaseSet for ", ident.ToBase32());
|
||||
updated = AddLeaseSet (ident, buf + offset, len - offset);
|
||||
}
|
||||
else // all others are considered as LeaseSet2
|
||||
{
|
||||
LogPrint (eLogDebug, "NetDb: store request: LeaseSet2 of type ", storeType, " for ", ident.ToBase32());
|
||||
LogPrint (eLogDebug, "NetDb: Store request: LeaseSet2 of type ", storeType, " for ", ident.ToBase32());
|
||||
updated = AddLeaseSet2 (ident, buf + offset, len - offset, storeType);
|
||||
}
|
||||
}
|
||||
}
|
||||
else // RouterInfo
|
||||
{
|
||||
LogPrint (eLogDebug, "NetDb: store request: RouterInfo");
|
||||
LogPrint (eLogDebug, "NetDb: Store request: RouterInfo");
|
||||
size_t size = bufbe16toh (buf + offset);
|
||||
offset += 2;
|
||||
if (size > MAX_RI_BUFFER_SIZE || size > len - offset)
|
||||
{
|
||||
LogPrint (eLogError, "NetDb: invalid RouterInfo length ", (int)size);
|
||||
LogPrint (eLogError, "NetDb: Invalid RouterInfo length ", (int)size);
|
||||
return;
|
||||
}
|
||||
uint8_t uncompressed[MAX_RI_BUFFER_SIZE];
|
||||
|
@ -792,7 +792,7 @@ namespace data
|
|||
updated = AddRouterInfo (ident, uncompressed, uncompressedSize);
|
||||
else
|
||||
{
|
||||
LogPrint (eLogInfo, "NetDb: decompression failed ", uncompressedSize);
|
||||
LogPrint (eLogInfo, "NetDb: Decompression failed ", uncompressedSize);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -867,7 +867,7 @@ namespace data
|
|||
m_Requests.RequestComplete (ident, nullptr);
|
||||
}
|
||||
else if(!m_FloodfillBootstrap)
|
||||
LogPrint (eLogWarning, "NetDb: requested destination for ", key, " not found");
|
||||
LogPrint (eLogWarning, "NetDb: Requested destination for ", key, " not found");
|
||||
|
||||
// try responses
|
||||
for (int i = 0; i < num; i++)
|
||||
|
@ -882,7 +882,7 @@ namespace data
|
|||
if (!r || i2p::util::GetMillisecondsSinceEpoch () > r->GetTimestamp () + 3600*1000LL)
|
||||
{
|
||||
// router with ident not found or too old (1 hour)
|
||||
LogPrint (eLogDebug, "NetDb: found new/outdated router. Requesting RouterInfo ...");
|
||||
LogPrint (eLogDebug, "NetDb: Found new/outdated router. Requesting RouterInfo ...");
|
||||
if(m_FloodfillBootstrap)
|
||||
RequestDestinationFrom(router, m_FloodfillBootstrap->GetIdentHash(), true);
|
||||
else
|
||||
|
@ -923,14 +923,14 @@ namespace data
|
|||
excluded += 2;
|
||||
if (numExcluded > 512)
|
||||
{
|
||||
LogPrint (eLogWarning, "NetDb: number of excluded peers", numExcluded, " exceeds 512");
|
||||
LogPrint (eLogWarning, "NetDb: Number of excluded peers", numExcluded, " exceeds 512");
|
||||
return;
|
||||
}
|
||||
|
||||
std::shared_ptr<I2NPMessage> replyMsg;
|
||||
if (lookupType == DATABASE_LOOKUP_TYPE_EXPLORATORY_LOOKUP)
|
||||
{
|
||||
LogPrint (eLogInfo, "NetDb: exploratory close to ", key, " ", numExcluded, " excluded");
|
||||
LogPrint (eLogInfo, "NetDb: Exploratory close to ", key, " ", numExcluded, " excluded");
|
||||
std::set<IdentHash> excludedRouters;
|
||||
for (int i = 0; i < numExcluded; i++)
|
||||
{
|
||||
|
@ -957,7 +957,7 @@ namespace data
|
|||
auto router = FindRouter (ident);
|
||||
if (router)
|
||||
{
|
||||
LogPrint (eLogDebug, "NetDb: requested RouterInfo ", key, " found");
|
||||
LogPrint (eLogDebug, "NetDb: Requested RouterInfo ", key, " found");
|
||||
router->LoadBuffer ();
|
||||
if (router->GetBuffer ())
|
||||
replyMsg = CreateDatabaseStoreMsg (router);
|
||||
|
@ -971,11 +971,11 @@ namespace data
|
|||
if (!leaseSet)
|
||||
{
|
||||
// no lease set found
|
||||
LogPrint(eLogDebug, "NetDb: requested LeaseSet not found for ", ident.ToBase32());
|
||||
LogPrint(eLogDebug, "NetDb: Requested LeaseSet not found for ", ident.ToBase32());
|
||||
}
|
||||
else if (!leaseSet->IsExpired ()) // we don't send back our LeaseSets
|
||||
{
|
||||
LogPrint (eLogDebug, "NetDb: requested LeaseSet ", key, " found");
|
||||
LogPrint (eLogDebug, "NetDb: Requested LeaseSet ", key, " found");
|
||||
replyMsg = CreateDatabaseStoreMsg (ident, leaseSet);
|
||||
}
|
||||
}
|
||||
|
@ -1045,8 +1045,8 @@ namespace data
|
|||
m_PublishExcluded.clear ();
|
||||
m_PublishReplyToken = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void NetDb::Explore (int numDestinations)
|
||||
{
|
||||
// new requests
|
||||
|
@ -1057,14 +1057,14 @@ namespace data
|
|||
|
||||
uint8_t randomHash[32];
|
||||
std::vector<i2p::tunnel::TunnelMessageBlock> msgs;
|
||||
LogPrint (eLogInfo, "NetDb: exploring new ", numDestinations, " routers ...");
|
||||
LogPrint (eLogInfo, "NetDb: Exploring new ", numDestinations, " routers ...");
|
||||
for (int i = 0; i < numDestinations; i++)
|
||||
{
|
||||
RAND_bytes (randomHash, 32);
|
||||
auto dest = m_Requests.CreateRequest (randomHash, true); // exploratory
|
||||
if (!dest)
|
||||
{
|
||||
LogPrint (eLogWarning, "NetDb: exploratory destination is requested already");
|
||||
LogPrint (eLogWarning, "NetDb: Exploratory destination is requested already");
|
||||
return;
|
||||
}
|
||||
auto floodfill = GetClosestFloodfill (randomHash, dest->GetExcludedPeers ());
|
||||
|
@ -1106,7 +1106,7 @@ namespace data
|
|||
LogPrint (eLogError, "NetDb: Couldn't publish our RouterInfo to ", NETDB_MAX_PUBLISH_EXCLUDED_FLOODFILLS, " closest routers. Try again");
|
||||
m_PublishExcluded.clear ();
|
||||
}
|
||||
|
||||
|
||||
auto floodfill = GetClosestFloodfill (i2p::context.GetIdentHash (), m_PublishExcluded);
|
||||
if (floodfill)
|
||||
{
|
||||
|
@ -1116,19 +1116,19 @@ namespace data
|
|||
m_PublishExcluded.insert (floodfill->GetIdentHash ());
|
||||
m_PublishReplyToken = replyToken;
|
||||
if (floodfill->IsReachableFrom (i2p::context.GetRouterInfo ()) || // are we able to connect?
|
||||
i2p::transport::transports.IsConnected (floodfill->GetIdentHash ())) // already connected ?
|
||||
i2p::transport::transports.IsConnected (floodfill->GetIdentHash ())) // already connected ?
|
||||
// send directly
|
||||
transports.SendMessage (floodfill->GetIdentHash (), CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken));
|
||||
else
|
||||
{
|
||||
// otherwise through exploratory
|
||||
// otherwise through exploratory
|
||||
auto exploratoryPool = i2p::tunnel::tunnels.GetExploratoryPool ();
|
||||
auto outbound = exploratoryPool ? exploratoryPool->GetNextOutboundTunnel () : nullptr;
|
||||
auto inbound = exploratoryPool ? exploratoryPool->GetNextInboundTunnel () : nullptr;
|
||||
auto inbound = exploratoryPool ? exploratoryPool->GetNextInboundTunnel () : nullptr;
|
||||
if (inbound && outbound)
|
||||
outbound->SendTunnelDataMsg (floodfill->GetIdentHash (), 0,
|
||||
CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken, inbound));
|
||||
}
|
||||
outbound->SendTunnelDataMsg (floodfill->GetIdentHash (), 0,
|
||||
CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken, inbound));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1210,11 +1210,11 @@ namespace data
|
|||
(reverse ? compatibleWith->IsReachableFrom (*router) :
|
||||
router->IsReachableFrom (*compatibleWith)) &&
|
||||
(router->GetCaps () & RouterInfo::eHighBandwidth) &&
|
||||
#if defined(__x86_64__)
|
||||
#if defined(__x86_64__)
|
||||
router->GetVersion () >= NETDB_MIN_HIGHBANDWIDTH_VERSION;
|
||||
#else
|
||||
router->GetIdentity ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD;
|
||||
#endif
|
||||
#endif
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1234,12 +1234,12 @@ namespace data
|
|||
return it->second;
|
||||
// try some routers around
|
||||
auto it1 = m_RouterInfos.begin ();
|
||||
if (inds[0])
|
||||
if (inds[0])
|
||||
{
|
||||
// before
|
||||
inds[1] %= inds[0];
|
||||
inds[1] %= inds[0];
|
||||
std::advance (it1, (inds[1] + inds[0])/2);
|
||||
}
|
||||
}
|
||||
else
|
||||
it1 = it;
|
||||
auto it2 = it;
|
||||
|
@ -1250,7 +1250,7 @@ namespace data
|
|||
std::advance (it2, inds[2]);
|
||||
}
|
||||
// it1 - from, it2 - to
|
||||
it = it1;
|
||||
it = it1;
|
||||
while (it != it2 && it != m_RouterInfos.end ())
|
||||
{
|
||||
if (!it->second->IsUnreachable () && filter (it->second))
|
||||
|
|
|
@ -73,7 +73,7 @@ namespace data
|
|||
|
||||
if (!i2p::fs::Exists(path))
|
||||
{
|
||||
LogPrint(eLogWarning, "Profiling: no profile yet for ", ident);
|
||||
LogPrint(eLogWarning, "Profiling: No profile yet for ", ident);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -194,7 +194,7 @@ namespace data
|
|||
continue;
|
||||
}
|
||||
if (((now - st.st_mtime) / 3600) >= PEER_PROFILE_EXPIRATION_TIMEOUT) {
|
||||
LogPrint(eLogDebug, "Profiling: removing expired peer profile: ", path);
|
||||
LogPrint(eLogDebug, "Profiling: Removing expired peer profile: ", path);
|
||||
i2p::fs::Remove(path);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,19 +60,19 @@ namespace data
|
|||
num = ProcessSU3File (su3FileName.c_str ());
|
||||
}
|
||||
if (num == 0)
|
||||
LogPrint (eLogWarning, "Reseed: failed to reseed from ", su3FileName);
|
||||
LogPrint (eLogWarning, "Reseed: Failed to reseed from ", su3FileName);
|
||||
}
|
||||
else if (zipFileName.length() > 0) // bootstrap from ZIP file
|
||||
{
|
||||
int num = ProcessZIPFile (zipFileName.c_str ());
|
||||
if (num == 0)
|
||||
LogPrint (eLogWarning, "Reseed: failed to reseed from ", zipFileName);
|
||||
LogPrint (eLogWarning, "Reseed: Failed to reseed from ", zipFileName);
|
||||
}
|
||||
else // bootstrap from reseed servers
|
||||
{
|
||||
int num = ReseedFromServers ();
|
||||
if (num == 0)
|
||||
LogPrint (eLogWarning, "Reseed: failed to reseed from servers");
|
||||
LogPrint (eLogWarning, "Reseed: Failed to reseed from servers");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,15 +84,15 @@ namespace data
|
|||
{
|
||||
bool ipv6; i2p::config::GetOption("ipv6", ipv6);
|
||||
bool ipv4; i2p::config::GetOption("ipv4", ipv4);
|
||||
|
||||
|
||||
std::vector<std::string> httpsReseedHostList;
|
||||
if (ipv4 || ipv6)
|
||||
{
|
||||
{
|
||||
std::string reseedURLs; i2p::config::GetOption("reseed.urls", reseedURLs);
|
||||
if (!reseedURLs.empty ())
|
||||
boost::split(httpsReseedHostList, reseedURLs, boost::is_any_of(","), boost::token_compress_on);
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::string> yggReseedHostList;
|
||||
if (!i2p::util::net::GetYggdrasilAddress ().is_unspecified ())
|
||||
{
|
||||
|
@ -100,7 +100,7 @@ namespace data
|
|||
std::string yggReseedURLs; i2p::config::GetOption("reseed.yggurls", yggReseedURLs);
|
||||
if (!yggReseedURLs.empty ())
|
||||
boost::split(yggReseedHostList, yggReseedURLs, boost::is_any_of(","), boost::token_compress_on);
|
||||
}
|
||||
}
|
||||
|
||||
if (httpsReseedHostList.empty () && yggReseedHostList.empty())
|
||||
{
|
||||
|
@ -113,14 +113,14 @@ namespace data
|
|||
{
|
||||
auto ind = rand () % (httpsReseedHostList.size () + yggReseedHostList.size ());
|
||||
bool isHttps = ind < httpsReseedHostList.size ();
|
||||
std::string reseedUrl = isHttps ? httpsReseedHostList[ind] :
|
||||
std::string reseedUrl = isHttps ? httpsReseedHostList[ind] :
|
||||
yggReseedHostList[ind - httpsReseedHostList.size ()];
|
||||
reseedUrl += "i2pseeds.su3";
|
||||
auto num = ReseedFromSU3Url (reseedUrl, isHttps);
|
||||
if (num > 0) return num; // success
|
||||
reseedRetries++;
|
||||
}
|
||||
LogPrint (eLogWarning, "Reseed: failed to reseed from servers after 10 attempts");
|
||||
LogPrint (eLogWarning, "Reseed: Failed to reseed from servers after 10 attempts");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -509,7 +509,7 @@ namespace data
|
|||
|
||||
for (const std::string & file : files) {
|
||||
if (file.compare(file.size() - 4, 4, ".crt") != 0) {
|
||||
LogPrint(eLogWarning, "Reseed: ignoring file ", file);
|
||||
LogPrint(eLogWarning, "Reseed: Ignoring file ", file);
|
||||
continue;
|
||||
}
|
||||
LoadCertificate (file);
|
||||
|
@ -533,17 +533,17 @@ namespace data
|
|||
}
|
||||
// check for valid proxy url schema
|
||||
if (proxyUrl.schema != "http" && proxyUrl.schema != "socks") {
|
||||
LogPrint(eLogError, "Reseed: bad proxy url: ", proxy);
|
||||
LogPrint(eLogError, "Reseed: Bad proxy URL: ", proxy);
|
||||
return "";
|
||||
}
|
||||
} else {
|
||||
LogPrint(eLogError, "Reseed: bad proxy url: ", proxy);
|
||||
LogPrint(eLogError, "Reseed: Bad proxy URL: ", proxy);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
i2p::http::URL url;
|
||||
if (!url.parse(address)) {
|
||||
LogPrint(eLogError, "Reseed: failed to parse url: ", address);
|
||||
LogPrint(eLogError, "Reseed: Failed to parse URL: ", address);
|
||||
return "";
|
||||
}
|
||||
url.schema = "https";
|
||||
|
@ -680,30 +680,30 @@ namespace data
|
|||
auto it = boost::asio::ip::tcp::resolver(service).resolve (
|
||||
boost::asio::ip::tcp::resolver::query (url.host, std::to_string(url.port)), ecode);
|
||||
if (!ecode)
|
||||
{
|
||||
{
|
||||
bool connected = false;
|
||||
boost::asio::ip::tcp::resolver::iterator end;
|
||||
while (it != end)
|
||||
{
|
||||
{
|
||||
boost::asio::ip::tcp::endpoint ep = *it;
|
||||
if ((ep.address ().is_v4 () && i2p::context.SupportsV4 ()) ||
|
||||
(ep.address ().is_v6 () && i2p::context.SupportsV6 ()))
|
||||
{
|
||||
{
|
||||
s.lowest_layer().connect (ep, ecode);
|
||||
if (!ecode)
|
||||
{
|
||||
connected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
it++;
|
||||
}
|
||||
if (!connected)
|
||||
{
|
||||
LogPrint(eLogError, "Reseed: Failed to connect to ", url.host);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!ecode)
|
||||
{
|
||||
|
@ -743,40 +743,40 @@ namespace data
|
|||
i2p::http::HTTPRes res;
|
||||
int len = res.parse(data);
|
||||
if (len <= 0) {
|
||||
LogPrint(eLogWarning, "Reseed: incomplete/broken response from ", uri);
|
||||
LogPrint(eLogWarning, "Reseed: Incomplete/broken response from ", uri);
|
||||
return "";
|
||||
}
|
||||
if (res.code != 200) {
|
||||
LogPrint(eLogError, "Reseed: failed to reseed from ", uri, ", http code ", res.code);
|
||||
LogPrint(eLogError, "Reseed: Failed to reseed from ", uri, ", http code ", res.code);
|
||||
return "";
|
||||
}
|
||||
data.erase(0, len); /* drop http headers from response */
|
||||
LogPrint(eLogDebug, "Reseed: got ", data.length(), " bytes of data from ", uri);
|
||||
LogPrint(eLogDebug, "Reseed: Got ", data.length(), " bytes of data from ", uri);
|
||||
if (res.is_chunked()) {
|
||||
std::stringstream in(data), out;
|
||||
if (!i2p::http::MergeChunkedResponse(in, out)) {
|
||||
LogPrint(eLogWarning, "Reseed: failed to merge chunked response from ", uri);
|
||||
LogPrint(eLogWarning, "Reseed: Failed to merge chunked response from ", uri);
|
||||
return "";
|
||||
}
|
||||
LogPrint(eLogDebug, "Reseed: got ", data.length(), "(", out.tellg(), ") bytes of data from ", uri);
|
||||
LogPrint(eLogDebug, "Reseed: Got ", data.length(), "(", out.tellg(), ") bytes of data from ", uri);
|
||||
data = out.str();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
std::string Reseeder::YggdrasilRequest (const std::string& address)
|
||||
{
|
||||
i2p::http::URL url;
|
||||
if (!url.parse(address))
|
||||
if (!url.parse(address))
|
||||
{
|
||||
LogPrint(eLogError, "Reseed: failed to parse url: ", address);
|
||||
LogPrint(eLogError, "Reseed: Failed to parse URL: ", address);
|
||||
return "";
|
||||
}
|
||||
url.schema = "http";
|
||||
if (!url.port) url.port = 80;
|
||||
|
||||
boost::system::error_code ecode;
|
||||
boost::asio::io_service service;
|
||||
boost::asio::io_service service;
|
||||
boost::asio::ip::tcp::socket s(service, boost::asio::ip::tcp::v6());
|
||||
|
||||
if (url.host.length () < 2) return ""; // assume []
|
||||
|
@ -789,9 +789,9 @@ namespace data
|
|||
return ReseedRequest (s, url.to_string());
|
||||
}
|
||||
else
|
||||
LogPrint (eLogError, "Reseed: Couldn't connect to yggdrasil ", url.host, ": ", ecode.message ());
|
||||
|
||||
LogPrint (eLogError, "Reseed: Couldn't connect to yggdrasil ", url.host, ": ", ecode.message ());
|
||||
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -205,10 +205,10 @@ namespace data
|
|||
char transportStyle[6];
|
||||
ReadString (transportStyle, 6, s);
|
||||
if (!strncmp (transportStyle, "NTCP", 4)) // NTCP or NTCP2
|
||||
{
|
||||
{
|
||||
address->transportStyle = eTransportNTCP;
|
||||
address->ntcp2.reset (new NTCP2Ext ());
|
||||
}
|
||||
}
|
||||
else if (!strcmp (transportStyle, "SSU"))
|
||||
{
|
||||
address->transportStyle = eTransportSSU;
|
||||
|
@ -302,39 +302,39 @@ namespace data
|
|||
if (address->transportStyle == eTransportNTCP)
|
||||
{
|
||||
if (isStaticKey)
|
||||
{
|
||||
{
|
||||
if (isHost)
|
||||
{
|
||||
if (address->host.is_v6 ())
|
||||
supportedTransports |= (i2p::util::net::IsYggdrasilAddress (address->host) ? eNTCP2V6Mesh : eNTCP2V6);
|
||||
else
|
||||
supportedTransports |= eNTCP2V4;
|
||||
supportedTransports |= eNTCP2V4;
|
||||
m_ReachableTransports |= supportedTransports;
|
||||
}
|
||||
}
|
||||
else if (!address->published)
|
||||
{
|
||||
if (address->caps)
|
||||
{
|
||||
{
|
||||
if (address->caps & AddressCaps::eV4) supportedTransports |= eNTCP2V4;
|
||||
if (address->caps & AddressCaps::eV6) supportedTransports |= eNTCP2V6;
|
||||
}
|
||||
else
|
||||
supportedTransports |= eNTCP2V4; // most likely, since we don't have host
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (address->transportStyle == eTransportSSU)
|
||||
{
|
||||
if (isIntroKey)
|
||||
{
|
||||
if (isHost)
|
||||
supportedTransports |= address->host.is_v4 () ? eSSUV4 : eSSUV6;
|
||||
else if (address->caps & AddressCaps::eV6)
|
||||
{
|
||||
else if (address->caps & AddressCaps::eV6)
|
||||
{
|
||||
supportedTransports |= eSSUV6;
|
||||
if (address->caps & AddressCaps::eV4) supportedTransports |= eSSUV4; // in additional to v6
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
supportedTransports |= eSSUV4; // in case if host or 6 caps is not preasented, we assume 4
|
||||
if (address->ssu && !address->ssu->introducers.empty ())
|
||||
{
|
||||
|
@ -344,24 +344,24 @@ namespace data
|
|||
for (auto& it: address->ssu->introducers)
|
||||
{
|
||||
if (!it.iExp) it.iExp = m_Timestamp/1000 + NETDB_INTRODUCEE_EXPIRATION_TIMEOUT;
|
||||
if (ts <= it.iExp && it.iPort > 0 &&
|
||||
((it.iHost.is_v4 () && address->IsV4 ()) || (it.iHost.is_v6 () && address->IsV6 ())))
|
||||
if (ts <= it.iExp && it.iPort > 0 &&
|
||||
((it.iHost.is_v4 () && address->IsV4 ()) || (it.iHost.is_v6 () && address->IsV6 ())))
|
||||
numValid++;
|
||||
else
|
||||
it.iPort = 0;
|
||||
}
|
||||
}
|
||||
if (numValid)
|
||||
m_ReachableTransports |= supportedTransports;
|
||||
else
|
||||
else
|
||||
address->ssu->introducers.resize (0);
|
||||
}
|
||||
}
|
||||
else if (isHost && address->port)
|
||||
{
|
||||
{
|
||||
address->published = true;
|
||||
m_ReachableTransports |= supportedTransports;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (supportedTransports)
|
||||
{
|
||||
addresses->push_back(address);
|
||||
|
@ -486,10 +486,10 @@ namespace data
|
|||
{
|
||||
case CAPS_FLAG_V4:
|
||||
caps |= AddressCaps::eV4;
|
||||
break;
|
||||
break;
|
||||
case CAPS_FLAG_V6:
|
||||
caps |= AddressCaps::eV6;
|
||||
break;
|
||||
break;
|
||||
case CAPS_FLAG_SSU_TESTING:
|
||||
caps |= AddressCaps::eSSUTesting;
|
||||
break;
|
||||
|
@ -502,7 +502,7 @@ namespace data
|
|||
}
|
||||
return caps;
|
||||
}
|
||||
|
||||
|
||||
void RouterInfo::UpdateCapsProperty ()
|
||||
{
|
||||
std::string caps;
|
||||
|
@ -553,7 +553,7 @@ namespace data
|
|||
if (address.transportStyle == eTransportNTCP)
|
||||
{
|
||||
if (address.IsNTCP2 ())
|
||||
{
|
||||
{
|
||||
WriteString ("NTCP2", s);
|
||||
if (address.IsPublishedNTCP2 () && !address.host.is_unspecified () && address.port)
|
||||
isPublished = true;
|
||||
|
@ -567,45 +567,45 @@ namespace data
|
|||
if (caps.empty ()) caps += CAPS_FLAG_V4;
|
||||
WriteString (caps, properties);
|
||||
properties << ';';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
continue; // don't write NTCP address
|
||||
}
|
||||
}
|
||||
else if (address.transportStyle == eTransportSSU)
|
||||
{
|
||||
WriteString ("SSU", s);
|
||||
// caps
|
||||
WriteString ("caps", properties);
|
||||
properties << '=';
|
||||
std::string caps;
|
||||
std::string caps;
|
||||
if (address.IsPeerTesting ()) caps += CAPS_FLAG_SSU_TESTING;
|
||||
if (address.host.is_v4 ())
|
||||
{
|
||||
{
|
||||
if (address.published)
|
||||
{
|
||||
{
|
||||
isPublished = true;
|
||||
if (address.IsIntroducer ()) caps += CAPS_FLAG_SSU_INTRODUCER;
|
||||
}
|
||||
}
|
||||
else
|
||||
caps += CAPS_FLAG_V4;
|
||||
}
|
||||
else if (address.host.is_v6 ())
|
||||
{
|
||||
{
|
||||
if (address.published)
|
||||
{
|
||||
{
|
||||
isPublished = true;
|
||||
if (address.IsIntroducer ()) caps += CAPS_FLAG_SSU_INTRODUCER;
|
||||
}
|
||||
}
|
||||
else
|
||||
caps += CAPS_FLAG_V6;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (address.IsV4 ()) caps += CAPS_FLAG_V4;
|
||||
if (address.IsV6 ()) caps += CAPS_FLAG_V6;
|
||||
if (caps.empty ()) caps += CAPS_FLAG_V4;
|
||||
}
|
||||
}
|
||||
WriteString (caps, properties);
|
||||
properties << ';';
|
||||
}
|
||||
|
@ -809,7 +809,7 @@ namespace data
|
|||
}
|
||||
else
|
||||
{
|
||||
LogPrint (eLogWarning, "RouterInfo: string length ", (int)l, " exceeds buffer size ", len);
|
||||
LogPrint (eLogWarning, "RouterInfo: String length ", (int)l, " exceeds buffer size ", len);
|
||||
s.seekg (l, std::ios::cur); // skip
|
||||
str[0] = 0;
|
||||
}
|
||||
|
@ -845,13 +845,13 @@ namespace data
|
|||
m_Addresses->push_back(std::move(addr));
|
||||
}
|
||||
|
||||
void RouterInfo::AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv,
|
||||
void RouterInfo::AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv,
|
||||
const boost::asio::ip::address& host, int port, uint8_t caps)
|
||||
{
|
||||
auto addr = std::make_shared<Address>();
|
||||
addr->host = host;
|
||||
addr->port = port;
|
||||
addr->transportStyle = eTransportNTCP;
|
||||
addr->transportStyle = eTransportNTCP;
|
||||
addr->caps = caps;
|
||||
addr->date = 0;
|
||||
addr->ntcp2.reset (new NTCP2Ext ());
|
||||
|
@ -862,12 +862,12 @@ namespace data
|
|||
{
|
||||
m_SupportedTransports |= eNTCP2V4;
|
||||
if (addr->published) m_ReachableTransports |= eNTCP2V4;
|
||||
}
|
||||
}
|
||||
if (addr->IsV6 ())
|
||||
{
|
||||
m_SupportedTransports |= eNTCP2V6;
|
||||
if (addr->published) m_ReachableTransports |= eNTCP2V6;
|
||||
}
|
||||
}
|
||||
m_Addresses->push_back(std::move(addr));
|
||||
}
|
||||
|
||||
|
@ -875,7 +875,7 @@ namespace data
|
|||
{
|
||||
for (auto& addr : *m_Addresses)
|
||||
{
|
||||
if (addr->transportStyle == eTransportSSU &&
|
||||
if (addr->transportStyle == eTransportSSU &&
|
||||
((addr->IsV4 () && introducer.iHost.is_v4 ()) || (addr->IsV6 () && introducer.iHost.is_v6 ())))
|
||||
{
|
||||
for (auto& intro: addr->ssu->introducers)
|
||||
|
@ -892,7 +892,7 @@ namespace data
|
|||
{
|
||||
for (auto& addr: *m_Addresses)
|
||||
{
|
||||
if (addr->transportStyle == eTransportSSU &&
|
||||
if (addr->transportStyle == eTransportSSU &&
|
||||
((addr->IsV4 () && e.address ().is_v4 ()) || (addr->IsV6 () && e.address ().is_v6 ())))
|
||||
{
|
||||
for (auto it = addr->ssu->introducers.begin (); it != addr->ssu->introducers.end (); ++it)
|
||||
|
@ -963,8 +963,8 @@ namespace data
|
|||
bool RouterInfo::IsNTCP2V6 () const
|
||||
{
|
||||
return m_SupportedTransports & eNTCP2V6;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool RouterInfo::IsV6 () const
|
||||
{
|
||||
return m_SupportedTransports & (eSSUV6 | eNTCP2V6);
|
||||
|
@ -978,28 +978,28 @@ namespace data
|
|||
bool RouterInfo::IsMesh () const
|
||||
{
|
||||
return m_SupportedTransports & eNTCP2V6Mesh;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void RouterInfo::EnableV6 ()
|
||||
{
|
||||
if (!IsV6 ())
|
||||
{
|
||||
{
|
||||
uint8_t addressCaps = AddressCaps::eV6;
|
||||
if (IsV4 ()) addressCaps |= AddressCaps::eV4;
|
||||
SetUnreachableAddressesTransportCaps (addressCaps);
|
||||
UpdateSupportedTransports ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RouterInfo::EnableV4 ()
|
||||
{
|
||||
if (!IsV4 ())
|
||||
{
|
||||
{
|
||||
uint8_t addressCaps = AddressCaps::eV4;
|
||||
if (IsV6 ()) addressCaps |= AddressCaps::eV6;
|
||||
SetUnreachableAddressesTransportCaps (addressCaps);
|
||||
UpdateSupportedTransports ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1011,15 +1011,15 @@ namespace data
|
|||
{
|
||||
auto addr = *it;
|
||||
if (addr->IsV6 ())
|
||||
{
|
||||
{
|
||||
if (addr->IsV4 ())
|
||||
{
|
||||
{
|
||||
addr->caps &= ~AddressCaps::eV6;
|
||||
++it;
|
||||
}
|
||||
}
|
||||
else
|
||||
it = m_Addresses->erase (it);
|
||||
}
|
||||
}
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
@ -1035,15 +1035,15 @@ namespace data
|
|||
{
|
||||
auto addr = *it;
|
||||
if (addr->IsV4 ())
|
||||
{
|
||||
{
|
||||
if (addr->IsV6 ())
|
||||
{
|
||||
{
|
||||
addr->caps &= ~AddressCaps::eV4;
|
||||
++it;
|
||||
}
|
||||
}
|
||||
else
|
||||
it = m_Addresses->erase (it);
|
||||
}
|
||||
}
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
@ -1054,14 +1054,14 @@ namespace data
|
|||
void RouterInfo::EnableMesh ()
|
||||
{
|
||||
if (!IsMesh ())
|
||||
{
|
||||
{
|
||||
m_SupportedTransports |= eNTCP2V6Mesh;
|
||||
m_ReachableTransports |= eNTCP2V6Mesh;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RouterInfo::DisableMesh ()
|
||||
{
|
||||
{
|
||||
if (IsMesh ())
|
||||
{
|
||||
m_SupportedTransports &= ~eNTCP2V6Mesh;
|
||||
|
@ -1074,8 +1074,8 @@ namespace data
|
|||
else
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetSSUAddress (bool v4only) const
|
||||
{
|
||||
|
@ -1115,7 +1115,7 @@ namespace data
|
|||
if (!key) return nullptr;
|
||||
return GetAddress (
|
||||
[key](std::shared_ptr<const RouterInfo::Address> address)->bool
|
||||
{
|
||||
{
|
||||
return address->IsNTCP2 () && !memcmp (address->ntcp2->staticKey, key, 32);
|
||||
});
|
||||
}
|
||||
|
@ -1128,16 +1128,16 @@ namespace data
|
|||
return address->IsPublishedNTCP2 () && address->host.is_v4 ();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetPublishedNTCP2V6Address () const
|
||||
{
|
||||
return GetAddress (
|
||||
[](std::shared_ptr<const RouterInfo::Address> address)->bool
|
||||
{
|
||||
return address->IsPublishedNTCP2 () && address->host.is_v6 () &&
|
||||
return address->IsPublishedNTCP2 () && address->host.is_v6 () &&
|
||||
!i2p::util::net::IsYggdrasilAddress (address->host);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetYggdrasilAddress () const
|
||||
{
|
||||
|
@ -1146,8 +1146,8 @@ namespace data
|
|||
{
|
||||
return address->IsPublishedNTCP2 () && i2p::util::net::IsYggdrasilAddress (address->host);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::shared_ptr<RouterProfile> RouterInfo::GetProfile () const
|
||||
{
|
||||
if (!m_Profile)
|
||||
|
@ -1162,34 +1162,34 @@ namespace data
|
|||
encryptor->Encrypt (data, encrypted, ctx, true);
|
||||
}
|
||||
|
||||
bool RouterInfo::IsEligibleFloodfill () const
|
||||
bool RouterInfo::IsEligibleFloodfill () const
|
||||
{
|
||||
// floodfill must be reachable by ipv4, >= 0.9.38 and not DSA
|
||||
return IsReachableBy (eNTCP2V4 | eSSUV4) && m_Version >= NETDB_MIN_FLOODFILL_VERSION &&
|
||||
GetIdentity ()->GetSigningKeyType () != SIGNING_KEY_TYPE_DSA_SHA1;
|
||||
}
|
||||
GetIdentity ()->GetSigningKeyType () != SIGNING_KEY_TYPE_DSA_SHA1;
|
||||
}
|
||||
|
||||
bool RouterInfo::IsPeerTesting (bool v4) const
|
||||
{
|
||||
if (!(m_SupportedTransports & (v4 ? eSSUV4 : eSSUV6))) return false;
|
||||
if (!(m_SupportedTransports & (v4 ? eSSUV4 : eSSUV6))) return false;
|
||||
return (bool)GetAddress (
|
||||
[v4](std::shared_ptr<const RouterInfo::Address> address)->bool
|
||||
{
|
||||
{
|
||||
return (address->transportStyle == eTransportSSU) && address->IsPeerTesting () &&
|
||||
((v4 && address->IsV4 ()) || (!v4 && address->IsV6 ())) && address->IsReachableSSU ();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
bool RouterInfo::IsIntroducer (bool v4) const
|
||||
{
|
||||
if (!(m_SupportedTransports & (v4 ? eSSUV4 : eSSUV6))) return false;
|
||||
if (!(m_SupportedTransports & (v4 ? eSSUV4 : eSSUV6))) return false;
|
||||
return (bool)GetAddress (
|
||||
[v4](std::shared_ptr<const RouterInfo::Address> address)->bool
|
||||
{
|
||||
{
|
||||
return (address->transportStyle == eTransportSSU) && address->IsIntroducer () &&
|
||||
((v4 && address->IsV4 ()) || (!v4 && address->IsV6 ())) && !address->host.is_unspecified ();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void RouterInfo::SetUnreachableAddressesTransportCaps (uint8_t transports)
|
||||
{
|
||||
|
@ -1214,7 +1214,7 @@ namespace data
|
|||
if (addr->transportStyle == eTransportNTCP)
|
||||
{
|
||||
if (addr->IsV4 ()) transports |= eNTCP2V4;
|
||||
if (addr->IsV6 ())
|
||||
if (addr->IsV6 ())
|
||||
transports |= (i2p::util::net::IsYggdrasilAddress (addr->host) ? eNTCP2V6Mesh : eNTCP2V6);
|
||||
if (addr->IsPublishedNTCP2 ())
|
||||
m_ReachableTransports |= transports;
|
||||
|
@ -1225,9 +1225,9 @@ namespace data
|
|||
if (addr->IsV6 ()) transports |= eSSUV6;
|
||||
if (addr->IsReachableSSU ())
|
||||
m_ReachableTransports |= transports;
|
||||
}
|
||||
}
|
||||
m_SupportedTransports |= transports;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ namespace transport
|
|||
}
|
||||
catch ( std::exception & ex )
|
||||
{
|
||||
LogPrint (eLogError, "SSU: failed to bind to v4 port ", m_Endpoint.port(), ": ", ex.what());
|
||||
LogPrint (eLogError, "SSU: Failed to bind to v4 port ", m_Endpoint.port(), ": ", ex.what());
|
||||
ThrowFatal ("Unable to start IPv4 SSU transport at port ", m_Endpoint.port(), ": ", ex.what ());
|
||||
}
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ namespace transport
|
|||
}
|
||||
catch ( std::exception & ex )
|
||||
{
|
||||
LogPrint (eLogError, "SSU: failed to bind to v6 port ", m_EndpointV6.port(), ": ", ex.what());
|
||||
LogPrint (eLogError, "SSU: Failed to bind to v6 port ", m_EndpointV6.port(), ": ", ex.what());
|
||||
ThrowFatal ("Unable to start IPv6 SSU transport at port ", m_Endpoint.port(), ": ", ex.what ());
|
||||
}
|
||||
}
|
||||
|
@ -156,7 +156,7 @@ namespace transport
|
|||
}
|
||||
catch (std::exception& ex)
|
||||
{
|
||||
LogPrint (eLogError, "SSU: server runtime exception: ", ex.what ());
|
||||
LogPrint (eLogError, "SSU: Server runtime exception: ", ex.what ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -173,7 +173,7 @@ namespace transport
|
|||
}
|
||||
catch (std::exception& ex)
|
||||
{
|
||||
LogPrint (eLogError, "SSU: receivers runtime exception: ", ex.what ());
|
||||
LogPrint (eLogError, "SSU: Receivers runtime exception: ", ex.what ());
|
||||
if (m_IsRunning)
|
||||
{
|
||||
// restart socket
|
||||
|
@ -249,7 +249,7 @@ namespace transport
|
|||
|
||||
if (ec)
|
||||
{
|
||||
LogPrint (eLogError, "SSU: send exception: ", ec.message (), " while trying to send data to ", to.address (), ":", to.port (), " (length: ", len, ")");
|
||||
LogPrint (eLogError, "SSU: Send exception: ", ec.message (), " while trying to send data to ", to.address (), ":", to.port (), " (length: ", len, ")");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -318,7 +318,7 @@ namespace transport
|
|||
delete packet;
|
||||
if (ecode != boost::asio::error::operation_aborted)
|
||||
{
|
||||
LogPrint (eLogError, "SSU: receive error: code ", ecode.value(), ": ", ecode.message ());
|
||||
LogPrint (eLogError, "SSU: Receive error: code ", ecode.value(), ": ", ecode.message ());
|
||||
m_Socket.close ();
|
||||
OpenSocket ();
|
||||
Receive ();
|
||||
|
@ -409,7 +409,7 @@ namespace transport
|
|||
session = std::make_shared<SSUSession> (*this, packet->from);
|
||||
session->WaitForConnect ();
|
||||
(*sessions)[packet->from] = session;
|
||||
LogPrint (eLogDebug, "SSU: new session from ", packet->from.address ().to_string (), ":", packet->from.port (), " created");
|
||||
LogPrint (eLogDebug, "SSU: New session from ", packet->from.address ().to_string (), ":", packet->from.port (), " created");
|
||||
}
|
||||
}
|
||||
if (session)
|
||||
|
@ -797,7 +797,7 @@ namespace transport
|
|||
if (sessions.empty () && !introducers.empty ())
|
||||
{
|
||||
// bump creation time for previous introducers if no new sessions found
|
||||
LogPrint (eLogDebug, "SSU: no new introducers found. Trying to reuse existing");
|
||||
LogPrint (eLogDebug, "SSU: No new introducers found. Trying to reuse existing");
|
||||
for (const auto& it : introducers)
|
||||
{
|
||||
auto session = FindSession (it);
|
||||
|
@ -847,7 +847,7 @@ namespace transport
|
|||
}
|
||||
else
|
||||
{
|
||||
LogPrint (eLogDebug, "SSU: can't find more introducers");
|
||||
LogPrint (eLogDebug, "SSU: Can't find more introducers");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -940,10 +940,10 @@ namespace transport
|
|||
{
|
||||
auto session = it.second;
|
||||
if (it.first != session->GetRemoteEndpoint ())
|
||||
LogPrint (eLogWarning, "SSU: remote endpoint ", session->GetRemoteEndpoint (), " doesn't match key ", it.first, " adjusted");
|
||||
LogPrint (eLogWarning, "SSU: Remote endpoint ", session->GetRemoteEndpoint (), " doesn't match key ", it.first, " adjusted");
|
||||
m_Service.post ([session]
|
||||
{
|
||||
LogPrint (eLogWarning, "SSU: no activity with ", session->GetRemoteEndpoint (), " for ", session->GetTerminationTimeout (), " seconds");
|
||||
LogPrint (eLogWarning, "SSU: No activity with ", session->GetRemoteEndpoint (), " for ", session->GetTerminationTimeout (), " seconds");
|
||||
session->Failed ();
|
||||
});
|
||||
}
|
||||
|
@ -968,10 +968,10 @@ namespace transport
|
|||
{
|
||||
auto session = it.second;
|
||||
if (it.first != session->GetRemoteEndpoint ())
|
||||
LogPrint (eLogWarning, "SSU: remote endpoint ", session->GetRemoteEndpoint (), " doesn't match key ", it.first);
|
||||
LogPrint (eLogWarning, "SSU: Remote endpoint ", session->GetRemoteEndpoint (), " doesn't match key ", it.first);
|
||||
m_Service.post ([session]
|
||||
{
|
||||
LogPrint (eLogWarning, "SSU: no activity with ", session->GetRemoteEndpoint (), " for ", session->GetTerminationTimeout (), " seconds");
|
||||
LogPrint (eLogWarning, "SSU: No activity with ", session->GetRemoteEndpoint (), " for ", session->GetTerminationTimeout (), " seconds");
|
||||
session->Failed ();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -177,12 +177,12 @@ namespace transport
|
|||
ProcessSessionConfirmed (buf, len); // buf with header
|
||||
break;
|
||||
case PAYLOAD_TYPE_PEER_TEST:
|
||||
LogPrint (eLogDebug, "SSU: peer test received");
|
||||
LogPrint (eLogDebug, "SSU: Peer test received");
|
||||
ProcessPeerTest (buf + headerSize, len - headerSize, senderEndpoint);
|
||||
break;
|
||||
case PAYLOAD_TYPE_SESSION_DESTROYED:
|
||||
{
|
||||
LogPrint (eLogDebug, "SSU: session destroy received");
|
||||
LogPrint (eLogDebug, "SSU: Session destroy received");
|
||||
m_Server.DeleteSession (shared_from_this ());
|
||||
break;
|
||||
}
|
||||
|
@ -192,11 +192,11 @@ namespace transport
|
|||
m_Server.DeleteSession (shared_from_this ());
|
||||
break;
|
||||
case PAYLOAD_TYPE_RELAY_REQUEST:
|
||||
LogPrint (eLogDebug, "SSU: relay request received");
|
||||
LogPrint (eLogDebug, "SSU: Relay request received");
|
||||
ProcessRelayRequest (buf + headerSize, len - headerSize, senderEndpoint);
|
||||
break;
|
||||
case PAYLOAD_TYPE_RELAY_INTRO:
|
||||
LogPrint (eLogDebug, "SSU: relay intro received");
|
||||
LogPrint (eLogDebug, "SSU: Relay intro received");
|
||||
ProcessRelayIntro (buf + headerSize, len - headerSize);
|
||||
break;
|
||||
default:
|
||||
|
@ -206,7 +206,7 @@ namespace transport
|
|||
|
||||
void SSUSession::ProcessSessionRequest (const uint8_t * buf, size_t len)
|
||||
{
|
||||
LogPrint (eLogDebug, "SSU message: session request");
|
||||
LogPrint (eLogDebug, "SSU message: Session request");
|
||||
bool sendRelayTag = true;
|
||||
auto headerSize = sizeof (SSUHeader);
|
||||
if (((SSUHeader *)buf)->IsExtendedOptions ())
|
||||
|
@ -222,7 +222,7 @@ namespace transport
|
|||
}
|
||||
if (headerSize >= len)
|
||||
{
|
||||
LogPrint (eLogError, "Session request header size ", headerSize, " exceeds packet length ", len);
|
||||
LogPrint (eLogError, "SSU: Session request header size ", headerSize, " exceeds packet length ", len);
|
||||
return;
|
||||
}
|
||||
if (!m_DHKeysPair)
|
||||
|
@ -230,7 +230,7 @@ namespace transport
|
|||
auto pair = std::make_shared<i2p::crypto::DHKeys> ();
|
||||
pair->GenerateKeys ();
|
||||
m_DHKeysPair = pair;
|
||||
}
|
||||
}
|
||||
CreateAESandMacKey (buf + headerSize);
|
||||
SendSessionCreated (buf + headerSize, sendRelayTag);
|
||||
}
|
||||
|
@ -243,13 +243,13 @@ namespace transport
|
|||
return;
|
||||
}
|
||||
|
||||
LogPrint (eLogDebug, "SSU message: session created");
|
||||
LogPrint (eLogDebug, "SSU message: Session created");
|
||||
m_ConnectTimer.cancel (); // connect timer
|
||||
SignedData s; // x,y, our IP, our port, remote IP, remote port, relayTag, signed on time
|
||||
auto headerSize = GetSSUHeaderSize (buf);
|
||||
if (headerSize >= len)
|
||||
{
|
||||
LogPrint (eLogError, "Session created header size ", headerSize, " exceeds packet length ", len);
|
||||
LogPrint (eLogError, "SSU: Session created header size ", headerSize, " exceeds packet length ", len);
|
||||
return;
|
||||
}
|
||||
uint8_t * payload = buf + headerSize;
|
||||
|
@ -259,7 +259,7 @@ namespace transport
|
|||
s.Insert (y, 256); // y
|
||||
payload += 256;
|
||||
boost::asio::ip::address ourIP;
|
||||
uint16_t ourPort = 0;
|
||||
uint16_t ourPort = 0;
|
||||
auto addressAndPortLen = ExtractIPAddressAndPort (payload, len, ourIP, ourPort);
|
||||
if (!addressAndPortLen) return;
|
||||
uint8_t * ourAddressAndPort = payload + 1;
|
||||
|
@ -280,7 +280,7 @@ namespace transport
|
|||
uint32_t signedOnTime = bufbe32toh(payload);
|
||||
if (signedOnTime < ts - SSU_CLOCK_SKEW || signedOnTime > ts + SSU_CLOCK_SKEW)
|
||||
{
|
||||
LogPrint (eLogError, "SSU: clock skew detected ", (int)ts - signedOnTime, ". Check your clock");
|
||||
LogPrint (eLogError, "SSU: Clock skew detected ", (int)ts - signedOnTime, ". Check your clock!");
|
||||
i2p::context.SetError (eRouterErrorClockSkew);
|
||||
}
|
||||
}
|
||||
|
@ -297,19 +297,19 @@ namespace transport
|
|||
{
|
||||
LogPrint (eLogInfo, "SSU: Our external address is ", ourIP.to_string (), ":", ourPort);
|
||||
if (!i2p::util::net::IsInReservedRange (ourIP))
|
||||
{
|
||||
{
|
||||
i2p::context.UpdateAddress (ourIP);
|
||||
SendSessionConfirmed (y, ourAddressAndPort, addressAndPortLen);
|
||||
}
|
||||
SendSessionConfirmed (y, ourAddressAndPort, addressAndPortLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
LogPrint (eLogError, "SSU: Wrong external address ", ourIP.to_string ());
|
||||
Failed ();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogPrint (eLogError, "SSU: message 'created' signature verification failed");
|
||||
LogPrint (eLogError, "SSU: Message 'created' signature verification failed");
|
||||
Failed ();
|
||||
}
|
||||
}
|
||||
|
@ -317,7 +317,7 @@ namespace transport
|
|||
void SSUSession::ProcessSessionConfirmed (const uint8_t * buf, size_t len)
|
||||
{
|
||||
LogPrint (eLogDebug, "SSU: Session confirmed received");
|
||||
m_ConnectTimer.cancel ();
|
||||
m_ConnectTimer.cancel ();
|
||||
auto headerSize = GetSSUHeaderSize (buf);
|
||||
if (headerSize >= len)
|
||||
{
|
||||
|
@ -331,7 +331,7 @@ namespace transport
|
|||
{
|
||||
LogPrint (eLogError, "SSU: Session confirmed identity size ", identitySize, " exceeds packet length ", len);
|
||||
return;
|
||||
}
|
||||
}
|
||||
payload += 2; // size of identity fragment
|
||||
auto identity = std::make_shared<i2p::data::IdentityEx> (payload, identitySize);
|
||||
auto existing = i2p::data::netdb.FindRouter (identity->GetIdentHash ()); // check if exists already
|
||||
|
@ -357,7 +357,7 @@ namespace transport
|
|||
{
|
||||
LogPrint (eLogError, "SSU: Session confirmed message is too short ", len);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// verify signature
|
||||
if (m_SignedData && m_SignedData->Verify (m_RemoteIdentity, payload))
|
||||
{
|
||||
|
@ -599,19 +599,19 @@ namespace transport
|
|||
uint8_t * payload = buf + sizeof (SSUHeader);
|
||||
// Charlie
|
||||
if (isV4)
|
||||
{
|
||||
{
|
||||
*payload = 4;
|
||||
payload++; // size
|
||||
memcpy (payload, to.address ().to_v4 ().to_bytes ().data (), 4); // Charlie's IP V4
|
||||
payload += 4; // address
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*payload = 16;
|
||||
payload++; // size
|
||||
memcpy (payload, to.address ().to_v6 ().to_bytes ().data (), 16); // Alice's IP V6
|
||||
payload += 16; // address
|
||||
}
|
||||
}
|
||||
htobe16buf (payload, to.port ()); // Charlie's port
|
||||
payload += 2; // port
|
||||
// Alice
|
||||
|
@ -647,7 +647,7 @@ namespace transport
|
|||
FillHeaderAndEncrypt (PAYLOAD_TYPE_RELAY_RESPONSE, buf, isV4 ? 64 : 80, introKey, iv, introKey);
|
||||
m_Server.Send (buf, isV4 ? 64 : 80, from);
|
||||
}
|
||||
LogPrint (eLogDebug, "SSU: relay response sent");
|
||||
LogPrint (eLogDebug, "SSU: Relay response sent");
|
||||
}
|
||||
|
||||
void SSUSession::SendRelayIntro (std::shared_ptr<SSUSession> session, const boost::asio::ip::udp::endpoint& from)
|
||||
|
@ -683,7 +683,7 @@ namespace transport
|
|||
RAND_bytes (iv, 16); // random iv
|
||||
FillHeaderAndEncrypt (PAYLOAD_TYPE_RELAY_INTRO, buf, isV4 ? 48 : 64, session->m_SessionKey, iv, session->m_MacKey);
|
||||
m_Server.Send (buf, isV4 ? 48 : 64, session->m_RemoteEndpoint);
|
||||
LogPrint (eLogDebug, "SSU: relay intro sent");
|
||||
LogPrint (eLogDebug, "SSU: Relay intro sent");
|
||||
}
|
||||
|
||||
void SSUSession::ProcessRelayResponse (const uint8_t * buf, size_t len)
|
||||
|
@ -705,15 +705,15 @@ namespace transport
|
|||
else
|
||||
LogPrint (eLogWarning, "SSU: Wrong external address ", ourIP.to_string ());
|
||||
if (ourIP.is_v4 ())
|
||||
{
|
||||
{
|
||||
if (ourPort != m_Server.GetPort ())
|
||||
{
|
||||
{
|
||||
if (i2p::context.GetStatus () == eRouterStatusTesting)
|
||||
i2p::context.SetError (eRouterErrorSymmetricNAT);
|
||||
}
|
||||
else if (i2p::context.GetStatus () == eRouterStatusError && i2p::context.GetError () == eRouterErrorSymmetricNAT)
|
||||
i2p::context.SetStatus (eRouterStatusTesting);
|
||||
}
|
||||
}
|
||||
uint32_t nonce = bufbe32toh (buf);
|
||||
buf += 4; // nonce
|
||||
auto it = m_RelayRequests.find (nonce);
|
||||
|
@ -727,7 +727,7 @@ namespace transport
|
|||
// now we do
|
||||
LogPrint (eLogInfo, "SSU: RelayReponse connecting to endpoint ", remoteEndpoint);
|
||||
if ((remoteIP.is_v4 () && i2p::context.GetStatus () == eRouterStatusFirewalled) ||
|
||||
(remoteIP.is_v6 () && i2p::context.GetStatusV6 () == eRouterStatusFirewalled))
|
||||
(remoteIP.is_v6 () && i2p::context.GetStatusV6 () == eRouterStatusFirewalled))
|
||||
m_Server.Send (buf, 0, remoteEndpoint); // send HolePunch
|
||||
// we assume that HolePunch has been sent by this time and our SessionRequest will go through
|
||||
m_Server.CreateDirectSession (it->second, remoteEndpoint, false);
|
||||
|
@ -803,7 +803,7 @@ namespace transport
|
|||
htobe16buf (out + len + 16, (netid == I2PD_NET_ID) ? encryptedLen : encryptedLen ^ ((netid - 2) << 8));
|
||||
i2p::crypto::HMACMD5Digest (encrypted, encryptedLen + 18, m_MacKey, header->mac);
|
||||
}
|
||||
|
||||
|
||||
void SSUSession::Decrypt (uint8_t * buf, size_t len, const i2p::crypto::AESKey& aesKey)
|
||||
{
|
||||
if (len < sizeof (SSUHeader))
|
||||
|
@ -872,7 +872,7 @@ namespace transport
|
|||
if (!IsOutgoing ()) // incoming session
|
||||
ScheduleConnectTimer ();
|
||||
else
|
||||
LogPrint (eLogError, "SSU: wait for connect for outgoing session");
|
||||
LogPrint (eLogError, "SSU: Wait for connect for outgoing session");
|
||||
}
|
||||
|
||||
void SSUSession::ScheduleConnectTimer ()
|
||||
|
@ -888,7 +888,7 @@ namespace transport
|
|||
if (!ecode)
|
||||
{
|
||||
// timeout expired
|
||||
LogPrint (eLogWarning, "SSU: session with ", m_RemoteEndpoint, " was not established after ", SSU_CONNECT_TIMEOUT, " seconds");
|
||||
LogPrint (eLogWarning, "SSU: Session with ", m_RemoteEndpoint, " was not established after ", SSU_CONNECT_TIMEOUT, " seconds");
|
||||
Failed ();
|
||||
}
|
||||
}
|
||||
|
@ -1023,29 +1023,29 @@ namespace transport
|
|||
{
|
||||
if (m_Server.GetPeerTestSession (nonce) == shared_from_this ()) // Alice-Bob
|
||||
{
|
||||
LogPrint (eLogDebug, "SSU: peer test from Bob. We are Alice");
|
||||
LogPrint (eLogDebug, "SSU: Peer test from Bob. We are Alice");
|
||||
if (IsV6 ())
|
||||
{
|
||||
if (i2p::context.GetStatusV6 () == eRouterStatusTesting)
|
||||
{
|
||||
if (i2p::context.GetStatusV6 () == eRouterStatusTesting)
|
||||
{
|
||||
i2p::context.SetStatusV6 (eRouterStatusFirewalled);
|
||||
m_Server.RescheduleIntroducersUpdateTimerV6 ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (i2p::context.GetStatus () == eRouterStatusTesting) // still not OK
|
||||
{
|
||||
{
|
||||
i2p::context.SetStatus (eRouterStatusFirewalled);
|
||||
m_Server.RescheduleIntroducersUpdateTimer ();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogPrint (eLogDebug, "SSU: first peer test from Charlie. We are Alice");
|
||||
LogPrint (eLogDebug, "SSU: First peer test from Charlie. We are Alice");
|
||||
if (m_State == eSessionStateEstablished)
|
||||
LogPrint (eLogWarning, "SSU: first peer test from Charlie through established session. We are Alice");
|
||||
LogPrint (eLogWarning, "SSU: First peer test from Charlie through established session. We are Alice");
|
||||
if (IsV6 ())
|
||||
i2p::context.SetStatusV6 (eRouterStatusOK);
|
||||
else
|
||||
else
|
||||
i2p::context.SetStatus (eRouterStatusOK);
|
||||
m_Server.UpdatePeerTest (nonce, ePeerTestParticipantAlice2);
|
||||
SendPeerTest (nonce, senderEndpoint.address (), senderEndpoint.port (), introKey, true, false); // to Charlie
|
||||
|
@ -1055,14 +1055,14 @@ namespace transport
|
|||
case ePeerTestParticipantAlice2:
|
||||
{
|
||||
if (m_Server.GetPeerTestSession (nonce) == shared_from_this ()) // Alice-Bob
|
||||
LogPrint (eLogDebug, "SSU: peer test from Bob. We are Alice");
|
||||
LogPrint (eLogDebug, "SSU: Peer test from Bob. We are Alice");
|
||||
else
|
||||
{
|
||||
// peer test successive
|
||||
LogPrint (eLogDebug, "SSU: second peer test from Charlie. We are Alice");
|
||||
LogPrint (eLogDebug, "SSU: Second peer test from Charlie. We are Alice");
|
||||
if (IsV6 ())
|
||||
i2p::context.SetStatusV6 (eRouterStatusOK);
|
||||
else
|
||||
i2p::context.SetStatusV6 (eRouterStatusOK);
|
||||
else
|
||||
i2p::context.SetStatus (eRouterStatusOK);
|
||||
m_Server.RemovePeerTest (nonce);
|
||||
}
|
||||
|
@ -1070,19 +1070,19 @@ namespace transport
|
|||
}
|
||||
case ePeerTestParticipantBob:
|
||||
{
|
||||
LogPrint (eLogDebug, "SSU: peer test from Charlie. We are Bob");
|
||||
LogPrint (eLogDebug, "SSU: Peer test from Charlie. We are Bob");
|
||||
auto session = m_Server.GetPeerTestSession (nonce); // session with Alice from PeerTest
|
||||
if (session && session->m_State == eSessionStateEstablished)
|
||||
{
|
||||
const auto& ep = session->GetRemoteEndpoint (); // Alice's endpoint as known to Bob
|
||||
session->SendPeerTest (nonce, ep.address (), ep.port (), introKey, false, true); // send back to Alice
|
||||
}
|
||||
}
|
||||
m_Server.RemovePeerTest (nonce); // nonce has been used
|
||||
break;
|
||||
}
|
||||
case ePeerTestParticipantCharlie:
|
||||
{
|
||||
LogPrint (eLogDebug, "SSU: peer test from Alice. We are Charlie");
|
||||
LogPrint (eLogDebug, "SSU: Peer test from Alice. We are Charlie");
|
||||
SendPeerTest (nonce, senderEndpoint.address (), senderEndpoint.port (), introKey); // to Alice with her actual address
|
||||
m_Server.RemovePeerTest (nonce); // nonce has been used
|
||||
break;
|
||||
|
@ -1095,17 +1095,17 @@ namespace transport
|
|||
// new test
|
||||
if (port)
|
||||
{
|
||||
LogPrint (eLogDebug, "SSU: peer test from Bob. We are Charlie");
|
||||
LogPrint (eLogDebug, "SSU: Peer test from Bob. We are Charlie");
|
||||
Send (PAYLOAD_TYPE_PEER_TEST, buf, len); // back to Bob
|
||||
if (!addr.is_unspecified () && !i2p::util::net::IsInReservedRange(addr))
|
||||
{
|
||||
{
|
||||
m_Server.NewPeerTest (nonce, ePeerTestParticipantCharlie);
|
||||
SendPeerTest (nonce, addr, port, introKey); // to Alice with her address received from Bob
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogPrint (eLogDebug, "SSU: peer test from Alice. We are Bob");
|
||||
LogPrint (eLogDebug, "SSU: Peer test from Alice. We are Bob");
|
||||
auto session = senderEndpoint.address ().is_v4 () ? m_Server.GetRandomEstablishedV4Session (shared_from_this ()) : m_Server.GetRandomEstablishedV6Session (shared_from_this ()); // Charlie
|
||||
if (session)
|
||||
{
|
||||
|
@ -1115,7 +1115,7 @@ namespace transport
|
|||
}
|
||||
}
|
||||
else
|
||||
LogPrint (eLogError, "SSU: unexpected peer test");
|
||||
LogPrint (eLogError, "SSU: Unexpected peer test");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1188,7 +1188,7 @@ namespace transport
|
|||
void SSUSession::SendPeerTest ()
|
||||
{
|
||||
// we are Alice
|
||||
LogPrint (eLogDebug, "SSU: sending peer test");
|
||||
LogPrint (eLogDebug, "SSU: Initiating peer test");
|
||||
auto address = IsV6 () ? i2p::context.GetRouterInfo ().GetSSUV6Address () : i2p::context.GetRouterInfo ().GetSSUAddress (true);
|
||||
if (!address)
|
||||
{
|
||||
|
@ -1233,9 +1233,9 @@ namespace transport
|
|||
}
|
||||
catch (std::exception& ex)
|
||||
{
|
||||
LogPrint (eLogWarning, "SSU: exception while sending session destoroyed: ", ex.what ());
|
||||
LogPrint (eLogWarning, "SSU: Exception while sending session destroyed: ", ex.what ());
|
||||
}
|
||||
LogPrint (eLogDebug, "SSU: session destroyed sent");
|
||||
LogPrint (eLogDebug, "SSU: Session destroyed sent");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1247,7 +1247,7 @@ namespace transport
|
|||
if (paddingSize > 0) msgSize += (16 - paddingSize);
|
||||
if (msgSize > SSU_MTU_V4)
|
||||
{
|
||||
LogPrint (eLogWarning, "SSU: payload size ", msgSize, " exceeds MTU");
|
||||
LogPrint (eLogWarning, "SSU: Payload size ", msgSize, " exceeds MTU");
|
||||
return;
|
||||
}
|
||||
memcpy (buf + sizeof (SSUHeader), payload, len);
|
||||
|
@ -1268,12 +1268,12 @@ namespace transport
|
|||
if (!len) return 0;
|
||||
uint8_t size = *buf;
|
||||
size_t s = 1 + size + 2; // size + address + port
|
||||
if (len < s)
|
||||
if (len < s)
|
||||
{
|
||||
LogPrint (eLogWarning, "SSU: Address is too short ", len);
|
||||
port = 0;
|
||||
return len;
|
||||
}
|
||||
}
|
||||
buf++; // size
|
||||
if (size == 4)
|
||||
{
|
||||
|
@ -1286,12 +1286,12 @@ namespace transport
|
|||
boost::asio::ip::address_v6::bytes_type bytes;
|
||||
memcpy (bytes.data (), buf, 16);
|
||||
ip = boost::asio::ip::address_v6 (bytes);
|
||||
}
|
||||
}
|
||||
else
|
||||
LogPrint (eLogWarning, "SSU: Address size ", size, " is not supported");
|
||||
buf += size;
|
||||
port = bufbe16toh (buf);
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -128,7 +128,7 @@ namespace transport
|
|||
m_Queue.push (pair);
|
||||
}
|
||||
else
|
||||
LogPrint(eLogError, "Transports: return null DHKeys");
|
||||
LogPrint(eLogError, "Transports: Return null DHKeys");
|
||||
}
|
||||
|
||||
Transports transports;
|
||||
|
@ -192,10 +192,10 @@ namespace transport
|
|||
i2p::context.SetStatus (eRouterStatusProxy);
|
||||
}
|
||||
else
|
||||
LogPrint(eLogError, "Transports: unsupported NTCP2 proxy URL ", ntcp2proxy);
|
||||
LogPrint(eLogError, "Transports: Unsupported NTCP2 proxy URL ", ntcp2proxy);
|
||||
}
|
||||
else
|
||||
LogPrint(eLogError, "Transports: invalid NTCP2 proxy url ", ntcp2proxy);
|
||||
LogPrint(eLogError, "Transports: invalid NTCP2 proxy URL ", ntcp2proxy);
|
||||
}
|
||||
else
|
||||
m_NTCP2Server = new NTCP2Server ();
|
||||
|
@ -204,7 +204,7 @@ namespace transport
|
|||
// create SSU server
|
||||
int ssuPort = 0;
|
||||
if (enableSSU)
|
||||
{
|
||||
{
|
||||
auto& addresses = context.GetRouterInfo ().GetAddresses ();
|
||||
for (const auto& address: addresses)
|
||||
{
|
||||
|
@ -216,39 +216,39 @@ namespace transport
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// bind to interfaces
|
||||
bool ipv4; i2p::config::GetOption("ipv4", ipv4);
|
||||
if (ipv4)
|
||||
{
|
||||
std::string address; i2p::config::GetOption("address4", address);
|
||||
if (!address.empty ())
|
||||
{
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
auto addr = boost::asio::ip::address::from_string (address, ec);
|
||||
if (!ec)
|
||||
{
|
||||
{
|
||||
if (m_NTCP2Server) m_NTCP2Server->SetLocalAddress (addr);
|
||||
if (m_SSUServer) m_SSUServer->SetLocalAddress (addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ipv6; i2p::config::GetOption("ipv6", ipv6);
|
||||
if (ipv6)
|
||||
{
|
||||
std::string address; i2p::config::GetOption("address6", address);
|
||||
if (!address.empty ())
|
||||
{
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
auto addr = boost::asio::ip::address::from_string (address, ec);
|
||||
if (!ec)
|
||||
{
|
||||
if (!ec)
|
||||
{
|
||||
if (m_NTCP2Server) m_NTCP2Server->SetLocalAddress (addr);
|
||||
if (m_SSUServer) m_SSUServer->SetLocalAddress (addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg);
|
||||
|
@ -256,12 +256,12 @@ namespace transport
|
|||
{
|
||||
std::string address; i2p::config::GetOption("meshnets.yggaddress", address);
|
||||
if (!address.empty ())
|
||||
{
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
auto addr = boost::asio::ip::address::from_string (address, ec);
|
||||
if (!ec && m_NTCP2Server && i2p::util::net::IsYggdrasilAddress (addr))
|
||||
m_NTCP2Server->SetLocalAddress (addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// start servers
|
||||
|
@ -269,11 +269,11 @@ namespace transport
|
|||
if (m_SSUServer)
|
||||
{
|
||||
LogPrint (eLogInfo, "Transports: Start listening UDP port ", ssuPort);
|
||||
try
|
||||
try
|
||||
{
|
||||
m_SSUServer->Start ();
|
||||
}
|
||||
catch (std::exception& ex )
|
||||
}
|
||||
catch (std::exception& ex )
|
||||
{
|
||||
LogPrint(eLogError, "Transports: Failed to bind to UDP port", ssuPort);
|
||||
m_SSUServer->Stop ();
|
||||
|
@ -281,8 +281,8 @@ namespace transport
|
|||
m_SSUServer = nullptr;
|
||||
}
|
||||
if (m_SSUServer) DetectExternalIP ();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
|
@ -335,7 +335,7 @@ namespace transport
|
|||
}
|
||||
catch (std::exception& ex)
|
||||
{
|
||||
LogPrint (eLogError, "Transports: runtime exception: ", ex.what ());
|
||||
LogPrint (eLogError, "Transports: Runtime exception: ", ex.what ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -426,7 +426,7 @@ namespace transport
|
|||
}
|
||||
else
|
||||
{
|
||||
LogPrint (eLogWarning, "Transports: delayed messages queue size to ",
|
||||
LogPrint (eLogWarning, "Transports: Delayed messages queue size to ",
|
||||
ident.ToBase64 (), " exceeds ", MAX_NUM_DELAYED_MESSAGES);
|
||||
std::unique_lock<std::mutex> l(m_PeersMutex);
|
||||
m_Peers.erase (it);
|
||||
|
@ -448,23 +448,23 @@ namespace transport
|
|||
if (!peer.numAttempts) // NTCP2 ipv6
|
||||
{
|
||||
if (context.GetRouterInfo ().IsNTCP2V6 () && peer.router->IsReachableBy (RouterInfo::eNTCP2V6))
|
||||
{
|
||||
{
|
||||
address = peer.router->GetPublishedNTCP2V6Address ();
|
||||
if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host))
|
||||
address = nullptr;
|
||||
}
|
||||
}
|
||||
peer.numAttempts++;
|
||||
}
|
||||
if (!address && peer.numAttempts == 1) // NTCP2 ipv4
|
||||
{
|
||||
if (!address && peer.numAttempts == 1) // NTCP2 ipv4
|
||||
{
|
||||
if (context.GetRouterInfo ().IsNTCP2 (true) && peer.router->IsReachableBy (RouterInfo::eNTCP2V4))
|
||||
{
|
||||
{
|
||||
address = peer.router->GetPublishedNTCP2V4Address ();
|
||||
if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host))
|
||||
address = nullptr;
|
||||
}
|
||||
}
|
||||
peer.numAttempts++;
|
||||
}
|
||||
}
|
||||
if (address)
|
||||
{
|
||||
auto s = std::make_shared<NTCP2Session> (*m_NTCP2Server, peer.router, address);
|
||||
|
@ -478,10 +478,10 @@ namespace transport
|
|||
else
|
||||
peer.numAttempts = 2; // switch to SSU
|
||||
}
|
||||
if (peer.numAttempts == 2 || peer.numAttempts == 3) // SSU
|
||||
if (peer.numAttempts == 2 || peer.numAttempts == 3) // SSU
|
||||
{
|
||||
if (m_SSUServer)
|
||||
{
|
||||
{
|
||||
std::shared_ptr<const RouterInfo::Address> address;
|
||||
if (peer.numAttempts == 2) // SSU ipv6
|
||||
{
|
||||
|
@ -507,7 +507,7 @@ namespace transport
|
|||
{
|
||||
if (m_SSUServer->CreateSession (peer.router, address))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
peer.numAttempts += 2; // switch to Mesh
|
||||
|
@ -523,8 +523,8 @@ namespace transport
|
|||
auto s = std::make_shared<NTCP2Session> (*m_NTCP2Server, peer.router, address);
|
||||
m_NTCP2Server->Connect (s);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
LogPrint (eLogInfo, "Transports: No compatble NTCP2 or SSU addresses available");
|
||||
i2p::data::netdb.SetUnreachable (ident, true); // we are here because all connection attempts failed
|
||||
|
@ -591,7 +591,7 @@ namespace transport
|
|||
bool statusChanged = false;
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
auto router = i2p::data::netdb.GetRandomPeerTestRouter (true, excluded); // v4
|
||||
auto router = i2p::data::netdb.GetRandomPeerTestRouter (true, excluded); // v4
|
||||
if (router)
|
||||
{
|
||||
auto addr = router->GetSSUAddress (true); // ipv4
|
||||
|
@ -602,8 +602,8 @@ namespace transport
|
|||
statusChanged = true;
|
||||
i2p::context.SetStatus (eRouterStatusTesting); // first time only
|
||||
}
|
||||
m_SSUServer->CreateSession (router, addr, true); // peer test v4
|
||||
}
|
||||
m_SSUServer->CreateSession (router, addr, true); // peer test v4
|
||||
}
|
||||
excluded.insert (router->GetIdentHash ());
|
||||
}
|
||||
}
|
||||
|
@ -622,20 +622,20 @@ namespace transport
|
|||
{
|
||||
auto addr = router->GetSSUV6Address ();
|
||||
if (addr && !i2p::util::net::IsInReservedRange(addr->host))
|
||||
{
|
||||
{
|
||||
if (!statusChanged)
|
||||
{
|
||||
statusChanged = true;
|
||||
i2p::context.SetStatusV6 (eRouterStatusTesting); // first time only
|
||||
}
|
||||
m_SSUServer->CreateSession (router, addr, true); // peer test v6
|
||||
}
|
||||
}
|
||||
excluded.insert (router->GetIdentHash ());
|
||||
}
|
||||
}
|
||||
if (!statusChanged)
|
||||
LogPrint (eLogWarning, "Transports: Can't find routers for peer test ipv6");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<i2p::crypto::X25519Keys> Transports::GetNextX25519KeysPair ()
|
||||
|
@ -680,7 +680,7 @@ namespace transport
|
|||
{
|
||||
if(RoutesRestricted() && ! IsRestrictedPeer(ident)) {
|
||||
// not trusted
|
||||
LogPrint(eLogWarning, "Transports: closing untrusted inbound connection from ", ident.ToBase64());
|
||||
LogPrint(eLogWarning, "Transports: Closing untrusted inbound connection from ", ident.ToBase64());
|
||||
session->Done();
|
||||
return;
|
||||
}
|
||||
|
@ -780,7 +780,7 @@ namespace transport
|
|||
std::advance (it, rand () % m_Peers.size ());
|
||||
if (it == m_Peers.end () || it->second.router) return nullptr; // not connected
|
||||
ident = it->first;
|
||||
}
|
||||
}
|
||||
return i2p::data::netdb.FindRouter (ident);
|
||||
}
|
||||
void Transports::RestrictRoutesToFamilies(std::set<std::string> families)
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace tunnel
|
|||
SHA256(fragment, TUNNEL_DATA_MSG_SIZE -(fragment - msg->GetPayload ()) + 16, hash); // payload + iv
|
||||
if (memcmp (hash, decrypted, 4))
|
||||
{
|
||||
LogPrint (eLogError, "TunnelMessage: checksum verification failed");
|
||||
LogPrint (eLogError, "TunnelMessage: Checksum verification failed");
|
||||
return;
|
||||
}
|
||||
// process fragments
|
||||
|
@ -57,7 +57,7 @@ namespace tunnel
|
|||
// first fragment
|
||||
if (m_CurrentMsgID)
|
||||
AddIncompleteCurrentMessage (); // we have got a new message while previous is not complete
|
||||
|
||||
|
||||
m_CurrentMessage.deliveryType = (TunnelDeliveryType)((flag >> 5) & 0x03);
|
||||
switch (m_CurrentMessage.deliveryType)
|
||||
{
|
||||
|
@ -108,8 +108,8 @@ namespace tunnel
|
|||
{
|
||||
HandleFollowOnFragment (msgID, isLastFragment, fragmentNum, fragment, size); // another
|
||||
m_CurrentMsgID = 0; m_CurrentMessage.data = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// new message
|
||||
|
@ -118,7 +118,7 @@ namespace tunnel
|
|||
// check message size
|
||||
if (msg->len > msg->maxLen)
|
||||
{
|
||||
LogPrint (eLogError, "TunnelMessage: fragment is too long ", (int)size);
|
||||
LogPrint (eLogError, "TunnelMessage: Fragment is too long ", (int)size);
|
||||
m_CurrentMsgID = 0; m_CurrentMessage.data = nullptr;
|
||||
return;
|
||||
}
|
||||
|
@ -131,35 +131,35 @@ namespace tunnel
|
|||
}
|
||||
else
|
||||
m_CurrentMessage.data = msg;
|
||||
|
||||
|
||||
if (isLastFragment)
|
||||
{
|
||||
{
|
||||
// single message
|
||||
HandleNextMessage (m_CurrentMessage);
|
||||
m_CurrentMsgID = 0; m_CurrentMessage.data = nullptr;
|
||||
}
|
||||
}
|
||||
else if (msgID)
|
||||
{
|
||||
// first fragment of a new message
|
||||
m_CurrentMessage.nextFragmentNum = 1;
|
||||
m_CurrentMessage.receiveTime = i2p::util::GetMillisecondsSinceEpoch ();
|
||||
HandleOutOfSequenceFragments (msgID, m_CurrentMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
LogPrint (eLogError, "TunnelMessage: Message is fragmented, but msgID is not presented");
|
||||
m_CurrentMsgID = 0; m_CurrentMessage.data = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fragment += size;
|
||||
}
|
||||
}
|
||||
else
|
||||
LogPrint (eLogError, "TunnelMessage: zero not found");
|
||||
LogPrint (eLogError, "TunnelMessage: Zero not found");
|
||||
}
|
||||
|
||||
void TunnelEndpoint::HandleFollowOnFragment (uint32_t msgID, bool isLastFragment,
|
||||
void TunnelEndpoint::HandleFollowOnFragment (uint32_t msgID, bool isLastFragment,
|
||||
uint8_t fragmentNum, const uint8_t * fragment, size_t size)
|
||||
{
|
||||
auto it = m_IncompleteMessages.find (msgID);
|
||||
|
@ -213,15 +213,15 @@ namespace tunnel
|
|||
msg.data = newMsg;
|
||||
}
|
||||
if (msg.data->Concat (fragment, size) < size) // concatenate fragment
|
||||
{
|
||||
{
|
||||
LogPrint (eLogError, "TunnelMessage: I2NP buffer overflow ", msg.data->maxLen);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void TunnelEndpoint::HandleCurrenMessageFollowOnFragment (const uint8_t * fragment, size_t size, bool isLastFragment)
|
||||
{
|
||||
|
@ -244,7 +244,7 @@ namespace tunnel
|
|||
LogPrint (eLogError, "TunnelMessage: Fragment ", m_CurrentMessage.nextFragmentNum, " of message ", m_CurrentMsgID, " exceeds max I2NP message size, message dropped");
|
||||
m_CurrentMsgID = 0; m_CurrentMessage.data = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TunnelEndpoint::AddIncompleteCurrentMessage ()
|
||||
{
|
||||
|
@ -255,16 +255,16 @@ namespace tunnel
|
|||
LogPrint (eLogError, "TunnelMessage: Incomplete message ", m_CurrentMsgID, " already exists");
|
||||
m_CurrentMessage.data = nullptr;
|
||||
m_CurrentMsgID = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void TunnelEndpoint::AddOutOfSequenceFragment (uint32_t msgID, uint8_t fragmentNum,
|
||||
bool isLastFragment, const uint8_t * fragment, size_t size)
|
||||
{
|
||||
std::unique_ptr<Fragment> f(new Fragment (isLastFragment, i2p::util::GetMillisecondsSinceEpoch (), size));
|
||||
std::unique_ptr<Fragment> f(new Fragment (isLastFragment, i2p::util::GetMillisecondsSinceEpoch (), size));
|
||||
memcpy (f->data.data (), fragment, size);
|
||||
if (!m_OutOfSequenceFragments.emplace ((uint64_t)msgID << 32 | fragmentNum, std::move (f)).second)
|
||||
LogPrint (eLogInfo, "TunnelMessage: duplicate out-of-sequence fragment ", fragmentNum, " of message ", msgID);
|
||||
LogPrint (eLogInfo, "TunnelMessage: Duplicate out-of-sequence fragment ", fragmentNum, " of message ", msgID);
|
||||
}
|
||||
|
||||
void TunnelEndpoint::HandleOutOfSequenceFragments (uint32_t msgID, TunnelMessageBlockEx& msg)
|
||||
|
@ -276,10 +276,10 @@ namespace tunnel
|
|||
HandleNextMessage (msg);
|
||||
if (&msg == &m_CurrentMessage)
|
||||
{
|
||||
m_CurrentMsgID = 0;
|
||||
m_CurrentMsgID = 0;
|
||||
m_CurrentMessage.data = nullptr;
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
m_IncompleteMessages.erase (msgID);
|
||||
LogPrint (eLogDebug, "TunnelMessage: All fragments of message ", msgID, " found");
|
||||
break;
|
||||
|
@ -318,11 +318,11 @@ namespace tunnel
|
|||
{
|
||||
if (!m_IsInbound && msg.data->IsExpired ())
|
||||
{
|
||||
LogPrint (eLogInfo, "TunnelMessage: message expired");
|
||||
LogPrint (eLogInfo, "TunnelMessage: Message expired");
|
||||
return;
|
||||
}
|
||||
uint8_t typeID = msg.data->GetTypeID ();
|
||||
LogPrint (eLogDebug, "TunnelMessage: handle fragment of ", msg.data->GetLength (), " bytes, msg type ", (int)typeID);
|
||||
LogPrint (eLogDebug, "TunnelMessage: Handle fragment of ", msg.data->GetLength (), " bytes, msg type ", (int)typeID);
|
||||
// catch RI or reply with new list of routers
|
||||
if ((IsRouterInfoMsg (msg.data) || typeID == eI2NPDatabaseSearchReply) &&
|
||||
!m_IsInbound && msg.deliveryType != eDeliveryTypeLocal)
|
||||
|
|
|
@ -60,22 +60,22 @@ namespace api
|
|||
else
|
||||
i2p::log::Logger().SendTo (i2p::fs::DataDirPath (i2p::fs::GetAppName () + ".log"));
|
||||
i2p::log::Logger().Start ();
|
||||
LogPrint(eLogInfo, "API: starting NetDB");
|
||||
LogPrint(eLogInfo, "API: Starting NetDB");
|
||||
i2p::data::netdb.Start();
|
||||
LogPrint(eLogInfo, "API: starting Transports");
|
||||
LogPrint(eLogInfo, "API: Starting Transports");
|
||||
i2p::transport::transports.Start();
|
||||
LogPrint(eLogInfo, "API: starting Tunnels");
|
||||
LogPrint(eLogInfo, "API: Starting Tunnels");
|
||||
i2p::tunnel::tunnels.Start();
|
||||
}
|
||||
|
||||
void StopI2P ()
|
||||
{
|
||||
LogPrint(eLogInfo, "API: shutting down");
|
||||
LogPrint(eLogInfo, "API: stopping Tunnels");
|
||||
LogPrint(eLogInfo, "API: Shutting down");
|
||||
LogPrint(eLogInfo, "API: Stopping Tunnels");
|
||||
i2p::tunnel::tunnels.Stop();
|
||||
LogPrint(eLogInfo, "API: stopping Transports");
|
||||
LogPrint(eLogInfo, "API: Stopping Transports");
|
||||
i2p::transport::transports.Stop();
|
||||
LogPrint(eLogInfo, "API: stopping NetDB");
|
||||
LogPrint(eLogInfo, "API: Stopping NetDB");
|
||||
i2p::data::netdb.Stop();
|
||||
i2p::log::Logger().Stop ();
|
||||
}
|
||||
|
|
|
@ -377,7 +377,7 @@ namespace net
|
|||
const boost::asio::ip::address GetInterfaceAddress (const std::string & ifname, bool ipv6)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
LogPrint(eLogError, "NetIface: cannot get address by interface name, not implemented on WIN32");
|
||||
LogPrint(eLogError, "NetIface: Cannot get address by interface name, not implemented on WIN32");
|
||||
if(ipv6)
|
||||
return boost::asio::ip::address::from_string("::1");
|
||||
else
|
||||
|
@ -413,10 +413,10 @@ namespace net
|
|||
if(ipv6)
|
||||
{
|
||||
fallback = "::1";
|
||||
LogPrint(eLogWarning, "NetIface: cannot find ipv6 address for interface ", ifname);
|
||||
LogPrint(eLogWarning, "NetIface: Can't find ipv6 address for interface ", ifname);
|
||||
} else {
|
||||
fallback = "127.0.0.1";
|
||||
LogPrint(eLogWarning, "NetIface: cannot find ipv4 address for interface ", ifname);
|
||||
LogPrint(eLogWarning, "NetIface: Can't find ipv4 address for interface ", ifname);
|
||||
}
|
||||
return boost::asio::ip::address::from_string(fallback);
|
||||
#endif
|
||||
|
@ -425,14 +425,14 @@ namespace net
|
|||
static bool IsYggdrasilAddress (const uint8_t addr[16])
|
||||
{
|
||||
return addr[0] == 0x02 || addr[0] == 0x03;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsYggdrasilAddress (const boost::asio::ip::address& addr)
|
||||
{
|
||||
if (!addr.is_v6 ()) return false;
|
||||
return IsYggdrasilAddress (addr.to_v6 ().to_bytes ().data ());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
boost::asio::ip::address_v6 GetYggdrasilAddress ()
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
|
@ -479,7 +479,7 @@ namespace net
|
|||
}
|
||||
pCurrAddresses = pCurrAddresses->Next;
|
||||
}
|
||||
LogPrint(eLogWarning, "NetIface: interface with yggdrasil network address not found");
|
||||
LogPrint(eLogWarning, "NetIface: Interface with yggdrasil network address not found");
|
||||
FREE(pAddresses);
|
||||
return boost::asio::ip::address_v6 ();
|
||||
#else
|
||||
|
@ -504,7 +504,7 @@ namespace net
|
|||
cur = cur->ifa_next;
|
||||
}
|
||||
}
|
||||
LogPrint(eLogWarning, "NetIface: interface with yggdrasil network address not found");
|
||||
LogPrint(eLogWarning, "NetIface: Interface with yggdrasil network address not found");
|
||||
if(addrs) freeifaddrs(addrs);
|
||||
return boost::asio::ip::address_v6 ();
|
||||
#endif
|
||||
|
@ -517,11 +517,11 @@ namespace net
|
|||
GetMTUWindows(addr, 0);
|
||||
#else
|
||||
GetMTUUnix(addr, 0);
|
||||
#endif
|
||||
#endif
|
||||
return mtu > 0;
|
||||
}
|
||||
|
||||
bool IsInReservedRange (const boost::asio::ip::address& host)
|
||||
}
|
||||
|
||||
bool IsInReservedRange (const boost::asio::ip::address& host)
|
||||
{
|
||||
// https://en.wikipedia.org/wiki/Reserved_IP_addresses
|
||||
if (host.is_unspecified ()) return false;
|
||||
|
|
|
@ -35,7 +35,7 @@ namespace client
|
|||
class AddressBookFilesystemStorage: public AddressBookStorage
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
AddressBookFilesystemStorage (): storage("addressbook", "b", "", "b32")
|
||||
{
|
||||
i2p::config::GetOption("persist.addressbook", m_IsPersist);
|
||||
|
@ -62,7 +62,7 @@ namespace client
|
|||
private:
|
||||
|
||||
i2p::fs::HashedStorage storage;
|
||||
std::string etagsPath, indexPath, localPath;
|
||||
std::string etagsPath, indexPath, localPath;
|
||||
bool m_IsPersist;
|
||||
std::string m_HostsFile; // file to dump hosts.txt, empty if not used
|
||||
};
|
||||
|
@ -119,7 +119,7 @@ namespace client
|
|||
std::string path = storage.Path( address->GetIdentHash().ToBase32() );
|
||||
std::ofstream f (path, std::ofstream::binary | std::ofstream::out);
|
||||
if (!f.is_open ()) {
|
||||
LogPrint (eLogError, "Addressbook: can't open file ", path);
|
||||
LogPrint (eLogError, "Addressbook: Can't open file ", path);
|
||||
return;
|
||||
}
|
||||
size_t len = address->GetFullLen ();
|
||||
|
@ -169,7 +169,7 @@ namespace client
|
|||
LogPrint(eLogWarning, "Addressbook: Can't open ", indexPath);
|
||||
return 0;
|
||||
}
|
||||
LogPrint(eLogInfo, "Addressbook: using index file ", indexPath);
|
||||
LogPrint(eLogInfo, "Addressbook: Using index file ", indexPath);
|
||||
LogPrint (eLogInfo, "Addressbook: ", num, " addresses loaded from storage");
|
||||
|
||||
return num;
|
||||
|
@ -185,9 +185,9 @@ namespace client
|
|||
|
||||
int AddressBookFilesystemStorage::Save (const std::map<std::string, std::shared_ptr<Address> >& addresses)
|
||||
{
|
||||
if (addresses.empty())
|
||||
if (addresses.empty())
|
||||
{
|
||||
LogPrint(eLogWarning, "Addressbook: not saving empty addressbook");
|
||||
LogPrint(eLogWarning, "Addressbook: Not saving empty addressbook");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -200,7 +200,7 @@ namespace client
|
|||
for (const auto& it: addresses)
|
||||
{
|
||||
if (it.second->IsValid ())
|
||||
{
|
||||
{
|
||||
f << it.first << ",";
|
||||
if (it.second->IsIdentHash ())
|
||||
f << it.second->identHash.ToBase32 ();
|
||||
|
@ -208,15 +208,15 @@ namespace client
|
|||
f << it.second->blindedPublicKey->ToB33 ();
|
||||
f << std::endl;
|
||||
num++;
|
||||
}
|
||||
}
|
||||
else
|
||||
LogPrint (eLogWarning, "Addressbook: invalid address ", it.first);
|
||||
LogPrint (eLogWarning, "Addressbook: Invalid address ", it.first);
|
||||
}
|
||||
LogPrint (eLogInfo, "Addressbook: ", num, " addresses saved");
|
||||
}
|
||||
}
|
||||
else
|
||||
LogPrint (eLogWarning, "Addressbook: Can't open ", indexPath);
|
||||
}
|
||||
}
|
||||
if (!m_HostsFile.empty ())
|
||||
{
|
||||
// dump full hosts.txt
|
||||
|
@ -226,18 +226,18 @@ namespace client
|
|||
for (const auto& it: addresses)
|
||||
{
|
||||
std::shared_ptr<const i2p::data::IdentityEx> addr;
|
||||
if (it.second->IsIdentHash ())
|
||||
{
|
||||
if (it.second->IsIdentHash ())
|
||||
{
|
||||
addr = GetAddress (it.second->identHash);
|
||||
if (addr)
|
||||
f << it.first << "=" << addr->ToBase64 () << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
LogPrint (eLogWarning, "Addressbook: Can't open ", m_HostsFile);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
|
@ -265,7 +265,7 @@ namespace client
|
|||
|
||||
void AddressBookFilesystemStorage::ResetEtags ()
|
||||
{
|
||||
LogPrint (eLogError, "Addressbook: resetting eTags");
|
||||
LogPrint (eLogError, "Addressbook: Resetting eTags");
|
||||
for (boost::filesystem::directory_iterator it (etagsPath); it != boost::filesystem::directory_iterator (); ++it)
|
||||
{
|
||||
if (!boost::filesystem::is_regular_file (it->status ()))
|
||||
|
@ -334,17 +334,17 @@ namespace client
|
|||
}
|
||||
if (m_IsDownloading)
|
||||
{
|
||||
LogPrint (eLogInfo, "Addressbook: subscriptions are downloading, abort");
|
||||
LogPrint (eLogInfo, "Addressbook: Subscriptions are downloading, abort");
|
||||
for (int i = 0; i < 30; i++)
|
||||
{
|
||||
if (!m_IsDownloading)
|
||||
{
|
||||
LogPrint (eLogInfo, "Addressbook: subscriptions download complete");
|
||||
LogPrint (eLogInfo, "Addressbook: Subscriptions download complete");
|
||||
break;
|
||||
}
|
||||
std::this_thread::sleep_for (std::chrono::seconds (1)); // wait for 1 seconds
|
||||
}
|
||||
LogPrint (eLogError, "Addressbook: subscription download timeout");
|
||||
LogPrint (eLogError, "Addressbook: Subscription download timeout");
|
||||
m_IsDownloading = false;
|
||||
}
|
||||
if (m_Storage)
|
||||
|
@ -397,7 +397,7 @@ namespace client
|
|||
if (pos != std::string::npos)
|
||||
{
|
||||
m_Addresses[address] = std::make_shared<Address>(jump.substr (0, pos));
|
||||
LogPrint (eLogInfo, "Addressbook: added ", address," -> ", jump);
|
||||
LogPrint (eLogInfo, "Addressbook: Added ", address," -> ", jump);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -407,10 +407,10 @@ namespace client
|
|||
{
|
||||
m_Storage->AddAddress (ident);
|
||||
m_Addresses[address] = std::make_shared<Address>(ident->GetIdentHash ());
|
||||
LogPrint (eLogInfo, "Addressbook: added ", address," -> ", ToAddress(ident->GetIdentHash ()));
|
||||
LogPrint (eLogInfo, "Addressbook: Added ", address," -> ", ToAddress(ident->GetIdentHash ()));
|
||||
}
|
||||
else
|
||||
LogPrint (eLogError, "Addressbook: malformed address ", jump);
|
||||
LogPrint (eLogError, "Addressbook: Malformed address ", jump);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -472,7 +472,7 @@ namespace client
|
|||
|
||||
auto ident = std::make_shared<i2p::data::IdentityEx> ();
|
||||
if (!ident->FromBase64(addr)) {
|
||||
LogPrint (eLogError, "Addressbook: malformed address ", addr, " for ", name);
|
||||
LogPrint (eLogError, "Addressbook: Malformed address ", addr, " for ", name);
|
||||
incomplete = f.eof ();
|
||||
continue;
|
||||
}
|
||||
|
@ -481,12 +481,12 @@ namespace client
|
|||
if (it != m_Addresses.end ()) // already exists ?
|
||||
{
|
||||
if (it->second->IsIdentHash () && it->second->identHash != ident->GetIdentHash () && // address changed?
|
||||
ident->GetSigningKeyType () != i2p::data::SIGNING_KEY_TYPE_DSA_SHA1) // don't replace by DSA
|
||||
ident->GetSigningKeyType () != i2p::data::SIGNING_KEY_TYPE_DSA_SHA1) // don't replace by DSA
|
||||
{
|
||||
it->second->identHash = ident->GetIdentHash ();
|
||||
m_Storage->AddAddress (ident);
|
||||
m_Storage->RemoveAddress (it->second->identHash);
|
||||
LogPrint (eLogInfo, "Addressbook: updated host: ", name);
|
||||
LogPrint (eLogInfo, "Addressbook: Updated host: ", name);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -494,7 +494,7 @@ namespace client
|
|||
m_Addresses.emplace (name, std::make_shared<Address>(ident->GetIdentHash ()));
|
||||
m_Storage->AddAddress (ident);
|
||||
if (is_update)
|
||||
LogPrint (eLogInfo, "Addressbook: added new host: ", name);
|
||||
LogPrint (eLogInfo, "Addressbook: Added new host: ", name);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -523,7 +523,7 @@ namespace client
|
|||
if (s.empty () || s[0] == '#') continue; // skip empty line or comment
|
||||
m_Subscriptions.push_back (std::make_shared<AddressBookSubscription> (*this, s));
|
||||
}
|
||||
LogPrint (eLogInfo, "Addressbook: ", m_Subscriptions.size (), " subscriptions urls loaded");
|
||||
LogPrint (eLogInfo, "Addressbook: ", m_Subscriptions.size (), " subscriptions URLs loaded");
|
||||
LogPrint (eLogWarning, "Addressbook: subscriptions.txt usage is deprecated, use config file instead");
|
||||
}
|
||||
else if (!i2p::config::IsDefault("addressbook.subscriptions"))
|
||||
|
@ -538,11 +538,11 @@ namespace client
|
|||
if (s.empty () || s[0] == '#') continue; // skip empty line or comment
|
||||
m_Subscriptions.push_back (std::make_shared<AddressBookSubscription> (*this, s));
|
||||
}
|
||||
LogPrint (eLogInfo, "Addressbook: ", m_Subscriptions.size (), " subscriptions urls loaded");
|
||||
LogPrint (eLogInfo, "Addressbook: ", m_Subscriptions.size (), " subscriptions URLs loaded");
|
||||
}
|
||||
}
|
||||
else
|
||||
LogPrint (eLogError, "Addressbook: subscriptions already loaded");
|
||||
LogPrint (eLogError, "Addressbook: Subscriptions already loaded");
|
||||
}
|
||||
|
||||
void AddressBook::LoadLocal ()
|
||||
|
@ -627,7 +627,7 @@ namespace client
|
|||
this, std::placeholders::_1));
|
||||
}
|
||||
else
|
||||
LogPrint (eLogError, "Addressbook: can't start subscriptions: missing shared local destination");
|
||||
LogPrint (eLogError, "Addressbook: Can't start subscriptions: missing shared local destination");
|
||||
}
|
||||
|
||||
void AddressBook::StopSubscriptions ()
|
||||
|
@ -642,7 +642,7 @@ namespace client
|
|||
{
|
||||
auto dest = i2p::client::context.GetSharedLocalDestination ();
|
||||
if (!dest) {
|
||||
LogPrint(eLogWarning, "Addressbook: missing local destination, skip subscription update");
|
||||
LogPrint(eLogWarning, "Addressbook: Missing local destination, skip subscription update");
|
||||
return;
|
||||
}
|
||||
if (!m_IsDownloading && dest->IsReady ())
|
||||
|
@ -788,7 +788,7 @@ namespace client
|
|||
LogPrint (eLogInfo, "Addressbook: Downloading hosts database from ", m_Link);
|
||||
if (!url.parse(m_Link))
|
||||
{
|
||||
LogPrint(eLogError, "Addressbook: failed to parse url: ", m_Link);
|
||||
LogPrint(eLogError, "Addressbook: Failed to parse URL: ", m_Link);
|
||||
return false;
|
||||
}
|
||||
auto addr = m_Book.GetAddress (url.host);
|
||||
|
@ -827,7 +827,7 @@ namespace client
|
|||
}
|
||||
if (m_Etag.empty() && m_LastModified.empty()) {
|
||||
m_Book.GetEtag (m_Ident, m_Etag, m_LastModified);
|
||||
LogPrint (eLogDebug, "Addressbook: loaded for ", url.host, ": ETag: ", m_Etag, ", Last-Modified: ", m_LastModified);
|
||||
LogPrint (eLogDebug, "Addressbook: Loaded for ", url.host, ": ETag: ", m_Etag, ", Last-Modified: ", m_LastModified);
|
||||
}
|
||||
/* save url parts for later use */
|
||||
std::string dest_host = url.host;
|
||||
|
@ -872,7 +872,7 @@ namespace client
|
|||
// wait 1 more second
|
||||
if (newDataReceived.wait_for (l, std::chrono::seconds (SUBSCRIPTION_REQUEST_TIMEOUT + 1)) == std::cv_status::timeout)
|
||||
{
|
||||
LogPrint (eLogError, "Addressbook: subscriptions request timeout expired");
|
||||
LogPrint (eLogError, "Addressbook: Subscriptions request timeout expired");
|
||||
numAttempts++;
|
||||
if (numAttempts > 5) end = true;
|
||||
}
|
||||
|
@ -885,35 +885,35 @@ namespace client
|
|||
int res_head_len = res.parse(response);
|
||||
if (res_head_len < 0)
|
||||
{
|
||||
LogPrint(eLogError, "Addressbook: can't parse http response from ", dest_host);
|
||||
LogPrint(eLogError, "Addressbook: Can't parse HTTP response from ", dest_host);
|
||||
return false;
|
||||
}
|
||||
if (res_head_len == 0)
|
||||
{
|
||||
LogPrint(eLogError, "Addressbook: incomplete http response from ", dest_host, ", interrupted by timeout");
|
||||
LogPrint(eLogError, "Addressbook: Incomplete HTTP response from ", dest_host, ", interrupted by timeout");
|
||||
return false;
|
||||
}
|
||||
/* assert: res_head_len > 0 */
|
||||
response.erase(0, res_head_len);
|
||||
if (res.code == 304)
|
||||
{
|
||||
LogPrint (eLogInfo, "Addressbook: no updates from ", dest_host, ", code 304");
|
||||
LogPrint (eLogInfo, "Addressbook: No updates from ", dest_host, ", code 304");
|
||||
return false;
|
||||
}
|
||||
if (res.code != 200)
|
||||
{
|
||||
LogPrint (eLogWarning, "Adressbook: can't get updates from ", dest_host, ", response code ", res.code);
|
||||
LogPrint (eLogWarning, "Adressbook: Can't get updates from ", dest_host, ", response code ", res.code);
|
||||
return false;
|
||||
}
|
||||
int len = res.content_length();
|
||||
if (response.empty())
|
||||
{
|
||||
LogPrint(eLogError, "Addressbook: empty response from ", dest_host, ", expected ", len, " bytes");
|
||||
LogPrint(eLogError, "Addressbook: Empty response from ", dest_host, ", expected ", len, " bytes");
|
||||
return false;
|
||||
}
|
||||
if (!res.is_gzipped () && len > 0 && len != (int) response.length())
|
||||
{
|
||||
LogPrint(eLogError, "Addressbook: response size mismatch, expected: ", len, ", got: ", response.length(), "bytes");
|
||||
LogPrint(eLogError, "Addressbook: Response size mismatch, expected: ", len, ", got: ", response.length(), "bytes");
|
||||
return false;
|
||||
}
|
||||
/* assert: res.code == 200 */
|
||||
|
@ -934,13 +934,13 @@ namespace client
|
|||
inflator.Inflate ((const uint8_t *) response.data(), response.length(), out);
|
||||
if (out.fail())
|
||||
{
|
||||
LogPrint(eLogError, "Addressbook: can't gunzip http response");
|
||||
LogPrint(eLogError, "Addressbook: Can't gunzip http response");
|
||||
return false;
|
||||
}
|
||||
response = out.str();
|
||||
}
|
||||
std::stringstream ss(response);
|
||||
LogPrint (eLogInfo, "Addressbook: got update from ", dest_host);
|
||||
LogPrint (eLogInfo, "Addressbook: Got update from ", dest_host);
|
||||
m_Book.LoadHostsFromStream (ss, true);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -660,7 +660,7 @@ namespace client
|
|||
else
|
||||
SendReplyError ("Local LeaseSet Not found");
|
||||
}
|
||||
|
||||
|
||||
void BOBCommandSession::ClearCommandHandler (const char * operand, size_t len)
|
||||
{
|
||||
LogPrint (eLogDebug, "BOB: clear");
|
||||
|
@ -786,7 +786,7 @@ namespace client
|
|||
m_CommandHandlers[BOB_COMMAND_INPORT] = &BOBCommandSession::InportCommandHandler;
|
||||
m_CommandHandlers[BOB_COMMAND_QUIET] = &BOBCommandSession::QuietCommandHandler;
|
||||
m_CommandHandlers[BOB_COMMAND_LOOKUP] = &BOBCommandSession::LookupCommandHandler;
|
||||
m_CommandHandlers[BOB_COMMAND_LOOKUP_LOCAL] = &BOBCommandSession::LookupLocalCommandHandler;
|
||||
m_CommandHandlers[BOB_COMMAND_LOOKUP_LOCAL] = &BOBCommandSession::LookupLocalCommandHandler;
|
||||
m_CommandHandlers[BOB_COMMAND_CLEAR] = &BOBCommandSession::ClearCommandHandler;
|
||||
m_CommandHandlers[BOB_COMMAND_LIST] = &BOBCommandSession::ListCommandHandler;
|
||||
m_CommandHandlers[BOB_COMMAND_OPTION] = &BOBCommandSession::OptionCommandHandler;
|
||||
|
@ -880,7 +880,7 @@ namespace client
|
|||
session->SendVersion ();
|
||||
}
|
||||
else
|
||||
LogPrint (eLogError, "BOB: accept error: ", ecode.message ());
|
||||
LogPrint (eLogError, "BOB: Accept error: ", ecode.message ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -567,7 +567,7 @@ namespace client
|
|||
Connect (leaseSet);
|
||||
else
|
||||
{
|
||||
LogPrint (eLogError, "SAM: destination to connect not found");
|
||||
LogPrint (eLogError, "SAM: Destination to connect not found");
|
||||
SendMessageReply (SAM_STREAM_STATUS_CANT_REACH_PEER, strlen(SAM_STREAM_STATUS_CANT_REACH_PEER), true);
|
||||
}
|
||||
}
|
||||
|
@ -603,7 +603,7 @@ namespace client
|
|||
|
||||
void SAMSocket::ProcessStreamForward (char * buf, size_t len)
|
||||
{
|
||||
LogPrint (eLogDebug, "SAM: stream forward: ", buf);
|
||||
LogPrint (eLogDebug, "SAM: Stream forward: ", buf);
|
||||
std::map<std::string, std::string> params;
|
||||
ExtractParams (buf, params);
|
||||
std::string& id = params[SAM_PARAM_ID];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue