aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2009-06-13 05:44:21 +0000
committerChristian Grothoff <christian@grothoff.org>2009-06-13 05:44:21 +0000
commita2355334e0a5116144f2588ddf1e37f596c520bd (patch)
treeade2f6d60a9aadc53e5731d7cca68c7f67901940 /src
parent73cd82b1494c8390c41e7b5afda96b250fd448fa (diff)
downloadgnunet-a2355334e0a5116144f2588ddf1e37f596c520bd.tar.gz
gnunet-a2355334e0a5116144f2588ddf1e37f596c520bd.zip
client part
Diffstat (limited to 'src')
-rw-r--r--src/hostlist/Makefile.am7
-rw-r--r--src/hostlist/gnunet-daemon-hostlist.c63
-rw-r--r--src/hostlist/hostlist-client.c662
-rw-r--r--src/hostlist/hostlist-client.h58
4 files changed, 783 insertions, 7 deletions
diff --git a/src/hostlist/Makefile.am b/src/hostlist/Makefile.am
index 565cb2e9a..efa4d6962 100644
--- a/src/hostlist/Makefile.am
+++ b/src/hostlist/Makefile.am
@@ -9,14 +9,15 @@ bin_PROGRAMS = \
9 gnunet-daemon-hostlist 9 gnunet-daemon-hostlist
10 10
11gnunet_daemon_hostlist_SOURCES = \ 11gnunet_daemon_hostlist_SOURCES = \
12 gnunet-daemon-hostlist.c 12 gnunet-daemon-hostlist.c \
13# 13 hostlist-client.c hostlist-client.h
14# hostlist-server.c hostlist-server.h 14# hostlist-server.c hostlist-server.h
15# hostlist-client.c hostlist-client.h 15
16gnunet_daemon_hostlist_LDADD = \ 16gnunet_daemon_hostlist_LDADD = \
17 $(top_builddir)/src/core/libgnunetcore.la \ 17 $(top_builddir)/src/core/libgnunetcore.la \
18 $(top_builddir)/src/hello/libgnunethello.la \ 18 $(top_builddir)/src/hello/libgnunethello.la \
19 $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ 19 $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \
20 $(top_builddir)/src/statistics/libgnunetstatistics.la \
20 $(top_builddir)/src/transport/libgnunettransport.la \ 21 $(top_builddir)/src/transport/libgnunettransport.la \
21 $(top_builddir)/src/util/libgnunetutil.la \ 22 $(top_builddir)/src/util/libgnunetutil.la \
22 -lmicrohttpd \ 23 -lmicrohttpd \
diff --git a/src/hostlist/gnunet-daemon-hostlist.c b/src/hostlist/gnunet-daemon-hostlist.c
index 0fb77ecbd..f11bcd87d 100644
--- a/src/hostlist/gnunet-daemon-hostlist.c
+++ b/src/hostlist/gnunet-daemon-hostlist.c
@@ -26,12 +26,15 @@
26 26
27#include <stdlib.h> 27#include <stdlib.h>
28#include "platform.h" 28#include "platform.h"
29#include "hostlist-client.h"
30#include "gnunet_core_service.h"
29#include "gnunet_getopt_lib.h" 31#include "gnunet_getopt_lib.h"
30#include "gnunet_protocols.h" 32#include "gnunet_protocols.h"
31#include "gnunet_program_lib.h" 33#include "gnunet_program_lib.h"
32#include "gnunet_statistics_service.h" 34#include "gnunet_statistics_service.h"
33#include "gnunet_strings_lib.h" 35#include "gnunet_strings_lib.h"
34#include "gnunet_time_lib.h" 36#include "gnunet_time_lib.h"
37#include "gnunet_util_lib.h"
35 38
36 39
37/** 40/**
@@ -51,6 +54,10 @@ static int learning;
51 */ 54 */
52static int provide_hostlist; 55static int provide_hostlist;
53 56
57/**
58 * Statistics handle.
59 */
60static struct GNUNET_STATISTICS_Handle *stats;
54 61
55/** 62/**
56 * gnunet-daemon-hostlist command line options. 63 * gnunet-daemon-hostlist command line options.
@@ -66,6 +73,33 @@ static struct GNUNET_GETOPT_CommandLineOption options[] = {
66}; 73};
67 74
68 75
76static void
77core_init (void *cls,
78 struct GNUNET_CORE_Handle * server,
79 const struct GNUNET_PeerIdentity *
80 my_identity,
81 const struct
82 GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *
83 publicKey)
84{
85 /* TODO: provide "server" to 'hostlist' module (if applicable) */
86}
87
88
89/**
90 * Last task run during shutdown. Disconnects us from
91 * the other services.
92 */
93static void
94cleaning_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
95{
96 if (stats != NULL)
97 {
98 GNUNET_STATISTICS_destroy (stats);
99 stats = NULL;
100 }
101}
102
69 103
70/** 104/**
71 * Main function that will be run. 105 * Main function that will be run.
@@ -83,6 +117,13 @@ run (void *cls,
83 const char *cfgfile, 117 const char *cfgfile,
84 struct GNUNET_CONFIGURATION_Handle * cfg) 118 struct GNUNET_CONFIGURATION_Handle * cfg)
85{ 119{
120 GNUNET_CORE_ClientEventHandler ch = NULL;
121 GNUNET_CORE_ClientEventHandler dh = NULL;
122 struct GNUNET_CORE_MessageHandler handlers[] =
123 {
124 { NULL, 0, 0 }
125 };
126
86 if ( (! bootstrapping) && 127 if ( (! bootstrapping) &&
87 (! learning) && 128 (! learning) &&
88 (! provide_hostlist) ) 129 (! provide_hostlist) )
@@ -91,6 +132,7 @@ run (void *cls,
91 _("None of the functions for the hostlist daemon were enabled. I have no reason to run!\n")); 132 _("None of the functions for the hostlist daemon were enabled. I have no reason to run!\n"));
92 return; 133 return;
93 } 134 }
135 stats = GNUNET_STATISTICS_create (sched, "hostlist", cfg);
94 if (learning) 136 if (learning)
95 { 137 {
96 // FIXME! 138 // FIXME!
@@ -98,10 +140,8 @@ run (void *cls,
98 } 140 }
99 if (bootstrapping) 141 if (bootstrapping)
100 { 142 {
101 // FIXME! 143 GNUNET_HOSTLIST_client_start (cfg, sched, stats,
102 // (register handler with core to monitor number of active 144 &ch, &dh);
103 // connections; trigger hostlist download via CURL if
104 // number is low)
105 } 145 }
106 if (provide_hostlist) 146 if (provide_hostlist)
107 { 147 {
@@ -109,6 +149,21 @@ run (void *cls,
109 // (initialize MHD server and run using scheduler; 149 // (initialize MHD server and run using scheduler;
110 // use peerinfo to gather HELLOs) 150 // use peerinfo to gather HELLOs)
111 } 151 }
152 GNUNET_CORE_connect (sched, cfg,
153 GNUNET_TIME_UNIT_FOREVER_REL,
154 NULL,
155 &core_init,
156 ch, dh,
157 NULL,
158 NULL, GNUNET_NO,
159 NULL, GNUNET_NO,
160 handlers);
161 GNUNET_SCHEDULER_add_delayed (sched,
162 GNUNET_YES,
163 GNUNET_SCHEDULER_PRIORITY_IDLE,
164 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
165 GNUNET_TIME_UNIT_FOREVER_REL,
166 &cleaning_task, NULL);
112} 167}
113 168
114 169
diff --git a/src/hostlist/hostlist-client.c b/src/hostlist/hostlist-client.c
new file mode 100644
index 000000000..5008b41fc
--- /dev/null
+++ b/src/hostlist/hostlist-client.c
@@ -0,0 +1,662 @@
1/*
2 This file is part of GNUnet.
3 (C) 2001, 2002, 2003, 2004, 2005, 2006, 2009 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file hostlist/hostlist-client.c
23 * @brief hostlist support. Downloads HELLOs via HTTP.
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "hostlist-client.h"
29#include "gnunet_core_service.h"
30#include "gnunet_hello_lib.h"
31#include "gnunet_transport_service.h"
32#include <curl/curl.h>
33
34/**
35 * Number of connections that we must have to NOT download
36 * hostlists anymore.
37 */
38#define MIN_CONNECTIONS 4
39
40/**
41 * Our configuration.
42 */
43static struct GNUNET_CONFIGURATION_Handle *cfg;
44
45/**
46 * Our scheduler.
47 */
48static struct GNUNET_SCHEDULER_Handle *sched;
49
50/**
51 * Statistics handle.
52 */
53struct GNUNET_STATISTICS_Handle *stats;
54
55/**
56 * Transport handle.
57 */
58struct GNUNET_TRANSPORT_Handle *transport;
59
60/**
61 * Proxy that we are using (can be NULL).
62 */
63static char *proxy;
64
65/**
66 * Buffer for data downloaded via HTTP.
67 */
68static char download_buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE];
69
70/**
71 * Number of bytes valid in 'download_buffer'.
72 */
73static size_t download_pos;
74
75/**
76 * Current URL that we are using.
77 */
78static char *current_url;
79
80/**
81 * Current CURL handle.
82 */
83static CURL *curl;
84
85/**
86 * Current multi-CURL handle.
87 */
88static CURLM *multi;
89
90/**
91 * ID of the current task scheduled.
92 */
93static GNUNET_SCHEDULER_TaskIdentifier current_task;
94
95/**
96 * Amount of time we wait between hostlist downloads.
97 */
98static struct GNUNET_TIME_Relative hostlist_delay;
99
100/**
101 * Set to GNUNET_YES if the current URL had some problems.
102 */
103static int bogus_url;
104
105/**
106 * Number of active connections (according to core service).
107 */
108static unsigned int connection_count;
109
110
111/**
112 * Process downloaded bits by calling callback on each HELLO.
113 *
114 * @param ptr buffer with downloaded data
115 * @param size size of a record
116 * @param nmemb number of records downloaded
117 * @param ctx unused
118 * @return number of bytes that were processed (always size*nmemb)
119 */
120static size_t
121download_hostlist_processor (void *ptr,
122 size_t size,
123 size_t nmemb,
124 void *ctx)
125{
126 const char * cbuf = ptr;
127 const struct GNUNET_MessageHeader *msg;
128 size_t total;
129 size_t cpy;
130 size_t left;
131 uint16_t msize;
132
133 total = size * nmemb;
134 if ( (total == 0) || (bogus_url) )
135 return total; /* ok, no data or bogus data */
136 left = total;
137 while (left > 0)
138 {
139 cpy = GNUNET_MIN (total, GNUNET_SERVER_MAX_MESSAGE_SIZE - download_pos);
140 GNUNET_assert (cpy > 0);
141 memcpy (&download_buffer[download_pos],
142 cbuf,
143 cpy);
144 cbuf += cpy;
145 download_pos += cpy;
146 left -= cpy;
147 if (download_pos < sizeof(struct GNUNET_MessageHeader))
148 break;
149 msg = (const struct GNUNET_MessageHeader *) download_buffer;
150 msize = ntohs(msg->size);
151 if (msize < sizeof(struct GNUNET_MessageHeader))
152 {
153 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
154 _("Invalid `%s' message received from hostlist at `%s'\n"),
155 "HELLO",
156 current_url);
157 bogus_url = 1;
158 return total;
159 }
160 if (download_pos < msize)
161 break;
162 if (GNUNET_HELLO_size ((const struct GNUNET_HELLO_Message*)msg) == msize)
163 {
164 GNUNET_TRANSPORT_offer_hello (transport, msg);
165 }
166 else
167 {
168 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
169 _("Invalid `%s' message received from hostlist at `%s'\n"),
170 "HELLO",
171 current_url);
172 bogus_url = 1;
173 return total;
174 }
175 memmove (download_buffer,
176 &download_buffer[msize],
177 download_pos - msize);
178 download_pos -= msize;
179 }
180 return total;
181}
182
183
184/**
185 * Obtain a hostlist URL that we should use.
186 *
187 * @return NULL if there is no URL available
188 */
189static char *
190get_url ()
191{
192 char *servers;
193 char *ret;
194 size_t urls;
195 size_t pos;
196
197 if (GNUNET_OK !=
198 GNUNET_CONFIGURATION_get_value_string (cfg,
199 "HOSTLIST",
200 "SERVERS",
201 &servers))
202 {
203 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
204 _("No `%s' specified in `%s' configuration, will not bootstrap.\n"),
205 "SERVERS", "HOSTLIST");
206 return NULL;
207 }
208
209 urls = 0;
210 if (strlen (servers) > 0)
211 {
212 urls++;
213 pos = strlen (servers) - 1;
214 while (pos > 0)
215 {
216 if (servers[pos] == ' ')
217 urls++;
218 pos--;
219 }
220 }
221 if (urls == 0)
222 {
223 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
224 _("No `%s' specified in `%s' configuration, will not bootstrap.\n"),
225 "SERVERS", "HOSTLIST");
226 GNUNET_free (servers);
227 return NULL;
228 }
229
230 urls = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, urls) + 1;
231 pos = strlen (servers) - 1;
232 while (pos > 0)
233 {
234 if (servers[pos] == ' ')
235 {
236 urls--;
237 servers[pos] = '\0';
238 }
239 if (urls == 0)
240 {
241 pos++;
242 break;
243 }
244 pos--;
245 }
246 ret = GNUNET_strdup (&servers[pos]);
247 GNUNET_free (servers);
248 return ret;
249}
250
251
252#define CURL_EASY_SETOPT(c, a, b) do { ret = curl_easy_setopt(c, a, b); if (ret != CURLE_OK) GNUNET_log(GNUNET_ERROR_TYPE_WARNING, _("%s failed at %s:%d: `%s'\n"), "curl_easy_setopt", __FILE__, __LINE__, curl_easy_strerror(ret)); } while (0);
253
254
255/**
256 * Schedule the background task that will (possibly)
257 * download a hostlist.
258 */
259static void
260schedule_hostlist_task (void);
261
262
263/**
264 * Clean up the state from the task that downloaded the
265 * hostlist and schedule the next task.
266 */
267static void
268clean_up ()
269{
270 CURLMcode mret;
271
272 if (multi != NULL)
273 {
274 mret = curl_multi_remove_handle (multi, curl);
275 if (mret != CURLM_OK)
276 {
277 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
278 _("%s failed at %s:%d: `%s'\n"),
279 "curl_multi_remove_handle", __FILE__, __LINE__,
280 curl_multi_strerror (mret));
281 }
282 mret = curl_multi_cleanup (multi);
283 if (mret != CURLM_OK)
284 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
285 _("%s failed at %s:%d: `%s'\n"),
286 "curl_multi_cleanup", __FILE__, __LINE__,
287 curl_multi_strerror (mret));
288 multi = NULL;
289 }
290 if (curl != NULL)
291 {
292 curl_easy_cleanup (curl);
293 curl = NULL;
294 }
295 if (transport != NULL)
296 {
297 GNUNET_TRANSPORT_disconnect (transport);
298 transport = NULL;
299 }
300 GNUNET_free_non_null (current_url);
301 current_url = NULL;
302 schedule_hostlist_task ();
303}
304
305
306/**
307 * Task that is run when we are ready to receive more data from the hostlist
308 * server.
309 *
310 * @param tc
311 */
312static void
313multi_ready (void *cls,
314 const struct GNUNET_SCHEDULER_TaskContext *tc)
315{
316 int running;
317 struct CURLMsg *msg;
318 CURLMcode mret;
319
320 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT))
321 {
322 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
323 _("Timeout trying to download hostlist from `%s'\n"),
324 current_url);
325 clean_up ();
326 return;
327 }
328 do
329 {
330 running = 0;
331 mret = curl_multi_perform (multi, &running);
332 if (running == 0)
333 {
334 do
335 {
336 msg = curl_multi_info_read (multi, &running);
337 GNUNET_break (msg != NULL);
338 if (msg == NULL)
339 break;
340 switch (msg->msg)
341 {
342 case CURLMSG_DONE:
343 if (msg->data.result != CURLE_OK)
344 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
345 _("%s failed at %s:%d: `%s'\n"),
346 "curl_multi_perform", __FILE__,
347 __LINE__,
348 curl_easy_strerror (msg->data.result));
349 break;
350 default:
351 break;
352 }
353 }
354 while (running > 0);
355 }
356 }
357 while (mret == CURLM_CALL_MULTI_PERFORM);
358 if (mret != CURLM_OK)
359 {
360 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
361 _("%s failed at %s:%d: `%s'\n"),
362 "curl_multi_perform", __FILE__, __LINE__,
363 curl_multi_strerror (mret));
364 clean_up ();
365 return;
366 }
367 clean_up ();
368}
369
370
371/**
372 * Ask CURL for the select set and then schedule the
373 * receiving task with the scheduler.
374 */
375static void
376run_multi ()
377{
378 CURLMcode mret;
379 fd_set rs;
380 fd_set ws;
381 fd_set es;
382 int max;
383
384 max = 0;
385 FD_ZERO (&rs);
386 FD_ZERO (&ws);
387 FD_ZERO (&es);
388 mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
389 if (mret != CURLM_OK)
390 {
391 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
392 _("%s failed at %s:%d: `%s'\n"),
393 "curl_multi_fdset", __FILE__, __LINE__,
394 curl_multi_strerror (mret));
395 clean_up ();
396 return;
397 }
398 current_task
399 = GNUNET_SCHEDULER_add_select (sched,
400 GNUNET_NO,
401 GNUNET_SCHEDULER_PRIORITY_DEFAULT,
402 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
403 GNUNET_TIME_UNIT_MINUTES,
404 max,
405 &rs,
406 &ws,
407 &multi_ready,
408 multi);
409}
410
411
412/**
413 * Main function that will download a hostlist and process its
414 * data.
415 */
416static void
417download_hostlist ()
418{
419 CURLcode ret;
420 CURLMcode mret;
421
422 curl = curl_easy_init ();
423 multi = NULL;
424 if (curl == NULL)
425 {
426 GNUNET_break (0);
427 clean_up ();
428 return;
429 }
430 transport = GNUNET_TRANSPORT_connect (sched, cfg, NULL, NULL, NULL, NULL);
431 current_url = get_url ();
432 GNUNET_log (GNUNET_ERROR_TYPE_INFO | GNUNET_ERROR_TYPE_BULK,
433 _("Bootstrapping using hostlist at `%s'.\n"),
434 current_url);
435
436 if (proxy != NULL)
437 CURL_EASY_SETOPT (curl, CURLOPT_PROXY, proxy);
438 download_pos = 0;
439 bogus_url = 0;
440 CURL_EASY_SETOPT (curl,
441 CURLOPT_WRITEFUNCTION,
442 &download_hostlist_processor);
443 if (ret != CURLE_OK)
444 {
445 clean_up ();
446 return;
447 }
448 CURL_EASY_SETOPT (curl,
449 CURLOPT_WRITEDATA,
450 NULL);
451 if (ret != CURLE_OK)
452 {
453 clean_up ();
454 return;
455 }
456 CURL_EASY_SETOPT (curl,
457 CURLOPT_URL,
458 current_url);
459 if (ret != CURLE_OK)
460 {
461 clean_up ();
462 return;
463 }
464 CURL_EASY_SETOPT (curl,
465 CURLOPT_FAILONERROR,
466 1);
467 CURL_EASY_SETOPT (curl,
468 CURLOPT_BUFFERSIZE,
469 GNUNET_SERVER_MAX_MESSAGE_SIZE);
470 if (0 == strncmp (current_url, "http", 4))
471 CURL_EASY_SETOPT (curl, CURLOPT_USERAGENT, "GNUnet");
472 CURL_EASY_SETOPT (curl,
473 CURLOPT_CONNECTTIMEOUT,
474 150L);
475 CURL_EASY_SETOPT (curl,
476 CURLOPT_NOSIGNAL,
477 1);
478 multi = curl_multi_init ();
479 if (multi == NULL)
480 {
481 GNUNET_break (0);
482 clean_up ();
483 return;
484 }
485 mret = curl_multi_add_handle (multi, curl);
486 if (mret != CURLM_OK)
487 {
488 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
489 _("%s failed at %s:%d: `%s'\n"),
490 "curl_multi_add_handle", __FILE__, __LINE__,
491 curl_multi_strerror (mret));
492 mret = curl_multi_cleanup (multi);
493 if (mret != CURLM_OK)
494 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
495 _("%s failed at %s:%d: `%s'\n"),
496 "curl_multi_cleanup", __FILE__, __LINE__,
497 curl_multi_strerror (mret));
498 multi = NULL;
499 clean_up ();
500 return;
501 }
502 run_multi (multi);
503}
504
505
506/**
507 * Task that checks if we should try to download a hostlist.
508 * If so, we initiate the download, otherwise we schedule
509 * this task again for a later time.
510 */
511static void
512check_task (void *cls,
513 const struct GNUNET_SCHEDULER_TaskContext *tc)
514{
515 if (connection_count < MIN_CONNECTIONS)
516 download_hostlist ();
517 else
518 schedule_hostlist_task ();
519}
520
521
522/**
523 * Compute when we should check the next time about downloading
524 * a hostlist; then schedule the task accordingly.
525 */
526static void
527schedule_hostlist_task ()
528{
529 struct GNUNET_TIME_Relative delay;
530
531 delay = hostlist_delay;
532 if (hostlist_delay.value == 0)
533 hostlist_delay = GNUNET_TIME_UNIT_SECONDS;
534 else
535 hostlist_delay = GNUNET_TIME_relative_multiply (hostlist_delay, 2);
536 if (hostlist_delay.value > GNUNET_TIME_UNIT_HOURS.value * connection_count)
537 hostlist_delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_DAYS,
538 connection_count);
539 GNUNET_STATISTICS_set (stats,
540 gettext_noop("Minimum time between hostlist downloads"),
541 hostlist_delay.value,
542 GNUNET_YES);
543 current_task = GNUNET_SCHEDULER_add_delayed (sched,
544 GNUNET_NO,
545 GNUNET_SCHEDULER_PRIORITY_IDLE,
546 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
547 delay,
548 &check_task,
549 NULL);
550}
551
552
553/**
554 * Method called whenever a given peer connects.
555 *
556 * @param cls closure
557 * @param peer peer identity this notification is about
558 */
559static void
560connect_handler (void *cls,
561 const struct
562 GNUNET_PeerIdentity * peer)
563{
564 connection_count++;
565}
566
567
568/**
569 * Method called whenever a given peer connects.
570 *
571 * @param cls closure
572 * @param peer peer identity this notification is about
573 */
574static void
575disconnect_handler (void *cls,
576 const struct
577 GNUNET_PeerIdentity * peer)
578{
579 connection_count--;
580}
581
582
583/**
584 * Continuation called by the statistics code once
585 * we go the stat. Initiates hostlist download scheduling.
586 *
587 * @param cls closure
588 * @param success GNUNET_OK if statistics were
589 * successfully obtained, GNUNET_SYSERR if not.
590 */
591static void
592primary_task (void *cls, int success)
593{
594 schedule_hostlist_task ();
595}
596
597
598static int
599process_stat (void *cls,
600 const char *subsystem,
601 const char *name,
602 unsigned long long value,
603 int is_persistent)
604{
605 hostlist_delay.value = (uint64_t) value;
606 return GNUNET_OK;
607}
608
609
610/**
611 * Start downloading hostlists from hostlist servers as necessary.
612 */
613int
614GNUNET_HOSTLIST_client_start (struct GNUNET_CONFIGURATION_Handle *c,
615 struct GNUNET_SCHEDULER_Handle *s,
616 struct GNUNET_STATISTICS_Handle *st,
617 GNUNET_CORE_ClientEventHandler *ch,
618 GNUNET_CORE_ClientEventHandler *dh)
619{
620 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
621 {
622 GNUNET_break (0);
623 return GNUNET_SYSERR;
624 }
625 cfg = c;
626 sched = s;
627 stats = st;
628 proxy = NULL;
629 GNUNET_CONFIGURATION_get_value_string (cfg,
630 "HOSTLIST",
631 "HTTP-PROXY",
632 &proxy);
633 *ch = &connect_handler;
634 *dh = &disconnect_handler;
635 GNUNET_STATISTICS_get (stats,
636 "hostlist",
637 gettext_noop("Minimum time between hostlist downloads"),
638 GNUNET_TIME_UNIT_MINUTES,
639 &primary_task,
640 &process_stat,
641 NULL);
642 return GNUNET_OK;
643}
644
645
646/**
647 * Stop downloading hostlists from hostlist servers as necessary.
648 */
649void
650GNUNET_HOSTLIST_client_stop ()
651{
652 GNUNET_SCHEDULER_cancel (sched,
653 current_task);
654 GNUNET_free_non_null (proxy);
655 proxy = NULL;
656 if (sched != NULL)
657 curl_global_cleanup ();
658 cfg = NULL;
659 sched = NULL;
660}
661
662/* end of hostlist-client.c */
diff --git a/src/hostlist/hostlist-client.h b/src/hostlist/hostlist-client.h
new file mode 100644
index 000000000..a17e1383f
--- /dev/null
+++ b/src/hostlist/hostlist-client.h
@@ -0,0 +1,58 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file hostlist/hostlist-client.h
23 * @brief hostlist support. Downloads HELLOs via HTTP.
24 * @author Christian Grothoff
25 */
26
27#ifndef HOSTLIST_CLIENT_H
28#define HOSTLIST_CLIENT_H
29
30#include "gnunet_core_service.h"
31#include "gnunet_statistics_service.h"
32#include "gnunet_util_lib.h"
33
34
35/**
36 * Start downloading hostlists from hostlist servers as necessary.
37 *
38 * @param ch set to handler for connect notifications
39 * @param dh set to handler for disconnect notifications
40 * @return GNUNET_OK on success
41 */
42int
43GNUNET_HOSTLIST_client_start (struct GNUNET_CONFIGURATION_Handle *c,
44 struct GNUNET_SCHEDULER_Handle *s,
45 struct GNUNET_STATISTICS_Handle *st,
46 GNUNET_CORE_ClientEventHandler *ch,
47 GNUNET_CORE_ClientEventHandler *dh);
48
49
50/**
51 * Stop downloading hostlists from hostlist servers as necessary.
52 */
53void
54GNUNET_HOSTLIST_client_stop (void);
55
56
57#endif
58/* end of hostlist-client.h */