aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-07-08 11:44:52 +0000
committerChristian Grothoff <christian@grothoff.org>2011-07-08 11:44:52 +0000
commite43aa53ca452e5c8a5be19be6212f0618e06a895 (patch)
treed3f0255e1a1475dd970a10821b89a368adec3b7f
parentceefc6de0ed40c33a644c571422d0b558aa851ca (diff)
downloadgnunet-e43aa53ca452e5c8a5be19be6212f0618e06a895.tar.gz
gnunet-e43aa53ca452e5c8a5be19be6212f0618e06a895.zip
integrating miniupnp with nat library
-rw-r--r--TODO2
-rw-r--r--contrib/defaults.conf4
-rw-r--r--src/nat/nat.c146
3 files changed, 145 insertions, 7 deletions
diff --git a/TODO b/TODO
index 2e41bbcc5..8a101f43d 100644
--- a/TODO
+++ b/TODO
@@ -8,8 +8,6 @@
8 8
90.9.0pre4: 90.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?
29PUNCHED_NAT = NO 29PUNCHED_NAT = NO
30 30
31# Disable UPNP by default until it gets cleaner! 31# Enable UPNP by default?
32ENABLE_UPNP = NO 32ENABLE_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
69DYNDNS_FREQUENCY = 140000 69DYNDNS_FREQUENCY = 140000
70 70
71[gnunet-nat-server] 71[gnunet-nat-server]
72HOSTNAME = nat.gnunet.org 72HOSTNAME = gnunet.org
73PORT = 5724 73PORT = 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 */
136struct 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 */
133struct GNUNET_NAT_Handle 165struct 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 */
979static void
980upnp_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 */
1029static void
1030add_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 */
932static void 1059static void
933add_from_bind (void *cls, 1060add_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);