/** * Handler for requests of deleting tunnels * * @param cls client identification of the client * @param msg the actual message */ static void handle_channel_destroy (void *cls, const struct GNUNET_CADET_ChannelDestroyMessage *msg) { struct CadetClient *c = cls; struct GNUNET_CADET_ClientChannelNumber chid; struct GNUNET_CONTAINER_MultiHashMap32 *map; struct CadetChannel *ch; /* Retrieve tunnel */ chid = msg->channel_id; map = get_map_by_chid (c, chid); ch = GNUNET_CONTAINER_multihashmap32_get (map, ntohl (chid.channel_of_client)); if (NULL == ch) { /* Client attempted to destroy unknown channel */ GNUNET_break (0); GNUNET_SERVICE_client_drop (c->client); return; } LOG (GNUNET_ERROR_TYPE_INFO, "Client %u is destroying channel %s\n", c->id, GCCH_2s (ch)); GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap32_remove (map, ntohl (chid.channel_of_client), ch)); GCCH_channel_local_destroy (ch); GNUNET_SERVICE_client_continue (c->client); }
/** * Handler for client's ACKs for payload traffic. * * @param cls identification of the client. * @param msg The actual message. */ static void handle_ack (void *cls, const struct GNUNET_CADET_LocalAck *msg) { struct CadetClient *c = cls; struct GNUNET_CONTAINER_MultiHashMap32 *map; struct GNUNET_CADET_ClientChannelNumber chid; struct CadetChannel *ch; chid = msg->channel_id; map = get_map_by_chid (c, chid); ch = GNUNET_CONTAINER_multihashmap32_get (map, ntohl (chid.channel_of_client)); if (NULL == ch) { /* Channel does not exist! */ GNUNET_break (0); GNUNET_SERVICE_client_drop (c->client); return; } LOG (GNUNET_ERROR_TYPE_DEBUG, "Got a local ACK from client %u for channel %s\n", c->id, GCCH_2s (ch)); GCCH_handle_local_ack (ch); GNUNET_SERVICE_client_continue (c->client); }
void * GNUNET_MQ_assoc_get (struct GNUNET_MQ_Handle *mq, uint32_t request_id) { if (NULL == mq->assoc_map) return NULL; return GNUNET_CONTAINER_multihashmap32_get (mq->assoc_map, request_id); }
/** * Handler for requests of new channels. * * @param cls Identification of the client. * @param ccm The actual message. */ static void handle_channel_create (void *cls, const struct GNUNET_CADET_ChannelCreateMessage *ccm) { struct CadetClient *c = cls; struct CadetChannel *ch; struct GNUNET_CADET_ClientChannelNumber chid; struct CadetPeer *dst; chid = ccm->channel_id; if (ntohl (chid.channel_of_client) < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI) { /* Channel ID not in allowed range. */ GNUNET_break (0); GNUNET_SERVICE_client_drop (c->client); return; } ch = GNUNET_CONTAINER_multihashmap32_get (c->own_channels, ntohl (chid.channel_of_client)); if (NULL != ch) { /* Channel ID already in use. Not allowed. */ GNUNET_break (0); GNUNET_SERVICE_client_drop (c->client); return; } dst = GCP_get (&ccm->peer, GNUNET_YES); /* Create channel */ ch = GCCH_channel_local_new (c, chid, dst, &ccm->port, ntohl (ccm->opt)); if (NULL == ch) { GNUNET_break (0); GNUNET_SERVICE_client_drop (c->client); return; } GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap32_put (c->own_channels, ntohl (chid.channel_of_client), ch, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); LOG (GNUNET_ERROR_TYPE_DEBUG, "New channel %s to %s at port %s requested by client %u\n", GCCH_2s (ch), GNUNET_i2s (&ccm->peer), GNUNET_h2s (&ccm->port), c->id); GNUNET_SERVICE_client_continue (c->client); }
void * GNUNET_MQ_assoc_remove (struct GNUNET_MQ_Handle *mq, uint32_t request_id) { void *val; if (NULL == mq->assoc_map) return NULL; val = GNUNET_CONTAINER_multihashmap32_get (mq->assoc_map, request_id); GNUNET_CONTAINER_multihashmap32_remove_all (mq->assoc_map, request_id); return val; }
/** * Looks up in the cache and returns the entry * * @param peer_id the peer identity of the peer whose corresponding entry has to * be looked up * @return the HELLO message; NULL if not found */ static struct CacheEntry * cache_lookup (unsigned int peer_id) { struct CacheEntry *entry; GNUNET_assert (NULL != cache); entry = GNUNET_CONTAINER_multihashmap32_get (cache, peer_id); if (NULL == entry) return NULL; GNUNET_CONTAINER_DLL_remove (cache_head, cache_tail, entry); GNUNET_CONTAINER_DLL_insert_tail (cache_head, cache_tail, entry); return entry; }
/** * Obtain the next LID to use for incoming connections to * the given client. * * @param c client handle */ static struct GNUNET_CADET_ClientChannelNumber client_get_next_lid (struct CadetClient *c) { struct GNUNET_CADET_ClientChannelNumber ccn = c->next_chid; /* increment until we have a free one... */ while (NULL != GNUNET_CONTAINER_multihashmap32_get (c->incoming_channels, ntohl (ccn.channel_of_client))) { ccn.channel_of_client = htonl (1 + (ntohl (ccn.channel_of_client))); if (ntohl (ccn.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI) ccn.channel_of_client = htonl (0); } c->next_chid.channel_of_client = htonl (1 + (ntohl (ccn.channel_of_client))); return ccn; }
/** * Add a channel to a tunnel. * * @param t Tunnel. * @param ch Channel * @return unique number identifying @a ch within @a t */ struct GCT_ChannelTunnelNumber GCT_add_channel (struct CadetTunnel *t, struct CadetChannel *ch) { struct GCT_ChannelTunnelNumber ret; uint32_t chid; chid = ntohl (t->next_chid.channel_in_tunnel); while (NULL != GNUNET_CONTAINER_multihashmap32_get (t->channels, chid)) chid++; GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap32_put (t->channels, chid, ch, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); t->next_chid.channel_in_tunnel = htonl (chid + 1); ret.channel_in_tunnel = htonl (chid); return ret; }
/** * Handler for client traffic * * @param cls identification of the client * @param msg the actual message */ static void handle_data (void *cls, const struct GNUNET_CADET_LocalData *msg) { struct CadetClient *c = cls; struct GNUNET_CONTAINER_MultiHashMap32 *map; struct GNUNET_CADET_ClientChannelNumber chid; struct CadetChannel *ch; const struct GNUNET_MessageHeader *payload; chid = msg->id; map = get_map_by_chid (c, chid); ch = GNUNET_CONTAINER_multihashmap32_get (map, ntohl (chid.channel_of_client)); if (NULL == ch) { /* Channel does not exist! */ GNUNET_break (0); GNUNET_SERVICE_client_drop (c->client); return; } payload = (const struct GNUNET_MessageHeader *) &msg[1]; LOG (GNUNET_ERROR_TYPE_DEBUG, "Received %u bytes payload from client %u for channel %s\n", ntohs (payload->size), c->id, GCCH_2s (ch)); if (GNUNET_OK != GCCH_handle_local_data (ch, payload)) { GNUNET_SERVICE_client_drop (c->client); return; } GNUNET_SERVICE_client_continue (c->client); }