diff options
author | Schanzenbach, Martin <mschanzenbach@posteo.de> | 2017-01-04 12:46:29 +0100 |
---|---|---|
committer | Schanzenbach, Martin <mschanzenbach@posteo.de> | 2017-01-04 12:46:29 +0100 |
commit | 7122f35e2c00c29b1af31bdd294e93e6fcc84498 (patch) | |
tree | 2d352c38d227d6c44d525efdbfd7324e4cec5015 /src | |
parent | 3c1b722a8778b9f1f2b7564d3d2709f220e96547 (diff) | |
parent | 60c6dfd1fe22a01a3f7723e7e2bb18d52895c527 (diff) | |
download | gnunet-7122f35e2c00c29b1af31bdd294e93e6fcc84498.tar.gz gnunet-7122f35e2c00c29b1af31bdd294e93e6fcc84498.zip |
Merge remote-tracking branch 'origin/master' into credentials
Diffstat (limited to 'src')
-rw-r--r-- | src/gns/gnunet-gns-proxy.c | 3 | ||||
-rw-r--r-- | src/include/gnunet_nat_service.h | 9 | ||||
-rw-r--r-- | src/nat/gnunet-helper-nat-server.c | 115 | ||||
-rw-r--r-- | src/nat/gnunet-nat.c | 25 | ||||
-rw-r--r-- | src/nat/gnunet-service-nat.c | 210 | ||||
-rw-r--r-- | src/nat/gnunet-service-nat_helper.c | 80 | ||||
-rw-r--r-- | src/nat/gnunet-service-nat_helper.h | 2 | ||||
-rw-r--r-- | src/nat/nat.h | 24 | ||||
-rw-r--r-- | src/nat/nat_api.c | 31 |
9 files changed, 339 insertions, 160 deletions
diff --git a/src/gns/gnunet-gns-proxy.c b/src/gns/gnunet-gns-proxy.c index ef9c7bf62..3a38970a8 100644 --- a/src/gns/gnunet-gns-proxy.c +++ b/src/gns/gnunet-gns-proxy.c | |||
@@ -1761,7 +1761,8 @@ create_response (void *cls, | |||
1761 | { | 1761 | { |
1762 | 1762 | ||
1763 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1763 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1764 | "Processing %lu bytes UPLOAD\n", *upload_data_size); | 1764 | "Processing %u bytes UPLOAD\n", |
1765 | (unsigned int) *upload_data_size); | ||
1765 | 1766 | ||
1766 | /* FIXME: This must be set or a header with Transfer-Encoding: chunked. Else | 1767 | /* FIXME: This must be set or a header with Transfer-Encoding: chunked. Else |
1767 | * upload callback is not called! | 1768 | * upload callback is not called! |
diff --git a/src/include/gnunet_nat_service.h b/src/include/gnunet_nat_service.h index 4df17b531..1620c9433 100644 --- a/src/include/gnunet_nat_service.h +++ b/src/include/gnunet_nat_service.h | |||
@@ -155,15 +155,11 @@ typedef void | |||
155 | * reversal. | 155 | * reversal. |
156 | * | 156 | * |
157 | * @param cls closure | 157 | * @param cls closure |
158 | * @param local_addr address where we received the request | ||
159 | * @param local_addrlen actual length of the @a local_addr | ||
160 | * @param remote_addr public IP address of the other peer | 158 | * @param remote_addr public IP address of the other peer |
161 | * @param remote_addrlen actual length of the @a remote_addr | 159 | * @param remote_addrlen actual length of the @a remote_addr |
162 | */ | 160 | */ |
163 | typedef void | 161 | typedef void |
164 | (*GNUNET_NAT_ReversalCallback) (void *cls, | 162 | (*GNUNET_NAT_ReversalCallback) (void *cls, |
165 | const struct sockaddr *local_addr, | ||
166 | socklen_t local_addrlen, | ||
167 | const struct sockaddr *remote_addr, | 163 | const struct sockaddr *remote_addr, |
168 | socklen_t remote_addrlen); | 164 | socklen_t remote_addrlen); |
169 | 165 | ||
@@ -184,8 +180,7 @@ struct GNUNET_NAT_Handle; | |||
184 | * | 180 | * |
185 | * @param cfg configuration to use | 181 | * @param cfg configuration to use |
186 | * @param proto protocol this is about, IPPROTO_TCP or IPPROTO_UDP | 182 | * @param proto protocol this is about, IPPROTO_TCP or IPPROTO_UDP |
187 | * @param adv_port advertised port (port we are either bound to or that our OS | 183 | * @param hole_external hostname and port of manually punched hole in NAT, otherwise NULL (or empty string) |
188 | * locally performs redirection from to our bound port). | ||
189 | * @param num_addrs number of addresses in @a addrs | 184 | * @param num_addrs number of addresses in @a addrs |
190 | * @param addrs list of local addresses packets should be redirected to | 185 | * @param addrs list of local addresses packets should be redirected to |
191 | * @param addrlens actual lengths of the addresses in @a addrs | 186 | * @param addrlens actual lengths of the addresses in @a addrs |
@@ -198,7 +193,7 @@ struct GNUNET_NAT_Handle; | |||
198 | struct GNUNET_NAT_Handle * | 193 | struct GNUNET_NAT_Handle * |
199 | GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, | 194 | GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, |
200 | uint8_t proto, | 195 | uint8_t proto, |
201 | uint16_t adv_port, | 196 | const char *hole_external, |
202 | unsigned int num_addrs, | 197 | unsigned int num_addrs, |
203 | const struct sockaddr **addrs, | 198 | const struct sockaddr **addrs, |
204 | const socklen_t *addrlens, | 199 | const socklen_t *addrlens, |
diff --git a/src/nat/gnunet-helper-nat-server.c b/src/nat/gnunet-helper-nat-server.c index 8c3df749d..ef8e97482 100644 --- a/src/nat/gnunet-helper-nat-server.c +++ b/src/nat/gnunet-helper-nat-server.c | |||
@@ -264,8 +264,11 @@ send_icmp_echo (const struct in_addr *my_ip) | |||
264 | ip_pkt.src_ip = my_ip->s_addr; | 264 | ip_pkt.src_ip = my_ip->s_addr; |
265 | ip_pkt.dst_ip = dummy.s_addr; | 265 | ip_pkt.dst_ip = dummy.s_addr; |
266 | ip_pkt.checksum = | 266 | ip_pkt.checksum = |
267 | htons (calc_checksum ((uint16_t *) & ip_pkt, sizeof (struct ip_header))); | 267 | htons (calc_checksum ((uint16_t *) & ip_pkt, |
268 | memcpy (&packet[off], &ip_pkt, sizeof (struct ip_header)); | 268 | sizeof (struct ip_header))); |
269 | memcpy (&packet[off], | ||
270 | &ip_pkt, | ||
271 | sizeof (struct ip_header)); | ||
269 | off += sizeof (struct ip_header); | 272 | off += sizeof (struct ip_header); |
270 | 273 | ||
271 | icmp_echo.type = ICMP_ECHO; | 274 | icmp_echo.type = ICMP_ECHO; |
@@ -273,9 +276,12 @@ send_icmp_echo (const struct in_addr *my_ip) | |||
273 | icmp_echo.checksum = 0; | 276 | icmp_echo.checksum = 0; |
274 | icmp_echo.reserved = 0; | 277 | icmp_echo.reserved = 0; |
275 | icmp_echo.checksum = | 278 | icmp_echo.checksum = |
276 | htons (calc_checksum | 279 | htons (calc_checksum |
277 | ((uint16_t *) & icmp_echo, sizeof (struct icmp_echo_header))); | 280 | ((uint16_t *) & icmp_echo, |
278 | memcpy (&packet[off], &icmp_echo, sizeof (struct icmp_echo_header)); | 281 | sizeof (struct icmp_echo_header))); |
282 | memcpy (&packet[off], | ||
283 | &icmp_echo, | ||
284 | sizeof (struct icmp_echo_header)); | ||
279 | off += sizeof (struct icmp_echo_header); | 285 | off += sizeof (struct icmp_echo_header); |
280 | 286 | ||
281 | memset (&dst, 0, sizeof (dst)); | 287 | memset (&dst, 0, sizeof (dst)); |
@@ -284,17 +290,24 @@ send_icmp_echo (const struct in_addr *my_ip) | |||
284 | dst.sin_len = sizeof (struct sockaddr_in); | 290 | dst.sin_len = sizeof (struct sockaddr_in); |
285 | #endif | 291 | #endif |
286 | dst.sin_addr = dummy; | 292 | dst.sin_addr = dummy; |
287 | err = | 293 | err = sendto (rawsock, |
288 | sendto (rawsock, packet, off, 0, (struct sockaddr *) &dst, sizeof (dst)); | 294 | packet, |
295 | off, | ||
296 | 0, | ||
297 | (struct sockaddr *) &dst, | ||
298 | sizeof (dst)); | ||
289 | if (err < 0) | 299 | if (err < 0) |
290 | { | 300 | { |
291 | #if VERBOSE | 301 | #if VERBOSE |
292 | fprintf (stderr, "sendto failed: %s\n", strerror (errno)); | 302 | fprintf (stderr, |
303 | "sendto failed: %s\n", | ||
304 | strerror (errno)); | ||
293 | #endif | 305 | #endif |
294 | } | 306 | } |
295 | else if (sizeof (packet) != err) | 307 | else if (sizeof (packet) != err) |
296 | { | 308 | { |
297 | fprintf (stderr, "Error: partial send of ICMP message\n"); | 309 | fprintf (stderr, |
310 | "Error: partial send of ICMP message\n"); | ||
298 | } | 311 | } |
299 | } | 312 | } |
300 | 313 | ||
@@ -315,16 +328,24 @@ send_udp () | |||
315 | #endif | 328 | #endif |
316 | dst.sin_addr = dummy; | 329 | dst.sin_addr = dummy; |
317 | dst.sin_port = htons (NAT_TRAV_PORT); | 330 | dst.sin_port = htons (NAT_TRAV_PORT); |
318 | err = sendto (udpsock, NULL, 0, 0, (struct sockaddr *) &dst, sizeof (dst)); | 331 | err = sendto (udpsock, |
332 | NULL, | ||
333 | 0, | ||
334 | 0, | ||
335 | (struct sockaddr *) &dst, | ||
336 | sizeof (dst)); | ||
319 | if (err < 0) | 337 | if (err < 0) |
320 | { | 338 | { |
321 | #if VERBOSE | 339 | #if VERBOSE |
322 | fprintf (stderr, "sendto failed: %s\n", strerror (errno)); | 340 | fprintf (stderr, |
341 | "sendto failed: %s\n", | ||
342 | strerror (errno)); | ||
323 | #endif | 343 | #endif |
324 | } | 344 | } |
325 | else if (0 != err) | 345 | else if (0 != err) |
326 | { | 346 | { |
327 | fprintf (stderr, "Error: partial send of ICMP message\n"); | 347 | fprintf (stderr, |
348 | "Error: partial send of ICMP message\n"); | ||
328 | } | 349 | } |
329 | } | 350 | } |
330 | 351 | ||
@@ -348,11 +369,15 @@ process_icmp_response () | |||
348 | have = read (icmpsock, buf, sizeof (buf)); | 369 | have = read (icmpsock, buf, sizeof (buf)); |
349 | if (-1 == have) | 370 | if (-1 == have) |
350 | { | 371 | { |
351 | fprintf (stderr, "Error reading raw socket: %s\n", strerror (errno)); | 372 | fprintf (stderr, |
373 | "Error reading raw socket: %s\n", | ||
374 | strerror (errno)); | ||
352 | return; | 375 | return; |
353 | } | 376 | } |
354 | #if VERBOSE | 377 | #if VERBOSE |
355 | fprintf (stderr, "Received message of %u bytes\n", (unsigned int) have); | 378 | fprintf (stderr, |
379 | "Received message of %u bytes\n", | ||
380 | (unsigned int) have); | ||
356 | #endif | 381 | #endif |
357 | if (have < | 382 | if (have < |
358 | (ssize_t) (sizeof (struct ip_header) + | 383 | (ssize_t) (sizeof (struct ip_header) + |
@@ -433,15 +458,27 @@ setup_raw_socket () | |||
433 | const int one = 1; | 458 | const int one = 1; |
434 | 459 | ||
435 | if (-1 == | 460 | if (-1 == |
436 | setsockopt (rawsock, SOL_SOCKET, SO_BROADCAST, (char *) &one, sizeof (one))) | 461 | setsockopt (rawsock, |
462 | SOL_SOCKET, | ||
463 | SO_BROADCAST, | ||
464 | (char *) &one, | ||
465 | sizeof (one))) | ||
437 | { | 466 | { |
438 | fprintf (stderr, "setsockopt failed: %s\n", strerror (errno)); | 467 | fprintf (stderr, |
468 | "setsockopt failed: %s\n", | ||
469 | strerror (errno)); | ||
439 | return -1; | 470 | return -1; |
440 | } | 471 | } |
441 | if (-1 == | 472 | if (-1 == |
442 | setsockopt (rawsock, IPPROTO_IP, IP_HDRINCL, (char *) &one, sizeof (one))) | 473 | setsockopt (rawsock, |
474 | IPPROTO_IP, | ||
475 | IP_HDRINCL, | ||
476 | (char *) &one, | ||
477 | sizeof (one))) | ||
443 | { | 478 | { |
444 | fprintf (stderr, "setsockopt failed: %s\n", strerror (errno)); | 479 | fprintf (stderr, |
480 | "setsockopt failed: %s\n", | ||
481 | strerror (errno)); | ||
445 | return -1; | 482 | return -1; |
446 | } | 483 | } |
447 | return 0; | 484 | return 0; |
@@ -492,7 +529,8 @@ make_udp_socket (const struct in_addr *my_ip) | |||
492 | 529 | ||
493 | 530 | ||
494 | int | 531 | int |
495 | main (int argc, char *const *argv) | 532 | main (int argc, |
533 | char *const *argv) | ||
496 | { | 534 | { |
497 | struct in_addr external; | 535 | struct in_addr external; |
498 | fd_set rs; | 536 | fd_set rs; |
@@ -504,11 +542,15 @@ main (int argc, char *const *argv) | |||
504 | int global_ret; | 542 | int global_ret; |
505 | 543 | ||
506 | /* Create an ICMP raw socket for reading (we'll check errors later) */ | 544 | /* Create an ICMP raw socket for reading (we'll check errors later) */ |
507 | icmpsock = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP); | 545 | icmpsock = socket (AF_INET, |
546 | SOCK_RAW, | ||
547 | IPPROTO_ICMP); | ||
508 | icmp_eno = errno; | 548 | icmp_eno = errno; |
509 | 549 | ||
510 | /* Create an (ICMP) raw socket for writing (we'll check errors later) */ | 550 | /* Create an (ICMP) raw socket for writing (we'll check errors later) */ |
511 | rawsock = socket (AF_INET, SOCK_RAW, IPPROTO_RAW); | 551 | rawsock = socket (AF_INET, |
552 | SOCK_RAW, | ||
553 | IPPROTO_RAW); | ||
512 | raw_eno = errno; | 554 | raw_eno = errno; |
513 | udpsock = -1; | 555 | udpsock = -1; |
514 | 556 | ||
@@ -517,14 +559,18 @@ main (int argc, char *const *argv) | |||
517 | #ifdef HAVE_SETRESUID | 559 | #ifdef HAVE_SETRESUID |
518 | if (0 != setresuid (uid, uid, uid)) | 560 | if (0 != setresuid (uid, uid, uid)) |
519 | { | 561 | { |
520 | fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno)); | 562 | fprintf (stderr, |
563 | "Failed to setresuid: %s\n", | ||
564 | strerror (errno)); | ||
521 | global_ret = 1; | 565 | global_ret = 1; |
522 | goto error_exit; | 566 | goto error_exit; |
523 | } | 567 | } |
524 | #else | 568 | #else |
525 | if (0 != (setuid (uid) | seteuid (uid))) | 569 | if (0 != (setuid (uid) | seteuid (uid))) |
526 | { | 570 | { |
527 | fprintf (stderr, "Failed to setuid: %s\n", strerror (errno)); | 571 | fprintf (stderr, |
572 | "Failed to setuid: %s\n", | ||
573 | strerror (errno)); | ||
528 | global_ret = 2; | 574 | global_ret = 2; |
529 | goto error_exit; | 575 | goto error_exit; |
530 | } | 576 | } |
@@ -540,13 +586,16 @@ main (int argc, char *const *argv) | |||
540 | } | 586 | } |
541 | if (1 != inet_pton (AF_INET, argv[1], &external)) | 587 | if (1 != inet_pton (AF_INET, argv[1], &external)) |
542 | { | 588 | { |
543 | fprintf (stderr, "Error parsing IPv4 address: %s\n", strerror (errno)); | 589 | fprintf (stderr, |
590 | "Error parsing IPv4 address: %s\n", | ||
591 | strerror (errno)); | ||
544 | global_ret = 4; | 592 | global_ret = 4; |
545 | goto error_exit; | 593 | goto error_exit; |
546 | } | 594 | } |
547 | if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy)) | 595 | if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy)) |
548 | { | 596 | { |
549 | fprintf (stderr, "Internal error converting dummy IP to binary.\n"); | 597 | fprintf (stderr, |
598 | "Internal error converting dummy IP to binary.\n"); | ||
550 | global_ret = 5; | 599 | global_ret = 5; |
551 | goto error_exit; | 600 | goto error_exit; |
552 | } | 601 | } |
@@ -554,7 +603,9 @@ main (int argc, char *const *argv) | |||
554 | /* error checking icmpsock */ | 603 | /* error checking icmpsock */ |
555 | if (-1 == icmpsock) | 604 | if (-1 == icmpsock) |
556 | { | 605 | { |
557 | fprintf (stderr, "Error opening RAW socket: %s\n", strerror (icmp_eno)); | 606 | fprintf (stderr, |
607 | "Error opening RAW socket: %s\n", | ||
608 | strerror (icmp_eno)); | ||
558 | global_ret = 6; | 609 | global_ret = 6; |
559 | goto error_exit; | 610 | goto error_exit; |
560 | } | 611 | } |
@@ -562,7 +613,9 @@ main (int argc, char *const *argv) | |||
562 | { | 613 | { |
563 | /* this could happen if we were started with a large number of already-open | 614 | /* this could happen if we were started with a large number of already-open |
564 | file descriptors... */ | 615 | file descriptors... */ |
565 | fprintf (stderr, "Socket number too large (%d > %u)\n", icmpsock, | 616 | fprintf (stderr, |
617 | "Socket number too large (%d > %u)\n", | ||
618 | icmpsock, | ||
566 | (unsigned int) FD_SETSIZE); | 619 | (unsigned int) FD_SETSIZE); |
567 | global_ret = 7; | 620 | global_ret = 7; |
568 | goto error_exit; | 621 | goto error_exit; |
@@ -571,7 +624,9 @@ main (int argc, char *const *argv) | |||
571 | /* error checking rawsock */ | 624 | /* error checking rawsock */ |
572 | if (-1 == rawsock) | 625 | if (-1 == rawsock) |
573 | { | 626 | { |
574 | fprintf (stderr, "Error opening RAW socket: %s\n", strerror (raw_eno)); | 627 | fprintf (stderr, |
628 | "Error opening RAW socket: %s\n", | ||
629 | strerror (raw_eno)); | ||
575 | global_ret = 8; | 630 | global_ret = 8; |
576 | goto error_exit; | 631 | goto error_exit; |
577 | } | 632 | } |
@@ -601,7 +656,9 @@ main (int argc, char *const *argv) | |||
601 | { | 656 | { |
602 | if (errno == EINTR) | 657 | if (errno == EINTR) |
603 | continue; | 658 | continue; |
604 | fprintf (stderr, "select failed: %s\n", strerror (errno)); | 659 | fprintf (stderr, |
660 | "select failed: %s\n", | ||
661 | strerror (errno)); | ||
605 | break; | 662 | break; |
606 | } | 663 | } |
607 | if (1 == getppid ()) /* Check the parent process id, if 1 the parent has died, so we should die too */ | 664 | if (1 == getppid ()) /* Check the parent process id, if 1 the parent has died, so we should die too */ |
diff --git a/src/nat/gnunet-nat.c b/src/nat/gnunet-nat.c index 4d0ed5723..81e4549b5 100644 --- a/src/nat/gnunet-nat.c +++ b/src/nat/gnunet-nat.c | |||
@@ -39,9 +39,10 @@ static int global_ret; | |||
39 | static struct GNUNET_NAT_AutoHandle *ah; | 39 | static struct GNUNET_NAT_AutoHandle *ah; |
40 | 40 | ||
41 | /** | 41 | /** |
42 | * Port we advertise. | 42 | * External hostname and port, if user manually punched |
43 | * the NAT. | ||
43 | */ | 44 | */ |
44 | static unsigned int adv_port; | 45 | static char *hole_external; |
45 | 46 | ||
46 | /** | 47 | /** |
47 | * Flag set to 1 if we use IPPROTO_UDP. | 48 | * Flag set to 1 if we use IPPROTO_UDP. |
@@ -338,15 +339,11 @@ address_cb (void *cls, | |||
338 | * reversal. | 339 | * reversal. |
339 | * | 340 | * |
340 | * @param cls closure, NULL | 341 | * @param cls closure, NULL |
341 | * @param local_addr address where we received the request | ||
342 | * @param local_addrlen actual length of the @a local_addr | ||
343 | * @param remote_addr public IP address of the other peer | 342 | * @param remote_addr public IP address of the other peer |
344 | * @param remote_addrlen actual length of the @a remote_addr | 343 | * @param remote_addrlen actual length of the @a remote_addr |
345 | */ | 344 | */ |
346 | static void | 345 | static void |
347 | reversal_cb (void *cls, | 346 | reversal_cb (void *cls, |
348 | const struct sockaddr *local_addr, | ||
349 | socklen_t local_addrlen, | ||
350 | const struct sockaddr *remote_addr, | 347 | const struct sockaddr *remote_addr, |
351 | socklen_t remote_addrlen) | 348 | socklen_t remote_addrlen) |
352 | { | 349 | { |
@@ -572,7 +569,7 @@ run (void *cls, | |||
572 | { | 569 | { |
573 | nh = GNUNET_NAT_register (c, | 570 | nh = GNUNET_NAT_register (c, |
574 | proto, | 571 | proto, |
575 | (uint16_t) adv_port, | 572 | hole_external, |
576 | 1, | 573 | 1, |
577 | (const struct sockaddr **) &local_sa, | 574 | (const struct sockaddr **) &local_sa, |
578 | &local_len, | 575 | &local_len, |
@@ -580,6 +577,14 @@ run (void *cls, | |||
580 | (listen_reversal) ? &reversal_cb : NULL, | 577 | (listen_reversal) ? &reversal_cb : NULL, |
581 | NULL); | 578 | NULL); |
582 | } | 579 | } |
580 | else if (listen_reversal) | ||
581 | { | ||
582 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, | ||
583 | "Use of `-W` only effective in combination with `-i`\n"); | ||
584 | global_ret = 1; | ||
585 | GNUNET_SCHEDULER_shutdown (); | ||
586 | return; | ||
587 | } | ||
583 | 588 | ||
584 | if (NULL != remote_addr) | 589 | if (NULL != remote_addr) |
585 | { | 590 | { |
@@ -693,9 +698,9 @@ main (int argc, | |||
693 | {'r', "remote", "ADDRESS", | 698 | {'r', "remote", "ADDRESS", |
694 | gettext_noop ("which remote IP and port should be asked for connection reversal"), | 699 | gettext_noop ("which remote IP and port should be asked for connection reversal"), |
695 | GNUNET_YES, &GNUNET_GETOPT_set_string, &remote_addr }, | 700 | GNUNET_YES, &GNUNET_GETOPT_set_string, &remote_addr }, |
696 | {'p', "port", NULL, | 701 | {'p', "punched", NULL, |
697 | gettext_noop ("port to use to advertise"), | 702 | gettext_noop ("external hostname and port of NAT, if punched manually; use AUTO for hostname for automatic determination of the external IP"), |
698 | GNUNET_YES, &GNUNET_GETOPT_set_uint, &adv_port }, | 703 | GNUNET_YES, &GNUNET_GETOPT_set_string, &hole_external }, |
699 | {'s', "stun", NULL, | 704 | {'s', "stun", NULL, |
700 | gettext_noop ("enable STUN processing"), | 705 | gettext_noop ("enable STUN processing"), |
701 | GNUNET_NO, &GNUNET_GETOPT_set_one, &do_stun }, | 706 | GNUNET_NO, &GNUNET_GETOPT_set_one, &do_stun }, |
diff --git a/src/nat/gnunet-service-nat.c b/src/nat/gnunet-service-nat.c index 762175437..e29f37108 100644 --- a/src/nat/gnunet-service-nat.c +++ b/src/nat/gnunet-service-nat.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2016 GNUnet e.V. | 3 | Copyright (C) 2016, 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 |
@@ -28,9 +28,12 @@ | |||
28 | * knowledge about the local network topology. | 28 | * knowledge about the local network topology. |
29 | * | 29 | * |
30 | * TODO: | 30 | * TODO: |
31 | * - test ICMP based NAT traversal | 31 | * - test and document (!) ICMP based NAT traversal |
32 | * - implement manual hole punching support (incl. DNS | ||
33 | * lookup for DynDNS setups!) | ||
32 | * - implement "more" autoconfig: | 34 | * - implement "more" autoconfig: |
33 | * re-work gnunet-nat-server & integrate! | 35 | * re-work gnunet-nat-server & integrate! |
36 | * + test manually punched NAT (how?) | ||
34 | * - implement & test STUN processing to classify NAT; | 37 | * - implement & test STUN processing to classify NAT; |
35 | * basically, open port & try different methods. | 38 | * basically, open port & try different methods. |
36 | * - implement NEW logic for external IP detection | 39 | * - implement NEW logic for external IP detection |
@@ -129,6 +132,16 @@ struct ClientHandle | |||
129 | * Array of addresses used by the service. | 132 | * Array of addresses used by the service. |
130 | */ | 133 | */ |
131 | struct ClientAddress *caddrs; | 134 | struct ClientAddress *caddrs; |
135 | |||
136 | /** | ||
137 | * External DNS name and port given by user due to manual | ||
138 | * hole punching. Special DNS name 'AUTO' is used to indicate | ||
139 | * desire for automatic determination of the external IP | ||
140 | * (instead of DNS or manual configuration, i.e. to be used | ||
141 | * if the IP keeps changing and we have no DynDNS, but we do | ||
142 | * have a hole punched). | ||
143 | */ | ||
144 | char *hole_external; | ||
132 | 145 | ||
133 | /** | 146 | /** |
134 | * What does this client care about? | 147 | * What does this client care about? |
@@ -141,12 +154,6 @@ struct ClientHandle | |||
141 | int natted_address; | 154 | int natted_address; |
142 | 155 | ||
143 | /** | 156 | /** |
144 | * Port we would like as we are configured to use this one for | ||
145 | * advertising (in addition to the one we are binding to). | ||
146 | */ | ||
147 | uint16_t adv_port; | ||
148 | |||
149 | /** | ||
150 | * Number of addresses that this service is bound to. | 157 | * Number of addresses that this service is bound to. |
151 | * Length of the @e caddrs array. | 158 | * Length of the @e caddrs array. |
152 | */ | 159 | */ |
@@ -176,6 +183,12 @@ struct LocalAddressList | |||
176 | struct LocalAddressList *prev; | 183 | struct LocalAddressList *prev; |
177 | 184 | ||
178 | /** | 185 | /** |
186 | * Context for a gnunet-helper-nat-server used to listen | ||
187 | * for ICMP messages to this client for connection reversal. | ||
188 | */ | ||
189 | struct HelperContext *hc; | ||
190 | |||
191 | /** | ||
179 | * The address itself (i.e. `struct sockaddr_in` or `struct | 192 | * The address itself (i.e. `struct sockaddr_in` or `struct |
180 | * sockaddr_in6`, in the respective byte order). | 193 | * sockaddr_in6`, in the respective byte order). |
181 | */ | 194 | */ |
@@ -383,6 +396,31 @@ static struct in_addr mini_external_ipv4; | |||
383 | 396 | ||
384 | 397 | ||
385 | /** | 398 | /** |
399 | * Remove and free an entry from the #lal_head DLL. | ||
400 | * | ||
401 | * @param lal entry to free | ||
402 | */ | ||
403 | static void | ||
404 | free_lal (struct LocalAddressList *lal) | ||
405 | { | ||
406 | GNUNET_CONTAINER_DLL_remove (lal_head, | ||
407 | lal_tail, | ||
408 | lal); | ||
409 | if (NULL != lal->hc) | ||
410 | { | ||
411 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, | ||
412 | "Lost NATed local address %s, stopping NAT server\n", | ||
413 | GNUNET_a2s ((const struct sockaddr *) &lal->addr, | ||
414 | sizeof (struct sockaddr_in))); | ||
415 | |||
416 | GN_stop_gnunet_nat_server_ (lal->hc); | ||
417 | lal->hc = NULL; | ||
418 | } | ||
419 | GNUNET_free (lal); | ||
420 | } | ||
421 | |||
422 | |||
423 | /** | ||
386 | * Free the DLL starting at #lal_head. | 424 | * Free the DLL starting at #lal_head. |
387 | */ | 425 | */ |
388 | static void | 426 | static void |
@@ -391,12 +429,7 @@ destroy_lal () | |||
391 | struct LocalAddressList *lal; | 429 | struct LocalAddressList *lal; |
392 | 430 | ||
393 | while (NULL != (lal = lal_head)) | 431 | while (NULL != (lal = lal_head)) |
394 | { | 432 | free_lal (lal); |
395 | GNUNET_CONTAINER_DLL_remove (lal_head, | ||
396 | lal_tail, | ||
397 | lal); | ||
398 | GNUNET_free (lal); | ||
399 | } | ||
400 | } | 433 | } |
401 | 434 | ||
402 | 435 | ||
@@ -448,7 +481,14 @@ check_register (void *cls, | |||
448 | GNUNET_break (0); | 481 | GNUNET_break (0); |
449 | return GNUNET_SYSERR; | 482 | return GNUNET_SYSERR; |
450 | } | 483 | } |
451 | } | 484 | off += alen; |
485 | left -= alen; | ||
486 | } | ||
487 | if (left != ntohs (message->hole_external_len)) | ||
488 | { | ||
489 | GNUNET_break (0); | ||
490 | return GNUNET_SYSERR; | ||
491 | } | ||
452 | return GNUNET_OK; | 492 | return GNUNET_OK; |
453 | } | 493 | } |
454 | 494 | ||
@@ -718,10 +758,12 @@ check_notify_client (struct LocalAddressList *delta, | |||
718 | GNUNET_memcpy (&v4, | 758 | GNUNET_memcpy (&v4, |
719 | &delta->addr, | 759 | &delta->addr, |
720 | alen); | 760 | alen); |
761 | |||
762 | /* Check for client notifications */ | ||
721 | for (unsigned int i=0;i<ch->num_caddrs;i++) | 763 | for (unsigned int i=0;i<ch->num_caddrs;i++) |
722 | { | 764 | { |
723 | const struct sockaddr_in *c4; | 765 | const struct sockaddr_in *c4; |
724 | 766 | ||
725 | if (AF_INET != ch->caddrs[i].ss.ss_family) | 767 | if (AF_INET != ch->caddrs[i].ss.ss_family) |
726 | return; /* IPv4 not relevant */ | 768 | return; /* IPv4 not relevant */ |
727 | c4 = (const struct sockaddr_in *) &ch->caddrs[i].ss; | 769 | c4 = (const struct sockaddr_in *) &ch->caddrs[i].ss; |
@@ -857,40 +899,37 @@ check_notify_client_external_ipv4_change (const struct in_addr *v4, | |||
857 | int add) | 899 | int add) |
858 | { | 900 | { |
859 | struct sockaddr_in sa; | 901 | struct sockaddr_in sa; |
860 | uint16_t port; | 902 | int have_v4; |
861 | uint16_t bport; | ||
862 | 903 | ||
863 | /* (1) check if client cares. */ | 904 | /* (1) check if client cares. */ |
864 | if (! ch->natted_address) | 905 | if (! ch->natted_address) |
865 | return; | 906 | return; |
866 | if (0 == (GNUNET_NAT_RF_ADDRESSES & ch->flags)) | 907 | if (0 == (GNUNET_NAT_RF_ADDRESSES & ch->flags)) |
867 | return; | 908 | return; |
868 | bport = 0; | 909 | have_v4 = GNUNET_NO; |
869 | for (unsigned int i=0;i<ch->num_caddrs;i++) | 910 | for (unsigned int i=0;i<ch->num_caddrs;i++) |
870 | { | 911 | { |
871 | const struct sockaddr_storage *ss = &ch->caddrs[i].ss; | 912 | const struct sockaddr_storage *ss = &ch->caddrs[i].ss; |
872 | 913 | ||
873 | if (AF_INET != ss->ss_family) | 914 | if (AF_INET != ss->ss_family) |
874 | continue; | 915 | continue; |
875 | bport = ntohs (((const struct sockaddr_in *) ss)->sin_port); | 916 | have_v4 = GNUNET_YES; |
917 | break; | ||
876 | } | 918 | } |
877 | if (0 == bport) | 919 | if (GNUNET_NO == have_v4) |
878 | return; /* IPv6-only */ | 920 | return; /* IPv6-only */ |
879 | 921 | ||
880 | /* (2) figure out external port, build sockaddr */ | 922 | /* build address info */ |
881 | port = ch->adv_port; | ||
882 | if (0 == port) | ||
883 | port = bport; | ||
884 | memset (&sa, | 923 | memset (&sa, |
885 | 0, | 924 | 0, |
886 | sizeof (sa)); | 925 | sizeof (sa)); |
887 | sa.sin_family = AF_INET; | 926 | sa.sin_family = AF_INET; |
888 | sa.sin_addr = *v4; | 927 | sa.sin_addr = *v4; |
889 | sa.sin_port = htons (port); | 928 | sa.sin_port = htons (0); |
890 | 929 | ||
891 | /* (3) notify client of change */ | 930 | /* (3) notify client of change */ |
892 | notify_client (is_nat_v4 (v4) | 931 | notify_client (is_nat_v4 (v4) |
893 | ? GNUNET_NAT_AC_EXTERN | GNUNET_NAT_AC_LAN_PRIVATE | 932 | ? GNUNET_NAT_AC_EXTERN | GNUNET_NAT_AC_LAN |
894 | : GNUNET_NAT_AC_EXTERN | GNUNET_NAT_AC_GLOBAL, | 933 | : GNUNET_NAT_AC_EXTERN | GNUNET_NAT_AC_GLOBAL, |
895 | ch, | 934 | ch, |
896 | add, | 935 | add, |
@@ -1006,6 +1045,65 @@ run_external_ip (void *cls) | |||
1006 | 1045 | ||
1007 | 1046 | ||
1008 | /** | 1047 | /** |
1048 | * We got a connection reversal request from another peer. | ||
1049 | * Notify applicable clients. | ||
1050 | * | ||
1051 | * @param cls closure with the `struct LocalAddressList` | ||
1052 | * @param ra IP address of the peer who wants us to connect to it | ||
1053 | */ | ||
1054 | static void | ||
1055 | reversal_callback (void *cls, | ||
1056 | const struct sockaddr_in *ra) | ||
1057 | { | ||
1058 | struct LocalAddressList *lal = cls; | ||
1059 | const struct sockaddr_in *l4; | ||
1060 | |||
1061 | GNUNET_assert (AF_INET == lal->af); | ||
1062 | l4 = (const struct sockaddr_in *) &lal->addr; | ||
1063 | for (struct ClientHandle *ch = ch_head; | ||
1064 | NULL != ch; | ||
1065 | ch = ch->next) | ||
1066 | { | ||
1067 | struct GNUNET_NAT_ConnectionReversalRequestedMessage *crrm; | ||
1068 | struct GNUNET_MQ_Envelope *env; | ||
1069 | int match; | ||
1070 | |||
1071 | /* Check if client is in applicable range for ICMP NAT traversal | ||
1072 | for this local address */ | ||
1073 | if (! ch->natted_address) | ||
1074 | continue; | ||
1075 | match = GNUNET_NO; | ||
1076 | for (unsigned int i=0;i<ch->num_caddrs;i++) | ||
1077 | { | ||
1078 | struct ClientAddress *ca = &ch->caddrs[i]; | ||
1079 | const struct sockaddr_in *c4; | ||
1080 | |||
1081 | if (AF_INET != ca->ss.ss_family) | ||
1082 | continue; | ||
1083 | c4 = (const struct sockaddr_in *) &ca->ss; | ||
1084 | if ( (0 != c4->sin_addr.s_addr) && | ||
1085 | (l4->sin_addr.s_addr != c4->sin_addr.s_addr) ) | ||
1086 | continue; | ||
1087 | match = GNUNET_YES; | ||
1088 | break; | ||
1089 | } | ||
1090 | if (! match) | ||
1091 | continue; | ||
1092 | |||
1093 | /* Notify applicable client about connection reversal request */ | ||
1094 | env = GNUNET_MQ_msg_extra (crrm, | ||
1095 | sizeof (struct sockaddr_in), | ||
1096 | GNUNET_MESSAGE_TYPE_NAT_CONNECTION_REVERSAL_REQUESTED); | ||
1097 | GNUNET_memcpy (&crrm[1], | ||
1098 | ra, | ||
1099 | sizeof (struct sockaddr_in)); | ||
1100 | GNUNET_MQ_send (ch->mq, | ||
1101 | env); | ||
1102 | } | ||
1103 | } | ||
1104 | |||
1105 | |||
1106 | /** | ||
1009 | * Task we run periodically to scan for network interfaces. | 1107 | * Task we run periodically to scan for network interfaces. |
1010 | * | 1108 | * |
1011 | * @param cls NULL | 1109 | * @param cls NULL |
@@ -1016,6 +1114,7 @@ run_scan (void *cls) | |||
1016 | struct IfcProcContext ifc_ctx; | 1114 | struct IfcProcContext ifc_ctx; |
1017 | int found; | 1115 | int found; |
1018 | int have_nat; | 1116 | int have_nat; |
1117 | struct LocalAddressList *lnext; | ||
1019 | 1118 | ||
1020 | scan_task = GNUNET_SCHEDULER_add_delayed (SCAN_FREQ, | 1119 | scan_task = GNUNET_SCHEDULER_add_delayed (SCAN_FREQ, |
1021 | &run_scan, | 1120 | &run_scan, |
@@ -1028,8 +1127,9 @@ run_scan (void *cls) | |||
1028 | /* remove addresses that disappeared */ | 1127 | /* remove addresses that disappeared */ |
1029 | for (struct LocalAddressList *lal = lal_head; | 1128 | for (struct LocalAddressList *lal = lal_head; |
1030 | NULL != lal; | 1129 | NULL != lal; |
1031 | lal = lal->next) | 1130 | lal = lnext) |
1032 | { | 1131 | { |
1132 | lnext = lal->next; | ||
1033 | found = GNUNET_NO; | 1133 | found = GNUNET_NO; |
1034 | for (struct LocalAddressList *pos = ifc_ctx.lal_head; | 1134 | for (struct LocalAddressList *pos = ifc_ctx.lal_head; |
1035 | NULL != pos; | 1135 | NULL != pos; |
@@ -1041,18 +1141,23 @@ run_scan (void *cls) | |||
1041 | (AF_INET == lal->af) | 1141 | (AF_INET == lal->af) |
1042 | ? sizeof (struct sockaddr_in) | 1142 | ? sizeof (struct sockaddr_in) |
1043 | : sizeof (struct sockaddr_in6))) ) | 1143 | : sizeof (struct sockaddr_in6))) ) |
1144 | { | ||
1044 | found = GNUNET_YES; | 1145 | found = GNUNET_YES; |
1146 | } | ||
1045 | } | 1147 | } |
1046 | if (GNUNET_NO == found) | 1148 | if (GNUNET_NO == found) |
1149 | { | ||
1047 | notify_clients (lal, | 1150 | notify_clients (lal, |
1048 | GNUNET_NO); | 1151 | GNUNET_NO); |
1152 | free_lal (lal); | ||
1153 | } | ||
1049 | } | 1154 | } |
1050 | 1155 | ||
1051 | /* add addresses that appeared */ | 1156 | /* add addresses that appeared */ |
1052 | have_nat = GNUNET_NO; | 1157 | have_nat = GNUNET_NO; |
1053 | for (struct LocalAddressList *pos = ifc_ctx.lal_head; | 1158 | for (struct LocalAddressList *pos = ifc_ctx.lal_head; |
1054 | NULL != pos; | 1159 | NULL != pos; |
1055 | pos = pos->next) | 1160 | pos = ifc_ctx.lal_head) |
1056 | { | 1161 | { |
1057 | found = GNUNET_NO; | 1162 | found = GNUNET_NO; |
1058 | if (GNUNET_NAT_AC_LAN == (GNUNET_NAT_AC_LAN & pos->ac)) | 1163 | if (GNUNET_NAT_AC_LAN == (GNUNET_NAT_AC_LAN & pos->ac)) |
@@ -1069,9 +1174,35 @@ run_scan (void *cls) | |||
1069 | : sizeof (struct sockaddr_in6))) ) | 1174 | : sizeof (struct sockaddr_in6))) ) |
1070 | found = GNUNET_YES; | 1175 | found = GNUNET_YES; |
1071 | } | 1176 | } |
1072 | if (GNUNET_NO == found) | 1177 | GNUNET_CONTAINER_DLL_remove (ifc_ctx.lal_head, |
1178 | ifc_ctx.lal_tail, | ||
1179 | pos); | ||
1180 | if (GNUNET_YES == found) | ||
1181 | { | ||
1182 | GNUNET_free (pos); | ||
1183 | } | ||
1184 | else | ||
1185 | { | ||
1073 | notify_clients (pos, | 1186 | notify_clients (pos, |
1074 | GNUNET_YES); | 1187 | GNUNET_YES); |
1188 | GNUNET_CONTAINER_DLL_insert (lal_head, | ||
1189 | lal_tail, | ||
1190 | pos); | ||
1191 | if ( (AF_INET == pos->af) && | ||
1192 | (NULL == pos->hc) && | ||
1193 | (0 != (GNUNET_NAT_AC_LAN & pos->ac)) ) | ||
1194 | { | ||
1195 | const struct sockaddr_in *s4 | ||
1196 | = (const struct sockaddr_in *) &pos->addr; | ||
1197 | |||
1198 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, | ||
1199 | "Found NATed local address %s, starting NAT server\n", | ||
1200 | GNUNET_a2s ((void *) &pos->addr, sizeof (*s4))); | ||
1201 | pos->hc = GN_start_gnunet_nat_server_ (&s4->sin_addr, | ||
1202 | &reversal_callback, | ||
1203 | pos); | ||
1204 | } | ||
1205 | } | ||
1075 | } | 1206 | } |
1076 | if ( (GNUNET_YES == have_nat) && | 1207 | if ( (GNUNET_YES == have_nat) && |
1077 | (GNUNET_YES == enable_upnp) && | 1208 | (GNUNET_YES == enable_upnp) && |
@@ -1096,10 +1227,6 @@ run_scan (void *cls) | |||
1096 | probe_external_ip_op = NULL; | 1227 | probe_external_ip_op = NULL; |
1097 | } | 1228 | } |
1098 | } | 1229 | } |
1099 | |||
1100 | destroy_lal (); | ||
1101 | lal_head = ifc_ctx.lal_head; | ||
1102 | lal_tail = ifc_ctx.lal_tail; | ||
1103 | } | 1230 | } |
1104 | 1231 | ||
1105 | 1232 | ||
@@ -1164,12 +1291,12 @@ upnp_addr_change_cb (void *cls, | |||
1164 | { | 1291 | { |
1165 | case AF_INET: | 1292 | case AF_INET: |
1166 | ac = is_nat_v4 (&((const struct sockaddr_in *) addr)->sin_addr) | 1293 | ac = is_nat_v4 (&((const struct sockaddr_in *) addr)->sin_addr) |
1167 | ? GNUNET_NAT_AC_LAN_PRIVATE | 1294 | ? GNUNET_NAT_AC_LAN |
1168 | : GNUNET_NAT_AC_EXTERN; | 1295 | : GNUNET_NAT_AC_EXTERN; |
1169 | break; | 1296 | break; |
1170 | case AF_INET6: | 1297 | case AF_INET6: |
1171 | ac = is_nat_v6 (&((const struct sockaddr_in6 *) addr)->sin6_addr) | 1298 | ac = is_nat_v6 (&((const struct sockaddr_in6 *) addr)->sin6_addr) |
1172 | ? GNUNET_NAT_AC_LAN_PRIVATE | 1299 | ? GNUNET_NAT_AC_LAN |
1173 | : GNUNET_NAT_AC_EXTERN; | 1300 | : GNUNET_NAT_AC_EXTERN; |
1174 | break; | 1301 | break; |
1175 | default: | 1302 | default: |
@@ -1216,7 +1343,6 @@ handle_register (void *cls, | |||
1216 | "Received REGISTER message from client\n"); | 1343 | "Received REGISTER message from client\n"); |
1217 | ch->flags = message->flags; | 1344 | ch->flags = message->flags; |
1218 | ch->proto = message->proto; | 1345 | ch->proto = message->proto; |
1219 | ch->adv_port = ntohs (message->adv_port); | ||
1220 | ch->num_caddrs = ntohs (message->num_addrs); | 1346 | ch->num_caddrs = ntohs (message->num_addrs); |
1221 | ch->caddrs = GNUNET_new_array (ch->num_caddrs, | 1347 | ch->caddrs = GNUNET_new_array (ch->num_caddrs, |
1222 | struct ClientAddress); | 1348 | struct ClientAddress); |
@@ -1292,6 +1418,11 @@ handle_register (void *cls, | |||
1292 | 1418 | ||
1293 | off += alen; | 1419 | off += alen; |
1294 | } | 1420 | } |
1421 | |||
1422 | ch->hole_external | ||
1423 | = GNUNET_strndup (off, | ||
1424 | ntohs (message->hole_external_len)); | ||
1425 | |||
1295 | /* Actually send IP address list to client */ | 1426 | /* Actually send IP address list to client */ |
1296 | for (struct LocalAddressList *lal = lal_head; | 1427 | for (struct LocalAddressList *lal = lal_head; |
1297 | NULL != lal; | 1428 | NULL != lal; |
@@ -1363,7 +1494,7 @@ notify_clients_stun_change (const struct sockaddr_in *ip, | |||
1363 | if (! ch->natted_address) | 1494 | if (! ch->natted_address) |
1364 | continue; | 1495 | continue; |
1365 | v4 = *ip; | 1496 | v4 = *ip; |
1366 | v4.sin_port = htons (ch->adv_port); | 1497 | v4.sin_port = htons (0); |
1367 | env = GNUNET_MQ_msg_extra (msg, | 1498 | env = GNUNET_MQ_msg_extra (msg, |
1368 | sizeof (v4), | 1499 | sizeof (v4), |
1369 | GNUNET_MESSAGE_TYPE_NAT_ADDRESS_CHANGE); | 1500 | GNUNET_MESSAGE_TYPE_NAT_ADDRESS_CHANGE); |
@@ -2045,6 +2176,7 @@ client_disconnect_cb (void *cls, | |||
2045 | } | 2176 | } |
2046 | } | 2177 | } |
2047 | GNUNET_free_non_null (ch->caddrs); | 2178 | GNUNET_free_non_null (ch->caddrs); |
2179 | GNUNET_free (ch->hole_external); | ||
2048 | GNUNET_free (ch); | 2180 | GNUNET_free (ch); |
2049 | } | 2181 | } |
2050 | 2182 | ||
diff --git a/src/nat/gnunet-service-nat_helper.c b/src/nat/gnunet-service-nat_helper.c index 379603ae2..7e5051d65 100644 --- a/src/nat/gnunet-service-nat_helper.c +++ b/src/nat/gnunet-service-nat_helper.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include "gnunet_util_lib.h" | 28 | #include "gnunet_util_lib.h" |
29 | #include "gnunet-service-nat_helper.h" | 29 | #include "gnunet-service-nat_helper.h" |
30 | 30 | ||
31 | #define LOG(kind,...) GNUNET_log_from (kind, "nat", __VA_ARGS__) | ||
32 | 31 | ||
33 | /** | 32 | /** |
34 | * Information we keep per NAT helper process. | 33 | * Information we keep per NAT helper process. |
@@ -39,7 +38,7 @@ struct HelperContext | |||
39 | /** | 38 | /** |
40 | * IP address we pass to the NAT helper. | 39 | * IP address we pass to the NAT helper. |
41 | */ | 40 | */ |
42 | const char *internal_address; | 41 | struct in_addr internal_address; |
43 | 42 | ||
44 | /** | 43 | /** |
45 | * Function to call if we receive a reversal request. | 44 | * Function to call if we receive a reversal request. |
@@ -133,11 +132,11 @@ nat_server_read (void *cls) | |||
133 | sizeof (mybuf)); | 132 | sizeof (mybuf)); |
134 | if (bytes < 1) | 133 | if (bytes < 1) |
135 | { | 134 | { |
136 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 135 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
137 | "Finished reading from server stdout with code: %d\n", | 136 | "Finished reading from server stdout with code: %d\n", |
138 | bytes); | 137 | bytes); |
139 | if (0 != GNUNET_OS_process_kill (h->server_proc, | 138 | if (0 != GNUNET_OS_process_kill (h->server_proc, |
140 | - GNUNET_TERM_SIG)) | 139 | GNUNET_TERM_SIG)) |
141 | GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_WARNING, | 140 | GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_WARNING, |
142 | "nat", | 141 | "nat", |
143 | "kill"); | 142 | "kill"); |
@@ -183,10 +182,9 @@ nat_server_read (void *cls) | |||
183 | &sin_addr.sin_addr))) | 182 | &sin_addr.sin_addr))) |
184 | { | 183 | { |
185 | /* should we restart gnunet-helper-nat-server? */ | 184 | /* should we restart gnunet-helper-nat-server? */ |
186 | LOG (GNUNET_ERROR_TYPE_WARNING, | 185 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
187 | "nat", | 186 | _("gnunet-helper-nat-server generated malformed address `%s'\n"), |
188 | _("gnunet-helper-nat-server generated malformed address `%s'\n"), | 187 | mybuf); |
189 | mybuf); | ||
190 | h->server_read_task | 188 | h->server_read_task |
191 | = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | 189 | = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, |
192 | h->server_stdout_handle, | 190 | h->server_stdout_handle, |
@@ -195,10 +193,10 @@ nat_server_read (void *cls) | |||
195 | return; | 193 | return; |
196 | } | 194 | } |
197 | sin_addr.sin_port = htons ((uint16_t) port); | 195 | sin_addr.sin_port = htons ((uint16_t) port); |
198 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 196 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
199 | "gnunet-helper-nat-server read: %s:%d\n", | 197 | "gnunet-helper-nat-server read: %s:%d\n", |
200 | mybuf, | 198 | mybuf, |
201 | port); | 199 | port); |
202 | h->cb (h->cb_cls, | 200 | h->cb (h->cb_cls, |
203 | &sin_addr); | 201 | &sin_addr); |
204 | h->server_read_task | 202 | h->server_read_task |
@@ -220,6 +218,7 @@ restart_nat_server (void *cls) | |||
220 | { | 218 | { |
221 | struct HelperContext *h = cls; | 219 | struct HelperContext *h = cls; |
222 | char *binary; | 220 | char *binary; |
221 | char ia[INET_ADDRSTRLEN]; | ||
223 | 222 | ||
224 | h->server_read_task = NULL; | 223 | h->server_read_task = NULL; |
225 | h->server_stdout | 224 | h->server_stdout |
@@ -232,10 +231,15 @@ restart_nat_server (void *cls) | |||
232 | try_again (h); | 231 | try_again (h); |
233 | return; | 232 | return; |
234 | } | 233 | } |
235 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 234 | GNUNET_assert (NULL != |
236 | "Starting `%s' at `%s'\n", | 235 | inet_ntop (AF_INET, |
237 | "gnunet-helper-nat-server", | 236 | &h->internal_address, |
238 | h->internal_address); | 237 | ia, |
238 | sizeof (ia))); | ||
239 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
240 | "Starting `%s' at `%s'\n", | ||
241 | "gnunet-helper-nat-server", | ||
242 | ia); | ||
239 | /* Start the server process */ | 243 | /* Start the server process */ |
240 | binary | 244 | binary |
241 | = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-nat-server"); | 245 | = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-nat-server"); |
@@ -247,15 +251,14 @@ restart_nat_server (void *cls) | |||
247 | NULL, | 251 | NULL, |
248 | binary, | 252 | binary, |
249 | "gnunet-helper-nat-server", | 253 | "gnunet-helper-nat-server", |
250 | h->internal_address, | 254 | ia, |
251 | NULL); | 255 | NULL); |
252 | GNUNET_free (binary); | 256 | GNUNET_free (binary); |
253 | if (NULL == h->server_proc) | 257 | if (NULL == h->server_proc) |
254 | { | 258 | { |
255 | LOG (GNUNET_ERROR_TYPE_WARNING, | 259 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
256 | "nat", | 260 | _("Failed to start %s\n"), |
257 | _("Failed to start %s\n"), | 261 | "gnunet-helper-nat-server"); |
258 | "gnunet-helper-nat-server"); | ||
259 | GNUNET_DISK_pipe_close (h->server_stdout); | 262 | GNUNET_DISK_pipe_close (h->server_stdout); |
260 | h->server_stdout = NULL; | 263 | h->server_stdout = NULL; |
261 | try_again (h); | 264 | try_again (h); |
@@ -285,7 +288,7 @@ restart_nat_server (void *cls) | |||
285 | * @return NULL on error | 288 | * @return NULL on error |
286 | */ | 289 | */ |
287 | struct HelperContext * | 290 | struct HelperContext * |
288 | GN_start_gnunet_nat_server_ (const char *internal_address, | 291 | GN_start_gnunet_nat_server_ (const struct in_addr *internal_address, |
289 | GN_ReversalCallback cb, | 292 | GN_ReversalCallback cb, |
290 | void *cb_cls) | 293 | void *cb_cls) |
291 | { | 294 | { |
@@ -294,8 +297,8 @@ GN_start_gnunet_nat_server_ (const char *internal_address, | |||
294 | h = GNUNET_new (struct HelperContext); | 297 | h = GNUNET_new (struct HelperContext); |
295 | h->cb = cb; | 298 | h->cb = cb; |
296 | h->cb_cls = cb_cls; | 299 | h->cb_cls = cb_cls; |
297 | h->internal_address | 300 | h->internal_address = *internal_address; |
298 | = internal_address; | 301 | restart_nat_server (h); |
299 | if (NULL == h->server_stdout) | 302 | if (NULL == h->server_stdout) |
300 | { | 303 | { |
301 | GN_stop_gnunet_nat_server_ (h); | 304 | GN_stop_gnunet_nat_server_ (h); |
@@ -323,9 +326,8 @@ GN_stop_gnunet_nat_server_ (struct HelperContext *h) | |||
323 | { | 326 | { |
324 | if (0 != GNUNET_OS_process_kill (h->server_proc, | 327 | if (0 != GNUNET_OS_process_kill (h->server_proc, |
325 | GNUNET_TERM_SIG)) | 328 | GNUNET_TERM_SIG)) |
326 | GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_WARNING, | 329 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, |
327 | "nat", | 330 | "kill"); |
328 | "kill"); | ||
329 | GNUNET_OS_process_wait (h->server_proc); | 331 | GNUNET_OS_process_wait (h->server_proc); |
330 | GNUNET_OS_process_destroy (h->server_proc); | 332 | GNUNET_OS_process_destroy (h->server_proc); |
331 | h->server_proc = NULL; | 333 | h->server_proc = NULL; |
@@ -370,9 +372,8 @@ GN_request_connection_reversal (const struct in_addr *internal_address, | |||
370 | intv4, | 372 | intv4, |
371 | INET_ADDRSTRLEN)) | 373 | INET_ADDRSTRLEN)) |
372 | { | 374 | { |
373 | GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_WARNING, | 375 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, |
374 | "nat", | 376 | "inet_ntop"); |
375 | "inet_ntop"); | ||
376 | return GNUNET_SYSERR; | 377 | return GNUNET_SYSERR; |
377 | } | 378 | } |
378 | if (NULL == inet_ntop (AF_INET, | 379 | if (NULL == inet_ntop (AF_INET, |
@@ -380,20 +381,19 @@ GN_request_connection_reversal (const struct in_addr *internal_address, | |||
380 | remv4, | 381 | remv4, |
381 | INET_ADDRSTRLEN)) | 382 | INET_ADDRSTRLEN)) |
382 | { | 383 | { |
383 | GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_WARNING, | 384 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, |
384 | "nat", | 385 | "inet_ntop"); |
385 | "inet_ntop"); | ||
386 | return GNUNET_SYSERR; | 386 | return GNUNET_SYSERR; |
387 | } | 387 | } |
388 | GNUNET_snprintf (port_as_string, | 388 | GNUNET_snprintf (port_as_string, |
389 | sizeof (port_as_string), | 389 | sizeof (port_as_string), |
390 | "%d", | 390 | "%d", |
391 | internal_port); | 391 | internal_port); |
392 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 392 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
393 | _("Running gnunet-helper-nat-client %s %s %u\n"), | 393 | _("Running gnunet-helper-nat-client %s %s %u\n"), |
394 | intv4, | 394 | intv4, |
395 | remv4, | 395 | remv4, |
396 | internal_port); | 396 | internal_port); |
397 | binary | 397 | binary |
398 | = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-nat-client"); | 398 | = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-nat-client"); |
399 | proc | 399 | proc |
diff --git a/src/nat/gnunet-service-nat_helper.h b/src/nat/gnunet-service-nat_helper.h index d3f1a757c..026526b05 100644 --- a/src/nat/gnunet-service-nat_helper.h +++ b/src/nat/gnunet-service-nat_helper.h | |||
@@ -56,7 +56,7 @@ typedef void | |||
56 | * @return NULL on error | 56 | * @return NULL on error |
57 | */ | 57 | */ |
58 | struct HelperContext * | 58 | struct HelperContext * |
59 | GN_start_gnunet_nat_server_ (const char *internal_address, | 59 | GN_start_gnunet_nat_server_ (const struct in_addr *internal_address, |
60 | GN_ReversalCallback cb, | 60 | GN_ReversalCallback cb, |
61 | void *cb_cls); | 61 | void *cb_cls); |
62 | 62 | ||
diff --git a/src/nat/nat.h b/src/nat/nat.h index 3356b19ce..af418c7c2 100644 --- a/src/nat/nat.h +++ b/src/nat/nat.h | |||
@@ -110,10 +110,11 @@ struct GNUNET_NAT_RegisterMessage | |||
110 | uint8_t proto; | 110 | uint8_t proto; |
111 | 111 | ||
112 | /** | 112 | /** |
113 | * Port we would like as we are configured to use this one for | 113 | * Number of bytes in the string that follow which |
114 | * advertising (in addition to the one we are binding to). | 114 | * specify the hostname and port of a manually punched |
115 | * hole for this client. | ||
115 | */ | 116 | */ |
116 | uint16_t adv_port GNUNET_PACKED; | 117 | uint16_t hole_external_len GNUNET_PACKED; |
117 | 118 | ||
118 | /** | 119 | /** |
119 | * Number of addresses that this service is bound to that follow. | 120 | * Number of addresses that this service is bound to that follow. |
@@ -124,6 +125,9 @@ struct GNUNET_NAT_RegisterMessage | |||
124 | 125 | ||
125 | /* Followed by @e num_addrs addresses of type 'struct | 126 | /* Followed by @e num_addrs addresses of type 'struct |
126 | sockaddr' */ | 127 | sockaddr' */ |
128 | |||
129 | /* Followed by @e hole_external_len bytes giving a hostname | ||
130 | and port */ | ||
127 | 131 | ||
128 | }; | 132 | }; |
129 | 133 | ||
@@ -191,19 +195,7 @@ struct GNUNET_NAT_ConnectionReversalRequestedMessage | |||
191 | */ | 195 | */ |
192 | struct GNUNET_MessageHeader header; | 196 | struct GNUNET_MessageHeader header; |
193 | 197 | ||
194 | /** | 198 | /* followed by a `struct sockaddr_in` */ |
195 | * Size of the local address where we received the request, in NBO. | ||
196 | */ | ||
197 | uint16_t local_addr_size; | ||
198 | |||
199 | /** | ||
200 | * Size of the remote address making the request, in NBO. | ||
201 | */ | ||
202 | uint16_t remote_addr_size; | ||
203 | |||
204 | /* followed by a `struct sockaddr` of @e local_addr_size bytes */ | ||
205 | |||
206 | /* followed by a `struct sockaddr` of @e remote_addr_size bytes */ | ||
207 | 199 | ||
208 | }; | 200 | }; |
209 | 201 | ||
diff --git a/src/nat/nat_api.c b/src/nat/nat_api.c index 481bc6fde..e4dfc1629 100644 --- a/src/nat/nat_api.c +++ b/src/nat/nat_api.c | |||
@@ -176,14 +176,7 @@ check_connection_reversal_request (void *cls, | |||
176 | { | 176 | { |
177 | if (ntohs (crm->header.size) != | 177 | if (ntohs (crm->header.size) != |
178 | sizeof (*crm) + | 178 | sizeof (*crm) + |
179 | ntohs (crm->local_addr_size) + | 179 | sizeof (struct sockaddr_in) ) |
180 | ntohs (crm->remote_addr_size) ) | ||
181 | { | ||
182 | GNUNET_break (0); | ||
183 | return GNUNET_SYSERR; | ||
184 | } | ||
185 | if ( (sizeof (struct sockaddr_in) != ntohs (crm->local_addr_size)) || | ||
186 | (sizeof (struct sockaddr_in) != ntohs (crm->remote_addr_size)) ) | ||
187 | { | 180 | { |
188 | GNUNET_break (0); | 181 | GNUNET_break (0); |
189 | return GNUNET_SYSERR; | 182 | return GNUNET_SYSERR; |
@@ -203,13 +196,9 @@ handle_connection_reversal_request (void *cls, | |||
203 | const struct GNUNET_NAT_ConnectionReversalRequestedMessage *crm) | 196 | const struct GNUNET_NAT_ConnectionReversalRequestedMessage *crm) |
204 | { | 197 | { |
205 | struct GNUNET_NAT_Handle *nh = cls; | 198 | struct GNUNET_NAT_Handle *nh = cls; |
206 | const struct sockaddr_in *local_sa = (const struct sockaddr_in *) &crm[1]; | ||
207 | const struct sockaddr_in *remote_sa = &local_sa[1]; | ||
208 | 199 | ||
209 | nh->reversal_callback (nh->callback_cls, | 200 | nh->reversal_callback (nh->callback_cls, |
210 | (const struct sockaddr *) local_sa, | 201 | (const struct sockaddr *) &crm[1], |
211 | sizeof (struct sockaddr_in), | ||
212 | (const struct sockaddr *) remote_sa, | ||
213 | sizeof (struct sockaddr_in)); | 202 | sizeof (struct sockaddr_in)); |
214 | } | 203 | } |
215 | 204 | ||
@@ -380,8 +369,7 @@ do_connect (void *cls) | |||
380 | * | 369 | * |
381 | * @param cfg configuration to use | 370 | * @param cfg configuration to use |
382 | * @param proto protocol this is about, IPPROTO_TCP or IPPROTO_UDP | 371 | * @param proto protocol this is about, IPPROTO_TCP or IPPROTO_UDP |
383 | * @param adv_port advertised port (port we are either bound to or that our OS | 372 | * @param hole_external hostname and port of manually punched hole in NAT, otherwise NULL (or empty string) |
384 | * locally performs redirection from to our bound port). | ||
385 | * @param num_addrs number of addresses in @a addrs | 373 | * @param num_addrs number of addresses in @a addrs |
386 | * @param addrs list of local addresses packets should be redirected to | 374 | * @param addrs list of local addresses packets should be redirected to |
387 | * @param addrlens actual lengths of the addresses in @a addrs | 375 | * @param addrlens actual lengths of the addresses in @a addrs |
@@ -394,7 +382,7 @@ do_connect (void *cls) | |||
394 | struct GNUNET_NAT_Handle * | 382 | struct GNUNET_NAT_Handle * |
395 | GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, | 383 | GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, |
396 | uint8_t proto, | 384 | uint8_t proto, |
397 | uint16_t adv_port, | 385 | const char *hole_external, |
398 | unsigned int num_addrs, | 386 | unsigned int num_addrs, |
399 | const struct sockaddr **addrs, | 387 | const struct sockaddr **addrs, |
400 | const socklen_t *addrlens, | 388 | const socklen_t *addrlens, |
@@ -405,11 +393,17 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
405 | struct GNUNET_NAT_Handle *nh; | 393 | struct GNUNET_NAT_Handle *nh; |
406 | struct GNUNET_NAT_RegisterMessage *rm; | 394 | struct GNUNET_NAT_RegisterMessage *rm; |
407 | size_t len; | 395 | size_t len; |
396 | size_t hole_external_len; | ||
408 | char *off; | 397 | char *off; |
409 | 398 | ||
410 | len = 0; | 399 | len = 0; |
411 | for (unsigned int i=0;i<num_addrs;i++) | 400 | for (unsigned int i=0;i<num_addrs;i++) |
412 | len += addrlens[i]; | 401 | len += addrlens[i]; |
402 | hole_external_len | ||
403 | = (NULL == hole_external) | ||
404 | ? 0 | ||
405 | : strlen (hole_external); | ||
406 | len += hole_external_len; | ||
413 | if ( (len > GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (*rm)) || | 407 | if ( (len > GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (*rm)) || |
414 | (num_addrs > UINT16_MAX) ) | 408 | (num_addrs > UINT16_MAX) ) |
415 | { | 409 | { |
@@ -425,7 +419,7 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
425 | if (NULL != reversal_callback) | 419 | if (NULL != reversal_callback) |
426 | rm->flags |= GNUNET_NAT_RF_REVERSAL; | 420 | rm->flags |= GNUNET_NAT_RF_REVERSAL; |
427 | rm->proto = proto; | 421 | rm->proto = proto; |
428 | rm->adv_port = htons (adv_port); | 422 | rm->hole_external_len = htons (hole_external_len); |
429 | rm->num_addrs = htons ((uint16_t) num_addrs); | 423 | rm->num_addrs = htons ((uint16_t) num_addrs); |
430 | off = (char *) &rm[1]; | 424 | off = (char *) &rm[1]; |
431 | for (unsigned int i=0;i<num_addrs;i++) | 425 | for (unsigned int i=0;i<num_addrs;i++) |
@@ -464,6 +458,9 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
464 | addrlens[i]); | 458 | addrlens[i]); |
465 | off += addrlens[i]; | 459 | off += addrlens[i]; |
466 | } | 460 | } |
461 | GNUNET_memcpy (off, | ||
462 | hole_external, | ||
463 | hole_external_len); | ||
467 | 464 | ||
468 | nh = GNUNET_new (struct GNUNET_NAT_Handle); | 465 | nh = GNUNET_new (struct GNUNET_NAT_Handle); |
469 | nh->reg = &rm->header; | 466 | nh->reg = &rm->header; |