diff options
-rw-r--r-- | TODO | 2 | ||||
-rw-r--r-- | contrib/defaults.conf | 4 | ||||
-rw-r--r-- | src/nat/nat.c | 146 |
3 files changed, 145 insertions, 7 deletions
@@ -8,8 +8,6 @@ | |||
8 | 8 | ||
9 | 0.9.0pre4: | 9 | 0.9.0pre4: |
10 | * NAT library: [CG/MW] | 10 | * NAT library: [CG/MW] |
11 | - UPnP support | ||
12 | - testcase | ||
13 | - more testing | 11 | - more testing |
14 | * Transport: | 12 | * Transport: |
15 | - UDP fragmentation [MW] | 13 | - UDP fragmentation [MW] |
diff --git a/contrib/defaults.conf b/contrib/defaults.conf index 4a9b44dc8..f6b0e0c87 100644 --- a/contrib/defaults.conf +++ b/contrib/defaults.conf | |||
@@ -28,7 +28,7 @@ BEHIND_NAT = NO | |||
28 | # Is the NAT hole-punched? | 28 | # Is the NAT hole-punched? |
29 | PUNCHED_NAT = NO | 29 | PUNCHED_NAT = NO |
30 | 30 | ||
31 | # Disable UPNP by default until it gets cleaner! | 31 | # Enable UPNP by default? |
32 | ENABLE_UPNP = NO | 32 | ENABLE_UPNP = NO |
33 | 33 | ||
34 | # Use addresses from the local network interfaces (inluding loopback, but also others) | 34 | # Use addresses from the local network interfaces (inluding loopback, but also others) |
@@ -69,7 +69,7 @@ IFC_SCAN_FREQUENCY = 3000000 | |||
69 | DYNDNS_FREQUENCY = 140000 | 69 | DYNDNS_FREQUENCY = 140000 |
70 | 70 | ||
71 | [gnunet-nat-server] | 71 | [gnunet-nat-server] |
72 | HOSTNAME = nat.gnunet.org | 72 | HOSTNAME = gnunet.org |
73 | PORT = 5724 | 73 | PORT = 5724 |
74 | 74 | ||
75 | [transport-tcp] | 75 | [transport-tcp] |
diff --git a/src/nat/nat.c b/src/nat/nat.c index 2f38998e5..9d7d3ee72 100644 --- a/src/nat/nat.c +++ b/src/nat/nat.c | |||
@@ -86,7 +86,10 @@ enum LocalAddressSource | |||
86 | */ | 86 | */ |
87 | LAL_BINDTO_ADDRESS, | 87 | LAL_BINDTO_ADDRESS, |
88 | 88 | ||
89 | /* TODO: add UPnP, etc. */ | 89 | /** |
90 | * Addresses from UPnP or PMP | ||
91 | */ | ||
92 | LAL_UPNP, | ||
90 | 93 | ||
91 | /** | 94 | /** |
92 | * End of the list. | 95 | * End of the list. |
@@ -128,6 +131,35 @@ struct LocalAddressList | |||
128 | 131 | ||
129 | 132 | ||
130 | /** | 133 | /** |
134 | * Handle for miniupnp-based NAT traversal actions. | ||
135 | */ | ||
136 | struct MiniList | ||
137 | { | ||
138 | |||
139 | /** | ||
140 | * Doubly-linked list. | ||
141 | */ | ||
142 | struct MiniList *next; | ||
143 | |||
144 | /** | ||
145 | * Doubly-linked list. | ||
146 | */ | ||
147 | struct MiniList *prev; | ||
148 | |||
149 | /** | ||
150 | * Handle to mini-action. | ||
151 | */ | ||
152 | struct GNUNET_NAT_MiniHandle *mini; | ||
153 | |||
154 | /** | ||
155 | * Local port number that was mapped. | ||
156 | */ | ||
157 | uint16_t port; | ||
158 | |||
159 | }; | ||
160 | |||
161 | |||
162 | /** | ||
131 | * Handle for active NAT registrations. | 163 | * Handle for active NAT registrations. |
132 | */ | 164 | */ |
133 | struct GNUNET_NAT_Handle | 165 | struct GNUNET_NAT_Handle |
@@ -246,6 +278,18 @@ struct GNUNET_NAT_Handle | |||
246 | socklen_t *local_addrlens; | 278 | socklen_t *local_addrlens; |
247 | 279 | ||
248 | /** | 280 | /** |
281 | * List of handles for UPnP-traversal, one per local port (if | ||
282 | * not IPv6-only). | ||
283 | */ | ||
284 | struct MiniList *mini_head; | ||
285 | |||
286 | /** | ||
287 | * List of handles for UPnP-traversal, one per local port (if | ||
288 | * not IPv6-only). | ||
289 | */ | ||
290 | struct MiniList *mini_tail; | ||
291 | |||
292 | /** | ||
249 | * Number of entries in 'local_addrs' array. | 293 | * Number of entries in 'local_addrs' array. |
250 | */ | 294 | */ |
251 | unsigned int num_local_addrs; | 295 | unsigned int num_local_addrs; |
@@ -924,6 +968,89 @@ resolve_dns (void *cls, | |||
924 | 968 | ||
925 | 969 | ||
926 | /** | 970 | /** |
971 | * Add or remove UPnP-mapped addresses. | ||
972 | * | ||
973 | * @param cls the GNUNET_NAT_Handle | ||
974 | * @param add_remove GNUNET_YES to mean the new public IP address, GNUNET_NO to mean | ||
975 | * the previous (now invalid) one | ||
976 | * @param addr either the previous or the new public IP address | ||
977 | * @param addrlen actual lenght of the address | ||
978 | */ | ||
979 | static void | ||
980 | upnp_add (void *cls, | ||
981 | int add_remove, | ||
982 | const struct sockaddr *addr, | ||
983 | socklen_t addrlen) | ||
984 | { | ||
985 | struct GNUNET_NAT_Handle *h = cls; | ||
986 | struct LocalAddressList *pos; | ||
987 | struct LocalAddressList *next; | ||
988 | |||
989 | if (GNUNET_YES == add_remove) | ||
990 | { | ||
991 | add_to_address_list (h, | ||
992 | LAL_UPNP, | ||
993 | addr, addrlen); | ||
994 | return; | ||
995 | } | ||
996 | /* remove address */ | ||
997 | next = h->lal_head; | ||
998 | while (NULL != (pos = next)) | ||
999 | { | ||
1000 | next = pos->next; | ||
1001 | if ( (pos->source != LAL_UPNP) || | ||
1002 | (pos->addrlen != addrlen) || | ||
1003 | (0 != memcmp (&pos[1], | ||
1004 | addr, | ||
1005 | addrlen)) ) | ||
1006 | continue; | ||
1007 | GNUNET_CONTAINER_DLL_remove (h->lal_head, | ||
1008 | h->lal_tail, | ||
1009 | pos); | ||
1010 | if (NULL != h->address_callback) | ||
1011 | h->address_callback (h->callback_cls, | ||
1012 | GNUNET_NO, | ||
1013 | (const struct sockaddr* ) &pos[1], | ||
1014 | pos->addrlen); | ||
1015 | GNUNET_free (pos); | ||
1016 | return; /* only remove once */ | ||
1017 | } | ||
1018 | /* asked to remove address that does not exist */ | ||
1019 | GNUNET_break (0); | ||
1020 | } | ||
1021 | |||
1022 | |||
1023 | /** | ||
1024 | * Try to add a port mapping using UPnP. | ||
1025 | * | ||
1026 | * @param h overall NAT handle | ||
1027 | * @param port port to map with UPnP | ||
1028 | */ | ||
1029 | static void | ||
1030 | add_minis (struct GNUNET_NAT_Handle *h, | ||
1031 | uint16_t port) | ||
1032 | { | ||
1033 | struct MiniList *ml; | ||
1034 | |||
1035 | ml = h->mini_head; | ||
1036 | while (NULL != ml) | ||
1037 | { | ||
1038 | if (port == ml->port) | ||
1039 | return; /* already got this port */ | ||
1040 | ml = ml->next; | ||
1041 | } | ||
1042 | ml = GNUNET_malloc (sizeof (struct MiniList)); | ||
1043 | ml->port = port; | ||
1044 | ml->mini = GNUNET_NAT_mini_map_start (port, | ||
1045 | h->is_tcp, | ||
1046 | &upnp_add, h); | ||
1047 | GNUNET_CONTAINER_DLL_insert (h->mini_head, | ||
1048 | h->mini_tail, | ||
1049 | ml); | ||
1050 | } | ||
1051 | |||
1052 | |||
1053 | /** | ||
927 | * Task to add addresses from original bind to set of valid addrs. | 1054 | * Task to add addresses from original bind to set of valid addrs. |
928 | * | 1055 | * |
929 | * @param cls the NAT handle | 1056 | * @param cls the NAT handle |
@@ -931,12 +1058,13 @@ resolve_dns (void *cls, | |||
931 | */ | 1058 | */ |
932 | static void | 1059 | static void |
933 | add_from_bind (void *cls, | 1060 | add_from_bind (void *cls, |
934 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 1061 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
935 | { | 1062 | { |
936 | static struct in6_addr any = IN6ADDR_ANY_INIT; | 1063 | static struct in6_addr any = IN6ADDR_ANY_INIT; |
937 | struct GNUNET_NAT_Handle *h = cls; | 1064 | struct GNUNET_NAT_Handle *h = cls; |
938 | unsigned int i; | 1065 | unsigned int i; |
939 | struct sockaddr *sa; | 1066 | struct sockaddr *sa; |
1067 | const struct sockaddr_in *v4; | ||
940 | 1068 | ||
941 | h->bind_task = GNUNET_SCHEDULER_NO_TASK; | 1069 | h->bind_task = GNUNET_SCHEDULER_NO_TASK; |
942 | for (i=0;i<h->num_local_addrs;i++) | 1070 | for (i=0;i<h->num_local_addrs;i++) |
@@ -950,8 +1078,11 @@ add_from_bind (void *cls, | |||
950 | GNUNET_break (0); | 1078 | GNUNET_break (0); |
951 | break; | 1079 | break; |
952 | } | 1080 | } |
953 | if (0 != ((const struct sockaddr_in*) sa)->sin_addr.s_addr) | 1081 | v4 = (const struct sockaddr_in*) sa; |
1082 | if (0 != v4->sin_addr.s_addr) | ||
954 | add_to_address_list (h, LAL_BINDTO_ADDRESS, sa, sizeof (struct sockaddr_in)); | 1083 | add_to_address_list (h, LAL_BINDTO_ADDRESS, sa, sizeof (struct sockaddr_in)); |
1084 | if (h->enable_upnp) | ||
1085 | add_minis (h, ntohs (v4->sin_port)); | ||
955 | break; | 1086 | break; |
956 | case AF_INET6: | 1087 | case AF_INET6: |
957 | if (sizeof (struct sockaddr_in6) != h->local_addrlens[i]) | 1088 | if (sizeof (struct sockaddr_in6) != h->local_addrlens[i]) |
@@ -1178,7 +1309,16 @@ GNUNET_NAT_unregister (struct GNUNET_NAT_Handle *h) | |||
1178 | { | 1309 | { |
1179 | unsigned int i; | 1310 | unsigned int i; |
1180 | struct LocalAddressList *lal; | 1311 | struct LocalAddressList *lal; |
1312 | struct MiniList *ml; | ||
1181 | 1313 | ||
1314 | while (NULL != (ml = h->mini_head)) | ||
1315 | { | ||
1316 | GNUNET_CONTAINER_DLL_remove (h->mini_head, | ||
1317 | h->mini_tail, | ||
1318 | ml); | ||
1319 | GNUNET_NAT_mini_map_stop (ml->mini); | ||
1320 | GNUNET_free (ml); | ||
1321 | } | ||
1182 | if (h->ext_dns != NULL) | 1322 | if (h->ext_dns != NULL) |
1183 | { | 1323 | { |
1184 | GNUNET_RESOLVER_request_cancel (h->ext_dns); | 1324 | GNUNET_RESOLVER_request_cancel (h->ext_dns); |