aboutsummaryrefslogtreecommitdiff
path: root/src/dht/gnunet-service-dht_clients.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-04-26 16:56:00 +0000
committerChristian Grothoff <christian@grothoff.org>2012-04-26 16:56:00 +0000
commit4757258de33285fed2aa318c374dcdbf586c29f0 (patch)
tree283fa337cdaa54fbb3bbf08c937fdb6467c2b5d1 /src/dht/gnunet-service-dht_clients.c
parent506d42b2ba6eb104e64fd0c8889ea7233a9b96b3 (diff)
downloadgnunet-4757258de33285fed2aa318c374dcdbf586c29f0.tar.gz
gnunet-4757258de33285fed2aa318c374dcdbf586c29f0.zip
-fixing #2277
Diffstat (limited to 'src/dht/gnunet-service-dht_clients.c')
-rw-r--r--src/dht/gnunet-service-dht_clients.c91
1 files changed, 36 insertions, 55 deletions
diff --git a/src/dht/gnunet-service-dht_clients.c b/src/dht/gnunet-service-dht_clients.c
index f26d77792..9eb1ef497 100644
--- a/src/dht/gnunet-service-dht_clients.c
+++ b/src/dht/gnunet-service-dht_clients.c
@@ -262,6 +262,31 @@ static GNUNET_SCHEDULER_TaskIdentifier retry_task;
262 262
263 263
264/** 264/**
265 * Task run to check for messages that need to be sent to a client.
266 *
267 * @param client a ClientList, containing the client and any messages to be sent to it
268 */
269static void
270process_pending_messages (struct ClientList *client);
271
272
273/**
274 * Add a PendingMessage to the clients list of messages to be sent
275 *
276 * @param client the active client to send the message to
277 * @param pending_message the actual message to send
278 */
279static void
280add_pending_message (struct ClientList *client,
281 struct PendingMessage *pending_message)
282{
283 GNUNET_CONTAINER_DLL_insert_tail (client->pending_head, client->pending_tail,
284 pending_message);
285 process_pending_messages (client);
286}
287
288
289/**
265 * Find a client if it exists, add it otherwise. 290 * Find a client if it exists, add it otherwise.
266 * 291 *
267 * @param client the server handle to the client 292 * @param client the server handle to the client
@@ -304,11 +329,9 @@ remove_client_records (void *cls, const GNUNET_HashCode * key, void *value)
304 329
305 if (record->client != client) 330 if (record->client != client)
306 return GNUNET_YES; 331 return GNUNET_YES;
307#if DEBUG_DHT
308 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 332 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
309 "Removing client %p's record for key %s\n", client, 333 "Removing client %p's record for key %s\n", client,
310 GNUNET_h2s (key)); 334 GNUNET_h2s (key));
311#endif
312 GNUNET_assert (GNUNET_YES == 335 GNUNET_assert (GNUNET_YES ==
313 GNUNET_CONTAINER_multihashmap_remove (forward_map, key, 336 GNUNET_CONTAINER_multihashmap_remove (forward_map, key,
314 record)); 337 record));
@@ -335,9 +358,7 @@ handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
335 struct PendingMessage *reply; 358 struct PendingMessage *reply;
336 struct ClientMonitorRecord *monitor; 359 struct ClientMonitorRecord *monitor;
337 360
338#if DEBUG_DHT
339 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Local client %p disconnects\n", client); 361 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Local client %p disconnects\n", client);
340#endif
341 pos = find_active_client (client); 362 pos = find_active_client (client);
342 GNUNET_CONTAINER_DLL_remove (client_head, client_tail, pos); 363 GNUNET_CONTAINER_DLL_remove (client_head, client_tail, pos);
343 if (pos->transmit_handle != NULL) 364 if (pos->transmit_handle != NULL)
@@ -464,6 +485,8 @@ handle_dht_local_put (void *cls, struct GNUNET_SERVER_Client *client,
464 const struct GNUNET_DHT_ClientPutMessage *dht_msg; 485 const struct GNUNET_DHT_ClientPutMessage *dht_msg;
465 struct GNUNET_CONTAINER_BloomFilter *peer_bf; 486 struct GNUNET_CONTAINER_BloomFilter *peer_bf;
466 uint16_t size; 487 uint16_t size;
488 struct PendingMessage *pm;
489 struct GNUNET_DHT_ClientPutConfirmationMessage *conf;
467 490
468 size = ntohs (message->size); 491 size = ntohs (message->size);
469 if (size < sizeof (struct GNUNET_DHT_ClientPutMessage)) 492 if (size < sizeof (struct GNUNET_DHT_ClientPutMessage))
@@ -478,12 +501,10 @@ handle_dht_local_put (void *cls, struct GNUNET_SERVER_Client *client,
478 GNUNET_NO); 501 GNUNET_NO);
479 dht_msg = (const struct GNUNET_DHT_ClientPutMessage *) message; 502 dht_msg = (const struct GNUNET_DHT_ClientPutMessage *) message;
480 /* give to local clients */ 503 /* give to local clients */
481#if DEBUG_DHT
482 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 504 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
483 "Handling local PUT of %u-bytes for query %s\n", 505 "Handling local PUT of %u-bytes for query %s\n",
484 size - sizeof (struct GNUNET_DHT_ClientPutMessage), 506 size - sizeof (struct GNUNET_DHT_ClientPutMessage),
485 GNUNET_h2s (&dht_msg->key)); 507 GNUNET_h2s (&dht_msg->key));
486#endif
487 GDS_CLIENTS_handle_reply (GNUNET_TIME_absolute_ntoh (dht_msg->expiration), 508 GDS_CLIENTS_handle_reply (GNUNET_TIME_absolute_ntoh (dht_msg->expiration),
488 &dht_msg->key, 0, NULL, 0, NULL, 509 &dht_msg->key, 0, NULL, 0, NULL,
489 ntohl (dht_msg->type), 510 ntohl (dht_msg->type),
@@ -516,6 +537,15 @@ handle_dht_local_put (void *cls, struct GNUNET_SERVER_Client *client,
516 &dht_msg[1], 537 &dht_msg[1],
517 size - sizeof (struct GNUNET_DHT_ClientPutMessage)); 538 size - sizeof (struct GNUNET_DHT_ClientPutMessage));
518 GNUNET_CONTAINER_bloomfilter_free (peer_bf); 539 GNUNET_CONTAINER_bloomfilter_free (peer_bf);
540 pm = GNUNET_malloc (sizeof (struct PendingMessage) +
541 sizeof (struct GNUNET_DHT_ClientPutConfirmationMessage));
542 conf = (struct GNUNET_DHT_ClientPutConfirmationMessage *) &pm[1];
543 conf->header.size = htons (sizeof (struct GNUNET_DHT_ClientPutConfirmationMessage));
544 conf->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_CLIENT_PUT_OK);
545 conf->reserved = htonl (0);
546 conf->unique_id = dht_msg->unique_id;
547 pm->msg = &conf->header;
548 add_pending_message (find_active_client (client), pm);
519 GNUNET_SERVER_receive_done (client, GNUNET_OK); 549 GNUNET_SERVER_receive_done (client, GNUNET_OK);
520} 550}
521 551
@@ -553,11 +583,9 @@ handle_dht_local_get (void *cls, struct GNUNET_SERVER_Client *client,
553 gettext_noop 583 gettext_noop
554 ("# GET requests received from clients"), 1, 584 ("# GET requests received from clients"), 1,
555 GNUNET_NO); 585 GNUNET_NO);
556#if DEBUG_DHT
557 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 586 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
558 "Received request for %s from local client %p\n", 587 "Received request for %s from local client %p\n",
559 GNUNET_h2s (&get->key), client); 588 GNUNET_h2s (&get->key), client);
560#endif
561 cqr = GNUNET_malloc (sizeof (struct ClientQueryRecord) + xquery_size); 589 cqr = GNUNET_malloc (sizeof (struct ClientQueryRecord) + xquery_size);
562 cqr->key = get->key; 590 cqr->key = get->key;
563 cqr->client = find_active_client (client); 591 cqr->client = find_active_client (client);
@@ -625,11 +653,9 @@ remove_by_unique_id (void *cls, const GNUNET_HashCode * key, void *value)
625 653
626 if (record->unique_id != ctx->unique_id) 654 if (record->unique_id != ctx->unique_id)
627 return GNUNET_YES; 655 return GNUNET_YES;
628#if DEBUG_DHT
629 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 656 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
630 "Removing client %p's record for key %s (by unique id)\n", 657 "Removing client %p's record for key %s (by unique id)\n",
631 ctx->client->client_handle, GNUNET_h2s (key)); 658 ctx->client->client_handle, GNUNET_h2s (key));
632#endif
633 return remove_client_records (ctx->client, key, record); 659 return remove_client_records (ctx->client, key, record);
634} 660}
635 661
@@ -655,10 +681,8 @@ handle_dht_local_get_stop (void *cls, struct GNUNET_SERVER_Client *client,
655 gettext_noop 681 gettext_noop
656 ("# GET STOP requests received from clients"), 1, 682 ("# GET STOP requests received from clients"), 1,
657 GNUNET_NO); 683 GNUNET_NO);
658#if DEBUG_DHT
659 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p stopped request for key %s\n", 684 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p stopped request for key %s\n",
660 client, GNUNET_h2s (&dht_stop_msg->key)); 685 client, GNUNET_h2s (&dht_stop_msg->key));
661#endif
662 ctx.client = find_active_client (client); 686 ctx.client = find_active_client (client);
663 ctx.unique_id = dht_stop_msg->unique_id; 687 ctx.unique_id = dht_stop_msg->unique_id;
664 GNUNET_CONTAINER_multihashmap_get_multiple (forward_map, &dht_stop_msg->key, 688 GNUNET_CONTAINER_multihashmap_get_multiple (forward_map, &dht_stop_msg->key,
@@ -708,15 +732,6 @@ handle_dht_local_monitor (void *cls, struct GNUNET_SERVER_Client *client,
708 732
709 733
710/** 734/**
711 * Task run to check for messages that need to be sent to a client.
712 *
713 * @param client a ClientList, containing the client and any messages to be sent to it
714 */
715static void
716process_pending_messages (struct ClientList *client);
717
718
719/**
720 * Callback called as a result of issuing a GNUNET_SERVER_notify_transmit_ready 735 * Callback called as a result of issuing a GNUNET_SERVER_notify_transmit_ready
721 * request. A ClientList is passed as closure, take the head of the list 736 * request. A ClientList is passed as closure, take the head of the list
722 * and copy it into buf, which has the result of sending the message to the 737 * and copy it into buf, which has the result of sending the message to the
@@ -741,11 +756,9 @@ send_reply_to_client (void *cls, size_t size, void *buf)
741 if (buf == NULL) 756 if (buf == NULL)
742 { 757 {
743 /* client disconnected */ 758 /* client disconnected */
744#if DEBUG_DHT
745 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 759 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
746 "Client %p disconnected, pending messages will be discarded\n", 760 "Client %p disconnected, pending messages will be discarded\n",
747 client->client_handle); 761 client->client_handle);
748#endif
749 return 0; 762 return 0;
750 } 763 }
751 off = 0; 764 off = 0;
@@ -756,17 +769,13 @@ send_reply_to_client (void *cls, size_t size, void *buf)
756 reply); 769 reply);
757 memcpy (&cbuf[off], reply->msg, msize); 770 memcpy (&cbuf[off], reply->msg, msize);
758 GNUNET_free (reply); 771 GNUNET_free (reply);
759#if DEBUG_DHT
760 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmitting %u bytes to client %p\n", 772 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmitting %u bytes to client %p\n",
761 msize, client->client_handle); 773 msize, client->client_handle);
762#endif
763 off += msize; 774 off += msize;
764 } 775 }
765 process_pending_messages (client); 776 process_pending_messages (client);
766#if DEBUG_DHT
767 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmitted %u/%u bytes to client %p\n", 777 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmitted %u/%u bytes to client %p\n",
768 (unsigned int) off, (unsigned int) size, client->client_handle); 778 (unsigned int) off, (unsigned int) size, client->client_handle);
769#endif
770 return off; 779 return off;
771} 780}
772 781
@@ -781,20 +790,16 @@ process_pending_messages (struct ClientList *client)
781{ 790{
782 if ((client->pending_head == NULL) || (client->transmit_handle != NULL)) 791 if ((client->pending_head == NULL) || (client->transmit_handle != NULL))
783 { 792 {
784#if DEBUG_DHT
785 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 793 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
786 "Not asking for transmission to %p now: %s\n", 794 "Not asking for transmission to %p now: %s\n",
787 client->client_handle, 795 client->client_handle,
788 client->pending_head == 796 client->pending_head ==
789 NULL ? "no more messages" : "request already pending"); 797 NULL ? "no more messages" : "request already pending");
790#endif
791 return; 798 return;
792 } 799 }
793#if DEBUG_DHT
794 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 800 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
795 "Asking for transmission of %u bytes to client %p\n", 801 "Asking for transmission of %u bytes to client %p\n",
796 ntohs (client->pending_head->msg->size), client->client_handle); 802 ntohs (client->pending_head->msg->size), client->client_handle);
797#endif
798 client->transmit_handle = 803 client->transmit_handle =
799 GNUNET_SERVER_notify_transmit_ready (client->client_handle, 804 GNUNET_SERVER_notify_transmit_ready (client->client_handle,
800 ntohs (client->pending_head-> 805 ntohs (client->pending_head->
@@ -805,22 +810,6 @@ process_pending_messages (struct ClientList *client)
805 810
806 811
807/** 812/**
808 * Add a PendingMessage to the clients list of messages to be sent
809 *
810 * @param client the active client to send the message to
811 * @param pending_message the actual message to send
812 */
813static void
814add_pending_message (struct ClientList *client,
815 struct PendingMessage *pending_message)
816{
817 GNUNET_CONTAINER_DLL_insert_tail (client->pending_head, client->pending_tail,
818 pending_message);
819 process_pending_messages (client);
820}
821
822
823/**
824 * Closure for 'forward_reply' 813 * Closure for 'forward_reply'
825 */ 814 */
826struct ForwardReplyContext 815struct ForwardReplyContext
@@ -879,11 +868,9 @@ forward_reply (void *cls, const GNUNET_HashCode * key, void *value)
879 868
880 if ((record->type != GNUNET_BLOCK_TYPE_ANY) && (record->type != frc->type)) 869 if ((record->type != GNUNET_BLOCK_TYPE_ANY) && (record->type != frc->type))
881 { 870 {
882#if DEBUG_DHT
883 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 871 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
884 "Record type missmatch, not passing request for key %s to local client\n", 872 "Record type missmatch, not passing request for key %s to local client\n",
885 GNUNET_h2s (key)); 873 GNUNET_h2s (key));
886#endif
887 GNUNET_STATISTICS_update (GDS_stats, 874 GNUNET_STATISTICS_update (GDS_stats,
888 gettext_noop 875 gettext_noop
889 ("# Key match, type mismatches in REPLY to CLIENT"), 876 ("# Key match, type mismatches in REPLY to CLIENT"),
@@ -894,11 +881,9 @@ forward_reply (void *cls, const GNUNET_HashCode * key, void *value)
894 for (i = 0; i < record->seen_replies_count; i++) 881 for (i = 0; i < record->seen_replies_count; i++)
895 if (0 == memcmp (&record->seen_replies[i], &ch, sizeof (GNUNET_HashCode))) 882 if (0 == memcmp (&record->seen_replies[i], &ch, sizeof (GNUNET_HashCode)))
896 { 883 {
897#if DEBUG_DHT
898 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 884 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
899 "Duplicate reply, not passing request for key %s to local client\n", 885 "Duplicate reply, not passing request for key %s to local client\n",
900 GNUNET_h2s (key)); 886 GNUNET_h2s (key));
901#endif
902 GNUNET_STATISTICS_update (GDS_stats, 887 GNUNET_STATISTICS_update (GDS_stats,
903 gettext_noop 888 gettext_noop
904 ("# Duplicate REPLIES to CLIENT request dropped"), 889 ("# Duplicate REPLIES to CLIENT request dropped"),
@@ -909,11 +894,9 @@ forward_reply (void *cls, const GNUNET_HashCode * key, void *value)
909 GNUNET_BLOCK_evaluate (GDS_block_context, record->type, key, NULL, 0, 894 GNUNET_BLOCK_evaluate (GDS_block_context, record->type, key, NULL, 0,
910 record->xquery, record->xquery_size, frc->data, 895 record->xquery, record->xquery_size, frc->data,
911 frc->data_size); 896 frc->data_size);
912#if DEBUG_DHT
913 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 897 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
914 "Evaluation result is %d for key %s for local client's query\n", 898 "Evaluation result is %d for key %s for local client's query\n",
915 (int) eval, GNUNET_h2s (key)); 899 (int) eval, GNUNET_h2s (key));
916#endif
917 switch (eval) 900 switch (eval)
918 { 901 {
919 case GNUNET_BLOCK_EVALUATION_OK_LAST: 902 case GNUNET_BLOCK_EVALUATION_OK_LAST:
@@ -964,11 +947,9 @@ forward_reply (void *cls, const GNUNET_HashCode * key, void *value)
964 GNUNET_NO); 947 GNUNET_NO);
965 reply = (struct GNUNET_DHT_ClientResultMessage *) &pm[1]; 948 reply = (struct GNUNET_DHT_ClientResultMessage *) &pm[1];
966 reply->unique_id = record->unique_id; 949 reply->unique_id = record->unique_id;
967#if DEBUG_DHT
968 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 950 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
969 "Queueing reply to query %s for client %p\n", GNUNET_h2s (key), 951 "Queueing reply to query %s for client %p\n", GNUNET_h2s (key),
970 record->client->client_handle); 952 record->client->client_handle);
971#endif
972 add_pending_message (record->client, pm); 953 add_pending_message (record->client, pm);
973 if (GNUNET_YES == do_free) 954 if (GNUNET_YES == do_free)
974 remove_client_records (record->client, key, record); 955 remove_client_records (record->client, key, record);