diff options
author | Christian Grothoff <christian@grothoff.org> | 2017-01-02 19:15:51 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2017-01-02 19:15:51 +0100 |
commit | f28533eb5fbd2b8e00bb351eb9fd1da322c70505 (patch) | |
tree | 793b1949dd681414d51ea18c151dd6684efa6b9f /src | |
parent | 1082a8e39e4f3d9b908b14995653ac262f640adb (diff) | |
download | gnunet-f28533eb5fbd2b8e00bb351eb9fd1da322c70505.tar.gz gnunet-f28533eb5fbd2b8e00bb351eb9fd1da322c70505.zip |
preparations for proper manual hole punching support in new NAT API
Diffstat (limited to 'src')
-rw-r--r-- | src/include/gnunet_nat_service.h | 5 | ||||
-rw-r--r-- | src/nat/gnunet-nat.c | 13 | ||||
-rw-r--r-- | src/nat/gnunet-service-nat.c | 58 | ||||
-rw-r--r-- | src/nat/nat.h | 10 | ||||
-rw-r--r-- | src/nat/nat_api.c | 16 |
5 files changed, 65 insertions, 37 deletions
diff --git a/src/include/gnunet_nat_service.h b/src/include/gnunet_nat_service.h index d9ce0e6f9..1620c9433 100644 --- a/src/include/gnunet_nat_service.h +++ b/src/include/gnunet_nat_service.h | |||
@@ -180,8 +180,7 @@ struct GNUNET_NAT_Handle; | |||
180 | * | 180 | * |
181 | * @param cfg configuration to use | 181 | * @param cfg configuration to use |
182 | * @param proto protocol this is about, IPPROTO_TCP or IPPROTO_UDP | 182 | * @param proto protocol this is about, IPPROTO_TCP or IPPROTO_UDP |
183 | * @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) |
184 | * locally performs redirection from to our bound port). | ||
185 | * @param num_addrs number of addresses in @a addrs | 184 | * @param num_addrs number of addresses in @a addrs |
186 | * @param addrs list of local addresses packets should be redirected to | 185 | * @param addrs list of local addresses packets should be redirected to |
187 | * @param addrlens actual lengths of the addresses in @a addrs | 186 | * @param addrlens actual lengths of the addresses in @a addrs |
@@ -194,7 +193,7 @@ struct GNUNET_NAT_Handle; | |||
194 | struct GNUNET_NAT_Handle * | 193 | struct GNUNET_NAT_Handle * |
195 | GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, | 194 | GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, |
196 | uint8_t proto, | 195 | uint8_t proto, |
197 | uint16_t adv_port, | 196 | const char *hole_external, |
198 | unsigned int num_addrs, | 197 | unsigned int num_addrs, |
199 | const struct sockaddr **addrs, | 198 | const struct sockaddr **addrs, |
200 | const socklen_t *addrlens, | 199 | const socklen_t *addrlens, |
diff --git a/src/nat/gnunet-nat.c b/src/nat/gnunet-nat.c index a145dc800..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. |
@@ -568,7 +569,7 @@ run (void *cls, | |||
568 | { | 569 | { |
569 | nh = GNUNET_NAT_register (c, | 570 | nh = GNUNET_NAT_register (c, |
570 | proto, | 571 | proto, |
571 | (uint16_t) adv_port, | 572 | hole_external, |
572 | 1, | 573 | 1, |
573 | (const struct sockaddr **) &local_sa, | 574 | (const struct sockaddr **) &local_sa, |
574 | &local_len, | 575 | &local_len, |
@@ -697,9 +698,9 @@ main (int argc, | |||
697 | {'r', "remote", "ADDRESS", | 698 | {'r', "remote", "ADDRESS", |
698 | 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"), |
699 | GNUNET_YES, &GNUNET_GETOPT_set_string, &remote_addr }, | 700 | GNUNET_YES, &GNUNET_GETOPT_set_string, &remote_addr }, |
700 | {'p', "port", NULL, | 701 | {'p', "punched", NULL, |
701 | 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"), |
702 | GNUNET_YES, &GNUNET_GETOPT_set_uint, &adv_port }, | 703 | GNUNET_YES, &GNUNET_GETOPT_set_string, &hole_external }, |
703 | {'s', "stun", NULL, | 704 | {'s', "stun", NULL, |
704 | gettext_noop ("enable STUN processing"), | 705 | gettext_noop ("enable STUN processing"), |
705 | 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 b547e773a..f432eca18 100644 --- a/src/nat/gnunet-service-nat.c +++ b/src/nat/gnunet-service-nat.c | |||
@@ -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 | */ |
@@ -459,7 +466,14 @@ check_register (void *cls, | |||
459 | GNUNET_break (0); | 466 | GNUNET_break (0); |
460 | return GNUNET_SYSERR; | 467 | return GNUNET_SYSERR; |
461 | } | 468 | } |
462 | } | 469 | off += alen; |
470 | left -= alen; | ||
471 | } | ||
472 | if (left != ntohs (message->hole_external_len)) | ||
473 | { | ||
474 | GNUNET_break (0); | ||
475 | return GNUNET_SYSERR; | ||
476 | } | ||
463 | return GNUNET_OK; | 477 | return GNUNET_OK; |
464 | } | 478 | } |
465 | 479 | ||
@@ -870,36 +884,33 @@ check_notify_client_external_ipv4_change (const struct in_addr *v4, | |||
870 | int add) | 884 | int add) |
871 | { | 885 | { |
872 | struct sockaddr_in sa; | 886 | struct sockaddr_in sa; |
873 | uint16_t port; | 887 | int have_v4; |
874 | uint16_t bport; | ||
875 | 888 | ||
876 | /* (1) check if client cares. */ | 889 | /* (1) check if client cares. */ |
877 | if (! ch->natted_address) | 890 | if (! ch->natted_address) |
878 | return; | 891 | return; |
879 | if (0 == (GNUNET_NAT_RF_ADDRESSES & ch->flags)) | 892 | if (0 == (GNUNET_NAT_RF_ADDRESSES & ch->flags)) |
880 | return; | 893 | return; |
881 | bport = 0; | 894 | have_v4 = GNUNET_NO; |
882 | for (unsigned int i=0;i<ch->num_caddrs;i++) | 895 | for (unsigned int i=0;i<ch->num_caddrs;i++) |
883 | { | 896 | { |
884 | const struct sockaddr_storage *ss = &ch->caddrs[i].ss; | 897 | const struct sockaddr_storage *ss = &ch->caddrs[i].ss; |
885 | 898 | ||
886 | if (AF_INET != ss->ss_family) | 899 | if (AF_INET != ss->ss_family) |
887 | continue; | 900 | continue; |
888 | bport = ntohs (((const struct sockaddr_in *) ss)->sin_port); | 901 | have_v4 = GNUNET_YES; |
902 | break; | ||
889 | } | 903 | } |
890 | if (0 == bport) | 904 | if (GNUNET_NO == have_v4) |
891 | return; /* IPv6-only */ | 905 | return; /* IPv6-only */ |
892 | 906 | ||
893 | /* (2) figure out external port, build sockaddr */ | 907 | /* build address info */ |
894 | port = ch->adv_port; | ||
895 | if (0 == port) | ||
896 | port = bport; | ||
897 | memset (&sa, | 908 | memset (&sa, |
898 | 0, | 909 | 0, |
899 | sizeof (sa)); | 910 | sizeof (sa)); |
900 | sa.sin_family = AF_INET; | 911 | sa.sin_family = AF_INET; |
901 | sa.sin_addr = *v4; | 912 | sa.sin_addr = *v4; |
902 | sa.sin_port = htons (port); | 913 | sa.sin_port = htons (0); |
903 | 914 | ||
904 | /* (3) notify client of change */ | 915 | /* (3) notify client of change */ |
905 | notify_client (is_nat_v4 (v4) | 916 | notify_client (is_nat_v4 (v4) |
@@ -1303,7 +1314,6 @@ handle_register (void *cls, | |||
1303 | "Received REGISTER message from client\n"); | 1314 | "Received REGISTER message from client\n"); |
1304 | ch->flags = message->flags; | 1315 | ch->flags = message->flags; |
1305 | ch->proto = message->proto; | 1316 | ch->proto = message->proto; |
1306 | ch->adv_port = ntohs (message->adv_port); | ||
1307 | ch->num_caddrs = ntohs (message->num_addrs); | 1317 | ch->num_caddrs = ntohs (message->num_addrs); |
1308 | ch->caddrs = GNUNET_new_array (ch->num_caddrs, | 1318 | ch->caddrs = GNUNET_new_array (ch->num_caddrs, |
1309 | struct ClientAddress); | 1319 | struct ClientAddress); |
@@ -1379,6 +1389,11 @@ handle_register (void *cls, | |||
1379 | 1389 | ||
1380 | off += alen; | 1390 | off += alen; |
1381 | } | 1391 | } |
1392 | |||
1393 | ch->hole_external | ||
1394 | = GNUNET_strndup (off, | ||
1395 | ntohs (message->hole_external_len)); | ||
1396 | |||
1382 | /* Actually send IP address list to client */ | 1397 | /* Actually send IP address list to client */ |
1383 | for (struct LocalAddressList *lal = lal_head; | 1398 | for (struct LocalAddressList *lal = lal_head; |
1384 | NULL != lal; | 1399 | NULL != lal; |
@@ -1450,7 +1465,7 @@ notify_clients_stun_change (const struct sockaddr_in *ip, | |||
1450 | if (! ch->natted_address) | 1465 | if (! ch->natted_address) |
1451 | continue; | 1466 | continue; |
1452 | v4 = *ip; | 1467 | v4 = *ip; |
1453 | v4.sin_port = htons (ch->adv_port); | 1468 | v4.sin_port = htons (0); |
1454 | env = GNUNET_MQ_msg_extra (msg, | 1469 | env = GNUNET_MQ_msg_extra (msg, |
1455 | sizeof (v4), | 1470 | sizeof (v4), |
1456 | GNUNET_MESSAGE_TYPE_NAT_ADDRESS_CHANGE); | 1471 | GNUNET_MESSAGE_TYPE_NAT_ADDRESS_CHANGE); |
@@ -2132,6 +2147,7 @@ client_disconnect_cb (void *cls, | |||
2132 | } | 2147 | } |
2133 | } | 2148 | } |
2134 | GNUNET_free_non_null (ch->caddrs); | 2149 | GNUNET_free_non_null (ch->caddrs); |
2150 | GNUNET_free (ch->hole_external); | ||
2135 | GNUNET_free (ch); | 2151 | GNUNET_free (ch); |
2136 | } | 2152 | } |
2137 | 2153 | ||
diff --git a/src/nat/nat.h b/src/nat/nat.h index 5cb1c1050..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 | ||
diff --git a/src/nat/nat_api.c b/src/nat/nat_api.c index ab36d6162..e4dfc1629 100644 --- a/src/nat/nat_api.c +++ b/src/nat/nat_api.c | |||
@@ -369,8 +369,7 @@ do_connect (void *cls) | |||
369 | * | 369 | * |
370 | * @param cfg configuration to use | 370 | * @param cfg configuration to use |
371 | * @param proto protocol this is about, IPPROTO_TCP or IPPROTO_UDP | 371 | * @param proto protocol this is about, IPPROTO_TCP or IPPROTO_UDP |
372 | * @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) |
373 | * locally performs redirection from to our bound port). | ||
374 | * @param num_addrs number of addresses in @a addrs | 373 | * @param num_addrs number of addresses in @a addrs |
375 | * @param addrs list of local addresses packets should be redirected to | 374 | * @param addrs list of local addresses packets should be redirected to |
376 | * @param addrlens actual lengths of the addresses in @a addrs | 375 | * @param addrlens actual lengths of the addresses in @a addrs |
@@ -383,7 +382,7 @@ do_connect (void *cls) | |||
383 | struct GNUNET_NAT_Handle * | 382 | struct GNUNET_NAT_Handle * |
384 | GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, | 383 | GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, |
385 | uint8_t proto, | 384 | uint8_t proto, |
386 | uint16_t adv_port, | 385 | const char *hole_external, |
387 | unsigned int num_addrs, | 386 | unsigned int num_addrs, |
388 | const struct sockaddr **addrs, | 387 | const struct sockaddr **addrs, |
389 | const socklen_t *addrlens, | 388 | const socklen_t *addrlens, |
@@ -394,11 +393,17 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
394 | struct GNUNET_NAT_Handle *nh; | 393 | struct GNUNET_NAT_Handle *nh; |
395 | struct GNUNET_NAT_RegisterMessage *rm; | 394 | struct GNUNET_NAT_RegisterMessage *rm; |
396 | size_t len; | 395 | size_t len; |
396 | size_t hole_external_len; | ||
397 | char *off; | 397 | char *off; |
398 | 398 | ||
399 | len = 0; | 399 | len = 0; |
400 | for (unsigned int i=0;i<num_addrs;i++) | 400 | for (unsigned int i=0;i<num_addrs;i++) |
401 | 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; | ||
402 | if ( (len > GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (*rm)) || | 407 | if ( (len > GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (*rm)) || |
403 | (num_addrs > UINT16_MAX) ) | 408 | (num_addrs > UINT16_MAX) ) |
404 | { | 409 | { |
@@ -414,7 +419,7 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
414 | if (NULL != reversal_callback) | 419 | if (NULL != reversal_callback) |
415 | rm->flags |= GNUNET_NAT_RF_REVERSAL; | 420 | rm->flags |= GNUNET_NAT_RF_REVERSAL; |
416 | rm->proto = proto; | 421 | rm->proto = proto; |
417 | rm->adv_port = htons (adv_port); | 422 | rm->hole_external_len = htons (hole_external_len); |
418 | rm->num_addrs = htons ((uint16_t) num_addrs); | 423 | rm->num_addrs = htons ((uint16_t) num_addrs); |
419 | off = (char *) &rm[1]; | 424 | off = (char *) &rm[1]; |
420 | for (unsigned int i=0;i<num_addrs;i++) | 425 | for (unsigned int i=0;i<num_addrs;i++) |
@@ -453,6 +458,9 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
453 | addrlens[i]); | 458 | addrlens[i]); |
454 | off += addrlens[i]; | 459 | off += addrlens[i]; |
455 | } | 460 | } |
461 | GNUNET_memcpy (off, | ||
462 | hole_external, | ||
463 | hole_external_len); | ||
456 | 464 | ||
457 | nh = GNUNET_new (struct GNUNET_NAT_Handle); | 465 | nh = GNUNET_new (struct GNUNET_NAT_Handle); |
458 | nh->reg = &rm->header; | 466 | nh->reg = &rm->header; |