diff options
author | Christian Fuchs <christian.fuchs@cfuchs.net> | 2014-06-04 13:49:37 +0000 |
---|---|---|
committer | Christian Fuchs <christian.fuchs@cfuchs.net> | 2014-06-04 13:49:37 +0000 |
commit | 4d3d60d2c8324e5d1b562c36fd5b0bdfb38ebfef (patch) | |
tree | befdd2d9ded5e7bf6901df0a502743e90e517272 | |
parent | 2b578307c94bb98769f148e3dccc71f72cb66c3c (diff) | |
download | gnunet-4d3d60d2c8324e5d1b562c36fd5b0bdfb38ebfef.tar.gz gnunet-4d3d60d2c8324e5d1b562c36fd5b0bdfb38ebfef.zip |
- added many lots of new error checking to nat_auto and nat_mini. icmp_client server and client not contained in this commit.
-rw-r--r-- | src/nat/nat_auto.c | 87 | ||||
-rw-r--r-- | src/nat/nat_mini.c | 31 |
2 files changed, 86 insertions, 32 deletions
diff --git a/src/nat/nat_auto.c b/src/nat/nat_auto.c index 184f23538..b53fd0d47 100644 --- a/src/nat/nat_auto.c +++ b/src/nat/nat_auto.c | |||
@@ -141,6 +141,10 @@ struct GNUNET_NAT_AutoHandle | |||
141 | */ | 141 | */ |
142 | int have_v6; | 142 | int have_v6; |
143 | 143 | ||
144 | /** | ||
145 | * Error code for better debugging and user feedback | ||
146 | */ | ||
147 | enum GNUNET_NAT_FailureCode ret; | ||
144 | }; | 148 | }; |
145 | 149 | ||
146 | 150 | ||
@@ -166,6 +170,7 @@ fail_timeout (void *cls, | |||
166 | { | 170 | { |
167 | struct GNUNET_NAT_AutoHandle *ah = cls; | 171 | struct GNUNET_NAT_AutoHandle *ah = cls; |
168 | 172 | ||
173 | ah->ret = GNUNET_NAT_ERROR_NAT_TEST_TIMEOUT; | ||
169 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 174 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
170 | _("NAT traversal with ICMP Server timed out.\n")); | 175 | _("NAT traversal with ICMP Server timed out.\n")); |
171 | GNUNET_assert (NULL != ah->tst); | 176 | GNUNET_assert (NULL != ah->tst); |
@@ -227,6 +232,7 @@ reversal_test (void *cls, | |||
227 | &result_callback, ah); | 232 | &result_callback, ah); |
228 | if (NULL == ah->tst) | 233 | if (NULL == ah->tst) |
229 | { | 234 | { |
235 | ah->ret = GNUNET_NAT_ERROR_NAT_TEST_START_FAILED; | ||
230 | next_phase (ah); | 236 | next_phase (ah); |
231 | return; | 237 | return; |
232 | } | 238 | } |
@@ -243,6 +249,10 @@ static void | |||
243 | test_online (struct GNUNET_NAT_AutoHandle *ah) | 249 | test_online (struct GNUNET_NAT_AutoHandle *ah) |
244 | { | 250 | { |
245 | // FIXME: not implemented | 251 | // FIXME: not implemented |
252 | /* | ||
253 | * if (failure) | ||
254 | * ah->ret = GNUNET_NAT_ERROR_NOT_ONLINE; | ||
255 | */ | ||
246 | next_phase (ah); | 256 | next_phase (ah); |
247 | } | 257 | } |
248 | 258 | ||
@@ -263,7 +273,8 @@ set_external_ipv4 (void *cls, | |||
263 | char buf[INET_ADDRSTRLEN]; | 273 | char buf[INET_ADDRSTRLEN]; |
264 | 274 | ||
265 | ah->eh = NULL; | 275 | ah->eh = NULL; |
266 | if (NULL == addr) | 276 | ah->ret = ret; |
277 | if (GNUNET_NAT_ERROR_SUCCESS != ret) | ||
267 | { | 278 | { |
268 | next_phase (ah); | 279 | next_phase (ah); |
269 | return; | 280 | return; |
@@ -281,6 +292,11 @@ set_external_ipv4 (void *cls, | |||
281 | if (NULL == inet_ntop (AF_INET, addr, buf, sizeof (buf))) | 292 | if (NULL == inet_ntop (AF_INET, addr, buf, sizeof (buf))) |
282 | { | 293 | { |
283 | GNUNET_break (0); | 294 | GNUNET_break (0); |
295 | /* actually, this should never happen, as the caller already executed just | ||
296 | * this check, but for consistency (eg: future changes in the caller) | ||
297 | * we still need to report this error... | ||
298 | */ | ||
299 | ah->ret = GNUNET_NAT_ERROR_EXTERNAL_IP_ADDRESS_INVALID; | ||
284 | next_phase (ah); | 300 | next_phase (ah); |
285 | return; | 301 | return; |
286 | } | 302 | } |
@@ -298,6 +314,9 @@ set_external_ipv4 (void *cls, | |||
298 | static void | 314 | static void |
299 | test_external_ip (struct GNUNET_NAT_AutoHandle *ah) | 315 | test_external_ip (struct GNUNET_NAT_AutoHandle *ah) |
300 | { | 316 | { |
317 | if (GNUNET_NAT_ERROR_SUCCESS != ah->ret) | ||
318 | next_phase (ah); | ||
319 | |||
301 | // FIXME: CPS? | 320 | // FIXME: CPS? |
302 | /* try to detect external IP */ | 321 | /* try to detect external IP */ |
303 | ah->eh = GNUNET_NAT_mini_get_external_ipv4 (TIMEOUT, | 322 | ah->eh = GNUNET_NAT_mini_get_external_ipv4 (TIMEOUT, |
@@ -319,7 +338,7 @@ test_external_ip (struct GNUNET_NAT_AutoHandle *ah) | |||
319 | * @return GNUNET_OK to continue iteration, #GNUNET_SYSERR to abort | 338 | * @return GNUNET_OK to continue iteration, #GNUNET_SYSERR to abort |
320 | */ | 339 | */ |
321 | static int | 340 | static int |
322 | nipo (void *cls, | 341 | process_if (void *cls, |
323 | const char *name, | 342 | const char *name, |
324 | int isDefault, | 343 | int isDefault, |
325 | const struct sockaddr *addr, | 344 | const struct sockaddr *addr, |
@@ -358,6 +377,7 @@ nipo (void *cls, | |||
358 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 377 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
359 | _("Detected internal network address `%s'.\n"), | 378 | _("Detected internal network address `%s'.\n"), |
360 | buf); | 379 | buf); |
380 | ah->ret = GNUNET_NAT_ERROR_SUCCESS; | ||
361 | /* no need to continue iteration */ | 381 | /* no need to continue iteration */ |
362 | return GNUNET_SYSERR; | 382 | return GNUNET_SYSERR; |
363 | } | 383 | } |
@@ -372,7 +392,9 @@ static void | |||
372 | test_local_ip (struct GNUNET_NAT_AutoHandle *ah) | 392 | test_local_ip (struct GNUNET_NAT_AutoHandle *ah) |
373 | { | 393 | { |
374 | ah->have_v6 = GNUNET_NO; | 394 | ah->have_v6 = GNUNET_NO; |
375 | GNUNET_OS_network_interfaces_list (&nipo, ah); | 395 | ah->ret = GNUNET_NAT_ERROR_NO_VALID_IF_IP_COMBO; // reset to success if any of the IFs in below iterator has a valid IP |
396 | GNUNET_OS_network_interfaces_list (&process_if, ah); | ||
397 | |||
376 | GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat", "DISABLEV6", | 398 | GNUNET_CONFIGURATION_set_value_string (ah->cfg, "nat", "DISABLEV6", |
377 | (GNUNET_YES == ah->have_v6) ? "NO" : "YES"); | 399 | (GNUNET_YES == ah->have_v6) ? "NO" : "YES"); |
378 | next_phase (ah); | 400 | next_phase (ah); |
@@ -387,7 +409,11 @@ test_local_ip (struct GNUNET_NAT_AutoHandle *ah) | |||
387 | static void | 409 | static void |
388 | test_nat_punched (struct GNUNET_NAT_AutoHandle *ah) | 410 | test_nat_punched (struct GNUNET_NAT_AutoHandle *ah) |
389 | { | 411 | { |
412 | if (GNUNET_NAT_ERROR_SUCCESS != ah->ret) | ||
413 | next_phase (ah); | ||
414 | |||
390 | // FIXME: not implemented | 415 | // FIXME: not implemented |
416 | |||
391 | next_phase (ah); | 417 | next_phase (ah); |
392 | } | 418 | } |
393 | 419 | ||
@@ -402,6 +428,9 @@ test_upnpc (struct GNUNET_NAT_AutoHandle *ah) | |||
402 | { | 428 | { |
403 | int have_upnpc; | 429 | int have_upnpc; |
404 | 430 | ||
431 | if (GNUNET_NAT_ERROR_SUCCESS != ah->ret) | ||
432 | next_phase (ah); | ||
433 | |||
405 | /* test if upnpc is available */ | 434 | /* test if upnpc is available */ |
406 | have_upnpc = (GNUNET_SYSERR != | 435 | have_upnpc = (GNUNET_SYSERR != |
407 | GNUNET_OS_check_helper_binary ("upnpc", GNUNET_NO, NULL)); | 436 | GNUNET_OS_check_helper_binary ("upnpc", GNUNET_NO, NULL)); |
@@ -425,27 +454,44 @@ test_upnpc (struct GNUNET_NAT_AutoHandle *ah) | |||
425 | static void | 454 | static void |
426 | test_icmp_server (struct GNUNET_NAT_AutoHandle *ah) | 455 | test_icmp_server (struct GNUNET_NAT_AutoHandle *ah) |
427 | { | 456 | { |
428 | int hns; | 457 | int ext_ip; |
458 | int nated; | ||
459 | int binary; | ||
429 | char *tmp; | 460 | char *tmp; |
430 | char *binary; | 461 | char *helper; |
431 | 462 | ext_ip = GNUNET_NO; | |
463 | nated = GNUNET_NO; | ||
464 | binary = GNUNET_NO; | ||
465 | |||
432 | tmp = NULL; | 466 | tmp = NULL; |
433 | binary = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-nat-server"); | 467 | helper = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-nat-server"); |
434 | hns = | 468 | if ((GNUNET_OK == |
435 | ((GNUNET_OK == | ||
436 | GNUNET_CONFIGURATION_get_value_string (ah->cfg, "nat", "EXTERNAL_ADDRESS", | 469 | GNUNET_CONFIGURATION_get_value_string (ah->cfg, "nat", "EXTERNAL_ADDRESS", |
437 | &tmp)) && (0 < strlen (tmp)) && | 470 | &tmp)) && (0 < strlen (tmp))){ |
438 | (GNUNET_YES == | 471 | ext_ip = GNUNET_OK; |
439 | GNUNET_CONFIGURATION_get_value_yesno (ah->cfg, "nat", "BEHIND_NAT")) && | 472 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("test_icmp_server not possible, as we have no public IPv4 address\n")); |
440 | (GNUNET_YES == | 473 | } |
441 | GNUNET_OS_check_helper_binary (binary, GNUNET_YES, "-d 127.0.0.1" ))); // use localhost as source for that one udp-port, ok for testing | 474 | else |
475 | goto err; | ||
476 | |||
477 | if (GNUNET_YES == | ||
478 | GNUNET_CONFIGURATION_get_value_yesno (ah->cfg, "nat", "BEHIND_NAT")){ | ||
479 | nated = GNUNET_YES; | ||
480 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("test_icmp_server not possible, as we are not behind NAT\n")); | ||
481 | } | ||
482 | else | ||
483 | goto err; | ||
484 | |||
485 | if (GNUNET_YES == | ||
486 | GNUNET_OS_check_helper_binary (helper, GNUNET_YES, "-d 127.0.0.1" )){ | ||
487 | binary = GNUNET_OK; // use localhost as source for that one udp-port, ok for testing | ||
488 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("No working gnunet-helper-nat-server found\n")); | ||
489 | } | ||
490 | err: | ||
442 | GNUNET_free_non_null (tmp); | 491 | GNUNET_free_non_null (tmp); |
443 | GNUNET_free (binary); | 492 | GNUNET_free (helper); |
444 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 493 | |
445 | (hns) | 494 | if (GNUNET_OK == ext_ip && GNUNET_YES == nated && GNUNET_OK == binary) |
446 | ? _("gnunet-helper-nat-server found, testing it\n") | ||
447 | : _("No working gnunet-helper-nat-server found\n")); | ||
448 | if (hns) | ||
449 | ah->task = GNUNET_SCHEDULER_add_now (&reversal_test, ah); | 495 | ah->task = GNUNET_SCHEDULER_add_now (&reversal_test, ah); |
450 | else | 496 | else |
451 | next_phase (ah); | 497 | next_phase (ah); |
@@ -551,6 +597,7 @@ GNUNET_NAT_autoconfig_start (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
551 | ah = GNUNET_new (struct GNUNET_NAT_AutoHandle); | 597 | ah = GNUNET_new (struct GNUNET_NAT_AutoHandle); |
552 | ah->fin_cb = cb; | 598 | ah->fin_cb = cb; |
553 | ah->fin_cb_cls = cb_cls; | 599 | ah->fin_cb_cls = cb_cls; |
600 | ah->ret = GNUNET_NAT_ERROR_SUCCESS; | ||
554 | ah->cfg = GNUNET_CONFIGURATION_dup (cfg); | 601 | ah->cfg = GNUNET_CONFIGURATION_dup (cfg); |
555 | ah->initial_cfg = GNUNET_CONFIGURATION_dup (cfg); | 602 | ah->initial_cfg = GNUNET_CONFIGURATION_dup (cfg); |
556 | 603 | ||
diff --git a/src/nat/nat_mini.c b/src/nat/nat_mini.c index 27a1361b2..ae15b5c13 100644 --- a/src/nat/nat_mini.c +++ b/src/nat/nat_mini.c | |||
@@ -98,6 +98,10 @@ struct GNUNET_NAT_ExternalHandle | |||
98 | */ | 98 | */ |
99 | char buf[17]; | 99 | char buf[17]; |
100 | 100 | ||
101 | /** | ||
102 | * Error code for better debugging and user feedback | ||
103 | */ | ||
104 | enum GNUNET_NAT_FailureCode ret; | ||
101 | }; | 105 | }; |
102 | 106 | ||
103 | 107 | ||
@@ -115,15 +119,16 @@ read_external_ipv4 (void *cls, | |||
115 | struct GNUNET_NAT_ExternalHandle *eh = cls; | 119 | struct GNUNET_NAT_ExternalHandle *eh = cls; |
116 | ssize_t ret; | 120 | ssize_t ret; |
117 | struct in_addr addr; | 121 | struct in_addr addr; |
118 | int iret; | ||
119 | 122 | ||
120 | eh->task = GNUNET_SCHEDULER_NO_TASK; | 123 | eh->task = GNUNET_SCHEDULER_NO_TASK; |
121 | if (GNUNET_YES == GNUNET_NETWORK_fdset_handle_isset (tc->read_ready, eh->r)) | 124 | if (GNUNET_YES == GNUNET_NETWORK_fdset_handle_isset (tc->read_ready, eh->r)) |
122 | ret = | 125 | ret = |
123 | GNUNET_DISK_file_read (eh->r, &eh->buf[eh->off], | 126 | GNUNET_DISK_file_read (eh->r, &eh->buf[eh->off], |
124 | sizeof (eh->buf) - eh->off); | 127 | sizeof (eh->buf) - eh->off); |
125 | else | 128 | else { |
129 | eh->ret = GNUNET_NAT_ERROR_IPC_FAILURE; | ||
126 | ret = -1; /* error reading, timeout, etc. */ | 130 | ret = -1; /* error reading, timeout, etc. */ |
131 | } | ||
127 | if (ret > 0) | 132 | if (ret > 0) |
128 | { | 133 | { |
129 | /* try to read more */ | 134 | /* try to read more */ |
@@ -134,23 +139,21 @@ read_external_ipv4 (void *cls, | |||
134 | &read_external_ipv4, eh); | 139 | &read_external_ipv4, eh); |
135 | return; | 140 | return; |
136 | } | 141 | } |
137 | iret = GNUNET_NO; | 142 | eh->ret = GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_OUTPUT_INVALID; |
138 | if ((eh->off > 7) && (eh->buf[eh->off - 1] == '\n')) | 143 | if ((eh->off > 7) && (eh->buf[eh->off - 1] == '\n')) |
139 | { | 144 | { |
140 | eh->buf[eh->off - 1] = '\0'; | 145 | eh->buf[eh->off - 1] = '\0'; |
141 | if (1 == inet_pton (AF_INET, eh->buf, &addr)) | 146 | if (1 == inet_pton (AF_INET, eh->buf, &addr)) |
142 | { | 147 | { |
143 | if (0 == addr.s_addr) | 148 | if (0 != addr.s_addr) |
144 | iret = GNUNET_NO; /* got 0.0.0.0 */ | 149 | eh->ret = GNUNET_NAT_ERROR_EXTERNAL_IP_ADDRESS_INVALID; /* got 0.0.0.0 */ |
145 | else | 150 | else |
146 | iret = GNUNET_OK; | 151 | eh->ret = GNUNET_NAT_ERROR_SUCCESS; |
147 | } | 152 | } |
148 | } | 153 | } |
149 | eh->cb (eh->cb_cls, | 154 | eh->cb (eh->cb_cls, |
150 | (GNUNET_OK == iret) | 155 | (GNUNET_NAT_ERROR_SUCCESS == eh->ret) ? &addr : NULL, |
151 | ? &addr : | 156 | eh->ret); |
152 | NULL, | ||
153 | GNUNET_NAT_ERROR_EXTERNAL_IP_NO_VALID_ADDRESS_FOUND); | ||
154 | GNUNET_NAT_mini_get_external_ipv4_cancel (eh); | 157 | GNUNET_NAT_mini_get_external_ipv4_cancel (eh); |
155 | } | 158 | } |
156 | 159 | ||
@@ -170,7 +173,7 @@ signal_external_ip_error (void *cls, | |||
170 | eh->task = GNUNET_SCHEDULER_NO_TASK; | 173 | eh->task = GNUNET_SCHEDULER_NO_TASK; |
171 | eh->cb (eh->cb_cls, | 174 | eh->cb (eh->cb_cls, |
172 | NULL, | 175 | NULL, |
173 | GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_NOT_FOUND); | 176 | eh->ret); |
174 | GNUNET_free (eh); | 177 | GNUNET_free (eh); |
175 | } | 178 | } |
176 | 179 | ||
@@ -181,7 +184,7 @@ signal_external_ip_error (void *cls, | |||
181 | * @param timeout when to fail | 184 | * @param timeout when to fail |
182 | * @param cb function to call with result | 185 | * @param cb function to call with result |
183 | * @param cb_cls closure for @a cb | 186 | * @param cb_cls closure for @a cb |
184 | * @return handle for cancellation (can only be used until @a cb is called), NULL on error | 187 | * @return handle for cancellation (can only be used until @a cb is called), never NULL |
185 | */ | 188 | */ |
186 | struct GNUNET_NAT_ExternalHandle * | 189 | struct GNUNET_NAT_ExternalHandle * |
187 | GNUNET_NAT_mini_get_external_ipv4 (struct GNUNET_TIME_Relative timeout, | 190 | GNUNET_NAT_mini_get_external_ipv4 (struct GNUNET_TIME_Relative timeout, |
@@ -192,11 +195,13 @@ GNUNET_NAT_mini_get_external_ipv4 (struct GNUNET_TIME_Relative timeout, | |||
192 | eh = GNUNET_new (struct GNUNET_NAT_ExternalHandle); | 195 | eh = GNUNET_new (struct GNUNET_NAT_ExternalHandle); |
193 | eh->cb = cb; | 196 | eh->cb = cb; |
194 | eh->cb_cls = cb_cls; | 197 | eh->cb_cls = cb_cls; |
198 | eh->ret = GNUNET_NAT_ERROR_SUCCESS; | ||
195 | if (GNUNET_SYSERR == | 199 | if (GNUNET_SYSERR == |
196 | GNUNET_OS_check_helper_binary ("external-ip", GNUNET_NO, NULL)) | 200 | GNUNET_OS_check_helper_binary ("external-ip", GNUNET_NO, NULL)) |
197 | { | 201 | { |
198 | LOG (GNUNET_ERROR_TYPE_INFO, | 202 | LOG (GNUNET_ERROR_TYPE_INFO, |
199 | _("`external-ip' command not found\n")); | 203 | _("`external-ip' command not found\n")); |
204 | eh->ret = GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_NOT_FOUND; | ||
200 | eh->task = GNUNET_SCHEDULER_add_now (&signal_external_ip_error, | 205 | eh->task = GNUNET_SCHEDULER_add_now (&signal_external_ip_error, |
201 | eh); | 206 | eh); |
202 | return eh; | 207 | return eh; |
@@ -206,6 +211,7 @@ GNUNET_NAT_mini_get_external_ipv4 (struct GNUNET_TIME_Relative timeout, | |||
206 | eh->opipe = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES); | 211 | eh->opipe = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES); |
207 | if (NULL == eh->opipe) | 212 | if (NULL == eh->opipe) |
208 | { | 213 | { |
214 | eh->ret = GNUNET_NAT_ERROR_IPC_FAILURE; | ||
209 | eh->task = GNUNET_SCHEDULER_add_now (&signal_external_ip_error, | 215 | eh->task = GNUNET_SCHEDULER_add_now (&signal_external_ip_error, |
210 | eh); | 216 | eh); |
211 | return eh; | 217 | return eh; |
@@ -217,6 +223,7 @@ GNUNET_NAT_mini_get_external_ipv4 (struct GNUNET_TIME_Relative timeout, | |||
217 | if (NULL == eh->eip) | 223 | if (NULL == eh->eip) |
218 | { | 224 | { |
219 | GNUNET_DISK_pipe_close (eh->opipe); | 225 | GNUNET_DISK_pipe_close (eh->opipe); |
226 | eh->ret = GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_NOT_EXECUTEABLE; | ||
220 | eh->task = GNUNET_SCHEDULER_add_now (&signal_external_ip_error, | 227 | eh->task = GNUNET_SCHEDULER_add_now (&signal_external_ip_error, |
221 | eh); | 228 | eh); |
222 | return eh; | 229 | return eh; |