2 This file is part of GNUnet.
3 Copyright (C) 2011, 2017, 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
21 * @file cadet/cadet_api_get_channel.c
22 * @brief cadet api: client implementation of cadet service
23 * @author Bartlomiej Polot
24 * @author Christian Grothoff
27 #include "gnunet_util_lib.h"
28 #include "gnunet_constants.h"
29 #include "gnunet_cadet_service.h"
31 #include "cadet_protocol.h"
37 struct GNUNET_CADET_ChannelMonitor {
41 GNUNET_CADET_ChannelCB channel_cb;
44 * Info callback closure for @c channel_cb.
49 * Configuration we use.
51 const struct GNUNET_CONFIGURATION_Handle *cfg;
54 * Message queue to talk to CADET service.
56 struct GNUNET_MQ_Handle *mq;
61 struct GNUNET_SCHEDULER_Task *reconnect_task;
64 * Backoff for reconnect attempts.
66 struct GNUNET_TIME_Relative backoff;
69 * Peer we want information about.
71 struct GNUNET_PeerIdentity peer;
76 * Check that message received from CADET service is well-formed.
79 * @param message the message we got
80 * @return #GNUNET_OK if the message is well-formed,
81 * #GNUNET_SYSERR otherwise
84 check_channel_info(void *cls,
85 const struct GNUNET_CADET_ChannelInfoMessage *message)
94 * Process a local peer info reply, pass info to the user.
97 * @param message Message itself.
100 handle_channel_info(void *cls,
101 const struct GNUNET_CADET_ChannelInfoMessage *message)
103 struct GNUNET_CADET_ChannelMonitor *cm = cls;
104 struct GNUNET_CADET_ChannelInternals ci;
106 ci.root = message->root;
107 ci.dest = message->dest;
108 cm->channel_cb(cm->channel_cb_cls,
110 GNUNET_CADET_get_channel_cancel(cm);
115 * Process a local peer info reply, pass info to the user.
118 * @param message Message itself.
121 handle_channel_info_end(void *cls,
122 const struct GNUNET_MessageHeader *message)
124 struct GNUNET_CADET_ChannelMonitor *cm = cls;
126 cm->channel_cb(cm->channel_cb_cls,
128 GNUNET_CADET_get_channel_cancel(cm);
133 * Reconnect to the service and try again.
135 * @param cls a `struct GNUNET_CADET_ChannelMonitor` operation
138 reconnect(void *cls);
142 * Function called on connection trouble. Reconnects.
144 * @param cls a `struct GNUNET_CADET_ChannelMonitor``
145 * @param error error code from MQ
148 error_handler(void *cls,
149 enum GNUNET_MQ_Error error)
151 struct GNUNET_CADET_ChannelMonitor *cm = cls;
153 GNUNET_MQ_destroy(cm->mq);
155 cm->backoff = GNUNET_TIME_randomized_backoff(cm->backoff,
156 GNUNET_TIME_UNIT_MINUTES);
157 cm->reconnect_task = GNUNET_SCHEDULER_add_delayed(cm->backoff,
164 * Reconnect to the service and try again.
166 * @param cls a `struct GNUNET_CADET_ChannelMonitor` operation
171 struct GNUNET_CADET_ChannelMonitor *cm = cls;
172 struct GNUNET_MQ_MessageHandler handlers[] = {
173 GNUNET_MQ_hd_fixed_size(channel_info_end,
174 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNEL_END,
175 struct GNUNET_MessageHeader,
177 GNUNET_MQ_hd_var_size(channel_info,
178 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNEL,
179 struct GNUNET_CADET_ChannelInfoMessage,
181 GNUNET_MQ_handler_end()
183 struct GNUNET_CADET_RequestChannelInfoMessage *msg;
184 struct GNUNET_MQ_Envelope *env;
186 cm->reconnect_task = NULL;
187 cm->mq = GNUNET_CLIENT_connect(cm->cfg,
194 env = GNUNET_MQ_msg(msg,
195 GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_CHANNEL);
196 msg->target = cm->peer;
197 GNUNET_MQ_send(cm->mq,
203 * Request information about a specific channel of the running cadet peer.
205 * @param cfg configuration to use
206 * @param peer ID of the other end of the channel.
207 * @param callback Function to call with the requested data.
208 * @param callback_cls Closure for @c callback.
209 * @return NULL on error
211 struct GNUNET_CADET_ChannelMonitor *
212 GNUNET_CADET_get_channel(const struct GNUNET_CONFIGURATION_Handle *cfg,
213 struct GNUNET_PeerIdentity *peer,
214 GNUNET_CADET_ChannelCB callback,
217 struct GNUNET_CADET_ChannelMonitor *cm;
219 if (NULL == callback)
224 cm = GNUNET_new(struct GNUNET_CADET_ChannelMonitor);
225 cm->channel_cb = callback;
226 cm->channel_cb_cls = callback_cls;
240 * Cancel a channel monitor request. The callback will not be called (anymore).
242 * @param h Cadet handle.
243 * @return Closure that was given to #GNUNET_CADET_get_channel().
246 GNUNET_CADET_get_channel_cancel(struct GNUNET_CADET_ChannelMonitor *cm)
248 void *ret = cm->channel_cb_cls;
251 GNUNET_MQ_destroy(cm->mq);
252 if (NULL != cm->reconnect_task)
253 GNUNET_SCHEDULER_cancel(cm->reconnect_task);
258 /* end of cadet_api_get_channel.c */