aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2018-11-22 17:29:01 +0100
committerChristian Grothoff <christian@grothoff.org>2018-11-22 17:29:01 +0100
commitca90313490f4233ce9d209abbdcc2d78d16b8326 (patch)
treeae0743a71f00cd744ba2368cb45c9a4f3949752c /src
parentae82c19b277ae3f5f43379ed6fc384aba4fdea83 (diff)
downloadgnunet-ca90313490f4233ce9d209abbdcc2d78d16b8326.tar.gz
gnunet-ca90313490f4233ce9d209abbdcc2d78d16b8326.zip
add new hello generation support logic to tng
Diffstat (limited to 'src')
-rw-r--r--src/hello/Makefile.am4
-rw-r--r--src/hello/hello-ng.c178
-rw-r--r--src/include/gnunet_hello_lib.h37
-rw-r--r--src/include/gnunet_signatures.h6
-rw-r--r--src/peerstore/plugin_peerstore_sqlite.c2
-rw-r--r--src/transport/Makefile.am2
-rw-r--r--src/transport/gnunet-service-tng.c245
7 files changed, 426 insertions, 48 deletions
diff --git a/src/hello/Makefile.am b/src/hello/Makefile.am
index 79003301b..00357f9e1 100644
--- a/src/hello/Makefile.am
+++ b/src/hello/Makefile.am
@@ -13,7 +13,9 @@ endif
13lib_LTLIBRARIES = libgnunethello.la 13lib_LTLIBRARIES = libgnunethello.la
14 14
15libgnunethello_la_SOURCES = \ 15libgnunethello_la_SOURCES = \
16 hello.c address.c 16 hello.c \
17 address.c \
18 hello-ng.c
17libgnunethello_la_LIBADD = \ 19libgnunethello_la_LIBADD = \
18 $(top_builddir)/src/util/libgnunetutil.la $(XLIB) \ 20 $(top_builddir)/src/util/libgnunetutil.la $(XLIB) \
19 $(LTLIBINTL) 21 $(LTLIBINTL)
diff --git a/src/hello/hello-ng.c b/src/hello/hello-ng.c
new file mode 100644
index 000000000..425095f9c
--- /dev/null
+++ b/src/hello/hello-ng.c
@@ -0,0 +1,178 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2018 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19/**
20 * @file hello/hello-ng.c
21 * @brief helper library for handling HELLOs
22 * @author Christian Grothoff
23 */
24#include "platform.h"
25#include "gnunet_signatures.h"
26#include "gnunet_hello_lib.h"
27#include "gnunet_protocols.h"
28#include "gnunet_util_lib.h"
29
30/**
31 * Binary block we sign when we sign an address.
32 */
33struct SignedAddress
34{
35 /**
36 * Purpose must be #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_ADDRESS
37 */
38 struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
39
40 /**
41 * When does the address expire.
42 */
43 struct GNUNET_TIME_AbsoluteNBO expiration;
44
45 /**
46 * Hash of the address.
47 */
48 struct GNUNET_HashCode h_addr;
49};
50
51
52/**
53 * Build address record by signing raw information with private key.
54 *
55 * @param address text address at @a communicator to sign
56 * @param expiration how long is @a address valid
57 * @param private_key signing key to use
58 * @param result[out] where to write address record (allocated)
59 * @param result_size[out] set to size of @a result
60 */
61void
62GNUNET_HELLO_sign_address (const char *address,
63 struct GNUNET_TIME_Absolute expiration,
64 const struct GNUNET_CRYPTO_EddsaPrivateKey *private_key,
65 void **result,
66 size_t *result_size)
67{
68 struct SignedAddress sa;
69 struct GNUNET_CRYPTO_EddsaSignature sig;
70 char *sig_str;
71
72 sa.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_ADDRESS);
73 sa.purpose.size = htonl (sizeof (sa));
74 sa.expiration = GNUNET_TIME_absolute_hton (expiration);
75 GNUNET_CRYPTO_hash (address,
76 strlen (address),
77 &sa.h_addr);
78 GNUNET_assert (GNUNET_YES ==
79 GNUNET_CRYPTO_eddsa_sign (private_key,
80 &sa.purpose,
81 &sig));
82 sig_str = NULL;
83 (void) GNUNET_STRINGS_base64_encode (&sig,
84 sizeof (sig),
85 &sig_str);
86 *result_size = 1 + GNUNET_asprintf ((char **) result,
87 "%s;%llu;%s",
88 sig_str,
89 (unsigned long long) expiration.abs_value_us,
90 address);
91 GNUNET_free (sig_str);
92}
93
94
95/**
96 * Check signature and extract address record.
97 *
98 * @param raw raw signed address
99 * @param raw_size size of @a raw
100 * @param public_key public key to use for signature verification
101 * @param expiration[out] how long is the address valid
102 * @return NULL on error, otherwise the address
103 */
104char *
105GNUNET_HELLO_extract_address (const void *raw,
106 size_t raw_size,
107 const struct GNUNET_CRYPTO_EddsaPublicKey *public_key,
108 struct GNUNET_TIME_Absolute *expiration)
109{
110 const char *raws = raw;
111 unsigned long long raw_us;
112 const char *sc;
113 const char *sc2;
114 const char *raw_addr;
115 struct GNUNET_TIME_Absolute raw_expiration;
116 struct SignedAddress sa;
117 struct GNUNET_CRYPTO_EddsaSignature *sig;
118
119 if ('\0' != raws[raw_size])
120 {
121 GNUNET_break_op (0);
122 return NULL;
123 }
124 if (NULL == (sc = strchr (raws,
125 ';')))
126 {
127 GNUNET_break_op (0);
128 return NULL;
129 }
130 if (NULL == (sc2 = strchr (sc + 1,
131 ';')))
132 {
133 GNUNET_break_op (0);
134 return NULL;
135 }
136 if (1 != sscanf (sc + 1,
137 "%llu;",
138 &raw_us))
139 {
140 GNUNET_break_op (0);
141 return NULL;
142 }
143 raw_expiration.abs_value_us = raw_us;
144 if (0 == GNUNET_TIME_absolute_get_remaining (raw_expiration).rel_value_us)
145 return NULL; /* expired */
146 sig = NULL;
147 if (sizeof (struct GNUNET_CRYPTO_EddsaSignature) !=
148 GNUNET_STRINGS_base64_decode (raws,
149 sc - raws,
150 (void **) &sig))
151 {
152 GNUNET_break_op (0);
153 GNUNET_free_non_null (sig);
154 return NULL;
155 }
156 raw_addr = sc2 + 1;
157
158 sa.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_ADDRESS);
159 sa.purpose.size = htonl (sizeof (sa));
160 sa.expiration = GNUNET_TIME_absolute_hton (raw_expiration);
161 GNUNET_CRYPTO_hash (raw_addr,
162 strlen (raw_addr),
163 &sa.h_addr);
164 if (GNUNET_YES !=
165 GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_ADDRESS,
166 &sa.purpose,
167 sig,
168 public_key))
169 {
170 GNUNET_break_op (0);
171 GNUNET_free (sig);
172 return NULL;
173 }
174 GNUNET_free (sig);
175 return GNUNET_strdup (raw_addr);
176}
177
178
diff --git a/src/include/gnunet_hello_lib.h b/src/include/gnunet_hello_lib.h
index 2a961e524..e19419f25 100644
--- a/src/include/gnunet_hello_lib.h
+++ b/src/include/gnunet_hello_lib.h
@@ -473,6 +473,43 @@ GNUNET_HELLO_parse_uri (const char *uri,
473 GNUNET_HELLO_TransportPluginsFind plugins_find); 473 GNUNET_HELLO_TransportPluginsFind plugins_find);
474 474
475 475
476
477/* NG API */
478
479/**
480 * Build address record by signing raw information with private key.
481 *
482 * @param address text address to sign
483 * @param expiration how long is @a address valid
484 * @param private_key signing key to use
485 * @param result[out] where to write address record (allocated)
486 * @param result_size[out] set to size of @a result
487 */
488void
489GNUNET_HELLO_sign_address (const char *address,
490 struct GNUNET_TIME_Absolute expiration,
491 const struct GNUNET_CRYPTO_EddsaPrivateKey *private_key,
492 void **result,
493 size_t *result_size);
494
495
496/**
497 * Check signature and extract address record.
498 *
499 * @param raw raw signed address
500 * @param raw_size size of @a raw
501 * @param public_key public key to use for signature verification
502 * @param expiration[out] how long is the address valid
503 * @return NULL on error, otherwise the address
504 */
505char *
506GNUNET_HELLO_extract_address (const void *raw,
507 size_t raw_size,
508 const struct GNUNET_CRYPTO_EddsaPublicKey *public_key,
509 struct GNUNET_TIME_Absolute *expiration);
510
511
512
476#if 0 /* keep Emacsens' auto-indent happy */ 513#if 0 /* keep Emacsens' auto-indent happy */
477{ 514{
478#endif 515#endif
diff --git a/src/include/gnunet_signatures.h b/src/include/gnunet_signatures.h
index 829f8be7e..03c97f199 100644
--- a/src/include/gnunet_signatures.h
+++ b/src/include/gnunet_signatures.h
@@ -188,6 +188,12 @@ extern "C"
188 */ 188 */
189#define GNUNET_SIGNATURE_PURPOSE_CREDENTIAL 28 189#define GNUNET_SIGNATURE_PURPOSE_CREDENTIAL 28
190 190
191/**
192 * Signature by a peer affirming that this is one of its
193 * addresses (for the given time period).
194 */
195#define GNUNET_SIGNATURE_PURPOSE_TRANSPORT_ADDRESS 29
196
191#if 0 /* keep Emacsens' auto-indent happy */ 197#if 0 /* keep Emacsens' auto-indent happy */
192{ 198{
193#endif 199#endif
diff --git a/src/peerstore/plugin_peerstore_sqlite.c b/src/peerstore/plugin_peerstore_sqlite.c
index 7ecb7bacd..e09274989 100644
--- a/src/peerstore/plugin_peerstore_sqlite.c
+++ b/src/peerstore/plugin_peerstore_sqlite.c
@@ -496,7 +496,7 @@ sql_prepare (sqlite3 *dbh,
496 * as needed as well). 496 * as needed as well).
497 * 497 *
498 * @param plugin the plugin context (state for this module) 498 * @param plugin the plugin context (state for this module)
499 * @return GNUNET_OK on success 499 * @return #GNUNET_OK on success
500 */ 500 */
501static int 501static int
502database_setup (struct Plugin *plugin) 502database_setup (struct Plugin *plugin)
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am
index deeb39b48..0693a0b9f 100644
--- a/src/transport/Makefile.am
+++ b/src/transport/Makefile.am
@@ -328,6 +328,8 @@ gnunet_service_tng_SOURCES = \
328 gnunet-service-tng.c 328 gnunet-service-tng.c
329gnunet_service_tng_LDADD = \ 329gnunet_service_tng_LDADD = \
330 $(top_builddir)/src/ats/libgnunetats.la \ 330 $(top_builddir)/src/ats/libgnunetats.la \
331 $(top_builddir)/src/peerstore/libgnunetpeerstore.la \
332 $(top_builddir)/src/hello/libgnunethello.la \
331 $(top_builddir)/src/statistics/libgnunetstatistics.la \ 333 $(top_builddir)/src/statistics/libgnunetstatistics.la \
332 $(top_builddir)/src/util/libgnunetutil.la \ 334 $(top_builddir)/src/util/libgnunetutil.la \
333 $(GN_LIBINTL) 335 $(GN_LIBINTL)
diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c
index c7bdfd77c..e5fb51bd2 100644
--- a/src/transport/gnunet-service-tng.c
+++ b/src/transport/gnunet-service-tng.c
@@ -21,8 +21,6 @@
21 * @author Christian Grothoff 21 * @author Christian Grothoff
22 * 22 *
23 * TODO: 23 * TODO:
24 * - make *our* collected addresses available somehow somewhere
25 * => Choices: in peerstore or revive/keep peerinfo?
26 * - MTU information is missing for queues! 24 * - MTU information is missing for queues!
27 * - start supporting monitor logic (add functions to signal monitors!) 25 * - start supporting monitor logic (add functions to signal monitors!)
28 * - manage fragmentation/defragmentation, retransmission, track RTT, loss, etc. 26 * - manage fragmentation/defragmentation, retransmission, track RTT, loss, etc.
@@ -33,7 +31,7 @@
33#include "gnunet_util_lib.h" 31#include "gnunet_util_lib.h"
34#include "gnunet_statistics_service.h" 32#include "gnunet_statistics_service.h"
35#include "gnunet_transport_service.h" 33#include "gnunet_transport_service.h"
36#include "gnunet_peerinfo_service.h" 34#include "gnunet_peerstore_service.h"
37#include "gnunet_ats_service.h" 35#include "gnunet_ats_service.h"
38#include "gnunet-service-transport.h" 36#include "gnunet-service-transport.h"
39#include "transport.h" 37#include "transport.h"
@@ -263,6 +261,16 @@ struct AddressListEntry
263 const char *address; 261 const char *address;
264 262
265 /** 263 /**
264 * Current context for storing this address in the peerstore.
265 */
266 struct GNUNET_PEERSTORE_StoreContext *sc;
267
268 /**
269 * Task to periodically do @e st operation.
270 */
271 struct GNUNET_SCHEDULER_Task *st;
272
273 /**
266 * What is a typical lifetime the communicator expects this 274 * What is a typical lifetime the communicator expects this
267 * address to have? (Always from now.) 275 * address to have? (Always from now.)
268 */ 276 */
@@ -425,6 +433,11 @@ struct GNUNET_CRYPTO_EddsaPrivateKey *GST_my_private_key;
425 */ 433 */
426static struct GNUNET_CONTAINER_MultiPeerMap *neighbours; 434static struct GNUNET_CONTAINER_MultiPeerMap *neighbours;
427 435
436/**
437 * Database for peer's HELLOs.
438 */
439static struct GNUNET_PEERSTORE_Handle *peerstore;
440
428 441
429/** 442/**
430 * Lookup neighbour record for peer @a pid. 443 * Lookup neighbour record for peer @a pid.
@@ -470,6 +483,78 @@ client_connect_cb (void *cls,
470 483
471 484
472/** 485/**
486 * Release memory used by @a neighbour.
487 *
488 * @param neighbour neighbour entry to free
489 */
490static void
491free_neighbour (struct Neighbour *neighbour)
492{
493 GNUNET_assert (NULL == neighbour->queue_head);
494 GNUNET_assert (GNUNET_YES ==
495 GNUNET_CONTAINER_multipeermap_remove (neighbours,
496 &neighbour->pid,
497 neighbour));
498 GNUNET_free (neighbour);
499}
500
501
502/**
503 * Free @a queue.
504 *
505 * @param queue the queue to free
506 */
507static void
508free_queue (struct Queue *queue)
509{
510 struct Neighbour *neighbour = queue->neighbour;
511 struct TransportClient *tc = queue->tc;
512
513 GNUNET_CONTAINER_MDLL_remove (neighbour,
514 neighbour->queue_head,
515 neighbour->queue_tail,
516 queue);
517 GNUNET_CONTAINER_MDLL_remove (client,
518 tc->details.communicator.queue_head,
519 tc->details.communicator.queue_tail,
520 queue);
521 GNUNET_free (queue);
522 if (NULL == neighbour->queue_head)
523 {
524 // FIXME: notify cores/monitors!
525 free_neighbour (neighbour);
526 }
527}
528
529
530/**
531 * Free @a ale
532 *
533 * @param ale address list entry to free
534 */
535static void
536free_address_list_entry (struct AddressListEntry *ale)
537{
538 struct TransportClient *tc = ale->tc;
539
540 GNUNET_CONTAINER_DLL_remove (tc->details.communicator.addr_head,
541 tc->details.communicator.addr_tail,
542 ale);
543 if (NULL != ale->sc)
544 {
545 GNUNET_PEERSTORE_store_cancel (ale->sc);
546 ale->sc = NULL;
547 }
548 if (NULL != ale->st)
549 {
550 GNUNET_SCHEDULER_cancel (ale->st);
551 ale->st = NULL;
552 }
553 GNUNET_free (ale);
554}
555
556
557/**
473 * Called whenever a client is disconnected. Frees our 558 * Called whenever a client is disconnected. Frees our
474 * resources associated with that client. 559 * resources associated with that client.
475 * 560 *
@@ -511,7 +596,16 @@ client_disconnect_cb (void *cls,
511 case CT_MONITOR: 596 case CT_MONITOR:
512 break; 597 break;
513 case CT_COMMUNICATOR: 598 case CT_COMMUNICATOR:
514 GNUNET_free (tc->details.communicator.address_prefix); 599 {
600 struct Queue *q;
601 struct AddressListEntry *ale;
602
603 while (NULL != (q = tc->details.communicator.queue_head))
604 free_queue (q);
605 while (NULL != (ale = tc->details.communicator.addr_head))
606 free_address_list_entry (ale);
607 GNUNET_free (tc->details.communicator.address_prefix);
608 }
515 break; 609 break;
516 } 610 }
517 GNUNET_free (tc); 611 GNUNET_free (tc);
@@ -789,6 +883,81 @@ check_add_address (void *cls,
789 883
790 884
791/** 885/**
886 * Ask peerstore to store our address.
887 *
888 * @param cls an `struct AddressListEntry *`
889 */
890static void
891store_pi (void *cls);
892
893
894/**
895 * Function called when peerstore is done storing our address.
896 */
897static void
898peerstore_store_cb (void *cls,
899 int success)
900{
901 struct AddressListEntry *ale = cls;
902
903 ale->sc = NULL;
904 if (GNUNET_YES != success)
905 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
906 "Failed to store our own address `%s' in peerstore!\n",
907 ale->address);
908 /* refresh period is 1/4 of expiration time, that should be plenty
909 without being excessive. */
910 ale->st = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_divide (ale->expiration,
911 4ULL),
912 &store_pi,
913 ale);
914}
915
916
917/**
918 * Ask peerstore to store our address.
919 *
920 * @param cls an `struct AddressListEntry *`
921 */
922static void
923store_pi (void *cls)
924{
925 struct AddressListEntry *ale = cls;
926 void *addr;
927 size_t addr_len;
928 struct GNUNET_TIME_Absolute expiration;
929
930 ale->st = NULL;
931 expiration = GNUNET_TIME_relative_to_absolute (ale->expiration);
932 GNUNET_HELLO_sign_address (ale->address,
933 expiration,
934 GST_my_private_key,
935 &addr,
936 &addr_len);
937 ale->sc = GNUNET_PEERSTORE_store (peerstore,
938 "transport",
939 &GST_my_identity,
940 "hello",
941 addr,
942 addr_len,
943 expiration,
944 GNUNET_PEERSTORE_STOREOPTION_MULTIPLE,
945 &peerstore_store_cb,
946 ale);
947 GNUNET_free (addr);
948 if (NULL == ale->sc)
949 {
950 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
951 "Failed to store our address `%s' with peerstore\n",
952 ale->address);
953 ale->st = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
954 &store_pi,
955 ale);
956 }
957}
958
959
960/**
792 * Address of our peer added. Process the request. 961 * Address of our peer added. Process the request.
793 * 962 *
794 * @param cls the client 963 * @param cls the client
@@ -815,7 +984,8 @@ handle_add_address (void *cls,
815 GNUNET_CONTAINER_DLL_insert (tc->details.communicator.addr_head, 984 GNUNET_CONTAINER_DLL_insert (tc->details.communicator.addr_head,
816 tc->details.communicator.addr_tail, 985 tc->details.communicator.addr_tail,
817 ale); 986 ale);
818 // FIXME: notify somebody?! 987 ale->st = GNUNET_SCHEDULER_add_now (&store_pi,
988 ale);
819 GNUNET_SERVICE_client_continue (tc->client); 989 GNUNET_SERVICE_client_continue (tc->client);
820} 990}
821 991
@@ -845,11 +1015,7 @@ handle_del_address (void *cls,
845 if (dam->aid != ale->aid) 1015 if (dam->aid != ale->aid)
846 continue; 1016 continue;
847 GNUNET_assert (ale->tc == tc); 1017 GNUNET_assert (ale->tc == tc);
848 GNUNET_CONTAINER_DLL_remove (tc->details.communicator.addr_head, 1018 free_address_list_entry (ale);
849 tc->details.communicator.addr_tail,
850 ale);
851 // FIXME: notify somebody?
852 GNUNET_free (ale);
853 GNUNET_SERVICE_client_continue (tc->client); 1019 GNUNET_SERVICE_client_continue (tc->client);
854 } 1020 }
855 GNUNET_break (0); 1021 GNUNET_break (0);
@@ -997,23 +1163,6 @@ handle_add_queue_message (void *cls,
997 1163
998 1164
999/** 1165/**
1000 * Release memory used by @a neighbour.
1001 *
1002 * @param neighbour neighbour entry to free
1003 */
1004static void
1005free_neighbour (struct Neighbour *neighbour)
1006{
1007 GNUNET_assert (NULL == neighbour->queue_head);
1008 GNUNET_assert (GNUNET_YES ==
1009 GNUNET_CONTAINER_multipeermap_remove (neighbours,
1010 &neighbour->pid,
1011 neighbour));
1012 GNUNET_free (neighbour);
1013}
1014
1015
1016/**
1017 * Queue to a peer went down. Process the request. 1166 * Queue to a peer went down. Process the request.
1018 * 1167 *
1019 * @param cls the client 1168 * @param cls the client
@@ -1042,20 +1191,7 @@ handle_del_queue_message (void *cls,
1042 &neighbour->pid, 1191 &neighbour->pid,
1043 sizeof (struct GNUNET_PeerIdentity))) ) 1192 sizeof (struct GNUNET_PeerIdentity))) )
1044 continue; 1193 continue;
1045 GNUNET_CONTAINER_MDLL_remove (neighbour, 1194 free_queue (queue);
1046 neighbour->queue_head,
1047 neighbour->queue_tail,
1048 queue);
1049 GNUNET_CONTAINER_MDLL_remove (client,
1050 tc->details.communicator.queue_head,
1051 tc->details.communicator.queue_tail,
1052 queue);
1053 GNUNET_free (queue);
1054 if (NULL == neighbour->queue_head)
1055 {
1056 // FIXME: notify cores/monitors!
1057 free_neighbour (neighbour);
1058 }
1059 GNUNET_SERVICE_client_continue (tc->client); 1195 GNUNET_SERVICE_client_continue (tc->client);
1060 return; 1196 return;
1061 } 1197 }
@@ -1094,7 +1230,7 @@ handle_send_message_ack (void *cls,
1094 */ 1230 */
1095static void 1231static void
1096handle_monitor_start (void *cls, 1232handle_monitor_start (void *cls,
1097 const struct GNUNET_TRANSPORT_MonitorStart *start) 1233 const struct GNUNET_TRANSPORT_MonitorStart *start)
1098{ 1234{
1099 struct TransportClient *tc = cls; 1235 struct TransportClient *tc = cls;
1100 1236
@@ -1147,20 +1283,30 @@ do_shutdown (void *cls)
1147{ 1283{
1148 (void) cls; 1284 (void) cls;
1149 1285
1286 GNUNET_CONTAINER_multipeermap_iterate (neighbours,
1287 &free_neighbour_cb,
1288 NULL);
1289 /* FIXME: if this assertion fails (likely!), make sure we
1290 clean up clients *before* doing the rest of the
1291 shutdown! (i.e. by scheduling rest asynchronously!) */
1292 GNUNET_assert (NULL == clients_head);
1293 if (NULL != peerstore)
1294 {
1295 GNUNET_PEERSTORE_disconnect (peerstore,
1296 GNUNET_NO);
1297 peerstore = NULL;
1298 }
1150 if (NULL != GST_stats) 1299 if (NULL != GST_stats)
1151 { 1300 {
1152 GNUNET_STATISTICS_destroy (GST_stats, 1301 GNUNET_STATISTICS_destroy (GST_stats,
1153 GNUNET_NO); 1302 GNUNET_NO);
1154 GST_stats = NULL; 1303 GST_stats = NULL;
1155 } 1304 }
1156 if (NULL != GST_my_private_key) 1305 if (NULL != GST_my_private_key)
1157 { 1306 {
1158 GNUNET_free (GST_my_private_key); 1307 GNUNET_free (GST_my_private_key);
1159 GST_my_private_key = NULL; 1308 GST_my_private_key = NULL;
1160 } 1309 }
1161 GNUNET_CONTAINER_multipeermap_iterate (neighbours,
1162 &free_neighbour_cb,
1163 NULL);
1164 GNUNET_CONTAINER_multipeermap_destroy (neighbours); 1310 GNUNET_CONTAINER_multipeermap_destroy (neighbours);
1165} 1311}
1166 1312
@@ -1200,6 +1346,13 @@ run (void *cls,
1200 GST_cfg); 1346 GST_cfg);
1201 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, 1347 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
1202 NULL); 1348 NULL);
1349 peerstore = GNUNET_PEERSTORE_connect (GST_cfg);
1350 if (NULL == peerstore)
1351 {
1352 GNUNET_break (0);
1353 GNUNET_SCHEDULER_shutdown ();
1354 return;
1355 }
1203 /* start subsystems */ 1356 /* start subsystems */
1204} 1357}
1205 1358