aboutsummaryrefslogtreecommitdiff
path: root/src/nat/nat.c
diff options
context:
space:
mode:
authorMoon <moon@140774ce-b5e7-0310-ab8b-a85725594a96>2010-10-09 13:53:47 +0000
committerMoon <moon@140774ce-b5e7-0310-ab8b-a85725594a96>2010-10-09 13:53:47 +0000
commit922a0672749ba9d496d1dd8f6596bb4f8035e71d (patch)
treeccd4b351bd5acd5cc3b8b1cc358c712d6c0c116d /src/nat/nat.c
parentdc24b5bf44bf8d9460b2571fe529403637aa3e16 (diff)
downloadgnunet-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.c362
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
124static int 136static int
125get_traversal_status (const struct GNUNET_NAT_Handle * s) 137get_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 */
136int 148int
137GNUNET_NAT_cmp_addr (const struct sockaddr *a, 149GNUNET_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 */
159static void 170static void
160notify_change (struct GNUNET_NAT_Handle *nat, 171notify_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
233static void nat_pulse (void *cls,
234 const struct GNUNET_SCHEDULER_TaskContext *tc);
227 235
228static void 236static void
229nat_pulse (void *cls, 237pulse_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
304static void
305upnp_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
317static void
318natpmp_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
330static void
331nat_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 */
324struct GNUNET_NAT_Handle * 383struct GNUNET_NAT_Handle *
325GNUNET_NAT_register (struct GNUNET_SCHEDULER_Handle *sched, 384GNUNET_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,
371void 439void
372GNUNET_NAT_unregister (struct GNUNET_NAT_Handle *h) 440GNUNET_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