aboutsummaryrefslogtreecommitdiff
path: root/src/dht/gnunet-service-dht_clients.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-11-10 21:21:01 +0000
committerChristian Grothoff <christian@grothoff.org>2012-11-10 21:21:01 +0000
commit3b2b7374d2d31f7b2638c82711f40f7113e9f7f0 (patch)
tree9dbdac6a4cabe0367bffd864c69c0ac8358a2c45 /src/dht/gnunet-service-dht_clients.c
parent5e756a09598021c6bb22cdbe1b0ac1011679ec0a (diff)
downloadgnunet-3b2b7374d2d31f7b2638c82711f40f7113e9f7f0.tar.gz
gnunet-3b2b7374d2d31f7b2638c82711f40f7113e9f7f0.zip
-implementing #2435
Diffstat (limited to 'src/dht/gnunet-service-dht_clients.c')
-rw-r--r--src/dht/gnunet-service-dht_clients.c103
1 files changed, 100 insertions, 3 deletions
diff --git a/src/dht/gnunet-service-dht_clients.c b/src/dht/gnunet-service-dht_clients.c
index 1d2e1e9bb..593674569 100644
--- a/src/dht/gnunet-service-dht_clients.c
+++ b/src/dht/gnunet-service-dht_clients.c
@@ -551,9 +551,7 @@ handle_dht_local_put (void *cls, struct GNUNET_SERVER_Client *client,
551 551
552 552
553/** 553/**
554 * Handler for any generic DHT messages, calls the appropriate handler 554 * Handler for DHT GET messages from the client.
555 * depending on message type, sends confirmation if responses aren't otherwise
556 * expected.
557 * 555 *
558 * @param cls closure for the service 556 * @param cls closure for the service
559 * @param client the client we received this message from 557 * @param client the client we received this message from
@@ -621,6 +619,103 @@ handle_dht_local_get (void *cls, struct GNUNET_SERVER_Client *client,
621 619
622 620
623/** 621/**
622 * Closure for 'find_by_unique_id'.
623 */
624struct FindByUniqueIdContext
625{
626 /**
627 * Where to store the result, if found.
628 */
629 struct ClientQueryRecord *cqr;
630
631 uint64_t unique_id;
632};
633
634
635/**
636 * Function called for each existing DHT record for the given
637 * query. Checks if it matches the UID given in the closure
638 * and if so returns the entry as a result.
639 *
640 * @param cls the search context
641 * @param key query for the lookup (not used)
642 * @param value the 'struct ClientQueryRecord'
643 * @return GNUNET_YES to continue iteration (result not yet found)
644 */
645static int
646find_by_unique_id (void *cls,
647 const struct GNUNET_HashCode *key,
648 void *value)
649{
650 struct FindByUniqueIdContext *fui_ctx = cls;
651 struct ClientQueryRecord *cqr = value;
652
653 if (cqr->unique_id != fui_ctx->unique_id)
654 return GNUNET_YES;
655 fui_ctx->cqr = cqr;
656 return GNUNET_NO;
657}
658
659
660/**
661 * Handler for "GET result seen" messages from the client.
662 *
663 * @param cls closure for the service
664 * @param client the client we received this message from
665 * @param message the actual message received
666 */
667static void
668handle_dht_local_get_result_seen (void *cls, struct GNUNET_SERVER_Client *client,
669 const struct GNUNET_MessageHeader *message)
670{
671 const struct GNUNET_DHT_ClientGetResultSeenMessage *seen;
672 uint16_t size;
673 unsigned int hash_count;
674 unsigned int old_count;
675 const struct GNUNET_HashCode *hc;
676 struct FindByUniqueIdContext fui_ctx;
677 struct ClientQueryRecord *cqr;
678
679 size = ntohs (message->size);
680 if (size < sizeof (struct GNUNET_DHT_ClientGetResultSeenMessage))
681 {
682 GNUNET_break (0);
683 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
684 return;
685 }
686 seen = (const struct GNUNET_DHT_ClientGetResultSeenMessage *) message;
687 hash_count = (size - sizeof (struct GNUNET_DHT_ClientGetResultSeenMessage)) / sizeof (struct GNUNET_HashCode);
688 if (size != sizeof (struct GNUNET_DHT_ClientGetResultSeenMessage) + hash_count * sizeof (struct GNUNET_HashCode))
689 {
690 GNUNET_break (0);
691 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
692 return;
693 }
694 hc = (const struct GNUNET_HashCode*) &seen[1];
695 fui_ctx.unique_id = seen->unique_id;
696 fui_ctx.cqr = NULL;
697 GNUNET_CONTAINER_multihashmap_get_multiple (forward_map,
698 &seen->key,
699 &find_by_unique_id,
700 &fui_ctx);
701 if (NULL == (cqr = fui_ctx.cqr))
702 {
703 GNUNET_break (0);
704 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
705 return;
706 }
707 /* finally, update 'seen' list */
708 old_count = cqr->seen_replies_count;
709 GNUNET_array_grow (cqr->seen_replies,
710 cqr->seen_replies_count,
711 cqr->seen_replies_count + hash_count);
712 memcpy (&cqr->seen_replies[old_count],
713 hc,
714 sizeof (struct GNUNET_HashCode) * hash_count);
715}
716
717
718/**
624 * Closure for 'remove_by_unique_id'. 719 * Closure for 'remove_by_unique_id'.
625 */ 720 */
626struct RemoveByUniqueIdContext 721struct RemoveByUniqueIdContext
@@ -1350,6 +1445,8 @@ GDS_CLIENTS_init (struct GNUNET_SERVER_Handle *server)
1350 {&handle_dht_local_monitor_stop, NULL, 1445 {&handle_dht_local_monitor_stop, NULL,
1351 GNUNET_MESSAGE_TYPE_DHT_MONITOR_STOP, 1446 GNUNET_MESSAGE_TYPE_DHT_MONITOR_STOP,
1352 sizeof (struct GNUNET_DHT_MonitorStartStopMessage)}, 1447 sizeof (struct GNUNET_DHT_MonitorStartStopMessage)},
1448 {&handle_dht_local_get_result_seen, NULL,
1449 GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_RESULTS_KNOWN, 0},
1353 {NULL, NULL, 0, 0} 1450 {NULL, NULL, 0, 0}
1354 }; 1451 };
1355 forward_map = GNUNET_CONTAINER_multihashmap_create (1024, GNUNET_NO); 1452 forward_map = GNUNET_CONTAINER_multihashmap_create (1024, GNUNET_NO);