/** * Iterate over routing table and remove entries with value as part of any trail. * * @param cls closure * @param key current public key * @param value value in the hash map * @return #GNUNET_YES if we should continue to iterate, * #GNUNET_NO if not. */ static int remove_matching_trails (void *cls, const struct GNUNET_HashCode *key, void *value) { struct RoutingTrail *remove_trail = value; struct GNUNET_PeerIdentity *disconnected_peer = cls; struct GNUNET_HashCode trail_id = *key; struct GNUNET_PeerIdentity my_identity; /* If disconnected_peer is next_hop, then send a trail teardown message through * prev_hop in direction from destination to source. */ if (0 == GNUNET_CRYPTO_cmp_peer_identity (&remove_trail->next_hop, disconnected_peer)) { my_identity = *GDS_NEIGHBOURS_get_id (); if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &remove_trail->prev_hop)) { GDS_NEIGHBOURS_send_trail_teardown (&trail_id, GDS_ROUTING_DEST_TO_SRC, &remove_trail->prev_hop); } } /* If disconnected_peer is prev_hop, then send a trail teardown through * next_hop in direction from Source to Destination. */ if (0 == GNUNET_CRYPTO_cmp_peer_identity (&remove_trail->prev_hop, disconnected_peer)) { my_identity = *GDS_NEIGHBOURS_get_id (); if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &remove_trail->next_hop)) { GDS_NEIGHBOURS_send_trail_teardown (&trail_id, GDS_ROUTING_SRC_TO_DEST, &remove_trail->next_hop); } } GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (routing_table, &trail_id, remove_trail)); GNUNET_free (remove_trail); return GNUNET_YES; }
/** * TEST FUNCTION * Remove after using. */ void GDS_ROUTING_test_print (void) { struct GNUNET_CONTAINER_MultiHashMapIterator *iter; struct RoutingTrail *trail; struct GNUNET_PeerIdentity print_peer; struct GNUNET_HashCode key_ret; int i; struct GNUNET_PeerIdentity my_identity = *GDS_NEIGHBOURS_get_id(); print_peer = my_identity; FPRINTF (stderr,_("\nSUPU ***PRINTING ROUTING TABLE ***** of =%s"),GNUNET_i2s(&print_peer)); iter =GNUNET_CONTAINER_multihashmap_iterator_create (routing_table); for (i = 0; i < GNUNET_CONTAINER_multihashmap_size(routing_table); i++) { if(GNUNET_YES == GNUNET_CONTAINER_multihashmap_iterator_next (iter, &key_ret, (const void **)&trail)) { FPRINTF (stderr,_("\nSUPU %s, %s, %d, trail->trail_id = %s"), __FILE__, __func__,__LINE__, GNUNET_h2s(&trail->trail_id)); GNUNET_memcpy (&print_peer, &trail->next_hop, sizeof (struct GNUNET_PeerIdentity)); FPRINTF (stderr,_("\nSUPU %s, %s, %d, trail->next_hop = %s"), __FILE__, __func__,__LINE__, GNUNET_i2s(&print_peer)); GNUNET_memcpy (&print_peer, &trail->prev_hop, sizeof (struct GNUNET_PeerIdentity)); FPRINTF (stderr,_("\nSUPU %s, %s, %d, trail->prev_hop = %s"), __FILE__, __func__,__LINE__, GNUNET_i2s(&print_peer)); } } }
/** * Handler for DHT GET messages from the client. * * @param cls closure for the service * @param client the client we received this message from * @param message the actual message received */ static void handle_dht_local_get (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { const struct GNUNET_DHT_ClientGetMessage *get; struct ClientQueryRecord *cqr; size_t xquery_size; const char *xquery; uint16_t size; size = ntohs (message->size); if (size < sizeof (struct GNUNET_DHT_ClientGetMessage)) { GNUNET_break (0); GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } xquery_size = size - sizeof (struct GNUNET_DHT_ClientGetMessage); get = (const struct GNUNET_DHT_ClientGetMessage *) message; xquery = (const char *) &get[1]; GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# GET requests received from clients"), 1, GNUNET_NO); LOG (GNUNET_ERROR_TYPE_DEBUG, "Received GET request for %s from local client %p, xq: %.*s\n", GNUNET_h2s (&get->key), client, xquery_size, xquery); LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, "XDHT CLIENT-GET %s @ %u\n", GNUNET_h2s (&get->key), getpid ()); cqr = GNUNET_malloc (sizeof (struct ClientQueryRecord) + xquery_size); cqr->key = get->key; cqr->client = find_active_client (client); cqr->xquery = (void *) &cqr[1]; memcpy (&cqr[1], xquery, xquery_size); cqr->hnode = GNUNET_CONTAINER_heap_insert (retry_heap, cqr, 0); cqr->retry_frequency = GNUNET_TIME_UNIT_SECONDS; cqr->retry_time = GNUNET_TIME_absolute_get (); cqr->unique_id = get->unique_id; cqr->xquery_size = xquery_size; cqr->replication = ntohl (get->desired_replication_level); cqr->msg_options = ntohl (get->options); cqr->type = ntohl (get->type); // FIXME use cqr->key, set multihashmap create to GNUNET_YES GNUNET_CONTAINER_multihashmap_put (forward_map, &get->key, cqr, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); GDS_CLIENTS_process_get (ntohl (get->options), ntohl (get->type), 0, ntohl (get->desired_replication_level), 1, GDS_NEIGHBOURS_get_id(), &get->key); /* start remote requests */ if (GNUNET_SCHEDULER_NO_TASK != retry_task) GNUNET_SCHEDULER_cancel (retry_task); retry_task = GNUNET_SCHEDULER_add_now (&transmit_next_request_task, NULL); /* perform local lookup */ GDS_DATACACHE_handle_get (&get->key, cqr->type, cqr->xquery, xquery_size, NULL, 0); GNUNET_SERVER_receive_done (client, GNUNET_OK); }
/** * Handler for PUT messages. * * @param cls closure for the service * @param client the client we received this message from * @param message the actual message received */ static void handle_dht_local_put (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { const struct GNUNET_DHT_ClientPutMessage *dht_msg; struct GNUNET_CONTAINER_BloomFilter *peer_bf; uint16_t size; struct PendingMessage *pm; struct GNUNET_DHT_ClientPutConfirmationMessage *conf; size = ntohs (message->size); if (size < sizeof (struct GNUNET_DHT_ClientPutMessage)) { GNUNET_break (0); GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# PUT requests received from clients"), 1, GNUNET_NO); dht_msg = (const struct GNUNET_DHT_ClientPutMessage *) message; LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, "XDHT CLIENT-PUT %s @ %u\n", GNUNET_h2s (&dht_msg->key), getpid ()); /* give to local clients */ LOG (GNUNET_ERROR_TYPE_DEBUG, "Handling local PUT of %u-bytes for query %s\n", size - sizeof (struct GNUNET_DHT_ClientPutMessage), GNUNET_h2s (&dht_msg->key)); GDS_CLIENTS_handle_reply (GNUNET_TIME_absolute_ntoh (dht_msg->expiration), &dht_msg->key, 0, NULL, 0, NULL, ntohl (dht_msg->type), size - sizeof (struct GNUNET_DHT_ClientPutMessage), &dht_msg[1]); /* store locally */ GDS_DATACACHE_handle_put (GNUNET_TIME_absolute_ntoh (dht_msg->expiration), &dht_msg->key, 0, NULL, ntohl (dht_msg->type), size - sizeof (struct GNUNET_DHT_ClientPutMessage), &dht_msg[1]); /* route to other peers */ peer_bf = GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE, GNUNET_CONSTANTS_BLOOMFILTER_K); GDS_NEIGHBOURS_handle_put (ntohl (dht_msg->type), ntohl (dht_msg->options), ntohl (dht_msg->desired_replication_level), GNUNET_TIME_absolute_ntoh (dht_msg->expiration), 0 /* hop count */ , peer_bf, &dht_msg->key, 0, NULL, &dht_msg[1], size - sizeof (struct GNUNET_DHT_ClientPutMessage)); GDS_CLIENTS_process_put (ntohl (dht_msg->options), ntohl (dht_msg->type), 0, ntohl (dht_msg->desired_replication_level), 1, GDS_NEIGHBOURS_get_id(), GNUNET_TIME_absolute_ntoh (dht_msg->expiration), &dht_msg->key, &dht_msg[1], size - sizeof (struct GNUNET_DHT_ClientPutMessage)); GNUNET_CONTAINER_bloomfilter_free (peer_bf); pm = GNUNET_malloc (sizeof (struct PendingMessage) + sizeof (struct GNUNET_DHT_ClientPutConfirmationMessage)); conf = (struct GNUNET_DHT_ClientPutConfirmationMessage *) &pm[1]; conf->header.size = htons (sizeof (struct GNUNET_DHT_ClientPutConfirmationMessage)); conf->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_CLIENT_PUT_OK); conf->reserved = htonl (0); conf->unique_id = dht_msg->unique_id; pm->msg = &conf->header; add_pending_message (find_active_client (client), pm); GNUNET_SERVER_receive_done (client, GNUNET_OK); }