aboutsummaryrefslogtreecommitdiff
path: root/src/hostlist/gnunet-daemon-hostlist_server.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/hostlist/gnunet-daemon-hostlist_server.c')
-rw-r--r--src/hostlist/gnunet-daemon-hostlist_server.c142
1 files changed, 74 insertions, 68 deletions
diff --git a/src/hostlist/gnunet-daemon-hostlist_server.c b/src/hostlist/gnunet-daemon-hostlist_server.c
index 54db95009..c4a7aab03 100644
--- a/src/hostlist/gnunet-daemon-hostlist_server.c
+++ b/src/hostlist/gnunet-daemon-hostlist_server.c
@@ -42,6 +42,10 @@
42#define GNUNET_ADV_TIMEOUT \ 42#define GNUNET_ADV_TIMEOUT \
43 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5) 43 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
44 44
45/**
46 * Map with hellos we build the hostlist with.
47 */
48struct GNUNET_CONTAINER_MultiPeerMap *hellos;
45 49
46/** 50/**
47 * Handle to the HTTP server as provided by libmicrohttpd for IPv6. 51 * Handle to the HTTP server as provided by libmicrohttpd for IPv6.
@@ -69,6 +73,12 @@ static struct GNUNET_STATISTICS_Handle *stats;
69static struct GNUNET_CORE_Handle *core; 73static struct GNUNET_CORE_Handle *core;
70 74
71/** 75/**
76 * The task to delayed start the notification process intially.
77 * We like to give transport some time to give us our hello to distribute it.
78 */
79struct GNUNET_SCHEDULER_Task *peerstore_notify_task;
80
81/**
72 * Our peerstore notification context. We use notification 82 * Our peerstore notification context. We use notification
73 * to instantly learn about new peers as they are discovered. 83 * to instantly learn about new peers as they are discovered.
74 */ 84 */
@@ -111,11 +121,6 @@ static char *hostlist_uri;
111struct HostSet 121struct HostSet
112{ 122{
113 /** 123 /**
114 * Iterator used to build @e data (NULL when done).
115 */
116 struct GNUNET_PEERSTORE_IterateContext *pitr;
117
118 /**
119 * Place where we accumulate all of the HELLO messages. 124 * Place where we accumulate all of the HELLO messages.
120 */ 125 */
121 char *data; 126 char *data;
@@ -188,64 +193,27 @@ finish_response ()
188 * @param hello hello message for the peer (can be NULL) 193 * @param hello hello message for the peer (can be NULL)
189 * @param err_msg message 194 * @param err_msg message
190 */ 195 */
191static void 196static enum GNUNET_GenericReturnValue
192host_processor (void *cls, 197host_processor (void *cls,
193 const struct GNUNET_PEERSTORE_Record *record, 198 const struct GNUNET_PeerIdentity *peer,
194 const char *emsg) 199 void *value)
195{ 200{
201 (void *) cls;
196 size_t old; 202 size_t old;
197 size_t s; 203 size_t s;
198 struct GNUNET_MessageHeader *hello; 204 struct GNUNET_MessageHeader *hello = value;
199 struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); 205 struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
200 struct GNUNET_TIME_Absolute hello_exp; 206 struct GNUNET_TIME_Absolute hello_exp;
201 207
202 if (NULL != emsg) 208 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
203 { 209 "host_processor\n");
204 GNUNET_assert (NULL == &record->peer);
205 builder->pitr = NULL;
206 GNUNET_free (builder->data);
207 GNUNET_free (builder);
208 builder = NULL;
209 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
210 _ ("Error in communication with PEERSTORE service: %s\n"),
211 emsg);
212 return;
213 }
214 if (NULL == record)
215 {
216 builder->pitr = NULL;
217 finish_response ();
218 return;
219 }
220 else
221 {
222 hello = record->value;
223 if ((0 == record->value_size))
224 {
225 GNUNET_break (0);
226 return;
227 }
228 hello_exp = GNUNET_HELLO_builder_get_expiration_time (hello);
229 if (GNUNET_TIME_absolute_cmp (hello_exp, <, now))
230 {
231 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
232 "HELLO for peer `%4s' has expired address, not suitable for hostlist!\n",
233 GNUNET_i2s (&record->peer));
234 GNUNET_STATISTICS_update (stats,
235 gettext_noop (
236 "Expired HELLO encountered (ignored)"),
237 1,
238 GNUNET_NO);
239 return;
240 }
241 }
242 old = builder->size; 210 old = builder->size;
243 s = ntohs (hello->size); 211 s = ntohs (hello->size);
244 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 212 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
245 "Received %u bytes of `%s' from peer `%s' for hostlist.\n", 213 "Received %u bytes of `%s' from peer `%s' for hostlist.\n",
246 (unsigned int) s, 214 (unsigned int) s,
247 "HELLO", 215 "HELLO",
248 GNUNET_i2s (&record->peer)); 216 GNUNET_i2s (peer));
249 if ((old + s >= GNUNET_MAX_MALLOC_CHECKED) || 217 if ((old + s >= GNUNET_MAX_MALLOC_CHECKED) ||
250 (old + s >= MAX_BYTES_PER_HOSTLISTS)) 218 (old + s >= MAX_BYTES_PER_HOSTLISTS))
251 { 219 {
@@ -255,14 +223,16 @@ host_processor (void *cls,
255 "bytes not included in hostlist (size limit)"), 223 "bytes not included in hostlist (size limit)"),
256 s, 224 s,
257 GNUNET_NO); 225 GNUNET_NO);
258 return; 226 return GNUNET_YES;
259 } 227 }
260 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 228 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
261 "Adding peer `%s' to hostlist (%u bytes)\n", 229 "Adding peer `%s' to hostlist (%u bytes)\n",
262 GNUNET_i2s (&record->peer), 230 GNUNET_i2s (peer),
263 (unsigned int) s); 231 (unsigned int) s);
264 GNUNET_array_grow (builder->data, builder->size, old + s); 232 GNUNET_array_grow (builder->data, builder->size, old + s);
265 GNUNET_memcpy (&builder->data[old], hello, s); 233 GNUNET_memcpy (&builder->data[old], hello, s);
234
235 return GNUNET_YES;
266} 236}
267 237
268 238
@@ -500,20 +470,23 @@ process_notify (void *cls,
500 const struct GNUNET_MessageHeader *hello, 470 const struct GNUNET_MessageHeader *hello,
501 const char *err_msg) 471 const char *err_msg)
502{ 472{
473 unsigned int map_size;
474 struct GNUNET_MessageHeader *hello_cpy;
475 struct GNUNET_PeerIdentity *peer_cpy;
476
477 map_size = GNUNET_CONTAINER_multipeermap_size (hellos);
503 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 478 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
504 "Peerstore is notifying us to rebuild our hostlist\n"); 479 "Peerstore is notifying us to rebuild our hostlist map size %u\n",
480 map_size);
505 if (NULL != err_msg) 481 if (NULL != err_msg)
482 {
506 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 483 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
507 _ ("Error in communication with PEERSTORE service: %s\n"), 484 _ ("Error in communication with PEERSTORE service: %s\n"),
508 err_msg); 485 err_msg);
486 return;
487 }
509 if (NULL != builder) 488 if (NULL != builder)
510 { 489 {
511 /* restart re-build already in progress ... */
512 if (NULL != builder->pitr)
513 {
514 GNUNET_PEERSTORE_iterate_cancel (builder->pitr);
515 builder->pitr = NULL;
516 }
517 GNUNET_free (builder->data); 490 GNUNET_free (builder->data);
518 builder->size = 0; 491 builder->size = 0;
519 builder->data = NULL; 492 builder->data = NULL;
@@ -522,9 +495,27 @@ process_notify (void *cls,
522 { 495 {
523 builder = GNUNET_new (struct HostSet); 496 builder = GNUNET_new (struct HostSet);
524 } 497 }
525 GNUNET_assert (NULL != peerstore); 498
526 builder->pitr = 499 peer_cpy = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
527 GNUNET_PEERSTORE_iterate (peerstore, "hostlist", NULL, GNUNET_PEERSTORE_HELLO_KEY, &host_processor, NULL); 500 GNUNET_memcpy (peer_cpy, peer, sizeof (struct GNUNET_PeerIdentity));
501 hello_cpy = GNUNET_malloc (ntohs (hello->size));
502 GNUNET_memcpy (hello_cpy, hello, ntohs (hello->size));
503 GNUNET_assert (GNUNET_YES ==
504 GNUNET_CONTAINER_multipeermap_put (hellos,
505 peer_cpy,
506 (struct
507 GNUNET_MessageHeader *)
508 hello_cpy,
509 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
510 if (0 != GNUNET_CONTAINER_multipeermap_iterate (hellos,
511 &host_processor,
512 NULL))
513 finish_response ();
514 map_size = GNUNET_CONTAINER_multipeermap_size (hellos);
515 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
516 "1 Peerstore is notifying us to rebuild our hostlist map size %u peer %s\n",
517 map_size,
518 GNUNET_i2s (peer));
528} 519}
529 520
530 521
@@ -605,6 +596,19 @@ prepare_daemon (struct MHD_Daemon *daemon_handle)
605} 596}
606 597
607 598
599static void
600start_notify (void *cls)
601{
602 (void) cls;
603
604 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
605 "Starting to process new hellos to add to hostlist.\n");
606 peerstore_notify =
607 GNUNET_PEERSTORE_hello_changed_notify (peerstore, GNUNET_NO,
608 &process_notify, NULL);
609}
610
611
608/** 612/**
609 * Start server offering our hostlist. 613 * Start server offering our hostlist.
610 * 614 *
@@ -634,6 +638,7 @@ GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c,
634 const struct sockaddr *sa4; 638 const struct sockaddr *sa4;
635 const struct sockaddr *sa6; 639 const struct sockaddr *sa6;
636 640
641 hellos = GNUNET_CONTAINER_multipeermap_create (16, GNUNET_YES);
637 advertising = advertise; 642 advertising = advertise;
638 if (! advertising) 643 if (! advertising)
639 { 644 {
@@ -817,7 +822,9 @@ GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c,
817 hostlist_task_v4 = prepare_daemon (daemon_handle_v4); 822 hostlist_task_v4 = prepare_daemon (daemon_handle_v4);
818 if (NULL != daemon_handle_v6) 823 if (NULL != daemon_handle_v6)
819 hostlist_task_v6 = prepare_daemon (daemon_handle_v6); 824 hostlist_task_v6 = prepare_daemon (daemon_handle_v6);
820 peerstore_notify = GNUNET_PEERSTORE_hello_changed_notify (peerstore, GNUNET_NO, &process_notify, NULL); 825 peerstore_notify_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
826 start_notify,
827 NULL);
821 return GNUNET_OK; 828 return GNUNET_OK;
822} 829}
823 830
@@ -859,13 +866,12 @@ GNUNET_HOSTLIST_server_stop ()
859 GNUNET_PEERSTORE_hello_changed_notify_cancel (peerstore_notify); 866 GNUNET_PEERSTORE_hello_changed_notify_cancel (peerstore_notify);
860 peerstore_notify = NULL; 867 peerstore_notify = NULL;
861 } 868 }
869 else if (NULL != peerstore_notify_task)
870 {
871 GNUNET_SCHEDULER_cancel (peerstore_notify_task);
872 }
862 if (NULL != builder) 873 if (NULL != builder)
863 { 874 {
864 if (NULL != builder->pitr)
865 {
866 GNUNET_PEERSTORE_iterate_cancel (builder->pitr);
867 builder->pitr = NULL;
868 }
869 GNUNET_free (builder->data); 875 GNUNET_free (builder->data);
870 GNUNET_free (builder); 876 GNUNET_free (builder);
871 builder = NULL; 877 builder = NULL;