diff options
-rw-r--r-- | src/transport/Makefile.am | 1 | ||||
-rw-r--r-- | src/transport/gnunet-transport.c | 202 |
2 files changed, 202 insertions, 1 deletions
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am index 06bea95ba..110b43cdf 100644 --- a/src/transport/Makefile.am +++ b/src/transport/Makefile.am | |||
@@ -129,6 +129,7 @@ gnunet_transport_SOURCES = \ | |||
129 | gnunet-transport.c | 129 | gnunet-transport.c |
130 | gnunet_transport_LDADD = \ | 130 | gnunet_transport_LDADD = \ |
131 | $(top_builddir)/src/transport/libgnunettransport.la \ | 131 | $(top_builddir)/src/transport/libgnunettransport.la \ |
132 | $(top_builddir)/src/nat/libgnunetnat.la \ | ||
132 | $(top_builddir)/src/util/libgnunetutil.la \ | 133 | $(top_builddir)/src/util/libgnunetutil.la \ |
133 | $(GN_LIBINTL) | 134 | $(GN_LIBINTL) |
134 | gnunet_transport_DEPENDENCIES = \ | 135 | gnunet_transport_DEPENDENCIES = \ |
diff --git a/src/transport/gnunet-transport.c b/src/transport/gnunet-transport.c index 68f508f5b..686423a3d 100644 --- a/src/transport/gnunet-transport.c +++ b/src/transport/gnunet-transport.c | |||
@@ -29,9 +29,16 @@ | |||
29 | */ | 29 | */ |
30 | 30 | ||
31 | #include "platform.h" | 31 | #include "platform.h" |
32 | #include "gnunet_program_lib.h" | 32 | #include "gnunet_util_lib.h" |
33 | #include "gnunet_resolver_service.h" | ||
33 | #include "gnunet_protocols.h" | 34 | #include "gnunet_protocols.h" |
34 | #include "gnunet_transport_service.h" | 35 | #include "gnunet_transport_service.h" |
36 | #include "gnunet_nat_lib.h" | ||
37 | |||
38 | /** | ||
39 | * How long do we wait for the NAT test to report success? | ||
40 | */ | ||
41 | #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1) | ||
35 | 42 | ||
36 | /** | 43 | /** |
37 | * Which peer should we connect to? | 44 | * Which peer should we connect to? |
@@ -64,6 +71,11 @@ static int benchmark_receive; | |||
64 | static int iterate_connections; | 71 | static int iterate_connections; |
65 | 72 | ||
66 | /** | 73 | /** |
74 | * Option -t. | ||
75 | */ | ||
76 | static int test_configuration; | ||
77 | |||
78 | /** | ||
67 | * Global return value (0 success). | 79 | * Global return value (0 success). |
68 | */ | 80 | */ |
69 | static int ret; | 81 | static int ret; |
@@ -104,6 +116,187 @@ static GNUNET_SCHEDULER_TaskIdentifier end; | |||
104 | */ | 116 | */ |
105 | static int verbosity; | 117 | static int verbosity; |
106 | 118 | ||
119 | /** | ||
120 | * Resolver process handle. | ||
121 | */ | ||
122 | struct GNUNET_OS_Process *resolver; | ||
123 | |||
124 | /** | ||
125 | * Number of tasks running that still need the resolver. | ||
126 | */ | ||
127 | static unsigned int resolver_users; | ||
128 | |||
129 | |||
130 | /** | ||
131 | * Context for a plugin test. | ||
132 | */ | ||
133 | struct TestContext | ||
134 | { | ||
135 | |||
136 | /** | ||
137 | * Handle to the active NAT test. | ||
138 | */ | ||
139 | struct GNUNET_NAT_Test *tst; | ||
140 | |||
141 | /** | ||
142 | * Task identifier for the timeout. | ||
143 | */ | ||
144 | GNUNET_SCHEDULER_TaskIdentifier tsk; | ||
145 | |||
146 | /** | ||
147 | * Name of plugin under test. | ||
148 | */ | ||
149 | const char *name; | ||
150 | |||
151 | }; | ||
152 | |||
153 | |||
154 | /** | ||
155 | * Display the result of the test. | ||
156 | * | ||
157 | * @param tc test context | ||
158 | * @param result GNUNET_YES on success | ||
159 | */ | ||
160 | static void | ||
161 | display_test_result (struct TestContext *tc, int result) | ||
162 | { | ||
163 | if (GNUNET_YES != result) | ||
164 | { | ||
165 | fprintf (stderr, | ||
166 | "Configuration for plugin `%s' did not work!\n", | ||
167 | tc->name); | ||
168 | } | ||
169 | else | ||
170 | { | ||
171 | fprintf (stderr, | ||
172 | "Configuration for plugin `%s' is working!\n", | ||
173 | tc->name); | ||
174 | } | ||
175 | if (GNUNET_SCHEDULER_NO_TASK != tc->tsk) | ||
176 | { | ||
177 | GNUNET_SCHEDULER_cancel (tc->tsk); | ||
178 | tc->tsk = GNUNET_SCHEDULER_NO_TASK; | ||
179 | } | ||
180 | if (NULL != tc->tst) | ||
181 | { | ||
182 | GNUNET_NAT_test_stop (tc->tst); | ||
183 | tc->tst = NULL; | ||
184 | } | ||
185 | GNUNET_free (tc); | ||
186 | resolver_users--; | ||
187 | if ( (0 == resolver_users) && | ||
188 | (NULL != resolver) ) | ||
189 | { | ||
190 | GNUNET_break (0 == GNUNET_OS_process_kill (resolver, SIGTERM)); | ||
191 | GNUNET_OS_process_close (resolver); | ||
192 | resolver = NULL; | ||
193 | } | ||
194 | } | ||
195 | |||
196 | |||
197 | /** | ||
198 | * Function called by NAT on success. | ||
199 | * Clean up and update GUI (with success). | ||
200 | * | ||
201 | * @param cls test context | ||
202 | * @param success currently always GNUNET_OK | ||
203 | */ | ||
204 | static void | ||
205 | result_callback (void *cls, int success) | ||
206 | { | ||
207 | struct TestContext *tc = cls; | ||
208 | |||
209 | display_test_result (tc, success); | ||
210 | } | ||
211 | |||
212 | |||
213 | /** | ||
214 | * Function called if NAT failed to confirm success. | ||
215 | * Clean up and update GUI (with failure). | ||
216 | * | ||
217 | * @param cls test context | ||
218 | * @param tc scheduler callback | ||
219 | */ | ||
220 | static void | ||
221 | fail_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
222 | { | ||
223 | struct TestContext *tstc = cls; | ||
224 | |||
225 | tstc->tsk = GNUNET_SCHEDULER_NO_TASK; | ||
226 | display_test_result (tstc, GNUNET_NO); | ||
227 | } | ||
228 | |||
229 | |||
230 | /** | ||
231 | * Test our plugin's configuration (NAT traversal, etc.). | ||
232 | * | ||
233 | * @param cfg configuration to test | ||
234 | */ | ||
235 | static void | ||
236 | do_test_configuration (const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
237 | { | ||
238 | char *plugins; | ||
239 | char *tok; | ||
240 | unsigned long long bnd_port; | ||
241 | unsigned long long adv_port; | ||
242 | struct TestContext *tc; | ||
243 | |||
244 | if (GNUNET_OK != | ||
245 | GNUNET_CONFIGURATION_get_value_string (cfg, | ||
246 | "transport", | ||
247 | "plugins", | ||
248 | &plugins)) | ||
249 | { | ||
250 | fprintf (stderr, | ||
251 | _("No transport plugins configured, peer will never communicate\n")); | ||
252 | ret = 4; | ||
253 | return; | ||
254 | } | ||
255 | for (tok = strtok (plugins, " "); tok != NULL; tok = strtok (NULL, " ")) | ||
256 | { | ||
257 | char section[12+strlen(tok)]; | ||
258 | |||
259 | GNUNET_snprintf (section, | ||
260 | sizeof (section), | ||
261 | "transport-%s", | ||
262 | tok); | ||
263 | if (GNUNET_OK != | ||
264 | GNUNET_CONFIGURATION_get_value_number (cfg, section, "PORT", | ||
265 | &bnd_port)) | ||
266 | { | ||
267 | fprintf (stderr, | ||
268 | _("No port configured for plugin `%s', cannot test it\n"), | ||
269 | tok); | ||
270 | continue; | ||
271 | } | ||
272 | if (GNUNET_OK != | ||
273 | GNUNET_CONFIGURATION_get_value_number (cfg, section, | ||
274 | "ADVERTISED_PORT", &adv_port)) | ||
275 | adv_port = bnd_port; | ||
276 | if (NULL == resolver) | ||
277 | resolver = | ||
278 | GNUNET_OS_start_process (NULL, NULL, "gnunet-service-resolver", | ||
279 | "gnunet-service-resolver", NULL); | ||
280 | resolver_users++; | ||
281 | GNUNET_RESOLVER_connect (cfg); | ||
282 | tc = GNUNET_malloc (sizeof (struct TestContext)); | ||
283 | tc->name = GNUNET_strdup (tok); | ||
284 | tc->tst = | ||
285 | GNUNET_NAT_test_start (cfg, | ||
286 | (0 == strcasecmp (tok, "udp")) | ||
287 | ? GNUNET_NO | ||
288 | : GNUNET_YES, | ||
289 | (uint16_t) bnd_port, | ||
290 | (uint16_t) adv_port, &result_callback, tc); | ||
291 | if (NULL == tc->tst) | ||
292 | { | ||
293 | display_test_result (tc, GNUNET_SYSERR); | ||
294 | continue; | ||
295 | } | ||
296 | tc->tsk = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &fail_timeout, tc); | ||
297 | } | ||
298 | GNUNET_free (plugins); | ||
299 | } | ||
107 | 300 | ||
108 | 301 | ||
109 | /** | 302 | /** |
@@ -323,6 +516,10 @@ static void | |||
323 | run (void *cls, char *const *args, const char *cfgfile, | 516 | run (void *cls, char *const *args, const char *cfgfile, |
324 | const struct GNUNET_CONFIGURATION_Handle *cfg) | 517 | const struct GNUNET_CONFIGURATION_Handle *cfg) |
325 | { | 518 | { |
519 | if (test_configuration) | ||
520 | { | ||
521 | do_test_configuration (cfg); | ||
522 | } | ||
326 | if (benchmark_send && (NULL == cpid)) | 523 | if (benchmark_send && (NULL == cpid)) |
327 | { | 524 | { |
328 | fprintf (stderr, _("Option `%s' makes no sense without option `%s'.\n"), | 525 | fprintf (stderr, _("Option `%s' makes no sense without option `%s'.\n"), |
@@ -385,6 +582,9 @@ main (int argc, char *const *argv) | |||
385 | {'s', "send", NULL, | 582 | {'s', "send", NULL, |
386 | gettext_noop ("send data for benchmarking to the other peer (until CTRL-C)"), | 583 | gettext_noop ("send data for benchmarking to the other peer (until CTRL-C)"), |
387 | 0, &GNUNET_GETOPT_set_one, &benchmark_send}, | 584 | 0, &GNUNET_GETOPT_set_one, &benchmark_send}, |
585 | {'t', "test", NULL, | ||
586 | gettext_noop ("test transport configuration (involves external server)"), | ||
587 | 0, &GNUNET_GETOPT_set_one, &test_configuration}, | ||
388 | GNUNET_GETOPT_OPTION_VERBOSE(&verbosity), | 588 | GNUNET_GETOPT_OPTION_VERBOSE(&verbosity), |
389 | GNUNET_GETOPT_OPTION_END | 589 | GNUNET_GETOPT_OPTION_END |
390 | }; | 590 | }; |