From 20c42b92b71cb31bc5ed9cc4e4ff32efbd95aae4 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 27 Jan 2019 01:16:00 +0100 Subject: [PATCH] more work on #5385 --- src/cadet/Makefile.am | 1 + src/cadet/cadet_api_get_peer.c | 2 +- src/cadet/cadet_api_get_tunnel.c | 1 + src/cadet/cadet_api_list_tunnels.c | 149 +++++++++++++++++------------ src/include/gnunet_cadet_service.h | 4 +- 5 files changed, 95 insertions(+), 62 deletions(-) diff --git a/src/cadet/Makefile.am b/src/cadet/Makefile.am index 57a716f29..8f4cd20d4 100644 --- a/src/cadet/Makefile.am +++ b/src/cadet/Makefile.am @@ -37,6 +37,7 @@ libgnunetcadet_la_SOURCES = \ cadet_api_get_peer.c \ cadet_api_get_tunnel.c \ cadet_api_list_peers.c \ + cadet_api_list_tunnels.c \ cadet_api_helper.c libgnunetcadet_la_LIBADD = \ $(top_builddir)/src/util/libgnunetutil.la \ diff --git a/src/cadet/cadet_api_get_peer.c b/src/cadet/cadet_api_get_peer.c index bfac8d583..6276de3a4 100644 --- a/src/cadet/cadet_api_get_peer.c +++ b/src/cadet/cadet_api_get_peer.c @@ -231,7 +231,7 @@ reconnect (void *cls) * @param id Peer whose tunnel to examine. * @param callback Function to call with the requested data. * @param callback_cls Closure for @c callback. - * @return #GNUNET_OK / #GNUNET_SYSERR + * @return NULL on error */ struct GNUNET_CADET_GetPeer * GNUNET_CADET_get_peer (const struct GNUNET_CONFIGURATION_Handle *cfg, diff --git a/src/cadet/cadet_api_get_tunnel.c b/src/cadet/cadet_api_get_tunnel.c index 3b489dd82..1d2776352 100644 --- a/src/cadet/cadet_api_get_tunnel.c +++ b/src/cadet/cadet_api_get_tunnel.c @@ -150,6 +150,7 @@ handle_get_tunnel (void *cls, conns, ntohs (msg->estate), ntohs (msg->cstate)); + GNUNET_CADET_get_tunnel_cancel (gt); } diff --git a/src/cadet/cadet_api_list_tunnels.c b/src/cadet/cadet_api_list_tunnels.c index 7d0534e41..631b321b7 100644 --- a/src/cadet/cadet_api_list_tunnels.c +++ b/src/cadet/cadet_api_list_tunnels.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2011, 2017 GNUnet e.V. + Copyright (C) 2011, 2017, 2019 GNUnet e.V. GNUnet is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published @@ -70,26 +70,6 @@ struct GNUNET_CADET_ListTunnels }; -/** - * Send message of @a type to CADET service of @a h - * - * @param h handle to CADET service - * @param type message type of trivial information request to send - */ -static void -send_info_request (struct GNUNET_CADET_Handle *h, - uint16_t type) -{ - struct GNUNET_MessageHeader *msg; - struct GNUNET_MQ_Envelope *env; - - env = GNUNET_MQ_msg (msg, - type); - GNUNET_MQ_send (h->mq, - env); -} - - /** * Check that message received from CADET service is well-formed. * @@ -117,59 +97,99 @@ check_get_tunnels (void *cls, /** * Process a local reply about info on all tunnels, pass info to the user. * - * @param cls Closure (Cadet handle). + * @param cls a `struct GNUNET_CADET_ListTunnels *` * @param message Message itself. */ static void handle_get_tunnels (void *cls, const struct GNUNET_MessageHeader *msg) { - struct GNUNET_CADET_Handle *h = cls; + struct GNUNET_CADET_ListTunnels *lt = cls; const struct GNUNET_CADET_LocalInfoTunnel *info = (const struct GNUNET_CADET_LocalInfoTunnel *) msg; - if (NULL == h->info_cb.tunnels_cb) - return; + // FIXME: use two message types! if (sizeof (struct GNUNET_CADET_LocalInfoTunnel) == ntohs (msg->size)) - h->info_cb.tunnels_cb (h->info_cls, - &info->destination, - ntohl (info->channels), - ntohl (info->connections), - ntohs (info->estate), - ntohs (info->cstate)); + lt->tunnels_cb (lt->tunnels_cb_cls, + &info->destination, + ntohl (info->channels), + ntohl (info->connections), + ntohs (info->estate), + ntohs (info->cstate)); else - h->info_cb.tunnels_cb (h->info_cls, - NULL, - 0, - 0, - 0, - 0); + { + lt->tunnels_cb (lt->tunnels_cb_cls, + NULL, + 0, + 0, + 0, + 0); + GNUNET_CADET_list_tunnels_cancel (lt); + } } +/** + * Reconnect to the service and try again. + * + * @param cls a `struct GNUNET_CADET_ListTunnels` operation + */ +static void +reconnect (void *cls); + + +/** + * Function called on connection trouble. Reconnects. + * + * @param cls a `struct GNUNET_CADET_ListTunnels` + * @param error error code from MQ + */ +static void +error_handler (void *cls, + enum GNUNET_MQ_Error error) +{ + struct GNUNET_CADET_ListTunnels *lt = cls; + + GNUNET_MQ_destroy (lt->mq); + lt->mq = NULL; + lt->backoff = GNUNET_TIME_randomized_backoff (lt->backoff, + GNUNET_TIME_UNIT_MINUTES); + lt->reconnect_task = GNUNET_SCHEDULER_add_delayed (lt->backoff, + &reconnect, + lt); +} + + +/** + * Reconnect to the service and try again. + * + * @param cls a `struct GNUNET_CADET_ListTunnels` operation + */ static void reconnect (void *cls) { struct GNUNET_CADET_ListTunnels *lt = cls; - struct GNUNET_MQ_MessageHandler *handlers[] = { + struct GNUNET_MQ_MessageHandler handlers[] = { GNUNET_MQ_hd_var_size (get_tunnels, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS, struct GNUNET_MessageHeader, - h), + lt), GNUNET_MQ_handler_end () - } + }; struct GNUNET_MessageHeader *msg; struct GNUNET_MQ_Envelope *env; - cm->mq = GNUNET_CLIENT_connect (cm->cfg, + lt->reconnect_task = NULL; + lt->mq = GNUNET_CLIENT_connect (lt->cfg, "cadet", handlers, &error_handler, - cm); - + lt); + if (NULL == lt->mq) + return; env = GNUNET_MQ_msg (msg, - type); - GNUNET_MQ_send (cm->mq, + GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS); + GNUNET_MQ_send (lt->mq, env); } @@ -184,41 +204,52 @@ reconnect (void *cls) * @param h Handle to the cadet peer. * @param callback Function to call with the requested data. * @param callback_cls Closure for @c callback. - * @return #GNUNET_OK / #GNUNET_SYSERR + * @return NULL on error */ struct GNUNET_CADET_ListTunnels * GNUNET_CADET_list_tunnels (const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_CADET_TunnelsCB callback, void *callback_cls) { + struct GNUNET_CADET_ListTunnels *lt; - if (NULL != h->info_cb.tunnels_cb) + if (NULL == callback) { GNUNET_break (0); - return GNUNET_SYSERR; + return NULL; } - send_info_request (h, - GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS); - h->info_cb.tunnels_cb = callback; - h->info_cls = callback_cls; - return GNUNET_OK; + lt = GNUNET_new (struct GNUNET_CADET_ListTunnels); + lt->tunnels_cb = callback; + lt->tunnels_cb_cls = callback_cls; + lt->cfg = cfg; + reconnect (lt); + if (NULL == lt->mq) + { + GNUNET_free (lt); + return NULL; + } + return lt; } /** * Cancel a monitor request. The monitor callback will not be called. * - * @param h Cadet handle. + * @param lt operation handle * @return Closure given to GNUNET_CADET_list_tunnels(). */ void * GNUNET_CADET_list_tunnels_cancel (struct GNUNET_CADET_ListTunnels *lt) { - void *cls = h->info_cls; - - h->info_cb.tunnels_cb = NULL; - h->info_cls = NULL; - return cls; + void *ret = lt->tunnels_cb_cls; + + if (NULL != lt->mq) + GNUNET_MQ_destroy (lt->mq); + if (NULL != lt->reconnect_task) + GNUNET_SCHEDULER_cancel (lt->reconnect_task); + GNUNET_free (lt); + return ret; } +/* end of cadet_api_list_tunnels.c */ diff --git a/src/include/gnunet_cadet_service.h b/src/include/gnunet_cadet_service.h index 3ff8cf59c..846260a08 100644 --- a/src/include/gnunet_cadet_service.h +++ b/src/include/gnunet_cadet_service.h @@ -569,7 +569,7 @@ struct GNUNET_CADET_ListTunnels; * @param cfg configuration to use * @param callback Function to call with the requested data. * @param callback_cls Closure for @c callback. - * @return #GNUNET_OK / #GNUNET_SYSERR + * @return NULL on error */ struct GNUNET_CADET_ListTunnels * GNUNET_CADET_list_tunnels (const struct GNUNET_CONFIGURATION_Handle *cfg, @@ -627,7 +627,7 @@ struct GNUNET_CADET_GetTunnel; * @param id Peer whose tunnel to examine. * @param callback Function to call with the requested data. * @param callback_cls Closure for @c callback. - * @return #GNUNET_OK / #GNUNET_SYSERR + * @return NULL on error */ struct GNUNET_CADET_GetTunnel * GNUNET_CADET_get_tunnel (const struct GNUNET_CONFIGURATION_Handle *cfg, -- 2.25.1