Browse Source

Merge remote-tracking branch 'purple/openssl'

pull/715/head
Jeff Becker 8 years ago
parent
commit
b1fdfec18c
  1. 8
      Config.cpp
  2. 25
      Destination.cpp
  3. 8
      Destination.h
  4. 42
      Garlic.cpp
  5. 3
      Garlic.h
  6. 13
      HTTPProxy.cpp
  7. 21
      TunnelPool.cpp

8
Config.cpp

@ -87,8 +87,8 @@ namespace config {
("httpproxy.outbound.length", value<std::string>()->default_value("3"), "HTTP proxy outbound tunnel length") ("httpproxy.outbound.length", value<std::string>()->default_value("3"), "HTTP proxy outbound tunnel length")
("httpproxy.inbound.quantity", value<std::string>()->default_value("5"), "HTTP proxy inbound tunnels quantity") ("httpproxy.inbound.quantity", value<std::string>()->default_value("5"), "HTTP proxy inbound tunnels quantity")
("httpproxy.outbound.quantity", value<std::string>()->default_value("5"), "HTTP proxy outbound tunnels quantity") ("httpproxy.outbound.quantity", value<std::string>()->default_value("5"), "HTTP proxy outbound tunnels quantity")
("httpproxy.latency.min", value<int>()->default_value(0), "HTTP proxy min latency for tunnels") ("httpproxy.latency.min", value<std::string>()->default_value("0"), "HTTP proxy min latency for tunnels")
("httpproxy.latency.max", value<int>()->default_value(0), "HTTP proxy max latency for tunnels") ("httpproxy.latency.max", value<std::string>()->default_value("0"), "HTTP proxy max latency for tunnels")
; ;
options_description socksproxy("SOCKS Proxy options"); options_description socksproxy("SOCKS Proxy options");
@ -101,8 +101,8 @@ namespace config {
("socksproxy.outbound.length", value<std::string>()->default_value("3"), "SOCKS proxy outbound tunnel length") ("socksproxy.outbound.length", value<std::string>()->default_value("3"), "SOCKS proxy outbound tunnel length")
("socksproxy.inbound.quantity", value<std::string>()->default_value("5"), "SOCKS proxy inbound tunnels quantity") ("socksproxy.inbound.quantity", value<std::string>()->default_value("5"), "SOCKS proxy inbound tunnels quantity")
("socksproxy.outbound.quantity", value<std::string>()->default_value("5"), "SOCKS proxy outbound tunnels quantity") ("socksproxy.outbound.quantity", value<std::string>()->default_value("5"), "SOCKS proxy outbound tunnels quantity")
("socksproxy.latency.min", value<int>()->default_value(0), "SOCKS proxy min latency for tunnels") ("socksproxy.latency.min", value<std::string>()->default_value("0"), "SOCKS proxy min latency for tunnels")
("socksproxy.latency.max", value<int>()->default_value(0), "SOCKS proxy max latency for tunnels") ("socksproxy.latency.max", value<std::string>()->default_value("0"), "SOCKS proxy max latency for tunnels")
("socksproxy.outproxy", value<std::string>()->default_value("127.0.0.1"), "Upstream outproxy address for SOCKS Proxy") ("socksproxy.outproxy", value<std::string>()->default_value("127.0.0.1"), "Upstream outproxy address for SOCKS Proxy")
("socksproxy.outproxyport", value<uint16_t>()->default_value(9050), "Upstream outproxy port for SOCKS Proxy") ("socksproxy.outproxyport", value<uint16_t>()->default_value(9050), "Upstream outproxy port for SOCKS Proxy")
; ;

25
Destination.cpp

@ -86,7 +86,7 @@ namespace client
if (m_IsRunning) if (m_IsRunning)
Stop (); Stop ();
for (auto& it: m_LeaseSetRequests) for (auto& it: m_LeaseSetRequests)
if (it.second->requestComplete) it.second->requestComplete (nullptr); it.second->Complete (nullptr);
m_LeaseSetRequests.clear (); m_LeaseSetRequests.clear ();
if (m_Pool) if (m_Pool)
i2p::tunnel::tunnels.DeleteTunnelPool (m_Pool); i2p::tunnel::tunnels.DeleteTunnelPool (m_Pool);
@ -345,7 +345,7 @@ namespace client
if (it1 != m_LeaseSetRequests.end ()) if (it1 != m_LeaseSetRequests.end ())
{ {
it1->second->requestTimeoutTimer.cancel (); it1->second->requestTimeoutTimer.cancel ();
if (it1->second->requestComplete) it1->second->requestComplete (leaseSet); if (it1->second) it1->second->Complete (leaseSet);
m_LeaseSetRequests.erase (it1); m_LeaseSetRequests.erase (it1);
} }
} }
@ -383,7 +383,7 @@ namespace client
if (!found) if (!found)
{ {
LogPrint (eLogInfo, "Destination: ", key.ToBase64 (), " was not found on ", MAX_NUM_FLOODFILLS_PER_REQUEST, " floodfills"); LogPrint (eLogInfo, "Destination: ", key.ToBase64 (), " was not found on ", MAX_NUM_FLOODFILLS_PER_REQUEST, " floodfills");
if (request->requestComplete) request->requestComplete (nullptr); request->Complete (nullptr);
m_LeaseSetRequests.erase (key); m_LeaseSetRequests.erase (key);
} }
} }
@ -512,9 +512,9 @@ namespace client
auto it = s->m_LeaseSetRequests.find (dest); auto it = s->m_LeaseSetRequests.find (dest);
if (it != s->m_LeaseSetRequests.end ()) if (it != s->m_LeaseSetRequests.end ())
{ {
auto requestComplete = it->second->requestComplete; auto requestComplete = it->second;
s->m_LeaseSetRequests.erase (it); s->m_LeaseSetRequests.erase (it);
if (notify && requestComplete) requestComplete (nullptr); if (notify && requestComplete) requestComplete->Complete (nullptr);
} }
}); });
} }
@ -526,7 +526,7 @@ namespace client
if (floodfill) if (floodfill)
{ {
auto request = std::make_shared<LeaseSetRequest> (m_Service); auto request = std::make_shared<LeaseSetRequest> (m_Service);
request->requestComplete = requestComplete; request->requestComplete.push_back (requestComplete);
auto ret = m_LeaseSetRequests.insert (std::pair<i2p::data::IdentHash, std::shared_ptr<LeaseSetRequest> >(dest,request)); auto ret = m_LeaseSetRequests.insert (std::pair<i2p::data::IdentHash, std::shared_ptr<LeaseSetRequest> >(dest,request));
if (ret.second) // inserted if (ret.second) // inserted
{ {
@ -534,20 +534,19 @@ namespace client
{ {
// request failed // request failed
m_LeaseSetRequests.erase (dest); m_LeaseSetRequests.erase (dest);
if (request->requestComplete) request->requestComplete (nullptr); requestComplete (nullptr);
} }
} }
else // duplicate else // duplicate
{ {
LogPrint (eLogWarning, "Destination: Request of LeaseSet ", dest.ToBase64 (), " is pending already"); LogPrint (eLogInfo, "Destination: Request of LeaseSet ", dest.ToBase64 (), " is pending already");
// TODO: queue up requests ret.first->second->requestComplete.push_back (requestComplete);
if (request->requestComplete) request->requestComplete (nullptr);
} }
} }
else else
{ {
LogPrint (eLogError, "Destination: Can't request LeaseSet, no floodfills found"); LogPrint (eLogError, "Destination: Can't request LeaseSet, no floodfills found");
if (requestComplete) requestComplete (nullptr); requestComplete (nullptr);
} }
} }
@ -622,9 +621,9 @@ namespace client
if (done) if (done)
{ {
auto requestComplete = it->second->requestComplete; auto requestComplete = it->second;
m_LeaseSetRequests.erase (it); m_LeaseSetRequests.erase (it);
if (requestComplete) requestComplete (nullptr); if (requestComplete) requestComplete->Complete (nullptr);
} }
} }
} }

