mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2024-11-02 09:40:18 +00:00
commit
8cc6756815
53
Garlic.cpp
53
Garlic.cpp
@ -38,9 +38,6 @@ namespace garlic
|
|||||||
|
|
||||||
GarlicRoutingSession::~GarlicRoutingSession ()
|
GarlicRoutingSession::~GarlicRoutingSession ()
|
||||||
{
|
{
|
||||||
for (auto it: m_UnconfirmedTagsMsgs)
|
|
||||||
delete it.second;
|
|
||||||
m_UnconfirmedTagsMsgs.clear ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<GarlicRoutingPath> GarlicRoutingSession::GetSharedRoutingPath ()
|
std::shared_ptr<GarlicRoutingPath> GarlicRoutingSession::GetSharedRoutingPath ()
|
||||||
@ -94,18 +91,27 @@ namespace garlic
|
|||||||
|
|
||||||
void GarlicRoutingSession::TagsConfirmed (uint32_t msgID)
|
void GarlicRoutingSession::TagsConfirmed (uint32_t msgID)
|
||||||
{
|
{
|
||||||
auto it = m_UnconfirmedTagsMsgs.find (msgID);
|
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
||||||
if (it != m_UnconfirmedTagsMsgs.end ())
|
for (auto it = m_UnconfirmedTagsMsgs.begin (); it != m_UnconfirmedTagsMsgs.end ();)
|
||||||
{
|
{
|
||||||
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
auto& tags = *it;
|
||||||
UnconfirmedTags * tags = it->second;
|
if (tags->msgID == msgID)
|
||||||
if (ts < tags->tagsCreationTime + OUTGOING_TAGS_EXPIRATION_TIMEOUT)
|
|
||||||
{
|
{
|
||||||
for (int i = 0; i < tags->numTags; i++)
|
if (ts < tags->tagsCreationTime + OUTGOING_TAGS_EXPIRATION_TIMEOUT)
|
||||||
m_SessionTags.push_back (tags->sessionTags[i]);
|
{
|
||||||
|
for (int i = 0; i < tags->numTags; i++)
|
||||||
|
m_SessionTags.push_back (tags->sessionTags[i]);
|
||||||
|
}
|
||||||
|
it = m_UnconfirmedTagsMsgs.erase (it);
|
||||||
}
|
}
|
||||||
m_UnconfirmedTagsMsgs.erase (it);
|
else if (ts >= tags->tagsCreationTime + OUTGOING_TAGS_CONFIRMATION_TIMEOUT)
|
||||||
delete tags;
|
{
|
||||||
|
if (m_Owner)
|
||||||
|
m_Owner->RemoveDeliveryStatusSession (tags->msgID);
|
||||||
|
it = m_UnconfirmedTagsMsgs.erase (it);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
it++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,21 +125,29 @@ namespace garlic
|
|||||||
else
|
else
|
||||||
it++;
|
it++;
|
||||||
}
|
}
|
||||||
|
CleanupUnconfirmedTags ();
|
||||||
|
return !m_SessionTags.empty () || !m_UnconfirmedTagsMsgs.empty ();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GarlicRoutingSession::CleanupUnconfirmedTags ()
|
||||||
|
{
|
||||||
|
bool ret = false;
|
||||||
|
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
|
||||||
// delete expired unconfirmed tags
|
// delete expired unconfirmed tags
|
||||||
for (auto it = m_UnconfirmedTagsMsgs.begin (); it != m_UnconfirmedTagsMsgs.end ();)
|
for (auto it = m_UnconfirmedTagsMsgs.begin (); it != m_UnconfirmedTagsMsgs.end ();)
|
||||||
{
|
{
|
||||||
if (ts >= it->second->tagsCreationTime + OUTGOING_TAGS_CONFIRMATION_TIMEOUT)
|
if (ts >= (*it)->tagsCreationTime + OUTGOING_TAGS_CONFIRMATION_TIMEOUT)
|
||||||
{
|
{
|
||||||
if (m_Owner)
|
if (m_Owner)
|
||||||
m_Owner->RemoveDeliveryStatusSession (it->first);
|
m_Owner->RemoveDeliveryStatusSession ((*it)->msgID);
|
||||||
delete it->second;
|
|
||||||
it = m_UnconfirmedTagsMsgs.erase (it);
|
it = m_UnconfirmedTagsMsgs.erase (it);
|
||||||
|
ret = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
it++;
|
it++;
|
||||||
}
|
}
|
||||||
return !m_SessionTags.empty () || !m_UnconfirmedTagsMsgs.empty ();
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<I2NPMessage> GarlicRoutingSession::WrapSingleMessage (std::shared_ptr<const I2NPMessage> msg)
|
std::shared_ptr<I2NPMessage> GarlicRoutingSession::WrapSingleMessage (std::shared_ptr<const I2NPMessage> msg)
|
||||||
{
|
{
|
||||||
@ -258,7 +272,10 @@ namespace garlic
|
|||||||
size += cloveSize;
|
size += cloveSize;
|
||||||
(*numCloves)++;
|
(*numCloves)++;
|
||||||
if (newTags) // new tags created
|
if (newTags) // new tags created
|
||||||
m_UnconfirmedTagsMsgs[msgID] = newTags;
|
{
|
||||||
|
newTags->msgID = msgID;
|
||||||
|
m_UnconfirmedTagsMsgs.emplace_back (newTags);
|
||||||
|
}
|
||||||
m_Owner->DeliveryStatusSent (shared_from_this (), msgID);
|
m_Owner->DeliveryStatusSent (shared_from_this (), msgID);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
4
Garlic.h
4
Garlic.h
@ -83,6 +83,7 @@ namespace garlic
|
|||||||
{
|
{
|
||||||
UnconfirmedTags (int n): numTags (n), tagsCreationTime (0) { sessionTags = new SessionTag[numTags]; };
|
UnconfirmedTags (int n): numTags (n), tagsCreationTime (0) { sessionTags = new SessionTag[numTags]; };
|
||||||
~UnconfirmedTags () { delete[] sessionTags; };
|
~UnconfirmedTags () { delete[] sessionTags; };
|
||||||
|
uint32_t msgID;
|
||||||
int numTags;
|
int numTags;
|
||||||
SessionTag * sessionTags;
|
SessionTag * sessionTags;
|
||||||
uint32_t tagsCreationTime;
|
uint32_t tagsCreationTime;
|
||||||
@ -97,6 +98,7 @@ namespace garlic
|
|||||||
std::shared_ptr<I2NPMessage> WrapSingleMessage (std::shared_ptr<const I2NPMessage> msg);
|
std::shared_ptr<I2NPMessage> WrapSingleMessage (std::shared_ptr<const I2NPMessage> msg);
|
||||||
void MessageConfirmed (uint32_t msgID);
|
void MessageConfirmed (uint32_t msgID);
|
||||||
bool CleanupExpiredTags (); // returns true if something left
|
bool CleanupExpiredTags (); // returns true if something left
|
||||||
|
bool CleanupUnconfirmedTags (); // returns true if something has been deleted
|
||||||
|
|
||||||
void SetLeaseSetUpdated ()
|
void SetLeaseSetUpdated ()
|
||||||
{
|
{
|
||||||
@ -123,7 +125,7 @@ namespace garlic
|
|||||||
i2p::crypto::AESKey m_SessionKey;
|
i2p::crypto::AESKey m_SessionKey;
|
||||||
std::list<SessionTag> m_SessionTags;
|
std::list<SessionTag> m_SessionTags;
|
||||||
int m_NumTags;
|
int m_NumTags;
|
||||||
std::map<uint32_t, UnconfirmedTags *> m_UnconfirmedTagsMsgs;
|
std::list<std::unique_ptr<UnconfirmedTags> > m_UnconfirmedTagsMsgs;
|
||||||
|
|
||||||
LeaseSetUpdateStatus m_LeaseSetUpdateStatus;
|
LeaseSetUpdateStatus m_LeaseSetUpdateStatus;
|
||||||
uint32_t m_LeaseSetUpdateMsgID;
|
uint32_t m_LeaseSetUpdateMsgID;
|
||||||
|
40
I2CP.cpp
40
I2CP.cpp
@ -88,17 +88,45 @@ namespace client
|
|||||||
|
|
||||||
bool I2CPDestination::SendMsg (std::shared_ptr<I2NPMessage> msg, std::shared_ptr<const i2p::data::LeaseSet> remote)
|
bool I2CPDestination::SendMsg (std::shared_ptr<I2NPMessage> msg, std::shared_ptr<const i2p::data::LeaseSet> remote)
|
||||||
{
|
{
|
||||||
auto outboundTunnel = GetTunnelPool ()->GetNextOutboundTunnel ();
|
auto remoteSession = GetRoutingSession (remote, true);
|
||||||
auto leases = remote->GetNonExpiredLeases ();
|
if (!remoteSession)
|
||||||
if (!leases.empty () && outboundTunnel)
|
{
|
||||||
|
LogPrint (eLogError, "I2CP: Failed to create remote session");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto path = remoteSession->GetSharedRoutingPath ();
|
||||||
|
std::shared_ptr<i2p::tunnel::OutboundTunnel> outboundTunnel;
|
||||||
|
std::shared_ptr<const i2p::data::Lease> remoteLease;
|
||||||
|
if (path)
|
||||||
|
{
|
||||||
|
if (!remoteSession->CleanupUnconfirmedTags ()) // no stuck tags
|
||||||
|
{
|
||||||
|
outboundTunnel = path->outboundTunnel;
|
||||||
|
remoteLease = path->remoteLease;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
remoteSession->SetSharedRoutingPath (nullptr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto outboundTunnel = GetTunnelPool ()->GetNextOutboundTunnel ();
|
||||||
|
auto leases = remote->GetNonExpiredLeases ();
|
||||||
|
if (!leases.empty ())
|
||||||
|
remoteLease = leases[rand () % leases.size ()];
|
||||||
|
if (remoteLease && outboundTunnel)
|
||||||
|
remoteSession->SetSharedRoutingPath (std::make_shared<i2p::garlic::GarlicRoutingPath> (
|
||||||
|
i2p::garlic::GarlicRoutingPath{outboundTunnel, remoteLease, 10000, 0, 0})); // 10 secs RTT
|
||||||
|
else
|
||||||
|
remoteSession->SetSharedRoutingPath (nullptr);
|
||||||
|
}
|
||||||
|
if (remoteLease && outboundTunnel)
|
||||||
{
|
{
|
||||||
std::vector<i2p::tunnel::TunnelMessageBlock> msgs;
|
std::vector<i2p::tunnel::TunnelMessageBlock> msgs;
|
||||||
uint32_t i = rand () % leases.size ();
|
auto garlic = remoteSession->WrapSingleMessage (msg);
|
||||||
auto garlic = WrapMessage (remote, msg, true);
|
|
||||||
msgs.push_back (i2p::tunnel::TunnelMessageBlock
|
msgs.push_back (i2p::tunnel::TunnelMessageBlock
|
||||||
{
|
{
|
||||||
i2p::tunnel::eDeliveryTypeTunnel,
|
i2p::tunnel::eDeliveryTypeTunnel,
|
||||||
leases[i]->tunnelGateway, leases[i]->tunnelID,
|
remoteLease->tunnelGateway, remoteLease->tunnelID,
|
||||||
garlic
|
garlic
|
||||||
});
|
});
|
||||||
outboundTunnel->SendTunnelDataMsg (msgs);
|
outboundTunnel->SendTunnelDataMsg (msgs);
|
||||||
|
@ -36,7 +36,6 @@ namespace stream
|
|||||||
|
|
||||||
Stream::~Stream ()
|
Stream::~Stream ()
|
||||||
{
|
{
|
||||||
Terminate ();
|
|
||||||
while (!m_ReceiveQueue.empty ())
|
while (!m_ReceiveQueue.empty ())
|
||||||
{
|
{
|
||||||
auto packet = m_ReceiveQueue.front ();
|
auto packet = m_ReceiveQueue.front ();
|
||||||
@ -66,6 +65,7 @@ namespace stream
|
|||||||
m_SendHandler = nullptr;
|
m_SendHandler = nullptr;
|
||||||
handler (boost::asio::error::make_error_code (boost::asio::error::operation_aborted));
|
handler (boost::asio::error::make_error_code (boost::asio::error::operation_aborted));
|
||||||
}
|
}
|
||||||
|
m_LocalDestination.DeleteStream (shared_from_this ());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Stream::HandleNextPacket (Packet * packet)
|
void Stream::HandleNextPacket (Packet * packet)
|
||||||
@ -220,11 +220,18 @@ namespace stream
|
|||||||
|
|
||||||
m_LastReceivedSequenceNumber = receivedSeqn;
|
m_LastReceivedSequenceNumber = receivedSeqn;
|
||||||
|
|
||||||
if (flags & (PACKET_FLAG_CLOSE | PACKET_FLAG_RESET))
|
if (flags & PACKET_FLAG_RESET)
|
||||||
{
|
{
|
||||||
m_Status = eStreamStatusReset;
|
m_Status = eStreamStatusReset;
|
||||||
Close ();
|
Close ();
|
||||||
}
|
}
|
||||||
|
else if (flags & PACKET_FLAG_CLOSE)
|
||||||
|
{
|
||||||
|
if (m_Status != eStreamStatusClosed)
|
||||||
|
SendClose ();
|
||||||
|
m_Status = eStreamStatusClosed;
|
||||||
|
Terminate ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Stream::ProcessAck (Packet * packet)
|
void Stream::ProcessAck (Packet * packet)
|
||||||
@ -294,8 +301,10 @@ namespace stream
|
|||||||
m_NumResendAttempts = 0;
|
m_NumResendAttempts = 0;
|
||||||
SendBuffer ();
|
SendBuffer ();
|
||||||
}
|
}
|
||||||
if (m_Status == eStreamStatusClosing)
|
if (m_Status == eStreamStatusClosed)
|
||||||
Close (); // all outgoing messages have been sent
|
Terminate ();
|
||||||
|
else if (m_Status == eStreamStatusClosing)
|
||||||
|
Close (); // check is all outgoing messages have been sent and we can send close
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Stream::Send (const uint8_t * buf, size_t len)
|
size_t Stream::Send (const uint8_t * buf, size_t len)
|
||||||
@ -495,23 +504,19 @@ namespace stream
|
|||||||
LogPrint (eLogDebug, "Streaming: Trying to send stream data before closing, sSID=", m_SendStreamID);
|
LogPrint (eLogDebug, "Streaming: Trying to send stream data before closing, sSID=", m_SendStreamID);
|
||||||
break;
|
break;
|
||||||
case eStreamStatusReset:
|
case eStreamStatusReset:
|
||||||
SendClose ();
|
// TODO: send reset
|
||||||
Terminate ();
|
Terminate ();
|
||||||
m_LocalDestination.DeleteStream (shared_from_this ());
|
|
||||||
break;
|
break;
|
||||||
case eStreamStatusClosing:
|
case eStreamStatusClosing:
|
||||||
if (m_SentPackets.empty () && m_SendBuffer.eof ()) // nothing to send
|
if (m_SentPackets.empty () && m_SendBuffer.eof ()) // nothing to send
|
||||||
{
|
{
|
||||||
m_Status = eStreamStatusClosed;
|
m_Status = eStreamStatusClosed;
|
||||||
SendClose ();
|
SendClose ();
|
||||||
Terminate ();
|
|
||||||
m_LocalDestination.DeleteStream (shared_from_this ());
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case eStreamStatusClosed:
|
case eStreamStatusClosed:
|
||||||
// already closed
|
// already closed
|
||||||
Terminate ();
|
Terminate ();
|
||||||
m_LocalDestination.DeleteStream (shared_from_this ());
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LogPrint (eLogWarning, "Streaming: Unexpected stream status ", (int)m_Status, "sSID=", m_SendStreamID);
|
LogPrint (eLogWarning, "Streaming: Unexpected stream status ", (int)m_Status, "sSID=", m_SendStreamID);
|
||||||
@ -578,15 +583,10 @@ namespace stream
|
|||||||
m_AckSendTimer.cancel ();
|
m_AckSendTimer.cancel ();
|
||||||
}
|
}
|
||||||
SendPackets (std::vector<Packet *> { packet });
|
SendPackets (std::vector<Packet *> { packet });
|
||||||
if (m_Status == eStreamStatusOpen)
|
bool isEmpty = m_SentPackets.empty ();
|
||||||
{
|
m_SentPackets.insert (packet);
|
||||||
bool isEmpty = m_SentPackets.empty ();
|
if (isEmpty)
|
||||||
m_SentPackets.insert (packet);
|
ScheduleResend ();
|
||||||
if (isEmpty)
|
|
||||||
ScheduleResend ();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
delete packet;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -330,8 +330,8 @@ namespace tunnel
|
|||||||
{
|
{
|
||||||
if (m_ExplicitPeers) return SelectExplicitPeers (peers, isInbound);
|
if (m_ExplicitPeers) return SelectExplicitPeers (peers, isInbound);
|
||||||
int numHops = isInbound ? m_NumInboundHops : m_NumOutboundHops;
|
int numHops = isInbound ? m_NumInboundHops : m_NumOutboundHops;
|
||||||
if (numHops <= 0) return true;
|
if (numHops <= 0) return true; // peers is empty
|
||||||
auto prevHop = i2p::context.GetSharedRouterInfo();
|
auto prevHop = i2p::context.GetSharedRouterInfo ();
|
||||||
if(i2p::transport::transports.RoutesRestricted())
|
if(i2p::transport::transports.RoutesRestricted())
|
||||||
{
|
{
|
||||||
/** if routes are restricted prepend trusted first hop */
|
/** if routes are restricted prepend trusted first hop */
|
||||||
@ -340,6 +340,17 @@ namespace tunnel
|
|||||||
peers.push_back(hop->GetRouterIdentity());
|
peers.push_back(hop->GetRouterIdentity());
|
||||||
prevHop = hop;
|
prevHop = hop;
|
||||||
}
|
}
|
||||||
|
else if (i2p::transport::transports.GetNumPeers () > 25)
|
||||||
|
{
|
||||||
|
auto r = i2p::transport::transports.GetRandomPeer ();
|
||||||
|
if (r && !r->GetProfile ()->IsBad ())
|
||||||
|
{
|
||||||
|
prevHop = r;
|
||||||
|
peers.push_back (r->GetRouterIdentity ());
|
||||||
|
numHops--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for(int i = 0; i < numHops; i++ )
|
for(int i = 0; i < numHops; i++ )
|
||||||
{
|
{
|
||||||
auto hop = SelectNextHop (prevHop);
|
auto hop = SelectNextHop (prevHop);
|
||||||
|
40
docs/build_notes_android.md
Normal file
40
docs/build_notes_android.md
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
Building on Android
|
||||||
|
===================
|
||||||
|
|
||||||
|
Pre-requesties
|
||||||
|
--------------
|
||||||
|
|
||||||
|
You need to install Android SDK, NDK and QT with android support.
|
||||||
|
|
||||||
|
- [SDK](https://developer.android.com/studio/index.html) (choose command line tools only)
|
||||||
|
- [NDK](https://developer.android.com/ndk/downloads/index.html)
|
||||||
|
- [QT](https://www.qt.io/download-open-source/). Choose one for your platform for android. For example QT 5.6 under Linux would be [this file](http://download.qt.io/official_releases/qt/5.6/5.6.1-1/qt-opensource-linux-x64-android-5.6.1-1.run )
|
||||||
|
|
||||||
|
You also need Java JDK and Ant.
|
||||||
|
|
||||||
|
QT-Creator
|
||||||
|
----------
|
||||||
|
Open QT-creator that should be installed with QT.
|
||||||
|
Go to Settings/Anndroid and specify correct paths to SDK and NDK.
|
||||||
|
If everything is correct you will see two set avaiable:
|
||||||
|
Android for armeabi-v7a (gcc, qt) and Android for x86 (gcc, qt).
|
||||||
|
|
||||||
|
Dependencies
|
||||||
|
--------------
|
||||||
|
Take following pre-compiled binaries from PurpleI2P's repositories.
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/PurpleI2P/Boost-for-Android-Prebuilt.git
|
||||||
|
git clone https://github.com/PurpleI2P/OpenSSL-for-Android-Prebuilt.git
|
||||||
|
git clone https://github.com/PurpleI2P/MiniUPnP-for-Android-Prebuilt.git
|
||||||
|
git clone https://github.com/PurpleI2P/android-ifaddrs.git
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Building the app
|
||||||
|
----------------
|
||||||
|
- Open qt/i2pd_qt/i2pd_qt.pro in the QT-creator.
|
||||||
|
- Change line MAIN_PATH = /path/to/libraries to actual path where did you put the dependancies to.
|
||||||
|
- Select appropriate project (usually armeabi-v7a) and build.
|
||||||
|
- You will find an .apk file in android-build/bin folder.
|
||||||
|
|
||||||
|
|
@ -32,6 +32,7 @@ Contents:
|
|||||||
build_requirements
|
build_requirements
|
||||||
build_notes_unix
|
build_notes_unix
|
||||||
build_notes_windows
|
build_notes_windows
|
||||||
|
build_notes_android
|
||||||
configuration
|
configuration
|
||||||
family
|
family
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user