+++ /dev/null
-/*
- This file is part of GNUnet.
- (C) 2009, 2010, 2013 Christian Grothoff (and other contributing authors)
-
- GNUnet is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-/**
- * @file integration-tests/connection_watchdog.c
- * @brief tool to monitor core and transport connections for consistency
- * @author Matthias Wachs
- */
-#include "platform.h"
-#include "gnunet_util_lib.h"
-#include "gnunet_constants.h"
-#include "gnunet_arm_service.h"
-#include "gnunet_core_service.h"
-#include "gnunet_transport_service.h"
-#include "gnunet_statistics_service.h"
-
-
-#define CHECK_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
-#define STATS_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
-#define REPEATED_STATS_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
-#define STATS_VALUES 4
-
-/**
- * Final status code.
- */
-static int ret;
-static int ping;
-
-static int have_tcp;
-static int have_udp;
-static int have_http;
-static int have_https;
-static int have_unix;
-
-static struct GNUNET_TRANSPORT_Handle *th;
-static struct GNUNET_CORE_Handle *ch;
-static struct GNUNET_PeerIdentity my_peer_id;
-static const struct GNUNET_CONFIGURATION_Handle *mycfg;
-static struct GNUNET_STATISTICS_Handle *stats;
-
-
-static unsigned int transport_connections;
-static unsigned int core_connections;
-
-static GNUNET_SCHEDULER_TaskIdentifier check_task;
-static GNUNET_SCHEDULER_TaskIdentifier statistics_task;
-
-static uint64_t statistics_transport_connections;
-static uint64_t statistics_transport_tcp_connections;
-static uint64_t statistics_core_neighbour_entries;
-static uint64_t statistics_core_entries_session_map;
-
-static int stat_check_running;
-
-static struct GNUNET_CONTAINER_MultiPeerMap *peers;
-
-struct PeerContainer
-{
- struct GNUNET_PeerIdentity id;
- int transport_connected;
- int core_connected;
- struct GNUNET_TRANSPORT_TransmitHandle *th_ping;
- struct GNUNET_CORE_TransmitHandle *ch_ping;
-
- struct GNUNET_TRANSPORT_TransmitHandle *th_pong;
- struct GNUNET_CORE_TransmitHandle *ch_pong;
-};
-
-
-enum protocol
-{
- tcp,
- udp,
- unixdomain
-};
-
-struct TransportPlugin
-{
- /**
- * This is a doubly-linked list.
- */
- struct TransportPlugin *next;
-
- /**
- * This is a doubly-linked list.
- */
- struct TransportPlugin *prev;
-
- /**
- * Short name for the plugin (i.e. "tcp").
- */
- char *short_name;
-
- int port;
-
- int protocol;
-};
-
-
-static struct TransportPlugin *phead;
-static struct TransportPlugin *ptail;
-
-
-static int
-map_check_it (void *cls,
- const struct GNUNET_PeerIdentity * key,
- void *value)
-{
- int *fail = cls;
- struct PeerContainer *pc = value;
- if (pc->core_connected != pc->transport_connected)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Inconsistent peer `%s': TRANSPORT %s <-> CORE %s\n",
- GNUNET_i2s (&pc->id),
- (GNUNET_YES == pc->transport_connected) ? "YES" : "NO",
- (GNUNET_YES == pc->core_connected) ? "YES" : "NO");
- (*fail) ++;
- }
-
- return GNUNET_OK;
-}
-
-
-static int
-map_cleanup_it (void *cls,
- const struct GNUNET_PeerIdentity * key,
- void *value)
-{
- struct PeerContainer *pc = value;
- GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multipeermap_remove(peers, key, value));
- if (NULL != pc->th_ping)
- {
- GNUNET_TRANSPORT_notify_transmit_ready_cancel(pc->th_ping);
- pc->th_ping = NULL;
- }
- if (NULL != pc->th_pong)
- {
- GNUNET_TRANSPORT_notify_transmit_ready_cancel(pc->th_pong);
- pc->th_pong = NULL;
- }
- if (NULL != pc->ch_ping)
- {
- GNUNET_CORE_notify_transmit_ready_cancel (pc->ch_ping);
- pc->ch_ping = NULL;
- }
- if (NULL != pc->ch_pong)
- {
- GNUNET_CORE_notify_transmit_ready_cancel(pc->ch_pong);
- pc->ch_pong = NULL;
- }
- GNUNET_free (pc);
- return GNUNET_OK;
-}
-
-static void
-map_cleanup (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- GNUNET_CONTAINER_multipeermap_iterate (peers, &map_cleanup_it, NULL);
- GNUNET_CONTAINER_multipeermap_destroy(peers);
-}
-
-static void
-map_check (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- int fail = 0;
- check_task = GNUNET_SCHEDULER_NO_TASK;
- GNUNET_CONTAINER_multipeermap_iterate (peers, &map_check_it, &fail);
- if (0 > fail)
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Inconsistent peers after connection consistency check: %u\n", fail);
- else
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Inconsistent peers after connection consistency check: %u\n", fail);
-
-
- if (NULL != cls)
- {
- GNUNET_SCHEDULER_add_now (cls, NULL);
- }
-}
-
-
-static void
-stats_check (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
-
-
-static int
-check_lowlevel_connections (int port, int protocol)
-{
-#ifdef MINGW
- #define DEVNULL "NUL"
-#else
- #define DEVNULL "/dev/null"
-#endif
-
- FILE *f;
- char * cmdline;
- char * proto;
- char line[1024];
- int count = -1;
-
- switch (protocol)
- {
- case tcp:
-#ifdef MINGW
- proto = "-p TCP";
-#else
- proto = "-t";
-#endif
- break;
- case udp:
-#ifdef MINGW
- proto = "-p UDP";
-#else
- proto = "-u";
-#endif
- break;
- case unixdomain:
-#ifdef MINGW
- proto = "-p UNIX";
-#else
- proto = "-x";
-#endif
- break;
- default:
- proto = "";
- break;
- }
-
- /* Use netstat to get a numeric list of all connections on port 'port' in state 'ESTABLISHED' */
- GNUNET_asprintf(&cmdline, "netstat -n %s | grep %u | grep ESTABLISHED", proto, port);
-
- if (system ("netstat -n > " DEVNULL " 2> " DEVNULL))
- if (system ("netstat -n > " DEVNULL " 2> "DEVNULL) == 0)
- f = popen (cmdline, "r");
- else
- f = NULL;
- else
- f = popen (cmdline, "r");
- if (!f)
- {
- GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR, "ss");
- GNUNET_free (cmdline);
- return -1;
- }
-
- count = 0;
- while (NULL != fgets (line, sizeof (line), f))
- {
- /* read */
- //printf ("%s", line);
- count++;
- }
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "%i TCP connections established with port %u\n",
- count, port);
-
- pclose (f);
- GNUNET_free (cmdline);
- return count;
-}
-
-
-static struct TransportPlugin *
-find_plugin (char * name)
-{
- struct TransportPlugin *cur = NULL;
-
- for (cur = phead; cur != NULL; cur = cur->next)
- {
- if (0 == strcmp(name, cur->short_name))
- return cur;
- }
- return cur;
-}
-
-static int
-stats_check_cb (void *cls, const char *subsystem,
- const char *name, uint64_t value,
- int is_persistent)
-{
- static int counter;
-
- uint64_t *val = cls;
-
- if (NULL != val)
- (*val) = value;
-
- counter ++;
- if ((STATS_VALUES == counter) || ((GNUNET_NO == have_tcp) && (STATS_VALUES - 1 == counter)))
- {
- int fail = GNUNET_NO;
-
-
-
- int low_level_connections_udp = check_lowlevel_connections (2086, udp);
-
- if (transport_connections != core_connections)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "%u transport notifications <-> %u core notifications\n",
- transport_connections, core_connections);
- fail = GNUNET_YES;
- }
-
- if (transport_connections != statistics_transport_connections)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "%u transport notifications <-> %u in statistics (peers connected)\n",
- transport_connections, statistics_transport_connections);
- fail = GNUNET_YES;
- }
-
- if (core_connections != statistics_core_entries_session_map)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "%u core notifications <-> %u in statistics (entries session map)\n",
- core_connections, statistics_core_entries_session_map);
- fail = GNUNET_YES;
- }
-
- if (core_connections != statistics_core_neighbour_entries)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "%u core notifications <-> %u in statistics (neighbour entries allocated)\n",
- core_connections, statistics_core_neighbour_entries);
- fail = GNUNET_YES;
- }
-
- if (GNUNET_NO == fail)
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Check successful : (%u transport / %u core) connections established\n", transport_connections, core_connections);
-
- /* TCP plugin specific checks */
- if (GNUNET_YES == have_tcp)
- {
- struct TransportPlugin * p = find_plugin ("tcp");
- int low_level_connections_tcp = check_lowlevel_connections (p->port, p->protocol);
-
- if (low_level_connections_tcp != -1)
- {
- if (statistics_transport_tcp_connections > low_level_connections_tcp)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "%u transport tcp sessions <-> %i established tcp connections\n",
- statistics_transport_tcp_connections, low_level_connections_tcp);
- }
- else if (low_level_connections_tcp != -1)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "%u TCP connections, %u UDP connections \n",
- low_level_connections_tcp, low_level_connections_udp);
- }
- }
- if (transport_connections > statistics_transport_tcp_connections)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "%u transport notifications <-> %u in statistics (statistics_transport_tcp_connections)\n",
- transport_connections, statistics_transport_tcp_connections);
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " %u transport notifications <-> %u in statistics (statistics_transport_tcp_connections)\n",
- transport_connections, statistics_transport_tcp_connections);
- }
- }
-
- if (GNUNET_SCHEDULER_NO_TASK == statistics_task)
- statistics_task = GNUNET_SCHEDULER_add_delayed(REPEATED_STATS_DELAY, &stats_check, NULL);
-
- stat_check_running = GNUNET_NO;
- counter = 0;
- }
-
- return GNUNET_OK;
-}
-
-GNUNET_NETWORK_STRUCT_BEGIN
-
-struct PING
-{
- struct GNUNET_MessageHeader header;
-
- uint16_t src;
-};
-
-struct PONG
-{
- struct GNUNET_MessageHeader header;
-
- uint16_t src;
-};
-GNUNET_NETWORK_STRUCT_END
-
-
-static size_t
-send_transport_ping_cb (void *cls, size_t size, void *buf)
-{
- struct PeerContainer * pc = cls;
- struct PING ping;
- size_t mlen = sizeof (struct PING);
-
- if (size < mlen)
- {
- GNUNET_break (0);
- return 0;
- }
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Sending transport ping to `%s'\n", GNUNET_i2s (&pc->id));
- ping.header.size = htons (mlen);
- ping.header.type = htons (1234);
- ping.src = htons (0);
-
- pc->th_ping = NULL;
-
- memcpy (buf, &ping, mlen);
- return mlen;
-}
-
-
-static size_t
-send_core_ping_cb (void *cls, size_t size, void *buf)
-{
- struct PeerContainer * pc = cls;
- struct PING ping;
- size_t mlen = sizeof (struct PING);
-
- if (size < mlen)
- {
- GNUNET_break (0);
- return 0;
- }
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Sending core ping to `%s'\n", GNUNET_i2s (&pc->id));
- ping.header.size = htons (mlen);
- ping.header.type = htons (1234);
- ping.src = htons (1);
-
- pc->ch_ping = NULL;
-
- memcpy (buf, &ping, mlen);
- return mlen;
-}
-
-
-static int
-map_ping_it (void *cls,
- const struct GNUNET_PeerIdentity * key,
- void *value)
-{
- struct PeerContainer *pc = value;
-
- if (ping == GNUNET_YES)
- {
- if ((GNUNET_YES == pc->transport_connected) && (NULL == pc->th_ping))
- pc->th_ping = GNUNET_TRANSPORT_notify_transmit_ready(th, &pc->id,
- sizeof (struct PING), UINT_MAX,
- GNUNET_TIME_UNIT_FOREVER_REL, &send_transport_ping_cb, pc);
- else
- GNUNET_break(0);
-
- if ((GNUNET_YES == pc->core_connected) && (NULL == pc->ch_ping))
- pc->ch_ping = GNUNET_CORE_notify_transmit_ready(ch,
- GNUNET_NO, UINT_MAX,
- GNUNET_TIME_UNIT_FOREVER_REL,
- &pc->id,
- sizeof (struct PING),
- send_core_ping_cb, pc);
- else
- GNUNET_break (0);
- }
- return GNUNET_OK;
-}
-
-
-static void
-stats_check (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- statistics_task = GNUNET_SCHEDULER_NO_TASK;
-
- if (GNUNET_YES == stat_check_running)
- {
- statistics_task = GNUNET_SCHEDULER_add_delayed(STATS_DELAY, &stats_check, NULL);
- }
-
- GNUNET_CONTAINER_multipeermap_iterate (peers, &map_ping_it, NULL);
-
- stat_check_running = GNUNET_YES;
-
- statistics_transport_connections = 0 ;
- statistics_core_entries_session_map = 0;
- statistics_core_neighbour_entries = 0;
-
- GNUNET_STATISTICS_get (stats, "transport", "# peers connected", GNUNET_TIME_UNIT_MINUTES, NULL, &stats_check_cb, &statistics_transport_connections);
- GNUNET_STATISTICS_get (stats, "core", "# neighbour entries allocated", GNUNET_TIME_UNIT_MINUTES, NULL, &stats_check_cb, &statistics_core_neighbour_entries);
- GNUNET_STATISTICS_get (stats, "core", "# peers connected", GNUNET_TIME_UNIT_MINUTES, NULL, &stats_check_cb, &statistics_core_entries_session_map);
-
- /* TCP plugin specific checks */
- if (GNUNET_YES == have_tcp)
- GNUNET_STATISTICS_get (stats, "transport", "# TCP sessions active", GNUNET_TIME_UNIT_MINUTES, NULL, &stats_check_cb, &statistics_transport_tcp_connections);
-}
-
-
-static size_t
-send_transport_pong_cb (void *cls, size_t size, void *buf)
-{
- struct PeerContainer * pc = cls;
- struct PING ping;
- size_t mlen = sizeof (struct PING);
-
- if (size < mlen)
- {
- GNUNET_break (0);
- return 0;
- }
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Sending transport pong to `%s'\n", GNUNET_i2s (&pc->id));
- ping.header.size = htons (mlen);
- ping.header.type = htons (4321);
- ping.src = htons (0);
-
- pc->th_pong = NULL;
-
- memcpy (buf, &ping, mlen);
- return mlen;
-}
-
-
-static size_t
-send_core_pong_cb (void *cls, size_t size, void *buf)
-{
- struct PeerContainer * pc = cls;
- struct PING ping;
- size_t mlen = sizeof (struct PING);
-
- if (size < mlen)
- {
- GNUNET_break (0);
- return 0;
- }
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Sending core pong to `%s'\n", GNUNET_i2s (&pc->id));
- ping.header.size = htons (mlen);
- ping.header.type = htons (4321);
- ping.src = htons (1);
-
- pc->ch_pong = NULL;
-
- memcpy (buf, &ping, mlen);
- return mlen;
-}
-
-
-static void
-map_connect (const struct GNUNET_PeerIdentity *peer, void * source)
-{
- struct PeerContainer * pc;
- if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains(peers, peer))
- {
- pc = GNUNET_malloc (sizeof (struct PeerContainer));
- pc->id = *peer;
- pc->core_connected = GNUNET_NO;
- pc->transport_connected = GNUNET_NO;
- GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multipeermap_put(peers, peer, pc, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
- }
-
- pc = GNUNET_CONTAINER_multipeermap_get(peers, peer);
- GNUNET_assert (NULL != pc);
-
- if (source == th)
- {
- if (GNUNET_NO == pc->transport_connected)
- {
- pc->transport_connected = GNUNET_YES;
- if (GNUNET_YES == ping)
- {
- if (NULL == pc->th_ping)
- pc->th_ping = GNUNET_TRANSPORT_notify_transmit_ready(th, peer, sizeof (struct PING), UINT_MAX, GNUNET_TIME_UNIT_FOREVER_REL, &send_transport_ping_cb, pc);
- else
- GNUNET_break(0);
- }
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "%s notified multiple times about for peers `%s' (%s : %s)\n",
- "TRANSPORT",
- GNUNET_i2s (&pc->id),
- "CORE", (pc->core_connected == GNUNET_YES) ? "yes" : "no");
- GNUNET_break (0);
- }
- }
- if (source == ch)
- {
- if (GNUNET_NO == pc->core_connected)
- {
- pc->core_connected = GNUNET_YES;
- if (GNUNET_YES == ping)
- {
- if (NULL == pc->ch_ping)
- pc->ch_ping = GNUNET_CORE_notify_transmit_ready(ch,
- GNUNET_NO, UINT_MAX,
- GNUNET_TIME_UNIT_FOREVER_REL,
- peer,
- sizeof (struct PING),
- send_core_ping_cb, pc);
- else
- GNUNET_break (0);
- }
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "%s notified multiple times about for peers `%s' (%s : %s)\n",
- "CORE",
- GNUNET_i2s (&pc->id),
- "TRANSPORT", (pc->transport_connected == GNUNET_YES) ? "yes" : "no");
- GNUNET_break (0);
- }
- }
- if (GNUNET_SCHEDULER_NO_TASK != check_task)
- GNUNET_SCHEDULER_cancel(check_task);
- check_task = GNUNET_SCHEDULER_add_delayed(CHECK_DELAY, &map_check, NULL);
-
- if (GNUNET_SCHEDULER_NO_TASK != statistics_task)
- GNUNET_SCHEDULER_cancel(statistics_task);
- statistics_task = GNUNET_SCHEDULER_add_delayed(STATS_DELAY, &stats_check, NULL);
-}
-
-
-static void
-map_disconnect (const struct GNUNET_PeerIdentity * peer, void * source)
-{
-
- struct PeerContainer * pc;
- if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains(peers, peer))
- {
- if (source == th)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "%s disconnect notification for unknown peer `%s'\n",
- "TRANSPORT", GNUNET_i2s (peer));
- GNUNET_break (0);
- return;
- }
- if (source == ch)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "%s disconnect notification for unknown peer `%s'\n",
- "CORE", GNUNET_i2s (peer));
- return;
- }
- }
-
- pc = GNUNET_CONTAINER_multipeermap_get(peers, peer);
- GNUNET_assert (NULL != pc);
-
- if (source == th)
- {
- if (NULL != pc->th_ping)
- {
- GNUNET_TRANSPORT_notify_transmit_ready_cancel(pc->th_ping);
- pc->th_ping = NULL;
- }
- if (NULL != pc->th_pong)
- {
- GNUNET_TRANSPORT_notify_transmit_ready_cancel(pc->th_pong);
- pc->th_pong = NULL;
- }
-
- if (GNUNET_YES == pc->transport_connected)
- {
- pc->transport_connected = GNUNET_NO;
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "%s notified for not connected peer `%s' (%s : %s)\n",
- "TRANSPORT",
- GNUNET_i2s (&pc->id),
- "CORE", (pc->core_connected == GNUNET_YES) ? "yes" : "no");
- GNUNET_break (0);
- }
- }
- if (source == ch)
- {
- if (NULL != pc->ch_ping)
- {
- GNUNET_CORE_notify_transmit_ready_cancel (pc->ch_ping);
- pc->ch_ping = NULL;
- }
- if (NULL != pc->ch_pong)
- {
- GNUNET_CORE_notify_transmit_ready_cancel (pc->ch_pong);
- pc->ch_pong = NULL;
- }
-
- if (GNUNET_YES == pc->core_connected)
- {
- pc->core_connected = GNUNET_NO;
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "%s notified for not connected peer `%s' (%s : %s)\n",
- "CORE",
- GNUNET_i2s (&pc->id),
- "TRANSPORT", (pc->transport_connected == GNUNET_YES) ? "yes" : "no");
- GNUNET_break (0);
- }
- }
-
- if ((GNUNET_NO == pc->core_connected) && (GNUNET_NO == pc->transport_connected))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing peer `%s'\n", GNUNET_i2s (&pc->id));
- GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multipeermap_remove (peers, peer, pc));
-
-
- GNUNET_free (pc);
- }
-
- if (GNUNET_SCHEDULER_NO_TASK != check_task)
- GNUNET_SCHEDULER_cancel(check_task);
- check_task = GNUNET_SCHEDULER_add_delayed(CHECK_DELAY, &map_check, NULL);
-
- if (GNUNET_SCHEDULER_NO_TASK != statistics_task)
- GNUNET_SCHEDULER_cancel(statistics_task);
- statistics_task = GNUNET_SCHEDULER_add_delayed(STATS_DELAY, &stats_check, NULL);
-}
-
-
-static void
-cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- struct TransportPlugin *cur;
-
- if (NULL != th)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Disconnecting from transport service\n");
- GNUNET_TRANSPORT_disconnect (th);
- th = NULL;
- }
-
-
- if (NULL != ch)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Disconnecting from core service\n");
- GNUNET_CORE_disconnect (ch);
- ch = NULL;
- }
-
- if (GNUNET_SCHEDULER_NO_TASK != statistics_task)
- {
- GNUNET_SCHEDULER_cancel(statistics_task);
- statistics_task = GNUNET_SCHEDULER_NO_TASK;
- }
-
- if (GNUNET_SCHEDULER_NO_TASK != check_task)
- {
- GNUNET_SCHEDULER_cancel(check_task);
- check_task = GNUNET_SCHEDULER_NO_TASK;
- }
-
- for (cur = phead; NULL != cur; cur = phead)
- {
- GNUNET_CONTAINER_DLL_remove(phead, ptail, cur);
- GNUNET_free (cur->short_name);
- GNUNET_free (cur);
- }
-
- check_task = GNUNET_SCHEDULER_add_now (&map_check, &map_cleanup);
-}
-
-
-static void
-transport_notify_connect_cb (void *cls,
- const struct GNUNET_PeerIdentity* peer)
-{
- transport_connections ++;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "TRANSPORT connect for peer `%s' (%u total)\n",
- GNUNET_i2s (peer),
- transport_connections);
- map_connect (peer, th);
-}
-
-
-/**
- * Function called to notify transport users that another
- * peer disconnected from us.
- *
- * @param cls closure
- * @param peer the peer that disconnected
- */
-static void
-transport_notify_disconnect_cb (void *cls,
- const struct GNUNET_PeerIdentity *peer)
-{
- GNUNET_assert (transport_connections > 0);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "TRANSPORT disconnect for peer `%s' (%u total)\n",
- GNUNET_i2s (peer),
- transport_connections);
- map_disconnect (peer, th);
- transport_connections --;
-}
-
-
-static void
-transport_notify_receive_cb (void *cls,
- const struct
- GNUNET_PeerIdentity * peer,
- const struct
- GNUNET_MessageHeader *
- message)
-{
- struct PeerContainer *pc;
-
- pc = GNUNET_CONTAINER_multipeermap_get (peers, peer);
- if (NULL == pc)
- {
- GNUNET_break (0);
- return;
- }
-
- if ((message->size == ntohs (sizeof (struct PING))) &&
- (message->type == ntohs (1234)))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Received %s %s from peer `%s'\n",
- "TRANSPORT",
- "PING",
- GNUNET_i2s (peer)) ;
- if (GNUNET_YES == ping)
- {
- if (NULL == pc->th_pong)
- pc->th_pong = GNUNET_TRANSPORT_notify_transmit_ready(th,
- peer, sizeof (struct PONG),
- UINT_MAX, GNUNET_TIME_UNIT_FOREVER_REL,
- &send_transport_pong_cb, pc);
- else
- GNUNET_break (0);
- }
-
- }
- if ((message->size == ntohs (sizeof (struct PONG))) && (message->type == ntohs (4321)))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Received %s %s from peer `%s'\n",
- "TRANSPORT",
- "PONG",
- GNUNET_i2s (peer));
- }
-}
-
-static int
-core_notify_receive_cb (void *cls,
- const struct GNUNET_PeerIdentity * peer,
- const struct GNUNET_MessageHeader * message)
-{
- struct PeerContainer *pc = NULL;
-
- pc = GNUNET_CONTAINER_multipeermap_get(peers, peer);
-
- if (NULL == pc)
- {
- if (0 == memcmp (peer, &my_peer_id, sizeof (my_peer_id)))
- return GNUNET_OK;
-
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Received unexpected message type %u from unknown peer `%s'\n",
- ntohs (message->type),
- GNUNET_i2s (peer));
-
- GNUNET_break (0);
- return GNUNET_OK;
- }
-
- if ((message->size == ntohs (sizeof (struct PING))) && (message->type == ntohs (1234)))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Received %s %s from peer `%s'\n",
- "CORE",
- "PING",
- GNUNET_i2s (peer));
- if (GNUNET_YES == ping)
- {
- if (NULL == pc->ch_pong)
- pc->ch_pong = GNUNET_CORE_notify_transmit_ready(ch,
- GNUNET_NO, UINT_MAX,
- GNUNET_TIME_UNIT_FOREVER_REL,
- peer,
- sizeof (struct PONG),
- send_core_pong_cb, pc);
- else
- GNUNET_break (0);
- }
- }
-
- if ((message->size == ntohs (sizeof (struct PONG))) && (message->type == ntohs (4321)))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Received %s %s from peer `%s'\n",
- "CORE",
- "PONG",
- GNUNET_i2s (peer));
-
- }
-
- return GNUNET_OK;
-}
-
-static void
-core_connect_cb (void *cls, const struct GNUNET_PeerIdentity *peer)
-{
- if (0 != memcmp (peer, &my_peer_id, sizeof (struct GNUNET_PeerIdentity)))
- {
- core_connections ++;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "CORE connect for peer `%s' (%u total)\n",
- GNUNET_i2s (peer), core_connections);
- map_connect (peer, ch);
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "CORE connect for myself `%s' (%u total)\n",
- GNUNET_i2s (peer), core_connections);
- }
-}
-
-static void
-core_disconnect_cb (void *cls,
- const struct
- GNUNET_PeerIdentity * peer)
-{
- if (0 != memcmp (peer, &my_peer_id, sizeof (struct GNUNET_PeerIdentity)))
- {
- GNUNET_assert (core_connections > 0);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "CORE disconnect for peer `%s' (%u total)\n",
- GNUNET_i2s (peer), core_connections);
- map_disconnect (peer, ch);
- core_connections --;
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "CORE disconnect for myself `%s' (%u total)\n",
- GNUNET_i2s (peer), core_connections);
- }
-}
-
-
-static void
-core_init_cb (void *cls,
- const struct GNUNET_PeerIdentity *my_identity)
-{
- my_peer_id = *my_identity;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Connected to core service\n");
-}
-
-
-static void
-init ()
-{
- struct TransportPlugin * cur;
- char *plugs;
- char *pos;
- char *secname;
- int counter;
- unsigned long long port;
-
- have_tcp = GNUNET_NO;
- have_udp = GNUNET_NO;
- have_http = GNUNET_NO;
- have_https = GNUNET_NO;
- have_unix = GNUNET_NO;
-
- if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (mycfg, "TRANSPORT", "PLUGINS", &plugs))
- return;
- counter = 0;
- for (pos = strtok (plugs, " "); pos != NULL; pos = strtok (NULL, " "))
- {
- counter++;
-
- GNUNET_asprintf(&secname, "transport-%s", pos);
-
- if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (mycfg, secname, "PORT", &port))
- {
- GNUNET_free (secname);
- continue;
- }
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Transport plugin: `%s' port %llu\n"), pos, port);
- cur = GNUNET_malloc(sizeof (struct TransportPlugin));
- cur->short_name = GNUNET_strdup (pos);
- cur->port = port;
- if (0 == strcmp("tcp", pos))
- {
- have_tcp = GNUNET_YES;
- cur->protocol = tcp;
- }
- if (0 == strcmp("udp", pos))
- {
- have_udp = GNUNET_YES;
- cur->protocol = udp;
- }
- if (0 == strcmp("http", pos))
- {
- have_http = GNUNET_YES;
- cur->protocol = tcp;
- }
- if (0 == strcmp("https", pos))
- {
- have_https = GNUNET_YES;
- cur->protocol = tcp;
- }
- if (0 == strcmp("unix", pos))
- {
- have_unix = GNUNET_YES;
- cur->protocol = unixdomain;
- }
-
- GNUNET_CONTAINER_DLL_insert(phead, ptail, cur);
- GNUNET_free (secname);
- }
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Found %u transport plugins: `%s'\n"),
- counter, plugs);
-
- GNUNET_free (plugs);
-}
-
-
-/**
- * Main function that will be run by the scheduler.
- *
- * @param cls closure
- * @param args remaining command-line arguments
- * @param cfgfile name of the configuration file used (for saving, can be NULL!)
- * @param cfg configuration
- */
-static void
-run (void *cls, char *const *args, const char *cfgfile,
- const struct GNUNET_CONFIGURATION_Handle *cfg)
-{
- transport_connections = 0;
- core_connections = 0;
- mycfg = cfg;
-
- init();
-
- stats = GNUNET_STATISTICS_create ("watchdog", cfg);
- peers = GNUNET_CONTAINER_multipeermap_create (32, GNUNET_NO);
-
- th = GNUNET_TRANSPORT_connect(cfg, NULL, NULL,
- &transport_notify_receive_cb,
- &transport_notify_connect_cb,
- &transport_notify_disconnect_cb);
- GNUNET_assert (th != NULL);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Connected to transport service\n");
- ch = GNUNET_CORE_connect (cfg, NULL,
- &core_init_cb,
- &core_connect_cb,
- &core_disconnect_cb,
- &core_notify_receive_cb, GNUNET_NO,
- NULL, GNUNET_NO,
- NULL);
- GNUNET_assert (ch != NULL);
-
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup_task, NULL);
-
-}
-
-
-/**
- * The main function.
- *
- * @param argc number of arguments from the command line
- * @param argv command line arguments
- * @return 0 ok, 1 on error
- */
-int
-main (int argc, char *const *argv)
-{
- ping = GNUNET_NO;
- static const struct GNUNET_GETOPT_CommandLineOption options[] = {
- {'p', "ping", NULL, gettext_noop ("Send ping messages to test connectivity (default == NO)"),
- GNUNET_NO, &GNUNET_GETOPT_set_one, &ping},
- GNUNET_GETOPT_OPTION_END
- };
-
- if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
- return 2;
- ret = (GNUNET_OK ==
- GNUNET_PROGRAM_run (argc, argv, "cn",
- gettext_noop ("help text"), options, &run,
- NULL)) ? ret : 1;
- GNUNET_free ((void*) argv);
- return ret;
-}
-
-/* end of connection_watchdog.c */
+++ /dev/null
-#!/usr/bin/python
-# This file is part of GNUnet.
-# (C) 2010 Christian Grothoff (and other contributing authors)
-#
-# GNUnet is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published
-# by the Free Software Foundation; either version 2, or (at your
-# option) any later version.
-#
-# GNUnet is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GNUnet; see the file COPYING. If not, write to the
-# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-# Boston, MA 02111-1307, USA.
-#
-#
-#
-# This test starts 3 peers and expects bootstrap and a connected clique
-#
-# Conditions for successful exit:
-# Both peers have 1 connected peer in transport, core, topology, fs
-
-import sys
-import os
-import subprocess
-import re
-import shutil
-import time
-from gnunet_testing import Peer
-from gnunet_testing import Test
-from gnunet_testing import Check
-from gnunet_testing import Condition
-from gnunet_testing import *
-
-if os.name == "nt":
- tmp = os.getenv ("TEMP")
-else:
- tmp = "/tmp"
-
-#definitions
-
-testname = "test_integration_clique"
-verbose = True
-check_timeout = 180
-
-
-def cleanup ():
- shutil.rmtree (os.path.join (tmp, "c_bootstrap_server"), True)
- shutil.rmtree (os.path.join (tmp, "c_no_nat_client"), True)
- shutil.rmtree (os.path.join (tmp, "c_no_nat_client_2"), True)
-
-
-
-def check_disconnect ():
- check = Check (test)
- check.add (StatisticsCondition (client, 'transport', '# peers connected',1))
- check.add (StatisticsCondition (client, 'core', '# neighbour entries allocated',1))
- check.add (StatisticsCondition (client, 'core', '# peers connected',1))
- check.add (StatisticsCondition (client, 'topology', '# peers connected',1))
- check.add (StatisticsCondition (client, 'fs', '# peers connected',1))
-
- check.add (StatisticsCondition (server, 'transport', '# peers connected',1))
- check.add (StatisticsCondition (server, 'core', '# neighbour entries allocated',1))
- check.add (StatisticsCondition (server, 'core', '# peers connected',1))
- check.add (StatisticsCondition (server, 'topology', '# peers connected',1))
- check.add (StatisticsCondition (server, 'fs', '# peers connected',1))
-
- check.run_blocking (check_timeout, None, None)
-
-
-
-def check_connect ():
- check = Check (test)
- check.add (StatisticsCondition (client, 'transport', '# peers connected',2))
- check.add (StatisticsCondition (client, 'core', '# neighbour entries allocated',2))
- check.add (StatisticsCondition (client, 'core', '# peers connected',2))
- check.add (StatisticsCondition (client, 'topology', '# peers connected',2))
- check.add (StatisticsCondition (client, 'fs', '# peers connected',2))
-
- check.add (StatisticsCondition (client2, 'transport', '# peers connected',2))
- check.add (StatisticsCondition (client2, 'core', '# neighbour entries allocated',2))
- check.add (StatisticsCondition (client2, 'core', '# peers connected',2))
- check.add (StatisticsCondition (client2, 'topology', '# peers connected',2))
- check.add (StatisticsCondition (client2, 'fs', '# peers connected',2))
-
- check.add (StatisticsCondition (server, 'transport', '# peers connected',2))
- check.add (StatisticsCondition (server, 'core', '# neighbour entries allocated',2))
- check.add (StatisticsCondition (server, 'core', '# peers connected',2))
- check.add (StatisticsCondition (server, 'topology', '# peers connected',2))
- check.add (StatisticsCondition (server, 'fs', '# peers connected',2))
-
- check.run_blocking (check_timeout, None, None)
-
-#
-# Test execution
-#
-def run ():
- global success
- global test
- global server
- global client
- global client2
- restarts = 0
- iterations = 10000
- success = False
-
- test = Test ('test_memory_consumption', verbose)
- server = Peer(test, './confs/c_bootstrap_server_w_massif.conf');
- server.start();
- client = Peer(test, './confs/c_no_nat_client.conf');
- client.start();
-
- while (restarts < iterations):
- print 'Iteration #' + str (restarts) + ' of ' + str (iterations)
- print '---------------------'
- restarts += 1
- client2 = Peer(test, './confs/c_no_nat_client_2.conf');
- client2.start();
- if ((client.started == True) and (client2.started == True) and (server.started == True)):
- test.p ('Peers started, waiting for clique connection')
- check_connect ()
- test.p ('All peers connected, stopping client2')
- client2.stop ()
- check_disconnect ()
- test.p ('Peer disconnected\n')
-
- print str (iterations) + " Iteration executed"
- server.stop ()
- client.stop ()
- cleanup ()
-
-try:
- run ()
-except (KeyboardInterrupt, SystemExit):
- print 'Test interrupted'
- server.stop ()
- client.stop ()
- client2.stop ()
- cleanup ()
-if (success == False):
- sys.exit(1)
-else:
- sys.exit(0)
-
-