From d3f013aba71486c121800d279cd1d3af4425c412 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 27 Jan 2019 04:05:12 +0100 Subject: more work towards fixing #5385 --- src/cadet/Makefile.am | 3 +- src/cadet/cadet.h | 97 +++++++++++-- src/cadet/cadet_api_get_channel.c | 90 +++++++++--- src/cadet/cadet_api_get_path.c | 277 +++++++++++++++++++++++++++++++++++++ src/cadet/cadet_api_get_peer.c | 284 -------------------------------------- src/cadet/cadet_api_list_peers.c | 76 +++++----- src/cadet/gnunet-cadet.c | 123 +++++++---------- src/cadet/gnunet-service-cadet.c | 158 +++------------------ 8 files changed, 538 insertions(+), 570 deletions(-) create mode 100644 src/cadet/cadet_api_get_path.c delete mode 100644 src/cadet/cadet_api_get_peer.c (limited to 'src/cadet') diff --git a/src/cadet/Makefile.am b/src/cadet/Makefile.am index 8f4cd20d4..80ad76737 100644 --- a/src/cadet/Makefile.am +++ b/src/cadet/Makefile.am @@ -34,7 +34,8 @@ lib_LTLIBRARIES = \ libgnunetcadet_la_SOURCES = \ cadet_api.c \ - cadet_api_get_peer.c \ + cadet_api_get_channel.c \ + cadet_api_get_path.c \ cadet_api_get_tunnel.c \ cadet_api_list_peers.c \ cadet_api_list_tunnels.c \ diff --git a/src/cadet/cadet.h b/src/cadet/cadet.h index 226288284..51296ae50 100644 --- a/src/cadet/cadet.h +++ b/src/cadet/cadet.h @@ -249,23 +249,96 @@ struct GNUNET_CADET_LocalInfo /** - * Message to inform the client about one of the peers in the service. - * - * TODO: split into two messages! + * Message to inform the client about channels in the service. */ -struct GNUNET_CADET_LocalInfoPeer +struct GNUNET_CADET_RequestPathInfoMessage { /** - * Type: #GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER or - * #GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS + * Type: #GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_PATH */ struct GNUNET_MessageHeader header; - + + /** + * Always zero. + */ + uint32_t resered GNUNET_PACKED; + + /** + * ID of the destination of the channel (can be local peer). + */ + struct GNUNET_PeerIdentity peer; +}; + + +/** + * Message to inform the client about channels in the service. + */ +struct GNUNET_CADET_ChannelInfoMessage +{ + /** + * Type: #GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNEL. + */ + struct GNUNET_MessageHeader header; + /** - * Offset the peer has in the path this message is about. + * Root of the channel */ - uint16_t offset GNUNET_PACKED; + struct GNUNET_PeerIdentity root; + /** + * Destination of the channel + */ + struct GNUNET_PeerIdentity dest; + + /* FIXME: expand! */ +}; + + +/** + * Message to as the service about information on a channel. + */ +struct GNUNET_CADET_RequestChannelInfoMessage +{ + /** + * Type: #GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_CHANNEL. + */ + struct GNUNET_MessageHeader header; + + /** + * Target of the channel. + */ + struct GNUNET_PeerIdentity target; + +}; + + +/** + * Message to inform the client about one of the paths known to the service. + */ +struct GNUNET_CADET_LocalInfoPath +{ + /** + * Type: #GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PATH. + */ + struct GNUNET_MessageHeader header; + + /** + * Zero. + */ + uint32_t reserved GNUNET_PACKED; +}; + + +/** + * Message to inform the client about one of the peers in the service. + */ +struct GNUNET_CADET_LocalInfoPeers +{ + /** + * Type: #GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS + */ + struct GNUNET_MessageHeader header; + /** * Number of paths. */ @@ -277,17 +350,15 @@ struct GNUNET_CADET_LocalInfoPeer int16_t tunnel GNUNET_PACKED; /** - * We are finished with the paths. + * Shortest known path. */ - uint16_t finished_with_paths; + uint32_t best_path_length GNUNET_PACKED; /** * ID of the peer (can be local peer). */ struct GNUNET_PeerIdentity destination; - /* If type == PEER (no 'S'): GNUNET_PeerIdentity paths[] - * (each path ends in destination) */ }; diff --git a/src/cadet/cadet_api_get_channel.c b/src/cadet/cadet_api_get_channel.c index 1249777c2..81f0691f1 100644 --- a/src/cadet/cadet_api_get_channel.c +++ b/src/cadet/cadet_api_get_channel.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 @@ -72,14 +72,66 @@ struct GNUNET_CADET_ChannelMonitor */ struct GNUNET_PeerIdentity peer; - /** - * Channel we want information about. - */ - uint32_t /* UGH */ channel_number; - }; +/** + * Check that message received from CADET service is well-formed. + * + * @param cls unused + * @param message the message we got + * @return #GNUNET_OK if the message is well-formed, + * #GNUNET_SYSERR otherwise + */ +static int +check_channel_info (void *cls, + const struct GNUNET_CADET_ChannelInfoMessage *message) +{ + (void) cls; + + return GNUNET_OK; +} + + +/** + * Process a local peer info reply, pass info to the user. + * + * @param cls Closure + * @param message Message itself. + */ +static void +handle_channel_info (void *cls, + const struct GNUNET_CADET_ChannelInfoMessage *message) +{ + struct GNUNET_CADET_ChannelMonitor *cm = cls; + struct GNUNET_CADET_ChannelInternals ci; + + ci.root = message->root; + ci.dest = message->dest; + cm->channel_cb (cm->channel_cb_cls, + &ci); + GNUNET_CADET_get_channel_cancel (cm); +} + + +/** + * Process a local peer info reply, pass info to the user. + * + * @param cls Closure + * @param message Message itself. + */ +static void +handle_channel_info_end (void *cls, + const struct GNUNET_MessageHeader *message) +{ + struct GNUNET_CADET_ChannelMonitor *cm = cls; + + cm->channel_cb (cm->channel_cb_cls, + NULL); + GNUNET_CADET_get_channel_cancel (cm); +} + + /** * Reconnect to the service and try again. * @@ -120,11 +172,18 @@ static void reconnect (void *cls) { struct GNUNET_CADET_ChannelMonitor *cm = cls; - struct GNUNET_MQ_MessageHandler *handlers[] = { - FIXME, + struct GNUNET_MQ_MessageHandler handlers[] = { + GNUNET_MQ_hd_fixed_size (channel_info_end, + GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNEL_END, + struct GNUNET_MessageHeader, + cm), + GNUNET_MQ_hd_var_size (channel_info, + GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNEL, + struct GNUNET_CADET_ChannelInfoMessage, + cm), GNUNET_MQ_handler_end () }; - struct GNUNET_MessageHeader *msg; + struct GNUNET_CADET_RequestChannelInfoMessage *msg; struct GNUNET_MQ_Envelope *env; cm->reconnect_task = NULL; @@ -136,7 +195,8 @@ reconnect (void *cls) if (NULL == cm->mq) return; env = GNUNET_MQ_msg (msg, - type); + GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_CHANNEL); + msg->target = cm->peer; GNUNET_MQ_send (cm->mq, env); } @@ -147,7 +207,6 @@ reconnect (void *cls) * * @param cfg configuration to use * @param peer ID of the other end of the channel. - * @param channel_number Channel number. * @param callback Function to call with the requested data. * @param callback_cls Closure for @c callback. * @return NULL on error @@ -155,7 +214,6 @@ reconnect (void *cls) struct GNUNET_CADET_ChannelMonitor * GNUNET_CADET_get_channel (const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_PeerIdentity *peer, - uint32_t /* UGH */ channel_number, GNUNET_CADET_ChannelCB callback, void *callback_cls) { @@ -167,10 +225,10 @@ GNUNET_CADET_get_channel (const struct GNUNET_CONFIGURATION_Handle *cfg, return NULL; } cm = GNUNET_new (struct GNUNET_CADET_ChannelMonitor); - cm->peer_cb = callback; - cm->peer_cb_cls = callback_cls; + cm->channel_cb = callback; + cm->channel_cb_cls = callback_cls; cm->cfg = cfg; - cm->id = *id; + cm->peer = *peer; reconnect (cm); if (NULL == cm->mq) { @@ -190,7 +248,7 @@ GNUNET_CADET_get_channel (const struct GNUNET_CONFIGURATION_Handle *cfg, void * GNUNET_CADET_get_channel_cancel (struct GNUNET_CADET_ChannelMonitor *cm) { - void *ret = cm->peer_cb_cls; + void *ret = cm->channel_cb_cls; if (NULL != cm->mq) GNUNET_MQ_destroy (cm->mq); diff --git a/src/cadet/cadet_api_get_path.c b/src/cadet/cadet_api_get_path.c new file mode 100644 index 000000000..2f35e365e --- /dev/null +++ b/src/cadet/cadet_api_get_path.c @@ -0,0 +1,277 @@ +/* + This file is part of GNUnet. + Copyright (C) 2011, 2017 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 + by the Free Software Foundation, either version 3 of the License, + 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 + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later +*/ +/** + * @file cadet/cadet_api_get_path.c + * @brief cadet api: client implementation of cadet service + * @author Bartlomiej Polot + * @author Christian Grothoff + */ +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_constants.h" +#include "gnunet_cadet_service.h" +#include "cadet.h" +#include "cadet_protocol.h" + + +/** + * Operation handle. + */ +struct GNUNET_CADET_GetPath +{ + + /** + * Monitor callback + */ + GNUNET_CADET_PathCB path_cb; + + /** + * Closure for @c path_cb. + */ + void *path_cb_cls; + + /** + * Message queue to talk to CADET service. + */ + struct GNUNET_MQ_Handle *mq; + + /** + * Configuration we use. + */ + const struct GNUNET_CONFIGURATION_Handle *cfg; + + /** + * Task to reconnect. + */ + struct GNUNET_SCHEDULER_Task *reconnect_task; + + /** + * Backoff for reconnect attempts. + */ + struct GNUNET_TIME_Relative backoff; + + /** + * Peer we want information about. + */ + struct GNUNET_PeerIdentity id; + +}; + + +/** + * Check that message received from CADET service is well-formed. + * + * @param cls unused + * @param message the message we got + * @return #GNUNET_OK if the message is well-formed, + * #GNUNET_SYSERR otherwise + */ +static int +check_get_path (void *cls, + const struct GNUNET_CADET_LocalInfoPath *message) +{ + size_t msize = sizeof (struct GNUNET_CADET_LocalInfoPath); + size_t esize; + + (void) cls; + esize = ntohs (message->header.size); + if (esize < msize) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + if (0 != ((esize - msize) % sizeof (struct GNUNET_PeerIdentity))) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + + +/** + * Process a local peer info reply, pass info to the user. + * + * @param cls Closure + * @param message Message itself. + */ +static void +handle_get_path (void *cls, + const struct GNUNET_CADET_LocalInfoPath *message) +{ + struct GNUNET_CADET_GetPath *gp = cls; + struct GNUNET_CADET_PeerPathDetail ppd; + + ppd.peer = gp->id; + ppd.path = (const struct GNUNET_PeerIdentity *) &message[1]; + ppd.path_length = (ntohs (message->header.size) - sizeof (*message)) + / sizeof (struct GNUNET_PeerIdentity); + gp->path_cb (gp->path_cb_cls, + &ppd); +} + + +/** + * Process a local peer info reply, pass info to the user. + * + * @param cls Closure + * @param message Message itself. + */ +static void +handle_get_path_end (void *cls, + const struct GNUNET_MessageHeader *message) +{ + struct GNUNET_CADET_GetPath *gp = cls; + + (void) message; + gp->path_cb (gp->path_cb_cls, + NULL); + GNUNET_CADET_get_path_cancel (gp); +} + + +/** + * Reconnect to the service and try again. + * + * @param cls a `struct GNUNET_CADET_GetPath` operation + */ +static void +reconnect (void *cls); + + +/** + * Function called on connection trouble. Reconnects. + * + * @param cls a `struct GNUNET_CADET_GetPath` + * @param error error code from MQ + */ +static void +error_handler (void *cls, + enum GNUNET_MQ_Error error) +{ + struct GNUNET_CADET_GetPath *gp = cls; + + GNUNET_MQ_destroy (gp->mq); + gp->mq = NULL; + gp->backoff = GNUNET_TIME_randomized_backoff (gp->backoff, + GNUNET_TIME_UNIT_MINUTES); + gp->reconnect_task = GNUNET_SCHEDULER_add_delayed (gp->backoff, + &reconnect, + gp); +} + + +/** + * Reconnect to the service and try again. + * + * @param cls a `struct GNUNET_CADET_GetPath` operation + */ +static void +reconnect (void *cls) +{ + struct GNUNET_CADET_GetPath *gp = cls; + struct GNUNET_MQ_MessageHandler handlers[] = { + GNUNET_MQ_hd_var_size (get_path, + GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PATH, + struct GNUNET_CADET_LocalInfoPath, + gp), + GNUNET_MQ_hd_fixed_size (get_path_end, + GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PATH_END, + struct GNUNET_MessageHeader, + gp), + GNUNET_MQ_handler_end () + }; + struct GNUNET_CADET_RequestPathInfoMessage *msg; + struct GNUNET_MQ_Envelope *env; + + gp->reconnect_task = NULL; + gp->mq = GNUNET_CLIENT_connect (gp->cfg, + "cadet", + handlers, + &error_handler, + gp); + if (NULL == gp->mq) + return; + env = GNUNET_MQ_msg (msg, + GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_PATH); + msg->peer = gp->id; + GNUNET_MQ_send (gp->mq, + env); +} + + +/** + * Request information about paths known to the running cadet peer. + * + * @param cfg configuration to use + * @param id Peer whose paths to examine. + * @param callback Function to call with the requested data. + * @param callback_cls Closure for @c callback. + * @return NULL on error + */ +struct GNUNET_CADET_GetPath * +GNUNET_CADET_get_path (const struct GNUNET_CONFIGURATION_Handle *cfg, + const struct GNUNET_PeerIdentity *id, + GNUNET_CADET_PathCB callback, + void *callback_cls) +{ + struct GNUNET_CADET_GetPath *gp; + + if (NULL == callback) + { + GNUNET_break (0); + return NULL; + } + gp = GNUNET_new (struct GNUNET_CADET_GetPath); + gp->path_cb = callback; + gp->path_cb_cls = callback_cls; + gp->cfg = cfg; + gp->id = *id; + reconnect (gp); + if (NULL == gp->mq) + { + GNUNET_free (gp); + return NULL; + } + return gp; +} + + +/** + * Cancel @a gp operation. + * + * @param gp operation to cancel + * @return closure from #GNUNET_CADET_get_path(). + */ +void * +GNUNET_CADET_get_path_cancel (struct GNUNET_CADET_GetPath *gp) +{ + void *ret = gp->path_cb_cls; + + if (NULL != gp->mq) + GNUNET_MQ_destroy (gp->mq); + if (NULL != gp->reconnect_task) + GNUNET_SCHEDULER_cancel (gp->reconnect_task); + GNUNET_free (gp); + return ret; +} + + +/* end of cadet_api_get_path.c */ diff --git a/src/cadet/cadet_api_get_peer.c b/src/cadet/cadet_api_get_peer.c deleted file mode 100644 index 6276de3a4..000000000 --- a/src/cadet/cadet_api_get_peer.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - This file is part of GNUnet. - Copyright (C) 2011, 2017 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 - by the Free Software Foundation, either version 3 of the License, - 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 - Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - - SPDX-License-Identifier: AGPL3.0-or-later -*/ -/** - * @file cadet/cadet_api_get_peer.c - * @brief cadet api: client implementation of cadet service - * @author Bartlomiej Polot - * @author Christian Grothoff - */ -#include "platform.h" -#include "gnunet_util_lib.h" -#include "gnunet_constants.h" -#include "gnunet_cadet_service.h" -#include "cadet.h" -#include "cadet_protocol.h" - - -/** - * Operation handle. - */ -struct GNUNET_CADET_GetPeer -{ - - /** - * Monitor callback - */ - GNUNET_CADET_PeerCB peer_cb; - - /** - * Closure for @c peer_cb. - */ - void *peer_cb_cls; - - /** - * Message queue to talk to CADET service. - */ - struct GNUNET_MQ_Handle *mq; - - /** - * Configuration we use. - */ - const struct GNUNET_CONFIGURATION_Handle *cfg; - - /** - * Task to reconnect. - */ - struct GNUNET_SCHEDULER_Task *reconnect_task; - - /** - * Backoff for reconnect attempts. - */ - struct GNUNET_TIME_Relative backoff; - - /** - * Peer we want information about. - */ - struct GNUNET_PeerIdentity id; - -}; - - -/** - * Check that message received from CADET service is well-formed. - * - * @param cls unused - * @param message the message we got - * @return #GNUNET_OK if the message is well-formed, - * #GNUNET_SYSERR otherwise - */ -static int -check_get_peer (void *cls, - const struct GNUNET_CADET_LocalInfoPeer *message) -{ - size_t msize = sizeof (struct GNUNET_CADET_LocalInfoPeer); - size_t esize; - - (void) cls; - esize = ntohs (message->header.size); - if (esize < msize) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - if (0 != ((esize - msize) % sizeof (struct GNUNET_PeerIdentity))) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - return GNUNET_OK; -} - - -/** - * Process a local peer info reply, pass info to the user. - * - * @param cls Closure - * @param message Message itself. - */ -static void -handle_get_peer (void *cls, - const struct GNUNET_CADET_LocalInfoPeer *message) -{ - struct GNUNET_CADET_GetPeer *gp = cls; - const struct GNUNET_PeerIdentity *paths_array; - unsigned int paths; - unsigned int path_length; - int neighbor; - unsigned int peers; - - paths = ntohs (message->paths); - paths_array = (const struct GNUNET_PeerIdentity *) &message[1]; - peers = (ntohs (message->header.size) - sizeof (*message)) - / sizeof (struct GNUNET_PeerIdentity); - path_length = 0; - neighbor = GNUNET_NO; - - for (unsigned int i = 0; i < peers; i++) - { - path_length++; - if (0 == memcmp (&paths_array[i], - &message->destination, - sizeof (struct GNUNET_PeerIdentity))) - { - if (1 == path_length) - neighbor = GNUNET_YES; - path_length = 0; - } - } - - /* Call Callback with tunnel info */ - paths_array = (const struct GNUNET_PeerIdentity *) &message[1]; - gp->peer_cb (gp->peer_cb_cls, - &message->destination, - (int) ntohs (message->tunnel), - neighbor, - paths, - paths_array, - (int) ntohs (message->offset), - (int) ntohs (message->finished_with_paths)); - GNUNET_CADET_get_peer_cancel (gp); -} - - -/** - * Reconnect to the service and try again. - * - * @param cls a `struct GNUNET_CADET_GetPeer` operation - */ -static void -reconnect (void *cls); - - -/** - * Function called on connection trouble. Reconnects. - * - * @param cls a `struct GNUNET_CADET_GetPeer` - * @param error error code from MQ - */ -static void -error_handler (void *cls, - enum GNUNET_MQ_Error error) -{ - struct GNUNET_CADET_GetPeer *gp = cls; - - GNUNET_MQ_destroy (gp->mq); - gp->mq = NULL; - gp->backoff = GNUNET_TIME_randomized_backoff (gp->backoff, - GNUNET_TIME_UNIT_MINUTES); - gp->reconnect_task = GNUNET_SCHEDULER_add_delayed (gp->backoff, - &reconnect, - gp); -} - - -/** - * Reconnect to the service and try again. - * - * @param cls a `struct GNUNET_CADET_GetPeer` operation - */ -static void -reconnect (void *cls) -{ - struct GNUNET_CADET_GetPeer *gp = cls; - struct GNUNET_MQ_MessageHandler handlers[] = { - GNUNET_MQ_hd_var_size (get_peer, - GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER, - struct GNUNET_CADET_LocalInfoPeer, - gp), - GNUNET_MQ_handler_end () - }; - struct GNUNET_CADET_LocalInfo *msg; - struct GNUNET_MQ_Envelope *env; - - gp->reconnect_task = NULL; - gp->mq = GNUNET_CLIENT_connect (gp->cfg, - "cadet", - handlers, - &error_handler, - gp); - if (NULL == gp->mq) - return; - env = GNUNET_MQ_msg (msg, - GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER); - msg->peer = gp->id; - GNUNET_MQ_send (gp->mq, - env); -} - - -/** - * Request information about a peer known to the running cadet peer. - * The callback will be called for the tunnel once. - * - * @param cfg configuration to use - * @param id Peer whose tunnel to examine. - * @param callback Function to call with the requested data. - * @param callback_cls Closure for @c callback. - * @return NULL on error - */ -struct GNUNET_CADET_GetPeer * -GNUNET_CADET_get_peer (const struct GNUNET_CONFIGURATION_Handle *cfg, - const struct GNUNET_PeerIdentity *id, - GNUNET_CADET_PeerCB callback, - void *callback_cls) -{ - struct GNUNET_CADET_GetPeer *gp; - - if (NULL == callback) - { - GNUNET_break (0); - return NULL; - } - gp = GNUNET_new (struct GNUNET_CADET_GetPeer); - gp->peer_cb = callback; - gp->peer_cb_cls = callback_cls; - gp->cfg = cfg; - gp->id = *id; - reconnect (gp); - if (NULL == gp->mq) - { - GNUNET_free (gp); - return NULL; - } - return gp; -} - - -/** - * Cancel @a gp operation. - * - * @param gp operation to cancel - * @return closure from #GNUNET_CADET_get_peer(). - */ -void * -GNUNET_CADET_get_peer_cancel (struct GNUNET_CADET_GetPeer *gp) -{ - void *ret = gp->peer_cb_cls; - - if (NULL != gp->mq) - GNUNET_MQ_destroy (gp->mq); - if (NULL != gp->reconnect_task) - GNUNET_SCHEDULER_cancel (gp->reconnect_task); - GNUNET_free (gp); - return ret; -} - - -/* end of cadet_api_get_peer.c */ diff --git a/src/cadet/cadet_api_list_peers.c b/src/cadet/cadet_api_list_peers.c index cc6948a36..4dc6d02f5 100644 --- a/src/cadet/cadet_api_list_peers.c +++ b/src/cadet/cadet_api_list_peers.c @@ -71,59 +71,43 @@ struct GNUNET_CADET_PeersLister /** - * Check that message received from CADET service is well-formed. + * Process a local reply about info on all tunnels, pass info to the user. * - * @param cls the `struct GNUNET_CADET_PeersLister` - * @param message the message we got - * @return #GNUNET_OK if the message is well-formed, - * #GNUNET_SYSERR otherwise + * @param cls a `struct GNUNET_CADET_PeersLister` + * @param info Message itself. */ -static int -check_get_peers (void *cls, - const struct GNUNET_MessageHeader *message) +static void +handle_get_peers (void *cls, + const struct GNUNET_CADET_LocalInfoPeers *info) { - size_t esize; - - (void) cls; - esize = ntohs (message->size); - if (sizeof (struct GNUNET_CADET_LocalInfoPeer) == esize) - return GNUNET_OK; - if (sizeof (struct GNUNET_MessageHeader) == esize) - return GNUNET_OK; - return GNUNET_SYSERR; + struct GNUNET_CADET_PeersLister *pl = cls; + struct GNUNET_CADET_PeerListEntry ple; + + ple.peer = info->destination; + ple.have_tunnel = (int) ntohs (info->tunnel); + ple.n_paths = (unsigned int) ntohs (info->paths); + ple.best_path_length = (unsigned int) ntohl (info->best_path_length); + pl->peers_cb (pl->peers_cb_cls, + &ple); } -// FIXME: use two different message types instead of this mess! /** - * Process a local reply about info on all tunnels, pass info to the user. + * Process a end of list reply about info on all peers. * * @param cls a `struct GNUNET_CADET_PeersLister` * @param msg Message itself. */ static void -handle_get_peers (void *cls, - const struct GNUNET_MessageHeader *msg) +handle_get_peers_end (void *cls, + const struct GNUNET_MessageHeader *msg) { struct GNUNET_CADET_PeersLister *pl = cls; - const struct GNUNET_CADET_LocalInfoPeer *info = - (const struct GNUNET_CADET_LocalInfoPeer *) msg; - - if (sizeof (struct GNUNET_CADET_LocalInfoPeer) == ntohs (msg->size)) - pl->peers_cb (pl->peers_cb_cls, - &info->destination, - (int) ntohs (info->tunnel), - (unsigned int) ntohs (info->paths), - 0); - else - { - pl->peers_cb (pl->peers_cb_cls, - NULL, - 0, - 0, - 0); - GNUNET_CADET_list_peers_cancel (pl); - } + (void) msg; + + pl->peers_cb (pl->peers_cb_cls, + NULL); + GNUNET_CADET_list_peers_cancel (pl); } @@ -168,10 +152,14 @@ reconnect (void *cls) { struct GNUNET_CADET_PeersLister *pl = cls; struct GNUNET_MQ_MessageHandler handlers[] = { - GNUNET_MQ_hd_var_size (get_peers, - GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS, - struct GNUNET_MessageHeader, - pl), + GNUNET_MQ_hd_fixed_size (get_peers, + GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS, + struct GNUNET_CADET_LocalInfoPeers, + pl), + GNUNET_MQ_hd_fixed_size (get_peers_end, + GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS_END, + struct GNUNET_MessageHeader, + pl), GNUNET_MQ_handler_end () }; struct GNUNET_MessageHeader *msg; @@ -186,7 +174,7 @@ reconnect (void *cls) if (NULL == pl->mq) return; env = GNUNET_MQ_msg (msg, - GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS); + GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_PEERS); GNUNET_MQ_send (pl->mq, env); } diff --git a/src/cadet/gnunet-cadet.c b/src/cadet/gnunet-cadet.c index b36113318..3386f7464 100644 --- a/src/cadet/gnunet-cadet.c +++ b/src/cadet/gnunet-cadet.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2012, 2017 GNUnet e.V. + Copyright (C) 2012, 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 @@ -101,6 +101,16 @@ static struct GNUNET_CADET_Handle *mh; */ static const struct GNUNET_CONFIGURATION_Handle *my_cfg; +/** + * Active get path operation. + */ +static struct GNUNET_CADET_GetPath *gpo; + +/** + * Active peer listing operation. + */ +struct GNUNET_CADET_PeersLister *plo; + /** * Channel handle. */ @@ -210,6 +220,16 @@ shutdown_task (void *cls) { GNUNET_CADET_channel_destroy (ch); ch = NULL; + } + if (NULL != gpo) + { + GNUNET_CADET_get_path_cancel (gpo); + gpo = NULL; + } + if (NULL != plo) + { + GNUNET_CADET_list_peers_cancel (plo); + plo = NULL; } if (NULL != mh) { @@ -496,93 +516,52 @@ handle_data (void *cls, * After last peer has been reported, an additional call with NULL is done. * * @param cls Closure. - * @param peer Peer, or NULL on "EOF". - * @param tunnel Do we have a tunnel towards this peer? - * @param n_paths Number of known paths towards this peer. - * @param best_path How long is the best path? - * (0 = unknown, 1 = ourselves, 2 = neighbor) + * @param ple information about peer, or NULL on "EOF". */ static void peers_callback (void *cls, - const struct GNUNET_PeerIdentity *peer, - int tunnel, - unsigned int n_paths, - unsigned int best_path) + const struct GNUNET_CADET_PeerListEntry *ple) { - if (NULL == peer) + if (NULL == ple) { + plo = NULL; GNUNET_SCHEDULER_shutdown(); return; } FPRINTF (stdout, "%s tunnel: %c, paths: %u\n", - GNUNET_i2s_full (peer), - tunnel ? 'Y' : 'N', - n_paths); + GNUNET_i2s_full (&ple->peer), + ple->have_tunnel ? 'Y' : 'N', + ple->n_paths); } /** - * Method called to retrieve information about a specific peer + * Method called to retrieve information about paths to a specific peer * known to the service. * * @param cls Closure. - * @param peer Peer ID. - * @param tunnel Do we have a tunnel towards this peer? #GNUNET_YES/#GNUNET_NO - * @param neighbor Is this a direct neighbor? #GNUNET_YES/#GNUNET_NO - * @param n_paths Number of paths known towards peer. - * @param paths Array of PEER_IDs representing all paths to reach the peer. - * Each path starts with the local peer. - * Each path ends with the destination peer (given in @c peer). + * @param ppd path detail */ static void -peer_callback (void *cls, - const struct GNUNET_PeerIdentity *peer, - int tunnel, - int neighbor, - unsigned int n_paths, - const struct GNUNET_PeerIdentity *paths, - int offset, - int finished_with_paths) +path_callback (void *cls, + const struct GNUNET_CADET_PeerPathDetail *ppd) { - unsigned int i; - const struct GNUNET_PeerIdentity *p; - - - if (GNUNET_YES == finished_with_paths) + if (NULL == ppd) { + gpo = NULL; GNUNET_SCHEDULER_shutdown(); return; } - - if (offset == 0){ - FPRINTF (stdout, - "%s [TUNNEL: %s, NEIGHBOR: %s, PATHS: %u]\n", - GNUNET_i2s_full (peer), - tunnel ? "Y" : "N", - neighbor ? "Y" : "N", - n_paths); - }else{ - p = paths; - FPRINTF (stdout, - "Indirekt path with offset %u: ", - offset); - for (i = 0; i <= offset && NULL != p;) - { - FPRINTF (stdout, - "%s ", - GNUNET_i2s (p)); - i++; - p++; - } - + FPRINTF (stdout, + "Path of length %u: ", + ppd->path_length); + for (unsigned int i = 0; i < ppd->path_length; i++) FPRINTF (stdout, - "\n"); - - } - - - + "%s ", + GNUNET_i2s (&ppd->path[i])); + FPRINTF (stdout, + "\n"); } @@ -669,11 +648,9 @@ static void get_peers (void *cls) { job = NULL; -#if FIXME5385 - GNUNET_CADET_list_peers (my_cfg, - &peers_callback, - NULL); -#endif + plo = GNUNET_CADET_list_peers (my_cfg, + &peers_callback, + NULL); } @@ -699,12 +676,10 @@ show_peer (void *cls) GNUNET_SCHEDULER_shutdown(); return; } -#if FIXME5385 - GNUNET_CADET_get_peer (my_cfg, - &pid, - &peer_callback, - NULL); -#endif + gpo = GNUNET_CADET_get_path (my_cfg, + &pid, + &path_callback, + NULL); } diff --git a/src/cadet/gnunet-service-cadet.c b/src/cadet/gnunet-service-cadet.c index ae5d48943..a62ce4cb0 100644 --- a/src/cadet/gnunet-service-cadet.c +++ b/src/cadet/gnunet-service-cadet.c @@ -821,7 +821,7 @@ get_all_peers_iterator (void *cls, struct CadetClient *c = cls; struct CadetPeer *p = value; struct GNUNET_MQ_Envelope *env; - struct GNUNET_CADET_LocalInfoPeer *msg; + struct GNUNET_CADET_LocalInfoPeers *msg; env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS); @@ -829,6 +829,7 @@ get_all_peers_iterator (void *cls, msg->paths = htons (GCP_count_paths (p)); msg->tunnel = htons (NULL != GCP_get_tunnel (p, GNUNET_NO)); + msg->best_path_length = htonl (0); // FIXME: get length of shortest known path! GNUNET_MQ_send (c->mq, env); return GNUNET_YES; @@ -852,7 +853,7 @@ handle_get_peers (void *cls, GCP_iterate_all (&get_all_peers_iterator, c); env = GNUNET_MQ_msg (reply, - GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS); + GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS_END); GNUNET_MQ_send (c->mq, env); GNUNET_SERVICE_client_continue (c->client); @@ -876,10 +877,9 @@ path_info_iterator (void *cls, { struct GNUNET_MQ_Handle *mq = cls; struct GNUNET_MQ_Envelope *env; - struct GNUNET_CADET_LocalInfoPeer *resp; + struct GNUNET_CADET_LocalInfoPath *resp; struct GNUNET_PeerIdentity *id; - uint16_t path_size; - unsigned int i; + size_t path_size; unsigned int path_length; path_length = GCPP_get_length (path); @@ -893,18 +893,13 @@ path_info_iterator (void *cls, } env = GNUNET_MQ_msg_extra (resp, path_size, - GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER); - - - resp->offset = htons(off); - resp->finished_with_paths = htons(0); - + GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PATH); id = (struct GNUNET_PeerIdentity *) &resp[1]; /* Don't copy first peer. First peer is always the local one. Last * peer is always the destination (leave as 0, EOL). */ - for (i = 0; i <= off; i++) + for (unsigned int i = 0; i <= off; i++) id[i] = *GCP_get_id (GCPP_get_peer_at_offset (path, i)); GNUNET_MQ_send (mq, @@ -912,70 +907,32 @@ path_info_iterator (void *cls, return GNUNET_YES; } -/** - * Getting summary information about the number of paths and if a tunnel exists, - * and the indirect paths to a peer, if there are ones. - * - * @param cls Closure (). - * @param peer Peer ID (tunnel remote peer). - * @param value Peer info. - * @return #GNUNET_YES, to keep iterating. - */ -static void -get_peer_info (void *cls, - const struct GNUNET_PeerIdentity *peer, - struct CadetPeer *p) -{ - struct CadetClient *c = cls; - struct GNUNET_MQ_Envelope *env; - struct GNUNET_CADET_LocalInfoPeer *msg; - - env = GNUNET_MQ_msg (msg, - GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER); - msg->offset = htons(0); - msg->destination = *peer; - msg->paths = htons (GCP_count_paths (p)); - msg->tunnel = htons (NULL != GCP_get_tunnel (p, - GNUNET_NO)); - msg->finished_with_paths = htons(0); - GNUNET_MQ_send (c->mq, - env); - GCP_iterate_indirect_paths (p, - &path_info_iterator, - c->mq); -} - /** - * Handler for client's SHOW_PEER request. + * Handler for client's #GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_PATH request. * * @param cls Identification of the client. * @param msg The actual message. */ static void -handle_show_peer (void *cls, - const struct GNUNET_CADET_LocalInfo *msg) +handle_show_path (void *cls, + const struct GNUNET_CADET_RequestPathInfoMessage *msg) { struct CadetClient *c = cls; struct CadetPeer *p; struct GNUNET_MQ_Envelope *env; - struct GNUNET_CADET_LocalInfoPeer *resp; + struct GNUNET_MessageHeader *resp; p = GCP_get (&msg->peer, GNUNET_NO); - if (NULL != p){ - get_peer_info(c, &(msg->peer), p); - } - - + if (NULL != p) + GCP_iterate_indirect_paths (p, + &path_info_iterator, + c->mq); env = GNUNET_MQ_msg (resp, - GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER); - resp->finished_with_paths = htons(1); - resp->destination = msg->peer; - + GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PATH_END); GNUNET_MQ_send (c->mq, env); - GNUNET_SERVICE_client_continue (c->client); } @@ -1143,77 +1100,6 @@ handle_info_tunnel (void *cls, } -/** - * Iterator over all peers to dump info for each peer. - * - * @param cls Closure (unused). - * @param peer Peer ID (tunnel remote peer). - * @param value Peer info. - * - * @return #GNUNET_YES, to keep iterating. - */ -static int -show_peer_iterator (void *cls, - const struct GNUNET_PeerIdentity *peer, - void *value) -{ - struct CadetPeer *p = value; - struct CadetTunnel *t; - - t = GCP_get_tunnel (p, - GNUNET_NO); - if (NULL != t) - GCT_debug (t, - GNUNET_ERROR_TYPE_ERROR); - LOG (GNUNET_ERROR_TYPE_ERROR, "\n"); - return GNUNET_YES; -} - - -/** - * Handler for client's INFO_DUMP request. - * - * @param cls Identification of the client. - * @param message The actual message. - */ -static void -handle_info_dump (void *cls, - const struct GNUNET_MessageHeader *message) -{ - struct CadetClient *c = cls; - - LOG (GNUNET_ERROR_TYPE_INFO, - "Received dump info request from client %u\n", - c->id); - - LOG (GNUNET_ERROR_TYPE_ERROR, - "*************************** DUMP START ***************************\n"); - for (struct CadetClient *ci = clients_head; - NULL != ci; - ci = ci->next) - { - LOG (GNUNET_ERROR_TYPE_ERROR, - "Client %u (%p), handle: %p, ports: %u, channels: %u\n", - ci->id, - ci, - ci->client, - (NULL != c->ports) - ? GNUNET_CONTAINER_multihashmap_size (ci->ports) - : 0, - GNUNET_CONTAINER_multihashmap32_size (ci->channels)); - } - LOG (GNUNET_ERROR_TYPE_ERROR, "***************************\n"); - GCP_iterate_all (&show_peer_iterator, - NULL); - - LOG (GNUNET_ERROR_TYPE_ERROR, - "**************************** DUMP END ****************************\n"); - - GNUNET_SERVICE_client_continue (c->client); -} - - - /** * Callback called when a client connects to the service. * @@ -1541,12 +1427,12 @@ GNUNET_SERVICE_MAIN struct GNUNET_CADET_LocalAck, NULL), GNUNET_MQ_hd_fixed_size (get_peers, - GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS, + GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_PEERS, struct GNUNET_MessageHeader, NULL), - GNUNET_MQ_hd_fixed_size (show_peer, - GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER, - struct GNUNET_CADET_LocalInfo, + GNUNET_MQ_hd_fixed_size (show_path, + GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_PATH, + struct GNUNET_CADET_RequestPathInfoMessage, NULL), GNUNET_MQ_hd_fixed_size (info_tunnels, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS, @@ -1556,10 +1442,6 @@ GNUNET_SERVICE_MAIN GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL, struct GNUNET_CADET_LocalInfo, NULL), - GNUNET_MQ_hd_fixed_size (info_dump, - GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_DUMP, - struct GNUNET_MessageHeader, - NULL), GNUNET_MQ_handler_end ()); /* end of gnunet-service-cadet-new.c */ -- cgit v1.2.3