2 This file is part of GNUnet.
3 Copyright (C) 2013 GNUnet e.V.
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.
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.
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.
23 #include "gnunet_util_lib.h"
25 #include "gnunet_statistics_service.h"
28 #include "cadet_protocol.h" /* GNUNET_CADET_Data is shared */
30 #include "gnunet-service-cadet_local.h"
31 #include "gnunet-service-cadet_channel.h"
34 #include "gnunet-service-cadet_tunnel.h"
35 #include "gnunet-service-cadet_peer.h"
37 #define LOG(level, ...) GNUNET_log_from(level,"cadet-loc",__VA_ARGS__)
39 /******************************************************************************/
40 /******************************** STRUCTS **********************************/
41 /******************************************************************************/
44 * Struct containing information about a client of the service
46 * TODO: add a list of 'waiting' ports
53 struct CadetClient *next;
58 struct CadetClient *prev;
61 * Tunnels that belong to this client, indexed by local id
63 struct GNUNET_CONTAINER_MultiHashMap32 *own_channels;
66 * Tunnels this client has accepted, indexed by incoming local id
68 struct GNUNET_CONTAINER_MultiHashMap32 *incoming_channels;
71 * Channel ID for the next incoming channel.
73 struct GNUNET_CADET_ClientChannelNumber next_ccn;
76 * Handle to communicate with the client
78 struct GNUNET_SERVER_Client *handle;
81 * Ports that this client has declared interest in.
82 * Indexed by port, contains *Client.
84 struct GNUNET_CONTAINER_MultiHashMap *ports;
87 * Whether the client is active or shutting down (don't send confirmations
88 * to a client that is shutting down.
93 * ID of the client, mainly for debug messages
98 /******************************************************************************/
99 /******************************* GLOBALS ***********************************/
100 /******************************************************************************/
103 * Global handle to the statistics service.
105 extern struct GNUNET_STATISTICS_Handle *stats;
108 * Handle to server lib.
110 static struct GNUNET_SERVER_Handle *server_handle;
113 * DLL with all the clients, head.
115 static struct CadetClient *clients_head;
118 * DLL with all the clients, tail.
120 static struct CadetClient *clients_tail;
123 * Next ID to assign to a client.
125 unsigned int next_client_id;
128 * All ports clients of this peer have opened.
130 static struct GNUNET_CONTAINER_MultiHashMap *ports;
133 * Notification context, to send messages to local clients.
135 static struct GNUNET_SERVER_NotificationContext *nc;
138 /******************************************************************************/
139 /******************************** STATIC ***********************************/
140 /******************************************************************************/
143 * Remove client's ports from the global hashmap on disconnect.
145 * @param cls Closure (unused).
147 * @param value Client structure.
149 * @return #GNUNET_OK, keep iterating.
152 client_release_ports (void *cls,
153 const struct GNUNET_HashCode *key,
158 res = GNUNET_CONTAINER_multihashmap_remove (ports, key, value);
159 if (GNUNET_YES != res)
162 LOG (GNUNET_ERROR_TYPE_WARNING,
163 "Port %s by client %p was not registered.\n",
164 GNUNET_h2s (key), value);
171 * Iterator for deleting each channel whose client endpoint disconnected.
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).
177 * @return #GNUNET_OK, keep iterating.
180 channel_destroy_iterator (void *cls,
184 struct CadetChannel *ch = value;
185 struct CadetClient *c = cls;
187 LOG (GNUNET_ERROR_TYPE_DEBUG,
188 " Channel %s destroy, due to client %s shutdown.\n",
189 GCCH_2s (ch), GML_2s (c));
191 GCCH_handle_local_destroy (ch,
193 key < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI);
199 * Unregister data and free memory for a client.
201 * @param c Client to destroy. No longer valid after call.
204 client_destroy (struct CadetClient *c)
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;
210 if (NULL != c->own_channels)
212 GNUNET_CONTAINER_multihashmap32_iterate (c->own_channels,
213 &channel_destroy_iterator, c);
214 GNUNET_CONTAINER_multihashmap32_destroy (c->own_channels);
216 if (NULL != c->incoming_channels)
218 GNUNET_CONTAINER_multihashmap32_iterate (c->incoming_channels,
219 &channel_destroy_iterator, c);
220 GNUNET_CONTAINER_multihashmap32_destroy (c->incoming_channels);
222 if (NULL != c->ports)
224 GNUNET_CONTAINER_multihashmap_iterate (c->ports,
225 &client_release_ports, c);
226 GNUNET_CONTAINER_multihashmap_destroy (c->ports);
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);
237 * Create a client record, register data and initialize memory.
239 * @param client Client's handle.
241 static struct CadetClient *
242 client_new (struct GNUNET_SERVER_Client *client)
244 struct CadetClient *c;
246 GNUNET_SERVER_client_keep (client);
247 GNUNET_SERVER_notification_context_add (nc, client);
249 c = GNUNET_new (struct CadetClient);
251 c->id = next_client_id++; /* overflow not important: just for debug */
253 c->own_channels = GNUNET_CONTAINER_multihashmap32_create (32);
254 c->incoming_channels = GNUNET_CONTAINER_multihashmap32_create (32);
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);
260 LOG (GNUNET_ERROR_TYPE_DEBUG, " client created: %p/%u\n", c, c->id);
266 /******************************************************************************/
267 /******************************** HANDLES ***********************************/
268 /******************************************************************************/
271 * Handler for client connection.
273 * @param cls Closure (unused).
274 * @param client Client handler.
277 handle_client_connect (void *cls, struct GNUNET_SERVER_Client *client)
279 LOG (GNUNET_ERROR_TYPE_DEBUG, "Client connected: %p\n", client);
283 (void) client_new (client);
288 * Handler for client disconnection
291 * @param client identification of the client; NULL
292 * for the last call when the server is destroyed
295 handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
297 struct CadetClient *c;
299 LOG (GNUNET_ERROR_TYPE_DEBUG, "Client disconnected: %p\n", client);
301 c = GML_client_get (client);
304 LOG (GNUNET_ERROR_TYPE_DEBUG, "matching client found (%u, %p)\n",
310 LOG (GNUNET_ERROR_TYPE_DEBUG, " disconnecting client's context NULL\n");
317 * Handler for port open requests.
319 * @param cls Closure.
320 * @param client Identification of the client.
321 * @param message The actual message.
324 handle_port_open (void *cls, struct GNUNET_SERVER_Client *client,
325 const struct GNUNET_MessageHeader *message)
327 struct CadetClient *c;
328 struct GNUNET_CADET_PortMessage *pmsg;
330 LOG (GNUNET_ERROR_TYPE_DEBUG, "open port requested\n");
332 /* Sanity check for client registration */
333 if (NULL == (c = GML_client_get (client)))
336 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
339 LOG (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
341 /* Message size sanity check */
342 if (sizeof (struct GNUNET_CADET_PortMessage) != ntohs (message->size))
345 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
349 pmsg = (struct GNUNET_CADET_PortMessage *) message;
350 if (NULL == c->ports)
352 c->ports = GNUNET_CONTAINER_multihashmap_create (4, GNUNET_NO);
354 /* store in client's hashmap */
356 GNUNET_CONTAINER_multihashmap_put (c->ports, &pmsg->port, c,
357 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
360 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
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);
369 GNUNET_SERVER_receive_done (client, GNUNET_OK);
374 * Handler for port close requests.
376 * @param cls Closure.
377 * @param client Identification of the client.
378 * @param message The actual message.
381 handle_port_close (void *cls, struct GNUNET_SERVER_Client *client,
382 const struct GNUNET_MessageHeader *message)
384 struct CadetClient *c;
385 struct GNUNET_CADET_PortMessage *pmsg;
388 LOG (GNUNET_ERROR_TYPE_DEBUG, "close port requested\n");
390 /* Sanity check for client registration */
391 if (NULL == (c = GML_client_get (client)))
394 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
397 LOG (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
399 /* Message size sanity check */
400 if (sizeof (struct GNUNET_CADET_PortMessage) != ntohs (message->size))
403 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
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);
413 GNUNET_SERVER_receive_done (client, GNUNET_OK);
418 * Handler for requests of new channels.
420 * @param cls Closure.
421 * @param client Identification of the client.
422 * @param message The actual message.
425 handle_channel_create (void *cls, struct GNUNET_SERVER_Client *client,
426 const struct GNUNET_MessageHeader *message)
428 struct CadetClient *c;
430 LOG (GNUNET_ERROR_TYPE_DEBUG, "\n");
431 LOG (GNUNET_ERROR_TYPE_DEBUG, "new channel requested\n");
433 /* Sanity check for client registration */
434 if (NULL == (c = GML_client_get (client)))
437 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
440 LOG (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
442 /* Message size sanity check */
443 if (sizeof (struct GNUNET_CADET_LocalChannelCreateMessage)
444 != ntohs (message->size))
447 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
452 GCCH_handle_local_create (c,
453 (struct GNUNET_CADET_LocalChannelCreateMessage *)
456 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
460 GNUNET_SERVER_receive_done (client, GNUNET_OK);
465 * Handler for requests of deleting tunnels
468 * @param client identification of the client
469 * @param message the actual message
472 handle_channel_destroy (void *cls, struct GNUNET_SERVER_Client *client,
473 const struct GNUNET_MessageHeader *message)
475 const struct GNUNET_CADET_LocalChannelDestroyMessage *msg;
476 struct CadetClient *c;
477 struct CadetChannel *ch;
478 struct GNUNET_CADET_ClientChannelNumber ccn;
480 LOG (GNUNET_ERROR_TYPE_DEBUG, "Got a DESTROY CHANNEL from client!\n");
482 /* Sanity check for client registration */
483 if (NULL == (c = GML_client_get (client)))
486 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
489 LOG (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
491 /* Message sanity check */
492 if (sizeof (struct GNUNET_CADET_LocalChannelDestroyMessage)
493 != ntohs (message->size))
496 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
500 msg = (const struct GNUNET_CADET_LocalChannelDestroyMessage *) message;
502 /* Retrieve tunnel */
504 ch = GML_channel_get (c, ccn);
506 LOG (GNUNET_ERROR_TYPE_INFO, "Client %u is destroying channel %X\n",
511 LOG (GNUNET_ERROR_TYPE_WARNING, " channel %X not found\n", ccn);
512 GNUNET_STATISTICS_update (stats,
513 "# client destroy messages on unknown channel",
515 GNUNET_SERVER_receive_done (client, GNUNET_OK);
519 GCCH_handle_local_destroy (ch,
521 ntohl (ccn.channel_of_client) < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI);
523 GNUNET_SERVER_receive_done (client, GNUNET_OK);
528 * Handler for client traffic
531 * @param client identification of the client
532 * @param message the actual message
535 handle_data (void *cls, struct GNUNET_SERVER_Client *client,
536 const struct GNUNET_MessageHeader *message)
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;
545 size_t payload_claimed_size;
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");
552 /* Sanity check for client registration */
553 if (NULL == (c = GML_client_get (client)))
556 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
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)
567 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
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)
580 LOG (GNUNET_ERROR_TYPE_WARNING,
581 "client claims to send %u bytes in %u payload\n",
582 payload_claimed_size, payload_size);
584 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
589 LOG (GNUNET_ERROR_TYPE_DEBUG, " %u bytes (%u payload) by client %u\n",
590 payload_size, payload_claimed_size, c->id);
592 /* Channel exists? */
593 fwd = ntohl (ccn.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI;
594 ch = GML_channel_get (c, ccn);
597 GNUNET_STATISTICS_update (stats,
598 "# client data messages on unknown channel",
600 GNUNET_SERVER_receive_done (client, GNUNET_OK);
604 if (GNUNET_OK != GCCH_handle_local_data (ch, c, fwd, payload, payload_size))
606 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
610 LOG (GNUNET_ERROR_TYPE_DEBUG, "receive done OK\n");
611 GNUNET_SERVER_receive_done (client, GNUNET_OK);
618 * Handler for client's ACKs for payload traffic.
620 * @param cls Closure (unused).
621 * @param client Identification of the client.
622 * @param message The actual message.
625 handle_ack (void *cls, struct GNUNET_SERVER_Client *client,
626 const struct GNUNET_MessageHeader *message)
628 struct GNUNET_CADET_LocalAck *msg;
629 struct CadetChannel *ch;
630 struct CadetClient *c;
631 struct GNUNET_CADET_ClientChannelNumber ccn;
634 LOG (GNUNET_ERROR_TYPE_DEBUG, "\n");
635 LOG (GNUNET_ERROR_TYPE_DEBUG, "Got a local ACK\n");
637 /* Sanity check for client registration */
638 if (NULL == (c = GML_client_get (client)))
641 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
644 LOG (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
646 msg = (struct GNUNET_CADET_LocalAck *) message;
648 /* Channel exists? */
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);
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",
663 GNUNET_SERVER_receive_done (client, GNUNET_OK);
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;
671 GCCH_handle_local_ack (ch, fwd);
672 GNUNET_SERVER_receive_done (client, GNUNET_OK);
677 * Iterator over all peers to send a monitoring client info about each peer.
679 * @param cls Closure ().
680 * @param peer Peer ID (tunnel remote peer).
681 * @param value Peer info.
683 * @return #GNUNET_YES, to keep iterating.
686 get_all_peers_iterator (void *cls,
687 const struct GNUNET_PeerIdentity * peer,
690 struct GNUNET_SERVER_Client *client = cls;
691 struct CadetPeer *p = value;
692 struct GNUNET_CADET_LocalInfoPeer msg;
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));
700 LOG (GNUNET_ERROR_TYPE_DEBUG, "sending info about peer %s\n",
703 GNUNET_SERVER_notification_context_unicast (nc, client,
704 &msg.header, GNUNET_NO);
710 * Iterator over all peers to dump info for each peer.
712 * @param cls Closure (unused).
713 * @param peer Peer ID (tunnel remote peer).
714 * @param value Peer info.
716 * @return #GNUNET_YES, to keep iterating.
719 show_peer_iterator (void *cls,
720 const struct GNUNET_PeerIdentity * peer,
723 struct CadetPeer *p = value;
724 struct CadetTunnel *t;
726 t = GCP_get_tunnel (p);
728 GCT_debug (t, GNUNET_ERROR_TYPE_ERROR);
730 LOG (GNUNET_ERROR_TYPE_ERROR, "\n");
737 * Iterator over all paths of a peer to build an InfoPeer message.
739 * Message contains blocks of peers, first not included.
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.
748 path_info_iterator (void *cls,
749 struct CadetPeer *peer,
750 struct CadetPeerPath *path)
752 struct GNUNET_CADET_LocalInfoPeer *resp = cls;
753 struct GNUNET_PeerIdentity *id;
758 msg_size = ntohs (resp->header.size);
759 path_size = sizeof (struct GNUNET_PeerIdentity) * (path->length - 1);
761 LOG (GNUNET_ERROR_TYPE_DEBUG, "Info Path %u\n", path->length);
762 if (msg_size + path_size > UINT16_MAX)
764 LOG (GNUNET_ERROR_TYPE_WARNING, "path too long for info message\n");
768 i = msg_size - sizeof (struct GNUNET_CADET_LocalInfoPeer);
769 i = i / sizeof (struct GNUNET_PeerIdentity);
771 /* Set id to the address of the first free peer slot. */
772 id = (struct GNUNET_PeerIdentity *) &resp[1];
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).
779 for (i = 0; i < path->length - 1; i++)
781 GNUNET_PEER_resolve (path->peers[i + 1], &id[i]);
782 LOG (GNUNET_ERROR_TYPE_DEBUG, " %s\n", GNUNET_i2s (&id[i]));
785 resp->header.size = htons (msg_size + path_size);
792 * Handler for client's INFO PEERS request.
794 * @param cls Closure (unused).
795 * @param client Identification of the client.
796 * @param message The actual message.
799 handle_get_peers (void *cls, struct GNUNET_SERVER_Client *client,
800 const struct GNUNET_MessageHeader *message)
802 struct CadetClient *c;
803 struct GNUNET_MessageHeader reply;
805 /* Sanity check for client registration */
806 if (NULL == (c = GML_client_get (client)))
809 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
813 LOG (GNUNET_ERROR_TYPE_DEBUG,
814 "Received get peers request from client %u (%p)\n",
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);
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);
829 * Handler for client's SHOW_PEER request.
831 * @param cls Closure (unused).
832 * @param client Identification of the client.
833 * @param message The actual message.
836 handle_show_peer (void *cls, struct GNUNET_SERVER_Client *client,
837 const struct GNUNET_MessageHeader *message)
839 const struct GNUNET_CADET_LocalInfo *msg;
840 struct GNUNET_CADET_LocalInfoPeer *resp;
842 struct CadetClient *c;
843 unsigned char cbuf[64 * 1024];
845 /* Sanity check for client registration */
846 if (NULL == (c = GML_client_get (client)))
849 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
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));
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);
865 /* We don't know the peer */
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));
872 GNUNET_SERVER_notification_context_unicast (nc, client,
875 GNUNET_SERVER_receive_done (client, GNUNET_OK);
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);
883 GNUNET_SERVER_notification_context_unicast (nc, c->handle,
884 &resp->header, GNUNET_NO);
886 LOG (GNUNET_ERROR_TYPE_INFO, "Show peer from client %u completed.\n", c->id);
887 GNUNET_SERVER_receive_done (client, GNUNET_OK);
892 * Iterator over all tunnels to send a monitoring client info about each tunnel.
894 * @param cls Closure ().
895 * @param peer Peer ID (tunnel remote peer).
896 * @param value Tunnel info.
898 * @return #GNUNET_YES, to keep iterating.
901 get_all_tunnels_iterator (void *cls,
902 const struct GNUNET_PeerIdentity * peer,
905 struct GNUNET_SERVER_Client *client = cls;
906 struct CadetTunnel *t = value;
907 struct GNUNET_CADET_LocalInfoTunnel msg;
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));
917 LOG (GNUNET_ERROR_TYPE_DEBUG, "sending info about tunnel ->%s\n",
920 GNUNET_SERVER_notification_context_unicast (nc, client,
921 &msg.header, GNUNET_NO);
927 * Handler for client's INFO TUNNELS request.
929 * @param cls Closure (unused).
930 * @param client Identification of the client.
931 * @param message The actual message.
934 handle_get_tunnels (void *cls, struct GNUNET_SERVER_Client *client,
935 const struct GNUNET_MessageHeader *message)
937 struct CadetClient *c;
938 struct GNUNET_MessageHeader reply;
940 /* Sanity check for client registration */
941 if (NULL == (c = GML_client_get (client)))
944 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
948 LOG (GNUNET_ERROR_TYPE_DEBUG,
949 "Received get tunnels request from client %u (%p)\n",
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);
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);
964 iter_connection (void *cls, struct CadetConnection *c)
966 struct GNUNET_CADET_LocalInfoTunnel *msg = cls;
967 struct GNUNET_CADET_ConnectionTunnelIdentifier *h;
969 h = (struct GNUNET_CADET_ConnectionTunnelIdentifier *) &msg[1];
970 h[msg->connections] = *(GCC_get_id (c));
975 iter_channel (void *cls, struct CadetChannel *ch)
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];
981 chn[msg->channels] = GCCH_get_id (ch);
987 * Handler for client's SHOW_TUNNEL request.
989 * @param cls Closure (unused).
990 * @param client Identification of the client.
991 * @param message The actual message.
994 handle_show_tunnel (void *cls, struct GNUNET_SERVER_Client *client,
995 const struct GNUNET_MessageHeader *message)
997 const struct GNUNET_CADET_LocalInfo *msg;
998 struct GNUNET_CADET_LocalInfoTunnel *resp;
999 struct CadetClient *c;
1000 struct CadetTunnel *t;
1005 /* Sanity check for client registration */
1006 if (NULL == (c = GML_client_get (client)))
1009 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
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));
1018 t = GCP_get_tunnel (GCP_get (&msg->peer, GNUNET_NO));
1021 /* We don't know the tunnel */
1022 struct GNUNET_CADET_LocalInfoTunnel warn;
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);
1034 GNUNET_SERVER_notification_context_unicast (nc, client,
1037 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1041 /* Initialize context */
1042 ch_n = GCT_count_channels (t);
1043 c_n = GCT_count_any_connections (t);
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);
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);
1065 LOG (GNUNET_ERROR_TYPE_DEBUG,
1066 "Show tunnel request from client %u completed. %u conn, %u ch\n",
1068 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1073 * Handler for client's INFO_DUMP request.
1075 * @param cls Closure (unused).
1076 * @param client Identification of the client.
1077 * @param message The actual message.
1080 handle_info_dump (void *cls, struct GNUNET_SERVER_Client *client,
1081 const struct GNUNET_MessageHeader *message)
1083 struct CadetClient *c;
1085 /* Sanity check for client registration */
1086 if (NULL == (c = GML_client_get (client)))
1089 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1093 LOG (GNUNET_ERROR_TYPE_INFO, "Received dump info request from client %u\n",
1095 LOG (GNUNET_ERROR_TYPE_ERROR,
1096 "*************************** DUMP START ***************************\n");
1098 for (c = clients_head; NULL != c; c = c->next)
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));
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));
1112 LOG (GNUNET_ERROR_TYPE_ERROR, "***************************\n");
1113 GCP_iterate_all (&show_peer_iterator, NULL);
1115 LOG (GNUNET_ERROR_TYPE_ERROR,
1116 "**************************** DUMP END ****************************\n");
1118 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1123 * Functions to handle messages from clients
1125 static 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)},
1152 /******************************************************************************/
1153 /******************************** API ***********************************/
1154 /******************************************************************************/
1157 * Initialize server subsystem.
1159 * @param handle Server handle.
1162 GML_init (struct GNUNET_SERVER_Handle *handle)
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);
1172 * Install server (service) handlers and start listening to clients.
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,
1181 nc = GNUNET_SERVER_notification_context_create (server_handle, 1);
1183 clients_head = NULL;
1184 clients_tail = NULL;
1186 GNUNET_SERVER_resume (server_handle);
1196 struct CadetClient *c;
1198 LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down local\n");
1200 for (c = clients_head; NULL != clients_head; c = clients_head)
1205 GNUNET_SERVER_notification_context_destroy (nc);
1213 * Get a channel from a client.
1215 * @param c Client to check.
1216 * @param ccn Channel ID, must be local (> 0x800...).
1218 * @return non-NULL if channel exists in the clients lists
1220 struct CadetChannel *
1221 GML_channel_get (struct CadetClient *c,
1222 struct GNUNET_CADET_ClientChannelNumber ccn)
1224 struct GNUNET_CONTAINER_MultiHashMap32 *map;
1226 if (ntohl (ccn.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
1227 map = c->own_channels;
1229 map = c->incoming_channels;
1234 LOG (GNUNET_ERROR_TYPE_DEBUG,
1235 "Client %s does no t have a valid map for CCN %X\n",
1239 return GNUNET_CONTAINER_multihashmap32_get (map,
1240 ccn.channel_of_client);
1245 * Add a channel to a client
1247 * @param client Client.
1248 * @param ccn Channel ID.
1249 * @param ch Channel.
1252 GML_channel_add (struct CadetClient *client,
1253 struct GNUNET_CADET_ClientChannelNumber ccn,
1254 struct CadetChannel *ch)
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,
1260 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
1262 GNUNET_CONTAINER_multihashmap32_put (client->incoming_channels,
1263 ccn.channel_of_client,
1265 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
1270 * Remove a channel from a client.
1272 * @param client Client.
1273 * @param ccn Channel ID.
1274 * @param ch Channel.
1277 GML_channel_remove (struct CadetClient *client,
1278 struct GNUNET_CADET_ClientChannelNumber ccn,
1279 struct CadetChannel *ch)
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,
1286 GNUNET_CONTAINER_multihashmap32_remove (client->incoming_channels,
1287 ccn.channel_of_client,
1293 * Get the tunnel's next free local channel ID.
1297 * @return LID of a channel free to use.
1299 struct GNUNET_CADET_ClientChannelNumber
1300 GML_get_next_ccn (struct CadetClient *c)
1302 struct GNUNET_CADET_ClientChannelNumber ccn;
1304 while (NULL != GML_channel_get (c,
1307 LOG (GNUNET_ERROR_TYPE_DEBUG,
1308 "Channel %u exists...\n",
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);
1317 c->next_ccn.channel_of_client
1318 = htonl (1 + (ntohl (c->next_ccn.channel_of_client)));
1325 * Check if client has registered with the service and has not disconnected
1327 * @param client the client to check
1329 * @return non-NULL if client exists in the global DLL
1331 struct CadetClient *
1332 GML_client_get (struct GNUNET_SERVER_Client *client)
1336 return GNUNET_SERVER_client_get_user_context (client,
1337 struct CadetClient);
1342 * Find a client that has opened a port
1344 * @param port Port to check.
1346 * @return non-NULL if a client has the port.
1348 struct CadetClient *
1349 GML_client_get_by_port (const struct GNUNET_HashCode *port)
1351 return GNUNET_CONTAINER_multihashmap_get (ports, port);
1356 * Deletes a channel from a client (either owner or destination).
1358 * @param c Client whose tunnel to delete.
1359 * @param ch Channel which should be deleted.
1360 * @param id Channel ID.
1363 GML_client_delete_channel (struct CadetClient *c,
1364 struct CadetChannel *ch,
1365 struct GNUNET_CADET_ClientChannelNumber id)
1369 if (ntohl (id.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
1371 res = GNUNET_CONTAINER_multihashmap32_remove (c->own_channels,
1372 id.channel_of_client,
1374 if (GNUNET_YES != res)
1375 LOG (GNUNET_ERROR_TYPE_DEBUG, "client_delete_tunnel root KO\n");
1379 res = GNUNET_CONTAINER_multihashmap32_remove (c->incoming_channels,
1380 id.channel_of_client,
1382 if (GNUNET_YES != res)
1383 LOG (GNUNET_ERROR_TYPE_DEBUG, "client_delete_channel dest KO\n");
1388 * Build a local ACK message and send it to a local client, if needed.
1390 * If the client was already allowed to send data, do nothing.
1392 * @param c Client to whom send the ACK.
1393 * @param ccn Channel ID to use
1396 GML_send_ack (struct CadetClient *c,
1397 struct GNUNET_CADET_ClientChannelNumber ccn)
1399 struct GNUNET_CADET_LocalAck msg;
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
1405 ntohl (ccn.channel_of_client),
1408 msg.header.size = htons (sizeof (msg));
1409 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK);
1411 GNUNET_SERVER_notification_context_unicast (nc,
1421 * Notify the client that a new incoming channel was created.
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.
1430 GML_send_channel_create (struct CadetClient *c,
1431 struct GNUNET_CADET_ClientChannelNumber ccn,
1432 const struct GNUNET_HashCode *port,
1434 const struct GNUNET_PeerIdentity *peer)
1436 struct GNUNET_CADET_LocalChannelCreateMessage msg;
1438 msg.header.size = htons (sizeof (msg));
1439 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE);
1442 msg.opt = htonl (opt);
1444 GNUNET_SERVER_notification_context_unicast (nc, c->handle,
1445 &msg.header, GNUNET_NO);
1450 * Build a local channel NACK message and send it to a local client.
1452 * @param c Client to whom send the NACK.
1453 * @param ccn Channel ID to use
1456 GML_send_channel_nack (struct CadetClient *c,
1457 struct GNUNET_CADET_ClientChannelNumber ccn)
1459 struct GNUNET_CADET_LocalAck msg;
1461 LOG (GNUNET_ERROR_TYPE_DEBUG,
1462 "send local nack on %X towards %p\n",
1463 ntohl (ccn.channel_of_client),
1466 msg.header.size = htons (sizeof (msg));
1467 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_NACK_DEPRECATED);
1469 GNUNET_SERVER_notification_context_unicast (nc,
1477 * Notify a client that a channel is no longer valid.
1480 * @param ccn ID of the channel that is destroyed.
1483 GML_send_channel_destroy (struct CadetClient *c,
1484 struct GNUNET_CADET_ClientChannelNumber ccn)
1486 struct GNUNET_CADET_LocalChannelDestroyMessage msg;
1493 if (GNUNET_YES == c->shutting_down)
1495 msg.header.size = htons (sizeof (msg));
1496 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY);
1498 GNUNET_SERVER_notification_context_unicast (nc, c->handle,
1499 &msg.header, GNUNET_NO);
1504 * Modify the cadet message ID from global to local and send to client.
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).
1511 GML_send_data (struct CadetClient *c,
1512 const struct GNUNET_CADET_ChannelAppDataMessage *msg,
1513 struct GNUNET_CADET_ClientChannelNumber ccn)
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)];
1519 if (size < sizeof (struct GNUNET_MessageHeader))
1521 GNUNET_break_op (0);
1529 copy = (struct GNUNET_CADET_LocalData *) cbuf;
1530 GNUNET_memcpy (©[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);
1534 GNUNET_SERVER_notification_context_unicast (nc, c->handle,
1535 ©->header, GNUNET_NO);
1540 * Get the static string to represent a client.
1544 * @return Static string for the client.
1547 GML_2s (const struct CadetClient *c)
1549 static char buf[32];
1551 SPRINTF (buf, "%u", c->id);