2 This file is part of GNUnet.
3 Copyright (C) 2009-2013, 2016 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_api_manipulation.c
23 * @brief library to access the low-level P2P IO service
24 * @author Christian Grothoff
27 #include "gnunet_util_lib.h"
28 #include "gnunet_constants.h"
29 #include "gnunet_arm_service.h"
30 #include "gnunet_hello_lib.h"
31 #include "gnunet_protocols.h"
32 #include "gnunet_transport_service.h"
33 #include "transport.h"
35 #define LOG(kind, ...) GNUNET_log_from (kind, "transport-api", __VA_ARGS__)
39 * Handle for the transport service (includes all of the
40 * state for the transport service).
42 struct GNUNET_TRANSPORT_ManipulationHandle
45 * My client connection to the transport service.
47 struct GNUNET_MQ_Handle *mq;
52 const struct GNUNET_CONFIGURATION_Handle *cfg;
55 * ID of the task trying to reconnect to the service.
57 struct GNUNET_SCHEDULER_Task *reconnect_task;
60 * Delay until we try to reconnect.
62 struct GNUNET_TIME_Relative reconnect_delay;
65 * Reconnect in progress
72 * Function that will schedule the job that will try
73 * to connect us again to the client.
75 * @param h transport service to reconnect
78 disconnect_and_schedule_reconnect (struct
79 GNUNET_TRANSPORT_ManipulationHandle *h);
83 * Generic error handler, called with the appropriate
84 * error code and the same closure specified at the creation of
86 * Not every message queue implementation supports an error handler.
88 * @param cls closure with the `struct GNUNET_TRANSPORT_ManipulationHandle *`
89 * @param error error code
92 mq_error_handler (void *cls,
93 enum GNUNET_MQ_Error error)
95 struct GNUNET_TRANSPORT_ManipulationHandle *h = cls;
97 LOG (GNUNET_ERROR_TYPE_DEBUG,
98 "Error receiving from transport service, disconnecting temporarily.\n");
99 h->reconnecting = GNUNET_YES;
100 disconnect_and_schedule_reconnect (h);
105 * Try again to connect to transport service.
107 * @param cls the handle to the transport service
110 reconnect (void *cls)
112 struct GNUNET_TRANSPORT_ManipulationHandle *h = cls;
113 struct GNUNET_MQ_MessageHandler handlers[] = {
114 GNUNET_MQ_handler_end ()
116 struct GNUNET_MQ_Envelope *env;
117 struct StartMessage *s;
119 h->reconnect_task = NULL;
120 LOG (GNUNET_ERROR_TYPE_DEBUG,
121 "Connecting to transport service.\n");
122 GNUNET_assert (NULL == h->mq);
123 h->reconnecting = GNUNET_NO;
124 h->mq = GNUNET_CLIENT_connect (h->cfg,
131 env = GNUNET_MQ_msg (s,
132 GNUNET_MESSAGE_TYPE_TRANSPORT_START);
133 GNUNET_MQ_send (h->mq,
139 * Function that will schedule the job that will try
140 * to connect us again to the client.
142 * @param h transport service to reconnect
145 disconnect_and_schedule_reconnect (struct
146 GNUNET_TRANSPORT_ManipulationHandle *h)
148 GNUNET_assert (NULL == h->reconnect_task);
151 GNUNET_MQ_destroy (h->mq);
155 GNUNET_SCHEDULER_add_delayed (h->reconnect_delay,
158 h->reconnect_delay = GNUNET_TIME_STD_BACKOFF (h->reconnect_delay);
163 * Set transport metrics for a peer and a direction.
165 * @param handle transport handle
166 * @param peer the peer to set the metric for
167 * @param prop the performance metrics to set
168 * @param delay_in inbound delay to introduce
169 * @param delay_out outbound delay to introduce
171 * Note: Delay restrictions in receiving direction will be enforced
172 * with one message delay.
175 GNUNET_TRANSPORT_manipulation_set (struct
176 GNUNET_TRANSPORT_ManipulationHandle *handle,
177 const struct GNUNET_PeerIdentity *peer,
178 const struct GNUNET_ATS_Properties *prop,
179 struct GNUNET_TIME_Relative delay_in,
180 struct GNUNET_TIME_Relative delay_out)
182 struct GNUNET_MQ_Envelope *env;
183 struct TrafficMetricMessage *msg;
185 if (NULL == handle->mq)
187 env = GNUNET_MQ_msg (msg,
188 GNUNET_MESSAGE_TYPE_TRANSPORT_TRAFFIC_METRIC);
189 msg->reserved = htonl (0);
191 GNUNET_ATS_properties_hton (&msg->properties,
193 msg->delay_in = GNUNET_TIME_relative_hton (delay_in);
194 msg->delay_out = GNUNET_TIME_relative_hton (delay_out);
195 GNUNET_MQ_send (handle->mq,
201 * Connect to the transport service. Note that the connection may
202 * complete (or fail) asynchronously.
204 * @param cfg configuration to use
205 * @return NULL on error
207 struct GNUNET_TRANSPORT_ManipulationHandle *
208 GNUNET_TRANSPORT_manipulation_connect (const struct
209 GNUNET_CONFIGURATION_Handle *cfg)
211 struct GNUNET_TRANSPORT_ManipulationHandle *h;
213 h = GNUNET_new (struct GNUNET_TRANSPORT_ManipulationHandle);
215 LOG (GNUNET_ERROR_TYPE_DEBUG,
216 "Connecting to transport service.\n");
228 * Disconnect from the transport service.
230 * @param handle handle to the service as returned from #GNUNET_TRANSPORT_manipulation_connect()
233 GNUNET_TRANSPORT_manipulation_disconnect (struct
234 GNUNET_TRANSPORT_ManipulationHandle *
237 if (NULL == handle->reconnect_task)
238 disconnect_and_schedule_reconnect (handle);
239 /* and now we stop trying to connect again... */
240 if (NULL != handle->reconnect_task)
242 GNUNET_SCHEDULER_cancel (handle->reconnect_task);
243 handle->reconnect_task = NULL;
245 GNUNET_free (handle);
249 /* end of transport_api_manipulation.c */