2 This file is part of GNUnet.
3 Copyright (C) 2009-2013, 2016, 2018, 2019 GNUnet e.V.
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 SPDX-License-Identifier: AGPL3.0-or-later
22 * @file transport/transport_api2_address.c
23 * @brief library to inform the transport service about addresses to be validated
24 * @author Christian Grothoff
27 #include "gnunet_util_lib.h"
28 #include "gnunet_constants.h"
29 #include "gnunet_protocols.h"
30 #include "gnunet_transport_address_service.h"
31 #include "gnunet_ats_transport_service.h"
32 #include "transport.h"
34 #define LOG(kind, ...) \
35 GNUNET_log_from (kind, "transport-api-address", __VA_ARGS__)
39 * Handle for the transport service (includes all of the
40 * state for the transport service).
42 struct GNUNET_TRANSPORT_AddressHandle
46 * My client connection to the transport service.
48 struct GNUNET_MQ_Handle *mq;
53 const struct GNUNET_CONFIGURATION_Handle *cfg;
56 * ID of the task trying to reconnect to the service.
58 struct GNUNET_SCHEDULER_Task *reconnect_task;
61 * Delay until we try to reconnect.
63 struct GNUNET_TIME_Relative reconnect_delay;
68 * Function that will schedule the job that will try
69 * to connect us again to the client.
71 * @param h transport service to reconnect
74 disconnect_and_schedule_reconnect (struct GNUNET_TRANSPORT_AddressHandle *h);
78 * Generic error handler, called with the appropriate
79 * error code and the same closure specified at the creation of
81 * Not every message queue implementation supports an error handler.
83 * @param cls closure with the `struct GNUNET_TRANSPORT_AddressHandle *`
84 * @param error error code
87 mq_error_handler (void *cls, enum GNUNET_MQ_Error error)
89 struct GNUNET_TRANSPORT_AddressHandle *h = cls;
91 LOG (GNUNET_ERROR_TYPE_DEBUG,
92 "Error receiving from transport service, disconnecting temporarily.\n");
93 disconnect_and_schedule_reconnect (h);
98 * Try again to connect to transport service.
100 * @param cls the handle to the transport service
103 reconnect (void *cls)
105 struct GNUNET_TRANSPORT_AddressHandle *h = cls;
106 struct GNUNET_MQ_MessageHandler handlers[] = {GNUNET_MQ_handler_end ()};
108 h->reconnect_task = NULL;
109 LOG (GNUNET_ERROR_TYPE_DEBUG, "Connecting to transport service.\n");
110 GNUNET_assert (NULL == h->mq);
112 GNUNET_CLIENT_connect (h->cfg, "transport", handlers, &mq_error_handler, h);
117 * Disconnect from the transport service.
119 * @param h transport service to disconnect
122 disconnect (struct GNUNET_TRANSPORT_AddressHandle *h)
126 GNUNET_MQ_destroy (h->mq);
133 * Function that will schedule the job that will try
134 * to connect us again to the client.
136 * @param h transport service to reconnect
139 disconnect_and_schedule_reconnect (struct GNUNET_TRANSPORT_AddressHandle *h)
141 GNUNET_assert (NULL == h->reconnect_task);
143 LOG (GNUNET_ERROR_TYPE_DEBUG,
144 "Scheduling task to reconnect to transport service in %s.\n",
145 GNUNET_STRINGS_relative_time_to_string (h->reconnect_delay, GNUNET_YES));
147 GNUNET_SCHEDULER_add_delayed (h->reconnect_delay, &reconnect, h);
148 h->reconnect_delay = GNUNET_TIME_STD_BACKOFF (h->reconnect_delay);
153 * Connect to the transport service.
155 * @param cfg configuration to use
156 * @return NULL on error
158 struct GNUNET_TRANSPORT_AddressHandle *
159 GNUNET_TRANSPORT_address_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
161 struct GNUNET_TRANSPORT_AddressHandle *h;
163 h = GNUNET_new (struct GNUNET_TRANSPORT_AddressHandle);
165 h->reconnect_delay = GNUNET_TIME_UNIT_ZERO;
166 LOG (GNUNET_ERROR_TYPE_DEBUG, "Connecting to transport service\n");
178 * Disconnect from the transport service.
180 * @param handle handle to the service as returned from #GNUNET_TRANSPORT_address_connect()
183 GNUNET_TRANSPORT_address_disconnect (
184 struct GNUNET_TRANSPORT_AddressHandle *handle)
186 LOG (GNUNET_ERROR_TYPE_DEBUG, "Transport disconnect called!\n");
187 /* this disconnects all neighbours... */
189 /* and now we stop trying to connect again... */
190 if (NULL != handle->reconnect_task)
192 GNUNET_SCHEDULER_cancel (handle->reconnect_task);
193 handle->reconnect_task = NULL;
195 GNUNET_free (handle);
200 * The client has learned about a possible address for peer @a pid
201 * (i.e. via broadcast, multicast, DHT, ...). The transport service
202 * should consider validating it. Note that the plugin is NOT expected
203 * to have verified the signature, the transport service must decide
204 * whether to check the signature.
206 * While the notification is sent to @a ch asynchronously, this API
207 * does not return a handle as the delivery of addresses is simply
208 * unreliable, and if @a ch is down, the data provided will simply be
211 * @param ch communicator handle
212 * @param pid peer the address is for
213 * @param raw raw address data
214 * @param raw_size number of bytes in @a raw
217 GNUNET_TRANSPORT_address_try (struct GNUNET_TRANSPORT_AddressHandle *ch,
218 const struct GNUNET_PeerIdentity *pid,
220 const size_t raw_size)
222 struct GNUNET_MQ_Envelope *env;
223 struct GNUNET_TRANSPORT_AddressToVerify *hdr;
226 GNUNET_MQ_msg_extra (hdr,
228 GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_CONSIDER_VERIFY);
230 memcpy (&hdr[1], raw, raw_size);
231 GNUNET_MQ_send (ch->mq, env);
235 /* end of transport_api2_address.c */