diff options
author | Moon <moon@140774ce-b5e7-0310-ab8b-a85725594a96> | 2010-10-09 13:53:47 +0000 |
---|---|---|
committer | Moon <moon@140774ce-b5e7-0310-ab8b-a85725594a96> | 2010-10-09 13:53:47 +0000 |
commit | 922a0672749ba9d496d1dd8f6596bb4f8035e71d (patch) | |
tree | ccd4b351bd5acd5cc3b8b1cc358c712d6c0c116d /src/nat/nat.c | |
parent | dc24b5bf44bf8d9460b2571fe529403637aa3e16 (diff) | |
download | gnunet-922a0672749ba9d496d1dd8f6596bb4f8035e71d.tar.gz gnunet-922a0672749ba9d496d1dd8f6596bb4f8035e71d.zip |
rework UPnP code to use GNUnet scheduler and network API
disable NAT-PMP support for now
Diffstat (limited to 'src/nat/nat.c')
-rw-r--r-- | src/nat/nat.c | 362 |
1 files changed, 214 insertions, 148 deletions
diff --git a/src/nat/nat.c b/src/nat/nat.c index 794d9405c..5159e0903 100644 --- a/src/nat/nat.c +++ b/src/nat/nat.c | |||
@@ -46,12 +46,12 @@ struct GNUNET_NAT_Handle | |||
46 | /** | 46 | /** |
47 | * Handle for UPnP operations. | 47 | * Handle for UPnP operations. |
48 | */ | 48 | */ |
49 | GNUNET_NAT_UPNP_Handle *upnp; | 49 | struct GNUNET_NAT_UPNP_Handle *upnp; |
50 | 50 | ||
51 | /** | 51 | /** |
52 | * Handle for NAT PMP operations. | 52 | * Handle for NAT PMP operations. |
53 | */ | 53 | */ |
54 | GNUNET_NAT_NATPMP_Handle *natpmp; | 54 | struct GNUNET_NAT_NATPMP_Handle *natpmp; |
55 | 55 | ||
56 | /** | 56 | /** |
57 | * Scheduler. | 57 | * Scheduler. |
@@ -61,17 +61,23 @@ struct GNUNET_NAT_Handle | |||
61 | /** | 61 | /** |
62 | * LAN address as passed by the caller | 62 | * LAN address as passed by the caller |
63 | */ | 63 | */ |
64 | struct sockaddr *local_addr; | 64 | struct sockaddr *local_addr; |
65 | 65 | ||
66 | /** | 66 | /** |
67 | * External address as reported by NAT box | 67 | * External address as reported by found NAT box |
68 | */ | 68 | */ |
69 | struct sockaddr *ext_addr; | 69 | struct sockaddr *ext_addr; |
70 | |||
71 | /** | ||
72 | * External address as reported by each type of NAT box | ||
73 | */ | ||
74 | struct sockaddr *ext_addr_upnp; | ||
75 | struct sockaddr *ext_addr_natpmp; | ||
70 | 76 | ||
71 | /** | 77 | /** |
72 | * External address and port where packets are redirected | 78 | * External address and port where packets are redirected |
73 | */ | 79 | */ |
74 | struct sockaddr *contact_addr; | 80 | struct sockaddr *contact_addr; |
75 | 81 | ||
76 | GNUNET_NAT_AddressCallback callback; | 82 | GNUNET_NAT_AddressCallback callback; |
77 | 83 | ||
@@ -92,8 +98,14 @@ struct GNUNET_NAT_Handle | |||
92 | 98 | ||
93 | int port_mapped; | 99 | int port_mapped; |
94 | 100 | ||
101 | int old_status; | ||
102 | |||
103 | int new_status; | ||
104 | |||
95 | int did_warn; | 105 | int did_warn; |
96 | 106 | ||
107 | int processing; | ||
108 | |||
97 | uint16_t public_port; | 109 | uint16_t public_port; |
98 | 110 | ||
99 | }; | 111 | }; |
@@ -122,9 +134,9 @@ get_nat_state_str (enum GNUNET_NAT_PortState state) | |||
122 | 134 | ||
123 | 135 | ||
124 | static int | 136 | static int |
125 | get_traversal_status (const struct GNUNET_NAT_Handle * s) | 137 | get_traversal_status (const struct GNUNET_NAT_Handle *h) |
126 | { | 138 | { |
127 | return MAX (s->natpmp_status, s->upnp_status); | 139 | return MAX (h->natpmp_status, h->upnp_status); |
128 | } | 140 | } |
129 | 141 | ||
130 | 142 | ||
@@ -134,16 +146,15 @@ get_traversal_status (const struct GNUNET_NAT_Handle * s) | |||
134 | * @param b second sockaddr | 146 | * @param b second sockaddr |
135 | * @return 0 if addresses are equal, non-null value otherwise */ | 147 | * @return 0 if addresses are equal, non-null value otherwise */ |
136 | int | 148 | int |
137 | GNUNET_NAT_cmp_addr (const struct sockaddr *a, | 149 | GNUNET_NAT_cmp_addr (const struct sockaddr *a, const struct sockaddr *b) |
138 | const struct sockaddr *b) | ||
139 | { | 150 | { |
140 | if (!(a && b)) | 151 | if (!(a && b)) |
141 | return -1; | 152 | return -1; |
142 | if ( (a->sa_family == AF_INET) && (b->sa_family == AF_INET) ) | 153 | if ((a->sa_family == AF_INET) && (b->sa_family == AF_INET)) |
143 | return memcmp (&(((struct sockaddr_in *) a)->sin_addr), | 154 | return memcmp (&(((struct sockaddr_in *) a)->sin_addr), |
144 | &(((struct sockaddr_in *) b)->sin_addr), | 155 | &(((struct sockaddr_in *) b)->sin_addr), |
145 | sizeof (struct in_addr)); | 156 | sizeof (struct in_addr)); |
146 | if ( (a->sa_family == AF_INET6) && (b->sa_family == AF_INET6) ) | 157 | if ((a->sa_family == AF_INET6) && (b->sa_family == AF_INET6)) |
147 | return memcmp (&(((struct sockaddr_in6 *) a)->sin6_addr), | 158 | return memcmp (&(((struct sockaddr_in6 *) a)->sin6_addr), |
148 | &(((struct sockaddr_in6 *) b)->sin6_addr), | 159 | &(((struct sockaddr_in6 *) b)->sin6_addr), |
149 | sizeof (struct in6_addr)); | 160 | sizeof (struct in6_addr)); |
@@ -157,50 +168,45 @@ GNUNET_NAT_cmp_addr (const struct sockaddr *a, | |||
157 | * or nullify the previous sockaddr. Change the port if needed. | 168 | * or nullify the previous sockaddr. Change the port if needed. |
158 | */ | 169 | */ |
159 | static void | 170 | static void |
160 | notify_change (struct GNUNET_NAT_Handle *nat, | 171 | notify_change (struct GNUNET_NAT_Handle *h, |
161 | struct sockaddr *addr, | 172 | struct sockaddr *addr, size_t addrlen, int new_port_mapped) |
162 | size_t addrlen, | ||
163 | int new_port_mapped) | ||
164 | { | 173 | { |
165 | if (new_port_mapped == nat->port_mapped) | 174 | if (new_port_mapped == h->port_mapped) |
166 | return; | 175 | return; |
167 | nat->port_mapped = new_port_mapped; | 176 | h->port_mapped = new_port_mapped; |
168 | 177 | ||
169 | if ( (NULL != nat->contact_addr) && | 178 | if ((NULL != h->contact_addr) && (NULL != h->callback)) |
170 | (NULL != nat->callback) ) | 179 | h->callback (h->callback_cls, |
171 | nat->callback (nat->callback_cls, | 180 | GNUNET_NO, h->contact_addr, sizeof (h->contact_addr)); |
172 | GNUNET_NO, | 181 | GNUNET_free_non_null (h->contact_addr); |
173 | nat->contact_addr, | 182 | h->contact_addr = NULL; |
174 | sizeof (nat->contact_addr)); | 183 | GNUNET_free_non_null (h->ext_addr); |
175 | GNUNET_free_non_null (nat->contact_addr); | 184 | h->ext_addr = NULL; |
176 | nat->contact_addr = NULL; | ||
177 | GNUNET_free_non_null (nat->ext_addr); | ||
178 | nat->ext_addr = NULL; | ||
179 | if (NULL == addr) | 185 | if (NULL == addr) |
180 | return; | 186 | return; |
181 | nat->ext_addr = GNUNET_malloc (addrlen); | 187 | h->ext_addr = GNUNET_malloc (addrlen); |
182 | memcpy (nat->ext_addr, addr, addrlen); | 188 | memcpy (h->ext_addr, addr, addrlen); |
183 | 189 | ||
184 | /* Recreate the ext_addr:public_port bogus address to pass to the callback */ | 190 | /* Recreate the ext_addr:public_port bogus address to pass to the callback */ |
185 | if (nat->ext_addr->sa_family == AF_INET) | 191 | if (h->ext_addr->sa_family == AF_INET) |
186 | { | 192 | { |
187 | struct sockaddr_in tmp_addr; | 193 | struct sockaddr_in *tmp_addr; |
188 | 194 | ||
189 | tmp_addr = GNUNET_malloc (sizeof (struct sockaddr_in)); | 195 | tmp_addr = GNUNET_malloc (sizeof (struct sockaddr_in)); |
190 | tmp_addr->sin_family = AF_INET; | 196 | tmp_addr->sin_family = AF_INET; |
191 | #ifdef HAVE_SOCKADDR_IN_SIN_LEN | 197 | #ifdef HAVE_SOCKADDR_IN_SIN_LEN |
192 | tmp_addr->sin_len = sizeof (struct sockaddr_in); | 198 | tmp_addr->sin_len = sizeof (struct sockaddr_in); |
193 | #endif | 199 | #endif |
194 | tmp_addr->sin_port = port_mapped ? htons (nat->public_port) : 0; | 200 | tmp_addr->sin_port = h->port_mapped ? htons (h->public_port) : 0; |
195 | tmp_addr->sin_addr = ((struct sockaddr_in *) nat->ext_addr)->sin_addr; | 201 | tmp_addr->sin_addr = ((struct sockaddr_in *) h->ext_addr)->sin_addr; |
196 | nat->contact_addr = (struct sockaddr *) tmp_addr; | 202 | h->contact_addr = (struct sockaddr *) tmp_addr; |
197 | if (NULL != nat->callback) | 203 | |
198 | nat->callback (nat->callback_cls, | 204 | if (NULL != h->callback) |
199 | GNUNET_YES, | 205 | h->callback (h->callback_cls, |
200 | nat->contact_addr, | 206 | GNUNET_YES, |
201 | sizeof (struct sockaddr_in)); | 207 | h->contact_addr, sizeof (struct sockaddr_in)); |
202 | } | 208 | } |
203 | else if (nat->ext_addr->sa_family == AF_INET6) | 209 | else if (h->ext_addr->sa_family == AF_INET6) |
204 | { | 210 | { |
205 | struct sockaddr_in6 *tmp_addr; | 211 | struct sockaddr_in6 *tmp_addr; |
206 | 212 | ||
@@ -209,14 +215,14 @@ notify_change (struct GNUNET_NAT_Handle *nat, | |||
209 | #ifdef HAVE_SOCKADDR_IN_SIN_LEN | 215 | #ifdef HAVE_SOCKADDR_IN_SIN_LEN |
210 | tmp_addr->sin6_len = sizeof (struct sockaddr_in6); | 216 | tmp_addr->sin6_len = sizeof (struct sockaddr_in6); |
211 | #endif | 217 | #endif |
212 | tmp_addr->sin6_port = port_mapped ? htons (nat->public_port) : 0; | 218 | tmp_addr->sin6_port = h->port_mapped ? htons (h->public_port) : 0; |
213 | tmp_addr->sin6_addr = ((struct sockaddr_in6 *) nat->ext_addr)->sin6_addr; | 219 | tmp_addr->sin6_addr = ((struct sockaddr_in6 *) h->ext_addr)->sin6_addr; |
214 | nat->contact_addr = (struct sockaddr *) tmp_addr; | 220 | h->contact_addr = (struct sockaddr *) tmp_addr; |
215 | if (NULL != nat->callback) | 221 | |
216 | nat->callback (nat->callback_cls, | 222 | if (NULL != h->callback) |
217 | GNUNET_YES, | 223 | h->callback (h->callback_cls, |
218 | nat->contact_addr, | 224 | GNUNET_YES, |
219 | sizeof (struct sockaddr_in6)); | 225 | h->contact_addr, sizeof (struct sockaddr_in6)); |
220 | } | 226 | } |
221 | else | 227 | else |
222 | { | 228 | { |
@@ -224,87 +230,140 @@ notify_change (struct GNUNET_NAT_Handle *nat, | |||
224 | } | 230 | } |
225 | } | 231 | } |
226 | 232 | ||
233 | static void nat_pulse (void *cls, | ||
234 | const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
227 | 235 | ||
228 | static void | 236 | static void |
229 | nat_pulse (void *cls, | 237 | pulse_cb (struct GNUNET_NAT_Handle *h) |
230 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
231 | { | 238 | { |
232 | struct GNUNET_NAT_Handle *nat = cls; | 239 | socklen_t addrlen; |
233 | int old_status; | ||
234 | int new_status; | ||
235 | int port_mapped; | 240 | int port_mapped; |
236 | struct sockaddr *ext_addr_upnp = NULL; | ||
237 | struct sockaddr *ext_addr_natpmp = NULL; | ||
238 | 241 | ||
239 | nat->pulse_timer = GNUNET_SCHEDULER_NO_TASK; | 242 | /* One of the protocols is still working, wait for it to complete */ |
240 | old_status = get_traversal_status (nat); | 243 | if (h->processing) |
244 | return; | ||
241 | 245 | ||
242 | /* Only update the protocol that has been successful until now */ | 246 | h->new_status = get_traversal_status (h); |
243 | if (nat->upnp_status >= GNUNET_NAT_PORT_UNMAPPED) | 247 | if ((h->old_status != h->new_status) && |
244 | nat->upnp_status = | 248 | ((h->new_status == GNUNET_NAT_PORT_UNMAPPED) || |
245 | GNUNET_NAT_UPNP_pulse (nat->upnp, nat->is_enabled, GNUNET_YES, | 249 | (h->new_status == GNUNET_NAT_PORT_ERROR))) |
246 | &ext_addr_upnp); | ||
247 | else if (nat->natpmp_status >= GNUNET_NAT_PORT_UNMAPPED) | ||
248 | nat->natpmp_status = | ||
249 | GNUNET_NAT_NATPMP_pulse (nat->natpmp, nat->is_enabled, | ||
250 | &ext_addr_natpmp); | ||
251 | else | ||
252 | { | ||
253 | /* try both */ | ||
254 | nat->upnp_status = | ||
255 | GNUNET_NAT_UPNP_pulse (nat->upnp, nat->is_enabled, GNUNET_YES, | ||
256 | &ext_addr_upnp); | ||
257 | nat->natpmp_status = | ||
258 | GNUNET_NAT_NATPMP_pulse (nat->natpmp, nat->is_enabled, | ||
259 | &ext_addr_natpmp); | ||
260 | } | ||
261 | new_status = get_traversal_status (nat); | ||
262 | if ( (old_status != new_status) && | ||
263 | ( (new_status == GNUNET_NAT_PORT_UNMAPPED) || | ||
264 | (new_status == GNUNET_NAT_PORT_ERROR) ) ) | ||
265 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, | 250 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, |
266 | "NAT", | 251 | "NAT", |
267 | _("Port redirection failed: no UPnP or NAT-PMP routers supporting this feature found\n")); | 252 | _ |
253 | ("Port redirection failed: no UPnP or NAT-PMP routers supporting this feature found\n")); | ||
268 | #ifdef DEBUG | 254 | #ifdef DEBUG |
269 | if (new_status != old_status) | 255 | if (h->new_status != h->old_status) |
270 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "NAT", | 256 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "NAT", |
271 | _("State changed from `%s' to `%s'\n"), | 257 | _("State changed from `%s' to `%s'\n"), |
272 | get_nat_state_str (old_status), | 258 | get_nat_state_str (h->old_status), |
273 | get_nat_state_str (new_status)); | 259 | get_nat_state_str (h->new_status)); |
274 | #endif | 260 | #endif |
275 | 261 | ||
276 | port_mapped = (new_status == GNUNET_NAT_PORT_MAPPED); | 262 | port_mapped = (h->new_status == GNUNET_NAT_PORT_MAPPED); |
277 | if (!(ext_addr_upnp || ext_addr_natpmp)) | 263 | if (!(h->ext_addr_upnp || h->ext_addr_natpmp)) |
278 | { | 264 | { |
279 | /* Address has just changed and we could not get it, or it's the first try */ | 265 | /* Address has just changed and we could not get it, or it's the first try, |
280 | if ( (NULL != nat->ext_addr) || | 266 | * and we're not waiting for a reply from UPnP or NAT-PMP */ |
281 | (GNUNET_NO == nat->did_warn) ) | 267 | if (((NULL != h->ext_addr) || |
268 | (GNUNET_NO == h->did_warn)) && h->processing != 0) | ||
282 | { | 269 | { |
283 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, | 270 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, |
284 | "NAT", | 271 | "NAT", |
285 | _("Could not determine external IP address\n")); | 272 | _("Could not determine external IP address\n")); |
286 | nat->did_warn = GNUNET_YES; | 273 | h->did_warn = GNUNET_YES; |
287 | } | 274 | } |
288 | notify_change (nat, NULL, port_mapped); | 275 | notify_change (h, NULL, 0, port_mapped); |
289 | } | 276 | } |
290 | else if (ext_addr_upnp && GNUNET_NAT_cmp_addr (nat->ext_addr, ext_addr_upnp) != 0) | 277 | else if (h->ext_addr_upnp |
278 | && GNUNET_NAT_cmp_addr (h->ext_addr, h->ext_addr_upnp) != 0) | ||
291 | { | 279 | { |
280 | addrlen = h->ext_addr_upnp->sa_family == AF_INET ? | ||
281 | sizeof (struct sockaddr_in) : sizeof (struct sockaddr_in6); | ||
292 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, | 282 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, |
293 | "NAT", | 283 | "NAT", |
294 | _("External IP address changed to %s\n"), | 284 | _("External IP address changed to %s\n"), |
295 | GNUNET_a2s (ext_addr_upnp, sizeof (ext_addr_upnp))); | 285 | GNUNET_a2s (h->ext_addr_upnp, addrlen)); |
296 | notify_change (nat, ext_addr_upnp, port_mapped); | 286 | notify_change (h, h->ext_addr_upnp, addrlen, port_mapped); |
297 | } | 287 | } |
298 | else if (ext_addr_natpmp && GNUNET_NAT_cmp_addr (nat->ext_addr, ext_addr_natpmp) != 0) | 288 | else if (h->ext_addr_natpmp |
289 | && GNUNET_NAT_cmp_addr (h->ext_addr, h->ext_addr_natpmp) != 0) | ||
299 | { | 290 | { |
291 | addrlen = h->ext_addr_natpmp->sa_family == AF_INET ? | ||
292 | sizeof (struct sockaddr_in) : sizeof (struct sockaddr_in6); | ||
300 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "NAT", | 293 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "NAT", |
301 | _("External IP address changed to `%s'\n"), | 294 | _("External IP address changed to `%s'\n"), |
302 | GNUNET_a2s (ext_addr_natpmp, sizeof (ext_addr_natpmp))); | 295 | GNUNET_a2s (h->ext_addr_natpmp, addrlen)); |
303 | notify_change (nat, ext_addr_natpmp, port_mapped); | 296 | notify_change (h, h->ext_addr_natpmp, addrlen, port_mapped); |
297 | } | ||
298 | |||
299 | h->pulse_timer = GNUNET_SCHEDULER_add_delayed (h->sched, | ||
300 | GNUNET_TIME_UNIT_SECONDS, | ||
301 | &nat_pulse, h); | ||
302 | } | ||
303 | |||
304 | static void | ||
305 | upnp_pulse_cb (int status, struct sockaddr *ext_addr, void *cls) | ||
306 | { | ||
307 | struct GNUNET_NAT_Handle *h = cls; | ||
308 | |||
309 | h->upnp_status = status; | ||
310 | h->ext_addr_upnp = ext_addr; | ||
311 | |||
312 | h->processing--; | ||
313 | pulse_cb (h); | ||
314 | } | ||
315 | |||
316 | #if 0 | ||
317 | static void | ||
318 | natpmp_pulse_cb (int status, struct sockaddr *ext_addr, void *cls) | ||
319 | { | ||
320 | struct GNUNET_NAT_Handle *h = cls; | ||
321 | |||
322 | h->natpmp_status = status; | ||
323 | h->ext_addr_natpmp = ext_addr; | ||
324 | |||
325 | h->processing--; | ||
326 | pulse_cb (h); | ||
327 | } | ||
328 | #endif | ||
329 | |||
330 | static void | ||
331 | nat_pulse (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
332 | { | ||
333 | struct GNUNET_NAT_Handle *h = cls; | ||
334 | |||
335 | /* Stop if we're already waiting for an action to complete */ | ||
336 | if (h->processing) | ||
337 | return; | ||
338 | |||
339 | h->pulse_timer = GNUNET_SCHEDULER_NO_TASK; | ||
340 | h->old_status = get_traversal_status (h); | ||
341 | |||
342 | /* Only update the protocol that has been successful until now */ | ||
343 | if (h->upnp_status >= GNUNET_NAT_PORT_UNMAPPED) | ||
344 | { | ||
345 | h->processing = 1; | ||
346 | GNUNET_NAT_UPNP_pulse (h->upnp, h->is_enabled, GNUNET_YES); | ||
347 | |||
348 | /* Wait for the callback to call pulse_cb() to handle changes */ | ||
349 | return; | ||
350 | } | ||
351 | else if (h->natpmp_status >= GNUNET_NAT_PORT_UNMAPPED) | ||
352 | { | ||
353 | h->processing = 1; | ||
354 | #if 0 | ||
355 | GNUNET_NAT_NATPMP_pulse (h->natpmp, h->is_enabled); | ||
356 | #endif | ||
357 | } | ||
358 | else /* try both */ | ||
359 | { | ||
360 | h->processing = 2; | ||
361 | |||
362 | GNUNET_NAT_UPNP_pulse (h->upnp, h->is_enabled, GNUNET_YES); | ||
363 | #if 0 | ||
364 | GNUNET_NAT_NATPMP_pulse (h->natpmp, h->is_enabled, natpmp_pulse_cb, h); | ||
365 | #endif | ||
304 | } | 366 | } |
305 | nat->pulse_timer = GNUNET_SCHEDULER_add_delayed (nat->sched, | ||
306 | GNUNET_TIME_UNIT_SECONDS, | ||
307 | &nat_pulse, nat); | ||
308 | } | 367 | } |
309 | 368 | ||
310 | 369 | ||
@@ -322,43 +381,52 @@ nat_pulse (void *cls, | |||
322 | * @return NULL on error, otherwise handle that can be used to unregister | 381 | * @return NULL on error, otherwise handle that can be used to unregister |
323 | */ | 382 | */ |
324 | struct GNUNET_NAT_Handle * | 383 | struct GNUNET_NAT_Handle * |
325 | GNUNET_NAT_register (struct GNUNET_SCHEDULER_Handle *sched, | 384 | GNUNET_NAT_register (struct GNUNET_SCHEDULER_Handle |
326 | const struct sockaddr *addr, socklen_t addrlen, | 385 | *sched, |
386 | const struct sockaddr *addr, | ||
387 | socklen_t addrlen, | ||
327 | GNUNET_NAT_AddressCallback callback, void *callback_cls) | 388 | GNUNET_NAT_AddressCallback callback, void *callback_cls) |
328 | { | 389 | { |
329 | struct GNUNET_NAT_Handle *nat; | 390 | struct GNUNET_NAT_Handle *h; |
391 | |||
392 | h = GNUNET_malloc (sizeof (struct GNUNET_NAT_Handle)); | ||
330 | 393 | ||
331 | nat = GNUNET_malloc (sizeof (struct GNUNET_NAT_Handle)); | ||
332 | if (addr) | 394 | if (addr) |
333 | { | 395 | { |
334 | GNUNET_assert ( (addr->sa_family == AF_INET) || | 396 | GNUNET_assert ((addr->sa_family == AF_INET) || |
335 | (addr->sa_family == AF_INET6) ); | 397 | (addr->sa_family == AF_INET6)); |
336 | nat->local_addr = GNUNET_malloc (addrlen); | 398 | h->local_addr = GNUNET_malloc (addrlen); |
337 | memcpy (nat->local_addr, addr, addrlen); | 399 | memcpy (h->local_addr, addr, addrlen); |
338 | if (addr->sa_family == AF_INET) | 400 | if (addr->sa_family == AF_INET) |
339 | { | 401 | { |
340 | nat->public_port = ntohs (((struct sockaddr_in *) addr)->sin_port); | 402 | h->public_port = ntohs (((struct sockaddr_in *) addr)->sin_port); |
341 | ((struct sockaddr_in *) nat->local_addr)->sin_port = 0; | 403 | ((struct sockaddr_in *) h->local_addr)->sin_port = 0; |
342 | } | 404 | } |
343 | else if (addr->sa_family == AF_INET6) | 405 | else if (addr->sa_family == AF_INET6) |
344 | { | 406 | { |
345 | nat->public_port = ntohs (((struct sockaddr_in6 *) addr)->sin6_port); | 407 | h->public_port = ntohs (((struct sockaddr_in6 *) addr)->sin6_port); |
346 | ((struct sockaddr_in6 *) nat->local_addr)->sin6_port = 0; | 408 | ((struct sockaddr_in6 *) h->local_addr)->sin6_port = 0; |
347 | } | 409 | } |
348 | } | 410 | } |
349 | nat->should_change = GNUNET_YES; | 411 | h->should_change = GNUNET_YES; |
350 | nat->sched = sched; | 412 | h->sched = sched; |
351 | nat->is_enabled = GNUNET_YES; | 413 | h->is_enabled = GNUNET_YES; |
352 | nat->upnp_status = GNUNET_NAT_PORT_UNMAPPED; | 414 | h->upnp_status = GNUNET_NAT_PORT_UNMAPPED; |
353 | nat->natpmp_status = GNUNET_NAT_PORT_UNMAPPED; | 415 | h->natpmp_status = GNUNET_NAT_PORT_UNMAPPED; |
354 | nat->callback = callback; | 416 | h->callback = callback; |
355 | nat->callback_cls = callback_cls; | 417 | h->callback_cls = callback_cls; |
356 | nat->natpmp = GNUNET_NAT_NATPMP_init (nat->local_addr, addrlen, nat->public_port); | 418 | h->upnp = |
357 | nat->upnp = GNUNET_NAT_UPNP_init (nat->local_addr, addrlen, nat->public_port); | 419 | GNUNET_NAT_UPNP_init (h->sched, h->local_addr, addrlen, h->public_port, |
358 | nat->pulse_timer = GNUNET_SCHEDULER_add_delayed (sched, | 420 | upnp_pulse_cb, h); |
359 | GNUNET_TIME_UNIT_SECONDS, | 421 | #if 0 |
360 | &nat_pulse, nat); | 422 | h->natpmp = |
361 | return nat; | 423 | GNUNET_NAT_NATPMP_init (h->sched, h->local_addr, addrlen, h->public_port, |
424 | natpmp_pulse_cb, h); | ||
425 | #endif | ||
426 | h->pulse_timer = GNUNET_SCHEDULER_add_delayed (sched, | ||
427 | GNUNET_TIME_UNIT_SECONDS, | ||
428 | &nat_pulse, h); | ||
429 | return h; | ||
362 | } | 430 | } |
363 | 431 | ||
364 | 432 | ||
@@ -371,23 +439,21 @@ GNUNET_NAT_register (struct GNUNET_SCHEDULER_Handle *sched, | |||
371 | void | 439 | void |
372 | GNUNET_NAT_unregister (struct GNUNET_NAT_Handle *h) | 440 | GNUNET_NAT_unregister (struct GNUNET_NAT_Handle *h) |
373 | { | 441 | { |
374 | struct sockaddr *addr; | 442 | GNUNET_NAT_UPNP_pulse (h->upnp, GNUNET_NO, GNUNET_NO); |
375 | |||
376 | GNUNET_SCHEDULER_cancel (h->sched, | ||
377 | h->pulse_timer); | ||
378 | h->upnp_status = | ||
379 | GNUNET_NAT_UPNP_pulse (h->upnp, | ||
380 | GNUNET_NO, GNUNET_NO, | ||
381 | &addr); | ||
382 | h->natpmp_status = | ||
383 | GNUNET_NAT_NATPMP_pulse (h->natpmp, GNUNET_NO, | ||
384 | &addr); | ||
385 | GNUNET_NAT_NATPMP_close (h->natpmp); | ||
386 | GNUNET_NAT_UPNP_close (h->upnp); | 443 | GNUNET_NAT_UPNP_close (h->upnp); |
444 | |||
445 | #if 0 | ||
446 | GNUNET_NAT_NATPMP_pulse (h->natpmp, GNUNET_NO); | ||
447 | GNUNET_NAT_NATPMP_close (h->natpmp); | ||
448 | #endif | ||
449 | |||
450 | GNUNET_SCHEDULER_cancel (h->sched, h->pulse_timer); | ||
451 | |||
387 | GNUNET_free_non_null (h->local_addr); | 452 | GNUNET_free_non_null (h->local_addr); |
388 | GNUNET_free_non_null (h->ext_addr); | 453 | GNUNET_free_non_null (h->ext_addr); |
454 | GNUNET_free_non_null (h->ext_addr_upnp); | ||
455 | GNUNET_free_non_null (h->ext_addr_natpmp); | ||
389 | GNUNET_free (h); | 456 | GNUNET_free (h); |
390 | } | 457 | } |
391 | 458 | ||
392 | /* end of nat.c */ | 459 | /* end of nat.c */ |
393 | |||