aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2019-04-15 11:32:51 +0200
committerChristian Grothoff <christian@grothoff.org>2019-04-15 11:34:42 +0200
commit6e7793d8d8018baeb85fb661e1ee58251b61bf9a (patch)
treeb5cce84fbee99f8df6dc8116209b77bff6dfddce
parent45a04d9f5558f666c01f7fd0844be964bf610c9a (diff)
downloadgnunet-6e7793d8d8018baeb85fb661e1ee58251b61bf9a.tar.gz
gnunet-6e7793d8d8018baeb85fb661e1ee58251b61bf9a.zip
misc work on TNG
-rw-r--r--src/include/gnunet_time_lib.h10
-rw-r--r--src/transport/gnunet-service-tng.c299
-rw-r--r--src/util/scheduler.c2
-rw-r--r--src/util/time.c100
4 files changed, 366 insertions, 45 deletions
diff --git a/src/include/gnunet_time_lib.h b/src/include/gnunet_time_lib.h
index 482ae52d8..d0da267a9 100644
--- a/src/include/gnunet_time_lib.h
+++ b/src/include/gnunet_time_lib.h
@@ -190,6 +190,16 @@ GNUNET_TIME_randomized_backoff(struct GNUNET_TIME_Relative rt, struct GNUNET_TIM
190 190
191 191
192/** 192/**
193 * Return a random time value between 0.5*r and 1.5*r.
194 *
195 * @param r input time for scaling
196 * @return randomized time
197 */
198struct GNUNET_TIME_Relative
199GNUNET_TIME_randomize(struct GNUNET_TIME_Relative r);
200
201
202/**
193 * Return relative time of 0ms. 203 * Return relative time of 0ms.
194 */ 204 */
195struct GNUNET_TIME_Relative 205struct GNUNET_TIME_Relative
diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c
index 2dd68bcc8..568e5b1d7 100644
--- a/src/transport/gnunet-service-tng.c
+++ b/src/transport/gnunet-service-tng.c
@@ -115,6 +115,12 @@
115#define MAX_DV_HOPS_ALLOWED 16 115#define MAX_DV_HOPS_ALLOWED 16
116 116
117/** 117/**
118 * Maximum number of DV learning activities we may
119 * have pending at the same time.
120 */
121#define MAX_DV_LEARN_PENDING 64
122
123/**
118 * Maximum number of DV paths we keep simultaneously to the same target. 124 * Maximum number of DV paths we keep simultaneously to the same target.
119 */ 125 */
120#define MAX_DV_PATHS_TO_TARGET 3 126#define MAX_DV_PATHS_TO_TARGET 3
@@ -127,6 +133,13 @@
127#define DELAY_WARN_THRESHOLD GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) 133#define DELAY_WARN_THRESHOLD GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
128 134
129/** 135/**
136 * We only consider queues as "quality" connections when
137 * suppressing the generation of DV initiation messages if
138 * the latency of the queue is below this threshold.
139 */
140#define DV_QUALITY_RTT_THRESHOLD GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1)
141
142/**
130 * How long do we consider a DV path valid if we see no 143 * How long do we consider a DV path valid if we see no
131 * further updates on it? Note: the value chosen here might be too low! 144 * further updates on it? Note: the value chosen here might be too low!
132 */ 145 */
@@ -160,6 +173,18 @@
160#define MAX_VALIDATION_CHALLENGE_FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_DAYS, 1) 173#define MAX_VALIDATION_CHALLENGE_FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_DAYS, 1)
161 174
162/** 175/**
176 * What is the non-randomized base frequency at which we
177 * would initiate DV learn messages?
178 */
179#define DV_LEARN_BASE_FREQUENCY GNUNET_TIME_UNIT_MINUTES
180
181/**
182 * How many good connections (confirmed, bi-directional, not DV)
183 * do we need to have to suppress initiating DV learn messages?
184 */
185#define DV_LEARN_QUALITY_THRESHOLD 100
186
187/**
163 * When do we forget an invalid address for sure? 188 * When do we forget an invalid address for sure?
164 */ 189 */
165#define MAX_ADDRESS_VALID_UNTIL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MONTHS, 1) 190#define MAX_ADDRESS_VALID_UNTIL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MONTHS, 1)
@@ -792,6 +817,36 @@ enum ClientType
792 817
793 818
794/** 819/**
820 * When did we launch this DV learning activity?
821 */
822struct LearnLaunchEntry
823{
824
825 /**
826 * Kept (also) in a DLL sorted by launch time.
827 */
828 struct LearnLaunchEntry *prev;
829
830 /**
831 * Kept (also) in a DLL sorted by launch time.
832 */
833 struct LearnLaunchEntry *next;
834
835 /**
836 * Challenge that uniquely identifies this activity.
837 */
838 struct GNUNET_ShortHashCode challenge;
839
840 /**
841 * When did we transmit the DV learn message (used to
842 * calculate RTT).
843 */
844 struct GNUNET_TIME_Absolute launch_time;
845
846};
847
848
849/**
795 * Entry in our cache of ephemeral keys we currently use. 850 * Entry in our cache of ephemeral keys we currently use.
796 * This way, we only sign an ephemeral once per @e target, 851 * This way, we only sign an ephemeral once per @e target,
797 * and then can re-use it over multiple 852 * and then can re-use it over multiple
@@ -1060,6 +1115,7 @@ struct Queue
1060 1115
1061 /** 1116 /**
1062 * Distance to the target of this queue. 1117 * Distance to the target of this queue.
1118 * FIXME: needed? DV is done differently these days...
1063 */ 1119 */
1064 uint32_t distance; 1120 uint32_t distance;
1065 1121
@@ -1814,6 +1870,21 @@ static struct GNUNET_CONTAINER_MultiPeerMap *dv_routes;
1814static struct GNUNET_CONTAINER_MultiPeerMap *validation_map; 1870static struct GNUNET_CONTAINER_MultiPeerMap *validation_map;
1815 1871
1816/** 1872/**
1873 * Map from challenges to `struct LearnLaunchEntry` values.
1874 */
1875static struct GNUNET_CONTAINER_MultiShortmap *dvlearn_map;
1876
1877/**
1878 * Head of a DLL sorted by launch time.
1879 */
1880static struct LearnLaunchEntry *lle_head;
1881
1882/**
1883 * Tail of a DLL sorted by launch time.
1884 */
1885static struct LearnLaunchEntry *lle_tail;
1886
1887/**
1817 * MIN Heap sorted by "next_challenge" to `struct ValidationState` entries 1888 * MIN Heap sorted by "next_challenge" to `struct ValidationState` entries
1818 * sorting addresses we are aware of by when we should next try to (re)validate 1889 * sorting addresses we are aware of by when we should next try to (re)validate
1819 * (or expire) them. 1890 * (or expire) them.
@@ -1846,6 +1917,11 @@ static struct GNUNET_CONTAINER_MultiPeerMap *ephemeral_map;
1846static struct GNUNET_SCHEDULER_Task *ephemeral_task; 1917static struct GNUNET_SCHEDULER_Task *ephemeral_task;
1847 1918
1848/** 1919/**
1920 * Task run to initiate DV learning.
1921 */
1922static struct GNUNET_SCHEDULER_Task *dvlearn_task;
1923
1924/**
1849 * Task to run address validation. 1925 * Task to run address validation.
1850 */ 1926 */
1851static struct GNUNET_SCHEDULER_Task *validation_task; 1927static struct GNUNET_SCHEDULER_Task *validation_task;
@@ -2088,6 +2164,7 @@ client_connect_cb (void *cls,
2088{ 2164{
2089 struct TransportClient *tc; 2165 struct TransportClient *tc;
2090 2166
2167 (void) cls;
2091 tc = GNUNET_new (struct TransportClient); 2168 tc = GNUNET_new (struct TransportClient);
2092 tc->client = client; 2169 tc->client = client;
2093 tc->mq = mq; 2170 tc->mq = mq;
@@ -2501,6 +2578,7 @@ client_disconnect_cb (void *cls,
2501{ 2578{
2502 struct TransportClient *tc = app_ctx; 2579 struct TransportClient *tc = app_ctx;
2503 2580
2581 (void) cls;
2504 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2582 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2505 "Client %p disconnected, cleaning up.\n", 2583 "Client %p disconnected, cleaning up.\n",
2506 tc); 2584 tc);
@@ -2732,7 +2810,7 @@ client_send_response (struct PendingMessage *pm,
2732 som->bytes_physical = htonl (bytes_physical); 2810 som->bytes_physical = htonl (bytes_physical);
2733 som->peer = target->pid; 2811 som->peer = target->pid;
2734 GNUNET_MQ_send (tc->mq, 2812 GNUNET_MQ_send (tc->mq,
2735 env); 2813 env);
2736 } 2814 }
2737 free_pending_message (pm); 2815 free_pending_message (pm);
2738} 2816}
@@ -2935,6 +3013,7 @@ check_communicator_backchannel (void *cls,
2935 uint16_t msize; 3013 uint16_t msize;
2936 uint16_t isize; 3014 uint16_t isize;
2937 3015
3016 (void) cls;
2938 msize = ntohs (cb->header.size) - sizeof (*cb); 3017 msize = ntohs (cb->header.size) - sizeof (*cb);
2939 if (UINT16_MAX - msize > 3018 if (UINT16_MAX - msize >
2940 sizeof (struct TransportBackchannelEncapsulationMessage) + 3019 sizeof (struct TransportBackchannelEncapsulationMessage) +
@@ -3761,6 +3840,7 @@ check_backchannel_encapsulation (void *cls,
3761{ 3840{
3762 uint16_t size = ntohs (be->header.size); 3841 uint16_t size = ntohs (be->header.size);
3763 3842
3843 (void) cls;
3764 if (size - sizeof (*be) < sizeof (struct GNUNET_MessageHeader)) 3844 if (size - sizeof (*be) < sizeof (struct GNUNET_MessageHeader))
3765 { 3845 {
3766 GNUNET_break_op (0); 3846 GNUNET_break_op (0);
@@ -4012,6 +4092,7 @@ check_dv_learn (void *cls,
4012 uint16_t num_hops = ntohs (dvl->num_hops); 4092 uint16_t num_hops = ntohs (dvl->num_hops);
4013 const struct DVPathEntryP *hops = (const struct DVPathEntryP *) &dvl[1]; 4093 const struct DVPathEntryP *hops = (const struct DVPathEntryP *) &dvl[1];
4014 4094
4095 (void) cls;
4015 if (size != sizeof (*dvl) + num_hops * sizeof (struct DVPathEntryP)) 4096 if (size != sizeof (*dvl) + num_hops * sizeof (struct DVPathEntryP))
4016 { 4097 {
4017 GNUNET_break_op (0); 4098 GNUNET_break_op (0);
@@ -4280,7 +4361,7 @@ handle_dv_learn (void *cls,
4280 break; 4361 break;
4281 } 4362 }
4282 if ( (GNUNET_NO == iret) && 4363 if ( (GNUNET_NO == iret) &&
4283 (nhops - 1 == i) ) 4364 (nhops == i + 1) )
4284 { 4365 {
4285 /* we have better paths, and this is the longest target, 4366 /* we have better paths, and this is the longest target,
4286 so there cannot be anything interesting later */ 4367 so there cannot be anything interesting later */
@@ -4359,6 +4440,7 @@ check_dv_box (void *cls,
4359 uint16_t isize; 4440 uint16_t isize;
4360 uint16_t itype; 4441 uint16_t itype;
4361 4442
4443 (void) cls;
4362 if (size < sizeof (*dvb) + num_hops * sizeof (struct GNUNET_PeerIdentity) + sizeof (struct GNUNET_MessageHeader)) 4444 if (size < sizeof (*dvb) + num_hops * sizeof (struct GNUNET_PeerIdentity) + sizeof (struct GNUNET_MessageHeader))
4363 { 4445 {
4364 GNUNET_break_op (0); 4446 GNUNET_break_op (0);
@@ -5239,6 +5321,8 @@ tracker_update_out_cb (void *cls)
5239static void 5321static void
5240tracker_excess_out_cb (void *cls) 5322tracker_excess_out_cb (void *cls)
5241{ 5323{
5324 (void) cls;
5325
5242 /* FIXME: trigger excess bandwidth report to core? Right now, 5326 /* FIXME: trigger excess bandwidth report to core? Right now,
5243 this is done internally within transport_api2_core already, 5327 this is done internally within transport_api2_core already,
5244 but we probably want to change the logic and trigger it 5328 but we probably want to change the logic and trigger it
@@ -5261,6 +5345,8 @@ tracker_excess_out_cb (void *cls)
5261static void 5345static void
5262tracker_excess_in_cb (void *cls) 5346tracker_excess_in_cb (void *cls)
5263{ 5347{
5348 (void) cls;
5349
5264 /* TODO: maybe inform somone at this point? */ 5350 /* TODO: maybe inform somone at this point? */
5265 GNUNET_STATISTICS_update (GST_stats, 5351 GNUNET_STATISTICS_update (GST_stats,
5266 "# Excess inbound bandwidth reported", 5352 "# Excess inbound bandwidth reported",
@@ -5560,6 +5646,8 @@ validation_transmit_on_queue (struct Queue *q,
5560 tvc->reserved = htonl (0); 5646 tvc->reserved = htonl (0);
5561 tvc->challenge = vs->challenge; 5647 tvc->challenge = vs->challenge;
5562 tvc->sender_time = GNUNET_TIME_absolute_hton (vs->last_challenge_use); 5648 tvc->sender_time = GNUNET_TIME_absolute_hton (vs->last_challenge_use);
5649 // FIXME: not so easy, need to BOX this message
5650 // in a transmission request! (mistake also done elsewhere!)
5563 GNUNET_MQ_send (q->tc->mq, 5651 GNUNET_MQ_send (q->tc->mq,
5564 env); 5652 env);
5565} 5653}
@@ -5625,6 +5713,193 @@ validation_start_cb (void *cls)
5625 5713
5626 5714
5627/** 5715/**
5716 * Closure for #check_connection_quality.
5717 */
5718struct QueueQualityContext
5719{
5720 /**
5721 * Set to the @e k'th queue encountered.
5722 */
5723 struct Queue *q;
5724
5725 /**
5726 * Set to the number of quality queues encountered.
5727 */
5728 unsigned int quality_count;
5729
5730 /**
5731 * Set to the total number of queues encountered.
5732 */
5733 unsigned int num_queues;
5734
5735 /**
5736 * Decremented for each queue, for selection of the
5737 * k-th queue in @e q.
5738 */
5739 unsigned int k;
5740
5741};
5742
5743
5744/**
5745 * Check whether any queue to the given neighbour is
5746 * of a good "quality" and if so, increment the counter.
5747 * Also counts the total number of queues, and returns
5748 * the k-th queue found.
5749 *
5750 * @param cls a `struct QueueQualityContext *` with counters
5751 * @param pid peer this is about
5752 * @param value a `struct Neighbour`
5753 * @return #GNUNET_OK (continue to iterate)
5754 */
5755static int
5756check_connection_quality (void *cls,
5757 const struct GNUNET_PeerIdentity *pid,
5758 void *value)
5759{
5760 struct QueueQualityContext *ctx = cls;
5761 struct Neighbour *n = value;
5762 int do_inc;
5763
5764 (void) pid;
5765 do_inc = GNUNET_NO;
5766 for (struct Queue *q = n->queue_head;
5767 NULL != q;
5768 q = q->next_neighbour)
5769 {
5770 if (0 != q->distance)
5771 continue; /* DV does not count */
5772 ctx->num_queues++;
5773 if (0 == ctx->k--)
5774 ctx->q = q;
5775 /* OPTIMIZE-FIXME: in the future, add reliability / goodput
5776 statistics and consider those as well here? */
5777 if (q->rtt.rel_value_us < DV_QUALITY_RTT_THRESHOLD.rel_value_us)
5778 do_inc = GNUNET_YES;
5779 }
5780 if (GNUNET_YES == do_inc)
5781 ctx->quality_count++;
5782 return GNUNET_OK;
5783}
5784
5785
5786/**
5787 * Task run when we CONSIDER initiating a DV learn
5788 * process. We first check that sending out a message is
5789 * even possible (queues exist), then that it is desirable
5790 * (if not, reschedule the task for later), and finally
5791 * we may then begin the job. If there are too many
5792 * entries in the #dvlearn_map, we purge the oldest entry
5793 * using #lle_tail.
5794 *
5795 * @param cls NULL
5796 */
5797static void
5798start_dv_learn (void *cls)
5799{
5800 struct LearnLaunchEntry *lle;
5801 struct QueueQualityContext qqc;
5802 struct GNUNET_MQ_Envelope *env;
5803 struct TransportDVLearn *dvl;
5804
5805 (void) cls;
5806 dvlearn_task = NULL;
5807 if (0 ==
5808 GNUNET_CONTAINER_multipeermap_size (neighbours))
5809 return; /* lost all connectivity, cannot do learning */
5810 qqc.quality_count = 0;
5811 qqc.num_queues = 0;
5812 GNUNET_CONTAINER_multipeermap_iterate (neighbours,
5813 &check_connection_quality,
5814 &qqc);
5815 if (qqc.quality_count > DV_LEARN_QUALITY_THRESHOLD)
5816 {
5817 struct GNUNET_TIME_Relative delay;
5818 unsigned int factor;
5819
5820 /* scale our retries by how far we are above the threshold */
5821 factor = qqc.quality_count / DV_LEARN_QUALITY_THRESHOLD;
5822 delay = GNUNET_TIME_relative_multiply (DV_LEARN_BASE_FREQUENCY,
5823 factor);
5824 dvlearn_task = GNUNET_SCHEDULER_add_delayed (delay,
5825 &start_dv_learn,
5826 NULL);
5827 return;
5828 }
5829 /* remove old entries in #dvlearn_map if it has grown too big */
5830 while (MAX_DV_LEARN_PENDING >=
5831 GNUNET_CONTAINER_multishortmap_size (dvlearn_map))
5832 {
5833 lle = lle_tail;
5834 GNUNET_assert (GNUNET_YES ==
5835 GNUNET_CONTAINER_multishortmap_remove (dvlearn_map,
5836 &lle->challenge,
5837 lle));
5838 GNUNET_CONTAINER_DLL_remove (lle_head,
5839 lle_tail,
5840 lle);
5841 GNUNET_free (lle);
5842 }
5843 /* setup data structure for learning */
5844 lle = GNUNET_new (struct LearnLaunchEntry);
5845 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
5846 &lle->challenge,
5847 sizeof (lle->challenge));
5848 GNUNET_CONTAINER_DLL_insert (lle_head,
5849 lle_tail,
5850 lle);
5851 GNUNET_break (GNUNET_YES ==
5852 GNUNET_CONTAINER_multishortmap_put (dvlearn_map,
5853 &lle->challenge,
5854 lle,
5855 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
5856 env = GNUNET_MQ_msg (dvl,
5857 GNUNET_MESSAGE_TYPE_TRANSPORT_DV_LEARN);
5858 dvl->num_hops = htons (0);
5859 dvl->bidirectional = htons (0);
5860 dvl->non_network_delay = GNUNET_TIME_relative_hton (GNUNET_TIME_UNIT_ZERO);
5861 {
5862 struct DvInitPS dvip = {
5863 .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_INITIATOR),
5864 .purpose.size = htonl (sizeof (dvip)),
5865 .challenge = lle->challenge
5866 };
5867
5868 GNUNET_assert (GNUNET_OK ==
5869 GNUNET_CRYPTO_eddsa_sign (GST_my_private_key,
5870 &dvip.purpose,
5871 &dvl->init_sig));
5872 }
5873 dvl->initiator = GST_my_identity;
5874 dvl->challenge = lle->challenge;
5875
5876 qqc.quality_count = 0;
5877 qqc.k = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
5878 qqc.num_queues);
5879 qqc.num_queues = 0;
5880 qqc.q = NULL;
5881 GNUNET_CONTAINER_multipeermap_iterate (neighbours,
5882 &check_connection_quality,
5883 &qqc);
5884 GNUNET_assert (NULL != qqc.q);
5885
5886 /* Do this as close to transmission time as possible! */
5887 lle->launch_time = GNUNET_TIME_absolute_get ();
5888 // FIXME: not so easy, need to BOX this message
5889 // in a transmission request! (mistake also done elsewhere!)
5890 GNUNET_MQ_send (qqc.q->tc->mq,
5891 env);
5892
5893 /* reschedule this job, randomizing the time it runs (but no
5894 actual backoff!) */
5895 dvlearn_task
5896 = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_randomize (DV_LEARN_BASE_FREQUENCY),
5897 &start_dv_learn,
5898 NULL);
5899}
5900
5901
5902/**
5628 * A new queue has been created, check if any address validation 5903 * A new queue has been created, check if any address validation
5629 * requests have been waiting for it. 5904 * requests have been waiting for it.
5630 * 5905 *
@@ -5747,6 +6022,10 @@ handle_add_queue_message (void *cls,
5747 &aqm->receiver, 6022 &aqm->receiver,
5748 &check_validation_request_pending, 6023 &check_validation_request_pending,
5749 queue); 6024 queue);
6025 /* might be our first queue, try launching DV learning */
6026 if (NULL == dvlearn_task)
6027 dvlearn_task = GNUNET_SCHEDULER_add_now (&start_dv_learn,
6028 NULL);
5750 GNUNET_SERVICE_client_continue (tc->client); 6029 GNUNET_SERVICE_client_continue (tc->client);
5751} 6030}
5752 6031
@@ -6109,6 +6388,7 @@ static int
6109check_request_hello_validation (void *cls, 6388check_request_hello_validation (void *cls,
6110 const struct RequestHelloValidationMessage *m) 6389 const struct RequestHelloValidationMessage *m)
6111{ 6390{
6391 (void) cls;
6112 GNUNET_MQ_check_zero_termination (m); 6392 GNUNET_MQ_check_zero_termination (m);
6113 return GNUNET_OK; 6393 return GNUNET_OK;
6114} 6394}
@@ -6234,6 +6514,7 @@ free_validation_state_cb (void *cls,
6234static void 6514static void
6235do_shutdown (void *cls) 6515do_shutdown (void *cls)
6236{ 6516{
6517 struct LearnLaunchEntry *lle;
6237 (void) cls; 6518 (void) cls;
6238 6519
6239 if (NULL != ephemeral_task) 6520 if (NULL != ephemeral_task)
@@ -6268,6 +6549,15 @@ do_shutdown (void *cls)
6268 NULL); 6549 NULL);
6269 GNUNET_CONTAINER_multipeermap_destroy (validation_map); 6550 GNUNET_CONTAINER_multipeermap_destroy (validation_map);
6270 validation_map = NULL; 6551 validation_map = NULL;
6552 while (NULL != (lle = lle_head))
6553 {
6554 GNUNET_CONTAINER_DLL_remove (lle_head,
6555 lle_tail,
6556 lle);
6557 GNUNET_free (lle);
6558 }
6559 GNUNET_CONTAINER_multishortmap_destroy (dvlearn_map);
6560 dvlearn_map = NULL;
6271 GNUNET_CONTAINER_heap_destroy (validation_heap); 6561 GNUNET_CONTAINER_heap_destroy (validation_heap);
6272 validation_heap = NULL; 6562 validation_heap = NULL;
6273 GNUNET_CONTAINER_multipeermap_iterate (dv_routes, 6563 GNUNET_CONTAINER_multipeermap_iterate (dv_routes,
@@ -6298,6 +6588,7 @@ run (void *cls,
6298 struct GNUNET_SERVICE_Handle *service) 6588 struct GNUNET_SERVICE_Handle *service)
6299{ 6589{
6300 (void) cls; 6590 (void) cls;
6591 (void) service;
6301 /* setup globals */ 6592 /* setup globals */
6302 GST_cfg = c; 6593 GST_cfg = c;
6303 neighbours = GNUNET_CONTAINER_multipeermap_create (1024, 6594 neighbours = GNUNET_CONTAINER_multipeermap_create (1024,
@@ -6307,6 +6598,8 @@ run (void *cls,
6307 ephemeral_map = GNUNET_CONTAINER_multipeermap_create (32, 6598 ephemeral_map = GNUNET_CONTAINER_multipeermap_create (32,
6308 GNUNET_YES); 6599 GNUNET_YES);
6309 ephemeral_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); 6600 ephemeral_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
6601 dvlearn_map = GNUNET_CONTAINER_multishortmap_create (2 * MAX_DV_LEARN_PENDING,
6602 GNUNET_YES);
6310 validation_map = GNUNET_CONTAINER_multipeermap_create (1024, 6603 validation_map = GNUNET_CONTAINER_multipeermap_create (1024,
6311 GNUNET_YES); 6604 GNUNET_YES);
6312 validation_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); 6605 validation_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
@@ -6326,7 +6619,7 @@ run (void *cls,
6326 GST_stats = GNUNET_STATISTICS_create ("transport", 6619 GST_stats = GNUNET_STATISTICS_create ("transport",
6327 GST_cfg); 6620 GST_cfg);
6328 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, 6621 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
6329 NULL); 6622 NULL);
6330 peerstore = GNUNET_PEERSTORE_connect (GST_cfg); 6623 peerstore = GNUNET_PEERSTORE_connect (GST_cfg);
6331 if (NULL == peerstore) 6624 if (NULL == peerstore)
6332 { 6625 {
diff --git a/src/util/scheduler.c b/src/util/scheduler.c
index 3bd7ccec7..2ddbb8c60 100644
--- a/src/util/scheduler.c
+++ b/src/util/scheduler.c
@@ -915,6 +915,7 @@ driver_add_multiple (struct GNUNET_SCHEDULER_Task *t)
915static void 915static void
916install_parent_control_handler (void *cls) 916install_parent_control_handler (void *cls)
917{ 917{
918 (void) cls;
918 install_parent_control_task = NULL; 919 install_parent_control_task = NULL;
919 GNUNET_OS_install_parent_control_handler (NULL); 920 GNUNET_OS_install_parent_control_handler (NULL);
920} 921}
@@ -926,6 +927,7 @@ shutdown_pipe_cb (void *cls)
926 char c; 927 char c;
927 const struct GNUNET_DISK_FileHandle *pr; 928 const struct GNUNET_DISK_FileHandle *pr;
928 929
930 (void) cls;
929 shutdown_pipe_task = NULL; 931 shutdown_pipe_task = NULL;
930 pr = GNUNET_DISK_pipe_handle (shutdown_pipe_handle, 932 pr = GNUNET_DISK_pipe_handle (shutdown_pipe_handle,
931 GNUNET_DISK_PIPE_END_READ); 933 GNUNET_DISK_PIPE_END_READ);
diff --git a/src/util/time.c b/src/util/time.c
index 799c6cc63..758921718 100644
--- a/src/util/time.c
+++ b/src/util/time.c
@@ -770,6 +770,22 @@ GNUNET_TIME_randomized_backoff(struct GNUNET_TIME_Relative rt, struct GNUNET_TIM
770 770
771 771
772/** 772/**
773 * Return a random time value between 0.5*r and 1.5*r.
774 *
775 * @param r input time for scaling
776 * @return randomized time
777 */
778struct GNUNET_TIME_Relative
779GNUNET_TIME_randomize (struct GNUNET_TIME_Relative r)
780{
781 double d = ((rand() % 1001) - 500) / 1000.0;
782
783 return relative_multiply_double (r,
784 d);
785}
786
787
788/**
773 * Obtain the current time and make sure it is monotonically 789 * Obtain the current time and make sure it is monotonically
774 * increasing. Guards against systems without an RTC or 790 * increasing. Guards against systems without an RTC or
775 * clocks running backwards and other nasty surprises. Does 791 * clocks running backwards and other nasty surprises. Does
@@ -819,53 +835,53 @@ GNUNET_TIME_absolute_get_monotonic (const struct GNUNET_CONFIGURATION_Handle *cf
819 struct GNUNET_DISK_FileHandle *fh; 835 struct GNUNET_DISK_FileHandle *fh;
820 836
821 fh = GNUNET_DISK_file_open (filename, 837 fh = GNUNET_DISK_file_open (filename,
822 GNUNET_DISK_OPEN_READWRITE | GNUNET_DISK_OPEN_CREATE, 838 GNUNET_DISK_OPEN_READWRITE | GNUNET_DISK_OPEN_CREATE,
823 GNUNET_DISK_PERM_USER_WRITE | GNUNET_DISK_PERM_GROUP_WRITE | 839 GNUNET_DISK_PERM_USER_WRITE | GNUNET_DISK_PERM_GROUP_WRITE |
824 GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_GROUP_READ); 840 GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_GROUP_READ);
825 if (NULL == fh) 841 if (NULL == fh)
826 { 842 {
827 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 843 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
828 _("Failed to map `%s', cannot assure monotonic time!\n"), 844 _("Failed to map `%s', cannot assure monotonic time!\n"),
829 filename); 845 filename);
830 } 846 }
831 else 847 else
832 { 848 {
833 off_t size; 849 off_t size;
834 850
835 size = 0; 851 size = 0;
836 GNUNET_break (GNUNET_OK == 852 GNUNET_break (GNUNET_OK ==
837 GNUNET_DISK_file_handle_size (fh, 853 GNUNET_DISK_file_handle_size (fh,
838 &size)); 854 &size));
839 if (size < sizeof (*map)) 855 if (size < (off_t) sizeof (*map))
840 { 856 {
841 struct GNUNET_TIME_AbsoluteNBO o; 857 struct GNUNET_TIME_AbsoluteNBO o;
842 858
843 o = GNUNET_TIME_absolute_hton (now); 859 o = GNUNET_TIME_absolute_hton (now);
844 if (sizeof (o) != 860 if (sizeof (o) !=
845 GNUNET_DISK_file_write (fh, 861 GNUNET_DISK_file_write (fh,
846 &o, 862 &o,
847 sizeof (o))) 863 sizeof (o)))
848 size = 0; 864 size = 0;
849 else 865 else
850 size = sizeof (o); 866 size = sizeof (o);
851 } 867 }
852 if (size == sizeof (*map)) 868 if (size == sizeof (*map))
853 { 869 {
854 map = GNUNET_DISK_file_map (fh, 870 map = GNUNET_DISK_file_map (fh,
855 &map_handle, 871 &map_handle,
856 GNUNET_DISK_MAP_TYPE_READWRITE, 872 GNUNET_DISK_MAP_TYPE_READWRITE,
857 sizeof (*map)); 873 sizeof (*map));
858 if (NULL == map) 874 if (NULL == map)
859 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 875 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
860 _("Failed to map `%s', cannot assure monotonic time!\n"), 876 _("Failed to map `%s', cannot assure monotonic time!\n"),
861 filename); 877 filename);
862 } 878 }
863 else 879 else
864 { 880 {
865 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 881 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
866 _("Failed to setup monotonic time file `%s', cannot assure monotonic time!\n"), 882 _("Failed to setup monotonic time file `%s', cannot assure monotonic time!\n"),
867 filename); 883 filename);
868 } 884 }
869 } 885 }
870 GNUNET_DISK_file_close (fh); 886 GNUNET_DISK_file_close (fh);
871 GNUNET_free (filename); 887 GNUNET_free (filename);