diff options
author | xrs <xrs@mail36.net> | 2017-02-28 19:37:43 +0100 |
---|---|---|
committer | xrs <xrs@mail36.net> | 2017-02-28 19:37:43 +0100 |
commit | f82b3a27df765f4a31548ae4efe66dc3dbc42cef (patch) | |
tree | 5a08cd0026d2b85bca3160b6ca40573c871c8635 /src | |
parent | b0042448a40e90426ea8013b1abba8b2ecb69c2b (diff) | |
parent | a9a6b98c54f5cc3e680c8ea2f9c69e3955e2a7da (diff) | |
download | gnunet-f82b3a27df765f4a31548ae4efe66dc3dbc42cef.tar.gz gnunet-f82b3a27df765f4a31548ae4efe66dc3dbc42cef.zip |
Merge branch 'master' of ssh://gnunet.org/gnunet
Conflicts:
src/multicast/test_multicast_multipeer.c
Diffstat (limited to 'src')
214 files changed, 8827 insertions, 17298 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 56f301ac0..e466cbc28 100644 --- a/src/Makefile.am +++ b/src/Makefile.am | |||
@@ -6,18 +6,13 @@ | |||
6 | if HAVE_TESTING | 6 | if HAVE_TESTING |
7 | TESTING = testing | 7 | TESTING = testing |
8 | TESTBED = testbed-logger testbed | 8 | TESTBED = testbed-logger testbed |
9 | CONSENSUS = consensus | ||
10 | SECRETSHARING = secretsharing | ||
11 | ATS_TESTS = ats-tests | 9 | ATS_TESTS = ats-tests |
12 | endif | 10 | endif |
13 | 11 | ||
14 | if HAVE_EXPERIMENTAL | 12 | if HAVE_EXPERIMENTAL |
15 | EXP_DIR = \ | 13 | EXP_DIR = \ |
16 | dv \ | 14 | dv \ |
17 | rps \ | 15 | rps |
18 | $(CONSENSUS) \ | ||
19 | $(SECRETSHARING) | ||
20 | |||
21 | endif | 16 | endif |
22 | 17 | ||
23 | if HAVE_JSON | 18 | if HAVE_JSON |
@@ -45,6 +40,10 @@ CONVERSATION_DIR = conversation | |||
45 | endif | 40 | endif |
46 | endif | 41 | endif |
47 | 42 | ||
43 | if HAVE_SQLITE | ||
44 | SQLITE_DIR = sq | ||
45 | endif | ||
46 | |||
48 | if HAVE_MYSQL | 47 | if HAVE_MYSQL |
49 | MYSQL_DIR = mysql my | 48 | MYSQL_DIR = mysql my |
50 | endif | 49 | endif |
@@ -83,6 +82,7 @@ SUBDIRS = \ | |||
83 | arm \ | 82 | arm \ |
84 | $(TESTING) \ | 83 | $(TESTING) \ |
85 | peerinfo \ | 84 | peerinfo \ |
85 | $(SQLITE_DIR) \ | ||
86 | $(MYSQL_DIR) \ | 86 | $(MYSQL_DIR) \ |
87 | $(POSTGRES_DIR) \ | 87 | $(POSTGRES_DIR) \ |
88 | datacache \ | 88 | datacache \ |
@@ -111,6 +111,7 @@ SUBDIRS = \ | |||
111 | peerstore \ | 111 | peerstore \ |
112 | cadet \ | 112 | cadet \ |
113 | set \ | 113 | set \ |
114 | consensus \ | ||
114 | scalarproduct \ | 115 | scalarproduct \ |
115 | revocation \ | 116 | revocation \ |
116 | vpn \ | 117 | vpn \ |
@@ -120,6 +121,7 @@ SUBDIRS = \ | |||
120 | fs \ | 121 | fs \ |
121 | exit \ | 122 | exit \ |
122 | pt \ | 123 | pt \ |
124 | secretsharing \ | ||
123 | integration-tests \ | 125 | integration-tests \ |
124 | multicast \ | 126 | multicast \ |
125 | psycutil \ | 127 | psycutil \ |
diff --git a/src/ats-tests/Makefile.am b/src/ats-tests/Makefile.am index 206f964cc..4811bc8d7 100644 --- a/src/ats-tests/Makefile.am +++ b/src/ats-tests/Makefile.am | |||
@@ -13,6 +13,7 @@ if USE_COVERAGE | |||
13 | AM_CFLAGS = -fprofile-arcs -ftest-coverage | 13 | AM_CFLAGS = -fprofile-arcs -ftest-coverage |
14 | endif | 14 | endif |
15 | 15 | ||
16 | if HAVE_EXPERIMENTAL | ||
16 | if HAVE_LIBGLPK | 17 | if HAVE_LIBGLPK |
17 | PERF_MLP = \ | 18 | PERF_MLP = \ |
18 | perf_ats_mlp_transport_none \ | 19 | perf_ats_mlp_transport_none \ |
@@ -22,6 +23,7 @@ if HAVE_LIBGLPK | |||
22 | perf_ats_mlp_core_bandwidth \ | 23 | perf_ats_mlp_core_bandwidth \ |
23 | perf_ats_mlp_core_latency | 24 | perf_ats_mlp_core_latency |
24 | endif | 25 | endif |
26 | endif | ||
25 | 27 | ||
26 | if HAVE_TESTING | 28 | if HAVE_TESTING |
27 | TESTING_TESTS = \ | 29 | TESTING_TESTS = \ |
@@ -140,7 +142,7 @@ perf_ats_proportional_transport_bandwidth_LDADD = \ | |||
140 | perf_ats_proportional_transport_bandwidth_DEPENDENCIES = \ | 142 | perf_ats_proportional_transport_bandwidth_DEPENDENCIES = \ |
141 | libgnunetatstesting.la \ | 143 | libgnunetatstesting.la \ |
142 | $(top_builddir)/src/util/libgnunetutil.la | 144 | $(top_builddir)/src/util/libgnunetutil.la |
143 | 145 | ||
144 | perf_ats_proportional_core_latency_SOURCES = \ | 146 | perf_ats_proportional_core_latency_SOURCES = \ |
145 | perf_ats.c | 147 | perf_ats.c |
146 | perf_ats_proportional_core_latency_LDADD = \ | 148 | perf_ats_proportional_core_latency_LDADD = \ |
diff --git a/src/ats/.gitignore b/src/ats/.gitignore index 983dc2843..97f1088b9 100644 --- a/src/ats/.gitignore +++ b/src/ats/.gitignore | |||
@@ -1,3 +1,5 @@ | |||
1 | gnunet-service-ats | 1 | gnunet-service-ats |
2 | test_ats_api_proportional | 2 | test_ats_api_proportional |
3 | test_ats_reservation_api_proportional | 3 | test_ats_reservation_api_proportional |
4 | test_ats_api_mlp | ||
5 | test_ats_api_ril | ||
diff --git a/src/ats/Makefile.am b/src/ats/Makefile.am index af7f6bd58..759dac0be 100644 --- a/src/ats/Makefile.am +++ b/src/ats/Makefile.am | |||
@@ -21,14 +21,16 @@ endif | |||
21 | lib_LTLIBRARIES = libgnunetats.la | 21 | lib_LTLIBRARIES = libgnunetats.la |
22 | 22 | ||
23 | plugin_LTLIBRARIES = \ | 23 | plugin_LTLIBRARIES = \ |
24 | libgnunet_plugin_ats_proportional.la \ | 24 | libgnunet_plugin_ats_proportional.la |
25 | $(GN_MLP_LIB) \ | ||
26 | libgnunet_plugin_ats_ril.la | ||
27 | 25 | ||
26 | if HAVE_EXPERIMENTAL | ||
27 | plugin_LTLIBRARIES += \ | ||
28 | libgnunet_plugin_ats_ril.la | ||
28 | if HAVE_LIBGLPK | 29 | if HAVE_LIBGLPK |
29 | plugin_LTLIBRARIES += \ | 30 | plugin_LTLIBRARIES += \ |
30 | libgnunet_plugin_ats_mlp.la | 31 | libgnunet_plugin_ats_mlp.la |
31 | endif | 32 | endif |
33 | endif | ||
32 | 34 | ||
33 | libgnunetats_la_SOURCES = \ | 35 | libgnunetats_la_SOURCES = \ |
34 | ats_api_connectivity.c \ | 36 | ats_api_connectivity.c \ |
@@ -54,7 +56,6 @@ libgnunet_plugin_ats_proportional_la_LDFLAGS = \ | |||
54 | $(GN_PLUGIN_LDFLAGS) | 56 | $(GN_PLUGIN_LDFLAGS) |
55 | 57 | ||
56 | 58 | ||
57 | if HAVE_LIBGLPK | ||
58 | libgnunet_plugin_ats_mlp_la_SOURCES = \ | 59 | libgnunet_plugin_ats_mlp_la_SOURCES = \ |
59 | plugin_ats_mlp.c | 60 | plugin_ats_mlp.c |
60 | libgnunet_plugin_ats_mlp_la_LIBADD = \ | 61 | libgnunet_plugin_ats_mlp_la_LIBADD = \ |
@@ -64,7 +65,6 @@ libgnunet_plugin_ats_mlp_la_LIBADD = \ | |||
64 | libgnunet_plugin_ats_mlp_la_LDFLAGS = \ | 65 | libgnunet_plugin_ats_mlp_la_LDFLAGS = \ |
65 | $(GN_PLUGIN_LDFLAGS) \ | 66 | $(GN_PLUGIN_LDFLAGS) \ |
66 | -lglpk | 67 | -lglpk |
67 | endif | ||
68 | 68 | ||
69 | libgnunet_plugin_ats_ril_la_SOURCES = \ | 69 | libgnunet_plugin_ats_ril_la_SOURCES = \ |
70 | plugin_ats_ril.c | 70 | plugin_ats_ril.c |
@@ -99,7 +99,7 @@ if HAVE_TESTING | |||
99 | TESTING_TESTS = \ | 99 | TESTING_TESTS = \ |
100 | test_ats_api_proportional \ | 100 | test_ats_api_proportional \ |
101 | test_ats_reservation_api_proportional | 101 | test_ats_reservation_api_proportional |
102 | if HAVE_WACHS | 102 | if HAVE_EXPERIMENTAL |
103 | TESTING_TESTS += \ | 103 | TESTING_TESTS += \ |
104 | test_ats_api_ril | 104 | test_ats_api_ril |
105 | if HAVE_LIBGLPK | 105 | if HAVE_LIBGLPK |
diff --git a/src/block/Makefile.am b/src/block/Makefile.am index da1d8257c..05df7541d 100644 --- a/src/block/Makefile.am +++ b/src/block/Makefile.am | |||
@@ -56,8 +56,10 @@ libgnunetblock_la_LDFLAGS = \ | |||
56 | libgnunetblockgroup_la_SOURCES = \ | 56 | libgnunetblockgroup_la_SOURCES = \ |
57 | bg_bf.c | 57 | bg_bf.c |
58 | libgnunetblockgroup_la_LIBADD = \ | 58 | libgnunetblockgroup_la_LIBADD = \ |
59 | libgnunetblock.la \ | ||
59 | $(top_builddir)/src/util/libgnunetutil.la | 60 | $(top_builddir)/src/util/libgnunetutil.la |
60 | libgnunetblockgroup_la_DEPENDENCIES = \ | 61 | libgnunetblockgroup_la_DEPENDENCIES = \ |
62 | libgnunetblock.la \ | ||
61 | $(top_builddir)/src/util/libgnunetutil.la | 63 | $(top_builddir)/src/util/libgnunetutil.la |
62 | libgnunetblockgroup_la_LDFLAGS = \ | 64 | libgnunetblockgroup_la_LDFLAGS = \ |
63 | $(GN_LIB_LDFLAGS) \ | 65 | $(GN_LIB_LDFLAGS) \ |
diff --git a/src/block/bg_bf.c b/src/block/bg_bf.c index 9c4dc9060..1a17ec84e 100644 --- a/src/block/bg_bf.c +++ b/src/block/bg_bf.c | |||
@@ -232,4 +232,36 @@ GNUNET_BLOCK_GROUP_bf_test_and_set (struct GNUNET_BLOCK_Group *bg, | |||
232 | } | 232 | } |
233 | 233 | ||
234 | 234 | ||
235 | /** | ||
236 | * How many bytes should a bloomfilter be if we have already seen | ||
237 | * entry_count responses? Sized so that do not have to | ||
238 | * re-size the filter too often (to keep it cheap). | ||
239 | * | ||
240 | * Since other peers will also add entries but not resize the filter, | ||
241 | * we should generally pick a slightly larger size than what the | ||
242 | * strict math would suggest. | ||
243 | * | ||
244 | * @param entry_count expected number of entries in the Bloom filter | ||
245 | * @param k number of bits set per entry | ||
246 | * @return must be a power of two and smaller or equal to 2^15. | ||
247 | */ | ||
248 | size_t | ||
249 | GNUNET_BLOCK_GROUP_compute_bloomfilter_size (unsigned int entry_count, | ||
250 | unsigned int k) | ||
251 | { | ||
252 | size_t size; | ||
253 | unsigned int ideal = (entry_count * k) / 4; | ||
254 | uint16_t max = 1 << 15; | ||
255 | |||
256 | if (entry_count > max) | ||
257 | return max; | ||
258 | size = 8; | ||
259 | while ((size < max) && (size < ideal)) | ||
260 | size *= 2; | ||
261 | if (size > max) | ||
262 | return max; | ||
263 | return size; | ||
264 | } | ||
265 | |||
266 | |||
235 | /* end of bg_bf.c */ | 267 | /* end of bg_bf.c */ |
diff --git a/src/block/block.c b/src/block/block.c index b7a19ae90..4b6f3826d 100644 --- a/src/block/block.c +++ b/src/block/block.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2010 GNUnet e.V. | 3 | Copyright (C) 2010, 2017 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -84,8 +84,12 @@ GNUNET_BLOCK_mingle_hash (const struct GNUNET_HashCode *in, | |||
84 | { | 84 | { |
85 | struct GNUNET_HashCode m; | 85 | struct GNUNET_HashCode m; |
86 | 86 | ||
87 | GNUNET_CRYPTO_hash (&mingle_number, sizeof (uint32_t), &m); | 87 | GNUNET_CRYPTO_hash (&mingle_number, |
88 | GNUNET_CRYPTO_hash_xor (&m, in, hc); | 88 | sizeof (uint32_t), |
89 | &m); | ||
90 | GNUNET_CRYPTO_hash_xor (&m, | ||
91 | in, | ||
92 | hc); | ||
89 | } | 93 | } |
90 | 94 | ||
91 | 95 | ||
@@ -111,7 +115,9 @@ add_plugin (void *cls, | |||
111 | plugin = GNUNET_new (struct Plugin); | 115 | plugin = GNUNET_new (struct Plugin); |
112 | plugin->api = api; | 116 | plugin->api = api; |
113 | plugin->library_name = GNUNET_strdup (library_name); | 117 | plugin->library_name = GNUNET_strdup (library_name); |
114 | GNUNET_array_append (ctx->plugins, ctx->num_plugins, plugin); | 118 | GNUNET_array_append (ctx->plugins, |
119 | ctx->num_plugins, | ||
120 | plugin); | ||
115 | } | 121 | } |
116 | 122 | ||
117 | 123 | ||
@@ -129,7 +135,10 @@ GNUNET_BLOCK_context_create (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
129 | 135 | ||
130 | ctx = GNUNET_new (struct GNUNET_BLOCK_Context); | 136 | ctx = GNUNET_new (struct GNUNET_BLOCK_Context); |
131 | ctx->cfg = cfg; | 137 | ctx->cfg = cfg; |
132 | GNUNET_PLUGIN_load_all ("libgnunet_plugin_block_", NULL, &add_plugin, ctx); | 138 | GNUNET_PLUGIN_load_all ("libgnunet_plugin_block_", |
139 | (void *) cfg, | ||
140 | &add_plugin, | ||
141 | ctx); | ||
133 | return ctx; | 142 | return ctx; |
134 | } | 143 | } |
135 | 144 | ||
@@ -149,7 +158,8 @@ GNUNET_BLOCK_context_destroy (struct GNUNET_BLOCK_Context *ctx) | |||
149 | { | 158 | { |
150 | plugin = ctx->plugins[i]; | 159 | plugin = ctx->plugins[i]; |
151 | GNUNET_break (NULL == | 160 | GNUNET_break (NULL == |
152 | GNUNET_PLUGIN_unload (plugin->library_name, plugin->api)); | 161 | GNUNET_PLUGIN_unload (plugin->library_name, |
162 | plugin->api)); | ||
153 | GNUNET_free (plugin->library_name); | 163 | GNUNET_free (plugin->library_name); |
154 | GNUNET_free (plugin); | 164 | GNUNET_free (plugin); |
155 | } | 165 | } |
@@ -249,10 +259,9 @@ find_plugin (struct GNUNET_BLOCK_Context *ctx, | |||
249 | enum GNUNET_BLOCK_Type type) | 259 | enum GNUNET_BLOCK_Type type) |
250 | { | 260 | { |
251 | struct Plugin *plugin; | 261 | struct Plugin *plugin; |
252 | unsigned int i; | ||
253 | unsigned int j; | 262 | unsigned int j; |
254 | 263 | ||
255 | for (i = 0; i < ctx->num_plugins; i++) | 264 | for (unsigned i = 0; i < ctx->num_plugins; i++) |
256 | { | 265 | { |
257 | plugin = ctx->plugins[i]; | 266 | plugin = ctx->plugins[i]; |
258 | j = 0; | 267 | j = 0; |
@@ -294,7 +303,8 @@ GNUNET_BLOCK_group_create (struct GNUNET_BLOCK_Context *ctx, | |||
294 | type); | 303 | type); |
295 | if (NULL == plugin->create_group) | 304 | if (NULL == plugin->create_group) |
296 | return NULL; | 305 | return NULL; |
297 | va_start (ap, raw_data_size); | 306 | va_start (ap, |
307 | raw_data_size); | ||
298 | bg = plugin->create_group (plugin->cls, | 308 | bg = plugin->create_group (plugin->cls, |
299 | type, | 309 | type, |
300 | nonce, | 310 | nonce, |
@@ -341,6 +351,7 @@ GNUNET_BLOCK_evaluate (struct GNUNET_BLOCK_Context *ctx, | |||
341 | if (NULL == plugin) | 351 | if (NULL == plugin) |
342 | return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; | 352 | return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; |
343 | return plugin->evaluate (plugin->cls, | 353 | return plugin->evaluate (plugin->cls, |
354 | ctx, | ||
344 | type, | 355 | type, |
345 | group, | 356 | group, |
346 | eo, | 357 | eo, |
@@ -375,7 +386,11 @@ GNUNET_BLOCK_get_key (struct GNUNET_BLOCK_Context *ctx, | |||
375 | 386 | ||
376 | if (plugin == NULL) | 387 | if (plugin == NULL) |
377 | return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; | 388 | return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; |
378 | return plugin->get_key (plugin->cls, type, block, block_size, key); | 389 | return plugin->get_key (plugin->cls, |
390 | type, | ||
391 | block, | ||
392 | block_size, | ||
393 | key); | ||
379 | } | 394 | } |
380 | 395 | ||
381 | 396 | ||
diff --git a/src/block/plugin_block_template.c b/src/block/plugin_block_template.c index 0e8107af2..0105fac38 100644 --- a/src/block/plugin_block_template.c +++ b/src/block/plugin_block_template.c | |||
@@ -63,8 +63,25 @@ block_plugin_template_create_group (void *cls, | |||
63 | size_t raw_data_size, | 63 | size_t raw_data_size, |
64 | va_list va) | 64 | va_list va) |
65 | { | 65 | { |
66 | unsigned int bf_size; | ||
67 | const char *guard; | ||
68 | |||
69 | guard = va_arg (va, const char *); | ||
70 | if (0 == strcmp (guard, | ||
71 | "seen-set-size")) | ||
72 | bf_size = GNUNET_BLOCK_GROUP_compute_bloomfilter_size (va_arg (va, unsigned int), | ||
73 | BLOOMFILTER_K); | ||
74 | else if (0 == strcmp (guard, | ||
75 | "filter-size")) | ||
76 | bf_size = va_arg (va, unsigned int); | ||
77 | else | ||
78 | { | ||
79 | GNUNET_break (0); | ||
80 | bf_size = TEMPLATE_BF_SIZE; | ||
81 | } | ||
82 | GNUNET_break (NULL == va_arg (va, const char *)); | ||
66 | return GNUNET_BLOCK_GROUP_bf_create (cls, | 83 | return GNUNET_BLOCK_GROUP_bf_create (cls, |
67 | TEMPLATE_BF_SIZE, | 84 | bf_size, |
68 | BLOOMFILTER_K, | 85 | BLOOMFILTER_K, |
69 | type, | 86 | type, |
70 | nonce, | 87 | nonce, |
@@ -78,6 +95,7 @@ block_plugin_template_create_group (void *cls, | |||
78 | * request evaluation, simply pass "NULL" for the reply_block. | 95 | * request evaluation, simply pass "NULL" for the reply_block. |
79 | * | 96 | * |
80 | * @param cls closure | 97 | * @param cls closure |
98 | * @param ctx context | ||
81 | * @param type block type | 99 | * @param type block type |
82 | * @param group block group to use | 100 | * @param group block group to use |
83 | * @param eo control flags | 101 | * @param eo control flags |
@@ -90,6 +108,7 @@ block_plugin_template_create_group (void *cls, | |||
90 | */ | 108 | */ |
91 | static enum GNUNET_BLOCK_EvaluationResult | 109 | static enum GNUNET_BLOCK_EvaluationResult |
92 | block_plugin_template_evaluate (void *cls, | 110 | block_plugin_template_evaluate (void *cls, |
111 | struct GNUNET_BLOCK_Context *ctx, | ||
93 | enum GNUNET_BLOCK_Type type, | 112 | enum GNUNET_BLOCK_Type type, |
94 | struct GNUNET_BLOCK_Group *group, | 113 | struct GNUNET_BLOCK_Group *group, |
95 | enum GNUNET_BLOCK_EvaluationOptions eo, | 114 | enum GNUNET_BLOCK_EvaluationOptions eo, |
@@ -138,6 +157,8 @@ block_plugin_template_get_key (void *cls, | |||
138 | 157 | ||
139 | /** | 158 | /** |
140 | * Entry point for the plugin. | 159 | * Entry point for the plugin. |
160 | * | ||
161 | * @param cls a `const struct GNUNET_CONFIGURATION_Handle` | ||
141 | */ | 162 | */ |
142 | void * | 163 | void * |
143 | libgnunet_plugin_block_template_init (void *cls) | 164 | libgnunet_plugin_block_template_init (void *cls) |
@@ -164,7 +185,7 @@ libgnunet_plugin_block_template_init (void *cls) | |||
164 | void * | 185 | void * |
165 | libgnunet_plugin_block_template_done (void *cls) | 186 | libgnunet_plugin_block_template_done (void *cls) |
166 | { | 187 | { |
167 | struct GNUNET_TRANSPORT_PluginFunctions *api = cls; | 188 | struct GNUNET_BLOCK_PluginFunctions *api = cls; |
168 | 189 | ||
169 | GNUNET_free (api); | 190 | GNUNET_free (api); |
170 | return NULL; | 191 | return NULL; |
diff --git a/src/block/plugin_block_test.c b/src/block/plugin_block_test.c index 615f1571b..e359acd7f 100644 --- a/src/block/plugin_block_test.c +++ b/src/block/plugin_block_test.c | |||
@@ -61,8 +61,25 @@ block_plugin_test_create_group (void *cls, | |||
61 | size_t raw_data_size, | 61 | size_t raw_data_size, |
62 | va_list va) | 62 | va_list va) |
63 | { | 63 | { |
64 | unsigned int bf_size; | ||
65 | const char *guard; | ||
66 | |||
67 | guard = va_arg (va, const char *); | ||
68 | if (0 == strcmp (guard, | ||
69 | "seen-set-size")) | ||
70 | bf_size = GNUNET_BLOCK_GROUP_compute_bloomfilter_size (va_arg (va, unsigned int), | ||
71 | BLOOMFILTER_K); | ||
72 | else if (0 == strcmp (guard, | ||
73 | "filter-size")) | ||
74 | bf_size = va_arg (va, unsigned int); | ||
75 | else | ||
76 | { | ||
77 | GNUNET_break (0); | ||
78 | bf_size = TEST_BF_SIZE; | ||
79 | } | ||
80 | GNUNET_break (NULL == va_arg (va, const char *)); | ||
64 | return GNUNET_BLOCK_GROUP_bf_create (cls, | 81 | return GNUNET_BLOCK_GROUP_bf_create (cls, |
65 | TEST_BF_SIZE, | 82 | bf_size, |
66 | BLOOMFILTER_K, | 83 | BLOOMFILTER_K, |
67 | type, | 84 | type, |
68 | nonce, | 85 | nonce, |
@@ -76,6 +93,7 @@ block_plugin_test_create_group (void *cls, | |||
76 | * request evaluation, simply pass "NULL" for the reply_block. | 93 | * request evaluation, simply pass "NULL" for the reply_block. |
77 | * | 94 | * |
78 | * @param cls closure | 95 | * @param cls closure |
96 | * @param ctx block context | ||
79 | * @param type block type | 97 | * @param type block type |
80 | * @param group group to check against | 98 | * @param group group to check against |
81 | * @param eo control flags | 99 | * @param eo control flags |
@@ -88,6 +106,7 @@ block_plugin_test_create_group (void *cls, | |||
88 | */ | 106 | */ |
89 | static enum GNUNET_BLOCK_EvaluationResult | 107 | static enum GNUNET_BLOCK_EvaluationResult |
90 | block_plugin_test_evaluate (void *cls, | 108 | block_plugin_test_evaluate (void *cls, |
109 | struct GNUNET_BLOCK_Context *ctx, | ||
91 | enum GNUNET_BLOCK_Type type, | 110 | enum GNUNET_BLOCK_Type type, |
92 | struct GNUNET_BLOCK_Group *group, | 111 | struct GNUNET_BLOCK_Group *group, |
93 | enum GNUNET_BLOCK_EvaluationOptions eo, | 112 | enum GNUNET_BLOCK_EvaluationOptions eo, |
diff --git a/src/cadet/Makefile.am b/src/cadet/Makefile.am index 3cf92c349..b52079b2e 100644 --- a/src/cadet/Makefile.am +++ b/src/cadet/Makefile.am | |||
@@ -110,13 +110,13 @@ endif | |||
110 | 110 | ||
111 | 111 | ||
112 | if HAVE_TESTING | 112 | if HAVE_TESTING |
113 | noinst_LIBRARIES = libgnunetcadettest.a libgnunetcadettestnew.a $(noinst_LIB_EXP) | 113 | noinst_LTLIBRARIES = libgnunetcadettest.la libgnunetcadettestnew.la $(noinst_LIB_EXP) |
114 | noinst_PROGRAMS = gnunet-cadet-profiler | 114 | noinst_PROGRAMS = gnunet-cadet-profiler |
115 | endif | 115 | endif |
116 | 116 | ||
117 | libgnunetcadettest_a_SOURCES = \ | 117 | libgnunetcadettest_la_SOURCES = \ |
118 | cadet_test_lib.c cadet_test_lib.h | 118 | cadet_test_lib.c cadet_test_lib.h |
119 | libgnunetcadettest_a_LIBADD = \ | 119 | libgnunetcadettest_la_LIBADD = \ |
120 | $(top_builddir)/src/util/libgnunetutil.la \ | 120 | $(top_builddir)/src/util/libgnunetutil.la \ |
121 | $(top_builddir)/src/testbed/libgnunettestbed.la \ | 121 | $(top_builddir)/src/testbed/libgnunettestbed.la \ |
122 | libgnunetcadet.la | 122 | libgnunetcadet.la |
@@ -164,14 +164,14 @@ endif | |||
164 | ld_cadet_test_lib = \ | 164 | ld_cadet_test_lib = \ |
165 | $(top_builddir)/src/util/libgnunetutil.la \ | 165 | $(top_builddir)/src/util/libgnunetutil.la \ |
166 | $(top_builddir)/src/testing/libgnunettesting.la \ | 166 | $(top_builddir)/src/testing/libgnunettesting.la \ |
167 | libgnunetcadettest.a \ | 167 | libgnunetcadettest.la \ |
168 | libgnunetcadet.la \ | 168 | libgnunetcadet.la \ |
169 | $(top_builddir)/src/testbed/libgnunettestbed.la \ | 169 | $(top_builddir)/src/testbed/libgnunettestbed.la \ |
170 | $(top_builddir)/src/statistics/libgnunetstatistics.la | 170 | $(top_builddir)/src/statistics/libgnunetstatistics.la |
171 | 171 | ||
172 | dep_cadet_test_lib = \ | 172 | dep_cadet_test_lib = \ |
173 | libgnunetcadet.la \ | 173 | libgnunetcadet.la \ |
174 | libgnunetcadettest.a \ | 174 | libgnunetcadettest.la \ |
175 | $(top_builddir)/src/statistics/libgnunetstatistics.la | 175 | $(top_builddir)/src/statistics/libgnunetstatistics.la |
176 | 176 | ||
177 | 177 | ||
@@ -263,9 +263,9 @@ test_cadet_5_speed_reliable_backwards_LDADD = $(ld_cadet_test_lib) | |||
263 | 263 | ||
264 | 264 | ||
265 | # NEW TESTS | 265 | # NEW TESTS |
266 | libgnunetcadettestnew_a_SOURCES = \ | 266 | libgnunetcadettestnew_la_SOURCES = \ |
267 | cadet_test_lib_new.c cadet_test_lib_new.h | 267 | cadet_test_lib_new.c cadet_test_lib_new.h |
268 | libgnunetcadettestnew_a_LIBADD = \ | 268 | libgnunetcadettestnew_la_LIBADD = \ |
269 | $(top_builddir)/src/util/libgnunetutil.la \ | 269 | $(top_builddir)/src/util/libgnunetutil.la \ |
270 | $(top_builddir)/src/testbed/libgnunettestbed.la \ | 270 | $(top_builddir)/src/testbed/libgnunettestbed.la \ |
271 | libgnunetcadetnew.la | 271 | libgnunetcadetnew.la |
@@ -274,12 +274,12 @@ ld_cadet_test_lib_new = \ | |||
274 | $(top_builddir)/src/util/libgnunetutil.la \ | 274 | $(top_builddir)/src/util/libgnunetutil.la \ |
275 | $(top_builddir)/src/testing/libgnunettesting.la \ | 275 | $(top_builddir)/src/testing/libgnunettesting.la \ |
276 | libgnunetcadetnew.la \ | 276 | libgnunetcadetnew.la \ |
277 | libgnunetcadettestnew.a \ | 277 | libgnunetcadettestnew.la \ |
278 | $(top_builddir)/src/testbed/libgnunettestbed.la \ | 278 | $(top_builddir)/src/testbed/libgnunettestbed.la \ |
279 | $(top_builddir)/src/statistics/libgnunetstatistics.la | 279 | $(top_builddir)/src/statistics/libgnunetstatistics.la |
280 | dep_cadet_test_lib_new = \ | 280 | dep_cadet_test_lib_new = \ |
281 | libgnunetcadetnew.la \ | 281 | libgnunetcadetnew.la \ |
282 | libgnunetcadettestnew.a \ | 282 | libgnunetcadettestnew.la \ |
283 | $(top_builddir)/src/statistics/libgnunetstatistics.la | 283 | $(top_builddir)/src/statistics/libgnunetstatistics.la |
284 | 284 | ||
285 | test_cadet_2_forward_new_SOURCES = \ | 285 | test_cadet_2_forward_new_SOURCES = \ |
diff --git a/src/cadet/cadet_api_new.c b/src/cadet/cadet_api_new.c index a62de0a47..2d5d853b3 100644 --- a/src/cadet/cadet_api_new.c +++ b/src/cadet/cadet_api_new.c | |||
@@ -626,7 +626,6 @@ handle_channel_created (void *cls, | |||
626 | struct GNUNET_CADET_LocalChannelDestroyMessage *d_msg; | 626 | struct GNUNET_CADET_LocalChannelDestroyMessage *d_msg; |
627 | struct GNUNET_MQ_Envelope *env; | 627 | struct GNUNET_MQ_Envelope *env; |
628 | 628 | ||
629 | GNUNET_break (0); | ||
630 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 629 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
631 | "No handler for incoming channel %X (on port %s, recently closed?)\n", | 630 | "No handler for incoming channel %X (on port %s, recently closed?)\n", |
632 | ntohl (ccn.channel_of_client), | 631 | ntohl (ccn.channel_of_client), |
@@ -682,16 +681,18 @@ handle_channel_destroy (void *cls, | |||
682 | struct GNUNET_CADET_Handle *h = cls; | 681 | struct GNUNET_CADET_Handle *h = cls; |
683 | struct GNUNET_CADET_Channel *ch; | 682 | struct GNUNET_CADET_Channel *ch; |
684 | 683 | ||
685 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
686 | "Received channel destroy for channel %X from CADET service\n", | ||
687 | ntohl (msg->ccn.channel_of_client)); | ||
688 | ch = find_channel (h, | 684 | ch = find_channel (h, |
689 | msg->ccn); | 685 | msg->ccn); |
690 | if (NULL == ch) | 686 | if (NULL == ch) |
691 | { | 687 | { |
692 | GNUNET_break (0); | 688 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
689 | "Received channel destroy for unknown channel %X from CADET service (recently close?)\n", | ||
690 | ntohl (msg->ccn.channel_of_client)); | ||
693 | return; | 691 | return; |
694 | } | 692 | } |
693 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
694 | "Received channel destroy for channel %X from CADET service\n", | ||
695 | ntohl (msg->ccn.channel_of_client)); | ||
695 | destroy_channel (ch); | 696 | destroy_channel (ch); |
696 | } | 697 | } |
697 | 698 | ||
@@ -708,8 +709,6 @@ static int | |||
708 | check_local_data (void *cls, | 709 | check_local_data (void *cls, |
709 | const struct GNUNET_CADET_LocalData *message) | 710 | const struct GNUNET_CADET_LocalData *message) |
710 | { | 711 | { |
711 | struct GNUNET_CADET_Handle *h = cls; | ||
712 | struct GNUNET_CADET_Channel *ch; | ||
713 | uint16_t size; | 712 | uint16_t size; |
714 | 713 | ||
715 | size = ntohs (message->header.size); | 714 | size = ntohs (message->header.size); |
@@ -718,15 +717,6 @@ check_local_data (void *cls, | |||
718 | GNUNET_break (0); | 717 | GNUNET_break (0); |
719 | return GNUNET_SYSERR; | 718 | return GNUNET_SYSERR; |
720 | } | 719 | } |
721 | |||
722 | ch = find_channel (h, | ||
723 | message->ccn); | ||
724 | if (NULL == ch) | ||
725 | { | ||
726 | GNUNET_break (0); | ||
727 | return GNUNET_SYSERR; | ||
728 | } | ||
729 | |||
730 | return GNUNET_OK; | 720 | return GNUNET_OK; |
731 | } | 721 | } |
732 | 722 | ||
@@ -751,8 +741,9 @@ handle_local_data (void *cls, | |||
751 | message->ccn); | 741 | message->ccn); |
752 | if (NULL == ch) | 742 | if (NULL == ch) |
753 | { | 743 | { |
754 | GNUNET_break (0); | 744 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
755 | reconnect (h); | 745 | "Unknown channel %X for incoming data (recently closed?)\n", |
746 | ntohl (message->ccn.channel_of_client)); | ||
756 | return; | 747 | return; |
757 | } | 748 | } |
758 | 749 | ||
diff --git a/src/cadet/gnunet-cadet-profiler.c b/src/cadet/gnunet-cadet-profiler.c index d688dc60b..15da05b6d 100644 --- a/src/cadet/gnunet-cadet-profiler.c +++ b/src/cadet/gnunet-cadet-profiler.c | |||
@@ -778,7 +778,9 @@ pong_handler (void *cls, struct GNUNET_CADET_Channel *channel, | |||
778 | latency = GNUNET_TIME_absolute_get_duration (send_time); | 778 | latency = GNUNET_TIME_absolute_get_duration (send_time); |
779 | r = ntohl (msg->round_number); | 779 | r = ntohl (msg->round_number); |
780 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "%u <- %u (%u) latency: %s\n", | 780 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "%u <- %u (%u) latency: %s\n", |
781 | get_index (peer), get_index (peer->dest), ntohl (msg->counter), | 781 | get_index (peer), |
782 | get_index (peer->dest), | ||
783 | (uint32_t) ntohl (msg->counter), | ||
782 | GNUNET_STRINGS_relative_time_to_string (latency, GNUNET_NO)); | 784 | GNUNET_STRINGS_relative_time_to_string (latency, GNUNET_NO)); |
783 | 785 | ||
784 | /* Online variance calculation */ | 786 | /* Online variance calculation */ |
diff --git a/src/cadet/gnunet-service-cadet-new.c b/src/cadet/gnunet-service-cadet-new.c index a9b30ccd5..93f53de4c 100644 --- a/src/cadet/gnunet-service-cadet-new.c +++ b/src/cadet/gnunet-service-cadet-new.c | |||
@@ -306,8 +306,8 @@ GSC_bind (struct CadetClient *c, | |||
306 | GCCH_2s (ch), | 306 | GCCH_2s (ch), |
307 | GCP_2s (dest), | 307 | GCP_2s (dest), |
308 | GNUNET_h2s (port), | 308 | GNUNET_h2s (port), |
309 | ntohl (options), | 309 | (uint32_t) ntohl (options), |
310 | ntohl (ccn.channel_of_client)); | 310 | (uint32_t) ntohl (ccn.channel_of_client)); |
311 | /* notify local client about incoming connection! */ | 311 | /* notify local client about incoming connection! */ |
312 | env = GNUNET_MQ_msg (cm, | 312 | env = GNUNET_MQ_msg (cm, |
313 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE); | 313 | GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE); |
@@ -622,7 +622,7 @@ handle_channel_destroy (void *cls, | |||
622 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 622 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
623 | "%s tried to destroy unknown channel %X\n", | 623 | "%s tried to destroy unknown channel %X\n", |
624 | GSC_2s(c), | 624 | GSC_2s(c), |
625 | ntohl (msg->ccn.channel_of_client)); | 625 | (uint32_t) ntohl (msg->ccn.channel_of_client)); |
626 | return; | 626 | return; |
627 | } | 627 | } |
628 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 628 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
@@ -716,12 +716,18 @@ handle_local_data (void *cls, | |||
716 | msg->ccn); | 716 | msg->ccn); |
717 | if (NULL == ch) | 717 | if (NULL == ch) |
718 | { | 718 | { |
719 | /* Channel does not exist! */ | 719 | /* Channel does not exist (anymore) */ |
720 | GNUNET_break (0); | 720 | LOG (GNUNET_ERROR_TYPE_WARNING, |
721 | GNUNET_SERVICE_client_drop (c->client); | 721 | "Dropping payload for channel %u from client (channel unknown, other endpoint may have disconnected)\n", |
722 | (unsigned int) ntohl (msg->ccn.channel_of_client)); | ||
723 | GNUNET_SERVICE_client_continue (c->client); | ||
722 | return; | 724 | return; |
723 | } | 725 | } |
724 | payload_size = ntohs (msg->header.size) - sizeof (*msg); | 726 | payload_size = ntohs (msg->header.size) - sizeof (*msg); |
727 | GNUNET_STATISTICS_update (stats, | ||
728 | "# payload received from clients", | ||
729 | payload_size, | ||
730 | GNUNET_NO); | ||
725 | buf = (const char *) &msg[1]; | 731 | buf = (const char *) &msg[1]; |
726 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 732 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
727 | "Received %u bytes payload from %s for %s\n", | 733 | "Received %u bytes payload from %s for %s\n", |
@@ -758,9 +764,11 @@ handle_local_ack (void *cls, | |||
758 | msg->ccn); | 764 | msg->ccn); |
759 | if (NULL == ch) | 765 | if (NULL == ch) |
760 | { | 766 | { |
761 | /* Channel does not exist! */ | 767 | /* Channel does not exist (anymore) */ |
762 | GNUNET_break (0); | 768 | LOG (GNUNET_ERROR_TYPE_WARNING, |
763 | GNUNET_SERVICE_client_drop (c->client); | 769 | "Ignoring local ACK for channel %u from client (channel unknown, other endpoint may have disconnected)\n", |
770 | (unsigned int) ntohl (msg->ccn.channel_of_client)); | ||
771 | GNUNET_SERVICE_client_continue (c->client); | ||
764 | return; | 772 | return; |
765 | } | 773 | } |
766 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 774 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
diff --git a/src/cadet/gnunet-service-cadet-new_channel.c b/src/cadet/gnunet-service-cadet-new_channel.c index c418893a8..8769601c2 100644 --- a/src/cadet/gnunet-service-cadet-new_channel.c +++ b/src/cadet/gnunet-service-cadet-new_channel.c | |||
@@ -1618,7 +1618,8 @@ GCCH_handle_remote_destroy (struct CadetChannel *ch, | |||
1618 | return; | 1618 | return; |
1619 | } | 1619 | } |
1620 | ccc = (NULL != ch->owner) ? ch->owner : ch->dest; | 1620 | ccc = (NULL != ch->owner) ? ch->owner : ch->dest; |
1621 | if (NULL != ccc->head_recv) | 1621 | if ( (NULL != ccc) && |
1622 | (NULL != ccc->head_recv) ) | ||
1622 | { | 1623 | { |
1623 | LOG (GNUNET_ERROR_TYPE_WARNING, | 1624 | LOG (GNUNET_ERROR_TYPE_WARNING, |
1624 | "Lost end of transmission due to remote shutdown on %s\n", | 1625 | "Lost end of transmission due to remote shutdown on %s\n", |
@@ -1626,9 +1627,10 @@ GCCH_handle_remote_destroy (struct CadetChannel *ch, | |||
1626 | /* FIXME: change API to notify client about truncated transmission! */ | 1627 | /* FIXME: change API to notify client about truncated transmission! */ |
1627 | } | 1628 | } |
1628 | ch->destroy = GNUNET_YES; | 1629 | ch->destroy = GNUNET_YES; |
1629 | GSC_handle_remote_channel_destroy (ccc->c, | 1630 | if (NULL != ccc) |
1630 | ccc->ccn, | 1631 | GSC_handle_remote_channel_destroy (ccc->c, |
1631 | ch); | 1632 | ccc->ccn, |
1633 | ch); | ||
1632 | channel_destroy (ch); | 1634 | channel_destroy (ch); |
1633 | } | 1635 | } |
1634 | 1636 | ||
diff --git a/src/cadet/gnunet-service-cadet-new_peer.c b/src/cadet/gnunet-service-cadet-new_peer.c index 7b944afd8..350c8efae 100644 --- a/src/cadet/gnunet-service-cadet-new_peer.c +++ b/src/cadet/gnunet-service-cadet-new_peer.c | |||
@@ -157,9 +157,9 @@ struct CadetPeer | |||
157 | struct GCD_search_handle *search_h; | 157 | struct GCD_search_handle *search_h; |
158 | 158 | ||
159 | /** | 159 | /** |
160 | * Task to stop the DHT search for paths to this peer | 160 | * Task to clean up @e path_heap asynchronously. |
161 | */ | 161 | */ |
162 | struct GNUNET_SCHEDULER_Task *search_delayedXXX; | 162 | struct GNUNET_SCHEDULER_Task *heap_cleanup_task; |
163 | 163 | ||
164 | /** | 164 | /** |
165 | * Task to destroy this entry. | 165 | * Task to destroy this entry. |
@@ -361,6 +361,11 @@ destroy_peer (void *cls) | |||
361 | GNUNET_CONTAINER_heap_destroy (cp->path_heap); | 361 | GNUNET_CONTAINER_heap_destroy (cp->path_heap); |
362 | cp->path_heap = NULL; | 362 | cp->path_heap = NULL; |
363 | } | 363 | } |
364 | if (NULL != cp->heap_cleanup_task) | ||
365 | { | ||
366 | GNUNET_SCHEDULER_cancel (cp->heap_cleanup_task); | ||
367 | cp->heap_cleanup_task = NULL; | ||
368 | } | ||
364 | GNUNET_free_non_null (cp->hello); | 369 | GNUNET_free_non_null (cp->hello); |
365 | /* Peer should not be freed if paths exist; if there are no paths, | 370 | /* Peer should not be freed if paths exist; if there are no paths, |
366 | there ought to be no connections, and without connections, no | 371 | there ought to be no connections, and without connections, no |
@@ -892,6 +897,41 @@ GCP_path_entry_remove (struct CadetPeer *cp, | |||
892 | 897 | ||
893 | 898 | ||
894 | /** | 899 | /** |
900 | * Prune down the number of paths to this peer, we seem to | ||
901 | * have way too many. | ||
902 | * | ||
903 | * @param cls the `struct CadetPeer` to maintain the path heap for | ||
904 | */ | ||
905 | static void | ||
906 | path_heap_cleanup (void *cls) | ||
907 | { | ||
908 | struct CadetPeer *cp = cls; | ||
909 | struct CadetPeerPath *root; | ||
910 | |||
911 | cp->heap_cleanup_task = NULL; | ||
912 | while (GNUNET_CONTAINER_heap_get_size (cp->path_heap) >= | ||
913 | 2 * DESIRED_CONNECTIONS_PER_TUNNEL) | ||
914 | { | ||
915 | /* Now we have way too many, drop least desirable UNLESS it is in use! | ||
916 | (Note that this intentionally keeps highly desireable, but currently | ||
917 | unused paths around in the hope that we might be able to switch, even | ||
918 | if the number of paths exceeds the threshold.) */ | ||
919 | root = GNUNET_CONTAINER_heap_peek (cp->path_heap); | ||
920 | if (NULL != | ||
921 | GCPP_get_connection (root, | ||
922 | cp, | ||
923 | GCPP_get_length (root) - 1)) | ||
924 | break; /* can't fix */ | ||
925 | /* Got plenty of paths to this destination, and this is a low-quality | ||
926 | one that we don't care about. Allow it to die. */ | ||
927 | GNUNET_assert (root == | ||
928 | GNUNET_CONTAINER_heap_remove_root (cp->path_heap)); | ||
929 | GCPP_release (root); | ||
930 | } | ||
931 | } | ||
932 | |||
933 | |||
934 | /** | ||
895 | * Try adding a @a path to this @a peer. If the peer already | 935 | * Try adding a @a path to this @a peer. If the peer already |
896 | * has plenty of paths, return NULL. | 936 | * has plenty of paths, return NULL. |
897 | * | 937 | * |
@@ -958,27 +998,11 @@ GCP_attach_path (struct CadetPeer *cp, | |||
958 | desirability); | 998 | desirability); |
959 | 999 | ||
960 | /* Consider maybe dropping other paths because of the new one */ | 1000 | /* Consider maybe dropping other paths because of the new one */ |
961 | if (GNUNET_CONTAINER_heap_get_size (cp->path_heap) >= | 1001 | if ( (GNUNET_CONTAINER_heap_get_size (cp->path_heap) >= |
962 | 2 * DESIRED_CONNECTIONS_PER_TUNNEL) | 1002 | 2 * DESIRED_CONNECTIONS_PER_TUNNEL) && |
963 | { | 1003 | (NULL != cp->heap_cleanup_task) ) |
964 | /* Now we have way too many, drop least desirable UNLESS it is in use! | 1004 | cp->heap_cleanup_task = GNUNET_SCHEDULER_add_now (&path_heap_cleanup, |
965 | (Note that this intentionally keeps highly desireable, but currently | 1005 | cp); |
966 | unused paths around in the hope that we might be able to switch, even | ||
967 | if the number of paths exceeds the threshold.) */ | ||
968 | root = GNUNET_CONTAINER_heap_peek (cp->path_heap); | ||
969 | if ( (path != root) && | ||
970 | (NULL == | ||
971 | GCPP_get_connection (root, | ||
972 | cp, | ||
973 | GCPP_get_length (root) - 1)) ) | ||
974 | { | ||
975 | /* Got plenty of paths to this destination, and this is a low-quality | ||
976 | one that we don't care about. Allow it to die. */ | ||
977 | GNUNET_assert (root == | ||
978 | GNUNET_CONTAINER_heap_remove_root (cp->path_heap)); | ||
979 | GCPP_release (root); | ||
980 | } | ||
981 | } | ||
982 | return hn; | 1006 | return hn; |
983 | } | 1007 | } |
984 | 1008 | ||
diff --git a/src/cadet/gnunet-service-cadet-new_tunnels.c b/src/cadet/gnunet-service-cadet-new_tunnels.c index ed3a3a362..d50860629 100644 --- a/src/cadet/gnunet-service-cadet-new_tunnels.c +++ b/src/cadet/gnunet-service-cadet-new_tunnels.c | |||
@@ -603,7 +603,11 @@ GCT_count_any_connections (const struct CadetTunnel *t) | |||
603 | static struct CadetTConnection * | 603 | static struct CadetTConnection * |
604 | get_ready_connection (struct CadetTunnel *t) | 604 | get_ready_connection (struct CadetTunnel *t) |
605 | { | 605 | { |
606 | return t->connection_ready_head; | 606 | struct CadetTConnection *hd = t->connection_ready_head; |
607 | |||
608 | GNUNET_assert ( (NULL == hd) || | ||
609 | (GNUNET_YES == hd->is_ready) ); | ||
610 | return hd; | ||
607 | } | 611 | } |
608 | 612 | ||
609 | 613 | ||
@@ -1315,7 +1319,8 @@ send_kx (struct CadetTunnel *t, | |||
1315 | struct GNUNET_CADET_TunnelKeyExchangeMessage *msg; | 1319 | struct GNUNET_CADET_TunnelKeyExchangeMessage *msg; |
1316 | enum GNUNET_CADET_KX_Flags flags; | 1320 | enum GNUNET_CADET_KX_Flags flags; |
1317 | 1321 | ||
1318 | if (NULL == ct) | 1322 | if ( (NULL == ct) || |
1323 | (GNUNET_NO == ct->is_ready) ) | ||
1319 | ct = get_ready_connection (t); | 1324 | ct = get_ready_connection (t); |
1320 | if (NULL == ct) | 1325 | if (NULL == ct) |
1321 | { | 1326 | { |
@@ -1820,9 +1825,12 @@ GCT_handle_kx_auth (struct CadetTConnection *ct, | |||
1820 | { | 1825 | { |
1821 | /* This KX_AUTH is not using the latest KX/KX_AUTH data | 1826 | /* This KX_AUTH is not using the latest KX/KX_AUTH data |
1822 | we transmitted to the sender, refuse it, try KX again. */ | 1827 | we transmitted to the sender, refuse it, try KX again. */ |
1823 | GNUNET_break_op (0); | 1828 | GNUNET_STATISTICS_update (stats, |
1829 | "# KX_AUTH not using our last KX received (auth failure)", | ||
1830 | 1, | ||
1831 | GNUNET_NO); | ||
1824 | send_kx (t, | 1832 | send_kx (t, |
1825 | NULL, | 1833 | ct, |
1826 | &t->ax); | 1834 | &t->ax); |
1827 | return; | 1835 | return; |
1828 | } | 1836 | } |
@@ -1968,13 +1976,19 @@ GCT_connection_lost (struct CadetTConnection *ct) | |||
1968 | struct CadetTunnel *t = ct->t; | 1976 | struct CadetTunnel *t = ct->t; |
1969 | 1977 | ||
1970 | if (GNUNET_YES == ct->is_ready) | 1978 | if (GNUNET_YES == ct->is_ready) |
1979 | { | ||
1971 | GNUNET_CONTAINER_DLL_remove (t->connection_ready_head, | 1980 | GNUNET_CONTAINER_DLL_remove (t->connection_ready_head, |
1972 | t->connection_ready_tail, | 1981 | t->connection_ready_tail, |
1973 | ct); | 1982 | ct); |
1983 | t->num_ready_connections--; | ||
1984 | } | ||
1974 | else | 1985 | else |
1986 | { | ||
1975 | GNUNET_CONTAINER_DLL_remove (t->connection_busy_head, | 1987 | GNUNET_CONTAINER_DLL_remove (t->connection_busy_head, |
1976 | t->connection_busy_tail, | 1988 | t->connection_busy_tail, |
1977 | ct); | 1989 | ct); |
1990 | t->num_busy_connections--; | ||
1991 | } | ||
1978 | GNUNET_free (ct); | 1992 | GNUNET_free (ct); |
1979 | } | 1993 | } |
1980 | 1994 | ||
@@ -3068,10 +3082,6 @@ GCT_handle_encrypted (struct CadetTConnection *ct, | |||
3068 | break; | 3082 | break; |
3069 | } | 3083 | } |
3070 | 3084 | ||
3071 | GNUNET_STATISTICS_update (stats, | ||
3072 | "# received encrypted", | ||
3073 | 1, | ||
3074 | GNUNET_NO); | ||
3075 | decrypted_size = -1; | 3085 | decrypted_size = -1; |
3076 | if (CADET_TUNNEL_KEY_OK == t->estate) | 3086 | if (CADET_TUNNEL_KEY_OK == t->estate) |
3077 | { | 3087 | { |
@@ -3152,6 +3162,10 @@ GCT_handle_encrypted (struct CadetTConnection *ct, | |||
3152 | &t->ax); | 3162 | &t->ax); |
3153 | return; | 3163 | return; |
3154 | } | 3164 | } |
3165 | GNUNET_STATISTICS_update (stats, | ||
3166 | "# decrypted bytes", | ||
3167 | decrypted_size, | ||
3168 | GNUNET_NO); | ||
3155 | 3169 | ||
3156 | /* The MST will ultimately call #handle_decrypted() on each message. */ | 3170 | /* The MST will ultimately call #handle_decrypted() on each message. */ |
3157 | t->current_ct = ct; | 3171 | t->current_ct = ct; |
@@ -3203,6 +3217,10 @@ GCT_send (struct CadetTunnel *t, | |||
3203 | &ax_msg[1], | 3217 | &ax_msg[1], |
3204 | message, | 3218 | message, |
3205 | payload_size); | 3219 | payload_size); |
3220 | GNUNET_STATISTICS_update (stats, | ||
3221 | "# encrypted bytes", | ||
3222 | payload_size, | ||
3223 | GNUNET_NO); | ||
3206 | ax_msg->ax_header.Ns = htonl (t->ax.Ns++); | 3224 | ax_msg->ax_header.Ns = htonl (t->ax.Ns++); |
3207 | ax_msg->ax_header.PNs = htonl (t->ax.PNs); | 3225 | ax_msg->ax_header.PNs = htonl (t->ax.PNs); |
3208 | /* FIXME: we should do this once, not once per message; | 3226 | /* FIXME: we should do this once, not once per message; |
diff --git a/src/consensus/.gitignore b/src/consensus/.gitignore index cc81511f9..d49147d17 100644 --- a/src/consensus/.gitignore +++ b/src/consensus/.gitignore | |||
@@ -2,3 +2,4 @@ gnunet-service-evil-consensus | |||
2 | gnunet-consensus-profiler | 2 | gnunet-consensus-profiler |
3 | gnunet-service-consensus | 3 | gnunet-service-consensus |
4 | test_consensus_api | 4 | test_consensus_api |
5 | resource.log.master | ||
diff --git a/src/consensus/Makefile.am b/src/consensus/Makefile.am index c04d4c207..2b1987fbc 100644 --- a/src/consensus/Makefile.am +++ b/src/consensus/Makefile.am | |||
@@ -5,6 +5,8 @@ pkgcfgdir= $(pkgdatadir)/config.d/ | |||
5 | 5 | ||
6 | libexecdir= $(pkglibdir)/libexec/ | 6 | libexecdir= $(pkglibdir)/libexec/ |
7 | 7 | ||
8 | plugindir = $(libdir)/gnunet | ||
9 | |||
8 | pkgcfg_DATA = \ | 10 | pkgcfg_DATA = \ |
9 | consensus.conf | 11 | consensus.conf |
10 | 12 | ||
@@ -67,6 +69,23 @@ libgnunetconsensus_la_LIBADD = \ | |||
67 | libgnunetconsensus_la_LDFLAGS = \ | 69 | libgnunetconsensus_la_LDFLAGS = \ |
68 | $(GN_LIB_LDFLAGS) | 70 | $(GN_LIB_LDFLAGS) |
69 | 71 | ||
72 | |||
73 | plugin_LTLIBRARIES = \ | ||
74 | libgnunet_plugin_block_consensus.la | ||
75 | |||
76 | libgnunet_plugin_block_consensus_la_SOURCES = \ | ||
77 | plugin_block_consensus.c | ||
78 | libgnunet_plugin_block_consensus_la_LIBADD = \ | ||
79 | $(top_builddir)/src/block/libgnunetblock.la \ | ||
80 | $(top_builddir)/src/block/libgnunetblockgroup.la \ | ||
81 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
82 | $(LTLIBINTL) | ||
83 | libgnunet_plugin_block_consensus_la_LDFLAGS = \ | ||
84 | $(GN_PLUGIN_LDFLAGS) | ||
85 | |||
86 | |||
87 | |||
88 | if HAVE_TESTING | ||
70 | check_PROGRAMS = \ | 89 | check_PROGRAMS = \ |
71 | test_consensus_api | 90 | test_consensus_api |
72 | 91 | ||
@@ -74,6 +93,7 @@ if ENABLE_TEST_RUN | |||
74 | AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; | 93 | AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; |
75 | TESTS = $(check_PROGRAMS) | 94 | TESTS = $(check_PROGRAMS) |
76 | endif | 95 | endif |
96 | endif | ||
77 | 97 | ||
78 | test_consensus_api_SOURCES = \ | 98 | test_consensus_api_SOURCES = \ |
79 | test_consensus_api.c | 99 | test_consensus_api.c |
diff --git a/src/consensus/consensus_protocol.h b/src/consensus/consensus_protocol.h index fb3bde628..e0002de56 100644 --- a/src/consensus/consensus_protocol.h +++ b/src/consensus/consensus_protocol.h | |||
@@ -29,6 +29,7 @@ | |||
29 | #define GNUNET_CONSENSUS_PROTOCOL_H | 29 | #define GNUNET_CONSENSUS_PROTOCOL_H |
30 | 30 | ||
31 | #include "platform.h" | 31 | #include "platform.h" |
32 | #include "gnunet_util_lib.h" | ||
32 | #include "gnunet_common.h" | 33 | #include "gnunet_common.h" |
33 | #include "gnunet_protocols.h" | 34 | #include "gnunet_protocols.h" |
34 | 35 | ||
@@ -87,6 +88,48 @@ struct GNUNET_CONSENSUS_RoundContextMessage | |||
87 | uint16_t is_contested; | 88 | uint16_t is_contested; |
88 | }; | 89 | }; |
89 | 90 | ||
91 | |||
92 | enum { | ||
93 | CONSENSUS_MARKER_CONTESTED = 1, | ||
94 | CONSENSUS_MARKER_SIZE = 2, | ||
95 | }; | ||
96 | |||
97 | |||
98 | /** | ||
99 | * Consensus element, either marker or payload. | ||
100 | */ | ||
101 | struct ConsensusElement | ||
102 | { | ||
103 | /** | ||
104 | * Payload element_type, only valid | ||
105 | * if this is not a marker element. | ||
106 | */ | ||
107 | uint16_t payload_type; | ||
108 | |||
109 | /** | ||
110 | * Is this a marker element? | ||
111 | */ | ||
112 | uint8_t marker; | ||
113 | |||
114 | /* rest: element data */ | ||
115 | }; | ||
116 | |||
117 | |||
118 | struct ConsensusSizeElement | ||
119 | { | ||
120 | struct ConsensusElement ce GNUNET_PACKED; | ||
121 | |||
122 | uint64_t size GNUNET_PACKED; | ||
123 | uint8_t sender_index; | ||
124 | }; | ||
125 | |||
126 | struct ConsensusStuffedElement | ||
127 | { | ||
128 | struct ConsensusElement ce GNUNET_PACKED; | ||
129 | struct GNUNET_HashCode rand GNUNET_PACKED; | ||
130 | }; | ||
131 | |||
132 | |||
90 | GNUNET_NETWORK_STRUCT_END | 133 | GNUNET_NETWORK_STRUCT_END |
91 | 134 | ||
92 | #endif | 135 | #endif |
diff --git a/src/consensus/gnunet-consensus-profiler.c b/src/consensus/gnunet-consensus-profiler.c index 290263d95..65542f4cd 100644 --- a/src/consensus/gnunet-consensus-profiler.c +++ b/src/consensus/gnunet-consensus-profiler.c | |||
@@ -55,6 +55,8 @@ static struct GNUNET_HashCode session_id; | |||
55 | 55 | ||
56 | static unsigned int peers_done = 0; | 56 | static unsigned int peers_done = 0; |
57 | 57 | ||
58 | static int dist_static; | ||
59 | |||
58 | static unsigned *results_for_peer; | 60 | static unsigned *results_for_peer; |
59 | 61 | ||
60 | /** | 62 | /** |
@@ -217,26 +219,45 @@ do_consensus () | |||
217 | { | 219 | { |
218 | int unique_indices[replication]; | 220 | int unique_indices[replication]; |
219 | unsigned int i; | 221 | unsigned int i; |
222 | unsigned int j; | ||
223 | struct GNUNET_HashCode val; | ||
224 | struct GNUNET_SET_Element element; | ||
220 | 225 | ||
221 | for (i = 0; i < num_values; i++) | 226 | if (dist_static) |
222 | { | 227 | { |
223 | unsigned int j; | 228 | for (i = 0; i < num_values; i++) |
224 | struct GNUNET_HashCode val; | 229 | { |
225 | struct GNUNET_SET_Element element; | ||
226 | 230 | ||
227 | generate_indices (unique_indices); | 231 | GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, &val); |
228 | GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, &val); | ||
229 | 232 | ||
230 | element.data = &val; | 233 | element.data = &val; |
231 | element.size = sizeof (val); | 234 | element.size = sizeof (val); |
232 | for (j = 0; j < replication; j++) | 235 | for (j = 0; j < replication; j++) |
236 | { | ||
237 | GNUNET_CONSENSUS_insert (consensus_handles[j], | ||
238 | &element, | ||
239 | NULL, NULL); | ||
240 | } | ||
241 | } | ||
242 | } | ||
243 | else | ||
244 | { | ||
245 | for (i = 0; i < num_values; i++) | ||
233 | { | 246 | { |
234 | int cid; | 247 | generate_indices (unique_indices); |
248 | GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, &val); | ||
235 | 249 | ||
236 | cid = unique_indices[j]; | 250 | element.data = &val; |
237 | GNUNET_CONSENSUS_insert (consensus_handles[cid], | 251 | element.size = sizeof (val); |
238 | &element, | 252 | for (j = 0; j < replication; j++) |
239 | NULL, NULL); | 253 | { |
254 | int cid; | ||
255 | |||
256 | cid = unique_indices[j]; | ||
257 | GNUNET_CONSENSUS_insert (consensus_handles[cid], | ||
258 | &element, | ||
259 | NULL, NULL); | ||
260 | } | ||
240 | } | 261 | } |
241 | } | 262 | } |
242 | 263 | ||
@@ -513,6 +534,9 @@ main (int argc, char **argv) | |||
513 | { 's', "statistics", NULL, | 534 | { 's', "statistics", NULL, |
514 | gettext_noop ("write statistics to file"), | 535 | gettext_noop ("write statistics to file"), |
515 | GNUNET_YES, &GNUNET_GETOPT_set_filename, &statistics_filename }, | 536 | GNUNET_YES, &GNUNET_GETOPT_set_filename, &statistics_filename }, |
537 | { 'S', "dist-static", NULL, | ||
538 | gettext_noop ("distribute elements to a static subset of good peers"), | ||
539 | GNUNET_YES, &GNUNET_GETOPT_set_one, &dist_static }, | ||
516 | { 'V', "verbose", NULL, | 540 | { 'V', "verbose", NULL, |
517 | gettext_noop ("be more verbose (print received values)"), | 541 | gettext_noop ("be more verbose (print received values)"), |
518 | GNUNET_NO, &GNUNET_GETOPT_set_one, &verbose }, | 542 | GNUNET_NO, &GNUNET_GETOPT_set_one, &verbose }, |
diff --git a/src/consensus/gnunet-service-consensus.c b/src/consensus/gnunet-service-consensus.c index 16ca6a57f..b934f468f 100644 --- a/src/consensus/gnunet-service-consensus.c +++ b/src/consensus/gnunet-service-consensus.c | |||
@@ -26,6 +26,7 @@ | |||
26 | 26 | ||
27 | #include "platform.h" | 27 | #include "platform.h" |
28 | #include "gnunet_util_lib.h" | 28 | #include "gnunet_util_lib.h" |
29 | #include "gnunet_block_lib.h" | ||
29 | #include "gnunet_protocols.h" | 30 | #include "gnunet_protocols.h" |
30 | #include "gnunet_applications.h" | 31 | #include "gnunet_applications.h" |
31 | #include "gnunet_set_service.h" | 32 | #include "gnunet_set_service.h" |
@@ -34,8 +35,6 @@ | |||
34 | #include "consensus_protocol.h" | 35 | #include "consensus_protocol.h" |
35 | #include "consensus.h" | 36 | #include "consensus.h" |
36 | 37 | ||
37 | #define ELEMENT_TYPE_CONTESTED_MARKER (GNUNET_CONSENSUS_ELEMENT_TYPE_USER_MAX + 1) | ||
38 | |||
39 | 38 | ||
40 | enum ReferendumVote | 39 | enum ReferendumVote |
41 | { | 40 | { |
@@ -65,11 +64,6 @@ enum EarlyStoppingPhase | |||
65 | 64 | ||
66 | GNUNET_NETWORK_STRUCT_BEGIN | 65 | GNUNET_NETWORK_STRUCT_BEGIN |
67 | 66 | ||
68 | |||
69 | struct ContestedPayload | ||
70 | { | ||
71 | }; | ||
72 | |||
73 | /** | 67 | /** |
74 | * Tuple of integers that together | 68 | * Tuple of integers that together |
75 | * identify a task uniquely. | 69 | * identify a task uniquely. |
@@ -147,6 +141,7 @@ GNUNET_NETWORK_STRUCT_END | |||
147 | enum PhaseKind | 141 | enum PhaseKind |
148 | { | 142 | { |
149 | PHASE_KIND_ALL_TO_ALL, | 143 | PHASE_KIND_ALL_TO_ALL, |
144 | PHASE_KIND_ALL_TO_ALL_2, | ||
150 | PHASE_KIND_GRADECAST_LEADER, | 145 | PHASE_KIND_GRADECAST_LEADER, |
151 | PHASE_KIND_GRADECAST_ECHO, | 146 | PHASE_KIND_GRADECAST_ECHO, |
152 | PHASE_KIND_GRADECAST_ECHO_GRADE, | 147 | PHASE_KIND_GRADECAST_ECHO_GRADE, |
@@ -492,6 +487,18 @@ struct ConsensusSession | |||
492 | * State of our early stopping scheme. | 487 | * State of our early stopping scheme. |
493 | */ | 488 | */ |
494 | int early_stopping; | 489 | int early_stopping; |
490 | |||
491 | /** | ||
492 | * Our set size from the first round. | ||
493 | */ | ||
494 | uint64_t first_size; | ||
495 | |||
496 | uint64_t *first_sizes_received; | ||
497 | |||
498 | /** | ||
499 | * Bounded Eppstein lower bound. | ||
500 | */ | ||
501 | uint64_t lower_bound; | ||
495 | }; | 502 | }; |
496 | 503 | ||
497 | /** | 504 | /** |
@@ -534,6 +541,7 @@ phasename (uint16_t phase) | |||
534 | switch (phase) | 541 | switch (phase) |
535 | { | 542 | { |
536 | case PHASE_KIND_ALL_TO_ALL: return "ALL_TO_ALL"; | 543 | case PHASE_KIND_ALL_TO_ALL: return "ALL_TO_ALL"; |
544 | case PHASE_KIND_ALL_TO_ALL_2: return "ALL_TO_ALL_2"; | ||
537 | case PHASE_KIND_FINISH: return "FINISH"; | 545 | case PHASE_KIND_FINISH: return "FINISH"; |
538 | case PHASE_KIND_GRADECAST_LEADER: return "GRADECAST_LEADER"; | 546 | case PHASE_KIND_GRADECAST_LEADER: return "GRADECAST_LEADER"; |
539 | case PHASE_KIND_GRADECAST_ECHO: return "GRADECAST_ECHO"; | 547 | case PHASE_KIND_GRADECAST_ECHO: return "GRADECAST_ECHO"; |
@@ -669,16 +677,25 @@ send_to_client_iter (void *cls, | |||
669 | if (NULL != element) | 677 | if (NULL != element) |
670 | { | 678 | { |
671 | struct GNUNET_CONSENSUS_ElementMessage *m; | 679 | struct GNUNET_CONSENSUS_ElementMessage *m; |
680 | const struct ConsensusElement *ce; | ||
681 | |||
682 | GNUNET_assert (GNUNET_BLOCK_TYPE_CONSENSUS_ELEMENT == element->element_type); | ||
683 | ce = element->data; | ||
684 | |||
685 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "marker is %u\n", (unsigned) ce->marker); | ||
686 | |||
687 | if (0 != ce->marker) | ||
688 | return GNUNET_YES; | ||
672 | 689 | ||
673 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 690 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
674 | "P%d: sending element %s to client\n", | 691 | "P%d: sending element %s to client\n", |
675 | session->local_peer_idx, | 692 | session->local_peer_idx, |
676 | debug_str_element (element)); | 693 | debug_str_element (element)); |
677 | 694 | ||
678 | ev = GNUNET_MQ_msg_extra (m, element->size, | 695 | ev = GNUNET_MQ_msg_extra (m, element->size - sizeof (struct ConsensusElement), |
679 | GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_RECEIVED_ELEMENT); | 696 | GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_RECEIVED_ELEMENT); |
680 | m->element_type = htons (element->element_type); | 697 | m->element_type = ce->payload_type; |
681 | GNUNET_memcpy (&m[1], element->data, element->size); | 698 | GNUNET_memcpy (&m[1], &ce[1], element->size - sizeof (struct ConsensusElement)); |
682 | GNUNET_MQ_send (session->client_mq, ev); | 699 | GNUNET_MQ_send (session->client_mq, ev); |
683 | } | 700 | } |
684 | else | 701 | else |
@@ -848,7 +865,7 @@ rfn_vote (struct ReferendumEntry *rfn, | |||
848 | } | 865 | } |
849 | 866 | ||
850 | 867 | ||
851 | uint16_t | 868 | static uint16_t |
852 | task_other_peer (struct TaskEntry *task) | 869 | task_other_peer (struct TaskEntry *task) |
853 | { | 870 | { |
854 | uint16_t me = task->step->session->local_peer_idx; | 871 | uint16_t me = task->step->session->local_peer_idx; |
@@ -858,17 +875,33 @@ task_other_peer (struct TaskEntry *task) | |||
858 | } | 875 | } |
859 | 876 | ||
860 | 877 | ||
878 | static int | ||
879 | cmp_uint64_t (const void *pa, const void *pb) | ||
880 | { | ||
881 | uint64_t a = *(uint64_t *) pa; | ||
882 | uint64_t b = *(uint64_t *) pb; | ||
883 | |||
884 | if (a == b) | ||
885 | return 0; | ||
886 | if (a < b) | ||
887 | return -1; | ||
888 | return 1; | ||
889 | } | ||
890 | |||
891 | |||
861 | /** | 892 | /** |
862 | * Callback for set operation results. Called for each element | 893 | * Callback for set operation results. Called for each element |
863 | * in the result set. | 894 | * in the result set. |
864 | * | 895 | * |
865 | * @param cls closure | 896 | * @param cls closure |
866 | * @param element a result element, only valid if status is GNUNET_SET_STATUS_OK | 897 | * @param element a result element, only valid if status is GNUNET_SET_STATUS_OK |
898 | * @param current_size current set size | ||
867 | * @param status see enum GNUNET_SET_Status | 899 | * @param status see enum GNUNET_SET_Status |
868 | */ | 900 | */ |
869 | static void | 901 | static void |
870 | set_result_cb (void *cls, | 902 | set_result_cb (void *cls, |
871 | const struct GNUNET_SET_Element *element, | 903 | const struct GNUNET_SET_Element *element, |
904 | uint64_t current_size, | ||
872 | enum GNUNET_SET_Status status) | 905 | enum GNUNET_SET_Status status) |
873 | { | 906 | { |
874 | struct TaskEntry *task = cls; | 907 | struct TaskEntry *task = cls; |
@@ -878,6 +911,18 @@ set_result_cb (void *cls, | |||
878 | struct ReferendumEntry *output_rfn = NULL; | 911 | struct ReferendumEntry *output_rfn = NULL; |
879 | unsigned int other_idx; | 912 | unsigned int other_idx; |
880 | struct SetOpCls *setop; | 913 | struct SetOpCls *setop; |
914 | const struct ConsensusElement *consensus_element = NULL; | ||
915 | |||
916 | if (NULL != element) | ||
917 | { | ||
918 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
919 | "P%u: got element of type %u, status %u\n", | ||
920 | session->local_peer_idx, | ||
921 | (unsigned) element->element_type, | ||
922 | (unsigned) status); | ||
923 | GNUNET_assert (GNUNET_BLOCK_TYPE_CONSENSUS_ELEMENT == element->element_type); | ||
924 | consensus_element = element->data; | ||
925 | } | ||
881 | 926 | ||
882 | setop = &task->cls.setop; | 927 | setop = &task->cls.setop; |
883 | 928 | ||
@@ -930,19 +975,53 @@ set_result_cb (void *cls, | |||
930 | return; | 975 | return; |
931 | } | 976 | } |
932 | 977 | ||
933 | if ( (GNUNET_SET_STATUS_ADD_LOCAL == status) || (GNUNET_SET_STATUS_ADD_REMOTE == status) ) | 978 | if ( (NULL != consensus_element) && (0 != consensus_element->marker) ) |
934 | { | 979 | { |
935 | if ( (GNUNET_YES == setop->transceive_contested) && (ELEMENT_TYPE_CONTESTED_MARKER == element->element_type) ) | 980 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
981 | "P%u: got some marker\n", | ||
982 | session->local_peer_idx); | ||
983 | if ( (GNUNET_YES == setop->transceive_contested) && | ||
984 | (CONSENSUS_MARKER_CONTESTED == consensus_element->marker) ) | ||
936 | { | 985 | { |
937 | GNUNET_assert (NULL != output_rfn); | 986 | GNUNET_assert (NULL != output_rfn); |
938 | rfn_contest (output_rfn, task_other_peer (task)); | 987 | rfn_contest (output_rfn, task_other_peer (task)); |
939 | return; | 988 | return; |
940 | } | 989 | } |
990 | |||
991 | if (CONSENSUS_MARKER_SIZE == consensus_element->marker) | ||
992 | { | ||
993 | |||
994 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
995 | "P%u: got size marker\n", | ||
996 | session->local_peer_idx); | ||
997 | |||
998 | |||
999 | struct ConsensusSizeElement *cse = (void *) consensus_element; | ||
1000 | |||
1001 | if (cse->sender_index == other_idx) | ||
1002 | { | ||
1003 | if (NULL == session->first_sizes_received) | ||
1004 | session->first_sizes_received = GNUNET_new_array (session->num_peers, uint64_t); | ||
1005 | session->first_sizes_received[other_idx] = GNUNET_ntohll (cse->size); | ||
1006 | |||
1007 | uint64_t *copy = GNUNET_memdup (session->first_sizes_received, sizeof (uint64_t) * session->num_peers); | ||
1008 | qsort (copy, session->num_peers, sizeof (uint64_t), cmp_uint64_t); | ||
1009 | session->lower_bound = copy[session->num_peers / 3 + 1]; | ||
1010 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1011 | "P%u: lower bound %llu\n", | ||
1012 | session->local_peer_idx, | ||
1013 | (long long) session->lower_bound); | ||
1014 | } | ||
1015 | return; | ||
1016 | } | ||
1017 | |||
1018 | return; | ||
941 | } | 1019 | } |
942 | 1020 | ||
943 | switch (status) | 1021 | switch (status) |
944 | { | 1022 | { |
945 | case GNUNET_SET_STATUS_ADD_LOCAL: | 1023 | case GNUNET_SET_STATUS_ADD_LOCAL: |
1024 | GNUNET_assert (NULL != consensus_element); | ||
946 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1025 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
947 | "Adding element in Task {%s}\n", | 1026 | "Adding element in Task {%s}\n", |
948 | debug_str_task_key (&task->key)); | 1027 | debug_str_task_key (&task->key)); |
@@ -989,9 +1068,10 @@ set_result_cb (void *cls, | |||
989 | // XXX: add result to structures in task | 1068 | // XXX: add result to structures in task |
990 | break; | 1069 | break; |
991 | case GNUNET_SET_STATUS_ADD_REMOTE: | 1070 | case GNUNET_SET_STATUS_ADD_REMOTE: |
1071 | GNUNET_assert (NULL != consensus_element); | ||
992 | if (GNUNET_YES == setop->do_not_remove) | 1072 | if (GNUNET_YES == setop->do_not_remove) |
993 | break; | 1073 | break; |
994 | if (ELEMENT_TYPE_CONTESTED_MARKER == element->element_type) | 1074 | if (CONSENSUS_MARKER_CONTESTED == consensus_element->marker) |
995 | break; | 1075 | break; |
996 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1076 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
997 | "Removing element in Task {%s}\n", | 1077 | "Removing element in Task {%s}\n", |
@@ -1047,6 +1127,10 @@ set_result_cb (void *cls, | |||
1047 | { | 1127 | { |
1048 | rfn_commit (output_rfn, task_other_peer (task)); | 1128 | rfn_commit (output_rfn, task_other_peer (task)); |
1049 | } | 1129 | } |
1130 | if (PHASE_KIND_ALL_TO_ALL == task->key.kind) | ||
1131 | { | ||
1132 | session->first_size = current_size; | ||
1133 | } | ||
1050 | finish_task (task); | 1134 | finish_task (task); |
1051 | break; | 1135 | break; |
1052 | case GNUNET_SET_STATUS_FAILURE: | 1136 | case GNUNET_SET_STATUS_FAILURE: |
@@ -1069,6 +1153,7 @@ enum EvilnessType | |||
1069 | EVILNESS_CRAM_LEAD, | 1153 | EVILNESS_CRAM_LEAD, |
1070 | EVILNESS_CRAM_ECHO, | 1154 | EVILNESS_CRAM_ECHO, |
1071 | EVILNESS_SLACK, | 1155 | EVILNESS_SLACK, |
1156 | EVILNESS_SLACK_A2A, | ||
1072 | }; | 1157 | }; |
1073 | 1158 | ||
1074 | enum EvilnessSubType | 1159 | enum EvilnessSubType |
@@ -1161,6 +1246,10 @@ get_evilness (struct ConsensusSession *session, struct Evilness *evil) | |||
1161 | { | 1246 | { |
1162 | evil->type = EVILNESS_SLACK; | 1247 | evil->type = EVILNESS_SLACK; |
1163 | } | 1248 | } |
1249 | if (0 == strcmp ("slack-a2a", evil_type_str)) | ||
1250 | { | ||
1251 | evil->type = EVILNESS_SLACK_A2A; | ||
1252 | } | ||
1164 | else if (0 == strcmp ("cram-all", evil_type_str)) | 1253 | else if (0 == strcmp ("cram-all", evil_type_str)) |
1165 | { | 1254 | { |
1166 | evil->type = EVILNESS_CRAM_ALL; | 1255 | evil->type = EVILNESS_CRAM_ALL; |
@@ -1226,6 +1315,31 @@ commit_set (struct ConsensusSession *session, | |||
1226 | set = lookup_set (session, &setop->input_set); | 1315 | set = lookup_set (session, &setop->input_set); |
1227 | GNUNET_assert (NULL != set); | 1316 | GNUNET_assert (NULL != set); |
1228 | 1317 | ||
1318 | if ( (GNUNET_YES == setop->transceive_contested) && (GNUNET_YES == set->is_contested) ) | ||
1319 | { | ||
1320 | struct GNUNET_SET_Element element; | ||
1321 | struct ConsensusElement ce = { 0 }; | ||
1322 | ce.marker = CONSENSUS_MARKER_CONTESTED; | ||
1323 | element.data = &ce; | ||
1324 | element.size = sizeof (struct ConsensusElement); | ||
1325 | element.element_type = GNUNET_BLOCK_TYPE_CONSENSUS_ELEMENT; | ||
1326 | GNUNET_SET_add_element (set->h, &element, NULL, NULL); | ||
1327 | } | ||
1328 | |||
1329 | if (PHASE_KIND_ALL_TO_ALL_2 == task->key.kind) | ||
1330 | { | ||
1331 | struct GNUNET_SET_Element element; | ||
1332 | struct ConsensusSizeElement cse = { 0 }; | ||
1333 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "inserting size marker\n"); | ||
1334 | cse.ce.marker = CONSENSUS_MARKER_SIZE; | ||
1335 | cse.size = GNUNET_htonll (session->first_size); | ||
1336 | cse.sender_index = session->local_peer_idx; | ||
1337 | element.data = &cse; | ||
1338 | element.size = sizeof (struct ConsensusSizeElement); | ||
1339 | element.element_type = GNUNET_BLOCK_TYPE_CONSENSUS_ELEMENT; | ||
1340 | GNUNET_SET_add_element (set->h, &element, NULL, NULL); | ||
1341 | } | ||
1342 | |||
1229 | #ifdef EVIL | 1343 | #ifdef EVIL |
1230 | { | 1344 | { |
1231 | unsigned int i; | 1345 | unsigned int i; |
@@ -1267,21 +1381,21 @@ commit_set (struct ConsensusSession *session, | |||
1267 | } | 1381 | } |
1268 | for (i = 0; i < evil.num; i++) | 1382 | for (i = 0; i < evil.num; i++) |
1269 | { | 1383 | { |
1270 | struct GNUNET_HashCode hash; | ||
1271 | struct GNUNET_SET_Element element; | 1384 | struct GNUNET_SET_Element element; |
1272 | element.data = &hash; | 1385 | struct ConsensusStuffedElement se = { 0 }; |
1273 | element.size = sizeof (struct GNUNET_HashCode); | 1386 | element.data = &se; |
1274 | element.element_type = 0; | 1387 | element.size = sizeof (struct ConsensusStuffedElement); |
1388 | element.element_type = GNUNET_BLOCK_TYPE_CONSENSUS_ELEMENT; | ||
1275 | 1389 | ||
1276 | if (EVILNESS_SUB_REPLACEMENT == evil.subtype) | 1390 | if (EVILNESS_SUB_REPLACEMENT == evil.subtype) |
1277 | { | 1391 | { |
1278 | /* Always generate a new element. */ | 1392 | /* Always generate a new element. */ |
1279 | GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, &hash); | 1393 | GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, &se.rand); |
1280 | } | 1394 | } |
1281 | else if (EVILNESS_SUB_NO_REPLACEMENT == evil.subtype) | 1395 | else if (EVILNESS_SUB_NO_REPLACEMENT == evil.subtype) |
1282 | { | 1396 | { |
1283 | /* Always cram the same elements, derived from counter. */ | 1397 | /* Always cram the same elements, derived from counter. */ |
1284 | GNUNET_CRYPTO_hash (&i, sizeof (i), &hash); | 1398 | GNUNET_CRYPTO_hash (&i, sizeof (i), &se.rand); |
1285 | } | 1399 | } |
1286 | else | 1400 | else |
1287 | { | 1401 | { |
@@ -1308,6 +1422,19 @@ commit_set (struct ConsensusSession *session, | |||
1308 | "P%u: evil peer: slacking\n", | 1422 | "P%u: evil peer: slacking\n", |
1309 | (unsigned int) session->local_peer_idx); | 1423 | (unsigned int) session->local_peer_idx); |
1310 | /* Do nothing. */ | 1424 | /* Do nothing. */ |
1425 | case EVILNESS_SLACK_A2A: | ||
1426 | if ( (PHASE_KIND_ALL_TO_ALL_2 == task->key.kind ) || | ||
1427 | (PHASE_KIND_ALL_TO_ALL == task->key.kind) ) | ||
1428 | { | ||
1429 | struct GNUNET_SET_Handle *empty_set; | ||
1430 | empty_set = GNUNET_SET_create (cfg, GNUNET_SET_OPERATION_UNION); | ||
1431 | GNUNET_SET_commit (setop->op, empty_set); | ||
1432 | GNUNET_SET_destroy (empty_set); | ||
1433 | } | ||
1434 | else | ||
1435 | { | ||
1436 | GNUNET_SET_commit (setop->op, set->h); | ||
1437 | } | ||
1311 | break; | 1438 | break; |
1312 | case EVILNESS_NONE: | 1439 | case EVILNESS_NONE: |
1313 | GNUNET_SET_commit (setop->op, set->h); | 1440 | GNUNET_SET_commit (setop->op, set->h); |
@@ -1315,15 +1442,6 @@ commit_set (struct ConsensusSession *session, | |||
1315 | } | 1442 | } |
1316 | } | 1443 | } |
1317 | #else | 1444 | #else |
1318 | if ( (GNUNET_YES == setop->transceive_contested) && (GNUNET_YES == set->is_contested) ) | ||
1319 | { | ||
1320 | struct GNUNET_SET_Element element; | ||
1321 | struct ContestedPayload payload; | ||
1322 | element.data = &payload; | ||
1323 | element.size = sizeof (struct ContestedPayload); | ||
1324 | element.element_type = ELEMENT_TYPE_CONTESTED_MARKER; | ||
1325 | GNUNET_SET_add_element (set->h, &element, NULL, NULL); | ||
1326 | } | ||
1327 | if (GNUNET_NO == session->peers_blacklisted[task_other_peer (task)]) | 1445 | if (GNUNET_NO == session->peers_blacklisted[task_other_peer (task)]) |
1328 | { | 1446 | { |
1329 | GNUNET_SET_commit (setop->op, set->h); | 1447 | GNUNET_SET_commit (setop->op, set->h); |
@@ -2007,12 +2125,18 @@ task_start_reconcile (struct TaskEntry *task) | |||
2007 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: initiating set op with P%u, our set is %s\n", | 2125 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: initiating set op with P%u, our set is %s\n", |
2008 | session->local_peer_idx, task->key.peer2, debug_str_set_key (&setop->input_set)); | 2126 | session->local_peer_idx, task->key.peer2, debug_str_set_key (&setop->input_set)); |
2009 | 2127 | ||
2128 | struct GNUNET_SET_Option opts[] = { | ||
2129 | { GNUNET_SET_OPTION_BYZANTINE, { .num = session->lower_bound } }, | ||
2130 | { GNUNET_SET_OPTION_END }, | ||
2131 | }; | ||
2132 | |||
2010 | // XXX: maybe this should be done while | 2133 | // XXX: maybe this should be done while |
2011 | // setting up tasks alreays? | 2134 | // setting up tasks alreays? |
2012 | setop->op = GNUNET_SET_prepare (&session->peers[task->key.peer2], | 2135 | setop->op = GNUNET_SET_prepare (&session->peers[task->key.peer2], |
2013 | &session->global_id, | 2136 | &session->global_id, |
2014 | &rcm.header, | 2137 | &rcm.header, |
2015 | GNUNET_SET_RESULT_SYMMETRIC, | 2138 | GNUNET_SET_RESULT_SYMMETRIC, |
2139 | opts, | ||
2016 | set_result_cb, | 2140 | set_result_cb, |
2017 | task); | 2141 | task); |
2018 | 2142 | ||
@@ -2437,8 +2561,14 @@ set_listen_cb (void *cls, | |||
2437 | GNUNET_assert (! ((task->key.peer1 == session->local_peer_idx) && | 2561 | GNUNET_assert (! ((task->key.peer1 == session->local_peer_idx) && |
2438 | (task->key.peer2 == session->local_peer_idx))); | 2562 | (task->key.peer2 == session->local_peer_idx))); |
2439 | 2563 | ||
2564 | struct GNUNET_SET_Option opts[] = { | ||
2565 | { GNUNET_SET_OPTION_BYZANTINE, { .num = session->lower_bound } }, | ||
2566 | { GNUNET_SET_OPTION_END }, | ||
2567 | }; | ||
2568 | |||
2440 | task->cls.setop.op = GNUNET_SET_accept (request, | 2569 | task->cls.setop.op = GNUNET_SET_accept (request, |
2441 | GNUNET_SET_RESULT_SYMMETRIC, | 2570 | GNUNET_SET_RESULT_SYMMETRIC, |
2571 | opts, | ||
2442 | set_result_cb, | 2572 | set_result_cb, |
2443 | task); | 2573 | task); |
2444 | 2574 | ||
@@ -2834,11 +2964,42 @@ construct_task_graph (struct ConsensusSession *session) | |||
2834 | put_task (session->taskmap, &task); | 2964 | put_task (session->taskmap, &task); |
2835 | } | 2965 | } |
2836 | 2966 | ||
2967 | round += 1; | ||
2837 | prev_step = step; | 2968 | prev_step = step; |
2838 | step = NULL; | 2969 | step = create_step (session, round, GNUNET_NO);; |
2970 | #ifdef GNUNET_EXTRA_LOGGING | ||
2971 | step->debug_name = GNUNET_strdup ("all to all 2"); | ||
2972 | #endif | ||
2973 | step_depend_on (step, prev_step); | ||
2974 | |||
2975 | |||
2976 | for (i = 0; i < n; i++) | ||
2977 | { | ||
2978 | uint16_t p1; | ||
2979 | uint16_t p2; | ||
2980 | |||
2981 | p1 = me; | ||
2982 | p2 = i; | ||
2983 | arrange_peers (&p1, &p2, n); | ||
2984 | task = ((struct TaskEntry) { | ||
2985 | .key = (struct TaskKey) { PHASE_KIND_ALL_TO_ALL_2, p1, p2, -1, -1 }, | ||
2986 | .step = step, | ||
2987 | .start = task_start_reconcile, | ||
2988 | .cancel = task_cancel_reconcile, | ||
2989 | }); | ||
2990 | task.cls.setop.input_set = (struct SetKey) { SET_KIND_CURRENT, 0 }; | ||
2991 | task.cls.setop.output_set = task.cls.setop.input_set; | ||
2992 | task.cls.setop.do_not_remove = GNUNET_YES; | ||
2993 | put_task (session->taskmap, &task); | ||
2994 | } | ||
2839 | 2995 | ||
2840 | round += 1; | 2996 | round += 1; |
2841 | 2997 | ||
2998 | prev_step = step; | ||
2999 | step = NULL; | ||
3000 | |||
3001 | |||
3002 | |||
2842 | /* Byzantine union */ | 3003 | /* Byzantine union */ |
2843 | 3004 | ||
2844 | /* sequential repetitions of the gradecasts */ | 3005 | /* sequential repetitions of the gradecasts */ |
@@ -3039,9 +3200,9 @@ handle_client_insert (void *cls, | |||
3039 | const struct GNUNET_CONSENSUS_ElementMessage *msg) | 3200 | const struct GNUNET_CONSENSUS_ElementMessage *msg) |
3040 | { | 3201 | { |
3041 | struct ConsensusSession *session = cls; | 3202 | struct ConsensusSession *session = cls; |
3042 | struct GNUNET_SET_Element *element; | ||
3043 | ssize_t element_size; | 3203 | ssize_t element_size; |
3044 | struct GNUNET_SET_Handle *initial_set; | 3204 | struct GNUNET_SET_Handle *initial_set; |
3205 | struct ConsensusElement *ce; | ||
3045 | 3206 | ||
3046 | if (GNUNET_YES == session->conclude_started) | 3207 | if (GNUNET_YES == session->conclude_started) |
3047 | { | 3208 | { |
@@ -3049,12 +3210,18 @@ handle_client_insert (void *cls, | |||
3049 | GNUNET_SERVICE_client_drop (session->client); | 3210 | GNUNET_SERVICE_client_drop (session->client); |
3050 | return; | 3211 | return; |
3051 | } | 3212 | } |
3213 | |||
3052 | element_size = ntohs (msg->header.size) - sizeof (struct GNUNET_CONSENSUS_ElementMessage); | 3214 | element_size = ntohs (msg->header.size) - sizeof (struct GNUNET_CONSENSUS_ElementMessage); |
3053 | element = GNUNET_malloc (sizeof (struct GNUNET_SET_Element) + element_size); | 3215 | ce = GNUNET_malloc (sizeof (struct ConsensusElement) + element_size); |
3054 | element->element_type = msg->element_type; | 3216 | GNUNET_memcpy (&ce[1], &msg[1], element_size); |
3055 | element->size = element_size; | 3217 | ce->payload_type = msg->element_type; |
3056 | GNUNET_memcpy (&element[1], &msg[1], element_size); | 3218 | |
3057 | element->data = &element[1]; | 3219 | struct GNUNET_SET_Element element = { |
3220 | .element_type = GNUNET_BLOCK_TYPE_CONSENSUS_ELEMENT, | ||
3221 | .size = sizeof (struct ConsensusElement) + element_size, | ||
3222 | .data = ce, | ||
3223 | }; | ||
3224 | |||
3058 | { | 3225 | { |
3059 | struct SetKey key = { SET_KIND_CURRENT, 0, 0 }; | 3226 | struct SetKey key = { SET_KIND_CURRENT, 0, 0 }; |
3060 | struct SetEntry *entry; | 3227 | struct SetEntry *entry; |
@@ -3064,26 +3231,22 @@ handle_client_insert (void *cls, | |||
3064 | GNUNET_assert (NULL != entry); | 3231 | GNUNET_assert (NULL != entry); |
3065 | initial_set = entry->h; | 3232 | initial_set = entry->h; |
3066 | } | 3233 | } |
3234 | |||
3067 | session->num_client_insert_pending++; | 3235 | session->num_client_insert_pending++; |
3068 | GNUNET_SET_add_element (initial_set, | 3236 | GNUNET_SET_add_element (initial_set, |
3069 | element, | 3237 | &element, |
3070 | &client_insert_done, | 3238 | &client_insert_done, |
3071 | session); | 3239 | session); |
3072 | 3240 | ||
3073 | #ifdef GNUNET_EXTRA_LOGGING | 3241 | #ifdef GNUNET_EXTRA_LOGGING |
3074 | { | 3242 | { |
3075 | struct GNUNET_HashCode hash; | ||
3076 | |||
3077 | GNUNET_SET_element_hash (element, | ||
3078 | &hash); | ||
3079 | |||
3080 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 3243 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
3081 | "P%u: element %s added\n", | 3244 | "P%u: element %s added\n", |
3082 | session->local_peer_idx, | 3245 | session->local_peer_idx, |
3083 | GNUNET_h2s (&hash)); | 3246 | debug_str_element (&element)); |
3084 | } | 3247 | } |
3085 | #endif | 3248 | #endif |
3086 | GNUNET_free (element); | 3249 | GNUNET_free (ce); |
3087 | GNUNET_SERVICE_client_continue (session->client); | 3250 | GNUNET_SERVICE_client_continue (session->client); |
3088 | } | 3251 | } |
3089 | 3252 | ||
diff --git a/src/consensus/plugin_block_consensus.c b/src/consensus/plugin_block_consensus.c new file mode 100644 index 000000000..de0f0886f --- /dev/null +++ b/src/consensus/plugin_block_consensus.c | |||
@@ -0,0 +1,137 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2017 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file consensus/plugin_block_consensus.c | ||
23 | * @brief consensus block, either nested block or marker | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | |||
27 | #include "platform.h" | ||
28 | #include "consensus_protocol.h" | ||
29 | #include "gnunet_block_plugin.h" | ||
30 | #include "gnunet_block_group_lib.h" | ||
31 | |||
32 | |||
33 | /** | ||
34 | * Function called to validate a reply or a request. For | ||
35 | * request evaluation, simply pass "NULL" for the reply_block. | ||
36 | * | ||
37 | * @param cls closure | ||
38 | * @param ctx context | ||
39 | * @param type block type | ||
40 | * @param group block group to use | ||
41 | * @param eo control flags | ||
42 | * @param query original query (hash) | ||
43 | * @param xquery extrended query data (can be NULL, depending on type) | ||
44 | * @param xquery_size number of bytes in xquery | ||
45 | * @param reply_block response to validate | ||
46 | * @param reply_block_size number of bytes in reply block | ||
47 | * @return characterization of result | ||
48 | */ | ||
49 | static enum GNUNET_BLOCK_EvaluationResult | ||
50 | block_plugin_consensus_evaluate (void *cls, | ||
51 | struct GNUNET_BLOCK_Context *ctx, | ||
52 | enum GNUNET_BLOCK_Type type, | ||
53 | struct GNUNET_BLOCK_Group *group, | ||
54 | enum GNUNET_BLOCK_EvaluationOptions eo, | ||
55 | const struct GNUNET_HashCode *query, | ||
56 | const void *xquery, | ||
57 | size_t xquery_size, | ||
58 | const void *reply_block, | ||
59 | size_t reply_block_size) | ||
60 | { | ||
61 | if (reply_block_size < sizeof (struct ConsensusElement)) | ||
62 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
63 | |||
64 | const struct ConsensusElement *ce = reply_block; | ||
65 | |||
66 | if ( (0 != ce->marker) || | ||
67 | (0 == ce->payload_type ) ) | ||
68 | return GNUNET_BLOCK_EVALUATION_OK_MORE; | ||
69 | |||
70 | return GNUNET_BLOCK_evaluate (ctx, | ||
71 | type, | ||
72 | group, | ||
73 | eo, | ||
74 | query, | ||
75 | xquery, | ||
76 | xquery_size, | ||
77 | &ce[1], | ||
78 | reply_block_size - sizeof (struct ConsensusElement)); | ||
79 | } | ||
80 | |||
81 | |||
82 | /** | ||
83 | * Function called to obtain the key for a block. | ||
84 | * | ||
85 | * @param cls closure | ||
86 | * @param type block type | ||
87 | * @param block block to get the key for | ||
88 | * @param block_size number of bytes in block | ||
89 | * @param key set to the key (query) for the given block | ||
90 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported | ||
91 | * (or if extracting a key from a block of this type does not work) | ||
92 | */ | ||
93 | static int | ||
94 | block_plugin_consensus_get_key (void *cls, | ||
95 | enum GNUNET_BLOCK_Type type, | ||
96 | const void *block, | ||
97 | size_t block_size, | ||
98 | struct GNUNET_HashCode *key) | ||
99 | { | ||
100 | return GNUNET_SYSERR; | ||
101 | } | ||
102 | |||
103 | |||
104 | /** | ||
105 | * Entry point for the plugin. | ||
106 | */ | ||
107 | void * | ||
108 | libgnunet_plugin_block_consensus_init (void *cls) | ||
109 | { | ||
110 | static enum GNUNET_BLOCK_Type types[] = | ||
111 | { | ||
112 | GNUNET_BLOCK_TYPE_CONSENSUS_ELEMENT, | ||
113 | GNUNET_BLOCK_TYPE_ANY /* end of list */ | ||
114 | }; | ||
115 | struct GNUNET_BLOCK_PluginFunctions *api; | ||
116 | |||
117 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); | ||
118 | api->evaluate = &block_plugin_consensus_evaluate; | ||
119 | api->get_key = &block_plugin_consensus_get_key; | ||
120 | api->types = types; | ||
121 | return api; | ||
122 | } | ||
123 | |||
124 | |||
125 | /** | ||
126 | * Exit point from the plugin. | ||
127 | */ | ||
128 | void * | ||
129 | libgnunet_plugin_block_consensus_done (void *cls) | ||
130 | { | ||
131 | struct GNUNET_BLOCK_PluginFunctions *api = cls; | ||
132 | |||
133 | GNUNET_free (api); | ||
134 | return NULL; | ||
135 | } | ||
136 | |||
137 | /* end of plugin_block_consensus.c */ | ||
diff --git a/src/consensus/test_consensus.conf b/src/consensus/test_consensus.conf index 8f144fa5e..881251a66 100644 --- a/src/consensus/test_consensus.conf +++ b/src/consensus/test_consensus.conf | |||
@@ -2,9 +2,11 @@ | |||
2 | GNUNET_TEST_HOME = /tmp/test-consensus/ | 2 | GNUNET_TEST_HOME = /tmp/test-consensus/ |
3 | 3 | ||
4 | [consensus] | 4 | [consensus] |
5 | OPTIONS = -L INFO | 5 | #OPTIONS = -L INFO |
6 | BINARY = gnunet-service-evil-consensus | 6 | BINARY = gnunet-service-evil-consensus |
7 | 7 | ||
8 | PREFIX = valgrind | ||
9 | |||
8 | #EVIL_SPEC = 0;cram-all;noreplace;5 | 10 | #EVIL_SPEC = 0;cram-all;noreplace;5 |
9 | #EVIL_SPEC = 0;cram;5/1;cram;5 | 11 | #EVIL_SPEC = 0;cram;5/1;cram;5 |
10 | #EVIL_SPEC = 0;cram;5/1;cram;5/2;cram;5 | 12 | #EVIL_SPEC = 0;cram;5/1;cram;5/2;cram;5 |
@@ -15,19 +17,22 @@ BINARY = gnunet-service-evil-consensus | |||
15 | RESOURCE_DIAGNOSTICS = resource.log.${PEERID:-master} | 17 | RESOURCE_DIAGNOSTICS = resource.log.${PEERID:-master} |
16 | 18 | ||
17 | [core] | 19 | [core] |
18 | FORECESTART = YES | 20 | FORCESTART = YES |
19 | 21 | ||
20 | [revocation] | 22 | [revocation] |
21 | FORECESTART = NO | 23 | FORCESTART = NO |
22 | 24 | ||
23 | [fs] | 25 | [fs] |
24 | FORECESTART = NO | 26 | FORCESTART = NO |
25 | 27 | ||
26 | [gns] | 28 | [gns] |
27 | FORECESTART = NO | 29 | FORCESTART = NO |
30 | |||
31 | [zonemaster] | ||
32 | FORCESTART = NO | ||
28 | 33 | ||
29 | [hostlist] | 34 | [hostlist] |
30 | FORECESTART = NO | 35 | FORCESTART = NO |
31 | 36 | ||
32 | [cadet] | 37 | [cadet] |
33 | #PREFIX = valgrind | 38 | #PREFIX = valgrind |
@@ -37,7 +42,7 @@ PLUGINS = unix | |||
37 | OPTIONS = -LERROR | 42 | OPTIONS = -LERROR |
38 | 43 | ||
39 | [set] | 44 | [set] |
40 | OPTIONS = -L INFO | 45 | #OPTIONS = -L INFO |
41 | #PREFIX = valgrind --leak-check=full | 46 | #PREFIX = valgrind --leak-check=full |
42 | #PREFIX = valgrind | 47 | #PREFIX = valgrind |
43 | 48 | ||
diff --git a/src/conversation/conversation_api_call.c b/src/conversation/conversation_api_call.c index a6bc506bc..7e4a147a0 100644 --- a/src/conversation/conversation_api_call.c +++ b/src/conversation/conversation_api_call.c | |||
@@ -603,7 +603,6 @@ GNUNET_CONVERSATION_call_start (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
603 | &my_zone, | 603 | &my_zone, |
604 | GNUNET_GNSRECORD_TYPE_PHONE, | 604 | GNUNET_GNSRECORD_TYPE_PHONE, |
605 | GNUNET_NO, | 605 | GNUNET_NO, |
606 | NULL /* FIXME: add shortening support */, | ||
607 | &handle_gns_response, call); | 606 | &handle_gns_response, call); |
608 | GNUNET_assert (NULL != call->gns_lookup); | 607 | GNUNET_assert (NULL != call->gns_lookup); |
609 | return call; | 608 | return call; |
diff --git a/src/conversation/gnunet_gst_def.h b/src/conversation/gnunet_gst_def.h index 9f519b564..85add54b6 100644 --- a/src/conversation/gnunet_gst_def.h +++ b/src/conversation/gnunet_gst_def.h | |||
@@ -65,20 +65,23 @@ | |||
65 | #include <gst/app/gstappsink.h> | 65 | #include <gst/app/gstappsink.h> |
66 | 66 | ||
67 | // sockets | 67 | // sockets |
68 | #ifndef MINGW | ||
69 | #if HAVE_NETINET_IN_H | ||
68 | #include <netinet/in.h> | 70 | #include <netinet/in.h> |
71 | #endif | ||
69 | #include <sys/socket.h> | 72 | #include <sys/socket.h> |
70 | #include <fcntl.h> | ||
71 | #include <arpa/inet.h> | 73 | #include <arpa/inet.h> |
74 | #include <netdb.h> | ||
75 | #endif | ||
72 | 76 | ||
73 | #include <sys/types.h> | 77 | #include <sys/types.h> |
74 | #include <sys/socket.h> | 78 | #include <fcntl.h> |
75 | #include <netdb.h> | ||
76 | 79 | ||
77 | 80 | ||
78 | //glib stuff | 81 | //glib stuff |
79 | //#include <glib.h> | 82 | //#include <glib.h> |
80 | #include <glib-2.0/glib/gprintf.h> | 83 | #include <glib-2.0/glib/gprintf.h> |
81 | #include <glib-unix.h> | 84 | //#include <glib-unix.h> |
82 | 85 | ||
83 | // static struct AudioMessage *audio_message; | 86 | // static struct AudioMessage *audio_message; |
84 | 87 | ||
diff --git a/src/core/gnunet-service-core.c b/src/core/gnunet-service-core.c index 52c6f72ab..31b91f12f 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 | /** |
@@ -819,6 +827,7 @@ GSC_CLIENTS_deliver_message (const struct GNUNET_PeerIdentity *sender, | |||
819 | struct GNUNET_MQ_Envelope *env; | 827 | struct GNUNET_MQ_Envelope *env; |
820 | struct NotifyTrafficMessage *ntm; | 828 | struct NotifyTrafficMessage *ntm; |
821 | uint16_t mtype; | 829 | uint16_t mtype; |
830 | unsigned int qlen; | ||
822 | int tm; | 831 | int tm; |
823 | 832 | ||
824 | tm = type_match (ntohs (msg->type), | 833 | tm = type_match (ntohs (msg->type), |
@@ -834,6 +843,45 @@ GSC_CLIENTS_deliver_message (const struct GNUNET_PeerIdentity *sender, | |||
834 | if ( (0 != (options & GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND)) && | 843 | if ( (0 != (options & GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND)) && |
835 | (0 != (c->options & GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND)) ) | 844 | (0 != (c->options & GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND)) ) |
836 | 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 | |||
837 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 885 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
838 | "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", |
839 | options, | 887 | options, |
diff --git a/src/core/gnunet-service-core_kx.c b/src/core/gnunet-service-core_kx.c index a0c343737..906898512 100644 --- a/src/core/gnunet-service-core_kx.c +++ b/src/core/gnunet-service-core_kx.c | |||
@@ -319,7 +319,7 @@ struct GSC_KeyExchangeInfo | |||
319 | * last were received (good for accepting out-of-order packets and | 319 | * last were received (good for accepting out-of-order packets and |
320 | * estimating reliability of the connection) | 320 | * estimating reliability of the connection) |
321 | */ | 321 | */ |
322 | unsigned int last_packets_bitmap; | 322 | uint32_t last_packets_bitmap; |
323 | 323 | ||
324 | /** | 324 | /** |
325 | * last sequence number received on this connection (highest) | 325 | * last sequence number received on this connection (highest) |
@@ -1573,7 +1573,7 @@ handle_encrypted (void *cls, | |||
1573 | } | 1573 | } |
1574 | if (kx->last_sequence_number_received > snum) | 1574 | if (kx->last_sequence_number_received > snum) |
1575 | { | 1575 | { |
1576 | unsigned int rotbit = 1 << (kx->last_sequence_number_received - snum - 1); | 1576 | uint32_t rotbit = 1U << (kx->last_sequence_number_received - snum - 1); |
1577 | 1577 | ||
1578 | if ((kx->last_packets_bitmap & rotbit) != 0) | 1578 | if ((kx->last_packets_bitmap & rotbit) != 0) |
1579 | { | 1579 | { |
diff --git a/src/datastore/datastore_api.c b/src/datastore/datastore_api.c index 311a61283..916e6acae 100644 --- a/src/datastore/datastore_api.c +++ b/src/datastore/datastore_api.c | |||
@@ -498,8 +498,17 @@ make_queue_entry (struct GNUNET_DATASTORE_Handle *h, | |||
498 | struct GNUNET_DATASTORE_QueueEntry *pos; | 498 | struct GNUNET_DATASTORE_QueueEntry *pos; |
499 | unsigned int c; | 499 | unsigned int c; |
500 | 500 | ||
501 | c = 0; | 501 | if ( (NULL != h->queue_tail) && |
502 | pos = h->queue_head; | 502 | (h->queue_tail->priority >= queue_priority) ) |
503 | { | ||
504 | c = h->queue_size; | ||
505 | pos = NULL; | ||
506 | } | ||
507 | else | ||
508 | { | ||
509 | c = 0; | ||
510 | pos = h->queue_head; | ||
511 | } | ||
503 | while ( (NULL != pos) && | 512 | while ( (NULL != pos) && |
504 | (c < max_queue_size) && | 513 | (c < max_queue_size) && |
505 | (pos->priority >= queue_priority) ) | 514 | (pos->priority >= queue_priority) ) |
diff --git a/src/datastore/gnunet-service-datastore.c b/src/datastore/gnunet-service-datastore.c index 445c3576e..1e699fea3 100644 --- a/src/datastore/gnunet-service-datastore.c +++ b/src/datastore/gnunet-service-datastore.c | |||
@@ -949,7 +949,7 @@ handle_put (void *cls, | |||
949 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 949 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
950 | "Processing PUT request for `%s' of type %u\n", | 950 | "Processing PUT request for `%s' of type %u\n", |
951 | GNUNET_h2s (&dm->key), | 951 | GNUNET_h2s (&dm->key), |
952 | ntohl (dm->type)); | 952 | (uint32_t) ntohl (dm->type)); |
953 | rid = ntohl (dm->rid); | 953 | rid = ntohl (dm->rid); |
954 | size = ntohl (dm->size); | 954 | size = ntohl (dm->size); |
955 | if (rid > 0) | 955 | if (rid > 0) |
@@ -1012,7 +1012,7 @@ handle_get (void *cls, | |||
1012 | 1012 | ||
1013 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1013 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1014 | "Processing GET request of type %u\n", | 1014 | "Processing GET request of type %u\n", |
1015 | ntohl (msg->type)); | 1015 | (uint32_t) ntohl (msg->type)); |
1016 | GNUNET_STATISTICS_update (stats, | 1016 | GNUNET_STATISTICS_update (stats, |
1017 | gettext_noop ("# GET requests received"), | 1017 | gettext_noop ("# GET requests received"), |
1018 | 1, | 1018 | 1, |
@@ -1043,7 +1043,7 @@ handle_get_key (void *cls, | |||
1043 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1043 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1044 | "Processing GET request for `%s' of type %u\n", | 1044 | "Processing GET request for `%s' of type %u\n", |
1045 | GNUNET_h2s (&msg->key), | 1045 | GNUNET_h2s (&msg->key), |
1046 | ntohl (msg->type)); | 1046 | (uint32_t) ntohl (msg->type)); |
1047 | GNUNET_STATISTICS_update (stats, | 1047 | GNUNET_STATISTICS_update (stats, |
1048 | gettext_noop ("# GET KEY requests received"), | 1048 | gettext_noop ("# GET KEY requests received"), |
1049 | 1, | 1049 | 1, |
@@ -1238,7 +1238,7 @@ handle_remove (void *cls, | |||
1238 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1238 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1239 | "Processing REMOVE request for `%s' of type %u\n", | 1239 | "Processing REMOVE request for `%s' of type %u\n", |
1240 | GNUNET_h2s (&dm->key), | 1240 | GNUNET_h2s (&dm->key), |
1241 | ntohl (dm->type)); | 1241 | (uint32_t) ntohl (dm->type)); |
1242 | plugin->api->get_key (plugin->api->cls, | 1242 | plugin->api->get_key (plugin->api->cls, |
1243 | 0, | 1243 | 0, |
1244 | &dm->key, | 1244 | &dm->key, |
diff --git a/src/datastore/plugin_datastore_sqlite.c b/src/datastore/plugin_datastore_sqlite.c index 028117d26..9ab50714f 100644 --- a/src/datastore/plugin_datastore_sqlite.c +++ b/src/datastore/plugin_datastore_sqlite.c | |||
@@ -229,35 +229,41 @@ database_setup (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
229 | { | 229 | { |
230 | sqlite3_stmt *stmt; | 230 | sqlite3_stmt *stmt; |
231 | char *afsdir; | 231 | char *afsdir; |
232 | |||
233 | #if ENULL_DEFINED | 232 | #if ENULL_DEFINED |
234 | char *e; | 233 | char *e; |
235 | #endif | 234 | #endif |
236 | 235 | ||
237 | if (GNUNET_OK != | 236 | if (GNUNET_OK != |
238 | GNUNET_CONFIGURATION_get_value_filename (cfg, "datastore-sqlite", | 237 | GNUNET_CONFIGURATION_get_value_filename (cfg, |
239 | "FILENAME", &afsdir)) | 238 | "datastore-sqlite", |
239 | "FILENAME", | ||
240 | &afsdir)) | ||
240 | { | 241 | { |
241 | GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, | 242 | GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, |
242 | "datastore-sqlite", "FILENAME"); | 243 | "datastore-sqlite", |
244 | "FILENAME"); | ||
243 | return GNUNET_SYSERR; | 245 | return GNUNET_SYSERR; |
244 | } | 246 | } |
245 | if (GNUNET_OK != GNUNET_DISK_file_test (afsdir)) | 247 | if (GNUNET_OK != GNUNET_DISK_file_test (afsdir)) |
246 | { | 248 | { |
247 | if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (afsdir)) | 249 | if (GNUNET_OK != |
250 | GNUNET_DISK_directory_create_for_file (afsdir)) | ||
248 | { | 251 | { |
249 | GNUNET_break (0); | 252 | GNUNET_break (0); |
250 | GNUNET_free (afsdir); | 253 | GNUNET_free (afsdir); |
251 | return GNUNET_SYSERR; | 254 | return GNUNET_SYSERR; |
252 | } | 255 | } |
253 | /* database is new or got deleted, reset payload to zero! */ | 256 | /* database is new or got deleted, reset payload to zero! */ |
254 | plugin->env->duc (plugin->env->cls, 0); | 257 | if (NULL != plugin->env->duc) |
258 | plugin->env->duc (plugin->env->cls, | ||
259 | 0); | ||
255 | } | 260 | } |
256 | /* afsdir should be UTF-8-encoded. If it isn't, it's a bug */ | 261 | /* afsdir should be UTF-8-encoded. If it isn't, it's a bug */ |
257 | plugin->fn = afsdir; | 262 | plugin->fn = afsdir; |
258 | 263 | ||
259 | /* Open database and precompile statements */ | 264 | /* Open database and precompile statements */ |
260 | if (sqlite3_open (plugin->fn, &plugin->dbh) != SQLITE_OK) | 265 | if (SQLITE_OK != |
266 | sqlite3_open (plugin->fn, &plugin->dbh)) | ||
261 | { | 267 | { |
262 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "sqlite", | 268 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "sqlite", |
263 | _("Unable to initialize SQLite: %s.\n"), | 269 | _("Unable to initialize SQLite: %s.\n"), |
@@ -265,25 +271,32 @@ database_setup (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
265 | return GNUNET_SYSERR; | 271 | return GNUNET_SYSERR; |
266 | } | 272 | } |
267 | CHECK (SQLITE_OK == | 273 | CHECK (SQLITE_OK == |
268 | sqlite3_exec (plugin->dbh, "PRAGMA temp_store=MEMORY", NULL, NULL, | 274 | sqlite3_exec (plugin->dbh, |
275 | "PRAGMA temp_store=MEMORY", NULL, NULL, | ||
269 | ENULL)); | 276 | ENULL)); |
270 | CHECK (SQLITE_OK == | 277 | CHECK (SQLITE_OK == |
271 | sqlite3_exec (plugin->dbh, "PRAGMA synchronous=OFF", NULL, NULL, | 278 | sqlite3_exec (plugin->dbh, |
279 | "PRAGMA synchronous=OFF", NULL, NULL, | ||
272 | ENULL)); | 280 | ENULL)); |
273 | CHECK (SQLITE_OK == | 281 | CHECK (SQLITE_OK == |
274 | sqlite3_exec (plugin->dbh, "PRAGMA legacy_file_format=OFF", NULL, NULL, | 282 | sqlite3_exec (plugin->dbh, |
283 | "PRAGMA legacy_file_format=OFF", NULL, NULL, | ||
275 | ENULL)); | 284 | ENULL)); |
276 | CHECK (SQLITE_OK == | 285 | CHECK (SQLITE_OK == |
277 | sqlite3_exec (plugin->dbh, "PRAGMA auto_vacuum=INCREMENTAL", NULL, | 286 | sqlite3_exec (plugin->dbh, |
287 | "PRAGMA auto_vacuum=INCREMENTAL", NULL, | ||
278 | NULL, ENULL)); | 288 | NULL, ENULL)); |
279 | CHECK (SQLITE_OK == | 289 | CHECK (SQLITE_OK == |
280 | sqlite3_exec (plugin->dbh, "PRAGMA locking_mode=EXCLUSIVE", NULL, NULL, | 290 | sqlite3_exec (plugin->dbh, |
291 | "PRAGMA locking_mode=EXCLUSIVE", NULL, NULL, | ||
281 | ENULL)); | 292 | ENULL)); |
282 | CHECK (SQLITE_OK == | 293 | CHECK (SQLITE_OK == |
283 | sqlite3_exec (plugin->dbh, "PRAGMA page_size=4092", NULL, NULL, | 294 | sqlite3_exec (plugin->dbh, |
295 | "PRAGMA page_size=4092", NULL, NULL, | ||
284 | ENULL)); | 296 | ENULL)); |
285 | 297 | ||
286 | CHECK (SQLITE_OK == sqlite3_busy_timeout (plugin->dbh, BUSY_TIMEOUT_MS)); | 298 | CHECK (SQLITE_OK == |
299 | sqlite3_busy_timeout (plugin->dbh, BUSY_TIMEOUT_MS)); | ||
287 | 300 | ||
288 | 301 | ||
289 | /* We have to do it here, because otherwise precompiling SQL might fail */ | 302 | /* We have to do it here, because otherwise precompiling SQL might fail */ |
@@ -552,7 +565,9 @@ sqlite_plugin_put (void *cls, | |||
552 | switch (n) | 565 | switch (n) |
553 | { | 566 | { |
554 | case SQLITE_DONE: | 567 | case SQLITE_DONE: |
555 | plugin->env->duc (plugin->env->cls, size + GNUNET_DATASTORE_ENTRY_OVERHEAD); | 568 | if (NULL != plugin->env->duc) |
569 | plugin->env->duc (plugin->env->cls, | ||
570 | size + GNUNET_DATASTORE_ENTRY_OVERHEAD); | ||
556 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", | 571 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", |
557 | "Stored new entry (%u bytes)\n", | 572 | "Stored new entry (%u bytes)\n", |
558 | size + GNUNET_DATASTORE_ENTRY_OVERHEAD); | 573 | size + GNUNET_DATASTORE_ENTRY_OVERHEAD); |
@@ -694,7 +709,8 @@ execute_get (struct Plugin *plugin, | |||
694 | LOG_SQLITE (plugin, | 709 | LOG_SQLITE (plugin, |
695 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | 710 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, |
696 | "sqlite3_reset"); | 711 | "sqlite3_reset"); |
697 | if (GNUNET_OK == delete_by_rowid (plugin, rowid)) | 712 | if ( (GNUNET_OK == delete_by_rowid (plugin, rowid)) && |
713 | (NULL != plugin->env->duc) ) | ||
698 | plugin->env->duc (plugin->env->cls, | 714 | plugin->env->duc (plugin->env->cls, |
699 | -(size + GNUNET_DATASTORE_ENTRY_OVERHEAD)); | 715 | -(size + GNUNET_DATASTORE_ENTRY_OVERHEAD)); |
700 | break; | 716 | break; |
@@ -713,7 +729,9 @@ execute_get (struct Plugin *plugin, | |||
713 | LOG_SQLITE (plugin, | 729 | LOG_SQLITE (plugin, |
714 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | 730 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, |
715 | "sqlite3_reset"); | 731 | "sqlite3_reset"); |
716 | if ((GNUNET_NO == ret) && (GNUNET_OK == delete_by_rowid (plugin, rowid))) | 732 | if ( (GNUNET_NO == ret) && |
733 | (GNUNET_OK == delete_by_rowid (plugin, rowid)) && | ||
734 | (NULL != plugin->env->duc) ) | ||
717 | plugin->env->duc (plugin->env->cls, | 735 | plugin->env->duc (plugin->env->cls, |
718 | -(size + GNUNET_DATASTORE_ENTRY_OVERHEAD)); | 736 | -(size + GNUNET_DATASTORE_ENTRY_OVERHEAD)); |
719 | return; | 737 | return; |
diff --git a/src/datastore/test_datastore_api_management.c b/src/datastore/test_datastore_api_management.c index 5e536d6c5..9a3e5446b 100644 --- a/src/datastore/test_datastore_api_management.c +++ b/src/datastore/test_datastore_api_management.c | |||
@@ -298,7 +298,21 @@ run (void *cls, | |||
298 | 298 | ||
299 | 299 | ||
300 | /** | 300 | /** |
301 | * check if plugin is actually working | 301 | * Function called when disk utilization changes, does nothing. |
302 | * | ||
303 | * @param cls closure | ||
304 | * @param delta change in utilization | ||
305 | */ | ||
306 | static void | ||
307 | ignore_payload_cb (void *cls, | ||
308 | int delta) | ||
309 | { | ||
310 | /* do nothing */ | ||
311 | } | ||
312 | |||
313 | |||
314 | /** | ||
315 | * check if plugin is actually working | ||
302 | */ | 316 | */ |
303 | static int | 317 | static int |
304 | test_plugin (const char *cfg_name) | 318 | test_plugin (const char *cfg_name) |
@@ -307,7 +321,7 @@ test_plugin (const char *cfg_name) | |||
307 | struct GNUNET_CONFIGURATION_Handle *cfg; | 321 | struct GNUNET_CONFIGURATION_Handle *cfg; |
308 | struct GNUNET_DATASTORE_PluginFunctions *api; | 322 | struct GNUNET_DATASTORE_PluginFunctions *api; |
309 | struct GNUNET_DATASTORE_PluginEnvironment env; | 323 | struct GNUNET_DATASTORE_PluginEnvironment env; |
310 | 324 | ||
311 | cfg = GNUNET_CONFIGURATION_create (); | 325 | cfg = GNUNET_CONFIGURATION_create (); |
312 | if (GNUNET_OK != | 326 | if (GNUNET_OK != |
313 | GNUNET_CONFIGURATION_load (cfg, | 327 | GNUNET_CONFIGURATION_load (cfg, |
@@ -321,6 +335,7 @@ test_plugin (const char *cfg_name) | |||
321 | } | 335 | } |
322 | memset (&env, 0, sizeof (env)); | 336 | memset (&env, 0, sizeof (env)); |
323 | env.cfg = cfg; | 337 | env.cfg = cfg; |
338 | env.duc = &ignore_payload_cb; | ||
324 | GNUNET_snprintf (libname, | 339 | GNUNET_snprintf (libname, |
325 | sizeof (libname), | 340 | sizeof (libname), |
326 | "libgnunet_plugin_datastore_%s", | 341 | "libgnunet_plugin_datastore_%s", |
diff --git a/src/dht/.gitignore b/src/dht/.gitignore index e7f3c2a86..25b1daf28 100644 --- a/src/dht/.gitignore +++ b/src/dht/.gitignore | |||
@@ -1,10 +1,8 @@ | |||
1 | gnunet-service-dht-xvine | ||
2 | gnunet-dht-get | 1 | gnunet-dht-get |
3 | gnunet-dht-monitor | 2 | gnunet-dht-monitor |
4 | gnunet-dht-profiler | 3 | gnunet-dht-profiler |
5 | gnunet-dht-put | 4 | gnunet-dht-put |
6 | gnunet-service-dht | 5 | gnunet-service-dht |
7 | gnunet-service-dht-whanau | ||
8 | test_dht_2dtorus | 6 | test_dht_2dtorus |
9 | test_dht_api | 7 | test_dht_api |
10 | test_dht_line | 8 | test_dht_line |
diff --git a/src/dht/Makefile.am b/src/dht/Makefile.am index 4216af400..f712890ac 100644 --- a/src/dht/Makefile.am +++ b/src/dht/Makefile.am | |||
@@ -50,12 +50,6 @@ libgnunet_plugin_block_dht_la_LDFLAGS = \ | |||
50 | libexec_PROGRAMS = \ | 50 | libexec_PROGRAMS = \ |
51 | gnunet-service-dht | 51 | gnunet-service-dht |
52 | 52 | ||
53 | if HAVE_EXPERIMENTAL | ||
54 | libexec_PROGRAMS += \ | ||
55 | gnunet-service-dht-xvine \ | ||
56 | gnunet-service-dht-whanau | ||
57 | endif | ||
58 | |||
59 | noinst_PROGRAMS = \ | 53 | noinst_PROGRAMS = \ |
60 | gnunet-dht-monitor \ | 54 | gnunet-dht-monitor \ |
61 | gnunet-dht-get \ | 55 | gnunet-dht-get \ |
@@ -82,47 +76,6 @@ gnunet_service_dht_LDADD = \ | |||
82 | $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ | 76 | $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ |
83 | $(top_builddir)/src/hello/libgnunethello.la \ | 77 | $(top_builddir)/src/hello/libgnunethello.la \ |
84 | $(top_builddir)/src/block/libgnunetblock.la \ | 78 | $(top_builddir)/src/block/libgnunetblock.la \ |
85 | $(top_builddir)/src/block/libgnunetblockgroup.la \ | ||
86 | $(top_builddir)/src/datacache/libgnunetdatacache.la \ | ||
87 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
88 | -lm | ||
89 | |||
90 | gnunet_service_dht_xvine_SOURCES = \ | ||
91 | gnunet-service-xdht.c gnunet-service-dht.h \ | ||
92 | gnunet-service-dht_datacache.c gnunet-service-dht_datacache.h \ | ||
93 | gnunet-service-dht_nse.c gnunet-service-dht_nse.h \ | ||
94 | gnunet-service-xdht_neighbours.c gnunet-service-xdht_neighbours.h \ | ||
95 | gnunet-service-xdht_routing.c gnunet-service-xdht_routing.h | ||
96 | |||
97 | gnunet_service_dht_xvine_LDADD = \ | ||
98 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | ||
99 | $(top_builddir)/src/core/libgnunetcore.la \ | ||
100 | $(top_builddir)/src/nse/libgnunetnse.la \ | ||
101 | $(top_builddir)/src/ats/libgnunetats.la \ | ||
102 | $(top_builddir)/src/transport/libgnunettransport.la \ | ||
103 | $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ | ||
104 | $(top_builddir)/src/hello/libgnunethello.la \ | ||
105 | $(top_builddir)/src/block/libgnunetblock.la \ | ||
106 | $(top_builddir)/src/block/libgnunetblockgroup.la \ | ||
107 | $(top_builddir)/src/datacache/libgnunetdatacache.la \ | ||
108 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
109 | -lm | ||
110 | |||
111 | gnunet_service_dht_whanau_SOURCES = \ | ||
112 | gnunet-service-wdht.c gnunet-service-wdht.h \ | ||
113 | gnunet-service-dht_datacache.c gnunet-service-dht_datacache.h \ | ||
114 | gnunet-service-dht_nse.c gnunet-service-dht_nse.h \ | ||
115 | gnunet-service-wdht_neighbours.c gnunet-service-dht_neighbours.h | ||
116 | gnunet_service_dht_whanau_LDADD = \ | ||
117 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | ||
118 | $(top_builddir)/src/core/libgnunetcore.la \ | ||
119 | $(top_builddir)/src/nse/libgnunetnse.la \ | ||
120 | $(top_builddir)/src/ats/libgnunetats.la \ | ||
121 | $(top_builddir)/src/transport/libgnunettransport.la \ | ||
122 | $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ | ||
123 | $(top_builddir)/src/hello/libgnunethello.la \ | ||
124 | $(top_builddir)/src/block/libgnunetblock.la \ | ||
125 | $(top_builddir)/src/block/libgnunetblockgroup.la \ | ||
126 | $(top_builddir)/src/datacache/libgnunetdatacache.la \ | 79 | $(top_builddir)/src/datacache/libgnunetdatacache.la \ |
127 | $(top_builddir)/src/util/libgnunetutil.la \ | 80 | $(top_builddir)/src/util/libgnunetutil.la \ |
128 | -lm | 81 | -lm |
diff --git a/src/dht/dht_api.c b/src/dht/dht_api.c index 070d248ed..ee208b50e 100644 --- a/src/dht/dht_api.c +++ b/src/dht/dht_api.c | |||
@@ -754,12 +754,25 @@ process_client_result (void *cls, | |||
754 | meta_length = | 754 | meta_length = |
755 | sizeof (struct GNUNET_PeerIdentity) * (get_path_length + put_path_length); | 755 | sizeof (struct GNUNET_PeerIdentity) * (get_path_length + put_path_length); |
756 | data_length = msize - meta_length; | 756 | data_length = msize - meta_length; |
757 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
758 | "Giving %u byte reply for %s to application\n", | ||
759 | (unsigned int) data_length, | ||
760 | GNUNET_h2s (key)); | ||
761 | put_path = (const struct GNUNET_PeerIdentity *) &crm[1]; | 757 | put_path = (const struct GNUNET_PeerIdentity *) &crm[1]; |
762 | get_path = &put_path[put_path_length]; | 758 | get_path = &put_path[put_path_length]; |
759 | { | ||
760 | char *pp; | ||
761 | char *gp; | ||
762 | |||
763 | gp = GNUNET_STRINGS_pp2s (get_path, | ||
764 | get_path_length); | ||
765 | pp = GNUNET_STRINGS_pp2s (put_path, | ||
766 | put_path_length); | ||
767 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
768 | "Giving %u byte reply for %s to application (GP: %s, PP: %s)\n", | ||
769 | (unsigned int) data_length, | ||
770 | GNUNET_h2s (key), | ||
771 | gp, | ||
772 | pp); | ||
773 | GNUNET_free (gp); | ||
774 | GNUNET_free (pp); | ||
775 | } | ||
763 | data = &get_path[get_path_length]; | 776 | data = &get_path[get_path_length]; |
764 | /* remember that we've seen this result */ | 777 | /* remember that we've seen this result */ |
765 | GNUNET_CRYPTO_hash (data, | 778 | GNUNET_CRYPTO_hash (data, |
diff --git a/src/dht/gnunet-service-dht_clients.c b/src/dht/gnunet-service-dht_clients.c index a42356e5f..0f521a401 100644 --- a/src/dht/gnunet-service-dht_clients.c +++ b/src/dht/gnunet-service-dht_clients.c | |||
@@ -374,7 +374,10 @@ transmit_request (struct ClientQueryRecord *cqr) | |||
374 | GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, | 374 | GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, |
375 | UINT32_MAX), | 375 | UINT32_MAX), |
376 | NULL, | 376 | NULL, |
377 | 0); | 377 | 0, |
378 | "seen-set-size", | ||
379 | cqr->seen_replies_count, | ||
380 | NULL); | ||
378 | GNUNET_BLOCK_group_set_seen (bg, | 381 | GNUNET_BLOCK_group_set_seen (bg, |
379 | cqr->seen_replies, | 382 | cqr->seen_replies, |
380 | cqr->seen_replies_count); | 383 | cqr->seen_replies_count); |
diff --git a/src/dht/gnunet-service-dht_neighbours.c b/src/dht/gnunet-service-dht_neighbours.c index 1bbc95a06..15071edca 100644 --- a/src/dht/gnunet-service-dht_neighbours.c +++ b/src/dht/gnunet-service-dht_neighbours.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include "platform.h" | 27 | #include "platform.h" |
28 | #include "gnunet_util_lib.h" | 28 | #include "gnunet_util_lib.h" |
29 | #include "gnunet_block_lib.h" | 29 | #include "gnunet_block_lib.h" |
30 | #include "gnunet_block_group_lib.h" | ||
31 | #include "gnunet_hello_lib.h" | 30 | #include "gnunet_hello_lib.h" |
32 | #include "gnunet_constants.h" | 31 | #include "gnunet_constants.h" |
33 | #include "gnunet_protocols.h" | 32 | #include "gnunet_protocols.h" |
@@ -622,8 +621,9 @@ add_known_to_bloom (void *cls, | |||
622 | GNUNET_CRYPTO_hash (key, | 621 | GNUNET_CRYPTO_hash (key, |
623 | sizeof (struct GNUNET_PeerIdentity), | 622 | sizeof (struct GNUNET_PeerIdentity), |
624 | &key_hash); | 623 | &key_hash); |
625 | GNUNET_BLOCK_GROUP_bf_test_and_set (bg, | 624 | GNUNET_BLOCK_group_set_seen (bg, |
626 | &key_hash); | 625 | &key_hash, |
626 | 1); | ||
627 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 627 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
628 | "Adding known peer (%s) to bloomfilter for FIND PEER\n", | 628 | "Adding known peer (%s) to bloomfilter for FIND PEER\n", |
629 | GNUNET_i2s (key)); | 629 | GNUNET_i2s (key)); |
@@ -656,14 +656,15 @@ send_find_peer_message (void *cls) | |||
656 | newly_found_peers = 0; | 656 | newly_found_peers = 0; |
657 | return; | 657 | return; |
658 | } | 658 | } |
659 | bg = GNUNET_BLOCK_GROUP_bf_create (NULL, | 659 | bg = GNUNET_BLOCK_group_create (GDS_block_context, |
660 | DHT_BLOOM_SIZE, | 660 | GNUNET_BLOCK_TYPE_DHT_HELLO, |
661 | GNUNET_CONSTANTS_BLOOMFILTER_K, | 661 | GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, |
662 | GNUNET_BLOCK_TYPE_DHT_HELLO, | 662 | UINT32_MAX), |
663 | GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, | 663 | NULL, |
664 | UINT32_MAX), | 664 | 0, |
665 | NULL, | 665 | "filter-size", |
666 | 0); | 666 | DHT_BLOOM_SIZE, |
667 | NULL); | ||
667 | GNUNET_CONTAINER_multipeermap_iterate (all_connected_peers, | 668 | GNUNET_CONTAINER_multipeermap_iterate (all_connected_peers, |
668 | &add_known_to_bloom, | 669 | &add_known_to_bloom, |
669 | bg); | 670 | bg); |
@@ -677,7 +678,7 @@ send_find_peer_message (void *cls) | |||
677 | GNUNET_CONSTANTS_BLOOMFILTER_K); | 678 | GNUNET_CONSTANTS_BLOOMFILTER_K); |
678 | // FIXME: pass priority!? | 679 | // FIXME: pass priority!? |
679 | GDS_NEIGHBOURS_handle_get (GNUNET_BLOCK_TYPE_DHT_HELLO, | 680 | GDS_NEIGHBOURS_handle_get (GNUNET_BLOCK_TYPE_DHT_HELLO, |
680 | GNUNET_DHT_RO_FIND_PEER, | 681 | GNUNET_DHT_RO_FIND_PEER | GNUNET_DHT_RO_RECORD_ROUTE, |
681 | FIND_PEER_REPLICATION_LEVEL, | 682 | FIND_PEER_REPLICATION_LEVEL, |
682 | 0, | 683 | 0, |
683 | &my_identity_hash, | 684 | &my_identity_hash, |
@@ -1022,10 +1023,10 @@ select_peer (const struct GNUNET_HashCode *key, | |||
1022 | count = 0; | 1023 | count = 0; |
1023 | while ((pos != NULL) && (count < bucket_size)) | 1024 | while ((pos != NULL) && (count < bucket_size)) |
1024 | { | 1025 | { |
1025 | if ((bloom == NULL) || | 1026 | if ( (NULL == bloom) || |
1026 | (GNUNET_NO == | 1027 | (GNUNET_NO == |
1027 | GNUNET_CONTAINER_bloomfilter_test (bloom, | 1028 | GNUNET_CONTAINER_bloomfilter_test (bloom, |
1028 | &pos->phash))) | 1029 | &pos->phash))) |
1029 | { | 1030 | { |
1030 | dist = get_distance (key, | 1031 | dist = get_distance (key, |
1031 | &pos->phash); | 1032 | &pos->phash); |
@@ -1059,8 +1060,14 @@ select_peer (const struct GNUNET_HashCode *key, | |||
1059 | } | 1060 | } |
1060 | if (NULL == chosen) | 1061 | if (NULL == chosen) |
1061 | GNUNET_STATISTICS_update (GDS_stats, | 1062 | GNUNET_STATISTICS_update (GDS_stats, |
1062 | gettext_noop ("# Peer selection failed"), 1, | 1063 | gettext_noop ("# Peer selection failed"), |
1064 | 1, | ||
1063 | GNUNET_NO); | 1065 | GNUNET_NO); |
1066 | else | ||
1067 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1068 | "Selected peer `%s' in greedy routing for %s\n", | ||
1069 | GNUNET_i2s (chosen->id), | ||
1070 | GNUNET_h2s (key)); | ||
1064 | return chosen; | 1071 | return chosen; |
1065 | } | 1072 | } |
1066 | 1073 | ||
@@ -1070,12 +1077,12 @@ select_peer (const struct GNUNET_HashCode *key, | |||
1070 | for (bc = 0; bc <= closest_bucket; bc++) | 1077 | for (bc = 0; bc <= closest_bucket; bc++) |
1071 | { | 1078 | { |
1072 | pos = k_buckets[bc].head; | 1079 | pos = k_buckets[bc].head; |
1073 | while ((pos != NULL) && (count < bucket_size)) | 1080 | while ( (NULL != pos) && (count < bucket_size) ) |
1074 | { | 1081 | { |
1075 | if ((bloom != NULL) && | 1082 | if ( (NULL != bloom) && |
1076 | (GNUNET_YES == | 1083 | (GNUNET_YES == |
1077 | GNUNET_CONTAINER_bloomfilter_test (bloom, | 1084 | GNUNET_CONTAINER_bloomfilter_test (bloom, |
1078 | &pos->phash))) | 1085 | &pos->phash)) ) |
1079 | { | 1086 | { |
1080 | GNUNET_STATISTICS_update (GDS_stats, | 1087 | GNUNET_STATISTICS_update (GDS_stats, |
1081 | gettext_noop | 1088 | gettext_noop |
@@ -1115,7 +1122,13 @@ select_peer (const struct GNUNET_HashCode *key, | |||
1115 | continue; /* Ignore bloomfiltered peers */ | 1122 | continue; /* Ignore bloomfiltered peers */ |
1116 | } | 1123 | } |
1117 | if (0 == selected--) | 1124 | if (0 == selected--) |
1125 | { | ||
1126 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1127 | "Selected peer `%s' in random routing for %s\n", | ||
1128 | GNUNET_i2s (pos->id), | ||
1129 | GNUNET_h2s (key)); | ||
1118 | return pos; | 1130 | return pos; |
1131 | } | ||
1119 | } | 1132 | } |
1120 | } | 1133 | } |
1121 | GNUNET_break (0); | 1134 | GNUNET_break (0); |
@@ -1160,7 +1173,9 @@ get_target_peers (const struct GNUNET_HashCode *key, | |||
1160 | struct PeerInfo *); | 1173 | struct PeerInfo *); |
1161 | for (off = 0; off < ret; off++) | 1174 | for (off = 0; off < ret; off++) |
1162 | { | 1175 | { |
1163 | nxt = select_peer (key, bloom, hop_count); | 1176 | nxt = select_peer (key, |
1177 | bloom, | ||
1178 | hop_count); | ||
1164 | if (NULL == nxt) | 1179 | if (NULL == nxt) |
1165 | break; | 1180 | break; |
1166 | rtargets[off] = nxt; | 1181 | rtargets[off] = nxt; |
@@ -1241,7 +1256,8 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type, | |||
1241 | "Adding myself (%s) to PUT bloomfilter for %s\n", | 1256 | "Adding myself (%s) to PUT bloomfilter for %s\n", |
1242 | GNUNET_i2s (&my_identity), | 1257 | GNUNET_i2s (&my_identity), |
1243 | GNUNET_h2s (key)); | 1258 | GNUNET_h2s (key)); |
1244 | GNUNET_CONTAINER_bloomfilter_add (bf, &my_identity_hash); | 1259 | GNUNET_CONTAINER_bloomfilter_add (bf, |
1260 | &my_identity_hash); | ||
1245 | GNUNET_STATISTICS_update (GDS_stats, | 1261 | GNUNET_STATISTICS_update (GDS_stats, |
1246 | gettext_noop ("# PUT requests routed"), | 1262 | gettext_noop ("# PUT requests routed"), |
1247 | 1, | 1263 | 1, |
@@ -1664,10 +1680,13 @@ handle_dht_p2p_put (void *cls, | |||
1664 | if (GNUNET_YES == log_route_details_stderr) | 1680 | if (GNUNET_YES == log_route_details_stderr) |
1665 | { | 1681 | { |
1666 | char *tmp; | 1682 | char *tmp; |
1683 | char *pp; | ||
1667 | 1684 | ||
1685 | pp = GNUNET_STRINGS_pp2s (put_path, | ||
1686 | putlen); | ||
1668 | tmp = GNUNET_strdup (GNUNET_i2s (&my_identity)); | 1687 | tmp = GNUNET_strdup (GNUNET_i2s (&my_identity)); |
1669 | LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, | 1688 | LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, |
1670 | "R5N PUT %s: %s->%s (%u, %u=>%u)\n", | 1689 | "R5N PUT %s: %s->%s (%u, %u=>%u, PP: %s)\n", |
1671 | GNUNET_h2s (&put->key), | 1690 | GNUNET_h2s (&put->key), |
1672 | GNUNET_i2s (peer->id), | 1691 | GNUNET_i2s (peer->id), |
1673 | tmp, | 1692 | tmp, |
@@ -1675,8 +1694,9 @@ handle_dht_p2p_put (void *cls, | |||
1675 | GNUNET_CRYPTO_hash_matching_bits (&peer->phash, | 1694 | GNUNET_CRYPTO_hash_matching_bits (&peer->phash, |
1676 | &put->key), | 1695 | &put->key), |
1677 | GNUNET_CRYPTO_hash_matching_bits (&my_identity_hash, | 1696 | GNUNET_CRYPTO_hash_matching_bits (&my_identity_hash, |
1678 | &put->key) | 1697 | &put->key), |
1679 | ); | 1698 | pp); |
1699 | GNUNET_free (pp); | ||
1680 | GNUNET_free (tmp); | 1700 | GNUNET_free (tmp); |
1681 | } | 1701 | } |
1682 | switch (GNUNET_BLOCK_get_key | 1702 | switch (GNUNET_BLOCK_get_key |
@@ -1839,22 +1859,26 @@ handle_find_peer (const struct GNUNET_PeerIdentity *sender, | |||
1839 | struct PeerInfo *peer; | 1859 | struct PeerInfo *peer; |
1840 | unsigned int choice; | 1860 | unsigned int choice; |
1841 | const struct GNUNET_HELLO_Message *hello; | 1861 | const struct GNUNET_HELLO_Message *hello; |
1862 | size_t hello_size; | ||
1842 | 1863 | ||
1843 | /* first, check about our own HELLO */ | 1864 | /* first, check about our own HELLO */ |
1844 | if (NULL != GDS_my_hello) | 1865 | if (NULL != GDS_my_hello) |
1845 | { | 1866 | { |
1846 | if (GNUNET_YES != | 1867 | hello_size = GNUNET_HELLO_size ((const struct GNUNET_HELLO_Message *) GDS_my_hello); |
1847 | GNUNET_BLOCK_GROUP_bf_test_and_set (bg, | 1868 | GNUNET_break (hello_size >= sizeof (struct GNUNET_MessageHeader)); |
1848 | &my_identity_hash)) | 1869 | if (GNUNET_BLOCK_EVALUATION_OK_MORE == |
1870 | GNUNET_BLOCK_evaluate (GDS_block_context, | ||
1871 | GNUNET_BLOCK_TYPE_DHT_HELLO, | ||
1872 | bg, | ||
1873 | GNUNET_BLOCK_EO_LOCAL_SKIP_CRYPTO, | ||
1874 | &my_identity_hash, | ||
1875 | NULL, 0, | ||
1876 | GDS_my_hello, | ||
1877 | hello_size)) | ||
1849 | { | 1878 | { |
1850 | size_t hello_size; | ||
1851 | |||
1852 | hello_size = GNUNET_HELLO_size ((const struct GNUNET_HELLO_Message *) GDS_my_hello); | ||
1853 | GNUNET_break (hello_size >= sizeof (struct GNUNET_MessageHeader)); | ||
1854 | GDS_NEIGHBOURS_handle_reply (sender, | 1879 | GDS_NEIGHBOURS_handle_reply (sender, |
1855 | GNUNET_BLOCK_TYPE_DHT_HELLO, | 1880 | GNUNET_BLOCK_TYPE_DHT_HELLO, |
1856 | GNUNET_TIME_relative_to_absolute | 1881 | GNUNET_TIME_relative_to_absolute (hello_expiration), |
1857 | (hello_expiration), | ||
1858 | key, | 1882 | key, |
1859 | 0, | 1883 | 0, |
1860 | NULL, | 1884 | NULL, |
@@ -1911,9 +1935,15 @@ handle_find_peer (const struct GNUNET_PeerIdentity *sender, | |||
1911 | peer = bucket->head; | 1935 | peer = bucket->head; |
1912 | hello = GDS_HELLO_get (peer->id); | 1936 | hello = GDS_HELLO_get (peer->id); |
1913 | } while ( (NULL == hello) || | 1937 | } while ( (NULL == hello) || |
1914 | (GNUNET_YES == | 1938 | (GNUNET_BLOCK_EVALUATION_OK_MORE != |
1915 | GNUNET_BLOCK_GROUP_bf_test_and_set (bg, | 1939 | GNUNET_BLOCK_evaluate (GDS_block_context, |
1916 | &peer->phash)) ); | 1940 | GNUNET_BLOCK_TYPE_DHT_HELLO, |
1941 | bg, | ||
1942 | GNUNET_BLOCK_EO_LOCAL_SKIP_CRYPTO, | ||
1943 | &peer->phash, | ||
1944 | NULL, 0, | ||
1945 | hello, | ||
1946 | (hello_size = GNUNET_HELLO_size (hello)))) ); | ||
1917 | GDS_NEIGHBOURS_handle_reply (sender, | 1947 | GDS_NEIGHBOURS_handle_reply (sender, |
1918 | GNUNET_BLOCK_TYPE_DHT_HELLO, | 1948 | GNUNET_BLOCK_TYPE_DHT_HELLO, |
1919 | GNUNET_TIME_relative_to_absolute | 1949 | GNUNET_TIME_relative_to_absolute |
@@ -1924,14 +1954,14 @@ handle_find_peer (const struct GNUNET_PeerIdentity *sender, | |||
1924 | 0, | 1954 | 0, |
1925 | NULL, | 1955 | NULL, |
1926 | hello, | 1956 | hello, |
1927 | GNUNET_HELLO_size (hello)); | 1957 | hello_size); |
1928 | } | 1958 | } |
1929 | 1959 | ||
1930 | 1960 | ||
1931 | /** | 1961 | /** |
1932 | * Handle a result from local datacache for a GET operation. | 1962 | * Handle a result from local datacache for a GET operation. |
1933 | * | 1963 | * |
1934 | * @param cls the `struct ClientHandle` of the client doing the query | 1964 | * @param cls the `struct PeerInfo` for which this is a reply |
1935 | * @param type type of the block | 1965 | * @param type type of the block |
1936 | * @param expiration_time when does the content expire | 1966 | * @param expiration_time when does the content expire |
1937 | * @param key key for the content | 1967 | * @param key key for the content |
@@ -1954,15 +1984,23 @@ handle_local_result (void *cls, | |||
1954 | const void *data, | 1984 | const void *data, |
1955 | size_t data_size) | 1985 | size_t data_size) |
1956 | { | 1986 | { |
1957 | // FIXME: we can probably do better here by | 1987 | struct PeerInfo *peer = cls; |
1958 | // passing the peer that did the query in the closure... | 1988 | char *pp; |
1959 | GDS_ROUTING_process (NULL, | 1989 | |
1960 | type, | 1990 | pp = GNUNET_STRINGS_pp2s (put_path, |
1961 | expiration_time, | 1991 | put_path_length); |
1962 | key, | 1992 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1963 | put_path_length, put_path, | 1993 | "Found local result for %s (PP: %s)\n", |
1964 | 0, NULL, | 1994 | GNUNET_h2s (key), |
1965 | data, data_size); | 1995 | pp); |
1996 | GNUNET_free (pp); | ||
1997 | GDS_NEIGHBOURS_handle_reply (peer->id, | ||
1998 | type, | ||
1999 | expiration_time, | ||
2000 | key, | ||
2001 | put_path_length, put_path, | ||
2002 | get_path_length, get_path, | ||
2003 | data, data_size); | ||
1966 | } | 2004 | } |
1967 | 2005 | ||
1968 | 2006 | ||
@@ -2013,11 +2051,6 @@ handle_dht_p2p_get (void *cls, | |||
2013 | const char *xquery; | 2051 | const char *xquery; |
2014 | int forwarded; | 2052 | int forwarded; |
2015 | 2053 | ||
2016 | if (NULL == peer) | ||
2017 | { | ||
2018 | GNUNET_break (0); | ||
2019 | return; | ||
2020 | } | ||
2021 | /* parse and validate message */ | 2054 | /* parse and validate message */ |
2022 | msize = ntohs (get->header.size); | 2055 | msize = ntohs (get->header.size); |
2023 | xquery_size = ntohl (get->xquery_size); | 2056 | xquery_size = ntohl (get->xquery_size); |
@@ -2052,15 +2085,10 @@ handle_dht_p2p_get (void *cls, | |||
2052 | xquery); | 2085 | xquery); |
2053 | GNUNET_free (tmp); | 2086 | GNUNET_free (tmp); |
2054 | } | 2087 | } |
2055 | bg = GNUNET_BLOCK_group_create (GDS_block_context, | ||
2056 | type, | ||
2057 | get->bf_mutator, | ||
2058 | &xquery[xquery_size], | ||
2059 | reply_bf_size); | ||
2060 | eval | 2088 | eval |
2061 | = GNUNET_BLOCK_evaluate (GDS_block_context, | 2089 | = GNUNET_BLOCK_evaluate (GDS_block_context, |
2062 | type, | 2090 | type, |
2063 | bg, | 2091 | NULL, |
2064 | GNUNET_BLOCK_EO_NONE, | 2092 | GNUNET_BLOCK_EO_NONE, |
2065 | &get->key, | 2093 | &get->key, |
2066 | xquery, | 2094 | xquery, |
@@ -2071,7 +2099,6 @@ handle_dht_p2p_get (void *cls, | |||
2071 | { | 2099 | { |
2072 | /* request invalid or block type not supported */ | 2100 | /* request invalid or block type not supported */ |
2073 | GNUNET_break_op (eval == GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED); | 2101 | GNUNET_break_op (eval == GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED); |
2074 | GNUNET_BLOCK_group_destroy (bg); | ||
2075 | return; | 2102 | return; |
2076 | } | 2103 | } |
2077 | peer_bf = GNUNET_CONTAINER_bloomfilter_init (get->bloomfilter, | 2104 | peer_bf = GNUNET_CONTAINER_bloomfilter_init (get->bloomfilter, |
@@ -2080,14 +2107,14 @@ handle_dht_p2p_get (void *cls, | |||
2080 | GNUNET_break_op (GNUNET_YES == | 2107 | GNUNET_break_op (GNUNET_YES == |
2081 | GNUNET_CONTAINER_bloomfilter_test (peer_bf, | 2108 | GNUNET_CONTAINER_bloomfilter_test (peer_bf, |
2082 | &peer->phash)); | 2109 | &peer->phash)); |
2083 | /* remember request for routing replies */ | 2110 | bg = GNUNET_BLOCK_group_create (GDS_block_context, |
2084 | GDS_ROUTING_add (peer->id, | 2111 | type, |
2085 | type, | 2112 | get->bf_mutator, |
2086 | bg, /* bg now owned by routing, but valid at least until end of this function! */ | 2113 | &xquery[xquery_size], |
2087 | options, | 2114 | reply_bf_size, |
2088 | &get->key, | 2115 | "filter-size", |
2089 | xquery, | 2116 | reply_bf_size, |
2090 | xquery_size); | 2117 | NULL); |
2091 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2118 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2092 | "GET for %s at %s after %u hops\n", | 2119 | "GET for %s at %s after %u hops\n", |
2093 | GNUNET_h2s (&get->key), | 2120 | GNUNET_h2s (&get->key), |
@@ -2116,7 +2143,7 @@ handle_dht_p2p_get (void *cls, | |||
2116 | xquery_size, | 2143 | xquery_size, |
2117 | bg, | 2144 | bg, |
2118 | &handle_local_result, | 2145 | &handle_local_result, |
2119 | NULL); | 2146 | peer); |
2120 | } | 2147 | } |
2121 | } | 2148 | } |
2122 | else | 2149 | else |
@@ -2127,6 +2154,15 @@ handle_dht_p2p_get (void *cls, | |||
2127 | GNUNET_NO); | 2154 | GNUNET_NO); |
2128 | } | 2155 | } |
2129 | 2156 | ||
2157 | /* remember request for routing replies */ | ||
2158 | GDS_ROUTING_add (peer->id, | ||
2159 | type, | ||
2160 | bg, /* bg now owned by routing, but valid at least until end of this function! */ | ||
2161 | options, | ||
2162 | &get->key, | ||
2163 | xquery, | ||
2164 | xquery_size); | ||
2165 | |||
2130 | /* P2P forwarding */ | 2166 | /* P2P forwarding */ |
2131 | forwarded = GNUNET_NO; | 2167 | forwarded = GNUNET_NO; |
2132 | if (eval != GNUNET_BLOCK_EVALUATION_OK_LAST) | 2168 | if (eval != GNUNET_BLOCK_EVALUATION_OK_LAST) |
@@ -2189,6 +2225,81 @@ check_dht_p2p_result (void *cls, | |||
2189 | 2225 | ||
2190 | 2226 | ||
2191 | /** | 2227 | /** |
2228 | * Process a reply, after the @a get_path has been updated. | ||
2229 | * | ||
2230 | * @param expiration_time when does the reply expire | ||
2231 | * @param key key matching the query | ||
2232 | * @param get_path_length number of entries in @a get_path | ||
2233 | * @param get_path path the reply has taken | ||
2234 | * @param put_path_length number of entries in @a put_path | ||
2235 | * @param put_path path the PUT has taken | ||
2236 | * @param type type of the block | ||
2237 | * @param data_size number of bytes in @a data | ||
2238 | * @param data payload of the reply | ||
2239 | */ | ||
2240 | static void | ||
2241 | process_reply_with_path (struct GNUNET_TIME_Absolute expiration_time, | ||
2242 | const struct GNUNET_HashCode *key, | ||
2243 | unsigned int get_path_length, | ||
2244 | const struct GNUNET_PeerIdentity *get_path, | ||
2245 | unsigned int put_path_length, | ||
2246 | const struct GNUNET_PeerIdentity *put_path, | ||
2247 | enum GNUNET_BLOCK_Type type, | ||
2248 | size_t data_size, | ||
2249 | const void *data) | ||
2250 | { | ||
2251 | /* forward to local clients */ | ||
2252 | GDS_CLIENTS_handle_reply (expiration_time, | ||
2253 | key, | ||
2254 | get_path_length, | ||
2255 | get_path, | ||
2256 | put_path_length, | ||
2257 | put_path, | ||
2258 | type, | ||
2259 | data_size, | ||
2260 | data); | ||
2261 | GDS_CLIENTS_process_get_resp (type, | ||
2262 | get_path, | ||
2263 | get_path_length, | ||
2264 | put_path, | ||
2265 | put_path_length, | ||
2266 | expiration_time, | ||
2267 | key, | ||
2268 | data, | ||
2269 | data_size); | ||
2270 | if (GNUNET_YES == cache_results) | ||
2271 | { | ||
2272 | struct GNUNET_PeerIdentity xput_path[get_path_length + 1 + put_path_length]; | ||
2273 | |||
2274 | GNUNET_memcpy (xput_path, | ||
2275 | put_path, | ||
2276 | put_path_length * sizeof (struct GNUNET_PeerIdentity)); | ||
2277 | GNUNET_memcpy (&xput_path[put_path_length], | ||
2278 | get_path, | ||
2279 | get_path_length * sizeof (struct GNUNET_PeerIdentity)); | ||
2280 | |||
2281 | GDS_DATACACHE_handle_put (expiration_time, | ||
2282 | key, | ||
2283 | get_path_length + put_path_length, | ||
2284 | xput_path, | ||
2285 | type, | ||
2286 | data_size, | ||
2287 | data); | ||
2288 | } | ||
2289 | /* forward to other peers */ | ||
2290 | GDS_ROUTING_process (type, | ||
2291 | expiration_time, | ||
2292 | key, | ||
2293 | put_path_length, | ||
2294 | put_path, | ||
2295 | get_path_length, | ||
2296 | get_path, | ||
2297 | data, | ||
2298 | data_size); | ||
2299 | } | ||
2300 | |||
2301 | |||
2302 | /** | ||
2192 | * Core handler for p2p result messages. | 2303 | * Core handler for p2p result messages. |
2193 | * | 2304 | * |
2194 | * @param cls closure | 2305 | * @param cls closure |
@@ -2230,14 +2341,23 @@ handle_dht_p2p_result (void *cls, | |||
2230 | if (GNUNET_YES == log_route_details_stderr) | 2341 | if (GNUNET_YES == log_route_details_stderr) |
2231 | { | 2342 | { |
2232 | char *tmp; | 2343 | char *tmp; |
2344 | char *pp; | ||
2345 | char *gp; | ||
2233 | 2346 | ||
2347 | gp = GNUNET_STRINGS_pp2s (get_path, | ||
2348 | get_path_length); | ||
2349 | pp = GNUNET_STRINGS_pp2s (put_path, | ||
2350 | put_path_length); | ||
2234 | tmp = GNUNET_strdup (GNUNET_i2s (&my_identity)); | 2351 | tmp = GNUNET_strdup (GNUNET_i2s (&my_identity)); |
2235 | LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, | 2352 | LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, |
2236 | "R5N RESULT %s: %s->%s (%u)\n", | 2353 | "R5N RESULT %s: %s->%s (GP: %s, PP: %s)\n", |
2237 | GNUNET_h2s (&prm->key), | 2354 | GNUNET_h2s (&prm->key), |
2238 | GNUNET_i2s (peer->id), | 2355 | GNUNET_i2s (peer->id), |
2239 | tmp, | 2356 | tmp, |
2240 | get_path_length + 1); | 2357 | gp, |
2358 | pp); | ||
2359 | GNUNET_free (gp); | ||
2360 | GNUNET_free (pp); | ||
2241 | GNUNET_free (tmp); | 2361 | GNUNET_free (tmp); |
2242 | } | 2362 | } |
2243 | /* if we got a HELLO, consider it for our own routing table */ | 2363 | /* if we got a HELLO, consider it for our own routing table */ |
@@ -2273,78 +2393,44 @@ handle_dht_p2p_result (void *cls, | |||
2273 | h); | 2393 | h); |
2274 | } | 2394 | } |
2275 | 2395 | ||
2276 | /* append 'peer' to 'get_path' */ | ||
2277 | { | ||
2278 | struct GNUNET_PeerIdentity xget_path[get_path_length + 1]; | ||
2279 | 2396 | ||
2280 | #if SANITY_CHECKS | 2397 | /* First, check if 'peer' is already on the path, and if |
2281 | for (unsigned int i=0;i<=get_path_length;i++) | 2398 | so, truncate it instead of expanding. */ |
2399 | for (unsigned int i=0;i<=get_path_length;i++) | ||
2400 | if (0 == memcmp (&get_path[i], | ||
2401 | peer->id, | ||
2402 | sizeof (struct GNUNET_PeerIdentity))) | ||
2282 | { | 2403 | { |
2283 | for (unsigned int j=0;j<i;j++) | 2404 | process_reply_with_path (GNUNET_TIME_absolute_ntoh (prm->expiration_time), |
2284 | { | 2405 | &prm->key, |
2285 | GNUNET_break (0 != memcmp (&get_path[i], | 2406 | i, |
2286 | &get_path[j], | 2407 | get_path, |
2287 | sizeof (struct GNUNET_PeerIdentity))); | 2408 | put_path_length, |
2288 | } | 2409 | put_path, |
2289 | GNUNET_break (0 != memcmp (&get_path[i], | 2410 | type, |
2290 | peer->id, | 2411 | data_size, |
2291 | sizeof (struct GNUNET_PeerIdentity))); | 2412 | data); |
2413 | return; | ||
2292 | } | 2414 | } |
2293 | #endif | 2415 | |
2416 | /* Need to append 'peer' to 'get_path' (normal case) */ | ||
2417 | { | ||
2418 | struct GNUNET_PeerIdentity xget_path[get_path_length + 1]; | ||
2419 | |||
2294 | GNUNET_memcpy (xget_path, | 2420 | GNUNET_memcpy (xget_path, |
2295 | get_path, | 2421 | get_path, |
2296 | get_path_length * sizeof (struct GNUNET_PeerIdentity)); | 2422 | get_path_length * sizeof (struct GNUNET_PeerIdentity)); |
2297 | xget_path[get_path_length] = *peer->id; | 2423 | xget_path[get_path_length] = *peer->id; |
2298 | get_path_length++; | ||
2299 | |||
2300 | /* forward to local clients */ | ||
2301 | GDS_CLIENTS_handle_reply (GNUNET_TIME_absolute_ntoh (prm->expiration_time), | ||
2302 | &prm->key, | ||
2303 | get_path_length, | ||
2304 | xget_path, | ||
2305 | put_path_length, | ||
2306 | put_path, | ||
2307 | type, | ||
2308 | data_size, | ||
2309 | data); | ||
2310 | GDS_CLIENTS_process_get_resp (type, | ||
2311 | xget_path, | ||
2312 | get_path_length, | ||
2313 | put_path, put_path_length, | ||
2314 | GNUNET_TIME_absolute_ntoh (prm->expiration_time), | ||
2315 | &prm->key, | ||
2316 | data, | ||
2317 | data_size); | ||
2318 | if (GNUNET_YES == cache_results) | ||
2319 | { | ||
2320 | struct GNUNET_PeerIdentity xput_path[get_path_length + 1 + put_path_length]; | ||
2321 | 2424 | ||
2322 | GNUNET_memcpy (xput_path, | 2425 | process_reply_with_path (GNUNET_TIME_absolute_ntoh (prm->expiration_time), |
2323 | put_path, | 2426 | &prm->key, |
2324 | put_path_length * sizeof (struct GNUNET_PeerIdentity)); | 2427 | get_path_length + 1, |
2325 | GNUNET_memcpy (&xput_path[put_path_length], | 2428 | xget_path, |
2326 | xget_path, | 2429 | put_path_length, |
2327 | get_path_length * sizeof (struct GNUNET_PeerIdentity)); | 2430 | put_path, |
2328 | 2431 | type, | |
2329 | GDS_DATACACHE_handle_put (GNUNET_TIME_absolute_ntoh (prm->expiration_time), | 2432 | data_size, |
2330 | &prm->key, | 2433 | data); |
2331 | get_path_length + put_path_length, | ||
2332 | xput_path, | ||
2333 | type, | ||
2334 | data_size, | ||
2335 | data); | ||
2336 | } | ||
2337 | /* forward to other peers */ | ||
2338 | GDS_ROUTING_process (NULL, | ||
2339 | type, | ||
2340 | GNUNET_TIME_absolute_ntoh (prm->expiration_time), | ||
2341 | &prm->key, | ||
2342 | put_path_length, | ||
2343 | put_path, | ||
2344 | get_path_length, | ||
2345 | xget_path, | ||
2346 | data, | ||
2347 | data_size); | ||
2348 | } | 2434 | } |
2349 | } | 2435 | } |
2350 | 2436 | ||
diff --git a/src/dht/gnunet-service-dht_routing.c b/src/dht/gnunet-service-dht_routing.c index 252995737..098b6e895 100644 --- a/src/dht/gnunet-service-dht_routing.c +++ b/src/dht/gnunet-service-dht_routing.c | |||
@@ -209,6 +209,11 @@ process (void *cls, | |||
209 | rr->xquery_size, | 209 | rr->xquery_size, |
210 | pc->data, | 210 | pc->data, |
211 | pc->data_size); | 211 | pc->data_size); |
212 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
213 | "Result for %s of type %d was evaluated as %d\n", | ||
214 | GNUNET_h2s (key), | ||
215 | pc->type, | ||
216 | eval); | ||
212 | switch (eval) | 217 | switch (eval) |
213 | { | 218 | { |
214 | case GNUNET_BLOCK_EVALUATION_OK_MORE: | 219 | case GNUNET_BLOCK_EVALUATION_OK_MORE: |
@@ -282,8 +287,7 @@ process (void *cls, | |||
282 | * @param data_size number of bytes in data | 287 | * @param data_size number of bytes in data |
283 | */ | 288 | */ |
284 | void | 289 | void |
285 | GDS_ROUTING_process (void *cls, | 290 | GDS_ROUTING_process (enum GNUNET_BLOCK_Type type, |
286 | enum GNUNET_BLOCK_Type type, | ||
287 | struct GNUNET_TIME_Absolute expiration_time, | 291 | struct GNUNET_TIME_Absolute expiration_time, |
288 | const struct GNUNET_HashCode *key, | 292 | const struct GNUNET_HashCode *key, |
289 | unsigned int put_path_length, | 293 | unsigned int put_path_length, |
diff --git a/src/dht/gnunet-service-dht_routing.h b/src/dht/gnunet-service-dht_routing.h index 1d9284164..ad7958363 100644 --- a/src/dht/gnunet-service-dht_routing.h +++ b/src/dht/gnunet-service-dht_routing.h | |||
@@ -35,10 +35,9 @@ | |||
35 | * Handle a reply (route to origin). Only forwards the reply back to | 35 | * Handle a reply (route to origin). Only forwards the reply back to |
36 | * other peers waiting for it. Does not do local caching or | 36 | * other peers waiting for it. Does not do local caching or |
37 | * forwarding to local clients. Essentially calls | 37 | * forwarding to local clients. Essentially calls |
38 | * GDS_NEIGHBOURS_handle_reply for all peers that sent us a matching | 38 | * #GDS_NEIGHBOURS_handle_reply() for all peers that sent us a matching |
39 | * request recently. | 39 | * request recently. |
40 | * | 40 | * |
41 | * @param cls closure | ||
42 | * @param type type of the block | 41 | * @param type type of the block |
43 | * @param expiration_time when does the content expire | 42 | * @param expiration_time when does the content expire |
44 | * @param key key for the content | 43 | * @param key key for the content |
@@ -50,8 +49,7 @@ | |||
50 | * @param data_size number of bytes in @a data | 49 | * @param data_size number of bytes in @a data |
51 | */ | 50 | */ |
52 | void | 51 | void |
53 | GDS_ROUTING_process (void *cls, | 52 | GDS_ROUTING_process (enum GNUNET_BLOCK_Type type, |
54 | enum GNUNET_BLOCK_Type type, | ||
55 | struct GNUNET_TIME_Absolute expiration_time, | 53 | struct GNUNET_TIME_Absolute expiration_time, |
56 | const struct GNUNET_HashCode *key, | 54 | const struct GNUNET_HashCode *key, |
57 | unsigned int put_path_length, | 55 | unsigned int put_path_length, |
@@ -72,7 +70,7 @@ GDS_ROUTING_process (void *cls, | |||
72 | * @param key key for the content | 70 | * @param key key for the content |
73 | * @param xquery extended query | 71 | * @param xquery extended query |
74 | * @param xquery_size number of bytes in @a xquery | 72 | * @param xquery_size number of bytes in @a xquery |
75 | */ | 73 | */ |
76 | void | 74 | void |
77 | GDS_ROUTING_add (const struct GNUNET_PeerIdentity *sender, | 75 | GDS_ROUTING_add (const struct GNUNET_PeerIdentity *sender, |
78 | enum GNUNET_BLOCK_Type type, | 76 | enum GNUNET_BLOCK_Type type, |
diff --git a/src/dht/gnunet-service-wdht.c b/src/dht/gnunet-service-wdht.c deleted file mode 100644 index e1ca1c968..000000000 --- a/src/dht/gnunet-service-wdht.c +++ /dev/null | |||
@@ -1,103 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2009, 2010, 2011 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file dht/gnunet-service-wdht.c | ||
23 | * @brief GNUnet DHT service | ||
24 | * @author Christian Grothoff | ||
25 | * @author Nathan Evans | ||
26 | */ | ||
27 | #include "platform.h" | ||
28 | #include "gnunet_block_lib.h" | ||
29 | #include "gnunet_util_lib.h" | ||
30 | #include "gnunet_transport_service.h" | ||
31 | #include "gnunet_hello_lib.h" | ||
32 | #include "gnunet_dht_service.h" | ||
33 | #include "gnunet_statistics_service.h" | ||
34 | #include "gnunet-service-wdht.h" | ||
35 | #include "gnunet-service-dht_datacache.h" | ||
36 | #include "gnunet-service-dht_neighbours.h" | ||
37 | #include "gnunet-service-dht_nse.h" | ||
38 | |||
39 | |||
40 | /* Code shared between different DHT implementations */ | ||
41 | #include "gnunet-service-dht_clients.c" | ||
42 | |||
43 | |||
44 | /** | ||
45 | * Task run during shutdown. | ||
46 | * | ||
47 | * @param cls unused | ||
48 | */ | ||
49 | static void | ||
50 | shutdown_task (void *cls) | ||
51 | { | ||
52 | GDS_NEIGHBOURS_done (); | ||
53 | GDS_DATACACHE_done (); | ||
54 | GDS_NSE_done (); | ||
55 | if (NULL != GDS_block_context) | ||
56 | { | ||
57 | GNUNET_BLOCK_context_destroy (GDS_block_context); | ||
58 | GDS_block_context = NULL; | ||
59 | } | ||
60 | if (NULL != GDS_stats) | ||
61 | { | ||
62 | GNUNET_STATISTICS_destroy (GDS_stats, GNUNET_YES); | ||
63 | GDS_stats = NULL; | ||
64 | } | ||
65 | GDS_CLIENTS_stop (); | ||
66 | } | ||
67 | |||
68 | |||
69 | /** | ||
70 | * Process dht requests. | ||
71 | * | ||
72 | * @param cls closure | ||
73 | * @param c configuration to use | ||
74 | * @param service the initialized service | ||
75 | */ | ||
76 | static void | ||
77 | run (void *cls, | ||
78 | const struct GNUNET_CONFIGURATION_Handle *c, | ||
79 | struct GNUNET_SERVICE_Handle *service) | ||
80 | { | ||
81 | GDS_cfg = c; | ||
82 | GDS_service = service; | ||
83 | GDS_block_context = GNUNET_BLOCK_context_create (GDS_cfg); | ||
84 | GDS_stats = GNUNET_STATISTICS_create ("dht", | ||
85 | GDS_cfg); | ||
86 | GDS_NSE_init (); | ||
87 | GDS_DATACACHE_init (); | ||
88 | GDS_CLIENTS_init (); | ||
89 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, | ||
90 | NULL); | ||
91 | if (GNUNET_OK != GDS_NEIGHBOURS_init ()) | ||
92 | { | ||
93 | GNUNET_SCHEDULER_shutdown (); | ||
94 | return; | ||
95 | } | ||
96 | } | ||
97 | |||
98 | |||
99 | /* Finally, define the main method */ | ||
100 | GDS_DHT_SERVICE_INIT("wdht", &run); | ||
101 | |||
102 | |||
103 | /* end of gnunet-service-wdht.c */ | ||
diff --git a/src/dht/gnunet-service-wdht.h b/src/dht/gnunet-service-wdht.h deleted file mode 100644 index 5a8e2e21d..000000000 --- a/src/dht/gnunet-service-wdht.h +++ /dev/null | |||
@@ -1,50 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2011 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file dht/gnunet-service-xdht.h | ||
23 | * @brief GNUnet DHT globals | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | #ifndef GNUNET_SERVICE_XDHT_H | ||
27 | #define GNUNET_SERVICE_XDHT_H | ||
28 | |||
29 | #include "gnunet_util_lib.h" | ||
30 | #include "gnunet_statistics_service.h" | ||
31 | #include "gnunet_transport_service.h" | ||
32 | |||
33 | #define DEBUG_DHT GNUNET_EXTRA_LOGGING | ||
34 | |||
35 | /** | ||
36 | * Configuration we use. | ||
37 | */ | ||
38 | extern const struct GNUNET_CONFIGURATION_Handle *GDS_cfg; | ||
39 | |||
40 | /** | ||
41 | * Our handle to the BLOCK library. | ||
42 | */ | ||
43 | extern struct GNUNET_BLOCK_Context *GDS_block_context; | ||
44 | |||
45 | /** | ||
46 | * Handle for the statistics service. | ||
47 | */ | ||
48 | extern struct GNUNET_STATISTICS_Handle *GDS_stats; | ||
49 | |||
50 | #endif | ||
diff --git a/src/dht/gnunet-service-wdht_clients.c b/src/dht/gnunet-service-wdht_clients.c deleted file mode 100644 index 7ad0d2904..000000000 --- a/src/dht/gnunet-service-wdht_clients.c +++ /dev/null | |||
@@ -1,1428 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2009, 2010, 2011, 2016 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file dht/gnunet-service-wdht_clients.c | ||
23 | * @brief GNUnet DHT service's client management code | ||
24 | * @author Christian Grothoff | ||
25 | * @author Nathan Evans | ||
26 | */ | ||
27 | |||
28 | #include "platform.h" | ||
29 | #include "gnunet_constants.h" | ||
30 | #include "gnunet_protocols.h" | ||
31 | #include "gnunet_statistics_service.h" | ||
32 | #include "gnunet-service-wdht.h" | ||
33 | #include "gnunet-service-wdht_clients.h" | ||
34 | #include "gnunet-service-dht_datacache.h" | ||
35 | #include "gnunet-service-wdht_neighbours.h" | ||
36 | #include "dht.h" | ||
37 | |||
38 | |||
39 | /** | ||
40 | * Should routing details be logged to stderr (for debugging)? | ||
41 | */ | ||
42 | #define LOG_TRAFFIC(kind,...) GNUNET_log_from (kind, "dht-traffic",__VA_ARGS__) | ||
43 | |||
44 | #define LOG(kind,...) GNUNET_log_from (kind, "dht-clients",__VA_ARGS__) | ||
45 | |||
46 | #define DEBUG(...) \ | ||
47 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__) | ||
48 | |||
49 | /** | ||
50 | * Linked list of messages to send to clients. | ||
51 | */ | ||
52 | struct PendingMessage | ||
53 | { | ||
54 | /** | ||
55 | * Pointer to next item in the list | ||
56 | */ | ||
57 | struct PendingMessage *next; | ||
58 | |||
59 | /** | ||
60 | * Pointer to previous item in the list | ||
61 | */ | ||
62 | struct PendingMessage *prev; | ||
63 | |||
64 | /** | ||
65 | * Actual message to be sent, allocated at the end of the struct: | ||
66 | * // msg = (cast) &pm[1]; | ||
67 | * // GNUNET_memcpy (&pm[1], data, len); | ||
68 | */ | ||
69 | const struct GNUNET_MessageHeader *msg; | ||
70 | |||
71 | }; | ||
72 | |||
73 | |||
74 | /** | ||
75 | * Struct containing information about a client, | ||
76 | * handle to connect to it, and any pending messages | ||
77 | * that need to be sent to it. | ||
78 | */ | ||
79 | struct ClientList | ||
80 | { | ||
81 | /** | ||
82 | * Linked list of active clients | ||
83 | */ | ||
84 | struct ClientList *next; | ||
85 | |||
86 | /** | ||
87 | * Linked list of active clients | ||
88 | */ | ||
89 | struct ClientList *prev; | ||
90 | |||
91 | /** | ||
92 | * The handle to this client | ||
93 | */ | ||
94 | struct GNUNET_SERVER_Client *client_handle; | ||
95 | |||
96 | /** | ||
97 | * Handle to the current transmission request, NULL | ||
98 | * if none pending. | ||
99 | */ | ||
100 | struct GNUNET_SERVER_TransmitHandle *transmit_handle; | ||
101 | |||
102 | /** | ||
103 | * Linked list of pending messages for this client | ||
104 | */ | ||
105 | struct PendingMessage *pending_head; | ||
106 | |||
107 | /** | ||
108 | * Tail of linked list of pending messages for this client | ||
109 | */ | ||
110 | struct PendingMessage *pending_tail; | ||
111 | |||
112 | }; | ||
113 | |||
114 | |||
115 | /** | ||
116 | * Entry in the local forwarding map for a client's GET request. | ||
117 | */ | ||
118 | struct ClientQueryRecord | ||
119 | { | ||
120 | |||
121 | /** | ||
122 | * The key this request was about | ||
123 | */ | ||
124 | struct GNUNET_HashCode key; | ||
125 | |||
126 | /** | ||
127 | * Client responsible for the request. | ||
128 | */ | ||
129 | struct ClientList *client; | ||
130 | |||
131 | /** | ||
132 | * Extended query (see gnunet_block_lib.h), allocated at the end of this struct. | ||
133 | */ | ||
134 | const void *xquery; | ||
135 | |||
136 | /** | ||
137 | * Replies we have already seen for this request. | ||
138 | */ | ||
139 | struct GNUNET_HashCode *seen_replies; | ||
140 | |||
141 | /** | ||
142 | * Pointer to this nodes heap location in the retry-heap (for fast removal) | ||
143 | */ | ||
144 | struct GNUNET_CONTAINER_HeapNode *hnode; | ||
145 | |||
146 | /** | ||
147 | * What's the delay between re-try operations that we currently use for this | ||
148 | * request? | ||
149 | */ | ||
150 | struct GNUNET_TIME_Relative retry_frequency; | ||
151 | |||
152 | /** | ||
153 | * What's the next time we should re-try this request? | ||
154 | */ | ||
155 | struct GNUNET_TIME_Absolute retry_time; | ||
156 | |||
157 | /** | ||
158 | * The unique identifier of this request | ||
159 | */ | ||
160 | uint64_t unique_id; | ||
161 | |||
162 | /** | ||
163 | * Number of bytes in xquery. | ||
164 | */ | ||
165 | size_t xquery_size; | ||
166 | |||
167 | /** | ||
168 | * Number of entries in @e seen_replies. | ||
169 | */ | ||
170 | unsigned int seen_replies_count; | ||
171 | |||
172 | /** | ||
173 | * Desired replication level | ||
174 | */ | ||
175 | uint32_t replication; | ||
176 | |||
177 | /** | ||
178 | * Any message options for this request | ||
179 | */ | ||
180 | uint32_t msg_options; | ||
181 | |||
182 | /** | ||
183 | * The type for the data for the GET request. | ||
184 | */ | ||
185 | enum GNUNET_BLOCK_Type type; | ||
186 | |||
187 | }; | ||
188 | |||
189 | |||
190 | /** | ||
191 | * Struct containing paremeters of monitoring requests. | ||
192 | */ | ||
193 | struct ClientMonitorRecord | ||
194 | { | ||
195 | |||
196 | /** | ||
197 | * Next element in DLL. | ||
198 | */ | ||
199 | struct ClientMonitorRecord *next; | ||
200 | |||
201 | /** | ||
202 | * Previous element in DLL. | ||
203 | */ | ||
204 | struct ClientMonitorRecord *prev; | ||
205 | |||
206 | /** | ||
207 | * Type of blocks that are of interest | ||
208 | */ | ||
209 | enum GNUNET_BLOCK_Type type; | ||
210 | |||
211 | /** | ||
212 | * Key of data of interest, NULL for all. | ||
213 | */ | ||
214 | struct GNUNET_HashCode *key; | ||
215 | |||
216 | /** | ||
217 | * Flag whether to notify about GET messages. | ||
218 | */ | ||
219 | int16_t get; | ||
220 | |||
221 | /** | ||
222 | * Flag whether to notify about GET_REPONSE messages. | ||
223 | */ | ||
224 | int16_t get_resp; | ||
225 | |||
226 | /** | ||
227 | * Flag whether to notify about PUT messages. | ||
228 | */ | ||
229 | uint16_t put; | ||
230 | |||
231 | /** | ||
232 | * Client to notify of these requests. | ||
233 | */ | ||
234 | struct ClientList *client; | ||
235 | }; | ||
236 | |||
237 | |||
238 | /** | ||
239 | * List of active clients. | ||
240 | */ | ||
241 | static struct ClientList *client_head; | ||
242 | |||
243 | /** | ||
244 | * List of active clients. | ||
245 | */ | ||
246 | static struct ClientList *client_tail; | ||
247 | |||
248 | /** | ||
249 | * List of active monitoring requests. | ||
250 | */ | ||
251 | static struct ClientMonitorRecord *monitor_head; | ||
252 | |||
253 | /** | ||
254 | * List of active monitoring requests. | ||
255 | */ | ||
256 | static struct ClientMonitorRecord *monitor_tail; | ||
257 | |||
258 | /** | ||
259 | * Hashmap for fast key based lookup, maps keys to `struct ClientQueryRecord` entries. | ||
260 | */ | ||
261 | static struct GNUNET_CONTAINER_MultiHashMap *forward_map; | ||
262 | |||
263 | /** | ||
264 | * Heap with all of our client's request, sorted by retry time (earliest on top). | ||
265 | */ | ||
266 | static struct GNUNET_CONTAINER_Heap *retry_heap; | ||
267 | |||
268 | /** | ||
269 | * Task that re-transmits requests (using retry_heap). | ||
270 | */ | ||
271 | static struct GNUNET_SCHEDULER_Task * retry_task; | ||
272 | |||
273 | |||
274 | /** | ||
275 | * Task run to check for messages that need to be sent to a client. | ||
276 | * | ||
277 | * @param client a ClientList, containing the client and any messages to be sent to it | ||
278 | */ | ||
279 | static void | ||
280 | process_pending_messages (struct ClientList *client); | ||
281 | |||
282 | |||
283 | /** | ||
284 | * Callback called as a result of issuing a #GNUNET_SERVER_notify_transmit_ready() | ||
285 | * request. A ClientList is passed as closure, take the head of the list | ||
286 | * and copy it into buf, which has the result of sending the message to the | ||
287 | * client. | ||
288 | * | ||
289 | * @param cls closure to this call | ||
290 | * @param size maximum number of bytes available to send | ||
291 | * @param buf where to copy the actual message to | ||
292 | * | ||
293 | * @return the number of bytes actually copied, 0 indicates failure | ||
294 | */ | ||
295 | static size_t | ||
296 | send_reply_to_client (void *cls, size_t size, void *buf) | ||
297 | { | ||
298 | struct ClientList *client = cls; | ||
299 | char *cbuf = buf; | ||
300 | struct PendingMessage *reply; | ||
301 | size_t off; | ||
302 | size_t msize; | ||
303 | |||
304 | client->transmit_handle = NULL; | ||
305 | if (buf == NULL) | ||
306 | { | ||
307 | /* client disconnected */ | ||
308 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
309 | "Client %p disconnected, pending messages will be discarded\n", | ||
310 | client->client_handle); | ||
311 | return 0; | ||
312 | } | ||
313 | off = 0; | ||
314 | while ((NULL != (reply = client->pending_head)) && | ||
315 | (size >= off + (msize = ntohs (reply->msg->size)))) | ||
316 | { | ||
317 | GNUNET_CONTAINER_DLL_remove (client->pending_head, client->pending_tail, | ||
318 | reply); | ||
319 | GNUNET_memcpy (&cbuf[off], reply->msg, msize); | ||
320 | GNUNET_free (reply); | ||
321 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
322 | "Transmitting %u bytes to client %p\n", | ||
323 | (unsigned int) msize, | ||
324 | client->client_handle); | ||
325 | off += msize; | ||
326 | } | ||
327 | process_pending_messages (client); | ||
328 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
329 | "Transmitted %u/%u bytes to client %p\n", | ||
330 | (unsigned int) off, | ||
331 | (unsigned int) size, | ||
332 | client->client_handle); | ||
333 | return off; | ||
334 | } | ||
335 | |||
336 | |||
337 | /** | ||
338 | * Task run to check for messages that need to be sent to a client. | ||
339 | * | ||
340 | * @param client a ClientList, containing the client and any messages to be sent to it | ||
341 | */ | ||
342 | static void | ||
343 | process_pending_messages (struct ClientList *client) | ||
344 | { | ||
345 | if ((client->pending_head == NULL) || (client->transmit_handle != NULL)) | ||
346 | { | ||
347 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
348 | "Not asking for transmission to %p now: %s\n", | ||
349 | client->client_handle, | ||
350 | client->pending_head == | ||
351 | NULL ? "no more messages" : "request already pending"); | ||
352 | return; | ||
353 | } | ||
354 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
355 | "Asking for transmission of %u bytes to client %p\n", | ||
356 | ntohs (client->pending_head->msg->size), client->client_handle); | ||
357 | client->transmit_handle = | ||
358 | GNUNET_SERVER_notify_transmit_ready (client->client_handle, | ||
359 | ntohs (client->pending_head-> | ||
360 | msg->size), | ||
361 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
362 | &send_reply_to_client, client); | ||
363 | } | ||
364 | |||
365 | |||
366 | /** | ||
367 | * Add a PendingMessage to the clients list of messages to be sent | ||
368 | * | ||
369 | * @param client the active client to send the message to | ||
370 | * @param pending_message the actual message to send | ||
371 | */ | ||
372 | static void | ||
373 | add_pending_message (struct ClientList *client, | ||
374 | struct PendingMessage *pending_message) | ||
375 | { | ||
376 | GNUNET_CONTAINER_DLL_insert_tail (client->pending_head, client->pending_tail, | ||
377 | pending_message); | ||
378 | process_pending_messages (client); | ||
379 | } | ||
380 | |||
381 | |||
382 | /** | ||
383 | * Closure for #forward_reply() | ||
384 | */ | ||
385 | struct ForwardReplyContext | ||
386 | { | ||
387 | |||
388 | /** | ||
389 | * Actual message to send to matching clients. | ||
390 | */ | ||
391 | struct PendingMessage *pm; | ||
392 | |||
393 | /** | ||
394 | * Embedded payload. | ||
395 | */ | ||
396 | const void *data; | ||
397 | |||
398 | /** | ||
399 | * Type of the data. | ||
400 | */ | ||
401 | enum GNUNET_BLOCK_Type type; | ||
402 | |||
403 | /** | ||
404 | * Number of bytes in data. | ||
405 | */ | ||
406 | size_t data_size; | ||
407 | |||
408 | /** | ||
409 | * Do we need to copy @e pm because it was already used? | ||
410 | */ | ||
411 | int do_copy; | ||
412 | |||
413 | }; | ||
414 | |||
415 | |||
416 | /** | ||
417 | * Find a client if it exists, add it otherwise. | ||
418 | * | ||
419 | * @param client the server handle to the client | ||
420 | * | ||
421 | * @return the client if found, a new client otherwise | ||
422 | */ | ||
423 | static struct ClientList * | ||
424 | find_active_client (struct GNUNET_SERVER_Client *client) | ||
425 | { | ||
426 | struct ClientList *pos = client_head; | ||
427 | struct ClientList *ret; | ||
428 | |||
429 | while (pos != NULL) | ||
430 | { | ||
431 | if (pos->client_handle == client) | ||
432 | return pos; | ||
433 | pos = pos->next; | ||
434 | } | ||
435 | ret = GNUNET_new (struct ClientList); | ||
436 | ret->client_handle = client; | ||
437 | GNUNET_CONTAINER_DLL_insert (client_head, client_tail, ret); | ||
438 | return ret; | ||
439 | } | ||
440 | |||
441 | |||
442 | /** | ||
443 | * Iterator over hash map entries that frees all entries | ||
444 | * associated with the given client. | ||
445 | * | ||
446 | * @param cls client to search for in source routes | ||
447 | * @param key current key code (ignored) | ||
448 | * @param value value in the hash map, a ClientQueryRecord | ||
449 | * @return #GNUNET_YES (we should continue to iterate) | ||
450 | */ | ||
451 | static int | ||
452 | remove_client_records (void *cls, const struct GNUNET_HashCode * key, void *value) | ||
453 | { | ||
454 | struct ClientList *client = cls; | ||
455 | struct ClientQueryRecord *record = value; | ||
456 | |||
457 | if (record->client != client) | ||
458 | return GNUNET_YES; | ||
459 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
460 | "Removing client %p's record for key %s\n", client, | ||
461 | GNUNET_h2s (key)); | ||
462 | GNUNET_assert (GNUNET_YES == | ||
463 | GNUNET_CONTAINER_multihashmap_remove (forward_map, key, | ||
464 | record)); | ||
465 | if (NULL != record->hnode) | ||
466 | GNUNET_CONTAINER_heap_remove_node (record->hnode); | ||
467 | GNUNET_array_grow (record->seen_replies, record->seen_replies_count, 0); | ||
468 | GNUNET_free (record); | ||
469 | return GNUNET_YES; | ||
470 | } | ||
471 | |||
472 | |||
473 | /** | ||
474 | * Iterator over hash map entries that send a given reply to | ||
475 | * each of the matching clients. With some tricky recycling | ||
476 | * of the buffer. | ||
477 | * | ||
478 | * @param cls the `struct ForwardReplyContext` | ||
479 | * @param key current key | ||
480 | * @param value value in the hash map, a ClientQueryRecord | ||
481 | * @return #GNUNET_YES (we should continue to iterate), | ||
482 | * if the result is mal-formed, #GNUNET_NO | ||
483 | */ | ||
484 | static int | ||
485 | forward_reply (void *cls, | ||
486 | const struct GNUNET_HashCode *key, | ||
487 | void *value) | ||
488 | { | ||
489 | struct ForwardReplyContext *frc = cls; | ||
490 | struct ClientQueryRecord *record = value; | ||
491 | struct PendingMessage *pm; | ||
492 | struct GNUNET_DHT_ClientResultMessage *reply; | ||
493 | enum GNUNET_BLOCK_EvaluationResult eval; | ||
494 | int do_free; | ||
495 | struct GNUNET_HashCode ch; | ||
496 | unsigned int i; | ||
497 | |||
498 | LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, | ||
499 | "XVINE CLIENT-RESULT %s\n", | ||
500 | GNUNET_h2s_full (key)); | ||
501 | #if 0 | ||
502 | if ((record->type != GNUNET_BLOCK_TYPE_ANY) && (record->type != frc->type)) | ||
503 | { | ||
504 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
505 | "Record type missmatch, not passing request for key %s to local client\n", | ||
506 | GNUNET_h2s (key)); | ||
507 | |||
508 | GNUNET_STATISTICS_update (GDS_stats, | ||
509 | gettext_noop | ||
510 | ("# Key match, type mismatches in REPLY to CLIENT"), | ||
511 | 1, GNUNET_NO); | ||
512 | return GNUNET_YES; /* type mismatch */ | ||
513 | } | ||
514 | #endif | ||
515 | GNUNET_CRYPTO_hash (frc->data, frc->data_size, &ch); | ||
516 | for (i = 0; i < record->seen_replies_count; i++) | ||
517 | if (0 == memcmp (&record->seen_replies[i], &ch, sizeof (struct GNUNET_HashCode))) | ||
518 | { | ||
519 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
520 | "Duplicate reply, not passing request for key %s to local client\n", | ||
521 | GNUNET_h2s (key)); | ||
522 | GNUNET_STATISTICS_update (GDS_stats, | ||
523 | gettext_noop | ||
524 | ("# Duplicate REPLIES to CLIENT request dropped"), | ||
525 | 1, GNUNET_NO); | ||
526 | return GNUNET_YES; /* duplicate */ | ||
527 | } | ||
528 | eval = | ||
529 | GNUNET_BLOCK_evaluate (GDS_block_context, | ||
530 | record->type, | ||
531 | GNUNET_BLOCK_EO_NONE, | ||
532 | key, NULL, 0, | ||
533 | record->xquery, | ||
534 | record->xquery_size, | ||
535 | frc->data, | ||
536 | frc->data_size); | ||
537 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
538 | "Evaluation result is %d for key %s for local client's query\n", | ||
539 | (int) eval, GNUNET_h2s (key)); | ||
540 | switch (eval) | ||
541 | { | ||
542 | case GNUNET_BLOCK_EVALUATION_OK_LAST: | ||
543 | do_free = GNUNET_YES; | ||
544 | break; | ||
545 | case GNUNET_BLOCK_EVALUATION_OK_MORE: | ||
546 | GNUNET_array_append (record->seen_replies, record->seen_replies_count, ch); | ||
547 | do_free = GNUNET_NO; | ||
548 | break; | ||
549 | case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE: | ||
550 | /* should be impossible to encounter here */ | ||
551 | GNUNET_break (0); | ||
552 | return GNUNET_YES; | ||
553 | case GNUNET_BLOCK_EVALUATION_RESULT_INVALID: | ||
554 | GNUNET_break_op (0); | ||
555 | return GNUNET_NO; | ||
556 | case GNUNET_BLOCK_EVALUATION_REQUEST_VALID: | ||
557 | GNUNET_break (0); | ||
558 | return GNUNET_NO; | ||
559 | case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID: | ||
560 | GNUNET_break (0); | ||
561 | return GNUNET_NO; | ||
562 | case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT: | ||
563 | return GNUNET_YES; | ||
564 | case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED: | ||
565 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
566 | _("Unsupported block type (%u) in request!\n"), record->type); | ||
567 | return GNUNET_NO; | ||
568 | default: | ||
569 | GNUNET_break (0); | ||
570 | return GNUNET_NO; | ||
571 | } | ||
572 | if (GNUNET_NO == frc->do_copy) | ||
573 | { | ||
574 | /* first time, we can use the original data */ | ||
575 | pm = frc->pm; | ||
576 | frc->do_copy = GNUNET_YES; | ||
577 | } | ||
578 | else | ||
579 | { | ||
580 | /* two clients waiting for same reply, must copy for queueing */ | ||
581 | pm = GNUNET_malloc (sizeof (struct PendingMessage) + | ||
582 | ntohs (frc->pm->msg->size)); | ||
583 | GNUNET_memcpy (pm, frc->pm, | ||
584 | sizeof (struct PendingMessage) + ntohs (frc->pm->msg->size)); | ||
585 | pm->next = pm->prev = NULL; | ||
586 | pm->msg = (struct GNUNET_MessageHeader *) &pm[1]; | ||
587 | } | ||
588 | GNUNET_STATISTICS_update (GDS_stats, | ||
589 | gettext_noop ("# RESULTS queued for clients"), 1, | ||
590 | GNUNET_NO); | ||
591 | reply = (struct GNUNET_DHT_ClientResultMessage *) &pm[1]; | ||
592 | reply->unique_id = record->unique_id; | ||
593 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
594 | "Queueing reply to query %s for client %p\n", | ||
595 | GNUNET_h2s (key), | ||
596 | record->client->client_handle); | ||
597 | add_pending_message (record->client, pm); | ||
598 | if (GNUNET_YES == do_free) | ||
599 | remove_client_records (record->client, key, record); | ||
600 | return GNUNET_YES; | ||
601 | } | ||
602 | |||
603 | |||
604 | /** | ||
605 | * Handle a reply we've received from another peer. If the reply | ||
606 | * matches any of our pending queries, forward it to the respective | ||
607 | * client(s). | ||
608 | * | ||
609 | * @param expiration when will the reply expire | ||
610 | * @param key the query this reply is for | ||
611 | * @param get_path_length number of peers in @a get_path | ||
612 | * @param get_path path the reply took on get | ||
613 | * @param put_path_length number of peers in @a put_path | ||
614 | * @param put_path path the reply took on put | ||
615 | * @param type type of the reply | ||
616 | * @param data_size number of bytes in @a data | ||
617 | * @param data application payload data | ||
618 | */ | ||
619 | void | ||
620 | GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration, | ||
621 | const struct GNUNET_HashCode *key, | ||
622 | unsigned int get_path_length, | ||
623 | const struct GNUNET_PeerIdentity *get_path, | ||
624 | unsigned int put_path_length, | ||
625 | const struct GNUNET_PeerIdentity *put_path, | ||
626 | enum GNUNET_BLOCK_Type type, size_t data_size, | ||
627 | const void *data) | ||
628 | { | ||
629 | struct ForwardReplyContext frc; | ||
630 | struct PendingMessage *pm; | ||
631 | struct GNUNET_DHT_ClientResultMessage *reply; | ||
632 | struct GNUNET_PeerIdentity *paths; | ||
633 | size_t msize; | ||
634 | |||
635 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
636 | "reply for key %s\n", | ||
637 | GNUNET_h2s (key)); | ||
638 | |||
639 | if (NULL == GNUNET_CONTAINER_multihashmap_get (forward_map, key)) | ||
640 | { | ||
641 | GNUNET_STATISTICS_update (GDS_stats, | ||
642 | gettext_noop | ||
643 | ("# REPLIES ignored for CLIENTS (no match)"), 1, | ||
644 | GNUNET_NO); | ||
645 | return; /* no matching request, fast exit! */ | ||
646 | } | ||
647 | msize = | ||
648 | sizeof (struct GNUNET_DHT_ClientResultMessage) + data_size + | ||
649 | (get_path_length + put_path_length) * sizeof (struct GNUNET_PeerIdentity); | ||
650 | if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
651 | { | ||
652 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
653 | _("Could not pass reply to client, message too big!\n")); | ||
654 | return; | ||
655 | } | ||
656 | DEBUG ("reply FOR DATA_SIZE = %u\n", | ||
657 | (unsigned int) msize); | ||
658 | pm = GNUNET_malloc (msize + sizeof (struct PendingMessage)); | ||
659 | reply = (struct GNUNET_DHT_ClientResultMessage *) &pm[1]; | ||
660 | pm->msg = &reply->header; | ||
661 | reply->header.size = htons ((uint16_t) msize); | ||
662 | reply->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_CLIENT_RESULT); | ||
663 | reply->type = htonl (type); | ||
664 | reply->get_path_length = htonl (get_path_length); | ||
665 | reply->put_path_length = htonl (put_path_length); | ||
666 | reply->unique_id = 0; /* filled in later */ | ||
667 | reply->expiration = GNUNET_TIME_absolute_hton (expiration); | ||
668 | reply->key = *key; | ||
669 | paths = (struct GNUNET_PeerIdentity *) &reply[1]; | ||
670 | GNUNET_memcpy (paths, | ||
671 | put_path, | ||
672 | sizeof (struct GNUNET_PeerIdentity) * put_path_length); | ||
673 | GNUNET_memcpy (&paths[put_path_length], | ||
674 | get_path, | ||
675 | sizeof (struct GNUNET_PeerIdentity) * get_path_length); | ||
676 | GNUNET_memcpy (&paths[get_path_length + put_path_length], | ||
677 | data, | ||
678 | data_size); | ||
679 | frc.do_copy = GNUNET_NO; | ||
680 | frc.pm = pm; | ||
681 | frc.data = data; | ||
682 | frc.data_size = data_size; | ||
683 | frc.type = type; | ||
684 | GNUNET_CONTAINER_multihashmap_get_multiple (forward_map, | ||
685 | key, | ||
686 | &forward_reply, | ||
687 | &frc); | ||
688 | if (GNUNET_NO == frc.do_copy) | ||
689 | { | ||
690 | /* did not match any of the requests, free! */ | ||
691 | GNUNET_STATISTICS_update (GDS_stats, | ||
692 | gettext_noop | ||
693 | ("# REPLIES ignored for CLIENTS (no match)"), 1, | ||
694 | GNUNET_NO); | ||
695 | GNUNET_free (pm); | ||
696 | } | ||
697 | } | ||
698 | |||
699 | |||
700 | /** | ||
701 | * Check if some client is monitoring GET messages and notify | ||
702 | * them in that case. | ||
703 | * | ||
704 | * @param options Options, for instance RecordRoute, DemultiplexEverywhere. | ||
705 | * @param type The type of data in the request. | ||
706 | * @param hop_count Hop count so far. | ||
707 | * @param path_length number of entries in path (or 0 if not recorded). | ||
708 | * @param path peers on the GET path (or NULL if not recorded). | ||
709 | * @param desired_replication_level Desired replication level. | ||
710 | * @param key Key of the requested data. | ||
711 | */ | ||
712 | void | ||
713 | GDS_CLIENTS_process_get (uint32_t options, | ||
714 | enum GNUNET_BLOCK_Type type, | ||
715 | uint32_t hop_count, | ||
716 | uint32_t desired_replication_level, | ||
717 | unsigned int path_length, | ||
718 | const struct GNUNET_PeerIdentity *path, | ||
719 | const struct GNUNET_HashCode *key) | ||
720 | { | ||
721 | struct ClientMonitorRecord *m; | ||
722 | struct ClientList **cl; | ||
723 | unsigned int cl_size; | ||
724 | |||
725 | cl = NULL; | ||
726 | cl_size = 0; | ||
727 | for (m = monitor_head; NULL != m; m = m->next) | ||
728 | { | ||
729 | if ((GNUNET_BLOCK_TYPE_ANY == m->type || m->type == type) && | ||
730 | (NULL == m->key || | ||
731 | memcmp (key, m->key, sizeof(struct GNUNET_HashCode)) == 0)) | ||
732 | { | ||
733 | struct PendingMessage *pm; | ||
734 | struct GNUNET_DHT_MonitorGetMessage *mmsg; | ||
735 | struct GNUNET_PeerIdentity *msg_path; | ||
736 | size_t msize; | ||
737 | unsigned int i; | ||
738 | |||
739 | /* Don't send duplicates */ | ||
740 | for (i = 0; i < cl_size; i++) | ||
741 | if (cl[i] == m->client) | ||
742 | break; | ||
743 | if (i < cl_size) | ||
744 | continue; | ||
745 | GNUNET_array_append (cl, cl_size, m->client); | ||
746 | |||
747 | msize = path_length * sizeof (struct GNUNET_PeerIdentity); | ||
748 | msize += sizeof (struct GNUNET_DHT_MonitorGetMessage); | ||
749 | msize += sizeof (struct PendingMessage); | ||
750 | pm = GNUNET_malloc (msize); | ||
751 | mmsg = (struct GNUNET_DHT_MonitorGetMessage *) &pm[1]; | ||
752 | pm->msg = &mmsg->header; | ||
753 | mmsg->header.size = htons (msize - sizeof (struct PendingMessage)); | ||
754 | mmsg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET); | ||
755 | mmsg->options = htonl(options); | ||
756 | mmsg->type = htonl(type); | ||
757 | mmsg->hop_count = htonl(hop_count); | ||
758 | mmsg->desired_replication_level = htonl(desired_replication_level); | ||
759 | mmsg->get_path_length = htonl(path_length); | ||
760 | GNUNET_memcpy (&mmsg->key, key, sizeof (struct GNUNET_HashCode)); | ||
761 | msg_path = (struct GNUNET_PeerIdentity *) &mmsg[1]; | ||
762 | if (path_length > 0) | ||
763 | GNUNET_memcpy (msg_path, path, | ||
764 | path_length * sizeof (struct GNUNET_PeerIdentity)); | ||
765 | add_pending_message (m->client, pm); | ||
766 | } | ||
767 | } | ||
768 | GNUNET_free_non_null (cl); | ||
769 | } | ||
770 | |||
771 | |||
772 | /** | ||
773 | * Check if some client is monitoring PUT messages and notify | ||
774 | * them in that case. | ||
775 | * | ||
776 | * @param options options, for instance RecordRoute, DemultiplexEverywhere. | ||
777 | * @param type type of data in the request. | ||
778 | * @param hop_count hop count so far. | ||
779 | * @param path_length number of entries in @a path (or 0 if not recorded). | ||
780 | * @param path peers on the PUT path (or NULL if not recorded). | ||
781 | * @param desired_replication_level desired replication level. | ||
782 | * @param exp expiration time of the data. | ||
783 | * @param key key under which @a data is to be stored. | ||
784 | * @param data pointer to the data carried. | ||
785 | * @param size number of bytes in @a data. | ||
786 | */ | ||
787 | void | ||
788 | GDS_CLIENTS_process_put (uint32_t options, | ||
789 | enum GNUNET_BLOCK_Type type, | ||
790 | uint32_t hop_count, | ||
791 | uint32_t desired_replication_level, | ||
792 | unsigned int path_length, | ||
793 | const struct GNUNET_PeerIdentity *path, | ||
794 | struct GNUNET_TIME_Absolute exp, | ||
795 | const struct GNUNET_HashCode *key, | ||
796 | const void *data, | ||
797 | size_t size) | ||
798 | { | ||
799 | struct ClientMonitorRecord *m; | ||
800 | struct ClientList **cl; | ||
801 | unsigned int cl_size; | ||
802 | |||
803 | cl = NULL; | ||
804 | cl_size = 0; | ||
805 | for (m = monitor_head; NULL != m; m = m->next) | ||
806 | { | ||
807 | if ((GNUNET_BLOCK_TYPE_ANY == m->type || m->type == type) && | ||
808 | (NULL == m->key || | ||
809 | memcmp (key, m->key, sizeof(struct GNUNET_HashCode)) == 0)) | ||
810 | { | ||
811 | struct PendingMessage *pm; | ||
812 | struct GNUNET_DHT_MonitorPutMessage *mmsg; | ||
813 | struct GNUNET_PeerIdentity *msg_path; | ||
814 | size_t msize; | ||
815 | unsigned int i; | ||
816 | |||
817 | /* Don't send duplicates */ | ||
818 | for (i = 0; i < cl_size; i++) | ||
819 | if (cl[i] == m->client) | ||
820 | break; | ||
821 | if (i < cl_size) | ||
822 | continue; | ||
823 | GNUNET_array_append (cl, cl_size, m->client); | ||
824 | |||
825 | msize = size; | ||
826 | msize += path_length * sizeof (struct GNUNET_PeerIdentity); | ||
827 | msize += sizeof (struct GNUNET_DHT_MonitorPutMessage); | ||
828 | msize += sizeof (struct PendingMessage); | ||
829 | pm = GNUNET_malloc (msize); | ||
830 | mmsg = (struct GNUNET_DHT_MonitorPutMessage *) &pm[1]; | ||
831 | pm->msg = (struct GNUNET_MessageHeader *) mmsg; | ||
832 | mmsg->header.size = htons (msize - sizeof (struct PendingMessage)); | ||
833 | mmsg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT); | ||
834 | mmsg->options = htonl(options); | ||
835 | mmsg->type = htonl(type); | ||
836 | mmsg->hop_count = htonl(hop_count); | ||
837 | mmsg->desired_replication_level = htonl(desired_replication_level); | ||
838 | mmsg->put_path_length = htonl(path_length); | ||
839 | msg_path = (struct GNUNET_PeerIdentity *) &mmsg[1]; | ||
840 | if (path_length > 0) | ||
841 | { | ||
842 | GNUNET_memcpy (msg_path, path, | ||
843 | path_length * sizeof (struct GNUNET_PeerIdentity)); | ||
844 | } | ||
845 | mmsg->expiration_time = GNUNET_TIME_absolute_hton(exp); | ||
846 | GNUNET_memcpy (&mmsg->key, key, sizeof (struct GNUNET_HashCode)); | ||
847 | if (size > 0) | ||
848 | GNUNET_memcpy (&msg_path[path_length], data, size); | ||
849 | add_pending_message (m->client, pm); | ||
850 | } | ||
851 | } | ||
852 | GNUNET_free_non_null (cl); | ||
853 | } | ||
854 | |||
855 | |||
856 | /** | ||
857 | * Route the given request via the DHT. | ||
858 | */ | ||
859 | static void | ||
860 | transmit_request (struct ClientQueryRecord *cqr) | ||
861 | { | ||
862 | GNUNET_STATISTICS_update (GDS_stats, | ||
863 | gettext_noop | ||
864 | ("# GET requests from clients injected"), 1, | ||
865 | GNUNET_NO); | ||
866 | |||
867 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
868 | "Initiating GET for %s, replication %u, already have %u replies\n", | ||
869 | GNUNET_h2s (&cqr->key), | ||
870 | cqr->replication, | ||
871 | cqr->seen_replies_count); | ||
872 | |||
873 | GDS_NEIGHBOURS_handle_get (&cqr->key, cqr->type, cqr->msg_options, | ||
874 | cqr->replication); | ||
875 | |||
876 | /* exponential back-off for retries. | ||
877 | * max GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD (15 min) */ | ||
878 | cqr->retry_frequency = GNUNET_TIME_STD_BACKOFF (cqr->retry_frequency); | ||
879 | cqr->retry_time = GNUNET_TIME_relative_to_absolute (cqr->retry_frequency); | ||
880 | } | ||
881 | |||
882 | |||
883 | /** | ||
884 | * Task that looks at the 'retry_heap' and transmits all of the requests | ||
885 | * on the heap that are ready for transmission. Then re-schedules | ||
886 | * itself (unless the heap is empty). | ||
887 | * | ||
888 | * @param cls unused | ||
889 | */ | ||
890 | static void | ||
891 | transmit_next_request_task (void *cls) | ||
892 | { | ||
893 | struct ClientQueryRecord *cqr; | ||
894 | struct GNUNET_TIME_Relative delay; | ||
895 | |||
896 | retry_task = NULL; | ||
897 | while (NULL != (cqr = GNUNET_CONTAINER_heap_remove_root (retry_heap))) | ||
898 | { | ||
899 | cqr->hnode = NULL; | ||
900 | delay = GNUNET_TIME_absolute_get_remaining (cqr->retry_time); | ||
901 | if (delay.rel_value_us > 0) | ||
902 | { | ||
903 | cqr->hnode = | ||
904 | GNUNET_CONTAINER_heap_insert (retry_heap, cqr, | ||
905 | cqr->retry_time.abs_value_us); | ||
906 | retry_task = | ||
907 | GNUNET_SCHEDULER_add_delayed (delay, &transmit_next_request_task, | ||
908 | NULL); | ||
909 | return; | ||
910 | } | ||
911 | transmit_request (cqr); | ||
912 | cqr->hnode = | ||
913 | GNUNET_CONTAINER_heap_insert (retry_heap, cqr, | ||
914 | cqr->retry_time.abs_value_us); | ||
915 | } | ||
916 | } | ||
917 | |||
918 | |||
919 | /** | ||
920 | * Handler for PUT messages. | ||
921 | * | ||
922 | * @param cls closure for the service | ||
923 | * @param client the client we received this message from | ||
924 | * @param message the actual message received | ||
925 | */ | ||
926 | static void | ||
927 | handle_dht_local_put (void *cls, | ||
928 | struct GNUNET_SERVER_Client *client, | ||
929 | const struct GNUNET_MessageHeader *message) | ||
930 | { | ||
931 | const struct GNUNET_DHT_ClientPutMessage *put_msg; | ||
932 | struct PendingMessage *pm; | ||
933 | struct GNUNET_DHT_ClientPutConfirmationMessage *conf; | ||
934 | uint16_t size; | ||
935 | |||
936 | size = ntohs (message->size); | ||
937 | if (size < sizeof (struct GNUNET_DHT_ClientPutMessage)) | ||
938 | { | ||
939 | GNUNET_break (0); | ||
940 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
941 | return; | ||
942 | } | ||
943 | GNUNET_STATISTICS_update (GDS_stats, | ||
944 | gettext_noop | ||
945 | ("# PUT requests received from clients"), 1, | ||
946 | GNUNET_NO); | ||
947 | put_msg = (const struct GNUNET_DHT_ClientPutMessage *) message; | ||
948 | LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, "X-VINE DHT CLIENT-PUT %s\n", | ||
949 | GNUNET_h2s_full (&put_msg->key)); | ||
950 | /* give to local clients */ | ||
951 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
952 | "Handling local PUT of %u-bytes for query %s\n", | ||
953 | size - sizeof (struct GNUNET_DHT_ClientPutMessage), | ||
954 | GNUNET_h2s (&put_msg->key)); | ||
955 | DEBUG("PUT doing put i = %s\n",GNUNET_h2s(&(put_msg->key))); | ||
956 | GDS_CLIENTS_handle_reply (GNUNET_TIME_absolute_ntoh (put_msg->expiration), | ||
957 | &put_msg->key, 0, NULL, 0, NULL, | ||
958 | ntohl (put_msg->type), | ||
959 | size - sizeof (struct GNUNET_DHT_ClientPutMessage), | ||
960 | &put_msg[1]); | ||
961 | |||
962 | GDS_NEIGHBOURS_handle_put (&put_msg->key, | ||
963 | ntohl (put_msg->type), ntohl (put_msg->options), | ||
964 | ntohl (put_msg->desired_replication_level), | ||
965 | GNUNET_TIME_absolute_ntoh (put_msg->expiration), | ||
966 | &put_msg[1], | ||
967 | size - sizeof (struct GNUNET_DHT_ClientPutMessage)); | ||
968 | pm = GNUNET_malloc (sizeof (struct PendingMessage) + | ||
969 | sizeof (struct GNUNET_DHT_ClientPutConfirmationMessage)); | ||
970 | conf = (struct GNUNET_DHT_ClientPutConfirmationMessage *) &pm[1]; | ||
971 | conf->header.size = htons (sizeof (struct GNUNET_DHT_ClientPutConfirmationMessage)); | ||
972 | conf->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_CLIENT_PUT_OK); | ||
973 | conf->reserved = htonl (0); | ||
974 | conf->unique_id = put_msg->unique_id; | ||
975 | pm->msg = &conf->header; | ||
976 | add_pending_message (find_active_client (client), pm); | ||
977 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
978 | } | ||
979 | |||
980 | |||
981 | /** | ||
982 | * Handler for DHT GET messages from the client. | ||
983 | * | ||
984 | * @param cls closure for the service | ||
985 | * @param client the client we received this message from | ||
986 | * @param message the actual message received | ||
987 | */ | ||
988 | static void | ||
989 | handle_dht_local_get (void *cls, | ||
990 | struct GNUNET_SERVER_Client *client, | ||
991 | const struct GNUNET_MessageHeader *message) | ||
992 | { | ||
993 | const struct GNUNET_DHT_ClientGetMessage *get; | ||
994 | struct ClientQueryRecord *cqr; | ||
995 | size_t xquery_size; | ||
996 | const char *xquery; | ||
997 | uint16_t size; | ||
998 | |||
999 | size = ntohs (message->size); | ||
1000 | if (size < sizeof (struct GNUNET_DHT_ClientGetMessage)) | ||
1001 | { | ||
1002 | GNUNET_break (0); | ||
1003 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
1004 | return; | ||
1005 | } | ||
1006 | xquery_size = size - sizeof (struct GNUNET_DHT_ClientGetMessage); | ||
1007 | get = (const struct GNUNET_DHT_ClientGetMessage *) message; | ||
1008 | xquery = (const char *) &get[1]; | ||
1009 | GNUNET_STATISTICS_update (GDS_stats, | ||
1010 | gettext_noop | ||
1011 | ("# GET requests received from clients"), 1, | ||
1012 | GNUNET_NO); | ||
1013 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1014 | "Received GET request for %s from local client %p, xq: %.*s\n", | ||
1015 | GNUNET_h2s (&get->key), client, xquery_size, xquery); | ||
1016 | |||
1017 | LOG_TRAFFIC (GNUNET_ERROR_TYPE_DEBUG, "X-VINE CLIENT-GET %s\n", | ||
1018 | GNUNET_h2s_full (&get->key)); | ||
1019 | |||
1020 | |||
1021 | cqr = GNUNET_malloc (sizeof (struct ClientQueryRecord) + xquery_size); | ||
1022 | cqr->key = get->key; | ||
1023 | cqr->client = find_active_client (client); | ||
1024 | cqr->xquery = (void *) &cqr[1]; | ||
1025 | GNUNET_memcpy (&cqr[1], xquery, xquery_size); | ||
1026 | cqr->hnode = GNUNET_CONTAINER_heap_insert (retry_heap, cqr, 0); | ||
1027 | cqr->retry_frequency = GNUNET_TIME_UNIT_SECONDS; | ||
1028 | cqr->retry_time = GNUNET_TIME_absolute_get (); | ||
1029 | cqr->unique_id = get->unique_id; | ||
1030 | cqr->xquery_size = xquery_size; | ||
1031 | cqr->replication = ntohl (get->desired_replication_level); | ||
1032 | cqr->msg_options = ntohl (get->options); | ||
1033 | cqr->type = ntohl (get->type); | ||
1034 | |||
1035 | // FIXME use cqr->key, set multihashmap create to GNUNET_YES | ||
1036 | GNUNET_CONTAINER_multihashmap_put (forward_map, &get->key, cqr, | ||
1037 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
1038 | |||
1039 | struct GNUNET_PeerIdentity my_identity; | ||
1040 | my_identity = GDS_NEIGHBOURS_get_my_id(); | ||
1041 | GDS_CLIENTS_process_get (ntohl (get->options), | ||
1042 | ntohl (get->type), | ||
1043 | 0, | ||
1044 | ntohl (get->desired_replication_level), | ||
1045 | 1, | ||
1046 | &my_identity, | ||
1047 | &get->key); | ||
1048 | /* start remote requests */ | ||
1049 | if (NULL != retry_task) | ||
1050 | GNUNET_SCHEDULER_cancel (retry_task); | ||
1051 | retry_task = GNUNET_SCHEDULER_add_now (&transmit_next_request_task, NULL); | ||
1052 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
1053 | } | ||
1054 | |||
1055 | |||
1056 | /** | ||
1057 | * Closure for #find_by_unique_id(). | ||
1058 | */ | ||
1059 | struct FindByUniqueIdContext | ||
1060 | { | ||
1061 | /** | ||
1062 | * Where to store the result, if found. | ||
1063 | */ | ||
1064 | struct ClientQueryRecord *cqr; | ||
1065 | |||
1066 | /** | ||
1067 | * Which ID are we looking for? | ||
1068 | */ | ||
1069 | uint64_t unique_id; | ||
1070 | }; | ||
1071 | |||
1072 | |||
1073 | /** | ||
1074 | * Function called for each existing DHT record for the given | ||
1075 | * query. Checks if it matches the UID given in the closure | ||
1076 | * and if so returns the entry as a result. | ||
1077 | * | ||
1078 | * @param cls the search context | ||
1079 | * @param key query for the lookup (not used) | ||
1080 | * @param value the `struct ClientQueryRecord` | ||
1081 | * @return #GNUNET_YES to continue iteration (result not yet found) | ||
1082 | */ | ||
1083 | static int | ||
1084 | find_by_unique_id (void *cls, | ||
1085 | const struct GNUNET_HashCode *key, | ||
1086 | void *value) | ||
1087 | { | ||
1088 | struct FindByUniqueIdContext *fui_ctx = cls; | ||
1089 | struct ClientQueryRecord *cqr = value; | ||
1090 | |||
1091 | if (cqr->unique_id != fui_ctx->unique_id) | ||
1092 | return GNUNET_YES; | ||
1093 | fui_ctx->cqr = cqr; | ||
1094 | return GNUNET_NO; | ||
1095 | } | ||
1096 | |||
1097 | |||
1098 | /** | ||
1099 | * Handler for "GET result seen" messages from the client. | ||
1100 | * | ||
1101 | * @param cls closure for the service | ||
1102 | * @param client the client we received this message from | ||
1103 | * @param message the actual message received | ||
1104 | */ | ||
1105 | static void | ||
1106 | handle_dht_local_get_result_seen (void *cls, | ||
1107 | struct GNUNET_SERVER_Client *client, | ||
1108 | const struct GNUNET_MessageHeader *message) | ||
1109 | { | ||
1110 | const struct GNUNET_DHT_ClientGetResultSeenMessage *seen; | ||
1111 | uint16_t size; | ||
1112 | unsigned int hash_count; | ||
1113 | unsigned int old_count; | ||
1114 | const struct GNUNET_HashCode *hc; | ||
1115 | struct FindByUniqueIdContext fui_ctx; | ||
1116 | struct ClientQueryRecord *cqr; | ||
1117 | |||
1118 | size = ntohs (message->size); | ||
1119 | if (size < sizeof (struct GNUNET_DHT_ClientGetResultSeenMessage)) | ||
1120 | { | ||
1121 | GNUNET_break (0); | ||
1122 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
1123 | return; | ||
1124 | } | ||
1125 | seen = (const struct GNUNET_DHT_ClientGetResultSeenMessage *) message; | ||
1126 | hash_count = (size - sizeof (struct GNUNET_DHT_ClientGetResultSeenMessage)) / sizeof (struct GNUNET_HashCode); | ||
1127 | if (size != sizeof (struct GNUNET_DHT_ClientGetResultSeenMessage) + hash_count * sizeof (struct GNUNET_HashCode)) | ||
1128 | { | ||
1129 | GNUNET_break (0); | ||
1130 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
1131 | return; | ||
1132 | } | ||
1133 | hc = (const struct GNUNET_HashCode*) &seen[1]; | ||
1134 | fui_ctx.unique_id = seen->unique_id; | ||
1135 | fui_ctx.cqr = NULL; | ||
1136 | GNUNET_CONTAINER_multihashmap_get_multiple (forward_map, | ||
1137 | &seen->key, | ||
1138 | &find_by_unique_id, | ||
1139 | &fui_ctx); | ||
1140 | if (NULL == (cqr = fui_ctx.cqr)) | ||
1141 | { | ||
1142 | GNUNET_break (0); | ||
1143 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
1144 | return; | ||
1145 | } | ||
1146 | /* finally, update 'seen' list */ | ||
1147 | old_count = cqr->seen_replies_count; | ||
1148 | GNUNET_array_grow (cqr->seen_replies, | ||
1149 | cqr->seen_replies_count, | ||
1150 | cqr->seen_replies_count + hash_count); | ||
1151 | GNUNET_memcpy (&cqr->seen_replies[old_count], | ||
1152 | hc, | ||
1153 | sizeof (struct GNUNET_HashCode) * hash_count); | ||
1154 | } | ||
1155 | |||
1156 | |||
1157 | /** | ||
1158 | * Closure for #remove_by_unique_id(). | ||
1159 | */ | ||
1160 | struct RemoveByUniqueIdContext | ||
1161 | { | ||
1162 | /** | ||
1163 | * Client that issued the removal request. | ||
1164 | */ | ||
1165 | struct ClientList *client; | ||
1166 | |||
1167 | /** | ||
1168 | * Unique ID of the request. | ||
1169 | */ | ||
1170 | uint64_t unique_id; | ||
1171 | }; | ||
1172 | |||
1173 | |||
1174 | /** | ||
1175 | * Iterator over hash map entries that frees all entries | ||
1176 | * that match the given client and unique ID. | ||
1177 | * | ||
1178 | * @param cls unique ID and client to search for in source routes | ||
1179 | * @param key current key code | ||
1180 | * @param value value in the hash map, a ClientQueryRecord | ||
1181 | * @return #GNUNET_YES (we should continue to iterate) | ||
1182 | */ | ||
1183 | static int | ||
1184 | remove_by_unique_id (void *cls, | ||
1185 | const struct GNUNET_HashCode *key, | ||
1186 | void *value) | ||
1187 | { | ||
1188 | const struct RemoveByUniqueIdContext *ctx = cls; | ||
1189 | struct ClientQueryRecord *record = value; | ||
1190 | |||
1191 | if (record->unique_id != ctx->unique_id) | ||
1192 | return GNUNET_YES; | ||
1193 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1194 | "Removing client %p's record for key %s (by unique id)\n", | ||
1195 | ctx->client->client_handle, GNUNET_h2s (key)); | ||
1196 | return remove_client_records (ctx->client, key, record); | ||
1197 | } | ||
1198 | |||
1199 | |||
1200 | /** | ||
1201 | * Handler for any generic DHT stop messages, calls the appropriate handler | ||
1202 | * depending on message type (if processed locally) | ||
1203 | * | ||
1204 | * @param cls closure for the service | ||
1205 | * @param client the client we received this message from | ||
1206 | * @param message the actual message received | ||
1207 | * | ||
1208 | */ | ||
1209 | static void | ||
1210 | handle_dht_local_get_stop (void *cls, | ||
1211 | struct GNUNET_SERVER_Client *client, | ||
1212 | const struct GNUNET_MessageHeader *message) | ||
1213 | { | ||
1214 | const struct GNUNET_DHT_ClientGetStopMessage *dht_stop_msg = | ||
1215 | (const struct GNUNET_DHT_ClientGetStopMessage *) message; | ||
1216 | struct RemoveByUniqueIdContext ctx; | ||
1217 | |||
1218 | GNUNET_STATISTICS_update (GDS_stats, | ||
1219 | gettext_noop | ||
1220 | ("# GET STOP requests received from clients"), 1, | ||
1221 | GNUNET_NO); | ||
1222 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1223 | "Received GET STOP request for %s from local client %p\n", | ||
1224 | GNUNET_h2s (&dht_stop_msg->key), | ||
1225 | client); | ||
1226 | ctx.client = find_active_client (client); | ||
1227 | ctx.unique_id = dht_stop_msg->unique_id; | ||
1228 | GNUNET_CONTAINER_multihashmap_get_multiple (forward_map, &dht_stop_msg->key, | ||
1229 | &remove_by_unique_id, &ctx); | ||
1230 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
1231 | } | ||
1232 | |||
1233 | |||
1234 | /** | ||
1235 | * Handler for monitor start messages | ||
1236 | * | ||
1237 | * @param cls closure for the service | ||
1238 | * @param client the client we received this message from | ||
1239 | * @param message the actual message received | ||
1240 | * | ||
1241 | */ | ||
1242 | static void | ||
1243 | handle_dht_local_monitor (void *cls, | ||
1244 | struct GNUNET_SERVER_Client *client, | ||
1245 | const struct GNUNET_MessageHeader *message) | ||
1246 | { | ||
1247 | struct ClientMonitorRecord *r; | ||
1248 | const struct GNUNET_DHT_MonitorStartStopMessage *msg; | ||
1249 | |||
1250 | msg = (struct GNUNET_DHT_MonitorStartStopMessage *) message; | ||
1251 | r = GNUNET_new (struct ClientMonitorRecord); | ||
1252 | |||
1253 | r->client = find_active_client(client); | ||
1254 | r->type = ntohl(msg->type); | ||
1255 | r->get = ntohs(msg->get); | ||
1256 | r->get_resp = ntohs(msg->get_resp); | ||
1257 | r->put = ntohs(msg->put); | ||
1258 | if (0 == ntohs(msg->filter_key)) | ||
1259 | r->key = NULL; | ||
1260 | else | ||
1261 | { | ||
1262 | r->key = GNUNET_new (struct GNUNET_HashCode); | ||
1263 | GNUNET_memcpy (r->key, &msg->key, sizeof (struct GNUNET_HashCode)); | ||
1264 | } | ||
1265 | GNUNET_CONTAINER_DLL_insert (monitor_head, monitor_tail, r); | ||
1266 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
1267 | } | ||
1268 | |||
1269 | |||
1270 | /** | ||
1271 | * Handler for monitor stop messages | ||
1272 | * | ||
1273 | * @param cls closure for the service | ||
1274 | * @param client the client we received this message from | ||
1275 | * @param message the actual message received | ||
1276 | */ | ||
1277 | static void | ||
1278 | handle_dht_local_monitor_stop (void *cls, | ||
1279 | struct GNUNET_SERVER_Client *client, | ||
1280 | const struct GNUNET_MessageHeader *message) | ||
1281 | { | ||
1282 | struct ClientMonitorRecord *r; | ||
1283 | const struct GNUNET_DHT_MonitorStartStopMessage *msg; | ||
1284 | int keys_match; | ||
1285 | |||
1286 | msg = (struct GNUNET_DHT_MonitorStartStopMessage *) message; | ||
1287 | r = monitor_head; | ||
1288 | |||
1289 | while (NULL != r) | ||
1290 | { | ||
1291 | if (NULL == r->key) | ||
1292 | keys_match = (0 == ntohs(msg->filter_key)); | ||
1293 | else | ||
1294 | { | ||
1295 | keys_match = (0 != ntohs(msg->filter_key) | ||
1296 | && !memcmp(r->key, &msg->key, sizeof(struct GNUNET_HashCode))); | ||
1297 | } | ||
1298 | if (find_active_client(client) == r->client | ||
1299 | && ntohl(msg->type) == r->type | ||
1300 | && r->get == msg->get | ||
1301 | && r->get_resp == msg->get_resp | ||
1302 | && r->put == msg->put | ||
1303 | && keys_match | ||
1304 | ) | ||
1305 | { | ||
1306 | GNUNET_CONTAINER_DLL_remove (monitor_head, monitor_tail, r); | ||
1307 | GNUNET_free_non_null (r->key); | ||
1308 | GNUNET_free (r); | ||
1309 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
1310 | return; /* Delete only ONE entry */ | ||
1311 | } | ||
1312 | r = r->next; | ||
1313 | } | ||
1314 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
1315 | } | ||
1316 | |||
1317 | |||
1318 | /** | ||
1319 | * Functions with this signature are called whenever a client | ||
1320 | * is disconnected on the network level. | ||
1321 | * | ||
1322 | * @param cls closure (NULL for dht) | ||
1323 | * @param client identification of the client; NULL | ||
1324 | * for the last call when the server is destroyed | ||
1325 | */ | ||
1326 | static void | ||
1327 | handle_client_disconnect (void *cls, | ||
1328 | struct GNUNET_SERVER_Client *client) | ||
1329 | { | ||
1330 | struct ClientList *pos; | ||
1331 | struct PendingMessage *reply; | ||
1332 | struct ClientMonitorRecord *monitor; | ||
1333 | |||
1334 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1335 | "Local client %p disconnects\n", | ||
1336 | client); | ||
1337 | pos = find_active_client (client); | ||
1338 | GNUNET_CONTAINER_DLL_remove (client_head, client_tail, pos); | ||
1339 | if (pos->transmit_handle != NULL) | ||
1340 | GNUNET_SERVER_notify_transmit_ready_cancel (pos->transmit_handle); | ||
1341 | while (NULL != (reply = pos->pending_head)) | ||
1342 | { | ||
1343 | GNUNET_CONTAINER_DLL_remove (pos->pending_head, pos->pending_tail, reply); | ||
1344 | GNUNET_free (reply); | ||
1345 | } | ||
1346 | monitor = monitor_head; | ||
1347 | while (NULL != monitor) | ||
1348 | { | ||
1349 | if (monitor->client == pos) | ||
1350 | { | ||
1351 | struct ClientMonitorRecord *next; | ||
1352 | |||
1353 | GNUNET_free_non_null (monitor->key); | ||
1354 | next = monitor->next; | ||
1355 | GNUNET_CONTAINER_DLL_remove (monitor_head, monitor_tail, monitor); | ||
1356 | GNUNET_free (monitor); | ||
1357 | monitor = next; | ||
1358 | } | ||
1359 | else | ||
1360 | monitor = monitor->next; | ||
1361 | } | ||
1362 | GNUNET_CONTAINER_multihashmap_iterate (forward_map, &remove_client_records, | ||
1363 | pos); | ||
1364 | GNUNET_free (pos); | ||
1365 | } | ||
1366 | |||
1367 | |||
1368 | /** | ||
1369 | * Initialize client subsystem. | ||
1370 | * | ||
1371 | * @param server the initialized server | ||
1372 | */ | ||
1373 | void | ||
1374 | GDS_CLIENTS_init (struct GNUNET_SERVER_Handle *server) | ||
1375 | { | ||
1376 | static struct GNUNET_SERVER_MessageHandler plugin_handlers[] = { | ||
1377 | {&handle_dht_local_put, NULL, | ||
1378 | GNUNET_MESSAGE_TYPE_DHT_CLIENT_PUT, 0}, | ||
1379 | {&handle_dht_local_get, NULL, | ||
1380 | GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET, 0}, | ||
1381 | {&handle_dht_local_get_stop, NULL, | ||
1382 | GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_STOP, | ||
1383 | sizeof (struct GNUNET_DHT_ClientGetStopMessage)}, | ||
1384 | {&handle_dht_local_monitor, NULL, | ||
1385 | GNUNET_MESSAGE_TYPE_DHT_MONITOR_START, | ||
1386 | sizeof (struct GNUNET_DHT_MonitorStartStopMessage)}, | ||
1387 | {&handle_dht_local_monitor_stop, NULL, | ||
1388 | GNUNET_MESSAGE_TYPE_DHT_MONITOR_STOP, | ||
1389 | sizeof (struct GNUNET_DHT_MonitorStartStopMessage)}, | ||
1390 | {&handle_dht_local_get_result_seen, NULL, | ||
1391 | GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_RESULTS_KNOWN, 0}, | ||
1392 | {NULL, NULL, 0, 0} | ||
1393 | }; | ||
1394 | forward_map = GNUNET_CONTAINER_multihashmap_create (1024, GNUNET_NO); | ||
1395 | retry_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); | ||
1396 | GNUNET_SERVER_add_handlers (server, plugin_handlers); | ||
1397 | GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL); | ||
1398 | } | ||
1399 | |||
1400 | |||
1401 | /** | ||
1402 | * Shutdown client subsystem. | ||
1403 | */ | ||
1404 | void | ||
1405 | GDS_CLIENTS_done () | ||
1406 | { | ||
1407 | GNUNET_assert (client_head == NULL); | ||
1408 | GNUNET_assert (client_tail == NULL); | ||
1409 | if (NULL != retry_task) | ||
1410 | { | ||
1411 | GNUNET_SCHEDULER_cancel (retry_task); | ||
1412 | retry_task = NULL; | ||
1413 | } | ||
1414 | if (NULL != retry_heap) | ||
1415 | { | ||
1416 | GNUNET_assert (0 == GNUNET_CONTAINER_heap_get_size (retry_heap)); | ||
1417 | GNUNET_CONTAINER_heap_destroy (retry_heap); | ||
1418 | retry_heap = NULL; | ||
1419 | } | ||
1420 | if (NULL != forward_map) | ||
1421 | { | ||
1422 | GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size (forward_map)); | ||
1423 | GNUNET_CONTAINER_multihashmap_destroy (forward_map); | ||
1424 | forward_map = NULL; | ||
1425 | } | ||
1426 | } | ||
1427 | |||
1428 | /* end of gnunet-service-wdht_clients.c */ | ||
diff --git a/src/dht/gnunet-service-wdht_neighbours.c b/src/dht/gnunet-service-wdht_neighbours.c deleted file mode 100644 index 78a04d66d..000000000 --- a/src/dht/gnunet-service-wdht_neighbours.c +++ /dev/null | |||
@@ -1,1768 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2009-2016 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file dht/gnunet-service-wdht_neighbours.c | ||
22 | * @brief GNUnet DHT service's finger and friend table management code | ||
23 | * @author Supriti Singh | ||
24 | * @author Christian Grothoff | ||
25 | * @author Arthur Dewarumez | ||
26 | * | ||
27 | * TODO: | ||
28 | * - initiate finding of successors | ||
29 | */ | ||
30 | #include "platform.h" | ||
31 | #include "gnunet_util_lib.h" | ||
32 | #include "gnunet_block_lib.h" | ||
33 | #include "gnunet_hello_lib.h" | ||
34 | #include "gnunet_constants.h" | ||
35 | #include "gnunet_protocols.h" | ||
36 | #include "gnunet_ats_service.h" | ||
37 | #include "gnunet_core_service.h" | ||
38 | #include "gnunet_datacache_lib.h" | ||
39 | #include "gnunet_transport_service.h" | ||
40 | #include "gnunet_dht_service.h" | ||
41 | #include "gnunet_statistics_service.h" | ||
42 | #include "gnunet-service-dht.h" | ||
43 | #include "gnunet-service-dht_datacache.h" | ||
44 | #include "gnunet-service-dht_neighbours.h" | ||
45 | #include "gnunet-service-dht_nse.h" | ||
46 | #include "dht.h" | ||
47 | |||
48 | #define DEBUG(...) \ | ||
49 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__) | ||
50 | |||
51 | /** | ||
52 | * Trail timeout. After what time do trails always die? | ||
53 | */ | ||
54 | #define TRAIL_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 42) | ||
55 | |||
56 | /** | ||
57 | * Random walk delay. How often do we walk the overlay? | ||
58 | */ | ||
59 | #define RANDOM_WALK_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 42) | ||
60 | |||
61 | /** | ||
62 | * The number of layered ID to use. | ||
63 | */ | ||
64 | #define NUMBER_LAYERED_ID 8 | ||
65 | |||
66 | /** | ||
67 | * The number of random walk to launch at the beginning of the initialization | ||
68 | */ | ||
69 | /* FIXME: find a better value */ | ||
70 | #define NUMBER_RANDOM_WALK 20 | ||
71 | |||
72 | |||
73 | /******************* The db structure and related functions *******************/ | ||
74 | |||
75 | /** | ||
76 | * Entry in #friends_peermap. | ||
77 | */ | ||
78 | struct FriendInfo; | ||
79 | |||
80 | /** | ||
81 | * | ||
82 | */ | ||
83 | struct FingerTable; | ||
84 | |||
85 | /** | ||
86 | * Information we keep per trail. | ||
87 | */ | ||
88 | struct Trail | ||
89 | { | ||
90 | |||
91 | /** | ||
92 | * Identifier of the trail with the predecessor. | ||
93 | */ | ||
94 | struct GNUNET_HashCode pred_id; | ||
95 | |||
96 | /** | ||
97 | * Identifier of the trail with the successor. | ||
98 | */ | ||
99 | struct GNUNET_HashCode succ_id; | ||
100 | |||
101 | /** | ||
102 | * When does this trail expire. | ||
103 | */ | ||
104 | struct GNUNET_TIME_Absolute expiration_time; | ||
105 | |||
106 | /** | ||
107 | * MDLL entry in the list of all trails with the same predecessor. | ||
108 | */ | ||
109 | struct Trail *prev_succ; | ||
110 | |||
111 | /** | ||
112 | * MDLL entry in the list of all trails with the same predecessor. | ||
113 | */ | ||
114 | struct Trail *next_succ; | ||
115 | |||
116 | /** | ||
117 | * MDLL entry in the list of all trails with the same predecessor. | ||
118 | */ | ||
119 | struct Trail *prev_pred; | ||
120 | |||
121 | /** | ||
122 | * MDLL entry in the list of all trails with the same predecessor. | ||
123 | */ | ||
124 | struct Trail *next_pred; | ||
125 | |||
126 | /** | ||
127 | * Our predecessor in the trail, NULL if we are initiator (?). | ||
128 | */ | ||
129 | struct FriendInfo *pred; | ||
130 | |||
131 | /** | ||
132 | * Our successor in the trail, NULL if we are the last peer. | ||
133 | */ | ||
134 | struct FriendInfo *succ; | ||
135 | |||
136 | /** | ||
137 | * Location of this trail in the heap. | ||
138 | */ | ||
139 | struct GNUNET_CONTAINER_HeapNode *hn; | ||
140 | |||
141 | /** | ||
142 | * If this peer started the to create a Finger (and thus @e pred is | ||
143 | * NULL), this is the finger table of the finger we are trying to | ||
144 | * intialize. | ||
145 | */ | ||
146 | struct FingerTable *ft; | ||
147 | |||
148 | /** | ||
149 | * If this peer started the trail to create a Finger (and thus @e | ||
150 | * pred is NULL), this is the offset of the finger we are trying to | ||
151 | * intialize in the unsorted array. | ||
152 | */ | ||
153 | unsigned int finger_off; | ||
154 | |||
155 | }; | ||
156 | |||
157 | |||
158 | /** | ||
159 | * Entry in #friends_peermap. | ||
160 | */ | ||
161 | struct FriendInfo | ||
162 | { | ||
163 | /** | ||
164 | * Friend Identity | ||
165 | */ | ||
166 | const struct GNUNET_PeerIdentity *id; | ||
167 | |||
168 | /** | ||
169 | * | ||
170 | */ | ||
171 | struct Trail *pred_head; | ||
172 | |||
173 | /** | ||
174 | * | ||
175 | */ | ||
176 | struct Trail *pred_tail; | ||
177 | |||
178 | /** | ||
179 | * | ||
180 | */ | ||
181 | struct Trail *succ_head; | ||
182 | |||
183 | /** | ||
184 | * | ||
185 | */ | ||
186 | struct Trail *succ_tail; | ||
187 | |||
188 | /** | ||
189 | * Core handle for sending messages to this friend. | ||
190 | */ | ||
191 | struct GNUNET_MQ_Handle *mq; | ||
192 | |||
193 | }; | ||
194 | |||
195 | |||
196 | /** | ||
197 | * | ||
198 | */ | ||
199 | struct Finger | ||
200 | { | ||
201 | /** | ||
202 | * | ||
203 | */ | ||
204 | struct Trail *trail; | ||
205 | |||
206 | /** | ||
207 | * | ||
208 | */ | ||
209 | struct FingerTable *ft; | ||
210 | |||
211 | /** | ||
212 | * | ||
213 | */ | ||
214 | struct GNUNET_HashCode destination; | ||
215 | |||
216 | /** | ||
217 | * #GNUNET_YES if a response has been received. Otherwise #GNUNET_NO. | ||
218 | */ | ||
219 | int valid; | ||
220 | }; | ||
221 | |||
222 | |||
223 | struct FingerTable | ||
224 | { | ||
225 | /** | ||
226 | * Array of our fingers, unsorted. | ||
227 | */ | ||
228 | struct Finger **fingers; | ||
229 | |||
230 | /** | ||
231 | * Size of the finger array. | ||
232 | */ | ||
233 | unsigned int finger_array_size; | ||
234 | |||
235 | /** | ||
236 | * Number of valid entries in @e fingers | ||
237 | */ | ||
238 | unsigned int number_valid_fingers; | ||
239 | |||
240 | /** | ||
241 | * Which offset in @e fingers will we redo next. | ||
242 | */ | ||
243 | unsigned int walk_offset; | ||
244 | |||
245 | /** | ||
246 | * Is the finger array sorted? | ||
247 | */ | ||
248 | int is_sorted; | ||
249 | |||
250 | }; | ||
251 | |||
252 | |||
253 | /*********************** end of the db structure part ***********************/ | ||
254 | |||
255 | |||
256 | GNUNET_NETWORK_STRUCT_BEGIN | ||
257 | |||
258 | /** | ||
259 | * Setup a finger using the underlay topology ("social network"). | ||
260 | */ | ||
261 | struct RandomWalkMessage | ||
262 | { | ||
263 | /** | ||
264 | * Type: #GNUNET_MESSAGE_TYPE_WDHT_RANDOM_WALK | ||
265 | */ | ||
266 | struct GNUNET_MessageHeader header; | ||
267 | |||
268 | /** | ||
269 | * Number of hops this message has taken so far, we stop at | ||
270 | * log(NSE), in NBO. | ||
271 | */ | ||
272 | uint16_t hops_taken GNUNET_PACKED; | ||
273 | |||
274 | /** | ||
275 | * Layer for the request, in NBO. | ||
276 | */ | ||
277 | uint16_t layer GNUNET_PACKED; | ||
278 | |||
279 | /** | ||
280 | * Unique (random) identifier this peer will use to | ||
281 | * identify the trail (in future messages). | ||
282 | */ | ||
283 | struct GNUNET_HashCode trail_id; | ||
284 | |||
285 | }; | ||
286 | |||
287 | /** | ||
288 | * Response to a `struct RandomWalkMessage`. | ||
289 | */ | ||
290 | struct RandomWalkResponseMessage | ||
291 | { | ||
292 | /** | ||
293 | * Type: #GNUNET_MESSAGE_TYPE_WDHT_RANDOM_WALK_RESPONSE | ||
294 | */ | ||
295 | struct GNUNET_MessageHeader header; | ||
296 | |||
297 | /** | ||
298 | * Zero, for alignment. | ||
299 | */ | ||
300 | uint32_t reserved GNUNET_PACKED; | ||
301 | |||
302 | /** | ||
303 | * Unique (random) identifier from the | ||
304 | * `struct RandomWalkMessage`. | ||
305 | */ | ||
306 | struct GNUNET_HashCode trail_id; | ||
307 | |||
308 | /** | ||
309 | * Random location in the respective layer where the | ||
310 | * random path of the finger setup terminated. | ||
311 | */ | ||
312 | struct GNUNET_HashCode location; | ||
313 | |||
314 | }; | ||
315 | |||
316 | /** | ||
317 | * Response to an event that causes a trail to die. | ||
318 | */ | ||
319 | struct TrailDestroyMessage | ||
320 | { | ||
321 | /** | ||
322 | * Type: #GNUNET_MESSAGE_TYPE_WDHT_TRAIL_DESTROY | ||
323 | */ | ||
324 | struct GNUNET_MessageHeader header; | ||
325 | |||
326 | /** | ||
327 | * Zero, for alignment. | ||
328 | */ | ||
329 | uint32_t reserved GNUNET_PACKED; | ||
330 | |||
331 | /** | ||
332 | * Unique (random) identifier this peer will use to | ||
333 | * identify the finger (in future messages). | ||
334 | */ | ||
335 | struct GNUNET_HashCode trail_id; | ||
336 | |||
337 | }; | ||
338 | |||
339 | |||
340 | /** | ||
341 | * Send a message along a trail. | ||
342 | */ | ||
343 | struct FindSuccessorMessage | ||
344 | { | ||
345 | /** | ||
346 | * Type: #GNUNET_MESSAGE_TYPE_WDHT_SUCCESSOR_FIND | ||
347 | */ | ||
348 | struct GNUNET_MessageHeader header; | ||
349 | |||
350 | /** | ||
351 | * Zero, for alignment. | ||
352 | */ | ||
353 | uint32_t reserved GNUNET_PACKED; | ||
354 | |||
355 | /** | ||
356 | * Key for which we would like close values returned. | ||
357 | * identify the finger (in future messages). | ||
358 | */ | ||
359 | struct GNUNET_HashCode key; | ||
360 | |||
361 | }; | ||
362 | |||
363 | |||
364 | /** | ||
365 | * Send a message along a trail. | ||
366 | */ | ||
367 | struct TrailRouteMessage | ||
368 | { | ||
369 | /** | ||
370 | * Type: #GNUNET_MESSAGE_TYPE_WDHT_TRAIL_ROUTE | ||
371 | */ | ||
372 | struct GNUNET_MessageHeader header; | ||
373 | |||
374 | /** | ||
375 | * #GNUNET_YES if the path should be recorded, #GNUNET_NO if not; in NBO. | ||
376 | */ | ||
377 | uint16_t record_path GNUNET_PACKED; | ||
378 | |||
379 | /** | ||
380 | * Length of the recorded trail, 0 if @e record_path is #GNUNET_NO; in NBO. | ||
381 | */ | ||
382 | uint16_t path_length GNUNET_PACKED; | ||
383 | |||
384 | /** | ||
385 | * Unique (random) identifier this peer will use to | ||
386 | * identify the finger (in future messages). | ||
387 | */ | ||
388 | struct GNUNET_HashCode trail_id; | ||
389 | |||
390 | /** | ||
391 | * Path the message has taken so far (excluding sender). | ||
392 | */ | ||
393 | /* struct GNUNET_PeerIdentity path[path_length]; */ | ||
394 | |||
395 | /* followed by payload (another `struct GNUNET_MessageHeader`) to | ||
396 | send along the trail */ | ||
397 | }; | ||
398 | |||
399 | |||
400 | /** | ||
401 | * P2P PUT message | ||
402 | */ | ||
403 | struct PeerPutMessage | ||
404 | { | ||
405 | /** | ||
406 | * Type: #GNUNET_MESSAGE_TYPE_WDHT_PUT | ||
407 | */ | ||
408 | struct GNUNET_MessageHeader header; | ||
409 | |||
410 | /** | ||
411 | * Processing options | ||
412 | */ | ||
413 | uint32_t options GNUNET_PACKED; | ||
414 | |||
415 | /** | ||
416 | * Content type. | ||
417 | */ | ||
418 | uint32_t block_type GNUNET_PACKED; | ||
419 | |||
420 | /** | ||
421 | * Hop count | ||
422 | */ | ||
423 | uint32_t hop_count GNUNET_PACKED; | ||
424 | |||
425 | /** | ||
426 | * Replication level for this message | ||
427 | * In the current implementation, this value is not used. | ||
428 | */ | ||
429 | uint32_t desired_replication_level GNUNET_PACKED; | ||
430 | |||
431 | /** | ||
432 | * Length of the PUT path that follows (if tracked). | ||
433 | */ | ||
434 | uint32_t put_path_length GNUNET_PACKED; | ||
435 | |||
436 | /** | ||
437 | * When does the content expire? | ||
438 | */ | ||
439 | struct GNUNET_TIME_AbsoluteNBO expiration_time; | ||
440 | |||
441 | /** | ||
442 | * The key to store the value under. | ||
443 | */ | ||
444 | struct GNUNET_HashCode key GNUNET_PACKED; | ||
445 | |||
446 | /* put path (if tracked) */ | ||
447 | |||
448 | /* Payload */ | ||
449 | |||
450 | }; | ||
451 | |||
452 | /** | ||
453 | * P2P GET message | ||
454 | */ | ||
455 | struct PeerGetMessage | ||
456 | { | ||
457 | /** | ||
458 | * Type: #GNUNET_MESSAGE_TYPE_WDHT_GET | ||
459 | */ | ||
460 | struct GNUNET_MessageHeader header; | ||
461 | |||
462 | /** | ||
463 | * Processing options | ||
464 | */ | ||
465 | uint32_t options GNUNET_PACKED; | ||
466 | |||
467 | /** | ||
468 | * Desired content type. | ||
469 | */ | ||
470 | uint32_t block_type GNUNET_PACKED; | ||
471 | |||
472 | /** | ||
473 | * Hop count | ||
474 | */ | ||
475 | uint32_t hop_count GNUNET_PACKED; | ||
476 | |||
477 | /** | ||
478 | * Desired replication level for this request. | ||
479 | * In the current implementation, this value is not used. | ||
480 | */ | ||
481 | uint32_t desired_replication_level GNUNET_PACKED; | ||
482 | |||
483 | /** | ||
484 | * Total number of peers in get path. | ||
485 | */ | ||
486 | unsigned int get_path_length; | ||
487 | |||
488 | /** | ||
489 | * The key we are looking for. | ||
490 | */ | ||
491 | struct GNUNET_HashCode key; | ||
492 | |||
493 | /* Get path. */ | ||
494 | /* struct GNUNET_PeerIdentity[]*/ | ||
495 | }; | ||
496 | |||
497 | |||
498 | /** | ||
499 | * P2P Result message | ||
500 | */ | ||
501 | struct PeerGetResultMessage | ||
502 | { | ||
503 | /** | ||
504 | * Type: #GNUNET_MESSAGE_TYPE_WDHT_GET_RESULT | ||
505 | */ | ||
506 | struct GNUNET_MessageHeader header; | ||
507 | |||
508 | /** | ||
509 | * The type for the data in NBO. | ||
510 | */ | ||
511 | uint32_t type GNUNET_PACKED; | ||
512 | |||
513 | /** | ||
514 | * Number of peers recorded in the outgoing path from source to the | ||
515 | * stored location of this message. | ||
516 | */ | ||
517 | uint32_t put_path_length GNUNET_PACKED; | ||
518 | |||
519 | /** | ||
520 | * When does the content expire? | ||
521 | */ | ||
522 | struct GNUNET_TIME_AbsoluteNBO expiration_time; | ||
523 | |||
524 | /** | ||
525 | * The key of the corresponding GET request. | ||
526 | */ | ||
527 | struct GNUNET_HashCode key; | ||
528 | |||
529 | /* put path (if tracked) */ | ||
530 | |||
531 | /* Payload */ | ||
532 | |||
533 | }; | ||
534 | |||
535 | GNUNET_NETWORK_STRUCT_END | ||
536 | |||
537 | |||
538 | /** | ||
539 | * Contains all the layered IDs of this peer. | ||
540 | */ | ||
541 | struct GNUNET_PeerIdentity layered_id[NUMBER_LAYERED_ID]; | ||
542 | |||
543 | /** | ||
544 | * Task to timeout trails that have expired. | ||
545 | */ | ||
546 | static struct GNUNET_SCHEDULER_Task *trail_timeout_task; | ||
547 | |||
548 | /** | ||
549 | * Task to perform random walks. | ||
550 | */ | ||
551 | static struct GNUNET_SCHEDULER_Task *random_walk_task; | ||
552 | |||
553 | /** | ||
554 | * Identity of this peer. | ||
555 | */ | ||
556 | static struct GNUNET_PeerIdentity my_identity; | ||
557 | |||
558 | /** | ||
559 | * Peer map of all the friends of a peer | ||
560 | */ | ||
561 | static struct GNUNET_CONTAINER_MultiPeerMap *friends_peermap; | ||
562 | |||
563 | /** | ||
564 | * Fingers per layer. | ||
565 | */ | ||
566 | static struct FingerTable fingers[NUMBER_LAYERED_ID]; | ||
567 | |||
568 | /** | ||
569 | * Tail map, mapping tail identifiers to `struct Trail`s | ||
570 | */ | ||
571 | static struct GNUNET_CONTAINER_MultiHashMap *trail_map; | ||
572 | |||
573 | /** | ||
574 | * Tail heap, organizing trails by expiration time. | ||
575 | */ | ||
576 | static struct GNUNET_CONTAINER_Heap *trail_heap; | ||
577 | |||
578 | /** | ||
579 | * Handle to CORE. | ||
580 | */ | ||
581 | static struct GNUNET_CORE_Handle *core_api; | ||
582 | |||
583 | |||
584 | /** | ||
585 | * Handle the put request from the client. | ||
586 | * | ||
587 | * @param block_type Type of the block | ||
588 | * @param options routing options | ||
589 | * @param desired_replication_level desired replication level | ||
590 | * @param expiration_time when does the content expire | ||
591 | * @param hop_count how many hops has this message traversed so far | ||
592 | * @param bf Bloom filter of peers this PUT has already traversed | ||
593 | * @param key key for the content | ||
594 | * @param put_path_length number of entries in put_path | ||
595 | * @param put_path peers this request has traversed so far (if tracked) | ||
596 | * @param data payload to store | ||
597 | * @param data_size number of bytes in data | ||
598 | * @return #GNUNET_OK if the request was forwarded, #GNUNET_NO if not | ||
599 | */ | ||
600 | int | ||
601 | GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type block_type, | ||
602 | enum GNUNET_DHT_RouteOption options, | ||
603 | uint32_t desired_replication_level, | ||
604 | struct GNUNET_TIME_Absolute expiration_time, | ||
605 | uint32_t hop_count, | ||
606 | struct GNUNET_CONTAINER_BloomFilter *bf, | ||
607 | const struct GNUNET_HashCode *key, | ||
608 | unsigned int put_path_length, | ||
609 | struct GNUNET_PeerIdentity *put_path, | ||
610 | const void *data, | ||
611 | size_t data_size) | ||
612 | { | ||
613 | GDS_DATACACHE_handle_put (expiration_time, | ||
614 | key, | ||
615 | 0, NULL, | ||
616 | block_type, | ||
617 | data_size, | ||
618 | data); | ||
619 | GDS_CLIENTS_process_put (options, | ||
620 | block_type, | ||
621 | hop_count, | ||
622 | desired_replication_level, | ||
623 | put_path_length, put_path, | ||
624 | expiration_time, | ||
625 | key, | ||
626 | data, | ||
627 | data_size); | ||
628 | return GNUNET_OK; /* FIXME... */ | ||
629 | } | ||
630 | |||
631 | |||
632 | /** | ||
633 | * Perform a GET operation. Forwards the given request to other | ||
634 | * peers. Does not lookup the key locally. May do nothing if this is | ||
635 | * the only peer in the network (or if we are the closest peer in the | ||
636 | * network). | ||
637 | * | ||
638 | * @param type type of the block | ||
639 | * @param options routing options | ||
640 | * @param desired_replication_level desired replication count | ||
641 | * @param hop_count how many hops did this request traverse so far? | ||
642 | * @param key key for the content | ||
643 | * @param xquery extended query | ||
644 | * @param xquery_size number of bytes in @a xquery | ||
645 | * @param reply_bf bloomfilter to filter duplicates | ||
646 | * @param reply_bf_mutator mutator for @a reply_bf | ||
647 | * @param peer_bf filter for peers not to select (again, updated) | ||
648 | * @return #GNUNET_OK if the request was forwarded, #GNUNET_NO if not | ||
649 | */ | ||
650 | int | ||
651 | GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type, | ||
652 | enum GNUNET_DHT_RouteOption options, | ||
653 | uint32_t desired_replication_level, | ||
654 | uint32_t hop_count, | ||
655 | const struct GNUNET_HashCode *key, | ||
656 | const void *xquery, size_t xquery_size, | ||
657 | const struct GNUNET_CONTAINER_BloomFilter *reply_bf, | ||
658 | uint32_t reply_bf_mutator, | ||
659 | struct GNUNET_CONTAINER_BloomFilter *peer_bf) | ||
660 | { | ||
661 | // find closest finger(s) on all layers | ||
662 | // use TrailRoute with PeerGetMessage embedded to contact peer | ||
663 | // NOTE: actually more complicated, see paper! | ||
664 | GNUNET_break (0); // not implemented! | ||
665 | return GNUNET_SYSERR; | ||
666 | } | ||
667 | |||
668 | |||
669 | /** | ||
670 | * Delete a trail, it died (timeout, link failure, etc.). | ||
671 | * | ||
672 | * @param trail trail to delete from all data structures | ||
673 | * @param inform_pred should we notify the predecessor? | ||
674 | * @param inform_succ should we inform the successor? | ||
675 | */ | ||
676 | static void | ||
677 | delete_trail (struct Trail *trail, | ||
678 | int inform_pred, | ||
679 | int inform_succ) | ||
680 | { | ||
681 | struct FriendInfo *friend; | ||
682 | struct GNUNET_MQ_Envelope *env; | ||
683 | struct TrailDestroyMessage *tdm; | ||
684 | struct Finger *finger; | ||
685 | |||
686 | friend = trail->pred; | ||
687 | if (NULL != friend) | ||
688 | { | ||
689 | if (GNUNET_YES == inform_pred) | ||
690 | { | ||
691 | env = GNUNET_MQ_msg (tdm, | ||
692 | GNUNET_MESSAGE_TYPE_WDHT_TRAIL_DESTROY); | ||
693 | tdm->trail_id = trail->pred_id; | ||
694 | GNUNET_MQ_send (friend->mq, | ||
695 | env); | ||
696 | } | ||
697 | GNUNET_CONTAINER_MDLL_remove (pred, | ||
698 | friend->pred_head, | ||
699 | friend->pred_tail, | ||
700 | trail); | ||
701 | } | ||
702 | friend = trail->succ; | ||
703 | if (NULL != friend) | ||
704 | { | ||
705 | if (GNUNET_YES == inform_succ) | ||
706 | { | ||
707 | env = GNUNET_MQ_msg (tdm, | ||
708 | GNUNET_MESSAGE_TYPE_WDHT_TRAIL_DESTROY); | ||
709 | tdm->trail_id = trail->pred_id; | ||
710 | GNUNET_MQ_send (friend->mq, | ||
711 | env); | ||
712 | } | ||
713 | GNUNET_CONTAINER_MDLL_remove (succ, | ||
714 | friend->pred_head, | ||
715 | friend->pred_tail, | ||
716 | trail); | ||
717 | } | ||
718 | GNUNET_break (trail == | ||
719 | GNUNET_CONTAINER_heap_remove_node (trail->hn)); | ||
720 | finger = trail->ft->fingers[trail->finger_off]; | ||
721 | if (NULL != finger) | ||
722 | { | ||
723 | trail->ft->fingers[trail->finger_off] = NULL; | ||
724 | trail->ft->number_valid_fingers--; | ||
725 | GNUNET_free (finger); | ||
726 | } | ||
727 | GNUNET_free (trail); | ||
728 | } | ||
729 | |||
730 | |||
731 | /** | ||
732 | * Forward the given payload message along the trail. | ||
733 | * | ||
734 | * @param next_target which direction along the trail should we forward | ||
735 | * @param trail_id which trail should we forward along | ||
736 | * @param have_path do we track the forwarding path? | ||
737 | * @param predecessor which peer do we tack on to the path? | ||
738 | * @param path path the message has taken so far along the trail | ||
739 | * @param path_length number of entries in @a path | ||
740 | * @param payload payload of the message | ||
741 | */ | ||
742 | static void | ||
743 | forward_message_on_trail (struct FriendInfo *next_target, | ||
744 | const struct GNUNET_HashCode *trail_id, | ||
745 | int have_path, | ||
746 | const struct GNUNET_PeerIdentity *predecessor, | ||
747 | const struct GNUNET_PeerIdentity *path, | ||
748 | uint16_t path_length, | ||
749 | const struct GNUNET_MessageHeader *payload) | ||
750 | { | ||
751 | struct GNUNET_MQ_Envelope *env; | ||
752 | struct TrailRouteMessage *trm; | ||
753 | struct GNUNET_PeerIdentity *new_path; | ||
754 | unsigned int plen; | ||
755 | uint16_t payload_len; | ||
756 | |||
757 | payload_len = ntohs (payload->size); | ||
758 | if (have_path) | ||
759 | { | ||
760 | plen = path_length + 1; | ||
761 | if (plen >= (GNUNET_SERVER_MAX_MESSAGE_SIZE | ||
762 | - payload_len | ||
763 | - sizeof (struct TrailRouteMessage)) | ||
764 | / sizeof (struct GNUNET_PeerIdentity)) | ||
765 | { | ||
766 | /* Should really not have paths this long... */ | ||
767 | GNUNET_break_op (0); | ||
768 | plen = 0; | ||
769 | have_path = 0; | ||
770 | } | ||
771 | } | ||
772 | else | ||
773 | { | ||
774 | GNUNET_break_op (0 == path_length); | ||
775 | path_length = 0; | ||
776 | plen = 0; | ||
777 | } | ||
778 | env = GNUNET_MQ_msg_extra (trm, | ||
779 | payload_len + | ||
780 | plen * sizeof (struct GNUNET_PeerIdentity), | ||
781 | GNUNET_MESSAGE_TYPE_WDHT_TRAIL_ROUTE); | ||
782 | trm->record_path = htons (have_path); | ||
783 | trm->path_length = htons (plen); | ||
784 | trm->trail_id = *trail_id; | ||
785 | new_path = (struct GNUNET_PeerIdentity *) &trm[1]; | ||
786 | if (have_path) | ||
787 | { | ||
788 | GNUNET_memcpy (new_path, | ||
789 | path, | ||
790 | path_length * sizeof (struct GNUNET_PeerIdentity)); | ||
791 | new_path[path_length] = *predecessor; | ||
792 | } | ||
793 | GNUNET_memcpy (&new_path[plen], | ||
794 | payload, | ||
795 | payload_len); | ||
796 | GNUNET_MQ_send (next_target->mq, | ||
797 | env); | ||
798 | } | ||
799 | |||
800 | |||
801 | /** | ||
802 | * Send the get result to requesting client. | ||
803 | * | ||
804 | * @param cls trail identifying where to send the result to, NULL for us | ||
805 | * @param options routing options (from GET request) | ||
806 | * @param key Key of the requested data. | ||
807 | * @param type Block type | ||
808 | * @param put_path_length Number of peers in @a put_path | ||
809 | * @param put_path Path taken to put the data at its stored location. | ||
810 | * @param expiration When will this result expire? | ||
811 | * @param data Payload to store | ||
812 | * @param data_size Size of the @a data | ||
813 | */ | ||
814 | void | ||
815 | GDS_NEIGHBOURS_send_get_result (void *cls, | ||
816 | enum GNUNET_DHT_RouteOption options, | ||
817 | const struct GNUNET_HashCode *key, | ||
818 | enum GNUNET_BLOCK_Type type, | ||
819 | unsigned int put_path_length, | ||
820 | const struct GNUNET_PeerIdentity *put_path, | ||
821 | struct GNUNET_TIME_Absolute expiration, | ||
822 | const void *data, | ||
823 | size_t data_size) | ||
824 | { | ||
825 | const struct GNUNET_HashCode *trail_id = cls; | ||
826 | struct GNUNET_MessageHeader *payload; | ||
827 | struct Trail *trail; | ||
828 | |||
829 | trail = GNUNET_CONTAINER_multihashmap_get (trail_map, | ||
830 | trail_id); | ||
831 | if (NULL == trail) | ||
832 | { | ||
833 | /* TODO: inform statistics */ | ||
834 | return; | ||
835 | } | ||
836 | if (NULL == trail->pred) | ||
837 | { | ||
838 | /* result is for *us* (local client) */ | ||
839 | GDS_CLIENTS_handle_reply (expiration, | ||
840 | key, | ||
841 | 0, NULL, | ||
842 | put_path_length, put_path, | ||
843 | type, | ||
844 | data_size, | ||
845 | data); | ||
846 | return; | ||
847 | } | ||
848 | |||
849 | payload = GNUNET_malloc(sizeof(struct GNUNET_MessageHeader) + data_size); | ||
850 | payload->size = data_size; | ||
851 | payload->type = GNUNET_MESSAGE_TYPE_WDHT_GET_RESULT; | ||
852 | |||
853 | forward_message_on_trail (trail->pred, | ||
854 | trail_id, | ||
855 | 0 != (options & GNUNET_DHT_RO_RECORD_ROUTE), | ||
856 | &my_identity, | ||
857 | NULL, 0, | ||
858 | payload); | ||
859 | GNUNET_free (payload); | ||
860 | } | ||
861 | |||
862 | |||
863 | /** | ||
864 | * Method called whenever a peer disconnects. | ||
865 | * | ||
866 | * @param cls closure | ||
867 | * @param peer peer identity this notification is about | ||
868 | * @param internal_cls our `struct FriendInfo` for @a peer | ||
869 | */ | ||
870 | static void | ||
871 | handle_core_disconnect (void *cls, | ||
872 | const struct GNUNET_PeerIdentity *peer, | ||
873 | void *internal_cls) | ||
874 | { | ||
875 | struct FriendInfo *remove_friend = internal_cls; | ||
876 | struct Trail *t; | ||
877 | |||
878 | /* If disconnected to own identity, then return. */ | ||
879 | if (NULL == remove_friend) | ||
880 | return; | ||
881 | GNUNET_assert (GNUNET_YES == | ||
882 | GNUNET_CONTAINER_multipeermap_remove (friends_peermap, | ||
883 | peer, | ||
884 | remove_friend)); | ||
885 | while (NULL != (t = remove_friend->succ_head)) | ||
886 | delete_trail (t, | ||
887 | GNUNET_YES, | ||
888 | GNUNET_NO); | ||
889 | while (NULL != (t = remove_friend->pred_head)) | ||
890 | delete_trail (t, | ||
891 | GNUNET_NO, | ||
892 | GNUNET_YES); | ||
893 | GNUNET_free (remove_friend); | ||
894 | if (0 == GNUNET_CONTAINER_multipeermap_size (friends_peermap)) | ||
895 | { | ||
896 | GNUNET_SCHEDULER_cancel (random_walk_task); | ||
897 | random_walk_task = NULL; | ||
898 | } | ||
899 | } | ||
900 | |||
901 | |||
902 | /** | ||
903 | * Function called with a random friend to be returned. | ||
904 | * | ||
905 | * @param cls a `struct FriendInfo **` with where to store the result | ||
906 | * @param peer the peer identity of the friend (ignored) | ||
907 | * @param value the `struct FriendInfo *` that was selected at random | ||
908 | * @return #GNUNET_OK (all good) | ||
909 | */ | ||
910 | static int | ||
911 | pick_random_helper (void *cls, | ||
912 | const struct GNUNET_PeerIdentity *peer, | ||
913 | void *value) | ||
914 | { | ||
915 | struct FriendInfo **fi = cls; | ||
916 | struct FriendInfo *v = value; | ||
917 | |||
918 | *fi = v; | ||
919 | return GNUNET_OK; | ||
920 | } | ||
921 | |||
922 | |||
923 | /** | ||
924 | * Pick random friend from friends for random walk. | ||
925 | * | ||
926 | * @return NULL if we have no friends | ||
927 | */ | ||
928 | static struct FriendInfo * | ||
929 | pick_random_friend () | ||
930 | { | ||
931 | struct FriendInfo *ret; | ||
932 | |||
933 | ret = NULL; | ||
934 | if (0 == | ||
935 | GNUNET_CONTAINER_multipeermap_get_random (friends_peermap, | ||
936 | &pick_random_helper, | ||
937 | &ret)) | ||
938 | return NULL; | ||
939 | return ret; | ||
940 | } | ||
941 | |||
942 | |||
943 | /** | ||
944 | * One of our trails might have timed out, check and | ||
945 | * possibly initiate cleanup. | ||
946 | * | ||
947 | * @param cls NULL | ||
948 | */ | ||
949 | static void | ||
950 | trail_timeout_callback (void *cls) | ||
951 | { | ||
952 | struct Trail *trail; | ||
953 | struct GNUNET_TIME_Relative left; | ||
954 | |||
955 | trail_timeout_task = NULL; | ||
956 | while (NULL != (trail = GNUNET_CONTAINER_heap_peek (trail_heap))) | ||
957 | { | ||
958 | left = GNUNET_TIME_absolute_get_remaining (trail->expiration_time); | ||
959 | if (0 != left.rel_value_us) | ||
960 | break; | ||
961 | delete_trail (trail, | ||
962 | GNUNET_YES, | ||
963 | GNUNET_YES); | ||
964 | } | ||
965 | if (NULL != trail) | ||
966 | trail_timeout_task = GNUNET_SCHEDULER_add_delayed (left, | ||
967 | &trail_timeout_callback, | ||
968 | NULL); | ||
969 | } | ||
970 | |||
971 | |||
972 | /** | ||
973 | * Compute how big our finger arrays should be (at least). | ||
974 | * | ||
975 | * @return size of the finger array, never 0 | ||
976 | */ | ||
977 | static unsigned int | ||
978 | get_desired_finger_array_size () | ||
979 | { | ||
980 | /* FIXME: This is just a stub... */ | ||
981 | return 64; | ||
982 | } | ||
983 | |||
984 | |||
985 | /** | ||
986 | * Initiate a random walk. | ||
987 | * | ||
988 | * @param cls NULL | ||
989 | */ | ||
990 | static void | ||
991 | do_random_walk (void *cls) | ||
992 | { | ||
993 | static unsigned int walk_layer; | ||
994 | struct FriendInfo *friend; | ||
995 | struct GNUNET_MQ_Envelope *env; | ||
996 | struct RandomWalkMessage *rwm; | ||
997 | struct FingerTable *ft; | ||
998 | struct Finger *finger; | ||
999 | struct Trail *trail; | ||
1000 | unsigned int nsize; | ||
1001 | |||
1002 | random_walk_task = NULL; | ||
1003 | friend = pick_random_friend (); | ||
1004 | |||
1005 | trail = GNUNET_new (struct Trail); | ||
1006 | /* We create the random walk so, no predecessor */ | ||
1007 | trail->succ = friend; | ||
1008 | GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_NONCE, | ||
1009 | &trail->succ_id); | ||
1010 | if (GNUNET_OK != | ||
1011 | GNUNET_CONTAINER_multihashmap_put (trail_map, | ||
1012 | &trail->succ_id, | ||
1013 | trail, | ||
1014 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) | ||
1015 | { | ||
1016 | GNUNET_break (0); | ||
1017 | GNUNET_free (trail); | ||
1018 | return; | ||
1019 | } | ||
1020 | GNUNET_CONTAINER_MDLL_insert (succ, | ||
1021 | friend->succ_head, | ||
1022 | friend->succ_tail, | ||
1023 | trail); | ||
1024 | trail->expiration_time = GNUNET_TIME_relative_to_absolute (TRAIL_TIMEOUT); | ||
1025 | trail->hn = GNUNET_CONTAINER_heap_insert (trail_heap, | ||
1026 | trail, | ||
1027 | trail->expiration_time.abs_value_us); | ||
1028 | if (NULL == trail_timeout_task) | ||
1029 | trail_timeout_task = GNUNET_SCHEDULER_add_delayed (TRAIL_TIMEOUT, | ||
1030 | &trail_timeout_callback, | ||
1031 | NULL); | ||
1032 | env = GNUNET_MQ_msg (rwm, | ||
1033 | GNUNET_MESSAGE_TYPE_WDHT_RANDOM_WALK); | ||
1034 | rwm->hops_taken = htonl (0); | ||
1035 | rwm->trail_id = trail->succ_id; | ||
1036 | GNUNET_MQ_send (friend->mq, | ||
1037 | env); | ||
1038 | /* clean up 'old' entry (implicitly via trail cleanup) */ | ||
1039 | ft = &fingers[walk_layer]; | ||
1040 | |||
1041 | if ( (NULL != ft->fingers) && | ||
1042 | (NULL != (finger = ft->fingers[ft->walk_offset])) ) | ||
1043 | delete_trail (finger->trail, | ||
1044 | GNUNET_NO, | ||
1045 | GNUNET_YES); | ||
1046 | if (ft->finger_array_size < (nsize = get_desired_finger_array_size()) ) | ||
1047 | GNUNET_array_grow (ft->fingers, | ||
1048 | ft->finger_array_size, | ||
1049 | nsize); | ||
1050 | GNUNET_assert (NULL == ft->fingers[ft->walk_offset]); | ||
1051 | trail->ft = ft; | ||
1052 | trail->finger_off = ft->walk_offset; | ||
1053 | finger = GNUNET_new (struct Finger); | ||
1054 | finger->trail = trail; | ||
1055 | finger->ft = ft; | ||
1056 | ft->fingers[ft->walk_offset] = finger; | ||
1057 | ft->is_sorted = GNUNET_NO; | ||
1058 | ft->number_valid_fingers++; | ||
1059 | ft->walk_offset = (ft->walk_offset + 1) % ft->finger_array_size; | ||
1060 | |||
1061 | walk_layer = (walk_layer + 1) % NUMBER_LAYERED_ID; | ||
1062 | random_walk_task = GNUNET_SCHEDULER_add_delayed (RANDOM_WALK_DELAY, | ||
1063 | &do_random_walk, | ||
1064 | NULL); | ||
1065 | } | ||
1066 | |||
1067 | |||
1068 | /** | ||
1069 | * Method called whenever a peer connects. | ||
1070 | * | ||
1071 | * @param cls closure | ||
1072 | * @param peer_identity peer identity this notification is about | ||
1073 | * @param mq message queue for transmission to @a peer_identity | ||
1074 | * @return the `struct FriendInfo` for the @a peer_identity, NULL for us | ||
1075 | */ | ||
1076 | static void * | ||
1077 | handle_core_connect (void *cls, | ||
1078 | const struct GNUNET_PeerIdentity *peer_identity, | ||
1079 | struct GNUNET_MQ_Handle *mq) | ||
1080 | { | ||
1081 | struct FriendInfo *friend; | ||
1082 | |||
1083 | /* Check for connect to self message */ | ||
1084 | if (0 == memcmp (&my_identity, | ||
1085 | peer_identity, | ||
1086 | sizeof (struct GNUNET_PeerIdentity))) | ||
1087 | return NULL; | ||
1088 | |||
1089 | friend = GNUNET_new (struct FriendInfo); | ||
1090 | friend->id = peer_identity; | ||
1091 | friend->mq = mq; | ||
1092 | GNUNET_assert (GNUNET_OK == | ||
1093 | GNUNET_CONTAINER_multipeermap_put (friends_peermap, | ||
1094 | peer_identity, | ||
1095 | friend, | ||
1096 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
1097 | if (NULL == random_walk_task) | ||
1098 | { | ||
1099 | /* random walk needs to be started -- we have a first connection */ | ||
1100 | random_walk_task = GNUNET_SCHEDULER_add_now (&do_random_walk, | ||
1101 | NULL); | ||
1102 | } | ||
1103 | return friend; | ||
1104 | } | ||
1105 | |||
1106 | |||
1107 | /** | ||
1108 | * To be called on core init/fail. | ||
1109 | * | ||
1110 | * @param cls service closure | ||
1111 | * @param identity the public identity of this peer | ||
1112 | */ | ||
1113 | static void | ||
1114 | core_init (void *cls, | ||
1115 | const struct GNUNET_PeerIdentity *identity) | ||
1116 | { | ||
1117 | my_identity = *identity; | ||
1118 | } | ||
1119 | |||
1120 | |||
1121 | /** | ||
1122 | * Handle a `struct RandomWalkMessage` from a | ||
1123 | * #GNUNET_MESSAGE_TYPE_WDHT_RANDOM_WALK message. | ||
1124 | * | ||
1125 | * @param cls the `struct FriendInfo` for the sender | ||
1126 | * @param m the setup message | ||
1127 | */ | ||
1128 | static void | ||
1129 | handle_dht_p2p_random_walk (void *cls, | ||
1130 | const struct RandomWalkMessage *m) | ||
1131 | { | ||
1132 | struct FriendInfo *pred = cls; | ||
1133 | struct Trail *t; | ||
1134 | uint16_t layer; | ||
1135 | |||
1136 | layer = ntohs (m->layer); | ||
1137 | if (layer > NUMBER_LAYERED_ID) | ||
1138 | { | ||
1139 | GNUNET_break_op (0); | ||
1140 | return; | ||
1141 | } | ||
1142 | t = GNUNET_new (struct Trail); | ||
1143 | t->pred_id = m->trail_id; | ||
1144 | t->pred = pred; | ||
1145 | if (GNUNET_OK != | ||
1146 | GNUNET_CONTAINER_multihashmap_put (trail_map, | ||
1147 | &t->pred_id, | ||
1148 | t, | ||
1149 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) | ||
1150 | { | ||
1151 | GNUNET_break_op (0); | ||
1152 | GNUNET_free (t); | ||
1153 | return; | ||
1154 | } | ||
1155 | GNUNET_CONTAINER_MDLL_insert (pred, | ||
1156 | pred->pred_head, | ||
1157 | pred->pred_tail, | ||
1158 | t); | ||
1159 | t->expiration_time = GNUNET_TIME_relative_to_absolute (TRAIL_TIMEOUT); | ||
1160 | t->hn = GNUNET_CONTAINER_heap_insert (trail_heap, | ||
1161 | t, | ||
1162 | t->expiration_time.abs_value_us); | ||
1163 | if (NULL == trail_timeout_task) | ||
1164 | trail_timeout_task = GNUNET_SCHEDULER_add_delayed (TRAIL_TIMEOUT, | ||
1165 | &trail_timeout_callback, | ||
1166 | NULL); | ||
1167 | |||
1168 | if (ntohl (m->hops_taken) > GDS_NSE_get ()) | ||
1169 | { | ||
1170 | /* We are the last hop, generate response */ | ||
1171 | struct GNUNET_MQ_Envelope *env; | ||
1172 | struct RandomWalkResponseMessage *rwrm; | ||
1173 | |||
1174 | env = GNUNET_MQ_msg (rwrm, | ||
1175 | GNUNET_MESSAGE_TYPE_WDHT_RANDOM_WALK_RESPONSE); | ||
1176 | rwrm->reserved = htonl (0); | ||
1177 | rwrm->trail_id = m->trail_id; | ||
1178 | if (0 == layer) | ||
1179 | (void) GDS_DATACACHE_get_random_key (&rwrm->location); | ||
1180 | else | ||
1181 | { | ||
1182 | struct FingerTable *ft; | ||
1183 | |||
1184 | ft = &fingers[layer-1]; | ||
1185 | if (0 == ft->number_valid_fingers) | ||
1186 | { | ||
1187 | GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_NONCE, | ||
1188 | &rwrm->location); | ||
1189 | } | ||
1190 | else | ||
1191 | { | ||
1192 | struct Finger *f; | ||
1193 | unsigned int off; | ||
1194 | unsigned int i; | ||
1195 | |||
1196 | off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, | ||
1197 | ft->number_valid_fingers); | ||
1198 | for (i=0; (NULL == (f = ft->fingers[i])) || (off > 0); i++) | ||
1199 | if (NULL != f) off--; | ||
1200 | rwrm->location = f->destination; | ||
1201 | } | ||
1202 | } | ||
1203 | GNUNET_MQ_send (pred->mq, | ||
1204 | env); | ||
1205 | } | ||
1206 | else | ||
1207 | { | ||
1208 | struct GNUNET_MQ_Envelope *env; | ||
1209 | struct RandomWalkMessage *rwm; | ||
1210 | struct FriendInfo *succ; | ||
1211 | |||
1212 | /* extend the trail by another random hop */ | ||
1213 | succ = pick_random_friend (); | ||
1214 | GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_NONCE, | ||
1215 | &t->succ_id); | ||
1216 | t->succ = succ; | ||
1217 | if (GNUNET_OK != | ||
1218 | GNUNET_CONTAINER_multihashmap_put (trail_map, | ||
1219 | &t->succ_id, | ||
1220 | t, | ||
1221 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) | ||
1222 | { | ||
1223 | GNUNET_break (0); | ||
1224 | GNUNET_CONTAINER_MDLL_remove (pred, | ||
1225 | pred->pred_head, | ||
1226 | pred->pred_tail, | ||
1227 | t); | ||
1228 | GNUNET_free (t); | ||
1229 | return; | ||
1230 | } | ||
1231 | GNUNET_CONTAINER_MDLL_insert (succ, | ||
1232 | succ->succ_head, | ||
1233 | succ->succ_tail, | ||
1234 | t); | ||
1235 | env = GNUNET_MQ_msg (rwm, | ||
1236 | GNUNET_MESSAGE_TYPE_WDHT_RANDOM_WALK); | ||
1237 | rwm->hops_taken = htons (1 + ntohs (m->hops_taken)); | ||
1238 | rwm->layer = m->layer; | ||
1239 | rwm->trail_id = t->succ_id; | ||
1240 | GNUNET_MQ_send (succ->mq, | ||
1241 | env); | ||
1242 | } | ||
1243 | } | ||
1244 | |||
1245 | |||
1246 | /** | ||
1247 | * Handle a `struct RandomWalkResponseMessage`. | ||
1248 | * | ||
1249 | * @param cls closure | ||
1250 | * @param rwrm the setup response message | ||
1251 | */ | ||
1252 | static void | ||
1253 | handle_dht_p2p_random_walk_response (void *cls, | ||
1254 | const struct RandomWalkResponseMessage *rwrm) | ||
1255 | { | ||
1256 | struct Trail *trail; | ||
1257 | struct FriendInfo *pred; | ||
1258 | struct FingerTable *ft; | ||
1259 | struct Finger *finger; | ||
1260 | |||
1261 | trail = GNUNET_CONTAINER_multihashmap_get (trail_map, | ||
1262 | &rwrm->trail_id); | ||
1263 | if (NULL == trail) | ||
1264 | { | ||
1265 | /* TODO: log/statistics: we didn't find the trail (can happen) */ | ||
1266 | return; | ||
1267 | } | ||
1268 | if (NULL != (pred = trail->pred)) | ||
1269 | { | ||
1270 | /* We are not the first hop, keep forwarding */ | ||
1271 | struct GNUNET_MQ_Envelope *env; | ||
1272 | struct RandomWalkResponseMessage *rwrm2; | ||
1273 | |||
1274 | env = GNUNET_MQ_msg (rwrm2, | ||
1275 | GNUNET_MESSAGE_TYPE_WDHT_RANDOM_WALK_RESPONSE); | ||
1276 | rwrm2->reserved = htonl (0); | ||
1277 | rwrm2->location = rwrm->location; | ||
1278 | rwrm2->trail_id = trail->pred_id; | ||
1279 | GNUNET_MQ_send (pred->mq, | ||
1280 | env); | ||
1281 | return; | ||
1282 | } | ||
1283 | /* We are the first hop, complete finger */ | ||
1284 | if (NULL == (ft = trail->ft)) | ||
1285 | { | ||
1286 | /* Eh, why did we create the trail if we have no FT? */ | ||
1287 | GNUNET_break (0); | ||
1288 | delete_trail (trail, | ||
1289 | GNUNET_NO, | ||
1290 | GNUNET_YES); | ||
1291 | return; | ||
1292 | } | ||
1293 | if (NULL == (finger = ft->fingers[trail->finger_off])) | ||
1294 | { | ||
1295 | /* Eh, finger got deleted, but why not the trail as well? */ | ||
1296 | GNUNET_break (0); | ||
1297 | delete_trail (trail, | ||
1298 | GNUNET_NO, | ||
1299 | GNUNET_YES); | ||
1300 | return; | ||
1301 | } | ||
1302 | |||
1303 | |||
1304 | // 1) lookup trail => find Finger entry => fill in 'destination' and mark valid, move to end of sorted array, | ||
1305 | //mark unsorted, update links from 'trails' | ||
1306 | /* | ||
1307 | * Steps : | ||
1308 | * 1 check if we are the correct layer | ||
1309 | * 1.a if true : add the returned value (finger) in the db structure | ||
1310 | * 1.b if true : do nothing | ||
1311 | */ | ||
1312 | /* FIXME: add the value in db structure 1.a */ | ||
1313 | |||
1314 | } | ||
1315 | |||
1316 | |||
1317 | /** | ||
1318 | * Handle a `struct TrailDestroyMessage`. | ||
1319 | * | ||
1320 | * @param cls closure | ||
1321 | * @param tdm the trail destroy message | ||
1322 | */ | ||
1323 | static void | ||
1324 | handle_dht_p2p_trail_destroy (void *cls, | ||
1325 | const struct TrailDestroyMessage *tdm) | ||
1326 | { | ||
1327 | struct FriendInfo *sender = cls; | ||
1328 | struct Trail *trail; | ||
1329 | |||
1330 | trail = GNUNET_CONTAINER_multihashmap_get (trail_map, | ||
1331 | &tdm->trail_id); | ||
1332 | delete_trail (trail, | ||
1333 | ( (NULL != trail->succ) && | ||
1334 | (0 == memcmp (sender->id, | ||
1335 | &trail->succ->id, | ||
1336 | sizeof (struct GNUNET_PeerIdentity))) ), | ||
1337 | ( (NULL != trail->pred) && | ||
1338 | (0 == memcmp (sender->id, | ||
1339 | &trail->pred->id, | ||
1340 | sizeof (struct GNUNET_PeerIdentity))) )); | ||
1341 | } | ||
1342 | |||
1343 | |||
1344 | /** | ||
1345 | * Handle a `struct FindSuccessorMessage` from a #GNUNET_MESSAGE_TYPE_WDHT_SUCCESSOR_FIND | ||
1346 | * message. | ||
1347 | * | ||
1348 | * @param cls closure (NULL) | ||
1349 | * @param trail_id path to the originator | ||
1350 | * @param trail_path path the message took on the trail, if available | ||
1351 | * @param trail_path_length number of entries on the @a trail_path | ||
1352 | * @param message the finger setup message | ||
1353 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
1354 | */ | ||
1355 | static int | ||
1356 | handle_dht_p2p_successor_find (void *cls, | ||
1357 | const struct GNUNET_HashCode *trail_id, | ||
1358 | const struct GNUNET_PeerIdentity *trail_path, | ||
1359 | unsigned int trail_path_length, | ||
1360 | const struct GNUNET_MessageHeader *message) | ||
1361 | { | ||
1362 | const struct FindSuccessorMessage *fsm; | ||
1363 | |||
1364 | /* We do not expect to track trails for the forward-direction | ||
1365 | of successor finding... */ | ||
1366 | GNUNET_break_op (0 == trail_path_length); | ||
1367 | fsm = (const struct FindSuccessorMessage *) message; | ||
1368 | GDS_DATACACHE_get_successors (&fsm->key, | ||
1369 | &GDS_NEIGHBOURS_send_get_result, | ||
1370 | (void *) trail_id); | ||
1371 | return GNUNET_OK; | ||
1372 | } | ||
1373 | |||
1374 | |||
1375 | /** | ||
1376 | * Handle a `struct PeerGetMessage`. | ||
1377 | * | ||
1378 | * @param cls closure (NULL) | ||
1379 | * @param trail_id path to the originator | ||
1380 | * @param trail_path path the message took on the trail, if available | ||
1381 | * @param trail_path_length number of entries on the @a trail_path | ||
1382 | * @param message the peer get message | ||
1383 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
1384 | */ | ||
1385 | static int | ||
1386 | handle_dht_p2p_peer_get (void *cls, | ||
1387 | const struct GNUNET_HashCode *trail_id, | ||
1388 | const struct GNUNET_PeerIdentity *trail_path, | ||
1389 | unsigned int trail_path_length, | ||
1390 | const struct GNUNET_MessageHeader *message) | ||
1391 | { | ||
1392 | #if 0 | ||
1393 | const struct PeerGetMessage *pgm; | ||
1394 | |||
1395 | // FIXME: note: never called like this, message embedded with trail route! | ||
1396 | pgm = (const struct PeerGetMessage *) message; | ||
1397 | #endif | ||
1398 | // -> lookup in datacache (figure out way to remember trail!) | ||
1399 | /* | ||
1400 | * steps : | ||
1401 | * 1 extract the result | ||
1402 | * 2 save the peer | ||
1403 | * 3 send it using the good trail | ||
1404 | * | ||
1405 | * What do i do when i don't have the key/value? | ||
1406 | */ | ||
1407 | |||
1408 | return GNUNET_OK; | ||
1409 | } | ||
1410 | |||
1411 | |||
1412 | /** | ||
1413 | * Handle a `struct PeerGetResultMessage`. | ||
1414 | * | ||
1415 | * @param cls closure (NULL) | ||
1416 | * @param trail_id path to the originator | ||
1417 | * @param trail_path path the message took on the trail, if available | ||
1418 | * @param trail_path_length number of entries on the @a trail_path | ||
1419 | * @param message the peer get result message | ||
1420 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
1421 | */ | ||
1422 | static int | ||
1423 | handle_dht_p2p_peer_get_result (void *cls, | ||
1424 | const struct GNUNET_HashCode *trail_id, | ||
1425 | const struct GNUNET_PeerIdentity *trail_path, | ||
1426 | unsigned int trail_path_length, | ||
1427 | const struct GNUNET_MessageHeader *message) | ||
1428 | { | ||
1429 | #if 0 | ||
1430 | const struct PeerGetResultMessage *pgrm; | ||
1431 | |||
1432 | pgrm = (const struct PeerGetResultMessage *) message; | ||
1433 | #endif | ||
1434 | // pretty much: parse, & pass to client (there is some call for that...) | ||
1435 | |||
1436 | #if 0 | ||
1437 | GDS_CLIENTS_process_get (options, | ||
1438 | type, | ||
1439 | 0, 0, | ||
1440 | path_length, path, | ||
1441 | key); | ||
1442 | (void) GDS_DATACACHE_handle_get (trail_id, | ||
1443 | key, | ||
1444 | type, | ||
1445 | xquery, | ||
1446 | xquery_size, | ||
1447 | &reply_bf, | ||
1448 | reply_bf_mutator); | ||
1449 | #endif | ||
1450 | return GNUNET_OK; | ||
1451 | } | ||
1452 | |||
1453 | |||
1454 | /** | ||
1455 | * Handle a `struct PeerPutMessage`. | ||
1456 | * | ||
1457 | * @param cls closure (NULL) | ||
1458 | * @param trail_id path to the originator | ||
1459 | * @param trail_path path the message took on the trail, if available | ||
1460 | * @param trail_path_length number of entries on the @a trail_path | ||
1461 | * @param message the peer put message | ||
1462 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
1463 | */ | ||
1464 | static int | ||
1465 | handle_dht_p2p_peer_put (void *cls, | ||
1466 | const struct GNUNET_HashCode *trail_id, | ||
1467 | const struct GNUNET_PeerIdentity *trail_path, | ||
1468 | unsigned int trail_path_length, | ||
1469 | const struct GNUNET_MessageHeader *message) | ||
1470 | { | ||
1471 | #if 0 | ||
1472 | const struct PeerGetResultMessage *pgrm; | ||
1473 | |||
1474 | pgrm = (const struct PeerGetResultMessage *) message; | ||
1475 | #endif | ||
1476 | // parse & store in datacache, this is in response to us asking for successors. | ||
1477 | /* | ||
1478 | * steps : | ||
1479 | * 1 check the size of the message | ||
1480 | * 2 use the API to add the value in the "database". Check on the xdht file, how to do it. | ||
1481 | * 3 Did i a have to return a notification or did i have to return GNUNET_[OK|SYSERR]? | ||
1482 | */ | ||
1483 | #if 0 | ||
1484 | GDS_DATACACHE_handle_put (expiration_time, | ||
1485 | key, | ||
1486 | combined_path_length, combined_path, | ||
1487 | block_type, | ||
1488 | data_size, | ||
1489 | data); | ||
1490 | GDS_CLIENTS_process_put (options, | ||
1491 | block_type, | ||
1492 | 0, 0, | ||
1493 | combined_path_length, combined_path, | ||
1494 | expiration_time, | ||
1495 | key, | ||
1496 | data, | ||
1497 | data_size); | ||
1498 | #endif | ||
1499 | return GNUNET_OK; | ||
1500 | } | ||
1501 | |||
1502 | |||
1503 | /** | ||
1504 | * Handler for a message we received along some trail. | ||
1505 | * | ||
1506 | * @param cls closure | ||
1507 | * @param trail_id trail identifier | ||
1508 | * @param trail_path path the message took on the trail, if available | ||
1509 | * @param trail_path_length number of entries on the @a trail_path | ||
1510 | * @param message the message we got | ||
1511 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
1512 | */ | ||
1513 | typedef int | ||
1514 | (*TrailHandlerCallback)(void *cls, | ||
1515 | const struct GNUNET_HashCode *trail_id, | ||
1516 | const struct GNUNET_PeerIdentity *trail_path, | ||
1517 | unsigned int trail_path_length, | ||
1518 | const struct GNUNET_MessageHeader *message); | ||
1519 | |||
1520 | |||
1521 | /** | ||
1522 | * Definition of a handler for a message received along some trail. | ||
1523 | */ | ||
1524 | struct TrailHandler | ||
1525 | { | ||
1526 | /** | ||
1527 | * NULL for end-of-list. | ||
1528 | */ | ||
1529 | TrailHandlerCallback callback; | ||
1530 | |||
1531 | /** | ||
1532 | * Closure for @e callback. | ||
1533 | */ | ||
1534 | void *cls; | ||
1535 | |||
1536 | /** | ||
1537 | * Message type this handler addresses. | ||
1538 | */ | ||
1539 | uint16_t message_type; | ||
1540 | |||
1541 | /** | ||
1542 | * Use 0 for variable-size. | ||
1543 | */ | ||
1544 | uint16_t message_size; | ||
1545 | }; | ||
1546 | |||
1547 | |||
1548 | /** | ||
1549 | * Check that a `struct TrailRouteMessage` is well-formed. | ||
1550 | * | ||
1551 | * @param cls closure | ||
1552 | * @param trm the finger destroy message | ||
1553 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
1554 | */ | ||
1555 | static int | ||
1556 | check_dht_p2p_trail_route (void *cls, | ||
1557 | const struct TrailRouteMessage *trm) | ||
1558 | { | ||
1559 | const struct GNUNET_PeerIdentity *path; | ||
1560 | uint16_t path_length; | ||
1561 | const struct GNUNET_MessageHeader *payload; | ||
1562 | size_t msize; | ||
1563 | |||
1564 | msize = ntohs (trm->header.size); | ||
1565 | path_length = ntohs (trm->path_length); | ||
1566 | if (msize < sizeof (struct TrailRouteMessage) + | ||
1567 | path_length * sizeof (struct GNUNET_PeerIdentity) + | ||
1568 | sizeof (struct GNUNET_MessageHeader) ) | ||
1569 | { | ||
1570 | GNUNET_break_op (0); | ||
1571 | return GNUNET_SYSERR; | ||
1572 | } | ||
1573 | path = (const struct GNUNET_PeerIdentity *) &trm[1]; | ||
1574 | payload = (const struct GNUNET_MessageHeader *) &path[path_length]; | ||
1575 | if (msize != (ntohs (payload->size) + | ||
1576 | sizeof (struct TrailRouteMessage) + | ||
1577 | path_length * sizeof (struct GNUNET_PeerIdentity))) | ||
1578 | { | ||
1579 | GNUNET_break_op (0); | ||
1580 | return GNUNET_SYSERR; | ||
1581 | } | ||
1582 | /* FIXME: verify payload is OK!? */ | ||
1583 | return GNUNET_OK; | ||
1584 | } | ||
1585 | |||
1586 | |||
1587 | /** | ||
1588 | * Handle a `struct TrailRouteMessage`. | ||
1589 | * | ||
1590 | * @param cls closure | ||
1591 | * @param trm the finger destroy message | ||
1592 | */ | ||
1593 | static void | ||
1594 | handle_dht_p2p_trail_route (void *cls, | ||
1595 | const struct TrailRouteMessage *trm) | ||
1596 | { | ||
1597 | static const struct TrailHandler handlers[] = { | ||
1598 | { &handle_dht_p2p_successor_find, NULL, | ||
1599 | GNUNET_MESSAGE_TYPE_WDHT_SUCCESSOR_FIND, | ||
1600 | sizeof (struct FindSuccessorMessage) }, | ||
1601 | { &handle_dht_p2p_peer_get, NULL, | ||
1602 | GNUNET_MESSAGE_TYPE_WDHT_GET, | ||
1603 | 0 }, | ||
1604 | { &handle_dht_p2p_peer_get_result, NULL, | ||
1605 | GNUNET_MESSAGE_TYPE_WDHT_GET_RESULT, | ||
1606 | 0 }, | ||
1607 | { &handle_dht_p2p_peer_put, NULL, | ||
1608 | GNUNET_MESSAGE_TYPE_WDHT_PUT, | ||
1609 | 0 }, | ||
1610 | { NULL, NULL, 0, 0 } | ||
1611 | }; | ||
1612 | struct FriendInfo *sender = cls; | ||
1613 | unsigned int i; | ||
1614 | const struct GNUNET_PeerIdentity *path; | ||
1615 | uint16_t path_length; | ||
1616 | const struct GNUNET_MessageHeader *payload; | ||
1617 | const struct TrailHandler *th; | ||
1618 | struct Trail *trail; | ||
1619 | |||
1620 | path_length = ntohs (trm->path_length); | ||
1621 | path = (const struct GNUNET_PeerIdentity *) &trm[1]; | ||
1622 | payload = (const struct GNUNET_MessageHeader *) &path[path_length]; | ||
1623 | /* Is this message for us? */ | ||
1624 | trail = GNUNET_CONTAINER_multihashmap_get (trail_map, | ||
1625 | &trm->trail_id); | ||
1626 | if ( (NULL != trail->pred) && | ||
1627 | (0 == memcmp (sender->id, | ||
1628 | &trail->pred->id, | ||
1629 | sizeof (struct GNUNET_PeerIdentity))) ) | ||
1630 | { | ||
1631 | /* forward to 'successor' */ | ||
1632 | if (NULL != trail->succ) | ||
1633 | { | ||
1634 | forward_message_on_trail (trail->succ, | ||
1635 | &trail->succ_id, | ||
1636 | ntohs (trm->record_path), | ||
1637 | sender->id, | ||
1638 | path, | ||
1639 | path_length, | ||
1640 | payload); | ||
1641 | return; | ||
1642 | } | ||
1643 | } | ||
1644 | else | ||
1645 | { | ||
1646 | /* forward to 'predecessor' */ | ||
1647 | GNUNET_break_op ( (NULL != trail->succ) && | ||
1648 | (0 == memcmp (sender->id, | ||
1649 | &trail->succ->id, | ||
1650 | sizeof (struct GNUNET_PeerIdentity))) ); | ||
1651 | if (NULL != trail->pred) | ||
1652 | { | ||
1653 | forward_message_on_trail (trail->pred, | ||
1654 | &trail->pred_id, | ||
1655 | ntohs (trm->record_path), | ||
1656 | sender->id, | ||
1657 | path, | ||
1658 | path_length, | ||
1659 | payload); | ||
1660 | return; | ||
1661 | } | ||
1662 | } | ||
1663 | |||
1664 | /* Message is for us, dispatch to handler */ | ||
1665 | th = NULL; | ||
1666 | for (i=0; NULL != handlers[i].callback; i++) | ||
1667 | { | ||
1668 | th = &handlers[i]; | ||
1669 | if (ntohs (payload->type) == th->message_type) | ||
1670 | { | ||
1671 | if ( (0 == th->message_size) || | ||
1672 | (ntohs (payload->size) == th->message_size) ) | ||
1673 | th->callback (th->cls, | ||
1674 | &trm->trail_id, | ||
1675 | path, | ||
1676 | path_length, | ||
1677 | payload); | ||
1678 | else | ||
1679 | GNUNET_break_op (0); | ||
1680 | break; | ||
1681 | } | ||
1682 | } | ||
1683 | GNUNET_break_op (NULL != th); | ||
1684 | } | ||
1685 | |||
1686 | |||
1687 | /** | ||
1688 | * Initialize neighbours subsystem. | ||
1689 | * | ||
1690 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
1691 | */ | ||
1692 | int | ||
1693 | GDS_NEIGHBOURS_init (void) | ||
1694 | { | ||
1695 | struct GNUNET_MQ_MessageHandler core_handlers[] = { | ||
1696 | GNUNET_MQ_hd_fixed_size (dht_p2p_random_walk, | ||
1697 | GNUNET_MESSAGE_TYPE_WDHT_RANDOM_WALK, | ||
1698 | struct RandomWalkMessage, | ||
1699 | NULL), | ||
1700 | GNUNET_MQ_hd_fixed_size (dht_p2p_random_walk_response, | ||
1701 | GNUNET_MESSAGE_TYPE_WDHT_RANDOM_WALK_RESPONSE, | ||
1702 | struct RandomWalkResponseMessage, | ||
1703 | NULL), | ||
1704 | GNUNET_MQ_hd_fixed_size (dht_p2p_trail_destroy, | ||
1705 | GNUNET_MESSAGE_TYPE_WDHT_TRAIL_DESTROY, | ||
1706 | struct TrailDestroyMessage, | ||
1707 | NULL), | ||
1708 | GNUNET_MQ_hd_var_size (dht_p2p_trail_route, | ||
1709 | GNUNET_MESSAGE_TYPE_WDHT_TRAIL_ROUTE, | ||
1710 | struct TrailRouteMessage, | ||
1711 | NULL), | ||
1712 | GNUNET_MQ_handler_end () | ||
1713 | }; | ||
1714 | |||
1715 | core_api = GNUNET_CORE_connect (GDS_cfg, NULL, | ||
1716 | &core_init, | ||
1717 | &handle_core_connect, | ||
1718 | &handle_core_disconnect, | ||
1719 | core_handlers); | ||
1720 | if (NULL == core_api) | ||
1721 | return GNUNET_SYSERR; | ||
1722 | friends_peermap = GNUNET_CONTAINER_multipeermap_create (256, | ||
1723 | GNUNET_NO); | ||
1724 | trail_map = GNUNET_CONTAINER_multihashmap_create (1024, | ||
1725 | GNUNET_YES); | ||
1726 | trail_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); | ||
1727 | return GNUNET_OK; | ||
1728 | } | ||
1729 | |||
1730 | |||
1731 | /** | ||
1732 | * Shutdown neighbours subsystem. | ||
1733 | */ | ||
1734 | void | ||
1735 | GDS_NEIGHBOURS_done (void) | ||
1736 | { | ||
1737 | if (NULL == core_api) | ||
1738 | return; | ||
1739 | GNUNET_CORE_disconnect (core_api); | ||
1740 | core_api = NULL; | ||
1741 | GNUNET_assert (0 == GNUNET_CONTAINER_multipeermap_size (friends_peermap)); | ||
1742 | GNUNET_CONTAINER_multipeermap_destroy (friends_peermap); | ||
1743 | friends_peermap = NULL; | ||
1744 | GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size (trail_map)); | ||
1745 | GNUNET_CONTAINER_multihashmap_destroy (trail_map); | ||
1746 | trail_map = NULL; | ||
1747 | GNUNET_CONTAINER_heap_destroy (trail_heap); | ||
1748 | trail_heap = NULL; | ||
1749 | if (NULL != trail_timeout_task) | ||
1750 | { | ||
1751 | GNUNET_SCHEDULER_cancel (trail_timeout_task); | ||
1752 | trail_timeout_task = NULL; | ||
1753 | } | ||
1754 | } | ||
1755 | |||
1756 | |||
1757 | /** | ||
1758 | * Get my identity | ||
1759 | * | ||
1760 | * @return my identity | ||
1761 | */ | ||
1762 | struct GNUNET_PeerIdentity * | ||
1763 | GDS_NEIGHBOURS_get_id (void) | ||
1764 | { | ||
1765 | return &my_identity; | ||
1766 | } | ||
1767 | |||
1768 | /* end of gnunet-service-wdht_neighbours.c */ | ||
diff --git a/src/dht/gnunet-service-xdht.c b/src/dht/gnunet-service-xdht.c deleted file mode 100644 index 7d0cb8a3a..000000000 --- a/src/dht/gnunet-service-xdht.c +++ /dev/null | |||
@@ -1,121 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2009, 2010, 2011 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file dht/gnunet-service-xdht.c | ||
22 | * @brief GNUnet DHT service | ||
23 | * @author Christian Grothoff | ||
24 | * @author Nathan Evans | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_block_lib.h" | ||
28 | #include "gnunet_util_lib.h" | ||
29 | #include "gnunet_transport_service.h" | ||
30 | #include "gnunet_hello_lib.h" | ||
31 | #include "gnunet_dht_service.h" | ||
32 | #include "gnunet_statistics_service.h" | ||
33 | #include "gnunet-service-dht.h" | ||
34 | #include "gnunet-service-dht_datacache.h" | ||
35 | #include "gnunet-service-dht_neighbours.h" | ||
36 | #include "gnunet-service-dht_nse.h" | ||
37 | #include "gnunet-service-xdht_routing.h" | ||
38 | |||
39 | |||
40 | /** | ||
41 | * Should we store our topology predecessor and successor IDs into statistics? | ||
42 | */ | ||
43 | extern unsigned int track_topology; | ||
44 | |||
45 | |||
46 | /* Code shared between different DHT implementations */ | ||
47 | #include "gnunet-service-dht_clients.c" | ||
48 | |||
49 | |||
50 | /** | ||
51 | * Task run during shutdown. | ||
52 | * | ||
53 | * @param cls unused | ||
54 | */ | ||
55 | static void | ||
56 | shutdown_task (void *cls) | ||
57 | { | ||
58 | GDS_NEIGHBOURS_done (); | ||
59 | GDS_DATACACHE_done (); | ||
60 | GDS_ROUTING_done (); | ||
61 | GDS_NSE_done (); | ||
62 | if (NULL != GDS_block_context) | ||
63 | { | ||
64 | GNUNET_BLOCK_context_destroy (GDS_block_context); | ||
65 | GDS_block_context = NULL; | ||
66 | } | ||
67 | if (NULL != GDS_stats) | ||
68 | { | ||
69 | GNUNET_STATISTICS_destroy (GDS_stats, GNUNET_YES); | ||
70 | GDS_stats = NULL; | ||
71 | } | ||
72 | GDS_CLIENTS_stop (); | ||
73 | } | ||
74 | |||
75 | |||
76 | /** | ||
77 | * Process dht requests. | ||
78 | * | ||
79 | * @param cls closure | ||
80 | * @param c configuration to use | ||
81 | * @param service the initialized service | ||
82 | */ | ||
83 | static void | ||
84 | run (void *cls, | ||
85 | const struct GNUNET_CONFIGURATION_Handle *c, | ||
86 | struct GNUNET_SERVICE_Handle *service) | ||
87 | { | ||
88 | unsigned long long _track_topology; | ||
89 | |||
90 | GDS_cfg = c; | ||
91 | GDS_service = service; | ||
92 | GDS_block_context = GNUNET_BLOCK_context_create (GDS_cfg); | ||
93 | GDS_stats = GNUNET_STATISTICS_create ("dht", | ||
94 | GDS_cfg); | ||
95 | GDS_ROUTING_init (); | ||
96 | GDS_NSE_init (); | ||
97 | GDS_DATACACHE_init (); | ||
98 | GDS_CLIENTS_init (); | ||
99 | if (GNUNET_OK == | ||
100 | GNUNET_CONFIGURATION_get_value_number (c, | ||
101 | "xdht", | ||
102 | "track_toplogy", | ||
103 | &_track_topology)) | ||
104 | { | ||
105 | track_topology = (unsigned int) _track_topology; | ||
106 | } | ||
107 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, | ||
108 | NULL); | ||
109 | if (GNUNET_OK != GDS_NEIGHBOURS_init ()) | ||
110 | { | ||
111 | GNUNET_SCHEDULER_shutdown (); | ||
112 | return; | ||
113 | } | ||
114 | } | ||
115 | |||
116 | |||
117 | /* Finally, define the main method */ | ||
118 | GDS_DHT_SERVICE_INIT("xdht", &run); | ||
119 | |||
120 | |||
121 | /* end of gnunet-service-xdht.c */ | ||
diff --git a/src/dht/gnunet-service-xdht.h b/src/dht/gnunet-service-xdht.h deleted file mode 100644 index 5a8e2e21d..000000000 --- a/src/dht/gnunet-service-xdht.h +++ /dev/null | |||
@@ -1,50 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2011 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file dht/gnunet-service-xdht.h | ||
23 | * @brief GNUnet DHT globals | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | #ifndef GNUNET_SERVICE_XDHT_H | ||
27 | #define GNUNET_SERVICE_XDHT_H | ||
28 | |||
29 | #include "gnunet_util_lib.h" | ||
30 | #include "gnunet_statistics_service.h" | ||
31 | #include "gnunet_transport_service.h" | ||
32 | |||
33 | #define DEBUG_DHT GNUNET_EXTRA_LOGGING | ||
34 | |||
35 | /** | ||
36 | * Configuration we use. | ||
37 | */ | ||
38 | extern const struct GNUNET_CONFIGURATION_Handle *GDS_cfg; | ||
39 | |||
40 | /** | ||
41 | * Our handle to the BLOCK library. | ||
42 | */ | ||
43 | extern struct GNUNET_BLOCK_Context *GDS_block_context; | ||
44 | |||
45 | /** | ||
46 | * Handle for the statistics service. | ||
47 | */ | ||
48 | extern struct GNUNET_STATISTICS_Handle *GDS_stats; | ||
49 | |||
50 | #endif | ||
diff --git a/src/dht/gnunet-service-xdht_hello.c b/src/dht/gnunet-service-xdht_hello.c deleted file mode 100644 index ceaf6f853..000000000 --- a/src/dht/gnunet-service-xdht_hello.c +++ /dev/null | |||
@@ -1,137 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2011 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file dht/gnunet-service-xdht_hello.c | ||
23 | * @brief GNUnet DHT integration with peerinfo | ||
24 | * @author Christian Grothoff | ||
25 | * | ||
26 | * TODO: | ||
27 | * - consider adding mechanism to remove expired HELLOs | ||
28 | */ | ||
29 | #include "platform.h" | ||
30 | #include "gnunet-service-xdht.h" | ||
31 | #include "gnunet-service-xdht_hello.h" | ||
32 | #include "gnunet_peerinfo_service.h" | ||
33 | |||
34 | |||
35 | /** | ||
36 | * Handle for peerinfo notifications. | ||
37 | */ | ||
38 | static struct GNUNET_PEERINFO_NotifyContext *pnc; | ||
39 | |||
40 | /** | ||
41 | * Hash map of peers to HELLOs. | ||
42 | */ | ||
43 | static struct GNUNET_CONTAINER_MultiPeerMap *peer_to_hello; | ||
44 | |||
45 | |||
46 | /** | ||
47 | * Obtain a peer's HELLO if available | ||
48 | * | ||
49 | * @param peer peer to look for a HELLO from | ||
50 | * @return HELLO for the given peer | ||
51 | */ | ||
52 | const struct GNUNET_HELLO_Message * | ||
53 | GDS_HELLO_get (const struct GNUNET_PeerIdentity *peer) | ||
54 | { | ||
55 | if (NULL == peer_to_hello) | ||
56 | return NULL; | ||
57 | return GNUNET_CONTAINER_multipeermap_get (peer_to_hello, peer); | ||
58 | } | ||
59 | |||
60 | |||
61 | /** | ||
62 | * Function called for each HELLO known to PEERINFO. | ||
63 | * | ||
64 | * @param cls closure | ||
65 | * @param peer id of the peer, NULL for last call | ||
66 | * @param hello hello message for the peer (can be NULL) | ||
67 | * @param err_msg error message (not used) | ||
68 | */ | ||
69 | static void | ||
70 | process_hello (void *cls, const struct GNUNET_PeerIdentity *peer, | ||
71 | const struct GNUNET_HELLO_Message *hello, const char *err_msg) | ||
72 | { | ||
73 | struct GNUNET_TIME_Absolute ex; | ||
74 | struct GNUNET_HELLO_Message *hm; | ||
75 | |||
76 | if (hello == NULL) | ||
77 | return; | ||
78 | ex = GNUNET_HELLO_get_last_expiration (hello); | ||
79 | if (0 == GNUNET_TIME_absolute_get_remaining (ex).rel_value_us) | ||
80 | return; | ||
81 | GNUNET_STATISTICS_update (GDS_stats, | ||
82 | gettext_noop ("# HELLOs obtained from peerinfo"), 1, | ||
83 | GNUNET_NO); | ||
84 | hm = GNUNET_CONTAINER_multipeermap_get (peer_to_hello, peer); | ||
85 | GNUNET_free_non_null (hm); | ||
86 | hm = GNUNET_malloc (GNUNET_HELLO_size (hello)); | ||
87 | GNUNET_memcpy (hm, hello, GNUNET_HELLO_size (hello)); | ||
88 | GNUNET_assert (GNUNET_SYSERR != | ||
89 | GNUNET_CONTAINER_multipeermap_put (peer_to_hello, | ||
90 | peer, hm, | ||
91 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE)); | ||
92 | } | ||
93 | |||
94 | |||
95 | /** | ||
96 | * Initialize HELLO subsystem. | ||
97 | */ | ||
98 | void | ||
99 | GDS_HELLO_init () | ||
100 | { | ||
101 | pnc = GNUNET_PEERINFO_notify (GDS_cfg, GNUNET_NO, &process_hello, NULL); | ||
102 | peer_to_hello = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_NO); | ||
103 | } | ||
104 | |||
105 | |||
106 | /** | ||
107 | * Free memory occopied by the HELLO. | ||
108 | */ | ||
109 | static int | ||
110 | free_hello (void *cls, | ||
111 | const struct GNUNET_PeerIdentity *key, | ||
112 | void *hello) | ||
113 | { | ||
114 | GNUNET_free (hello); | ||
115 | return GNUNET_OK; | ||
116 | } | ||
117 | |||
118 | |||
119 | /** | ||
120 | * Shutdown HELLO subsystem. | ||
121 | */ | ||
122 | void | ||
123 | GDS_HELLO_done () | ||
124 | { | ||
125 | if (NULL != pnc) | ||
126 | { | ||
127 | GNUNET_PEERINFO_notify_cancel (pnc); | ||
128 | pnc = NULL; | ||
129 | } | ||
130 | if (NULL != peer_to_hello) | ||
131 | { | ||
132 | GNUNET_CONTAINER_multipeermap_iterate (peer_to_hello, &free_hello, NULL); | ||
133 | GNUNET_CONTAINER_multipeermap_destroy (peer_to_hello); | ||
134 | } | ||
135 | } | ||
136 | |||
137 | /* end of gnunet-service-dht_hello.c */ | ||
diff --git a/src/dht/gnunet-service-xdht_hello.h b/src/dht/gnunet-service-xdht_hello.h deleted file mode 100644 index 7e7a79bcf..000000000 --- a/src/dht/gnunet-service-xdht_hello.h +++ /dev/null | |||
@@ -1,55 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2011 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file dht/gnunet-service-xdht_hello.h | ||
23 | * @brief GNUnet DHT integration with peerinfo | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | #ifndef GNUNET_SERVICE_XDHT_HELLO_H | ||
27 | #define GNUNET_SERVICE_XDHT_HELLO_H | ||
28 | |||
29 | #include "gnunet_util_lib.h" | ||
30 | #include "gnunet_hello_lib.h" | ||
31 | |||
32 | /** | ||
33 | * Obtain a peer's HELLO if available | ||
34 | * | ||
35 | * @param peer peer to look for a HELLO from | ||
36 | * @return HELLO for the given peer | ||
37 | */ | ||
38 | const struct GNUNET_HELLO_Message * | ||
39 | GDS_HELLO_get (const struct GNUNET_PeerIdentity *peer); | ||
40 | |||
41 | |||
42 | /** | ||
43 | * Initialize HELLO subsystem. | ||
44 | */ | ||
45 | void | ||
46 | GDS_HELLO_init (void); | ||
47 | |||
48 | |||
49 | /** | ||
50 | * Shutdown HELLO subsystem. | ||
51 | */ | ||
52 | void | ||
53 | GDS_HELLO_done (void); | ||
54 | |||
55 | #endif | ||
diff --git a/src/dht/gnunet-service-xdht_neighbours.c b/src/dht/gnunet-service-xdht_neighbours.c deleted file mode 100644 index d41eb1900..000000000 --- a/src/dht/gnunet-service-xdht_neighbours.c +++ /dev/null | |||
@@ -1,6265 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2009-2014, 2016 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file dht/gnunet-service-xdht_neighbours.c | ||
23 | * @brief GNUnet DHT service's finger and friend table management code | ||
24 | * @author Supriti Singh | ||
25 | * @author Christian Grothoff | ||
26 | */ | ||
27 | |||
28 | #include "platform.h" | ||
29 | #include "gnunet_util_lib.h" | ||
30 | #include "gnunet_block_lib.h" | ||
31 | #include "gnunet_hello_lib.h" | ||
32 | #include "gnunet_constants.h" | ||
33 | #include "gnunet_protocols.h" | ||
34 | #include "gnunet_ats_service.h" | ||
35 | #include "gnunet_core_service.h" | ||
36 | #include "gnunet_datacache_lib.h" | ||
37 | #include "gnunet_transport_service.h" | ||
38 | #include "gnunet_dht_service.h" | ||
39 | #include "gnunet_statistics_service.h" | ||
40 | #include "gnunet-service-dht.h" | ||
41 | #include "gnunet-service-dht_datacache.h" | ||
42 | #include "gnunet-service-dht_neighbours.h" | ||
43 | #include "gnunet-service-xdht_routing.h" | ||
44 | #include "dht.h" | ||
45 | |||
46 | /** | ||
47 | * TODO: | ||
48 | * 1. In X-Vine paper, there is no policy defined for replicating the data to | ||
49 | * recover in case of peer failure. We can do it in Chord way. In R5N, the key | ||
50 | * is hashed and then data is stored according to the key value generated after | ||
51 | * hashing. | ||
52 | */ | ||
53 | |||
54 | #define DEBUG(...) \ | ||
55 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__) | ||
56 | |||
57 | /** | ||
58 | * Maximum possible fingers (including predecessor) of a peer | ||
59 | */ | ||
60 | #define MAX_FINGERS 65 | ||
61 | |||
62 | /** | ||
63 | * Maximum allowed number of pending messages per friend peer. | ||
64 | */ | ||
65 | #define MAXIMUM_PENDING_PER_FRIEND 64 | ||
66 | |||
67 | /** | ||
68 | * How long to wait before sending another find finger trail request | ||
69 | */ | ||
70 | #define DHT_FIND_FINGER_TRAIL_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 2) | ||
71 | |||
72 | /** | ||
73 | * How long to wait before sending another verify successor message. | ||
74 | */ | ||
75 | #define DHT_SEND_VERIFY_SUCCESSOR_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 2) | ||
76 | |||
77 | /** | ||
78 | * How long to wait before sending another verify successor message. | ||
79 | */ | ||
80 | #define DHT_SEND_VERIFY_SUCCESSOR_RETRY_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) | ||
81 | |||
82 | /** | ||
83 | * How long to wait before retrying notify successor. | ||
84 | */ | ||
85 | #define DHT_SEND_NOTIFY_SUCCESSOR_RETRY_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) | ||
86 | |||
87 | /** | ||
88 | * How long at most to wait for transmission of a request to a friend ? | ||
89 | */ | ||
90 | #define PENDING_MESSAGE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 2) | ||
91 | |||
92 | /** | ||
93 | * Duration for which I may remain congested. | ||
94 | * Note: Its a static value. In future, a peer may do some analysis and calculate | ||
95 | * congestion_timeout based on 'some' parameters. | ||
96 | */ | ||
97 | #define CONGESTION_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 2) | ||
98 | |||
99 | /** | ||
100 | * In case we don't hear back from the current successor, then we can start | ||
101 | * verify successor. | ||
102 | */ | ||
103 | #define WAIT_NOTIFY_CONFIRMATION GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 200) | ||
104 | |||
105 | /** | ||
106 | * Maximum number of trails allowed to go through a friend. | ||
107 | */ | ||
108 | #define TRAILS_THROUGH_FRIEND_THRESHOLD 64 | ||
109 | |||
110 | /** | ||
111 | * Maximum number of trails stored per finger. | ||
112 | */ | ||
113 | #define MAXIMUM_TRAILS_PER_FINGER 4 | ||
114 | |||
115 | /** | ||
116 | * Finger map index for predecessor entry in finger table. | ||
117 | */ | ||
118 | #define PREDECESSOR_FINGER_ID 64 | ||
119 | |||
120 | /** | ||
121 | * FIXME: Its use only at 3 places check if you can remove it. | ||
122 | * To check if a finger is predecessor or not. | ||
123 | */ | ||
124 | enum GDS_NEIGHBOURS_finger_type | ||
125 | { | ||
126 | GDS_FINGER_TYPE_PREDECESSOR = 1, | ||
127 | GDS_FINGER_TYPE_NON_PREDECESSOR = 0 | ||
128 | }; | ||
129 | |||
130 | GNUNET_NETWORK_STRUCT_BEGIN | ||
131 | |||
132 | /** | ||
133 | * P2P PUT message | ||
134 | */ | ||
135 | struct PeerPutMessage | ||
136 | { | ||
137 | /** | ||
138 | * Type: #GNUNET_MESSAGE_TYPE_XDHT_P2P_PUT | ||
139 | */ | ||
140 | struct GNUNET_MessageHeader header; | ||
141 | |||
142 | /** | ||
143 | * Processing options | ||
144 | */ | ||
145 | uint32_t options GNUNET_PACKED; | ||
146 | |||
147 | /** | ||
148 | * Content type. | ||
149 | */ | ||
150 | uint32_t block_type GNUNET_PACKED; | ||
151 | |||
152 | /** | ||
153 | * Hop count | ||
154 | */ | ||
155 | uint32_t hop_count GNUNET_PACKED; | ||
156 | |||
157 | /** | ||
158 | * Replication level for this message | ||
159 | * In the current implementation, this value is not used. | ||
160 | */ | ||
161 | uint32_t desired_replication_level GNUNET_PACKED; | ||
162 | |||
163 | /** | ||
164 | * Length of the PUT path that follows (if tracked). | ||
165 | */ | ||
166 | uint32_t put_path_length GNUNET_PACKED; | ||
167 | |||
168 | /** | ||
169 | * Best known destination (could be my friend or finger) which should | ||
170 | * get this message next. | ||
171 | */ | ||
172 | struct GNUNET_PeerIdentity best_known_destination; | ||
173 | |||
174 | /** | ||
175 | * In case best_known_destination is a finger, then trail to reach | ||
176 | * to that finger. Else its default value is 0. | ||
177 | */ | ||
178 | struct GNUNET_HashCode intermediate_trail_id; | ||
179 | |||
180 | /** | ||
181 | * When does the content expire? | ||
182 | */ | ||
183 | struct GNUNET_TIME_AbsoluteNBO expiration_time; | ||
184 | |||
185 | /** | ||
186 | * The key to store the value under. | ||
187 | */ | ||
188 | struct GNUNET_HashCode key GNUNET_PACKED; | ||
189 | |||
190 | /* put path (if tracked) */ | ||
191 | |||
192 | /* Payload */ | ||
193 | |||
194 | }; | ||
195 | |||
196 | /** | ||
197 | * P2P GET message | ||
198 | */ | ||
199 | struct PeerGetMessage | ||
200 | { | ||
201 | /** | ||
202 | * Type: #GNUNET_MESSAGE_TYPE_XDHT_P2P_GET | ||
203 | */ | ||
204 | struct GNUNET_MessageHeader header; | ||
205 | |||
206 | /** | ||
207 | * Processing options | ||
208 | */ | ||
209 | uint32_t options GNUNET_PACKED; | ||
210 | |||
211 | /** | ||
212 | * Desired content type. | ||
213 | */ | ||
214 | uint32_t block_type GNUNET_PACKED; | ||
215 | |||
216 | /** | ||
217 | * Hop count | ||
218 | */ | ||
219 | uint32_t hop_count GNUNET_PACKED; | ||
220 | |||
221 | /** | ||
222 | * Desired replication level for this request. | ||
223 | * In the current implementation, this value is not used. | ||
224 | */ | ||
225 | uint32_t desired_replication_level GNUNET_PACKED; | ||
226 | |||
227 | /** | ||
228 | * Total number of peers in get path. | ||
229 | */ | ||
230 | unsigned int get_path_length; | ||
231 | |||
232 | /** | ||
233 | * Best known destination (could be my friend or finger) which should | ||
234 | * get this message next. | ||
235 | */ | ||
236 | struct GNUNET_PeerIdentity best_known_destination; | ||
237 | |||
238 | /** | ||
239 | * In case best_known_destination is a finger, then trail to reach | ||
240 | * to that finger. Else its default value is 0. | ||
241 | */ | ||
242 | struct GNUNET_HashCode intermediate_trail_id; | ||
243 | |||
244 | /** | ||
245 | * The key we are looking for. | ||
246 | */ | ||
247 | struct GNUNET_HashCode key; | ||
248 | |||
249 | /* Get path. */ | ||
250 | /* struct GNUNET_PeerIdentity[]*/ | ||
251 | }; | ||
252 | |||
253 | /** | ||
254 | * P2P Result message | ||
255 | */ | ||
256 | struct PeerGetResultMessage | ||
257 | { | ||
258 | /** | ||
259 | * Type: #GNUNET_MESSAGE_TYPE_XDHT_P2P_GET_RESULT | ||
260 | */ | ||
261 | struct GNUNET_MessageHeader header; | ||
262 | |||
263 | /** | ||
264 | * The type for the data. | ||
265 | */ | ||
266 | uint32_t type GNUNET_PACKED; | ||
267 | |||
268 | /** | ||
269 | * Number of peers recorded in the outgoing path from source to the | ||
270 | * stored location of this message. | ||
271 | */ | ||
272 | uint32_t put_path_length GNUNET_PACKED; | ||
273 | |||
274 | /** | ||
275 | * Length of the GET path that follows (if tracked). | ||
276 | */ | ||
277 | uint32_t get_path_length GNUNET_PACKED; | ||
278 | |||
279 | /** | ||
280 | * Peer which queried for get and should get the result. | ||
281 | */ | ||
282 | struct GNUNET_PeerIdentity querying_peer; | ||
283 | |||
284 | /** | ||
285 | * When does the content expire? | ||
286 | */ | ||
287 | struct GNUNET_TIME_AbsoluteNBO expiration_time; | ||
288 | |||
289 | /** | ||
290 | * The key of the corresponding GET request. | ||
291 | */ | ||
292 | struct GNUNET_HashCode key; | ||
293 | |||
294 | /* put path (if tracked) */ | ||
295 | |||
296 | /* get path (if tracked) */ | ||
297 | |||
298 | /* Payload */ | ||
299 | |||
300 | }; | ||
301 | |||
302 | /** | ||
303 | * P2P Trail setup message | ||
304 | */ | ||
305 | struct PeerTrailSetupMessage | ||
306 | { | ||
307 | /** | ||
308 | * Type: #GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_SETUP | ||
309 | */ | ||
310 | struct GNUNET_MessageHeader header; | ||
311 | |||
312 | /** | ||
313 | * Is source_peer trying to setup the trail to a predecessor or any finger. | ||
314 | */ | ||
315 | uint32_t is_predecessor; | ||
316 | |||
317 | /** | ||
318 | * Peer closest to this value will be our finger. | ||
319 | */ | ||
320 | uint64_t final_destination_finger_value; | ||
321 | |||
322 | /** | ||
323 | * Source peer which wants to setup the trail to one of its finger. | ||
324 | */ | ||
325 | struct GNUNET_PeerIdentity source_peer; | ||
326 | |||
327 | /** | ||
328 | * Best known destination (could be my friend or finger) which should | ||
329 | * get this message next. | ||
330 | * | ||
331 | * FIXME: this could be removed if we include trail_source / trail_dest | ||
332 | * in the routing table. This way we save 32 bytes of bandwidth by using | ||
333 | * extra 8 bytes of memory (2 * sizeof (GNUNET_PEER_ID)) | ||
334 | */ | ||
335 | struct GNUNET_PeerIdentity best_known_destination; | ||
336 | |||
337 | /** | ||
338 | * In case best_known_destination is a finger, then trail id of trail to | ||
339 | * reach to this finger. | ||
340 | */ | ||
341 | struct GNUNET_HashCode intermediate_trail_id; | ||
342 | |||
343 | /** | ||
344 | * Trail id for trail which we are trying to setup. | ||
345 | */ | ||
346 | struct GNUNET_HashCode trail_id; | ||
347 | |||
348 | /* List of peers which are part of trail setup so far. | ||
349 | * Trail does NOT include source_peer and peer which will be closest to | ||
350 | * ultimate_destination_finger_value. | ||
351 | * struct GNUNET_PeerIdentity trail[] | ||
352 | */ | ||
353 | }; | ||
354 | |||
355 | /** | ||
356 | * P2P Trail Setup Result message | ||
357 | */ | ||
358 | struct PeerTrailSetupResultMessage | ||
359 | { | ||
360 | |||
361 | /** | ||
362 | * Type: #GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_SETUP_RESULT | ||
363 | */ | ||
364 | struct GNUNET_MessageHeader header; | ||
365 | |||
366 | /** | ||
367 | * Finger to which we have found the path. | ||
368 | */ | ||
369 | struct GNUNET_PeerIdentity finger_identity; | ||
370 | |||
371 | /** | ||
372 | * Peer which started trail_setup to find trail to finger_identity | ||
373 | */ | ||
374 | struct GNUNET_PeerIdentity querying_peer; | ||
375 | |||
376 | /** | ||
377 | * Is the trail setup to querying_peer's predecessor or finger? | ||
378 | */ | ||
379 | uint32_t is_predecessor; | ||
380 | |||
381 | /** | ||
382 | * Value to which finger_identity is the closest peer. | ||
383 | */ | ||
384 | uint64_t ultimate_destination_finger_value; | ||
385 | |||
386 | /** | ||
387 | * Identifier of the trail from querying peer to finger_identity, NOT | ||
388 | * including both endpoints. | ||
389 | */ | ||
390 | struct GNUNET_HashCode trail_id; | ||
391 | |||
392 | /* List of peers which are part of the trail from querying peer to | ||
393 | * finger_identity, NOT including both endpoints. | ||
394 | * struct GNUNET_PeerIdentity trail[] | ||
395 | */ | ||
396 | }; | ||
397 | |||
398 | /** | ||
399 | * P2P Verify Successor Message. | ||
400 | */ | ||
401 | struct PeerVerifySuccessorMessage | ||
402 | { | ||
403 | /** | ||
404 | * Type: #GNUNET_MESSAGE_TYPE_XDHT_P2P_VERIFY_SUCCESSOR | ||
405 | */ | ||
406 | struct GNUNET_MessageHeader header; | ||
407 | |||
408 | /** | ||
409 | * Peer which wants to verify its successor. | ||
410 | */ | ||
411 | struct GNUNET_PeerIdentity source_peer; | ||
412 | |||
413 | /** | ||
414 | * Source Peer's current successor. | ||
415 | */ | ||
416 | struct GNUNET_PeerIdentity successor; | ||
417 | |||
418 | /** | ||
419 | * Identifier of trail to reach from source_peer to successor. | ||
420 | */ | ||
421 | struct GNUNET_HashCode trail_id; | ||
422 | |||
423 | /* List of the peers which are part of trail to reach from source_peer | ||
424 | * to successor, NOT including them | ||
425 | * struct GNUNET_PeerIdentity trail[] | ||
426 | */ | ||
427 | }; | ||
428 | |||
429 | /** | ||
430 | * P2P Verify Successor Result Message | ||
431 | */ | ||
432 | struct PeerVerifySuccessorResultMessage | ||
433 | { | ||
434 | /** | ||
435 | * Type: #GNUNET_MESSAGE_TYPE_XDHT_P2P_VERIFY_SUCCESSOR_RESULT | ||
436 | */ | ||
437 | struct GNUNET_MessageHeader header; | ||
438 | |||
439 | /** | ||
440 | * Peer which sent the request to verify its successor. | ||
441 | */ | ||
442 | struct GNUNET_PeerIdentity querying_peer; | ||
443 | |||
444 | /** | ||
445 | * Successor to which PeerVerifySuccessorMessage was sent. | ||
446 | */ | ||
447 | struct GNUNET_PeerIdentity current_successor; | ||
448 | |||
449 | /** | ||
450 | * Current Predecessor of source_successor. It can be same as querying peer | ||
451 | * or different. In case it is different then it can be querying_peer's | ||
452 | * probable successor. | ||
453 | */ | ||
454 | struct GNUNET_PeerIdentity probable_successor; | ||
455 | |||
456 | /** | ||
457 | * Trail identifier of trail from querying_peer to current_successor. | ||
458 | */ | ||
459 | struct GNUNET_HashCode trail_id; | ||
460 | |||
461 | /** | ||
462 | * Direction in which we are looking at the trail. | ||
463 | */ | ||
464 | uint32_t trail_direction; | ||
465 | |||
466 | /* In case probable_successor != querying_peer, then trail to reach from | ||
467 | * querying_peer to probable_successor, NOT including end points. | ||
468 | * struct GNUNET_PeerIdentity trail[] | ||
469 | */ | ||
470 | }; | ||
471 | |||
472 | /** | ||
473 | * P2P Notify New Successor Message. | ||
474 | */ | ||
475 | struct PeerNotifyNewSuccessorMessage | ||
476 | { | ||
477 | /** | ||
478 | * Type: #GNUNET_MESSAGE_TYPE_XDHT_P2P_NOTIFY_NEW_SUCCESSOR | ||
479 | */ | ||
480 | struct GNUNET_MessageHeader header; | ||
481 | |||
482 | /** | ||
483 | * Peer which wants to notify its new successor. | ||
484 | */ | ||
485 | struct GNUNET_PeerIdentity source_peer; | ||
486 | |||
487 | /** | ||
488 | * New successor of source_peer. | ||
489 | */ | ||
490 | struct GNUNET_PeerIdentity new_successor; | ||
491 | |||
492 | /** | ||
493 | * Unique identifier of the trail from source_peer to new_successor, | ||
494 | * NOT including the endpoints. | ||
495 | */ | ||
496 | struct GNUNET_HashCode trail_id; | ||
497 | |||
498 | /* List of peers in trail from source_peer to new_successor, | ||
499 | * NOT including the endpoints. | ||
500 | * struct GNUNET_PeerIdentity trail[] | ||
501 | */ | ||
502 | }; | ||
503 | |||
504 | /** | ||
505 | * P2P Notify Successor Confirmation message. | ||
506 | */ | ||
507 | struct PeerNotifyConfirmationMessage | ||
508 | { | ||
509 | /** | ||
510 | * Type: #GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_TEARDOWN | ||
511 | */ | ||
512 | struct GNUNET_MessageHeader header; | ||
513 | |||
514 | /** | ||
515 | * Unique identifier of the trail. | ||
516 | */ | ||
517 | struct GNUNET_HashCode trail_id; | ||
518 | |||
519 | /** | ||
520 | * Direction of trail. | ||
521 | */ | ||
522 | uint32_t trail_direction; | ||
523 | }; | ||
524 | |||
525 | |||
526 | /** | ||
527 | * P2P Trail Tear Down message. | ||
528 | */ | ||
529 | struct PeerTrailTearDownMessage | ||
530 | { | ||
531 | /** | ||
532 | * Type: #GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_TEARDOWN | ||
533 | */ | ||
534 | struct GNUNET_MessageHeader header; | ||
535 | |||
536 | /** | ||
537 | * Unique identifier of the trail. | ||
538 | */ | ||
539 | struct GNUNET_HashCode trail_id; | ||
540 | |||
541 | /** | ||
542 | * Direction of trail. | ||
543 | */ | ||
544 | uint32_t trail_direction; | ||
545 | }; | ||
546 | |||
547 | |||
548 | /** | ||
549 | * P2P Trail Rejection Message. | ||
550 | */ | ||
551 | struct PeerTrailRejectionMessage | ||
552 | { | ||
553 | /** | ||
554 | * Type: #GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_SETUP_REJECTION | ||
555 | */ | ||
556 | struct GNUNET_MessageHeader header; | ||
557 | |||
558 | /** | ||
559 | * Peer which wants to set up the trail. | ||
560 | */ | ||
561 | struct GNUNET_PeerIdentity source_peer; | ||
562 | |||
563 | /** | ||
564 | * Peer which sent trail rejection message as it it congested. | ||
565 | */ | ||
566 | struct GNUNET_PeerIdentity congested_peer; | ||
567 | |||
568 | /** | ||
569 | * Peer identity closest to this value will be finger of | ||
570 | * source_peer. | ||
571 | */ | ||
572 | uint64_t ultimate_destination_finger_value; | ||
573 | |||
574 | /** | ||
575 | * Is source_peer trying to setup the trail to its predecessor or finger. | ||
576 | */ | ||
577 | uint32_t is_predecessor; | ||
578 | |||
579 | /** | ||
580 | * Identifier for the trail that source peer is trying to setup. | ||
581 | */ | ||
582 | struct GNUNET_HashCode trail_id; | ||
583 | |||
584 | /** | ||
585 | * Relative time for which congested_peer will remain congested. | ||
586 | */ | ||
587 | struct GNUNET_TIME_Relative congestion_time; | ||
588 | |||
589 | /* Trail_list from source_peer to peer which sent the message for trail setup | ||
590 | * to congested peer. This trail does NOT include source_peer. | ||
591 | struct GNUNET_PeerIdnetity trail[]*/ | ||
592 | }; | ||
593 | |||
594 | /** | ||
595 | * P2P Add Trail Message. | ||
596 | */ | ||
597 | struct PeerAddTrailMessage | ||
598 | { | ||
599 | /** | ||
600 | * Type: #GNUNET_MESSAGE_TYPE_XDHT_P2P_ADD_TRAIL | ||
601 | */ | ||
602 | struct GNUNET_MessageHeader header; | ||
603 | |||
604 | /** | ||
605 | * Source of the routing trail. | ||
606 | */ | ||
607 | struct GNUNET_PeerIdentity source_peer; | ||
608 | |||
609 | /** | ||
610 | * Destination of the routing trail. | ||
611 | */ | ||
612 | struct GNUNET_PeerIdentity destination_peer; | ||
613 | |||
614 | /** | ||
615 | * Unique identifier of the trail from source_peer to destination_peer, | ||
616 | * NOT including the endpoints. | ||
617 | */ | ||
618 | struct GNUNET_HashCode trail_id; | ||
619 | |||
620 | /* Trail from source peer to destination peer, NOT including them. | ||
621 | * struct GNUNET_PeerIdentity trail[] | ||
622 | */ | ||
623 | }; | ||
624 | |||
625 | |||
626 | GNUNET_NETWORK_STRUCT_END | ||
627 | |||
628 | |||
629 | /** | ||
630 | * Entry in friend_peermap. | ||
631 | */ | ||
632 | struct FriendInfo | ||
633 | { | ||
634 | /** | ||
635 | * Friend Identity | ||
636 | */ | ||
637 | const struct GNUNET_PeerIdentity *id; | ||
638 | |||
639 | /** | ||
640 | * Number of trails for which this friend is the first hop or if the friend | ||
641 | * is finger. | ||
642 | */ | ||
643 | unsigned int trails_count; | ||
644 | |||
645 | /** | ||
646 | * In case not 0, then amount of time for which this friend is congested. | ||
647 | */ | ||
648 | struct GNUNET_TIME_Absolute congestion_timestamp; | ||
649 | |||
650 | /** | ||
651 | * Handle for sending messages to this friend. | ||
652 | */ | ||
653 | struct GNUNET_MQ_Handle *mq; | ||
654 | |||
655 | }; | ||
656 | |||
657 | /** | ||
658 | * An individual element of the trail to reach to a finger. | ||
659 | */ | ||
660 | struct Trail_Element | ||
661 | { | ||
662 | /** | ||
663 | * Pointer to next item in the list | ||
664 | */ | ||
665 | struct Trail_Element *next; | ||
666 | |||
667 | /** | ||
668 | * Pointer to prev item in the list | ||
669 | */ | ||
670 | struct Trail_Element *prev; | ||
671 | |||
672 | /** | ||
673 | * An element in this trail. | ||
674 | */ | ||
675 | struct GNUNET_PeerIdentity peer; | ||
676 | }; | ||
677 | |||
678 | /** | ||
679 | * Information about an individual trail. | ||
680 | */ | ||
681 | struct Trail | ||
682 | { | ||
683 | /** | ||
684 | * Head of trail. | ||
685 | */ | ||
686 | struct Trail_Element *trail_head; | ||
687 | |||
688 | /** | ||
689 | * Tail of trail. | ||
690 | */ | ||
691 | struct Trail_Element *trail_tail; | ||
692 | |||
693 | /** | ||
694 | * Unique identifier of this trail. | ||
695 | */ | ||
696 | struct GNUNET_HashCode trail_id; | ||
697 | |||
698 | /** | ||
699 | * Length of trail pointed | ||
700 | */ | ||
701 | unsigned int trail_length; | ||
702 | |||
703 | /** | ||
704 | * Is there a valid trail entry. | ||
705 | */ | ||
706 | unsigned int is_present; | ||
707 | }; | ||
708 | |||
709 | /** | ||
710 | * An entry in finger_table | ||
711 | */ | ||
712 | struct FingerInfo | ||
713 | { | ||
714 | /** | ||
715 | * Finger identity. | ||
716 | */ | ||
717 | struct GNUNET_PeerIdentity finger_identity; | ||
718 | |||
719 | /** | ||
720 | * In case not 0, this amount is time to wait for notify successor message. | ||
721 | * Used ONLY for successor. NOT for any other finger. | ||
722 | */ | ||
723 | struct GNUNET_TIME_Absolute wait_notify_confirmation; | ||
724 | |||
725 | /** | ||
726 | * Is any finger stored at this finger index. | ||
727 | */ | ||
728 | unsigned int is_present; | ||
729 | |||
730 | /** | ||
731 | * Index in finger peer map | ||
732 | */ | ||
733 | uint32_t finger_table_index; | ||
734 | |||
735 | /** | ||
736 | * Number of trails setup so far for this finger. | ||
737 | * Should not cross MAXIMUM_TRAILS_PER_FINGER. | ||
738 | */ | ||
739 | uint32_t trails_count; | ||
740 | |||
741 | /** | ||
742 | * Array of trails to reach to this finger. | ||
743 | */ | ||
744 | struct Trail trail_list[MAXIMUM_TRAILS_PER_FINGER]; | ||
745 | }; | ||
746 | |||
747 | |||
748 | /** | ||
749 | * Stores information about the peer which is closest to destination_finger_value. | ||
750 | * 'closest' can be either successor or predecessor depending on is_predecessor | ||
751 | * flag. | ||
752 | */ | ||
753 | struct Closest_Peer | ||
754 | { | ||
755 | /** | ||
756 | * Destination finger value. | ||
757 | */ | ||
758 | uint64_t destination_finger_value; | ||
759 | |||
760 | /** | ||
761 | * Is finger_value a predecessor or any other finger. | ||
762 | */ | ||
763 | unsigned int is_predecessor; | ||
764 | |||
765 | /** | ||
766 | * Trail id to reach to peer. | ||
767 | * In case peer is my identity or friend, it is set to 0. | ||
768 | */ | ||
769 | struct GNUNET_HashCode trail_id; | ||
770 | |||
771 | /** | ||
772 | * Next destination. In case of friend and my_identity , it is same as next_hop | ||
773 | * In case of finger it is finger identity. | ||
774 | */ | ||
775 | struct GNUNET_PeerIdentity best_known_destination; | ||
776 | |||
777 | /** | ||
778 | * In case best_known_destination is a finger, then first friend in the trail | ||
779 | * to reach to it. In other case, same as best_known_destination. | ||
780 | */ | ||
781 | struct GNUNET_PeerIdentity next_hop; | ||
782 | |||
783 | /** | ||
784 | * In case finger is the next hop, it contains a valid finger table index | ||
785 | * at which the finger is stored. Else, It contains 65, which is out of range | ||
786 | * of finger table index. | ||
787 | */ | ||
788 | unsigned int finger_table_index; | ||
789 | }; | ||
790 | |||
791 | /** | ||
792 | * Context for send_verify_successor_task. | ||
793 | */ | ||
794 | struct VerifySuccessorContext | ||
795 | { | ||
796 | /** | ||
797 | * Number of times this has been scheduled. | ||
798 | */ | ||
799 | unsigned int num_retries_scheduled; | ||
800 | }; | ||
801 | |||
802 | /** | ||
803 | * Task that sends FIND FINGER TRAIL requests. This task is started when we have | ||
804 | * get our first friend. | ||
805 | */ | ||
806 | static struct GNUNET_SCHEDULER_Task *find_finger_trail_task; | ||
807 | |||
808 | /** | ||
809 | * Task that sends verify successor message. This task is started when we get | ||
810 | * our successor for the first time. | ||
811 | */ | ||
812 | static struct GNUNET_SCHEDULER_Task *send_verify_successor_task; | ||
813 | |||
814 | /** | ||
815 | * Task that sends verify successor message. This task is started when we get | ||
816 | * our successor for the first time. | ||
817 | */ | ||
818 | static struct GNUNET_SCHEDULER_Task *send_verify_successor_retry_task; | ||
819 | |||
820 | /** | ||
821 | * Task that sends verify successor message. This task is started when we get | ||
822 | * our successor for the first time. | ||
823 | */ | ||
824 | static struct GNUNET_SCHEDULER_Task *send_notify_new_successor_retry_task; | ||
825 | |||
826 | /** | ||
827 | * Identity of this peer. | ||
828 | */ | ||
829 | static struct GNUNET_PeerIdentity my_identity; | ||
830 | |||
831 | /** | ||
832 | * Peer map of all the friends of a peer | ||
833 | */ | ||
834 | static struct GNUNET_CONTAINER_MultiPeerMap *friend_peermap; | ||
835 | |||
836 | /** | ||
837 | * Array of all the fingers. | ||
838 | */ | ||
839 | static struct FingerInfo finger_table [MAX_FINGERS]; | ||
840 | |||
841 | /** | ||
842 | * Handle to CORE. | ||
843 | */ | ||
844 | static struct GNUNET_CORE_Handle *core_api; | ||
845 | |||
846 | /** | ||
847 | * The current finger index that we have want to find trail to. We start the | ||
848 | * search with value = 0, i.e. successor and then go to PREDCESSOR_FINGER_ID | ||
849 | * and decrement it. For any index 63 <= index < 0, if finger is same as successor, | ||
850 | * we reset this index to 0. | ||
851 | */ | ||
852 | static unsigned int current_search_finger_index; | ||
853 | |||
854 | /** | ||
855 | * Time duration to schedule find finger trail task. | ||
856 | */ | ||
857 | static struct GNUNET_TIME_Relative find_finger_trail_task_next_send_time; | ||
858 | |||
859 | /** | ||
860 | * Time duration to schedule verify successor task. | ||
861 | */ | ||
862 | static struct GNUNET_TIME_Relative verify_successor_next_send_time; | ||
863 | |||
864 | /** | ||
865 | * Time duration to send verify successor again, if result was not received in time. | ||
866 | */ | ||
867 | static struct GNUNET_TIME_Relative verify_successor_retry_time; | ||
868 | |||
869 | /** | ||
870 | * Time duration to retry send_notify_successor. | ||
871 | */ | ||
872 | static struct GNUNET_TIME_Relative notify_successor_retry_time; | ||
873 | |||
874 | /** | ||
875 | * Are we waiting for confirmation from our new successor that it got the | ||
876 | * message | ||
877 | */ | ||
878 | //static unsigned int waiting_for_notify_confirmation; | ||
879 | |||
880 | /* Below variables are used only for testing, and statistics collection. */ | ||
881 | /** | ||
882 | * Should we store our topology predecessor and successor IDs into statistics? | ||
883 | */ | ||
884 | unsigned int track_topology; | ||
885 | |||
886 | /** | ||
887 | * Count of fingers found. Ideally we should have O(logn) fingers for a | ||
888 | * stable network. | ||
889 | */ | ||
890 | static unsigned int total_fingers_found; | ||
891 | |||
892 | /** | ||
893 | * Number of times we found the same successor. | ||
894 | */ | ||
895 | static unsigned int successor_times; | ||
896 | |||
897 | /** | ||
898 | * Number of rounds for which we should search for finger. | ||
899 | */ | ||
900 | static unsigned int fingers_round_count; | ||
901 | |||
902 | |||
903 | /** | ||
904 | * Construct a trail setup message and forward it to @a target_friend | ||
905 | * | ||
906 | * @param source_peer Peer which wants to setup the trail | ||
907 | * @param ultimate_destination_finger_value Peer identity closest to this value | ||
908 | * will be finger to @a source_peer | ||
909 | * @param best_known_destination Best known destination (could be finger or friend) | ||
910 | * which should get this message. In case it is | ||
911 | * friend, then it is same as target_friend | ||
912 | * @param target_friend Friend to which message is forwarded now. | ||
913 | * @param trail_length Total number of peers in trail setup so far. | ||
914 | * @param trail_peer_list Trail setup so far | ||
915 | * @param is_predecessor Is @a source_peer looking for trail to a predecessor or not. | ||
916 | * @param trail_id Unique identifier for the trail we are trying to setup. | ||
917 | * @param intermediate_trail_id Trail id of intermediate trail to reach to | ||
918 | * best_known_destination when its a finger. If not | ||
919 | * used then set to 0. | ||
920 | */ | ||
921 | static void | ||
922 | GDS_NEIGHBOURS_send_trail_setup (const struct GNUNET_PeerIdentity *source_peer, | ||
923 | uint64_t ultimate_destination_finger_value, | ||
924 | const struct GNUNET_PeerIdentity *best_known_destination, | ||
925 | const struct FriendInfo *target_friend, | ||
926 | unsigned int trail_length, | ||
927 | const struct GNUNET_PeerIdentity *trail_peer_list, | ||
928 | unsigned int is_predecessor, | ||
929 | const struct GNUNET_HashCode *trail_id, | ||
930 | const struct GNUNET_HashCode *intermediate_trail_id) | ||
931 | { | ||
932 | struct GNUNET_MQ_Envelope *env; | ||
933 | struct PeerTrailSetupMessage *tsm; | ||
934 | size_t msize; | ||
935 | |||
936 | msize = trail_length * sizeof (struct GNUNET_PeerIdentity); | ||
937 | if (msize + sizeof (struct PeerTrailSetupMessage) | ||
938 | >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE) | ||
939 | { | ||
940 | GNUNET_break (0); | ||
941 | return; | ||
942 | } | ||
943 | if (GNUNET_MQ_get_length (target_friend->mq) >= MAXIMUM_PENDING_PER_FRIEND) | ||
944 | { | ||
945 | GNUNET_STATISTICS_update (GDS_stats, | ||
946 | gettext_noop ("# P2P messages dropped due to full queue"), | ||
947 | 1, | ||
948 | GNUNET_NO); | ||
949 | return; | ||
950 | } | ||
951 | env = GNUNET_MQ_msg_extra (tsm, | ||
952 | msize, | ||
953 | GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_SETUP); | ||
954 | tsm->final_destination_finger_value = GNUNET_htonll (ultimate_destination_finger_value); | ||
955 | tsm->source_peer = *source_peer; | ||
956 | tsm->best_known_destination = *best_known_destination; | ||
957 | tsm->is_predecessor = htonl (is_predecessor); | ||
958 | tsm->trail_id = *trail_id; | ||
959 | tsm->intermediate_trail_id = *intermediate_trail_id; | ||
960 | GNUNET_memcpy (&tsm[1], | ||
961 | trail_peer_list, | ||
962 | msize); | ||
963 | GNUNET_MQ_send (target_friend->mq, | ||
964 | env); | ||
965 | } | ||
966 | |||
967 | |||
968 | /** | ||
969 | * Construct a trail setup result message and forward it to @a target_friend. | ||
970 | * | ||
971 | * @param querying_peer Peer which sent the trail setup request and should get | ||
972 | * the result back. | ||
973 | * @param Finger Peer to which the trail has been setup to. | ||
974 | * @param target_friend Friend to which this message should be forwarded. | ||
975 | * @param trail_length Numbers of peers in the trail. | ||
976 | * @param trail_peer_list Peers which are part of the trail from | ||
977 | * querying_peer to Finger, NOT including them. | ||
978 | * @param is_predecessor Is @a Finger predecessor to @a querying_peer ? | ||
979 | * @param ultimate_destination_finger_value Value to which @a finger is the closest | ||
980 | * peer. | ||
981 | * @param trail_id Unique identifier of the trail. | ||
982 | */ | ||
983 | static void | ||
984 | GDS_NEIGHBOURS_send_trail_setup_result (const struct GNUNET_PeerIdentity *querying_peer, | ||
985 | const struct GNUNET_PeerIdentity *finger, | ||
986 | struct FriendInfo *target_friend, | ||
987 | unsigned int trail_length, | ||
988 | const struct GNUNET_PeerIdentity *trail_peer_list, | ||
989 | unsigned int is_predecessor, | ||
990 | uint64_t ultimate_destination_finger_value, | ||
991 | const struct GNUNET_HashCode *trail_id) | ||
992 | { | ||
993 | struct GNUNET_MQ_Envelope *env; | ||
994 | struct PeerTrailSetupResultMessage *tsrm; | ||
995 | size_t msize; | ||
996 | |||
997 | msize = trail_length * sizeof (struct GNUNET_PeerIdentity); | ||
998 | if (msize + sizeof (struct PeerTrailSetupResultMessage) | ||
999 | >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE) | ||
1000 | { | ||
1001 | GNUNET_break (0); | ||
1002 | return; | ||
1003 | } | ||
1004 | if (GNUNET_MQ_get_length (target_friend->mq) >= MAXIMUM_PENDING_PER_FRIEND) | ||
1005 | { | ||
1006 | GNUNET_STATISTICS_update (GDS_stats, | ||
1007 | gettext_noop ("# P2P messages dropped due to full queue"), | ||
1008 | 1, | ||
1009 | GNUNET_NO); | ||
1010 | return; | ||
1011 | } | ||
1012 | env = GNUNET_MQ_msg_extra (tsrm, | ||
1013 | msize, | ||
1014 | GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_SETUP_RESULT); | ||
1015 | tsrm->querying_peer = *querying_peer; | ||
1016 | tsrm->finger_identity = *finger; | ||
1017 | tsrm->is_predecessor = htonl (is_predecessor); | ||
1018 | tsrm->trail_id = *trail_id; | ||
1019 | tsrm->ultimate_destination_finger_value | ||
1020 | = GNUNET_htonll (ultimate_destination_finger_value); | ||
1021 | GNUNET_memcpy (&tsrm[1], | ||
1022 | trail_peer_list, | ||
1023 | msize); | ||
1024 | GNUNET_MQ_send (target_friend->mq, | ||
1025 | env); | ||
1026 | } | ||
1027 | |||
1028 | |||
1029 | /** | ||
1030 | * Send notify successor confirmation message. | ||
1031 | * | ||
1032 | * @param trail_id Unique Identifier of the trail. | ||
1033 | * @param trail_direction Destination to Source. | ||
1034 | * @param target_friend Friend to get this message next. | ||
1035 | */ | ||
1036 | static void | ||
1037 | GDS_NEIGHBOURS_send_notify_succcessor_confirmation (const struct GNUNET_HashCode *trail_id, | ||
1038 | unsigned int trail_direction, | ||
1039 | struct FriendInfo *target_friend) | ||
1040 | { | ||
1041 | struct PeerNotifyConfirmationMessage *ncm; | ||
1042 | struct GNUNET_MQ_Envelope *env; | ||
1043 | |||
1044 | if (GNUNET_MQ_get_length (target_friend->mq) >= MAXIMUM_PENDING_PER_FRIEND) | ||
1045 | { | ||
1046 | GNUNET_STATISTICS_update (GDS_stats, | ||
1047 | gettext_noop ("# P2P messages dropped due to full queue"), | ||
1048 | 1, | ||
1049 | GNUNET_NO); | ||
1050 | return; | ||
1051 | } | ||
1052 | env = GNUNET_MQ_msg (ncm, | ||
1053 | GNUNET_MESSAGE_TYPE_XDHT_P2P_NOTIFY_SUCCESSOR_CONFIRMATION); | ||
1054 | ncm->trail_id = *trail_id; | ||
1055 | ncm->trail_direction = htonl (trail_direction); | ||
1056 | GNUNET_MQ_send (target_friend->mq, | ||
1057 | env); | ||
1058 | } | ||
1059 | |||
1060 | |||
1061 | /** | ||
1062 | * Send trail rejection message to @a target_friend | ||
1063 | * | ||
1064 | * @param source_peer Peer which is trying to setup the trail. | ||
1065 | * @param ultimate_destination_finger_value Peer closest to this value will be | ||
1066 | * @a source_peer's finger | ||
1067 | * @param congested_peer Peer which sent this message as it is congested. | ||
1068 | * @param is_predecessor Is source_peer looking for trail to a predecessor or not. | ||
1069 | * @param trail_peer_list Trails seen so far in trail setup before getting rejected | ||
1070 | * by congested_peer. This does NOT include @a source_peer | ||
1071 | * and congested_peer. | ||
1072 | * @param trail_length Total number of peers in trail_peer_list, NOT including | ||
1073 | * @a source_peer and @a congested_peer | ||
1074 | * @param trail_id Unique identifier of this trail. | ||
1075 | * @param congestion_timeout Duration given by congested peer as an estimate of | ||
1076 | * how long it may remain congested. | ||
1077 | */ | ||
1078 | static void | ||
1079 | GDS_NEIGHBOURS_send_trail_rejection (const struct GNUNET_PeerIdentity *source_peer, | ||
1080 | uint64_t ultimate_destination_finger_value, | ||
1081 | const struct GNUNET_PeerIdentity *congested_peer, | ||
1082 | unsigned int is_predecessor, | ||
1083 | const struct GNUNET_PeerIdentity *trail_peer_list, | ||
1084 | unsigned int trail_length, | ||
1085 | const struct GNUNET_HashCode *trail_id, | ||
1086 | struct FriendInfo *target_friend, | ||
1087 | const struct GNUNET_TIME_Relative congestion_timeout) | ||
1088 | { | ||
1089 | struct PeerTrailRejectionMessage *trm; | ||
1090 | struct GNUNET_MQ_Envelope *env; | ||
1091 | size_t msize; | ||
1092 | |||
1093 | msize = trail_length * sizeof (struct GNUNET_PeerIdentity); | ||
1094 | if (msize + sizeof (struct PeerTrailRejectionMessage) | ||
1095 | >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE) | ||
1096 | { | ||
1097 | GNUNET_break (0); | ||
1098 | return; | ||
1099 | } | ||
1100 | if (GNUNET_MQ_get_length (target_friend->mq) >= MAXIMUM_PENDING_PER_FRIEND) | ||
1101 | { | ||
1102 | GNUNET_STATISTICS_update (GDS_stats, | ||
1103 | gettext_noop ("# P2P messages dropped due to full queue"), | ||
1104 | 1, | ||
1105 | GNUNET_NO); | ||
1106 | return; | ||
1107 | } | ||
1108 | env = GNUNET_MQ_msg_extra (trm, | ||
1109 | msize, | ||
1110 | GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_SETUP_REJECTION); | ||
1111 | trm->source_peer = *source_peer; | ||
1112 | trm->congested_peer = *congested_peer; | ||
1113 | trm->congestion_time = congestion_timeout; | ||
1114 | trm->is_predecessor = htonl (is_predecessor); | ||
1115 | trm->trail_id = *trail_id; | ||
1116 | trm->ultimate_destination_finger_value | ||
1117 | = GNUNET_htonll (ultimate_destination_finger_value); | ||
1118 | GNUNET_memcpy (&trm[1], | ||
1119 | trail_peer_list, | ||
1120 | msize); | ||
1121 | GNUNET_MQ_send (target_friend->mq, | ||
1122 | env); | ||
1123 | } | ||
1124 | |||
1125 | |||
1126 | /** | ||
1127 | * Construct a verify successor message and forward it to target_friend. | ||
1128 | * @param source_peer Peer which wants to verify its successor. | ||
1129 | * @param successor Peer which is @a source_peer's current successor. | ||
1130 | * @param trail_id Unique Identifier of trail from @a source_peer to @a successor, | ||
1131 | * NOT including them. | ||
1132 | * @param trail List of peers which are part of trail to reach from @a source_peer | ||
1133 | * to @a successor, NOT including them. | ||
1134 | * @param trail_length Total number of peers in @a trail. | ||
1135 | * @param target_friend Next friend to get this message. | ||
1136 | */ | ||
1137 | static void | ||
1138 | GDS_NEIGHBOURS_send_verify_successor_message (const struct GNUNET_PeerIdentity *source_peer, | ||
1139 | const struct GNUNET_PeerIdentity *successor, | ||
1140 | const struct GNUNET_HashCode *trail_id, | ||
1141 | struct GNUNET_PeerIdentity *trail, | ||
1142 | unsigned int trail_length, | ||
1143 | struct FriendInfo *target_friend) | ||
1144 | { | ||
1145 | struct PeerVerifySuccessorMessage *vsm; | ||
1146 | struct GNUNET_MQ_Envelope *env; | ||
1147 | size_t msize; | ||
1148 | |||
1149 | msize = trail_length * sizeof (struct GNUNET_PeerIdentity); | ||
1150 | if (msize + sizeof (*vsm) >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE) | ||
1151 | { | ||
1152 | GNUNET_break (0); | ||
1153 | return; | ||
1154 | } | ||
1155 | if (GNUNET_MQ_get_length (target_friend->mq) >= MAXIMUM_PENDING_PER_FRIEND) | ||
1156 | { | ||
1157 | GNUNET_STATISTICS_update (GDS_stats, | ||
1158 | gettext_noop ("# P2P messages dropped due to full queue"), | ||
1159 | 1, | ||
1160 | GNUNET_NO); | ||
1161 | return; | ||
1162 | } | ||
1163 | env = GNUNET_MQ_msg_extra (vsm, | ||
1164 | msize, | ||
1165 | GNUNET_MESSAGE_TYPE_XDHT_P2P_VERIFY_SUCCESSOR); | ||
1166 | vsm->source_peer = *source_peer; | ||
1167 | vsm->successor = *successor; | ||
1168 | vsm->trail_id = *trail_id; | ||
1169 | GNUNET_memcpy (&vsm[1], | ||
1170 | trail, | ||
1171 | msize); | ||
1172 | GNUNET_MQ_send (target_friend->mq, | ||
1173 | env); | ||
1174 | } | ||
1175 | |||
1176 | |||
1177 | /** | ||
1178 | * FIXME: In every function we pass target friend except for this one. | ||
1179 | * so, either change everything or this one. also, should we just store | ||
1180 | * the pointer to friend in routing table rather than gnunet_peeridentity. | ||
1181 | * if yes then we should keep friend info in.h andmake lot of changes. | ||
1182 | * Construct a trail teardown message and forward it to target friend. | ||
1183 | * | ||
1184 | * @param trail_id Unique identifier of the trail. | ||
1185 | * @param trail_direction Direction of trail. | ||
1186 | * @param target_friend Friend to get this message. | ||
1187 | */ | ||
1188 | void | ||
1189 | GDS_NEIGHBOURS_send_trail_teardown (const struct GNUNET_HashCode *trail_id, | ||
1190 | unsigned int trail_direction, | ||
1191 | const struct GNUNET_PeerIdentity *peer) | ||
1192 | { | ||
1193 | struct PeerTrailTearDownMessage *ttdm; | ||
1194 | struct GNUNET_MQ_Envelope *env; | ||
1195 | struct FriendInfo *target_friend; | ||
1196 | |||
1197 | if (NULL == (target_friend = | ||
1198 | GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
1199 | peer))) | ||
1200 | { | ||
1201 | /* FIXME: In what case friend can be null. ?*/ | ||
1202 | GNUNET_break (0); | ||
1203 | return; | ||
1204 | } | ||
1205 | if (GNUNET_MQ_get_length (target_friend->mq) >= MAXIMUM_PENDING_PER_FRIEND) | ||
1206 | { | ||
1207 | GNUNET_STATISTICS_update (GDS_stats, | ||
1208 | gettext_noop ("# P2P messages dropped due to full queue"), | ||
1209 | 1, | ||
1210 | GNUNET_NO); | ||
1211 | return; | ||
1212 | } | ||
1213 | env = GNUNET_MQ_msg (ttdm, | ||
1214 | GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_TEARDOWN); | ||
1215 | ttdm->trail_id = *trail_id; | ||
1216 | ttdm->trail_direction = htonl (trail_direction); | ||
1217 | GNUNET_MQ_send (target_friend->mq, | ||
1218 | env); | ||
1219 | } | ||
1220 | |||
1221 | |||
1222 | /** | ||
1223 | * Construct a verify successor result message and send it to target_friend | ||
1224 | * | ||
1225 | * @param querying_peer Peer which sent the verify successor message. | ||
1226 | * @param source_successor Current_successor of @a querying_peer. | ||
1227 | * @param current_predecessor Current predecessor of @a successor. Could be same | ||
1228 | * or different from @a querying_peer. | ||
1229 | * @param trail_id Unique identifier of the trail from @a querying_peer to | ||
1230 | * @a successor, NOT including them. | ||
1231 | * @param trail List of peers which are part of trail from @a querying_peer to | ||
1232 | * @a successor, NOT including them. | ||
1233 | * @param trail_length Total number of peers in @a trail | ||
1234 | * @param trail_direction Direction in which we are sending the message. In this | ||
1235 | * case we are sending result from @a successor to @a querying_peer. | ||
1236 | * @param target_friend Next friend to get this message. | ||
1237 | */ | ||
1238 | static void | ||
1239 | GDS_NEIGHBOURS_send_verify_successor_result (const struct GNUNET_PeerIdentity *querying_peer, | ||
1240 | const struct GNUNET_PeerIdentity *current_successor, | ||
1241 | const struct GNUNET_PeerIdentity *probable_successor, | ||
1242 | const struct GNUNET_HashCode *trail_id, | ||
1243 | const struct GNUNET_PeerIdentity *trail, | ||
1244 | unsigned int trail_length, | ||
1245 | enum GDS_ROUTING_trail_direction trail_direction, | ||
1246 | struct FriendInfo *target_friend) | ||
1247 | { | ||
1248 | struct PeerVerifySuccessorResultMessage *vsmr; | ||
1249 | struct GNUNET_MQ_Envelope *env; | ||
1250 | size_t msize; | ||
1251 | |||
1252 | msize = trail_length * sizeof(struct GNUNET_PeerIdentity); | ||
1253 | if (msize + sizeof (struct PeerVerifySuccessorResultMessage) | ||
1254 | >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE) | ||
1255 | { | ||
1256 | GNUNET_break (0); | ||
1257 | return; | ||
1258 | } | ||
1259 | if (GNUNET_MQ_get_length (target_friend->mq) >= MAXIMUM_PENDING_PER_FRIEND) | ||
1260 | { | ||
1261 | GNUNET_STATISTICS_update (GDS_stats, | ||
1262 | gettext_noop ("# P2P messages dropped due to full queue"), | ||
1263 | 1, | ||
1264 | GNUNET_NO); | ||
1265 | return; | ||
1266 | } | ||
1267 | env = GNUNET_MQ_msg_extra (vsmr, | ||
1268 | msize, | ||
1269 | GNUNET_MESSAGE_TYPE_XDHT_P2P_VERIFY_SUCCESSOR_RESULT); | ||
1270 | vsmr->querying_peer = *querying_peer; | ||
1271 | vsmr->current_successor = *current_successor; | ||
1272 | vsmr->probable_successor = *probable_successor; | ||
1273 | vsmr->trail_direction = htonl (trail_direction); | ||
1274 | vsmr->trail_id = *trail_id; | ||
1275 | GNUNET_memcpy (&vsmr[1], | ||
1276 | trail, | ||
1277 | msize); | ||
1278 | GNUNET_MQ_send (target_friend->mq, | ||
1279 | env); | ||
1280 | } | ||
1281 | |||
1282 | |||
1283 | /** | ||
1284 | * Construct a notify new successor message and send it to target_friend | ||
1285 | * @param source_peer Peer which wants to notify to its new successor that it | ||
1286 | * could be its predecessor. | ||
1287 | * @param successor New successor of @a source_peer | ||
1288 | * @param successor_trail List of peers in Trail to reach from | ||
1289 | * @a source_peer to @a new_successor, NOT including | ||
1290 | * the endpoints. | ||
1291 | * @param successor_trail_length Total number of peers in @a new_successor_trail. | ||
1292 | * @param successor_trail_id Unique identifier of @a new_successor_trail. | ||
1293 | * @param target_friend Next friend to get this message. | ||
1294 | */ | ||
1295 | static void | ||
1296 | GDS_NEIGHBOURS_send_notify_new_successor (const struct GNUNET_PeerIdentity *source_peer, | ||
1297 | const struct GNUNET_PeerIdentity *successor, | ||
1298 | const struct GNUNET_PeerIdentity *successor_trail, | ||
1299 | unsigned int successor_trail_length, | ||
1300 | const struct GNUNET_HashCode *succesor_trail_id, | ||
1301 | struct FriendInfo *target_friend) | ||
1302 | { | ||
1303 | struct PeerNotifyNewSuccessorMessage *nsm; | ||
1304 | struct GNUNET_MQ_Envelope *env; | ||
1305 | size_t msize; | ||
1306 | |||
1307 | msize = successor_trail_length * sizeof(struct GNUNET_PeerIdentity); | ||
1308 | if (msize + sizeof (struct PeerNotifyNewSuccessorMessage) | ||
1309 | >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE) | ||
1310 | { | ||
1311 | GNUNET_break (0); | ||
1312 | return; | ||
1313 | } | ||
1314 | if (GNUNET_MQ_get_length (target_friend->mq) >= MAXIMUM_PENDING_PER_FRIEND) | ||
1315 | { | ||
1316 | GNUNET_STATISTICS_update (GDS_stats, | ||
1317 | gettext_noop ("# P2P messages dropped due to full queue"), | ||
1318 | 1, | ||
1319 | GNUNET_NO); | ||
1320 | return; | ||
1321 | } | ||
1322 | env = GNUNET_MQ_msg_extra (nsm, | ||
1323 | msize, | ||
1324 | GNUNET_MESSAGE_TYPE_XDHT_P2P_NOTIFY_NEW_SUCCESSOR); | ||
1325 | nsm->new_successor = *successor; | ||
1326 | nsm->source_peer = *source_peer; | ||
1327 | nsm->trail_id = *succesor_trail_id; | ||
1328 | GNUNET_memcpy (&nsm[1], | ||
1329 | successor_trail, | ||
1330 | msize); | ||
1331 | GNUNET_MQ_send (target_friend->mq, | ||
1332 | env); | ||
1333 | } | ||
1334 | |||
1335 | |||
1336 | /** | ||
1337 | * Construct an add_trail message and send it to target_friend | ||
1338 | * | ||
1339 | * @param source_peer Source of the trail. | ||
1340 | * @param destination_peer Destination of the trail. | ||
1341 | * @param trail_id Unique identifier of the trail from | ||
1342 | * @a source_peer to @a destination_peer, NOT including the endpoints. | ||
1343 | * @param trail List of peers in Trail from @a source_peer to @a destination_peer, | ||
1344 | * NOT including the endpoints. | ||
1345 | * @param trail_length Total number of peers in @a trail. | ||
1346 | * @param target_friend Next friend to get this message. | ||
1347 | */ | ||
1348 | static void | ||
1349 | GDS_NEIGHBOURS_send_add_trail (const struct GNUNET_PeerIdentity *source_peer, | ||
1350 | const struct GNUNET_PeerIdentity *destination_peer, | ||
1351 | const struct GNUNET_HashCode *trail_id, | ||
1352 | const struct GNUNET_PeerIdentity *trail, | ||
1353 | unsigned int trail_length, | ||
1354 | struct FriendInfo *target_friend) | ||
1355 | { | ||
1356 | struct PeerAddTrailMessage *adm; | ||
1357 | struct GNUNET_MQ_Envelope *env; | ||
1358 | size_t msize; | ||
1359 | |||
1360 | msize = trail_length * sizeof(struct GNUNET_PeerIdentity); | ||
1361 | if (msize + sizeof (struct PeerAddTrailMessage) | ||
1362 | >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE) | ||
1363 | { | ||
1364 | GNUNET_break (0); | ||
1365 | return; | ||
1366 | } | ||
1367 | if (GNUNET_MQ_get_length (target_friend->mq) >= MAXIMUM_PENDING_PER_FRIEND) | ||
1368 | { | ||
1369 | GNUNET_STATISTICS_update (GDS_stats, | ||
1370 | gettext_noop ("# P2P messages dropped due to full queue"), | ||
1371 | 1, | ||
1372 | GNUNET_NO); | ||
1373 | return; | ||
1374 | } | ||
1375 | env = GNUNET_MQ_msg_extra (adm, | ||
1376 | msize, | ||
1377 | GNUNET_MESSAGE_TYPE_XDHT_P2P_ADD_TRAIL); | ||
1378 | adm->source_peer = *source_peer; | ||
1379 | adm->destination_peer = *destination_peer; | ||
1380 | adm->trail_id = *trail_id; | ||
1381 | GNUNET_memcpy (&adm[1], | ||
1382 | trail, | ||
1383 | msize); | ||
1384 | GNUNET_MQ_send (target_friend->mq, | ||
1385 | env); | ||
1386 | } | ||
1387 | |||
1388 | |||
1389 | /** | ||
1390 | * Search my location in trail. In case I am present more than once in the | ||
1391 | * trail (can happen during trail setup), then return my lowest index. | ||
1392 | * | ||
1393 | * @param trail List of peers | ||
1394 | * @return my_index if found | ||
1395 | * trail_length + 1 if an entry is present twice, It is an error. | ||
1396 | * -1 if no entry found. | ||
1397 | */ | ||
1398 | static int | ||
1399 | search_my_index (const struct GNUNET_PeerIdentity *trail, | ||
1400 | int trail_length) | ||
1401 | { | ||
1402 | int i; | ||
1403 | int index_seen = trail_length + 1; | ||
1404 | int flag = 0; | ||
1405 | |||
1406 | for (i = 0; i < trail_length; i++) | ||
1407 | { | ||
1408 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &trail[i])) | ||
1409 | { | ||
1410 | flag = 1; | ||
1411 | if(index_seen == (trail_length + 1)) | ||
1412 | index_seen = i; | ||
1413 | else | ||
1414 | { | ||
1415 | DEBUG("Entry is present twice in trail. Its not allowed\n"); | ||
1416 | } | ||
1417 | break; | ||
1418 | } | ||
1419 | } | ||
1420 | |||
1421 | if (1 == flag) | ||
1422 | return index_seen; | ||
1423 | return -1; | ||
1424 | } | ||
1425 | |||
1426 | |||
1427 | /** | ||
1428 | * Check if the friend is congested or have reached maximum number of trails | ||
1429 | * it can be part of of. | ||
1430 | * @param friend Friend to be checked. | ||
1431 | * @return #GNUNET_NO if friend is not congested or have not crossed threshold. | ||
1432 | * #GNUNET_YES if friend is either congested or have crossed threshold | ||
1433 | */ | ||
1434 | static int | ||
1435 | is_friend_congested (struct FriendInfo *friend) | ||
1436 | { | ||
1437 | if (( friend->trails_count < TRAILS_THROUGH_FRIEND_THRESHOLD) && | ||
1438 | ((0 == GNUNET_TIME_absolute_get_remaining | ||
1439 | (friend->congestion_timestamp).rel_value_us))) | ||
1440 | return GNUNET_NO; | ||
1441 | return GNUNET_YES; | ||
1442 | } | ||
1443 | |||
1444 | |||
1445 | /** | ||
1446 | * Select closest finger to value. | ||
1447 | * | ||
1448 | * @param peer1 First peer | ||
1449 | * @param peer2 Second peer | ||
1450 | * @param value Value to be compare | ||
1451 | * @return Closest peer | ||
1452 | */ | ||
1453 | static const struct GNUNET_PeerIdentity * | ||
1454 | select_closest_finger (const struct GNUNET_PeerIdentity *peer1, | ||
1455 | const struct GNUNET_PeerIdentity *peer2, | ||
1456 | uint64_t value) | ||
1457 | { | ||
1458 | uint64_t peer1_value; | ||
1459 | uint64_t peer2_value; | ||
1460 | |||
1461 | GNUNET_memcpy (&peer1_value, peer1, sizeof (uint64_t)); | ||
1462 | GNUNET_memcpy (&peer2_value, peer2, sizeof (uint64_t)); | ||
1463 | peer1_value = GNUNET_ntohll (peer1_value); | ||
1464 | peer2_value = GNUNET_ntohll (peer2_value); | ||
1465 | |||
1466 | if (peer1_value == value) | ||
1467 | { | ||
1468 | return peer1; | ||
1469 | } | ||
1470 | |||
1471 | if (peer2_value == value) | ||
1472 | { | ||
1473 | return peer2; | ||
1474 | } | ||
1475 | |||
1476 | if (value < peer1_value && peer1_value < peer2_value) | ||
1477 | { | ||
1478 | return peer1; | ||
1479 | } | ||
1480 | else if (value < peer2_value && peer2_value < peer1_value) | ||
1481 | { | ||
1482 | return peer2; | ||
1483 | } | ||
1484 | else if (peer1_value < value && value < peer2_value) | ||
1485 | { | ||
1486 | return peer2; | ||
1487 | } | ||
1488 | else if (peer2_value < value && value < peer1_value) | ||
1489 | { | ||
1490 | return peer1; | ||
1491 | } | ||
1492 | else if (peer1_value < peer2_value && peer2_value < value) | ||
1493 | { | ||
1494 | return peer1; | ||
1495 | } | ||
1496 | else // if (peer2_value < peer1_value && peer1_value < value) | ||
1497 | { | ||
1498 | return peer2; | ||
1499 | } | ||
1500 | } | ||
1501 | |||
1502 | |||
1503 | /** | ||
1504 | * Select closest predecessor to value. | ||
1505 | * | ||
1506 | * @param peer1 First peer | ||
1507 | * @param peer2 Second peer | ||
1508 | * @param value Value to be compare | ||
1509 | * @return Peer which precedes value in the network. | ||
1510 | */ | ||
1511 | static const struct GNUNET_PeerIdentity * | ||
1512 | select_closest_predecessor (const struct GNUNET_PeerIdentity *peer1, | ||
1513 | const struct GNUNET_PeerIdentity *peer2, | ||
1514 | uint64_t value) | ||
1515 | { | ||
1516 | uint64_t peer1_value; | ||
1517 | uint64_t peer2_value; | ||
1518 | |||
1519 | GNUNET_memcpy (&peer1_value, peer1, sizeof (uint64_t)); | ||
1520 | GNUNET_memcpy (&peer2_value, peer2, sizeof (uint64_t)); | ||
1521 | peer1_value = GNUNET_ntohll (peer1_value); | ||
1522 | peer2_value = GNUNET_ntohll (peer2_value); | ||
1523 | |||
1524 | if (peer1_value == value) | ||
1525 | { | ||
1526 | return peer1; | ||
1527 | } | ||
1528 | |||
1529 | if (peer2_value == value) | ||
1530 | { | ||
1531 | return peer2; | ||
1532 | } | ||
1533 | |||
1534 | if (value < peer1_value && peer1_value < peer2_value) | ||
1535 | { | ||
1536 | return peer2; | ||
1537 | } | ||
1538 | else if (value < peer2_value && peer2_value < peer1_value) | ||
1539 | { | ||
1540 | return peer1; | ||
1541 | } | ||
1542 | else if (peer1_value < value && value < peer2_value) | ||
1543 | { | ||
1544 | return peer1; | ||
1545 | } | ||
1546 | else if (peer2_value < value && value < peer1_value) | ||
1547 | { | ||
1548 | return peer2; | ||
1549 | } | ||
1550 | else if (peer1_value < peer2_value && peer2_value < value) | ||
1551 | { | ||
1552 | return peer2; | ||
1553 | } | ||
1554 | else // if (peer2_value < peer1_value && peer1_value < value) | ||
1555 | { | ||
1556 | return peer1; | ||
1557 | } | ||
1558 | } | ||
1559 | |||
1560 | #if 0 | ||
1561 | /** | ||
1562 | * | ||
1563 | * | ||
1564 | */ | ||
1565 | void | ||
1566 | test_print_trail (struct GNUNET_PeerIdentity *trail, | ||
1567 | unsigned int trail_length) | ||
1568 | { | ||
1569 | struct GNUNET_PeerIdentity print_peer; | ||
1570 | int i; | ||
1571 | |||
1572 | FPRINTF (stderr,_("\nSUPU %s, %s, %d,trail_length = %d"), | ||
1573 | __FILE__, __func__,__LINE__,trail_length); | ||
1574 | for (i =0 ; i< trail_length; i++) | ||
1575 | { | ||
1576 | print_peer = trail[i]; | ||
1577 | FPRINTF (stderr,_("\nSUPU %s, %s, %d,trail[%d]=%s"), | ||
1578 | __FILE__, __func__,__LINE__,i,GNUNET_i2s(&print_peer)); | ||
1579 | } | ||
1580 | } | ||
1581 | #endif | ||
1582 | |||
1583 | #if 0 | ||
1584 | /** | ||
1585 | * This is a test function to print all the entries of friend table. | ||
1586 | */ | ||
1587 | static void | ||
1588 | test_friend_peermap_print () | ||
1589 | { | ||
1590 | struct FriendInfo *friend; | ||
1591 | struct GNUNET_CONTAINER_MultiPeerMapIterator *friend_iter; | ||
1592 | struct GNUNET_PeerIdentity print_peer; | ||
1593 | struct GNUNET_PeerIdentity key_ret; | ||
1594 | int i; | ||
1595 | |||
1596 | print_peer = my_identity; | ||
1597 | FPRINTF (stderr,_("\nSUPU************ FRIEND_PEERMAP of %s"),GNUNET_i2s(&print_peer)); | ||
1598 | friend_iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap); | ||
1599 | |||
1600 | for (i = 0; i < GNUNET_CONTAINER_multipeermap_size (friend_peermap); i++) | ||
1601 | { | ||
1602 | if(GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (friend_iter, | ||
1603 | &key_ret, | ||
1604 | (const void **)&friend)) | ||
1605 | { | ||
1606 | GNUNET_memcpy (&print_peer, &key_ret, sizeof (struct GNUNET_PeerIdentity)); | ||
1607 | FPRINTF (stderr,_("\nSUPU %s, %s, %d, friend = %s, friend->trails_count = %d"), | ||
1608 | __FILE__, __func__,__LINE__, GNUNET_i2s(&print_peer), friend->trails_count); | ||
1609 | } | ||
1610 | } | ||
1611 | } | ||
1612 | #endif | ||
1613 | |||
1614 | #if 0 | ||
1615 | /** | ||
1616 | * This is a test function, to print all the entries of finger table. | ||
1617 | */ | ||
1618 | static void | ||
1619 | test_finger_table_print() | ||
1620 | { | ||
1621 | struct FingerInfo *finger; | ||
1622 | struct GNUNET_PeerIdentity print_peer; | ||
1623 | //struct Trail *trail; | ||
1624 | int i; | ||
1625 | //int j; | ||
1626 | //int k; | ||
1627 | print_peer = my_identity; | ||
1628 | FPRINTF (stderr,_("\nSUPU************ FINGER_TABLE of %s"),GNUNET_i2s(&print_peer)); | ||
1629 | for (i = 0; i < MAX_FINGERS; i++) | ||
1630 | { | ||
1631 | finger = &finger_table[i]; | ||
1632 | |||
1633 | if (GNUNET_NO == finger->is_present) | ||
1634 | continue; | ||
1635 | |||
1636 | print_peer = finger->finger_identity; | ||
1637 | FPRINTF (stderr,_("\nSUPU %s, %s, %d, finger_table[%d] = %s, trails_count = %d"), | ||
1638 | __FILE__, __func__,__LINE__,i,GNUNET_i2s (&print_peer), finger->trails_count); | ||
1639 | |||
1640 | #if 0 | ||
1641 | for (j = 0; j < finger->trails_count; j++) | ||
1642 | { | ||
1643 | trail = &finger->trail_list[j]; | ||
1644 | FPRINTF (stderr,_("\nSUPU %s, %s, %d, trail_id[%d]=%s"),__FILE__, __func__,__LINE__,j, GNUNET_h2s(&trail->trail_id)); | ||
1645 | struct Trail_Element *element; | ||
1646 | element = trail->trail_head; | ||
1647 | for (k = 0; k < trail->trail_length; k++) | ||
1648 | { | ||
1649 | print_peer = element->peer; | ||
1650 | FPRINTF (stderr,_("\nSUPU %s, %s, %d,trail[%d] = %s "),__FILE__, __func__,__LINE__,k, GNUNET_i2s(&print_peer)); | ||
1651 | element = element->next; | ||
1652 | } | ||
1653 | } | ||
1654 | #endif | ||
1655 | } | ||
1656 | } | ||
1657 | #endif | ||
1658 | |||
1659 | /** | ||
1660 | * Select the closest peer among two peers (which should not be same) | ||
1661 | * with respect to value and finger_table_index | ||
1662 | * NOTE: peer1 != peer2 | ||
1663 | * @param peer1 First peer | ||
1664 | * @param peer2 Second peer | ||
1665 | * @param value Value relative to which we find the closest | ||
1666 | * @param is_predecessor Is value a predecessor or any other finger. | ||
1667 | * @return Closest peer among two peers. | ||
1668 | */ | ||
1669 | static const struct GNUNET_PeerIdentity * | ||
1670 | select_closest_peer (const struct GNUNET_PeerIdentity *peer1, | ||
1671 | const struct GNUNET_PeerIdentity *peer2, | ||
1672 | uint64_t value, | ||
1673 | unsigned int is_predecessor) | ||
1674 | { | ||
1675 | /* This check is here to ensure that calling function never sends | ||
1676 | same peer value in peer1 and peer2. Remove it later. */ | ||
1677 | GNUNET_assert(0 != GNUNET_CRYPTO_cmp_peer_identity (peer1, peer2)); | ||
1678 | if (1 == is_predecessor) | ||
1679 | return select_closest_predecessor (peer1, peer2, value); | ||
1680 | |||
1681 | // TODO: Change name to something like select_closest_successor!! | ||
1682 | return select_closest_finger (peer1, peer2, value); | ||
1683 | } | ||
1684 | |||
1685 | |||
1686 | /** | ||
1687 | * Iterate over the list of all the trails of a finger. In case the first | ||
1688 | * friend to reach the finger has reached trail threshold or is congested, | ||
1689 | * then don't select it. In case there multiple available good trails to reach | ||
1690 | * to Finger, choose the one with shortest trail length. | ||
1691 | * Note: We use length as parameter. But we can use any other suitable parameter | ||
1692 | * also. | ||
1693 | * @param finger Finger Finger whose trail we have to select. | ||
1694 | * @return Trail Selected Trail. | ||
1695 | */ | ||
1696 | static struct Trail * | ||
1697 | select_finger_trail (struct FingerInfo *finger) | ||
1698 | { | ||
1699 | struct FriendInfo *friend; | ||
1700 | struct Trail *current_finger_trail; | ||
1701 | struct Trail *best_trail = NULL; | ||
1702 | unsigned int i; | ||
1703 | |||
1704 | GNUNET_assert (finger->trails_count > 0); | ||
1705 | for (i = 0; i < finger->trails_count; i++) | ||
1706 | { | ||
1707 | current_finger_trail = &finger->trail_list[i]; | ||
1708 | |||
1709 | /* No trail stored at this index. */ | ||
1710 | if (GNUNET_NO == current_finger_trail->is_present) | ||
1711 | continue; | ||
1712 | |||
1713 | GNUNET_assert (NULL != | ||
1714 | (friend = | ||
1715 | GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
1716 | ¤t_finger_trail->trail_head->peer))); | ||
1717 | |||
1718 | /* First friend to reach trail is not free. */ | ||
1719 | if (GNUNET_YES == is_friend_congested (friend)) | ||
1720 | continue; | ||
1721 | |||
1722 | if (NULL == best_trail || | ||
1723 | best_trail->trail_length > current_finger_trail->trail_length) | ||
1724 | { | ||
1725 | best_trail = current_finger_trail; | ||
1726 | } | ||
1727 | } | ||
1728 | |||
1729 | return best_trail; | ||
1730 | } | ||
1731 | |||
1732 | |||
1733 | /** | ||
1734 | * Compare FINGER entry with current successor. If finger's first friend of all | ||
1735 | * its trail is not congested and has not crossed trail threshold, then check | ||
1736 | * if finger peer identity is closer to final_destination_finger_value than | ||
1737 | * current_successor. If yes then update current_successor. | ||
1738 | * @param current_successor[in/out] | ||
1739 | * @return | ||
1740 | */ | ||
1741 | static void | ||
1742 | compare_finger_and_current_closest_peer (struct Closest_Peer *current_closest_peer) | ||
1743 | { | ||
1744 | struct FingerInfo *finger; | ||
1745 | const struct GNUNET_PeerIdentity *closest_peer; | ||
1746 | struct Trail *finger_trail; | ||
1747 | int i; | ||
1748 | |||
1749 | /* Iterate over finger table. */ | ||
1750 | for (i = 0; i < MAX_FINGERS; i++) | ||
1751 | { | ||
1752 | finger = &finger_table[i]; | ||
1753 | |||
1754 | if (GNUNET_NO == finger->is_present) | ||
1755 | continue; | ||
1756 | |||
1757 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&finger->finger_identity, | ||
1758 | ¤t_closest_peer->best_known_destination)) | ||
1759 | continue; | ||
1760 | |||
1761 | /* If I am my own finger, then ignore this finger. */ | ||
1762 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&finger->finger_identity, | ||
1763 | &my_identity)) | ||
1764 | continue; | ||
1765 | |||
1766 | /* If finger is a friend, we have already checked it in previous function. */ | ||
1767 | if (NULL != (GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
1768 | &finger->finger_identity))) | ||
1769 | { | ||
1770 | continue; | ||
1771 | } | ||
1772 | |||
1773 | closest_peer = select_closest_peer (&finger->finger_identity, | ||
1774 | ¤t_closest_peer->best_known_destination, | ||
1775 | current_closest_peer->destination_finger_value, | ||
1776 | current_closest_peer->is_predecessor); | ||
1777 | |||
1778 | if (0 == GNUNET_CRYPTO_cmp_peer_identity(&finger->finger_identity, | ||
1779 | closest_peer)) | ||
1780 | { | ||
1781 | /* Choose one of the trail to reach to finger. */ | ||
1782 | finger_trail = select_finger_trail (finger); | ||
1783 | |||
1784 | /* In case no trail found, ignore this finger. */ | ||
1785 | if (NULL == finger_trail) | ||
1786 | continue; | ||
1787 | |||
1788 | current_closest_peer->best_known_destination = *closest_peer; | ||
1789 | current_closest_peer->next_hop = finger_trail->trail_head->peer; | ||
1790 | current_closest_peer->trail_id = finger_trail->trail_id; | ||
1791 | current_closest_peer->finger_table_index = i; | ||
1792 | } | ||
1793 | continue; | ||
1794 | } | ||
1795 | } | ||
1796 | |||
1797 | |||
1798 | /** | ||
1799 | * Compare friend entry with current successor. | ||
1800 | * If friend identity and current_successor is same, then do nothing. | ||
1801 | * If friend is not congested and has not crossed trail threshold, then check | ||
1802 | * if friend peer identity is closer to final_destination_finger_value than | ||
1803 | * current_successor. If yes then update current_successor. | ||
1804 | * | ||
1805 | * @param cls closure | ||
1806 | * @param key current public key | ||
1807 | * @param value struct Closest_Peer | ||
1808 | * @return #GNUNET_YES if we should continue to iterate, | ||
1809 | * #GNUNET_NO if not. | ||
1810 | */ | ||
1811 | static int | ||
1812 | compare_friend_and_current_closest_peer (void *cls, | ||
1813 | const struct GNUNET_PeerIdentity *key, | ||
1814 | void *value) | ||
1815 | { | ||
1816 | struct FriendInfo *friend = value; | ||
1817 | struct Closest_Peer *current_closest_peer = cls; | ||
1818 | const struct GNUNET_PeerIdentity *closest_peer; | ||
1819 | |||
1820 | /* Friend is either congested or has crossed threshold. */ | ||
1821 | if (GNUNET_YES == is_friend_congested (friend)) | ||
1822 | return GNUNET_YES; | ||
1823 | |||
1824 | /* If current_closest_peer and friend identity are same, then do nothing.*/ | ||
1825 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (friend->id, | ||
1826 | ¤t_closest_peer->best_known_destination)) | ||
1827 | { | ||
1828 | GNUNET_break (0); | ||
1829 | return GNUNET_YES; | ||
1830 | } | ||
1831 | |||
1832 | closest_peer = select_closest_peer (friend->id, | ||
1833 | ¤t_closest_peer->best_known_destination, | ||
1834 | current_closest_peer->destination_finger_value, | ||
1835 | current_closest_peer->is_predecessor); | ||
1836 | |||
1837 | /* Is friend the closest successor? */ | ||
1838 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (friend->id, | ||
1839 | closest_peer)) | ||
1840 | { | ||
1841 | current_closest_peer->best_known_destination = *friend->id; | ||
1842 | current_closest_peer->next_hop = *friend->id; | ||
1843 | } | ||
1844 | return GNUNET_YES; | ||
1845 | } | ||
1846 | |||
1847 | |||
1848 | /** | ||
1849 | * Initialize current_successor to my_identity. | ||
1850 | * @param my_identity My peer identity | ||
1851 | * @return Updated closest_peer | ||
1852 | */ | ||
1853 | static struct Closest_Peer | ||
1854 | init_closest_peer (struct GNUNET_PeerIdentity my_identity, | ||
1855 | uint64_t destination_finger_value, | ||
1856 | unsigned int is_predecessor) | ||
1857 | { | ||
1858 | struct Closest_Peer current_closest_peer; | ||
1859 | |||
1860 | memset (¤t_closest_peer.trail_id, | ||
1861 | 0, | ||
1862 | sizeof(struct GNUNET_HashCode)); | ||
1863 | current_closest_peer.destination_finger_value = destination_finger_value; | ||
1864 | current_closest_peer.is_predecessor = is_predecessor; | ||
1865 | current_closest_peer.next_hop = my_identity; | ||
1866 | current_closest_peer.best_known_destination = my_identity; | ||
1867 | current_closest_peer.finger_table_index = 65; //65 is a for non valid finger table index. | ||
1868 | return current_closest_peer; | ||
1869 | } | ||
1870 | |||
1871 | |||
1872 | /** | ||
1873 | * Find locally best known peer, among your own identity, friend and finger list, | ||
1874 | * which is closest to given destination_finger_value. | ||
1875 | * | ||
1876 | * NOTE: In case a friend is also a finger, then it is always chosen as friend | ||
1877 | * not a finger. | ||
1878 | * @param destination_finger_value Peer closest to this value will be the next destination. | ||
1879 | * @param is_predecessor Are we looking for predecessor or finger? | ||
1880 | * @return Closest_Peer that contains all the relevant field to reach to | ||
1881 | * @a destination_finger_value | ||
1882 | */ | ||
1883 | static struct Closest_Peer | ||
1884 | find_local_best_known_next_hop (uint64_t destination_finger_value, | ||
1885 | unsigned int is_predecessor) | ||
1886 | { | ||
1887 | struct Closest_Peer current_closest_peer; | ||
1888 | |||
1889 | /* Initialize current_successor to my_identity. */ | ||
1890 | current_closest_peer = init_closest_peer (my_identity, | ||
1891 | destination_finger_value, | ||
1892 | is_predecessor); | ||
1893 | |||
1894 | /* Compare each friend entry with current_successor and update current_successor | ||
1895 | * with friend if its closest. */ | ||
1896 | GNUNET_assert | ||
1897 | (GNUNET_SYSERR != | ||
1898 | GNUNET_CONTAINER_multipeermap_iterate (friend_peermap, | ||
1899 | &compare_friend_and_current_closest_peer, | ||
1900 | ¤t_closest_peer)); | ||
1901 | |||
1902 | /* Compare each finger entry with current_successor and update current_successor | ||
1903 | * with finger if its closest. */ | ||
1904 | compare_finger_and_current_closest_peer (¤t_closest_peer); | ||
1905 | return current_closest_peer; | ||
1906 | } | ||
1907 | |||
1908 | |||
1909 | /** | ||
1910 | * Construct a Put message and send it to target_peer. | ||
1911 | * @param key Key for the content | ||
1912 | * @param block_type Type of the block | ||
1913 | * @param options Routing options | ||
1914 | * @param desired_replication_level Desired replication count | ||
1915 | * @param best_known_dest Peer to which this message should reach eventually, | ||
1916 | * as it is best known destination to me. | ||
1917 | * @param intermediate_trail_id Trail id in case | ||
1918 | * @param target_peer Peer to which this message will be forwarded. | ||
1919 | * @param hop_count Number of hops traversed so far. | ||
1920 | * @param put_path_length Total number of peers in @a put_path | ||
1921 | * @param put_path Number of peers traversed so far | ||
1922 | * @param expiration_time When does the content expire | ||
1923 | * @param data Content to store | ||
1924 | * @param data_size Size of content @a data in bytes | ||
1925 | */ | ||
1926 | void | ||
1927 | GDS_NEIGHBOURS_send_put (const struct GNUNET_HashCode *key, | ||
1928 | enum GNUNET_BLOCK_Type block_type, | ||
1929 | enum GNUNET_DHT_RouteOption options, | ||
1930 | uint32_t desired_replication_level, | ||
1931 | struct GNUNET_PeerIdentity best_known_dest, | ||
1932 | struct GNUNET_HashCode intermediate_trail_id, | ||
1933 | struct GNUNET_PeerIdentity *target_peer, | ||
1934 | uint32_t hop_count, | ||
1935 | uint32_t put_path_length, | ||
1936 | struct GNUNET_PeerIdentity *put_path, | ||
1937 | struct GNUNET_TIME_Absolute expiration_time, | ||
1938 | const void *data, size_t data_size) | ||
1939 | { | ||
1940 | struct PeerPutMessage *ppm; | ||
1941 | struct GNUNET_MQ_Envelope *env; | ||
1942 | struct FriendInfo *target_friend; | ||
1943 | struct GNUNET_PeerIdentity *pp; | ||
1944 | size_t msize; | ||
1945 | |||
1946 | msize = put_path_length * sizeof (struct GNUNET_PeerIdentity) + data_size; | ||
1947 | if (msize + sizeof (struct PeerPutMessage) | ||
1948 | >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE) | ||
1949 | { | ||
1950 | put_path_length = 0; | ||
1951 | msize = data_size; | ||
1952 | } | ||
1953 | if (msize + sizeof (struct PeerPutMessage) | ||
1954 | >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE) | ||
1955 | { | ||
1956 | GNUNET_break (0); | ||
1957 | return; | ||
1958 | } | ||
1959 | |||
1960 | GNUNET_assert (NULL != | ||
1961 | (target_friend = | ||
1962 | GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
1963 | target_peer))); | ||
1964 | env = GNUNET_MQ_msg_extra (ppm, | ||
1965 | msize, | ||
1966 | GNUNET_MESSAGE_TYPE_XDHT_P2P_PUT); | ||
1967 | ppm->options = htonl (options); | ||
1968 | ppm->block_type = htonl (block_type); | ||
1969 | ppm->hop_count = htonl (hop_count + 1); | ||
1970 | ppm->desired_replication_level = htonl (desired_replication_level); | ||
1971 | ppm->expiration_time = GNUNET_TIME_absolute_hton (expiration_time); | ||
1972 | ppm->best_known_destination = best_known_dest; | ||
1973 | ppm->intermediate_trail_id = intermediate_trail_id; | ||
1974 | ppm->key = *key; | ||
1975 | ppm->put_path_length = htonl (put_path_length); | ||
1976 | pp = (struct GNUNET_PeerIdentity *) &ppm[1]; | ||
1977 | GNUNET_memcpy (pp, | ||
1978 | put_path, | ||
1979 | put_path_length * sizeof (struct GNUNET_PeerIdentity)); | ||
1980 | GNUNET_memcpy (&pp[put_path_length], | ||
1981 | data, | ||
1982 | data_size); | ||
1983 | GNUNET_MQ_send (target_friend->mq, | ||
1984 | env); | ||
1985 | } | ||
1986 | |||
1987 | |||
1988 | /** | ||
1989 | * Handle the put request from the client. | ||
1990 | * | ||
1991 | * @param block_type Type of the block | ||
1992 | * @param options Routing options | ||
1993 | * @param desired_replication_level Desired replication count | ||
1994 | * @param expiration_time When does the content expire | ||
1995 | * @param hop_count how many hops has this message traversed so far | ||
1996 | * @param bf Bloom filter of peers this PUT has already traversed | ||
1997 | * @param key Key for the content | ||
1998 | * @param put_path_length number of entries in put_path | ||
1999 | * @param put_path peers this request has traversed so far (if tracked) | ||
2000 | * @param data Content to store | ||
2001 | * @param data_size Size of content @a data in bytes | ||
2002 | * @return #GNUNET_OK if the request was forwarded, #GNUNET_NO if not | ||
2003 | */ | ||
2004 | int | ||
2005 | GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type block_type, | ||
2006 | enum GNUNET_DHT_RouteOption options, | ||
2007 | uint32_t desired_replication_level, | ||
2008 | struct GNUNET_TIME_Absolute expiration_time, | ||
2009 | uint32_t hop_count, | ||
2010 | struct GNUNET_CONTAINER_BloomFilter *bf, | ||
2011 | const struct GNUNET_HashCode *key, | ||
2012 | unsigned int put_path_length, | ||
2013 | struct GNUNET_PeerIdentity *put_path, | ||
2014 | const void *data, | ||
2015 | size_t data_size) | ||
2016 | { | ||
2017 | struct GNUNET_PeerIdentity best_known_dest; | ||
2018 | struct GNUNET_HashCode intermediate_trail_id; | ||
2019 | struct GNUNET_PeerIdentity next_hop; | ||
2020 | uint64_t key_value; | ||
2021 | struct Closest_Peer successor; | ||
2022 | |||
2023 | GNUNET_memcpy (&key_value, | ||
2024 | key, | ||
2025 | sizeof (uint64_t)); | ||
2026 | key_value = GNUNET_ntohll (key_value); | ||
2027 | successor = find_local_best_known_next_hop (key_value, | ||
2028 | GDS_FINGER_TYPE_NON_PREDECESSOR); | ||
2029 | best_known_dest = successor.best_known_destination; | ||
2030 | next_hop = successor.next_hop; | ||
2031 | intermediate_trail_id = successor.trail_id; | ||
2032 | |||
2033 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&best_known_dest, | ||
2034 | &my_identity)) | ||
2035 | { | ||
2036 | DEBUG("\n PUT_REQUEST_SUCCESSFUL for key = %s", | ||
2037 | GNUNET_h2s(key)); | ||
2038 | /* I am the destination. */ | ||
2039 | GDS_DATACACHE_handle_put (expiration_time, | ||
2040 | key, | ||
2041 | 0, | ||
2042 | NULL, | ||
2043 | block_type, | ||
2044 | data_size, | ||
2045 | data); | ||
2046 | GDS_CLIENTS_process_put (options, | ||
2047 | block_type, | ||
2048 | 0, | ||
2049 | ntohl (desired_replication_level), | ||
2050 | 1, | ||
2051 | &my_identity, | ||
2052 | expiration_time, | ||
2053 | key, | ||
2054 | data, | ||
2055 | data_size); | ||
2056 | return GNUNET_NO; | ||
2057 | } | ||
2058 | /* In case we are sending the request to a finger, then send across all of its | ||
2059 | trail.*/ | ||
2060 | GDS_NEIGHBOURS_send_put (key, | ||
2061 | block_type, | ||
2062 | options, | ||
2063 | desired_replication_level, | ||
2064 | best_known_dest, | ||
2065 | intermediate_trail_id, | ||
2066 | &next_hop, | ||
2067 | 0, | ||
2068 | 1, | ||
2069 | &my_identity, | ||
2070 | expiration_time, | ||
2071 | data, | ||
2072 | data_size); | ||
2073 | return GNUNET_OK; | ||
2074 | } | ||
2075 | |||
2076 | |||
2077 | /** | ||
2078 | * Construct a Get message and send it to target_peer. | ||
2079 | * | ||
2080 | * @param key Key for the content | ||
2081 | * @param block_type Type of the block | ||
2082 | * @param options Routing options | ||
2083 | * @param desired_replication_level Desired replication count | ||
2084 | * @param best_known_dest Peer which should get this message. Same as target peer | ||
2085 | * if best_known_dest is a friend else its a finger. | ||
2086 | * @param intermediate_trail_id Trail id to reach to @a best_known_dest | ||
2087 | * in case it is a finger else set to 0. | ||
2088 | * @param target_peer Peer to which this message will be forwarded. | ||
2089 | * @param hop_count Number of hops traversed so far. | ||
2090 | * @param data Content to store | ||
2091 | * @param data_size Size of content @a data in bytes | ||
2092 | * @param get_path_length Total number of peers in @a get_path | ||
2093 | * @param get_path Number of peers traversed so far | ||
2094 | */ | ||
2095 | void | ||
2096 | GDS_NEIGHBOURS_send_get (const struct GNUNET_HashCode *key, | ||
2097 | enum GNUNET_BLOCK_Type block_type, | ||
2098 | enum GNUNET_DHT_RouteOption options, | ||
2099 | uint32_t desired_replication_level, | ||
2100 | const struct GNUNET_PeerIdentity *best_known_dest, | ||
2101 | const struct GNUNET_HashCode *intermediate_trail_id, | ||
2102 | const struct GNUNET_PeerIdentity *target_peer, | ||
2103 | uint32_t hop_count, | ||
2104 | uint32_t get_path_length, | ||
2105 | const struct GNUNET_PeerIdentity *get_path) | ||
2106 | { | ||
2107 | struct PeerGetMessage *pgm; | ||
2108 | struct GNUNET_MQ_Envelope *env; | ||
2109 | struct FriendInfo *target_friend; | ||
2110 | size_t msize; | ||
2111 | |||
2112 | msize = get_path_length * sizeof (struct GNUNET_PeerIdentity); | ||
2113 | if (msize + sizeof (struct PeerGetMessage) | ||
2114 | >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE) | ||
2115 | { | ||
2116 | GNUNET_break (0); | ||
2117 | return; | ||
2118 | } | ||
2119 | GNUNET_assert (NULL != | ||
2120 | (target_friend = | ||
2121 | GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
2122 | target_peer))); | ||
2123 | env = GNUNET_MQ_msg_extra (pgm, | ||
2124 | msize, | ||
2125 | GNUNET_MESSAGE_TYPE_XDHT_P2P_GET); | ||
2126 | pgm->get_path_length = htonl (get_path_length); | ||
2127 | pgm->best_known_destination = *best_known_dest; | ||
2128 | pgm->key = *key; | ||
2129 | pgm->intermediate_trail_id = *intermediate_trail_id; | ||
2130 | pgm->hop_count = htonl (hop_count + 1); | ||
2131 | pgm->get_path_length = htonl (get_path_length); | ||
2132 | GNUNET_memcpy (&pgm[1], | ||
2133 | get_path, | ||
2134 | msize); | ||
2135 | GNUNET_MQ_send (target_friend->mq, | ||
2136 | env); | ||
2137 | } | ||
2138 | |||
2139 | |||
2140 | /** | ||
2141 | * Send the get result to requesting client. | ||
2142 | * | ||
2143 | * @param key Key of the requested data. | ||
2144 | * @param block_type Block type | ||
2145 | * @param target_peer Next peer to forward the message to. | ||
2146 | * @param source_peer Peer which has the data for the key. | ||
2147 | * @param put_path_length Number of peers in @a put_path | ||
2148 | * @param put_path Path taken to put the data at its stored location. | ||
2149 | * @param get_path_length Number of peers in @a get_path | ||
2150 | * @param get_path Path taken to reach to the location of the key. | ||
2151 | * @param expiration When will this result expire? | ||
2152 | * @param data Payload to store | ||
2153 | * @param data_size Size of the @a data | ||
2154 | */ | ||
2155 | void | ||
2156 | GDS_NEIGHBOURS_send_get_result (const struct GNUNET_HashCode *key, | ||
2157 | enum GNUNET_BLOCK_Type block_type, | ||
2158 | const struct GNUNET_PeerIdentity *target_peer, | ||
2159 | const struct GNUNET_PeerIdentity *source_peer, | ||
2160 | unsigned int put_path_length, | ||
2161 | const struct GNUNET_PeerIdentity *put_path, | ||
2162 | unsigned int get_path_length, | ||
2163 | const struct GNUNET_PeerIdentity *get_path, | ||
2164 | struct GNUNET_TIME_Absolute expiration, | ||
2165 | const void *data, size_t data_size) | ||
2166 | { | ||
2167 | struct PeerGetResultMessage *get_result; | ||
2168 | struct GNUNET_PeerIdentity *paths; | ||
2169 | struct GNUNET_MQ_Envelope *env; | ||
2170 | struct FriendInfo *target_friend; | ||
2171 | int current_path_index; | ||
2172 | size_t msize; | ||
2173 | |||
2174 | msize = (put_path_length + get_path_length) * sizeof (struct GNUNET_PeerIdentity) + | ||
2175 | data_size; | ||
2176 | if (msize + sizeof (struct PeerGetResultMessage) | ||
2177 | >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE) | ||
2178 | { | ||
2179 | put_path_length = 0; | ||
2180 | msize = data_size; | ||
2181 | } | ||
2182 | if (msize + sizeof (struct PeerGetResultMessage) | ||
2183 | >= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE) | ||
2184 | { | ||
2185 | GNUNET_break(0); | ||
2186 | return; | ||
2187 | } | ||
2188 | current_path_index = 0; | ||
2189 | if (get_path_length > 0) | ||
2190 | { | ||
2191 | current_path_index = search_my_index (get_path, | ||
2192 | get_path_length); | ||
2193 | if (-1 == current_path_index) | ||
2194 | { | ||
2195 | GNUNET_break (0); | ||
2196 | return; | ||
2197 | } | ||
2198 | if ((get_path_length + 1) == current_path_index) | ||
2199 | { | ||
2200 | DEBUG ("Peer found twice in get path. Not allowed \n"); | ||
2201 | GNUNET_break (0); | ||
2202 | return; | ||
2203 | } | ||
2204 | } | ||
2205 | if (0 == current_path_index) | ||
2206 | { | ||
2207 | DEBUG ("GET_RESULT TO CLIENT KEY = %s, Peer = %s", | ||
2208 | GNUNET_h2s (key), | ||
2209 | GNUNET_i2s (&my_identity)); | ||
2210 | GDS_CLIENTS_handle_reply (expiration, | ||
2211 | key, | ||
2212 | get_path_length, | ||
2213 | get_path, | ||
2214 | put_path_length, | ||
2215 | put_path, | ||
2216 | block_type, | ||
2217 | data_size, | ||
2218 | data); | ||
2219 | return; | ||
2220 | } | ||
2221 | env = GNUNET_MQ_msg_extra (get_result, | ||
2222 | msize, | ||
2223 | GNUNET_MESSAGE_TYPE_XDHT_P2P_GET_RESULT); | ||
2224 | get_result->key = *key; | ||
2225 | get_result->querying_peer = *source_peer; | ||
2226 | get_result->expiration_time = GNUNET_TIME_absolute_hton (expiration); | ||
2227 | get_result->get_path_length = htonl (get_path_length); | ||
2228 | get_result->put_path_length = htonl (put_path_length); | ||
2229 | paths = (struct GNUNET_PeerIdentity *)&get_result[1]; | ||
2230 | GNUNET_memcpy (paths, | ||
2231 | put_path, | ||
2232 | put_path_length * sizeof (struct GNUNET_PeerIdentity)); | ||
2233 | GNUNET_memcpy (&paths[put_path_length], | ||
2234 | get_path, | ||
2235 | get_path_length * sizeof (struct GNUNET_PeerIdentity)); | ||
2236 | GNUNET_memcpy (&paths[put_path_length + get_path_length], | ||
2237 | data, | ||
2238 | data_size); | ||
2239 | |||
2240 | GNUNET_assert (NULL != | ||
2241 | (target_friend = | ||
2242 | GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
2243 | &get_path[current_path_index - 1]))); | ||
2244 | GNUNET_MQ_send (target_friend->mq, | ||
2245 | env); | ||
2246 | } | ||
2247 | |||
2248 | |||
2249 | /** | ||
2250 | * Handle a result for a GET operation. | ||
2251 | * | ||
2252 | * @param cls closure | ||
2253 | * @param type type of the block | ||
2254 | * @param expiration_time when does the content expire | ||
2255 | * @param key key for the content | ||
2256 | * @param put_path_length number of entries in @a put_path | ||
2257 | * @param put_path peers the original PUT traversed (if tracked) | ||
2258 | * @param get_path_length number of entries in @a get_path | ||
2259 | * @param get_path peers this reply has traversed so far (if tracked) | ||
2260 | * @param data payload of the reply | ||
2261 | * @param data_size number of bytes in @a data | ||
2262 | */ | ||
2263 | static void | ||
2264 | get_cb (void *cls, | ||
2265 | enum GNUNET_BLOCK_Type type, | ||
2266 | struct GNUNET_TIME_Absolute expiration_time, | ||
2267 | const struct GNUNET_HashCode *key, | ||
2268 | unsigned int put_path_length, | ||
2269 | const struct GNUNET_PeerIdentity *put_path, | ||
2270 | unsigned int get_path_length, | ||
2271 | const struct GNUNET_PeerIdentity *get_path, | ||
2272 | const void *data, | ||
2273 | size_t data_size) | ||
2274 | { | ||
2275 | struct GNUNET_PeerIdentity *target_peer = cls; | ||
2276 | // FIXME: inline? | ||
2277 | GDS_NEIGHBOURS_send_get_result (key, | ||
2278 | type, | ||
2279 | target_peer, | ||
2280 | &my_identity, | ||
2281 | put_path_length, | ||
2282 | put_path, | ||
2283 | 1, | ||
2284 | &my_identity, | ||
2285 | expiration_time, | ||
2286 | data, | ||
2287 | data_size); | ||
2288 | } | ||
2289 | |||
2290 | |||
2291 | /** | ||
2292 | * Perform a GET operation. Forwards the given request to other | ||
2293 | * peers. Does not lookup the key locally. May do nothing if this is | ||
2294 | * the only peer in the network (or if we are the closest peer in the | ||
2295 | * network). | ||
2296 | * | ||
2297 | * @param block_type type of the block | ||
2298 | * @param options routing options | ||
2299 | * @param desired_replication_level desired replication count | ||
2300 | * @param hop_count how many hops did this request traverse so far? | ||
2301 | * @param key key for the content | ||
2302 | * @param xquery extended query | ||
2303 | * @param xquery_size number of bytes in @a xquery | ||
2304 | * @param reply_bf bloomfilter to filter duplicates | ||
2305 | * @param reply_bf_mutator mutator for @a reply_bf | ||
2306 | * @param peer_bf filter for peers not to select (again, updated) | ||
2307 | * @return #GNUNET_OK if the request was forwarded, #GNUNET_NO if not | ||
2308 | */ | ||
2309 | int | ||
2310 | GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type block_type, | ||
2311 | enum GNUNET_DHT_RouteOption options, | ||
2312 | uint32_t desired_replication_level, | ||
2313 | uint32_t hop_count, | ||
2314 | const struct GNUNET_HashCode *key, | ||
2315 | const void *xquery, size_t xquery_size, | ||
2316 | const struct GNUNET_CONTAINER_BloomFilter *reply_bf, | ||
2317 | uint32_t reply_bf_mutator, | ||
2318 | struct GNUNET_CONTAINER_BloomFilter *peer_bf) | ||
2319 | { | ||
2320 | struct Closest_Peer successor; | ||
2321 | struct GNUNET_PeerIdentity best_known_dest; | ||
2322 | struct GNUNET_HashCode intermediate_trail_id; | ||
2323 | uint64_t key_value; | ||
2324 | |||
2325 | GNUNET_memcpy (&key_value, | ||
2326 | key, | ||
2327 | sizeof (uint64_t)); | ||
2328 | key_value = GNUNET_ntohll (key_value); | ||
2329 | successor = find_local_best_known_next_hop (key_value, | ||
2330 | GDS_FINGER_TYPE_NON_PREDECESSOR); | ||
2331 | best_known_dest = successor.best_known_destination; | ||
2332 | intermediate_trail_id = successor.trail_id; | ||
2333 | |||
2334 | /* I am the destination. I have the data. */ | ||
2335 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, | ||
2336 | &best_known_dest)) | ||
2337 | { | ||
2338 | GDS_DATACACHE_handle_get (key, | ||
2339 | block_type, | ||
2340 | NULL, | ||
2341 | 0, | ||
2342 | NULL, | ||
2343 | 0, | ||
2344 | &get_cb, | ||
2345 | NULL); | ||
2346 | return GNUNET_NO; | ||
2347 | } | ||
2348 | |||
2349 | GDS_NEIGHBOURS_send_get (key, | ||
2350 | block_type, | ||
2351 | options, | ||
2352 | desired_replication_level, | ||
2353 | &best_known_dest, | ||
2354 | &intermediate_trail_id, | ||
2355 | &successor.next_hop, | ||
2356 | 0, | ||
2357 | 1, | ||
2358 | &my_identity); | ||
2359 | return GNUNET_OK; | ||
2360 | } | ||
2361 | |||
2362 | |||
2363 | /** | ||
2364 | * Randomly choose one of your friends (which is not congested and have not crossed | ||
2365 | * trail threshold) from the friend_peermap | ||
2366 | * @return Friend Randomly chosen friend. | ||
2367 | * NULL in case friend peermap is empty, or all the friends are either | ||
2368 | * congested or have crossed trail threshold. | ||
2369 | */ | ||
2370 | static struct FriendInfo * | ||
2371 | select_random_friend () | ||
2372 | { | ||
2373 | unsigned int current_size; | ||
2374 | uint32_t index; | ||
2375 | unsigned int j = 0; | ||
2376 | struct GNUNET_CONTAINER_MultiPeerMapIterator *iter; | ||
2377 | struct GNUNET_PeerIdentity key_ret; | ||
2378 | struct FriendInfo *friend; | ||
2379 | |||
2380 | current_size = GNUNET_CONTAINER_multipeermap_size (friend_peermap); | ||
2381 | |||
2382 | /* No friends.*/ | ||
2383 | if (0 == current_size) | ||
2384 | return NULL; | ||
2385 | |||
2386 | index = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, current_size); | ||
2387 | iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap); | ||
2388 | |||
2389 | /* Iterate till you don't reach to index. */ | ||
2390 | for (j = 0; j < index ; j++) | ||
2391 | GNUNET_assert (GNUNET_YES == | ||
2392 | GNUNET_CONTAINER_multipeermap_iterator_next (iter, NULL, NULL)); | ||
2393 | |||
2394 | do | ||
2395 | { | ||
2396 | /* Reset the index in friend peermap to 0 as we reached to the end. */ | ||
2397 | if (j == current_size) | ||
2398 | { | ||
2399 | j = 0; | ||
2400 | GNUNET_CONTAINER_multipeermap_iterator_destroy (iter); | ||
2401 | iter = GNUNET_CONTAINER_multipeermap_iterator_create (friend_peermap); | ||
2402 | |||
2403 | } | ||
2404 | |||
2405 | /* Get the friend stored at the index, j*/ | ||
2406 | GNUNET_assert (GNUNET_YES == | ||
2407 | GNUNET_CONTAINER_multipeermap_iterator_next (iter, | ||
2408 | &key_ret, | ||
2409 | (const void **)&friend)); | ||
2410 | |||
2411 | /* This friend is not congested and has not crossed trail threshold. */ | ||
2412 | if ((friend->trails_count < TRAILS_THROUGH_FRIEND_THRESHOLD) && | ||
2413 | (0 == GNUNET_TIME_absolute_get_remaining (friend->congestion_timestamp).rel_value_us)) | ||
2414 | { | ||
2415 | break; | ||
2416 | } | ||
2417 | friend = NULL; | ||
2418 | j++; | ||
2419 | } while (j != index); | ||
2420 | |||
2421 | GNUNET_CONTAINER_multipeermap_iterator_destroy (iter); | ||
2422 | return friend; | ||
2423 | } | ||
2424 | |||
2425 | |||
2426 | /** | ||
2427 | * Compute 64 bit value of finger_identity corresponding to a finger index using | ||
2428 | * Chord formula. | ||
2429 | * For all fingers, n.finger[i] = n + pow (2,i), | ||
2430 | * For predecessor, n.finger[PREDECESSOR_FINGER_ID] = n - 1, where | ||
2431 | * n = my_identity, i = finger_index, n.finger[i] = 64 bit finger value | ||
2432 | * | ||
2433 | * @param finger_index Index corresponding to which we calculate 64 bit value. | ||
2434 | * @return 64 bit value. | ||
2435 | */ | ||
2436 | static uint64_t | ||
2437 | compute_finger_identity_value (unsigned int finger_index) | ||
2438 | { | ||
2439 | uint64_t my_id64; | ||
2440 | |||
2441 | GNUNET_memcpy (&my_id64, | ||
2442 | &my_identity, | ||
2443 | sizeof (uint64_t)); | ||
2444 | my_id64 = GNUNET_ntohll (my_id64); | ||
2445 | |||
2446 | /* Are we looking for immediate predecessor? */ | ||
2447 | if (PREDECESSOR_FINGER_ID == finger_index) | ||
2448 | return (my_id64 - 1); | ||
2449 | uint64_t add = (uint64_t)1 << finger_index; | ||
2450 | return (my_id64 + add); | ||
2451 | } | ||
2452 | |||
2453 | |||
2454 | /** | ||
2455 | * Choose a random friend. Calculate the next finger identity to search,from | ||
2456 | * current_search_finger_index. Start looking for the trail to reach to | ||
2457 | * finger identity through this random friend. | ||
2458 | * | ||
2459 | * @param cls closure for this task | ||
2460 | */ | ||
2461 | static void | ||
2462 | send_find_finger_trail_message (void *cls) | ||
2463 | { | ||
2464 | struct FriendInfo *target_friend; | ||
2465 | struct GNUNET_HashCode trail_id; | ||
2466 | struct GNUNET_HashCode intermediate_trail_id; | ||
2467 | unsigned int is_predecessor = 0; | ||
2468 | uint64_t finger_id_value; | ||
2469 | |||
2470 | /* Schedule another send_find_finger_trail_message task. After one round of | ||
2471 | * finger search, this time is exponentially backoff. */ | ||
2472 | find_finger_trail_task_next_send_time.rel_value_us = | ||
2473 | find_finger_trail_task_next_send_time.rel_value_us + | ||
2474 | GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, | ||
2475 | DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us); | ||
2476 | find_finger_trail_task = | ||
2477 | GNUNET_SCHEDULER_add_delayed (find_finger_trail_task_next_send_time, | ||
2478 | &send_find_finger_trail_message, | ||
2479 | NULL); | ||
2480 | |||
2481 | /* No space in my routing table. (Source and destination peers also store entries | ||
2482 | * in their routing table). */ | ||
2483 | if (GNUNET_YES == GDS_ROUTING_threshold_reached()) | ||
2484 | return; | ||
2485 | |||
2486 | target_friend = select_random_friend (); | ||
2487 | if (NULL == target_friend) | ||
2488 | return; | ||
2489 | |||
2490 | finger_id_value = compute_finger_identity_value (current_search_finger_index); | ||
2491 | if (PREDECESSOR_FINGER_ID == current_search_finger_index) | ||
2492 | is_predecessor = 1; | ||
2493 | |||
2494 | /* Generate a unique trail id for trail we are trying to setup. */ | ||
2495 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG, | ||
2496 | &trail_id, | ||
2497 | sizeof (trail_id)); | ||
2498 | memset (&intermediate_trail_id, | ||
2499 | 0, | ||
2500 | sizeof (struct GNUNET_HashCode)); | ||
2501 | GDS_NEIGHBOURS_send_trail_setup (&my_identity, | ||
2502 | finger_id_value, | ||
2503 | target_friend->id, | ||
2504 | target_friend, | ||
2505 | 0, NULL, | ||
2506 | is_predecessor, | ||
2507 | &trail_id, | ||
2508 | &intermediate_trail_id); | ||
2509 | } | ||
2510 | |||
2511 | |||
2512 | /** | ||
2513 | * In case there are already maximum number of possible trails to reach to a | ||
2514 | * finger, then check if the new trail's length is lesser than any of the | ||
2515 | * existing trails. | ||
2516 | * If yes then replace that old trail by new trail. | ||
2517 | * | ||
2518 | * Note: Here we are taking length as a parameter to choose the best possible | ||
2519 | * trail, but there could be other parameters also like: | ||
2520 | * 1. duration of existence of a trail - older the better. | ||
2521 | * 2. if the new trail is completely disjoint than the | ||
2522 | * other trails, then may be choosing it is better. | ||
2523 | * | ||
2524 | * @param finger Finger | ||
2525 | * @param new_finger_trail List of peers to reach from me to @a finger, NOT | ||
2526 | * including the endpoints. | ||
2527 | * @param new_finger_trail_length Total number of peers in @a new_finger_trail | ||
2528 | * @param new_finger_trail_id Unique identifier of @a new_finger_trail. | ||
2529 | */ | ||
2530 | static void | ||
2531 | select_and_replace_trail (struct FingerInfo *finger, | ||
2532 | const struct GNUNET_PeerIdentity *new_trail, | ||
2533 | unsigned int new_trail_length, | ||
2534 | const struct GNUNET_HashCode *new_trail_id) | ||
2535 | { | ||
2536 | struct Trail *current_trail; | ||
2537 | unsigned int largest_trail_length; | ||
2538 | unsigned int largest_trail_index; | ||
2539 | struct Trail_Element *trail_element; | ||
2540 | const struct GNUNET_PeerIdentity *next_hop; | ||
2541 | unsigned int i; | ||
2542 | |||
2543 | largest_trail_length = new_trail_length; | ||
2544 | largest_trail_index = MAXIMUM_TRAILS_PER_FINGER + 1; | ||
2545 | |||
2546 | GNUNET_assert (MAXIMUM_TRAILS_PER_FINGER == finger->trails_count); | ||
2547 | |||
2548 | for (i = 0; i < finger->trails_count; i++) | ||
2549 | { | ||
2550 | current_trail = &finger->trail_list[i]; | ||
2551 | GNUNET_assert (GNUNET_YES == current_trail->is_present); | ||
2552 | if (current_trail->trail_length > largest_trail_length) | ||
2553 | { | ||
2554 | largest_trail_length = current_trail->trail_length; | ||
2555 | largest_trail_index = i; | ||
2556 | } | ||
2557 | } | ||
2558 | |||
2559 | /* New trail is not better than existing ones. Send trail teardown. */ | ||
2560 | if (largest_trail_index == (MAXIMUM_TRAILS_PER_FINGER + 1)) | ||
2561 | { | ||
2562 | next_hop = GDS_ROUTING_get_next_hop (new_trail_id, | ||
2563 | GDS_ROUTING_SRC_TO_DEST); | ||
2564 | GDS_ROUTING_remove_trail (new_trail_id); | ||
2565 | GDS_NEIGHBOURS_send_trail_teardown (new_trail_id, | ||
2566 | GDS_ROUTING_SRC_TO_DEST, | ||
2567 | next_hop); | ||
2568 | return; | ||
2569 | } | ||
2570 | |||
2571 | /* Send trail teardown message across the replaced trail. */ | ||
2572 | struct Trail *replace_trail = &finger->trail_list[largest_trail_index]; | ||
2573 | next_hop = GDS_ROUTING_get_next_hop (&replace_trail->trail_id, | ||
2574 | GDS_ROUTING_SRC_TO_DEST); | ||
2575 | GNUNET_assert (GNUNET_YES == GDS_ROUTING_remove_trail (&replace_trail->trail_id)); | ||
2576 | GDS_NEIGHBOURS_send_trail_teardown (&replace_trail->trail_id, | ||
2577 | GDS_ROUTING_SRC_TO_DEST, | ||
2578 | next_hop); | ||
2579 | |||
2580 | /* Free the trail. */ | ||
2581 | while (NULL != (trail_element = replace_trail->trail_head)) | ||
2582 | { | ||
2583 | GNUNET_CONTAINER_DLL_remove (replace_trail->trail_head, | ||
2584 | replace_trail->trail_tail, | ||
2585 | trail_element); | ||
2586 | GNUNET_free_non_null (trail_element); | ||
2587 | } | ||
2588 | |||
2589 | /* Add new trial at that location. */ | ||
2590 | replace_trail->is_present = GNUNET_YES; | ||
2591 | replace_trail->trail_length = new_trail_length; | ||
2592 | replace_trail->trail_id = *new_trail_id; | ||
2593 | |||
2594 | for (i = 0; i < new_trail_length; i++) | ||
2595 | { | ||
2596 | struct Trail_Element *element = GNUNET_new (struct Trail_Element); | ||
2597 | element->peer = new_trail[i]; | ||
2598 | |||
2599 | GNUNET_CONTAINER_DLL_insert_tail (replace_trail->trail_head, | ||
2600 | replace_trail->trail_tail, | ||
2601 | element); | ||
2602 | } | ||
2603 | /* FIXME: URGENT Are we adding the trail back to the list. */ | ||
2604 | } | ||
2605 | |||
2606 | |||
2607 | /** | ||
2608 | * Check if the new trail to reach to finger is unique or do we already have | ||
2609 | * such a trail present for finger. | ||
2610 | * @param existing_finger Finger identity | ||
2611 | * @param new_trail New trail to reach @a existing_finger | ||
2612 | * @param trail_length Total number of peers in new_trail. | ||
2613 | * @return #GNUNET_YES if the new trail is unique | ||
2614 | * #GNUNET_NO if same trail is already present. | ||
2615 | */ | ||
2616 | static int | ||
2617 | is_new_trail_unique (struct FingerInfo *existing_finger, | ||
2618 | const struct GNUNET_PeerIdentity *new_trail, | ||
2619 | unsigned int trail_length) | ||
2620 | { | ||
2621 | struct Trail *current_trail; | ||
2622 | struct Trail_Element *trail_element; | ||
2623 | int i; | ||
2624 | int j; | ||
2625 | |||
2626 | GNUNET_assert (existing_finger->trails_count > 0); | ||
2627 | |||
2628 | /* Iterate over list of trails. */ | ||
2629 | for (i = 0; i < existing_finger->trails_count; i++) | ||
2630 | { | ||
2631 | current_trail = &(existing_finger->trail_list[i]); | ||
2632 | if(GNUNET_NO == current_trail->is_present) | ||
2633 | continue; | ||
2634 | |||
2635 | /* New trail and existing trail length are not same. */ | ||
2636 | if (current_trail->trail_length != trail_length) | ||
2637 | { | ||
2638 | return GNUNET_YES; | ||
2639 | } | ||
2640 | |||
2641 | trail_element = current_trail->trail_head; | ||
2642 | for (j = 0; j < current_trail->trail_length; j++) | ||
2643 | { | ||
2644 | if (0 != GNUNET_CRYPTO_cmp_peer_identity (&new_trail[j], | ||
2645 | &trail_element->peer)) | ||
2646 | { | ||
2647 | return GNUNET_YES; | ||
2648 | } | ||
2649 | trail_element = trail_element->next; | ||
2650 | } | ||
2651 | } | ||
2652 | return GNUNET_NO; | ||
2653 | } | ||
2654 | |||
2655 | |||
2656 | /** | ||
2657 | * FIXME; In case of multiple trails, we may have a case where a trail from in | ||
2658 | * between has been removed, then we should try to find a free slot , not simply | ||
2659 | * add a trail at then end of the list. | ||
2660 | * Add a new trail at a free slot in trail array of existing finger. | ||
2661 | * @param existing_finger Finger | ||
2662 | * @param new_finger_trail New trail from me to finger, NOT including endpoints | ||
2663 | * @param new_finger_trail_length Total number of peers in @a new_finger_trail | ||
2664 | * @param new_finger_trail_id Unique identifier of the trail. | ||
2665 | */ | ||
2666 | static void | ||
2667 | add_new_trail (struct FingerInfo *existing_finger, | ||
2668 | const struct GNUNET_PeerIdentity *new_trail, | ||
2669 | unsigned int new_trail_length, | ||
2670 | const struct GNUNET_HashCode *new_trail_id) | ||
2671 | { | ||
2672 | struct FriendInfo *friend; | ||
2673 | struct Trail *trail; | ||
2674 | unsigned int i; | ||
2675 | int free_slot = -1; | ||
2676 | |||
2677 | if (GNUNET_NO == is_new_trail_unique (existing_finger, | ||
2678 | new_trail, | ||
2679 | new_trail_length)) | ||
2680 | return; | ||
2681 | |||
2682 | for (i = 0; i < existing_finger->trails_count; i++) | ||
2683 | { | ||
2684 | if (GNUNET_NO == existing_finger->trail_list[i].is_present) | ||
2685 | { | ||
2686 | free_slot = i; | ||
2687 | break; | ||
2688 | } | ||
2689 | } | ||
2690 | |||
2691 | if (-1 == free_slot) | ||
2692 | free_slot = i; | ||
2693 | |||
2694 | trail = &existing_finger->trail_list[free_slot]; | ||
2695 | GNUNET_assert (GNUNET_NO == trail->is_present); | ||
2696 | trail->trail_id = *new_trail_id; | ||
2697 | trail->trail_length = new_trail_length; | ||
2698 | existing_finger->trails_count++; | ||
2699 | trail->is_present = GNUNET_YES; | ||
2700 | if (0 == new_trail_length) | ||
2701 | { | ||
2702 | friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
2703 | &existing_finger->finger_identity); | ||
2704 | } | ||
2705 | else | ||
2706 | { | ||
2707 | friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
2708 | &new_trail[0]); | ||
2709 | } | ||
2710 | GNUNET_assert (NULL != friend); | ||
2711 | friend->trails_count++; | ||
2712 | for (i = 0; i < new_trail_length; i++) | ||
2713 | { | ||
2714 | struct Trail_Element *element; | ||
2715 | |||
2716 | element = GNUNET_new (struct Trail_Element); | ||
2717 | element->peer = new_trail[i]; | ||
2718 | GNUNET_CONTAINER_DLL_insert_tail (trail->trail_head, | ||
2719 | trail->trail_tail, | ||
2720 | element); | ||
2721 | } | ||
2722 | |||
2723 | existing_finger->trail_list[free_slot].trail_head = trail->trail_head; | ||
2724 | existing_finger->trail_list[free_slot].trail_tail = trail->trail_tail; | ||
2725 | existing_finger->trail_list[free_slot].trail_length = new_trail_length; | ||
2726 | existing_finger->trail_list[free_slot].trail_id = *new_trail_id; | ||
2727 | existing_finger->trail_list[free_slot].is_present = GNUNET_YES; | ||
2728 | } | ||
2729 | |||
2730 | |||
2731 | #if 0 | ||
2732 | /** | ||
2733 | * FIXME; In case of multiple trails, we may have a case where a trail from in | ||
2734 | * between has been removed, then we should try to find a free slot , not simply | ||
2735 | * add a trail at then end of the list. | ||
2736 | * Add a new trail at a free slot in trail array of existing finger. | ||
2737 | * @param existing_finger Finger | ||
2738 | * @param new_finger_trail New trail from me to finger, NOT including endpoints | ||
2739 | * @param new_finger_trail_length Total number of peers in @a new_finger_trail | ||
2740 | * @param new_finger_trail_id Unique identifier of the trail. | ||
2741 | */ | ||
2742 | static void | ||
2743 | add_new_trail (struct FingerInfo *existing_finger, | ||
2744 | const struct GNUNET_PeerIdentity *new_trail, | ||
2745 | unsigned int new_trail_length, | ||
2746 | const struct GNUNET_HashCode *new_trail_id) | ||
2747 | { | ||
2748 | struct Trail *trail; | ||
2749 | struct FriendInfo *first_friend; | ||
2750 | int i; | ||
2751 | int index; | ||
2752 | |||
2753 | if (GNUNET_NO == is_new_trail_unique (existing_finger, | ||
2754 | new_trail, | ||
2755 | new_trail_length)) | ||
2756 | return; | ||
2757 | |||
2758 | index = existing_finger->trails_count; | ||
2759 | trail = &existing_finger->trail_list[index]; | ||
2760 | GNUNET_assert (GNUNET_NO == trail->is_present); | ||
2761 | trail->trail_id = *new_trail_id; | ||
2762 | trail->trail_length = new_trail_length; | ||
2763 | existing_finger->trails_count++; | ||
2764 | trail->is_present = GNUNET_YES; | ||
2765 | |||
2766 | GNUNET_assert (NULL == (GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
2767 | &existing_finger->finger_identity))); | ||
2768 | /* If finger is a friend then we never call this function. */ | ||
2769 | GNUNET_assert (new_trail_length > 0); | ||
2770 | |||
2771 | first_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
2772 | &new_trail[0]); | ||
2773 | first_friend->trails_count++; | ||
2774 | |||
2775 | for (i = 0; i < new_trail_length; i++) | ||
2776 | { | ||
2777 | struct Trail_Element *element; | ||
2778 | |||
2779 | element = GNUNET_new (struct Trail_Element); | ||
2780 | element->peer = new_trail[i]; | ||
2781 | GNUNET_CONTAINER_DLL_insert_tail (trail->trail_head, | ||
2782 | trail->trail_tail, | ||
2783 | element); | ||
2784 | } | ||
2785 | /* Do we need to add trail head and trail tail in the trail list itearator.*/ | ||
2786 | existing_finger->trail_list[index].trail_head = trail->trail_head; | ||
2787 | existing_finger->trail_list[index].trail_tail = trail->trail_tail; | ||
2788 | existing_finger->trail_list[index].trail_length = new_trail_length; | ||
2789 | existing_finger->trail_list[index].trail_id = *new_trail_id; | ||
2790 | existing_finger->trail_list[index].is_present = GNUNET_YES; | ||
2791 | } | ||
2792 | #endif | ||
2793 | |||
2794 | /** | ||
2795 | * Get the next hop to send trail teardown message from routing table and | ||
2796 | * then delete the entry from routing table. Send trail teardown message for a | ||
2797 | * specific trail of a finger. | ||
2798 | * @param finger Finger whose trail is to be removed. | ||
2799 | * @param trail List of peers in trail from me to a finger, NOT including | ||
2800 | * endpoints. | ||
2801 | */ | ||
2802 | static void | ||
2803 | send_trail_teardown (struct FingerInfo *finger, | ||
2804 | struct Trail *trail) | ||
2805 | { | ||
2806 | struct FriendInfo *friend; | ||
2807 | const struct GNUNET_PeerIdentity *next_hop; | ||
2808 | |||
2809 | next_hop = GDS_ROUTING_get_next_hop (&trail->trail_id, | ||
2810 | GDS_ROUTING_SRC_TO_DEST); | ||
2811 | if (NULL == next_hop) | ||
2812 | { | ||
2813 | // DEBUG(" NO ENTRY FOUND IN %s ROUTING TABLE for trail id %s, line=%d,traillength = %d", | ||
2814 | // GNUNET_i2s(&my_identity), GNUNET_h2s(&trail->trail_id), __LINE__,trail->trail_length); | ||
2815 | return; | ||
2816 | } | ||
2817 | GNUNET_assert (0 != GNUNET_CRYPTO_cmp_peer_identity (&finger->finger_identity, | ||
2818 | &my_identity)); | ||
2819 | |||
2820 | GNUNET_assert(GNUNET_YES == trail->is_present); | ||
2821 | if (trail->trail_length > 0) | ||
2822 | { | ||
2823 | friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
2824 | &trail->trail_head->peer); | ||
2825 | } | ||
2826 | else | ||
2827 | { | ||
2828 | friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
2829 | &finger->finger_identity); | ||
2830 | } | ||
2831 | |||
2832 | if(NULL == friend) | ||
2833 | { | ||
2834 | DEBUG ("\n LINE NO: = %d, Friend not found for trail id %s of peer %s trail length = %d", | ||
2835 | __LINE__, | ||
2836 | GNUNET_h2s (&trail->trail_id), | ||
2837 | GNUNET_i2s(&my_identity), | ||
2838 | trail->trail_length); | ||
2839 | return; | ||
2840 | } | ||
2841 | if ( (0 != GNUNET_CRYPTO_cmp_peer_identity (next_hop, | ||
2842 | friend->id) ) && | ||
2843 | (0 == trail->trail_length)) | ||
2844 | { | ||
2845 | DEBUG ("\n LINE NO: = %d, Friend not found for trail id %s of peer %s trail length = %d", | ||
2846 | __LINE__, | ||
2847 | GNUNET_h2s (&trail->trail_id), | ||
2848 | GNUNET_i2s (&my_identity), | ||
2849 | trail->trail_length); | ||
2850 | return; | ||
2851 | } | ||
2852 | GNUNET_assert (GNUNET_YES == | ||
2853 | GDS_ROUTING_remove_trail (&trail->trail_id)); | ||
2854 | friend->trails_count--; | ||
2855 | GDS_NEIGHBOURS_send_trail_teardown (&trail->trail_id, | ||
2856 | GDS_ROUTING_SRC_TO_DEST, | ||
2857 | friend->id); | ||
2858 | } | ||
2859 | |||
2860 | |||
2861 | /** | ||
2862 | * Send trail teardown message across all the trails to reach to finger. | ||
2863 | * @param finger Finger whose all the trail should be freed. | ||
2864 | */ | ||
2865 | static void | ||
2866 | send_all_finger_trails_teardown (struct FingerInfo *finger) | ||
2867 | { | ||
2868 | for (unsigned int i = 0; i < finger->trails_count; i++) | ||
2869 | { | ||
2870 | struct Trail *trail; | ||
2871 | |||
2872 | trail = &finger->trail_list[i]; | ||
2873 | if (GNUNET_YES == trail->is_present) | ||
2874 | { | ||
2875 | send_trail_teardown (finger, trail); | ||
2876 | trail->is_present = GNUNET_NO; | ||
2877 | } | ||
2878 | } | ||
2879 | } | ||
2880 | |||
2881 | |||
2882 | /** | ||
2883 | * Free a specific trail | ||
2884 | * @param trail List of peers to be freed. | ||
2885 | */ | ||
2886 | static void | ||
2887 | free_trail (struct Trail *trail) | ||
2888 | { | ||
2889 | struct Trail_Element *trail_element; | ||
2890 | |||
2891 | while (NULL != (trail_element = trail->trail_head)) | ||
2892 | { | ||
2893 | GNUNET_CONTAINER_DLL_remove (trail->trail_head, | ||
2894 | trail->trail_tail, | ||
2895 | trail_element); | ||
2896 | GNUNET_free_non_null (trail_element); | ||
2897 | } | ||
2898 | trail->trail_head = NULL; | ||
2899 | trail->trail_tail = NULL; | ||
2900 | } | ||
2901 | |||
2902 | |||
2903 | /** | ||
2904 | * Free finger and its trail. | ||
2905 | * | ||
2906 | * @param finger Finger to be freed. | ||
2907 | * @param finger_table_index Index at which finger is stored. | ||
2908 | */ | ||
2909 | static void | ||
2910 | free_finger (struct FingerInfo *finger, | ||
2911 | unsigned int finger_table_index) | ||
2912 | { | ||
2913 | struct Trail *trail; | ||
2914 | |||
2915 | for (unsigned int i = 0; i < finger->trails_count; i++) | ||
2916 | { | ||
2917 | trail = &finger->trail_list[i]; | ||
2918 | if (GNUNET_NO == trail->is_present) | ||
2919 | continue; | ||
2920 | |||
2921 | if (trail->trail_length > 0) | ||
2922 | free_trail (trail); | ||
2923 | trail->is_present = GNUNET_NO; | ||
2924 | } | ||
2925 | |||
2926 | finger->is_present = GNUNET_NO; | ||
2927 | memset (&finger_table[finger_table_index], | ||
2928 | 0, | ||
2929 | sizeof (finger_table[finger_table_index])); | ||
2930 | } | ||
2931 | |||
2932 | |||
2933 | /** | ||
2934 | * Add a new entry in finger table at finger_table_index. | ||
2935 | * In case I am my own finger, then we don't have a trail. In case of a friend, | ||
2936 | * we have a trail with unique id and '0' trail length. | ||
2937 | * In case a finger is a friend, then increment the trails count of the friend. | ||
2938 | * | ||
2939 | * @param finger_identity Peer Identity of new finger | ||
2940 | * @param finger_trail Trail to reach from me to finger (excluding both end points). | ||
2941 | * @param finger_trail_length Total number of peers in @a finger_trail. | ||
2942 | * @param trail_id Unique identifier of the trail. | ||
2943 | * @param finger_table_index Index in finger table. | ||
2944 | */ | ||
2945 | static void | ||
2946 | add_new_finger (const struct GNUNET_PeerIdentity *finger_identity, | ||
2947 | const struct GNUNET_PeerIdentity *finger_trail, | ||
2948 | unsigned int finger_trail_length, | ||
2949 | const struct GNUNET_HashCode *trail_id, | ||
2950 | unsigned int finger_table_index) | ||
2951 | { | ||
2952 | struct FingerInfo *new_entry; | ||
2953 | struct FriendInfo *first_trail_hop; | ||
2954 | struct Trail *trail; | ||
2955 | unsigned int i; | ||
2956 | |||
2957 | new_entry = GNUNET_new (struct FingerInfo); | ||
2958 | new_entry->finger_identity = *finger_identity; | ||
2959 | new_entry->finger_table_index = finger_table_index; | ||
2960 | new_entry->is_present = GNUNET_YES; | ||
2961 | |||
2962 | /* If the new entry is my own identity. */ | ||
2963 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, | ||
2964 | finger_identity)) | ||
2965 | { | ||
2966 | new_entry->trails_count = 0; | ||
2967 | finger_table[finger_table_index] = *new_entry; | ||
2968 | GNUNET_free (new_entry); | ||
2969 | return; | ||
2970 | } | ||
2971 | |||
2972 | /* Finger is a friend. */ | ||
2973 | if (0 == finger_trail_length) | ||
2974 | { | ||
2975 | new_entry->trail_list[0].trail_id = *trail_id; | ||
2976 | new_entry->trails_count = 1; | ||
2977 | new_entry->trail_list[0].is_present = GNUNET_YES; | ||
2978 | new_entry->trail_list[0].trail_length = 0; | ||
2979 | new_entry->trail_list[0].trail_head = NULL; | ||
2980 | new_entry->trail_list[0].trail_tail = NULL; | ||
2981 | finger_table[finger_table_index] = *new_entry; | ||
2982 | GNUNET_assert (NULL != | ||
2983 | (first_trail_hop = | ||
2984 | GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
2985 | finger_identity))); | ||
2986 | |||
2987 | first_trail_hop->trails_count++; | ||
2988 | GNUNET_free (new_entry); | ||
2989 | return; | ||
2990 | } | ||
2991 | |||
2992 | GNUNET_assert (NULL != | ||
2993 | (first_trail_hop = | ||
2994 | GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
2995 | &finger_trail[0]))); | ||
2996 | new_entry->trails_count = 1; | ||
2997 | first_trail_hop->trails_count++; | ||
2998 | /* Copy the finger trail into trail. */ | ||
2999 | trail = &new_entry->trail_list[0]; | ||
3000 | for(i = 0; i < finger_trail_length; i++) | ||
3001 | { | ||
3002 | struct Trail_Element *element = GNUNET_new (struct Trail_Element); | ||
3003 | |||
3004 | element->next = NULL; | ||
3005 | element->prev = NULL; | ||
3006 | element->peer = finger_trail[i]; | ||
3007 | GNUNET_CONTAINER_DLL_insert_tail (trail->trail_head, | ||
3008 | trail->trail_tail, | ||
3009 | element); | ||
3010 | } | ||
3011 | |||
3012 | /* Add trail to trail list. */ | ||
3013 | trail->trail_length = finger_trail_length; | ||
3014 | trail->trail_id = *trail_id; | ||
3015 | trail->is_present = GNUNET_YES; | ||
3016 | finger_table[finger_table_index] = *new_entry; | ||
3017 | GNUNET_free (new_entry); | ||
3018 | } | ||
3019 | |||
3020 | |||
3021 | /** | ||
3022 | * Periodic task to verify current successor. There can be multiple trails to reach | ||
3023 | * to successor, choose the shortest one and send verify successor message | ||
3024 | * across that trail. | ||
3025 | * | ||
3026 | * @param cls closure for this task | ||
3027 | */ | ||
3028 | static void | ||
3029 | send_verify_successor_message (void *cls) | ||
3030 | { | ||
3031 | struct FriendInfo *target_friend; | ||
3032 | struct Trail *trail; | ||
3033 | struct Trail_Element *element; | ||
3034 | unsigned int trail_length; | ||
3035 | unsigned int i = 0; | ||
3036 | struct FingerInfo *successor; | ||
3037 | |||
3038 | successor = &finger_table[0]; | ||
3039 | |||
3040 | /* This task will be scheduled when the result for Verify Successor is received. */ | ||
3041 | send_verify_successor_task = NULL; | ||
3042 | |||
3043 | /* When verify successor is being called for first time *for current context* | ||
3044 | * cls will be NULL. If send_verify_successor_retry_task is not NO_TASK, we | ||
3045 | * must cancel the retry task scheduled for verify_successor of previous | ||
3046 | * context. | ||
3047 | */ | ||
3048 | if (NULL == cls) | ||
3049 | { | ||
3050 | /* FIXME: Here we are scheduling a new verify successor task, as we | ||
3051 | got a new successor. But a send verify successor task may be in progress. | ||
3052 | 1. We need to be sure that this is indeed a new successor. As this function | ||
3053 | is called even if we add a new trail to reach t old successor. | ||
3054 | 2. Assuming the new successor is different, then verify successor message | ||
3055 | * to old successor may be following stages. | ||
3056 | * --> Waiting for verify successor result. Don't wait anymore. there is | ||
3057 | * no trail to reach from old successor to me, hence, routing | ||
3058 | * lookup will fail. | ||
3059 | * --> Waiting for notify confirmation. again don't wait for it. notify | ||
3060 | * confirmation will not succeded. | ||
3061 | */ | ||
3062 | if (send_verify_successor_retry_task != NULL) | ||
3063 | { | ||
3064 | /* FIXME: Are we scheduling retry task as soon as we send verify message. | ||
3065 | If yes then here before making this task, first check if the message | ||
3066 | is for the same peer again. */ | ||
3067 | struct VerifySuccessorContext *old_ctx = | ||
3068 | GNUNET_SCHEDULER_cancel(send_verify_successor_retry_task); | ||
3069 | /* old_ctx must not be NULL, as the retry task had been scheduled */ | ||
3070 | GNUNET_assert(NULL != old_ctx); | ||
3071 | GNUNET_free(old_ctx); | ||
3072 | /* FIXME: Why don't we reset the task to NO_TASK here? */ | ||
3073 | } | ||
3074 | |||
3075 | struct VerifySuccessorContext *ctx; | ||
3076 | ctx = GNUNET_new (struct VerifySuccessorContext); | ||
3077 | |||
3078 | ctx->num_retries_scheduled++; | ||
3079 | send_verify_successor_retry_task = | ||
3080 | GNUNET_SCHEDULER_add_delayed (verify_successor_retry_time, | ||
3081 | &send_verify_successor_message, | ||
3082 | ctx); | ||
3083 | } | ||
3084 | else | ||
3085 | { | ||
3086 | /* This is a retry attempt for verify_successor for a previous context */ | ||
3087 | struct VerifySuccessorContext *ctx; | ||
3088 | |||
3089 | ctx = cls; | ||
3090 | ctx->num_retries_scheduled++; | ||
3091 | send_verify_successor_retry_task = | ||
3092 | GNUNET_SCHEDULER_add_delayed (verify_successor_retry_time, | ||
3093 | &send_verify_successor_message, | ||
3094 | ctx); | ||
3095 | } | ||
3096 | |||
3097 | /* Among all the trails to reach to successor, select first one which is present.*/ | ||
3098 | for (i = 0; i < successor->trails_count; i++) | ||
3099 | { | ||
3100 | trail = &successor->trail_list[i]; | ||
3101 | if (GNUNET_YES == trail->is_present) | ||
3102 | break; | ||
3103 | } | ||
3104 | |||
3105 | /* No valid trail found to reach to successor. */ | ||
3106 | if (i == successor->trails_count) | ||
3107 | return; | ||
3108 | |||
3109 | GNUNET_assert(0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity, | ||
3110 | &successor->finger_identity)); | ||
3111 | /* Trail stored at this index. */ | ||
3112 | GNUNET_assert (GNUNET_YES == trail->is_present); | ||
3113 | if (NULL == GDS_ROUTING_get_next_hop (&trail->trail_id, | ||
3114 | GDS_ROUTING_SRC_TO_DEST)) | ||
3115 | { | ||
3116 | DEBUG (" NO ENTRY FOUND IN %s ROUTING TABLE for trail id %s, line %u", | ||
3117 | GNUNET_i2s (&my_identity), | ||
3118 | GNUNET_h2s (&trail->trail_id), | ||
3119 | __LINE__); | ||
3120 | GNUNET_break(0); | ||
3121 | return; | ||
3122 | } | ||
3123 | trail_length = trail->trail_length; | ||
3124 | if (trail_length > 0) | ||
3125 | { | ||
3126 | /* Copy the trail into peer list. */ | ||
3127 | struct GNUNET_PeerIdentity peer_list[trail_length]; | ||
3128 | |||
3129 | element = trail->trail_head; | ||
3130 | for(i = 0; i < trail_length; i++) | ||
3131 | { | ||
3132 | peer_list[i] = element->peer; | ||
3133 | element = element->next; | ||
3134 | } | ||
3135 | GNUNET_assert (NULL != (target_friend = | ||
3136 | GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
3137 | &peer_list[0]))); | ||
3138 | GDS_NEIGHBOURS_send_verify_successor_message (&my_identity, | ||
3139 | &successor->finger_identity, | ||
3140 | &trail->trail_id, | ||
3141 | peer_list, | ||
3142 | trail_length, | ||
3143 | target_friend); | ||
3144 | } | ||
3145 | else | ||
3146 | { | ||
3147 | GNUNET_assert (NULL != (target_friend = | ||
3148 | GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
3149 | &successor->finger_identity))); | ||
3150 | GDS_NEIGHBOURS_send_verify_successor_message (&my_identity, | ||
3151 | &successor->finger_identity, | ||
3152 | &trail->trail_id, | ||
3153 | NULL, | ||
3154 | 0, | ||
3155 | target_friend); | ||
3156 | } | ||
3157 | } | ||
3158 | |||
3159 | |||
3160 | /** | ||
3161 | * FIXME: should this be a periodic task, incrementing the search finger index? | ||
3162 | * Update the current search finger index. | ||
3163 | * @a finger_identity | ||
3164 | * @a finger_table_index | ||
3165 | */ | ||
3166 | static void | ||
3167 | update_current_search_finger_index (unsigned int finger_table_index) | ||
3168 | { | ||
3169 | struct FingerInfo *successor; | ||
3170 | |||
3171 | /* FIXME correct this: only move current index periodically */ | ||
3172 | if (finger_table_index != current_search_finger_index) | ||
3173 | return; | ||
3174 | |||
3175 | successor = &finger_table[0]; | ||
3176 | GNUNET_assert (GNUNET_YES == successor->is_present); | ||
3177 | |||
3178 | /* We were looking for immediate successor. */ | ||
3179 | if (0 == current_search_finger_index) | ||
3180 | { | ||
3181 | current_search_finger_index = PREDECESSOR_FINGER_ID; | ||
3182 | if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity, | ||
3183 | &successor->finger_identity)) | ||
3184 | { | ||
3185 | if (NULL == send_verify_successor_task) | ||
3186 | { | ||
3187 | send_verify_successor_task | ||
3188 | = GNUNET_SCHEDULER_add_now (&send_verify_successor_message, | ||
3189 | NULL); | ||
3190 | } | ||
3191 | } | ||
3192 | return; | ||
3193 | } | ||
3194 | current_search_finger_index--; | ||
3195 | } | ||
3196 | |||
3197 | |||
3198 | /** | ||
3199 | * Get the least significant bit set in val. | ||
3200 | * | ||
3201 | * @param val Value | ||
3202 | * @return Position of first bit set, 65 in case of error. | ||
3203 | */ | ||
3204 | static unsigned int | ||
3205 | find_set_bit (uint64_t val) | ||
3206 | { | ||
3207 | uint64_t i; | ||
3208 | unsigned int pos; | ||
3209 | |||
3210 | i = 1; | ||
3211 | pos = 0; | ||
3212 | |||
3213 | while (!(i & val)) | ||
3214 | { | ||
3215 | i = i << 1; | ||
3216 | pos++; | ||
3217 | if (pos > 63) | ||
3218 | { | ||
3219 | GNUNET_break (0); | ||
3220 | return 65; | ||
3221 | } | ||
3222 | } | ||
3223 | |||
3224 | if (val/i != 1) | ||
3225 | return 65; /* Some other bit was set to 1 as well. */ | ||
3226 | |||
3227 | return pos; | ||
3228 | } | ||
3229 | |||
3230 | |||
3231 | /** | ||
3232 | * Calculate finger_table_index from initial 64 bit finger identity value that | ||
3233 | * we send in trail setup message. | ||
3234 | * @param ultimate_destination_finger_value Value that we calculated from our | ||
3235 | * identity and finger_table_index. | ||
3236 | * @param is_predecessor Is the entry for predecessor or not? | ||
3237 | * @return finger_table_index Value between 0 <= finger_table_index <= 64 | ||
3238 | * finger_table_index > PREDECESSOR_FINGER_ID, if error occurs. | ||
3239 | */ | ||
3240 | static unsigned int | ||
3241 | get_finger_table_index (uint64_t ultimate_destination_finger_value, | ||
3242 | unsigned int is_predecessor) | ||
3243 | { | ||
3244 | uint64_t my_id64; | ||
3245 | uint64_t diff; | ||
3246 | unsigned int finger_table_index; | ||
3247 | |||
3248 | GNUNET_memcpy (&my_id64, &my_identity, sizeof (uint64_t)); | ||
3249 | my_id64 = GNUNET_ntohll (my_id64); | ||
3250 | |||
3251 | /* Is this a predecessor finger? */ | ||
3252 | if (1 == is_predecessor) | ||
3253 | { | ||
3254 | diff = my_id64 - ultimate_destination_finger_value; | ||
3255 | if (1 == diff) | ||
3256 | finger_table_index = PREDECESSOR_FINGER_ID; | ||
3257 | else | ||
3258 | finger_table_index = PREDECESSOR_FINGER_ID + 1; //error value | ||
3259 | |||
3260 | } | ||
3261 | else | ||
3262 | { | ||
3263 | diff = ultimate_destination_finger_value - my_id64; | ||
3264 | finger_table_index = find_set_bit (diff); | ||
3265 | } | ||
3266 | return finger_table_index; | ||
3267 | } | ||
3268 | |||
3269 | |||
3270 | /** | ||
3271 | * Remove finger and its associated data structures from finger table. | ||
3272 | * @param existing_finger Finger to be removed which is in finger table. | ||
3273 | * @param finger_table_index Index in finger table where @a existing_finger | ||
3274 | * is stored. | ||
3275 | */ | ||
3276 | static void | ||
3277 | remove_existing_finger (struct FingerInfo *existing_finger, | ||
3278 | unsigned int finger_table_index) | ||
3279 | { | ||
3280 | GNUNET_assert (GNUNET_YES == existing_finger->is_present); | ||
3281 | |||
3282 | /* If I am my own finger, then we have no trails. */ | ||
3283 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&existing_finger->finger_identity, | ||
3284 | &my_identity)) | ||
3285 | { | ||
3286 | existing_finger->is_present = GNUNET_NO; | ||
3287 | memset ((void *)&finger_table[finger_table_index], 0, | ||
3288 | sizeof (finger_table[finger_table_index])); | ||
3289 | return; | ||
3290 | } | ||
3291 | |||
3292 | /* For all other fingers, send trail teardown across all the trails to reach | ||
3293 | finger, and free the finger. */ | ||
3294 | send_all_finger_trails_teardown (existing_finger); | ||
3295 | free_finger (existing_finger, finger_table_index); | ||
3296 | } | ||
3297 | |||
3298 | |||
3299 | /** | ||
3300 | * Check if there is already an entry in finger_table at finger_table_index. | ||
3301 | * We get the finger_table_index from 64bit finger value we got from the network. | ||
3302 | * -- If yes, then select the closest finger. | ||
3303 | * -- If new and existing finger are same, then check if you can store more | ||
3304 | * trails. | ||
3305 | * -- If yes then add trail, else keep the best trails to reach to the | ||
3306 | * finger. | ||
3307 | * -- If the new finger is closest, remove the existing entry, send trail | ||
3308 | * teardown message across all the trails to reach the existing entry. | ||
3309 | * Add the new finger. | ||
3310 | * -- If new and existing finger are different, and existing finger is closest | ||
3311 | * then do nothing. | ||
3312 | * -- Update current_search_finger_index. | ||
3313 | * @param finger_identity Peer Identity of new finger | ||
3314 | * @param finger_trail Trail to reach the new finger | ||
3315 | * @param finger_trail_length Total number of peers in @a new_finger_trail. | ||
3316 | * @param is_predecessor Is this entry for predecessor in finger_table? | ||
3317 | * @param finger_value 64 bit value of finger identity that we got from network. | ||
3318 | * @param finger_trail_id Unique identifier of @finger_trail. | ||
3319 | */ | ||
3320 | static void | ||
3321 | finger_table_add (const struct GNUNET_PeerIdentity *finger_identity, | ||
3322 | const struct GNUNET_PeerIdentity *finger_trail, | ||
3323 | unsigned int finger_trail_length, | ||
3324 | unsigned int is_predecessor, | ||
3325 | uint64_t finger_value, | ||
3326 | const struct GNUNET_HashCode *finger_trail_id) | ||
3327 | { | ||
3328 | struct FingerInfo *existing_finger; | ||
3329 | const struct GNUNET_PeerIdentity *closest_peer; | ||
3330 | struct FingerInfo *successor; | ||
3331 | unsigned int finger_table_index; | ||
3332 | |||
3333 | /* Get the finger_table_index corresponding to finger_value we got from network.*/ | ||
3334 | finger_table_index = get_finger_table_index (finger_value, is_predecessor); | ||
3335 | |||
3336 | /* Invalid finger_table_index. */ | ||
3337 | if ((finger_table_index > PREDECESSOR_FINGER_ID)) | ||
3338 | { | ||
3339 | GNUNET_break_op (0); | ||
3340 | return; | ||
3341 | } | ||
3342 | |||
3343 | /* Check if new entry is same as successor. */ | ||
3344 | if ((0 != finger_table_index) && | ||
3345 | (PREDECESSOR_FINGER_ID != finger_table_index)) | ||
3346 | { | ||
3347 | successor = &finger_table[0]; | ||
3348 | if (GNUNET_NO == successor->is_present) | ||
3349 | { | ||
3350 | GNUNET_break (0); //ASSERTION FAILS HERE. FIXME | ||
3351 | return; | ||
3352 | } | ||
3353 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (finger_identity, | ||
3354 | &successor->finger_identity)) | ||
3355 | { | ||
3356 | if (0 == fingers_round_count) | ||
3357 | { | ||
3358 | find_finger_trail_task_next_send_time = | ||
3359 | GNUNET_TIME_STD_BACKOFF(find_finger_trail_task_next_send_time); | ||
3360 | } | ||
3361 | else | ||
3362 | fingers_round_count--; | ||
3363 | current_search_finger_index = 0; | ||
3364 | GNUNET_STATISTICS_update (GDS_stats, | ||
3365 | gettext_noop | ||
3366 | ("# FINGERS_COUNT"), (int64_t) total_fingers_found, | ||
3367 | GNUNET_NO); | ||
3368 | total_fingers_found = 0; | ||
3369 | return; | ||
3370 | } | ||
3371 | |||
3372 | struct FingerInfo prev_finger; | ||
3373 | prev_finger = finger_table[finger_table_index - 1]; | ||
3374 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (finger_identity, | ||
3375 | &prev_finger.finger_identity)) | ||
3376 | { | ||
3377 | current_search_finger_index--; | ||
3378 | return; | ||
3379 | } | ||
3380 | } | ||
3381 | |||
3382 | total_fingers_found++; | ||
3383 | existing_finger = &finger_table[finger_table_index]; | ||
3384 | |||
3385 | /* No entry present in finger_table for given finger map index. */ | ||
3386 | if (GNUNET_NO == existing_finger->is_present) | ||
3387 | { | ||
3388 | /* Shorten the trail if possible. */ | ||
3389 | add_new_finger (finger_identity, | ||
3390 | finger_trail, | ||
3391 | finger_trail_length, | ||
3392 | finger_trail_id, | ||
3393 | finger_table_index); | ||
3394 | update_current_search_finger_index (finger_table_index); | ||
3395 | return; | ||
3396 | } | ||
3397 | |||
3398 | /* If existing entry and finger identity are not same. */ | ||
3399 | if (0 != GNUNET_CRYPTO_cmp_peer_identity (&existing_finger->finger_identity, | ||
3400 | finger_identity)) | ||
3401 | { | ||
3402 | closest_peer = select_closest_peer (&existing_finger->finger_identity, | ||
3403 | finger_identity, | ||
3404 | finger_value, | ||
3405 | is_predecessor); | ||
3406 | |||
3407 | /* If the new finger is the closest peer. */ | ||
3408 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (finger_identity, | ||
3409 | closest_peer)) | ||
3410 | { | ||
3411 | remove_existing_finger (existing_finger, | ||
3412 | finger_table_index); | ||
3413 | add_new_finger (finger_identity, | ||
3414 | finger_trail, | ||
3415 | finger_trail_length, | ||
3416 | finger_trail_id, | ||
3417 | finger_table_index); | ||
3418 | } | ||
3419 | else | ||
3420 | { | ||
3421 | /* Existing finger is the closest one. We need to send trail teardown | ||
3422 | across the trail setup in routing table of all the peers. */ | ||
3423 | if (0 != GNUNET_CRYPTO_cmp_peer_identity (finger_identity, | ||
3424 | &my_identity)) | ||
3425 | { | ||
3426 | if (finger_trail_length > 0) | ||
3427 | GDS_NEIGHBOURS_send_trail_teardown (finger_trail_id, | ||
3428 | GDS_ROUTING_SRC_TO_DEST, | ||
3429 | &finger_trail[0]); | ||
3430 | else | ||
3431 | GDS_NEIGHBOURS_send_trail_teardown (finger_trail_id, | ||
3432 | GDS_ROUTING_SRC_TO_DEST, | ||
3433 | finger_identity); | ||
3434 | } | ||
3435 | } | ||
3436 | } | ||
3437 | else | ||
3438 | { | ||
3439 | /* If both new and existing entry are same as my_identity, then do nothing. */ | ||
3440 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&existing_finger->finger_identity, | ||
3441 | &my_identity)) | ||
3442 | { | ||
3443 | return; | ||
3444 | } | ||
3445 | |||
3446 | /* If there is space to store more trails. */ | ||
3447 | if (existing_finger->trails_count < MAXIMUM_TRAILS_PER_FINGER) | ||
3448 | add_new_trail (existing_finger, | ||
3449 | finger_trail, | ||
3450 | finger_trail_length, | ||
3451 | finger_trail_id); | ||
3452 | else | ||
3453 | select_and_replace_trail (existing_finger, | ||
3454 | finger_trail, | ||
3455 | finger_trail_length, | ||
3456 | finger_trail_id); | ||
3457 | } | ||
3458 | update_current_search_finger_index (finger_table_index); | ||
3459 | return; | ||
3460 | } | ||
3461 | |||
3462 | |||
3463 | /** | ||
3464 | * Verify validity of P2P put messages. | ||
3465 | * | ||
3466 | * @param cls closure | ||
3467 | * @param put the message | ||
3468 | * @return #GNUNET_OK if the message is well-formed | ||
3469 | */ | ||
3470 | static int | ||
3471 | check_dht_p2p_put (void *cls, | ||
3472 | const struct PeerPutMessage *put) | ||
3473 | { | ||
3474 | size_t msize; | ||
3475 | uint32_t putlen; | ||
3476 | |||
3477 | msize = ntohs (put->header.size); | ||
3478 | putlen = ntohl (put->put_path_length); | ||
3479 | if ((msize < | ||
3480 | sizeof (struct PeerPutMessage) + | ||
3481 | putlen * sizeof (struct GNUNET_PeerIdentity)) || | ||
3482 | (putlen > | ||
3483 | GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity))) | ||
3484 | { | ||
3485 | GNUNET_break_op (0); | ||
3486 | return GNUNET_SYSERR; | ||
3487 | } | ||
3488 | return GNUNET_OK; | ||
3489 | } | ||
3490 | |||
3491 | |||
3492 | /** | ||
3493 | * Core handler for P2P put messages. | ||
3494 | * | ||
3495 | * @param cls closure | ||
3496 | * @param put the message | ||
3497 | */ | ||
3498 | static void | ||
3499 | handle_dht_p2p_put (void *cls, | ||
3500 | const struct PeerPutMessage *put) | ||
3501 | { | ||
3502 | struct GNUNET_PeerIdentity *put_path; | ||
3503 | struct GNUNET_PeerIdentity current_best_known_dest; | ||
3504 | struct GNUNET_PeerIdentity best_known_dest; | ||
3505 | struct GNUNET_HashCode received_intermediate_trail_id; | ||
3506 | struct GNUNET_HashCode intermediate_trail_id; | ||
3507 | struct GNUNET_PeerIdentity next_hop; | ||
3508 | const struct GNUNET_PeerIdentity *next_routing_hop; | ||
3509 | enum GNUNET_DHT_RouteOption options; | ||
3510 | struct GNUNET_HashCode test_key; | ||
3511 | struct Closest_Peer successor; | ||
3512 | void *payload; | ||
3513 | size_t msize; | ||
3514 | uint32_t putlen = ntohl (put->put_path_length); | ||
3515 | struct GNUNET_PeerIdentity pp[putlen + 1]; | ||
3516 | uint32_t hop_count; | ||
3517 | size_t payload_size; | ||
3518 | uint64_t key_value; | ||
3519 | |||
3520 | msize = ntohs (put->header.size); | ||
3521 | GNUNET_STATISTICS_update (GDS_stats, | ||
3522 | gettext_noop ("# Bytes received from other peers"), | ||
3523 | (int64_t) msize, | ||
3524 | GNUNET_NO); | ||
3525 | |||
3526 | current_best_known_dest = put->best_known_destination; | ||
3527 | put_path = (struct GNUNET_PeerIdentity *) &put[1]; | ||
3528 | payload = &put_path[putlen]; | ||
3529 | options = ntohl (put->options); | ||
3530 | received_intermediate_trail_id = put->intermediate_trail_id; | ||
3531 | hop_count = ntohl(put->hop_count); | ||
3532 | payload_size = msize - (sizeof (struct PeerPutMessage) + | ||
3533 | putlen * sizeof (struct GNUNET_PeerIdentity)); | ||
3534 | hop_count++; | ||
3535 | switch (GNUNET_BLOCK_get_key (GDS_block_context, | ||
3536 | ntohl (put->block_type), | ||
3537 | payload, | ||
3538 | payload_size, | ||
3539 | &test_key)) | ||
3540 | { | ||
3541 | case GNUNET_YES: | ||
3542 | if (0 != memcmp (&test_key, | ||
3543 | &put->key, | ||
3544 | sizeof (struct GNUNET_HashCode))) | ||
3545 | { | ||
3546 | char *put_s = GNUNET_strdup (GNUNET_h2s_full (&put->key)); | ||
3547 | GNUNET_break_op (0); | ||
3548 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
3549 | "PUT with key `%s' for block with key %s\n", | ||
3550 | put_s, | ||
3551 | GNUNET_h2s_full (&test_key)); | ||
3552 | GNUNET_free (put_s); | ||
3553 | return; | ||
3554 | } | ||
3555 | break; | ||
3556 | case GNUNET_NO: | ||
3557 | GNUNET_break_op (0); | ||
3558 | return; | ||
3559 | case GNUNET_SYSERR: | ||
3560 | /* cannot verify, good luck */ | ||
3561 | break; | ||
3562 | } | ||
3563 | |||
3564 | if (ntohl (put->block_type) == GNUNET_BLOCK_TYPE_REGEX) /* FIXME: do for all tpyes */ | ||
3565 | { | ||
3566 | switch (GNUNET_BLOCK_evaluate (GDS_block_context, | ||
3567 | ntohl (put->block_type), | ||
3568 | GNUNET_BLOCK_EO_NONE, | ||
3569 | NULL, /* query */ | ||
3570 | NULL, 0, /* bloom filer */ | ||
3571 | NULL, 0, /* xquery */ | ||
3572 | payload, | ||
3573 | payload_size)) | ||
3574 | { | ||
3575 | case GNUNET_BLOCK_EVALUATION_OK_MORE: | ||
3576 | case GNUNET_BLOCK_EVALUATION_OK_LAST: | ||
3577 | break; | ||
3578 | |||
3579 | case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE: | ||
3580 | case GNUNET_BLOCK_EVALUATION_RESULT_INVALID: | ||
3581 | case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT: | ||
3582 | case GNUNET_BLOCK_EVALUATION_REQUEST_VALID: | ||
3583 | case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID: | ||
3584 | case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED: | ||
3585 | default: | ||
3586 | GNUNET_break_op (0); | ||
3587 | return; | ||
3588 | } | ||
3589 | } | ||
3590 | |||
3591 | /* Check if you are already a part of put path. */ | ||
3592 | unsigned int i; | ||
3593 | for (i = 0; i < putlen; i++) | ||
3594 | { | ||
3595 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, | ||
3596 | &put_path[i])) | ||
3597 | { | ||
3598 | putlen = i; | ||
3599 | break; | ||
3600 | } | ||
3601 | } | ||
3602 | |||
3603 | /* Add yourself to the list. */ | ||
3604 | //if (0 != (options & GNUNET_DHT_RO_RECORD_ROUTE)) | ||
3605 | if (1) | ||
3606 | { | ||
3607 | GNUNET_memcpy (pp, | ||
3608 | put_path, | ||
3609 | putlen * sizeof (struct GNUNET_PeerIdentity)); | ||
3610 | pp[putlen] = my_identity; | ||
3611 | putlen++; | ||
3612 | } | ||
3613 | else | ||
3614 | { | ||
3615 | putlen = 0; | ||
3616 | } | ||
3617 | GNUNET_memcpy (&key_value, | ||
3618 | &put->key, | ||
3619 | sizeof (uint64_t)); | ||
3620 | key_value = GNUNET_ntohll (key_value); | ||
3621 | successor = find_local_best_known_next_hop (key_value, | ||
3622 | GDS_FINGER_TYPE_NON_PREDECESSOR); | ||
3623 | next_hop = successor.next_hop; | ||
3624 | intermediate_trail_id = successor.trail_id; | ||
3625 | best_known_dest = successor.best_known_destination; | ||
3626 | |||
3627 | if (0 != (GNUNET_CRYPTO_cmp_peer_identity (¤t_best_known_dest, | ||
3628 | &my_identity))) | ||
3629 | { | ||
3630 | next_routing_hop = GDS_ROUTING_get_next_hop (&received_intermediate_trail_id, | ||
3631 | GDS_ROUTING_SRC_TO_DEST); | ||
3632 | if (NULL != next_routing_hop) | ||
3633 | { | ||
3634 | next_hop = *next_routing_hop; | ||
3635 | intermediate_trail_id = received_intermediate_trail_id; | ||
3636 | best_known_dest = current_best_known_dest; | ||
3637 | } | ||
3638 | } | ||
3639 | |||
3640 | GDS_CLIENTS_process_put (options, | ||
3641 | ntohl (put->block_type), | ||
3642 | hop_count, | ||
3643 | ntohl (put->desired_replication_level), | ||
3644 | putlen, | ||
3645 | pp, | ||
3646 | GNUNET_TIME_absolute_ntoh (put->expiration_time), | ||
3647 | &put->key, | ||
3648 | payload, | ||
3649 | payload_size); | ||
3650 | |||
3651 | /* I am the final destination */ | ||
3652 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, | ||
3653 | &best_known_dest)) | ||
3654 | { | ||
3655 | DEBUG ("\n PUT_REQUEST_SUCCESSFUL for key = %s", | ||
3656 | GNUNET_h2s(&put->key)); | ||
3657 | GDS_DATACACHE_handle_put (GNUNET_TIME_absolute_ntoh (put->expiration_time), | ||
3658 | &put->key, | ||
3659 | putlen, | ||
3660 | pp, | ||
3661 | ntohl (put->block_type), | ||
3662 | payload_size, | ||
3663 | payload); | ||
3664 | } | ||
3665 | GDS_NEIGHBOURS_send_put (&put->key, | ||
3666 | ntohl (put->block_type), | ||
3667 | ntohl (put->options), | ||
3668 | ntohl (put->desired_replication_level), | ||
3669 | best_known_dest, | ||
3670 | intermediate_trail_id, | ||
3671 | &next_hop, | ||
3672 | hop_count, | ||
3673 | putlen, | ||
3674 | pp, | ||
3675 | GNUNET_TIME_absolute_ntoh (put->expiration_time), | ||
3676 | payload, | ||
3677 | payload_size); | ||
3678 | } | ||
3679 | |||
3680 | |||
3681 | /** | ||
3682 | * Check integrity of @a get message. | ||
3683 | * | ||
3684 | * @param cls closure | ||
3685 | * @param get the message | ||
3686 | * @return #GNUNET_OK if @a get is well-formed | ||
3687 | */ | ||
3688 | static int | ||
3689 | check_dht_p2p_get (void *cls, | ||
3690 | const struct PeerGetMessage *get) | ||
3691 | { | ||
3692 | uint32_t get_length; | ||
3693 | size_t msize; | ||
3694 | |||
3695 | msize = ntohs (get->header.size); | ||
3696 | get_length = ntohl (get->get_path_length); | ||
3697 | if ((msize < | ||
3698 | sizeof (struct PeerGetMessage) + | ||
3699 | get_length * sizeof (struct GNUNET_PeerIdentity)) || | ||
3700 | (get_length > | ||
3701 | GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity))) | ||
3702 | { | ||
3703 | GNUNET_break_op (0); | ||
3704 | return GNUNET_SYSERR; | ||
3705 | } | ||
3706 | return GNUNET_OK; | ||
3707 | } | ||
3708 | |||
3709 | |||
3710 | /** | ||
3711 | * FIXME: Check for loop in the request. If you already are part of get path, | ||
3712 | * then you need to reset the get path length. | ||
3713 | * Core handler for p2p get requests. | ||
3714 | * | ||
3715 | * @param cls closure | ||
3716 | * @param get the message | ||
3717 | */ | ||
3718 | static void | ||
3719 | handle_dht_p2p_get (void *cls, | ||
3720 | const struct PeerGetMessage *get) | ||
3721 | { | ||
3722 | const struct GNUNET_PeerIdentity *get_path; | ||
3723 | struct GNUNET_PeerIdentity best_known_dest; | ||
3724 | struct GNUNET_PeerIdentity current_best_known_dest; | ||
3725 | struct GNUNET_HashCode intermediate_trail_id; | ||
3726 | struct GNUNET_HashCode received_intermediate_trail_id; | ||
3727 | struct Closest_Peer successor; | ||
3728 | struct GNUNET_PeerIdentity next_hop; | ||
3729 | const struct GNUNET_PeerIdentity *next_routing_hop; | ||
3730 | uint32_t get_length; | ||
3731 | uint64_t key_value; | ||
3732 | uint32_t hop_count; | ||
3733 | size_t msize; | ||
3734 | |||
3735 | msize = ntohs (get->header.size); | ||
3736 | get_length = ntohl (get->get_path_length); | ||
3737 | current_best_known_dest = get->best_known_destination; | ||
3738 | received_intermediate_trail_id = get->intermediate_trail_id; | ||
3739 | get_path = (const struct GNUNET_PeerIdentity *) &get[1]; | ||
3740 | hop_count = get->hop_count; | ||
3741 | hop_count++; | ||
3742 | GNUNET_STATISTICS_update (GDS_stats, | ||
3743 | gettext_noop ("# Bytes received from other peers"), | ||
3744 | msize, | ||
3745 | GNUNET_NO); | ||
3746 | GNUNET_memcpy (&key_value, | ||
3747 | &get->key, | ||
3748 | sizeof (uint64_t)); | ||
3749 | key_value = GNUNET_ntohll (key_value); | ||
3750 | |||
3751 | /* Check if you are already a part of get path. */ | ||
3752 | for (unsigned int i = 0; i < get_length; i++) | ||
3753 | { | ||
3754 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, | ||
3755 | &get_path[i])) | ||
3756 | { | ||
3757 | get_length = i; | ||
3758 | break; | ||
3759 | } | ||
3760 | } | ||
3761 | |||
3762 | /* Add yourself in the get path. */ | ||
3763 | struct GNUNET_PeerIdentity gp[get_length + 1]; | ||
3764 | GNUNET_memcpy (gp, | ||
3765 | get_path, | ||
3766 | get_length * sizeof (struct GNUNET_PeerIdentity)); | ||
3767 | gp[get_length] = my_identity; | ||
3768 | get_length = get_length + 1; | ||
3769 | GDS_CLIENTS_process_get (get->options, | ||
3770 | get->block_type, | ||
3771 | hop_count, | ||
3772 | get->desired_replication_level, | ||
3773 | get->get_path_length, | ||
3774 | gp, | ||
3775 | &get->key); | ||
3776 | |||
3777 | |||
3778 | successor = find_local_best_known_next_hop (key_value, | ||
3779 | GDS_FINGER_TYPE_NON_PREDECESSOR); | ||
3780 | next_hop = successor.next_hop; | ||
3781 | best_known_dest = successor.best_known_destination; | ||
3782 | intermediate_trail_id = successor.trail_id; | ||
3783 | /* I am not the final destination. I am part of trail to reach final dest. */ | ||
3784 | if (0 != (GNUNET_CRYPTO_cmp_peer_identity (¤t_best_known_dest, &my_identity))) | ||
3785 | { | ||
3786 | next_routing_hop = GDS_ROUTING_get_next_hop (&received_intermediate_trail_id, | ||
3787 | GDS_ROUTING_SRC_TO_DEST); | ||
3788 | if (NULL != next_routing_hop) | ||
3789 | { | ||
3790 | next_hop = *next_routing_hop; | ||
3791 | best_known_dest = current_best_known_dest; | ||
3792 | intermediate_trail_id = received_intermediate_trail_id; | ||
3793 | } | ||
3794 | } | ||
3795 | |||
3796 | /* I am the final destination. */ | ||
3797 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, | ||
3798 | &best_known_dest)) | ||
3799 | { | ||
3800 | if (1 == get_length) | ||
3801 | { | ||
3802 | DEBUG ("\n GET_REQUEST DONE for key = %s", | ||
3803 | GNUNET_h2s(&get->key)); | ||
3804 | GDS_DATACACHE_handle_get (&get->key, | ||
3805 | get->block_type, /* FIXME: endianess? */ | ||
3806 | NULL, | ||
3807 | 0, | ||
3808 | NULL, | ||
3809 | 0, | ||
3810 | &get_cb, | ||
3811 | NULL); | ||
3812 | } | ||
3813 | else | ||
3814 | { | ||
3815 | GDS_DATACACHE_handle_get (&get->key, | ||
3816 | get->block_type, /* FIXME: endianess? */ | ||
3817 | NULL, | ||
3818 | 0, | ||
3819 | NULL, | ||
3820 | 0, | ||
3821 | &get_cb, | ||
3822 | &gp[get_length - 2]); | ||
3823 | } | ||
3824 | } | ||
3825 | else | ||
3826 | { | ||
3827 | GDS_NEIGHBOURS_send_get (&get->key, | ||
3828 | get->block_type, /* FIXME: endianess? */ | ||
3829 | get->options, | ||
3830 | get->desired_replication_level, | ||
3831 | &best_known_dest, | ||
3832 | &intermediate_trail_id, | ||
3833 | &next_hop, | ||
3834 | hop_count, | ||
3835 | get_length, | ||
3836 | gp); | ||
3837 | } | ||
3838 | } | ||
3839 | |||
3840 | |||
3841 | /** | ||
3842 | * Check validity of @a get_result message. | ||
3843 | * | ||
3844 | * @param cls closure | ||
3845 | * @param get_result the message | ||
3846 | * @return #GNUNET_OK if @a get_result is well-formed | ||
3847 | */ | ||
3848 | static int | ||
3849 | check_dht_p2p_get_result (void *cls, | ||
3850 | const struct PeerGetResultMessage *get_result) | ||
3851 | { | ||
3852 | size_t msize; | ||
3853 | unsigned int getlen; | ||
3854 | unsigned int putlen; | ||
3855 | |||
3856 | msize = ntohs (get_result->header.size); | ||
3857 | getlen = ntohl (get_result->get_path_length); | ||
3858 | putlen = ntohl (get_result->put_path_length); | ||
3859 | if ((msize < | ||
3860 | sizeof (struct PeerGetResultMessage) + | ||
3861 | getlen * sizeof (struct GNUNET_PeerIdentity) + | ||
3862 | putlen * sizeof (struct GNUNET_PeerIdentity)) || | ||
3863 | (getlen > | ||
3864 | GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity) || | ||
3865 | (putlen > | ||
3866 | GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE / sizeof (struct GNUNET_PeerIdentity)))) | ||
3867 | { | ||
3868 | GNUNET_break_op (0); | ||
3869 | return GNUNET_SYSERR; | ||
3870 | } | ||
3871 | return GNUNET_OK; | ||
3872 | } | ||
3873 | |||
3874 | |||
3875 | /** | ||
3876 | * Core handler for get result | ||
3877 | * | ||
3878 | * @param cls closure | ||
3879 | * @param get_result the message | ||
3880 | */ | ||
3881 | static void | ||
3882 | handle_dht_p2p_get_result (void *cls, | ||
3883 | const struct PeerGetResultMessage *get_result) | ||
3884 | { | ||
3885 | const struct GNUNET_PeerIdentity *get_path; | ||
3886 | const struct GNUNET_PeerIdentity *put_path; | ||
3887 | const void *payload; | ||
3888 | size_t payload_size; | ||
3889 | size_t msize; | ||
3890 | unsigned int getlen; | ||
3891 | unsigned int putlen; | ||
3892 | int current_path_index; | ||
3893 | |||
3894 | msize = ntohs (get_result->header.size); | ||
3895 | getlen = ntohl (get_result->get_path_length); | ||
3896 | putlen = ntohl (get_result->put_path_length); | ||
3897 | DEBUG ("GET_RESULT FOR DATA_SIZE = %u\n", | ||
3898 | (unsigned int) msize); | ||
3899 | GNUNET_STATISTICS_update (GDS_stats, | ||
3900 | gettext_noop ("# Bytes received from other peers"), | ||
3901 | msize, | ||
3902 | GNUNET_NO); | ||
3903 | put_path = (const struct GNUNET_PeerIdentity *) &get_result[1]; | ||
3904 | get_path = &put_path[putlen]; | ||
3905 | payload = (const void *) &get_path[getlen]; | ||
3906 | payload_size = msize - (sizeof (struct PeerGetResultMessage) + | ||
3907 | (getlen + putlen) * sizeof (struct GNUNET_PeerIdentity)); | ||
3908 | |||
3909 | if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&my_identity, | ||
3910 | &get_path[0]))) | ||
3911 | { | ||
3912 | GDS_CLIENTS_handle_reply (GNUNET_TIME_absolute_ntoh (get_result->expiration_time), | ||
3913 | &get_result->key, | ||
3914 | getlen, | ||
3915 | get_path, | ||
3916 | putlen, | ||
3917 | put_path, | ||
3918 | get_result->type, | ||
3919 | payload_size, | ||
3920 | payload); | ||
3921 | return; | ||
3922 | } | ||
3923 | current_path_index = search_my_index (get_path, | ||
3924 | getlen); | ||
3925 | if (-1 == current_path_index) | ||
3926 | { | ||
3927 | DEBUG ("No entry found in get path.\n"); | ||
3928 | GNUNET_break (0); | ||
3929 | return; | ||
3930 | } | ||
3931 | if ((getlen + 1) == current_path_index) | ||
3932 | { | ||
3933 | DEBUG("Present twice in get path. Not allowed. \n"); | ||
3934 | GNUNET_break (0); | ||
3935 | return; | ||
3936 | } | ||
3937 | GDS_NEIGHBOURS_send_get_result (&get_result->key, | ||
3938 | get_result->type, /* FIXME: endianess? */ | ||
3939 | &get_path[current_path_index - 1], | ||
3940 | &get_result->querying_peer, | ||
3941 | putlen, | ||
3942 | put_path, | ||
3943 | getlen, | ||
3944 | get_path, | ||
3945 | GNUNET_TIME_absolute_ntoh (get_result->expiration_time), | ||
3946 | payload, | ||
3947 | payload_size); | ||
3948 | } | ||
3949 | |||
3950 | |||
3951 | /** | ||
3952 | * Find the next hop to pass trail setup message. First find the local best known | ||
3953 | * hop from your own identity, friends and finger. If you were part of trail, | ||
3954 | * then get the next hop from routing table. Compare next_hop from routing table | ||
3955 | * and local best known hop, and return the closest one to final_dest_finger_val | ||
3956 | * @param final_dest_finger_val 64 bit value of finger identity | ||
3957 | * @param intermediate_trail_id If you are part of trail to reach to some other | ||
3958 | * finger, then it is the trail id to reach to | ||
3959 | * that finger, else set to 0. | ||
3960 | * @param is_predecessor Are we looking for closest successor or predecessor. | ||
3961 | * @param source Source of trail setup message. | ||
3962 | * @param current_dest In case you are part of trail, then finger to which | ||
3963 | * we should forward the message. Else my own identity | ||
3964 | * @return Closest Peer for @a final_dest_finger_val | ||
3965 | */ | ||
3966 | static struct Closest_Peer | ||
3967 | get_local_best_known_next_hop (uint64_t final_dest_finger_val, | ||
3968 | const struct GNUNET_HashCode *intermediate_trail_id, | ||
3969 | unsigned int is_predecessor, | ||
3970 | const struct GNUNET_PeerIdentity *source, | ||
3971 | const struct GNUNET_PeerIdentity *current_dest) | ||
3972 | { | ||
3973 | struct Closest_Peer peer; | ||
3974 | |||
3975 | peer = find_local_best_known_next_hop (final_dest_finger_val, | ||
3976 | is_predecessor); | ||
3977 | |||
3978 | /* Am I just a part of a trail towards a finger (current_destination)? */ | ||
3979 | if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity, | ||
3980 | current_dest) && | ||
3981 | 0 != GNUNET_CRYPTO_cmp_peer_identity (&peer.best_known_destination, | ||
3982 | current_dest)) | ||
3983 | { | ||
3984 | const struct GNUNET_PeerIdentity *closest_peer; | ||
3985 | |||
3986 | /* Select best successor among one found locally and current_destination | ||
3987 | * that we got from network.*/ | ||
3988 | closest_peer = select_closest_peer (&peer.best_known_destination, | ||
3989 | current_dest, | ||
3990 | final_dest_finger_val, | ||
3991 | is_predecessor); | ||
3992 | |||
3993 | /* Is current dest (end point of the trail of which I am a part) closest_peer? */ | ||
3994 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (current_dest, | ||
3995 | closest_peer)) | ||
3996 | { | ||
3997 | const struct GNUNET_PeerIdentity *next_hop; | ||
3998 | |||
3999 | next_hop = GDS_ROUTING_get_next_hop (intermediate_trail_id, | ||
4000 | GDS_ROUTING_SRC_TO_DEST); | ||
4001 | /* next_hop NULL is a valid case. This intermediate trail id is set by | ||
4002 | some other finger, and while this trail setup is in progress, that other | ||
4003 | peer might have found a better trail ,and send trail teardown message | ||
4004 | across the network. In case we got the trail teardown message first, | ||
4005 | then next_hop will be NULL. A possible solution could be to keep track | ||
4006 | * of all removed trail id, and be sure that there is no other reason . */ | ||
4007 | if(NULL != next_hop) | ||
4008 | { | ||
4009 | peer.next_hop = *next_hop; | ||
4010 | peer.best_known_destination = *current_dest; | ||
4011 | peer.trail_id = *intermediate_trail_id; | ||
4012 | } | ||
4013 | } | ||
4014 | } | ||
4015 | return peer; | ||
4016 | } | ||
4017 | |||
4018 | |||
4019 | /** | ||
4020 | * Check format of a PeerTrailSetupMessage. | ||
4021 | * | ||
4022 | * @param cls closure | ||
4023 | * @param trail_setup the message | ||
4024 | * @return #GNUNET_OK if @a trail_setup is well-formed | ||
4025 | */ | ||
4026 | static int | ||
4027 | check_dht_p2p_trail_setup (void *cls, | ||
4028 | const struct PeerTrailSetupMessage *trail_setup) | ||
4029 | { | ||
4030 | size_t msize; | ||
4031 | |||
4032 | msize = ntohs (trail_setup->header.size); | ||
4033 | if ((msize - sizeof (struct PeerTrailSetupMessage)) % | ||
4034 | sizeof (struct GNUNET_PeerIdentity) != 0) | ||
4035 | { | ||
4036 | GNUNET_break_op (0); | ||
4037 | return GNUNET_SYSERR; | ||
4038 | } | ||
4039 | return GNUNET_OK; | ||
4040 | } | ||
4041 | |||
4042 | |||
4043 | /** | ||
4044 | * Core handle for PeerTrailSetupMessage. | ||
4045 | * | ||
4046 | * @param cls closure | ||
4047 | * @param trail_setup the message | ||
4048 | */ | ||
4049 | static void | ||
4050 | handle_dht_p2p_trail_setup (void *cls, | ||
4051 | const struct PeerTrailSetupMessage *trail_setup) | ||
4052 | { | ||
4053 | struct FriendInfo *friend = cls; | ||
4054 | const struct GNUNET_PeerIdentity *trail_peer_list; | ||
4055 | struct GNUNET_PeerIdentity current_dest; | ||
4056 | struct FriendInfo *target_friend; | ||
4057 | struct GNUNET_PeerIdentity source; | ||
4058 | struct GNUNET_HashCode intermediate_trail_id; | ||
4059 | struct GNUNET_HashCode trail_id; | ||
4060 | unsigned int is_predecessor; | ||
4061 | uint32_t trail_length; | ||
4062 | uint64_t final_dest_finger_val; | ||
4063 | int i; | ||
4064 | size_t msize; | ||
4065 | |||
4066 | msize = ntohs (trail_setup->header.size); | ||
4067 | trail_length = (msize - sizeof (struct PeerTrailSetupMessage))/ | ||
4068 | sizeof (struct GNUNET_PeerIdentity); | ||
4069 | GNUNET_STATISTICS_update (GDS_stats, | ||
4070 | gettext_noop ("# Bytes received from other peers"), | ||
4071 | msize, | ||
4072 | GNUNET_NO); | ||
4073 | trail_peer_list = (const struct GNUNET_PeerIdentity *) &trail_setup[1]; | ||
4074 | current_dest = trail_setup->best_known_destination; | ||
4075 | trail_id = trail_setup->trail_id; | ||
4076 | final_dest_finger_val | ||
4077 | = GNUNET_ntohll (trail_setup->final_destination_finger_value); | ||
4078 | source = trail_setup->source_peer; | ||
4079 | is_predecessor = ntohl (trail_setup->is_predecessor); | ||
4080 | intermediate_trail_id = trail_setup->intermediate_trail_id; | ||
4081 | |||
4082 | /* Did the friend insert its ID in the trail list? */ | ||
4083 | if ( (trail_length > 0) && | ||
4084 | (0 != memcmp (&trail_peer_list[trail_length-1], | ||
4085 | friend->id, | ||
4086 | sizeof (struct GNUNET_PeerIdentity))) ) | ||
4087 | { | ||
4088 | GNUNET_break_op (0); | ||
4089 | return; | ||
4090 | } | ||
4091 | |||
4092 | /* If I was the source and got the message back, then set trail length to 0.*/ | ||
4093 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, | ||
4094 | &source)) | ||
4095 | { | ||
4096 | trail_length = 0; | ||
4097 | } | ||
4098 | |||
4099 | /* Check if you are present in the trail seen so far? */ | ||
4100 | for (i = 0; i < trail_length; i++) | ||
4101 | { | ||
4102 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&trail_peer_list[i], | ||
4103 | &my_identity)) | ||
4104 | { | ||
4105 | /* We will add ourself later in code, if NOT destination. */ | ||
4106 | trail_length = i; | ||
4107 | break; | ||
4108 | } | ||
4109 | } | ||
4110 | |||
4111 | /* Is my routing table full? */ | ||
4112 | if (GNUNET_YES == GDS_ROUTING_threshold_reached ()) | ||
4113 | { | ||
4114 | target_friend | ||
4115 | = (trail_length > 0) | ||
4116 | ? GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
4117 | &trail_peer_list[trail_length - 1]) | ||
4118 | : GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
4119 | &source); | ||
4120 | if (NULL == target_friend) | ||
4121 | { | ||
4122 | DEBUG ("\n friend not found"); | ||
4123 | GNUNET_break(0); | ||
4124 | return; | ||
4125 | } | ||
4126 | GDS_NEIGHBOURS_send_trail_rejection (&source, | ||
4127 | final_dest_finger_val, | ||
4128 | &my_identity, | ||
4129 | is_predecessor, | ||
4130 | trail_peer_list, | ||
4131 | trail_length, | ||
4132 | &trail_id, | ||
4133 | target_friend, | ||
4134 | CONGESTION_TIMEOUT); | ||
4135 | return; | ||
4136 | } | ||
4137 | |||
4138 | /* Get the next hop to forward the trail setup request. */ | ||
4139 | struct Closest_Peer next_peer | ||
4140 | = get_local_best_known_next_hop (final_dest_finger_val, | ||
4141 | &intermediate_trail_id, | ||
4142 | is_predecessor, | ||
4143 | &source, | ||
4144 | ¤t_dest); | ||
4145 | |||
4146 | /* Am I the final destination? */ | ||
4147 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&next_peer.best_known_destination, | ||
4148 | &my_identity)) | ||
4149 | { | ||
4150 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&source, | ||
4151 | &my_identity)) | ||
4152 | { | ||
4153 | finger_table_add (&my_identity, | ||
4154 | NULL, | ||
4155 | 0, | ||
4156 | is_predecessor, | ||
4157 | final_dest_finger_val, | ||
4158 | &trail_id); | ||
4159 | return; | ||
4160 | } | ||
4161 | |||
4162 | target_friend | ||
4163 | = (trail_length > 0) | ||
4164 | ? GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
4165 | &trail_peer_list[trail_length-1]) | ||
4166 | : GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
4167 | &source); | ||
4168 | if (NULL == target_friend) | ||
4169 | { | ||
4170 | GNUNET_break_op (0); | ||
4171 | return; | ||
4172 | } | ||
4173 | GDS_ROUTING_add (&trail_id, | ||
4174 | target_friend->id, | ||
4175 | &my_identity); | ||
4176 | GDS_NEIGHBOURS_send_trail_setup_result (&source, | ||
4177 | &my_identity, | ||
4178 | target_friend, | ||
4179 | trail_length, | ||
4180 | trail_peer_list, | ||
4181 | is_predecessor, | ||
4182 | final_dest_finger_val, | ||
4183 | &trail_id); | ||
4184 | return; | ||
4185 | } | ||
4186 | /* I'm not the final destination. */ | ||
4187 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
4188 | &next_peer.next_hop); | ||
4189 | if (NULL == target_friend) | ||
4190 | { | ||
4191 | DEBUG ("\n target friend not found for peer = %s", | ||
4192 | GNUNET_i2s(&next_peer.next_hop)); | ||
4193 | GNUNET_break (0); | ||
4194 | return; | ||
4195 | } | ||
4196 | if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity, | ||
4197 | &source)) | ||
4198 | { | ||
4199 | /* Add yourself to list of peers. */ | ||
4200 | struct GNUNET_PeerIdentity peer_list[trail_length + 1]; | ||
4201 | |||
4202 | GNUNET_memcpy (peer_list, | ||
4203 | trail_peer_list, | ||
4204 | trail_length * sizeof (struct GNUNET_PeerIdentity)); | ||
4205 | peer_list[trail_length] = my_identity; | ||
4206 | GDS_NEIGHBOURS_send_trail_setup (&source, | ||
4207 | final_dest_finger_val, | ||
4208 | &next_peer.best_known_destination, | ||
4209 | target_friend, | ||
4210 | trail_length + 1, | ||
4211 | peer_list, | ||
4212 | is_predecessor, | ||
4213 | &trail_id, | ||
4214 | &next_peer.trail_id); | ||
4215 | return; | ||
4216 | } | ||
4217 | GDS_NEIGHBOURS_send_trail_setup (&source, | ||
4218 | final_dest_finger_val, | ||
4219 | &next_peer.best_known_destination, | ||
4220 | target_friend, | ||
4221 | 0, | ||
4222 | NULL, | ||
4223 | is_predecessor, | ||
4224 | &trail_id, | ||
4225 | &next_peer.trail_id); | ||
4226 | } | ||
4227 | |||
4228 | |||
4229 | /** | ||
4230 | * Validate format of trail setup result messages. | ||
4231 | * | ||
4232 | * @param closure | ||
4233 | * @param trail_result the message | ||
4234 | * @return #GNUNET_OK if @a trail_result is well-formed | ||
4235 | */ | ||
4236 | static int | ||
4237 | check_dht_p2p_trail_setup_result (void *cls, | ||
4238 | const struct PeerTrailSetupResultMessage *trail_result) | ||
4239 | { | ||
4240 | size_t msize; | ||
4241 | |||
4242 | msize = ntohs (trail_result->header.size); | ||
4243 | if ((msize - sizeof (struct PeerTrailSetupResultMessage)) % | ||
4244 | sizeof (struct GNUNET_PeerIdentity) != 0) | ||
4245 | { | ||
4246 | GNUNET_break_op (0); | ||
4247 | return GNUNET_SYSERR; | ||
4248 | } | ||
4249 | return GNUNET_OK; | ||
4250 | } | ||
4251 | |||
4252 | |||
4253 | /** | ||
4254 | * Core handle for p2p trail setup result messages. | ||
4255 | * | ||
4256 | * @param closure | ||
4257 | * @param trail_result the message | ||
4258 | */ | ||
4259 | static void | ||
4260 | handle_dht_p2p_trail_setup_result (void *cls, | ||
4261 | const struct PeerTrailSetupResultMessage *trail_result) | ||
4262 | { | ||
4263 | struct FriendInfo *friend = cls; | ||
4264 | const struct GNUNET_PeerIdentity *trail_peer_list; | ||
4265 | struct GNUNET_PeerIdentity next_hop; | ||
4266 | struct FriendInfo *target_friend; | ||
4267 | struct GNUNET_PeerIdentity querying_peer; | ||
4268 | struct GNUNET_PeerIdentity finger_identity; | ||
4269 | uint32_t trail_length; | ||
4270 | uint64_t ultimate_destination_finger_value; | ||
4271 | uint32_t is_predecessor; | ||
4272 | struct GNUNET_HashCode trail_id; | ||
4273 | int my_index; | ||
4274 | size_t msize; | ||
4275 | |||
4276 | msize = ntohs (trail_result->header.size); | ||
4277 | trail_length = (msize - sizeof (struct PeerTrailSetupResultMessage))/ | ||
4278 | sizeof (struct GNUNET_PeerIdentity); | ||
4279 | |||
4280 | GNUNET_STATISTICS_update (GDS_stats, | ||
4281 | gettext_noop ("# Bytes received from other peers"), | ||
4282 | msize, | ||
4283 | GNUNET_NO); | ||
4284 | |||
4285 | is_predecessor = ntohl (trail_result->is_predecessor); | ||
4286 | querying_peer = trail_result->querying_peer; | ||
4287 | finger_identity = trail_result->finger_identity; | ||
4288 | trail_id = trail_result->trail_id; | ||
4289 | trail_peer_list = (const struct GNUNET_PeerIdentity *) &trail_result[1]; | ||
4290 | ultimate_destination_finger_value | ||
4291 | = GNUNET_ntohll (trail_result->ultimate_destination_finger_value); | ||
4292 | |||
4293 | /* Am I the one who initiated the query? */ | ||
4294 | if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&querying_peer, | ||
4295 | &my_identity))) | ||
4296 | { | ||
4297 | /* Check that you got the message from the correct peer. */ | ||
4298 | if (trail_length > 0) | ||
4299 | { | ||
4300 | GNUNET_assert (0 == GNUNET_CRYPTO_cmp_peer_identity (&trail_peer_list[0], | ||
4301 | friend->id)); | ||
4302 | } | ||
4303 | else | ||
4304 | { | ||
4305 | GNUNET_assert (0 == GNUNET_CRYPTO_cmp_peer_identity (&finger_identity, | ||
4306 | friend->id)); | ||
4307 | } | ||
4308 | GDS_ROUTING_add (&trail_id, | ||
4309 | &my_identity, | ||
4310 | friend->id); | ||
4311 | finger_table_add (&finger_identity, | ||
4312 | trail_peer_list, | ||
4313 | trail_length, | ||
4314 | is_predecessor, | ||
4315 | ultimate_destination_finger_value, | ||
4316 | &trail_id); | ||
4317 | return; | ||
4318 | } | ||
4319 | |||
4320 | /* Get my location in the trail. */ | ||
4321 | my_index = search_my_index (trail_peer_list, | ||
4322 | trail_length); | ||
4323 | if (-1 == my_index) | ||
4324 | { | ||
4325 | DEBUG ("Not found in trail\n"); | ||
4326 | GNUNET_break_op(0); | ||
4327 | return; | ||
4328 | } | ||
4329 | //TODO; return -2. | ||
4330 | if ((trail_length + 1) == my_index) | ||
4331 | { | ||
4332 | DEBUG ("Found twice in trail.\n"); | ||
4333 | GNUNET_break_op(0); | ||
4334 | return; | ||
4335 | } | ||
4336 | |||
4337 | //TODO; Refactor code here and above to check if sender peer is correct | ||
4338 | if (my_index == 0) | ||
4339 | { | ||
4340 | if (trail_length > 1) | ||
4341 | GNUNET_assert (0 == GNUNET_CRYPTO_cmp_peer_identity (&trail_peer_list[1], | ||
4342 | friend->id)); | ||
4343 | else | ||
4344 | GNUNET_assert (0 == GNUNET_CRYPTO_cmp_peer_identity (&finger_identity, | ||
4345 | friend->id)); | ||
4346 | next_hop = trail_result->querying_peer; | ||
4347 | } | ||
4348 | else | ||
4349 | { | ||
4350 | if (my_index == trail_length - 1) | ||
4351 | { | ||
4352 | GNUNET_assert (0 == | ||
4353 | GNUNET_CRYPTO_cmp_peer_identity (&finger_identity, | ||
4354 | friend->id)); | ||
4355 | } | ||
4356 | else | ||
4357 | GNUNET_assert (0 == | ||
4358 | GNUNET_CRYPTO_cmp_peer_identity (&trail_peer_list[my_index + 1], | ||
4359 | friend->id)); | ||
4360 | next_hop = trail_peer_list[my_index - 1]; | ||
4361 | } | ||
4362 | |||
4363 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
4364 | &next_hop); | ||
4365 | if (NULL == target_friend) | ||
4366 | { | ||
4367 | GNUNET_break_op (0); | ||
4368 | return; | ||
4369 | } | ||
4370 | GDS_ROUTING_add (&trail_id, | ||
4371 | &next_hop, | ||
4372 | friend->id); | ||
4373 | GDS_NEIGHBOURS_send_trail_setup_result (&querying_peer, | ||
4374 | &finger_identity, | ||
4375 | target_friend, | ||
4376 | trail_length, | ||
4377 | trail_peer_list, | ||
4378 | is_predecessor, | ||
4379 | ultimate_destination_finger_value, | ||
4380 | &trail_id); | ||
4381 | } | ||
4382 | |||
4383 | |||
4384 | /** | ||
4385 | * Invert the trail. | ||
4386 | * | ||
4387 | * @param trail Trail to be inverted | ||
4388 | * @param trail_length Total number of peers in the trail. | ||
4389 | * @return Updated trail | ||
4390 | */ | ||
4391 | static struct GNUNET_PeerIdentity * | ||
4392 | invert_trail (const struct GNUNET_PeerIdentity *trail, | ||
4393 | unsigned int trail_length) | ||
4394 | { | ||
4395 | int i; | ||
4396 | int j; | ||
4397 | struct GNUNET_PeerIdentity *inverted_trail; | ||
4398 | |||
4399 | inverted_trail = GNUNET_new_array (trail_length, | ||
4400 | struct GNUNET_PeerIdentity); | ||
4401 | i = 0; | ||
4402 | j = trail_length - 1; | ||
4403 | while (i < trail_length) | ||
4404 | { | ||
4405 | inverted_trail[i] = trail[j]; | ||
4406 | i++; | ||
4407 | j--; | ||
4408 | } | ||
4409 | |||
4410 | GNUNET_assert (NULL != | ||
4411 | GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
4412 | &inverted_trail[0])); | ||
4413 | return inverted_trail; | ||
4414 | } | ||
4415 | |||
4416 | |||
4417 | /** | ||
4418 | * Return the shortest trail among all the trails to reach to finger from me. | ||
4419 | * | ||
4420 | * @param finger Finger | ||
4421 | * @param shortest_trail_length[out] Trail length of shortest trail from me | ||
4422 | * to @a finger | ||
4423 | * @return Shortest trail. | ||
4424 | */ | ||
4425 | static struct GNUNET_PeerIdentity * | ||
4426 | get_shortest_trail (struct FingerInfo *finger, | ||
4427 | unsigned int *trail_length) | ||
4428 | { | ||
4429 | struct Trail *trail; | ||
4430 | unsigned int flag = 0; | ||
4431 | unsigned int shortest_trail_index = 0; | ||
4432 | int shortest_trail_length = -1; | ||
4433 | struct Trail_Element *trail_element; | ||
4434 | struct GNUNET_PeerIdentity *trail_list; | ||
4435 | unsigned int i; | ||
4436 | |||
4437 | /* Get the shortest trail to reach to current successor. */ | ||
4438 | for (i = 0; i < finger->trails_count; i++) | ||
4439 | { | ||
4440 | trail = &finger->trail_list[i]; | ||
4441 | |||
4442 | if (0 == flag) | ||
4443 | { | ||
4444 | shortest_trail_index = i; | ||
4445 | shortest_trail_length = trail->trail_length; | ||
4446 | flag = 1; | ||
4447 | continue; | ||
4448 | } | ||
4449 | |||
4450 | if (shortest_trail_length > trail->trail_length) | ||
4451 | { | ||
4452 | shortest_trail_index = i; | ||
4453 | shortest_trail_length = trail->trail_length; | ||
4454 | } | ||
4455 | continue; | ||
4456 | } | ||
4457 | |||
4458 | /* Copy the shortest trail and return. */ | ||
4459 | trail = &finger->trail_list[shortest_trail_index]; | ||
4460 | trail_element = trail->trail_head; | ||
4461 | |||
4462 | trail_list = GNUNET_new_array (shortest_trail_length, | ||
4463 | struct GNUNET_PeerIdentity); | ||
4464 | |||
4465 | for (i = 0; i < shortest_trail_length; i++,trail_element = trail_element->next) | ||
4466 | { | ||
4467 | trail_list[i] = trail_element->peer; | ||
4468 | } | ||
4469 | |||
4470 | GNUNET_assert(shortest_trail_length != -1); | ||
4471 | |||
4472 | *trail_length = shortest_trail_length; | ||
4473 | return trail_list; | ||
4474 | } | ||
4475 | |||
4476 | |||
4477 | /** | ||
4478 | * Check if @a trail_1 and @a trail_2 have any common element. If yes then join | ||
4479 | * them at common element. @a trail_1 always preceeds @a trail_2 in joined trail. | ||
4480 | * | ||
4481 | * @param trail_1 Trail from source to me, NOT including endpoints. | ||
4482 | * @param trail_1_len Total number of peers @a trail_1 | ||
4483 | * @param trail_2 Trail from me to current predecessor, NOT including endpoints. | ||
4484 | * @param trail_2_len Total number of peers @a trail_2 | ||
4485 | * @param joined_trail_len Total number of peers in combined trail of @a trail_1 | ||
4486 | * @a trail_2. | ||
4487 | * @return Joined trail. | ||
4488 | */ | ||
4489 | static struct GNUNET_PeerIdentity * | ||
4490 | check_for_duplicate_entries (const struct GNUNET_PeerIdentity *trail_1, | ||
4491 | unsigned int trail_1_len, | ||
4492 | const struct GNUNET_PeerIdentity *trail_2, | ||
4493 | unsigned int trail_2_len, | ||
4494 | unsigned int *joined_trail_len) | ||
4495 | { | ||
4496 | struct GNUNET_PeerIdentity *joined_trail; | ||
4497 | unsigned int i; | ||
4498 | unsigned int j; | ||
4499 | unsigned int k; | ||
4500 | |||
4501 | for (i = 0; i < trail_1_len; i++) | ||
4502 | { | ||
4503 | for (j = 0; j < trail_2_len; j++) | ||
4504 | { | ||
4505 | if (0 != GNUNET_CRYPTO_cmp_peer_identity (&trail_1[i], | ||
4506 | &trail_2[j])) | ||
4507 | continue; | ||
4508 | |||
4509 | *joined_trail_len = i + (trail_2_len - j); | ||
4510 | joined_trail = GNUNET_new_array (*joined_trail_len, | ||
4511 | struct GNUNET_PeerIdentity); | ||
4512 | |||
4513 | |||
4514 | /* Copy all the elements from 0 to i into joined_trail. */ | ||
4515 | for(k = 0; k < ( i+1); k++) | ||
4516 | { | ||
4517 | joined_trail[k] = trail_1[k]; | ||
4518 | } | ||
4519 | |||
4520 | /* Increment j as entry stored is same as entry stored at i*/ | ||
4521 | j = j+1; | ||
4522 | |||
4523 | /* Copy all the elements from j to trail_2_len-1 to joined trail.*/ | ||
4524 | while(k <= (*joined_trail_len - 1)) | ||
4525 | { | ||
4526 | joined_trail[k] = trail_2[j]; | ||
4527 | j++; | ||
4528 | k++; | ||
4529 | } | ||
4530 | |||
4531 | return joined_trail; | ||
4532 | } | ||
4533 | } | ||
4534 | |||
4535 | /* Here you should join the trails. */ | ||
4536 | *joined_trail_len = trail_1_len + trail_2_len + 1; | ||
4537 | joined_trail = GNUNET_new_array (*joined_trail_len, | ||
4538 | struct GNUNET_PeerIdentity); | ||
4539 | |||
4540 | |||
4541 | for(i = 0; i < trail_1_len;i++) | ||
4542 | { | ||
4543 | joined_trail[i] = trail_1[i]; | ||
4544 | } | ||
4545 | |||
4546 | joined_trail[i] = my_identity; | ||
4547 | i++; | ||
4548 | |||
4549 | for (j = 0; i < *joined_trail_len; i++,j++) | ||
4550 | { | ||
4551 | joined_trail[i] = trail_2[j]; | ||
4552 | } | ||
4553 | |||
4554 | return joined_trail; | ||
4555 | } | ||
4556 | |||
4557 | |||
4558 | /** | ||
4559 | * Return the trail from source to my current predecessor. Check if source | ||
4560 | * is already part of the this trail, if yes then return the shorten trail. | ||
4561 | * | ||
4562 | * @param current_trail Trail from source to me, NOT including the endpoints. | ||
4563 | * @param current_trail_length Number of peers in @a current_trail. | ||
4564 | * @param trail_src_to_curr_pred_length[out] Number of peers in trail from | ||
4565 | * source to my predecessor, NOT including | ||
4566 | * the endpoints. | ||
4567 | * @return Trail from source to my predecessor. | ||
4568 | */ | ||
4569 | static struct GNUNET_PeerIdentity * | ||
4570 | get_trail_src_to_curr_pred (struct GNUNET_PeerIdentity source_peer, | ||
4571 | const struct GNUNET_PeerIdentity *trail_src_to_me, | ||
4572 | unsigned int trail_src_to_me_len, | ||
4573 | unsigned int *trail_src_to_curr_pred_length) | ||
4574 | { | ||
4575 | struct GNUNET_PeerIdentity *trail_me_to_curr_pred; | ||
4576 | struct GNUNET_PeerIdentity *trail_src_to_curr_pred; | ||
4577 | unsigned int trail_me_to_curr_pred_length; | ||
4578 | struct FingerInfo *current_predecessor; | ||
4579 | int i; | ||
4580 | unsigned int j; | ||
4581 | unsigned int len; | ||
4582 | |||
4583 | current_predecessor = &finger_table[PREDECESSOR_FINGER_ID]; | ||
4584 | |||
4585 | /* Check if trail_src_to_me contains current_predecessor. */ | ||
4586 | for (i = 0; i < trail_src_to_me_len; i++) | ||
4587 | { | ||
4588 | if (0 != GNUNET_CRYPTO_cmp_peer_identity(&trail_src_to_me[i], | ||
4589 | ¤t_predecessor->finger_identity)) | ||
4590 | continue; | ||
4591 | |||
4592 | |||
4593 | *trail_src_to_curr_pred_length = i; | ||
4594 | |||
4595 | if(0 == i) | ||
4596 | return NULL; | ||
4597 | |||
4598 | trail_src_to_curr_pred = GNUNET_new_array (*trail_src_to_curr_pred_length, | ||
4599 | struct GNUNET_PeerIdentity); | ||
4600 | for (j = 0; j < i; j++) | ||
4601 | trail_src_to_curr_pred[j] = trail_src_to_me[j]; | ||
4602 | return trail_src_to_curr_pred; | ||
4603 | } | ||
4604 | |||
4605 | |||
4606 | trail_me_to_curr_pred = get_shortest_trail (current_predecessor, | ||
4607 | &trail_me_to_curr_pred_length); | ||
4608 | |||
4609 | /* Check if trail contains the source_peer. */ | ||
4610 | for (i = trail_me_to_curr_pred_length - 1; i >= 0; i--) | ||
4611 | { | ||
4612 | if (0 != GNUNET_CRYPTO_cmp_peer_identity (&source_peer, | ||
4613 | &trail_me_to_curr_pred[i])) | ||
4614 | continue; | ||
4615 | |||
4616 | /* Source is NOT part of trail. */ | ||
4617 | i++; | ||
4618 | |||
4619 | /* Source is the last element in the trail to reach to my pred. | ||
4620 | Source is direct friend of the pred. */ | ||
4621 | if (trail_me_to_curr_pred_length == i) | ||
4622 | { | ||
4623 | *trail_src_to_curr_pred_length = 0; | ||
4624 | GNUNET_free_non_null (trail_me_to_curr_pred); | ||
4625 | return NULL; | ||
4626 | } | ||
4627 | |||
4628 | *trail_src_to_curr_pred_length = trail_me_to_curr_pred_length - i; | ||
4629 | trail_src_to_curr_pred = GNUNET_new_array (*trail_src_to_curr_pred_length, | ||
4630 | struct GNUNET_PeerIdentity); | ||
4631 | |||
4632 | |||
4633 | for (j = 0; j < *trail_src_to_curr_pred_length; i++,j++) | ||
4634 | trail_src_to_curr_pred[j] = trail_me_to_curr_pred[i]; | ||
4635 | GNUNET_free_non_null (trail_me_to_curr_pred); | ||
4636 | return trail_src_to_curr_pred; | ||
4637 | } | ||
4638 | |||
4639 | trail_src_to_curr_pred = check_for_duplicate_entries (trail_src_to_me, | ||
4640 | trail_src_to_me_len, | ||
4641 | trail_me_to_curr_pred, | ||
4642 | trail_me_to_curr_pred_length, | ||
4643 | &len); | ||
4644 | *trail_src_to_curr_pred_length = len; | ||
4645 | GNUNET_free_non_null(trail_me_to_curr_pred); | ||
4646 | return trail_src_to_curr_pred; | ||
4647 | } | ||
4648 | |||
4649 | |||
4650 | /** | ||
4651 | * Add finger as your predecessor. To add, first generate a new trail id, invert | ||
4652 | * the trail to get the trail from me to finger, add an entry in your routing | ||
4653 | * table, send add trail message to peers which are part of trail from me to | ||
4654 | * finger and add finger in finger table. | ||
4655 | * | ||
4656 | * @param finger | ||
4657 | * @param trail | ||
4658 | * @param trail_length | ||
4659 | */ | ||
4660 | static void | ||
4661 | update_predecessor (const struct GNUNET_PeerIdentity *finger, | ||
4662 | const struct GNUNET_PeerIdentity *trail, | ||
4663 | unsigned int trail_length) | ||
4664 | { | ||
4665 | struct GNUNET_HashCode trail_to_new_predecessor_id; | ||
4666 | struct GNUNET_PeerIdentity *trail_to_new_predecessor; | ||
4667 | struct FriendInfo *target_friend; | ||
4668 | |||
4669 | /* Generate trail id for trail from me to new predecessor = finger. */ | ||
4670 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG, | ||
4671 | &trail_to_new_predecessor_id, | ||
4672 | sizeof (trail_to_new_predecessor_id)); | ||
4673 | |||
4674 | if (0 == trail_length) | ||
4675 | { | ||
4676 | trail_to_new_predecessor = NULL; | ||
4677 | GDS_ROUTING_add (&trail_to_new_predecessor_id, | ||
4678 | &my_identity, | ||
4679 | finger); | ||
4680 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
4681 | finger); | ||
4682 | if (NULL == target_friend) | ||
4683 | { | ||
4684 | GNUNET_break (0); | ||
4685 | return; | ||
4686 | } | ||
4687 | } | ||
4688 | else | ||
4689 | { | ||
4690 | /* Invert the trail to get the trail from me to finger, NOT including the | ||
4691 | endpoints.*/ | ||
4692 | GNUNET_assert(NULL != GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
4693 | &trail[trail_length-1])); | ||
4694 | trail_to_new_predecessor = invert_trail (trail, | ||
4695 | trail_length); | ||
4696 | |||
4697 | /* Add an entry in your routing table. */ | ||
4698 | GDS_ROUTING_add (&trail_to_new_predecessor_id, | ||
4699 | &my_identity, | ||
4700 | &trail_to_new_predecessor[0]); | ||
4701 | |||
4702 | GNUNET_assert (NULL != (target_friend = | ||
4703 | GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
4704 | &trail_to_new_predecessor[0]))); | ||
4705 | } | ||
4706 | |||
4707 | /* Add entry in routing table of all peers that are part of trail from me | ||
4708 | to finger, including finger. */ | ||
4709 | GDS_NEIGHBOURS_send_add_trail (&my_identity, | ||
4710 | finger, | ||
4711 | &trail_to_new_predecessor_id, | ||
4712 | trail_to_new_predecessor, | ||
4713 | trail_length, | ||
4714 | target_friend); | ||
4715 | |||
4716 | add_new_finger (finger, | ||
4717 | trail_to_new_predecessor, | ||
4718 | trail_length, | ||
4719 | &trail_to_new_predecessor_id, | ||
4720 | PREDECESSOR_FINGER_ID); | ||
4721 | GNUNET_free_non_null (trail_to_new_predecessor); | ||
4722 | } | ||
4723 | |||
4724 | |||
4725 | /** | ||
4726 | * Check if you already have a predecessor. If not then add finger as your | ||
4727 | * predecessor. If you have predecessor, then compare two peer identites. | ||
4728 | * If finger is correct predecessor, then remove the old entry, add finger in | ||
4729 | * finger table and send add_trail message to add the trail in the routing | ||
4730 | * table of all peers which are part of trail to reach from me to finger. | ||
4731 | * @param finger New peer which may be our predecessor. | ||
4732 | * @param trail List of peers to reach from @finger to me. | ||
4733 | * @param trail_length Total number of peer in @a trail. | ||
4734 | */ | ||
4735 | static void | ||
4736 | compare_and_update_predecessor (const struct GNUNET_PeerIdentity *finger, | ||
4737 | const struct GNUNET_PeerIdentity *trail, | ||
4738 | unsigned int trail_length) | ||
4739 | { | ||
4740 | struct FingerInfo *current_predecessor; | ||
4741 | const struct GNUNET_PeerIdentity *closest_peer; | ||
4742 | uint64_t predecessor_value; | ||
4743 | unsigned int is_predecessor = 1; | ||
4744 | |||
4745 | current_predecessor = &finger_table[PREDECESSOR_FINGER_ID]; | ||
4746 | GNUNET_assert (0 != GNUNET_CRYPTO_cmp_peer_identity (finger, | ||
4747 | &my_identity)); | ||
4748 | |||
4749 | /* No predecessor. Add finger as your predecessor. */ | ||
4750 | if (GNUNET_NO == current_predecessor->is_present) | ||
4751 | { | ||
4752 | update_predecessor (finger, | ||
4753 | trail, | ||
4754 | trail_length); | ||
4755 | return; | ||
4756 | } | ||
4757 | |||
4758 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (¤t_predecessor->finger_identity, | ||
4759 | finger)) | ||
4760 | { | ||
4761 | return; | ||
4762 | } | ||
4763 | |||
4764 | predecessor_value = compute_finger_identity_value (PREDECESSOR_FINGER_ID); | ||
4765 | closest_peer = select_closest_peer (finger, | ||
4766 | ¤t_predecessor->finger_identity, | ||
4767 | predecessor_value, | ||
4768 | is_predecessor); | ||
4769 | |||
4770 | /* Finger is the closest predecessor. Remove the existing one and add the new | ||
4771 | one. */ | ||
4772 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (closest_peer, | ||
4773 | finger)) | ||
4774 | { | ||
4775 | remove_existing_finger (current_predecessor, | ||
4776 | PREDECESSOR_FINGER_ID); | ||
4777 | update_predecessor (finger, | ||
4778 | trail, | ||
4779 | trail_length); | ||
4780 | return; | ||
4781 | } | ||
4782 | } | ||
4783 | |||
4784 | |||
4785 | /** | ||
4786 | * Check format of a p2p verify successor messages. | ||
4787 | * | ||
4788 | * @param cls closure | ||
4789 | * @param vsm the message | ||
4790 | * @return #GNUNET_OK if @a vsm is well-formed | ||
4791 | */ | ||
4792 | static int | ||
4793 | check_dht_p2p_verify_successor (void *cls, | ||
4794 | const struct PeerVerifySuccessorMessage *vsm) | ||
4795 | { | ||
4796 | size_t msize; | ||
4797 | |||
4798 | msize = ntohs (vsm->header.size); | ||
4799 | if ((msize - sizeof (struct PeerVerifySuccessorMessage)) % | ||
4800 | sizeof (struct GNUNET_PeerIdentity) != 0) | ||
4801 | { | ||
4802 | GNUNET_break_op (0); | ||
4803 | return GNUNET_SYSERR; | ||
4804 | } | ||
4805 | return GNUNET_OK; | ||
4806 | } | ||
4807 | |||
4808 | |||
4809 | /** | ||
4810 | * Core handle for p2p verify successor messages. | ||
4811 | * | ||
4812 | * @param cls closure | ||
4813 | * @param vsm the message | ||
4814 | */ | ||
4815 | static void | ||
4816 | handle_dht_p2p_verify_successor (void *cls, | ||
4817 | const struct PeerVerifySuccessorMessage *vsm) | ||
4818 | { | ||
4819 | struct FriendInfo *friend = cls; | ||
4820 | struct GNUNET_HashCode trail_id; | ||
4821 | struct GNUNET_PeerIdentity successor; | ||
4822 | struct GNUNET_PeerIdentity source_peer; | ||
4823 | struct GNUNET_PeerIdentity *trail; | ||
4824 | const struct GNUNET_PeerIdentity *next_hop; | ||
4825 | struct FingerInfo current_predecessor; | ||
4826 | struct FriendInfo *target_friend; | ||
4827 | unsigned int trail_src_to_curr_pred_len = 0; | ||
4828 | struct GNUNET_PeerIdentity *trail_src_to_curr_pred; | ||
4829 | unsigned int trail_length; | ||
4830 | size_t msize; | ||
4831 | |||
4832 | msize = ntohs (vsm->header.size); | ||
4833 | trail_length = (msize - sizeof (struct PeerVerifySuccessorMessage))/ | ||
4834 | sizeof (struct GNUNET_PeerIdentity); | ||
4835 | GNUNET_STATISTICS_update (GDS_stats, | ||
4836 | gettext_noop ("# Bytes received from other peers"), | ||
4837 | msize, | ||
4838 | GNUNET_NO); | ||
4839 | |||
4840 | trail_id = vsm->trail_id; | ||
4841 | source_peer = vsm->source_peer; | ||
4842 | successor = vsm->successor; | ||
4843 | trail = (struct GNUNET_PeerIdentity *)&vsm[1]; | ||
4844 | |||
4845 | /* I am NOT the successor of source_peer. Pass the message to next_hop on | ||
4846 | * the trail. */ | ||
4847 | if (0 != (GNUNET_CRYPTO_cmp_peer_identity (&successor, | ||
4848 | &my_identity))) | ||
4849 | { | ||
4850 | next_hop = GDS_ROUTING_get_next_hop (&trail_id, | ||
4851 | GDS_ROUTING_SRC_TO_DEST); | ||
4852 | if (NULL == next_hop) | ||
4853 | return; | ||
4854 | |||
4855 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
4856 | next_hop); | ||
4857 | if (NULL == target_friend) | ||
4858 | { | ||
4859 | GNUNET_break_op(0); | ||
4860 | return; | ||
4861 | } | ||
4862 | GDS_NEIGHBOURS_send_verify_successor_message (&source_peer, | ||
4863 | &successor, | ||
4864 | &trail_id, | ||
4865 | trail, | ||
4866 | trail_length, | ||
4867 | target_friend); | ||
4868 | return; | ||
4869 | } | ||
4870 | |||
4871 | /* I am the destination of this message. */ | ||
4872 | /* Check if the source_peer could be our predecessor and if yes then update | ||
4873 | * it. */ | ||
4874 | compare_and_update_predecessor (&source_peer, | ||
4875 | trail, | ||
4876 | trail_length); | ||
4877 | current_predecessor = finger_table[PREDECESSOR_FINGER_ID]; | ||
4878 | |||
4879 | /* Is source of this message NOT my predecessor. */ | ||
4880 | if (0 != (GNUNET_CRYPTO_cmp_peer_identity (¤t_predecessor.finger_identity, | ||
4881 | &source_peer))) | ||
4882 | { | ||
4883 | trail_src_to_curr_pred | ||
4884 | = get_trail_src_to_curr_pred (source_peer, | ||
4885 | trail, | ||
4886 | trail_length, | ||
4887 | &trail_src_to_curr_pred_len); | ||
4888 | } | ||
4889 | else | ||
4890 | { | ||
4891 | trail_src_to_curr_pred_len = trail_length; | ||
4892 | trail_src_to_curr_pred = GNUNET_new_array (trail_src_to_curr_pred_len, | ||
4893 | struct GNUNET_PeerIdentity); | ||
4894 | |||
4895 | for (unsigned int i = 0; i < trail_src_to_curr_pred_len; i++) | ||
4896 | { | ||
4897 | trail_src_to_curr_pred[i] = trail[i]; | ||
4898 | } | ||
4899 | } | ||
4900 | |||
4901 | GNUNET_assert (NULL != | ||
4902 | (target_friend = | ||
4903 | GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
4904 | friend->id))); | ||
4905 | GDS_NEIGHBOURS_send_verify_successor_result (&source_peer, | ||
4906 | &my_identity, | ||
4907 | ¤t_predecessor.finger_identity, | ||
4908 | &trail_id, | ||
4909 | trail_src_to_curr_pred, | ||
4910 | trail_src_to_curr_pred_len, | ||
4911 | GDS_ROUTING_DEST_TO_SRC, | ||
4912 | target_friend); | ||
4913 | GNUNET_free_non_null (trail_src_to_curr_pred); | ||
4914 | } | ||
4915 | |||
4916 | |||
4917 | /** | ||
4918 | * If the trail from me to my probable successor contains a friend not | ||
4919 | * at index 0, then we can shorten the trail. | ||
4920 | * | ||
4921 | * @param probable_successor Peer which is our probable successor | ||
4922 | * @param trail_me_to_probable_successor Peers in path from me to my probable | ||
4923 | * successor, NOT including the endpoints. | ||
4924 | * @param trail_me_to_probable_successor_len Total number of peers in | ||
4925 | * @a trail_me_to_probable_succesor. | ||
4926 | * @return Updated trail, if any friend found. | ||
4927 | * Else the trail_me_to_probable_successor. | ||
4928 | */ | ||
4929 | const struct GNUNET_PeerIdentity * | ||
4930 | check_trail_me_to_probable_succ (const struct GNUNET_PeerIdentity *probable_successor, | ||
4931 | const struct GNUNET_PeerIdentity *trail_me_to_probable_successor, | ||
4932 | unsigned int trail_me_to_probable_successor_len, | ||
4933 | unsigned int *trail_to_new_successor_length) | ||
4934 | { | ||
4935 | unsigned int i; | ||
4936 | unsigned int j; | ||
4937 | struct GNUNET_PeerIdentity *trail_to_new_successor; | ||
4938 | |||
4939 | /* Probable successor is a friend */ | ||
4940 | if (NULL != GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
4941 | probable_successor)) | ||
4942 | { | ||
4943 | trail_to_new_successor = NULL; | ||
4944 | *trail_to_new_successor_length = 0; | ||
4945 | return trail_to_new_successor; | ||
4946 | } | ||
4947 | |||
4948 | /* Is there any friend of yours in this trail. */ | ||
4949 | if (trail_me_to_probable_successor_len > 1) | ||
4950 | { | ||
4951 | for (i = trail_me_to_probable_successor_len - 1; i > 0; i--) | ||
4952 | { | ||
4953 | if (NULL == GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
4954 | &trail_me_to_probable_successor[i])) | ||
4955 | continue; | ||
4956 | |||
4957 | *trail_to_new_successor_length = (trail_me_to_probable_successor_len - i); | ||
4958 | trail_to_new_successor = GNUNET_new_array (*trail_to_new_successor_length, | ||
4959 | struct GNUNET_PeerIdentity); | ||
4960 | for (j = 0; j < *trail_to_new_successor_length; i++,j++) | ||
4961 | { | ||
4962 | trail_to_new_successor[j] = trail_me_to_probable_successor[i]; | ||
4963 | } | ||
4964 | |||
4965 | return trail_to_new_successor; | ||
4966 | } | ||
4967 | } | ||
4968 | |||
4969 | *trail_to_new_successor_length = trail_me_to_probable_successor_len; | ||
4970 | return trail_me_to_probable_successor; | ||
4971 | } | ||
4972 | |||
4973 | |||
4974 | // TODO: Move up | ||
4975 | struct SendNotifyContext | ||
4976 | { | ||
4977 | struct GNUNET_PeerIdentity source_peer; | ||
4978 | struct GNUNET_PeerIdentity successor; | ||
4979 | struct GNUNET_PeerIdentity *successor_trail; | ||
4980 | unsigned int successor_trail_length; | ||
4981 | struct GNUNET_HashCode succesor_trail_id; | ||
4982 | struct FriendInfo *target_friend; | ||
4983 | unsigned int num_retries_scheduled; | ||
4984 | }; | ||
4985 | |||
4986 | |||
4987 | void | ||
4988 | send_notify_new_successor (void *cls); | ||
4989 | |||
4990 | |||
4991 | /** | ||
4992 | * Check if the peer which sent us verify successor result message is still ours | ||
4993 | * successor or not. If not, then compare existing successor and probable successor. | ||
4994 | * In case probable successor is the correct successor, remove the existing | ||
4995 | * successor. Add probable successor as new successor. Send notify new successor | ||
4996 | * message to new successor. | ||
4997 | * @param curr_succ Peer to which we sent the verify successor message. It may | ||
4998 | * or may not be our real current successor, as we may have few iterations of | ||
4999 | * find finger trail task. | ||
5000 | * @param probable_successor Peer which should be our successor accroding to @a | ||
5001 | * curr_succ | ||
5002 | * @param trail List of peers to reach from me to @a probable successor, NOT including | ||
5003 | * endpoints. | ||
5004 | * @param trail_length Total number of peers in @a trail. | ||
5005 | */ | ||
5006 | static void | ||
5007 | compare_and_update_successor (const struct GNUNET_PeerIdentity *curr_succ, | ||
5008 | const struct GNUNET_PeerIdentity *probable_successor, | ||
5009 | const struct GNUNET_PeerIdentity *trail, | ||
5010 | unsigned int trail_length) | ||
5011 | { | ||
5012 | struct FingerInfo *current_successor; | ||
5013 | const struct GNUNET_PeerIdentity *closest_peer; | ||
5014 | struct GNUNET_HashCode trail_id; | ||
5015 | const struct GNUNET_PeerIdentity *trail_me_to_probable_succ; | ||
5016 | struct FriendInfo *target_friend; | ||
5017 | unsigned int trail_me_to_probable_succ_len; | ||
5018 | unsigned int is_predecessor = 0; | ||
5019 | uint64_t successor_value; | ||
5020 | struct SendNotifyContext *notify_ctx; | ||
5021 | |||
5022 | current_successor = &finger_table[0]; | ||
5023 | successor_value = compute_finger_identity_value(0); | ||
5024 | |||
5025 | /* If probable successor is same as current_successor, do nothing. */ | ||
5026 | if(0 == GNUNET_CRYPTO_cmp_peer_identity (probable_successor, | ||
5027 | ¤t_successor->finger_identity)) | ||
5028 | { | ||
5029 | if ((NULL != GDS_stats)) | ||
5030 | { | ||
5031 | char *my_id_str; | ||
5032 | uint64_t succ; | ||
5033 | char *key; | ||
5034 | uint64_t my_id; | ||
5035 | GNUNET_memcpy (&my_id, &my_identity, sizeof(uint64_t)); | ||
5036 | my_id_str = GNUNET_strdup (GNUNET_i2s_full (&my_identity)); | ||
5037 | GNUNET_memcpy (&succ, | ||
5038 | ¤t_successor->finger_identity, | ||
5039 | sizeof(uint64_t)); | ||
5040 | succ = GNUNET_ntohll(succ); | ||
5041 | GNUNET_asprintf (&key, | ||
5042 | "XDHT:%s:", | ||
5043 | my_id_str); | ||
5044 | GNUNET_free (my_id_str); | ||
5045 | |||
5046 | GNUNET_STATISTICS_set (GDS_stats, key, succ, 0); | ||
5047 | GNUNET_free (key); | ||
5048 | } | ||
5049 | if (send_verify_successor_task == NULL) | ||
5050 | send_verify_successor_task = | ||
5051 | GNUNET_SCHEDULER_add_delayed(verify_successor_next_send_time, | ||
5052 | &send_verify_successor_message, | ||
5053 | NULL); | ||
5054 | return; | ||
5055 | } | ||
5056 | closest_peer = select_closest_peer (probable_successor, | ||
5057 | ¤t_successor->finger_identity, | ||
5058 | successor_value, | ||
5059 | is_predecessor); | ||
5060 | |||
5061 | /* If the current_successor in the finger table is closest, then do nothing. */ | ||
5062 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (closest_peer, | ||
5063 | ¤t_successor->finger_identity)) | ||
5064 | { | ||
5065 | //FIXME: Is this a good place to return the stats. | ||
5066 | if ((NULL != GDS_stats)) | ||
5067 | { | ||
5068 | char *my_id_str; | ||
5069 | uint64_t succ; | ||
5070 | char *key; | ||
5071 | |||
5072 | my_id_str = GNUNET_strdup (GNUNET_i2s_full (&my_identity)); | ||
5073 | GNUNET_memcpy(&succ, ¤t_successor->finger_identity, sizeof(uint64_t)); | ||
5074 | GNUNET_asprintf (&key, "XDHT:%s:", my_id_str); | ||
5075 | GNUNET_free (my_id_str); | ||
5076 | GNUNET_STATISTICS_set (GDS_stats, key, succ, 0); | ||
5077 | GNUNET_free (key); | ||
5078 | } | ||
5079 | |||
5080 | if(0 == successor_times) | ||
5081 | { | ||
5082 | // successor_times = 3; | ||
5083 | verify_successor_next_send_time = | ||
5084 | GNUNET_TIME_STD_BACKOFF (verify_successor_next_send_time); | ||
5085 | } | ||
5086 | else | ||
5087 | successor_times--; | ||
5088 | |||
5089 | |||
5090 | if (send_verify_successor_task == NULL) | ||
5091 | send_verify_successor_task = | ||
5092 | GNUNET_SCHEDULER_add_delayed (verify_successor_next_send_time, | ||
5093 | &send_verify_successor_message, | ||
5094 | NULL); | ||
5095 | return; | ||
5096 | } | ||
5097 | |||
5098 | /* Probable successor is the closest peer.*/ | ||
5099 | if(trail_length > 0) | ||
5100 | { | ||
5101 | GNUNET_assert(NULL != GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
5102 | &trail[0])); | ||
5103 | } | ||
5104 | else | ||
5105 | { | ||
5106 | GNUNET_assert(NULL != GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
5107 | probable_successor)); | ||
5108 | } | ||
5109 | |||
5110 | trail_me_to_probable_succ_len = 0; | ||
5111 | trail_me_to_probable_succ = check_trail_me_to_probable_succ (probable_successor, | ||
5112 | trail, | ||
5113 | trail_length, | ||
5114 | &trail_me_to_probable_succ_len); | ||
5115 | |||
5116 | /* Remove the existing successor. */ | ||
5117 | remove_existing_finger (current_successor, 0); | ||
5118 | /* Generate a new trail id to reach to your new successor. */ | ||
5119 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG, | ||
5120 | &trail_id, | ||
5121 | sizeof (trail_id)); | ||
5122 | |||
5123 | if (trail_me_to_probable_succ_len > 0) | ||
5124 | { | ||
5125 | GDS_ROUTING_add (&trail_id, | ||
5126 | &my_identity, | ||
5127 | &trail_me_to_probable_succ[0]); | ||
5128 | GNUNET_assert (NULL != | ||
5129 | (target_friend = | ||
5130 | GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
5131 | &trail_me_to_probable_succ[0]))); | ||
5132 | } | ||
5133 | else | ||
5134 | { | ||
5135 | GDS_ROUTING_add (&trail_id, | ||
5136 | &my_identity, | ||
5137 | probable_successor); | ||
5138 | GNUNET_assert (NULL != | ||
5139 | (target_friend = | ||
5140 | GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
5141 | probable_successor))); | ||
5142 | } | ||
5143 | |||
5144 | add_new_finger (probable_successor, | ||
5145 | trail_me_to_probable_succ, | ||
5146 | trail_me_to_probable_succ_len, | ||
5147 | &trail_id, | ||
5148 | 0); | ||
5149 | |||
5150 | notify_ctx = GNUNET_new (struct SendNotifyContext); | ||
5151 | |||
5152 | notify_ctx->source_peer = my_identity; | ||
5153 | notify_ctx->successor = *probable_successor; | ||
5154 | notify_ctx->successor_trail = GNUNET_new_array (trail_me_to_probable_succ_len, | ||
5155 | struct GNUNET_PeerIdentity); | ||
5156 | GNUNET_memcpy (notify_ctx->successor_trail, | ||
5157 | trail_me_to_probable_succ, | ||
5158 | sizeof(struct GNUNET_PeerIdentity) * trail_me_to_probable_succ_len); | ||
5159 | notify_ctx->successor_trail_length = trail_me_to_probable_succ_len; | ||
5160 | notify_ctx->succesor_trail_id = trail_id; | ||
5161 | notify_ctx->target_friend = target_friend; | ||
5162 | notify_ctx->num_retries_scheduled = 0; | ||
5163 | |||
5164 | // TODO: Check if we should verify before schedule if already scheduled. | ||
5165 | GNUNET_SCHEDULER_add_now (&send_notify_new_successor, | ||
5166 | notify_ctx); | ||
5167 | } | ||
5168 | |||
5169 | |||
5170 | void | ||
5171 | send_notify_new_successor (void *cls) | ||
5172 | { | ||
5173 | struct SendNotifyContext *ctx = cls; | ||
5174 | |||
5175 | GDS_NEIGHBOURS_send_notify_new_successor (&ctx->source_peer, | ||
5176 | &ctx->successor, | ||
5177 | ctx->successor_trail, | ||
5178 | ctx->successor_trail_length, | ||
5179 | &ctx->succesor_trail_id, | ||
5180 | ctx->target_friend); | ||
5181 | |||
5182 | if ( (0 == ctx->num_retries_scheduled) && | ||
5183 | (send_notify_new_successor_retry_task != NULL) ) | ||
5184 | { | ||
5185 | // Result from previous notify successos hasn't arrived, so the retry task | ||
5186 | // hasn't been cancelled! Already a new notify successor must be called. | ||
5187 | // We will cancel the retry request. | ||
5188 | struct SendNotifyContext *old_notify_ctx; | ||
5189 | |||
5190 | old_notify_ctx = GNUNET_SCHEDULER_cancel(send_notify_new_successor_retry_task); | ||
5191 | GNUNET_free (old_notify_ctx->successor_trail); | ||
5192 | GNUNET_free (old_notify_ctx); | ||
5193 | send_notify_new_successor_retry_task = NULL; | ||
5194 | } | ||
5195 | |||
5196 | ctx->num_retries_scheduled++; | ||
5197 | send_notify_new_successor_retry_task | ||
5198 | = GNUNET_SCHEDULER_add_delayed (notify_successor_retry_time, | ||
5199 | &send_notify_new_successor, | ||
5200 | cls); | ||
5201 | } | ||
5202 | |||
5203 | |||
5204 | /** | ||
5205 | * Check integrity of verify successor result messages. | ||
5206 | * | ||
5207 | * @param cls closure | ||
5208 | * @param vsrm the message | ||
5209 | * @return #GNUNET_OK if @a vrsm is well-formed | ||
5210 | */ | ||
5211 | static int | ||
5212 | check_dht_p2p_verify_successor_result (void *cls, | ||
5213 | const struct PeerVerifySuccessorResultMessage *vsrm) | ||
5214 | { | ||
5215 | size_t msize; | ||
5216 | |||
5217 | msize = ntohs (vsrm->header.size); | ||
5218 | if ((msize - sizeof (struct PeerVerifySuccessorResultMessage)) % | ||
5219 | sizeof (struct GNUNET_PeerIdentity) != 0) | ||
5220 | { | ||
5221 | GNUNET_break_op (0); | ||
5222 | return GNUNET_SYSERR; | ||
5223 | } | ||
5224 | return GNUNET_OK; | ||
5225 | } | ||
5226 | |||
5227 | |||
5228 | /** | ||
5229 | * Core handle for p2p verify successor result messages. | ||
5230 | * | ||
5231 | * @param cls closure | ||
5232 | * @param vsrm the message | ||
5233 | */ | ||
5234 | static void | ||
5235 | handle_dht_p2p_verify_successor_result (void *cls, | ||
5236 | const struct PeerVerifySuccessorResultMessage *vsrm) | ||
5237 | { | ||
5238 | enum GDS_ROUTING_trail_direction trail_direction; | ||
5239 | struct GNUNET_PeerIdentity querying_peer; | ||
5240 | struct GNUNET_HashCode trail_id; | ||
5241 | const struct GNUNET_PeerIdentity *next_hop; | ||
5242 | struct FriendInfo *target_friend; | ||
5243 | struct GNUNET_PeerIdentity probable_successor; | ||
5244 | struct GNUNET_PeerIdentity current_successor; | ||
5245 | const struct GNUNET_PeerIdentity *trail; | ||
5246 | unsigned int trail_length; | ||
5247 | size_t msize; | ||
5248 | |||
5249 | msize = ntohs (vsrm->header.size); | ||
5250 | trail_length = (msize - sizeof (struct PeerVerifySuccessorResultMessage)) | ||
5251 | / sizeof (struct GNUNET_PeerIdentity); | ||
5252 | |||
5253 | GNUNET_STATISTICS_update (GDS_stats, | ||
5254 | gettext_noop ("# Bytes received from other peers"), | ||
5255 | msize, | ||
5256 | GNUNET_NO); | ||
5257 | |||
5258 | trail = (const struct GNUNET_PeerIdentity *) &vsrm[1]; | ||
5259 | querying_peer = vsrm->querying_peer; | ||
5260 | trail_direction = ntohl (vsrm->trail_direction); | ||
5261 | trail_id = vsrm->trail_id; | ||
5262 | probable_successor = vsrm->probable_successor; | ||
5263 | current_successor = vsrm->current_successor; | ||
5264 | |||
5265 | /* Am I the querying_peer? */ | ||
5266 | if (0 == (GNUNET_CRYPTO_cmp_peer_identity (&querying_peer, | ||
5267 | &my_identity))) | ||
5268 | { | ||
5269 | /* Cancel Retry Task */ | ||
5270 | if (NULL != send_verify_successor_retry_task) | ||
5271 | { | ||
5272 | struct VerifySuccessorContext *ctx; | ||
5273 | |||
5274 | ctx = GNUNET_SCHEDULER_cancel (send_verify_successor_retry_task); | ||
5275 | GNUNET_free (ctx); | ||
5276 | send_verify_successor_retry_task = NULL; | ||
5277 | } | ||
5278 | compare_and_update_successor (¤t_successor, | ||
5279 | &probable_successor, | ||
5280 | trail, | ||
5281 | trail_length); | ||
5282 | return; | ||
5283 | } | ||
5284 | |||
5285 | /*If you are not the querying peer then pass on the message */ | ||
5286 | if(NULL == (next_hop = | ||
5287 | GDS_ROUTING_get_next_hop (&trail_id, | ||
5288 | trail_direction))) | ||
5289 | { | ||
5290 | /* Here it may happen that source peer has found a new successor, and removed | ||
5291 | the trail, Hence no entry found in the routing table. Fail silently.*/ | ||
5292 | DEBUG (" NO ENTRY FOUND IN %s ROUTING TABLE for trail id %s, line %u", | ||
5293 | GNUNET_i2s (&my_identity), | ||
5294 | GNUNET_h2s (&trail_id), | ||
5295 | __LINE__); | ||
5296 | GNUNET_break_op(0); | ||
5297 | return; | ||
5298 | } | ||
5299 | if (NULL == (target_friend = | ||
5300 | GNUNET_CONTAINER_multipeermap_get (friend_peermap, next_hop))) | ||
5301 | { | ||
5302 | GNUNET_break_op(0); | ||
5303 | return; | ||
5304 | } | ||
5305 | GDS_NEIGHBOURS_send_verify_successor_result (&querying_peer, | ||
5306 | &vsrm->current_successor, | ||
5307 | &probable_successor, | ||
5308 | &trail_id, | ||
5309 | trail, | ||
5310 | trail_length, | ||
5311 | trail_direction, | ||
5312 | target_friend); | ||
5313 | } | ||
5314 | |||
5315 | |||
5316 | /** | ||
5317 | * Check integrity of p2p notify new successor messages. | ||
5318 | * | ||
5319 | * @param cls closure | ||
5320 | * @param nsm the message | ||
5321 | * @return #GNUNET_OK if @a nsm is well-formed | ||
5322 | */ | ||
5323 | static int | ||
5324 | check_dht_p2p_notify_new_successor (void *cls, | ||
5325 | const struct PeerNotifyNewSuccessorMessage *nsm) | ||
5326 | { | ||
5327 | size_t msize; | ||
5328 | |||
5329 | msize = ntohs (nsm->header.size); | ||
5330 | if ((msize - sizeof (struct PeerNotifyNewSuccessorMessage)) % | ||
5331 | sizeof (struct GNUNET_PeerIdentity) != 0) | ||
5332 | { | ||
5333 | GNUNET_break_op (0); | ||
5334 | return GNUNET_SYSERR; | ||
5335 | } | ||
5336 | return GNUNET_OK; | ||
5337 | } | ||
5338 | |||
5339 | |||
5340 | /** | ||
5341 | * Core handle for p2p notify new successor messages. | ||
5342 | * | ||
5343 | * @param cls closure | ||
5344 | * @param nsm the message | ||
5345 | */ | ||
5346 | static void | ||
5347 | handle_dht_p2p_notify_new_successor (void *cls, | ||
5348 | const struct PeerNotifyNewSuccessorMessage *nsm) | ||
5349 | { | ||
5350 | struct FriendInfo *friend = cls; | ||
5351 | const struct GNUNET_PeerIdentity *trail; | ||
5352 | struct GNUNET_PeerIdentity source; | ||
5353 | struct GNUNET_PeerIdentity new_successor; | ||
5354 | struct GNUNET_HashCode trail_id; | ||
5355 | struct GNUNET_PeerIdentity next_hop; | ||
5356 | struct FriendInfo *target_friend; | ||
5357 | int my_index; | ||
5358 | size_t msize; | ||
5359 | uint32_t trail_length; | ||
5360 | |||
5361 | msize = ntohs (nsm->header.size); | ||
5362 | trail_length = (msize - sizeof (struct PeerNotifyNewSuccessorMessage))/ | ||
5363 | sizeof (struct GNUNET_PeerIdentity); | ||
5364 | GNUNET_STATISTICS_update (GDS_stats, | ||
5365 | gettext_noop ("# Bytes received from other peers"), | ||
5366 | msize, | ||
5367 | GNUNET_NO); | ||
5368 | trail = (const struct GNUNET_PeerIdentity *) &nsm[1]; | ||
5369 | source = nsm->source_peer; | ||
5370 | new_successor = nsm->new_successor; | ||
5371 | trail_id = nsm->trail_id; | ||
5372 | |||
5373 | /* I am the new_successor to source_peer. */ | ||
5374 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&my_identity, | ||
5375 | &new_successor)) | ||
5376 | { | ||
5377 | if (trail_length > 0) | ||
5378 | GNUNET_assert(0 == GNUNET_CRYPTO_cmp_peer_identity (&trail[trail_length - 1], | ||
5379 | friend->id)); | ||
5380 | else | ||
5381 | GNUNET_assert(0 == GNUNET_CRYPTO_cmp_peer_identity (&source, | ||
5382 | friend->id)); | ||
5383 | |||
5384 | compare_and_update_predecessor (&source, | ||
5385 | trail, | ||
5386 | trail_length); | ||
5387 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
5388 | friend->id); | ||
5389 | GNUNET_assert (NULL != target_friend); | ||
5390 | GDS_NEIGHBOURS_send_notify_succcessor_confirmation (&trail_id, | ||
5391 | GDS_ROUTING_DEST_TO_SRC, | ||
5392 | target_friend); | ||
5393 | return; | ||
5394 | } | ||
5395 | |||
5396 | GNUNET_assert(trail_length > 0); | ||
5397 | /* I am part of trail to reach to successor. */ | ||
5398 | my_index = search_my_index (trail, trail_length); | ||
5399 | if (-1 == my_index) | ||
5400 | { | ||
5401 | DEBUG ("No entry found in trail\n"); | ||
5402 | GNUNET_break_op (0); | ||
5403 | return; | ||
5404 | } | ||
5405 | if((trail_length + 1) == my_index) | ||
5406 | { | ||
5407 | DEBUG ("Found twice in trail.\n"); | ||
5408 | GNUNET_break_op (0); | ||
5409 | return; | ||
5410 | } | ||
5411 | if ((trail_length-1) == my_index) | ||
5412 | next_hop = new_successor; | ||
5413 | else | ||
5414 | next_hop = trail[my_index + 1]; | ||
5415 | |||
5416 | GDS_ROUTING_add (&trail_id, | ||
5417 | friend->id, | ||
5418 | &next_hop); | ||
5419 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
5420 | &next_hop); | ||
5421 | if (NULL == target_friend) | ||
5422 | { | ||
5423 | GNUNET_break(0); | ||
5424 | return; | ||
5425 | } | ||
5426 | GDS_NEIGHBOURS_send_notify_new_successor (&source, | ||
5427 | &new_successor, | ||
5428 | trail, | ||
5429 | trail_length, | ||
5430 | &trail_id, | ||
5431 | target_friend); | ||
5432 | } | ||
5433 | |||
5434 | |||
5435 | /** | ||
5436 | * Core handler for P2P notify successor message | ||
5437 | * | ||
5438 | * @param cls closure | ||
5439 | * @param notify_confirmation the message | ||
5440 | */ | ||
5441 | static void | ||
5442 | handle_dht_p2p_notify_succ_confirmation (void *cls, | ||
5443 | const struct PeerNotifyConfirmationMessage *notify_confirmation) | ||
5444 | { | ||
5445 | enum GDS_ROUTING_trail_direction trail_direction; | ||
5446 | struct GNUNET_HashCode trail_id; | ||
5447 | struct FriendInfo *target_friend; | ||
5448 | const struct GNUNET_PeerIdentity *next_hop; | ||
5449 | |||
5450 | GNUNET_STATISTICS_update (GDS_stats, | ||
5451 | gettext_noop ("# Bytes received from other peers"), | ||
5452 | ntohs (notify_confirmation->header.size), | ||
5453 | GNUNET_NO); | ||
5454 | trail_direction = ntohl (notify_confirmation->trail_direction); | ||
5455 | trail_id = notify_confirmation->trail_id; | ||
5456 | |||
5457 | next_hop = GDS_ROUTING_get_next_hop (&trail_id, | ||
5458 | trail_direction); | ||
5459 | if (NULL == next_hop) | ||
5460 | { | ||
5461 | /* The source of notify new successor, might have found even a better | ||
5462 | successor. In that case it send a trail teardown message, and hence, | ||
5463 | the next hop is NULL. */ | ||
5464 | //Fixme: Add some print to confirm the above theory. | ||
5465 | return; | ||
5466 | } | ||
5467 | |||
5468 | /* I peer which sent the notify successor message to the successor. */ | ||
5469 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (next_hop, | ||
5470 | &my_identity)) | ||
5471 | { | ||
5472 | /* | ||
5473 | * Schedule another round of verify sucessor with your current successor | ||
5474 | * which may or may not be source of this message. This message is used | ||
5475 | * only to ensure that we have a path setup to reach to our successor. | ||
5476 | */ | ||
5477 | |||
5478 | // TODO: cancel schedule of notify_successor_retry_task | ||
5479 | if (send_notify_new_successor_retry_task != NULL) | ||
5480 | { | ||
5481 | struct SendNotifyContext *notify_ctx; | ||
5482 | notify_ctx = GNUNET_SCHEDULER_cancel(send_notify_new_successor_retry_task); | ||
5483 | GNUNET_free (notify_ctx->successor_trail); | ||
5484 | GNUNET_free (notify_ctx); | ||
5485 | send_notify_new_successor_retry_task = NULL; | ||
5486 | } | ||
5487 | if (send_verify_successor_task == NULL) | ||
5488 | { | ||
5489 | verify_successor_next_send_time.rel_value_us = | ||
5490 | DHT_SEND_VERIFY_SUCCESSOR_INTERVAL.rel_value_us + | ||
5491 | GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, | ||
5492 | DHT_SEND_VERIFY_SUCCESSOR_INTERVAL.rel_value_us); | ||
5493 | send_verify_successor_task | ||
5494 | = GNUNET_SCHEDULER_add_delayed(verify_successor_next_send_time, | ||
5495 | &send_verify_successor_message, | ||
5496 | NULL); | ||
5497 | } | ||
5498 | } | ||
5499 | else | ||
5500 | { | ||
5501 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
5502 | next_hop); | ||
5503 | if (NULL == target_friend) | ||
5504 | { | ||
5505 | DEBUG ("\n friend not found, line number = %d", | ||
5506 | __LINE__); | ||
5507 | return; | ||
5508 | } | ||
5509 | GDS_NEIGHBOURS_send_notify_succcessor_confirmation (&trail_id, | ||
5510 | GDS_ROUTING_DEST_TO_SRC, | ||
5511 | target_friend); | ||
5512 | } | ||
5513 | } | ||
5514 | |||
5515 | |||
5516 | /** | ||
5517 | * Check integrity of P2P trail rejection message | ||
5518 | * | ||
5519 | * @param cls closure | ||
5520 | * @param trail_rejection the message | ||
5521 | * @return #GNUNET_OK if @a trail_rejection is well-formed | ||
5522 | */ | ||
5523 | static int | ||
5524 | check_dht_p2p_trail_setup_rejection (void *cls, | ||
5525 | const struct PeerTrailRejectionMessage *trail_rejection) | ||
5526 | { | ||
5527 | size_t msize; | ||
5528 | |||
5529 | msize = ntohs (trail_rejection->header.size); | ||
5530 | if ((msize - sizeof (struct PeerTrailRejectionMessage)) % | ||
5531 | sizeof (struct GNUNET_PeerIdentity) != 0) | ||
5532 | { | ||
5533 | GNUNET_break_op (0); | ||
5534 | return GNUNET_SYSERR; | ||
5535 | } | ||
5536 | return GNUNET_OK; | ||
5537 | } | ||
5538 | |||
5539 | |||
5540 | /** | ||
5541 | * Core handler for P2P trail rejection message | ||
5542 | * | ||
5543 | * @param cls closure | ||
5544 | * @param trail_rejection the message | ||
5545 | */ | ||
5546 | static void | ||
5547 | handle_dht_p2p_trail_setup_rejection (void *cls, | ||
5548 | const struct PeerTrailRejectionMessage *trail_rejection) | ||
5549 | { | ||
5550 | struct FriendInfo *friend = cls; | ||
5551 | unsigned int trail_length; | ||
5552 | const struct GNUNET_PeerIdentity *trail_peer_list; | ||
5553 | struct FriendInfo *target_friend; | ||
5554 | struct GNUNET_TIME_Relative congestion_timeout; | ||
5555 | struct GNUNET_HashCode trail_id; | ||
5556 | struct GNUNET_PeerIdentity next_peer; | ||
5557 | struct GNUNET_PeerIdentity source; | ||
5558 | uint64_t ultimate_destination_finger_value; | ||
5559 | unsigned int is_predecessor; | ||
5560 | struct Closest_Peer successor; | ||
5561 | size_t msize; | ||
5562 | |||
5563 | msize = ntohs (trail_rejection->header.size); | ||
5564 | trail_length = (msize - sizeof (struct PeerTrailRejectionMessage))/ | ||
5565 | sizeof (struct GNUNET_PeerIdentity); | ||
5566 | GNUNET_STATISTICS_update (GDS_stats, | ||
5567 | gettext_noop ("# Bytes received from other peers"), | ||
5568 | msize, | ||
5569 | GNUNET_NO); | ||
5570 | |||
5571 | trail_peer_list = (const struct GNUNET_PeerIdentity *) &trail_rejection[1]; | ||
5572 | is_predecessor = ntohl (trail_rejection->is_predecessor); | ||
5573 | congestion_timeout = trail_rejection->congestion_time; | ||
5574 | source = trail_rejection->source_peer; | ||
5575 | trail_id = trail_rejection->trail_id; | ||
5576 | ultimate_destination_finger_value | ||
5577 | = GNUNET_ntohll (trail_rejection->ultimate_destination_finger_value); | ||
5578 | /* First set the congestion time of the friend that sent you this message. */ | ||
5579 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
5580 | friend->id); | ||
5581 | if (NULL == target_friend) | ||
5582 | { | ||
5583 | DEBUG ("\nLINE = %d ,No friend found.",__LINE__); | ||
5584 | GNUNET_break(0); | ||
5585 | return; | ||
5586 | } | ||
5587 | target_friend->congestion_timestamp | ||
5588 | = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(), | ||
5589 | congestion_timeout); | ||
5590 | |||
5591 | /* I am the source peer which wants to setup the trail. Do nothing. | ||
5592 | * send_find_finger_trail_task is scheduled periodically.*/ | ||
5593 | if(0 == (GNUNET_CRYPTO_cmp_peer_identity (&my_identity, &source))) | ||
5594 | return; | ||
5595 | |||
5596 | /* If I am congested then pass this message to peer before me in trail. */ | ||
5597 | if (GNUNET_YES == GDS_ROUTING_threshold_reached()) | ||
5598 | { | ||
5599 | /* First remove yourself from the trail. */ | ||
5600 | unsigned int new_trail_length = trail_length - 1; | ||
5601 | struct GNUNET_PeerIdentity trail[new_trail_length]; | ||
5602 | |||
5603 | GNUNET_memcpy (trail, | ||
5604 | trail_peer_list, | ||
5605 | new_trail_length * sizeof(struct GNUNET_PeerIdentity)); | ||
5606 | if (0 == trail_length) | ||
5607 | next_peer = source; | ||
5608 | else | ||
5609 | next_peer = trail[new_trail_length-1]; | ||
5610 | |||
5611 | target_friend | ||
5612 | = GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
5613 | &next_peer); | ||
5614 | if (NULL == target_friend) | ||
5615 | { | ||
5616 | DEBUG ("\nLINE = %d ,No friend found.", | ||
5617 | __LINE__); | ||
5618 | GNUNET_break(0); | ||
5619 | return; | ||
5620 | } | ||
5621 | GDS_NEIGHBOURS_send_trail_rejection (&source, | ||
5622 | ultimate_destination_finger_value, | ||
5623 | &my_identity, | ||
5624 | is_predecessor, | ||
5625 | trail, | ||
5626 | new_trail_length, | ||
5627 | &trail_id, | ||
5628 | target_friend, | ||
5629 | CONGESTION_TIMEOUT); | ||
5630 | return; | ||
5631 | } | ||
5632 | |||
5633 | successor = find_local_best_known_next_hop (ultimate_destination_finger_value, | ||
5634 | is_predecessor); | ||
5635 | |||
5636 | /* Am I the final destination? */ | ||
5637 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&successor.best_known_destination, | ||
5638 | &my_identity)) | ||
5639 | { | ||
5640 | /*Here you are already part of trail. Copy the trail removing yourself. */ | ||
5641 | unsigned int new_trail_length = trail_length - 1; | ||
5642 | struct GNUNET_PeerIdentity trail[new_trail_length]; | ||
5643 | |||
5644 | GNUNET_memcpy (trail, | ||
5645 | trail_peer_list, | ||
5646 | new_trail_length * sizeof(struct GNUNET_PeerIdentity)); | ||
5647 | |||
5648 | if (0 == new_trail_length) | ||
5649 | next_peer = source; | ||
5650 | else | ||
5651 | { | ||
5652 | next_peer = trail[new_trail_length-1]; | ||
5653 | } | ||
5654 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
5655 | &next_peer); | ||
5656 | |||
5657 | if (NULL == target_friend) | ||
5658 | { | ||
5659 | DEBUG ("\nLINE = %d ,No friend found.", | ||
5660 | __LINE__); | ||
5661 | GNUNET_break(0); | ||
5662 | return; | ||
5663 | } | ||
5664 | GDS_NEIGHBOURS_send_trail_setup_result (&source, | ||
5665 | &my_identity, | ||
5666 | target_friend, | ||
5667 | new_trail_length, | ||
5668 | trail, | ||
5669 | is_predecessor, | ||
5670 | ultimate_destination_finger_value, | ||
5671 | &trail_id); | ||
5672 | return; | ||
5673 | } | ||
5674 | /* Here I was already part of trail. So no need to add. */ | ||
5675 | target_friend = GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
5676 | &successor.next_hop); | ||
5677 | if (NULL == target_friend) | ||
5678 | { | ||
5679 | DEBUG ("\nLINE = %d ,No friend found.",__LINE__); | ||
5680 | GNUNET_break (0); | ||
5681 | return; | ||
5682 | } | ||
5683 | GDS_NEIGHBOURS_send_trail_setup (&source, | ||
5684 | ultimate_destination_finger_value, | ||
5685 | &successor.best_known_destination, | ||
5686 | target_friend, | ||
5687 | trail_length, | ||
5688 | trail_peer_list, | ||
5689 | is_predecessor, | ||
5690 | &trail_id, | ||
5691 | &successor.trail_id); | ||
5692 | } | ||
5693 | |||
5694 | |||
5695 | /** | ||
5696 | * Core handler for trail teardown message. | ||
5697 | * | ||
5698 | * @param cls closure | ||
5699 | * @param trail_teardown the message | ||
5700 | */ | ||
5701 | static void | ||
5702 | handle_dht_p2p_trail_teardown (void *cls, | ||
5703 | const struct PeerTrailTearDownMessage *trail_teardown) | ||
5704 | { | ||
5705 | enum GDS_ROUTING_trail_direction trail_direction; | ||
5706 | struct GNUNET_HashCode trail_id; | ||
5707 | const struct GNUNET_PeerIdentity *next_hop; | ||
5708 | size_t msize; | ||
5709 | |||
5710 | msize = ntohs (trail_teardown->header.size); | ||
5711 | GNUNET_STATISTICS_update (GDS_stats, | ||
5712 | gettext_noop ("# Bytes received from other peers"), | ||
5713 | msize, | ||
5714 | GNUNET_NO); | ||
5715 | trail_direction = ntohl (trail_teardown->trail_direction); | ||
5716 | trail_id = trail_teardown->trail_id; | ||
5717 | |||
5718 | /* Check if peer is the real peer from which we should get this message.*/ | ||
5719 | /* Get the prev_hop for this trail by getting the next hop in opposite direction. */ | ||
5720 | #if 0 | ||
5721 | GNUNET_assert (NULL != (prev_hop = | ||
5722 | GDS_ROUTING_get_next_hop (trail_id, ! trail_direction))); | ||
5723 | if (0 != GNUNET_CRYPTO_cmp_peer_identity (prev_hop, | ||
5724 | friend->id)) | ||
5725 | { | ||
5726 | GNUNET_break (0); | ||
5727 | return; | ||
5728 | } | ||
5729 | #endif | ||
5730 | |||
5731 | next_hop = GDS_ROUTING_get_next_hop (&trail_id, | ||
5732 | trail_direction); | ||
5733 | if (NULL == next_hop) | ||
5734 | { | ||
5735 | DEBUG(" NO ENTRY FOUND IN %s ROUTING TABLE for trail id %s, line %u", | ||
5736 | GNUNET_i2s (&my_identity), | ||
5737 | GNUNET_h2s (&trail_id), | ||
5738 | __LINE__); | ||
5739 | GNUNET_break (0); | ||
5740 | return; | ||
5741 | } | ||
5742 | |||
5743 | /* I am the next hop, which means I am the final destination. */ | ||
5744 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (next_hop, &my_identity)) | ||
5745 | { | ||
5746 | GNUNET_assert (GNUNET_YES == | ||
5747 | GDS_ROUTING_remove_trail (&trail_id)); | ||
5748 | return; | ||
5749 | } | ||
5750 | /* If not final destination, then send a trail teardown message to next hop.*/ | ||
5751 | GNUNET_assert (NULL != GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
5752 | next_hop)); | ||
5753 | GNUNET_assert (GNUNET_YES == | ||
5754 | GDS_ROUTING_remove_trail (&trail_id)); | ||
5755 | GDS_NEIGHBOURS_send_trail_teardown (&trail_id, | ||
5756 | trail_direction, | ||
5757 | next_hop); | ||
5758 | } | ||
5759 | |||
5760 | |||
5761 | /** | ||
5762 | * Check validity of p2p add trail message. | ||
5763 | * | ||
5764 | * @param cls closure | ||
5765 | * @param add_trail the message | ||
5766 | * @return #GNUNET_OK if @a add_trail is well-formed | ||
5767 | */ | ||
5768 | static int | ||
5769 | check_dht_p2p_add_trail (void *cls, | ||
5770 | const struct PeerAddTrailMessage *add_trail) | ||
5771 | { | ||
5772 | size_t msize; | ||
5773 | |||
5774 | msize = ntohs (add_trail->header.size); | ||
5775 | if ((msize - sizeof (struct PeerAddTrailMessage)) % | ||
5776 | sizeof (struct GNUNET_PeerIdentity) != 0) | ||
5777 | { | ||
5778 | GNUNET_break_op (0); | ||
5779 | return GNUNET_SYSERR; | ||
5780 | } | ||
5781 | return GNUNET_OK; | ||
5782 | } | ||
5783 | |||
5784 | |||
5785 | /** | ||
5786 | * Core handle for p2p add trail message. | ||
5787 | * | ||
5788 | * @param cls closure | ||
5789 | * @param add_trail the message | ||
5790 | */ | ||
5791 | static void | ||
5792 | handle_dht_p2p_add_trail (void *cls, | ||
5793 | const struct PeerAddTrailMessage *add_trail) | ||
5794 | { | ||
5795 | struct FriendInfo *friend = cls; | ||
5796 | const struct GNUNET_PeerIdentity *trail; | ||
5797 | struct GNUNET_HashCode trail_id; | ||
5798 | struct GNUNET_PeerIdentity destination_peer; | ||
5799 | struct GNUNET_PeerIdentity source_peer; | ||
5800 | struct GNUNET_PeerIdentity next_hop; | ||
5801 | unsigned int trail_length; | ||
5802 | unsigned int my_index; | ||
5803 | size_t msize; | ||
5804 | |||
5805 | msize = ntohs (add_trail->header.size); | ||
5806 | /* In this message we pass the whole trail from source to destination as we | ||
5807 | * are adding that trail.*/ | ||
5808 | //FIXME: failed when run with 1000 pears. check why. | ||
5809 | trail_length = (msize - sizeof (struct PeerAddTrailMessage))/ | ||
5810 | sizeof (struct GNUNET_PeerIdentity); | ||
5811 | GNUNET_STATISTICS_update (GDS_stats, | ||
5812 | gettext_noop ("# Bytes received from other peers"), | ||
5813 | msize, | ||
5814 | GNUNET_NO); | ||
5815 | |||
5816 | trail = (const struct GNUNET_PeerIdentity *) &add_trail[1]; | ||
5817 | destination_peer = add_trail->destination_peer; | ||
5818 | source_peer = add_trail->source_peer; | ||
5819 | trail_id = add_trail->trail_id; | ||
5820 | |||
5821 | /* I am not the destination of the trail. */ | ||
5822 | if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity, | ||
5823 | &destination_peer)) | ||
5824 | { | ||
5825 | struct FriendInfo *target_friend; | ||
5826 | |||
5827 | /* Get my location in the trail. */ | ||
5828 | my_index = search_my_index (trail, trail_length); | ||
5829 | if (-1 == my_index) | ||
5830 | { | ||
5831 | GNUNET_break_op (0); | ||
5832 | return; | ||
5833 | } | ||
5834 | if((trail_length + 1) == my_index) | ||
5835 | { | ||
5836 | DEBUG ("Found twice in trail.\n"); | ||
5837 | GNUNET_break_op (0); | ||
5838 | return; | ||
5839 | } | ||
5840 | if ((trail_length - 1) == my_index) | ||
5841 | { | ||
5842 | next_hop = destination_peer; | ||
5843 | } | ||
5844 | else | ||
5845 | { | ||
5846 | next_hop = trail[my_index + 1]; | ||
5847 | } | ||
5848 | /* Add in your routing table. */ | ||
5849 | GNUNET_assert (GNUNET_OK == GDS_ROUTING_add (&trail_id, | ||
5850 | friend->id, | ||
5851 | &next_hop)); | ||
5852 | //GNUNET_assert (GNUNET_OK == GDS_ROUTING_add (trail_id, next_hop, *peer)); | ||
5853 | GNUNET_assert (NULL != | ||
5854 | (target_friend = | ||
5855 | GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
5856 | &next_hop))); | ||
5857 | GDS_NEIGHBOURS_send_add_trail (&source_peer, | ||
5858 | &destination_peer, | ||
5859 | &trail_id, | ||
5860 | trail, | ||
5861 | trail_length, | ||
5862 | target_friend); | ||
5863 | return; | ||
5864 | } | ||
5865 | /* I am the destination. Add an entry in routing table. */ | ||
5866 | GNUNET_assert (GNUNET_OK == GDS_ROUTING_add (&trail_id, | ||
5867 | friend->id, | ||
5868 | &my_identity)); | ||
5869 | } | ||
5870 | |||
5871 | |||
5872 | /** | ||
5873 | * Free the finger trail in which the first friend to reach to a finger is | ||
5874 | * disconnected_friend. Also remove entry from routing table for that particular | ||
5875 | * trail id. | ||
5876 | * @param disconnected_friend PeerIdentity of friend which got disconnected | ||
5877 | * @param remove_finger Finger whose trail we need to check if it has | ||
5878 | * disconnected_friend as the first hop. | ||
5879 | * @return Total number of trails in which disconnected_friend was the first | ||
5880 | * hop. | ||
5881 | */ | ||
5882 | static int | ||
5883 | remove_matching_trails (const struct GNUNET_PeerIdentity *disconnected_friend, | ||
5884 | struct FingerInfo *finger) | ||
5885 | { | ||
5886 | const struct GNUNET_PeerIdentity *next_hop; | ||
5887 | struct FriendInfo *remove_friend; | ||
5888 | struct Trail *current_trail; | ||
5889 | unsigned int matching_trails_count = 0; | ||
5890 | int i; | ||
5891 | |||
5892 | /* Iterate over all the trails of finger. */ | ||
5893 | for (i = 0; i < finger->trails_count; i++) | ||
5894 | { | ||
5895 | current_trail = &finger->trail_list[i]; | ||
5896 | if (GNUNET_NO == current_trail->is_present) | ||
5897 | continue; | ||
5898 | |||
5899 | /* First friend to reach to finger is disconnected_peer. */ | ||
5900 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (¤t_trail->trail_head->peer, | ||
5901 | disconnected_friend)) | ||
5902 | { | ||
5903 | remove_friend = | ||
5904 | GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
5905 | disconnected_friend); | ||
5906 | GNUNET_assert (NULL != remove_friend); | ||
5907 | next_hop = GDS_ROUTING_get_next_hop (¤t_trail->trail_id, | ||
5908 | GDS_ROUTING_SRC_TO_DEST); | ||
5909 | |||
5910 | /* Here it may happen that as all the peers got disconnected, the entry in | ||
5911 | routing table for that particular trail has been removed, because the | ||
5912 | previously disconnected peer was either a next hop or prev hop of that | ||
5913 | peer. */ | ||
5914 | if (NULL != next_hop) | ||
5915 | { | ||
5916 | GNUNET_assert (0 == (GNUNET_CRYPTO_cmp_peer_identity (disconnected_friend, | ||
5917 | next_hop))); | ||
5918 | GNUNET_assert (GNUNET_YES == | ||
5919 | GDS_ROUTING_remove_trail (¤t_trail->trail_id)); | ||
5920 | } | ||
5921 | matching_trails_count++; | ||
5922 | free_trail (current_trail); | ||
5923 | current_trail->is_present = GNUNET_NO; | ||
5924 | } | ||
5925 | } | ||
5926 | return matching_trails_count; | ||
5927 | } | ||
5928 | |||
5929 | |||
5930 | /** | ||
5931 | * Iterate over finger_table entries. | ||
5932 | * 0. Ignore finger which is my_identity or if no valid entry present at | ||
5933 | * that finger index. | ||
5934 | * 1. If disconnected_friend is a finger, then remove the routing entry from | ||
5935 | your own table. Free the trail. | ||
5936 | * 2. Check if disconnected_friend is the first friend in the trail to reach to a finger. | ||
5937 | * 2.1 Remove all the trails and entry from routing table in which disconnected | ||
5938 | * friend is the first friend in the trail. If disconnected_friend is the | ||
5939 | * first friend in all the trails to reach finger, then remove the finger. | ||
5940 | * @param disconnected_friend Peer identity of friend which got disconnected. | ||
5941 | */ | ||
5942 | static void | ||
5943 | remove_matching_fingers (const struct GNUNET_PeerIdentity *disconnected_peer) | ||
5944 | { | ||
5945 | struct FingerInfo *current_finger; | ||
5946 | int removed_trails_count; | ||
5947 | int i; | ||
5948 | |||
5949 | /* Iterate over finger table entries. */ | ||
5950 | for (i = 0; i < MAX_FINGERS; i++) | ||
5951 | { | ||
5952 | current_finger = &finger_table[i]; | ||
5953 | |||
5954 | /* No finger stored at this trail index or I am the finger. */ | ||
5955 | if ((GNUNET_NO == current_finger->is_present) || | ||
5956 | (0 == GNUNET_CRYPTO_cmp_peer_identity (¤t_finger->finger_identity, | ||
5957 | &my_identity))) | ||
5958 | continue; | ||
5959 | |||
5960 | /* Is disconnected_peer a finger? */ | ||
5961 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (disconnected_peer, | ||
5962 | ¤t_finger->finger_identity)) | ||
5963 | { | ||
5964 | remove_existing_finger (current_finger, i); | ||
5965 | } | ||
5966 | |||
5967 | /* If finger is a friend but not disconnected_friend, then continue. */ | ||
5968 | if (NULL != GNUNET_CONTAINER_multipeermap_get (friend_peermap, | ||
5969 | ¤t_finger->finger_identity)) | ||
5970 | continue; | ||
5971 | |||
5972 | /* Iterate over the list of trails to reach remove_finger. Check if | ||
5973 | * disconnected_friend is the first friend in any of the trail. */ | ||
5974 | removed_trails_count = remove_matching_trails (disconnected_peer, | ||
5975 | current_finger); | ||
5976 | current_finger->trails_count = | ||
5977 | current_finger->trails_count - removed_trails_count; | ||
5978 | if (0 == current_finger->trails_count) | ||
5979 | { | ||
5980 | current_finger->is_present = GNUNET_NO; | ||
5981 | memset (&finger_table[i], | ||
5982 | 0, | ||
5983 | sizeof (finger_table[i])); | ||
5984 | } | ||
5985 | } | ||
5986 | } | ||
5987 | |||
5988 | |||
5989 | /** | ||
5990 | * Method called whenever a peer disconnects. | ||
5991 | * | ||
5992 | * @param cls closure | ||
5993 | * @param peer peer identity this notification is about | ||
5994 | * @param internal_cls our `struct FriendInfo` for @a peer | ||
5995 | */ | ||
5996 | static void | ||
5997 | handle_core_disconnect (void *cls, | ||
5998 | const struct GNUNET_PeerIdentity *peer, | ||
5999 | void *internal_cls) | ||
6000 | { | ||
6001 | struct FriendInfo *remove_friend = internal_cls; | ||
6002 | |||
6003 | /* If disconnected to own identity, then return. */ | ||
6004 | if (NULL == remove_friend) | ||
6005 | return; | ||
6006 | remove_matching_fingers (peer); | ||
6007 | GNUNET_assert (GNUNET_SYSERR != | ||
6008 | GDS_ROUTING_remove_trail_by_peer (peer)); | ||
6009 | GNUNET_assert (GNUNET_YES == | ||
6010 | GNUNET_CONTAINER_multipeermap_remove (friend_peermap, | ||
6011 | peer, | ||
6012 | remove_friend)); | ||
6013 | if (0 != GNUNET_CONTAINER_multipeermap_size (friend_peermap)) | ||
6014 | return; | ||
6015 | |||
6016 | if (NULL != find_finger_trail_task) | ||
6017 | { | ||
6018 | GNUNET_SCHEDULER_cancel (find_finger_trail_task); | ||
6019 | find_finger_trail_task = NULL; | ||
6020 | } | ||
6021 | else | ||
6022 | GNUNET_break (0); | ||
6023 | } | ||
6024 | |||
6025 | |||
6026 | /** | ||
6027 | * Method called whenever a peer connects. | ||
6028 | * | ||
6029 | * @param cls closure | ||
6030 | * @param peer_identity peer identity this notification is about | ||
6031 | * @param mq message queue for sending data to @a peer | ||
6032 | * @return our `struct FriendInfo` for this peer | ||
6033 | */ | ||
6034 | static void * | ||
6035 | handle_core_connect (void *cls, | ||
6036 | const struct GNUNET_PeerIdentity *peer_identity, | ||
6037 | struct GNUNET_MQ_Handle *mq) | ||
6038 | { | ||
6039 | struct FriendInfo *friend; | ||
6040 | |||
6041 | /* Check for connect to self message */ | ||
6042 | if (0 == memcmp (&my_identity, | ||
6043 | peer_identity, | ||
6044 | sizeof (struct GNUNET_PeerIdentity))) | ||
6045 | return NULL; | ||
6046 | friend = GNUNET_new (struct FriendInfo); | ||
6047 | friend->id = peer_identity; | ||
6048 | friend->mq = mq; | ||
6049 | GNUNET_assert (GNUNET_OK == | ||
6050 | GNUNET_CONTAINER_multipeermap_put (friend_peermap, | ||
6051 | friend->id, | ||
6052 | friend, | ||
6053 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
6054 | |||
6055 | /* FIXME: now we are not making a distinction between fingers which are friends | ||
6056 | * also.But later, we should add a congestion timestamp on the friend, so that it is | ||
6057 | * selected after some time out. This is to ensure that both peers have added | ||
6058 | * each other as their friend. */ | ||
6059 | /* Got a first connection, good time to start with FIND FINGER TRAIL requests...*/ | ||
6060 | if (NULL == find_finger_trail_task) | ||
6061 | { | ||
6062 | find_finger_trail_task | ||
6063 | = GNUNET_SCHEDULER_add_now (&send_find_finger_trail_message, | ||
6064 | NULL); | ||
6065 | } | ||
6066 | return friend; | ||
6067 | } | ||
6068 | |||
6069 | |||
6070 | /** | ||
6071 | * To be called on core init/fail. | ||
6072 | * | ||
6073 | * @param cls service closure | ||
6074 | * @param identity the public identity of this peer | ||
6075 | */ | ||
6076 | static void | ||
6077 | core_init (void *cls, | ||
6078 | const struct GNUNET_PeerIdentity *identity) | ||
6079 | { | ||
6080 | my_identity = *identity; | ||
6081 | } | ||
6082 | |||
6083 | |||
6084 | /** | ||
6085 | * Initialize finger table entries. | ||
6086 | */ | ||
6087 | static void | ||
6088 | finger_table_init () | ||
6089 | { | ||
6090 | memset (&finger_table, 0, sizeof (finger_table)); | ||
6091 | } | ||
6092 | |||
6093 | |||
6094 | /** | ||
6095 | * Initialize neighbours subsystem. | ||
6096 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
6097 | */ | ||
6098 | int | ||
6099 | GDS_NEIGHBOURS_init (void) | ||
6100 | { | ||
6101 | struct GNUNET_MQ_MessageHandler core_handlers[] = { | ||
6102 | GNUNET_MQ_hd_var_size (dht_p2p_put, | ||
6103 | GNUNET_MESSAGE_TYPE_XDHT_P2P_PUT, | ||
6104 | struct PeerPutMessage, | ||
6105 | NULL), | ||
6106 | GNUNET_MQ_hd_var_size (dht_p2p_get, | ||
6107 | GNUNET_MESSAGE_TYPE_XDHT_P2P_GET, | ||
6108 | struct PeerGetMessage, | ||
6109 | NULL), | ||
6110 | GNUNET_MQ_hd_var_size (dht_p2p_get_result, | ||
6111 | GNUNET_MESSAGE_TYPE_XDHT_P2P_GET_RESULT, | ||
6112 | struct PeerGetResultMessage, | ||
6113 | NULL), | ||
6114 | GNUNET_MQ_hd_var_size (dht_p2p_trail_setup, | ||
6115 | GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_SETUP, | ||
6116 | struct PeerTrailSetupMessage, | ||
6117 | NULL), | ||
6118 | GNUNET_MQ_hd_var_size (dht_p2p_trail_setup_result, | ||
6119 | GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_SETUP_RESULT, | ||
6120 | struct PeerTrailSetupResultMessage, | ||
6121 | NULL), | ||
6122 | GNUNET_MQ_hd_var_size (dht_p2p_verify_successor, | ||
6123 | GNUNET_MESSAGE_TYPE_XDHT_P2P_VERIFY_SUCCESSOR, | ||
6124 | struct PeerVerifySuccessorMessage, | ||
6125 | NULL), | ||
6126 | GNUNET_MQ_hd_var_size (dht_p2p_verify_successor_result, | ||
6127 | GNUNET_MESSAGE_TYPE_XDHT_P2P_VERIFY_SUCCESSOR_RESULT, | ||
6128 | struct PeerVerifySuccessorResultMessage, | ||
6129 | NULL), | ||
6130 | GNUNET_MQ_hd_var_size (dht_p2p_notify_new_successor, | ||
6131 | GNUNET_MESSAGE_TYPE_XDHT_P2P_NOTIFY_NEW_SUCCESSOR, | ||
6132 | struct PeerNotifyNewSuccessorMessage, | ||
6133 | NULL), | ||
6134 | GNUNET_MQ_hd_var_size (dht_p2p_trail_setup_rejection, | ||
6135 | GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_SETUP_REJECTION, | ||
6136 | struct PeerTrailRejectionMessage, | ||
6137 | NULL), | ||
6138 | GNUNET_MQ_hd_fixed_size (dht_p2p_trail_teardown, | ||
6139 | GNUNET_MESSAGE_TYPE_XDHT_P2P_TRAIL_TEARDOWN, | ||
6140 | struct PeerTrailTearDownMessage, | ||
6141 | NULL), | ||
6142 | GNUNET_MQ_hd_var_size (dht_p2p_add_trail, | ||
6143 | GNUNET_MESSAGE_TYPE_XDHT_P2P_ADD_TRAIL, | ||
6144 | struct PeerAddTrailMessage, | ||
6145 | NULL), | ||
6146 | GNUNET_MQ_hd_fixed_size (dht_p2p_notify_succ_confirmation, | ||
6147 | GNUNET_MESSAGE_TYPE_XDHT_P2P_NOTIFY_SUCCESSOR_CONFIRMATION, | ||
6148 | struct PeerNotifyConfirmationMessage, | ||
6149 | NULL), | ||
6150 | GNUNET_MQ_handler_end () | ||
6151 | }; | ||
6152 | |||
6153 | core_api = GNUNET_CORE_connect (GDS_cfg, | ||
6154 | NULL, | ||
6155 | &core_init, | ||
6156 | &handle_core_connect, | ||
6157 | &handle_core_disconnect, | ||
6158 | core_handlers); | ||
6159 | if (NULL == core_api) | ||
6160 | return GNUNET_SYSERR; | ||
6161 | friend_peermap = GNUNET_CONTAINER_multipeermap_create (256, | ||
6162 | GNUNET_YES); | ||
6163 | finger_table_init (); | ||
6164 | successor_times = 10; | ||
6165 | fingers_round_count = 5; | ||
6166 | find_finger_trail_task_next_send_time.rel_value_us = | ||
6167 | DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us + | ||
6168 | GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, | ||
6169 | DHT_FIND_FINGER_TRAIL_INTERVAL.rel_value_us); | ||
6170 | |||
6171 | verify_successor_next_send_time.rel_value_us = | ||
6172 | DHT_SEND_VERIFY_SUCCESSOR_INTERVAL.rel_value_us + | ||
6173 | GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, | ||
6174 | DHT_SEND_VERIFY_SUCCESSOR_INTERVAL.rel_value_us); | ||
6175 | |||
6176 | verify_successor_retry_time.rel_value_us = | ||
6177 | DHT_SEND_VERIFY_SUCCESSOR_RETRY_INTERVAL.rel_value_us + | ||
6178 | GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, | ||
6179 | DHT_SEND_VERIFY_SUCCESSOR_RETRY_INTERVAL.rel_value_us); | ||
6180 | |||
6181 | notify_successor_retry_time.rel_value_us = | ||
6182 | DHT_SEND_NOTIFY_SUCCESSOR_RETRY_INTERVAL.rel_value_us + | ||
6183 | GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, | ||
6184 | DHT_SEND_NOTIFY_SUCCESSOR_RETRY_INTERVAL.rel_value_us); | ||
6185 | |||
6186 | return GNUNET_OK; | ||
6187 | } | ||
6188 | |||
6189 | |||
6190 | /** | ||
6191 | * Free the memory held up by trails of a finger. | ||
6192 | */ | ||
6193 | static void | ||
6194 | delete_finger_table_entries() | ||
6195 | { | ||
6196 | for (unsigned int i = 0; i < MAX_FINGERS; i++) | ||
6197 | { | ||
6198 | if (GNUNET_YES != finger_table[i].is_present) | ||
6199 | continue; | ||
6200 | for (unsigned int j = 0; j < finger_table[i].trails_count; j++) | ||
6201 | free_trail(&finger_table[i].trail_list[j]); | ||
6202 | } | ||
6203 | } | ||
6204 | |||
6205 | |||
6206 | /** | ||
6207 | * Shutdown neighbours subsystem. | ||
6208 | */ | ||
6209 | void | ||
6210 | GDS_NEIGHBOURS_done (void) | ||
6211 | { | ||
6212 | if (NULL == core_api) | ||
6213 | return; | ||
6214 | |||
6215 | GNUNET_CORE_disconnect (core_api); | ||
6216 | core_api = NULL; | ||
6217 | |||
6218 | delete_finger_table_entries(); | ||
6219 | GNUNET_assert (0 == GNUNET_CONTAINER_multipeermap_size (friend_peermap)); | ||
6220 | GNUNET_CONTAINER_multipeermap_destroy (friend_peermap); | ||
6221 | friend_peermap = NULL; | ||
6222 | |||
6223 | if (NULL != find_finger_trail_task) | ||
6224 | { | ||
6225 | GNUNET_SCHEDULER_cancel (find_finger_trail_task); | ||
6226 | find_finger_trail_task = NULL; | ||
6227 | } | ||
6228 | |||
6229 | if (NULL != send_verify_successor_task) | ||
6230 | { | ||
6231 | GNUNET_SCHEDULER_cancel (send_verify_successor_task); | ||
6232 | send_verify_successor_task = NULL; | ||
6233 | } | ||
6234 | if (NULL != send_verify_successor_retry_task) | ||
6235 | { | ||
6236 | struct VerifySuccessorContext *ctx; | ||
6237 | |||
6238 | ctx = GNUNET_SCHEDULER_cancel (send_verify_successor_retry_task); | ||
6239 | GNUNET_free (ctx); | ||
6240 | send_verify_successor_retry_task = NULL; | ||
6241 | } | ||
6242 | if (NULL != send_notify_new_successor_retry_task) | ||
6243 | { | ||
6244 | struct SendNotifyContext *notify_ctx; | ||
6245 | |||
6246 | notify_ctx = GNUNET_SCHEDULER_cancel (send_notify_new_successor_retry_task); | ||
6247 | GNUNET_free (notify_ctx->successor_trail); | ||
6248 | GNUNET_free (notify_ctx); | ||
6249 | send_notify_new_successor_retry_task = NULL; | ||
6250 | } | ||
6251 | } | ||
6252 | |||
6253 | |||
6254 | /** | ||
6255 | * Get my identity | ||
6256 | * | ||
6257 | * @return my identity | ||
6258 | */ | ||
6259 | struct GNUNET_PeerIdentity * | ||
6260 | GDS_NEIGHBOURS_get_id (void) | ||
6261 | { | ||
6262 | return &my_identity; | ||
6263 | } | ||
6264 | |||
6265 | /* end of gnunet-service-xdht_neighbours.c */ | ||
diff --git a/src/dht/gnunet-service-xdht_neighbours.h b/src/dht/gnunet-service-xdht_neighbours.h deleted file mode 100644 index 2fb118448..000000000 --- a/src/dht/gnunet-service-xdht_neighbours.h +++ /dev/null | |||
@@ -1,47 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2009, 2010, 2011 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file dht/gnunet-service-xdht_neighbours.h | ||
23 | * @brief GNUnet DHT routing code | ||
24 | * @author Supriti Singh | ||
25 | */ | ||
26 | |||
27 | #ifndef GNUNET_SERVICE_XDHT_NEIGHBOURS_H | ||
28 | #define GNUNET_SERVICE_XDHT_NEIGHBOURS_H | ||
29 | |||
30 | #include "gnunet_util_lib.h" | ||
31 | #include "gnunet_block_lib.h" | ||
32 | #include "gnunet_dht_service.h" | ||
33 | |||
34 | |||
35 | /** | ||
36 | * Construct a trail teardown message and forward it to target friend. | ||
37 | * @param trail_id Unique identifier of the trail. | ||
38 | * @param trail_direction Direction of trail. | ||
39 | * @param target_friend Friend to get this message. | ||
40 | */ | ||
41 | void | ||
42 | GDS_NEIGHBOURS_send_trail_teardown (const struct GNUNET_HashCode *trail_id, | ||
43 | unsigned int trail_direction, | ||
44 | const struct GNUNET_PeerIdentity *peer); | ||
45 | |||
46 | |||
47 | #endif | ||
diff --git a/src/dht/gnunet-service-xdht_routing.c b/src/dht/gnunet-service-xdht_routing.c deleted file mode 100644 index ec7361579..000000000 --- a/src/dht/gnunet-service-xdht_routing.c +++ /dev/null | |||
@@ -1,368 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2011 - 2014 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file dht/gnunet-service-xdht_routing.c | ||
23 | * @brief GNUnet DHT tracking of requests for routing replies | ||
24 | * @author Supriti Singh | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet-service-dht_neighbours.h" | ||
28 | #include "gnunet-service-xdht_neighbours.h" | ||
29 | #include "gnunet-service-xdht_routing.h" | ||
30 | #include "gnunet-service-dht.h" | ||
31 | |||
32 | |||
33 | /** | ||
34 | * FIXME: Check if its better to store pointer to friend rather than storing | ||
35 | * peer identity next_hop or prev_hop. | ||
36 | * keep entries in destnation and source peer also. so when we send the trail | ||
37 | * teardown message then we don't know the source but if source gets the message | ||
38 | * then it shold remove that trail id from its finger table. But how does | ||
39 | * source know what is the desination finger ? It will whenevr contact a trail | ||
40 | * will do a lookup in routing table and if no trail id present the remove | ||
41 | * that trail of the finger and if only one trail then remove the finger. | ||
42 | * because of this use case of trail teardown I think trail compression | ||
43 | * and trail teardown should not be merged. | ||
44 | * 2. store a pointer to friendInfo in place o peer identity. | ||
45 | */ | ||
46 | /** | ||
47 | * Maximum number of entries in routing table. | ||
48 | */ | ||
49 | #define ROUTING_TABLE_THRESHOLD 80000 | ||
50 | |||
51 | /** | ||
52 | * FIXME: Store friend pointer instead of peer identifier. | ||
53 | * Routing table entry . | ||
54 | */ | ||
55 | struct RoutingTrail | ||
56 | { | ||
57 | /** | ||
58 | * Global Unique identifier of the trail. | ||
59 | */ | ||
60 | struct GNUNET_HashCode trail_id; | ||
61 | |||
62 | /** | ||
63 | * The peer to which this request should be passed to. | ||
64 | */ | ||
65 | struct GNUNET_PeerIdentity next_hop; | ||
66 | |||
67 | /** | ||
68 | * Peer just before next hop in the trail. | ||
69 | */ | ||
70 | struct GNUNET_PeerIdentity prev_hop; | ||
71 | }; | ||
72 | |||
73 | /** | ||
74 | * Routing table of the peer | ||
75 | */ | ||
76 | static struct GNUNET_CONTAINER_MultiHashMap *routing_table; | ||
77 | |||
78 | /** | ||
79 | * Update the prev. hop of the trail. Call made by trail compression where | ||
80 | * if you are the first friend now in the trail then you need to update | ||
81 | * your prev. hop. | ||
82 | * @param trail_id | ||
83 | * @return #GNUNET_OK success | ||
84 | * #GNUNET_SYSERR in case no matching entry found in routing table. | ||
85 | */ | ||
86 | int | ||
87 | GDS_ROUTING_update_trail_prev_hop (const struct GNUNET_HashCode *trail_id, | ||
88 | const struct GNUNET_PeerIdentity *prev_hop) | ||
89 | { | ||
90 | struct RoutingTrail *trail; | ||
91 | |||
92 | trail = GNUNET_CONTAINER_multihashmap_get (routing_table, | ||
93 | trail_id); | ||
94 | |||
95 | if (NULL == trail) | ||
96 | return GNUNET_SYSERR; | ||
97 | trail->prev_hop = *prev_hop; | ||
98 | return GNUNET_OK; | ||
99 | } | ||
100 | |||
101 | |||
102 | /** | ||
103 | * Update the next hop of the trail. Call made by trail compression where | ||
104 | * if you are source of the trail and now you have a new first friend, then | ||
105 | * you should update the trail. | ||
106 | * @param trail_id | ||
107 | * @return #GNUNET_OK success | ||
108 | * #GNUNET_SYSERR in case no matching entry found in routing table. | ||
109 | */ | ||
110 | int | ||
111 | GDS_ROUTING_update_trail_next_hop (const struct GNUNET_HashCode *trail_id, | ||
112 | const struct GNUNET_PeerIdentity *next_hop) | ||
113 | { | ||
114 | struct RoutingTrail *trail; | ||
115 | |||
116 | trail = GNUNET_CONTAINER_multihashmap_get (routing_table, | ||
117 | trail_id); | ||
118 | if (NULL == trail) | ||
119 | return GNUNET_SYSERR; | ||
120 | trail->next_hop = *next_hop; | ||
121 | return GNUNET_OK; | ||
122 | } | ||
123 | |||
124 | |||
125 | /** | ||
126 | * Get the next hop for trail corresponding to trail_id | ||
127 | * | ||
128 | * @param trail_id Trail id to be searched. | ||
129 | * @return Next_hop if found | ||
130 | * NULL If next hop not found. | ||
131 | */ | ||
132 | const struct GNUNET_PeerIdentity * | ||
133 | GDS_ROUTING_get_next_hop (const struct GNUNET_HashCode *trail_id, | ||
134 | enum GDS_ROUTING_trail_direction trail_direction) | ||
135 | { | ||
136 | struct RoutingTrail *trail; | ||
137 | |||
138 | trail = GNUNET_CONTAINER_multihashmap_get (routing_table, | ||
139 | trail_id); | ||
140 | if (NULL == trail) | ||
141 | { | ||
142 | /* If a friend got disconnected and we removed all the entry from the | ||
143 | routing table, then trail will be deleted and my identity will not know | ||
144 | and when it tries to reach to that finger it fails. thats why | ||
145 | assertion always fails in*/ | ||
146 | return NULL; | ||
147 | } | ||
148 | switch (trail_direction) | ||
149 | { | ||
150 | case GDS_ROUTING_SRC_TO_DEST: | ||
151 | return &trail->next_hop; | ||
152 | case GDS_ROUTING_DEST_TO_SRC: | ||
153 | return &trail->prev_hop; | ||
154 | } | ||
155 | return NULL; | ||
156 | } | ||
157 | |||
158 | |||
159 | /** | ||
160 | * Remove trail with trail_id | ||
161 | * @param trail_id Trail id to be removed | ||
162 | * @return #GNUNET_YES success | ||
163 | * #GNUNET_NO if entry not found. | ||
164 | */ | ||
165 | int | ||
166 | GDS_ROUTING_remove_trail (const struct GNUNET_HashCode *remove_trail_id) | ||
167 | { | ||
168 | struct RoutingTrail *remove_entry; | ||
169 | |||
170 | remove_entry = GNUNET_CONTAINER_multihashmap_get (routing_table, | ||
171 | remove_trail_id); | ||
172 | if (NULL == remove_entry) | ||
173 | return GNUNET_NO; | ||
174 | |||
175 | if (GNUNET_YES == | ||
176 | GNUNET_CONTAINER_multihashmap_remove (routing_table, | ||
177 | remove_trail_id, | ||
178 | remove_entry)) | ||
179 | { | ||
180 | GNUNET_free (remove_entry); | ||
181 | return GNUNET_YES; | ||
182 | } | ||
183 | return GNUNET_NO; | ||
184 | } | ||
185 | |||
186 | |||
187 | /** | ||
188 | * Iterate over routing table and remove entries with value as part of any trail. | ||
189 | * | ||
190 | * @param cls closure | ||
191 | * @param key current public key | ||
192 | * @param value value in the hash map | ||
193 | * @return #GNUNET_YES if we should continue to iterate, | ||
194 | * #GNUNET_NO if not. | ||
195 | */ | ||
196 | static int | ||
197 | remove_matching_trails (void *cls, | ||
198 | const struct GNUNET_HashCode *key, | ||
199 | void *value) | ||
200 | { | ||
201 | struct RoutingTrail *remove_trail = value; | ||
202 | struct GNUNET_PeerIdentity *disconnected_peer = cls; | ||
203 | struct GNUNET_HashCode trail_id = *key; | ||
204 | struct GNUNET_PeerIdentity my_identity; | ||
205 | |||
206 | /* If disconnected_peer is next_hop, then send a trail teardown message through | ||
207 | * prev_hop in direction from destination to source. */ | ||
208 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&remove_trail->next_hop, | ||
209 | disconnected_peer)) | ||
210 | { | ||
211 | my_identity = *GDS_NEIGHBOURS_get_id (); | ||
212 | if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity, | ||
213 | &remove_trail->prev_hop)) | ||
214 | { | ||
215 | GDS_NEIGHBOURS_send_trail_teardown (&trail_id, | ||
216 | GDS_ROUTING_DEST_TO_SRC, | ||
217 | &remove_trail->prev_hop); | ||
218 | } | ||
219 | } | ||
220 | |||
221 | /* If disconnected_peer is prev_hop, then send a trail teardown through | ||
222 | * next_hop in direction from Source to Destination. */ | ||
223 | if (0 == GNUNET_CRYPTO_cmp_peer_identity (&remove_trail->prev_hop, | ||
224 | disconnected_peer)) | ||
225 | { | ||
226 | my_identity = *GDS_NEIGHBOURS_get_id (); | ||
227 | |||
228 | if (0 != GNUNET_CRYPTO_cmp_peer_identity (&my_identity, | ||
229 | &remove_trail->next_hop)) | ||
230 | { | ||
231 | GDS_NEIGHBOURS_send_trail_teardown (&trail_id, | ||
232 | GDS_ROUTING_SRC_TO_DEST, | ||
233 | &remove_trail->next_hop); | ||
234 | } | ||
235 | } | ||
236 | |||
237 | GNUNET_assert (GNUNET_YES == | ||
238 | GNUNET_CONTAINER_multihashmap_remove (routing_table, | ||
239 | &trail_id, | ||
240 | remove_trail)); | ||
241 | GNUNET_free (remove_trail); | ||
242 | return GNUNET_YES; | ||
243 | } | ||
244 | |||
245 | #if 0 | ||
246 | /** | ||
247 | * TEST FUNCTION | ||
248 | * Remove after using. | ||
249 | */ | ||
250 | void | ||
251 | GDS_ROUTING_test_print (void) | ||
252 | { | ||
253 | struct GNUNET_CONTAINER_MultiHashMapIterator *iter; | ||
254 | struct RoutingTrail *trail; | ||
255 | struct GNUNET_PeerIdentity print_peer; | ||
256 | struct GNUNET_HashCode key_ret; | ||
257 | int i; | ||
258 | |||
259 | struct GNUNET_PeerIdentity my_identity = *GDS_NEIGHBOURS_get_id(); | ||
260 | print_peer = my_identity; | ||
261 | FPRINTF (stderr,_("\nSUPU ***PRINTING ROUTING TABLE ***** of =%s"),GNUNET_i2s(&print_peer)); | ||
262 | iter =GNUNET_CONTAINER_multihashmap_iterator_create (routing_table); | ||
263 | for (i = 0; i < GNUNET_CONTAINER_multihashmap_size(routing_table); i++) | ||
264 | { | ||
265 | if(GNUNET_YES == GNUNET_CONTAINER_multihashmap_iterator_next (iter, | ||
266 | &key_ret, | ||
267 | (const void **)&trail)) | ||
268 | { | ||
269 | FPRINTF (stderr,_("\nSUPU %s, %s, %d, trail->trail_id = %s"), | ||
270 | __FILE__, __func__,__LINE__, GNUNET_h2s(&trail->trail_id)); | ||
271 | GNUNET_memcpy (&print_peer, &trail->next_hop, sizeof (struct GNUNET_PeerIdentity)); | ||
272 | FPRINTF (stderr,_("\nSUPU %s, %s, %d, trail->next_hop = %s"), | ||
273 | __FILE__, __func__,__LINE__, GNUNET_i2s(&print_peer)); | ||
274 | GNUNET_memcpy (&print_peer, &trail->prev_hop, sizeof (struct GNUNET_PeerIdentity)); | ||
275 | FPRINTF (stderr,_("\nSUPU %s, %s, %d, trail->prev_hop = %s"), | ||
276 | __FILE__, __func__,__LINE__, GNUNET_i2s(&print_peer)); | ||
277 | } | ||
278 | } | ||
279 | } | ||
280 | #endif | ||
281 | |||
282 | /** | ||
283 | * Remove every trail where peer is either next_hop or prev_hop. Also send a | ||
284 | * trail teardown message in direction of hop which is not disconnected. | ||
285 | * @param peer Peer identity. Trail containing this peer should be removed. | ||
286 | */ | ||
287 | int | ||
288 | GDS_ROUTING_remove_trail_by_peer (const struct GNUNET_PeerIdentity *peer) | ||
289 | { | ||
290 | int ret; | ||
291 | |||
292 | |||
293 | /* No entries in my routing table. */ | ||
294 | if (0 == GNUNET_CONTAINER_multihashmap_size(routing_table)) | ||
295 | return GNUNET_YES; | ||
296 | |||
297 | ret = GNUNET_CONTAINER_multihashmap_iterate (routing_table, | ||
298 | &remove_matching_trails, | ||
299 | (void *)peer); | ||
300 | return ret; | ||
301 | } | ||
302 | |||
303 | |||
304 | /** | ||
305 | * Add a new entry in routing table | ||
306 | * @param new_trail_id | ||
307 | * @param prev_hop | ||
308 | * @param next_hop | ||
309 | * @return #GNUNET_OK success | ||
310 | * #GNUNET_SYSERR in case new_trail_id already exists in the network | ||
311 | * but with different prev_hop/next_hop | ||
312 | */ | ||
313 | int | ||
314 | GDS_ROUTING_add (const struct GNUNET_HashCode *new_trail_id, | ||
315 | const struct GNUNET_PeerIdentity *prev_hop, | ||
316 | const struct GNUNET_PeerIdentity *next_hop) | ||
317 | { | ||
318 | struct RoutingTrail *new_entry; | ||
319 | |||
320 | new_entry = GNUNET_new (struct RoutingTrail); | ||
321 | new_entry->trail_id = *new_trail_id; | ||
322 | new_entry->next_hop = *next_hop; | ||
323 | new_entry->prev_hop = *prev_hop; | ||
324 | |||
325 | // FIXME: this leaks memory if the put fails! | ||
326 | return GNUNET_CONTAINER_multihashmap_put (routing_table, | ||
327 | &new_entry->trail_id, | ||
328 | new_entry, | ||
329 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | ||
330 | } | ||
331 | |||
332 | |||
333 | /** | ||
334 | * Check if the size of routing table has crossed ROUTING_TABLE_THRESHOLD. | ||
335 | * It means that I don't have any more space in my routing table and I can not | ||
336 | * be part of any more trails till there is free space in my routing table. | ||
337 | * @return #GNUNET_YES, if threshold crossed else #GNUNET_NO. | ||
338 | */ | ||
339 | int | ||
340 | GDS_ROUTING_threshold_reached (void) | ||
341 | { | ||
342 | return (GNUNET_CONTAINER_multihashmap_size(routing_table) > | ||
343 | ROUTING_TABLE_THRESHOLD) ? GNUNET_YES:GNUNET_NO; | ||
344 | } | ||
345 | |||
346 | |||
347 | /** | ||
348 | * Initialize routing subsystem. | ||
349 | */ | ||
350 | void | ||
351 | GDS_ROUTING_init (void) | ||
352 | { | ||
353 | routing_table = GNUNET_CONTAINER_multihashmap_create (ROUTING_TABLE_THRESHOLD * 4 / 3, | ||
354 | GNUNET_NO); | ||
355 | } | ||
356 | |||
357 | |||
358 | /** | ||
359 | * Shutdown routing subsystem. | ||
360 | */ | ||
361 | void | ||
362 | GDS_ROUTING_done (void) | ||
363 | { | ||
364 | GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size (routing_table)); | ||
365 | GNUNET_CONTAINER_multihashmap_destroy (routing_table); | ||
366 | } | ||
367 | |||
368 | /* end of gnunet-service-xdht_routing.c */ | ||
diff --git a/src/dht/gnunet-service-xdht_routing.h b/src/dht/gnunet-service-xdht_routing.h deleted file mode 100644 index 69ab1ff78..000000000 --- a/src/dht/gnunet-service-xdht_routing.h +++ /dev/null | |||
@@ -1,141 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2011 - 2014 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file dht/gnunet-service-xdht_routing.h | ||
23 | * @brief GNUnet DHT tracking of requests for routing replies | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | #ifndef GNUNET_SERVICE_XDHT_ROUTING_H | ||
27 | #define GNUNET_SERVICE_XDHT_ROUTING_H | ||
28 | |||
29 | #include "gnunet_util_lib.h" | ||
30 | #include "gnunet_block_lib.h" | ||
31 | #include "gnunet_dht_service.h" | ||
32 | |||
33 | /** | ||
34 | * To understand the direction in which trial should be read. | ||
35 | */ | ||
36 | enum GDS_ROUTING_trail_direction | ||
37 | { | ||
38 | GDS_ROUTING_SRC_TO_DEST, | ||
39 | GDS_ROUTING_DEST_TO_SRC | ||
40 | }; | ||
41 | |||
42 | |||
43 | /** | ||
44 | * Update the prev. hop of the trail. Call made by trail teardown where | ||
45 | * if you are the first friend now in the trail then you need to update | ||
46 | * your prev. hop. | ||
47 | * @param trail_id | ||
48 | * @return #GNUNET_OK success | ||
49 | * #GNUNET_SYSERR in case no matching entry found in routing table. | ||
50 | */ | ||
51 | int | ||
52 | GDS_ROUTING_update_trail_prev_hop (const struct GNUNET_HashCode *trail_id, | ||
53 | const struct GNUNET_PeerIdentity *prev_hop); | ||
54 | |||
55 | |||
56 | /** | ||
57 | * Update the next hop of the trail. Call made by trail compression where | ||
58 | * if you are source of the trail and now you have a new first friend, then | ||
59 | * you should update the trail. | ||
60 | * @param trail_id | ||
61 | * @return #GNUNET_OK success | ||
62 | * #GNUNET_SYSERR in case no matching entry found in routing table. | ||
63 | */ | ||
64 | int | ||
65 | GDS_ROUTING_update_trail_next_hop (const struct GNUNET_HashCode *trail_id, | ||
66 | const struct GNUNET_PeerIdentity *next_hop); | ||
67 | |||
68 | /** | ||
69 | * Get the next hop for trail corresponding to trail_id | ||
70 | * @param trail_id Trail id to be searched. | ||
71 | * @return Next_hop if found | ||
72 | * NULL If next hop not found. | ||
73 | */ | ||
74 | const struct GNUNET_PeerIdentity * | ||
75 | GDS_ROUTING_get_next_hop (const struct GNUNET_HashCode *trail_id, | ||
76 | enum GDS_ROUTING_trail_direction trail_direction); | ||
77 | |||
78 | |||
79 | /** | ||
80 | * Remove every trail where peer is either next_hop or prev_hop | ||
81 | * @param peer Peer to be searched. | ||
82 | */ | ||
83 | int | ||
84 | GDS_ROUTING_remove_trail_by_peer (const struct GNUNET_PeerIdentity *peer); | ||
85 | |||
86 | |||
87 | /** | ||
88 | * Remove trail with trail_id | ||
89 | * | ||
90 | * @param trail_id Trail id to be removed | ||
91 | * @return #GNUNET_YES success | ||
92 | * #GNUNET_NO if entry not found. | ||
93 | */ | ||
94 | int | ||
95 | GDS_ROUTING_remove_trail (const struct GNUNET_HashCode *remove_trail_id); | ||
96 | |||
97 | |||
98 | /** | ||
99 | * Add a new entry in routing table | ||
100 | * @param new_trail_id | ||
101 | * @param prev_hop | ||
102 | * @param next_hop | ||
103 | * @return #GNUNET_OK success | ||
104 | * #GNUNET_SYSERR in case new_trail_id already exists in the network | ||
105 | * but with different prev_hop/next_hop | ||
106 | */ | ||
107 | int | ||
108 | GDS_ROUTING_add (const struct GNUNET_HashCode *new_trail_id, | ||
109 | const struct GNUNET_PeerIdentity *prev_hop, | ||
110 | const struct GNUNET_PeerIdentity *next_hop); | ||
111 | |||
112 | |||
113 | /** | ||
114 | * Check if the size of routing table has crossed threshold. | ||
115 | * @return #GNUNET_YES, if threshold crossed | ||
116 | * #GNUNET_NO, if size is within threshold | ||
117 | */ | ||
118 | int | ||
119 | GDS_ROUTING_threshold_reached (void); | ||
120 | |||
121 | #if 0 | ||
122 | /** | ||
123 | * Test function. Remove afterwards. | ||
124 | */ | ||
125 | void | ||
126 | GDS_ROUTING_test_print (void); | ||
127 | #endif | ||
128 | |||
129 | /** | ||
130 | * Initialize routing subsystem. | ||
131 | */ | ||
132 | void | ||
133 | GDS_ROUTING_init (void); | ||
134 | |||
135 | /** | ||
136 | * Shutdown routing subsystem. | ||
137 | */ | ||
138 | void | ||
139 | GDS_ROUTING_done (void); | ||
140 | |||
141 | #endif | ||
diff --git a/src/dht/plugin_block_dht.c b/src/dht/plugin_block_dht.c index 0304dad87..24f8b21b2 100644 --- a/src/dht/plugin_block_dht.c +++ b/src/dht/plugin_block_dht.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | Copyright (C) 2010 GNUnet e.V. | 3 | Copyright (C) 2010, 2017 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -34,9 +34,10 @@ | |||
34 | #define DEBUG_DHT GNUNET_EXTRA_LOGGING | 34 | #define DEBUG_DHT GNUNET_EXTRA_LOGGING |
35 | 35 | ||
36 | /** | 36 | /** |
37 | * How big is the BF we use for DHT blocks? | 37 | * Number of bits we set per entry in the bloomfilter. |
38 | * Do not change! | ||
38 | */ | 39 | */ |
39 | #define DHT_BF_SIZE 8 | 40 | #define BLOOMFILTER_K 16 |
40 | 41 | ||
41 | 42 | ||
42 | /** | 43 | /** |
@@ -59,9 +60,26 @@ block_plugin_dht_create_group (void *cls, | |||
59 | size_t raw_data_size, | 60 | size_t raw_data_size, |
60 | va_list va) | 61 | va_list va) |
61 | { | 62 | { |
63 | unsigned int bf_size; | ||
64 | const char *guard; | ||
65 | |||
66 | guard = va_arg (va, const char *); | ||
67 | if (0 == strcmp (guard, | ||
68 | "seen-set-size")) | ||
69 | bf_size = GNUNET_BLOCK_GROUP_compute_bloomfilter_size (va_arg (va, unsigned int), | ||
70 | BLOOMFILTER_K); | ||
71 | else if (0 == strcmp (guard, | ||
72 | "filter-size")) | ||
73 | bf_size = va_arg (va, unsigned int); | ||
74 | else | ||
75 | { | ||
76 | GNUNET_break (0); | ||
77 | bf_size = 8; | ||
78 | } | ||
79 | GNUNET_break (NULL == va_arg (va, const char *)); | ||
62 | return GNUNET_BLOCK_GROUP_bf_create (cls, | 80 | return GNUNET_BLOCK_GROUP_bf_create (cls, |
63 | DHT_BF_SIZE, | 81 | bf_size, |
64 | GNUNET_CONSTANTS_BLOOMFILTER_K, | 82 | BLOOMFILTER_K, |
65 | type, | 83 | type, |
66 | nonce, | 84 | nonce, |
67 | raw_data, | 85 | raw_data, |
@@ -74,6 +92,7 @@ block_plugin_dht_create_group (void *cls, | |||
74 | * request evaluation, simply pass "NULL" for the @a reply_block. | 92 | * request evaluation, simply pass "NULL" for the @a reply_block. |
75 | * | 93 | * |
76 | * @param cls closure | 94 | * @param cls closure |
95 | * @param ctx context | ||
77 | * @param type block type | 96 | * @param type block type |
78 | * @param group block group to check against | 97 | * @param group block group to check against |
79 | * @param eo control flags | 98 | * @param eo control flags |
@@ -86,6 +105,7 @@ block_plugin_dht_create_group (void *cls, | |||
86 | */ | 105 | */ |
87 | static enum GNUNET_BLOCK_EvaluationResult | 106 | static enum GNUNET_BLOCK_EvaluationResult |
88 | block_plugin_dht_evaluate (void *cls, | 107 | block_plugin_dht_evaluate (void *cls, |
108 | struct GNUNET_BLOCK_Context *ctx, | ||
89 | enum GNUNET_BLOCK_Type type, | 109 | enum GNUNET_BLOCK_Type type, |
90 | struct GNUNET_BLOCK_Group *group, | 110 | struct GNUNET_BLOCK_Group *group, |
91 | enum GNUNET_BLOCK_EvaluationOptions eo, | 111 | enum GNUNET_BLOCK_EvaluationOptions eo, |
@@ -217,7 +237,7 @@ libgnunet_plugin_block_dht_init (void *cls) | |||
217 | void * | 237 | void * |
218 | libgnunet_plugin_block_dht_done (void *cls) | 238 | libgnunet_plugin_block_dht_done (void *cls) |
219 | { | 239 | { |
220 | struct GNUNET_TRANSPORT_PluginFunctions *api = cls; | 240 | struct GNUNET_BLOCK_PluginFunctions *api = cls; |
221 | 241 | ||
222 | GNUNET_free (api); | 242 | GNUNET_free (api); |
223 | return NULL; | 243 | return NULL; |
diff --git a/src/dht/test_dht_api.c b/src/dht/test_dht_api.c index 99f17699c..8f4e0ed31 100644 --- a/src/dht/test_dht_api.c +++ b/src/dht/test_dht_api.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2009, 2015 GNUnet e.V. | 3 | Copyright (C) 2009, 2015, 2017 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -20,6 +20,7 @@ | |||
20 | /** | 20 | /** |
21 | * @file dht/test_dht_api.c | 21 | * @file dht/test_dht_api.c |
22 | * @brief base test case for dht api | 22 | * @brief base test case for dht api |
23 | * @author Christian Grothoff | ||
23 | * | 24 | * |
24 | * This test case tests DHT api to DUMMY DHT service communication. | 25 | * This test case tests DHT api to DUMMY DHT service communication. |
25 | */ | 26 | */ |
@@ -33,116 +34,70 @@ | |||
33 | /** | 34 | /** |
34 | * How long until we really give up on a particular testcase portion? | 35 | * How long until we really give up on a particular testcase portion? |
35 | */ | 36 | */ |
36 | #define TOTAL_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 600) | 37 | #define TOTAL_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60) |
37 | |||
38 | /** | ||
39 | * How long until we give up on any particular operation (and retry)? | ||
40 | */ | ||
41 | #define BASE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3) | ||
42 | |||
43 | #define MTYPE 12345 | ||
44 | |||
45 | |||
46 | struct RetryContext | ||
47 | { | ||
48 | /** | ||
49 | * When to really abort the operation. | ||
50 | */ | ||
51 | struct GNUNET_TIME_Absolute real_timeout; | ||
52 | |||
53 | /** | ||
54 | * What timeout to set for the current attempt (increases) | ||
55 | */ | ||
56 | struct GNUNET_TIME_Relative next_timeout; | ||
57 | |||
58 | /** | ||
59 | * The task identifier of the retry task, so it can be cancelled. | ||
60 | */ | ||
61 | struct GNUNET_SCHEDULER_Task * retry_task; | ||
62 | |||
63 | }; | ||
64 | |||
65 | 38 | ||
66 | static struct GNUNET_DHT_Handle *dht_handle; | 39 | static struct GNUNET_DHT_Handle *dht_handle; |
67 | 40 | ||
68 | static struct GNUNET_DHT_GetHandle *get_handle; | 41 | static struct GNUNET_DHT_GetHandle *get_handle; |
69 | 42 | ||
70 | struct RetryContext retry_context; | 43 | static struct GNUNET_DHT_PutHandle *put_handle; |
71 | 44 | ||
72 | static int ok = 1; | 45 | static int ok = 1; |
73 | 46 | ||
74 | static struct GNUNET_SCHEDULER_Task * die_task; | 47 | static struct GNUNET_SCHEDULER_Task *die_task; |
75 | |||
76 | |||
77 | #if VERBOSE | ||
78 | #define OKPP do { ok++; FPRINTF (stderr, "Now at stage %u at %s:%u\n", ok, __FILE__, __LINE__); } while (0) | ||
79 | #else | ||
80 | #define OKPP do { ok++; } while (0) | ||
81 | #endif | ||
82 | 48 | ||
83 | 49 | ||
84 | static void | 50 | static void |
85 | end (void *cls) | 51 | do_shutdown (void *cls) |
86 | { | 52 | { |
87 | GNUNET_SCHEDULER_cancel (die_task); | 53 | if (NULL != die_task) |
88 | die_task = NULL; | 54 | { |
89 | GNUNET_DHT_disconnect (dht_handle); | 55 | GNUNET_SCHEDULER_cancel (die_task); |
90 | dht_handle = NULL; | 56 | die_task = NULL; |
91 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 57 | } |
92 | "DHT disconnected, returning success!\n"); | 58 | if (NULL != put_handle) |
93 | ok = 0; | 59 | { |
94 | } | 60 | GNUNET_DHT_put_cancel (put_handle); |
95 | 61 | put_handle = NULL; | |
96 | 62 | } | |
97 | static void | 63 | if (NULL != get_handle) |
98 | end_badly () | ||
99 | { | ||
100 | /* do work here */ | ||
101 | FPRINTF (stderr, "%s", "Ending on an unhappy note.\n"); | ||
102 | if (get_handle != NULL) | ||
103 | { | 64 | { |
104 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping get request!\n"); | ||
105 | GNUNET_DHT_get_stop (get_handle); | 65 | GNUNET_DHT_get_stop (get_handle); |
66 | get_handle = NULL; | ||
106 | } | 67 | } |
107 | if (retry_context.retry_task != NULL) | ||
108 | GNUNET_SCHEDULER_cancel (retry_context.retry_task); | ||
109 | GNUNET_DHT_disconnect (dht_handle); | 68 | GNUNET_DHT_disconnect (dht_handle); |
110 | dht_handle = NULL; | 69 | dht_handle = NULL; |
111 | ok = 1; | ||
112 | } | 70 | } |
113 | 71 | ||
114 | 72 | ||
115 | /** | ||
116 | * Signature of the main function of a task. | ||
117 | * | ||
118 | * @param cls closure | ||
119 | */ | ||
120 | static void | 73 | static void |
121 | test_get_stop (void *cls) | 74 | end_badly (void *cls) |
122 | { | 75 | { |
123 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 76 | die_task = NULL; |
124 | "Called test_get_stop!\n"); | 77 | FPRINTF (stderr, |
125 | GNUNET_assert (NULL != dht_handle); | 78 | "%s", |
126 | GNUNET_DHT_get_stop (get_handle); | 79 | "Ending on an unhappy note.\n"); |
127 | get_handle = NULL; | 80 | GNUNET_SCHEDULER_shutdown (); |
128 | GNUNET_SCHEDULER_add_now (&end, NULL); | 81 | ok = 1; |
129 | } | 82 | } |
130 | 83 | ||
131 | 84 | ||
132 | static void | 85 | static void |
133 | test_get_iterator (void *cls, struct GNUNET_TIME_Absolute exp, | 86 | test_get_iterator (void *cls, |
134 | const struct GNUNET_HashCode * key, | 87 | struct GNUNET_TIME_Absolute exp, |
88 | const struct GNUNET_HashCode *key, | ||
135 | const struct GNUNET_PeerIdentity *get_path, | 89 | const struct GNUNET_PeerIdentity *get_path, |
136 | unsigned int get_path_length, | 90 | unsigned int get_path_length, |
137 | const struct GNUNET_PeerIdentity *put_path, | 91 | const struct GNUNET_PeerIdentity *put_path, |
138 | unsigned int put_path_length, | 92 | unsigned int put_path_length, |
139 | enum GNUNET_BLOCK_Type type, | 93 | enum GNUNET_BLOCK_Type type, |
140 | size_t size, const void *data) | 94 | size_t size, |
95 | const void *data) | ||
141 | { | 96 | { |
142 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 97 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
143 | "test_get_iterator called (we got a result), stopping get request!\n"); | 98 | "test_get_iterator called (we got a result), stopping get request!\n"); |
144 | GNUNET_SCHEDULER_add_now (&test_get_stop, | 99 | GNUNET_SCHEDULER_shutdown (); |
145 | NULL); | 100 | ok = 0; |
146 | } | 101 | } |
147 | 102 | ||
148 | 103 | ||
@@ -153,31 +108,33 @@ test_get_iterator (void *cls, struct GNUNET_TIME_Absolute exp, | |||
153 | * @param success result of PUT | 108 | * @param success result of PUT |
154 | */ | 109 | */ |
155 | static void | 110 | static void |
156 | test_get (void *cls, int success) | 111 | test_get (void *cls, |
112 | int success) | ||
157 | { | 113 | { |
158 | struct GNUNET_HashCode hash; | 114 | struct GNUNET_HashCode hash; |
159 | 115 | ||
116 | put_handle = NULL; | ||
160 | memset (&hash, | 117 | memset (&hash, |
161 | 42, | 118 | 42, |
162 | sizeof (struct GNUNET_HashCode)); | 119 | sizeof (struct GNUNET_HashCode)); |
163 | |||
164 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 120 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
165 | "Called test_get!\n"); | 121 | "Called test_get!\n"); |
166 | GNUNET_assert (dht_handle != NULL); | 122 | GNUNET_assert (dht_handle != NULL); |
167 | retry_context.real_timeout = GNUNET_TIME_relative_to_absolute (TOTAL_TIMEOUT); | 123 | get_handle = GNUNET_DHT_get_start (dht_handle, |
168 | retry_context.next_timeout = BASE_TIMEOUT; | 124 | GNUNET_BLOCK_TYPE_TEST, |
169 | 125 | &hash, | |
170 | get_handle = | 126 | 1, |
171 | GNUNET_DHT_get_start (dht_handle, | 127 | GNUNET_DHT_RO_NONE, |
172 | GNUNET_BLOCK_TYPE_TEST, &hash, 1, | 128 | NULL, |
173 | GNUNET_DHT_RO_NONE, NULL, 0, &test_get_iterator, | 129 | 0, |
174 | NULL); | 130 | &test_get_iterator, |
175 | 131 | NULL); | |
176 | if (get_handle == NULL) | 132 | |
133 | if (NULL == get_handle) | ||
177 | { | 134 | { |
178 | GNUNET_break (0); | 135 | GNUNET_break (0); |
179 | GNUNET_SCHEDULER_cancel (die_task); | 136 | ok = 1; |
180 | die_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL); | 137 | GNUNET_SCHEDULER_shutdown (); |
181 | return; | 138 | return; |
182 | } | 139 | } |
183 | } | 140 | } |
@@ -193,29 +150,38 @@ run (void *cls, | |||
193 | size_t data_size = 42; | 150 | size_t data_size = 42; |
194 | 151 | ||
195 | GNUNET_assert (ok == 1); | 152 | GNUNET_assert (ok == 1); |
196 | OKPP; | 153 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, |
197 | die_task = | 154 | NULL); |
198 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply | 155 | die_task = GNUNET_SCHEDULER_add_delayed (TOTAL_TIMEOUT, |
199 | (GNUNET_TIME_UNIT_MINUTES, 1), &end_badly, | 156 | &end_badly, |
200 | NULL); | 157 | NULL); |
201 | 158 | memset (&hash, | |
202 | 159 | 42, | |
203 | memset (&hash, 42, sizeof (struct GNUNET_HashCode)); | 160 | sizeof (struct GNUNET_HashCode)); |
204 | data = GNUNET_malloc (data_size); | 161 | data = GNUNET_malloc (data_size); |
205 | memset (data, 43, data_size); | 162 | memset (data, 43, data_size); |
206 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called test_put!\n"); | 163 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
207 | dht_handle = GNUNET_DHT_connect (cfg, 100); | 164 | "Called test_put!\n"); |
208 | GNUNET_assert (dht_handle != NULL); | 165 | dht_handle = GNUNET_DHT_connect (cfg, |
209 | GNUNET_DHT_put (dht_handle, &hash, 1, GNUNET_DHT_RO_NONE, | 166 | 100); |
210 | GNUNET_BLOCK_TYPE_TEST, data_size, data, | 167 | GNUNET_assert (NULL != dht_handle); |
211 | GNUNET_TIME_relative_to_absolute (TOTAL_TIMEOUT), | 168 | put_handle = GNUNET_DHT_put (dht_handle, |
212 | &test_get, NULL); | 169 | &hash, |
170 | 1, | ||
171 | GNUNET_DHT_RO_NONE, | ||
172 | GNUNET_BLOCK_TYPE_TEST, | ||
173 | data_size, | ||
174 | data, | ||
175 | GNUNET_TIME_relative_to_absolute (TOTAL_TIMEOUT), | ||
176 | &test_get, | ||
177 | NULL); | ||
213 | GNUNET_free (data); | 178 | GNUNET_free (data); |
214 | } | 179 | } |
215 | 180 | ||
216 | 181 | ||
217 | int | 182 | int |
218 | main (int argc, char *argv[]) | 183 | main (int argc, |
184 | char *argv[]) | ||
219 | { | 185 | { |
220 | if (0 != GNUNET_TESTING_peer_run ("test-dht-api", | 186 | if (0 != GNUNET_TESTING_peer_run ("test-dht-api", |
221 | "test_dht_api_data.conf", | 187 | "test_dht_api_data.conf", |
diff --git a/src/dht/test_dht_monitor.c b/src/dht/test_dht_monitor.c index 5e6fc074a..3de800144 100644 --- a/src/dht/test_dht_monitor.c +++ b/src/dht/test_dht_monitor.c | |||
@@ -90,7 +90,7 @@ static unsigned int NUM_PEERS = 3; | |||
90 | /** | 90 | /** |
91 | * Task called to disconnect peers. | 91 | * Task called to disconnect peers. |
92 | */ | 92 | */ |
93 | static struct GNUNET_SCHEDULER_Task * timeout_task; | 93 | static struct GNUNET_SCHEDULER_Task *timeout_task; |
94 | 94 | ||
95 | /** | 95 | /** |
96 | * Task to do DHT_puts | 96 | * Task to do DHT_puts |
@@ -107,7 +107,7 @@ static unsigned int monitor_counter; | |||
107 | * Terminates active get operations and shuts down | 107 | * Terminates active get operations and shuts down |
108 | * the testbed. | 108 | * the testbed. |
109 | * | 109 | * |
110 | * @param cls the 'struct GNUNET_DHT_TestContext' | 110 | * @param cls the `struct GNUNET_DHT_TEST_Context` |
111 | */ | 111 | */ |
112 | static void | 112 | static void |
113 | shutdown_task (void *cls) | 113 | shutdown_task (void *cls) |
@@ -133,6 +133,26 @@ shutdown_task (void *cls) | |||
133 | GNUNET_free (monitors); | 133 | GNUNET_free (monitors); |
134 | GNUNET_SCHEDULER_cancel (put_task); | 134 | GNUNET_SCHEDULER_cancel (put_task); |
135 | GNUNET_DHT_TEST_cleanup (ctx); | 135 | GNUNET_DHT_TEST_cleanup (ctx); |
136 | if (NULL != timeout_task) | ||
137 | { | ||
138 | GNUNET_SCHEDULER_cancel (timeout_task); | ||
139 | timeout_task = NULL; | ||
140 | } | ||
141 | } | ||
142 | |||
143 | |||
144 | /** | ||
145 | * Task run on success or timeout to clean up. | ||
146 | * Terminates active get operations and shuts down | ||
147 | * the testbed. | ||
148 | * | ||
149 | * @param cls NULL | ||
150 | */ | ||
151 | static void | ||
152 | timeout_task_cb (void *cls) | ||
153 | { | ||
154 | timeout_task = NULL; | ||
155 | GNUNET_SCHEDULER_shutdown (); | ||
136 | } | 156 | } |
137 | 157 | ||
138 | 158 | ||
@@ -157,12 +177,12 @@ dht_get_handler (void *cls, struct GNUNET_TIME_Absolute exp, | |||
157 | const struct GNUNET_PeerIdentity *get_path, | 177 | const struct GNUNET_PeerIdentity *get_path, |
158 | unsigned int get_path_length, | 178 | unsigned int get_path_length, |
159 | const struct GNUNET_PeerIdentity *put_path, | 179 | const struct GNUNET_PeerIdentity *put_path, |
160 | unsigned int put_path_length, enum GNUNET_BLOCK_Type type, | 180 | unsigned int put_path_length, |
181 | enum GNUNET_BLOCK_Type type, | ||
161 | size_t size, const void *data) | 182 | size_t size, const void *data) |
162 | { | 183 | { |
163 | struct GetOperation *get_op = cls; | 184 | struct GetOperation *get_op = cls; |
164 | struct GNUNET_HashCode want; | 185 | struct GNUNET_HashCode want; |
165 | struct GNUNET_DHT_TestContext *ctx; | ||
166 | 186 | ||
167 | if (sizeof (struct GNUNET_HashCode) != size) | 187 | if (sizeof (struct GNUNET_HashCode) != size) |
168 | { | 188 | { |
@@ -186,8 +206,7 @@ dht_get_handler (void *cls, struct GNUNET_TIME_Absolute exp, | |||
186 | return; | 206 | return; |
187 | /* all DHT GET operations successful; terminate! */ | 207 | /* all DHT GET operations successful; terminate! */ |
188 | ok = 0; | 208 | ok = 0; |
189 | ctx = GNUNET_SCHEDULER_cancel (timeout_task); | 209 | GNUNET_SCHEDULER_shutdown (); |
190 | timeout_task = GNUNET_SCHEDULER_add_now (&shutdown_task, ctx); | ||
191 | } | 210 | } |
192 | 211 | ||
193 | 212 | ||
@@ -202,11 +221,10 @@ do_puts (void *cls) | |||
202 | struct GNUNET_DHT_Handle **hs = cls; | 221 | struct GNUNET_DHT_Handle **hs = cls; |
203 | struct GNUNET_HashCode key; | 222 | struct GNUNET_HashCode key; |
204 | struct GNUNET_HashCode value; | 223 | struct GNUNET_HashCode value; |
205 | unsigned int i; | ||
206 | 224 | ||
207 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 225 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
208 | "Putting values into DHT\n"); | 226 | "Putting values into DHT\n"); |
209 | for (i = 0; i < NUM_PEERS; i++) | 227 | for (unsigned int i = 0; i < NUM_PEERS; i++) |
210 | { | 228 | { |
211 | GNUNET_CRYPTO_hash (&i, sizeof (i), &key); | 229 | GNUNET_CRYPTO_hash (&i, sizeof (i), &key); |
212 | GNUNET_CRYPTO_hash (&key, sizeof (key), &value); | 230 | GNUNET_CRYPTO_hash (&key, sizeof (key), &value); |
@@ -360,7 +378,8 @@ run (void *cls, | |||
360 | 378 | ||
361 | GNUNET_assert (NUM_PEERS == num_peers); | 379 | GNUNET_assert (NUM_PEERS == num_peers); |
362 | my_peers = peers; | 380 | my_peers = peers; |
363 | monitors = GNUNET_malloc (num_peers * sizeof (struct GNUNET_DHT_MonitorHandle *)); | 381 | monitors = GNUNET_new_array (num_peers, |
382 | struct GNUNET_DHT_MonitorHandle *); | ||
364 | for (i = 0; i < num_peers; i++) | 383 | for (i = 0; i < num_peers; i++) |
365 | monitors[i] = GNUNET_DHT_monitor_start (dhts[i], | 384 | monitors[i] = GNUNET_DHT_monitor_start (dhts[i], |
366 | GNUNET_BLOCK_TYPE_ANY, | 385 | GNUNET_BLOCK_TYPE_ANY, |
@@ -392,7 +411,10 @@ run (void *cls, | |||
392 | } | 411 | } |
393 | } | 412 | } |
394 | timeout_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, | 413 | timeout_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, |
395 | &shutdown_task, ctx); | 414 | &timeout_task_cb, |
415 | NULL); | ||
416 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, | ||
417 | ctx); | ||
396 | } | 418 | } |
397 | 419 | ||
398 | 420 | ||
diff --git a/src/dns/plugin_block_dns.c b/src/dns/plugin_block_dns.c index 65da0de63..ca6ea84c4 100644 --- a/src/dns/plugin_block_dns.c +++ b/src/dns/plugin_block_dns.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | Copyright (C) 2013 GNUnet e.V. | 3 | Copyright (C) 2013, 2017 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -31,6 +31,61 @@ | |||
31 | #include "gnunet_block_plugin.h" | 31 | #include "gnunet_block_plugin.h" |
32 | #include "block_dns.h" | 32 | #include "block_dns.h" |
33 | #include "gnunet_signatures.h" | 33 | #include "gnunet_signatures.h" |
34 | #include "gnunet_block_group_lib.h" | ||
35 | |||
36 | |||
37 | /** | ||
38 | * Number of bits we set per entry in the bloomfilter. | ||
39 | * Do not change! | ||
40 | */ | ||
41 | #define BLOOMFILTER_K 16 | ||
42 | |||
43 | |||
44 | /** | ||
45 | * Create a new block group. | ||
46 | * | ||
47 | * @param ctx block context in which the block group is created | ||
48 | * @param type type of the block for which we are creating the group | ||
49 | * @param nonce random value used to seed the group creation | ||
50 | * @param raw_data optional serialized prior state of the group, NULL if unavailable/fresh | ||
51 | * @param raw_data_size number of bytes in @a raw_data, 0 if unavailable/fresh | ||
52 | * @param va variable arguments specific to @a type | ||
53 | * @return block group handle, NULL if block groups are not supported | ||
54 | * by this @a type of block (this is not an error) | ||
55 | */ | ||
56 | static struct GNUNET_BLOCK_Group * | ||
57 | block_plugin_dns_create_group (void *cls, | ||
58 | enum GNUNET_BLOCK_Type type, | ||
59 | uint32_t nonce, | ||
60 | const void *raw_data, | ||
61 | size_t raw_data_size, | ||
62 | va_list va) | ||
63 | { | ||
64 | unsigned int bf_size; | ||
65 | const char *guard; | ||
66 | |||
67 | guard = va_arg (va, const char *); | ||
68 | if (0 == strcmp (guard, | ||
69 | "seen-set-size")) | ||
70 | bf_size = GNUNET_BLOCK_GROUP_compute_bloomfilter_size (va_arg (va, unsigned int), | ||
71 | BLOOMFILTER_K); | ||
72 | else if (0 == strcmp (guard, | ||
73 | "filter-size")) | ||
74 | bf_size = va_arg (va, unsigned int); | ||
75 | else | ||
76 | { | ||
77 | GNUNET_break (0); | ||
78 | bf_size = 8; | ||
79 | } | ||
80 | GNUNET_break (NULL == va_arg (va, const char *)); | ||
81 | return GNUNET_BLOCK_GROUP_bf_create (cls, | ||
82 | bf_size, | ||
83 | BLOOMFILTER_K, | ||
84 | type, | ||
85 | nonce, | ||
86 | raw_data, | ||
87 | raw_data_size); | ||
88 | } | ||
34 | 89 | ||
35 | 90 | ||
36 | /** | 91 | /** |
@@ -38,6 +93,7 @@ | |||
38 | * request evaluation, simply pass "NULL" for the reply_block. | 93 | * request evaluation, simply pass "NULL" for the reply_block. |
39 | * | 94 | * |
40 | * @param cls closure | 95 | * @param cls closure |
96 | * @param ctx block context | ||
41 | * @param type block type | 97 | * @param type block type |
42 | * @param bg group to evaluate against | 98 | * @param bg group to evaluate against |
43 | * @param eo control flags | 99 | * @param eo control flags |
@@ -50,6 +106,7 @@ | |||
50 | */ | 106 | */ |
51 | static enum GNUNET_BLOCK_EvaluationResult | 107 | static enum GNUNET_BLOCK_EvaluationResult |
52 | block_plugin_dns_evaluate (void *cls, | 108 | block_plugin_dns_evaluate (void *cls, |
109 | struct GNUNET_BLOCK_Context *ctx, | ||
53 | enum GNUNET_BLOCK_Type type, | 110 | enum GNUNET_BLOCK_Type type, |
54 | struct GNUNET_BLOCK_Group *bg, | 111 | struct GNUNET_BLOCK_Group *bg, |
55 | enum GNUNET_BLOCK_EvaluationOptions eo, | 112 | enum GNUNET_BLOCK_EvaluationOptions eo, |
@@ -60,6 +117,7 @@ block_plugin_dns_evaluate (void *cls, | |||
60 | size_t reply_block_size) | 117 | size_t reply_block_size) |
61 | { | 118 | { |
62 | const struct GNUNET_DNS_Advertisement *ad; | 119 | const struct GNUNET_DNS_Advertisement *ad; |
120 | struct GNUNET_HashCode phash; | ||
63 | 121 | ||
64 | switch (type) | 122 | switch (type) |
65 | { | 123 | { |
@@ -101,6 +159,13 @@ block_plugin_dns_evaluate (void *cls, | |||
101 | GNUNET_break_op (0); | 159 | GNUNET_break_op (0); |
102 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | 160 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; |
103 | } | 161 | } |
162 | GNUNET_CRYPTO_hash (reply_block, | ||
163 | reply_block_size, | ||
164 | &phash); | ||
165 | if (GNUNET_YES == | ||
166 | GNUNET_BLOCK_GROUP_bf_test_and_set (bg, | ||
167 | &phash)) | ||
168 | return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE; | ||
104 | return GNUNET_BLOCK_EVALUATION_OK_MORE; | 169 | return GNUNET_BLOCK_EVALUATION_OK_MORE; |
105 | default: | 170 | default: |
106 | return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; | 171 | return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; |
@@ -147,6 +212,7 @@ libgnunet_plugin_block_dns_init (void *cls) | |||
147 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); | 212 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); |
148 | api->evaluate = &block_plugin_dns_evaluate; | 213 | api->evaluate = &block_plugin_dns_evaluate; |
149 | api->get_key = &block_plugin_dns_get_key; | 214 | api->get_key = &block_plugin_dns_get_key; |
215 | api->create_group = &block_plugin_dns_create_group; | ||
150 | api->types = types; | 216 | api->types = types; |
151 | return api; | 217 | return api; |
152 | } | 218 | } |
diff --git a/src/dv/gnunet-service-dv.c b/src/dv/gnunet-service-dv.c index 6adaa04d9..7d101c8ae 100644 --- a/src/dv/gnunet-service-dv.c +++ b/src/dv/gnunet-service-dv.c | |||
@@ -1346,11 +1346,13 @@ check_target_added (void *cls, | |||
1346 | * | 1346 | * |
1347 | * @param cls the `struct DirectNeighbor` we're building the consensus with | 1347 | * @param cls the `struct DirectNeighbor` we're building the consensus with |
1348 | * @param element a result element, only valid if status is #GNUNET_SET_STATUS_OK | 1348 | * @param element a result element, only valid if status is #GNUNET_SET_STATUS_OK |
1349 | * @param current_size current set size | ||
1349 | * @param status see `enum GNUNET_SET_Status` | 1350 | * @param status see `enum GNUNET_SET_Status` |
1350 | */ | 1351 | */ |
1351 | static void | 1352 | static void |
1352 | handle_set_union_result (void *cls, | 1353 | handle_set_union_result (void *cls, |
1353 | const struct GNUNET_SET_Element *element, | 1354 | const struct GNUNET_SET_Element *element, |
1355 | uint64_t current_size, | ||
1354 | enum GNUNET_SET_Status status) | 1356 | enum GNUNET_SET_Status status) |
1355 | { | 1357 | { |
1356 | struct DirectNeighbor *neighbor = cls; | 1358 | struct DirectNeighbor *neighbor = cls; |
@@ -1528,6 +1530,7 @@ listen_set_union (void *cls, | |||
1528 | GNUNET_SET_OPERATION_UNION); | 1530 | GNUNET_SET_OPERATION_UNION); |
1529 | neighbor->set_op = GNUNET_SET_accept (request, | 1531 | neighbor->set_op = GNUNET_SET_accept (request, |
1530 | GNUNET_SET_RESULT_ADDED, | 1532 | GNUNET_SET_RESULT_ADDED, |
1533 | (struct GNUNET_SET_Option[]) { 0 }, | ||
1531 | &handle_set_union_result, | 1534 | &handle_set_union_result, |
1532 | neighbor); | 1535 | neighbor); |
1533 | neighbor->consensus_insertion_offset = 0; | 1536 | neighbor->consensus_insertion_offset = 0; |
@@ -1558,6 +1561,7 @@ initiate_set_union (void *cls) | |||
1558 | &neighbor->real_session_id, | 1561 | &neighbor->real_session_id, |
1559 | NULL, | 1562 | NULL, |
1560 | GNUNET_SET_RESULT_ADDED, | 1563 | GNUNET_SET_RESULT_ADDED, |
1564 | (struct GNUNET_SET_Option[]) { 0 }, | ||
1561 | &handle_set_union_result, | 1565 | &handle_set_union_result, |
1562 | neighbor); | 1566 | neighbor); |
1563 | neighbor->consensus_insertion_offset = 0; | 1567 | neighbor->consensus_insertion_offset = 0; |
diff --git a/src/exit/Makefile.am b/src/exit/Makefile.am index 6c4cbf114..271b4ebd7 100644 --- a/src/exit/Makefile.am +++ b/src/exit/Makefile.am | |||
@@ -30,11 +30,11 @@ endif | |||
30 | 30 | ||
31 | libexec_PROGRAMS = \ | 31 | libexec_PROGRAMS = \ |
32 | gnunet-daemon-exit \ | 32 | gnunet-daemon-exit \ |
33 | $(EXITBIN) | 33 | $(EXITBIN) |
34 | 34 | ||
35 | if MINGW | 35 | if MINGW |
36 | gnunet_helper_exit_LDFLAGS = \ | 36 | gnunet_helper_exit_LDFLAGS = \ |
37 | -no-undefined -Wl,--export-all-symbols | 37 | -no-undefined -Wl,--export-all-symbols |
38 | 38 | ||
39 | gnunet_helper_exit_LDADD = \ | 39 | gnunet_helper_exit_LDADD = \ |
40 | -lsetupapi -lnewdev -lshell32 -liconv -lstdc++ \ | 40 | -lsetupapi -lnewdev -lshell32 -liconv -lstdc++ \ |
@@ -47,13 +47,13 @@ else | |||
47 | gnunet-helper-exit.c | 47 | gnunet-helper-exit.c |
48 | endif | 48 | endif |
49 | gnunet_daemon_exit_SOURCES = \ | 49 | gnunet_daemon_exit_SOURCES = \ |
50 | gnunet-daemon-exit.c exit.h | 50 | gnunet-daemon-exit.c exit.h |
51 | gnunet_daemon_exit_LDADD = \ | 51 | gnunet_daemon_exit_LDADD = \ |
52 | $(top_builddir)/src/dns/libgnunetdnsstub.la \ | 52 | $(top_builddir)/src/dns/libgnunetdnsstub.la \ |
53 | $(top_builddir)/src/dht/libgnunetdht.la \ | 53 | $(top_builddir)/src/dht/libgnunetdht.la \ |
54 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | 54 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ |
55 | $(top_builddir)/src/tun/libgnunettun.la \ | 55 | $(top_builddir)/src/tun/libgnunettun.la \ |
56 | $(top_builddir)/src/util/libgnunetutil.la \ | 56 | $(top_builddir)/src/util/libgnunetutil.la \ |
57 | $(top_builddir)/src/cadet/libgnunetcadet.la \ | 57 | $(top_builddir)/src/cadet/libgnunetcadetnew.la \ |
58 | $(top_builddir)/src/regex/libgnunetregex.la \ | 58 | $(top_builddir)/src/regex/libgnunetregex.la \ |
59 | $(GN_LIBINTL) | 59 | $(GN_LIBINTL) |
diff --git a/src/exit/gnunet-daemon-exit.c b/src/exit/gnunet-daemon-exit.c index 92acc61cd..09576e393 100644 --- a/src/exit/gnunet-daemon-exit.c +++ b/src/exit/gnunet-daemon-exit.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2010-2013 Christian Grothoff | 3 | Copyright (C) 2010-2013, 2017 Christian Grothoff |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -195,33 +195,6 @@ struct RedirectInformation | |||
195 | 195 | ||
196 | 196 | ||
197 | /** | 197 | /** |
198 | * Queue of messages to a channel. | ||
199 | */ | ||
200 | struct ChannelMessageQueue | ||
201 | { | ||
202 | /** | ||
203 | * This is a doubly-linked list. | ||
204 | */ | ||
205 | struct ChannelMessageQueue *next; | ||
206 | |||
207 | /** | ||
208 | * This is a doubly-linked list. | ||
209 | */ | ||
210 | struct ChannelMessageQueue *prev; | ||
211 | |||
212 | /** | ||
213 | * Payload to send via the channel. | ||
214 | */ | ||
215 | const void *payload; | ||
216 | |||
217 | /** | ||
218 | * Number of bytes in @e payload. | ||
219 | */ | ||
220 | size_t len; | ||
221 | }; | ||
222 | |||
223 | |||
224 | /** | ||
225 | * This struct is saved into #connections_map to allow finding the | 198 | * This struct is saved into #connections_map to allow finding the |
226 | * right channel given an IP packet from TUN. It is also associated | 199 | * right channel given an IP packet from TUN. It is also associated |
227 | * with the channel's closure so we can find it again for the next | 200 | * with the channel's closure so we can find it again for the next |
@@ -241,11 +214,6 @@ struct ChannelState | |||
241 | struct GNUNET_PeerIdentity peer; | 214 | struct GNUNET_PeerIdentity peer; |
242 | 215 | ||
243 | /** | 216 | /** |
244 | * Active channel transmission request (or NULL). | ||
245 | */ | ||
246 | struct GNUNET_CADET_TransmitHandle *th; | ||
247 | |||
248 | /** | ||
249 | * #GNUNET_NO if this is a channel for TCP/UDP, | 217 | * #GNUNET_NO if this is a channel for TCP/UDP, |
250 | * #GNUNET_YES if this is a channel for DNS, | 218 | * #GNUNET_YES if this is a channel for DNS, |
251 | * #GNUNET_SYSERR if the channel is not yet initialized. | 219 | * #GNUNET_SYSERR if the channel is not yet initialized. |
@@ -273,16 +241,6 @@ struct ChannelState | |||
273 | struct LocalService *serv; | 241 | struct LocalService *serv; |
274 | 242 | ||
275 | /** | 243 | /** |
276 | * Head of DLL of messages for this channel. | ||
277 | */ | ||
278 | struct ChannelMessageQueue *head; | ||
279 | |||
280 | /** | ||
281 | * Tail of DLL of messages for this channel. | ||
282 | */ | ||
283 | struct ChannelMessageQueue *tail; | ||
284 | |||
285 | /** | ||
286 | * Primary redirection information for this connection. | 244 | * Primary redirection information for this connection. |
287 | */ | 245 | */ |
288 | struct RedirectInformation ri; | 246 | struct RedirectInformation ri; |
@@ -292,22 +250,12 @@ struct ChannelState | |||
292 | { | 250 | { |
293 | 251 | ||
294 | /** | 252 | /** |
295 | * DNS reply ready for transmission. | ||
296 | */ | ||
297 | char *reply; | ||
298 | |||
299 | /** | ||
300 | * Socket we are using to transmit this request (must match if we receive | 253 | * Socket we are using to transmit this request (must match if we receive |
301 | * a response). | 254 | * a response). |
302 | */ | 255 | */ |
303 | struct GNUNET_DNSSTUB_RequestSocket *rs; | 256 | struct GNUNET_DNSSTUB_RequestSocket *rs; |
304 | 257 | ||
305 | /** | 258 | /** |
306 | * Number of bytes in 'reply'. | ||
307 | */ | ||
308 | size_t reply_length; | ||
309 | |||
310 | /** | ||
311 | * Original DNS request ID as used by the client. | 259 | * Original DNS request ID as used by the client. |
312 | */ | 260 | */ |
313 | uint16_t original_id; | 261 | uint16_t original_id; |
@@ -428,7 +376,7 @@ static struct GNUNET_DHT_Handle *dht; | |||
428 | /** | 376 | /** |
429 | * Task for doing DHT PUTs to advertise exit service. | 377 | * Task for doing DHT PUTs to advertise exit service. |
430 | */ | 378 | */ |
431 | static struct GNUNET_SCHEDULER_Task * dht_task; | 379 | static struct GNUNET_SCHEDULER_Task *dht_task; |
432 | 380 | ||
433 | /** | 381 | /** |
434 | * Advertisement message we put into the DHT to advertise us | 382 | * Advertisement message we put into the DHT to advertise us |
@@ -447,6 +395,21 @@ static struct GNUNET_HashCode dht_put_key; | |||
447 | static struct GNUNET_CRYPTO_EddsaPrivateKey *peer_key; | 395 | static struct GNUNET_CRYPTO_EddsaPrivateKey *peer_key; |
448 | 396 | ||
449 | /** | 397 | /** |
398 | * Port for DNS exit. | ||
399 | */ | ||
400 | static struct GNUNET_CADET_Port *dns_port; | ||
401 | |||
402 | /** | ||
403 | * Port for IPv4 exit. | ||
404 | */ | ||
405 | static struct GNUNET_CADET_Port *cadet_port4; | ||
406 | |||
407 | /** | ||
408 | * Port for IPv6 exit. | ||
409 | */ | ||
410 | static struct GNUNET_CADET_Port *cadet_port6; | ||
411 | |||
412 | /** | ||
450 | * Are we an IPv4-exit? | 413 | * Are we an IPv4-exit? |
451 | */ | 414 | */ |
452 | static int ipv4_exit; | 415 | static int ipv4_exit; |
@@ -467,51 +430,27 @@ static int ipv4_enabled; | |||
467 | static int ipv6_enabled; | 430 | static int ipv6_enabled; |
468 | 431 | ||
469 | 432 | ||
433 | GNUNET_NETWORK_STRUCT_BEGIN | ||
434 | |||
470 | /** | 435 | /** |
471 | * We got a reply from DNS for a request of a CADET channel. Send it | 436 | * Message with a DNS response. |
472 | * via the channel (after changing the request ID back). | 437 | */ |
473 | * | 438 | struct DnsResponseMessage |
474 | * @param cls the `struct ChannelState` | ||
475 | * @param size number of bytes available in @a buf | ||
476 | * @param buf where to copy the reply | ||
477 | * @return number of bytes written to @a buf | ||
478 | */ | ||
479 | static size_t | ||
480 | transmit_reply_to_cadet (void *cls, | ||
481 | size_t size, | ||
482 | void *buf) | ||
483 | { | 439 | { |
484 | struct ChannelState *ts = cls; | 440 | /** |
485 | size_t off; | 441 | * GNUnet header, of type #GNUNET_MESSAGE_TYPE_VPN_DNS_FROM_INTERNET |
486 | size_t ret; | 442 | */ |
487 | char *cbuf = buf; | 443 | struct GNUNET_MessageHeader header; |
488 | struct GNUNET_MessageHeader hdr; | 444 | |
445 | /** | ||
446 | * DNS header. | ||
447 | */ | ||
489 | struct GNUNET_TUN_DnsHeader dns; | 448 | struct GNUNET_TUN_DnsHeader dns; |
490 | 449 | ||
491 | GNUNET_assert (GNUNET_YES == ts->is_dns); | 450 | /* Followed by more DNS payload */ |
492 | ts->th = NULL; | 451 | }; |
493 | GNUNET_assert (ts->specifics.dns.reply != NULL); | 452 | |
494 | if (size == 0) | 453 | GNUNET_NETWORK_STRUCT_END |
495 | return 0; | ||
496 | ret = sizeof (struct GNUNET_MessageHeader) + ts->specifics.dns.reply_length; | ||
497 | GNUNET_assert (ret <= size); | ||
498 | hdr.size = htons (ret); | ||
499 | hdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_DNS_FROM_INTERNET); | ||
500 | GNUNET_memcpy (&dns, ts->specifics.dns.reply, sizeof (dns)); | ||
501 | dns.id = ts->specifics.dns.original_id; | ||
502 | off = 0; | ||
503 | GNUNET_memcpy (&cbuf[off], &hdr, sizeof (hdr)); | ||
504 | off += sizeof (hdr); | ||
505 | GNUNET_memcpy (&cbuf[off], &dns, sizeof (dns)); | ||
506 | off += sizeof (dns); | ||
507 | GNUNET_memcpy (&cbuf[off], &ts->specifics.dns.reply[sizeof (dns)], ts->specifics.dns.reply_length - sizeof (dns)); | ||
508 | off += ts->specifics.dns.reply_length - sizeof (dns); | ||
509 | GNUNET_free (ts->specifics.dns.reply); | ||
510 | ts->specifics.dns.reply = NULL; | ||
511 | ts->specifics.dns.reply_length = 0; | ||
512 | GNUNET_assert (ret == off); | ||
513 | return ret; | ||
514 | } | ||
515 | 454 | ||
516 | 455 | ||
517 | /** | 456 | /** |
@@ -521,7 +460,7 @@ transmit_reply_to_cadet (void *cls, | |||
521 | * @param cls NULL | 460 | * @param cls NULL |
522 | * @param rs the socket that received the response | 461 | * @param rs the socket that received the response |
523 | * @param dns the response itself | 462 | * @param dns the response itself |
524 | * @param r number of bytes in dns | 463 | * @param r number of bytes in @a dns |
525 | */ | 464 | */ |
526 | static void | 465 | static void |
527 | process_dns_result (void *cls, | 466 | process_dns_result (void *cls, |
@@ -530,6 +469,8 @@ process_dns_result (void *cls, | |||
530 | size_t r) | 469 | size_t r) |
531 | { | 470 | { |
532 | struct ChannelState *ts; | 471 | struct ChannelState *ts; |
472 | struct GNUNET_MQ_Envelope *env; | ||
473 | struct DnsResponseMessage *resp; | ||
533 | 474 | ||
534 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 475 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
535 | "Processing DNS result from stub resolver\n"); | 476 | "Processing DNS result from stub resolver\n"); |
@@ -542,48 +483,35 @@ process_dns_result (void *cls, | |||
542 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 483 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
543 | "Got a response from the stub resolver for DNS request received via CADET!\n"); | 484 | "Got a response from the stub resolver for DNS request received via CADET!\n"); |
544 | channels[dns->id] = NULL; | 485 | channels[dns->id] = NULL; |
545 | GNUNET_free_non_null (ts->specifics.dns.reply); | 486 | env = GNUNET_MQ_msg_extra (resp, |
546 | ts->specifics.dns.reply = GNUNET_malloc (r); | 487 | r - sizeof (struct GNUNET_TUN_DnsHeader), |
547 | ts->specifics.dns.reply_length = r; | 488 | GNUNET_MESSAGE_TYPE_VPN_DNS_FROM_INTERNET); |
548 | GNUNET_memcpy (ts->specifics.dns.reply, dns, r); | 489 | GNUNET_memcpy (&resp->dns, |
549 | if (NULL != ts->th) | 490 | dns, |
550 | GNUNET_CADET_notify_transmit_ready_cancel (ts->th); | 491 | r); |
551 | ts->th = GNUNET_CADET_notify_transmit_ready (ts->channel, | 492 | resp->dns.id = ts->specifics.dns.original_id; |
552 | GNUNET_NO, | 493 | GNUNET_MQ_send (GNUNET_CADET_get_mq (ts->channel), |
553 | GNUNET_TIME_UNIT_FOREVER_REL, | 494 | env); |
554 | sizeof (struct GNUNET_MessageHeader) + r, | ||
555 | &transmit_reply_to_cadet, | ||
556 | ts); | ||
557 | } | 495 | } |
558 | 496 | ||
559 | 497 | ||
560 | /** | 498 | /** |
561 | * Process a request via cadet to perform a DNS query. | 499 | * Check a request via cadet to perform a DNS query. |
562 | * | ||
563 | * @param cls closure, NULL | ||
564 | * @param channel connection to the other end | ||
565 | * @param channel_ctx pointer to our `struct ChannelState *` | ||
566 | * @param message the actual message | ||
567 | * | 500 | * |
501 | * @param cls our `struct ChannelState *` | ||
502 | * @param msg the actual message | ||
568 | * @return #GNUNET_OK to keep the connection open, | 503 | * @return #GNUNET_OK to keep the connection open, |
569 | * #GNUNET_SYSERR to close it (signal serious error) | 504 | * #GNUNET_SYSERR to close it (signal serious error) |
570 | */ | 505 | */ |
571 | static int | 506 | static int |
572 | receive_dns_request (void *cls GNUNET_UNUSED, | 507 | check_dns_request (void *cls, |
573 | struct GNUNET_CADET_Channel *channel, | 508 | const struct DnsResponseMessage *msg) |
574 | void **channel_ctx, | ||
575 | const struct GNUNET_MessageHeader *message) | ||
576 | { | 509 | { |
577 | struct ChannelState *ts = *channel_ctx; | 510 | struct ChannelState *ts = cls; |
578 | const struct GNUNET_TUN_DnsHeader *dns; | ||
579 | size_t mlen = ntohs (message->size); | ||
580 | size_t dlen = mlen - sizeof (struct GNUNET_MessageHeader); | ||
581 | char buf[dlen] GNUNET_ALIGN; | ||
582 | struct GNUNET_TUN_DnsHeader *dout; | ||
583 | 511 | ||
584 | if (NULL == dnsstub) | 512 | if (NULL == dnsstub) |
585 | { | 513 | { |
586 | GNUNET_break_op (0); | 514 | GNUNET_break (0); |
587 | return GNUNET_SYSERR; | 515 | return GNUNET_SYSERR; |
588 | } | 516 | } |
589 | if (GNUNET_NO == ts->is_dns) | 517 | if (GNUNET_NO == ts->is_dns) |
@@ -591,34 +519,53 @@ receive_dns_request (void *cls GNUNET_UNUSED, | |||
591 | GNUNET_break_op (0); | 519 | GNUNET_break_op (0); |
592 | return GNUNET_SYSERR; | 520 | return GNUNET_SYSERR; |
593 | } | 521 | } |
522 | return GNUNET_OK; | ||
523 | } | ||
524 | |||
525 | |||
526 | /** | ||
527 | * Process a request via cadet to perform a DNS query. | ||
528 | * | ||
529 | * @param cls our `struct ChannelState *` | ||
530 | * @param msg the actual message | ||
531 | */ | ||
532 | static void | ||
533 | handle_dns_request (void *cls, | ||
534 | const struct DnsResponseMessage *msg) | ||
535 | { | ||
536 | struct ChannelState *ts = cls; | ||
537 | size_t mlen = ntohs (msg->header.size); | ||
538 | size_t dlen = mlen - sizeof (struct GNUNET_MessageHeader); | ||
539 | char buf[dlen] GNUNET_ALIGN; | ||
540 | struct GNUNET_TUN_DnsHeader *dout; | ||
541 | |||
594 | if (GNUNET_SYSERR == ts->is_dns) | 542 | if (GNUNET_SYSERR == ts->is_dns) |
595 | { | 543 | { |
596 | /* channel is DNS from now on */ | 544 | /* channel is DNS from now on */ |
597 | ts->is_dns = GNUNET_YES; | 545 | ts->is_dns = GNUNET_YES; |
598 | } | 546 | } |
599 | if (dlen < sizeof (struct GNUNET_TUN_DnsHeader)) | 547 | ts->specifics.dns.original_id = msg->dns.id; |
600 | { | ||
601 | GNUNET_break_op (0); | ||
602 | return GNUNET_SYSERR; | ||
603 | } | ||
604 | dns = (const struct GNUNET_TUN_DnsHeader *) &message[1]; | ||
605 | ts->specifics.dns.original_id = dns->id; | ||
606 | if (channels[ts->specifics.dns.my_id] == ts) | 548 | if (channels[ts->specifics.dns.my_id] == ts) |
607 | channels[ts->specifics.dns.my_id] = NULL; | 549 | channels[ts->specifics.dns.my_id] = NULL; |
608 | ts->specifics.dns.my_id = (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, | 550 | ts->specifics.dns.my_id = (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, |
609 | UINT16_MAX + 1); | 551 | UINT16_MAX + 1); |
610 | channels[ts->specifics.dns.my_id] = ts; | 552 | channels[ts->specifics.dns.my_id] = ts; |
611 | GNUNET_memcpy (buf, dns, dlen); | 553 | GNUNET_memcpy (buf, |
554 | &msg->dns, | ||
555 | dlen); | ||
612 | dout = (struct GNUNET_TUN_DnsHeader *) buf; | 556 | dout = (struct GNUNET_TUN_DnsHeader *) buf; |
613 | dout->id = ts->specifics.dns.my_id; | 557 | dout->id = ts->specifics.dns.my_id; |
614 | ts->specifics.dns.rs = GNUNET_DNSSTUB_resolve2 (dnsstub, | 558 | ts->specifics.dns.rs = GNUNET_DNSSTUB_resolve2 (dnsstub, |
615 | buf, dlen, | 559 | buf, |
560 | dlen, | ||
616 | &process_dns_result, | 561 | &process_dns_result, |
617 | NULL); | 562 | NULL); |
618 | if (NULL == ts->specifics.dns.rs) | 563 | if (NULL == ts->specifics.dns.rs) |
619 | return GNUNET_SYSERR; | 564 | { |
620 | GNUNET_CADET_receive_done (channel); | 565 | GNUNET_break_op (0); |
621 | return GNUNET_OK; | 566 | return; |
567 | } | ||
568 | GNUNET_CADET_receive_done (ts->channel); | ||
622 | } | 569 | } |
623 | 570 | ||
624 | 571 | ||
@@ -753,706 +700,445 @@ get_redirect_state (int af, | |||
753 | } | 700 | } |
754 | 701 | ||
755 | 702 | ||
756 | /** | ||
757 | * Free memory associated with a service record. | ||
758 | * | ||
759 | * @param cls unused | ||
760 | * @param key service descriptor | ||
761 | * @param value service record to free | ||
762 | * @return #GNUNET_OK | ||
763 | */ | ||
764 | static int | ||
765 | free_service_record (void *cls, | ||
766 | const struct GNUNET_HashCode *key, | ||
767 | void *value) | ||
768 | { | ||
769 | struct LocalService *service = value; | ||
770 | |||
771 | GNUNET_assert (GNUNET_YES == | ||
772 | GNUNET_CONTAINER_multihashmap_remove (services, | ||
773 | key, | ||
774 | service)); | ||
775 | GNUNET_CADET_close_port (service->port); | ||
776 | GNUNET_free_non_null (service->name); | ||
777 | GNUNET_free (service); | ||
778 | return GNUNET_OK; | ||
779 | } | ||
780 | |||
781 | |||
782 | /** | ||
783 | * Callback from CADET for new channels. | ||
784 | * | ||
785 | * @param cls closure | ||
786 | * @param channel new handle to the channel | ||
787 | * @param initiator peer that started the channel | ||
788 | * @param port destination port | ||
789 | * @param options channel options flags | ||
790 | * @return initial channel context for the channel | ||
791 | */ | ||
792 | static void * | ||
793 | new_service_channel (void *cls, | ||
794 | struct GNUNET_CADET_Channel *channel, | ||
795 | const struct GNUNET_PeerIdentity *initiator, | ||
796 | const struct GNUNET_HashCode *port, | ||
797 | enum GNUNET_CADET_ChannelOption options) | ||
798 | { | ||
799 | struct LocalService *ls = cls; | ||
800 | struct ChannelState *s = GNUNET_new (struct ChannelState); | ||
801 | |||
802 | s->peer = *initiator; | ||
803 | GNUNET_STATISTICS_update (stats, | ||
804 | gettext_noop ("# Inbound CADET channels created"), | ||
805 | 1, | ||
806 | GNUNET_NO); | ||
807 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
808 | "Received inbound channel from `%s'\n", | ||
809 | GNUNET_i2s (initiator)); | ||
810 | s->channel = channel; | ||
811 | s->specifics.tcp_udp.serv = ls; | ||
812 | s->specifics.tcp_udp.ri.remote_address = ls->address; | ||
813 | return s; | ||
814 | } | ||
815 | |||
816 | 703 | ||
817 | /** | 704 | /** |
818 | * Given a service descriptor and a destination port, find the | 705 | * Check a request via cadet to send a request to a TCP service |
819 | * respective service entry. | 706 | * offered by this system. |
820 | * | 707 | * |
821 | * @param proto IPPROTO_TCP or IPPROTO_UDP | 708 | * @param cls our `struct ChannelState *` |
822 | * @param name name of the service | 709 | * @param start the actual message |
823 | * @param destination_port destination port | 710 | * @return #GNUNET_OK to keep the connection open, |
824 | * @param service service information record to store (service->name will be set). | 711 | * #GNUNET_SYSERR to close it (signal serious error) |
825 | */ | 712 | */ |
826 | static void | 713 | static int |
827 | store_service (int proto, | 714 | check_tcp_service (void *cls, |
828 | const char *name, | 715 | const struct GNUNET_EXIT_TcpServiceStartMessage *start) |
829 | uint16_t destination_port, | ||
830 | struct LocalService *service) | ||
831 | { | 716 | { |
832 | struct GNUNET_HashCode cadet_port; | 717 | struct ChannelState *state = cls; |
833 | 718 | ||
834 | service->name = GNUNET_strdup (name); | 719 | if (NULL == state) |
835 | GNUNET_TUN_service_name_to_hash (name, | ||
836 | &service->descriptor); | ||
837 | GNUNET_TUN_compute_service_cadet_port (&service->descriptor, | ||
838 | destination_port, | ||
839 | &cadet_port); | ||
840 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
841 | "Opening CADET port %s for SERVICE exit %s on port %u\n", | ||
842 | GNUNET_h2s (&cadet_port), | ||
843 | name, | ||
844 | (unsigned int) destination_port); | ||
845 | service->port = GNUNET_CADET_open_port (cadet_handle, | ||
846 | &cadet_port, | ||
847 | &new_service_channel, | ||
848 | service); | ||
849 | service->is_udp = (IPPROTO_UDP == proto); | ||
850 | if (GNUNET_OK != | ||
851 | GNUNET_CONTAINER_multihashmap_put (services, | ||
852 | &cadet_port, | ||
853 | service, | ||
854 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) | ||
855 | { | 720 | { |
856 | GNUNET_CADET_close_port (service->port); | 721 | GNUNET_break_op (0); |
857 | GNUNET_free_non_null (service->name); | 722 | return GNUNET_SYSERR; |
858 | GNUNET_free (service); | ||
859 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
860 | _("Got duplicate service records for `%s:%u'\n"), | ||
861 | name, | ||
862 | (unsigned int) destination_port); | ||
863 | } | 723 | } |
724 | if (GNUNET_YES == state->is_dns) | ||
725 | { | ||
726 | GNUNET_break_op (0); | ||
727 | return GNUNET_SYSERR; | ||
728 | } | ||
729 | if (NULL == state->specifics.tcp_udp.serv) | ||
730 | { | ||
731 | GNUNET_break_op (0); | ||
732 | return GNUNET_SYSERR; | ||
733 | } | ||
734 | if (NULL != state->specifics.tcp_udp.heap_node) | ||
735 | { | ||
736 | GNUNET_break_op (0); | ||
737 | return GNUNET_SYSERR; | ||
738 | } | ||
739 | if (start->tcp_header.off * 4 < sizeof (struct GNUNET_TUN_TcpHeader)) | ||
740 | { | ||
741 | GNUNET_break_op (0); | ||
742 | return GNUNET_SYSERR; | ||
743 | } | ||
744 | return GNUNET_OK; | ||
864 | } | 745 | } |
865 | 746 | ||
866 | 747 | ||
867 | /** | 748 | /** |
868 | * CADET is ready to receive a message for the channel. Transmit it. | 749 | * Prepare an IPv4 packet for transmission via the TUN interface. |
869 | * | 750 | * Initializes the IP header and calculates checksums (IP+UDP/TCP). |
870 | * @param cls the `struct ChannelState`. | 751 | * For UDP, the UDP header will be fully created, whereas for TCP |
871 | * @param size number of bytes available in @a buf | 752 | * only the ports and checksum will be filled in. So for TCP, |
872 | * @param buf where to copy the message | 753 | * a skeleton TCP header must be part of the provided payload. |
873 | * @return number of bytes copied to @a buf | ||
874 | */ | ||
875 | static size_t | ||
876 | send_to_peer_notify_callback (void *cls, | ||
877 | size_t size, | ||
878 | void *buf) | ||
879 | { | ||
880 | struct ChannelState *s = cls; | ||
881 | struct GNUNET_CADET_Channel *channel = s->channel; | ||
882 | struct ChannelMessageQueue *tnq; | ||
883 | |||
884 | s->th = NULL; | ||
885 | tnq = s->specifics.tcp_udp.head; | ||
886 | if (NULL == tnq) | ||
887 | return 0; | ||
888 | if (0 == size) | ||
889 | { | ||
890 | s->th = GNUNET_CADET_notify_transmit_ready (channel, | ||
891 | GNUNET_NO /* corking */, | ||
892 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
893 | tnq->len, | ||
894 | &send_to_peer_notify_callback, | ||
895 | s); | ||
896 | return 0; | ||
897 | } | ||
898 | GNUNET_assert (size >= tnq->len); | ||
899 | GNUNET_memcpy (buf, tnq->payload, tnq->len); | ||
900 | size = tnq->len; | ||
901 | GNUNET_CONTAINER_DLL_remove (s->specifics.tcp_udp.head, | ||
902 | s->specifics.tcp_udp.tail, | ||
903 | tnq); | ||
904 | GNUNET_free (tnq); | ||
905 | if (NULL != (tnq = s->specifics.tcp_udp.head)) | ||
906 | s->th = GNUNET_CADET_notify_transmit_ready (channel, | ||
907 | GNUNET_NO /* corking */, | ||
908 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
909 | tnq->len, | ||
910 | &send_to_peer_notify_callback, | ||
911 | s); | ||
912 | GNUNET_STATISTICS_update (stats, | ||
913 | gettext_noop ("# Bytes transmitted via cadet channels"), | ||
914 | size, GNUNET_NO); | ||
915 | return size; | ||
916 | } | ||
917 | |||
918 | |||
919 | /** | ||
920 | * Send the given packet via the cadet channel. | ||
921 | * | ||
922 | * @param s channel destination | ||
923 | * @param tnq message to queue | ||
924 | */ | ||
925 | static void | ||
926 | send_packet_to_cadet_channel (struct ChannelState *s, | ||
927 | struct ChannelMessageQueue *tnq) | ||
928 | { | ||
929 | struct GNUNET_CADET_Channel *cadet_channel; | ||
930 | |||
931 | cadet_channel = s->channel; | ||
932 | GNUNET_assert (NULL != s); | ||
933 | GNUNET_CONTAINER_DLL_insert_tail (s->specifics.tcp_udp.head, | ||
934 | s->specifics.tcp_udp.tail, | ||
935 | tnq); | ||
936 | if (NULL == s->th) | ||
937 | s->th = GNUNET_CADET_notify_transmit_ready (cadet_channel, | ||
938 | GNUNET_NO /* cork */, | ||
939 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
940 | tnq->len, | ||
941 | &send_to_peer_notify_callback, | ||
942 | s); | ||
943 | } | ||
944 | |||
945 | |||
946 | /** | ||
947 | * @brief Handles an ICMP packet received from the helper. | ||
948 | * | 754 | * |
949 | * @param icmp A pointer to the Packet | 755 | * @param payload payload of the packet (starting with UDP payload or |
950 | * @param pktlen number of bytes in @a icmp | 756 | * TCP header, depending on protocol) |
951 | * @param af address family (AFINET or AF_INET6) | 757 | * @param payload_length number of bytes in @a payload |
952 | * @param destination_ip destination IP-address of the IP packet (should | 758 | * @param protocol IPPROTO_UDP or IPPROTO_TCP |
953 | * be our local address) | 759 | * @param tcp_header skeleton of the TCP header, NULL for UDP |
954 | * @param source_ip original source IP-address of the IP packet (should | 760 | * @param src_address source address to use (IP and port) |
955 | * be the original destination address) | 761 | * @param dst_address destination address to use (IP and port) |
762 | * @param pkt4 where to write the assembled packet; must | ||
763 | * contain enough space for the IP header, UDP/TCP header | ||
764 | * AND the payload | ||
956 | */ | 765 | */ |
957 | static void | 766 | static void |
958 | icmp_from_helper (const struct GNUNET_TUN_IcmpHeader *icmp, | 767 | prepare_ipv4_packet (const void *payload, |
959 | size_t pktlen, | 768 | size_t payload_length, |
960 | int af, | 769 | int protocol, |
961 | const void *destination_ip, | 770 | const struct GNUNET_TUN_TcpHeader *tcp_header, |
962 | const void *source_ip) | 771 | const struct SocketAddress *src_address, |
772 | const struct SocketAddress *dst_address, | ||
773 | struct GNUNET_TUN_IPv4Header *pkt4) | ||
963 | { | 774 | { |
964 | struct ChannelState *state; | 775 | size_t len; |
965 | struct ChannelMessageQueue *tnq; | ||
966 | struct GNUNET_EXIT_IcmpToVPNMessage *i2v; | ||
967 | const struct GNUNET_TUN_IPv4Header *ipv4; | ||
968 | const struct GNUNET_TUN_IPv6Header *ipv6; | ||
969 | const struct GNUNET_TUN_UdpHeader *udp; | ||
970 | size_t mlen; | ||
971 | uint16_t source_port; | ||
972 | uint16_t destination_port; | ||
973 | uint8_t protocol; | ||
974 | 776 | ||
777 | len = payload_length; | ||
778 | switch (protocol) | ||
975 | { | 779 | { |
976 | char sbuf[INET6_ADDRSTRLEN]; | 780 | case IPPROTO_UDP: |
977 | char dbuf[INET6_ADDRSTRLEN]; | 781 | len += sizeof (struct GNUNET_TUN_UdpHeader); |
978 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 782 | break; |
979 | "Received ICMP packet going from %s to %s\n", | 783 | case IPPROTO_TCP: |
980 | inet_ntop (af, | 784 | len += sizeof (struct GNUNET_TUN_TcpHeader); |
981 | source_ip, | 785 | GNUNET_assert (NULL != tcp_header); |
982 | sbuf, sizeof (sbuf)), | 786 | break; |
983 | inet_ntop (af, | 787 | default: |
984 | destination_ip, | 788 | GNUNET_break (0); |
985 | dbuf, sizeof (dbuf))); | 789 | return; |
986 | } | 790 | } |
987 | if (pktlen < sizeof (struct GNUNET_TUN_IcmpHeader)) | 791 | if (len + sizeof (struct GNUNET_TUN_IPv4Header) > UINT16_MAX) |
988 | { | 792 | { |
989 | /* blame kernel */ | ||
990 | GNUNET_break (0); | 793 | GNUNET_break (0); |
991 | return; | 794 | return; |
992 | } | 795 | } |
993 | 796 | ||
994 | /* Find out if this is an ICMP packet in response to an existing | 797 | GNUNET_TUN_initialize_ipv4_header (pkt4, |
995 | TCP/UDP packet and if so, figure out ports / protocol of the | 798 | protocol, |
996 | existing session from the IP data in the ICMP payload */ | 799 | len, |
997 | source_port = 0; | 800 | &src_address->address.ipv4, |
998 | destination_port = 0; | 801 | &dst_address->address.ipv4); |
999 | switch (af) | ||
1000 | { | ||
1001 | case AF_INET: | ||
1002 | protocol = IPPROTO_ICMP; | ||
1003 | switch (icmp->type) | ||
1004 | { | ||
1005 | case GNUNET_TUN_ICMPTYPE_ECHO_REPLY: | ||
1006 | case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST: | ||
1007 | break; | ||
1008 | case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE: | ||
1009 | case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH: | ||
1010 | case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED: | ||
1011 | if (pktlen < | ||
1012 | sizeof (struct GNUNET_TUN_IcmpHeader) + | ||
1013 | sizeof (struct GNUNET_TUN_IPv4Header) + 8) | ||
1014 | { | ||
1015 | /* blame kernel */ | ||
1016 | GNUNET_break (0); | ||
1017 | return; | ||
1018 | } | ||
1019 | ipv4 = (const struct GNUNET_TUN_IPv4Header *) &icmp[1]; | ||
1020 | protocol = ipv4->protocol; | ||
1021 | /* could be TCP or UDP, but both have the ports in the right | ||
1022 | place, so that doesn't matter here */ | ||
1023 | udp = (const struct GNUNET_TUN_UdpHeader *) &ipv4[1]; | ||
1024 | /* swap ports, as they are from the original message */ | ||
1025 | destination_port = ntohs (udp->source_port); | ||
1026 | source_port = ntohs (udp->destination_port); | ||
1027 | /* throw away ICMP payload, won't be useful for the other side anyway */ | ||
1028 | pktlen = sizeof (struct GNUNET_TUN_IcmpHeader); | ||
1029 | break; | ||
1030 | default: | ||
1031 | GNUNET_STATISTICS_update (stats, | ||
1032 | gettext_noop ("# ICMPv4 packets dropped (type not allowed)"), | ||
1033 | 1, GNUNET_NO); | ||
1034 | return; | ||
1035 | } | ||
1036 | break; | ||
1037 | case AF_INET6: | ||
1038 | protocol = IPPROTO_ICMPV6; | ||
1039 | switch (icmp->type) | ||
1040 | { | ||
1041 | case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE: | ||
1042 | case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG: | ||
1043 | case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED: | ||
1044 | case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM: | ||
1045 | if (pktlen < | ||
1046 | sizeof (struct GNUNET_TUN_IcmpHeader) + | ||
1047 | sizeof (struct GNUNET_TUN_IPv6Header) + 8) | ||
1048 | { | ||
1049 | /* blame kernel */ | ||
1050 | GNUNET_break (0); | ||
1051 | return; | ||
1052 | } | ||
1053 | ipv6 = (const struct GNUNET_TUN_IPv6Header *) &icmp[1]; | ||
1054 | protocol = ipv6->next_header; | ||
1055 | /* could be TCP or UDP, but both have the ports in the right | ||
1056 | place, so that doesn't matter here */ | ||
1057 | udp = (const struct GNUNET_TUN_UdpHeader *) &ipv6[1]; | ||
1058 | /* swap ports, as they are from the original message */ | ||
1059 | destination_port = ntohs (udp->source_port); | ||
1060 | source_port = ntohs (udp->destination_port); | ||
1061 | /* throw away ICMP payload, won't be useful for the other side anyway */ | ||
1062 | pktlen = sizeof (struct GNUNET_TUN_IcmpHeader); | ||
1063 | break; | ||
1064 | case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST: | ||
1065 | case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY: | ||
1066 | break; | ||
1067 | default: | ||
1068 | GNUNET_STATISTICS_update (stats, | ||
1069 | gettext_noop ("# ICMPv6 packets dropped (type not allowed)"), | ||
1070 | 1, GNUNET_NO); | ||
1071 | return; | ||
1072 | } | ||
1073 | break; | ||
1074 | default: | ||
1075 | GNUNET_assert (0); | ||
1076 | } | ||
1077 | switch (protocol) | 802 | switch (protocol) |
1078 | { | 803 | { |
1079 | case IPPROTO_ICMP: | ||
1080 | state = get_redirect_state (af, | ||
1081 | IPPROTO_ICMP, | ||
1082 | source_ip, | ||
1083 | 0, | ||
1084 | destination_ip, | ||
1085 | 0, | ||
1086 | NULL); | ||
1087 | break; | ||
1088 | case IPPROTO_ICMPV6: | ||
1089 | state = get_redirect_state (af, | ||
1090 | IPPROTO_ICMPV6, | ||
1091 | source_ip, | ||
1092 | 0, | ||
1093 | destination_ip, | ||
1094 | 0, | ||
1095 | NULL); | ||
1096 | break; | ||
1097 | case IPPROTO_UDP: | 804 | case IPPROTO_UDP: |
1098 | state = get_redirect_state (af, | 805 | { |
1099 | IPPROTO_UDP, | 806 | struct GNUNET_TUN_UdpHeader *pkt4_udp = (struct GNUNET_TUN_UdpHeader *) &pkt4[1]; |
1100 | source_ip, | 807 | |
1101 | source_port, | 808 | pkt4_udp->source_port = htons (src_address->port); |
1102 | destination_ip, | 809 | pkt4_udp->destination_port = htons (dst_address->port); |
1103 | destination_port, | 810 | pkt4_udp->len = htons ((uint16_t) payload_length); |
1104 | NULL); | 811 | GNUNET_TUN_calculate_udp4_checksum (pkt4, |
812 | pkt4_udp, | ||
813 | payload, | ||
814 | payload_length); | ||
815 | GNUNET_memcpy (&pkt4_udp[1], | ||
816 | payload, | ||
817 | payload_length); | ||
818 | } | ||
1105 | break; | 819 | break; |
1106 | case IPPROTO_TCP: | 820 | case IPPROTO_TCP: |
1107 | state = get_redirect_state (af, | 821 | { |
1108 | IPPROTO_TCP, | 822 | struct GNUNET_TUN_TcpHeader *pkt4_tcp = (struct GNUNET_TUN_TcpHeader *) &pkt4[1]; |
1109 | source_ip, | 823 | |
1110 | source_port, | 824 | *pkt4_tcp = *tcp_header; |
1111 | destination_ip, | 825 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1112 | destination_port, | 826 | "Sending TCP packet from port %u to port %u\n", |
1113 | NULL); | 827 | src_address->port, |
828 | dst_address->port); | ||
829 | pkt4_tcp->source_port = htons (src_address->port); | ||
830 | pkt4_tcp->destination_port = htons (dst_address->port); | ||
831 | GNUNET_TUN_calculate_tcp4_checksum (pkt4, | ||
832 | pkt4_tcp, | ||
833 | payload, | ||
834 | payload_length); | ||
835 | GNUNET_memcpy (&pkt4_tcp[1], | ||
836 | payload, | ||
837 | payload_length); | ||
838 | } | ||
1114 | break; | 839 | break; |
1115 | default: | 840 | default: |
1116 | GNUNET_STATISTICS_update (stats, | 841 | GNUNET_assert (0); |
1117 | gettext_noop ("# ICMP packets dropped (not allowed)"), | ||
1118 | 1, | ||
1119 | GNUNET_NO); | ||
1120 | return; | ||
1121 | } | ||
1122 | if (NULL == state) | ||
1123 | { | ||
1124 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1125 | _("ICMP Packet dropped, have no matching connection information\n")); | ||
1126 | return; | ||
1127 | } | 842 | } |
1128 | mlen = sizeof (struct GNUNET_EXIT_IcmpToVPNMessage) + pktlen - sizeof (struct GNUNET_TUN_IcmpHeader); | ||
1129 | tnq = GNUNET_malloc (sizeof (struct ChannelMessageQueue) + mlen); | ||
1130 | tnq->payload = &tnq[1]; | ||
1131 | tnq->len = mlen; | ||
1132 | i2v = (struct GNUNET_EXIT_IcmpToVPNMessage *) &tnq[1]; | ||
1133 | i2v->header.size = htons ((uint16_t) mlen); | ||
1134 | i2v->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_VPN); | ||
1135 | i2v->af = htonl (af); | ||
1136 | GNUNET_memcpy (&i2v->icmp_header, | ||
1137 | icmp, | ||
1138 | pktlen); | ||
1139 | send_packet_to_cadet_channel (state, tnq); | ||
1140 | } | 843 | } |
1141 | 844 | ||
1142 | 845 | ||
1143 | /** | 846 | /** |
1144 | * @brief Handles an UDP packet received from the helper. | 847 | * Prepare an IPv6 packet for transmission via the TUN interface. |
848 | * Initializes the IP header and calculates checksums (IP+UDP/TCP). | ||
849 | * For UDP, the UDP header will be fully created, whereas for TCP | ||
850 | * only the ports and checksum will be filled in. So for TCP, | ||
851 | * a skeleton TCP header must be part of the provided payload. | ||
1145 | * | 852 | * |
1146 | * @param udp A pointer to the Packet | 853 | * @param payload payload of the packet (starting with UDP payload or |
1147 | * @param pktlen number of bytes in 'udp' | 854 | * TCP header, depending on protocol) |
1148 | * @param af address family (AFINET or AF_INET6) | 855 | * @param payload_length number of bytes in @a payload |
1149 | * @param destination_ip destination IP-address of the IP packet (should | 856 | * @param protocol IPPROTO_UDP or IPPROTO_TCP |
1150 | * be our local address) | 857 | * @param tcp_header skeleton TCP header data to send, NULL for UDP |
1151 | * @param source_ip original source IP-address of the IP packet (should | 858 | * @param src_address source address to use (IP and port) |
1152 | * be the original destination address) | 859 | * @param dst_address destination address to use (IP and port) |
860 | * @param pkt6 where to write the assembled packet; must | ||
861 | * contain enough space for the IP header, UDP/TCP header | ||
862 | * AND the payload | ||
1153 | */ | 863 | */ |
1154 | static void | 864 | static void |
1155 | udp_from_helper (const struct GNUNET_TUN_UdpHeader *udp, | 865 | prepare_ipv6_packet (const void *payload, |
1156 | size_t pktlen, | 866 | size_t payload_length, |
1157 | int af, | 867 | int protocol, |
1158 | const void *destination_ip, | 868 | const struct GNUNET_TUN_TcpHeader *tcp_header, |
1159 | const void *source_ip) | 869 | const struct SocketAddress *src_address, |
870 | const struct SocketAddress *dst_address, | ||
871 | struct GNUNET_TUN_IPv6Header *pkt6) | ||
1160 | { | 872 | { |
1161 | struct ChannelState *state; | 873 | size_t len; |
1162 | struct ChannelMessageQueue *tnq; | ||
1163 | struct GNUNET_EXIT_UdpReplyMessage *urm; | ||
1164 | size_t mlen; | ||
1165 | 874 | ||
875 | len = payload_length; | ||
876 | switch (protocol) | ||
1166 | { | 877 | { |
1167 | char sbuf[INET6_ADDRSTRLEN]; | 878 | case IPPROTO_UDP: |
1168 | char dbuf[INET6_ADDRSTRLEN]; | 879 | len += sizeof (struct GNUNET_TUN_UdpHeader); |
1169 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 880 | break; |
1170 | "Received UDP packet going from %s:%u to %s:%u\n", | 881 | case IPPROTO_TCP: |
1171 | inet_ntop (af, | 882 | len += sizeof (struct GNUNET_TUN_TcpHeader); |
1172 | source_ip, | 883 | break; |
1173 | sbuf, sizeof (sbuf)), | 884 | default: |
1174 | (unsigned int) ntohs (udp->source_port), | ||
1175 | inet_ntop (af, | ||
1176 | destination_ip, | ||
1177 | dbuf, sizeof (dbuf)), | ||
1178 | (unsigned int) ntohs (udp->destination_port)); | ||
1179 | } | ||
1180 | if (pktlen < sizeof (struct GNUNET_TUN_UdpHeader)) | ||
1181 | { | ||
1182 | /* blame kernel */ | ||
1183 | GNUNET_break (0); | 885 | GNUNET_break (0); |
1184 | return; | 886 | return; |
1185 | } | 887 | } |
1186 | if (pktlen != ntohs (udp->len)) | 888 | if (len > UINT16_MAX) |
1187 | { | 889 | { |
1188 | /* blame kernel */ | ||
1189 | GNUNET_break (0); | 890 | GNUNET_break (0); |
1190 | return; | 891 | return; |
1191 | } | 892 | } |
1192 | state = get_redirect_state (af, | 893 | |
1193 | IPPROTO_UDP, | 894 | GNUNET_TUN_initialize_ipv6_header (pkt6, |
1194 | source_ip, | 895 | protocol, |
1195 | ntohs (udp->source_port), | 896 | len, |
1196 | destination_ip, | 897 | &src_address->address.ipv6, |
1197 | ntohs (udp->destination_port), | 898 | &dst_address->address.ipv6); |
1198 | NULL); | 899 | |
1199 | if (NULL == state) | 900 | switch (protocol) |
1200 | { | 901 | { |
1201 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 902 | case IPPROTO_UDP: |
1202 | _("UDP Packet dropped, have no matching connection information\n")); | 903 | { |
1203 | return; | 904 | struct GNUNET_TUN_UdpHeader *pkt6_udp = (struct GNUNET_TUN_UdpHeader *) &pkt6[1]; |
905 | |||
906 | pkt6_udp->source_port = htons (src_address->port); | ||
907 | pkt6_udp->destination_port = htons (dst_address->port); | ||
908 | pkt6_udp->len = htons ((uint16_t) payload_length); | ||
909 | GNUNET_TUN_calculate_udp6_checksum (pkt6, | ||
910 | pkt6_udp, | ||
911 | payload, | ||
912 | payload_length); | ||
913 | GNUNET_memcpy (&pkt6_udp[1], | ||
914 | payload, | ||
915 | payload_length); | ||
916 | } | ||
917 | break; | ||
918 | case IPPROTO_TCP: | ||
919 | { | ||
920 | struct GNUNET_TUN_TcpHeader *pkt6_tcp = (struct GNUNET_TUN_TcpHeader *) &pkt6[1]; | ||
921 | |||
922 | /* GNUNET_memcpy first here as some TCP header fields are initialized this way! */ | ||
923 | *pkt6_tcp = *tcp_header; | ||
924 | pkt6_tcp->source_port = htons (src_address->port); | ||
925 | pkt6_tcp->destination_port = htons (dst_address->port); | ||
926 | GNUNET_TUN_calculate_tcp6_checksum (pkt6, | ||
927 | pkt6_tcp, | ||
928 | payload, | ||
929 | payload_length); | ||
930 | GNUNET_memcpy (&pkt6_tcp[1], | ||
931 | payload, | ||
932 | payload_length); | ||
933 | } | ||
934 | break; | ||
935 | default: | ||
936 | GNUNET_assert (0); | ||
937 | break; | ||
1204 | } | 938 | } |
1205 | mlen = sizeof (struct GNUNET_EXIT_UdpReplyMessage) + pktlen - sizeof (struct GNUNET_TUN_UdpHeader); | ||
1206 | tnq = GNUNET_malloc (sizeof (struct ChannelMessageQueue) + mlen); | ||
1207 | tnq->payload = &tnq[1]; | ||
1208 | tnq->len = mlen; | ||
1209 | urm = (struct GNUNET_EXIT_UdpReplyMessage *) &tnq[1]; | ||
1210 | urm->header.size = htons ((uint16_t) mlen); | ||
1211 | urm->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY); | ||
1212 | urm->source_port = htons (0); | ||
1213 | urm->destination_port = htons (0); | ||
1214 | GNUNET_memcpy (&urm[1], | ||
1215 | &udp[1], | ||
1216 | pktlen - sizeof (struct GNUNET_TUN_UdpHeader)); | ||
1217 | send_packet_to_cadet_channel (state, tnq); | ||
1218 | } | 939 | } |
1219 | 940 | ||
1220 | 941 | ||
1221 | /** | 942 | /** |
1222 | * @brief Handles a TCP packet received from the helper. | 943 | * Send a TCP packet via the TUN interface. |
1223 | * | 944 | * |
1224 | * @param tcp A pointer to the Packet | 945 | * @param destination_address IP and port to use for the TCP packet's destination |
1225 | * @param pktlen the length of the packet, including its TCP header | 946 | * @param source_address IP and port to use for the TCP packet's source |
1226 | * @param af address family (AFINET or AF_INET6) | 947 | * @param tcp_header header template to use |
1227 | * @param destination_ip destination IP-address of the IP packet (should | 948 | * @param payload payload of the TCP packet |
1228 | * be our local address) | 949 | * @param payload_length number of bytes in @a payload |
1229 | * @param source_ip original source IP-address of the IP packet (should | ||
1230 | * be the original destination address) | ||
1231 | */ | 950 | */ |
1232 | static void | 951 | static void |
1233 | tcp_from_helper (const struct GNUNET_TUN_TcpHeader *tcp, | 952 | send_tcp_packet_via_tun (const struct SocketAddress *destination_address, |
1234 | size_t pktlen, | 953 | const struct SocketAddress *source_address, |
1235 | int af, | 954 | const struct GNUNET_TUN_TcpHeader *tcp_header, |
1236 | const void *destination_ip, | 955 | const void *payload, |
1237 | const void *source_ip) | 956 | size_t payload_length) |
1238 | { | 957 | { |
1239 | struct ChannelState *state; | 958 | size_t len; |
1240 | char buf[pktlen] GNUNET_ALIGN; | ||
1241 | struct GNUNET_TUN_TcpHeader *mtcp; | ||
1242 | struct GNUNET_EXIT_TcpDataMessage *tdm; | ||
1243 | struct ChannelMessageQueue *tnq; | ||
1244 | size_t mlen; | ||
1245 | 959 | ||
960 | GNUNET_STATISTICS_update (stats, | ||
961 | gettext_noop ("# TCP packets sent via TUN"), | ||
962 | 1, | ||
963 | GNUNET_NO); | ||
964 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
965 | "Sending packet with %u bytes TCP payload via TUN\n", | ||
966 | (unsigned int) payload_length); | ||
967 | len = sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_TUN_Layer2PacketHeader); | ||
968 | switch (source_address->af) | ||
1246 | { | 969 | { |
1247 | char sbuf[INET6_ADDRSTRLEN]; | 970 | case AF_INET: |
1248 | char dbuf[INET6_ADDRSTRLEN]; | 971 | len += sizeof (struct GNUNET_TUN_IPv4Header); |
1249 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 972 | break; |
1250 | "Received TCP packet with %u bytes going from %s:%u to %s:%u\n", | 973 | case AF_INET6: |
1251 | (unsigned int) (pktlen - sizeof (struct GNUNET_TUN_TcpHeader)), | 974 | len += sizeof (struct GNUNET_TUN_IPv6Header); |
1252 | inet_ntop (af, | 975 | break; |
1253 | source_ip, | 976 | default: |
1254 | sbuf, sizeof (sbuf)), | 977 | GNUNET_break (0); |
1255 | (unsigned int) ntohs (tcp->source_port), | 978 | return; |
1256 | inet_ntop (af, | ||
1257 | destination_ip, | ||
1258 | dbuf, sizeof (dbuf)), | ||
1259 | (unsigned int) ntohs (tcp->destination_port)); | ||
1260 | } | 979 | } |
1261 | if (pktlen < sizeof (struct GNUNET_TUN_TcpHeader)) | 980 | len += sizeof (struct GNUNET_TUN_TcpHeader); |
981 | len += payload_length; | ||
982 | if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
1262 | { | 983 | { |
1263 | /* blame kernel */ | ||
1264 | GNUNET_break (0); | 984 | GNUNET_break (0); |
1265 | return; | 985 | return; |
1266 | } | 986 | } |
1267 | state = get_redirect_state (af, | ||
1268 | IPPROTO_TCP, | ||
1269 | source_ip, | ||
1270 | ntohs (tcp->source_port), | ||
1271 | destination_ip, | ||
1272 | ntohs (tcp->destination_port), | ||
1273 | NULL); | ||
1274 | if (NULL == state) | ||
1275 | { | 987 | { |
1276 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 988 | char buf[len] GNUNET_ALIGN; |
1277 | _("TCP Packet dropped, have no matching connection information\n")); | 989 | struct GNUNET_MessageHeader *hdr; |
990 | struct GNUNET_TUN_Layer2PacketHeader *tun; | ||
1278 | 991 | ||
1279 | return; | 992 | hdr = (struct GNUNET_MessageHeader *) buf; |
1280 | } | 993 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); |
1281 | /* mug port numbers and crc to avoid information leakage; | 994 | hdr->size = htons (len); |
1282 | sender will need to lookup the correct values anyway */ | 995 | tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1]; |
1283 | GNUNET_memcpy (buf, tcp, pktlen); | 996 | tun->flags = htons (0); |
1284 | mtcp = (struct GNUNET_TUN_TcpHeader *) buf; | 997 | switch (source_address->af) |
1285 | mtcp->source_port = 0; | 998 | { |
1286 | mtcp->destination_port = 0; | 999 | case AF_INET: |
1287 | mtcp->crc = 0; | 1000 | { |
1001 | struct GNUNET_TUN_IPv4Header *ipv4 | ||
1002 | = (struct GNUNET_TUN_IPv4Header*) &tun[1]; | ||
1288 | 1003 | ||
1289 | mlen = sizeof (struct GNUNET_EXIT_TcpDataMessage) + (pktlen - sizeof (struct GNUNET_TUN_TcpHeader)); | 1004 | tun->proto = htons (ETH_P_IPV4); |
1290 | if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | 1005 | prepare_ipv4_packet (payload, |
1291 | { | 1006 | payload_length, |
1292 | GNUNET_break (0); | 1007 | IPPROTO_TCP, |
1293 | return; | 1008 | tcp_header, |
1294 | } | 1009 | source_address, |
1010 | destination_address, | ||
1011 | ipv4); | ||
1012 | } | ||
1013 | break; | ||
1014 | case AF_INET6: | ||
1015 | { | ||
1016 | struct GNUNET_TUN_IPv6Header *ipv6 | ||
1017 | = (struct GNUNET_TUN_IPv6Header*) &tun[1]; | ||
1295 | 1018 | ||
1296 | tnq = GNUNET_malloc (sizeof (struct ChannelMessageQueue) + mlen); | 1019 | tun->proto = htons (ETH_P_IPV6); |
1297 | tnq->payload = &tnq[1]; | 1020 | prepare_ipv6_packet (payload, |
1298 | tnq->len = mlen; | 1021 | payload_length, |
1299 | tdm = (struct GNUNET_EXIT_TcpDataMessage *) &tnq[1]; | 1022 | IPPROTO_TCP, |
1300 | tdm->header.size = htons ((uint16_t) mlen); | 1023 | tcp_header, |
1301 | tdm->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_VPN); | 1024 | source_address, |
1302 | tdm->reserved = htonl (0); | 1025 | destination_address, |
1303 | GNUNET_memcpy (&tdm->tcp_header, | 1026 | ipv6); |
1304 | buf, | 1027 | } |
1305 | pktlen); | 1028 | break; |
1306 | send_packet_to_cadet_channel (state, tnq); | 1029 | default: |
1030 | GNUNET_assert (0); | ||
1031 | break; | ||
1032 | } | ||
1033 | if (NULL != helper_handle) | ||
1034 | (void) GNUNET_HELPER_send (helper_handle, | ||
1035 | (const struct GNUNET_MessageHeader*) buf, | ||
1036 | GNUNET_YES, | ||
1037 | NULL, | ||
1038 | NULL); | ||
1039 | } | ||
1307 | } | 1040 | } |
1308 | 1041 | ||
1309 | 1042 | ||
1310 | /** | 1043 | /** |
1311 | * Receive packets from the helper-process | 1044 | * Send an ICMP packet via the TUN interface. |
1312 | * | 1045 | * |
1313 | * @param cls unused | 1046 | * @param destination_address IP to use for the ICMP packet's destination |
1314 | * @param client unsued | 1047 | * @param source_address IP to use for the ICMP packet's source |
1315 | * @param message message received from helper | 1048 | * @param icmp_header ICMP header to send |
1049 | * @param payload payload of the ICMP packet (does NOT include ICMP header) | ||
1050 | * @param payload_length number of bytes of data in @a payload | ||
1316 | */ | 1051 | */ |
1317 | static int | 1052 | static void |
1318 | message_token (void *cls GNUNET_UNUSED, | 1053 | send_icmp_packet_via_tun (const struct SocketAddress *destination_address, |
1319 | void *client GNUNET_UNUSED, | 1054 | const struct SocketAddress *source_address, |
1320 | const struct GNUNET_MessageHeader *message) | 1055 | const struct GNUNET_TUN_IcmpHeader *icmp_header, |
1056 | const void *payload, size_t payload_length) | ||
1321 | { | 1057 | { |
1322 | const struct GNUNET_TUN_Layer2PacketHeader *pkt_tun; | 1058 | size_t len; |
1323 | size_t size; | 1059 | struct GNUNET_TUN_IcmpHeader *icmp; |
1324 | 1060 | ||
1325 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1326 | "Got %u-byte message of type %u from gnunet-helper-exit\n", | ||
1327 | ntohs (message->size), | ||
1328 | ntohs (message->type)); | ||
1329 | GNUNET_STATISTICS_update (stats, | 1061 | GNUNET_STATISTICS_update (stats, |
1330 | gettext_noop ("# Packets received from TUN"), | 1062 | gettext_noop ("# ICMP packets sent via TUN"), |
1331 | 1, GNUNET_NO); | 1063 | 1, GNUNET_NO); |
1332 | if (ntohs (message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) | 1064 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1065 | "Sending packet with %u bytes ICMP payload via TUN\n", | ||
1066 | (unsigned int) payload_length); | ||
1067 | len = sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_TUN_Layer2PacketHeader); | ||
1068 | switch (destination_address->af) | ||
1333 | { | 1069 | { |
1070 | case AF_INET: | ||
1071 | len += sizeof (struct GNUNET_TUN_IPv4Header); | ||
1072 | break; | ||
1073 | case AF_INET6: | ||
1074 | len += sizeof (struct GNUNET_TUN_IPv6Header); | ||
1075 | break; | ||
1076 | default: | ||
1334 | GNUNET_break (0); | 1077 | GNUNET_break (0); |
1335 | return GNUNET_OK; | 1078 | return; |
1336 | } | 1079 | } |
1337 | size = ntohs (message->size); | 1080 | len += sizeof (struct GNUNET_TUN_IcmpHeader); |
1338 | if (size < sizeof (struct GNUNET_TUN_Layer2PacketHeader) + sizeof (struct GNUNET_MessageHeader)) | 1081 | len += payload_length; |
1082 | if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
1339 | { | 1083 | { |
1340 | GNUNET_break (0); | 1084 | GNUNET_break (0); |
1341 | return GNUNET_OK; | 1085 | return; |
1342 | } | 1086 | } |
1343 | GNUNET_STATISTICS_update (stats, | ||
1344 | gettext_noop ("# Bytes received from TUN"), | ||
1345 | size, GNUNET_NO); | ||
1346 | pkt_tun = (const struct GNUNET_TUN_Layer2PacketHeader *) &message[1]; | ||
1347 | size -= sizeof (struct GNUNET_TUN_Layer2PacketHeader) + sizeof (struct GNUNET_MessageHeader); | ||
1348 | switch (ntohs (pkt_tun->proto)) | ||
1349 | { | 1087 | { |
1350 | case ETH_P_IPV4: | 1088 | char buf[len] GNUNET_ALIGN; |
1351 | { | 1089 | struct GNUNET_MessageHeader *hdr; |
1352 | const struct GNUNET_TUN_IPv4Header *pkt4; | 1090 | struct GNUNET_TUN_Layer2PacketHeader *tun; |
1353 | |||
1354 | if (size < sizeof (struct GNUNET_TUN_IPv4Header)) | ||
1355 | { | ||
1356 | /* Kernel to blame? */ | ||
1357 | GNUNET_break (0); | ||
1358 | return GNUNET_OK; | ||
1359 | } | ||
1360 | pkt4 = (const struct GNUNET_TUN_IPv4Header *) &pkt_tun[1]; | ||
1361 | if (size != ntohs (pkt4->total_length)) | ||
1362 | { | ||
1363 | /* Kernel to blame? */ | ||
1364 | GNUNET_break (0); | ||
1365 | return GNUNET_OK; | ||
1366 | } | ||
1367 | if (pkt4->header_length * 4 != sizeof (struct GNUNET_TUN_IPv4Header)) | ||
1368 | { | ||
1369 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1370 | _("IPv4 packet options received. Ignored.\n")); | ||
1371 | return GNUNET_OK; | ||
1372 | } | ||
1373 | 1091 | ||
1374 | size -= sizeof (struct GNUNET_TUN_IPv4Header); | 1092 | hdr= (struct GNUNET_MessageHeader *) buf; |
1375 | switch (pkt4->protocol) | 1093 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); |
1376 | { | 1094 | hdr->size = htons (len); |
1377 | case IPPROTO_UDP: | 1095 | tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1]; |
1378 | udp_from_helper ((const struct GNUNET_TUN_UdpHeader *) &pkt4[1], size, | 1096 | tun->flags = htons (0); |
1379 | AF_INET, | 1097 | switch (source_address->af) |
1380 | &pkt4->destination_address, | ||
1381 | &pkt4->source_address); | ||
1382 | break; | ||
1383 | case IPPROTO_TCP: | ||
1384 | tcp_from_helper ((const struct GNUNET_TUN_TcpHeader *) &pkt4[1], size, | ||
1385 | AF_INET, | ||
1386 | &pkt4->destination_address, | ||
1387 | &pkt4->source_address); | ||
1388 | break; | ||
1389 | case IPPROTO_ICMP: | ||
1390 | icmp_from_helper ((const struct GNUNET_TUN_IcmpHeader *) &pkt4[1], size, | ||
1391 | AF_INET, | ||
1392 | &pkt4->destination_address, | ||
1393 | &pkt4->source_address); | ||
1394 | break; | ||
1395 | default: | ||
1396 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1397 | _("IPv4 packet with unsupported next header %u received. Ignored.\n"), | ||
1398 | (int) pkt4->protocol); | ||
1399 | return GNUNET_OK; | ||
1400 | } | ||
1401 | } | ||
1402 | break; | ||
1403 | case ETH_P_IPV6: | ||
1404 | { | 1098 | { |
1405 | const struct GNUNET_TUN_IPv6Header *pkt6; | 1099 | case AF_INET: |
1406 | |||
1407 | if (size < sizeof (struct GNUNET_TUN_IPv6Header)) | ||
1408 | { | ||
1409 | /* Kernel to blame? */ | ||
1410 | GNUNET_break (0); | ||
1411 | return GNUNET_OK; | ||
1412 | } | ||
1413 | pkt6 = (struct GNUNET_TUN_IPv6Header *) &pkt_tun[1]; | ||
1414 | if (size != ntohs (pkt6->payload_length) + sizeof (struct GNUNET_TUN_IPv6Header)) | ||
1415 | { | 1100 | { |
1416 | /* Kernel to blame? */ | 1101 | struct GNUNET_TUN_IPv4Header * ipv4 = (struct GNUNET_TUN_IPv4Header*) &tun[1]; |
1417 | GNUNET_break (0); | 1102 | |
1418 | return GNUNET_OK; | 1103 | tun->proto = htons (ETH_P_IPV4); |
1104 | GNUNET_TUN_initialize_ipv4_header (ipv4, | ||
1105 | IPPROTO_ICMP, | ||
1106 | sizeof (struct GNUNET_TUN_IcmpHeader) + payload_length, | ||
1107 | &source_address->address.ipv4, | ||
1108 | &destination_address->address.ipv4); | ||
1109 | icmp = (struct GNUNET_TUN_IcmpHeader*) &ipv4[1]; | ||
1419 | } | 1110 | } |
1420 | size -= sizeof (struct GNUNET_TUN_IPv6Header); | 1111 | break; |
1421 | switch (pkt6->next_header) | 1112 | case AF_INET6: |
1422 | { | 1113 | { |
1423 | case IPPROTO_UDP: | 1114 | struct GNUNET_TUN_IPv6Header * ipv6 = (struct GNUNET_TUN_IPv6Header*) &tun[1]; |
1424 | udp_from_helper ((const struct GNUNET_TUN_UdpHeader *) &pkt6[1], size, | 1115 | |
1425 | AF_INET6, | 1116 | tun->proto = htons (ETH_P_IPV6); |
1426 | &pkt6->destination_address, | 1117 | GNUNET_TUN_initialize_ipv6_header (ipv6, |
1427 | &pkt6->source_address); | 1118 | IPPROTO_ICMPV6, |
1428 | break; | 1119 | sizeof (struct GNUNET_TUN_IcmpHeader) + payload_length, |
1429 | case IPPROTO_TCP: | 1120 | &source_address->address.ipv6, |
1430 | tcp_from_helper ((const struct GNUNET_TUN_TcpHeader *) &pkt6[1], size, | 1121 | &destination_address->address.ipv6); |
1431 | AF_INET6, | 1122 | icmp = (struct GNUNET_TUN_IcmpHeader*) &ipv6[1]; |
1432 | &pkt6->destination_address, | ||
1433 | &pkt6->source_address); | ||
1434 | break; | ||
1435 | case IPPROTO_ICMPV6: | ||
1436 | icmp_from_helper ((const struct GNUNET_TUN_IcmpHeader *) &pkt6[1], size, | ||
1437 | AF_INET6, | ||
1438 | &pkt6->destination_address, | ||
1439 | &pkt6->source_address); | ||
1440 | break; | ||
1441 | default: | ||
1442 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1443 | _("IPv6 packet with unsupported next header %d received. Ignored.\n"), | ||
1444 | pkt6->next_header); | ||
1445 | return GNUNET_OK; | ||
1446 | } | 1123 | } |
1124 | break; | ||
1125 | default: | ||
1126 | GNUNET_assert (0); | ||
1127 | break; | ||
1447 | } | 1128 | } |
1448 | break; | 1129 | *icmp = *icmp_header; |
1449 | default: | 1130 | GNUNET_memcpy (&icmp[1], |
1450 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1131 | payload, |
1451 | _("Packet from unknown protocol %u received. Ignored.\n"), | 1132 | payload_length); |
1452 | ntohs (pkt_tun->proto)); | 1133 | GNUNET_TUN_calculate_icmp_checksum (icmp, |
1453 | break; | 1134 | payload, |
1135 | payload_length); | ||
1136 | if (NULL != helper_handle) | ||
1137 | (void) GNUNET_HELPER_send (helper_handle, | ||
1138 | (const struct GNUNET_MessageHeader*) buf, | ||
1139 | GNUNET_YES, | ||
1140 | NULL, NULL); | ||
1454 | } | 1141 | } |
1455 | return GNUNET_OK; | ||
1456 | } | 1142 | } |
1457 | 1143 | ||
1458 | 1144 | ||
@@ -1637,223 +1323,25 @@ setup_state_record (struct ChannelState *state) | |||
1637 | 1323 | ||
1638 | 1324 | ||
1639 | /** | 1325 | /** |
1640 | * Prepare an IPv4 packet for transmission via the TUN interface. | 1326 | * Send a UDP packet via the TUN interface. |
1641 | * Initializes the IP header and calculates checksums (IP+UDP/TCP). | ||
1642 | * For UDP, the UDP header will be fully created, whereas for TCP | ||
1643 | * only the ports and checksum will be filled in. So for TCP, | ||
1644 | * a skeleton TCP header must be part of the provided payload. | ||
1645 | * | ||
1646 | * @param payload payload of the packet (starting with UDP payload or | ||
1647 | * TCP header, depending on protocol) | ||
1648 | * @param payload_length number of bytes in @a payload | ||
1649 | * @param protocol IPPROTO_UDP or IPPROTO_TCP | ||
1650 | * @param tcp_header skeleton of the TCP header, NULL for UDP | ||
1651 | * @param src_address source address to use (IP and port) | ||
1652 | * @param dst_address destination address to use (IP and port) | ||
1653 | * @param pkt4 where to write the assembled packet; must | ||
1654 | * contain enough space for the IP header, UDP/TCP header | ||
1655 | * AND the payload | ||
1656 | */ | ||
1657 | static void | ||
1658 | prepare_ipv4_packet (const void *payload, | ||
1659 | size_t payload_length, | ||
1660 | int protocol, | ||
1661 | const struct GNUNET_TUN_TcpHeader *tcp_header, | ||
1662 | const struct SocketAddress *src_address, | ||
1663 | const struct SocketAddress *dst_address, | ||
1664 | struct GNUNET_TUN_IPv4Header *pkt4) | ||
1665 | { | ||
1666 | size_t len; | ||
1667 | |||
1668 | len = payload_length; | ||
1669 | switch (protocol) | ||
1670 | { | ||
1671 | case IPPROTO_UDP: | ||
1672 | len += sizeof (struct GNUNET_TUN_UdpHeader); | ||
1673 | break; | ||
1674 | case IPPROTO_TCP: | ||
1675 | len += sizeof (struct GNUNET_TUN_TcpHeader); | ||
1676 | GNUNET_assert (NULL != tcp_header); | ||
1677 | break; | ||
1678 | default: | ||
1679 | GNUNET_break (0); | ||
1680 | return; | ||
1681 | } | ||
1682 | if (len + sizeof (struct GNUNET_TUN_IPv4Header) > UINT16_MAX) | ||
1683 | { | ||
1684 | GNUNET_break (0); | ||
1685 | return; | ||
1686 | } | ||
1687 | |||
1688 | GNUNET_TUN_initialize_ipv4_header (pkt4, | ||
1689 | protocol, | ||
1690 | len, | ||
1691 | &src_address->address.ipv4, | ||
1692 | &dst_address->address.ipv4); | ||
1693 | switch (protocol) | ||
1694 | { | ||
1695 | case IPPROTO_UDP: | ||
1696 | { | ||
1697 | struct GNUNET_TUN_UdpHeader *pkt4_udp = (struct GNUNET_TUN_UdpHeader *) &pkt4[1]; | ||
1698 | |||
1699 | pkt4_udp->source_port = htons (src_address->port); | ||
1700 | pkt4_udp->destination_port = htons (dst_address->port); | ||
1701 | pkt4_udp->len = htons ((uint16_t) payload_length); | ||
1702 | GNUNET_TUN_calculate_udp4_checksum (pkt4, | ||
1703 | pkt4_udp, | ||
1704 | payload, | ||
1705 | payload_length); | ||
1706 | GNUNET_memcpy (&pkt4_udp[1], | ||
1707 | payload, | ||
1708 | payload_length); | ||
1709 | } | ||
1710 | break; | ||
1711 | case IPPROTO_TCP: | ||
1712 | { | ||
1713 | struct GNUNET_TUN_TcpHeader *pkt4_tcp = (struct GNUNET_TUN_TcpHeader *) &pkt4[1]; | ||
1714 | |||
1715 | *pkt4_tcp = *tcp_header; | ||
1716 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1717 | "Sending TCP packet from port %u to port %u\n", | ||
1718 | src_address->port, | ||
1719 | dst_address->port); | ||
1720 | pkt4_tcp->source_port = htons (src_address->port); | ||
1721 | pkt4_tcp->destination_port = htons (dst_address->port); | ||
1722 | GNUNET_TUN_calculate_tcp4_checksum (pkt4, | ||
1723 | pkt4_tcp, | ||
1724 | payload, | ||
1725 | payload_length); | ||
1726 | GNUNET_memcpy (&pkt4_tcp[1], | ||
1727 | payload, | ||
1728 | payload_length); | ||
1729 | } | ||
1730 | break; | ||
1731 | default: | ||
1732 | GNUNET_assert (0); | ||
1733 | } | ||
1734 | } | ||
1735 | |||
1736 | |||
1737 | /** | ||
1738 | * Prepare an IPv6 packet for transmission via the TUN interface. | ||
1739 | * Initializes the IP header and calculates checksums (IP+UDP/TCP). | ||
1740 | * For UDP, the UDP header will be fully created, whereas for TCP | ||
1741 | * only the ports and checksum will be filled in. So for TCP, | ||
1742 | * a skeleton TCP header must be part of the provided payload. | ||
1743 | * | ||
1744 | * @param payload payload of the packet (starting with UDP payload or | ||
1745 | * TCP header, depending on protocol) | ||
1746 | * @param payload_length number of bytes in @a payload | ||
1747 | * @param protocol IPPROTO_UDP or IPPROTO_TCP | ||
1748 | * @param tcp_header skeleton TCP header data to send, NULL for UDP | ||
1749 | * @param src_address source address to use (IP and port) | ||
1750 | * @param dst_address destination address to use (IP and port) | ||
1751 | * @param pkt6 where to write the assembled packet; must | ||
1752 | * contain enough space for the IP header, UDP/TCP header | ||
1753 | * AND the payload | ||
1754 | */ | ||
1755 | static void | ||
1756 | prepare_ipv6_packet (const void *payload, | ||
1757 | size_t payload_length, | ||
1758 | int protocol, | ||
1759 | const struct GNUNET_TUN_TcpHeader *tcp_header, | ||
1760 | const struct SocketAddress *src_address, | ||
1761 | const struct SocketAddress *dst_address, | ||
1762 | struct GNUNET_TUN_IPv6Header *pkt6) | ||
1763 | { | ||
1764 | size_t len; | ||
1765 | |||
1766 | len = payload_length; | ||
1767 | switch (protocol) | ||
1768 | { | ||
1769 | case IPPROTO_UDP: | ||
1770 | len += sizeof (struct GNUNET_TUN_UdpHeader); | ||
1771 | break; | ||
1772 | case IPPROTO_TCP: | ||
1773 | len += sizeof (struct GNUNET_TUN_TcpHeader); | ||
1774 | break; | ||
1775 | default: | ||
1776 | GNUNET_break (0); | ||
1777 | return; | ||
1778 | } | ||
1779 | if (len > UINT16_MAX) | ||
1780 | { | ||
1781 | GNUNET_break (0); | ||
1782 | return; | ||
1783 | } | ||
1784 | |||
1785 | GNUNET_TUN_initialize_ipv6_header (pkt6, | ||
1786 | protocol, | ||
1787 | len, | ||
1788 | &src_address->address.ipv6, | ||
1789 | &dst_address->address.ipv6); | ||
1790 | |||
1791 | switch (protocol) | ||
1792 | { | ||
1793 | case IPPROTO_UDP: | ||
1794 | { | ||
1795 | struct GNUNET_TUN_UdpHeader *pkt6_udp = (struct GNUNET_TUN_UdpHeader *) &pkt6[1]; | ||
1796 | |||
1797 | pkt6_udp->source_port = htons (src_address->port); | ||
1798 | pkt6_udp->destination_port = htons (dst_address->port); | ||
1799 | pkt6_udp->len = htons ((uint16_t) payload_length); | ||
1800 | GNUNET_TUN_calculate_udp6_checksum (pkt6, | ||
1801 | pkt6_udp, | ||
1802 | payload, | ||
1803 | payload_length); | ||
1804 | GNUNET_memcpy (&pkt6_udp[1], | ||
1805 | payload, | ||
1806 | payload_length); | ||
1807 | } | ||
1808 | break; | ||
1809 | case IPPROTO_TCP: | ||
1810 | { | ||
1811 | struct GNUNET_TUN_TcpHeader *pkt6_tcp = (struct GNUNET_TUN_TcpHeader *) &pkt6[1]; | ||
1812 | |||
1813 | /* GNUNET_memcpy first here as some TCP header fields are initialized this way! */ | ||
1814 | *pkt6_tcp = *tcp_header; | ||
1815 | pkt6_tcp->source_port = htons (src_address->port); | ||
1816 | pkt6_tcp->destination_port = htons (dst_address->port); | ||
1817 | GNUNET_TUN_calculate_tcp6_checksum (pkt6, | ||
1818 | pkt6_tcp, | ||
1819 | payload, | ||
1820 | payload_length); | ||
1821 | GNUNET_memcpy (&pkt6_tcp[1], | ||
1822 | payload, | ||
1823 | payload_length); | ||
1824 | } | ||
1825 | break; | ||
1826 | default: | ||
1827 | GNUNET_assert (0); | ||
1828 | break; | ||
1829 | } | ||
1830 | } | ||
1831 | |||
1832 | |||
1833 | /** | ||
1834 | * Send a TCP packet via the TUN interface. | ||
1835 | * | 1327 | * |
1836 | * @param destination_address IP and port to use for the TCP packet's destination | 1328 | * @param destination_address IP and port to use for the UDP packet's destination |
1837 | * @param source_address IP and port to use for the TCP packet's source | 1329 | * @param source_address IP and port to use for the UDP packet's source |
1838 | * @param tcp_header header template to use | 1330 | * @param payload payload of the UDP packet (does NOT include UDP header) |
1839 | * @param payload payload of the TCP packet | 1331 | * @param payload_length number of bytes of data in @a payload |
1840 | * @param payload_length number of bytes in @a payload | ||
1841 | */ | 1332 | */ |
1842 | static void | 1333 | static void |
1843 | send_tcp_packet_via_tun (const struct SocketAddress *destination_address, | 1334 | send_udp_packet_via_tun (const struct SocketAddress *destination_address, |
1844 | const struct SocketAddress *source_address, | 1335 | const struct SocketAddress *source_address, |
1845 | const struct GNUNET_TUN_TcpHeader *tcp_header, | 1336 | const void *payload, size_t payload_length) |
1846 | const void *payload, | ||
1847 | size_t payload_length) | ||
1848 | { | 1337 | { |
1849 | size_t len; | 1338 | size_t len; |
1850 | 1339 | ||
1851 | GNUNET_STATISTICS_update (stats, | 1340 | GNUNET_STATISTICS_update (stats, |
1852 | gettext_noop ("# TCP packets sent via TUN"), | 1341 | gettext_noop ("# UDP packets sent via TUN"), |
1853 | 1, | 1342 | 1, GNUNET_NO); |
1854 | GNUNET_NO); | ||
1855 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1343 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1856 | "Sending packet with %u bytes TCP payload via TUN\n", | 1344 | "Sending packet with %u bytes UDP payload via TUN\n", |
1857 | (unsigned int) payload_length); | 1345 | (unsigned int) payload_length); |
1858 | len = sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_TUN_Layer2PacketHeader); | 1346 | len = sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_TUN_Layer2PacketHeader); |
1859 | switch (source_address->af) | 1347 | switch (source_address->af) |
@@ -1868,7 +1356,7 @@ send_tcp_packet_via_tun (const struct SocketAddress *destination_address, | |||
1868 | GNUNET_break (0); | 1356 | GNUNET_break (0); |
1869 | return; | 1357 | return; |
1870 | } | 1358 | } |
1871 | len += sizeof (struct GNUNET_TUN_TcpHeader); | 1359 | len += sizeof (struct GNUNET_TUN_UdpHeader); |
1872 | len += payload_length; | 1360 | len += payload_length; |
1873 | if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | 1361 | if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE) |
1874 | { | 1362 | { |
@@ -1880,7 +1368,7 @@ send_tcp_packet_via_tun (const struct SocketAddress *destination_address, | |||
1880 | struct GNUNET_MessageHeader *hdr; | 1368 | struct GNUNET_MessageHeader *hdr; |
1881 | struct GNUNET_TUN_Layer2PacketHeader *tun; | 1369 | struct GNUNET_TUN_Layer2PacketHeader *tun; |
1882 | 1370 | ||
1883 | hdr = (struct GNUNET_MessageHeader *) buf; | 1371 | hdr= (struct GNUNET_MessageHeader *) buf; |
1884 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | 1372 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); |
1885 | hdr->size = htons (len); | 1373 | hdr->size = htons (len); |
1886 | tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1]; | 1374 | tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1]; |
@@ -1889,14 +1377,13 @@ send_tcp_packet_via_tun (const struct SocketAddress *destination_address, | |||
1889 | { | 1377 | { |
1890 | case AF_INET: | 1378 | case AF_INET: |
1891 | { | 1379 | { |
1892 | struct GNUNET_TUN_IPv4Header *ipv4 | 1380 | struct GNUNET_TUN_IPv4Header * ipv4 = (struct GNUNET_TUN_IPv4Header*) &tun[1]; |
1893 | = (struct GNUNET_TUN_IPv4Header*) &tun[1]; | ||
1894 | 1381 | ||
1895 | tun->proto = htons (ETH_P_IPV4); | 1382 | tun->proto = htons (ETH_P_IPV4); |
1896 | prepare_ipv4_packet (payload, | 1383 | prepare_ipv4_packet (payload, |
1897 | payload_length, | 1384 | payload_length, |
1898 | IPPROTO_TCP, | 1385 | IPPROTO_UDP, |
1899 | tcp_header, | 1386 | NULL, |
1900 | source_address, | 1387 | source_address, |
1901 | destination_address, | 1388 | destination_address, |
1902 | ipv4); | 1389 | ipv4); |
@@ -1904,14 +1391,13 @@ send_tcp_packet_via_tun (const struct SocketAddress *destination_address, | |||
1904 | break; | 1391 | break; |
1905 | case AF_INET6: | 1392 | case AF_INET6: |
1906 | { | 1393 | { |
1907 | struct GNUNET_TUN_IPv6Header *ipv6 | 1394 | struct GNUNET_TUN_IPv6Header * ipv6 = (struct GNUNET_TUN_IPv6Header*) &tun[1]; |
1908 | = (struct GNUNET_TUN_IPv6Header*) &tun[1]; | ||
1909 | 1395 | ||
1910 | tun->proto = htons (ETH_P_IPV6); | 1396 | tun->proto = htons (ETH_P_IPV6); |
1911 | prepare_ipv6_packet (payload, | 1397 | prepare_ipv6_packet (payload, |
1912 | payload_length, | 1398 | payload_length, |
1913 | IPPROTO_TCP, | 1399 | IPPROTO_UDP, |
1914 | tcp_header, | 1400 | NULL, |
1915 | source_address, | 1401 | source_address, |
1916 | destination_address, | 1402 | destination_address, |
1917 | ipv6); | 1403 | ipv6); |
@@ -1925,48 +1411,202 @@ send_tcp_packet_via_tun (const struct SocketAddress *destination_address, | |||
1925 | (void) GNUNET_HELPER_send (helper_handle, | 1411 | (void) GNUNET_HELPER_send (helper_handle, |
1926 | (const struct GNUNET_MessageHeader*) buf, | 1412 | (const struct GNUNET_MessageHeader*) buf, |
1927 | GNUNET_YES, | 1413 | GNUNET_YES, |
1928 | NULL, | 1414 | NULL, NULL); |
1929 | NULL); | ||
1930 | } | 1415 | } |
1931 | } | 1416 | } |
1932 | 1417 | ||
1933 | 1418 | ||
1934 | /** | 1419 | /** |
1935 | * Process a request via cadet to send a request to a TCP service | 1420 | * Check a request to forward UDP data to the Internet via this peer. |
1936 | * offered by this system. | ||
1937 | * | 1421 | * |
1938 | * @param cls closure, NULL | 1422 | * @param cls our `struct ChannelState *` |
1939 | * @param channel connection to the other end | 1423 | * @param msg the actual message |
1940 | * @param channel_ctx pointer to our `struct ChannelState *` | ||
1941 | * @param message the actual message | ||
1942 | * @return #GNUNET_OK to keep the connection open, | 1424 | * @return #GNUNET_OK to keep the connection open, |
1943 | * #GNUNET_SYSERR to close it (signal serious error) | 1425 | * #GNUNET_SYSERR to close it (signal serious error) |
1944 | */ | 1426 | */ |
1945 | static int | 1427 | static int |
1946 | receive_tcp_service (void *cls, | 1428 | check_udp_remote (void *cls, |
1947 | struct GNUNET_CADET_Channel *channel, | 1429 | const struct GNUNET_EXIT_UdpInternetMessage *msg) |
1948 | void **channel_ctx, | ||
1949 | const struct GNUNET_MessageHeader *message) | ||
1950 | { | 1430 | { |
1951 | struct ChannelState *state = *channel_ctx; | 1431 | struct ChannelState *state = cls; |
1952 | const struct GNUNET_EXIT_TcpServiceStartMessage *start; | ||
1953 | uint16_t pkt_len = ntohs (message->size); | ||
1954 | 1432 | ||
1955 | if (NULL == state) | 1433 | if (GNUNET_YES == state->is_dns) |
1956 | { | 1434 | { |
1957 | GNUNET_break_op (0); | 1435 | GNUNET_break_op (0); |
1958 | return GNUNET_SYSERR; | 1436 | return GNUNET_SYSERR; |
1959 | } | 1437 | } |
1960 | if (GNUNET_YES == state->is_dns) | 1438 | return GNUNET_OK; |
1439 | } | ||
1440 | |||
1441 | |||
1442 | /** | ||
1443 | * Process a request to forward UDP data to the Internet via this peer. | ||
1444 | * | ||
1445 | * @param cls our `struct ChannelState *` | ||
1446 | * @param msg the actual message | ||
1447 | */ | ||
1448 | static void | ||
1449 | handle_udp_remote (void *cls, | ||
1450 | const struct GNUNET_EXIT_UdpInternetMessage *msg) | ||
1451 | { | ||
1452 | struct ChannelState *state = cls; | ||
1453 | uint16_t pkt_len = ntohs (msg->header.size) - sizeof (struct GNUNET_EXIT_UdpInternetMessage); | ||
1454 | const struct in_addr *v4; | ||
1455 | const struct in6_addr *v6; | ||
1456 | const void *payload; | ||
1457 | int af; | ||
1458 | |||
1459 | if (GNUNET_SYSERR == state->is_dns) | ||
1460 | { | ||
1461 | /* channel is UDP/TCP from now on */ | ||
1462 | state->is_dns = GNUNET_NO; | ||
1463 | } | ||
1464 | GNUNET_STATISTICS_update (stats, | ||
1465 | gettext_noop ("# Bytes received from CADET"), | ||
1466 | pkt_len, GNUNET_NO); | ||
1467 | GNUNET_STATISTICS_update (stats, | ||
1468 | gettext_noop ("# UDP IP-exit requests received via cadet"), | ||
1469 | 1, GNUNET_NO); | ||
1470 | af = (int) ntohl (msg->af); | ||
1471 | state->specifics.tcp_udp.ri.remote_address.af = af; | ||
1472 | switch (af) | ||
1961 | { | 1473 | { |
1474 | case AF_INET: | ||
1475 | if (pkt_len < sizeof (struct in_addr)) | ||
1476 | { | ||
1477 | GNUNET_break_op (0); | ||
1478 | return; | ||
1479 | } | ||
1480 | if (! ipv4_exit) | ||
1481 | { | ||
1482 | GNUNET_break_op (0); | ||
1483 | return; | ||
1484 | } | ||
1485 | v4 = (const struct in_addr*) &msg[1]; | ||
1486 | payload = &v4[1]; | ||
1487 | pkt_len -= sizeof (struct in_addr); | ||
1488 | state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4; | ||
1489 | break; | ||
1490 | case AF_INET6: | ||
1491 | if (pkt_len < sizeof (struct in6_addr)) | ||
1492 | { | ||
1493 | GNUNET_break_op (0); | ||
1494 | return; | ||
1495 | } | ||
1496 | if (! ipv6_exit) | ||
1497 | { | ||
1498 | GNUNET_break_op (0); | ||
1499 | return; | ||
1500 | } | ||
1501 | v6 = (const struct in6_addr*) &msg[1]; | ||
1502 | payload = &v6[1]; | ||
1503 | pkt_len -= sizeof (struct in6_addr); | ||
1504 | state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6; | ||
1505 | break; | ||
1506 | default: | ||
1962 | GNUNET_break_op (0); | 1507 | GNUNET_break_op (0); |
1963 | return GNUNET_SYSERR; | 1508 | return; |
1964 | } | 1509 | } |
1510 | { | ||
1511 | char buf[INET6_ADDRSTRLEN]; | ||
1512 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1513 | "Received data from %s for forwarding to UDP %s:%u\n", | ||
1514 | GNUNET_i2s (&state->peer), | ||
1515 | inet_ntop (af, | ||
1516 | &state->specifics.tcp_udp.ri.remote_address.address, | ||
1517 | buf, sizeof (buf)), | ||
1518 | (unsigned int) ntohs (msg->destination_port)); | ||
1519 | } | ||
1520 | state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_UDP; | ||
1521 | state->specifics.tcp_udp.ri.remote_address.port = msg->destination_port; | ||
1522 | if (NULL == state->specifics.tcp_udp.heap_node) | ||
1523 | setup_state_record (state); | ||
1524 | if (0 != ntohs (msg->source_port)) | ||
1525 | state->specifics.tcp_udp.ri.local_address.port = msg->source_port; | ||
1526 | send_udp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address, | ||
1527 | &state->specifics.tcp_udp.ri.local_address, | ||
1528 | payload, | ||
1529 | pkt_len); | ||
1530 | GNUNET_CADET_receive_done (state->channel); | ||
1531 | } | ||
1532 | |||
1533 | |||
1534 | /** | ||
1535 | * Check a request via cadet to send a request to a UDP service | ||
1536 | * offered by this system. | ||
1537 | * | ||
1538 | * @param cls our `struct ChannelState *` | ||
1539 | * @param msg the actual message | ||
1540 | * @return #GNUNET_OK to keep the connection open, | ||
1541 | * #GNUNET_SYSERR to close it (signal serious error) | ||
1542 | */ | ||
1543 | static int | ||
1544 | check_udp_service (void *cls, | ||
1545 | const struct GNUNET_EXIT_UdpServiceMessage *msg) | ||
1546 | { | ||
1547 | struct ChannelState *state = cls; | ||
1548 | |||
1965 | if (NULL == state->specifics.tcp_udp.serv) | 1549 | if (NULL == state->specifics.tcp_udp.serv) |
1966 | { | 1550 | { |
1967 | GNUNET_break_op (0); | 1551 | GNUNET_break_op (0); |
1968 | return GNUNET_SYSERR; | 1552 | return GNUNET_SYSERR; |
1969 | } | 1553 | } |
1554 | return GNUNET_OK; | ||
1555 | } | ||
1556 | |||
1557 | |||
1558 | /** | ||
1559 | * Process a request via cadet to send a request to a UDP service | ||
1560 | * offered by this system. | ||
1561 | * | ||
1562 | * @param cls our `struct ChannelState *` | ||
1563 | * @param msg the actual message | ||
1564 | */ | ||
1565 | static void | ||
1566 | handle_udp_service (void *cls, | ||
1567 | const struct GNUNET_EXIT_UdpServiceMessage *msg) | ||
1568 | { | ||
1569 | struct ChannelState *state = cls; | ||
1570 | uint16_t pkt_len = ntohs (msg->header.size) - sizeof (struct GNUNET_EXIT_UdpServiceMessage); | ||
1571 | |||
1572 | GNUNET_STATISTICS_update (stats, | ||
1573 | gettext_noop ("# Bytes received from CADET"), | ||
1574 | pkt_len, GNUNET_NO); | ||
1575 | GNUNET_STATISTICS_update (stats, | ||
1576 | gettext_noop ("# UDP service requests received via cadet"), | ||
1577 | 1, GNUNET_NO); | ||
1578 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1579 | "Received data from %s for forwarding to UDP service %s on port %u\n", | ||
1580 | GNUNET_i2s (&state->peer), | ||
1581 | GNUNET_h2s (&state->specifics.tcp_udp.serv->descriptor), | ||
1582 | (unsigned int) ntohs (msg->destination_port)); | ||
1583 | setup_state_record (state); | ||
1584 | if (0 != ntohs (msg->source_port)) | ||
1585 | state->specifics.tcp_udp.ri.local_address.port = msg->source_port; | ||
1586 | send_udp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address, | ||
1587 | &state->specifics.tcp_udp.ri.local_address, | ||
1588 | &msg[1], | ||
1589 | pkt_len); | ||
1590 | GNUNET_CADET_receive_done (state->channel); | ||
1591 | } | ||
1592 | |||
1593 | |||
1594 | /** | ||
1595 | * Process a request via cadet to send a request to a TCP service | ||
1596 | * offered by this system. | ||
1597 | * | ||
1598 | * @param cls our `struct ChannelState *` | ||
1599 | * @param start the actual message | ||
1600 | * @return #GNUNET_OK to keep the connection open, | ||
1601 | * #GNUNET_SYSERR to close it (signal serious error) | ||
1602 | */ | ||
1603 | static void | ||
1604 | handle_tcp_service (void *cls, | ||
1605 | const struct GNUNET_EXIT_TcpServiceStartMessage *start) | ||
1606 | { | ||
1607 | struct ChannelState *state = cls; | ||
1608 | uint16_t pkt_len = ntohs (start->header.size) - sizeof (struct GNUNET_EXIT_TcpServiceStartMessage); | ||
1609 | |||
1970 | if (GNUNET_SYSERR == state->is_dns) | 1610 | if (GNUNET_SYSERR == state->is_dns) |
1971 | { | 1611 | { |
1972 | /* channel is UDP/TCP from now on */ | 1612 | /* channel is UDP/TCP from now on */ |
@@ -1980,24 +1620,6 @@ receive_tcp_service (void *cls, | |||
1980 | gettext_noop ("# Bytes received from CADET"), | 1620 | gettext_noop ("# Bytes received from CADET"), |
1981 | pkt_len, | 1621 | pkt_len, |
1982 | GNUNET_NO); | 1622 | GNUNET_NO); |
1983 | /* check that we got at least a valid header */ | ||
1984 | if (pkt_len < sizeof (struct GNUNET_EXIT_TcpServiceStartMessage)) | ||
1985 | { | ||
1986 | GNUNET_break_op (0); | ||
1987 | return GNUNET_SYSERR; | ||
1988 | } | ||
1989 | start = (const struct GNUNET_EXIT_TcpServiceStartMessage*) message; | ||
1990 | pkt_len -= sizeof (struct GNUNET_EXIT_TcpServiceStartMessage); | ||
1991 | if (NULL != state->specifics.tcp_udp.heap_node) | ||
1992 | { | ||
1993 | GNUNET_break_op (0); | ||
1994 | return GNUNET_SYSERR; | ||
1995 | } | ||
1996 | if (start->tcp_header.off * 4 < sizeof (struct GNUNET_TUN_TcpHeader)) | ||
1997 | { | ||
1998 | GNUNET_break_op (0); | ||
1999 | return GNUNET_SYSERR; | ||
2000 | } | ||
2001 | GNUNET_break_op (ntohl (start->reserved) == 0); | 1623 | GNUNET_break_op (ntohl (start->reserved) == 0); |
2002 | /* setup fresh connection */ | 1624 | /* setup fresh connection */ |
2003 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1625 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -2011,34 +1633,23 @@ receive_tcp_service (void *cls, | |||
2011 | &start->tcp_header, | 1633 | &start->tcp_header, |
2012 | &start[1], | 1634 | &start[1], |
2013 | pkt_len); | 1635 | pkt_len); |
2014 | GNUNET_CADET_receive_done (channel); | 1636 | GNUNET_CADET_receive_done (state->channel); |
2015 | return GNUNET_YES; | ||
2016 | } | 1637 | } |
2017 | 1638 | ||
2018 | 1639 | ||
2019 | /** | 1640 | /** |
2020 | * Process a request to forward TCP data to the Internet via this peer. | 1641 | * Check a request to forward TCP data to the Internet via this peer. |
2021 | * | 1642 | * |
2022 | * @param cls closure, NULL | 1643 | * @param cls our `struct ChannelState *` |
2023 | * @param channel connection to the other end | 1644 | * @param start the actual message |
2024 | * @param channel_ctx pointer to our `struct ChannelState *` | ||
2025 | * @param message the actual message | ||
2026 | * @return #GNUNET_OK to keep the connection open, | 1645 | * @return #GNUNET_OK to keep the connection open, |
2027 | * #GNUNET_SYSERR to close it (signal serious error) | 1646 | * #GNUNET_SYSERR to close it (signal serious error) |
2028 | */ | 1647 | */ |
2029 | static int | 1648 | static int |
2030 | receive_tcp_remote (void *cls GNUNET_UNUSED, | 1649 | check_tcp_remote (void *cls, |
2031 | struct GNUNET_CADET_Channel *channel, | 1650 | const struct GNUNET_EXIT_TcpInternetStartMessage *start) |
2032 | void **channel_ctx GNUNET_UNUSED, | ||
2033 | const struct GNUNET_MessageHeader *message) | ||
2034 | { | 1651 | { |
2035 | struct ChannelState *state = *channel_ctx; | 1652 | struct ChannelState *state = cls; |
2036 | const struct GNUNET_EXIT_TcpInternetStartMessage *start; | ||
2037 | uint16_t pkt_len = ntohs (message->size); | ||
2038 | const struct in_addr *v4; | ||
2039 | const struct in6_addr *v6; | ||
2040 | const void *payload; | ||
2041 | int af; | ||
2042 | 1653 | ||
2043 | if (NULL == state) | 1654 | if (NULL == state) |
2044 | { | 1655 | { |
@@ -2050,24 +1661,6 @@ receive_tcp_remote (void *cls GNUNET_UNUSED, | |||
2050 | GNUNET_break_op (0); | 1661 | GNUNET_break_op (0); |
2051 | return GNUNET_SYSERR; | 1662 | return GNUNET_SYSERR; |
2052 | } | 1663 | } |
2053 | if (GNUNET_SYSERR == state->is_dns) | ||
2054 | { | ||
2055 | /* channel is UDP/TCP from now on */ | ||
2056 | state->is_dns = GNUNET_NO; | ||
2057 | } | ||
2058 | GNUNET_STATISTICS_update (stats, | ||
2059 | gettext_noop ("# Bytes received from CADET"), | ||
2060 | pkt_len, GNUNET_NO); | ||
2061 | GNUNET_STATISTICS_update (stats, | ||
2062 | gettext_noop ("# TCP IP-exit creation requests received via cadet"), | ||
2063 | 1, GNUNET_NO); | ||
2064 | if (pkt_len < sizeof (struct GNUNET_EXIT_TcpInternetStartMessage)) | ||
2065 | { | ||
2066 | GNUNET_break_op (0); | ||
2067 | return GNUNET_SYSERR; | ||
2068 | } | ||
2069 | start = (const struct GNUNET_EXIT_TcpInternetStartMessage*) message; | ||
2070 | pkt_len -= sizeof (struct GNUNET_EXIT_TcpInternetStartMessage); | ||
2071 | if ( (NULL != state->specifics.tcp_udp.serv) || | 1664 | if ( (NULL != state->specifics.tcp_udp.serv) || |
2072 | (NULL != state->specifics.tcp_udp.heap_node) ) | 1665 | (NULL != state->specifics.tcp_udp.heap_node) ) |
2073 | { | 1666 | { |
@@ -2079,6 +1672,38 @@ receive_tcp_remote (void *cls GNUNET_UNUSED, | |||
2079 | GNUNET_break_op (0); | 1672 | GNUNET_break_op (0); |
2080 | return GNUNET_SYSERR; | 1673 | return GNUNET_SYSERR; |
2081 | } | 1674 | } |
1675 | return GNUNET_OK; | ||
1676 | } | ||
1677 | |||
1678 | |||
1679 | /** | ||
1680 | * Process a request to forward TCP data to the Internet via this peer. | ||
1681 | * | ||
1682 | * @param cls our `struct ChannelState *` | ||
1683 | * @param start the actual message | ||
1684 | */ | ||
1685 | static void | ||
1686 | handle_tcp_remote (void *cls, | ||
1687 | const struct GNUNET_EXIT_TcpInternetStartMessage *start) | ||
1688 | { | ||
1689 | struct ChannelState *state = cls; | ||
1690 | uint16_t pkt_len = ntohs (start->header.size) - sizeof (struct GNUNET_EXIT_TcpInternetStartMessage); | ||
1691 | const struct in_addr *v4; | ||
1692 | const struct in6_addr *v6; | ||
1693 | const void *payload; | ||
1694 | int af; | ||
1695 | |||
1696 | if (GNUNET_SYSERR == state->is_dns) | ||
1697 | { | ||
1698 | /* channel is UDP/TCP from now on */ | ||
1699 | state->is_dns = GNUNET_NO; | ||
1700 | } | ||
1701 | GNUNET_STATISTICS_update (stats, | ||
1702 | gettext_noop ("# Bytes received from CADET"), | ||
1703 | pkt_len, GNUNET_NO); | ||
1704 | GNUNET_STATISTICS_update (stats, | ||
1705 | gettext_noop ("# TCP IP-exit creation requests received via cadet"), | ||
1706 | 1, GNUNET_NO); | ||
2082 | af = (int) ntohl (start->af); | 1707 | af = (int) ntohl (start->af); |
2083 | state->specifics.tcp_udp.ri.remote_address.af = af; | 1708 | state->specifics.tcp_udp.ri.remote_address.af = af; |
2084 | switch (af) | 1709 | switch (af) |
@@ -2087,12 +1712,12 @@ receive_tcp_remote (void *cls GNUNET_UNUSED, | |||
2087 | if (pkt_len < sizeof (struct in_addr)) | 1712 | if (pkt_len < sizeof (struct in_addr)) |
2088 | { | 1713 | { |
2089 | GNUNET_break_op (0); | 1714 | GNUNET_break_op (0); |
2090 | return GNUNET_SYSERR; | 1715 | return; |
2091 | } | 1716 | } |
2092 | if (! ipv4_exit) | 1717 | if (! ipv4_exit) |
2093 | { | 1718 | { |
2094 | GNUNET_break_op (0); | 1719 | GNUNET_break_op (0); |
2095 | return GNUNET_SYSERR; | 1720 | return; |
2096 | } | 1721 | } |
2097 | v4 = (const struct in_addr*) &start[1]; | 1722 | v4 = (const struct in_addr*) &start[1]; |
2098 | payload = &v4[1]; | 1723 | payload = &v4[1]; |
@@ -2103,12 +1728,12 @@ receive_tcp_remote (void *cls GNUNET_UNUSED, | |||
2103 | if (pkt_len < sizeof (struct in6_addr)) | 1728 | if (pkt_len < sizeof (struct in6_addr)) |
2104 | { | 1729 | { |
2105 | GNUNET_break_op (0); | 1730 | GNUNET_break_op (0); |
2106 | return GNUNET_SYSERR; | 1731 | return; |
2107 | } | 1732 | } |
2108 | if (! ipv6_exit) | 1733 | if (! ipv6_exit) |
2109 | { | 1734 | { |
2110 | GNUNET_break_op (0); | 1735 | GNUNET_break_op (0); |
2111 | return GNUNET_SYSERR; | 1736 | return; |
2112 | } | 1737 | } |
2113 | v6 = (const struct in6_addr*) &start[1]; | 1738 | v6 = (const struct in6_addr*) &start[1]; |
2114 | payload = &v6[1]; | 1739 | payload = &v6[1]; |
@@ -2117,7 +1742,7 @@ receive_tcp_remote (void *cls GNUNET_UNUSED, | |||
2117 | break; | 1742 | break; |
2118 | default: | 1743 | default: |
2119 | GNUNET_break_op (0); | 1744 | GNUNET_break_op (0); |
2120 | return GNUNET_SYSERR; | 1745 | return; |
2121 | } | 1746 | } |
2122 | { | 1747 | { |
2123 | char buf[INET6_ADDRSTRLEN]; | 1748 | char buf[INET6_ADDRSTRLEN]; |
@@ -2135,46 +1760,27 @@ receive_tcp_remote (void *cls GNUNET_UNUSED, | |||
2135 | send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address, | 1760 | send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address, |
2136 | &state->specifics.tcp_udp.ri.local_address, | 1761 | &state->specifics.tcp_udp.ri.local_address, |
2137 | &start->tcp_header, | 1762 | &start->tcp_header, |
2138 | payload, pkt_len); | 1763 | payload, |
2139 | GNUNET_CADET_receive_done (channel); | 1764 | pkt_len); |
2140 | return GNUNET_YES; | 1765 | GNUNET_CADET_receive_done (state->channel); |
2141 | } | 1766 | } |
2142 | 1767 | ||
2143 | 1768 | ||
2144 | /** | 1769 | /** |
2145 | * Process a request to forward TCP data on an established | 1770 | * Check a request to forward TCP data on an established |
2146 | * connection via this peer. | 1771 | * connection via this peer. |
2147 | * | 1772 | * |
2148 | * @param cls closure, NULL | 1773 | * @param cls our `struct ChannelState *` |
2149 | * @param channel connection to the other end | ||
2150 | * @param channel_ctx pointer to our `struct ChannelState *` | ||
2151 | * @param message the actual message | 1774 | * @param message the actual message |
2152 | * @return #GNUNET_OK to keep the connection open, | 1775 | * @return #GNUNET_OK to keep the connection open, |
2153 | * #GNUNET_SYSERR to close it (signal serious error) | 1776 | * #GNUNET_SYSERR to close it (signal serious error) |
2154 | */ | 1777 | */ |
2155 | static int | 1778 | static int |
2156 | receive_tcp_data (void *cls GNUNET_UNUSED, | 1779 | check_tcp_data (void *cls, |
2157 | struct GNUNET_CADET_Channel *channel, | 1780 | const struct GNUNET_EXIT_TcpDataMessage *data) |
2158 | void **channel_ctx GNUNET_UNUSED, | ||
2159 | const struct GNUNET_MessageHeader *message) | ||
2160 | { | 1781 | { |
2161 | struct ChannelState *state = *channel_ctx; | 1782 | struct ChannelState *state = cls; |
2162 | const struct GNUNET_EXIT_TcpDataMessage *data; | ||
2163 | uint16_t pkt_len = ntohs (message->size); | ||
2164 | 1783 | ||
2165 | GNUNET_STATISTICS_update (stats, | ||
2166 | gettext_noop ("# Bytes received from CADET"), | ||
2167 | pkt_len, GNUNET_NO); | ||
2168 | GNUNET_STATISTICS_update (stats, | ||
2169 | gettext_noop ("# TCP data requests received via cadet"), | ||
2170 | 1, GNUNET_NO); | ||
2171 | if (pkt_len < sizeof (struct GNUNET_EXIT_TcpDataMessage)) | ||
2172 | { | ||
2173 | GNUNET_break_op (0); | ||
2174 | return GNUNET_SYSERR; | ||
2175 | } | ||
2176 | data = (const struct GNUNET_EXIT_TcpDataMessage*) message; | ||
2177 | pkt_len -= sizeof (struct GNUNET_EXIT_TcpDataMessage); | ||
2178 | if ( (NULL == state) || | 1784 | if ( (NULL == state) || |
2179 | (NULL == state->specifics.tcp_udp.heap_node) ) | 1785 | (NULL == state->specifics.tcp_udp.heap_node) ) |
2180 | { | 1786 | { |
@@ -2195,6 +1801,30 @@ receive_tcp_data (void *cls GNUNET_UNUSED, | |||
2195 | GNUNET_break_op (0); | 1801 | GNUNET_break_op (0); |
2196 | return GNUNET_SYSERR; | 1802 | return GNUNET_SYSERR; |
2197 | } | 1803 | } |
1804 | return GNUNET_OK; | ||
1805 | } | ||
1806 | |||
1807 | |||
1808 | /** | ||
1809 | * Process a request to forward TCP data on an established | ||
1810 | * connection via this peer. | ||
1811 | * | ||
1812 | * @param cls our `struct ChannelState *` | ||
1813 | * @param message the actual message | ||
1814 | */ | ||
1815 | static void | ||
1816 | handle_tcp_data (void *cls, | ||
1817 | const struct GNUNET_EXIT_TcpDataMessage *data) | ||
1818 | { | ||
1819 | struct ChannelState *state = cls; | ||
1820 | uint16_t pkt_len = ntohs (data->header.size) - sizeof (struct GNUNET_EXIT_TcpDataMessage); | ||
1821 | |||
1822 | GNUNET_STATISTICS_update (stats, | ||
1823 | gettext_noop ("# Bytes received from CADET"), | ||
1824 | pkt_len, GNUNET_NO); | ||
1825 | GNUNET_STATISTICS_update (stats, | ||
1826 | gettext_noop ("# TCP data requests received via cadet"), | ||
1827 | 1, GNUNET_NO); | ||
2198 | if (GNUNET_SYSERR == state->is_dns) | 1828 | if (GNUNET_SYSERR == state->is_dns) |
2199 | { | 1829 | { |
2200 | /* channel is UDP/TCP from now on */ | 1830 | /* channel is UDP/TCP from now on */ |
@@ -2218,110 +1848,7 @@ receive_tcp_data (void *cls GNUNET_UNUSED, | |||
2218 | &state->specifics.tcp_udp.ri.local_address, | 1848 | &state->specifics.tcp_udp.ri.local_address, |
2219 | &data->tcp_header, | 1849 | &data->tcp_header, |
2220 | &data[1], pkt_len); | 1850 | &data[1], pkt_len); |
2221 | GNUNET_CADET_receive_done (channel); | 1851 | GNUNET_CADET_receive_done (state->channel); |
2222 | return GNUNET_YES; | ||
2223 | } | ||
2224 | |||
2225 | |||
2226 | /** | ||
2227 | * Send an ICMP packet via the TUN interface. | ||
2228 | * | ||
2229 | * @param destination_address IP to use for the ICMP packet's destination | ||
2230 | * @param source_address IP to use for the ICMP packet's source | ||
2231 | * @param icmp_header ICMP header to send | ||
2232 | * @param payload payload of the ICMP packet (does NOT include ICMP header) | ||
2233 | * @param payload_length number of bytes of data in @a payload | ||
2234 | */ | ||
2235 | static void | ||
2236 | send_icmp_packet_via_tun (const struct SocketAddress *destination_address, | ||
2237 | const struct SocketAddress *source_address, | ||
2238 | const struct GNUNET_TUN_IcmpHeader *icmp_header, | ||
2239 | const void *payload, size_t payload_length) | ||
2240 | { | ||
2241 | size_t len; | ||
2242 | struct GNUNET_TUN_IcmpHeader *icmp; | ||
2243 | |||
2244 | GNUNET_STATISTICS_update (stats, | ||
2245 | gettext_noop ("# ICMP packets sent via TUN"), | ||
2246 | 1, GNUNET_NO); | ||
2247 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2248 | "Sending packet with %u bytes ICMP payload via TUN\n", | ||
2249 | (unsigned int) payload_length); | ||
2250 | len = sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_TUN_Layer2PacketHeader); | ||
2251 | switch (destination_address->af) | ||
2252 | { | ||
2253 | case AF_INET: | ||
2254 | len += sizeof (struct GNUNET_TUN_IPv4Header); | ||
2255 | break; | ||
2256 | case AF_INET6: | ||
2257 | len += sizeof (struct GNUNET_TUN_IPv6Header); | ||
2258 | break; | ||
2259 | default: | ||
2260 | GNUNET_break (0); | ||
2261 | return; | ||
2262 | } | ||
2263 | len += sizeof (struct GNUNET_TUN_IcmpHeader); | ||
2264 | len += payload_length; | ||
2265 | if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
2266 | { | ||
2267 | GNUNET_break (0); | ||
2268 | return; | ||
2269 | } | ||
2270 | { | ||
2271 | char buf[len] GNUNET_ALIGN; | ||
2272 | struct GNUNET_MessageHeader *hdr; | ||
2273 | struct GNUNET_TUN_Layer2PacketHeader *tun; | ||
2274 | |||
2275 | hdr= (struct GNUNET_MessageHeader *) buf; | ||
2276 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
2277 | hdr->size = htons (len); | ||
2278 | tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1]; | ||
2279 | tun->flags = htons (0); | ||
2280 | switch (source_address->af) | ||
2281 | { | ||
2282 | case AF_INET: | ||
2283 | { | ||
2284 | struct GNUNET_TUN_IPv4Header * ipv4 = (struct GNUNET_TUN_IPv4Header*) &tun[1]; | ||
2285 | |||
2286 | tun->proto = htons (ETH_P_IPV4); | ||
2287 | GNUNET_TUN_initialize_ipv4_header (ipv4, | ||
2288 | IPPROTO_ICMP, | ||
2289 | sizeof (struct GNUNET_TUN_IcmpHeader) + payload_length, | ||
2290 | &source_address->address.ipv4, | ||
2291 | &destination_address->address.ipv4); | ||
2292 | icmp = (struct GNUNET_TUN_IcmpHeader*) &ipv4[1]; | ||
2293 | } | ||
2294 | break; | ||
2295 | case AF_INET6: | ||
2296 | { | ||
2297 | struct GNUNET_TUN_IPv6Header * ipv6 = (struct GNUNET_TUN_IPv6Header*) &tun[1]; | ||
2298 | |||
2299 | tun->proto = htons (ETH_P_IPV6); | ||
2300 | GNUNET_TUN_initialize_ipv6_header (ipv6, | ||
2301 | IPPROTO_ICMPV6, | ||
2302 | sizeof (struct GNUNET_TUN_IcmpHeader) + payload_length, | ||
2303 | &source_address->address.ipv6, | ||
2304 | &destination_address->address.ipv6); | ||
2305 | icmp = (struct GNUNET_TUN_IcmpHeader*) &ipv6[1]; | ||
2306 | } | ||
2307 | break; | ||
2308 | default: | ||
2309 | GNUNET_assert (0); | ||
2310 | break; | ||
2311 | } | ||
2312 | *icmp = *icmp_header; | ||
2313 | GNUNET_memcpy (&icmp[1], | ||
2314 | payload, | ||
2315 | payload_length); | ||
2316 | GNUNET_TUN_calculate_icmp_checksum (icmp, | ||
2317 | payload, | ||
2318 | payload_length); | ||
2319 | if (NULL != helper_handle) | ||
2320 | (void) GNUNET_HELPER_send (helper_handle, | ||
2321 | (const struct GNUNET_MessageHeader*) buf, | ||
2322 | GNUNET_YES, | ||
2323 | NULL, NULL); | ||
2324 | } | ||
2325 | } | 1852 | } |
2326 | 1853 | ||
2327 | 1854 | ||
@@ -2378,35 +1905,46 @@ make_up_icmpv6_payload (struct ChannelState *state, | |||
2378 | 1905 | ||
2379 | 1906 | ||
2380 | /** | 1907 | /** |
2381 | * Process a request to forward ICMP data to the Internet via this peer. | 1908 | * Check a request to forward ICMP data to the Internet via this peer. |
2382 | * | 1909 | * |
2383 | * @param cls closure, NULL | 1910 | * @param cls our `struct ChannelState *` |
2384 | * @param channel connection to the other end | 1911 | * @param msg the actual message |
2385 | * @param channel_ctx pointer to our 'struct ChannelState *' | ||
2386 | * @param message the actual message | ||
2387 | * @return #GNUNET_OK to keep the connection open, | 1912 | * @return #GNUNET_OK to keep the connection open, |
2388 | * #GNUNET_SYSERR to close it (signal serious error) | 1913 | * #GNUNET_SYSERR to close it (signal serious error) |
2389 | */ | 1914 | */ |
2390 | static int | 1915 | static int |
2391 | receive_icmp_remote (void *cls, | 1916 | check_icmp_remote (void *cls, |
2392 | struct GNUNET_CADET_Channel *channel, | 1917 | const struct GNUNET_EXIT_IcmpInternetMessage *msg) |
2393 | void **channel_ctx, | ||
2394 | const struct GNUNET_MessageHeader *message) | ||
2395 | { | 1918 | { |
2396 | struct ChannelState *state = *channel_ctx; | 1919 | struct ChannelState *state = cls; |
2397 | const struct GNUNET_EXIT_IcmpInternetMessage *msg; | ||
2398 | uint16_t pkt_len = ntohs (message->size); | ||
2399 | const struct in_addr *v4; | ||
2400 | const struct in6_addr *v6; | ||
2401 | const void *payload; | ||
2402 | char buf[sizeof (struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN; | ||
2403 | int af; | ||
2404 | 1920 | ||
2405 | if (GNUNET_YES == state->is_dns) | 1921 | if (GNUNET_YES == state->is_dns) |
2406 | { | 1922 | { |
2407 | GNUNET_break_op (0); | 1923 | GNUNET_break_op (0); |
2408 | return GNUNET_SYSERR; | 1924 | return GNUNET_SYSERR; |
2409 | } | 1925 | } |
1926 | return GNUNET_OK; | ||
1927 | } | ||
1928 | |||
1929 | |||
1930 | /** | ||
1931 | * Process a request to forward ICMP data to the Internet via this peer. | ||
1932 | * | ||
1933 | * @param cls our `struct ChannelState *` | ||
1934 | * @param msg the actual message | ||
1935 | */ | ||
1936 | static void | ||
1937 | handle_icmp_remote (void *cls, | ||
1938 | const struct GNUNET_EXIT_IcmpInternetMessage *msg) | ||
1939 | { | ||
1940 | struct ChannelState *state = cls; | ||
1941 | uint16_t pkt_len = ntohs (msg->header.size) - sizeof (struct GNUNET_EXIT_IcmpInternetMessage); | ||
1942 | const struct in_addr *v4; | ||
1943 | const struct in6_addr *v6; | ||
1944 | const void *payload; | ||
1945 | char buf[sizeof (struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN; | ||
1946 | int af; | ||
1947 | |||
2410 | if (GNUNET_SYSERR == state->is_dns) | 1948 | if (GNUNET_SYSERR == state->is_dns) |
2411 | { | 1949 | { |
2412 | /* channel is UDP/TCP from now on */ | 1950 | /* channel is UDP/TCP from now on */ |
@@ -2418,13 +1956,6 @@ receive_icmp_remote (void *cls, | |||
2418 | GNUNET_STATISTICS_update (stats, | 1956 | GNUNET_STATISTICS_update (stats, |
2419 | gettext_noop ("# ICMP IP-exit requests received via cadet"), | 1957 | gettext_noop ("# ICMP IP-exit requests received via cadet"), |
2420 | 1, GNUNET_NO); | 1958 | 1, GNUNET_NO); |
2421 | if (pkt_len < sizeof (struct GNUNET_EXIT_IcmpInternetMessage)) | ||
2422 | { | ||
2423 | GNUNET_break_op (0); | ||
2424 | return GNUNET_SYSERR; | ||
2425 | } | ||
2426 | msg = (const struct GNUNET_EXIT_IcmpInternetMessage*) message; | ||
2427 | pkt_len -= sizeof (struct GNUNET_EXIT_IcmpInternetMessage); | ||
2428 | 1959 | ||
2429 | af = (int) ntohl (msg->af); | 1960 | af = (int) ntohl (msg->af); |
2430 | if ( (NULL != state->specifics.tcp_udp.heap_node) && | 1961 | if ( (NULL != state->specifics.tcp_udp.heap_node) && |
@@ -2432,7 +1963,7 @@ receive_icmp_remote (void *cls, | |||
2432 | { | 1963 | { |
2433 | /* other peer switched AF on this channel; not allowed */ | 1964 | /* other peer switched AF on this channel; not allowed */ |
2434 | GNUNET_break_op (0); | 1965 | GNUNET_break_op (0); |
2435 | return GNUNET_SYSERR; | 1966 | return; |
2436 | } | 1967 | } |
2437 | 1968 | ||
2438 | switch (af) | 1969 | switch (af) |
@@ -2441,12 +1972,12 @@ receive_icmp_remote (void *cls, | |||
2441 | if (pkt_len < sizeof (struct in_addr)) | 1972 | if (pkt_len < sizeof (struct in_addr)) |
2442 | { | 1973 | { |
2443 | GNUNET_break_op (0); | 1974 | GNUNET_break_op (0); |
2444 | return GNUNET_SYSERR; | 1975 | return; |
2445 | } | 1976 | } |
2446 | if (! ipv4_exit) | 1977 | if (! ipv4_exit) |
2447 | { | 1978 | { |
2448 | GNUNET_break_op (0); | 1979 | GNUNET_break_op (0); |
2449 | return GNUNET_SYSERR; | 1980 | return; |
2450 | } | 1981 | } |
2451 | v4 = (const struct in_addr*) &msg[1]; | 1982 | v4 = (const struct in_addr*) &msg[1]; |
2452 | payload = &v4[1]; | 1983 | payload = &v4[1]; |
@@ -2471,7 +2002,7 @@ receive_icmp_remote (void *cls, | |||
2471 | if (0 != pkt_len) | 2002 | if (0 != pkt_len) |
2472 | { | 2003 | { |
2473 | GNUNET_break_op (0); | 2004 | GNUNET_break_op (0); |
2474 | return GNUNET_SYSERR; | 2005 | return; |
2475 | } | 2006 | } |
2476 | /* make up payload */ | 2007 | /* make up payload */ |
2477 | { | 2008 | { |
@@ -2491,7 +2022,7 @@ receive_icmp_remote (void *cls, | |||
2491 | GNUNET_STATISTICS_update (stats, | 2022 | GNUNET_STATISTICS_update (stats, |
2492 | gettext_noop ("# ICMPv4 packets dropped (type not allowed)"), | 2023 | gettext_noop ("# ICMPv4 packets dropped (type not allowed)"), |
2493 | 1, GNUNET_NO); | 2024 | 1, GNUNET_NO); |
2494 | return GNUNET_SYSERR; | 2025 | return; |
2495 | } | 2026 | } |
2496 | /* end AF_INET */ | 2027 | /* end AF_INET */ |
2497 | break; | 2028 | break; |
@@ -2499,12 +2030,12 @@ receive_icmp_remote (void *cls, | |||
2499 | if (pkt_len < sizeof (struct in6_addr)) | 2030 | if (pkt_len < sizeof (struct in6_addr)) |
2500 | { | 2031 | { |
2501 | GNUNET_break_op (0); | 2032 | GNUNET_break_op (0); |
2502 | return GNUNET_SYSERR; | 2033 | return; |
2503 | } | 2034 | } |
2504 | if (! ipv6_exit) | 2035 | if (! ipv6_exit) |
2505 | { | 2036 | { |
2506 | GNUNET_break_op (0); | 2037 | GNUNET_break_op (0); |
2507 | return GNUNET_SYSERR; | 2038 | return; |
2508 | } | 2039 | } |
2509 | v6 = (const struct in6_addr*) &msg[1]; | 2040 | v6 = (const struct in6_addr*) &msg[1]; |
2510 | payload = &v6[1]; | 2041 | payload = &v6[1]; |
@@ -2530,7 +2061,7 @@ receive_icmp_remote (void *cls, | |||
2530 | if (0 != pkt_len) | 2061 | if (0 != pkt_len) |
2531 | { | 2062 | { |
2532 | GNUNET_break_op (0); | 2063 | GNUNET_break_op (0); |
2533 | return GNUNET_SYSERR; | 2064 | return; |
2534 | } | 2065 | } |
2535 | /* make up payload */ | 2066 | /* make up payload */ |
2536 | { | 2067 | { |
@@ -2550,14 +2081,14 @@ receive_icmp_remote (void *cls, | |||
2550 | GNUNET_STATISTICS_update (stats, | 2081 | GNUNET_STATISTICS_update (stats, |
2551 | gettext_noop ("# ICMPv6 packets dropped (type not allowed)"), | 2082 | gettext_noop ("# ICMPv6 packets dropped (type not allowed)"), |
2552 | 1, GNUNET_NO); | 2083 | 1, GNUNET_NO); |
2553 | return GNUNET_SYSERR; | 2084 | return; |
2554 | } | 2085 | } |
2555 | /* end AF_INET6 */ | 2086 | /* end AF_INET6 */ |
2556 | break; | 2087 | break; |
2557 | default: | 2088 | default: |
2558 | /* bad AF */ | 2089 | /* bad AF */ |
2559 | GNUNET_break_op (0); | 2090 | GNUNET_break_op (0); |
2560 | return GNUNET_SYSERR; | 2091 | return; |
2561 | } | 2092 | } |
2562 | 2093 | ||
2563 | { | 2094 | { |
@@ -2573,8 +2104,7 @@ receive_icmp_remote (void *cls, | |||
2573 | &state->specifics.tcp_udp.ri.local_address, | 2104 | &state->specifics.tcp_udp.ri.local_address, |
2574 | &msg->icmp_header, | 2105 | &msg->icmp_header, |
2575 | payload, pkt_len); | 2106 | payload, pkt_len); |
2576 | GNUNET_CADET_receive_done (channel); | 2107 | GNUNET_CADET_receive_done (state->channel); |
2577 | return GNUNET_YES; | ||
2578 | } | 2108 | } |
2579 | 2109 | ||
2580 | 2110 | ||
@@ -2629,28 +2159,19 @@ make_up_icmp_service_payload (struct ChannelState *state, | |||
2629 | 2159 | ||
2630 | 2160 | ||
2631 | /** | 2161 | /** |
2632 | * Process a request via cadet to send ICMP data to a service | 2162 | * Check a request via cadet to send ICMP data to a service |
2633 | * offered by this system. | 2163 | * offered by this system. |
2634 | * | 2164 | * |
2635 | * @param cls closure, NULL | 2165 | * @param cls our `struct ChannelState *` |
2636 | * @param channel connection to the other end | 2166 | * @param msg the actual message |
2637 | * @param channel_ctx pointer to our 'struct ChannelState *' | ||
2638 | * @param message the actual message | ||
2639 | * @return #GNUNET_OK to keep the connection open, | 2167 | * @return #GNUNET_OK to keep the connection open, |
2640 | * #GNUNET_SYSERR to close it (signal serious error) | 2168 | * #GNUNET_SYSERR to close it (signal serious error) |
2641 | */ | 2169 | */ |
2642 | static int | 2170 | static int |
2643 | receive_icmp_service (void *cls, | 2171 | check_icmp_service (void *cls, |
2644 | struct GNUNET_CADET_Channel *channel, | 2172 | const struct GNUNET_EXIT_IcmpServiceMessage *msg) |
2645 | void **channel_ctx, | ||
2646 | const struct GNUNET_MessageHeader *message) | ||
2647 | { | 2173 | { |
2648 | struct ChannelState *state = *channel_ctx; | 2174 | struct ChannelState *state = cls; |
2649 | const struct GNUNET_EXIT_IcmpServiceMessage *msg; | ||
2650 | uint16_t pkt_len = ntohs (message->size); | ||
2651 | struct GNUNET_TUN_IcmpHeader icmp; | ||
2652 | char buf[sizeof (struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN; | ||
2653 | const void *payload; | ||
2654 | 2175 | ||
2655 | if (GNUNET_YES == state->is_dns) | 2176 | if (GNUNET_YES == state->is_dns) |
2656 | { | 2177 | { |
@@ -2662,6 +2183,27 @@ receive_icmp_service (void *cls, | |||
2662 | GNUNET_break_op (0); | 2183 | GNUNET_break_op (0); |
2663 | return GNUNET_SYSERR; | 2184 | return GNUNET_SYSERR; |
2664 | } | 2185 | } |
2186 | return GNUNET_OK; | ||
2187 | } | ||
2188 | |||
2189 | |||
2190 | /** | ||
2191 | * Process a request via cadet to send ICMP data to a service | ||
2192 | * offered by this system. | ||
2193 | * | ||
2194 | * @param cls our `struct ChannelState *` | ||
2195 | * @param msg the actual message | ||
2196 | */ | ||
2197 | static void | ||
2198 | handle_icmp_service (void *cls, | ||
2199 | const struct GNUNET_EXIT_IcmpServiceMessage *msg) | ||
2200 | { | ||
2201 | struct ChannelState *state = cls; | ||
2202 | uint16_t pkt_len = ntohs (msg->header.size) - sizeof (struct GNUNET_EXIT_IcmpServiceMessage); | ||
2203 | struct GNUNET_TUN_IcmpHeader icmp; | ||
2204 | char buf[sizeof (struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN; | ||
2205 | const void *payload; | ||
2206 | |||
2665 | GNUNET_STATISTICS_update (stats, | 2207 | GNUNET_STATISTICS_update (stats, |
2666 | gettext_noop ("# Bytes received from CADET"), | 2208 | gettext_noop ("# Bytes received from CADET"), |
2667 | pkt_len, GNUNET_NO); | 2209 | pkt_len, GNUNET_NO); |
@@ -2669,13 +2211,6 @@ receive_icmp_service (void *cls, | |||
2669 | gettext_noop ("# ICMP service requests received via cadet"), | 2211 | gettext_noop ("# ICMP service requests received via cadet"), |
2670 | 1, GNUNET_NO); | 2212 | 1, GNUNET_NO); |
2671 | /* check that we got at least a valid header */ | 2213 | /* check that we got at least a valid header */ |
2672 | if (pkt_len < sizeof (struct GNUNET_EXIT_IcmpServiceMessage)) | ||
2673 | { | ||
2674 | GNUNET_break_op (0); | ||
2675 | return GNUNET_SYSERR; | ||
2676 | } | ||
2677 | msg = (const struct GNUNET_EXIT_IcmpServiceMessage*) message; | ||
2678 | pkt_len -= sizeof (struct GNUNET_EXIT_IcmpServiceMessage); | ||
2679 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2214 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2680 | "Received data from %s for forwarding to ICMP service %s\n", | 2215 | "Received data from %s for forwarding to ICMP service %s\n", |
2681 | GNUNET_i2s (&state->peer), | 2216 | GNUNET_i2s (&state->peer), |
@@ -2707,7 +2242,7 @@ receive_icmp_service (void *cls, | |||
2707 | if (0 != pkt_len) | 2242 | if (0 != pkt_len) |
2708 | { | 2243 | { |
2709 | GNUNET_break_op (0); | 2244 | GNUNET_break_op (0); |
2710 | return GNUNET_SYSERR; | 2245 | return; |
2711 | } | 2246 | } |
2712 | payload = buf; | 2247 | payload = buf; |
2713 | pkt_len = make_up_icmp_service_payload (state, buf); | 2248 | pkt_len = make_up_icmp_service_payload (state, buf); |
@@ -2718,7 +2253,7 @@ receive_icmp_service (void *cls, | |||
2718 | if (0 != pkt_len) | 2253 | if (0 != pkt_len) |
2719 | { | 2254 | { |
2720 | GNUNET_break_op (0); | 2255 | GNUNET_break_op (0); |
2721 | return GNUNET_SYSERR; | 2256 | return; |
2722 | } | 2257 | } |
2723 | payload = buf; | 2258 | payload = buf; |
2724 | pkt_len = make_up_icmp_service_payload (state, buf); | 2259 | pkt_len = make_up_icmp_service_payload (state, buf); |
@@ -2729,12 +2264,12 @@ receive_icmp_service (void *cls, | |||
2729 | GNUNET_STATISTICS_update (stats, | 2264 | GNUNET_STATISTICS_update (stats, |
2730 | gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"), | 2265 | gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"), |
2731 | 1, GNUNET_NO); | 2266 | 1, GNUNET_NO); |
2732 | return GNUNET_OK; | 2267 | return; |
2733 | } | 2268 | } |
2734 | if (0 != pkt_len) | 2269 | if (0 != pkt_len) |
2735 | { | 2270 | { |
2736 | GNUNET_break_op (0); | 2271 | GNUNET_break_op (0); |
2737 | return GNUNET_SYSERR; | 2272 | return; |
2738 | } | 2273 | } |
2739 | payload = buf; | 2274 | payload = buf; |
2740 | pkt_len = make_up_icmp_service_payload (state, buf); | 2275 | pkt_len = make_up_icmp_service_payload (state, buf); |
@@ -2744,7 +2279,7 @@ receive_icmp_service (void *cls, | |||
2744 | GNUNET_STATISTICS_update (stats, | 2279 | GNUNET_STATISTICS_update (stats, |
2745 | gettext_noop ("# ICMPv4 packets dropped (type not allowed)"), | 2280 | gettext_noop ("# ICMPv4 packets dropped (type not allowed)"), |
2746 | 1, GNUNET_NO); | 2281 | 1, GNUNET_NO); |
2747 | return GNUNET_SYSERR; | 2282 | return; |
2748 | } | 2283 | } |
2749 | /* end of AF_INET */ | 2284 | /* end of AF_INET */ |
2750 | break; | 2285 | break; |
@@ -2765,7 +2300,7 @@ receive_icmp_service (void *cls, | |||
2765 | if (0 != pkt_len) | 2300 | if (0 != pkt_len) |
2766 | { | 2301 | { |
2767 | GNUNET_break_op (0); | 2302 | GNUNET_break_op (0); |
2768 | return GNUNET_SYSERR; | 2303 | return; |
2769 | } | 2304 | } |
2770 | payload = buf; | 2305 | payload = buf; |
2771 | pkt_len = make_up_icmp_service_payload (state, buf); | 2306 | pkt_len = make_up_icmp_service_payload (state, buf); |
@@ -2776,7 +2311,7 @@ receive_icmp_service (void *cls, | |||
2776 | if (0 != pkt_len) | 2311 | if (0 != pkt_len) |
2777 | { | 2312 | { |
2778 | GNUNET_break_op (0); | 2313 | GNUNET_break_op (0); |
2779 | return GNUNET_SYSERR; | 2314 | return; |
2780 | } | 2315 | } |
2781 | payload = buf; | 2316 | payload = buf; |
2782 | pkt_len = make_up_icmp_service_payload (state, buf); | 2317 | pkt_len = make_up_icmp_service_payload (state, buf); |
@@ -2788,12 +2323,12 @@ receive_icmp_service (void *cls, | |||
2788 | GNUNET_STATISTICS_update (stats, | 2323 | GNUNET_STATISTICS_update (stats, |
2789 | gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"), | 2324 | gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"), |
2790 | 1, GNUNET_NO); | 2325 | 1, GNUNET_NO); |
2791 | return GNUNET_OK; | 2326 | return; |
2792 | } | 2327 | } |
2793 | if (0 != pkt_len) | 2328 | if (0 != pkt_len) |
2794 | { | 2329 | { |
2795 | GNUNET_break_op (0); | 2330 | GNUNET_break_op (0); |
2796 | return GNUNET_SYSERR; | 2331 | return; |
2797 | } | 2332 | } |
2798 | payload = buf; | 2333 | payload = buf; |
2799 | pkt_len = make_up_icmp_service_payload (state, buf); | 2334 | pkt_len = make_up_icmp_service_payload (state, buf); |
@@ -2803,283 +2338,715 @@ receive_icmp_service (void *cls, | |||
2803 | GNUNET_STATISTICS_update (stats, | 2338 | GNUNET_STATISTICS_update (stats, |
2804 | gettext_noop ("# ICMPv6 packets dropped (type not allowed)"), | 2339 | gettext_noop ("# ICMPv6 packets dropped (type not allowed)"), |
2805 | 1, GNUNET_NO); | 2340 | 1, GNUNET_NO); |
2806 | return GNUNET_SYSERR; | 2341 | return; |
2807 | } | 2342 | } |
2808 | /* end of AF_INET6 */ | 2343 | /* end of AF_INET6 */ |
2809 | break; | 2344 | break; |
2810 | default: | 2345 | default: |
2811 | GNUNET_break_op (0); | 2346 | GNUNET_break_op (0); |
2812 | return GNUNET_SYSERR; | 2347 | return; |
2813 | } | 2348 | } |
2814 | 2349 | ||
2815 | send_icmp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address, | 2350 | send_icmp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address, |
2816 | &state->specifics.tcp_udp.ri.local_address, | 2351 | &state->specifics.tcp_udp.ri.local_address, |
2817 | &icmp, | 2352 | &icmp, |
2818 | payload, pkt_len); | 2353 | payload, |
2819 | GNUNET_CADET_receive_done (channel); | 2354 | pkt_len); |
2820 | return GNUNET_YES; | 2355 | GNUNET_CADET_receive_done (state->channel); |
2821 | } | 2356 | } |
2822 | 2357 | ||
2823 | 2358 | ||
2824 | /** | 2359 | /** |
2825 | * Send a UDP packet via the TUN interface. | 2360 | * Free memory associated with a service record. |
2826 | * | 2361 | * |
2827 | * @param destination_address IP and port to use for the UDP packet's destination | 2362 | * @param cls unused |
2828 | * @param source_address IP and port to use for the UDP packet's source | 2363 | * @param key service descriptor |
2829 | * @param payload payload of the UDP packet (does NOT include UDP header) | 2364 | * @param value service record to free |
2830 | * @param payload_length number of bytes of data in @a payload | 2365 | * @return #GNUNET_OK |
2831 | */ | 2366 | */ |
2832 | static void | 2367 | static int |
2833 | send_udp_packet_via_tun (const struct SocketAddress *destination_address, | 2368 | free_service_record (void *cls, |
2834 | const struct SocketAddress *source_address, | 2369 | const struct GNUNET_HashCode *key, |
2835 | const void *payload, size_t payload_length) | 2370 | void *value) |
2836 | { | 2371 | { |
2837 | size_t len; | 2372 | struct LocalService *service = value; |
2373 | |||
2374 | GNUNET_assert (GNUNET_YES == | ||
2375 | GNUNET_CONTAINER_multihashmap_remove (services, | ||
2376 | key, | ||
2377 | service)); | ||
2378 | GNUNET_CADET_close_port (service->port); | ||
2379 | GNUNET_free_non_null (service->name); | ||
2380 | GNUNET_free (service); | ||
2381 | return GNUNET_OK; | ||
2382 | } | ||
2838 | 2383 | ||
2384 | |||
2385 | /** | ||
2386 | * Callback from CADET for new channels. | ||
2387 | * | ||
2388 | * @param cls closure | ||
2389 | * @param channel new handle to the channel | ||
2390 | * @param initiator peer that started the channel | ||
2391 | * @return initial channel context for the channel | ||
2392 | */ | ||
2393 | static void * | ||
2394 | new_service_channel (void *cls, | ||
2395 | struct GNUNET_CADET_Channel *channel, | ||
2396 | const struct GNUNET_PeerIdentity *initiator) | ||
2397 | { | ||
2398 | struct LocalService *ls = cls; | ||
2399 | struct ChannelState *s = GNUNET_new (struct ChannelState); | ||
2400 | |||
2401 | s->peer = *initiator; | ||
2839 | GNUNET_STATISTICS_update (stats, | 2402 | GNUNET_STATISTICS_update (stats, |
2840 | gettext_noop ("# UDP packets sent via TUN"), | 2403 | gettext_noop ("# Inbound CADET channels created"), |
2841 | 1, GNUNET_NO); | 2404 | 1, |
2405 | GNUNET_NO); | ||
2842 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2406 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2843 | "Sending packet with %u bytes UDP payload via TUN\n", | 2407 | "Received inbound channel from `%s'\n", |
2844 | (unsigned int) payload_length); | 2408 | GNUNET_i2s (initiator)); |
2845 | len = sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_TUN_Layer2PacketHeader); | 2409 | s->channel = channel; |
2846 | switch (source_address->af) | 2410 | s->specifics.tcp_udp.serv = ls; |
2411 | s->specifics.tcp_udp.ri.remote_address = ls->address; | ||
2412 | return s; | ||
2413 | } | ||
2414 | |||
2415 | |||
2416 | /** | ||
2417 | * Function called by cadet whenever an inbound channel is destroyed. | ||
2418 | * Should clean up any associated state. | ||
2419 | * | ||
2420 | * @param cls our `struct ChannelState *` | ||
2421 | * @param channel connection to the other end (henceforth invalid) | ||
2422 | */ | ||
2423 | static void | ||
2424 | clean_channel (void *cls, | ||
2425 | const struct GNUNET_CADET_Channel *channel) | ||
2426 | { | ||
2427 | struct ChannelState *s = cls; | ||
2428 | |||
2429 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2430 | "Channel destroyed\n"); | ||
2431 | if (GNUNET_SYSERR == s->is_dns) | ||
2847 | { | 2432 | { |
2848 | case AF_INET: | 2433 | GNUNET_free (s); |
2849 | len += sizeof (struct GNUNET_TUN_IPv4Header); | ||
2850 | break; | ||
2851 | case AF_INET6: | ||
2852 | len += sizeof (struct GNUNET_TUN_IPv6Header); | ||
2853 | break; | ||
2854 | default: | ||
2855 | GNUNET_break (0); | ||
2856 | return; | 2434 | return; |
2857 | } | 2435 | } |
2858 | len += sizeof (struct GNUNET_TUN_UdpHeader); | 2436 | if (GNUNET_YES == s->is_dns) |
2859 | len += payload_length; | ||
2860 | if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
2861 | { | 2437 | { |
2862 | GNUNET_break (0); | 2438 | if (channels[s->specifics.dns.my_id] == s) |
2863 | return; | 2439 | channels[s->specifics.dns.my_id] = NULL; |
2864 | } | 2440 | } |
2441 | else | ||
2865 | { | 2442 | { |
2866 | char buf[len] GNUNET_ALIGN; | 2443 | if (NULL != s->specifics.tcp_udp.heap_node) |
2867 | struct GNUNET_MessageHeader *hdr; | ||
2868 | struct GNUNET_TUN_Layer2PacketHeader *tun; | ||
2869 | |||
2870 | hdr= (struct GNUNET_MessageHeader *) buf; | ||
2871 | hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
2872 | hdr->size = htons (len); | ||
2873 | tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1]; | ||
2874 | tun->flags = htons (0); | ||
2875 | switch (source_address->af) | ||
2876 | { | 2444 | { |
2877 | case AF_INET: | 2445 | GNUNET_assert (GNUNET_YES == |
2878 | { | 2446 | GNUNET_CONTAINER_multihashmap_remove (connections_map, |
2879 | struct GNUNET_TUN_IPv4Header * ipv4 = (struct GNUNET_TUN_IPv4Header*) &tun[1]; | 2447 | &s->specifics.tcp_udp.state_key, |
2880 | 2448 | s)); | |
2881 | tun->proto = htons (ETH_P_IPV4); | 2449 | GNUNET_CONTAINER_heap_remove_node (s->specifics.tcp_udp.heap_node); |
2882 | prepare_ipv4_packet (payload, | 2450 | s->specifics.tcp_udp.heap_node = NULL; |
2883 | payload_length, | ||
2884 | IPPROTO_UDP, | ||
2885 | NULL, | ||
2886 | source_address, | ||
2887 | destination_address, | ||
2888 | ipv4); | ||
2889 | } | ||
2890 | break; | ||
2891 | case AF_INET6: | ||
2892 | { | ||
2893 | struct GNUNET_TUN_IPv6Header * ipv6 = (struct GNUNET_TUN_IPv6Header*) &tun[1]; | ||
2894 | |||
2895 | tun->proto = htons (ETH_P_IPV6); | ||
2896 | prepare_ipv6_packet (payload, | ||
2897 | payload_length, | ||
2898 | IPPROTO_UDP, | ||
2899 | NULL, | ||
2900 | source_address, | ||
2901 | destination_address, | ||
2902 | ipv6); | ||
2903 | } | ||
2904 | break; | ||
2905 | default: | ||
2906 | GNUNET_assert (0); | ||
2907 | break; | ||
2908 | } | 2451 | } |
2909 | if (NULL != helper_handle) | ||
2910 | (void) GNUNET_HELPER_send (helper_handle, | ||
2911 | (const struct GNUNET_MessageHeader*) buf, | ||
2912 | GNUNET_YES, | ||
2913 | NULL, NULL); | ||
2914 | } | 2452 | } |
2453 | GNUNET_free (s); | ||
2915 | } | 2454 | } |
2916 | 2455 | ||
2917 | 2456 | ||
2918 | /** | 2457 | /** |
2919 | * Process a request to forward UDP data to the Internet via this peer. | 2458 | * Given a service descriptor and a destination port, find the |
2459 | * respective service entry. | ||
2920 | * | 2460 | * |
2921 | * @param cls closure, NULL | 2461 | * @param proto IPPROTO_TCP or IPPROTO_UDP |
2922 | * @param channel connection to the other end | 2462 | * @param name name of the service |
2923 | * @param channel_ctx pointer to our 'struct ChannelState *' | 2463 | * @param destination_port destination port |
2924 | * @param message the actual message | 2464 | * @param service service information record to store (service->name will be set). |
2925 | * @return #GNUNET_OK to keep the connection open, | ||
2926 | * #GNUNET_SYSERR to close it (signal serious error) | ||
2927 | */ | 2465 | */ |
2928 | static int | 2466 | static void |
2929 | receive_udp_remote (void *cls, | 2467 | store_service (int proto, |
2930 | struct GNUNET_CADET_Channel *channel, | 2468 | const char *name, |
2931 | void **channel_ctx, | 2469 | uint16_t destination_port, |
2932 | const struct GNUNET_MessageHeader *message) | 2470 | struct LocalService *service) |
2933 | { | 2471 | { |
2934 | struct ChannelState *state = *channel_ctx; | 2472 | struct GNUNET_MQ_MessageHandler handlers[] = { |
2935 | const struct GNUNET_EXIT_UdpInternetMessage *msg; | 2473 | GNUNET_MQ_hd_var_size (icmp_service, |
2936 | uint16_t pkt_len = ntohs (message->size); | 2474 | GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_SERVICE, |
2937 | const struct in_addr *v4; | 2475 | struct GNUNET_EXIT_IcmpServiceMessage, |
2938 | const struct in6_addr *v6; | 2476 | service), |
2939 | const void *payload; | 2477 | GNUNET_MQ_hd_var_size (udp_service, |
2940 | int af; | 2478 | GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE, |
2479 | struct GNUNET_EXIT_UdpServiceMessage, | ||
2480 | service), | ||
2481 | GNUNET_MQ_hd_var_size (tcp_service, | ||
2482 | GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START, | ||
2483 | struct GNUNET_EXIT_TcpServiceStartMessage, | ||
2484 | service), | ||
2485 | GNUNET_MQ_hd_var_size (tcp_data, | ||
2486 | GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT, | ||
2487 | struct GNUNET_EXIT_TcpDataMessage, | ||
2488 | service), | ||
2489 | GNUNET_MQ_handler_end () | ||
2490 | }; | ||
2941 | 2491 | ||
2942 | if (GNUNET_YES == state->is_dns) | 2492 | struct GNUNET_HashCode cadet_port; |
2493 | |||
2494 | service->name = GNUNET_strdup (name); | ||
2495 | GNUNET_TUN_service_name_to_hash (name, | ||
2496 | &service->descriptor); | ||
2497 | GNUNET_TUN_compute_service_cadet_port (&service->descriptor, | ||
2498 | destination_port, | ||
2499 | &cadet_port); | ||
2500 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2501 | "Opening CADET port %s for SERVICE exit %s on port %u\n", | ||
2502 | GNUNET_h2s (&cadet_port), | ||
2503 | name, | ||
2504 | (unsigned int) destination_port); | ||
2505 | service->port = GNUNET_CADET_open_porT (cadet_handle, | ||
2506 | &cadet_port, | ||
2507 | &new_service_channel, | ||
2508 | service, | ||
2509 | NULL, | ||
2510 | &clean_channel, | ||
2511 | handlers); | ||
2512 | service->is_udp = (IPPROTO_UDP == proto); | ||
2513 | if (GNUNET_OK != | ||
2514 | GNUNET_CONTAINER_multihashmap_put (services, | ||
2515 | &cadet_port, | ||
2516 | service, | ||
2517 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) | ||
2943 | { | 2518 | { |
2944 | GNUNET_break_op (0); | 2519 | GNUNET_CADET_close_port (service->port); |
2945 | return GNUNET_SYSERR; | 2520 | GNUNET_free_non_null (service->name); |
2521 | GNUNET_free (service); | ||
2522 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
2523 | _("Got duplicate service records for `%s:%u'\n"), | ||
2524 | name, | ||
2525 | (unsigned int) destination_port); | ||
2946 | } | 2526 | } |
2947 | if (GNUNET_SYSERR == state->is_dns) | 2527 | } |
2528 | |||
2529 | |||
2530 | /** | ||
2531 | * Send the given packet via the cadet channel. | ||
2532 | * | ||
2533 | * @param s channel destination | ||
2534 | * @param env message to queue | ||
2535 | */ | ||
2536 | static void | ||
2537 | send_packet_to_cadet_channel (struct ChannelState *s, | ||
2538 | struct GNUNET_MQ_Envelope *env) | ||
2539 | { | ||
2540 | GNUNET_assert (NULL != s); | ||
2541 | GNUNET_STATISTICS_update (stats, | ||
2542 | gettext_noop ("# Messages transmitted via cadet channels"), | ||
2543 | 1, | ||
2544 | GNUNET_NO); | ||
2545 | GNUNET_MQ_send (GNUNET_CADET_get_mq (s->channel), | ||
2546 | env); | ||
2547 | } | ||
2548 | |||
2549 | |||
2550 | /** | ||
2551 | * @brief Handles an ICMP packet received from the helper. | ||
2552 | * | ||
2553 | * @param icmp A pointer to the Packet | ||
2554 | * @param pktlen number of bytes in @a icmp | ||
2555 | * @param af address family (AFINET or AF_INET6) | ||
2556 | * @param destination_ip destination IP-address of the IP packet (should | ||
2557 | * be our local address) | ||
2558 | * @param source_ip original source IP-address of the IP packet (should | ||
2559 | * be the original destination address) | ||
2560 | */ | ||
2561 | static void | ||
2562 | icmp_from_helper (const struct GNUNET_TUN_IcmpHeader *icmp, | ||
2563 | size_t pktlen, | ||
2564 | int af, | ||
2565 | const void *destination_ip, | ||
2566 | const void *source_ip) | ||
2567 | { | ||
2568 | struct ChannelState *state; | ||
2569 | struct GNUNET_MQ_Envelope *env; | ||
2570 | struct GNUNET_EXIT_IcmpToVPNMessage *i2v; | ||
2571 | const struct GNUNET_TUN_IPv4Header *ipv4; | ||
2572 | const struct GNUNET_TUN_IPv6Header *ipv6; | ||
2573 | const struct GNUNET_TUN_UdpHeader *udp; | ||
2574 | uint16_t source_port; | ||
2575 | uint16_t destination_port; | ||
2576 | uint8_t protocol; | ||
2577 | |||
2948 | { | 2578 | { |
2949 | /* channel is UDP/TCP from now on */ | 2579 | char sbuf[INET6_ADDRSTRLEN]; |
2950 | state->is_dns = GNUNET_NO; | 2580 | char dbuf[INET6_ADDRSTRLEN]; |
2581 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2582 | "Received ICMP packet going from %s to %s\n", | ||
2583 | inet_ntop (af, | ||
2584 | source_ip, | ||
2585 | sbuf, sizeof (sbuf)), | ||
2586 | inet_ntop (af, | ||
2587 | destination_ip, | ||
2588 | dbuf, sizeof (dbuf))); | ||
2951 | } | 2589 | } |
2952 | GNUNET_STATISTICS_update (stats, | 2590 | if (pktlen < sizeof (struct GNUNET_TUN_IcmpHeader)) |
2953 | gettext_noop ("# Bytes received from CADET"), | ||
2954 | pkt_len, GNUNET_NO); | ||
2955 | GNUNET_STATISTICS_update (stats, | ||
2956 | gettext_noop ("# UDP IP-exit requests received via cadet"), | ||
2957 | 1, GNUNET_NO); | ||
2958 | if (pkt_len < sizeof (struct GNUNET_EXIT_UdpInternetMessage)) | ||
2959 | { | 2591 | { |
2960 | GNUNET_break_op (0); | 2592 | /* blame kernel */ |
2961 | return GNUNET_SYSERR; | 2593 | GNUNET_break (0); |
2594 | return; | ||
2962 | } | 2595 | } |
2963 | msg = (const struct GNUNET_EXIT_UdpInternetMessage*) message; | 2596 | |
2964 | pkt_len -= sizeof (struct GNUNET_EXIT_UdpInternetMessage); | 2597 | /* Find out if this is an ICMP packet in response to an existing |
2965 | af = (int) ntohl (msg->af); | 2598 | TCP/UDP packet and if so, figure out ports / protocol of the |
2966 | state->specifics.tcp_udp.ri.remote_address.af = af; | 2599 | existing session from the IP data in the ICMP payload */ |
2600 | source_port = 0; | ||
2601 | destination_port = 0; | ||
2967 | switch (af) | 2602 | switch (af) |
2968 | { | 2603 | { |
2969 | case AF_INET: | 2604 | case AF_INET: |
2970 | if (pkt_len < sizeof (struct in_addr)) | 2605 | protocol = IPPROTO_ICMP; |
2971 | { | 2606 | switch (icmp->type) |
2972 | GNUNET_break_op (0); | 2607 | { |
2973 | return GNUNET_SYSERR; | 2608 | case GNUNET_TUN_ICMPTYPE_ECHO_REPLY: |
2974 | } | 2609 | case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST: |
2975 | if (! ipv4_exit) | 2610 | break; |
2976 | { | 2611 | case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE: |
2977 | GNUNET_break_op (0); | 2612 | case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH: |
2978 | return GNUNET_SYSERR; | 2613 | case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED: |
2979 | } | 2614 | if (pktlen < |
2980 | v4 = (const struct in_addr*) &msg[1]; | 2615 | sizeof (struct GNUNET_TUN_IcmpHeader) + |
2981 | payload = &v4[1]; | 2616 | sizeof (struct GNUNET_TUN_IPv4Header) + 8) |
2982 | pkt_len -= sizeof (struct in_addr); | 2617 | { |
2983 | state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4; | 2618 | /* blame kernel */ |
2619 | GNUNET_break (0); | ||
2620 | return; | ||
2621 | } | ||
2622 | ipv4 = (const struct GNUNET_TUN_IPv4Header *) &icmp[1]; | ||
2623 | protocol = ipv4->protocol; | ||
2624 | /* could be TCP or UDP, but both have the ports in the right | ||
2625 | place, so that doesn't matter here */ | ||
2626 | udp = (const struct GNUNET_TUN_UdpHeader *) &ipv4[1]; | ||
2627 | /* swap ports, as they are from the original message */ | ||
2628 | destination_port = ntohs (udp->source_port); | ||
2629 | source_port = ntohs (udp->destination_port); | ||
2630 | /* throw away ICMP payload, won't be useful for the other side anyway */ | ||
2631 | pktlen = sizeof (struct GNUNET_TUN_IcmpHeader); | ||
2632 | break; | ||
2633 | default: | ||
2634 | GNUNET_STATISTICS_update (stats, | ||
2635 | gettext_noop ("# ICMPv4 packets dropped (type not allowed)"), | ||
2636 | 1, GNUNET_NO); | ||
2637 | return; | ||
2638 | } | ||
2984 | break; | 2639 | break; |
2985 | case AF_INET6: | 2640 | case AF_INET6: |
2986 | if (pkt_len < sizeof (struct in6_addr)) | 2641 | protocol = IPPROTO_ICMPV6; |
2987 | { | 2642 | switch (icmp->type) |
2988 | GNUNET_break_op (0); | 2643 | { |
2989 | return GNUNET_SYSERR; | 2644 | case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE: |
2990 | } | 2645 | case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG: |
2991 | if (! ipv6_exit) | 2646 | case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED: |
2992 | { | 2647 | case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM: |
2993 | GNUNET_break_op (0); | 2648 | if (pktlen < |
2994 | return GNUNET_SYSERR; | 2649 | sizeof (struct GNUNET_TUN_IcmpHeader) + |
2995 | } | 2650 | sizeof (struct GNUNET_TUN_IPv6Header) + 8) |
2996 | v6 = (const struct in6_addr*) &msg[1]; | 2651 | { |
2997 | payload = &v6[1]; | 2652 | /* blame kernel */ |
2998 | pkt_len -= sizeof (struct in6_addr); | 2653 | GNUNET_break (0); |
2999 | state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6; | 2654 | return; |
2655 | } | ||
2656 | ipv6 = (const struct GNUNET_TUN_IPv6Header *) &icmp[1]; | ||
2657 | protocol = ipv6->next_header; | ||
2658 | /* could be TCP or UDP, but both have the ports in the right | ||
2659 | place, so that doesn't matter here */ | ||
2660 | udp = (const struct GNUNET_TUN_UdpHeader *) &ipv6[1]; | ||
2661 | /* swap ports, as they are from the original message */ | ||
2662 | destination_port = ntohs (udp->source_port); | ||
2663 | source_port = ntohs (udp->destination_port); | ||
2664 | /* throw away ICMP payload, won't be useful for the other side anyway */ | ||
2665 | pktlen = sizeof (struct GNUNET_TUN_IcmpHeader); | ||
2666 | break; | ||
2667 | case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST: | ||
2668 | case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY: | ||
2669 | break; | ||
2670 | default: | ||
2671 | GNUNET_STATISTICS_update (stats, | ||
2672 | gettext_noop ("# ICMPv6 packets dropped (type not allowed)"), | ||
2673 | 1, GNUNET_NO); | ||
2674 | return; | ||
2675 | } | ||
3000 | break; | 2676 | break; |
3001 | default: | 2677 | default: |
3002 | GNUNET_break_op (0); | 2678 | GNUNET_assert (0); |
3003 | return GNUNET_SYSERR; | ||
3004 | } | 2679 | } |
2680 | switch (protocol) | ||
3005 | { | 2681 | { |
3006 | char buf[INET6_ADDRSTRLEN]; | 2682 | case IPPROTO_ICMP: |
2683 | state = get_redirect_state (af, | ||
2684 | IPPROTO_ICMP, | ||
2685 | source_ip, | ||
2686 | 0, | ||
2687 | destination_ip, | ||
2688 | 0, | ||
2689 | NULL); | ||
2690 | break; | ||
2691 | case IPPROTO_ICMPV6: | ||
2692 | state = get_redirect_state (af, | ||
2693 | IPPROTO_ICMPV6, | ||
2694 | source_ip, | ||
2695 | 0, | ||
2696 | destination_ip, | ||
2697 | 0, | ||
2698 | NULL); | ||
2699 | break; | ||
2700 | case IPPROTO_UDP: | ||
2701 | state = get_redirect_state (af, | ||
2702 | IPPROTO_UDP, | ||
2703 | source_ip, | ||
2704 | source_port, | ||
2705 | destination_ip, | ||
2706 | destination_port, | ||
2707 | NULL); | ||
2708 | break; | ||
2709 | case IPPROTO_TCP: | ||
2710 | state = get_redirect_state (af, | ||
2711 | IPPROTO_TCP, | ||
2712 | source_ip, | ||
2713 | source_port, | ||
2714 | destination_ip, | ||
2715 | destination_port, | ||
2716 | NULL); | ||
2717 | break; | ||
2718 | default: | ||
2719 | GNUNET_STATISTICS_update (stats, | ||
2720 | gettext_noop ("# ICMP packets dropped (not allowed)"), | ||
2721 | 1, | ||
2722 | GNUNET_NO); | ||
2723 | return; | ||
2724 | } | ||
2725 | if (NULL == state) | ||
2726 | { | ||
2727 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
2728 | _("ICMP Packet dropped, have no matching connection information\n")); | ||
2729 | return; | ||
2730 | } | ||
2731 | env = GNUNET_MQ_msg_extra (i2v, | ||
2732 | pktlen - sizeof (struct GNUNET_TUN_IcmpHeader), | ||
2733 | GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_VPN); | ||
2734 | i2v->af = htonl (af); | ||
2735 | GNUNET_memcpy (&i2v->icmp_header, | ||
2736 | icmp, | ||
2737 | pktlen); | ||
2738 | send_packet_to_cadet_channel (state, | ||
2739 | env); | ||
2740 | } | ||
2741 | |||
2742 | |||
2743 | /** | ||
2744 | * @brief Handles an UDP packet received from the helper. | ||
2745 | * | ||
2746 | * @param udp A pointer to the Packet | ||
2747 | * @param pktlen number of bytes in 'udp' | ||
2748 | * @param af address family (AFINET or AF_INET6) | ||
2749 | * @param destination_ip destination IP-address of the IP packet (should | ||
2750 | * be our local address) | ||
2751 | * @param source_ip original source IP-address of the IP packet (should | ||
2752 | * be the original destination address) | ||
2753 | */ | ||
2754 | static void | ||
2755 | udp_from_helper (const struct GNUNET_TUN_UdpHeader *udp, | ||
2756 | size_t pktlen, | ||
2757 | int af, | ||
2758 | const void *destination_ip, | ||
2759 | const void *source_ip) | ||
2760 | { | ||
2761 | struct ChannelState *state; | ||
2762 | struct GNUNET_MQ_Envelope *env; | ||
2763 | struct GNUNET_EXIT_UdpReplyMessage *urm; | ||
2764 | |||
2765 | { | ||
2766 | char sbuf[INET6_ADDRSTRLEN]; | ||
2767 | char dbuf[INET6_ADDRSTRLEN]; | ||
2768 | |||
3007 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2769 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
3008 | "Received data from %s for forwarding to UDP %s:%u\n", | 2770 | "Received UDP packet going from %s:%u to %s:%u\n", |
3009 | GNUNET_i2s (&state->peer), | ||
3010 | inet_ntop (af, | 2771 | inet_ntop (af, |
3011 | &state->specifics.tcp_udp.ri.remote_address.address, | 2772 | source_ip, |
3012 | buf, sizeof (buf)), | 2773 | sbuf, sizeof (sbuf)), |
3013 | (unsigned int) ntohs (msg->destination_port)); | 2774 | (unsigned int) ntohs (udp->source_port), |
2775 | inet_ntop (af, | ||
2776 | destination_ip, | ||
2777 | dbuf, sizeof (dbuf)), | ||
2778 | (unsigned int) ntohs (udp->destination_port)); | ||
3014 | } | 2779 | } |
3015 | state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_UDP; | 2780 | if (pktlen < sizeof (struct GNUNET_TUN_UdpHeader)) |
3016 | state->specifics.tcp_udp.ri.remote_address.port = msg->destination_port; | 2781 | { |
3017 | if (NULL == state->specifics.tcp_udp.heap_node) | 2782 | /* blame kernel */ |
3018 | setup_state_record (state); | 2783 | GNUNET_break (0); |
3019 | if (0 != ntohs (msg->source_port)) | 2784 | return; |
3020 | state->specifics.tcp_udp.ri.local_address.port = msg->source_port; | 2785 | } |
3021 | send_udp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address, | 2786 | if (pktlen != ntohs (udp->len)) |
3022 | &state->specifics.tcp_udp.ri.local_address, | 2787 | { |
3023 | payload, pkt_len); | 2788 | /* blame kernel */ |
3024 | GNUNET_CADET_receive_done (channel); | 2789 | GNUNET_break (0); |
3025 | return GNUNET_YES; | 2790 | return; |
2791 | } | ||
2792 | state = get_redirect_state (af, | ||
2793 | IPPROTO_UDP, | ||
2794 | source_ip, | ||
2795 | ntohs (udp->source_port), | ||
2796 | destination_ip, | ||
2797 | ntohs (udp->destination_port), | ||
2798 | NULL); | ||
2799 | if (NULL == state) | ||
2800 | { | ||
2801 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
2802 | _("UDP Packet dropped, have no matching connection information\n")); | ||
2803 | return; | ||
2804 | } | ||
2805 | env = GNUNET_MQ_msg_extra (urm, | ||
2806 | pktlen - sizeof (struct GNUNET_TUN_UdpHeader), | ||
2807 | GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY); | ||
2808 | urm->source_port = htons (0); | ||
2809 | urm->destination_port = htons (0); | ||
2810 | GNUNET_memcpy (&urm[1], | ||
2811 | &udp[1], | ||
2812 | pktlen - sizeof (struct GNUNET_TUN_UdpHeader)); | ||
2813 | send_packet_to_cadet_channel (state, | ||
2814 | env); | ||
3026 | } | 2815 | } |
3027 | 2816 | ||
3028 | 2817 | ||
3029 | /** | 2818 | /** |
3030 | * Process a request via cadet to send a request to a UDP service | 2819 | * @brief Handles a TCP packet received from the helper. |
3031 | * offered by this system. | ||
3032 | * | 2820 | * |
3033 | * @param cls closure, NULL | 2821 | * @param tcp A pointer to the Packet |
3034 | * @param channel connection to the other end | 2822 | * @param pktlen the length of the packet, including its TCP header |
3035 | * @param channel_ctx pointer to our 'struct ChannelState *' | 2823 | * @param af address family (AFINET or AF_INET6) |
3036 | * @param message the actual message | 2824 | * @param destination_ip destination IP-address of the IP packet (should |
3037 | * @return #GNUNET_OK to keep the connection open, | 2825 | * be our local address) |
3038 | * #GNUNET_SYSERR to close it (signal serious error) | 2826 | * @param source_ip original source IP-address of the IP packet (should |
2827 | * be the original destination address) | ||
3039 | */ | 2828 | */ |
3040 | static int | 2829 | static void |
3041 | receive_udp_service (void *cls, | 2830 | tcp_from_helper (const struct GNUNET_TUN_TcpHeader *tcp, |
3042 | struct GNUNET_CADET_Channel *channel, | 2831 | size_t pktlen, |
3043 | void **channel_ctx, | 2832 | int af, |
3044 | const struct GNUNET_MessageHeader *message) | 2833 | const void *destination_ip, |
2834 | const void *source_ip) | ||
3045 | { | 2835 | { |
3046 | struct ChannelState *state = *channel_ctx; | 2836 | struct ChannelState *state; |
3047 | const struct GNUNET_EXIT_UdpServiceMessage *msg; | 2837 | char buf[pktlen] GNUNET_ALIGN; |
3048 | uint16_t pkt_len = ntohs (message->size); | 2838 | struct GNUNET_TUN_TcpHeader *mtcp; |
2839 | struct GNUNET_EXIT_TcpDataMessage *tdm; | ||
2840 | struct GNUNET_MQ_Envelope *env; | ||
2841 | size_t mlen; | ||
3049 | 2842 | ||
3050 | if (NULL == state->specifics.tcp_udp.serv) | ||
3051 | { | 2843 | { |
3052 | GNUNET_break_op (0); | 2844 | char sbuf[INET6_ADDRSTRLEN]; |
3053 | return GNUNET_SYSERR; | 2845 | char dbuf[INET6_ADDRSTRLEN]; |
2846 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2847 | "Received TCP packet with %u bytes going from %s:%u to %s:%u\n", | ||
2848 | (unsigned int) (pktlen - sizeof (struct GNUNET_TUN_TcpHeader)), | ||
2849 | inet_ntop (af, | ||
2850 | source_ip, | ||
2851 | sbuf, sizeof (sbuf)), | ||
2852 | (unsigned int) ntohs (tcp->source_port), | ||
2853 | inet_ntop (af, | ||
2854 | destination_ip, | ||
2855 | dbuf, sizeof (dbuf)), | ||
2856 | (unsigned int) ntohs (tcp->destination_port)); | ||
3054 | } | 2857 | } |
2858 | if (pktlen < sizeof (struct GNUNET_TUN_TcpHeader)) | ||
2859 | { | ||
2860 | /* blame kernel */ | ||
2861 | GNUNET_break (0); | ||
2862 | return; | ||
2863 | } | ||
2864 | state = get_redirect_state (af, | ||
2865 | IPPROTO_TCP, | ||
2866 | source_ip, | ||
2867 | ntohs (tcp->source_port), | ||
2868 | destination_ip, | ||
2869 | ntohs (tcp->destination_port), | ||
2870 | NULL); | ||
2871 | if (NULL == state) | ||
2872 | { | ||
2873 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
2874 | _("TCP Packet dropped, have no matching connection information\n")); | ||
2875 | |||
2876 | return; | ||
2877 | } | ||
2878 | /* mug port numbers and crc to avoid information leakage; | ||
2879 | sender will need to lookup the correct values anyway */ | ||
2880 | GNUNET_memcpy (buf, tcp, pktlen); | ||
2881 | mtcp = (struct GNUNET_TUN_TcpHeader *) buf; | ||
2882 | mtcp->source_port = 0; | ||
2883 | mtcp->destination_port = 0; | ||
2884 | mtcp->crc = 0; | ||
2885 | |||
2886 | mlen = sizeof (struct GNUNET_EXIT_TcpDataMessage) + (pktlen - sizeof (struct GNUNET_TUN_TcpHeader)); | ||
2887 | if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
2888 | { | ||
2889 | GNUNET_break (0); | ||
2890 | return; | ||
2891 | } | ||
2892 | env = GNUNET_MQ_msg_extra (tdm, | ||
2893 | pktlen - sizeof (struct GNUNET_TUN_TcpHeader), | ||
2894 | GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_VPN); | ||
2895 | tdm->reserved = htonl (0); | ||
2896 | GNUNET_memcpy (&tdm->tcp_header, | ||
2897 | buf, | ||
2898 | pktlen); | ||
2899 | send_packet_to_cadet_channel (state, | ||
2900 | env); | ||
2901 | } | ||
2902 | |||
2903 | |||
2904 | /** | ||
2905 | * Receive packets from the helper-process | ||
2906 | * | ||
2907 | * @param cls unused | ||
2908 | * @param client unsued | ||
2909 | * @param message message received from helper | ||
2910 | */ | ||
2911 | static int | ||
2912 | message_token (void *cls GNUNET_UNUSED, | ||
2913 | void *client GNUNET_UNUSED, | ||
2914 | const struct GNUNET_MessageHeader *message) | ||
2915 | { | ||
2916 | const struct GNUNET_TUN_Layer2PacketHeader *pkt_tun; | ||
2917 | size_t size; | ||
2918 | |||
2919 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2920 | "Got %u-byte message of type %u from gnunet-helper-exit\n", | ||
2921 | ntohs (message->size), | ||
2922 | ntohs (message->type)); | ||
3055 | GNUNET_STATISTICS_update (stats, | 2923 | GNUNET_STATISTICS_update (stats, |
3056 | gettext_noop ("# Bytes received from CADET"), | 2924 | gettext_noop ("# Packets received from TUN"), |
3057 | pkt_len, GNUNET_NO); | ||
3058 | GNUNET_STATISTICS_update (stats, | ||
3059 | gettext_noop ("# UDP service requests received via cadet"), | ||
3060 | 1, GNUNET_NO); | 2925 | 1, GNUNET_NO); |
3061 | /* check that we got at least a valid header */ | 2926 | if (ntohs (message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) |
3062 | if (pkt_len < sizeof (struct GNUNET_EXIT_UdpServiceMessage)) | ||
3063 | { | 2927 | { |
3064 | GNUNET_break_op (0); | 2928 | GNUNET_break (0); |
3065 | return GNUNET_SYSERR; | 2929 | return GNUNET_OK; |
3066 | } | 2930 | } |
3067 | msg = (const struct GNUNET_EXIT_UdpServiceMessage*) message; | 2931 | size = ntohs (message->size); |
3068 | pkt_len -= sizeof (struct GNUNET_EXIT_UdpServiceMessage); | 2932 | if (size < sizeof (struct GNUNET_TUN_Layer2PacketHeader) + sizeof (struct GNUNET_MessageHeader)) |
3069 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 2933 | { |
3070 | "Received data from %s for forwarding to UDP service %s on port %u\n", | 2934 | GNUNET_break (0); |
3071 | GNUNET_i2s (&state->peer), | 2935 | return GNUNET_OK; |
3072 | GNUNET_h2s (&state->specifics.tcp_udp.serv->descriptor), | 2936 | } |
3073 | (unsigned int) ntohs (msg->destination_port)); | 2937 | GNUNET_STATISTICS_update (stats, |
3074 | setup_state_record (state); | 2938 | gettext_noop ("# Bytes received from TUN"), |
3075 | if (0 != ntohs (msg->source_port)) | 2939 | size, GNUNET_NO); |
3076 | state->specifics.tcp_udp.ri.local_address.port = msg->source_port; | 2940 | pkt_tun = (const struct GNUNET_TUN_Layer2PacketHeader *) &message[1]; |
3077 | send_udp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address, | 2941 | size -= sizeof (struct GNUNET_TUN_Layer2PacketHeader) + sizeof (struct GNUNET_MessageHeader); |
3078 | &state->specifics.tcp_udp.ri.local_address, | 2942 | switch (ntohs (pkt_tun->proto)) |
3079 | &msg[1], | 2943 | { |
3080 | pkt_len); | 2944 | case ETH_P_IPV4: |
3081 | GNUNET_CADET_receive_done (channel); | 2945 | { |
3082 | return GNUNET_YES; | 2946 | const struct GNUNET_TUN_IPv4Header *pkt4; |
2947 | |||
2948 | if (size < sizeof (struct GNUNET_TUN_IPv4Header)) | ||
2949 | { | ||
2950 | /* Kernel to blame? */ | ||
2951 | GNUNET_break (0); | ||
2952 | return GNUNET_OK; | ||
2953 | } | ||
2954 | pkt4 = (const struct GNUNET_TUN_IPv4Header *) &pkt_tun[1]; | ||
2955 | if (size != ntohs (pkt4->total_length)) | ||
2956 | { | ||
2957 | /* Kernel to blame? */ | ||
2958 | GNUNET_break (0); | ||
2959 | return GNUNET_OK; | ||
2960 | } | ||
2961 | if (pkt4->header_length * 4 != sizeof (struct GNUNET_TUN_IPv4Header)) | ||
2962 | { | ||
2963 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
2964 | _("IPv4 packet options received. Ignored.\n")); | ||
2965 | return GNUNET_OK; | ||
2966 | } | ||
2967 | |||
2968 | size -= sizeof (struct GNUNET_TUN_IPv4Header); | ||
2969 | switch (pkt4->protocol) | ||
2970 | { | ||
2971 | case IPPROTO_UDP: | ||
2972 | udp_from_helper ((const struct GNUNET_TUN_UdpHeader *) &pkt4[1], size, | ||
2973 | AF_INET, | ||
2974 | &pkt4->destination_address, | ||
2975 | &pkt4->source_address); | ||
2976 | break; | ||
2977 | case IPPROTO_TCP: | ||
2978 | tcp_from_helper ((const struct GNUNET_TUN_TcpHeader *) &pkt4[1], size, | ||
2979 | AF_INET, | ||
2980 | &pkt4->destination_address, | ||
2981 | &pkt4->source_address); | ||
2982 | break; | ||
2983 | case IPPROTO_ICMP: | ||
2984 | icmp_from_helper ((const struct GNUNET_TUN_IcmpHeader *) &pkt4[1], size, | ||
2985 | AF_INET, | ||
2986 | &pkt4->destination_address, | ||
2987 | &pkt4->source_address); | ||
2988 | break; | ||
2989 | default: | ||
2990 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
2991 | _("IPv4 packet with unsupported next header %u received. Ignored.\n"), | ||
2992 | (int) pkt4->protocol); | ||
2993 | return GNUNET_OK; | ||
2994 | } | ||
2995 | } | ||
2996 | break; | ||
2997 | case ETH_P_IPV6: | ||
2998 | { | ||
2999 | const struct GNUNET_TUN_IPv6Header *pkt6; | ||
3000 | |||
3001 | if (size < sizeof (struct GNUNET_TUN_IPv6Header)) | ||
3002 | { | ||
3003 | /* Kernel to blame? */ | ||
3004 | GNUNET_break (0); | ||
3005 | return GNUNET_OK; | ||
3006 | } | ||
3007 | pkt6 = (struct GNUNET_TUN_IPv6Header *) &pkt_tun[1]; | ||
3008 | if (size != ntohs (pkt6->payload_length) + sizeof (struct GNUNET_TUN_IPv6Header)) | ||
3009 | { | ||
3010 | /* Kernel to blame? */ | ||
3011 | GNUNET_break (0); | ||
3012 | return GNUNET_OK; | ||
3013 | } | ||
3014 | size -= sizeof (struct GNUNET_TUN_IPv6Header); | ||
3015 | switch (pkt6->next_header) | ||
3016 | { | ||
3017 | case IPPROTO_UDP: | ||
3018 | udp_from_helper ((const struct GNUNET_TUN_UdpHeader *) &pkt6[1], size, | ||
3019 | AF_INET6, | ||
3020 | &pkt6->destination_address, | ||
3021 | &pkt6->source_address); | ||
3022 | break; | ||
3023 | case IPPROTO_TCP: | ||
3024 | tcp_from_helper ((const struct GNUNET_TUN_TcpHeader *) &pkt6[1], size, | ||
3025 | AF_INET6, | ||
3026 | &pkt6->destination_address, | ||
3027 | &pkt6->source_address); | ||
3028 | break; | ||
3029 | case IPPROTO_ICMPV6: | ||
3030 | icmp_from_helper ((const struct GNUNET_TUN_IcmpHeader *) &pkt6[1], size, | ||
3031 | AF_INET6, | ||
3032 | &pkt6->destination_address, | ||
3033 | &pkt6->source_address); | ||
3034 | break; | ||
3035 | default: | ||
3036 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
3037 | _("IPv6 packet with unsupported next header %d received. Ignored.\n"), | ||
3038 | pkt6->next_header); | ||
3039 | return GNUNET_OK; | ||
3040 | } | ||
3041 | } | ||
3042 | break; | ||
3043 | default: | ||
3044 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
3045 | _("Packet from unknown protocol %u received. Ignored.\n"), | ||
3046 | ntohs (pkt_tun->proto)); | ||
3047 | break; | ||
3048 | } | ||
3049 | return GNUNET_OK; | ||
3083 | } | 3050 | } |
3084 | 3051 | ||
3085 | 3052 | ||
@@ -3089,16 +3056,12 @@ receive_udp_service (void *cls, | |||
3089 | * @param cls closure | 3056 | * @param cls closure |
3090 | * @param channel new handle to the channel | 3057 | * @param channel new handle to the channel |
3091 | * @param initiator peer that started the channel | 3058 | * @param initiator peer that started the channel |
3092 | * @param port destination port | ||
3093 | * @param options channel options flags | ||
3094 | * @return initial channel context for the channel | 3059 | * @return initial channel context for the channel |
3095 | */ | 3060 | */ |
3096 | static void * | 3061 | static void * |
3097 | new_channel (void *cls, | 3062 | new_channel (void *cls, |
3098 | struct GNUNET_CADET_Channel *channel, | 3063 | struct GNUNET_CADET_Channel *channel, |
3099 | const struct GNUNET_PeerIdentity *initiator, | 3064 | const struct GNUNET_PeerIdentity *initiator) |
3100 | const struct GNUNET_HashCode *port, | ||
3101 | enum GNUNET_CADET_ChannelOption options) | ||
3102 | { | 3065 | { |
3103 | struct ChannelState *s = GNUNET_new (struct ChannelState); | 3066 | struct ChannelState *s = GNUNET_new (struct ChannelState); |
3104 | 3067 | ||
@@ -3106,7 +3069,8 @@ new_channel (void *cls, | |||
3106 | s->peer = *initiator; | 3069 | s->peer = *initiator; |
3107 | GNUNET_STATISTICS_update (stats, | 3070 | GNUNET_STATISTICS_update (stats, |
3108 | gettext_noop ("# Inbound CADET channels created"), | 3071 | gettext_noop ("# Inbound CADET channels created"), |
3109 | 1, GNUNET_NO); | 3072 | 1, |
3073 | GNUNET_NO); | ||
3110 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 3074 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
3111 | "Received inbound channel from `%s'\n", | 3075 | "Received inbound channel from `%s'\n", |
3112 | GNUNET_i2s (initiator)); | 3076 | GNUNET_i2s (initiator)); |
@@ -3116,64 +3080,6 @@ new_channel (void *cls, | |||
3116 | 3080 | ||
3117 | 3081 | ||
3118 | /** | 3082 | /** |
3119 | * Function called by cadet whenever an inbound channel is destroyed. | ||
3120 | * Should clean up any associated state. | ||
3121 | * | ||
3122 | * @param cls closure (set from #GNUNET_CADET_connect) | ||
3123 | * @param channel connection to the other end (henceforth invalid) | ||
3124 | * @param channel_ctx place where local state associated | ||
3125 | * with the channel is stored | ||
3126 | */ | ||
3127 | static void | ||
3128 | clean_channel (void *cls, | ||
3129 | const struct GNUNET_CADET_Channel *channel, | ||
3130 | void *channel_ctx) | ||
3131 | { | ||
3132 | struct ChannelState *s = channel_ctx; | ||
3133 | struct ChannelMessageQueue *tnq; | ||
3134 | |||
3135 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
3136 | "Channel destroyed\n"); | ||
3137 | if (GNUNET_SYSERR == s->is_dns) | ||
3138 | { | ||
3139 | GNUNET_free (s); | ||
3140 | return; | ||
3141 | } | ||
3142 | if (GNUNET_YES == s->is_dns) | ||
3143 | { | ||
3144 | if (channels[s->specifics.dns.my_id] == s) | ||
3145 | channels[s->specifics.dns.my_id] = NULL; | ||
3146 | GNUNET_free_non_null (s->specifics.dns.reply); | ||
3147 | } | ||
3148 | else | ||
3149 | { | ||
3150 | while (NULL != (tnq = s->specifics.tcp_udp.head)) | ||
3151 | { | ||
3152 | GNUNET_CONTAINER_DLL_remove (s->specifics.tcp_udp.head, | ||
3153 | s->specifics.tcp_udp.tail, | ||
3154 | tnq); | ||
3155 | GNUNET_free (tnq); | ||
3156 | } | ||
3157 | if (NULL != s->specifics.tcp_udp.heap_node) | ||
3158 | { | ||
3159 | GNUNET_assert (GNUNET_YES == | ||
3160 | GNUNET_CONTAINER_multihashmap_remove (connections_map, | ||
3161 | &s->specifics.tcp_udp.state_key, | ||
3162 | s)); | ||
3163 | GNUNET_CONTAINER_heap_remove_node (s->specifics.tcp_udp.heap_node); | ||
3164 | s->specifics.tcp_udp.heap_node = NULL; | ||
3165 | } | ||
3166 | } | ||
3167 | if (NULL != s->th) | ||
3168 | { | ||
3169 | GNUNET_CADET_notify_transmit_ready_cancel (s->th); | ||
3170 | s->th = NULL; | ||
3171 | } | ||
3172 | GNUNET_free (s); | ||
3173 | } | ||
3174 | |||
3175 | |||
3176 | /** | ||
3177 | * Function that frees everything from a hashmap | 3083 | * Function that frees everything from a hashmap |
3178 | * | 3084 | * |
3179 | * @param cls unused | 3085 | * @param cls unused |
@@ -3241,6 +3147,21 @@ cleanup (void *cls) | |||
3241 | NULL); | 3147 | NULL); |
3242 | GNUNET_CONTAINER_multihashmap_destroy (services); | 3148 | GNUNET_CONTAINER_multihashmap_destroy (services); |
3243 | } | 3149 | } |
3150 | if (NULL != dns_port) | ||
3151 | { | ||
3152 | GNUNET_CADET_close_port (dns_port); | ||
3153 | dns_port = NULL; | ||
3154 | } | ||
3155 | if (NULL != cadet_port4) | ||
3156 | { | ||
3157 | GNUNET_CADET_close_port (cadet_port4); | ||
3158 | cadet_port4 = NULL; | ||
3159 | } | ||
3160 | if (NULL != cadet_port6) | ||
3161 | { | ||
3162 | GNUNET_CADET_close_port (cadet_port6); | ||
3163 | cadet_port6 = NULL; | ||
3164 | } | ||
3244 | if (NULL != cadet_handle) | 3165 | if (NULL != cadet_handle) |
3245 | { | 3166 | { |
3246 | GNUNET_CADET_disconnect (cadet_handle); | 3167 | GNUNET_CADET_disconnect (cadet_handle); |
@@ -3286,7 +3207,8 @@ cleanup (void *cls) | |||
3286 | } | 3207 | } |
3287 | if (NULL != stats) | 3208 | if (NULL != stats) |
3288 | { | 3209 | { |
3289 | GNUNET_STATISTICS_destroy (stats, GNUNET_NO); | 3210 | GNUNET_STATISTICS_destroy (stats, |
3211 | GNUNET_NO); | ||
3290 | stats = NULL; | 3212 | stats = NULL; |
3291 | } | 3213 | } |
3292 | for (i=0;i<8;i++) | 3214 | for (i=0;i<8;i++) |
@@ -3614,6 +3536,13 @@ parse_ip_options () | |||
3614 | static void | 3536 | static void |
3615 | advertise_dns_exit () | 3537 | advertise_dns_exit () |
3616 | { | 3538 | { |
3539 | struct GNUNET_MQ_MessageHandler handlers[] = { | ||
3540 | GNUNET_MQ_hd_var_size (dns_request, | ||
3541 | GNUNET_MESSAGE_TYPE_VPN_DNS_TO_INTERNET, | ||
3542 | struct DnsResponseMessage, | ||
3543 | NULL), | ||
3544 | GNUNET_MQ_handler_end () | ||
3545 | }; | ||
3617 | char *dns_exit; | 3546 | char *dns_exit; |
3618 | struct GNUNET_HashCode port; | 3547 | struct GNUNET_HashCode port; |
3619 | struct in_addr dns_exit4; | 3548 | struct in_addr dns_exit4; |
@@ -3650,10 +3579,13 @@ advertise_dns_exit () | |||
3650 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 3579 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
3651 | "Opening CADET port %s for DNS exit service\n", | 3580 | "Opening CADET port %s for DNS exit service\n", |
3652 | GNUNET_h2s (&port)); | 3581 | GNUNET_h2s (&port)); |
3653 | GNUNET_CADET_open_port (cadet_handle, | 3582 | dns_port = GNUNET_CADET_open_porT (cadet_handle, |
3654 | &port, | 3583 | &port, |
3655 | &new_channel, | 3584 | &new_channel, |
3656 | NULL); | 3585 | NULL, |
3586 | NULL, | ||
3587 | &clean_channel, | ||
3588 | handlers); | ||
3657 | /* advertise exit */ | 3589 | /* advertise exit */ |
3658 | dht = GNUNET_DHT_connect (cfg, | 3590 | dht = GNUNET_DHT_connect (cfg, |
3659 | 1); | 3591 | 1); |
@@ -3833,16 +3765,24 @@ run (void *cls, | |||
3833 | const char *cfgfile, | 3765 | const char *cfgfile, |
3834 | const struct GNUNET_CONFIGURATION_Handle *cfg_) | 3766 | const struct GNUNET_CONFIGURATION_Handle *cfg_) |
3835 | { | 3767 | { |
3836 | static struct GNUNET_CADET_MessageHandler handlers[] = { | 3768 | struct GNUNET_MQ_MessageHandler handlers[] = { |
3837 | {&receive_icmp_service, GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_SERVICE, 0}, | 3769 | GNUNET_MQ_hd_var_size (icmp_remote, |
3838 | {&receive_icmp_remote, GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_INTERNET, 0}, | 3770 | GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_INTERNET, |
3839 | {&receive_udp_service, GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE, 0}, | 3771 | struct GNUNET_EXIT_IcmpInternetMessage, |
3840 | {&receive_udp_remote, GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET, 0}, | 3772 | NULL), |
3841 | {&receive_tcp_service, GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START, 0}, | 3773 | GNUNET_MQ_hd_var_size (udp_remote, |
3842 | {&receive_tcp_remote, GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START, 0}, | 3774 | GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET, |
3843 | {&receive_tcp_data, GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT, 0}, | 3775 | struct GNUNET_EXIT_UdpInternetMessage, |
3844 | {&receive_dns_request, GNUNET_MESSAGE_TYPE_VPN_DNS_TO_INTERNET, 0}, | 3776 | NULL), |
3845 | {NULL, 0, 0} | 3777 | GNUNET_MQ_hd_var_size (tcp_remote, |
3778 | GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START, | ||
3779 | struct GNUNET_EXIT_TcpInternetStartMessage, | ||
3780 | NULL), | ||
3781 | GNUNET_MQ_hd_var_size (tcp_data, | ||
3782 | GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT, | ||
3783 | struct GNUNET_EXIT_TcpDataMessage, | ||
3784 | NULL), | ||
3785 | GNUNET_MQ_handler_end () | ||
3846 | }; | 3786 | }; |
3847 | struct GNUNET_HashCode port; | 3787 | struct GNUNET_HashCode port; |
3848 | char *policy; | 3788 | char *policy; |
@@ -3889,10 +3829,7 @@ run (void *cls, | |||
3889 | NULL); | 3829 | NULL); |
3890 | stats = GNUNET_STATISTICS_create ("exit", | 3830 | stats = GNUNET_STATISTICS_create ("exit", |
3891 | cfg); | 3831 | cfg); |
3892 | cadet_handle = GNUNET_CADET_connect (cfg, | 3832 | cadet_handle = GNUNET_CADET_connecT (cfg); |
3893 | NULL, | ||
3894 | &clean_channel, | ||
3895 | handlers); | ||
3896 | if (NULL == cadet_handle) | 3833 | if (NULL == cadet_handle) |
3897 | { | 3834 | { |
3898 | GNUNET_SCHEDULER_shutdown (); | 3835 | GNUNET_SCHEDULER_shutdown (); |
@@ -3925,10 +3862,13 @@ run (void *cls, | |||
3925 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 3862 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
3926 | "Opening CADET port %s for IPv4 gateway service\n", | 3863 | "Opening CADET port %s for IPv4 gateway service\n", |
3927 | GNUNET_h2s (&port)); | 3864 | GNUNET_h2s (&port)); |
3928 | GNUNET_CADET_open_port (cadet_handle, | 3865 | cadet_port4 = GNUNET_CADET_open_porT (cadet_handle, |
3929 | &port, | 3866 | &port, |
3930 | &new_channel, | 3867 | &new_channel, |
3931 | NULL); | 3868 | NULL, |
3869 | NULL, | ||
3870 | &clean_channel, | ||
3871 | handlers); | ||
3932 | policy = NULL; | 3872 | policy = NULL; |
3933 | if (GNUNET_OK != | 3873 | if (GNUNET_OK != |
3934 | GNUNET_CONFIGURATION_get_value_string (cfg, | 3874 | GNUNET_CONFIGURATION_get_value_string (cfg, |
@@ -3962,10 +3902,13 @@ run (void *cls, | |||
3962 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 3902 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
3963 | "Opening CADET port %s for IPv6 gateway service\n", | 3903 | "Opening CADET port %s for IPv6 gateway service\n", |
3964 | GNUNET_h2s (&port)); | 3904 | GNUNET_h2s (&port)); |
3965 | GNUNET_CADET_open_port (cadet_handle, | 3905 | cadet_port6 = GNUNET_CADET_open_porT (cadet_handle, |
3966 | &port, | 3906 | &port, |
3967 | &new_channel, | 3907 | &new_channel, |
3968 | NULL); | 3908 | NULL, |
3909 | NULL, | ||
3910 | &clean_channel, | ||
3911 | handlers); | ||
3969 | policy = NULL; | 3912 | policy = NULL; |
3970 | if (GNUNET_OK != | 3913 | if (GNUNET_OK != |
3971 | GNUNET_CONFIGURATION_get_value_string (cfg, | 3914 | GNUNET_CONFIGURATION_get_value_string (cfg, |
diff --git a/src/fs/.gitignore b/src/fs/.gitignore index 7f0b0ddc3..f0e2a4f7b 100644 --- a/src/fs/.gitignore +++ b/src/fs/.gitignore | |||
@@ -40,3 +40,4 @@ test_plugin_block_fs | |||
40 | perf_gnunet_service_fs_p2p | 40 | perf_gnunet_service_fs_p2p |
41 | perf_gnunet_service_fs_p2p_index | 41 | perf_gnunet_service_fs_p2p_index |
42 | perf_gnunet_service_fs_p2p_respect | 42 | perf_gnunet_service_fs_p2p_respect |
43 | rdir.gnd | ||
diff --git a/src/fs/fs.conf.in b/src/fs/fs.conf.in index 3534378ae..d46de387f 100644 --- a/src/fs/fs.conf.in +++ b/src/fs/fs.conf.in | |||
@@ -36,7 +36,7 @@ MAX_PENDING_REQUESTS = 65536 | |||
36 | 36 | ||
37 | # How many requests do we have at most waiting in the queue towards | 37 | # How many requests do we have at most waiting in the queue towards |
38 | # the datastore? (important for memory consumption) | 38 | # the datastore? (important for memory consumption) |
39 | DATASTORE_QUEUE_SIZE = 1024 | 39 | DATASTORE_QUEUE_SIZE = 32 |
40 | 40 | ||
41 | # Maximum frequency we're allowed to poll the datastore | 41 | # Maximum frequency we're allowed to poll the datastore |
42 | # for content for migration (can be used to reduce | 42 | # for content for migration (can be used to reduce |
diff --git a/src/fs/fs_search.c b/src/fs/fs_search.c index 75ce4b54f..3cbf2afef 100644 --- a/src/fs/fs_search.c +++ b/src/fs/fs_search.c | |||
@@ -1145,7 +1145,7 @@ schedule_transmit_search_request (struct GNUNET_FS_SearchContext *sc) | |||
1145 | &build_result_set, | 1145 | &build_result_set, |
1146 | &mbc); | 1146 | &mbc); |
1147 | search_request_map_offset += todo; | 1147 | search_request_map_offset += todo; |
1148 | GNUNET_assert (0 == mbc.put_cnt); | 1148 | GNUNET_assert (0 == mbc.put_cnt); /* #4608 reports this fails? */ |
1149 | GNUNET_assert (total_seen_results >= search_request_map_offset); | 1149 | GNUNET_assert (total_seen_results >= search_request_map_offset); |
1150 | if (total_seen_results != search_request_map_offset) | 1150 | if (total_seen_results != search_request_map_offset) |
1151 | { | 1151 | { |
diff --git a/src/fs/gnunet-service-fs.c b/src/fs/gnunet-service-fs.c index 8c605c6a2..256d0c2b8 100644 --- a/src/fs/gnunet-service-fs.c +++ b/src/fs/gnunet-service-fs.c | |||
@@ -1349,7 +1349,7 @@ run (void *cls, | |||
1349 | GNUNET_log_config_missing (GNUNET_ERROR_TYPE_INFO, | 1349 | GNUNET_log_config_missing (GNUNET_ERROR_TYPE_INFO, |
1350 | "fs", | 1350 | "fs", |
1351 | "DATASTORE_QUEUE_SIZE"); | 1351 | "DATASTORE_QUEUE_SIZE"); |
1352 | dqs = 1024; | 1352 | dqs = 32; |
1353 | } | 1353 | } |
1354 | GSF_datastore_queue_size = (unsigned int) dqs; | 1354 | GSF_datastore_queue_size = (unsigned int) dqs; |
1355 | GSF_enable_randomized_delays = | 1355 | GSF_enable_randomized_delays = |
diff --git a/src/fs/gnunet-service-fs_pr.c b/src/fs/gnunet-service-fs_pr.c index 87e2d2ee1..b0fda24b5 100644 --- a/src/fs/gnunet-service-fs_pr.c +++ b/src/fs/gnunet-service-fs_pr.c | |||
@@ -264,8 +264,9 @@ refresh_bloomfilter (enum GNUNET_BLOCK_Type type, | |||
264 | UINT32_MAX), | 264 | UINT32_MAX), |
265 | NULL, | 265 | NULL, |
266 | 0, | 266 | 0, |
267 | "fs-seen-set-size", | 267 | "seen-set-size", |
268 | pr->replies_seen_count); | 268 | pr->replies_seen_count, |
269 | NULL); | ||
269 | if (NULL == pr->bg) | 270 | if (NULL == pr->bg) |
270 | return; | 271 | return; |
271 | GNUNET_break (GNUNET_OK == | 272 | GNUNET_break (GNUNET_OK == |
@@ -383,8 +384,9 @@ GSF_pending_request_create_ (enum GSF_PendingRequestOptions options, | |||
383 | mingle, | 384 | mingle, |
384 | bf_data, | 385 | bf_data, |
385 | bf_size, | 386 | bf_size, |
386 | "fs-seen-set-size", | 387 | "seen-set-size", |
387 | 0); | 388 | 0, |
389 | NULL); | ||
388 | } | 390 | } |
389 | else if ((replies_seen_count > 0) && | 391 | else if ((replies_seen_count > 0) && |
390 | (0 != (options & GSF_PRO_BLOOMFILTER_FULL_REFRESH))) | 392 | (0 != (options & GSF_PRO_BLOOMFILTER_FULL_REFRESH))) |
diff --git a/src/fs/plugin_block_fs.c b/src/fs/plugin_block_fs.c index 6c574fca2..902519f15 100644 --- a/src/fs/plugin_block_fs.c +++ b/src/fs/plugin_block_fs.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include "gnunet_fs_service.h" | 28 | #include "gnunet_fs_service.h" |
29 | #include "block_fs.h" | 29 | #include "block_fs.h" |
30 | #include "gnunet_signatures.h" | 30 | #include "gnunet_signatures.h" |
31 | #include "gnunet_constants.h" | ||
32 | #include "gnunet_block_group_lib.h" | 31 | #include "gnunet_block_group_lib.h" |
33 | 32 | ||
34 | 33 | ||
@@ -40,37 +39,6 @@ | |||
40 | 39 | ||
41 | 40 | ||
42 | /** | 41 | /** |
43 | * How many bytes should a bloomfilter be if we have already seen | ||
44 | * entry_count responses? Note that #GNUNET_CONSTANTS_BLOOMFILTER_K | ||
45 | * gives us the number of bits set per entry. Furthermore, we should | ||
46 | * not re-size the filter too often (to keep it cheap). | ||
47 | * | ||
48 | * Since other peers will also add entries but not resize the filter, | ||
49 | * we should generally pick a slightly larger size than what the | ||
50 | * strict math would suggest. | ||
51 | * | ||
52 | * @param entry_count expected number of entries in the Bloom filter | ||
53 | * @return must be a power of two and smaller or equal to 2^15. | ||
54 | */ | ||
55 | static size_t | ||
56 | compute_bloomfilter_size (unsigned int entry_count) | ||
57 | { | ||
58 | size_t size; | ||
59 | unsigned int ideal = (entry_count * GNUNET_CONSTANTS_BLOOMFILTER_K) / 4; | ||
60 | uint16_t max = 1 << 15; | ||
61 | |||
62 | if (entry_count > max) | ||
63 | return max; | ||
64 | size = 8; | ||
65 | while ((size < max) && (size < ideal)) | ||
66 | size *= 2; | ||
67 | if (size > max) | ||
68 | return max; | ||
69 | return size; | ||
70 | } | ||
71 | |||
72 | |||
73 | /** | ||
74 | * Create a new block group. | 42 | * Create a new block group. |
75 | * | 43 | * |
76 | * @param ctx block context in which the block group is created | 44 | * @param ctx block context in which the block group is created |
@@ -96,14 +64,15 @@ block_plugin_fs_create_group (void *cls, | |||
96 | switch (type) | 64 | switch (type) |
97 | { | 65 | { |
98 | case GNUNET_BLOCK_TYPE_FS_DBLOCK: | 66 | case GNUNET_BLOCK_TYPE_FS_DBLOCK: |
67 | GNUNET_break (NULL == va_arg (va, const char *)); | ||
99 | return NULL; | 68 | return NULL; |
100 | case GNUNET_BLOCK_TYPE_FS_IBLOCK: | 69 | case GNUNET_BLOCK_TYPE_FS_IBLOCK: |
70 | GNUNET_break (NULL == va_arg (va, const char *)); | ||
101 | return NULL; | 71 | return NULL; |
102 | case GNUNET_BLOCK_TYPE_FS_UBLOCK: | 72 | case GNUNET_BLOCK_TYPE_FS_UBLOCK: |
103 | guard = va_arg (va, const char *); | 73 | guard = va_arg (va, const char *); |
104 | if (0 != memcmp (guard, | 74 | if (0 != strcmp (guard, |
105 | "fs-seen-set-size", | 75 | "seen-set-size")) |
106 | strlen ("fs-seen-set-size"))) | ||
107 | { | 76 | { |
108 | /* va-args invalid! bad bug, complain! */ | 77 | /* va-args invalid! bad bug, complain! */ |
109 | GNUNET_break (0); | 78 | GNUNET_break (0); |
@@ -111,10 +80,12 @@ block_plugin_fs_create_group (void *cls, | |||
111 | } | 80 | } |
112 | else | 81 | else |
113 | { | 82 | { |
114 | size = compute_bloomfilter_size (va_arg (va, unsigned int)); | 83 | size = GNUNET_BLOCK_GROUP_compute_bloomfilter_size (va_arg (va, unsigned int), |
84 | BLOOMFILTER_K); | ||
115 | } | 85 | } |
116 | if (0 == size) | 86 | if (0 == size) |
117 | size = raw_data_size; /* not for us to determine, use what we got! */ | 87 | size = raw_data_size; /* not for us to determine, use what we got! */ |
88 | GNUNET_break (NULL == va_arg (va, const char *)); | ||
118 | return GNUNET_BLOCK_GROUP_bf_create (cls, | 89 | return GNUNET_BLOCK_GROUP_bf_create (cls, |
119 | size, | 90 | size, |
120 | BLOOMFILTER_K, | 91 | BLOOMFILTER_K, |
@@ -123,6 +94,7 @@ block_plugin_fs_create_group (void *cls, | |||
123 | raw_data, | 94 | raw_data, |
124 | raw_data_size); | 95 | raw_data_size); |
125 | default: | 96 | default: |
97 | GNUNET_break (NULL == va_arg (va, const char *)); | ||
126 | GNUNET_break (0); | 98 | GNUNET_break (0); |
127 | return NULL; | 99 | return NULL; |
128 | } | 100 | } |
@@ -137,6 +109,7 @@ block_plugin_fs_create_group (void *cls, | |||
137 | * be done with the #GNUNET_BLOCK_get_key() function. | 109 | * be done with the #GNUNET_BLOCK_get_key() function. |
138 | * | 110 | * |
139 | * @param cls closure | 111 | * @param cls closure |
112 | * @param ctx block context | ||
140 | * @param type block type | 113 | * @param type block type |
141 | * @param bg group to use for evaluation | 114 | * @param bg group to use for evaluation |
142 | * @param eo control flags | 115 | * @param eo control flags |
@@ -149,6 +122,7 @@ block_plugin_fs_create_group (void *cls, | |||
149 | */ | 122 | */ |
150 | static enum GNUNET_BLOCK_EvaluationResult | 123 | static enum GNUNET_BLOCK_EvaluationResult |
151 | block_plugin_fs_evaluate (void *cls, | 124 | block_plugin_fs_evaluate (void *cls, |
125 | struct GNUNET_BLOCK_Context *ctx, | ||
152 | enum GNUNET_BLOCK_Type type, | 126 | enum GNUNET_BLOCK_Type type, |
153 | struct GNUNET_BLOCK_Group *bg, | 127 | struct GNUNET_BLOCK_Group *bg, |
154 | enum GNUNET_BLOCK_EvaluationOptions eo, | 128 | enum GNUNET_BLOCK_EvaluationOptions eo, |
@@ -302,7 +276,7 @@ libgnunet_plugin_block_fs_init (void *cls) | |||
302 | void * | 276 | void * |
303 | libgnunet_plugin_block_fs_done (void *cls) | 277 | libgnunet_plugin_block_fs_done (void *cls) |
304 | { | 278 | { |
305 | struct GNUNET_TRANSPORT_PluginFunctions *api = cls; | 279 | struct GNUNET_BLOCK_PluginFunctions *api = cls; |
306 | 280 | ||
307 | GNUNET_free (api); | 281 | GNUNET_free (api); |
308 | return NULL; | 282 | return NULL; |
diff --git a/src/gns/Makefile.am b/src/gns/Makefile.am index d59908c0a..464bbbca1 100644 --- a/src/gns/Makefile.am +++ b/src/gns/Makefile.am | |||
@@ -12,7 +12,6 @@ SUBDIRS = . $(NSS_SUBDIR) | |||
12 | EXTRA_DIST = \ | 12 | EXTRA_DIST = \ |
13 | test_gns_defaults.conf \ | 13 | test_gns_defaults.conf \ |
14 | test_gns_lookup.conf \ | 14 | test_gns_lookup.conf \ |
15 | test_gns_nick_shorten.conf \ | ||
16 | test_gns_proxy.conf \ | 15 | test_gns_proxy.conf \ |
17 | test_gns_simple_lookup.conf \ | 16 | test_gns_simple_lookup.conf \ |
18 | gns-helper-service-w32.conf \ | 17 | gns-helper-service-w32.conf \ |
@@ -70,8 +69,8 @@ endif | |||
70 | 69 | ||
71 | libexec_PROGRAMS = \ | 70 | libexec_PROGRAMS = \ |
72 | gnunet-service-gns \ | 71 | gnunet-service-gns \ |
73 | $(DO_W32_HELPER) \ | ||
74 | gnunet-dns2gns \ | 72 | gnunet-dns2gns \ |
73 | $(DO_W32_HELPER) \ | ||
75 | $(DO_PROXY) | 74 | $(DO_PROXY) |
76 | 75 | ||
77 | bin_PROGRAMS = \ | 76 | bin_PROGRAMS = \ |
@@ -114,7 +113,6 @@ gnunet_gns_SOURCES = \ | |||
114 | gnunet_gns_LDADD = \ | 113 | gnunet_gns_LDADD = \ |
115 | libgnunetgns.la \ | 114 | libgnunetgns.la \ |
116 | $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ | 115 | $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ |
117 | $(top_builddir)/src/namestore/libgnunetnamestore.la \ | ||
118 | $(top_builddir)/src/identity/libgnunetidentity.la \ | 116 | $(top_builddir)/src/identity/libgnunetidentity.la \ |
119 | $(top_builddir)/src/util/libgnunetutil.la \ | 117 | $(top_builddir)/src/util/libgnunetutil.la \ |
120 | $(GN_LIBINTL) | 118 | $(GN_LIBINTL) |
@@ -134,11 +132,18 @@ gnunet_dns2gns_LDADD = \ | |||
134 | libgnunetgns.la \ | 132 | libgnunetgns.la \ |
135 | $(top_builddir)/src/util/libgnunetutil.la \ | 133 | $(top_builddir)/src/util/libgnunetutil.la \ |
136 | $(top_builddir)/src/identity/libgnunetidentity.la \ | 134 | $(top_builddir)/src/identity/libgnunetidentity.la \ |
137 | $(top_builddir)/src/namestore/libgnunetnamestore.la \ | ||
138 | $(top_builddir)/src/dns/libgnunetdnsparser.la \ | 135 | $(top_builddir)/src/dns/libgnunetdnsparser.la \ |
139 | $(top_builddir)/src/dns/libgnunetdnsstub.la \ | 136 | $(top_builddir)/src/dns/libgnunetdnsstub.la \ |
140 | $(GN_LIBINTL) | 137 | $(GN_LIBINTL) |
141 | 138 | ||
139 | if LINUX | ||
140 | HIJACKBIN = gnunet-dns2gns | ||
141 | install-exec-hook: | ||
142 | $(SUDO_BINARY) setcap 'cap_net_bind_service=+ep' $(DESTDIR)$(libexecdir)/gnunet-dns2gns || true | ||
143 | else | ||
144 | install-exec-hook: | ||
145 | endif | ||
146 | |||
142 | gnunet_gns_proxy_SOURCES = \ | 147 | gnunet_gns_proxy_SOURCES = \ |
143 | gnunet-gns-proxy.c | 148 | gnunet-gns-proxy.c |
144 | gnunet_gns_proxy_CPPFLAGS = $(AM_CPPFLAGS) $(CPP_GNURL) | 149 | gnunet_gns_proxy_CPPFLAGS = $(AM_CPPFLAGS) $(CPP_GNURL) |
@@ -184,8 +189,6 @@ w32nsp_resolve_LDADD = -lws2_32 | |||
184 | gnunet_service_gns_SOURCES = \ | 189 | gnunet_service_gns_SOURCES = \ |
185 | gnunet-service-gns.c \ | 190 | gnunet-service-gns.c \ |
186 | gnunet-service-gns_resolver.c gnunet-service-gns_resolver.h \ | 191 | gnunet-service-gns_resolver.c gnunet-service-gns_resolver.h \ |
187 | gnunet-service-gns_reverser.c gnunet-service-gns_reverser.h \ | ||
188 | gnunet-service-gns_shorten.c gnunet-service-gns_shorten.h \ | ||
189 | gnunet-service-gns_interceptor.c gnunet-service-gns_interceptor.h | 192 | gnunet-service-gns_interceptor.c gnunet-service-gns_interceptor.h |
190 | gnunet_service_gns_LDADD = \ | 193 | gnunet_service_gns_LDADD = \ |
191 | -lm \ | 194 | -lm \ |
@@ -200,7 +203,6 @@ gnunet_service_gns_LDADD = \ | |||
200 | $(top_builddir)/src/dht/libgnunetdht.la \ | 203 | $(top_builddir)/src/dht/libgnunetdht.la \ |
201 | $(top_builddir)/src/tun/libgnunettun.la \ | 204 | $(top_builddir)/src/tun/libgnunettun.la \ |
202 | $(top_builddir)/src/namecache/libgnunetnamecache.la \ | 205 | $(top_builddir)/src/namecache/libgnunetnamecache.la \ |
203 | $(top_builddir)/src/namestore/libgnunetnamestore.la \ | ||
204 | $(USE_VPN) \ | 206 | $(USE_VPN) \ |
205 | $(GN_LIBINTL) | 207 | $(GN_LIBINTL) |
206 | 208 | ||
@@ -254,14 +256,12 @@ check_SCRIPTS = \ | |||
254 | test_gns_gns2dns_lookup.sh \ | 256 | test_gns_gns2dns_lookup.sh \ |
255 | test_gns_dht_lookup.sh\ | 257 | test_gns_dht_lookup.sh\ |
256 | test_gns_delegated_lookup.sh \ | 258 | test_gns_delegated_lookup.sh \ |
257 | test_gns_nick_shorten.sh\ | ||
258 | test_gns_plus_lookup.sh\ | 259 | test_gns_plus_lookup.sh\ |
259 | test_gns_zkey_lookup.sh\ | 260 | test_gns_zkey_lookup.sh\ |
260 | test_gns_rel_expiration.sh\ | 261 | test_gns_rel_expiration.sh\ |
261 | test_gns_soa_lookup.sh\ | 262 | test_gns_soa_lookup.sh\ |
262 | test_gns_revocation.sh\ | 263 | test_gns_revocation.sh\ |
263 | test_gns_cname_lookup.sh \ | 264 | test_gns_cname_lookup.sh |
264 | test_gns_reverse_lookup.sh | ||
265 | 265 | ||
266 | if ENABLE_TEST_RUN | 266 | if ENABLE_TEST_RUN |
267 | if HAVE_SQLITE | 267 | if HAVE_SQLITE |
diff --git a/src/gns/gns.h b/src/gns/gns.h index ca5525f80..d77bf53c6 100644 --- a/src/gns/gns.h +++ b/src/gns/gns.h | |||
@@ -72,51 +72,20 @@ struct LookupMessage | |||
72 | int16_t options GNUNET_PACKED; | 72 | int16_t options GNUNET_PACKED; |
73 | 73 | ||
74 | /** | 74 | /** |
75 | * Is a shorten key attached? | 75 | * Always 0. |
76 | */ | 76 | */ |
77 | int16_t have_key GNUNET_PACKED; | 77 | int16_t reserved GNUNET_PACKED; |
78 | 78 | ||
79 | /** | 79 | /** |
80 | * the type of record to look up | 80 | * the type of record to look up |
81 | */ | 81 | */ |
82 | int32_t type GNUNET_PACKED; | 82 | int32_t type GNUNET_PACKED; |
83 | 83 | ||
84 | /** | ||
85 | * The key for shorten, if @e have_key is set | ||
86 | */ | ||
87 | struct GNUNET_CRYPTO_EcdsaPrivateKey shorten_key; | ||
88 | |||
89 | /* Followed by the zero-terminated name to look up */ | 84 | /* Followed by the zero-terminated name to look up */ |
90 | }; | 85 | }; |
91 | 86 | ||
92 | 87 | ||
93 | /** | 88 | /** |
94 | * Message from client to GNS service to lookup records. | ||
95 | */ | ||
96 | struct ReverseLookupMessage | ||
97 | { | ||
98 | /** | ||
99 | * Header of type #GNUNET_MESSAGE_TYPE_GNS_REVERSE_LOOKUP | ||
100 | */ | ||
101 | struct GNUNET_MessageHeader header; | ||
102 | |||
103 | /** | ||
104 | * Unique identifier for this request (for key collisions). | ||
105 | */ | ||
106 | uint32_t id GNUNET_PACKED; | ||
107 | |||
108 | /** | ||
109 | * Zone that is target for reverse lookup | ||
110 | */ | ||
111 | struct GNUNET_CRYPTO_EcdsaPublicKey zone_pkey; | ||
112 | |||
113 | /** | ||
114 | * Root zone | ||
115 | */ | ||
116 | struct GNUNET_CRYPTO_EcdsaPublicKey root_pkey; | ||
117 | }; | ||
118 | |||
119 | /** | ||
120 | * Message from GNS service to client: new results. | 89 | * Message from GNS service to client: new results. |
121 | */ | 90 | */ |
122 | struct LookupResultMessage | 91 | struct LookupResultMessage |
@@ -140,24 +109,6 @@ struct LookupResultMessage | |||
140 | 109 | ||
141 | }; | 110 | }; |
142 | 111 | ||
143 | /** | ||
144 | * Message from GNS service to client: new results. | ||
145 | */ | ||
146 | struct ReverseLookupResultMessage | ||
147 | { | ||
148 | /** | ||
149 | * Header of type #GNUNET_MESSAGE_TYPE_GNS_REVERSE_LOOKUP_RESULT | ||
150 | */ | ||
151 | struct GNUNET_MessageHeader header; | ||
152 | |||
153 | /** | ||
154 | * Unique identifier for this request (for key collisions). | ||
155 | */ | ||
156 | uint32_t id GNUNET_PACKED; | ||
157 | |||
158 | /* followed by the resulting name of the reverse lookup */ | ||
159 | }; | ||
160 | |||
161 | 112 | ||
162 | GNUNET_NETWORK_STRUCT_END | 113 | GNUNET_NETWORK_STRUCT_END |
163 | 114 | ||
diff --git a/src/gns/gns_api.c b/src/gns/gns_api.c index 5d6158bd4..15a59a4bc 100644 --- a/src/gns/gns_api.c +++ b/src/gns/gns_api.c | |||
@@ -79,49 +79,6 @@ struct GNUNET_GNS_LookupRequest | |||
79 | 79 | ||
80 | }; | 80 | }; |
81 | 81 | ||
82 | /** | ||
83 | * Handle to a lookup request | ||
84 | */ | ||
85 | struct GNUNET_GNS_ReverseLookupRequest | ||
86 | { | ||
87 | |||
88 | /** | ||
89 | * DLL | ||
90 | */ | ||
91 | struct GNUNET_GNS_ReverseLookupRequest *next; | ||
92 | |||
93 | /** | ||
94 | * DLL | ||
95 | */ | ||
96 | struct GNUNET_GNS_ReverseLookupRequest *prev; | ||
97 | |||
98 | /** | ||
99 | * handle to gns | ||
100 | */ | ||
101 | struct GNUNET_GNS_Handle *gns_handle; | ||
102 | |||
103 | /** | ||
104 | * processor to call on lookup result | ||
105 | */ | ||
106 | GNUNET_GNS_ReverseLookupResultProcessor lookup_proc; | ||
107 | |||
108 | /** | ||
109 | * @e lookup_proc closure | ||
110 | */ | ||
111 | void *proc_cls; | ||
112 | |||
113 | /** | ||
114 | * Envelope with the message for this queue entry. | ||
115 | */ | ||
116 | struct GNUNET_MQ_Envelope *env; | ||
117 | |||
118 | /** | ||
119 | * request id | ||
120 | */ | ||
121 | uint32_t r_id; | ||
122 | |||
123 | }; | ||
124 | |||
125 | 82 | ||
126 | /** | 83 | /** |
127 | * Connection to the GNS service. | 84 | * Connection to the GNS service. |
@@ -150,15 +107,6 @@ struct GNUNET_GNS_Handle | |||
150 | struct GNUNET_GNS_LookupRequest *lookup_tail; | 107 | struct GNUNET_GNS_LookupRequest *lookup_tail; |
151 | 108 | ||
152 | /** | 109 | /** |
153 | * Head of linked list of active reverse lookup requests. | ||
154 | */ | ||
155 | struct GNUNET_GNS_ReverseLookupRequest *rev_lookup_head; | ||
156 | |||
157 | /** | ||
158 | * Tail of linked list of active reverse lookup requests. | ||
159 | */ | ||
160 | struct GNUNET_GNS_ReverseLookupRequest *rev_lookup_tail; | ||
161 | /** | ||
162 | * Reconnect task | 110 | * Reconnect task |
163 | */ | 111 | */ |
164 | struct GNUNET_SCHEDULER_Task *reconnect_task; | 112 | struct GNUNET_SCHEDULER_Task *reconnect_task; |
@@ -232,71 +180,13 @@ mq_error_handler (void *cls, | |||
232 | enum GNUNET_MQ_Error error) | 180 | enum GNUNET_MQ_Error error) |
233 | { | 181 | { |
234 | struct GNUNET_GNS_Handle *handle = cls; | 182 | struct GNUNET_GNS_Handle *handle = cls; |
235 | LOG (GNUNET_ERROR_TYPE_WARNING, "Problem with message queue. error: %i\n", | 183 | |
184 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
185 | "Problem with message queue. error: %i\n", | ||
236 | error); | 186 | error); |
237 | force_reconnect (handle); | 187 | force_reconnect (handle); |
238 | } | 188 | } |
239 | 189 | ||
240 | /** | ||
241 | * Check validity of message received from the GNS service | ||
242 | * | ||
243 | * @param cls the `struct GNUNET_GNS_Handle *` | ||
244 | * @param loookup_msg the incoming message | ||
245 | */ | ||
246 | static int | ||
247 | check_rev_result (void *cls, | ||
248 | const struct ReverseLookupResultMessage *lookup_msg) | ||
249 | { | ||
250 | size_t mlen = ntohs (lookup_msg->header.size) - sizeof (*lookup_msg); | ||
251 | char *name; | ||
252 | |||
253 | name = (char*) &lookup_msg[1]; | ||
254 | if ('\0' != name[mlen-1]) | ||
255 | { | ||
256 | GNUNET_break (0); | ||
257 | return GNUNET_SYSERR; | ||
258 | } | ||
259 | return GNUNET_OK; | ||
260 | } | ||
261 | |||
262 | |||
263 | /** | ||
264 | * Handler for messages received from the GNS service | ||
265 | * | ||
266 | * @param cls the `struct GNUNET_GNS_Handle *` | ||
267 | * @param loookup_msg the incoming message | ||
268 | */ | ||
269 | static void | ||
270 | handle_rev_result (void *cls, | ||
271 | const struct ReverseLookupResultMessage *lookup_msg) | ||
272 | { | ||
273 | struct GNUNET_GNS_Handle *handle = cls; | ||
274 | char *name; | ||
275 | uint32_t r_id = ntohl (lookup_msg->id); | ||
276 | struct GNUNET_GNS_ReverseLookupRequest *rlr; | ||
277 | GNUNET_GNS_ReverseLookupResultProcessor proc; | ||
278 | void *proc_cls; | ||
279 | |||
280 | name = (char*)&lookup_msg[1]; | ||
281 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
282 | "Received reverse lookup reply from GNS service (%s)\n", | ||
283 | name); | ||
284 | for (rlr = handle->rev_lookup_head; NULL != rlr; rlr = rlr->next) | ||
285 | if (rlr->r_id == r_id) | ||
286 | break; | ||
287 | if (NULL == rlr) | ||
288 | return; | ||
289 | proc = rlr->lookup_proc; | ||
290 | proc_cls = rlr->proc_cls; | ||
291 | GNUNET_CONTAINER_DLL_remove (handle->rev_lookup_head, | ||
292 | handle->rev_lookup_tail, | ||
293 | rlr); | ||
294 | GNUNET_free (rlr); | ||
295 | proc (proc_cls, | ||
296 | name); | ||
297 | } | ||
298 | |||
299 | |||
300 | 190 | ||
301 | /** | 191 | /** |
302 | * Check validity of message received from the GNS service | 192 | * Check validity of message received from the GNS service |
@@ -382,14 +272,9 @@ reconnect (struct GNUNET_GNS_Handle *handle) | |||
382 | GNUNET_MESSAGE_TYPE_GNS_LOOKUP_RESULT, | 272 | GNUNET_MESSAGE_TYPE_GNS_LOOKUP_RESULT, |
383 | struct LookupResultMessage, | 273 | struct LookupResultMessage, |
384 | handle), | 274 | handle), |
385 | GNUNET_MQ_hd_var_size (rev_result, | ||
386 | GNUNET_MESSAGE_TYPE_GNS_REVERSE_LOOKUP_RESULT, | ||
387 | struct ReverseLookupResultMessage, | ||
388 | handle), | ||
389 | GNUNET_MQ_handler_end () | 275 | GNUNET_MQ_handler_end () |
390 | }; | 276 | }; |
391 | struct GNUNET_GNS_LookupRequest *lh; | 277 | struct GNUNET_GNS_LookupRequest *lh; |
392 | struct GNUNET_GNS_ReverseLookupRequest *rlh; | ||
393 | 278 | ||
394 | GNUNET_assert (NULL == handle->mq); | 279 | GNUNET_assert (NULL == handle->mq); |
395 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 280 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
@@ -404,9 +289,6 @@ reconnect (struct GNUNET_GNS_Handle *handle) | |||
404 | for (lh = handle->lookup_head; NULL != lh; lh = lh->next) | 289 | for (lh = handle->lookup_head; NULL != lh; lh = lh->next) |
405 | GNUNET_MQ_send_copy (handle->mq, | 290 | GNUNET_MQ_send_copy (handle->mq, |
406 | lh->env); | 291 | lh->env); |
407 | for (rlh = handle->rev_lookup_head; NULL != rlh; rlh = rlh->next) | ||
408 | GNUNET_MQ_send_copy (handle->mq, | ||
409 | rlh->env); | ||
410 | } | 292 | } |
411 | 293 | ||
412 | 294 | ||
@@ -452,7 +334,6 @@ GNUNET_GNS_disconnect (struct GNUNET_GNS_Handle *handle) | |||
452 | handle->reconnect_task = NULL; | 334 | handle->reconnect_task = NULL; |
453 | } | 335 | } |
454 | GNUNET_assert (NULL == handle->lookup_head); | 336 | GNUNET_assert (NULL == handle->lookup_head); |
455 | GNUNET_assert (NULL == handle->rev_lookup_head); | ||
456 | GNUNET_free (handle); | 337 | GNUNET_free (handle); |
457 | } | 338 | } |
458 | 339 | ||
@@ -474,22 +355,6 @@ GNUNET_GNS_lookup_cancel (struct GNUNET_GNS_LookupRequest *lr) | |||
474 | GNUNET_free (lr); | 355 | GNUNET_free (lr); |
475 | } | 356 | } |
476 | 357 | ||
477 | /** | ||
478 | * Cancel pending reverse lookup request | ||
479 | * | ||
480 | * @param lr the lookup request to cancel | ||
481 | */ | ||
482 | void | ||
483 | GNUNET_GNS_reverse_lookup_cancel (struct GNUNET_GNS_ReverseLookupRequest *lr) | ||
484 | { | ||
485 | struct GNUNET_GNS_Handle *handle = lr->gns_handle; | ||
486 | |||
487 | GNUNET_CONTAINER_DLL_remove (handle->rev_lookup_head, | ||
488 | handle->rev_lookup_tail, | ||
489 | lr); | ||
490 | GNUNET_MQ_discard (lr->env); | ||
491 | GNUNET_free (lr); | ||
492 | } | ||
493 | 358 | ||
494 | /** | 359 | /** |
495 | * Perform an asynchronous lookup operation on the GNS. | 360 | * Perform an asynchronous lookup operation on the GNS. |
@@ -499,7 +364,6 @@ GNUNET_GNS_reverse_lookup_cancel (struct GNUNET_GNS_ReverseLookupRequest *lr) | |||
499 | * @param zone the zone to start the resolution in | 364 | * @param zone the zone to start the resolution in |
500 | * @param type the record type to look up | 365 | * @param type the record type to look up |
501 | * @param options local options for the lookup | 366 | * @param options local options for the lookup |
502 | * @param shorten_zone_key the private key of the shorten zone (can be NULL) | ||
503 | * @param proc processor to call on result | 367 | * @param proc processor to call on result |
504 | * @param proc_cls closure for @a proc | 368 | * @param proc_cls closure for @a proc |
505 | * @return handle to the get request | 369 | * @return handle to the get request |
@@ -510,7 +374,6 @@ GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle, | |||
510 | const struct GNUNET_CRYPTO_EcdsaPublicKey *zone, | 374 | const struct GNUNET_CRYPTO_EcdsaPublicKey *zone, |
511 | uint32_t type, | 375 | uint32_t type, |
512 | enum GNUNET_GNS_LocalOptions options, | 376 | enum GNUNET_GNS_LocalOptions options, |
513 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *shorten_zone_key, | ||
514 | GNUNET_GNS_LookupResultProcessor proc, | 377 | GNUNET_GNS_LookupResultProcessor proc, |
515 | void *proc_cls) | 378 | void *proc_cls) |
516 | { | 379 | { |
@@ -545,11 +408,6 @@ GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle, | |||
545 | lookup_msg->options = htons ((uint16_t) options); | 408 | lookup_msg->options = htons ((uint16_t) options); |
546 | lookup_msg->zone = *zone; | 409 | lookup_msg->zone = *zone; |
547 | lookup_msg->type = htonl (type); | 410 | lookup_msg->type = htonl (type); |
548 | if (NULL != shorten_zone_key) | ||
549 | { | ||
550 | lookup_msg->have_key = htons (GNUNET_YES); | ||
551 | lookup_msg->shorten_key = *shorten_zone_key; | ||
552 | } | ||
553 | GNUNET_memcpy (&lookup_msg[1], | 411 | GNUNET_memcpy (&lookup_msg[1], |
554 | name, | 412 | name, |
555 | nlen); | 413 | nlen); |
@@ -562,50 +420,4 @@ GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle, | |||
562 | return lr; | 420 | return lr; |
563 | } | 421 | } |
564 | 422 | ||
565 | /** | ||
566 | * Perform an asynchronous reverse lookup operation on the GNS. | ||
567 | * | ||
568 | * @param handle handle to the GNS service | ||
569 | * @param zone_key zone to find a name for | ||
570 | * @param root_key our zone | ||
571 | * @param proc processor to call on result | ||
572 | * @param proc_cls closure for @a proc | ||
573 | * @return handle to the request | ||
574 | */ | ||
575 | struct GNUNET_GNS_ReverseLookupRequest* | ||
576 | GNUNET_GNS_reverse_lookup (struct GNUNET_GNS_Handle *handle, | ||
577 | const struct GNUNET_CRYPTO_EcdsaPublicKey *zone_key, | ||
578 | const struct GNUNET_CRYPTO_EcdsaPublicKey *root_key, | ||
579 | GNUNET_GNS_ReverseLookupResultProcessor proc, | ||
580 | void *proc_cls) | ||
581 | { | ||
582 | /* IPC to shorten gns names, return shorten_handle */ | ||
583 | struct ReverseLookupMessage *rev_lookup_msg; | ||
584 | struct GNUNET_GNS_ReverseLookupRequest *lr; | ||
585 | |||
586 | if ((NULL == zone_key) || (NULL == root_key)) | ||
587 | { | ||
588 | GNUNET_break (0); | ||
589 | return NULL; | ||
590 | } | ||
591 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
592 | "Trying to reverse lookup in GNS\n"); | ||
593 | lr = GNUNET_new (struct GNUNET_GNS_ReverseLookupRequest); | ||
594 | lr->gns_handle = handle; | ||
595 | lr->lookup_proc = proc; | ||
596 | lr->proc_cls = proc_cls; | ||
597 | lr->r_id = handle->r_id_gen++; | ||
598 | lr->env = GNUNET_MQ_msg (rev_lookup_msg, | ||
599 | GNUNET_MESSAGE_TYPE_GNS_REVERSE_LOOKUP); | ||
600 | rev_lookup_msg->id = htonl (lr->r_id); | ||
601 | rev_lookup_msg->zone_pkey = *zone_key; | ||
602 | rev_lookup_msg->root_pkey = *root_key; | ||
603 | GNUNET_CONTAINER_DLL_insert (handle->rev_lookup_head, | ||
604 | handle->rev_lookup_tail, | ||
605 | lr); | ||
606 | if (NULL != handle->mq) | ||
607 | GNUNET_MQ_send_copy (handle->mq, | ||
608 | lr->env); | ||
609 | return lr; | ||
610 | } | ||
611 | /* end of gns_api.c */ | 423 | /* end of gns_api.c */ |
diff --git a/src/gns/gnunet-dns2gns.c b/src/gns/gnunet-dns2gns.c index f58303789..813ecdf8e 100644 --- a/src/gns/gnunet-dns2gns.c +++ b/src/gns/gnunet-dns2gns.c | |||
@@ -138,7 +138,7 @@ static char *dns_ip; | |||
138 | /** | 138 | /** |
139 | * UDP Port we listen on for inbound DNS requests. | 139 | * UDP Port we listen on for inbound DNS requests. |
140 | */ | 140 | */ |
141 | static unsigned int listen_port = 2853; | 141 | static unsigned int listen_port = 53; |
142 | 142 | ||
143 | /** | 143 | /** |
144 | * Which GNS zone do we translate incoming DNS requests to? | 144 | * Which GNS zone do we translate incoming DNS requests to? |
@@ -483,7 +483,6 @@ handle_request (struct GNUNET_NETWORK_Handle *lsock, | |||
483 | &my_zone, | 483 | &my_zone, |
484 | type, | 484 | type, |
485 | GNUNET_NO, | 485 | GNUNET_NO, |
486 | NULL /* no shorten */, | ||
487 | &result_processor, | 486 | &result_processor, |
488 | request); | 487 | request); |
489 | } | 488 | } |
@@ -618,7 +617,7 @@ run_dnsd () | |||
618 | if (NULL != listen_socket4) | 617 | if (NULL != listen_socket4) |
619 | { | 618 | { |
620 | struct sockaddr_in v4; | 619 | struct sockaddr_in v4; |
621 | 620 | ||
622 | memset (&v4, 0, sizeof (v4)); | 621 | memset (&v4, 0, sizeof (v4)); |
623 | v4.sin_family = AF_INET; | 622 | v4.sin_family = AF_INET; |
624 | #if HAVE_SOCKADDR_IN_SIN_LEN | 623 | #if HAVE_SOCKADDR_IN_SIN_LEN |
@@ -641,7 +640,7 @@ run_dnsd () | |||
641 | if (NULL != listen_socket6) | 640 | if (NULL != listen_socket6) |
642 | { | 641 | { |
643 | struct sockaddr_in6 v6; | 642 | struct sockaddr_in6 v6; |
644 | 643 | ||
645 | memset (&v6, 0, sizeof (v6)); | 644 | memset (&v6, 0, sizeof (v6)); |
646 | v6.sin6_family = AF_INET6; | 645 | v6.sin6_family = AF_INET6; |
647 | #if HAVE_SOCKADDR_IN_SIN_LEN | 646 | #if HAVE_SOCKADDR_IN_SIN_LEN |
@@ -797,13 +796,17 @@ main (int argc, | |||
797 | }; | 796 | }; |
798 | int ret; | 797 | int ret; |
799 | 798 | ||
800 | if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, | 799 | if (GNUNET_OK != |
801 | &argc, &argv)) | 800 | GNUNET_STRINGS_get_utf8_args (argc, argv, |
801 | &argc, &argv)) | ||
802 | return 2; | 802 | return 2; |
803 | GNUNET_log_setup ("gnunet-dns2gns", "WARNING", NULL); | 803 | GNUNET_log_setup ("gnunet-dns2gns", |
804 | "WARNING", | ||
805 | NULL); | ||
804 | ret = | 806 | ret = |
805 | (GNUNET_OK == | 807 | (GNUNET_OK == |
806 | GNUNET_PROGRAM_run (argc, argv, "gnunet-dns2gns", | 808 | GNUNET_PROGRAM_run (argc, argv, |
809 | "gnunet-dns2gns", | ||
807 | _("GNUnet DNS-to-GNS proxy (a DNS server)"), | 810 | _("GNUnet DNS-to-GNS proxy (a DNS server)"), |
808 | options, | 811 | options, |
809 | &run, NULL)) ? 0 : 1; | 812 | &run, NULL)) ? 0 : 1; |
diff --git a/src/gns/gnunet-gns-helper-service-w32.c b/src/gns/gnunet-gns-helper-service-w32.c index bfee2b498..a59cc5981 100644 --- a/src/gns/gnunet-gns-helper-service-w32.c +++ b/src/gns/gnunet-gns-helper-service-w32.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2012 GNUnet e.V. | 3 | Copyright (C) 2012, 2017 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -48,6 +48,7 @@ DEFINE_DNS_GUID(SVCID_DNS_TYPE_SRV, 0x0021); | |||
48 | DEFINE_GUID(SVCID_HOSTNAME, 0x0002a800, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); | 48 | DEFINE_GUID(SVCID_HOSTNAME, 0x0002a800, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); |
49 | DEFINE_GUID(SVCID_INET_HOSTADDRBYNAME, 0x0002a803, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); | 49 | DEFINE_GUID(SVCID_INET_HOSTADDRBYNAME, 0x0002a803, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); |
50 | 50 | ||
51 | |||
51 | struct request | 52 | struct request |
52 | { | 53 | { |
53 | /** | 54 | /** |
@@ -60,14 +61,23 @@ struct request | |||
60 | */ | 61 | */ |
61 | struct request *prev; | 62 | struct request *prev; |
62 | 63 | ||
63 | struct GNUNET_SERVER_Client *client; | 64 | /** |
65 | * Client that issued the request | ||
66 | */ | ||
67 | struct GNUNET_SERVICE_Client *client; | ||
68 | |||
64 | GUID sc; | 69 | GUID sc; |
70 | |||
65 | int af; | 71 | int af; |
72 | |||
66 | wchar_t *name; | 73 | wchar_t *name; |
74 | |||
67 | char *u8name; | 75 | char *u8name; |
76 | |||
68 | struct GNUNET_GNS_LookupRequest *lookup_request; | 77 | struct GNUNET_GNS_LookupRequest *lookup_request; |
69 | }; | 78 | }; |
70 | 79 | ||
80 | |||
71 | /** | 81 | /** |
72 | * Head of the doubly-linked list (for cleanup). | 82 | * Head of the doubly-linked list (for cleanup). |
73 | */ | 83 | */ |
@@ -99,14 +109,10 @@ static struct GNUNET_IDENTITY_Handle *identity; | |||
99 | static struct GNUNET_CRYPTO_EcdsaPublicKey gns_master_pubkey; | 109 | static struct GNUNET_CRYPTO_EcdsaPublicKey gns_master_pubkey; |
100 | 110 | ||
101 | /** | 111 | /** |
102 | * Private key of the gns-short ego | ||
103 | */ | ||
104 | static struct GNUNET_CRYPTO_EcdsaPrivateKey gns_short_privkey; | ||
105 | |||
106 | /** | ||
107 | * Set to 1 once egos are obtained. | 112 | * Set to 1 once egos are obtained. |
108 | */ | 113 | */ |
109 | static int got_egos = 0; | 114 | static int got_egos; |
115 | |||
110 | 116 | ||
111 | /** | 117 | /** |
112 | * Task run on shutdown. Cleans up everything. | 118 | * Task run on shutdown. Cleans up everything. |
@@ -117,6 +123,7 @@ static void | |||
117 | do_shutdown (void *cls) | 123 | do_shutdown (void *cls) |
118 | { | 124 | { |
119 | struct request *rq; | 125 | struct request *rq; |
126 | |||
120 | if (NULL != id_op) | 127 | if (NULL != id_op) |
121 | { | 128 | { |
122 | GNUNET_IDENTITY_cancel (id_op); | 129 | GNUNET_IDENTITY_cancel (id_op); |
@@ -130,8 +137,10 @@ do_shutdown (void *cls) | |||
130 | while (NULL != (rq = rq_head)) | 137 | while (NULL != (rq = rq_head)) |
131 | { | 138 | { |
132 | if (NULL != rq->lookup_request) | 139 | if (NULL != rq->lookup_request) |
133 | GNUNET_GNS_lookup_cancel(rq->lookup_request); | 140 | GNUNET_GNS_lookup_cancel (rq->lookup_request); |
134 | GNUNET_CONTAINER_DLL_remove (rq_head, rq_tail, rq); | 141 | GNUNET_CONTAINER_DLL_remove (rq_head, |
142 | rq_tail, | ||
143 | rq); | ||
135 | GNUNET_free_non_null (rq->name); | 144 | GNUNET_free_non_null (rq->name); |
136 | if (rq->u8name) | 145 | if (rq->u8name) |
137 | free (rq->u8name); | 146 | free (rq->u8name); |
@@ -144,133 +153,6 @@ do_shutdown (void *cls) | |||
144 | } | 153 | } |
145 | } | 154 | } |
146 | 155 | ||
147 | /** | ||
148 | * Context for transmitting replies to clients. | ||
149 | */ | ||
150 | struct TransmitCallbackContext | ||
151 | { | ||
152 | |||
153 | /** | ||
154 | * We keep these in a doubly-linked list (for cleanup). | ||
155 | */ | ||
156 | struct TransmitCallbackContext *next; | ||
157 | |||
158 | /** | ||
159 | * We keep these in a doubly-linked list (for cleanup). | ||
160 | */ | ||
161 | struct TransmitCallbackContext *prev; | ||
162 | |||
163 | /** | ||
164 | * The message that we're asked to transmit. | ||
165 | */ | ||
166 | struct GNUNET_MessageHeader *msg; | ||
167 | |||
168 | /** | ||
169 | * Handle for the transmission request. | ||
170 | */ | ||
171 | struct GNUNET_SERVER_TransmitHandle *th; | ||
172 | |||
173 | |||
174 | /** | ||
175 | * Handle for the client to which to send | ||
176 | */ | ||
177 | struct GNUNET_SERVER_Client *client; | ||
178 | }; | ||
179 | |||
180 | |||
181 | /** | ||
182 | * Head of the doubly-linked list (for cleanup). | ||
183 | */ | ||
184 | static struct TransmitCallbackContext *tcc_head; | ||
185 | |||
186 | /** | ||
187 | * Tail of the doubly-linked list (for cleanup). | ||
188 | */ | ||
189 | static struct TransmitCallbackContext *tcc_tail; | ||
190 | |||
191 | /** | ||
192 | * Have we already cleaned up the TCCs and are hence no longer | ||
193 | * willing (or able) to transmit anything to anyone? | ||
194 | */ | ||
195 | static int cleaning_done; | ||
196 | |||
197 | |||
198 | /** | ||
199 | * Function called to notify a client about the socket | ||
200 | * being ready to queue more data. "buf" will be | ||
201 | * NULL and "size" zero if the socket was closed for | ||
202 | * writing in the meantime. | ||
203 | * | ||
204 | * @param cls closure | ||
205 | * @param size number of bytes available in buf | ||
206 | * @param buf where the callee should write the message | ||
207 | * @return number of bytes written to buf | ||
208 | */ | ||
209 | static size_t | ||
210 | transmit_callback (void *cls, size_t size, void *buf) | ||
211 | { | ||
212 | struct TransmitCallbackContext *tcc = cls; | ||
213 | size_t msize; | ||
214 | |||
215 | tcc->th = NULL; | ||
216 | GNUNET_CONTAINER_DLL_remove (tcc_head, tcc_tail, tcc); | ||
217 | msize = ntohs (tcc->msg->size); | ||
218 | if (size == 0) | ||
219 | { | ||
220 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
221 | _("Transmission to client failed!\n")); | ||
222 | GNUNET_free (tcc->msg); | ||
223 | GNUNET_free (tcc); | ||
224 | return 0; | ||
225 | } | ||
226 | GNUNET_assert (size >= msize); | ||
227 | GNUNET_memcpy (buf, tcc->msg, msize); | ||
228 | GNUNET_free (tcc->msg); | ||
229 | GNUNET_free (tcc); | ||
230 | for (tcc = tcc_head; tcc; tcc = tcc->next) | ||
231 | { | ||
232 | if (NULL == tcc->th) | ||
233 | { | ||
234 | tcc->th = GNUNET_SERVER_notify_transmit_ready (tcc->client, | ||
235 | ntohs (tcc->msg->size), | ||
236 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
237 | &transmit_callback, tcc); | ||
238 | break; | ||
239 | } | ||
240 | } | ||
241 | return msize; | ||
242 | } | ||
243 | |||
244 | |||
245 | /** | ||
246 | * Transmit the given message to the client. | ||
247 | * | ||
248 | * @param client target of the message | ||
249 | * @param msg message to transmit, will be freed! | ||
250 | */ | ||
251 | static void | ||
252 | transmit (struct GNUNET_SERVER_Client *client, | ||
253 | struct GNUNET_MessageHeader *msg) | ||
254 | { | ||
255 | struct TransmitCallbackContext *tcc; | ||
256 | |||
257 | if (GNUNET_YES == cleaning_done) | ||
258 | { | ||
259 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
260 | _("Shutdown in progress, aborting transmission.\n")); | ||
261 | GNUNET_free (msg); | ||
262 | return; | ||
263 | } | ||
264 | tcc = GNUNET_new (struct TransmitCallbackContext); | ||
265 | tcc->msg = msg; | ||
266 | tcc->client = client; | ||
267 | tcc->th = GNUNET_SERVER_notify_transmit_ready (client, | ||
268 | ntohs (msg->size), | ||
269 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
270 | &transmit_callback, tcc); | ||
271 | GNUNET_CONTAINER_DLL_insert (tcc_head, tcc_tail, tcc); | ||
272 | } | ||
273 | |||
274 | 156 | ||
275 | #define MarshallPtr(ptr, base, type) \ | 157 | #define MarshallPtr(ptr, base, type) \ |
276 | if (ptr) \ | 158 | if (ptr) \ |
@@ -280,7 +162,6 @@ transmit (struct GNUNET_SERVER_Client *client, | |||
280 | void | 162 | void |
281 | MarshallWSAQUERYSETW (WSAQUERYSETW *qs, GUID *sc) | 163 | MarshallWSAQUERYSETW (WSAQUERYSETW *qs, GUID *sc) |
282 | { | 164 | { |
283 | int i; | ||
284 | MarshallPtr (qs->lpszServiceInstanceName, qs, wchar_t); | 165 | MarshallPtr (qs->lpszServiceInstanceName, qs, wchar_t); |
285 | MarshallPtr (qs->lpServiceClassId, qs, GUID); | 166 | MarshallPtr (qs->lpServiceClassId, qs, GUID); |
286 | MarshallPtr (qs->lpVersion, qs, WSAVERSION); | 167 | MarshallPtr (qs->lpVersion, qs, WSAVERSION); |
@@ -288,7 +169,7 @@ MarshallWSAQUERYSETW (WSAQUERYSETW *qs, GUID *sc) | |||
288 | MarshallPtr (qs->lpszContext, qs, wchar_t); | 169 | MarshallPtr (qs->lpszContext, qs, wchar_t); |
289 | MarshallPtr (qs->lpafpProtocols, qs, AFPROTOCOLS); | 170 | MarshallPtr (qs->lpafpProtocols, qs, AFPROTOCOLS); |
290 | MarshallPtr (qs->lpszQueryString, qs, wchar_t); | 171 | MarshallPtr (qs->lpszQueryString, qs, wchar_t); |
291 | for (i = 0; i < qs->dwNumberOfCsAddrs; i++) | 172 | for (int i = 0; i < qs->dwNumberOfCsAddrs; i++) |
292 | { | 173 | { |
293 | MarshallPtr (qs->lpcsaBuffer[i].LocalAddr.lpSockaddr, qs, SOCKADDR); | 174 | MarshallPtr (qs->lpcsaBuffer[i].LocalAddr.lpSockaddr, qs, SOCKADDR); |
294 | MarshallPtr (qs->lpcsaBuffer[i].RemoteAddr.lpSockaddr, qs, SOCKADDR); | 175 | MarshallPtr (qs->lpcsaBuffer[i].RemoteAddr.lpSockaddr, qs, SOCKADDR); |
@@ -297,12 +178,13 @@ MarshallWSAQUERYSETW (WSAQUERYSETW *qs, GUID *sc) | |||
297 | if (IsEqualGUID (&SVCID_INET_HOSTADDRBYNAME, sc) && qs->lpBlob != NULL && qs->lpBlob->pBlobData != NULL) | 178 | if (IsEqualGUID (&SVCID_INET_HOSTADDRBYNAME, sc) && qs->lpBlob != NULL && qs->lpBlob->pBlobData != NULL) |
298 | { | 179 | { |
299 | struct hostent *he; | 180 | struct hostent *he; |
181 | |||
300 | he = (struct hostent *) qs->lpBlob->pBlobData; | 182 | he = (struct hostent *) qs->lpBlob->pBlobData; |
301 | for (i = 0; he->h_aliases[i] != NULL; i++) | 183 | for (int i = 0; he->h_aliases[i] != NULL; i++) |
302 | MarshallPtr (he->h_aliases[i], he, char); | 184 | MarshallPtr (he->h_aliases[i], he, char); |
303 | MarshallPtr (he->h_aliases, he, char *); | 185 | MarshallPtr (he->h_aliases, he, char *); |
304 | MarshallPtr (he->h_name, he, char); | 186 | MarshallPtr (he->h_name, he, char); |
305 | for (i = 0; he->h_addr_list[i] != NULL; i++) | 187 | for (int i = 0; he->h_addr_list[i] != NULL; i++) |
306 | MarshallPtr (he->h_addr_list[i], he, void); | 188 | MarshallPtr (he->h_addr_list[i], he, void); |
307 | MarshallPtr (he->h_addr_list, he, char *); | 189 | MarshallPtr (he->h_addr_list, he, char *); |
308 | MarshallPtr (qs->lpBlob->pBlobData, qs, void); | 190 | MarshallPtr (qs->lpBlob->pBlobData, qs, void); |
@@ -312,13 +194,16 @@ MarshallWSAQUERYSETW (WSAQUERYSETW *qs, GUID *sc) | |||
312 | 194 | ||
313 | 195 | ||
314 | static void | 196 | static void |
315 | process_lookup_result (void* cls, uint32_t rd_count, | 197 | process_lookup_result (void *cls, |
316 | const struct GNUNET_GNSRECORD_Data *rd) | 198 | uint32_t rd_count, |
199 | const struct GNUNET_GNSRECORD_Data *rd) | ||
317 | { | 200 | { |
201 | struct request *rq = cls; | ||
318 | int i, j, csanum; | 202 | int i, j, csanum; |
319 | struct request *rq = (struct request *) cls; | ||
320 | struct GNUNET_W32RESOLVER_GetMessage *msg; | 203 | struct GNUNET_W32RESOLVER_GetMessage *msg; |
204 | struct GNUNET_MQ_Envelope *msg_env; | ||
321 | struct GNUNET_MessageHeader *msgend; | 205 | struct GNUNET_MessageHeader *msgend; |
206 | struct GNUNET_MQ_Envelope *msgend_env; | ||
322 | WSAQUERYSETW *qs; | 207 | WSAQUERYSETW *qs; |
323 | size_t size; | 208 | size_t size; |
324 | size_t size_recalc; | 209 | size_t size_recalc; |
@@ -327,18 +212,20 @@ process_lookup_result (void* cls, uint32_t rd_count, | |||
327 | size_t blobaddrcount = 0; | 212 | size_t blobaddrcount = 0; |
328 | 213 | ||
329 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 214 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
330 | "Got lookup result with count %u for rq %p with client %p\n", | 215 | "Got lookup result with count %u for rq %p with client %p\n", |
331 | rd_count, rq, rq->client); | 216 | rd_count, |
217 | rq, | ||
218 | rq->client); | ||
332 | rq->lookup_request = NULL; | 219 | rq->lookup_request = NULL; |
333 | 220 | ||
334 | if (rd_count == 0) | 221 | if (0 == rd_count) |
335 | { | 222 | { |
336 | size = sizeof (struct GNUNET_MessageHeader); | 223 | msgend_env = GNUNET_MQ_msg (msgend, GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE); |
337 | msg = GNUNET_malloc (size); | 224 | GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (rq->client), |
338 | msg->header.size = htons (size); | 225 | msgend_env); |
339 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE); | 226 | GNUNET_CONTAINER_DLL_remove (rq_head, |
340 | transmit (rq->client, &msg->header); | 227 | rq_tail, |
341 | GNUNET_CONTAINER_DLL_remove (rq_head, rq_tail, rq); | 228 | rq); |
342 | GNUNET_free_non_null (rq->name); | 229 | GNUNET_free_non_null (rq->name); |
343 | if (rq->u8name) | 230 | if (rq->u8name) |
344 | free (rq->u8name); | 231 | free (rq->u8name); |
@@ -396,9 +283,9 @@ process_lookup_result (void* cls, uint32_t rd_count, | |||
396 | size += blobsize; | 283 | size += blobsize; |
397 | } | 284 | } |
398 | size_recalc = sizeof (struct GNUNET_W32RESOLVER_GetMessage) + sizeof (WSAQUERYSETW); | 285 | size_recalc = sizeof (struct GNUNET_W32RESOLVER_GetMessage) + sizeof (WSAQUERYSETW); |
399 | msg = GNUNET_malloc (size); | 286 | msg_env = GNUNET_MQ_msg_extra (msg, |
400 | msg->header.size = htons (size - sizeof (struct GNUNET_MessageHeader)); | 287 | size - sizeof (struct GNUNET_MessageHeader), |
401 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE); | 288 | GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE); |
402 | msg->af = htonl (rq->af); | 289 | msg->af = htonl (rq->af); |
403 | msg->sc_data1 = htonl (rq->sc.Data1); | 290 | msg->sc_data1 = htonl (rq->sc.Data1); |
404 | msg->sc_data2 = htons (rq->sc.Data2); | 291 | msg->sc_data2 = htons (rq->sc.Data2); |
@@ -557,19 +444,24 @@ process_lookup_result (void* cls, uint32_t rd_count, | |||
557 | } | 444 | } |
558 | he->h_addr_list[j] = NULL; | 445 | he->h_addr_list[j] = NULL; |
559 | } | 446 | } |
560 | msgend = GNUNET_new (struct GNUNET_MessageHeader); | 447 | msgend_env = GNUNET_MQ_msg (msgend, GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE); |
561 | |||
562 | msgend->type = htons (GNUNET_MESSAGE_TYPE_W32RESOLVER_RESPONSE); | ||
563 | msgend->size = htons (sizeof (struct GNUNET_MessageHeader)); | ||
564 | 448 | ||
565 | if ((char *) ptr - (char *) msg != size || size_recalc != size || size_recalc != ((char *) ptr - (char *) msg)) | 449 | if ((char *) ptr - (char *) msg != size || size_recalc != size || size_recalc != ((char *) ptr - (char *) msg)) |
566 | { | 450 | { |
567 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error in WSAQUERYSETW size calc: expected %lu, got %lu (recalc %lu)\n", size, (unsigned long) ((char *) ptr - (char *) msg), size_recalc); | 451 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
452 | "Error in WSAQUERYSETW size calc: expected %u, got %lu (recalc %u)\n", | ||
453 | size, | ||
454 | (unsigned long) ((char *) ptr - (char *) msg), | ||
455 | size_recalc); | ||
568 | } | 456 | } |
569 | MarshallWSAQUERYSETW (qs, &rq->sc); | 457 | MarshallWSAQUERYSETW (qs, &rq->sc); |
570 | transmit (rq->client, &msg->header); | 458 | GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (rq->client), |
571 | transmit (rq->client, msgend); | 459 | msg_env); |
572 | GNUNET_CONTAINER_DLL_remove (rq_head, rq_tail, rq); | 460 | GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (rq->client), |
461 | msgend_env); | ||
462 | GNUNET_CONTAINER_DLL_remove (rq_head, | ||
463 | rq_tail, | ||
464 | rq); | ||
573 | GNUNET_free_non_null (rq->name); | 465 | GNUNET_free_non_null (rq->name); |
574 | if (rq->u8name) | 466 | if (rq->u8name) |
575 | free (rq->u8name); | 467 | free (rq->u8name); |
@@ -578,8 +470,10 @@ process_lookup_result (void* cls, uint32_t rd_count, | |||
578 | 470 | ||
579 | 471 | ||
580 | static void | 472 | static void |
581 | get_ip_from_hostname (struct GNUNET_SERVER_Client *client, | 473 | get_ip_from_hostname (struct GNUNET_SERVICE_Client *client, |
582 | const wchar_t *name, int af, GUID sc) | 474 | const wchar_t *name, |
475 | int af, | ||
476 | GUID sc) | ||
583 | { | 477 | { |
584 | struct request *rq; | 478 | struct request *rq; |
585 | char *hostname; | 479 | char *hostname; |
@@ -610,10 +504,19 @@ get_ip_from_hostname (struct GNUNET_SERVER_Client *client, | |||
610 | else | 504 | else |
611 | { | 505 | { |
612 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 506 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
613 | "Unknown GUID: %08X-%04X-%04X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n", | 507 | "Unknown GUID: %08lX-%04X-%04X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n", |
614 | sc.Data1, sc.Data2, sc.Data3, sc.Data4[0], sc.Data4[1], sc.Data4[2], | 508 | sc.Data1, |
615 | sc.Data4[3], sc.Data4[4], sc.Data4[5], sc.Data4[6], sc.Data4[7]); | 509 | sc.Data2, |
616 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 510 | sc.Data3, |
511 | sc.Data4[0], | ||
512 | sc.Data4[1], | ||
513 | sc.Data4[2], | ||
514 | sc.Data4[3], | ||
515 | sc.Data4[4], | ||
516 | sc.Data4[5], | ||
517 | sc.Data4[6], | ||
518 | sc.Data4[7]); | ||
519 | GNUNET_SERVICE_client_drop (client); | ||
617 | return; | 520 | return; |
618 | } | 521 | } |
619 | 522 | ||
@@ -640,24 +543,31 @@ get_ip_from_hostname (struct GNUNET_SERVER_Client *client, | |||
640 | if (namelen) | 543 | if (namelen) |
641 | { | 544 | { |
642 | rq->name = GNUNET_malloc ((namelen + 1) * sizeof (wchar_t)); | 545 | rq->name = GNUNET_malloc ((namelen + 1) * sizeof (wchar_t)); |
643 | GNUNET_memcpy (rq->name, name, (namelen + 1) * sizeof (wchar_t)); | 546 | GNUNET_memcpy (rq->name, |
547 | name, | ||
548 | (namelen + 1) * sizeof (wchar_t)); | ||
644 | rq->u8name = hostname; | 549 | rq->u8name = hostname; |
645 | } | 550 | } |
646 | 551 | ||
647 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 552 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
648 | "Launching a lookup for client %p with rq %p\n", | 553 | "Launching a lookup for client %p with rq %p\n", |
649 | client, rq); | 554 | client, |
650 | 555 | rq); | |
651 | rq->lookup_request = GNUNET_GNS_lookup (gns, hostname, &gns_master_pubkey, | 556 | rq->lookup_request = GNUNET_GNS_lookup (gns, |
652 | rtype, GNUNET_NO /* Use DHT */, &gns_short_privkey, &process_lookup_result, | 557 | hostname, |
653 | rq); | 558 | &gns_master_pubkey, |
654 | 559 | rtype, | |
560 | GNUNET_NO /* Use DHT */, | ||
561 | &process_lookup_result, | ||
562 | rq); | ||
655 | if (NULL != rq->lookup_request) | 563 | if (NULL != rq->lookup_request) |
656 | { | 564 | { |
657 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 565 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
658 | "Lookup launched, waiting for a reply\n"); | 566 | "Lookup launched, waiting for a reply\n"); |
659 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 567 | GNUNET_SERVICE_client_continue (client); |
660 | GNUNET_CONTAINER_DLL_insert (rq_head, rq_tail, rq); | 568 | GNUNET_CONTAINER_DLL_insert (rq_head, |
569 | rq_tail, | ||
570 | rq); | ||
661 | } | 571 | } |
662 | else | 572 | else |
663 | { | 573 | { |
@@ -667,110 +577,105 @@ get_ip_from_hostname (struct GNUNET_SERVER_Client *client, | |||
667 | if (rq->u8name) | 577 | if (rq->u8name) |
668 | free (rq->u8name); | 578 | free (rq->u8name); |
669 | GNUNET_free (rq); | 579 | GNUNET_free (rq); |
670 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 580 | GNUNET_SERVICE_client_drop (client); |
671 | } | 581 | } |
672 | } | 582 | } |
673 | 583 | ||
674 | 584 | ||
675 | /** | 585 | /** |
676 | * Handle GET-message. | 586 | * Check GET-message. |
677 | * | 587 | * |
678 | * @param cls closure | 588 | * @param cls identification of the client |
679 | * @param client identification of the client | 589 | * @param msg the actual message |
680 | * @param message the actual message | 590 | * @return #GNUNET_OK if @a msg is well-formed |
681 | */ | 591 | */ |
682 | static void | 592 | static int |
683 | handle_get (void *cls, struct GNUNET_SERVER_Client *client, | 593 | check_get (void *cls, |
684 | const struct GNUNET_MessageHeader *message) | 594 | const struct GNUNET_W32RESOLVER_GetMessage *msg) |
685 | { | 595 | { |
686 | uint16_t msize; | ||
687 | const struct GNUNET_W32RESOLVER_GetMessage *msg; | ||
688 | GUID sc; | ||
689 | uint16_t size; | 596 | uint16_t size; |
690 | int i; | ||
691 | const wchar_t *hostname; | 597 | const wchar_t *hostname; |
692 | int af; | ||
693 | |||
694 | if (!got_egos) | ||
695 | { | ||
696 | /* | ||
697 | * FIXME: be done with GNUNET_OK, put the get request into a queue? | ||
698 | * or postpone GNUNET_SERVER_add_handlers() until egos are obtained? | ||
699 | */ | ||
700 | GNUNET_SERVER_receive_done (client, GNUNET_NO); | ||
701 | return; | ||
702 | } | ||
703 | 598 | ||
704 | msize = ntohs (message->size); | 599 | if (! got_egos) |
705 | if (msize <= sizeof (struct GNUNET_W32RESOLVER_GetMessage)) | ||
706 | { | 600 | { |
707 | GNUNET_break (0); | 601 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
708 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 602 | _("Not ready to process requests, lacking ego data\n")); |
709 | return; | 603 | return GNUNET_SYSERR; |
710 | } | 604 | } |
711 | msg = (const struct GNUNET_W32RESOLVER_GetMessage *) message; | 605 | size = ntohs (msg->header.size) - sizeof (struct GNUNET_W32RESOLVER_GetMessage); |
712 | size = msize - sizeof (struct GNUNET_W32RESOLVER_GetMessage); | ||
713 | af = ntohl (msg->af); | ||
714 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
715 | "Got NBO GUID: %08X-%04X-%04X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n", | ||
716 | msg->sc_data1, msg->sc_data2, msg->sc_data3, msg->sc_data4[0], msg->sc_data4[1], | ||
717 | msg->sc_data4[2], msg->sc_data4[3], msg->sc_data4[4], msg->sc_data4[5], | ||
718 | msg->sc_data4[6], msg->sc_data4[7]); | ||
719 | sc.Data1 = ntohl (msg->sc_data1); | ||
720 | sc.Data2 = ntohs (msg->sc_data2); | ||
721 | sc.Data3 = ntohs (msg->sc_data3); | ||
722 | for (i = 0; i < 8; i++) | ||
723 | sc.Data4[i] = msg->sc_data4[i]; | ||
724 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
725 | "Got GUID: %08X-%04X-%04X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n", | ||
726 | sc.Data1, sc.Data2, sc.Data3, sc.Data4[0], sc.Data4[1], sc.Data4[2], | ||
727 | sc.Data4[3], sc.Data4[4], sc.Data4[5], sc.Data4[6], sc.Data4[7]); | ||
728 | |||
729 | hostname = (const wchar_t *) &msg[1]; | 606 | hostname = (const wchar_t *) &msg[1]; |
730 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "name of %u bytes (last word is 0x%0X): %*S\n", | ||
731 | size, hostname[size / 2 - 2], size / 2, hostname); | ||
732 | if (hostname[size / 2 - 1] != L'\0') | 607 | if (hostname[size / 2 - 1] != L'\0') |
733 | { | 608 | { |
734 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "name of length %u, not 0-terminated (%d-th word is 0x%0X): %*S\n", | ||
735 | size, size / 2 - 1, hostname[size / 2 - 1], size, hostname); | ||
736 | GNUNET_break (0); | 609 | GNUNET_break (0); |
737 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 610 | return GNUNET_SYSERR; |
738 | return; | ||
739 | } | 611 | } |
740 | get_ip_from_hostname (client, hostname, af, sc); | 612 | return GNUNET_OK; |
741 | } | 613 | } |
742 | 614 | ||
743 | 615 | ||
744 | /** | 616 | /** |
745 | * Method called to with the ego we are to use for shortening | 617 | * Handle GET-message. |
746 | * during the lookup. | ||
747 | * | 618 | * |
748 | * @param cls closure (NULL, unused) | 619 | * @param cls identification of the client |
749 | * @param ego ego handle, NULL if not found | 620 | * @param msg the actual message |
750 | * @param ctx context for application to store data for this ego | ||
751 | * (during the lifetime of this process, initially NULL) | ||
752 | * @param name name assigned by the user for this ego, | ||
753 | * NULL if the user just deleted the ego and it | ||
754 | * must thus no longer be used | ||
755 | */ | 621 | */ |
756 | static void | 622 | static void |
757 | identity_shorten_cb (void *cls, | 623 | handle_get (void *cls, |
758 | struct GNUNET_IDENTITY_Ego *ego, | 624 | const struct GNUNET_W32RESOLVER_GetMessage *msg) |
759 | void **ctx, | ||
760 | const char *name) | ||
761 | { | 625 | { |
762 | id_op = NULL; | 626 | struct GNUNET_SERVICE_Client *client = cls; |
763 | if (NULL == ego) | 627 | GUID sc; |
764 | { | 628 | uint16_t size; |
765 | fprintf (stderr, | 629 | const wchar_t *hostname; |
766 | _("Ego for `gns-short' not found. This is not really fatal, but i'll pretend that it is and refuse to perform a lookup. Did you run gnunet-gns-import.sh?\n")); | 630 | int af; |
767 | GNUNET_SCHEDULER_shutdown (); | 631 | |
768 | return; | 632 | size = ntohs (msg->header.size) - sizeof (struct GNUNET_W32RESOLVER_GetMessage); |
769 | } | 633 | af = ntohl (msg->af); |
770 | gns_short_privkey = *GNUNET_IDENTITY_ego_get_private_key (ego); | 634 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
771 | got_egos = 1; | 635 | "Got NBO GUID: %08X-%04X-%04X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n", |
636 | msg->sc_data1, | ||
637 | msg->sc_data2, | ||
638 | msg->sc_data3, | ||
639 | msg->sc_data4[0], | ||
640 | msg->sc_data4[1], | ||
641 | msg->sc_data4[2], | ||
642 | msg->sc_data4[3], | ||
643 | msg->sc_data4[4], | ||
644 | msg->sc_data4[5], | ||
645 | msg->sc_data4[6], | ||
646 | msg->sc_data4[7]); | ||
647 | sc.Data1 = ntohl (msg->sc_data1); | ||
648 | sc.Data2 = ntohs (msg->sc_data2); | ||
649 | sc.Data3 = ntohs (msg->sc_data3); | ||
650 | for (int i = 0; i < 8; i++) | ||
651 | sc.Data4[i] = msg->sc_data4[i]; | ||
652 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
653 | "Got GUID: %08lX-%04X-%04X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n", | ||
654 | sc.Data1, | ||
655 | sc.Data2, | ||
656 | sc.Data3, | ||
657 | sc.Data4[0], | ||
658 | sc.Data4[1], | ||
659 | sc.Data4[2], | ||
660 | sc.Data4[3], | ||
661 | sc.Data4[4], | ||
662 | sc.Data4[5], | ||
663 | sc.Data4[6], | ||
664 | sc.Data4[7]); | ||
665 | hostname = (const wchar_t *) &msg[1]; | ||
666 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
667 | "Name of %u bytes (last word is 0x%0X): %*S\n", | ||
668 | size, | ||
669 | hostname[size / 2 - 2], | ||
670 | size / 2, | ||
671 | hostname); | ||
672 | get_ip_from_hostname (client, | ||
673 | hostname, | ||
674 | af, | ||
675 | sc); | ||
772 | } | 676 | } |
773 | 677 | ||
678 | |||
774 | /** | 679 | /** |
775 | * Method called to with the ego we are to use for the lookup, | 680 | * Method called to with the ego we are to use for the lookup, |
776 | * when the ego is the one for the default master zone. | 681 | * when the ego is the one for the default master zone. |
@@ -785,22 +690,21 @@ identity_shorten_cb (void *cls, | |||
785 | */ | 690 | */ |
786 | static void | 691 | static void |
787 | identity_master_cb (void *cls, | 692 | identity_master_cb (void *cls, |
788 | struct GNUNET_IDENTITY_Ego *ego, | 693 | struct GNUNET_IDENTITY_Ego *ego, |
789 | void **ctx, | 694 | void **ctx, |
790 | const char *name) | 695 | const char *name) |
791 | { | 696 | { |
792 | id_op = NULL; | 697 | id_op = NULL; |
793 | if (NULL == ego) | 698 | if (NULL == ego) |
794 | { | 699 | { |
795 | fprintf (stderr, | 700 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
796 | _("Ego for `gns-master' not found, cannot perform lookup. Did you run gnunet-gns-import.sh?\n")); | 701 | _("Ego for `gns-master' not found, cannot perform lookup. Did you run gnunet-gns-import.sh?\n")); |
797 | GNUNET_SCHEDULER_shutdown (); | 702 | GNUNET_SCHEDULER_shutdown (); |
798 | return; | 703 | return; |
799 | } | 704 | } |
800 | GNUNET_IDENTITY_ego_get_public_key (ego, &gns_master_pubkey); | 705 | GNUNET_IDENTITY_ego_get_public_key (ego, |
801 | id_op = GNUNET_IDENTITY_get (identity, "gns-short", &identity_shorten_cb, | 706 | &gns_master_pubkey); |
802 | NULL); | 707 | got_egos = 1; |
803 | GNUNET_assert (NULL != id_op); | ||
804 | } | 708 | } |
805 | 709 | ||
806 | 710 | ||
@@ -808,59 +712,90 @@ identity_master_cb (void *cls, | |||
808 | * Start up gns-helper-w32 service. | 712 | * Start up gns-helper-w32 service. |
809 | * | 713 | * |
810 | * @param cls closure | 714 | * @param cls closure |
811 | * @param server the initialized server | ||
812 | * @param cfg configuration to use | 715 | * @param cfg configuration to use |
716 | * @param service the initialized service | ||
813 | */ | 717 | */ |
814 | static void | 718 | static void |
815 | run (void *cls, struct GNUNET_SERVER_Handle *server, | 719 | run (void *cls, |
816 | const struct GNUNET_CONFIGURATION_Handle *cfg) | 720 | const struct GNUNET_CONFIGURATION_Handle *cfg, |
721 | struct GNUNET_SERVICE_Handle *service) | ||
817 | { | 722 | { |
818 | static const struct GNUNET_SERVER_MessageHandler handlers[] = { | ||
819 | {&handle_get, NULL, GNUNET_MESSAGE_TYPE_W32RESOLVER_REQUEST, 0}, | ||
820 | {NULL, NULL, 0, 0} | ||
821 | }; | ||
822 | |||
823 | gns = GNUNET_GNS_connect (cfg); | 723 | gns = GNUNET_GNS_connect (cfg); |
824 | if (NULL == gns) | 724 | if (NULL == gns) |
825 | { | 725 | { |
826 | fprintf (stderr, _("Failed to connect to GNS\n")); | 726 | fprintf (stderr, |
727 | _("Failed to connect to GNS\n")); | ||
827 | GNUNET_SCHEDULER_shutdown (); | 728 | GNUNET_SCHEDULER_shutdown (); |
828 | return; | 729 | return; |
829 | } | 730 | } |
830 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, | 731 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, |
831 | NULL); | 732 | NULL); |
832 | 733 | identity = GNUNET_IDENTITY_connect (cfg, | |
833 | identity = GNUNET_IDENTITY_connect (cfg, NULL, NULL); | 734 | NULL, |
735 | NULL); | ||
834 | if (NULL == identity) | 736 | if (NULL == identity) |
835 | { | 737 | { |
836 | fprintf (stderr, _("Failed to connect to identity service\n")); | 738 | fprintf (stderr, |
739 | _("Failed to connect to identity service\n")); | ||
837 | GNUNET_SCHEDULER_shutdown (); | 740 | GNUNET_SCHEDULER_shutdown (); |
838 | return; | 741 | return; |
839 | } | 742 | } |
840 | 743 | id_op = GNUNET_IDENTITY_get (identity, | |
841 | id_op = GNUNET_IDENTITY_get (identity, "gns-master", &identity_master_cb, | 744 | "gns-master", |
842 | NULL); | 745 | &identity_master_cb, |
746 | NULL); | ||
843 | GNUNET_assert (NULL != id_op); | 747 | GNUNET_assert (NULL != id_op); |
844 | |||
845 | GNUNET_SERVER_add_handlers (server, handlers); | ||
846 | } | 748 | } |
847 | 749 | ||
848 | 750 | ||
849 | /** | 751 | /** |
850 | * The main function for gns-helper-w32. | 752 | * Handle client connecting to the service. |
851 | * | 753 | * |
852 | * @param argc number of arguments from the command line | 754 | * @param cls NULL |
853 | * @param argv command line arguments | 755 | * @param client the new client |
854 | * @return 0 ok, 1 on error | 756 | * @param mq the message queue of @a client |
757 | * @return @a client | ||
855 | */ | 758 | */ |
856 | int | 759 | static void * |
857 | main (int argc, char *const *argv) | 760 | client_connect_cb (void *cls, |
761 | struct GNUNET_SERVICE_Client *client, | ||
762 | struct GNUNET_MQ_Handle *mq) | ||
858 | { | 763 | { |
859 | int ret; | 764 | return client; |
765 | } | ||
860 | 766 | ||
861 | ret = GNUNET_SERVICE_run (argc, argv, "gns-helper-service-w32", | 767 | |
862 | GNUNET_SERVICE_OPTION_NONE, &run, NULL); | 768 | /** |
863 | return (GNUNET_OK == ret) ? 0 : 1; | 769 | * Callback called when a client disconnected from the service |
770 | * | ||
771 | * @param cls closure for the service | ||
772 | * @param c the client that disconnected | ||
773 | * @param internal_cls should be equal to @a c | ||
774 | */ | ||
775 | static void | ||
776 | client_disconnect_cb (void *cls, | ||
777 | struct GNUNET_SERVICE_Client *client, | ||
778 | void *internal_cls) | ||
779 | { | ||
780 | GNUNET_assert (internal_cls == client); | ||
864 | } | 781 | } |
865 | 782 | ||
783 | |||
784 | /** | ||
785 | * Define "main" method using service macro. | ||
786 | */ | ||
787 | GNUNET_SERVICE_MAIN | ||
788 | ("gns-helper-service-w32", | ||
789 | GNUNET_SERVICE_OPTION_NONE, | ||
790 | &run, | ||
791 | &client_connect_cb, | ||
792 | &client_disconnect_cb, | ||
793 | NULL, | ||
794 | GNUNET_MQ_hd_var_size (get, | ||
795 | GNUNET_MESSAGE_TYPE_W32RESOLVER_REQUEST, | ||
796 | struct GNUNET_W32RESOLVER_GetMessage, | ||
797 | NULL), | ||
798 | GNUNET_MQ_handler_end()); | ||
799 | |||
800 | |||
866 | /* end of gnunet-gns-helper-service-w32.c */ | 801 | /* end of gnunet-gns-helper-service-w32.c */ |
diff --git a/src/gns/gnunet-gns-import.c b/src/gns/gnunet-gns-import.c index e98babfa8..49f6e495f 100644 --- a/src/gns/gnunet-gns-import.c +++ b/src/gns/gnunet-gns-import.c | |||
@@ -224,45 +224,52 @@ zone_iterator (void *cls, | |||
224 | else if (0 == strcmp (rname, "pin")) | 224 | else if (0 == strcmp (rname, "pin")) |
225 | check_pkey (rd_len, rd, pin_zone_pkey, &found_pin_rec); | 225 | check_pkey (rd_len, rd, pin_zone_pkey, &found_pin_rec); |
226 | } | 226 | } |
227 | if (NULL == rname && 0 == rd_len && NULL == rd) | 227 | GNUNET_NAMESTORE_zone_iterator_next (list_it); |
228 | } | ||
229 | |||
230 | static void | ||
231 | zone_iteration_error (void *cls) | ||
232 | { | ||
233 | enum GNUNET_OS_ProcessStatusType st; | ||
234 | unsigned long code; | ||
235 | if (!found_private_rec) | ||
228 | { | 236 | { |
229 | enum GNUNET_OS_ProcessStatusType st; | 237 | if (0 != run_process_and_wait (GNUNET_NO, GNUNET_OS_INHERIT_STD_OUT_AND_ERR, NULL, NULL, &st, &code, |
230 | unsigned long code; | 238 | "gnunet-namestore", |
231 | if (!found_private_rec) | 239 | "gnunet-namestore", "-z", "master-zone", "-a", "-e", "never", "-n", "private", "-p", "-t", "PKEY", "-V", private_zone_pkey, NULL)) |
232 | { | 240 | { |
233 | if (0 != run_process_and_wait (GNUNET_NO, GNUNET_OS_INHERIT_STD_OUT_AND_ERR, NULL, NULL, &st, &code, | 241 | ret = 8; |
234 | "gnunet-namestore", | 242 | return; |
235 | "gnunet-namestore", "-z", "master-zone", "-a", "-e", "never", "-n", "private", "-p", "-t", "PKEY", "-V", private_zone_pkey, NULL)) | ||
236 | { | ||
237 | ret = 8; | ||
238 | return; | ||
239 | } | ||
240 | } | 243 | } |
241 | if (!found_short_rec) | 244 | } |
245 | if (!found_short_rec) | ||
246 | { | ||
247 | if (0 != run_process_and_wait (GNUNET_NO, GNUNET_OS_INHERIT_STD_OUT_AND_ERR, NULL, NULL, &st, &code, | ||
248 | "gnunet-namestore", | ||
249 | "gnunet-namestore", "-z", "master-zone", "-a", "-e", "never", "-n", "short", "-p", "-t", "PKEY", "-V", short_zone_pkey, NULL)) | ||
242 | { | 250 | { |
243 | if (0 != run_process_and_wait (GNUNET_NO, GNUNET_OS_INHERIT_STD_OUT_AND_ERR, NULL, NULL, &st, &code, | 251 | ret = 9; |
244 | "gnunet-namestore", | 252 | return; |
245 | "gnunet-namestore", "-z", "master-zone", "-a", "-e", "never", "-n", "short", "-p", "-t", "PKEY", "-V", short_zone_pkey, NULL)) | ||
246 | { | ||
247 | ret = 9; | ||
248 | return; | ||
249 | } | ||
250 | } | 253 | } |
251 | if (!found_pin_rec) | 254 | } |
255 | if (!found_pin_rec) | ||
256 | { | ||
257 | if (0 != run_process_and_wait (GNUNET_NO, GNUNET_OS_INHERIT_STD_OUT_AND_ERR, NULL, NULL, &st, &code, | ||
258 | "gnunet-namestore", | ||
259 | "gnunet-namestore", "-z", "master-zone", "-a", "-e", "never", "-n", "pin", "-p", "-t", "PKEY", "-V", pin_zone_pkey, NULL)) | ||
252 | { | 260 | { |
253 | if (0 != run_process_and_wait (GNUNET_NO, GNUNET_OS_INHERIT_STD_OUT_AND_ERR, NULL, NULL, &st, &code, | 261 | ret = 10; |
254 | "gnunet-namestore", | 262 | return; |
255 | "gnunet-namestore", "-z", "master-zone", "-a", "-e", "never", "-n", "pin", "-p", "-t", "PKEY", "-V", pin_zone_pkey, NULL)) | ||
256 | { | ||
257 | ret = 10; | ||
258 | return; | ||
259 | } | ||
260 | } | 263 | } |
261 | list_it = NULL; | ||
262 | GNUNET_SCHEDULER_shutdown (); | ||
263 | return; | ||
264 | } | 264 | } |
265 | GNUNET_NAMESTORE_zone_iterator_next (list_it); | 265 | list_it = NULL; |
266 | GNUNET_SCHEDULER_shutdown (); | ||
267 | } | ||
268 | |||
269 | |||
270 | static void | ||
271 | zone_iteration_finished (void *cls) | ||
272 | { | ||
266 | } | 273 | } |
267 | 274 | ||
268 | 275 | ||
@@ -317,7 +324,7 @@ get_ego (void *cls, | |||
317 | return; | 324 | return; |
318 | } | 325 | } |
319 | list_it = GNUNET_NAMESTORE_zone_iteration_start (ns, | 326 | list_it = GNUNET_NAMESTORE_zone_iteration_start (ns, |
320 | &master_pk, &zone_iterator, NULL); | 327 | &master_pk, &zone_iteration_error, NULL, &zone_iterator, NULL, &zone_iteration_finished, NULL); |
321 | if (NULL == list_it) | 328 | if (NULL == list_it) |
322 | { | 329 | { |
323 | ret = 12; | 330 | ret = 12; |
diff --git a/src/gns/gnunet-gns-proxy.c b/src/gns/gnunet-gns-proxy.c index 3a38970a8..6eb87a95e 100644 --- a/src/gns/gnunet-gns-proxy.c +++ b/src/gns/gnunet-gns-proxy.c | |||
@@ -606,7 +606,7 @@ struct Socks5Request | |||
606 | * Headers from response | 606 | * Headers from response |
607 | */ | 607 | */ |
608 | struct HttpResponseHeader *header_tail; | 608 | struct HttpResponseHeader *header_tail; |
609 | 609 | ||
610 | /** | 610 | /** |
611 | * SSL Certificate status | 611 | * SSL Certificate status |
612 | */ | 612 | */ |
@@ -695,16 +695,6 @@ static struct Socks5Request *s5r_tail; | |||
695 | static struct GNUNET_CRYPTO_EcdsaPublicKey local_gns_zone; | 695 | static struct GNUNET_CRYPTO_EcdsaPublicKey local_gns_zone; |
696 | 696 | ||
697 | /** | 697 | /** |
698 | * The users local shorten zone | ||
699 | */ | ||
700 | static struct GNUNET_CRYPTO_EcdsaPrivateKey local_shorten_zone; | ||
701 | |||
702 | /** | ||
703 | * Is shortening enabled? | ||
704 | */ | ||
705 | static int do_shorten; | ||
706 | |||
707 | /** | ||
708 | * The CA for SSL certificate generation | 698 | * The CA for SSL certificate generation |
709 | */ | 699 | */ |
710 | static struct ProxyCA proxy_ca; | 700 | static struct ProxyCA proxy_ca; |
@@ -873,7 +863,7 @@ check_ssl_certificate (struct Socks5Request *s5r) | |||
873 | gnutls_x509_crt_t x509_cert; | 863 | gnutls_x509_crt_t x509_cert; |
874 | int rc; | 864 | int rc; |
875 | const char *name; | 865 | const char *name; |
876 | 866 | ||
877 | s5r->ssl_checked = GNUNET_YES; | 867 | s5r->ssl_checked = GNUNET_YES; |
878 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "XXXXXX\n"); | 868 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "XXXXXX\n"); |
879 | if (CURLE_OK != | 869 | if (CURLE_OK != |
@@ -1039,7 +1029,7 @@ curl_check_hdr (void *buffer, size_t size, size_t nmemb, void *cls) | |||
1039 | size_t delta_cdomain; | 1029 | size_t delta_cdomain; |
1040 | int domain_matched; | 1030 | int domain_matched; |
1041 | char *tok; | 1031 | char *tok; |
1042 | 1032 | ||
1043 | /* first, check SSL certificate */ | 1033 | /* first, check SSL certificate */ |
1044 | if ((GNUNET_YES != s5r->ssl_checked) && | 1034 | if ((GNUNET_YES != s5r->ssl_checked) && |
1045 | (HTTPS_PORT == s5r->port)) | 1035 | (HTTPS_PORT == s5r->port)) |
@@ -1047,7 +1037,7 @@ curl_check_hdr (void *buffer, size_t size, size_t nmemb, void *cls) | |||
1047 | if (GNUNET_OK != check_ssl_certificate (s5r)) | 1037 | if (GNUNET_OK != check_ssl_certificate (s5r)) |
1048 | return 0; | 1038 | return 0; |
1049 | } | 1039 | } |
1050 | 1040 | ||
1051 | ndup = GNUNET_strndup (buffer, bytes); | 1041 | ndup = GNUNET_strndup (buffer, bytes); |
1052 | hdr_type = strtok (ndup, ":"); | 1042 | hdr_type = strtok (ndup, ":"); |
1053 | if (NULL == hdr_type) | 1043 | if (NULL == hdr_type) |
@@ -1287,7 +1277,7 @@ curl_upload_cb (void *buf, size_t size, size_t nmemb, void *cls) | |||
1287 | struct Socks5Request *s5r = cls; | 1277 | struct Socks5Request *s5r = cls; |
1288 | size_t len = size * nmemb; | 1278 | size_t len = size * nmemb; |
1289 | size_t to_copy; | 1279 | size_t to_copy; |
1290 | 1280 | ||
1291 | if ( (0 == s5r->io_len) && | 1281 | if ( (0 == s5r->io_len) && |
1292 | (SOCKS5_SOCKET_UPLOAD_DONE != s5r->state) ) | 1282 | (SOCKS5_SOCKET_UPLOAD_DONE != s5r->state) ) |
1293 | { | 1283 | { |
@@ -1763,7 +1753,7 @@ create_response (void *cls, | |||
1763 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1753 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1764 | "Processing %u bytes UPLOAD\n", | 1754 | "Processing %u bytes UPLOAD\n", |
1765 | (unsigned int) *upload_data_size); | 1755 | (unsigned int) *upload_data_size); |
1766 | 1756 | ||
1767 | /* FIXME: This must be set or a header with Transfer-Encoding: chunked. Else | 1757 | /* FIXME: This must be set or a header with Transfer-Encoding: chunked. Else |
1768 | * upload callback is not called! | 1758 | * upload callback is not called! |
1769 | */ | 1759 | */ |
@@ -2827,7 +2817,6 @@ do_s5r_read (void *cls) | |||
2827 | &local_gns_zone, | 2817 | &local_gns_zone, |
2828 | GNUNET_DNSPARSER_TYPE_A, | 2818 | GNUNET_DNSPARSER_TYPE_A, |
2829 | GNUNET_NO /* only cached */, | 2819 | GNUNET_NO /* only cached */, |
2830 | (GNUNET_YES == do_shorten) ? &local_shorten_zone : NULL, | ||
2831 | &handle_gns_result, | 2820 | &handle_gns_result, |
2832 | s5r); | 2821 | s5r); |
2833 | break; | 2822 | break; |
@@ -3141,46 +3130,6 @@ run_cont () | |||
3141 | 3130 | ||
3142 | 3131 | ||
3143 | /** | 3132 | /** |
3144 | * Method called to inform about the egos of the shorten zone of this peer. | ||
3145 | * | ||
3146 | * When used with #GNUNET_IDENTITY_create or #GNUNET_IDENTITY_get, | ||
3147 | * this function is only called ONCE, and 'NULL' being passed in | ||
3148 | * @a ego does indicate an error (i.e. name is taken or no default | ||
3149 | * value is known). If @a ego is non-NULL and if '*ctx' | ||
3150 | * is set in those callbacks, the value WILL be passed to a subsequent | ||
3151 | * call to the identity callback of #GNUNET_IDENTITY_connect (if | ||
3152 | * that one was not NULL). | ||
3153 | * | ||
3154 | * @param cls closure, NULL | ||
3155 | * @param ego ego handle | ||
3156 | * @param ctx context for application to store data for this ego | ||
3157 | * (during the lifetime of this process, initially NULL) | ||
3158 | * @param name name assigned by the user for this ego, | ||
3159 | * NULL if the user just deleted the ego and it | ||
3160 | * must thus no longer be used | ||
3161 | */ | ||
3162 | static void | ||
3163 | identity_shorten_cb (void *cls, | ||
3164 | struct GNUNET_IDENTITY_Ego *ego, | ||
3165 | void **ctx, | ||
3166 | const char *name) | ||
3167 | { | ||
3168 | id_op = NULL; | ||
3169 | if (NULL == ego) | ||
3170 | { | ||
3171 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
3172 | _("No ego configured for `shorten-zone`\n")); | ||
3173 | } | ||
3174 | else | ||
3175 | { | ||
3176 | local_shorten_zone = *GNUNET_IDENTITY_ego_get_private_key (ego); | ||
3177 | do_shorten = GNUNET_YES; | ||
3178 | } | ||
3179 | run_cont (); | ||
3180 | } | ||
3181 | |||
3182 | |||
3183 | /** | ||
3184 | * Method called to inform about the egos of the master zone of this peer. | 3133 | * Method called to inform about the egos of the master zone of this peer. |
3185 | * | 3134 | * |
3186 | * When used with #GNUNET_IDENTITY_create or #GNUNET_IDENTITY_get, | 3135 | * When used with #GNUNET_IDENTITY_create or #GNUNET_IDENTITY_get, |
@@ -3216,10 +3165,7 @@ identity_master_cb (void *cls, | |||
3216 | } | 3165 | } |
3217 | GNUNET_IDENTITY_ego_get_public_key (ego, | 3166 | GNUNET_IDENTITY_ego_get_public_key (ego, |
3218 | &local_gns_zone); | 3167 | &local_gns_zone); |
3219 | id_op = GNUNET_IDENTITY_get (identity, | 3168 | run_cont (); |
3220 | "gns-short", | ||
3221 | &identity_shorten_cb, | ||
3222 | NULL); | ||
3223 | } | 3169 | } |
3224 | 3170 | ||
3225 | 3171 | ||
@@ -3232,7 +3178,9 @@ identity_master_cb (void *cls, | |||
3232 | * @param c configuration | 3178 | * @param c configuration |
3233 | */ | 3179 | */ |
3234 | static void | 3180 | static void |
3235 | run (void *cls, char *const *args, const char *cfgfile, | 3181 | run (void *cls, |
3182 | char *const *args, | ||
3183 | const char *cfgfile, | ||
3236 | const struct GNUNET_CONFIGURATION_Handle *c) | 3184 | const struct GNUNET_CONFIGURATION_Handle *c) |
3237 | { | 3185 | { |
3238 | char* cafile_cfg = NULL; | 3186 | char* cafile_cfg = NULL; |
@@ -3323,22 +3271,26 @@ main (int argc, char *const *argv) | |||
3323 | "</head><body>cURL fail</body></html>"; | 3271 | "</head><body>cURL fail</body></html>"; |
3324 | int ret; | 3272 | int ret; |
3325 | 3273 | ||
3326 | if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) | 3274 | if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, |
3275 | &argc, &argv)) | ||
3327 | return 2; | 3276 | return 2; |
3328 | GNUNET_log_setup ("gnunet-gns-proxy", "WARNING", NULL); | 3277 | GNUNET_log_setup ("gnunet-gns-proxy", |
3329 | curl_failure_response = MHD_create_response_from_buffer (strlen (page), | 3278 | "WARNING", |
3330 | (void*)page, | 3279 | NULL); |
3331 | MHD_RESPMEM_PERSISTENT); | 3280 | curl_failure_response |
3281 | = MHD_create_response_from_buffer (strlen (page), | ||
3282 | (void *) page, | ||
3283 | MHD_RESPMEM_PERSISTENT); | ||
3332 | 3284 | ||
3333 | ret = | 3285 | ret = |
3334 | (GNUNET_OK == | 3286 | (GNUNET_OK == |
3335 | GNUNET_PROGRAM_run (argc, argv, "gnunet-gns-proxy", | 3287 | GNUNET_PROGRAM_run (argc, argv, |
3288 | "gnunet-gns-proxy", | ||
3336 | _("GNUnet GNS proxy"), | 3289 | _("GNUnet GNS proxy"), |
3337 | options, | 3290 | options, |
3338 | &run, NULL)) ? 0 : 1; | 3291 | &run, NULL)) ? 0 : 1; |
3339 | MHD_destroy_response (curl_failure_response); | 3292 | MHD_destroy_response (curl_failure_response); |
3340 | GNUNET_free_non_null ((char *) argv); | 3293 | GNUNET_free_non_null ((char *) argv); |
3341 | GNUNET_CRYPTO_ecdsa_key_clear (&local_shorten_zone); | ||
3342 | return ret; | 3294 | return ret; |
3343 | } | 3295 | } |
3344 | 3296 | ||
diff --git a/src/gns/gnunet-gns.c b/src/gns/gnunet-gns.c index 17fe4cbda..a261e008b 100644 --- a/src/gns/gnunet-gns.c +++ b/src/gns/gnunet-gns.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2012-2013 GNUnet e.V. | 3 | Copyright (C) 2012-2013, 2017 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -66,16 +66,6 @@ static char *zone_ego_name; | |||
66 | static char *public_key; | 66 | static char *public_key; |
67 | 67 | ||
68 | /** | 68 | /** |
69 | * Reverse key | ||
70 | */ | ||
71 | static char *reverse_key; | ||
72 | |||
73 | /** | ||
74 | * Reverse key | ||
75 | */ | ||
76 | static struct GNUNET_CRYPTO_EcdsaPublicKey rkey; | ||
77 | |||
78 | /** | ||
79 | * Set to GNUNET_GNS_LO_LOCAL_MASTER if we are looking up in the master zone. | 69 | * Set to GNUNET_GNS_LO_LOCAL_MASTER if we are looking up in the master zone. |
80 | */ | 70 | */ |
81 | static enum GNUNET_GNS_LocalOptions local_options; | 71 | static enum GNUNET_GNS_LocalOptions local_options; |
@@ -96,11 +86,6 @@ static int rtype; | |||
96 | static struct GNUNET_GNS_LookupRequest *lookup_request; | 86 | static struct GNUNET_GNS_LookupRequest *lookup_request; |
97 | 87 | ||
98 | /** | 88 | /** |
99 | * Handle to reverse lookup request | ||
100 | */ | ||
101 | static struct GNUNET_GNS_ReverseLookupRequest *rev_lookup_request; | ||
102 | |||
103 | /** | ||
104 | * Lookup an ego with the identity service. | 89 | * Lookup an ego with the identity service. |
105 | */ | 90 | */ |
106 | static struct GNUNET_IDENTITY_EgoLookup *el; | 91 | static struct GNUNET_IDENTITY_EgoLookup *el; |
@@ -174,24 +159,6 @@ do_timeout (void *cls) | |||
174 | GNUNET_SCHEDULER_shutdown (); | 159 | GNUNET_SCHEDULER_shutdown (); |
175 | } | 160 | } |
176 | 161 | ||
177 | static void | ||
178 | process_reverse_result (void *cls, | ||
179 | const char *name) | ||
180 | { | ||
181 | rev_lookup_request = NULL; | ||
182 | if (NULL == name) | ||
183 | { | ||
184 | printf ("No name found.\n"); | ||
185 | return; | ||
186 | } | ||
187 | if (raw) | ||
188 | printf ("%s\n", name); | ||
189 | else | ||
190 | printf ("%s is known as %s\n", | ||
191 | reverse_key, | ||
192 | name); | ||
193 | GNUNET_SCHEDULER_shutdown (); | ||
194 | } | ||
195 | 162 | ||
196 | /** | 163 | /** |
197 | * Function called with the result of a GNS lookup. | 164 | * Function called with the result of a GNS lookup. |
@@ -201,7 +168,8 @@ process_reverse_result (void *cls, | |||
201 | * @param rd array of @a rd_count records with the results | 168 | * @param rd array of @a rd_count records with the results |
202 | */ | 169 | */ |
203 | static void | 170 | static void |
204 | process_lookup_result (void *cls, uint32_t rd_count, | 171 | process_lookup_result (void *cls, |
172 | uint32_t rd_count, | ||
205 | const struct GNUNET_GNSRECORD_Data *rd) | 173 | const struct GNUNET_GNSRECORD_Data *rd) |
206 | { | 174 | { |
207 | const char *name = cls; | 175 | const char *name = cls; |
@@ -253,11 +221,9 @@ process_lookup_result (void *cls, uint32_t rd_count, | |||
253 | * identified by the given public key and the shorten zone. | 221 | * identified by the given public key and the shorten zone. |
254 | * | 222 | * |
255 | * @param pkey public key to use for the zone, can be NULL | 223 | * @param pkey public key to use for the zone, can be NULL |
256 | * @param shorten_key private key used for shortening, can be NULL | ||
257 | */ | 224 | */ |
258 | static void | 225 | static void |
259 | lookup_with_keys (const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey, | 226 | lookup_with_public_key (const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey) |
260 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *shorten_key) | ||
261 | { | 227 | { |
262 | if (NULL != lookup_type) | 228 | if (NULL != lookup_type) |
263 | rtype = GNUNET_GNSRECORD_typename_to_number (lookup_type); | 229 | rtype = GNUNET_GNSRECORD_typename_to_number (lookup_type); |
@@ -277,18 +243,9 @@ lookup_with_keys (const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey, | |||
277 | pkey, | 243 | pkey, |
278 | rtype, | 244 | rtype, |
279 | local_options, | 245 | local_options, |
280 | shorten_key, | ||
281 | &process_lookup_result, | 246 | &process_lookup_result, |
282 | lookup_name); | 247 | lookup_name); |
283 | } | 248 | } |
284 | else if (NULL != reverse_key) | ||
285 | { | ||
286 | rev_lookup_request = GNUNET_GNS_reverse_lookup (gns, | ||
287 | &rkey, | ||
288 | pkey, | ||
289 | &process_reverse_result, | ||
290 | NULL); | ||
291 | } | ||
292 | else | 249 | else |
293 | { | 250 | { |
294 | fprintf (stderr, | 251 | fprintf (stderr, |
@@ -300,63 +257,6 @@ lookup_with_keys (const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey, | |||
300 | 257 | ||
301 | 258 | ||
302 | /** | 259 | /** |
303 | * Method called to with the ego we are to use for shortening | ||
304 | * during the lookup. | ||
305 | * | ||
306 | * @param cls closure contains the public key to use | ||
307 | * @param ego ego handle, NULL if not found | ||
308 | * @param ctx context for application to store data for this ego | ||
309 | * (during the lifetime of this process, initially NULL) | ||
310 | * @param name name assigned by the user for this ego, | ||
311 | * NULL if the user just deleted the ego and it | ||
312 | * must thus no longer be used | ||
313 | */ | ||
314 | static void | ||
315 | identity_shorten_cb (void *cls, | ||
316 | struct GNUNET_IDENTITY_Ego *ego, | ||
317 | void **ctx, | ||
318 | const char *name) | ||
319 | { | ||
320 | struct GNUNET_CRYPTO_EcdsaPublicKey *pkeym = cls; | ||
321 | |||
322 | id_op = NULL; | ||
323 | if (NULL == ego) | ||
324 | lookup_with_keys (pkeym, NULL); | ||
325 | else | ||
326 | lookup_with_keys (pkeym, | ||
327 | GNUNET_IDENTITY_ego_get_private_key (ego)); | ||
328 | GNUNET_free (pkeym); | ||
329 | } | ||
330 | |||
331 | |||
332 | /** | ||
333 | * Perform the actual resolution, starting with the zone | ||
334 | * identified by the given public key. | ||
335 | * | ||
336 | * @param pkey public key to use for the zone | ||
337 | */ | ||
338 | static void | ||
339 | lookup_with_public_key (const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey) | ||
340 | { | ||
341 | struct GNUNET_CRYPTO_EcdsaPublicKey *pkeym; | ||
342 | |||
343 | GNUNET_assert (NULL != pkey); | ||
344 | pkeym = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey); | ||
345 | *pkeym = *pkey; | ||
346 | GNUNET_break (NULL == id_op); | ||
347 | id_op = GNUNET_IDENTITY_get (identity, | ||
348 | "gns-short", | ||
349 | &identity_shorten_cb, | ||
350 | pkeym); | ||
351 | if (NULL == id_op) | ||
352 | { | ||
353 | GNUNET_break (0); | ||
354 | lookup_with_keys (pkey, NULL); | ||
355 | } | ||
356 | } | ||
357 | |||
358 | |||
359 | /** | ||
360 | * Method called to with the ego we are to use for the lookup, | 260 | * Method called to with the ego we are to use for the lookup, |
361 | * when the ego is determined by a name. | 261 | * when the ego is determined by a name. |
362 | * | 262 | * |
@@ -449,7 +349,6 @@ run (void *cls, | |||
449 | 349 | ||
450 | cfg = c; | 350 | cfg = c; |
451 | gns = GNUNET_GNS_connect (cfg); | 351 | gns = GNUNET_GNS_connect (cfg); |
452 | identity = GNUNET_IDENTITY_connect (cfg, NULL, NULL); | ||
453 | if (NULL == gns) | 352 | if (NULL == gns) |
454 | { | 353 | { |
455 | fprintf (stderr, | 354 | fprintf (stderr, |
@@ -457,22 +356,13 @@ run (void *cls, | |||
457 | return; | 356 | return; |
458 | } | 357 | } |
459 | tt = GNUNET_SCHEDULER_add_delayed (timeout, | 358 | tt = GNUNET_SCHEDULER_add_delayed (timeout, |
460 | &do_timeout, NULL); | 359 | &do_timeout, |
461 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); | 360 | NULL); |
462 | if (NULL != reverse_key) | 361 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, |
463 | { | 362 | NULL); |
464 | if (GNUNET_OK != | 363 | identity = GNUNET_IDENTITY_connect (cfg, |
465 | GNUNET_CRYPTO_ecdsa_public_key_from_string (reverse_key, | 364 | NULL, |
466 | strlen (reverse_key), | 365 | NULL); |
467 | &rkey)) | ||
468 | { | ||
469 | fprintf (stderr, | ||
470 | _("Reverse key `%s' is not well-formed\n"), | ||
471 | reverse_key); | ||
472 | GNUNET_SCHEDULER_shutdown (); | ||
473 | return; | ||
474 | } | ||
475 | } | ||
476 | if (NULL != public_key) | 366 | if (NULL != public_key) |
477 | { | 367 | { |
478 | if (GNUNET_OK != | 368 | if (GNUNET_OK != |
@@ -489,20 +379,6 @@ run (void *cls, | |||
489 | lookup_with_public_key (&pkey); | 379 | lookup_with_public_key (&pkey); |
490 | return; | 380 | return; |
491 | } | 381 | } |
492 | if (NULL != reverse_key) | ||
493 | { | ||
494 | if (GNUNET_OK != | ||
495 | GNUNET_CRYPTO_ecdsa_public_key_from_string (reverse_key, | ||
496 | strlen (reverse_key), | ||
497 | &rkey)) | ||
498 | { | ||
499 | fprintf (stderr, | ||
500 | _("Reverse key `%s' is not well-formed\n"), | ||
501 | reverse_key); | ||
502 | GNUNET_SCHEDULER_shutdown (); | ||
503 | return; | ||
504 | } | ||
505 | } | ||
506 | if (NULL != zone_ego_name) | 382 | if (NULL != zone_ego_name) |
507 | { | 383 | { |
508 | el = GNUNET_IDENTITY_ego_lookup (cfg, | 384 | el = GNUNET_IDENTITY_ego_lookup (cfg, |
@@ -541,7 +417,8 @@ run (void *cls, | |||
541 | * @return 0 ok, 1 on error | 417 | * @return 0 ok, 1 on error |
542 | */ | 418 | */ |
543 | int | 419 | int |
544 | main (int argc, char *const *argv) | 420 | main (int argc, |
421 | char *const *argv) | ||
545 | { | 422 | { |
546 | static const struct GNUNET_GETOPT_CommandLineOption options[] = { | 423 | static const struct GNUNET_GETOPT_CommandLineOption options[] = { |
547 | {'u', "lookup", "NAME", | 424 | {'u', "lookup", "NAME", |
@@ -562,21 +439,22 @@ main (int argc, char *const *argv) | |||
562 | {'z', "zone", "NAME", | 439 | {'z', "zone", "NAME", |
563 | gettext_noop ("Specify the name of the ego of the zone to lookup the record in"), 1, | 440 | gettext_noop ("Specify the name of the ego of the zone to lookup the record in"), 1, |
564 | &GNUNET_GETOPT_set_string, &zone_ego_name}, | 441 | &GNUNET_GETOPT_set_string, &zone_ego_name}, |
565 | {'R', "reverse", "PKEY", | ||
566 | gettext_noop ("Specify the public key of the zone to reverse lookup a name for"), 1, | ||
567 | &GNUNET_GETOPT_set_string, &reverse_key}, | ||
568 | GNUNET_GETOPT_OPTION_END | 442 | GNUNET_GETOPT_OPTION_END |
569 | }; | 443 | }; |
570 | int ret; | 444 | int ret; |
571 | 445 | ||
572 | timeout = GNUNET_TIME_UNIT_FOREVER_REL; | 446 | timeout = GNUNET_TIME_UNIT_FOREVER_REL; |
573 | if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) | 447 | if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, |
448 | &argc, &argv)) | ||
574 | return 2; | 449 | return 2; |
575 | 450 | ||
576 | GNUNET_log_setup ("gnunet-gns", "WARNING", NULL); | 451 | GNUNET_log_setup ("gnunet-gns", |
452 | "WARNING", | ||
453 | NULL); | ||
577 | ret = | 454 | ret = |
578 | (GNUNET_OK == | 455 | (GNUNET_OK == |
579 | GNUNET_PROGRAM_run (argc, argv, "gnunet-gns", | 456 | GNUNET_PROGRAM_run (argc, argv, |
457 | "gnunet-gns", | ||
580 | _("GNUnet GNS resolver tool"), | 458 | _("GNUnet GNS resolver tool"), |
581 | options, | 459 | options, |
582 | &run, NULL)) ? 0 : 1; | 460 | &run, NULL)) ? 0 : 1; |
diff --git a/src/gns/gnunet-service-gns.c b/src/gns/gnunet-service-gns.c index cec31ff48..0ca25ac19 100644 --- a/src/gns/gnunet-service-gns.c +++ b/src/gns/gnunet-service-gns.c | |||
@@ -29,14 +29,11 @@ | |||
29 | #include "gnunet_dnsparser_lib.h" | 29 | #include "gnunet_dnsparser_lib.h" |
30 | #include "gnunet_dht_service.h" | 30 | #include "gnunet_dht_service.h" |
31 | #include "gnunet_namecache_service.h" | 31 | #include "gnunet_namecache_service.h" |
32 | #include "gnunet_namestore_service.h" | ||
33 | #include "gnunet_identity_service.h" | 32 | #include "gnunet_identity_service.h" |
34 | #include "gnunet_gns_service.h" | 33 | #include "gnunet_gns_service.h" |
35 | #include "gnunet_statistics_service.h" | 34 | #include "gnunet_statistics_service.h" |
36 | #include "gns.h" | 35 | #include "gns.h" |
37 | #include "gnunet-service-gns_resolver.h" | 36 | #include "gnunet-service-gns_resolver.h" |
38 | #include "gnunet-service-gns_reverser.h" | ||
39 | #include "gnunet-service-gns_shorten.h" | ||
40 | #include "gnunet-service-gns_interceptor.h" | 37 | #include "gnunet-service-gns_interceptor.h" |
41 | #include "gnunet_protocols.h" | 38 | #include "gnunet_protocols.h" |
42 | 39 | ||
@@ -61,7 +58,7 @@ struct ClientLookupHandle | |||
61 | * We keep these in a DLL. | 58 | * We keep these in a DLL. |
62 | */ | 59 | */ |
63 | struct ClientLookupHandle *prev; | 60 | struct ClientLookupHandle *prev; |
64 | 61 | ||
65 | /** | 62 | /** |
66 | * Client handle | 63 | * Client handle |
67 | */ | 64 | */ |
@@ -73,11 +70,6 @@ struct ClientLookupHandle | |||
73 | struct GNS_ResolverHandle *lookup; | 70 | struct GNS_ResolverHandle *lookup; |
74 | 71 | ||
75 | /** | 72 | /** |
76 | * Active handle for a reverse lookup | ||
77 | */ | ||
78 | struct GNS_ReverserHandle *rev_lookup; | ||
79 | |||
80 | /** | ||
81 | * request id | 73 | * request id |
82 | */ | 74 | */ |
83 | uint32_t request_id; | 75 | uint32_t request_id; |
@@ -119,11 +111,6 @@ static struct GNUNET_DHT_Handle *dht_handle; | |||
119 | static struct GNUNET_NAMECACHE_Handle *namecache_handle; | 111 | static struct GNUNET_NAMECACHE_Handle *namecache_handle; |
120 | 112 | ||
121 | /** | 113 | /** |
122 | * Our handle to the namestore service | ||
123 | */ | ||
124 | static struct GNUNET_NAMESTORE_Handle *namestore_handle; | ||
125 | |||
126 | /** | ||
127 | * Our handle to the identity service | 114 | * Our handle to the identity service |
128 | */ | 115 | */ |
129 | static struct GNUNET_IDENTITY_Handle *identity_handle; | 116 | static struct GNUNET_IDENTITY_Handle *identity_handle; |
@@ -173,19 +160,12 @@ shutdown_task (void *cls) | |||
173 | identity_handle = NULL; | 160 | identity_handle = NULL; |
174 | } | 161 | } |
175 | GNS_resolver_done (); | 162 | GNS_resolver_done (); |
176 | GNS_reverse_done (); | ||
177 | GNS_shorten_done (); | ||
178 | if (NULL != statistics) | 163 | if (NULL != statistics) |
179 | { | 164 | { |
180 | GNUNET_STATISTICS_destroy (statistics, | 165 | GNUNET_STATISTICS_destroy (statistics, |
181 | GNUNET_NO); | 166 | GNUNET_NO); |
182 | statistics = NULL; | 167 | statistics = NULL; |
183 | } | 168 | } |
184 | if (NULL != namestore_handle) | ||
185 | { | ||
186 | GNUNET_NAMESTORE_disconnect (namestore_handle); | ||
187 | namestore_handle = NULL; | ||
188 | } | ||
189 | if (NULL != namecache_handle) | 169 | if (NULL != namecache_handle) |
190 | { | 170 | { |
191 | GNUNET_NAMECACHE_disconnect (namecache_handle); | 171 | GNUNET_NAMECACHE_disconnect (namecache_handle); |
@@ -221,15 +201,13 @@ client_disconnect_cb (void *cls, | |||
221 | { | 201 | { |
222 | if (NULL != clh->lookup) | 202 | if (NULL != clh->lookup) |
223 | GNS_resolver_lookup_cancel (clh->lookup); | 203 | GNS_resolver_lookup_cancel (clh->lookup); |
224 | if (NULL != clh->rev_lookup) | ||
225 | GNS_reverse_lookup_cancel (clh->rev_lookup); | ||
226 | GNUNET_CONTAINER_DLL_remove (gc->clh_head, | 204 | GNUNET_CONTAINER_DLL_remove (gc->clh_head, |
227 | gc->clh_tail, | 205 | gc->clh_tail, |
228 | clh); | 206 | clh); |
229 | GNUNET_free (clh); | 207 | GNUNET_free (clh); |
230 | } | 208 | } |
231 | 209 | ||
232 | GNUNET_free (gc); | 210 | GNUNET_free (gc); |
233 | } | 211 | } |
234 | 212 | ||
235 | 213 | ||
@@ -288,7 +266,9 @@ send_lookup_response (void* cls, | |||
288 | (char*) &rmsg[1]); | 266 | (char*) &rmsg[1]); |
289 | GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq(clh->gc->client), | 267 | GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq(clh->gc->client), |
290 | env); | 268 | env); |
291 | GNUNET_CONTAINER_DLL_remove (clh->gc->clh_head, clh->gc->clh_tail, clh); | 269 | GNUNET_CONTAINER_DLL_remove (clh->gc->clh_head, |
270 | clh->gc->clh_tail, | ||
271 | clh); | ||
292 | GNUNET_free (clh); | 272 | GNUNET_free (clh); |
293 | GNUNET_STATISTICS_update (statistics, | 273 | GNUNET_STATISTICS_update (statistics, |
294 | "Completed lookups", 1, | 274 | "Completed lookups", 1, |
@@ -299,47 +279,6 @@ send_lookup_response (void* cls, | |||
299 | GNUNET_NO); | 279 | GNUNET_NO); |
300 | } | 280 | } |
301 | 281 | ||
302 | /** | ||
303 | * Reply to client with the result from our reverse lookup. | ||
304 | * | ||
305 | * @param cls the closure (our client lookup handle) | ||
306 | * @param rd_count the number of records in @a rd | ||
307 | * @param rd the record data | ||
308 | */ | ||
309 | static void | ||
310 | send_reverse_lookup_response (void* cls, | ||
311 | const char *name) | ||
312 | { | ||
313 | struct ClientLookupHandle *clh = cls; | ||
314 | struct GNUNET_MQ_Envelope *env; | ||
315 | struct ReverseLookupResultMessage *rmsg; | ||
316 | size_t len; | ||
317 | |||
318 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
319 | "Sending LOOKUP_RESULT message with %s\n", | ||
320 | name); | ||
321 | |||
322 | if (NULL == name) | ||
323 | len = 1; | ||
324 | else | ||
325 | len = strlen (name) + 1; | ||
326 | env = GNUNET_MQ_msg_extra (rmsg, | ||
327 | len, | ||
328 | GNUNET_MESSAGE_TYPE_GNS_REVERSE_LOOKUP_RESULT); | ||
329 | rmsg->id = clh->request_id; | ||
330 | if (1 < len) | ||
331 | GNUNET_memcpy ((char*) &rmsg[1], | ||
332 | name, | ||
333 | strlen (name)); | ||
334 | GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq(clh->gc->client), | ||
335 | env); | ||
336 | GNUNET_CONTAINER_DLL_remove (clh->gc->clh_head, clh->gc->clh_tail, clh); | ||
337 | GNUNET_free (clh); | ||
338 | GNUNET_STATISTICS_update (statistics, | ||
339 | "Completed reverse lookups", 1, | ||
340 | GNUNET_NO); | ||
341 | } | ||
342 | |||
343 | 282 | ||
344 | /** | 283 | /** |
345 | * Checks a #GNUNET_MESSAGE_TYPE_GNS_LOOKUP message | 284 | * Checks a #GNUNET_MESSAGE_TYPE_GNS_LOOKUP message |
@@ -371,6 +310,7 @@ check_lookup (void *cls, | |||
371 | return GNUNET_OK; | 310 | return GNUNET_OK; |
372 | } | 311 | } |
373 | 312 | ||
313 | |||
374 | /** | 314 | /** |
375 | * Handle lookup requests from client | 315 | * Handle lookup requests from client |
376 | * | 316 | * |
@@ -387,20 +327,18 @@ handle_lookup (void *cls, | |||
387 | struct ClientLookupHandle *clh; | 327 | struct ClientLookupHandle *clh; |
388 | char *nameptr = name; | 328 | char *nameptr = name; |
389 | const char *utf_in; | 329 | const char *utf_in; |
390 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *key; | ||
391 | 330 | ||
392 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
393 | "Received LOOKUP message\n"); | ||
394 | GNUNET_SERVICE_client_continue (gc->client); | 331 | GNUNET_SERVICE_client_continue (gc->client); |
395 | if (GNUNET_YES == ntohs (sh_msg->have_key)) | ||
396 | key = &sh_msg->shorten_key; | ||
397 | else | ||
398 | key = NULL; | ||
399 | utf_in = (const char *) &sh_msg[1]; | 332 | utf_in = (const char *) &sh_msg[1]; |
400 | GNUNET_STRINGS_utf8_tolower (utf_in, nameptr); | 333 | GNUNET_STRINGS_utf8_tolower (utf_in, nameptr); |
334 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
335 | "Received LOOKUP `%s' message\n", | ||
336 | name); | ||
401 | 337 | ||
402 | clh = GNUNET_new (struct ClientLookupHandle); | 338 | clh = GNUNET_new (struct ClientLookupHandle); |
403 | GNUNET_CONTAINER_DLL_insert (gc->clh_head, gc->clh_tail, clh); | 339 | GNUNET_CONTAINER_DLL_insert (gc->clh_head, |
340 | gc->clh_tail, | ||
341 | clh); | ||
404 | clh->gc = gc; | 342 | clh->gc = gc; |
405 | clh->request_id = sh_msg->id; | 343 | clh->request_id = sh_msg->id; |
406 | if ( (GNUNET_DNSPARSER_TYPE_A == ntohl (sh_msg->type)) && | 344 | if ( (GNUNET_DNSPARSER_TYPE_A == ntohl (sh_msg->type)) && |
@@ -422,7 +360,6 @@ handle_lookup (void *cls, | |||
422 | clh->lookup = GNS_resolver_lookup (&sh_msg->zone, | 360 | clh->lookup = GNS_resolver_lookup (&sh_msg->zone, |
423 | ntohl (sh_msg->type), | 361 | ntohl (sh_msg->type), |
424 | name, | 362 | name, |
425 | key, | ||
426 | (enum GNUNET_GNS_LocalOptions) ntohs (sh_msg->options), | 363 | (enum GNUNET_GNS_LocalOptions) ntohs (sh_msg->options), |
427 | &send_lookup_response, clh); | 364 | &send_lookup_response, clh); |
428 | GNUNET_STATISTICS_update (statistics, | 365 | GNUNET_STATISTICS_update (statistics, |
@@ -430,82 +367,6 @@ handle_lookup (void *cls, | |||
430 | 1, GNUNET_NO); | 367 | 1, GNUNET_NO); |
431 | } | 368 | } |
432 | 369 | ||
433 | /** | ||
434 | * Handle reverse lookup requests from client | ||
435 | * | ||
436 | * @param cls the closure | ||
437 | * @param client the client | ||
438 | * @param message the message | ||
439 | */ | ||
440 | static void | ||
441 | handle_rev_lookup (void *cls, | ||
442 | const struct ReverseLookupMessage *sh_msg) | ||
443 | { | ||
444 | struct GnsClient *gc = cls; | ||
445 | struct ClientLookupHandle *clh; | ||
446 | |||
447 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
448 | "Received REVERSE_LOOKUP message\n"); | ||
449 | GNUNET_SERVICE_client_continue (gc->client); | ||
450 | |||
451 | clh = GNUNET_new (struct ClientLookupHandle); | ||
452 | GNUNET_CONTAINER_DLL_insert (gc->clh_head, gc->clh_tail, clh); | ||
453 | clh->gc = gc; | ||
454 | clh->request_id = sh_msg->id; | ||
455 | clh->rev_lookup = GNS_reverse_lookup (&sh_msg->zone_pkey, | ||
456 | &sh_msg->root_pkey, | ||
457 | &send_reverse_lookup_response, | ||
458 | clh); | ||
459 | GNUNET_STATISTICS_update (statistics, | ||
460 | "Reverse lookup attempts", | ||
461 | 1, GNUNET_NO); | ||
462 | } | ||
463 | |||
464 | |||
465 | /** | ||
466 | * Method called to inform about the ego to be used for the master zone | ||
467 | * for DNS interceptions. | ||
468 | * | ||
469 | * This function is only called ONCE, and 'NULL' being passed in | ||
470 | * @a ego does indicate that interception is not configured. | ||
471 | * If @a ego is non-NULL, we should start to intercept DNS queries | ||
472 | * and resolve ".gnu" queries using the given ego as the master zone. | ||
473 | * | ||
474 | * @param cls closure, our `const struct GNUNET_CONFIGURATION_Handle *c` | ||
475 | * @param ego ego handle | ||
476 | * @param ctx context for application to store data for this ego | ||
477 | * (during the lifetime of this process, initially NULL) | ||
478 | * @param name name assigned by the user for this ego, | ||
479 | * NULL if the user just deleted the ego and it | ||
480 | * must thus no longer be used | ||
481 | */ | ||
482 | static void | ||
483 | identity_reverse_cb (void *cls, | ||
484 | struct GNUNET_IDENTITY_Ego *ego, | ||
485 | void **ctx, | ||
486 | const char *name) | ||
487 | { | ||
488 | identity_op = NULL; | ||
489 | |||
490 | if (NULL == ego) | ||
491 | { | ||
492 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
493 | _("No ego configured for `%s`\n"), | ||
494 | "gns-master"); | ||
495 | |||
496 | return; | ||
497 | } | ||
498 | if (GNUNET_SYSERR == | ||
499 | GNS_reverse_init (namestore_handle, | ||
500 | GNUNET_IDENTITY_ego_get_private_key (ego), | ||
501 | name)) | ||
502 | { | ||
503 | GNUNET_break (0); | ||
504 | GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); | ||
505 | return; | ||
506 | } | ||
507 | } | ||
508 | |||
509 | 370 | ||
510 | /** | 371 | /** |
511 | * Method called to inform about the ego to be used for the master zone | 372 | * Method called to inform about the ego to be used for the master zone |
@@ -532,16 +393,10 @@ identity_intercept_cb (void *cls, | |||
532 | { | 393 | { |
533 | const struct GNUNET_CONFIGURATION_Handle *cfg = cls; | 394 | const struct GNUNET_CONFIGURATION_Handle *cfg = cls; |
534 | struct GNUNET_CRYPTO_EcdsaPublicKey dns_root; | 395 | struct GNUNET_CRYPTO_EcdsaPublicKey dns_root; |
535 | identity_op = NULL; | ||
536 | 396 | ||
397 | identity_op = NULL; | ||
537 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 398 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
538 | "Looking for gns-intercept ego\n"); | 399 | "Looking for gns-intercept ego\n"); |
539 | identity_op = GNUNET_IDENTITY_get (identity_handle, | ||
540 | "gns-reverse", | ||
541 | &identity_reverse_cb, | ||
542 | (void*)cfg); | ||
543 | |||
544 | |||
545 | if (NULL == ego) | 400 | if (NULL == ego) |
546 | { | 401 | { |
547 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 402 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
@@ -553,10 +408,12 @@ identity_intercept_cb (void *cls, | |||
553 | GNUNET_IDENTITY_ego_get_public_key (ego, | 408 | GNUNET_IDENTITY_ego_get_public_key (ego, |
554 | &dns_root); | 409 | &dns_root); |
555 | if (GNUNET_SYSERR == | 410 | if (GNUNET_SYSERR == |
556 | GNS_interceptor_init (&dns_root, cfg)) | 411 | GNS_interceptor_init (&dns_root, |
412 | cfg)) | ||
557 | { | 413 | { |
558 | GNUNET_break (0); | 414 | GNUNET_break (0); |
559 | GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); | 415 | GNUNET_SCHEDULER_add_now (&shutdown_task, |
416 | NULL); | ||
560 | return; | 417 | return; |
561 | } | 418 | } |
562 | } | 419 | } |
@@ -577,16 +434,8 @@ run (void *cls, | |||
577 | unsigned long long max_parallel_bg_queries = 16; | 434 | unsigned long long max_parallel_bg_queries = 16; |
578 | 435 | ||
579 | v6_enabled = GNUNET_NETWORK_test_pf (PF_INET6); | 436 | v6_enabled = GNUNET_NETWORK_test_pf (PF_INET6); |
580 | v4_enabled = GNUNET_NETWORK_test_pf (PF_INET); | 437 | v4_enabled = GNUNET_NETWORK_test_pf (PF_INET); |
581 | namestore_handle = GNUNET_NAMESTORE_connect (c); | 438 | namecache_handle = GNUNET_NAMECACHE_connect (c); |
582 | if (NULL == namestore_handle) | ||
583 | { | ||
584 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
585 | _("Failed to connect to the namestore!\n")); | ||
586 | GNUNET_SCHEDULER_shutdown (); | ||
587 | return; | ||
588 | } | ||
589 | namecache_handle = GNUNET_NAMECACHE_connect (c); | ||
590 | if (NULL == namecache_handle) | 439 | if (NULL == namecache_handle) |
591 | { | 440 | { |
592 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 441 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
@@ -635,11 +484,9 @@ run (void *cls, | |||
635 | dht_handle, | 484 | dht_handle, |
636 | c, | 485 | c, |
637 | max_parallel_bg_queries); | 486 | max_parallel_bg_queries); |
638 | GNS_shorten_init (namestore_handle, | ||
639 | namecache_handle, | ||
640 | dht_handle); | ||
641 | statistics = GNUNET_STATISTICS_create ("gns", c); | 487 | statistics = GNUNET_STATISTICS_create ("gns", c); |
642 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); | 488 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, |
489 | NULL); | ||
643 | } | 490 | } |
644 | 491 | ||
645 | 492 | ||
@@ -657,10 +504,6 @@ GNUNET_SERVICE_MAIN | |||
657 | GNUNET_MESSAGE_TYPE_GNS_LOOKUP, | 504 | GNUNET_MESSAGE_TYPE_GNS_LOOKUP, |
658 | struct LookupMessage, | 505 | struct LookupMessage, |
659 | NULL), | 506 | NULL), |
660 | GNUNET_MQ_hd_fixed_size (rev_lookup, | ||
661 | GNUNET_MESSAGE_TYPE_GNS_REVERSE_LOOKUP, | ||
662 | struct ReverseLookupMessage, | ||
663 | NULL), | ||
664 | GNUNET_MQ_handler_end()); | 507 | GNUNET_MQ_handler_end()); |
665 | 508 | ||
666 | 509 | ||
diff --git a/src/gns/gnunet-service-gns_interceptor.c b/src/gns/gnunet-service-gns_interceptor.c index 7a3cfc0dd..a9e207891 100644 --- a/src/gns/gnunet-service-gns_interceptor.c +++ b/src/gns/gnunet-service-gns_interceptor.c | |||
@@ -333,7 +333,6 @@ handle_dns_request (void *cls, | |||
333 | ilh->lookup = GNS_resolver_lookup (&zone, | 333 | ilh->lookup = GNS_resolver_lookup (&zone, |
334 | p->queries[0].type, | 334 | p->queries[0].type, |
335 | p->queries[0].name, | 335 | p->queries[0].name, |
336 | NULL /* FIXME: enable shorten for DNS intercepts? */, | ||
337 | GNUNET_NO, | 336 | GNUNET_NO, |
338 | &reply_to_dns, ilh); | 337 | &reply_to_dns, ilh); |
339 | return; | 338 | return; |
diff --git a/src/gns/gnunet-service-gns_resolver.c b/src/gns/gnunet-service-gns_resolver.c index 5e957871e..c58190599 100644 --- a/src/gns/gnunet-service-gns_resolver.c +++ b/src/gns/gnunet-service-gns_resolver.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include "gnunet_dht_service.h" | 30 | #include "gnunet_dht_service.h" |
31 | #include "gnunet_gnsrecord_lib.h" | 31 | #include "gnunet_gnsrecord_lib.h" |
32 | #include "gnunet_namecache_service.h" | 32 | #include "gnunet_namecache_service.h" |
33 | #include "gnunet_namestore_service.h" | ||
34 | #include "gnunet_dns_service.h" | 33 | #include "gnunet_dns_service.h" |
35 | #include "gnunet_resolver_service.h" | 34 | #include "gnunet_resolver_service.h" |
36 | #include "gnunet_revocation_service.h" | 35 | #include "gnunet_revocation_service.h" |
@@ -39,7 +38,6 @@ | |||
39 | #include "gnunet_gns_service.h" | 38 | #include "gnunet_gns_service.h" |
40 | #include "gns.h" | 39 | #include "gns.h" |
41 | #include "gnunet-service-gns_resolver.h" | 40 | #include "gnunet-service-gns_resolver.h" |
42 | #include "gnunet-service-gns_shorten.h" | ||
43 | #include "gnunet_vpn_service.h" | 41 | #include "gnunet_vpn_service.h" |
44 | 42 | ||
45 | 43 | ||
@@ -327,11 +325,6 @@ struct GNS_ResolverHandle | |||
327 | struct AuthorityChain *ac_tail; | 325 | struct AuthorityChain *ac_tail; |
328 | 326 | ||
329 | /** | 327 | /** |
330 | * Private key of the shorten zone, NULL to not shorten. | ||
331 | */ | ||
332 | struct GNUNET_CRYPTO_EcdsaPrivateKey *shorten_key; | ||
333 | |||
334 | /** | ||
335 | * ID of a task associated with the resolution process. | 328 | * ID of a task associated with the resolution process. |
336 | */ | 329 | */ |
337 | struct GNUNET_SCHEDULER_Task * task_id; | 330 | struct GNUNET_SCHEDULER_Task * task_id; |
@@ -1750,23 +1743,6 @@ handle_gns_resolution_result (void *cls, | |||
1750 | } /* end: switch */ | 1743 | } /* end: switch */ |
1751 | } /* end: for rd_count */ | 1744 | } /* end: for rd_count */ |
1752 | 1745 | ||
1753 | /* trigger shortening */ | ||
1754 | if ((NULL != rh->shorten_key) && | ||
1755 | (NULL != shorten_ac) && | ||
1756 | (GNUNET_NO == shorten_ac->shortening_started) && | ||
1757 | (NULL != shorten_ac->suggested_shortening_label)) | ||
1758 | { | ||
1759 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1760 | "Start shortening for label `%s' based on nick `%s'\n", | ||
1761 | shorten_ac->label, | ||
1762 | shorten_ac->suggested_shortening_label); | ||
1763 | shorten_ac->shortening_started = GNUNET_YES; | ||
1764 | GNS_shorten_start (shorten_ac->label, | ||
1765 | shorten_ac->suggested_shortening_label, | ||
1766 | &shorten_ac->authority_info.gns_authority, | ||
1767 | rh->shorten_key); | ||
1768 | } | ||
1769 | |||
1770 | /* yes, we are done, return result */ | 1746 | /* yes, we are done, return result */ |
1771 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1747 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1772 | "Returning GNS response for `%s' with %u answers\n", | 1748 | "Returning GNS response for `%s' with %u answers\n", |
@@ -2374,7 +2350,6 @@ start_resolver_lookup (struct GNS_ResolverHandle *rh) | |||
2374 | * @param zone the zone to perform the lookup in | 2350 | * @param zone the zone to perform the lookup in |
2375 | * @param record_type the record type to look up | 2351 | * @param record_type the record type to look up |
2376 | * @param name the name to look up | 2352 | * @param name the name to look up |
2377 | * @param shorten_key a private key for use with PSEU import (can be NULL) | ||
2378 | * @param options local options to control local lookup | 2353 | * @param options local options to control local lookup |
2379 | * @param proc the processor to call on result | 2354 | * @param proc the processor to call on result |
2380 | * @param proc_cls the closure to pass to @a proc | 2355 | * @param proc_cls the closure to pass to @a proc |
@@ -2384,16 +2359,13 @@ struct GNS_ResolverHandle * | |||
2384 | GNS_resolver_lookup (const struct GNUNET_CRYPTO_EcdsaPublicKey *zone, | 2359 | GNS_resolver_lookup (const struct GNUNET_CRYPTO_EcdsaPublicKey *zone, |
2385 | uint32_t record_type, | 2360 | uint32_t record_type, |
2386 | const char *name, | 2361 | const char *name, |
2387 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *shorten_key, | ||
2388 | enum GNUNET_GNS_LocalOptions options, | 2362 | enum GNUNET_GNS_LocalOptions options, |
2389 | GNS_ResultProcessor proc, void *proc_cls) | 2363 | GNS_ResultProcessor proc, void *proc_cls) |
2390 | { | 2364 | { |
2391 | struct GNS_ResolverHandle *rh; | 2365 | struct GNS_ResolverHandle *rh; |
2392 | 2366 | ||
2393 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2367 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2394 | (NULL == shorten_key) | 2368 | "Starting lookup for `%s'\n", |
2395 | ? "Starting lookup for `%s' with shortening disabled\n" | ||
2396 | : "Starting lookup for `%s' with shortening enabled\n", | ||
2397 | name); | 2369 | name); |
2398 | rh = GNUNET_new (struct GNS_ResolverHandle); | 2370 | rh = GNUNET_new (struct GNS_ResolverHandle); |
2399 | GNUNET_CONTAINER_DLL_insert (rlh_head, | 2371 | GNUNET_CONTAINER_DLL_insert (rlh_head, |
@@ -2406,11 +2378,6 @@ GNS_resolver_lookup (const struct GNUNET_CRYPTO_EcdsaPublicKey *zone, | |||
2406 | rh->record_type = record_type; | 2378 | rh->record_type = record_type; |
2407 | rh->name = GNUNET_strdup (name); | 2379 | rh->name = GNUNET_strdup (name); |
2408 | rh->name_resolution_pos = strlen (name); | 2380 | rh->name_resolution_pos = strlen (name); |
2409 | if (NULL != shorten_key) | ||
2410 | { | ||
2411 | rh->shorten_key = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPrivateKey); | ||
2412 | *rh->shorten_key = *shorten_key; | ||
2413 | } | ||
2414 | start_resolver_lookup (rh); | 2381 | start_resolver_lookup (rh); |
2415 | return rh; | 2382 | return rh; |
2416 | } | 2383 | } |
@@ -2507,7 +2474,6 @@ GNS_resolver_lookup_cancel (struct GNS_ResolverHandle *rh) | |||
2507 | dr); | 2474 | dr); |
2508 | GNUNET_free (dr); | 2475 | GNUNET_free (dr); |
2509 | } | 2476 | } |
2510 | GNUNET_free_non_null (rh->shorten_key); | ||
2511 | GNUNET_free (rh->name); | 2477 | GNUNET_free (rh->name); |
2512 | GNUNET_free (rh); | 2478 | GNUNET_free (rh); |
2513 | } | 2479 | } |
diff --git a/src/gns/gnunet-service-gns_resolver.h b/src/gns/gnunet-service-gns_resolver.h index 863398093..c71d3983d 100644 --- a/src/gns/gnunet-service-gns_resolver.h +++ b/src/gns/gnunet-service-gns_resolver.h | |||
@@ -65,9 +65,10 @@ struct GNS_ResolverHandle; | |||
65 | * @param rd_count number of records in @a rd | 65 | * @param rd_count number of records in @a rd |
66 | * @param rd records returned for the lookup | 66 | * @param rd records returned for the lookup |
67 | */ | 67 | */ |
68 | typedef void (*GNS_ResultProcessor)(void *cls, | 68 | typedef void |
69 | uint32_t rd_count, | 69 | (*GNS_ResultProcessor)(void *cls, |
70 | const struct GNUNET_GNSRECORD_Data *rd); | 70 | uint32_t rd_count, |
71 | const struct GNUNET_GNSRECORD_Data *rd); | ||
71 | 72 | ||
72 | 73 | ||
73 | /** | 74 | /** |
@@ -77,7 +78,6 @@ typedef void (*GNS_ResultProcessor)(void *cls, | |||
77 | * @param zone the zone to perform the lookup in | 78 | * @param zone the zone to perform the lookup in |
78 | * @param record_type the record type to look up | 79 | * @param record_type the record type to look up |
79 | * @param name the name to look up | 80 | * @param name the name to look up |
80 | * @param shorten_key optional private key for authority caching, can be NULL | ||
81 | * @param options options set to control local lookup | 81 | * @param options options set to control local lookup |
82 | * @param proc the processor to call | 82 | * @param proc the processor to call |
83 | * @param proc_cls the closure to pass to @a proc | 83 | * @param proc_cls the closure to pass to @a proc |
@@ -87,7 +87,6 @@ struct GNS_ResolverHandle * | |||
87 | GNS_resolver_lookup (const struct GNUNET_CRYPTO_EcdsaPublicKey *zone, | 87 | GNS_resolver_lookup (const struct GNUNET_CRYPTO_EcdsaPublicKey *zone, |
88 | uint32_t record_type, | 88 | uint32_t record_type, |
89 | const char *name, | 89 | const char *name, |
90 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *shorten_key, | ||
91 | enum GNUNET_GNS_LocalOptions options, | 90 | enum GNUNET_GNS_LocalOptions options, |
92 | GNS_ResultProcessor proc, | 91 | GNS_ResultProcessor proc, |
93 | void *proc_cls); | 92 | void *proc_cls); |
@@ -102,8 +101,6 @@ void | |||
102 | GNS_resolver_lookup_cancel (struct GNS_ResolverHandle *rh); | 101 | GNS_resolver_lookup_cancel (struct GNS_ResolverHandle *rh); |
103 | 102 | ||
104 | 103 | ||
105 | |||
106 | |||
107 | /** | 104 | /** |
108 | * Generic function to check for TLDs. Checks if "name" ends in ".tld" | 105 | * Generic function to check for TLDs. Checks if "name" ends in ".tld" |
109 | * | 106 | * |
diff --git a/src/gns/gnunet-service-gns_reverser.c b/src/gns/gnunet-service-gns_reverser.c deleted file mode 100644 index b5b8b31b7..000000000 --- a/src/gns/gnunet-service-gns_reverser.c +++ /dev/null | |||
@@ -1,601 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2009-2013 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file gns/gnunet-service-gns_reverser.c | ||
22 | * @brief GNUnet GNS service | ||
23 | * @author Martin Schanzenbach | ||
24 | */ | ||
25 | |||
26 | |||
27 | #include "platform.h" | ||
28 | #include "gnunet_gns_service.h" | ||
29 | #include "gnunet-service-gns_resolver.h" | ||
30 | #include "gnunet-service-gns_reverser.h" | ||
31 | |||
32 | struct ReverseRecordEntry | ||
33 | { | ||
34 | /** | ||
35 | * DLL | ||
36 | */ | ||
37 | struct ReverseRecordEntry *next; | ||
38 | |||
39 | /** | ||
40 | * DLL | ||
41 | */ | ||
42 | struct ReverseRecordEntry *prev; | ||
43 | |||
44 | /** | ||
45 | * ReverseRecord | ||
46 | */ | ||
47 | struct GNUNET_GNSRECORD_ReverseRecord *record; | ||
48 | |||
49 | /** | ||
50 | * Record length | ||
51 | */ | ||
52 | size_t record_len; | ||
53 | |||
54 | }; | ||
55 | |||
56 | struct IteratorHandle | ||
57 | { | ||
58 | /** | ||
59 | * Records found | ||
60 | */ | ||
61 | struct ReverseRecordEntry *records_head; | ||
62 | |||
63 | /** | ||
64 | * Records found | ||
65 | */ | ||
66 | struct ReverseRecordEntry *records_tail; | ||
67 | |||
68 | /** | ||
69 | * Record count | ||
70 | */ | ||
71 | uint64_t record_count; | ||
72 | |||
73 | /** | ||
74 | * Current delegation to expect | ||
75 | */ | ||
76 | struct GNUNET_CRYPTO_EcdsaPublicKey target; | ||
77 | |||
78 | /** | ||
79 | * Queue entry | ||
80 | */ | ||
81 | struct GNUNET_NAMESTORE_QueueEntry *ns_qe; | ||
82 | |||
83 | }; | ||
84 | |||
85 | struct ReverseTreeNode | ||
86 | { | ||
87 | /** | ||
88 | * DLL | ||
89 | */ | ||
90 | struct ReverseTreeNode *next; | ||
91 | |||
92 | /** | ||
93 | * DLL | ||
94 | */ | ||
95 | struct ReverseTreeNode *prev; | ||
96 | |||
97 | /** | ||
98 | * Resolved name until now | ||
99 | */ | ||
100 | char *name; | ||
101 | |||
102 | /** | ||
103 | * Depth of the resolution at this node | ||
104 | */ | ||
105 | uint8_t depth; | ||
106 | |||
107 | /** | ||
108 | * The pkey of the namespace | ||
109 | */ | ||
110 | struct GNUNET_CRYPTO_EcdsaPublicKey pkey; | ||
111 | |||
112 | }; | ||
113 | |||
114 | |||
115 | struct GNS_ReverserHandle | ||
116 | { | ||
117 | /** | ||
118 | * GNS resolver handle | ||
119 | */ | ||
120 | struct GNS_ResolverHandle *rh; | ||
121 | |||
122 | /** | ||
123 | * The authority to look for | ||
124 | */ | ||
125 | struct GNUNET_CRYPTO_EcdsaPublicKey authority; | ||
126 | |||
127 | /** | ||
128 | * Resolution candidate queue | ||
129 | */ | ||
130 | struct ReverseTreeNode *node_queue_head; | ||
131 | |||
132 | /** | ||
133 | * Resolution candidate queue | ||
134 | */ | ||
135 | struct ReverseTreeNode *node_queue_tail; | ||
136 | |||
137 | /** | ||
138 | * Max depth for the resolution | ||
139 | */ | ||
140 | uint8_t max_depth; | ||
141 | |||
142 | /** | ||
143 | * Result callback | ||
144 | */ | ||
145 | GNS_ReverseResultProcessor proc; | ||
146 | |||
147 | /** | ||
148 | * Callback closure | ||
149 | */ | ||
150 | void *proc_cls; | ||
151 | }; | ||
152 | |||
153 | /** | ||
154 | * Reverse record collection task | ||
155 | */ | ||
156 | static struct GNUNET_SCHEDULER_Task *reverse_record_check_task; | ||
157 | |||
158 | /** | ||
159 | * NS iterator task | ||
160 | */ | ||
161 | static struct GNUNET_SCHEDULER_Task *it_task; | ||
162 | |||
163 | /** | ||
164 | * GNS lookup handle | ||
165 | */ | ||
166 | static struct GNS_ResolverHandle *gns_lookup_reverse; | ||
167 | |||
168 | /** | ||
169 | * NS handle | ||
170 | */ | ||
171 | static struct GNUNET_NAMESTORE_Handle *ns; | ||
172 | |||
173 | /** | ||
174 | * NS Iterator | ||
175 | */ | ||
176 | static struct GNUNET_NAMESTORE_ZoneIterator *namestore_iter; | ||
177 | |||
178 | /** | ||
179 | * The zone target for reverse record resolution | ||
180 | */ | ||
181 | static struct GNUNET_CRYPTO_EcdsaPublicKey myzone; | ||
182 | |||
183 | /** | ||
184 | * The zone target for reverse record resolution | ||
185 | */ | ||
186 | static struct GNUNET_CRYPTO_EcdsaPrivateKey pzone; | ||
187 | |||
188 | /** | ||
189 | * The nick of our zone | ||
190 | */ | ||
191 | static char *mynick; | ||
192 | |||
193 | |||
194 | static void | ||
195 | cleanup_handle (struct GNS_ReverserHandle *rh) | ||
196 | { | ||
197 | struct ReverseTreeNode *rtn; | ||
198 | |||
199 | for (rtn = rh->node_queue_head; NULL != rtn; rtn = rh->node_queue_head) | ||
200 | { | ||
201 | if (NULL != rtn->name) | ||
202 | GNUNET_free (rtn->name); | ||
203 | GNUNET_CONTAINER_DLL_remove (rh->node_queue_head, | ||
204 | rh->node_queue_tail, | ||
205 | rtn); | ||
206 | GNUNET_free (rtn); | ||
207 | } | ||
208 | GNUNET_free (rh); | ||
209 | } | ||
210 | |||
211 | static void | ||
212 | handle_gns_result (void *cls, | ||
213 | uint32_t rd_count, | ||
214 | const struct GNUNET_GNSRECORD_Data *rd) | ||
215 | { | ||
216 | struct GNS_ReverserHandle *rh = cls; | ||
217 | const struct GNUNET_GNSRECORD_ReverseRecord *rr; | ||
218 | struct ReverseTreeNode *rtn; | ||
219 | char *result; | ||
220 | const char *name; | ||
221 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
222 | "Got result (%d)\n", rd_count); | ||
223 | |||
224 | for (int i = 0; i < rd_count; i++) | ||
225 | { | ||
226 | /** | ||
227 | * Check if we are in the delegation set | ||
228 | */ | ||
229 | if (GNUNET_GNSRECORD_TYPE_REVERSE != rd[i].record_type) | ||
230 | continue; | ||
231 | rr = rd[i].data; | ||
232 | name = (const char*) &rr[1]; | ||
233 | if (0 == memcmp (&rh->authority, | ||
234 | &rr->pkey, | ||
235 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) | ||
236 | { | ||
237 | //Found! | ||
238 | GNUNET_asprintf (&result, | ||
239 | "%s.%s.gnu", | ||
240 | rh->node_queue_head->name, | ||
241 | name); | ||
242 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
243 | "Found path from %s\n", result); | ||
244 | |||
245 | rh->proc (rh->proc_cls, result); | ||
246 | cleanup_handle (rh); | ||
247 | GNUNET_free (result); | ||
248 | return; | ||
249 | } else { | ||
250 | if (rh->node_queue_head->depth >= rh->max_depth) | ||
251 | break; | ||
252 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
253 | "Found REVERSE from %s\n", name); | ||
254 | |||
255 | rtn = GNUNET_new (struct ReverseTreeNode); | ||
256 | if (NULL == rh->node_queue_head->name) | ||
257 | rtn->name = GNUNET_strdup (name); | ||
258 | else | ||
259 | GNUNET_asprintf (&rtn->name, | ||
260 | "%s.%s", | ||
261 | rh->node_queue_head->name, | ||
262 | name); | ||
263 | rtn->depth = rh->node_queue_head->depth + 1; | ||
264 | rtn->pkey = rr->pkey; | ||
265 | GNUNET_CONTAINER_DLL_insert_tail (rh->node_queue_head, | ||
266 | rh->node_queue_tail, | ||
267 | rtn); | ||
268 | } | ||
269 | } | ||
270 | |||
271 | /** | ||
272 | * Done here remove node from queue | ||
273 | */ | ||
274 | rtn = rh->node_queue_head; | ||
275 | if (NULL != rtn) | ||
276 | GNUNET_CONTAINER_DLL_remove (rh->node_queue_head, | ||
277 | rh->node_queue_tail, | ||
278 | rtn); | ||
279 | if (NULL == rh->node_queue_head) | ||
280 | { | ||
281 | //No luck | ||
282 | rh->proc (rh->proc_cls, NULL); | ||
283 | cleanup_handle (rh); | ||
284 | return; | ||
285 | } | ||
286 | rh->rh = GNS_resolver_lookup (&rh->node_queue_head->pkey, | ||
287 | GNUNET_GNSRECORD_TYPE_REVERSE, | ||
288 | "+.gnu", | ||
289 | NULL, | ||
290 | GNUNET_GNS_LO_DEFAULT, | ||
291 | &handle_gns_result, | ||
292 | rh); | ||
293 | } | ||
294 | |||
295 | /** | ||
296 | * Reverse lookup of a specific zone | ||
297 | * calls RecordLookupProcessor on result or timeout | ||
298 | * | ||
299 | * @param target the zone to perform the lookup in | ||
300 | * @param authority the authority | ||
301 | * @param proc the processor to call | ||
302 | * @param proc_cls the closure to pass to @a proc | ||
303 | * @return handle to cancel operation | ||
304 | */ | ||
305 | struct GNS_ReverserHandle * | ||
306 | GNS_reverse_lookup (const struct GNUNET_CRYPTO_EcdsaPublicKey *target, | ||
307 | const struct GNUNET_CRYPTO_EcdsaPublicKey *authority, | ||
308 | GNS_ReverseResultProcessor proc, | ||
309 | void *proc_cls) | ||
310 | { | ||
311 | struct GNS_ReverserHandle *rh; | ||
312 | struct ReverseTreeNode *rtn; | ||
313 | |||
314 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
315 | "Starting reverse resolution\n"); | ||
316 | rh = GNUNET_new (struct GNS_ReverserHandle); | ||
317 | rh->proc = proc; | ||
318 | rh->proc_cls = proc_cls; | ||
319 | rtn = GNUNET_new (struct ReverseTreeNode); | ||
320 | rtn->name = NULL; | ||
321 | rtn->pkey = *target; | ||
322 | rtn->depth = 0; | ||
323 | GNUNET_CONTAINER_DLL_insert (rh->node_queue_head, | ||
324 | rh->node_queue_tail, | ||
325 | rtn); | ||
326 | rh->authority = *authority; | ||
327 | rh->max_depth = 3; //TODO make argument | ||
328 | rh->rh = GNS_resolver_lookup (target, | ||
329 | GNUNET_GNSRECORD_TYPE_REVERSE, | ||
330 | "+.gnu", | ||
331 | NULL, | ||
332 | GNUNET_GNS_LO_DEFAULT, | ||
333 | &handle_gns_result, | ||
334 | rh); | ||
335 | return rh; | ||
336 | } | ||
337 | |||
338 | /** | ||
339 | * Cancel active resolution (i.e. client disconnected). | ||
340 | * | ||
341 | * @param rh resolution to abort | ||
342 | */ | ||
343 | void | ||
344 | GNS_reverse_lookup_cancel (struct GNS_ReverserHandle *rh) | ||
345 | { | ||
346 | cleanup_handle (rh); | ||
347 | return; | ||
348 | } | ||
349 | |||
350 | /******************************************** | ||
351 | * Reverse iterator | ||
352 | * ******************************************/ | ||
353 | |||
354 | |||
355 | static void | ||
356 | next_it (void *cls); | ||
357 | |||
358 | static void | ||
359 | handle_gns_result_iter (void *cls, | ||
360 | uint32_t rd_count, | ||
361 | const struct GNUNET_GNSRECORD_Data *rd) | ||
362 | { | ||
363 | struct IteratorHandle *ith = cls; | ||
364 | struct ReverseRecordEntry *rr; | ||
365 | gns_lookup_reverse = NULL; | ||
366 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
367 | "GNS for REVERSE (%s)\n", mynick); | ||
368 | |||
369 | |||
370 | if ((rd_count != 1) || | ||
371 | (GNUNET_GNSRECORD_TYPE_PKEY != rd->record_type)) | ||
372 | { | ||
373 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
374 | "GNS invalid REVERSE (%s)\n", mynick); | ||
375 | gns_lookup_reverse = NULL; | ||
376 | it_task = GNUNET_SCHEDULER_add_now (&next_it, ith); | ||
377 | return; | ||
378 | } | ||
379 | |||
380 | |||
381 | rr = GNUNET_new (struct ReverseRecordEntry); | ||
382 | rr->record_len = sizeof (struct GNUNET_GNSRECORD_ReverseRecord) | ||
383 | + strlen (mynick) + 1; | ||
384 | rr->record = GNUNET_malloc (rr->record_len); | ||
385 | rr->record->pkey = ith->target; | ||
386 | rr->record->expiration.abs_value_us = rd->expiration_time; | ||
387 | GNUNET_memcpy ((char*)&rr->record[1], | ||
388 | mynick, | ||
389 | strlen (mynick)); | ||
390 | GNUNET_CONTAINER_DLL_insert (ith->records_head, | ||
391 | ith->records_tail, | ||
392 | rr); | ||
393 | ith->record_count++; | ||
394 | it_task = GNUNET_SCHEDULER_add_now (&next_it, ith); | ||
395 | } | ||
396 | |||
397 | |||
398 | static void | ||
399 | next_it (void *cls) | ||
400 | { | ||
401 | it_task = NULL; | ||
402 | GNUNET_assert (NULL != namestore_iter); | ||
403 | GNUNET_NAMESTORE_zone_iterator_next (namestore_iter); | ||
404 | } | ||
405 | |||
406 | |||
407 | static void | ||
408 | iterator_cb (void *cls, | ||
409 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | ||
410 | const char *label, | ||
411 | unsigned int rd_count, | ||
412 | const struct GNUNET_GNSRECORD_Data *rd) | ||
413 | { | ||
414 | struct IteratorHandle *ith = cls; | ||
415 | struct GNUNET_CRYPTO_EcdsaPublicKey zone; | ||
416 | char *name; | ||
417 | |||
418 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
419 | "iterating for REVERSE (%s / %s)\n", | ||
420 | label, | ||
421 | mynick); | ||
422 | |||
423 | |||
424 | if ((rd_count != 1) || | ||
425 | (GNUNET_GNSRECORD_TYPE_PKEY != rd->record_type)) | ||
426 | { | ||
427 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
428 | "wrong format (%s)\n", mynick); | ||
429 | |||
430 | |||
431 | it_task = GNUNET_SCHEDULER_add_now (&next_it, ith); | ||
432 | return; | ||
433 | } | ||
434 | GNUNET_CRYPTO_ecdsa_key_get_public (key, | ||
435 | &zone); | ||
436 | if (0 != memcmp (&zone, &myzone, | ||
437 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) | ||
438 | { | ||
439 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
440 | "wrong zone (%s)\n", mynick); | ||
441 | |||
442 | |||
443 | it_task = GNUNET_SCHEDULER_add_now (&next_it, ith); | ||
444 | return; | ||
445 | } | ||
446 | ith->target = *((struct GNUNET_CRYPTO_EcdsaPublicKey *) rd->data); | ||
447 | GNUNET_asprintf (&name, | ||
448 | "%s.gnu", | ||
449 | mynick); | ||
450 | gns_lookup_reverse = GNS_resolver_lookup (&ith->target, | ||
451 | GNUNET_GNSRECORD_TYPE_PKEY, | ||
452 | name, | ||
453 | NULL, | ||
454 | GNUNET_GNS_LO_DEFAULT, | ||
455 | &handle_gns_result_iter, | ||
456 | ith); | ||
457 | GNUNET_free (name); | ||
458 | } | ||
459 | |||
460 | static void check_reverse_records (void *cls); | ||
461 | |||
462 | static void | ||
463 | store_reverse (void *cls, | ||
464 | int32_t success, | ||
465 | const char *emsg) | ||
466 | { | ||
467 | struct IteratorHandle *ith = cls; | ||
468 | struct ReverseRecordEntry *rr; | ||
469 | |||
470 | if (GNUNET_SYSERR == success) | ||
471 | { | ||
472 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
473 | "%s\n", | ||
474 | emsg); | ||
475 | } | ||
476 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stored records (%s)\n", mynick); | ||
477 | |||
478 | for (rr = ith->records_head; NULL != rr; rr = ith->records_head) | ||
479 | { | ||
480 | GNUNET_CONTAINER_DLL_remove (ith->records_head, | ||
481 | ith->records_tail, | ||
482 | rr); | ||
483 | GNUNET_free (rr->record); | ||
484 | GNUNET_free (rr); | ||
485 | } | ||
486 | reverse_record_check_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_DAYS, | ||
487 | &check_reverse_records, | ||
488 | NULL); | ||
489 | GNUNET_free (ith); | ||
490 | } | ||
491 | |||
492 | |||
493 | static void | ||
494 | finished_cb (void *cls) | ||
495 | { | ||
496 | struct IteratorHandle *ith = cls; | ||
497 | struct ReverseRecordEntry *rr; | ||
498 | struct GNUNET_GNSRECORD_Data rd[ith->record_count]; | ||
499 | |||
500 | memset (rd, 0, sizeof (struct GNUNET_GNSRECORD_Data) * ith->record_count); | ||
501 | |||
502 | rr = ith->records_head; | ||
503 | for (int i = 0; i < ith->record_count; i++) | ||
504 | { | ||
505 | rd[i].data_size = rr->record_len; | ||
506 | rd[i].data = GNUNET_malloc (rr->record_len); | ||
507 | rd[i].record_type = GNUNET_GNSRECORD_TYPE_REVERSE; | ||
508 | rd[i].expiration_time = rr->record->expiration.abs_value_us; | ||
509 | GNUNET_memcpy ((char*) rd[i].data, | ||
510 | rr->record, | ||
511 | rr->record_len); | ||
512 | rr = rr->next; | ||
513 | } | ||
514 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
515 | "Finished iterating for REVERSE\n"); | ||
516 | |||
517 | ith->ns_qe = GNUNET_NAMESTORE_records_store (ns, | ||
518 | &pzone, | ||
519 | "+", | ||
520 | ith->record_count, | ||
521 | rd, | ||
522 | &store_reverse, | ||
523 | ith); | ||
524 | namestore_iter = NULL; | ||
525 | |||
526 | } | ||
527 | |||
528 | |||
529 | static void | ||
530 | it_error (void *cls) | ||
531 | { | ||
532 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
533 | "Error iterating for REVERSE\n"); | ||
534 | } | ||
535 | |||
536 | |||
537 | static void | ||
538 | check_reverse_records (void *cls) | ||
539 | { | ||
540 | struct IteratorHandle *ith; | ||
541 | ith = GNUNET_new (struct IteratorHandle); | ||
542 | ith->record_count = 0; | ||
543 | reverse_record_check_task = NULL; | ||
544 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
545 | "Start iterating for REVERSE (%s)\n", mynick); | ||
546 | namestore_iter = GNUNET_NAMESTORE_zone_iteration_start (ns, | ||
547 | NULL, | ||
548 | &it_error, | ||
549 | ith, | ||
550 | &iterator_cb, | ||
551 | ith, | ||
552 | &finished_cb, | ||
553 | ith); | ||
554 | } | ||
555 | |||
556 | |||
557 | /** | ||
558 | * Initialize reverser | ||
559 | * | ||
560 | * @param nh handle to a namestore | ||
561 | * @param key the private key of the gns-reverse zone | ||
562 | * @param name the name of the gns-reverse zone | ||
563 | * @return GNUNET_OK | ||
564 | */ | ||
565 | int | ||
566 | GNS_reverse_init (struct GNUNET_NAMESTORE_Handle *nh, | ||
567 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, | ||
568 | const char *nick) | ||
569 | { | ||
570 | GNUNET_asprintf (&mynick, | ||
571 | "%s", | ||
572 | nick); | ||
573 | GNUNET_CRYPTO_ecdsa_key_get_public (zone, | ||
574 | &myzone); | ||
575 | GNUNET_memcpy (&pzone, | ||
576 | zone, | ||
577 | sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)); | ||
578 | ns = nh; | ||
579 | reverse_record_check_task = GNUNET_SCHEDULER_add_now (&check_reverse_records, | ||
580 | NULL); | ||
581 | return GNUNET_OK; | ||
582 | } | ||
583 | |||
584 | /** | ||
585 | * Cleanup reverser | ||
586 | */ | ||
587 | void | ||
588 | GNS_reverse_done () | ||
589 | { | ||
590 | if (NULL != mynick) | ||
591 | GNUNET_free (mynick); | ||
592 | if (NULL != it_task) | ||
593 | GNUNET_SCHEDULER_cancel (it_task); | ||
594 | if (NULL != reverse_record_check_task) | ||
595 | GNUNET_SCHEDULER_cancel (reverse_record_check_task); | ||
596 | if (NULL != gns_lookup_reverse) | ||
597 | GNS_resolver_lookup_cancel (gns_lookup_reverse); | ||
598 | if (NULL != namestore_iter) | ||
599 | GNUNET_NAMESTORE_zone_iteration_stop (namestore_iter); | ||
600 | } | ||
601 | |||
diff --git a/src/gns/gnunet-service-gns_reverser.h b/src/gns/gnunet-service-gns_reverser.h deleted file mode 100644 index fc9680a29..000000000 --- a/src/gns/gnunet-service-gns_reverser.h +++ /dev/null | |||
@@ -1,91 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2009-2013 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file gns/gnunet-service-gns_reverser.h | ||
22 | * @brief GNUnet GNS service | ||
23 | * @author Martin Schanzenbach | ||
24 | */ | ||
25 | #ifndef GNS_REVERSER_H | ||
26 | #define GNS_REVERSER_H | ||
27 | #include "gns.h" | ||
28 | #include "gnunet_gns_service.h" | ||
29 | |||
30 | /** | ||
31 | * Handle for an active request. | ||
32 | */ | ||
33 | struct GNS_ReverserHandle; | ||
34 | |||
35 | |||
36 | /** | ||
37 | * Function called with results for a GNS resolution. | ||
38 | * | ||
39 | * @param cls closure | ||
40 | * @param rd_count number of records in @a rd | ||
41 | * @param rd records returned for the lookup | ||
42 | */ | ||
43 | typedef void (*GNS_ReverseResultProcessor)(void *cls, | ||
44 | const char *name); | ||
45 | |||
46 | |||
47 | /** | ||
48 | * Reverse lookup of a specific zone | ||
49 | * calls RecordLookupProcessor on result or timeout | ||
50 | * | ||
51 | * @param target the zone to perform the lookup in | ||
52 | * @param authority the authority | ||
53 | * @param proc the processor to call | ||
54 | * @param proc_cls the closure to pass to @a proc | ||
55 | * @return handle to cancel operation | ||
56 | */ | ||
57 | struct GNS_ReverserHandle * | ||
58 | GNS_reverse_lookup (const struct GNUNET_CRYPTO_EcdsaPublicKey *target, | ||
59 | const struct GNUNET_CRYPTO_EcdsaPublicKey *authority, | ||
60 | GNS_ReverseResultProcessor proc, | ||
61 | void *proc_cls); | ||
62 | |||
63 | |||
64 | /** | ||
65 | * Cancel active resolution (i.e. client disconnected). | ||
66 | * | ||
67 | * @param rh resolution to abort | ||
68 | */ | ||
69 | void | ||
70 | GNS_reverse_lookup_cancel (struct GNS_ReverserHandle *rh); | ||
71 | |||
72 | /** | ||
73 | * Initialize reverser | ||
74 | * | ||
75 | * @param nh handle to a namestore | ||
76 | * @param key the private key of the gns-reverse zone | ||
77 | * @param name the name of the gns-reverse zone | ||
78 | * @return GNUNET_OK | ||
79 | */ | ||
80 | int | ||
81 | GNS_reverse_init (struct GNUNET_NAMESTORE_Handle *nh, | ||
82 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | ||
83 | const char *name); | ||
84 | |||
85 | /** | ||
86 | * Cleanup reverser | ||
87 | */ | ||
88 | void | ||
89 | GNS_reverse_done (); | ||
90 | |||
91 | #endif | ||
diff --git a/src/gns/gnunet-service-gns_shorten.c b/src/gns/gnunet-service-gns_shorten.c deleted file mode 100644 index 9aa0419aa..000000000 --- a/src/gns/gnunet-service-gns_shorten.c +++ /dev/null | |||
@@ -1,466 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2011-2013 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file gns/gnunet-service-gns_shorten.c | ||
23 | * @brief GNUnet GNS shortening logic | ||
24 | * @author Martin Schanzenbach | ||
25 | * @author Christian Grothoff | ||
26 | */ | ||
27 | #include "platform.h" | ||
28 | #include "gnunet_util_lib.h" | ||
29 | #include "gnunet_dht_service.h" | ||
30 | #include "gnunet_gnsrecord_lib.h" | ||
31 | #include "gnunet_namestore_service.h" | ||
32 | #include "gnunet_resolver_service.h" | ||
33 | #include "gnunet_gns_service.h" | ||
34 | #include "gns.h" | ||
35 | #include "gnunet-service-gns_shorten.h" | ||
36 | #include "gnunet_vpn_service.h" | ||
37 | |||
38 | |||
39 | /** | ||
40 | * Default DHT timeout for lookups. | ||
41 | */ | ||
42 | #define DHT_LOOKUP_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60) | ||
43 | |||
44 | /** | ||
45 | * DHT replication level | ||
46 | */ | ||
47 | #define DHT_GNS_REPLICATION_LEVEL 5 | ||
48 | |||
49 | |||
50 | /** | ||
51 | * Handle for a PSEU lookup used to shorten names. | ||
52 | */ | ||
53 | struct GetPseuAuthorityHandle | ||
54 | { | ||
55 | /** | ||
56 | * DLL | ||
57 | */ | ||
58 | struct GetPseuAuthorityHandle *next; | ||
59 | |||
60 | /** | ||
61 | * DLL | ||
62 | */ | ||
63 | struct GetPseuAuthorityHandle *prev; | ||
64 | |||
65 | /** | ||
66 | * Private key of the (shorten) zone to store the resulting | ||
67 | * pseudonym in. | ||
68 | */ | ||
69 | struct GNUNET_CRYPTO_EcdsaPrivateKey shorten_zone_key; | ||
70 | |||
71 | /** | ||
72 | * Original label (used if no PSEU record is found). | ||
73 | */ | ||
74 | char label[GNUNET_DNSPARSER_MAX_LABEL_LENGTH + 1]; | ||
75 | |||
76 | /** | ||
77 | * Suggested label based on NICK record | ||
78 | */ | ||
79 | char * suggested_label; | ||
80 | |||
81 | /** | ||
82 | * Label we are currently trying out | ||
83 | */ | ||
84 | char *current_label; | ||
85 | |||
86 | /** | ||
87 | * The zone for which we are trying to find the PSEU record. | ||
88 | */ | ||
89 | struct GNUNET_CRYPTO_EcdsaPublicKey target_zone; | ||
90 | |||
91 | /** | ||
92 | * Handle for DHT lookups. Should be NULL if no lookups are in progress | ||
93 | */ | ||
94 | struct GNUNET_DHT_GetHandle *get_handle; | ||
95 | |||
96 | /** | ||
97 | * Handle to namestore request | ||
98 | */ | ||
99 | struct GNUNET_NAMESTORE_QueueEntry *namestore_task; | ||
100 | |||
101 | /** | ||
102 | * Handle to namecache request | ||
103 | */ | ||
104 | struct GNUNET_NAMECACHE_QueueEntry *namecache_task; | ||
105 | |||
106 | /** | ||
107 | * Task to abort DHT lookup operation. | ||
108 | */ | ||
109 | struct GNUNET_SCHEDULER_Task * timeout_task; | ||
110 | |||
111 | }; | ||
112 | |||
113 | |||
114 | /** | ||
115 | * Head of PSEU/shorten operations list. | ||
116 | */ | ||
117 | static struct GetPseuAuthorityHandle *gph_head; | ||
118 | |||
119 | /** | ||
120 | * Tail of PSEU/shorten operations list. | ||
121 | */ | ||
122 | static struct GetPseuAuthorityHandle *gph_tail; | ||
123 | |||
124 | /** | ||
125 | * Our handle to the namestore service | ||
126 | */ | ||
127 | static struct GNUNET_NAMESTORE_Handle *namestore_handle; | ||
128 | |||
129 | /** | ||
130 | * Our handle to the namecache service | ||
131 | */ | ||
132 | static struct GNUNET_NAMECACHE_Handle *namecache_handle; | ||
133 | |||
134 | /** | ||
135 | * Resolver handle to the dht | ||
136 | */ | ||
137 | static struct GNUNET_DHT_Handle *dht_handle; | ||
138 | |||
139 | /** | ||
140 | * Cleanup a 'struct GetPseuAuthorityHandle', terminating all | ||
141 | * pending activities. | ||
142 | * | ||
143 | * @param gph handle to terminate | ||
144 | */ | ||
145 | static void | ||
146 | free_get_pseu_authority_handle (struct GetPseuAuthorityHandle *gph) | ||
147 | { | ||
148 | if (NULL != gph->get_handle) | ||
149 | { | ||
150 | GNUNET_DHT_get_stop (gph->get_handle); | ||
151 | gph->get_handle = NULL; | ||
152 | } | ||
153 | if (NULL != gph->namestore_task) | ||
154 | { | ||
155 | GNUNET_NAMESTORE_cancel (gph->namestore_task); | ||
156 | gph->namestore_task = NULL; | ||
157 | } | ||
158 | if (NULL != gph->namecache_task) | ||
159 | { | ||
160 | GNUNET_NAMECACHE_cancel (gph->namecache_task); | ||
161 | gph->namecache_task = NULL; | ||
162 | } | ||
163 | if (NULL != gph->timeout_task) | ||
164 | { | ||
165 | GNUNET_SCHEDULER_cancel (gph->timeout_task); | ||
166 | gph->timeout_task = NULL; | ||
167 | } | ||
168 | GNUNET_CONTAINER_DLL_remove (gph_head, gph_tail, gph); | ||
169 | GNUNET_free_non_null (gph->current_label); | ||
170 | GNUNET_free (gph); | ||
171 | } | ||
172 | |||
173 | |||
174 | /** | ||
175 | * Continuation for pkey record creation (shorten) | ||
176 | * | ||
177 | * @param cls a GetPseuAuthorityHandle | ||
178 | * @param success unused | ||
179 | * @param emsg unused | ||
180 | */ | ||
181 | static void | ||
182 | create_pkey_cont (void* cls, | ||
183 | int32_t success, | ||
184 | const char *emsg) | ||
185 | { | ||
186 | struct GetPseuAuthorityHandle* gph = cls; | ||
187 | |||
188 | gph->namestore_task = NULL; | ||
189 | free_get_pseu_authority_handle (gph); | ||
190 | } | ||
191 | |||
192 | |||
193 | /** | ||
194 | * Namestore calls this function if we have record for this name. | ||
195 | * (or with rd_count=0 to indicate no matches). | ||
196 | * | ||
197 | * @param cls the pending query | ||
198 | * @param rd_count the number of records with 'name' | ||
199 | * @param rd the record data | ||
200 | */ | ||
201 | static void | ||
202 | process_pseu_lookup_ns (void *cls, | ||
203 | unsigned int rd_count, | ||
204 | const struct GNUNET_GNSRECORD_Data *rd); | ||
205 | |||
206 | |||
207 | /** | ||
208 | * We obtained a result for our query to the shorten zone from | ||
209 | * the namestore. Try to decrypt. | ||
210 | * | ||
211 | * @param cls the handle to our shorten operation | ||
212 | * @param block resulting encrypted block | ||
213 | */ | ||
214 | static void | ||
215 | process_pseu_block_ns (void *cls, | ||
216 | const struct GNUNET_GNSRECORD_Block *block) | ||
217 | { | ||
218 | struct GetPseuAuthorityHandle *gph = cls; | ||
219 | struct GNUNET_CRYPTO_EcdsaPublicKey pub; | ||
220 | |||
221 | gph->namecache_task = NULL; | ||
222 | if (NULL == block) | ||
223 | { | ||
224 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
225 | "Namecache did not return information for label `%s' \n", | ||
226 | gph->current_label); | ||
227 | process_pseu_lookup_ns (gph, 0, NULL); | ||
228 | return; | ||
229 | } | ||
230 | GNUNET_CRYPTO_ecdsa_key_get_public (&gph->shorten_zone_key, | ||
231 | &pub); | ||
232 | if (GNUNET_OK != | ||
233 | GNUNET_GNSRECORD_block_decrypt (block, | ||
234 | &pub, | ||
235 | gph->current_label, | ||
236 | &process_pseu_lookup_ns, | ||
237 | gph)) | ||
238 | { | ||
239 | GNUNET_break (0); | ||
240 | free_get_pseu_authority_handle (gph); | ||
241 | return; | ||
242 | } | ||
243 | } | ||
244 | |||
245 | |||
246 | /** | ||
247 | * Lookup in the namecache for the shorten zone the given label. | ||
248 | * | ||
249 | * @param gph the handle to our shorten operation | ||
250 | * @param label the label to lookup | ||
251 | */ | ||
252 | static void | ||
253 | perform_nick_lookup (struct GetPseuAuthorityHandle *gph, | ||
254 | const char *label) | ||
255 | { | ||
256 | struct GNUNET_CRYPTO_EcdsaPublicKey pub; | ||
257 | struct GNUNET_HashCode query; | ||
258 | |||
259 | GNUNET_CRYPTO_ecdsa_key_get_public (&gph->shorten_zone_key, | ||
260 | &pub); | ||
261 | GNUNET_free_non_null (gph->current_label); | ||
262 | gph->current_label = GNUNET_strdup (label); | ||
263 | GNUNET_GNSRECORD_query_from_public_key (&pub, | ||
264 | label, | ||
265 | &query); | ||
266 | gph->namecache_task = GNUNET_NAMECACHE_lookup_block (namecache_handle, | ||
267 | &query, | ||
268 | &process_pseu_block_ns, | ||
269 | gph); | ||
270 | } | ||
271 | |||
272 | |||
273 | /** | ||
274 | * Namestore calls this function if we have record for this name. | ||
275 | * (or with rd_count=0 to indicate no matches). | ||
276 | * | ||
277 | * @param cls the pending query | ||
278 | * @param rd_count the number of records with 'name' | ||
279 | * @param rd the record data | ||
280 | */ | ||
281 | static void | ||
282 | process_pseu_lookup_ns (void *cls, | ||
283 | unsigned int rd_count, | ||
284 | const struct GNUNET_GNSRECORD_Data *rd) | ||
285 | { | ||
286 | struct GetPseuAuthorityHandle *gph = cls; | ||
287 | struct GNUNET_GNSRECORD_Data new_pkey; | ||
288 | |||
289 | gph->namestore_task = NULL; | ||
290 | if (rd_count > 0) | ||
291 | { | ||
292 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
293 | "Name `%s' already taken, cannot shorten.\n", | ||
294 | gph->current_label); | ||
295 | /* if this was not yet the original label, try one more | ||
296 | time, this time not using PSEU but the original label */ | ||
297 | if (0 == strcmp (gph->current_label, | ||
298 | gph->label)) | ||
299 | { | ||
300 | free_get_pseu_authority_handle (gph); | ||
301 | } | ||
302 | else | ||
303 | { | ||
304 | perform_nick_lookup (gph, gph->label); | ||
305 | } | ||
306 | return; | ||
307 | } | ||
308 | /* name is available */ | ||
309 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
310 | "Shortening `%s' to `%s'\n", | ||
311 | GNUNET_GNSRECORD_z2s (&gph->target_zone), | ||
312 | gph->current_label); | ||
313 | new_pkey.expiration_time = UINT64_MAX; | ||
314 | new_pkey.data_size = sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey); | ||
315 | new_pkey.data = &gph->target_zone; | ||
316 | new_pkey.record_type = GNUNET_GNSRECORD_TYPE_PKEY; | ||
317 | new_pkey.flags = GNUNET_GNSRECORD_RF_NONE | ||
318 | | GNUNET_GNSRECORD_RF_PRIVATE; | ||
319 | gph->namestore_task | ||
320 | = GNUNET_NAMESTORE_records_store (namestore_handle, | ||
321 | &gph->shorten_zone_key, | ||
322 | gph->current_label, | ||
323 | 1, &new_pkey, | ||
324 | &create_pkey_cont, gph); | ||
325 | } | ||
326 | |||
327 | |||
328 | /** | ||
329 | * Encountered an error in zone-to-name lookup, give up on shortening. | ||
330 | */ | ||
331 | static void | ||
332 | zone_to_name_error_cb (void *cls) | ||
333 | { | ||
334 | struct GetPseuAuthorityHandle* gph = cls; | ||
335 | |||
336 | gph->namestore_task = NULL; | ||
337 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
338 | "Shortening aborted, internal error talking to namestore\n"); | ||
339 | free_get_pseu_authority_handle (gph); | ||
340 | } | ||
341 | |||
342 | |||
343 | /** | ||
344 | * Callback called by namestore for a zone to name result. We're | ||
345 | * trying to see if a short name for a given zone already exists. | ||
346 | * | ||
347 | * @param cls the closure | ||
348 | * @param zone_key the zone we queried | ||
349 | * @param name the name found or NULL | ||
350 | * @param rd_len number of records for the name | ||
351 | * @param rd the record data (PKEY) for the name | ||
352 | */ | ||
353 | static void | ||
354 | process_zone_to_name_discover (void *cls, | ||
355 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, | ||
356 | const char *name, | ||
357 | unsigned int rd_len, | ||
358 | const struct GNUNET_GNSRECORD_Data *rd) | ||
359 | { | ||
360 | struct GetPseuAuthorityHandle* gph = cls; | ||
361 | |||
362 | gph->namestore_task = NULL; | ||
363 | if (0 != rd_len) | ||
364 | { | ||
365 | /* we found a match in our own zone */ | ||
366 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
367 | "Shortening aborted, name `%s' already reserved for the zone\n", | ||
368 | name); | ||
369 | free_get_pseu_authority_handle (gph); | ||
370 | return; | ||
371 | } | ||
372 | else | ||
373 | { | ||
374 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
375 | "Shortening continuing, no name not reserved in shorten zone\n"); | ||
376 | } | ||
377 | /* record does not yet exist, check if suggested label is available */ | ||
378 | perform_nick_lookup (gph, gph->suggested_label); | ||
379 | } | ||
380 | |||
381 | |||
382 | /** | ||
383 | * Start shortening algorithm, try to allocate a nice short | ||
384 | * canonical name for @a pub in @a shorten_zone, using | ||
385 | * @a original_label as one possible suggestion. | ||
386 | * | ||
387 | * @param original_label original label for the zone | ||
388 | * @param suggested_label suggested label for the zone | ||
389 | * @param pub public key of the zone to shorten | ||
390 | * @param shorten_zone private key of the target zone for the new record | ||
391 | */ | ||
392 | void | ||
393 | GNS_shorten_start (const char *original_label, | ||
394 | const char *suggested_label, | ||
395 | const struct GNUNET_CRYPTO_EcdsaPublicKey *pub, | ||
396 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *shorten_zone) | ||
397 | { | ||
398 | struct GetPseuAuthorityHandle *gph; | ||
399 | struct GNUNET_CRYPTO_EcdsaPublicKey shorten_pub; | ||
400 | |||
401 | if (strlen (original_label) > GNUNET_DNSPARSER_MAX_LABEL_LENGTH) | ||
402 | { | ||
403 | GNUNET_break (0); | ||
404 | return; | ||
405 | } | ||
406 | GNUNET_CRYPTO_ecdsa_key_get_public (shorten_zone, &shorten_pub); | ||
407 | if (0 == memcmp (&shorten_pub, pub, sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) | ||
408 | { | ||
409 | /* Do not shorten the shorten zone */ | ||
410 | return; | ||
411 | } | ||
412 | |||
413 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
414 | "Starting shortening process for `%s' with old label `%s' and suggested nickname `%s'\n", | ||
415 | GNUNET_GNSRECORD_z2s (pub), | ||
416 | original_label, suggested_label); | ||
417 | gph = GNUNET_new (struct GetPseuAuthorityHandle); | ||
418 | gph->shorten_zone_key = *shorten_zone; | ||
419 | gph->target_zone = *pub; | ||
420 | gph->suggested_label = GNUNET_strdup (suggested_label); | ||
421 | strcpy (gph->label, original_label); | ||
422 | GNUNET_CONTAINER_DLL_insert (gph_head, gph_tail, gph); | ||
423 | /* first, check if we *already* have a record for this zone */ | ||
424 | gph->namestore_task = GNUNET_NAMESTORE_zone_to_name (namestore_handle, | ||
425 | shorten_zone, | ||
426 | pub, | ||
427 | &zone_to_name_error_cb, | ||
428 | gph, | ||
429 | &process_zone_to_name_discover, | ||
430 | gph); | ||
431 | } | ||
432 | |||
433 | |||
434 | /** | ||
435 | * Initialize the shortening subsystem | ||
436 | * | ||
437 | * @param nh the namestore handle | ||
438 | * @param nc the namecache handle | ||
439 | * @param dht the dht handle | ||
440 | */ | ||
441 | void | ||
442 | GNS_shorten_init (struct GNUNET_NAMESTORE_Handle *nh, | ||
443 | struct GNUNET_NAMECACHE_Handle *nc, | ||
444 | struct GNUNET_DHT_Handle *dht) | ||
445 | { | ||
446 | namestore_handle = nh; | ||
447 | namecache_handle = nc; | ||
448 | dht_handle = dht; | ||
449 | } | ||
450 | |||
451 | |||
452 | /** | ||
453 | * Shutdown shortening. | ||
454 | */ | ||
455 | void | ||
456 | GNS_shorten_done () | ||
457 | { | ||
458 | /* abort active shorten operations */ | ||
459 | while (NULL != gph_head) | ||
460 | free_get_pseu_authority_handle (gph_head); | ||
461 | dht_handle = NULL; | ||
462 | namestore_handle = NULL; | ||
463 | namecache_handle = NULL; | ||
464 | } | ||
465 | |||
466 | /* end of gnunet-service-gns_shorten.c */ | ||
diff --git a/src/gns/gnunet-service-gns_shorten.h b/src/gns/gnunet-service-gns_shorten.h deleted file mode 100644 index d82bb52f7..000000000 --- a/src/gns/gnunet-service-gns_shorten.h +++ /dev/null | |||
@@ -1,70 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2009-2013 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file gns/gnunet-service-gns_shorten.h | ||
22 | * @brief GNUnet GNS shortening API | ||
23 | * @author Martin Schanzenbach | ||
24 | */ | ||
25 | #ifndef GNS_SHORTEN_H | ||
26 | #define GNS_SHORTEN_H | ||
27 | #include "gns.h" | ||
28 | #include "gnunet_dht_service.h" | ||
29 | #include "gnunet_namecache_service.h" | ||
30 | #include "gnunet_namestore_service.h" | ||
31 | |||
32 | |||
33 | /** | ||
34 | * Initialize the shorten subsystem. | ||
35 | * MUST be called before #GNS_shorten_start. | ||
36 | * | ||
37 | * @param nh handle to the namestore | ||
38 | * @param nc the namecache handle | ||
39 | * @param dht handle to the dht | ||
40 | */ | ||
41 | void | ||
42 | GNS_shorten_init (struct GNUNET_NAMESTORE_Handle *nh, | ||
43 | struct GNUNET_NAMECACHE_Handle *nc, | ||
44 | struct GNUNET_DHT_Handle *dht); | ||
45 | |||
46 | |||
47 | /** | ||
48 | * Cleanup shorten: Terminate pending lookups | ||
49 | */ | ||
50 | void | ||
51 | GNS_shorten_done (void); | ||
52 | |||
53 | |||
54 | /** | ||
55 | * Start shortening algorithm, try to allocate a nice short | ||
56 | * canonical name for @a pub in @a shorten_zone, using | ||
57 | * @a original_label as one possible suggestion. | ||
58 | * | ||
59 | * @param original_label original label for the zone | ||
60 | * @param pub public key of the zone to shorten | ||
61 | * @param shorten_zone private key of the target zone for the new record | ||
62 | */ | ||
63 | void | ||
64 | GNS_shorten_start (const char *original_label, | ||
65 | const char *suggested_label, | ||
66 | const struct GNUNET_CRYPTO_EcdsaPublicKey *pub, | ||
67 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *shorten_zone); | ||
68 | |||
69 | |||
70 | #endif | ||
diff --git a/src/gns/plugin_block_gns.c b/src/gns/plugin_block_gns.c index 94222e32b..a42fef953 100644 --- a/src/gns/plugin_block_gns.c +++ b/src/gns/plugin_block_gns.c | |||
@@ -63,8 +63,25 @@ block_plugin_gns_create_group (void *cls, | |||
63 | size_t raw_data_size, | 63 | size_t raw_data_size, |
64 | va_list va) | 64 | va_list va) |
65 | { | 65 | { |
66 | unsigned int bf_size; | ||
67 | const char *guard; | ||
68 | |||
69 | guard = va_arg (va, const char *); | ||
70 | if (0 == strcmp (guard, | ||
71 | "seen-set-size")) | ||
72 | bf_size = GNUNET_BLOCK_GROUP_compute_bloomfilter_size (va_arg (va, unsigned int), | ||
73 | BLOOMFILTER_K); | ||
74 | else if (0 == strcmp (guard, | ||
75 | "filter-size")) | ||
76 | bf_size = va_arg (va, unsigned int); | ||
77 | else | ||
78 | { | ||
79 | GNUNET_break (0); | ||
80 | bf_size = GNS_BF_SIZE; | ||
81 | } | ||
82 | GNUNET_break (NULL == va_arg (va, const char *)); | ||
66 | return GNUNET_BLOCK_GROUP_bf_create (cls, | 83 | return GNUNET_BLOCK_GROUP_bf_create (cls, |
67 | GNS_BF_SIZE, | 84 | bf_size, |
68 | BLOOMFILTER_K, | 85 | BLOOMFILTER_K, |
69 | type, | 86 | type, |
70 | nonce, | 87 | nonce, |
@@ -81,6 +98,7 @@ block_plugin_gns_create_group (void *cls, | |||
81 | * be done with the "get_key" function. | 98 | * be done with the "get_key" function. |
82 | * | 99 | * |
83 | * @param cls closure | 100 | * @param cls closure |
101 | * @param ctx block context | ||
84 | * @param type block type | 102 | * @param type block type |
85 | * @param bg block group to use for evaluation | 103 | * @param bg block group to use for evaluation |
86 | * @param eo control flags | 104 | * @param eo control flags |
@@ -93,6 +111,7 @@ block_plugin_gns_create_group (void *cls, | |||
93 | */ | 111 | */ |
94 | static enum GNUNET_BLOCK_EvaluationResult | 112 | static enum GNUNET_BLOCK_EvaluationResult |
95 | block_plugin_gns_evaluate (void *cls, | 113 | block_plugin_gns_evaluate (void *cls, |
114 | struct GNUNET_BLOCK_Context *ctx, | ||
96 | enum GNUNET_BLOCK_Type type, | 115 | enum GNUNET_BLOCK_Type type, |
97 | struct GNUNET_BLOCK_Group *bg, | 116 | struct GNUNET_BLOCK_Group *bg, |
98 | enum GNUNET_BLOCK_EvaluationOptions eo, | 117 | enum GNUNET_BLOCK_EvaluationOptions eo, |
@@ -219,7 +238,7 @@ libgnunet_plugin_block_gns_init (void *cls) | |||
219 | void * | 238 | void * |
220 | libgnunet_plugin_block_gns_done (void *cls) | 239 | libgnunet_plugin_block_gns_done (void *cls) |
221 | { | 240 | { |
222 | struct GNUNET_TRANSPORT_PluginFunctions *api = cls; | 241 | struct GNUNET_BLOCK_PluginFunctions *api = cls; |
223 | 242 | ||
224 | GNUNET_free (api); | 243 | GNUNET_free (api); |
225 | return NULL; | 244 | return NULL; |
diff --git a/src/gns/plugin_rest_gns.c b/src/gns/plugin_rest_gns.c index 3cddbc246..5d4734d9a 100644 --- a/src/gns/plugin_rest_gns.c +++ b/src/gns/plugin_rest_gns.c | |||
@@ -336,10 +336,9 @@ process_lookup_result (void *cls, uint32_t rd_count, | |||
336 | * identified by the given public key and the shorten zone. | 336 | * identified by the given public key and the shorten zone. |
337 | * | 337 | * |
338 | * @param pkey public key to use for the zone, can be NULL | 338 | * @param pkey public key to use for the zone, can be NULL |
339 | * @param shorten_key private key used for shortening, can be NULL | ||
340 | */ | 339 | */ |
341 | static void | 340 | static void |
342 | lookup_with_keys (struct LookupHandle *handle, const struct GNUNET_CRYPTO_EcdsaPrivateKey *shorten_key) | 341 | lookup_with_public_key (struct LookupHandle *handle) |
343 | { | 342 | { |
344 | if (UINT32_MAX == handle->type) | 343 | if (UINT32_MAX == handle->type) |
345 | { | 344 | { |
@@ -354,7 +353,6 @@ lookup_with_keys (struct LookupHandle *handle, const struct GNUNET_CRYPTO_EcdsaP | |||
354 | &handle->pkey, | 353 | &handle->pkey, |
355 | handle->type, | 354 | handle->type, |
356 | handle->options, | 355 | handle->options, |
357 | shorten_key, | ||
358 | &process_lookup_result, | 356 | &process_lookup_result, |
359 | handle); | 357 | handle); |
360 | } | 358 | } |
@@ -365,55 +363,6 @@ lookup_with_keys (struct LookupHandle *handle, const struct GNUNET_CRYPTO_EcdsaP | |||
365 | } | 363 | } |
366 | } | 364 | } |
367 | 365 | ||
368 | /** | ||
369 | * Method called to with the ego we are to use for shortening | ||
370 | * during the lookup. | ||
371 | * | ||
372 | * @param cls closure contains the public key to use | ||
373 | * @param ego ego handle, NULL if not found | ||
374 | * @param ctx context for application to store data for this ego | ||
375 | * (during the lifetime of this process, initially NULL) | ||
376 | * @param name name assigned by the user for this ego, | ||
377 | * NULL if the user just deleted the ego and it | ||
378 | * must thus no longer be used | ||
379 | */ | ||
380 | static void | ||
381 | identity_shorten_cb (void *cls, | ||
382 | struct GNUNET_IDENTITY_Ego *ego, | ||
383 | void **ctx, | ||
384 | const char *name) | ||
385 | { | ||
386 | struct LookupHandle *handle = cls; | ||
387 | |||
388 | handle->id_op = NULL; | ||
389 | if (NULL == ego) | ||
390 | lookup_with_keys (handle, NULL); | ||
391 | else | ||
392 | lookup_with_keys (handle, | ||
393 | GNUNET_IDENTITY_ego_get_private_key (ego)); | ||
394 | } | ||
395 | |||
396 | /** | ||
397 | * Perform the actual resolution, starting with the zone | ||
398 | * identified by the given public key. | ||
399 | * | ||
400 | * @param pkey public key to use for the zone | ||
401 | */ | ||
402 | static void | ||
403 | lookup_with_public_key (struct LookupHandle *handle) | ||
404 | { | ||
405 | handle->pkeym = handle->pkey; | ||
406 | GNUNET_break (NULL == handle->id_op); | ||
407 | handle->id_op = GNUNET_IDENTITY_get (handle->identity, | ||
408 | "gns-short", | ||
409 | &identity_shorten_cb, | ||
410 | handle); | ||
411 | if (NULL == handle->id_op) | ||
412 | { | ||
413 | GNUNET_break (0); | ||
414 | lookup_with_keys (handle, NULL); | ||
415 | } | ||
416 | } | ||
417 | 366 | ||
418 | /** | 367 | /** |
419 | * Method called to with the ego we are to use for the lookup, | 368 | * Method called to with the ego we are to use for the lookup, |
@@ -444,6 +393,7 @@ identity_zone_cb (void *cls, | |||
444 | json_decref(handle->json_root); | 393 | json_decref(handle->json_root); |
445 | } | 394 | } |
446 | 395 | ||
396 | |||
447 | /** | 397 | /** |
448 | * Method called to with the ego we are to use for the lookup, | 398 | * Method called to with the ego we are to use for the lookup, |
449 | * when the ego is the one for the default master zone. | 399 | * when the ego is the one for the default master zone. |
diff --git a/src/gns/test_gns_nick_shorten.sh b/src/gns/test_gns_nick_shorten.sh deleted file mode 100755 index df69bbba9..000000000 --- a/src/gns/test_gns_nick_shorten.sh +++ /dev/null | |||
@@ -1,124 +0,0 @@ | |||
1 | #!/bin/bash | ||
2 | trap "gnunet-arm -e -c test_gns_nick_shorten.conf" SIGINT | ||
3 | which timeout &> /dev/null && DO_TIMEOUT="timeout 5" | ||
4 | |||
5 | # This test tests shortening functionality based on NICK records: | ||
6 | # | ||
7 | # zone "delegatedego": Alice's zone | ||
8 | # zone "testego": Local zone with delegation to alice | ||
9 | |||
10 | LOCATION=$(which gnunet-config) | ||
11 | if [ -z $LOCATION ] | ||
12 | then | ||
13 | LOCATION="gnunet-config" | ||
14 | fi | ||
15 | $LOCATION --version 1> /dev/null | ||
16 | if test $? != 0 | ||
17 | then | ||
18 | echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX" | ||
19 | exit 77 | ||
20 | fi | ||
21 | |||
22 | # Deleting home directory from previous runs | ||
23 | TEST_CONFIG="test_gns_nick_shorten.conf " | ||
24 | rm -rf /tmp/test-gnunet-gns-peer-1/ | ||
25 | TEST_IP="127.0.0.1" | ||
26 | TEST_IP="127.0.0.2" | ||
27 | TEST_NICK_EGO="ego" | ||
28 | TEST_NICK_DELEGATED="alice" | ||
29 | TEST_NAME="www.mybestfriendalice.gnu" | ||
30 | TEST_NAME_SHORT="www.alice.short.gnu" | ||
31 | |||
32 | # export GNUNET_FORCE_LOG="namestore;;;;DEBUG/gns;;;;DEBUG/;;;;WARNING" | ||
33 | |||
34 | # Start gnunet | ||
35 | echo "Starting arm with configuration $TEST_CONFIG" | ||
36 | gnunet-arm -s -c $TEST_CONFIG | ||
37 | |||
38 | # Create initial identities: short-zone, delegated-zone, testego | ||
39 | echo "Creating identities" | ||
40 | gnunet-identity -d -c $TEST_CONFIG | ||
41 | gnunet-identity -C short-zone -c $TEST_CONFIG | ||
42 | gnunet-identity -C delegatedego -c $TEST_CONFIG | ||
43 | gnunet-identity -e short-zone -s gns-short -c $TEST_CONFIG | ||
44 | gnunet-identity -C testego -c $TEST_CONFIG | ||
45 | |||
46 | echo "Adding nick names for identities" | ||
47 | gnunet-namestore -z testego -i $TEST_NICK_EGO -c $TEST_CONFIG | ||
48 | gnunet-namestore -z delegatedego -i $TEST_NICK_DELEGATED -c $TEST_CONFIG | ||
49 | |||
50 | # Adding label www in Alice's delegatedego zone | ||
51 | echo "Adding www record with IP $TEST_IP" | ||
52 | gnunet-namestore -p -z delegatedego -a -n www -t A -V $TEST_IP -e never -c test_gns_nick_shorten.conf | ||
53 | |||
54 | # Retrieve PKEYs for delegation | ||
55 | DELEGATED_PKEY=$(gnunet-identity -d -c $TEST_CONFIG| grep delegatedego | awk '{print $3}') | ||
56 | echo "Alice's PKEY is $DELEGATED_PKEY" | ||
57 | |||
58 | SHORTEN_PKEY=$(gnunet-identity -c test_gns_nick_shorten.conf -d | grep short-zone | awk '{print $3}') | ||
59 | echo "Shorten PKEY is $SHORTEN_PKEY" | ||
60 | |||
61 | # Delegate the name "short" to shortenzone | ||
62 | gnunet-namestore -p -z testego -a -n short -t PKEY -V $SHORTEN_PKEY -e never -c test_gns_nick_shorten.conf | ||
63 | |||
64 | # Delegate the name "mybestfriendalice" to alice | ||
65 | gnunet-namestore -p -z testego -a -n mybestfriendalice -t PKEY -V $DELEGATED_PKEY -e never -c test_gns_nick_shorten.conf | ||
66 | |||
67 | # Perform lookup to shorten | ||
68 | echo "Start gns..." | ||
69 | gnunet-arm -c test_gns_nick_shorten.conf -i gns | ||
70 | |||
71 | |||
72 | RES_IP=`$DO_TIMEOUT gnunet-gns --raw -z testego -u $TEST_NAME -t A -c test_gns_nick_shorten.conf` | ||
73 | |||
74 | sleep 1 | ||
75 | |||
76 | echo "Lookup shortened names" | ||
77 | PKEY_SHORT_RES=$($DO_TIMEOUT gnunet-gns --raw -c test_gns_nick_shorten.conf -z short-zone -u alice.gnu -t PKEY) | ||
78 | echo "Resolving alice's PKEY in shorten zone: $PKEY_SHORT_RES" | ||
79 | PKEY_RES=$($DO_TIMEOUT gnunet-gns --raw -c test_gns_nick_shorten.conf -z testego -u alice.short.gnu -t PKEY) | ||
80 | echo "Resolving alice's PKEY in master zone: $PKEY_RES" | ||
81 | |||
82 | RES=0 | ||
83 | if [ "$DELEGATED_PKEY" == "$PKEY_SHORT_RES" ] | ||
84 | then | ||
85 | echo "PASS: Resolved delegation for shorten name in shortened zone" | ||
86 | else | ||
87 | echo "FAIL: Expected PKEY in $DELEGATED_PKEY, received PKEY '$PKEY_SHORT_RES' in shorten zone." | ||
88 | RES=1 | ||
89 | fi | ||
90 | |||
91 | if [ "$DELEGATED_PKEY" == "$PKEY_RES" ] | ||
92 | then | ||
93 | echo "PASS: Resolved delegation for shorten name in master zone" | ||
94 | else | ||
95 | echo "FAIL: Expected PKEY in $DELEGATED_PKEY, received PKEY $PKEY_SHORT_RES in master zone." | ||
96 | RES=1 | ||
97 | fi | ||
98 | |||
99 | if [ $RES -eq 0 ] | ||
100 | then | ||
101 | RES_IP=`$DO_TIMEOUT gnunet-gns --raw -z testego -u $TEST_NAME_SHORT -t A -c test_gns_nick_shorten.conf` | ||
102 | if [ "$RES_IP" == "$TEST_IP" ] | ||
103 | then | ||
104 | echo "PASS: Received $TEST_IP for $TEST_NAME_SHORT" | ||
105 | else | ||
106 | echo "FAIL: Expected IP in $TEST_IP, received IP '$RES_IP' for $TEST_SHORT_NAME." | ||
107 | RES=1 | ||
108 | fi | ||
109 | fi | ||
110 | |||
111 | |||
112 | # Clean up | ||
113 | echo "Clean up..." | ||
114 | gnunet-namestore -z testego -d -n mybestfriendalice -t PKEY -V $DELEGATED_PKEY -e never -c test_gns_nick_shorten.conf | ||
115 | gnunet-namestore -z delegatedego -d -n www -t A -V $TEST_IP -e never -c test_gns_nick_shorten.conf | ||
116 | gnunet-identity -D -z testego -c $TEST_CONFIG | ||
117 | gnunet-identity -D -z delegatedego -c $TEST_CONFIG | ||
118 | gnunet-identity -D -z short-zone -c $TEST_CONFIG | ||
119 | |||
120 | gnunet-arm -e -c test_gns_nick_shorten.conf | ||
121 | rm -rf /tmp/test-gnunet-gns-peer-1/ | ||
122 | |||
123 | exit $RES | ||
124 | |||
diff --git a/src/gns/test_gns_reverse_lookup.sh b/src/gns/test_gns_reverse_lookup.sh deleted file mode 100755 index 189adef11..000000000 --- a/src/gns/test_gns_reverse_lookup.sh +++ /dev/null | |||
@@ -1,50 +0,0 @@ | |||
1 | #!/bin/bash | ||
2 | trap "gnunet-arm -e -c test_gns_lookup.conf" SIGINT | ||
3 | which timeout &> /dev/null && DO_TIMEOUT="timeout 30" | ||
4 | |||
5 | LOCATION=$(which gnunet-config) | ||
6 | if [ -z $LOCATION ] | ||
7 | then | ||
8 | LOCATION="gnunet-config" | ||
9 | fi | ||
10 | $LOCATION --version 1> /dev/null | ||
11 | if test $? != 0 | ||
12 | then | ||
13 | echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX" | ||
14 | exit 77 | ||
15 | fi | ||
16 | |||
17 | TEST_NAME="dave.bob.alice.gnu" | ||
18 | gnunet-arm -s -c test_gns_lookup.conf | ||
19 | gnunet-identity -C bob -c test_gns_lookup.conf | ||
20 | BOB_PKEY=$(gnunet-identity -d -c test_gns_lookup.conf | grep bob | awk '{print $3}') | ||
21 | gnunet-identity -C daveego -c test_gns_lookup.conf | ||
22 | DAVE_PKEY=$(gnunet-identity -d -c test_gns_lookup.conf | grep dave | awk '{print $3}') | ||
23 | gnunet-identity -C aliceego -c test_gns_lookup.conf | ||
24 | ALICE_PKEY=$(gnunet-identity -d -c test_gns_lookup.conf | grep alice | awk '{print $3}') | ||
25 | gnunet-identity -C testego -c test_gns_lookup.conf | ||
26 | ROOT_PKEY=$(gnunet-identity -d -c test_gns_lookup.conf | grep testego | awk '{print $3}') | ||
27 | |||
28 | gnunet-identity -s gns-reverse -e bob -c test_gns_lookup.conf | ||
29 | |||
30 | gnunet-namestore -p -z testego -a -n alice -t PKEY -V $ALICE_PKEY -e never -c test_gns_lookup.conf | ||
31 | gnunet-namestore -p -z aliceego -a -n bob -t PKEY -V $BOB_PKEY -e never -c test_gns_lookup.conf | ||
32 | gnunet-namestore -p -z aliceego -a -n + -t REVERSE -V "alice $ROOT_PKEY 0" -e never -c test_gns_lookup.conf | ||
33 | gnunet-namestore -p -z bob -a -n dave -t PKEY -V $DAVE_PKEY -e never -c test_gns_lookup.conf | ||
34 | gnunet-namestore -p -z bob -a -n alice -t PKEY -V $ALICE_PKEY -e never -c test_gns_lookup.conf | ||
35 | #gnunet-namestore -p -z bob -a -n + -t REVERSE -V "bob $ALICE_PKEY 0" -e never -c test_gns_lookup.conf | ||
36 | gnunet-namestore -p -z daveego -a -n + -t REVERSE -V "dave $BOB_PKEY 0" -e never -c test_gns_lookup.conf | ||
37 | gnunet-namestore -p -z daveego -a -n bob -t PKEY -V $BOB_PKEY -e never -c test_gns_lookup.conf | ||
38 | gnunet-arm -i gns -c test_gns_lookup.conf | ||
39 | sleep 10 | ||
40 | RES_NAME=`$DO_TIMEOUT gnunet-gns --raw -z testego -R $DAVE_PKEY -c test_gns_lookup.conf` | ||
41 | gnunet-arm -e -c test_gns_lookup.conf | ||
42 | rm -rf /tmp/test-gnunet-gns-peer-1/ | ||
43 | |||
44 | if [ "$RES_NAME" == "$TEST_NAME" ] | ||
45 | then | ||
46 | exit 0 | ||
47 | else | ||
48 | echo "Failed to resolve to proper IP, got $RES_IP." | ||
49 | exit 1 | ||
50 | fi | ||
diff --git a/src/gns/w32nsp-resolve.c b/src/gns/w32nsp-resolve.c index 1de1a3657..82f15c6cc 100644 --- a/src/gns/w32nsp-resolve.c +++ b/src/gns/w32nsp-resolve.c | |||
@@ -22,6 +22,9 @@ | |||
22 | * @brief W32 integration for GNS | 22 | * @brief W32 integration for GNS |
23 | * @author LRN | 23 | * @author LRN |
24 | */ | 24 | */ |
25 | /* Instead of including gnunet_common.h */ | ||
26 | #define GNUNET_memcpy(dst,src,n) do { if (0 != n) { (void) memcpy (dst,src,n); } } while (0) | ||
27 | |||
25 | #include <ws2tcpip.h> | 28 | #include <ws2tcpip.h> |
26 | #include <windows.h> | 29 | #include <windows.h> |
27 | #include <nspapi.h> | 30 | #include <nspapi.h> |
diff --git a/src/identity-provider/gnunet-service-identity-provider.c b/src/identity-provider/gnunet-service-identity-provider.c index d72b92c0f..17c288368 100644 --- a/src/identity-provider/gnunet-service-identity-provider.c +++ b/src/identity-provider/gnunet-service-identity-provider.c | |||
@@ -714,7 +714,7 @@ attribute_collect (void *cls, | |||
714 | GNUNET_CONTAINER_DLL_insert (attr->val_head, | 714 | GNUNET_CONTAINER_DLL_insert (attr->val_head, |
715 | attr->val_tail, | 715 | attr->val_tail, |
716 | val); | 716 | val); |
717 | GNUNET_assert (GNUNET_OK == | 717 | GNUNET_assert (GNUNET_OK == |
718 | GNUNET_CONTAINER_multihashmap_put (ego_entry->attr_map, | 718 | GNUNET_CONTAINER_multihashmap_put (ego_entry->attr_map, |
719 | &key, | 719 | &key, |
720 | attr, | 720 | attr, |
@@ -949,7 +949,7 @@ create_issue_result_message (const char* label, | |||
949 | struct IssueResultMessage *irm; | 949 | struct IssueResultMessage *irm; |
950 | char *tmp_str; | 950 | char *tmp_str; |
951 | size_t len; | 951 | size_t len; |
952 | 952 | ||
953 | GNUNET_asprintf (&tmp_str, "%s,%s,%s", label, ticket, token); | 953 | GNUNET_asprintf (&tmp_str, "%s,%s,%s", label, ticket, token); |
954 | len = strlen (tmp_str) + 1; | 954 | len = strlen (tmp_str) + 1; |
955 | env = GNUNET_MQ_msg_extra (irm, | 955 | env = GNUNET_MQ_msg_extra (irm, |
@@ -1279,7 +1279,7 @@ check_exchange_message (void *cls, | |||
1279 | return GNUNET_SYSERR; | 1279 | return GNUNET_SYSERR; |
1280 | } | 1280 | } |
1281 | return GNUNET_OK; | 1281 | return GNUNET_OK; |
1282 | } | 1282 | } |
1283 | 1283 | ||
1284 | /** | 1284 | /** |
1285 | * | 1285 | * |
@@ -1326,7 +1326,6 @@ handle_exchange_message (void *cls, | |||
1326 | &xchange_handle->ticket->payload->identity_key, | 1326 | &xchange_handle->ticket->payload->identity_key, |
1327 | GNUNET_GNSRECORD_TYPE_ID_TOKEN, | 1327 | GNUNET_GNSRECORD_TYPE_ID_TOKEN, |
1328 | GNUNET_GNS_LO_LOCAL_MASTER, | 1328 | GNUNET_GNS_LO_LOCAL_MASTER, |
1329 | NULL, | ||
1330 | &process_lookup_result, | 1329 | &process_lookup_result, |
1331 | xchange_handle); | 1330 | xchange_handle); |
1332 | GNUNET_free (lookup_query); | 1331 | GNUNET_free (lookup_query); |
diff --git a/src/identity/gnunet-identity.c b/src/identity/gnunet-identity.c index f632aa0a8..8c8485249 100644 --- a/src/identity/gnunet-identity.c +++ b/src/identity/gnunet-identity.c | |||
@@ -29,6 +29,12 @@ | |||
29 | #include "gnunet_util_lib.h" | 29 | #include "gnunet_util_lib.h" |
30 | #include "gnunet_identity_service.h" | 30 | #include "gnunet_identity_service.h" |
31 | 31 | ||
32 | |||
33 | /** | ||
34 | * Return value from main on timeout. | ||
35 | */ | ||
36 | #define TIMEOUT_STATUS_CODE 40 | ||
37 | |||
32 | /** | 38 | /** |
33 | * Handle to IDENTITY service. | 39 | * Handle to IDENTITY service. |
34 | */ | 40 | */ |
@@ -79,6 +85,11 @@ static struct GNUNET_IDENTITY_Operation *create_op; | |||
79 | */ | 85 | */ |
80 | static struct GNUNET_IDENTITY_Operation *delete_op; | 86 | static struct GNUNET_IDENTITY_Operation *delete_op; |
81 | 87 | ||
88 | /** | ||
89 | * Value to return from #main(). | ||
90 | */ | ||
91 | static int global_ret; | ||
92 | |||
82 | 93 | ||
83 | /** | 94 | /** |
84 | * Task run on shutdown. | 95 | * Task run on shutdown. |
@@ -120,7 +131,11 @@ test_finished () | |||
120 | (NULL == set_ego) && | 131 | (NULL == set_ego) && |
121 | (! list) && | 132 | (! list) && |
122 | (! monitor) ) | 133 | (! monitor) ) |
134 | { | ||
135 | if (TIMEOUT_STATUS_CODE == global_ret) | ||
136 | global_ret = 0; | ||
123 | GNUNET_SCHEDULER_shutdown (); | 137 | GNUNET_SCHEDULER_shutdown (); |
138 | } | ||
124 | } | 139 | } |
125 | 140 | ||
126 | 141 | ||
@@ -159,9 +174,12 @@ create_finished (void *cls, | |||
159 | 174 | ||
160 | *op = NULL; | 175 | *op = NULL; |
161 | if (NULL != emsg) | 176 | if (NULL != emsg) |
177 | { | ||
162 | fprintf (stderr, | 178 | fprintf (stderr, |
163 | _("Failed to create ego: %s\n"), | 179 | _("Failed to create ego: %s\n"), |
164 | emsg); | 180 | emsg); |
181 | global_ret = 1; | ||
182 | } | ||
165 | test_finished (); | 183 | test_finished (); |
166 | } | 184 | } |
167 | 185 | ||
@@ -178,9 +196,12 @@ set_done (void *cls, | |||
178 | { | 196 | { |
179 | set_op = NULL; | 197 | set_op = NULL; |
180 | if (NULL != emsg) | 198 | if (NULL != emsg) |
199 | { | ||
181 | fprintf (stderr, | 200 | fprintf (stderr, |
182 | _("Failed to set default ego: %s\n"), | 201 | _("Failed to set default ego: %s\n"), |
183 | emsg); | 202 | emsg); |
203 | global_ret = 1; | ||
204 | } | ||
184 | test_finished (); | 205 | test_finished (); |
185 | } | 206 | } |
186 | 207 | ||
@@ -257,17 +278,23 @@ print_ego (void *cls, | |||
257 | } | 278 | } |
258 | if ( (NULL == ego) && (! monitor) ) | 279 | if ( (NULL == ego) && (! monitor) ) |
259 | { | 280 | { |
260 | GNUNET_SCHEDULER_shutdown (); | 281 | list = 0; |
282 | test_finished (); | ||
261 | return; | 283 | return; |
262 | } | 284 | } |
263 | if (! (list | monitor)) | 285 | if (! (list | monitor)) |
264 | return; | 286 | return; |
265 | if (NULL == ego) | 287 | if (NULL == ego) |
266 | return; | 288 | return; |
267 | GNUNET_IDENTITY_ego_get_public_key (ego, &pk); | 289 | GNUNET_IDENTITY_ego_get_public_key (ego, |
290 | &pk); | ||
268 | s = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); | 291 | s = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); |
269 | if ( (monitor) || (NULL != identifier) ) | 292 | if ( (monitor) || |
270 | fprintf (stdout, "%s - %s\n", identifier, s); | 293 | (NULL != identifier) ) |
294 | fprintf (stdout, | ||
295 | "%s - %s\n", | ||
296 | identifier, | ||
297 | s); | ||
271 | GNUNET_free (s); | 298 | GNUNET_free (s); |
272 | } | 299 | } |
273 | 300 | ||
@@ -281,7 +308,9 @@ print_ego (void *cls, | |||
281 | * @param cfg configuration | 308 | * @param cfg configuration |
282 | */ | 309 | */ |
283 | static void | 310 | static void |
284 | run (void *cls, char *const *args, const char *cfgfile, | 311 | run (void *cls, |
312 | char *const *args, | ||
313 | const char *cfgfile, | ||
285 | const struct GNUNET_CONFIGURATION_Handle *cfg) | 314 | const struct GNUNET_CONFIGURATION_Handle *cfg) |
286 | { | 315 | { |
287 | if ( (NULL == set_subsystem) ^ | 316 | if ( (NULL == set_subsystem) ^ |
@@ -291,7 +320,9 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
291 | "Options -e and -s must always be specified together\n"); | 320 | "Options -e and -s must always be specified together\n"); |
292 | return; | 321 | return; |
293 | } | 322 | } |
294 | sh = GNUNET_IDENTITY_connect (cfg, &print_ego, NULL); | 323 | sh = GNUNET_IDENTITY_connect (cfg, |
324 | &print_ego, | ||
325 | NULL); | ||
295 | if (NULL != delete_ego) | 326 | if (NULL != delete_ego) |
296 | delete_op = GNUNET_IDENTITY_delete (sh, | 327 | delete_op = GNUNET_IDENTITY_delete (sh, |
297 | delete_ego, | 328 | delete_ego, |
@@ -302,7 +333,8 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
302 | create_ego, | 333 | create_ego, |
303 | &create_finished, | 334 | &create_finished, |
304 | &create_op); | 335 | &create_op); |
305 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); | 336 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, |
337 | NULL); | ||
306 | test_finished (); | 338 | test_finished (); |
307 | } | 339 | } |
308 | 340 | ||
@@ -317,8 +349,6 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
317 | int | 349 | int |
318 | main (int argc, char *const *argv) | 350 | main (int argc, char *const *argv) |
319 | { | 351 | { |
320 | int res; | ||
321 | |||
322 | static const struct GNUNET_GETOPT_CommandLineOption options[] = { | 352 | static const struct GNUNET_GETOPT_CommandLineOption options[] = { |
323 | {'C', "create", "NAME", | 353 | {'C', "create", "NAME", |
324 | gettext_noop ("create ego NAME"), | 354 | gettext_noop ("create ego NAME"), |
@@ -340,19 +370,23 @@ main (int argc, char *const *argv) | |||
340 | 1, &GNUNET_GETOPT_set_string, &set_subsystem}, | 370 | 1, &GNUNET_GETOPT_set_string, &set_subsystem}, |
341 | GNUNET_GETOPT_OPTION_END | 371 | GNUNET_GETOPT_OPTION_END |
342 | }; | 372 | }; |
373 | int res; | ||
343 | 374 | ||
344 | if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) | 375 | if (GNUNET_OK != |
345 | return 2; | 376 | GNUNET_STRINGS_get_utf8_args (argc, argv, |
346 | 377 | &argc, &argv)) | |
347 | res = GNUNET_PROGRAM_run (argc, argv, "gnunet-identity", | 378 | return 4; |
379 | global_ret = TIMEOUT_STATUS_CODE; /* timeout */ | ||
380 | res = GNUNET_PROGRAM_run (argc, argv, | ||
381 | "gnunet-identity", | ||
348 | gettext_noop ("Maintain egos"), | 382 | gettext_noop ("Maintain egos"), |
349 | options, &run, | 383 | options, &run, |
350 | NULL); | 384 | NULL); |
351 | GNUNET_free ((void *) argv); | 385 | GNUNET_free ((void *) argv); |
352 | 386 | ||
353 | if (GNUNET_OK != res) | 387 | if (GNUNET_OK != res) |
354 | return 1; | 388 | return 3; |
355 | return 0; | 389 | return global_ret; |
356 | } | 390 | } |
357 | 391 | ||
358 | /* end of gnunet-identity.c */ | 392 | /* end of gnunet-identity.c */ |
diff --git a/src/include/Makefile.am b/src/include/Makefile.am index bf3ffe482..4fb2577fd 100644 --- a/src/include/Makefile.am +++ b/src/include/Makefile.am | |||
@@ -114,6 +114,7 @@ gnunetinclude_HEADERS = \ | |||
114 | gnunet_signatures.h \ | 114 | gnunet_signatures.h \ |
115 | gnunet_social_service.h \ | 115 | gnunet_social_service.h \ |
116 | gnunet_speaker_lib.h \ | 116 | gnunet_speaker_lib.h \ |
117 | gnunet_sq_lib.h \ | ||
117 | gnunet_statistics_service.h \ | 118 | gnunet_statistics_service.h \ |
118 | gnunet_strings_lib.h \ | 119 | gnunet_strings_lib.h \ |
119 | gnunet_testbed_service.h \ | 120 | gnunet_testbed_service.h \ |
diff --git a/src/include/gnunet_block_group_lib.h b/src/include/gnunet_block_group_lib.h index a1ea807f6..3a3dfb2e2 100644 --- a/src/include/gnunet_block_group_lib.h +++ b/src/include/gnunet_block_group_lib.h | |||
@@ -44,6 +44,24 @@ extern "C" | |||
44 | 44 | ||
45 | 45 | ||
46 | /** | 46 | /** |
47 | * How many bytes should a bloomfilter be if we have already seen | ||
48 | * entry_count responses? Sized so that do not have to | ||
49 | * re-size the filter too often (to keep it cheap). | ||
50 | * | ||
51 | * Since other peers will also add entries but not resize the filter, | ||
52 | * we should generally pick a slightly larger size than what the | ||
53 | * strict math would suggest. | ||
54 | * | ||
55 | * @param entry_count expected number of entries in the Bloom filter | ||
56 | * @param k number of bits set per entry | ||
57 | * @return must be a power of two and smaller or equal to 2^15. | ||
58 | */ | ||
59 | size_t | ||
60 | GNUNET_BLOCK_GROUP_compute_bloomfilter_size (unsigned int entry_count, | ||
61 | unsigned int k); | ||
62 | |||
63 | |||
64 | /** | ||
47 | * Create a new block group that filters duplicates using a Bloom filter. | 65 | * Create a new block group that filters duplicates using a Bloom filter. |
48 | * | 66 | * |
49 | * @param ctx block context in which the block group is created | 67 | * @param ctx block context in which the block group is created |
diff --git a/src/include/gnunet_block_lib.h b/src/include/gnunet_block_lib.h index a40f33699..d8ee68c21 100644 --- a/src/include/gnunet_block_lib.h +++ b/src/include/gnunet_block_lib.h | |||
@@ -112,6 +112,11 @@ enum GNUNET_BLOCK_Type | |||
112 | GNUNET_BLOCK_TYPE_GNS_NAMERECORD = 11, | 112 | GNUNET_BLOCK_TYPE_GNS_NAMERECORD = 11, |
113 | 113 | ||
114 | /** | 114 | /** |
115 | * Block type for a revocation message by which a key is revoked. | ||
116 | */ | ||
117 | GNUNET_BLOCK_TYPE_REVOCATION = 12, | ||
118 | |||
119 | /** | ||
115 | * Block to store a cadet regex state | 120 | * Block to store a cadet regex state |
116 | */ | 121 | */ |
117 | GNUNET_BLOCK_TYPE_REGEX = 22, | 122 | GNUNET_BLOCK_TYPE_REGEX = 22, |
@@ -119,7 +124,19 @@ enum GNUNET_BLOCK_Type | |||
119 | /** | 124 | /** |
120 | * Block to store a cadet regex accepting state | 125 | * Block to store a cadet regex accepting state |
121 | */ | 126 | */ |
122 | GNUNET_BLOCK_TYPE_REGEX_ACCEPT = 23 | 127 | GNUNET_BLOCK_TYPE_REGEX_ACCEPT = 23, |
128 | |||
129 | /** | ||
130 | * Block for testing set/consensus. If first byte of the block | ||
131 | * is non-zero, the block is considered invalid. | ||
132 | */ | ||
133 | GNUNET_BLOCK_TYPE_SET_TEST = 24, | ||
134 | |||
135 | /** | ||
136 | * Block type for consensus elements. | ||
137 | * Contains either special marker elements or a nested block. | ||
138 | */ | ||
139 | GNUNET_BLOCK_TYPE_CONSENSUS_ELEMENT = 25, | ||
123 | }; | 140 | }; |
124 | 141 | ||
125 | 142 | ||
diff --git a/src/include/gnunet_block_plugin.h b/src/include/gnunet_block_plugin.h index 171b6cfc0..3eb031573 100644 --- a/src/include/gnunet_block_plugin.h +++ b/src/include/gnunet_block_plugin.h | |||
@@ -171,6 +171,7 @@ typedef struct GNUNET_BLOCK_Group * | |||
171 | * be done with the "get_key" function. | 171 | * be done with the "get_key" function. |
172 | * | 172 | * |
173 | * @param cls closure | 173 | * @param cls closure |
174 | * @param ctx block context | ||
174 | * @param type block type | 175 | * @param type block type |
175 | * @param group which block group to use for evaluation | 176 | * @param group which block group to use for evaluation |
176 | * @param eo evaluation options to control evaluation | 177 | * @param eo evaluation options to control evaluation |
@@ -183,6 +184,7 @@ typedef struct GNUNET_BLOCK_Group * | |||
183 | */ | 184 | */ |
184 | typedef enum GNUNET_BLOCK_EvaluationResult | 185 | typedef enum GNUNET_BLOCK_EvaluationResult |
185 | (*GNUNET_BLOCK_EvaluationFunction) (void *cls, | 186 | (*GNUNET_BLOCK_EvaluationFunction) (void *cls, |
187 | struct GNUNET_BLOCK_Context *ctx, | ||
186 | enum GNUNET_BLOCK_Type type, | 188 | enum GNUNET_BLOCK_Type type, |
187 | struct GNUNET_BLOCK_Group *group, | 189 | struct GNUNET_BLOCK_Group *group, |
188 | enum GNUNET_BLOCK_EvaluationOptions eo, | 190 | enum GNUNET_BLOCK_EvaluationOptions eo, |
diff --git a/src/include/gnunet_cadet_service.h b/src/include/gnunet_cadet_service.h index 4d13606ef..fd838df8d 100644 --- a/src/include/gnunet_cadet_service.h +++ b/src/include/gnunet_cadet_service.h | |||
@@ -740,9 +740,9 @@ typedef void | |||
740 | * #GNUNET_CADET_ConnectEventHandler, also with a non-zero value. | 740 | * #GNUNET_CADET_ConnectEventHandler, also with a non-zero value. |
741 | * | 741 | * |
742 | * @param cls Channel closure. | 742 | * @param cls Channel closure. |
743 | * @param channel Connection to the other end (henceforth invalid). | 743 | * @param channel Connection to the other end --- FIXME: drop? |
744 | * @param window_size New window size. If the is more messages than buffer size | 744 | * @param window_size New window size. If the is more messages than buffer size |
745 | * this value will be negative.. | 745 | * this value will be negative. -- FIXME: make unsigned, we never call negative? |
746 | */ | 746 | */ |
747 | typedef void | 747 | typedef void |
748 | (*GNUNET_CADET_WindowSizeEventHandler) (void *cls, | 748 | (*GNUNET_CADET_WindowSizeEventHandler) (void *cls, |
diff --git a/src/include/gnunet_common.h b/src/include/gnunet_common.h index fdcae66fa..bda011fb2 100644 --- a/src/include/gnunet_common.h +++ b/src/include/gnunet_common.h | |||
@@ -391,7 +391,7 @@ GNUNET_get_log_call_status (int caller_level, | |||
391 | */ | 391 | */ |
392 | void | 392 | void |
393 | GNUNET_log_nocheck (enum GNUNET_ErrorType kind, const char *message, ...) | 393 | GNUNET_log_nocheck (enum GNUNET_ErrorType kind, const char *message, ...) |
394 | __attribute__ ((format (printf, 2, 3))); | 394 | __attribute__ ((format (gnu_printf, 2, 3))); |
395 | 395 | ||
396 | /* from glib */ | 396 | /* from glib */ |
397 | #if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__) | 397 | #if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__) |
diff --git a/src/include/gnunet_gns_service.h b/src/include/gnunet_gns_service.h index 44f57014d..ccc868c05 100644 --- a/src/include/gnunet_gns_service.h +++ b/src/include/gnunet_gns_service.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | Copyright (C) 2012-2014 GNUnet e.V. | 3 | Copyright (C) 2012-2014, 2017 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -95,16 +95,6 @@ typedef void | |||
95 | uint32_t rd_count, | 95 | uint32_t rd_count, |
96 | const struct GNUNET_GNSRECORD_Data *rd); | 96 | const struct GNUNET_GNSRECORD_Data *rd); |
97 | 97 | ||
98 | /** | ||
99 | * Iterator called on obtained result for a GNS lookup. | ||
100 | * | ||
101 | * @param cls closure | ||
102 | * @param name result of the reverse lookup | ||
103 | */ | ||
104 | typedef void | ||
105 | (*GNUNET_GNS_ReverseLookupResultProcessor) (void *cls, | ||
106 | const char* name); | ||
107 | |||
108 | 98 | ||
109 | /** | 99 | /** |
110 | * Options for the GNS lookup. | 100 | * Options for the GNS lookup. |
@@ -138,13 +128,8 @@ enum GNUNET_GNS_LocalOptions | |||
138 | * @param zone zone to look in | 128 | * @param zone zone to look in |
139 | * @param type the GNS record type to look for | 129 | * @param type the GNS record type to look for |
140 | * @param options local options for the lookup | 130 | * @param options local options for the lookup |
141 | * @param shorten_zone_key the private key of the shorten zone (can be NULL); | ||
142 | * specify to enable automatic shortening (given a PSEU | ||
143 | * record, if a given pseudonym is not yet used in the | ||
144 | * shorten zone, we automatically add the respective zone | ||
145 | * under that name) | ||
146 | * @param proc function to call on result | 131 | * @param proc function to call on result |
147 | * @param proc_cls closure for processor | 132 | * @param proc_cls closure for @a proc |
148 | * @return handle to the queued request | 133 | * @return handle to the queued request |
149 | */ | 134 | */ |
150 | struct GNUNET_GNS_LookupRequest * | 135 | struct GNUNET_GNS_LookupRequest * |
@@ -153,27 +138,9 @@ GNUNET_GNS_lookup (struct GNUNET_GNS_Handle *handle, | |||
153 | const struct GNUNET_CRYPTO_EcdsaPublicKey *zone, | 138 | const struct GNUNET_CRYPTO_EcdsaPublicKey *zone, |
154 | uint32_t type, | 139 | uint32_t type, |
155 | enum GNUNET_GNS_LocalOptions options, | 140 | enum GNUNET_GNS_LocalOptions options, |
156 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *shorten_zone_key, | ||
157 | GNUNET_GNS_LookupResultProcessor proc, | 141 | GNUNET_GNS_LookupResultProcessor proc, |
158 | void *proc_cls); | 142 | void *proc_cls); |
159 | 143 | ||
160 | /** | ||
161 | * Perform an asynchronous reverse lookup operation on the GNS. | ||
162 | * | ||
163 | * @param handle handle to the GNS service | ||
164 | * @param zone_key zone to find a name for | ||
165 | * @param root_key our zone | ||
166 | * @param proc processor to call on result | ||
167 | * @param proc_cls closure for @a proc | ||
168 | * @return handle to the request | ||
169 | */ | ||
170 | struct GNUNET_GNS_ReverseLookupRequest * | ||
171 | GNUNET_GNS_reverse_lookup (struct GNUNET_GNS_Handle *handle, | ||
172 | const struct GNUNET_CRYPTO_EcdsaPublicKey *zone_key, | ||
173 | const struct GNUNET_CRYPTO_EcdsaPublicKey *root_key, | ||
174 | GNUNET_GNS_ReverseLookupResultProcessor proc, | ||
175 | void *proc_cls); | ||
176 | |||
177 | 144 | ||
178 | /** | 145 | /** |
179 | * Cancel pending lookup request | 146 | * Cancel pending lookup request |
diff --git a/src/include/gnunet_mq_lib.h b/src/include/gnunet_mq_lib.h index f9ad6c913..b05128ccc 100644 --- a/src/include/gnunet_mq_lib.h +++ b/src/include/gnunet_mq_lib.h | |||
@@ -32,8 +32,8 @@ | |||
32 | * | 32 | * |
33 | * @{ | 33 | * @{ |
34 | */ | 34 | */ |
35 | #ifndef GNUNET_MQ_H | 35 | #ifndef GNUNET_MQ_LIB_H |
36 | #define GNUNET_MQ_H | 36 | #define GNUNET_MQ_LIB_H |
37 | 37 | ||
38 | 38 | ||
39 | /** | 39 | /** |
@@ -473,7 +473,6 @@ struct GNUNET_MQ_MessageHandler | |||
473 | */ | 473 | */ |
474 | struct GNUNET_MQ_Envelope * | 474 | struct GNUNET_MQ_Envelope * |
475 | GNUNET_MQ_msg_ (struct GNUNET_MessageHeader **mhp, | 475 | GNUNET_MQ_msg_ (struct GNUNET_MessageHeader **mhp, |
476 | |||
477 | uint16_t size, | 476 | uint16_t size, |
478 | uint16_t type); | 477 | uint16_t type); |
479 | 478 | ||
@@ -511,6 +510,17 @@ GNUNET_MQ_get_current_envelope (struct GNUNET_MQ_Handle *mq); | |||
511 | 510 | ||
512 | 511 | ||
513 | /** | 512 | /** |
513 | * Function to copy an envelope. The envelope must not yet | ||
514 | * be in any queue or have any options or callbacks set. | ||
515 | * | ||
516 | * @param env envelope to copy | ||
517 | * @return copy of @a env | ||
518 | */ | ||
519 | struct GNUNET_MQ_Envelope * | ||
520 | GNUNET_MQ_env_copy (struct GNUNET_MQ_Envelope *env); | ||
521 | |||
522 | |||
523 | /** | ||
514 | * Function to obtain the last envelope in the queue. | 524 | * Function to obtain the last envelope in the queue. |
515 | * | 525 | * |
516 | * @param mq message queue to interrogate | 526 | * @param mq message queue to interrogate |
@@ -548,6 +558,17 @@ GNUNET_MQ_env_get_options (struct GNUNET_MQ_Envelope *env, | |||
548 | 558 | ||
549 | 559 | ||
550 | /** | 560 | /** |
561 | * Remove the first envelope that has not yet been sent from the message | ||
562 | * queue and return it. | ||
563 | * | ||
564 | * @param mq queue to remove envelope from | ||
565 | * @return NULL if queue is empty (or has no envelope that is not under transmission) | ||
566 | */ | ||
567 | struct GNUNET_MQ_Envelope * | ||
568 | GNUNET_MQ_unsent_head (struct GNUNET_MQ_Handle *mq); | ||
569 | |||
570 | |||
571 | /** | ||
551 | * Set application-specific options for this queue. | 572 | * Set application-specific options for this queue. |
552 | * | 573 | * |
553 | * @param mq message queue to set options for | 574 | * @param mq message queue to set options for |
diff --git a/src/include/gnunet_mysql_lib.h b/src/include/gnunet_mysql_lib.h index fc6f42f86..6a1e5b3ac 100644 --- a/src/include/gnunet_mysql_lib.h +++ b/src/include/gnunet_mysql_lib.h | |||
@@ -61,10 +61,12 @@ struct GNUNET_MYSQL_StatementHandle; | |||
61 | * @param cls user-defined argument | 61 | * @param cls user-defined argument |
62 | * @param num_values number of elements in values | 62 | * @param num_values number of elements in values |
63 | * @param values values returned by MySQL | 63 | * @param values values returned by MySQL |
64 | * @return GNUNET_OK to continue iterating, GNUNET_SYSERR to abort | 64 | * @return #GNUNET_OK to continue iterating, #GNUNET_SYSERR to abort |
65 | */ | 65 | */ |
66 | typedef int (*GNUNET_MYSQL_DataProcessor) (void *cls, unsigned int num_values, | 66 | typedef int |
67 | MYSQL_BIND * values); | 67 | (*GNUNET_MYSQL_DataProcessor) (void *cls, |
68 | unsigned int num_values, | ||
69 | MYSQL_BIND * values); | ||
68 | 70 | ||
69 | 71 | ||
70 | /** | 72 | /** |
@@ -102,7 +104,7 @@ GNUNET_MYSQL_statements_invalidate (struct GNUNET_MYSQL_Context *mc); | |||
102 | /** | 104 | /** |
103 | * Get internal handle for a prepared statement. This function should rarely | 105 | * Get internal handle for a prepared statement. This function should rarely |
104 | * be used, and if, with caution! On failures during the interaction with | 106 | * be used, and if, with caution! On failures during the interaction with |
105 | * the handle, you must call 'GNUNET_MYSQL_statements_invalidate'! | 107 | * the handle, you must call #GNUNET_MYSQL_statements_invalidate()! |
106 | * | 108 | * |
107 | * @param sh prepared statement to introspect | 109 | * @param sh prepared statement to introspect |
108 | * @return MySQL statement handle, NULL on error | 110 | * @return MySQL statement handle, NULL on error |
@@ -129,8 +131,8 @@ GNUNET_MYSQL_statement_prepare (struct GNUNET_MYSQL_Context *mc, | |||
129 | * | 131 | * |
130 | * @param mc mysql context | 132 | * @param mc mysql context |
131 | * @param sql SQL statement to run | 133 | * @param sql SQL statement to run |
132 | * @return GNUNET_OK on success | 134 | * @return #GNUNET_OK on success |
133 | * GNUNET_SYSERR if there was a problem | 135 | * #GNUNET_SYSERR if there was a problem |
134 | */ | 136 | */ |
135 | int | 137 | int |
136 | GNUNET_MYSQL_statement_run (struct GNUNET_MYSQL_Context *mc, | 138 | GNUNET_MYSQL_statement_run (struct GNUNET_MYSQL_Context *mc, |
diff --git a/src/include/gnunet_plugin_lib.h b/src/include/gnunet_plugin_lib.h index b76b9f9cf..9e3e72a21 100644 --- a/src/include/gnunet_plugin_lib.h +++ b/src/include/gnunet_plugin_lib.h | |||
@@ -87,7 +87,7 @@ GNUNET_PLUGIN_load (const char *library_name, | |||
87 | 87 | ||
88 | 88 | ||
89 | /** | 89 | /** |
90 | * Signature of a function called by 'GNUNET_PLUGIN_load_all'. | 90 | * Signature of a function called by #GNUNET_PLUGIN_load_all(). |
91 | * | 91 | * |
92 | * @param cls closure | 92 | * @param cls closure |
93 | * @param library_name full name of the library (to be used with | 93 | * @param library_name full name of the library (to be used with |
diff --git a/src/include/gnunet_pq_lib.h b/src/include/gnunet_pq_lib.h index 33a3e5425..756370b74 100644 --- a/src/include/gnunet_pq_lib.h +++ b/src/include/gnunet_pq_lib.h | |||
@@ -15,11 +15,11 @@ | |||
15 | */ | 15 | */ |
16 | /** | 16 | /** |
17 | * @file include/gnunet_pq_lib.h | 17 | * @file include/gnunet_pq_lib.h |
18 | * @brief helper functions for DB interactions | 18 | * @brief helper functions for Postgres DB interactions |
19 | * @author Christian Grothoff | 19 | * @author Christian Grothoff |
20 | */ | 20 | */ |
21 | #ifndef GNUNET_PQ_LIB_H_ | 21 | #ifndef GNUNET_PQ_LIB_H |
22 | #define GNUNET_PQ_LIB_H_ | 22 | #define GNUNET_PQ_LIB_H |
23 | 23 | ||
24 | #include <libpq-fe.h> | 24 | #include <libpq-fe.h> |
25 | #include "gnunet_util_lib.h" | 25 | #include "gnunet_util_lib.h" |
@@ -317,20 +317,6 @@ GNUNET_PQ_result_spec_fixed_size (const char *name, | |||
317 | 317 | ||
318 | 318 | ||
319 | /** | 319 | /** |
320 | * Variable-size result expected. | ||
321 | * | ||
322 | * @param name name of the field in the table | ||
323 | * @param[out] dst where to store the result, allocated | ||
324 | * @param[out] sptr where to store the size of @a dst | ||
325 | * @return array entry for the result specification to use | ||
326 | */ | ||
327 | struct GNUNET_PQ_ResultSpec | ||
328 | GNUNET_PQ_result_spec_variable_size (const char *name, | ||
329 | void **dst, | ||
330 | size_t *sptr); | ||
331 | |||
332 | |||
333 | /** | ||
334 | * 0-terminated string expected. | 320 | * 0-terminated string expected. |
335 | * | 321 | * |
336 | * @param name name of the field in the table | 322 | * @param name name of the field in the table |
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index eeb9a8a92..8822a6302 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h | |||
@@ -1640,6 +1640,12 @@ extern "C" | |||
1640 | * Demand the whole element from the other | 1640 | * Demand the whole element from the other |
1641 | * peer, given only the hash code. | 1641 | * peer, given only the hash code. |
1642 | */ | 1642 | */ |
1643 | #define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_REQUEST_FULL 565 | ||
1644 | |||
1645 | /** | ||
1646 | * Demand the whole element from the other | ||
1647 | * peer, given only the hash code. | ||
1648 | */ | ||
1643 | #define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DEMAND 566 | 1649 | #define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DEMAND 566 |
1644 | 1650 | ||
1645 | /** | 1651 | /** |
@@ -1795,6 +1801,19 @@ extern "C" | |||
1795 | */ | 1801 | */ |
1796 | #define GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_CONNECT 596 | 1802 | #define GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_CONNECT 596 |
1797 | 1803 | ||
1804 | /** | ||
1805 | * Request all missing elements from the other peer, | ||
1806 | * based on their sets and the elements we previously sent | ||
1807 | * with #GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENTS. | ||
1808 | */ | ||
1809 | #define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_DONE 597 | ||
1810 | |||
1811 | /** | ||
1812 | * Send a set element, not as response to a demand but because | ||
1813 | * we're sending the full set. | ||
1814 | */ | ||
1815 | #define GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_ELEMENT 598 | ||
1816 | |||
1798 | 1817 | ||
1799 | /******************************************************************************* | 1818 | /******************************************************************************* |
1800 | * TESTBED LOGGER message types | 1819 | * TESTBED LOGGER message types |
diff --git a/src/include/gnunet_set_service.h b/src/include/gnunet_set_service.h index 15bc0f04f..6e822d82e 100644 --- a/src/include/gnunet_set_service.h +++ b/src/include/gnunet_set_service.h | |||
@@ -126,7 +126,7 @@ enum GNUNET_SET_Status | |||
126 | 126 | ||
127 | /** | 127 | /** |
128 | * Element should be added to the result set | 128 | * Element should be added to the result set |
129 | * of the remove peer, i.e. the remote peer is | 129 | * of the remote peer, i.e. the remote peer is |
130 | * missing an element. | 130 | * missing an element. |
131 | * | 131 | * |
132 | * Only applies to #GNUNET_SET_RESULT_SYMMETRIC | 132 | * Only applies to #GNUNET_SET_RESULT_SYMMETRIC |
@@ -153,6 +153,7 @@ enum GNUNET_SET_Status | |||
153 | }; | 153 | }; |
154 | 154 | ||
155 | 155 | ||
156 | |||
156 | /** | 157 | /** |
157 | * The way results are given to the client. | 158 | * The way results are given to the client. |
158 | */ | 159 | */ |
@@ -212,6 +213,58 @@ struct GNUNET_SET_Element | |||
212 | 213 | ||
213 | 214 | ||
214 | /** | 215 | /** |
216 | * Possible options to pass to a set operation. | ||
217 | * | ||
218 | * Used as tag for struct #GNUNET_SET_Option. | ||
219 | */ | ||
220 | enum GNUNET_SET_OptionType | ||
221 | { | ||
222 | /** | ||
223 | * List terminator. | ||
224 | */ | ||
225 | GNUNET_SET_OPTION_END=0, | ||
226 | /** | ||
227 | * Fail set operations when the other peer shows weird behavior | ||
228 | * that might by a Byzantine fault. | ||
229 | * | ||
230 | * For set union, 'v.num' is a lower bound on elements | ||
231 | * that the other peer must have in common with us. | ||
232 | */ | ||
233 | GNUNET_SET_OPTION_BYZANTINE=1, | ||
234 | /** | ||
235 | * Do not use the optimized set operation, but send full sets. | ||
236 | * Might trigger Byzantine fault detection. | ||
237 | */ | ||
238 | GNUNET_SET_OPTION_FORCE_FULL=2, | ||
239 | /** | ||
240 | * Only use optimized set operations, even though for this | ||
241 | * particular set operation they might be much slower. | ||
242 | * Might trigger Byzantine fault detection. | ||
243 | */ | ||
244 | GNUNET_SET_OPTION_FORCE_DELTA=4, | ||
245 | }; | ||
246 | |||
247 | |||
248 | /** | ||
249 | * Option for set operations. | ||
250 | */ | ||
251 | struct GNUNET_SET_Option | ||
252 | { | ||
253 | /** | ||
254 | * Type of the option. | ||
255 | */ | ||
256 | enum GNUNET_SET_OptionType type; | ||
257 | |||
258 | /** | ||
259 | * Value for the option, only used with some options. | ||
260 | */ | ||
261 | union { | ||
262 | uint64_t num; | ||
263 | } v; | ||
264 | }; | ||
265 | |||
266 | |||
267 | /** | ||
215 | * Continuation used for some of the set operations | 268 | * Continuation used for some of the set operations |
216 | * | 269 | * |
217 | * @param cls closure | 270 | * @param cls closure |
@@ -226,11 +279,13 @@ typedef void | |||
226 | * | 279 | * |
227 | * @param cls closure | 280 | * @param cls closure |
228 | * @param element a result element, only valid if status is #GNUNET_SET_STATUS_OK | 281 | * @param element a result element, only valid if status is #GNUNET_SET_STATUS_OK |
282 | * @param current_size current set size | ||
229 | * @param status see `enum GNUNET_SET_Status` | 283 | * @param status see `enum GNUNET_SET_Status` |
230 | */ | 284 | */ |
231 | typedef void | 285 | typedef void |
232 | (*GNUNET_SET_ResultIterator) (void *cls, | 286 | (*GNUNET_SET_ResultIterator) (void *cls, |
233 | const struct GNUNET_SET_Element *element, | 287 | const struct GNUNET_SET_Element *element, |
288 | uint64_t current_size, | ||
234 | enum GNUNET_SET_Status status); | 289 | enum GNUNET_SET_Status status); |
235 | 290 | ||
236 | /** | 291 | /** |
@@ -367,6 +422,7 @@ GNUNET_SET_prepare (const struct GNUNET_PeerIdentity *other_peer, | |||
367 | const struct GNUNET_HashCode *app_id, | 422 | const struct GNUNET_HashCode *app_id, |
368 | const struct GNUNET_MessageHeader *context_msg, | 423 | const struct GNUNET_MessageHeader *context_msg, |
369 | enum GNUNET_SET_ResultMode result_mode, | 424 | enum GNUNET_SET_ResultMode result_mode, |
425 | struct GNUNET_SET_Option options[], | ||
370 | GNUNET_SET_ResultIterator result_cb, | 426 | GNUNET_SET_ResultIterator result_cb, |
371 | void *result_cls); | 427 | void *result_cls); |
372 | 428 | ||
@@ -420,6 +476,7 @@ GNUNET_SET_listen_cancel (struct GNUNET_SET_ListenHandle *lh); | |||
420 | struct GNUNET_SET_OperationHandle * | 476 | struct GNUNET_SET_OperationHandle * |
421 | GNUNET_SET_accept (struct GNUNET_SET_Request *request, | 477 | GNUNET_SET_accept (struct GNUNET_SET_Request *request, |
422 | enum GNUNET_SET_ResultMode result_mode, | 478 | enum GNUNET_SET_ResultMode result_mode, |
479 | struct GNUNET_SET_Option options[], | ||
423 | GNUNET_SET_ResultIterator result_cb, | 480 | GNUNET_SET_ResultIterator result_cb, |
424 | void *result_cls); | 481 | void *result_cls); |
425 | 482 | ||
diff --git a/src/include/gnunet_sq_lib.h b/src/include/gnunet_sq_lib.h new file mode 100644 index 000000000..c03f83e07 --- /dev/null +++ b/src/include/gnunet_sq_lib.h | |||
@@ -0,0 +1,440 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2017 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify it under the | ||
6 | terms of the GNU General Public License as published by the Free Software | ||
7 | Foundation; either version 3, or (at your option) any later version. | ||
8 | |||
9 | GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY | ||
10 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
11 | A PARTICULAR PURPOSE. See the GNU General Public License for more details. | ||
12 | |||
13 | You should have received a copy of the GNU General Public License along with | ||
14 | GNUnet; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/> | ||
15 | */ | ||
16 | /** | ||
17 | * @file include/gnunet_sq_lib.h | ||
18 | * @brief helper functions for Sqlite3 DB interactions | ||
19 | * @author Christian Grothoff | ||
20 | */ | ||
21 | #ifndef GNUNET_SQ_LIB_H | ||
22 | #define GNUNET_SQ_LIB_H | ||
23 | |||
24 | #include <sqlite3.h> | ||
25 | #include "gnunet_util_lib.h" | ||
26 | |||
27 | |||
28 | /** | ||
29 | * Function called to convert input argument into SQL parameters. | ||
30 | * | ||
31 | * @param cls closure | ||
32 | * @param data pointer to input argument | ||
33 | * @param data_len number of bytes in @a data (if applicable) | ||
34 | * @param stmt sqlite statement to bind parameters for | ||
35 | * @param off offset of the argument to bind in @a stmt, numbered from 1, | ||
36 | * so immediately suitable for passing to `sqlite3_bind`-functions. | ||
37 | * @return #GNUNET_SYSERR on error, #GNUNET_OK on success | ||
38 | */ | ||
39 | typedef int | ||
40 | (*GNUNET_SQ_QueryConverter)(void *cls, | ||
41 | const void *data, | ||
42 | size_t data_len, | ||
43 | sqlite3_stmt *stmt, | ||
44 | unsigned int off); | ||
45 | |||
46 | |||
47 | /** | ||
48 | * @brief Description of a DB query parameter. | ||
49 | */ | ||
50 | struct GNUNET_SQ_QueryParam | ||
51 | { | ||
52 | |||
53 | /** | ||
54 | * Function for how to handle this type of entry. | ||
55 | */ | ||
56 | GNUNET_SQ_QueryConverter conv; | ||
57 | |||
58 | /** | ||
59 | * Closure for @e conv. | ||
60 | */ | ||
61 | void *conv_cls; | ||
62 | |||
63 | /** | ||
64 | * Data or NULL. | ||
65 | */ | ||
66 | const void *data; | ||
67 | |||
68 | /** | ||
69 | * Size of @e data | ||
70 | */ | ||
71 | size_t size; | ||
72 | |||
73 | /** | ||
74 | * Number of parameters eaten by this operation. | ||
75 | */ | ||
76 | unsigned int num_params; | ||
77 | }; | ||
78 | |||
79 | |||
80 | /** | ||
81 | * End of query parameter specification. | ||
82 | */ | ||
83 | #define GNUNET_SQ_query_param_end { NULL, NULL, NULL, 0, 0 } | ||
84 | |||
85 | |||
86 | /** | ||
87 | * Generate query parameter for a buffer @a ptr of | ||
88 | * @a ptr_size bytes. | ||
89 | * | ||
90 | * @param ptr pointer to the query parameter to pass | ||
91 | * @oaran ptr_size number of bytes in @a ptr | ||
92 | */ | ||
93 | struct GNUNET_SQ_QueryParam | ||
94 | GNUNET_SQ_query_param_fixed_size (const void *ptr, | ||
95 | size_t ptr_size); | ||
96 | |||
97 | |||
98 | |||
99 | /** | ||
100 | * Generate query parameter for a string. | ||
101 | * | ||
102 | * @param ptr pointer to the string query parameter to pass | ||
103 | */ | ||
104 | struct GNUNET_SQ_QueryParam | ||
105 | GNUNET_SQ_query_param_string (const char *ptr); | ||
106 | |||
107 | |||
108 | /** | ||
109 | * Generate fixed-size query parameter with size determined | ||
110 | * by variable type. | ||
111 | * | ||
112 | * @param x pointer to the query parameter to pass. | ||
113 | */ | ||
114 | #define GNUNET_SQ_query_param_auto_from_type(x) GNUNET_SQ_query_param_fixed_size ((x), sizeof (*(x))) | ||
115 | |||
116 | |||
117 | /** | ||
118 | * Generate query parameter for an RSA public key. The | ||
119 | * database must contain a BLOB type in the respective position. | ||
120 | * | ||
121 | * @param x the query parameter to pass. | ||
122 | */ | ||
123 | struct GNUNET_SQ_QueryParam | ||
124 | GNUNET_SQ_query_param_rsa_public_key (const struct GNUNET_CRYPTO_RsaPublicKey *x); | ||
125 | |||
126 | |||
127 | /** | ||
128 | * Generate query parameter for an RSA signature. The | ||
129 | * database must contain a BLOB type in the respective position. | ||
130 | * | ||
131 | * @param x the query parameter to pass | ||
132 | */ | ||
133 | struct GNUNET_SQ_QueryParam | ||
134 | GNUNET_SQ_query_param_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *x); | ||
135 | |||
136 | |||
137 | /** | ||
138 | * Generate query parameter for an absolute time value. | ||
139 | * The database must store a 64-bit integer. | ||
140 | * | ||
141 | * @param x pointer to the query parameter to pass | ||
142 | */ | ||
143 | struct GNUNET_SQ_QueryParam | ||
144 | GNUNET_SQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x); | ||
145 | |||
146 | |||
147 | /** | ||
148 | * Generate query parameter for an absolute time value. | ||
149 | * The database must store a 64-bit integer. | ||
150 | * | ||
151 | * @param x pointer to the query parameter to pass | ||
152 | */ | ||
153 | struct GNUNET_SQ_QueryParam | ||
154 | GNUNET_SQ_query_param_absolute_time_nbo (const struct GNUNET_TIME_AbsoluteNBO *x); | ||
155 | |||
156 | |||
157 | /** | ||
158 | * Generate query parameter for an uint16_t in host byte order. | ||
159 | * | ||
160 | * @param x pointer to the query parameter to pass | ||
161 | */ | ||
162 | struct GNUNET_SQ_QueryParam | ||
163 | GNUNET_SQ_query_param_uint16 (const uint16_t *x); | ||
164 | |||
165 | |||
166 | /** | ||
167 | * Generate query parameter for an uint32_t in host byte order. | ||
168 | * | ||
169 | * @param x pointer to the query parameter to pass | ||
170 | */ | ||
171 | struct GNUNET_SQ_QueryParam | ||
172 | GNUNET_SQ_query_param_uint32 (const uint32_t *x); | ||
173 | |||
174 | |||
175 | /** | ||
176 | * Generate query parameter for an uint16_t in host byte order. | ||
177 | * | ||
178 | * @param x pointer to the query parameter to pass | ||
179 | */ | ||
180 | struct GNUNET_SQ_QueryParam | ||
181 | GNUNET_SQ_query_param_uint64 (const uint64_t *x); | ||
182 | |||
183 | |||
184 | /** | ||
185 | * Extract data from a Postgres database @a result at row @a row. | ||
186 | * | ||
187 | * @param cls closure | ||
188 | * @param result where to extract data from | ||
189 | * @param column column to extract data from | ||
190 | * @param[in,out] dst_size where to store size of result, may be NULL | ||
191 | * @param[out] dst where to store the result | ||
192 | * @return | ||
193 | * #GNUNET_YES if all results could be extracted | ||
194 | * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) | ||
195 | */ | ||
196 | typedef int | ||
197 | (*GNUNET_SQ_ResultConverter)(void *cls, | ||
198 | sqlite3_stmt *result, | ||
199 | unsigned int column, | ||
200 | size_t *dst_size, | ||
201 | void *dst); | ||
202 | |||
203 | |||
204 | /** | ||
205 | * @brief Description of a DB result cell. | ||
206 | */ | ||
207 | struct GNUNET_SQ_ResultSpec; | ||
208 | |||
209 | |||
210 | /** | ||
211 | * Function called to clean up memory allocated | ||
212 | * by a #GNUNET_SQ_ResultConverter. | ||
213 | * | ||
214 | * @param cls closure | ||
215 | */ | ||
216 | typedef void | ||
217 | (*GNUNET_SQ_ResultCleanup)(void *cls); | ||
218 | |||
219 | |||
220 | /** | ||
221 | * @brief Description of a DB result cell. | ||
222 | */ | ||
223 | struct GNUNET_SQ_ResultSpec | ||
224 | { | ||
225 | |||
226 | /** | ||
227 | * What is the format of the result? | ||
228 | */ | ||
229 | GNUNET_SQ_ResultConverter conv; | ||
230 | |||
231 | /** | ||
232 | * Function to clean up result data, NULL if cleanup is | ||
233 | * not necessary. | ||
234 | */ | ||
235 | GNUNET_SQ_ResultCleanup cleaner; | ||
236 | |||
237 | /** | ||
238 | * Closure for @e conv and @e cleaner. | ||
239 | */ | ||
240 | void *cls; | ||
241 | |||
242 | /** | ||
243 | * Destination for the data. | ||
244 | */ | ||
245 | void *dst; | ||
246 | |||
247 | /** | ||
248 | * Allowed size for the data, 0 for variable-size | ||
249 | * (in this case, the type of @e dst is a `void **` | ||
250 | * and we need to allocate a buffer of the right size). | ||
251 | */ | ||
252 | size_t dst_size; | ||
253 | |||
254 | /** | ||
255 | * Where to store actual size of the result. If left at | ||
256 | * NULL, will be made to point to @e dst_size before | ||
257 | * @a conv is called. | ||
258 | */ | ||
259 | size_t *result_size; | ||
260 | |||
261 | /** | ||
262 | * Number of parameters (columns) eaten by this operation. | ||
263 | */ | ||
264 | unsigned int num_params; | ||
265 | |||
266 | }; | ||
267 | |||
268 | |||
269 | /** | ||
270 | * End of result parameter specification. | ||
271 | * | ||
272 | * @return array last entry for the result specification to use | ||
273 | */ | ||
274 | #define GNUNET_SQ_result_spec_end { NULL, NULL, NULL, NULL, 0, NULL } | ||
275 | |||
276 | |||
277 | /** | ||
278 | * Variable-size result expected. | ||
279 | * | ||
280 | * @param[out] dst where to store the result, allocated | ||
281 | * @param[out] sptr where to store the size of @a dst | ||
282 | * @return array entry for the result specification to use | ||
283 | */ | ||
284 | struct GNUNET_SQ_ResultSpec | ||
285 | GNUNET_SQ_result_spec_variable_size (void **dst, | ||
286 | size_t *sptr); | ||
287 | |||
288 | |||
289 | /** | ||
290 | * Fixed-size result expected. | ||
291 | * | ||
292 | * @param[out] dst where to store the result | ||
293 | * @param dst_size number of bytes in @a dst | ||
294 | * @return array entry for the result specification to use | ||
295 | */ | ||
296 | struct GNUNET_SQ_ResultSpec | ||
297 | GNUNET_SQ_result_spec_fixed_size (void *dst, | ||
298 | size_t dst_size); | ||
299 | |||
300 | |||
301 | /** | ||
302 | * We expect a fixed-size result, with size determined by the type of `* dst` | ||
303 | * | ||
304 | * @param dst point to where to store the result, type fits expected result size | ||
305 | * @return array entry for the result specification to use | ||
306 | */ | ||
307 | #define GNUNET_SQ_result_spec_auto_from_type(dst) GNUNET_SQ_result_spec_fixed_size ((dst), sizeof (*(dst))) | ||
308 | |||
309 | |||
310 | /** | ||
311 | * Variable-size result expected. | ||
312 | * | ||
313 | * @param[out] dst where to store the result, allocated | ||
314 | * @param[out] sptr where to store the size of @a dst | ||
315 | * @return array entry for the result specification to use | ||
316 | */ | ||
317 | struct GNUNET_SQ_ResultSpec | ||
318 | GNUNET_SQ_result_spec_variable_size (void **dst, | ||
319 | size_t *sptr); | ||
320 | |||
321 | |||
322 | /** | ||
323 | * 0-terminated string expected. | ||
324 | * | ||
325 | * @param[out] dst where to store the result, allocated | ||
326 | * @return array entry for the result specification to use | ||
327 | */ | ||
328 | struct GNUNET_SQ_ResultSpec | ||
329 | GNUNET_SQ_result_spec_string (char **dst); | ||
330 | |||
331 | |||
332 | /** | ||
333 | * RSA public key expected. | ||
334 | * | ||
335 | * @param[out] rsa where to store the result | ||
336 | * @return array entry for the result specification to use | ||
337 | */ | ||
338 | struct GNUNET_SQ_ResultSpec | ||
339 | GNUNET_SQ_result_spec_rsa_public_key (struct GNUNET_CRYPTO_RsaPublicKey **rsa); | ||
340 | |||
341 | |||
342 | /** | ||
343 | * RSA signature expected. | ||
344 | * | ||
345 | * @param[out] sig where to store the result; | ||
346 | * @return array entry for the result specification to use | ||
347 | */ | ||
348 | struct GNUNET_SQ_ResultSpec | ||
349 | GNUNET_SQ_result_spec_rsa_signature (struct GNUNET_CRYPTO_RsaSignature **sig); | ||
350 | |||
351 | |||
352 | /** | ||
353 | * Absolute time expected. | ||
354 | * | ||
355 | * @param[out] at where to store the result | ||
356 | * @return array entry for the result specification to use | ||
357 | */ | ||
358 | struct GNUNET_SQ_ResultSpec | ||
359 | GNUNET_SQ_result_spec_absolute_time (struct GNUNET_TIME_Absolute *at); | ||
360 | |||
361 | |||
362 | /** | ||
363 | * Absolute time expected. | ||
364 | * | ||
365 | * @param[out] at where to store the result | ||
366 | * @return array entry for the result specification to use | ||
367 | */ | ||
368 | struct GNUNET_SQ_ResultSpec | ||
369 | GNUNET_SQ_result_spec_absolute_time_nbo (struct GNUNET_TIME_AbsoluteNBO *at); | ||
370 | |||
371 | |||
372 | /** | ||
373 | * uint16_t expected. | ||
374 | * | ||
375 | * @param[out] u16 where to store the result | ||
376 | * @return array entry for the result specification to use | ||
377 | */ | ||
378 | struct GNUNET_SQ_ResultSpec | ||
379 | GNUNET_SQ_result_spec_uint16 (uint16_t *u16); | ||
380 | |||
381 | |||
382 | /** | ||
383 | * uint32_t expected. | ||
384 | * | ||
385 | * @param[out] u32 where to store the result | ||
386 | * @return array entry for the result specification to use | ||
387 | */ | ||
388 | struct GNUNET_SQ_ResultSpec | ||
389 | GNUNET_SQ_result_spec_uint32 (uint32_t *u32); | ||
390 | |||
391 | |||
392 | /** | ||
393 | * uint64_t expected. | ||
394 | * | ||
395 | * @param[out] u64 where to store the result | ||
396 | * @return array entry for the result specification to use | ||
397 | */ | ||
398 | struct GNUNET_SQ_ResultSpec | ||
399 | GNUNET_SQ_result_spec_uint64 (uint64_t *u64); | ||
400 | |||
401 | |||
402 | /** | ||
403 | * Execute a prepared statement. | ||
404 | * | ||
405 | * @param db_conn database connection | ||
406 | * @param params parameters to the statement | ||
407 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
408 | */ | ||
409 | int | ||
410 | GNUNET_SQ_bind (sqlite3_stmt *stmt, | ||
411 | const struct GNUNET_SQ_QueryParam *params); | ||
412 | |||
413 | |||
414 | /** | ||
415 | * Extract results from a query result according to the given specification. | ||
416 | * | ||
417 | * @param result result to process | ||
418 | * @param[in,out] rs result specification to extract for | ||
419 | * @return | ||
420 | * #GNUNET_OK if all results could be extracted | ||
421 | * #GNUNET_SYSERR if a result was invalid (non-existing field) | ||
422 | */ | ||
423 | int | ||
424 | GNUNET_SQ_extract_result (sqlite3_stmt *result, | ||
425 | struct GNUNET_SQ_ResultSpec *rs); | ||
426 | |||
427 | |||
428 | /** | ||
429 | * Free all memory that was allocated in @a rs during | ||
430 | * #GNUNET_SQ_extract_result(). | ||
431 | * | ||
432 | * @param rs reult specification to clean up | ||
433 | */ | ||
434 | void | ||
435 | GNUNET_SQ_cleanup_result (struct GNUNET_SQ_ResultSpec *rs); | ||
436 | |||
437 | |||
438 | #endif /* GNUNET_SQ_LIB_H_ */ | ||
439 | |||
440 | /* end of include/gnunet_sq_lib.h */ | ||
diff --git a/src/include/gnunet_strings_lib.h b/src/include/gnunet_strings_lib.h index 0328882dd..144780c82 100644 --- a/src/include/gnunet_strings_lib.h +++ b/src/include/gnunet_strings_lib.h | |||
@@ -360,6 +360,18 @@ GNUNET_STRINGS_base64_decode (const char *data, | |||
360 | 360 | ||
361 | 361 | ||
362 | /** | 362 | /** |
363 | * Convert a peer path to a human-readable string. | ||
364 | * | ||
365 | * @param pids array of PIDs to convert to a string | ||
366 | * @param num_pids length of the @a pids array | ||
367 | * @return string representing the array of @a pids | ||
368 | */ | ||
369 | char * | ||
370 | GNUNET_STRINGS_pp2s (const struct GNUNET_PeerIdentity *pids, | ||
371 | unsigned int num_pids); | ||
372 | |||
373 | |||
374 | /** | ||
363 | * Parse a path that might be an URI. | 375 | * Parse a path that might be an URI. |
364 | * | 376 | * |
365 | * @param path path to parse. Must be NULL-terminated. | 377 | * @param path path to parse. Must be NULL-terminated. |
@@ -477,7 +489,7 @@ GNUNET_STRINGS_to_address_ipv4 (const char *zt_addr, | |||
477 | 489 | ||
478 | 490 | ||
479 | /** | 491 | /** |
480 | * Parse an address given as a string into a | 492 | * Parse an address given as a string into a |
481 | * `struct sockaddr`. | 493 | * `struct sockaddr`. |
482 | * | 494 | * |
483 | * @param addr the address | 495 | * @param addr the address |
diff --git a/src/integration-tests/.gitignore b/src/integration-tests/.gitignore index c4d1568f0..46915b2a4 100644 --- a/src/integration-tests/.gitignore +++ b/src/integration-tests/.gitignore | |||
@@ -1,2 +1,10 @@ | |||
1 | gnunet_testing.py | 1 | gnunet_testing.py |
2 | gnunet_pyexpect.py | 2 | gnunet_pyexpect.py |
3 | gnunet_pyexpect.pyc | ||
4 | gnunet_testing.pyc | ||
5 | test_integration_bootstrap_and_connect.py | ||
6 | test_integration_clique.py | ||
7 | test_integration_disconnect_nat.py | ||
8 | test_integration_disconnect.py | ||
9 | test_integration_reconnect_nat.py | ||
10 | test_integration_reconnect.py | ||
diff --git a/src/multicast/Makefile.am b/src/multicast/Makefile.am index a598e8242..9abe38506 100644 --- a/src/multicast/Makefile.am +++ b/src/multicast/Makefile.am | |||
@@ -46,7 +46,7 @@ gnunet_service_multicast_SOURCES = \ | |||
46 | gnunet-service-multicast.c | 46 | gnunet-service-multicast.c |
47 | gnunet_service_multicast_LDADD = \ | 47 | gnunet_service_multicast_LDADD = \ |
48 | $(top_builddir)/src/util/libgnunetutil.la \ | 48 | $(top_builddir)/src/util/libgnunetutil.la \ |
49 | $(top_builddir)/src/cadet/libgnunetcadet.la \ | 49 | $(top_builddir)/src/cadet/libgnunetcadetnew.la \ |
50 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | 50 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ |
51 | $(GN_LIBINTL) | 51 | $(GN_LIBINTL) |
52 | 52 | ||
@@ -55,7 +55,7 @@ check_PROGRAMS = \ | |||
55 | test_multicast_multipeer | 55 | test_multicast_multipeer |
56 | 56 | ||
57 | if ENABLE_TEST_RUN | 57 | if ENABLE_TEST_RUN |
58 | AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; | 58 | AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@}; export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH; unset XDG_DATA_HOME; unset XDG_CONFIG_HOME; export GNUNET_FORCE_LOG=';;;;INFO' |
59 | TESTS = $(check_PROGRAMS) | 59 | TESTS = $(check_PROGRAMS) |
60 | endif | 60 | endif |
61 | 61 | ||
diff --git a/src/multicast/gnunet-service-multicast.c b/src/multicast/gnunet-service-multicast.c index de65e0ab7..b068f1308 100644 --- a/src/multicast/gnunet-service-multicast.c +++ b/src/multicast/gnunet-service-multicast.c | |||
@@ -163,6 +163,16 @@ struct Channel | |||
163 | struct GNUNET_PeerIdentity peer; | 163 | struct GNUNET_PeerIdentity peer; |
164 | 164 | ||
165 | /** | 165 | /** |
166 | * Current window size, set by cadet_notify_window_change() | ||
167 | */ | ||
168 | int32_t window_size; | ||
169 | |||
170 | /** | ||
171 | * Is the connection established? | ||
172 | */ | ||
173 | int8_t is_connected; | ||
174 | |||
175 | /** | ||
166 | * Is the remote peer admitted to the group? | 176 | * Is the remote peer admitted to the group? |
167 | * @see enum JoinStatus | 177 | * @see enum JoinStatus |
168 | */ | 178 | */ |
@@ -336,6 +346,17 @@ struct ReplayRequestKey | |||
336 | }; | 346 | }; |
337 | 347 | ||
338 | 348 | ||
349 | static struct Channel * | ||
350 | cadet_channel_create (struct Group *grp, struct GNUNET_PeerIdentity *peer); | ||
351 | |||
352 | static void | ||
353 | cadet_channel_destroy (struct Channel *chn); | ||
354 | |||
355 | static void | ||
356 | client_send_join_decision (struct Member *mem, | ||
357 | const struct MulticastJoinDecisionMessageHeader *hdcsn); | ||
358 | |||
359 | |||
339 | /** | 360 | /** |
340 | * Task run during shutdown. | 361 | * Task run during shutdown. |
341 | * | 362 | * |
@@ -497,7 +518,7 @@ replay_req_remove_client (struct Group *grp, struct GNUNET_SERVICE_Client *clien | |||
497 | { | 518 | { |
498 | if (c == client) | 519 | if (c == client) |
499 | { | 520 | { |
500 | GNUNET_CONTAINER_multihashmap_remove (replay_req_client, &key, client); | 521 | GNUNET_CONTAINER_multihashmap_remove (grp_replay_req, &key, client); |
501 | GNUNET_CONTAINER_multihashmap_iterator_destroy (it); | 522 | GNUNET_CONTAINER_multihashmap_iterator_destroy (it); |
502 | return GNUNET_YES; | 523 | return GNUNET_YES; |
503 | } | 524 | } |
@@ -653,6 +674,9 @@ client_send_origin (struct GNUNET_HashCode *pub_key_hash, | |||
653 | static void | 674 | static void |
654 | client_send_ack (struct GNUNET_HashCode *pub_key_hash) | 675 | client_send_ack (struct GNUNET_HashCode *pub_key_hash) |
655 | { | 676 | { |
677 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
678 | "Sending message ACK to client.\n"); | ||
679 | |||
656 | static struct GNUNET_MessageHeader *msg = NULL; | 680 | static struct GNUNET_MessageHeader *msg = NULL; |
657 | if (NULL == msg) | 681 | if (NULL == msg) |
658 | { | 682 | { |
@@ -672,36 +696,6 @@ struct CadetTransmitClosure | |||
672 | 696 | ||
673 | 697 | ||
674 | /** | 698 | /** |
675 | * CADET is ready to transmit a message. | ||
676 | */ | ||
677 | size_t | ||
678 | cadet_notify_transmit_ready (void *cls, size_t buf_size, void *buf) | ||
679 | { | ||
680 | if (0 == buf_size) | ||
681 | { | ||
682 | /* FIXME: connection closed */ | ||
683 | return 0; | ||
684 | } | ||
685 | struct CadetTransmitClosure *tcls = cls; | ||
686 | struct Channel *chn = tcls->chn; | ||
687 | uint16_t msg_size = ntohs (tcls->msg->size); | ||
688 | GNUNET_assert (msg_size <= buf_size); | ||
689 | GNUNET_memcpy (buf, tcls->msg, msg_size); | ||
690 | GNUNET_free (tcls); | ||
691 | |||
692 | if (0 == chn->msgs_pending) | ||
693 | { | ||
694 | GNUNET_break (0); | ||
695 | } | ||
696 | else if (0 == --chn->msgs_pending) | ||
697 | { | ||
698 | client_send_ack (&chn->group_pub_hash); | ||
699 | } | ||
700 | return msg_size; | ||
701 | } | ||
702 | |||
703 | |||
704 | /** | ||
705 | * Send a message to a CADET channel. | 699 | * Send a message to a CADET channel. |
706 | * | 700 | * |
707 | * @param chn Channel. | 701 | * @param chn Channel. |
@@ -710,53 +704,22 @@ cadet_notify_transmit_ready (void *cls, size_t buf_size, void *buf) | |||
710 | static void | 704 | static void |
711 | cadet_send_channel (struct Channel *chn, const struct GNUNET_MessageHeader *msg) | 705 | cadet_send_channel (struct Channel *chn, const struct GNUNET_MessageHeader *msg) |
712 | { | 706 | { |
713 | uint16_t msg_size = ntohs (msg->size); | 707 | struct GNUNET_MQ_Envelope * |
714 | struct GNUNET_MessageHeader *msg_copy = GNUNET_malloc (msg_size); | 708 | env = GNUNET_MQ_msg_copy (msg); |
715 | GNUNET_memcpy (msg_copy, msg, msg_size); | ||
716 | |||
717 | struct CadetTransmitClosure *tcls = GNUNET_malloc (sizeof (*tcls)); | ||
718 | tcls->chn = chn; | ||
719 | tcls->msg = msg_copy; | ||
720 | |||
721 | chn->msgs_pending++; | ||
722 | chn->tmit_handle | ||
723 | = GNUNET_CADET_notify_transmit_ready (chn->channel, GNUNET_NO, | ||
724 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
725 | msg_size, | ||
726 | &cadet_notify_transmit_ready, | ||
727 | tcls); | ||
728 | GNUNET_assert (NULL != chn->tmit_handle); | ||
729 | } | ||
730 | 709 | ||
710 | GNUNET_MQ_send (GNUNET_CADET_get_mq (chn->channel), env); | ||
731 | 711 | ||
732 | /** | 712 | if (0 < chn->window_size) |
733 | * Create new outgoing CADET channel. | 713 | { |
734 | * | 714 | client_send_ack (&chn->group_pub_hash); |
735 | * @param peer | 715 | } |
736 | * Peer to connect to. | 716 | else |
737 | * @param group_pub_key | 717 | { |
738 | * Public key of group the channel belongs to. | 718 | chn->msgs_pending++; |
739 | * @param group_pub_hash | 719 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
740 | * Hash of @a group_pub_key. | 720 | "%p Queuing message. Pending messages: %u\n", |
741 | * | 721 | chn, chn->msgs_pending); |
742 | * @return Channel. | 722 | } |
743 | */ | ||
744 | static struct Channel * | ||
745 | cadet_channel_create (struct Group *grp, struct GNUNET_PeerIdentity *peer) | ||
746 | { | ||
747 | struct Channel *chn = GNUNET_malloc (sizeof (*chn)); | ||
748 | chn->group = grp; | ||
749 | chn->group_pub_key = grp->pub_key; | ||
750 | chn->group_pub_hash = grp->pub_key_hash; | ||
751 | chn->peer = *peer; | ||
752 | chn->direction = DIR_OUTGOING; | ||
753 | chn->join_status = JOIN_WAITING; | ||
754 | chn->channel = GNUNET_CADET_channel_create (cadet, chn, &chn->peer, | ||
755 | &grp->cadet_port_hash, | ||
756 | GNUNET_CADET_OPTION_RELIABLE); | ||
757 | GNUNET_CONTAINER_multihashmap_put (channels_out, &chn->group_pub_hash, chn, | ||
758 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
759 | return chn; | ||
760 | } | 723 | } |
761 | 724 | ||
762 | 725 | ||
@@ -787,7 +750,7 @@ cadet_send_join_decision_cb (void *cls, | |||
787 | const struct MulticastJoinDecisionMessageHeader *hdcsn = cls; | 750 | const struct MulticastJoinDecisionMessageHeader *hdcsn = cls; |
788 | struct Channel *chn = channel; | 751 | struct Channel *chn = channel; |
789 | 752 | ||
790 | const struct MulticastJoinDecisionMessage *dcsn = | 753 | const struct MulticastJoinDecisionMessage *dcsn = |
791 | (struct MulticastJoinDecisionMessage *) &hdcsn[1]; | 754 | (struct MulticastJoinDecisionMessage *) &hdcsn[1]; |
792 | 755 | ||
793 | if (0 == memcmp (&hdcsn->member_pub_key, &chn->member_pub_key, sizeof (chn->member_pub_key)) | 756 | if (0 == memcmp (&hdcsn->member_pub_key, &chn->member_pub_key, sizeof (chn->member_pub_key)) |
@@ -870,31 +833,74 @@ cadet_send_parents (struct GNUNET_HashCode *pub_key_hash, | |||
870 | 833 | ||
871 | 834 | ||
872 | /** | 835 | /** |
873 | * New incoming CADET channel. | 836 | * CADET channel connect handler. |
837 | * | ||
838 | * @see GNUNET_CADET_ConnectEventHandler() | ||
874 | */ | 839 | */ |
875 | static void * | 840 | static void * |
876 | cadet_notify_channel_new (void *cls, | 841 | cadet_notify_connect (void *cls, |
877 | struct GNUNET_CADET_Channel *channel, | 842 | struct GNUNET_CADET_Channel *channel, |
878 | const struct GNUNET_PeerIdentity *initiator, | 843 | const struct GNUNET_PeerIdentity *source) |
879 | const struct GNUNET_HashCode *port, | 844 | { |
880 | enum GNUNET_CADET_ChannelOption options) | 845 | struct Channel *chn = GNUNET_malloc (sizeof *chn); |
846 | chn->group = cls; | ||
847 | chn->channel = channel; | ||
848 | chn->direction = DIR_INCOMING; | ||
849 | chn->join_status = JOIN_NOT_ASKED; | ||
850 | |||
851 | GNUNET_CONTAINER_multihashmap_put (channels_in, &chn->group_pub_hash, chn, | ||
852 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
853 | return chn; | ||
854 | } | ||
855 | |||
856 | |||
857 | /** | ||
858 | * CADET window size change handler. | ||
859 | * | ||
860 | * @see GNUNET_CADET_WindowSizeEventHandler() | ||
861 | */ | ||
862 | static void | ||
863 | cadet_notify_window_change (void *cls, | ||
864 | const struct GNUNET_CADET_Channel *channel, | ||
865 | int window_size) | ||
881 | { | 866 | { |
882 | return NULL; | 867 | struct Channel *chn = cls; |
868 | |||
869 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
870 | "%p Window size changed to %d. Pending messages: %u\n", | ||
871 | chn, window_size, chn->msgs_pending); | ||
872 | |||
873 | chn->is_connected = GNUNET_YES; | ||
874 | chn->window_size = (int32_t) window_size; | ||
875 | |||
876 | for (int i = 0; i < window_size; i++) | ||
877 | { | ||
878 | if (0 < chn->msgs_pending) | ||
879 | { | ||
880 | client_send_ack (&chn->group_pub_hash); | ||
881 | chn->msgs_pending--; | ||
882 | } | ||
883 | else | ||
884 | { | ||
885 | break; | ||
886 | } | ||
887 | } | ||
883 | } | 888 | } |
884 | 889 | ||
885 | 890 | ||
886 | /** | 891 | /** |
887 | * CADET channel is being destroyed. | 892 | * CADET channel disconnect handler. |
893 | * | ||
894 | * @see GNUNET_CADET_DisconnectEventHandler() | ||
888 | */ | 895 | */ |
889 | static void | 896 | static void |
890 | cadet_notify_channel_end (void *cls, | 897 | cadet_notify_disconnect (void *cls, |
891 | const struct GNUNET_CADET_Channel *channel, | 898 | const struct GNUNET_CADET_Channel *channel) |
892 | void *ctx) | ||
893 | { | 899 | { |
894 | if (NULL == ctx) | 900 | if (NULL == cls) |
895 | return; | 901 | return; |
896 | 902 | ||
897 | struct Channel *chn = ctx; | 903 | struct Channel *chn = cls; |
898 | if (NULL != chn->group) | 904 | if (NULL != chn->group) |
899 | { | 905 | { |
900 | if (GNUNET_NO == chn->group->is_origin) | 906 | if (GNUNET_NO == chn->group->is_origin) |
@@ -905,12 +911,331 @@ cadet_notify_channel_end (void *cls, | |||
905 | } | 911 | } |
906 | } | 912 | } |
907 | 913 | ||
908 | while (GNUNET_YES == replay_req_remove_cadet (chn)); | 914 | int ret; |
915 | do | ||
916 | { | ||
917 | ret = replay_req_remove_cadet (chn); | ||
918 | } | ||
919 | while (GNUNET_YES == ret); | ||
909 | 920 | ||
910 | GNUNET_free (chn); | 921 | GNUNET_free (chn); |
911 | } | 922 | } |
912 | 923 | ||
913 | 924 | ||
925 | static int | ||
926 | check_cadet_join_request (void *cls, | ||
927 | const struct MulticastJoinRequestMessage *req) | ||
928 | { | ||
929 | struct Channel *chn = cls; | ||
930 | |||
931 | if (NULL == chn | ||
932 | || JOIN_NOT_ASKED != chn->join_status) | ||
933 | { | ||
934 | return GNUNET_SYSERR; | ||
935 | } | ||
936 | |||
937 | uint16_t size = ntohs (req->header.size); | ||
938 | if (size < sizeof (*req)) | ||
939 | { | ||
940 | GNUNET_break_op (0); | ||
941 | return GNUNET_SYSERR; | ||
942 | } | ||
943 | if (ntohl (req->purpose.size) != (size | ||
944 | - sizeof (req->header) | ||
945 | - sizeof (req->reserved) | ||
946 | - sizeof (req->signature))) | ||
947 | { | ||
948 | GNUNET_break_op (0); | ||
949 | return GNUNET_SYSERR; | ||
950 | } | ||
951 | if (GNUNET_OK != | ||
952 | GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_MULTICAST_REQUEST, | ||
953 | &req->purpose, &req->signature, | ||
954 | &req->member_pub_key)) | ||
955 | { | ||
956 | GNUNET_break_op (0); | ||
957 | return GNUNET_SYSERR; | ||
958 | } | ||
959 | |||
960 | return GNUNET_OK; | ||
961 | } | ||
962 | |||
963 | |||
964 | /** | ||
965 | * Incoming join request message from CADET. | ||
966 | */ | ||
967 | static void | ||
968 | handle_cadet_join_request (void *cls, | ||
969 | const struct MulticastJoinRequestMessage *req) | ||
970 | { | ||
971 | struct Channel *chn = cls; | ||
972 | GNUNET_CADET_receive_done (chn->channel); | ||
973 | |||
974 | struct GNUNET_HashCode group_pub_hash; | ||
975 | GNUNET_CRYPTO_hash (&req->group_pub_key, sizeof (req->group_pub_key), &group_pub_hash); | ||
976 | chn->group_pub_key = req->group_pub_key; | ||
977 | chn->group_pub_hash = group_pub_hash; | ||
978 | chn->member_pub_key = req->member_pub_key; | ||
979 | chn->peer = req->peer; | ||
980 | chn->join_status = JOIN_WAITING; | ||
981 | |||
982 | client_send_all (&group_pub_hash, &req->header); | ||
983 | } | ||
984 | |||
985 | |||
986 | static int | ||
987 | check_cadet_join_decision (void *cls, | ||
988 | const struct MulticastJoinDecisionMessageHeader *hdcsn) | ||
989 | { | ||
990 | uint16_t size = ntohs (hdcsn->header.size); | ||
991 | if (size < sizeof (struct MulticastJoinDecisionMessageHeader) + | ||
992 | sizeof (struct MulticastJoinDecisionMessage)) | ||
993 | { | ||
994 | GNUNET_break_op (0); | ||
995 | return GNUNET_SYSERR; | ||
996 | } | ||
997 | |||
998 | struct Channel *chn = cls; | ||
999 | if (NULL == chn) | ||
1000 | { | ||
1001 | GNUNET_break (0); | ||
1002 | return GNUNET_SYSERR; | ||
1003 | } | ||
1004 | if (NULL == chn->group || GNUNET_NO != chn->group->is_origin) | ||
1005 | { | ||
1006 | GNUNET_break (0); | ||
1007 | return GNUNET_SYSERR; | ||
1008 | } | ||
1009 | switch (chn->join_status) | ||
1010 | { | ||
1011 | case JOIN_REFUSED: | ||
1012 | return GNUNET_SYSERR; | ||
1013 | |||
1014 | case JOIN_ADMITTED: | ||
1015 | return GNUNET_OK; | ||
1016 | |||
1017 | case JOIN_NOT_ASKED: | ||
1018 | case JOIN_WAITING: | ||
1019 | break; | ||
1020 | } | ||
1021 | |||
1022 | return GNUNET_OK; | ||
1023 | } | ||
1024 | |||
1025 | |||
1026 | /** | ||
1027 | * Incoming join decision message from CADET. | ||
1028 | */ | ||
1029 | static void | ||
1030 | handle_cadet_join_decision (void *cls, | ||
1031 | const struct MulticastJoinDecisionMessageHeader *hdcsn) | ||
1032 | { | ||
1033 | const struct MulticastJoinDecisionMessage * | ||
1034 | dcsn = (const struct MulticastJoinDecisionMessage *) &hdcsn[1]; | ||
1035 | |||
1036 | struct Channel *chn = cls; | ||
1037 | GNUNET_CADET_receive_done (chn->channel); | ||
1038 | |||
1039 | // FIXME: do we need to copy chn->peer or compare it with hdcsn->peer? | ||
1040 | struct Member *mem = (struct Member *) chn->group; | ||
1041 | client_send_join_decision (mem, hdcsn); | ||
1042 | if (GNUNET_YES == ntohl (dcsn->is_admitted)) | ||
1043 | { | ||
1044 | chn->join_status = JOIN_ADMITTED; | ||
1045 | } | ||
1046 | else | ||
1047 | { | ||
1048 | chn->join_status = JOIN_REFUSED; | ||
1049 | cadet_channel_destroy (chn); | ||
1050 | } | ||
1051 | } | ||
1052 | |||
1053 | |||
1054 | static int | ||
1055 | check_cadet_message (void *cls, | ||
1056 | const struct GNUNET_MULTICAST_MessageHeader *msg) | ||
1057 | { | ||
1058 | uint16_t size = ntohs (msg->header.size); | ||
1059 | if (size < sizeof (*msg)) | ||
1060 | { | ||
1061 | GNUNET_break_op (0); | ||
1062 | return GNUNET_SYSERR; | ||
1063 | } | ||
1064 | |||
1065 | struct Channel *chn = cls; | ||
1066 | if (NULL == chn) | ||
1067 | { | ||
1068 | GNUNET_break (0); | ||
1069 | return GNUNET_SYSERR; | ||
1070 | } | ||
1071 | if (ntohl (msg->purpose.size) != (size | ||
1072 | - sizeof (msg->header) | ||
1073 | - sizeof (msg->hop_counter) | ||
1074 | - sizeof (msg->signature))) | ||
1075 | { | ||
1076 | GNUNET_break_op (0); | ||
1077 | return GNUNET_SYSERR; | ||
1078 | } | ||
1079 | if (GNUNET_OK != | ||
1080 | GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_MULTICAST_MESSAGE, | ||
1081 | &msg->purpose, &msg->signature, | ||
1082 | &chn->group_pub_key)) | ||
1083 | { | ||
1084 | GNUNET_break_op (0); | ||
1085 | return GNUNET_SYSERR; | ||
1086 | } | ||
1087 | |||
1088 | return GNUNET_OK; | ||
1089 | } | ||
1090 | |||
1091 | |||
1092 | /** | ||
1093 | * Incoming multicast message from CADET. | ||
1094 | */ | ||
1095 | static void | ||
1096 | handle_cadet_message (void *cls, | ||
1097 | const struct GNUNET_MULTICAST_MessageHeader *msg) | ||
1098 | { | ||
1099 | struct Channel *chn = cls; | ||
1100 | GNUNET_CADET_receive_done (chn->channel); | ||
1101 | client_send_all (&chn->group_pub_hash, &msg->header); | ||
1102 | } | ||
1103 | |||
1104 | |||
1105 | static int | ||
1106 | check_cadet_request (void *cls, | ||
1107 | const struct GNUNET_MULTICAST_RequestHeader *req) | ||
1108 | { | ||
1109 | uint16_t size = ntohs (req->header.size); | ||
1110 | if (size < sizeof (*req)) | ||
1111 | { | ||
1112 | GNUNET_break_op (0); | ||
1113 | return GNUNET_SYSERR; | ||
1114 | } | ||
1115 | |||
1116 | struct Channel *chn = cls; | ||
1117 | if (NULL == chn) | ||
1118 | { | ||
1119 | GNUNET_break (0); | ||
1120 | return GNUNET_SYSERR; | ||
1121 | } | ||
1122 | if (ntohl (req->purpose.size) != (size | ||
1123 | - sizeof (req->header) | ||
1124 | - sizeof (req->member_pub_key) | ||
1125 | - sizeof (req->signature))) | ||
1126 | { | ||
1127 | GNUNET_break_op (0); | ||
1128 | return GNUNET_SYSERR; | ||
1129 | } | ||
1130 | if (GNUNET_OK != | ||
1131 | GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_MULTICAST_REQUEST, | ||
1132 | &req->purpose, &req->signature, | ||
1133 | &req->member_pub_key)) | ||
1134 | { | ||
1135 | GNUNET_break_op (0); | ||
1136 | return GNUNET_SYSERR; | ||
1137 | } | ||
1138 | |||
1139 | return GNUNET_OK; | ||
1140 | } | ||
1141 | |||
1142 | |||
1143 | /** | ||
1144 | * Incoming multicast request message from CADET. | ||
1145 | */ | ||
1146 | static void | ||
1147 | handle_cadet_request (void *cls, | ||
1148 | const struct GNUNET_MULTICAST_RequestHeader *req) | ||
1149 | { | ||
1150 | struct Channel *chn = cls; | ||
1151 | GNUNET_CADET_receive_done (chn->channel); | ||
1152 | client_send_origin (&chn->group_pub_hash, &req->header); | ||
1153 | } | ||
1154 | |||
1155 | |||
1156 | static int | ||
1157 | check_cadet_replay_request (void *cls, | ||
1158 | const struct MulticastReplayRequestMessage *req) | ||
1159 | { | ||
1160 | uint16_t size = ntohs (req->header.size); | ||
1161 | if (size < sizeof (*req)) | ||
1162 | { | ||
1163 | GNUNET_break_op (0); | ||
1164 | return GNUNET_SYSERR; | ||
1165 | } | ||
1166 | |||
1167 | struct Channel *chn = cls; | ||
1168 | if (NULL == chn) | ||
1169 | { | ||
1170 | GNUNET_break_op (0); | ||
1171 | return GNUNET_SYSERR; | ||
1172 | } | ||
1173 | |||
1174 | return GNUNET_OK; | ||
1175 | } | ||
1176 | |||
1177 | |||
1178 | /** | ||
1179 | * Incoming multicast replay request from CADET. | ||
1180 | */ | ||
1181 | static void | ||
1182 | handle_cadet_replay_request (void *cls, | ||
1183 | const struct MulticastReplayRequestMessage *req) | ||
1184 | { | ||
1185 | struct Channel *chn = cls; | ||
1186 | GNUNET_CADET_receive_done (chn->channel); | ||
1187 | |||
1188 | struct MulticastReplayRequestMessage rep = *req; | ||
1189 | GNUNET_memcpy (&rep.member_pub_key, &chn->member_pub_key, sizeof (chn->member_pub_key)); | ||
1190 | |||
1191 | struct GNUNET_CONTAINER_MultiHashMap * | ||
1192 | grp_replay_req = GNUNET_CONTAINER_multihashmap_get (replay_req_cadet, | ||
1193 | &chn->group->pub_key_hash); | ||
1194 | if (NULL == grp_replay_req) | ||
1195 | { | ||
1196 | grp_replay_req = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); | ||
1197 | GNUNET_CONTAINER_multihashmap_put (replay_req_cadet, | ||
1198 | &chn->group->pub_key_hash, grp_replay_req, | ||
1199 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | ||
1200 | } | ||
1201 | struct GNUNET_HashCode key_hash; | ||
1202 | replay_key_hash (rep.fragment_id, rep.message_id, rep.fragment_offset, | ||
1203 | rep.flags, &key_hash); | ||
1204 | GNUNET_CONTAINER_multihashmap_put (grp_replay_req, &key_hash, chn, | ||
1205 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
1206 | |||
1207 | client_send_random (&chn->group_pub_hash, &rep.header); | ||
1208 | } | ||
1209 | |||
1210 | |||
1211 | static int | ||
1212 | check_cadet_replay_response (void *cls, | ||
1213 | const struct MulticastReplayResponseMessage *res) | ||
1214 | { | ||
1215 | struct Channel *chn = cls; | ||
1216 | if (NULL == chn) | ||
1217 | { | ||
1218 | GNUNET_break (0); | ||
1219 | return GNUNET_SYSERR; | ||
1220 | } | ||
1221 | return GNUNET_OK; | ||
1222 | } | ||
1223 | |||
1224 | |||
1225 | /** | ||
1226 | * Incoming multicast replay response from CADET. | ||
1227 | */ | ||
1228 | static void | ||
1229 | handle_cadet_replay_response (void *cls, | ||
1230 | const struct MulticastReplayResponseMessage *res) | ||
1231 | { | ||
1232 | struct Channel *chn = cls; | ||
1233 | GNUNET_CADET_receive_done (chn->channel); | ||
1234 | |||
1235 | /* @todo FIXME: got replay error response, send request to other members */ | ||
1236 | } | ||
1237 | |||
1238 | |||
914 | static void | 1239 | static void |
915 | group_set_cadet_port_hash (struct Group *grp) | 1240 | group_set_cadet_port_hash (struct Group *grp) |
916 | { | 1241 | { |
@@ -925,6 +1250,78 @@ group_set_cadet_port_hash (struct Group *grp) | |||
925 | } | 1250 | } |
926 | 1251 | ||
927 | 1252 | ||
1253 | |||
1254 | /** | ||
1255 | * Create new outgoing CADET channel. | ||
1256 | * | ||
1257 | * @param peer | ||
1258 | * Peer to connect to. | ||
1259 | * @param group_pub_key | ||
1260 | * Public key of group the channel belongs to. | ||
1261 | * @param group_pub_hash | ||
1262 | * Hash of @a group_pub_key. | ||
1263 | * | ||
1264 | * @return Channel. | ||
1265 | */ | ||
1266 | static struct Channel * | ||
1267 | cadet_channel_create (struct Group *grp, struct GNUNET_PeerIdentity *peer) | ||
1268 | { | ||
1269 | struct Channel *chn = GNUNET_malloc (sizeof (*chn)); | ||
1270 | chn->group = grp; | ||
1271 | chn->group_pub_key = grp->pub_key; | ||
1272 | chn->group_pub_hash = grp->pub_key_hash; | ||
1273 | chn->peer = *peer; | ||
1274 | chn->direction = DIR_OUTGOING; | ||
1275 | chn->is_connected = GNUNET_NO; | ||
1276 | chn->join_status = JOIN_WAITING; | ||
1277 | |||
1278 | struct GNUNET_MQ_MessageHandler cadet_handlers[] = { | ||
1279 | GNUNET_MQ_hd_var_size (cadet_message, | ||
1280 | GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE, | ||
1281 | struct GNUNET_MULTICAST_MessageHeader, | ||
1282 | chn), | ||
1283 | |||
1284 | GNUNET_MQ_hd_var_size (cadet_join_decision, | ||
1285 | GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION, | ||
1286 | struct MulticastJoinDecisionMessageHeader, | ||
1287 | chn), | ||
1288 | |||
1289 | GNUNET_MQ_hd_var_size (cadet_replay_request, | ||
1290 | GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST, | ||
1291 | struct MulticastReplayRequestMessage, | ||
1292 | chn), | ||
1293 | |||
1294 | GNUNET_MQ_hd_var_size (cadet_replay_response, | ||
1295 | GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_RESPONSE, | ||
1296 | struct MulticastReplayResponseMessage, | ||
1297 | chn), | ||
1298 | |||
1299 | GNUNET_MQ_handler_end () | ||
1300 | }; | ||
1301 | |||
1302 | chn->channel = GNUNET_CADET_channel_creatE (cadet, chn, &chn->peer, | ||
1303 | &grp->cadet_port_hash, | ||
1304 | GNUNET_CADET_OPTION_RELIABLE, | ||
1305 | cadet_notify_window_change, | ||
1306 | cadet_notify_disconnect, | ||
1307 | cadet_handlers); | ||
1308 | GNUNET_CONTAINER_multihashmap_put (channels_out, &chn->group_pub_hash, chn, | ||
1309 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
1310 | return chn; | ||
1311 | } | ||
1312 | |||
1313 | |||
1314 | /** | ||
1315 | * Destroy outgoing CADET channel. | ||
1316 | */ | ||
1317 | static void | ||
1318 | cadet_channel_destroy (struct Channel *chn) | ||
1319 | { | ||
1320 | GNUNET_CADET_channel_destroy (chn->channel); | ||
1321 | GNUNET_CONTAINER_multihashmap_remove_all (channels_out, &chn->group_pub_hash); | ||
1322 | GNUNET_free (chn); | ||
1323 | } | ||
1324 | |||
928 | /** | 1325 | /** |
929 | * Handle a connecting client starting an origin. | 1326 | * Handle a connecting client starting an origin. |
930 | */ | 1327 | */ |
@@ -961,8 +1358,44 @@ handle_client_origin_start (void *cls, | |||
961 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | 1358 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); |
962 | 1359 | ||
963 | group_set_cadet_port_hash (grp); | 1360 | group_set_cadet_port_hash (grp); |
964 | orig->cadet_port = GNUNET_CADET_open_port (cadet, &grp->cadet_port_hash, | 1361 | |
965 | cadet_notify_channel_new, NULL); | 1362 | struct GNUNET_MQ_MessageHandler cadet_handlers[] = { |
1363 | GNUNET_MQ_hd_var_size (cadet_message, | ||
1364 | GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE, | ||
1365 | struct GNUNET_MULTICAST_MessageHeader, | ||
1366 | grp), | ||
1367 | |||
1368 | GNUNET_MQ_hd_var_size (cadet_request, | ||
1369 | GNUNET_MESSAGE_TYPE_MULTICAST_REQUEST, | ||
1370 | struct GNUNET_MULTICAST_RequestHeader, | ||
1371 | grp), | ||
1372 | |||
1373 | GNUNET_MQ_hd_var_size (cadet_join_request, | ||
1374 | GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_REQUEST, | ||
1375 | struct MulticastJoinRequestMessage, | ||
1376 | grp), | ||
1377 | |||
1378 | GNUNET_MQ_hd_var_size (cadet_replay_request, | ||
1379 | GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST, | ||
1380 | struct MulticastReplayRequestMessage, | ||
1381 | grp), | ||
1382 | |||
1383 | GNUNET_MQ_hd_var_size (cadet_replay_response, | ||
1384 | GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_RESPONSE, | ||
1385 | struct MulticastReplayResponseMessage, | ||
1386 | grp), | ||
1387 | |||
1388 | GNUNET_MQ_handler_end () | ||
1389 | }; | ||
1390 | |||
1391 | |||
1392 | orig->cadet_port = GNUNET_CADET_open_porT (cadet, | ||
1393 | &grp->cadet_port_hash, | ||
1394 | cadet_notify_connect, | ||
1395 | NULL, | ||
1396 | cadet_notify_window_change, | ||
1397 | cadet_notify_disconnect, | ||
1398 | cadet_handlers); | ||
966 | } | 1399 | } |
967 | else | 1400 | else |
968 | { | 1401 | { |
@@ -1258,10 +1691,8 @@ handle_client_multicast_message (void *cls, | |||
1258 | } | 1691 | } |
1259 | 1692 | ||
1260 | client_send_all (&grp->pub_key_hash, &out->header); | 1693 | client_send_all (&grp->pub_key_hash, &out->header); |
1261 | if (0 == cadet_send_children (&grp->pub_key_hash, &out->header)) | 1694 | cadet_send_children (&grp->pub_key_hash, &out->header); |
1262 | { | 1695 | client_send_ack (&grp->pub_key_hash); |
1263 | client_send_ack (&grp->pub_key_hash); | ||
1264 | } | ||
1265 | GNUNET_free (out); | 1696 | GNUNET_free (out); |
1266 | 1697 | ||
1267 | GNUNET_SERVICE_client_continue (client); | 1698 | GNUNET_SERVICE_client_continue (client); |
@@ -1544,278 +1975,6 @@ handle_client_replay_response (void *cls, | |||
1544 | 1975 | ||
1545 | 1976 | ||
1546 | /** | 1977 | /** |
1547 | * Incoming join request message from CADET. | ||
1548 | */ | ||
1549 | int | ||
1550 | cadet_recv_join_request (void *cls, | ||
1551 | struct GNUNET_CADET_Channel *channel, | ||
1552 | void **ctx, | ||
1553 | const struct GNUNET_MessageHeader *m) | ||
1554 | { | ||
1555 | GNUNET_CADET_receive_done(channel); | ||
1556 | const struct MulticastJoinRequestMessage * | ||
1557 | req = (const struct MulticastJoinRequestMessage *) m; | ||
1558 | uint16_t size = ntohs (m->size); | ||
1559 | if (size < sizeof (*req)) | ||
1560 | { | ||
1561 | GNUNET_break_op (0); | ||
1562 | return GNUNET_SYSERR; | ||
1563 | } | ||
1564 | if (NULL != *ctx) | ||
1565 | { | ||
1566 | GNUNET_break_op (0); | ||
1567 | return GNUNET_SYSERR; | ||
1568 | } | ||
1569 | if (ntohl (req->purpose.size) != (size | ||
1570 | - sizeof (req->header) | ||
1571 | - sizeof (req->reserved) | ||
1572 | - sizeof (req->signature))) | ||
1573 | { | ||
1574 | GNUNET_break_op (0); | ||
1575 | return GNUNET_SYSERR; | ||
1576 | } | ||
1577 | if (GNUNET_OK != | ||
1578 | GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_MULTICAST_REQUEST, | ||
1579 | &req->purpose, &req->signature, | ||
1580 | &req->member_pub_key)) | ||
1581 | { | ||
1582 | GNUNET_break_op (0); | ||
1583 | return GNUNET_SYSERR; | ||
1584 | } | ||
1585 | |||
1586 | struct GNUNET_HashCode group_pub_hash; | ||
1587 | GNUNET_CRYPTO_hash (&req->group_pub_key, sizeof (req->group_pub_key), &group_pub_hash); | ||
1588 | |||
1589 | struct Channel *chn = GNUNET_malloc (sizeof *chn); | ||
1590 | chn->channel = channel; | ||
1591 | chn->group_pub_key = req->group_pub_key; | ||
1592 | chn->group_pub_hash = group_pub_hash; | ||
1593 | chn->member_pub_key = req->member_pub_key; | ||
1594 | chn->peer = req->peer; | ||
1595 | chn->join_status = JOIN_WAITING; | ||
1596 | GNUNET_CONTAINER_multihashmap_put (channels_in, &chn->group_pub_hash, chn, | ||
1597 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
1598 | *ctx = chn; | ||
1599 | |||
1600 | client_send_all (&group_pub_hash, m); | ||
1601 | return GNUNET_OK; | ||
1602 | } | ||
1603 | |||
1604 | |||
1605 | /** | ||
1606 | * Incoming join decision message from CADET. | ||
1607 | */ | ||
1608 | int | ||
1609 | cadet_recv_join_decision (void *cls, | ||
1610 | struct GNUNET_CADET_Channel *channel, | ||
1611 | void **ctx, | ||
1612 | const struct GNUNET_MessageHeader *m) | ||
1613 | { | ||
1614 | GNUNET_CADET_receive_done (channel); | ||
1615 | const struct MulticastJoinDecisionMessageHeader * | ||
1616 | hdcsn = (const struct MulticastJoinDecisionMessageHeader *) m; | ||
1617 | const struct MulticastJoinDecisionMessage * | ||
1618 | dcsn = (const struct MulticastJoinDecisionMessage *) &hdcsn[1]; | ||
1619 | uint16_t size = ntohs (m->size); | ||
1620 | if (size < sizeof (struct MulticastJoinDecisionMessageHeader) + | ||
1621 | sizeof (struct MulticastJoinDecisionMessage)) | ||
1622 | { | ||
1623 | GNUNET_break_op (0); | ||
1624 | return GNUNET_SYSERR; | ||
1625 | } | ||
1626 | struct Channel *chn = *ctx; | ||
1627 | if (NULL == chn) | ||
1628 | { | ||
1629 | GNUNET_break_op (0); | ||
1630 | return GNUNET_SYSERR; | ||
1631 | } | ||
1632 | if (NULL == chn->group || GNUNET_NO != chn->group->is_origin) | ||
1633 | { | ||
1634 | GNUNET_break_op (0); | ||
1635 | return GNUNET_SYSERR; | ||
1636 | } | ||
1637 | switch (chn->join_status) | ||
1638 | { | ||
1639 | case JOIN_REFUSED: | ||
1640 | return GNUNET_SYSERR; | ||
1641 | |||
1642 | case JOIN_ADMITTED: | ||
1643 | return GNUNET_OK; | ||
1644 | |||
1645 | case JOIN_NOT_ASKED: | ||
1646 | case JOIN_WAITING: | ||
1647 | break; | ||
1648 | } | ||
1649 | |||
1650 | // FIXME: do we need to copy chn->peer or compare it with hdcsn->peer? | ||
1651 | struct Member *mem = (struct Member *) chn->group; | ||
1652 | client_send_join_decision (mem, hdcsn); | ||
1653 | if (GNUNET_YES == ntohl (dcsn->is_admitted)) | ||
1654 | { | ||
1655 | chn->join_status = JOIN_ADMITTED; | ||
1656 | return GNUNET_OK; | ||
1657 | } | ||
1658 | else | ||
1659 | { | ||
1660 | chn->join_status = JOIN_REFUSED; | ||
1661 | return GNUNET_SYSERR; | ||
1662 | } | ||
1663 | } | ||
1664 | |||
1665 | /** | ||
1666 | * Incoming multicast message from CADET. | ||
1667 | */ | ||
1668 | int | ||
1669 | cadet_recv_message (void *cls, | ||
1670 | struct GNUNET_CADET_Channel *channel, | ||
1671 | void **ctx, | ||
1672 | const struct GNUNET_MessageHeader *m) | ||
1673 | { | ||
1674 | GNUNET_CADET_receive_done(channel); | ||
1675 | const struct GNUNET_MULTICAST_MessageHeader * | ||
1676 | msg = (const struct GNUNET_MULTICAST_MessageHeader *) m; | ||
1677 | uint16_t size = ntohs (m->size); | ||
1678 | if (size < sizeof (*msg)) | ||
1679 | { | ||
1680 | GNUNET_break_op (0); | ||
1681 | return GNUNET_SYSERR; | ||
1682 | } | ||
1683 | struct Channel *chn = *ctx; | ||
1684 | if (NULL == chn) | ||
1685 | { | ||
1686 | GNUNET_break_op (0); | ||
1687 | return GNUNET_SYSERR; | ||
1688 | } | ||
1689 | if (ntohl (msg->purpose.size) != (size | ||
1690 | - sizeof (msg->header) | ||
1691 | - sizeof (msg->hop_counter) | ||
1692 | - sizeof (msg->signature))) | ||
1693 | { | ||
1694 | GNUNET_break_op (0); | ||
1695 | return GNUNET_SYSERR; | ||
1696 | } | ||
1697 | if (GNUNET_OK != | ||
1698 | GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_MULTICAST_MESSAGE, | ||
1699 | &msg->purpose, &msg->signature, | ||
1700 | &chn->group_pub_key)) | ||
1701 | { | ||
1702 | GNUNET_break_op (0); | ||
1703 | return GNUNET_SYSERR; | ||
1704 | } | ||
1705 | |||
1706 | client_send_all (&chn->group_pub_hash, m); | ||
1707 | return GNUNET_OK; | ||
1708 | } | ||
1709 | |||
1710 | |||
1711 | /** | ||
1712 | * Incoming multicast request message from CADET. | ||
1713 | */ | ||
1714 | int | ||
1715 | cadet_recv_request (void *cls, | ||
1716 | struct GNUNET_CADET_Channel *channel, | ||
1717 | void **ctx, | ||
1718 | const struct GNUNET_MessageHeader *m) | ||
1719 | { | ||
1720 | GNUNET_CADET_receive_done(channel); | ||
1721 | const struct GNUNET_MULTICAST_RequestHeader * | ||
1722 | req = (const struct GNUNET_MULTICAST_RequestHeader *) m; | ||
1723 | uint16_t size = ntohs (m->size); | ||
1724 | if (size < sizeof (*req)) | ||
1725 | { | ||
1726 | GNUNET_break_op (0); | ||
1727 | return GNUNET_SYSERR; | ||
1728 | } | ||
1729 | struct Channel *chn = *ctx; | ||
1730 | if (NULL == chn) | ||
1731 | { | ||
1732 | GNUNET_break_op (0); | ||
1733 | return GNUNET_SYSERR; | ||
1734 | } | ||
1735 | if (ntohl (req->purpose.size) != (size | ||
1736 | - sizeof (req->header) | ||
1737 | - sizeof (req->member_pub_key) | ||
1738 | - sizeof (req->signature))) | ||
1739 | { | ||
1740 | GNUNET_break_op (0); | ||
1741 | return GNUNET_SYSERR; | ||
1742 | } | ||
1743 | if (GNUNET_OK != | ||
1744 | GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_MULTICAST_REQUEST, | ||
1745 | &req->purpose, &req->signature, | ||
1746 | &req->member_pub_key)) | ||
1747 | { | ||
1748 | GNUNET_break_op (0); | ||
1749 | return GNUNET_SYSERR; | ||
1750 | } | ||
1751 | |||
1752 | client_send_origin (&chn->group_pub_hash, m); | ||
1753 | return GNUNET_OK; | ||
1754 | } | ||
1755 | |||
1756 | |||
1757 | /** | ||
1758 | * Incoming multicast replay request from CADET. | ||
1759 | */ | ||
1760 | int | ||
1761 | cadet_recv_replay_request (void *cls, | ||
1762 | struct GNUNET_CADET_Channel *channel, | ||
1763 | void **ctx, | ||
1764 | const struct GNUNET_MessageHeader *m) | ||
1765 | { | ||
1766 | GNUNET_CADET_receive_done(channel); | ||
1767 | struct MulticastReplayRequestMessage rep; | ||
1768 | uint16_t size = ntohs (m->size); | ||
1769 | if (size < sizeof (rep)) | ||
1770 | { | ||
1771 | GNUNET_break_op (0); | ||
1772 | return GNUNET_SYSERR; | ||
1773 | } | ||
1774 | struct Channel *chn = *ctx; | ||
1775 | |||
1776 | GNUNET_memcpy (&rep, m, sizeof (rep)); | ||
1777 | GNUNET_memcpy (&rep.member_pub_key, &chn->member_pub_key, sizeof (chn->member_pub_key)); | ||
1778 | |||
1779 | struct GNUNET_CONTAINER_MultiHashMap * | ||
1780 | grp_replay_req = GNUNET_CONTAINER_multihashmap_get (replay_req_cadet, | ||
1781 | &chn->group->pub_key_hash); | ||
1782 | if (NULL == grp_replay_req) | ||
1783 | { | ||
1784 | grp_replay_req = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); | ||
1785 | GNUNET_CONTAINER_multihashmap_put (replay_req_cadet, | ||
1786 | &chn->group->pub_key_hash, grp_replay_req, | ||
1787 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | ||
1788 | } | ||
1789 | struct GNUNET_HashCode key_hash; | ||
1790 | replay_key_hash (rep.fragment_id, rep.message_id, rep.fragment_offset, | ||
1791 | rep.flags, &key_hash); | ||
1792 | GNUNET_CONTAINER_multihashmap_put (grp_replay_req, &key_hash, chn, | ||
1793 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
1794 | |||
1795 | client_send_random (&chn->group_pub_hash, &rep.header); | ||
1796 | return GNUNET_OK; | ||
1797 | } | ||
1798 | |||
1799 | |||
1800 | /** | ||
1801 | * Incoming multicast replay response from CADET. | ||
1802 | */ | ||
1803 | int | ||
1804 | cadet_recv_replay_response (void *cls, | ||
1805 | struct GNUNET_CADET_Channel *channel, | ||
1806 | void **ctx, | ||
1807 | const struct GNUNET_MessageHeader *m) | ||
1808 | { | ||
1809 | GNUNET_CADET_receive_done(channel); | ||
1810 | //struct Channel *chn = *ctx; | ||
1811 | |||
1812 | /* @todo FIXME: got replay error response, send request to other members */ | ||
1813 | |||
1814 | return GNUNET_OK; | ||
1815 | } | ||
1816 | |||
1817 | |||
1818 | /** | ||
1819 | * A new client connected. | 1978 | * A new client connected. |
1820 | * | 1979 | * |
1821 | * @param cls NULL | 1980 | * @param cls NULL |
@@ -1899,32 +2058,6 @@ client_notify_disconnect (void *cls, | |||
1899 | 2058 | ||
1900 | 2059 | ||
1901 | /** | 2060 | /** |
1902 | * Message handlers for CADET. | ||
1903 | */ | ||
1904 | static const struct GNUNET_CADET_MessageHandler cadet_handlers[] = { | ||
1905 | { cadet_recv_join_request, | ||
1906 | GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_REQUEST, 0 }, | ||
1907 | |||
1908 | { cadet_recv_join_decision, | ||
1909 | GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION, 0 }, | ||
1910 | |||
1911 | { cadet_recv_message, | ||
1912 | GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE, 0 }, | ||
1913 | |||
1914 | { cadet_recv_request, | ||
1915 | GNUNET_MESSAGE_TYPE_MULTICAST_REQUEST, 0 }, | ||
1916 | |||
1917 | { cadet_recv_replay_request, | ||
1918 | GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST, 0 }, | ||
1919 | |||
1920 | { cadet_recv_replay_response, | ||
1921 | GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_RESPONSE, 0 }, | ||
1922 | |||
1923 | { NULL, 0, 0 } | ||
1924 | }; | ||
1925 | |||
1926 | |||
1927 | /** | ||
1928 | * Service started. | 2061 | * Service started. |
1929 | * | 2062 | * |
1930 | * @param cls closure | 2063 | * @param cls closure |
@@ -1949,9 +2082,8 @@ run (void *cls, | |||
1949 | replay_req_cadet = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); | 2082 | replay_req_cadet = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); |
1950 | replay_req_client = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); | 2083 | replay_req_client = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); |
1951 | 2084 | ||
1952 | cadet = GNUNET_CADET_connect (cfg, NULL, | 2085 | cadet = GNUNET_CADET_connecT (cfg); |
1953 | cadet_notify_channel_end, | 2086 | |
1954 | cadet_handlers); | ||
1955 | GNUNET_assert (NULL != cadet); | 2087 | GNUNET_assert (NULL != cadet); |
1956 | 2088 | ||
1957 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, | 2089 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, |
diff --git a/src/multicast/test_multicast.c b/src/multicast/test_multicast.c index 1e3a4922b..7e9b51e23 100644 --- a/src/multicast/test_multicast.c +++ b/src/multicast/test_multicast.c | |||
@@ -484,6 +484,10 @@ member_recv_message (void *cls, | |||
484 | 484 | ||
485 | switch (test) | 485 | switch (test) |
486 | { | 486 | { |
487 | case TEST_ORIGIN_TO_ALL: | ||
488 | test = TEST_ORIGIN_TO_ALL_RECV; | ||
489 | break; | ||
490 | |||
487 | case TEST_ORIGIN_TO_ALL_RECV: | 491 | case TEST_ORIGIN_TO_ALL_RECV: |
488 | // Test 6 starts here | 492 | // Test 6 starts here |
489 | member_to_origin (); | 493 | member_to_origin (); |
@@ -523,6 +527,11 @@ origin_recv_message (void *cls, | |||
523 | test = TEST_ORIGIN_TO_ALL_RECV; | 527 | test = TEST_ORIGIN_TO_ALL_RECV; |
524 | break; | 528 | break; |
525 | 529 | ||
530 | case TEST_ORIGIN_TO_ALL_RECV: | ||
531 | // Test 6 starts here | ||
532 | member_to_origin (); | ||
533 | break; | ||
534 | |||
526 | default: | 535 | default: |
527 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 536 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
528 | "Invalid test #%d in origin_recv_message()\n", test); | 537 | "Invalid test #%d in origin_recv_message()\n", test); |
diff --git a/src/multicast/test_multicast.conf b/src/multicast/test_multicast.conf index 675776bbc..3081aeecc 100644 --- a/src/multicast/test_multicast.conf +++ b/src/multicast/test_multicast.conf | |||
@@ -1,4 +1,12 @@ | |||
1 | [testbed] | ||
2 | HOSTNAME = localhost | ||
3 | |||
1 | [arm] | 4 | [arm] |
2 | GLOBAL_POSTFIX=-L ERROR | 5 | GLOBAL_POSTFIX=-L ERROR |
3 | 6 | ||
4 | #PREFIX = sakura -t test-multicast -e cgdb --args | 7 | [multicast] |
8 | #PREFIX = xterm -T peer -e gdb --args | ||
9 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-multicast.sock | ||
10 | |||
11 | [vpn] | ||
12 | AUTOSTART = NO | ||
diff --git a/src/multicast/test_multicast_multipeer.c b/src/multicast/test_multicast_multipeer.c index aee3a44d5..0f973517d 100644 --- a/src/multicast/test_multicast_multipeer.c +++ b/src/multicast/test_multicast_multipeer.c | |||
@@ -35,7 +35,7 @@ | |||
35 | 35 | ||
36 | #define NUM_PEERS 2 | 36 | #define NUM_PEERS 2 |
37 | 37 | ||
38 | static struct GNUNET_TESTBED_Operation *op0; | 38 | static struct GNUNET_TESTBED_Operation *op0; |
39 | static struct GNUNET_TESTBED_Operation *op1; | 39 | static struct GNUNET_TESTBED_Operation *op1; |
40 | static struct GNUNET_TESTBED_Operation *pi_op0; | 40 | static struct GNUNET_TESTBED_Operation *pi_op0; |
41 | static struct GNUNET_TESTBED_Operation *pi_op1; | 41 | static struct GNUNET_TESTBED_Operation *pi_op1; |
@@ -114,15 +114,15 @@ timeout_task (void *cls) | |||
114 | } | 114 | } |
115 | 115 | ||
116 | 116 | ||
117 | static void | 117 | static void |
118 | member_join_request (void *cls, | 118 | member_join_request (void *cls, |
119 | const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key, | 119 | const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key, |
120 | const struct GNUNET_MessageHeader *join_msg, | 120 | const struct GNUNET_MessageHeader *join_msg, |
121 | struct GNUNET_MULTICAST_JoinHandle *jh) | 121 | struct GNUNET_MULTICAST_JoinHandle *jh) |
122 | { | 122 | { |
123 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 123 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
124 | "Member sent a join request.\n"); | 124 | "Member sent a join request.\n"); |
125 | 125 | ||
126 | } | 126 | } |
127 | 127 | ||
128 | int notify (void *cls, | 128 | int notify (void *cls, |
@@ -143,7 +143,7 @@ int notify (void *cls, | |||
143 | } | 143 | } |
144 | 144 | ||
145 | 145 | ||
146 | static void | 146 | static void |
147 | member_join_decision (void *cls, | 147 | member_join_decision (void *cls, |
148 | int is_admitted, | 148 | int is_admitted, |
149 | const struct GNUNET_PeerIdentity *peer, | 149 | const struct GNUNET_PeerIdentity *peer, |
@@ -165,32 +165,32 @@ member_join_decision (void *cls, | |||
165 | } | 165 | } |
166 | } | 166 | } |
167 | 167 | ||
168 | static void | 168 | static void |
169 | member_replay_frag () | 169 | member_replay_frag () |
170 | { | 170 | { |
171 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 171 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
172 | "member replay frag...\n"); | 172 | "member replay frag...\n"); |
173 | } | 173 | } |
174 | 174 | ||
175 | static void | 175 | static void |
176 | member_replay_msg () | 176 | member_replay_msg () |
177 | { | 177 | { |
178 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 178 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
179 | "member replay msg...\n"); | 179 | "member replay msg...\n"); |
180 | } | 180 | } |
181 | 181 | ||
182 | static void | 182 | static void |
183 | member_message () | 183 | member_message () |
184 | { | 184 | { |
185 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 185 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
186 | "member message...\n"); | 186 | "member message...\n"); |
187 | } | 187 | } |
188 | 188 | ||
189 | static void | 189 | static void |
190 | origin_join_request (void *cls, | 190 | origin_join_request (void *cls, |
191 | const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key, | 191 | const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key, |
192 | const struct GNUNET_MessageHeader *join_msg, | 192 | const struct GNUNET_MessageHeader *join_msg, |
193 | struct GNUNET_MULTICAST_JoinHandle *jh) | 193 | struct GNUNET_MULTICAST_JoinHandle *jh) |
194 | { | 194 | { |
195 | struct GNUNET_MessageHeader *join_resp; | 195 | struct GNUNET_MessageHeader *join_resp; |
196 | 196 | ||
@@ -217,7 +217,7 @@ origin_join_request (void *cls, | |||
217 | result = GNUNET_OK; | 217 | result = GNUNET_OK; |
218 | } | 218 | } |
219 | 219 | ||
220 | static void | 220 | static void |
221 | origin_replay_frag (void *cls, | 221 | origin_replay_frag (void *cls, |
222 | const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key, | 222 | const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key, |
223 | uint64_t fragment_id, | 223 | uint64_t fragment_id, |
@@ -227,7 +227,7 @@ origin_replay_frag (void *cls, | |||
227 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "origin replay fraq msg\n"); | 227 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "origin replay fraq msg\n"); |
228 | } | 228 | } |
229 | 229 | ||
230 | static void | 230 | static void |
231 | origin_replay_msg (void *cls, | 231 | origin_replay_msg (void *cls, |
232 | const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key, | 232 | const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key, |
233 | uint64_t message_id, | 233 | uint64_t message_id, |
@@ -235,7 +235,7 @@ origin_replay_msg (void *cls, | |||
235 | uint64_t flags, | 235 | uint64_t flags, |
236 | struct GNUNET_MULTICAST_ReplayHandle *rh) | 236 | struct GNUNET_MULTICAST_ReplayHandle *rh) |
237 | { | 237 | { |
238 | 238 | ||
239 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "origin replay msg\n"); | 239 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "origin replay msg\n"); |
240 | } | 240 | } |
241 | 241 | ||
@@ -267,11 +267,11 @@ service_connect1 (void *cls, | |||
267 | void *ca_result, | 267 | void *ca_result, |
268 | const char *emsg) | 268 | const char *emsg) |
269 | { | 269 | { |
270 | member = ca_result; | 270 | member = ca_result; |
271 | 271 | ||
272 | if (NULL != member) | 272 | if (NULL != member) |
273 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Connected to multicast service of member\n"); | 273 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Connected to multicast service of member\n"); |
274 | else | 274 | else |
275 | result = GNUNET_SYSERR; | 275 | result = GNUNET_SYSERR; |
276 | } | 276 | } |
277 | 277 | ||
@@ -291,7 +291,7 @@ multicast_ca1 (void *cls, | |||
291 | const struct GNUNET_CONFIGURATION_Handle *cfg) | 291 | const struct GNUNET_CONFIGURATION_Handle *cfg) |
292 | { | 292 | { |
293 | struct GNUNET_MessageHeader *join_msg; | 293 | struct GNUNET_MessageHeader *join_msg; |
294 | 294 | ||
295 | // Get members keys | 295 | // Get members keys |
296 | member_key = GNUNET_CRYPTO_ecdsa_key_create (); | 296 | member_key = GNUNET_CRYPTO_ecdsa_key_create (); |
297 | GNUNET_CRYPTO_ecdsa_key_get_public (member_key, &member_pub_key); | 297 | GNUNET_CRYPTO_ecdsa_key_get_public (member_key, &member_pub_key); |
@@ -302,10 +302,10 @@ multicast_ca1 (void *cls, | |||
302 | join_msg->size = htons (sizeof (join_msg) + data_size); | 302 | join_msg->size = htons (sizeof (join_msg) + data_size); |
303 | join_msg->type = htons (123); | 303 | join_msg->type = htons (123); |
304 | GNUNET_memcpy (&join_msg[1], data, data_size); | 304 | GNUNET_memcpy (&join_msg[1], data, data_size); |
305 | 305 | ||
306 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 306 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
307 | "Members tries to join multicast group\n"); | 307 | "Members tries to join multicast group\n"); |
308 | 308 | ||
309 | return GNUNET_MULTICAST_member_join (cfg, | 309 | return GNUNET_MULTICAST_member_join (cfg, |
310 | &group_pub_key, | 310 | &group_pub_key, |
311 | member_key, | 311 | member_key, |
@@ -328,13 +328,13 @@ peer_information_cb (void *cls, | |||
328 | const struct GNUNET_TESTBED_PeerInformation *pinfo, | 328 | const struct GNUNET_TESTBED_PeerInformation *pinfo, |
329 | const char *emsg) | 329 | const char *emsg) |
330 | { | 330 | { |
331 | int i = (int) cls; | 331 | int i = (int) (long) cls; |
332 | 332 | ||
333 | if (NULL == pinfo) { | 333 | if (NULL == pinfo) { |
334 | result = GNUNET_SYSERR; | 334 | result = GNUNET_SYSERR; |
335 | GNUNET_SCHEDULER_shutdown (); | 335 | GNUNET_SCHEDULER_shutdown (); |
336 | } | 336 | } |
337 | 337 | ||
338 | peer_id[i] = pinfo->result.id; | 338 | peer_id[i] = pinfo->result.id; |
339 | 339 | ||
340 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 340 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
@@ -403,13 +403,13 @@ service_connect0 (void *cls, | |||
403 | * Function run when service multicast has started and is providing us | 403 | * Function run when service multicast has started and is providing us |
404 | * with a configuration file. | 404 | * with a configuration file. |
405 | */ | 405 | */ |
406 | static void * | 406 | static void * |
407 | multicast_ca0 (void *cls, | 407 | multicast_ca0 (void *cls, |
408 | const struct GNUNET_CONFIGURATION_Handle *cfg) | 408 | const struct GNUNET_CONFIGURATION_Handle *cfg) |
409 | { | 409 | { |
410 | group_key = GNUNET_CRYPTO_eddsa_key_create (); | 410 | group_key = GNUNET_CRYPTO_eddsa_key_create (); |
411 | GNUNET_CRYPTO_eddsa_key_get_public (group_key, &group_pub_key); | 411 | GNUNET_CRYPTO_eddsa_key_get_public (group_key, &group_pub_key); |
412 | 412 | ||
413 | return GNUNET_MULTICAST_origin_start (cfg, | 413 | return GNUNET_MULTICAST_origin_start (cfg, |
414 | group_key, | 414 | group_key, |
415 | 0, | 415 | 0, |
@@ -460,7 +460,7 @@ testbed_master (void *cls, | |||
460 | topology (FIXME) */ | 460 | topology (FIXME) */ |
461 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 461 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
462 | "Connected to testbed_master()\n"); | 462 | "Connected to testbed_master()\n"); |
463 | 463 | ||
464 | peers = p; | 464 | peers = p; |
465 | 465 | ||
466 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 466 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
@@ -478,7 +478,7 @@ testbed_master (void *cls, | |||
478 | NULL); /* closure for the above two callbacks */ | 478 | NULL); /* closure for the above two callbacks */ |
479 | 479 | ||
480 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); /* Schedule a new task on shutdown */ | 480 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); /* Schedule a new task on shutdown */ |
481 | 481 | ||
482 | /* Schedule the shutdown task with a delay of a few Seconds */ | 482 | /* Schedule the shutdown task with a delay of a few Seconds */ |
483 | timeout_tid = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 40), | 483 | timeout_tid = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 40), |
484 | &timeout_task, NULL); | 484 | &timeout_task, NULL); |
diff --git a/src/namecache/.gitignore b/src/namecache/.gitignore index 6d2d8488a..2abc07dfb 100644 --- a/src/namecache/.gitignore +++ b/src/namecache/.gitignore | |||
@@ -4,3 +4,4 @@ test_namecache_api_cache_block | |||
4 | test_plugin_namecache_postgres | 4 | test_plugin_namecache_postgres |
5 | test_plugin_namecache_sqlite | 5 | test_plugin_namecache_sqlite |
6 | zonefiles | 6 | zonefiles |
7 | test_plugin_namecache_flat | ||
diff --git a/src/namestore/.gitignore b/src/namestore/.gitignore index 6943b888a..4995a9e36 100644 --- a/src/namestore/.gitignore +++ b/src/namestore/.gitignore | |||
@@ -18,3 +18,4 @@ test_namestore_api_zone_iteration_specific_zone.nc | |||
18 | test_namestore_api_zone_iteration_stop.nc | 18 | test_namestore_api_zone_iteration_stop.nc |
19 | test_plugin_namestore_postgres | 19 | test_plugin_namestore_postgres |
20 | test_plugin_namestore_sqlite | 20 | test_plugin_namestore_sqlite |
21 | test_plugin_namestore_flat | ||
diff --git a/src/nat/gnunet-helper-nat-client-windows.c b/src/nat/gnunet-helper-nat-client-windows.c index 89dad9e7b..622f8c961 100644 --- a/src/nat/gnunet-helper-nat-client-windows.c +++ b/src/nat/gnunet-helper-nat-client-windows.c | |||
@@ -42,6 +42,8 @@ | |||
42 | * - Nathan Evans | 42 | * - Nathan Evans |
43 | */ | 43 | */ |
44 | #define _GNU_SOURCE | 44 | #define _GNU_SOURCE |
45 | /* Instead of including gnunet_common.h */ | ||
46 | #define GNUNET_memcpy(dst,src,n) do { if (0 != n) { (void) memcpy (dst,src,n); } } while (0) | ||
45 | 47 | ||
46 | #define FD_SETSIZE 1024 | 48 | #define FD_SETSIZE 1024 |
47 | #include <winsock2.h> | 49 | #include <winsock2.h> |
diff --git a/src/nat/gnunet-helper-nat-server-windows.c b/src/nat/gnunet-helper-nat-server-windows.c index c8e1193e4..09bd02538 100644 --- a/src/nat/gnunet-helper-nat-server-windows.c +++ b/src/nat/gnunet-helper-nat-server-windows.c | |||
@@ -41,6 +41,8 @@ | |||
41 | * - Christian Grothoff | 41 | * - Christian Grothoff |
42 | */ | 42 | */ |
43 | #define _GNU_SOURCE | 43 | #define _GNU_SOURCE |
44 | /* Instead of including gnunet_common.h */ | ||
45 | #define GNUNET_memcpy(dst,src,n) do { if (0 != n) { (void) memcpy (dst,src,n); } } while (0) | ||
44 | 46 | ||
45 | #define FD_SETSIZE 1024 | 47 | #define FD_SETSIZE 1024 |
46 | #include <winsock2.h> | 48 | #include <winsock2.h> |
diff --git a/src/nat/gnunet-nat.c b/src/nat/gnunet-nat.c index f198adc0a..80bfb5726 100644 --- a/src/nat/gnunet-nat.c +++ b/src/nat/gnunet-nat.c | |||
@@ -283,6 +283,9 @@ run (void *cls, | |||
283 | return; | 283 | return; |
284 | } | 284 | } |
285 | } | 285 | } |
286 | |||
287 | remote_len = 0; | ||
288 | |||
286 | if (NULL != remote_addr) | 289 | if (NULL != remote_addr) |
287 | { | 290 | { |
288 | remote_len = GNUNET_STRINGS_parse_socket_addr (remote_addr, | 291 | remote_len = GNUNET_STRINGS_parse_socket_addr (remote_addr, |
diff --git a/src/peerinfo/.gitignore b/src/peerinfo/.gitignore index e2a79a211..152ca2916 100644 --- a/src/peerinfo/.gitignore +++ b/src/peerinfo/.gitignore | |||
@@ -3,3 +3,4 @@ test_peerinfo_api | |||
3 | test_peerinfo_api_friend_only | 3 | test_peerinfo_api_friend_only |
4 | test_peerinfo_api_notify_friend_only | 4 | test_peerinfo_api_notify_friend_only |
5 | test_peerinfo_shipped_hellos | 5 | test_peerinfo_shipped_hellos |
6 | perf_peerinfo_api | ||
diff --git a/src/peerinfo/perf_peerinfo_api.c b/src/peerinfo/perf_peerinfo_api.c index d446cbe3f..840c85c1b 100644 --- a/src/peerinfo/perf_peerinfo_api.c +++ b/src/peerinfo/perf_peerinfo_api.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2004, 2009, 2010 GNUnet e.V. | 3 | Copyright (C) 2004, 2009, 2010, 2017 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -22,7 +22,7 @@ | |||
22 | * @file peerinfo/perf_peerinfo_api.c | 22 | * @file peerinfo/perf_peerinfo_api.c |
23 | * @brief testcase for peerinfo_api.c, hopefully hammer the peerinfo service, | 23 | * @brief testcase for peerinfo_api.c, hopefully hammer the peerinfo service, |
24 | * this performance test adds up to 5000 peers with one address each and checks | 24 | * this performance test adds up to 5000 peers with one address each and checks |
25 | * over how many peers it can iterate before receiving a timeout after 30 seconds | 25 | * over how many peers it can iterate before receiving a timeout after 5 seconds |
26 | * @author Nathan Evans | 26 | * @author Nathan Evans |
27 | */ | 27 | */ |
28 | 28 | ||
@@ -34,8 +34,6 @@ | |||
34 | #include "peerinfo.h" | 34 | #include "peerinfo.h" |
35 | #include <gauger.h> | 35 | #include <gauger.h> |
36 | 36 | ||
37 | #define START_SERVICE 1 | ||
38 | |||
39 | #define NUM_REQUESTS 5000 | 37 | #define NUM_REQUESTS 5000 |
40 | 38 | ||
41 | static struct GNUNET_PEERINFO_IteratorContext *ic[NUM_REQUESTS]; | 39 | static struct GNUNET_PEERINFO_IteratorContext *ic[NUM_REQUESTS]; |
@@ -46,9 +44,36 @@ static unsigned int numpeers; | |||
46 | 44 | ||
47 | static struct GNUNET_PeerIdentity pid; | 45 | static struct GNUNET_PeerIdentity pid; |
48 | 46 | ||
47 | static struct GNUNET_SCHEDULER_Task *tt; | ||
48 | |||
49 | |||
50 | static void | ||
51 | do_shutdown (void *cls) | ||
52 | { | ||
53 | if (NULL != tt) | ||
54 | { | ||
55 | GNUNET_SCHEDULER_cancel (tt); | ||
56 | tt = NULL; | ||
57 | } | ||
58 | for (unsigned int i = 0; i < NUM_REQUESTS; i++) | ||
59 | if (NULL != ic[i]) | ||
60 | GNUNET_PEERINFO_iterate_cancel (ic[i]); | ||
61 | GNUNET_PEERINFO_disconnect (h); | ||
62 | h = NULL; | ||
63 | } | ||
64 | |||
65 | |||
66 | static void | ||
67 | do_timeout (void *cls) | ||
68 | { | ||
69 | tt = NULL; | ||
70 | GNUNET_SCHEDULER_shutdown (); | ||
71 | } | ||
72 | |||
49 | 73 | ||
50 | static int | 74 | static int |
51 | check_it (void *cls, const struct GNUNET_HELLO_Address *address, | 75 | check_it (void *cls, |
76 | const struct GNUNET_HELLO_Address *address, | ||
52 | struct GNUNET_TIME_Absolute expiration) | 77 | struct GNUNET_TIME_Absolute expiration) |
53 | { | 78 | { |
54 | return GNUNET_OK; | 79 | return GNUNET_OK; |
@@ -87,23 +112,34 @@ add_peer (size_t i) | |||
87 | struct GNUNET_HELLO_Message *h2; | 112 | struct GNUNET_HELLO_Message *h2; |
88 | 113 | ||
89 | memset (&pid, i, sizeof (pid)); | 114 | memset (&pid, i, sizeof (pid)); |
90 | h2 = GNUNET_HELLO_create (&pid.public_key, &address_generator, &i, GNUNET_NO); | 115 | h2 = GNUNET_HELLO_create (&pid.public_key, |
116 | &address_generator, | ||
117 | &i, | ||
118 | GNUNET_NO); | ||
91 | GNUNET_PEERINFO_add_peer (h, h2, NULL, NULL); | 119 | GNUNET_PEERINFO_add_peer (h, h2, NULL, NULL); |
92 | GNUNET_free (h2); | 120 | GNUNET_free (h2); |
93 | } | 121 | } |
94 | 122 | ||
95 | 123 | ||
96 | static void | 124 | static void |
97 | process (void *cls, const struct GNUNET_PeerIdentity *peer, | 125 | process (void *cls, |
98 | const struct GNUNET_HELLO_Message *hello, const char *err_msg) | 126 | const struct GNUNET_PeerIdentity *peer, |
127 | const struct GNUNET_HELLO_Message *hello, | ||
128 | const char *err_msg) | ||
99 | { | 129 | { |
100 | if (NULL != peer) | 130 | struct GNUNET_PEERINFO_IteratorContext **icp = cls; |
101 | { | ||
102 | numpeers++; | ||
103 | if (0 && (hello != NULL)) | ||
104 | GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &check_it, NULL); | ||
105 | 131 | ||
132 | if (NULL == peer) | ||
133 | { | ||
134 | *icp = NULL; | ||
135 | return; | ||
106 | } | 136 | } |
137 | numpeers++; | ||
138 | if (0 && (NULL != hello) ) | ||
139 | GNUNET_HELLO_iterate_addresses (hello, | ||
140 | GNUNET_NO, | ||
141 | &check_it, | ||
142 | NULL); | ||
107 | } | 143 | } |
108 | 144 | ||
109 | 145 | ||
@@ -112,32 +148,43 @@ run (void *cls, | |||
112 | const struct GNUNET_CONFIGURATION_Handle *cfg, | 148 | const struct GNUNET_CONFIGURATION_Handle *cfg, |
113 | struct GNUNET_TESTING_Peer *peer) | 149 | struct GNUNET_TESTING_Peer *peer) |
114 | { | 150 | { |
115 | size_t i; | ||
116 | |||
117 | h = GNUNET_PEERINFO_connect (cfg); | 151 | h = GNUNET_PEERINFO_connect (cfg); |
118 | GNUNET_assert (h != NULL); | 152 | GNUNET_assert (h != NULL); |
119 | for (i = 0; i < NUM_REQUESTS; i++) | 153 | for (unsigned int i = 0; i < NUM_REQUESTS; i++) |
120 | { | 154 | { |
121 | add_peer (i); | 155 | add_peer (i); |
122 | ic[i] = | 156 | ic[i] = GNUNET_PEERINFO_iterate (h, |
123 | GNUNET_PEERINFO_iterate (h, GNUNET_YES, NULL, | 157 | GNUNET_YES, |
124 | GNUNET_TIME_relative_multiply | 158 | NULL, |
125 | (GNUNET_TIME_UNIT_SECONDS, 30), &process, cls); | 159 | &process, |
160 | &ic[i]); | ||
126 | } | 161 | } |
162 | tt = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, | ||
163 | 5), | ||
164 | &do_timeout, | ||
165 | NULL); | ||
166 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, | ||
167 | NULL); | ||
127 | } | 168 | } |
128 | 169 | ||
129 | 170 | ||
130 | int | 171 | int |
131 | main (int argc, char *argv[]) | 172 | main (int argc, |
173 | char *argv[]) | ||
132 | { | 174 | { |
133 | if (0 != GNUNET_TESTING_service_run ("perf-gnunet-peerinfo", | 175 | if (0 != GNUNET_TESTING_service_run ("perf-gnunet-peerinfo", |
134 | "peerinfo", | 176 | "peerinfo", |
135 | "test_peerinfo_api_data.conf", | 177 | "test_peerinfo_api_data.conf", |
136 | &run, NULL)) | 178 | &run, NULL)) |
137 | return 1; | 179 | return 1; |
138 | FPRINTF (stderr, "Received %u/%u calls before timeout\n", numpeers, | 180 | FPRINTF (stderr, |
181 | "Received %u/%u calls before timeout\n", | ||
182 | numpeers, | ||
139 | NUM_REQUESTS * NUM_REQUESTS / 2); | 183 | NUM_REQUESTS * NUM_REQUESTS / 2); |
140 | GAUGER ("PEERINFO", "Peerinfo lookups", numpeers / 30, "peers/s"); | 184 | GAUGER ("PEERINFO", |
185 | "Peerinfo lookups", | ||
186 | numpeers / 5, | ||
187 | "peers/s"); | ||
141 | return 0; | 188 | return 0; |
142 | } | 189 | } |
143 | 190 | ||
diff --git a/src/peerstore/.gitignore b/src/peerstore/.gitignore index 33304d90b..7fc22bbdb 100644 --- a/src/peerstore/.gitignore +++ b/src/peerstore/.gitignore | |||
@@ -6,3 +6,4 @@ test_peerstore_api_store | |||
6 | test_peerstore_api_sync | 6 | test_peerstore_api_sync |
7 | test_peerstore_api_watch | 7 | test_peerstore_api_watch |
8 | test_plugin_peerstore_sqlite | 8 | test_plugin_peerstore_sqlite |
9 | test_plugin_peerstore_flat | ||
diff --git a/src/peerstore/gnunet-service-peerstore.c b/src/peerstore/gnunet-service-peerstore.c index 665e625fd..8200c2366 100644 --- a/src/peerstore/gnunet-service-peerstore.c +++ b/src/peerstore/gnunet-service-peerstore.c | |||
@@ -523,11 +523,11 @@ handle_store (void *cls, | |||
523 | 523 | ||
524 | record = PEERSTORE_parse_record_message (srm); | 524 | record = PEERSTORE_parse_record_message (srm); |
525 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 525 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
526 | "Received a store request. Sub system `%s' Peer `%s Key `%s' Options: %d.\n", | 526 | "Received a store request. Sub system `%s' Peer `%s Key `%s' Options: %u.\n", |
527 | record->sub_system, | 527 | record->sub_system, |
528 | GNUNET_i2s (record->peer), | 528 | GNUNET_i2s (record->peer), |
529 | record->key, | 529 | record->key, |
530 | ntohl (srm->options)); | 530 | (uint32_t) ntohl (srm->options)); |
531 | record->client = client; | 531 | record->client = client; |
532 | if (GNUNET_OK != | 532 | if (GNUNET_OK != |
533 | db->store_record (db->cls, | 533 | db->store_record (db->cls, |
diff --git a/src/pq/pq_result_helper.c b/src/pq/pq_result_helper.c index 180c5fc18..c5c8e56b9 100644 --- a/src/pq/pq_result_helper.c +++ b/src/pq/pq_result_helper.c | |||
@@ -77,9 +77,7 @@ extract_varsize_blob (void *cls, | |||
77 | fname); | 77 | fname); |
78 | if (fnum < 0) | 78 | if (fnum < 0) |
79 | { | 79 | { |
80 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 80 | GNUNET_break (0); |
81 | "Field `%s' does not exist in result\n", | ||
82 | fname); | ||
83 | return GNUNET_SYSERR; | 81 | return GNUNET_SYSERR; |
84 | } | 82 | } |
85 | if (PQgetisnull (result, | 83 | if (PQgetisnull (result, |
@@ -156,9 +154,7 @@ extract_fixed_blob (void *cls, | |||
156 | fname); | 154 | fname); |
157 | if (fnum < 0) | 155 | if (fnum < 0) |
158 | { | 156 | { |
159 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 157 | GNUNET_break (0); |
160 | "Field `%s' does not exist in result\n", | ||
161 | fname); | ||
162 | return GNUNET_SYSERR; | 158 | return GNUNET_SYSERR; |
163 | } | 159 | } |
164 | if (PQgetisnull (result, | 160 | if (PQgetisnull (result, |
@@ -173,11 +169,7 @@ extract_fixed_blob (void *cls, | |||
173 | fnum); | 169 | fnum); |
174 | if (*dst_size != len) | 170 | if (*dst_size != len) |
175 | { | 171 | { |
176 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 172 | GNUNET_break (0); |
177 | "Field `%s' has wrong size (got %u, expected %u)\n", | ||
178 | fname, | ||
179 | (unsigned int) len, | ||
180 | (unsigned int) *dst_size); | ||
181 | return GNUNET_SYSERR; | 173 | return GNUNET_SYSERR; |
182 | } | 174 | } |
183 | res = PQgetvalue (result, | 175 | res = PQgetvalue (result, |
@@ -243,9 +235,7 @@ extract_rsa_public_key (void *cls, | |||
243 | fname); | 235 | fname); |
244 | if (fnum < 0) | 236 | if (fnum < 0) |
245 | { | 237 | { |
246 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 238 | GNUNET_break (0); |
247 | "Field `%s' does not exist in result\n", | ||
248 | fname); | ||
249 | return GNUNET_SYSERR; | 239 | return GNUNET_SYSERR; |
250 | } | 240 | } |
251 | if (PQgetisnull (result, | 241 | if (PQgetisnull (result, |
@@ -265,9 +255,7 @@ extract_rsa_public_key (void *cls, | |||
265 | len); | 255 | len); |
266 | if (NULL == *pk) | 256 | if (NULL == *pk) |
267 | { | 257 | { |
268 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 258 | GNUNET_break (0); |
269 | "Field `%s' contains bogus value (fails to decode)\n", | ||
270 | fname); | ||
271 | return GNUNET_SYSERR; | 259 | return GNUNET_SYSERR; |
272 | } | 260 | } |
273 | return GNUNET_OK; | 261 | return GNUNET_OK; |
@@ -346,9 +334,7 @@ extract_rsa_signature (void *cls, | |||
346 | fname); | 334 | fname); |
347 | if (fnum < 0) | 335 | if (fnum < 0) |
348 | { | 336 | { |
349 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 337 | GNUNET_break (0); |
350 | "Field `%s' does not exist in result\n", | ||
351 | fname); | ||
352 | return GNUNET_SYSERR; | 338 | return GNUNET_SYSERR; |
353 | } | 339 | } |
354 | if (PQgetisnull (result, | 340 | if (PQgetisnull (result, |
@@ -368,9 +354,7 @@ extract_rsa_signature (void *cls, | |||
368 | len); | 354 | len); |
369 | if (NULL == *sig) | 355 | if (NULL == *sig) |
370 | { | 356 | { |
371 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 357 | GNUNET_break (0); |
372 | "Field `%s' contains bogus value (fails to decode)\n", | ||
373 | fname); | ||
374 | return GNUNET_SYSERR; | 358 | return GNUNET_SYSERR; |
375 | } | 359 | } |
376 | return GNUNET_OK; | 360 | return GNUNET_OK; |
@@ -449,9 +433,7 @@ extract_string (void *cls, | |||
449 | fname); | 433 | fname); |
450 | if (fnum < 0) | 434 | if (fnum < 0) |
451 | { | 435 | { |
452 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 436 | GNUNET_break (0); |
453 | "Field `%s' does not exist in result\n", | ||
454 | fname); | ||
455 | return GNUNET_SYSERR; | 437 | return GNUNET_SYSERR; |
456 | } | 438 | } |
457 | if (PQgetisnull (result, | 439 | if (PQgetisnull (result, |
@@ -471,9 +453,7 @@ extract_string (void *cls, | |||
471 | len); | 453 | len); |
472 | if (NULL == *str) | 454 | if (NULL == *str) |
473 | { | 455 | { |
474 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 456 | GNUNET_break (0); |
475 | "Field `%s' contains bogus value (fails to decode)\n", | ||
476 | fname); | ||
477 | return GNUNET_SYSERR; | 457 | return GNUNET_SYSERR; |
478 | } | 458 | } |
479 | return GNUNET_OK; | 459 | return GNUNET_OK; |
@@ -583,9 +563,7 @@ extract_uint16 (void *cls, | |||
583 | fname); | 563 | fname); |
584 | if (fnum < 0) | 564 | if (fnum < 0) |
585 | { | 565 | { |
586 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 566 | GNUNET_break (0); |
587 | "Field `%s' does not exist in result\n", | ||
588 | fname); | ||
589 | return GNUNET_SYSERR; | 567 | return GNUNET_SYSERR; |
590 | } | 568 | } |
591 | if (PQgetisnull (result, | 569 | if (PQgetisnull (result, |
@@ -655,9 +633,7 @@ extract_uint32 (void *cls, | |||
655 | fname); | 633 | fname); |
656 | if (fnum < 0) | 634 | if (fnum < 0) |
657 | { | 635 | { |
658 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 636 | GNUNET_break (0); |
659 | "Field `%s' does not exist in result\n", | ||
660 | fname); | ||
661 | return GNUNET_SYSERR; | 637 | return GNUNET_SYSERR; |
662 | } | 638 | } |
663 | if (PQgetisnull (result, | 639 | if (PQgetisnull (result, |
@@ -727,9 +703,7 @@ extract_uint64 (void *cls, | |||
727 | fname); | 703 | fname); |
728 | if (fnum < 0) | 704 | if (fnum < 0) |
729 | { | 705 | { |
730 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 706 | GNUNET_break (0); |
731 | "Field `%s' does not exist in result\n", | ||
732 | fname); | ||
733 | return GNUNET_SYSERR; | 707 | return GNUNET_SYSERR; |
734 | } | 708 | } |
735 | if (PQgetisnull (result, | 709 | if (PQgetisnull (result, |
diff --git a/src/pq/test_pq.c b/src/pq/test_pq.c index 49705103f..b54318110 100644 --- a/src/pq/test_pq.c +++ b/src/pq/test_pq.c | |||
@@ -218,8 +218,8 @@ run_queries (PGconn *conn) | |||
218 | 218 | ||
219 | 219 | ||
220 | int | 220 | int |
221 | main(int argc, | 221 | main (int argc, |
222 | const char *const argv[]) | 222 | const char *const argv[]) |
223 | { | 223 | { |
224 | PGconn *conn; | 224 | PGconn *conn; |
225 | PGresult *result; | 225 | PGresult *result; |
@@ -236,7 +236,7 @@ main(int argc, | |||
236 | PQerrorMessage (conn)); | 236 | PQerrorMessage (conn)); |
237 | GNUNET_break (0); | 237 | GNUNET_break (0); |
238 | PQfinish (conn); | 238 | PQfinish (conn); |
239 | return 0; /* We ignore this type of error... */ | 239 | return 77; /* signal test was skipped */ |
240 | } | 240 | } |
241 | 241 | ||
242 | result = PQexec (conn, | 242 | result = PQexec (conn, |
diff --git a/src/pt/.gitignore b/src/pt/.gitignore index 22f803ed6..ea678ffe5 100644 --- a/src/pt/.gitignore +++ b/src/pt/.gitignore | |||
@@ -1 +1,6 @@ | |||
1 | gnunet-daemon-pt | 1 | gnunet-daemon-pt |
2 | test_gns_vpn | ||
3 | test_gnunet_vpn-4_over | ||
4 | test_gnunet_vpn-4_to_6 | ||
5 | test_gnunet_vpn-6_over | ||
6 | test_gnunet_vpn-6_to_4 | ||
diff --git a/src/pt/Makefile.am b/src/pt/Makefile.am index e36630ae4..7ea8257d5 100644 --- a/src/pt/Makefile.am +++ b/src/pt/Makefile.am | |||
@@ -25,7 +25,7 @@ gnunet_daemon_pt_SOURCES = \ | |||
25 | gnunet-daemon-pt.c | 25 | gnunet-daemon-pt.c |
26 | gnunet_daemon_pt_LDADD = \ | 26 | gnunet_daemon_pt_LDADD = \ |
27 | $(top_builddir)/src/vpn/libgnunetvpn.la \ | 27 | $(top_builddir)/src/vpn/libgnunetvpn.la \ |
28 | $(top_builddir)/src/cadet/libgnunetcadet.la \ | 28 | $(top_builddir)/src/cadet/libgnunetcadetnew.la \ |
29 | $(top_builddir)/src/dht/libgnunetdht.la \ | 29 | $(top_builddir)/src/dht/libgnunetdht.la \ |
30 | $(top_builddir)/src/dns/libgnunetdns.la \ | 30 | $(top_builddir)/src/dns/libgnunetdns.la \ |
31 | $(top_builddir)/src/dns/libgnunetdnsparser.la \ | 31 | $(top_builddir)/src/dns/libgnunetdnsparser.la \ |
diff --git a/src/pt/gnunet-daemon-pt.c b/src/pt/gnunet-daemon-pt.c index 06ef88832..54556cc52 100644 --- a/src/pt/gnunet-daemon-pt.c +++ b/src/pt/gnunet-daemon-pt.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2010, 2012 Christian Grothoff | 3 | Copyright (C) 2010, 2012, 2017 Christian Grothoff |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -17,7 +17,6 @@ | |||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
18 | Boston, MA 02110-1301, USA. | 18 | Boston, MA 02110-1301, USA. |
19 | */ | 19 | */ |
20 | |||
21 | /** | 20 | /** |
22 | * @file pt/gnunet-daemon-pt.c | 21 | * @file pt/gnunet-daemon-pt.c |
23 | * @brief tool to manipulate DNS and VPN services to perform protocol translation (IPvX over GNUnet) | 22 | * @brief tool to manipulate DNS and VPN services to perform protocol translation (IPvX over GNUnet) |
@@ -161,21 +160,6 @@ struct CadetExit | |||
161 | struct RequestContext *receive_queue_tail; | 160 | struct RequestContext *receive_queue_tail; |
162 | 161 | ||
163 | /** | 162 | /** |
164 | * Head of DLL of requests to be transmitted to a cadet_channel. | ||
165 | */ | ||
166 | struct RequestContext *transmit_queue_head; | ||
167 | |||
168 | /** | ||
169 | * Tail of DLL of requests to be transmitted to a cadet_channel. | ||
170 | */ | ||
171 | struct RequestContext *transmit_queue_tail; | ||
172 | |||
173 | /** | ||
174 | * Active transmission request for this channel (or NULL). | ||
175 | */ | ||
176 | struct GNUNET_CADET_TransmitHandle *cadet_th; | ||
177 | |||
178 | /** | ||
179 | * Identity of the peer that is providing the exit for us. | 163 | * Identity of the peer that is providing the exit for us. |
180 | */ | 164 | */ |
181 | struct GNUNET_PeerIdentity peer; | 165 | struct GNUNET_PeerIdentity peer; |
@@ -190,6 +174,11 @@ struct CadetExit | |||
190 | */ | 174 | */ |
191 | unsigned int num_answered; | 175 | unsigned int num_answered; |
192 | 176 | ||
177 | /** | ||
178 | * Size of the window, 0 if we are busy. | ||
179 | */ | ||
180 | /* unsigned */ int idle; | ||
181 | |||
193 | }; | 182 | }; |
194 | 183 | ||
195 | 184 | ||
@@ -220,10 +209,9 @@ struct RequestContext | |||
220 | struct GNUNET_DNS_RequestHandle *rh; | 209 | struct GNUNET_DNS_RequestHandle *rh; |
221 | 210 | ||
222 | /** | 211 | /** |
223 | * Message we're sending out via CADET, allocated at the | 212 | * Envelope with the request we are transmitting. |
224 | * end of this struct. | ||
225 | */ | 213 | */ |
226 | const struct GNUNET_MessageHeader *cadet_message; | 214 | struct GNUNET_MQ_Envelope *env; |
227 | 215 | ||
228 | /** | 216 | /** |
229 | * Task used to abort this operation with timeout. | 217 | * Task used to abort this operation with timeout. |
@@ -240,12 +228,6 @@ struct RequestContext | |||
240 | */ | 228 | */ |
241 | uint16_t dns_id; | 229 | uint16_t dns_id; |
242 | 230 | ||
243 | /** | ||
244 | * #GNUNET_NO if this request is still in the transmit_queue, | ||
245 | * #GNUNET_YES if we are in the receive_queue. | ||
246 | */ | ||
247 | int16_t was_transmitted; | ||
248 | |||
249 | }; | 231 | }; |
250 | 232 | ||
251 | 233 | ||
@@ -328,59 +310,7 @@ static unsigned int dns_exit_available; | |||
328 | * We are short on cadet exits, try to open another one. | 310 | * We are short on cadet exits, try to open another one. |
329 | */ | 311 | */ |
330 | static void | 312 | static void |
331 | try_open_exit () | 313 | try_open_exit (void); |
332 | { | ||
333 | struct CadetExit *pos; | ||
334 | uint32_t candidate_count; | ||
335 | uint32_t candidate_selected; | ||
336 | struct GNUNET_HashCode port; | ||
337 | |||
338 | GNUNET_CRYPTO_hash (GNUNET_APPLICATION_PORT_INTERNET_RESOLVER, | ||
339 | strlen (GNUNET_APPLICATION_PORT_INTERNET_RESOLVER), | ||
340 | &port); | ||
341 | candidate_count = 0; | ||
342 | for (pos = exit_head; NULL != pos; pos = pos->next) | ||
343 | if (NULL == pos->cadet_channel) | ||
344 | candidate_count++; | ||
345 | if (0 == candidate_count) | ||
346 | { | ||
347 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
348 | "No DNS exits available yet.\n"); | ||
349 | return; | ||
350 | } | ||
351 | candidate_selected = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, | ||
352 | candidate_count); | ||
353 | candidate_count = 0; | ||
354 | for (pos = exit_head; NULL != pos; pos = pos->next) | ||
355 | if (NULL == pos->cadet_channel) | ||
356 | { | ||
357 | candidate_count++; | ||
358 | if (candidate_selected < candidate_count) | ||
359 | { | ||
360 | /* move to the head of the DLL */ | ||
361 | pos->cadet_channel | ||
362 | = GNUNET_CADET_channel_create (cadet_handle, | ||
363 | pos, | ||
364 | &pos->peer, | ||
365 | &port, | ||
366 | GNUNET_CADET_OPTION_DEFAULT); | ||
367 | if (NULL == pos->cadet_channel) | ||
368 | { | ||
369 | GNUNET_break (0); | ||
370 | continue; | ||
371 | } | ||
372 | GNUNET_CONTAINER_DLL_remove (exit_head, | ||
373 | exit_tail, | ||
374 | pos); | ||
375 | GNUNET_CONTAINER_DLL_insert (exit_head, | ||
376 | exit_tail, | ||
377 | pos); | ||
378 | dns_exit_available++; | ||
379 | return; | ||
380 | } | ||
381 | } | ||
382 | GNUNET_assert (NULL == exit_head); | ||
383 | } | ||
384 | 314 | ||
385 | 315 | ||
386 | /** | 316 | /** |
@@ -443,7 +373,7 @@ choose_exit () | |||
443 | channel_weight = get_channel_weight (pos); | 373 | channel_weight = get_channel_weight (pos); |
444 | total_transmitted += channel_weight; | 374 | total_transmitted += channel_weight; |
445 | /* double weight for idle channels */ | 375 | /* double weight for idle channels */ |
446 | if (NULL == pos->cadet_th) | 376 | if (0 != pos->idle) |
447 | total_transmitted += channel_weight; | 377 | total_transmitted += channel_weight; |
448 | } | 378 | } |
449 | if (0 == total_transmitted) | 379 | if (0 == total_transmitted) |
@@ -461,7 +391,7 @@ choose_exit () | |||
461 | channel_weight = get_channel_weight (pos); | 391 | channel_weight = get_channel_weight (pos); |
462 | total_transmitted += channel_weight; | 392 | total_transmitted += channel_weight; |
463 | /* double weight for idle channels */ | 393 | /* double weight for idle channels */ |
464 | if (NULL == pos->cadet_th) | 394 | if (0 != pos->idle) |
465 | total_transmitted += channel_weight; | 395 | total_transmitted += channel_weight; |
466 | if (total_transmitted > selected_offset) | 396 | if (total_transmitted > selected_offset) |
467 | return pos; | 397 | return pos; |
@@ -768,62 +698,6 @@ dns_post_request_handler (void *cls, | |||
768 | 698 | ||
769 | 699 | ||
770 | /** | 700 | /** |
771 | * Transmit a DNS request via CADET and move the request | ||
772 | * handle to the receive queue. | ||
773 | * | ||
774 | * @param cls the `struct CadetExit` | ||
775 | * @param size number of bytes available in buf | ||
776 | * @param buf where to copy the message | ||
777 | * @return number of bytes written to buf | ||
778 | */ | ||
779 | static size_t | ||
780 | transmit_dns_request_to_cadet (void *cls, | ||
781 | size_t size, | ||
782 | void *buf) | ||
783 | { | ||
784 | struct CadetExit *exit = cls; | ||
785 | struct RequestContext *rc; | ||
786 | size_t mlen; | ||
787 | |||
788 | exit->cadet_th = NULL; | ||
789 | if (NULL == (rc = exit->transmit_queue_head)) | ||
790 | return 0; | ||
791 | mlen = rc->mlen; | ||
792 | if (mlen > size) | ||
793 | { | ||
794 | exit->cadet_th | ||
795 | = GNUNET_CADET_notify_transmit_ready (exit->cadet_channel, | ||
796 | GNUNET_NO, | ||
797 | TIMEOUT, | ||
798 | mlen, | ||
799 | &transmit_dns_request_to_cadet, | ||
800 | exit); | ||
801 | return 0; | ||
802 | } | ||
803 | GNUNET_assert (GNUNET_NO == rc->was_transmitted); | ||
804 | GNUNET_memcpy (buf, | ||
805 | rc->cadet_message, | ||
806 | mlen); | ||
807 | GNUNET_CONTAINER_DLL_remove (exit->transmit_queue_head, | ||
808 | exit->transmit_queue_tail, | ||
809 | rc); | ||
810 | rc->was_transmitted = GNUNET_YES; | ||
811 | GNUNET_CONTAINER_DLL_insert (exit->receive_queue_head, | ||
812 | exit->receive_queue_tail, | ||
813 | rc); | ||
814 | rc = exit->transmit_queue_head; | ||
815 | if (NULL != rc) | ||
816 | exit->cadet_th = GNUNET_CADET_notify_transmit_ready (exit->cadet_channel, | ||
817 | GNUNET_NO, | ||
818 | TIMEOUT, | ||
819 | rc->mlen, | ||
820 | &transmit_dns_request_to_cadet, | ||
821 | exit); | ||
822 | return mlen; | ||
823 | } | ||
824 | |||
825 | |||
826 | /** | ||
827 | * Task run if the time to answer a DNS request via CADET is over. | 701 | * Task run if the time to answer a DNS request via CADET is over. |
828 | * | 702 | * |
829 | * @param cls the `struct RequestContext` to abort | 703 | * @param cls the `struct RequestContext` to abort |
@@ -834,19 +708,6 @@ timeout_request (void *cls) | |||
834 | struct RequestContext *rc = cls; | 708 | struct RequestContext *rc = cls; |
835 | struct CadetExit *exit = rc->exit; | 709 | struct CadetExit *exit = rc->exit; |
836 | 710 | ||
837 | if (rc->was_transmitted) | ||
838 | { | ||
839 | exit->num_transmitted++; | ||
840 | GNUNET_CONTAINER_DLL_remove (exit->receive_queue_head, | ||
841 | exit->receive_queue_tail, | ||
842 | rc); | ||
843 | } | ||
844 | else | ||
845 | { | ||
846 | GNUNET_CONTAINER_DLL_remove (exit->transmit_queue_head, | ||
847 | exit->transmit_queue_tail, | ||
848 | rc); | ||
849 | } | ||
850 | GNUNET_STATISTICS_update (stats, | 711 | GNUNET_STATISTICS_update (stats, |
851 | gettext_noop ("# DNS requests dropped (timeout)"), | 712 | gettext_noop ("# DNS requests dropped (timeout)"), |
852 | 1, | 713 | 1, |
@@ -854,12 +715,10 @@ timeout_request (void *cls) | |||
854 | GNUNET_DNS_request_drop (rc->rh); | 715 | GNUNET_DNS_request_drop (rc->rh); |
855 | GNUNET_free (rc); | 716 | GNUNET_free (rc); |
856 | if ( (0 == get_channel_weight (exit)) && | 717 | if ( (0 == get_channel_weight (exit)) && |
857 | (NULL == exit->receive_queue_head) && | 718 | (NULL == exit->receive_queue_head) ) |
858 | (NULL == exit->transmit_queue_head) ) | ||
859 | { | 719 | { |
860 | /* this straw broke the camel's back: this channel now has | 720 | /* this straw broke the camel's back: this channel now has |
861 | such a low score that it will not be used; close it! */ | 721 | such a low score that it will not be used; close it! */ |
862 | GNUNET_assert (NULL == exit->cadet_th); | ||
863 | GNUNET_CADET_channel_destroy (exit->cadet_channel); | 722 | GNUNET_CADET_channel_destroy (exit->cadet_channel); |
864 | exit->cadet_channel = NULL; | 723 | exit->cadet_channel = NULL; |
865 | GNUNET_CONTAINER_DLL_remove (exit_head, | 724 | GNUNET_CONTAINER_DLL_remove (exit_head, |
@@ -870,7 +729,7 @@ timeout_request (void *cls) | |||
870 | exit); | 729 | exit); |
871 | /* go back to semi-innocent: mark as not great, but | 730 | /* go back to semi-innocent: mark as not great, but |
872 | avoid a prohibitively negative score (see | 731 | avoid a prohibitively negative score (see |
873 | #get_channel_weight, which checks for a certain | 732 | #get_channel_weight(), which checks for a certain |
874 | minimum number of transmissions before making | 733 | minimum number of transmissions before making |
875 | up an opinion) */ | 734 | up an opinion) */ |
876 | exit->num_transmitted = 5; | 735 | exit->num_transmitted = 5; |
@@ -900,8 +759,8 @@ dns_pre_request_handler (void *cls, | |||
900 | const char *request) | 759 | const char *request) |
901 | { | 760 | { |
902 | struct RequestContext *rc; | 761 | struct RequestContext *rc; |
903 | size_t mlen; | 762 | struct GNUNET_MQ_Envelope *env; |
904 | struct GNUNET_MessageHeader hdr; | 763 | struct GNUNET_MessageHeader *hdr; |
905 | struct GNUNET_TUN_DnsHeader dns; | 764 | struct GNUNET_TUN_DnsHeader dns; |
906 | struct CadetExit *exit; | 765 | struct CadetExit *exit; |
907 | 766 | ||
@@ -924,93 +783,115 @@ dns_pre_request_handler (void *cls, | |||
924 | GNUNET_DNS_request_drop (rh); | 783 | GNUNET_DNS_request_drop (rh); |
925 | return; | 784 | return; |
926 | } | 785 | } |
927 | GNUNET_memcpy (&dns, request, sizeof (dns)); | ||
928 | mlen = sizeof (struct GNUNET_MessageHeader) + request_length; | ||
929 | exit = choose_exit (); | 786 | exit = choose_exit (); |
930 | GNUNET_assert (NULL != exit); | 787 | GNUNET_assert (NULL != exit); |
931 | GNUNET_assert (NULL != exit->cadet_channel); | 788 | GNUNET_assert (NULL != exit->cadet_channel); |
932 | rc = GNUNET_malloc (sizeof (struct RequestContext) + mlen); | 789 | |
790 | env = GNUNET_MQ_msg_extra (hdr, | ||
791 | request_length, | ||
792 | GNUNET_MESSAGE_TYPE_VPN_DNS_TO_INTERNET); | ||
793 | GNUNET_memcpy (&hdr[1], | ||
794 | request, | ||
795 | request_length); | ||
796 | rc = GNUNET_new (struct RequestContext); | ||
933 | rc->exit = exit; | 797 | rc->exit = exit; |
934 | rc->rh = rh; | 798 | rc->rh = rh; |
935 | rc->cadet_message = (const struct GNUNET_MessageHeader*) &rc[1]; | ||
936 | rc->timeout_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, | 799 | rc->timeout_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, |
937 | &timeout_request, | 800 | &timeout_request, |
938 | rc); | 801 | rc); |
802 | GNUNET_memcpy (&dns, | ||
803 | request, | ||
804 | sizeof (dns)); | ||
939 | rc->dns_id = dns.id; | 805 | rc->dns_id = dns.id; |
940 | rc->mlen = mlen; | 806 | rc->env = env; |
941 | hdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_DNS_TO_INTERNET); | 807 | GNUNET_CONTAINER_DLL_remove (exit->receive_queue_head, |
942 | hdr.size = htons (mlen); | 808 | exit->receive_queue_tail, |
943 | GNUNET_memcpy (&rc[1], &hdr, sizeof (struct GNUNET_MessageHeader)); | 809 | rc); |
944 | GNUNET_memcpy (&(((char*)&rc[1])[sizeof (struct GNUNET_MessageHeader)]), | 810 | if (0 < exit->idle) |
945 | request, | 811 | exit->idle--; |
946 | request_length); | 812 | exit->num_transmitted++; |
947 | GNUNET_CONTAINER_DLL_insert_tail (exit->transmit_queue_head, | 813 | GNUNET_MQ_send (GNUNET_CADET_get_mq (exit->cadet_channel), |
948 | exit->transmit_queue_tail, | 814 | GNUNET_MQ_env_copy (env)); |
949 | rc); | ||
950 | if (NULL == exit->cadet_th) | ||
951 | exit->cadet_th = GNUNET_CADET_notify_transmit_ready (exit->cadet_channel, | ||
952 | GNUNET_NO, | ||
953 | TIMEOUT, | ||
954 | mlen, | ||
955 | &transmit_dns_request_to_cadet, | ||
956 | exit); | ||
957 | } | 815 | } |
958 | 816 | ||
959 | 817 | ||
818 | GNUNET_NETWORK_STRUCT_BEGIN | ||
819 | |||
820 | /** | ||
821 | * Message with a DNS response. | ||
822 | */ | ||
823 | struct DnsResponseMessage | ||
824 | { | ||
825 | /** | ||
826 | * GNUnet header, of type #GNUNET_MESSAGE_TYPE_VPN_DNS_FROM_INTERNET | ||
827 | */ | ||
828 | struct GNUNET_MessageHeader header; | ||
829 | |||
830 | /** | ||
831 | * DNS header. | ||
832 | */ | ||
833 | struct GNUNET_TUN_DnsHeader dns; | ||
834 | |||
835 | /* Followed by more DNS payload */ | ||
836 | }; | ||
837 | |||
838 | GNUNET_NETWORK_STRUCT_END | ||
839 | |||
960 | /** | 840 | /** |
961 | * Process a request via cadet to perform a DNS query. | 841 | * Process a request via cadet to perform a DNS query. |
962 | * | 842 | * |
963 | * @param cls NULL | 843 | * @param cls the `struct CadetExit` which got the message |
964 | * @param channel connection to the other end | 844 | * @param msg the actual message |
965 | * @param channel_ctx pointer to our `struct CadetExit` | ||
966 | * @param message the actual message | ||
967 | * @return #GNUNET_OK to keep the connection open, | 845 | * @return #GNUNET_OK to keep the connection open, |
968 | * #GNUNET_SYSERR to close it (signal serious error) | 846 | * #GNUNET_SYSERR to close it (signal serious error) |
969 | */ | 847 | */ |
970 | static int | 848 | static int |
971 | receive_dns_response (void *cls, | 849 | check_dns_response (void *cls, |
972 | struct GNUNET_CADET_Channel *channel, | 850 | const struct DnsResponseMessage *msg) |
973 | void **channel_ctx, | ||
974 | const struct GNUNET_MessageHeader *message) | ||
975 | { | 851 | { |
976 | struct CadetExit *exit = *channel_ctx; | 852 | return GNUNET_OK; /* all OK */ |
977 | struct GNUNET_TUN_DnsHeader dns; | 853 | } |
854 | |||
855 | |||
856 | /** | ||
857 | * Process a request via cadet to perform a DNS query. | ||
858 | * | ||
859 | * @param cls the `struct CadetExit` which got the message | ||
860 | * @param msg the actual message | ||
861 | */ | ||
862 | static void | ||
863 | handle_dns_response (void *cls, | ||
864 | const struct DnsResponseMessage *msg) | ||
865 | { | ||
866 | struct CadetExit *exit = cls; | ||
978 | size_t mlen; | 867 | size_t mlen; |
979 | struct RequestContext *rc; | 868 | struct RequestContext *rc; |
980 | 869 | ||
981 | mlen = ntohs (message->size); | 870 | mlen = ntohs (msg->header.size) - sizeof (*msg); |
982 | mlen -= sizeof (struct GNUNET_MessageHeader); | ||
983 | if (mlen < sizeof (struct GNUNET_TUN_DnsHeader)) | ||
984 | { | ||
985 | GNUNET_break_op (0); | ||
986 | return GNUNET_SYSERR; | ||
987 | } | ||
988 | GNUNET_memcpy (&dns, &message[1], sizeof (dns)); | ||
989 | for (rc = exit->receive_queue_head; NULL != rc; rc = rc->next) | 871 | for (rc = exit->receive_queue_head; NULL != rc; rc = rc->next) |
990 | { | 872 | { |
991 | GNUNET_assert (GNUNET_YES == rc->was_transmitted); | 873 | if (msg->dns.id == rc->dns_id) |
992 | if (dns.id == rc->dns_id) | ||
993 | { | 874 | { |
994 | GNUNET_STATISTICS_update (stats, | 875 | GNUNET_STATISTICS_update (stats, |
995 | gettext_noop ("# DNS replies received"), | 876 | gettext_noop ("# DNS replies received"), |
996 | 1, GNUNET_NO); | 877 | 1, |
878 | GNUNET_NO); | ||
997 | GNUNET_DNS_request_answer (rc->rh, | 879 | GNUNET_DNS_request_answer (rc->rh, |
998 | mlen, | 880 | mlen + sizeof (struct GNUNET_TUN_DnsHeader), |
999 | (const void*) &message[1]); | 881 | (const void*) &msg->dns); |
1000 | GNUNET_CONTAINER_DLL_remove (exit->receive_queue_head, | 882 | GNUNET_CONTAINER_DLL_remove (exit->receive_queue_head, |
1001 | exit->receive_queue_tail, | 883 | exit->receive_queue_tail, |
1002 | rc); | 884 | rc); |
1003 | GNUNET_SCHEDULER_cancel (rc->timeout_task); | 885 | GNUNET_SCHEDULER_cancel (rc->timeout_task); |
886 | GNUNET_MQ_discard (rc->env); | ||
1004 | GNUNET_free (rc); | 887 | GNUNET_free (rc); |
1005 | exit->num_answered++; | 888 | exit->num_answered++; |
1006 | exit->num_transmitted++; | 889 | return; |
1007 | return GNUNET_OK; | ||
1008 | } | 890 | } |
1009 | } | 891 | } |
1010 | GNUNET_STATISTICS_update (stats, | 892 | GNUNET_STATISTICS_update (stats, |
1011 | gettext_noop ("# DNS replies dropped (too late?)"), | 893 | gettext_noop ("# DNS replies dropped (too late?)"), |
1012 | 1, GNUNET_NO); | 894 | 1, GNUNET_NO); |
1013 | return GNUNET_OK; | ||
1014 | } | 895 | } |
1015 | 896 | ||
1016 | 897 | ||
@@ -1031,15 +912,7 @@ abort_all_requests (struct CadetExit *exit) | |||
1031 | rc); | 912 | rc); |
1032 | GNUNET_DNS_request_drop (rc->rh); | 913 | GNUNET_DNS_request_drop (rc->rh); |
1033 | GNUNET_SCHEDULER_cancel (rc->timeout_task); | 914 | GNUNET_SCHEDULER_cancel (rc->timeout_task); |
1034 | GNUNET_free (rc); | 915 | GNUNET_MQ_discard (rc->env); |
1035 | } | ||
1036 | while (NULL != (rc = exit->transmit_queue_head)) | ||
1037 | { | ||
1038 | GNUNET_CONTAINER_DLL_remove (exit->transmit_queue_head, | ||
1039 | exit->transmit_queue_tail, | ||
1040 | rc); | ||
1041 | GNUNET_DNS_request_drop (rc->rh); | ||
1042 | GNUNET_SCHEDULER_cancel (rc->timeout_task); | ||
1043 | GNUNET_free (rc); | 916 | GNUNET_free (rc); |
1044 | } | 917 | } |
1045 | } | 918 | } |
@@ -1067,11 +940,6 @@ cleanup (void *cls) | |||
1067 | GNUNET_CONTAINER_DLL_remove (exit_head, | 940 | GNUNET_CONTAINER_DLL_remove (exit_head, |
1068 | exit_tail, | 941 | exit_tail, |
1069 | exit); | 942 | exit); |
1070 | if (NULL != exit->cadet_th) | ||
1071 | { | ||
1072 | GNUNET_CADET_notify_transmit_ready_cancel (exit->cadet_th); | ||
1073 | exit->cadet_th = NULL; | ||
1074 | } | ||
1075 | if (NULL != exit->cadet_channel) | 943 | if (NULL != exit->cadet_channel) |
1076 | { | 944 | { |
1077 | GNUNET_CADET_channel_destroy (exit->cadet_channel); | 945 | GNUNET_CADET_channel_destroy (exit->cadet_channel); |
@@ -1126,63 +994,120 @@ cleanup (void *cls) | |||
1126 | */ | 994 | */ |
1127 | static void | 995 | static void |
1128 | cadet_channel_end_cb (void *cls, | 996 | cadet_channel_end_cb (void *cls, |
1129 | const struct GNUNET_CADET_Channel *channel, | 997 | const struct GNUNET_CADET_Channel *channel) |
1130 | void *channel_ctx) | ||
1131 | { | 998 | { |
1132 | struct CadetExit *exit = channel_ctx; | 999 | struct CadetExit *exit = cls; |
1133 | struct CadetExit *alt; | 1000 | struct CadetExit *alt; |
1134 | struct RequestContext *rc; | 1001 | struct RequestContext *rc; |
1135 | 1002 | ||
1136 | if (NULL != exit->cadet_th) | ||
1137 | { | ||
1138 | GNUNET_CADET_notify_transmit_ready_cancel (exit->cadet_th); | ||
1139 | exit->cadet_th = NULL; | ||
1140 | } | ||
1141 | exit->cadet_channel = NULL; | 1003 | exit->cadet_channel = NULL; |
1142 | dns_exit_available--; | 1004 | dns_exit_available--; |
1143 | /* open alternative channels */ | 1005 | /* open alternative channels */ |
1144 | try_open_exit (); | 1006 | /* our channel is now closed, move our requests to an alternative |
1145 | if (NULL == exit->cadet_channel) | 1007 | channel */ |
1008 | alt = choose_exit (); | ||
1009 | while (NULL != (rc = exit->receive_queue_head)) | ||
1146 | { | 1010 | { |
1147 | /* our channel is now closed, move our requests to an alternative | 1011 | GNUNET_CONTAINER_DLL_remove (exit->receive_queue_head, |
1148 | channel */ | 1012 | exit->receive_queue_tail, |
1149 | alt = choose_exit (); | 1013 | rc); |
1150 | while (NULL != (rc = exit->transmit_queue_head)) | 1014 | rc->exit = alt; |
1151 | { | 1015 | GNUNET_CONTAINER_DLL_insert (alt->receive_queue_head, |
1152 | GNUNET_CONTAINER_DLL_remove (exit->transmit_queue_head, | 1016 | alt->receive_queue_tail, |
1153 | exit->transmit_queue_tail, | 1017 | rc); |
1154 | rc); | 1018 | GNUNET_MQ_send (GNUNET_CADET_get_mq (exit->cadet_channel), |
1155 | rc->exit = alt; | 1019 | GNUNET_MQ_env_copy (rc->env)); |
1156 | GNUNET_CONTAINER_DLL_insert (alt->transmit_queue_head, | ||
1157 | alt->transmit_queue_tail, | ||
1158 | rc); | ||
1159 | } | ||
1160 | while (NULL != (rc = exit->receive_queue_head)) | ||
1161 | { | ||
1162 | GNUNET_CONTAINER_DLL_remove (exit->receive_queue_head, | ||
1163 | exit->receive_queue_tail, | ||
1164 | rc); | ||
1165 | rc->was_transmitted = GNUNET_NO; | ||
1166 | rc->exit = alt; | ||
1167 | GNUNET_CONTAINER_DLL_insert (alt->transmit_queue_head, | ||
1168 | alt->transmit_queue_tail, | ||
1169 | rc); | ||
1170 | } | ||
1171 | } | 1020 | } |
1172 | else | 1021 | try_open_exit (); |
1022 | } | ||
1023 | |||
1024 | |||
1025 | /** | ||
1026 | * Function called whenever a channel has excess capacity. | ||
1027 | * | ||
1028 | * @param cls the `struct CadetExit` | ||
1029 | * @param channel connection to the other end | ||
1030 | * @param window_size how much capacity do we have | ||
1031 | */ | ||
1032 | static void | ||
1033 | channel_idle_notify_cb (void *cls, | ||
1034 | const struct GNUNET_CADET_Channel *channel, | ||
1035 | int window_size) | ||
1036 | { | ||
1037 | struct CadetExit *pos = cls; | ||
1038 | |||
1039 | pos->idle = window_size; | ||
1040 | } | ||
1041 | |||
1042 | |||
1043 | /** | ||
1044 | * We are short on cadet exits, try to open another one. | ||
1045 | */ | ||
1046 | static void | ||
1047 | try_open_exit () | ||
1048 | { | ||
1049 | struct CadetExit *pos; | ||
1050 | uint32_t candidate_count; | ||
1051 | uint32_t candidate_selected; | ||
1052 | struct GNUNET_HashCode port; | ||
1053 | |||
1054 | GNUNET_CRYPTO_hash (GNUNET_APPLICATION_PORT_INTERNET_RESOLVER, | ||
1055 | strlen (GNUNET_APPLICATION_PORT_INTERNET_RESOLVER), | ||
1056 | &port); | ||
1057 | candidate_count = 0; | ||
1058 | for (pos = exit_head; NULL != pos; pos = pos->next) | ||
1059 | if (NULL == pos->cadet_channel) | ||
1060 | candidate_count++; | ||
1061 | if (0 == candidate_count) | ||
1173 | { | 1062 | { |
1174 | /* the same peer was chosen, just make sure the queue processing is restarted */ | 1063 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1175 | alt = exit; | 1064 | "No DNS exits available yet.\n"); |
1065 | return; | ||
1176 | } | 1066 | } |
1177 | if ( (NULL == alt->cadet_th) && | 1067 | candidate_selected = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, |
1178 | (NULL != (rc = alt->transmit_queue_head)) ) | 1068 | candidate_count); |
1179 | alt->cadet_th | 1069 | candidate_count = 0; |
1180 | = GNUNET_CADET_notify_transmit_ready (alt->cadet_channel, | 1070 | for (pos = exit_head; NULL != pos; pos = pos->next) |
1181 | GNUNET_NO, | 1071 | if (NULL == pos->cadet_channel) |
1182 | TIMEOUT, | 1072 | { |
1183 | rc->mlen, | 1073 | candidate_count++; |
1184 | &transmit_dns_request_to_cadet, | 1074 | if (candidate_selected < candidate_count) |
1185 | alt); | 1075 | { |
1076 | struct GNUNET_MQ_MessageHandler cadet_handlers[] = { | ||
1077 | GNUNET_MQ_hd_var_size (dns_response, | ||
1078 | GNUNET_MESSAGE_TYPE_VPN_DNS_FROM_INTERNET, | ||
1079 | struct DnsResponseMessage, | ||
1080 | pos), | ||
1081 | GNUNET_MQ_handler_end () | ||
1082 | }; | ||
1083 | |||
1084 | |||
1085 | /* move to the head of the DLL */ | ||
1086 | pos->cadet_channel | ||
1087 | = GNUNET_CADET_channel_creatE (cadet_handle, | ||
1088 | pos, | ||
1089 | &pos->peer, | ||
1090 | &port, | ||
1091 | GNUNET_CADET_OPTION_DEFAULT, | ||
1092 | &channel_idle_notify_cb, | ||
1093 | &cadet_channel_end_cb, | ||
1094 | cadet_handlers); | ||
1095 | if (NULL == pos->cadet_channel) | ||
1096 | { | ||
1097 | GNUNET_break (0); | ||
1098 | continue; | ||
1099 | } | ||
1100 | GNUNET_CONTAINER_DLL_remove (exit_head, | ||
1101 | exit_tail, | ||
1102 | pos); | ||
1103 | GNUNET_CONTAINER_DLL_insert (exit_head, | ||
1104 | exit_tail, | ||
1105 | pos); | ||
1106 | dns_exit_available++; | ||
1107 | return; | ||
1108 | } | ||
1109 | } | ||
1110 | GNUNET_assert (NULL == exit_head); | ||
1186 | } | 1111 | } |
1187 | 1112 | ||
1188 | 1113 | ||
@@ -1308,11 +1233,6 @@ run (void *cls, char *const *args GNUNET_UNUSED, | |||
1308 | } | 1233 | } |
1309 | if (dns_channel) | 1234 | if (dns_channel) |
1310 | { | 1235 | { |
1311 | static struct GNUNET_CADET_MessageHandler cadet_handlers[] = { | ||
1312 | {&receive_dns_response, GNUNET_MESSAGE_TYPE_VPN_DNS_FROM_INTERNET, 0}, | ||
1313 | {NULL, 0, 0} | ||
1314 | }; | ||
1315 | |||
1316 | dns_pre_handle | 1236 | dns_pre_handle |
1317 | = GNUNET_DNS_connect (cfg, | 1237 | = GNUNET_DNS_connect (cfg, |
1318 | GNUNET_DNS_FLAG_PRE_RESOLUTION, | 1238 | GNUNET_DNS_FLAG_PRE_RESOLUTION, |
@@ -1326,10 +1246,7 @@ run (void *cls, char *const *args GNUNET_UNUSED, | |||
1326 | GNUNET_SCHEDULER_shutdown (); | 1246 | GNUNET_SCHEDULER_shutdown (); |
1327 | return; | 1247 | return; |
1328 | } | 1248 | } |
1329 | cadet_handle = GNUNET_CADET_connect (cfg, | 1249 | cadet_handle = GNUNET_CADET_connecT (cfg); |
1330 | NULL, | ||
1331 | &cadet_channel_end_cb, | ||
1332 | cadet_handlers); | ||
1333 | if (NULL == cadet_handle) | 1250 | if (NULL == cadet_handle) |
1334 | { | 1251 | { |
1335 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 1252 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
diff --git a/src/pt/test_gns_vpn.c b/src/pt/test_gns_vpn.c index 4b7e817e8..53f27610b 100644 --- a/src/pt/test_gns_vpn.c +++ b/src/pt/test_gns_vpn.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | Copyright (C) 2007, 2009, 2011, 2012, 2015 Christian Grothoff | 3 | Copyright (C) 2007, 2009, 2011, 2012, 2015, 2017 Christian Grothoff |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -22,6 +22,19 @@ | |||
22 | * @file test_gns_vpn.c | 22 | * @file test_gns_vpn.c |
23 | * @brief testcase for accessing VPN services via GNS | 23 | * @brief testcase for accessing VPN services via GNS |
24 | * @author Martin Schanzenbach | 24 | * @author Martin Schanzenbach |
25 | * @author Christian Grothoff | ||
26 | * | ||
27 | * This test requires libcurl/libgnurl *with* support for C-ARES. | ||
28 | * This is NOT the default on most platforms, which means the test | ||
29 | * will be skipped in many cases. Compile libcurl/libgnurl with | ||
30 | * "--enable-ares" to get this test to pass. | ||
31 | * | ||
32 | * Furthermore, the test relies on gnunet-dns2gns being able to bind | ||
33 | * to port 53. This means that 'setcap' has to have worked during | ||
34 | * 'make install'. If this failed, but everything else is OK, the | ||
35 | * test may FAIL hard even though it is just an installation issue (we | ||
36 | * cannot conveniently test for the setcap to have worked). However, | ||
37 | * you should get a warning that gnunet-dns2gns failed to 'bind'. | ||
25 | */ | 38 | */ |
26 | #include "platform.h" | 39 | #include "platform.h" |
27 | #if HAVE_CURL_CURL_H | 40 | #if HAVE_CURL_CURL_H |
@@ -39,7 +52,7 @@ | |||
39 | #define PORT 8080 | 52 | #define PORT 8080 |
40 | #define TEST_DOMAIN "www.gnu" | 53 | #define TEST_DOMAIN "www.gnu" |
41 | 54 | ||
42 | #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 300) | 55 | #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) |
43 | 56 | ||
44 | /** | 57 | /** |
45 | * Return value for #main(). | 58 | * Return value for #main(). |
@@ -96,7 +109,10 @@ static struct CBC cbc; | |||
96 | 109 | ||
97 | 110 | ||
98 | static size_t | 111 | static size_t |
99 | copy_buffer (void *ptr, size_t size, size_t nmemb, void *ctx) | 112 | copy_buffer (void *ptr, |
113 | size_t size, | ||
114 | size_t nmemb, | ||
115 | void *ctx) | ||
100 | { | 116 | { |
101 | struct CBC *cbc = ctx; | 117 | struct CBC *cbc = ctx; |
102 | 118 | ||
@@ -174,6 +190,11 @@ do_shutdown (void *cls) | |||
174 | GNUNET_NAMESTORE_cancel (qe); | 190 | GNUNET_NAMESTORE_cancel (qe); |
175 | qe = NULL; | 191 | qe = NULL; |
176 | } | 192 | } |
193 | if (NULL != namestore) | ||
194 | { | ||
195 | GNUNET_NAMESTORE_disconnect (namestore); | ||
196 | namestore = NULL; | ||
197 | } | ||
177 | GNUNET_free_non_null (url); | 198 | GNUNET_free_non_null (url); |
178 | url = NULL; | 199 | url = NULL; |
179 | } | 200 | } |
@@ -280,6 +301,9 @@ curl_main () | |||
280 | static void | 301 | static void |
281 | start_curl (void *cls) | 302 | start_curl (void *cls) |
282 | { | 303 | { |
304 | CURLcode ec; | ||
305 | |||
306 | curl_task_id = NULL; | ||
283 | GNUNET_asprintf (&url, | 307 | GNUNET_asprintf (&url, |
284 | "http://%s/hello_world", | 308 | "http://%s/hello_world", |
285 | TEST_DOMAIN); | 309 | TEST_DOMAIN); |
@@ -291,7 +315,18 @@ start_curl (void *cls) | |||
291 | curl_easy_setopt (curl, CURLOPT_TIMEOUT, 150L); | 315 | curl_easy_setopt (curl, CURLOPT_TIMEOUT, 150L); |
292 | curl_easy_setopt (curl, CURLOPT_CONNECTTIMEOUT, 150L); | 316 | curl_easy_setopt (curl, CURLOPT_CONNECTTIMEOUT, 150L); |
293 | curl_easy_setopt (curl, CURLOPT_NOSIGNAL, 1); | 317 | curl_easy_setopt (curl, CURLOPT_NOSIGNAL, 1); |
294 | 318 | if (CURLE_OK != | |
319 | (ec = curl_easy_setopt (curl, | ||
320 | CURLOPT_DNS_SERVERS, | ||
321 | "127.0.0.1:53"))) | ||
322 | { | ||
323 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
324 | "curl build without support for CURLOPT_DNS_SERVERS (%s), cannot run test\n", | ||
325 | curl_easy_strerror (ec)); | ||
326 | global_ret = 77; | ||
327 | GNUNET_SCHEDULER_shutdown (); | ||
328 | return; | ||
329 | } | ||
295 | multi = curl_multi_init (); | 330 | multi = curl_multi_init (); |
296 | GNUNET_assert (multi != NULL); | 331 | GNUNET_assert (multi != NULL); |
297 | GNUNET_assert (CURLM_OK == curl_multi_add_handle (multi, curl)); | 332 | GNUNET_assert (CURLM_OK == curl_multi_add_handle (multi, curl)); |
@@ -302,14 +337,6 @@ start_curl (void *cls) | |||
302 | } | 337 | } |
303 | 338 | ||
304 | 339 | ||
305 | static void | ||
306 | disco_ns (void* cls) | ||
307 | { | ||
308 | GNUNET_NAMESTORE_disconnect (namestore); | ||
309 | namestore = NULL; | ||
310 | } | ||
311 | |||
312 | |||
313 | /** | 340 | /** |
314 | * Callback invoked from the namestore service once record is | 341 | * Callback invoked from the namestore service once record is |
315 | * created. | 342 | * created. |
@@ -328,9 +355,8 @@ commence_testing (void *cls, | |||
328 | const char *emsg) | 355 | const char *emsg) |
329 | { | 356 | { |
330 | qe = NULL; | 357 | qe = NULL; |
331 | GNUNET_SCHEDULER_add_now (&disco_ns, NULL); | 358 | if ( (NULL != emsg) && |
332 | 359 | (GNUNET_YES != success) ) | |
333 | if ((emsg != NULL) && (GNUNET_YES != success)) | ||
334 | { | 360 | { |
335 | fprintf (stderr, | 361 | fprintf (stderr, |
336 | "NS failed to create record %s\n", | 362 | "NS failed to create record %s\n", |
@@ -338,11 +364,14 @@ commence_testing (void *cls, | |||
338 | GNUNET_SCHEDULER_shutdown (); | 364 | GNUNET_SCHEDULER_shutdown (); |
339 | return; | 365 | return; |
340 | } | 366 | } |
367 | |||
341 | /* wait a little bit before downloading, as we just created the record */ | 368 | /* wait a little bit before downloading, as we just created the record */ |
342 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply | 369 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
343 | (GNUNET_TIME_UNIT_SECONDS, 1), | 370 | "Launching cURL request\n"); |
344 | &start_curl, | 371 | curl_task_id |
345 | NULL); | 372 | = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, |
373 | &start_curl, | ||
374 | NULL); | ||
346 | } | 375 | } |
347 | 376 | ||
348 | 377 | ||
@@ -402,7 +431,6 @@ mhd_main () | |||
402 | 431 | ||
403 | 432 | ||
404 | 433 | ||
405 | |||
406 | /** | 434 | /** |
407 | * Open '/dev/null' and make the result the given | 435 | * Open '/dev/null' and make the result the given |
408 | * file descriptor. | 436 | * file descriptor. |
@@ -448,9 +476,8 @@ fork_and_exec (const char *file, | |||
448 | pid = fork (); | 476 | pid = fork (); |
449 | if (-1 == pid) | 477 | if (-1 == pid) |
450 | { | 478 | { |
451 | fprintf (stderr, | 479 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, |
452 | "fork failed: %s\n", | 480 | "fork"); |
453 | strerror (errno)); | ||
454 | return 1; | 481 | return 1; |
455 | } | 482 | } |
456 | if (0 == pid) | 483 | if (0 == pid) |
@@ -464,10 +491,9 @@ fork_and_exec (const char *file, | |||
464 | open_dev_null (1, O_WRONLY); | 491 | open_dev_null (1, O_WRONLY); |
465 | (void) execv (file, cmd); | 492 | (void) execv (file, cmd); |
466 | /* can only get here on error */ | 493 | /* can only get here on error */ |
467 | fprintf (stderr, | 494 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, |
468 | "exec `%s' failed: %s\n", | 495 | "exec", |
469 | file, | 496 | file); |
470 | strerror (errno)); | ||
471 | _exit (1); | 497 | _exit (1); |
472 | } | 498 | } |
473 | /* keep running waitpid as long as the only error we get is 'EINTR' */ | 499 | /* keep running waitpid as long as the only error we get is 'EINTR' */ |
@@ -475,13 +501,20 @@ fork_and_exec (const char *file, | |||
475 | (errno == EINTR) ); | 501 | (errno == EINTR) ); |
476 | if (-1 == ret) | 502 | if (-1 == ret) |
477 | { | 503 | { |
478 | fprintf (stderr, | 504 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, |
479 | "waitpid failed: %s\n", | 505 | "waitpid"); |
480 | strerror (errno)); | ||
481 | return 1; | 506 | return 1; |
482 | } | 507 | } |
483 | if (! (WIFEXITED (status) && (0 == WEXITSTATUS (status)))) | 508 | if (! (WIFEXITED (status) && |
509 | (0 == WEXITSTATUS (status))) ) | ||
510 | { | ||
511 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
512 | "Process `%s` returned status code %d/%d.\n", | ||
513 | file, | ||
514 | WIFEXITED (status), | ||
515 | WEXITSTATUS (status)); | ||
484 | return 1; | 516 | return 1; |
517 | } | ||
485 | /* child process completed and returned success, we're happy */ | 518 | /* child process completed and returned success, we're happy */ |
486 | return 0; | 519 | return 0; |
487 | } | 520 | } |
@@ -572,6 +605,8 @@ identity_cb (void *cls, | |||
572 | &rd.data_size)); | 605 | &rd.data_size)); |
573 | rd.record_type = GNUNET_GNSRECORD_TYPE_VPN; | 606 | rd.record_type = GNUNET_GNSRECORD_TYPE_VPN; |
574 | 607 | ||
608 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
609 | "Creating `www` record\n"); | ||
575 | qe = GNUNET_NAMESTORE_records_store (namestore, | 610 | qe = GNUNET_NAMESTORE_records_store (namestore, |
576 | zone_key, | 611 | zone_key, |
577 | "www", | 612 | "www", |
@@ -593,15 +628,18 @@ run (void *cls, | |||
593 | char *bin; | 628 | char *bin; |
594 | char *bin_identity; | 629 | char *bin_identity; |
595 | char *bin_gns; | 630 | char *bin_gns; |
631 | char *bin_arm; | ||
596 | char *config; | 632 | char *config; |
597 | 633 | ||
634 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
635 | "Test logic starting...\n"); | ||
598 | if (GNUNET_OK != | 636 | if (GNUNET_OK != |
599 | GNUNET_CONFIGURATION_get_value_string (cfg, | 637 | GNUNET_CONFIGURATION_get_value_string (cfg, |
600 | "arm", | 638 | "arm", |
601 | "CONFIG", | 639 | "CONFIG", |
602 | &config)) | 640 | &config)) |
603 | { | 641 | { |
604 | fprintf (stderr, | 642 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
605 | "Failed to locate configuration file. Skipping test.\n"); | 643 | "Failed to locate configuration file. Skipping test.\n"); |
606 | GNUNET_SCHEDULER_shutdown (); | 644 | GNUNET_SCHEDULER_shutdown (); |
607 | return; | 645 | return; |
@@ -626,18 +664,27 @@ run (void *cls, | |||
626 | { | 664 | { |
627 | "gnunet-identity", | 665 | "gnunet-identity", |
628 | "-e", "master-zone", | 666 | "-e", "master-zone", |
629 | "-s", "gns-intercept", | 667 | "-s", "dns2gns", |
668 | "-c", config, | ||
669 | NULL | ||
670 | }; | ||
671 | char *const arm_args[] = | ||
672 | { | ||
673 | "gnunet-arm", | ||
674 | "-i", "dns2gns", | ||
630 | "-c", config, | 675 | "-c", config, |
631 | NULL | 676 | NULL |
632 | }; | 677 | }; |
633 | char *const gns_args[] = | 678 | char *const gns_args[] = |
634 | { | 679 | { |
635 | "gnunet-gns", | 680 | "gnunet-gns", |
636 | "-u", "www.gns", | 681 | "-u", "www.gnu", |
637 | "-c", config, | 682 | "-c", config, |
638 | NULL | 683 | NULL |
639 | }; | 684 | }; |
640 | GNUNET_TESTING_peer_get_identity (peer, &id); | 685 | |
686 | GNUNET_TESTING_peer_get_identity (peer, | ||
687 | &id); | ||
641 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, | 688 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, |
642 | NULL); | 689 | NULL); |
643 | timeout_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, | 690 | timeout_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, |
@@ -648,20 +695,24 @@ run (void *cls, | |||
648 | "%s/%s", | 695 | "%s/%s", |
649 | bin, | 696 | bin, |
650 | "gnunet-identity"); | 697 | "gnunet-identity"); |
698 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
699 | "Creating `master-zone` ego\n"); | ||
651 | if (0 != fork_and_exec (bin_identity, identity_args)) | 700 | if (0 != fork_and_exec (bin_identity, identity_args)) |
652 | { | 701 | { |
653 | fprintf (stderr, | 702 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
654 | "Failed to run `gnunet-identity -C. Skipping test.\n"); | 703 | "Failed to run `gnunet-identity -C`. Skipping test.\n"); |
655 | GNUNET_SCHEDULER_shutdown (); | 704 | GNUNET_SCHEDULER_shutdown (); |
656 | GNUNET_free (bin_identity); | 705 | GNUNET_free (bin_identity); |
657 | GNUNET_free (config); | 706 | GNUNET_free (config); |
658 | GNUNET_free (bin); | 707 | GNUNET_free (bin); |
659 | return; | 708 | return; |
660 | } | 709 | } |
710 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
711 | "Setting `master-zone` ego as default for `gns-master` and `dns2gns`\n"); | ||
661 | if (0 != fork_and_exec (bin_identity, identity2_args)) | 712 | if (0 != fork_and_exec (bin_identity, identity2_args)) |
662 | { | 713 | { |
663 | fprintf (stderr, | 714 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
664 | "Failed to run `gnunet-identity -e. Skipping test.\n"); | 715 | "Failed to run `gnunet-identity -e`. Skipping test.\n"); |
665 | GNUNET_SCHEDULER_shutdown (); | 716 | GNUNET_SCHEDULER_shutdown (); |
666 | GNUNET_free (bin_identity); | 717 | GNUNET_free (bin_identity); |
667 | GNUNET_free (config); | 718 | GNUNET_free (config); |
@@ -670,8 +721,8 @@ run (void *cls, | |||
670 | } | 721 | } |
671 | if (0 != fork_and_exec (bin_identity, identity3_args)) | 722 | if (0 != fork_and_exec (bin_identity, identity3_args)) |
672 | { | 723 | { |
673 | fprintf (stderr, | 724 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
674 | "Failed to run `gnunet-identity -e. Skipping test.\n"); | 725 | "Failed to run `gnunet-identity -e`. Skipping test.\n"); |
675 | GNUNET_SCHEDULER_shutdown (); | 726 | GNUNET_SCHEDULER_shutdown (); |
676 | GNUNET_free (bin_identity); | 727 | GNUNET_free (bin_identity); |
677 | GNUNET_free (config); | 728 | GNUNET_free (config); |
@@ -681,14 +732,17 @@ run (void *cls, | |||
681 | GNUNET_free (bin_identity); | 732 | GNUNET_free (bin_identity); |
682 | 733 | ||
683 | /* do lookup just to launch GNS service */ | 734 | /* do lookup just to launch GNS service */ |
735 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
736 | "Resolving `www.gnu` zone entry to launch GNS (will yield no answer yet)\n"); | ||
684 | GNUNET_asprintf (&bin_gns, | 737 | GNUNET_asprintf (&bin_gns, |
685 | "%s/%s", | 738 | "%s/%s", |
686 | bin, | 739 | bin, |
687 | "gnunet-gns"); | 740 | "gnunet-gns"); |
688 | if (0 != fork_and_exec (bin_gns, gns_args)) | 741 | if (0 != fork_and_exec (bin_gns, |
742 | gns_args)) | ||
689 | { | 743 | { |
690 | fprintf (stderr, | 744 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
691 | "Failed to run `gnunet-gns -u. Skipping test.\n"); | 745 | "Failed to run `gnunet-gns -u. Skipping test.\n"); |
692 | GNUNET_SCHEDULER_shutdown (); | 746 | GNUNET_SCHEDULER_shutdown (); |
693 | GNUNET_free (bin_gns); | 747 | GNUNET_free (bin_gns); |
694 | GNUNET_free (config); | 748 | GNUNET_free (config); |
@@ -696,9 +750,27 @@ run (void *cls, | |||
696 | return; | 750 | return; |
697 | } | 751 | } |
698 | GNUNET_free (bin_gns); | 752 | GNUNET_free (bin_gns); |
753 | |||
754 | GNUNET_asprintf (&bin_arm, | ||
755 | "%s/%s", | ||
756 | bin, | ||
757 | "gnunet-arm"); | ||
758 | if (0 != fork_and_exec (bin_arm, | ||
759 | arm_args)) | ||
760 | { | ||
761 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
762 | "Failed to run `gnunet-arm -i dns2gns. Skipping test.\n"); | ||
763 | GNUNET_SCHEDULER_shutdown (); | ||
764 | GNUNET_free (bin_arm); | ||
765 | GNUNET_free (config); | ||
766 | GNUNET_free (bin); | ||
767 | return; | ||
768 | } | ||
769 | GNUNET_free (bin_arm); | ||
770 | |||
699 | GNUNET_free (config); | 771 | GNUNET_free (config); |
700 | GNUNET_free (bin); | 772 | GNUNET_free (bin); |
701 | 773 | sleep (1); /* give dns2gns chance to really run */ | |
702 | 774 | ||
703 | namestore = GNUNET_NAMESTORE_connect (cfg); | 775 | namestore = GNUNET_NAMESTORE_connect (cfg); |
704 | GNUNET_assert (NULL != namestore); | 776 | GNUNET_assert (NULL != namestore); |
@@ -720,39 +792,15 @@ run (void *cls, | |||
720 | 792 | ||
721 | 793 | ||
722 | int | 794 | int |
723 | main (int argc, char *const *argv) | 795 | main (int argc, |
796 | char *const *argv) | ||
724 | { | 797 | { |
725 | char *sbin_iptables; | ||
726 | char *bin_vpn; | 798 | char *bin_vpn; |
727 | char *bin_exit; | 799 | char *bin_exit; |
728 | char *bin_dns; | ||
729 | char *srv_dns; | ||
730 | struct stat s; | ||
731 | gid_t my_gid; | ||
732 | char *const iptables_args[] = | ||
733 | { | ||
734 | "iptables", "-t", "mangle", "-L", "-v", NULL | ||
735 | }; | ||
736 | |||
737 | if (0 == access ("/sbin/iptables", X_OK)) | ||
738 | sbin_iptables = "/sbin/iptables"; | ||
739 | else if (0 == access ("/usr/sbin/iptables", X_OK)) | ||
740 | sbin_iptables = "/usr/sbin/iptables"; | ||
741 | else | ||
742 | { | ||
743 | fprintf (stderr, | ||
744 | "Executable iptables not found in approved directories: %s, skipping\n", | ||
745 | strerror (errno)); | ||
746 | return 77; | ||
747 | } | ||
748 | |||
749 | if (0 != fork_and_exec (sbin_iptables, iptables_args)) | ||
750 | { | ||
751 | fprintf (stderr, | ||
752 | "Failed to run `iptables -t mangle -L -v'. Skipping test.\n"); | ||
753 | return 77; | ||
754 | } | ||
755 | 800 | ||
801 | GNUNET_log_setup ("test-gns-vpn", | ||
802 | "WARNING", | ||
803 | NULL); | ||
756 | if (0 != ACCESS ("/dev/net/tun", R_OK)) | 804 | if (0 != ACCESS ("/dev/net/tun", R_OK)) |
757 | { | 805 | { |
758 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, | 806 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, |
@@ -765,59 +813,26 @@ main (int argc, char *const *argv) | |||
765 | 813 | ||
766 | bin_vpn = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-vpn"); | 814 | bin_vpn = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-vpn"); |
767 | bin_exit = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-exit"); | 815 | bin_exit = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-exit"); |
768 | bin_dns = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-dns"); | ||
769 | srv_dns = GNUNET_OS_get_libexec_binary_path ("gnunet-service-dns"); | ||
770 | if ( (0 != geteuid ()) && | 816 | if ( (0 != geteuid ()) && |
771 | ( (GNUNET_YES != | 817 | ( (GNUNET_YES != |
772 | GNUNET_OS_check_helper_binary (bin_vpn, GNUNET_YES, "-d gnunet-vpn - - 169.1.3.3.7 255.255.255.0")) || //ipv4 only please! | 818 | GNUNET_OS_check_helper_binary (bin_vpn, |
819 | GNUNET_YES, | ||
820 | "-d gnunet-vpn - - 169.1.3.3.7 255.255.255.0")) || //ipv4 only please! | ||
773 | (GNUNET_YES != | 821 | (GNUNET_YES != |
774 | GNUNET_OS_check_helper_binary (bin_exit, GNUNET_YES, "-d gnunet-vpn - - - 169.1.3.3.7 255.255.255.0")) || //no nat, ipv4 only | 822 | GNUNET_OS_check_helper_binary (bin_exit, |
775 | (GNUNET_YES != | 823 | GNUNET_YES, |
776 | GNUNET_OS_check_helper_binary (bin_dns, GNUNET_YES, NULL))) ) // TODO: once we have a windows-testcase, add test parameters here | 824 | "-d gnunet-vpn - - - 169.1.3.3.7 255.255.255.0")) ) ) //no nat, ipv4 only |
777 | { | 825 | { |
778 | fprintf (stderr, | 826 | fprintf (stderr, |
779 | "WARNING: gnunet-helper-{exit,vpn,dns} binaries in $PATH are not SUID, refusing to run test (as it would have to fail).\n"); | 827 | "WARNING: gnunet-helper-{exit,vpn} binaries in $PATH are not SUID, refusing to run test (as it would have to fail).\n"); |
780 | fprintf (stderr, | 828 | fprintf (stderr, |
781 | "Change $PATH ('.' in $PATH before $GNUNET_PREFIX/bin is problematic) or permissions (run 'make install' as root) to fix this!\n"); | 829 | "Change $PATH ('.' in $PATH before $GNUNET_PREFIX/bin is problematic) or permissions (run 'make install' as root) to fix this!\n"); |
782 | GNUNET_free (bin_vpn); | 830 | GNUNET_free (bin_vpn); |
783 | GNUNET_free (bin_exit); | 831 | GNUNET_free (bin_exit); |
784 | GNUNET_free (bin_dns); | ||
785 | GNUNET_free (srv_dns); | ||
786 | return 77; | 832 | return 77; |
787 | } | 833 | } |
788 | GNUNET_free (bin_vpn); | 834 | GNUNET_free (bin_vpn); |
789 | GNUNET_free (bin_exit); | 835 | GNUNET_free (bin_exit); |
790 | my_gid = getgid (); | ||
791 | if ( (0 != stat (bin_dns, &s)) || | ||
792 | (my_gid == s.st_gid) || | ||
793 | ( (0 == (S_ISUID & s.st_mode)) && (0 != getuid()) ) ) | ||
794 | { | ||
795 | fprintf (stderr, | ||
796 | "WARNING: %s has wrong permissions (%d, %d, %d), refusing to run test (as it would have to fail).\n", | ||
797 | bin_dns, | ||
798 | (0 != stat (bin_dns, &s)), | ||
799 | (my_gid == s.st_gid), | ||
800 | (0 == (S_ISUID & s.st_mode)) || (0 != getuid()) ); | ||
801 | GNUNET_free (bin_dns); | ||
802 | GNUNET_free (srv_dns); | ||
803 | return 77; | ||
804 | } | ||
805 | if ( (0 != stat (srv_dns, &s)) || | ||
806 | (my_gid == s.st_gid) || | ||
807 | (0 == (S_ISGID & s.st_mode)) ) | ||
808 | { | ||
809 | fprintf (stderr, | ||
810 | "WARNING: %s has wrong permissions (%d, %d, %d), refusing to run test (as it would have to fail).\n", | ||
811 | srv_dns, | ||
812 | (0 != stat (bin_dns, &s)), | ||
813 | (my_gid == s.st_gid), | ||
814 | (0 == (S_ISGID & s.st_mode)) ); | ||
815 | GNUNET_free (bin_dns); | ||
816 | GNUNET_free (srv_dns); | ||
817 | return 77; | ||
818 | } | ||
819 | GNUNET_free (bin_dns); | ||
820 | GNUNET_free (srv_dns); | ||
821 | 836 | ||
822 | dest_ip = "169.254.86.1"; | 837 | dest_ip = "169.254.86.1"; |
823 | dest_af = AF_INET; | 838 | dest_af = AF_INET; |
@@ -842,9 +857,11 @@ main (int argc, char *const *argv) | |||
842 | } | 857 | } |
843 | 858 | ||
844 | 859 | ||
845 | if (0 != GNUNET_TESTING_peer_run ("test-gnunet-vpn", | 860 | if (0 != |
846 | "test_gns_vpn.conf", | 861 | GNUNET_TESTING_peer_run ("test_gns_vpn", |
847 | &run, NULL)) | 862 | "test_gns_vpn.conf", |
863 | &run, | ||
864 | NULL)) | ||
848 | return 1; | 865 | return 1; |
849 | GNUNET_DISK_directory_remove ("/tmp/gnunet-test-vpn"); | 866 | GNUNET_DISK_directory_remove ("/tmp/gnunet-test-vpn"); |
850 | return global_ret; | 867 | return global_ret; |
diff --git a/src/pt/test_gns_vpn.conf b/src/pt/test_gns_vpn.conf index ac9724c04..86642465f 100644 --- a/src/pt/test_gns_vpn.conf +++ b/src/pt/test_gns_vpn.conf | |||
@@ -35,6 +35,10 @@ FORCESTART = YES | |||
35 | AUTOSTART = NO | 35 | AUTOSTART = NO |
36 | FORCESTART = NO | 36 | FORCESTART = NO |
37 | 37 | ||
38 | [zonemaster] | ||
39 | AUTOSTART = YES | ||
40 | FORCESTART = YES | ||
41 | |||
38 | #[vpn] | 42 | #[vpn] |
39 | #PREFIX = valgrind | 43 | #PREFIX = valgrind |
40 | 44 | ||
diff --git a/src/regex/plugin_block_regex.c b/src/regex/plugin_block_regex.c index 6636f3cdb..287ecf905 100644 --- a/src/regex/plugin_block_regex.c +++ b/src/regex/plugin_block_regex.c | |||
@@ -28,11 +28,17 @@ | |||
28 | #include "gnunet_block_group_lib.h" | 28 | #include "gnunet_block_group_lib.h" |
29 | #include "block_regex.h" | 29 | #include "block_regex.h" |
30 | #include "regex_block_lib.h" | 30 | #include "regex_block_lib.h" |
31 | #include "gnunet_constants.h" | ||
32 | #include "gnunet_signatures.h" | 31 | #include "gnunet_signatures.h" |
33 | 32 | ||
34 | 33 | ||
35 | /** | 34 | /** |
35 | * Number of bits we set per entry in the bloomfilter. | ||
36 | * Do not change! | ||
37 | */ | ||
38 | #define BLOOMFILTER_K 16 | ||
39 | |||
40 | |||
41 | /** | ||
36 | * How big is the BF we use for REGEX blocks? | 42 | * How big is the BF we use for REGEX blocks? |
37 | */ | 43 | */ |
38 | #define REGEX_BF_SIZE 8 | 44 | #define REGEX_BF_SIZE 8 |
@@ -58,9 +64,26 @@ block_plugin_regex_create_group (void *cls, | |||
58 | size_t raw_data_size, | 64 | size_t raw_data_size, |
59 | va_list va) | 65 | va_list va) |
60 | { | 66 | { |
67 | unsigned int bf_size; | ||
68 | const char *guard; | ||
69 | |||
70 | guard = va_arg (va, const char *); | ||
71 | if (0 == strcmp (guard, | ||
72 | "seen-set-size")) | ||
73 | bf_size = GNUNET_BLOCK_GROUP_compute_bloomfilter_size (va_arg (va, unsigned int), | ||
74 | BLOOMFILTER_K); | ||
75 | else if (0 == strcmp (guard, | ||
76 | "filter-size")) | ||
77 | bf_size = va_arg (va, unsigned int); | ||
78 | else | ||
79 | { | ||
80 | GNUNET_break (0); | ||
81 | bf_size = REGEX_BF_SIZE; | ||
82 | } | ||
83 | GNUNET_break (NULL == va_arg (va, const char *)); | ||
61 | return GNUNET_BLOCK_GROUP_bf_create (cls, | 84 | return GNUNET_BLOCK_GROUP_bf_create (cls, |
62 | REGEX_BF_SIZE, | 85 | bf_size, |
63 | GNUNET_CONSTANTS_BLOOMFILTER_K, | 86 | BLOOMFILTER_K, |
64 | type, | 87 | type, |
65 | nonce, | 88 | nonce, |
66 | raw_data, | 89 | raw_data, |
@@ -246,6 +269,7 @@ evaluate_block_regex_accept (void *cls, | |||
246 | * be done with the #GNUNET_BLOCK_get_key() function. | 269 | * be done with the #GNUNET_BLOCK_get_key() function. |
247 | * | 270 | * |
248 | * @param cls closure | 271 | * @param cls closure |
272 | * @param ctx block context | ||
249 | * @param type block type | 273 | * @param type block type |
250 | * @param bg group to evaluate against | 274 | * @param bg group to evaluate against |
251 | * @param eo control flags | 275 | * @param eo control flags |
@@ -258,6 +282,7 @@ evaluate_block_regex_accept (void *cls, | |||
258 | */ | 282 | */ |
259 | static enum GNUNET_BLOCK_EvaluationResult | 283 | static enum GNUNET_BLOCK_EvaluationResult |
260 | block_plugin_regex_evaluate (void *cls, | 284 | block_plugin_regex_evaluate (void *cls, |
285 | struct GNUNET_BLOCK_Context *ctx, | ||
261 | enum GNUNET_BLOCK_Type type, | 286 | enum GNUNET_BLOCK_Type type, |
262 | struct GNUNET_BLOCK_Group *bg, | 287 | struct GNUNET_BLOCK_Group *bg, |
263 | enum GNUNET_BLOCK_EvaluationOptions eo, | 288 | enum GNUNET_BLOCK_EvaluationOptions eo, |
@@ -370,7 +395,7 @@ libgnunet_plugin_block_regex_init (void *cls) | |||
370 | void * | 395 | void * |
371 | libgnunet_plugin_block_regex_done (void *cls) | 396 | libgnunet_plugin_block_regex_done (void *cls) |
372 | { | 397 | { |
373 | struct GNUNET_TRANSPORT_PluginFunctions *api = cls; | 398 | struct GNUNET_BLOCK_PluginFunctions *api = cls; |
374 | 399 | ||
375 | GNUNET_free (api); | 400 | GNUNET_free (api); |
376 | return NULL; | 401 | return NULL; |
diff --git a/src/revocation/Makefile.am b/src/revocation/Makefile.am index 541c7120d..82755b485 100644 --- a/src/revocation/Makefile.am +++ b/src/revocation/Makefile.am | |||
@@ -1,6 +1,8 @@ | |||
1 | # This Makefile.am is in the public domain | 1 | # This Makefile.am is in the public domain |
2 | AM_CPPFLAGS = -I$(top_srcdir)/src/include | 2 | AM_CPPFLAGS = -I$(top_srcdir)/src/include |
3 | 3 | ||
4 | plugindir = $(libdir)/gnunet | ||
5 | |||
4 | if MINGW | 6 | if MINGW |
5 | WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols | 7 | WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols |
6 | endif | 8 | endif |
@@ -21,6 +23,20 @@ bin_PROGRAMS = \ | |||
21 | gnunet-revocation | 23 | gnunet-revocation |
22 | 24 | ||
23 | 25 | ||
26 | plugin_LTLIBRARIES = \ | ||
27 | libgnunet_plugin_block_revocation.la | ||
28 | |||
29 | libgnunet_plugin_block_revocation_la_SOURCES = \ | ||
30 | plugin_block_revocation.c | ||
31 | libgnunet_plugin_block_revocation_la_LIBADD = \ | ||
32 | libgnunetrevocation.la \ | ||
33 | $(top_builddir)/src/block/libgnunetblockgroup.la \ | ||
34 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
35 | $(LTLIBINTL) | ||
36 | libgnunet_plugin_block_revocation_la_LDFLAGS = \ | ||
37 | $(GN_PLUGIN_LDFLAGS) | ||
38 | |||
39 | |||
24 | gnunet_revocation_SOURCES = \ | 40 | gnunet_revocation_SOURCES = \ |
25 | gnunet-revocation.c | 41 | gnunet-revocation.c |
26 | gnunet_revocation_LDADD = \ | 42 | gnunet_revocation_LDADD = \ |
@@ -86,4 +102,3 @@ test_local_revocation.py: test_local_revocation.py.in Makefile | |||
86 | 102 | ||
87 | EXTRA_DIST = test_revocation.conf \ | 103 | EXTRA_DIST = test_revocation.conf \ |
88 | test_local_revocation.py.in | 104 | test_local_revocation.py.in |
89 | |||
diff --git a/src/revocation/gnunet-service-revocation.c b/src/revocation/gnunet-service-revocation.c index 2965808fa..9d077f874 100644 --- a/src/revocation/gnunet-service-revocation.c +++ b/src/revocation/gnunet-service-revocation.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include "platform.h" | 38 | #include "platform.h" |
39 | #include <math.h> | 39 | #include <math.h> |
40 | #include "gnunet_util_lib.h" | 40 | #include "gnunet_util_lib.h" |
41 | #include "gnunet_block_lib.h" | ||
41 | #include "gnunet_constants.h" | 42 | #include "gnunet_constants.h" |
42 | #include "gnunet_protocols.h" | 43 | #include "gnunet_protocols.h" |
43 | #include "gnunet_signatures.h" | 44 | #include "gnunet_signatures.h" |
@@ -215,7 +216,7 @@ client_connect_cb (void *cls, | |||
215 | * @param client the new client | 216 | * @param client the new client |
216 | * @param app_cls must alias @a client | 217 | * @param app_cls must alias @a client |
217 | */ | 218 | */ |
218 | static void | 219 | static void |
219 | client_disconnect_cb (void *cls, | 220 | client_disconnect_cb (void *cls, |
220 | struct GNUNET_SERVICE_Client *client, | 221 | struct GNUNET_SERVICE_Client *client, |
221 | void *app_cls) | 222 | void *app_cls) |
@@ -352,7 +353,7 @@ publicize_rm (const struct RevokeMessage *rm) | |||
352 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | 353 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); |
353 | /* add to set for future connections */ | 354 | /* add to set for future connections */ |
354 | e.size = htons (rm->header.size); | 355 | e.size = htons (rm->header.size); |
355 | e.element_type = 0; | 356 | e.element_type = GNUNET_BLOCK_TYPE_REVOCATION; |
356 | e.data = rm; | 357 | e.data = rm; |
357 | if (GNUNET_OK != | 358 | if (GNUNET_OK != |
358 | GNUNET_SET_add_element (revocation_set, | 359 | GNUNET_SET_add_element (revocation_set, |
@@ -432,11 +433,13 @@ handle_p2p_revoke (void *cls, | |||
432 | * | 433 | * |
433 | * @param cls closure | 434 | * @param cls closure |
434 | * @param element a result element, only valid if status is #GNUNET_SET_STATUS_OK | 435 | * @param element a result element, only valid if status is #GNUNET_SET_STATUS_OK |
436 | * @param current_size current set size | ||
435 | * @param status see `enum GNUNET_SET_Status` | 437 | * @param status see `enum GNUNET_SET_Status` |
436 | */ | 438 | */ |
437 | static void | 439 | static void |
438 | add_revocation (void *cls, | 440 | add_revocation (void *cls, |
439 | const struct GNUNET_SET_Element *element, | 441 | const struct GNUNET_SET_Element *element, |
442 | uint64_t current_size, | ||
440 | enum GNUNET_SET_Status status) | 443 | enum GNUNET_SET_Status status) |
441 | { | 444 | { |
442 | struct PeerEntry *peer_entry = cls; | 445 | struct PeerEntry *peer_entry = cls; |
@@ -450,11 +453,12 @@ add_revocation (void *cls, | |||
450 | GNUNET_break_op (0); | 453 | GNUNET_break_op (0); |
451 | return; | 454 | return; |
452 | } | 455 | } |
453 | if (0 != element->element_type) | 456 | if (GNUNET_BLOCK_TYPE_REVOCATION != element->element_type) |
454 | { | 457 | { |
455 | GNUNET_STATISTICS_update (stats, | 458 | GNUNET_STATISTICS_update (stats, |
456 | gettext_noop ("# unsupported revocations received via set union"), | 459 | gettext_noop ("# unsupported revocations received via set union"), |
457 | 1, GNUNET_NO); | 460 | 1, |
461 | GNUNET_NO); | ||
458 | return; | 462 | return; |
459 | } | 463 | } |
460 | rm = element->data; | 464 | rm = element->data; |
@@ -509,6 +513,7 @@ transmit_task_cb (void *cls) | |||
509 | &revocation_set_union_app_id, | 513 | &revocation_set_union_app_id, |
510 | NULL, | 514 | NULL, |
511 | GNUNET_SET_RESULT_ADDED, | 515 | GNUNET_SET_RESULT_ADDED, |
516 | (struct GNUNET_SET_Option[]) {{ 0 }}, | ||
512 | &add_revocation, | 517 | &add_revocation, |
513 | peer_entry); | 518 | peer_entry); |
514 | if (GNUNET_OK != | 519 | if (GNUNET_OK != |
@@ -601,12 +606,12 @@ handle_core_disconnect (void *cls, | |||
601 | void *internal_cls) | 606 | void *internal_cls) |
602 | { | 607 | { |
603 | struct PeerEntry *peer_entry = internal_cls; | 608 | struct PeerEntry *peer_entry = internal_cls; |
604 | 609 | ||
605 | if (0 == memcmp (peer, | 610 | if (0 == memcmp (peer, |
606 | &my_identity, | 611 | &my_identity, |
607 | sizeof (my_identity))) | 612 | sizeof (my_identity))) |
608 | return; | 613 | return; |
609 | GNUNET_assert (NULL != peer_entry); | 614 | GNUNET_assert (NULL != peer_entry); |
610 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 615 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
611 | "Peer `%s' disconnected from us\n", | 616 | "Peer `%s' disconnected from us\n", |
612 | GNUNET_i2s (peer)); | 617 | GNUNET_i2s (peer)); |
@@ -755,6 +760,7 @@ handle_revocation_union_request (void *cls, | |||
755 | } | 760 | } |
756 | peer_entry->so = GNUNET_SET_accept (request, | 761 | peer_entry->so = GNUNET_SET_accept (request, |
757 | GNUNET_SET_RESULT_ADDED, | 762 | GNUNET_SET_RESULT_ADDED, |
763 | (struct GNUNET_SET_Option[]) {{ 0 }}, | ||
758 | &add_revocation, | 764 | &add_revocation, |
759 | peer_entry); | 765 | peer_entry); |
760 | if (GNUNET_OK != | 766 | if (GNUNET_OK != |
@@ -779,7 +785,7 @@ handle_revocation_union_request (void *cls, | |||
779 | static void | 785 | static void |
780 | run (void *cls, | 786 | run (void *cls, |
781 | const struct GNUNET_CONFIGURATION_Handle *c, | 787 | const struct GNUNET_CONFIGURATION_Handle *c, |
782 | struct GNUNET_SERVICE_Handle *service) | 788 | struct GNUNET_SERVICE_Handle *service) |
783 | { | 789 | { |
784 | struct GNUNET_MQ_MessageHandler core_handlers[] = { | 790 | struct GNUNET_MQ_MessageHandler core_handlers[] = { |
785 | GNUNET_MQ_hd_fixed_size (p2p_revoke, | 791 | GNUNET_MQ_hd_fixed_size (p2p_revoke, |
diff --git a/src/revocation/plugin_block_revocation.c b/src/revocation/plugin_block_revocation.c new file mode 100644 index 000000000..eb0766b81 --- /dev/null +++ b/src/revocation/plugin_block_revocation.c | |||
@@ -0,0 +1,257 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2017 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file block/plugin_block_revocation.c | ||
23 | * @brief revocation for a block plugin | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | |||
27 | #include "platform.h" | ||
28 | #include "gnunet_signatures.h" | ||
29 | #include "gnunet_block_plugin.h" | ||
30 | #include "gnunet_block_group_lib.h" | ||
31 | #include "revocation.h" | ||
32 | #include "gnunet_revocation_service.h" | ||
33 | |||
34 | #define DEBUG_REVOCATION GNUNET_EXTRA_LOGGING | ||
35 | |||
36 | /** | ||
37 | * Number of bits we set per entry in the bloomfilter. | ||
38 | * Do not change! | ||
39 | */ | ||
40 | #define BLOOMFILTER_K 16 | ||
41 | |||
42 | |||
43 | /** | ||
44 | * How big is the BF we use for DHT blocks? | ||
45 | */ | ||
46 | #define REVOCATION_BF_SIZE 8 | ||
47 | |||
48 | |||
49 | /** | ||
50 | * Context used inside the plugin. | ||
51 | */ | ||
52 | struct InternalContext | ||
53 | { | ||
54 | |||
55 | unsigned int matching_bits; | ||
56 | |||
57 | }; | ||
58 | |||
59 | |||
60 | /** | ||
61 | * Create a new block group. | ||
62 | * | ||
63 | * @param ctx block context in which the block group is created | ||
64 | * @param type type of the block for which we are creating the group | ||
65 | * @param nonce random value used to seed the group creation | ||
66 | * @param raw_data optional serialized prior state of the group, NULL if unavailable/fresh | ||
67 | * @param raw_data_size number of bytes in @a raw_data, 0 if unavailable/fresh | ||
68 | * @param va variable arguments specific to @a type | ||
69 | * @return block group handle, NULL if block groups are not supported | ||
70 | * by this @a type of block (this is not an error) | ||
71 | */ | ||
72 | static struct GNUNET_BLOCK_Group * | ||
73 | block_plugin_revocation_create_group (void *cls, | ||
74 | enum GNUNET_BLOCK_Type type, | ||
75 | uint32_t nonce, | ||
76 | const void *raw_data, | ||
77 | size_t raw_data_size, | ||
78 | va_list va) | ||
79 | { | ||
80 | unsigned int bf_size; | ||
81 | const char *guard; | ||
82 | |||
83 | guard = va_arg (va, const char *); | ||
84 | if (0 == strcmp (guard, | ||
85 | "seen-set-size")) | ||
86 | bf_size = GNUNET_BLOCK_GROUP_compute_bloomfilter_size (va_arg (va, unsigned int), | ||
87 | BLOOMFILTER_K); | ||
88 | else if (0 == strcmp (guard, | ||
89 | "filter-size")) | ||
90 | bf_size = va_arg (va, unsigned int); | ||
91 | else | ||
92 | { | ||
93 | GNUNET_break (0); | ||
94 | bf_size = REVOCATION_BF_SIZE; | ||
95 | } | ||
96 | GNUNET_break (NULL == va_arg (va, const char *)); | ||
97 | return GNUNET_BLOCK_GROUP_bf_create (cls, | ||
98 | bf_size, | ||
99 | BLOOMFILTER_K, | ||
100 | type, | ||
101 | nonce, | ||
102 | raw_data, | ||
103 | raw_data_size); | ||
104 | } | ||
105 | |||
106 | |||
107 | /** | ||
108 | * Function called to validate a reply or a request. For | ||
109 | * request evaluation, simply pass "NULL" for the reply_block. | ||
110 | * | ||
111 | * @param cls our `struct InternalContext` | ||
112 | * @param ctx context | ||
113 | * @param type block type | ||
114 | * @param group block group to use | ||
115 | * @param eo control flags | ||
116 | * @param query original query (hash) | ||
117 | * @param xquery extrended query data (can be NULL, depending on type) | ||
118 | * @param xquery_size number of bytes in xquery | ||
119 | * @param reply_block response to validate | ||
120 | * @param reply_block_size number of bytes in reply block | ||
121 | * @return characterization of result | ||
122 | */ | ||
123 | static enum GNUNET_BLOCK_EvaluationResult | ||
124 | block_plugin_revocation_evaluate (void *cls, | ||
125 | struct GNUNET_BLOCK_Context *ctx, | ||
126 | enum GNUNET_BLOCK_Type type, | ||
127 | struct GNUNET_BLOCK_Group *group, | ||
128 | enum GNUNET_BLOCK_EvaluationOptions eo, | ||
129 | const struct GNUNET_HashCode *query, | ||
130 | const void *xquery, | ||
131 | size_t xquery_size, | ||
132 | const void *reply_block, | ||
133 | size_t reply_block_size) | ||
134 | { | ||
135 | struct InternalContext *ic = cls; | ||
136 | struct GNUNET_HashCode chash; | ||
137 | const struct RevokeMessage *rm = reply_block; | ||
138 | |||
139 | if (NULL == reply_block) | ||
140 | return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; | ||
141 | if (reply_block_size != sizeof (*rm)) | ||
142 | { | ||
143 | GNUNET_break_op (0); | ||
144 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
145 | } | ||
146 | if (GNUNET_YES != | ||
147 | GNUNET_REVOCATION_check_pow (&rm->public_key, | ||
148 | rm->proof_of_work, | ||
149 | ic->matching_bits)) | ||
150 | { | ||
151 | GNUNET_break_op (0); | ||
152 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
153 | } | ||
154 | if (GNUNET_OK != | ||
155 | GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_REVOCATION, | ||
156 | &rm->purpose, | ||
157 | &rm->signature, | ||
158 | &rm->public_key)) | ||
159 | { | ||
160 | GNUNET_break_op (0); | ||
161 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
162 | } | ||
163 | GNUNET_CRYPTO_hash (&rm->public_key, | ||
164 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey), | ||
165 | &chash); | ||
166 | if (GNUNET_YES == | ||
167 | GNUNET_BLOCK_GROUP_bf_test_and_set (group, | ||
168 | &chash)) | ||
169 | return GNUNET_BLOCK_EVALUATION_OK_DUPLICATE; | ||
170 | return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; | ||
171 | } | ||
172 | |||
173 | |||
174 | /** | ||
175 | * Function called to obtain the key for a block. | ||
176 | * | ||
177 | * @param cls closure | ||
178 | * @param type block type | ||
179 | * @param block block to get the key for | ||
180 | * @param block_size number of bytes in block | ||
181 | * @param key set to the key (query) for the given block | ||
182 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported | ||
183 | * (or if extracting a key from a block of this type does not work) | ||
184 | */ | ||
185 | static int | ||
186 | block_plugin_revocation_get_key (void *cls, | ||
187 | enum GNUNET_BLOCK_Type type, | ||
188 | const void *block, | ||
189 | size_t block_size, | ||
190 | struct GNUNET_HashCode *key) | ||
191 | { | ||
192 | const struct RevokeMessage *rm = block; | ||
193 | |||
194 | if (block_size != sizeof (*rm)) | ||
195 | { | ||
196 | GNUNET_break_op (0); | ||
197 | return GNUNET_SYSERR; | ||
198 | } | ||
199 | GNUNET_CRYPTO_hash (&rm->public_key, | ||
200 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey), | ||
201 | key); | ||
202 | return GNUNET_OK; | ||
203 | } | ||
204 | |||
205 | |||
206 | /** | ||
207 | * Entry point for the plugin. | ||
208 | * | ||
209 | * @param cls the configuration to use | ||
210 | */ | ||
211 | void * | ||
212 | libgnunet_plugin_block_revocation_init (void *cls) | ||
213 | { | ||
214 | static enum GNUNET_BLOCK_Type types[] = | ||
215 | { | ||
216 | GNUNET_BLOCK_TYPE_REVOCATION, | ||
217 | GNUNET_BLOCK_TYPE_ANY /* end of list */ | ||
218 | }; | ||
219 | const struct GNUNET_CONFIGURATION_Handle *cfg = cls; | ||
220 | struct GNUNET_BLOCK_PluginFunctions *api; | ||
221 | struct InternalContext *ic; | ||
222 | unsigned long long matching_bits; | ||
223 | |||
224 | if (GNUNET_OK != | ||
225 | GNUNET_CONFIGURATION_get_value_number (cfg, | ||
226 | "REVOCATION", | ||
227 | "WORKBITS", | ||
228 | &matching_bits)) | ||
229 | return NULL; | ||
230 | |||
231 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); | ||
232 | api->evaluate = &block_plugin_revocation_evaluate; | ||
233 | api->get_key = &block_plugin_revocation_get_key; | ||
234 | api->create_group = &block_plugin_revocation_create_group; | ||
235 | api->types = types; | ||
236 | ic = GNUNET_new (struct InternalContext); | ||
237 | ic->matching_bits = (unsigned int) matching_bits; | ||
238 | api->cls = ic; | ||
239 | return api; | ||
240 | } | ||
241 | |||
242 | |||
243 | /** | ||
244 | * Exit point from the plugin. | ||
245 | */ | ||
246 | void * | ||
247 | libgnunet_plugin_block_revocation_done (void *cls) | ||
248 | { | ||
249 | struct GNUNET_BLOCK_PluginFunctions *api = cls; | ||
250 | struct InternalContext *ic = api->cls; | ||
251 | |||
252 | GNUNET_free (ic); | ||
253 | GNUNET_free (api); | ||
254 | return NULL; | ||
255 | } | ||
256 | |||
257 | /* end of plugin_block_revocation.c */ | ||
diff --git a/src/revocation/revocation_api.c b/src/revocation/revocation_api.c index fde0296a4..ef659baa0 100644 --- a/src/revocation/revocation_api.c +++ b/src/revocation/revocation_api.c | |||
@@ -91,7 +91,7 @@ handle_revocation_query_response (void *cls, | |||
91 | 91 | ||
92 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 92 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
93 | "Revocation query result: %d\n", | 93 | "Revocation query result: %d\n", |
94 | ntohl (qrm->is_valid)); | 94 | (uint32_t) ntohl (qrm->is_valid)); |
95 | q->func (q->func_cls, | 95 | q->func (q->func_cls, |
96 | ntohl (qrm->is_valid)); | 96 | ntohl (qrm->is_valid)); |
97 | GNUNET_REVOCATION_query_cancel (q); | 97 | GNUNET_REVOCATION_query_cancel (q); |
@@ -225,7 +225,7 @@ handle_revocation_response (void *cls, | |||
225 | 225 | ||
226 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 226 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
227 | "Revocation transmission result: %d\n", | 227 | "Revocation transmission result: %d\n", |
228 | ntohl (rrm->is_valid)); | 228 | (uint32_t) ntohl (rrm->is_valid)); |
229 | h->func (h->func_cls, | 229 | h->func (h->func_cls, |
230 | ntohl (rrm->is_valid)); | 230 | ntohl (rrm->is_valid)); |
231 | GNUNET_REVOCATION_revoke_cancel (h); | 231 | GNUNET_REVOCATION_revoke_cancel (h); |
diff --git a/src/revocation/test_local_revocation.py.in b/src/revocation/test_local_revocation.py.in index 69e68a197..28257715f 100644 --- a/src/revocation/test_local_revocation.py.in +++ b/src/revocation/test_local_revocation.py.in | |||
@@ -42,6 +42,7 @@ TEST_REVOCATION_EGO = "revoc_test" | |||
42 | 42 | ||
43 | get_clean = subprocess.Popen ([config, '-c', TEST_CONFIGURATION, '-s', 'PATHS', '-o', 'GNUNET_HOME', '-f'], stdout=subprocess.PIPE) | 43 | get_clean = subprocess.Popen ([config, '-c', TEST_CONFIGURATION, '-s', 'PATHS', '-o', 'GNUNET_HOME', '-f'], stdout=subprocess.PIPE) |
44 | cleandir, x = get_clean.communicate () | 44 | cleandir, x = get_clean.communicate () |
45 | cleandir = cleandir.decode("utf-8") | ||
45 | cleandir = cleandir.rstrip ('\n').rstrip ('\r') | 46 | cleandir = cleandir.rstrip ('\n').rstrip ('\r') |
46 | 47 | ||
47 | if os.path.isdir (cleandir): | 48 | if os.path.isdir (cleandir): |
@@ -64,6 +65,7 @@ try: | |||
64 | sys.stderr.flush () | 65 | sys.stderr.flush () |
65 | idd = subprocess.Popen ([ident, '-d'], stdout=subprocess.PIPE) | 66 | idd = subprocess.Popen ([ident, '-d'], stdout=subprocess.PIPE) |
66 | rev_key, x = idd.communicate () | 67 | rev_key, x = idd.communicate () |
68 | rev_key = rev_key.decode("utf-8") | ||
67 | if len (rev_key.split ()) < 3: | 69 | if len (rev_key.split ()) < 3: |
68 | raise Exception ("can't get revocation key out of `" + rev_key + "'") | 70 | raise Exception ("can't get revocation key out of `" + rev_key + "'") |
69 | rev_key = rev_key.split ()[2] | 71 | rev_key = rev_key.split ()[2] |
@@ -73,6 +75,7 @@ try: | |||
73 | sys.stderr.flush () | 75 | sys.stderr.flush () |
74 | tst = subprocess.Popen ([revoc, '-t', rev_key, '-c', TEST_CONFIGURATION], stdout=subprocess.PIPE) | 76 | tst = subprocess.Popen ([revoc, '-t', rev_key, '-c', TEST_CONFIGURATION], stdout=subprocess.PIPE) |
75 | output_not_revoked, x = tst.communicate () | 77 | output_not_revoked, x = tst.communicate () |
78 | output_not_revoked = output_not_revoked.decode("utf-8") | ||
76 | if tst.returncode != 0: | 79 | if tst.returncode != 0: |
77 | raise Exception ("gnunet-revocation failed to test a key - " + str (tst.returncode) + ": " + output_not_revoked) | 80 | raise Exception ("gnunet-revocation failed to test a key - " + str (tst.returncode) + ": " + output_not_revoked) |
78 | if 'valid' not in output_not_revoked: | 81 | if 'valid' not in output_not_revoked: |
@@ -94,6 +97,7 @@ try: | |||
94 | sys.stderr.flush () | 97 | sys.stderr.flush () |
95 | tst = subprocess.Popen ([revoc, '-t', rev_key, '-c', TEST_CONFIGURATION], stdout=subprocess.PIPE) | 98 | tst = subprocess.Popen ([revoc, '-t', rev_key, '-c', TEST_CONFIGURATION], stdout=subprocess.PIPE) |
96 | output_revoked, x = tst.communicate () | 99 | output_revoked, x = tst.communicate () |
100 | output_revoked = output_revoked.decode("utf-8") | ||
97 | if tst.returncode != 0: | 101 | if tst.returncode != 0: |
98 | raise Exception ("gnunet-revocation failed to test a revoked key") | 102 | raise Exception ("gnunet-revocation failed to test a revoked key") |
99 | if 'revoked' not in output_revoked: | 103 | if 'revoked' not in output_revoked: |
diff --git a/src/rps/gnunet-service-rps.c b/src/rps/gnunet-service-rps.c index 9de1f8d3a..adcfe7d02 100644 --- a/src/rps/gnunet-service-rps.c +++ b/src/rps/gnunet-service-rps.c | |||
@@ -2241,8 +2241,8 @@ client_connect_cb (void *cls, | |||
2241 | */ | 2241 | */ |
2242 | static void | 2242 | static void |
2243 | client_disconnect_cb (void *cls, | 2243 | client_disconnect_cb (void *cls, |
2244 | struct GNUNET_SERVICE_Client *client, | 2244 | struct GNUNET_SERVICE_Client *client, |
2245 | void *internal_cls) | 2245 | void *internal_cls) |
2246 | { | 2246 | { |
2247 | struct ClientContext *cli_ctx = internal_cls; | 2247 | struct ClientContext *cli_ctx = internal_cls; |
2248 | 2248 | ||
diff --git a/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c b/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c index 9f8d98657..ca92fb9ea 100644 --- a/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c +++ b/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c | |||
@@ -687,11 +687,13 @@ send_alices_cryptodata_message (struct AliceServiceSession *s) | |||
687 | * | 687 | * |
688 | * @param cls closure with the `struct AliceServiceSession` | 688 | * @param cls closure with the `struct AliceServiceSession` |
689 | * @param element a result element, only valid if status is #GNUNET_SET_STATUS_OK | 689 | * @param element a result element, only valid if status is #GNUNET_SET_STATUS_OK |
690 | * @param current_size current set size | ||
690 | * @param status what has happened with the set intersection? | 691 | * @param status what has happened with the set intersection? |
691 | */ | 692 | */ |
692 | static void | 693 | static void |
693 | cb_intersection_element_removed (void *cls, | 694 | cb_intersection_element_removed (void *cls, |
694 | const struct GNUNET_SET_Element *element, | 695 | const struct GNUNET_SET_Element *element, |
696 | uint64_t current_size, | ||
695 | enum GNUNET_SET_Status status) | 697 | enum GNUNET_SET_Status status) |
696 | { | 698 | { |
697 | struct AliceServiceSession *s = cls; | 699 | struct AliceServiceSession *s = cls; |
@@ -788,6 +790,7 @@ cb_intersection_request_alice (void *cls, | |||
788 | s->intersection_op | 790 | s->intersection_op |
789 | = GNUNET_SET_accept (request, | 791 | = GNUNET_SET_accept (request, |
790 | GNUNET_SET_RESULT_REMOVED, | 792 | GNUNET_SET_RESULT_REMOVED, |
793 | (struct GNUNET_SET_Option[]) {{ 0 }}, | ||
791 | &cb_intersection_element_removed, | 794 | &cb_intersection_element_removed, |
792 | s); | 795 | s); |
793 | if (NULL == s->intersection_op) | 796 | if (NULL == s->intersection_op) |
diff --git a/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c b/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c index 7fd69a4ea..3851ca763 100644 --- a/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c +++ b/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c | |||
@@ -580,11 +580,13 @@ handle_alices_cryptodata_message (void *cls, | |||
580 | * | 580 | * |
581 | * @param cls closure with the `struct BobServiceSession` | 581 | * @param cls closure with the `struct BobServiceSession` |
582 | * @param element a result element, only valid if status is #GNUNET_SET_STATUS_OK | 582 | * @param element a result element, only valid if status is #GNUNET_SET_STATUS_OK |
583 | * @param current_size current set size | ||
583 | * @param status what has happened with the set intersection? | 584 | * @param status what has happened with the set intersection? |
584 | */ | 585 | */ |
585 | static void | 586 | static void |
586 | cb_intersection_element_removed (void *cls, | 587 | cb_intersection_element_removed (void *cls, |
587 | const struct GNUNET_SET_Element *element, | 588 | const struct GNUNET_SET_Element *element, |
589 | uint64_t current_size, | ||
588 | enum GNUNET_SET_Status status) | 590 | enum GNUNET_SET_Status status) |
589 | { | 591 | { |
590 | struct BobServiceSession *s = cls; | 592 | struct BobServiceSession *s = cls; |
@@ -670,6 +672,7 @@ start_intersection (struct BobServiceSession *s) | |||
670 | &set_sid, | 672 | &set_sid, |
671 | NULL, | 673 | NULL, |
672 | GNUNET_SET_RESULT_REMOVED, | 674 | GNUNET_SET_RESULT_REMOVED, |
675 | (struct GNUNET_SET_Option[]) {{ 0 }}, | ||
673 | &cb_intersection_element_removed, | 676 | &cb_intersection_element_removed, |
674 | s); | 677 | s); |
675 | if (GNUNET_OK != | 678 | if (GNUNET_OK != |
diff --git a/src/scalarproduct/gnunet-service-scalarproduct_alice.c b/src/scalarproduct/gnunet-service-scalarproduct_alice.c index 779d84b60..6d7a0a3b8 100644 --- a/src/scalarproduct/gnunet-service-scalarproduct_alice.c +++ b/src/scalarproduct/gnunet-service-scalarproduct_alice.c | |||
@@ -924,11 +924,13 @@ send_alices_cryptodata_message (struct AliceServiceSession *s) | |||
924 | * | 924 | * |
925 | * @param cls closure with the `struct AliceServiceSession` | 925 | * @param cls closure with the `struct AliceServiceSession` |
926 | * @param element a result element, only valid if status is #GNUNET_SET_STATUS_OK | 926 | * @param element a result element, only valid if status is #GNUNET_SET_STATUS_OK |
927 | * @param current_size current set size | ||
927 | * @param status what has happened with the set intersection? | 928 | * @param status what has happened with the set intersection? |
928 | */ | 929 | */ |
929 | static void | 930 | static void |
930 | cb_intersection_element_removed (void *cls, | 931 | cb_intersection_element_removed (void *cls, |
931 | const struct GNUNET_SET_Element *element, | 932 | const struct GNUNET_SET_Element *element, |
933 | uint64_t current_size, | ||
932 | enum GNUNET_SET_Status status) | 934 | enum GNUNET_SET_Status status) |
933 | { | 935 | { |
934 | struct AliceServiceSession *s = cls; | 936 | struct AliceServiceSession *s = cls; |
@@ -1022,6 +1024,7 @@ cb_intersection_request_alice (void *cls, | |||
1022 | s->intersection_op | 1024 | s->intersection_op |
1023 | = GNUNET_SET_accept (request, | 1025 | = GNUNET_SET_accept (request, |
1024 | GNUNET_SET_RESULT_REMOVED, | 1026 | GNUNET_SET_RESULT_REMOVED, |
1027 | (struct GNUNET_SET_Option[]) {{ 0 }}, | ||
1025 | &cb_intersection_element_removed, | 1028 | &cb_intersection_element_removed, |
1026 | s); | 1029 | s); |
1027 | if (NULL == s->intersection_op) | 1030 | if (NULL == s->intersection_op) |
diff --git a/src/scalarproduct/gnunet-service-scalarproduct_bob.c b/src/scalarproduct/gnunet-service-scalarproduct_bob.c index a2bceba43..f3b5327f1 100644 --- a/src/scalarproduct/gnunet-service-scalarproduct_bob.c +++ b/src/scalarproduct/gnunet-service-scalarproduct_bob.c | |||
@@ -879,11 +879,13 @@ handle_alices_cryptodata_message (void *cls, | |||
879 | * | 879 | * |
880 | * @param cls closure with the `struct BobServiceSession` | 880 | * @param cls closure with the `struct BobServiceSession` |
881 | * @param element a result element, only valid if status is #GNUNET_SET_STATUS_OK | 881 | * @param element a result element, only valid if status is #GNUNET_SET_STATUS_OK |
882 | * @param current_size current set size | ||
882 | * @param status what has happened with the set intersection? | 883 | * @param status what has happened with the set intersection? |
883 | */ | 884 | */ |
884 | static void | 885 | static void |
885 | cb_intersection_element_removed (void *cls, | 886 | cb_intersection_element_removed (void *cls, |
886 | const struct GNUNET_SET_Element *element, | 887 | const struct GNUNET_SET_Element *element, |
888 | uint64_t current_size, | ||
887 | enum GNUNET_SET_Status status) | 889 | enum GNUNET_SET_Status status) |
888 | { | 890 | { |
889 | struct BobServiceSession *s = cls; | 891 | struct BobServiceSession *s = cls; |
@@ -964,6 +966,7 @@ start_intersection (struct BobServiceSession *s) | |||
964 | &s->session_id, | 966 | &s->session_id, |
965 | NULL, | 967 | NULL, |
966 | GNUNET_SET_RESULT_REMOVED, | 968 | GNUNET_SET_RESULT_REMOVED, |
969 | (struct GNUNET_SET_Option[]) {{ 0 }}, | ||
967 | &cb_intersection_element_removed, | 970 | &cb_intersection_element_removed, |
968 | s); | 971 | s); |
969 | if (GNUNET_OK != | 972 | if (GNUNET_OK != |
@@ -1172,11 +1175,11 @@ handle_bob_client_message (void *cls, | |||
1172 | GNUNET_MQ_hd_fixed_size (alices_computation_request, | 1175 | GNUNET_MQ_hd_fixed_size (alices_computation_request, |
1173 | GNUNET_MESSAGE_TYPE_SCALARPRODUCT_SESSION_INITIALIZATION, | 1176 | GNUNET_MESSAGE_TYPE_SCALARPRODUCT_SESSION_INITIALIZATION, |
1174 | struct ServiceRequestMessage, | 1177 | struct ServiceRequestMessage, |
1175 | s), | 1178 | NULL), |
1176 | GNUNET_MQ_hd_var_size (alices_cryptodata_message, | 1179 | GNUNET_MQ_hd_var_size (alices_cryptodata_message, |
1177 | GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ALICE_CRYPTODATA, | 1180 | GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ALICE_CRYPTODATA, |
1178 | struct AliceCryptodataMessage, | 1181 | struct AliceCryptodataMessage, |
1179 | s), | 1182 | NULL), |
1180 | GNUNET_MQ_handler_end () | 1183 | GNUNET_MQ_handler_end () |
1181 | }; | 1184 | }; |
1182 | uint32_t contained_count; | 1185 | uint32_t contained_count; |
diff --git a/src/secretsharing/.gitignore b/src/secretsharing/.gitignore index bb169f0c4..fe9db53a4 100644 --- a/src/secretsharing/.gitignore +++ b/src/secretsharing/.gitignore | |||
@@ -1,2 +1,3 @@ | |||
1 | gnunet-service-secretsharing | 1 | gnunet-service-secretsharing |
2 | gnunet-secretsharing-profiler | 2 | gnunet-secretsharing-profiler |
3 | test_secretsharing_api | ||
diff --git a/src/secretsharing/Makefile.am b/src/secretsharing/Makefile.am index 562688dd9..485183e36 100644 --- a/src/secretsharing/Makefile.am +++ b/src/secretsharing/Makefile.am | |||
@@ -56,6 +56,7 @@ libgnunetsecretsharing_la_LIBADD = \ | |||
56 | libgnunetsecretsharing_la_LDFLAGS = \ | 56 | libgnunetsecretsharing_la_LDFLAGS = \ |
57 | $(GN_LIB_LDFLAGS) | 57 | $(GN_LIB_LDFLAGS) |
58 | 58 | ||
59 | if HAVE_TESTING | ||
59 | check_PROGRAMS = \ | 60 | check_PROGRAMS = \ |
60 | test_secretsharing_api | 61 | test_secretsharing_api |
61 | 62 | ||
@@ -63,6 +64,7 @@ if ENABLE_TEST_RUN | |||
63 | AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; | 64 | AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; |
64 | TESTS = $(check_PROGRAMS) | 65 | TESTS = $(check_PROGRAMS) |
65 | endif | 66 | endif |
67 | endif | ||
66 | 68 | ||
67 | test_secretsharing_api_SOURCES = \ | 69 | test_secretsharing_api_SOURCES = \ |
68 | test_secretsharing_api.c | 70 | test_secretsharing_api.c |
@@ -73,4 +75,3 @@ test_secretsharing_api_LDADD = \ | |||
73 | 75 | ||
74 | EXTRA_DIST = \ | 76 | EXTRA_DIST = \ |
75 | test_secretsharing.conf | 77 | test_secretsharing.conf |
76 | |||
diff --git a/src/set/Makefile.am b/src/set/Makefile.am index 10f7ddc5d..cfe95bc1a 100644 --- a/src/set/Makefile.am +++ b/src/set/Makefile.am | |||
@@ -5,6 +5,8 @@ pkgcfgdir= $(pkgdatadir)/config.d/ | |||
5 | 5 | ||
6 | libexecdir= $(pkglibdir)/libexec/ | 6 | libexecdir= $(pkglibdir)/libexec/ |
7 | 7 | ||
8 | plugindir = $(libdir)/gnunet | ||
9 | |||
8 | pkgcfg_DATA = \ | 10 | pkgcfg_DATA = \ |
9 | set.conf | 11 | set.conf |
10 | 12 | ||
@@ -112,5 +114,19 @@ test_set_union_copy_LDADD = \ | |||
112 | $(top_builddir)/src/testing/libgnunettesting.la \ | 114 | $(top_builddir)/src/testing/libgnunettesting.la \ |
113 | libgnunetset.la | 115 | libgnunetset.la |
114 | 116 | ||
117 | plugin_LTLIBRARIES = \ | ||
118 | libgnunet_plugin_block_set_test.la | ||
119 | |||
120 | libgnunet_plugin_block_set_test_la_SOURCES = \ | ||
121 | plugin_block_set_test.c | ||
122 | libgnunet_plugin_block_set_test_la_LIBADD = \ | ||
123 | $(top_builddir)/src/block/libgnunetblock.la \ | ||
124 | $(top_builddir)/src/block/libgnunetblockgroup.la \ | ||
125 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
126 | $(LTLIBINTL) | ||
127 | libgnunet_plugin_block_set_test_la_LDFLAGS = \ | ||
128 | $(GN_PLUGIN_LDFLAGS) | ||
129 | |||
130 | |||
115 | EXTRA_DIST = \ | 131 | EXTRA_DIST = \ |
116 | test_set.conf | 132 | test_set.conf |
diff --git a/src/set/gnunet-service-set.c b/src/set/gnunet-service-set.c index a545e8a06..b0f8b2091 100644 --- a/src/set/gnunet-service-set.c +++ b/src/set/gnunet-service-set.c | |||
@@ -223,6 +223,9 @@ listener_destroy (struct Listener *listener) | |||
223 | { | 223 | { |
224 | struct GNUNET_SERVICE_Client *client = listener->client; | 224 | struct GNUNET_SERVICE_Client *client = listener->client; |
225 | 225 | ||
226 | GNUNET_MQ_destroy (listener->client_mq); | ||
227 | listener->client_mq = NULL; | ||
228 | |||
226 | listener->client = NULL; | 229 | listener->client = NULL; |
227 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 230 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
228 | "Disconnecting listener client\n"); | 231 | "Disconnecting listener client\n"); |
@@ -611,42 +614,6 @@ client_connect_cb (void *cls, | |||
611 | 614 | ||
612 | 615 | ||
613 | /** | 616 | /** |
614 | * Clean up after a client has disconnected | ||
615 | * | ||
616 | * @param cls closure, unused | ||
617 | * @param client the client to clean up after | ||
618 | * @param internal_cls our client-specific internal data structure | ||
619 | */ | ||
620 | static void | ||
621 | client_disconnect_cb (void *cls, | ||
622 | struct GNUNET_SERVICE_Client *client, | ||
623 | void *internal_cls) | ||
624 | { | ||
625 | struct Listener *listener; | ||
626 | struct Set *set; | ||
627 | |||
628 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
629 | "client disconnected, cleaning up\n"); | ||
630 | set = set_get (client); | ||
631 | if (NULL != set) | ||
632 | { | ||
633 | set->client = NULL; | ||
634 | set_destroy (set); | ||
635 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
636 | "Client's set destroyed\n"); | ||
637 | } | ||
638 | listener = listener_get (client); | ||
639 | if (NULL != listener) | ||
640 | { | ||
641 | listener->client = NULL; | ||
642 | listener_destroy (listener); | ||
643 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
644 | "Client's listener destroyed\n"); | ||
645 | } | ||
646 | } | ||
647 | |||
648 | |||
649 | /** | ||
650 | * Destroy an incoming request from a remote peer | 617 | * Destroy an incoming request from a remote peer |
651 | * | 618 | * |
652 | * @param incoming remote request to destroy | 619 | * @param incoming remote request to destroy |
@@ -681,6 +648,52 @@ incoming_destroy (struct Operation *incoming) | |||
681 | 648 | ||
682 | 649 | ||
683 | /** | 650 | /** |
651 | * Clean up after a client has disconnected | ||
652 | * | ||
653 | * @param cls closure, unused | ||
654 | * @param client the client to clean up after | ||
655 | * @param internal_cls our client-specific internal data structure | ||
656 | */ | ||
657 | static void | ||
658 | client_disconnect_cb (void *cls, | ||
659 | struct GNUNET_SERVICE_Client *client, | ||
660 | void *internal_cls) | ||
661 | { | ||
662 | struct Set *set; | ||
663 | |||
664 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
665 | "client disconnected, cleaning up\n"); | ||
666 | set = set_get (client); | ||
667 | if (NULL != set) | ||
668 | { | ||
669 | set->client = NULL; | ||
670 | set_destroy (set); | ||
671 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
672 | "Client's set destroyed\n"); | ||
673 | } | ||
674 | struct Listener *listener = listener_get (client); | ||
675 | struct Operation *op = incoming_head; | ||
676 | if (NULL != listener) | ||
677 | { | ||
678 | /* destroy all incoming operations whose client just | ||
679 | * got destroyed */ | ||
680 | while (NULL != op) | ||
681 | { | ||
682 | struct Operation *curr = op; | ||
683 | op = op->next; | ||
684 | if ( (GNUNET_YES == curr->is_incoming) && | ||
685 | (curr->listener == listener) ) | ||
686 | incoming_destroy (curr); | ||
687 | } | ||
688 | listener->client = NULL; | ||
689 | listener_destroy (listener); | ||
690 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
691 | "Client's listener destroyed\n"); | ||
692 | } | ||
693 | } | ||
694 | |||
695 | |||
696 | /** | ||
684 | * Suggest the given request to the listener. The listening client can | 697 | * Suggest the given request to the listener. The listening client can |
685 | * then accept or reject the remote request. | 698 | * then accept or reject the remote request. |
686 | * | 699 | * |
@@ -781,7 +794,7 @@ handle_incoming_msg (struct Operation *op, | |||
781 | listener = op->listener; | 794 | listener = op->listener; |
782 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 795 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
783 | "Received P2P operation request (op %u, port %s) for active listener\n", | 796 | "Received P2P operation request (op %u, port %s) for active listener\n", |
784 | ntohl (msg->operation), | 797 | (uint32_t) ntohl (msg->operation), |
785 | GNUNET_h2s (&listener->app_id)); | 798 | GNUNET_h2s (&listener->app_id)); |
786 | incoming_suggest (op, | 799 | incoming_suggest (op, |
787 | listener); | 800 | listener); |
@@ -1075,7 +1088,7 @@ handle_client_create_set (void *cls, | |||
1075 | 1088 | ||
1076 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1089 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1077 | "Client created new set (operation %u)\n", | 1090 | "Client created new set (operation %u)\n", |
1078 | ntohl (msg->operation)); | 1091 | (uint32_t) ntohl (msg->operation)); |
1079 | if (NULL != set_get (client)) | 1092 | if (NULL != set_get (client)) |
1080 | { | 1093 | { |
1081 | /* There can only be one set per client */ | 1094 | /* There can only be one set per client */ |
@@ -1371,6 +1384,14 @@ handle_client_listen (void *cls, | |||
1371 | struct GNUNET_MessageHeader, | 1384 | struct GNUNET_MessageHeader, |
1372 | NULL), | 1385 | NULL), |
1373 | GNUNET_MQ_hd_var_size (p2p_message, | 1386 | GNUNET_MQ_hd_var_size (p2p_message, |
1387 | GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_DONE, | ||
1388 | struct GNUNET_MessageHeader, | ||
1389 | NULL), | ||
1390 | GNUNET_MQ_hd_var_size (p2p_message, | ||
1391 | GNUNET_MESSAGE_TYPE_SET_UNION_P2P_REQUEST_FULL, | ||
1392 | struct GNUNET_MessageHeader, | ||
1393 | NULL), | ||
1394 | GNUNET_MQ_hd_var_size (p2p_message, | ||
1374 | GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE, | 1395 | GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE, |
1375 | struct GNUNET_MessageHeader, | 1396 | struct GNUNET_MessageHeader, |
1376 | NULL), | 1397 | NULL), |
@@ -1379,6 +1400,10 @@ handle_client_listen (void *cls, | |||
1379 | struct GNUNET_MessageHeader, | 1400 | struct GNUNET_MessageHeader, |
1380 | NULL), | 1401 | NULL), |
1381 | GNUNET_MQ_hd_var_size (p2p_message, | 1402 | GNUNET_MQ_hd_var_size (p2p_message, |
1403 | GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_ELEMENT, | ||
1404 | struct GNUNET_MessageHeader, | ||
1405 | NULL), | ||
1406 | GNUNET_MQ_hd_var_size (p2p_message, | ||
1382 | GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO, | 1407 | GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO, |
1383 | struct GNUNET_MessageHeader, | 1408 | struct GNUNET_MessageHeader, |
1384 | NULL), | 1409 | NULL), |
@@ -1393,7 +1418,6 @@ handle_client_listen (void *cls, | |||
1393 | GNUNET_MQ_handler_end () | 1418 | GNUNET_MQ_handler_end () |
1394 | }; | 1419 | }; |
1395 | struct Listener *listener; | 1420 | struct Listener *listener; |
1396 | struct Operation *op; | ||
1397 | 1421 | ||
1398 | if (NULL != listener_get (client)) | 1422 | if (NULL != listener_get (client)) |
1399 | { | 1423 | { |
@@ -1422,7 +1446,7 @@ handle_client_listen (void *cls, | |||
1422 | &channel_end_cb, | 1446 | &channel_end_cb, |
1423 | cadet_handlers); | 1447 | cadet_handlers); |
1424 | /* check for existing incoming requests the listener might be interested in */ | 1448 | /* check for existing incoming requests the listener might be interested in */ |
1425 | for (op = incoming_head; NULL != op; op = op->next) | 1449 | for (struct Operation *op = incoming_head; NULL != op; op = op->next) |
1426 | { | 1450 | { |
1427 | if (NULL == op->spec) | 1451 | if (NULL == op->spec) |
1428 | continue; /* no details available yet */ | 1452 | continue; /* no details available yet */ |
@@ -1634,6 +1658,18 @@ handle_client_evaluate (void *cls, | |||
1634 | struct GNUNET_MessageHeader, | 1658 | struct GNUNET_MessageHeader, |
1635 | op), | 1659 | op), |
1636 | GNUNET_MQ_hd_var_size (p2p_message, | 1660 | GNUNET_MQ_hd_var_size (p2p_message, |
1661 | GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_DONE, | ||
1662 | struct GNUNET_MessageHeader, | ||
1663 | op), | ||
1664 | GNUNET_MQ_hd_var_size (p2p_message, | ||
1665 | GNUNET_MESSAGE_TYPE_SET_UNION_P2P_REQUEST_FULL, | ||
1666 | struct GNUNET_MessageHeader, | ||
1667 | op), | ||
1668 | GNUNET_MQ_hd_var_size (p2p_message, | ||
1669 | GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_ELEMENT, | ||
1670 | struct GNUNET_MessageHeader, | ||
1671 | op), | ||
1672 | GNUNET_MQ_hd_var_size (p2p_message, | ||
1637 | GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO, | 1673 | GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO, |
1638 | struct GNUNET_MessageHeader, | 1674 | struct GNUNET_MessageHeader, |
1639 | op), | 1675 | op), |
@@ -1668,6 +1704,10 @@ handle_client_evaluate (void *cls, | |||
1668 | spec->set = set; | 1704 | spec->set = set; |
1669 | spec->result_mode = ntohl (msg->result_mode); | 1705 | spec->result_mode = ntohl (msg->result_mode); |
1670 | spec->client_request_id = ntohl (msg->request_id); | 1706 | spec->client_request_id = ntohl (msg->request_id); |
1707 | spec->byzantine = msg->byzantine; | ||
1708 | spec->byzantine_lower_bound = msg->byzantine_lower_bound; | ||
1709 | spec->force_full = msg->force_full; | ||
1710 | spec->force_delta = msg->force_delta; | ||
1671 | context = GNUNET_MQ_extract_nested_mh (msg); | 1711 | context = GNUNET_MQ_extract_nested_mh (msg); |
1672 | op->spec = spec; | 1712 | op->spec = spec; |
1673 | 1713 | ||
@@ -1918,7 +1958,7 @@ handle_client_cancel (void *cls, | |||
1918 | } | 1958 | } |
1919 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1959 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1920 | "Client requested cancel for op %u\n", | 1960 | "Client requested cancel for op %u\n", |
1921 | ntohl (msg->request_id)); | 1961 | (uint32_t) ntohl (msg->request_id)); |
1922 | found = GNUNET_NO; | 1962 | found = GNUNET_NO; |
1923 | for (op = set->ops_head; NULL != op; op = op->next) | 1963 | for (op = set->ops_head; NULL != op; op = op->next) |
1924 | { | 1964 | { |
@@ -1992,7 +2032,7 @@ handle_client_accept (void *cls, | |||
1992 | 2032 | ||
1993 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2033 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1994 | "Client accepting request %u\n", | 2034 | "Client accepting request %u\n", |
1995 | ntohl (msg->accept_reject_id)); | 2035 | (uint32_t) ntohl (msg->accept_reject_id)); |
1996 | GNUNET_assert (GNUNET_YES == op->is_incoming); | 2036 | GNUNET_assert (GNUNET_YES == op->is_incoming); |
1997 | op->is_incoming = GNUNET_NO; | 2037 | op->is_incoming = GNUNET_NO; |
1998 | GNUNET_CONTAINER_DLL_remove (incoming_head, | 2038 | GNUNET_CONTAINER_DLL_remove (incoming_head, |
@@ -2004,6 +2044,10 @@ handle_client_accept (void *cls, | |||
2004 | op); | 2044 | op); |
2005 | op->spec->client_request_id = ntohl (msg->request_id); | 2045 | op->spec->client_request_id = ntohl (msg->request_id); |
2006 | op->spec->result_mode = ntohl (msg->result_mode); | 2046 | op->spec->result_mode = ntohl (msg->result_mode); |
2047 | op->spec->byzantine = msg->byzantine; | ||
2048 | op->spec->byzantine_lower_bound = msg->byzantine_lower_bound; | ||
2049 | op->spec->force_full = msg->force_full; | ||
2050 | op->spec->force_delta = msg->force_delta; | ||
2007 | 2051 | ||
2008 | // Advance generation values, so that | 2052 | // Advance generation values, so that |
2009 | // mutations won't interfer with the running operation. | 2053 | // mutations won't interfer with the running operation. |
diff --git a/src/set/gnunet-service-set.h b/src/set/gnunet-service-set.h index 1460707fa..68d8fe81f 100644 --- a/src/set/gnunet-service-set.h +++ b/src/set/gnunet-service-set.h | |||
@@ -119,6 +119,30 @@ struct OperationSpecification | |||
119 | * When are elements sent to the client, and which elements are sent? | 119 | * When are elements sent to the client, and which elements are sent? |
120 | */ | 120 | */ |
121 | enum GNUNET_SET_ResultMode result_mode; | 121 | enum GNUNET_SET_ResultMode result_mode; |
122 | |||
123 | /** | ||
124 | * Always use delta operation instead of sending full sets, | ||
125 | * even it it's less efficient. | ||
126 | */ | ||
127 | int force_delta; | ||
128 | |||
129 | /** | ||
130 | * Always send full sets, even if delta operations would | ||
131 | * be more efficient. | ||
132 | */ | ||
133 | int force_full; | ||
134 | |||
135 | /** | ||
136 | * #GNUNET_YES to fail operations where Byzantine faults | ||
137 | * are suspected | ||
138 | */ | ||
139 | int byzantine; | ||
140 | |||
141 | /** | ||
142 | * Lower bound for the set size, used only when | ||
143 | * byzantine mode is enabled. | ||
144 | */ | ||
145 | int byzantine_lower_bound; | ||
122 | }; | 146 | }; |
123 | 147 | ||
124 | 148 | ||
diff --git a/src/set/gnunet-service-set_protocol.h b/src/set/gnunet-service-set_protocol.h index 748da15fc..0138b21c7 100644 --- a/src/set/gnunet-service-set_protocol.h +++ b/src/set/gnunet-service-set_protocol.h | |||
@@ -208,6 +208,20 @@ struct IntersectionDoneMessage | |||
208 | struct GNUNET_HashCode element_xor_hash; | 208 | struct GNUNET_HashCode element_xor_hash; |
209 | }; | 209 | }; |
210 | 210 | ||
211 | |||
212 | /** | ||
213 | * Strata estimator together with the peer's overall set size. | ||
214 | */ | ||
215 | struct StrataEstimatorMessage | ||
216 | { | ||
217 | /** | ||
218 | * Type: #GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE(C) | ||
219 | */ | ||
220 | struct GNUNET_MessageHeader header; | ||
221 | |||
222 | uint64_t set_size; | ||
223 | }; | ||
224 | |||
211 | GNUNET_NETWORK_STRUCT_END | 225 | GNUNET_NETWORK_STRUCT_END |
212 | 226 | ||
213 | #endif | 227 | #endif |
diff --git a/src/set/gnunet-service-set_union.c b/src/set/gnunet-service-set_union.c index acaabd94a..f46713c31 100644 --- a/src/set/gnunet-service-set_union.c +++ b/src/set/gnunet-service-set_union.c | |||
@@ -85,6 +85,7 @@ enum UnionOperationPhase | |||
85 | * upon initialization and later via #PHASE_EXPECT_ELEMENTS_AND_REQUESTS. | 85 | * upon initialization and later via #PHASE_EXPECT_ELEMENTS_AND_REQUESTS. |
86 | * | 86 | * |
87 | * XXX: could use better wording. | 87 | * XXX: could use better wording. |
88 | * XXX: repurposed to also expect a "request full set" message, should be renamed | ||
88 | * | 89 | * |
89 | * After receiving the complete IBF, we enter #PHASE_EXPECT_ELEMENTS | 90 | * After receiving the complete IBF, we enter #PHASE_EXPECT_ELEMENTS |
90 | */ | 91 | */ |
@@ -115,14 +116,22 @@ enum UnionOperationPhase | |||
115 | * In the penultimate phase, | 116 | * In the penultimate phase, |
116 | * we wait until all our demands | 117 | * we wait until all our demands |
117 | * are satisfied. Then we send a done | 118 | * are satisfied. Then we send a done |
118 | * message, and wait for another done message.*/ | 119 | * message, and wait for another done message. |
120 | */ | ||
119 | PHASE_FINISH_WAITING, | 121 | PHASE_FINISH_WAITING, |
120 | 122 | ||
121 | /** | 123 | /** |
122 | * In the ultimate phase, we wait until | 124 | * In the ultimate phase, we wait until |
123 | * our demands are satisfied and then | 125 | * our demands are satisfied and then |
124 | * quit (sending another DONE message). */ | 126 | * quit (sending another DONE message). |
125 | PHASE_DONE | 127 | */ |
128 | PHASE_DONE, | ||
129 | |||
130 | /** | ||
131 | * After sending the full set, wait for responses with the elements | ||
132 | * that the local peer is missing. | ||
133 | */ | ||
134 | PHASE_FULL_SENDING, | ||
126 | }; | 135 | }; |
127 | 136 | ||
128 | 137 | ||
@@ -148,7 +157,7 @@ struct OperationState | |||
148 | struct InvertibleBloomFilter *local_ibf; | 157 | struct InvertibleBloomFilter *local_ibf; |
149 | 158 | ||
150 | /** | 159 | /** |
151 | * Maps IBF-Keys (specific to the current salt) to elements. | 160 | * Maps unsalted IBF-Keys to elements. |
152 | * Used as a multihashmap, the keys being the lower 32bit of the IBF-Key. | 161 | * Used as a multihashmap, the keys being the lower 32bit of the IBF-Key. |
153 | * Colliding IBF-Keys are linked. | 162 | * Colliding IBF-Keys are linked. |
154 | */ | 163 | */ |
@@ -183,6 +192,23 @@ struct OperationState | |||
183 | * Salt for the IBF we've received and that we're currently decoding. | 192 | * Salt for the IBF we've received and that we're currently decoding. |
184 | */ | 193 | */ |
185 | uint32_t salt_receive; | 194 | uint32_t salt_receive; |
195 | |||
196 | /** | ||
197 | * Number of elements we received from the other peer | ||
198 | * that were not in the local set yet. | ||
199 | */ | ||
200 | uint32_t received_fresh; | ||
201 | |||
202 | /** | ||
203 | * Total number of elements received from the other peer. | ||
204 | */ | ||
205 | uint32_t received_total; | ||
206 | |||
207 | /** | ||
208 | * Initial size of our set, just before | ||
209 | * the operation started. | ||
210 | */ | ||
211 | uint64_t initial_size; | ||
186 | }; | 212 | }; |
187 | 213 | ||
188 | 214 | ||
@@ -203,6 +229,14 @@ struct KeyEntry | |||
203 | * is #GNUNET_YES. | 229 | * is #GNUNET_YES. |
204 | */ | 230 | */ |
205 | struct ElementEntry *element; | 231 | struct ElementEntry *element; |
232 | |||
233 | /** | ||
234 | * Did we receive this element? | ||
235 | * Even if element->is_foreign is false, we might | ||
236 | * have received the element, so this indicates that | ||
237 | * the other peer has it. | ||
238 | */ | ||
239 | int received; | ||
206 | }; | 240 | }; |
207 | 241 | ||
208 | 242 | ||
@@ -362,6 +396,16 @@ get_ibf_key (const struct GNUNET_HashCode *src) | |||
362 | 396 | ||
363 | 397 | ||
364 | /** | 398 | /** |
399 | * Context for #op_get_element_iterator | ||
400 | */ | ||
401 | struct GetElementContext | ||
402 | { | ||
403 | struct GNUNET_HashCode hash; | ||
404 | struct KeyEntry *k; | ||
405 | }; | ||
406 | |||
407 | |||
408 | /** | ||
365 | * Iterator over the mapping from IBF keys to element entries. Checks if we | 409 | * Iterator over the mapping from IBF keys to element entries. Checks if we |
366 | * have an element with a given GNUNET_HashCode. | 410 | * have an element with a given GNUNET_HashCode. |
367 | * | 411 | * |
@@ -372,17 +416,20 @@ get_ibf_key (const struct GNUNET_HashCode *src) | |||
372 | * #GNUNET_NO if we've found the element. | 416 | * #GNUNET_NO if we've found the element. |
373 | */ | 417 | */ |
374 | static int | 418 | static int |
375 | op_has_element_iterator (void *cls, | 419 | op_get_element_iterator (void *cls, |
376 | uint32_t key, | 420 | uint32_t key, |
377 | void *value) | 421 | void *value) |
378 | { | 422 | { |
379 | struct GNUNET_HashCode *element_hash = cls; | 423 | struct GetElementContext *ctx = cls; |
380 | struct KeyEntry *k = value; | 424 | struct KeyEntry *k = value; |
381 | 425 | ||
382 | GNUNET_assert (NULL != k); | 426 | GNUNET_assert (NULL != k); |
383 | if (0 == GNUNET_CRYPTO_hash_cmp (&k->element->element_hash, | 427 | if (0 == GNUNET_CRYPTO_hash_cmp (&k->element->element_hash, |
384 | element_hash)) | 428 | &ctx->hash)) |
429 | { | ||
430 | ctx->k = k; | ||
385 | return GNUNET_NO; | 431 | return GNUNET_NO; |
432 | } | ||
386 | return GNUNET_YES; | 433 | return GNUNET_YES; |
387 | } | 434 | } |
388 | 435 | ||
@@ -395,23 +442,29 @@ op_has_element_iterator (void *cls, | |||
395 | * @param element_hash hash of the element to look for | 442 | * @param element_hash hash of the element to look for |
396 | * @return #GNUNET_YES if the element has been found, #GNUNET_NO otherwise | 443 | * @return #GNUNET_YES if the element has been found, #GNUNET_NO otherwise |
397 | */ | 444 | */ |
398 | static int | 445 | static struct KeyEntry * |
399 | op_has_element (struct Operation *op, | 446 | op_get_element (struct Operation *op, |
400 | const struct GNUNET_HashCode *element_hash) | 447 | const struct GNUNET_HashCode *element_hash) |
401 | { | 448 | { |
402 | int ret; | 449 | int ret; |
403 | struct IBF_Key ibf_key; | 450 | struct IBF_Key ibf_key; |
451 | struct GetElementContext ctx = {{{ 0 }} , 0}; | ||
452 | |||
453 | ctx.hash = *element_hash; | ||
404 | 454 | ||
405 | ibf_key = get_ibf_key (element_hash); | 455 | ibf_key = get_ibf_key (element_hash); |
406 | ret = GNUNET_CONTAINER_multihashmap32_get_multiple (op->state->key_to_element, | 456 | ret = GNUNET_CONTAINER_multihashmap32_get_multiple (op->state->key_to_element, |
407 | (uint32_t) ibf_key.key_val, | 457 | (uint32_t) ibf_key.key_val, |
408 | op_has_element_iterator, | 458 | op_get_element_iterator, |
409 | (void *) element_hash); | 459 | &ctx); |
410 | 460 | ||
411 | /* was the iteration aborted because we found the element? */ | 461 | /* was the iteration aborted because we found the element? */ |
412 | if (GNUNET_SYSERR == ret) | 462 | if (GNUNET_SYSERR == ret) |
413 | return GNUNET_YES; | 463 | { |
414 | return GNUNET_NO; | 464 | GNUNET_assert (NULL != ctx.k); |
465 | return ctx.k; | ||
466 | } | ||
467 | return NULL; | ||
415 | } | 468 | } |
416 | 469 | ||
417 | 470 | ||
@@ -427,10 +480,12 @@ op_has_element (struct Operation *op, | |||
427 | * | 480 | * |
428 | * @param op the union operation | 481 | * @param op the union operation |
429 | * @param ee the element entry | 482 | * @param ee the element entry |
483 | * @parem received was this element received from the remote peer? | ||
430 | */ | 484 | */ |
431 | static void | 485 | static void |
432 | op_register_element (struct Operation *op, | 486 | op_register_element (struct Operation *op, |
433 | struct ElementEntry *ee) | 487 | struct ElementEntry *ee, |
488 | int received) | ||
434 | { | 489 | { |
435 | struct IBF_Key ibf_key; | 490 | struct IBF_Key ibf_key; |
436 | struct KeyEntry *k; | 491 | struct KeyEntry *k; |
@@ -439,6 +494,7 @@ op_register_element (struct Operation *op, | |||
439 | k = GNUNET_new (struct KeyEntry); | 494 | k = GNUNET_new (struct KeyEntry); |
440 | k->element = ee; | 495 | k->element = ee; |
441 | k->ibf_key = ibf_key; | 496 | k->ibf_key = ibf_key; |
497 | k->received = received; | ||
442 | GNUNET_assert (GNUNET_OK == | 498 | GNUNET_assert (GNUNET_OK == |
443 | GNUNET_CONTAINER_multihashmap32_put (op->state->key_to_element, | 499 | GNUNET_CONTAINER_multihashmap32_put (op->state->key_to_element, |
444 | (uint32_t) ibf_key.key_val, | 500 | (uint32_t) ibf_key.key_val, |
@@ -524,12 +580,30 @@ init_key_to_element_iterator (void *cls, | |||
524 | 580 | ||
525 | GNUNET_assert (GNUNET_NO == ee->remote); | 581 | GNUNET_assert (GNUNET_NO == ee->remote); |
526 | 582 | ||
527 | op_register_element (op, ee); | 583 | op_register_element (op, ee, GNUNET_NO); |
528 | return GNUNET_YES; | 584 | return GNUNET_YES; |
529 | } | 585 | } |
530 | 586 | ||
531 | 587 | ||
532 | /** | 588 | /** |
589 | * Initialize the IBF key to element mapping local to this set | ||
590 | * operation. | ||
591 | * | ||
592 | * @param op the set union operation | ||
593 | */ | ||
594 | static void | ||
595 | initialize_key_to_element (struct Operation *op) | ||
596 | { | ||
597 | unsigned int len; | ||
598 | |||
599 | GNUNET_assert (NULL == op->state->key_to_element); | ||
600 | len = GNUNET_CONTAINER_multihashmap_size (op->spec->set->content->elements); | ||
601 | op->state->key_to_element = GNUNET_CONTAINER_multihashmap32_create (len + 1); | ||
602 | GNUNET_CONTAINER_multihashmap_iterate (op->spec->set->content->elements, init_key_to_element_iterator, op); | ||
603 | } | ||
604 | |||
605 | |||
606 | /** | ||
533 | * Create an ibf with the operation's elements | 607 | * Create an ibf with the operation's elements |
534 | * of the specified size | 608 | * of the specified size |
535 | * | 609 | * |
@@ -541,15 +615,8 @@ static int | |||
541 | prepare_ibf (struct Operation *op, | 615 | prepare_ibf (struct Operation *op, |
542 | uint32_t size) | 616 | uint32_t size) |
543 | { | 617 | { |
544 | if (NULL == op->state->key_to_element) | 618 | GNUNET_assert (NULL != op->state->key_to_element); |
545 | { | ||
546 | unsigned int len; | ||
547 | 619 | ||
548 | len = GNUNET_CONTAINER_multihashmap_size (op->spec->set->content->elements); | ||
549 | op->state->key_to_element = GNUNET_CONTAINER_multihashmap32_create (len + 1); | ||
550 | GNUNET_CONTAINER_multihashmap_iterate (op->spec->set->content->elements, | ||
551 | init_key_to_element_iterator, op); | ||
552 | } | ||
553 | if (NULL != op->state->local_ibf) | 620 | if (NULL != op->state->local_ibf) |
554 | ibf_destroy (op->state->local_ibf); | 621 | ibf_destroy (op->state->local_ibf); |
555 | op->state->local_ibf = ibf_create (size, SE_IBF_HASH_NUM); | 622 | op->state->local_ibf = ibf_create (size, SE_IBF_HASH_NUM); |
@@ -648,7 +715,7 @@ send_strata_estimator (struct Operation *op) | |||
648 | { | 715 | { |
649 | const struct StrataEstimator *se = op->state->se; | 716 | const struct StrataEstimator *se = op->state->se; |
650 | struct GNUNET_MQ_Envelope *ev; | 717 | struct GNUNET_MQ_Envelope *ev; |
651 | struct GNUNET_MessageHeader *strata_msg; | 718 | struct StrataEstimatorMessage *strata_msg; |
652 | char *buf; | 719 | char *buf; |
653 | size_t len; | 720 | size_t len; |
654 | uint16_t type; | 721 | uint16_t type; |
@@ -660,13 +727,14 @@ send_strata_estimator (struct Operation *op) | |||
660 | type = GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SEC; | 727 | type = GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SEC; |
661 | else | 728 | else |
662 | type = GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE; | 729 | type = GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE; |
663 | ev = GNUNET_MQ_msg_header_extra (strata_msg, | 730 | ev = GNUNET_MQ_msg_extra (strata_msg, |
664 | len, | 731 | len, |
665 | type); | 732 | type); |
666 | GNUNET_memcpy (&strata_msg[1], | 733 | GNUNET_memcpy (&strata_msg[1], |
667 | buf, | 734 | buf, |
668 | len); | 735 | len); |
669 | GNUNET_free (buf); | 736 | GNUNET_free (buf); |
737 | strata_msg->set_size = GNUNET_htonll (GNUNET_CONTAINER_multihashmap_size (op->spec->set->content->elements)); | ||
670 | GNUNET_MQ_send (op->mq, | 738 | GNUNET_MQ_send (op->mq, |
671 | ev); | 739 | ev); |
672 | op->state->phase = PHASE_EXPECT_IBF; | 740 | op->state->phase = PHASE_EXPECT_IBF; |
@@ -693,7 +761,51 @@ get_order_from_difference (unsigned int diff) | |||
693 | ibf_order++; | 761 | ibf_order++; |
694 | if (ibf_order > MAX_IBF_ORDER) | 762 | if (ibf_order > MAX_IBF_ORDER) |
695 | ibf_order = MAX_IBF_ORDER; | 763 | ibf_order = MAX_IBF_ORDER; |
696 | return ibf_order; | 764 | // add one for correction |
765 | return ibf_order + 1; | ||
766 | } | ||
767 | |||
768 | |||
769 | /** | ||
770 | * Send a set element. | ||
771 | * | ||
772 | * @param cls the union operation `struct Operation *` | ||
773 | * @param key unused | ||
774 | * @param value the `struct ElementEntry *` to insert | ||
775 | * into the key-to-element mapping | ||
776 | * @return #GNUNET_YES (to continue iterating) | ||
777 | */ | ||
778 | static int | ||
779 | send_element_iterator (void *cls, | ||
780 | const struct GNUNET_HashCode *key, | ||
781 | void *value) | ||
782 | { | ||
783 | struct Operation *op = cls; | ||
784 | struct GNUNET_SET_ElementMessage *emsg; | ||
785 | struct ElementEntry *ee = value; | ||
786 | struct GNUNET_SET_Element *el = &ee->element; | ||
787 | struct GNUNET_MQ_Envelope *ev; | ||
788 | |||
789 | |||
790 | ev = GNUNET_MQ_msg_extra (emsg, el->size, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_ELEMENT); | ||
791 | emsg->element_type = htons (el->element_type); | ||
792 | GNUNET_memcpy (&emsg[1], el->data, el->size); | ||
793 | GNUNET_MQ_send (op->mq, ev); | ||
794 | return GNUNET_YES; | ||
795 | } | ||
796 | |||
797 | |||
798 | static void | ||
799 | send_full_set (struct Operation *op) | ||
800 | { | ||
801 | struct GNUNET_MQ_Envelope *ev; | ||
802 | |||
803 | op->state->phase = PHASE_FULL_SENDING; | ||
804 | |||
805 | (void) GNUNET_CONTAINER_multihashmap_iterate (op->spec->set->content->elements, | ||
806 | &send_element_iterator, op); | ||
807 | ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_DONE); | ||
808 | GNUNET_MQ_send (op->mq, ev); | ||
697 | } | 809 | } |
698 | 810 | ||
699 | 811 | ||
@@ -713,7 +825,9 @@ handle_p2p_strata_estimator (void *cls, | |||
713 | { | 825 | { |
714 | struct Operation *op = cls; | 826 | struct Operation *op = cls; |
715 | struct StrataEstimator *remote_se; | 827 | struct StrataEstimator *remote_se; |
716 | int diff; | 828 | struct StrataEstimatorMessage *msg = (void *) mh; |
829 | unsigned int diff; | ||
830 | uint64_t other_size; | ||
717 | size_t len; | 831 | size_t len; |
718 | 832 | ||
719 | GNUNET_STATISTICS_update (_GSS_statistics, | 833 | GNUNET_STATISTICS_update (_GSS_statistics, |
@@ -723,11 +837,11 @@ handle_p2p_strata_estimator (void *cls, | |||
723 | 837 | ||
724 | if (op->state->phase != PHASE_EXPECT_SE) | 838 | if (op->state->phase != PHASE_EXPECT_SE) |
725 | { | 839 | { |
726 | fail_union_operation (op); | ||
727 | GNUNET_break (0); | 840 | GNUNET_break (0); |
841 | fail_union_operation (op); | ||
728 | return GNUNET_SYSERR; | 842 | return GNUNET_SYSERR; |
729 | } | 843 | } |
730 | len = ntohs (mh->size) - sizeof (struct GNUNET_MessageHeader); | 844 | len = ntohs (mh->size) - sizeof (struct StrataEstimatorMessage); |
731 | if ( (GNUNET_NO == is_compressed) && | 845 | if ( (GNUNET_NO == is_compressed) && |
732 | (len != SE_STRATA_COUNT * SE_IBF_SIZE * IBF_BUCKET_SIZE) ) | 846 | (len != SE_STRATA_COUNT * SE_IBF_SIZE * IBF_BUCKET_SIZE) ) |
733 | { | 847 | { |
@@ -735,6 +849,7 @@ handle_p2p_strata_estimator (void *cls, | |||
735 | GNUNET_break (0); | 849 | GNUNET_break (0); |
736 | return GNUNET_SYSERR; | 850 | return GNUNET_SYSERR; |
737 | } | 851 | } |
852 | other_size = GNUNET_ntohll (msg->set_size); | ||
738 | remote_se = strata_estimator_create (SE_STRATA_COUNT, | 853 | remote_se = strata_estimator_create (SE_STRATA_COUNT, |
739 | SE_IBF_SIZE, | 854 | SE_IBF_SIZE, |
740 | SE_IBF_HASH_NUM); | 855 | SE_IBF_HASH_NUM); |
@@ -745,7 +860,7 @@ handle_p2p_strata_estimator (void *cls, | |||
745 | return GNUNET_SYSERR; | 860 | return GNUNET_SYSERR; |
746 | } | 861 | } |
747 | if (GNUNET_OK != | 862 | if (GNUNET_OK != |
748 | strata_estimator_read (&mh[1], | 863 | strata_estimator_read (&msg[1], |
749 | len, | 864 | len, |
750 | is_compressed, | 865 | is_compressed, |
751 | remote_se)) | 866 | remote_se)) |
@@ -758,6 +873,10 @@ handle_p2p_strata_estimator (void *cls, | |||
758 | GNUNET_assert (NULL != op->state->se); | 873 | GNUNET_assert (NULL != op->state->se); |
759 | diff = strata_estimator_difference (remote_se, | 874 | diff = strata_estimator_difference (remote_se, |
760 | op->state->se); | 875 | op->state->se); |
876 | |||
877 | if (diff > 200) | ||
878 | diff = diff * 3 / 2; | ||
879 | |||
761 | strata_estimator_destroy (remote_se); | 880 | strata_estimator_destroy (remote_se); |
762 | strata_estimator_destroy (op->state->se); | 881 | strata_estimator_destroy (op->state->se); |
763 | op->state->se = NULL; | 882 | op->state->se = NULL; |
@@ -765,16 +884,55 @@ handle_p2p_strata_estimator (void *cls, | |||
765 | "got se diff=%d, using ibf size %d\n", | 884 | "got se diff=%d, using ibf size %d\n", |
766 | diff, | 885 | diff, |
767 | 1<<get_order_from_difference (diff)); | 886 | 1<<get_order_from_difference (diff)); |
768 | if (GNUNET_OK != | 887 | |
769 | send_ibf (op, | 888 | if ((GNUNET_YES == op->spec->byzantine) && (other_size < op->spec->byzantine_lower_bound)) |
770 | get_order_from_difference (diff))) | ||
771 | { | 889 | { |
772 | /* Internal error, best we can do is shut the connection */ | 890 | GNUNET_break (0); |
773 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
774 | "Failed to send IBF, closing connection\n"); | ||
775 | fail_union_operation (op); | 891 | fail_union_operation (op); |
776 | return GNUNET_SYSERR; | 892 | return GNUNET_SYSERR; |
777 | } | 893 | } |
894 | |||
895 | |||
896 | if ( (GNUNET_YES == op->spec->force_full) || (diff > op->state->initial_size / 4)) | ||
897 | { | ||
898 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
899 | "Sending full set (diff=%d, own set=%u)\n", | ||
900 | diff, | ||
901 | op->state->initial_size); | ||
902 | GNUNET_STATISTICS_update (_GSS_statistics, | ||
903 | "# of full sends", | ||
904 | 1, | ||
905 | GNUNET_NO); | ||
906 | if (op->state->initial_size <= other_size) | ||
907 | { | ||
908 | send_full_set (op); | ||
909 | } | ||
910 | else | ||
911 | { | ||
912 | struct GNUNET_MQ_Envelope *ev; | ||
913 | op->state->phase = PHASE_EXPECT_IBF; | ||
914 | ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_UNION_P2P_REQUEST_FULL); | ||
915 | GNUNET_MQ_send (op->mq, ev); | ||
916 | } | ||
917 | } | ||
918 | else | ||
919 | { | ||
920 | GNUNET_STATISTICS_update (_GSS_statistics, | ||
921 | "# of ibf sends", | ||
922 | 1, | ||
923 | GNUNET_NO); | ||
924 | if (GNUNET_OK != | ||
925 | send_ibf (op, | ||
926 | get_order_from_difference (diff))) | ||
927 | { | ||
928 | /* Internal error, best we can do is shut the connection */ | ||
929 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
930 | "Failed to send IBF, closing connection\n"); | ||
931 | fail_union_operation (op); | ||
932 | return GNUNET_SYSERR; | ||
933 | } | ||
934 | } | ||
935 | |||
778 | return GNUNET_OK; | 936 | return GNUNET_OK; |
779 | } | 937 | } |
780 | 938 | ||
@@ -1141,7 +1299,8 @@ send_client_element (struct Operation *op, | |||
1141 | } | 1299 | } |
1142 | rm->result_status = htons (status); | 1300 | rm->result_status = htons (status); |
1143 | rm->request_id = htonl (op->spec->client_request_id); | 1301 | rm->request_id = htonl (op->spec->client_request_id); |
1144 | rm->element_type = element->element_type; | 1302 | rm->element_type = htons (element->element_type); |
1303 | rm->current_size = GNUNET_htonll (GNUNET_CONTAINER_multihashmap32_size (op->state->key_to_element)); | ||
1145 | GNUNET_memcpy (&rm[1], element->data, element->size); | 1304 | GNUNET_memcpy (&rm[1], element->data, element->size); |
1146 | GNUNET_MQ_send (op->spec->set->client_mq, ev); | 1305 | GNUNET_MQ_send (op->spec->set->client_mq, ev); |
1147 | } | 1306 | } |
@@ -1164,6 +1323,7 @@ send_done_and_destroy (void *cls) | |||
1164 | rm->request_id = htonl (op->spec->client_request_id); | 1323 | rm->request_id = htonl (op->spec->client_request_id); |
1165 | rm->result_status = htons (GNUNET_SET_STATUS_DONE); | 1324 | rm->result_status = htons (GNUNET_SET_STATUS_DONE); |
1166 | rm->element_type = htons (0); | 1325 | rm->element_type = htons (0); |
1326 | rm->current_size = GNUNET_htonll (GNUNET_CONTAINER_multihashmap32_size (op->state->key_to_element)); | ||
1167 | GNUNET_MQ_send (op->spec->set->client_mq, ev); | 1327 | GNUNET_MQ_send (op->spec->set->client_mq, ev); |
1168 | /* Will also call the union-specific cancel function. */ | 1328 | /* Will also call the union-specific cancel function. */ |
1169 | _GSS_operation_destroy (op, GNUNET_YES); | 1329 | _GSS_operation_destroy (op, GNUNET_YES); |
@@ -1210,6 +1370,8 @@ maybe_finish (struct Operation *op) | |||
1210 | 1370 | ||
1211 | /** | 1371 | /** |
1212 | * Handle an element message from a remote peer. | 1372 | * Handle an element message from a remote peer. |
1373 | * Sent by the other peer either because we decoded an IBF and placed a demand, | ||
1374 | * or because the other peer switched to full set transmission. | ||
1213 | * | 1375 | * |
1214 | * @param cls the union operation | 1376 | * @param cls the union operation |
1215 | * @param mh the message | 1377 | * @param mh the message |
@@ -1273,7 +1435,11 @@ handle_p2p_elements (void *cls, | |||
1273 | 1, | 1435 | 1, |
1274 | GNUNET_NO); | 1436 | GNUNET_NO); |
1275 | 1437 | ||
1276 | if (GNUNET_YES == op_has_element (op, &ee->element_hash)) | 1438 | op->state->received_total += 1; |
1439 | |||
1440 | struct KeyEntry *ke = op_get_element (op, &ee->element_hash); | ||
1441 | |||
1442 | if (NULL != ke) | ||
1277 | { | 1443 | { |
1278 | /* Got repeated element. Should not happen since | 1444 | /* Got repeated element. Should not happen since |
1279 | * we track demands. */ | 1445 | * we track demands. */ |
@@ -1281,13 +1447,15 @@ handle_p2p_elements (void *cls, | |||
1281 | "# repeated elements", | 1447 | "# repeated elements", |
1282 | 1, | 1448 | 1, |
1283 | GNUNET_NO); | 1449 | GNUNET_NO); |
1450 | ke->received = GNUNET_YES; | ||
1284 | GNUNET_free (ee); | 1451 | GNUNET_free (ee); |
1285 | } | 1452 | } |
1286 | else | 1453 | else |
1287 | { | 1454 | { |
1288 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1455 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1289 | "Registering new element from remote peer\n"); | 1456 | "Registering new element from remote peer\n"); |
1290 | op_register_element (op, ee); | 1457 | op->state->received_fresh += 1; |
1458 | op_register_element (op, ee, GNUNET_YES); | ||
1291 | /* only send results immediately if the client wants it */ | 1459 | /* only send results immediately if the client wants it */ |
1292 | switch (op->spec->result_mode) | 1460 | switch (op->spec->result_mode) |
1293 | { | 1461 | { |
@@ -1304,11 +1472,118 @@ handle_p2p_elements (void *cls, | |||
1304 | } | 1472 | } |
1305 | } | 1473 | } |
1306 | 1474 | ||
1475 | if (op->state->received_total > 8 && op->state->received_fresh < op->state->received_total / 3) | ||
1476 | { | ||
1477 | /* The other peer gave us lots of old elements, there's something wrong. */ | ||
1478 | GNUNET_break_op (0); | ||
1479 | fail_union_operation (op); | ||
1480 | return; | ||
1481 | } | ||
1482 | |||
1307 | maybe_finish (op); | 1483 | maybe_finish (op); |
1308 | } | 1484 | } |
1309 | 1485 | ||
1310 | 1486 | ||
1311 | /** | 1487 | /** |
1488 | * Handle an element message from a remote peer. | ||
1489 | * | ||
1490 | * @param cls the union operation | ||
1491 | * @param mh the message | ||
1492 | */ | ||
1493 | static void | ||
1494 | handle_p2p_full_element (void *cls, | ||
1495 | const struct GNUNET_MessageHeader *mh) | ||
1496 | { | ||
1497 | struct Operation *op = cls; | ||
1498 | struct ElementEntry *ee; | ||
1499 | const struct GNUNET_SET_ElementMessage *emsg; | ||
1500 | uint16_t element_size; | ||
1501 | |||
1502 | if (ntohs (mh->size) < sizeof (struct GNUNET_SET_ElementMessage)) | ||
1503 | { | ||
1504 | GNUNET_break_op (0); | ||
1505 | fail_union_operation (op); | ||
1506 | return; | ||
1507 | } | ||
1508 | |||
1509 | emsg = (const struct GNUNET_SET_ElementMessage *) mh; | ||
1510 | |||
1511 | element_size = ntohs (mh->size) - sizeof (struct GNUNET_SET_ElementMessage); | ||
1512 | ee = GNUNET_malloc (sizeof (struct ElementEntry) + element_size); | ||
1513 | GNUNET_memcpy (&ee[1], &emsg[1], element_size); | ||
1514 | ee->element.size = element_size; | ||
1515 | ee->element.data = &ee[1]; | ||
1516 | ee->element.element_type = ntohs (emsg->element_type); | ||
1517 | ee->remote = GNUNET_YES; | ||
1518 | GNUNET_SET_element_hash (&ee->element, &ee->element_hash); | ||
1519 | |||
1520 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1521 | "Got element (full diff, size %u, hash %s) from peer\n", | ||
1522 | (unsigned int) element_size, | ||
1523 | GNUNET_h2s (&ee->element_hash)); | ||
1524 | |||
1525 | GNUNET_STATISTICS_update (_GSS_statistics, | ||
1526 | "# received elements", | ||
1527 | 1, | ||
1528 | GNUNET_NO); | ||
1529 | GNUNET_STATISTICS_update (_GSS_statistics, | ||
1530 | "# exchanged elements", | ||
1531 | 1, | ||
1532 | GNUNET_NO); | ||
1533 | |||
1534 | op->state->received_total += 1; | ||
1535 | |||
1536 | struct KeyEntry *ke = op_get_element (op, &ee->element_hash); | ||
1537 | |||
1538 | if (NULL != ke) | ||
1539 | { | ||
1540 | /* Got repeated element. Should not happen since | ||
1541 | * we track demands. */ | ||
1542 | GNUNET_STATISTICS_update (_GSS_statistics, | ||
1543 | "# repeated elements", | ||
1544 | 1, | ||
1545 | GNUNET_NO); | ||
1546 | ke->received = GNUNET_YES; | ||
1547 | GNUNET_free (ee); | ||
1548 | } | ||
1549 | else | ||
1550 | { | ||
1551 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1552 | "Registering new element from remote peer\n"); | ||
1553 | op->state->received_fresh += 1; | ||
1554 | op_register_element (op, ee, GNUNET_YES); | ||
1555 | /* only send results immediately if the client wants it */ | ||
1556 | switch (op->spec->result_mode) | ||
1557 | { | ||
1558 | case GNUNET_SET_RESULT_ADDED: | ||
1559 | send_client_element (op, &ee->element, GNUNET_SET_STATUS_OK); | ||
1560 | break; | ||
1561 | case GNUNET_SET_RESULT_SYMMETRIC: | ||
1562 | send_client_element (op, &ee->element, GNUNET_SET_STATUS_ADD_LOCAL); | ||
1563 | break; | ||
1564 | default: | ||
1565 | /* Result mode not supported, should have been caught earlier. */ | ||
1566 | GNUNET_break (0); | ||
1567 | break; | ||
1568 | } | ||
1569 | } | ||
1570 | |||
1571 | if ( (GNUNET_YES == op->spec->byzantine) && | ||
1572 | (op->state->received_total > 384 + op->state->received_fresh * 4) && | ||
1573 | (op->state->received_fresh < op->state->received_total / 6) ) | ||
1574 | { | ||
1575 | /* The other peer gave us lots of old elements, there's something wrong. */ | ||
1576 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
1577 | "Other peer sent only %llu/%llu fresh elements, failing operation\n", | ||
1578 | (unsigned long long) op->state->received_fresh, | ||
1579 | (unsigned long long) op->state->received_total); | ||
1580 | GNUNET_break_op (0); | ||
1581 | fail_union_operation (op); | ||
1582 | return; | ||
1583 | } | ||
1584 | } | ||
1585 | |||
1586 | /** | ||
1312 | * Send offers (for GNUNET_Hash-es) in response | 1587 | * Send offers (for GNUNET_Hash-es) in response |
1313 | * to inquiries (for IBF_Key-s). | 1588 | * to inquiries (for IBF_Key-s). |
1314 | * | 1589 | * |
@@ -1355,7 +1630,116 @@ handle_p2p_inquiry (void *cls, | |||
1355 | 1630 | ||
1356 | 1631 | ||
1357 | /** | 1632 | /** |
1358 | * FIXME | 1633 | * Iterator over hash map entries, called to |
1634 | * destroy the linked list of colliding ibf key entries. | ||
1635 | * | ||
1636 | * @param cls closure | ||
1637 | * @param key current key code | ||
1638 | * @param value value in the hash map | ||
1639 | * @return #GNUNET_YES if we should continue to iterate, | ||
1640 | * #GNUNET_NO if not. | ||
1641 | */ | ||
1642 | static int | ||
1643 | send_missing_elements_iter (void *cls, | ||
1644 | uint32_t key, | ||
1645 | void *value) | ||
1646 | { | ||
1647 | struct Operation *op = cls; | ||
1648 | struct KeyEntry *ke = value; | ||
1649 | struct GNUNET_MQ_Envelope *ev; | ||
1650 | struct GNUNET_SET_ElementMessage *emsg; | ||
1651 | struct ElementEntry *ee = ke->element; | ||
1652 | |||
1653 | if (GNUNET_YES == ke->received) | ||
1654 | return GNUNET_YES; | ||
1655 | |||
1656 | ev = GNUNET_MQ_msg_extra (emsg, ee->element.size, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_ELEMENT); | ||
1657 | GNUNET_memcpy (&emsg[1], ee->element.data, ee->element.size); | ||
1658 | emsg->reserved = htons (0); | ||
1659 | emsg->element_type = htons (ee->element.element_type); | ||
1660 | GNUNET_MQ_send (op->mq, ev); | ||
1661 | |||
1662 | return GNUNET_YES; | ||
1663 | } | ||
1664 | |||
1665 | |||
1666 | /** | ||
1667 | * Handle a | ||
1668 | * | ||
1669 | * @parem cls closure, a set union operation | ||
1670 | * @param mh the demand message | ||
1671 | */ | ||
1672 | static void | ||
1673 | handle_p2p_request_full (void *cls, | ||
1674 | const struct GNUNET_MessageHeader *mh) | ||
1675 | { | ||
1676 | struct Operation *op = cls; | ||
1677 | |||
1678 | if (PHASE_EXPECT_IBF != op->state->phase) | ||
1679 | { | ||
1680 | fail_union_operation (op); | ||
1681 | GNUNET_break_op (0); | ||
1682 | return; | ||
1683 | } | ||
1684 | |||
1685 | // FIXME: we need to check that our set is larger than the | ||
1686 | // byzantine_lower_bound by some threshold | ||
1687 | send_full_set (op); | ||
1688 | } | ||
1689 | |||
1690 | |||
1691 | /** | ||
1692 | * Handle a "full done" message. | ||
1693 | * | ||
1694 | * @parem cls closure, a set union operation | ||
1695 | * @param mh the demand message | ||
1696 | */ | ||
1697 | static void | ||
1698 | handle_p2p_full_done (void *cls, | ||
1699 | const struct GNUNET_MessageHeader *mh) | ||
1700 | { | ||
1701 | struct Operation *op = cls; | ||
1702 | |||
1703 | if (PHASE_EXPECT_IBF == op->state->phase) | ||
1704 | { | ||
1705 | struct GNUNET_MQ_Envelope *ev; | ||
1706 | |||
1707 | LOG (GNUNET_ERROR_TYPE_DEBUG, "got FULL DONE, sending elements that other peer is missing\n"); | ||
1708 | |||
1709 | /* send all the elements that did not come from the remote peer */ | ||
1710 | GNUNET_CONTAINER_multihashmap32_iterate (op->state->key_to_element, | ||
1711 | &send_missing_elements_iter, | ||
1712 | op); | ||
1713 | |||
1714 | ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_DONE); | ||
1715 | GNUNET_MQ_send (op->mq, ev); | ||
1716 | op->state->phase = PHASE_DONE; | ||
1717 | |||
1718 | /* we now wait until the other peer shuts the tunnel down*/ | ||
1719 | } | ||
1720 | else if (PHASE_FULL_SENDING == op->state->phase) | ||
1721 | { | ||
1722 | LOG (GNUNET_ERROR_TYPE_DEBUG, "got FULL DONE, finishing\n"); | ||
1723 | /* We sent the full set, and got the response for that. We're done. */ | ||
1724 | op->state->phase = PHASE_DONE; | ||
1725 | send_done_and_destroy (op); | ||
1726 | } | ||
1727 | else | ||
1728 | { | ||
1729 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "handle full done phase is %u\n", (unsigned) op->state->phase); | ||
1730 | GNUNET_break_op (0); | ||
1731 | fail_union_operation (op); | ||
1732 | return; | ||
1733 | } | ||
1734 | } | ||
1735 | |||
1736 | |||
1737 | /** | ||
1738 | * Handle a demand by the other peer for elements based on a list | ||
1739 | * of GNUNET_HashCode-s. | ||
1740 | * | ||
1741 | * @parem cls closure, a set union operation | ||
1742 | * @param mh the demand message | ||
1359 | */ | 1743 | */ |
1360 | static void | 1744 | static void |
1361 | handle_p2p_demand (void *cls, | 1745 | handle_p2p_demand (void *cls, |
@@ -1607,6 +1991,9 @@ union_evaluate (struct Operation *op, | |||
1607 | else | 1991 | else |
1608 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1992 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1609 | "sent op request without context message\n"); | 1993 | "sent op request without context message\n"); |
1994 | |||
1995 | initialize_key_to_element (op); | ||
1996 | op->state->initial_size = GNUNET_CONTAINER_multihashmap32_size (op->state->key_to_element); | ||
1610 | } | 1997 | } |
1611 | 1998 | ||
1612 | 1999 | ||
@@ -1636,6 +2023,8 @@ union_accept (struct Operation *op) | |||
1636 | op->state->se = strata_estimator_dup (op->spec->set->state->se); | 2023 | op->state->se = strata_estimator_dup (op->spec->set->state->se); |
1637 | op->state->demanded_hashes = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO); | 2024 | op->state->demanded_hashes = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO); |
1638 | op->state->salt_receive = op->state->salt_send = 42; | 2025 | op->state->salt_receive = op->state->salt_send = 42; |
2026 | initialize_key_to_element (op); | ||
2027 | op->state->initial_size = GNUNET_CONTAINER_multihashmap32_size (op->state->key_to_element); | ||
1639 | /* kick off the operation */ | 2028 | /* kick off the operation */ |
1640 | send_strata_estimator (op); | 2029 | send_strata_estimator (op); |
1641 | } | 2030 | } |
@@ -1743,6 +2132,9 @@ union_handle_p2p_message (struct Operation *op, | |||
1743 | case GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENTS: | 2132 | case GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENTS: |
1744 | handle_p2p_elements (op, mh); | 2133 | handle_p2p_elements (op, mh); |
1745 | break; | 2134 | break; |
2135 | case GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_ELEMENT: | ||
2136 | handle_p2p_full_element (op, mh); | ||
2137 | break; | ||
1746 | case GNUNET_MESSAGE_TYPE_SET_UNION_P2P_INQUIRY: | 2138 | case GNUNET_MESSAGE_TYPE_SET_UNION_P2P_INQUIRY: |
1747 | handle_p2p_inquiry (op, mh); | 2139 | handle_p2p_inquiry (op, mh); |
1748 | break; | 2140 | break; |
@@ -1755,6 +2147,12 @@ union_handle_p2p_message (struct Operation *op, | |||
1755 | case GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DEMAND: | 2147 | case GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DEMAND: |
1756 | handle_p2p_demand (op, mh); | 2148 | handle_p2p_demand (op, mh); |
1757 | break; | 2149 | break; |
2150 | case GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_DONE: | ||
2151 | handle_p2p_full_done (op, mh); | ||
2152 | break; | ||
2153 | case GNUNET_MESSAGE_TYPE_SET_UNION_P2P_REQUEST_FULL: | ||
2154 | handle_p2p_request_full (op, mh); | ||
2155 | break; | ||
1758 | default: | 2156 | default: |
1759 | /* Something wrong with cadet's message handlers? */ | 2157 | /* Something wrong with cadet's message handlers? */ |
1760 | GNUNET_assert (0); | 2158 | GNUNET_assert (0); |
diff --git a/src/set/gnunet-set-profiler.c b/src/set/gnunet-set-profiler.c index f89817ff5..8404b191c 100644 --- a/src/set/gnunet-set-profiler.c +++ b/src/set/gnunet-set-profiler.c | |||
@@ -58,6 +58,11 @@ static struct GNUNET_PeerIdentity local_peer; | |||
58 | 58 | ||
59 | static struct GNUNET_SET_ListenHandle *set_listener; | 59 | static struct GNUNET_SET_ListenHandle *set_listener; |
60 | 60 | ||
61 | static int byzantine; | ||
62 | static int force_delta; | ||
63 | static int force_full; | ||
64 | static unsigned int element_size = 32; | ||
65 | |||
61 | /** | 66 | /** |
62 | * Handle to the statistics service. | 67 | * Handle to the statistics service. |
63 | */ | 68 | */ |
@@ -86,7 +91,7 @@ map_remove_iterator (void *cls, | |||
86 | 91 | ||
87 | GNUNET_assert (NULL != key); | 92 | GNUNET_assert (NULL != key); |
88 | 93 | ||
89 | ret = GNUNET_CONTAINER_multihashmap_remove (m, key, NULL); | 94 | ret = GNUNET_CONTAINER_multihashmap_remove_all (m, key); |
90 | if (GNUNET_OK != ret) | 95 | if (GNUNET_OK != ret) |
91 | printf ("spurious element\n"); | 96 | printf ("spurious element\n"); |
92 | return GNUNET_YES; | 97 | return GNUNET_YES; |
@@ -158,6 +163,7 @@ check_all_done (void) | |||
158 | static void | 163 | static void |
159 | set_result_cb (void *cls, | 164 | set_result_cb (void *cls, |
160 | const struct GNUNET_SET_Element *element, | 165 | const struct GNUNET_SET_Element *element, |
166 | uint64_t current_size, | ||
161 | enum GNUNET_SET_Status status) | 167 | enum GNUNET_SET_Status status) |
162 | { | 168 | { |
163 | struct SetInfo *info = cls; | 169 | struct SetInfo *info = cls; |
@@ -191,7 +197,7 @@ set_result_cb (void *cls, | |||
191 | GNUNET_assert (0); | 197 | GNUNET_assert (0); |
192 | } | 198 | } |
193 | 199 | ||
194 | if (element->size != sizeof (struct GNUNET_HashCode)) | 200 | if (element->size != element_size) |
195 | { | 201 | { |
196 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 202 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
197 | "wrong element size: %u, expected %u\n", | 203 | "wrong element size: %u, expected %u\n", |
@@ -203,8 +209,10 @@ set_result_cb (void *cls, | |||
203 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "set %s: got element (%s)\n", | 209 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "set %s: got element (%s)\n", |
204 | info->id, GNUNET_h2s (element->data)); | 210 | info->id, GNUNET_h2s (element->data)); |
205 | GNUNET_assert (NULL != element->data); | 211 | GNUNET_assert (NULL != element->data); |
212 | struct GNUNET_HashCode data_hash; | ||
213 | GNUNET_CRYPTO_hash (element->data, element_size, &data_hash); | ||
206 | GNUNET_CONTAINER_multihashmap_put (info->received, | 214 | GNUNET_CONTAINER_multihashmap_put (info->received, |
207 | element->data, NULL, | 215 | &data_hash, NULL, |
208 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); | 216 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); |
209 | } | 217 | } |
210 | 218 | ||
@@ -215,6 +223,10 @@ set_listen_cb (void *cls, | |||
215 | const struct GNUNET_MessageHeader *context_msg, | 223 | const struct GNUNET_MessageHeader *context_msg, |
216 | struct GNUNET_SET_Request *request) | 224 | struct GNUNET_SET_Request *request) |
217 | { | 225 | { |
226 | /* max. 2 options plus terminator */ | ||
227 | struct GNUNET_SET_Option opts[3] = {{0}}; | ||
228 | unsigned int n_opts = 0; | ||
229 | |||
218 | if (NULL == request) | 230 | if (NULL == request) |
219 | { | 231 | { |
220 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 232 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
@@ -224,8 +236,24 @@ set_listen_cb (void *cls, | |||
224 | GNUNET_assert (NULL == info2.oh); | 236 | GNUNET_assert (NULL == info2.oh); |
225 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 237 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
226 | "set listen cb called\n"); | 238 | "set listen cb called\n"); |
239 | if (byzantine) | ||
240 | { | ||
241 | opts[n_opts++] = (struct GNUNET_SET_Option) { .type = GNUNET_SET_OPTION_BYZANTINE }; | ||
242 | } | ||
243 | GNUNET_assert (!(force_full && force_delta)); | ||
244 | if (force_full) | ||
245 | { | ||
246 | opts[n_opts++] = (struct GNUNET_SET_Option) { .type = GNUNET_SET_OPTION_FORCE_FULL }; | ||
247 | } | ||
248 | if (force_delta) | ||
249 | { | ||
250 | opts[n_opts++] = (struct GNUNET_SET_Option) { .type = GNUNET_SET_OPTION_FORCE_DELTA }; | ||
251 | } | ||
252 | |||
253 | opts[n_opts].type = 0; | ||
227 | info2.oh = GNUNET_SET_accept (request, GNUNET_SET_RESULT_SYMMETRIC, | 254 | info2.oh = GNUNET_SET_accept (request, GNUNET_SET_RESULT_SYMMETRIC, |
228 | set_result_cb, &info2); | 255 | opts, |
256 | set_result_cb, &info2); | ||
229 | GNUNET_SET_commit (info2.oh, info2.set); | 257 | GNUNET_SET_commit (info2.oh, info2.set); |
230 | } | 258 | } |
231 | 259 | ||
@@ -236,16 +264,12 @@ set_insert_iterator (void *cls, | |||
236 | void *value) | 264 | void *value) |
237 | { | 265 | { |
238 | struct GNUNET_SET_Handle *set = cls; | 266 | struct GNUNET_SET_Handle *set = cls; |
239 | struct GNUNET_SET_Element *el; | 267 | struct GNUNET_SET_Element el; |
240 | 268 | ||
241 | el = GNUNET_malloc (sizeof (struct GNUNET_SET_Element) + | 269 | el.element_type = 0; |
242 | sizeof (struct GNUNET_HashCode)); | 270 | el.data = value; |
243 | el->element_type = 0; | 271 | el.size = element_size; |
244 | GNUNET_memcpy (&el[1], key, sizeof *key); | 272 | GNUNET_SET_add_element (set, &el, NULL, NULL); |
245 | el->data = &el[1]; | ||
246 | el->size = sizeof *key; | ||
247 | GNUNET_SET_add_element (set, el, NULL, NULL); | ||
248 | GNUNET_free (el); | ||
249 | return GNUNET_YES; | 273 | return GNUNET_YES; |
250 | } | 274 | } |
251 | 275 | ||
@@ -291,9 +315,14 @@ run (void *cls, | |||
291 | { | 315 | { |
292 | unsigned int i; | 316 | unsigned int i; |
293 | struct GNUNET_HashCode hash; | 317 | struct GNUNET_HashCode hash; |
318 | /* max. 2 options plus terminator */ | ||
319 | struct GNUNET_SET_Option opts[3] = {{0}}; | ||
320 | unsigned int n_opts = 0; | ||
294 | 321 | ||
295 | config = cfg; | 322 | config = cfg; |
296 | 323 | ||
324 | GNUNET_assert (element_size > 0); | ||
325 | |||
297 | if (GNUNET_OK != GNUNET_CRYPTO_get_peer_identity (cfg, &local_peer)) | 326 | if (GNUNET_OK != GNUNET_CRYPTO_get_peer_identity (cfg, &local_peer)) |
298 | { | 327 | { |
299 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "could not retrieve host identity\n"); | 328 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "could not retrieve host identity\n"); |
@@ -317,22 +346,28 @@ run (void *cls, | |||
317 | 346 | ||
318 | for (i = 0; i < num_a; i++) | 347 | for (i = 0; i < num_a; i++) |
319 | { | 348 | { |
320 | GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_STRONG, &hash); | 349 | char *data = GNUNET_malloc (element_size); |
321 | GNUNET_CONTAINER_multihashmap_put (info1.sent, &hash, NULL, | 350 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, data, element_size); |
351 | GNUNET_CRYPTO_hash (data, element_size, &hash); | ||
352 | GNUNET_CONTAINER_multihashmap_put (info1.sent, &hash, data, | ||
322 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); | 353 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); |
323 | } | 354 | } |
324 | 355 | ||
325 | for (i = 0; i < num_b; i++) | 356 | for (i = 0; i < num_b; i++) |
326 | { | 357 | { |
327 | GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_STRONG, &hash); | 358 | char *data = GNUNET_malloc (element_size); |
328 | GNUNET_CONTAINER_multihashmap_put (info2.sent, &hash, NULL, | 359 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, data, element_size); |
360 | GNUNET_CRYPTO_hash (data, element_size, &hash); | ||
361 | GNUNET_CONTAINER_multihashmap_put (info2.sent, &hash, data, | ||
329 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); | 362 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); |
330 | } | 363 | } |
331 | 364 | ||
332 | for (i = 0; i < num_c; i++) | 365 | for (i = 0; i < num_c; i++) |
333 | { | 366 | { |
334 | GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_STRONG, &hash); | 367 | char *data = GNUNET_malloc (element_size); |
335 | GNUNET_CONTAINER_multihashmap_put (common_sent, &hash, NULL, | 368 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, data, element_size); |
369 | GNUNET_CRYPTO_hash (data, element_size, &hash); | ||
370 | GNUNET_CONTAINER_multihashmap_put (common_sent, &hash, data, | ||
336 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); | 371 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); |
337 | } | 372 | } |
338 | 373 | ||
@@ -350,8 +385,26 @@ run (void *cls, | |||
350 | set_listener = GNUNET_SET_listen (config, GNUNET_SET_OPERATION_UNION, | 385 | set_listener = GNUNET_SET_listen (config, GNUNET_SET_OPERATION_UNION, |
351 | &app_id, set_listen_cb, NULL); | 386 | &app_id, set_listen_cb, NULL); |
352 | 387 | ||
388 | |||
389 | if (byzantine) | ||
390 | { | ||
391 | opts[n_opts++] = (struct GNUNET_SET_Option) { .type = GNUNET_SET_OPTION_BYZANTINE }; | ||
392 | } | ||
393 | GNUNET_assert (!(force_full && force_delta)); | ||
394 | if (force_full) | ||
395 | { | ||
396 | opts[n_opts++] = (struct GNUNET_SET_Option) { .type = GNUNET_SET_OPTION_FORCE_FULL }; | ||
397 | } | ||
398 | if (force_delta) | ||
399 | { | ||
400 | opts[n_opts++] = (struct GNUNET_SET_Option) { .type = GNUNET_SET_OPTION_FORCE_DELTA }; | ||
401 | } | ||
402 | |||
403 | opts[n_opts].type = 0; | ||
404 | |||
353 | info1.oh = GNUNET_SET_prepare (&local_peer, &app_id, NULL, | 405 | info1.oh = GNUNET_SET_prepare (&local_peer, &app_id, NULL, |
354 | GNUNET_SET_RESULT_SYMMETRIC, | 406 | GNUNET_SET_RESULT_SYMMETRIC, |
407 | opts, | ||
355 | set_result_cb, &info1); | 408 | set_result_cb, &info1); |
356 | GNUNET_SET_commit (info1.oh, info1.set); | 409 | GNUNET_SET_commit (info1.oh, info1.set); |
357 | GNUNET_SET_destroy (info1.set); | 410 | GNUNET_SET_destroy (info1.set); |
@@ -380,12 +433,24 @@ main (int argc, char **argv) | |||
380 | { 'B', "num-second", NULL, | 433 | { 'B', "num-second", NULL, |
381 | gettext_noop ("number of values"), | 434 | gettext_noop ("number of values"), |
382 | GNUNET_YES, &GNUNET_GETOPT_set_uint, &num_b }, | 435 | GNUNET_YES, &GNUNET_GETOPT_set_uint, &num_b }, |
436 | { 'b', "byzantine", NULL, | ||
437 | gettext_noop ("use byzantine mode"), | ||
438 | GNUNET_NO, &GNUNET_GETOPT_set_one, &byzantine }, | ||
439 | { 'f', "force-full", NULL, | ||
440 | gettext_noop ("force sending full set"), | ||
441 | GNUNET_NO, &GNUNET_GETOPT_set_uint, &force_full }, | ||
442 | { 'd', "force-delta", NULL, | ||
443 | gettext_noop ("number delta operation"), | ||
444 | GNUNET_NO, &GNUNET_GETOPT_set_uint, &force_delta }, | ||
383 | { 'C', "num-common", NULL, | 445 | { 'C', "num-common", NULL, |
384 | gettext_noop ("number of values"), | 446 | gettext_noop ("number of values"), |
385 | GNUNET_YES, &GNUNET_GETOPT_set_uint, &num_c }, | 447 | GNUNET_YES, &GNUNET_GETOPT_set_uint, &num_c }, |
386 | { 'x', "operation", NULL, | 448 | { 'x', "operation", NULL, |
387 | gettext_noop ("operation to execute"), | 449 | gettext_noop ("operation to execute"), |
388 | GNUNET_YES, &GNUNET_GETOPT_set_string, &op_str }, | 450 | GNUNET_YES, &GNUNET_GETOPT_set_string, &op_str }, |
451 | { 'w', "element-size", NULL, | ||
452 | gettext_noop ("element size"), | ||
453 | GNUNET_YES, &GNUNET_GETOPT_set_uint, &element_size }, | ||
389 | { 's', "statistics", NULL, | 454 | { 's', "statistics", NULL, |
390 | gettext_noop ("write statistics to file"), | 455 | gettext_noop ("write statistics to file"), |
391 | GNUNET_YES, &GNUNET_GETOPT_set_filename, &statistics_filename }, | 456 | GNUNET_YES, &GNUNET_GETOPT_set_filename, &statistics_filename }, |
diff --git a/src/set/plugin_block_set_test.c b/src/set/plugin_block_set_test.c new file mode 100644 index 000000000..01b0c8602 --- /dev/null +++ b/src/set/plugin_block_set_test.c | |||
@@ -0,0 +1,123 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2017 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file set/plugin_block_set_test.c | ||
23 | * @brief set test block, recognizes elements with non-zero first byte as invalid | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | |||
27 | #include "platform.h" | ||
28 | #include "gnunet_block_plugin.h" | ||
29 | #include "gnunet_block_group_lib.h" | ||
30 | |||
31 | |||
32 | /** | ||
33 | * Function called to validate a reply or a request. For | ||
34 | * request evaluation, simply pass "NULL" for the reply_block. | ||
35 | * | ||
36 | * @param cls closure | ||
37 | * @param ctx block context | ||
38 | * @param type block type | ||
39 | * @param group block group to use | ||
40 | * @param eo control flags | ||
41 | * @param query original query (hash) | ||
42 | * @param xquery extrended query data (can be NULL, depending on type) | ||
43 | * @param xquery_size number of bytes in xquery | ||
44 | * @param reply_block response to validate | ||
45 | * @param reply_block_size number of bytes in reply block | ||
46 | * @return characterization of result | ||
47 | */ | ||
48 | static enum GNUNET_BLOCK_EvaluationResult | ||
49 | block_plugin_set_test_evaluate (void *cls, | ||
50 | struct GNUNET_BLOCK_Context *ctx, | ||
51 | enum GNUNET_BLOCK_Type type, | ||
52 | struct GNUNET_BLOCK_Group *group, | ||
53 | enum GNUNET_BLOCK_EvaluationOptions eo, | ||
54 | const struct GNUNET_HashCode *query, | ||
55 | const void *xquery, | ||
56 | size_t xquery_size, | ||
57 | const void *reply_block, | ||
58 | size_t reply_block_size) | ||
59 | { | ||
60 | if ( (NULL == reply_block) || | ||
61 | (reply_block_size == 0) || | ||
62 | (0 != ((char *) reply_block)[0]) ) | ||
63 | return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; | ||
64 | return GNUNET_BLOCK_EVALUATION_OK_MORE; | ||
65 | } | ||
66 | |||
67 | |||
68 | /** | ||
69 | * Function called to obtain the key for a block. | ||
70 | * | ||
71 | * @param cls closure | ||
72 | * @param type block type | ||
73 | * @param block block to get the key for | ||
74 | * @param block_size number of bytes in block | ||
75 | * @param key set to the key (query) for the given block | ||
76 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported | ||
77 | * (or if extracting a key from a block of this type does not work) | ||
78 | */ | ||
79 | static int | ||
80 | block_plugin_set_test_get_key (void *cls, | ||
81 | enum GNUNET_BLOCK_Type type, | ||
82 | const void *block, | ||
83 | size_t block_size, | ||
84 | struct GNUNET_HashCode *key) | ||
85 | { | ||
86 | return GNUNET_SYSERR; | ||
87 | } | ||
88 | |||
89 | |||
90 | /** | ||
91 | * Entry point for the plugin. | ||
92 | */ | ||
93 | void * | ||
94 | libgnunet_plugin_block_set_test_init (void *cls) | ||
95 | { | ||
96 | static enum GNUNET_BLOCK_Type types[] = | ||
97 | { | ||
98 | GNUNET_BLOCK_TYPE_SET_TEST, | ||
99 | GNUNET_BLOCK_TYPE_ANY /* end of list */ | ||
100 | }; | ||
101 | struct GNUNET_BLOCK_PluginFunctions *api; | ||
102 | |||
103 | api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions); | ||
104 | api->evaluate = &block_plugin_set_test_evaluate; | ||
105 | api->get_key = &block_plugin_set_test_get_key; | ||
106 | api->types = types; | ||
107 | return api; | ||
108 | } | ||
109 | |||
110 | |||
111 | /** | ||
112 | * Exit point from the plugin. | ||
113 | */ | ||
114 | void * | ||
115 | libgnunet_plugin_block_set_test_done (void *cls) | ||
116 | { | ||
117 | struct GNUNET_BLOCK_PluginFunctions *api = cls; | ||
118 | |||
119 | GNUNET_free (api); | ||
120 | return NULL; | ||
121 | } | ||
122 | |||
123 | /* end of plugin_block_set_test.c */ | ||
diff --git a/src/set/set.h b/src/set/set.h index f31216cb8..258e2bff9 100644 --- a/src/set/set.h +++ b/src/set/set.h | |||
@@ -102,6 +102,30 @@ struct GNUNET_SET_AcceptMessage | |||
102 | * See `enum GNUNET_SET_ResultMode`. | 102 | * See `enum GNUNET_SET_ResultMode`. |
103 | */ | 103 | */ |
104 | uint32_t result_mode GNUNET_PACKED; | 104 | uint32_t result_mode GNUNET_PACKED; |
105 | |||
106 | /** | ||
107 | * Always use delta operation instead of sending full sets, | ||
108 | * even it it's less efficient. | ||
109 | */ | ||
110 | uint8_t force_delta; | ||
111 | |||
112 | /** | ||
113 | * Always send full sets, even if delta operations would | ||
114 | * be more efficient. | ||
115 | */ | ||
116 | uint8_t force_full; | ||
117 | |||
118 | /** | ||
119 | * #GNUNET_YES to fail operations where Byzantine faults | ||
120 | * are suspected | ||
121 | */ | ||
122 | uint8_t byzantine; | ||
123 | |||
124 | /** | ||
125 | * Lower bound for the set size, used only when | ||
126 | * byzantine mode is enabled. | ||
127 | */ | ||
128 | uint8_t byzantine_lower_bound; | ||
105 | }; | 129 | }; |
106 | 130 | ||
107 | 131 | ||
@@ -184,6 +208,30 @@ struct GNUNET_SET_EvaluateMessage | |||
184 | */ | 208 | */ |
185 | uint32_t request_id GNUNET_PACKED; | 209 | uint32_t request_id GNUNET_PACKED; |
186 | 210 | ||
211 | /** | ||
212 | * Always use delta operation instead of sending full sets, | ||
213 | * even it it's less efficient. | ||
214 | */ | ||
215 | uint8_t force_delta; | ||
216 | |||
217 | /** | ||
218 | * Always send full sets, even if delta operations would | ||
219 | * be more efficient. | ||
220 | */ | ||
221 | uint8_t force_full; | ||
222 | |||
223 | /** | ||
224 | * #GNUNET_YES to fail operations where Byzantine faults | ||
225 | * are suspected | ||
226 | */ | ||
227 | uint8_t byzantine; | ||
228 | |||
229 | /** | ||
230 | * Lower bound for the set size, used only when | ||
231 | * byzantine mode is enabled. | ||
232 | */ | ||
233 | uint8_t byzantine_lower_bound; | ||
234 | |||
187 | /* rest: context message, that is, application-specific | 235 | /* rest: context message, that is, application-specific |
188 | message to convince listener to pick up */ | 236 | message to convince listener to pick up */ |
189 | }; | 237 | }; |
@@ -203,6 +251,11 @@ struct GNUNET_SET_ResultMessage | |||
203 | struct GNUNET_MessageHeader header; | 251 | struct GNUNET_MessageHeader header; |
204 | 252 | ||
205 | /** | 253 | /** |
254 | * Current set size. | ||
255 | */ | ||
256 | uint64_t current_size; | ||
257 | |||
258 | /** | ||
206 | * id the result belongs to | 259 | * id the result belongs to |
207 | */ | 260 | */ |
208 | uint32_t request_id GNUNET_PACKED; | 261 | uint32_t request_id GNUNET_PACKED; |
diff --git a/src/set/set_api.c b/src/set/set_api.c index baeee6da0..5b5b1b8ee 100644 --- a/src/set/set_api.c +++ b/src/set/set_api.c | |||
@@ -432,6 +432,7 @@ do_final: | |||
432 | { | 432 | { |
433 | oh->result_cb (oh->result_cls, | 433 | oh->result_cb (oh->result_cls, |
434 | NULL, | 434 | NULL, |
435 | GNUNET_ntohll (msg->current_size), | ||
435 | result_status); | 436 | result_status); |
436 | } | 437 | } |
437 | else | 438 | else |
@@ -453,6 +454,7 @@ do_element: | |||
453 | if (NULL != oh->result_cb) | 454 | if (NULL != oh->result_cb) |
454 | oh->result_cb (oh->result_cls, | 455 | oh->result_cb (oh->result_cls, |
455 | &e, | 456 | &e, |
457 | GNUNET_ntohll (msg->current_size), | ||
456 | result_status); | 458 | result_status); |
457 | } | 459 | } |
458 | 460 | ||
@@ -538,6 +540,7 @@ handle_client_set_error (void *cls, | |||
538 | if (NULL != set->ops_head->result_cb) | 540 | if (NULL != set->ops_head->result_cb) |
539 | set->ops_head->result_cb (set->ops_head->result_cls, | 541 | set->ops_head->result_cb (set->ops_head->result_cls, |
540 | NULL, | 542 | NULL, |
543 | 0, | ||
541 | GNUNET_SET_STATUS_FAILURE); | 544 | GNUNET_SET_STATUS_FAILURE); |
542 | set_operation_destroy (set->ops_head); | 545 | set_operation_destroy (set->ops_head); |
543 | } | 546 | } |
@@ -654,6 +657,8 @@ GNUNET_SET_add_element (struct GNUNET_SET_Handle *set, | |||
654 | struct GNUNET_MQ_Envelope *mqm; | 657 | struct GNUNET_MQ_Envelope *mqm; |
655 | struct GNUNET_SET_ElementMessage *msg; | 658 | struct GNUNET_SET_ElementMessage *msg; |
656 | 659 | ||
660 | LOG (GNUNET_ERROR_TYPE_INFO, "adding element of type %u\n", (unsigned) element->element_type); | ||
661 | |||
657 | if (GNUNET_YES == set->invalid) | 662 | if (GNUNET_YES == set->invalid) |
658 | { | 663 | { |
659 | if (NULL != cont) | 664 | if (NULL != cont) |
@@ -766,12 +771,14 @@ GNUNET_SET_prepare (const struct GNUNET_PeerIdentity *other_peer, | |||
766 | const struct GNUNET_HashCode *app_id, | 771 | const struct GNUNET_HashCode *app_id, |
767 | const struct GNUNET_MessageHeader *context_msg, | 772 | const struct GNUNET_MessageHeader *context_msg, |
768 | enum GNUNET_SET_ResultMode result_mode, | 773 | enum GNUNET_SET_ResultMode result_mode, |
774 | struct GNUNET_SET_Option options[], | ||
769 | GNUNET_SET_ResultIterator result_cb, | 775 | GNUNET_SET_ResultIterator result_cb, |
770 | void *result_cls) | 776 | void *result_cls) |
771 | { | 777 | { |
772 | struct GNUNET_MQ_Envelope *mqm; | 778 | struct GNUNET_MQ_Envelope *mqm; |
773 | struct GNUNET_SET_OperationHandle *oh; | 779 | struct GNUNET_SET_OperationHandle *oh; |
774 | struct GNUNET_SET_EvaluateMessage *msg; | 780 | struct GNUNET_SET_EvaluateMessage *msg; |
781 | struct GNUNET_SET_Option *opt; | ||
775 | 782 | ||
776 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 783 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
777 | "Client prepares set operation (%d)\n", | 784 | "Client prepares set operation (%d)\n", |
@@ -785,6 +792,25 @@ GNUNET_SET_prepare (const struct GNUNET_PeerIdentity *other_peer, | |||
785 | msg->app_id = *app_id; | 792 | msg->app_id = *app_id; |
786 | msg->result_mode = htonl (result_mode); | 793 | msg->result_mode = htonl (result_mode); |
787 | msg->target_peer = *other_peer; | 794 | msg->target_peer = *other_peer; |
795 | for (opt = options; opt->type != 0; opt++) | ||
796 | { | ||
797 | switch (opt->type) | ||
798 | { | ||
799 | case GNUNET_SET_OPTION_BYZANTINE: | ||
800 | msg->byzantine = GNUNET_YES; | ||
801 | msg->byzantine_lower_bound = opt->v.num; | ||
802 | break; | ||
803 | case GNUNET_SET_OPTION_FORCE_FULL: | ||
804 | msg->force_full = GNUNET_YES; | ||
805 | break; | ||
806 | case GNUNET_SET_OPTION_FORCE_DELTA: | ||
807 | msg->force_delta = GNUNET_YES; | ||
808 | break; | ||
809 | default: | ||
810 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
811 | "Option with type %d not recognized\n", (int) opt->type); | ||
812 | } | ||
813 | } | ||
788 | oh->conclude_mqm = mqm; | 814 | oh->conclude_mqm = mqm; |
789 | oh->request_id_addr = &msg->request_id; | 815 | oh->request_id_addr = &msg->request_id; |
790 | 816 | ||
@@ -1006,6 +1032,7 @@ GNUNET_SET_listen_cancel (struct GNUNET_SET_ListenHandle *lh) | |||
1006 | struct GNUNET_SET_OperationHandle * | 1032 | struct GNUNET_SET_OperationHandle * |
1007 | GNUNET_SET_accept (struct GNUNET_SET_Request *request, | 1033 | GNUNET_SET_accept (struct GNUNET_SET_Request *request, |
1008 | enum GNUNET_SET_ResultMode result_mode, | 1034 | enum GNUNET_SET_ResultMode result_mode, |
1035 | struct GNUNET_SET_Option options[], | ||
1009 | GNUNET_SET_ResultIterator result_cb, | 1036 | GNUNET_SET_ResultIterator result_cb, |
1010 | void *result_cls) | 1037 | void *result_cls) |
1011 | { | 1038 | { |
diff --git a/src/set/test_set.conf b/src/set/test_set.conf index 69e7f5c52..e28dfc6e9 100644 --- a/src/set/test_set.conf +++ b/src/set/test_set.conf | |||
@@ -5,7 +5,6 @@ GNUNET_TEST_HOME = /tmp/test-gnunet-set/ | |||
5 | 5 | ||
6 | [set] | 6 | [set] |
7 | AUTOSTART = YES | 7 | AUTOSTART = YES |
8 | # PREFIX = valgrind | ||
9 | #PREFIX = valgrind --leak-check=full | 8 | #PREFIX = valgrind --leak-check=full |
10 | #PREFIX = gdbserver :1234 | 9 | #PREFIX = gdbserver :1234 |
11 | OPTIONS = -L INFO | 10 | OPTIONS = -L INFO |
diff --git a/src/set/test_set_api.c b/src/set/test_set_api.c index 21af45f8a..dd3f004f2 100644 --- a/src/set/test_set_api.c +++ b/src/set/test_set_api.c | |||
@@ -55,6 +55,7 @@ static struct GNUNET_SCHEDULER_Task *tt; | |||
55 | static void | 55 | static void |
56 | result_cb_set1 (void *cls, | 56 | result_cb_set1 (void *cls, |
57 | const struct GNUNET_SET_Element *element, | 57 | const struct GNUNET_SET_Element *element, |
58 | uint64_t size, | ||
58 | enum GNUNET_SET_Status status) | 59 | enum GNUNET_SET_Status status) |
59 | { | 60 | { |
60 | switch (status) | 61 | switch (status) |
@@ -101,6 +102,7 @@ result_cb_set1 (void *cls, | |||
101 | static void | 102 | static void |
102 | result_cb_set2 (void *cls, | 103 | result_cb_set2 (void *cls, |
103 | const struct GNUNET_SET_Element *element, | 104 | const struct GNUNET_SET_Element *element, |
105 | uint64_t size, | ||
104 | enum GNUNET_SET_Status status) | 106 | enum GNUNET_SET_Status status) |
105 | { | 107 | { |
106 | switch (status) | 108 | switch (status) |
@@ -149,6 +151,7 @@ listen_cb (void *cls, | |||
149 | listen_handle = NULL; | 151 | listen_handle = NULL; |
150 | oh2 = GNUNET_SET_accept (request, | 152 | oh2 = GNUNET_SET_accept (request, |
151 | GNUNET_SET_RESULT_ADDED, | 153 | GNUNET_SET_RESULT_ADDED, |
154 | (struct GNUNET_SET_Option[]) { 0 }, | ||
152 | &result_cb_set2, | 155 | &result_cb_set2, |
153 | NULL); | 156 | NULL); |
154 | GNUNET_SET_commit (oh2, | 157 | GNUNET_SET_commit (oh2, |
@@ -179,6 +182,7 @@ start (void *cls) | |||
179 | &app_id, | 182 | &app_id, |
180 | &context_msg, | 183 | &context_msg, |
181 | GNUNET_SET_RESULT_ADDED, | 184 | GNUNET_SET_RESULT_ADDED, |
185 | (struct GNUNET_SET_Option[]) { 0 }, | ||
182 | &result_cb_set1, | 186 | &result_cb_set1, |
183 | NULL); | 187 | NULL); |
184 | GNUNET_SET_commit (oh1, | 188 | GNUNET_SET_commit (oh1, |
@@ -378,6 +382,7 @@ run (void *cls, | |||
378 | &app_id, | 382 | &app_id, |
379 | NULL, | 383 | NULL, |
380 | GNUNET_SET_RESULT_ADDED, | 384 | GNUNET_SET_RESULT_ADDED, |
385 | (struct GNUNET_SET_Option[]) { 0 }, | ||
381 | NULL, | 386 | NULL, |
382 | NULL); | 387 | NULL); |
383 | 388 | ||
diff --git a/src/set/test_set_intersection_result_full.c b/src/set/test_set_intersection_result_full.c index b2d6ce8a9..a36aae4d5 100644 --- a/src/set/test_set_intersection_result_full.c +++ b/src/set/test_set_intersection_result_full.c | |||
@@ -56,6 +56,7 @@ static struct GNUNET_SET_OperationHandle *oh2; | |||
56 | static void | 56 | static void |
57 | result_cb_set1 (void *cls, | 57 | result_cb_set1 (void *cls, |
58 | const struct GNUNET_SET_Element *element, | 58 | const struct GNUNET_SET_Element *element, |
59 | uint64_t current_size, | ||
59 | enum GNUNET_SET_Status status) | 60 | enum GNUNET_SET_Status status) |
60 | { | 61 | { |
61 | static int count; | 62 | static int count; |
@@ -89,6 +90,7 @@ result_cb_set1 (void *cls, | |||
89 | static void | 90 | static void |
90 | result_cb_set2 (void *cls, | 91 | result_cb_set2 (void *cls, |
91 | const struct GNUNET_SET_Element *element, | 92 | const struct GNUNET_SET_Element *element, |
93 | uint64_t current_size, | ||
92 | enum GNUNET_SET_Status status) | 94 | enum GNUNET_SET_Status status) |
93 | { | 95 | { |
94 | static int count; | 96 | static int count; |
@@ -133,6 +135,7 @@ listen_cb (void *cls, | |||
133 | listen_handle = NULL; | 135 | listen_handle = NULL; |
134 | oh2 = GNUNET_SET_accept (request, | 136 | oh2 = GNUNET_SET_accept (request, |
135 | GNUNET_SET_RESULT_FULL, | 137 | GNUNET_SET_RESULT_FULL, |
138 | (struct GNUNET_SET_Option[]) { 0 }, | ||
136 | &result_cb_set2, | 139 | &result_cb_set2, |
137 | NULL); | 140 | NULL); |
138 | GNUNET_SET_commit (oh2, | 141 | GNUNET_SET_commit (oh2, |
@@ -163,6 +166,7 @@ start (void *cls) | |||
163 | &app_id, | 166 | &app_id, |
164 | &context_msg, | 167 | &context_msg, |
165 | GNUNET_SET_RESULT_FULL, | 168 | GNUNET_SET_RESULT_FULL, |
169 | (struct GNUNET_SET_Option[]) { 0 }, | ||
166 | &result_cb_set1, | 170 | &result_cb_set1, |
167 | NULL); | 171 | NULL); |
168 | GNUNET_SET_commit (oh1, | 172 | GNUNET_SET_commit (oh1, |
diff --git a/src/set/test_set_union_result_symmetric.c b/src/set/test_set_union_result_symmetric.c index ab191a34a..f81c7b8f7 100644 --- a/src/set/test_set_union_result_symmetric.c +++ b/src/set/test_set_union_result_symmetric.c | |||
@@ -77,6 +77,7 @@ static struct GNUNET_SCHEDULER_Task *timeout_task; | |||
77 | static void | 77 | static void |
78 | result_cb_set1 (void *cls, | 78 | result_cb_set1 (void *cls, |
79 | const struct GNUNET_SET_Element *element, | 79 | const struct GNUNET_SET_Element *element, |
80 | uint64_t current_size, | ||
80 | enum GNUNET_SET_Status status) | 81 | enum GNUNET_SET_Status status) |
81 | { | 82 | { |
82 | switch (status) | 83 | switch (status) |
@@ -125,6 +126,7 @@ result_cb_set1 (void *cls, | |||
125 | static void | 126 | static void |
126 | result_cb_set2 (void *cls, | 127 | result_cb_set2 (void *cls, |
127 | const struct GNUNET_SET_Element *element, | 128 | const struct GNUNET_SET_Element *element, |
129 | uint64_t current_size, | ||
128 | enum GNUNET_SET_Status status) | 130 | enum GNUNET_SET_Status status) |
129 | { | 131 | { |
130 | switch (status) | 132 | switch (status) |
@@ -184,6 +186,7 @@ listen_cb (void *cls, | |||
184 | listen_handle = NULL; | 186 | listen_handle = NULL; |
185 | oh2 = GNUNET_SET_accept (request, | 187 | oh2 = GNUNET_SET_accept (request, |
186 | GNUNET_SET_RESULT_SYMMETRIC, | 188 | GNUNET_SET_RESULT_SYMMETRIC, |
189 | (struct GNUNET_SET_Option[]) { 0 }, | ||
187 | &result_cb_set2, | 190 | &result_cb_set2, |
188 | NULL); | 191 | NULL); |
189 | GNUNET_SET_commit (oh2, | 192 | GNUNET_SET_commit (oh2, |
@@ -212,6 +215,7 @@ start (void *cls) | |||
212 | &app_id, | 215 | &app_id, |
213 | &context_msg, | 216 | &context_msg, |
214 | GNUNET_SET_RESULT_SYMMETRIC, | 217 | GNUNET_SET_RESULT_SYMMETRIC, |
218 | (struct GNUNET_SET_Option[]) { 0 }, | ||
215 | &result_cb_set1, NULL); | 219 | &result_cb_set1, NULL); |
216 | GNUNET_SET_commit (oh1, set1); | 220 | GNUNET_SET_commit (oh1, set1); |
217 | } | 221 | } |
diff --git a/src/social/gnunet-service-social.c b/src/social/gnunet-service-social.c index e6ee24a4f..dee68fdb8 100644 --- a/src/social/gnunet-service-social.c +++ b/src/social/gnunet-service-social.c | |||
@@ -1955,9 +1955,11 @@ handle_client_guest_enter_by_name (void *cls, | |||
1955 | GNUNET_memcpy (gcls->password, password, password_size); | 1955 | GNUNET_memcpy (gcls->password, password, password_size); |
1956 | } | 1956 | } |
1957 | 1957 | ||
1958 | GNUNET_GNS_lookup (gns, gns_name, &greq->ego_pub_key, | 1958 | GNUNET_GNS_lookup (gns, gns_name, |
1959 | GNUNET_GNSRECORD_TYPE_PLACE, GNUNET_GNS_LO_DEFAULT, | 1959 | &greq->ego_pub_key, |
1960 | NULL, gns_result_guest_enter, gcls); | 1960 | GNUNET_GNSRECORD_TYPE_PLACE, |
1961 | GNUNET_GNS_LO_DEFAULT, | ||
1962 | &gns_result_guest_enter, gcls); | ||
1961 | } | 1963 | } |
1962 | 1964 | ||
1963 | 1965 | ||
diff --git a/src/sq/.gitignore b/src/sq/.gitignore new file mode 100644 index 000000000..951587047 --- /dev/null +++ b/src/sq/.gitignore | |||
@@ -0,0 +1 @@ | |||
test_sq | |||
diff --git a/src/sq/Makefile.am b/src/sq/Makefile.am new file mode 100644 index 000000000..c5f80bcf6 --- /dev/null +++ b/src/sq/Makefile.am | |||
@@ -0,0 +1,40 @@ | |||
1 | # This Makefile.am is in the public domain | ||
2 | AM_CPPFLAGS = -I$(top_srcdir)/src/include $(POSTGRESQL_CPPFLAGS) | ||
3 | |||
4 | if MINGW | ||
5 | WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols | ||
6 | endif | ||
7 | |||
8 | if USE_COVERAGE | ||
9 | AM_CFLAGS = --coverage | ||
10 | endif | ||
11 | |||
12 | if HAVE_POSTGRESQL | ||
13 | lib_LTLIBRARIES = libgnunetsq.la | ||
14 | endif | ||
15 | |||
16 | libgnunetsq_la_SOURCES = \ | ||
17 | sq.c \ | ||
18 | sq_query_helper.c \ | ||
19 | sq_result_helper.c | ||
20 | libgnunetsq_la_LIBADD = -lsqlite3 \ | ||
21 | $(top_builddir)/src/util/libgnunetutil.la | ||
22 | libgnunetsq_la_LDFLAGS = \ | ||
23 | $(POSTGRESQL_LDFLAGS) \ | ||
24 | $(GN_LIB_LDFLAGS) \ | ||
25 | -version-info 0:0:0 | ||
26 | |||
27 | if ENABLE_TEST_RUN | ||
28 | TESTS = \ | ||
29 | test_sq | ||
30 | endif | ||
31 | |||
32 | check_PROGRAMS= \ | ||
33 | test_sq | ||
34 | |||
35 | test_sq_SOURCES = \ | ||
36 | test_sq.c | ||
37 | test_sq_LDADD = \ | ||
38 | libgnunetsq.la \ | ||
39 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
40 | -lsqlite3 $(XLIB) | ||
diff --git a/src/sq/sq.c b/src/sq/sq.c new file mode 100644 index 000000000..dc4416761 --- /dev/null +++ b/src/sq/sq.c | |||
@@ -0,0 +1,108 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2017 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify it under the | ||
6 | terms of the GNU General Public License as published by the Free Software | ||
7 | Foundation; either version 3, or (at your option) any later version. | ||
8 | |||
9 | GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY | ||
10 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
11 | A PARTICULAR PURPOSE. See the GNU General Public License for more details. | ||
12 | |||
13 | You should have received a copy of the GNU General Public License along with | ||
14 | GNUnet; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/> | ||
15 | */ | ||
16 | /** | ||
17 | * @file sq/sq.c | ||
18 | * @brief helper functions for Sqlite3 DB interactions | ||
19 | * @author Christian Grothoff | ||
20 | */ | ||
21 | #include "platform.h" | ||
22 | #include "gnunet_sq_lib.h" | ||
23 | |||
24 | |||
25 | /** | ||
26 | * Execute a prepared statement. | ||
27 | * | ||
28 | * @param db_conn database connection | ||
29 | * @param params parameters to the statement | ||
30 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
31 | */ | ||
32 | int | ||
33 | GNUNET_SQ_bind (sqlite3_stmt *stmt, | ||
34 | const struct GNUNET_SQ_QueryParam *params) | ||
35 | { | ||
36 | unsigned int j; | ||
37 | |||
38 | j = 1; | ||
39 | for (unsigned int i=0;NULL != params[i].conv; i++) | ||
40 | { | ||
41 | if (GNUNET_OK != | ||
42 | params[i].conv (params[i].conv_cls, | ||
43 | params[i].data, | ||
44 | params[i].size, | ||
45 | stmt, | ||
46 | j)) | ||
47 | { | ||
48 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, | ||
49 | "sq", | ||
50 | _("Failure to bind %u-th SQL parameter\n"), | ||
51 | i); | ||
52 | return GNUNET_SYSERR; | ||
53 | } | ||
54 | GNUNET_assert (0 != params[i].num_params); | ||
55 | j += params[i].num_params; | ||
56 | } | ||
57 | return GNUNET_OK; | ||
58 | } | ||
59 | |||
60 | |||
61 | /** | ||
62 | * Extract results from a query result according to the given specification. | ||
63 | * | ||
64 | * @param result result to process | ||
65 | * @param[in,out] rs result specification to extract for | ||
66 | * @return | ||
67 | * #GNUNET_OK if all results could be extracted | ||
68 | * #GNUNET_SYSERR if a result was invalid (non-existing field) | ||
69 | */ | ||
70 | int | ||
71 | GNUNET_SQ_extract_result (sqlite3_stmt *result, | ||
72 | struct GNUNET_SQ_ResultSpec *rs) | ||
73 | { | ||
74 | unsigned int j = 0; | ||
75 | |||
76 | for (unsigned int i=0;NULL != rs[i].conv; i++) | ||
77 | { | ||
78 | if (NULL == rs[i].result_size) | ||
79 | rs[i].result_size = &rs[i].dst_size; | ||
80 | if (GNUNET_OK != | ||
81 | rs[i].conv (rs[i].cls, | ||
82 | result, | ||
83 | j, | ||
84 | rs[i].result_size, | ||
85 | rs[i].dst)) | ||
86 | return GNUNET_SYSERR; | ||
87 | GNUNET_assert (0 != rs[i].num_params); | ||
88 | j += rs[i].num_params; | ||
89 | } | ||
90 | return GNUNET_OK; | ||
91 | } | ||
92 | |||
93 | |||
94 | /** | ||
95 | * Free all memory that was allocated in @a rs during | ||
96 | * #GNUNET_SQ_extract_result(). | ||
97 | * | ||
98 | * @param rs reult specification to clean up | ||
99 | */ | ||
100 | void | ||
101 | GNUNET_SQ_cleanup_result (struct GNUNET_SQ_ResultSpec *rs) | ||
102 | { | ||
103 | for (unsigned int i=0;NULL != rs[i].conv; i++) | ||
104 | if (NULL != rs[i].cleaner) | ||
105 | rs[i].cleaner (rs[i].cls); | ||
106 | } | ||
107 | |||
108 | /* end of sq.c */ | ||
diff --git a/src/sq/sq_query_helper.c b/src/sq/sq_query_helper.c new file mode 100644 index 000000000..5529c5e6c --- /dev/null +++ b/src/sq/sq_query_helper.c | |||
@@ -0,0 +1,443 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2017 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify it under the | ||
6 | terms of the GNU General Public License as published by the Free Software | ||
7 | Foundation; either version 3, or (at your option) any later version. | ||
8 | |||
9 | GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY | ||
10 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
11 | A PARTICULAR PURPOSE. See the GNU General Public License for more details. | ||
12 | |||
13 | You should have received a copy of the GNU General Public License along with | ||
14 | GNUnet; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/> | ||
15 | */ | ||
16 | /** | ||
17 | * @file sq/sq_query_helper.c | ||
18 | * @brief helper functions for queries | ||
19 | * @author Christian Grothoff | ||
20 | */ | ||
21 | #include "platform.h" | ||
22 | #include "gnunet_sq_lib.h" | ||
23 | |||
24 | |||
25 | /** | ||
26 | * Function called to convert input argument into SQL parameters. | ||
27 | * | ||
28 | * @param cls closure | ||
29 | * @param data pointer to input argument | ||
30 | * @param data_len number of bytes in @a data (if applicable) | ||
31 | * @param stmt sqlite statement to bind parameters for | ||
32 | * @param off offset of the argument to bind in @a stmt, numbered from 1, | ||
33 | * so immediately suitable for passing to `sqlite3_bind`-functions. | ||
34 | * @return #GNUNET_SYSERR on error, #GNUNET_OK on success | ||
35 | */ | ||
36 | static int | ||
37 | bind_fixed_blob (void *cls, | ||
38 | const void *data, | ||
39 | size_t data_len, | ||
40 | sqlite3_stmt *stmt, | ||
41 | unsigned int off) | ||
42 | { | ||
43 | if (SQLITE_OK != | ||
44 | sqlite3_bind_blob64 (stmt, | ||
45 | (int) off, | ||
46 | data, | ||
47 | (sqlite3_uint64) data_len, | ||
48 | SQLITE_TRANSIENT)) | ||
49 | return GNUNET_SYSERR; | ||
50 | return GNUNET_OK; | ||
51 | } | ||
52 | |||
53 | |||
54 | /** | ||
55 | * Generate query parameter for a buffer @a ptr of | ||
56 | * @a ptr_size bytes. | ||
57 | * | ||
58 | * @param ptr pointer to the query parameter to pass | ||
59 | * @oaran ptr_size number of bytes in @a ptr | ||
60 | */ | ||
61 | struct GNUNET_SQ_QueryParam | ||
62 | GNUNET_SQ_query_param_fixed_size (const void *ptr, | ||
63 | size_t ptr_size) | ||
64 | { | ||
65 | struct GNUNET_SQ_QueryParam qp = { | ||
66 | .conv = &bind_fixed_blob, | ||
67 | .data = ptr, | ||
68 | .size = ptr_size, | ||
69 | .num_params = 1 | ||
70 | }; | ||
71 | return qp; | ||
72 | } | ||
73 | |||
74 | |||
75 | /** | ||
76 | * Function called to convert input argument into SQL parameters. | ||
77 | * | ||
78 | * @param cls closure | ||
79 | * @param data pointer to input argument | ||
80 | * @param data_len number of bytes in @a data (if applicable) | ||
81 | * @param stmt sqlite statement to bind parameters for | ||
82 | * @param off offset of the argument to bind in @a stmt, numbered from 1, | ||
83 | * so immediately suitable for passing to `sqlite3_bind`-functions. | ||
84 | * @return #GNUNET_SYSERR on error, #GNUNET_OK on success | ||
85 | */ | ||
86 | static int | ||
87 | bind_string (void *cls, | ||
88 | const void *data, | ||
89 | size_t data_len, | ||
90 | sqlite3_stmt *stmt, | ||
91 | unsigned int off) | ||
92 | { | ||
93 | if (SQLITE_OK != | ||
94 | sqlite3_bind_text (stmt, | ||
95 | (int) off, | ||
96 | (const char *) data, | ||
97 | -1, | ||
98 | SQLITE_TRANSIENT)) | ||
99 | return GNUNET_SYSERR; | ||
100 | return GNUNET_OK; | ||
101 | } | ||
102 | |||
103 | |||
104 | /** | ||
105 | * Generate query parameter for a string. | ||
106 | * | ||
107 | * @param ptr pointer to the string query parameter to pass | ||
108 | */ | ||
109 | struct GNUNET_SQ_QueryParam | ||
110 | GNUNET_SQ_query_param_string (const char *ptr) | ||
111 | { | ||
112 | struct GNUNET_SQ_QueryParam qp = { | ||
113 | .conv = &bind_string, | ||
114 | .data = ptr, | ||
115 | .num_params = 1 | ||
116 | }; | ||
117 | return qp; | ||
118 | } | ||
119 | |||
120 | |||
121 | /** | ||
122 | * Function called to convert input argument into SQL parameters. | ||
123 | * | ||
124 | * @param cls closure | ||
125 | * @param data pointer to input argument | ||
126 | * @param data_len number of bytes in @a data (if applicable) | ||
127 | * @param stmt sqlite statement to bind parameters for | ||
128 | * @param off offset of the argument to bind in @a stmt, numbered from 1, | ||
129 | * so immediately suitable for passing to `sqlite3_bind`-functions. | ||
130 | * @return #GNUNET_SYSERR on error, #GNUNET_OK on success | ||
131 | */ | ||
132 | static int | ||
133 | bind_rsa_pub (void *cls, | ||
134 | const void *data, | ||
135 | size_t data_len, | ||
136 | sqlite3_stmt *stmt, | ||
137 | unsigned int off) | ||
138 | { | ||
139 | const struct GNUNET_CRYPTO_RsaPublicKey *rsa = data; | ||
140 | char *buf; | ||
141 | size_t buf_size; | ||
142 | |||
143 | GNUNET_break (NULL == cls); | ||
144 | buf_size = GNUNET_CRYPTO_rsa_public_key_encode (rsa, | ||
145 | &buf); | ||
146 | if (SQLITE_OK != | ||
147 | sqlite3_bind_blob64 (stmt, | ||
148 | (int) off, | ||
149 | buf, | ||
150 | (sqlite3_uint64) buf_size, | ||
151 | SQLITE_TRANSIENT)) | ||
152 | { | ||
153 | GNUNET_free (buf); | ||
154 | return GNUNET_SYSERR; | ||
155 | } | ||
156 | GNUNET_free (buf); | ||
157 | return GNUNET_OK; | ||
158 | } | ||
159 | |||
160 | |||
161 | /** | ||
162 | * Generate query parameter for an RSA public key. The | ||
163 | * database must contain a BLOB type in the respective position. | ||
164 | * | ||
165 | * @param x the query parameter to pass. | ||
166 | */ | ||
167 | struct GNUNET_SQ_QueryParam | ||
168 | GNUNET_SQ_query_param_rsa_public_key (const struct GNUNET_CRYPTO_RsaPublicKey *x) | ||
169 | { | ||
170 | struct GNUNET_SQ_QueryParam qp = { | ||
171 | .conv = &bind_rsa_pub, | ||
172 | .data = x, | ||
173 | .num_params = 1 | ||
174 | }; | ||
175 | return qp; | ||
176 | } | ||
177 | |||
178 | |||
179 | /** | ||
180 | * Function called to convert input argument into SQL parameters. | ||
181 | * | ||
182 | * @param cls closure | ||
183 | * @param data pointer to input argument | ||
184 | * @param data_len number of bytes in @a data (if applicable) | ||
185 | * @param stmt sqlite statement to bind parameters for | ||
186 | * @param off offset of the argument to bind in @a stmt, numbered from 1, | ||
187 | * so immediately suitable for passing to `sqlite3_bind`-functions. | ||
188 | * @return #GNUNET_SYSERR on error, #GNUNET_OK on success | ||
189 | */ | ||
190 | static int | ||
191 | bind_rsa_sig (void *cls, | ||
192 | const void *data, | ||
193 | size_t data_len, | ||
194 | sqlite3_stmt *stmt, | ||
195 | unsigned int off) | ||
196 | { | ||
197 | const struct GNUNET_CRYPTO_RsaSignature *sig = data; | ||
198 | char *buf; | ||
199 | size_t buf_size; | ||
200 | |||
201 | GNUNET_break (NULL == cls); | ||
202 | buf_size = GNUNET_CRYPTO_rsa_signature_encode (sig, | ||
203 | &buf); | ||
204 | if (SQLITE_OK != | ||
205 | sqlite3_bind_blob64 (stmt, | ||
206 | (int) off, | ||
207 | buf, | ||
208 | (sqlite3_uint64) buf_size, | ||
209 | SQLITE_TRANSIENT)) | ||
210 | { | ||
211 | GNUNET_free (buf); | ||
212 | return GNUNET_SYSERR; | ||
213 | } | ||
214 | GNUNET_free (buf); | ||
215 | return GNUNET_OK; | ||
216 | } | ||
217 | |||
218 | |||
219 | /** | ||
220 | * Generate query parameter for an RSA signature. The | ||
221 | * database must contain a BLOB type in the respective position. | ||
222 | * | ||
223 | * @param x the query parameter to pass | ||
224 | */ | ||
225 | struct GNUNET_SQ_QueryParam | ||
226 | GNUNET_SQ_query_param_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *x) | ||
227 | { | ||
228 | struct GNUNET_SQ_QueryParam qp = { | ||
229 | .conv = &bind_rsa_sig, | ||
230 | .data = x, | ||
231 | .num_params = 1 | ||
232 | }; | ||
233 | return qp; | ||
234 | } | ||
235 | |||
236 | |||
237 | /** | ||
238 | * Generate query parameter for an absolute time value. | ||
239 | * The database must store a 64-bit integer. | ||
240 | * | ||
241 | * @param x pointer to the query parameter to pass | ||
242 | */ | ||
243 | struct GNUNET_SQ_QueryParam | ||
244 | GNUNET_SQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x) | ||
245 | { | ||
246 | return GNUNET_SQ_query_param_uint64 (&x->abs_value_us); | ||
247 | } | ||
248 | |||
249 | |||
250 | /** | ||
251 | * Function called to convert input argument into SQL parameters. | ||
252 | * | ||
253 | * @param cls closure | ||
254 | * @param data pointer to input argument | ||
255 | * @param data_len number of bytes in @a data (if applicable) | ||
256 | * @param stmt sqlite statement to bind parameters for | ||
257 | * @param off offset of the argument to bind in @a stmt, numbered from 1, | ||
258 | * so immediately suitable for passing to `sqlite3_bind`-functions. | ||
259 | * @return #GNUNET_SYSERR on error, #GNUNET_OK on success | ||
260 | */ | ||
261 | static int | ||
262 | bind_nbotime (void *cls, | ||
263 | const void *data, | ||
264 | size_t data_len, | ||
265 | sqlite3_stmt *stmt, | ||
266 | unsigned int off) | ||
267 | { | ||
268 | const struct GNUNET_TIME_AbsoluteNBO *u = data; | ||
269 | struct GNUNET_TIME_Absolute abs; | ||
270 | |||
271 | abs = GNUNET_TIME_absolute_ntoh (*u); | ||
272 | GNUNET_assert (sizeof (uint64_t) == data_len); | ||
273 | if (SQLITE_OK != | ||
274 | sqlite3_bind_int64 (stmt, | ||
275 | (int) off, | ||
276 | (sqlite3_int64) abs.abs_value_us)) | ||
277 | return GNUNET_SYSERR; | ||
278 | return GNUNET_OK; | ||
279 | } | ||
280 | |||
281 | |||
282 | /** | ||
283 | * Generate query parameter for an absolute time value. | ||
284 | * The database must store a 64-bit integer. | ||
285 | * | ||
286 | * @param x pointer to the query parameter to pass | ||
287 | */ | ||
288 | struct GNUNET_SQ_QueryParam | ||
289 | GNUNET_SQ_query_param_absolute_time_nbo (const struct GNUNET_TIME_AbsoluteNBO *x) | ||
290 | { | ||
291 | struct GNUNET_SQ_QueryParam qp = { | ||
292 | .conv = &bind_nbotime, | ||
293 | .data = x, | ||
294 | .size = sizeof (struct GNUNET_TIME_AbsoluteNBO), | ||
295 | .num_params = 1 | ||
296 | }; | ||
297 | return qp; | ||
298 | } | ||
299 | |||
300 | |||
301 | /** | ||
302 | * Function called to convert input argument into SQL parameters. | ||
303 | * | ||
304 | * @param cls closure | ||
305 | * @param data pointer to input argument | ||
306 | * @param data_len number of bytes in @a data (if applicable) | ||
307 | * @param stmt sqlite statement to bind parameters for | ||
308 | * @param off offset of the argument to bind in @a stmt, numbered from 1, | ||
309 | * so immediately suitable for passing to `sqlite3_bind`-functions. | ||
310 | * @return #GNUNET_SYSERR on error, #GNUNET_OK on success | ||
311 | */ | ||
312 | static int | ||
313 | bind_u16 (void *cls, | ||
314 | const void *data, | ||
315 | size_t data_len, | ||
316 | sqlite3_stmt *stmt, | ||
317 | unsigned int off) | ||
318 | { | ||
319 | const uint16_t *u = data; | ||
320 | |||
321 | GNUNET_assert (sizeof (uint16_t) == data_len); | ||
322 | if (SQLITE_OK != | ||
323 | sqlite3_bind_int (stmt, | ||
324 | (int) off, | ||
325 | (int) *u)) | ||
326 | return GNUNET_SYSERR; | ||
327 | return GNUNET_OK; | ||
328 | } | ||
329 | |||
330 | |||
331 | /** | ||
332 | * Generate query parameter for an uint16_t in host byte order. | ||
333 | * | ||
334 | * @param x pointer to the query parameter to pass | ||
335 | */ | ||
336 | struct GNUNET_SQ_QueryParam | ||
337 | GNUNET_SQ_query_param_uint16 (const uint16_t *x) | ||
338 | { | ||
339 | struct GNUNET_SQ_QueryParam qp = { | ||
340 | .conv = &bind_u16, | ||
341 | .data = x, | ||
342 | .size = sizeof (uint16_t), | ||
343 | .num_params = 1 | ||
344 | }; | ||
345 | return qp; | ||
346 | } | ||
347 | |||
348 | |||
349 | /** | ||
350 | * Function called to convert input argument into SQL parameters. | ||
351 | * | ||
352 | * @param cls closure | ||
353 | * @param data pointer to input argument | ||
354 | * @param data_len number of bytes in @a data (if applicable) | ||
355 | * @param stmt sqlite statement to bind parameters for | ||
356 | * @param off offset of the argument to bind in @a stmt, numbered from 1, | ||
357 | * so immediately suitable for passing to `sqlite3_bind`-functions. | ||
358 | * @return #GNUNET_SYSERR on error, #GNUNET_OK on success | ||
359 | */ | ||
360 | static int | ||
361 | bind_u32 (void *cls, | ||
362 | const void *data, | ||
363 | size_t data_len, | ||
364 | sqlite3_stmt *stmt, | ||
365 | unsigned int off) | ||
366 | { | ||
367 | const uint32_t *u = data; | ||
368 | |||
369 | GNUNET_assert (sizeof (uint32_t) == data_len); | ||
370 | if (SQLITE_OK != | ||
371 | sqlite3_bind_int64 (stmt, | ||
372 | (int) off, | ||
373 | (sqlite3_int64) *u)) | ||
374 | return GNUNET_SYSERR; | ||
375 | return GNUNET_OK; | ||
376 | } | ||
377 | |||
378 | /** | ||
379 | * Generate query parameter for an uint32_t in host byte order. | ||
380 | * | ||
381 | * @param x pointer to the query parameter to pass | ||
382 | */ | ||
383 | struct GNUNET_SQ_QueryParam | ||
384 | GNUNET_SQ_query_param_uint32 (const uint32_t *x) | ||
385 | { | ||
386 | struct GNUNET_SQ_QueryParam qp = { | ||
387 | .conv = &bind_u32, | ||
388 | .data = x, | ||
389 | .size = sizeof (uint32_t), | ||
390 | .num_params = 1 | ||
391 | }; | ||
392 | return qp; | ||
393 | } | ||
394 | |||
395 | |||
396 | /** | ||
397 | * Function called to convert input argument into SQL parameters. | ||
398 | * | ||
399 | * @param cls closure | ||
400 | * @param data pointer to input argument | ||
401 | * @param data_len number of bytes in @a data (if applicable) | ||
402 | * @param stmt sqlite statement to bind parameters for | ||
403 | * @param off offset of the argument to bind in @a stmt, numbered from 1, | ||
404 | * so immediately suitable for passing to `sqlite3_bind`-functions. | ||
405 | * @return #GNUNET_SYSERR on error, #GNUNET_OK on success | ||
406 | */ | ||
407 | static int | ||
408 | bind_u64 (void *cls, | ||
409 | const void *data, | ||
410 | size_t data_len, | ||
411 | sqlite3_stmt *stmt, | ||
412 | unsigned int off) | ||
413 | { | ||
414 | const uint64_t *u = data; | ||
415 | |||
416 | GNUNET_assert (sizeof (uint64_t) == data_len); | ||
417 | if (SQLITE_OK != | ||
418 | sqlite3_bind_int64 (stmt, | ||
419 | (int) off, | ||
420 | (sqlite3_int64) *u)) | ||
421 | return GNUNET_SYSERR; | ||
422 | return GNUNET_OK; | ||
423 | } | ||
424 | |||
425 | |||
426 | /** | ||
427 | * Generate query parameter for an uint16_t in host byte order. | ||
428 | * | ||
429 | * @param x pointer to the query parameter to pass | ||
430 | */ | ||
431 | struct GNUNET_SQ_QueryParam | ||
432 | GNUNET_SQ_query_param_uint64 (const uint64_t *x) | ||
433 | { | ||
434 | struct GNUNET_SQ_QueryParam qp = { | ||
435 | .conv = &bind_u64, | ||
436 | .data = x, | ||
437 | .size = sizeof (uint64_t), | ||
438 | .num_params = 1 | ||
439 | }; | ||
440 | return qp; | ||
441 | } | ||
442 | |||
443 | /* end of sq_query_helper.c */ | ||
diff --git a/src/sq/sq_result_helper.c b/src/sq/sq_result_helper.c new file mode 100644 index 000000000..eaf606aa4 --- /dev/null +++ b/src/sq/sq_result_helper.c | |||
@@ -0,0 +1,710 @@ | |||
1 | |||
2 | /* | ||
3 | This file is part of GNUnet | ||
4 | Copyright (C) 2017 GNUnet e.V. | ||
5 | |||
6 | GNUnet is free software; you can redistribute it and/or modify it under the | ||
7 | terms of the GNU General Public License as published by the Free Software | ||
8 | Foundation; either version 3, or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY | ||
11 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
12 | A PARTICULAR PURPOSE. See the GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License along with | ||
15 | GNUnet; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/> | ||
16 | */ | ||
17 | /** | ||
18 | * @file sq/sq_result_helper.c | ||
19 | * @brief helper functions for queries | ||
20 | * @author Christian Grothoff | ||
21 | */ | ||
22 | #include "platform.h" | ||
23 | #include "gnunet_sq_lib.h" | ||
24 | |||
25 | |||
26 | /** | ||
27 | * Extract variable-sized binary data from a Postgres database @a result at row @a row. | ||
28 | * | ||
29 | * @param cls closure | ||
30 | * @param result where to extract data from | ||
31 | * @param column column to extract data from | ||
32 | * @param[in,out] dst_size where to store size of result, may be NULL | ||
33 | * @param[out] dst where to store the result (actually a `void **`) | ||
34 | * @return | ||
35 | * #GNUNET_YES if all results could be extracted | ||
36 | * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) | ||
37 | */ | ||
38 | static int | ||
39 | extract_var_blob (void *cls, | ||
40 | sqlite3_stmt *result, | ||
41 | unsigned int column, | ||
42 | size_t *dst_size, | ||
43 | void *dst) | ||
44 | { | ||
45 | int have; | ||
46 | const void *ret; | ||
47 | void **rdst = (void **) dst; | ||
48 | |||
49 | if (SQLITE_BLOB != | ||
50 | sqlite3_column_type (result, | ||
51 | column)) | ||
52 | { | ||
53 | GNUNET_break (0); | ||
54 | return GNUNET_SYSERR; | ||
55 | } | ||
56 | /* sqlite manual says to invoke 'sqlite3_column_blob()' | ||
57 | before calling sqlite3_column_bytes() */ | ||
58 | ret = sqlite3_column_blob (result, | ||
59 | column); | ||
60 | have = sqlite3_column_bytes (result, | ||
61 | column); | ||
62 | if (have < 0) | ||
63 | { | ||
64 | GNUNET_break (0); | ||
65 | return GNUNET_SYSERR; | ||
66 | } | ||
67 | *dst_size = have; | ||
68 | if (0 == have) | ||
69 | { | ||
70 | *rdst = NULL; | ||
71 | return GNUNET_OK; | ||
72 | } | ||
73 | *rdst = GNUNET_malloc (have); | ||
74 | GNUNET_memcpy (*rdst, | ||
75 | ret, | ||
76 | have); | ||
77 | return GNUNET_OK; | ||
78 | } | ||
79 | |||
80 | |||
81 | /** | ||
82 | * Cleanup memory allocated by #extract_var_blob(). | ||
83 | * | ||
84 | * @param cls pointer to pointer of allocation | ||
85 | */ | ||
86 | static void | ||
87 | clean_var_blob (void *cls) | ||
88 | { | ||
89 | void **dptr = (void **) cls; | ||
90 | |||
91 | if (NULL != *dptr) | ||
92 | { | ||
93 | GNUNET_free (*dptr); | ||
94 | *dptr = NULL; | ||
95 | } | ||
96 | } | ||
97 | |||
98 | |||
99 | /** | ||
100 | * Variable-size result expected. | ||
101 | * | ||
102 | * @param[out] dst where to store the result, allocated | ||
103 | * @param[out] sptr where to store the size of @a dst | ||
104 | * @return array entry for the result specification to use | ||
105 | */ | ||
106 | struct GNUNET_SQ_ResultSpec | ||
107 | GNUNET_SQ_result_spec_variable_size (void **dst, | ||
108 | size_t *sptr) | ||
109 | { | ||
110 | struct GNUNET_SQ_ResultSpec rs = { | ||
111 | .conv = &extract_var_blob, | ||
112 | .cleaner = &clean_var_blob, | ||
113 | .dst = dst, | ||
114 | .cls = dst, | ||
115 | .result_size = sptr, | ||
116 | .num_params = 1 | ||
117 | }; | ||
118 | |||
119 | return rs; | ||
120 | } | ||
121 | |||
122 | |||
123 | /** | ||
124 | * Extract fixed-sized binary data from a Postgres database @a result at row @a row. | ||
125 | * | ||
126 | * @param cls closure | ||
127 | * @param result where to extract data from | ||
128 | * @param column column to extract data from | ||
129 | * @param[in,out] dst_size where to store size of result, may be NULL | ||
130 | * @param[out] dst where to store the result | ||
131 | * @return | ||
132 | * #GNUNET_YES if all results could be extracted | ||
133 | * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) | ||
134 | */ | ||
135 | static int | ||
136 | extract_fixed_blob (void *cls, | ||
137 | sqlite3_stmt *result, | ||
138 | unsigned int column, | ||
139 | size_t *dst_size, | ||
140 | void *dst) | ||
141 | { | ||
142 | int have; | ||
143 | const void *ret; | ||
144 | |||
145 | if (SQLITE_BLOB != | ||
146 | sqlite3_column_type (result, | ||
147 | column)) | ||
148 | { | ||
149 | GNUNET_break (0); | ||
150 | return GNUNET_SYSERR; | ||
151 | } | ||
152 | /* sqlite manual says to invoke 'sqlite3_column_blob()' | ||
153 | before calling sqlite3_column_bytes() */ | ||
154 | ret = sqlite3_column_blob (result, | ||
155 | column); | ||
156 | have = sqlite3_column_bytes (result, | ||
157 | column); | ||
158 | if (*dst_size != have) | ||
159 | { | ||
160 | GNUNET_break (0); | ||
161 | return GNUNET_SYSERR; | ||
162 | } | ||
163 | GNUNET_memcpy (dst, | ||
164 | ret, | ||
165 | have); | ||
166 | return GNUNET_OK; | ||
167 | } | ||
168 | |||
169 | |||
170 | /** | ||
171 | * Fixed-size result expected. | ||
172 | * | ||
173 | * @param[out] dst where to store the result | ||
174 | * @param dst_size number of bytes in @a dst | ||
175 | * @return array entry for the result specification to use | ||
176 | */ | ||
177 | struct GNUNET_SQ_ResultSpec | ||
178 | GNUNET_SQ_result_spec_fixed_size (void *dst, | ||
179 | size_t dst_size) | ||
180 | { | ||
181 | struct GNUNET_SQ_ResultSpec rs = { | ||
182 | .conv = &extract_fixed_blob, | ||
183 | .dst = dst, | ||
184 | .dst_size = dst_size, | ||
185 | .num_params = 1 | ||
186 | }; | ||
187 | |||
188 | return rs; | ||
189 | } | ||
190 | |||
191 | |||
192 | /** | ||
193 | * Extract fixed-sized binary data from a Postgres database @a result at row @a row. | ||
194 | * | ||
195 | * @param cls closure | ||
196 | * @param result where to extract data from | ||
197 | * @param column column to extract data from | ||
198 | * @param[in,out] dst_size where to store size of result, may be NULL | ||
199 | * @param[out] dst where to store the result | ||
200 | * @return | ||
201 | * #GNUNET_YES if all results could be extracted | ||
202 | * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) | ||
203 | */ | ||
204 | static int | ||
205 | extract_utf8_string (void *cls, | ||
206 | sqlite3_stmt *result, | ||
207 | unsigned int column, | ||
208 | size_t *dst_size, | ||
209 | void *dst) | ||
210 | { | ||
211 | const char *text; | ||
212 | char **rdst = dst; | ||
213 | |||
214 | if (SQLITE_TEXT != | ||
215 | sqlite3_column_type (result, | ||
216 | column)) | ||
217 | { | ||
218 | GNUNET_break (0); | ||
219 | return GNUNET_SYSERR; | ||
220 | } | ||
221 | /* sqlite manual guarantees that 'sqlite3_column_text()' | ||
222 | is 0-terminated */ | ||
223 | text = (const char *) sqlite3_column_text (result, | ||
224 | column); | ||
225 | if (NULL == text) | ||
226 | { | ||
227 | GNUNET_break (0); | ||
228 | return GNUNET_SYSERR; | ||
229 | } | ||
230 | *dst_size = strlen (text) + 1; | ||
231 | *rdst = GNUNET_strdup (text); | ||
232 | return GNUNET_OK; | ||
233 | } | ||
234 | |||
235 | |||
236 | /** | ||
237 | * Cleanup memory allocated by #extract_var_blob(). | ||
238 | * | ||
239 | * @param cls pointer to pointer of allocation | ||
240 | */ | ||
241 | static void | ||
242 | clean_utf8_string (void *cls) | ||
243 | { | ||
244 | char **dptr = (char **) cls; | ||
245 | |||
246 | if (NULL != *dptr) | ||
247 | { | ||
248 | GNUNET_free (*dptr); | ||
249 | *dptr = NULL; | ||
250 | } | ||
251 | } | ||
252 | |||
253 | |||
254 | /** | ||
255 | * 0-terminated string expected. | ||
256 | * | ||
257 | * @param[out] dst where to store the result, allocated | ||
258 | * @return array entry for the result specification to use | ||
259 | */ | ||
260 | struct GNUNET_SQ_ResultSpec | ||
261 | GNUNET_SQ_result_spec_string (char **dst) | ||
262 | { | ||
263 | struct GNUNET_SQ_ResultSpec rs = { | ||
264 | .conv = &extract_utf8_string, | ||
265 | .cleaner = &clean_utf8_string, | ||
266 | .cls = dst, | ||
267 | .dst = dst, | ||
268 | .num_params = 1 | ||
269 | }; | ||
270 | |||
271 | return rs; | ||
272 | } | ||
273 | |||
274 | |||
275 | /** | ||
276 | * Extract data from a Postgres database @a result at row @a row. | ||
277 | * | ||
278 | * @param cls closure | ||
279 | * @param result where to extract data from | ||
280 | * @param column column to extract data from | ||
281 | * @param[in,out] dst_size where to store size of result, may be NULL | ||
282 | * @param[out] dst where to store the result | ||
283 | * @return | ||
284 | * #GNUNET_YES if all results could be extracted | ||
285 | * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) | ||
286 | */ | ||
287 | static int | ||
288 | extract_rsa_pub (void *cls, | ||
289 | sqlite3_stmt *result, | ||
290 | unsigned int column, | ||
291 | size_t *dst_size, | ||
292 | void *dst) | ||
293 | { | ||
294 | struct GNUNET_CRYPTO_RsaPublicKey **pk = dst; | ||
295 | int have; | ||
296 | const void *ret; | ||
297 | |||
298 | if (SQLITE_BLOB != | ||
299 | sqlite3_column_type (result, | ||
300 | column)) | ||
301 | { | ||
302 | GNUNET_break (0); | ||
303 | return GNUNET_SYSERR; | ||
304 | } | ||
305 | /* sqlite manual says to invoke 'sqlite3_column_blob()' | ||
306 | before calling sqlite3_column_bytes() */ | ||
307 | ret = sqlite3_column_blob (result, | ||
308 | column); | ||
309 | have = sqlite3_column_bytes (result, | ||
310 | column); | ||
311 | if (have < 0) | ||
312 | { | ||
313 | GNUNET_break (0); | ||
314 | return GNUNET_SYSERR; | ||
315 | } | ||
316 | |||
317 | *pk = GNUNET_CRYPTO_rsa_public_key_decode (ret, | ||
318 | have); | ||
319 | if (NULL == *pk) | ||
320 | { | ||
321 | GNUNET_break (0); | ||
322 | return GNUNET_SYSERR; | ||
323 | } | ||
324 | return GNUNET_OK; | ||
325 | } | ||
326 | |||
327 | |||
328 | /** | ||
329 | * Function called to clean up memory allocated | ||
330 | * by a #GNUNET_PQ_ResultConverter. | ||
331 | * | ||
332 | * @param cls closure | ||
333 | */ | ||
334 | static void | ||
335 | clean_rsa_pub (void *cls) | ||
336 | { | ||
337 | struct GNUNET_CRYPTO_RsaPublicKey **pk = cls; | ||
338 | |||
339 | if (NULL != *pk) | ||
340 | { | ||
341 | GNUNET_CRYPTO_rsa_public_key_free (*pk); | ||
342 | *pk = NULL; | ||
343 | } | ||
344 | } | ||
345 | |||
346 | |||
347 | /** | ||
348 | * RSA public key expected. | ||
349 | * | ||
350 | * @param[out] rsa where to store the result | ||
351 | * @return array entry for the result specification to use | ||
352 | */ | ||
353 | struct GNUNET_SQ_ResultSpec | ||
354 | GNUNET_SQ_result_spec_rsa_public_key (struct GNUNET_CRYPTO_RsaPublicKey **rsa) | ||
355 | { | ||
356 | struct GNUNET_SQ_ResultSpec rs = { | ||
357 | .conv = &extract_rsa_pub, | ||
358 | .cleaner = &clean_rsa_pub, | ||
359 | .dst = rsa, | ||
360 | .cls = rsa, | ||
361 | .num_params = 1 | ||
362 | }; | ||
363 | |||
364 | return rs; | ||
365 | } | ||
366 | |||
367 | |||
368 | /** | ||
369 | * Extract data from a Postgres database @a result at row @a row. | ||
370 | * | ||
371 | * @param cls closure | ||
372 | * @param result where to extract data from | ||
373 | * @param column column to extract data from | ||
374 | * @param[in,out] dst_size where to store size of result, may be NULL | ||
375 | * @param[out] dst where to store the result | ||
376 | * @return | ||
377 | * #GNUNET_YES if all results could be extracted | ||
378 | * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) | ||
379 | */ | ||
380 | static int | ||
381 | extract_rsa_sig (void *cls, | ||
382 | sqlite3_stmt *result, | ||
383 | unsigned int column, | ||
384 | size_t *dst_size, | ||
385 | void *dst) | ||
386 | { | ||
387 | struct GNUNET_CRYPTO_RsaSignature **sig = dst; | ||
388 | int have; | ||
389 | const void *ret; | ||
390 | |||
391 | if (SQLITE_BLOB != | ||
392 | sqlite3_column_type (result, | ||
393 | column)) | ||
394 | { | ||
395 | GNUNET_break (0); | ||
396 | return GNUNET_SYSERR; | ||
397 | } | ||
398 | /* sqlite manual says to invoke 'sqlite3_column_blob()' | ||
399 | before calling sqlite3_column_bytes() */ | ||
400 | ret = sqlite3_column_blob (result, | ||
401 | column); | ||
402 | have = sqlite3_column_bytes (result, | ||
403 | column); | ||
404 | if (have < 0) | ||
405 | { | ||
406 | GNUNET_break (0); | ||
407 | return GNUNET_SYSERR; | ||
408 | } | ||
409 | |||
410 | *sig = GNUNET_CRYPTO_rsa_signature_decode (ret, | ||
411 | have); | ||
412 | if (NULL == *sig) | ||
413 | { | ||
414 | GNUNET_break (0); | ||
415 | return GNUNET_SYSERR; | ||
416 | } | ||
417 | return GNUNET_OK; | ||
418 | } | ||
419 | |||
420 | |||
421 | /** | ||
422 | * Function called to clean up memory allocated | ||
423 | * by a #GNUNET_PQ_ResultConverter. | ||
424 | * | ||
425 | * @param cls result data to clean up | ||
426 | */ | ||
427 | static void | ||
428 | clean_rsa_sig (void *cls) | ||
429 | { | ||
430 | struct GNUNET_CRYPTO_RsaSignature **sig = cls; | ||
431 | |||
432 | if (NULL != *sig) | ||
433 | { | ||
434 | GNUNET_CRYPTO_rsa_signature_free (*sig); | ||
435 | *sig = NULL; | ||
436 | } | ||
437 | } | ||
438 | |||
439 | |||
440 | /** | ||
441 | * RSA signature expected. | ||
442 | * | ||
443 | * @param[out] sig where to store the result; | ||
444 | * @return array entry for the result specification to use | ||
445 | */ | ||
446 | struct GNUNET_SQ_ResultSpec | ||
447 | GNUNET_SQ_result_spec_rsa_signature (struct GNUNET_CRYPTO_RsaSignature **sig) | ||
448 | { | ||
449 | struct GNUNET_SQ_ResultSpec rs = { | ||
450 | .conv = &extract_rsa_sig, | ||
451 | .cleaner = &clean_rsa_sig, | ||
452 | .dst = sig, | ||
453 | .cls = sig, | ||
454 | .num_params = 1 | ||
455 | }; | ||
456 | |||
457 | return rs; | ||
458 | } | ||
459 | |||
460 | |||
461 | /** | ||
462 | * Absolute time expected. | ||
463 | * | ||
464 | * @param[out] at where to store the result | ||
465 | * @return array entry for the result specification to use | ||
466 | */ | ||
467 | struct GNUNET_SQ_ResultSpec | ||
468 | GNUNET_SQ_result_spec_absolute_time (struct GNUNET_TIME_Absolute *at) | ||
469 | { | ||
470 | return GNUNET_SQ_result_spec_uint64 (&at->abs_value_us); | ||
471 | } | ||
472 | |||
473 | |||
474 | /** | ||
475 | * Extract absolute time value in NBO from a Postgres database @a result at row @a row. | ||
476 | * | ||
477 | * @param cls closure | ||
478 | * @param result where to extract data from | ||
479 | * @param column column to extract data from | ||
480 | * @param[in,out] dst_size where to store size of result, may be NULL | ||
481 | * @param[out] dst where to store the result | ||
482 | * @return | ||
483 | * #GNUNET_YES if all results could be extracted | ||
484 | * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) | ||
485 | */ | ||
486 | static int | ||
487 | extract_abs_time_nbo (void *cls, | ||
488 | sqlite3_stmt *result, | ||
489 | unsigned int column, | ||
490 | size_t *dst_size, | ||
491 | void *dst) | ||
492 | { | ||
493 | struct GNUNET_TIME_AbsoluteNBO *u = dst; | ||
494 | struct GNUNET_TIME_Absolute t; | ||
495 | |||
496 | GNUNET_assert (sizeof (uint64_t) == *dst_size); | ||
497 | if (SQLITE_INTEGER != | ||
498 | sqlite3_column_type (result, | ||
499 | column)) | ||
500 | { | ||
501 | GNUNET_break (0); | ||
502 | return GNUNET_SYSERR; | ||
503 | } | ||
504 | t.abs_value_us = (uint64_t) sqlite3_column_int64 (result, | ||
505 | column); | ||
506 | *u = GNUNET_TIME_absolute_hton (t); | ||
507 | return GNUNET_OK; | ||
508 | } | ||
509 | |||
510 | |||
511 | /** | ||
512 | * Absolute time expected. | ||
513 | * | ||
514 | * @param[out] at where to store the result | ||
515 | * @return array entry for the result specification to use | ||
516 | */ | ||
517 | struct GNUNET_SQ_ResultSpec | ||
518 | GNUNET_SQ_result_spec_absolute_time_nbo (struct GNUNET_TIME_AbsoluteNBO *at) | ||
519 | { | ||
520 | struct GNUNET_SQ_ResultSpec rs = { | ||
521 | .conv = &extract_abs_time_nbo, | ||
522 | .dst = at, | ||
523 | .dst_size = sizeof (struct GNUNET_TIME_AbsoluteNBO), | ||
524 | .num_params = 1 | ||
525 | }; | ||
526 | |||
527 | return rs; | ||
528 | } | ||
529 | |||
530 | |||
531 | /** | ||
532 | * Extract 16-bit integer from a Postgres database @a result at row @a row. | ||
533 | * | ||
534 | * @param cls closure | ||
535 | * @param result where to extract data from | ||
536 | * @param column column to extract data from | ||
537 | * @param[in,out] dst_size where to store size of result, may be NULL | ||
538 | * @param[out] dst where to store the result | ||
539 | * @return | ||
540 | * #GNUNET_YES if all results could be extracted | ||
541 | * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) | ||
542 | */ | ||
543 | static int | ||
544 | extract_uint16 (void *cls, | ||
545 | sqlite3_stmt *result, | ||
546 | unsigned int column, | ||
547 | size_t *dst_size, | ||
548 | void *dst) | ||
549 | { | ||
550 | uint64_t v; | ||
551 | uint32_t *u = dst; | ||
552 | |||
553 | GNUNET_assert (sizeof (uint16_t) == *dst_size); | ||
554 | if (SQLITE_INTEGER != | ||
555 | sqlite3_column_type (result, | ||
556 | column)) | ||
557 | { | ||
558 | GNUNET_break (0); | ||
559 | return GNUNET_SYSERR; | ||
560 | } | ||
561 | v = (uint64_t) sqlite3_column_int64 (result, | ||
562 | column); | ||
563 | if (v > UINT16_MAX) | ||
564 | { | ||
565 | GNUNET_break (0); | ||
566 | return GNUNET_SYSERR; | ||
567 | } | ||
568 | *u = (uint16_t) v; | ||
569 | return GNUNET_OK; | ||
570 | } | ||
571 | |||
572 | |||
573 | /** | ||
574 | * uint16_t expected. | ||
575 | * | ||
576 | * @param[out] u16 where to store the result | ||
577 | * @return array entry for the result specification to use | ||
578 | */ | ||
579 | struct GNUNET_SQ_ResultSpec | ||
580 | GNUNET_SQ_result_spec_uint16 (uint16_t *u16) | ||
581 | { | ||
582 | struct GNUNET_SQ_ResultSpec rs = { | ||
583 | .conv = &extract_uint16, | ||
584 | .dst = u16, | ||
585 | .dst_size = sizeof (uint16_t), | ||
586 | .num_params = 1 | ||
587 | }; | ||
588 | |||
589 | return rs; | ||
590 | } | ||
591 | |||
592 | |||
593 | /** | ||
594 | * Extract 32-bit integer from a Postgres database @a result at row @a row. | ||
595 | * | ||
596 | * @param cls closure | ||
597 | * @param result where to extract data from | ||
598 | * @param column column to extract data from | ||
599 | * @param[in,out] dst_size where to store size of result, may be NULL | ||
600 | * @param[out] dst where to store the result | ||
601 | * @return | ||
602 | * #GNUNET_YES if all results could be extracted | ||
603 | * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) | ||
604 | */ | ||
605 | static int | ||
606 | extract_uint32 (void *cls, | ||
607 | sqlite3_stmt *result, | ||
608 | unsigned int column, | ||
609 | size_t *dst_size, | ||
610 | void *dst) | ||
611 | { | ||
612 | uint64_t v; | ||
613 | uint32_t *u = dst; | ||
614 | |||
615 | GNUNET_assert (sizeof (uint32_t) == *dst_size); | ||
616 | if (SQLITE_INTEGER != | ||
617 | sqlite3_column_type (result, | ||
618 | column)) | ||
619 | { | ||
620 | GNUNET_break (0); | ||
621 | return GNUNET_SYSERR; | ||
622 | } | ||
623 | v = (uint64_t) sqlite3_column_int64 (result, | ||
624 | column); | ||
625 | if (v > UINT32_MAX) | ||
626 | { | ||
627 | GNUNET_break (0); | ||
628 | return GNUNET_SYSERR; | ||
629 | } | ||
630 | *u = (uint32_t) v; | ||
631 | return GNUNET_OK; | ||
632 | } | ||
633 | |||
634 | |||
635 | /** | ||
636 | * uint32_t expected. | ||
637 | * | ||
638 | * @param[out] u32 where to store the result | ||
639 | * @return array entry for the result specification to use | ||
640 | */ | ||
641 | struct GNUNET_SQ_ResultSpec | ||
642 | GNUNET_SQ_result_spec_uint32 (uint32_t *u32) | ||
643 | { | ||
644 | struct GNUNET_SQ_ResultSpec rs = { | ||
645 | .conv = &extract_uint32, | ||
646 | .dst = u32, | ||
647 | .dst_size = sizeof (uint32_t), | ||
648 | .num_params = 1 | ||
649 | }; | ||
650 | |||
651 | return rs; | ||
652 | } | ||
653 | |||
654 | |||
655 | /** | ||
656 | * Extract 64-bit integer from a Postgres database @a result at row @a row. | ||
657 | * | ||
658 | * @param cls closure | ||
659 | * @param result where to extract data from | ||
660 | * @param column column to extract data from | ||
661 | * @param[in,out] dst_size where to store size of result, may be NULL | ||
662 | * @param[out] dst where to store the result | ||
663 | * @return | ||
664 | * #GNUNET_YES if all results could be extracted | ||
665 | * #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) | ||
666 | */ | ||
667 | static int | ||
668 | extract_uint64 (void *cls, | ||
669 | sqlite3_stmt *result, | ||
670 | unsigned int column, | ||
671 | size_t *dst_size, | ||
672 | void *dst) | ||
673 | { | ||
674 | uint64_t *u = dst; | ||
675 | |||
676 | GNUNET_assert (sizeof (uint64_t) == *dst_size); | ||
677 | if (SQLITE_INTEGER != | ||
678 | sqlite3_column_type (result, | ||
679 | column)) | ||
680 | { | ||
681 | GNUNET_break (0); | ||
682 | return GNUNET_SYSERR; | ||
683 | } | ||
684 | *u = (uint64_t) sqlite3_column_int64 (result, | ||
685 | column); | ||
686 | return GNUNET_OK; | ||
687 | } | ||
688 | |||
689 | |||
690 | /** | ||
691 | * uint64_t expected. | ||
692 | * | ||
693 | * @param[out] u64 where to store the result | ||
694 | * @return array entry for the result specification to use | ||
695 | */ | ||
696 | struct GNUNET_SQ_ResultSpec | ||
697 | GNUNET_SQ_result_spec_uint64 (uint64_t *u64) | ||
698 | { | ||
699 | struct GNUNET_SQ_ResultSpec rs = { | ||
700 | .conv = &extract_uint64, | ||
701 | .dst = u64, | ||
702 | .dst_size = sizeof (uint64_t), | ||
703 | .num_params = 1 | ||
704 | }; | ||
705 | |||
706 | return rs; | ||
707 | } | ||
708 | |||
709 | |||
710 | /* end of sq_result_helper.c */ | ||
diff --git a/src/sq/test_sq.c b/src/sq/test_sq.c new file mode 100644 index 000000000..e6896861e --- /dev/null +++ b/src/sq/test_sq.c | |||
@@ -0,0 +1,279 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | (C) 2015, 2016, 2017 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify it under the | ||
6 | terms of the GNU General Public License as published by the Free Software | ||
7 | Foundation; either version 3, or (at your option) any later version. | ||
8 | |||
9 | GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY | ||
10 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
11 | A PARTICULAR PURPOSE. See the GNU General Public License for more details. | ||
12 | |||
13 | You should have received a copy of the GNU General Public License along with | ||
14 | GNUnet; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/> | ||
15 | */ | ||
16 | /** | ||
17 | * @file sq/test_sq.c | ||
18 | * @brief Tests for sqlite3 convenience API | ||
19 | * @author Christian Grothoff | ||
20 | */ | ||
21 | #include "platform.h" | ||
22 | #include "gnunet_util_lib.h" | ||
23 | #include "gnunet_sq_lib.h" | ||
24 | |||
25 | |||
26 | /** | ||
27 | * @brief Prepare a SQL statement | ||
28 | * | ||
29 | * @param dbh handle to the database | ||
30 | * @param zSql SQL statement, UTF-8 encoded | ||
31 | * @param[out] ppStmt set to the prepared statement | ||
32 | * @return 0 on success | ||
33 | */ | ||
34 | static int | ||
35 | sq_prepare (sqlite3 *dbh, | ||
36 | const char *zSql, | ||
37 | sqlite3_stmt **ppStmt) | ||
38 | { | ||
39 | char *dummy; | ||
40 | int result; | ||
41 | |||
42 | result = sqlite3_prepare_v2 (dbh, | ||
43 | zSql, | ||
44 | strlen (zSql), | ||
45 | ppStmt, | ||
46 | (const char **) &dummy); | ||
47 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
48 | "Prepared `%s' / %p: %d\n", | ||
49 | zSql, | ||
50 | *ppStmt, | ||
51 | result); | ||
52 | return result; | ||
53 | } | ||
54 | |||
55 | |||
56 | /** | ||
57 | * Run actual test queries. | ||
58 | * | ||
59 | * @return 0 on success | ||
60 | */ | ||
61 | static int | ||
62 | run_queries (sqlite3 *dbh) | ||
63 | { | ||
64 | struct GNUNET_CRYPTO_RsaPublicKey *pub; | ||
65 | struct GNUNET_CRYPTO_RsaPublicKey *pub2 = NULL; | ||
66 | struct GNUNET_CRYPTO_RsaSignature *sig; | ||
67 | struct GNUNET_CRYPTO_RsaSignature *sig2 = NULL; | ||
68 | struct GNUNET_TIME_Absolute abs_time = GNUNET_TIME_absolute_get (); | ||
69 | struct GNUNET_TIME_Absolute abs_time2; | ||
70 | struct GNUNET_TIME_Absolute forever = GNUNET_TIME_UNIT_FOREVER_ABS; | ||
71 | struct GNUNET_TIME_Absolute forever2; | ||
72 | struct GNUNET_HashCode hc; | ||
73 | struct GNUNET_HashCode hc2; | ||
74 | sqlite3_stmt *stmt; | ||
75 | struct GNUNET_CRYPTO_RsaPrivateKey *priv; | ||
76 | const char msg[] = "hello"; | ||
77 | void *msg2; | ||
78 | struct GNUNET_HashCode hmsg; | ||
79 | size_t msg2_len; | ||
80 | uint16_t u16; | ||
81 | uint16_t u162; | ||
82 | uint32_t u32; | ||
83 | uint32_t u322; | ||
84 | uint64_t u64; | ||
85 | uint64_t u642; | ||
86 | |||
87 | priv = GNUNET_CRYPTO_rsa_private_key_create (1024); | ||
88 | pub = GNUNET_CRYPTO_rsa_private_key_get_public (priv); | ||
89 | memset (&hmsg, 42, sizeof (hmsg)); | ||
90 | sig = GNUNET_CRYPTO_rsa_sign_fdh (priv, | ||
91 | &hmsg); | ||
92 | u16 = 16; | ||
93 | u32 = 32; | ||
94 | u64 = 64; | ||
95 | /* FIXME: test GNUNET_SQ_result_spec_variable_size */ | ||
96 | |||
97 | sq_prepare (dbh, | ||
98 | "INSERT INTO test_sq (" | ||
99 | " pub" | ||
100 | ",sig" | ||
101 | ",abs_time" | ||
102 | ",forever" | ||
103 | ",hash" | ||
104 | ",vsize" | ||
105 | ",u16" | ||
106 | ",u32" | ||
107 | ",u64" | ||
108 | ") VALUES " | ||
109 | "($1, $2, $3, $4, $5, $6," | ||
110 | "$7, $8, $9);", | ||
111 | &stmt); | ||
112 | { | ||
113 | struct GNUNET_SQ_QueryParam params_insert[] = { | ||
114 | GNUNET_SQ_query_param_rsa_public_key (pub), | ||
115 | GNUNET_SQ_query_param_rsa_signature (sig), | ||
116 | GNUNET_SQ_query_param_absolute_time (&abs_time), | ||
117 | GNUNET_SQ_query_param_absolute_time (&forever), | ||
118 | GNUNET_SQ_query_param_auto_from_type (&hc), | ||
119 | GNUNET_SQ_query_param_fixed_size (msg, strlen (msg)), | ||
120 | GNUNET_SQ_query_param_uint16 (&u16), | ||
121 | GNUNET_SQ_query_param_uint32 (&u32), | ||
122 | GNUNET_SQ_query_param_uint64 (&u64), | ||
123 | GNUNET_SQ_query_param_end | ||
124 | }; | ||
125 | |||
126 | GNUNET_assert (GNUNET_OK == | ||
127 | GNUNET_SQ_bind (stmt, | ||
128 | params_insert)); | ||
129 | if (SQLITE_DONE != | ||
130 | sqlite3_step (stmt)) | ||
131 | { | ||
132 | GNUNET_CRYPTO_rsa_signature_free (sig); | ||
133 | GNUNET_CRYPTO_rsa_private_key_free (priv); | ||
134 | GNUNET_CRYPTO_rsa_public_key_free (pub); | ||
135 | return 1; | ||
136 | } | ||
137 | } | ||
138 | sqlite3_finalize (stmt); | ||
139 | |||
140 | sq_prepare (dbh, | ||
141 | "SELECT" | ||
142 | " pub" | ||
143 | ",sig" | ||
144 | ",abs_time" | ||
145 | ",forever" | ||
146 | ",hash" | ||
147 | ",vsize" | ||
148 | ",u16" | ||
149 | ",u32" | ||
150 | ",u64" | ||
151 | " FROM test_sq" | ||
152 | " ORDER BY abs_time DESC " | ||
153 | " LIMIT 1;", | ||
154 | &stmt); | ||
155 | { | ||
156 | struct GNUNET_SQ_QueryParam params_select[] = { | ||
157 | GNUNET_SQ_query_param_end | ||
158 | }; | ||
159 | struct GNUNET_SQ_ResultSpec results_select[] = { | ||
160 | GNUNET_SQ_result_spec_rsa_public_key (&pub2), | ||
161 | GNUNET_SQ_result_spec_rsa_signature (&sig2), | ||
162 | GNUNET_SQ_result_spec_absolute_time (&abs_time2), | ||
163 | GNUNET_SQ_result_spec_absolute_time (&forever2), | ||
164 | GNUNET_SQ_result_spec_auto_from_type (&hc2), | ||
165 | GNUNET_SQ_result_spec_variable_size (&msg2, &msg2_len), | ||
166 | GNUNET_SQ_result_spec_uint16 (&u162), | ||
167 | GNUNET_SQ_result_spec_uint32 (&u322), | ||
168 | GNUNET_SQ_result_spec_uint64 (&u642), | ||
169 | GNUNET_SQ_result_spec_end | ||
170 | }; | ||
171 | |||
172 | GNUNET_assert (GNUNET_OK == | ||
173 | GNUNET_SQ_bind (stmt, | ||
174 | params_select)); | ||
175 | if (SQLITE_ROW != | ||
176 | sqlite3_step (stmt)) | ||
177 | { | ||
178 | GNUNET_break (0); | ||
179 | sqlite3_finalize (stmt); | ||
180 | GNUNET_CRYPTO_rsa_signature_free (sig); | ||
181 | GNUNET_CRYPTO_rsa_private_key_free (priv); | ||
182 | GNUNET_CRYPTO_rsa_public_key_free (pub); | ||
183 | return 1; | ||
184 | } | ||
185 | GNUNET_assert (GNUNET_OK == | ||
186 | GNUNET_SQ_extract_result (stmt, | ||
187 | results_select)); | ||
188 | GNUNET_break (abs_time.abs_value_us == abs_time2.abs_value_us); | ||
189 | GNUNET_break (forever.abs_value_us == forever2.abs_value_us); | ||
190 | GNUNET_break (0 == | ||
191 | memcmp (&hc, | ||
192 | &hc2, | ||
193 | sizeof (struct GNUNET_HashCode))); | ||
194 | GNUNET_break (0 == | ||
195 | GNUNET_CRYPTO_rsa_signature_cmp (sig, | ||
196 | sig2)); | ||
197 | GNUNET_break (0 == | ||
198 | GNUNET_CRYPTO_rsa_public_key_cmp (pub, | ||
199 | pub2)); | ||
200 | GNUNET_break (strlen (msg) == msg2_len); | ||
201 | GNUNET_break (0 == | ||
202 | strncmp (msg, | ||
203 | msg2, | ||
204 | msg2_len)); | ||
205 | GNUNET_break (16 == u162); | ||
206 | GNUNET_break (32 == u322); | ||
207 | GNUNET_break (64 == u642); | ||
208 | GNUNET_SQ_cleanup_result (results_select); | ||
209 | } | ||
210 | sqlite3_finalize (stmt); | ||
211 | |||
212 | GNUNET_CRYPTO_rsa_signature_free (sig); | ||
213 | GNUNET_CRYPTO_rsa_private_key_free (priv); | ||
214 | GNUNET_CRYPTO_rsa_public_key_free (pub); | ||
215 | return 0; | ||
216 | } | ||
217 | |||
218 | |||
219 | int | ||
220 | main(int argc, | ||
221 | const char *const argv[]) | ||
222 | { | ||
223 | sqlite3 *dbh; | ||
224 | int ret; | ||
225 | |||
226 | GNUNET_log_setup ("test-sq", | ||
227 | "WARNING", | ||
228 | NULL); | ||
229 | if (SQLITE_OK != | ||
230 | sqlite3_open ("test.db", | ||
231 | &dbh)) | ||
232 | { | ||
233 | fprintf (stderr, | ||
234 | "Cannot run test, sqlite3 initialization failed\n"); | ||
235 | GNUNET_break (0); | ||
236 | return 77; /* Signal test was skipped... */ | ||
237 | } | ||
238 | |||
239 | if (SQLITE_OK != | ||
240 | sqlite3_exec (dbh, | ||
241 | "CREATE TEMPORARY TABLE IF NOT EXISTS test_sq (" | ||
242 | " pub BYTEA NOT NULL" | ||
243 | ",sig BYTEA NOT NULL" | ||
244 | ",abs_time INT8 NOT NULL" | ||
245 | ",forever INT8 NOT NULL" | ||
246 | ",hash BYTEA NOT NULL" | ||
247 | ",vsize VARCHAR NOT NULL" | ||
248 | ",u16 INT2 NOT NULL" | ||
249 | ",u32 INT4 NOT NULL" | ||
250 | ",u64 INT8 NOT NULL" | ||
251 | ")", | ||
252 | NULL, NULL, NULL)) | ||
253 | { | ||
254 | fprintf (stderr, | ||
255 | "Failed to create table\n"); | ||
256 | sqlite3_close (dbh); | ||
257 | unlink ("test.db"); | ||
258 | return 1; | ||
259 | } | ||
260 | |||
261 | ret = run_queries (dbh); | ||
262 | if (SQLITE_OK != | ||
263 | sqlite3_exec (dbh, | ||
264 | "DROP TABLE test_sq", | ||
265 | NULL, NULL, NULL)) | ||
266 | { | ||
267 | fprintf (stderr, | ||
268 | "Failed to drop table\n"); | ||
269 | sqlite3_close (dbh); | ||
270 | unlink ("test.db"); | ||
271 | return 1; | ||
272 | } | ||
273 | sqlite3_close (dbh); | ||
274 | unlink ("test.db"); | ||
275 | return ret; | ||
276 | } | ||
277 | |||
278 | |||
279 | /* end of test_sq.c */ | ||
diff --git a/src/testing/testing.c b/src/testing/testing.c index 043bdd7d2..bab7976ea 100644 --- a/src/testing/testing.c +++ b/src/testing/testing.c | |||
@@ -1633,7 +1633,9 @@ GNUNET_TESTING_service_run (const char *testdir, | |||
1633 | char *binary; | 1633 | char *binary; |
1634 | char *libexec_binary; | 1634 | char *libexec_binary; |
1635 | 1635 | ||
1636 | GNUNET_log_setup (testdir, "WARNING", NULL); | 1636 | GNUNET_log_setup (testdir, |
1637 | "WARNING", | ||
1638 | NULL); | ||
1637 | system = GNUNET_TESTING_system_create (testdir, "127.0.0.1", NULL, NULL); | 1639 | system = GNUNET_TESTING_system_create (testdir, "127.0.0.1", NULL, NULL); |
1638 | if (NULL == system) | 1640 | if (NULL == system) |
1639 | return 1; | 1641 | return 1; |
diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c index 3952a728e..19f5fd081 100644 --- a/src/transport/gnunet-service-transport_neighbours.c +++ b/src/transport/gnunet-service-transport_neighbours.c | |||
@@ -1150,17 +1150,18 @@ set_incoming_quota (struct NeighbourMapEntry *n, | |||
1150 | sqm.header.size = htons (sizeof (struct GNUNET_ATS_SessionQuotaMessage)); | 1150 | sqm.header.size = htons (sizeof (struct GNUNET_ATS_SessionQuotaMessage)); |
1151 | sqm.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_QUOTA); | 1151 | sqm.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_QUOTA); |
1152 | sqm.quota = quota.value__; | 1152 | sqm.quota = quota.value__; |
1153 | (void) send_with_session (n, | 1153 | if (NULL != n->primary_address.session) |
1154 | &sqm, | 1154 | (void) send_with_session (n, |
1155 | sizeof (sqm), | 1155 | &sqm, |
1156 | UINT32_MAX - 1, | 1156 | sizeof (sqm), |
1157 | GNUNET_TIME_UNIT_FOREVER_REL, | 1157 | UINT32_MAX - 1, |
1158 | GNUNET_NO, | 1158 | GNUNET_TIME_UNIT_FOREVER_REL, |
1159 | NULL, NULL); | 1159 | GNUNET_NO, |
1160 | NULL, NULL); | ||
1160 | return; | 1161 | return; |
1161 | } | 1162 | } |
1162 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 1163 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
1163 | "Disconnecting peer `%4s' due to SET_QUOTA\n", | 1164 | "Disconnecting peer `%s' due to SET_QUOTA\n", |
1164 | GNUNET_i2s (&n->id)); | 1165 | GNUNET_i2s (&n->id)); |
1165 | if (GNUNET_YES == test_connected (n)) | 1166 | if (GNUNET_YES == test_connected (n)) |
1166 | GNUNET_STATISTICS_update (GST_stats, | 1167 | GNUNET_STATISTICS_update (GST_stats, |
@@ -2135,13 +2136,18 @@ setup_neighbour (const struct GNUNET_PeerIdentity *peer) | |||
2135 | { | 2136 | { |
2136 | struct NeighbourMapEntry *n; | 2137 | struct NeighbourMapEntry *n; |
2137 | 2138 | ||
2139 | if (0 == | ||
2140 | memcmp (&GST_my_identity, | ||
2141 | peer, | ||
2142 | sizeof (struct GNUNET_PeerIdentity))) | ||
2143 | { | ||
2144 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2145 | "Cowardly refusing to consider myself my neighbour!\n"); | ||
2146 | return NULL; | ||
2147 | } | ||
2138 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2148 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2139 | "Creating new neighbour entry for `%s'\n", | 2149 | "Creating new neighbour entry for `%s'\n", |
2140 | GNUNET_i2s (peer)); | 2150 | GNUNET_i2s (peer)); |
2141 | GNUNET_assert (0 != | ||
2142 | memcmp (&GST_my_identity, | ||
2143 | peer, | ||
2144 | sizeof (struct GNUNET_PeerIdentity))); | ||
2145 | n = GNUNET_new (struct NeighbourMapEntry); | 2151 | n = GNUNET_new (struct NeighbourMapEntry); |
2146 | n->id = *peer; | 2152 | n->id = *peer; |
2147 | n->ack_state = ACK_UNDEFINED; | 2153 | n->ack_state = ACK_UNDEFINED; |
@@ -2249,6 +2255,7 @@ GST_neighbours_handle_session_syn (const struct GNUNET_MessageHeader *message, | |||
2249 | { | 2255 | { |
2250 | /* This is a new neighbour and set to not connected */ | 2256 | /* This is a new neighbour and set to not connected */ |
2251 | n = setup_neighbour (peer); | 2257 | n = setup_neighbour (peer); |
2258 | GNUNET_assert (NULL != n); | ||
2252 | } | 2259 | } |
2253 | 2260 | ||
2254 | /* Remember this SYN message in neighbour */ | 2261 | /* Remember this SYN message in neighbour */ |
@@ -2318,6 +2325,7 @@ GST_neighbours_handle_session_syn (const struct GNUNET_MessageHeader *message, | |||
2318 | /* Get rid of remains and re-try */ | 2325 | /* Get rid of remains and re-try */ |
2319 | free_neighbour (n); | 2326 | free_neighbour (n); |
2320 | n = setup_neighbour (peer); | 2327 | n = setup_neighbour (peer); |
2328 | GNUNET_assert (NULL != n); | ||
2321 | /* Remember the SYN time stamp for ACK message */ | 2329 | /* Remember the SYN time stamp for ACK message */ |
2322 | n->ack_state = ACK_SEND_SYN_ACK; | 2330 | n->ack_state = ACK_SEND_SYN_ACK; |
2323 | n->connect_ack_timestamp = ts; | 2331 | n->connect_ack_timestamp = ts; |
@@ -2495,6 +2503,12 @@ switch_address_bl_check_cont (void *cls, | |||
2495 | if (NULL == (n = lookup_neighbour (peer))) | 2503 | if (NULL == (n = lookup_neighbour (peer))) |
2496 | { | 2504 | { |
2497 | n = setup_neighbour (peer); | 2505 | n = setup_neighbour (peer); |
2506 | if (NULL == n) | ||
2507 | { | ||
2508 | /* not sure how this can happen... */ | ||
2509 | GNUNET_break (0); | ||
2510 | goto cleanup; | ||
2511 | } | ||
2498 | n->state = GNUNET_TRANSPORT_PS_INIT_ATS; | 2512 | n->state = GNUNET_TRANSPORT_PS_INIT_ATS; |
2499 | } | 2513 | } |
2500 | 2514 | ||
diff --git a/src/transport/test_transport_address_switch.c b/src/transport/test_transport_address_switch.c index 77bc9aef8..e076d3501 100644 --- a/src/transport/test_transport_address_switch.c +++ b/src/transport/test_transport_address_switch.c | |||
@@ -49,9 +49,9 @@ | |||
49 | 49 | ||
50 | 50 | ||
51 | /** | 51 | /** |
52 | * Testcase timeout | 52 | * Testcase timeout (set aggressively as we know this test doesn't work right now) |
53 | */ | 53 | */ |
54 | #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60) | 54 | #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) |
55 | 55 | ||
56 | 56 | ||
57 | static struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc; | 57 | static struct GNUNET_TRANSPORT_TESTING_ConnectCheckContext *ccc; |
@@ -199,7 +199,7 @@ custom_shutdown (void *cls) | |||
199 | { | 199 | { |
200 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 200 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
201 | "Fail (timeout)! No transmission after switch! Stopping peers\n"); | 201 | "Fail (timeout)! No transmission after switch! Stopping peers\n"); |
202 | ccc->global_ret = GNUNET_SYSERR; | 202 | ccc->global_ret = 77; /* GNUNET_SYSERR; */ |
203 | } | 203 | } |
204 | 204 | ||
205 | /* stop statistics */ | 205 | /* stop statistics */ |
@@ -277,8 +277,11 @@ custom_shutdown (void *cls) | |||
277 | GNUNET_break (0); | 277 | GNUNET_break (0); |
278 | result++; | 278 | result++; |
279 | } | 279 | } |
280 | #if 0 | ||
281 | /* This test is not really expected to pass right now... */ | ||
280 | if (0 != result) | 282 | if (0 != result) |
281 | ccc->global_ret = GNUNET_SYSERR; | 283 | ccc->global_ret = GNUNET_SYSERR; |
284 | #endif | ||
282 | } | 285 | } |
283 | 286 | ||
284 | 287 | ||
@@ -298,7 +301,7 @@ notify_receive (void *cls, | |||
298 | "Peer %u (`%s') got message %u of size %u from peer (`%s')\n", | 301 | "Peer %u (`%s') got message %u of size %u from peer (`%s')\n", |
299 | receiver->no, | 302 | receiver->no, |
300 | ps, | 303 | ps, |
301 | ntohl (hdr->num), | 304 | (uint32_t) ntohl (hdr->num), |
302 | ntohs (hdr->header.size), | 305 | ntohs (hdr->header.size), |
303 | GNUNET_i2s (sender)); | 306 | GNUNET_i2s (sender)); |
304 | GNUNET_free (ps); | 307 | GNUNET_free (ps); |
diff --git a/src/transport/test_transport_api_reliability.c b/src/transport/test_transport_api_reliability.c index d6702cc25..375a935c8 100644 --- a/src/transport/test_transport_api_reliability.c +++ b/src/transport/test_transport_api_reliability.c | |||
@@ -91,7 +91,7 @@ get_size (unsigned int iter) | |||
91 | #ifndef LINUX | 91 | #ifndef LINUX |
92 | /* FreeBSD/OSX etc. Unix DGRAMs do not work | 92 | /* FreeBSD/OSX etc. Unix DGRAMs do not work |
93 | * with large messages */ | 93 | * with large messages */ |
94 | if (0 == strcmp ("unix", test_plugin)) | 94 | if (0 == strcmp ("unix", ccc->test_plugin)) |
95 | ret = sizeof (struct GNUNET_TRANSPORT_TESTING_TestMessage) + (ret % 1024); | 95 | ret = sizeof (struct GNUNET_TRANSPORT_TESTING_TestMessage) + (ret % 1024); |
96 | #endif | 96 | #endif |
97 | ret = sizeof (struct GNUNET_TRANSPORT_TESTING_TestMessage) + (ret % 60000); | 97 | ret = sizeof (struct GNUNET_TRANSPORT_TESTING_TestMessage) + (ret % 60000); |
@@ -228,10 +228,10 @@ notify_receive (void *cls, | |||
228 | { | 228 | { |
229 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 229 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
230 | "Expected message %u of size %u, got %u bytes of message %u\n", | 230 | "Expected message %u of size %u, got %u bytes of message %u\n", |
231 | ntohl (hdr->num), | 231 | (uint32_t) ntohl (hdr->num), |
232 | s, | 232 | s, |
233 | ntohs (hdr->header.size), | 233 | ntohs (hdr->header.size), |
234 | ntohl (hdr->num)); | 234 | (uint32_t) ntohl (hdr->num)); |
235 | ccc->global_ret = GNUNET_SYSERR; | 235 | ccc->global_ret = GNUNET_SYSERR; |
236 | GNUNET_SCHEDULER_shutdown (); | 236 | GNUNET_SCHEDULER_shutdown (); |
237 | return; | 237 | return; |
@@ -247,7 +247,7 @@ notify_receive (void *cls, | |||
247 | { | 247 | { |
248 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 248 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
249 | "Expected message %u with bits %u, but body did not match\n", | 249 | "Expected message %u with bits %u, but body did not match\n", |
250 | ntohl (hdr->num), | 250 | (uint32_t) ntohl (hdr->num), |
251 | (unsigned char) ntohl (hdr->num)); | 251 | (unsigned char) ntohl (hdr->num)); |
252 | ccc->global_ret = GNUNET_SYSERR; | 252 | ccc->global_ret = GNUNET_SYSERR; |
253 | GNUNET_SCHEDULER_shutdown (); | 253 | GNUNET_SCHEDULER_shutdown (); |
@@ -258,7 +258,7 @@ notify_receive (void *cls, | |||
258 | { | 258 | { |
259 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 259 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
260 | "Got message %u of size %u\n", | 260 | "Got message %u of size %u\n", |
261 | ntohl (hdr->num), | 261 | (uint32_t) ntohl (hdr->num), |
262 | ntohs (hdr->header.size)); | 262 | ntohs (hdr->header.size)); |
263 | } | 263 | } |
264 | #endif | 264 | #endif |
@@ -267,7 +267,7 @@ notify_receive (void *cls, | |||
267 | { | 267 | { |
268 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 268 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
269 | "Message id %u is bigger than maxmimum number of messages %u expected\n", | 269 | "Message id %u is bigger than maxmimum number of messages %u expected\n", |
270 | ntohl (hdr->num), | 270 | (uint32_t) ntohl (hdr->num), |
271 | TOTAL_MSGS / xhdr); | 271 | TOTAL_MSGS / xhdr); |
272 | } | 272 | } |
273 | if (0 == (n % (TOTAL_MSGS / xhdr / 100))) | 273 | if (0 == (n % (TOTAL_MSGS / xhdr / 100))) |
diff --git a/src/transport/transport.conf.in b/src/transport/transport.conf.in index 37cb4efc7..2c99af000 100644 --- a/src/transport/transport.conf.in +++ b/src/transport/transport.conf.in | |||
@@ -4,6 +4,8 @@ AUTOSTART = @AUTOSTART@ | |||
4 | HOSTNAME = localhost | 4 | HOSTNAME = localhost |
5 | BINARY = gnunet-service-transport | 5 | BINARY = gnunet-service-transport |
6 | # PREFIX = valgrind | 6 | # PREFIX = valgrind |
7 | |||
8 | # Maximum number of neighbours PER PLUGIN (not in total). | ||
7 | NEIGHBOUR_LIMIT = 50 | 9 | NEIGHBOUR_LIMIT = 50 |
8 | ACCEPT_FROM = 127.0.0.1; | 10 | ACCEPT_FROM = 127.0.0.1; |
9 | ACCEPT_FROM6 = ::1; | 11 | ACCEPT_FROM6 = ::1; |
diff --git a/src/util/Makefile.am b/src/util/Makefile.am index ac125fb66..df319fe77 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am | |||
@@ -31,6 +31,9 @@ endif | |||
31 | 31 | ||
32 | if !MINGW | 32 | if !MINGW |
33 | SERVER_CLIENT_UNIX = test_server_with_client_unix | 33 | SERVER_CLIENT_UNIX = test_server_with_client_unix |
34 | TEST_CLIENT_UNIC_NC = test_client_unix.nc | ||
35 | else | ||
36 | TEST_CLIENT_UNIC_NC = | ||
34 | endif | 37 | endif |
35 | 38 | ||
36 | if USE_COVERAGE | 39 | if USE_COVERAGE |
@@ -266,7 +269,7 @@ endif | |||
266 | check_PROGRAMS = \ | 269 | check_PROGRAMS = \ |
267 | test_bio \ | 270 | test_bio \ |
268 | test_client.nc \ | 271 | test_client.nc \ |
269 | test_client_unix.nc \ | 272 | $(TEST_CLIENT_UNIX_NC) \ |
270 | $(SSH_USING_TESTS) \ | 273 | $(SSH_USING_TESTS) \ |
271 | test_common_allocation \ | 274 | test_common_allocation \ |
272 | test_common_endian \ | 275 | test_common_endian \ |
diff --git a/src/util/bio.c b/src/util/bio.c index 62f4904f7..08e30dc01 100644 --- a/src/util/bio.c +++ b/src/util/bio.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include "platform.h" | 25 | #include "platform.h" |
26 | #include "gnunet_util_lib.h" | 26 | #include "gnunet_util_lib.h" |
27 | 27 | ||
28 | #define LOG(kind,...) GNUNET_log_from (kind, "util",__VA_ARGS__) | 28 | #define LOG(kind,...) GNUNET_log_from (kind, "util-bio",__VA_ARGS__) |
29 | 29 | ||
30 | #ifndef PATH_MAX | 30 | #ifndef PATH_MAX |
31 | /** | 31 | /** |
diff --git a/src/util/client.c b/src/util/client.c index a5e04d7b2..0f7d0d359 100644 --- a/src/util/client.c +++ b/src/util/client.c | |||
@@ -33,7 +33,7 @@ | |||
33 | #include "gnunet_socks.h" | 33 | #include "gnunet_socks.h" |
34 | 34 | ||
35 | 35 | ||
36 | #define LOG(kind,...) GNUNET_log_from (kind, "util",__VA_ARGS__) | 36 | #define LOG(kind,...) GNUNET_log_from (kind, "util-client",__VA_ARGS__) |
37 | 37 | ||
38 | 38 | ||
39 | /** | 39 | /** |
@@ -298,6 +298,11 @@ recv_message (void *cls, | |||
298 | 298 | ||
299 | if (GNUNET_YES == cstate->in_destroy) | 299 | if (GNUNET_YES == cstate->in_destroy) |
300 | return GNUNET_SYSERR; | 300 | return GNUNET_SYSERR; |
301 | |||
302 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
303 | "Received message of type %u and size %u from %s\n", | ||
304 | ntohs (msg->type), ntohs (msg->size), cstate->service_name); | ||
305 | |||
301 | GNUNET_MQ_inject_message (cstate->mq, | 306 | GNUNET_MQ_inject_message (cstate->mq, |
302 | msg); | 307 | msg); |
303 | if (GNUNET_YES == cstate->in_destroy) | 308 | if (GNUNET_YES == cstate->in_destroy) |
diff --git a/src/util/common_allocation.c b/src/util/common_allocation.c index 71a2221ee..737584815 100644 --- a/src/util/common_allocation.c +++ b/src/util/common_allocation.c | |||
@@ -32,9 +32,9 @@ | |||
32 | #include <malloc/malloc.h> | 32 | #include <malloc/malloc.h> |
33 | #endif | 33 | #endif |
34 | 34 | ||
35 | #define LOG(kind,...) GNUNET_log_from (kind, "util",__VA_ARGS__) | 35 | #define LOG(kind,...) GNUNET_log_from (kind, "util-common-allocation",__VA_ARGS__) |
36 | 36 | ||
37 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall) | 37 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-common-allocation", syscall) |
38 | 38 | ||
39 | #ifndef INT_MAX | 39 | #ifndef INT_MAX |
40 | #define INT_MAX 0x7FFFFFFF | 40 | #define INT_MAX 0x7FFFFFFF |
diff --git a/src/util/common_endian.c b/src/util/common_endian.c index 4c8ad7182..f29e42c98 100644 --- a/src/util/common_endian.c +++ b/src/util/common_endian.c | |||
@@ -28,7 +28,7 @@ | |||
28 | #include "platform.h" | 28 | #include "platform.h" |
29 | #include "gnunet_crypto_lib.h" | 29 | #include "gnunet_crypto_lib.h" |
30 | 30 | ||
31 | #define LOG(kind,...) GNUNET_log_from (kind, "util",__VA_ARGS__) | 31 | #define LOG(kind,...) GNUNET_log_from (kind, "util-common-endian",__VA_ARGS__) |
32 | 32 | ||
33 | 33 | ||
34 | uint64_t | 34 | uint64_t |
diff --git a/src/util/configuration_loader.c b/src/util/configuration_loader.c index 07eeb98f0..ceaf2a6ea 100644 --- a/src/util/configuration_loader.c +++ b/src/util/configuration_loader.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include "platform.h" | 27 | #include "platform.h" |
28 | #include "gnunet_util_lib.h" | 28 | #include "gnunet_util_lib.h" |
29 | 29 | ||
30 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 30 | #define LOG(kind,...) GNUNET_log_from (kind, "util-configuration", __VA_ARGS__) |
31 | 31 | ||
32 | 32 | ||
33 | /** | 33 | /** |
diff --git a/src/util/connection.c b/src/util/connection.c index 02dd9f991..e822b264f 100644 --- a/src/util/connection.c +++ b/src/util/connection.c | |||
@@ -35,9 +35,9 @@ | |||
35 | #include "gnunet_resolver_service.h" | 35 | #include "gnunet_resolver_service.h" |
36 | 36 | ||
37 | 37 | ||
38 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 38 | #define LOG(kind,...) GNUNET_log_from (kind, "util-connection", __VA_ARGS__) |
39 | 39 | ||
40 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall) | 40 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-connection", syscall) |
41 | 41 | ||
42 | 42 | ||
43 | /** | 43 | /** |
@@ -335,12 +335,17 @@ GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access_cb, | |||
335 | struct sockaddr_in6 *v6; | 335 | struct sockaddr_in6 *v6; |
336 | struct sockaddr *sa; | 336 | struct sockaddr *sa; |
337 | void *uaddr; | 337 | void *uaddr; |
338 | struct GNUNET_CONNECTION_Credentials *gcp; | ||
339 | struct GNUNET_CONNECTION_Credentials gc; | ||
340 | #ifdef SO_PEERCRED | 338 | #ifdef SO_PEERCRED |
341 | struct ucred uc; | 339 | struct ucred uc; |
342 | socklen_t olen; | 340 | socklen_t olen; |
343 | #endif | 341 | #endif |
342 | struct GNUNET_CONNECTION_Credentials *gcp; | ||
343 | #if HAVE_GETPEEREID || defined(SO_PEERCRED) || HAVE_GETPEERUCRED | ||
344 | struct GNUNET_CONNECTION_Credentials gc; | ||
345 | |||
346 | gc.uid = 0; | ||
347 | gc.gid = 0; | ||
348 | #endif | ||
344 | 349 | ||
345 | addrlen = sizeof (addr); | 350 | addrlen = sizeof (addr); |
346 | sock = | 351 | sock = |
@@ -386,8 +391,6 @@ GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access_cb, | |||
386 | GNUNET_memcpy (uaddr, addr, addrlen); | 391 | GNUNET_memcpy (uaddr, addr, addrlen); |
387 | } | 392 | } |
388 | gcp = NULL; | 393 | gcp = NULL; |
389 | gc.uid = 0; | ||
390 | gc.gid = 0; | ||
391 | if (AF_UNIX == sa->sa_family) | 394 | if (AF_UNIX == sa->sa_family) |
392 | { | 395 | { |
393 | #if HAVE_GETPEEREID | 396 | #if HAVE_GETPEEREID |
diff --git a/src/util/container_bloomfilter.c b/src/util/container_bloomfilter.c index 58725dcc5..aedca232d 100644 --- a/src/util/container_bloomfilter.c +++ b/src/util/container_bloomfilter.c | |||
@@ -42,11 +42,11 @@ | |||
42 | #include "platform.h" | 42 | #include "platform.h" |
43 | #include "gnunet_util_lib.h" | 43 | #include "gnunet_util_lib.h" |
44 | 44 | ||
45 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 45 | #define LOG(kind,...) GNUNET_log_from (kind, "util-container-bloomfilter", __VA_ARGS__) |
46 | 46 | ||
47 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall) | 47 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-container-bloomfilter", syscall) |
48 | 48 | ||
49 | #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename) | 49 | #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util-container-bloomfilter", syscall, filename) |
50 | 50 | ||
51 | struct GNUNET_CONTAINER_BloomFilter | 51 | struct GNUNET_CONTAINER_BloomFilter |
52 | { | 52 | { |
diff --git a/src/util/container_heap.c b/src/util/container_heap.c index 1ead5ec6d..21bdee834 100644 --- a/src/util/container_heap.c +++ b/src/util/container_heap.c | |||
@@ -28,7 +28,7 @@ | |||
28 | #include "platform.h" | 28 | #include "platform.h" |
29 | #include "gnunet_container_lib.h" | 29 | #include "gnunet_container_lib.h" |
30 | 30 | ||
31 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 31 | #define LOG(kind,...) GNUNET_log_from (kind, "util-container-heap", __VA_ARGS__) |
32 | 32 | ||
33 | #define EXTRA_CHECKS 0 | 33 | #define EXTRA_CHECKS 0 |
34 | 34 | ||
diff --git a/src/util/container_meta_data.c b/src/util/container_meta_data.c index b4d231dae..ec527005a 100644 --- a/src/util/container_meta_data.c +++ b/src/util/container_meta_data.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #endif | 31 | #endif |
32 | #include <zlib.h> | 32 | #include <zlib.h> |
33 | 33 | ||
34 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 34 | #define LOG(kind,...) GNUNET_log_from (kind, "util-container-meta-data", __VA_ARGS__) |
35 | 35 | ||
36 | 36 | ||
37 | 37 | ||
diff --git a/src/util/container_multihashmap.c b/src/util/container_multihashmap.c index d85562579..ffeb4a71f 100644 --- a/src/util/container_multihashmap.c +++ b/src/util/container_multihashmap.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #include "platform.h" | 26 | #include "platform.h" |
27 | #include "gnunet_container_lib.h" | 27 | #include "gnunet_container_lib.h" |
28 | 28 | ||
29 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 29 | #define LOG(kind,...) GNUNET_log_from (kind, "util-container-multihashmap", __VA_ARGS__) |
30 | 30 | ||
31 | /** | 31 | /** |
32 | * An entry in the hash map with the full key. | 32 | * An entry in the hash map with the full key. |
diff --git a/src/util/container_multihashmap32.c b/src/util/container_multihashmap32.c index 4cc9b7ebd..d33c3c2d9 100644 --- a/src/util/container_multihashmap32.c +++ b/src/util/container_multihashmap32.c | |||
@@ -28,7 +28,7 @@ | |||
28 | #include "platform.h" | 28 | #include "platform.h" |
29 | #include "gnunet_container_lib.h" | 29 | #include "gnunet_container_lib.h" |
30 | 30 | ||
31 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 31 | #define LOG(kind,...) GNUNET_log_from (kind, "util-container-multihashmap32", __VA_ARGS__) |
32 | 32 | ||
33 | /** | 33 | /** |
34 | * An entry in the hash map. | 34 | * An entry in the hash map. |
diff --git a/src/util/container_multipeermap.c b/src/util/container_multipeermap.c index 6c62e7403..7830771d8 100644 --- a/src/util/container_multipeermap.c +++ b/src/util/container_multipeermap.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #include "platform.h" | 26 | #include "platform.h" |
27 | #include "gnunet_util_lib.h" | 27 | #include "gnunet_util_lib.h" |
28 | 28 | ||
29 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 29 | #define LOG(kind,...) GNUNET_log_from (kind, "util-container-multipeermap", __VA_ARGS__) |
30 | 30 | ||
31 | /** | 31 | /** |
32 | * An entry in the hash map with the full key. | 32 | * An entry in the hash map with the full key. |
diff --git a/src/util/container_multishortmap.c b/src/util/container_multishortmap.c index 5e8a47b09..cfa82ca20 100644 --- a/src/util/container_multishortmap.c +++ b/src/util/container_multishortmap.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #include "platform.h" | 26 | #include "platform.h" |
27 | #include "gnunet_util_lib.h" | 27 | #include "gnunet_util_lib.h" |
28 | 28 | ||
29 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 29 | #define LOG(kind,...) GNUNET_log_from (kind, "util-container-multishortmap", __VA_ARGS__) |
30 | 30 | ||
31 | /** | 31 | /** |
32 | * An entry in the hash map with the full key. | 32 | * An entry in the hash map with the full key. |
diff --git a/src/util/crypto_crc.c b/src/util/crypto_crc.c index d7f5f7fc8..03b24d9f7 100644 --- a/src/util/crypto_crc.c +++ b/src/util/crypto_crc.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #include "platform.h" | 30 | #include "platform.h" |
31 | #include "gnunet_crypto_lib.h" | 31 | #include "gnunet_crypto_lib.h" |
32 | 32 | ||
33 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 33 | #define LOG(kind,...) GNUNET_log_from (kind, "util-crypto-crc", __VA_ARGS__) |
34 | 34 | ||
35 | /* Avoid wasting space on 8-byte longs. */ | 35 | /* Avoid wasting space on 8-byte longs. */ |
36 | #if UINT_MAX >= 0xffffffff | 36 | #if UINT_MAX >= 0xffffffff |
diff --git a/src/util/crypto_ecc.c b/src/util/crypto_ecc.c index 3f9150762..eaa49a991 100644 --- a/src/util/crypto_ecc.c +++ b/src/util/crypto_ecc.c | |||
@@ -38,11 +38,11 @@ | |||
38 | */ | 38 | */ |
39 | #define CURVE "Ed25519" | 39 | #define CURVE "Ed25519" |
40 | 40 | ||
41 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 41 | #define LOG(kind,...) GNUNET_log_from (kind, "util-crypto-ecc", __VA_ARGS__) |
42 | 42 | ||
43 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall) | 43 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-crypto-ecc", syscall) |
44 | 44 | ||
45 | #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename) | 45 | #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util-crypto-ecc", syscall, filename) |
46 | 46 | ||
47 | /** | 47 | /** |
48 | * Log an error message at log-level 'level' that indicates | 48 | * Log an error message at log-level 'level' that indicates |
diff --git a/src/util/crypto_ecc_setup.c b/src/util/crypto_ecc_setup.c index 0ce55ddbf..2f2e2f122 100644 --- a/src/util/crypto_ecc_setup.c +++ b/src/util/crypto_ecc_setup.c | |||
@@ -27,11 +27,11 @@ | |||
27 | #include <gcrypt.h> | 27 | #include <gcrypt.h> |
28 | #include "gnunet_util_lib.h" | 28 | #include "gnunet_util_lib.h" |
29 | 29 | ||
30 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 30 | #define LOG(kind,...) GNUNET_log_from (kind, "util-crypto-ecc", __VA_ARGS__) |
31 | 31 | ||
32 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall) | 32 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-crypto-ecc", syscall) |
33 | 33 | ||
34 | #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename) | 34 | #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util-crypto-ecc", syscall, filename) |
35 | 35 | ||
36 | /** | 36 | /** |
37 | * Log an error message at log-level 'level' that indicates | 37 | * Log an error message at log-level 'level' that indicates |
diff --git a/src/util/crypto_hash.c b/src/util/crypto_hash.c index 31824e72a..49dbacd0b 100644 --- a/src/util/crypto_hash.c +++ b/src/util/crypto_hash.c | |||
@@ -28,9 +28,9 @@ | |||
28 | #include "gnunet_strings_lib.h" | 28 | #include "gnunet_strings_lib.h" |
29 | #include <gcrypt.h> | 29 | #include <gcrypt.h> |
30 | 30 | ||
31 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 31 | #define LOG(kind,...) GNUNET_log_from (kind, "util-crypto-hash", __VA_ARGS__) |
32 | 32 | ||
33 | #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename) | 33 | #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util-crypto-hash", syscall, filename) |
34 | 34 | ||
35 | /** | 35 | /** |
36 | * Hash block of given size. | 36 | * Hash block of given size. |
diff --git a/src/util/crypto_hash_file.c b/src/util/crypto_hash_file.c index ace5212c9..3e5900200 100644 --- a/src/util/crypto_hash_file.c +++ b/src/util/crypto_hash_file.c | |||
@@ -27,9 +27,9 @@ | |||
27 | #include "gnunet_util_lib.h" | 27 | #include "gnunet_util_lib.h" |
28 | #include <gcrypt.h> | 28 | #include <gcrypt.h> |
29 | 29 | ||
30 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 30 | #define LOG(kind,...) GNUNET_log_from (kind, "util-crypto-hash-file", __VA_ARGS__) |
31 | 31 | ||
32 | #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename) | 32 | #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util-crypto-hash-file", syscall, filename) |
33 | 33 | ||
34 | 34 | ||
35 | /** | 35 | /** |
diff --git a/src/util/crypto_hkdf.c b/src/util/crypto_hkdf.c index c6c43f800..f04d3e675 100644 --- a/src/util/crypto_hkdf.c +++ b/src/util/crypto_hkdf.c | |||
@@ -36,7 +36,7 @@ | |||
36 | * - Matthias Wachs (08.10.2010) | 36 | * - Matthias Wachs (08.10.2010) |
37 | */ | 37 | */ |
38 | 38 | ||
39 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 39 | #define LOG(kind,...) GNUNET_log_from (kind, "util-crypto-hkdf", __VA_ARGS__) |
40 | 40 | ||
41 | /** | 41 | /** |
42 | * Set this to 0 if you compile this code outside of GNUnet. | 42 | * Set this to 0 if you compile this code outside of GNUnet. |
diff --git a/src/util/crypto_kdf.c b/src/util/crypto_kdf.c index 78fb1911a..6d7c5a096 100644 --- a/src/util/crypto_kdf.c +++ b/src/util/crypto_kdf.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #include "platform.h" | 30 | #include "platform.h" |
31 | #include "gnunet_crypto_lib.h" | 31 | #include "gnunet_crypto_lib.h" |
32 | 32 | ||
33 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 33 | #define LOG(kind,...) GNUNET_log_from (kind, "util-crypto-kdf", __VA_ARGS__) |
34 | 34 | ||
35 | /** | 35 | /** |
36 | * @brief Derive key | 36 | * @brief Derive key |
diff --git a/src/util/crypto_mpi.c b/src/util/crypto_mpi.c index 668d5e602..ff3e9a8a7 100644 --- a/src/util/crypto_mpi.c +++ b/src/util/crypto_mpi.c | |||
@@ -29,7 +29,7 @@ | |||
29 | #include "gnunet_crypto_lib.h" | 29 | #include "gnunet_crypto_lib.h" |
30 | 30 | ||
31 | 31 | ||
32 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 32 | #define LOG(kind,...) GNUNET_log_from (kind, "util-crypto-mpi", __VA_ARGS__) |
33 | 33 | ||
34 | /** | 34 | /** |
35 | * Log an error message at log-level 'level' that indicates | 35 | * Log an error message at log-level 'level' that indicates |
diff --git a/src/util/crypto_random.c b/src/util/crypto_random.c index 8897ae24f..d5b5eb9ec 100644 --- a/src/util/crypto_random.c +++ b/src/util/crypto_random.c | |||
@@ -28,9 +28,9 @@ | |||
28 | #include "gnunet_crypto_lib.h" | 28 | #include "gnunet_crypto_lib.h" |
29 | #include <gcrypt.h> | 29 | #include <gcrypt.h> |
30 | 30 | ||
31 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 31 | #define LOG(kind,...) GNUNET_log_from (kind, "util-crypto-random", __VA_ARGS__) |
32 | 32 | ||
33 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall) | 33 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-crypto-random", syscall) |
34 | 34 | ||
35 | 35 | ||
36 | /* TODO: ndurner, move this to plibc? */ | 36 | /* TODO: ndurner, move this to plibc? */ |
diff --git a/src/util/crypto_rsa.c b/src/util/crypto_rsa.c index 443d597e4..7a108c21b 100644 --- a/src/util/crypto_rsa.c +++ b/src/util/crypto_rsa.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <gcrypt.h> | 25 | #include <gcrypt.h> |
26 | #include "gnunet_crypto_lib.h" | 26 | #include "gnunet_crypto_lib.h" |
27 | 27 | ||
28 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 28 | #define LOG(kind,...) GNUNET_log_from (kind, "util-crypto-rsa", __VA_ARGS__) |
29 | 29 | ||
30 | 30 | ||
31 | /** | 31 | /** |
@@ -430,7 +430,7 @@ rsa_blinding_key_derive (const struct GNUNET_CRYPTO_RsaPublicKey *pkey, | |||
430 | char *xts = "Blinding KDF extrator HMAC key"; /* Trusts bks' randomness more */ | 430 | char *xts = "Blinding KDF extrator HMAC key"; /* Trusts bks' randomness more */ |
431 | struct RsaBlindingKey *blind; | 431 | struct RsaBlindingKey *blind; |
432 | gcry_mpi_t n; | 432 | gcry_mpi_t n; |
433 | 433 | ||
434 | blind = GNUNET_new (struct RsaBlindingKey); | 434 | blind = GNUNET_new (struct RsaBlindingKey); |
435 | GNUNET_assert( NULL != blind ); | 435 | GNUNET_assert( NULL != blind ); |
436 | 436 | ||
@@ -454,25 +454,25 @@ rsa_blinding_key_derive (const struct GNUNET_CRYPTO_RsaPublicKey *pkey, | |||
454 | } | 454 | } |
455 | 455 | ||
456 | 456 | ||
457 | /* | 457 | /* |
458 | We originally added GNUNET_CRYPTO_kdf_mod_mpi for the benifit of the | 458 | We originally added GNUNET_CRYPTO_kdf_mod_mpi for the benifit of the |
459 | previous routine. | 459 | previous routine. |
460 | 460 | ||
461 | There was previously a call to GNUNET_CRYPTO_kdf in | 461 | There was previously a call to GNUNET_CRYPTO_kdf in |
462 | bkey = rsa_blinding_key_derive (len, bks); | 462 | bkey = rsa_blinding_key_derive (len, bks); |
463 | that gives exactly len bits where | 463 | that gives exactly len bits where |
464 | len = GNUNET_CRYPTO_rsa_public_key_len (pkey); | 464 | len = GNUNET_CRYPTO_rsa_public_key_len (pkey); |
465 | 465 | ||
466 | Now r = 2^(len-1)/pkey.n is the probability that a set high bit being | 466 | Now r = 2^(len-1)/pkey.n is the probability that a set high bit being |
467 | okay, meaning bkey < pkey.n. It follows that (1-r)/2 of the time bkey > | 467 | okay, meaning bkey < pkey.n. It follows that (1-r)/2 of the time bkey > |
468 | pkey.n making the effective bkey be | 468 | pkey.n making the effective bkey be |
469 | bkey mod pkey.n = bkey - pkey.n | 469 | bkey mod pkey.n = bkey - pkey.n |
470 | so the effective bkey has its high bit set with probability r/2. | 470 | so the effective bkey has its high bit set with probability r/2. |
471 | 471 | ||
472 | We expect r to be close to 1/2 if the exchange is honest, but the | 472 | We expect r to be close to 1/2 if the exchange is honest, but the |
473 | exchange can choose r otherwise. | 473 | exchange can choose r otherwise. |
474 | 474 | ||
475 | In blind signing, the exchange sees | 475 | In blind signing, the exchange sees |
476 | B = bkey * S mod pkey.n | 476 | B = bkey * S mod pkey.n |
477 | On deposit, the exchange sees S so they can compute bkey' = B/S mod | 477 | On deposit, the exchange sees S so they can compute bkey' = B/S mod |
478 | pkey.n for all B they recorded to see if bkey' has it's high bit set. | 478 | pkey.n for all B they recorded to see if bkey' has it's high bit set. |
@@ -489,7 +489,7 @@ the wrong and right probabilities 1/3 and 1/4, respectively. | |||
489 | I feared this gives the exchange a meaningful fraction of a bit of | 489 | I feared this gives the exchange a meaningful fraction of a bit of |
490 | information per coin involved in the transaction. It sounds damaging if | 490 | information per coin involved in the transaction. It sounds damaging if |
491 | numerous coins were involved. And it could run across transactions in | 491 | numerous coins were involved. And it could run across transactions in |
492 | some scenarios. | 492 | some scenarios. |
493 | 493 | ||
494 | We fixed this by using a more uniform deterministic pseudo-random number | 494 | We fixed this by using a more uniform deterministic pseudo-random number |
495 | generator for blinding factors. I do not believe this to be a problem | 495 | generator for blinding factors. I do not believe this to be a problem |
@@ -748,7 +748,7 @@ GNUNET_CRYPTO_rsa_blind (const struct GNUNET_HashCode *hash, | |||
748 | } | 748 | } |
749 | 749 | ||
750 | data = rsa_full_domain_hash (pkey, hash); | 750 | data = rsa_full_domain_hash (pkey, hash); |
751 | if (NULL == data) | 751 | if (NULL == data) |
752 | goto rsa_gcd_validate_failure; | 752 | goto rsa_gcd_validate_failure; |
753 | 753 | ||
754 | bkey = rsa_blinding_key_derive (pkey, bks); | 754 | bkey = rsa_blinding_key_derive (pkey, bks); |
@@ -771,7 +771,7 @@ GNUNET_CRYPTO_rsa_blind (const struct GNUNET_HashCode *hash, | |||
771 | gcry_mpi_release (ne[0]); | 771 | gcry_mpi_release (ne[0]); |
772 | gcry_mpi_release (ne[1]); | 772 | gcry_mpi_release (ne[1]); |
773 | gcry_mpi_release (r_e); | 773 | gcry_mpi_release (r_e); |
774 | rsa_blinding_key_free (bkey); | 774 | rsa_blinding_key_free (bkey); |
775 | 775 | ||
776 | *buf_size = numeric_mpi_alloc_n_print (data_r_e, buf); | 776 | *buf_size = numeric_mpi_alloc_n_print (data_r_e, buf); |
777 | gcry_mpi_release (data_r_e); | 777 | gcry_mpi_release (data_r_e); |
@@ -917,7 +917,7 @@ GNUNET_CRYPTO_rsa_sign_fdh (const struct GNUNET_CRYPTO_RsaPrivateKey *key, | |||
917 | GNUNET_CRYPTO_rsa_public_key_free (pkey); | 917 | GNUNET_CRYPTO_rsa_public_key_free (pkey); |
918 | if (NULL == v) /* rsa_gcd_validate failed meaning */ | 918 | if (NULL == v) /* rsa_gcd_validate failed meaning */ |
919 | return NULL; /* our *own* RSA key is malicious. */ | 919 | return NULL; /* our *own* RSA key is malicious. */ |
920 | 920 | ||
921 | sig = rsa_sign_mpi (key, v); | 921 | sig = rsa_sign_mpi (key, v); |
922 | gcry_mpi_release (v); | 922 | gcry_mpi_release (v); |
923 | return sig; | 923 | return sig; |
@@ -1077,11 +1077,11 @@ GNUNET_CRYPTO_rsa_unblind (struct GNUNET_CRYPTO_RsaSignature *sig, | |||
1077 | } | 1077 | } |
1078 | 1078 | ||
1079 | bkey = rsa_blinding_key_derive (pkey, bks); | 1079 | bkey = rsa_blinding_key_derive (pkey, bks); |
1080 | if (NULL == bkey) | 1080 | if (NULL == bkey) |
1081 | { | 1081 | { |
1082 | /* RSA key is malicious since rsa_gcd_validate failed here. | 1082 | /* RSA key is malicious since rsa_gcd_validate failed here. |
1083 | * It should have failed during GNUNET_CRYPTO_rsa_blind too though, | 1083 | * It should have failed during GNUNET_CRYPTO_rsa_blind too though, |
1084 | * so the exchange is being malicious in an unfamilair way, maybe | 1084 | * so the exchange is being malicious in an unfamilair way, maybe |
1085 | * just trying to crash us. */ | 1085 | * just trying to crash us. */ |
1086 | GNUNET_break_op (0); | 1086 | GNUNET_break_op (0); |
1087 | gcry_mpi_release (n); | 1087 | gcry_mpi_release (n); |
@@ -1096,10 +1096,10 @@ GNUNET_CRYPTO_rsa_unblind (struct GNUNET_CRYPTO_RsaSignature *sig, | |||
1096 | n)) | 1096 | n)) |
1097 | { | 1097 | { |
1098 | /* We cannot find r mod n, so gcd(r,n) != 1, which should get * | 1098 | /* We cannot find r mod n, so gcd(r,n) != 1, which should get * |
1099 | * caught above, but we handle it the same here. */ | 1099 | * caught above, but we handle it the same here. */ |
1100 | GNUNET_break_op (0); | 1100 | GNUNET_break_op (0); |
1101 | gcry_mpi_release (r_inv); | 1101 | gcry_mpi_release (r_inv); |
1102 | rsa_blinding_key_free (bkey); | 1102 | rsa_blinding_key_free (bkey); |
1103 | gcry_mpi_release (n); | 1103 | gcry_mpi_release (n); |
1104 | gcry_mpi_release (s); | 1104 | gcry_mpi_release (s); |
1105 | return NULL; | 1105 | return NULL; |
@@ -1144,11 +1144,11 @@ GNUNET_CRYPTO_rsa_verify (const struct GNUNET_HashCode *hash, | |||
1144 | r = rsa_full_domain_hash (pkey, hash); | 1144 | r = rsa_full_domain_hash (pkey, hash); |
1145 | if (NULL == r) { | 1145 | if (NULL == r) { |
1146 | GNUNET_break_op (0); | 1146 | GNUNET_break_op (0); |
1147 | /* RSA key is malicious since rsa_gcd_validate failed here. | 1147 | /* RSA key is malicious since rsa_gcd_validate failed here. |
1148 | * It should have failed during GNUNET_CRYPTO_rsa_blind too though, | 1148 | * It should have failed during GNUNET_CRYPTO_rsa_blind too though, |
1149 | * so the exchange is being malicious in an unfamilair way, maybe | 1149 | * so the exchange is being malicious in an unfamilair way, maybe |
1150 | * just trying to crash us. Arguably, we've only an internal error | 1150 | * just trying to crash us. Arguably, we've only an internal error |
1151 | * though because we should've detected this in our previous call | 1151 | * though because we should've detected this in our previous call |
1152 | * to GNUNET_CRYPTO_rsa_unblind. */ | 1152 | * to GNUNET_CRYPTO_rsa_unblind. */ |
1153 | return GNUNET_NO; | 1153 | return GNUNET_NO; |
1154 | } | 1154 | } |
diff --git a/src/util/crypto_symmetric.c b/src/util/crypto_symmetric.c index 381a5d2f8..e25e2f1dd 100644 --- a/src/util/crypto_symmetric.c +++ b/src/util/crypto_symmetric.c | |||
@@ -29,7 +29,7 @@ | |||
29 | #include "gnunet_crypto_lib.h" | 29 | #include "gnunet_crypto_lib.h" |
30 | #include <gcrypt.h> | 30 | #include <gcrypt.h> |
31 | 31 | ||
32 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 32 | #define LOG(kind,...) GNUNET_log_from (kind, "util-crypto-symmetric", __VA_ARGS__) |
33 | 33 | ||
34 | /** | 34 | /** |
35 | * Create a new SessionKey (for symmetric encryption). | 35 | * Create a new SessionKey (for symmetric encryption). |
diff --git a/src/util/disk.c b/src/util/disk.c index 40043549b..d3d5d87dc 100644 --- a/src/util/disk.c +++ b/src/util/disk.c | |||
@@ -28,11 +28,11 @@ | |||
28 | #include "gnunet_strings_lib.h" | 28 | #include "gnunet_strings_lib.h" |
29 | #include "gnunet_disk_lib.h" | 29 | #include "gnunet_disk_lib.h" |
30 | 30 | ||
31 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 31 | #define LOG(kind,...) GNUNET_log_from (kind, "util-disk", __VA_ARGS__) |
32 | 32 | ||
33 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall) | 33 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-disk", syscall) |
34 | 34 | ||
35 | #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename) | 35 | #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util-disk", syscall, filename) |
36 | 36 | ||
37 | /** | 37 | /** |
38 | * Block size for IO for copying files. | 38 | * Block size for IO for copying files. |
@@ -1840,6 +1840,8 @@ GNUNET_DISK_get_handle_from_w32_handle (HANDLE osfh) | |||
1840 | { | 1840 | { |
1841 | if (0 != ResetEvent (osfh)) | 1841 | if (0 != ResetEvent (osfh)) |
1842 | ftype = GNUNET_DISK_HANLDE_TYPE_EVENT; | 1842 | ftype = GNUNET_DISK_HANLDE_TYPE_EVENT; |
1843 | else | ||
1844 | return NULL; | ||
1843 | } | 1845 | } |
1844 | else | 1846 | else |
1845 | return NULL; | 1847 | return NULL; |
diff --git a/src/util/getopt.c b/src/util/getopt.c index e150496ae..ff62dba9b 100644 --- a/src/util/getopt.c +++ b/src/util/getopt.c | |||
@@ -47,9 +47,9 @@ Copyright Copyright (C) 2006 Christian Grothoff | |||
47 | #endif | 47 | #endif |
48 | #endif | 48 | #endif |
49 | 49 | ||
50 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 50 | #define LOG(kind,...) GNUNET_log_from (kind, "util-getopt", __VA_ARGS__) |
51 | 51 | ||
52 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall) | 52 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-getopt", syscall) |
53 | 53 | ||
54 | #if defined (WIN32) && !defined (__CYGWIN32__) | 54 | #if defined (WIN32) && !defined (__CYGWIN32__) |
55 | /* It's not Unix, really. See? Capital letters. */ | 55 | /* It's not Unix, really. See? Capital letters. */ |
diff --git a/src/util/getopt_helpers.c b/src/util/getopt_helpers.c index ab0b67412..4d7104503 100644 --- a/src/util/getopt_helpers.c +++ b/src/util/getopt_helpers.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #include "platform.h" | 26 | #include "platform.h" |
27 | #include "gnunet_util_lib.h" | 27 | #include "gnunet_util_lib.h" |
28 | 28 | ||
29 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 29 | #define LOG(kind,...) GNUNET_log_from (kind, "util-getopt", __VA_ARGS__) |
30 | 30 | ||
31 | 31 | ||
32 | /** | 32 | /** |
diff --git a/src/util/load.c b/src/util/load.c index d374d7a17..d1de6aa36 100644 --- a/src/util/load.c +++ b/src/util/load.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include "gnunet_util_lib.h" | 27 | #include "gnunet_util_lib.h" |
28 | 28 | ||
29 | 29 | ||
30 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 30 | #define LOG(kind,...) GNUNET_log_from (kind, "util-load", __VA_ARGS__) |
31 | 31 | ||
32 | /** | 32 | /** |
33 | * Values we track for load calculations. | 33 | * Values we track for load calculations. |
diff --git a/src/util/mq.c b/src/util/mq.c index fe47f6ab4..79e2d0455 100644 --- a/src/util/mq.c +++ b/src/util/mq.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2012-2014 GNUnet e.V. | 3 | Copyright (C) 2012-2017 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -26,7 +26,7 @@ | |||
26 | #include "platform.h" | 26 | #include "platform.h" |
27 | #include "gnunet_util_lib.h" | 27 | #include "gnunet_util_lib.h" |
28 | 28 | ||
29 | #define LOG(kind,...) GNUNET_log_from (kind, "mq",__VA_ARGS__) | 29 | #define LOG(kind,...) GNUNET_log_from (kind, "util-mq",__VA_ARGS__) |
30 | 30 | ||
31 | 31 | ||
32 | struct GNUNET_MQ_Envelope | 32 | struct GNUNET_MQ_Envelope |
@@ -235,24 +235,29 @@ GNUNET_MQ_inject_message (struct GNUNET_MQ_Handle *mq, | |||
235 | { | 235 | { |
236 | const struct GNUNET_MQ_MessageHandler *handler; | 236 | const struct GNUNET_MQ_MessageHandler *handler; |
237 | int handled = GNUNET_NO; | 237 | int handled = GNUNET_NO; |
238 | uint16_t ms = ntohs (mh->size); | 238 | uint16_t msize = ntohs (mh->size); |
239 | uint16_t mtype = ntohs (mh->type); | ||
240 | |||
241 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
242 | "Received message of type %u and size %u\n", | ||
243 | mtype, msize); | ||
239 | 244 | ||
240 | if (NULL == mq->handlers) | 245 | if (NULL == mq->handlers) |
241 | goto done; | 246 | goto done; |
242 | for (handler = mq->handlers; NULL != handler->cb; handler++) | 247 | for (handler = mq->handlers; NULL != handler->cb; handler++) |
243 | { | 248 | { |
244 | if (handler->type == ntohs (mh->type)) | 249 | if (handler->type == mtype) |
245 | { | 250 | { |
246 | handled = GNUNET_YES; | 251 | handled = GNUNET_YES; |
247 | if ( (handler->expected_size > ms) || | 252 | if ( (handler->expected_size > msize) || |
248 | ( (handler->expected_size != ms) && | 253 | ( (handler->expected_size != msize) && |
249 | (NULL == handler->mv) ) ) | 254 | (NULL == handler->mv) ) ) |
250 | { | 255 | { |
251 | /* Too small, or not an exact size and | 256 | /* Too small, or not an exact size and |
252 | no 'mv' handler to check rest */ | 257 | no 'mv' handler to check rest */ |
253 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 258 | LOG (GNUNET_ERROR_TYPE_ERROR, |
254 | "Received malformed message of type %u\n", | 259 | "Received malformed message of type %u\n", |
255 | (unsigned int) handler->type); | 260 | (unsigned int) handler->type); |
256 | GNUNET_MQ_inject_error (mq, | 261 | GNUNET_MQ_inject_error (mq, |
257 | GNUNET_MQ_ERROR_MALFORMED); | 262 | GNUNET_MQ_ERROR_MALFORMED); |
258 | break; | 263 | break; |
@@ -267,9 +272,9 @@ GNUNET_MQ_inject_message (struct GNUNET_MQ_Handle *mq, | |||
267 | else | 272 | else |
268 | { | 273 | { |
269 | /* Message rejected by check routine */ | 274 | /* Message rejected by check routine */ |
270 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 275 | LOG (GNUNET_ERROR_TYPE_ERROR, |
271 | "Received malformed message of type %u\n", | 276 | "Received malformed message of type %u\n", |
272 | (unsigned int) handler->type); | 277 | (unsigned int) handler->type); |
273 | GNUNET_MQ_inject_error (mq, | 278 | GNUNET_MQ_inject_error (mq, |
274 | GNUNET_MQ_ERROR_MALFORMED); | 279 | GNUNET_MQ_ERROR_MALFORMED); |
275 | } | 280 | } |
@@ -279,9 +284,8 @@ GNUNET_MQ_inject_message (struct GNUNET_MQ_Handle *mq, | |||
279 | done: | 284 | done: |
280 | if (GNUNET_NO == handled) | 285 | if (GNUNET_NO == handled) |
281 | LOG (GNUNET_ERROR_TYPE_INFO, | 286 | LOG (GNUNET_ERROR_TYPE_INFO, |
282 | "No handler for message of type %d and size %d\n", | 287 | "No handler for message of type %u and size %u\n", |
283 | ntohs (mh->type), | 288 | mtype, msize); |
284 | ntohs (mh->size)); | ||
285 | } | 289 | } |
286 | 290 | ||
287 | 291 | ||
@@ -358,6 +362,7 @@ GNUNET_MQ_send (struct GNUNET_MQ_Handle *mq, | |||
358 | GNUNET_assert (NULL == ev->parent_queue); | 362 | GNUNET_assert (NULL == ev->parent_queue); |
359 | 363 | ||
360 | mq->queue_length++; | 364 | mq->queue_length++; |
365 | GNUNET_break (mq->queue_length < 10000); /* This would seem like a bug... */ | ||
361 | ev->parent_queue = mq; | 366 | ev->parent_queue = mq; |
362 | /* is the implementation busy? queue it! */ | 367 | /* is the implementation busy? queue it! */ |
363 | if ( (NULL != mq->current_envelope) || | 368 | if ( (NULL != mq->current_envelope) || |
@@ -377,6 +382,46 @@ GNUNET_MQ_send (struct GNUNET_MQ_Handle *mq, | |||
377 | 382 | ||
378 | 383 | ||
379 | /** | 384 | /** |
385 | * Remove the first envelope that has not yet been sent from the message | ||
386 | * queue and return it. | ||
387 | * | ||
388 | * @param mq queue to remove envelope from | ||
389 | * @return NULL if queue is empty (or has no envelope that is not under transmission) | ||
390 | */ | ||
391 | struct GNUNET_MQ_Envelope * | ||
392 | GNUNET_MQ_unsent_head (struct GNUNET_MQ_Handle *mq) | ||
393 | { | ||
394 | struct GNUNET_MQ_Envelope *env; | ||
395 | |||
396 | env = mq->envelope_head; | ||
397 | GNUNET_CONTAINER_DLL_remove (mq->envelope_head, | ||
398 | mq->envelope_tail, | ||
399 | env); | ||
400 | mq->queue_length--; | ||
401 | env->parent_queue = NULL; | ||
402 | return env; | ||
403 | } | ||
404 | |||
405 | |||
406 | /** | ||
407 | * Function to copy an envelope. The envelope must not yet | ||
408 | * be in any queue or have any options or callbacks set. | ||
409 | * | ||
410 | * @param env envelope to copy | ||
411 | * @return copy of @a env | ||
412 | */ | ||
413 | struct GNUNET_MQ_Envelope * | ||
414 | GNUNET_MQ_env_copy (struct GNUNET_MQ_Envelope *env) | ||
415 | { | ||
416 | GNUNET_assert (NULL == env->next); | ||
417 | GNUNET_assert (NULL == env->parent_queue); | ||
418 | GNUNET_assert (NULL == env->sent_cb); | ||
419 | GNUNET_assert (GNUNET_NO == env->have_custom_options); | ||
420 | return GNUNET_MQ_msg_copy (env->mh); | ||
421 | } | ||
422 | |||
423 | |||
424 | /** | ||
380 | * Send a copy of a message with the given message queue. | 425 | * Send a copy of a message with the given message queue. |
381 | * Can be called repeatedly on the same envelope. | 426 | * Can be called repeatedly on the same envelope. |
382 | * | 427 | * |
@@ -716,9 +761,13 @@ server_client_send_impl (struct GNUNET_MQ_Handle *mq, | |||
716 | const struct GNUNET_MessageHeader *msg, | 761 | const struct GNUNET_MessageHeader *msg, |
717 | void *impl_state) | 762 | void *impl_state) |
718 | { | 763 | { |
719 | struct ServerClientSocketState *state = impl_state; | ||
720 | |||
721 | GNUNET_assert (NULL != mq); | 764 | GNUNET_assert (NULL != mq); |
765 | |||
766 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
767 | "Sending message of type %u and size %u\n", | ||
768 | ntohs (msg->type), ntohs (msg->size)); | ||
769 | |||
770 | struct ServerClientSocketState *state = impl_state; | ||
722 | state->th = GNUNET_SERVER_notify_transmit_ready (state->client, | 771 | state->th = GNUNET_SERVER_notify_transmit_ready (state->client, |
723 | ntohs (msg->size), | 772 | ntohs (msg->size), |
724 | GNUNET_TIME_UNIT_FOREVER_REL, | 773 | GNUNET_TIME_UNIT_FOREVER_REL, |
diff --git a/src/util/mst.c b/src/util/mst.c index 1422c248e..9f1d30d7a 100644 --- a/src/util/mst.c +++ b/src/util/mst.c | |||
@@ -34,7 +34,7 @@ | |||
34 | #define ALIGN_FACTOR 8 | 34 | #define ALIGN_FACTOR 8 |
35 | #endif | 35 | #endif |
36 | 36 | ||
37 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 37 | #define LOG(kind,...) GNUNET_log_from (kind, "util-mst", __VA_ARGS__) |
38 | 38 | ||
39 | 39 | ||
40 | /** | 40 | /** |
diff --git a/src/util/network.c b/src/util/network.c index 67f2801c5..c82caafd9 100644 --- a/src/util/network.c +++ b/src/util/network.c | |||
@@ -28,9 +28,9 @@ | |||
28 | #include "gnunet_util_lib.h" | 28 | #include "gnunet_util_lib.h" |
29 | #include "disk.h" | 29 | #include "disk.h" |
30 | 30 | ||
31 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 31 | #define LOG(kind,...) GNUNET_log_from (kind, "util-network", __VA_ARGS__) |
32 | #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename) | 32 | #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util-network", syscall, filename) |
33 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall) | 33 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-network", syscall) |
34 | 34 | ||
35 | #define DEBUG_NETWORK GNUNET_EXTRA_LOGGING | 35 | #define DEBUG_NETWORK GNUNET_EXTRA_LOGGING |
36 | 36 | ||
diff --git a/src/util/os_installation.c b/src/util/os_installation.c index ea3ae3e79..1226c5966 100644 --- a/src/util/os_installation.c +++ b/src/util/os_installation.c | |||
@@ -44,9 +44,9 @@ | |||
44 | #endif | 44 | #endif |
45 | 45 | ||
46 | 46 | ||
47 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 47 | #define LOG(kind,...) GNUNET_log_from (kind, "util-os-installation", __VA_ARGS__) |
48 | 48 | ||
49 | #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename) | 49 | #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util-os-installation", syscall, filename) |
50 | 50 | ||
51 | 51 | ||
52 | /** | 52 | /** |
@@ -823,9 +823,13 @@ GNUNET_OS_check_helper_binary (const char *binary, | |||
823 | #ifdef MINGW | 823 | #ifdef MINGW |
824 | char *binaryexe; | 824 | char *binaryexe; |
825 | 825 | ||
826 | GNUNET_asprintf (&binaryexe, "%s.exe", binary); | 826 | GNUNET_asprintf (&binaryexe, |
827 | if ( (GNUNET_YES == GNUNET_STRINGS_path_is_absolute (binaryexe, GNUNET_NO, | 827 | "%s.exe", |
828 | NULL, NULL)) || | 828 | binary); |
829 | if ( (GNUNET_YES == | ||
830 | GNUNET_STRINGS_path_is_absolute (binaryexe, | ||
831 | GNUNET_NO, | ||
832 | NULL, NULL)) || | ||
829 | (0 == strncmp (binary, "./", 2)) ) | 833 | (0 == strncmp (binary, "./", 2)) ) |
830 | p = GNUNET_strdup (binaryexe); | 834 | p = GNUNET_strdup (binaryexe); |
831 | else | 835 | else |
@@ -840,16 +844,24 @@ GNUNET_OS_check_helper_binary (const char *binary, | |||
840 | } | 844 | } |
841 | GNUNET_free (binaryexe); | 845 | GNUNET_free (binaryexe); |
842 | #else | 846 | #else |
843 | if ( (GNUNET_YES == GNUNET_STRINGS_path_is_absolute (binary, GNUNET_NO, | 847 | if ( (GNUNET_YES == |
844 | NULL, NULL)) || | 848 | GNUNET_STRINGS_path_is_absolute (binary, |
849 | GNUNET_NO, | ||
850 | NULL, | ||
851 | NULL)) || | ||
845 | (0 == strncmp (binary, "./", 2)) ) | 852 | (0 == strncmp (binary, "./", 2)) ) |
853 | { | ||
846 | p = GNUNET_strdup (binary); | 854 | p = GNUNET_strdup (binary); |
855 | } | ||
847 | else | 856 | else |
848 | { | 857 | { |
849 | p = get_path_from_PATH (binary); | 858 | p = get_path_from_PATH (binary); |
850 | if (NULL != p) | 859 | if (NULL != p) |
851 | { | 860 | { |
852 | GNUNET_asprintf (&pf, "%s/%s", p, binary); | 861 | GNUNET_asprintf (&pf, |
862 | "%s/%s", | ||
863 | p, | ||
864 | binary); | ||
853 | GNUNET_free (p); | 865 | GNUNET_free (p); |
854 | p = pf; | 866 | p = pf; |
855 | } | 867 | } |
@@ -862,9 +874,12 @@ GNUNET_OS_check_helper_binary (const char *binary, | |||
862 | binary); | 874 | binary); |
863 | return GNUNET_SYSERR; | 875 | return GNUNET_SYSERR; |
864 | } | 876 | } |
865 | if (0 != ACCESS (p, X_OK)) | 877 | if (0 != ACCESS (p, |
878 | X_OK)) | ||
866 | { | 879 | { |
867 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "access", p); | 880 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, |
881 | "access", | ||
882 | p); | ||
868 | GNUNET_free (p); | 883 | GNUNET_free (p); |
869 | return GNUNET_SYSERR; | 884 | return GNUNET_SYSERR; |
870 | } | 885 | } |
@@ -873,22 +888,30 @@ GNUNET_OS_check_helper_binary (const char *binary, | |||
873 | { | 888 | { |
874 | /* as we run as root, we don't insist on SUID */ | 889 | /* as we run as root, we don't insist on SUID */ |
875 | GNUNET_free (p); | 890 | GNUNET_free (p); |
876 | return GNUNET_OK; | 891 | return GNUNET_YES; |
877 | } | 892 | } |
878 | #endif | 893 | #endif |
879 | if (0 != STAT (p, &statbuf)) | 894 | if (0 != STAT (p, |
895 | &statbuf)) | ||
880 | { | 896 | { |
881 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat", p); | 897 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, |
898 | "stat", | ||
899 | p); | ||
882 | GNUNET_free (p); | 900 | GNUNET_free (p); |
883 | return GNUNET_SYSERR; | 901 | return GNUNET_SYSERR; |
884 | } | 902 | } |
885 | if (check_suid){ | 903 | if (check_suid) |
904 | { | ||
886 | #ifndef MINGW | 905 | #ifndef MINGW |
887 | if ((0 != (statbuf.st_mode & S_ISUID)) && (0 == statbuf.st_uid)) | 906 | if ( (0 != (statbuf.st_mode & S_ISUID)) && |
907 | (0 == statbuf.st_uid) ) | ||
888 | { | 908 | { |
889 | GNUNET_free (p); | 909 | GNUNET_free (p); |
890 | return GNUNET_YES; | 910 | return GNUNET_YES; |
891 | } | 911 | } |
912 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
913 | _("Binary `%s' exists, but is not SUID\n"), | ||
914 | p); | ||
892 | /* binary exists, but not SUID */ | 915 | /* binary exists, but not SUID */ |
893 | #else | 916 | #else |
894 | STARTUPINFO start; | 917 | STARTUPINFO start; |
diff --git a/src/util/os_network.c b/src/util/os_network.c index 5e4546d08..5cb2b6864 100644 --- a/src/util/os_network.c +++ b/src/util/os_network.c | |||
@@ -31,11 +31,11 @@ | |||
31 | #include "gnunet_util_lib.h" | 31 | #include "gnunet_util_lib.h" |
32 | 32 | ||
33 | 33 | ||
34 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 34 | #define LOG(kind,...) GNUNET_log_from (kind, "util-os-network", __VA_ARGS__) |
35 | #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename) | 35 | #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util-os-network", syscall, filename) |
36 | 36 | ||
37 | 37 | ||
38 | #if ! (HAVE_GETIFADDRS && HAVE_FREEIFADDRS) | 38 | #if ! (HAVE_GETIFADDRS && HAVE_FREEIFADDRS) && !MINGW |
39 | /** | 39 | /** |
40 | * Try to enumerate all network interfaces using 'ifconfig'. | 40 | * Try to enumerate all network interfaces using 'ifconfig'. |
41 | * | 41 | * |
diff --git a/src/util/os_priority.c b/src/util/os_priority.c index 4b1dbd491..2c4f7ca09 100644 --- a/src/util/os_priority.c +++ b/src/util/os_priority.c | |||
@@ -29,11 +29,11 @@ | |||
29 | #include "disk.h" | 29 | #include "disk.h" |
30 | #include <unistr.h> | 30 | #include <unistr.h> |
31 | 31 | ||
32 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 32 | #define LOG(kind,...) GNUNET_log_from (kind, "util-os-priority", __VA_ARGS__) |
33 | 33 | ||
34 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall) | 34 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-os-priority", syscall) |
35 | 35 | ||
36 | #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename) | 36 | #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util-os-priority", syscall, filename) |
37 | 37 | ||
38 | #define GNUNET_OS_CONTROL_PIPE "GNUNET_OS_CONTROL_PIPE" | 38 | #define GNUNET_OS_CONTROL_PIPE "GNUNET_OS_CONTROL_PIPE" |
39 | 39 | ||
@@ -1091,7 +1091,10 @@ start_process (int pipe_control, | |||
1091 | &lsocks_read, sizeof (HANDLE)); | 1091 | &lsocks_read, sizeof (HANDLE)); |
1092 | } | 1092 | } |
1093 | else | 1093 | else |
1094 | { | ||
1094 | lsocks_pipe = NULL; | 1095 | lsocks_pipe = NULL; |
1096 | lsocks_write_fd = NULL; | ||
1097 | } | ||
1095 | 1098 | ||
1096 | env_off = 0; | 1099 | env_off = 0; |
1097 | if (GNUNET_YES == pipe_control) | 1100 | if (GNUNET_YES == pipe_control) |
@@ -1229,7 +1232,7 @@ start_process (int pipe_control, | |||
1229 | if (sizeof (count) != wrote) | 1232 | if (sizeof (count) != wrote) |
1230 | { | 1233 | { |
1231 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 1234 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
1232 | "Failed to write %u count bytes to the child: %u\n", | 1235 | "Failed to write %u count bytes to the child: %lu\n", |
1233 | sizeof (count), GetLastError ()); | 1236 | sizeof (count), GetLastError ()); |
1234 | break; | 1237 | break; |
1235 | } | 1238 | } |
@@ -1240,7 +1243,7 @@ start_process (int pipe_control, | |||
1240 | if (SOCKET_ERROR == WSADuplicateSocketA (lsocks[i], gnunet_proc->pid, &pi)) | 1243 | if (SOCKET_ERROR == WSADuplicateSocketA (lsocks[i], gnunet_proc->pid, &pi)) |
1241 | { | 1244 | { |
1242 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 1245 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
1243 | "Failed to duplicate an socket[%llu]: %u\n", i, | 1246 | "Failed to duplicate an socket[%u]: %lu\n", i, |
1244 | GetLastError ()); | 1247 | GetLastError ()); |
1245 | break; | 1248 | break; |
1246 | } | 1249 | } |
@@ -1257,7 +1260,7 @@ start_process (int pipe_control, | |||
1257 | if (sizeof (size) != wrote) | 1260 | if (sizeof (size) != wrote) |
1258 | { | 1261 | { |
1259 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 1262 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
1260 | "Failed to write %u size[%llu] bytes to the child: %u\n", | 1263 | "Failed to write %u size[%u] bytes to the child: %lu\n", |
1261 | sizeof (size), i, GetLastError ()); | 1264 | sizeof (size), i, GetLastError ()); |
1262 | break; | 1265 | break; |
1263 | } | 1266 | } |
@@ -1266,7 +1269,7 @@ start_process (int pipe_control, | |||
1266 | if (sizeof (pi) != wrote) | 1269 | if (sizeof (pi) != wrote) |
1267 | { | 1270 | { |
1268 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 1271 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
1269 | "Failed to write %u socket[%llu] bytes to the child: %u\n", | 1272 | "Failed to write %u socket[%u] bytes to the child: %lu\n", |
1270 | sizeof (pi), i, GetLastError ()); | 1273 | sizeof (pi), i, GetLastError ()); |
1271 | break; | 1274 | break; |
1272 | } | 1275 | } |
diff --git a/src/util/peer.c b/src/util/peer.c index 5d54a4301..b637dc229 100644 --- a/src/util/peer.c +++ b/src/util/peer.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #include "platform.h" | 26 | #include "platform.h" |
27 | #include "gnunet_peer_lib.h" | 27 | #include "gnunet_peer_lib.h" |
28 | 28 | ||
29 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 29 | #define LOG(kind,...) GNUNET_log_from (kind, "util-peer", __VA_ARGS__) |
30 | 30 | ||
31 | 31 | ||
32 | struct PeerEntry | 32 | struct PeerEntry |
diff --git a/src/util/plugin.c b/src/util/plugin.c index c7ac47a7c..fb296f80d 100644 --- a/src/util/plugin.c +++ b/src/util/plugin.c | |||
@@ -28,7 +28,7 @@ | |||
28 | #include <ltdl.h> | 28 | #include <ltdl.h> |
29 | #include "gnunet_util_lib.h" | 29 | #include "gnunet_util_lib.h" |
30 | 30 | ||
31 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 31 | #define LOG(kind,...) GNUNET_log_from (kind, "util-plugin", __VA_ARGS__) |
32 | 32 | ||
33 | /** | 33 | /** |
34 | * Linked list of active plugins. | 34 | * Linked list of active plugins. |
diff --git a/src/util/program.c b/src/util/program.c index d0dd49909..e2b356f88 100644 --- a/src/util/program.c +++ b/src/util/program.c | |||
@@ -31,9 +31,9 @@ | |||
31 | #include "speedup.h" | 31 | #include "speedup.h" |
32 | #include <gcrypt.h> | 32 | #include <gcrypt.h> |
33 | 33 | ||
34 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 34 | #define LOG(kind,...) GNUNET_log_from (kind, "util-program", __VA_ARGS__) |
35 | 35 | ||
36 | #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename) | 36 | #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util-program", syscall, filename) |
37 | 37 | ||
38 | /** | 38 | /** |
39 | * Context for the command. | 39 | * Context for the command. |
diff --git a/src/util/resolver_api.c b/src/util/resolver_api.c index fdeaed006..f33c31f1c 100644 --- a/src/util/resolver_api.c +++ b/src/util/resolver_api.c | |||
@@ -29,9 +29,9 @@ | |||
29 | #include "gnunet_resolver_service.h" | 29 | #include "gnunet_resolver_service.h" |
30 | #include "resolver.h" | 30 | #include "resolver.h" |
31 | 31 | ||
32 | #define LOG(kind,...) GNUNET_log_from (kind, "resolver-api", __VA_ARGS__) | 32 | #define LOG(kind,...) GNUNET_log_from (kind, "util-resolver-api", __VA_ARGS__) |
33 | 33 | ||
34 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "resolver-api", syscall) | 34 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-resolver-api", syscall) |
35 | 35 | ||
36 | /** | 36 | /** |
37 | * Maximum supported length for a hostname | 37 | * Maximum supported length for a hostname |
@@ -250,7 +250,7 @@ void | |||
250 | GNUNET_RESOLVER_disconnect () | 250 | GNUNET_RESOLVER_disconnect () |
251 | { | 251 | { |
252 | struct GNUNET_RESOLVER_RequestHandle *rh; | 252 | struct GNUNET_RESOLVER_RequestHandle *rh; |
253 | 253 | ||
254 | while (NULL != (rh = req_head)) | 254 | while (NULL != (rh = req_head)) |
255 | { | 255 | { |
256 | GNUNET_assert (GNUNET_SYSERR == rh->was_transmitted); | 256 | GNUNET_assert (GNUNET_SYSERR == rh->was_transmitted); |
@@ -298,7 +298,7 @@ static void | |||
298 | check_disconnect () | 298 | check_disconnect () |
299 | { | 299 | { |
300 | struct GNUNET_RESOLVER_RequestHandle *rh; | 300 | struct GNUNET_RESOLVER_RequestHandle *rh; |
301 | 301 | ||
302 | for (rh = req_head; NULL != rh; rh = rh->next) | 302 | for (rh = req_head; NULL != rh; rh = rh->next) |
303 | if (GNUNET_SYSERR != rh->was_transmitted) | 303 | if (GNUNET_SYSERR != rh->was_transmitted) |
304 | return; | 304 | return; |
diff --git a/src/util/server.c b/src/util/server.c index 00e37c9d9..83c30e328 100644 --- a/src/util/server.c +++ b/src/util/server.c | |||
@@ -28,11 +28,11 @@ | |||
28 | #include "gnunet_util_lib.h" | 28 | #include "gnunet_util_lib.h" |
29 | #include "gnunet_protocols.h" | 29 | #include "gnunet_protocols.h" |
30 | 30 | ||
31 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 31 | #define LOG(kind,...) GNUNET_log_from (kind, "util-server", __VA_ARGS__) |
32 | 32 | ||
33 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall) | 33 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-server", syscall) |
34 | 34 | ||
35 | #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename) | 35 | #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util-server", syscall, filename) |
36 | 36 | ||
37 | 37 | ||
38 | /** | 38 | /** |
@@ -945,9 +945,9 @@ GNUNET_SERVER_inject (struct GNUNET_SERVER_Handle *server, | |||
945 | 945 | ||
946 | type = ntohs (message->type); | 946 | type = ntohs (message->type); |
947 | size = ntohs (message->size); | 947 | size = ntohs (message->size); |
948 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 948 | LOG (GNUNET_ERROR_TYPE_INFO, |
949 | "Server schedules transmission of %u-byte message of type %u to client.\n", | 949 | "Received message of type %u and size %u from client\n", |
950 | size, type); | 950 | type, size); |
951 | found = GNUNET_NO; | 951 | found = GNUNET_NO; |
952 | for (pos = server->handlers; NULL != pos; pos = pos->next) | 952 | for (pos = server->handlers; NULL != pos; pos = pos->next) |
953 | { | 953 | { |
@@ -1240,8 +1240,8 @@ client_message_tokenizer_callback (void *cls, | |||
1240 | int ret; | 1240 | int ret; |
1241 | 1241 | ||
1242 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1242 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1243 | "Tokenizer gives server message of type %u from client\n", | 1243 | "Tokenizer gives server message of type %u and size %u from client\n", |
1244 | ntohs (message->type)); | 1244 | ntohs (message->type), ntohs (message->size)); |
1245 | sender->in_process_client_buffer = GNUNET_YES; | 1245 | sender->in_process_client_buffer = GNUNET_YES; |
1246 | ret = GNUNET_SERVER_inject (server, sender, message); | 1246 | ret = GNUNET_SERVER_inject (server, sender, message); |
1247 | sender->in_process_client_buffer = GNUNET_NO; | 1247 | sender->in_process_client_buffer = GNUNET_NO; |
diff --git a/src/util/server_mst.c b/src/util/server_mst.c index 8c9bc4b5b..5155b54da 100644 --- a/src/util/server_mst.c +++ b/src/util/server_mst.c | |||
@@ -34,7 +34,7 @@ | |||
34 | #define ALIGN_FACTOR 8 | 34 | #define ALIGN_FACTOR 8 |
35 | #endif | 35 | #endif |
36 | 36 | ||
37 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 37 | #define LOG(kind,...) GNUNET_log_from (kind, "util-server-mst", __VA_ARGS__) |
38 | 38 | ||
39 | 39 | ||
40 | /** | 40 | /** |
diff --git a/src/util/server_tc.c b/src/util/server_tc.c index 40a8ba015..8ae380a85 100644 --- a/src/util/server_tc.c +++ b/src/util/server_tc.c | |||
@@ -29,7 +29,7 @@ | |||
29 | #include "gnunet_util_lib.h" | 29 | #include "gnunet_util_lib.h" |
30 | 30 | ||
31 | 31 | ||
32 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 32 | #define LOG(kind,...) GNUNET_log_from (kind, "util-server-tc", __VA_ARGS__) |
33 | 33 | ||
34 | 34 | ||
35 | /** | 35 | /** |
diff --git a/src/util/service.c b/src/util/service.c index 11128425d..496904fb1 100644 --- a/src/util/service.c +++ b/src/util/service.c | |||
@@ -36,11 +36,11 @@ | |||
36 | #endif | 36 | #endif |
37 | 37 | ||
38 | 38 | ||
39 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 39 | #define LOG(kind,...) GNUNET_log_from (kind, "util-service", __VA_ARGS__) |
40 | 40 | ||
41 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall) | 41 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-service", syscall) |
42 | 42 | ||
43 | #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename) | 43 | #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util-service", syscall, filename) |
44 | 44 | ||
45 | 45 | ||
46 | /* ******************* access control ******************** */ | 46 | /* ******************* access control ******************** */ |
diff --git a/src/util/service_new.c b/src/util/service_new.c index 90829c08c..22eec0bde 100644 --- a/src/util/service_new.c +++ b/src/util/service_new.c | |||
@@ -37,11 +37,11 @@ | |||
37 | #endif | 37 | #endif |
38 | 38 | ||
39 | 39 | ||
40 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 40 | #define LOG(kind,...) GNUNET_log_from (kind, "util-service", __VA_ARGS__) |
41 | 41 | ||
42 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall) | 42 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-service", syscall) |
43 | 43 | ||
44 | #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename) | 44 | #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util-service", syscall, filename) |
45 | 45 | ||
46 | 46 | ||
47 | /** | 47 | /** |
@@ -1969,6 +1969,7 @@ do_send (void *cls) | |||
1969 | client->msg_pos += ret; | 1969 | client->msg_pos += ret; |
1970 | if (left > ret) | 1970 | if (left > ret) |
1971 | { | 1971 | { |
1972 | GNUNET_assert (NULL == client->drop_task); | ||
1972 | client->send_task | 1973 | client->send_task |
1973 | = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, | 1974 | = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, |
1974 | client->sock, | 1975 | client->sock, |
@@ -1995,7 +1996,14 @@ service_mq_send (struct GNUNET_MQ_Handle *mq, | |||
1995 | { | 1996 | { |
1996 | struct GNUNET_SERVICE_Client *client = impl_state; | 1997 | struct GNUNET_SERVICE_Client *client = impl_state; |
1997 | 1998 | ||
1999 | if (NULL != client->drop_task) | ||
2000 | return; /* we're going down right now, do not try to send */ | ||
1998 | GNUNET_assert (NULL == client->send_task); | 2001 | GNUNET_assert (NULL == client->send_task); |
2002 | |||
2003 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
2004 | "Sending message of type %u and size %u to client\n", | ||
2005 | ntohs (msg->type), ntohs (msg->size)); | ||
2006 | |||
1999 | client->msg = msg; | 2007 | client->msg = msg; |
2000 | client->msg_pos = 0; | 2008 | client->msg_pos = 0; |
2001 | client->send_task | 2009 | client->send_task |
@@ -2094,6 +2102,10 @@ service_client_mst_cb (void *cls, | |||
2094 | { | 2102 | { |
2095 | struct GNUNET_SERVICE_Client *client = cls; | 2103 | struct GNUNET_SERVICE_Client *client = cls; |
2096 | 2104 | ||
2105 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
2106 | "Received message of type %u and size %u from client\n", | ||
2107 | ntohs (message->type), ntohs (message->size)); | ||
2108 | |||
2097 | GNUNET_assert (GNUNET_NO == client->needs_continue); | 2109 | GNUNET_assert (GNUNET_NO == client->needs_continue); |
2098 | client->needs_continue = GNUNET_YES; | 2110 | client->needs_continue = GNUNET_YES; |
2099 | client->warn_type = ntohs (message->type); | 2111 | client->warn_type = ntohs (message->type); |
@@ -2390,8 +2402,8 @@ resume_client_receive (void *cls) | |||
2390 | GNUNET_YES); | 2402 | GNUNET_YES); |
2391 | if (GNUNET_SYSERR == ret) | 2403 | if (GNUNET_SYSERR == ret) |
2392 | { | 2404 | { |
2393 | GNUNET_break (0); | 2405 | if (NULL != c->drop_task) |
2394 | GNUNET_SERVICE_client_drop (c); | 2406 | GNUNET_SERVICE_client_drop (c); |
2395 | return; | 2407 | return; |
2396 | } | 2408 | } |
2397 | if (GNUNET_NO == ret) | 2409 | if (GNUNET_NO == ret) |
@@ -2464,6 +2476,10 @@ finish_client_drop (void *cls) | |||
2464 | struct GNUNET_SERVICE_Client *c = cls; | 2476 | struct GNUNET_SERVICE_Client *c = cls; |
2465 | struct GNUNET_SERVICE_Handle *sh = c->sh; | 2477 | struct GNUNET_SERVICE_Handle *sh = c->sh; |
2466 | 2478 | ||
2479 | c->drop_task = NULL; | ||
2480 | GNUNET_assert (NULL == c->send_task); | ||
2481 | GNUNET_assert (NULL == c->recv_task); | ||
2482 | GNUNET_assert (NULL == c->warn_task); | ||
2467 | GNUNET_MST_destroy (c->mst); | 2483 | GNUNET_MST_destroy (c->mst); |
2468 | GNUNET_MQ_destroy (c->mq); | 2484 | GNUNET_MQ_destroy (c->mq); |
2469 | if (GNUNET_NO == c->persist) | 2485 | if (GNUNET_NO == c->persist) |
@@ -2500,7 +2516,7 @@ GNUNET_SERVICE_client_drop (struct GNUNET_SERVICE_Client *c) | |||
2500 | if (NULL != c->drop_task) | 2516 | if (NULL != c->drop_task) |
2501 | { | 2517 | { |
2502 | /* asked to drop twice! */ | 2518 | /* asked to drop twice! */ |
2503 | GNUNET_break (0); | 2519 | GNUNET_assert (0); |
2504 | return; | 2520 | return; |
2505 | } | 2521 | } |
2506 | GNUNET_CONTAINER_DLL_remove (sh->clients_head, | 2522 | GNUNET_CONTAINER_DLL_remove (sh->clients_head, |
diff --git a/src/util/signal.c b/src/util/signal.c index 543fcd899..cb917e36a 100644 --- a/src/util/signal.c +++ b/src/util/signal.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include "platform.h" | 27 | #include "platform.h" |
28 | #include "gnunet_util_lib.h" | 28 | #include "gnunet_util_lib.h" |
29 | 29 | ||
30 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 30 | #define LOG(kind,...) GNUNET_log_from (kind, "util-signal", __VA_ARGS__) |
31 | 31 | ||
32 | 32 | ||
33 | struct GNUNET_SIGNAL_Context | 33 | struct GNUNET_SIGNAL_Context |
diff --git a/src/util/socks.c b/src/util/socks.c index fee79cc80..37e60e3e4 100644 --- a/src/util/socks.c +++ b/src/util/socks.c | |||
@@ -29,9 +29,9 @@ | |||
29 | #include "gnunet_util_lib.h" | 29 | #include "gnunet_util_lib.h" |
30 | 30 | ||
31 | 31 | ||
32 | #define LOG(kind,...) GNUNET_log_from (kind, "socks", __VA_ARGS__) | 32 | #define LOG(kind,...) GNUNET_log_from (kind, "util-socks", __VA_ARGS__) |
33 | 33 | ||
34 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "socks", syscall) | 34 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-socks", syscall) |
35 | 35 | ||
36 | 36 | ||
37 | /* SOCKS5 authentication methods */ | 37 | /* SOCKS5 authentication methods */ |
diff --git a/src/util/speedup.c b/src/util/speedup.c index 97df65c8e..c6a4cf678 100644 --- a/src/util/speedup.c +++ b/src/util/speedup.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include "gnunet_util_lib.h" | 27 | #include "gnunet_util_lib.h" |
28 | #include "speedup.h" | 28 | #include "speedup.h" |
29 | 29 | ||
30 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 30 | #define LOG(kind,...) GNUNET_log_from (kind, "util-speedup", __VA_ARGS__) |
31 | 31 | ||
32 | 32 | ||
33 | static struct GNUNET_TIME_Relative interval; | 33 | static struct GNUNET_TIME_Relative interval; |
diff --git a/src/util/strings.c b/src/util/strings.c index 2b51d3e52..d3268f4d9 100644 --- a/src/util/strings.c +++ b/src/util/strings.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2005-2013 GNUnet e.V. | 3 | Copyright (C) 2005-2017 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -17,7 +17,6 @@ | |||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
18 | Boston, MA 02110-1301, USA. | 18 | Boston, MA 02110-1301, USA. |
19 | */ | 19 | */ |
20 | |||
21 | /** | 20 | /** |
22 | * @file util/strings.c | 21 | * @file util/strings.c |
23 | * @brief string functions | 22 | * @brief string functions |
@@ -35,9 +34,9 @@ | |||
35 | #include <unistr.h> | 34 | #include <unistr.h> |
36 | #include <uniconv.h> | 35 | #include <uniconv.h> |
37 | 36 | ||
38 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 37 | #define LOG(kind,...) GNUNET_log_from (kind, "util-strings", __VA_ARGS__) |
39 | 38 | ||
40 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall) | 39 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-strings", syscall) |
41 | 40 | ||
42 | 41 | ||
43 | /** | 42 | /** |
@@ -90,6 +89,37 @@ GNUNET_STRINGS_buffer_fill (char *buffer, size_t size, unsigned int count, ...) | |||
90 | 89 | ||
91 | 90 | ||
92 | /** | 91 | /** |
92 | * Convert a peer path to a human-readable string. | ||
93 | * | ||
94 | * @param pids array of PIDs to convert to a string | ||
95 | * @param num_pids length of the @a pids array | ||
96 | * @return string representing the array of @a pids | ||
97 | */ | ||
98 | char * | ||
99 | GNUNET_STRINGS_pp2s (const struct GNUNET_PeerIdentity *pids, | ||
100 | unsigned int num_pids) | ||
101 | { | ||
102 | char *buf; | ||
103 | size_t off; | ||
104 | size_t plen = num_pids * 5 + 1; | ||
105 | |||
106 | off = 0; | ||
107 | buf = GNUNET_malloc (plen); | ||
108 | for (unsigned int i = 0; | ||
109 | i < num_pids; | ||
110 | i++) | ||
111 | { | ||
112 | off += GNUNET_snprintf (&buf[off], | ||
113 | plen - off, | ||
114 | "%s%s", | ||
115 | GNUNET_i2s (&pids[i]), | ||
116 | (i == num_pids -1) ? "" : "-"); | ||
117 | } | ||
118 | return buf; | ||
119 | } | ||
120 | |||
121 | |||
122 | /** | ||
93 | * Given a buffer of a given size, find "count" | 123 | * Given a buffer of a given size, find "count" |
94 | * 0-terminated strings in the buffer and assign | 124 | * 0-terminated strings in the buffer and assign |
95 | * the count (varargs) of type "const char**" to the | 125 | * the count (varargs) of type "const char**" to the |
diff --git a/src/util/time.c b/src/util/time.c index 89b0c2d44..19100ac36 100644 --- a/src/util/time.c +++ b/src/util/time.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include "gnunet_crypto_lib.h" | 27 | #include "gnunet_crypto_lib.h" |
28 | #include "gnunet_time_lib.h" | 28 | #include "gnunet_time_lib.h" |
29 | 29 | ||
30 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 30 | #define LOG(kind,...) GNUNET_log_from (kind, "util-time", __VA_ARGS__) |
31 | 31 | ||
32 | /** | 32 | /** |
33 | * Variable used to simulate clock skew. Used for testing, never in production. | 33 | * Variable used to simulate clock skew. Used for testing, never in production. |
diff --git a/src/util/win.c b/src/util/win.c index 7cd7e0f3c..97877b0ca 100644 --- a/src/util/win.c +++ b/src/util/win.c | |||
@@ -534,10 +534,9 @@ EnumNICs3 (struct EnumNICs3_results **results, int *results_count) | |||
534 | for (i = 0; !found && i < interfaces4_len / sizeof (INTERFACE_INFO); i++) | 534 | for (i = 0; !found && i < interfaces4_len / sizeof (INTERFACE_INFO); i++) |
535 | { | 535 | { |
536 | struct sockaddr_in *m = (struct sockaddr_in *) &r->mask; | 536 | struct sockaddr_in *m = (struct sockaddr_in *) &r->mask; |
537 | if (GNUNET_memcpy (&interfaces4[i].iiAddress.Address, | 537 | GNUNET_memcpy (&interfaces4[i].iiAddress.Address, |
538 | unicast->Address.lpSockaddr, | 538 | unicast->Address.lpSockaddr, |
539 | unicast->Address.iSockaddrLength) != 0) | 539 | unicast->Address.iSockaddrLength); |
540 | continue; | ||
541 | found = 1; | 540 | found = 1; |
542 | GNUNET_memcpy (&r->address, &interfaces4[i].iiAddress.Address, | 541 | GNUNET_memcpy (&r->address, &interfaces4[i].iiAddress.Address, |
543 | sizeof (struct sockaddr_in)); | 542 | sizeof (struct sockaddr_in)); |
@@ -557,10 +556,9 @@ EnumNICs3 (struct EnumNICs3_results **results, int *results_count) | |||
557 | interfaces6 != NULL && !found && i < interfaces6->iAddressCount; | 556 | interfaces6 != NULL && !found && i < interfaces6->iAddressCount; |
558 | i++) | 557 | i++) |
559 | { | 558 | { |
560 | if (GNUNET_memcpy (interfaces6->Address[i].lpSockaddr, | 559 | GNUNET_memcpy (interfaces6->Address[i].lpSockaddr, |
561 | unicast->Address.lpSockaddr, | 560 | unicast->Address.lpSockaddr, |
562 | unicast->Address.iSockaddrLength) != 0) | 561 | unicast->Address.iSockaddrLength); |
563 | continue; | ||
564 | found = 1; | 562 | found = 1; |
565 | GNUNET_memcpy (&r->address, interfaces6->Address[i].lpSockaddr, | 563 | GNUNET_memcpy (&r->address, interfaces6->Address[i].lpSockaddr, |
566 | sizeof (struct sockaddr_in6)); | 564 | sizeof (struct sockaddr_in6)); |
diff --git a/src/util/winproc.c b/src/util/winproc.c index 66c225ce5..318b68a88 100644 --- a/src/util/winproc.c +++ b/src/util/winproc.c | |||
@@ -69,7 +69,7 @@ TAddAce GNAddAce; | |||
69 | TAddAccessAllowedAce GNAddAccessAllowedAce; | 69 | TAddAccessAllowedAce GNAddAccessAllowedAce; |
70 | TSetNamedSecurityInfo GNSetNamedSecurityInfo; | 70 | TSetNamedSecurityInfo GNSetNamedSecurityInfo; |
71 | 71 | ||
72 | #define LOG(kind,...) GNUNET_log_from (kind, "winproc", __VA_ARGS__) | 72 | #define LOG(kind,...) GNUNET_log_from (kind, "util-winproc", __VA_ARGS__) |
73 | /** | 73 | /** |
74 | * Log (panic) messages from PlibC | 74 | * Log (panic) messages from PlibC |
75 | */ | 75 | */ |
diff --git a/src/vpn/Makefile.am b/src/vpn/Makefile.am index 5517a45e3..417d2eb89 100644 --- a/src/vpn/Makefile.am +++ b/src/vpn/Makefile.am | |||
@@ -59,7 +59,7 @@ gnunet_service_vpn_LDADD = \ | |||
59 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | 59 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ |
60 | $(top_builddir)/src/tun/libgnunettun.la \ | 60 | $(top_builddir)/src/tun/libgnunettun.la \ |
61 | $(top_builddir)/src/util/libgnunetutil.la \ | 61 | $(top_builddir)/src/util/libgnunetutil.la \ |
62 | $(top_builddir)/src/cadet/libgnunetcadet.la \ | 62 | $(top_builddir)/src/cadet/libgnunetcadetnew.la \ |
63 | $(top_builddir)/src/regex/libgnunetregex.la \ | 63 | $(top_builddir)/src/regex/libgnunetregex.la \ |
64 | $(GN_LIBINTL) | 64 | $(GN_LIBINTL) |
65 | gnunet_service_vpn_CFLAGS = \ | 65 | gnunet_service_vpn_CFLAGS = \ |
@@ -79,5 +79,3 @@ libgnunetvpn_la_LIBADD = \ | |||
79 | $(top_builddir)/src/util/libgnunetutil.la $(XLIB) | 79 | $(top_builddir)/src/util/libgnunetutil.la $(XLIB) |
80 | libgnunetvpn_la_LDFLAGS = \ | 80 | libgnunetvpn_la_LDFLAGS = \ |
81 | $(GN_LIB_LDFLAGS) | 81 | $(GN_LIB_LDFLAGS) |
82 | |||
83 | |||
diff --git a/src/vpn/gnunet-service-vpn.c b/src/vpn/gnunet-service-vpn.c index c66023c85..aa0ea51a3 100644 --- a/src/vpn/gnunet-service-vpn.c +++ b/src/vpn/gnunet-service-vpn.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2010, 2011, 2012, 2016 Christian Grothoff | 3 | Copyright (C) 2010, 2011, 2012, 2016, 2017 Christian Grothoff |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -221,11 +221,6 @@ struct ChannelState | |||
221 | struct GNUNET_REGEX_Search *search; | 221 | struct GNUNET_REGEX_Search *search; |
222 | 222 | ||
223 | /** | 223 | /** |
224 | * Active transmission handle, NULL for none. | ||
225 | */ | ||
226 | struct GNUNET_CADET_TransmitHandle *th; | ||
227 | |||
228 | /** | ||
229 | * Entry for this entry in the channel_heap, NULL as long as this | 224 | * Entry for this entry in the channel_heap, NULL as long as this |
230 | * channel state is not fully bound. | 225 | * channel state is not fully bound. |
231 | */ | 226 | */ |
@@ -535,11 +530,6 @@ free_channel_state (struct ChannelState *ts) | |||
535 | 530 | ||
536 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 531 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
537 | "Cleaning up channel state\n"); | 532 | "Cleaning up channel state\n"); |
538 | if (NULL != ts->th) | ||
539 | { | ||
540 | GNUNET_CADET_notify_transmit_ready_cancel (ts->th); | ||
541 | ts->th = NULL; | ||
542 | } | ||
543 | if (NULL != (channel = ts->channel)) | 533 | if (NULL != (channel = ts->channel)) |
544 | { | 534 | { |
545 | ts->channel = NULL; | 535 | ts->channel = NULL; |
@@ -585,97 +575,32 @@ free_channel_state (struct ChannelState *ts) | |||
585 | 575 | ||
586 | 576 | ||
587 | /** | 577 | /** |
588 | * Send a message from the message queue via cadet. | ||
589 | * | ||
590 | * @param cls the `struct ChannelState` with the message queue | ||
591 | * @param size number of bytes available in @a buf | ||
592 | * @param buf where to copy the message | ||
593 | * @return number of bytes copied to @a buf | ||
594 | */ | ||
595 | static size_t | ||
596 | send_to_peer_notify_callback (void *cls, size_t size, void *buf) | ||
597 | { | ||
598 | struct ChannelState *ts = cls; | ||
599 | struct ChannelMessageQueueEntry *tnq; | ||
600 | size_t ret; | ||
601 | |||
602 | ts->th = NULL; | ||
603 | if (NULL == buf) | ||
604 | return 0; | ||
605 | tnq = ts->tmq_head; | ||
606 | GNUNET_assert (NULL != tnq); | ||
607 | GNUNET_assert (size >= tnq->len); | ||
608 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
609 | "Sending %u bytes via cadet channel\n", | ||
610 | (unsigned int) tnq->len); | ||
611 | GNUNET_CONTAINER_DLL_remove (ts->tmq_head, | ||
612 | ts->tmq_tail, | ||
613 | tnq); | ||
614 | ts->tmq_length--; | ||
615 | GNUNET_memcpy (buf, tnq->msg, tnq->len); | ||
616 | ret = tnq->len; | ||
617 | GNUNET_free (tnq); | ||
618 | if (NULL != (tnq = ts->tmq_head)) | ||
619 | { | ||
620 | if (NULL == ts->th) | ||
621 | ts->th = GNUNET_CADET_notify_transmit_ready (ts->channel, | ||
622 | GNUNET_NO /* cork */, | ||
623 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
624 | tnq->len, | ||
625 | &send_to_peer_notify_callback, | ||
626 | ts); | ||
627 | } | ||
628 | GNUNET_STATISTICS_update (stats, | ||
629 | gettext_noop ("# Bytes given to cadet for transmission"), | ||
630 | ret, GNUNET_NO); | ||
631 | return ret; | ||
632 | } | ||
633 | |||
634 | |||
635 | /** | ||
636 | * Add the given message to the given channel and trigger the | 578 | * Add the given message to the given channel and trigger the |
637 | * transmission process. | 579 | * transmission process. |
638 | * | 580 | * |
639 | * @param tnq message to queue | ||
640 | * @param ts channel to queue the message for | 581 | * @param ts channel to queue the message for |
582 | * @param env message to queue | ||
641 | */ | 583 | */ |
642 | static void | 584 | static void |
643 | send_to_channel (struct ChannelMessageQueueEntry *tnq, | 585 | send_to_channel (struct ChannelState *ts, |
644 | struct ChannelState *ts) | 586 | struct GNUNET_MQ_Envelope *env) |
645 | { | 587 | { |
646 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 588 | struct GNUNET_MQ_Handle *mq; |
647 | "Queueing %u bytes for transmission via cadet channel\n", | 589 | |
648 | (unsigned int) tnq->len); | ||
649 | GNUNET_assert (NULL != ts->channel); | 590 | GNUNET_assert (NULL != ts->channel); |
650 | GNUNET_CONTAINER_DLL_insert_tail (ts->tmq_head, | 591 | mq = GNUNET_CADET_get_mq (ts->channel); |
651 | ts->tmq_tail, | 592 | GNUNET_MQ_send (mq, |
652 | tnq); | 593 | env); |
653 | ts->tmq_length++; | 594 | if (GNUNET_MQ_get_length (mq) > MAX_MESSAGE_QUEUE_SIZE) |
654 | if (ts->tmq_length > MAX_MESSAGE_QUEUE_SIZE) | ||
655 | { | 595 | { |
656 | struct ChannelMessageQueueEntry *dq; | 596 | env = GNUNET_MQ_unsent_head (mq); |
657 | 597 | GNUNET_assert (NULL != env); | |
658 | dq = ts->tmq_head; | ||
659 | GNUNET_assert (dq != tnq); | ||
660 | GNUNET_CONTAINER_DLL_remove (ts->tmq_head, | ||
661 | ts->tmq_tail, | ||
662 | dq); | ||
663 | ts->tmq_length--; | ||
664 | GNUNET_CADET_notify_transmit_ready_cancel (ts->th); | ||
665 | ts->th = NULL; | ||
666 | GNUNET_STATISTICS_update (stats, | 598 | GNUNET_STATISTICS_update (stats, |
667 | gettext_noop ("# Bytes dropped in cadet queue (overflow)"), | 599 | gettext_noop ("# Messages dropped in cadet queue (overflow)"), |
668 | dq->len, | 600 | 1, |
669 | GNUNET_NO); | 601 | GNUNET_NO); |
670 | GNUNET_free (dq); | 602 | GNUNET_MQ_discard (env); |
671 | } | 603 | } |
672 | if (NULL == ts->th) | ||
673 | ts->th = GNUNET_CADET_notify_transmit_ready (ts->channel, | ||
674 | GNUNET_NO /* cork */, | ||
675 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
676 | tnq->len, | ||
677 | &send_to_peer_notify_callback, | ||
678 | ts); | ||
679 | } | 604 | } |
680 | 605 | ||
681 | 606 | ||
@@ -710,6 +635,767 @@ print_channel_destination (const struct DestinationEntry *de) | |||
710 | 635 | ||
711 | 636 | ||
712 | /** | 637 | /** |
638 | * Function called whenever a channel is destroyed. Should clean up | ||
639 | * any associated state. | ||
640 | * | ||
641 | * @param cls our `struct ChannelState` | ||
642 | * @param channel connection to the other end (henceforth invalid) | ||
643 | */ | ||
644 | static void | ||
645 | channel_cleaner (void *cls, | ||
646 | const struct GNUNET_CADET_Channel *channel) | ||
647 | { | ||
648 | struct ChannelState *ts = cls; | ||
649 | |||
650 | ts->channel = NULL; /* we must not call GNUNET_CADET_channel_destroy() anymore */ | ||
651 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
652 | "CADET notified us about death of channel to `%s'\n", | ||
653 | print_channel_destination (&ts->destination)); | ||
654 | free_channel_state (ts); | ||
655 | } | ||
656 | |||
657 | |||
658 | /** | ||
659 | * Synthesize a plausible ICMP payload for an ICMP error | ||
660 | * response on the given channel. | ||
661 | * | ||
662 | * @param ts channel information | ||
663 | * @param ipp IPv4 header to fill in (ICMP payload) | ||
664 | * @param udp "UDP" header to fill in (ICMP payload); might actually | ||
665 | * also be the first 8 bytes of the TCP header | ||
666 | */ | ||
667 | static void | ||
668 | make_up_icmpv4_payload (struct ChannelState *ts, | ||
669 | struct GNUNET_TUN_IPv4Header *ipp, | ||
670 | struct GNUNET_TUN_UdpHeader *udp) | ||
671 | { | ||
672 | GNUNET_TUN_initialize_ipv4_header (ipp, | ||
673 | ts->protocol, | ||
674 | sizeof (struct GNUNET_TUN_TcpHeader), | ||
675 | &ts->source_ip.v4, | ||
676 | &ts->destination_ip.v4); | ||
677 | udp->source_port = htons (ts->source_port); | ||
678 | udp->destination_port = htons (ts->destination_port); | ||
679 | udp->len = htons (0); | ||
680 | udp->crc = htons (0); | ||
681 | } | ||
682 | |||
683 | |||
684 | /** | ||
685 | * Synthesize a plausible ICMP payload for an ICMP error | ||
686 | * response on the given channel. | ||
687 | * | ||
688 | * @param ts channel information | ||
689 | * @param ipp IPv6 header to fill in (ICMP payload) | ||
690 | * @param udp "UDP" header to fill in (ICMP payload); might actually | ||
691 | * also be the first 8 bytes of the TCP header | ||
692 | */ | ||
693 | static void | ||
694 | make_up_icmpv6_payload (struct ChannelState *ts, | ||
695 | struct GNUNET_TUN_IPv6Header *ipp, | ||
696 | struct GNUNET_TUN_UdpHeader *udp) | ||
697 | { | ||
698 | GNUNET_TUN_initialize_ipv6_header (ipp, | ||
699 | ts->protocol, | ||
700 | sizeof (struct GNUNET_TUN_TcpHeader), | ||
701 | &ts->source_ip.v6, | ||
702 | &ts->destination_ip.v6); | ||
703 | udp->source_port = htons (ts->source_port); | ||
704 | udp->destination_port = htons (ts->destination_port); | ||
705 | udp->len = htons (0); | ||
706 | udp->crc = htons (0); | ||
707 | } | ||
708 | |||
709 | |||
710 | /** | ||
711 | * We got an ICMP packet back from the CADET channel. Check it is OK. | ||
712 | * | ||
713 | * @param cls our `struct ChannelState *` | ||
714 | * @param message the actual message | ||
715 | * @return #GNUNET_OK to keep the connection open, | ||
716 | * #GNUNET_SYSERR to close it (signal serious error) | ||
717 | */ | ||
718 | static int | ||
719 | check_icmp_back (void *cls, | ||
720 | const struct GNUNET_EXIT_IcmpToVPNMessage *i2v) | ||
721 | { | ||
722 | struct ChannelState *ts = cls; | ||
723 | |||
724 | if (NULL == ts->heap_node) | ||
725 | { | ||
726 | GNUNET_break_op (0); | ||
727 | return GNUNET_SYSERR; | ||
728 | } | ||
729 | if (AF_UNSPEC == ts->af) | ||
730 | { | ||
731 | GNUNET_break_op (0); | ||
732 | return GNUNET_SYSERR; | ||
733 | } | ||
734 | return GNUNET_OK; | ||
735 | } | ||
736 | |||
737 | |||
738 | /** | ||
739 | * We got an ICMP packet back from the CADET channel. Pass it on to the | ||
740 | * local virtual interface via the helper. | ||
741 | * | ||
742 | * @param cls our `struct ChannelState *` | ||
743 | * @param message the actual message | ||
744 | */ | ||
745 | static void | ||
746 | handle_icmp_back (void *cls, | ||
747 | const struct GNUNET_EXIT_IcmpToVPNMessage *i2v) | ||
748 | { | ||
749 | struct ChannelState *ts = cls; | ||
750 | size_t mlen; | ||
751 | |||
752 | GNUNET_STATISTICS_update (stats, | ||
753 | gettext_noop ("# ICMP packets received from cadet"), | ||
754 | 1, | ||
755 | GNUNET_NO); | ||
756 | mlen = ntohs (i2v->header.size) - sizeof (struct GNUNET_EXIT_IcmpToVPNMessage); | ||
757 | { | ||
758 | char sbuf[INET6_ADDRSTRLEN]; | ||
759 | char dbuf[INET6_ADDRSTRLEN]; | ||
760 | |||
761 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
762 | "Received ICMP packet from cadet, sending %u bytes from %s -> %s via TUN\n", | ||
763 | (unsigned int) mlen, | ||
764 | inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof (sbuf)), | ||
765 | inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof (dbuf))); | ||
766 | } | ||
767 | switch (ts->af) | ||
768 | { | ||
769 | case AF_INET: | ||
770 | { | ||
771 | size_t size = sizeof (struct GNUNET_TUN_IPv4Header) | ||
772 | + sizeof (struct GNUNET_TUN_IcmpHeader) | ||
773 | + sizeof (struct GNUNET_MessageHeader) + | ||
774 | sizeof (struct GNUNET_TUN_Layer2PacketHeader) + | ||
775 | mlen; | ||
776 | { | ||
777 | /* reserve some extra space in case we have an ICMP type here where | ||
778 | we will need to make up the payload ourselves */ | ||
779 | char buf[size + sizeof (struct GNUNET_TUN_IPv4Header) + 8] GNUNET_ALIGN; | ||
780 | struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; | ||
781 | struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1]; | ||
782 | struct GNUNET_TUN_IPv4Header *ipv4 = (struct GNUNET_TUN_IPv4Header *) &tun[1]; | ||
783 | struct GNUNET_TUN_IcmpHeader *icmp = (struct GNUNET_TUN_IcmpHeader *) &ipv4[1]; | ||
784 | msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
785 | tun->flags = htons (0); | ||
786 | tun->proto = htons (ETH_P_IPV4); | ||
787 | GNUNET_TUN_initialize_ipv4_header (ipv4, | ||
788 | IPPROTO_ICMP, | ||
789 | sizeof (struct GNUNET_TUN_IcmpHeader) + mlen, | ||
790 | &ts->destination_ip.v4, | ||
791 | &ts->source_ip.v4); | ||
792 | *icmp = i2v->icmp_header; | ||
793 | GNUNET_memcpy (&icmp[1], | ||
794 | &i2v[1], | ||
795 | mlen); | ||
796 | /* For some ICMP types, we need to adjust (make up) the payload here. | ||
797 | Also, depending on the AF used on the other side, we have to | ||
798 | do ICMP PT (translate ICMP types) */ | ||
799 | switch (ntohl (i2v->af)) | ||
800 | { | ||
801 | case AF_INET: | ||
802 | switch (icmp->type) | ||
803 | { | ||
804 | case GNUNET_TUN_ICMPTYPE_ECHO_REPLY: | ||
805 | case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST: | ||
806 | break; | ||
807 | case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE: | ||
808 | case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH: | ||
809 | case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED: | ||
810 | { | ||
811 | struct GNUNET_TUN_IPv4Header *ipp = (struct GNUNET_TUN_IPv4Header *) &icmp[1]; | ||
812 | struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1]; | ||
813 | |||
814 | if (mlen != 0) | ||
815 | { | ||
816 | /* sender did not strip ICMP payload? */ | ||
817 | GNUNET_break_op (0); | ||
818 | return; | ||
819 | } | ||
820 | size += sizeof (struct GNUNET_TUN_IPv4Header) + 8; | ||
821 | GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); | ||
822 | make_up_icmpv4_payload (ts, ipp, udp); | ||
823 | } | ||
824 | break; | ||
825 | default: | ||
826 | GNUNET_break_op (0); | ||
827 | GNUNET_STATISTICS_update (stats, | ||
828 | gettext_noop ("# ICMPv4 packets dropped (type not allowed)"), | ||
829 | 1, GNUNET_NO); | ||
830 | return; | ||
831 | } | ||
832 | /* end AF_INET */ | ||
833 | break; | ||
834 | case AF_INET6: | ||
835 | /* ICMP PT 6-to-4 and possibly making up payloads */ | ||
836 | switch (icmp->type) | ||
837 | { | ||
838 | case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE: | ||
839 | icmp->type = GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE; | ||
840 | { | ||
841 | struct GNUNET_TUN_IPv4Header *ipp = (struct GNUNET_TUN_IPv4Header *) &icmp[1]; | ||
842 | struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1]; | ||
843 | |||
844 | if (mlen != 0) | ||
845 | { | ||
846 | /* sender did not strip ICMP payload? */ | ||
847 | GNUNET_break_op (0); | ||
848 | return; | ||
849 | } | ||
850 | size += sizeof (struct GNUNET_TUN_IPv4Header) + 8; | ||
851 | GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); | ||
852 | make_up_icmpv4_payload (ts, ipp, udp); | ||
853 | } | ||
854 | break; | ||
855 | case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED: | ||
856 | icmp->type = GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED; | ||
857 | { | ||
858 | struct GNUNET_TUN_IPv4Header *ipp = (struct GNUNET_TUN_IPv4Header *) &icmp[1]; | ||
859 | struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1]; | ||
860 | |||
861 | if (mlen != 0) | ||
862 | { | ||
863 | /* sender did not strip ICMP payload? */ | ||
864 | GNUNET_break_op (0); | ||
865 | return; | ||
866 | } | ||
867 | size += sizeof (struct GNUNET_TUN_IPv4Header) + 8; | ||
868 | GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); | ||
869 | make_up_icmpv4_payload (ts, ipp, udp); | ||
870 | } | ||
871 | break; | ||
872 | case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG: | ||
873 | case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM: | ||
874 | GNUNET_STATISTICS_update (stats, | ||
875 | gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"), | ||
876 | 1, GNUNET_NO); | ||
877 | return; | ||
878 | case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST: | ||
879 | icmp->type = GNUNET_TUN_ICMPTYPE_ECHO_REQUEST; | ||
880 | break; | ||
881 | case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY: | ||
882 | icmp->type = GNUNET_TUN_ICMPTYPE_ECHO_REPLY; | ||
883 | break; | ||
884 | default: | ||
885 | GNUNET_break_op (0); | ||
886 | GNUNET_STATISTICS_update (stats, | ||
887 | gettext_noop ("# ICMPv6 packets dropped (type not allowed)"), | ||
888 | 1, GNUNET_NO); | ||
889 | return; | ||
890 | } | ||
891 | /* end AF_INET6 */ | ||
892 | break; | ||
893 | default: | ||
894 | GNUNET_break_op (0); | ||
895 | return; | ||
896 | } | ||
897 | msg->size = htons (size); | ||
898 | GNUNET_TUN_calculate_icmp_checksum (icmp, | ||
899 | &i2v[1], | ||
900 | mlen); | ||
901 | (void) GNUNET_HELPER_send (helper_handle, | ||
902 | msg, | ||
903 | GNUNET_YES, | ||
904 | NULL, NULL); | ||
905 | } | ||
906 | } | ||
907 | break; | ||
908 | case AF_INET6: | ||
909 | { | ||
910 | size_t size = sizeof (struct GNUNET_TUN_IPv6Header) | ||
911 | + sizeof (struct GNUNET_TUN_IcmpHeader) | ||
912 | + sizeof (struct GNUNET_MessageHeader) + | ||
913 | sizeof (struct GNUNET_TUN_Layer2PacketHeader) + | ||
914 | mlen; | ||
915 | { | ||
916 | char buf[size + sizeof (struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN; | ||
917 | struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; | ||
918 | struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1]; | ||
919 | struct GNUNET_TUN_IPv6Header *ipv6 = (struct GNUNET_TUN_IPv6Header *) &tun[1]; | ||
920 | struct GNUNET_TUN_IcmpHeader *icmp = (struct GNUNET_TUN_IcmpHeader *) &ipv6[1]; | ||
921 | msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
922 | tun->flags = htons (0); | ||
923 | tun->proto = htons (ETH_P_IPV6); | ||
924 | GNUNET_TUN_initialize_ipv6_header (ipv6, | ||
925 | IPPROTO_ICMPV6, | ||
926 | sizeof (struct GNUNET_TUN_IcmpHeader) + mlen, | ||
927 | &ts->destination_ip.v6, | ||
928 | &ts->source_ip.v6); | ||
929 | *icmp = i2v->icmp_header; | ||
930 | GNUNET_memcpy (&icmp[1], | ||
931 | &i2v[1], | ||
932 | mlen); | ||
933 | |||
934 | /* For some ICMP types, we need to adjust (make up) the payload here. | ||
935 | Also, depending on the AF used on the other side, we have to | ||
936 | do ICMP PT (translate ICMP types) */ | ||
937 | switch (ntohl (i2v->af)) | ||
938 | { | ||
939 | case AF_INET: | ||
940 | /* ICMP PT 4-to-6 and possibly making up payloads */ | ||
941 | switch (icmp->type) | ||
942 | { | ||
943 | case GNUNET_TUN_ICMPTYPE_ECHO_REPLY: | ||
944 | icmp->type = GNUNET_TUN_ICMPTYPE6_ECHO_REPLY; | ||
945 | break; | ||
946 | case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST: | ||
947 | icmp->type = GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST; | ||
948 | break; | ||
949 | case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE: | ||
950 | icmp->type = GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE; | ||
951 | { | ||
952 | struct GNUNET_TUN_IPv6Header *ipp = (struct GNUNET_TUN_IPv6Header *) &icmp[1]; | ||
953 | struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1]; | ||
954 | |||
955 | if (mlen != 0) | ||
956 | { | ||
957 | /* sender did not strip ICMP payload? */ | ||
958 | GNUNET_break_op (0); | ||
959 | return; | ||
960 | } | ||
961 | size += sizeof (struct GNUNET_TUN_IPv6Header) + 8; | ||
962 | GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); | ||
963 | make_up_icmpv6_payload (ts, ipp, udp); | ||
964 | } | ||
965 | break; | ||
966 | case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED: | ||
967 | icmp->type = GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED; | ||
968 | { | ||
969 | struct GNUNET_TUN_IPv6Header *ipp = (struct GNUNET_TUN_IPv6Header *) &icmp[1]; | ||
970 | struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1]; | ||
971 | |||
972 | if (mlen != 0) | ||
973 | { | ||
974 | /* sender did not strip ICMP payload? */ | ||
975 | GNUNET_break_op (0); | ||
976 | return; | ||
977 | } | ||
978 | size += sizeof (struct GNUNET_TUN_IPv6Header) + 8; | ||
979 | GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); | ||
980 | make_up_icmpv6_payload (ts, ipp, udp); | ||
981 | } | ||
982 | break; | ||
983 | case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH: | ||
984 | GNUNET_STATISTICS_update (stats, | ||
985 | gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"), | ||
986 | 1, GNUNET_NO); | ||
987 | return; | ||
988 | default: | ||
989 | GNUNET_break_op (0); | ||
990 | GNUNET_STATISTICS_update (stats, | ||
991 | gettext_noop ("# ICMPv4 packets dropped (type not allowed)"), | ||
992 | 1, GNUNET_NO); | ||
993 | return; | ||
994 | } | ||
995 | /* end AF_INET */ | ||
996 | break; | ||
997 | case AF_INET6: | ||
998 | switch (icmp->type) | ||
999 | { | ||
1000 | case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE: | ||
1001 | case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED: | ||
1002 | case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG: | ||
1003 | case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM: | ||
1004 | { | ||
1005 | struct GNUNET_TUN_IPv6Header *ipp = (struct GNUNET_TUN_IPv6Header *) &icmp[1]; | ||
1006 | struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1]; | ||
1007 | |||
1008 | if (mlen != 0) | ||
1009 | { | ||
1010 | /* sender did not strip ICMP payload? */ | ||
1011 | GNUNET_break_op (0); | ||
1012 | return; | ||
1013 | } | ||
1014 | size += sizeof (struct GNUNET_TUN_IPv6Header) + 8; | ||
1015 | GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); | ||
1016 | make_up_icmpv6_payload (ts, ipp, udp); | ||
1017 | } | ||
1018 | break; | ||
1019 | case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST: | ||
1020 | break; | ||
1021 | default: | ||
1022 | GNUNET_break_op (0); | ||
1023 | GNUNET_STATISTICS_update (stats, | ||
1024 | gettext_noop ("# ICMPv6 packets dropped (type not allowed)"), | ||
1025 | 1, GNUNET_NO); | ||
1026 | return; | ||
1027 | } | ||
1028 | /* end AF_INET6 */ | ||
1029 | break; | ||
1030 | default: | ||
1031 | GNUNET_break_op (0); | ||
1032 | return; | ||
1033 | } | ||
1034 | msg->size = htons (size); | ||
1035 | GNUNET_TUN_calculate_icmp_checksum (icmp, | ||
1036 | &i2v[1], mlen); | ||
1037 | (void) GNUNET_HELPER_send (helper_handle, | ||
1038 | msg, | ||
1039 | GNUNET_YES, | ||
1040 | NULL, NULL); | ||
1041 | } | ||
1042 | } | ||
1043 | break; | ||
1044 | default: | ||
1045 | GNUNET_assert (0); | ||
1046 | } | ||
1047 | GNUNET_CONTAINER_heap_update_cost (ts->heap_node, | ||
1048 | GNUNET_TIME_absolute_get ().abs_value_us); | ||
1049 | GNUNET_CADET_receive_done (ts->channel); | ||
1050 | } | ||
1051 | |||
1052 | |||
1053 | /** | ||
1054 | * We got a UDP packet back from the CADET channel. Check that it is OK. | ||
1055 | * | ||
1056 | * @param cls our `struct ChannelState *` | ||
1057 | * @param reply the actual message | ||
1058 | * @return #GNUNET_OK to keep the connection open, | ||
1059 | * #GNUNET_SYSERR to close it (signal serious error) | ||
1060 | */ | ||
1061 | static int | ||
1062 | check_udp_back (void *cls, | ||
1063 | const struct GNUNET_EXIT_UdpReplyMessage *reply) | ||
1064 | { | ||
1065 | struct ChannelState *ts = cls; | ||
1066 | |||
1067 | if (NULL == ts->heap_node) | ||
1068 | { | ||
1069 | GNUNET_break_op (0); | ||
1070 | return GNUNET_SYSERR; | ||
1071 | } | ||
1072 | if (AF_UNSPEC == ts->af) | ||
1073 | { | ||
1074 | GNUNET_break_op (0); | ||
1075 | return GNUNET_SYSERR; | ||
1076 | } | ||
1077 | return GNUNET_OK; | ||
1078 | } | ||
1079 | |||
1080 | |||
1081 | /** | ||
1082 | * We got a UDP packet back from the CADET channel. Pass it on to the | ||
1083 | * local virtual interface via the helper. | ||
1084 | * | ||
1085 | * @param cls our `struct ChannelState *` | ||
1086 | * @param reply the actual message | ||
1087 | */ | ||
1088 | static void | ||
1089 | handle_udp_back (void *cls, | ||
1090 | const struct GNUNET_EXIT_UdpReplyMessage *reply) | ||
1091 | { | ||
1092 | struct ChannelState *ts = cls; | ||
1093 | size_t mlen; | ||
1094 | |||
1095 | GNUNET_STATISTICS_update (stats, | ||
1096 | gettext_noop ("# UDP packets received from cadet"), | ||
1097 | 1, | ||
1098 | GNUNET_NO); | ||
1099 | mlen = ntohs (reply->header.size) - sizeof (struct GNUNET_EXIT_UdpReplyMessage); | ||
1100 | { | ||
1101 | char sbuf[INET6_ADDRSTRLEN]; | ||
1102 | char dbuf[INET6_ADDRSTRLEN]; | ||
1103 | |||
1104 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1105 | "Received UDP reply from cadet, sending %u bytes from [%s]:%u -> [%s]:%u via TUN\n", | ||
1106 | (unsigned int) mlen, | ||
1107 | inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof (sbuf)), | ||
1108 | ts->destination_port, | ||
1109 | inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof (dbuf)), | ||
1110 | ts->source_port); | ||
1111 | } | ||
1112 | switch (ts->af) | ||
1113 | { | ||
1114 | case AF_INET: | ||
1115 | { | ||
1116 | size_t size = sizeof (struct GNUNET_TUN_IPv4Header) | ||
1117 | + sizeof (struct GNUNET_TUN_UdpHeader) | ||
1118 | + sizeof (struct GNUNET_MessageHeader) + | ||
1119 | sizeof (struct GNUNET_TUN_Layer2PacketHeader) + | ||
1120 | mlen; | ||
1121 | { | ||
1122 | char buf[size] GNUNET_ALIGN; | ||
1123 | struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; | ||
1124 | struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1]; | ||
1125 | struct GNUNET_TUN_IPv4Header *ipv4 = (struct GNUNET_TUN_IPv4Header *) &tun[1]; | ||
1126 | struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipv4[1]; | ||
1127 | msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
1128 | msg->size = htons (size); | ||
1129 | tun->flags = htons (0); | ||
1130 | tun->proto = htons (ETH_P_IPV4); | ||
1131 | GNUNET_TUN_initialize_ipv4_header (ipv4, | ||
1132 | IPPROTO_UDP, | ||
1133 | sizeof (struct GNUNET_TUN_UdpHeader) + mlen, | ||
1134 | &ts->destination_ip.v4, | ||
1135 | &ts->source_ip.v4); | ||
1136 | if (0 == ntohs (reply->source_port)) | ||
1137 | udp->source_port = htons (ts->destination_port); | ||
1138 | else | ||
1139 | udp->source_port = reply->source_port; | ||
1140 | if (0 == ntohs (reply->destination_port)) | ||
1141 | udp->destination_port = htons (ts->source_port); | ||
1142 | else | ||
1143 | udp->destination_port = reply->destination_port; | ||
1144 | udp->len = htons (mlen + sizeof (struct GNUNET_TUN_UdpHeader)); | ||
1145 | GNUNET_TUN_calculate_udp4_checksum (ipv4, | ||
1146 | udp, | ||
1147 | &reply[1], | ||
1148 | mlen); | ||
1149 | GNUNET_memcpy (&udp[1], | ||
1150 | &reply[1], | ||
1151 | mlen); | ||
1152 | (void) GNUNET_HELPER_send (helper_handle, | ||
1153 | msg, | ||
1154 | GNUNET_YES, | ||
1155 | NULL, NULL); | ||
1156 | } | ||
1157 | } | ||
1158 | break; | ||
1159 | case AF_INET6: | ||
1160 | { | ||
1161 | size_t size = sizeof (struct GNUNET_TUN_IPv6Header) | ||
1162 | + sizeof (struct GNUNET_TUN_UdpHeader) | ||
1163 | + sizeof (struct GNUNET_MessageHeader) + | ||
1164 | sizeof (struct GNUNET_TUN_Layer2PacketHeader) + | ||
1165 | mlen; | ||
1166 | { | ||
1167 | char buf[size] GNUNET_ALIGN; | ||
1168 | struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; | ||
1169 | struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1]; | ||
1170 | struct GNUNET_TUN_IPv6Header *ipv6 = (struct GNUNET_TUN_IPv6Header *) &tun[1]; | ||
1171 | struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipv6[1]; | ||
1172 | msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
1173 | msg->size = htons (size); | ||
1174 | tun->flags = htons (0); | ||
1175 | tun->proto = htons (ETH_P_IPV6); | ||
1176 | GNUNET_TUN_initialize_ipv6_header (ipv6, | ||
1177 | IPPROTO_UDP, | ||
1178 | sizeof (struct GNUNET_TUN_UdpHeader) + mlen, | ||
1179 | &ts->destination_ip.v6, | ||
1180 | &ts->source_ip.v6); | ||
1181 | if (0 == ntohs (reply->source_port)) | ||
1182 | udp->source_port = htons (ts->destination_port); | ||
1183 | else | ||
1184 | udp->source_port = reply->source_port; | ||
1185 | if (0 == ntohs (reply->destination_port)) | ||
1186 | udp->destination_port = htons (ts->source_port); | ||
1187 | else | ||
1188 | udp->destination_port = reply->destination_port; | ||
1189 | udp->len = htons (mlen + sizeof (struct GNUNET_TUN_UdpHeader)); | ||
1190 | GNUNET_TUN_calculate_udp6_checksum (ipv6, | ||
1191 | udp, | ||
1192 | &reply[1], mlen); | ||
1193 | GNUNET_memcpy (&udp[1], | ||
1194 | &reply[1], | ||
1195 | mlen); | ||
1196 | (void) GNUNET_HELPER_send (helper_handle, | ||
1197 | msg, | ||
1198 | GNUNET_YES, | ||
1199 | NULL, NULL); | ||
1200 | } | ||
1201 | } | ||
1202 | break; | ||
1203 | default: | ||
1204 | GNUNET_assert (0); | ||
1205 | } | ||
1206 | GNUNET_CONTAINER_heap_update_cost (ts->heap_node, | ||
1207 | GNUNET_TIME_absolute_get ().abs_value_us); | ||
1208 | GNUNET_CADET_receive_done (ts->channel); | ||
1209 | } | ||
1210 | |||
1211 | |||
1212 | /** | ||
1213 | * We got a TCP packet back from the CADET channel. Check it is OK. | ||
1214 | * | ||
1215 | * @param cls our `struct ChannelState *` | ||
1216 | * @param data the actual message | ||
1217 | * @return #GNUNET_OK to keep the connection open, | ||
1218 | * #GNUNET_SYSERR to close it (signal serious error) | ||
1219 | */ | ||
1220 | static int | ||
1221 | check_tcp_back (void *cls, | ||
1222 | const struct GNUNET_EXIT_TcpDataMessage *data) | ||
1223 | { | ||
1224 | struct ChannelState *ts = cls; | ||
1225 | |||
1226 | if (NULL == ts->heap_node) | ||
1227 | { | ||
1228 | GNUNET_break_op (0); | ||
1229 | return GNUNET_SYSERR; | ||
1230 | } | ||
1231 | if (data->tcp_header.off * 4 < sizeof (struct GNUNET_TUN_TcpHeader)) | ||
1232 | { | ||
1233 | GNUNET_break_op (0); | ||
1234 | return GNUNET_SYSERR; | ||
1235 | } | ||
1236 | return GNUNET_OK; | ||
1237 | } | ||
1238 | |||
1239 | |||
1240 | /** | ||
1241 | * We got a TCP packet back from the CADET channel. Pass it on to the | ||
1242 | * local virtual interface via the helper. | ||
1243 | * | ||
1244 | * @param cls our `struct ChannelState *` | ||
1245 | * @param data the actual message | ||
1246 | */ | ||
1247 | static void | ||
1248 | handle_tcp_back (void *cls, | ||
1249 | const struct GNUNET_EXIT_TcpDataMessage *data) | ||
1250 | { | ||
1251 | struct ChannelState *ts = cls; | ||
1252 | size_t mlen; | ||
1253 | |||
1254 | GNUNET_STATISTICS_update (stats, | ||
1255 | gettext_noop ("# TCP packets received from cadet"), | ||
1256 | 1, | ||
1257 | GNUNET_NO); | ||
1258 | mlen = ntohs (data->header.size) - sizeof (struct GNUNET_EXIT_TcpDataMessage); | ||
1259 | { | ||
1260 | char sbuf[INET6_ADDRSTRLEN]; | ||
1261 | char dbuf[INET6_ADDRSTRLEN]; | ||
1262 | |||
1263 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1264 | "Received TCP reply from cadet, sending %u bytes from [%s]:%u -> [%s]:%u via TUN\n", | ||
1265 | (unsigned int) mlen, | ||
1266 | inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof (sbuf)), | ||
1267 | ts->destination_port, | ||
1268 | inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof (dbuf)), | ||
1269 | ts->source_port); | ||
1270 | } | ||
1271 | switch (ts->af) | ||
1272 | { | ||
1273 | case AF_INET: | ||
1274 | { | ||
1275 | size_t size = sizeof (struct GNUNET_TUN_IPv4Header) | ||
1276 | + sizeof (struct GNUNET_TUN_TcpHeader) | ||
1277 | + sizeof (struct GNUNET_MessageHeader) + | ||
1278 | sizeof (struct GNUNET_TUN_Layer2PacketHeader) + | ||
1279 | mlen; | ||
1280 | { | ||
1281 | char buf[size] GNUNET_ALIGN; | ||
1282 | struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; | ||
1283 | struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1]; | ||
1284 | struct GNUNET_TUN_IPv4Header *ipv4 = (struct GNUNET_TUN_IPv4Header *) &tun[1]; | ||
1285 | struct GNUNET_TUN_TcpHeader *tcp = (struct GNUNET_TUN_TcpHeader *) &ipv4[1]; | ||
1286 | msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
1287 | msg->size = htons (size); | ||
1288 | tun->flags = htons (0); | ||
1289 | tun->proto = htons (ETH_P_IPV4); | ||
1290 | GNUNET_TUN_initialize_ipv4_header (ipv4, | ||
1291 | IPPROTO_TCP, | ||
1292 | sizeof (struct GNUNET_TUN_TcpHeader) + mlen, | ||
1293 | &ts->destination_ip.v4, | ||
1294 | &ts->source_ip.v4); | ||
1295 | *tcp = data->tcp_header; | ||
1296 | tcp->source_port = htons (ts->destination_port); | ||
1297 | tcp->destination_port = htons (ts->source_port); | ||
1298 | GNUNET_TUN_calculate_tcp4_checksum (ipv4, | ||
1299 | tcp, | ||
1300 | &data[1], | ||
1301 | mlen); | ||
1302 | GNUNET_memcpy (&tcp[1], | ||
1303 | &data[1], | ||
1304 | mlen); | ||
1305 | (void) GNUNET_HELPER_send (helper_handle, | ||
1306 | msg, | ||
1307 | GNUNET_YES, | ||
1308 | NULL, NULL); | ||
1309 | } | ||
1310 | } | ||
1311 | break; | ||
1312 | case AF_INET6: | ||
1313 | { | ||
1314 | size_t size = sizeof (struct GNUNET_TUN_IPv6Header) | ||
1315 | + sizeof (struct GNUNET_TUN_TcpHeader) | ||
1316 | + sizeof (struct GNUNET_MessageHeader) + | ||
1317 | sizeof (struct GNUNET_TUN_Layer2PacketHeader) + | ||
1318 | mlen; | ||
1319 | { | ||
1320 | char buf[size] GNUNET_ALIGN; | ||
1321 | struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; | ||
1322 | struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1]; | ||
1323 | struct GNUNET_TUN_IPv6Header *ipv6 = (struct GNUNET_TUN_IPv6Header *) &tun[1]; | ||
1324 | struct GNUNET_TUN_TcpHeader *tcp = (struct GNUNET_TUN_TcpHeader *) &ipv6[1]; | ||
1325 | msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
1326 | msg->size = htons (size); | ||
1327 | tun->flags = htons (0); | ||
1328 | tun->proto = htons (ETH_P_IPV6); | ||
1329 | GNUNET_TUN_initialize_ipv6_header (ipv6, | ||
1330 | IPPROTO_TCP, | ||
1331 | sizeof (struct GNUNET_TUN_TcpHeader) + mlen, | ||
1332 | &ts->destination_ip.v6, | ||
1333 | &ts->source_ip.v6); | ||
1334 | *tcp = data->tcp_header; | ||
1335 | tcp->source_port = htons (ts->destination_port); | ||
1336 | tcp->destination_port = htons (ts->source_port); | ||
1337 | GNUNET_TUN_calculate_tcp6_checksum (ipv6, | ||
1338 | tcp, | ||
1339 | &data[1], | ||
1340 | mlen); | ||
1341 | GNUNET_memcpy (&tcp[1], | ||
1342 | &data[1], | ||
1343 | mlen); | ||
1344 | (void) GNUNET_HELPER_send (helper_handle, | ||
1345 | msg, | ||
1346 | GNUNET_YES, | ||
1347 | NULL, NULL); | ||
1348 | } | ||
1349 | } | ||
1350 | break; | ||
1351 | } | ||
1352 | GNUNET_CONTAINER_heap_update_cost (ts->heap_node, | ||
1353 | GNUNET_TIME_absolute_get ().abs_value_us); | ||
1354 | GNUNET_CADET_receive_done (ts->channel); | ||
1355 | } | ||
1356 | |||
1357 | |||
1358 | /** | ||
1359 | * Create a channel for @a ts to @a target at @a port | ||
1360 | * | ||
1361 | * @param ts channel state to create the channel for | ||
1362 | * @param target peer to connect to | ||
1363 | * @param port destination port | ||
1364 | * @return the channel handle | ||
1365 | */ | ||
1366 | static struct GNUNET_CADET_Channel * | ||
1367 | create_channel (struct ChannelState *ts, | ||
1368 | const struct GNUNET_PeerIdentity *target, | ||
1369 | const struct GNUNET_HashCode *port) | ||
1370 | { | ||
1371 | struct GNUNET_MQ_MessageHandler cadet_handlers[] = { | ||
1372 | GNUNET_MQ_hd_var_size (udp_back, | ||
1373 | GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY, | ||
1374 | struct GNUNET_EXIT_UdpReplyMessage, | ||
1375 | ts), | ||
1376 | GNUNET_MQ_hd_var_size (tcp_back, | ||
1377 | GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_VPN, | ||
1378 | struct GNUNET_EXIT_TcpDataMessage, | ||
1379 | ts), | ||
1380 | GNUNET_MQ_hd_var_size (icmp_back, | ||
1381 | GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_VPN, | ||
1382 | struct GNUNET_EXIT_IcmpToVPNMessage, | ||
1383 | ts), | ||
1384 | GNUNET_MQ_handler_end() | ||
1385 | }; | ||
1386 | |||
1387 | return GNUNET_CADET_channel_creatE (cadet_handle, | ||
1388 | ts, | ||
1389 | target, | ||
1390 | port, | ||
1391 | GNUNET_CADET_OPTION_DEFAULT, | ||
1392 | NULL, | ||
1393 | &channel_cleaner, | ||
1394 | cadet_handlers); | ||
1395 | } | ||
1396 | |||
1397 | |||
1398 | /** | ||
713 | * Regex has found a potential exit peer for us; consider using it. | 1399 | * Regex has found a potential exit peer for us; consider using it. |
714 | * | 1400 | * |
715 | * @param cls the `struct ChannelState` | 1401 | * @param cls the `struct ChannelState` |
@@ -758,11 +1444,9 @@ handle_regex_result (void *cls, | |||
758 | "Creating tunnel to %s for destination %s!\n", | 1444 | "Creating tunnel to %s for destination %s!\n", |
759 | GNUNET_i2s (id), | 1445 | GNUNET_i2s (id), |
760 | print_channel_destination (&ts->destination)); | 1446 | print_channel_destination (&ts->destination)); |
761 | ts->channel = GNUNET_CADET_channel_create (cadet_handle, | 1447 | ts->channel = create_channel (ts, |
762 | ts, | 1448 | id, |
763 | id, | 1449 | &port); |
764 | &port, | ||
765 | GNUNET_CADET_OPTION_DEFAULT); | ||
766 | } | 1450 | } |
767 | 1451 | ||
768 | 1452 | ||
@@ -795,12 +1479,10 @@ create_channel_to_destination (struct DestinationChannel *dt, | |||
795 | GNUNET_TUN_compute_service_cadet_port (&ts->destination.details.service_destination.service_descriptor, | 1479 | GNUNET_TUN_compute_service_cadet_port (&ts->destination.details.service_destination.service_descriptor, |
796 | ts->destination_port, | 1480 | ts->destination_port, |
797 | &cadet_port); | 1481 | &cadet_port); |
798 | ts->channel | 1482 | ts->channel = create_channel (ts, |
799 | = GNUNET_CADET_channel_create (cadet_handle, | 1483 | &dt->destination->details.service_destination.target, |
800 | ts, | 1484 | &cadet_port); |
801 | &dt->destination->details.service_destination.target, | 1485 | |
802 | &cadet_port, | ||
803 | GNUNET_CADET_OPTION_DEFAULT); | ||
804 | if (NULL == ts->channel) | 1486 | if (NULL == ts->channel) |
805 | { | 1487 | { |
806 | GNUNET_break (0); | 1488 | GNUNET_break (0); |
@@ -906,9 +1588,9 @@ route_packet (struct DestinationEntry *destination, | |||
906 | { | 1588 | { |
907 | struct GNUNET_HashCode key; | 1589 | struct GNUNET_HashCode key; |
908 | struct ChannelState *ts; | 1590 | struct ChannelState *ts; |
909 | struct ChannelMessageQueueEntry *tnq; | ||
910 | size_t alen; | 1591 | size_t alen; |
911 | size_t mlen; | 1592 | size_t mlen; |
1593 | struct GNUNET_MQ_Envelope *env; | ||
912 | const struct GNUNET_TUN_UdpHeader *udp; | 1594 | const struct GNUNET_TUN_UdpHeader *udp; |
913 | const struct GNUNET_TUN_TcpHeader *tcp; | 1595 | const struct GNUNET_TUN_TcpHeader *tcp; |
914 | const struct GNUNET_TUN_IcmpHeader *icmp; | 1596 | const struct GNUNET_TUN_IcmpHeader *icmp; |
@@ -1162,12 +1844,9 @@ route_packet (struct DestinationEntry *destination, | |||
1162 | GNUNET_break (0); | 1844 | GNUNET_break (0); |
1163 | return; | 1845 | return; |
1164 | } | 1846 | } |
1165 | tnq = GNUNET_malloc (sizeof (struct ChannelMessageQueueEntry) + mlen); | 1847 | env = GNUNET_MQ_msg_extra (usm, |
1166 | tnq->len = mlen; | 1848 | payload_length - sizeof (struct GNUNET_TUN_UdpHeader), |
1167 | tnq->msg = &tnq[1]; | 1849 | GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE); |
1168 | usm = (struct GNUNET_EXIT_UdpServiceMessage *) &tnq[1]; | ||
1169 | usm->header.size = htons ((uint16_t) mlen); | ||
1170 | usm->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE); | ||
1171 | /* if the source port is below 32000, we assume it has a special | 1850 | /* if the source port is below 32000, we assume it has a special |
1172 | meaning; if not, we pick a random port (this is a heuristic) */ | 1851 | meaning; if not, we pick a random port (this is a heuristic) */ |
1173 | usm->source_port = (ntohs (udp->source_port) < 32000) ? udp->source_port : 0; | 1852 | usm->source_port = (ntohs (udp->source_port) < 32000) ? udp->source_port : 0; |
@@ -1190,12 +1869,9 @@ route_packet (struct DestinationEntry *destination, | |||
1190 | GNUNET_break (0); | 1869 | GNUNET_break (0); |
1191 | return; | 1870 | return; |
1192 | } | 1871 | } |
1193 | tnq = GNUNET_malloc (sizeof (struct ChannelMessageQueueEntry) + mlen); | 1872 | env = GNUNET_MQ_msg_extra (uim, |
1194 | tnq->len = mlen; | 1873 | payload_length + alen - sizeof (struct GNUNET_TUN_UdpHeader), |
1195 | tnq->msg = &tnq[1]; | 1874 | GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET); |
1196 | uim = (struct GNUNET_EXIT_UdpInternetMessage *) &tnq[1]; | ||
1197 | uim->header.size = htons ((uint16_t) mlen); | ||
1198 | uim->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET); | ||
1199 | uim->af = htonl (destination->details.exit_destination.af); | 1875 | uim->af = htonl (destination->details.exit_destination.af); |
1200 | uim->source_port = (ntohs (udp->source_port) < 32000) ? udp->source_port : 0; | 1876 | uim->source_port = (ntohs (udp->source_port) < 32000) ? udp->source_port : 0; |
1201 | uim->destination_port = udp->destination_port; | 1877 | uim->destination_port = udp->destination_port; |
@@ -1215,8 +1891,8 @@ route_packet (struct DestinationEntry *destination, | |||
1215 | GNUNET_assert (0); | 1891 | GNUNET_assert (0); |
1216 | } | 1892 | } |
1217 | GNUNET_memcpy (payload, | 1893 | GNUNET_memcpy (payload, |
1218 | &udp[1], | 1894 | &udp[1], |
1219 | payload_length - sizeof (struct GNUNET_TUN_UdpHeader)); | 1895 | payload_length - sizeof (struct GNUNET_TUN_UdpHeader)); |
1220 | } | 1896 | } |
1221 | break; | 1897 | break; |
1222 | case IPPROTO_TCP: | 1898 | case IPPROTO_TCP: |
@@ -1233,12 +1909,9 @@ route_packet (struct DestinationEntry *destination, | |||
1233 | GNUNET_break (0); | 1909 | GNUNET_break (0); |
1234 | return; | 1910 | return; |
1235 | } | 1911 | } |
1236 | tnq = GNUNET_malloc (sizeof (struct ChannelMessageQueueEntry) + mlen); | 1912 | env = GNUNET_MQ_msg_extra (tsm, |
1237 | tnq->len = mlen; | 1913 | payload_length - sizeof (struct GNUNET_TUN_TcpHeader), |
1238 | tnq->msg = &tnq[1]; | 1914 | GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START); |
1239 | tsm = (struct GNUNET_EXIT_TcpServiceStartMessage *) &tnq[1]; | ||
1240 | tsm->header.size = htons ((uint16_t) mlen); | ||
1241 | tsm->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START); | ||
1242 | tsm->reserved = htonl (0); | 1915 | tsm->reserved = htonl (0); |
1243 | tsm->tcp_header = *tcp; | 1916 | tsm->tcp_header = *tcp; |
1244 | GNUNET_memcpy (&tsm[1], | 1917 | GNUNET_memcpy (&tsm[1], |
@@ -1259,12 +1932,9 @@ route_packet (struct DestinationEntry *destination, | |||
1259 | GNUNET_break (0); | 1932 | GNUNET_break (0); |
1260 | return; | 1933 | return; |
1261 | } | 1934 | } |
1262 | tnq = GNUNET_malloc (sizeof (struct ChannelMessageQueueEntry) + mlen); | 1935 | env = GNUNET_MQ_msg_extra (tim, |
1263 | tnq->len = mlen; | 1936 | payload_length + alen - sizeof (struct GNUNET_TUN_TcpHeader), |
1264 | tnq->msg = &tnq[1]; | 1937 | GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START); |
1265 | tim = (struct GNUNET_EXIT_TcpInternetStartMessage *) &tnq[1]; | ||
1266 | tim->header.size = htons ((uint16_t) mlen); | ||
1267 | tim->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START); | ||
1268 | tim->af = htonl (destination->details.exit_destination.af); | 1938 | tim->af = htonl (destination->details.exit_destination.af); |
1269 | tim->tcp_header = *tcp; | 1939 | tim->tcp_header = *tcp; |
1270 | switch (destination->details.exit_destination.af) | 1940 | switch (destination->details.exit_destination.af) |
@@ -1283,8 +1953,8 @@ route_packet (struct DestinationEntry *destination, | |||
1283 | GNUNET_assert (0); | 1953 | GNUNET_assert (0); |
1284 | } | 1954 | } |
1285 | GNUNET_memcpy (payload, | 1955 | GNUNET_memcpy (payload, |
1286 | &tcp[1], | 1956 | &tcp[1], |
1287 | payload_length - sizeof (struct GNUNET_TUN_TcpHeader)); | 1957 | payload_length - sizeof (struct GNUNET_TUN_TcpHeader)); |
1288 | } | 1958 | } |
1289 | } | 1959 | } |
1290 | else | 1960 | else |
@@ -1298,17 +1968,14 @@ route_packet (struct DestinationEntry *destination, | |||
1298 | GNUNET_break (0); | 1968 | GNUNET_break (0); |
1299 | return; | 1969 | return; |
1300 | } | 1970 | } |
1301 | tnq = GNUNET_malloc (sizeof (struct ChannelMessageQueueEntry) + mlen); | 1971 | env = GNUNET_MQ_msg_extra (tdm, |
1302 | tnq->len = mlen; | 1972 | payload_length - sizeof (struct GNUNET_TUN_TcpHeader), |
1303 | tnq->msg = &tnq[1]; | 1973 | GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT); |
1304 | tdm = (struct GNUNET_EXIT_TcpDataMessage *) &tnq[1]; | ||
1305 | tdm->header.size = htons ((uint16_t) mlen); | ||
1306 | tdm->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT); | ||
1307 | tdm->reserved = htonl (0); | 1974 | tdm->reserved = htonl (0); |
1308 | tdm->tcp_header = *tcp; | 1975 | tdm->tcp_header = *tcp; |
1309 | GNUNET_memcpy (&tdm[1], | 1976 | GNUNET_memcpy (&tdm[1], |
1310 | &tcp[1], | 1977 | &tcp[1], |
1311 | payload_length - sizeof (struct GNUNET_TUN_TcpHeader)); | 1978 | payload_length - sizeof (struct GNUNET_TUN_TcpHeader)); |
1312 | } | 1979 | } |
1313 | break; | 1980 | break; |
1314 | case IPPROTO_ICMP: | 1981 | case IPPROTO_ICMP: |
@@ -1317,19 +1984,6 @@ route_packet (struct DestinationEntry *destination, | |||
1317 | { | 1984 | { |
1318 | struct GNUNET_EXIT_IcmpServiceMessage *ism; | 1985 | struct GNUNET_EXIT_IcmpServiceMessage *ism; |
1319 | 1986 | ||
1320 | mlen = sizeof (struct GNUNET_EXIT_IcmpServiceMessage) + | ||
1321 | payload_length - sizeof (struct GNUNET_TUN_IcmpHeader); | ||
1322 | if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
1323 | { | ||
1324 | GNUNET_break (0); | ||
1325 | return; | ||
1326 | } | ||
1327 | tnq = GNUNET_malloc (sizeof (struct ChannelMessageQueueEntry) + mlen); | ||
1328 | tnq->msg = &tnq[1]; | ||
1329 | ism = (struct GNUNET_EXIT_IcmpServiceMessage *) &tnq[1]; | ||
1330 | ism->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_SERVICE); | ||
1331 | ism->af = htonl (af); /* need to tell destination ICMP protocol family! */ | ||
1332 | ism->icmp_header = *icmp; | ||
1333 | /* ICMP protocol translation will be done by the receiver (as we don't know | 1987 | /* ICMP protocol translation will be done by the receiver (as we don't know |
1334 | the target AF); however, we still need to possibly discard the payload | 1988 | the target AF); however, we still need to possibly discard the payload |
1335 | depending on the ICMP type */ | 1989 | depending on the ICMP type */ |
@@ -1384,12 +2038,20 @@ route_packet (struct DestinationEntry *destination, | |||
1384 | /* update length calculations, as payload_length may have changed */ | 2038 | /* update length calculations, as payload_length may have changed */ |
1385 | mlen = sizeof (struct GNUNET_EXIT_IcmpServiceMessage) + | 2039 | mlen = sizeof (struct GNUNET_EXIT_IcmpServiceMessage) + |
1386 | alen + payload_length - sizeof (struct GNUNET_TUN_IcmpHeader); | 2040 | alen + payload_length - sizeof (struct GNUNET_TUN_IcmpHeader); |
1387 | tnq->len = mlen; | 2041 | if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) |
1388 | ism->header.size = htons ((uint16_t) mlen); | 2042 | { |
1389 | /* finally, copy payload (if there is any left...) */ | 2043 | GNUNET_break (0); |
2044 | return; | ||
2045 | } | ||
2046 | |||
2047 | env = GNUNET_MQ_msg_extra (ism, | ||
2048 | payload_length - sizeof (struct GNUNET_TUN_IcmpHeader), | ||
2049 | GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_SERVICE); | ||
2050 | ism->af = htonl (af); /* need to tell destination ICMP protocol family! */ | ||
2051 | ism->icmp_header = *icmp; | ||
1390 | GNUNET_memcpy (&ism[1], | 2052 | GNUNET_memcpy (&ism[1], |
1391 | &icmp[1], | 2053 | &icmp[1], |
1392 | payload_length - sizeof (struct GNUNET_TUN_IcmpHeader)); | 2054 | payload_length - sizeof (struct GNUNET_TUN_IcmpHeader)); |
1393 | } | 2055 | } |
1394 | else | 2056 | else |
1395 | { | 2057 | { |
@@ -1397,19 +2059,8 @@ route_packet (struct DestinationEntry *destination, | |||
1397 | struct in_addr *ip4dst; | 2059 | struct in_addr *ip4dst; |
1398 | struct in6_addr *ip6dst; | 2060 | struct in6_addr *ip6dst; |
1399 | void *payload; | 2061 | void *payload; |
2062 | uint8_t new_type; | ||
1400 | 2063 | ||
1401 | mlen = sizeof (struct GNUNET_EXIT_IcmpInternetMessage) + | ||
1402 | alen + payload_length - sizeof (struct GNUNET_TUN_IcmpHeader); | ||
1403 | if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
1404 | { | ||
1405 | GNUNET_break (0); | ||
1406 | return; | ||
1407 | } | ||
1408 | tnq = GNUNET_malloc (sizeof (struct ChannelMessageQueueEntry) + mlen); | ||
1409 | tnq->msg = &tnq[1]; | ||
1410 | iim = (struct GNUNET_EXIT_IcmpInternetMessage *) &tnq[1]; | ||
1411 | iim->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_INTERNET); | ||
1412 | iim->icmp_header = *icmp; | ||
1413 | /* Perform ICMP protocol-translation (depending on destination AF and source AF) | 2064 | /* Perform ICMP protocol-translation (depending on destination AF and source AF) |
1414 | and throw away ICMP payload depending on ICMP message type */ | 2065 | and throw away ICMP payload depending on ICMP message type */ |
1415 | switch (af) | 2066 | switch (af) |
@@ -1419,21 +2070,21 @@ route_packet (struct DestinationEntry *destination, | |||
1419 | { | 2070 | { |
1420 | case GNUNET_TUN_ICMPTYPE_ECHO_REPLY: | 2071 | case GNUNET_TUN_ICMPTYPE_ECHO_REPLY: |
1421 | if (destination->details.exit_destination.af == AF_INET6) | 2072 | if (destination->details.exit_destination.af == AF_INET6) |
1422 | iim->icmp_header.type = GNUNET_TUN_ICMPTYPE6_ECHO_REPLY; | 2073 | new_type = GNUNET_TUN_ICMPTYPE6_ECHO_REPLY; |
1423 | break; | 2074 | break; |
1424 | case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST: | 2075 | case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST: |
1425 | if (destination->details.exit_destination.af == AF_INET6) | 2076 | if (destination->details.exit_destination.af == AF_INET6) |
1426 | iim->icmp_header.type = GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST; | 2077 | new_type = GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST; |
1427 | break; | 2078 | break; |
1428 | case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE: | 2079 | case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE: |
1429 | if (destination->details.exit_destination.af == AF_INET6) | 2080 | if (destination->details.exit_destination.af == AF_INET6) |
1430 | iim->icmp_header.type = GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE; | 2081 | new_type = GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE; |
1431 | /* throw away IP-payload, exit will have to make it up anyway */ | 2082 | /* throw away IP-payload, exit will have to make it up anyway */ |
1432 | payload_length = sizeof (struct GNUNET_TUN_IcmpHeader); | 2083 | payload_length = sizeof (struct GNUNET_TUN_IcmpHeader); |
1433 | break; | 2084 | break; |
1434 | case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED: | 2085 | case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED: |
1435 | if (destination->details.exit_destination.af == AF_INET6) | 2086 | if (destination->details.exit_destination.af == AF_INET6) |
1436 | iim->icmp_header.type = GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED; | 2087 | new_type = GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED; |
1437 | /* throw away IP-payload, exit will have to make it up anyway */ | 2088 | /* throw away IP-payload, exit will have to make it up anyway */ |
1438 | payload_length = sizeof (struct GNUNET_TUN_IcmpHeader); | 2089 | payload_length = sizeof (struct GNUNET_TUN_IcmpHeader); |
1439 | break; | 2090 | break; |
@@ -1443,7 +2094,6 @@ route_packet (struct DestinationEntry *destination, | |||
1443 | GNUNET_STATISTICS_update (stats, | 2094 | GNUNET_STATISTICS_update (stats, |
1444 | gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"), | 2095 | gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"), |
1445 | 1, GNUNET_NO); | 2096 | 1, GNUNET_NO); |
1446 | GNUNET_free (tnq); | ||
1447 | return; | 2097 | return; |
1448 | } | 2098 | } |
1449 | /* throw away IP-payload, exit will have to make it up anyway */ | 2099 | /* throw away IP-payload, exit will have to make it up anyway */ |
@@ -1453,7 +2103,6 @@ route_packet (struct DestinationEntry *destination, | |||
1453 | GNUNET_STATISTICS_update (stats, | 2103 | GNUNET_STATISTICS_update (stats, |
1454 | gettext_noop ("# ICMPv4 packets dropped (type not allowed)"), | 2104 | gettext_noop ("# ICMPv4 packets dropped (type not allowed)"), |
1455 | 1, GNUNET_NO); | 2105 | 1, GNUNET_NO); |
1456 | GNUNET_free (tnq); | ||
1457 | return; | 2106 | return; |
1458 | } | 2107 | } |
1459 | /* end of AF_INET */ | 2108 | /* end of AF_INET */ |
@@ -1463,13 +2112,13 @@ route_packet (struct DestinationEntry *destination, | |||
1463 | { | 2112 | { |
1464 | case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE: | 2113 | case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE: |
1465 | if (destination->details.exit_destination.af == AF_INET6) | 2114 | if (destination->details.exit_destination.af == AF_INET6) |
1466 | iim->icmp_header.type = GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE; | 2115 | new_type = GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE; |
1467 | /* throw away IP-payload, exit will have to make it up anyway */ | 2116 | /* throw away IP-payload, exit will have to make it up anyway */ |
1468 | payload_length = sizeof (struct GNUNET_TUN_IcmpHeader); | 2117 | payload_length = sizeof (struct GNUNET_TUN_IcmpHeader); |
1469 | break; | 2118 | break; |
1470 | case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED: | 2119 | case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED: |
1471 | if (destination->details.exit_destination.af == AF_INET) | 2120 | if (destination->details.exit_destination.af == AF_INET) |
1472 | iim->icmp_header.type = GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED; | 2121 | new_type = GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED; |
1473 | /* throw away IP-payload, exit will have to make it up anyway */ | 2122 | /* throw away IP-payload, exit will have to make it up anyway */ |
1474 | payload_length = sizeof (struct GNUNET_TUN_IcmpHeader); | 2123 | payload_length = sizeof (struct GNUNET_TUN_IcmpHeader); |
1475 | break; | 2124 | break; |
@@ -1479,7 +2128,6 @@ route_packet (struct DestinationEntry *destination, | |||
1479 | GNUNET_STATISTICS_update (stats, | 2128 | GNUNET_STATISTICS_update (stats, |
1480 | gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"), | 2129 | gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"), |
1481 | 1, GNUNET_NO); | 2130 | 1, GNUNET_NO); |
1482 | GNUNET_free (tnq); | ||
1483 | return; | 2131 | return; |
1484 | } | 2132 | } |
1485 | /* throw away IP-payload, exit will have to make it up anyway */ | 2133 | /* throw away IP-payload, exit will have to make it up anyway */ |
@@ -1491,7 +2139,6 @@ route_packet (struct DestinationEntry *destination, | |||
1491 | GNUNET_STATISTICS_update (stats, | 2139 | GNUNET_STATISTICS_update (stats, |
1492 | gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"), | 2140 | gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"), |
1493 | 1, GNUNET_NO); | 2141 | 1, GNUNET_NO); |
1494 | GNUNET_free (tnq); | ||
1495 | return; | 2142 | return; |
1496 | } | 2143 | } |
1497 | /* throw away IP-payload, exit will have to make it up anyway */ | 2144 | /* throw away IP-payload, exit will have to make it up anyway */ |
@@ -1499,17 +2146,16 @@ route_packet (struct DestinationEntry *destination, | |||
1499 | break; | 2146 | break; |
1500 | case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST: | 2147 | case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST: |
1501 | if (destination->details.exit_destination.af == AF_INET) | 2148 | if (destination->details.exit_destination.af == AF_INET) |
1502 | iim->icmp_header.type = GNUNET_TUN_ICMPTYPE_ECHO_REQUEST; | 2149 | new_type = GNUNET_TUN_ICMPTYPE_ECHO_REQUEST; |
1503 | break; | 2150 | break; |
1504 | case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY: | 2151 | case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY: |
1505 | if (destination->details.exit_destination.af == AF_INET) | 2152 | if (destination->details.exit_destination.af == AF_INET) |
1506 | iim->icmp_header.type = GNUNET_TUN_ICMPTYPE_ECHO_REPLY; | 2153 | new_type = GNUNET_TUN_ICMPTYPE_ECHO_REPLY; |
1507 | break; | 2154 | break; |
1508 | default: | 2155 | default: |
1509 | GNUNET_STATISTICS_update (stats, | 2156 | GNUNET_STATISTICS_update (stats, |
1510 | gettext_noop ("# ICMPv6 packets dropped (type not allowed)"), | 2157 | gettext_noop ("# ICMPv6 packets dropped (type not allowed)"), |
1511 | 1, GNUNET_NO); | 2158 | 1, GNUNET_NO); |
1512 | GNUNET_free (tnq); | ||
1513 | return; | 2159 | return; |
1514 | } | 2160 | } |
1515 | /* end of AF_INET6 */ | 2161 | /* end of AF_INET6 */ |
@@ -1517,13 +2163,20 @@ route_packet (struct DestinationEntry *destination, | |||
1517 | default: | 2163 | default: |
1518 | GNUNET_assert (0); | 2164 | GNUNET_assert (0); |
1519 | } | 2165 | } |
2166 | |||
1520 | /* update length calculations, as payload_length may have changed */ | 2167 | /* update length calculations, as payload_length may have changed */ |
1521 | mlen = sizeof (struct GNUNET_EXIT_IcmpInternetMessage) + | 2168 | mlen = sizeof (struct GNUNET_EXIT_IcmpInternetMessage) + |
1522 | alen + payload_length - sizeof (struct GNUNET_TUN_IcmpHeader); | 2169 | alen + payload_length - sizeof (struct GNUNET_TUN_IcmpHeader); |
1523 | tnq->len = mlen; | 2170 | if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) |
1524 | iim->header.size = htons ((uint16_t) mlen); | 2171 | { |
1525 | 2172 | GNUNET_break (0); | |
1526 | /* need to tell destination ICMP protocol family! */ | 2173 | return; |
2174 | } | ||
2175 | env = GNUNET_MQ_msg_extra (iim, | ||
2176 | alen + payload_length - sizeof (struct GNUNET_TUN_IcmpHeader), | ||
2177 | GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_INTERNET); | ||
2178 | iim->icmp_header = *icmp; | ||
2179 | iim->icmp_header.type = new_type; | ||
1527 | iim->af = htonl (destination->details.exit_destination.af); | 2180 | iim->af = htonl (destination->details.exit_destination.af); |
1528 | switch (destination->details.exit_destination.af) | 2181 | switch (destination->details.exit_destination.af) |
1529 | { | 2182 | { |
@@ -1541,8 +2194,8 @@ route_packet (struct DestinationEntry *destination, | |||
1541 | GNUNET_assert (0); | 2194 | GNUNET_assert (0); |
1542 | } | 2195 | } |
1543 | GNUNET_memcpy (payload, | 2196 | GNUNET_memcpy (payload, |
1544 | &icmp[1], | 2197 | &icmp[1], |
1545 | payload_length - sizeof (struct GNUNET_TUN_IcmpHeader)); | 2198 | payload_length - sizeof (struct GNUNET_TUN_IcmpHeader)); |
1546 | } | 2199 | } |
1547 | break; | 2200 | break; |
1548 | default: | 2201 | default: |
@@ -1551,7 +2204,8 @@ route_packet (struct DestinationEntry *destination, | |||
1551 | break; | 2204 | break; |
1552 | } | 2205 | } |
1553 | ts->is_established = GNUNET_YES; | 2206 | ts->is_established = GNUNET_YES; |
1554 | send_to_channel (tnq, ts); | 2207 | send_to_channel (ts, |
2208 | env); | ||
1555 | } | 2209 | } |
1556 | 2210 | ||
1557 | 2211 | ||
@@ -1678,694 +2332,6 @@ message_token (void *cls, | |||
1678 | 2332 | ||
1679 | 2333 | ||
1680 | /** | 2334 | /** |
1681 | * Synthesize a plausible ICMP payload for an ICMP error | ||
1682 | * response on the given channel. | ||
1683 | * | ||
1684 | * @param ts channel information | ||
1685 | * @param ipp IPv4 header to fill in (ICMP payload) | ||
1686 | * @param udp "UDP" header to fill in (ICMP payload); might actually | ||
1687 | * also be the first 8 bytes of the TCP header | ||
1688 | */ | ||
1689 | static void | ||
1690 | make_up_icmpv4_payload (struct ChannelState *ts, | ||
1691 | struct GNUNET_TUN_IPv4Header *ipp, | ||
1692 | struct GNUNET_TUN_UdpHeader *udp) | ||
1693 | { | ||
1694 | GNUNET_TUN_initialize_ipv4_header (ipp, | ||
1695 | ts->protocol, | ||
1696 | sizeof (struct GNUNET_TUN_TcpHeader), | ||
1697 | &ts->source_ip.v4, | ||
1698 | &ts->destination_ip.v4); | ||
1699 | udp->source_port = htons (ts->source_port); | ||
1700 | udp->destination_port = htons (ts->destination_port); | ||
1701 | udp->len = htons (0); | ||
1702 | udp->crc = htons (0); | ||
1703 | } | ||
1704 | |||
1705 | |||
1706 | /** | ||
1707 | * Synthesize a plausible ICMP payload for an ICMP error | ||
1708 | * response on the given channel. | ||
1709 | * | ||
1710 | * @param ts channel information | ||
1711 | * @param ipp IPv6 header to fill in (ICMP payload) | ||
1712 | * @param udp "UDP" header to fill in (ICMP payload); might actually | ||
1713 | * also be the first 8 bytes of the TCP header | ||
1714 | */ | ||
1715 | static void | ||
1716 | make_up_icmpv6_payload (struct ChannelState *ts, | ||
1717 | struct GNUNET_TUN_IPv6Header *ipp, | ||
1718 | struct GNUNET_TUN_UdpHeader *udp) | ||
1719 | { | ||
1720 | GNUNET_TUN_initialize_ipv6_header (ipp, | ||
1721 | ts->protocol, | ||
1722 | sizeof (struct GNUNET_TUN_TcpHeader), | ||
1723 | &ts->source_ip.v6, | ||
1724 | &ts->destination_ip.v6); | ||
1725 | udp->source_port = htons (ts->source_port); | ||
1726 | udp->destination_port = htons (ts->destination_port); | ||
1727 | udp->len = htons (0); | ||
1728 | udp->crc = htons (0); | ||
1729 | } | ||
1730 | |||
1731 | |||
1732 | /** | ||
1733 | * We got an ICMP packet back from the CADET channel. Pass it on to the | ||
1734 | * local virtual interface via the helper. | ||
1735 | * | ||
1736 | * @param cls closure, NULL | ||
1737 | * @param channel connection to the other end | ||
1738 | * @param channel_ctx pointer to our 'struct ChannelState *' | ||
1739 | * @param message the actual message | ||
1740 | * @return #GNUNET_OK to keep the connection open, | ||
1741 | * #GNUNET_SYSERR to close it (signal serious error) | ||
1742 | */ | ||
1743 | static int | ||
1744 | receive_icmp_back (void *cls, | ||
1745 | struct GNUNET_CADET_Channel *channel, | ||
1746 | void **channel_ctx, | ||
1747 | const struct GNUNET_MessageHeader *message) | ||
1748 | { | ||
1749 | struct ChannelState *ts = *channel_ctx; | ||
1750 | const struct GNUNET_EXIT_IcmpToVPNMessage *i2v; | ||
1751 | size_t mlen; | ||
1752 | |||
1753 | GNUNET_STATISTICS_update (stats, | ||
1754 | gettext_noop ("# ICMP packets received from cadet"), | ||
1755 | 1, GNUNET_NO); | ||
1756 | mlen = ntohs (message->size); | ||
1757 | if (mlen < sizeof (struct GNUNET_EXIT_IcmpToVPNMessage)) | ||
1758 | { | ||
1759 | GNUNET_break_op (0); | ||
1760 | return GNUNET_SYSERR; | ||
1761 | } | ||
1762 | if (NULL == ts->heap_node) | ||
1763 | { | ||
1764 | GNUNET_break_op (0); | ||
1765 | return GNUNET_SYSERR; | ||
1766 | } | ||
1767 | if (AF_UNSPEC == ts->af) | ||
1768 | { | ||
1769 | GNUNET_break_op (0); | ||
1770 | return GNUNET_SYSERR; | ||
1771 | } | ||
1772 | i2v = (const struct GNUNET_EXIT_IcmpToVPNMessage *) message; | ||
1773 | mlen -= sizeof (struct GNUNET_EXIT_IcmpToVPNMessage); | ||
1774 | { | ||
1775 | char sbuf[INET6_ADDRSTRLEN]; | ||
1776 | char dbuf[INET6_ADDRSTRLEN]; | ||
1777 | |||
1778 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1779 | "Received ICMP packet from cadet, sending %u bytes from %s -> %s via TUN\n", | ||
1780 | (unsigned int) mlen, | ||
1781 | inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof (sbuf)), | ||
1782 | inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof (dbuf))); | ||
1783 | } | ||
1784 | switch (ts->af) | ||
1785 | { | ||
1786 | case AF_INET: | ||
1787 | { | ||
1788 | size_t size = sizeof (struct GNUNET_TUN_IPv4Header) | ||
1789 | + sizeof (struct GNUNET_TUN_IcmpHeader) | ||
1790 | + sizeof (struct GNUNET_MessageHeader) + | ||
1791 | sizeof (struct GNUNET_TUN_Layer2PacketHeader) + | ||
1792 | mlen; | ||
1793 | { | ||
1794 | /* reserve some extra space in case we have an ICMP type here where | ||
1795 | we will need to make up the payload ourselves */ | ||
1796 | char buf[size + sizeof (struct GNUNET_TUN_IPv4Header) + 8] GNUNET_ALIGN; | ||
1797 | struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; | ||
1798 | struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1]; | ||
1799 | struct GNUNET_TUN_IPv4Header *ipv4 = (struct GNUNET_TUN_IPv4Header *) &tun[1]; | ||
1800 | struct GNUNET_TUN_IcmpHeader *icmp = (struct GNUNET_TUN_IcmpHeader *) &ipv4[1]; | ||
1801 | msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
1802 | tun->flags = htons (0); | ||
1803 | tun->proto = htons (ETH_P_IPV4); | ||
1804 | GNUNET_TUN_initialize_ipv4_header (ipv4, | ||
1805 | IPPROTO_ICMP, | ||
1806 | sizeof (struct GNUNET_TUN_IcmpHeader) + mlen, | ||
1807 | &ts->destination_ip.v4, | ||
1808 | &ts->source_ip.v4); | ||
1809 | *icmp = i2v->icmp_header; | ||
1810 | GNUNET_memcpy (&icmp[1], | ||
1811 | &i2v[1], | ||
1812 | mlen); | ||
1813 | /* For some ICMP types, we need to adjust (make up) the payload here. | ||
1814 | Also, depending on the AF used on the other side, we have to | ||
1815 | do ICMP PT (translate ICMP types) */ | ||
1816 | switch (ntohl (i2v->af)) | ||
1817 | { | ||
1818 | case AF_INET: | ||
1819 | switch (icmp->type) | ||
1820 | { | ||
1821 | case GNUNET_TUN_ICMPTYPE_ECHO_REPLY: | ||
1822 | case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST: | ||
1823 | break; | ||
1824 | case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE: | ||
1825 | case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH: | ||
1826 | case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED: | ||
1827 | { | ||
1828 | struct GNUNET_TUN_IPv4Header *ipp = (struct GNUNET_TUN_IPv4Header *) &icmp[1]; | ||
1829 | struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1]; | ||
1830 | |||
1831 | if (mlen != 0) | ||
1832 | { | ||
1833 | /* sender did not strip ICMP payload? */ | ||
1834 | GNUNET_break_op (0); | ||
1835 | return GNUNET_SYSERR; | ||
1836 | } | ||
1837 | size += sizeof (struct GNUNET_TUN_IPv4Header) + 8; | ||
1838 | GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); | ||
1839 | make_up_icmpv4_payload (ts, ipp, udp); | ||
1840 | } | ||
1841 | break; | ||
1842 | default: | ||
1843 | GNUNET_break_op (0); | ||
1844 | GNUNET_STATISTICS_update (stats, | ||
1845 | gettext_noop ("# ICMPv4 packets dropped (type not allowed)"), | ||
1846 | 1, GNUNET_NO); | ||
1847 | return GNUNET_SYSERR; | ||
1848 | } | ||
1849 | /* end AF_INET */ | ||
1850 | break; | ||
1851 | case AF_INET6: | ||
1852 | /* ICMP PT 6-to-4 and possibly making up payloads */ | ||
1853 | switch (icmp->type) | ||
1854 | { | ||
1855 | case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE: | ||
1856 | icmp->type = GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE; | ||
1857 | { | ||
1858 | struct GNUNET_TUN_IPv4Header *ipp = (struct GNUNET_TUN_IPv4Header *) &icmp[1]; | ||
1859 | struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1]; | ||
1860 | |||
1861 | if (mlen != 0) | ||
1862 | { | ||
1863 | /* sender did not strip ICMP payload? */ | ||
1864 | GNUNET_break_op (0); | ||
1865 | return GNUNET_SYSERR; | ||
1866 | } | ||
1867 | size += sizeof (struct GNUNET_TUN_IPv4Header) + 8; | ||
1868 | GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); | ||
1869 | make_up_icmpv4_payload (ts, ipp, udp); | ||
1870 | } | ||
1871 | break; | ||
1872 | case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED: | ||
1873 | icmp->type = GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED; | ||
1874 | { | ||
1875 | struct GNUNET_TUN_IPv4Header *ipp = (struct GNUNET_TUN_IPv4Header *) &icmp[1]; | ||
1876 | struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1]; | ||
1877 | |||
1878 | if (mlen != 0) | ||
1879 | { | ||
1880 | /* sender did not strip ICMP payload? */ | ||
1881 | GNUNET_break_op (0); | ||
1882 | return GNUNET_SYSERR; | ||
1883 | } | ||
1884 | size += sizeof (struct GNUNET_TUN_IPv4Header) + 8; | ||
1885 | GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); | ||
1886 | make_up_icmpv4_payload (ts, ipp, udp); | ||
1887 | } | ||
1888 | break; | ||
1889 | case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG: | ||
1890 | case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM: | ||
1891 | GNUNET_STATISTICS_update (stats, | ||
1892 | gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"), | ||
1893 | 1, GNUNET_NO); | ||
1894 | return GNUNET_OK; | ||
1895 | case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST: | ||
1896 | icmp->type = GNUNET_TUN_ICMPTYPE_ECHO_REQUEST; | ||
1897 | break; | ||
1898 | case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY: | ||
1899 | icmp->type = GNUNET_TUN_ICMPTYPE_ECHO_REPLY; | ||
1900 | break; | ||
1901 | default: | ||
1902 | GNUNET_break_op (0); | ||
1903 | GNUNET_STATISTICS_update (stats, | ||
1904 | gettext_noop ("# ICMPv6 packets dropped (type not allowed)"), | ||
1905 | 1, GNUNET_NO); | ||
1906 | return GNUNET_SYSERR; | ||
1907 | } | ||
1908 | /* end AF_INET6 */ | ||
1909 | break; | ||
1910 | default: | ||
1911 | GNUNET_break_op (0); | ||
1912 | return GNUNET_SYSERR; | ||
1913 | } | ||
1914 | msg->size = htons (size); | ||
1915 | GNUNET_TUN_calculate_icmp_checksum (icmp, | ||
1916 | &i2v[1], | ||
1917 | mlen); | ||
1918 | (void) GNUNET_HELPER_send (helper_handle, | ||
1919 | msg, | ||
1920 | GNUNET_YES, | ||
1921 | NULL, NULL); | ||
1922 | } | ||
1923 | } | ||
1924 | break; | ||
1925 | case AF_INET6: | ||
1926 | { | ||
1927 | size_t size = sizeof (struct GNUNET_TUN_IPv6Header) | ||
1928 | + sizeof (struct GNUNET_TUN_IcmpHeader) | ||
1929 | + sizeof (struct GNUNET_MessageHeader) + | ||
1930 | sizeof (struct GNUNET_TUN_Layer2PacketHeader) + | ||
1931 | mlen; | ||
1932 | { | ||
1933 | char buf[size + sizeof (struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN; | ||
1934 | struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; | ||
1935 | struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1]; | ||
1936 | struct GNUNET_TUN_IPv6Header *ipv6 = (struct GNUNET_TUN_IPv6Header *) &tun[1]; | ||
1937 | struct GNUNET_TUN_IcmpHeader *icmp = (struct GNUNET_TUN_IcmpHeader *) &ipv6[1]; | ||
1938 | msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
1939 | tun->flags = htons (0); | ||
1940 | tun->proto = htons (ETH_P_IPV6); | ||
1941 | GNUNET_TUN_initialize_ipv6_header (ipv6, | ||
1942 | IPPROTO_ICMPV6, | ||
1943 | sizeof (struct GNUNET_TUN_IcmpHeader) + mlen, | ||
1944 | &ts->destination_ip.v6, | ||
1945 | &ts->source_ip.v6); | ||
1946 | *icmp = i2v->icmp_header; | ||
1947 | GNUNET_memcpy (&icmp[1], | ||
1948 | &i2v[1], | ||
1949 | mlen); | ||
1950 | |||
1951 | /* For some ICMP types, we need to adjust (make up) the payload here. | ||
1952 | Also, depending on the AF used on the other side, we have to | ||
1953 | do ICMP PT (translate ICMP types) */ | ||
1954 | switch (ntohl (i2v->af)) | ||
1955 | { | ||
1956 | case AF_INET: | ||
1957 | /* ICMP PT 4-to-6 and possibly making up payloads */ | ||
1958 | switch (icmp->type) | ||
1959 | { | ||
1960 | case GNUNET_TUN_ICMPTYPE_ECHO_REPLY: | ||
1961 | icmp->type = GNUNET_TUN_ICMPTYPE6_ECHO_REPLY; | ||
1962 | break; | ||
1963 | case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST: | ||
1964 | icmp->type = GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST; | ||
1965 | break; | ||
1966 | case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE: | ||
1967 | icmp->type = GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE; | ||
1968 | { | ||
1969 | struct GNUNET_TUN_IPv6Header *ipp = (struct GNUNET_TUN_IPv6Header *) &icmp[1]; | ||
1970 | struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1]; | ||
1971 | |||
1972 | if (mlen != 0) | ||
1973 | { | ||
1974 | /* sender did not strip ICMP payload? */ | ||
1975 | GNUNET_break_op (0); | ||
1976 | return GNUNET_SYSERR; | ||
1977 | } | ||
1978 | size += sizeof (struct GNUNET_TUN_IPv6Header) + 8; | ||
1979 | GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); | ||
1980 | make_up_icmpv6_payload (ts, ipp, udp); | ||
1981 | } | ||
1982 | break; | ||
1983 | case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED: | ||
1984 | icmp->type = GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED; | ||
1985 | { | ||
1986 | struct GNUNET_TUN_IPv6Header *ipp = (struct GNUNET_TUN_IPv6Header *) &icmp[1]; | ||
1987 | struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1]; | ||
1988 | |||
1989 | if (mlen != 0) | ||
1990 | { | ||
1991 | /* sender did not strip ICMP payload? */ | ||
1992 | GNUNET_break_op (0); | ||
1993 | return GNUNET_SYSERR; | ||
1994 | } | ||
1995 | size += sizeof (struct GNUNET_TUN_IPv6Header) + 8; | ||
1996 | GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); | ||
1997 | make_up_icmpv6_payload (ts, ipp, udp); | ||
1998 | } | ||
1999 | break; | ||
2000 | case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH: | ||
2001 | GNUNET_STATISTICS_update (stats, | ||
2002 | gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"), | ||
2003 | 1, GNUNET_NO); | ||
2004 | return GNUNET_OK; | ||
2005 | default: | ||
2006 | GNUNET_break_op (0); | ||
2007 | GNUNET_STATISTICS_update (stats, | ||
2008 | gettext_noop ("# ICMPv4 packets dropped (type not allowed)"), | ||
2009 | 1, GNUNET_NO); | ||
2010 | return GNUNET_SYSERR; | ||
2011 | } | ||
2012 | /* end AF_INET */ | ||
2013 | break; | ||
2014 | case AF_INET6: | ||
2015 | switch (icmp->type) | ||
2016 | { | ||
2017 | case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE: | ||
2018 | case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED: | ||
2019 | case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG: | ||
2020 | case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM: | ||
2021 | { | ||
2022 | struct GNUNET_TUN_IPv6Header *ipp = (struct GNUNET_TUN_IPv6Header *) &icmp[1]; | ||
2023 | struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1]; | ||
2024 | |||
2025 | if (mlen != 0) | ||
2026 | { | ||
2027 | /* sender did not strip ICMP payload? */ | ||
2028 | GNUNET_break_op (0); | ||
2029 | return GNUNET_SYSERR; | ||
2030 | } | ||
2031 | size += sizeof (struct GNUNET_TUN_IPv6Header) + 8; | ||
2032 | GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); | ||
2033 | make_up_icmpv6_payload (ts, ipp, udp); | ||
2034 | } | ||
2035 | break; | ||
2036 | case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST: | ||
2037 | break; | ||
2038 | default: | ||
2039 | GNUNET_break_op (0); | ||
2040 | GNUNET_STATISTICS_update (stats, | ||
2041 | gettext_noop ("# ICMPv6 packets dropped (type not allowed)"), | ||
2042 | 1, GNUNET_NO); | ||
2043 | return GNUNET_SYSERR; | ||
2044 | } | ||
2045 | /* end AF_INET6 */ | ||
2046 | break; | ||
2047 | default: | ||
2048 | GNUNET_break_op (0); | ||
2049 | return GNUNET_SYSERR; | ||
2050 | } | ||
2051 | msg->size = htons (size); | ||
2052 | GNUNET_TUN_calculate_icmp_checksum (icmp, | ||
2053 | &i2v[1], mlen); | ||
2054 | (void) GNUNET_HELPER_send (helper_handle, | ||
2055 | msg, | ||
2056 | GNUNET_YES, | ||
2057 | NULL, NULL); | ||
2058 | } | ||
2059 | } | ||
2060 | break; | ||
2061 | default: | ||
2062 | GNUNET_assert (0); | ||
2063 | } | ||
2064 | GNUNET_CONTAINER_heap_update_cost (ts->heap_node, | ||
2065 | GNUNET_TIME_absolute_get ().abs_value_us); | ||
2066 | GNUNET_CADET_receive_done (channel); | ||
2067 | return GNUNET_OK; | ||
2068 | } | ||
2069 | |||
2070 | |||
2071 | /** | ||
2072 | * We got a UDP packet back from the CADET channel. Pass it on to the | ||
2073 | * local virtual interface via the helper. | ||
2074 | * | ||
2075 | * @param cls closure, NULL | ||
2076 | * @param channel connection to the other end | ||
2077 | * @param channel_ctx pointer to our 'struct ChannelState *' | ||
2078 | * @param message the actual message | ||
2079 | * @return #GNUNET_OK to keep the connection open, | ||
2080 | * #GNUNET_SYSERR to close it (signal serious error) | ||
2081 | */ | ||
2082 | static int | ||
2083 | receive_udp_back (void *cls, | ||
2084 | struct GNUNET_CADET_Channel *channel, | ||
2085 | void **channel_ctx, | ||
2086 | const struct GNUNET_MessageHeader *message) | ||
2087 | { | ||
2088 | struct ChannelState *ts = *channel_ctx; | ||
2089 | const struct GNUNET_EXIT_UdpReplyMessage *reply; | ||
2090 | size_t mlen; | ||
2091 | |||
2092 | GNUNET_STATISTICS_update (stats, | ||
2093 | gettext_noop ("# UDP packets received from cadet"), | ||
2094 | 1, GNUNET_NO); | ||
2095 | mlen = ntohs (message->size); | ||
2096 | if (mlen < sizeof (struct GNUNET_EXIT_UdpReplyMessage)) | ||
2097 | { | ||
2098 | GNUNET_break_op (0); | ||
2099 | return GNUNET_SYSERR; | ||
2100 | } | ||
2101 | if (NULL == ts->heap_node) | ||
2102 | { | ||
2103 | GNUNET_break_op (0); | ||
2104 | return GNUNET_SYSERR; | ||
2105 | } | ||
2106 | if (AF_UNSPEC == ts->af) | ||
2107 | { | ||
2108 | GNUNET_break_op (0); | ||
2109 | return GNUNET_SYSERR; | ||
2110 | } | ||
2111 | reply = (const struct GNUNET_EXIT_UdpReplyMessage *) message; | ||
2112 | mlen -= sizeof (struct GNUNET_EXIT_UdpReplyMessage); | ||
2113 | { | ||
2114 | char sbuf[INET6_ADDRSTRLEN]; | ||
2115 | char dbuf[INET6_ADDRSTRLEN]; | ||
2116 | |||
2117 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2118 | "Received UDP reply from cadet, sending %u bytes from [%s]:%u -> [%s]:%u via TUN\n", | ||
2119 | (unsigned int) mlen, | ||
2120 | inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof (sbuf)), | ||
2121 | ts->destination_port, | ||
2122 | inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof (dbuf)), | ||
2123 | ts->source_port); | ||
2124 | } | ||
2125 | switch (ts->af) | ||
2126 | { | ||
2127 | case AF_INET: | ||
2128 | { | ||
2129 | size_t size = sizeof (struct GNUNET_TUN_IPv4Header) | ||
2130 | + sizeof (struct GNUNET_TUN_UdpHeader) | ||
2131 | + sizeof (struct GNUNET_MessageHeader) + | ||
2132 | sizeof (struct GNUNET_TUN_Layer2PacketHeader) + | ||
2133 | mlen; | ||
2134 | { | ||
2135 | char buf[size] GNUNET_ALIGN; | ||
2136 | struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; | ||
2137 | struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1]; | ||
2138 | struct GNUNET_TUN_IPv4Header *ipv4 = (struct GNUNET_TUN_IPv4Header *) &tun[1]; | ||
2139 | struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipv4[1]; | ||
2140 | msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
2141 | msg->size = htons (size); | ||
2142 | tun->flags = htons (0); | ||
2143 | tun->proto = htons (ETH_P_IPV4); | ||
2144 | GNUNET_TUN_initialize_ipv4_header (ipv4, | ||
2145 | IPPROTO_UDP, | ||
2146 | sizeof (struct GNUNET_TUN_UdpHeader) + mlen, | ||
2147 | &ts->destination_ip.v4, | ||
2148 | &ts->source_ip.v4); | ||
2149 | if (0 == ntohs (reply->source_port)) | ||
2150 | udp->source_port = htons (ts->destination_port); | ||
2151 | else | ||
2152 | udp->source_port = reply->source_port; | ||
2153 | if (0 == ntohs (reply->destination_port)) | ||
2154 | udp->destination_port = htons (ts->source_port); | ||
2155 | else | ||
2156 | udp->destination_port = reply->destination_port; | ||
2157 | udp->len = htons (mlen + sizeof (struct GNUNET_TUN_UdpHeader)); | ||
2158 | GNUNET_TUN_calculate_udp4_checksum (ipv4, | ||
2159 | udp, | ||
2160 | &reply[1], | ||
2161 | mlen); | ||
2162 | GNUNET_memcpy (&udp[1], | ||
2163 | &reply[1], | ||
2164 | mlen); | ||
2165 | (void) GNUNET_HELPER_send (helper_handle, | ||
2166 | msg, | ||
2167 | GNUNET_YES, | ||
2168 | NULL, NULL); | ||
2169 | } | ||
2170 | } | ||
2171 | break; | ||
2172 | case AF_INET6: | ||
2173 | { | ||
2174 | size_t size = sizeof (struct GNUNET_TUN_IPv6Header) | ||
2175 | + sizeof (struct GNUNET_TUN_UdpHeader) | ||
2176 | + sizeof (struct GNUNET_MessageHeader) + | ||
2177 | sizeof (struct GNUNET_TUN_Layer2PacketHeader) + | ||
2178 | mlen; | ||
2179 | { | ||
2180 | char buf[size] GNUNET_ALIGN; | ||
2181 | struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; | ||
2182 | struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1]; | ||
2183 | struct GNUNET_TUN_IPv6Header *ipv6 = (struct GNUNET_TUN_IPv6Header *) &tun[1]; | ||
2184 | struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipv6[1]; | ||
2185 | msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
2186 | msg->size = htons (size); | ||
2187 | tun->flags = htons (0); | ||
2188 | tun->proto = htons (ETH_P_IPV6); | ||
2189 | GNUNET_TUN_initialize_ipv6_header (ipv6, | ||
2190 | IPPROTO_UDP, | ||
2191 | sizeof (struct GNUNET_TUN_UdpHeader) + mlen, | ||
2192 | &ts->destination_ip.v6, | ||
2193 | &ts->source_ip.v6); | ||
2194 | if (0 == ntohs (reply->source_port)) | ||
2195 | udp->source_port = htons (ts->destination_port); | ||
2196 | else | ||
2197 | udp->source_port = reply->source_port; | ||
2198 | if (0 == ntohs (reply->destination_port)) | ||
2199 | udp->destination_port = htons (ts->source_port); | ||
2200 | else | ||
2201 | udp->destination_port = reply->destination_port; | ||
2202 | udp->len = htons (mlen + sizeof (struct GNUNET_TUN_UdpHeader)); | ||
2203 | GNUNET_TUN_calculate_udp6_checksum (ipv6, | ||
2204 | udp, | ||
2205 | &reply[1], mlen); | ||
2206 | GNUNET_memcpy (&udp[1], | ||
2207 | &reply[1], | ||
2208 | mlen); | ||
2209 | (void) GNUNET_HELPER_send (helper_handle, | ||
2210 | msg, | ||
2211 | GNUNET_YES, | ||
2212 | NULL, NULL); | ||
2213 | } | ||
2214 | } | ||
2215 | break; | ||
2216 | default: | ||
2217 | GNUNET_assert (0); | ||
2218 | } | ||
2219 | GNUNET_CONTAINER_heap_update_cost (ts->heap_node, | ||
2220 | GNUNET_TIME_absolute_get ().abs_value_us); | ||
2221 | GNUNET_CADET_receive_done (channel); | ||
2222 | return GNUNET_OK; | ||
2223 | } | ||
2224 | |||
2225 | |||
2226 | /** | ||
2227 | * We got a TCP packet back from the CADET channel. Pass it on to the | ||
2228 | * local virtual interface via the helper. | ||
2229 | * | ||
2230 | * @param cls closure, NULL | ||
2231 | * @param channel connection to the other end | ||
2232 | * @param channel_ctx pointer to our `struct ChannelState *` | ||
2233 | * @param message the actual message | ||
2234 | * @return #GNUNET_OK to keep the connection open, | ||
2235 | * #GNUNET_SYSERR to close it (signal serious error) | ||
2236 | */ | ||
2237 | static int | ||
2238 | receive_tcp_back (void *cls, | ||
2239 | struct GNUNET_CADET_Channel *channel, | ||
2240 | void **channel_ctx, | ||
2241 | const struct GNUNET_MessageHeader *message) | ||
2242 | { | ||
2243 | struct ChannelState *ts = *channel_ctx; | ||
2244 | const struct GNUNET_EXIT_TcpDataMessage *data; | ||
2245 | size_t mlen; | ||
2246 | |||
2247 | GNUNET_STATISTICS_update (stats, | ||
2248 | gettext_noop ("# TCP packets received from cadet"), | ||
2249 | 1, GNUNET_NO); | ||
2250 | mlen = ntohs (message->size); | ||
2251 | if (mlen < sizeof (struct GNUNET_EXIT_TcpDataMessage)) | ||
2252 | { | ||
2253 | GNUNET_break_op (0); | ||
2254 | return GNUNET_SYSERR; | ||
2255 | } | ||
2256 | if (NULL == ts->heap_node) | ||
2257 | { | ||
2258 | GNUNET_break_op (0); | ||
2259 | return GNUNET_SYSERR; | ||
2260 | } | ||
2261 | data = (const struct GNUNET_EXIT_TcpDataMessage *) message; | ||
2262 | mlen -= sizeof (struct GNUNET_EXIT_TcpDataMessage); | ||
2263 | { | ||
2264 | char sbuf[INET6_ADDRSTRLEN]; | ||
2265 | char dbuf[INET6_ADDRSTRLEN]; | ||
2266 | |||
2267 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2268 | "Received TCP reply from cadet, sending %u bytes from [%s]:%u -> [%s]:%u via TUN\n", | ||
2269 | (unsigned int) mlen, | ||
2270 | inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof (sbuf)), | ||
2271 | ts->destination_port, | ||
2272 | inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof (dbuf)), | ||
2273 | ts->source_port); | ||
2274 | } | ||
2275 | if (data->tcp_header.off * 4 < sizeof (struct GNUNET_TUN_TcpHeader)) | ||
2276 | { | ||
2277 | GNUNET_break_op (0); | ||
2278 | return GNUNET_SYSERR; | ||
2279 | } | ||
2280 | switch (ts->af) | ||
2281 | { | ||
2282 | case AF_INET: | ||
2283 | { | ||
2284 | size_t size = sizeof (struct GNUNET_TUN_IPv4Header) | ||
2285 | + sizeof (struct GNUNET_TUN_TcpHeader) | ||
2286 | + sizeof (struct GNUNET_MessageHeader) + | ||
2287 | sizeof (struct GNUNET_TUN_Layer2PacketHeader) + | ||
2288 | mlen; | ||
2289 | { | ||
2290 | char buf[size] GNUNET_ALIGN; | ||
2291 | struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; | ||
2292 | struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1]; | ||
2293 | struct GNUNET_TUN_IPv4Header *ipv4 = (struct GNUNET_TUN_IPv4Header *) &tun[1]; | ||
2294 | struct GNUNET_TUN_TcpHeader *tcp = (struct GNUNET_TUN_TcpHeader *) &ipv4[1]; | ||
2295 | msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
2296 | msg->size = htons (size); | ||
2297 | tun->flags = htons (0); | ||
2298 | tun->proto = htons (ETH_P_IPV4); | ||
2299 | GNUNET_TUN_initialize_ipv4_header (ipv4, | ||
2300 | IPPROTO_TCP, | ||
2301 | sizeof (struct GNUNET_TUN_TcpHeader) + mlen, | ||
2302 | &ts->destination_ip.v4, | ||
2303 | &ts->source_ip.v4); | ||
2304 | *tcp = data->tcp_header; | ||
2305 | tcp->source_port = htons (ts->destination_port); | ||
2306 | tcp->destination_port = htons (ts->source_port); | ||
2307 | GNUNET_TUN_calculate_tcp4_checksum (ipv4, | ||
2308 | tcp, | ||
2309 | &data[1], | ||
2310 | mlen); | ||
2311 | GNUNET_memcpy (&tcp[1], | ||
2312 | &data[1], | ||
2313 | mlen); | ||
2314 | (void) GNUNET_HELPER_send (helper_handle, | ||
2315 | msg, | ||
2316 | GNUNET_YES, | ||
2317 | NULL, NULL); | ||
2318 | } | ||
2319 | } | ||
2320 | break; | ||
2321 | case AF_INET6: | ||
2322 | { | ||
2323 | size_t size = sizeof (struct GNUNET_TUN_IPv6Header) | ||
2324 | + sizeof (struct GNUNET_TUN_TcpHeader) | ||
2325 | + sizeof (struct GNUNET_MessageHeader) + | ||
2326 | sizeof (struct GNUNET_TUN_Layer2PacketHeader) + | ||
2327 | mlen; | ||
2328 | { | ||
2329 | char buf[size] GNUNET_ALIGN; | ||
2330 | struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; | ||
2331 | struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1]; | ||
2332 | struct GNUNET_TUN_IPv6Header *ipv6 = (struct GNUNET_TUN_IPv6Header *) &tun[1]; | ||
2333 | struct GNUNET_TUN_TcpHeader *tcp = (struct GNUNET_TUN_TcpHeader *) &ipv6[1]; | ||
2334 | msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
2335 | msg->size = htons (size); | ||
2336 | tun->flags = htons (0); | ||
2337 | tun->proto = htons (ETH_P_IPV6); | ||
2338 | GNUNET_TUN_initialize_ipv6_header (ipv6, | ||
2339 | IPPROTO_TCP, | ||
2340 | sizeof (struct GNUNET_TUN_TcpHeader) + mlen, | ||
2341 | &ts->destination_ip.v6, | ||
2342 | &ts->source_ip.v6); | ||
2343 | *tcp = data->tcp_header; | ||
2344 | tcp->source_port = htons (ts->destination_port); | ||
2345 | tcp->destination_port = htons (ts->source_port); | ||
2346 | GNUNET_TUN_calculate_tcp6_checksum (ipv6, | ||
2347 | tcp, | ||
2348 | &data[1], | ||
2349 | mlen); | ||
2350 | GNUNET_memcpy (&tcp[1], | ||
2351 | &data[1], | ||
2352 | mlen); | ||
2353 | (void) GNUNET_HELPER_send (helper_handle, | ||
2354 | msg, | ||
2355 | GNUNET_YES, | ||
2356 | NULL, NULL); | ||
2357 | } | ||
2358 | } | ||
2359 | break; | ||
2360 | } | ||
2361 | GNUNET_CONTAINER_heap_update_cost (ts->heap_node, | ||
2362 | GNUNET_TIME_absolute_get ().abs_value_us); | ||
2363 | GNUNET_CADET_receive_done (channel); | ||
2364 | return GNUNET_OK; | ||
2365 | } | ||
2366 | |||
2367 | |||
2368 | /** | ||
2369 | * Allocate an IPv4 address from the range of the channel | 2335 | * Allocate an IPv4 address from the range of the channel |
2370 | * for a new redirection. | 2336 | * for a new redirection. |
2371 | * | 2337 | * |
@@ -2813,29 +2779,6 @@ handle_client_redirect_to_service (void *cls, | |||
2813 | } | 2779 | } |
2814 | 2780 | ||
2815 | 2781 | ||
2816 | /** | ||
2817 | * Function called whenever a channel is destroyed. Should clean up | ||
2818 | * any associated state. | ||
2819 | * | ||
2820 | * @param cls closure (set from #GNUNET_CADET_connect) | ||
2821 | * @param channel connection to the other end (henceforth invalid) | ||
2822 | * @param channel_ctx place where local state associated | ||
2823 | * with the channel is stored (our `struct ChannelState`) | ||
2824 | */ | ||
2825 | static void | ||
2826 | channel_cleaner (void *cls, | ||
2827 | const struct GNUNET_CADET_Channel *channel, | ||
2828 | void *channel_ctx) | ||
2829 | { | ||
2830 | struct ChannelState *ts = channel_ctx; | ||
2831 | |||
2832 | ts->channel = NULL; /* we must not call GNUNET_CADET_channel_destroy() anymore */ | ||
2833 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2834 | "CADET notified us about death of channel to `%s'\n", | ||
2835 | print_channel_destination (&ts->destination)); | ||
2836 | free_channel_state (ts); | ||
2837 | } | ||
2838 | |||
2839 | 2782 | ||
2840 | /** | 2783 | /** |
2841 | * Free memory occupied by an entry in the destination map. | 2784 | * Free memory occupied by an entry in the destination map. |
@@ -2984,12 +2927,6 @@ run (void *cls, | |||
2984 | const struct GNUNET_CONFIGURATION_Handle *cfg_, | 2927 | const struct GNUNET_CONFIGURATION_Handle *cfg_, |
2985 | struct GNUNET_SERVICE_Handle *service) | 2928 | struct GNUNET_SERVICE_Handle *service) |
2986 | { | 2929 | { |
2987 | static const struct GNUNET_CADET_MessageHandler cadet_handlers[] = { | ||
2988 | { &receive_udp_back, GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY, 0}, | ||
2989 | { &receive_tcp_back, GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_VPN, 0}, | ||
2990 | { &receive_icmp_back, GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_VPN, 0}, | ||
2991 | {NULL, 0, 0} | ||
2992 | }; | ||
2993 | char *ifname; | 2930 | char *ifname; |
2994 | char *ipv6addr; | 2931 | char *ipv6addr; |
2995 | char *ipv6prefix_s; | 2932 | char *ipv6prefix_s; |
@@ -3130,11 +3067,7 @@ run (void *cls, | |||
3130 | } | 3067 | } |
3131 | vpn_argv[6] = NULL; | 3068 | vpn_argv[6] = NULL; |
3132 | 3069 | ||
3133 | cadet_handle | 3070 | cadet_handle = GNUNET_CADET_connecT (cfg_); |
3134 | = GNUNET_CADET_connect (cfg_, | ||
3135 | NULL, | ||
3136 | &channel_cleaner, | ||
3137 | cadet_handlers); | ||
3138 | // FIXME never opens ports??? | 3071 | // FIXME never opens ports??? |
3139 | helper_handle = GNUNET_HELPER_start (GNUNET_NO, | 3072 | helper_handle = GNUNET_HELPER_start (GNUNET_NO, |
3140 | "gnunet-helper-vpn", vpn_argv, | 3073 | "gnunet-helper-vpn", vpn_argv, |