aboutsummaryrefslogtreecommitdiff
path: root/src/nat
diff options
context:
space:
mode:
Diffstat (limited to 'src/nat')
-rw-r--r--src/nat/gnunet-nat.c223
-rw-r--r--src/nat/gnunet-service-nat_helper.c211
-rw-r--r--src/nat/gnunet-service-nat_mini.c263
3 files changed, 293 insertions, 404 deletions
diff --git a/src/nat/gnunet-nat.c b/src/nat/gnunet-nat.c
index 275553203..6c533374e 100644
--- a/src/nat/gnunet-nat.c
+++ b/src/nat/gnunet-nat.c
@@ -120,20 +120,19 @@ test_finished ()
120 */ 120 */
121static void 121static void
122address_cb (void *cls, 122address_cb (void *cls,
123 void **app_ctx, 123 void **app_ctx,
124 int add_remove, 124 int add_remove,
125 enum GNUNET_NAT_AddressClass ac, 125 enum GNUNET_NAT_AddressClass ac,
126 const struct sockaddr *addr, 126 const struct sockaddr *addr,
127 socklen_t addrlen) 127 socklen_t addrlen)
128{ 128{
129 (void) cls; 129 (void) cls;
130 (void) app_ctx; 130 (void) app_ctx;
131 131
132 fprintf (stdout, 132 fprintf (stdout,
133 "%s %s (%d)\n", 133 "%s %s (%d)\n",
134 add_remove ? "+" : "-", 134 add_remove ? "+" : "-",
135 GNUNET_a2s (addr, 135 GNUNET_a2s (addr, addrlen),
136 addrlen),
137 (int) ac); 136 (int) ac);
138} 137}
139 138
@@ -149,13 +148,12 @@ address_cb (void *cls,
149 */ 148 */
150static void 149static void
151reversal_cb (void *cls, 150reversal_cb (void *cls,
152 const struct sockaddr *remote_addr, 151 const struct sockaddr *remote_addr,
153 socklen_t remote_addrlen) 152 socklen_t remote_addrlen)
154{ 153{
155 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, 154 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
156 "Connection reversal requested by %s\n", 155 "Connection reversal requested by %s\n",
157 GNUNET_a2s (remote_addr, 156 GNUNET_a2s (remote_addr, remote_addrlen));
158 remote_addrlen));
159} 157}
160 158
161 159
@@ -194,9 +192,9 @@ stun_read_task (void *cls)
194 ssize_t size; 192 ssize_t size;
195 193
196 rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 194 rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
197 ls, 195 ls,
198 &stun_read_task, 196 &stun_read_task,
199 NULL); 197 NULL);
200 size = GNUNET_NETWORK_socket_recvfrom_amount (ls); 198 size = GNUNET_NETWORK_socket_recvfrom_amount (ls);
201 if (size > 0) 199 if (size > 0)
202 { 200 {
@@ -212,10 +210,10 @@ stun_read_task (void *cls)
212 ssize_t ret; 210 ssize_t ret;
213 211
214 ret = GNUNET_NETWORK_socket_recvfrom (ls, 212 ret = GNUNET_NETWORK_socket_recvfrom (ls,
215 buf, 213 buf,
216 size + 1, 214 size + 1,
217 (struct sockaddr *) &sa, 215 (struct sockaddr *) &sa,
218 &salen); 216 &salen);
219 if (ret != size) 217 if (ret != size)
220 { 218 {
221 GNUNET_break (0); 219 GNUNET_break (0);
@@ -224,10 +222,10 @@ stun_read_task (void *cls)
224 return; 222 return;
225 } 223 }
226 (void) GNUNET_NAT_stun_handle_packet (nh, 224 (void) GNUNET_NAT_stun_handle_packet (nh,
227 (const struct sockaddr *) &sa, 225 (const struct sockaddr *) &sa,
228 salen, 226 salen,
229 buf, 227 buf,
230 ret); 228 ret);
231 } 229 }
232} 230}
233 231
@@ -254,8 +252,7 @@ run (void *cls,
254 252
255 if (use_tcp && use_udp) 253 if (use_tcp && use_udp)
256 { 254 {
257 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, 255 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "Cannot use TCP and UDP\n");
258 "Cannot use TCP and UDP\n");
259 global_ret = 1; 256 global_ret = 1;
260 return; 257 return;
261 } 258 }
@@ -265,13 +262,11 @@ run (void *cls,
265 if (use_udp) 262 if (use_udp)
266 proto = IPPROTO_UDP; 263 proto = IPPROTO_UDP;
267 264
268 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, 265 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
269 NULL);
270 266
271 if (0 == proto) 267 if (0 == proto)
272 { 268 {
273 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, 269 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "Must specify either TCP or UDP\n");
274 "Must specify either TCP or UDP\n");
275 global_ret = 1; 270 global_ret = 1;
276 return; 271 return;
277 } 272 }
@@ -281,28 +276,26 @@ run (void *cls,
281 remote_sa = NULL; 276 remote_sa = NULL;
282 if (NULL != local_addr) 277 if (NULL != local_addr)
283 { 278 {
284 local_len = (socklen_t) GNUNET_STRINGS_parse_socket_addr (local_addr, 279 local_len =
285 &af, 280 (socklen_t) GNUNET_STRINGS_parse_socket_addr (local_addr, &af, &local_sa);
286 &local_sa);
287 if (0 == local_len) 281 if (0 == local_len)
288 { 282 {
289 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, 283 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
290 "Invalid socket address `%s'\n", 284 "Invalid socket address `%s'\n",
291 local_addr); 285 local_addr);
292 goto fail_and_shutdown; 286 goto fail_and_shutdown;
293 } 287 }
294 } 288 }
295 289
296 if (NULL != remote_addr) 290 if (NULL != remote_addr)
297 { 291 {
298 remote_len = GNUNET_STRINGS_parse_socket_addr (remote_addr, 292 remote_len =
299 &af, 293 GNUNET_STRINGS_parse_socket_addr (remote_addr, &af, &remote_sa);
300 &remote_sa);
301 if (0 == remote_len) 294 if (0 == remote_len)
302 { 295 {
303 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, 296 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
304 "Invalid socket address `%s'\n", 297 "Invalid socket address `%s'\n",
305 remote_addr); 298 remote_addr);
306 goto fail_and_shutdown; 299 goto fail_and_shutdown;
307 } 300 }
308 } 301 }
@@ -312,19 +305,19 @@ run (void *cls,
312 if (NULL == section_name) 305 if (NULL == section_name)
313 section_name = GNUNET_strdup ("undefined"); 306 section_name = GNUNET_strdup ("undefined");
314 nh = GNUNET_NAT_register (c, 307 nh = GNUNET_NAT_register (c,
315 section_name, 308 section_name,
316 proto, 309 proto,
317 1, 310 1,
318 (const struct sockaddr **) &local_sa, 311 (const struct sockaddr **) &local_sa,
319 &local_len, 312 &local_len,
320 &address_cb, 313 &address_cb,
321 (listen_reversal) ? &reversal_cb : NULL, 314 (listen_reversal) ? &reversal_cb : NULL,
322 NULL); 315 NULL);
323 } 316 }
324 else if (listen_reversal) 317 else if (listen_reversal)
325 { 318 {
326 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, 319 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
327 "Use of `-W` only effective in combination with `-i`\n"); 320 "Use of `-W` only effective in combination with `-i`\n");
328 goto fail_and_shutdown; 321 goto fail_and_shutdown;
329 } 322 }
330 323
@@ -332,33 +325,32 @@ run (void *cls,
332 { 325 {
333 int ret; 326 int ret;
334 327
335 if ( (NULL == nh) || 328 if ((NULL == nh) || (sizeof (struct sockaddr_in) != local_len))
336 (sizeof (struct sockaddr_in) != local_len) )
337 { 329 {
338 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, 330 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
339 "Require IPv4 local address to initiate connection reversal\n"); 331 "Require IPv4 local address to initiate connection reversal\n");
340 goto fail_and_shutdown; 332 goto fail_and_shutdown;
341 } 333 }
342 if (sizeof (struct sockaddr_in) != remote_len) 334 if (sizeof (struct sockaddr_in) != remote_len)
343 { 335 {
344 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, 336 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
345 "Require IPv4 reversal target address\n"); 337 "Require IPv4 reversal target address\n");
346 goto fail_and_shutdown; 338 goto fail_and_shutdown;
347 } 339 }
348 GNUNET_assert (AF_INET == local_sa->sa_family); 340 GNUNET_assert (AF_INET == local_sa->sa_family);
349 GNUNET_assert (AF_INET == remote_sa->sa_family); 341 GNUNET_assert (AF_INET == remote_sa->sa_family);
350 ret = GNUNET_NAT_request_reversal (nh, 342 ret = GNUNET_NAT_request_reversal (nh,
351 (const struct sockaddr_in *) local_sa, 343 (const struct sockaddr_in *) local_sa,
352 (const struct sockaddr_in *) remote_sa); 344 (const struct sockaddr_in *) remote_sa);
353 switch (ret) 345 switch (ret)
354 { 346 {
355 case GNUNET_SYSERR: 347 case GNUNET_SYSERR:
356 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, 348 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
357 "Connection reversal internal error\n"); 349 "Connection reversal internal error\n");
358 break; 350 break;
359 case GNUNET_NO: 351 case GNUNET_NO:
360 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, 352 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
361 "Connection reversal unavailable\n"); 353 "Connection reversal unavailable\n");
362 break; 354 break;
363 case GNUNET_OK: 355 case GNUNET_OK:
364 /* operation in progress */ 356 /* operation in progress */
@@ -371,46 +363,38 @@ run (void *cls,
371 if (NULL == local_addr) 363 if (NULL == local_addr)
372 { 364 {
373 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, 365 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
374 "Require local address to support STUN requests\n"); 366 "Require local address to support STUN requests\n");
375 goto fail_and_shutdown; 367 goto fail_and_shutdown;
376 } 368 }
377 if (IPPROTO_UDP != proto) 369 if (IPPROTO_UDP != proto)
378 { 370 {
379 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, 371 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "STUN only supported over UDP\n");
380 "STUN only supported over UDP\n");
381 goto fail_and_shutdown; 372 goto fail_and_shutdown;
382 } 373 }
383 ls = GNUNET_NETWORK_socket_create (af, 374 ls = GNUNET_NETWORK_socket_create (af, SOCK_DGRAM, IPPROTO_UDP);
384 SOCK_DGRAM,
385 IPPROTO_UDP);
386 if (NULL == ls) 375 if (NULL == ls)
387 { 376 {
388 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, 377 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "Failed to create socket\n");
389 "Failed to create socket\n");
390 goto fail_and_shutdown; 378 goto fail_and_shutdown;
391 } 379 }
392 if (GNUNET_OK != 380 if (GNUNET_OK != GNUNET_NETWORK_socket_bind (ls, local_sa, local_len))
393 GNUNET_NETWORK_socket_bind (ls,
394 local_sa,
395 local_len))
396 { 381 {
397 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 382 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
398 "Failed to bind to %s: %s\n", 383 "Failed to bind to %s: %s\n",
399 GNUNET_a2s (local_sa, 384 GNUNET_a2s (local_sa, local_len),
400 local_len), 385 strerror (errno));
401 STRERROR (errno));
402 goto fail_and_shutdown; 386 goto fail_and_shutdown;
403 } 387 }
404 rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 388 rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
405 ls, 389 ls,
406 &stun_read_task, 390 &stun_read_task,
407 NULL); 391 NULL);
408 } 392 }
409 GNUNET_free_non_null (remote_sa); 393 GNUNET_free_non_null (remote_sa);
410 GNUNET_free_non_null (local_sa); 394 GNUNET_free_non_null (local_sa);
411 test_finished (); 395 test_finished ();
412 return; 396 return;
413 fail_and_shutdown: 397fail_and_shutdown:
414 global_ret = 1; 398 global_ret = 1;
415 GNUNET_SCHEDULER_shutdown (); 399 GNUNET_SCHEDULER_shutdown ();
416 GNUNET_free_non_null (remote_sa); 400 GNUNET_free_non_null (remote_sa);
@@ -426,66 +410,63 @@ run (void *cls,
426 * @return 0 on success, -1 on error 410 * @return 0 on success, -1 on error
427 */ 411 */
428int 412int
429main (int argc, 413main (int argc, char *const argv[])
430 char *const argv[])
431{ 414{
432 struct GNUNET_GETOPT_CommandLineOption options[] = { 415 struct GNUNET_GETOPT_CommandLineOption options[] = {
433 416
434 GNUNET_GETOPT_option_string ('i', 417 GNUNET_GETOPT_option_string (
435 "in", 418 'i',
436 "ADDRESS", 419 "in",
437 gettext_noop ("which IP and port are we locally using to bind/listen to"), 420 "ADDRESS",
438 &local_addr), 421 gettext_noop ("which IP and port are we locally using to bind/listen to"),
439 422 &local_addr),
440 GNUNET_GETOPT_option_string ('r', 423
441 "remote", 424 GNUNET_GETOPT_option_string (
442 "ADDRESS", 425 'r',
443 gettext_noop ("which remote IP and port should be asked for connection reversal"), 426 "remote",
444 &remote_addr), 427 "ADDRESS",
445 428 gettext_noop (
446 GNUNET_GETOPT_option_string ('S', 429 "which remote IP and port should be asked for connection reversal"),
447 "section", 430 &remote_addr),
448 NULL, 431
449 gettext_noop ("name of configuration section to find additional options, such as manual host punching data"), 432 GNUNET_GETOPT_option_string (
450 &section_name), 433 'S',
434 "section",
435 NULL,
436 gettext_noop (
437 "name of configuration section to find additional options, such as manual host punching data"),
438 &section_name),
451 439
452 GNUNET_GETOPT_option_flag ('s', 440 GNUNET_GETOPT_option_flag ('s',
453 "stun", 441 "stun",
454 gettext_noop ("enable STUN processing"), 442 gettext_noop ("enable STUN processing"),
455 &do_stun), 443 &do_stun),
456 444
457 GNUNET_GETOPT_option_flag ('t', 445 GNUNET_GETOPT_option_flag ('t', "tcp", gettext_noop ("use TCP"), &use_tcp),
458 "tcp",
459 gettext_noop ("use TCP"),
460 &use_tcp),
461 446
462 GNUNET_GETOPT_option_flag ('u', 447 GNUNET_GETOPT_option_flag ('u', "udp", gettext_noop ("use UDP"), &use_udp),
463 "udp",
464 gettext_noop ("use UDP"),
465 &use_udp),
466 448
467 GNUNET_GETOPT_option_flag ('W', 449 GNUNET_GETOPT_option_flag ('W',
468 "watch", 450 "watch",
469 gettext_noop ("watch for connection reversal requests"), 451 gettext_noop (
470 &listen_reversal), 452 "watch for connection reversal requests"),
471 GNUNET_GETOPT_OPTION_END 453 &listen_reversal),
472 }; 454 GNUNET_GETOPT_OPTION_END};
473 455
474 if (GNUNET_OK != 456 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
475 GNUNET_STRINGS_get_utf8_args (argc, argv,
476 &argc, &argv))
477 return 2; 457 return 2;
478 if (GNUNET_OK != 458 if (GNUNET_OK !=
479 GNUNET_PROGRAM_run (argc, argv, 459 GNUNET_PROGRAM_run (argc,
480 "gnunet-nat [options]", 460 argv,
481 _("GNUnet NAT traversal autoconfigure daemon"), 461 "gnunet-nat [options]",
482 options, 462 _ ("GNUnet NAT traversal autoconfigure daemon"),
463 options,
483 &run, 464 &run,
484 NULL)) 465 NULL))
485 { 466 {
486 global_ret = 1; 467 global_ret = 1;
487 } 468 }
488 GNUNET_free ((void*) argv); 469 GNUNET_free ((void *) argv);
489 return global_ret; 470 return global_ret;
490} 471}
491 472
diff --git a/src/nat/gnunet-service-nat_helper.c b/src/nat/gnunet-service-nat_helper.c
index 43ac54adf..cf5038dd7 100644
--- a/src/nat/gnunet-service-nat_helper.c
+++ b/src/nat/gnunet-service-nat_helper.c
@@ -101,12 +101,10 @@ static void
101try_again (struct HelperContext *h) 101try_again (struct HelperContext *h)
102{ 102{
103 GNUNET_assert (NULL == h->server_read_task); 103 GNUNET_assert (NULL == h->server_read_task);
104 h->server_retry_delay 104 h->server_retry_delay = GNUNET_TIME_STD_BACKOFF (h->server_retry_delay);
105 = GNUNET_TIME_STD_BACKOFF (h->server_retry_delay); 105 h->server_read_task = GNUNET_SCHEDULER_add_delayed (h->server_retry_delay,
106 h->server_read_task 106 &restart_nat_server,
107 = GNUNET_SCHEDULER_add_delayed (h->server_retry_delay, 107 h);
108 &restart_nat_server,
109 h);
110} 108}
111 109
112 110
@@ -128,23 +126,16 @@ nat_server_read (void *cls)
128 struct sockaddr_in sin_addr; 126 struct sockaddr_in sin_addr;
129 127
130 h->server_read_task = NULL; 128 h->server_read_task = NULL;
131 memset (mybuf, 129 memset (mybuf, 0, sizeof (mybuf));
132 0, 130 bytes =
133 sizeof (mybuf)); 131 GNUNET_DISK_file_read (h->server_stdout_handle, mybuf, sizeof (mybuf));
134 bytes
135 = GNUNET_DISK_file_read (h->server_stdout_handle,
136 mybuf,
137 sizeof (mybuf));
138 if (bytes < 1) 132 if (bytes < 1)
139 { 133 {
140 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 134 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
141 "Finished reading from server stdout with code: %d\n", 135 "Finished reading from server stdout with code: %d\n",
142 (int) bytes); 136 (int) bytes);
143 if (0 != GNUNET_OS_process_kill (h->server_proc, 137 if (0 != GNUNET_OS_process_kill (h->server_proc, GNUNET_TERM_SIG))
144 GNUNET_TERM_SIG)) 138 GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_WARNING, "nat", "kill");
145 GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_WARNING,
146 "nat",
147 "kill");
148 GNUNET_OS_process_wait (h->server_proc); 139 GNUNET_OS_process_wait (h->server_proc);
149 GNUNET_OS_process_destroy (h->server_proc); 140 GNUNET_OS_process_destroy (h->server_proc);
150 h->server_proc = NULL; 141 h->server_proc = NULL;
@@ -171,44 +162,37 @@ nat_server_read (void *cls)
171 } 162 }
172 163
173 /* construct socket address of sender */ 164 /* construct socket address of sender */
174 memset (&sin_addr, 165 memset (&sin_addr, 0, sizeof (sin_addr));
175 0,
176 sizeof (sin_addr));
177 sin_addr.sin_family = AF_INET; 166 sin_addr.sin_family = AF_INET;
178#if HAVE_SOCKADDR_IN_SIN_LEN 167#if HAVE_SOCKADDR_IN_SIN_LEN
179 sin_addr.sin_len = sizeof (sin_addr); 168 sin_addr.sin_len = sizeof (sin_addr);
180#endif 169#endif
181 if ( (NULL == port_start) || 170 if ((NULL == port_start) || (1 != sscanf (port_start, "%d", &port)) ||
182 (1 != SSCANF (port_start, 171 (-1 == inet_pton (AF_INET, mybuf, &sin_addr.sin_addr)))
183 "%d",
184 &port)) ||
185 (-1 == inet_pton (AF_INET,
186 mybuf,
187 &sin_addr.sin_addr)))
188 { 172 {
189 /* should we restart gnunet-helper-nat-server? */ 173 /* should we restart gnunet-helper-nat-server? */
190 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 174 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
191 _("gnunet-helper-nat-server generated malformed address `%s'\n"), 175 _ (
192 mybuf); 176 "gnunet-helper-nat-server generated malformed address `%s'\n"),
193 h->server_read_task 177 mybuf);
194 = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, 178 h->server_read_task =
195 h->server_stdout_handle, 179 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
196 &nat_server_read, 180 h->server_stdout_handle,
197 h); 181 &nat_server_read,
182 h);
198 return; 183 return;
199 } 184 }
200 sin_addr.sin_port = htons ((uint16_t) port); 185 sin_addr.sin_port = htons ((uint16_t) port);
201 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 186 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
202 "gnunet-helper-nat-server read: %s:%d\n", 187 "gnunet-helper-nat-server read: %s:%d\n",
203 mybuf, 188 mybuf,
204 port); 189 port);
205 h->cb (h->cb_cls, 190 h->cb (h->cb_cls, &sin_addr);
206 &sin_addr); 191 h->server_read_task =
207 h->server_read_task 192 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
208 = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, 193 h->server_stdout_handle,
209 h->server_stdout_handle, 194 &nat_server_read,
210 &nat_server_read, 195 h);
211 h);
212} 196}
213 197
214 198
@@ -227,71 +211,59 @@ restart_nat_server (void *cls)
227 211
228 h->server_read_task = NULL; 212 h->server_read_task = NULL;
229 GNUNET_assert (NULL != 213 GNUNET_assert (NULL !=
230 inet_ntop (AF_INET, 214 inet_ntop (AF_INET, &h->internal_address, ia, sizeof (ia)));
231 &h->internal_address,
232 ia,
233 sizeof (ia)));
234 /* Start the server process */ 215 /* Start the server process */
235 binary = GNUNET_OS_get_suid_binary_path (h->cfg, "gnunet-helper-nat-server"); 216 binary = GNUNET_OS_get_suid_binary_path (h->cfg, "gnunet-helper-nat-server");
236 if (GNUNET_YES != 217 if (GNUNET_YES != GNUNET_OS_check_helper_binary (binary, GNUNET_YES, ia))
237 GNUNET_OS_check_helper_binary (binary,
238 GNUNET_YES,
239 ia))
240 { 218 {
241 /* move instantly to max delay, as this is unlikely to be fixed */ 219 /* move instantly to max delay, as this is unlikely to be fixed */
242 h->server_retry_delay 220 h->server_retry_delay = GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD;
243 = GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD;
244 GNUNET_free (binary); 221 GNUNET_free (binary);
245 try_again (h); 222 try_again (h);
246 return; 223 return;
247 } 224 }
248 h->server_stdout 225 h->server_stdout =
249 = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, 226 GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES);
250 GNUNET_NO, GNUNET_YES);
251 if (NULL == h->server_stdout) 227 if (NULL == h->server_stdout)
252 { 228 {
253 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, 229 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "pipe");
254 "pipe");
255 GNUNET_free (binary); 230 GNUNET_free (binary);
256 try_again (h); 231 try_again (h);
257 return; 232 return;
258 } 233 }
259 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 234 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
260 "Starting `%s' at `%s'\n", 235 "Starting `%s' at `%s'\n",
261 "gnunet-helper-nat-server", 236 "gnunet-helper-nat-server",
262 ia); 237 ia);
263 h->server_proc 238 h->server_proc = GNUNET_OS_start_process (GNUNET_NO,
264 = GNUNET_OS_start_process (GNUNET_NO, 239 0,
265 0, 240 NULL,
266 NULL, 241 h->server_stdout,
267 h->server_stdout, 242 NULL,
268 NULL, 243 binary,
269 binary, 244 "gnunet-helper-nat-server",
270 "gnunet-helper-nat-server", 245 ia,
271 ia, 246 NULL);
272 NULL);
273 GNUNET_free (binary); 247 GNUNET_free (binary);
274 if (NULL == h->server_proc) 248 if (NULL == h->server_proc)
275 { 249 {
276 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 250 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
277 _("Failed to start %s\n"), 251 _ ("Failed to start %s\n"),
278 "gnunet-helper-nat-server"); 252 "gnunet-helper-nat-server");
279 GNUNET_DISK_pipe_close (h->server_stdout); 253 GNUNET_DISK_pipe_close (h->server_stdout);
280 h->server_stdout = NULL; 254 h->server_stdout = NULL;
281 try_again (h); 255 try_again (h);
282 return; 256 return;
283 } 257 }
284 /* Close the write end of the read pipe */ 258 /* Close the write end of the read pipe */
285 GNUNET_DISK_pipe_close_end (h->server_stdout, 259 GNUNET_DISK_pipe_close_end (h->server_stdout, GNUNET_DISK_PIPE_END_WRITE);
286 GNUNET_DISK_PIPE_END_WRITE); 260 h->server_stdout_handle =
287 h->server_stdout_handle 261 GNUNET_DISK_pipe_handle (h->server_stdout, GNUNET_DISK_PIPE_END_READ);
288 = GNUNET_DISK_pipe_handle (h->server_stdout, 262 h->server_read_task =
289 GNUNET_DISK_PIPE_END_READ); 263 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
290 h->server_read_task 264 h->server_stdout_handle,
291 = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, 265 &nat_server_read,
292 h->server_stdout_handle, 266 h);
293 &nat_server_read,
294 h);
295} 267}
296 268
297 269
@@ -307,9 +279,9 @@ restart_nat_server (void *cls)
307 */ 279 */
308struct HelperContext * 280struct HelperContext *
309GN_start_gnunet_nat_server_ (const struct in_addr *internal_address, 281GN_start_gnunet_nat_server_ (const struct in_addr *internal_address,
310 GN_ReversalCallback cb, 282 GN_ReversalCallback cb,
311 void *cb_cls, 283 void *cb_cls,
312 const struct GNUNET_CONFIGURATION_Handle *cfg) 284 const struct GNUNET_CONFIGURATION_Handle *cfg)
313{ 285{
314 struct HelperContext *h; 286 struct HelperContext *h;
315 287
@@ -344,10 +316,8 @@ GN_stop_gnunet_nat_server_ (struct HelperContext *h)
344 } 316 }
345 if (NULL != h->server_proc) 317 if (NULL != h->server_proc)
346 { 318 {
347 if (0 != GNUNET_OS_process_kill (h->server_proc, 319 if (0 != GNUNET_OS_process_kill (h->server_proc, GNUNET_TERM_SIG))
348 GNUNET_TERM_SIG)) 320 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
349 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
350 "kill");
351 GNUNET_OS_process_wait (h->server_proc); 321 GNUNET_OS_process_wait (h->server_proc);
352 GNUNET_OS_process_destroy (h->server_proc); 322 GNUNET_OS_process_destroy (h->server_proc);
353 h->server_proc = NULL; 323 h->server_proc = NULL;
@@ -379,9 +349,9 @@ GN_stop_gnunet_nat_server_ (struct HelperContext *h)
379 */ 349 */
380int 350int
381GN_request_connection_reversal (const struct in_addr *internal_address, 351GN_request_connection_reversal (const struct in_addr *internal_address,
382 uint16_t internal_port, 352 uint16_t internal_port,
383 const struct in_addr *remote_v4, 353 const struct in_addr *remote_v4,
384 const struct GNUNET_CONFIGURATION_Handle *cfg) 354 const struct GNUNET_CONFIGURATION_Handle *cfg)
385{ 355{
386 char intv4[INET_ADDRSTRLEN]; 356 char intv4[INET_ADDRSTRLEN];
387 char remv4[INET_ADDRSTRLEN]; 357 char remv4[INET_ADDRSTRLEN];
@@ -389,22 +359,14 @@ GN_request_connection_reversal (const struct in_addr *internal_address,
389 struct GNUNET_OS_Process *proc; 359 struct GNUNET_OS_Process *proc;
390 char *binary; 360 char *binary;
391 361
392 if (NULL == inet_ntop (AF_INET, 362 if (NULL == inet_ntop (AF_INET, internal_address, intv4, INET_ADDRSTRLEN))
393 internal_address,
394 intv4,
395 INET_ADDRSTRLEN))
396 { 363 {
397 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, 364 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "inet_ntop");
398 "inet_ntop");
399 return GNUNET_SYSERR; 365 return GNUNET_SYSERR;
400 } 366 }
401 if (NULL == inet_ntop (AF_INET, 367 if (NULL == inet_ntop (AF_INET, remote_v4, remv4, INET_ADDRSTRLEN))
402 remote_v4,
403 remv4,
404 INET_ADDRSTRLEN))
405 { 368 {
406 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, 369 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "inet_ntop");
407 "inet_ntop");
408 return GNUNET_SYSERR; 370 return GNUNET_SYSERR;
409 } 371 }
410 GNUNET_snprintf (port_as_string, 372 GNUNET_snprintf (port_as_string,
@@ -412,23 +374,22 @@ GN_request_connection_reversal (const struct in_addr *internal_address,
412 "%d", 374 "%d",
413 internal_port); 375 internal_port);
414 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 376 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
415 "Running gnunet-helper-nat-client %s %s %u\n", 377 "Running gnunet-helper-nat-client %s %s %u\n",
416 intv4, 378 intv4,
417 remv4, 379 remv4,
418 internal_port); 380 internal_port);
419 binary = GNUNET_OS_get_suid_binary_path (cfg, "gnunet-helper-nat-client"); 381 binary = GNUNET_OS_get_suid_binary_path (cfg, "gnunet-helper-nat-client");
420 proc 382 proc = GNUNET_OS_start_process (GNUNET_NO,
421 = GNUNET_OS_start_process (GNUNET_NO, 383 0,
422 0, 384 NULL,
423 NULL, 385 NULL,
424 NULL, 386 NULL,
425 NULL, 387 binary,
426 binary, 388 "gnunet-helper-nat-client",
427 "gnunet-helper-nat-client", 389 intv4,
428 intv4, 390 remv4,
429 remv4, 391 port_as_string,
430 port_as_string, 392 NULL);
431 NULL);
432 GNUNET_free (binary); 393 GNUNET_free (binary);
433 if (NULL == proc) 394 if (NULL == proc)
434 return GNUNET_SYSERR; 395 return GNUNET_SYSERR;
diff --git a/src/nat/gnunet-service-nat_mini.c b/src/nat/gnunet-service-nat_mini.c
index c156d0eb0..375188ff2 100644
--- a/src/nat/gnunet-service-nat_mini.c
+++ b/src/nat/gnunet-service-nat_mini.c
@@ -29,7 +29,7 @@
29#include "gnunet-service-nat_mini.h" 29#include "gnunet-service-nat_mini.h"
30#include "nat.h" 30#include "nat.h"
31 31
32#define LOG(kind,...) GNUNET_log_from (kind, "nat", __VA_ARGS__) 32#define LOG(kind, ...) GNUNET_log_from (kind, "nat", __VA_ARGS__)
33 33
34/** 34/**
35 * How long do we give upnpc to create a mapping? 35 * How long do we give upnpc to create a mapping?
@@ -39,12 +39,14 @@
39/** 39/**
40 * How long do we give upnpc to remove a mapping? 40 * How long do we give upnpc to remove a mapping?
41 */ 41 */
42#define UNMAP_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1) 42#define UNMAP_TIMEOUT \
43 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1)
43 44
44/** 45/**
45 * How often do we check for changes in the mapping? 46 * How often do we check for changes in the mapping?
46 */ 47 */
47#define MAP_REFRESH_FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5) 48#define MAP_REFRESH_FREQ \
49 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
48 50
49 51
50/* ************************* external-ip calling ************************ */ 52/* ************************* external-ip calling ************************ */
@@ -117,30 +119,27 @@ read_external_ipv4 (void *cls)
117 119
118 eh->task = NULL; 120 eh->task = NULL;
119 ret = GNUNET_DISK_file_read (eh->r, 121 ret = GNUNET_DISK_file_read (eh->r,
120 &eh->buf[eh->off], 122 &eh->buf[eh->off],
121 sizeof (eh->buf) - eh->off); 123 sizeof (eh->buf) - eh->off);
122 if (ret > 0) 124 if (ret > 0)
123 { 125 {
124 /* try to read more */ 126 /* try to read more */
125 eh->off += ret; 127 eh->off += ret;
126 eh->task 128 eh->task = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
127 = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, 129 eh->r,
128 eh->r, 130 &read_external_ipv4,
129 &read_external_ipv4, 131 eh);
130 eh);
131 return; 132 return;
132 } 133 }
133 eh->ret = GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_OUTPUT_INVALID; 134 eh->ret = GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_OUTPUT_INVALID;
134 if ( (eh->off > 7) && 135 if ((eh->off > 7) && (eh->buf[eh->off - 1] == '\n'))
135 (eh->buf[eh->off - 1] == '\n') )
136 { 136 {
137 eh->buf[eh->off - 1] = '\0'; 137 eh->buf[eh->off - 1] = '\0';
138 if (1 == inet_pton (AF_INET, 138 if (1 == inet_pton (AF_INET, eh->buf, &addr))
139 eh->buf,
140 &addr))
141 { 139 {
142 if (0 == addr.s_addr) 140 if (0 == addr.s_addr)
143 eh->ret = GNUNET_NAT_ERROR_EXTERNAL_IP_ADDRESS_INVALID; /* got 0.0.0.0 */ 141 eh->ret =
142 GNUNET_NAT_ERROR_EXTERNAL_IP_ADDRESS_INVALID; /* got 0.0.0.0 */
144 else 143 else
145 eh->ret = GNUNET_NAT_ERROR_SUCCESS; 144 eh->ret = GNUNET_NAT_ERROR_SUCCESS;
146 } 145 }
@@ -163,9 +162,7 @@ signal_external_ip_error (void *cls)
163 struct GNUNET_NAT_ExternalHandle *eh = cls; 162 struct GNUNET_NAT_ExternalHandle *eh = cls;
164 163
165 eh->task = NULL; 164 eh->task = NULL;
166 eh->cb (eh->cb_cls, 165 eh->cb (eh->cb_cls, NULL, eh->ret);
167 NULL,
168 eh->ret);
169 GNUNET_free (eh); 166 GNUNET_free (eh);
170} 167}
171 168
@@ -178,8 +175,7 @@ signal_external_ip_error (void *cls)
178 * @return handle for cancellation (can only be used until @a cb is called), never NULL 175 * @return handle for cancellation (can only be used until @a cb is called), never NULL
179 */ 176 */
180struct GNUNET_NAT_ExternalHandle * 177struct GNUNET_NAT_ExternalHandle *
181GNUNET_NAT_mini_get_external_ipv4_ (GNUNET_NAT_IPCallback cb, 178GNUNET_NAT_mini_get_external_ipv4_ (GNUNET_NAT_IPCallback cb, void *cb_cls)
182 void *cb_cls)
183{ 179{
184 struct GNUNET_NAT_ExternalHandle *eh; 180 struct GNUNET_NAT_ExternalHandle *eh;
185 181
@@ -188,56 +184,43 @@ GNUNET_NAT_mini_get_external_ipv4_ (GNUNET_NAT_IPCallback cb,
188 eh->cb_cls = cb_cls; 184 eh->cb_cls = cb_cls;
189 eh->ret = GNUNET_NAT_ERROR_SUCCESS; 185 eh->ret = GNUNET_NAT_ERROR_SUCCESS;
190 if (GNUNET_SYSERR == 186 if (GNUNET_SYSERR ==
191 GNUNET_OS_check_helper_binary ("external-ip", 187 GNUNET_OS_check_helper_binary ("external-ip", GNUNET_NO, NULL))
192 GNUNET_NO,
193 NULL))
194 { 188 {
195 LOG (GNUNET_ERROR_TYPE_INFO, 189 LOG (GNUNET_ERROR_TYPE_INFO, _ ("`external-ip' command not found\n"));
196 _("`external-ip' command not found\n"));
197 eh->ret = GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_NOT_FOUND; 190 eh->ret = GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_NOT_FOUND;
198 eh->task = GNUNET_SCHEDULER_add_now (&signal_external_ip_error, 191 eh->task = GNUNET_SCHEDULER_add_now (&signal_external_ip_error, eh);
199 eh);
200 return eh; 192 return eh;
201 } 193 }
202 LOG (GNUNET_ERROR_TYPE_DEBUG, 194 LOG (GNUNET_ERROR_TYPE_DEBUG,
203 "Running `external-ip' to determine our external IP\n"); 195 "Running `external-ip' to determine our external IP\n");
204 eh->opipe = GNUNET_DISK_pipe (GNUNET_YES, 196 eh->opipe = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES);
205 GNUNET_YES,
206 GNUNET_NO,
207 GNUNET_YES);
208 if (NULL == eh->opipe) 197 if (NULL == eh->opipe)
209 { 198 {
210 eh->ret = GNUNET_NAT_ERROR_IPC_FAILURE; 199 eh->ret = GNUNET_NAT_ERROR_IPC_FAILURE;
211 eh->task = GNUNET_SCHEDULER_add_now (&signal_external_ip_error, 200 eh->task = GNUNET_SCHEDULER_add_now (&signal_external_ip_error, eh);
212 eh);
213 return eh; 201 return eh;
214 } 202 }
215 eh->eip = 203 eh->eip = GNUNET_OS_start_process (GNUNET_NO,
216 GNUNET_OS_start_process (GNUNET_NO, 204 0,
217 0, 205 NULL,
218 NULL, 206 eh->opipe,
219 eh->opipe, 207 NULL,
220 NULL, 208 "external-ip",
221 "external-ip", 209 "external-ip",
222 "external-ip", 210 NULL);
223 NULL);
224 if (NULL == eh->eip) 211 if (NULL == eh->eip)
225 { 212 {
226 GNUNET_DISK_pipe_close (eh->opipe); 213 GNUNET_DISK_pipe_close (eh->opipe);
227 eh->ret = GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_FAILED; 214 eh->ret = GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_FAILED;
228 eh->task = GNUNET_SCHEDULER_add_now (&signal_external_ip_error, 215 eh->task = GNUNET_SCHEDULER_add_now (&signal_external_ip_error, eh);
229 eh);
230 return eh; 216 return eh;
231 } 217 }
232 GNUNET_DISK_pipe_close_end (eh->opipe, 218 GNUNET_DISK_pipe_close_end (eh->opipe, GNUNET_DISK_PIPE_END_WRITE);
233 GNUNET_DISK_PIPE_END_WRITE); 219 eh->r = GNUNET_DISK_pipe_handle (eh->opipe, GNUNET_DISK_PIPE_END_READ);
234 eh->r = GNUNET_DISK_pipe_handle (eh->opipe, 220 eh->task = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
235 GNUNET_DISK_PIPE_END_READ); 221 eh->r,
236 eh->task 222 &read_external_ipv4,
237 = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, 223 eh);
238 eh->r,
239 &read_external_ipv4,
240 eh);
241 return eh; 224 return eh;
242} 225}
243 226
@@ -252,10 +235,8 @@ GNUNET_NAT_mini_get_external_ipv4_cancel_ (struct GNUNET_NAT_ExternalHandle *eh)
252{ 235{
253 if (NULL != eh->eip) 236 if (NULL != eh->eip)
254 { 237 {
255 (void) GNUNET_OS_process_kill (eh->eip, 238 (void) GNUNET_OS_process_kill (eh->eip, SIGKILL);
256 SIGKILL); 239 GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (eh->eip));
257 GNUNET_break (GNUNET_OK ==
258 GNUNET_OS_process_wait (eh->eip));
259 GNUNET_OS_process_destroy (eh->eip); 240 GNUNET_OS_process_destroy (eh->eip);
260 } 241 }
261 if (NULL != eh->opipe) 242 if (NULL != eh->opipe)
@@ -336,7 +317,6 @@ struct GNUNET_NAT_MiniHandle
336 * Which port are we mapping? 317 * Which port are we mapping?
337 */ 318 */
338 uint16_t port; 319 uint16_t port;
339
340}; 320};
341 321
342 322
@@ -356,8 +336,7 @@ do_refresh (void *cls);
356 * @param line line of output, NULL at the end 336 * @param line line of output, NULL at the end
357 */ 337 */
358static void 338static void
359process_map_output (void *cls, 339process_map_output (void *cls, const char *line);
360 const char *line);
361 340
362 341
363/** 342/**
@@ -370,26 +349,22 @@ run_upnpc_r (struct GNUNET_NAT_MiniHandle *mini)
370{ 349{
371 char pstr[6]; 350 char pstr[6];
372 351
373 GNUNET_snprintf (pstr, 352 GNUNET_snprintf (pstr, sizeof (pstr), "%u", (unsigned int) mini->port);
374 sizeof (pstr), 353 mini->map_cmd = GNUNET_OS_command_run (&process_map_output,
375 "%u", 354 mini,
376 (unsigned int) mini->port); 355 MAP_TIMEOUT,
377 mini->map_cmd 356 "upnpc",
378 = GNUNET_OS_command_run (&process_map_output, 357 "upnpc",
379 mini, 358 "-r",
380 MAP_TIMEOUT, 359 pstr,
381 "upnpc", 360 mini->is_tcp ? "tcp" : "udp",
382 "upnpc", 361 NULL);
383 "-r",
384 pstr,
385 mini->is_tcp ? "tcp" : "udp",
386 NULL);
387 if (NULL == mini->map_cmd) 362 if (NULL == mini->map_cmd)
388 { 363 {
389 mini->ac (mini->ac_cls, 364 mini->ac (mini->ac_cls,
390 GNUNET_SYSERR, 365 GNUNET_SYSERR,
391 NULL, 366 NULL,
392 0, 367 0,
393 GNUNET_NAT_ERROR_UPNPC_FAILED); 368 GNUNET_NAT_ERROR_UPNPC_FAILED);
394 return; 369 return;
395 } 370 }
@@ -404,8 +379,7 @@ run_upnpc_r (struct GNUNET_NAT_MiniHandle *mini)
404 * @param line line of output, NULL at the end 379 * @param line line of output, NULL at the end
405 */ 380 */
406static void 381static void
407process_refresh_output (void *cls, 382process_refresh_output (void *cls, const char *line)
408 const char *line)
409{ 383{
410 struct GNUNET_NAT_MiniHandle *mini = cls; 384 struct GNUNET_NAT_MiniHandle *mini = cls;
411 char pstr[9]; 385 char pstr[9];
@@ -434,31 +408,28 @@ process_refresh_output (void *cls,
434 return; 408 return;
435 } 409 }
436 if (! mini->did_map) 410 if (! mini->did_map)
437 return; /* never mapped, won't find our mapping anyway */ 411 return; /* never mapped, won't find our mapping anyway */
438 412
439 /* we're looking for output of the form: 413 /* we're looking for output of the form:
440 * "ExternalIPAddress = 12.134.41.124" */ 414 * "ExternalIPAddress = 12.134.41.124" */
441 415
442 s = strstr (line, 416 s = strstr (line, "ExternalIPAddress = ");
443 "ExternalIPAddress = ");
444 if (NULL != s) 417 if (NULL != s)
445 { 418 {
446 s += strlen ("ExternalIPAddress = "); 419 s += strlen ("ExternalIPAddress = ");
447 if (1 != inet_pton (AF_INET, 420 if (1 != inet_pton (AF_INET, s, &exip))
448 s, 421 return; /* skip */
449 &exip))
450 return; /* skip */
451 if (exip.s_addr == mini->current_addr.sin_addr.s_addr) 422 if (exip.s_addr == mini->current_addr.sin_addr.s_addr)
452 return; /* no change */ 423 return; /* no change */
453 /* update mapping */ 424 /* update mapping */
454 mini->ac (mini->ac_cls, 425 mini->ac (mini->ac_cls,
455 GNUNET_NO, 426 GNUNET_NO,
456 (const struct sockaddr *) &mini->current_addr, 427 (const struct sockaddr *) &mini->current_addr,
457 sizeof (mini->current_addr), 428 sizeof (mini->current_addr),
458 GNUNET_NAT_ERROR_SUCCESS); 429 GNUNET_NAT_ERROR_SUCCESS);
459 mini->current_addr.sin_addr = exip; 430 mini->current_addr.sin_addr = exip;
460 mini->ac (mini->ac_cls, 431 mini->ac (mini->ac_cls,
461 GNUNET_YES, 432 GNUNET_YES,
462 (const struct sockaddr *) &mini->current_addr, 433 (const struct sockaddr *) &mini->current_addr,
463 sizeof (mini->current_addr), 434 sizeof (mini->current_addr),
464 GNUNET_NAT_ERROR_SUCCESS); 435 GNUNET_NAT_ERROR_SUCCESS);
@@ -475,32 +446,29 @@ process_refresh_output (void *cls,
475 * "%s TCP PORT->STRING:OURPORT *" or 446 * "%s TCP PORT->STRING:OURPORT *" or
476 * "%s UDP PORT->STRING:OURPORT *" 447 * "%s UDP PORT->STRING:OURPORT *"
477 */ 448 */
478 GNUNET_snprintf (pstr, 449 GNUNET_snprintf (pstr, sizeof (pstr), ":%u ", mini->port);
479 sizeof (pstr),
480 ":%u ",
481 mini->port);
482 if (NULL == (s = strstr (line, "->"))) 450 if (NULL == (s = strstr (line, "->")))
483 return; /* skip */ 451 return; /* skip */
484 if (NULL == strstr (s, pstr)) 452 if (NULL == strstr (s, pstr))
485 return; /* skip */ 453 return; /* skip */
486 if (1 != 454 if (1 != sscanf (line,
487 SSCANF (line, 455 (mini->is_tcp) ? "%*u TCP %u->%*s:%*u %*s"
488 (mini->is_tcp) ? "%*u TCP %u->%*s:%*u %*s" : 456 : "%*u UDP %u->%*s:%*u %*s",
489 "%*u UDP %u->%*s:%*u %*s", &nport)) 457 &nport))
490 return; /* skip */ 458 return; /* skip */
491 mini->found = GNUNET_YES; 459 mini->found = GNUNET_YES;
492 if (nport == ntohs (mini->current_addr.sin_port)) 460 if (nport == ntohs (mini->current_addr.sin_port))
493 return; /* no change */ 461 return; /* no change */
494 462
495 /* external port changed, update mapping */ 463 /* external port changed, update mapping */
496 mini->ac (mini->ac_cls, 464 mini->ac (mini->ac_cls,
497 GNUNET_NO, 465 GNUNET_NO,
498 (const struct sockaddr *) &mini->current_addr, 466 (const struct sockaddr *) &mini->current_addr,
499 sizeof (mini->current_addr), 467 sizeof (mini->current_addr),
500 GNUNET_NAT_ERROR_SUCCESS); 468 GNUNET_NAT_ERROR_SUCCESS);
501 mini->current_addr.sin_port = htons ((uint16_t) nport); 469 mini->current_addr.sin_port = htons ((uint16_t) nport);
502 mini->ac (mini->ac_cls, 470 mini->ac (mini->ac_cls,
503 GNUNET_YES, 471 GNUNET_YES,
504 (const struct sockaddr *) &mini->current_addr, 472 (const struct sockaddr *) &mini->current_addr,
505 sizeof (mini->current_addr), 473 sizeof (mini->current_addr),
506 GNUNET_NAT_ERROR_SUCCESS); 474 GNUNET_NAT_ERROR_SUCCESS);
@@ -518,10 +486,8 @@ do_refresh (void *cls)
518 struct GNUNET_NAT_MiniHandle *mini = cls; 486 struct GNUNET_NAT_MiniHandle *mini = cls;
519 int ac; 487 int ac;
520 488
521 mini->refresh_task 489 mini->refresh_task =
522 = GNUNET_SCHEDULER_add_delayed (MAP_REFRESH_FREQ, 490 GNUNET_SCHEDULER_add_delayed (MAP_REFRESH_FREQ, &do_refresh, mini);
523 &do_refresh,
524 mini);
525 LOG (GNUNET_ERROR_TYPE_DEBUG, 491 LOG (GNUNET_ERROR_TYPE_DEBUG,
526 "Running `upnpc' to check if our mapping still exists\n"); 492 "Running `upnpc' to check if our mapping still exists\n");
527 mini->found = GNUNET_NO; 493 mini->found = GNUNET_NO;
@@ -540,19 +506,18 @@ do_refresh (void *cls)
540 mini->refresh_cmd = NULL; 506 mini->refresh_cmd = NULL;
541 ac = GNUNET_YES; 507 ac = GNUNET_YES;
542 } 508 }
543 mini->refresh_cmd 509 mini->refresh_cmd = GNUNET_OS_command_run (&process_refresh_output,
544 = GNUNET_OS_command_run (&process_refresh_output, 510 mini,
545 mini, 511 MAP_TIMEOUT,
546 MAP_TIMEOUT, 512 "upnpc",
547 "upnpc", 513 "upnpc",
548 "upnpc", 514 "-l",
549 "-l", 515 NULL);
550 NULL);
551 if (GNUNET_YES == ac) 516 if (GNUNET_YES == ac)
552 mini->ac (mini->ac_cls, 517 mini->ac (mini->ac_cls,
553 GNUNET_SYSERR, 518 GNUNET_SYSERR,
554 NULL, 519 NULL,
555 0, 520 0,
556 GNUNET_NAT_ERROR_UPNPC_TIMEOUT); 521 GNUNET_NAT_ERROR_UPNPC_TIMEOUT);
557} 522}
558 523
@@ -564,8 +529,7 @@ do_refresh (void *cls)
564 * @param line line of output, NULL at the end 529 * @param line line of output, NULL at the end
565 */ 530 */
566static void 531static void
567process_map_output (void *cls, 532process_map_output (void *cls, const char *line)
568 const char *line)
569{ 533{
570 struct GNUNET_NAT_MiniHandle *mini = cls; 534 struct GNUNET_NAT_MiniHandle *mini = cls;
571 const char *ipaddr; 535 const char *ipaddr;
@@ -581,13 +545,11 @@ process_map_output (void *cls,
581 mini->ac (mini->ac_cls, 545 mini->ac (mini->ac_cls,
582 GNUNET_SYSERR, 546 GNUNET_SYSERR,
583 NULL, 547 NULL,
584 0, 548 0,
585 GNUNET_NAT_ERROR_UPNPC_PORTMAP_FAILED); 549 GNUNET_NAT_ERROR_UPNPC_PORTMAP_FAILED);
586 if (NULL == mini->refresh_task) 550 if (NULL == mini->refresh_task)
587 mini->refresh_task 551 mini->refresh_task =
588 = GNUNET_SCHEDULER_add_delayed (MAP_REFRESH_FREQ, 552 GNUNET_SCHEDULER_add_delayed (MAP_REFRESH_FREQ, &do_refresh, mini);
589 &do_refresh,
590 mini);
591 return; 553 return;
592 } 554 }
593 /* 555 /*
@@ -597,18 +559,16 @@ process_map_output (void *cls,
597 */ 559 */
598 if ((NULL == (ipaddr = strstr (line, " "))) || 560 if ((NULL == (ipaddr = strstr (line, " "))) ||
599 (NULL == (pstr = strstr (ipaddr, ":"))) || 561 (NULL == (pstr = strstr (ipaddr, ":"))) ||
600 (1 != SSCANF (pstr + 1, "%u", &port))) 562 (1 != sscanf (pstr + 1, "%u", &port)))
601 { 563 {
602 return; /* skip line */ 564 return; /* skip line */
603 } 565 }
604 ipa = GNUNET_strdup (ipaddr + 1); 566 ipa = GNUNET_strdup (ipaddr + 1);
605 strstr (ipa, ":")[0] = '\0'; 567 strstr (ipa, ":")[0] = '\0';
606 if (1 != inet_pton (AF_INET, 568 if (1 != inet_pton (AF_INET, ipa, &mini->current_addr.sin_addr))
607 ipa,
608 &mini->current_addr.sin_addr))
609 { 569 {
610 GNUNET_free (ipa); 570 GNUNET_free (ipa);
611 return; /* skip line */ 571 return; /* skip line */
612 } 572 }
613 GNUNET_free (ipa); 573 GNUNET_free (ipa);
614 574
@@ -619,7 +579,7 @@ process_map_output (void *cls,
619#endif 579#endif
620 mini->did_map = GNUNET_YES; 580 mini->did_map = GNUNET_YES;
621 mini->ac (mini->ac_cls, 581 mini->ac (mini->ac_cls,
622 GNUNET_YES, 582 GNUNET_YES,
623 (const struct sockaddr *) &mini->current_addr, 583 (const struct sockaddr *) &mini->current_addr,
624 sizeof (mini->current_addr), 584 sizeof (mini->current_addr),
625 GNUNET_NAT_ERROR_SUCCESS); 585 GNUNET_NAT_ERROR_SUCCESS);
@@ -647,30 +607,20 @@ GNUNET_NAT_mini_map_start (uint16_t port,
647{ 607{
648 struct GNUNET_NAT_MiniHandle *ret; 608 struct GNUNET_NAT_MiniHandle *ret;
649 609
650 if (GNUNET_SYSERR == 610 if (GNUNET_SYSERR == GNUNET_OS_check_helper_binary ("upnpc", GNUNET_NO, NULL))
651 GNUNET_OS_check_helper_binary ("upnpc",
652 GNUNET_NO,
653 NULL))
654 { 611 {
655 LOG (GNUNET_ERROR_TYPE_INFO, 612 LOG (GNUNET_ERROR_TYPE_INFO, _ ("`upnpc' command not found\n"));
656 _("`upnpc' command not found\n")); 613 ac (ac_cls, GNUNET_SYSERR, NULL, 0, GNUNET_NAT_ERROR_UPNPC_NOT_FOUND);
657 ac (ac_cls,
658 GNUNET_SYSERR,
659 NULL, 0,
660 GNUNET_NAT_ERROR_UPNPC_NOT_FOUND);
661 return NULL; 614 return NULL;
662 } 615 }
663 LOG (GNUNET_ERROR_TYPE_DEBUG, 616 LOG (GNUNET_ERROR_TYPE_DEBUG, "Running `upnpc' to install mapping\n");
664 "Running `upnpc' to install mapping\n");
665 ret = GNUNET_new (struct GNUNET_NAT_MiniHandle); 617 ret = GNUNET_new (struct GNUNET_NAT_MiniHandle);
666 ret->ac = ac; 618 ret->ac = ac;
667 ret->ac_cls = ac_cls; 619 ret->ac_cls = ac_cls;
668 ret->is_tcp = is_tcp; 620 ret->is_tcp = is_tcp;
669 ret->port = port; 621 ret->port = port;
670 ret->refresh_task = 622 ret->refresh_task =
671 GNUNET_SCHEDULER_add_delayed (MAP_REFRESH_FREQ, 623 GNUNET_SCHEDULER_add_delayed (MAP_REFRESH_FREQ, &do_refresh, ret);
672 &do_refresh,
673 ret);
674 run_upnpc_r (ret); 624 run_upnpc_r (ret);
675 return ret; 625 return ret;
676} 626}
@@ -683,15 +633,13 @@ GNUNET_NAT_mini_map_start (uint16_t port,
683 * @param line line of output, NULL at the end 633 * @param line line of output, NULL at the end
684 */ 634 */
685static void 635static void
686process_unmap_output (void *cls, 636process_unmap_output (void *cls, const char *line)
687 const char *line)
688{ 637{
689 struct GNUNET_NAT_MiniHandle *mini = cls; 638 struct GNUNET_NAT_MiniHandle *mini = cls;
690 639
691 if (NULL == line) 640 if (NULL == line)
692 { 641 {
693 LOG (GNUNET_ERROR_TYPE_DEBUG, 642 LOG (GNUNET_ERROR_TYPE_DEBUG, "UPnP unmap done\n");
694 "UPnP unmap done\n");
695 GNUNET_OS_command_stop (mini->unmap_cmd); 643 GNUNET_OS_command_stop (mini->unmap_cmd);
696 mini->unmap_cmd = NULL; 644 mini->unmap_cmd = NULL;
697 GNUNET_free (mini); 645 GNUNET_free (mini);
@@ -735,7 +683,7 @@ GNUNET_NAT_mini_map_stop (struct GNUNET_NAT_MiniHandle *mini)
735 return; 683 return;
736 } 684 }
737 mini->ac (mini->ac_cls, 685 mini->ac (mini->ac_cls,
738 GNUNET_NO, 686 GNUNET_NO,
739 (const struct sockaddr *) &mini->current_addr, 687 (const struct sockaddr *) &mini->current_addr,
740 sizeof (mini->current_addr), 688 sizeof (mini->current_addr),
741 GNUNET_NAT_ERROR_SUCCESS); 689 GNUNET_NAT_ERROR_SUCCESS);
@@ -749,16 +697,15 @@ GNUNET_NAT_mini_map_stop (struct GNUNET_NAT_MiniHandle *mini)
749 LOG (GNUNET_ERROR_TYPE_DEBUG, 697 LOG (GNUNET_ERROR_TYPE_DEBUG,
750 "Unmapping port %u with UPnP\n", 698 "Unmapping port %u with UPnP\n",
751 ntohs (mini->current_addr.sin_port)); 699 ntohs (mini->current_addr.sin_port));
752 mini->unmap_cmd 700 mini->unmap_cmd = GNUNET_OS_command_run (&process_unmap_output,
753 = GNUNET_OS_command_run (&process_unmap_output, 701 mini,
754 mini, 702 UNMAP_TIMEOUT,
755 UNMAP_TIMEOUT, 703 "upnpc",
756 "upnpc", 704 "upnpc",
757 "upnpc", 705 "-d",
758 "-d", 706 pstr,
759 pstr, 707 mini->is_tcp ? "tcp" : "udp",
760 mini->is_tcp ? "tcp" : "udp", 708 NULL);
761 NULL);
762} 709}
763 710
764 711