From 6b659c8a65c34d194d6440489442c411bb3f4c26 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 13 Feb 2019 17:51:29 +0100 Subject: trying to fix #5532 --- src/cadet/cadet.h | 10 +++++----- src/cadet/cadet_api_get_path.c | 13 +++++++------ src/cadet/gnunet-cadet.c | 16 ++++++++-------- src/cadet/gnunet-service-cadet.c | 10 +++++++++- src/include/gnunet_cadet_service.h | 21 +++++++++++++-------- src/rps/profiler_rps.conf | 2 +- 6 files changed, 43 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/cadet/cadet.h b/src/cadet/cadet.h index 51296ae50..f6cc860cc 100644 --- a/src/cadet/cadet.h +++ b/src/cadet/cadet.h @@ -11,7 +11,7 @@ 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 . @@ -323,9 +323,9 @@ struct GNUNET_CADET_LocalInfoPath struct GNUNET_MessageHeader header; /** - * Zero. + * Offset of the peer that was requested. */ - uint32_t reserved GNUNET_PACKED; + uint32_t off GNUNET_PACKED; }; @@ -338,7 +338,7 @@ struct GNUNET_CADET_LocalInfoPeers * Type: #GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS */ struct GNUNET_MessageHeader header; - + /** * Number of paths. */ @@ -348,7 +348,7 @@ struct GNUNET_CADET_LocalInfoPeers * Do we have a tunnel toward this peer? */ int16_t tunnel GNUNET_PACKED; - + /** * Shortest known path. */ diff --git a/src/cadet/cadet_api_get_path.c b/src/cadet/cadet_api_get_path.c index 2f35e365e..fcc79c3d5 100644 --- a/src/cadet/cadet_api_get_path.c +++ b/src/cadet/cadet_api_get_path.c @@ -11,7 +11,7 @@ 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 . @@ -66,7 +66,7 @@ struct GNUNET_CADET_GetPath * Backoff for reconnect attempts. */ struct GNUNET_TIME_Relative backoff; - + /** * Peer we want information about. */ @@ -109,7 +109,7 @@ check_get_path (void *cls, /** * Process a local peer info reply, pass info to the user. * - * @param cls Closure + * @param cls Closure * @param message Message itself. */ static void @@ -118,9 +118,10 @@ handle_get_path (void *cls, { struct GNUNET_CADET_GetPath *gp = cls; struct GNUNET_CADET_PeerPathDetail ppd; - + ppd.peer = gp->id; ppd.path = (const struct GNUNET_PeerIdentity *) &message[1]; + ppd.target_offset = ntohl (message->off); ppd.path_length = (ntohs (message->header.size) - sizeof (*message)) / sizeof (struct GNUNET_PeerIdentity); gp->path_cb (gp->path_cb_cls, @@ -131,7 +132,7 @@ handle_get_path (void *cls, /** * Process a local peer info reply, pass info to the user. * - * @param cls Closure + * @param cls Closure * @param message Message itself. */ static void @@ -177,7 +178,7 @@ error_handler (void *cls, gp); } - + /** * Reconnect to the service and try again. * diff --git a/src/cadet/gnunet-cadet.c b/src/cadet/gnunet-cadet.c index dba517a7b..932d069a1 100644 --- a/src/cadet/gnunet-cadet.c +++ b/src/cadet/gnunet-cadet.c @@ -11,7 +11,7 @@ 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 . @@ -103,7 +103,7 @@ static struct GNUNET_CADET_GetPath *gpo; /** * Active peer listing operation. - */ + */ static struct GNUNET_CADET_PeersLister *plo; /** @@ -220,7 +220,7 @@ shutdown_task (void *cls) { GNUNET_CADET_channel_destroy (ch); ch = NULL; - } + } if (NULL != gpo) { GNUNET_CADET_get_path_cancel (gpo); @@ -306,12 +306,12 @@ read_stdio (void *cls) if (GNUNET_NO == echo) { // Use MQ's notification if too much data of stdin is pooring in too fast. - if (STREAM_BUFFER_SIZE < sent_pkt) + if (STREAM_BUFFER_SIZE < sent_pkt) { GNUNET_MQ_notify_sent (env, mq_cb, cls); sent_pkt = 0; } - else + else { listen_stdio (); } @@ -563,7 +563,7 @@ path_callback (void *cls, ppd->path_length); for (unsigned int i = 0; i < ppd->path_length; i++) FPRINTF (stdout, - "%s ", + (i == ppd->target_offset) ? "*%s* " : "%s ", GNUNET_i2s (&ppd->path[i])); FPRINTF (stdout, "\n"); @@ -626,7 +626,7 @@ show_peer (void *cls) GNUNET_CRYPTO_eddsa_public_key_from_string (peer_id, strlen (peer_id), &pid.public_key)) - { + { fprintf (stderr, _("Invalid peer ID `%s'\n"), peer_id); @@ -859,7 +859,7 @@ main (int argc, GNUNET_GETOPT_option_flag ('e', "echo", gettext_noop ("Activate echo mode"), - &echo), + &echo), GNUNET_GETOPT_option_string ('o', "open-port", "SHARED_SECRET", diff --git a/src/cadet/gnunet-service-cadet.c b/src/cadet/gnunet-service-cadet.c index d64242943..e29330f99 100644 --- a/src/cadet/gnunet-service-cadet.c +++ b/src/cadet/gnunet-service-cadet.c @@ -885,6 +885,13 @@ path_info_iterator (void *cls, path_length = GCPP_get_length (path); path_size = sizeof (struct GNUNET_PeerIdentity) * path_length; if (sizeof (*resp) + path_size > UINT16_MAX) + { + /* try just giving the relevant path */ + path_length = GNUNET_MIN ((UINT16_MAX - sizeof (*resp)) / sizeof (struct GNUNET_PeerIdentity), + off); + path_size = sizeof (struct GNUNET_PeerIdentity) * path_length; + } + if (sizeof (*resp) + path_size > UINT16_MAX) { LOG (GNUNET_ERROR_TYPE_WARNING, "Path of %u entries is too long for info message\n", @@ -899,9 +906,10 @@ path_info_iterator (void *cls, /* Don't copy first peer. First peer is always the local one. Last * peer is always the destination (leave as 0, EOL). */ - for (unsigned int i = 0; i <= off; i++) + for (unsigned int i = 0; i < path_length; i++) id[i] = *GCP_get_id (GCPP_get_peer_at_offset (path, i)); + resp->off = htonl (off); GNUNET_MQ_send (mq, env); return GNUNET_YES; diff --git a/src/include/gnunet_cadet_service.h b/src/include/gnunet_cadet_service.h index ac3d11216..b8326657d 100644 --- a/src/include/gnunet_cadet_service.h +++ b/src/include/gnunet_cadet_service.h @@ -11,7 +11,7 @@ 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 . @@ -369,7 +369,7 @@ GNUNET_CADET_channel_get_info (struct GNUNET_CADET_Channel *channel, /** * Internal details about a channel. - */ + */ struct GNUNET_CADET_ChannelInternals { /** @@ -431,7 +431,7 @@ GNUNET_CADET_get_channel_cancel (struct GNUNET_CADET_ChannelMonitor *cm); /** * Information we return per peer. - */ + */ struct GNUNET_CADET_PeerListEntry { /** @@ -446,7 +446,7 @@ struct GNUNET_CADET_PeerListEntry /** * Number of disjoint known paths to @e peer. - */ + */ unsigned int n_paths; /** @@ -504,7 +504,7 @@ GNUNET_CADET_list_peers_cancel (struct GNUNET_CADET_PeersLister *pl); /** * Detailed information we return per peer. - */ + */ struct GNUNET_CADET_PeerPathDetail { /** @@ -512,6 +512,11 @@ struct GNUNET_CADET_PeerPathDetail */ struct GNUNET_PeerIdentity peer; + /** + * Offset of the target peer on the @e path. + */ + unsigned int target_offset; + /** * Number of entries on the @e path. */ @@ -583,7 +588,7 @@ struct GNUNET_CADET_TunnelDetails /** * How many channels use the tunnel. - */ + */ uint32_t channels; /** @@ -597,8 +602,8 @@ struct GNUNET_CADET_TunnelDetails uint16_t estate; /** - * What is our connectivity state? - */ + * What is our connectivity state? + */ uint16_t cstate; }; diff --git a/src/rps/profiler_rps.conf b/src/rps/profiler_rps.conf index 375015cae..dc156f876 100644 --- a/src/rps/profiler_rps.conf +++ b/src/rps/profiler_rps.conf @@ -84,7 +84,7 @@ DISABLE_TRY_CONNECT = YES [cadet] OPTIONS=-l /tmp/rps_profiler_logs/cadet-[]-%Y-%m-%d.log -PREFIX = valgrind +PREFIX = valgrind --log-file=/home/grothoff/cadet.%p.log #[arm] #GLOBAL_POSTFIX=-l /tmp/rps_profiler_logs/other-[]-%Y-%m-%d.log -- cgit v1.2.3 From b5296ebccf5190bfc9f7976a1c88cd86d4ccf44c Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 13 Feb 2019 18:25:39 +0100 Subject: undo accidental commit --- src/rps/profiler_rps.conf | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/rps/profiler_rps.conf b/src/rps/profiler_rps.conf index dc156f876..6049da5a0 100644 --- a/src/rps/profiler_rps.conf +++ b/src/rps/profiler_rps.conf @@ -84,7 +84,6 @@ DISABLE_TRY_CONNECT = YES [cadet] OPTIONS=-l /tmp/rps_profiler_logs/cadet-[]-%Y-%m-%d.log -PREFIX = valgrind --log-file=/home/grothoff/cadet.%p.log #[arm] #GLOBAL_POSTFIX=-l /tmp/rps_profiler_logs/other-[]-%Y-%m-%d.log -- cgit v1.2.3 From a4475afe1ad535c898bb0be7f30d2d3eff14dddf Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 13 Feb 2019 19:31:49 +0100 Subject: implementing libgnunettransportaddress --- src/include/gnunet_protocols.h | 33 ++-- src/include/gnunet_transport_address_service.h | 2 +- src/transport/Makefile.am | 10 + src/transport/transport_api2_address.c | 246 +++++++++++++++++++++++++ 4 files changed, 277 insertions(+), 14 deletions(-) create mode 100644 src/transport/transport_api2_address.c (limited to 'src') diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index 793430184..29db8372f 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h @@ -3106,40 +3106,47 @@ extern "C" /** * Type of a fragment of a CORE message created by transport to adjust * message length to a queue's MTU. - */ + */ #define GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT 1214 -/** +/** * Acknowledgement generated for a fragment. - */ + */ #define GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT_ACK 1215 -/** +/** * Wrapper around non-fragmented CORE message used to measure RTT * and ensure reliability. - */ + */ #define GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_BOX 1216 -/** +/** * Confirmation for a #GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_BOX. - */ + */ #define GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_ACK 1217 -/** +/** * Message sent for topology discovery at transport level. - */ + */ #define GNUNET_MESSAGE_TYPE_TRANSPORT_DV_LEARN 1218 -/** +/** * Source-routed transport message based DV information gathered. - */ + */ #define GNUNET_MESSAGE_TYPE_TRANSPORT_DV_BOX 1219 /** * Transport signalling incoming backchannel message to a communicator. - */ + */ #define GNUNET_MESSAGE_TYPE_TRANSPORT_COMMUNICATOR_BACKCHANNEL_INCOMING 1220 +/** + * We learned a possible network address of another peer. Transport + * should consider verifying it, and if successful, remembering it + * in the Peerstore. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_CONSIDER_VERIFY 1221 + /** * Message sent to indicate to the transport that a monitor @@ -3230,7 +3237,7 @@ extern "C" /** * TCP communicator end of stream. - */ + */ #define GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH 1452 /** diff --git a/src/include/gnunet_transport_address_service.h b/src/include/gnunet_transport_address_service.h index 86d0a423e..afd065d66 100644 --- a/src/include/gnunet_transport_address_service.h +++ b/src/include/gnunet_transport_address_service.h @@ -94,7 +94,7 @@ GNUNET_TRANSPORT_address_disconnect (struct GNUNET_TRANSPORT_AddressHandle *ch); * @param raw_size number of bytes in @a raw */ void -GNUNET_TRANSPORT_address_try (struct GNUNET_TRANSPORT_CommunicatorHandle *ch, +GNUNET_TRANSPORT_address_try (struct GNUNET_TRANSPORT_AddressHandle *ch, const void *raw, const size_t raw_size); diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am index 93615b023..9cf16ddb6 100644 --- a/src/transport/Makefile.am +++ b/src/transport/Makefile.am @@ -154,6 +154,7 @@ endif lib_LTLIBRARIES = \ libgnunettransport.la \ + libgnunettransportaddress.la \ libgnunettransportcore.la \ libgnunettransportcommunicator.la \ libgnunettransportmonitor.la \ @@ -197,6 +198,15 @@ libgnunettransport_la_LDFLAGS = \ +libgnunettransportaddress_la_SOURCES = \ + transport_api2_address.c +libgnunettransportaddress_la_LIBADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(GN_LIBINTL) +libgnunettransportaddress_la_LDFLAGS = \ + $(GN_LIB_LDFLAGS) $(WINFLAGS) \ + -version-info 0:0:0 + libgnunettransportcore_la_SOURCES = \ transport_api2_core.c libgnunettransportcore_la_LIBADD = \ diff --git a/src/transport/transport_api2_address.c b/src/transport/transport_api2_address.c new file mode 100644 index 000000000..0693a51ac --- /dev/null +++ b/src/transport/transport_api2_address.c @@ -0,0 +1,246 @@ +/* + This file is part of GNUnet. + Copyright (C) 2009-2013, 2016, 2018, 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 + 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 transport/transport_api2_address.c + * @brief library to inform the transport service about addresses to be validated + * @author Christian Grothoff + */ +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_constants.h" +#include "gnunet_protocols.h" +#include "gnunet_transport_address_service.h" +#include "gnunet_ats_transport_service.h" +#include "transport.h" + +#define LOG(kind,...) GNUNET_log_from (kind, "transport-api-address",__VA_ARGS__) + + +/** + * Handle for the transport service (includes all of the + * state for the transport service). + */ +struct GNUNET_TRANSPORT_AddressHandle +{ + + /** + * My client connection to the transport service. + */ + struct GNUNET_MQ_Handle *mq; + + /** + * My configuration. + */ + const struct GNUNET_CONFIGURATION_Handle *cfg; + + /** + * ID of the task trying to reconnect to the service. + */ + struct GNUNET_SCHEDULER_Task *reconnect_task; + + /** + * Delay until we try to reconnect. + */ + struct GNUNET_TIME_Relative reconnect_delay; + +}; + + +/** + * Function that will schedule the job that will try + * to connect us again to the client. + * + * @param h transport service to reconnect + */ +static void +disconnect_and_schedule_reconnect (struct GNUNET_TRANSPORT_AddressHandle *h); + + +/** + * Generic error handler, called with the appropriate + * error code and the same closure specified at the creation of + * the message queue. + * Not every message queue implementation supports an error handler. + * + * @param cls closure with the `struct GNUNET_TRANSPORT_AddressHandle *` + * @param error error code + */ +static void +mq_error_handler (void *cls, + enum GNUNET_MQ_Error error) +{ + struct GNUNET_TRANSPORT_AddressHandle *h = cls; + + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Error receiving from transport service, disconnecting temporarily.\n"); + disconnect_and_schedule_reconnect (h); +} + + +/** + * Try again to connect to transport service. + * + * @param cls the handle to the transport service + */ +static void +reconnect (void *cls) +{ + struct GNUNET_TRANSPORT_AddressHandle *h = cls; + struct GNUNET_MQ_MessageHandler handlers[] = { + GNUNET_MQ_handler_end () + }; + + h->reconnect_task = NULL; + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Connecting to transport service.\n"); + GNUNET_assert (NULL == h->mq); + h->mq = GNUNET_CLIENT_connect (h->cfg, + "transport", + handlers, + &mq_error_handler, + h); +} + + +/** + * Disconnect from the transport service. + * + * @param h transport service to reconnect + */ +static void +disconnect (struct GNUNET_TRANSPORT_AddressHandle *h) +{ + if (NULL != h->mq) + { + GNUNET_MQ_destroy (h->mq); + h->mq = NULL; + } +} + + +/** + * Function that will schedule the job that will try + * to connect us again to the client. + * + * @param h transport service to reconnect + */ +static void +disconnect_and_schedule_reconnect (struct GNUNET_TRANSPORT_AddressHandle *h) +{ + GNUNET_assert (NULL == h->reconnect_task); + disconnect (h); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Scheduling task to reconnect to transport service in %s.\n", + GNUNET_STRINGS_relative_time_to_string (h->reconnect_delay, + GNUNET_YES)); + h->reconnect_task = + GNUNET_SCHEDULER_add_delayed (h->reconnect_delay, + &reconnect, + h); + h->reconnect_delay = GNUNET_TIME_STD_BACKOFF (h->reconnect_delay); +} + + +/** + * Connect to the transport service. + * + * @param cfg configuration to use + * @return NULL on error + */ +struct GNUNET_TRANSPORT_AddressHandle * +GNUNET_TRANSPORT_address_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + struct GNUNET_TRANSPORT_AddressHandle *h; + + h = GNUNET_new (struct GNUNET_TRANSPORT_AddressHandle); + h->cfg = cfg; + h->reconnect_delay = GNUNET_TIME_UNIT_ZERO; + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Connecting to transport service\n"); + reconnect (h); + if (NULL == h->mq) + { + GNUNET_free (h); + return NULL; + } + return h; +} + + +/** + * Disconnect from the transport service. + * + * @param handle handle to the service as returned from #GNUNET_TRANSPORT_address_connect() + */ +void +GNUNET_TRANSPORT_address_disconnect (struct GNUNET_TRANSPORT_AddressHandle *handle) +{ + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Transport disconnect called!\n"); + /* this disconnects all neighbours... */ + disconnect (handle); + /* and now we stop trying to connect again... */ + if (NULL != handle->reconnect_task) + { + GNUNET_SCHEDULER_cancel (handle->reconnect_task); + handle->reconnect_task = NULL; + } + GNUNET_free (handle); +} + + +/** + * The client has learned about a possible address for peer @a pid + * (i.e. via broadcast, multicast, DHT, ...). The transport service + * should consider validating it. Note that the plugin is NOT expected + * to have verified the signature, the transport service must decide + * whether to check the signature. + * + * While the notification is sent to @a ch asynchronously, this API + * does not return a handle as the delivery of addresses is simply + * unreliable, and if @a ch is down, the data provided will simply be + * lost. + * + * @param ch communicator handle + * @param raw raw address data + * @param raw_size number of bytes in @a raw + */ +void +GNUNET_TRANSPORT_address_try (struct GNUNET_TRANSPORT_AddressHandle *ch, + const void *raw, + const size_t raw_size) +{ + struct GNUNET_MQ_Envelope *env; + struct GNUNET_MessageHeader *hdr; + + env = GNUNET_MQ_msg_extra (hdr, + raw_size, + GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_CONSIDER_VERIFY); + memcpy (&hdr[1], + raw, + raw_size); + GNUNET_MQ_send (ch->mq, + env); +} + + + +/* end of transport_api2_address.c */ -- cgit v1.2.3 From 94911c3e57d5f77ddf68032789244d0475955149 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 13 Feb 2019 19:42:57 +0100 Subject: add handle_address_consider_verify skeleton --- src/include/gnunet_hello_lib.h | 2 +- src/include/gnunet_transport_address_service.h | 2 + src/transport/gnunet-service-tng.c | 349 +++++++++++++++---------- src/transport/transport.h | 26 ++ src/transport/transport_api2_address.c | 5 +- 5 files changed, 237 insertions(+), 147 deletions(-) (limited to 'src') diff --git a/src/include/gnunet_hello_lib.h b/src/include/gnunet_hello_lib.h index c2256fd0a..fcd422701 100644 --- a/src/include/gnunet_hello_lib.h +++ b/src/include/gnunet_hello_lib.h @@ -526,7 +526,7 @@ GNUNET_HELLO_extract_address (const void *raw, * * @param address a peer's address * @return NULL if the address is mal-formed, otherwise the prefix - */ + */ char * GNUNET_HELLO_address_to_prefix (const char *address); diff --git a/src/include/gnunet_transport_address_service.h b/src/include/gnunet_transport_address_service.h index afd065d66..9f0717d00 100644 --- a/src/include/gnunet_transport_address_service.h +++ b/src/include/gnunet_transport_address_service.h @@ -90,11 +90,13 @@ GNUNET_TRANSPORT_address_disconnect (struct GNUNET_TRANSPORT_AddressHandle *ch); * lost. * * @param ch communicator handle + * @param pid peer the address is for * @param raw raw address data * @param raw_size number of bytes in @a raw */ void GNUNET_TRANSPORT_address_try (struct GNUNET_TRANSPORT_AddressHandle *ch, + const struct GNUNET_PeerIdentity *pid, const void *raw, const size_t raw_size); diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c index a32d1872c..1d6329c21 100644 --- a/src/transport/gnunet-service-tng.c +++ b/src/transport/gnunet-service-tng.c @@ -33,16 +33,17 @@ * transport-to-transport traffic) * * Implement next: - * - ACK handling / retransmission + * - ACK handling / retransmission + * - address verification * - track RTT, distance, loss, etc. * - DV data structures: * + learning - * + forgetting + * + forgetting * + using them! * - routing of messages (using DV data structures!) * - handling of DV-boxed messages that need to be forwarded * - backchannel message encryption & decryption - * - + * - * * Easy: * - use ATS bandwidth allocation callback and schedule transmissions! @@ -59,7 +60,7 @@ * (requires planning at receiver, and additional MST-style demultiplex * at receiver!) * - could avoid copying body of message into each fragment and keep - * fragments as just pointers into the original message and only + * fragments as just pointers into the original message and only * fully build fragments just before transmission (optimization, should * reduce CPU and memory use) * @@ -128,7 +129,7 @@ /** * How many messages can we have pending for a given communicator * process before we start to throttle that communicator? - * + * * Used if a communicator might be CPU-bound and cannot handle the traffic. */ #define COMMUNICATOR_TOTAL_QUEUE_LIMIT 512 @@ -137,7 +138,7 @@ * How many messages can we have pending for a given session (queue to * a particular peer via a communicator) process before we start to * throttle that queue? - * + * * Used if ATS assigns more bandwidth to a particular transmission * method than that transmission method can right now handle. (Yes, * ATS should eventually notice utilization below allocation and @@ -182,7 +183,7 @@ struct TransportBackchannelEncapsulationMessage // FIXME: probably should add random IV here as well, // especially if we re-use ephemeral keys! - + /** * HMAC over the ciphertext of the encrypted, variable-size * body that follows. Verified via DH of @e target and @@ -211,8 +212,8 @@ struct EphemeralConfirmation * only interpret the value as a mononic time and reject * "older" values than the last one observed. Even with this, * there is no real guarantee against replay achieved here, - * as the latest timestamp is not persisted. This is - * necessary as we do not want to require synchronized + * as the latest timestamp is not persisted. This is + * necessary as we do not want to require synchronized * clocks and may not have a bidirectional communication * channel. Communicators must protect against replay * attacks when using backchannel communication! @@ -360,17 +361,17 @@ struct TransportFragmentBox /** * Original message ID for of the message that all the1 * fragments belong to. Must be the same for all fragments. - */ + */ struct GNUNET_ShortHashCode msg_uuid; /** * Offset of this fragment in the overall message. - */ + */ uint16_t frag_off GNUNET_PACKED; /** * Total size of the message that is being fragmented. - */ + */ uint16_t msg_size GNUNET_PACKED; }; @@ -399,13 +400,13 @@ struct TransportFragmentAckMessage /** * Bitfield of up to 64 additional fragments following the * @e msg_uuid being acknowledged by this message. - */ + */ uint64_t extra_acks GNUNET_PACKED; /** * Original message ID for of the message that all the * fragments belong to. - */ + */ struct GNUNET_ShortHashCode msg_uuid; /** @@ -431,7 +432,7 @@ struct TransportFragmentAckMessage * to a subset of their neighbours to limit discoverability of the * network topology). To the extend that the @e bidirectional bits * are set, peers may learn the inverse paths even if they did not - * initiate. + * initiate. * * Unless received on a bidirectional queue and @e num_hops just * zero, peers that can forward to the initator should always try to @@ -456,13 +457,13 @@ struct TransportDVLearn * to possibly instantly learn a path in both directions. Each peer * should shift this value by one to the left, and then set the * lowest bit IF the current sender can be reached from it (without - * DV routing). - */ + * DV routing). + */ uint16_t bidirectional GNUNET_PACKED; /** * Peers receiving this message and delaying forwarding to other - * peers for any reason should increment this value such as to + * peers for any reason should increment this value such as to * enable the origin to determine the actual network-only delay * in addition to the real-time delay (assuming the message loops * back to the origin). @@ -473,11 +474,11 @@ struct TransportDVLearn * Identity of the peer that started this learning activity. */ struct GNUNET_PeerIdentity initiator; - + /* Followed by @e num_hops `struct GNUNET_PeerIdentity` values, excluding the initiator of the DV trace; the last entry is the current sender; the current peer must not be included. */ - + }; @@ -514,7 +515,7 @@ struct TransportDVBox * Number of hops this messages includes. In NBO. */ uint16_t num_hops GNUNET_PACKED; - + /** * Identity of the peer that originated the message. */ @@ -564,7 +565,7 @@ enum ClientType /** * Entry in our cache of ephemeral keys we currently use. * This way, we only sign an ephemeral once per @e target, - * and then can re-use it over multiple + * and then can re-use it over multiple * #GNUNET_MESSAGE_TYPE_TRANSPORT_BACKCHANNEL_ENCAPSULATION * messages (as signing is expensive). */ @@ -632,39 +633,39 @@ struct DistanceVectorHop /** * Kept in a MDLL, sorted by @e timeout. - */ + */ struct DistanceVectorHop *next_dv; /** * Kept in a MDLL, sorted by @e timeout. - */ + */ struct DistanceVectorHop *prev_dv; /** * Kept in a MDLL. - */ + */ struct DistanceVectorHop *next_neighbour; /** * Kept in a MDLL. - */ + */ struct DistanceVectorHop *prev_neighbour; /** * What would be the next hop to @e target? - */ + */ struct Neighbour *next_hop; /** * Distance vector entry this hop belongs with. - */ + */ struct DistanceVector *dv; - + /** * Array of @e distance hops to the target, excluding @e next_hop. * NULL if the entire path is us to @e next_hop to `target`. Allocated * at the end of this struct. - */ + */ const struct GNUNET_PeerIdentity *path; /** @@ -672,11 +673,11 @@ struct DistanceVectorHop * while learning? */ struct GNUNET_TIME_Absolute timeout; - + /** * How many hops in total to the `target` (excluding @e next_hop and `target` itself), * thus 0 still means a distance of 2 hops (to @e next_hop and then to `target`)? - */ + */ unsigned int distance; }; @@ -695,12 +696,12 @@ struct DistanceVector /** * Known paths to @e target. - */ + */ struct DistanceVectorHop *dv_head; /** * Known paths to @e target. - */ + */ struct DistanceVectorHop *dv_tail; /** @@ -724,19 +725,19 @@ struct QueueEntry /** * Kept as a DLL. - */ + */ struct QueueEntry *next; /** * Kept as a DLL. - */ + */ struct QueueEntry *prev; /** * ATS session this entry is queued with. */ struct GNUNET_ATS_Session *session; - + /** * Message ID used for this message with the queue used for transmission. */ @@ -772,12 +773,12 @@ struct GNUNET_ATS_Session /** * Head of DLL of unacked transmission requests. - */ + */ struct QueueEntry *queue_head; /** * End of DLL of unacked transmission requests. - */ + */ struct QueueEntry *queue_tail; /** @@ -803,9 +804,9 @@ struct GNUNET_ATS_Session /** * Task scheduled for the time when this queue can (likely) transmit the * next message. Still needs to check with the @e tracker_out to be sure. - */ + */ struct GNUNET_SCHEDULER_Task *transmit_task; - + /** * Our current RTT estimate for this ATS session. */ @@ -813,9 +814,9 @@ struct GNUNET_ATS_Session /** * Message ID generator for transmissions on this queue. - */ + */ uint64_t mid_gen; - + /** * Unique identifier of this ATS session with the communicator. */ @@ -845,7 +846,7 @@ struct GNUNET_ATS_Session * Length of the DLL starting at @e queue_head. */ unsigned int queue_length; - + /** * Network type offered by this ATS session. */ @@ -870,14 +871,14 @@ struct GNUNET_ATS_Session /** * Information we keep for a message that we are reassembling. - */ + */ struct ReassemblyContext { /** * Original message ID for of the message that all the * fragments belong to. - */ + */ struct GNUNET_ShortHashCode msg_uuid; /** @@ -887,7 +888,7 @@ struct ReassemblyContext /** * Entry in the reassembly heap (sorted by expiration). - */ + */ struct GNUNET_CONTAINER_HeapNode *hn; /** @@ -905,7 +906,7 @@ struct ReassemblyContext * task is for the latter case. */ struct GNUNET_SCHEDULER_Task *ack_task; - + /** * At what time will we give up reassembly of this message? */ @@ -928,7 +929,7 @@ struct ReassemblyContext * to be acknowledged in the next cummulative ACK. */ uint64_t extra_acks; - + /** * Unique ID of the lowest fragment UUID to be acknowledged in the * next cummulative ACK. Only valid if @e num_acks > 0. @@ -940,7 +941,7 @@ struct ReassemblyContext * whenever we send a #GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT_ACK. */ unsigned int num_acks; - + /** * How big is the message we are reassembling in total? */ @@ -973,21 +974,21 @@ struct Neighbour * Map with `struct ReassemblyContext` structs for fragments under * reassembly. May be NULL if we currently have no fragments from * this @e pid (lazy initialization). - */ + */ struct GNUNET_CONTAINER_MultiShortmap *reassembly_map; /** * Heap with `struct ReassemblyContext` structs for fragments under * reassembly. May be NULL if we currently have no fragments from * this @e pid (lazy initialization). - */ + */ struct GNUNET_CONTAINER_Heap *reassembly_heap; /** * Task to free old entries from the @e reassembly_heap and @e reassembly_map. */ struct GNUNET_SCHEDULER_Task *reassembly_timeout_task; - + /** * Head of list of messages pending for this neighbour. */ @@ -1001,13 +1002,13 @@ struct Neighbour /** * Head of MDLL of DV hops that have this neighbour as next hop. Must be * purged if this neighbour goes down. - */ + */ struct DistanceVectorHop *dv_head; /** * Tail of MDLL of DV hops that have this neighbour as next hop. Must be * purged if this neighbour goes down. - */ + */ struct DistanceVectorHop *dv_tail; /** @@ -1022,7 +1023,7 @@ struct Neighbour /** * Task run to cleanup pending messages that have exceeded their timeout. - */ + */ struct GNUNET_SCHEDULER_Task *timeout_task; /** @@ -1039,15 +1040,15 @@ struct Neighbour /** * What is the earliest timeout of any message in @e pending_msg_tail? - */ + */ struct GNUNET_TIME_Absolute earliest_timeout; - + }; /** * Types of different pending messages. - */ + */ enum PendingMessageType { @@ -1071,7 +1072,7 @@ enum PendingMessageType */ PMT_ACKNOWLEDGEMENT = 3 - + }; @@ -1088,13 +1089,13 @@ enum PendingMessageType * either calculate the next fragment (based on @e frag_off) from the * current node, or, if all fragments have already been created, * descend to the @e head_frag. Even though the node was already - * fragmented, the fragment may be too big if the fragment was + * fragmented, the fragment may be too big if the fragment was * generated for a queue with a larger MTU. In this case, the node * may be fragmented again, thus creating a tree. * * When acknowledgements for fragments are received, the tree - * must be pruned, removing those parts that were already - * acknowledged. When fragments are sent over a reliable + * must be pruned, removing those parts that were already + * acknowledged. When fragments are sent over a reliable * channel, they can be immediately removed. * * If a message is ever fragmented, then the original "full" message @@ -1117,7 +1118,7 @@ struct PendingMessage * Kept in a MDLL of messages from this @a client (if @e pmt is #PMT_CORE) */ struct PendingMessage *next_client; - + /** * Kept in a MDLL of messages from this @a client (if @e pmt is #PMT_CORE) */ @@ -1127,7 +1128,7 @@ struct PendingMessage * Kept in a MDLL of messages from this @a cpm (if @e pmt is #PMT_FRAGMENT_BOx) */ struct PendingMessage *next_frag; - + /** * Kept in a MDLL of messages from this @a cpm (if @e pmt is #PMT_FRAGMENT_BOX) */ @@ -1135,24 +1136,24 @@ struct PendingMessage /** * This message, reliability boxed. Only possibly available if @e pmt is #PMT_CORE. - */ + */ struct PendingMessage *bpm; - + /** * Target of the request. */ struct Neighbour *target; - + /** * Client that issued the transmission request, if @e pmt is #PMT_CORE. */ struct TransportClient *client; - + /** * Head of a MDLL of fragments created for this core message. */ struct PendingMessage *head_frag; - + /** * Tail of a MDLL of fragments created for this core message. */ @@ -1162,7 +1163,7 @@ struct PendingMessage * Our parent in the fragmentation tree. */ struct PendingMessage *frag_parent; - + /** * At what time should we give up on the transmission (and no longer retry)? */ @@ -1178,12 +1179,12 @@ struct PendingMessage * initialized if @e msg_uuid_set is #GNUNET_YES). */ struct GNUNET_ShortHashCode msg_uuid; - + /** * Counter incremented per generated fragment. - */ + */ uint32_t frag_uuidgen; - + /** * Type of the pending message. */ @@ -1196,14 +1197,14 @@ struct PendingMessage /** * Offset at which we should generate the next fragment. - */ + */ uint16_t frag_off; /** * #GNUNET_YES once @e msg_uuid was initialized */ int16_t msg_uuid_set; - + /* Followed by @e bytes_msg to transmit */ }; @@ -1303,7 +1304,7 @@ struct TransportClient struct { /** - * Head of list of messages pending for this client, sorted by + * Head of list of messages pending for this client, sorted by * transmission time ("next_attempt" + possibly internal prioritization). */ struct PendingMessage *pending_msg_head; @@ -1371,7 +1372,7 @@ struct TransportClient * is globally unable to keep up. */ unsigned int total_queue_length; - + /** * Characteristics of this communicator. */ @@ -1546,7 +1547,7 @@ free_distance_vector_hop (struct DistanceVectorHop *dvh) GNUNET_free (dvh); if (NULL == dv->dv_head) { - GNUNET_assert (GNUNET_YES == + GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multipeermap_remove (dv_routes, &dv->target, dv)); @@ -1751,7 +1752,7 @@ free_reassembly_cb (void *cls, struct ReassemblyContext *rc = value; (void) cls; (void) key; - + free_reassembly_context (rc); return GNUNET_OK; } @@ -1766,7 +1767,7 @@ static void free_neighbour (struct Neighbour *neighbour) { struct DistanceVectorHop *dvh; - + GNUNET_assert (NULL == neighbour->session_head); GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multipeermap_remove (neighbours, @@ -1868,25 +1869,25 @@ cores_send_disconnect_info (const struct GNUNET_PeerIdentity *pid) /** * We believe we are ready to transmit a message on a queue. Double-checks - * with the queue's "tracker_out" and then gives the message to the + * with the queue's "tracker_out" and then gives the message to the * communicator for transmission (updating the tracker, and re-scheduling - * itself if applicable). + * itself if applicable). * * @param cls the `struct GNUNET_ATS_Session` to process transmissions for - */ + */ static void transmit_on_queue (void *cls); /** - * Schedule next run of #transmit_on_queue(). Does NOTHING if + * Schedule next run of #transmit_on_queue(). Does NOTHING if * we should run immediately or if the message queue is empty. * Test for no task being added AND queue not being empty to * transmit immediately afterwards! This function must only * be called if the message queue is non-empty! * * @param queue the queue to do scheduling for - */ + */ static void schedule_transmit_on_queue (struct GNUNET_ATS_Session *queue) { @@ -1901,7 +1902,7 @@ schedule_transmit_on_queue (struct GNUNET_ATS_Session *queue) GNUNET_STATISTICS_update (GST_stats, "# Transmission throttled due to communicator queue limit", 1, - GNUNET_NO); + GNUNET_NO); return; } if (queue->queue_length >= SESSION_QUEUE_LIMIT) @@ -1909,10 +1910,10 @@ schedule_transmit_on_queue (struct GNUNET_ATS_Session *queue) GNUNET_STATISTICS_update (GST_stats, "# Transmission throttled due to session queue limit", 1, - GNUNET_NO); + GNUNET_NO); return; } - + wsize = (0 == queue->mtu) ? pm->bytes_msg /* FIXME: add overheads? */ : queue->mtu; @@ -2200,7 +2201,7 @@ check_client_send (void *cls, * Free fragment tree below @e root, excluding @e root itself. * * @param root root of the tree to free - */ + */ static void free_fragment_tree (struct PendingMessage *root) { @@ -2315,7 +2316,7 @@ check_queue_timeouts (void *cls) GNUNET_NO); client_send_response (pm, GNUNET_NO, - 0); + 0); continue; } earliest_timeout = GNUNET_TIME_absolute_min (earliest_timeout, @@ -2394,7 +2395,7 @@ handle_client_send (void *cls, target->earliest_timeout.abs_value_us = pm->timeout.abs_value_us; if (NULL != target->timeout_task) GNUNET_SCHEDULER_cancel (target->timeout_task); - target->timeout_task + target->timeout_task = GNUNET_SCHEDULER_add_at (target->earliest_timeout, &check_queue_timeouts, target); @@ -2529,7 +2530,7 @@ expire_ephemerals (void *cls) * one, cache it and return it. * * @param pid peer to look up ephemeral for - * @param private_key[out] set to the private key + * @param private_key[out] set to the private key * @param ephemeral_key[out] set to the key * @param ephemeral_sender_sig[out] set to the signature * @param ephemeral_validity[out] set to the validity expiration time @@ -2543,7 +2544,7 @@ lookup_ephemeral (const struct GNUNET_PeerIdentity *pid, { struct EphemeralCacheEntry *ece; struct EphemeralConfirmation ec; - + ece = GNUNET_CONTAINER_multipeermap_get (ephemeral_map, pid); if ( (NULL != ece) && @@ -2605,7 +2606,7 @@ route_message (const struct GNUNET_PeerIdentity *target, GNUNET_free (hdr); } - + /** * Communicator requests backchannel transmission. Process the request. * @@ -2623,7 +2624,7 @@ handle_communicator_backchannel (void *cls, struct TransportBackchannelRequestPayload ppay; char *mpos; uint16_t msize; - + /* encapsulate and encrypt message */ msize = ntohs (cb->header.size) - sizeof (*cb) + sizeof (struct TransportBackchannelRequestPayload); enc = GNUNET_malloc (sizeof (*enc) + msize); @@ -2858,7 +2859,7 @@ struct CommunicatorMessageContext * * @param cmc context for demultiplexing * @param msg message to demultiplex - */ + */ static void demultiplex_with_cmc (struct CommunicatorMessageContext *cmc, const struct GNUNET_MessageHeader *msg); @@ -2936,7 +2937,7 @@ handle_raw_message (void *cls, env); } /* FIXME: consider doing this _only_ once the message - was drained from the CORE MQs to extend flow control to CORE! + was drained from the CORE MQs to extend flow control to CORE! (basically, increment counter in cmc, decrement on MQ send continuation! */ finish_cmc_handling (cmc); } @@ -2961,12 +2962,12 @@ check_fragment_box (void *cls, GNUNET_break_op (0); return GNUNET_SYSERR; } - if (bsize + ntohs (fb->frag_off) > ntohs (fb->msg_size)) + if (bsize + ntohs (fb->frag_off) > ntohs (fb->msg_size)) { GNUNET_break_op (0); return GNUNET_SYSERR; } - if (ntohs (fb->frag_off) >= ntohs (fb->msg_size)) + if (ntohs (fb->frag_off) >= ntohs (fb->msg_size)) { GNUNET_break_op (0); return GNUNET_SYSERR; @@ -3033,7 +3034,7 @@ handle_fragment_box (void *cls, if (NULL == n) { struct GNUNET_SERVICE_Client *client = cmc->tc->client; - + GNUNET_break (0); finish_cmc_handling (cmc); GNUNET_SERVICE_client_drop (client); @@ -3083,7 +3084,7 @@ handle_fragment_box (void *cls, finish_cmc_handling (cmc); return; } - + /* reassemble */ fsize = ntohs (fb->header.size) - sizeof (*fb); frag_off = ntohs (fb->frag_off); @@ -3099,7 +3100,7 @@ handle_fragment_box (void *cls, rc->msg_missing--; } } - + /* Compute cummulative ACK */ frag_uuid = ntohl (fb->frag_uuid); cdelay = GNUNET_TIME_absolute_get_duration (rc->last_frag); @@ -3138,7 +3139,7 @@ handle_fragment_box (void *cls, ( (rc->frag_uuid < frag_uuid + 64) && (rc->extra_acks == (rc->extra_acks & ~ ((1LLU << (64 - (rc->frag_uuid - frag_uuid))) - 1LLU))) ) ) ) { - /* can fit ack by shifting extra acks and starting at + /* can fit ack by shifting extra acks and starting at frag_uid, test above esured that the bits we will shift 'extra_acks' by are all zero. */ rc->extra_acks <<= (rc->frag_uuid - frag_uuid); @@ -3149,8 +3150,8 @@ handle_fragment_box (void *cls, if (65 == rc->num_acks) /* FIXME: maybe use smaller threshold? This is very aggressive. */ ack_now = GNUNET_YES; /* maximum acks received */ // FIXME: possibly also ACK based on RTT (but for that we'd need to - // determine the session used for the ACK first!) - + // determine the session used for the ACK first!) + /* is reassembly complete? */ if (0 != rc->msg_missing) { @@ -3174,7 +3175,7 @@ handle_fragment_box (void *cls, msg); /* FIXME: really free here? Might be bad if fragments are still en-route and we forget that we finished this reassembly immediately! - -> keep around until timeout? + -> keep around until timeout? -> shorten timeout based on ACK? */ free_reassembly_context (rc); } @@ -3191,7 +3192,7 @@ handle_fragment_ack (void *cls, const struct TransportFragmentAckMessage *fa) { struct CommunicatorMessageContext *cmc = cls; - + // FIXME: do work: identify original message; then identify fragments being acked; // remove those from the tree to prevent retransmission; // compute RTT @@ -3235,10 +3236,10 @@ handle_reliability_box (void *cls, /* FIXME: implement cummulative ACKs and ack_countdown, then setting the avg_ack_delay field below: */ - ack = GNUNET_malloc (sizeof (*ack) + + ack = GNUNET_malloc (sizeof (*ack) + sizeof (struct GNUNET_ShortHashCode)); ack->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_ACK); - ack->header.size = htons (sizeof (*ack) + + ack->header.size = htons (sizeof (*ack) + sizeof (struct GNUNET_ShortHashCode)); memcpy (&ack[1], &rb->msg_uuid, @@ -3263,7 +3264,7 @@ handle_reliability_ack (void *cls, const struct TransportReliabilityAckMessage *ra) { struct CommunicatorMessageContext *cmc = cls; - + // FIXME: do work: find message that was acknowledged, and // remove from transmission queue; update RTT. finish_cmc_handling (cmc); @@ -3318,7 +3319,7 @@ handle_backchannel_encapsulation (void *cls, // FIXME: check HMAC // FIXME: decrypt payload // FIXME: forward to specified communicator! - // (using GNUNET_MESSAGE_TYPE_TRANSPORT_COMMUNICATOR_BACKCHANNEL_INCOMING) + // (using GNUNET_MESSAGE_TYPE_TRANSPORT_COMMUNICATOR_BACKCHANNEL_INCOMING) finish_cmc_handling (cmc); } @@ -3375,7 +3376,7 @@ handle_dv_learn (void *cls, const struct TransportDVLearn *dvl) { struct CommunicatorMessageContext *cmc = cls; - + // FIXME: learn path from DV message (if bi-directional flags are set) // FIXME: expand DV message, forward on (unless path is getting too long) finish_cmc_handling (cmc); @@ -3406,7 +3407,7 @@ check_dv_box (void *cls, return GNUNET_SYSERR; } isize = ntohs (inbox->size); - if (size != sizeof (*dvb) + num_hops * sizeof (struct GNUNET_PeerIdentity) + isize) + if (size != sizeof (*dvb) + num_hops * sizeof (struct GNUNET_PeerIdentity) + isize) { GNUNET_break_op (0); return GNUNET_SYSERR; @@ -3442,14 +3443,14 @@ handle_dv_box (void *cls, { // FIXME: if we are not the target, shorten path and forward along. // Try from the _end_ of hops array if we know the given - // neighbour (shortening the path!). + // neighbour (shortening the path!). // NOTE: increment total_hops! finish_cmc_handling (cmc); return; } /* We are the target. Unbox and handle message. */ cmc->im.sender = dvb->origin; - cmc->total_hops = ntohs (dvb->total_hops); + cmc->total_hops = ntohs (dvb->total_hops); demultiplex_with_cmc (cmc, inbox); } @@ -3503,7 +3504,7 @@ handle_incoming_msg (void *cls, * * @param cmc context for demultiplexing * @param msg message to demultiplex - */ + */ static void demultiplex_with_cmc (struct CommunicatorMessageContext *cmc, const struct GNUNET_MessageHeader *msg) @@ -3593,7 +3594,7 @@ tracker_update_in_cb (void *cls) struct GNUNET_ATS_Session *queue = cls; struct GNUNET_TIME_Relative in_delay; unsigned int rsize; - + rsize = (0 == queue->mtu) ? IN_PACKET_SIZE_WITHOUT_MTU : queue->mtu; in_delay = GNUNET_BANDWIDTH_tracker_get_delay (&queue->tracker_in, rsize); @@ -3619,7 +3620,7 @@ set_pending_message_uuid (struct PendingMessage *pm) /** - * Fragment the given @a pm to the given @a mtu. Adds + * Fragment the given @a pm to the given @a mtu. Adds * additional fragments to the neighbour as well. If the * @a mtu is too small, generates and error for the @a pm * and returns NULL. @@ -3635,7 +3636,7 @@ fragment_message (struct PendingMessage *pm, struct PendingMessage *ff; set_pending_message_uuid (pm); - + /* This invariant is established in #handle_add_queue_message() */ GNUNET_assert (mtu > sizeof (struct TransportFragmentBox)); @@ -3743,7 +3744,7 @@ reliability_box_message (struct PendingMessage *pm) if (NULL != pm->bpm) return pm->bpm; /* already computed earlier: do nothing */ GNUNET_assert (NULL == pm->head_frag); - if (pm->bytes_msg + sizeof (rbox) > UINT16_MAX) + if (pm->bytes_msg + sizeof (rbox) > UINT16_MAX) { /* failed hard */ GNUNET_break (0); @@ -3753,7 +3754,7 @@ reliability_box_message (struct PendingMessage *pm) return NULL; } bpm = GNUNET_malloc (sizeof (struct PendingMessage) + - sizeof (rbox) + + sizeof (rbox) + pm->bytes_msg); bpm->target = pm->target; bpm->frag_parent = pm; @@ -3783,12 +3784,12 @@ reliability_box_message (struct PendingMessage *pm) /** * We believe we are ready to transmit a message on a queue. Double-checks - * with the queue's "tracker_out" and then gives the message to the + * with the queue's "tracker_out" and then gives the message to the * communicator for transmission (updating the tracker, and re-scheduling - * itself if applicable). + * itself if applicable). * * @param cls the `struct GNUNET_ATS_Session` to process transmissions for - */ + */ static void transmit_on_queue (void *cls) { @@ -3805,7 +3806,7 @@ transmit_on_queue (void *cls) if (NULL == (pm = n->pending_msg_head)) { /* no message pending, nothing to do here! */ - return; + return; } schedule_transmit_on_queue (queue); if (NULL != queue->transmit_task) @@ -3861,7 +3862,7 @@ transmit_on_queue (void *cls) queue->tc->details.communicator.total_queue_length++; GNUNET_MQ_send (queue->tc->mq, env); - + // FIXME: do something similar to the logic below // in defragmentation / reliability ACK handling! @@ -3879,7 +3880,7 @@ transmit_on_queue (void *cls) (PMT_FRAGMENT_BOX == s->pmt) ) { struct PendingMessage *pos; - + /* Fragment sent over reliabile channel */ free_fragment_tree (s); pos = s->frag_parent; @@ -3899,9 +3900,9 @@ transmit_on_queue (void *cls) pos->head_frag, pos->tail_frag, s); - GNUNET_free (s); + GNUNET_free (s); } - + /* Was this the last applicable fragmment? */ if ( (NULL == pm->head_frag) && (pm->frag_off == pm->bytes_msg) ) @@ -3968,7 +3969,7 @@ transmit_on_queue (void *cls) s); } } - + /* finally, re-schedule queue transmission task itself */ schedule_transmit_on_queue (queue); } @@ -4010,13 +4011,13 @@ tracker_excess_out_cb (void *cls) { /* FIXME: trigger excess bandwidth report to core? Right now, this is done internally within transport_api2_core already, - but we probably want to change the logic and trigger it + but we probably want to change the logic and trigger it from here via a message instead! */ /* TODO: maybe inform ATS at this point? */ GNUNET_STATISTICS_update (GST_stats, "# Excess outbound bandwidth reported", 1, - GNUNET_NO); + GNUNET_NO); } @@ -4034,7 +4035,7 @@ tracker_excess_in_cb (void *cls) GNUNET_STATISTICS_update (GST_stats, "# Excess inbound bandwidth reported", 1, - GNUNET_NO); + GNUNET_NO); } @@ -4113,7 +4114,7 @@ handle_add_queue_message (void *cls, .nt = queue->nt, .cc = tc->details.communicator.cc }; - + queue->sr = GNUNET_ATS_session_add (ats, &neighbour->pid, queue->address, @@ -4211,7 +4212,7 @@ handle_send_message_ack (void *cls, { struct TransportClient *tc = cls; struct QueueEntry *queue; - + if (CT_COMMUNICATOR != tc->type) { GNUNET_break (0); @@ -4238,12 +4239,12 @@ handle_send_message_ack (void *cls, queue = qe; break; } - break; + break; } if (NULL == queue) { /* this should never happen */ - GNUNET_break (0); + GNUNET_break (0); GNUNET_SERVICE_client_drop (tc->client); return; } @@ -4273,10 +4274,10 @@ handle_send_message_ack (void *cls, GNUNET_STATISTICS_update (GST_stats, "# Transmission throttled due to session queue limit", -1, - GNUNET_NO); + GNUNET_NO); schedule_transmit_on_queue (queue->session); } - + /* TODO: we also should react on the status! */ // FIXME: this probably requires queue->pm = s assignment! // FIXME: react to communicator status about transmission request. We got: @@ -4439,7 +4440,7 @@ ats_suggestion_cb (void *cls, GNUNET_STATISTICS_update (GST_stats, "# ATS suggestions ignored due to missing communicator", 1, - GNUNET_NO); + GNUNET_NO); return; } /* forward suggestion for queue creation to communicator */ @@ -4468,7 +4469,7 @@ ats_suggestion_cb (void *cls, * * @param cls the `struct TransportClient` * @param cqr confirmation message - */ + */ static void handle_queue_create_ok (void *cls, const struct GNUNET_TRANSPORT_CreateQueueResponse *cqr) @@ -4488,7 +4489,7 @@ handle_queue_create_ok (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Request #%u for communicator to create queue succeeded\n", (unsigned int) ntohs (cqr->request_id)); - GNUNET_SERVICE_client_continue (tc->client); + GNUNET_SERVICE_client_continue (tc->client); } @@ -4499,7 +4500,7 @@ handle_queue_create_ok (void *cls, * * @param cls the `struct TransportClient` * @param cqr failure message - */ + */ static void handle_queue_create_fail (void *cls, const struct GNUNET_TRANSPORT_CreateQueueResponse *cqr) @@ -4519,7 +4520,61 @@ handle_queue_create_fail (void *cls, "# ATS suggestions failed in queue creation at communicator", 1, GNUNET_NO); - GNUNET_SERVICE_client_continue (tc->client); + GNUNET_SERVICE_client_continue (tc->client); +} + + +/** + * Check #GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_CONSIDER_VERIFY + * messages. We do nothing here, real verification is done later. + * + * @param cls a `struct TransportClient *` + * @param msg message to verify + * @return #GNUNET_OK + */ +static int +check_address_consider_verify (void *cls, + const struct GNUNET_TRANSPORT_AddressToVerify *hdr) +{ + (void) cls; + (void) hdr; + return GNUNET_OK; +} + + +/** + * Given another peers address, consider checking it for validity + * and then adding it to the Peerstore. + * + * @param cls a `struct TransportClient` + * @param hdr message containing the raw address data and + * signature in the body, see #GNUNET_HELLO_extract_address() + */ +static void +handle_address_consider_verify (void *cls, + const struct GNUNET_TRANSPORT_AddressToVerify *hdr) +{ + char *address; + enum GNUNET_NetworkType nt; + struct GNUNET_TIME_Absolute expiration; + + (void) cls; + // FIXME: pre-check: do we know this address already? + // FIXME: pre-check: rate-limit signature verification / validation! + address = GNUNET_HELLO_extract_address (&hdr[1], + ntohs (hdr->header.size) - sizeof (*hdr), + &hdr->peer, + &nt, + &expiration); + if (NULL == address) + { + GNUNET_break_op (0); + return; + } + if (0 == GNUNET_TIME_absolute_get_remaining (expiration).rel_value_us) + return; /* expired */ + // FIXME: do begin actual verification here! + GNUNET_free (address); } @@ -4762,6 +4817,10 @@ GNUNET_SERVICE_MAIN GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_SETUP, struct GNUNET_TRANSPORT_AddQueueMessage, NULL), + GNUNET_MQ_hd_var_size (address_consider_verify, + GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_CONSIDER_VERIFY, + struct GNUNET_TRANSPORT_AddressToVerify, + NULL), GNUNET_MQ_hd_fixed_size (del_queue_message, GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_TEARDOWN, struct GNUNET_TRANSPORT_DelQueueMessage, diff --git a/src/transport/transport.h b/src/transport/transport.h index 931ba4810..c0e02c3d9 100644 --- a/src/transport/transport.h +++ b/src/transport/transport.h @@ -1081,6 +1081,32 @@ struct GNUNET_TRANSPORT_MonitorData }; + +/** + * Request to verify address. + */ +struct GNUNET_TRANSPORT_AddressToVerify +{ + + /** + * Type will be #GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_CONSIDER_VERIFY. + */ + struct GNUNET_MessageHeader header; + + /** + * Reserved. 0. + */ + uint32_t reserved; + + /** + * Peer the address is from. + */ + struct GNUNET_PeerIdentity peer; + + /* followed by variable-size raw address */ +}; + + #endif GNUNET_NETWORK_STRUCT_END diff --git a/src/transport/transport_api2_address.c b/src/transport/transport_api2_address.c index 0693a51ac..1ae1e5b1e 100644 --- a/src/transport/transport_api2_address.c +++ b/src/transport/transport_api2_address.c @@ -220,20 +220,23 @@ GNUNET_TRANSPORT_address_disconnect (struct GNUNET_TRANSPORT_AddressHandle *hand * lost. * * @param ch communicator handle + * @param pid peer the address is for * @param raw raw address data * @param raw_size number of bytes in @a raw */ void GNUNET_TRANSPORT_address_try (struct GNUNET_TRANSPORT_AddressHandle *ch, + const struct GNUNET_PeerIdentity *pid, const void *raw, const size_t raw_size) { struct GNUNET_MQ_Envelope *env; - struct GNUNET_MessageHeader *hdr; + struct GNUNET_TRANSPORT_AddressToVerify *hdr; env = GNUNET_MQ_msg_extra (hdr, raw_size, GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_CONSIDER_VERIFY); + hdr->peer = *pid; memcpy (&hdr[1], raw, raw_size); -- cgit v1.2.3