aboutsummaryrefslogtreecommitdiff
path: root/src/dv/dv_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dv/dv_api.c')
-rw-r--r--src/dv/dv_api.c467
1 files changed, 0 insertions, 467 deletions
diff --git a/src/dv/dv_api.c b/src/dv/dv_api.c
deleted file mode 100644
index dd46ce9f5..000000000
--- a/src/dv/dv_api.c
+++ /dev/null
@@ -1,467 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009--2013, 2016 GNUnet e.V.
4
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.
9
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.
14
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/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19*/
20
21/**
22 * @file dv/dv_api.c
23 * @brief library to access the DV service
24 * @author Christian Grothoff
25 * @author Nathan Evans
26 */
27#include "platform.h"
28#include "gnunet_util_lib.h"
29#include "gnunet_dv_service.h"
30#include "gnunet_protocols.h"
31#include "dv.h"
32#include "gnunet_transport_plugin.h"
33
34#define LOG(kind,...) GNUNET_log_from (kind, "dv-api",__VA_ARGS__)
35
36
37/**
38 * Information we track for each peer.
39 */
40struct ConnectedPeer
41{
42
43 /**
44 * Identity of the peer.
45 */
46 struct GNUNET_PeerIdentity pid;
47
48};
49
50
51/**
52 * Handle to the DV service.
53 */
54struct GNUNET_DV_ServiceHandle
55{
56
57 /**
58 * Connection to DV service.
59 */
60 struct GNUNET_MQ_Handle *mq;
61
62 /**
63 * Our configuration.
64 */
65 const struct GNUNET_CONFIGURATION_Handle *cfg;
66
67 /**
68 * Closure for the callbacks.
69 */
70 void *cls;
71
72 /**
73 * Function to call on connect events.
74 */
75 GNUNET_DV_ConnectCallback connect_cb;
76
77 /**
78 * Function to call on distance change events.
79 */
80 GNUNET_DV_DistanceChangedCallback distance_cb;
81
82 /**
83 * Function to call on disconnect events.
84 */
85 GNUNET_DV_DisconnectCallback disconnect_cb;
86
87 /**
88 * Function to call on receiving messages events.
89 */
90 GNUNET_DV_MessageReceivedCallback message_cb;
91
92 /**
93 * Information tracked per connected peer. Maps peer
94 * identities to `struct ConnectedPeer` entries.
95 */
96 struct GNUNET_CONTAINER_MultiPeerMap *peers;
97
98};
99
100
101/**
102 * Disconnect and then reconnect to the DV service.
103 *
104 * @param sh service handle
105 */
106static void
107reconnect (struct GNUNET_DV_ServiceHandle *sh);
108
109
110/**
111 * We got disconnected from the service and thus all of the
112 * connections need to be torn down.
113 *
114 * @param cls the `struct GNUNET_DV_ServiceHandle`
115 * @param key a peer identity
116 * @param value a `struct ConnectedPeer` to clean up
117 * @return #GNUNET_OK (continue to iterate)
118 */
119static int
120cleanup_send_cb (void *cls,
121 const struct GNUNET_PeerIdentity *key,
122 void *value)
123{
124 struct GNUNET_DV_ServiceHandle *sh = cls;
125 struct ConnectedPeer *peer = value;
126
127 GNUNET_assert (GNUNET_YES ==
128 GNUNET_CONTAINER_multipeermap_remove (sh->peers,
129 key,
130 peer));
131 sh->disconnect_cb (sh->cls,
132 key);
133 GNUNET_free (peer);
134 return GNUNET_OK;
135}
136
137
138/**
139 * Handles a message sent from the DV service to us.
140 * Parse it out and give it to the plugin.
141 *
142 * @param cls the handle to the DV API
143 * @param cm the message that was received
144 */
145static void
146handle_connect (void *cls,
147 const struct GNUNET_DV_ConnectMessage *cm)
148{
149 struct GNUNET_DV_ServiceHandle *sh = cls;
150 struct ConnectedPeer *peer;
151
152 peer = GNUNET_CONTAINER_multipeermap_get (sh->peers,
153 &cm->peer);
154 if (NULL != peer)
155 {
156 GNUNET_break (0);
157 reconnect (sh);
158 return;
159 }
160 peer = GNUNET_new (struct ConnectedPeer);
161 peer->pid = cm->peer;
162 GNUNET_assert (GNUNET_OK ==
163 GNUNET_CONTAINER_multipeermap_put (sh->peers,
164 &peer->pid,
165 peer,
166 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
167 sh->connect_cb (sh->cls,
168 &cm->peer,
169 ntohl (cm->distance),
170 (enum GNUNET_NetworkType) ntohl (cm->network));
171}
172
173
174/**
175 * Handles a message sent from the DV service to us.
176 * Parse it out and give it to the plugin.
177 *
178 * @param cls the handle to the DV API
179 * @param dm the message that was received
180 */
181static void
182handle_disconnect (void *cls,
183 const struct GNUNET_DV_DisconnectMessage *dm)
184{
185 struct GNUNET_DV_ServiceHandle *sh = cls;
186 struct ConnectedPeer *peer;
187
188 peer = GNUNET_CONTAINER_multipeermap_get (sh->peers,
189 &dm->peer);
190 if (NULL == peer)
191 {
192 GNUNET_break (0);
193 reconnect (sh);
194 return;
195 }
196 cleanup_send_cb (sh,
197 &dm->peer,
198 peer);
199}
200
201
202/**
203 * Handles a message sent from the DV service to us.
204 * Parse it out and give it to the plugin.
205 *
206 * @param cls the handle to the DV API
207 * @param msg the message that was received
208 */
209static void
210handle_distance_update (void *cls,
211 const struct GNUNET_DV_DistanceUpdateMessage *dum)
212{
213 struct GNUNET_DV_ServiceHandle *sh = cls;
214 struct ConnectedPeer *peer;
215
216 peer = GNUNET_CONTAINER_multipeermap_get (sh->peers,
217 &dum->peer);
218 if (NULL == peer)
219 {
220 GNUNET_break (0);
221 reconnect (sh);
222 return;
223 }
224 sh->distance_cb (sh->cls,
225 &dum->peer,
226 ntohl (dum->distance),
227 (enum GNUNET_NetworkType) ntohl (dum->network));
228}
229
230
231/**
232 * Handles a message sent from the DV service to us.
233 * Parse it out and give it to the plugin.
234 *
235 * @param cls the handle to the DV API
236 * @param rm the message that was received
237 */
238static int
239check_received (void *cls,
240 const struct GNUNET_DV_ReceivedMessage *rm)
241{
242 struct GNUNET_DV_ServiceHandle *sh = cls;
243 const struct GNUNET_MessageHeader *payload;
244
245 if (NULL ==
246 GNUNET_CONTAINER_multipeermap_get (sh->peers,
247 &rm->sender))
248 {
249 GNUNET_break (0);
250 return GNUNET_SYSERR;
251 }
252 if (ntohs (rm->header.size) - sizeof (struct GNUNET_DV_ReceivedMessage) <
253 sizeof (*payload))
254 {
255 GNUNET_break (0);
256 return GNUNET_SYSERR;
257 }
258 payload = (const struct GNUNET_MessageHeader *) &rm[1];
259 if (ntohs (rm->header.size) !=
260 sizeof (struct GNUNET_DV_ReceivedMessage) + ntohs (payload->size))
261 {
262 GNUNET_break (0);
263 return GNUNET_SYSERR;
264 }
265 return GNUNET_OK;
266}
267
268
269/**
270 * Handles a message sent from the DV service to us.
271 * Parse it out and give it to the plugin.
272 *
273 * @param cls the handle to the DV API
274 * @param rm the message that was received
275 */
276static void
277handle_received (void *cls,
278 const struct GNUNET_DV_ReceivedMessage *rm)
279{
280 struct GNUNET_DV_ServiceHandle *sh = cls;
281 const struct GNUNET_MessageHeader *payload;
282
283 payload = (const struct GNUNET_MessageHeader *) &rm[1];
284 sh->message_cb (sh->cls,
285 &rm->sender,
286 ntohl (rm->distance),
287 payload);
288}
289
290
291/**
292 * Generic error handler, called with the appropriate error code and
293 * the same closure specified at the creation of the message queue.
294 * Not every message queue implementation supports an error handler.
295 *
296 * @param cls closure with the `struct GNUNET_DV_ServiceHandle *`
297 * @param error error code
298 */
299static void
300mq_error_handler (void *cls,
301 enum GNUNET_MQ_Error error)
302{
303 struct GNUNET_DV_ServiceHandle *sh = cls;
304
305 reconnect (sh);
306}
307
308
309/**
310 * Disconnect and then reconnect to the DV service.
311 *
312 * @param sh service handle
313 */
314static void
315reconnect (struct GNUNET_DV_ServiceHandle *sh)
316{
317 struct GNUNET_MQ_MessageHandler handlers[] = {
318 GNUNET_MQ_hd_fixed_size (connect,
319 GNUNET_MESSAGE_TYPE_DV_CONNECT,
320 struct GNUNET_DV_ConnectMessage,
321 sh),
322 GNUNET_MQ_hd_fixed_size (disconnect,
323 GNUNET_MESSAGE_TYPE_DV_DISCONNECT,
324 struct GNUNET_DV_DisconnectMessage,
325 sh),
326 GNUNET_MQ_hd_fixed_size (distance_update,
327 GNUNET_MESSAGE_TYPE_DV_DISTANCE_CHANGED,
328 struct GNUNET_DV_DistanceUpdateMessage,
329 sh),
330 GNUNET_MQ_hd_var_size (received,
331 GNUNET_MESSAGE_TYPE_DV_RECV,
332 struct GNUNET_DV_ReceivedMessage,
333 sh),
334 GNUNET_MQ_handler_end ()
335 };
336 struct GNUNET_MessageHeader *sm;
337 struct GNUNET_MQ_Envelope *env;
338
339 if (NULL != sh->mq)
340 {
341 GNUNET_MQ_destroy (sh->mq);
342 sh->mq = NULL;
343 }
344 GNUNET_CONTAINER_multipeermap_iterate (sh->peers,
345 &cleanup_send_cb,
346 sh);
347 LOG (GNUNET_ERROR_TYPE_DEBUG,
348 "Connecting to DV service\n");
349 sh->mq = GNUNET_CLIENT_connect (sh->cfg,
350 "dv",
351 handlers,
352 &mq_error_handler,
353 sh);
354 if (NULL == sh->mq)
355 {
356 GNUNET_break (0);
357 return;
358 }
359 env = GNUNET_MQ_msg (sm,
360 GNUNET_MESSAGE_TYPE_DV_START);
361 GNUNET_MQ_send (sh->mq,
362 env);
363}
364
365
366/**
367 * Connect to the DV service.
368 *
369 * @param cfg configuration
370 * @param cls closure for callbacks
371 * @param connect_cb function to call on connects
372 * @param distance_cb function to call if distances change
373 * @param disconnect_cb function to call on disconnects
374 * @param message_cb function to call if we receive messages
375 * @return handle to access the service
376 */
377struct GNUNET_DV_ServiceHandle *
378GNUNET_DV_service_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
379 void *cls,
380 GNUNET_DV_ConnectCallback connect_cb,
381 GNUNET_DV_DistanceChangedCallback distance_cb,
382 GNUNET_DV_DisconnectCallback disconnect_cb,
383 GNUNET_DV_MessageReceivedCallback message_cb)
384{
385 struct GNUNET_DV_ServiceHandle *sh;
386
387 sh = GNUNET_new (struct GNUNET_DV_ServiceHandle);
388 sh->cfg = cfg;
389 sh->cls = cls;
390 sh->connect_cb = connect_cb;
391 sh->distance_cb = distance_cb;
392 sh->disconnect_cb = disconnect_cb;
393 sh->message_cb = message_cb;
394 sh->peers = GNUNET_CONTAINER_multipeermap_create (128,
395 GNUNET_YES);
396 reconnect (sh);
397 return sh;
398}
399
400
401/**
402 * Disconnect from DV service.
403 *
404 * @param sh service handle
405 */
406void
407GNUNET_DV_service_disconnect (struct GNUNET_DV_ServiceHandle *sh)
408{
409 if (NULL == sh)
410 return;
411 if (NULL != sh->mq)
412 {
413 GNUNET_MQ_destroy (sh->mq);
414 sh->mq = NULL;
415 }
416 GNUNET_CONTAINER_multipeermap_iterate (sh->peers,
417 &cleanup_send_cb,
418 sh);
419 GNUNET_CONTAINER_multipeermap_destroy (sh->peers);
420 GNUNET_free (sh);
421}
422
423
424/**
425 * Send a message via DV service.
426 *
427 * @param sh service handle
428 * @param target intended recpient
429 * @param msg message payload
430 */
431void
432GNUNET_DV_send (struct GNUNET_DV_ServiceHandle *sh,
433 const struct GNUNET_PeerIdentity *target,
434 const struct GNUNET_MessageHeader *msg)
435{
436 struct GNUNET_DV_SendMessage *sm;
437 struct ConnectedPeer *peer;
438 struct GNUNET_MQ_Envelope *env;
439
440 if (ntohs (msg->size) + sizeof (*sm) >= GNUNET_MAX_MESSAGE_SIZE)
441 {
442 GNUNET_break (0);
443 return;
444 }
445 LOG (GNUNET_ERROR_TYPE_DEBUG,
446 "Asked to send %u bytes of type %u to %s\n",
447 (unsigned int) ntohs (msg->size),
448 (unsigned int) ntohs (msg->type),
449 GNUNET_i2s (target));
450 peer = GNUNET_CONTAINER_multipeermap_get (sh->peers,
451 target);
452 if (NULL == peer)
453 {
454 GNUNET_break (0);
455 return;
456 }
457 GNUNET_assert (NULL != sh->mq);
458 env = GNUNET_MQ_msg_nested_mh (sm,
459 GNUNET_MESSAGE_TYPE_DV_SEND,
460 msg);
461 sm->target = *target;
462 GNUNET_MQ_send (sh->mq,
463 env);
464}
465
466
467/* end of dv_api.c */