aboutsummaryrefslogtreecommitdiff
path: root/src/cadet/gnunet-service-cadet_local.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cadet/gnunet-service-cadet_local.c')
-rw-r--r--src/cadet/gnunet-service-cadet_local.c1553
1 files changed, 0 insertions, 1553 deletions
diff --git a/src/cadet/gnunet-service-cadet_local.c b/src/cadet/gnunet-service-cadet_local.c
deleted file mode 100644
index dea6681df..000000000
--- a/src/cadet/gnunet-service-cadet_local.c
+++ /dev/null
@@ -1,1553 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2013 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21
22#include "platform.h"
23#include "gnunet_util_lib.h"
24
25#include "gnunet_statistics_service.h"
26
27#include "cadet.h"
28#include "cadet_protocol.h" /* GNUNET_CADET_Data is shared */
29
30#include "gnunet-service-cadet_local.h"
31#include "gnunet-service-cadet_channel.h"
32
33/* INFO DEBUG */
34#include "gnunet-service-cadet_tunnel.h"
35#include "gnunet-service-cadet_peer.h"
36
37#define LOG(level, ...) GNUNET_log_from(level,"cadet-loc",__VA_ARGS__)
38
39/******************************************************************************/
40/******************************** STRUCTS **********************************/
41/******************************************************************************/
42
43/**
44 * Struct containing information about a client of the service
45 *
46 * TODO: add a list of 'waiting' ports
47 */
48struct CadetClient
49{
50 /**
51 * Linked list next
52 */
53 struct CadetClient *next;
54
55 /**
56 * Linked list prev
57 */
58 struct CadetClient *prev;
59
60 /**
61 * Tunnels that belong to this client, indexed by local id
62 */
63 struct GNUNET_CONTAINER_MultiHashMap32 *own_channels;
64
65 /**
66 * Tunnels this client has accepted, indexed by incoming local id
67 */
68 struct GNUNET_CONTAINER_MultiHashMap32 *incoming_channels;
69
70 /**
71 * Channel ID for the next incoming channel.
72 */
73 struct GNUNET_CADET_ClientChannelNumber next_ccn;
74
75 /**
76 * Handle to communicate with the client
77 */
78 struct GNUNET_SERVER_Client *handle;
79
80 /**
81 * Ports that this client has declared interest in.
82 * Indexed by port, contains *Client.
83 */
84 struct GNUNET_CONTAINER_MultiHashMap *ports;
85
86 /**
87 * Whether the client is active or shutting down (don't send confirmations
88 * to a client that is shutting down.
89 */
90 int shutting_down;
91
92 /**
93 * ID of the client, mainly for debug messages
94 */
95 unsigned int id;
96};
97
98/******************************************************************************/
99/******************************* GLOBALS ***********************************/
100/******************************************************************************/
101
102/**
103 * Global handle to the statistics service.
104 */
105extern struct GNUNET_STATISTICS_Handle *stats;
106
107/**
108 * Handle to server lib.
109 */
110static struct GNUNET_SERVER_Handle *server_handle;
111
112/**
113 * DLL with all the clients, head.
114 */
115static struct CadetClient *clients_head;
116
117/**
118 * DLL with all the clients, tail.
119 */
120static struct CadetClient *clients_tail;
121
122/**
123 * Next ID to assign to a client.
124 */
125unsigned int next_client_id;
126
127/**
128 * All ports clients of this peer have opened.
129 */
130static struct GNUNET_CONTAINER_MultiHashMap *ports;
131
132/**
133 * Notification context, to send messages to local clients.
134 */
135static struct GNUNET_SERVER_NotificationContext *nc;
136
137
138/******************************************************************************/
139/******************************** STATIC ***********************************/
140/******************************************************************************/
141
142/**
143 * Remove client's ports from the global hashmap on disconnect.
144 *
145 * @param cls Closure (unused).
146 * @param key Port.
147 * @param value Client structure.
148 *
149 * @return #GNUNET_OK, keep iterating.
150 */
151static int
152client_release_ports (void *cls,
153 const struct GNUNET_HashCode *key,
154 void *value)
155{
156 int res;
157
158 res = GNUNET_CONTAINER_multihashmap_remove (ports, key, value);
159 if (GNUNET_YES != res)
160 {
161 GNUNET_break (0);
162 LOG (GNUNET_ERROR_TYPE_WARNING,
163 "Port %s by client %p was not registered.\n",
164 GNUNET_h2s (key), value);
165 }
166 return GNUNET_OK;
167}
168
169
170/**
171 * Iterator for deleting each channel whose client endpoint disconnected.
172 *
173 * @param cls Closure (client that has disconnected).
174 * @param key The local channel id (used to access the hashmap).
175 * @param value The value stored at the key (channel to destroy).
176 *
177 * @return #GNUNET_OK, keep iterating.
178 */
179static int
180channel_destroy_iterator (void *cls,
181 uint32_t key,
182 void *value)
183{
184 struct CadetChannel *ch = value;
185 struct CadetClient *c = cls;
186
187 LOG (GNUNET_ERROR_TYPE_DEBUG,
188 " Channel %s destroy, due to client %s shutdown.\n",
189 GCCH_2s (ch), GML_2s (c));
190
191 GCCH_handle_local_destroy (ch,
192 c,
193 key < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI);
194 return GNUNET_OK;
195}
196
197
198/**
199 * Unregister data and free memory for a client.
200 *
201 * @param c Client to destroy. No longer valid after call.
202 */
203static void
204client_destroy (struct CadetClient *c)
205{
206 LOG (GNUNET_ERROR_TYPE_DEBUG, " client destroy: %p/%u\n", c, c->id);
207 GNUNET_SERVER_client_drop (c->handle);
208 c->shutting_down = GNUNET_YES;
209
210 if (NULL != c->own_channels)
211 {
212 GNUNET_CONTAINER_multihashmap32_iterate (c->own_channels,
213 &channel_destroy_iterator, c);
214 GNUNET_CONTAINER_multihashmap32_destroy (c->own_channels);
215 }
216 if (NULL != c->incoming_channels)
217 {
218 GNUNET_CONTAINER_multihashmap32_iterate (c->incoming_channels,
219 &channel_destroy_iterator, c);
220 GNUNET_CONTAINER_multihashmap32_destroy (c->incoming_channels);
221 }
222 if (NULL != c->ports)
223 {
224 GNUNET_CONTAINER_multihashmap_iterate (c->ports,
225 &client_release_ports, c);
226 GNUNET_CONTAINER_multihashmap_destroy (c->ports);
227 }
228
229 GNUNET_CONTAINER_DLL_remove (clients_head, clients_tail, c);
230 GNUNET_STATISTICS_update (stats, "# clients", -1, GNUNET_NO);
231 GNUNET_SERVER_client_set_user_context (c->handle, NULL);
232 GNUNET_free (c);
233}
234
235
236/**
237 * Create a client record, register data and initialize memory.
238 *
239 * @param client Client's handle.
240 */
241static struct CadetClient *
242client_new (struct GNUNET_SERVER_Client *client)
243{
244 struct CadetClient *c;
245
246 GNUNET_SERVER_client_keep (client);
247 GNUNET_SERVER_notification_context_add (nc, client);
248
249 c = GNUNET_new (struct CadetClient);
250 c->handle = client;
251 c->id = next_client_id++; /* overflow not important: just for debug */
252
253 c->own_channels = GNUNET_CONTAINER_multihashmap32_create (32);
254 c->incoming_channels = GNUNET_CONTAINER_multihashmap32_create (32);
255
256 GNUNET_SERVER_client_set_user_context (client, c);
257 GNUNET_CONTAINER_DLL_insert (clients_head, clients_tail, c);
258 GNUNET_STATISTICS_update (stats, "# clients", +1, GNUNET_NO);
259
260 LOG (GNUNET_ERROR_TYPE_DEBUG, " client created: %p/%u\n", c, c->id);
261
262 return c;
263}
264
265
266/******************************************************************************/
267/******************************** HANDLES ***********************************/
268/******************************************************************************/
269
270/**
271 * Handler for client connection.
272 *
273 * @param cls Closure (unused).
274 * @param client Client handler.
275 */
276static void
277handle_client_connect (void *cls, struct GNUNET_SERVER_Client *client)
278{
279 LOG (GNUNET_ERROR_TYPE_DEBUG, "Client connected: %p\n", client);
280 if (NULL == client)
281 return;
282
283 (void) client_new (client);
284}
285
286
287/**
288 * Handler for client disconnection
289 *
290 * @param cls closure
291 * @param client identification of the client; NULL
292 * for the last call when the server is destroyed
293 */
294static void
295handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
296{
297 struct CadetClient *c;
298
299 LOG (GNUNET_ERROR_TYPE_DEBUG, "Client disconnected: %p\n", client);
300
301 c = GML_client_get (client);
302 if (NULL != c)
303 {
304 LOG (GNUNET_ERROR_TYPE_DEBUG, "matching client found (%u, %p)\n",
305 c->id, c);
306 client_destroy (c);
307 }
308 else
309 {
310 LOG (GNUNET_ERROR_TYPE_DEBUG, " disconnecting client's context NULL\n");
311 }
312 return;
313}
314
315
316/**
317 * Handler for port open requests.
318 *
319 * @param cls Closure.
320 * @param client Identification of the client.
321 * @param message The actual message.
322 */
323static void
324handle_port_open (void *cls, struct GNUNET_SERVER_Client *client,
325 const struct GNUNET_MessageHeader *message)
326{
327 struct CadetClient *c;
328 struct GNUNET_CADET_PortMessage *pmsg;
329
330 LOG (GNUNET_ERROR_TYPE_DEBUG, "open port requested\n");
331
332 /* Sanity check for client registration */
333 if (NULL == (c = GML_client_get (client)))
334 {
335 GNUNET_break (0);
336 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
337 return;
338 }
339 LOG (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
340
341 /* Message size sanity check */
342 if (sizeof (struct GNUNET_CADET_PortMessage) != ntohs (message->size))
343 {
344 GNUNET_break (0);
345 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
346 return;
347 }
348
349 pmsg = (struct GNUNET_CADET_PortMessage *) message;
350 if (NULL == c->ports)
351 {
352 c->ports = GNUNET_CONTAINER_multihashmap_create (4, GNUNET_NO);
353 }
354 /* store in client's hashmap */
355 if (GNUNET_OK !=
356 GNUNET_CONTAINER_multihashmap_put (c->ports, &pmsg->port, c,
357 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
358 {
359 GNUNET_break (0);
360 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
361 return;
362 }
363 /* store in global hashmap */
364 /* FIXME only allow one client to have the port open,
365 * have a backup hashmap with waiting clients */
366 GNUNET_CONTAINER_multihashmap_put (ports, &pmsg->port, c,
367 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
368
369 GNUNET_SERVER_receive_done (client, GNUNET_OK);
370}
371
372
373/**
374 * Handler for port close requests.
375 *
376 * @param cls Closure.
377 * @param client Identification of the client.
378 * @param message The actual message.
379 */
380static void
381handle_port_close (void *cls, struct GNUNET_SERVER_Client *client,
382 const struct GNUNET_MessageHeader *message)
383{
384 struct CadetClient *c;
385 struct GNUNET_CADET_PortMessage *pmsg;
386 int removed;
387
388 LOG (GNUNET_ERROR_TYPE_DEBUG, "close port requested\n");
389
390 /* Sanity check for client registration */
391 if (NULL == (c = GML_client_get (client)))
392 {
393 GNUNET_break (0);
394 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
395 return;
396 }
397 LOG (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
398
399 /* Message size sanity check */
400 if (sizeof (struct GNUNET_CADET_PortMessage) != ntohs (message->size))
401 {
402 GNUNET_break (0);
403 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
404 return;
405 }
406
407 pmsg = (struct GNUNET_CADET_PortMessage *) message;
408 removed = GNUNET_CONTAINER_multihashmap_remove (c->ports, &pmsg->port, c);
409 GNUNET_break_op (GNUNET_YES == removed);
410 removed = GNUNET_CONTAINER_multihashmap_remove (ports, &pmsg->port, c);
411 GNUNET_break_op (GNUNET_YES == removed);
412
413 GNUNET_SERVER_receive_done (client, GNUNET_OK);
414}
415
416
417/**
418 * Handler for requests of new channels.
419 *
420 * @param cls Closure.
421 * @param client Identification of the client.
422 * @param message The actual message.
423 */
424static void
425handle_channel_create (void *cls, struct GNUNET_SERVER_Client *client,
426 const struct GNUNET_MessageHeader *message)
427{
428 struct CadetClient *c;
429
430 LOG (GNUNET_ERROR_TYPE_DEBUG, "\n");
431 LOG (GNUNET_ERROR_TYPE_DEBUG, "new channel requested\n");
432
433 /* Sanity check for client registration */
434 if (NULL == (c = GML_client_get (client)))
435 {
436 GNUNET_break (0);
437 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
438 return;
439 }
440 LOG (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
441
442 /* Message size sanity check */
443 if (sizeof (struct GNUNET_CADET_LocalChannelCreateMessage)
444 != ntohs (message->size))
445 {
446 GNUNET_break (0);
447 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
448 return;
449 }
450
451 if (GNUNET_OK !=
452 GCCH_handle_local_create (c,
453 (struct GNUNET_CADET_LocalChannelCreateMessage *)
454 message))
455 {
456 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
457 return;
458 }
459
460 GNUNET_SERVER_receive_done (client, GNUNET_OK);
461}
462
463
464/**
465 * Handler for requests of deleting tunnels
466 *
467 * @param cls closure
468 * @param client identification of the client
469 * @param message the actual message
470 */
471static void
472handle_channel_destroy (void *cls, struct GNUNET_SERVER_Client *client,
473 const struct GNUNET_MessageHeader *message)
474{
475 const struct GNUNET_CADET_LocalChannelDestroyMessage *msg;
476 struct CadetClient *c;
477 struct CadetChannel *ch;
478 struct GNUNET_CADET_ClientChannelNumber ccn;
479
480 LOG (GNUNET_ERROR_TYPE_DEBUG, "Got a DESTROY CHANNEL from client!\n");
481
482 /* Sanity check for client registration */
483 if (NULL == (c = GML_client_get (client)))
484 {
485 GNUNET_break (0);
486 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
487 return;
488 }
489 LOG (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
490
491 /* Message sanity check */
492 if (sizeof (struct GNUNET_CADET_LocalChannelDestroyMessage)
493 != ntohs (message->size))
494 {
495 GNUNET_break (0);
496 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
497 return;
498 }
499
500 msg = (const struct GNUNET_CADET_LocalChannelDestroyMessage *) message;
501
502 /* Retrieve tunnel */
503 ccn = msg->ccn;
504 ch = GML_channel_get (c, ccn);
505
506 LOG (GNUNET_ERROR_TYPE_INFO, "Client %u is destroying channel %X\n",
507 c->id, ccn);
508
509 if (NULL == ch)
510 {
511 LOG (GNUNET_ERROR_TYPE_WARNING, " channel %X not found\n", ccn);
512 GNUNET_STATISTICS_update (stats,
513 "# client destroy messages on unknown channel",
514 1, GNUNET_NO);
515 GNUNET_SERVER_receive_done (client, GNUNET_OK);
516 return;
517 }
518
519 GCCH_handle_local_destroy (ch,
520 c,
521 ntohl (ccn.channel_of_client) < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI);
522
523 GNUNET_SERVER_receive_done (client, GNUNET_OK);
524}
525
526
527/**
528 * Handler for client traffic
529 *
530 * @param cls closure
531 * @param client identification of the client
532 * @param message the actual message
533 */
534static void
535handle_data (void *cls, struct GNUNET_SERVER_Client *client,
536 const struct GNUNET_MessageHeader *message)
537{
538 const struct GNUNET_MessageHeader *payload;
539 struct GNUNET_CADET_LocalData *msg;
540 struct CadetClient *c;
541 struct CadetChannel *ch;
542 struct GNUNET_CADET_ClientChannelNumber ccn;
543 size_t message_size;
544 size_t payload_size;
545 size_t payload_claimed_size;
546 int fwd;
547
548 LOG (GNUNET_ERROR_TYPE_DEBUG, "\n");
549 LOG (GNUNET_ERROR_TYPE_DEBUG, "\n");
550 LOG (GNUNET_ERROR_TYPE_DEBUG, "Got data from a client\n");
551
552 /* Sanity check for client registration */
553 if (NULL == (c = GML_client_get (client)))
554 {
555 GNUNET_break (0);
556 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
557 return;
558 }
559
560 /* Sanity check for message size */
561 message_size = ntohs (message->size);
562 if (sizeof (struct GNUNET_CADET_LocalData)
563 + sizeof (struct GNUNET_MessageHeader) > message_size
564 || GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE < message_size)
565 {
566 GNUNET_break (0);
567 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
568 return;
569 }
570
571 /* Sanity check for payload size */
572 payload_size = message_size - sizeof (struct GNUNET_CADET_LocalData);
573 msg = (struct GNUNET_CADET_LocalData *) message;
574 payload = (struct GNUNET_MessageHeader *) &msg[1];
575 payload_claimed_size = ntohs (payload->size);
576 if (sizeof (struct GNUNET_MessageHeader) > payload_claimed_size
577 || GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE < payload_claimed_size
578 || payload_claimed_size > payload_size)
579 {
580 LOG (GNUNET_ERROR_TYPE_WARNING,
581 "client claims to send %u bytes in %u payload\n",
582 payload_claimed_size, payload_size);
583 GNUNET_break (0);
584 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
585 return;
586 }
587
588 ccn = msg->ccn;
589 LOG (GNUNET_ERROR_TYPE_DEBUG, " %u bytes (%u payload) by client %u\n",
590 payload_size, payload_claimed_size, c->id);
591
592 /* Channel exists? */
593 fwd = ntohl (ccn.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI;
594 ch = GML_channel_get (c, ccn);
595 if (NULL == ch)
596 {
597 GNUNET_STATISTICS_update (stats,
598 "# client data messages on unknown channel",
599 1, GNUNET_NO);
600 GNUNET_SERVER_receive_done (client, GNUNET_OK);
601 return;
602 }
603
604 if (GNUNET_OK != GCCH_handle_local_data (ch, c, fwd, payload, payload_size))
605 {
606 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
607 return;
608 }
609
610 LOG (GNUNET_ERROR_TYPE_DEBUG, "receive done OK\n");
611 GNUNET_SERVER_receive_done (client, GNUNET_OK);
612
613 return;
614}
615
616
617/**
618 * Handler for client's ACKs for payload traffic.
619 *
620 * @param cls Closure (unused).
621 * @param client Identification of the client.
622 * @param message The actual message.
623 */
624static void
625handle_ack (void *cls, struct GNUNET_SERVER_Client *client,
626 const struct GNUNET_MessageHeader *message)
627{
628 struct GNUNET_CADET_LocalAck *msg;
629 struct CadetChannel *ch;
630 struct CadetClient *c;
631 struct GNUNET_CADET_ClientChannelNumber ccn;
632 int fwd;
633
634 LOG (GNUNET_ERROR_TYPE_DEBUG, "\n");
635 LOG (GNUNET_ERROR_TYPE_DEBUG, "Got a local ACK\n");
636
637 /* Sanity check for client registration */
638 if (NULL == (c = GML_client_get (client)))
639 {
640 GNUNET_break (0);
641 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
642 return;
643 }
644 LOG (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
645
646 msg = (struct GNUNET_CADET_LocalAck *) message;
647
648 /* Channel exists? */
649 ccn = msg->ccn;
650 LOG (GNUNET_ERROR_TYPE_DEBUG, " on channel %X\n",
651 ntohl (ccn.channel_of_client));
652 ch = GML_channel_get (c, ccn);
653 LOG (GNUNET_ERROR_TYPE_DEBUG, " -- ch %p\n", ch);
654 if (NULL == ch)
655 {
656 LOG (GNUNET_ERROR_TYPE_DEBUG,
657 "Channel %X unknown.\n",
658 ntohl (ccn.channel_of_client));
659 LOG (GNUNET_ERROR_TYPE_DEBUG, " for client %u.\n", c->id);
660 GNUNET_STATISTICS_update (stats,
661 "# client ack messages on unknown channel",
662 1, GNUNET_NO);
663 GNUNET_SERVER_receive_done (client, GNUNET_OK);
664 return;
665 }
666
667 /* If client is root, the ACK is going FWD, therefore this is "BCK ACK". */
668 /* If client is dest, the ACK is going BCK, therefore this is "FWD ACK" */
669 fwd = ntohl (ccn.channel_of_client) < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI;
670
671 GCCH_handle_local_ack (ch, fwd);
672 GNUNET_SERVER_receive_done (client, GNUNET_OK);
673}
674
675
676/**
677 * Iterator over all peers to send a monitoring client info about each peer.
678 *
679 * @param cls Closure ().
680 * @param peer Peer ID (tunnel remote peer).
681 * @param value Peer info.
682 *
683 * @return #GNUNET_YES, to keep iterating.
684 */
685static int
686get_all_peers_iterator (void *cls,
687 const struct GNUNET_PeerIdentity * peer,
688 void *value)
689{
690 struct GNUNET_SERVER_Client *client = cls;
691 struct CadetPeer *p = value;
692 struct GNUNET_CADET_LocalInfoPeer msg;
693
694 msg.header.size = htons (sizeof (msg));
695 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS);
696 msg.destination = *peer;
697 msg.paths = htons (GCP_count_paths (p));
698 msg.tunnel = htons (NULL != GCP_get_tunnel (p));
699
700 LOG (GNUNET_ERROR_TYPE_DEBUG, "sending info about peer %s\n",
701 GNUNET_i2s (peer));
702
703 GNUNET_SERVER_notification_context_unicast (nc, client,
704 &msg.header, GNUNET_NO);
705 return GNUNET_YES;
706}
707
708
709/**
710 * Iterator over all peers to dump info for each peer.
711 *
712 * @param cls Closure (unused).
713 * @param peer Peer ID (tunnel remote peer).
714 * @param value Peer info.
715 *
716 * @return #GNUNET_YES, to keep iterating.
717 */
718static int
719show_peer_iterator (void *cls,
720 const struct GNUNET_PeerIdentity * peer,
721 void *value)
722{
723 struct CadetPeer *p = value;
724 struct CadetTunnel *t;
725
726 t = GCP_get_tunnel (p);
727 if (NULL != t)
728 GCT_debug (t, GNUNET_ERROR_TYPE_ERROR);
729
730 LOG (GNUNET_ERROR_TYPE_ERROR, "\n");
731
732 return GNUNET_YES;
733}
734
735
736/**
737 * Iterator over all paths of a peer to build an InfoPeer message.
738 *
739 * Message contains blocks of peers, first not included.
740 *
741 * @param cls Closure (message to build).
742 * @param peer Peer this path is towards.
743 * @param path Path itself
744 * @return #GNUNET_YES if should keep iterating.
745 * #GNUNET_NO otherwise.
746 */
747static int
748path_info_iterator (void *cls,
749 struct CadetPeer *peer,
750 struct CadetPeerPath *path)
751{
752 struct GNUNET_CADET_LocalInfoPeer *resp = cls;
753 struct GNUNET_PeerIdentity *id;
754 uint16_t msg_size;
755 uint16_t path_size;
756 unsigned int i;
757
758 msg_size = ntohs (resp->header.size);
759 path_size = sizeof (struct GNUNET_PeerIdentity) * (path->length - 1);
760
761 LOG (GNUNET_ERROR_TYPE_DEBUG, "Info Path %u\n", path->length);
762 if (msg_size + path_size > UINT16_MAX)
763 {
764 LOG (GNUNET_ERROR_TYPE_WARNING, "path too long for info message\n");
765 return GNUNET_NO;
766 }
767
768 i = msg_size - sizeof (struct GNUNET_CADET_LocalInfoPeer);
769 i = i / sizeof (struct GNUNET_PeerIdentity);
770
771 /* Set id to the address of the first free peer slot. */
772 id = (struct GNUNET_PeerIdentity *) &resp[1];
773 id = &id[i];
774
775 /* Don't copy first peers.
776 * First peer is always the local one.
777 * Last peer is always the destination (leave as 0, EOL).
778 */
779 for (i = 0; i < path->length - 1; i++)
780 {
781 GNUNET_PEER_resolve (path->peers[i + 1], &id[i]);
782 LOG (GNUNET_ERROR_TYPE_DEBUG, " %s\n", GNUNET_i2s (&id[i]));
783 }
784
785 resp->header.size = htons (msg_size + path_size);
786
787 return GNUNET_YES;
788}
789
790
791/**
792 * Handler for client's INFO PEERS request.
793 *
794 * @param cls Closure (unused).
795 * @param client Identification of the client.
796 * @param message The actual message.
797 */
798static void
799handle_get_peers (void *cls, struct GNUNET_SERVER_Client *client,
800 const struct GNUNET_MessageHeader *message)
801{
802 struct CadetClient *c;
803 struct GNUNET_MessageHeader reply;
804
805 /* Sanity check for client registration */
806 if (NULL == (c = GML_client_get (client)))
807 {
808 GNUNET_break (0);
809 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
810 return;
811 }
812
813 LOG (GNUNET_ERROR_TYPE_DEBUG,
814 "Received get peers request from client %u (%p)\n",
815 c->id, client);
816
817 GCP_iterate_all (get_all_peers_iterator, client);
818 reply.size = htons (sizeof (reply));
819 reply.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS);
820 GNUNET_SERVER_notification_context_unicast (nc, client, &reply, GNUNET_NO);
821
822 LOG (GNUNET_ERROR_TYPE_DEBUG,
823 "Get peers request from client %u completed\n", c->id);
824 GNUNET_SERVER_receive_done (client, GNUNET_OK);
825}
826
827
828/**
829 * Handler for client's SHOW_PEER request.
830 *
831 * @param cls Closure (unused).
832 * @param client Identification of the client.
833 * @param message The actual message.
834 */
835void
836handle_show_peer (void *cls, struct GNUNET_SERVER_Client *client,
837 const struct GNUNET_MessageHeader *message)
838{
839 const struct GNUNET_CADET_LocalInfo *msg;
840 struct GNUNET_CADET_LocalInfoPeer *resp;
841 struct CadetPeer *p;
842 struct CadetClient *c;
843 unsigned char cbuf[64 * 1024];
844
845 /* Sanity check for client registration */
846 if (NULL == (c = GML_client_get (client)))
847 {
848 GNUNET_break (0);
849 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
850 return;
851 }
852
853 msg = (struct GNUNET_CADET_LocalInfo *) message;
854 resp = (struct GNUNET_CADET_LocalInfoPeer *) cbuf;
855 LOG (GNUNET_ERROR_TYPE_INFO,
856 "Received peer info request from client %u for peer %s\n",
857 c->id, GNUNET_i2s_full (&msg->peer));
858
859 resp->header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER);
860 resp->header.size = htons (sizeof (struct GNUNET_CADET_LocalInfoPeer));
861 resp->destination = msg->peer;
862 p = GCP_get (&msg->peer, GNUNET_NO);
863 if (NULL == p)
864 {
865 /* We don't know the peer */
866
867 LOG (GNUNET_ERROR_TYPE_INFO, "Peer %s unknown\n",
868 GNUNET_i2s_full (&msg->peer));
869 resp->paths = htons (0);
870 resp->tunnel = htons (NULL != GCP_get_tunnel (p));
871
872 GNUNET_SERVER_notification_context_unicast (nc, client,
873 &resp->header,
874 GNUNET_NO);
875 GNUNET_SERVER_receive_done (client, GNUNET_OK);
876 return;
877 }
878
879 resp->paths = htons (GCP_count_paths (p));
880 resp->tunnel = htons (NULL != GCP_get_tunnel (p));
881 GCP_iterate_paths (p, &path_info_iterator, resp);
882
883 GNUNET_SERVER_notification_context_unicast (nc, c->handle,
884 &resp->header, GNUNET_NO);
885
886 LOG (GNUNET_ERROR_TYPE_INFO, "Show peer from client %u completed.\n", c->id);
887 GNUNET_SERVER_receive_done (client, GNUNET_OK);
888}
889
890
891/**
892 * Iterator over all tunnels to send a monitoring client info about each tunnel.
893 *
894 * @param cls Closure ().
895 * @param peer Peer ID (tunnel remote peer).
896 * @param value Tunnel info.
897 *
898 * @return #GNUNET_YES, to keep iterating.
899 */
900static int
901get_all_tunnels_iterator (void *cls,
902 const struct GNUNET_PeerIdentity * peer,
903 void *value)
904{
905 struct GNUNET_SERVER_Client *client = cls;
906 struct CadetTunnel *t = value;
907 struct GNUNET_CADET_LocalInfoTunnel msg;
908
909 msg.header.size = htons (sizeof (msg));
910 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS);
911 msg.destination = *peer;
912 msg.channels = htonl (GCT_count_channels (t));
913 msg.connections = htonl (GCT_count_any_connections (t));
914 msg.cstate = htons ((uint16_t) GCT_get_cstate (t));
915 msg.estate = htons ((uint16_t) GCT_get_estate (t));
916
917 LOG (GNUNET_ERROR_TYPE_DEBUG, "sending info about tunnel ->%s\n",
918 GNUNET_i2s (peer));
919
920 GNUNET_SERVER_notification_context_unicast (nc, client,
921 &msg.header, GNUNET_NO);
922 return GNUNET_YES;
923}
924
925
926/**
927 * Handler for client's INFO TUNNELS request.
928 *
929 * @param cls Closure (unused).
930 * @param client Identification of the client.
931 * @param message The actual message.
932 */
933static void
934handle_get_tunnels (void *cls, struct GNUNET_SERVER_Client *client,
935 const struct GNUNET_MessageHeader *message)
936{
937 struct CadetClient *c;
938 struct GNUNET_MessageHeader reply;
939
940 /* Sanity check for client registration */
941 if (NULL == (c = GML_client_get (client)))
942 {
943 GNUNET_break (0);
944 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
945 return;
946 }
947
948 LOG (GNUNET_ERROR_TYPE_DEBUG,
949 "Received get tunnels request from client %u (%p)\n",
950 c->id, client);
951
952 GCT_iterate_all (get_all_tunnels_iterator, client);
953 reply.size = htons (sizeof (reply));
954 reply.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS);
955 GNUNET_SERVER_notification_context_unicast (nc, client, &reply, GNUNET_NO);
956
957 LOG (GNUNET_ERROR_TYPE_DEBUG,
958 "Get tunnels request from client %u completed\n", c->id);
959 GNUNET_SERVER_receive_done (client, GNUNET_OK);
960}
961
962
963static void
964iter_connection (void *cls, struct CadetConnection *c)
965{
966 struct GNUNET_CADET_LocalInfoTunnel *msg = cls;
967 struct GNUNET_CADET_ConnectionTunnelIdentifier *h;
968
969 h = (struct GNUNET_CADET_ConnectionTunnelIdentifier *) &msg[1];
970 h[msg->connections] = *(GCC_get_id (c));
971 msg->connections++;
972}
973
974static void
975iter_channel (void *cls, struct CadetChannel *ch)
976{
977 struct GNUNET_CADET_LocalInfoTunnel *msg = cls;
978 struct GNUNET_CADET_ConnectionTunnelIdentifier *h = (struct GNUNET_CADET_ConnectionTunnelIdentifier *) &msg[1];
979 struct GNUNET_CADET_ChannelTunnelNumber *chn = (struct GNUNET_CADET_ChannelTunnelNumber *) &h[msg->connections];
980
981 chn[msg->channels] = GCCH_get_id (ch);
982 msg->channels++;
983}
984
985
986/**
987 * Handler for client's SHOW_TUNNEL request.
988 *
989 * @param cls Closure (unused).
990 * @param client Identification of the client.
991 * @param message The actual message.
992 */
993void
994handle_show_tunnel (void *cls, struct GNUNET_SERVER_Client *client,
995 const struct GNUNET_MessageHeader *message)
996{
997 const struct GNUNET_CADET_LocalInfo *msg;
998 struct GNUNET_CADET_LocalInfoTunnel *resp;
999 struct CadetClient *c;
1000 struct CadetTunnel *t;
1001 unsigned int ch_n;
1002 unsigned int c_n;
1003 size_t size;
1004
1005 /* Sanity check for client registration */
1006 if (NULL == (c = GML_client_get (client)))
1007 {
1008 GNUNET_break (0);
1009 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1010 return;
1011 }
1012
1013 msg = (struct GNUNET_CADET_LocalInfo *) message;
1014 LOG (GNUNET_ERROR_TYPE_DEBUG,
1015 "Received tunnel info request from client %u for tunnel %s\n",
1016 c->id, GNUNET_i2s_full(&msg->peer));
1017
1018 t = GCP_get_tunnel (GCP_get (&msg->peer, GNUNET_NO));
1019 if (NULL == t)
1020 {
1021 /* We don't know the tunnel */
1022 struct GNUNET_CADET_LocalInfoTunnel warn;
1023
1024 LOG (GNUNET_ERROR_TYPE_INFO, "Tunnel %s unknown %u\n",
1025 GNUNET_i2s_full(&msg->peer), sizeof (warn));
1026 warn.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL);
1027 warn.header.size = htons (sizeof (warn));
1028 warn.destination = msg->peer;
1029 warn.channels = htonl (0);
1030 warn.connections = htonl (0);
1031 warn.cstate = htons (0);
1032 warn.estate = htons (0);
1033
1034 GNUNET_SERVER_notification_context_unicast (nc, client,
1035 &warn.header,
1036 GNUNET_NO);
1037 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1038 return;
1039 }
1040
1041 /* Initialize context */
1042 ch_n = GCT_count_channels (t);
1043 c_n = GCT_count_any_connections (t);
1044
1045 size = sizeof (struct GNUNET_CADET_LocalInfoTunnel);
1046 size += c_n * sizeof (struct GNUNET_CADET_ConnectionTunnelIdentifier);
1047 size += ch_n * sizeof (struct GNUNET_CADET_ChannelTunnelNumber);
1048
1049 resp = GNUNET_malloc (size);
1050 resp->header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL);
1051 resp->header.size = htons (size);
1052 resp->destination = msg->peer;
1053 /* Do not interleave with iterators, iter_channel needs conn in HBO */
1054 GCT_iterate_connections (t, &iter_connection, resp);
1055 GCT_iterate_channels (t, &iter_channel, resp);
1056 resp->connections = htonl (resp->connections);
1057 resp->channels = htonl (resp->channels);
1058 /* Do not interleave end */
1059 resp->cstate = htons (GCT_get_cstate (t));
1060 resp->estate = htons (GCT_get_estate (t));
1061 GNUNET_SERVER_notification_context_unicast (nc, c->handle,
1062 &resp->header, GNUNET_NO);
1063 GNUNET_free (resp);
1064
1065 LOG (GNUNET_ERROR_TYPE_DEBUG,
1066 "Show tunnel request from client %u completed. %u conn, %u ch\n",
1067 c->id, c_n, ch_n);
1068 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1069}
1070
1071
1072/**
1073 * Handler for client's INFO_DUMP request.
1074 *
1075 * @param cls Closure (unused).
1076 * @param client Identification of the client.
1077 * @param message The actual message.
1078 */
1079void
1080handle_info_dump (void *cls, struct GNUNET_SERVER_Client *client,
1081 const struct GNUNET_MessageHeader *message)
1082{
1083 struct CadetClient *c;
1084
1085 /* Sanity check for client registration */
1086 if (NULL == (c = GML_client_get (client)))
1087 {
1088 GNUNET_break (0);
1089 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1090 return;
1091 }
1092
1093 LOG (GNUNET_ERROR_TYPE_INFO, "Received dump info request from client %u\n",
1094 c->id);
1095 LOG (GNUNET_ERROR_TYPE_ERROR,
1096 "*************************** DUMP START ***************************\n");
1097
1098 for (c = clients_head; NULL != c; c = c->next)
1099 {
1100 LOG (GNUNET_ERROR_TYPE_ERROR, "Client %u (%p), handle: %p\n",
1101 c->id, c, c->handle);
1102 if (NULL != c->ports)
1103 LOG (GNUNET_ERROR_TYPE_ERROR, "\t%3u ports registered\n",
1104 GNUNET_CONTAINER_multihashmap_size (c->ports));
1105 else
1106 LOG (GNUNET_ERROR_TYPE_ERROR, "\t no ports registered\n");
1107 LOG (GNUNET_ERROR_TYPE_ERROR, "\t%3u own channles\n",
1108 GNUNET_CONTAINER_multihashmap32_size (c->own_channels));
1109 LOG (GNUNET_ERROR_TYPE_ERROR, "\t%3u incoming channles\n",
1110 GNUNET_CONTAINER_multihashmap32_size (c->incoming_channels));
1111 }
1112 LOG (GNUNET_ERROR_TYPE_ERROR, "***************************\n");
1113 GCP_iterate_all (&show_peer_iterator, NULL);
1114
1115 LOG (GNUNET_ERROR_TYPE_ERROR,
1116 "**************************** DUMP END ****************************\n");
1117
1118 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1119}
1120
1121
1122/**
1123 * Functions to handle messages from clients
1124 */
1125static struct GNUNET_SERVER_MessageHandler client_handlers[] = {
1126 {&handle_port_open, NULL, GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN,
1127 sizeof (struct GNUNET_CADET_PortMessage)},
1128 {&handle_port_close, NULL, GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE,
1129 sizeof (struct GNUNET_CADET_PortMessage)},
1130 {&handle_channel_create, NULL, GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE,
1131 sizeof (struct GNUNET_CADET_LocalChannelCreateMessage)},
1132 {&handle_channel_destroy, NULL, GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY,
1133 sizeof (struct GNUNET_CADET_LocalChannelDestroyMessage)},
1134 {&handle_data, NULL, GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA, 0},
1135 {&handle_ack, NULL, GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK,
1136 sizeof (struct GNUNET_CADET_LocalAck)},
1137 {&handle_get_peers, NULL, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS,
1138 sizeof (struct GNUNET_MessageHeader)},
1139 {&handle_show_peer, NULL, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER,
1140 sizeof (struct GNUNET_CADET_LocalInfo)},
1141 {&handle_get_tunnels, NULL, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS,
1142 sizeof (struct GNUNET_MessageHeader)},
1143 {&handle_show_tunnel, NULL, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL,
1144 sizeof (struct GNUNET_CADET_LocalInfo)},
1145 {&handle_info_dump, NULL, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_DUMP,
1146 sizeof (struct GNUNET_MessageHeader)},
1147 {NULL, NULL, 0, 0}
1148};
1149
1150
1151
1152/******************************************************************************/
1153/******************************** API ***********************************/
1154/******************************************************************************/
1155
1156/**
1157 * Initialize server subsystem.
1158 *
1159 * @param handle Server handle.
1160 */
1161void
1162GML_init (struct GNUNET_SERVER_Handle *handle)
1163{
1164 LOG (GNUNET_ERROR_TYPE_DEBUG, "init\n");
1165 server_handle = handle;
1166 GNUNET_SERVER_suspend (server_handle);
1167 ports = GNUNET_CONTAINER_multihashmap_create (16, GNUNET_NO);
1168}
1169
1170
1171/**
1172 * Install server (service) handlers and start listening to clients.
1173 */
1174void
1175GML_start (void)
1176{
1177 GNUNET_SERVER_add_handlers (server_handle, client_handlers);
1178 GNUNET_SERVER_connect_notify (server_handle, &handle_client_connect, NULL);
1179 GNUNET_SERVER_disconnect_notify (server_handle, &handle_client_disconnect,
1180 NULL);
1181 nc = GNUNET_SERVER_notification_context_create (server_handle, 1);
1182
1183 clients_head = NULL;
1184 clients_tail = NULL;
1185 next_client_id = 0;
1186 GNUNET_SERVER_resume (server_handle);
1187}
1188
1189
1190/**
1191 * Shutdown server.
1192 */
1193void
1194GML_shutdown (void)
1195{
1196 struct CadetClient *c;
1197
1198 LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down local\n");
1199
1200 for (c = clients_head; NULL != clients_head; c = clients_head)
1201 client_destroy (c);
1202
1203 if (nc != NULL)
1204 {
1205 GNUNET_SERVER_notification_context_destroy (nc);
1206 nc = NULL;
1207 }
1208
1209}
1210
1211
1212/**
1213 * Get a channel from a client.
1214 *
1215 * @param c Client to check.
1216 * @param ccn Channel ID, must be local (> 0x800...).
1217 *
1218 * @return non-NULL if channel exists in the clients lists
1219 */
1220struct CadetChannel *
1221GML_channel_get (struct CadetClient *c,
1222 struct GNUNET_CADET_ClientChannelNumber ccn)
1223{
1224 struct GNUNET_CONTAINER_MultiHashMap32 *map;
1225
1226 if (ntohl (ccn.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
1227 map = c->own_channels;
1228 else
1229 map = c->incoming_channels;
1230
1231 if (NULL == map)
1232 {
1233 GNUNET_break (0);
1234 LOG (GNUNET_ERROR_TYPE_DEBUG,
1235 "Client %s does no t have a valid map for CCN %X\n",
1236 GML_2s (c), ccn);
1237 return NULL;
1238 }
1239 return GNUNET_CONTAINER_multihashmap32_get (map,
1240 ccn.channel_of_client);
1241}
1242
1243
1244/**
1245 * Add a channel to a client
1246 *
1247 * @param client Client.
1248 * @param ccn Channel ID.
1249 * @param ch Channel.
1250 */
1251void
1252GML_channel_add (struct CadetClient *client,
1253 struct GNUNET_CADET_ClientChannelNumber ccn,
1254 struct CadetChannel *ch)
1255{
1256 if (ntohl (ccn.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
1257 GNUNET_CONTAINER_multihashmap32_put (client->own_channels,
1258 ccn.channel_of_client,
1259 ch,
1260 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
1261 else
1262 GNUNET_CONTAINER_multihashmap32_put (client->incoming_channels,
1263 ccn.channel_of_client,
1264 ch,
1265 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
1266}
1267
1268
1269/**
1270 * Remove a channel from a client.
1271 *
1272 * @param client Client.
1273 * @param ccn Channel ID.
1274 * @param ch Channel.
1275 */
1276void
1277GML_channel_remove (struct CadetClient *client,
1278 struct GNUNET_CADET_ClientChannelNumber ccn,
1279 struct CadetChannel *ch)
1280{
1281 if (ntohl (ccn.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
1282 GNUNET_CONTAINER_multihashmap32_remove (client->own_channels,
1283 ccn.channel_of_client,
1284 ch);
1285 else
1286 GNUNET_CONTAINER_multihashmap32_remove (client->incoming_channels,
1287 ccn.channel_of_client,
1288 ch);
1289}
1290
1291
1292/**
1293 * Get the tunnel's next free local channel ID.
1294 *
1295 * @param c Client.
1296 *
1297 * @return LID of a channel free to use.
1298 */
1299struct GNUNET_CADET_ClientChannelNumber
1300GML_get_next_ccn (struct CadetClient *c)
1301{
1302 struct GNUNET_CADET_ClientChannelNumber ccn;
1303
1304 while (NULL != GML_channel_get (c,
1305 c->next_ccn))
1306 {
1307 LOG (GNUNET_ERROR_TYPE_DEBUG,
1308 "Channel %u exists...\n",
1309 c->next_ccn);
1310 c->next_ccn.channel_of_client
1311 = htonl (1 + (ntohl (c->next_ccn.channel_of_client)));
1312 if (ntohl (c->next_ccn.channel_of_client) >=
1313 GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
1314 c->next_ccn.channel_of_client = htonl (0);
1315 }
1316 ccn = c->next_ccn;
1317 c->next_ccn.channel_of_client
1318 = htonl (1 + (ntohl (c->next_ccn.channel_of_client)));
1319
1320 return ccn;
1321}
1322
1323
1324/**
1325 * Check if client has registered with the service and has not disconnected
1326 *
1327 * @param client the client to check
1328 *
1329 * @return non-NULL if client exists in the global DLL
1330 */
1331struct CadetClient *
1332GML_client_get (struct GNUNET_SERVER_Client *client)
1333{
1334 if (NULL == client)
1335 return NULL;
1336 return GNUNET_SERVER_client_get_user_context (client,
1337 struct CadetClient);
1338}
1339
1340
1341/**
1342 * Find a client that has opened a port
1343 *
1344 * @param port Port to check.
1345 *
1346 * @return non-NULL if a client has the port.
1347 */
1348struct CadetClient *
1349GML_client_get_by_port (const struct GNUNET_HashCode *port)
1350{
1351 return GNUNET_CONTAINER_multihashmap_get (ports, port);
1352}
1353
1354
1355/**
1356 * Deletes a channel from a client (either owner or destination).
1357 *
1358 * @param c Client whose tunnel to delete.
1359 * @param ch Channel which should be deleted.
1360 * @param id Channel ID.
1361 */
1362void
1363GML_client_delete_channel (struct CadetClient *c,
1364 struct CadetChannel *ch,
1365 struct GNUNET_CADET_ClientChannelNumber id)
1366{
1367 int res;
1368
1369 if (ntohl (id.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
1370 {
1371 res = GNUNET_CONTAINER_multihashmap32_remove (c->own_channels,
1372 id.channel_of_client,
1373 ch);
1374 if (GNUNET_YES != res)
1375 LOG (GNUNET_ERROR_TYPE_DEBUG, "client_delete_tunnel root KO\n");
1376 }
1377 else
1378 {
1379 res = GNUNET_CONTAINER_multihashmap32_remove (c->incoming_channels,
1380 id.channel_of_client,
1381 ch);
1382 if (GNUNET_YES != res)
1383 LOG (GNUNET_ERROR_TYPE_DEBUG, "client_delete_channel dest KO\n");
1384 }
1385}
1386
1387/**
1388 * Build a local ACK message and send it to a local client, if needed.
1389 *
1390 * If the client was already allowed to send data, do nothing.
1391 *
1392 * @param c Client to whom send the ACK.
1393 * @param ccn Channel ID to use
1394 */
1395void
1396GML_send_ack (struct CadetClient *c,
1397 struct GNUNET_CADET_ClientChannelNumber ccn)
1398{
1399 struct GNUNET_CADET_LocalAck msg;
1400
1401 LOG (GNUNET_ERROR_TYPE_DEBUG,
1402 "send local %s ack on %X towards %p\n",
1403 ntohl (ccn.channel_of_client) < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI
1404 ? "FWD" : "BCK",
1405 ntohl (ccn.channel_of_client),
1406 c);
1407
1408 msg.header.size = htons (sizeof (msg));
1409 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK);
1410 msg.ccn = ccn;
1411 GNUNET_SERVER_notification_context_unicast (nc,
1412 c->handle,
1413 &msg.header,
1414 GNUNET_NO);
1415
1416}
1417
1418
1419
1420/**
1421 * Notify the client that a new incoming channel was created.
1422 *
1423 * @param c Client to notify.
1424 * @param ccn Channel ID.
1425 * @param port Channel's destination port.
1426 * @param opt Options (bit array).
1427 * @param peer Origin peer.
1428 */
1429void
1430GML_send_channel_create (struct CadetClient *c,
1431 struct GNUNET_CADET_ClientChannelNumber ccn,
1432 const struct GNUNET_HashCode *port,
1433 uint32_t opt,
1434 const struct GNUNET_PeerIdentity *peer)
1435{
1436 struct GNUNET_CADET_LocalChannelCreateMessage msg;
1437
1438 msg.header.size = htons (sizeof (msg));
1439 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE);
1440 msg.ccn = ccn;
1441 msg.port = *port;
1442 msg.opt = htonl (opt);
1443 msg.peer = *peer;
1444 GNUNET_SERVER_notification_context_unicast (nc, c->handle,
1445 &msg.header, GNUNET_NO);
1446}
1447
1448
1449/**
1450 * Build a local channel NACK message and send it to a local client.
1451 *
1452 * @param c Client to whom send the NACK.
1453 * @param ccn Channel ID to use
1454 */
1455void
1456GML_send_channel_nack (struct CadetClient *c,
1457 struct GNUNET_CADET_ClientChannelNumber ccn)
1458{
1459 struct GNUNET_CADET_LocalAck msg;
1460
1461 LOG (GNUNET_ERROR_TYPE_DEBUG,
1462 "send local nack on %X towards %p\n",
1463 ntohl (ccn.channel_of_client),
1464 c);
1465
1466 msg.header.size = htons (sizeof (msg));
1467 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_NACK_DEPRECATED);
1468 msg.ccn = ccn;
1469 GNUNET_SERVER_notification_context_unicast (nc,
1470 c->handle,
1471 &msg.header,
1472 GNUNET_NO);
1473
1474}
1475
1476/**
1477 * Notify a client that a channel is no longer valid.
1478 *
1479 * @param c Client.
1480 * @param ccn ID of the channel that is destroyed.
1481 */
1482void
1483GML_send_channel_destroy (struct CadetClient *c,
1484 struct GNUNET_CADET_ClientChannelNumber ccn)
1485{
1486 struct GNUNET_CADET_LocalChannelDestroyMessage msg;
1487
1488 if (NULL == c)
1489 {
1490 GNUNET_break (0);
1491 return;
1492 }
1493 if (GNUNET_YES == c->shutting_down)
1494 return;
1495 msg.header.size = htons (sizeof (msg));
1496 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY);
1497 msg.ccn = ccn;
1498 GNUNET_SERVER_notification_context_unicast (nc, c->handle,
1499 &msg.header, GNUNET_NO);
1500}
1501
1502
1503/**
1504 * Modify the cadet message ID from global to local and send to client.
1505 *
1506 * @param c Client to send to.
1507 * @param msg Message to modify and send.
1508 * @param ccn Channel ID to use (c can be both owner and client).
1509 */
1510void
1511GML_send_data (struct CadetClient *c,
1512 const struct GNUNET_CADET_ChannelAppDataMessage *msg,
1513 struct GNUNET_CADET_ClientChannelNumber ccn)
1514{
1515 struct GNUNET_CADET_LocalData *copy;
1516 uint16_t size = ntohs (msg->header.size) - sizeof (struct GNUNET_CADET_ChannelAppDataMessage);
1517 char cbuf[size + sizeof (struct GNUNET_CADET_LocalData)];
1518
1519 if (size < sizeof (struct GNUNET_MessageHeader))
1520 {
1521 GNUNET_break_op (0);
1522 return;
1523 }
1524 if (NULL == c)
1525 {
1526 GNUNET_break (0);
1527 return;
1528 }
1529 copy = (struct GNUNET_CADET_LocalData *) cbuf;
1530 GNUNET_memcpy (&copy[1], &msg[1], size);
1531 copy->header.size = htons (sizeof (struct GNUNET_CADET_LocalData) + size);
1532 copy->header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA);
1533 copy->ccn = ccn;
1534 GNUNET_SERVER_notification_context_unicast (nc, c->handle,
1535 &copy->header, GNUNET_NO);
1536}
1537
1538
1539/**
1540 * Get the static string to represent a client.
1541 *
1542 * @param c Client.
1543 *
1544 * @return Static string for the client.
1545 */
1546const char *
1547GML_2s (const struct CadetClient *c)
1548{
1549 static char buf[32];
1550
1551 SPRINTF (buf, "%u", c->id);
1552 return buf;
1553}