aboutsummaryrefslogtreecommitdiff
path: root/src/ats-tool/gnunet-ats.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ats-tool/gnunet-ats.c')
-rw-r--r--src/ats-tool/gnunet-ats.c992
1 files changed, 0 insertions, 992 deletions
diff --git a/src/ats-tool/gnunet-ats.c b/src/ats-tool/gnunet-ats.c
deleted file mode 100644
index 169daa6f1..000000000
--- a/src/ats-tool/gnunet-ats.c
+++ /dev/null
@@ -1,992 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009--2015 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your 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 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file ats-tool/gnunet-ats.c
23 * @brief ATS command line tool
24 * @author Matthias Wachs
25 * @author Christian Grothoff
26 */
27#include "platform.h"
28#include "gnunet_util_lib.h"
29#include "gnunet_ats_service.h"
30#include "gnunet_transport_service.h"
31
32/**
33 * String to respresent unlimited
34 */
35#define UNLIMITED_STRING "unlimited"
36
37
38/**
39 * CLI Opt:
40 */
41static int opt_resolve_addresses_numeric;
42
43/**
44 * CLI Opt: Print verbose ATS information
45 */
46static int opt_verbose;
47
48/**
49 * CLI Option: List only addresses currently used (active)
50 */
51static int opt_list_used;
52
53/**
54 * CLI Option: List all addresses
55 */
56static int opt_list_all;
57
58/**
59 * CLI Option: set preference
60 */
61static int opt_set_pref;
62
63/**
64 * CLI Option: print quotas configured
65 */
66static int opt_print_quotas;
67
68/**
69 * CLI Option: Monitor addresses used
70 */
71static int opt_monitor;
72
73/**
74 * CLI Option: use specific peer
75 */
76static char *opt_pid_str;
77
78/**
79 * CLI Option: preference type to set
80 */
81static char *opt_type_str;
82
83/**
84 * CLI Option: preference value to set
85 */
86static unsigned int opt_pref_value;
87
88/**
89 * Final status code.
90 */
91static int ret;
92
93/**
94 * Number of results returned from service
95 */
96static int stat_results;
97
98/**
99 * State: all pending receive operations done?
100 */
101static int stat_receive_done;
102
103/**
104 * State: number of pending operations
105 */
106static int stat_pending;
107
108/**
109 * Which peer should we connect to?
110 */
111static char *cpid_str;
112
113/**
114 * ATS performance handle used
115 */
116static struct GNUNET_ATS_PerformanceHandle *ph;
117
118/**
119 * Our connectivity handle.
120 */
121static struct GNUNET_ATS_ConnectivityHandle *ats_ch;
122
123/**
124 * Handle for address suggestion request.
125 */
126static struct GNUNET_ATS_ConnectivitySuggestHandle *ats_sh;
127
128/**
129 * ATS address list handle used
130 */
131static struct GNUNET_ATS_AddressListHandle *alh;
132
133/**
134 * Configuration handle
135 */
136static struct GNUNET_CONFIGURATION_Handle *cfg;
137
138/**
139 * Shutdown task
140 */
141static struct GNUNET_SCHEDULER_Task *shutdown_task;
142
143/**
144 * Hashmap to store addresses
145 */
146static struct GNUNET_CONTAINER_MultiPeerMap *addresses;
147
148
149/**
150 * Structure used to remember all pending address resolutions.
151 * We keep address information in here while we talk to transport
152 * to map the address to a string.
153 */
154struct PendingResolutions
155{
156 /**
157 * Kept in a DLL.
158 */
159 struct PendingResolutions *next;
160
161 /**
162 * Kept in a DLL.
163 */
164 struct PendingResolutions *prev;
165
166 /**
167 * Copy of the address we are resolving.
168 */
169 struct GNUNET_HELLO_Address *address;
170
171 /**
172 * Handle to the transport request to convert the address
173 * to a string.
174 */
175 struct GNUNET_TRANSPORT_AddressToStringContext *tats_ctx;
176
177 /**
178 * Performance data.
179 */
180 struct GNUNET_ATS_Properties properties;
181
182 /**
183 * Amount of outbound bandwidth assigned by ATS.
184 */
185 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out;
186
187 /**
188 * Amount of inbound bandwidth assigned by ATS.
189 */
190 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in;
191
192 /**
193 * Is this an active address?
194 */
195 int active;
196};
197
198
199/**
200 * Information we keep for an address. Used to avoid
201 * printing the same data multiple times.
202 */
203struct ATSAddress
204{
205 /**
206 * Address information.
207 */
208 struct GNUNET_HELLO_Address *address;
209
210 /**
211 * Current outbound bandwidth.
212 */
213 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out;
214
215 /**
216 * Current inbound bandwidth.
217 */
218 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in;
219
220 /**
221 * Is this an active address?
222 */
223 int active;
224};
225
226
227/**
228 * Head of list of pending resolution requests.
229 */
230static struct PendingResolutions *head;
231
232/**
233 * Tail of list of pending resolution requests.
234 */
235static struct PendingResolutions *tail;
236
237
238/**
239 * Free address corresponding to a given peer.
240 *
241 * @param cls NULL
242 * @param key peer identity
243 * @param value the `struct ATSAddress *` to be freed
244 * @return #GNUNET_YES (always)
245 */
246static int
247free_addr_it (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
248{
249 struct ATSAddress *a = value;
250
251 GNUNET_assert (GNUNET_OK ==
252 GNUNET_CONTAINER_multipeermap_remove (addresses, key, value));
253 GNUNET_HELLO_address_free (a->address);
254 GNUNET_free (a);
255 return GNUNET_OK;
256}
257
258
259/**
260 * Task run on shutdown.
261 *
262 * @param cls NULL
263 */
264static void
265end (void *cls)
266{
267 struct PendingResolutions *pr;
268 struct PendingResolutions *next;
269 unsigned int pending;
270
271 if (NULL != alh)
272 {
273 GNUNET_ATS_performance_list_addresses_cancel (alh);
274 alh = NULL;
275 }
276
277 if (NULL != ph)
278 {
279 GNUNET_ATS_performance_done (ph);
280 ph = NULL;
281 }
282
283 pending = 0;
284 next = head;
285 while (NULL != (pr = next))
286 {
287 next = pr->next;
288 GNUNET_CONTAINER_DLL_remove (head, tail, pr);
289 GNUNET_TRANSPORT_address_to_string_cancel (pr->tats_ctx);
290 GNUNET_free (pr->address);
291 GNUNET_free (pr);
292 pending++;
293 }
294 GNUNET_CONTAINER_multipeermap_iterate (addresses, &free_addr_it, NULL);
295 GNUNET_CONTAINER_multipeermap_destroy (addresses);
296 addresses = NULL;
297
298 if (0 < pending)
299 fprintf (stdout, _ ("%u address resolutions had a timeout\n"), pending);
300 if (opt_list_used || opt_list_all)
301 fprintf (stdout,
302 _ ("ATS returned stat_results for %u addresses\n"),
303 stat_results);
304
305 if (NULL != ats_sh)
306 {
307 GNUNET_ATS_connectivity_suggest_cancel (ats_sh);
308 ats_sh = NULL;
309 }
310 if (NULL != ats_ch)
311 {
312 GNUNET_ATS_connectivity_done (ats_ch);
313 ats_ch = NULL;
314 }
315 ret = 0;
316}
317
318
319/**
320 * Function to call with a textual representation of an address. This
321 * function will be called several times with different possible
322 * textual representations, and a last time with @a address being NULL
323 * to signal the end of the iteration. Note that @a address NULL
324 * always is the last call, regardless of the value in @a res.
325 *
326 * @param cls closure, a `struct PendingResolutions *`
327 * @param address NULL on end of iteration,
328 * otherwise 0-terminated printable UTF-8 string,
329 * in particular an empty string if @a res is #GNUNET_NO
330 * @param res result of the address to string conversion:
331 * if #GNUNET_OK: conversion successful
332 * if #GNUNET_NO: address was invalid (or not supported)
333 * if #GNUNET_SYSERR: communication error (IPC error)
334 */
335static void
336transport_addr_to_str_cb (void *cls, const char *address, int res)
337{
338 struct PendingResolutions *pr = cls;
339
340 if (NULL == address)
341 {
342 /* We're done */
343 GNUNET_CONTAINER_DLL_remove (head, tail, pr);
344 GNUNET_free (pr->address);
345 GNUNET_free (pr);
346 stat_pending--;
347
348 if ((GNUNET_YES == stat_receive_done) && (0 == stat_pending))
349 {
350 /* All messages received and no resolutions pending*/
351 if (shutdown_task != NULL)
352 GNUNET_SCHEDULER_cancel (shutdown_task);
353 shutdown_task = GNUNET_SCHEDULER_add_now (&end, NULL);
354 }
355 return;
356 }
357 switch (res)
358 {
359 case GNUNET_SYSERR:
360 fprintf (
361 stderr,
362 "Failed to convert address for peer `%s' plugin `%s' length %u to string (communication error)\n",
363 GNUNET_i2s (&pr->address->peer),
364 pr->address->transport_name,
365 (unsigned int) pr->address->address_length);
366 return;
367
368 case GNUNET_NO:
369 fprintf (
370 stderr,
371 "Failed to convert address for peer `%s' plugin `%s' length %u to string (address invalid or not supported)\n",
372 GNUNET_i2s (&pr->address->peer),
373 pr->address->transport_name,
374 (unsigned int) pr->address->address_length);
375 return;
376
377 case GNUNET_OK:
378 /* continues below */
379 break;
380
381 default:
382 GNUNET_break (0);
383 return;
384 }
385
386 fprintf (
387 stdout,
388 _ (
389 "Peer `%s' plugin `%s', address `%s', `%s' bw out: %u Bytes/s, bw in %u Bytes/s, %s\n"),
390 GNUNET_i2s (&pr->address->peer),
391 pr->address->transport_name,
392 address,
393 GNUNET_NT_to_string (pr->properties.scope),
394 ntohl (pr->bandwidth_out.value__),
395 ntohl (pr->bandwidth_in.value__),
396 pr->active ? _ ("active ") : _ ("inactive "));
397}
398
399
400/**
401 * Closure for #find_address_it().
402 */
403struct AddressFindCtx
404{
405 /**
406 * Address we are looking for.
407 */
408 const struct GNUNET_HELLO_Address *src;
409
410 /**
411 * Where to write the `struct ATSAddress` if we found one that matches.
412 */
413 struct ATSAddress *res;
414};
415
416
417/**
418 * Find address corresponding to a given peer.
419 *
420 * @param cls the `struct AddressFindCtx *`
421 * @param key peer identity
422 * @param value the `struct ATSAddress *` for an existing address
423 * @return #GNUNET_NO if we found a match, #GNUNET_YES if not
424 */
425static int
426find_address_it (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
427{
428 struct AddressFindCtx *actx = cls;
429 struct ATSAddress *exist = value;
430
431 if (0 == GNUNET_HELLO_address_cmp (actx->src, exist->address))
432 {
433 actx->res = exist;
434 return GNUNET_NO;
435 }
436 return GNUNET_YES;
437}
438
439
440/**
441 * Signature of a function that is called with QoS information about an address.
442 *
443 * @param cls closure (NULL)
444 * @param address the address, NULL if ATS service was disconnected
445 * @param active #GNUNET_YES if this address is actively used
446 * to maintain a connection to a peer;
447 * #GNUNET_NO if the address is not actively used;
448 * #GNUNET_SYSERR if this address is no longer available for ATS
449 * @param bandwidth_out assigned outbound bandwidth for the connection
450 * @param bandwidth_in assigned inbound bandwidth for the connection
451 * @param prop performance data for the address (as far as known)
452 */
453static void
454ats_perf_mon_cb (void *cls,
455 const struct GNUNET_HELLO_Address *address,
456 int active,
457 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
458 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
459 const struct GNUNET_ATS_Properties *prop)
460{
461 struct PendingResolutions *pr;
462 struct PendingResolutions *cur;
463 struct PendingResolutions *next;
464
465 if (NULL == address)
466 {
467 /* ATS service temporarily disconnected, remove current state */
468 next = head;
469 for (cur = next; NULL != cur; cur = next)
470 {
471 next = cur->next;
472 GNUNET_CONTAINER_DLL_remove (head, tail, cur);
473 GNUNET_TRANSPORT_address_to_string_cancel (cur->tats_ctx);
474 GNUNET_HELLO_address_free (cur->address);
475 GNUNET_free (cur);
476 }
477 GNUNET_CONTAINER_multipeermap_iterate (addresses, &free_addr_it, NULL);
478 return;
479 }
480 if (GNUNET_SYSERR == active)
481 {
482 /* remove address */
483 struct AddressFindCtx actx;
484
485 actx.src = address;
486 actx.res = NULL;
487 GNUNET_CONTAINER_multipeermap_get_multiple (addresses,
488 &address->peer,
489 &find_address_it,
490 &actx);
491 if (NULL == actx.res)
492 {
493 GNUNET_break (0);
494 return;
495 }
496 GNUNET_break (GNUNET_OK ==
497 GNUNET_CONTAINER_multipeermap_remove (addresses,
498 &address->peer,
499 actx.res));
500 fprintf (stdout,
501 _ ("Removed address of peer `%s' with plugin `%s'\n"),
502 GNUNET_i2s (&address->peer),
503 actx.res->address->transport_name);
504 GNUNET_HELLO_address_free (actx.res);
505 return;
506 }
507
508 if (GNUNET_NO == opt_verbose)
509 {
510 struct AddressFindCtx actx;
511 struct ATSAddress *a;
512
513 actx.src = address;
514 actx.res = NULL;
515 GNUNET_CONTAINER_multipeermap_get_multiple (addresses,
516 &address->peer,
517 &find_address_it,
518 &actx);
519 if ((NULL != actx.res))
520 {
521 if ((bandwidth_in.value__ == actx.res->bandwidth_in.value__) &&
522 (bandwidth_out.value__ == actx.res->bandwidth_out.value__) &&
523 (active == actx.res->active))
524 {
525 return; /* Nothing to do here */
526 }
527 else
528 {
529 actx.res->bandwidth_in = bandwidth_in;
530 actx.res->bandwidth_out = bandwidth_out;
531 }
532 }
533 else
534 {
535 a = GNUNET_new (struct ATSAddress);
536
537 a->address = GNUNET_HELLO_address_copy (address);
538 a->bandwidth_in = bandwidth_in;
539 a->bandwidth_out = bandwidth_out;
540 a->active = active;
541 GNUNET_CONTAINER_multipeermap_put (
542 addresses,
543 &address->peer,
544 a,
545 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
546 }
547 }
548
549 pr = GNUNET_new (struct PendingResolutions);
550 pr->properties = *prop;
551 pr->address = GNUNET_HELLO_address_copy (address);
552 pr->bandwidth_in = bandwidth_in;
553 pr->bandwidth_out = bandwidth_out;
554 pr->active = active;
555 pr->tats_ctx = GNUNET_TRANSPORT_address_to_string (
556 cfg,
557 address,
558 opt_resolve_addresses_numeric,
559 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10),
560 &transport_addr_to_str_cb,
561 pr);
562 GNUNET_CONTAINER_DLL_insert (head, tail, pr);
563 stat_results++;
564 stat_pending++;
565}
566
567
568/**
569 * Signature of a function that is called with QoS information about an address.
570 *
571 * @param cls closure (NULL)
572 * @param address the address, NULL if ATS service was disconnected
573 * @param active is this address actively used to maintain a connection
574 to a peer
575 * @param bandwidth_out assigned outbound bandwidth for the connection
576 * @param bandwidth_in assigned inbound bandwidth for the connection
577 * @param prop performance data for the address (as far as known)
578 */
579static void
580ats_perf_cb (void *cls,
581 const struct GNUNET_HELLO_Address *address,
582 int active,
583 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
584 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
585 const struct GNUNET_ATS_Properties *prop)
586{
587 struct PendingResolutions *pr;
588
589 if (NULL == address)
590 {
591 /* All messages received */
592 stat_receive_done = GNUNET_YES;
593 alh = NULL;
594 if (0 == stat_pending)
595 {
596 /* All messages received and no resolutions pending*/
597 if (shutdown_task != NULL)
598 GNUNET_SCHEDULER_cancel (shutdown_task);
599 shutdown_task = GNUNET_SCHEDULER_add_now (&end, NULL);
600 }
601 return;
602 }
603
604 pr = GNUNET_new (struct PendingResolutions);
605 pr->properties = *prop;
606 pr->address = GNUNET_HELLO_address_copy (address);
607 pr->bandwidth_in = bandwidth_in;
608 pr->bandwidth_out = bandwidth_out;
609 pr->active = active;
610 pr->tats_ctx = GNUNET_TRANSPORT_address_to_string (
611 cfg,
612 address,
613 opt_resolve_addresses_numeric,
614 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10),
615 &transport_addr_to_str_cb,
616 pr);
617 GNUNET_CONTAINER_DLL_insert (head, tail, pr);
618 stat_results++;
619 stat_pending++;
620}
621
622
623/**
624 * Print information about the quotas configured for the various
625 * network scopes.
626 *
627 * @param cfg configuration to obtain quota information from
628 * @return total number of ATS network types known
629 */
630static unsigned int
631print_quotas (const struct GNUNET_CONFIGURATION_Handle *cfg)
632{
633 char *entry_in = NULL;
634 char *entry_out = NULL;
635 char *quota_out_str;
636 char *quota_in_str;
637 unsigned long long int quota_out;
638 unsigned long long int quota_in;
639 int c;
640
641 for (c = 0; (c < GNUNET_NT_COUNT); c++)
642 {
643 GNUNET_asprintf (&entry_out, "%s_QUOTA_OUT", GNUNET_NT_to_string (c));
644 GNUNET_asprintf (&entry_in, "%s_QUOTA_IN", GNUNET_NT_to_string (c));
645
646 /* quota out */
647 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg,
648 "ats",
649 entry_out,
650 &quota_out_str))
651 {
652 if ((0 == strcmp (quota_out_str, UNLIMITED_STRING)) ||
653 (GNUNET_SYSERR ==
654 GNUNET_STRINGS_fancy_size_to_bytes (quota_out_str, &quota_out)))
655 quota_out = UINT32_MAX;
656
657 GNUNET_free (quota_out_str);
658 GNUNET_asprintf (&quota_out_str, "%llu", quota_out);
659 }
660 else
661 {
662 fprintf (stderr,
663 "Outbound quota for network `%11s' not configured!\n",
664 GNUNET_NT_to_string (c));
665 GNUNET_asprintf (&quota_out_str, "-");
666 }
667 GNUNET_free (entry_out);
668
669 /* quota in */
670 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg,
671 "ats",
672 entry_in,
673 &quota_in_str))
674 {
675 if ((0 == strcmp (quota_in_str, UNLIMITED_STRING)) ||
676 (GNUNET_SYSERR ==
677 GNUNET_STRINGS_fancy_size_to_bytes (quota_in_str, &quota_in)))
678 quota_in = UINT32_MAX;
679 GNUNET_free (quota_in_str);
680 GNUNET_asprintf (&quota_in_str, "%llu", quota_in);
681 }
682 else
683 {
684 fprintf (stderr,
685 "Inbound quota for network `%11s' not configured!\n",
686 GNUNET_NT_to_string (c));
687 GNUNET_asprintf (&quota_in_str, "-");
688 }
689 GNUNET_free (entry_in);
690
691 fprintf (stdout,
692 _ ("Quota for network `%11s' (in/out): %10s / %10s\n"),
693 GNUNET_NT_to_string (c),
694 quota_in_str,
695 quota_out_str);
696 GNUNET_free (quota_out_str);
697 GNUNET_free (quota_in_str);
698 }
699 return GNUNET_NT_COUNT;
700}
701
702
703/**
704 * Main function that will be run by the scheduler.
705 *
706 * @param cls closure
707 * @param args remaining command-line arguments
708 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
709 * @param my_cfg configuration
710 */
711static void
712run (void *cls,
713 char *const *args,
714 const char *cfgfile,
715 const struct GNUNET_CONFIGURATION_Handle *my_cfg)
716{
717 struct GNUNET_PeerIdentity pid;
718 struct GNUNET_PeerIdentity cpid;
719 unsigned int c;
720 unsigned int type;
721
722 cfg = (struct GNUNET_CONFIGURATION_Handle *) my_cfg;
723 addresses = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO);
724 stat_results = 0;
725
726 c = 0;
727 if (NULL != opt_pid_str)
728 {
729 if (GNUNET_OK !=
730 GNUNET_CRYPTO_eddsa_public_key_from_string (opt_pid_str,
731 strlen (opt_pid_str),
732 &pid.public_key))
733 {
734 fprintf (stderr, _ ("Failed to parse peer identity `%s'\n"), opt_pid_str);
735 return;
736 }
737 }
738 if (NULL != cpid_str)
739 {
740 if (GNUNET_OK !=
741 GNUNET_CRYPTO_eddsa_public_key_from_string (cpid_str,
742 strlen (cpid_str),
743 &cpid.public_key))
744 {
745 fprintf (stderr, _ ("Failed to parse peer identity `%s'\n"), cpid_str);
746 return;
747 }
748 c++;
749 }
750
751 c += opt_list_all + opt_list_used + opt_monitor + opt_set_pref;
752
753 if (1 < c)
754 {
755 fprintf (stderr,
756 _ ("Please select one operation: %s or %s or %s or %s or %s\n"),
757 "--used",
758 "--all",
759 "--monitor",
760 "--preference",
761 "--quotas");
762 return;
763 }
764 if (0 == c)
765 opt_list_used = GNUNET_YES; /* set default */
766 if (opt_print_quotas)
767 {
768 ret = print_quotas (cfg);
769 return;
770 }
771 if (opt_list_all)
772 {
773 ph = GNUNET_ATS_performance_init (cfg, NULL, NULL);
774 if (NULL == ph)
775 {
776 fprintf (stderr, "%s", _ ("Cannot connect to ATS service, exiting...\n"));
777 return;
778 }
779 alh = GNUNET_ATS_performance_list_addresses (ph,
780 (NULL == opt_pid_str) ? NULL
781 : &pid,
782 GNUNET_YES,
783 &ats_perf_cb,
784 NULL);
785 if (NULL == alh)
786 {
787 fprintf (stderr,
788 "%s",
789 _ ("Cannot issue request to ATS service, exiting...\n"));
790 shutdown_task = GNUNET_SCHEDULER_add_now (&end, NULL);
791 return;
792 }
793 shutdown_task = GNUNET_SCHEDULER_add_shutdown (&end, NULL);
794 return;
795 }
796 if (opt_list_used)
797 {
798 ph = GNUNET_ATS_performance_init (cfg, NULL, NULL);
799 if (NULL == ph)
800 fprintf (stderr, "%s", _ ("Cannot connect to ATS service, exiting...\n"));
801
802 alh = GNUNET_ATS_performance_list_addresses (ph,
803 (NULL == opt_pid_str) ? NULL
804 : &pid,
805 GNUNET_NO,
806 &ats_perf_cb,
807 NULL);
808 if (NULL == alh)
809 {
810 fprintf (stderr,
811 "%s",
812 _ ("Cannot issue request to ATS service, exiting...\n"));
813 shutdown_task = GNUNET_SCHEDULER_add_now (&end, NULL);
814 return;
815 }
816 shutdown_task = GNUNET_SCHEDULER_add_shutdown (&end, NULL);
817 return;
818 }
819 if (opt_monitor)
820 {
821 ph = GNUNET_ATS_performance_init (cfg, &ats_perf_mon_cb, NULL);
822 shutdown_task = GNUNET_SCHEDULER_add_shutdown (&end, NULL);
823 if (NULL == ph)
824 {
825 fprintf (stderr, "%s", _ ("Cannot connect to ATS service, exiting...\n"));
826 GNUNET_SCHEDULER_shutdown ();
827 }
828 return;
829 }
830 if (opt_set_pref)
831 {
832 if (NULL == opt_type_str)
833 {
834 fprintf (stderr, "%s", _ ("No preference type given!\n"));
835 return;
836 }
837 if (NULL == opt_pid_str)
838 {
839 fprintf (stderr, "%s", _ ("No peer given!\n"));
840 return;
841 }
842
843 for (c = 0; c < strlen (opt_type_str); c++)
844 {
845 if (isupper ((unsigned char) opt_type_str[c]))
846 opt_type_str[c] = tolower ((unsigned char) opt_type_str[c]);
847 }
848
849 if (0 == strcasecmp ("latency", opt_type_str))
850 type = GNUNET_ATS_PREFERENCE_LATENCY;
851 else if (0 == strcasecmp ("bandwidth", opt_type_str))
852 type = GNUNET_ATS_PREFERENCE_BANDWIDTH;
853 else
854 {
855 fprintf (stderr, "%s", _ ("Valid type required\n"));
856 return;
857 }
858
859 /* set */
860 ph = GNUNET_ATS_performance_init (cfg, NULL, NULL);
861 if (NULL == ph)
862 fprintf (stderr, "%s", _ ("Cannot connect to ATS service, exiting...\n"));
863
864 GNUNET_ATS_performance_change_preference (ph,
865 &pid,
866 type,
867 (double) opt_pref_value,
868 GNUNET_ATS_PREFERENCE_END);
869
870 shutdown_task =
871 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &end, NULL);
872 return;
873 }
874 if (NULL != cpid_str)
875 {
876 ats_ch = GNUNET_ATS_connectivity_init (cfg);
877 ats_sh = GNUNET_ATS_connectivity_suggest (ats_ch, &cpid, 1000);
878 shutdown_task =
879 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &end, NULL);
880 return;
881 }
882 ret = 1;
883}
884
885
886/**
887 * The main function.
888 *
889 * @param argc number of arguments from the command line
890 * @param argv command line arguments
891 * @return 0 ok, 1 on error
892 */
893int
894main (int argc, char *const *argv)
895{
896 int res;
897
898 opt_resolve_addresses_numeric = GNUNET_NO;
899 opt_monitor = GNUNET_NO;
900 opt_list_all = GNUNET_NO;
901 opt_list_used = GNUNET_NO;
902 opt_set_pref = GNUNET_NO;
903 stat_pending = 0;
904 stat_receive_done = GNUNET_NO;
905 opt_type_str = NULL;
906
907 struct GNUNET_GETOPT_CommandLineOption options[] =
908 { GNUNET_GETOPT_option_flag ('u',
909 "used",
910 gettext_noop (
911 "get list of active addresses currently used"),
912 &opt_list_used),
913 GNUNET_GETOPT_option_flag ('a',
914 "all",
915 gettext_noop (
916 "get list of all active addresses"),
917 &opt_list_all),
918
919 GNUNET_GETOPT_option_string ('C',
920 "connect",
921 NULL,
922 gettext_noop ("connect to PEER"),
923 &cpid_str),
924 GNUNET_GETOPT_option_flag ('n',
925 "numeric",
926 gettext_noop (
927 "do not resolve IP addresses to hostnames"),
928 &opt_resolve_addresses_numeric),
929
930 GNUNET_GETOPT_option_flag ('m',
931 "monitor",
932 gettext_noop ("monitor mode"),
933 &opt_monitor),
934
935 GNUNET_GETOPT_option_flag ('p',
936 "preference",
937 gettext_noop (
938 "set preference for the given peer"),
939 &opt_set_pref),
940
941 GNUNET_GETOPT_option_flag ('q',
942 "quotas",
943 gettext_noop ("print all configured quotas"),
944 &opt_print_quotas),
945 GNUNET_GETOPT_option_string ('i',
946 "id",
947 "TYPE",
948 gettext_noop ("peer id"),
949 &opt_pid_str),
950
951 GNUNET_GETOPT_option_string ('t',
952 "type",
953 "TYPE",
954 gettext_noop (
955 "preference type to set: latency | bandwidth"),
956 &opt_type_str),
957
958 GNUNET_GETOPT_option_uint ('k',
959 "value",
960 "VALUE",
961 gettext_noop ("preference value"),
962 &opt_pref_value),
963
964 GNUNET_GETOPT_option_flag (
965 'V',
966 "verbose",
967 gettext_noop ("verbose output (include ATS address properties)"),
968 &opt_verbose),
969 GNUNET_GETOPT_OPTION_END };
970
971 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
972 return 2;
973
974 res = GNUNET_PROGRAM_run (argc,
975 argv,
976 "gnunet-ats",
977 gettext_noop ("Print information about ATS state"),
978 options,
979 &run,
980 NULL);
981 GNUNET_free (opt_pid_str);
982 GNUNET_free (opt_type_str);
983 GNUNET_free_nz ((void *) argv);
984
985 if (GNUNET_OK == res)
986 return ret;
987 else
988 return 1;
989}
990
991
992/* end of gnunet-ats.c */