aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-service-tng.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/gnunet-service-tng.c')
-rw-r--r--src/transport/gnunet-service-tng.c299
1 files changed, 296 insertions, 3 deletions
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 {