diff options
-rw-r--r-- | doc/man/gnunet-transport.1 | 7 | ||||
-rw-r--r-- | src/transport/gnunet-transport.c | 217 |
2 files changed, 209 insertions, 15 deletions
diff --git a/doc/man/gnunet-transport.1 b/doc/man/gnunet-transport.1 index 63c3163b2..228ebae87 100644 --- a/doc/man/gnunet-transport.1 +++ b/doc/man/gnunet-transport.1 | |||
@@ -1,4 +1,4 @@ | |||
1 | .TH gnunet\-transport "1" "26 Oct 2011" "GNUnet" | 1 | .TH gnunet\-transport "1" "7 Nov 2014" "GNUnet" |
2 | .SH NAME | 2 | .SH NAME |
3 | gnunet\-transport \- measure and control the transport subsystem | 3 | gnunet\-transport \- measure and control the transport subsystem |
4 | 4 | ||
@@ -39,7 +39,10 @@ configure logging to write logs to LOGFILE | |||
39 | print information about our current connections (continuously) | 39 | print information about our current connections (continuously) |
40 | .TP | 40 | .TP |
41 | \fB\-p \fIPEER\fR, \fB\-\-peer=PEER\fR | 41 | \fB\-p \fIPEER\fR, \fB\-\-peer=PEER\fR |
42 | the peer identity | 42 | the peer identity to connect to or monitor |
43 | .TP | ||
44 | \fB\-P, \fB\-\-plugins\fR | ||
45 | monitor session state of transport plugins | ||
43 | .TP | 46 | .TP |
44 | \fB\-s\fR, \fB\-\-send\fR | 47 | \fB\-s\fR, \fB\-\-send\fR |
45 | transmit (dummy) traffic as quickly as possible to the peer specified with the \-p option. The rate will still be limited by the quota(s) determined by the peers (ATS subsystem). Will run until CTRL\-C is pressed or until the connection to the other peer is disrupted. | 48 | transmit (dummy) traffic as quickly as possible to the peer specified with the \-p option. The rate will still be limited by the quota(s) determined by the peers (ATS subsystem). Will run until CTRL\-C is pressed or until the connection to the other peer is disrupted. |
diff --git a/src/transport/gnunet-transport.c b/src/transport/gnunet-transport.c index 7f1c056ea..cf1609a5a 100644 --- a/src/transport/gnunet-transport.c +++ b/src/transport/gnunet-transport.c | |||
@@ -336,6 +336,11 @@ static int monitor_connections; | |||
336 | static int monitor_validation; | 336 | static int monitor_validation; |
337 | 337 | ||
338 | /** | 338 | /** |
339 | * Option -P. | ||
340 | */ | ||
341 | static int monitor_plugins; | ||
342 | |||
343 | /** | ||
339 | * Option -C. | 344 | * Option -C. |
340 | */ | 345 | */ |
341 | static int try_connect; | 346 | static int try_connect; |
@@ -386,16 +391,26 @@ static struct GNUNET_TRANSPORT_TransmitHandle *th; | |||
386 | static struct GNUNET_CONTAINER_MultiPeerMap *monitored_peers; | 391 | static struct GNUNET_CONTAINER_MultiPeerMap *monitored_peers; |
387 | 392 | ||
388 | /** | 393 | /** |
389 | * | 394 | * Map storing information about monitored plugins's sessions. |
395 | */ | ||
396 | static struct GNUNET_CONTAINER_MultiPeerMap *monitored_plugins; | ||
397 | |||
398 | /** | ||
399 | * Handle if we are monitoring peers at the transport level. | ||
390 | */ | 400 | */ |
391 | static struct GNUNET_TRANSPORT_PeerMonitoringContext *pic; | 401 | static struct GNUNET_TRANSPORT_PeerMonitoringContext *pic; |
392 | 402 | ||
393 | /** | 403 | /** |
394 | * | 404 | * Handle if we are monitoring transport validation activity. |
395 | */ | 405 | */ |
396 | static struct GNUNET_TRANSPORT_ValidationMonitoringContext *vic; | 406 | static struct GNUNET_TRANSPORT_ValidationMonitoringContext *vic; |
397 | 407 | ||
398 | /** | 408 | /** |
409 | * Handle if we are monitoring plugin session activity. | ||
410 | */ | ||
411 | static struct GNUNET_TRANSPORT_PluginMonitor *pm; | ||
412 | |||
413 | /** | ||
399 | * Identity of the peer we transmit to / connect to. | 414 | * Identity of the peer we transmit to / connect to. |
400 | * (equivalent to 'cpid' string). | 415 | * (equivalent to 'cpid' string). |
401 | */ | 416 | */ |
@@ -462,6 +477,14 @@ static struct PeerResolutionContext *rc_head; | |||
462 | static struct PeerResolutionContext *rc_tail; | 477 | static struct PeerResolutionContext *rc_tail; |
463 | 478 | ||
464 | 479 | ||
480 | /** | ||
481 | * Function called to release data stored in the #monitored_peers map. | ||
482 | * | ||
483 | * @param cls unused | ||
484 | * @param key the peer identity | ||
485 | * @param value a `struct MonitoredPeer` to release | ||
486 | * @return #GNUNET_OK (continue to iterate) | ||
487 | */ | ||
465 | static int | 488 | static int |
466 | destroy_it (void *cls, | 489 | destroy_it (void *cls, |
467 | const struct GNUNET_PeerIdentity *key, | 490 | const struct GNUNET_PeerIdentity *key, |
@@ -515,6 +538,11 @@ shutdown_task (void *cls, | |||
515 | GNUNET_TRANSPORT_monitor_validation_entries_cancel (vic); | 538 | GNUNET_TRANSPORT_monitor_validation_entries_cancel (vic); |
516 | vic = NULL; | 539 | vic = NULL; |
517 | } | 540 | } |
541 | if (NULL != pm) | ||
542 | { | ||
543 | GNUNET_TRANSPORT_monitor_plugins_cancel (pm); | ||
544 | pm = NULL; | ||
545 | } | ||
518 | 546 | ||
519 | next = vc_head; | 547 | next = vc_head; |
520 | for (cur = next; NULL != cur; cur = next) | 548 | for (cur = next; NULL != cur; cur = next) |
@@ -563,6 +591,13 @@ shutdown_task (void *cls, | |||
563 | GNUNET_CONTAINER_multipeermap_destroy (monitored_peers); | 591 | GNUNET_CONTAINER_multipeermap_destroy (monitored_peers); |
564 | monitored_peers = NULL; | 592 | monitored_peers = NULL; |
565 | } | 593 | } |
594 | if (NULL != monitored_plugins) | ||
595 | { | ||
596 | GNUNET_break (0 == | ||
597 | GNUNET_CONTAINER_multipeermap_size (monitored_plugins)); | ||
598 | GNUNET_CONTAINER_multipeermap_destroy (monitored_plugins); | ||
599 | monitored_plugins = NULL; | ||
600 | } | ||
566 | } | 601 | } |
567 | 602 | ||
568 | 603 | ||
@@ -1487,6 +1522,147 @@ process_peer_iteration_cb (void *cls, | |||
1487 | 1522 | ||
1488 | 1523 | ||
1489 | /** | 1524 | /** |
1525 | * Context for address resolution by #plugin_monitoring_cb(). | ||
1526 | */ | ||
1527 | struct PluginMonitorAddress | ||
1528 | { | ||
1529 | |||
1530 | /** | ||
1531 | * Ongoing resolution request. | ||
1532 | */ | ||
1533 | struct GNUNET_TRANSPORT_AddressToStringContext *asc; | ||
1534 | |||
1535 | /** | ||
1536 | * Resolved address as string. | ||
1537 | */ | ||
1538 | char *str; | ||
1539 | }; | ||
1540 | |||
1541 | |||
1542 | /** | ||
1543 | * Function called with a textual representation of an address. This | ||
1544 | * function will be called several times with different possible | ||
1545 | * textual representations, and a last time with @a address being NULL | ||
1546 | * to signal the end of the iteration. Note that @a address NULL | ||
1547 | * always is the last call, regardless of the value in @a res. | ||
1548 | * | ||
1549 | * @param cls closure | ||
1550 | * @param address NULL on end of iteration, | ||
1551 | * otherwise 0-terminated printable UTF-8 string, | ||
1552 | * in particular an empty string if @a res is #GNUNET_NO | ||
1553 | * @param res result of the address to string conversion: | ||
1554 | * if #GNUNET_OK: conversion successful | ||
1555 | * if #GNUNET_NO: address was invalid (or not supported) | ||
1556 | * if #GNUNET_SYSERR: communication error (IPC error) | ||
1557 | */ | ||
1558 | static void | ||
1559 | address_cb (void *cls, | ||
1560 | const char *address, | ||
1561 | int res) | ||
1562 | { | ||
1563 | struct PluginMonitorAddress *addr = cls; | ||
1564 | |||
1565 | if (NULL == address) | ||
1566 | { | ||
1567 | addr->asc = NULL; | ||
1568 | return; | ||
1569 | } | ||
1570 | if (NULL != addr->str) | ||
1571 | return; | ||
1572 | addr->str = GNUNET_strdup (address); | ||
1573 | } | ||
1574 | |||
1575 | |||
1576 | /** | ||
1577 | * Function called by the plugin with information about the | ||
1578 | * current sessions managed by the plugin (for monitoring). | ||
1579 | * | ||
1580 | * @param cls closure (NULL) | ||
1581 | * @param session session handle this information is about, | ||
1582 | * NULL to indicate that we are "in sync" (initial | ||
1583 | * iteration complete) | ||
1584 | * @param session_ctx storage location where the application | ||
1585 | * can store data; will point to NULL on #GNUNET_TRANSPORT_SS_INIT, | ||
1586 | * and must be reset to NULL on #GNUNET_TRANSPORT_SS_DONE | ||
1587 | * @param info information about the state of the session, | ||
1588 | * NULL if @a session is also NULL and we are | ||
1589 | * merely signalling that the initial iteration is over; | ||
1590 | * NULL with @a session being non-NULL if the monitor | ||
1591 | * was being cancelled while sessions were active | ||
1592 | */ | ||
1593 | static void | ||
1594 | plugin_monitoring_cb (void *cls, | ||
1595 | struct GNUNET_TRANSPORT_PluginSession *session, | ||
1596 | void **session_ctx, | ||
1597 | const struct GNUNET_TRANSPORT_SessionInfo *info) | ||
1598 | { | ||
1599 | const char *state; | ||
1600 | struct PluginMonitorAddress *addr; | ||
1601 | |||
1602 | if ( (NULL != cpid) && | ||
1603 | (0 != memcmp (&info->address->peer, | ||
1604 | cpid, | ||
1605 | sizeof (struct GNUNET_PeerIdentity))) ) | ||
1606 | return; /* filtered */ | ||
1607 | addr = *session_ctx; | ||
1608 | if (NULL == addr) | ||
1609 | { | ||
1610 | addr = GNUNET_new (struct PluginMonitorAddress); | ||
1611 | addr->asc = GNUNET_TRANSPORT_address_to_string (cfg, | ||
1612 | info->address, | ||
1613 | GNUNET_NO, | ||
1614 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
1615 | &address_cb, | ||
1616 | addr); | ||
1617 | *session_ctx = addr; | ||
1618 | } | ||
1619 | switch (info->state) | ||
1620 | { | ||
1621 | case GNUNET_TRANSPORT_SS_INIT: | ||
1622 | state = "INIT"; | ||
1623 | break; | ||
1624 | case GNUNET_TRANSPORT_SS_HANDSHAKE: | ||
1625 | state = "HANDSHAKE"; | ||
1626 | break; | ||
1627 | case GNUNET_TRANSPORT_SS_UP: | ||
1628 | state = "UP"; | ||
1629 | break; | ||
1630 | case GNUNET_TRANSPORT_SS_UPDATE: | ||
1631 | state = "UPDATE"; | ||
1632 | break; | ||
1633 | case GNUNET_TRANSPORT_SS_DONE: | ||
1634 | state = "DONE"; | ||
1635 | break; | ||
1636 | default: | ||
1637 | state = "UNKNOWN"; | ||
1638 | break; | ||
1639 | } | ||
1640 | fprintf (stdout, | ||
1641 | "%s: %s %s (# %u/%u b) blocked until %s timeout in %s [%s]\n", | ||
1642 | GNUNET_i2s (&info->address->peer), | ||
1643 | addr->str, | ||
1644 | (info->is_inbound == GNUNET_YES) ? "<-" : ((info->is_inbound == GNUNET_NO) ? "->" : "<>"), | ||
1645 | info->num_msg_pending, | ||
1646 | info->num_bytes_pending, | ||
1647 | GNUNET_STRINGS_absolute_time_to_string (info->receive_delay), | ||
1648 | GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_remaining (info->session_timeout), | ||
1649 | GNUNET_YES), | ||
1650 | state); | ||
1651 | if (GNUNET_TRANSPORT_SS_DONE == info->state) | ||
1652 | { | ||
1653 | if (NULL != addr->asc) | ||
1654 | { | ||
1655 | GNUNET_TRANSPORT_address_to_string_cancel (addr->asc); | ||
1656 | addr->asc = NULL; | ||
1657 | } | ||
1658 | GNUNET_free_non_null (addr->str); | ||
1659 | GNUNET_free (addr); | ||
1660 | *session_ctx = NULL; | ||
1661 | } | ||
1662 | } | ||
1663 | |||
1664 | |||
1665 | /** | ||
1490 | * Function called with information about a peers | 1666 | * Function called with information about a peers |
1491 | * | 1667 | * |
1492 | * @param cls closure | 1668 | * @param cls closure |
@@ -1650,22 +1826,22 @@ testservice_task (void *cls, int result) | |||
1650 | 1826 | ||
1651 | counter = benchmark_send + benchmark_receive + iterate_connections | 1827 | counter = benchmark_send + benchmark_receive + iterate_connections |
1652 | + monitor_connections + monitor_connects + try_connect + try_disconnect + | 1828 | + monitor_connections + monitor_connects + try_connect + try_disconnect + |
1653 | + iterate_validation + monitor_validation; | 1829 | + iterate_validation + monitor_validation + monitor_plugins; |
1654 | 1830 | ||
1655 | if (1 < counter) | 1831 | if (1 < counter) |
1656 | { | 1832 | { |
1657 | FPRINTF (stderr, | 1833 | FPRINTF (stderr, |
1658 | _("Multiple operations given. Please choose only one operation: %s, %s, %s, %s, %s, %s\n"), | 1834 | _("Multiple operations given. Please choose only one operation: %s, %s, %s, %s, %s, %s %s\n"), |
1659 | "connect", "benchmark send", "benchmark receive", "information", | 1835 | "connect", "benchmark send", "benchmark receive", "information", |
1660 | "monitor", "events"); | 1836 | "monitor", "events", "plugins"); |
1661 | return; | 1837 | return; |
1662 | } | 1838 | } |
1663 | if (0 == counter) | 1839 | if (0 == counter) |
1664 | { | 1840 | { |
1665 | FPRINTF (stderr, | 1841 | FPRINTF (stderr, |
1666 | _("No operation given. Please choose one operation: %s, %s, %s, %s, %s, %s\n"), | 1842 | _("No operation given. Please choose one operation: %s, %s, %s, %s, %s, %s, %s\n"), |
1667 | "connect", "benchmark send", "benchmark receive", "information", | 1843 | "connect", "benchmark send", "benchmark receive", "information", |
1668 | "monitor", "events"); | 1844 | "monitor", "events", "plugins"); |
1669 | return; | 1845 | return; |
1670 | } | 1846 | } |
1671 | 1847 | ||
@@ -1738,16 +1914,20 @@ testservice_task (void *cls, int result) | |||
1738 | ret = 1; | 1914 | ret = 1; |
1739 | return; | 1915 | return; |
1740 | } | 1916 | } |
1741 | handle = GNUNET_TRANSPORT_connect (cfg, NULL, NULL, ¬ify_receive, | 1917 | handle = GNUNET_TRANSPORT_connect (cfg, NULL, NULL, |
1742 | ¬ify_connect, ¬ify_disconnect); | 1918 | ¬ify_receive, |
1919 | ¬ify_connect, | ||
1920 | ¬ify_disconnect); | ||
1743 | if (NULL == handle) | 1921 | if (NULL == handle) |
1744 | { | 1922 | { |
1745 | FPRINTF (stderr, "%s", _("Failed to connect to transport service\n")); | 1923 | FPRINTF (stderr, "%s", _("Failed to connect to transport service\n")); |
1746 | ret = 1; | 1924 | ret = 1; |
1747 | return; | 1925 | return; |
1748 | } | 1926 | } |
1749 | tc_handle = GNUNET_TRANSPORT_try_connect (handle, &pid, try_connect_cb, | 1927 | tc_handle = GNUNET_TRANSPORT_try_connect (handle, |
1750 | NULL); | 1928 | &pid, |
1929 | &try_connect_cb, | ||
1930 | NULL); | ||
1751 | if (NULL == tc_handle) | 1931 | if (NULL == tc_handle) |
1752 | { | 1932 | { |
1753 | FPRINTF (stderr, "%s", | 1933 | FPRINTF (stderr, "%s", |
@@ -1756,8 +1936,9 @@ testservice_task (void *cls, int result) | |||
1756 | return; | 1936 | return; |
1757 | } | 1937 | } |
1758 | start_time = GNUNET_TIME_absolute_get (); | 1938 | start_time = GNUNET_TIME_absolute_get (); |
1759 | op_timeout = GNUNET_SCHEDULER_add_delayed (OP_TIMEOUT, &operation_timeout, | 1939 | op_timeout = GNUNET_SCHEDULER_add_delayed (OP_TIMEOUT, |
1760 | NULL); | 1940 | &operation_timeout, |
1941 | NULL); | ||
1761 | } | 1942 | } |
1762 | else if (benchmark_receive) /* -b: Benchmark receiving */ | 1943 | else if (benchmark_receive) /* -b: Benchmark receiving */ |
1763 | { | 1944 | { |
@@ -1790,6 +1971,13 @@ testservice_task (void *cls, int result) | |||
1790 | GNUNET_NO, TIMEOUT, | 1971 | GNUNET_NO, TIMEOUT, |
1791 | &process_peer_monitoring_cb, (void *) cfg); | 1972 | &process_peer_monitoring_cb, (void *) cfg); |
1792 | } | 1973 | } |
1974 | else if (monitor_plugins) /* -P: List information about plugins continuously */ | ||
1975 | { | ||
1976 | monitored_plugins = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO); | ||
1977 | pm = GNUNET_TRANSPORT_monitor_plugins (cfg, | ||
1978 | &plugin_monitoring_cb, | ||
1979 | NULL); | ||
1980 | } | ||
1793 | else if (iterate_validation) /* -d: Print information about validations */ | 1981 | else if (iterate_validation) /* -d: Print information about validations */ |
1794 | { | 1982 | { |
1795 | vic = GNUNET_TRANSPORT_monitor_validation_entries (cfg, | 1983 | vic = GNUNET_TRANSPORT_monitor_validation_entries (cfg, |
@@ -1894,6 +2082,9 @@ main (int argc, char * const *argv) | |||
1894 | { 'p', "peer", "PEER", | 2082 | { 'p', "peer", "PEER", |
1895 | gettext_noop ("peer identity"), 1, &GNUNET_GETOPT_set_string, | 2083 | gettext_noop ("peer identity"), 1, &GNUNET_GETOPT_set_string, |
1896 | &cpid }, | 2084 | &cpid }, |
2085 | { 'P', "plugins", NULL, | ||
2086 | gettext_noop ("monitor plugin sessions"), 1, &GNUNET_GETOPT_set_one, | ||
2087 | &monitor_plugins }, | ||
1897 | { 's', "send", NULL, gettext_noop | 2088 | { 's', "send", NULL, gettext_noop |
1898 | ("send data for benchmarking to the other peer (until CTRL-C)"), 0, | 2089 | ("send data for benchmarking to the other peer (until CTRL-C)"), 0, |
1899 | &GNUNET_GETOPT_set_one, &benchmark_send }, | 2090 | &GNUNET_GETOPT_set_one, &benchmark_send }, |