8
Destination.h

@ -69,9 +69,15 @@ namespace client
std::set<i2p::data::IdentHash> excluded; std::set<i2p::data::IdentHash> excluded;
uint64_t requestTime; uint64_t requestTime;
boost::asio::deadline_timer requestTimeoutTimer; boost::asio::deadline_timer requestTimeoutTimer;
RequestComplete requestComplete; std::list<RequestComplete> requestComplete;
std::shared_ptr<i2p::tunnel::OutboundTunnel> outboundTunnel; std::shared_ptr<i2p::tunnel::OutboundTunnel> outboundTunnel;
std::shared_ptr<i2p::tunnel::InboundTunnel> replyTunnel; std::shared_ptr<i2p::tunnel::InboundTunnel> replyTunnel;
void Complete (std::shared_ptr<i2p::data::LeaseSet> ls)
{
for (auto& it: requestComplete) it (ls);
requestComplete.clear ();
}
}; };

42
Garlic.cpp

@ -20,6 +20,7 @@ namespace garlic
std::shared_ptr<const i2p::data::RoutingDestination> destination, int numTags, bool attachLeaseSet): std::shared_ptr<const i2p::data::RoutingDestination> destination, int numTags, bool attachLeaseSet):
m_Owner (owner), m_Destination (destination), m_NumTags (numTags), m_Owner (owner), m_Destination (destination), m_NumTags (numTags),
m_LeaseSetUpdateStatus (attachLeaseSet ? eLeaseSetUpdated : eLeaseSetDoNotSend), m_LeaseSetUpdateStatus (attachLeaseSet ? eLeaseSetUpdated : eLeaseSetDoNotSend),
m_LeaseSetUpdateMsgID (0),
m_ElGamalEncryption (new i2p::crypto::ElGamalEncryption (destination->GetEncryptionPublicKey ())) m_ElGamalEncryption (new i2p::crypto::ElGamalEncryption (destination->GetEncryptionPublicKey ()))
{ {
// create new session tags and session key // create new session tags and session key
@ -28,7 +29,7 @@ namespace garlic
} }
GarlicRoutingSession::GarlicRoutingSession (const uint8_t * sessionKey, const SessionTag& sessionTag): GarlicRoutingSession::GarlicRoutingSession (const uint8_t * sessionKey, const SessionTag& sessionTag):
m_Owner (nullptr), m_Destination (nullptr), m_NumTags (1), m_LeaseSetUpdateStatus (eLeaseSetDoNotSend) m_Owner (nullptr), m_Destination (nullptr), m_NumTags (1), m_LeaseSetUpdateStatus (eLeaseSetDoNotSend), m_LeaseSetUpdateMsgID (0)
{ {
memcpy (m_SessionKey, sessionKey, 32); memcpy (m_SessionKey, sessionKey, 32);
m_Encryption.SetKey (m_SessionKey); m_Encryption.SetKey (m_SessionKey);
@ -83,6 +84,7 @@ namespace garlic
if (msgID == m_LeaseSetUpdateMsgID) if (msgID == m_LeaseSetUpdateMsgID)
{ {
m_LeaseSetUpdateStatus = eLeaseSetUpToDate; m_LeaseSetUpdateStatus = eLeaseSetUpToDate;
m_LeaseSetUpdateMsgID = 0;
LogPrint (eLogInfo, "Garlic: LeaseSet update confirmed"); LogPrint (eLogInfo, "Garlic: LeaseSet update confirmed");
} }
else else
@ -117,7 +119,7 @@ namespace garlic
bool GarlicRoutingSession::CleanupExpiredTags () bool GarlicRoutingSession::CleanupExpiredTags ()
{ {
uint32_t ts = i2p::util::GetSecondsSinceEpoch (); auto ts = i2p::util::GetSecondsSinceEpoch ();
for (auto it = m_SessionTags.begin (); it != m_SessionTags.end ();) for (auto it = m_SessionTags.begin (); it != m_SessionTags.end ();)
{ {
if (ts >= it->creationTime + OUTGOING_TAGS_EXPIRATION_TIMEOUT) if (ts >= it->creationTime + OUTGOING_TAGS_EXPIRATION_TIMEOUT)
@ -126,6 +128,12 @@ namespace garlic
++it; ++it;
} }
CleanupUnconfirmedTags (); CleanupUnconfirmedTags ();
if (m_LeaseSetUpdateMsgID && ts*1000LL > m_LeaseSetSubmissionTime + LEASET_CONFIRMATION_TIMEOUT)
{
if (m_Owner)
m_Owner->RemoveDeliveryStatusSession (m_LeaseSetUpdateMsgID);
m_LeaseSetUpdateMsgID = 0;
}
return !m_SessionTags.empty () || !m_UnconfirmedTagsMsgs.empty (); return !m_SessionTags.empty () || !m_UnconfirmedTagsMsgs.empty ();
} }
@ -277,6 +285,7 @@ namespace garlic
{ {
newTags->msgID = msgID; newTags->msgID = msgID;
m_UnconfirmedTagsMsgs.emplace_back (newTags); m_UnconfirmedTagsMsgs.emplace_back (newTags);
newTags = nullptr; // got acquired
} }
m_Owner->DeliveryStatusSent (shared_from_this (), msgID); m_Owner->DeliveryStatusSent (shared_from_this (), msgID);
} }
@ -286,6 +295,7 @@ namespace garlic
// attach LeaseSet // attach LeaseSet
if (m_LeaseSetUpdateStatus == eLeaseSetUpdated) if (m_LeaseSetUpdateStatus == eLeaseSetUpdated)
{ {
if (m_LeaseSetUpdateMsgID) m_Owner->RemoveDeliveryStatusSession (m_LeaseSetUpdateMsgID); // remove previous
m_LeaseSetUpdateStatus = eLeaseSetSubmitted; m_LeaseSetUpdateStatus = eLeaseSetSubmitted;
m_LeaseSetUpdateMsgID = msgID; m_LeaseSetUpdateMsgID = msgID;
m_LeaseSetSubmissionTime = ts; m_LeaseSetSubmissionTime = ts;
@ -300,13 +310,14 @@ namespace garlic
size += CreateGarlicClove (payload + size, msg, m_Destination ? m_Destination->IsDestination () : false); size += CreateGarlicClove (payload + size, msg, m_Destination ? m_Destination->IsDestination () : false);
(*numCloves)++; (*numCloves)++;
} }
memset (payload + size, 0, 3); // certificate of message memset (payload + size, 0, 3); // certificate of message
size += 3; size += 3;
htobe32buf (payload + size, msgID); // MessageID htobe32buf (payload + size, msgID); // MessageID
size += 4; size += 4;
htobe64buf (payload + size, ts + 8000); // Expiration of message, 8 sec htobe64buf (payload + size, ts + 8000); // Expiration of message, 8 sec
size += 8; size += 8;
if (newTags) delete newTags; // not acquired, delete
return size; return size;
} }
@ -623,18 +634,29 @@ namespace garlic
LogPrint (eLogDebug, "Garlic: ", numExpiredTags, " tags expired for ", GetIdentHash().ToBase64 ()); LogPrint (eLogDebug, "Garlic: ", numExpiredTags, " tags expired for ", GetIdentHash().ToBase64 ());
// outgoing // outgoing
std::unique_lock<std::mutex> l(m_SessionsMutex);
for (auto it = m_Sessions.begin (); it != m_Sessions.end ();)
{ {
it->second->GetSharedRoutingPath (); // delete shared path if necessary std::unique_lock<std::mutex> l(m_SessionsMutex);
if (!it->second->CleanupExpiredTags ()) for (auto it = m_Sessions.begin (); it != m_Sessions.end ();)
{ {
LogPrint (eLogInfo, "Routing session to ", it->first.ToBase32 (), " deleted"); it->second->GetSharedRoutingPath (); // delete shared path if necessary
it = m_Sessions.erase (it); if (!it->second->CleanupExpiredTags ())
{
LogPrint (eLogInfo, "Routing session to ", it->first.ToBase32 (), " deleted");
it->second->SetOwner (nullptr);
it = m_Sessions.erase (it);
}
else
++it;
} }
}
// delivery status sessions
for (auto it = m_DeliveryStatusSessions.begin (); it != m_DeliveryStatusSessions.end (); )
{
if (it->second->GetOwner () != this)
it = m_DeliveryStatusSessions.erase (it);
else else
++it; ++it;
} }
} }
void GarlicDestination::RemoveDeliveryStatusSession (uint32_t msgID) void GarlicDestination::RemoveDeliveryStatusSession (uint32_t msgID)

