[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r33032 - in gnunet/src: core include
From: |
gnunet |
Subject: |
[GNUnet-SVN] r33032 - in gnunet/src: core include |
Date: |
Fri, 11 Apr 2014 13:49:51 +0200 |
Author: grothoff
Date: 2014-04-11 13:49:51 +0200 (Fri, 11 Apr 2014)
New Revision: 33032
Modified:
gnunet/src/core/core.h
gnunet/src/core/core_api_iterate_peers.c
gnunet/src/core/gnunet-core.c
gnunet/src/core/gnunet-service-core.c
gnunet/src/core/gnunet-service-core_clients.c
gnunet/src/core/gnunet-service-core_kx.c
gnunet/src/core/gnunet-service-core_kx.h
gnunet/src/core/gnunet-service-core_sessions.c
gnunet/src/core/gnunet-service-core_sessions.h
gnunet/src/include/gnunet_core_service.h
gnunet/src/include/gnunet_protocols.h
Log:
towards fixing #3363: replacing old iteration API with new monitoring API for
core (needs testing, gnunet-core incomplete)
Modified: gnunet/src/core/core.h
===================================================================
--- gnunet/src/core/core.h 2014-04-10 17:05:39 UTC (rev 33031)
+++ gnunet/src/core/core.h 2014-04-11 11:49:51 UTC (rev 33032)
@@ -62,7 +62,7 @@
{
/**
- * Header with type GNUNET_MESSAGE_TYPE_CORE_INIT.
+ * Header with type #GNUNET_MESSAGE_TYPE_CORE_INIT.
*/
struct GNUNET_MessageHeader header;
@@ -82,7 +82,7 @@
{
/**
- * Header with type GNUNET_MESSAGE_TYPE_CORE_INIT_REPLY
+ * Header with type #GNUNET_MESSAGE_TYPE_CORE_INIT_REPLY
*/
struct GNUNET_MessageHeader header;
@@ -106,7 +106,7 @@
struct ConnectNotifyMessage
{
/**
- * Header with type GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT
+ * Header with type #GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT
*/
struct GNUNET_MessageHeader header;
@@ -130,7 +130,7 @@
struct DisconnectNotifyMessage
{
/**
- * Header with type GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT.
+ * Header with type #GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT.
*/
struct GNUNET_MessageHeader header;
@@ -159,8 +159,8 @@
struct NotifyTrafficMessage
{
/**
- * Header with type GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND
- * or GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND.
+ * Header with type #GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND
+ * or #GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND.
*/
struct GNUNET_MessageHeader header;
@@ -291,6 +291,35 @@
};
+/**
+ * Message sent by the service to monitor clients to notify them
+ * about a peer changing status.
+ */
+struct MonitorNotifyMessage
+{
+ /**
+ * Header with type #GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * New peer state, an `enum GNUNET_CORE_KxState` in NBO.
+ */
+ uint32_t state GNUNET_PACKED;
+
+ /**
+ * Identity of the peer.
+ */
+ struct GNUNET_PeerIdentity peer;
+
+ /**
+ * How long will we stay in this state (if nothing else happens)?
+ */
+ struct GNUNET_TIME_AbsoluteNBO timeout;
+
+};
+
+
GNUNET_NETWORK_STRUCT_END
#endif
/* end of core.h */
Modified: gnunet/src/core/core_api_iterate_peers.c
===================================================================
--- gnunet/src/core/core_api_iterate_peers.c 2014-04-10 17:05:39 UTC (rev
33031)
+++ gnunet/src/core/core_api_iterate_peers.c 2014-04-11 11:49:51 UTC (rev
33032)
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- (C) 2009, 2010 Christian Grothoff (and other contributing authors)
+ (C) 2009-2014 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
@@ -19,7 +19,7 @@
*/
/**
- * @file core/core_api_iterate_peers.c
+ * @file core/core_api_monitor_peers.c
* @brief implementation of the peer_iterate function
* @author Christian Grothoff
* @author Nathan Evans
@@ -29,15 +29,23 @@
#include "core.h"
-struct GNUNET_CORE_RequestContext
+/**
+ * Handle to a CORE monitoring operation.
+ */
+struct GNUNET_CORE_MonitorHandle
{
+
/**
+ * Our configuration.
+ */
+ const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+ /**
* Our connection to the service.
*/
struct GNUNET_CLIENT_Connection *client;
/**
-
* Handle for transmitting a request.
*/
struct GNUNET_CLIENT_TransmitHandle *th;
@@ -45,140 +53,200 @@
/**
* Function called with the peer.
*/
- GNUNET_CORE_ConnectEventHandler peer_cb;
+ GNUNET_CORE_MonitorCallback peer_cb;
/**
- * Peer to check for.
+ * Closure for @e peer_cb.
*/
- struct GNUNET_PeerIdentity *peer;
+ void *peer_cb_cls;
- /**
- * Closure for peer_cb.
- */
- void *cb_cls;
-
};
/**
- * Receive reply from core service with information about a peer.
+ * Transmits the monitor request to the CORE service.
*
- * @param cls our 'struct GNUNET_CORE_RequestContext *'
+ * Function is called to notify a client about the socket begin ready
+ * to queue more data. @a buf will be NULL and @a size zero if the
+ * socket was closed for writing in the meantime.
+ *
+ * @param cls closure, our `struct GNUNET_CORE_MonitorHandle *`
+ * @param size number of bytes available in @a buf
+ * @param buf where the callee should write the message
+ * @return number of bytes written to @a buf
+ */
+static size_t
+transmit_monitor_request (void *cls,
+ size_t size,
+ void *buf);
+
+
+/**
+ * Protocol error, reconnect to CORE service and notify
+ * client.
+ *
+ * @param mh monitoring session to reconnect to CORE
+ */
+static void
+reconnect (struct GNUNET_CORE_MonitorHandle *mh)
+{
+ GNUNET_CLIENT_disconnect (mh->client);
+ /* FIXME: use backoff? */
+ mh->client = GNUNET_CLIENT_connect ("core", mh->cfg);
+ GNUNET_assert (NULL != mh->client);
+ mh->th =
+ GNUNET_CLIENT_notify_transmit_ready (mh->client,
+ sizeof (struct GNUNET_MessageHeader),
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ GNUNET_YES,
+ &transmit_monitor_request, mh);
+ /* notify callback about reconnect */
+ mh->peer_cb (mh->peer_cb_cls,
+ NULL,
+ GNUNET_CORE_KX_CORE_DISCONNECT,
+ GNUNET_TIME_UNIT_FOREVER_ABS);
+}
+
+
+/**
+ * Receive reply from CORE service with information about a peer.
+ *
+ * @param cls our `struct GNUNET_CORE_MonitorHandle *`
* @param msg NULL on error or last entry
*/
static void
-receive_info (void *cls, const struct GNUNET_MessageHeader *msg)
+receive_info (void *cls,
+ const struct GNUNET_MessageHeader *msg)
{
- struct GNUNET_CORE_RequestContext *request_context = cls;
- const struct ConnectNotifyMessage *connect_message;
+ struct GNUNET_CORE_MonitorHandle *mh = cls;
+ const struct MonitorNotifyMessage *mon_message;
uint16_t msize;
- /* Handle last message or error case, disconnect and clean up */
- if ((msg == NULL) ||
- ((ntohs (msg->type) == GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS_END) &&
- (ntohs (msg->size) == sizeof (struct GNUNET_MessageHeader))))
+ if (NULL == msg)
{
- if (request_context->peer_cb != NULL)
- request_context->peer_cb (request_context->cb_cls, NULL);
- GNUNET_CLIENT_disconnect (request_context->client);
- GNUNET_free (request_context);
+ reconnect (mh);
return;
}
-
msize = ntohs (msg->size);
/* Handle incorrect message type or size, disconnect and clean up */
- if ((ntohs (msg->type) != GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT) ||
- (msize < sizeof (struct ConnectNotifyMessage)))
+ if ((ntohs (msg->type) != GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY) ||
+ (sizeof (struct MonitorNotifyMessage) != msize))
{
GNUNET_break (0);
- if (request_context->peer_cb != NULL)
- request_context->peer_cb (request_context->cb_cls, NULL);
- GNUNET_CLIENT_disconnect (request_context->client);
- GNUNET_free (request_context);
+ reconnect (mh);
return;
}
- connect_message = (const struct ConnectNotifyMessage *) msg;
- if (msize != sizeof (struct ConnectNotifyMessage))
- {
- GNUNET_break (0);
- if (request_context->peer_cb != NULL)
- request_context->peer_cb (request_context->cb_cls, NULL);
- GNUNET_CLIENT_disconnect (request_context->client);
- GNUNET_free (request_context);
- return;
- }
- /* Normal case */
- if (request_context->peer_cb != NULL)
- request_context->peer_cb (request_context->cb_cls, &connect_message->peer);
- GNUNET_CLIENT_receive (request_context->client, &receive_info,
- request_context, GNUNET_TIME_UNIT_FOREVER_REL);
+ mon_message = (const struct MonitorNotifyMessage *) msg;
+ GNUNET_CLIENT_receive (mh->client,
+ &receive_info, mh,
+ GNUNET_TIME_UNIT_FOREVER_REL);
+ mh->peer_cb (mh->peer_cb_cls,
+ &mon_message->peer,
+ (enum GNUNET_CORE_KxState) ntohl (mon_message->state),
+ GNUNET_TIME_absolute_ntoh (mon_message->timeout));
}
/**
- * Function called to notify a client about the socket
- * begin ready to queue more data. "buf" will be
- * NULL and "size" zero if the socket was closed for
- * writing in the meantime.
+ * Transmits the monitor request to the CORE service.
*
- * @param cls closure, always NULL
- * @param size number of bytes available in buf
+ * Function is called to notify a client about the socket begin ready
+ * to queue more data. @a buf will be NULL and @a size zero if the
+ * socket was closed for writing in the meantime.
+ *
+ * @param cls closure, our `struct GNUNET_CORE_MonitorHandle *`
+ * @param size number of bytes available in @a buf
* @param buf where the callee should write the message
- * @return number of bytes written to buf
+ * @return number of bytes written to @a buf
*/
static size_t
-transmit_request (void *cls, size_t size, void *buf)
+transmit_monitor_request (void *cls,
+ size_t size,
+ void *buf)
{
+ struct GNUNET_CORE_MonitorHandle *mh = cls;
struct GNUNET_MessageHeader *msg;
int msize;
msize = sizeof (struct GNUNET_MessageHeader);
- if ((size < msize) || (buf == NULL))
+ if ((size < msize) || (NULL == buf))
+ {
+ reconnect (mh);
return 0;
+ }
msg = (struct GNUNET_MessageHeader *) buf;
msg->size = htons (msize);
- msg->type = htons (GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS);
-
+ msg->type = htons (GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS);
+ GNUNET_CLIENT_receive (mh->client,
+ &receive_info, mh,
+ GNUNET_TIME_UNIT_FOREVER_REL);
return msize;
}
/**
- * Iterate over all currently connected peers.
- * Calls peer_cb with each connected peer, and then
- * once with NULL to indicate that all peers have
- * been handled.
+ * Monitor connectivity and KX status of all peers known to CORE.
+ * Calls @a peer_cb with the current status for each connected peer,
+ * and then once with NULL to indicate that all peers that are
+ * currently active have been handled. After that, the iteration
+ * continues until it is cancelled. Normal users of the CORE API are
+ * not expected to use this function. It is different in that it
+ * truly lists all connections (including those where the KX is in
+ * progress), not just those relevant to the application. This
+ * function is used by special applications for diagnostics.
*
- * @param cfg configuration to use
+ * @param cfg configuration handle
* @param peer_cb function to call with the peer information
- * @param cb_cls closure for @a peer_cb
- * @return #GNUNET_OK if iterating, #GNUNET_SYSERR on error
+ * @param peer_cb_cls closure for @a peer_cb
+ * @return NULL on error
*/
-int
-GNUNET_CORE_iterate_peers (const struct GNUNET_CONFIGURATION_Handle *cfg,
- GNUNET_CORE_ConnectEventHandler peer_cb,
- void *cb_cls)
+struct GNUNET_CORE_MonitorHandle *
+GNUNET_CORE_monitor_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ GNUNET_CORE_MonitorCallback peer_cb,
+ void *peer_cb_cls)
{
- struct GNUNET_CORE_RequestContext *request_context;
+ struct GNUNET_CORE_MonitorHandle *mh;
struct GNUNET_CLIENT_Connection *client;
+ GNUNET_assert (NULL != peer_cb);
client = GNUNET_CLIENT_connect ("core", cfg);
- if (client == NULL)
- return GNUNET_SYSERR;
- request_context = GNUNET_new (struct GNUNET_CORE_RequestContext);
- request_context->client = client;
- request_context->peer_cb = peer_cb;
- request_context->cb_cls = cb_cls;
+ if (NULL == client)
+ return NULL;
+ mh = GNUNET_new (struct GNUNET_CORE_MonitorHandle);
+ mh->cfg = cfg;
+ mh->client = client;
+ mh->peer_cb = peer_cb;
+ mh->peer_cb_cls = peer_cb_cls;
+ mh->th =
+ GNUNET_CLIENT_notify_transmit_ready (client,
+ sizeof (struct GNUNET_MessageHeader),
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ GNUNET_YES,
+ &transmit_monitor_request, mh);
+ return mh;
+}
- request_context->th =
- GNUNET_CLIENT_notify_transmit_ready (client,
- sizeof (struct
GNUNET_MessageHeader),
- GNUNET_TIME_UNIT_FOREVER_REL,
- GNUNET_YES, &transmit_request,
NULL);
- GNUNET_CLIENT_receive (client, &receive_info, request_context,
- GNUNET_TIME_UNIT_FOREVER_REL);
- return GNUNET_OK;
+/**
+ * Stop monitoring CORE activity.
+ *
+ * @param mh monitor to stop
+ */
+void
+GNUNET_CORE_monitor_stop (struct GNUNET_CORE_MonitorHandle *mh)
+{
+ if (NULL != mh->th)
+ {
+ GNUNET_CLIENT_notify_transmit_ready_cancel (mh->th);
+ mh->th = NULL;
+ }
+ if (NULL != mh->client)
+ {
+ GNUNET_CLIENT_disconnect (mh->client);
+ mh->client = NULL;
+ }
+ GNUNET_free (mh);
}
-/* end of core_api_iterate_peers.c */
+
+/* end of core_api_monitor_peers.c */
Modified: gnunet/src/core/gnunet-core.c
===================================================================
--- gnunet/src/core/gnunet-core.c 2014-04-10 17:05:39 UTC (rev 33031)
+++ gnunet/src/core/gnunet-core.c 2014-04-11 11:49:51 UTC (rev 33032)
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- (C) 2011, 2012 Christian Grothoff (and other contributing authors)
+ (C) 2011, 2012, 2014 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
@@ -24,14 +24,10 @@
* @author Nathan Evans
*/
#include "platform.h"
-#include "gnunet_crypto_lib.h"
-#include "gnunet_configuration_lib.h"
-#include "gnunet_getopt_lib.h"
-#include "gnunet_peerinfo_service.h"
-#include "gnunet_transport_service.h"
+#include "gnunet_util_lib.h"
#include "gnunet_core_service.h"
-#include "gnunet_program_lib.h"
+
/**
* Option -m.
*/
@@ -40,11 +36,13 @@
/**
* Current number of connections in monitor mode
*/
-static int monitor_connections_counter;
+// static unsigned int monitor_connections_counter;
-static struct GNUNET_CORE_Handle *ch;
+/**
+ * Handle to the CORE monitor.
+ */
+static struct GNUNET_CORE_MonitorHandle *mh;
-static struct GNUNET_PeerIdentity my_id;
/**
* Task run in monitor mode when the user presses CTRL-C to abort.
@@ -57,143 +55,81 @@
shutdown_task (void *cls,
const struct GNUNET_SCHEDULER_TaskContext *tc)
{
- if (NULL != ch)
+ if (NULL != mh)
{
- GNUNET_CORE_disconnect (ch);
- ch = NULL;
+ GNUNET_CORE_monitor_stop (mh);
+ mh = NULL;
}
}
/**
- * Callback for retrieving a list of connected peers.
- *
- * @param cls closure (unused)
- * @param peer peer identity this notification is about
- */
-static void
-connected_peer_callback (void *cls,
- const struct GNUNET_PeerIdentity *peer)
-{
- if (NULL == peer)
- return;
- printf (_("Peer `%s'\n"),
- GNUNET_i2s_full (peer));
-}
-
-
-static void
-monitor_notify_startup (void *cls,
- const struct GNUNET_PeerIdentity *my_identity)
-{
- my_id = (*my_identity);
-}
-
-
-/**
* Function called to notify core users that another
- * peer connected to us.
+ * peer changed its state with us.
*
* @param cls closure
- * @param peer the peer that connected
+ * @param peer the peer that changed state
+ * @param state new state of the peer
+ * @param timeout timeout for the new state
*/
static void
-monitor_notify_connect (void *cls, const struct GNUNET_PeerIdentity *peer)
+monitor_cb (void *cls,
+ const struct GNUNET_PeerIdentity *peer,
+ enum GNUNET_CORE_KxState state,
+ struct GNUNET_TIME_Absolute timeout)
{
struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get();
const char *now_str;
- if (0 != memcmp (&my_id, peer, sizeof (my_id)))
+ if ( (NULL == peer) &&
+ (GNUNET_NO == monitor_connections) )
{
- monitor_connections_counter ++;
- now_str = GNUNET_STRINGS_absolute_time_to_string (now);
- FPRINTF (stdout, _("%24s: %-17s %4s (%u connections in total)\n"),
- now_str,
- _("Connected to"),
- GNUNET_i2s (peer),
- monitor_connections_counter);
+ GNUNET_SCHEDULER_shutdown ();
+ return;
}
+ now_str = GNUNET_STRINGS_absolute_time_to_string (now);
+ FPRINTF (stdout,
+ _("%24s: %-17s %d %4s\n"),
+ now_str,
+ "FIXME",
+ state,
+ GNUNET_i2s (peer));
}
/**
- * Function called to notify core users that another
- * peer disconnected from us.
- *
- * @param cls closure
- * @param peer the peer that disconnected
- */
-static void
-monitor_notify_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
-{
- struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get();
- const char *now_str;
-
- if (0 != memcmp (&my_id, peer, sizeof (my_id)))
- {
- now_str = GNUNET_STRINGS_absolute_time_to_string (now);
-
- GNUNET_assert (monitor_connections_counter > 0);
- monitor_connections_counter--;
- FPRINTF (stdout, _("%24s: %-17s %4s (%u connections in total)\n"),
- now_str,
- _("Disconnected from"),
- GNUNET_i2s (peer),
- monitor_connections_counter);
- }
-}
-
-/**
- * Function called with the result of the check if the 'transport'
+ * Function called with the result of the check if the CORE
* service is running.
*
* @param cls closure with our configuration
- * @param result #GNUNET_YES if transport is running
+ * @param result #GNUNET_YES if CORE is running
*/
static void
-testservice_task (void *cls, int result)
+testservice_task (void *cls,
+ int result)
{
const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
- static const struct GNUNET_CORE_MessageHandler handlers[] = {
- {NULL, 0, 0}
- };
- if (result != GNUNET_OK)
- {
- FPRINTF (stderr, _("Service `%s' is not running\n"), "core");
- return;
- }
-
- if (GNUNET_NO == monitor_connections)
+ if (GNUNET_OK != result)
{
- if (GNUNET_OK != GNUNET_CORE_iterate_peers (cfg, &connected_peer_callback,
NULL))
- {
- fprintf (stderr, ("Failed to connect to CORE service to iterate
peers!\n"));
- return;
- }
+ FPRINTF (stderr, _("Service `%s' is not running\n"), "core");
+ return;
}
- else
+
+ mh = GNUNET_CORE_monitor_start (cfg,
+ &monitor_cb,
+ NULL);
+ if (NULL == mh)
{
- memset(&my_id, '\0', sizeof (my_id));
- ch = GNUNET_CORE_connect (cfg, NULL,
- monitor_notify_startup,
- monitor_notify_connect,
- monitor_notify_disconnect,
- NULL, GNUNET_NO,
- NULL, GNUNET_NO,
- handlers);
-
- if (NULL == ch)
- {
- GNUNET_SCHEDULER_add_now (shutdown_task, NULL);
- fprintf (stderr, ("Failed to connect to CORE service!\n"));
- return;
- }
- else
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
shutdown_task, NULL);
+ GNUNET_SCHEDULER_add_now (shutdown_task, NULL);
+ fprintf (stderr, ("Failed to connect to CORE service!\n"));
+ return;
}
+ GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
+ &shutdown_task, NULL);
}
+
/**
* Main function that will be run by the scheduler.
*
@@ -206,19 +142,21 @@
run (void *cls, char *const *args, const char *cfgfile,
const struct GNUNET_CONFIGURATION_Handle *cfg)
{
- if (args[0] != NULL)
+ if (NULL != args[0])
{
- FPRINTF (stderr, _("Invalid command line argument `%s'\n"), args[0]);
+ FPRINTF (stderr,
+ _("Invalid command line argument `%s'\n"),
+ args[0]);
return;
}
-
- GNUNET_CLIENT_service_test ("core", cfg, GNUNET_TIME_UNIT_SECONDS,
- &testservice_task, (void *) cfg);
+ GNUNET_CLIENT_service_test ("core", cfg,
+ GNUNET_TIME_UNIT_SECONDS,
+ &testservice_task, (void *) cfg);
}
/**
- * The main function to obtain peer information.
+ * The main function to obtain peer information from CORE.
*
* @param argc number of arguments from the command line
* @param argv command line arguments
@@ -237,19 +175,15 @@
if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
return 2;
-
-
res = GNUNET_PROGRAM_run (argc, argv, "gnunet-core",
- gettext_noop
- ("Print information about connected peers."),
- options, &run, NULL);
+ gettext_noop
+ ("Print information about connected peers."),
+ options, &run, NULL);
GNUNET_free ((void *) argv);
-
if (GNUNET_OK == res)
return 0;
- else
- return 1;
+ return 1;
}
/* end of gnunet-core.c */
Modified: gnunet/src/core/gnunet-service-core.c
===================================================================
--- gnunet/src/core/gnunet-service-core.c 2014-04-10 17:05:39 UTC (rev
33031)
+++ gnunet/src/core/gnunet-service-core.c 2014-04-11 11:49:51 UTC (rev
33032)
@@ -101,20 +101,21 @@
&keyfile))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- _
- ("Core service is lacking HOSTKEY configuration setting.
Exiting.\n"));
+ _("Core service is lacking HOSTKEY configuration setting.
Exiting.\n"));
GNUNET_SCHEDULER_shutdown ();
return;
}
GSC_stats = GNUNET_STATISTICS_create ("core", GSC_cfg);
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
+ GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
+ &shutdown_task,
NULL);
GNUNET_SERVER_suspend (server);
GSC_TYPEMAP_init ();
pk = GNUNET_CRYPTO_eddsa_key_create_from_file (keyfile);
GNUNET_free (keyfile);
GNUNET_assert (NULL != pk);
- if ((GNUNET_OK != GSC_KX_init (pk)) ||
+ if ((GNUNET_OK != GSC_KX_init (pk,
+ server)) ||
(GNUNET_OK != GSC_NEIGHBOURS_init ()))
{
GNUNET_SCHEDULER_shutdown ();
@@ -123,7 +124,8 @@
GSC_SESSIONS_init ();
GSC_CLIENTS_init (GSC_server);
GNUNET_SERVER_resume (GSC_server);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Core service of `%4s' ready.\n"),
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ _("Core service of `%4s' ready.\n"),
GNUNET_i2s (&GSC_my_identity));
}
@@ -139,7 +141,8 @@
main (int argc, char *const *argv)
{
return (GNUNET_OK ==
- GNUNET_SERVICE_run (argc, argv, "core", GNUNET_SERVICE_OPTION_NONE,
+ GNUNET_SERVICE_run (argc, argv, "core",
+ GNUNET_SERVICE_OPTION_NONE,
&run, NULL)) ? 0 : 1;
}
Modified: gnunet/src/core/gnunet-service-core_clients.c
===================================================================
--- gnunet/src/core/gnunet-service-core_clients.c 2014-04-10 17:05:39 UTC
(rev 33031)
+++ gnunet/src/core/gnunet-service-core_clients.c 2014-04-11 11:49:51 UTC
(rev 33032)
@@ -600,11 +600,12 @@
* @param client identification of the client
*/
static void
-handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
+handle_client_disconnect (void *cls,
+ struct GNUNET_SERVER_Client *client)
{
struct GSC_Client *c;
- if (client == NULL)
+ if (NULL == client)
return;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Client %p has disconnected from core service.\n", client);
@@ -840,8 +841,8 @@
static const struct GNUNET_SERVER_MessageHandler handlers[] = {
{&handle_client_init, NULL,
GNUNET_MESSAGE_TYPE_CORE_INIT, 0},
- {&GSC_SESSIONS_handle_client_iterate_peers, NULL,
- GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS,
+ {&GSC_KX_handle_client_monitor_peers, NULL,
+ GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS,
sizeof (struct GNUNET_MessageHeader)},
{&handle_client_send_request, NULL,
GNUNET_MESSAGE_TYPE_CORE_SEND_REQUEST,
@@ -855,7 +856,8 @@
client_mst = GNUNET_SERVER_mst_create (&client_tokenizer_callback, NULL);
notifier =
GNUNET_SERVER_notification_context_create (server, MAX_NOTIFY_QUEUE);
- GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL);
+ GNUNET_SERVER_disconnect_notify (server,
+ &handle_client_disconnect, NULL);
GNUNET_SERVER_add_handlers (server, handlers);
}
Modified: gnunet/src/core/gnunet-service-core_kx.c
===================================================================
--- gnunet/src/core/gnunet-service-core_kx.c 2014-04-10 17:05:39 UTC (rev
33031)
+++ gnunet/src/core/gnunet-service-core_kx.c 2014-04-11 11:49:51 UTC (rev
33032)
@@ -237,50 +237,6 @@
/**
- * State machine for our P2P encryption handshake. Everyone starts in
- * "DOWN", if we receive the other peer's key (other peer initiated)
- * we start in state RECEIVED (since we will immediately send our
- * own); otherwise we start in SENT. If we get back a PONG from
- * within either state, we move up to CONFIRMED (the PONG will always
- * be sent back encrypted with the key we sent to the other peer).
- */
-enum KxStateMachine
-{
- /**
- * No handshake yet.
- */
- KX_STATE_DOWN,
-
- /**
- * We've sent our session key.
- */
- KX_STATE_KEY_SENT,
-
- /**
- * We've received the other peers session key.
- */
- KX_STATE_KEY_RECEIVED,
-
- /**
- * The other peer has confirmed our session key + PING with a PONG
- * message encrypted with his session key (which we got). Key
- * exchange is done.
- */
- KX_STATE_UP,
-
- /**
- * We're rekeying (or had a timeout), so we have sent the other peer
- * our new ephemeral key, but we did not get a matching PONG yet.
- * This is equivalent to being 'KX_STATE_KEY_RECEIVED', except that
- * the session is marked as 'up' with sessions (as we don't want to
- * drop and re-establish P2P connections simply due to rekeying).
- */
- KX_STATE_REKEY_SENT
-
-};
-
-
-/**
* Information about the status of a key exchange with another peer.
*/
struct GSC_KeyExchangeInfo
@@ -373,7 +329,7 @@
/**
* What is our connection status?
*/
- enum KxStateMachine status;
+ enum GNUNET_CORE_KxState status;
};
@@ -414,8 +370,59 @@
*/
static GNUNET_SCHEDULER_TaskIdentifier rekey_task;
+/**
+ * Notification context for all monitors.
+ */
+static struct GNUNET_SERVER_NotificationContext *nc;
+
/**
+ * Inform the given monitor about the KX state of
+ * the given peer.
+ *
+ * @param mc monitor to inform
+ * @param kx key exchange state to inform about
+ */
+static void
+monitor_notify (struct GNUNET_SERVER_Client *client,
+ struct GSC_KeyExchangeInfo *kx)
+{
+ struct MonitorNotifyMessage msg;
+
+ msg.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY);
+ msg.header.size = htons (sizeof (msg));
+ msg.state = htonl ((uint32_t) kx->status);
+ msg.peer = kx->peer;
+ msg.timeout = GNUNET_TIME_absolute_hton (kx->timeout);
+ GNUNET_SERVER_notification_context_unicast (nc,
+ client,
+ &msg.header,
+ GNUNET_NO);
+}
+
+
+/**
+ * Inform all monitors about the KX state of the given peer.
+ *
+ * @param kx key exchange state to inform about
+ */
+static void
+monitor_notify_all (struct GSC_KeyExchangeInfo *kx)
+{
+ struct MonitorNotifyMessage msg;
+
+ msg.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY);
+ msg.header.size = htons (sizeof (msg));
+ msg.state = htonl ((uint32_t) kx->status);
+ msg.peer = kx->peer;
+ msg.timeout = GNUNET_TIME_absolute_hton (kx->timeout);
+ GNUNET_SERVER_notification_context_broadcast (nc,
+ &msg.header,
+ GNUNET_NO);
+}
+
+
+/**
* Derive an authentication key from "set key" information
*
* @param akey authentication key to derive
@@ -570,8 +577,9 @@
GNUNET_break (0);
return GNUNET_NO;
}
- if ( (kx->status != KX_STATE_KEY_RECEIVED) && (kx->status != KX_STATE_UP) &&
- (kx->status != KX_STATE_REKEY_SENT) )
+ if ( (kx->status != GNUNET_CORE_KX_STATE_KEY_RECEIVED) &&
+ (kx->status != GNUNET_CORE_KX_STATE_UP) &&
+ (kx->status != GNUNET_CORE_KX_STATE_REKEY_SENT) )
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
@@ -622,7 +630,7 @@
kx->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK;
kx->set_key_retry_frequency = GNUNET_TIME_STD_BACKOFF
(kx->set_key_retry_frequency);
- GNUNET_assert (KX_STATE_DOWN != kx->status);
+ GNUNET_assert (GNUNET_CORE_KX_STATE_DOWN != kx->status);
send_key (kx);
}
@@ -678,10 +686,14 @@
GNUNET_CONTAINER_DLL_insert (kx_head,
kx_tail,
kx);
- GNUNET_CRYPTO_hash (pid, sizeof (struct GNUNET_PeerIdentity), &h1);
- GNUNET_CRYPTO_hash (&GSC_my_identity, sizeof (struct GNUNET_PeerIdentity),
&h2);
-
- kx->status = KX_STATE_KEY_SENT;
+ kx->status = GNUNET_CORE_KX_STATE_KEY_SENT;
+ monitor_notify_all (kx);
+ GNUNET_CRYPTO_hash (pid,
+ sizeof (struct GNUNET_PeerIdentity),
+ &h1);
+ GNUNET_CRYPTO_hash (&GSC_my_identity,
+ sizeof (struct GNUNET_PeerIdentity),
+ &h2);
if (0 < GNUNET_CRYPTO_hash_cmp (&h1,
&h2))
{
@@ -722,6 +734,8 @@
GNUNET_SCHEDULER_cancel (kx->keep_alive_task);
kx->keep_alive_task = GNUNET_SCHEDULER_NO_TASK;
}
+ kx->status = GNUNET_CORE_KX_PEER_DISCONNECT;
+ monitor_notify_all (kx);
GNUNET_CONTAINER_DLL_remove (kx_head,
kx_tail,
kx);
@@ -791,7 +805,7 @@
struct GNUNET_TIME_Absolute start_t;
struct GNUNET_TIME_Absolute end_t;
struct GNUNET_TIME_Absolute now;
- enum KxStateMachine sender_status;
+ enum GNUNET_CORE_KxState sender_status;
uint16_t size;
size = ntohs (msg->size);
@@ -802,9 +816,9 @@
}
m = (const struct EphemeralKeyMessage *) msg;
end_t = GNUNET_TIME_absolute_ntoh (m->expiration_time);
- if ( ( (KX_STATE_KEY_RECEIVED == kx->status) ||
- (KX_STATE_UP == kx->status) ||
- (KX_STATE_REKEY_SENT == kx->status) ) &&
+ if ( ( (GNUNET_CORE_KX_STATE_KEY_RECEIVED == kx->status) ||
+ (GNUNET_CORE_KX_STATE_UP == kx->status) ||
+ (GNUNET_CORE_KX_STATE_REKEY_SENT == kx->status) ) &&
(end_t.abs_value_us <= kx->foreign_key_expires.abs_value_us) )
{
GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# old ephemeral keys
ignored"),
@@ -862,18 +876,18 @@
GNUNET_NO);
/* check if we still need to send the sender our key */
- sender_status = (enum KxStateMachine) ntohl (m->sender_status);
+ sender_status = (enum GNUNET_CORE_KxState) ntohl (m->sender_status);
switch (sender_status)
{
- case KX_STATE_DOWN:
+ case GNUNET_CORE_KX_STATE_DOWN:
GNUNET_break_op (0);
break;
- case KX_STATE_KEY_SENT:
+ case GNUNET_CORE_KX_STATE_KEY_SENT:
/* fine, need to send our key after updating our status, see below */
break;
- case KX_STATE_KEY_RECEIVED:
- case KX_STATE_UP:
- case KX_STATE_REKEY_SENT:
+ case GNUNET_CORE_KX_STATE_KEY_RECEIVED:
+ case GNUNET_CORE_KX_STATE_UP:
+ case GNUNET_CORE_KX_STATE_REKEY_SENT:
/* other peer already got our key */
break;
default:
@@ -883,35 +897,38 @@
/* check if we need to confirm everything is fine via PING + PONG */
switch (kx->status)
{
- case KX_STATE_DOWN:
+ case GNUNET_CORE_KX_STATE_DOWN:
GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == kx->keep_alive_task);
- kx->status = KX_STATE_KEY_RECEIVED;
- if (KX_STATE_KEY_SENT == sender_status)
+ kx->status = GNUNET_CORE_KX_STATE_KEY_RECEIVED;
+ monitor_notify_all (kx);
+ if (GNUNET_CORE_KX_STATE_KEY_SENT == sender_status)
send_key (kx);
send_ping (kx);
break;
- case KX_STATE_KEY_SENT:
+ case GNUNET_CORE_KX_STATE_KEY_SENT:
GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == kx->keep_alive_task);
- kx->status = KX_STATE_KEY_RECEIVED;
- if (KX_STATE_KEY_SENT == sender_status)
+ kx->status = GNUNET_CORE_KX_STATE_KEY_RECEIVED;
+ monitor_notify_all (kx);
+ if (GNUNET_CORE_KX_STATE_KEY_SENT == sender_status)
send_key (kx);
send_ping (kx);
break;
- case KX_STATE_KEY_RECEIVED:
+ case GNUNET_CORE_KX_STATE_KEY_RECEIVED:
GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == kx->keep_alive_task);
- if (KX_STATE_KEY_SENT == sender_status)
+ if (GNUNET_CORE_KX_STATE_KEY_SENT == sender_status)
send_key (kx);
send_ping (kx);
break;
- case KX_STATE_UP:
- kx->status = KX_STATE_REKEY_SENT;
- if (KX_STATE_KEY_SENT == sender_status)
+ case GNUNET_CORE_KX_STATE_UP:
+ kx->status = GNUNET_CORE_KX_STATE_REKEY_SENT;
+ monitor_notify_all (kx);
+ if (GNUNET_CORE_KX_STATE_KEY_SENT == sender_status)
send_key (kx);
/* we got a new key, need to reconfirm! */
send_ping (kx);
break;
- case KX_STATE_REKEY_SENT:
- if (KX_STATE_KEY_SENT == sender_status)
+ case GNUNET_CORE_KX_STATE_REKEY_SENT:
+ if (GNUNET_CORE_KX_STATE_KEY_SENT == sender_status)
send_key (kx);
/* we got a new key, need to reconfirm! */
send_ping (kx);
@@ -950,9 +967,9 @@
GNUNET_STATISTICS_update (GSC_stats,
gettext_noop ("# PING messages received"), 1,
GNUNET_NO);
- if ( (kx->status != KX_STATE_KEY_RECEIVED) &&
- (kx->status != KX_STATE_UP) &&
- (kx->status != KX_STATE_REKEY_SENT))
+ if ( (kx->status != GNUNET_CORE_KX_STATE_KEY_RECEIVED) &&
+ (kx->status != GNUNET_CORE_KX_STATE_UP) &&
+ (kx->status != GNUNET_CORE_KX_STATE_REKEY_SENT))
{
/* ignore */
GNUNET_STATISTICS_update (GSC_stats,
@@ -1029,7 +1046,8 @@
gettext_noop ("# sessions terminated by
timeout"),
1, GNUNET_NO);
GSC_SESSIONS_end (&kx->peer);
- kx->status = KX_STATE_KEY_SENT;
+ kx->status = GNUNET_CORE_KX_STATE_KEY_SENT;
+ monitor_notify_all (kx);
send_key (kx);
return;
}
@@ -1097,21 +1115,21 @@
GNUNET_NO);
switch (kx->status)
{
- case KX_STATE_DOWN:
+ case GNUNET_CORE_KX_STATE_DOWN:
GNUNET_STATISTICS_update (GSC_stats,
gettext_noop ("# PONG messages dropped
(connection down)"), 1,
GNUNET_NO);
return;
- case KX_STATE_KEY_SENT:
+ case GNUNET_CORE_KX_STATE_KEY_SENT:
GNUNET_STATISTICS_update (GSC_stats,
gettext_noop ("# PONG messages dropped (out of
order)"), 1,
GNUNET_NO);
return;
- case KX_STATE_KEY_RECEIVED:
+ case GNUNET_CORE_KX_STATE_KEY_RECEIVED:
break;
- case KX_STATE_UP:
+ case GNUNET_CORE_KX_STATE_UP:
break;
- case KX_STATE_REKEY_SENT:
+ case GNUNET_CORE_KX_STATE_REKEY_SENT:
break;
default:
GNUNET_break (0);
@@ -1159,35 +1177,37 @@
}
switch (kx->status)
{
- case KX_STATE_DOWN:
+ case GNUNET_CORE_KX_STATE_DOWN:
GNUNET_assert (0); /* should be impossible */
return;
- case KX_STATE_KEY_SENT:
+ case GNUNET_CORE_KX_STATE_KEY_SENT:
GNUNET_assert (0); /* should be impossible */
return;
- case KX_STATE_KEY_RECEIVED:
+ case GNUNET_CORE_KX_STATE_KEY_RECEIVED:
GNUNET_STATISTICS_update (GSC_stats,
gettext_noop
("# session keys confirmed via PONG"), 1,
GNUNET_NO);
- kx->status = KX_STATE_UP;
+ kx->status = GNUNET_CORE_KX_STATE_UP;
+ monitor_notify_all (kx);
GSC_SESSIONS_create (&kx->peer, kx);
GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == kx->keep_alive_task);
update_timeout (kx);
break;
- case KX_STATE_UP:
+ case GNUNET_CORE_KX_STATE_UP:
GNUNET_STATISTICS_update (GSC_stats,
gettext_noop
("# timeouts prevented via PONG"), 1,
GNUNET_NO);
update_timeout (kx);
break;
- case KX_STATE_REKEY_SENT:
+ case GNUNET_CORE_KX_STATE_REKEY_SENT:
GNUNET_STATISTICS_update (GSC_stats,
gettext_noop
("# rekey operations confirmed via PONG"), 1,
GNUNET_NO);
- kx->status = KX_STATE_UP;
+ kx->status = GNUNET_CORE_KX_STATE_UP;
+ monitor_notify_all (kx);
update_timeout (kx);
break;
default:
@@ -1205,7 +1225,7 @@
static void
send_key (struct GSC_KeyExchangeInfo *kx)
{
- GNUNET_assert (KX_STATE_DOWN != kx->status);
+ GNUNET_assert (GNUNET_CORE_KX_STATE_DOWN != kx->status);
if (GNUNET_SCHEDULER_NO_TASK != kx->retry_set_key_task)
{
GNUNET_SCHEDULER_cancel (kx->retry_set_key_task);
@@ -1321,7 +1341,7 @@
return;
}
m = (const struct EncryptedMessage *) msg;
- if (KX_STATE_UP != kx->status)
+ if (GNUNET_CORE_KX_STATE_UP != kx->status)
{
GNUNET_STATISTICS_update (GSC_stats,
gettext_noop
@@ -1343,7 +1363,8 @@
GNUNET_SCHEDULER_cancel (kx->keep_alive_task);
kx->keep_alive_task = GNUNET_SCHEDULER_NO_TASK;
}
- kx->status = KX_STATE_KEY_SENT;
+ kx->status = GNUNET_CORE_KX_STATE_KEY_SENT;
+ monitor_notify_all (kx);
send_key (kx);
return;
}
@@ -1473,7 +1494,7 @@
{
struct DeliverMessageContext *dmc = client;
- if (KX_STATE_UP != dmc->kx->status)
+ if (GNUNET_CORE_KX_STATE_UP != dmc->kx->status)
{
GNUNET_STATISTICS_update (GSC_stats,
gettext_noop
@@ -1560,15 +1581,18 @@
sign_ephemeral_key ();
for (pos = kx_head; NULL != pos; pos = pos->next)
{
- if (KX_STATE_UP == pos->status)
+ if (GNUNET_CORE_KX_STATE_UP == pos->status)
{
- pos->status = KX_STATE_REKEY_SENT;
+ pos->status = GNUNET_CORE_KX_STATE_REKEY_SENT;
+ monitor_notify_all (pos);
derive_session_keys (pos);
}
- if (KX_STATE_DOWN == pos->status)
+ if (GNUNET_CORE_KX_STATE_DOWN == pos->status)
{
- pos->status = KX_STATE_KEY_SENT;
+ pos->status = GNUNET_CORE_KX_STATE_KEY_SENT;
+ monitor_notify_all (pos);
}
+ monitor_notify_all (pos);
send_key (pos);
}
}
@@ -1578,11 +1602,15 @@
* Initialize KX subsystem.
*
* @param pk private key to use for the peer
+ * @param server the server of the CORE service
* @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
*/
int
-GSC_KX_init (struct GNUNET_CRYPTO_EddsaPrivateKey *pk)
+GSC_KX_init (struct GNUNET_CRYPTO_EddsaPrivateKey *pk,
+ struct GNUNET_SERVER_Handle *server)
{
+ nc = GNUNET_SERVER_notification_context_create (server,
+ 1);
my_private_key = pk;
GNUNET_CRYPTO_eddsa_key_get_public (my_private_key,
&GSC_my_identity.public_key);
@@ -1629,6 +1657,46 @@
GNUNET_SERVER_mst_destroy (mst);
mst = NULL;
}
+ if (NULL != nc)
+ {
+ GNUNET_SERVER_notification_context_destroy (nc);
+ nc = NULL;
+ }
}
+
+/**
+ * Handle #GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS request. For this
+ * request type, the client does not have to have transmitted an INIT
+ * request. All current peers are returned, regardless of which
+ * message types they accept.
+ *
+ * @param cls unused
+ * @param client client sending the iteration request
+ * @param message iteration request message
+ */
+void
+GSC_KX_handle_client_monitor_peers (void *cls,
+ struct GNUNET_SERVER_Client *client,
+ const struct GNUNET_MessageHeader *message)
+{
+ struct MonitorNotifyMessage done_msg;
+ struct GSC_KeyExchangeInfo *kx;
+
+ GNUNET_SERVER_notification_context_add (nc,
+ client);
+ for (kx = kx_head; NULL != kx; kx = kx->next)
+ monitor_notify (client, kx);
+ done_msg.header.size = htons (sizeof (struct MonitorNotifyMessage));
+ done_msg.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY);
+ done_msg.state = htonl ((uint32_t) GNUNET_CORE_KX_ITERATION_FINISHED);
+ memset (&done_msg.peer, 0, sizeof (struct GNUNET_PeerIdentity));
+ done_msg.timeout = GNUNET_TIME_absolute_hton (GNUNET_TIME_UNIT_FOREVER_ABS);
+ GNUNET_SERVER_notification_context_unicast (nc,
+ client,
+ &done_msg.header,
+ GNUNET_NO);
+}
+
+
/* end of gnunet-service-core_kx.c */
Modified: gnunet/src/core/gnunet-service-core_kx.h
===================================================================
--- gnunet/src/core/gnunet-service-core_kx.h 2014-04-10 17:05:39 UTC (rev
33031)
+++ gnunet/src/core/gnunet-service-core_kx.h 2014-04-11 11:49:51 UTC (rev
33032)
@@ -118,10 +118,12 @@
* Initialize KX subsystem.
*
* @param pk private key to use for the peer
+ * @param server the server of the CORE service
* @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
*/
int
-GSC_KX_init (struct GNUNET_CRYPTO_EddsaPrivateKey *pk);
+GSC_KX_init (struct GNUNET_CRYPTO_EddsaPrivateKey *pk,
+ struct GNUNET_SERVER_Handle *server);
/**
@@ -130,5 +132,22 @@
void
GSC_KX_done (void);
+
+/**
+ * Handle #GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS request. For this
+ * request type, the client does not have to have transmitted an INIT
+ * request. All current peers are returned, regardless of which
+ * message types they accept.
+ *
+ * @param cls unused
+ * @param client client sending the iteration request
+ * @param message iteration request message
+ */
+void
+GSC_KX_handle_client_monitor_peers (void *cls,
+ struct GNUNET_SERVER_Client *client,
+ const struct GNUNET_MessageHeader
*message);
+
+
#endif
/* end of gnunet-service-core_kx.h */
Modified: gnunet/src/core/gnunet-service-core_sessions.c
===================================================================
--- gnunet/src/core/gnunet-service-core_sessions.c 2014-04-10 17:05:39 UTC
(rev 33031)
+++ gnunet/src/core/gnunet-service-core_sessions.c 2014-04-11 11:49:51 UTC
(rev 33032)
@@ -732,59 +732,6 @@
/**
- * Helper function for #GSC_SESSIONS_handle_client_iterate_peers().
- *
- * @param cls the `struct GNUNET_SERVER_TransmitContext` to queue replies
- * @param key identity of the connected peer
- * @param value the `struct Neighbour` for the peer
- * @return #GNUNET_OK (continue to iterate)
- */
-static int
-queue_connect_message (void *cls,
- const struct GNUNET_PeerIdentity *key,
- void *value)
-{
- struct GNUNET_SERVER_TransmitContext *tc = cls;
- struct Session *session = value;
- struct ConnectNotifyMessage cnm;
-
- /* FIXME: code duplication with clients... */
- cnm.header.size = htons (sizeof (struct ConnectNotifyMessage));
- cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
- cnm.reserved = htonl (0);
- cnm.peer = session->peer;
- GNUNET_SERVER_transmit_context_append_message (tc, &cnm.header);
- return GNUNET_OK;
-}
-
-
-/**
- * Handle CORE_ITERATE_PEERS request. For this request type, the client
- * does not have to have transmitted an INIT request. All current peers
- * are returned, regardless of which message types they accept.
- *
- * @param cls unused
- * @param client client sending the iteration request
- * @param message iteration request message
- */
-void
-GSC_SESSIONS_handle_client_iterate_peers (void *cls,
- struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader
*message)
-{
- struct GNUNET_MessageHeader done_msg;
- struct GNUNET_SERVER_TransmitContext *tc;
-
- tc = GNUNET_SERVER_transmit_context_create (client);
- GNUNET_CONTAINER_multipeermap_iterate (sessions, &queue_connect_message, tc);
- done_msg.size = htons (sizeof (struct GNUNET_MessageHeader));
- done_msg.type = htons (GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS_END);
- GNUNET_SERVER_transmit_context_append_message (tc, &done_msg);
- GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
-}
-
-
-/**
* We've received a typemap message from a peer, update ours.
* Notifies clients about the session.
*
Modified: gnunet/src/core/gnunet-service-core_sessions.h
===================================================================
--- gnunet/src/core/gnunet-service-core_sessions.h 2014-04-10 17:05:39 UTC
(rev 33031)
+++ gnunet/src/core/gnunet-service-core_sessions.h 2014-04-11 11:49:51 UTC
(rev 33032)
@@ -118,6 +118,7 @@
void
GSC_SESSIONS_notify_client_about_sessions (struct GSC_Client *client);
+
/**
* We've received a typemap message from a peer, update ours.
* Notifies clients about the session.
@@ -144,22 +145,6 @@
/**
- * Handle CORE_ITERATE_PEERS request. For this request type, the client
- * does not have to have transmitted an INIT request. All current peers
- * are returned, regardless of which message types they accept.
- *
- * @param cls unused
- * @param client client sending the iteration request
- * @param message iteration request message
- */
-void
-GSC_SESSIONS_handle_client_iterate_peers (void *cls,
- struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader
- *message);
-
-
-/**
* Initialize sessions subsystem.
*/
void
Modified: gnunet/src/include/gnunet_core_service.h
===================================================================
--- gnunet/src/include/gnunet_core_service.h 2014-04-10 17:05:39 UTC (rev
33031)
+++ gnunet/src/include/gnunet_core_service.h 2014-04-11 11:49:51 UTC (rev
33032)
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- (C) 2009-2013 Christian Grothoff (and other contributing authors)
+ (C) 2009-2014 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
@@ -280,34 +280,135 @@
* @param th handle that was returned by "notify_transmit_ready".
*/
void
-GNUNET_CORE_notify_transmit_ready_cancel (struct GNUNET_CORE_TransmitHandle
- *th);
+GNUNET_CORE_notify_transmit_ready_cancel (struct GNUNET_CORE_TransmitHandle
*th);
/**
- * Iterate over all connected peers. Calls @a peer_cb with each
- * connected peer, and then once with NULL to indicate that all peers
- * have been handled. Normal users of the CORE API are not expected
- * to use this function. It is different in that it truly lists
- * all connections, not just those relevant to the application. This
- * function is used by special applications for diagnostics. This
- * function is NOT part of the 'versioned', 'official' API.
+ * Handle to a CORE monitoring operation.
+ */
+struct GNUNET_CORE_MonitorHandle;
+
+
+/**
+ * State machine for our P2P encryption handshake. Everyone starts in
+ * #GNUNET_CORE_KX_STATE_DOWN, if we receive the other peer's key
+ * (other peer initiated) we start in state
+ * #GNUNET_CORE_KX_STATE_KEY_RECEIVED (since we will immediately send
+ * our own); otherwise we start in #GNUNET_CORE_KX_STATE_KEY_SENT. If
+ * we get back a PONG from within either state, we move up to
+ * #GNUNET_CORE_KX_STATE_UP (the PONG will always be sent back
+ * encrypted with the key we sent to the other peer). Eventually,
+ * we will try to rekey, for this we will enter
+ * #GNUNET_CORE_KX_STATE_REKEY_SENT until the rekey operation is
+ * confirmed by a PONG from the other peer.
+ */
+enum GNUNET_CORE_KxState
+{
+ /**
+ * No handshake yet.
+ */
+ GNUNET_CORE_KX_STATE_DOWN,
+
+ /**
+ * We've sent our session key.
+ */
+ GNUNET_CORE_KX_STATE_KEY_SENT,
+
+ /**
+ * We've received the other peers session key.
+ */
+ GNUNET_CORE_KX_STATE_KEY_RECEIVED,
+
+ /**
+ * The other peer has confirmed our session key + PING with a PONG
+ * message encrypted with his session key (which we got). Key
+ * exchange is done.
+ */
+ GNUNET_CORE_KX_STATE_UP,
+
+ /**
+ * We're rekeying (or had a timeout), so we have sent the other peer
+ * our new ephemeral key, but we did not get a matching PONG yet.
+ * This is equivalent to being #GNUNET_CORE_KX_STATE_KEY_RECEIVED,
+ * except that the session is marked as 'up' with sessions (as we
+ * don't want to drop and re-establish P2P connections simply due to
+ * rekeying).
+ */
+ GNUNET_CORE_KX_STATE_REKEY_SENT,
+
+ /**
+ * Last state of a KX (when it is being terminated). Set
+ * just before CORE frees the internal state for this peer.
+ */
+ GNUNET_CORE_KX_PEER_DISCONNECT,
+
+ /**
+ * This is not a state in a peer's state machine, but a special
+ * value used with the #GNUNET_CORE_MonitorCallback to indicate
+ * that we finished the initial iteration over the peers.
+ */
+ GNUNET_CORE_KX_ITERATION_FINISHED,
+
+ /**
+ * This is not a state in a peer's state machine, but a special
+ * value used with the #GNUNET_CORE_MonitorCallback to indicate
+ * that we lost the connection to the CORE service (and will try
+ * to reconnect). If this happens, most likely the CORE service
+ * crashed and thus all connection state should be assumed lost.
+ */
+ GNUNET_CORE_KX_CORE_DISCONNECT
+
+};
+
+
+/**
+ * Function called by the monitor callback whenever
+ * a peer's connection status changes.
*
- * FIXME: we should probably make it possible to 'cancel' the
- * operation...
+ * @param cls closure
+ * @param pid identity of the peer this update is about
+ * @param state current key exchange state of the peer
+ * @param timeout when does the current state expire
+ */
+typedef void
+(*GNUNET_CORE_MonitorCallback)(void *cls,
+ const struct GNUNET_PeerIdentity *pid,
+ enum GNUNET_CORE_KxState state,
+ struct GNUNET_TIME_Absolute timeout);
+
+
+/**
+ * Monitor connectivity and KX status of all peers known to CORE.
+ * Calls @a peer_cb with the current status for each connected peer,
+ * and then once with NULL to indicate that all peers that are
+ * currently active have been handled. After that, the iteration
+ * continues until it is cancelled. Normal users of the CORE API are
+ * not expected to use this function. It is different in that it
+ * truly lists all connections (including those where the KX is in
+ * progress), not just those relevant to the application. This
+ * function is used by special applications for diagnostics.
*
* @param cfg configuration handle
* @param peer_cb function to call with the peer information
- * @param cb_cls closure for @a peer_cb
- * @return #GNUNET_OK on success, #GNUNET_SYSERR on errors
+ * @param peer_cb_cls closure for @a peer_cb
+ * @return NULL on error
*/
-int
-GNUNET_CORE_iterate_peers (const struct GNUNET_CONFIGURATION_Handle *cfg,
- GNUNET_CORE_ConnectEventHandler peer_cb,
- void *cb_cls);
+struct GNUNET_CORE_MonitorHandle *
+GNUNET_CORE_monitor_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ GNUNET_CORE_MonitorCallback peer_cb,
+ void *peer_cb_cls);
/**
+ * Stop monitoring CORE activity.
+ *
+ * @param mh monitor to stop
+ */
+void
+GNUNET_CORE_monitor_stop (struct GNUNET_CORE_MonitorHandle *mh);
+
+
+/**
* Check if the given peer is currently connected. This function is for special
* cirumstances (GNUNET_TESTBED uses it), normal users of the CORE API are
* expected to track which peers are connected based on the connect/disconnect
Modified: gnunet/src/include/gnunet_protocols.h
===================================================================
--- gnunet/src/include/gnunet_protocols.h 2014-04-10 17:05:39 UTC (rev
33031)
+++ gnunet/src/include/gnunet_protocols.h 2014-04-11 11:49:51 UTC (rev
33032)
@@ -334,14 +334,14 @@
#define GNUNET_MESSAGE_TYPE_CORE_SEND 76
/**
- * Request for peer iteration from CORE service.
+ * Request for connection monitoring from CORE service.
*/
-#define GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS 78
+#define GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS 78
/**
- * Last reply from core to request for peer iteration from CORE service.
+ * Reply for monitor by CORE service.
*/
-#define GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS_END 79
+#define GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY 79
/**
* Encapsulation for an encrypted message between peers.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r33032 - in gnunet/src: core include,
gnunet <=