MatchedDestination.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #include "MatchedDestination.h"
  2. #include "Log.h"
  3. #include "ClientContext.h"
  4. namespace i2p
  5. {
  6. namespace client
  7. {
  8. MatchedTunnelDestination::MatchedTunnelDestination(const i2p::data::PrivateKeys & keys, const std::string & remoteName, const std::map<std::string, std::string> * params)
  9. : ClientDestination(keys, false, params),
  10. m_RemoteName(remoteName) {}
  11. void MatchedTunnelDestination::ResolveCurrentLeaseSet()
  12. {
  13. auto addr = i2p::client::context.GetAddressBook().GetAddress (m_RemoteName);
  14. if(addr && addr->IsIdentHash ())
  15. {
  16. m_RemoteIdent = addr->identHash;
  17. auto ls = FindLeaseSet(m_RemoteIdent);
  18. if(ls)
  19. HandleFoundCurrentLeaseSet(ls);
  20. else
  21. RequestDestination(m_RemoteIdent, std::bind(&MatchedTunnelDestination::HandleFoundCurrentLeaseSet, this, std::placeholders::_1));
  22. }
  23. else
  24. LogPrint(eLogWarning, "Destination: failed to resolve ", m_RemoteName);
  25. }
  26. void MatchedTunnelDestination::HandleFoundCurrentLeaseSet(std::shared_ptr<const i2p::data::LeaseSet> ls)
  27. {
  28. if(ls)
  29. {
  30. LogPrint(eLogDebug, "Destination: resolved remote lease set for ", m_RemoteName);
  31. m_RemoteLeaseSet = ls;
  32. }
  33. else
  34. {
  35. m_ResolveTimer->expires_from_now(boost::posix_time::seconds(1));
  36. m_ResolveTimer->async_wait([&](const boost::system::error_code & ec) {
  37. if(!ec) ResolveCurrentLeaseSet();
  38. });
  39. }
  40. }
  41. bool MatchedTunnelDestination::Start()
  42. {
  43. if(ClientDestination::Start())
  44. {
  45. m_ResolveTimer = std::make_shared<boost::asio::deadline_timer>(GetService());
  46. GetTunnelPool()->SetCustomPeerSelector(this);
  47. ResolveCurrentLeaseSet();
  48. return true;
  49. }
  50. else
  51. return false;
  52. }
  53. bool MatchedTunnelDestination::Stop()
  54. {
  55. if(ClientDestination::Stop())
  56. {
  57. if(m_ResolveTimer)
  58. m_ResolveTimer->cancel();
  59. return true;
  60. }
  61. else
  62. return false;
  63. }
  64. bool MatchedTunnelDestination::SelectPeers(i2p::tunnel::Path & path, int hops, bool inbound)
  65. {
  66. auto pool = GetTunnelPool();
  67. if(!i2p::tunnel::StandardSelectPeers(path, hops, inbound, std::bind(&i2p::tunnel::TunnelPool::SelectNextHop, pool, std::placeholders::_1)))
  68. return false;
  69. // more here for outbound tunnels
  70. if(!inbound && m_RemoteLeaseSet)
  71. {
  72. if(m_RemoteLeaseSet->IsExpired())
  73. {
  74. ResolveCurrentLeaseSet();
  75. }
  76. if(m_RemoteLeaseSet && !m_RemoteLeaseSet->IsExpired())
  77. {
  78. // remote lease set is good
  79. auto leases = m_RemoteLeaseSet->GetNonExpiredLeases();
  80. // pick lease
  81. std::shared_ptr<i2p::data::RouterInfo> obep;
  82. while(!obep && leases.size() > 0) {
  83. auto idx = rand() % leases.size();
  84. auto lease = leases[idx];
  85. obep = i2p::data::netdb.FindRouter(lease->tunnelGateway);
  86. leases.erase(leases.begin()+idx);
  87. }
  88. if(obep) {
  89. path.push_back(obep->GetRouterIdentity());
  90. LogPrint(eLogDebug, "Destination: found OBEP matching IBGW");
  91. } else
  92. LogPrint(eLogWarning, "Destination: could not find proper IBGW for matched outbound tunnel");
  93. }
  94. }
  95. return true;
  96. }
  97. bool MatchedTunnelDestination::OnBuildResult(const i2p::tunnel::Path & path, bool inbound, i2p::tunnel::TunnelBuildResult result)
  98. {
  99. return true;
  100. }
  101. }
  102. }