diff options
Diffstat (limited to 'src/nat/gnunet-nat.c')
-rw-r--r-- | src/nat/gnunet-nat.c | 223 |
1 files changed, 102 insertions, 121 deletions
diff --git a/src/nat/gnunet-nat.c b/src/nat/gnunet-nat.c index 275553203..6c533374e 100644 --- a/src/nat/gnunet-nat.c +++ b/src/nat/gnunet-nat.c | |||
@@ -120,20 +120,19 @@ test_finished () | |||
120 | */ | 120 | */ |
121 | static void | 121 | static void |
122 | address_cb (void *cls, | 122 | address_cb (void *cls, |
123 | void **app_ctx, | 123 | void **app_ctx, |
124 | int add_remove, | 124 | int add_remove, |
125 | enum GNUNET_NAT_AddressClass ac, | 125 | enum GNUNET_NAT_AddressClass ac, |
126 | const struct sockaddr *addr, | 126 | const struct sockaddr *addr, |
127 | socklen_t addrlen) | 127 | socklen_t addrlen) |
128 | { | 128 | { |
129 | (void) cls; | 129 | (void) cls; |
130 | (void) app_ctx; | 130 | (void) app_ctx; |
131 | 131 | ||
132 | fprintf (stdout, | 132 | fprintf (stdout, |
133 | "%s %s (%d)\n", | 133 | "%s %s (%d)\n", |
134 | add_remove ? "+" : "-", | 134 | add_remove ? "+" : "-", |
135 | GNUNET_a2s (addr, | 135 | GNUNET_a2s (addr, addrlen), |
136 | addrlen), | ||
137 | (int) ac); | 136 | (int) ac); |
138 | } | 137 | } |
139 | 138 | ||
@@ -149,13 +148,12 @@ address_cb (void *cls, | |||
149 | */ | 148 | */ |
150 | static void | 149 | static void |
151 | reversal_cb (void *cls, | 150 | reversal_cb (void *cls, |
152 | const struct sockaddr *remote_addr, | 151 | const struct sockaddr *remote_addr, |
153 | socklen_t remote_addrlen) | 152 | socklen_t remote_addrlen) |
154 | { | 153 | { |
155 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, | 154 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, |
156 | "Connection reversal requested by %s\n", | 155 | "Connection reversal requested by %s\n", |
157 | GNUNET_a2s (remote_addr, | 156 | GNUNET_a2s (remote_addr, remote_addrlen)); |
158 | remote_addrlen)); | ||
159 | } | 157 | } |
160 | 158 | ||
161 | 159 | ||
@@ -194,9 +192,9 @@ stun_read_task (void *cls) | |||
194 | ssize_t size; | 192 | ssize_t size; |
195 | 193 | ||
196 | rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, | 194 | rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, |
197 | ls, | 195 | ls, |
198 | &stun_read_task, | 196 | &stun_read_task, |
199 | NULL); | 197 | NULL); |
200 | size = GNUNET_NETWORK_socket_recvfrom_amount (ls); | 198 | size = GNUNET_NETWORK_socket_recvfrom_amount (ls); |
201 | if (size > 0) | 199 | if (size > 0) |
202 | { | 200 | { |
@@ -212,10 +210,10 @@ stun_read_task (void *cls) | |||
212 | ssize_t ret; | 210 | ssize_t ret; |
213 | 211 | ||
214 | ret = GNUNET_NETWORK_socket_recvfrom (ls, | 212 | ret = GNUNET_NETWORK_socket_recvfrom (ls, |
215 | buf, | 213 | buf, |
216 | size + 1, | 214 | size + 1, |
217 | (struct sockaddr *) &sa, | 215 | (struct sockaddr *) &sa, |
218 | &salen); | 216 | &salen); |
219 | if (ret != size) | 217 | if (ret != size) |
220 | { | 218 | { |
221 | GNUNET_break (0); | 219 | GNUNET_break (0); |
@@ -224,10 +222,10 @@ stun_read_task (void *cls) | |||
224 | return; | 222 | return; |
225 | } | 223 | } |
226 | (void) GNUNET_NAT_stun_handle_packet (nh, | 224 | (void) GNUNET_NAT_stun_handle_packet (nh, |
227 | (const struct sockaddr *) &sa, | 225 | (const struct sockaddr *) &sa, |
228 | salen, | 226 | salen, |
229 | buf, | 227 | buf, |
230 | ret); | 228 | ret); |
231 | } | 229 | } |
232 | } | 230 | } |
233 | 231 | ||
@@ -254,8 +252,7 @@ run (void *cls, | |||
254 | 252 | ||
255 | if (use_tcp && use_udp) | 253 | if (use_tcp && use_udp) |
256 | { | 254 | { |
257 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, | 255 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "Cannot use TCP and UDP\n"); |
258 | "Cannot use TCP and UDP\n"); | ||
259 | global_ret = 1; | 256 | global_ret = 1; |
260 | return; | 257 | return; |
261 | } | 258 | } |
@@ -265,13 +262,11 @@ run (void *cls, | |||
265 | if (use_udp) | 262 | if (use_udp) |
266 | proto = IPPROTO_UDP; | 263 | proto = IPPROTO_UDP; |
267 | 264 | ||
268 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, | 265 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); |
269 | NULL); | ||
270 | 266 | ||
271 | if (0 == proto) | 267 | if (0 == proto) |
272 | { | 268 | { |
273 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, | 269 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "Must specify either TCP or UDP\n"); |
274 | "Must specify either TCP or UDP\n"); | ||
275 | global_ret = 1; | 270 | global_ret = 1; |
276 | return; | 271 | return; |
277 | } | 272 | } |
@@ -281,28 +276,26 @@ run (void *cls, | |||
281 | remote_sa = NULL; | 276 | remote_sa = NULL; |
282 | if (NULL != local_addr) | 277 | if (NULL != local_addr) |
283 | { | 278 | { |
284 | local_len = (socklen_t) GNUNET_STRINGS_parse_socket_addr (local_addr, | 279 | local_len = |
285 | &af, | 280 | (socklen_t) GNUNET_STRINGS_parse_socket_addr (local_addr, &af, &local_sa); |
286 | &local_sa); | ||
287 | if (0 == local_len) | 281 | if (0 == local_len) |
288 | { | 282 | { |
289 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, | 283 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, |
290 | "Invalid socket address `%s'\n", | 284 | "Invalid socket address `%s'\n", |
291 | local_addr); | 285 | local_addr); |
292 | goto fail_and_shutdown; | 286 | goto fail_and_shutdown; |
293 | } | 287 | } |
294 | } | 288 | } |
295 | 289 | ||
296 | if (NULL != remote_addr) | 290 | if (NULL != remote_addr) |
297 | { | 291 | { |
298 | remote_len = GNUNET_STRINGS_parse_socket_addr (remote_addr, | 292 | remote_len = |
299 | &af, | 293 | GNUNET_STRINGS_parse_socket_addr (remote_addr, &af, &remote_sa); |
300 | &remote_sa); | ||
301 | if (0 == remote_len) | 294 | if (0 == remote_len) |
302 | { | 295 | { |
303 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, | 296 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, |
304 | "Invalid socket address `%s'\n", | 297 | "Invalid socket address `%s'\n", |
305 | remote_addr); | 298 | remote_addr); |
306 | goto fail_and_shutdown; | 299 | goto fail_and_shutdown; |
307 | } | 300 | } |
308 | } | 301 | } |
@@ -312,19 +305,19 @@ run (void *cls, | |||
312 | if (NULL == section_name) | 305 | if (NULL == section_name) |
313 | section_name = GNUNET_strdup ("undefined"); | 306 | section_name = GNUNET_strdup ("undefined"); |
314 | nh = GNUNET_NAT_register (c, | 307 | nh = GNUNET_NAT_register (c, |
315 | section_name, | 308 | section_name, |
316 | proto, | 309 | proto, |
317 | 1, | 310 | 1, |
318 | (const struct sockaddr **) &local_sa, | 311 | (const struct sockaddr **) &local_sa, |
319 | &local_len, | 312 | &local_len, |
320 | &address_cb, | 313 | &address_cb, |
321 | (listen_reversal) ? &reversal_cb : NULL, | 314 | (listen_reversal) ? &reversal_cb : NULL, |
322 | NULL); | 315 | NULL); |
323 | } | 316 | } |
324 | else if (listen_reversal) | 317 | else if (listen_reversal) |
325 | { | 318 | { |
326 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, | 319 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, |
327 | "Use of `-W` only effective in combination with `-i`\n"); | 320 | "Use of `-W` only effective in combination with `-i`\n"); |
328 | goto fail_and_shutdown; | 321 | goto fail_and_shutdown; |
329 | } | 322 | } |
330 | 323 | ||
@@ -332,33 +325,32 @@ run (void *cls, | |||
332 | { | 325 | { |
333 | int ret; | 326 | int ret; |
334 | 327 | ||
335 | if ( (NULL == nh) || | 328 | if ((NULL == nh) || (sizeof (struct sockaddr_in) != local_len)) |
336 | (sizeof (struct sockaddr_in) != local_len) ) | ||
337 | { | 329 | { |
338 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, | 330 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, |
339 | "Require IPv4 local address to initiate connection reversal\n"); | 331 | "Require IPv4 local address to initiate connection reversal\n"); |
340 | goto fail_and_shutdown; | 332 | goto fail_and_shutdown; |
341 | } | 333 | } |
342 | if (sizeof (struct sockaddr_in) != remote_len) | 334 | if (sizeof (struct sockaddr_in) != remote_len) |
343 | { | 335 | { |
344 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, | 336 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, |
345 | "Require IPv4 reversal target address\n"); | 337 | "Require IPv4 reversal target address\n"); |
346 | goto fail_and_shutdown; | 338 | goto fail_and_shutdown; |
347 | } | 339 | } |
348 | GNUNET_assert (AF_INET == local_sa->sa_family); | 340 | GNUNET_assert (AF_INET == local_sa->sa_family); |
349 | GNUNET_assert (AF_INET == remote_sa->sa_family); | 341 | GNUNET_assert (AF_INET == remote_sa->sa_family); |
350 | ret = GNUNET_NAT_request_reversal (nh, | 342 | ret = GNUNET_NAT_request_reversal (nh, |
351 | (const struct sockaddr_in *) local_sa, | 343 | (const struct sockaddr_in *) local_sa, |
352 | (const struct sockaddr_in *) remote_sa); | 344 | (const struct sockaddr_in *) remote_sa); |
353 | switch (ret) | 345 | switch (ret) |
354 | { | 346 | { |
355 | case GNUNET_SYSERR: | 347 | case GNUNET_SYSERR: |
356 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, | 348 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, |
357 | "Connection reversal internal error\n"); | 349 | "Connection reversal internal error\n"); |
358 | break; | 350 | break; |
359 | case GNUNET_NO: | 351 | case GNUNET_NO: |
360 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, | 352 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, |
361 | "Connection reversal unavailable\n"); | 353 | "Connection reversal unavailable\n"); |
362 | break; | 354 | break; |
363 | case GNUNET_OK: | 355 | case GNUNET_OK: |
364 | /* operation in progress */ | 356 | /* operation in progress */ |
@@ -371,46 +363,38 @@ run (void *cls, | |||
371 | if (NULL == local_addr) | 363 | if (NULL == local_addr) |
372 | { | 364 | { |
373 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, | 365 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, |
374 | "Require local address to support STUN requests\n"); | 366 | "Require local address to support STUN requests\n"); |
375 | goto fail_and_shutdown; | 367 | goto fail_and_shutdown; |
376 | } | 368 | } |
377 | if (IPPROTO_UDP != proto) | 369 | if (IPPROTO_UDP != proto) |
378 | { | 370 | { |
379 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, | 371 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "STUN only supported over UDP\n"); |
380 | "STUN only supported over UDP\n"); | ||
381 | goto fail_and_shutdown; | 372 | goto fail_and_shutdown; |
382 | } | 373 | } |
383 | ls = GNUNET_NETWORK_socket_create (af, | 374 | ls = GNUNET_NETWORK_socket_create (af, SOCK_DGRAM, IPPROTO_UDP); |
384 | SOCK_DGRAM, | ||
385 | IPPROTO_UDP); | ||
386 | if (NULL == ls) | 375 | if (NULL == ls) |
387 | { | 376 | { |
388 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, | 377 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "Failed to create socket\n"); |
389 | "Failed to create socket\n"); | ||
390 | goto fail_and_shutdown; | 378 | goto fail_and_shutdown; |
391 | } | 379 | } |
392 | if (GNUNET_OK != | 380 | if (GNUNET_OK != GNUNET_NETWORK_socket_bind (ls, local_sa, local_len)) |
393 | GNUNET_NETWORK_socket_bind (ls, | ||
394 | local_sa, | ||
395 | local_len)) | ||
396 | { | 381 | { |
397 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 382 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
398 | "Failed to bind to %s: %s\n", | 383 | "Failed to bind to %s: %s\n", |
399 | GNUNET_a2s (local_sa, | 384 | GNUNET_a2s (local_sa, local_len), |
400 | local_len), | 385 | strerror (errno)); |
401 | STRERROR (errno)); | ||
402 | goto fail_and_shutdown; | 386 | goto fail_and_shutdown; |
403 | } | 387 | } |
404 | rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, | 388 | rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, |
405 | ls, | 389 | ls, |
406 | &stun_read_task, | 390 | &stun_read_task, |
407 | NULL); | 391 | NULL); |
408 | } | 392 | } |
409 | GNUNET_free_non_null (remote_sa); | 393 | GNUNET_free_non_null (remote_sa); |
410 | GNUNET_free_non_null (local_sa); | 394 | GNUNET_free_non_null (local_sa); |
411 | test_finished (); | 395 | test_finished (); |
412 | return; | 396 | return; |
413 | fail_and_shutdown: | 397 | fail_and_shutdown: |
414 | global_ret = 1; | 398 | global_ret = 1; |
415 | GNUNET_SCHEDULER_shutdown (); | 399 | GNUNET_SCHEDULER_shutdown (); |
416 | GNUNET_free_non_null (remote_sa); | 400 | GNUNET_free_non_null (remote_sa); |
@@ -426,66 +410,63 @@ run (void *cls, | |||
426 | * @return 0 on success, -1 on error | 410 | * @return 0 on success, -1 on error |
427 | */ | 411 | */ |
428 | int | 412 | int |
429 | main (int argc, | 413 | main (int argc, char *const argv[]) |
430 | char *const argv[]) | ||
431 | { | 414 | { |
432 | struct GNUNET_GETOPT_CommandLineOption options[] = { | 415 | struct GNUNET_GETOPT_CommandLineOption options[] = { |
433 | 416 | ||
434 | GNUNET_GETOPT_option_string ('i', | 417 | GNUNET_GETOPT_option_string ( |
435 | "in", | 418 | 'i', |
436 | "ADDRESS", | 419 | "in", |
437 | gettext_noop ("which IP and port are we locally using to bind/listen to"), | 420 | "ADDRESS", |
438 | &local_addr), | 421 | gettext_noop ("which IP and port are we locally using to bind/listen to"), |
439 | 422 | &local_addr), | |
440 | GNUNET_GETOPT_option_string ('r', | 423 | |
441 | "remote", | 424 | GNUNET_GETOPT_option_string ( |
442 | "ADDRESS", | 425 | 'r', |
443 | gettext_noop ("which remote IP and port should be asked for connection reversal"), | 426 | "remote", |
444 | &remote_addr), | 427 | "ADDRESS", |
445 | 428 | gettext_noop ( | |
446 | GNUNET_GETOPT_option_string ('S', | 429 | "which remote IP and port should be asked for connection reversal"), |
447 | "section", | 430 | &remote_addr), |
448 | NULL, | 431 | |
449 | gettext_noop ("name of configuration section to find additional options, such as manual host punching data"), | 432 | GNUNET_GETOPT_option_string ( |
450 | §ion_name), | 433 | 'S', |
434 | "section", | ||
435 | NULL, | ||
436 | gettext_noop ( | ||
437 | "name of configuration section to find additional options, such as manual host punching data"), | ||
438 | §ion_name), | ||
451 | 439 | ||
452 | GNUNET_GETOPT_option_flag ('s', | 440 | GNUNET_GETOPT_option_flag ('s', |
453 | "stun", | 441 | "stun", |
454 | gettext_noop ("enable STUN processing"), | 442 | gettext_noop ("enable STUN processing"), |
455 | &do_stun), | 443 | &do_stun), |
456 | 444 | ||
457 | GNUNET_GETOPT_option_flag ('t', | 445 | GNUNET_GETOPT_option_flag ('t', "tcp", gettext_noop ("use TCP"), &use_tcp), |
458 | "tcp", | ||
459 | gettext_noop ("use TCP"), | ||
460 | &use_tcp), | ||
461 | 446 | ||
462 | GNUNET_GETOPT_option_flag ('u', | 447 | GNUNET_GETOPT_option_flag ('u', "udp", gettext_noop ("use UDP"), &use_udp), |
463 | "udp", | ||
464 | gettext_noop ("use UDP"), | ||
465 | &use_udp), | ||
466 | 448 | ||
467 | GNUNET_GETOPT_option_flag ('W', | 449 | GNUNET_GETOPT_option_flag ('W', |
468 | "watch", | 450 | "watch", |
469 | gettext_noop ("watch for connection reversal requests"), | 451 | gettext_noop ( |
470 | &listen_reversal), | 452 | "watch for connection reversal requests"), |
471 | GNUNET_GETOPT_OPTION_END | 453 | &listen_reversal), |
472 | }; | 454 | GNUNET_GETOPT_OPTION_END}; |
473 | 455 | ||
474 | if (GNUNET_OK != | 456 | if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) |
475 | GNUNET_STRINGS_get_utf8_args (argc, argv, | ||
476 | &argc, &argv)) | ||
477 | return 2; | 457 | return 2; |
478 | if (GNUNET_OK != | 458 | if (GNUNET_OK != |
479 | GNUNET_PROGRAM_run (argc, argv, | 459 | GNUNET_PROGRAM_run (argc, |
480 | "gnunet-nat [options]", | 460 | argv, |
481 | _("GNUnet NAT traversal autoconfigure daemon"), | 461 | "gnunet-nat [options]", |
482 | options, | 462 | _ ("GNUnet NAT traversal autoconfigure daemon"), |
463 | options, | ||
483 | &run, | 464 | &run, |
484 | NULL)) | 465 | NULL)) |
485 | { | 466 | { |
486 | global_ret = 1; | 467 | global_ret = 1; |
487 | } | 468 | } |
488 | GNUNET_free ((void*) argv); | 469 | GNUNET_free ((void *) argv); |
489 | return global_ret; | 470 | return global_ret; |
490 | } | 471 | } |
491 | 472 | ||