3
Garlic.h

@ -111,6 +111,9 @@ namespace garlic
std::shared_ptr<GarlicRoutingPath> GetSharedRoutingPath (); std::shared_ptr<GarlicRoutingPath> GetSharedRoutingPath ();
void SetSharedRoutingPath (std::shared_ptr<GarlicRoutingPath> path); void SetSharedRoutingPath (std::shared_ptr<GarlicRoutingPath> path);
const GarlicDestination * GetOwner () const { return m_Owner; }
void SetOwner (GarlicDestination * owner) { m_Owner = owner; }
private: private:
size_t CreateAESBlock (uint8_t * buf, std::shared_ptr<const I2NPMessage> msg); size_t CreateAESBlock (uint8_t * buf, std::shared_ptr<const I2NPMessage> msg);

13
HTTPProxy.cpp

@ -29,7 +29,7 @@ namespace proxy {
static const char *pageHead = static const char *pageHead =
"<head>\r\n" "<head>\r\n"
" <title>I2P HTTP proxy: error</title>\r\n" " <title>I2Pd HTTP proxy</title>\r\n"
" <style type=\"text/css\">\r\n" " <style type=\"text/css\">\r\n"
" body { font: 100%/1.5em sans-serif; margin: 0; padding: 1.5em; background: #FAFAFA; color: #103456; }\r\n" " body { font: 100%/1.5em sans-serif; margin: 0; padding: 1.5em; background: #FAFAFA; color: #103456; }\r\n"
" .header { font-size: 2.5em; text-align: center; margin: 1.5em 0; color: #894C84; }\r\n" " .header { font-size: 2.5em; text-align: center; margin: 1.5em 0; color: #894C84; }\r\n"
@ -60,6 +60,7 @@ namespace proxy {
void HandleStreamRequestComplete (std::shared_ptr<i2p::stream::Stream> stream); void HandleStreamRequestComplete (std::shared_ptr<i2p::stream::Stream> stream);
/* error helpers */ /* error helpers */
void GenericProxyError(const char *title, const char *description); void GenericProxyError(const char *title, const char *description);
void GenericProxyInfo(const char *title, const char *description);
void HostNotFound(std::string & host); void HostNotFound(std::string & host);
void SendProxyError(std::string & content); void SendProxyError(std::string & content);
@ -107,6 +108,14 @@ namespace proxy {
SendProxyError(content); SendProxyError(content);
} }
void HTTPReqHandler::GenericProxyInfo(const char *title, const char *description) {
std::stringstream ss;
ss << "<h1>Proxy info: " << title << "</h1>\r\n";
ss << "<p>" << description << "</p>\r\n";
std::string content = ss.str();
SendProxyError(content);
}
void HTTPReqHandler::HostNotFound(std::string & host) { void HTTPReqHandler::HostNotFound(std::string & host) {
std::stringstream ss; std::stringstream ss;
ss << "<h1>Proxy error: Host not found</h1>\r\n" ss << "<h1>Proxy error: Host not found</h1>\r\n"
@ -216,7 +225,7 @@ namespace proxy {
std::stringstream ss; std::stringstream ss;
ss << "Host " << url.host << " added to router's addressbook from helper. " ss << "Host " << url.host << " added to router's addressbook from helper. "
<< "Click <a href=\"" << full_url << "\">here</a> to proceed."; << "Click <a href=\"" << full_url << "\">here</a> to proceed.";
GenericProxyError("Addresshelper found", ss.str().c_str()); GenericProxyInfo("Addresshelper found", ss.str().c_str());
return true; /* request processed */ return true; /* request processed */
} }

21
TunnelPool.cpp

@ -219,15 +219,6 @@ namespace tunnel
void TunnelPool::CreateTunnels () void TunnelPool::CreateTunnels ()
{ {
int num = 0; int num = 0;
{
std::unique_lock<std::mutex> l(m_InboundTunnelsMutex);
for (const auto& it : m_InboundTunnels)
if (it->IsEstablished ()) num++;
}
for (int i = num; i < m_NumInboundTunnels; i++)
CreateInboundTunnel ();
num = 0;
{ {
std::unique_lock<std::mutex> l(m_OutboundTunnelsMutex); std::unique_lock<std::mutex> l(m_OutboundTunnelsMutex);
for (const auto& it : m_OutboundTunnels) for (const auto& it : m_OutboundTunnels)
@ -235,6 +226,18 @@ namespace tunnel
} }
for (int i = num; i < m_NumOutboundTunnels; i++) for (int i = num; i < m_NumOutboundTunnels; i++)
CreateOutboundTunnel (); CreateOutboundTunnel ();
num = 0;
{
std::unique_lock<std::mutex> l(m_InboundTunnelsMutex);
for (const auto& it : m_InboundTunnels)
if (it->IsEstablished ()) num++;
}
for (int i = num; i < m_NumInboundTunnels; i++)
CreateInboundTunnel ();
if (num < m_NumInboundTunnels && m_NumInboundHops <= 0 && m_LocalDestination) // zero hops IB
m_LocalDestination->SetLeaseSetUpdated (); // update LeaseSet immediately
} }
void TunnelPool::TestTunnels () void TunnelPool::TestTunnels ()

Loading…
Cancel
Save