mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-22 13:27:17 +01:00
save and use previous routing session
This commit is contained in:
parent
d3062d2994
commit
0153748134
|
@ -234,16 +234,24 @@ namespace client
|
||||||
else
|
else
|
||||||
remoteSession->SetSharedRoutingPath (nullptr);
|
remoteSession->SetSharedRoutingPath (nullptr);
|
||||||
}
|
}
|
||||||
|
m_Owner->AddRoutingSession (remote->GetIdentity ()->GetStandardIdentity ().signingKey - 96, remoteSession); // last 32 bytes
|
||||||
|
return SendMsg (garlic, outboundTunnel, remoteLease);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool I2CPDestination::SendMsg (std::shared_ptr<I2NPMessage> garlic,
|
||||||
|
std::shared_ptr<i2p::tunnel::OutboundTunnel> outboundTunnel, std::shared_ptr<const i2p::data::Lease> remoteLease)
|
||||||
|
{
|
||||||
if (remoteLease && outboundTunnel)
|
if (remoteLease && outboundTunnel)
|
||||||
{
|
{
|
||||||
std::vector<i2p::tunnel::TunnelMessageBlock> msgs;
|
outboundTunnel->SendTunnelDataMsgs (
|
||||||
msgs.push_back (i2p::tunnel::TunnelMessageBlock
|
{
|
||||||
{
|
i2p::tunnel::TunnelMessageBlock
|
||||||
i2p::tunnel::eDeliveryTypeTunnel,
|
{
|
||||||
remoteLease->tunnelGateway, remoteLease->tunnelID,
|
i2p::tunnel::eDeliveryTypeTunnel,
|
||||||
garlic
|
remoteLease->tunnelGateway, remoteLease->tunnelID,
|
||||||
|
garlic
|
||||||
|
}
|
||||||
});
|
});
|
||||||
outboundTunnel->SendTunnelDataMsgs (msgs);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -253,9 +261,43 @@ namespace client
|
||||||
else
|
else
|
||||||
LogPrint (eLogWarning, "I2CP: Failed to send message. No outbound tunnels");
|
LogPrint (eLogWarning, "I2CP: Failed to send message. No outbound tunnels");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool I2CPDestination::SendMsg (const uint8_t * payload, size_t len,
|
||||||
|
std::shared_ptr<i2p::garlic::GarlicRoutingSession> remoteSession, uint32_t nonce)
|
||||||
|
{
|
||||||
|
if (!remoteSession) return false;
|
||||||
|
auto path = remoteSession->GetSharedRoutingPath ();
|
||||||
|
if (!path) return false;
|
||||||
|
// get tunnels
|
||||||
|
std::shared_ptr<i2p::tunnel::OutboundTunnel> outboundTunnel;
|
||||||
|
std::shared_ptr<const i2p::data::Lease> remoteLease;
|
||||||
|
if (!remoteSession->CleanupUnconfirmedTags ()) // no stuck tags
|
||||||
|
{
|
||||||
|
outboundTunnel = path->outboundTunnel;
|
||||||
|
remoteLease = path->remoteLease;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
remoteSession->SetSharedRoutingPath (nullptr);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// create Data message
|
||||||
|
auto msg = m_I2NPMsgsPool.AcquireSharedMt ();
|
||||||
|
uint8_t * buf = msg->GetPayload ();
|
||||||
|
htobe32buf (buf, len);
|
||||||
|
memcpy (buf + 4, payload, len);
|
||||||
|
msg->len += len + 4;
|
||||||
|
msg->FillI2NPMessageHeader (eI2NPData);
|
||||||
|
// wrap in gralic
|
||||||
|
auto garlic = remoteSession->WrapSingleMessage (msg);
|
||||||
|
// send
|
||||||
|
bool sent = SendMsg (garlic, outboundTunnel, remoteLease);
|
||||||
|
m_Owner->SendMessageStatusMessage (nonce, eI2CPMessageStatusGuaranteedSuccess);
|
||||||
|
return sent;
|
||||||
|
}
|
||||||
|
|
||||||
RunnableI2CPDestination::RunnableI2CPDestination (std::shared_ptr<I2CPSession> owner,
|
RunnableI2CPDestination::RunnableI2CPDestination (std::shared_ptr<I2CPSession> owner,
|
||||||
std::shared_ptr<const i2p::data::IdentityEx> identity, bool isPublic, const std::map<std::string, std::string>& params):
|
std::shared_ptr<const i2p::data::IdentityEx> identity, bool isPublic, const std::map<std::string, std::string>& params):
|
||||||
RunnableService ("I2CP"),
|
RunnableService ("I2CP"),
|
||||||
|
@ -707,6 +749,13 @@ namespace client
|
||||||
SendI2CPMessage (I2CP_MESSAGE_STATUS_MESSAGE, buf, 15);
|
SendI2CPMessage (I2CP_MESSAGE_STATUS_MESSAGE, buf, 15);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void I2CPSession::AddRoutingSession (const i2p::data::IdentHash& signingKey, std::shared_ptr<i2p::garlic::GarlicRoutingSession> remoteSession)
|
||||||
|
{
|
||||||
|
if (!remoteSession) return;
|
||||||
|
std::lock_guard<std::mutex> l(m_RoutingSessionsMutex);
|
||||||
|
m_RoutingSessions[signingKey] = remoteSession;
|
||||||
|
}
|
||||||
|
|
||||||
void I2CPSession::CreateLeaseSetMessageHandler (const uint8_t * buf, size_t len)
|
void I2CPSession::CreateLeaseSetMessageHandler (const uint8_t * buf, size_t len)
|
||||||
{
|
{
|
||||||
uint16_t sessionID = bufbe16toh (buf);
|
uint16_t sessionID = bufbe16toh (buf);
|
||||||
|
@ -777,11 +826,10 @@ namespace client
|
||||||
size_t offset = 2;
|
size_t offset = 2;
|
||||||
if (m_Destination)
|
if (m_Destination)
|
||||||
{
|
{
|
||||||
size_t identSize = i2p::data::GetIdentityBufferLen (buf + offset, len - offset);
|
const uint8_t * ident = buf + offset;
|
||||||
|
size_t identSize = i2p::data::GetIdentityBufferLen (ident, len - offset);
|
||||||
if (identSize)
|
if (identSize)
|
||||||
{
|
{
|
||||||
i2p::data::IdentHash identHash;
|
|
||||||
SHA256(buf + offset, identSize, identHash); // caclulate ident hash, because we don't need full identity
|
|
||||||
offset += identSize;
|
offset += identSize;
|
||||||
uint32_t payloadLen = bufbe32toh (buf + offset);
|
uint32_t payloadLen = bufbe32toh (buf + offset);
|
||||||
if (payloadLen + offset <= len)
|
if (payloadLen + offset <= len)
|
||||||
|
@ -792,10 +840,30 @@ namespace client
|
||||||
{
|
{
|
||||||
if (m_IsSendAccepted)
|
if (m_IsSendAccepted)
|
||||||
SendMessageStatusMessage (nonce, eI2CPMessageStatusAccepted); // accepted
|
SendMessageStatusMessage (nonce, eI2CPMessageStatusAccepted); // accepted
|
||||||
m_Destination->SendMsgTo (buf + offset, payloadLen, identHash, nonce);
|
std::shared_ptr<i2p::garlic::GarlicRoutingSession> remoteSession;
|
||||||
}
|
{
|
||||||
|
std::lock_guard<std::mutex> l(m_RoutingSessionsMutex);
|
||||||
|
auto it = m_RoutingSessions.find (ident + i2p::data::DEFAULT_IDENTITY_SIZE - 35); // 32 bytes signing key
|
||||||
|
if (it != m_RoutingSessions.end ())
|
||||||
|
{
|
||||||
|
if (!it->second->IsTerminated ())
|
||||||
|
remoteSession = it->second;
|
||||||
|
else
|
||||||
|
m_RoutingSessions.erase (it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!remoteSession || !m_Destination->SendMsg (buf + offset, payloadLen, remoteSession, nonce))
|
||||||
|
{
|
||||||
|
i2p::data::IdentHash identHash;
|
||||||
|
SHA256(ident, identSize, identHash); // caclulate ident hash, because we don't need full identity
|
||||||
|
m_Destination->SendMsgTo (buf + offset, payloadLen, identHash, nonce);
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
LogPrint(eLogInfo, "I2CP: Destination is not ready");
|
||||||
SendMessageStatusMessage (nonce, eI2CPMessageStatusNoLocalTunnels);
|
SendMessageStatusMessage (nonce, eI2CPMessageStatusNoLocalTunnels);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint(eLogError, "I2CP: Cannot send message, too big");
|
LogPrint(eLogError, "I2CP: Cannot send message, too big");
|
||||||
|
|
|
@ -12,8 +12,10 @@
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <unordered_map>
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "Destination.h"
|
#include "Destination.h"
|
||||||
|
@ -92,7 +94,8 @@ namespace client
|
||||||
void LeaseSetCreated (const uint8_t * buf, size_t len); // called from I2CPSession
|
void LeaseSetCreated (const uint8_t * buf, size_t len); // called from I2CPSession
|
||||||
void LeaseSet2Created (uint8_t storeType, const uint8_t * buf, size_t len); // called from I2CPSession
|
void LeaseSet2Created (uint8_t storeType, const uint8_t * buf, size_t len); // called from I2CPSession
|
||||||
void SendMsgTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash& ident, uint32_t nonce); // called from I2CPSession
|
void SendMsgTo (const uint8_t * payload, size_t len, const i2p::data::IdentHash& ident, uint32_t nonce); // called from I2CPSession
|
||||||
|
bool SendMsg (const uint8_t * payload, size_t len, std::shared_ptr<i2p::garlic::GarlicRoutingSession> remoteSession, uint32_t nonce);
|
||||||
|
|
||||||
// implements LocalDestination
|
// implements LocalDestination
|
||||||
bool Decrypt (const uint8_t * encrypted, uint8_t * data, i2p::data::CryptoKeyType preferredCrypto) const;
|
bool Decrypt (const uint8_t * encrypted, uint8_t * data, i2p::data::CryptoKeyType preferredCrypto) const;
|
||||||
bool SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const;
|
bool SupportsEncryptionType (i2p::data::CryptoKeyType keyType) const;
|
||||||
|
@ -110,7 +113,9 @@ namespace client
|
||||||
std::shared_ptr<I2CPDestination> GetSharedFromThis ()
|
std::shared_ptr<I2CPDestination> GetSharedFromThis ()
|
||||||
{ return std::static_pointer_cast<I2CPDestination>(shared_from_this ()); }
|
{ return std::static_pointer_cast<I2CPDestination>(shared_from_this ()); }
|
||||||
bool SendMsg (std::shared_ptr<I2NPMessage> msg, std::shared_ptr<const i2p::data::LeaseSet> remote);
|
bool SendMsg (std::shared_ptr<I2NPMessage> msg, std::shared_ptr<const i2p::data::LeaseSet> remote);
|
||||||
|
bool SendMsg (std::shared_ptr<I2NPMessage> garlic,
|
||||||
|
std::shared_ptr<i2p::tunnel::OutboundTunnel> outboundTunnel, std::shared_ptr<const i2p::data::Lease> remoteLease);
|
||||||
|
|
||||||
void PostCreateNewLeaseSet (std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> > tunnels);
|
void PostCreateNewLeaseSet (std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> > tunnels);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -157,6 +162,7 @@ namespace client
|
||||||
void SendI2CPMessage (uint8_t type, const uint8_t * payload, size_t len);
|
void SendI2CPMessage (uint8_t type, const uint8_t * payload, size_t len);
|
||||||
void SendMessagePayloadMessage (const uint8_t * payload, size_t len);
|
void SendMessagePayloadMessage (const uint8_t * payload, size_t len);
|
||||||
void SendMessageStatusMessage (uint32_t nonce, I2CPMessageStatus status);
|
void SendMessageStatusMessage (uint32_t nonce, I2CPMessageStatus status);
|
||||||
|
void AddRoutingSession (const i2p::data::IdentHash& signingKey, std::shared_ptr<i2p::garlic::GarlicRoutingSession> remoteSession);
|
||||||
|
|
||||||
// message handlers
|
// message handlers
|
||||||
void GetDateMessageHandler (const uint8_t * buf, size_t len);
|
void GetDateMessageHandler (const uint8_t * buf, size_t len);
|
||||||
|
@ -197,6 +203,8 @@ namespace client
|
||||||
size_t m_PayloadLen;
|
size_t m_PayloadLen;
|
||||||
|
|
||||||
std::shared_ptr<I2CPDestination> m_Destination;
|
std::shared_ptr<I2CPDestination> m_Destination;
|
||||||
|
std::mutex m_RoutingSessionsMutex;
|
||||||
|
std::unordered_map<i2p::data::IdentHash, std::shared_ptr<i2p::garlic::GarlicRoutingSession> > m_RoutingSessions; // signing key->session
|
||||||
uint16_t m_SessionID;
|
uint16_t m_SessionID;
|
||||||
uint32_t m_MessageID;
|
uint32_t m_MessageID;
|
||||||
bool m_IsSendAccepted;
|
bool m_IsSendAccepted;
|
||||||
|
@ -226,8 +234,6 @@ namespace client
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void Run ();
|
|
||||||
|
|
||||||
void Accept ();
|
void Accept ();
|
||||||
|
|
||||||
void HandleAccept(const boost::system::error_code& ecode, std::shared_ptr<boost::asio::ip::tcp::socket> socket);
|
void HandleAccept(const boost::system::error_code& ecode, std::shared_ptr<boost::asio::ip::tcp::socket> socket);
|
||||||
|
|
Loading…
Reference in a new issue