diff options
Diffstat (limited to 'src/core/gnunet-service-core.c')
-rw-r--r-- | src/core/gnunet-service-core.c | 69 |
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, |