/** * Creates a new cache entry and then puts it into the cache's hashtable. * * @param peer_id the index of the peer to tag the newly created entry * @return the newly created entry */ static struct CacheEntry * add_entry (unsigned int peer_id) { struct CacheEntry *entry; GNUNET_assert (NULL != cache); if (cache_size == GNUNET_CONTAINER_multihashmap32_size (cache)) { /* remove the LRU head */ entry = cache_head; GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap32_remove (cache, (uint32_t) entry->peer_id, entry)); free_entry (entry); } entry = GNUNET_new (struct CacheEntry); entry->peer_id = peer_id; GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap32_put (cache, (uint32_t) peer_id, entry, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)); GNUNET_CONTAINER_DLL_insert_tail (cache_head, cache_tail, entry); return entry; }
/** * Bind incoming channel to this client, and notify client * about incoming connection. * * @param c client to bind to * @param ch channel to be bound * @param dest peer that establishes the connection * @param port port number * @param options options * @return local channel number assigned to the new client */ struct GNUNET_CADET_ClientChannelNumber GSC_bind (struct CadetClient *c, struct CadetChannel *ch, struct CadetPeer *dest, const struct GNUNET_HashCode *port, uint32_t options) { struct GNUNET_MQ_Envelope *env; struct GNUNET_CADET_ChannelCreateMessage *msg; struct GNUNET_CADET_ClientChannelNumber lid; lid = client_get_next_lid (c); GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap32_put (c->incoming_channels, ntohl (lid.channel_of_client), ch, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); /* notify local client about incoming connection! */ env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_CHANNEL_CREATE); msg->channel_id = lid; msg->port = *port; msg->opt = htonl (options); msg->peer = *GCP_get_id (dest); GSC_send_to_client (c, env); return lid; }
struct GCD_search_handle * GCD_search (const struct GNUNET_PeerIdentity *peer_id, GCD_search_callback callback, void *cls) { struct GNUNET_HashCode phash; struct GCD_search_handle *h; LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting DHT GET for peer %s\n", GNUNET_i2s (peer_id)); GNUNET_STATISTICS_update (stats, "# DHT search", 1, GNUNET_NO); memset (&phash, 0, sizeof (phash)); GNUNET_memcpy (&phash, peer_id, sizeof (*peer_id)); h = GNUNET_new (struct GCD_search_handle); h->peer_id = GNUNET_PEER_intern (peer_id); h->callback = callback; h->cls = cls; h->dhtget = GNUNET_DHT_get_start (dht_handle, /* handle */ GNUNET_BLOCK_TYPE_DHT_HELLO, /* type */ &phash, /* key to search */ dht_replication_level, /* replication level */ GNUNET_DHT_RO_RECORD_ROUTE | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, NULL, /* xquery */ 0, /* xquery bits */ &dht_get_id_handler, h); GNUNET_CONTAINER_multihashmap32_put (get_requests, h->peer_id, h, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); return h; }
/** * Insert an RunContextOperation into the rcop_map of the given RunContext * * @param rc the RunContext into whose map is to be used for insertion * @param rcop the RunContextOperation to insert */ static void insert_rcop (struct GNUNET_TESTBED_RunHandle *rc, struct RunContextOperation *rcop) { GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap32_put (rc->rcop_map, rcop_key (rcop->op), rcop, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); }
/** * 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); }
/** * Associate the assoc_data in mq with a unique request id. * * @param mq message queue, id will be unique for the queue * @param assoc_data to associate */ uint32_t GNUNET_MQ_assoc_add (struct GNUNET_MQ_Handle *mq, void *assoc_data) { uint32_t id; if (NULL == mq->assoc_map) { mq->assoc_map = GNUNET_CONTAINER_multihashmap32_create (8); mq->assoc_id = 1; } id = mq->assoc_id++; GNUNET_CONTAINER_multihashmap32_put (mq->assoc_map, id, assoc_data, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); return id; }
/** * 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; }