2
0

gnunet-service-fs.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2009-2014 Christian Grothoff (and other contributing authors)
  4. GNUnet is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published
  6. by the Free Software Foundation; either version 3, or (at your
  7. 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. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNUnet; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  15. Boston, MA 02111-1307, USA.
  16. */
  17. /**
  18. * @file fs/gnunet-service-fs.c
  19. * @brief gnunet anonymity protocol implementation
  20. * @author Christian Grothoff
  21. */
  22. #include "platform.h"
  23. #include <float.h>
  24. #include "gnunet_constants.h"
  25. #include "gnunet_core_service.h"
  26. #include "gnunet_dht_service.h"
  27. #include "gnunet_datastore_service.h"
  28. #include "gnunet_load_lib.h"
  29. #include "gnunet_peer_lib.h"
  30. #include "gnunet_protocols.h"
  31. #include "gnunet_signatures.h"
  32. #include "gnunet_statistics_service.h"
  33. #include "gnunet_transport_service.h"
  34. #include "gnunet_util_lib.h"
  35. #include "gnunet-service-fs_cp.h"
  36. #include "gnunet-service-fs_indexing.h"
  37. #include "gnunet-service-fs_lc.h"
  38. #include "gnunet-service-fs_pe.h"
  39. #include "gnunet-service-fs_pr.h"
  40. #include "gnunet-service-fs_push.h"
  41. #include "gnunet-service-fs_put.h"
  42. #include "gnunet-service-fs_cadet.h"
  43. #include "fs.h"
  44. #include "fs_api.h"
  45. /**
  46. * Size for the hash map for DHT requests from the FS
  47. * service. Should be about the number of concurrent
  48. * DHT requests we plan to make.
  49. */
  50. #define FS_DHT_HT_SIZE 1024
  51. /**
  52. * How quickly do we age cover traffic? At the given
  53. * time interval, remaining cover traffic counters are
  54. * decremented by 1/16th.
  55. */
  56. #define COVER_AGE_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
  57. /**
  58. * Collect an instane number of statistics? May cause excessive IPC.
  59. */
  60. #define INSANE_STATISTICS GNUNET_NO
  61. /* ****************************** globals ****************************** */
  62. /**
  63. * Our connection to the datastore.
  64. */
  65. struct GNUNET_DATASTORE_Handle *GSF_dsh;
  66. /**
  67. * Our configuration.
  68. */
  69. const struct GNUNET_CONFIGURATION_Handle *GSF_cfg;
  70. /**
  71. * Handle for reporting statistics.
  72. */
  73. struct GNUNET_STATISTICS_Handle *GSF_stats;
  74. /**
  75. * Handle for DHT operations.
  76. */
  77. struct GNUNET_DHT_Handle *GSF_dht;
  78. /**
  79. * How long do requests typically stay in the routing table?
  80. */
  81. struct GNUNET_LOAD_Value *GSF_rt_entry_lifetime;
  82. /**
  83. * Running average of the observed latency to other peers (round trip).
  84. * Initialized to 5s as the initial default.
  85. */
  86. struct GNUNET_TIME_Relative GSF_avg_latency = { 500 };
  87. /**
  88. * Handle to ATS service.
  89. */
  90. struct GNUNET_ATS_PerformanceHandle *GSF_ats;
  91. /**
  92. * Typical priorities we're seeing from other peers right now. Since
  93. * most priorities will be zero, this value is the weighted average of
  94. * non-zero priorities seen "recently". In order to ensure that new
  95. * values do not dramatically change the ratio, values are first
  96. * "capped" to a reasonable range (+N of the current value) and then
  97. * averaged into the existing value by a ratio of 1:N. Hence
  98. * receiving the largest possible priority can still only raise our
  99. * "current_priorities" by at most 1.
  100. */
  101. double GSF_current_priorities;
  102. /**
  103. * Size of the datastore queue we assume for common requests.
  104. */
  105. unsigned int GSF_datastore_queue_size;
  106. /**
  107. * How many query messages have we received 'recently' that
  108. * have not yet been claimed as cover traffic?
  109. */
  110. unsigned int GSF_cover_query_count;
  111. /**
  112. * How many content messages have we received 'recently' that
  113. * have not yet been claimed as cover traffic?
  114. */
  115. unsigned int GSF_cover_content_count;
  116. /**
  117. * Our block context.
  118. */
  119. struct GNUNET_BLOCK_Context *GSF_block_ctx;
  120. /**
  121. * Pointer to handle to the core service (points to NULL until we've
  122. * connected to it).
  123. */
  124. struct GNUNET_CORE_Handle *GSF_core;
  125. /**
  126. * Are we introducing randomized delays for better anonymity?
  127. */
  128. int GSF_enable_randomized_delays;
  129. /* ***************************** locals ******************************* */
  130. /**
  131. * Configuration for block library.
  132. */
  133. static struct GNUNET_CONFIGURATION_Handle *block_cfg;
  134. /**
  135. * Private key of this peer. Used to sign LOC URI requests.
  136. */
  137. static struct GNUNET_CRYPTO_EddsaPrivateKey *pk;
  138. /**
  139. * ID of our task that we use to age the cover counters.
  140. */
  141. static struct GNUNET_SCHEDULER_Task * cover_age_task;
  142. /**
  143. * Datastore 'GET' load tracking.
  144. */
  145. static struct GNUNET_LOAD_Value *datastore_get_load;
  146. /**
  147. * Identity of this peer.
  148. */
  149. static struct GNUNET_PeerIdentity my_id;
  150. /**
  151. * Task that periodically ages our cover traffic statistics.
  152. *
  153. * @param cls unused closure
  154. * @param tc task context
  155. */
  156. static void
  157. age_cover_counters (void *cls,
  158. const struct GNUNET_SCHEDULER_TaskContext *tc)
  159. {
  160. GSF_cover_content_count = (GSF_cover_content_count * 15) / 16;
  161. GSF_cover_query_count = (GSF_cover_query_count * 15) / 16;
  162. cover_age_task =
  163. GNUNET_SCHEDULER_add_delayed (COVER_AGE_FREQUENCY, &age_cover_counters,
  164. NULL);
  165. }
  166. /**
  167. * We've just now completed a datastore request. Update our
  168. * datastore load calculations.
  169. *
  170. * @param start time when the datastore request was issued
  171. */
  172. void
  173. GSF_update_datastore_delay_ (struct GNUNET_TIME_Absolute start)
  174. {
  175. struct GNUNET_TIME_Relative delay;
  176. delay = GNUNET_TIME_absolute_get_duration (start);
  177. GNUNET_LOAD_update (datastore_get_load, delay.rel_value_us);
  178. }
  179. /**
  180. * Test if the DATABASE (GET) load on this peer is too high
  181. * to even consider processing the query at
  182. * all.
  183. *
  184. * @param priority priority of the request (used as a reference point to compare with the load)
  185. * @return #GNUNET_YES if the load is too high to do anything (load high)
  186. * #GNUNET_NO to process normally (load normal)
  187. * #GNUNET_SYSERR to process for free (load low)
  188. */
  189. int
  190. GSF_test_get_load_too_high_ (uint32_t priority)
  191. {
  192. double ld;
  193. ld = GNUNET_LOAD_get_load (datastore_get_load);
  194. if (ld < 1)
  195. return GNUNET_SYSERR;
  196. if (ld <= priority)
  197. return GNUNET_NO;
  198. return GNUNET_YES;
  199. }
  200. /**
  201. * We've received peer performance information. Update
  202. * our running average for the P2P latency.
  203. *
  204. * @param cls closure
  205. * @param address the address
  206. * @param active is this address in active use
  207. * @param bandwidth_out assigned outbound bandwidth for the connection
  208. * @param bandwidth_in assigned inbound bandwidth for the connection
  209. * @param prop performance data for the address (as far as known)
  210. */
  211. static void
  212. update_latencies (void *cls,
  213. const struct GNUNET_HELLO_Address *address,
  214. int active,
  215. struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
  216. struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
  217. const struct GNUNET_ATS_Properties *prop)
  218. {
  219. if (NULL == address)
  220. {
  221. /* ATS service temporarily disconnected */
  222. return;
  223. }
  224. if (GNUNET_YES != active)
  225. return;
  226. GSF_update_peer_latency_ (&address->peer,
  227. prop->delay);
  228. GSF_avg_latency.rel_value_us =
  229. (GSF_avg_latency.rel_value_us * 31 +
  230. GNUNET_MIN (5000, prop->delay.rel_value_us)) / 32;
  231. GNUNET_STATISTICS_set (GSF_stats,
  232. gettext_noop ("# running average P2P latency (ms)"),
  233. GSF_avg_latency.rel_value_us / 1000LL,
  234. GNUNET_NO);
  235. }
  236. /**
  237. * Handle P2P "PUT" message.
  238. *
  239. * @param cls closure, always NULL
  240. * @param other the other peer involved (sender or receiver, NULL
  241. * for loopback messages where we are both sender and receiver)
  242. * @param message the actual message
  243. * @return #GNUNET_OK to keep the connection open,
  244. * #GNUNET_SYSERR to close it (signal serious error)
  245. */
  246. static int
  247. handle_p2p_put (void *cls,
  248. const struct GNUNET_PeerIdentity *other,
  249. const struct GNUNET_MessageHeader *message)
  250. {
  251. struct GSF_ConnectedPeer *cp;
  252. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  253. "Received P2P PUT from %s\n",
  254. GNUNET_i2s (other));
  255. cp = GSF_peer_get_ (other);
  256. if (NULL == cp)
  257. {
  258. GNUNET_break (0);
  259. return GNUNET_OK;
  260. }
  261. GSF_cover_content_count++;
  262. return GSF_handle_p2p_content_ (cp, message);
  263. }
  264. /**
  265. * We have a new request, consider forwarding it to the given
  266. * peer.
  267. *
  268. * @param cls the `struct GSF_PendingRequest`
  269. * @param peer identity of the peer
  270. * @param cp handle to the connected peer record
  271. * @param ppd peer performance data
  272. */
  273. static void
  274. consider_request_for_forwarding (void *cls,
  275. const struct GNUNET_PeerIdentity *peer,
  276. struct GSF_ConnectedPeer *cp,
  277. const struct GSF_PeerPerformanceData *ppd)
  278. {
  279. struct GSF_PendingRequest *pr = cls;
  280. if (GNUNET_YES != GSF_pending_request_test_target_ (pr, peer))
  281. {
  282. #if INSANE_STATISTICS
  283. GNUNET_STATISTICS_update (GSF_stats,
  284. gettext_noop ("# Loopback routes suppressed"), 1,
  285. GNUNET_NO);
  286. #endif
  287. return;
  288. }
  289. GSF_plan_add_ (cp, pr);
  290. }
  291. /**
  292. * Function to be called after we're done processing
  293. * replies from the local lookup. If the result status
  294. * code indicates that there may be more replies, plan
  295. * forwarding the request.
  296. *
  297. * @param cls closure (NULL)
  298. * @param pr the pending request we were processing
  299. * @param result final datastore lookup result
  300. */
  301. static void
  302. consider_forwarding (void *cls,
  303. struct GSF_PendingRequest *pr,
  304. enum GNUNET_BLOCK_EvaluationResult result)
  305. {
  306. if (GNUNET_BLOCK_EVALUATION_OK_LAST == result)
  307. return; /* we're done... */
  308. GSF_iterate_connected_peers_ (&consider_request_for_forwarding, pr);
  309. }
  310. /**
  311. * Handle P2P "GET" request.
  312. *
  313. * @param cls closure, always NULL
  314. * @param other the other peer involved (sender or receiver, NULL
  315. * for loopback messages where we are both sender and receiver)
  316. * @param message the actual message
  317. * @return #GNUNET_OK to keep the connection open,
  318. * #GNUNET_SYSERR to close it (signal serious error)
  319. */
  320. static int
  321. handle_p2p_get (void *cls,
  322. const struct GNUNET_PeerIdentity *other,
  323. const struct GNUNET_MessageHeader *message)
  324. {
  325. struct GSF_PendingRequest *pr;
  326. pr = GSF_handle_p2p_query_ (other, message);
  327. if (NULL == pr)
  328. return GNUNET_SYSERR;
  329. GSF_pending_request_get_data_ (pr)->has_started = GNUNET_YES;
  330. GSF_local_lookup_ (pr,
  331. &consider_forwarding, NULL);
  332. return GNUNET_OK;
  333. }
  334. /**
  335. * We're done with the local lookup, now consider
  336. * P2P processing (depending on request options and
  337. * result status). Also signal that we can now
  338. * receive more request information from the client.
  339. *
  340. * @param cls the client doing the request (`struct GNUNET_SERVER_Client`)
  341. * @param pr the pending request we were processing
  342. * @param result final datastore lookup result
  343. */
  344. static void
  345. start_p2p_processing (void *cls,
  346. struct GSF_PendingRequest *pr,
  347. enum GNUNET_BLOCK_EvaluationResult result)
  348. {
  349. struct GNUNET_SERVER_Client *client = cls;
  350. struct GSF_PendingRequestData *prd;
  351. GNUNET_SERVER_receive_done (client,
  352. GNUNET_OK);
  353. if (GNUNET_BLOCK_EVALUATION_OK_LAST == result)
  354. return; /* we're done, 'pr' was already destroyed... */
  355. prd = GSF_pending_request_get_data_ (pr);
  356. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  357. "Finished database lookup for local request `%s' with result %d\n",
  358. GNUNET_h2s (&prd->query), result);
  359. if (0 == prd->anonymity_level)
  360. {
  361. switch (prd->type)
  362. {
  363. case GNUNET_BLOCK_TYPE_FS_DBLOCK:
  364. case GNUNET_BLOCK_TYPE_FS_IBLOCK:
  365. /* the above block types MAY be available via 'cadet' */
  366. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  367. "Considering cadet-based download for block\n");
  368. GSF_cadet_lookup_ (pr);
  369. break;
  370. case GNUNET_BLOCK_TYPE_FS_UBLOCK:
  371. /* the above block types are in the DHT */
  372. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  373. "Considering DHT-based search for block\n");
  374. GSF_dht_lookup_ (pr);
  375. break;
  376. default:
  377. GNUNET_break (0);
  378. break;
  379. }
  380. }
  381. consider_forwarding (NULL, pr, result);
  382. }
  383. /**
  384. * Handle START_SEARCH-message (search request from client).
  385. *
  386. * @param cls closure
  387. * @param client identification of the client
  388. * @param message the actual message
  389. */
  390. static void
  391. handle_start_search (void *cls,
  392. struct GNUNET_SERVER_Client *client,
  393. const struct GNUNET_MessageHeader *message)
  394. {
  395. struct GSF_PendingRequest *pr;
  396. int ret;
  397. pr = NULL;
  398. ret = GSF_local_client_start_search_handler_ (client,
  399. message,
  400. &pr);
  401. switch (ret)
  402. {
  403. case GNUNET_SYSERR:
  404. GNUNET_SERVER_receive_done (client,
  405. GNUNET_SYSERR);
  406. break;
  407. case GNUNET_NO:
  408. GNUNET_SERVER_receive_done (client,
  409. GNUNET_OK);
  410. break;
  411. case GNUNET_YES:
  412. GSF_pending_request_get_data_ (pr)->has_started = GNUNET_YES;
  413. GSF_local_lookup_ (pr,
  414. &start_p2p_processing,
  415. client);
  416. break;
  417. default:
  418. GNUNET_assert (0);
  419. }
  420. }
  421. /**
  422. * Handle request to sign a LOC URI (from client).
  423. *
  424. * @param cls closure (NULL)
  425. * @param client identification of the client
  426. * @param message the actual message
  427. */
  428. static void
  429. handle_loc_sign (void *cls,
  430. struct GNUNET_SERVER_Client *client,
  431. const struct GNUNET_MessageHeader *message)
  432. {
  433. const struct RequestLocSignatureMessage *msg;
  434. struct GNUNET_FS_Uri base;
  435. struct GNUNET_FS_Uri *loc;
  436. struct ResponseLocSignatureMessage resp;
  437. struct GSF_LocalClient *lc;
  438. msg = (const struct RequestLocSignatureMessage *) message;
  439. GNUNET_break (GNUNET_SIGNATURE_PURPOSE_PEER_PLACEMENT ==
  440. ntohl (msg->purpose));
  441. base.type = GNUNET_FS_URI_CHK;
  442. base.data.chk.chk = msg->chk;
  443. base.data.chk.file_length = GNUNET_ntohll (msg->file_length);
  444. loc = GNUNET_FS_uri_loc_create (&base,
  445. pk,
  446. GNUNET_TIME_absolute_ntoh (msg->expiration_time));
  447. resp.header.size = htons (sizeof (struct ResponseLocSignatureMessage));
  448. resp.header.type = htons (GNUNET_MESSAGE_TYPE_FS_REQUEST_LOC_SIGNATURE);
  449. resp.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_PEER_PLACEMENT);
  450. resp.expiration_time = GNUNET_TIME_absolute_hton (loc->data.loc.expirationTime);
  451. resp.signature = loc->data.loc.contentSignature;
  452. resp.peer = loc->data.loc.peer;
  453. GNUNET_FS_uri_destroy (loc);
  454. lc = GSF_local_client_lookup_ (client);
  455. GSF_local_client_transmit_ (lc,
  456. &resp.header);
  457. GNUNET_SERVER_receive_done (client, GNUNET_OK);
  458. }
  459. /**
  460. * Task run during shutdown.
  461. *
  462. * @param cls unused
  463. * @param tc unused
  464. */
  465. static void
  466. shutdown_task (void *cls,
  467. const struct GNUNET_SCHEDULER_TaskContext *tc)
  468. {
  469. GSF_cadet_stop_client ();
  470. GSF_cadet_stop_server ();
  471. if (NULL != GSF_core)
  472. {
  473. GNUNET_CORE_disconnect (GSF_core);
  474. GSF_core = NULL;
  475. }
  476. if (NULL != GSF_ats)
  477. {
  478. GNUNET_ATS_performance_done (GSF_ats);
  479. GSF_ats = NULL;
  480. }
  481. GSF_put_done_ ();
  482. GSF_push_done_ ();
  483. GSF_pending_request_done_ ();
  484. GSF_plan_done ();
  485. GSF_connected_peer_done_ ();
  486. GNUNET_DATASTORE_disconnect (GSF_dsh, GNUNET_NO);
  487. GSF_dsh = NULL;
  488. GNUNET_DHT_disconnect (GSF_dht);
  489. GSF_dht = NULL;
  490. GNUNET_BLOCK_context_destroy (GSF_block_ctx);
  491. GSF_block_ctx = NULL;
  492. GNUNET_CONFIGURATION_destroy (block_cfg);
  493. block_cfg = NULL;
  494. GNUNET_STATISTICS_destroy (GSF_stats, GNUNET_NO);
  495. GSF_stats = NULL;
  496. if (NULL != cover_age_task)
  497. {
  498. GNUNET_SCHEDULER_cancel (cover_age_task);
  499. cover_age_task = NULL;
  500. }
  501. GNUNET_FS_indexing_done ();
  502. GNUNET_LOAD_value_free (datastore_get_load);
  503. datastore_get_load = NULL;
  504. GNUNET_LOAD_value_free (GSF_rt_entry_lifetime);
  505. GSF_rt_entry_lifetime = NULL;
  506. }
  507. /**
  508. * Function called for each pending request whenever a new
  509. * peer connects, giving us a chance to decide about submitting
  510. * the existing request to the new peer.
  511. *
  512. * @param cls the 'struct GSF_ConnectedPeer' of the new peer
  513. * @param key query for the request
  514. * @param pr handle to the pending request
  515. * @return #GNUNET_YES to continue to iterate
  516. */
  517. static int
  518. consider_peer_for_forwarding (void *cls,
  519. const struct GNUNET_HashCode *key,
  520. struct GSF_PendingRequest *pr)
  521. {
  522. struct GSF_ConnectedPeer *cp = cls;
  523. struct GNUNET_PeerIdentity pid;
  524. GSF_connected_peer_get_identity_ (cp, &pid);
  525. if (GNUNET_YES != GSF_pending_request_test_target_ (pr, &pid))
  526. {
  527. GNUNET_STATISTICS_update (GSF_stats,
  528. gettext_noop ("# Loopback routes suppressed"), 1,
  529. GNUNET_NO);
  530. return GNUNET_YES;
  531. }
  532. GSF_plan_add_ (cp, pr);
  533. return GNUNET_YES;
  534. }
  535. /**
  536. * Function called after the creation of a connected peer record is complete.
  537. *
  538. * @param cls closure (unused)
  539. * @param cp handle to the newly created connected peer record
  540. */
  541. static void
  542. connected_peer_cb (void *cls, struct GSF_ConnectedPeer *cp)
  543. {
  544. if (NULL == cp)
  545. return;
  546. GSF_iterate_pending_requests_ (&consider_peer_for_forwarding, cp);
  547. }
  548. /**
  549. * Method called whenever a given peer connects.
  550. *
  551. * @param cls closure, not used
  552. * @param peer peer identity this notification is about
  553. */
  554. static void
  555. peer_connect_handler (void *cls,
  556. const struct GNUNET_PeerIdentity *peer)
  557. {
  558. if (0 ==
  559. GNUNET_CRYPTO_cmp_peer_identity (&my_id,
  560. peer))
  561. return;
  562. GSF_peer_connect_handler_ (peer,
  563. &connected_peer_cb,
  564. NULL);
  565. }
  566. /**
  567. * Function called after GNUNET_CORE_connect has succeeded
  568. * (or failed for good). Note that the private key of the
  569. * peer is intentionally not exposed here; if you need it,
  570. * your process should try to read the private key file
  571. * directly (which should work if you are authorized...).
  572. *
  573. * @param cls closure
  574. * @param my_identity ID of this peer, NULL if we failed
  575. */
  576. static void
  577. peer_init_handler (void *cls,
  578. const struct GNUNET_PeerIdentity *my_identity)
  579. {
  580. if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_id,
  581. my_identity))
  582. {
  583. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  584. "Peer identity missmatch, refusing to start!\n");
  585. GNUNET_SCHEDULER_shutdown ();
  586. }
  587. }
  588. /**
  589. * Process fs requests.
  590. *
  591. * @param server the initialized server
  592. * @param c configuration to use
  593. */
  594. static int
  595. main_init (struct GNUNET_SERVER_Handle *server,
  596. const struct GNUNET_CONFIGURATION_Handle *c)
  597. {
  598. static const struct GNUNET_CORE_MessageHandler no_p2p_handlers[] = {
  599. { NULL, 0, 0 }
  600. };
  601. static const struct GNUNET_CORE_MessageHandler p2p_handlers[] = {
  602. { &handle_p2p_get,
  603. GNUNET_MESSAGE_TYPE_FS_GET, 0 },
  604. { &handle_p2p_put,
  605. GNUNET_MESSAGE_TYPE_FS_PUT, 0 },
  606. { &GSF_handle_p2p_migration_stop_,
  607. GNUNET_MESSAGE_TYPE_FS_MIGRATION_STOP,
  608. sizeof (struct MigrationStopMessage) },
  609. { NULL, 0, 0 }
  610. };
  611. static const struct GNUNET_SERVER_MessageHandler handlers[] = {
  612. { &GNUNET_FS_handle_index_start, NULL,
  613. GNUNET_MESSAGE_TYPE_FS_INDEX_START, 0 },
  614. { &GNUNET_FS_handle_index_list_get, NULL,
  615. GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_GET,
  616. sizeof (struct GNUNET_MessageHeader) },
  617. { &GNUNET_FS_handle_unindex, NULL,
  618. GNUNET_MESSAGE_TYPE_FS_UNINDEX,
  619. sizeof (struct UnindexMessage) },
  620. { &handle_start_search, NULL,
  621. GNUNET_MESSAGE_TYPE_FS_START_SEARCH, 0 },
  622. { &handle_loc_sign, NULL,
  623. GNUNET_MESSAGE_TYPE_FS_REQUEST_LOC_SIGN,
  624. sizeof (struct RequestLocSignatureMessage) },
  625. {NULL, NULL, 0, 0}
  626. };
  627. int anon_p2p_off;
  628. char *keyfile;
  629. /* this option is really only for testcases that need to disable
  630. _anonymous_ file-sharing for some reason */
  631. anon_p2p_off = (GNUNET_YES ==
  632. GNUNET_CONFIGURATION_get_value_yesno (GSF_cfg,
  633. "fs",
  634. "DISABLE_ANON_TRANSFER"));
  635. if (GNUNET_OK !=
  636. GNUNET_CONFIGURATION_get_value_filename (GSF_cfg,
  637. "PEER",
  638. "PRIVATE_KEY",
  639. &keyfile))
  640. {
  641. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  642. _("FS service is lacking HOSTKEY configuration setting. Exiting.\n"));
  643. GNUNET_SCHEDULER_shutdown ();
  644. return GNUNET_SYSERR;
  645. }
  646. pk = GNUNET_CRYPTO_eddsa_key_create_from_file (keyfile);
  647. GNUNET_free (keyfile);
  648. GNUNET_assert (NULL != pk);
  649. GNUNET_CRYPTO_eddsa_key_get_public (pk,
  650. &my_id.public_key);
  651. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  652. "I am peer %s\n",
  653. GNUNET_i2s (&my_id));
  654. GSF_core
  655. = GNUNET_CORE_connect (GSF_cfg, NULL,
  656. &peer_init_handler,
  657. &peer_connect_handler,
  658. &GSF_peer_disconnect_handler_,
  659. NULL, GNUNET_NO,
  660. NULL, GNUNET_NO,
  661. (GNUNET_YES == anon_p2p_off)
  662. ? no_p2p_handlers
  663. : p2p_handlers);
  664. if (NULL == GSF_core)
  665. {
  666. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  667. _("Failed to connect to `%s' service.\n"), "core");
  668. return GNUNET_SYSERR;
  669. }
  670. GNUNET_SERVER_disconnect_notify (server, &GSF_client_disconnect_handler_,
  671. NULL);
  672. GNUNET_SERVER_add_handlers (server, handlers);
  673. cover_age_task =
  674. GNUNET_SCHEDULER_add_delayed (COVER_AGE_FREQUENCY, &age_cover_counters,
  675. NULL);
  676. datastore_get_load = GNUNET_LOAD_value_init (DATASTORE_LOAD_AUTODECLINE);
  677. GSF_cadet_start_server ();
  678. GSF_cadet_start_client ();
  679. GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
  680. NULL);
  681. return GNUNET_OK;
  682. }
  683. /**
  684. * Process fs requests.
  685. *
  686. * @param cls closure
  687. * @param server the initialized server
  688. * @param cfg configuration to use
  689. */
  690. static void
  691. run (void *cls, struct GNUNET_SERVER_Handle *server,
  692. const struct GNUNET_CONFIGURATION_Handle *cfg)
  693. {
  694. unsigned long long dqs;
  695. GSF_cfg = cfg;
  696. if (GNUNET_OK !=
  697. GNUNET_CONFIGURATION_get_value_size (GSF_cfg, "fs", "DATASTORE_QUEUE_SIZE",
  698. &dqs))
  699. {
  700. GNUNET_log_config_missing (GNUNET_ERROR_TYPE_INFO,
  701. "fs", "DATASTORE_QUEUE_SIZE");
  702. dqs = 1024;
  703. }
  704. GSF_datastore_queue_size = (unsigned int) dqs;
  705. GSF_enable_randomized_delays =
  706. GNUNET_CONFIGURATION_get_value_yesno (cfg, "fs", "DELAY");
  707. GSF_dsh = GNUNET_DATASTORE_connect (cfg);
  708. if (NULL == GSF_dsh)
  709. {
  710. GNUNET_SCHEDULER_shutdown ();
  711. return;
  712. }
  713. GSF_rt_entry_lifetime = GNUNET_LOAD_value_init (GNUNET_TIME_UNIT_FOREVER_REL);
  714. GSF_stats = GNUNET_STATISTICS_create ("fs", cfg);
  715. block_cfg = GNUNET_CONFIGURATION_create ();
  716. GSF_block_ctx = GNUNET_BLOCK_context_create (block_cfg);
  717. GNUNET_assert (NULL != GSF_block_ctx);
  718. GSF_dht = GNUNET_DHT_connect (cfg, FS_DHT_HT_SIZE);
  719. GSF_plan_init ();
  720. GSF_pending_request_init_ ();
  721. GSF_connected_peer_init_ ();
  722. GSF_ats = GNUNET_ATS_performance_init (GSF_cfg, &update_latencies, NULL);
  723. GSF_push_init_ ();
  724. GSF_put_init_ ();
  725. if ((GNUNET_OK != GNUNET_FS_indexing_init (cfg, GSF_dsh)) ||
  726. (GNUNET_OK != main_init (server, cfg)))
  727. {
  728. GNUNET_SCHEDULER_shutdown ();
  729. shutdown_task (NULL, NULL);
  730. return;
  731. }
  732. }
  733. /**
  734. * The main function for the fs service.
  735. *
  736. * @param argc number of arguments from the command line
  737. * @param argv command line arguments
  738. * @return 0 ok, 1 on error
  739. */
  740. int
  741. main (int argc, char *const *argv)
  742. {
  743. return (GNUNET_OK ==
  744. GNUNET_SERVICE_run (argc, argv, "fs", GNUNET_SERVICE_OPTION_NONE,
  745. &run, NULL)) ? 0 : 1;
  746. }
  747. /* end of gnunet-service-fs.c */