diff options
author | Christian Grothoff <christian@grothoff.org> | 2009-06-13 23:15:58 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2009-06-13 23:15:58 +0000 |
commit | 3da76c97d01ec6dc652183c1f457d1379f15f4f8 (patch) | |
tree | 8f860c76d7237e287eed299bea29095f027c28f8 /src/topology | |
parent | a14ead2e712910bb5e4d818d2757592c4f14031b (diff) | |
download | gnunet-3da76c97d01ec6dc652183c1f457d1379f15f4f8.tar.gz gnunet-3da76c97d01ec6dc652183c1f457d1379f15f4f8.zip |
first hack at topology -- incomplete
Diffstat (limited to 'src/topology')
-rw-r--r-- | src/topology/gnunet-daemon-topology.c | 618 |
1 files changed, 609 insertions, 9 deletions
diff --git a/src/topology/gnunet-daemon-topology.c b/src/topology/gnunet-daemon-topology.c index 5d8c92523..4db35a17c 100644 --- a/src/topology/gnunet-daemon-topology.c +++ b/src/topology/gnunet-daemon-topology.c | |||
@@ -22,16 +22,476 @@ | |||
22 | * @file topology/gnunet-daemon-topology.c | 22 | * @file topology/gnunet-daemon-topology.c |
23 | * @brief code for bootstrapping via topology servers | 23 | * @brief code for bootstrapping via topology servers |
24 | * @author Christian Grothoff | 24 | * @author Christian Grothoff |
25 | * | ||
26 | * TODO: | ||
27 | * - blacklisting & respect for blacklist | ||
28 | * - calculate target_connection_count! | ||
29 | * - calculate peer_search retry delay | ||
25 | */ | 30 | */ |
26 | 31 | ||
27 | #include <stdlib.h> | 32 | #include <stdlib.h> |
28 | #include "platform.h" | 33 | #include "platform.h" |
29 | #include "gnunet_getopt_lib.h" | 34 | #include "gnunet_core_service.h" |
30 | #include "gnunet_protocols.h" | 35 | #include "gnunet_protocols.h" |
31 | #include "gnunet_program_lib.h" | 36 | #include "gnunet_peerinfo_service.h" |
32 | #include "gnunet_statistics_service.h" | 37 | #include "gnunet_util_lib.h" |
33 | #include "gnunet_strings_lib.h" | 38 | |
34 | #include "gnunet_time_lib.h" | 39 | |
40 | #define DEBUG_TOPOLOGY GNUNET_NO | ||
41 | |||
42 | |||
43 | /** | ||
44 | * List of neighbours and friends. | ||
45 | */ | ||
46 | struct FriendList | ||
47 | { | ||
48 | |||
49 | /** | ||
50 | * This is a linked list. | ||
51 | */ | ||
52 | struct FriendList *next; | ||
53 | |||
54 | /** | ||
55 | * Is this peer listed here because he is a friend? | ||
56 | */ | ||
57 | int is_friend; | ||
58 | |||
59 | /** | ||
60 | * Are we connected to this peer right now? | ||
61 | */ | ||
62 | int is_connected; | ||
63 | |||
64 | /** | ||
65 | * Until what time should we not try to connect again | ||
66 | * to this peer? | ||
67 | */ | ||
68 | struct GNUNET_TIME_Absolute blacklisted_until; | ||
69 | |||
70 | /** | ||
71 | * ID of the peer. | ||
72 | */ | ||
73 | struct GNUNET_PeerIdentity id; | ||
74 | |||
75 | }; | ||
76 | |||
77 | |||
78 | /** | ||
79 | * Our scheduler. | ||
80 | */ | ||
81 | static struct GNUNET_SCHEDULER_Handle * sched; | ||
82 | |||
83 | /** | ||
84 | * Our configuration. | ||
85 | */ | ||
86 | static struct GNUNET_CONFIGURATION_Handle * cfg; | ||
87 | |||
88 | /** | ||
89 | * Handle to the core API. | ||
90 | */ | ||
91 | static struct GNUNET_CORE_Handle *handle; | ||
92 | |||
93 | /** | ||
94 | * Identity of this peer. | ||
95 | */ | ||
96 | static struct GNUNET_PeerIdentity my_identity; | ||
97 | |||
98 | /** | ||
99 | * Linked list of all of our friends and all of our current | ||
100 | * neighbours. | ||
101 | */ | ||
102 | static struct FriendList *friends; | ||
103 | |||
104 | /** | ||
105 | * Flag to disallow non-friend connections (pure F2F mode). | ||
106 | */ | ||
107 | static int friends_only; | ||
108 | |||
109 | /** | ||
110 | * Minimum number of friends to have in the | ||
111 | * connection set before we allow non-friends. | ||
112 | */ | ||
113 | static unsigned int minimum_friend_count; | ||
114 | |||
115 | /** | ||
116 | * Number of peers (friends and others) that we are currently connected to. | ||
117 | */ | ||
118 | static unsigned int connection_count; | ||
119 | |||
120 | /** | ||
121 | * Target number of connections. | ||
122 | */ | ||
123 | static unsigned int target_connection_count; | ||
124 | |||
125 | /** | ||
126 | * Number of friends that we are currently connected to. | ||
127 | */ | ||
128 | static unsigned int friend_count; | ||
129 | |||
130 | /** | ||
131 | * Should the topology daemon try to establish connections? | ||
132 | */ | ||
133 | static int autoconnect; | ||
134 | |||
135 | |||
136 | |||
137 | /** | ||
138 | * Force a disconnect from the specified peer. | ||
139 | */ | ||
140 | static void | ||
141 | force_disconnect (const struct GNUNET_PeerIdentity *peer) | ||
142 | { | ||
143 | GNUNET_CORE_peer_configure (handle, | ||
144 | peer, | ||
145 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
146 | 0, | ||
147 | 0, | ||
148 | 0, | ||
149 | NULL, | ||
150 | NULL); | ||
151 | } | ||
152 | |||
153 | |||
154 | /** | ||
155 | * Function called by core when our attempt to connect | ||
156 | * succeeded. Does nothing. | ||
157 | */ | ||
158 | static size_t | ||
159 | ready_callback (void *cls, | ||
160 | size_t size, void *buf) | ||
161 | { | ||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | |||
166 | /** | ||
167 | * Try to connect to the specified peer. | ||
168 | * | ||
169 | * @param pos NULL if not in friend list yet | ||
170 | */ | ||
171 | static void | ||
172 | attempt_connect (const struct GNUNET_PeerIdentity *peer, | ||
173 | struct FriendList *pos) | ||
174 | { | ||
175 | /* FIXME: do blacklist! */ | ||
176 | GNUNET_CORE_notify_transmit_ready (handle, | ||
177 | 0 /* priority */, | ||
178 | GNUNET_TIME_UNIT_MINUTES, | ||
179 | peer, | ||
180 | sizeof(struct GNUNET_MessageHeader), | ||
181 | &ready_callback, | ||
182 | NULL); | ||
183 | } | ||
184 | |||
185 | |||
186 | /** | ||
187 | * Is this peer one of our friends? | ||
188 | */ | ||
189 | static int | ||
190 | is_friend (const struct GNUNET_PeerIdentity * peer) | ||
191 | { | ||
192 | struct FriendList *pos; | ||
193 | |||
194 | pos = friends; | ||
195 | while (pos != NULL) | ||
196 | { | ||
197 | if ( (GNUNET_YES == pos->is_friend) && | ||
198 | (0 == memcmp (&pos->id, peer, sizeof (struct GNUNET_PeerIdentity))) ) | ||
199 | return GNUNET_YES; | ||
200 | pos = pos->next; | ||
201 | } | ||
202 | return GNUNET_NO; | ||
203 | } | ||
204 | |||
205 | |||
206 | /** | ||
207 | * Check if an additional connection from the given peer is allowed. | ||
208 | */ | ||
209 | static int | ||
210 | is_connection_allowed (const struct GNUNET_PeerIdentity * peer) | ||
211 | { | ||
212 | if (0 == memcmp (&my_identity, peer, sizeof (struct GNUNET_PeerIdentity))) | ||
213 | return GNUNET_SYSERR; /* disallow connections to self */ | ||
214 | if (is_friend (peer)) | ||
215 | return GNUNET_OK; | ||
216 | if (GNUNET_YES == friends_only) | ||
217 | return GNUNET_SYSERR; | ||
218 | if (friend_count >= minimum_friend_count) | ||
219 | return GNUNET_OK; | ||
220 | return GNUNET_SYSERR; | ||
221 | } | ||
222 | |||
223 | |||
224 | /** | ||
225 | * Method called whenever a peer connects. | ||
226 | * | ||
227 | * @param cls closure | ||
228 | * @param peer peer identity this notification is about | ||
229 | */ | ||
230 | static void connect_notify (void *cls, | ||
231 | const struct | ||
232 | GNUNET_PeerIdentity * peer) | ||
233 | { | ||
234 | struct FriendList *pos; | ||
235 | |||
236 | connection_count++; | ||
237 | pos = friends; | ||
238 | while (pos != NULL) | ||
239 | { | ||
240 | if ( (GNUNET_YES == pos->is_friend) && | ||
241 | (0 == memcmp (&pos->id, peer, sizeof (struct GNUNET_PeerIdentity))) ) | ||
242 | { | ||
243 | GNUNET_assert (GNUNET_NO == pos->is_connected); | ||
244 | pos->is_connected = GNUNET_YES; | ||
245 | friend_count++; | ||
246 | return; | ||
247 | } | ||
248 | pos = pos->next; | ||
249 | } | ||
250 | pos = GNUNET_malloc (sizeof(struct FriendList)); | ||
251 | pos->id = *peer; | ||
252 | pos->is_connected = GNUNET_YES; | ||
253 | pos->next = friends; | ||
254 | friends = pos; | ||
255 | if (GNUNET_OK != is_connection_allowed (peer)) | ||
256 | force_disconnect (peer); | ||
257 | } | ||
258 | |||
259 | |||
260 | /** | ||
261 | * Disconnect from all non-friends (we're below quota). | ||
262 | */ | ||
263 | static void | ||
264 | drop_non_friends () | ||
265 | { | ||
266 | struct FriendList *pos; | ||
267 | |||
268 | pos = friends; | ||
269 | while (pos != NULL) | ||
270 | { | ||
271 | if (GNUNET_NO == pos->is_friend) | ||
272 | { | ||
273 | GNUNET_assert (GNUNET_YES == pos->is_connected); | ||
274 | force_disconnect (&pos->id); | ||
275 | } | ||
276 | pos = pos->next; | ||
277 | } | ||
278 | } | ||
279 | |||
280 | |||
281 | /** | ||
282 | * Method called whenever a peer disconnects. | ||
283 | * | ||
284 | * @param cls closure | ||
285 | * @param peer peer identity this notification is about | ||
286 | */ | ||
287 | static void disconnect_notify (void *cls, | ||
288 | const struct | ||
289 | GNUNET_PeerIdentity * peer) | ||
290 | { | ||
291 | struct FriendList *pos; | ||
292 | struct FriendList *prev; | ||
293 | |||
294 | connection_count--; | ||
295 | pos = friends; | ||
296 | prev = NULL; | ||
297 | while (pos != NULL) | ||
298 | { | ||
299 | if (0 == memcmp (&pos->id, peer, sizeof (struct GNUNET_PeerIdentity))) | ||
300 | { | ||
301 | GNUNET_assert (GNUNET_YES == pos->is_connected); | ||
302 | pos->is_connected = GNUNET_NO; | ||
303 | if (GNUNET_YES == pos->is_friend) | ||
304 | { | ||
305 | friend_count--; | ||
306 | if (friend_count < minimum_friend_count) | ||
307 | { | ||
308 | /* disconnect from all non-friends */ | ||
309 | drop_non_friends (); | ||
310 | attempt_connect (peer, pos); | ||
311 | } | ||
312 | } | ||
313 | else | ||
314 | { | ||
315 | /* free entry */ | ||
316 | if (prev == NULL) | ||
317 | friends = pos->next; | ||
318 | else | ||
319 | prev->next = pos->next; | ||
320 | GNUNET_free (pos); | ||
321 | } | ||
322 | return; | ||
323 | } | ||
324 | prev = pos; | ||
325 | pos = pos->next; | ||
326 | } | ||
327 | GNUNET_break (0); | ||
328 | } | ||
329 | |||
330 | /** | ||
331 | * Find more peers that we should connect to and ask the | ||
332 | * core to establish connections. | ||
333 | */ | ||
334 | static void | ||
335 | find_more_peers (void *cls, | ||
336 | const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
337 | |||
338 | |||
339 | /** | ||
340 | * Determine when we should try again to find more peers and | ||
341 | * schedule the task. | ||
342 | */ | ||
343 | static void | ||
344 | schedule_peer_search () | ||
345 | { | ||
346 | struct GNUNET_TIME_Relative delay; | ||
347 | |||
348 | /* FIXME: calculate reasonable delay here */ | ||
349 | delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, | ||
350 | 42); | ||
351 | GNUNET_SCHEDULER_add_delayed (sched, | ||
352 | GNUNET_NO, | ||
353 | GNUNET_SCHEDULER_PRIORITY_DEFAULT, | ||
354 | GNUNET_SCHEDULER_NO_PREREQUISITE_TASK, | ||
355 | delay, | ||
356 | &find_more_peers, | ||
357 | NULL); | ||
358 | } | ||
359 | |||
360 | |||
361 | /** | ||
362 | * Peerinfo calls this function to let us know about a | ||
363 | * possible peer that we might want to connect to. | ||
364 | */ | ||
365 | static void | ||
366 | process_peer (void *cls, | ||
367 | const struct GNUNET_PeerIdentity * peer, | ||
368 | const struct GNUNET_HELLO_Message * hello, | ||
369 | uint32_t trust) | ||
370 | { | ||
371 | struct FriendList *pos; | ||
372 | |||
373 | if (peer == NULL) | ||
374 | { | ||
375 | /* last call, schedule 'find_more_peers' again... */ | ||
376 | schedule_peer_search (); | ||
377 | return; | ||
378 | } | ||
379 | if (hello == NULL) | ||
380 | { | ||
381 | /* no HELLO known; can not connect, ignore! */ | ||
382 | return; | ||
383 | } | ||
384 | if (0 == memcmp (&my_identity, | ||
385 | peer, sizeof (struct GNUNET_PeerIdentity))) | ||
386 | return; /* that's me! */ | ||
387 | |||
388 | pos = friends; | ||
389 | while (pos != NULL) | ||
390 | { | ||
391 | if (0 == memcmp (&pos->id, peer, sizeof (struct GNUNET_PeerIdentity))) | ||
392 | { | ||
393 | if (GNUNET_YES == pos->is_connected) | ||
394 | return; | ||
395 | /* FIXME: check blacklisted... */ | ||
396 | if (GNUNET_YES == pos->is_friend) | ||
397 | { | ||
398 | attempt_connect (peer, pos); | ||
399 | return; | ||
400 | } | ||
401 | } | ||
402 | pos = pos->next; | ||
403 | } | ||
404 | if (GNUNET_YES == friends_only) | ||
405 | return; | ||
406 | if (friend_count < minimum_friend_count) | ||
407 | return; | ||
408 | attempt_connect (peer, NULL); | ||
409 | } | ||
410 | |||
411 | |||
412 | /** | ||
413 | * Try to add more friends to our connection set. | ||
414 | */ | ||
415 | static void | ||
416 | try_add_friends () | ||
417 | { | ||
418 | struct FriendList *pos; | ||
419 | |||
420 | pos = friends; | ||
421 | while (pos != NULL) | ||
422 | { | ||
423 | /* FIXME: check friends for blacklisting... */ | ||
424 | if ( (GNUNET_YES == pos->is_friend) && | ||
425 | (GNUNET_YES != pos->is_connected) ) | ||
426 | attempt_connect (&pos->id, pos); | ||
427 | pos = pos->next; | ||
428 | } | ||
429 | } | ||
430 | |||
431 | |||
432 | /** | ||
433 | * Find more peers that we should connect to and ask the | ||
434 | * core to establish connections. | ||
435 | */ | ||
436 | static void | ||
437 | find_more_peers (void *cls, | ||
438 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
439 | { | ||
440 | if (target_connection_count <= connection_count) | ||
441 | { | ||
442 | schedule_peer_search (); | ||
443 | return; | ||
444 | } | ||
445 | if ( (GNUNET_YES == friends_only) || | ||
446 | (friend_count < minimum_friend_count) ) | ||
447 | { | ||
448 | try_add_friends (); | ||
449 | schedule_peer_search (); | ||
450 | return; | ||
451 | } | ||
452 | GNUNET_PEERINFO_for_all (cfg, | ||
453 | sched, | ||
454 | NULL, | ||
455 | 0, GNUNET_TIME_UNIT_FOREVER_REL, | ||
456 | &process_peer, NULL); | ||
457 | } | ||
458 | |||
459 | |||
460 | /** | ||
461 | * Function called after GNUNET_CORE_connect has succeeded | ||
462 | * (or failed for good). | ||
463 | * | ||
464 | * @param cls closure | ||
465 | * @param server handle to the server, NULL if we failed | ||
466 | * @param my_id ID of this peer, NULL if we failed | ||
467 | * @param publicKey public key of this peer, NULL if we failed | ||
468 | */ | ||
469 | static void | ||
470 | core_init (void *cls, | ||
471 | struct GNUNET_CORE_Handle * server, | ||
472 | const struct GNUNET_PeerIdentity * | ||
473 | my_id, | ||
474 | const struct | ||
475 | GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded * | ||
476 | publicKey) | ||
477 | { | ||
478 | if (server == NULL) | ||
479 | { | ||
480 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
481 | _("Failed to connect to core service, can not manage topology!\n")); | ||
482 | return; | ||
483 | } | ||
484 | handle = server; | ||
485 | my_identity = *my_id; | ||
486 | if (autoconnect) | ||
487 | GNUNET_SCHEDULER_add_delayed (sched, | ||
488 | GNUNET_NO, | ||
489 | GNUNET_SCHEDULER_PRIORITY_DEFAULT, | ||
490 | GNUNET_SCHEDULER_NO_PREREQUISITE_TASK, | ||
491 | GNUNET_TIME_UNIT_SECONDS /* give core time to tell us about existing connections */, | ||
492 | &find_more_peers, | ||
493 | NULL); | ||
494 | } | ||
35 | 495 | ||
36 | 496 | ||
37 | /** | 497 | /** |
@@ -42,23 +502,163 @@ static struct GNUNET_GETOPT_CommandLineOption options[] = { | |||
42 | }; | 502 | }; |
43 | 503 | ||
44 | 504 | ||
505 | /** | ||
506 | * Read the friends file. | ||
507 | */ | ||
508 | static void | ||
509 | read_friends_file (struct GNUNET_CONFIGURATION_Handle *cfg) | ||
510 | { | ||
511 | char *fn; | ||
512 | char *data; | ||
513 | size_t pos; | ||
514 | GNUNET_HashCode hc; | ||
515 | struct stat frstat; | ||
516 | struct GNUNET_CRYPTO_HashAsciiEncoded enc; | ||
517 | unsigned int entries_found; | ||
518 | struct FriendList *fl; | ||
519 | |||
520 | fn = NULL; | ||
521 | GNUNET_CONFIGURATION_get_value_filename (cfg, | ||
522 | "TOPOLOGY", | ||
523 | "FRIENDS", | ||
524 | &fn); | ||
525 | if (GNUNET_OK != GNUNET_DISK_file_test (fn)) | ||
526 | GNUNET_DISK_file_write (fn, NULL, 0, "600"); | ||
527 | if (0 != STAT (fn, &frstat)) | ||
528 | { | ||
529 | if ((friends_only) || (minimum_friend_count > 0)) | ||
530 | { | ||
531 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
532 | _("Could not read friends list `%s'\n"), fn); | ||
533 | GNUNET_free (fn); | ||
534 | return; | ||
535 | } | ||
536 | } | ||
537 | if (frstat.st_size == 0) | ||
538 | { | ||
539 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
540 | _("Friends file `%s' is empty.\n"), | ||
541 | fn); | ||
542 | GNUNET_free (fn); | ||
543 | return; | ||
544 | } | ||
545 | data = GNUNET_malloc_large (frstat.st_size); | ||
546 | if (frstat.st_size != | ||
547 | GNUNET_DISK_file_read (fn, frstat.st_size, data)) | ||
548 | { | ||
549 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
550 | _("Failed to read friends list from `%s'\n"), fn); | ||
551 | GNUNET_free (fn); | ||
552 | GNUNET_free (data); | ||
553 | return; | ||
554 | } | ||
555 | entries_found = 0; | ||
556 | pos = 0; | ||
557 | while ((pos < frstat.st_size) && isspace (data[pos])) | ||
558 | pos++; | ||
559 | while ((frstat.st_size >= sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)) && | ||
560 | (pos <= frstat.st_size - sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded))) | ||
561 | { | ||
562 | memcpy (&enc, &data[pos], sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)); | ||
563 | if (!isspace (enc.encoding[sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1])) | ||
564 | { | ||
565 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
566 | _("Syntax error in topology specification at offset %llu, skipping bytes.\n"), | ||
567 | (unsigned long long) pos); | ||
568 | pos++; | ||
569 | while ((pos < frstat.st_size) && (!isspace (data[pos]))) | ||
570 | pos++; | ||
571 | continue; | ||
572 | } | ||
573 | enc.encoding[sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] = '\0'; | ||
574 | if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string ((char *) &enc, &hc)) | ||
575 | { | ||
576 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
577 | _("Syntax error in topology specification at offset %llu, skipping bytes `%s'.\n"), | ||
578 | (unsigned long long) pos, | ||
579 | &enc); | ||
580 | } | ||
581 | else | ||
582 | { | ||
583 | entries_found++; | ||
584 | fl = GNUNET_malloc (sizeof(struct FriendList)); | ||
585 | fl->is_friend = GNUNET_YES; | ||
586 | fl->id.hashPubKey = hc; | ||
587 | fl->next = friends; | ||
588 | friends = fl; | ||
589 | } | ||
590 | pos = pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded); | ||
591 | while ((pos < frstat.st_size) && isspace (data[pos])) | ||
592 | pos++; | ||
593 | } | ||
594 | GNUNET_free (data); | ||
595 | GNUNET_free (fn); | ||
596 | if ( (minimum_friend_count > entries_found) && | ||
597 | (friends_only == GNUNET_NO) ) | ||
598 | { | ||
599 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
600 | _("Fewer friends specified than required by minimum friend count. Will only connect to friends.\n")); | ||
601 | } | ||
602 | if ( (minimum_friend_count > target_connection_count) && | ||
603 | (friends_only == GNUNET_NO) ) | ||
604 | { | ||
605 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
606 | _("More friendly connections required than target total number of connections.\n")); | ||
607 | } | ||
608 | } | ||
609 | |||
45 | 610 | ||
46 | /** | 611 | /** |
47 | * Main function that will be run. | 612 | * Main function that will be run. |
48 | * | 613 | * |
49 | * @param cls closure | 614 | * @param cls closure |
50 | * @param sched the scheduler to use | 615 | * @param s the scheduler to use |
51 | * @param args remaining command-line arguments | 616 | * @param args remaining command-line arguments |
52 | * @param cfgfile name of the configuration file used (for saving, can be NULL!) | 617 | * @param cfgfile name of the configuration file used (for saving, can be NULL!) |
53 | * @param cfg configuration | 618 | * @param c configuration |
54 | */ | 619 | */ |
55 | static void | 620 | static void |
56 | run (void *cls, | 621 | run (void *cls, |
57 | struct GNUNET_SCHEDULER_Handle * sched, | 622 | struct GNUNET_SCHEDULER_Handle * s, |
58 | char *const *args, | 623 | char *const *args, |
59 | const char *cfgfile, | 624 | const char *cfgfile, |
60 | struct GNUNET_CONFIGURATION_Handle * cfg) | 625 | struct GNUNET_CONFIGURATION_Handle * c) |
61 | { | 626 | { |
627 | struct GNUNET_CORE_MessageHandler handlers[] = | ||
628 | { | ||
629 | { NULL, 0, 0 } | ||
630 | }; | ||
631 | unsigned long long opt; | ||
632 | |||
633 | sched = s; | ||
634 | cfg = c; | ||
635 | autoconnect = GNUNET_CONFIGURATION_get_value_yesno (cfg, | ||
636 | "TOPOLOGY", | ||
637 | "AUTOCONNECT"); | ||
638 | friends_only = GNUNET_CONFIGURATION_get_value_yesno (cfg, | ||
639 | "TOPOLOGY", | ||
640 | "FRIENDS-ONLY"); | ||
641 | opt = 0; | ||
642 | GNUNET_CONFIGURATION_get_value_number (cfg, | ||
643 | "TOPOLOGY", | ||
644 | "MINIMUM-FRIENDS", | ||
645 | &opt); | ||
646 | minimum_friend_count = (unsigned int) opt; | ||
647 | |||
648 | if ( (friends_only == GNUNET_YES) || | ||
649 | (minimum_friend_count > 0) ) | ||
650 | read_friends_file (cfg); | ||
651 | GNUNET_CORE_connect (sched, | ||
652 | cfg, | ||
653 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
654 | NULL, | ||
655 | &core_init, | ||
656 | &connect_notify, | ||
657 | &disconnect_notify, | ||
658 | NULL, | ||
659 | NULL, GNUNET_NO, | ||
660 | NULL, GNUNET_NO, | ||
661 | handlers); | ||
62 | } | 662 | } |
63 | 663 | ||
64 | 664 | ||