Merge pull request #566 from PurpleI2P/openssl

recent changes
This commit is contained in:
orignal 2016-07-09 21:41:43 -04:00 committed by GitHub
commit 8cc6756815
7 changed files with 149 additions and 50 deletions

View File

@ -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 ()
@ -93,19 +90,28 @@ namespace garlic
} }
void GarlicRoutingSession::TagsConfirmed (uint32_t msgID) void GarlicRoutingSession::TagsConfirmed (uint32_t msgID)
{
auto it = m_UnconfirmedTagsMsgs.find (msgID);
if (it != m_UnconfirmedTagsMsgs.end ())
{ {
uint32_t ts = i2p::util::GetSecondsSinceEpoch (); uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
UnconfirmedTags * tags = it->second; for (auto it = m_UnconfirmedTagsMsgs.begin (); it != m_UnconfirmedTagsMsgs.end ();)
{
auto& tags = *it;
if (tags->msgID == msgID)
{
if (ts < tags->tagsCreationTime + OUTGOING_TAGS_EXPIRATION_TIMEOUT) if (ts < tags->tagsCreationTime + OUTGOING_TAGS_EXPIRATION_TIMEOUT)
{ {
for (int i = 0; i < tags->numTags; i++) for (int i = 0; i < tags->numTags; i++)
m_SessionTags.push_back (tags->sessionTags[i]); m_SessionTags.push_back (tags->sessionTags[i]);
} }
m_UnconfirmedTagsMsgs.erase (it); it = m_UnconfirmedTagsMsgs.erase (it);
delete tags; }
else if (ts >= tags->tagsCreationTime + OUTGOING_TAGS_CONFIRMATION_TIMEOUT)
{
if (m_Owner)
m_Owner->RemoveDeliveryStatusSession (tags->msgID);
it = m_UnconfirmedTagsMsgs.erase (it);
}
else
it++;
} }
} }
@ -119,20 +125,28 @@ 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

View File

@ -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;

View File

@ -87,18 +87,46 @@ 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 remoteSession = GetRoutingSession (remote, true);
if (!remoteSession)
{
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 outboundTunnel = GetTunnelPool ()->GetNextOutboundTunnel ();
auto leases = remote->GetNonExpiredLeases (); auto leases = remote->GetNonExpiredLeases ();
if (!leases.empty () && outboundTunnel) 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);

View File

@ -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 (); bool isEmpty = m_SentPackets.empty ();
m_SentPackets.insert (packet); m_SentPackets.insert (packet);
if (isEmpty) if (isEmpty)
ScheduleResend (); ScheduleResend ();
}
else
delete packet;
return true; return true;
} }
else else

View File

@ -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);

View 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.

View File

@ -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