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 ()
{
for (auto it: m_UnconfirmedTagsMsgs)
delete it.second;
m_UnconfirmedTagsMsgs.clear ();
}
std::shared_ptr<GarlicRoutingPath> GarlicRoutingSession::GetSharedRoutingPath ()
@ -94,18 +91,27 @@ namespace garlic
void GarlicRoutingSession::TagsConfirmed (uint32_t msgID)
{
auto it = m_UnconfirmedTagsMsgs.find (msgID);
if (it != m_UnconfirmedTagsMsgs.end ())
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
for (auto it = m_UnconfirmedTagsMsgs.begin (); it != m_UnconfirmedTagsMsgs.end ();)
{
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
UnconfirmedTags * tags = it->second;
if (ts < tags->tagsCreationTime + OUTGOING_TAGS_EXPIRATION_TIMEOUT)
{
for (int i = 0; i < tags->numTags; i++)
m_SessionTags.push_back (tags->sessionTags[i]);
auto& tags = *it;
if (tags->msgID == msgID)
{
if (ts < tags->tagsCreationTime + OUTGOING_TAGS_EXPIRATION_TIMEOUT)
{
for (int i = 0; i < tags->numTags; i++)
m_SessionTags.push_back (tags->sessionTags[i]);
}
it = m_UnconfirmedTagsMsgs.erase (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,21 +125,29 @@ namespace garlic
else
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
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)
m_Owner->RemoveDeliveryStatusSession (it->first);
delete it->second;
m_Owner->RemoveDeliveryStatusSession ((*it)->msgID);
it = m_UnconfirmedTagsMsgs.erase (it);
ret = true;
}
else
it++;
}
return !m_SessionTags.empty () || !m_UnconfirmedTagsMsgs.empty ();
}
return ret;
}
std::shared_ptr<I2NPMessage> GarlicRoutingSession::WrapSingleMessage (std::shared_ptr<const I2NPMessage> msg)
{
@ -258,7 +272,10 @@ namespace garlic
size += cloveSize;
(*numCloves)++;
if (newTags) // new tags created
m_UnconfirmedTagsMsgs[msgID] = newTags;
{
newTags->msgID = msgID;
m_UnconfirmedTagsMsgs.emplace_back (newTags);
}
m_Owner->DeliveryStatusSent (shared_from_this (), msgID);
}
else
@ -617,7 +634,7 @@ namespace garlic
it++;
}
}
void GarlicDestination::RemoveDeliveryStatusSession (uint32_t msgID)
{
m_DeliveryStatusSessions.erase (msgID);

View File

@ -83,6 +83,7 @@ namespace garlic
{
UnconfirmedTags (int n): numTags (n), tagsCreationTime (0) { sessionTags = new SessionTag[numTags]; };
~UnconfirmedTags () { delete[] sessionTags; };
uint32_t msgID;
int numTags;
SessionTag * sessionTags;
uint32_t tagsCreationTime;
@ -97,6 +98,7 @@ namespace garlic
std::shared_ptr<I2NPMessage> WrapSingleMessage (std::shared_ptr<const I2NPMessage> msg);
void MessageConfirmed (uint32_t msgID);
bool CleanupExpiredTags (); // returns true if something left
bool CleanupUnconfirmedTags (); // returns true if something has been deleted
void SetLeaseSetUpdated ()
{
@ -123,7 +125,7 @@ namespace garlic
i2p::crypto::AESKey m_SessionKey;
std::list<SessionTag> m_SessionTags;
int m_NumTags;
std::map<uint32_t, UnconfirmedTags *> m_UnconfirmedTagsMsgs;
std::list<std::unique_ptr<UnconfirmedTags> > m_UnconfirmedTagsMsgs;
LeaseSetUpdateStatus m_LeaseSetUpdateStatus;
uint32_t m_LeaseSetUpdateMsgID;

View File

@ -87,23 +87,51 @@ namespace client
}
bool I2CPDestination::SendMsg (std::shared_ptr<I2NPMessage> msg, std::shared_ptr<const i2p::data::LeaseSet> remote)
{
auto outboundTunnel = GetTunnelPool ()->GetNextOutboundTunnel ();
auto leases = remote->GetNonExpiredLeases ();
if (!leases.empty () && outboundTunnel)
{
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 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;
uint32_t i = rand () % leases.size ();
auto garlic = WrapMessage (remote, msg, true);
auto garlic = remoteSession->WrapSingleMessage (msg);
msgs.push_back (i2p::tunnel::TunnelMessageBlock
{
i2p::tunnel::eDeliveryTypeTunnel,
leases[i]->tunnelGateway, leases[i]->tunnelID,
remoteLease->tunnelGateway, remoteLease->tunnelID,
garlic
});
outboundTunnel->SendTunnelDataMsg (msgs);
return true;
}
}
else
{
if (outboundTunnel)

View File

@ -36,7 +36,6 @@ namespace stream
Stream::~Stream ()
{
Terminate ();
while (!m_ReceiveQueue.empty ())
{
auto packet = m_ReceiveQueue.front ();
@ -66,6 +65,7 @@ namespace stream
m_SendHandler = nullptr;
handler (boost::asio::error::make_error_code (boost::asio::error::operation_aborted));
}
m_LocalDestination.DeleteStream (shared_from_this ());
}
void Stream::HandleNextPacket (Packet * packet)
@ -220,11 +220,18 @@ namespace stream
m_LastReceivedSequenceNumber = receivedSeqn;
if (flags & (PACKET_FLAG_CLOSE | PACKET_FLAG_RESET))
if (flags & PACKET_FLAG_RESET)
{
m_Status = eStreamStatusReset;
Close ();
}
else if (flags & PACKET_FLAG_CLOSE)
{
if (m_Status != eStreamStatusClosed)
SendClose ();
m_Status = eStreamStatusClosed;
Terminate ();
}
}
void Stream::ProcessAck (Packet * packet)
@ -294,8 +301,10 @@ namespace stream
m_NumResendAttempts = 0;
SendBuffer ();
}
if (m_Status == eStreamStatusClosing)
Close (); // all outgoing messages have been sent
if (m_Status == eStreamStatusClosed)
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)
@ -495,23 +504,19 @@ namespace stream
LogPrint (eLogDebug, "Streaming: Trying to send stream data before closing, sSID=", m_SendStreamID);
break;
case eStreamStatusReset:
SendClose ();
Terminate ();
m_LocalDestination.DeleteStream (shared_from_this ());
// TODO: send reset
Terminate ();
break;
case eStreamStatusClosing:
if (m_SentPackets.empty () && m_SendBuffer.eof ()) // nothing to send
{
m_Status = eStreamStatusClosed;
SendClose ();
Terminate ();
m_LocalDestination.DeleteStream (shared_from_this ());
}
break;
case eStreamStatusClosed:
// already closed
Terminate ();
m_LocalDestination.DeleteStream (shared_from_this ());
break;
default:
LogPrint (eLogWarning, "Streaming: Unexpected stream status ", (int)m_Status, "sSID=", m_SendStreamID);
@ -578,15 +583,10 @@ namespace stream
m_AckSendTimer.cancel ();
}
SendPackets (std::vector<Packet *> { packet });
if (m_Status == eStreamStatusOpen)
{
bool isEmpty = m_SentPackets.empty ();
m_SentPackets.insert (packet);
if (isEmpty)
ScheduleResend ();
}
else
delete packet;
bool isEmpty = m_SentPackets.empty ();
m_SentPackets.insert (packet);
if (isEmpty)
ScheduleResend ();
return true;
}
else

View File

@ -330,8 +330,8 @@ namespace tunnel
{
if (m_ExplicitPeers) return SelectExplicitPeers (peers, isInbound);
int numHops = isInbound ? m_NumInboundHops : m_NumOutboundHops;
if (numHops <= 0) return true;
auto prevHop = i2p::context.GetSharedRouterInfo();
if (numHops <= 0) return true; // peers is empty
auto prevHop = i2p::context.GetSharedRouterInfo ();
if(i2p::transport::transports.RoutesRestricted())
{
/** if routes are restricted prepend trusted first hop */
@ -340,6 +340,17 @@ namespace tunnel
peers.push_back(hop->GetRouterIdentity());
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++ )
{
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_notes_unix
build_notes_windows
build_notes_android
configuration
family