aboutsummaryrefslogtreecommitdiff
path: root/src/namestore
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2019-01-10 17:37:54 +0100
committerChristian Grothoff <christian@grothoff.org>2019-01-10 17:37:54 +0100
commit722feeecccf0194b9912a5fff873be087fc65528 (patch)
tree4938b3576052067cfac5936fbf11d84bcf84f768 /src/namestore
parent87a05357dba158dd0ada1e37d5a53d390b2ce122 (diff)
downloadgnunet-722feeecccf0194b9912a5fff873be087fc65528.tar.gz
gnunet-722feeecccf0194b9912a5fff873be087fc65528.zip
try helping rexxnor with flow control
Diffstat (limited to 'src/namestore')
-rw-r--r--src/namestore/gnunet-namestore.c2
-rw-r--r--src/namestore/gnunet-service-namestore.c94
2 files changed, 71 insertions, 25 deletions
diff --git a/src/namestore/gnunet-namestore.c b/src/namestore/gnunet-namestore.c
index 5f5a75f2a..c409cede3 100644
--- a/src/namestore/gnunet-namestore.c
+++ b/src/namestore/gnunet-namestore.c
@@ -1028,7 +1028,7 @@ identity_cb (void *cls,
1028 { 1028 {
1029 fprintf (stderr, 1029 fprintf (stderr,
1030 _("Missing option `%s' for operation `%s'\n"), 1030 _("Missing option `%s' for operation `%s'\n"),
1031 "-n", _("replace")); 1031 "-R", _("replace"));
1032 GNUNET_SCHEDULER_shutdown (); 1032 GNUNET_SCHEDULER_shutdown ();
1033 ret = 1; 1033 ret = 1;
1034 return; 1034 return;
diff --git a/src/namestore/gnunet-service-namestore.c b/src/namestore/gnunet-service-namestore.c
index d9e9a9e82..cc222220f 100644
--- a/src/namestore/gnunet-service-namestore.c
+++ b/src/namestore/gnunet-service-namestore.c
@@ -110,6 +110,19 @@ struct ZoneIteration
110 */ 110 */
111 uint32_t offset; 111 uint32_t offset;
112 112
113 /**
114 * Number of pending cache operations triggered by this zone iteration which we
115 * need to wait for before allowing the client to continue.
116 */
117 unsigned int cache_ops;
118
119 /**
120 * Set to #GNUNET_YES if the last iteration exhausted the limit set by the
121 * client and we should send the #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT_END
122 * message and free the data structure once @e cache_ops is zero.
123 */
124 int send_end;
125
113}; 126};
114 127
115 128
@@ -244,11 +257,17 @@ struct CacheOperation
244 struct GNUNET_NAMECACHE_QueueEntry *qe; 257 struct GNUNET_NAMECACHE_QueueEntry *qe;
245 258
246 /** 259 /**
247 * Client to notify about the result. 260 * Client to notify about the result, can be NULL.
248 */ 261 */
249 struct NamestoreClient *nc; 262 struct NamestoreClient *nc;
250 263
251 /** 264 /**
265 * Zone iteration to call #zone_iteration_done_client_continue()
266 * for if applicable, can be NULL.
267 */
268 struct ZoneIteration *zi;
269
270 /**
252 * Client's request ID. 271 * Client's request ID.
253 */ 272 */
254 uint32_t rid; 273 uint32_t rid;
@@ -831,6 +850,35 @@ send_store_response (struct NamestoreClient *nc,
831 850
832 851
833/** 852/**
853 * Function called once we are done with the zone iteration and
854 * allow the zone iteration client to send us more messages.
855 *
856 * @param zi zone iteration we are processing
857 */
858static void
859zone_iteration_done_client_continue (struct ZoneIteration *zi)
860{
861 struct GNUNET_MQ_Envelope *env;
862 struct GNUNET_NAMESTORE_Header *em;
863
864 GNUNET_SERVICE_client_continue (zi->nc->client);
865 if (! zi->send_end)
866 return;
867 /* send empty response to indicate end of list */
868 env = GNUNET_MQ_msg (em,
869 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT_END);
870 em->r_id = htonl (zi->request_id);
871 GNUNET_MQ_send (zi->nc->mq,
872 env);
873
874 GNUNET_CONTAINER_DLL_remove (zi->nc->op_head,
875 zi->nc->op_tail,
876 zi);
877 GNUNET_free (zi);
878}
879
880
881/**
834 * Cache operation complete, clean up. 882 * Cache operation complete, clean up.
835 * 883 *
836 * @param cls the `struct CacheOperation` 884 * @param cls the `struct CacheOperation`
@@ -843,6 +891,7 @@ finish_cache_operation (void *cls,
843 const char *emsg) 891 const char *emsg)
844{ 892{
845 struct CacheOperation *cop = cls; 893 struct CacheOperation *cop = cls;
894 struct ZoneIteration *zi;
846 895
847 if (NULL != emsg) 896 if (NULL != emsg)
848 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 897 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@@ -858,6 +907,15 @@ finish_cache_operation (void *cls,
858 send_store_response (cop->nc, 907 send_store_response (cop->nc,
859 success, 908 success,
860 cop->rid); 909 cop->rid);
910 if (NULL != (zi = cop->zi))
911 {
912 zi->cache_ops--;
913 if (0 == zi->cache_ops)
914 {
915 /* unchoke zone iteration, cache has caught up */
916 zone_iteration_done_client_continue (zi);
917 }
918 }
861 GNUNET_free (cop); 919 GNUNET_free (cop);
862} 920}
863 921
@@ -867,6 +925,7 @@ finish_cache_operation (void *cls,
867 * refresh the corresponding (encrypted) block in the namecache. 925 * refresh the corresponding (encrypted) block in the namecache.
868 * 926 *
869 * @param nc client responsible for the request, can be NULL 927 * @param nc client responsible for the request, can be NULL
928 * @param zi zone iteration response for the request, can be NULL
870 * @param rid request ID of the client 929 * @param rid request ID of the client
871 * @param zone_key private key of the zone 930 * @param zone_key private key of the zone
872 * @param name label for the records 931 * @param name label for the records
@@ -875,6 +934,7 @@ finish_cache_operation (void *cls,
875 */ 934 */
876static void 935static void
877refresh_block (struct NamestoreClient *nc, 936refresh_block (struct NamestoreClient *nc,
937 struct ZoneIteration *zi,
878 uint32_t rid, 938 uint32_t rid,
879 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, 939 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
880 const char *name, 940 const char *name,
@@ -950,6 +1010,9 @@ refresh_block (struct NamestoreClient *nc,
950 GNUNET_NO); 1010 GNUNET_NO);
951 cop = GNUNET_new (struct CacheOperation); 1011 cop = GNUNET_new (struct CacheOperation);
952 cop->nc = nc; 1012 cop->nc = nc;
1013 cop->zi = zi;
1014 if (NULL != zi)
1015 zi->cache_ops++;
953 cop->rid = rid; 1016 cop->rid = rid;
954 GNUNET_CONTAINER_DLL_insert (cop_head, 1017 GNUNET_CONTAINER_DLL_insert (cop_head,
955 cop_tail, 1018 cop_tail,
@@ -1052,6 +1115,7 @@ continue_store_activity (struct StoreActivity *sa)
1052 } 1115 }
1053 /* great, done with the monitors, unpack (again) for refresh_block operation */ 1116 /* great, done with the monitors, unpack (again) for refresh_block operation */
1054 refresh_block (sa->nc, 1117 refresh_block (sa->nc,
1118 NULL,
1055 rid, 1119 rid,
1056 &rp_msg->private_key, 1120 &rp_msg->private_key,
1057 sa->conv_name, 1121 sa->conv_name,
@@ -1810,8 +1874,9 @@ zone_iterate_proc (void *cls,
1810 do_refresh_block = GNUNET_YES; 1874 do_refresh_block = GNUNET_YES;
1811 break; 1875 break;
1812 } 1876 }
1813 if (GNUNET_YES == do_refresh_block) 1877 if (GNUNET_YES == do_refresh_block)
1814 refresh_block (NULL, 1878 refresh_block (NULL,
1879 proc->zi,
1815 0, 1880 0,
1816 zone_key, 1881 zone_key,
1817 name, 1882 name,
@@ -1831,8 +1896,6 @@ run_zone_iteration_round (struct ZoneIteration *zi,
1831 uint64_t limit) 1896 uint64_t limit)
1832{ 1897{
1833 struct ZoneIterationProcResult proc; 1898 struct ZoneIterationProcResult proc;
1834 struct GNUNET_MQ_Envelope *env;
1835 struct GNUNET_NAMESTORE_Header *em;
1836 struct GNUNET_TIME_Absolute start; 1899 struct GNUNET_TIME_Absolute start;
1837 struct GNUNET_TIME_Relative duration; 1900 struct GNUNET_TIME_Relative duration;
1838 1901
@@ -1865,27 +1928,12 @@ run_zone_iteration_round (struct ZoneIteration *zi,
1865 duration.rel_value_us, 1928 duration.rel_value_us,
1866 GNUNET_NO); 1929 GNUNET_NO);
1867 if (0 == proc.limit) 1930 if (0 == proc.limit)
1868 {
1869 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1931 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1870 "Returned %llu results, more results available\n", 1932 "Returned %llu results, more results available\n",
1871 (unsigned long long) limit); 1933 (unsigned long long) limit);
1872 return; /* more results later after we get the 1934 zi->send_end = (0 != proc.limit);
1873 #GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT message */ 1935 if (0 == zi->cache_ops)
1874 } 1936 zone_iteration_done_client_continue (zi);
1875 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1876 "Completed iteration after %llu/%llu results\n",
1877 (unsigned long long) (limit - proc.limit),
1878 (unsigned long long) limit);
1879 /* send empty response to indicate end of list */
1880 env = GNUNET_MQ_msg (em,
1881 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT_END);
1882 em->r_id = htonl (zi->request_id);
1883 GNUNET_MQ_send (zi->nc->mq,
1884 env);
1885 GNUNET_CONTAINER_DLL_remove (zi->nc->op_head,
1886 zi->nc->op_tail,
1887 zi);
1888 GNUNET_free (zi);
1889} 1937}
1890 1938
1891 1939
@@ -1915,7 +1963,6 @@ handle_iteration_start (void *cls,
1915 zi); 1963 zi);
1916 run_zone_iteration_round (zi, 1964 run_zone_iteration_round (zi,
1917 1); 1965 1);
1918 GNUNET_SERVICE_client_continue (nc->client);
1919} 1966}
1920 1967
1921 1968
@@ -1987,7 +2034,6 @@ handle_iteration_next (void *cls,
1987 } 2034 }
1988 run_zone_iteration_round (zi, 2035 run_zone_iteration_round (zi,
1989 limit); 2036 limit);
1990 GNUNET_SERVICE_client_continue (nc->client);
1991} 2037}
1992 2038
1993 2039