diff options
Diffstat (limited to 'src/setup/gnunet-setup-transport.c')
-rw-r--r-- | src/setup/gnunet-setup-transport.c | 483 |
1 files changed, 379 insertions, 104 deletions
diff --git a/src/setup/gnunet-setup-transport.c b/src/setup/gnunet-setup-transport.c index d8b25c29..0b8f47e6 100644 --- a/src/setup/gnunet-setup-transport.c +++ b/src/setup/gnunet-setup-transport.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | (C) 2010 Christian Grothoff (and other contributing authors) | 3 | (C) 2010, 2012 Christian Grothoff (and other contributing authors) |
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,8 +22,15 @@ | |||
22 | * @file src/setup/gnunet-setup-transport.c | 22 | * @file src/setup/gnunet-setup-transport.c |
23 | * @brief support for transport (NAT) configuration | 23 | * @brief support for transport (NAT) configuration |
24 | * @author Christian Grothoff | 24 | * @author Christian Grothoff |
25 | * | ||
26 | * TODO: | ||
27 | * - cummulate collected information in the context | ||
28 | * - implement and refine existing network setup tests | ||
29 | * - if NAT detected and all traversal methods fail and no IPv6, | ||
30 | * set transport plugin ports to 0 | ||
25 | */ | 31 | */ |
26 | #include "gnunet-setup.h" | 32 | #include "gnunet-setup.h" |
33 | #include "gnunet-setup-transport.h" | ||
27 | #include <gnunet/gnunet_util_lib.h> | 34 | #include <gnunet/gnunet_util_lib.h> |
28 | #include <gnunet/gnunet_resolver_service.h> | 35 | #include <gnunet/gnunet_resolver_service.h> |
29 | #include <gnunet/gnunet_nat_lib.h> | 36 | #include <gnunet/gnunet_nat_lib.h> |
@@ -31,19 +38,105 @@ | |||
31 | /** | 38 | /** |
32 | * How long do we wait for the NAT test to report success? | 39 | * How long do we wait for the NAT test to report success? |
33 | */ | 40 | */ |
34 | #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1) | 41 | #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15) |
35 | 42 | ||
36 | /** | 43 | /** |
37 | * Handle to the active NAT test. | 44 | * Phases of the auto configuration. |
38 | */ | 45 | */ |
39 | static struct GNUNET_NAT_Test *tst; | 46 | enum AutoPhase |
47 | { | ||
48 | /** | ||
49 | * Initial start value. | ||
50 | */ | ||
51 | AUTO_INIT = 0, | ||
52 | |||
53 | /** | ||
54 | * Test if we are online. | ||
55 | */ | ||
56 | AUTO_ONLINE = 1, | ||
57 | |||
58 | /** | ||
59 | * Test our external IP. | ||
60 | */ | ||
61 | AUTO_EXTERNAL_IP, | ||
62 | |||
63 | /** | ||
64 | * Test our internal IP. | ||
65 | */ | ||
66 | AUTO_LOCAL_IP, | ||
67 | |||
68 | /** | ||
69 | * Test if NAT was punched. | ||
70 | */ | ||
71 | AUTO_NAT_PUNCHED, | ||
72 | |||
73 | /** | ||
74 | * Test if UPnP is working. | ||
75 | */ | ||
76 | AUTO_UPNPC, | ||
77 | |||
78 | /** | ||
79 | * Test if ICMP server works. | ||
80 | */ | ||
81 | AUTO_ICMP_SERVER, | ||
82 | |||
83 | /** | ||
84 | * Test if ICMP client works. | ||
85 | */ | ||
86 | AUTO_ICMP_CLIENT, | ||
87 | |||
88 | /** | ||
89 | * Last phase, we're done. | ||
90 | */ | ||
91 | AUTO_DONE | ||
92 | |||
93 | }; | ||
94 | |||
40 | 95 | ||
41 | /** | 96 | /** |
42 | * Task identifier for the timeout. | 97 | * Context for the autoconfig test. |
43 | */ | 98 | */ |
44 | static GNUNET_SCHEDULER_TaskIdentifier tsk; | 99 | struct GNUNET_SetupAutoContext |
100 | { | ||
101 | |||
102 | /** | ||
103 | * Handle to the active NAT test. | ||
104 | */ | ||
105 | struct GNUNET_NAT_Test *tst; | ||
106 | |||
107 | /** | ||
108 | * Function to call when done. | ||
109 | */ | ||
110 | GNUNET_SetupAutoConfigFinished fin_cb; | ||
111 | |||
112 | /** | ||
113 | * Closure for 'fin_cb'. | ||
114 | */ | ||
115 | void *fin_cb_cls; | ||
116 | |||
117 | /** | ||
118 | * Handle for active 'GNUNET_NAT_mini_get_external_ipv4'-operation. | ||
119 | */ | ||
120 | struct GNUNET_NAT_ExternalHandle *eh; | ||
121 | |||
122 | /** | ||
123 | * Task identifier for the timeout. | ||
124 | */ | ||
125 | GNUNET_SCHEDULER_TaskIdentifier tsk; | ||
126 | |||
127 | /** | ||
128 | * Where are we in the test? | ||
129 | */ | ||
130 | enum AutoPhase phase; | ||
131 | |||
132 | }; | ||
45 | 133 | ||
46 | static struct GNUNET_OS_Process *resolver; | 134 | |
135 | /** | ||
136 | * Run the next phase of the auto test. | ||
137 | */ | ||
138 | static void | ||
139 | next_phase (struct GNUNET_SetupAutoContext *ac); | ||
47 | 140 | ||
48 | 141 | ||
49 | /** | 142 | /** |
@@ -78,16 +171,14 @@ update_icmp_server_enable_button (int on) | |||
78 | static void | 171 | static void |
79 | result_callback (void *cls, int success) | 172 | result_callback (void *cls, int success) |
80 | { | 173 | { |
81 | GNUNET_SCHEDULER_cancel (tsk); | 174 | struct GNUNET_SetupAutoContext *ac = cls; |
82 | tsk = GNUNET_SCHEDULER_NO_TASK; | 175 | |
83 | GNUNET_NAT_test_stop (tst); | 176 | GNUNET_SCHEDULER_cancel (ac->tsk); |
84 | tst = NULL; | 177 | ac->tsk = GNUNET_SCHEDULER_NO_TASK; |
85 | if (NULL != resolver) | 178 | GNUNET_NAT_test_stop (ac->tst); |
86 | { | 179 | ac->tst = NULL; |
87 | GNUNET_break (0 == GNUNET_OS_process_kill (resolver, SIGTERM)); | ||
88 | GNUNET_OS_process_destroy (resolver); | ||
89 | } | ||
90 | update_icmp_server_enable_button (success); | 180 | update_icmp_server_enable_button (success); |
181 | next_phase (ac); | ||
91 | } | 182 | } |
92 | 183 | ||
93 | 184 | ||
@@ -95,17 +186,20 @@ result_callback (void *cls, int success) | |||
95 | * Function called if NAT failed to confirm success. | 186 | * Function called if NAT failed to confirm success. |
96 | * Clean up and update GUI (with failure). | 187 | * Clean up and update GUI (with failure). |
97 | * | 188 | * |
98 | * @param cls closure (unused) | 189 | * @param cls closure with setup context |
99 | * @param tc scheduler callback | 190 | * @param tc scheduler callback |
100 | */ | 191 | */ |
101 | static void | 192 | static void |
102 | fail_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 193 | fail_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
103 | { | 194 | { |
104 | GNUNET_assert (NULL != tst); | 195 | struct GNUNET_SetupAutoContext *ac = cls; |
105 | tsk = GNUNET_SCHEDULER_NO_TASK; | 196 | |
106 | GNUNET_NAT_test_stop (tst); | 197 | GNUNET_assert (NULL != ac->tst); |
107 | tst = NULL; | 198 | ac->tsk = GNUNET_SCHEDULER_NO_TASK; |
199 | GNUNET_NAT_test_stop (ac->tst); | ||
200 | ac->tst = NULL; | ||
108 | update_icmp_server_enable_button (GNUNET_NO); | 201 | update_icmp_server_enable_button (GNUNET_NO); |
202 | next_phase (ac); | ||
109 | } | 203 | } |
110 | 204 | ||
111 | 205 | ||
@@ -118,32 +212,92 @@ fail_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
118 | static void | 212 | static void |
119 | reversal_test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 213 | reversal_test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
120 | { | 214 | { |
121 | int *ok = cls; | 215 | struct GNUNET_SetupAutoContext *ac = cls; |
122 | 216 | ||
123 | GNUNET_assert (NULL != cfg); | 217 | GNUNET_assert (NULL != cfg); |
124 | GNUNET_RESOLVER_connect (cfg); | 218 | GNUNET_RESOLVER_connect (cfg); |
125 | tst = GNUNET_NAT_test_start (cfg, GNUNET_YES, 0, 0, &result_callback, ok); | 219 | ac->tst = GNUNET_NAT_test_start (cfg, GNUNET_YES, 0, 0, &result_callback, ac); |
126 | if (NULL == tst) | 220 | if (NULL == ac->tst) |
127 | { | 221 | { |
128 | *ok = GNUNET_SYSERR; | 222 | next_phase (ac); |
129 | return; | 223 | return; |
130 | } | 224 | } |
131 | tsk = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &fail_timeout, ok); | 225 | ac->tsk = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &fail_timeout, ac); |
132 | } | 226 | } |
133 | 227 | ||
228 | |||
134 | /** | 229 | /** |
135 | * Test if connection reversal (ICMP method) works. | 230 | * Test if we are online at all. |
231 | * | ||
232 | * @param ac auto setup context | ||
136 | */ | 233 | */ |
137 | static void | 234 | static void |
138 | test_connection_reversal () | 235 | test_online (struct GNUNET_SetupAutoContext *ac) |
139 | { | 236 | { |
140 | if (NULL != resolver) | 237 | // FIXME: not implemented |
141 | return; /* test already active!? */ | 238 | next_phase (ac); |
142 | resolver = | 239 | } |
143 | GNUNET_OS_start_process (GNUNET_YES, GNUNET_OS_INHERIT_STD_ALL, | 240 | |
144 | NULL, NULL, "gnunet-service-resolver", | 241 | |
145 | "gnunet-service-resolver", NULL); | 242 | /** |
146 | GNUNET_SCHEDULER_add_now (&reversal_test, NULL); | 243 | * Set our external IPv4 address. |
244 | * | ||
245 | * @param cls closure with our setup context | ||
246 | * @param addr the address, NULL on errors | ||
247 | */ | ||
248 | static void | ||
249 | set_external_ipv4 (void *cls, const struct in_addr *addr) | ||
250 | { | ||
251 | struct GNUNET_SetupAutoContext *ac = cls; | ||
252 | char buf[INET_ADDRSTRLEN]; | ||
253 | GObject *o; | ||
254 | |||
255 | ac->eh = NULL; | ||
256 | if (NULL == addr) | ||
257 | { | ||
258 | next_phase (ac); | ||
259 | return; | ||
260 | } | ||
261 | /* enable 'behind nat' */ | ||
262 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
263 | _("Detected external IP `%s'\n"), | ||
264 | inet_ntop (AF_INET, | ||
265 | addr, | ||
266 | buf, | ||
267 | sizeof (buf))); | ||
268 | if (NULL != cfg) | ||
269 | GNUNET_CONFIGURATION_set_value_string (cfg, "nat", "BEHIND_NAT", "YES"); | ||
270 | o = GNUNET_SETUP_get_object ("GNUNET_setup_transport_nat_checkbutton"); | ||
271 | gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (o), TRUE); | ||
272 | |||
273 | /* set external IP address */ | ||
274 | if (NULL == inet_ntop (AF_INET, addr, buf, sizeof (buf))) | ||
275 | { | ||
276 | GNUNET_break (0); | ||
277 | next_phase (ac); | ||
278 | return; | ||
279 | } | ||
280 | if (NULL != cfg) | ||
281 | GNUNET_CONFIGURATION_set_value_string (cfg, "nat", "EXTERNAL_ADDRESS", | ||
282 | buf); | ||
283 | o = GNUNET_SETUP_get_object ("GNUNET_setup_transport_external_ip_address_entry"); | ||
284 | gtk_entry_set_text (GTK_ENTRY (o), buf); | ||
285 | next_phase (ac); | ||
286 | } | ||
287 | |||
288 | |||
289 | /** | ||
290 | * Determine our external IPv4 address. | ||
291 | * | ||
292 | * @param ac auto setup context | ||
293 | */ | ||
294 | static void | ||
295 | test_external_ip (struct GNUNET_SetupAutoContext *ac) | ||
296 | { | ||
297 | // FIXME: CPS? | ||
298 | /* try to detect external IP */ | ||
299 | ac->eh = GNUNET_NAT_mini_get_external_ipv4 (TIMEOUT, | ||
300 | &set_external_ipv4, ac); | ||
147 | } | 301 | } |
148 | 302 | ||
149 | 303 | ||
@@ -151,7 +305,7 @@ test_connection_reversal () | |||
151 | * Process list of local IP addresses. Find and set the | 305 | * Process list of local IP addresses. Find and set the |
152 | * one of the default interface. | 306 | * one of the default interface. |
153 | * | 307 | * |
154 | * @param cls closure (not used) | 308 | * @param cls pointer to int to store if we have a non-local IPv6 address |
155 | * @param name name of the interface (can be NULL for unknown) | 309 | * @param name name of the interface (can be NULL for unknown) |
156 | * @param isDefault is this presumably the default interface | 310 | * @param isDefault is this presumably the default interface |
157 | * @param addr address of this interface (can be NULL for unknown or unassigned) | 311 | * @param addr address of this interface (can be NULL for unknown or unassigned) |
@@ -165,12 +319,21 @@ nipo (void *cls, const char *name, int isDefault, const struct sockaddr *addr, | |||
165 | const struct sockaddr *broadcast_addr, const struct sockaddr *netmask, | 319 | const struct sockaddr *broadcast_addr, const struct sockaddr *netmask, |
166 | socklen_t addrlen) | 320 | socklen_t addrlen) |
167 | { | 321 | { |
322 | int *have_v6 = cls; | ||
168 | const struct sockaddr_in *in; | 323 | const struct sockaddr_in *in; |
169 | char buf[INET_ADDRSTRLEN]; | 324 | char buf[INET_ADDRSTRLEN]; |
170 | GtkEntry *entry; | 325 | GtkEntry *entry; |
171 | 326 | ||
172 | if (!isDefault) | 327 | if (!isDefault) |
173 | return GNUNET_OK; | 328 | return GNUNET_OK; |
329 | if ( (sizeof (struct sockaddr_in6) == addrlen) && | ||
330 | (0 != memcmp (&in6addr_loopback, addr, | ||
331 | addrlen)) && | ||
332 | (! IN6_IS_ADDR_LINKLOCAL(addr)) ) | ||
333 | { | ||
334 | *have_v6 = GNUNET_YES; | ||
335 | return GNUNET_OK; | ||
336 | } | ||
174 | if (addrlen != sizeof (struct sockaddr_in)) | 337 | if (addrlen != sizeof (struct sockaddr_in)) |
175 | return GNUNET_OK; | 338 | return GNUNET_OK; |
176 | in = (const struct sockaddr_in *) addr; | 339 | in = (const struct sockaddr_in *) addr; |
@@ -185,11 +348,6 @@ nipo (void *cls, const char *name, int isDefault, const struct sockaddr *addr, | |||
185 | entry = | 348 | entry = |
186 | GTK_ENTRY (GNUNET_SETUP_get_object | 349 | GTK_ENTRY (GNUNET_SETUP_get_object |
187 | ("GNUNET_setup_transport_internal_ip_entry")); | 350 | ("GNUNET_setup_transport_internal_ip_entry")); |
188 | if (entry == NULL) | ||
189 | { | ||
190 | GNUNET_break (0); | ||
191 | return GNUNET_SYSERR; | ||
192 | } | ||
193 | gtk_entry_set_text (entry, buf); | 351 | gtk_entry_set_text (entry, buf); |
194 | /* no need to continue iteration */ | 352 | /* no need to continue iteration */ |
195 | return GNUNET_SYSERR; | 353 | return GNUNET_SYSERR; |
@@ -197,80 +355,80 @@ nipo (void *cls, const char *name, int isDefault, const struct sockaddr *addr, | |||
197 | 355 | ||
198 | 356 | ||
199 | /** | 357 | /** |
200 | * Set our external IPv4 address. | 358 | * Determine our local IP addresses; detect internal IP & IPv6-support |
201 | * | 359 | * |
202 | * @param cls closure | 360 | * @param ac auto setup context |
203 | * @param addr the address, NULL on errors | ||
204 | */ | 361 | */ |
205 | static void | 362 | static void |
206 | set_external_ipv4 (void *cls, const struct in_addr *addr) | 363 | test_local_ip (struct GNUNET_SetupAutoContext *ac) |
207 | { | 364 | { |
208 | char buf[INET_ADDRSTRLEN]; | ||
209 | GObject *o; | ||
210 | GtkEntry *entry; | ||
211 | GtkToggleButton *button; | 365 | GtkToggleButton *button; |
366 | int have_v6; | ||
367 | |||
368 | have_v6 = GNUNET_NO; | ||
369 | GNUNET_OS_network_interfaces_list (&nipo, &have_v6); | ||
370 | button = GTK_TOGGLE_BUTTON (GNUNET_SETUP_get_object ("GNUNET_setup_transport_disable_ipv6_checkbutton")); | ||
371 | gtk_toggle_button_set_active (button, | ||
372 | (GNUNET_YES == have_v6) ? FALSE : TRUE); | ||
373 | if (NULL != cfg) | ||
374 | GNUNET_CONFIGURATION_set_value_string (cfg, "nat", "DISABLEV6", | ||
375 | (GNUNET_YES == have_v6) ? "NO" : "YES"); | ||
376 | next_phase (ac); | ||
377 | } | ||
212 | 378 | ||
213 | if (NULL != addr) | 379 | |
214 | { | 380 | /** |
215 | /* enable 'behind nat' */ | 381 | * Test if NAT has been punched |
216 | if (NULL != cfg) | 382 | * |
217 | GNUNET_CONFIGURATION_set_value_string (cfg, "nat", "BEHIND_NAT", "YES"); | 383 | * @param ac auto setup context |
218 | o = GNUNET_SETUP_get_object ("GNUNET_setup_transport_nat_checkbutton"); | 384 | */ |
219 | if (NULL != o) | 385 | static void |
220 | { | 386 | test_nat_punched (struct GNUNET_SetupAutoContext *ac) |
221 | button = GTK_TOGGLE_BUTTON (o); | 387 | { |
222 | if (button == NULL) | 388 | // FIXME: not implemented |
223 | { | 389 | next_phase (ac); |
224 | GNUNET_break (0); | ||
225 | return; | ||
226 | } | ||
227 | gtk_toggle_button_set_active (button, TRUE); | ||
228 | } | ||
229 | |||
230 | /* set external IP address */ | ||
231 | if (NULL == inet_ntop (AF_INET, addr, buf, sizeof (buf))) | ||
232 | { | ||
233 | GNUNET_break (0); | ||
234 | return; | ||
235 | } | ||
236 | if (NULL != cfg) | ||
237 | GNUNET_CONFIGURATION_set_value_string (cfg, "nat", "EXTERNAL_ADDRESS", | ||
238 | buf); | ||
239 | o = GNUNET_SETUP_get_object | ||
240 | ("GNUNET_setup_transport_external_ip_address_entry"); | ||
241 | if (NULL != o) | ||
242 | { | ||
243 | entry = GTK_ENTRY (o); | ||
244 | if (entry == NULL) | ||
245 | { | ||
246 | GNUNET_break (0); | ||
247 | return; | ||
248 | } | ||
249 | gtk_entry_set_text (entry, buf); | ||
250 | } | ||
251 | } | ||
252 | } | 390 | } |
253 | 391 | ||
254 | 392 | ||
255 | /** | 393 | /** |
256 | * User asked for autoconfiguration. Try the full program. | 394 | * Test if UPnPC works. |
395 | * | ||
396 | * @param ac auto setup context | ||
257 | */ | 397 | */ |
258 | void | 398 | static void |
259 | GNUNET_setup_transport_autoconfig_button_clicked_cb () | 399 | test_upnpc (struct GNUNET_SetupAutoContext *ac) |
260 | { | 400 | { |
401 | int have_upnpc; | ||
261 | GtkToggleButton *button; | 402 | GtkToggleButton *button; |
262 | int hns; | ||
263 | int hnc; | ||
264 | char *tmp; | ||
265 | 403 | ||
266 | /* try to detect external IP */ | 404 | /* test if upnpc is available */ |
267 | (void) GNUNET_NAT_mini_get_external_ipv4 (TIMEOUT, &set_external_ipv4, NULL); | 405 | button = GTK_TOGGLE_BUTTON (GNUNET_SETUP_get_object ("GNUNET_setup_transport_upnp_enable_checkbutton")); |
268 | /* Try to detect internal IP */ | 406 | have_upnpc = (GNUNET_SYSERR != |
269 | GNUNET_OS_network_interfaces_list (&nipo, NULL); | 407 | GNUNET_OS_check_helper_binary ("upnpc")); |
408 | /* FIXME: test if upnpc is actually working, that is, if transports | ||
409 | start to work once we use UPnP */ | ||
410 | gtk_toggle_button_set_active (button, | ||
411 | have_upnpc | ||
412 | ? TRUE | ||
413 | : FALSE); | ||
414 | if (NULL != cfg) | ||
415 | GNUNET_CONFIGURATION_set_value_string (cfg, "nat", "ENABLE_UPNP", | ||
416 | (GNUNET_YES == have_upnpc) ? "YES" : "NO"); | ||
417 | next_phase (ac); | ||
418 | } | ||
270 | 419 | ||
271 | /* FIXME: do more: test if UPnP works */ | ||
272 | 420 | ||
273 | /* test gnunet-helper-nat-server */ | 421 | /** |
422 | * Test if ICMP server is working | ||
423 | * | ||
424 | * @param ac auto setup context | ||
425 | */ | ||
426 | static void | ||
427 | test_icmp_server (struct GNUNET_SetupAutoContext *ac) | ||
428 | { | ||
429 | int hns; | ||
430 | char *tmp; | ||
431 | |||
274 | tmp = NULL; | 432 | tmp = NULL; |
275 | hns = | 433 | hns = |
276 | ((GNUNET_OK == | 434 | ((GNUNET_OK == |
@@ -282,9 +440,24 @@ GNUNET_setup_transport_autoconfig_button_clicked_cb () | |||
282 | GNUNET_OS_check_helper_binary ("gnunet-helper-nat-server"))); | 440 | GNUNET_OS_check_helper_binary ("gnunet-helper-nat-server"))); |
283 | GNUNET_free_non_null (tmp); | 441 | GNUNET_free_non_null (tmp); |
284 | if (hns) | 442 | if (hns) |
285 | test_connection_reversal (); | 443 | GNUNET_SCHEDULER_add_now (&reversal_test, ac); |
444 | else | ||
445 | next_phase (ac); | ||
446 | } | ||
447 | |||
448 | |||
449 | /** | ||
450 | * Test if ICMP client is working | ||
451 | * | ||
452 | * @param ac auto setup context | ||
453 | */ | ||
454 | static void | ||
455 | test_icmp_client (struct GNUNET_SetupAutoContext *ac) | ||
456 | { | ||
457 | GtkToggleButton *button; | ||
458 | int hnc; | ||
459 | char *tmp; | ||
286 | 460 | ||
287 | /* test gnunet-helper-nat-client */ | ||
288 | tmp = NULL; | 461 | tmp = NULL; |
289 | hnc = | 462 | hnc = |
290 | ((GNUNET_OK == | 463 | ((GNUNET_OK == |
@@ -298,12 +471,114 @@ GNUNET_setup_transport_autoconfig_button_clicked_cb () | |||
298 | button = | 471 | button = |
299 | GTK_TOGGLE_BUTTON (GNUNET_SETUP_get_object | 472 | GTK_TOGGLE_BUTTON (GNUNET_SETUP_get_object |
300 | ("GNUNET_setup_transport_icmp_client_enable_checkbutton")); | 473 | ("GNUNET_setup_transport_icmp_client_enable_checkbutton")); |
301 | if (button == NULL) | 474 | gtk_toggle_button_set_active (button, hnc ? TRUE : FALSE); |
475 | next_phase (ac); | ||
476 | } | ||
477 | |||
478 | |||
479 | /** | ||
480 | * User asked for autoconfiguration. Try the full program. | ||
481 | * | ||
482 | * @param fin_cb function to call when done | ||
483 | * @param fin_cb_cls closure for 'fin_cb' | ||
484 | * @return handle for the operation | ||
485 | */ | ||
486 | struct GNUNET_SetupAutoContext * | ||
487 | GNUNET_setup_transport_autoconfig_start (GNUNET_SetupAutoConfigFinished fin_cb, | ||
488 | void *fin_cb_cls) | ||
489 | { | ||
490 | struct GNUNET_SetupAutoContext *ac; | ||
491 | |||
492 | ac = GNUNET_malloc (sizeof (struct GNUNET_SetupAutoContext)); | ||
493 | ac->fin_cb = fin_cb; | ||
494 | ac->fin_cb_cls = fin_cb_cls; | ||
495 | |||
496 | /* never use loopback addresses if user wanted autoconfiguration */ | ||
497 | GNUNET_CONFIGURATION_set_value_string (cfg, "nat", | ||
498 | "USE_LOCALADDR", | ||
499 | "NO"); | ||
500 | next_phase (ac); | ||
501 | return ac; | ||
502 | } | ||
503 | |||
504 | |||
505 | /** | ||
506 | * Run the next phase of the auto test. | ||
507 | */ | ||
508 | static void | ||
509 | next_phase (struct GNUNET_SetupAutoContext *ac) | ||
510 | { | ||
511 | ac->phase++; | ||
512 | switch (ac->phase) | ||
302 | { | 513 | { |
303 | GNUNET_break (0); | 514 | case AUTO_INIT: |
515 | GNUNET_assert (0); | ||
516 | break; | ||
517 | case AUTO_ONLINE: | ||
518 | test_online (ac); | ||
519 | break; | ||
520 | case AUTO_EXTERNAL_IP: | ||
521 | test_external_ip (ac); | ||
522 | break; | ||
523 | case AUTO_LOCAL_IP: | ||
524 | test_local_ip (ac); | ||
525 | break; | ||
526 | case AUTO_NAT_PUNCHED: | ||
527 | test_nat_punched (ac); | ||
528 | break; | ||
529 | case AUTO_UPNPC: | ||
530 | test_upnpc (ac); | ||
531 | break; | ||
532 | case AUTO_ICMP_SERVER: | ||
533 | test_icmp_server (ac); | ||
534 | break; | ||
535 | case AUTO_ICMP_CLIENT: | ||
536 | test_icmp_client (ac); | ||
537 | break; | ||
538 | case AUTO_DONE: | ||
539 | ac->fin_cb (ac->fin_cb_cls); | ||
540 | GNUNET_free (ac); | ||
304 | return; | 541 | return; |
305 | } | 542 | } |
306 | gtk_toggle_button_set_active (button, hnc ? TRUE : FALSE); | ||
307 | } | 543 | } |
308 | 544 | ||
545 | |||
546 | /** | ||
547 | * Autoconfiguration test is finished, clear the block so | ||
548 | * that it can be run again. | ||
549 | * | ||
550 | * @param cls pointer to the location that needs to be NULLed | ||
551 | */ | ||
552 | static void | ||
553 | clear_ac (void *cls) | ||
554 | { | ||
555 | struct GNUNET_SetupAutoContext **acp = cls; | ||
556 | |||
557 | *acp = NULL; | ||
558 | gtk_widget_set_sensitive (GTK_WIDGET (GNUNET_SETUP_get_object ("GNUNET_setup_transport_autoconfig_button")), | ||
559 | TRUE); | ||
560 | } | ||
561 | |||
562 | |||
563 | /** | ||
564 | * User asked for autoconfiguration. Try the full program | ||
565 | */ | ||
566 | void | ||
567 | GNUNET_setup_transport_autoconfig_button_clicked_cb () | ||
568 | { | ||
569 | static struct GNUNET_SetupAutoContext *ac; | ||
570 | |||
571 | /* make sure only one test is running at a time */ | ||
572 | if (NULL != ac) | ||
573 | { | ||
574 | GNUNET_break (0); | ||
575 | return; | ||
576 | } | ||
577 | gtk_widget_set_sensitive (GTK_WIDGET (GNUNET_SETUP_get_object ("GNUNET_setup_transport_autoconfig_button")), | ||
578 | FALSE); | ||
579 | ac = GNUNET_setup_transport_autoconfig_start (&clear_ac, | ||
580 | &ac); | ||
581 | } | ||
582 | |||
583 | |||
309 | /* end of gnunet-setup-transport.c */ | 584 | /* end of gnunet-setup-transport.c */ |