mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-22 04:04:16 +00:00
Merge branch 'master' of https://github.com/orignal/i2pd
This commit is contained in:
commit
370324d119
38
NetDb.cpp
38
NetDb.cpp
@ -448,10 +448,18 @@ namespace data
|
|||||||
{
|
{
|
||||||
auto r = FindRouter (router);
|
auto r = FindRouter (router);
|
||||||
// do we have that floodfill router in our database?
|
// do we have that floodfill router in our database?
|
||||||
if (r)
|
if (r)
|
||||||
{
|
{
|
||||||
|
// we do
|
||||||
if (!dest->IsExcluded (r->GetIdentHash ()) && dest->GetNumExcludedPeers () < 30) // TODO: fix TunnelGateway first
|
if (!dest->IsExcluded (r->GetIdentHash ()) && dest->GetNumExcludedPeers () < 30) // TODO: fix TunnelGateway first
|
||||||
{
|
{
|
||||||
|
// tell floodfill about us
|
||||||
|
msgs.push_back (i2p::tunnel::TunnelMessageBlock
|
||||||
|
{
|
||||||
|
i2p::tunnel::eDeliveryTypeRouter,
|
||||||
|
r->GetIdentHash (), 0,
|
||||||
|
CreateDatabaseStoreMsg ()
|
||||||
|
});
|
||||||
// request destination
|
// request destination
|
||||||
auto msg = dest->CreateRequestMessage (r, dest->GetLastReplyTunnel ());
|
auto msg = dest->CreateRequestMessage (r, dest->GetLastReplyTunnel ());
|
||||||
msgs.push_back (i2p::tunnel::TunnelMessageBlock
|
msgs.push_back (i2p::tunnel::TunnelMessageBlock
|
||||||
@ -506,16 +514,15 @@ namespace data
|
|||||||
auto inbound = i2p::tunnel::tunnels.GetNextInboundTunnel ();
|
auto inbound = i2p::tunnel::tunnels.GetNextInboundTunnel ();
|
||||||
if (outbound && inbound)
|
if (outbound && inbound)
|
||||||
{
|
{
|
||||||
auto floodfill = GetRandomRouter (outbound->GetEndpointRouter (), true);
|
CryptoPP::RandomNumberGenerator& rnd = i2p::context.GetRandomNumberGenerator ();
|
||||||
|
uint8_t randomHash[32];
|
||||||
|
rnd.GenerateBlock (randomHash, 32);
|
||||||
|
RequestedDestination * dest = CreateRequestedDestination (IdentHash (randomHash), false, true);
|
||||||
|
dest->SetLastOutboundTunnel (outbound);
|
||||||
|
auto floodfill = GetClosestFloodfill (randomHash, dest->GetExcludedPeers ());
|
||||||
if (floodfill)
|
if (floodfill)
|
||||||
{
|
{
|
||||||
LogPrint ("Exploring new routers ...");
|
LogPrint ("Exploring new routers ...");
|
||||||
CryptoPP::RandomNumberGenerator& rnd = i2p::context.GetRandomNumberGenerator ();
|
|
||||||
uint8_t randomHash[32];
|
|
||||||
rnd.GenerateBlock (randomHash, 32);
|
|
||||||
RequestedDestination * dest = CreateRequestedDestination (IdentHash (randomHash), false, true);
|
|
||||||
dest->SetLastOutboundTunnel (outbound);
|
|
||||||
|
|
||||||
std::vector<i2p::tunnel::TunnelMessageBlock> msgs;
|
std::vector<i2p::tunnel::TunnelMessageBlock> msgs;
|
||||||
msgs.push_back (i2p::tunnel::TunnelMessageBlock
|
msgs.push_back (i2p::tunnel::TunnelMessageBlock
|
||||||
{
|
{
|
||||||
@ -529,8 +536,10 @@ namespace data
|
|||||||
floodfill->GetIdentHash (), 0,
|
floodfill->GetIdentHash (), 0,
|
||||||
dest->CreateRequestMessage (floodfill, inbound) // explore
|
dest->CreateRequestMessage (floodfill, inbound) // explore
|
||||||
});
|
});
|
||||||
outbound->SendTunnelDataMsg (msgs);
|
outbound->SendTunnelDataMsg (msgs);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
DeleteRequestedDestination (dest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -557,6 +566,15 @@ namespace data
|
|||||||
m_RequestedDestinations.erase (it);
|
m_RequestedDestinations.erase (it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NetDb::DeleteRequestedDestination (RequestedDestination * dest)
|
||||||
|
{
|
||||||
|
if (dest)
|
||||||
|
{
|
||||||
|
m_RequestedDestinations.erase (dest->GetDestination ());
|
||||||
|
delete dest;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const RouterInfo * NetDb::GetRandomNTCPRouter (bool floodfillOnly) const
|
const RouterInfo * NetDb::GetRandomNTCPRouter (bool floodfillOnly) const
|
||||||
{
|
{
|
||||||
|
1
NetDb.h
1
NetDb.h
@ -87,6 +87,7 @@ namespace data
|
|||||||
RequestedDestination * CreateRequestedDestination (const IdentHash& dest,
|
RequestedDestination * CreateRequestedDestination (const IdentHash& dest,
|
||||||
bool isLeaseSet, bool isExploratory = false);
|
bool isLeaseSet, bool isExploratory = false);
|
||||||
void DeleteRequestedDestination (const IdentHash& dest);
|
void DeleteRequestedDestination (const IdentHash& dest);
|
||||||
|
void DeleteRequestedDestination (RequestedDestination * dest);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
138
SSU.cpp
138
SSU.cpp
@ -47,6 +47,7 @@ namespace ssu
|
|||||||
{
|
{
|
||||||
switch (m_State)
|
switch (m_State)
|
||||||
{
|
{
|
||||||
|
case eSessionStateConfirmedSent:
|
||||||
case eSessionStateEstablished:
|
case eSessionStateEstablished:
|
||||||
// most common case
|
// most common case
|
||||||
ProcessMessage (buf, len);
|
ProcessMessage (buf, len);
|
||||||
@ -86,23 +87,38 @@ namespace ssu
|
|||||||
LogPrint ("SSU test received");
|
LogPrint ("SSU test received");
|
||||||
break;
|
break;
|
||||||
case PAYLOAD_TYPE_SESSION_DESTROYED:
|
case PAYLOAD_TYPE_SESSION_DESTROYED:
|
||||||
|
{
|
||||||
LogPrint ("SSU session destroy received");
|
LogPrint ("SSU session destroy received");
|
||||||
|
if (m_Server)
|
||||||
|
m_Server->DeleteSession (this); // delete this
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LogPrint ("Unexpected SSU payload type ", (int)payloadType);
|
LogPrint ("Unexpected SSU payload type ", (int)payloadType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: try intro key as well
|
|
||||||
else
|
else
|
||||||
LogPrint ("MAC verifcation failed");
|
{
|
||||||
|
LogPrint ("MAC key failed. Trying intro key");
|
||||||
|
auto introKey = GetIntroKey ();
|
||||||
|
if (introKey && Validate (buf, len, introKey))
|
||||||
|
{
|
||||||
|
Decrypt (buf, len, introKey);
|
||||||
|
SSUHeader * header = (SSUHeader *)buf;
|
||||||
|
LogPrint ("Unexpected SSU payload type ", (int)(header->flag >> 4));
|
||||||
|
// TODO:
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LogPrint ("MAC verifcation failed");
|
||||||
|
m_State = eSessionStateUnknown;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSUSession::ProcessSessionRequest (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint)
|
void SSUSession::ProcessSessionRequest (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint)
|
||||||
{
|
{
|
||||||
LogPrint ("Process session request");
|
LogPrint ("Process session request");
|
||||||
// use our intro key
|
// use our intro key
|
||||||
if (ProcessIntroKeyEncryptedMessage (PAYLOAD_TYPE_SESSION_REQUEST,
|
if (ProcessIntroKeyEncryptedMessage (PAYLOAD_TYPE_SESSION_REQUEST, buf, len))
|
||||||
i2p::context.GetRouterInfo (), buf, len))
|
|
||||||
{
|
{
|
||||||
m_State = eSessionStateRequestReceived;
|
m_State = eSessionStateRequestReceived;
|
||||||
LogPrint ("Session request received");
|
LogPrint ("Session request received");
|
||||||
@ -121,7 +137,7 @@ namespace ssu
|
|||||||
}
|
}
|
||||||
|
|
||||||
// use remote intro key
|
// use remote intro key
|
||||||
if (ProcessIntroKeyEncryptedMessage (PAYLOAD_TYPE_SESSION_CREATED, *m_RemoteRouter, buf, len))
|
if (ProcessIntroKeyEncryptedMessage (PAYLOAD_TYPE_SESSION_CREATED, buf, len))
|
||||||
{
|
{
|
||||||
m_State = eSessionStateCreatedReceived;
|
m_State = eSessionStateCreatedReceived;
|
||||||
LogPrint ("Session created received");
|
LogPrint ("Session created received");
|
||||||
@ -132,8 +148,6 @@ namespace ssu
|
|||||||
i2p::context.UpdateAddress (ourIP.to_string ().c_str ());
|
i2p::context.UpdateAddress (ourIP.to_string ().c_str ());
|
||||||
uint32_t relayTag = be32toh (*(uint32_t *)(buf + sizeof (SSUHeader) + 263));
|
uint32_t relayTag = be32toh (*(uint32_t *)(buf + sizeof (SSUHeader) + 263));
|
||||||
SendSessionConfirmed (buf + sizeof (SSUHeader), ourAddress, relayTag);
|
SendSessionConfirmed (buf + sizeof (SSUHeader), ourAddress, relayTag);
|
||||||
m_State = eSessionStateEstablished;
|
|
||||||
Established ();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,9 +161,9 @@ namespace ssu
|
|||||||
if ((header->flag >> 4) == PAYLOAD_TYPE_SESSION_CONFIRMED)
|
if ((header->flag >> 4) == PAYLOAD_TYPE_SESSION_CONFIRMED)
|
||||||
{
|
{
|
||||||
m_State = eSessionStateConfirmedReceived;
|
m_State = eSessionStateConfirmedReceived;
|
||||||
LogPrint ("Session confirmed received");
|
LogPrint ("Session confirmed received");
|
||||||
// TODO:
|
|
||||||
m_State = eSessionStateEstablished;
|
m_State = eSessionStateEstablished;
|
||||||
|
// TODO: send DeliverStatus
|
||||||
Established ();
|
Established ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -161,10 +175,10 @@ namespace ssu
|
|||||||
|
|
||||||
void SSUSession::SendSessionRequest ()
|
void SSUSession::SendSessionRequest ()
|
||||||
{
|
{
|
||||||
auto address = m_RemoteRouter ? m_RemoteRouter->GetSSUAddress () : nullptr;
|
auto introKey = GetIntroKey ();
|
||||||
if (!address)
|
if (!introKey)
|
||||||
{
|
{
|
||||||
LogPrint ("Missing remote SSU address");
|
LogPrint ("SSU is not supported");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,7 +191,7 @@ namespace ssu
|
|||||||
uint8_t iv[16];
|
uint8_t iv[16];
|
||||||
CryptoPP::RandomNumberGenerator& rnd = i2p::context.GetRandomNumberGenerator ();
|
CryptoPP::RandomNumberGenerator& rnd = i2p::context.GetRandomNumberGenerator ();
|
||||||
rnd.GenerateBlock (iv, 16); // random iv
|
rnd.GenerateBlock (iv, 16); // random iv
|
||||||
FillHeaderAndEncrypt (PAYLOAD_TYPE_SESSION_REQUEST, buf, 304, address->key, iv, address->key);
|
FillHeaderAndEncrypt (PAYLOAD_TYPE_SESSION_REQUEST, buf, 304, introKey, iv, introKey);
|
||||||
|
|
||||||
m_State = eSessionStateRequestSent;
|
m_State = eSessionStateRequestSent;
|
||||||
m_Server->Send (buf, 304, m_RemoteEndpoint);
|
m_Server->Send (buf, 304, m_RemoteEndpoint);
|
||||||
@ -185,10 +199,10 @@ namespace ssu
|
|||||||
|
|
||||||
void SSUSession::SendSessionCreated (const uint8_t * x)
|
void SSUSession::SendSessionCreated (const uint8_t * x)
|
||||||
{
|
{
|
||||||
auto address = m_RemoteRouter ? m_RemoteRouter->GetSSUAddress () : nullptr;
|
auto introKey = GetIntroKey ();
|
||||||
if (!address)
|
if (!introKey)
|
||||||
{
|
{
|
||||||
LogPrint ("Missing remote SSU address");
|
LogPrint ("SSU is not supported");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint8_t signedData[532]; // x,y, remote IP, remote port, our IP, our port, relayTag, signed on time
|
uint8_t signedData[532]; // x,y, remote IP, remote port, our IP, our port, relayTag, signed on time
|
||||||
@ -224,20 +238,13 @@ namespace ssu
|
|||||||
m_Encryption.ProcessData (payload, payload, 48);
|
m_Encryption.ProcessData (payload, payload, 48);
|
||||||
|
|
||||||
// encrypt message with intro key
|
// encrypt message with intro key
|
||||||
FillHeaderAndEncrypt (PAYLOAD_TYPE_SESSION_CREATED, buf, 368, address->key, iv, address->key);
|
FillHeaderAndEncrypt (PAYLOAD_TYPE_SESSION_CREATED, buf, 368, introKey, iv, introKey);
|
||||||
m_State = eSessionStateRequestSent;
|
m_State = eSessionStateRequestSent;
|
||||||
m_Server->Send (buf, 368, m_RemoteEndpoint);
|
m_Server->Send (buf, 368, m_RemoteEndpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSUSession::SendSessionConfirmed (const uint8_t * y, const uint8_t * ourAddress, uint32_t relayTag)
|
void SSUSession::SendSessionConfirmed (const uint8_t * y, const uint8_t * ourAddress, uint32_t relayTag)
|
||||||
{
|
{
|
||||||
auto address = m_RemoteRouter ? m_RemoteRouter->GetSSUAddress () : nullptr;
|
|
||||||
if (!address)
|
|
||||||
{
|
|
||||||
LogPrint ("Missing remote SSU address");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t buf[480 + 18];
|
uint8_t buf[480 + 18];
|
||||||
uint8_t * payload = buf + sizeof (SSUHeader);
|
uint8_t * payload = buf + sizeof (SSUHeader);
|
||||||
*payload = 1; // 1 fragment
|
*payload = 1; // 1 fragment
|
||||||
@ -275,15 +282,15 @@ namespace ssu
|
|||||||
m_Server->Send (buf, 480, m_RemoteEndpoint);
|
m_Server->Send (buf, 480, m_RemoteEndpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SSUSession::ProcessIntroKeyEncryptedMessage (uint8_t expectedPayloadType, const i2p::data::RouterInfo& r, uint8_t * buf, size_t len)
|
bool SSUSession::ProcessIntroKeyEncryptedMessage (uint8_t expectedPayloadType, uint8_t * buf, size_t len)
|
||||||
{
|
{
|
||||||
auto address = r.GetSSUAddress ();
|
auto introKey = GetIntroKey ();
|
||||||
if (address)
|
if (introKey)
|
||||||
{
|
{
|
||||||
// use intro key for verification and decryption
|
// use intro key for verification and decryption
|
||||||
if (Validate (buf, len, address->key))
|
if (Validate (buf, len, introKey))
|
||||||
{
|
{
|
||||||
Decrypt (buf, len, address->key);
|
Decrypt (buf, len, introKey);
|
||||||
SSUHeader * header = (SSUHeader *)buf;
|
SSUHeader * header = (SSUHeader *)buf;
|
||||||
if ((header->flag >> 4) == expectedPayloadType)
|
if ((header->flag >> 4) == expectedPayloadType)
|
||||||
{
|
{
|
||||||
@ -297,7 +304,7 @@ namespace ssu
|
|||||||
LogPrint ("MAC verifcation failed");
|
LogPrint ("MAC verifcation failed");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint ("SSU is not supported by ", r.GetIdentHashAbbreviation ());
|
LogPrint ("SSU is not supported");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -374,6 +381,7 @@ namespace ssu
|
|||||||
|
|
||||||
void SSUSession::Established ()
|
void SSUSession::Established ()
|
||||||
{
|
{
|
||||||
|
SendI2NPMessage (CreateDatabaseStoreMsg ());
|
||||||
if (!m_DelayedMessages.empty ())
|
if (!m_DelayedMessages.empty ())
|
||||||
{
|
{
|
||||||
for (auto it :m_DelayedMessages)
|
for (auto it :m_DelayedMessages)
|
||||||
@ -382,6 +390,22 @@ namespace ssu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const uint8_t * SSUSession::GetIntroKey () const
|
||||||
|
{
|
||||||
|
if (m_RemoteRouter)
|
||||||
|
{
|
||||||
|
// we are client
|
||||||
|
auto address = m_RemoteRouter->GetSSUAddress ();
|
||||||
|
return address ? address->key : nullptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// we are server
|
||||||
|
auto address = i2p::context.GetRouterInfo ().GetSSUAddress ();
|
||||||
|
return address ? address->key : nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SSUSession::SendI2NPMessage (I2NPMessage * msg)
|
void SSUSession::SendI2NPMessage (I2NPMessage * msg)
|
||||||
{
|
{
|
||||||
if (msg)
|
if (msg)
|
||||||
@ -463,11 +487,25 @@ namespace ssu
|
|||||||
m_IncomleteMessages[msgID] = msg;
|
m_IncomleteMessages[msgID] = msg;
|
||||||
if (isLast)
|
if (isLast)
|
||||||
{
|
{
|
||||||
|
SendMsgAck (msgID);
|
||||||
if (fragmentNum > 0)
|
if (fragmentNum > 0)
|
||||||
m_IncomleteMessages.erase (msgID);
|
m_IncomleteMessages.erase (msgID);
|
||||||
msg->FromSSU (msgID);
|
msg->FromSSU (msgID);
|
||||||
i2p::HandleI2NPMessage (msg, false);
|
if (m_State == eSessionStateEstablished)
|
||||||
SendMsgAck (msgID);
|
i2p::HandleI2NPMessage (msg, false);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// we expect DeliveryStatus
|
||||||
|
if (msg->GetHeader ()->typeID == eI2NPDeliveryStatus)
|
||||||
|
{
|
||||||
|
LogPrint ("SSU session established");
|
||||||
|
m_State = eSessionStateEstablished;
|
||||||
|
Established ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LogPrint ("SSU unexpected message ", (int)msg->GetHeader ()->typeID);
|
||||||
|
DeleteI2NPMessage (msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buf += fragmentSize;
|
buf += fragmentSize;
|
||||||
@ -499,8 +537,21 @@ namespace ssu
|
|||||||
uint8_t buf[48 + 18], iv[16];
|
uint8_t buf[48 + 18], iv[16];
|
||||||
CryptoPP::RandomNumberGenerator& rnd = i2p::context.GetRandomNumberGenerator ();
|
CryptoPP::RandomNumberGenerator& rnd = i2p::context.GetRandomNumberGenerator ();
|
||||||
rnd.GenerateBlock (iv, 16); // random iv
|
rnd.GenerateBlock (iv, 16); // random iv
|
||||||
// encrypt message with session key
|
if (m_State == eSessionStateEstablished)
|
||||||
FillHeaderAndEncrypt (PAYLOAD_TYPE_SESSION_DESTROYED, buf, 48, m_SessionKey, iv, m_MacKey);
|
// encrypt message with session key
|
||||||
|
FillHeaderAndEncrypt (PAYLOAD_TYPE_SESSION_DESTROYED, buf, 48, m_SessionKey, iv, m_MacKey);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto introKey = GetIntroKey ();
|
||||||
|
if (introKey)
|
||||||
|
// encrypt message with intro key
|
||||||
|
FillHeaderAndEncrypt (PAYLOAD_TYPE_SESSION_DESTROYED, buf, 48, introKey, iv, introKey);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogPrint ("SSU: can't send SessionDestroyed message");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
m_Server->Send (buf, 48, m_RemoteEndpoint);
|
m_Server->Send (buf, 48, m_RemoteEndpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -514,10 +565,13 @@ namespace ssu
|
|||||||
uint32_t fragmentNum = 0;
|
uint32_t fragmentNum = 0;
|
||||||
while (len > 0)
|
while (len > 0)
|
||||||
{
|
{
|
||||||
uint8_t buf[SSU_MTU + 18], iv[16];
|
uint8_t buf[SSU_MTU + 18], iv[16], * payload = buf + sizeof (SSUHeader);
|
||||||
buf[0] = DATA_FLAG_WANT_REPLY; // for compatibility
|
*payload = DATA_FLAG_WANT_REPLY; // for compatibility
|
||||||
buf[1] = 1; // always 1 message fragment per message
|
payload++;
|
||||||
*(uint32_t *)(buf + 2) = msgID;
|
*payload = 1; // always 1 message fragment per message
|
||||||
|
payload++;
|
||||||
|
*(uint32_t *)payload = msgID;
|
||||||
|
payload += 4;
|
||||||
bool isLast = (len <= payloadSize);
|
bool isLast = (len <= payloadSize);
|
||||||
size_t size = isLast ? len : payloadSize;
|
size_t size = isLast ? len : payloadSize;
|
||||||
uint32_t fragmentInfo = (fragmentNum << 17);
|
uint32_t fragmentInfo = (fragmentNum << 17);
|
||||||
@ -526,10 +580,11 @@ namespace ssu
|
|||||||
|
|
||||||
fragmentInfo |= size;
|
fragmentInfo |= size;
|
||||||
fragmentInfo = htobe32 (fragmentInfo);
|
fragmentInfo = htobe32 (fragmentInfo);
|
||||||
memcpy (buf + 6, (uint8_t *)(&fragmentInfo) + 1, 3);
|
memcpy (payload, (uint8_t *)(&fragmentInfo) + 1, 3);
|
||||||
memcpy (buf + 9, msgBuf, size);
|
payload += 3;
|
||||||
|
memcpy (payload, msgBuf, size);
|
||||||
|
|
||||||
size += sizeof (SSUHeader) + 9;
|
size += payload - buf;
|
||||||
if (size % 16) // make sure 16 bytes boundary
|
if (size % 16) // make sure 16 bytes boundary
|
||||||
size = (size/16 + 1)*16;
|
size = (size/16 + 1)*16;
|
||||||
|
|
||||||
@ -570,6 +625,7 @@ namespace ssu
|
|||||||
|
|
||||||
void SSUServer::Stop ()
|
void SSUServer::Stop ()
|
||||||
{
|
{
|
||||||
|
DeleteAllSessions ();
|
||||||
m_Socket.close ();
|
m_Socket.close ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
3
SSU.h
3
SSU.h
@ -89,10 +89,11 @@ namespace ssu
|
|||||||
void SendSesionDestroyed ();
|
void SendSesionDestroyed ();
|
||||||
void Send (i2p::I2NPMessage * msg);
|
void Send (i2p::I2NPMessage * msg);
|
||||||
|
|
||||||
bool ProcessIntroKeyEncryptedMessage (uint8_t expectedPayloadType, const i2p::data::RouterInfo& r, uint8_t * buf, size_t len);
|
bool ProcessIntroKeyEncryptedMessage (uint8_t expectedPayloadType, uint8_t * buf, size_t len);
|
||||||
void FillHeaderAndEncrypt (uint8_t payloadType, uint8_t * buf, size_t len, const uint8_t * aesKey, const uint8_t * iv, const uint8_t * macKey);
|
void FillHeaderAndEncrypt (uint8_t payloadType, uint8_t * buf, size_t len, const uint8_t * aesKey, const uint8_t * iv, const uint8_t * macKey);
|
||||||
void Decrypt (uint8_t * buf, size_t len, const uint8_t * aesKey);
|
void Decrypt (uint8_t * buf, size_t len, const uint8_t * aesKey);
|
||||||
bool Validate (uint8_t * buf, size_t len, const uint8_t * macKey);
|
bool Validate (uint8_t * buf, size_t len, const uint8_t * macKey);
|
||||||
|
const uint8_t * GetIntroKey () const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -168,7 +168,23 @@ namespace i2p
|
|||||||
AddNTCPSession (session);
|
AddNTCPSession (session);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint ("No NTCP addresses available");
|
{
|
||||||
|
// SSU always have lower prioprity than NTCP
|
||||||
|
// TODO: it shouldn't
|
||||||
|
LogPrint ("No NTCP addresses available. Trying SSU");
|
||||||
|
address = r->GetSSUAddress ();
|
||||||
|
if (address && m_SSUServer)
|
||||||
|
{
|
||||||
|
auto s = m_SSUServer->GetSession (r);
|
||||||
|
if (s)
|
||||||
|
{
|
||||||
|
s->SendI2NPMessage (msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LogPrint ("No SSU addresses available");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user