diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-03-11 23:26:24 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-03-11 23:26:24 +0000 |
commit | bd3d0ed05e2c190a5e3f64e874f6cb4b8e3071ed (patch) | |
tree | 2684c31b29033d3bb5ae44651b396926e86e7cc5 /src | |
parent | 0d7234799b96e9822330d70d3dd8ffea89eb0a75 (diff) | |
download | gnunet-bd3d0ed05e2c190a5e3f64e874f6cb4b8e3071ed.tar.gz gnunet-bd3d0ed05e2c190a5e3f64e874f6cb4b8e3071ed.zip |
-towards addressing #2206
Diffstat (limited to 'src')
-rw-r--r-- | src/peerinfo-tool/gnunet-peerinfo.c | 194 |
1 files changed, 141 insertions, 53 deletions
diff --git a/src/peerinfo-tool/gnunet-peerinfo.c b/src/peerinfo-tool/gnunet-peerinfo.c index 7867191b7..2ffea8bcd 100644 --- a/src/peerinfo-tool/gnunet-peerinfo.c +++ b/src/peerinfo-tool/gnunet-peerinfo.c | |||
@@ -37,8 +37,46 @@ | |||
37 | /** | 37 | /** |
38 | * Structure we use to collect printable address information. | 38 | * Structure we use to collect printable address information. |
39 | */ | 39 | */ |
40 | struct PrintContext; | ||
41 | |||
42 | /** | ||
43 | * Record we keep for each printable address. | ||
44 | */ | ||
45 | struct AddressRecord | ||
46 | { | ||
47 | /** | ||
48 | * Current address-to-string context (if active, otherwise NULL). | ||
49 | */ | ||
50 | struct GNUNET_TRANSPORT_AddressToStringContext *atsc; | ||
51 | |||
52 | /** | ||
53 | * Printable address. | ||
54 | */ | ||
55 | char *result; | ||
56 | |||
57 | /** | ||
58 | * Print context this address record belongs to. | ||
59 | */ | ||
60 | struct PrintContext *pc; | ||
61 | }; | ||
62 | |||
63 | |||
64 | /** | ||
65 | * Structure we use to collect printable address information. | ||
66 | */ | ||
40 | struct PrintContext | 67 | struct PrintContext |
41 | { | 68 | { |
69 | |||
70 | /** | ||
71 | * Kept in DLL. | ||
72 | */ | ||
73 | struct PrintContext *next; | ||
74 | |||
75 | /** | ||
76 | * Kept in DLL. | ||
77 | */ | ||
78 | struct PrintContext *prev; | ||
79 | |||
42 | /** | 80 | /** |
43 | * Identity of the peer. | 81 | * Identity of the peer. |
44 | */ | 82 | */ |
@@ -47,27 +85,23 @@ struct PrintContext | |||
47 | /** | 85 | /** |
48 | * List of printable addresses. | 86 | * List of printable addresses. |
49 | */ | 87 | */ |
50 | char **address_list; | 88 | struct AddressRecord *address_list; |
51 | 89 | ||
52 | /** | 90 | /** |
53 | * Number of addresses in 'address_list'. | 91 | * Number of completed addresses in 'address_list'. |
54 | */ | 92 | */ |
55 | unsigned int num_addresses; | 93 | unsigned int num_addresses; |
56 | 94 | ||
57 | /** | 95 | /** |
58 | * Current offset in 'address_list' | 96 | * Number of addresses allocated in 'address_list'. |
59 | */ | 97 | */ |
60 | uint32_t off; | 98 | unsigned int address_list_size; |
61 | 99 | ||
62 | /** | 100 | /** |
63 | * URI (FIXME: overloaded struct!) | 101 | * Current offset in 'address_list' (counted down). |
64 | */ | 102 | */ |
65 | char *uri; | 103 | unsigned int off; |
66 | 104 | ||
67 | /** | ||
68 | * Length of 'uri' (FIXME: not nice) | ||
69 | */ | ||
70 | size_t uri_len; | ||
71 | }; | 105 | }; |
72 | 106 | ||
73 | 107 | ||
@@ -81,7 +115,6 @@ struct GetUriContext | |||
81 | */ | 115 | */ |
82 | char *uri; | 116 | char *uri; |
83 | 117 | ||
84 | struct PrintContext *pc; | ||
85 | }; | 118 | }; |
86 | 119 | ||
87 | 120 | ||
@@ -158,11 +191,6 @@ static GNUNET_SCHEDULER_TaskIdentifier tt; | |||
158 | static struct GNUNET_PEERINFO_IteratorContext *pic; | 191 | static struct GNUNET_PEERINFO_IteratorContext *pic; |
159 | 192 | ||
160 | /** | 193 | /** |
161 | * Current address-to-string context (if active, otherwise NULL). | ||
162 | */ | ||
163 | static struct GNUNET_TRANSPORT_AddressToStringContext *atsc; | ||
164 | |||
165 | /** | ||
166 | * My peer identity. | 194 | * My peer identity. |
167 | */ | 195 | */ |
168 | static struct GNUNET_PeerIdentity my_peer_identity; | 196 | static struct GNUNET_PeerIdentity my_peer_identity; |
@@ -172,6 +200,16 @@ static struct GNUNET_PeerIdentity my_peer_identity; | |||
172 | */ | 200 | */ |
173 | static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded my_public_key; | 201 | static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded my_public_key; |
174 | 202 | ||
203 | /** | ||
204 | * Head of list of print contexts. | ||
205 | */ | ||
206 | static struct PrintContext *pc_head; | ||
207 | |||
208 | /** | ||
209 | * Tail of list of print contexts. | ||
210 | */ | ||
211 | static struct PrintContext *pc_tail; | ||
212 | |||
175 | 213 | ||
176 | /** | 214 | /** |
177 | * Main state machine that goes over all options and | 215 | * Main state machine that goes over all options and |
@@ -199,15 +237,25 @@ dump_pc (struct PrintContext *pc) | |||
199 | unsigned int i; | 237 | unsigned int i; |
200 | 238 | ||
201 | GNUNET_CRYPTO_hash_to_enc (&pc->peer.hashPubKey, &enc); | 239 | GNUNET_CRYPTO_hash_to_enc (&pc->peer.hashPubKey, &enc); |
202 | printf (_("Peer `%s'\n"), (const char *) &enc); | 240 | printf (_("Peer `%s'\n"), |
241 | (const char *) &enc); | ||
203 | for (i = 0; i < pc->num_addresses; i++) | 242 | for (i = 0; i < pc->num_addresses; i++) |
204 | { | 243 | { |
205 | printf ("\t%s\n", pc->address_list[i]); | 244 | if (NULL != pc->address_list[i].result) |
206 | GNUNET_free (pc->address_list[i]); | 245 | { |
246 | printf ("\t%s\n", pc->address_list[i].result); | ||
247 | GNUNET_free (pc->address_list[i].result); | ||
248 | } | ||
207 | } | 249 | } |
208 | printf ("\n"); | 250 | printf ("\n"); |
209 | GNUNET_array_grow (pc->address_list, pc->num_addresses, 0); | 251 | GNUNET_free_non_null (pc->address_list); |
252 | GNUNET_CONTAINER_DLL_remove (pc_head, | ||
253 | pc_tail, | ||
254 | pc); | ||
210 | GNUNET_free (pc); | 255 | GNUNET_free (pc); |
256 | if ( (NULL == pc_head) && | ||
257 | (NULL == pic) ) | ||
258 | tt = GNUNET_SCHEDULER_add_now (&state_machine, NULL); | ||
211 | } | 259 | } |
212 | 260 | ||
213 | 261 | ||
@@ -223,18 +271,19 @@ dump_pc (struct PrintContext *pc) | |||
223 | static void | 271 | static void |
224 | process_resolved_address (void *cls, const char *address) | 272 | process_resolved_address (void *cls, const char *address) |
225 | { | 273 | { |
226 | struct PrintContext *pc = cls; | 274 | struct AddressRecord * ar = cls; |
275 | struct PrintContext *pc = ar->pc; | ||
227 | 276 | ||
228 | atsc = NULL; | 277 | if (NULL != address) |
229 | if (address == NULL) | ||
230 | { | 278 | { |
231 | pc->off--; | 279 | if (NULL == ar->result) |
232 | if (pc->off == 0) | 280 | ar->result = GNUNET_strdup (address); |
233 | dump_pc (pc); | ||
234 | return; | 281 | return; |
235 | } | 282 | } |
236 | GNUNET_array_append (pc->address_list, pc->num_addresses, | 283 | ar->atsc = NULL; |
237 | GNUNET_strdup (address)); | 284 | pc->num_addresses++; |
285 | if (pc->num_addresses == pc->address_list_size) | ||
286 | dump_pc (pc); | ||
238 | } | 287 | } |
239 | 288 | ||
240 | 289 | ||
@@ -270,20 +319,27 @@ print_address (void *cls, const struct GNUNET_HELLO_Address *address, | |||
270 | struct GNUNET_TIME_Absolute expiration) | 319 | struct GNUNET_TIME_Absolute expiration) |
271 | { | 320 | { |
272 | struct PrintContext *pc = cls; | 321 | struct PrintContext *pc = cls; |
273 | 322 | struct AddressRecord *ar; | |
274 | // FIXME: this is called many times in parallel! | 323 | |
275 | atsc = GNUNET_TRANSPORT_address_to_string (cfg, address, no_resolve, | 324 | GNUNET_assert (0 < pc->off); |
276 | GNUNET_TIME_relative_multiply | 325 | ar = &pc->address_list[--pc->off]; |
277 | (GNUNET_TIME_UNIT_SECONDS, 10), | 326 | ar->pc = pc; |
278 | &process_resolved_address, pc); | 327 | ar->atsc = GNUNET_TRANSPORT_address_to_string (cfg, address, no_resolve, |
328 | GNUNET_TIME_relative_multiply | ||
329 | (GNUNET_TIME_UNIT_SECONDS, 10), | ||
330 | &process_resolved_address, ar); | ||
279 | return GNUNET_OK; | 331 | return GNUNET_OK; |
280 | } | 332 | } |
281 | 333 | ||
282 | 334 | ||
283 | /** | 335 | /** |
284 | * Print information about the peer. | 336 | * Print information about the peer. |
285 | * Currently prints the GNUNET_PeerIdentity and the IP. | 337 | * Currently prints the GNUNET_PeerIdentity and the transport address. |
286 | * Could of course do more (e.g. resolve via DNS). | 338 | * |
339 | * @param cls the 'struct PrintContext' | ||
340 | * @param peer identity of the peer | ||
341 | * @param hello addresses of the peer | ||
342 | * @param err_msg error message | ||
287 | */ | 343 | */ |
288 | static void | 344 | static void |
289 | print_peer_info (void *cls, const struct GNUNET_PeerIdentity *peer, | 345 | print_peer_info (void *cls, const struct GNUNET_PeerIdentity *peer, |
@@ -294,28 +350,41 @@ print_peer_info (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
294 | 350 | ||
295 | if (peer == NULL) | 351 | if (peer == NULL) |
296 | { | 352 | { |
353 | pic = NULL; /* end of iteration */ | ||
297 | if (err_msg != NULL) | 354 | if (err_msg != NULL) |
298 | FPRINTF (stderr, "%s", _("Error in communication with PEERINFO service\n")); | 355 | { |
299 | // FIXME: this doesn't mean we're fully done with the printing! | 356 | FPRINTF (stderr, |
300 | // (as the a2s calls happen asynchronously!) | 357 | _("Error in communication with PEERINFO service: %s\n"), |
301 | tt = GNUNET_SCHEDULER_add_now (&state_machine, NULL); | 358 | err_msg); |
359 | } | ||
360 | if (NULL == pc_head) | ||
361 | tt = GNUNET_SCHEDULER_add_now (&state_machine, NULL); | ||
302 | return; | 362 | return; |
303 | } | 363 | } |
304 | if ((be_quiet) || (NULL == hello)) | 364 | if ((GNUNET_YES == be_quiet) || (NULL == hello)) |
305 | { | 365 | { |
306 | GNUNET_CRYPTO_hash_to_enc (&peer->hashPubKey, &enc); | 366 | GNUNET_CRYPTO_hash_to_enc (&peer->hashPubKey, &enc); |
307 | printf ("%s\n", (const char *) &enc); | 367 | printf ("%s\n", (const char *) &enc); |
308 | return; | 368 | return; |
309 | } | 369 | } |
310 | pc = GNUNET_malloc (sizeof (struct PrintContext)); | 370 | pc = GNUNET_malloc (sizeof (struct PrintContext)); |
371 | GNUNET_CONTAINER_DLL_insert (pc_head, | ||
372 | pc_tail, | ||
373 | pc); | ||
311 | pc->peer = *peer; | 374 | pc->peer = *peer; |
312 | GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &count_address, pc); | 375 | GNUNET_HELLO_iterate_addresses (hello, |
376 | GNUNET_NO, | ||
377 | &count_address, | ||
378 | pc); | ||
313 | if (0 == pc->off) | 379 | if (0 == pc->off) |
314 | { | 380 | { |
315 | dump_pc (pc); | 381 | dump_pc (pc); |
316 | return; | 382 | return; |
317 | } | 383 | } |
318 | GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &print_address, pc); | 384 | pc->address_list_size = pc->off; |
385 | pc->address_list = GNUNET_malloc (sizeof (struct AddressRecord) * pc->off); | ||
386 | GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, | ||
387 | &print_address, pc); | ||
319 | } | 388 | } |
320 | 389 | ||
321 | 390 | ||
@@ -635,6 +704,10 @@ static void | |||
635 | shutdown_task (void *cls, | 704 | shutdown_task (void *cls, |
636 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 705 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
637 | { | 706 | { |
707 | struct PrintContext *pc; | ||
708 | struct AddressRecord *ar; | ||
709 | unsigned int i; | ||
710 | |||
638 | if (GNUNET_SCHEDULER_NO_TASK != tt) | 711 | if (GNUNET_SCHEDULER_NO_TASK != tt) |
639 | { | 712 | { |
640 | GNUNET_SCHEDULER_cancel (tt); | 713 | GNUNET_SCHEDULER_cancel (tt); |
@@ -645,14 +718,30 @@ shutdown_task (void *cls, | |||
645 | GNUNET_PEERINFO_iterate_cancel (pic); | 718 | GNUNET_PEERINFO_iterate_cancel (pic); |
646 | pic = NULL; | 719 | pic = NULL; |
647 | } | 720 | } |
648 | if (NULL != atsc) | 721 | while (NULL != (pc = pc_head)) |
649 | { | 722 | { |
650 | GNUNET_TRANSPORT_address_to_string_cancel (atsc); | 723 | GNUNET_CONTAINER_DLL_remove (pc_head, |
651 | atsc = NULL; | 724 | pc_tail, |
725 | pc); | ||
726 | for (i=0;i<pc->address_list_size;i++) | ||
727 | { | ||
728 | ar = &pc->address_list[i]; | ||
729 | GNUNET_free_non_null (ar->result); | ||
730 | if (NULL != ar->atsc) | ||
731 | { | ||
732 | GNUNET_TRANSPORT_address_to_string_cancel (ar->atsc); | ||
733 | ar->atsc = NULL; | ||
734 | } | ||
735 | } | ||
736 | GNUNET_free_non_null (pc->address_list); | ||
737 | GNUNET_free (pc); | ||
652 | } | 738 | } |
653 | GPI_plugins_unload (); | 739 | GPI_plugins_unload (); |
654 | GNUNET_PEERINFO_disconnect (peerinfo); | 740 | if (NULL != peerinfo) |
655 | peerinfo = NULL; | 741 | { |
742 | GNUNET_PEERINFO_disconnect (peerinfo); | ||
743 | peerinfo = NULL; | ||
744 | } | ||
656 | } | 745 | } |
657 | 746 | ||
658 | 747 | ||
@@ -740,10 +829,9 @@ state_machine (void *cls, | |||
740 | { | 829 | { |
741 | get_info = GNUNET_NO; | 830 | get_info = GNUNET_NO; |
742 | GPI_plugins_load (cfg); | 831 | GPI_plugins_load (cfg); |
743 | GNUNET_PEERINFO_iterate (peerinfo, NULL, | 832 | pic = GNUNET_PEERINFO_iterate (peerinfo, NULL, |
744 | GNUNET_TIME_relative_multiply | 833 | GNUNET_TIME_UNIT_FOREVER_REL, |
745 | (GNUNET_TIME_UNIT_SECONDS, 5), &print_peer_info, | 834 | &print_peer_info, NULL); |
746 | NULL); | ||
747 | return; | 835 | return; |
748 | } | 836 | } |
749 | if (GNUNET_YES == get_self) | 837 | if (GNUNET_YES == get_self) |
@@ -770,7 +858,7 @@ state_machine (void *cls, | |||
770 | GNUNET_free (pkey); | 858 | GNUNET_free (pkey); |
771 | GPI_plugins_load (cfg); | 859 | GPI_plugins_load (cfg); |
772 | pic = GNUNET_PEERINFO_iterate (peerinfo, &my_peer_identity, | 860 | pic = GNUNET_PEERINFO_iterate (peerinfo, &my_peer_identity, |
773 | GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5), | 861 | GNUNET_TIME_UNIT_FOREVER_REL, |
774 | &print_my_uri, guc); | 862 | &print_my_uri, guc); |
775 | get_uri = GNUNET_NO; | 863 | get_uri = GNUNET_NO; |
776 | return; | 864 | return; |