|
|
@ -1,5 +1,5 @@ |
|
|
|
/*
|
|
|
|
/*
|
|
|
|
* Copyright (c) 2013-2023, The PurpleI2P Project |
|
|
|
* Copyright (c) 2013-2024, The PurpleI2P Project |
|
|
|
* |
|
|
|
* |
|
|
|
* This file is part of Purple i2pd project and licensed under BSD3 |
|
|
|
* This file is part of Purple i2pd project and licensed under BSD3 |
|
|
|
* |
|
|
|
* |
|
|
@ -360,35 +360,57 @@ namespace tunnel |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// new tests
|
|
|
|
// new tests
|
|
|
|
std::unique_lock<std::mutex> l1(m_OutboundTunnelsMutex); |
|
|
|
std::vector<std::pair<std::shared_ptr<OutboundTunnel>, std::shared_ptr<InboundTunnel> > > newTests; |
|
|
|
auto it1 = m_OutboundTunnels.begin (); |
|
|
|
{ |
|
|
|
std::unique_lock<std::mutex> l2(m_InboundTunnelsMutex); |
|
|
|
std::unique_lock<std::mutex> l1(m_OutboundTunnelsMutex); |
|
|
|
auto it2 = m_InboundTunnels.begin (); |
|
|
|
auto it1 = m_OutboundTunnels.begin (); |
|
|
|
while (it1 != m_OutboundTunnels.end () && it2 != m_InboundTunnels.end ()) |
|
|
|
std::unique_lock<std::mutex> l2(m_InboundTunnelsMutex); |
|
|
|
{ |
|
|
|
auto it2 = m_InboundTunnels.begin (); |
|
|
|
bool failed = false; |
|
|
|
while (it1 != m_OutboundTunnels.end () && it2 != m_InboundTunnels.end ()) |
|
|
|
if ((*it1)->IsFailed ()) |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
failed = true; |
|
|
|
bool failed = false; |
|
|
|
++it1; |
|
|
|
if ((*it1)->IsFailed ()) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
failed = true; |
|
|
|
|
|
|
|
++it1; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if ((*it2)->IsFailed ()) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
failed = true; |
|
|
|
|
|
|
|
++it2; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (!failed) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
newTests.push_back(std::make_pair (*it1, *it2)); |
|
|
|
|
|
|
|
++it1; ++it2; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
if ((*it2)->IsFailed ()) |
|
|
|
} |
|
|
|
|
|
|
|
for (auto& it: newTests) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
uint32_t msgID; |
|
|
|
|
|
|
|
RAND_bytes ((uint8_t *)&msgID, 4); |
|
|
|
{ |
|
|
|
{ |
|
|
|
failed = true; |
|
|
|
std::unique_lock<std::mutex> l(m_TestsMutex); |
|
|
|
++it2; |
|
|
|
m_Tests[msgID] = it; |
|
|
|
} |
|
|
|
} |
|
|
|
if (!failed) |
|
|
|
auto msg = CreateDeliveryStatusMsg (msgID); |
|
|
|
{ |
|
|
|
auto outbound = it.first; |
|
|
|
uint32_t msgID; |
|
|
|
auto s = shared_from_this (); |
|
|
|
RAND_bytes ((uint8_t *)&msgID, 4); |
|
|
|
msg->onDrop = [msgID, outbound, s]() |
|
|
|
{ |
|
|
|
{ |
|
|
|
std::unique_lock<std::mutex> l(m_TestsMutex); |
|
|
|
// if test msg dropped locally it's outbound tunnel to blame
|
|
|
|
m_Tests[msgID] = std::make_pair (*it1, *it2); |
|
|
|
outbound->SetState (eTunnelStateFailed); |
|
|
|
} |
|
|
|
{ |
|
|
|
(*it1)->SendTunnelDataMsgTo ((*it2)->GetNextIdentHash (), (*it2)->GetNextTunnelID (), |
|
|
|
std::unique_lock<std::mutex> l(s->m_TestsMutex); |
|
|
|
CreateDeliveryStatusMsg (msgID)); |
|
|
|
s->m_Tests.erase (msgID); |
|
|
|
++it1; ++it2; |
|
|
|
} |
|
|
|
} |
|
|
|
{ |
|
|
|
|
|
|
|
std::unique_lock<std::mutex> l(s->m_OutboundTunnelsMutex); |
|
|
|
|
|
|
|
s->m_OutboundTunnels.erase (outbound); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
outbound->SendTunnelDataMsgTo (it.second->GetNextIdentHash (), it.second->GetNextTunnelID (), msg); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|