aboutsummaryrefslogtreecommitdiff
path: root/src/core/gnunet-service-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/gnunet-service-core.c')
-rw-r--r--src/core/gnunet-service-core.c69
1 files changed, 63 insertions, 6 deletions
diff --git a/src/core/gnunet-service-core.c b/src/core/gnunet-service-core.c
index b0d7b24ba..625bf9655 100644
--- a/src/core/gnunet-service-core.c
+++ b/src/core/gnunet-service-core.c
@@ -32,11 +32,19 @@
32#include "gnunet-service-core_typemap.h" 32#include "gnunet-service-core_typemap.h"
33 33
34/** 34/**
35 * How many messages do we queue up at most for optional 35 * How many messages do we queue up at most for any client? This can
36 * notifications to a client? (this can cause notifications 36 * cause messages to be dropped if clients do not process them fast
37 * about outgoing messages to be dropped). 37 * enough! Note that this is a soft limit; we try
38 * to keep a few larger messages above the limit.
38 */ 39 */
39#define MAX_NOTIFY_QUEUE 1024 40#define SOFT_MAX_QUEUE 128
41
42/**
43 * How many messages do we queue up at most for any client? This can
44 * cause messages to be dropped if clients do not process them fast
45 * enough! Note that this is the hard limit.
46 */
47#define HARD_MAX_QUEUE 256
40 48
41 49
42/** 50/**
@@ -696,6 +704,11 @@ GSC_CLIENTS_notify_client_about_neighbour (struct GSC_Client *client,
696 new_match = GSC_TYPEMAP_test_match (tmap_new, 704 new_match = GSC_TYPEMAP_test_match (tmap_new,
697 client->types, 705 client->types,
698 client->tcnt); 706 client->tcnt);
707 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
708 "Notifying client about neighbour %s (%d/%d)\n",
709 GNUNET_i2s (neighbour),
710 old_match,
711 new_match);
699 if (old_match == new_match) 712 if (old_match == new_match)
700 { 713 {
701 GNUNET_assert (old_match == 714 GNUNET_assert (old_match ==
@@ -720,7 +733,8 @@ GSC_CLIENTS_notify_client_about_neighbour (struct GSC_Client *client,
720 GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT); 733 GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
721 cnm->reserved = htonl (0); 734 cnm->reserved = htonl (0);
722 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 735 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
723 "Sending NOTIFY_CONNECT message to client.\n"); 736 "Sending NOTIFY_CONNECT message about peer %s to client.\n",
737 GNUNET_i2s (neighbour));
724 cnm->peer = *neighbour; 738 cnm->peer = *neighbour;
725 GNUNET_MQ_send (client->mq, 739 GNUNET_MQ_send (client->mq,
726 env); 740 env);
@@ -740,6 +754,9 @@ GSC_CLIENTS_notify_client_about_neighbour (struct GSC_Client *client,
740 env = GNUNET_MQ_msg (dcm, 754 env = GNUNET_MQ_msg (dcm,
741 GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT); 755 GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT);
742 dcm->reserved = htonl (0); 756 dcm->reserved = htonl (0);
757 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
758 "Sending NOTIFY_DISCONNECT message about peer %s to client.\n",
759 GNUNET_i2s (neighbour));
743 dcm->peer = *neighbour; 760 dcm->peer = *neighbour;
744 GNUNET_MQ_send (client->mq, 761 GNUNET_MQ_send (client->mq,
745 env); 762 env);
@@ -790,7 +807,7 @@ GSC_CLIENTS_deliver_message (const struct GNUNET_PeerIdentity *sender,
790{ 807{
791 size_t size = msize + sizeof (struct NotifyTrafficMessage); 808 size_t size = msize + sizeof (struct NotifyTrafficMessage);
792 809
793 if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 810 if (size >= GNUNET_MAX_MESSAGE_SIZE)
794 { 811 {
795 GNUNET_break (0); 812 GNUNET_break (0);
796 return; 813 return;
@@ -810,6 +827,7 @@ GSC_CLIENTS_deliver_message (const struct GNUNET_PeerIdentity *sender,
810 struct GNUNET_MQ_Envelope *env; 827 struct GNUNET_MQ_Envelope *env;
811 struct NotifyTrafficMessage *ntm; 828 struct NotifyTrafficMessage *ntm;
812 uint16_t mtype; 829 uint16_t mtype;
830 unsigned int qlen;
813 int tm; 831 int tm;
814 832
815 tm = type_match (ntohs (msg->type), 833 tm = type_match (ntohs (msg->type),
@@ -825,6 +843,45 @@ GSC_CLIENTS_deliver_message (const struct GNUNET_PeerIdentity *sender,
825 if ( (0 != (options & GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND)) && 843 if ( (0 != (options & GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND)) &&
826 (0 != (c->options & GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND)) ) 844 (0 != (c->options & GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND)) )
827 continue; 845 continue;
846
847 /* Drop messages if:
848 1) We are above the hard limit, or
849 2) We are above the soft limit, and a coin toss limited
850 to the message size (giving larger messages a
851 proportionally higher chance of being queued) falls
852 below the threshold. The threshold is based on where
853 we are between the soft and the hard limit, scaled
854 to match the range of message sizes we usually encounter
855 (i.e. up to 32k); so a 64k message has a 50% chance of
856 being kept if we are just barely below the hard max,
857 and a 99% chance of being kept if we are at the soft max.
858 The reason is to make it more likely to drop control traffic
859 (ACK, queries) which may be cummulative or highly redundant,
860 and cheap to drop than data traffic. */
861 qlen = GNUNET_MQ_get_length (c->mq);
862 if ( (qlen >= HARD_MAX_QUEUE) ||
863 ( (qlen > SOFT_MAX_QUEUE) &&
864 ( (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
865 ntohs (msg->size)) ) <
866 (qlen - SOFT_MAX_QUEUE) * 0x8000 /
867 (HARD_MAX_QUEUE - SOFT_MAX_QUEUE) ) ) )
868 {
869 char buf[1024];
870
871 GNUNET_log (GNUNET_ERROR_TYPE_INFO | GNUNET_ERROR_TYPE_BULK,
872 "Dropping decrypted message of type %u as client is too busy (queue full)\n",
873 (unsigned int) ntohs (msg->type));
874 GNUNET_snprintf (buf,
875 sizeof (buf),
876 gettext_noop ("# messages of type %u discarded (client busy)"),
877 (unsigned int) ntohs (msg->type));
878 GNUNET_STATISTICS_update (GSC_stats,
879 buf,
880 1,
881 GNUNET_NO);
882 continue;
883 }
884
828 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 885 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
829 "Sending %u message with %u bytes to client interested in messages of type %u.\n", 886 "Sending %u message with %u bytes to client interested in messages of type %u.\n",
830 options, 887 options,