gnunet-service-cadet_connection.c 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2001-2017 GNUnet e.V.
  4. GNUnet is free software: you can redistribute it and/or modify it
  5. under the terms of the GNU Affero General Public License as published
  6. by the Free Software Foundation, either version 3 of the License,
  7. or (at your option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Affero General Public License for more details.
  12. You should have received a copy of the GNU Affero General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. SPDX-License-Identifier: AGPL3.0-or-later
  15. */
  16. /**
  17. * @file cadet/gnunet-service-cadet_connection.c
  18. * @brief management of CORE-level end-to-end connections; establishes
  19. * end-to-end routes and transmits messages along the route
  20. * @author Bartlomiej Polot
  21. * @author Christian Grothoff
  22. */
  23. #include "platform.h"
  24. #include "gnunet_signatures.h"
  25. #include "gnunet-service-cadet_connection.h"
  26. #include "gnunet-service-cadet_channel.h"
  27. #include "gnunet-service-cadet_paths.h"
  28. #include "gnunet-service-cadet_tunnels.h"
  29. #include "gnunet_cadet_service.h"
  30. #include "gnunet_statistics_service.h"
  31. #include "cadet_protocol.h"
  32. #define LOG(level, ...) GNUNET_log_from (level, "cadet-con", __VA_ARGS__)
  33. /**
  34. * How long do we wait initially before retransmitting the KX?
  35. * TODO: replace by 2 RTT if/once we have connection-level RTT data!
  36. */
  37. #define INITIAL_CONNECTION_CREATE_RETRY_DELAY \
  38. GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 200)
  39. /**
  40. * All the states a connection can be in.
  41. */
  42. enum CadetConnectionState
  43. {
  44. /**
  45. * Uninitialized status, we have not yet even gotten the message queue.
  46. */
  47. CADET_CONNECTION_NEW,
  48. /**
  49. * Connection create message in queue, awaiting transmission by CORE.
  50. */
  51. CADET_CONNECTION_SENDING_CREATE,
  52. /**
  53. * Connection create message sent, waiting for ACK.
  54. */
  55. CADET_CONNECTION_SENT,
  56. /**
  57. * We are an inbound connection, and received a CREATE. Need to
  58. * send an CREATE_ACK back.
  59. */
  60. CADET_CONNECTION_CREATE_RECEIVED,
  61. /**
  62. * Connection confirmed, ready to carry traffic.
  63. */
  64. CADET_CONNECTION_READY
  65. };
  66. /**
  67. * Low-level connection to a destination.
  68. */
  69. struct CadetConnection
  70. {
  71. /**
  72. * ID of the connection.
  73. */
  74. struct GNUNET_CADET_ConnectionTunnelIdentifier cid;
  75. /**
  76. * To which peer does this connection go?
  77. */
  78. struct CadetPeer *destination;
  79. /**
  80. * Which tunnel is using this connection?
  81. */
  82. struct CadetTConnection *ct;
  83. /**
  84. * Path we are using to our destination.
  85. */
  86. struct CadetPeerPath *path;
  87. /**
  88. * Pending message, NULL if we are ready to transmit.
  89. */
  90. struct GNUNET_MQ_Envelope *env;
  91. /**
  92. * Handle for calling #GCP_request_mq_cancel() once we are finished.
  93. */
  94. struct GCP_MessageQueueManager *mq_man;
  95. /**
  96. * Task for connection maintenance.
  97. */
  98. struct GNUNET_SCHEDULER_Task *task;
  99. /**
  100. * Queue entry for keepalive messages.
  101. */
  102. struct CadetTunnelQueueEntry *keepalive_qe;
  103. /**
  104. * Function to call once we are ready to transmit.
  105. */
  106. GCC_ReadyCallback ready_cb;
  107. /**
  108. * Closure for @e ready_cb.
  109. */
  110. void *ready_cb_cls;
  111. /**
  112. * How long do we wait before we try again with a CREATE message?
  113. */
  114. struct GNUNET_TIME_Relative retry_delay;
  115. /**
  116. * Earliest time for re-trying CREATE
  117. */
  118. struct GNUNET_TIME_Absolute create_at;
  119. /**
  120. * Earliest time for re-trying CREATE_ACK
  121. */
  122. struct GNUNET_TIME_Absolute create_ack_at;
  123. /**
  124. * Performance metrics for this connection.
  125. */
  126. struct CadetConnectionMetrics metrics;
  127. /**
  128. * State of the connection.
  129. */
  130. enum CadetConnectionState state;
  131. /**
  132. * How many latency observations did we make for this connection?
  133. */
  134. unsigned int latency_datapoints;
  135. /**
  136. * Offset of our @e destination in @e path.
  137. */
  138. unsigned int off;
  139. /**
  140. * Are we ready to transmit via @e mq_man right now?
  141. */
  142. int mqm_ready;
  143. };
  144. /**
  145. * Lookup a connection by its identifier.
  146. *
  147. * @param cid identifier to resolve
  148. * @return NULL if connection was not found
  149. */
  150. struct CadetConnection *
  151. GCC_lookup (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
  152. {
  153. return GNUNET_CONTAINER_multishortmap_get (connections,
  154. &cid->connection_of_tunnel);
  155. }
  156. /**
  157. * Update the connection state. Also triggers the necessary
  158. * MQM notifications.
  159. *
  160. * @param cc connection to update the state for
  161. * @param new_state new state for @a cc
  162. * @param new_mqm_ready new `mqm_ready` state for @a cc
  163. */
  164. static void
  165. update_state (struct CadetConnection *cc,
  166. enum CadetConnectionState new_state,
  167. int new_mqm_ready)
  168. {
  169. int old_ready;
  170. int new_ready;
  171. LOG (GNUNET_ERROR_TYPE_DEBUG,
  172. "Trying to update connection state for %s having old state %d to new %d and mqm_ready old %d to mqm_ready new %d\n",
  173. GCT_2s (cc->ct->t),
  174. cc->state,
  175. new_state,
  176. cc->mqm_ready,
  177. new_mqm_ready);
  178. if ((new_state == cc->state) && (new_mqm_ready == cc->mqm_ready))
  179. return; /* no change, nothing to do */
  180. old_ready =
  181. ((CADET_CONNECTION_READY == cc->state) && (GNUNET_YES == cc->mqm_ready));
  182. new_ready =
  183. ((CADET_CONNECTION_READY == new_state) && (GNUNET_YES == new_mqm_ready));
  184. cc->state = new_state;
  185. cc->mqm_ready = new_mqm_ready;
  186. LOG (GNUNET_ERROR_TYPE_DEBUG,
  187. "Updating connection state for %s having old_ready %d and new_rady %d\n",
  188. GCT_2s (cc->ct->t),
  189. old_ready,
  190. new_ready);
  191. if (old_ready != new_ready)
  192. cc->ready_cb (cc->ready_cb_cls, new_ready);
  193. }
  194. /**
  195. * Destroy a connection, part of the internal implementation. Called
  196. * only from #GCC_destroy_from_core() or #GCC_destroy_from_tunnel().
  197. *
  198. * @param cc connection to destroy
  199. */
  200. static void
  201. GCC_destroy (struct CadetConnection *cc)
  202. {
  203. LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroying %s\n", GCC_2s (cc));
  204. if (NULL != cc->mq_man)
  205. {
  206. GCP_request_mq_cancel (cc->mq_man, NULL);
  207. cc->mq_man = NULL;
  208. }
  209. if (NULL != cc->task)
  210. {
  211. GNUNET_SCHEDULER_cancel (cc->task);
  212. cc->task = NULL;
  213. }
  214. if (NULL != cc->keepalive_qe)
  215. {
  216. GCT_send_cancel (cc->keepalive_qe);
  217. cc->keepalive_qe = NULL;
  218. }
  219. GCPP_del_connection (cc->path, cc->off, cc);
  220. for (unsigned int i = 0; i < cc->off; i++)
  221. GCP_remove_connection (GCPP_get_peer_at_offset (cc->path, i), cc);
  222. GNUNET_assert (
  223. GNUNET_YES ==
  224. GNUNET_CONTAINER_multishortmap_remove (connections,
  225. &GCC_get_id (cc)
  226. ->connection_of_tunnel,
  227. cc));
  228. GNUNET_free (cc);
  229. }
  230. /**
  231. * Destroy a connection, called when the CORE layer is already done
  232. * (i.e. has received a BROKEN message), but if we still have to
  233. * communicate the destruction of the connection to the tunnel (if one
  234. * exists).
  235. *
  236. * @param cc connection to destroy
  237. */
  238. void
  239. GCC_destroy_without_core (struct CadetConnection *cc)
  240. {
  241. if (NULL != cc->ct)
  242. {
  243. GCT_connection_lost (cc->ct);
  244. cc->ct = NULL;
  245. }
  246. GCC_destroy (cc);
  247. }
  248. /**
  249. * Destroy a connection, called if the tunnel association with the
  250. * connection was already broken, but we still need to notify the CORE
  251. * layer about the breakage.
  252. *
  253. * @param cc connection to destroy
  254. */
  255. void
  256. GCC_destroy_without_tunnel (struct CadetConnection *cc)
  257. {
  258. cc->ct = NULL;
  259. if ((CADET_CONNECTION_SENDING_CREATE != cc->state) && (NULL != cc->mq_man))
  260. {
  261. struct GNUNET_MQ_Envelope *env;
  262. struct GNUNET_CADET_ConnectionDestroyMessage *destroy_msg;
  263. /* Need to notify next hop that we are down. */
  264. env =
  265. GNUNET_MQ_msg (destroy_msg, GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY);
  266. destroy_msg->cid = cc->cid;
  267. GCP_request_mq_cancel (cc->mq_man, env);
  268. cc->mq_man = NULL;
  269. }
  270. GCC_destroy (cc);
  271. }
  272. /**
  273. * Return the tunnel associated with this connection.
  274. *
  275. * @param cc connection to query
  276. * @return corresponding entry in the tunnel's connection list
  277. */
  278. struct CadetTConnection *
  279. GCC_get_ct (struct CadetConnection *cc)
  280. {
  281. return cc->ct;
  282. }
  283. /**
  284. * Obtain performance @a metrics from @a cc.
  285. *
  286. * @param cc connection to query
  287. * @return the metrics
  288. */
  289. const struct CadetConnectionMetrics *
  290. GCC_get_metrics (struct CadetConnection *cc)
  291. {
  292. return &cc->metrics;
  293. }
  294. /**
  295. * Send a #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE through the
  296. * tunnel to prevent it from timing out.
  297. *
  298. * @param cls the `struct CadetConnection` to keep alive.
  299. */
  300. static void
  301. send_keepalive (void *cls);
  302. /**
  303. * Keepalive was transmitted. Remember this, and possibly
  304. * schedule the next one.
  305. *
  306. * @param cls the `struct CadetConnection` to keep alive.
  307. * @param cid identifier of the connection within the tunnel, NULL
  308. * if transmission failed
  309. */
  310. static void
  311. keepalive_done (void *cls,
  312. const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
  313. {
  314. struct CadetConnection *cc = cls;
  315. cc->keepalive_qe = NULL;
  316. if ((GNUNET_YES == cc->mqm_ready) && (NULL == cc->task))
  317. cc->task =
  318. GNUNET_SCHEDULER_add_delayed (keepalive_period, &send_keepalive, cc);
  319. }
  320. /**
  321. * Send a #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE through the
  322. * tunnel to prevent it from timing out.
  323. *
  324. * @param cls the `struct CadetConnection` to keep alive.
  325. */
  326. static void
  327. send_keepalive (void *cls)
  328. {
  329. struct CadetConnection *cc = cls;
  330. struct GNUNET_MessageHeader msg;
  331. cc->task = NULL;
  332. if (CADET_TUNNEL_KEY_OK != GCT_get_estate (cc->ct->t))
  333. {
  334. /* Tunnel not yet ready, wait with keepalives... */
  335. cc->task =
  336. GNUNET_SCHEDULER_add_delayed (keepalive_period, &send_keepalive, cc);
  337. return;
  338. }
  339. GNUNET_assert (NULL != cc->ct);
  340. GNUNET_assert (GNUNET_YES == cc->mqm_ready);
  341. GNUNET_assert (NULL == cc->keepalive_qe);
  342. LOG (GNUNET_ERROR_TYPE_INFO,
  343. "Sending KEEPALIVE on behalf of %s via %s\n",
  344. GCC_2s (cc),
  345. GCT_2s (cc->ct->t));
  346. GNUNET_STATISTICS_update (stats, "# keepalives sent", 1, GNUNET_NO);
  347. msg.size = htons (sizeof(msg));
  348. msg.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE);
  349. cc->keepalive_qe = GCT_send (cc->ct->t, &msg, &keepalive_done, cc, NULL);
  350. }
  351. /**
  352. * We sent a message for which we expect to receive an ACK via
  353. * the connection identified by @a cti.
  354. *
  355. * @param cid connection identifier where we expect an ACK
  356. */
  357. void
  358. GCC_ack_expected (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
  359. {
  360. struct CadetConnection *cc;
  361. cc = GCC_lookup (cid);
  362. if (NULL == cc)
  363. return; /* whopise, connection alredy down? */
  364. cc->metrics.num_acked_transmissions++;
  365. }
  366. /**
  367. * We observed an ACK for a message that was originally sent via
  368. * the connection identified by @a cti.
  369. *
  370. * @param cti connection identifier where we got an ACK for a message
  371. * that was originally sent via this connection (the ACK
  372. * may have gotten back to us via a different connection).
  373. */
  374. void
  375. GCC_ack_observed (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
  376. {
  377. struct CadetConnection *cc;
  378. cc = GCC_lookup (cid);
  379. if (NULL == cc)
  380. return; /* whopise, connection alredy down? */
  381. cc->metrics.num_successes++;
  382. }
  383. /**
  384. * We observed some the given @a latency on the connection
  385. * identified by @a cti. (The same connection was taken
  386. * in both directions.)
  387. *
  388. * @param cid connection identifier where we measured latency
  389. * @param latency the observed latency
  390. */
  391. void
  392. GCC_latency_observed (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
  393. struct GNUNET_TIME_Relative latency)
  394. {
  395. struct CadetConnection *cc;
  396. double weight;
  397. double result;
  398. cc = GCC_lookup (cid);
  399. if (NULL == cc)
  400. return; /* whopise, connection alredy down? */
  401. GNUNET_STATISTICS_update (stats, "# latencies observed", 1, GNUNET_NO);
  402. cc->latency_datapoints++;
  403. if (cc->latency_datapoints >= 7)
  404. weight = 7.0;
  405. else
  406. weight = cc->latency_datapoints;
  407. /* Compute weighted average, giving at MOST weight 7 to the
  408. existing values, or less if that value is based on fewer than 7
  409. measurements. */
  410. result = (weight * cc->metrics.aged_latency.rel_value_us)
  411. + 1.0 * latency.rel_value_us;
  412. result /= (weight + 1.0);
  413. cc->metrics.aged_latency.rel_value_us = (uint64_t) result;
  414. }
  415. /**
  416. * A #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK was received for
  417. * this connection, implying that the end-to-end connection is up.
  418. * Process it.
  419. *
  420. * @param cc the connection that got the ACK.
  421. */
  422. void
  423. GCC_handle_connection_create_ack (struct CadetConnection *cc)
  424. {
  425. LOG (GNUNET_ERROR_TYPE_DEBUG,
  426. "Received CADET_CONNECTION_CREATE_ACK for %s in state %d (%s)\n",
  427. GCC_2s (cc),
  428. cc->state,
  429. (GNUNET_YES == cc->mqm_ready) ? "MQM ready" : "MQM busy");
  430. if (CADET_CONNECTION_READY == cc->state)
  431. return; /* Duplicate ACK, ignore */
  432. if (NULL != cc->task)
  433. {
  434. GNUNET_SCHEDULER_cancel (cc->task);
  435. cc->task = NULL;
  436. }
  437. cc->metrics.age = GNUNET_TIME_absolute_get ();
  438. update_state (cc, CADET_CONNECTION_READY, cc->mqm_ready);
  439. if ((NULL == cc->keepalive_qe) && (GNUNET_YES == cc->mqm_ready) &&
  440. (NULL == cc->task))
  441. cc->task =
  442. GNUNET_SCHEDULER_add_delayed (keepalive_period, &send_keepalive, cc);
  443. }
  444. /**
  445. * Handle KX message.
  446. *
  447. * @param cc connection that received encrypted message
  448. * @param msg the key exchange message
  449. */
  450. void
  451. GCC_handle_kx (struct CadetConnection *cc,
  452. const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg)
  453. {
  454. LOG (GNUNET_ERROR_TYPE_DEBUG,
  455. "Received KX message with ephermal %s on CC %s in state %d\n",
  456. GNUNET_e2s (&msg->ephemeral_key),
  457. GNUNET_sh2s (&cc->cid.connection_of_tunnel),
  458. cc->state);
  459. if (CADET_CONNECTION_SENT == cc->state)
  460. {
  461. /* We didn't get the CADET_CONNECTION_CREATE_ACK, but instead got payload. That's fine,
  462. clearly something is working, so pretend we got an ACK. */
  463. LOG (GNUNET_ERROR_TYPE_DEBUG,
  464. "Faking connection CADET_CONNECTION_CREATE_ACK for %s due to KX\n",
  465. GCC_2s (cc));
  466. GCC_handle_connection_create_ack (cc);
  467. }
  468. GCT_handle_kx (cc->ct, msg);
  469. }
  470. /**
  471. * Handle KX_AUTH message.
  472. *
  473. * @param cc connection that received encrypted message
  474. * @param msg the key exchange message
  475. */
  476. void
  477. GCC_handle_kx_auth (struct CadetConnection *cc,
  478. const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage *msg)
  479. {
  480. LOG (GNUNET_ERROR_TYPE_DEBUG,
  481. "Received KX AUTH message with ephermal %s on CC %s in state %d\n",
  482. GNUNET_e2s (&msg->kx.ephemeral_key),
  483. GNUNET_sh2s (&cc->cid.connection_of_tunnel),
  484. cc->state);
  485. if (CADET_CONNECTION_SENT == cc->state)
  486. {
  487. /* We didn't get the CADET_CONNECTION_CREATE_ACK, but instead got payload. That's fine,
  488. clearly something is working, so pretend we got an ACK. */
  489. LOG (GNUNET_ERROR_TYPE_DEBUG,
  490. "Faking connection CADET_CONNECTION_CREATE_ACK for %s due to KX\n",
  491. GCC_2s (cc));
  492. GCC_handle_connection_create_ack (cc);
  493. }
  494. GCT_handle_kx_auth (cc->ct, msg);
  495. }
  496. /**
  497. * Handle encrypted message.
  498. *
  499. * @param cc connection that received encrypted message
  500. * @param msg the encrypted message to decrypt
  501. */
  502. void
  503. GCC_handle_encrypted (struct CadetConnection *cc,
  504. const struct GNUNET_CADET_TunnelEncryptedMessage *msg)
  505. {
  506. if (CADET_CONNECTION_SENT == cc->state)
  507. {
  508. /* We didn't get the CREATE_ACK, but instead got payload. That's fine,
  509. clearly something is working, so pretend we got an ACK. */
  510. LOG (GNUNET_ERROR_TYPE_DEBUG,
  511. "Faking connection ACK for %s due to ENCRYPTED payload\n",
  512. GCC_2s (cc));
  513. GCC_handle_connection_create_ack (cc);
  514. }
  515. cc->metrics.last_use = GNUNET_TIME_absolute_get ();
  516. GCT_handle_encrypted (cc->ct, msg);
  517. }
  518. /**
  519. * Set the signature for a monotime value on a GNUNET_CADET_ConnectionCreateMessage.
  520. *
  521. * @param msg The GNUNET_CADET_ConnectionCreateMessage.
  522. */
  523. void
  524. set_monotime_sig (struct GNUNET_CADET_ConnectionCreateMessage *msg)
  525. {
  526. struct CadetConnectionCreatePS cp = { .purpose.purpose = htonl (
  527. GNUNET_SIGNATURE_PURPOSE_CADET_CONNECTION_INITIATOR),
  528. .purpose.size = htonl (sizeof(cp)),
  529. .monotonic_time = msg->monotime};
  530. GNUNET_CRYPTO_eddsa_sign (my_private_key, &cp,
  531. &msg->monotime_sig);
  532. }
  533. /**
  534. * Send a #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE message to the
  535. * first hop.
  536. *
  537. * @param cls the `struct CadetConnection` to initiate
  538. */
  539. static void
  540. send_create (void *cls)
  541. {
  542. struct CadetConnection *cc = cls;
  543. struct GNUNET_CADET_ConnectionCreateMessage *create_msg;
  544. struct GNUNET_PeerIdentity *pids;
  545. struct GNUNET_MQ_Envelope *env;
  546. struct CadetTunnel *t;
  547. cc->task = NULL;
  548. GNUNET_assert (GNUNET_YES == cc->mqm_ready);
  549. env =
  550. GNUNET_MQ_msg_extra (create_msg,
  551. (2 + cc->off) * sizeof(struct GNUNET_PeerIdentity),
  552. GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE);
  553. // TODO This will be removed in a major release, because this will be a protocol breaking change. We set the deprecated 'reliable' bit here that was removed.
  554. create_msg->options = 2;
  555. create_msg->cid = cc->cid;
  556. // check for tunnel state and set signed monotime (xrs,t3ss)
  557. t = GCP_get_tunnel (cc->destination, GNUNET_YES);
  558. if ((NULL != t) && (GCT_get_estate (t) == CADET_TUNNEL_KEY_UNINITIALIZED) &&
  559. (GCT_alice_or_betty (GCP_get_id (cc->destination)) == GNUNET_NO))
  560. {
  561. create_msg->has_monotime = GNUNET_YES;
  562. create_msg->monotime = GNUNET_TIME_absolute_hton (
  563. GNUNET_TIME_absolute_get_monotonic (cfg));
  564. set_monotime_sig (create_msg);
  565. }
  566. pids = (struct GNUNET_PeerIdentity *) &create_msg[1];
  567. pids[0] = my_full_id;
  568. for (unsigned int i = 0; i <= cc->off; i++)
  569. pids[i + 1] = *GCP_get_id (GCPP_get_peer_at_offset (cc->path, i));
  570. LOG (GNUNET_ERROR_TYPE_DEBUG,
  571. "Sending CADET_CONNECTION_CREATE message for %s with %u hops\n",
  572. GCC_2s (cc),
  573. cc->off + 2);
  574. cc->env = env;
  575. cc->retry_delay = GNUNET_TIME_STD_BACKOFF (cc->retry_delay);
  576. cc->create_at = GNUNET_TIME_relative_to_absolute (cc->retry_delay);
  577. update_state (cc, CADET_CONNECTION_SENT, GNUNET_NO);
  578. GCP_send (cc->mq_man, env);
  579. }
  580. /**
  581. * Send a CREATE_ACK message towards the origin.
  582. *
  583. * @param cls the `struct CadetConnection` to initiate
  584. */
  585. static void
  586. send_create_ack (void *cls)
  587. {
  588. struct CadetConnection *cc = cls;
  589. struct GNUNET_CADET_ConnectionCreateAckMessage *ack_msg;
  590. struct GNUNET_MQ_Envelope *env;
  591. cc->task = NULL;
  592. LOG (GNUNET_ERROR_TYPE_DEBUG,
  593. "Sending CONNECTION_CREATE_ACK message for %s\n",
  594. GCC_2s (cc));
  595. GNUNET_assert (GNUNET_YES == cc->mqm_ready);
  596. env =
  597. GNUNET_MQ_msg (ack_msg, GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK);
  598. ack_msg->cid = cc->cid;
  599. cc->env = env;
  600. cc->retry_delay = GNUNET_TIME_STD_BACKOFF (cc->retry_delay);
  601. cc->create_ack_at = GNUNET_TIME_relative_to_absolute (cc->retry_delay);
  602. if (CADET_CONNECTION_CREATE_RECEIVED == cc->state)
  603. update_state (cc, CADET_CONNECTION_READY, GNUNET_NO);
  604. if (CADET_CONNECTION_READY == cc->state)
  605. cc->task =
  606. GNUNET_SCHEDULER_add_delayed (keepalive_period, &send_keepalive, cc);
  607. GCP_send (cc->mq_man, env);
  608. }
  609. /**
  610. * We got a #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE for a
  611. * connection that we already have. Either our ACK got lost
  612. * or something is fishy. Consider retransmitting the ACK.
  613. *
  614. * @param cc connection that got the duplicate CREATE
  615. */
  616. void
  617. GCC_handle_duplicate_create (struct CadetConnection *cc)
  618. {
  619. if (GNUNET_YES == cc->mqm_ready)
  620. {
  621. LOG (GNUNET_ERROR_TYPE_DEBUG,
  622. "Got duplicate CREATE for %s, scheduling another ACK (%s)\n",
  623. GCC_2s (cc),
  624. (GNUNET_YES == cc->mqm_ready) ? "MQM ready" : "MQM busy");
  625. /* Revert back to the state of having only received the 'CREATE',
  626. and immediately proceed to send the CREATE_ACK. */
  627. update_state (cc, CADET_CONNECTION_CREATE_RECEIVED, cc->mqm_ready);
  628. if (NULL != cc->task)
  629. GNUNET_SCHEDULER_cancel (cc->task);
  630. cc->task =
  631. GNUNET_SCHEDULER_add_at (cc->create_ack_at, &send_create_ack, cc);
  632. }
  633. else
  634. {
  635. /* We are currently sending something else back, which
  636. can only be an ACK or payload, either of which would
  637. do. So actually no need to do anything. */
  638. LOG (GNUNET_ERROR_TYPE_DEBUG,
  639. "Got duplicate CREATE for %s. MQ is busy, not queueing another ACK\n",
  640. GCC_2s (cc));
  641. }
  642. }
  643. /**
  644. * There has been a change in the message queue existence for our
  645. * peer at the first hop. Adjust accordingly.
  646. *
  647. * @param cls the `struct CadetConnection`
  648. * @param available #GNUNET_YES if sending is now possible,
  649. * #GNUNET_NO if sending is no longer possible
  650. * #GNUNET_SYSERR if sending is no longer possible
  651. * and the last envelope was discarded
  652. */
  653. static void
  654. manage_first_hop_mq (void *cls, int available)
  655. {
  656. struct CadetConnection *cc = cls;
  657. if (GNUNET_YES != available)
  658. {
  659. /* Connection is down, for now... */
  660. LOG (GNUNET_ERROR_TYPE_DEBUG, "Core MQ for %s went down\n", GCC_2s (cc));
  661. update_state (cc, CADET_CONNECTION_NEW, GNUNET_NO);
  662. cc->retry_delay = INITIAL_CONNECTION_CREATE_RETRY_DELAY;
  663. if (NULL != cc->task)
  664. {
  665. GNUNET_SCHEDULER_cancel (cc->task);
  666. cc->task = NULL;
  667. }
  668. return;
  669. }
  670. update_state (cc, cc->state, GNUNET_YES);
  671. LOG (GNUNET_ERROR_TYPE_DEBUG,
  672. "Core MQ for %s became available in state %d\n",
  673. GCC_2s (cc),
  674. cc->state);
  675. switch (cc->state)
  676. {
  677. case CADET_CONNECTION_NEW:
  678. /* Transmit immediately */
  679. cc->task = GNUNET_SCHEDULER_add_at (cc->create_at, &send_create, cc);
  680. break;
  681. case CADET_CONNECTION_SENDING_CREATE:
  682. /* Should not be possible to be called in this state. */
  683. GNUNET_assert (0);
  684. break;
  685. case CADET_CONNECTION_SENT:
  686. /* Retry a bit later... */
  687. cc->task = GNUNET_SCHEDULER_add_at (cc->create_at, &send_create, cc);
  688. break;
  689. case CADET_CONNECTION_CREATE_RECEIVED:
  690. /* We got the 'CREATE' (incoming connection), should send the CREATE_ACK */
  691. cc->metrics.age = GNUNET_TIME_absolute_get ();
  692. cc->task =
  693. GNUNET_SCHEDULER_add_at (cc->create_ack_at, &send_create_ack, cc);
  694. break;
  695. case CADET_CONNECTION_READY:
  696. if ((NULL == cc->keepalive_qe) && (GNUNET_YES == cc->mqm_ready) &&
  697. (NULL == cc->task))
  698. {
  699. LOG (GNUNET_ERROR_TYPE_DEBUG,
  700. "Scheduling keepalive for %s in %s\n",
  701. GCC_2s (cc),
  702. GNUNET_STRINGS_relative_time_to_string (keepalive_period,
  703. GNUNET_YES));
  704. cc->task =
  705. GNUNET_SCHEDULER_add_delayed (keepalive_period, &send_keepalive, cc);
  706. }
  707. break;
  708. }
  709. }
  710. /**
  711. * Create a connection to @a destination via @a path and notify @a cb
  712. * whenever we are ready for more data. Shared logic independent of
  713. * who is initiating the connection.
  714. *
  715. * @param destination where to go
  716. * @param path which path to take (may not be the full path)
  717. * @param off offset of @a destination on @a path
  718. * @param ct which tunnel uses this connection
  719. * @param init_state initial state for the connection
  720. * @param ready_cb function to call when ready to transmit
  721. * @param ready_cb_cls closure for @a cb
  722. * @return handle to the connection
  723. */
  724. static struct CadetConnection *
  725. connection_create (struct CadetPeer *destination,
  726. struct CadetPeerPath *path,
  727. unsigned int off,
  728. struct CadetTConnection *ct,
  729. const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
  730. enum CadetConnectionState init_state,
  731. GCC_ReadyCallback ready_cb,
  732. void *ready_cb_cls)
  733. {
  734. struct CadetConnection *cc;
  735. struct CadetPeer *first_hop;
  736. cc = GNUNET_new (struct CadetConnection);
  737. cc->state = init_state;
  738. cc->ct = ct;
  739. cc->destination = destination; /* xrs,t3ss,lurchi*/
  740. cc->cid = *cid;
  741. cc->retry_delay =
  742. GNUNET_TIME_relative_multiply (INITIAL_CONNECTION_CREATE_RETRY_DELAY, off);
  743. GNUNET_assert (GNUNET_OK ==
  744. GNUNET_CONTAINER_multishortmap_put (
  745. connections,
  746. &GCC_get_id (cc)->connection_of_tunnel,
  747. cc,
  748. GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
  749. cc->ready_cb = ready_cb;
  750. cc->ready_cb_cls = ready_cb_cls;
  751. cc->path = path;
  752. cc->off = off;
  753. LOG (GNUNET_ERROR_TYPE_DEBUG,
  754. "Creating %s using path %s (offset: %u)\n",
  755. GCC_2s (cc),
  756. GCPP_2s (path),
  757. off);
  758. GCPP_add_connection (path, off, cc);
  759. for (unsigned int i = 0; i < off; i++)
  760. GCP_add_connection (GCPP_get_peer_at_offset (path, i), cc);
  761. first_hop = GCPP_get_peer_at_offset (path, 0);
  762. cc->mq_man = GCP_request_mq (first_hop, &manage_first_hop_mq, cc);
  763. return cc;
  764. }
  765. /**
  766. * Create a connection to @a destination via @a path and
  767. * notify @a cb whenever we are ready for more data. This
  768. * is an inbound tunnel, so we must use the existing @a cid
  769. *
  770. * @param destination where to go
  771. * @param path which path to take (may not be the full path)
  772. * @param ct which tunnel uses this connection
  773. * @param ready_cb function to call when ready to transmit
  774. * @param ready_cb_cls closure for @a cb
  775. * @return handle to the connection, NULL if we already have
  776. * a connection that takes precedence on @a path
  777. */
  778. struct CadetConnection *
  779. GCC_create_inbound (struct CadetPeer *destination,
  780. struct CadetPeerPath *path,
  781. struct CadetTConnection *ct,
  782. const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
  783. GCC_ReadyCallback ready_cb,
  784. void *ready_cb_cls)
  785. {
  786. struct CadetConnection *cc;
  787. unsigned int off;
  788. off = GCPP_find_peer (path, destination);
  789. GNUNET_assert (UINT_MAX != off);
  790. cc = GCPP_get_connection (path, destination, off);
  791. if (NULL != cc)
  792. {
  793. int cmp;
  794. cmp = GNUNET_memcmp (cid, &cc->cid);
  795. if (0 == cmp)
  796. {
  797. /* Two peers picked the SAME random connection identifier at the
  798. same time for the same path? Must be malicious. Drop
  799. connection (existing and inbound), even if it is the only
  800. one. */
  801. GNUNET_break_op (0);
  802. GCT_connection_lost (cc->ct);
  803. GCC_destroy_without_tunnel (cc);
  804. return NULL;
  805. }
  806. if (0 < cmp)
  807. {
  808. /* drop existing */
  809. LOG (GNUNET_ERROR_TYPE_DEBUG,
  810. "Got two connections on %s, dropping my existing %s\n",
  811. GCPP_2s (path),
  812. GCC_2s (cc));
  813. GCT_connection_lost (cc->ct);
  814. GCC_destroy_without_tunnel (cc);
  815. }
  816. else
  817. {
  818. /* keep existing */
  819. LOG (GNUNET_ERROR_TYPE_DEBUG,
  820. "Got two connections on %s, keeping my existing %s\n",
  821. GCPP_2s (path),
  822. GCC_2s (cc));
  823. return NULL;
  824. }
  825. }
  826. return connection_create (destination,
  827. path,
  828. off,
  829. ct,
  830. cid,
  831. CADET_CONNECTION_CREATE_RECEIVED,
  832. ready_cb,
  833. ready_cb_cls);
  834. }
  835. /**
  836. * Create a connection to @a destination via @a path and
  837. * notify @a cb whenever we are ready for more data.
  838. *
  839. * @param destination where to go
  840. * @param path which path to take (may not be the full path)
  841. * @param off offset of @a destination on @a path
  842. * @param ct tunnel that uses the connection
  843. * @param ready_cb function to call when ready to transmit
  844. * @param ready_cb_cls closure for @a cb
  845. * @return handle to the connection
  846. */
  847. struct CadetConnection *
  848. GCC_create (struct CadetPeer *destination,
  849. struct CadetPeerPath *path,
  850. unsigned int off,
  851. struct CadetTConnection *ct,
  852. GCC_ReadyCallback ready_cb,
  853. void *ready_cb_cls)
  854. {
  855. struct GNUNET_CADET_ConnectionTunnelIdentifier cid;
  856. GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, &cid, sizeof(cid));
  857. return connection_create (destination,
  858. path,
  859. off,
  860. ct,
  861. &cid,
  862. CADET_CONNECTION_NEW,
  863. ready_cb,
  864. ready_cb_cls);
  865. }
  866. /**
  867. * Transmit message @a msg via connection @a cc. Must only be called
  868. * (once) after the connection has signalled that it is ready via the
  869. * `ready_cb`. Clients can also use #GCC_is_ready() to check if the
  870. * connection is right now ready for transmission.
  871. *
  872. * @param cc connection identification
  873. * @param env envelope with message to transmit; must NOT
  874. * yet have a #GNUNET_MQ_notify_sent() callback attached to it
  875. */
  876. void
  877. GCC_transmit (struct CadetConnection *cc, struct GNUNET_MQ_Envelope *env)
  878. {
  879. LOG (GNUNET_ERROR_TYPE_DEBUG,
  880. "Scheduling message for transmission on %s\n",
  881. GCC_2s (cc));
  882. GNUNET_assert (GNUNET_YES == cc->mqm_ready);
  883. GNUNET_assert (CADET_CONNECTION_READY == cc->state);
  884. cc->metrics.last_use = GNUNET_TIME_absolute_get ();
  885. cc->mqm_ready = GNUNET_NO;
  886. if (NULL != cc->task)
  887. {
  888. GNUNET_SCHEDULER_cancel (cc->task);
  889. cc->task = NULL;
  890. }
  891. GCP_send (cc->mq_man, env);
  892. }
  893. /**
  894. * Obtain the path used by this connection.
  895. *
  896. * @param cc connection
  897. * @param off[out] set to the length of the path we use
  898. * @return path to @a cc
  899. */
  900. struct CadetPeerPath *
  901. GCC_get_path (struct CadetConnection *cc, unsigned int *off)
  902. {
  903. *off = cc->off;
  904. return cc->path;
  905. }
  906. /**
  907. * Obtain unique ID for the connection.
  908. *
  909. * @param cc connection.
  910. * @return unique number of the connection
  911. */
  912. const struct GNUNET_CADET_ConnectionTunnelIdentifier *
  913. GCC_get_id (struct CadetConnection *cc)
  914. {
  915. return &cc->cid;
  916. }
  917. /**
  918. * Get a (static) string for a connection.
  919. *
  920. * @param cc Connection.
  921. */
  922. const char *
  923. GCC_2s (const struct CadetConnection *cc)
  924. {
  925. static char buf[128];
  926. if (NULL == cc)
  927. return "Connection(NULL)";
  928. if (NULL != cc->ct)
  929. {
  930. GNUNET_snprintf (buf,
  931. sizeof(buf),
  932. "Connection %s (%s)",
  933. GNUNET_sh2s (&cc->cid.connection_of_tunnel),
  934. GCT_2s (cc->ct->t));
  935. return buf;
  936. }
  937. GNUNET_snprintf (buf,
  938. sizeof(buf),
  939. "Connection %s",
  940. GNUNET_sh2s (&cc->cid.connection_of_tunnel));
  941. return buf;
  942. }
  943. #define LOG2(level, ...) \
  944. GNUNET_log_from_nocheck (level, "cadet-con", __VA_ARGS__)
  945. /**
  946. * Log connection info.
  947. *
  948. * @param cc connection
  949. * @param level Debug level to use.
  950. */
  951. void
  952. GCC_debug (struct CadetConnection *cc, enum GNUNET_ErrorType level)
  953. {
  954. #if ! defined(GNUNET_CULL_LOGGING)
  955. int do_log;
  956. do_log = GNUNET_get_log_call_status (level & (~GNUNET_ERROR_TYPE_BULK),
  957. "cadet-con",
  958. __FILE__,
  959. __FUNCTION__,
  960. __LINE__);
  961. if (0 == do_log)
  962. return;
  963. if (NULL == cc)
  964. {
  965. LOG2 (level, "Connection (NULL)\n");
  966. return;
  967. }
  968. LOG2 (level,
  969. "%s to %s via path %s in state %d is %s\n",
  970. GCC_2s (cc),
  971. GCP_2s (cc->destination),
  972. GCPP_2s (cc->path),
  973. cc->state,
  974. (GNUNET_YES == cc->mqm_ready) ? "ready" : "busy");
  975. #endif
  976. }
  977. /* end of gnunet-service-cadet_connection.c */