Tunnel.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947
  1. #include <string.h>
  2. #include "I2PEndian.h"
  3. #include <thread>
  4. #include <algorithm>
  5. #include <vector>
  6. #include "Crypto.h"
  7. #include "RouterContext.h"
  8. #include "Log.h"
  9. #include "Timestamp.h"
  10. #include "I2NPProtocol.h"
  11. #include "Transports.h"
  12. #include "NetDb.hpp"
  13. #include "Config.h"
  14. #include "Tunnel.h"
  15. #include "TunnelPool.h"
  16. #ifdef WITH_EVENTS
  17. #include "Event.h"
  18. #endif
  19. namespace i2p
  20. {
  21. namespace tunnel
  22. {
  23. Tunnel::Tunnel (std::shared_ptr<const TunnelConfig> config):
  24. TunnelBase (config->GetTunnelID (), config->GetNextTunnelID (), config->GetNextIdentHash ()),
  25. m_Config (config), m_Pool (nullptr), m_State (eTunnelStatePending), m_IsRecreated (false),
  26. m_Latency (0)
  27. {
  28. }
  29. Tunnel::~Tunnel ()
  30. {
  31. }
  32. void Tunnel::Build (uint32_t replyMsgID, std::shared_ptr<OutboundTunnel> outboundTunnel)
  33. {
  34. #ifdef WITH_EVENTS
  35. std::string peers = i2p::context.GetIdentity()->GetIdentHash().ToBase64();
  36. #endif
  37. auto numHops = m_Config->GetNumHops ();
  38. int numRecords = numHops <= STANDARD_NUM_RECORDS ? STANDARD_NUM_RECORDS : numHops;
  39. auto msg = NewI2NPShortMessage ();
  40. *msg->GetPayload () = numRecords;
  41. msg->len += numRecords*TUNNEL_BUILD_RECORD_SIZE + 1;
  42. // shuffle records
  43. std::vector<int> recordIndicies;
  44. for (int i = 0; i < numRecords; i++) recordIndicies.push_back(i);
  45. std::random_shuffle (recordIndicies.begin(), recordIndicies.end());
  46. // create real records
  47. uint8_t * records = msg->GetPayload () + 1;
  48. TunnelHopConfig * hop = m_Config->GetFirstHop ();
  49. int i = 0;
  50. BN_CTX * ctx = BN_CTX_new ();
  51. while (hop)
  52. {
  53. uint32_t msgID;
  54. if (hop->next) // we set replyMsgID for last hop only
  55. RAND_bytes ((uint8_t *)&msgID, 4);
  56. else
  57. msgID = replyMsgID;
  58. int idx = recordIndicies[i];
  59. hop->CreateBuildRequestRecord (records + idx*TUNNEL_BUILD_RECORD_SIZE, msgID, ctx);
  60. hop->recordIndex = idx;
  61. i++;
  62. #ifdef WITH_EVENTS
  63. peers += ":" + hop->ident->GetIdentHash().ToBase64();
  64. #endif
  65. hop = hop->next;
  66. }
  67. BN_CTX_free (ctx);
  68. #ifdef WITH_EVENTS
  69. EmitTunnelEvent("tunnel.build", this, peers);
  70. #endif
  71. // fill up fake records with random data
  72. for (int i = numHops; i < numRecords; i++)
  73. {
  74. int idx = recordIndicies[i];
  75. RAND_bytes (records + idx*TUNNEL_BUILD_RECORD_SIZE, TUNNEL_BUILD_RECORD_SIZE);
  76. }
  77. // decrypt real records
  78. i2p::crypto::CBCDecryption decryption;
  79. hop = m_Config->GetLastHop ()->prev;
  80. while (hop)
  81. {
  82. decryption.SetKey (hop->replyKey);
  83. // decrypt records after current hop
  84. TunnelHopConfig * hop1 = hop->next;
  85. while (hop1)
  86. {
  87. decryption.SetIV (hop->replyIV);
  88. uint8_t * record = records + hop1->recordIndex*TUNNEL_BUILD_RECORD_SIZE;
  89. decryption.Decrypt(record, TUNNEL_BUILD_RECORD_SIZE, record);
  90. hop1 = hop1->next;
  91. }
  92. hop = hop->prev;
  93. }
  94. msg->FillI2NPMessageHeader (eI2NPVariableTunnelBuild);
  95. // send message
  96. if (outboundTunnel)
  97. outboundTunnel->SendTunnelDataMsg (GetNextIdentHash (), 0, msg);
  98. else
  99. i2p::transport::transports.SendMessage (GetNextIdentHash (), msg);
  100. }
  101. bool Tunnel::HandleTunnelBuildResponse (uint8_t * msg, size_t len)
  102. {
  103. LogPrint (eLogDebug, "Tunnel: TunnelBuildResponse ", (int)msg[0], " records.");
  104. i2p::crypto::CBCDecryption decryption;
  105. TunnelHopConfig * hop = m_Config->GetLastHop ();
  106. while (hop)
  107. {
  108. decryption.SetKey (hop->replyKey);
  109. // decrypt records before and including current hop
  110. TunnelHopConfig * hop1 = hop;
  111. while (hop1)
  112. {
  113. auto idx = hop1->recordIndex;
  114. if (idx >= 0 && idx < msg[0])
  115. {
  116. uint8_t * record = msg + 1 + idx*TUNNEL_BUILD_RECORD_SIZE;
  117. decryption.SetIV (hop->replyIV);
  118. decryption.Decrypt(record, TUNNEL_BUILD_RECORD_SIZE, record);
  119. }
  120. else
  121. LogPrint (eLogWarning, "Tunnel: hop index ", idx, " is out of range");
  122. hop1 = hop1->prev;
  123. }
  124. hop = hop->prev;
  125. }
  126. bool established = true;
  127. hop = m_Config->GetFirstHop ();
  128. while (hop)
  129. {
  130. const uint8_t * record = msg + 1 + hop->recordIndex*TUNNEL_BUILD_RECORD_SIZE;
  131. uint8_t ret = record[BUILD_RESPONSE_RECORD_RET_OFFSET];
  132. LogPrint (eLogDebug, "Tunnel: Build response ret code=", (int)ret);
  133. auto profile = i2p::data::netdb.FindRouterProfile (hop->ident->GetIdentHash ());
  134. if (profile)
  135. profile->TunnelBuildResponse (ret);
  136. if (ret)
  137. // if any of participants declined the tunnel is not established
  138. established = false;
  139. hop = hop->next;
  140. }
  141. if (established)
  142. {
  143. // create tunnel decryptions from layer and iv keys in reverse order
  144. hop = m_Config->GetLastHop ();
  145. while (hop)
  146. {
  147. auto tunnelHop = new TunnelHop;
  148. tunnelHop->ident = hop->ident;
  149. tunnelHop->decryption.SetKeys (hop->layerKey, hop->ivKey);
  150. m_Hops.push_back (std::unique_ptr<TunnelHop>(tunnelHop));
  151. hop = hop->prev;
  152. }
  153. m_Config = nullptr;
  154. }
  155. if (established) m_State = eTunnelStateEstablished;
  156. return established;
  157. }
  158. bool Tunnel::LatencyFitsRange(uint64_t lower, uint64_t upper) const
  159. {
  160. auto latency = GetMeanLatency();
  161. return latency >= lower && latency <= upper;
  162. }
  163. void Tunnel::EncryptTunnelMsg (std::shared_ptr<const I2NPMessage> in, std::shared_ptr<I2NPMessage> out)
  164. {
  165. const uint8_t * inPayload = in->GetPayload () + 4;
  166. uint8_t * outPayload = out->GetPayload () + 4;
  167. for (auto& it: m_Hops)
  168. {
  169. it->decryption.Decrypt (inPayload, outPayload);
  170. inPayload = outPayload;
  171. }
  172. }
  173. void Tunnel::SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg)
  174. {
  175. LogPrint (eLogWarning, "Tunnel: Can't send I2NP messages without delivery instructions");
  176. }
  177. std::vector<std::shared_ptr<const i2p::data::IdentityEx> > Tunnel::GetPeers () const
  178. {
  179. auto peers = GetInvertedPeers ();
  180. std::reverse (peers.begin (), peers.end ());
  181. return peers;
  182. }
  183. std::vector<std::shared_ptr<const i2p::data::IdentityEx> > Tunnel::GetInvertedPeers () const
  184. {
  185. // hops are in inverted order
  186. std::vector<std::shared_ptr<const i2p::data::IdentityEx> > ret;
  187. for (auto& it: m_Hops)
  188. ret.push_back (it->ident);
  189. return ret;
  190. }
  191. void Tunnel::SetState(TunnelState state)
  192. {
  193. m_State = state;
  194. #ifdef WITH_EVENTS
  195. EmitTunnelEvent("tunnel.state", this, state);
  196. #endif
  197. }
  198. void Tunnel::PrintHops (std::stringstream& s) const
  199. {
  200. // hops are in inverted order, we must print in direct order
  201. for (auto it = m_Hops.rbegin (); it != m_Hops.rend (); it++)
  202. {
  203. s << " &#8658; ";
  204. s << i2p::data::GetIdentHashAbbreviation ((*it)->ident->GetIdentHash ());
  205. }
  206. }
  207. void InboundTunnel::HandleTunnelDataMsg (std::shared_ptr<const I2NPMessage> msg)
  208. {
  209. if (IsFailed ()) SetState (eTunnelStateEstablished); // incoming messages means a tunnel is alive
  210. auto newMsg = CreateEmptyTunnelDataMsg ();
  211. EncryptTunnelMsg (msg, newMsg);
  212. newMsg->from = shared_from_this ();
  213. m_Endpoint.HandleDecryptedTunnelDataMsg (newMsg);
  214. }
  215. void InboundTunnel::Print (std::stringstream& s) const
  216. {
  217. PrintHops (s);
  218. s << " &#8658; " << GetTunnelID () << ":me";
  219. }
  220. ZeroHopsInboundTunnel::ZeroHopsInboundTunnel ():
  221. InboundTunnel (std::make_shared<ZeroHopsTunnelConfig> ()),
  222. m_NumReceivedBytes (0)
  223. {
  224. }
  225. void ZeroHopsInboundTunnel::SendTunnelDataMsg (std::shared_ptr<i2p::I2NPMessage> msg)
  226. {
  227. if (msg)
  228. {
  229. m_NumReceivedBytes += msg->GetLength ();
  230. msg->from = shared_from_this ();
  231. HandleI2NPMessage (msg);
  232. }
  233. }
  234. void ZeroHopsInboundTunnel::Print (std::stringstream& s) const
  235. {
  236. s << " &#8658; " << GetTunnelID () << ":me";
  237. }
  238. void OutboundTunnel::SendTunnelDataMsg (const uint8_t * gwHash, uint32_t gwTunnel, std::shared_ptr<i2p::I2NPMessage> msg)
  239. {
  240. TunnelMessageBlock block;
  241. if (gwHash)
  242. {
  243. block.hash = gwHash;
  244. if (gwTunnel)
  245. {
  246. block.deliveryType = eDeliveryTypeTunnel;
  247. block.tunnelID = gwTunnel;
  248. }
  249. else
  250. block.deliveryType = eDeliveryTypeRouter;
  251. }
  252. else
  253. block.deliveryType = eDeliveryTypeLocal;
  254. block.data = msg;
  255. SendTunnelDataMsg ({block});
  256. }
  257. void OutboundTunnel::SendTunnelDataMsg (const std::vector<TunnelMessageBlock>& msgs)
  258. {
  259. std::unique_lock<std::mutex> l(m_SendMutex);
  260. for (auto& it : msgs)
  261. m_Gateway.PutTunnelDataMsg (it);
  262. m_Gateway.SendBuffer ();
  263. }
  264. void OutboundTunnel::HandleTunnelDataMsg (std::shared_ptr<const i2p::I2NPMessage> tunnelMsg)
  265. {
  266. LogPrint (eLogError, "Tunnel: incoming message for outbound tunnel ", GetTunnelID ());
  267. }
  268. void OutboundTunnel::Print (std::stringstream& s) const
  269. {
  270. s << GetTunnelID () << ":me";
  271. PrintHops (s);
  272. s << " &#8658; ";
  273. }
  274. ZeroHopsOutboundTunnel::ZeroHopsOutboundTunnel ():
  275. OutboundTunnel (std::make_shared<ZeroHopsTunnelConfig> ()),
  276. m_NumSentBytes (0)
  277. {
  278. }
  279. void ZeroHopsOutboundTunnel::SendTunnelDataMsg (const std::vector<TunnelMessageBlock>& msgs)
  280. {
  281. for (auto& msg : msgs)
  282. {
  283. switch (msg.deliveryType)
  284. {
  285. case eDeliveryTypeLocal:
  286. i2p::HandleI2NPMessage (msg.data);
  287. break;
  288. case eDeliveryTypeTunnel:
  289. i2p::transport::transports.SendMessage (msg.hash, i2p::CreateTunnelGatewayMsg (msg.tunnelID, msg.data));
  290. break;
  291. case eDeliveryTypeRouter:
  292. i2p::transport::transports.SendMessage (msg.hash, msg.data);
  293. break;
  294. default:
  295. LogPrint (eLogError, "Tunnel: Unknown delivery type ", (int)msg.deliveryType);
  296. }
  297. }
  298. }
  299. void ZeroHopsOutboundTunnel::Print (std::stringstream& s) const
  300. {
  301. s << GetTunnelID () << ":me &#8658; ";
  302. }
  303. Tunnels tunnels;
  304. Tunnels::Tunnels (): m_IsRunning (false), m_Thread (nullptr),
  305. m_NumSuccesiveTunnelCreations (0), m_NumFailedTunnelCreations (0)
  306. {
  307. }
  308. Tunnels::~Tunnels ()
  309. {
  310. }
  311. std::shared_ptr<TunnelBase> Tunnels::GetTunnel (uint32_t tunnelID)
  312. {
  313. auto it = m_Tunnels.find(tunnelID);
  314. if (it != m_Tunnels.end ())
  315. return it->second;
  316. return nullptr;
  317. }
  318. std::shared_ptr<InboundTunnel> Tunnels::GetPendingInboundTunnel (uint32_t replyMsgID)
  319. {
  320. return GetPendingTunnel (replyMsgID, m_PendingInboundTunnels);
  321. }
  322. std::shared_ptr<OutboundTunnel> Tunnels::GetPendingOutboundTunnel (uint32_t replyMsgID)
  323. {
  324. return GetPendingTunnel (replyMsgID, m_PendingOutboundTunnels);
  325. }
  326. template<class TTunnel>
  327. std::shared_ptr<TTunnel> Tunnels::GetPendingTunnel (uint32_t replyMsgID, const std::map<uint32_t, std::shared_ptr<TTunnel> >& pendingTunnels)
  328. {
  329. auto it = pendingTunnels.find(replyMsgID);
  330. if (it != pendingTunnels.end () && it->second->GetState () == eTunnelStatePending)
  331. {
  332. it->second->SetState (eTunnelStateBuildReplyReceived);
  333. return it->second;
  334. }
  335. return nullptr;
  336. }
  337. std::shared_ptr<InboundTunnel> Tunnels::GetNextInboundTunnel ()
  338. {
  339. std::shared_ptr<InboundTunnel> tunnel;
  340. size_t minReceived = 0;
  341. for (const auto& it : m_InboundTunnels)
  342. {
  343. if (!it->IsEstablished ()) continue;
  344. if (!tunnel || it->GetNumReceivedBytes () < minReceived)
  345. {
  346. tunnel = it;
  347. minReceived = it->GetNumReceivedBytes ();
  348. }
  349. }
  350. return tunnel;
  351. }
  352. std::shared_ptr<OutboundTunnel> Tunnels::GetNextOutboundTunnel ()
  353. {
  354. if (m_OutboundTunnels.empty ()) return nullptr;
  355. uint32_t ind = rand () % m_OutboundTunnels.size (), i = 0;
  356. std::shared_ptr<OutboundTunnel> tunnel;
  357. for (const auto& it: m_OutboundTunnels)
  358. {
  359. if (it->IsEstablished ())
  360. {
  361. tunnel = it;
  362. i++;
  363. }
  364. if (i > ind && tunnel) break;
  365. }
  366. return tunnel;
  367. }
  368. std::shared_ptr<TunnelPool> Tunnels::CreateTunnelPool (int numInboundHops,
  369. int numOutboundHops, int numInboundTunnels, int numOutboundTunnels)
  370. {
  371. auto pool = std::make_shared<TunnelPool> (numInboundHops, numOutboundHops, numInboundTunnels, numOutboundTunnels);
  372. std::unique_lock<std::mutex> l(m_PoolsMutex);
  373. m_Pools.push_back (pool);
  374. return pool;
  375. }
  376. void Tunnels::DeleteTunnelPool (std::shared_ptr<TunnelPool> pool)
  377. {
  378. if (pool)
  379. {
  380. StopTunnelPool (pool);
  381. {
  382. std::unique_lock<std::mutex> l(m_PoolsMutex);
  383. m_Pools.remove (pool);
  384. }
  385. }
  386. }
  387. void Tunnels::StopTunnelPool (std::shared_ptr<TunnelPool> pool)
  388. {
  389. if (pool)
  390. {
  391. pool->SetActive (false);
  392. pool->DetachTunnels ();
  393. }
  394. }
  395. void Tunnels::AddTransitTunnel (std::shared_ptr<TransitTunnel> tunnel)
  396. {
  397. if (m_Tunnels.emplace (tunnel->GetTunnelID (), tunnel).second)
  398. m_TransitTunnels.push_back (tunnel);
  399. else
  400. LogPrint (eLogError, "Tunnel: tunnel with id ", tunnel->GetTunnelID (), " already exists");
  401. }
  402. void Tunnels::Start ()
  403. {
  404. m_IsRunning = true;
  405. m_Thread = new std::thread (std::bind (&Tunnels::Run, this));
  406. }
  407. void Tunnels::Stop ()
  408. {
  409. m_IsRunning = false;
  410. m_Queue.WakeUp ();
  411. if (m_Thread)
  412. {
  413. m_Thread->join ();
  414. delete m_Thread;
  415. m_Thread = 0;
  416. }
  417. }
  418. void Tunnels::Run ()
  419. {
  420. std::this_thread::sleep_for (std::chrono::seconds(1)); // wait for other parts are ready
  421. uint64_t lastTs = 0;
  422. while (m_IsRunning)
  423. {
  424. try
  425. {
  426. auto msg = m_Queue.GetNextWithTimeout (1000); // 1 sec
  427. if (msg)
  428. {
  429. uint32_t prevTunnelID = 0, tunnelID = 0;
  430. std::shared_ptr<TunnelBase> prevTunnel;
  431. do
  432. {
  433. std::shared_ptr<TunnelBase> tunnel;
  434. uint8_t typeID = msg->GetTypeID ();
  435. switch (typeID)
  436. {
  437. case eI2NPTunnelData:
  438. case eI2NPTunnelGateway:
  439. {
  440. tunnelID = bufbe32toh (msg->GetPayload ());
  441. if (tunnelID == prevTunnelID)
  442. tunnel = prevTunnel;
  443. else if (prevTunnel)
  444. prevTunnel->FlushTunnelDataMsgs ();
  445. if (!tunnel)
  446. tunnel = GetTunnel (tunnelID);
  447. if (tunnel)
  448. {
  449. if (typeID == eI2NPTunnelData)
  450. tunnel->HandleTunnelDataMsg (msg);
  451. else // tunnel gateway assumed
  452. HandleTunnelGatewayMsg (tunnel, msg);
  453. }
  454. else
  455. LogPrint (eLogWarning, "Tunnel: tunnel not found, tunnelID=", tunnelID, " previousTunnelID=", prevTunnelID, " type=", (int)typeID);
  456. break;
  457. }
  458. case eI2NPVariableTunnelBuild:
  459. case eI2NPVariableTunnelBuildReply:
  460. case eI2NPTunnelBuild:
  461. case eI2NPTunnelBuildReply:
  462. HandleI2NPMessage (msg->GetBuffer (), msg->GetLength ());
  463. break;
  464. default:
  465. LogPrint (eLogWarning, "Tunnel: unexpected message type ", (int) typeID);
  466. }
  467. msg = m_Queue.Get ();
  468. if (msg)
  469. {
  470. prevTunnelID = tunnelID;
  471. prevTunnel = tunnel;
  472. }
  473. else if (tunnel)
  474. tunnel->FlushTunnelDataMsgs ();
  475. }
  476. while (msg);
  477. }
  478. uint64_t ts = i2p::util::GetSecondsSinceEpoch ();
  479. if (ts - lastTs >= 15) // manage tunnels every 15 seconds
  480. {
  481. ManageTunnels ();
  482. lastTs = ts;
  483. }
  484. }
  485. catch (std::exception& ex)
  486. {
  487. LogPrint (eLogError, "Tunnel: runtime exception: ", ex.what ());
  488. }
  489. }
  490. }
  491. void Tunnels::HandleTunnelGatewayMsg (std::shared_ptr<TunnelBase> tunnel, std::shared_ptr<I2NPMessage> msg)
  492. {
  493. if (!tunnel)
  494. {
  495. LogPrint (eLogError, "Tunnel: missing tunnel for gateway");
  496. return;
  497. }
  498. const uint8_t * payload = msg->GetPayload ();
  499. uint16_t len = bufbe16toh(payload + TUNNEL_GATEWAY_HEADER_LENGTH_OFFSET);
  500. // we make payload as new I2NP message to send
  501. msg->offset += I2NP_HEADER_SIZE + TUNNEL_GATEWAY_HEADER_SIZE;
  502. if (msg->offset + len > msg->len)
  503. {
  504. LogPrint (eLogError, "Tunnel: gateway payload ", (int)len, " exceeds message length ", (int)msg->len);
  505. return;
  506. }
  507. msg->len = msg->offset + len;
  508. auto typeID = msg->GetTypeID ();
  509. LogPrint (eLogDebug, "Tunnel: gateway of ", (int) len, " bytes for tunnel ", tunnel->GetTunnelID (), ", msg type ", (int)typeID);
  510. if (IsRouterInfoMsg (msg) || typeID == eI2NPDatabaseSearchReply)
  511. // transit DatabaseStore my contain new/updated RI
  512. // or DatabaseSearchReply with new routers
  513. i2p::data::netdb.PostI2NPMsg (CopyI2NPMessage (msg));
  514. tunnel->SendTunnelDataMsg (msg);
  515. }
  516. void Tunnels::ManageTunnels ()
  517. {
  518. ManagePendingTunnels ();
  519. ManageInboundTunnels ();
  520. ManageOutboundTunnels ();
  521. ManageTransitTunnels ();
  522. ManageTunnelPools ();
  523. }
  524. void Tunnels::ManagePendingTunnels ()
  525. {
  526. ManagePendingTunnels (m_PendingInboundTunnels);
  527. ManagePendingTunnels (m_PendingOutboundTunnels);
  528. }
  529. template<class PendingTunnels>
  530. void Tunnels::ManagePendingTunnels (PendingTunnels& pendingTunnels)
  531. {
  532. // check pending tunnel. delete failed or timeout
  533. uint64_t ts = i2p::util::GetSecondsSinceEpoch ();
  534. for (auto it = pendingTunnels.begin (); it != pendingTunnels.end ();)
  535. {
  536. auto tunnel = it->second;
  537. auto pool = tunnel->GetTunnelPool();
  538. switch (tunnel->GetState ())
  539. {
  540. case eTunnelStatePending:
  541. if (ts > tunnel->GetCreationTime () + TUNNEL_CREATION_TIMEOUT)
  542. {
  543. LogPrint (eLogDebug, "Tunnel: pending build request ", it->first, " timeout, deleted");
  544. // update stats
  545. auto config = tunnel->GetTunnelConfig ();
  546. if (config)
  547. {
  548. auto hop = config->GetFirstHop ();
  549. while (hop)
  550. {
  551. if (hop->ident)
  552. {
  553. auto profile = i2p::data::netdb.FindRouterProfile (hop->ident->GetIdentHash ());
  554. if (profile)
  555. profile->TunnelNonReplied ();
  556. }
  557. hop = hop->next;
  558. }
  559. }
  560. #ifdef WITH_EVENTS
  561. EmitTunnelEvent("tunnel.state", tunnel.get(), eTunnelStateBuildFailed);
  562. #endif
  563. // for i2lua
  564. if(pool) pool->OnTunnelBuildResult(tunnel, eBuildResultTimeout);
  565. // delete
  566. it = pendingTunnels.erase (it);
  567. m_NumFailedTunnelCreations++;
  568. }
  569. else
  570. ++it;
  571. break;
  572. case eTunnelStateBuildFailed:
  573. LogPrint (eLogDebug, "Tunnel: pending build request ", it->first, " failed, deleted");
  574. #ifdef WITH_EVENTS
  575. EmitTunnelEvent("tunnel.state", tunnel.get(), eTunnelStateBuildFailed);
  576. #endif
  577. // for i2lua
  578. if(pool) pool->OnTunnelBuildResult(tunnel, eBuildResultRejected);
  579. it = pendingTunnels.erase (it);
  580. m_NumFailedTunnelCreations++;
  581. break;
  582. case eTunnelStateBuildReplyReceived:
  583. // intermediate state, will be either established of build failed
  584. ++it;
  585. break;
  586. default:
  587. // success
  588. it = pendingTunnels.erase (it);
  589. m_NumSuccesiveTunnelCreations++;
  590. }
  591. }
  592. }
  593. void Tunnels::ManageOutboundTunnels ()
  594. {
  595. uint64_t ts = i2p::util::GetSecondsSinceEpoch ();
  596. {
  597. for (auto it = m_OutboundTunnels.begin (); it != m_OutboundTunnels.end ();)
  598. {
  599. auto tunnel = *it;
  600. if (ts > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT)
  601. {
  602. LogPrint (eLogDebug, "Tunnel: tunnel with id ", tunnel->GetTunnelID (), " expired");
  603. auto pool = tunnel->GetTunnelPool ();
  604. if (pool)
  605. pool->TunnelExpired (tunnel);
  606. // we don't have outbound tunnels in m_Tunnels
  607. it = m_OutboundTunnels.erase (it);
  608. }
  609. else
  610. {
  611. if (tunnel->IsEstablished ())
  612. {
  613. if (!tunnel->IsRecreated () && ts + TUNNEL_RECREATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT)
  614. {
  615. auto pool = tunnel->GetTunnelPool ();
  616. // let it die if the tunnel pool has been reconfigured and this is old
  617. if (pool && tunnel->GetNumHops() == pool->GetNumOutboundHops())
  618. {
  619. tunnel->SetIsRecreated ();
  620. pool->RecreateOutboundTunnel (tunnel);
  621. }
  622. }
  623. if (ts + TUNNEL_EXPIRATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT)
  624. tunnel->SetState (eTunnelStateExpiring);
  625. }
  626. ++it;
  627. }
  628. }
  629. }
  630. if (m_OutboundTunnels.size () < 3)
  631. {
  632. // trying to create one more oubound tunnel
  633. auto inboundTunnel = GetNextInboundTunnel ();
  634. auto router = i2p::transport::transports.RoutesRestricted() ?
  635. i2p::transport::transports.GetRestrictedPeer() :
  636. i2p::data::netdb.GetRandomRouter ();
  637. if (!inboundTunnel || !router) return;
  638. LogPrint (eLogDebug, "Tunnel: creating one hop outbound tunnel");
  639. CreateTunnel<OutboundTunnel> (
  640. std::make_shared<TunnelConfig> (std::vector<std::shared_ptr<const i2p::data::IdentityEx> > { router->GetRouterIdentity () },
  641. inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ())
  642. );
  643. }
  644. }
  645. void Tunnels::ManageInboundTunnels ()
  646. {
  647. uint64_t ts = i2p::util::GetSecondsSinceEpoch ();
  648. {
  649. for (auto it = m_InboundTunnels.begin (); it != m_InboundTunnels.end ();)
  650. {
  651. auto tunnel = *it;
  652. if (ts > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT)
  653. {
  654. LogPrint (eLogDebug, "Tunnel: tunnel with id ", tunnel->GetTunnelID (), " expired");
  655. auto pool = tunnel->GetTunnelPool ();
  656. if (pool)
  657. pool->TunnelExpired (tunnel);
  658. m_Tunnels.erase (tunnel->GetTunnelID ());
  659. it = m_InboundTunnels.erase (it);
  660. }
  661. else
  662. {
  663. if (tunnel->IsEstablished ())
  664. {
  665. if (!tunnel->IsRecreated () && ts + TUNNEL_RECREATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT)
  666. {
  667. auto pool = tunnel->GetTunnelPool ();
  668. // let it die if the tunnel pool was reconfigured and has different number of hops
  669. if (pool && tunnel->GetNumHops() == pool->GetNumInboundHops())
  670. {
  671. tunnel->SetIsRecreated ();
  672. pool->RecreateInboundTunnel (tunnel);
  673. }
  674. }
  675. if (ts + TUNNEL_EXPIRATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT)
  676. tunnel->SetState (eTunnelStateExpiring);
  677. else // we don't need to cleanup expiring tunnels
  678. tunnel->Cleanup ();
  679. }
  680. it++;
  681. }
  682. }
  683. }
  684. if (m_InboundTunnels.empty ())
  685. {
  686. LogPrint (eLogDebug, "Tunnel: Creating zero hops inbound tunnel");
  687. CreateZeroHopsInboundTunnel ();
  688. CreateZeroHopsOutboundTunnel ();
  689. if (!m_ExploratoryPool)
  690. {
  691. int ibLen; i2p::config::GetOption("exploratory.inbound.length", ibLen);
  692. int obLen; i2p::config::GetOption("exploratory.outbound.length", obLen);
  693. int ibNum; i2p::config::GetOption("exploratory.inbound.quantity", ibNum);
  694. int obNum; i2p::config::GetOption("exploratory.outbound.quantity", obNum);
  695. m_ExploratoryPool = CreateTunnelPool (ibLen, obLen, ibNum, obNum);
  696. m_ExploratoryPool->SetLocalDestination (i2p::context.GetSharedDestination ());
  697. }
  698. return;
  699. }
  700. if (m_OutboundTunnels.empty () || m_InboundTunnels.size () < 3)
  701. {
  702. // trying to create one more inbound tunnel
  703. auto router = i2p::transport::transports.RoutesRestricted() ?
  704. i2p::transport::transports.GetRestrictedPeer() :
  705. i2p::data::netdb.GetRandomRouter ();
  706. if (!router) {
  707. LogPrint (eLogWarning, "Tunnel: can't find any router, skip creating tunnel");
  708. return;
  709. }
  710. LogPrint (eLogDebug, "Tunnel: creating one hop inbound tunnel");
  711. CreateTunnel<InboundTunnel> (
  712. std::make_shared<TunnelConfig> (std::vector<std::shared_ptr<const i2p::data::IdentityEx> > { router->GetRouterIdentity () })
  713. );
  714. }
  715. }
  716. void Tunnels::ManageTransitTunnels ()
  717. {
  718. uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
  719. for (auto it = m_TransitTunnels.begin (); it != m_TransitTunnels.end ();)
  720. {
  721. auto tunnel = *it;
  722. if (ts > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT)
  723. {
  724. LogPrint (eLogDebug, "Tunnel: Transit tunnel with id ", tunnel->GetTunnelID (), " expired");
  725. m_Tunnels.erase (tunnel->GetTunnelID ());
  726. it = m_TransitTunnels.erase (it);
  727. }
  728. else
  729. {
  730. tunnel->Cleanup ();
  731. it++;
  732. }
  733. }
  734. }
  735. void Tunnels::ManageTunnelPools ()
  736. {
  737. std::unique_lock<std::mutex> l(m_PoolsMutex);
  738. for (auto& pool : m_Pools)
  739. {
  740. if (pool && pool->IsActive ())
  741. {
  742. pool->CreateTunnels ();
  743. pool->TestTunnels ();
  744. }
  745. }
  746. }
  747. void Tunnels::PostTunnelData (std::shared_ptr<I2NPMessage> msg)
  748. {
  749. if (msg) m_Queue.Put (msg);
  750. }
  751. void Tunnels::PostTunnelData (const std::vector<std::shared_ptr<I2NPMessage> >& msgs)
  752. {
  753. m_Queue.Put (msgs);
  754. }
  755. template<class TTunnel>
  756. std::shared_ptr<TTunnel> Tunnels::CreateTunnel (std::shared_ptr<TunnelConfig> config, std::shared_ptr<OutboundTunnel> outboundTunnel)
  757. {
  758. auto newTunnel = std::make_shared<TTunnel> (config);
  759. uint32_t replyMsgID;
  760. RAND_bytes ((uint8_t *)&replyMsgID, 4);
  761. AddPendingTunnel (replyMsgID, newTunnel);
  762. newTunnel->Build (replyMsgID, outboundTunnel);
  763. return newTunnel;
  764. }
  765. std::shared_ptr<InboundTunnel> Tunnels::CreateInboundTunnel (std::shared_ptr<TunnelConfig> config, std::shared_ptr<OutboundTunnel> outboundTunnel)
  766. {
  767. if (config)
  768. return CreateTunnel<InboundTunnel>(config, outboundTunnel);
  769. else
  770. return CreateZeroHopsInboundTunnel ();
  771. }
  772. std::shared_ptr<OutboundTunnel> Tunnels::CreateOutboundTunnel (std::shared_ptr<TunnelConfig> config)
  773. {
  774. if (config)
  775. return CreateTunnel<OutboundTunnel>(config);
  776. else
  777. return CreateZeroHopsOutboundTunnel ();
  778. }
  779. void Tunnels::AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr<InboundTunnel> tunnel)
  780. {
  781. m_PendingInboundTunnels[replyMsgID] = tunnel;
  782. }
  783. void Tunnels::AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr<OutboundTunnel> tunnel)
  784. {
  785. m_PendingOutboundTunnels[replyMsgID] = tunnel;
  786. }
  787. void Tunnels::AddOutboundTunnel (std::shared_ptr<OutboundTunnel> newTunnel)
  788. {
  789. // we don't need to insert it to m_Tunnels
  790. m_OutboundTunnels.push_back (newTunnel);
  791. auto pool = newTunnel->GetTunnelPool ();
  792. if (pool && pool->IsActive ())
  793. pool->TunnelCreated (newTunnel);
  794. else
  795. newTunnel->SetTunnelPool (nullptr);
  796. }
  797. void Tunnels::AddInboundTunnel (std::shared_ptr<InboundTunnel> newTunnel)
  798. {
  799. if (m_Tunnels.emplace (newTunnel->GetTunnelID (), newTunnel).second)
  800. {
  801. m_InboundTunnels.push_back (newTunnel);
  802. auto pool = newTunnel->GetTunnelPool ();
  803. if (!pool)
  804. {
  805. // build symmetric outbound tunnel
  806. CreateTunnel<OutboundTunnel> (std::make_shared<TunnelConfig>(newTunnel->GetInvertedPeers (),
  807. newTunnel->GetNextTunnelID (), newTunnel->GetNextIdentHash ()),
  808. GetNextOutboundTunnel ());
  809. }
  810. else
  811. {
  812. if (pool->IsActive ())
  813. pool->TunnelCreated (newTunnel);
  814. else
  815. newTunnel->SetTunnelPool (nullptr);
  816. }
  817. }
  818. else
  819. LogPrint (eLogError, "Tunnel: tunnel with id ", newTunnel->GetTunnelID (), " already exists");
  820. }
  821. std::shared_ptr<ZeroHopsInboundTunnel> Tunnels::CreateZeroHopsInboundTunnel ()
  822. {
  823. auto inboundTunnel = std::make_shared<ZeroHopsInboundTunnel> ();
  824. inboundTunnel->SetState (eTunnelStateEstablished);
  825. m_InboundTunnels.push_back (inboundTunnel);
  826. m_Tunnels[inboundTunnel->GetTunnelID ()] = inboundTunnel;
  827. return inboundTunnel;
  828. }
  829. std::shared_ptr<ZeroHopsOutboundTunnel> Tunnels::CreateZeroHopsOutboundTunnel ()
  830. {
  831. auto outboundTunnel = std::make_shared<ZeroHopsOutboundTunnel> ();
  832. outboundTunnel->SetState (eTunnelStateEstablished);
  833. m_OutboundTunnels.push_back (outboundTunnel);
  834. // we don't insert into m_Tunnels
  835. return outboundTunnel;
  836. }
  837. int Tunnels::GetTransitTunnelsExpirationTimeout ()
  838. {
  839. int timeout = 0;
  840. uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
  841. // TODO: possible race condition with I2PControl
  842. for (const auto& it : m_TransitTunnels)
  843. {
  844. int t = it->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT - ts;
  845. if (t > timeout) timeout = t;
  846. }
  847. return timeout;
  848. }
  849. size_t Tunnels::CountTransitTunnels() const
  850. {
  851. // TODO: locking
  852. return m_TransitTunnels.size();
  853. }
  854. size_t Tunnels::CountInboundTunnels() const
  855. {
  856. // TODO: locking
  857. return m_InboundTunnels.size();
  858. }
  859. size_t Tunnels::CountOutboundTunnels() const
  860. {
  861. // TODO: locking
  862. return m_OutboundTunnels.size();
  863. }
  864. }
  865. }