aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2014-11-07 17:43:28 +0000
committerChristian Grothoff <christian@grothoff.org>2014-11-07 17:43:28 +0000
commit91b9ba2fc36c1919e11d515d790bae68860653db (patch)
treea450aefca76bc26e759f43c7f49c4a0a08ab1d3b /src
parent0c89b2a16eae49cb23635f6d6c0f13da070c5c66 (diff)
downloadgnunet-91b9ba2fc36c1919e11d515d790bae68860653db.tar.gz
gnunet-91b9ba2fc36c1919e11d515d790bae68860653db.zip
implement transport plugin session monitoring support in gnunet-transport (#3452)
Diffstat (limited to 'src')
-rw-r--r--src/transport/gnunet-transport.c217
1 files changed, 204 insertions, 13 deletions
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;
336static int monitor_validation; 336static int monitor_validation;
337 337
338/** 338/**
339 * Option -P.
340 */
341static int monitor_plugins;
342
343/**
339 * Option -C. 344 * Option -C.
340 */ 345 */
341static int try_connect; 346static int try_connect;
@@ -386,16 +391,26 @@ static struct GNUNET_TRANSPORT_TransmitHandle *th;
386static struct GNUNET_CONTAINER_MultiPeerMap *monitored_peers; 391static struct GNUNET_CONTAINER_MultiPeerMap *monitored_peers;
387 392
388/** 393/**
389 * 394 * Map storing information about monitored plugins's sessions.
395 */
396static struct GNUNET_CONTAINER_MultiPeerMap *monitored_plugins;
397
398/**
399 * Handle if we are monitoring peers at the transport level.
390 */ 400 */
391static struct GNUNET_TRANSPORT_PeerMonitoringContext *pic; 401static struct GNUNET_TRANSPORT_PeerMonitoringContext *pic;
392 402
393/** 403/**
394 * 404 * Handle if we are monitoring transport validation activity.
395 */ 405 */
396static struct GNUNET_TRANSPORT_ValidationMonitoringContext *vic; 406static struct GNUNET_TRANSPORT_ValidationMonitoringContext *vic;
397 407
398/** 408/**
409 * Handle if we are monitoring plugin session activity.
410 */
411static 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;
462static struct PeerResolutionContext *rc_tail; 477static 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 */
465static int 488static int
466destroy_it (void *cls, 489destroy_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 */
1527struct 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 */
1558static void
1559address_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 */
1593static void
1594plugin_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, &notify_receive, 1917 handle = GNUNET_TRANSPORT_connect (cfg, NULL, NULL,
1742 &notify_connect, &notify_disconnect); 1918 &notify_receive,
1919 &notify_connect,
1920 &notify_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 },