aboutsummaryrefslogtreecommitdiff
path: root/src/nat
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-08-15 21:46:35 +0000
committerChristian Grothoff <christian@grothoff.org>2011-08-15 21:46:35 +0000
commit502af2167f7c218366666ca4944bd7cc54b5b19a (patch)
treea91fec5cc9769d260640bd91c6633cb9cf395524 /src/nat
parent03af5a603b7cc53432249d5854cd412aa90dde0d (diff)
downloadgnunet-502af2167f7c218366666ca4944bd7cc54b5b19a.tar.gz
gnunet-502af2167f7c218366666ca4944bd7cc54b5b19a.zip
indentation
Diffstat (limited to 'src/nat')
-rw-r--r--src/nat/gnunet-helper-nat-client-windows.c303
-rw-r--r--src/nat/gnunet-helper-nat-client.c278
-rw-r--r--src/nat/gnunet-helper-nat-server-windows.c419
-rw-r--r--src/nat/gnunet-helper-nat-server.c401
-rw-r--r--src/nat/gnunet-nat-server.c200
-rw-r--r--src/nat/nat.c1187
-rw-r--r--src/nat/nat.h6
-rw-r--r--src/nat/nat_mini.c423
-rw-r--r--src/nat/nat_test.c289
-rw-r--r--src/nat/test_nat.c32
-rw-r--r--src/nat/test_nat_mini.c34
-rw-r--r--src/nat/test_nat_test.c34
12 files changed, 1594 insertions, 2012 deletions
diff --git a/src/nat/gnunet-helper-nat-client-windows.c b/src/nat/gnunet-helper-nat-client-windows.c
index 0717eecfe..0fa62ff7c 100644
--- a/src/nat/gnunet-helper-nat-client-windows.c
+++ b/src/nat/gnunet-helper-nat-client-windows.c
@@ -193,19 +193,14 @@ static uint16_t port;
193 * @return 1 on success 193 * @return 1 on success
194 */ 194 */
195static int 195static int
196inet_pton (int af, 196inet_pton (int af, const char *cp, struct in_addr *buf)
197 const char *cp,
198 struct in_addr *buf)
199{ 197{
200 buf->s_addr = inet_addr(cp); 198 buf->s_addr = inet_addr (cp);
201 if (buf->s_addr == INADDR_NONE) 199 if (buf->s_addr == INADDR_NONE)
202 { 200 {
203 fprintf(stderr, 201 fprintf (stderr, "Error %d handling address %s", WSAGetLastError (), cp);
204 "Error %d handling address %s", 202 return 0;
205 WSAGetLastError(), 203 }
206 cp);
207 return 0;
208 }
209 return 1; 204 return 1;
210} 205}
211 206
@@ -218,17 +213,16 @@ inet_pton (int af,
218 * @return the CRC 16. 213 * @return the CRC 16.
219 */ 214 */
220static uint16_t 215static uint16_t
221calc_checksum(const uint16_t *data, 216calc_checksum (const uint16_t * data, unsigned int bytes)
222 unsigned int bytes)
223{ 217{
224 uint32_t sum; 218 uint32_t sum;
225 unsigned int i; 219 unsigned int i;
226 220
227 sum = 0; 221 sum = 0;
228 for (i=0;i<bytes/2;i++) 222 for (i = 0; i < bytes / 2; i++)
229 sum += data[i]; 223 sum += data[i];
230 sum = (sum & 0xffff) + (sum >> 16); 224 sum = (sum & 0xffff) + (sum >> 16);
231 sum = htons(0xffff - sum); 225 sum = htons (0xffff - sum);
232 return sum; 226 return sum;
233} 227}
234 228
@@ -240,12 +234,11 @@ calc_checksum(const uint16_t *data,
240 * @param other target address 234 * @param other target address
241 */ 235 */
242static void 236static void
243send_icmp_udp (const struct in_addr *my_ip, 237send_icmp_udp (const struct in_addr *my_ip, const struct in_addr *other)
244 const struct in_addr *other)
245{ 238{
246 char packet[sizeof(struct ip_header) * 2 + 239 char packet[sizeof (struct ip_header) * 2 +
247 sizeof(struct icmp_ttl_exceeded_header) + 240 sizeof (struct icmp_ttl_exceeded_header) +
248 sizeof(struct udp_header)]; 241 sizeof (struct udp_header)];
249 struct ip_header ip_pkt; 242 struct ip_header ip_pkt;
250 struct icmp_ttl_exceeded_header icmp_pkt; 243 struct icmp_ttl_exceeded_header icmp_pkt;
251 struct udp_header udp_pkt; 244 struct udp_header udp_pkt;
@@ -257,86 +250,74 @@ send_icmp_udp (const struct in_addr *my_ip,
257 off = 0; 250 off = 0;
258 ip_pkt.vers_ihl = 0x45; 251 ip_pkt.vers_ihl = 0x45;
259 ip_pkt.tos = 0; 252 ip_pkt.tos = 0;
260 ip_pkt.pkt_len = htons(sizeof (packet)); 253 ip_pkt.pkt_len = htons (sizeof (packet));
261 ip_pkt.id = htons(256); 254 ip_pkt.id = htons (256);
262 ip_pkt.flags_frag_offset = 0; 255 ip_pkt.flags_frag_offset = 0;
263 ip_pkt.ttl = 128; 256 ip_pkt.ttl = 128;
264 ip_pkt.proto = IPPROTO_ICMP; 257 ip_pkt.proto = IPPROTO_ICMP;
265 ip_pkt.checksum = 0; 258 ip_pkt.checksum = 0;
266 ip_pkt.src_ip = my_ip->s_addr; 259 ip_pkt.src_ip = my_ip->s_addr;
267 ip_pkt.dst_ip = other->s_addr; 260 ip_pkt.dst_ip = other->s_addr;
268 ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, 261 ip_pkt.checksum = htons (calc_checksum ((uint16_t *) & ip_pkt,
269 sizeof (struct ip_header))); 262 sizeof (struct ip_header)));
270 memcpy(&packet[off], 263 memcpy (&packet[off], &ip_pkt, sizeof (struct ip_header));
271 &ip_pkt, 264 off += sizeof (struct ip_header);
272 sizeof(struct ip_header));
273 off += sizeof(struct ip_header);
274 265
275 icmp_pkt.type = ICMP_TIME_EXCEEDED; 266 icmp_pkt.type = ICMP_TIME_EXCEEDED;
276 icmp_pkt.code = 0; 267 icmp_pkt.code = 0;
277 icmp_pkt.checksum = 0; 268 icmp_pkt.checksum = 0;
278 icmp_pkt.unused = 0; 269 icmp_pkt.unused = 0;
279 memcpy(&packet[off], 270 memcpy (&packet[off], &icmp_pkt, sizeof (struct icmp_ttl_exceeded_header));
280 &icmp_pkt, 271 off += sizeof (struct icmp_ttl_exceeded_header);
281 sizeof(struct icmp_ttl_exceeded_header));
282 off += sizeof(struct icmp_ttl_exceeded_header);
283 272
284 /* ip header of the presumably 'lost' udp packet */ 273 /* ip header of the presumably 'lost' udp packet */
285 ip_pkt.vers_ihl = 0x45; 274 ip_pkt.vers_ihl = 0x45;
286 ip_pkt.tos = 0; 275 ip_pkt.tos = 0;
287 ip_pkt.pkt_len = htons(sizeof (struct ip_header) + 276 ip_pkt.pkt_len = htons (sizeof (struct ip_header) +
288 sizeof (struct udp_header)); 277 sizeof (struct udp_header));
289 ip_pkt.id = htons(0); 278 ip_pkt.id = htons (0);
290 ip_pkt.flags_frag_offset = 0; 279 ip_pkt.flags_frag_offset = 0;
291 ip_pkt.ttl = 128; 280 ip_pkt.ttl = 128;
292 ip_pkt.proto = IPPROTO_UDP; 281 ip_pkt.proto = IPPROTO_UDP;
293 ip_pkt.checksum = 0; 282 ip_pkt.checksum = 0;
294 ip_pkt.src_ip = other->s_addr; 283 ip_pkt.src_ip = other->s_addr;
295 ip_pkt.dst_ip = dummy.s_addr; 284 ip_pkt.dst_ip = dummy.s_addr;
296 ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, 285 ip_pkt.checksum = htons (calc_checksum ((uint16_t *) & ip_pkt,
297 sizeof (struct ip_header))); 286 sizeof (struct ip_header)));
298 memcpy(&packet[off], 287 memcpy (&packet[off], &ip_pkt, sizeof (struct ip_header));
299 &ip_pkt, 288 off += sizeof (struct ip_header);
300 sizeof(struct ip_header));
301 off += sizeof(struct ip_header);
302 289
303 /* build UDP header */ 290 /* build UDP header */
304 udp_pkt.src_port = htons(NAT_TRAV_PORT); 291 udp_pkt.src_port = htons (NAT_TRAV_PORT);
305 udp_pkt.dst_port = htons(NAT_TRAV_PORT); 292 udp_pkt.dst_port = htons (NAT_TRAV_PORT);
306 udp_pkt.length = htons (port); 293 udp_pkt.length = htons (port);
307 udp_pkt.crc = 0; 294 udp_pkt.crc = 0;
308 memcpy(&packet[off], 295 memcpy (&packet[off], &udp_pkt, sizeof (struct udp_header));
309 &udp_pkt, 296 off += sizeof (struct udp_header);
310 sizeof(struct udp_header));
311 off += sizeof(struct udp_header);
312 297
313 /* no go back to calculate ICMP packet checksum */ 298 /* no go back to calculate ICMP packet checksum */
314 icmp_pkt.checksum = htons(calc_checksum((uint16_t*)&packet[off], 299 icmp_pkt.checksum = htons (calc_checksum ((uint16_t *) & packet[off],
315 sizeof (struct icmp_ttl_exceeded_header) + 300 sizeof (struct
316 sizeof (struct ip_header) + 301 icmp_ttl_exceeded_header) +
317 sizeof (struct udp_header))); 302 sizeof (struct ip_header) +
318 memcpy (&packet[sizeof (struct ip_header)], 303 sizeof (struct udp_header)));
319 &icmp_pkt, 304 memcpy (&packet[sizeof (struct ip_header)], &icmp_pkt,
320 sizeof (struct icmp_ttl_exceeded_header)); 305 sizeof (struct icmp_ttl_exceeded_header));
321 306
322 memset (&dst, 0, sizeof (dst)); 307 memset (&dst, 0, sizeof (dst));
323 dst.sin_family = AF_INET; 308 dst.sin_family = AF_INET;
324 dst.sin_addr = *other; 309 dst.sin_addr = *other;
325 err = sendto(rawsock, 310 err = sendto (rawsock,
326 packet, 311 packet,
327 sizeof (packet), 0, 312 sizeof (packet), 0, (struct sockaddr *) &dst, sizeof (dst));
328 (struct sockaddr*)&dst,
329 sizeof(dst));
330 if (err < 0) 313 if (err < 0)
331 { 314 {
332 fprintf(stderr, 315 fprintf (stderr, "sendto failed: %s\n", strerror (errno));
333 "sendto failed: %s\n", strerror(errno)); 316 }
334 }
335 else if (sizeof (packet) != (size_t) err) 317 else if (sizeof (packet) != (size_t) err)
336 { 318 {
337 fprintf(stderr, 319 fprintf (stderr, "Error: partial send of ICMP message\n");
338 "Error: partial send of ICMP message\n"); 320 }
339 }
340} 321}
341 322
342 323
@@ -347,16 +328,15 @@ send_icmp_udp (const struct in_addr *my_ip,
347 * @param other target address 328 * @param other target address
348 */ 329 */
349static void 330static void
350send_icmp (const struct in_addr *my_ip, 331send_icmp (const struct in_addr *my_ip, const struct in_addr *other)
351 const struct in_addr *other)
352{ 332{
353 struct ip_header ip_pkt; 333 struct ip_header ip_pkt;
354 struct icmp_ttl_exceeded_header icmp_ttl; 334 struct icmp_ttl_exceeded_header icmp_ttl;
355 struct icmp_echo_header icmp_echo; 335 struct icmp_echo_header icmp_echo;
356 struct sockaddr_in dst; 336 struct sockaddr_in dst;
357 char packet[sizeof (struct ip_header) * 2 + 337 char packet[sizeof (struct ip_header) * 2 +
358 sizeof (struct icmp_ttl_exceeded_header) + 338 sizeof (struct icmp_ttl_exceeded_header) +
359 sizeof(struct icmp_echo_header)]; 339 sizeof (struct icmp_echo_header)];
360 size_t off; 340 size_t off;
361 int err; 341 int err;
362 342
@@ -365,88 +345,76 @@ send_icmp (const struct in_addr *my_ip,
365 ip_pkt.vers_ihl = 0x45; 345 ip_pkt.vers_ihl = 0x45;
366 ip_pkt.tos = 0; 346 ip_pkt.tos = 0;
367 ip_pkt.pkt_len = htons (sizeof (packet)); 347 ip_pkt.pkt_len = htons (sizeof (packet));
368 ip_pkt.id = htons(256); 348 ip_pkt.id = htons (256);
369 ip_pkt.flags_frag_offset = 0; 349 ip_pkt.flags_frag_offset = 0;
370 ip_pkt.ttl = IPDEFTTL; 350 ip_pkt.ttl = IPDEFTTL;
371 ip_pkt.proto = IPPROTO_ICMP; 351 ip_pkt.proto = IPPROTO_ICMP;
372 ip_pkt.checksum = 0; 352 ip_pkt.checksum = 0;
373 ip_pkt.src_ip = my_ip->s_addr; 353 ip_pkt.src_ip = my_ip->s_addr;
374 ip_pkt.dst_ip = other->s_addr; 354 ip_pkt.dst_ip = other->s_addr;
375 ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, 355 ip_pkt.checksum = htons (calc_checksum ((uint16_t *) & ip_pkt,
376 sizeof (struct ip_header))); 356 sizeof (struct ip_header)));
377 memcpy (&packet[off], 357 memcpy (&packet[off], &ip_pkt, sizeof (struct ip_header));
378 &ip_pkt,
379 sizeof (struct ip_header));
380 off += sizeof (ip_pkt); 358 off += sizeof (ip_pkt);
381 359
382 /* icmp reply: time exceeded */ 360 /* icmp reply: time exceeded */
383 icmp_ttl.type = ICMP_TIME_EXCEEDED; 361 icmp_ttl.type = ICMP_TIME_EXCEEDED;
384 icmp_ttl.code = 0; 362 icmp_ttl.code = 0;
385 icmp_ttl.checksum = 0; 363 icmp_ttl.checksum = 0;
386 icmp_ttl.unused = 0; 364 icmp_ttl.unused = 0;
387 memcpy (&packet[off], 365 memcpy (&packet[off], &icmp_ttl, sizeof (struct icmp_ttl_exceeded_header));
388 &icmp_ttl,
389 sizeof (struct icmp_ttl_exceeded_header));
390 off += sizeof (struct icmp_ttl_exceeded_header); 366 off += sizeof (struct icmp_ttl_exceeded_header);
391 367
392 /* ip header of the presumably 'lost' udp packet */ 368 /* ip header of the presumably 'lost' udp packet */
393 ip_pkt.vers_ihl = 0x45; 369 ip_pkt.vers_ihl = 0x45;
394 ip_pkt.tos = 0; 370 ip_pkt.tos = 0;
395 ip_pkt.pkt_len = htons(sizeof (struct ip_header) + sizeof (struct icmp_echo_header)); 371 ip_pkt.pkt_len =
372 htons (sizeof (struct ip_header) + sizeof (struct icmp_echo_header));
396 ip_pkt.id = htons (256); 373 ip_pkt.id = htons (256);
397 ip_pkt.flags_frag_offset = 0; 374 ip_pkt.flags_frag_offset = 0;
398 ip_pkt.ttl = 1; /* real TTL would be 1 on a time exceeded packet */ 375 ip_pkt.ttl = 1; /* real TTL would be 1 on a time exceeded packet */
399 ip_pkt.proto = IPPROTO_ICMP; 376 ip_pkt.proto = IPPROTO_ICMP;
400 ip_pkt.src_ip = other->s_addr; 377 ip_pkt.src_ip = other->s_addr;
401 ip_pkt.dst_ip = dummy.s_addr; 378 ip_pkt.dst_ip = dummy.s_addr;
402 ip_pkt.checksum = 0; 379 ip_pkt.checksum = 0;
403 ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, 380 ip_pkt.checksum = htons (calc_checksum ((uint16_t *) & ip_pkt,
404 sizeof (struct ip_header))); 381 sizeof (struct ip_header)));
405 memcpy (&packet[off], 382 memcpy (&packet[off], &ip_pkt, sizeof (struct ip_header));
406 &ip_pkt,
407 sizeof (struct ip_header));
408 off += sizeof (struct ip_header); 383 off += sizeof (struct ip_header);
409 384
410 icmp_echo.type = ICMP_ECHO; 385 icmp_echo.type = ICMP_ECHO;
411 icmp_echo.code = 0; 386 icmp_echo.code = 0;
412 icmp_echo.reserved = htonl(port); 387 icmp_echo.reserved = htonl (port);
413 icmp_echo.checksum = 0; 388 icmp_echo.checksum = 0;
414 icmp_echo.checksum = htons(calc_checksum((uint16_t*) &icmp_echo, 389 icmp_echo.checksum = htons (calc_checksum ((uint16_t *) & icmp_echo,
415 sizeof (struct icmp_echo_header))); 390 sizeof (struct icmp_echo_header)));
416 memcpy (&packet[off], 391 memcpy (&packet[off], &icmp_echo, sizeof (struct icmp_echo_header));
417 &icmp_echo,
418 sizeof(struct icmp_echo_header));
419 392
420 /* no go back to calculate ICMP packet checksum */ 393 /* no go back to calculate ICMP packet checksum */
421 off = sizeof (struct ip_header); 394 off = sizeof (struct ip_header);
422 icmp_ttl.checksum = htons(calc_checksum((uint16_t*) &packet[off], 395 icmp_ttl.checksum = htons (calc_checksum ((uint16_t *) & packet[off],
423 sizeof (struct icmp_ttl_exceeded_header) + 396 sizeof (struct
424 sizeof (struct ip_header) + 397 icmp_ttl_exceeded_header) +
425 sizeof (struct icmp_echo_header))); 398 sizeof (struct ip_header) +
426 memcpy (&packet[off], 399 sizeof (struct icmp_echo_header)));
427 &icmp_ttl, 400 memcpy (&packet[off], &icmp_ttl, sizeof (struct icmp_ttl_exceeded_header));
428 sizeof (struct icmp_ttl_exceeded_header));
429 401
430 memset (&dst, 0, sizeof (dst)); 402 memset (&dst, 0, sizeof (dst));
431 dst.sin_family = AF_INET; 403 dst.sin_family = AF_INET;
432 dst.sin_addr = *other; 404 dst.sin_addr = *other;
433 405
434 err = sendto(rawsock, 406 err = sendto (rawsock,
435 packet, 407 packet,
436 sizeof (packet), 0, 408 sizeof (packet), 0, (struct sockaddr *) &dst, sizeof (dst));
437 (struct sockaddr*)&dst,
438 sizeof(dst));
439 409
440 if (err < 0) 410 if (err < 0)
441 { 411 {
442 fprintf(stderr, 412 fprintf (stderr, "sendto failed: %s\n", strerror (errno));
443 "sendto failed: %s\n", strerror(errno)); 413 }
444 }
445 else if (sizeof (packet) != (size_t) err) 414 else if (sizeof (packet) != (size_t) err)
446 { 415 {
447 fprintf(stderr, 416 fprintf (stderr, "Error: partial send of ICMP message\n");
448 "Error: partial send of ICMP message\n"); 417 }
449 }
450} 418}
451 419
452 420
@@ -459,34 +427,30 @@ static SOCKET
459make_raw_socket () 427make_raw_socket ()
460{ 428{
461 DWORD bOptVal = TRUE; 429 DWORD bOptVal = TRUE;
462 int bOptLen = sizeof(bOptVal); 430 int bOptLen = sizeof (bOptVal);
463 SOCKET ret; 431 SOCKET ret;
464 432
465 ret = socket (AF_INET, SOCK_RAW, IPPROTO_RAW); 433 ret = socket (AF_INET, SOCK_RAW, IPPROTO_RAW);
466 if (INVALID_SOCKET == ret) 434 if (INVALID_SOCKET == ret)
467 { 435 {
468 fprintf (stderr, 436 fprintf (stderr, "Error opening RAW socket: %s\n", strerror (errno));
469 "Error opening RAW socket: %s\n", 437 return INVALID_SOCKET;
470 strerror (errno)); 438 }
471 return INVALID_SOCKET; 439 if (0 !=
472 } 440 setsockopt (ret, SOL_SOCKET, SO_BROADCAST, (char *) &bOptVal, bOptLen))
473 if (0 != setsockopt(ret, SOL_SOCKET, SO_BROADCAST, (char*)&bOptVal, bOptLen)) 441 {
474 { 442 fprintf (stderr,
475 fprintf(stderr, 443 "Error setting SO_BROADCAST to ON: %s\n", strerror (errno));
476 "Error setting SO_BROADCAST to ON: %s\n", 444 closesocket (rawsock);
477 strerror (errno)); 445 return INVALID_SOCKET;
478 closesocket(rawsock); 446 }
479 return INVALID_SOCKET; 447
480 } 448 if (0 != setsockopt (ret, IPPROTO_IP, IP_HDRINCL, (char *) &bOptVal, bOptLen))
481 449 {
482 if (0 != setsockopt(ret, IPPROTO_IP, IP_HDRINCL, (char*)&bOptVal, bOptLen)) 450 fprintf (stderr, "Error setting IP_HDRINCL to ON: %s\n", strerror (errno));
483 { 451 closesocket (rawsock);
484 fprintf(stderr, 452 return INVALID_SOCKET;
485 "Error setting IP_HDRINCL to ON: %s\n", 453 }
486 strerror (errno));
487 closesocket(rawsock);
488 return INVALID_SOCKET;
489 }
490 return ret; 454 return ret;
491} 455}
492 456
@@ -501,47 +465,38 @@ main (int argc, char *const *argv)
501 unsigned int p; 465 unsigned int p;
502 466
503 if (argc != 4) 467 if (argc != 4)
504 { 468 {
505 fprintf (stderr, 469 fprintf (stderr,
506 "This program must be started with our IP, the targets external IP, and our port as arguments.\n"); 470 "This program must be started with our IP, the targets external IP, and our port as arguments.\n");
507 return 1; 471 return 1;
508 } 472 }
509 if ( (1 != inet_pton (AF_INET, argv[1], &external)) || 473 if ((1 != inet_pton (AF_INET, argv[1], &external)) ||
510 (1 != inet_pton (AF_INET, argv[2], &target)) ) 474 (1 != inet_pton (AF_INET, argv[2], &target)))
511 { 475 {
512 fprintf (stderr, 476 fprintf (stderr, "Error parsing IPv4 address: %s\n", strerror (errno));
513 "Error parsing IPv4 address: %s\n", 477 return 1;
514 strerror (errno)); 478 }
515 return 1; 479 if ((1 != sscanf (argv[3], "%u", &p)) || (0 == p) || (0xFFFF < p))
516 } 480 {
517 if ( (1 != sscanf (argv[3], "%u", &p) ) || 481 fprintf (stderr, "Error parsing port value `%s'\n", argv[3]);
518 (0 == p) || 482 return 1;
519 (0xFFFF < p) ) 483 }
520 {
521 fprintf (stderr,
522 "Error parsing port value `%s'\n",
523 argv[3]);
524 return 1;
525 }
526 port = (uint16_t) p; 484 port = (uint16_t) p;
527 485
528 if (0 != WSAStartup (MAKEWORD (2, 1), &wsaData)) 486 if (0 != WSAStartup (MAKEWORD (2, 1), &wsaData))
529 { 487 {
530 fprintf (stderr, "Failed to find Winsock 2.1 or better.\n"); 488 fprintf (stderr, "Failed to find Winsock 2.1 or better.\n");
531 return 2; 489 return 2;
532 } 490 }
533 if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy)) 491 if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy))
534 { 492 {
535 fprintf (stderr, 493 fprintf (stderr, "Internal error converting dummy IP to binary.\n");
536 "Internal error converting dummy IP to binary.\n"); 494 return 2;
537 return 2; 495 }
538 } 496 if (-1 == (rawsock = make_raw_socket ()))
539 if (-1 == (rawsock = make_raw_socket()))
540 return 3; 497 return 3;
541 send_icmp (&external, 498 send_icmp (&external, &target);
542 &target); 499 send_icmp_udp (&external, &target);
543 send_icmp_udp (&external,
544 &target);
545 closesocket (rawsock); 500 closesocket (rawsock);
546 WSACleanup (); 501 WSACleanup ();
547 return 0; 502 return 0;
diff --git a/src/nat/gnunet-helper-nat-client.c b/src/nat/gnunet-helper-nat-client.c
index 10aa2f438..76f405bf1 100644
--- a/src/nat/gnunet-helper-nat-client.c
+++ b/src/nat/gnunet-helper-nat-client.c
@@ -190,17 +190,16 @@ static uint16_t port;
190 * @return the CRC 16. 190 * @return the CRC 16.
191 */ 191 */
192static uint16_t 192static uint16_t
193calc_checksum (const uint16_t *data, 193calc_checksum (const uint16_t * data, unsigned int bytes)
194 unsigned int bytes)
195{ 194{
196 uint32_t sum; 195 uint32_t sum;
197 unsigned int i; 196 unsigned int i;
198 197
199 sum = 0; 198 sum = 0;
200 for (i=0;i<bytes/2;i++) 199 for (i = 0; i < bytes / 2; i++)
201 sum += data[i]; 200 sum += data[i];
202 sum = (sum & 0xffff) + (sum >> 16); 201 sum = (sum & 0xffff) + (sum >> 16);
203 sum = htons(0xffff - sum); 202 sum = htons (0xffff - sum);
204 return sum; 203 return sum;
205} 204}
206 205
@@ -212,12 +211,11 @@ calc_checksum (const uint16_t *data,
212 * @param other target address 211 * @param other target address
213 */ 212 */
214static void 213static void
215send_icmp_udp (const struct in_addr *my_ip, 214send_icmp_udp (const struct in_addr *my_ip, const struct in_addr *other)
216 const struct in_addr *other)
217{ 215{
218 char packet[sizeof(struct ip_header) * 2 + 216 char packet[sizeof (struct ip_header) * 2 +
219 sizeof(struct icmp_ttl_exceeded_header) + 217 sizeof (struct icmp_ttl_exceeded_header) +
220 sizeof(struct udp_header)]; 218 sizeof (struct udp_header)];
221 struct ip_header ip_pkt; 219 struct ip_header ip_pkt;
222 struct icmp_ttl_exceeded_header icmp_pkt; 220 struct icmp_ttl_exceeded_header icmp_pkt;
223 struct udp_header udp_pkt; 221 struct udp_header udp_pkt;
@@ -230,66 +228,58 @@ send_icmp_udp (const struct in_addr *my_ip,
230 ip_pkt.vers_ihl = 0x45; 228 ip_pkt.vers_ihl = 0x45;
231 ip_pkt.tos = 0; 229 ip_pkt.tos = 0;
232 ip_pkt.pkt_len = htons (sizeof (packet)); 230 ip_pkt.pkt_len = htons (sizeof (packet));
233 ip_pkt.id = htons(256); 231 ip_pkt.id = htons (256);
234 ip_pkt.flags_frag_offset = 0; 232 ip_pkt.flags_frag_offset = 0;
235 ip_pkt.ttl = 128; 233 ip_pkt.ttl = 128;
236 ip_pkt.proto = IPPROTO_ICMP; 234 ip_pkt.proto = IPPROTO_ICMP;
237 ip_pkt.checksum = 0; 235 ip_pkt.checksum = 0;
238 ip_pkt.src_ip = my_ip->s_addr; 236 ip_pkt.src_ip = my_ip->s_addr;
239 ip_pkt.dst_ip = other->s_addr; 237 ip_pkt.dst_ip = other->s_addr;
240 ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, 238 ip_pkt.checksum = htons (calc_checksum ((uint16_t *) & ip_pkt,
241 sizeof (struct ip_header))); 239 sizeof (struct ip_header)));
242 memcpy(&packet[off], 240 memcpy (&packet[off], &ip_pkt, sizeof (struct ip_header));
243 &ip_pkt, 241 off += sizeof (struct ip_header);
244 sizeof(struct ip_header));
245 off += sizeof(struct ip_header);
246 242
247 icmp_pkt.type = ICMP_TIME_EXCEEDED; 243 icmp_pkt.type = ICMP_TIME_EXCEEDED;
248 icmp_pkt.code = 0; 244 icmp_pkt.code = 0;
249 icmp_pkt.checksum = 0; 245 icmp_pkt.checksum = 0;
250 icmp_pkt.unused = 0; 246 icmp_pkt.unused = 0;
251 memcpy(&packet[off], 247 memcpy (&packet[off], &icmp_pkt, sizeof (struct icmp_ttl_exceeded_header));
252 &icmp_pkt, 248 off += sizeof (struct icmp_ttl_exceeded_header);
253 sizeof(struct icmp_ttl_exceeded_header));
254 off += sizeof(struct icmp_ttl_exceeded_header);
255 249
256 /* ip header of the presumably 'lost' udp packet */ 250 /* ip header of the presumably 'lost' udp packet */
257 ip_pkt.vers_ihl = 0x45; 251 ip_pkt.vers_ihl = 0x45;
258 ip_pkt.tos = 0; 252 ip_pkt.tos = 0;
259 ip_pkt.pkt_len = htons(sizeof (struct ip_header) + 253 ip_pkt.pkt_len = htons (sizeof (struct ip_header) +
260 sizeof (struct udp_header)); 254 sizeof (struct udp_header));
261 ip_pkt.id = htons(0); 255 ip_pkt.id = htons (0);
262 ip_pkt.flags_frag_offset = 0; 256 ip_pkt.flags_frag_offset = 0;
263 ip_pkt.ttl = 128; 257 ip_pkt.ttl = 128;
264 ip_pkt.proto = IPPROTO_UDP; 258 ip_pkt.proto = IPPROTO_UDP;
265 ip_pkt.checksum = 0; 259 ip_pkt.checksum = 0;
266 ip_pkt.src_ip = other->s_addr; 260 ip_pkt.src_ip = other->s_addr;
267 ip_pkt.dst_ip = dummy.s_addr; 261 ip_pkt.dst_ip = dummy.s_addr;
268 ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, 262 ip_pkt.checksum = htons (calc_checksum ((uint16_t *) & ip_pkt,
269 sizeof (struct ip_header))); 263 sizeof (struct ip_header)));
270 memcpy(&packet[off], 264 memcpy (&packet[off], &ip_pkt, sizeof (struct ip_header));
271 &ip_pkt, 265 off += sizeof (struct ip_header);
272 sizeof(struct ip_header));
273 off += sizeof(struct ip_header);
274 266
275 /* build UDP header */ 267 /* build UDP header */
276 udp_pkt.src_port = htons(NAT_TRAV_PORT); 268 udp_pkt.src_port = htons (NAT_TRAV_PORT);
277 udp_pkt.dst_port = htons(NAT_TRAV_PORT); 269 udp_pkt.dst_port = htons (NAT_TRAV_PORT);
278 udp_pkt.length = htons (port); 270 udp_pkt.length = htons (port);
279 udp_pkt.crc = 0; 271 udp_pkt.crc = 0;
280 memcpy(&packet[off], 272 memcpy (&packet[off], &udp_pkt, sizeof (struct udp_header));
281 &udp_pkt, 273 off += sizeof (struct udp_header);
282 sizeof(struct udp_header));
283 off += sizeof(struct udp_header);
284 274
285 /* set ICMP checksum */ 275 /* set ICMP checksum */
286 icmp_pkt.checksum = htons(calc_checksum((uint16_t*)&packet[sizeof(struct ip_header)], 276 icmp_pkt.checksum =
287 sizeof (struct icmp_ttl_exceeded_header) + 277 htons (calc_checksum
288 sizeof (struct ip_header) + 278 ((uint16_t *) & packet[sizeof (struct ip_header)],
289 sizeof (struct udp_header))); 279 sizeof (struct icmp_ttl_exceeded_header) +
290 memcpy (&packet[sizeof(struct ip_header)], 280 sizeof (struct ip_header) + sizeof (struct udp_header)));
291 &icmp_pkt, 281 memcpy (&packet[sizeof (struct ip_header)], &icmp_pkt,
292 sizeof (struct icmp_ttl_exceeded_header)); 282 sizeof (struct icmp_ttl_exceeded_header));
293 283
294 memset (&dst, 0, sizeof (dst)); 284 memset (&dst, 0, sizeof (dst));
295 dst.sin_family = AF_INET; 285 dst.sin_family = AF_INET;
@@ -297,21 +287,17 @@ send_icmp_udp (const struct in_addr *my_ip,
297 dst.sin_len = sizeof (struct sockaddr_in); 287 dst.sin_len = sizeof (struct sockaddr_in);
298#endif 288#endif
299 dst.sin_addr = *other; 289 dst.sin_addr = *other;
300 err = sendto(rawsock, 290 err = sendto (rawsock,
301 packet, 291 packet,
302 sizeof (packet), 0, 292 sizeof (packet), 0, (struct sockaddr *) &dst, sizeof (dst));
303 (struct sockaddr*)&dst,
304 sizeof(dst));
305 if (err < 0) 293 if (err < 0)
306 { 294 {
307 fprintf(stderr, 295 fprintf (stderr, "sendto failed: %s\n", strerror (errno));
308 "sendto failed: %s\n", strerror(errno)); 296 }
309 }
310 else if (sizeof (packet) != (size_t) err) 297 else if (sizeof (packet) != (size_t) err)
311 { 298 {
312 fprintf(stderr, 299 fprintf (stderr, "Error: partial send of ICMP message\n");
313 "Error: partial send of ICMP message\n"); 300 }
314 }
315} 301}
316 302
317 303
@@ -322,16 +308,15 @@ send_icmp_udp (const struct in_addr *my_ip,
322 * @param other target address 308 * @param other target address
323 */ 309 */
324static void 310static void
325send_icmp (const struct in_addr *my_ip, 311send_icmp (const struct in_addr *my_ip, const struct in_addr *other)
326 const struct in_addr *other)
327{ 312{
328 struct ip_header ip_pkt; 313 struct ip_header ip_pkt;
329 struct icmp_ttl_exceeded_header icmp_ttl; 314 struct icmp_ttl_exceeded_header icmp_ttl;
330 struct icmp_echo_header icmp_echo; 315 struct icmp_echo_header icmp_echo;
331 struct sockaddr_in dst; 316 struct sockaddr_in dst;
332 char packet[sizeof (struct ip_header) * 2 + 317 char packet[sizeof (struct ip_header) * 2 +
333 sizeof (struct icmp_ttl_exceeded_header) + 318 sizeof (struct icmp_ttl_exceeded_header) +
334 sizeof (struct icmp_echo_header)]; 319 sizeof (struct icmp_echo_header)];
335 size_t off; 320 size_t off;
336 int err; 321 int err;
337 322
@@ -347,11 +332,9 @@ send_icmp (const struct in_addr *my_ip,
347 ip_pkt.checksum = 0; 332 ip_pkt.checksum = 0;
348 ip_pkt.src_ip = my_ip->s_addr; 333 ip_pkt.src_ip = my_ip->s_addr;
349 ip_pkt.dst_ip = other->s_addr; 334 ip_pkt.dst_ip = other->s_addr;
350 ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, 335 ip_pkt.checksum = htons (calc_checksum ((uint16_t *) & ip_pkt,
351 sizeof (struct ip_header))); 336 sizeof (struct ip_header)));
352 memcpy (&packet[off], 337 memcpy (&packet[off], &ip_pkt, sizeof (struct ip_header));
353 &ip_pkt,
354 sizeof (struct ip_header));
355 off = sizeof (ip_pkt); 338 off = sizeof (ip_pkt);
356 339
357 /* icmp reply: time exceeded */ 340 /* icmp reply: time exceeded */
@@ -359,48 +342,42 @@ send_icmp (const struct in_addr *my_ip,
359 icmp_ttl.code = 0; 342 icmp_ttl.code = 0;
360 icmp_ttl.checksum = 0; 343 icmp_ttl.checksum = 0;
361 icmp_ttl.unused = 0; 344 icmp_ttl.unused = 0;
362 memcpy (&packet[off], 345 memcpy (&packet[off], &icmp_ttl, sizeof (struct icmp_ttl_exceeded_header));
363 &icmp_ttl,
364 sizeof (struct icmp_ttl_exceeded_header));
365 off += sizeof (struct icmp_ttl_exceeded_header); 346 off += sizeof (struct icmp_ttl_exceeded_header);
366 347
367 /* ip header of the presumably 'lost' udp packet */ 348 /* ip header of the presumably 'lost' udp packet */
368 ip_pkt.vers_ihl = 0x45; 349 ip_pkt.vers_ihl = 0x45;
369 ip_pkt.tos = 0; 350 ip_pkt.tos = 0;
370 ip_pkt.pkt_len = htons (sizeof (struct ip_header) + sizeof (struct icmp_echo_header)); 351 ip_pkt.pkt_len =
352 htons (sizeof (struct ip_header) + sizeof (struct icmp_echo_header));
371 ip_pkt.id = htons (256); 353 ip_pkt.id = htons (256);
372 ip_pkt.flags_frag_offset = 0; 354 ip_pkt.flags_frag_offset = 0;
373 ip_pkt.ttl = 1; /* real TTL would be 1 on a time exceeded packet */ 355 ip_pkt.ttl = 1; /* real TTL would be 1 on a time exceeded packet */
374 ip_pkt.proto = IPPROTO_ICMP; 356 ip_pkt.proto = IPPROTO_ICMP;
375 ip_pkt.src_ip = other->s_addr; 357 ip_pkt.src_ip = other->s_addr;
376 ip_pkt.dst_ip = dummy.s_addr; 358 ip_pkt.dst_ip = dummy.s_addr;
377 ip_pkt.checksum = 0; 359 ip_pkt.checksum = 0;
378 ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, 360 ip_pkt.checksum = htons (calc_checksum ((uint16_t *) & ip_pkt,
379 sizeof (struct ip_header))); 361 sizeof (struct ip_header)));
380 memcpy (&packet[off], 362 memcpy (&packet[off], &ip_pkt, sizeof (struct ip_header));
381 &ip_pkt,
382 sizeof (struct ip_header));
383 off += sizeof (struct ip_header); 363 off += sizeof (struct ip_header);
384 364
385 icmp_echo.type = ICMP_ECHO; 365 icmp_echo.type = ICMP_ECHO;
386 icmp_echo.code = 0; 366 icmp_echo.code = 0;
387 icmp_echo.reserved = htonl (port); 367 icmp_echo.reserved = htonl (port);
388 icmp_echo.checksum = 0; 368 icmp_echo.checksum = 0;
389 icmp_echo.checksum = htons(calc_checksum((uint16_t*) &icmp_echo, 369 icmp_echo.checksum = htons (calc_checksum ((uint16_t *) & icmp_echo,
390 sizeof (struct icmp_echo_header))); 370 sizeof (struct icmp_echo_header)));
391 memcpy (&packet[off], 371 memcpy (&packet[off], &icmp_echo, sizeof (struct icmp_echo_header));
392 &icmp_echo,
393 sizeof(struct icmp_echo_header));
394 372
395 /* no go back to calculate ICMP packet checksum */ 373 /* no go back to calculate ICMP packet checksum */
396 off = sizeof (struct ip_header); 374 off = sizeof (struct ip_header);
397 icmp_ttl.checksum = htons(calc_checksum((uint16_t*) &packet[off], 375 icmp_ttl.checksum = htons (calc_checksum ((uint16_t *) & packet[off],
398 sizeof (struct icmp_ttl_exceeded_header) + 376 sizeof (struct
399 sizeof (struct ip_header) + 377 icmp_ttl_exceeded_header) +
400 sizeof (struct icmp_echo_header))); 378 sizeof (struct ip_header) +
401 memcpy (&packet[off], 379 sizeof (struct icmp_echo_header)));
402 &icmp_ttl, 380 memcpy (&packet[off], &icmp_ttl, sizeof (struct icmp_ttl_exceeded_header));
403 sizeof (struct icmp_ttl_exceeded_header));
404 381
405 /* prepare for transmission */ 382 /* prepare for transmission */
406 memset (&dst, 0, sizeof (dst)); 383 memset (&dst, 0, sizeof (dst));
@@ -409,21 +386,17 @@ send_icmp (const struct in_addr *my_ip,
409 dst.sin_len = sizeof (struct sockaddr_in); 386 dst.sin_len = sizeof (struct sockaddr_in);
410#endif 387#endif
411 dst.sin_addr = *other; 388 dst.sin_addr = *other;
412 err = sendto(rawsock, 389 err = sendto (rawsock,
413 packet, 390 packet,
414 sizeof (packet), 0, 391 sizeof (packet), 0, (struct sockaddr *) &dst, sizeof (dst));
415 (struct sockaddr*)&dst,
416 sizeof(dst));
417 if (err < 0) 392 if (err < 0)
418 { 393 {
419 fprintf(stderr, 394 fprintf (stderr, "sendto failed: %s\n", strerror (errno));
420 "sendto failed: %s\n", strerror(errno)); 395 }
421 }
422 else if (sizeof (packet) != (size_t) err) 396 else if (sizeof (packet) != (size_t) err)
423 { 397 {
424 fprintf(stderr, 398 fprintf (stderr, "Error: partial send of ICMP message\n");
425 "Error: partial send of ICMP message\n"); 399 }
426 }
427} 400}
428 401
429 402
@@ -440,30 +413,24 @@ make_raw_socket ()
440 413
441 ret = socket (AF_INET, SOCK_RAW, IPPROTO_RAW); 414 ret = socket (AF_INET, SOCK_RAW, IPPROTO_RAW);
442 if (-1 == ret) 415 if (-1 == ret)
443 { 416 {
444 fprintf (stderr, 417 fprintf (stderr, "Error opening RAW socket: %s\n", strerror (errno));
445 "Error opening RAW socket: %s\n", 418 return -1;
446 strerror (errno)); 419 }
447 return -1; 420 if (0 != setsockopt (ret, SOL_SOCKET, SO_BROADCAST,
448 } 421 (char *) &one, sizeof (one)))
449 if (0 != setsockopt(ret, SOL_SOCKET, SO_BROADCAST, 422 {
450 (char *)&one, sizeof(one))) 423 fprintf (stderr, "setsockopt failed: %s\n", strerror (errno));
451 { 424 close (ret);
452 fprintf(stderr, 425 return -1;
453 "setsockopt failed: %s\n", 426 }
454 strerror (errno)); 427 if (0 != setsockopt (ret, IPPROTO_IP, IP_HDRINCL,
455 close (ret); 428 (char *) &one, sizeof (one)))
456 return -1; 429 {
457 } 430 fprintf (stderr, "setsockopt failed: %s\n", strerror (errno));
458 if (0 != setsockopt(ret, IPPROTO_IP, IP_HDRINCL, 431 close (ret);
459 (char *)&one, sizeof(one))) 432 return -1;
460 { 433 }
461 fprintf(stderr,
462 "setsockopt failed: %s\n",
463 strerror (errno));
464 close (ret);
465 return -1;
466 }
467 return ret; 434 return ret;
468} 435}
469 436
@@ -477,49 +444,38 @@ main (int argc, char *const *argv)
477 unsigned int p; 444 unsigned int p;
478 445
479 if (4 != argc) 446 if (4 != argc)
480 { 447 {
481 fprintf (stderr, 448 fprintf (stderr,
482 "This program must be started with our IP, the targets external IP, and our port as arguments.\n"); 449 "This program must be started with our IP, the targets external IP, and our port as arguments.\n");
483 return 1; 450 return 1;
484 } 451 }
485 if ( (1 != inet_pton (AF_INET, argv[1], &external)) || 452 if ((1 != inet_pton (AF_INET, argv[1], &external)) ||
486 (1 != inet_pton (AF_INET, argv[2], &target)) ) 453 (1 != inet_pton (AF_INET, argv[2], &target)))
487 { 454 {
488 fprintf (stderr, 455 fprintf (stderr, "Error parsing IPv4 address: %s\n", strerror (errno));
489 "Error parsing IPv4 address: %s\n", 456 return 1;
490 strerror (errno)); 457 }
491 return 1; 458 if ((1 != sscanf (argv[3], "%u", &p)) || (0 == p) || (0xFFFF < p))
492 } 459 {
493 if ( (1 != sscanf (argv[3], "%u", &p) ) || 460 fprintf (stderr, "Error parsing port value `%s'\n", argv[3]);
494 (0 == p) || 461 return 1;
495 (0xFFFF < p) ) 462 }
496 {
497 fprintf (stderr,
498 "Error parsing port value `%s'\n",
499 argv[3]);
500 return 1;
501 }
502 port = (uint16_t) p; 463 port = (uint16_t) p;
503 if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy)) 464 if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy))
504 { 465 {
505 fprintf (stderr, 466 fprintf (stderr, "Internal error converting dummy IP to binary.\n");
506 "Internal error converting dummy IP to binary.\n"); 467 return 2;
507 return 2; 468 }
508 } 469 if (-1 == (rawsock = make_raw_socket ()))
509 if (-1 == (rawsock = make_raw_socket()))
510 return 2; 470 return 2;
511 uid = getuid (); 471 uid = getuid ();
512 if (0 != setresuid (uid, uid, uid)) 472 if (0 != setresuid (uid, uid, uid))
513 { 473 {
514 fprintf (stderr, 474 fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
515 "Failed to setresuid: %s\n", 475 /* not critical, continue anyway */
516 strerror (errno)); 476 }
517 /* not critical, continue anyway */ 477 send_icmp (&external, &target);
518 } 478 send_icmp_udp (&external, &target);
519 send_icmp (&external,
520 &target);
521 send_icmp_udp (&external,
522 &target);
523 close (rawsock); 479 close (rawsock);
524 return 0; 480 return 0;
525} 481}
diff --git a/src/nat/gnunet-helper-nat-server-windows.c b/src/nat/gnunet-helper-nat-server-windows.c
index 7a607c62d..727a7be67 100644
--- a/src/nat/gnunet-helper-nat-server-windows.c
+++ b/src/nat/gnunet-helper-nat-server-windows.c
@@ -118,12 +118,12 @@ struct ip_header
118 /** 118 /**
119 * Time to live 119 * Time to live
120 */ 120 */
121 uint8_t ttl; 121 uint8_t ttl;
122 122
123 /** 123 /**
124 * Protocol 124 * Protocol
125 */ 125 */
126 uint8_t proto; 126 uint8_t proto;
127 127
128 /** 128 /**
129 * Header checksum 129 * Header checksum
@@ -133,12 +133,12 @@ struct ip_header
133 /** 133 /**
134 * Source address 134 * Source address
135 */ 135 */
136 uint32_t src_ip; 136 uint32_t src_ip;
137 137
138 /** 138 /**
139 * Destination address 139 * Destination address
140 */ 140 */
141 uint32_t dst_ip; 141 uint32_t dst_ip;
142}; 142};
143 143
144/** 144/**
@@ -211,17 +211,16 @@ static struct in_addr dummy;
211 * @return the CRC 16. 211 * @return the CRC 16.
212 */ 212 */
213static uint16_t 213static uint16_t
214calc_checksum(const uint16_t *data, 214calc_checksum (const uint16_t * data, unsigned int bytes)
215 unsigned int bytes)
216{ 215{
217 uint32_t sum; 216 uint32_t sum;
218 unsigned int i; 217 unsigned int i;
219 218
220 sum = 0; 219 sum = 0;
221 for (i=0;i<bytes/2;i++) 220 for (i = 0; i < bytes / 2; i++)
222 sum += data[i]; 221 sum += data[i];
223 sum = (sum & 0xffff) + (sum >> 16); 222 sum = (sum & 0xffff) + (sum >> 16);
224 sum = htons(0xffff - sum); 223 sum = htons (0xffff - sum);
225 return sum; 224 return sum;
226} 225}
227 226
@@ -235,19 +234,14 @@ calc_checksum(const uint16_t *data,
235 * @return 1 on success 234 * @return 1 on success
236 */ 235 */
237static int 236static int
238inet_pton (int af, 237inet_pton (int af, const char *cp, struct in_addr *buf)
239 const char *cp,
240 struct in_addr *buf)
241{ 238{
242 buf->s_addr = inet_addr(cp); 239 buf->s_addr = inet_addr (cp);
243 if (buf->s_addr == INADDR_NONE) 240 if (buf->s_addr == INADDR_NONE)
244 { 241 {
245 fprintf(stderr, 242 fprintf (stderr, "Error %d handling address %s", WSAGetLastError (), cp);
246 "Error %d handling address %s", 243 return 0;
247 WSAGetLastError(), 244 }
248 cp);
249 return 0;
250 }
251 return 1; 245 return 1;
252} 246}
253 247
@@ -278,43 +272,35 @@ send_icmp_echo (const struct in_addr *my_ip)
278 ip_pkt.checksum = 0; 272 ip_pkt.checksum = 0;
279 ip_pkt.src_ip = my_ip->s_addr; 273 ip_pkt.src_ip = my_ip->s_addr;
280 ip_pkt.dst_ip = dummy.s_addr; 274 ip_pkt.dst_ip = dummy.s_addr;
281 ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, 275 ip_pkt.checksum = htons (calc_checksum ((uint16_t *) & ip_pkt,
282 sizeof (struct ip_header))); 276 sizeof (struct ip_header)));
283 memcpy (&packet[off], 277 memcpy (&packet[off], &ip_pkt, sizeof (struct ip_header));
284 &ip_pkt,
285 sizeof (struct ip_header));
286 off += sizeof (struct ip_header); 278 off += sizeof (struct ip_header);
287 279
288 icmp_echo.type = ICMP_ECHO; 280 icmp_echo.type = ICMP_ECHO;
289 icmp_echo.code = 0; 281 icmp_echo.code = 0;
290 icmp_echo.reserved = 0; 282 icmp_echo.reserved = 0;
291 icmp_echo.checksum = 0; 283 icmp_echo.checksum = 0;
292 icmp_echo.checksum = htons(calc_checksum((uint16_t*) &icmp_echo, 284 icmp_echo.checksum = htons (calc_checksum ((uint16_t *) & icmp_echo,
293 sizeof (struct icmp_echo_header))); 285 sizeof (struct icmp_echo_header)));
294 memcpy (&packet[off], 286 memcpy (&packet[off], &icmp_echo, sizeof (struct icmp_echo_header));
295 &icmp_echo,
296 sizeof (struct icmp_echo_header));
297 off += sizeof (struct icmp_echo_header); 287 off += sizeof (struct icmp_echo_header);
298 288
299 memset (&dst, 0, sizeof (dst)); 289 memset (&dst, 0, sizeof (dst));
300 dst.sin_family = AF_INET; 290 dst.sin_family = AF_INET;
301 dst.sin_addr = dummy; 291 dst.sin_addr = dummy;
302 err = sendto(rawsock, 292 err = sendto (rawsock,
303 packet, off, 0, 293 packet, off, 0, (struct sockaddr *) &dst, sizeof (dst));
304 (struct sockaddr*)&dst,
305 sizeof(dst));
306 if (err < 0) 294 if (err < 0)
307 { 295 {
308#if VERBOSE 296#if VERBOSE
309 fprintf(stderr, 297 fprintf (stderr, "sendto failed: %s\n", strerror (errno));
310 "sendto failed: %s\n", strerror(errno));
311#endif 298#endif
312 } 299 }
313 else if (err != off) 300 else if (err != off)
314 { 301 {
315 fprintf(stderr, 302 fprintf (stderr, "Error: partial send of ICMP message\n");
316 "Error: partial send of ICMP message\n"); 303 }
317 }
318} 304}
319 305
320 306
@@ -331,22 +317,17 @@ send_udp ()
331 dst.sin_family = AF_INET; 317 dst.sin_family = AF_INET;
332 dst.sin_addr = dummy; 318 dst.sin_addr = dummy;
333 dst.sin_port = htons (NAT_TRAV_PORT); 319 dst.sin_port = htons (NAT_TRAV_PORT);
334 err = sendto(udpsock, 320 err = sendto (udpsock, NULL, 0, 0, (struct sockaddr *) &dst, sizeof (dst));
335 NULL, 0, 0,
336 (struct sockaddr*)&dst,
337 sizeof(dst));
338 if (err < 0) 321 if (err < 0)
339 { 322 {
340#if VERBOSE 323#if VERBOSE
341 fprintf(stderr, 324 fprintf (stderr, "sendto failed: %s\n", strerror (errno));
342 "sendto failed: %s\n", strerror(errno));
343#endif 325#endif
344 } 326 }
345 else if (0 != err) 327 else if (0 != err)
346 { 328 {
347 fprintf(stderr, 329 fprintf (stderr, "Error: partial send of ICMP message\n");
348 "Error: partial send of ICMP message\n"); 330 }
349 }
350} 331}
351 332
352 333
@@ -369,96 +350,74 @@ process_icmp_response ()
369 350
370 have = read (icmpsock, buf, sizeof (buf)); 351 have = read (icmpsock, buf, sizeof (buf));
371 if (have == -1) 352 if (have == -1)
372 { 353 {
373 fprintf (stderr, 354 fprintf (stderr, "Error reading raw socket: %s\n", strerror (errno));
374 "Error reading raw socket: %s\n", 355 return;
375 strerror (errno)); 356 }
376 return;
377 }
378#if VERBOSE 357#if VERBOSE
379 fprintf (stderr, 358 fprintf (stderr, "Received message of %u bytes\n", (unsigned int) have);
380 "Received message of %u bytes\n",
381 (unsigned int) have);
382#endif 359#endif
383 if (have < (ssize_t) (sizeof (struct ip_header) + sizeof (struct icmp_ttl_exceeded_header) + sizeof (struct ip_header))) 360 if (have <
384 { 361 (ssize_t) (sizeof (struct ip_header) +
385 /* malformed */ 362 sizeof (struct icmp_ttl_exceeded_header) +
386 return; 363 sizeof (struct ip_header)))
387 } 364 {
365 /* malformed */
366 return;
367 }
388 off = 0; 368 off = 0;
389 memcpy (&ip_pkt, 369 memcpy (&ip_pkt, &buf[off], sizeof (struct ip_header));
390 &buf[off],
391 sizeof (struct ip_header));
392 off += sizeof (struct ip_header); 370 off += sizeof (struct ip_header);
393 memcpy(&source_ip, 371 memcpy (&source_ip, &ip_pkt.src_ip, sizeof (source_ip));
394 &ip_pkt.src_ip, 372 memcpy (&icmp_ttl, &buf[off], sizeof (struct icmp_ttl_exceeded_header));
395 sizeof (source_ip));
396 memcpy (&icmp_ttl,
397 &buf[off],
398 sizeof (struct icmp_ttl_exceeded_header));
399 off += sizeof (struct icmp_ttl_exceeded_header); 373 off += sizeof (struct icmp_ttl_exceeded_header);
400 if ( (ICMP_TIME_EXCEEDED != icmp_ttl.type) || 374 if ((ICMP_TIME_EXCEEDED != icmp_ttl.type) || (0 != icmp_ttl.code))
401 (0 != icmp_ttl.code) ) 375 {
402 { 376 /* different type than what we want */
403 /* different type than what we want */ 377 return;
404 return; 378 }
405 }
406 /* skip 2nd IP header */ 379 /* skip 2nd IP header */
407 memcpy (&ip_pkt, 380 memcpy (&ip_pkt, &buf[off], sizeof (struct ip_header));
408 &buf[off],
409 sizeof (struct ip_header));
410 off += sizeof (struct ip_header); 381 off += sizeof (struct ip_header);
411 382
412 switch (ip_pkt.proto) 383 switch (ip_pkt.proto)
384 {
385 case IPPROTO_ICMP:
386 if (have != (sizeof (struct ip_header) * 2 +
387 sizeof (struct icmp_ttl_exceeded_header) +
388 sizeof (struct icmp_echo_header)))
413 { 389 {
414 case IPPROTO_ICMP: 390 /* malformed */
415 if (have != (sizeof (struct ip_header) * 2 +
416 sizeof (struct icmp_ttl_exceeded_header) +
417 sizeof (struct icmp_echo_header)) )
418 {
419 /* malformed */
420 return;
421 }
422 /* grab ICMP ECHO content */
423 memcpy (&icmp_echo,
424 &buf[off],
425 sizeof (struct icmp_echo_header));
426 port = (uint16_t) ntohl (icmp_echo.reserved);
427 break;
428 case IPPROTO_UDP:
429 if (have != (sizeof (struct ip_header) * 2 +
430 sizeof (struct icmp_ttl_exceeded_header) +
431 sizeof (struct udp_header)) )
432 {
433 /* malformed */
434 return;
435 }
436 /* grab UDP content */
437 memcpy (&udp_pkt,
438 &buf[off],
439 sizeof (struct udp_header));
440 port = ntohs (udp_pkt.length);
441 break;
442 default:
443 /* different type than what we want */
444 return; 391 return;
445 } 392 }
446 393 /* grab ICMP ECHO content */
447 ssize = sizeof(buf); 394 memcpy (&icmp_echo, &buf[off], sizeof (struct icmp_echo_header));
448 WSAAddressToString((LPSOCKADDR)&source_ip, 395 port = (uint16_t) ntohl (icmp_echo.reserved);
449 sizeof(source_ip), 396 break;
450 NULL, 397 case IPPROTO_UDP:
451 buf, 398 if (have != (sizeof (struct ip_header) * 2 +
452 &ssize); 399 sizeof (struct icmp_ttl_exceeded_header) +
400 sizeof (struct udp_header)))
401 {
402 /* malformed */
403 return;
404 }
405 /* grab UDP content */
406 memcpy (&udp_pkt, &buf[off], sizeof (struct udp_header));
407 port = ntohs (udp_pkt.length);
408 break;
409 default:
410 /* different type than what we want */
411 return;
412 }
413
414 ssize = sizeof (buf);
415 WSAAddressToString ((LPSOCKADDR) & source_ip,
416 sizeof (source_ip), NULL, buf, &ssize);
453 if (port == 0) 417 if (port == 0)
454 fprintf (stdout, 418 fprintf (stdout, "%s\n", buf);
455 "%s\n",
456 buf);
457 else 419 else
458 fprintf (stdout, 420 fprintf (stdout, "%s:%u\n", buf, (unsigned int) port);
459 "%s:%u\n",
460 buf,
461 (unsigned int) port);
462 fflush (stdout); 421 fflush (stdout);
463} 422}
464 423
@@ -475,12 +434,10 @@ make_icmp_socket ()
475 434
476 ret = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP); 435 ret = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP);
477 if (INVALID_SOCKET == ret) 436 if (INVALID_SOCKET == ret)
478 { 437 {
479 fprintf (stderr, 438 fprintf (stderr, "Error opening RAW socket: %s\n", strerror (errno));
480 "Error opening RAW socket: %s\n", 439 return INVALID_SOCKET;
481 strerror (errno)); 440 }
482 return INVALID_SOCKET;
483 }
484 return ret; 441 return ret;
485} 442}
486 443
@@ -494,39 +451,30 @@ static SOCKET
494make_raw_socket () 451make_raw_socket ()
495{ 452{
496 DWORD bOptVal = TRUE; 453 DWORD bOptVal = TRUE;
497 int bOptLen = sizeof(bOptVal); 454 int bOptLen = sizeof (bOptVal);
498 455
499 rawsock = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP); 456 rawsock = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP);
500 if (INVALID_SOCKET == rawsock) 457 if (INVALID_SOCKET == rawsock)
501 { 458 {
502 fprintf (stderr, 459 fprintf (stderr, "Error opening RAW socket: %s\n", strerror (errno));
503 "Error opening RAW socket: %s\n", 460 return INVALID_SOCKET;
504 strerror (errno)); 461 }
505 return INVALID_SOCKET; 462
506 } 463 if (0 != setsockopt (rawsock,
507 464 SOL_SOCKET, SO_BROADCAST, (char *) &bOptVal, bOptLen))
508 if (0 != setsockopt(rawsock, 465 {
509 SOL_SOCKET, 466 fprintf (stderr,
510 SO_BROADCAST, 467 "Error setting SO_BROADCAST to ON: %s\n", strerror (errno));
511 (char*)&bOptVal, bOptLen)) 468 closesocket (rawsock);
512 { 469 return INVALID_SOCKET;
513 fprintf(stderr, 470 }
514 "Error setting SO_BROADCAST to ON: %s\n", 471 if (0 != setsockopt (rawsock,
515 strerror (errno)); 472 IPPROTO_IP, IP_HDRINCL, (char *) &bOptVal, bOptLen))
516 closesocket(rawsock); 473 {
517 return INVALID_SOCKET; 474 fprintf (stderr, "Error setting IP_HDRINCL to ON: %s\n", strerror (errno));
518 } 475 closesocket (rawsock);
519 if (0 != setsockopt(rawsock, 476 return INVALID_SOCKET;
520 IPPROTO_IP, 477 }
521 IP_HDRINCL,
522 (char*)&bOptVal, bOptLen))
523 {
524 fprintf(stderr,
525 "Error setting IP_HDRINCL to ON: %s\n",
526 strerror (errno));
527 closesocket(rawsock);
528 return INVALID_SOCKET;
529 }
530 return rawsock; 478 return rawsock;
531} 479}
532 480
@@ -545,33 +493,27 @@ make_udp_socket (const struct in_addr *my_ip)
545 493
546 ret = socket (AF_INET, SOCK_DGRAM, 0); 494 ret = socket (AF_INET, SOCK_DGRAM, 0);
547 if (INVALID_SOCKET == ret) 495 if (INVALID_SOCKET == ret)
548 { 496 {
549 fprintf (stderr, 497 fprintf (stderr, "Error opening UDP socket: %s\n", strerror (errno));
550 "Error opening UDP socket: %s\n", 498 return INVALID_SOCKET;
551 strerror (errno)); 499 }
552 return INVALID_SOCKET;
553 }
554 memset (&addr, 0, sizeof (addr)); 500 memset (&addr, 0, sizeof (addr));
555 addr.sin_family = AF_INET; 501 addr.sin_family = AF_INET;
556 addr.sin_addr = *my_ip; 502 addr.sin_addr = *my_ip;
557 addr.sin_port = htons (NAT_TRAV_PORT); 503 addr.sin_port = htons (NAT_TRAV_PORT);
558 if (0 != bind (ret, 504 if (0 != bind (ret, (struct sockaddr *) &addr, sizeof (addr)))
559 (struct sockaddr *)&addr, 505 {
560 sizeof(addr))) 506 fprintf (stderr,
561 { 507 "Error binding UDP socket to port %u: %s\n",
562 fprintf (stderr, 508 NAT_TRAV_PORT, strerror (errno));
563 "Error binding UDP socket to port %u: %s\n", 509 /* likely problematic, but not certain, try to continue */
564 NAT_TRAV_PORT, 510 }
565 strerror (errno));
566 /* likely problematic, but not certain, try to continue */
567 }
568 return ret; 511 return ret;
569} 512}
570 513
571 514
572int 515int
573main (int argc, 516main (int argc, char *const *argv)
574 char *const *argv)
575{ 517{
576 struct in_addr external; 518 struct in_addr external;
577 fd_set rs; 519 fd_set rs;
@@ -581,70 +523,67 @@ main (int argc,
581 523
582 alt = 0; 524 alt = 0;
583 if (2 != argc) 525 if (2 != argc)
584 { 526 {
585 fprintf (stderr, 527 fprintf (stderr,
586 "This program must be started with our (internal NAT) IP as the only argument.\n"); 528 "This program must be started with our (internal NAT) IP as the only argument.\n");
587 return 1; 529 return 1;
588 } 530 }
589 if (1 != inet_pton (AF_INET, argv[1], &external)) 531 if (1 != inet_pton (AF_INET, argv[1], &external))
590 { 532 {
591 fprintf (stderr, 533 fprintf (stderr,
592 "Error parsing IPv4 address: %s, error %s\n", 534 "Error parsing IPv4 address: %s, error %s\n",
593 argv[1], strerror (errno)); 535 argv[1], strerror (errno));
594 return 1; 536 return 1;
595 } 537 }
596 if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy)) 538 if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy))
597 { 539 {
598 fprintf (stderr, 540 fprintf (stderr, "Internal error converting dummy IP to binary.\n");
599 "Internal error converting dummy IP to binary.\n"); 541 return 2;
600 return 2; 542 }
601 }
602 if (WSAStartup (MAKEWORD (2, 1), &wsaData) != 0) 543 if (WSAStartup (MAKEWORD (2, 1), &wsaData) != 0)
603 { 544 {
604 fprintf (stderr, "Failed to find Winsock 2.1 or better.\n"); 545 fprintf (stderr, "Failed to find Winsock 2.1 or better.\n");
605 return 2; 546 return 2;
606 } 547 }
607 if (INVALID_SOCKET == (icmpsock = make_icmp_socket())) 548 if (INVALID_SOCKET == (icmpsock = make_icmp_socket ()))
608 { 549 {
609 return 3; 550 return 3;
610 } 551 }
611 if (INVALID_SOCKET == (make_raw_socket())) 552 if (INVALID_SOCKET == (make_raw_socket ()))
612 { 553 {
613 closesocket (icmpsock); 554 closesocket (icmpsock);
614 return 3; 555 return 3;
615 } 556 }
616 if (INVALID_SOCKET == (udpsock = make_udp_socket(&external))) 557 if (INVALID_SOCKET == (udpsock = make_udp_socket (&external)))
617 { 558 {
618 closesocket (icmpsock); 559 closesocket (icmpsock);
619 closesocket (rawsock); 560 closesocket (rawsock);
620 return 3; 561 return 3;
621 } 562 }
622 while (1) 563 while (1)
564 {
565 FD_ZERO (&rs);
566 FD_SET (icmpsock, &rs);
567 tv.tv_sec = 0;
568 tv.tv_usec = ICMP_SEND_FREQUENCY_MS * 1000;
569 if (-1 == select (icmpsock + 1, &rs, NULL, NULL, &tv))
623 { 570 {
624 FD_ZERO (&rs); 571 if (errno == EINTR)
625 FD_SET (icmpsock, &rs); 572 continue;
626 tv.tv_sec = 0; 573 fprintf (stderr, "select failed: %s\n", strerror (errno));
627 tv.tv_usec = ICMP_SEND_FREQUENCY_MS * 1000; 574 break;
628 if (-1 == select (icmpsock + 1, &rs, NULL, NULL, &tv))
629 {
630 if (errno == EINTR)
631 continue;
632 fprintf (stderr,
633 "select failed: %s\n",
634 strerror (errno));
635 break;
636 }
637 if (FD_ISSET (icmpsock, &rs))
638 process_icmp_response ();
639 if (0 == (++alt % 2))
640 send_icmp_echo (&external);
641 else
642 send_udp ();
643 } 575 }
576 if (FD_ISSET (icmpsock, &rs))
577 process_icmp_response ();
578 if (0 == (++alt % 2))
579 send_icmp_echo (&external);
580 else
581 send_udp ();
582 }
644 /* select failed (internal error or OS out of resources) */ 583 /* select failed (internal error or OS out of resources) */
645 closesocket(icmpsock); 584 closesocket (icmpsock);
646 closesocket(rawsock); 585 closesocket (rawsock);
647 closesocket(udpsock); 586 closesocket (udpsock);
648 WSACleanup (); 587 WSACleanup ();
649 return 4; 588 return 4;
650} 589}
diff --git a/src/nat/gnunet-helper-nat-server.c b/src/nat/gnunet-helper-nat-server.c
index 945c98735..636ae6003 100644
--- a/src/nat/gnunet-helper-nat-server.c
+++ b/src/nat/gnunet-helper-nat-server.c
@@ -212,17 +212,16 @@ static struct in_addr dummy;
212 * @return the CRC 16. 212 * @return the CRC 16.
213 */ 213 */
214static uint16_t 214static uint16_t
215calc_checksum(const uint16_t *data, 215calc_checksum (const uint16_t * data, unsigned int bytes)
216 unsigned int bytes)
217{ 216{
218 uint32_t sum; 217 uint32_t sum;
219 unsigned int i; 218 unsigned int i;
220 219
221 sum = 0; 220 sum = 0;
222 for (i=0;i<bytes/2;i++) 221 for (i = 0; i < bytes / 2; i++)
223 sum += data[i]; 222 sum += data[i];
224 sum = (sum & 0xffff) + (sum >> 16); 223 sum = (sum & 0xffff) + (sum >> 16);
225 sum = htons(0xffff - sum); 224 sum = htons (0xffff - sum);
226 return sum; 225 return sum;
227} 226}
228 227
@@ -253,22 +252,18 @@ send_icmp_echo (const struct in_addr *my_ip)
253 ip_pkt.checksum = 0; 252 ip_pkt.checksum = 0;
254 ip_pkt.src_ip = my_ip->s_addr; 253 ip_pkt.src_ip = my_ip->s_addr;
255 ip_pkt.dst_ip = dummy.s_addr; 254 ip_pkt.dst_ip = dummy.s_addr;
256 ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, 255 ip_pkt.checksum = htons (calc_checksum ((uint16_t *) & ip_pkt,
257 sizeof (struct ip_header))); 256 sizeof (struct ip_header)));
258 memcpy (&packet[off], 257 memcpy (&packet[off], &ip_pkt, sizeof (struct ip_header));
259 &ip_pkt,
260 sizeof (struct ip_header));
261 off += sizeof (struct ip_header); 258 off += sizeof (struct ip_header);
262 259
263 icmp_echo.type = ICMP_ECHO; 260 icmp_echo.type = ICMP_ECHO;
264 icmp_echo.code = 0; 261 icmp_echo.code = 0;
265 icmp_echo.checksum = 0; 262 icmp_echo.checksum = 0;
266 icmp_echo.reserved = 0; 263 icmp_echo.reserved = 0;
267 icmp_echo.checksum = htons(calc_checksum((uint16_t*)&icmp_echo, 264 icmp_echo.checksum = htons (calc_checksum ((uint16_t *) & icmp_echo,
268 sizeof (struct icmp_echo_header))); 265 sizeof (struct icmp_echo_header)));
269 memcpy (&packet[off], 266 memcpy (&packet[off], &icmp_echo, sizeof (struct icmp_echo_header));
270 &icmp_echo,
271 sizeof (struct icmp_echo_header));
272 off += sizeof (struct icmp_echo_header); 267 off += sizeof (struct icmp_echo_header);
273 268
274 memset (&dst, 0, sizeof (dst)); 269 memset (&dst, 0, sizeof (dst));
@@ -277,22 +272,18 @@ send_icmp_echo (const struct in_addr *my_ip)
277 dst.sin_len = sizeof (struct sockaddr_in); 272 dst.sin_len = sizeof (struct sockaddr_in);
278#endif 273#endif
279 dst.sin_addr = dummy; 274 dst.sin_addr = dummy;
280 err = sendto(rawsock, 275 err = sendto (rawsock,
281 packet, off, 0, 276 packet, off, 0, (struct sockaddr *) &dst, sizeof (dst));
282 (struct sockaddr*)&dst,
283 sizeof(dst));
284 if (err < 0) 277 if (err < 0)
285 { 278 {
286#if VERBOSE 279#if VERBOSE
287 fprintf(stderr, 280 fprintf (stderr, "sendto failed: %s\n", strerror (errno));
288 "sendto failed: %s\n", strerror(errno));
289#endif 281#endif
290 } 282 }
291 else if (sizeof (packet) != err) 283 else if (sizeof (packet) != err)
292 { 284 {
293 fprintf(stderr, 285 fprintf (stderr, "Error: partial send of ICMP message\n");
294 "Error: partial send of ICMP message\n"); 286 }
295 }
296} 287}
297 288
298 289
@@ -312,22 +303,17 @@ send_udp ()
312#endif 303#endif
313 dst.sin_addr = dummy; 304 dst.sin_addr = dummy;
314 dst.sin_port = htons (NAT_TRAV_PORT); 305 dst.sin_port = htons (NAT_TRAV_PORT);
315 err = sendto(udpsock, 306 err = sendto (udpsock, NULL, 0, 0, (struct sockaddr *) &dst, sizeof (dst));
316 NULL, 0, 0,
317 (struct sockaddr*)&dst,
318 sizeof(dst));
319 if (err < 0) 307 if (err < 0)
320 { 308 {
321#if VERBOSE 309#if VERBOSE
322 fprintf(stderr, 310 fprintf (stderr, "sendto failed: %s\n", strerror (errno));
323 "sendto failed: %s\n", strerror(errno));
324#endif 311#endif
325 } 312 }
326 else if (0 != err) 313 else if (0 != err)
327 { 314 {
328 fprintf(stderr, 315 fprintf (stderr, "Error: partial send of ICMP message\n");
329 "Error: partial send of ICMP message\n"); 316 }
330 }
331} 317}
332 318
333 319
@@ -349,96 +335,75 @@ process_icmp_response ()
349 335
350 have = read (icmpsock, buf, sizeof (buf)); 336 have = read (icmpsock, buf, sizeof (buf));
351 if (-1 == have) 337 if (-1 == have)
352 { 338 {
353 fprintf (stderr, 339 fprintf (stderr, "Error reading raw socket: %s\n", strerror (errno));
354 "Error reading raw socket: %s\n", 340 return;
355 strerror (errno)); 341 }
356 return;
357 }
358#if VERBOSE 342#if VERBOSE
359 fprintf (stderr, 343 fprintf (stderr, "Received message of %u bytes\n", (unsigned int) have);
360 "Received message of %u bytes\n",
361 (unsigned int) have);
362#endif 344#endif
363 if (have < (ssize_t) (sizeof (struct ip_header) + sizeof (struct icmp_ttl_exceeded_header) + sizeof (struct ip_header))) 345 if (have <
364 { 346 (ssize_t) (sizeof (struct ip_header) +
365 /* malformed */ 347 sizeof (struct icmp_ttl_exceeded_header) +
366 return; 348 sizeof (struct ip_header)))
367 } 349 {
350 /* malformed */
351 return;
352 }
368 off = 0; 353 off = 0;
369 memcpy (&ip_pkt, 354 memcpy (&ip_pkt, &buf[off], sizeof (struct ip_header));
370 &buf[off],
371 sizeof (struct ip_header));
372 off += sizeof (struct ip_header); 355 off += sizeof (struct ip_header);
373 memcpy(&source_ip, 356 memcpy (&source_ip, &ip_pkt.src_ip, sizeof (source_ip));
374 &ip_pkt.src_ip, 357 memcpy (&icmp_ttl, &buf[off], sizeof (struct icmp_ttl_exceeded_header));
375 sizeof (source_ip));
376 memcpy (&icmp_ttl,
377 &buf[off],
378 sizeof (struct icmp_ttl_exceeded_header));
379 off += sizeof (struct icmp_ttl_exceeded_header); 358 off += sizeof (struct icmp_ttl_exceeded_header);
380 if ( (ICMP_TIME_EXCEEDED != icmp_ttl.type) || 359 if ((ICMP_TIME_EXCEEDED != icmp_ttl.type) || (0 != icmp_ttl.code))
381 (0 != icmp_ttl.code) ) 360 {
382 { 361 /* different type than what we want */
383 /* different type than what we want */ 362 return;
384 return; 363 }
385 }
386 /* skip 2nd IP header */ 364 /* skip 2nd IP header */
387 memcpy (&ip_pkt, 365 memcpy (&ip_pkt, &buf[off], sizeof (struct ip_header));
388 &buf[off],
389 sizeof (struct ip_header));
390 off += sizeof (struct ip_header); 366 off += sizeof (struct ip_header);
391 367
392 switch (ip_pkt.proto) 368 switch (ip_pkt.proto)
369 {
370 case IPPROTO_ICMP:
371 if (have != (sizeof (struct ip_header) * 2 +
372 sizeof (struct icmp_ttl_exceeded_header) +
373 sizeof (struct icmp_echo_header)))
393 { 374 {
394 case IPPROTO_ICMP: 375 /* malformed */
395 if (have != (sizeof (struct ip_header) * 2 +
396 sizeof (struct icmp_ttl_exceeded_header) +
397 sizeof (struct icmp_echo_header)) )
398 {
399 /* malformed */
400 return;
401 }
402 /* grab ICMP ECHO content */
403 memcpy (&icmp_echo,
404 &buf[off],
405 sizeof (struct icmp_echo_header));
406 port = (uint16_t) ntohl (icmp_echo.reserved);
407 break;
408 case IPPROTO_UDP:
409 if (have != (sizeof (struct ip_header) * 2 +
410 sizeof (struct icmp_ttl_exceeded_header) +
411 sizeof (struct udp_header)) )
412 {
413 /* malformed */
414 return;
415 }
416 /* grab UDP content */
417 memcpy (&udp_pkt,
418 &buf[off],
419 sizeof (struct udp_header));
420 port = ntohs (udp_pkt.length);
421 break;
422 default:
423 /* different type than what we want */
424 return; 376 return;
425 } 377 }
378 /* grab ICMP ECHO content */
379 memcpy (&icmp_echo, &buf[off], sizeof (struct icmp_echo_header));
380 port = (uint16_t) ntohl (icmp_echo.reserved);
381 break;
382 case IPPROTO_UDP:
383 if (have != (sizeof (struct ip_header) * 2 +
384 sizeof (struct icmp_ttl_exceeded_header) +
385 sizeof (struct udp_header)))
386 {
387 /* malformed */
388 return;
389 }
390 /* grab UDP content */
391 memcpy (&udp_pkt, &buf[off], sizeof (struct udp_header));
392 port = ntohs (udp_pkt.length);
393 break;
394 default:
395 /* different type than what we want */
396 return;
397 }
426 398
427 if (port == 0) 399 if (port == 0)
428 fprintf (stdout, 400 fprintf (stdout,
429 "%s\n", 401 "%s\n", inet_ntop (AF_INET, &source_ip, buf, sizeof (buf)));
430 inet_ntop (AF_INET,
431 &source_ip,
432 buf,
433 sizeof (buf)));
434 else 402 else
435 fprintf (stdout, 403 fprintf (stdout,
436 "%s:%u\n", 404 "%s:%u\n",
437 inet_ntop (AF_INET, 405 inet_ntop (AF_INET,
438 &source_ip, 406 &source_ip, buf, sizeof (buf)), (unsigned int) port);
439 buf,
440 sizeof (buf)),
441 (unsigned int) port);
442 fflush (stdout); 407 fflush (stdout);
443} 408}
444 409
@@ -455,21 +420,18 @@ make_icmp_socket ()
455 420
456 ret = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP); 421 ret = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP);
457 if (-1 == ret) 422 if (-1 == ret)
458 { 423 {
459 fprintf (stderr, 424 fprintf (stderr, "Error opening RAW socket: %s\n", strerror (errno));
460 "Error opening RAW socket: %s\n", 425 return -1;
461 strerror (errno)); 426 }
462 return -1;
463 }
464 if (ret >= FD_SETSIZE) 427 if (ret >= FD_SETSIZE)
465 { 428 {
466 fprintf (stderr, 429 fprintf (stderr,
467 "Socket number too large (%d > %u)\n", 430 "Socket number too large (%d > %u)\n",
468 ret, 431 ret, (unsigned int) FD_SETSIZE);
469 (unsigned int) FD_SETSIZE); 432 close (ret);
470 close (ret); 433 return -1;
471 return -1; 434 }
472 }
473 return ret; 435 return ret;
474} 436}
475 437
@@ -487,34 +449,24 @@ make_raw_socket ()
487 449
488 ret = socket (AF_INET, SOCK_RAW, IPPROTO_RAW); 450 ret = socket (AF_INET, SOCK_RAW, IPPROTO_RAW);
489 if (-1 == ret) 451 if (-1 == ret)
490 { 452 {
491 fprintf (stderr, 453 fprintf (stderr, "Error opening RAW socket: %s\n", strerror (errno));
492 "Error opening RAW socket: %s\n", 454 return -1;
493 strerror (errno)); 455 }
494 return -1; 456 if (-1 == setsockopt (ret,
495 } 457 SOL_SOCKET, SO_BROADCAST, (char *) &one, sizeof (one)))
496 if (-1 == setsockopt(ret, 458 {
497 SOL_SOCKET, 459 fprintf (stderr, "setsockopt failed: %s\n", strerror (errno));
498 SO_BROADCAST, 460 close (ret);
499 (char *)&one, sizeof(one))) 461 return -1;
500 { 462 }
501 fprintf(stderr, 463 if (-1 == setsockopt (ret,
502 "setsockopt failed: %s\n", 464 IPPROTO_IP, IP_HDRINCL, (char *) &one, sizeof (one)))
503 strerror (errno)); 465 {
504 close (ret); 466 fprintf (stderr, "setsockopt failed: %s\n", strerror (errno));
505 return -1; 467 close (ret);
506 } 468 return -1;
507 if (-1 == setsockopt(ret, 469 }
508 IPPROTO_IP,
509 IP_HDRINCL,
510 (char *)&one, sizeof(one)))
511 {
512 fprintf(stderr,
513 "setsockopt failed: %s\n",
514 strerror (errno));
515 close (ret);
516 return -1;
517 }
518 return ret; 470 return ret;
519} 471}
520 472
@@ -533,15 +485,11 @@ make_udp_socket (const struct in_addr *my_ip)
533 485
534 ret = socket (AF_INET, SOCK_DGRAM, 0); 486 ret = socket (AF_INET, SOCK_DGRAM, 0);
535 if (-1 == ret) 487 if (-1 == ret)
536 { 488 {
537 fprintf (stderr, 489 fprintf (stderr, "Error opening UDP socket: %s\n", strerror (errno));
538 "Error opening UDP socket: %s\n", 490 return -1;
539 strerror (errno)); 491 }
540 return -1; 492 memset (&addr, 0, sizeof (addr));
541 }
542 memset (&addr,
543 0,
544 sizeof (addr));
545 addr.sin_family = AF_INET; 493 addr.sin_family = AF_INET;
546#if HAVE_SOCKADDR_IN_SIN_LEN 494#if HAVE_SOCKADDR_IN_SIN_LEN
547 addr.sin_len = sizeof (struct sockaddr_in); 495 addr.sin_len = sizeof (struct sockaddr_in);
@@ -549,23 +497,19 @@ make_udp_socket (const struct in_addr *my_ip)
549 addr.sin_addr = *my_ip; 497 addr.sin_addr = *my_ip;
550 addr.sin_port = htons (NAT_TRAV_PORT); 498 addr.sin_port = htons (NAT_TRAV_PORT);
551 499
552 if (0 != bind (ret, 500 if (0 != bind (ret, &addr, sizeof (addr)))
553 &addr, 501 {
554 sizeof(addr))) 502 fprintf (stderr,
555 { 503 "Error binding UDP socket to port %u: %s\n",
556 fprintf (stderr, 504 NAT_TRAV_PORT, strerror (errno));
557 "Error binding UDP socket to port %u: %s\n", 505 /* likely problematic, but not certain, try to continue */
558 NAT_TRAV_PORT, 506 }
559 strerror (errno));
560 /* likely problematic, but not certain, try to continue */
561 }
562 return ret; 507 return ret;
563} 508}
564 509
565 510
566int 511int
567main (int argc, 512main (int argc, char *const *argv)
568 char *const *argv)
569{ 513{
570 struct in_addr external; 514 struct in_addr external;
571 fd_set rs; 515 fd_set rs;
@@ -574,72 +518,65 @@ main (int argc,
574 unsigned int alt; 518 unsigned int alt;
575 519
576 if (2 != argc) 520 if (2 != argc)
577 { 521 {
578 fprintf (stderr, 522 fprintf (stderr,
579 "This program must be started with our (internal NAT) IP as the only argument.\n"); 523 "This program must be started with our (internal NAT) IP as the only argument.\n");
580 return 1; 524 return 1;
581 } 525 }
582 if (1 != inet_pton (AF_INET, argv[1], &external)) 526 if (1 != inet_pton (AF_INET, argv[1], &external))
583 { 527 {
584 fprintf (stderr, 528 fprintf (stderr, "Error parsing IPv4 address: %s\n", strerror (errno));
585 "Error parsing IPv4 address: %s\n", 529 return 1;
586 strerror (errno)); 530 }
587 return 1;
588 }
589 if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy)) 531 if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy))
590 { 532 {
591 fprintf (stderr, 533 fprintf (stderr, "Internal error converting dummy IP to binary.\n");
592 "Internal error converting dummy IP to binary.\n"); 534 return 2;
593 return 2; 535 }
594 } 536 if (-1 == (icmpsock = make_icmp_socket ()))
595 if (-1 == (icmpsock = make_icmp_socket())) 537 {
596 { 538 return 3;
597 return 3; 539 }
598 } 540 if (-1 == (rawsock = make_raw_socket ()))
599 if (-1 == (rawsock = make_raw_socket())) 541 {
600 { 542 close (icmpsock);
601 close (icmpsock); 543 return 3;
602 return 3; 544 }
603 }
604 uid = getuid (); 545 uid = getuid ();
605 if (0 != setresuid (uid, uid, uid)) 546 if (0 != setresuid (uid, uid, uid))
606 { 547 {
607 fprintf (stderr, 548 fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
608 "Failed to setresuid: %s\n", 549 /* not critical, continue anyway */
609 strerror (errno)); 550 }
610 /* not critical, continue anyway */ 551 if (-1 == (udpsock = make_udp_socket (&external)))
611 } 552 {
612 if (-1 == (udpsock = make_udp_socket(&external))) 553 close (icmpsock);
613 { 554 close (rawsock);
614 close (icmpsock); 555 return 3;
615 close (rawsock); 556 }
616 return 3;
617 }
618 alt = 0; 557 alt = 0;
619 while (1) 558 while (1)
559 {
560 FD_ZERO (&rs);
561 FD_SET (icmpsock, &rs);
562 tv.tv_sec = 0;
563 tv.tv_usec = ICMP_SEND_FREQUENCY_MS * 1000;
564 if (-1 == select (icmpsock + 1, &rs, NULL, NULL, &tv))
620 { 565 {
621 FD_ZERO (&rs); 566 if (errno == EINTR)
622 FD_SET (icmpsock, &rs); 567 continue;
623 tv.tv_sec = 0; 568 fprintf (stderr, "select failed: %s\n", strerror (errno));
624 tv.tv_usec = ICMP_SEND_FREQUENCY_MS * 1000; 569 break;
625 if (-1 == select (icmpsock + 1, &rs, NULL, NULL, &tv))
626 {
627 if (errno == EINTR)
628 continue;
629 fprintf (stderr,
630 "select failed: %s\n",
631 strerror (errno));
632 break;
633 }
634 if (1 == getppid()) /* Check the parent process id, if 1 the parent has died, so we should die too */
635 break;
636 if (FD_ISSET (icmpsock, &rs))
637 process_icmp_response ();
638 if (0 == (++alt % 2))
639 send_icmp_echo (&external);
640 else
641 send_udp ();
642 } 570 }
571 if (1 == getppid ()) /* Check the parent process id, if 1 the parent has died, so we should die too */
572 break;
573 if (FD_ISSET (icmpsock, &rs))
574 process_icmp_response ();
575 if (0 == (++alt % 2))
576 send_icmp_echo (&external);
577 else
578 send_udp ();
579 }
643 /* select failed (internal error or OS out of resources) */ 580 /* select failed (internal error or OS out of resources) */
644 close (icmpsock); 581 close (icmpsock);
645 close (rawsock); 582 close (rawsock);
diff --git a/src/nat/gnunet-nat-server.c b/src/nat/gnunet-nat-server.c
index bf4318a91..3b4ec2293 100644
--- a/src/nat/gnunet-nat-server.c
+++ b/src/nat/gnunet-nat-server.c
@@ -51,30 +51,23 @@ static const struct GNUNET_CONFIGURATION_Handle *cfg;
51 * @param is_tcp mark for TCP (GNUNET_YES) or UDP (GNUNET_NO) 51 * @param is_tcp mark for TCP (GNUNET_YES) or UDP (GNUNET_NO)
52 */ 52 */
53static void 53static void
54try_anat (uint32_t dst_ipv4, 54try_anat (uint32_t dst_ipv4, uint16_t dport, int is_tcp)
55 uint16_t dport,
56 int is_tcp)
57{ 55{
58 struct GNUNET_NAT_Handle *h; 56 struct GNUNET_NAT_Handle *h;
59 struct sockaddr_in sa; 57 struct sockaddr_in sa;
60 58
61#if DEBUG_NAT 59#if DEBUG_NAT
62 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 60 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
63 "Asking for connection reversal with %x and code %u\n", 61 "Asking for connection reversal with %x and code %u\n",
64 (unsigned int) dst_ipv4, 62 (unsigned int) dst_ipv4, (unsigned int) dport);
65 (unsigned int) dport);
66#endif 63#endif
67 h = GNUNET_NAT_register (cfg, 64 h = GNUNET_NAT_register (cfg, is_tcp, dport, 0, NULL, NULL, NULL, NULL, NULL);
68 is_tcp,
69 dport,
70 0, NULL, NULL,
71 NULL, NULL, NULL);
72 memset (&sa, 0, sizeof (sa)); 65 memset (&sa, 0, sizeof (sa));
73 sa.sin_family = AF_INET; 66 sa.sin_family = AF_INET;
74#if HAVE_SOCKADDR_IN_SIN_LEN 67#if HAVE_SOCKADDR_IN_SIN_LEN
75 sa.sin_len = sizeof (sa); 68 sa.sin_len = sizeof (sa);
76#endif 69#endif
77 sa.sin_addr.s_addr = dst_ipv4; 70 sa.sin_addr.s_addr = dst_ipv4;
78 GNUNET_NAT_run_client (h, &sa); 71 GNUNET_NAT_run_client (h, &sa);
79 GNUNET_NAT_unregister (h); 72 GNUNET_NAT_unregister (h);
80} 73}
@@ -83,7 +76,7 @@ try_anat (uint32_t dst_ipv4,
83/** 76/**
84 * Closure for 'tcp_send'. 77 * Closure for 'tcp_send'.
85 */ 78 */
86struct TcpContext 79struct TcpContext
87{ 80{
88 /** 81 /**
89 * TCP socket. 82 * TCP socket.
@@ -92,7 +85,7 @@ struct TcpContext
92 85
93 /** 86 /**
94 * Data to transmit. 87 * Data to transmit.
95 */ 88 */
96 uint16_t data; 89 uint16_t data;
97}; 90};
98 91
@@ -105,23 +98,22 @@ struct TcpContext
105 * @param tc scheduler context 98 * @param tc scheduler context
106 */ 99 */
107static void 100static void
108tcp_send (void *cls, 101tcp_send (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
109 const struct GNUNET_SCHEDULER_TaskContext *tc)
110{ 102{
111 struct TcpContext *ctx = cls; 103 struct TcpContext *ctx = cls;
112 104
113 if ( (NULL != tc->write_ready) && 105 if ((NULL != tc->write_ready) &&
114 (GNUNET_NETWORK_fdset_isset (tc->write_ready, 106 (GNUNET_NETWORK_fdset_isset (tc->write_ready, ctx->s)))
115 ctx->s)) ) 107 {
108 if (-1 ==
109 GNUNET_NETWORK_socket_send (ctx->s, &ctx->data, sizeof (ctx->data)))
116 { 110 {
117 if (-1 == GNUNET_NETWORK_socket_send (ctx->s, &ctx->data, sizeof (ctx->data)))
118 {
119#if DEBUG_NAT 111#if DEBUG_NAT
120 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, "send"); 112 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, "send");
121#endif 113#endif
122 }
123 GNUNET_NETWORK_socket_shutdown (ctx->s, SHUT_RDWR);
124 } 114 }
115 GNUNET_NETWORK_socket_shutdown (ctx->s, SHUT_RDWR);
116 }
125 GNUNET_NETWORK_socket_close (ctx->s); 117 GNUNET_NETWORK_socket_close (ctx->s);
126 GNUNET_free (ctx); 118 GNUNET_free (ctx);
127} 119}
@@ -136,9 +128,7 @@ tcp_send (void *cls,
136 * @param data data to send 128 * @param data data to send
137 */ 129 */
138static void 130static void
139try_send_tcp (uint32_t dst_ipv4, 131try_send_tcp (uint32_t dst_ipv4, uint16_t dport, uint16_t data)
140 uint16_t dport,
141 uint16_t data)
142{ 132{
143 struct GNUNET_NETWORK_Handle *s; 133 struct GNUNET_NETWORK_Handle *s;
144 struct sockaddr_in sa; 134 struct sockaddr_in sa;
@@ -146,37 +136,35 @@ try_send_tcp (uint32_t dst_ipv4,
146 136
147 s = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0); 137 s = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0);
148 if (NULL == s) 138 if (NULL == s)
149 { 139 {
150 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "socket"); 140 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "socket");
151 return; 141 return;
152 } 142 }
153 memset (&sa, 0, sizeof (sa)); 143 memset (&sa, 0, sizeof (sa));
154 sa.sin_family = AF_INET; 144 sa.sin_family = AF_INET;
155#if HAVE_SOCKADDR_IN_SIN_LEN 145#if HAVE_SOCKADDR_IN_SIN_LEN
156 sa.sin_len = sizeof (sa); 146 sa.sin_len = sizeof (sa);
157#endif 147#endif
158 sa.sin_addr.s_addr = dst_ipv4; 148 sa.sin_addr.s_addr = dst_ipv4;
159 sa.sin_port = htons (dport); 149 sa.sin_port = htons (dport);
160#if DEBUG_NAT 150#if DEBUG_NAT
161 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 151 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
162 "Sending TCP message to `%s'\n", 152 "Sending TCP message to `%s'\n",
163 GNUNET_a2s ((struct sockaddr*) &sa, sizeof (sa))); 153 GNUNET_a2s ((struct sockaddr *) &sa, sizeof (sa)));
164#endif 154#endif
165 if ( (GNUNET_OK != 155 if ((GNUNET_OK !=
166 GNUNET_NETWORK_socket_connect (s, 156 GNUNET_NETWORK_socket_connect (s,
167 (const struct sockaddr*) &sa, sizeof (sa))) && 157 (const struct sockaddr *) &sa,
168 (errno != EINPROGRESS) ) 158 sizeof (sa))) && (errno != EINPROGRESS))
169 { 159 {
170 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "connect"); 160 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "connect");
171 GNUNET_NETWORK_socket_close (s); 161 GNUNET_NETWORK_socket_close (s);
172 return; 162 return;
173 } 163 }
174 ctx = GNUNET_malloc (sizeof (struct TcpContext)); 164 ctx = GNUNET_malloc (sizeof (struct TcpContext));
175 ctx->s = s; 165 ctx->s = s;
176 ctx->data = data; 166 ctx->data = data;
177 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_SECONDS, 167 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_SECONDS, s, &tcp_send, ctx);
178 s,
179 &tcp_send, ctx);
180} 168}
181 169
182 170
@@ -189,34 +177,33 @@ try_send_tcp (uint32_t dst_ipv4,
189 * @param data data to send 177 * @param data data to send
190 */ 178 */
191static void 179static void
192try_send_udp (uint32_t dst_ipv4, 180try_send_udp (uint32_t dst_ipv4, uint16_t dport, uint16_t data)
193 uint16_t dport,
194 uint16_t data)
195{ 181{
196 struct GNUNET_NETWORK_Handle *s; 182 struct GNUNET_NETWORK_Handle *s;
197 struct sockaddr_in sa; 183 struct sockaddr_in sa;
198 184
199 s = GNUNET_NETWORK_socket_create (AF_INET, SOCK_DGRAM, 0); 185 s = GNUNET_NETWORK_socket_create (AF_INET, SOCK_DGRAM, 0);
200 if (NULL == s) 186 if (NULL == s)
201 { 187 {
202 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "socket"); 188 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "socket");
203 return; 189 return;
204 } 190 }
205 memset (&sa, 0, sizeof (sa)); 191 memset (&sa, 0, sizeof (sa));
206 sa.sin_family = AF_INET; 192 sa.sin_family = AF_INET;
207#if HAVE_SOCKADDR_IN_SIN_LEN 193#if HAVE_SOCKADDR_IN_SIN_LEN
208 sa.sin_len = sizeof (sa); 194 sa.sin_len = sizeof (sa);
209#endif 195#endif
210 sa.sin_addr.s_addr = dst_ipv4; 196 sa.sin_addr.s_addr = dst_ipv4;
211 sa.sin_port = htons (dport); 197 sa.sin_port = htons (dport);
212#if DEBUG_NAT 198#if DEBUG_NAT
213 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 199 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
214 "Sending UDP packet to `%s'\n", 200 "Sending UDP packet to `%s'\n",
215 GNUNET_a2s ((struct sockaddr*) &sa, sizeof (sa))); 201 GNUNET_a2s ((struct sockaddr *) &sa, sizeof (sa)));
216#endif 202#endif
217 if (-1 == GNUNET_NETWORK_socket_sendto (s, 203 if (-1 == GNUNET_NETWORK_socket_sendto (s,
218 &data, sizeof(data), 204 &data, sizeof (data),
219 (const struct sockaddr*) &sa, sizeof (sa))) 205 (const struct sockaddr *) &sa,
206 sizeof (sa)))
220 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "sendto"); 207 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "sendto");
221 GNUNET_NETWORK_socket_close (s); 208 GNUNET_NETWORK_socket_close (s);
222} 209}
@@ -239,21 +226,17 @@ test (void *cls,
239 uint16_t dport; 226 uint16_t dport;
240 227
241#if DEBUG_NAT 228#if DEBUG_NAT
242 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 229 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received test request\n");
243 "Received test request\n");
244#endif 230#endif
245 tm = (const struct GNUNET_NAT_TestMessage*) msg; 231 tm = (const struct GNUNET_NAT_TestMessage *) msg;
246 dport = ntohs (tm->dport); 232 dport = ntohs (tm->dport);
247 if (0 == dport) 233 if (0 == dport)
248 try_anat (tm->dst_ipv4, 234 try_anat (tm->dst_ipv4, ntohs (tm->data), (int) ntohl (tm->is_tcp));
249 ntohs (tm->data),
250 (int) ntohl (tm->is_tcp));
251 else if (GNUNET_YES == ntohl (tm->is_tcp)) 235 else if (GNUNET_YES == ntohl (tm->is_tcp))
252 try_send_tcp (tm->dst_ipv4, dport, tm->data); 236 try_send_tcp (tm->dst_ipv4, dport, tm->data);
253 else 237 else
254 try_send_udp (tm->dst_ipv4, dport, tm->data); 238 try_send_udp (tm->dst_ipv4, dport, tm->data);
255 GNUNET_SERVER_receive_done (client, 239 GNUNET_SERVER_receive_done (client, GNUNET_NO);
256 GNUNET_NO);
257} 240}
258 241
259 242
@@ -264,8 +247,7 @@ test (void *cls,
264 * @param tc scheduler context 247 * @param tc scheduler context
265 */ 248 */
266static void 249static void
267shutdown_task (void *cls, 250shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
268 const struct GNUNET_SCHEDULER_TaskContext *tc)
269{ 251{
270 GNUNET_SERVER_destroy (server); 252 GNUNET_SERVER_destroy (server);
271 server = NULL; 253 server = NULL;
@@ -283,43 +265,40 @@ shutdown_task (void *cls,
283static void 265static void
284run (void *cls, 266run (void *cls,
285 char *const *args, 267 char *const *args,
286 const char *cfgfile, 268 const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
287 const struct GNUNET_CONFIGURATION_Handle *c)
288{ 269{
289 static const struct GNUNET_SERVER_MessageHandler handlers[] = 270 static const struct GNUNET_SERVER_MessageHandler handlers[] = {
290 { 271 {&test, NULL, GNUNET_MESSAGE_TYPE_NAT_TEST,
291 { &test, NULL, GNUNET_MESSAGE_TYPE_NAT_TEST, sizeof (struct GNUNET_NAT_TestMessage) }, 272 sizeof (struct GNUNET_NAT_TestMessage)},
292 { NULL, NULL, 0, 0 } 273 {NULL, NULL, 0, 0}
293 }; 274 };
294 unsigned int port; 275 unsigned int port;
295 struct sockaddr_in in4; 276 struct sockaddr_in in4;
296 struct sockaddr_in6 in6; 277 struct sockaddr_in6 in6;
297 socklen_t slen[] = 278
298 { 279 socklen_t slen[] = {
299 sizeof (in4), 280 sizeof (in4),
300 sizeof (in6), 281 sizeof (in6),
301 0 282 0
302 }; 283 };
303 struct sockaddr *sa[] = 284 struct sockaddr *sa[] = {
304 { 285 (struct sockaddr *) &in4,
305 (struct sockaddr*) &in4, 286 (struct sockaddr *) &in6,
306 (struct sockaddr*) &in6, 287 NULL
307 NULL 288 };
308 };
309 289
310 cfg = c; 290 cfg = c;
311 if ( (args[0] == NULL) || 291 if ((args[0] == NULL) ||
312 (1 != SSCANF (args[0], "%u", &port)) || 292 (1 != SSCANF (args[0], "%u", &port)) || (0 == port) || (65536 <= port))
313 (0 == port) || 293 {
314 (65536 <= port) ) 294 fprintf (stderr,
315 { 295 _
316 fprintf (stderr, 296 ("Please pass valid port number as the first argument! (got `%s')\n"),
317 _("Please pass valid port number as the first argument! (got `%s')\n"), 297 args[0]);
318 args[0]); 298 return;
319 return; 299 }
320 } 300 memset (&in4, 0, sizeof (in4));
321 memset (&in4, 0, sizeof (in4)); 301 memset (&in6, 0, sizeof (in6));
322 memset (&in6, 0, sizeof (in6));
323 in4.sin_family = AF_INET; 302 in4.sin_family = AF_INET;
324 in4.sin_port = htons ((uint16_t) port); 303 in4.sin_port = htons ((uint16_t) port);
325 in6.sin6_family = AF_INET6; 304 in6.sin6_family = AF_INET6;
@@ -329,15 +308,11 @@ run (void *cls,
329 in6.sin6_len = sizeof (in6); 308 in6.sin6_len = sizeof (in6);
330#endif 309#endif
331 server = GNUNET_SERVER_create (NULL, NULL, 310 server = GNUNET_SERVER_create (NULL, NULL,
332 (struct sockaddr*const*) sa, 311 (struct sockaddr * const *) sa,
333 slen, 312 slen, GNUNET_TIME_UNIT_SECONDS, GNUNET_YES);
334 GNUNET_TIME_UNIT_SECONDS, 313 GNUNET_SERVER_add_handlers (server, handlers);
335 GNUNET_YES);
336 GNUNET_SERVER_add_handlers (server,
337 handlers);
338 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, 314 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
339 &shutdown_task, 315 &shutdown_task, NULL);
340 NULL);
341} 316}
342 317
343 318
@@ -356,11 +331,10 @@ main (int argc, char *const argv[])
356 }; 331 };
357 332
358 if (GNUNET_OK != 333 if (GNUNET_OK !=
359 GNUNET_PROGRAM_run (argc, argv, 334 GNUNET_PROGRAM_run (argc, argv,
360 "gnunet-nat-server [options] PORT", 335 "gnunet-nat-server [options] PORT",
361 _("GNUnet NAT traversal test helper daemon"), 336 _("GNUnet NAT traversal test helper daemon"),
362 options, 337 options, &run, NULL))
363 &run, NULL))
364 return 1; 338 return 1;
365 return 0; 339 return 0;
366} 340}
diff --git a/src/nat/nat.c b/src/nat/nat.c
index a4efb7084..ed72be9f8 100644
--- a/src/nat/nat.c
+++ b/src/nat/nat.c
@@ -62,40 +62,39 @@
62 * we reevaluate the source. 62 * we reevaluate the source.
63 */ 63 */
64enum LocalAddressSource 64enum LocalAddressSource
65 { 65{
66 /** 66 /**
67 * Address was obtained by DNS resolution of the external hostname 67 * Address was obtained by DNS resolution of the external hostname
68 * given in the configuration (i.e. hole-punched DynDNS setup). 68 * given in the configuration (i.e. hole-punched DynDNS setup).
69 */ 69 */
70 LAL_EXTERNAL_IP, 70 LAL_EXTERNAL_IP,
71 71
72 /** 72 /**
73 * Address was obtained by looking up our own hostname in DNS. 73 * Address was obtained by looking up our own hostname in DNS.
74 */ 74 */
75 LAL_HOSTNAME_DNS, 75 LAL_HOSTNAME_DNS,
76 76
77 /** 77 /**
78 * Address was obtained by scanning our hosts's network interfaces 78 * Address was obtained by scanning our hosts's network interfaces
79 * and taking their address (no DNS involved). 79 * and taking their address (no DNS involved).
80 */ 80 */
81 LAL_INTERFACE_ADDRESS, 81 LAL_INTERFACE_ADDRESS,
82 82
83 /** 83 /**
84 * Addresses we were explicitly bound to. 84 * Addresses we were explicitly bound to.
85 */ 85 */
86 LAL_BINDTO_ADDRESS, 86 LAL_BINDTO_ADDRESS,
87 87
88 /** 88 /**
89 * Addresses from UPnP or PMP 89 * Addresses from UPnP or PMP
90 */ 90 */
91 LAL_UPNP, 91 LAL_UPNP,
92 92
93 /** 93 /**
94 * End of the list. 94 * End of the list.
95 */ 95 */
96 LAL_END 96 LAL_END
97 97};
98 };
99 98
100 99
101/** 100/**
@@ -114,7 +113,7 @@ struct LocalAddressList
114 113
115 /** 114 /**
116 * Previous entry. 115 * Previous entry.
117 */ 116 */
118 struct LocalAddressList *prev; 117 struct LocalAddressList *prev;
119 118
120 /** 119 /**
@@ -168,7 +167,7 @@ struct GNUNET_NAT_Handle
168 * Configuration to use. 167 * Configuration to use.
169 */ 168 */
170 const struct GNUNET_CONFIGURATION_Handle *cfg; 169 const struct GNUNET_CONFIGURATION_Handle *cfg;
171 170
172 /** 171 /**
173 * Function to call when we learn about a new address. 172 * Function to call when we learn about a new address.
174 */ 173 */
@@ -345,7 +344,7 @@ struct GNUNET_NAT_Handle
345 344
346 /** 345 /**
347 * Is this TCP or UDP? 346 * Is this TCP or UDP?
348 */ 347 */
349 int is_tcp; 348 int is_tcp;
350 349
351 /** 350 /**
@@ -362,8 +361,7 @@ struct GNUNET_NAT_Handle
362 * 361 *
363 * @param h handle to NAT 362 * @param h handle to NAT
364 */ 363 */
365static void 364static void start_gnunet_nat_server (struct GNUNET_NAT_Handle *h);
366start_gnunet_nat_server (struct GNUNET_NAT_Handle *h);
367 365
368 366
369/** 367/**
@@ -375,27 +373,24 @@ start_gnunet_nat_server (struct GNUNET_NAT_Handle *h);
375 */ 373 */
376static void 374static void
377remove_from_address_list_by_source (struct GNUNET_NAT_Handle *h, 375remove_from_address_list_by_source (struct GNUNET_NAT_Handle *h,
378 enum LocalAddressSource src) 376 enum LocalAddressSource src)
379{ 377{
380 struct LocalAddressList *pos; 378 struct LocalAddressList *pos;
381 struct LocalAddressList *next; 379 struct LocalAddressList *next;
382 380
383 next = h->lal_head; 381 next = h->lal_head;
384 while (NULL != (pos = next)) 382 while (NULL != (pos = next))
385 { 383 {
386 next = pos->next; 384 next = pos->next;
387 if (pos->source != src) 385 if (pos->source != src)
388 continue; 386 continue;
389 GNUNET_CONTAINER_DLL_remove (h->lal_head, 387 GNUNET_CONTAINER_DLL_remove (h->lal_head, h->lal_tail, pos);
390 h->lal_tail, 388 if (NULL != h->address_callback)
391 pos); 389 h->address_callback (h->callback_cls,
392 if (NULL != h->address_callback) 390 GNUNET_NO,
393 h->address_callback (h->callback_cls, 391 (const struct sockaddr *) &pos[1], pos->addrlen);
394 GNUNET_NO, 392 GNUNET_free (pos);
395 (const struct sockaddr* ) &pos[1], 393 }
396 pos->addrlen);
397 GNUNET_free (pos);
398 }
399} 394}
400 395
401 396
@@ -410,9 +405,8 @@ remove_from_address_list_by_source (struct GNUNET_NAT_Handle *h,
410 */ 405 */
411static void 406static void
412add_to_address_list_as_is (struct GNUNET_NAT_Handle *h, 407add_to_address_list_as_is (struct GNUNET_NAT_Handle *h,
413 enum LocalAddressSource src, 408 enum LocalAddressSource src,
414 const struct sockaddr *arg, 409 const struct sockaddr *arg, socklen_t arg_size)
415 socklen_t arg_size)
416{ 410{
417 struct LocalAddressList *lal; 411 struct LocalAddressList *lal;
418 412
@@ -420,21 +414,15 @@ add_to_address_list_as_is (struct GNUNET_NAT_Handle *h,
420 memcpy (&lal[1], arg, arg_size); 414 memcpy (&lal[1], arg, arg_size);
421 lal->addrlen = arg_size; 415 lal->addrlen = arg_size;
422 lal->source = src; 416 lal->source = src;
423 GNUNET_CONTAINER_DLL_insert (h->lal_head, 417 GNUNET_CONTAINER_DLL_insert (h->lal_head, h->lal_tail, lal);
424 h->lal_tail,
425 lal);
426#if DEBUG_NAT 418#if DEBUG_NAT
427 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 419 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
428 "nat", 420 "nat",
429 "Adding address `%s' from source %d\n", 421 "Adding address `%s' from source %d\n",
430 GNUNET_a2s (arg, arg_size), 422 GNUNET_a2s (arg, arg_size), src);
431 src);
432#endif 423#endif
433 if (NULL != h->address_callback) 424 if (NULL != h->address_callback)
434 h->address_callback (h->callback_cls, 425 h->address_callback (h->callback_cls, GNUNET_YES, arg, arg_size);
435 GNUNET_YES,
436 arg,
437 arg_size);
438} 426}
439 427
440 428
@@ -451,9 +439,8 @@ add_to_address_list_as_is (struct GNUNET_NAT_Handle *h,
451 */ 439 */
452static void 440static void
453add_to_address_list (struct GNUNET_NAT_Handle *h, 441add_to_address_list (struct GNUNET_NAT_Handle *h,
454 enum LocalAddressSource src, 442 enum LocalAddressSource src,
455 const struct sockaddr *arg, 443 const struct sockaddr *arg, socklen_t arg_size)
456 socklen_t arg_size)
457{ 444{
458 struct sockaddr_in s4; 445 struct sockaddr_in s4;
459 const struct sockaddr_in *in4; 446 const struct sockaddr_in *in4;
@@ -461,41 +448,41 @@ add_to_address_list (struct GNUNET_NAT_Handle *h,
461 const struct sockaddr_in6 *in6; 448 const struct sockaddr_in6 *in6;
462 449
463 if (arg_size == sizeof (struct sockaddr_in)) 450 if (arg_size == sizeof (struct sockaddr_in))
451 {
452 in4 = (const struct sockaddr_in *) arg;
453 s4 = *in4;
454 s4.sin_port = htons (h->adv_port);
455 add_to_address_list_as_is (h,
456 src,
457 (const struct sockaddr *) &s4,
458 sizeof (struct sockaddr_in));
459 if (GNUNET_YES == h->enable_nat_server)
464 { 460 {
465 in4 = (const struct sockaddr_in *) arg; 461 /* also add with PORT = 0 to indicate NAT server is enabled */
466 s4 = *in4; 462 s4.sin_port = htons (0);
467 s4.sin_port = htons (h->adv_port); 463 add_to_address_list_as_is (h,
468 add_to_address_list_as_is (h, 464 src,
469 src, 465 (const struct sockaddr *) &s4,
470 (const struct sockaddr*) &s4, 466 sizeof (struct sockaddr_in));
471 sizeof (struct sockaddr_in));
472 if (GNUNET_YES == h->enable_nat_server)
473 {
474 /* also add with PORT = 0 to indicate NAT server is enabled */
475 s4.sin_port = htons(0);
476 add_to_address_list_as_is (h,
477 src,
478 (const struct sockaddr*) &s4,
479 sizeof (struct sockaddr_in));
480 }
481 } 467 }
468 }
482 else if (arg_size == sizeof (struct sockaddr_in6)) 469 else if (arg_size == sizeof (struct sockaddr_in6))
470 {
471 if (GNUNET_YES != h->disable_ipv6)
483 { 472 {
484 if (GNUNET_YES != h->disable_ipv6) 473 in6 = (const struct sockaddr_in6 *) arg;
485 { 474 s6 = *in6;
486 in6 = (const struct sockaddr_in6 *) arg; 475 s6.sin6_port = htons (h->adv_port);
487 s6 = *in6; 476 add_to_address_list_as_is (h,
488 s6.sin6_port = htons(h->adv_port); 477 src,
489 add_to_address_list_as_is (h, 478 (const struct sockaddr *) &s6,
490 src, 479 sizeof (struct sockaddr_in6));
491 (const struct sockaddr*) &s6,
492 sizeof (struct sockaddr_in6));
493 }
494 } 480 }
481 }
495 else 482 else
496 { 483 {
497 GNUNET_assert (0); 484 GNUNET_assert (0);
498 } 485 }
499} 486}
500 487
501 488
@@ -510,9 +497,8 @@ add_to_address_list (struct GNUNET_NAT_Handle *h,
510 */ 497 */
511static void 498static void
512add_ip_to_address_list (struct GNUNET_NAT_Handle *h, 499add_ip_to_address_list (struct GNUNET_NAT_Handle *h,
513 enum LocalAddressSource src, 500 enum LocalAddressSource src,
514 const void *addr, 501 const void *addr, socklen_t addrlen)
515 socklen_t addrlen)
516{ 502{
517 struct sockaddr_in s4; 503 struct sockaddr_in s4;
518 const struct in_addr *in4; 504 const struct in_addr *in4;
@@ -520,52 +506,52 @@ add_ip_to_address_list (struct GNUNET_NAT_Handle *h,
520 const struct in6_addr *in6; 506 const struct in6_addr *in6;
521 507
522 if (addrlen == sizeof (struct in_addr)) 508 if (addrlen == sizeof (struct in_addr))
523 { 509 {
524 in4 = (const struct in_addr *) addr; 510 in4 = (const struct in_addr *) addr;
525 memset (&s4, 0, sizeof (s4)); 511 memset (&s4, 0, sizeof (s4));
526 s4.sin_family = AF_INET; 512 s4.sin_family = AF_INET;
527 s4.sin_port = 0; 513 s4.sin_port = 0;
528#if HAVE_SOCKADDR_IN_SIN_LEN 514#if HAVE_SOCKADDR_IN_SIN_LEN
529 s4.sin_len = (u_char) sizeof (struct sockaddr_in); 515 s4.sin_len = (u_char) sizeof (struct sockaddr_in);
530#endif 516#endif
531 s4.sin_addr = *in4; 517 s4.sin_addr = *in4;
532 add_to_address_list (h, 518 add_to_address_list (h,
533 src, 519 src,
534 (const struct sockaddr*) &s4, 520 (const struct sockaddr *) &s4,
535 sizeof (struct sockaddr_in)); 521 sizeof (struct sockaddr_in));
536 if (GNUNET_YES == h->enable_nat_server) 522 if (GNUNET_YES == h->enable_nat_server)
537 { 523 {
538 /* also add with PORT = 0 to indicate NAT server is enabled */ 524 /* also add with PORT = 0 to indicate NAT server is enabled */
539 s4.sin_port = htons(0); 525 s4.sin_port = htons (0);
540 add_to_address_list (h, 526 add_to_address_list (h,
541 src, 527 src,
542 (const struct sockaddr*) &s4, 528 (const struct sockaddr *) &s4,
543 sizeof (struct sockaddr_in)); 529 sizeof (struct sockaddr_in));
544 530
545 }
546 } 531 }
532 }
547 else if (addrlen == sizeof (struct in6_addr)) 533 else if (addrlen == sizeof (struct in6_addr))
534 {
535 if (GNUNET_YES != h->disable_ipv6)
548 { 536 {
549 if (GNUNET_YES != h->disable_ipv6) 537 in6 = (const struct in6_addr *) addr;
550 { 538 memset (&s6, 0, sizeof (s6));
551 in6 = (const struct in6_addr *) addr; 539 s6.sin6_family = AF_INET6;
552 memset (&s6, 0, sizeof (s6)); 540 s6.sin6_port = htons (h->adv_port);
553 s6.sin6_family = AF_INET6;
554 s6.sin6_port = htons(h->adv_port);
555#if HAVE_SOCKADDR_IN_SIN_LEN 541#if HAVE_SOCKADDR_IN_SIN_LEN
556 s6.sin6_len = (u_char) sizeof (struct sockaddr_in6); 542 s6.sin6_len = (u_char) sizeof (struct sockaddr_in6);
557#endif 543#endif
558 s6.sin6_addr = *in6; 544 s6.sin6_addr = *in6;
559 add_to_address_list (h, 545 add_to_address_list (h,
560 src, 546 src,
561 (const struct sockaddr*) &s6, 547 (const struct sockaddr *) &s6,
562 sizeof (struct sockaddr_in6)); 548 sizeof (struct sockaddr_in6));
563 }
564 } 549 }
550 }
565 else 551 else
566 { 552 {
567 GNUNET_assert (0); 553 GNUNET_assert (0);
568 } 554 }
569} 555}
570 556
571 557
@@ -577,8 +563,7 @@ add_ip_to_address_list (struct GNUNET_NAT_Handle *h,
577 * @param tc scheduler context 563 * @param tc scheduler context
578 */ 564 */
579static void 565static void
580resolve_dns (void *cls, 566resolve_dns (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
581 const struct GNUNET_SCHEDULER_TaskContext *tc);
582 567
583 568
584/** 569/**
@@ -590,24 +575,20 @@ resolve_dns (void *cls,
590 * @param addrlen number of bytes in addr 575 * @param addrlen number of bytes in addr
591 */ 576 */
592static void 577static void
593process_external_ip (void *cls, 578process_external_ip (void *cls, const struct sockaddr *addr, socklen_t addrlen)
594 const struct sockaddr *addr,
595 socklen_t addrlen)
596{ 579{
597 struct GNUNET_NAT_Handle *h = cls; 580 struct GNUNET_NAT_Handle *h = cls;
598 struct in_addr dummy; 581 struct in_addr dummy;
599 582
600 if (addr == NULL) 583 if (addr == NULL)
601 { 584 {
602 h->ext_dns = NULL; 585 h->ext_dns = NULL;
603 if (1 == inet_pton (AF_INET, 586 if (1 == inet_pton (AF_INET, h->external_address, &dummy))
604 h->external_address, 587 return; /* repated lookup pointless: was numeric! */
605 &dummy)) 588 h->dns_task = GNUNET_SCHEDULER_add_delayed (h->dyndns_frequency,
606 return; /* repated lookup pointless: was numeric! */ 589 &resolve_dns, h);
607 h->dns_task = GNUNET_SCHEDULER_add_delayed (h->dyndns_frequency, 590 return;
608 &resolve_dns, h); 591 }
609 return;
610 }
611 add_to_address_list (h, LAL_EXTERNAL_IP, addr, addrlen); 592 add_to_address_list (h, LAL_EXTERNAL_IP, addr, addrlen);
612} 593}
613 594
@@ -619,8 +600,7 @@ process_external_ip (void *cls,
619 * @param tc scheduler context 600 * @param tc scheduler context
620 */ 601 */
621static void 602static void
622resolve_hostname (void *cls, 603resolve_hostname (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
623 const struct GNUNET_SCHEDULER_TaskContext *tc);
624 604
625 605
626/** 606/**
@@ -633,18 +613,17 @@ resolve_hostname (void *cls,
633 * @param addrlen length of the address 613 * @param addrlen length of the address
634 */ 614 */
635static void 615static void
636process_hostname_ip (void *cls, 616process_hostname_ip (void *cls, const struct sockaddr *addr, socklen_t addrlen)
637 const struct sockaddr *addr, socklen_t addrlen)
638{ 617{
639 struct GNUNET_NAT_Handle *h = cls; 618 struct GNUNET_NAT_Handle *h = cls;
640 619
641 if (addr == NULL) 620 if (addr == NULL)
642 { 621 {
643 h->hostname_dns = NULL; 622 h->hostname_dns = NULL;
644 h->hostname_task = GNUNET_SCHEDULER_add_delayed (h->hostname_dns_frequency, 623 h->hostname_task = GNUNET_SCHEDULER_add_delayed (h->hostname_dns_frequency,
645 &resolve_hostname, h); 624 &resolve_hostname, h);
646 return; 625 return;
647 } 626 }
648 add_to_address_list (h, LAL_HOSTNAME_DNS, addr, addrlen); 627 add_to_address_list (h, LAL_HOSTNAME_DNS, addr, addrlen);
649} 628}
650 629
@@ -673,48 +652,44 @@ process_interfaces (void *cls,
673 char buf[INET6_ADDRSTRLEN]; 652 char buf[INET6_ADDRSTRLEN];
674 653
675 switch (addr->sa_family) 654 switch (addr->sa_family)
655 {
656 case AF_INET:
657 s4 = (struct sockaddr_in *) addr;
658 ip = &s4->sin_addr;
659 if (GNUNET_YES == h->use_localaddresses)
660 add_ip_to_address_list (h,
661 LAL_INTERFACE_ADDRESS,
662 &s4->sin_addr, sizeof (struct in_addr));
663 break;
664 case AF_INET6:
665 s6 = (struct sockaddr_in6 *) addr;
666 if (IN6_IS_ADDR_LINKLOCAL (&((struct sockaddr_in6 *) addr)->sin6_addr))
676 { 667 {
677 case AF_INET: 668 /* skip link local addresses */
678 s4 = (struct sockaddr_in *) addr;
679 ip = &s4->sin_addr;
680 if (GNUNET_YES == h->use_localaddresses)
681 add_ip_to_address_list (h,
682 LAL_INTERFACE_ADDRESS,
683 &s4->sin_addr,
684 sizeof (struct in_addr));
685 break;
686 case AF_INET6:
687 s6 = (struct sockaddr_in6 *) addr;
688 if (IN6_IS_ADDR_LINKLOCAL (&((struct sockaddr_in6 *) addr)->sin6_addr))
689 {
690 /* skip link local addresses */
691 return GNUNET_OK;
692 }
693 ip = &s6->sin6_addr;
694 if (GNUNET_YES == h->use_localaddresses)
695 add_ip_to_address_list (h,
696 LAL_INTERFACE_ADDRESS,
697 &s6->sin6_addr,
698 sizeof (struct in6_addr));
699 break;
700 default:
701 GNUNET_break (0);
702 return GNUNET_OK; 669 return GNUNET_OK;
703 } 670 }
704 if ( (h->internal_address == NULL) && 671 ip = &s6->sin6_addr;
705 (h->server_proc == NULL) && 672 if (GNUNET_YES == h->use_localaddresses)
706 (h->server_read_task == GNUNET_SCHEDULER_NO_TASK) && 673 add_ip_to_address_list (h,
707 (GNUNET_YES == isDefault) && 674 LAL_INTERFACE_ADDRESS,
708 ( (addr->sa_family == AF_INET) || (addr->sa_family == AF_INET6) ) ) 675 &s6->sin6_addr, sizeof (struct in6_addr));
709 { 676 break;
710 /* no internal address configured, but we found a "default" 677 default:
711 interface, try using that as our 'internal' address */ 678 GNUNET_break (0);
712 h->internal_address = GNUNET_strdup (inet_ntop (addr->sa_family, 679 return GNUNET_OK;
713 ip, 680 }
714 buf, 681 if ((h->internal_address == NULL) &&
715 sizeof (buf))); 682 (h->server_proc == NULL) &&
716 start_gnunet_nat_server (h); 683 (h->server_read_task == GNUNET_SCHEDULER_NO_TASK) &&
717 } 684 (GNUNET_YES == isDefault) &&
685 ((addr->sa_family == AF_INET) || (addr->sa_family == AF_INET6)))
686 {
687 /* no internal address configured, but we found a "default"
688 * interface, try using that as our 'internal' address */
689 h->internal_address = GNUNET_strdup (inet_ntop (addr->sa_family,
690 ip, buf, sizeof (buf)));
691 start_gnunet_nat_server (h);
692 }
718 return GNUNET_OK; 693 return GNUNET_OK;
719} 694}
720 695
@@ -725,16 +700,15 @@ process_interfaces (void *cls,
725 * 700 *
726 * @param cls the 'struct GNUNET_NAT_Handle' 701 * @param cls the 'struct GNUNET_NAT_Handle'
727 * @param tc scheduler context 702 * @param tc scheduler context
728 */ 703 */
729static void 704static void
730restart_nat_server (void *cls, 705restart_nat_server (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
731 const struct GNUNET_SCHEDULER_TaskContext *tc)
732{ 706{
733 struct GNUNET_NAT_Handle *h = cls; 707 struct GNUNET_NAT_Handle *h = cls;
734 708
735 h->server_read_task = GNUNET_SCHEDULER_NO_TASK; 709 h->server_read_task = GNUNET_SCHEDULER_NO_TASK;
736 if ( (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) 710 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
737 return; 711 return;
738 start_gnunet_nat_server (h); 712 start_gnunet_nat_server (h);
739} 713}
740 714
@@ -748,8 +722,7 @@ restart_nat_server (void *cls,
748 * @param tc the scheduling context 722 * @param tc the scheduling context
749 */ 723 */
750static void 724static void
751nat_server_read (void *cls, 725nat_server_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
752 const struct GNUNET_SCHEDULER_TaskContext *tc)
753{ 726{
754 struct GNUNET_NAT_Handle *h = cls; 727 struct GNUNET_NAT_Handle *h = cls;
755 char mybuf[40]; 728 char mybuf[40];
@@ -760,52 +733,53 @@ nat_server_read (void *cls,
760 struct sockaddr_in sin_addr; 733 struct sockaddr_in sin_addr;
761 734
762 h->server_read_task = GNUNET_SCHEDULER_NO_TASK; 735 h->server_read_task = GNUNET_SCHEDULER_NO_TASK;
763 if ( (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) 736 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
764 return; 737 return;
765 memset (mybuf, 0, sizeof(mybuf)); 738 memset (mybuf, 0, sizeof (mybuf));
766 bytes = GNUNET_DISK_file_read(h->server_stdout_handle, 739 bytes = GNUNET_DISK_file_read (h->server_stdout_handle,
767 mybuf, 740 mybuf, sizeof (mybuf));
768 sizeof(mybuf));
769 if (bytes < 1) 741 if (bytes < 1)
770 { 742 {
771#if DEBUG_NAT 743#if DEBUG_NAT
772 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 744 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
773 "nat", 745 "nat",
774 "Finished reading from server stdout with code: %d\n", 746 "Finished reading from server stdout with code: %d\n",
775 bytes); 747 bytes);
776#endif 748#endif
777 if (0 != GNUNET_OS_process_kill (h->server_proc, SIGTERM)) 749 if (0 != GNUNET_OS_process_kill (h->server_proc, SIGTERM))
778 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); 750 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
779 GNUNET_OS_process_wait (h->server_proc); 751 GNUNET_OS_process_wait (h->server_proc);
780 GNUNET_OS_process_close (h->server_proc); 752 GNUNET_OS_process_close (h->server_proc);
781 h->server_proc = NULL; 753 h->server_proc = NULL;
782 GNUNET_DISK_pipe_close (h->server_stdout); 754 GNUNET_DISK_pipe_close (h->server_stdout);
783 h->server_stdout = NULL; 755 h->server_stdout = NULL;
784 h->server_stdout_handle = NULL; 756 h->server_stdout_handle = NULL;
785 /* now try to restart it */ 757 /* now try to restart it */
786 h->server_retry_delay = GNUNET_TIME_relative_multiply (h->server_retry_delay, 2); 758 h->server_retry_delay =
787 h->server_retry_delay = GNUNET_TIME_relative_max (GNUNET_TIME_UNIT_HOURS, 759 GNUNET_TIME_relative_multiply (h->server_retry_delay, 2);
788 h->server_retry_delay); 760 h->server_retry_delay =
789 h->server_read_task = GNUNET_SCHEDULER_add_delayed (h->server_retry_delay, 761 GNUNET_TIME_relative_max (GNUNET_TIME_UNIT_HOURS,
790 &restart_nat_server, 762 h->server_retry_delay);
791 h); 763 h->server_read_task =
792 return; 764 GNUNET_SCHEDULER_add_delayed (h->server_retry_delay,
793 } 765 &restart_nat_server, h);
766 return;
767 }
794 768
795 port_start = NULL; 769 port_start = NULL;
796 for (i = 0; i < sizeof(mybuf); i++) 770 for (i = 0; i < sizeof (mybuf); i++)
771 {
772 if (mybuf[i] == '\n')
773 {
774 mybuf[i] = '\0';
775 break;
776 }
777 if ((mybuf[i] == ':') && (i + 1 < sizeof (mybuf)))
797 { 778 {
798 if (mybuf[i] == '\n') 779 mybuf[i] = '\0';
799 { 780 port_start = &mybuf[i + 1];
800 mybuf[i] = '\0';
801 break;
802 }
803 if ( (mybuf[i] == ':') && (i + 1 < sizeof(mybuf)) )
804 {
805 mybuf[i] = '\0';
806 port_start = &mybuf[i + 1];
807 }
808 } 781 }
782 }
809 783
810 /* construct socket address of sender */ 784 /* construct socket address of sender */
811 memset (&sin_addr, 0, sizeof (sin_addr)); 785 memset (&sin_addr, 0, sizeof (sin_addr));
@@ -813,37 +787,34 @@ nat_server_read (void *cls,
813#if HAVE_SOCKADDR_IN_SIN_LEN 787#if HAVE_SOCKADDR_IN_SIN_LEN
814 sin_addr.sin_len = sizeof (sin_addr); 788 sin_addr.sin_len = sizeof (sin_addr);
815#endif 789#endif
816 if ( (NULL == port_start) || 790 if ((NULL == port_start) ||
817 (1 != sscanf (port_start, "%d", &port)) || 791 (1 != sscanf (port_start, "%d", &port)) ||
818 (-1 == inet_pton(AF_INET, mybuf, &sin_addr.sin_addr)) ) 792 (-1 == inet_pton (AF_INET, mybuf, &sin_addr.sin_addr)))
819 { 793 {
820 /* should we restart gnunet-helper-nat-server? */ 794 /* should we restart gnunet-helper-nat-server? */
821 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, 795 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING,
822 "nat", 796 "nat",
823 _("gnunet-helper-nat-server generated malformed address `%s'\n"), 797 _
824 mybuf); 798 ("gnunet-helper-nat-server generated malformed address `%s'\n"),
825 h->server_read_task 799 mybuf);
826 = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, 800 h->server_read_task =
827 h->server_stdout_handle, 801 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
828 &nat_server_read, 802 h->server_stdout_handle,
829 h); 803 &nat_server_read, h);
830 return; 804 return;
831 } 805 }
832 sin_addr.sin_port = htons((uint16_t) port); 806 sin_addr.sin_port = htons ((uint16_t) port);
833#if DEBUG_NAT 807#if DEBUG_NAT
834 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 808 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
835 "nat", 809 "nat",
836 "gnunet-helper-nat-server read: %s:%d\n", 810 "gnunet-helper-nat-server read: %s:%d\n", mybuf, port);
837 mybuf, port);
838#endif 811#endif
839 h->reversal_callback (h->callback_cls, 812 h->reversal_callback (h->callback_cls,
840 (const struct sockaddr*) &sin_addr, 813 (const struct sockaddr *) &sin_addr, sizeof (sin_addr));
841 sizeof (sin_addr));
842 h->server_read_task = 814 h->server_read_task =
843 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, 815 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
844 h->server_stdout_handle, 816 h->server_stdout_handle,
845 &nat_server_read, 817 &nat_server_read, h);
846 h);
847} 818}
848 819
849 820
@@ -856,51 +827,45 @@ nat_server_read (void *cls,
856static void 827static void
857start_gnunet_nat_server (struct GNUNET_NAT_Handle *h) 828start_gnunet_nat_server (struct GNUNET_NAT_Handle *h)
858{ 829{
859 if ( (h->behind_nat == GNUNET_YES) && 830 if ((h->behind_nat == GNUNET_YES) &&
860 (h->enable_nat_server == GNUNET_YES) && 831 (h->enable_nat_server == GNUNET_YES) &&
861 (h->internal_address != NULL) && 832 (h->internal_address != NULL) &&
862 (NULL != (h->server_stdout = GNUNET_DISK_pipe (GNUNET_YES, 833 (NULL != (h->server_stdout = GNUNET_DISK_pipe (GNUNET_YES,
863 GNUNET_NO, 834 GNUNET_NO, GNUNET_YES))))
864 GNUNET_YES))) ) 835 {
865 {
866#if DEBUG_NAT 836#if DEBUG_NAT
867 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 837 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
868 "nat" 838 "nat"
869 "Starting %s at `%s'\n", 839 "Starting %s at `%s'\n",
870 "gnunet-helper-nat-server", 840 "gnunet-helper-nat-server", h->internal_address);
871 h->internal_address);
872#endif 841#endif
873 /* Start the server process */ 842 /* Start the server process */
874 h->server_proc = GNUNET_OS_start_process (NULL, 843 h->server_proc = GNUNET_OS_start_process (NULL,
875 h->server_stdout, 844 h->server_stdout,
876 "gnunet-helper-nat-server", 845 "gnunet-helper-nat-server",
877 "gnunet-helper-nat-server", 846 "gnunet-helper-nat-server",
878 h->internal_address, 847 h->internal_address, NULL);
879 NULL); 848 if (h->server_proc == NULL)
880 if (h->server_proc == NULL) 849 {
881 { 850 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING,
882 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, 851 "nat",
883 "nat", 852 _("Failed to start %s\n"), "gnunet-helper-nat-server");
884 _("Failed to start %s\n"), 853 GNUNET_DISK_pipe_close (h->server_stdout);
885 "gnunet-helper-nat-server"); 854 h->server_stdout = NULL;
886 GNUNET_DISK_pipe_close (h->server_stdout); 855 }
887 h->server_stdout = NULL; 856 else
888 } 857 {
889 else 858 /* Close the write end of the read pipe */
890 { 859 GNUNET_DISK_pipe_close_end (h->server_stdout, GNUNET_DISK_PIPE_END_WRITE);
891 /* Close the write end of the read pipe */ 860 h->server_stdout_handle
892 GNUNET_DISK_pipe_close_end(h->server_stdout, 861 = GNUNET_DISK_pipe_handle (h->server_stdout,
893 GNUNET_DISK_PIPE_END_WRITE); 862 GNUNET_DISK_PIPE_END_READ);
894 h->server_stdout_handle 863 h->server_read_task
895 = GNUNET_DISK_pipe_handle (h->server_stdout, 864 = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
896 GNUNET_DISK_PIPE_END_READ); 865 h->server_stdout_handle,
897 h->server_read_task 866 &nat_server_read, h);
898 = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, 867 }
899 h->server_stdout_handle, 868 }
900 &nat_server_read,
901 h);
902 }
903 }
904} 869}
905 870
906 871
@@ -911,16 +876,15 @@ start_gnunet_nat_server (struct GNUNET_NAT_Handle *h)
911 * @param tc scheduler context 876 * @param tc scheduler context
912 */ 877 */
913static void 878static void
914list_interfaces (void *cls, 879list_interfaces (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
915 const struct GNUNET_SCHEDULER_TaskContext *tc)
916{ 880{
917 struct GNUNET_NAT_Handle *h = cls; 881 struct GNUNET_NAT_Handle *h = cls;
918 882
919 h->ifc_task = GNUNET_SCHEDULER_NO_TASK; 883 h->ifc_task = GNUNET_SCHEDULER_NO_TASK;
920 remove_from_address_list_by_source (h, LAL_INTERFACE_ADDRESS); 884 remove_from_address_list_by_source (h, LAL_INTERFACE_ADDRESS);
921 GNUNET_OS_network_interfaces_list (&process_interfaces, h); 885 GNUNET_OS_network_interfaces_list (&process_interfaces, h);
922 h->ifc_task = GNUNET_SCHEDULER_add_delayed (h->ifc_scan_frequency, 886 h->ifc_task = GNUNET_SCHEDULER_add_delayed (h->ifc_scan_frequency,
923 &list_interfaces, h); 887 &list_interfaces, h);
924} 888}
925 889
926 890
@@ -931,17 +895,15 @@ list_interfaces (void *cls,
931 * @param tc scheduler context 895 * @param tc scheduler context
932 */ 896 */
933static void 897static void
934resolve_hostname (void *cls, 898resolve_hostname (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
935 const struct GNUNET_SCHEDULER_TaskContext *tc)
936{ 899{
937 struct GNUNET_NAT_Handle *h = cls; 900 struct GNUNET_NAT_Handle *h = cls;
938 901
939 h->hostname_task = GNUNET_SCHEDULER_NO_TASK; 902 h->hostname_task = GNUNET_SCHEDULER_NO_TASK;
940 remove_from_address_list_by_source (h, LAL_HOSTNAME_DNS); 903 remove_from_address_list_by_source (h, LAL_HOSTNAME_DNS);
941 h->hostname_dns = GNUNET_RESOLVER_hostname_resolve (AF_UNSPEC, 904 h->hostname_dns = GNUNET_RESOLVER_hostname_resolve (AF_UNSPEC,
942 HOSTNAME_RESOLVE_TIMEOUT, 905 HOSTNAME_RESOLVE_TIMEOUT,
943 &process_hostname_ip, 906 &process_hostname_ip, h);
944 h);
945} 907}
946 908
947 909
@@ -953,18 +915,16 @@ resolve_hostname (void *cls,
953 * @param tc scheduler context 915 * @param tc scheduler context
954 */ 916 */
955static void 917static void
956resolve_dns (void *cls, 918resolve_dns (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
957 const struct GNUNET_SCHEDULER_TaskContext *tc)
958{ 919{
959 struct GNUNET_NAT_Handle *h = cls; 920 struct GNUNET_NAT_Handle *h = cls;
960 921
961 h->dns_task = GNUNET_SCHEDULER_NO_TASK; 922 h->dns_task = GNUNET_SCHEDULER_NO_TASK;
962 remove_from_address_list_by_source (h, LAL_EXTERNAL_IP); 923 remove_from_address_list_by_source (h, LAL_EXTERNAL_IP);
963 h->ext_dns = GNUNET_RESOLVER_ip_get (h->external_address, 924 h->ext_dns = GNUNET_RESOLVER_ip_get (h->external_address,
964 AF_INET, 925 AF_INET,
965 GNUNET_TIME_UNIT_MINUTES, 926 GNUNET_TIME_UNIT_MINUTES,
966 &process_external_ip, 927 &process_external_ip, h);
967 h);
968} 928}
969 929
970 930
@@ -977,45 +937,35 @@ resolve_dns (void *cls,
977 * @param addr either the previous or the new public IP address 937 * @param addr either the previous or the new public IP address
978 * @param addrlen actual lenght of the address 938 * @param addrlen actual lenght of the address
979 */ 939 */
980static void 940static void
981upnp_add (void *cls, 941upnp_add (void *cls,
982 int add_remove, 942 int add_remove, const struct sockaddr *addr, socklen_t addrlen)
983 const struct sockaddr *addr,
984 socklen_t addrlen)
985{ 943{
986 struct GNUNET_NAT_Handle *h = cls; 944 struct GNUNET_NAT_Handle *h = cls;
987 struct LocalAddressList *pos; 945 struct LocalAddressList *pos;
988 struct LocalAddressList *next; 946 struct LocalAddressList *next;
989 947
990 if (GNUNET_YES == add_remove) 948 if (GNUNET_YES == add_remove)
991 { 949 {
992 add_to_address_list (h, 950 add_to_address_list (h, LAL_UPNP, addr, addrlen);
993 LAL_UPNP, 951 return;
994 addr, addrlen); 952 }
995 return;
996 }
997 /* remove address */ 953 /* remove address */
998 next = h->lal_head; 954 next = h->lal_head;
999 while (NULL != (pos = next)) 955 while (NULL != (pos = next))
1000 { 956 {
1001 next = pos->next; 957 next = pos->next;
1002 if ( (pos->source != LAL_UPNP) || 958 if ((pos->source != LAL_UPNP) ||
1003 (pos->addrlen != addrlen) || 959 (pos->addrlen != addrlen) || (0 != memcmp (&pos[1], addr, addrlen)))
1004 (0 != memcmp (&pos[1], 960 continue;
1005 addr, 961 GNUNET_CONTAINER_DLL_remove (h->lal_head, h->lal_tail, pos);
1006 addrlen)) ) 962 if (NULL != h->address_callback)
1007 continue; 963 h->address_callback (h->callback_cls,
1008 GNUNET_CONTAINER_DLL_remove (h->lal_head, 964 GNUNET_NO,
1009 h->lal_tail, 965 (const struct sockaddr *) &pos[1], pos->addrlen);
1010 pos); 966 GNUNET_free (pos);
1011 if (NULL != h->address_callback) 967 return; /* only remove once */
1012 h->address_callback (h->callback_cls, 968 }
1013 GNUNET_NO,
1014 (const struct sockaddr* ) &pos[1],
1015 pos->addrlen);
1016 GNUNET_free (pos);
1017 return; /* only remove once */
1018 }
1019 /* asked to remove address that does not exist */ 969 /* asked to remove address that does not exist */
1020 GNUNET_break (0); 970 GNUNET_break (0);
1021} 971}
@@ -1028,26 +978,21 @@ upnp_add (void *cls,
1028 * @param port port to map with UPnP 978 * @param port port to map with UPnP
1029 */ 979 */
1030static void 980static void
1031add_minis (struct GNUNET_NAT_Handle *h, 981add_minis (struct GNUNET_NAT_Handle *h, uint16_t port)
1032 uint16_t port)
1033{ 982{
1034 struct MiniList *ml; 983 struct MiniList *ml;
1035 984
1036 ml = h->mini_head; 985 ml = h->mini_head;
1037 while (NULL != ml) 986 while (NULL != ml)
1038 { 987 {
1039 if (port == ml->port) 988 if (port == ml->port)
1040 return; /* already got this port */ 989 return; /* already got this port */
1041 ml = ml->next; 990 ml = ml->next;
1042 } 991 }
1043 ml = GNUNET_malloc (sizeof (struct MiniList)); 992 ml = GNUNET_malloc (sizeof (struct MiniList));
1044 ml->port = port; 993 ml->port = port;
1045 ml->mini = GNUNET_NAT_mini_map_start (port, 994 ml->mini = GNUNET_NAT_mini_map_start (port, h->is_tcp, &upnp_add, h);
1046 h->is_tcp, 995 GNUNET_CONTAINER_DLL_insert (h->mini_head, h->mini_tail, ml);
1047 &upnp_add, h);
1048 GNUNET_CONTAINER_DLL_insert (h->mini_head,
1049 h->mini_tail,
1050 ml);
1051} 996}
1052 997
1053 998
@@ -1058,8 +1003,7 @@ add_minis (struct GNUNET_NAT_Handle *h,
1058 * @param tc scheduler context 1003 * @param tc scheduler context
1059 */ 1004 */
1060static void 1005static void
1061add_from_bind (void *cls, 1006add_from_bind (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1062 const struct GNUNET_SCHEDULER_TaskContext *tc)
1063{ 1007{
1064 static struct in6_addr any = IN6ADDR_ANY_INIT; 1008 static struct in6_addr any = IN6ADDR_ANY_INIT;
1065 struct GNUNET_NAT_Handle *h = cls; 1009 struct GNUNET_NAT_Handle *h = cls;
@@ -1068,38 +1012,39 @@ add_from_bind (void *cls,
1068 const struct sockaddr_in *v4; 1012 const struct sockaddr_in *v4;
1069 1013
1070 h->bind_task = GNUNET_SCHEDULER_NO_TASK; 1014 h->bind_task = GNUNET_SCHEDULER_NO_TASK;
1071 for (i=0;i<h->num_local_addrs;i++) 1015 for (i = 0; i < h->num_local_addrs; i++)
1016 {
1017 sa = h->local_addrs[i];
1018 switch (sa->sa_family)
1072 { 1019 {
1073 sa = h->local_addrs[i]; 1020 case AF_INET:
1074 switch (sa->sa_family) 1021 if (sizeof (struct sockaddr_in) != h->local_addrlens[i])
1075 { 1022 {
1076 case AF_INET: 1023 GNUNET_break (0);
1077 if (sizeof (struct sockaddr_in) != h->local_addrlens[i]) 1024 break;
1078 { 1025 }
1079 GNUNET_break (0); 1026 v4 = (const struct sockaddr_in *) sa;
1080 break; 1027 if (0 != v4->sin_addr.s_addr)
1081 } 1028 add_to_address_list (h, LAL_BINDTO_ADDRESS, sa,
1082 v4 = (const struct sockaddr_in*) sa; 1029 sizeof (struct sockaddr_in));
1083 if (0 != v4->sin_addr.s_addr) 1030 if (h->enable_upnp)
1084 add_to_address_list (h, LAL_BINDTO_ADDRESS, sa, sizeof (struct sockaddr_in)); 1031 add_minis (h, ntohs (v4->sin_port));
1085 if (h->enable_upnp) 1032 break;
1086 add_minis (h, ntohs (v4->sin_port)); 1033 case AF_INET6:
1087 break; 1034 if (sizeof (struct sockaddr_in6) != h->local_addrlens[i])
1088 case AF_INET6: 1035 {
1089 if (sizeof (struct sockaddr_in6) != h->local_addrlens[i]) 1036 GNUNET_break (0);
1090 { 1037 break;
1091 GNUNET_break (0); 1038 }
1092 break; 1039 if (0 != memcmp (&((const struct sockaddr_in6 *) sa)->sin6_addr,
1093 } 1040 &any, sizeof (struct in6_addr)))
1094 if (0 != memcmp (&((const struct sockaddr_in6*) sa)->sin6_addr, 1041 add_to_address_list (h, LAL_BINDTO_ADDRESS, sa,
1095 &any, 1042 sizeof (struct sockaddr_in6));
1096 sizeof (struct in6_addr))) 1043 break;
1097 add_to_address_list (h, LAL_BINDTO_ADDRESS, sa, sizeof (struct sockaddr_in6)); 1044 default:
1098 break; 1045 break;
1099 default:
1100 break;
1101 }
1102 } 1046 }
1047 }
1103} 1048}
1104 1049
1105 1050
@@ -1124,14 +1069,14 @@ add_from_bind (void *cls,
1124 */ 1069 */
1125struct GNUNET_NAT_Handle * 1070struct GNUNET_NAT_Handle *
1126GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, 1071GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg,
1127 int is_tcp, 1072 int is_tcp,
1128 uint16_t adv_port, 1073 uint16_t adv_port,
1129 unsigned int num_addrs, 1074 unsigned int num_addrs,
1130 const struct sockaddr **addrs, 1075 const struct sockaddr **addrs,
1131 const socklen_t *addrlens, 1076 const socklen_t * addrlens,
1132 GNUNET_NAT_AddressCallback address_callback, 1077 GNUNET_NAT_AddressCallback address_callback,
1133 GNUNET_NAT_ReversalCallback reversal_callback, 1078 GNUNET_NAT_ReversalCallback reversal_callback,
1134 void *callback_cls) 1079 void *callback_cls)
1135{ 1080{
1136 struct GNUNET_NAT_Handle *h; 1081 struct GNUNET_NAT_Handle *h;
1137 struct in_addr in_addr; 1082 struct in_addr in_addr;
@@ -1139,10 +1084,9 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg,
1139 1084
1140#if DEBUG_NAT 1085#if DEBUG_NAT
1141 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 1086 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1142 "nat", 1087 "nat",
1143 "Registered with NAT service at port %u with %u IP bound local addresses\n", 1088 "Registered with NAT service at port %u with %u IP bound local addresses\n",
1144 (unsigned int) adv_port, 1089 (unsigned int) adv_port, num_addrs);
1145 num_addrs);
1146#endif 1090#endif
1147 h = GNUNET_malloc (sizeof (struct GNUNET_NAT_Handle)); 1091 h = GNUNET_malloc (sizeof (struct GNUNET_NAT_Handle));
1148 h->server_retry_delay = GNUNET_TIME_UNIT_SECONDS; 1092 h->server_retry_delay = GNUNET_TIME_UNIT_SECONDS;
@@ -1154,147 +1098,140 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg,
1154 h->num_local_addrs = num_addrs; 1098 h->num_local_addrs = num_addrs;
1155 h->adv_port = adv_port; 1099 h->adv_port = adv_port;
1156 if (num_addrs != 0) 1100 if (num_addrs != 0)
1101 {
1102 h->local_addrs = GNUNET_malloc (num_addrs * sizeof (struct sockaddr *));
1103 h->local_addrlens = GNUNET_malloc (num_addrs * sizeof (socklen_t));
1104 for (i = 0; i < num_addrs; i++)
1157 { 1105 {
1158 h->local_addrs = GNUNET_malloc (num_addrs * sizeof (struct sockaddr*)); 1106 GNUNET_assert (addrlens[i] > 0);
1159 h->local_addrlens = GNUNET_malloc (num_addrs * sizeof (socklen_t)); 1107 GNUNET_assert (addrs[i] != NULL);
1160 for (i=0;i<num_addrs;i++) 1108 h->local_addrlens[i] = addrlens[i];
1161 { 1109 h->local_addrs[i] = GNUNET_malloc (addrlens[i]);
1162 GNUNET_assert (addrlens[i] > 0); 1110 memcpy (h->local_addrs[i], addrs[i], addrlens[i]);
1163 GNUNET_assert (addrs[i] != NULL);
1164 h->local_addrlens[i] = addrlens[i];
1165 h->local_addrs[i] = GNUNET_malloc (addrlens[i]);
1166 memcpy (h->local_addrs[i], addrs[i], addrlens[i]);
1167 }
1168 } 1111 }
1112 }
1169 h->bind_task = GNUNET_SCHEDULER_add_now (&add_from_bind, h); 1113 h->bind_task = GNUNET_SCHEDULER_add_now (&add_from_bind, h);
1170 if (GNUNET_OK == 1114 if (GNUNET_OK ==
1171 GNUNET_CONFIGURATION_have_value (cfg, 1115 GNUNET_CONFIGURATION_have_value (cfg, "nat", "INTERNAL_ADDRESS"))
1172 "nat", 1116 {
1173 "INTERNAL_ADDRESS")) 1117 (void) GNUNET_CONFIGURATION_get_value_string (cfg,
1174 { 1118 "nat",
1175 (void) GNUNET_CONFIGURATION_get_value_string (cfg, 1119 "INTERNAL_ADDRESS",
1176 "nat", 1120 &h->internal_address);
1177 "INTERNAL_ADDRESS", 1121 }
1178 &h->internal_address); 1122 if ((h->internal_address != NULL) &&
1179 } 1123 (inet_pton (AF_INET, h->internal_address, &in_addr) != 1))
1180 if ( (h->internal_address != NULL) && 1124 {
1181 (inet_pton(AF_INET, h->internal_address, &in_addr) != 1) ) 1125 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING,
1182 { 1126 "nat",
1183 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, 1127 _("Malformed %s `%s' given in configuration!\n"),
1184 "nat", 1128 "INTERNAL_ADDRESS", h->internal_address);
1185 _("Malformed %s `%s' given in configuration!\n"), 1129 GNUNET_free (h->internal_address);
1186 "INTERNAL_ADDRESS", 1130 h->internal_address = NULL;
1187 h->internal_address); 1131 }
1188 GNUNET_free (h->internal_address);
1189 h->internal_address = NULL;
1190 }
1191 1132
1192 if (GNUNET_OK == 1133 if (GNUNET_OK ==
1193 GNUNET_CONFIGURATION_have_value (cfg, 1134 GNUNET_CONFIGURATION_have_value (cfg, "nat", "EXTERNAL_ADDRESS"))
1194 "nat", 1135 {
1195 "EXTERNAL_ADDRESS")) 1136 (void) GNUNET_CONFIGURATION_get_value_string (cfg,
1196 { 1137 "nat",
1197 (void) GNUNET_CONFIGURATION_get_value_string (cfg, 1138 "EXTERNAL_ADDRESS",
1198 "nat", 1139 &h->external_address);
1199 "EXTERNAL_ADDRESS", 1140 }
1200 &h->external_address); 1141 if ((h->external_address != NULL) &&
1201 } 1142 (inet_pton (AF_INET, h->external_address, &in_addr) != 1))
1202 if ( (h->external_address != NULL) && 1143 {
1203 (inet_pton(AF_INET, h->external_address, &in_addr) != 1) ) 1144 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING,
1204 { 1145 "nat",
1205 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, 1146 _("Malformed %s `%s' given in configuration!\n"),
1206 "nat", 1147 "EXTERNAL_ADDRESS", h->external_address);
1207 _("Malformed %s `%s' given in configuration!\n"), 1148 GNUNET_free (h->external_address);
1208 "EXTERNAL_ADDRESS", 1149 h->external_address = NULL;
1209 h->external_address); 1150 }
1210 GNUNET_free (h->external_address);
1211 h->external_address = NULL;
1212 }
1213 h->behind_nat = GNUNET_CONFIGURATION_get_value_yesno (cfg, 1151 h->behind_nat = GNUNET_CONFIGURATION_get_value_yesno (cfg,
1214 "nat", 1152 "nat", "BEHIND_NAT");
1215 "BEHIND_NAT");
1216 h->nat_punched = GNUNET_CONFIGURATION_get_value_yesno (cfg, 1153 h->nat_punched = GNUNET_CONFIGURATION_get_value_yesno (cfg,
1217 "nat", 1154 "nat", "PUNCHED_NAT");
1218 "PUNCHED_NAT");
1219 h->enable_nat_client = GNUNET_CONFIGURATION_get_value_yesno (cfg, 1155 h->enable_nat_client = GNUNET_CONFIGURATION_get_value_yesno (cfg,
1220 "nat", 1156 "nat",
1221 "ENABLE_NAT_CLIENT"); 1157 "ENABLE_NAT_CLIENT");
1222 h->enable_nat_server = GNUNET_CONFIGURATION_get_value_yesno (cfg, 1158 h->enable_nat_server = GNUNET_CONFIGURATION_get_value_yesno (cfg,
1223 "nat", 1159 "nat",
1224 "ENABLE_NAT_SERVER"); 1160 "ENABLE_NAT_SERVER");
1225 h->enable_upnp = GNUNET_CONFIGURATION_get_value_yesno (cfg, 1161 h->enable_upnp = GNUNET_CONFIGURATION_get_value_yesno (cfg,
1226 "nat", 1162 "nat", "ENABLE_UPNP");
1227 "ENABLE_UPNP");
1228 h->use_localaddresses = GNUNET_CONFIGURATION_get_value_yesno (cfg, 1163 h->use_localaddresses = GNUNET_CONFIGURATION_get_value_yesno (cfg,
1229 "nat", 1164 "nat",
1230 "USE_LOCALADDR"); 1165 "USE_LOCALADDR");
1231 h->use_hostname = GNUNET_CONFIGURATION_get_value_yesno (cfg, 1166 h->use_hostname = GNUNET_CONFIGURATION_get_value_yesno (cfg,
1232 "nat", 1167 "nat",
1233 "USE_HOSTNAME"); 1168 "USE_HOSTNAME");
1234 h->disable_ipv6 = GNUNET_CONFIGURATION_get_value_yesno(cfg, 1169 h->disable_ipv6 = GNUNET_CONFIGURATION_get_value_yesno (cfg,
1235 "nat", 1170 "nat", "DISABLEV6");
1236 "DISABLEV6");
1237 if (GNUNET_OK != 1171 if (GNUNET_OK !=
1238 GNUNET_CONFIGURATION_get_value_time (cfg, 1172 GNUNET_CONFIGURATION_get_value_time (cfg,
1239 "nat", 1173 "nat",
1240 "DYNDNS_FREQUENCY", 1174 "DYNDNS_FREQUENCY",
1241 &h->dyndns_frequency)) 1175 &h->dyndns_frequency))
1242 h->dyndns_frequency = DYNDNS_FREQUENCY; 1176 h->dyndns_frequency = DYNDNS_FREQUENCY;
1243 if (GNUNET_OK != 1177 if (GNUNET_OK !=
1244 GNUNET_CONFIGURATION_get_value_time (cfg, 1178 GNUNET_CONFIGURATION_get_value_time (cfg,
1245 "nat", 1179 "nat",
1246 "IFC_SCAN_FREQUENCY", 1180 "IFC_SCAN_FREQUENCY",
1247 &h->ifc_scan_frequency)) 1181 &h->ifc_scan_frequency))
1248 h->ifc_scan_frequency = IFC_SCAN_FREQUENCY; 1182 h->ifc_scan_frequency = IFC_SCAN_FREQUENCY;
1249 if (GNUNET_OK != 1183 if (GNUNET_OK !=
1250 GNUNET_CONFIGURATION_get_value_time (cfg, 1184 GNUNET_CONFIGURATION_get_value_time (cfg,
1251 "nat", 1185 "nat",
1252 "HOSTNAME_DNS_FREQUENCY", 1186 "HOSTNAME_DNS_FREQUENCY",
1253 &h->hostname_dns_frequency)) 1187 &h->hostname_dns_frequency))
1254 h->hostname_dns_frequency = HOSTNAME_DNS_FREQUENCY; 1188 h->hostname_dns_frequency = HOSTNAME_DNS_FREQUENCY;
1255 1189
1256 if (NULL == reversal_callback) 1190 if (NULL == reversal_callback)
1257 h->enable_nat_server = GNUNET_NO; 1191 h->enable_nat_server = GNUNET_NO;
1258 1192
1259 /* Check if NAT was hole-punched */ 1193 /* Check if NAT was hole-punched */
1260 if ( (NULL != h->address_callback) && 1194 if ((NULL != h->address_callback) &&
1261 (h->external_address != NULL) && 1195 (h->external_address != NULL) && (h->nat_punched == GNUNET_YES))
1262 (h->nat_punched == GNUNET_YES) ) 1196 {
1263 { 1197 h->dns_task = GNUNET_SCHEDULER_add_now (&resolve_dns, h);
1264 h->dns_task = GNUNET_SCHEDULER_add_now (&resolve_dns, h); 1198 h->enable_nat_server = GNUNET_NO;
1265 h->enable_nat_server = GNUNET_NO; 1199 h->enable_upnp = GNUNET_NO;
1266 h->enable_upnp = GNUNET_NO; 1200 }
1267 }
1268 1201
1269 /* Test for SUID binaries */ 1202 /* Test for SUID binaries */
1270 if ( (h->behind_nat == GNUNET_YES) && 1203 if ((h->behind_nat == GNUNET_YES) &&
1271 (GNUNET_YES == h->enable_nat_server) && 1204 (GNUNET_YES == h->enable_nat_server) &&
1272 (GNUNET_YES != GNUNET_OS_check_helper_binary("gnunet-helper-nat-server")) ) 1205 (GNUNET_YES !=
1273 { 1206 GNUNET_OS_check_helper_binary ("gnunet-helper-nat-server")))
1274 h->enable_nat_server = GNUNET_NO; 1207 {
1275 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1208 h->enable_nat_server = GNUNET_NO;
1276 _("Configuration requires `%s', but binary is not installed properly (SUID bit not set). Option disabled.\n"), 1209 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1277 "gnunet-helper-nat-server"); 1210 _
1278 } 1211 ("Configuration requires `%s', but binary is not installed properly (SUID bit not set). Option disabled.\n"),
1279 if ( (GNUNET_YES == h->enable_nat_client) && 1212 "gnunet-helper-nat-server");
1280 (GNUNET_YES != GNUNET_OS_check_helper_binary("gnunet-helper-nat-client")) ) 1213 }
1281 { 1214 if ((GNUNET_YES == h->enable_nat_client) &&
1282 h->enable_nat_client = GNUNET_NO; 1215 (GNUNET_YES !=
1283 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1216 GNUNET_OS_check_helper_binary ("gnunet-helper-nat-client")))
1284 _("Configuration requires `%s', but binary is not installed properly (SUID bit not set). Option disabled.\n"), 1217 {
1285 "gnunet-helper-nat-client"); 1218 h->enable_nat_client = GNUNET_NO;
1286 } 1219 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1220 _
1221 ("Configuration requires `%s', but binary is not installed properly (SUID bit not set). Option disabled.\n"),
1222 "gnunet-helper-nat-client");
1223 }
1287 1224
1288 start_gnunet_nat_server (h); 1225 start_gnunet_nat_server (h);
1289 1226
1290 /* FIXME: add support for UPnP, etc */ 1227 /* FIXME: add support for UPnP, etc */
1291 1228
1292 if (NULL != h->address_callback) 1229 if (NULL != h->address_callback)
1293 { 1230 {
1294 h->ifc_task = GNUNET_SCHEDULER_add_now (&list_interfaces, h); 1231 h->ifc_task = GNUNET_SCHEDULER_add_now (&list_interfaces, h);
1295 if (GNUNET_YES == h->use_hostname) 1232 if (GNUNET_YES == h->use_hostname)
1296 h->hostname_task = GNUNET_SCHEDULER_add_now (&resolve_hostname, h); 1233 h->hostname_task = GNUNET_SCHEDULER_add_now (&resolve_hostname, h);
1297 } 1234 }
1298 1235
1299 return h; 1236 return h;
1300} 1237}
@@ -1314,84 +1251,79 @@ GNUNET_NAT_unregister (struct GNUNET_NAT_Handle *h)
1314 struct MiniList *ml; 1251 struct MiniList *ml;
1315 1252
1316 while (NULL != (ml = h->mini_head)) 1253 while (NULL != (ml = h->mini_head))
1317 { 1254 {
1318 GNUNET_CONTAINER_DLL_remove (h->mini_head, 1255 GNUNET_CONTAINER_DLL_remove (h->mini_head, h->mini_tail, ml);
1319 h->mini_tail, 1256 if (NULL != ml->mini)
1320 ml); 1257 GNUNET_NAT_mini_map_stop (ml->mini);
1321 if (NULL != ml->mini) 1258 GNUNET_free (ml);
1322 GNUNET_NAT_mini_map_stop (ml->mini); 1259 }
1323 GNUNET_free (ml);
1324 }
1325 if (h->ext_dns != NULL) 1260 if (h->ext_dns != NULL)
1326 { 1261 {
1327 GNUNET_RESOLVER_request_cancel (h->ext_dns); 1262 GNUNET_RESOLVER_request_cancel (h->ext_dns);
1328 h->ext_dns = NULL; 1263 h->ext_dns = NULL;
1329 } 1264 }
1330 if (NULL != h->hostname_dns) 1265 if (NULL != h->hostname_dns)
1331 { 1266 {
1332 GNUNET_RESOLVER_request_cancel (h->hostname_dns); 1267 GNUNET_RESOLVER_request_cancel (h->hostname_dns);
1333 h->hostname_dns = NULL; 1268 h->hostname_dns = NULL;
1334 } 1269 }
1335 if (GNUNET_SCHEDULER_NO_TASK != h->server_read_task) 1270 if (GNUNET_SCHEDULER_NO_TASK != h->server_read_task)
1336 { 1271 {
1337 GNUNET_SCHEDULER_cancel (h->server_read_task); 1272 GNUNET_SCHEDULER_cancel (h->server_read_task);
1338 h->server_read_task = GNUNET_SCHEDULER_NO_TASK; 1273 h->server_read_task = GNUNET_SCHEDULER_NO_TASK;
1339 } 1274 }
1340 if (GNUNET_SCHEDULER_NO_TASK != h->bind_task) 1275 if (GNUNET_SCHEDULER_NO_TASK != h->bind_task)
1341 { 1276 {
1342 GNUNET_SCHEDULER_cancel (h->bind_task); 1277 GNUNET_SCHEDULER_cancel (h->bind_task);
1343 h->bind_task = GNUNET_SCHEDULER_NO_TASK; 1278 h->bind_task = GNUNET_SCHEDULER_NO_TASK;
1344 } 1279 }
1345 if (GNUNET_SCHEDULER_NO_TASK != h->ifc_task) 1280 if (GNUNET_SCHEDULER_NO_TASK != h->ifc_task)
1346 { 1281 {
1347 GNUNET_SCHEDULER_cancel (h->ifc_task); 1282 GNUNET_SCHEDULER_cancel (h->ifc_task);
1348 h->ifc_task = GNUNET_SCHEDULER_NO_TASK; 1283 h->ifc_task = GNUNET_SCHEDULER_NO_TASK;
1349 } 1284 }
1350 if (GNUNET_SCHEDULER_NO_TASK != h->hostname_task) 1285 if (GNUNET_SCHEDULER_NO_TASK != h->hostname_task)
1351 { 1286 {
1352 GNUNET_SCHEDULER_cancel (h->hostname_task); 1287 GNUNET_SCHEDULER_cancel (h->hostname_task);
1353 h->hostname_task = GNUNET_SCHEDULER_NO_TASK; 1288 h->hostname_task = GNUNET_SCHEDULER_NO_TASK;
1354 } 1289 }
1355 if (GNUNET_SCHEDULER_NO_TASK != h->dns_task) 1290 if (GNUNET_SCHEDULER_NO_TASK != h->dns_task)
1356 { 1291 {
1357 GNUNET_SCHEDULER_cancel (h->dns_task); 1292 GNUNET_SCHEDULER_cancel (h->dns_task);
1358 h->dns_task = GNUNET_SCHEDULER_NO_TASK; 1293 h->dns_task = GNUNET_SCHEDULER_NO_TASK;
1359 } 1294 }
1360 if (NULL != h->server_proc) 1295 if (NULL != h->server_proc)
1361 { 1296 {
1362 if (0 != GNUNET_OS_process_kill (h->server_proc, SIGTERM)) 1297 if (0 != GNUNET_OS_process_kill (h->server_proc, SIGTERM))
1363 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); 1298 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
1364 GNUNET_OS_process_wait (h->server_proc); 1299 GNUNET_OS_process_wait (h->server_proc);
1365 GNUNET_OS_process_close (h->server_proc); 1300 GNUNET_OS_process_close (h->server_proc);
1366 h->server_proc = NULL; 1301 h->server_proc = NULL;
1367 GNUNET_DISK_pipe_close (h->server_stdout); 1302 GNUNET_DISK_pipe_close (h->server_stdout);
1368 h->server_stdout = NULL; 1303 h->server_stdout = NULL;
1369 h->server_stdout_handle = NULL; 1304 h->server_stdout_handle = NULL;
1370 } 1305 }
1371 if (NULL != h->server_stdout) 1306 if (NULL != h->server_stdout)
1372 { 1307 {
1373 GNUNET_DISK_pipe_close (h->server_stdout); 1308 GNUNET_DISK_pipe_close (h->server_stdout);
1374 h->server_stdout = NULL; 1309 h->server_stdout = NULL;
1375 h->server_stdout_handle = NULL; 1310 h->server_stdout_handle = NULL;
1376 } 1311 }
1377 while (NULL != (lal = h->lal_head)) 1312 while (NULL != (lal = h->lal_head))
1378 { 1313 {
1379 GNUNET_CONTAINER_DLL_remove (h->lal_head, 1314 GNUNET_CONTAINER_DLL_remove (h->lal_head, h->lal_tail, lal);
1380 h->lal_tail, 1315 if (NULL != h->address_callback)
1381 lal); 1316 h->address_callback (h->callback_cls,
1382 if (NULL != h->address_callback) 1317 GNUNET_NO,
1383 h->address_callback (h->callback_cls, 1318 (const struct sockaddr *) &lal[1], lal->addrlen);
1384 GNUNET_NO, 1319 GNUNET_free (lal);
1385 (const struct sockaddr*) &lal[1], 1320 }
1386 lal->addrlen); 1321 for (i = 0; i < h->num_local_addrs; i++)
1387 GNUNET_free (lal);
1388 }
1389 for (i=0;i<h->num_local_addrs;i++)
1390 GNUNET_free (h->local_addrs[i]); 1322 GNUNET_free (h->local_addrs[i]);
1391 GNUNET_free_non_null (h->local_addrs); 1323 GNUNET_free_non_null (h->local_addrs);
1392 GNUNET_free_non_null (h->local_addrlens); 1324 GNUNET_free_non_null (h->local_addrlens);
1393 GNUNET_free_non_null (h->external_address); 1325 GNUNET_free_non_null (h->external_address);
1394 GNUNET_free_non_null (h->internal_address); 1326 GNUNET_free_non_null (h->internal_address);
1395 GNUNET_free (h); 1327 GNUNET_free (h);
1396} 1328}
1397 1329
@@ -1406,54 +1338,46 @@ GNUNET_NAT_unregister (struct GNUNET_NAT_Handle *h)
1406 */ 1338 */
1407void 1339void
1408GNUNET_NAT_run_client (struct GNUNET_NAT_Handle *h, 1340GNUNET_NAT_run_client (struct GNUNET_NAT_Handle *h,
1409 const struct sockaddr_in *sa) 1341 const struct sockaddr_in *sa)
1410{ 1342{
1411 char inet4[INET_ADDRSTRLEN]; 1343 char inet4[INET_ADDRSTRLEN];
1412 char port_as_string[6]; 1344 char port_as_string[6];
1413 struct GNUNET_OS_Process *proc; 1345 struct GNUNET_OS_Process *proc;
1414 1346
1415 if (GNUNET_YES != h->enable_nat_client) 1347 if (GNUNET_YES != h->enable_nat_client)
1416 return; /* not permitted / possible */ 1348 return; /* not permitted / possible */
1417 1349
1418 if (h->internal_address == NULL) 1350 if (h->internal_address == NULL)
1419 { 1351 {
1420 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, 1352 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING,
1421 "nat", 1353 "nat",
1422 _("Internal IP address not known, cannot use ICMP NAT traversal method\n")); 1354 _
1423 return; 1355 ("Internal IP address not known, cannot use ICMP NAT traversal method\n"));
1424 } 1356 return;
1357 }
1425 GNUNET_assert (sa->sin_family == AF_INET); 1358 GNUNET_assert (sa->sin_family == AF_INET);
1426 if (NULL == inet_ntop (AF_INET, 1359 if (NULL == inet_ntop (AF_INET, &sa->sin_addr, inet4, INET_ADDRSTRLEN))
1427 &sa->sin_addr, 1360 {
1428 inet4, INET_ADDRSTRLEN)) 1361 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "inet_ntop");
1429 { 1362 return;
1430 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "inet_ntop"); 1363 }
1431 return; 1364 GNUNET_snprintf (port_as_string, sizeof (port_as_string), "%d", h->adv_port);
1432 }
1433 GNUNET_snprintf (port_as_string,
1434 sizeof (port_as_string),
1435 "%d",
1436 h->adv_port);
1437#if DEBUG_NAT 1365#if DEBUG_NAT
1438 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 1366 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1439 "nat", 1367 "nat",
1440 _("Running gnunet-helper-nat-client %s %s %u\n"), 1368 _("Running gnunet-helper-nat-client %s %s %u\n"),
1441 h->internal_address, 1369 h->internal_address, inet4, (unsigned int) h->adv_port);
1442 inet4,
1443 (unsigned int) h->adv_port);
1444#endif 1370#endif
1445 proc = GNUNET_OS_start_process (NULL, 1371 proc = GNUNET_OS_start_process (NULL,
1446 NULL, 1372 NULL,
1447 "gnunet-helper-nat-client", 1373 "gnunet-helper-nat-client",
1448 "gnunet-helper-nat-client", 1374 "gnunet-helper-nat-client",
1449 h->internal_address, 1375 h->internal_address,
1450 inet4, 1376 inet4, port_as_string, NULL);
1451 port_as_string,
1452 NULL);
1453 if (NULL == proc) 1377 if (NULL == proc)
1454 return; 1378 return;
1455 /* we know that the gnunet-helper-nat-client will terminate virtually 1379 /* we know that the gnunet-helper-nat-client will terminate virtually
1456 instantly */ 1380 * instantly */
1457 GNUNET_OS_process_wait (proc); 1381 GNUNET_OS_process_wait (proc);
1458 GNUNET_OS_process_close (proc); 1382 GNUNET_OS_process_close (proc);
1459} 1383}
@@ -1471,44 +1395,43 @@ GNUNET_NAT_run_client (struct GNUNET_NAT_Handle *h,
1471 */ 1395 */
1472int 1396int
1473GNUNET_NAT_test_address (struct GNUNET_NAT_Handle *h, 1397GNUNET_NAT_test_address (struct GNUNET_NAT_Handle *h,
1474 const void *addr, 1398 const void *addr, socklen_t addrlen)
1475 socklen_t addrlen)
1476{ 1399{
1477 struct LocalAddressList *pos; 1400 struct LocalAddressList *pos;
1478 const struct sockaddr_in *in4; 1401 const struct sockaddr_in *in4;
1479 const struct sockaddr_in6 *in6; 1402 const struct sockaddr_in6 *in6;
1480 1403
1481 if ( (addrlen != sizeof (struct in_addr)) && 1404 if ((addrlen != sizeof (struct in_addr)) &&
1482 (addrlen != sizeof (struct in6_addr)) ) 1405 (addrlen != sizeof (struct in6_addr)))
1483 { 1406 {
1484 GNUNET_break (0); 1407 GNUNET_break (0);
1485 return GNUNET_SYSERR; 1408 return GNUNET_SYSERR;
1486 } 1409 }
1487 pos = h->lal_head; 1410 pos = h->lal_head;
1488 while (NULL != pos) 1411 while (NULL != pos)
1412 {
1413 if (pos->addrlen == sizeof (struct sockaddr_in))
1489 { 1414 {
1490 if (pos->addrlen == sizeof (struct sockaddr_in)) 1415 in4 = (struct sockaddr_in *) &pos[1];
1491 { 1416 if ((addrlen == sizeof (struct in_addr)) &&
1492 in4 = (struct sockaddr_in* ) &pos[1]; 1417 (0 == memcmp (&in4->sin_addr, addr, sizeof (struct in_addr))))
1493 if ( (addrlen == sizeof (struct in_addr)) && 1418 return GNUNET_YES;
1494 (0 == memcmp (&in4->sin_addr, addr, sizeof (struct in_addr))) ) 1419 }
1495 return GNUNET_YES; 1420 else if (pos->addrlen == sizeof (struct sockaddr_in6))
1496 } 1421 {
1497 else if (pos->addrlen == sizeof (struct sockaddr_in6)) 1422 in6 = (struct sockaddr_in6 *) &pos[1];
1498 { 1423 if ((addrlen == sizeof (struct in6_addr)) &&
1499 in6 = (struct sockaddr_in6* ) &pos[1]; 1424 (0 == memcmp (&in6->sin6_addr, addr, sizeof (struct in6_addr))))
1500 if ( (addrlen == sizeof (struct in6_addr)) && 1425 return GNUNET_YES;
1501 (0 == memcmp (&in6->sin6_addr, addr, sizeof (struct in6_addr))) ) 1426 }
1502 return GNUNET_YES; 1427 else
1503 } 1428 {
1504 else 1429 GNUNET_assert (0);
1505 {
1506 GNUNET_assert (0);
1507 }
1508 pos = pos->next;
1509 } 1430 }
1431 pos = pos->next;
1432 }
1510 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1433 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1511 "Asked to validate one of my addresses and validation failed!\n"); 1434 "Asked to validate one of my addresses and validation failed!\n");
1512 return GNUNET_NO; 1435 return GNUNET_NO;
1513} 1436}
1514 1437
diff --git a/src/nat/nat.h b/src/nat/nat.h
index bff444e6d..bb13e5274 100644
--- a/src/nat/nat.h
+++ b/src/nat/nat.h
@@ -35,17 +35,17 @@ struct GNUNET_NAT_TestMessage
35{ 35{
36 /** 36 /**
37 * Header with type "GNUNET_MESSAGE_TYPE_NAT_TEST" 37 * Header with type "GNUNET_MESSAGE_TYPE_NAT_TEST"
38 */ 38 */
39 struct GNUNET_MessageHeader header; 39 struct GNUNET_MessageHeader header;
40 40
41 /** 41 /**
42 * IPv4 target IP address 42 * IPv4 target IP address
43 */ 43 */
44 uint32_t dst_ipv4; 44 uint32_t dst_ipv4;
45 45
46 /** 46 /**
47 * Port to use, 0 to send dummy ICMP response. 47 * Port to use, 0 to send dummy ICMP response.
48 */ 48 */
49 uint16_t dport; 49 uint16_t dport;
50 50
51 /** 51 /**
diff --git a/src/nat/nat_mini.c b/src/nat/nat_mini.c
index 058e8dda2..c40231067 100644
--- a/src/nat/nat_mini.c
+++ b/src/nat/nat_mini.c
@@ -109,8 +109,7 @@ struct GNUNET_NAT_ExternalHandle
109 * @param tc scheduler context 109 * @param tc scheduler context
110 */ 110 */
111static void 111static void
112read_external_ipv4 (void *cls, 112read_external_ipv4 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
113 const struct GNUNET_SCHEDULER_TaskContext *tc)
114{ 113{
115 struct GNUNET_NAT_ExternalHandle *eh = cls; 114 struct GNUNET_NAT_ExternalHandle *eh = cls;
116 ssize_t ret; 115 ssize_t ret;
@@ -118,39 +117,34 @@ read_external_ipv4 (void *cls,
118 int iret; 117 int iret;
119 118
120 eh->task = GNUNET_SCHEDULER_NO_TASK; 119 eh->task = GNUNET_SCHEDULER_NO_TASK;
121 if (GNUNET_YES == 120 if (GNUNET_YES == GNUNET_NETWORK_fdset_handle_isset (tc->read_ready, eh->r))
122 GNUNET_NETWORK_fdset_handle_isset (tc->read_ready,
123 eh->r))
124 ret = GNUNET_DISK_file_read (eh->r, 121 ret = GNUNET_DISK_file_read (eh->r,
125 &eh->buf[eh->off], 122 &eh->buf[eh->off], sizeof (eh->buf) - eh->off);
126 sizeof (eh->buf)-eh->off);
127 else 123 else
128 ret = -1; /* error reading, timeout, etc. */ 124 ret = -1; /* error reading, timeout, etc. */
129 if (ret > 0) 125 if (ret > 0)
130 { 126 {
131 /* try to read more */ 127 /* try to read more */
132 eh->off += ret; 128 eh->off += ret;
133 eh->task = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_absolute_get_remaining (eh->timeout), 129 eh->task =
134 eh->r, 130 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_absolute_get_remaining
135 &read_external_ipv4, 131 (eh->timeout), eh->r,
136 eh); 132 &read_external_ipv4, eh);
137 return; 133 return;
138 } 134 }
139 iret = GNUNET_NO; 135 iret = GNUNET_NO;
140 if ( (eh->off > 7) && 136 if ((eh->off > 7) && (eh->buf[eh->off - 1] == '\n'))
141 (eh->buf[eh->off-1] == '\n') ) 137 {
138 eh->buf[eh->off - 1] = '\0';
139 if (1 == inet_pton (AF_INET, eh->buf, &addr))
142 { 140 {
143 eh->buf[eh->off-1] = '\0'; 141 if (addr.s_addr == 0)
144 if (1 == inet_pton (AF_INET, eh->buf, &addr)) 142 iret = GNUNET_NO; /* got 0.0.0.0 */
145 { 143 else
146 if (addr.s_addr == 0) 144 iret = GNUNET_OK;
147 iret = GNUNET_NO; /* got 0.0.0.0 */
148 else
149 iret = GNUNET_OK;
150 }
151 } 145 }
152 eh->cb (eh->cb_cls, 146 }
153 (iret == GNUNET_OK) ? &addr : NULL); 147 eh->cb (eh->cb_cls, (iret == GNUNET_OK) ? &addr : NULL);
154 GNUNET_NAT_mini_get_external_ipv4_cancel (eh); 148 GNUNET_NAT_mini_get_external_ipv4_cancel (eh);
155} 149}
156 150
@@ -165,40 +159,33 @@ read_external_ipv4 (void *cls,
165 */ 159 */
166struct GNUNET_NAT_ExternalHandle * 160struct GNUNET_NAT_ExternalHandle *
167GNUNET_NAT_mini_get_external_ipv4 (struct GNUNET_TIME_Relative timeout, 161GNUNET_NAT_mini_get_external_ipv4 (struct GNUNET_TIME_Relative timeout,
168 GNUNET_NAT_IPCallback cb, 162 GNUNET_NAT_IPCallback cb, void *cb_cls)
169 void *cb_cls)
170{ 163{
171 struct GNUNET_NAT_ExternalHandle *eh; 164 struct GNUNET_NAT_ExternalHandle *eh;
172 165
173 eh = GNUNET_malloc (sizeof (struct GNUNET_NAT_ExternalHandle)); 166 eh = GNUNET_malloc (sizeof (struct GNUNET_NAT_ExternalHandle));
174 eh->cb = cb; 167 eh->cb = cb;
175 eh->cb_cls = cb_cls; 168 eh->cb_cls = cb_cls;
176 eh->opipe = GNUNET_DISK_pipe (GNUNET_YES, 169 eh->opipe = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_NO, GNUNET_YES);
177 GNUNET_NO,
178 GNUNET_YES);
179 if (NULL == eh->opipe) 170 if (NULL == eh->opipe)
180 { 171 {
181 GNUNET_free (eh); 172 GNUNET_free (eh);
182 return NULL; 173 return NULL;
183 } 174 }
184 eh->eip = GNUNET_OS_start_process (NULL, 175 eh->eip = GNUNET_OS_start_process (NULL,
185 eh->opipe, 176 eh->opipe,
186 "external-ip", 177 "external-ip", "external-ip", NULL);
187 "external-ip", NULL);
188 if (NULL == eh->eip) 178 if (NULL == eh->eip)
189 { 179 {
190 GNUNET_DISK_pipe_close (eh->opipe); 180 GNUNET_DISK_pipe_close (eh->opipe);
191 GNUNET_free (eh); 181 GNUNET_free (eh);
192 return NULL; 182 return NULL;
193 } 183 }
194 GNUNET_DISK_pipe_close_end (eh->opipe, GNUNET_DISK_PIPE_END_WRITE); 184 GNUNET_DISK_pipe_close_end (eh->opipe, GNUNET_DISK_PIPE_END_WRITE);
195 eh->timeout = GNUNET_TIME_relative_to_absolute (timeout); 185 eh->timeout = GNUNET_TIME_relative_to_absolute (timeout);
196 eh->r = GNUNET_DISK_pipe_handle (eh->opipe, 186 eh->r = GNUNET_DISK_pipe_handle (eh->opipe, GNUNET_DISK_PIPE_END_READ);
197 GNUNET_DISK_PIPE_END_READ);
198 eh->task = GNUNET_SCHEDULER_add_read_file (timeout, 187 eh->task = GNUNET_SCHEDULER_add_read_file (timeout,
199 eh->r, 188 eh->r, &read_external_ipv4, eh);
200 &read_external_ipv4,
201 eh);
202 return eh; 189 return eh;
203} 190}
204 191
@@ -222,7 +209,7 @@ GNUNET_NAT_mini_get_external_ipv4_cancel (struct GNUNET_NAT_ExternalHandle *eh)
222 209
223/** 210/**
224 * Handle to a mapping created with upnpc. 211 * Handle to a mapping created with upnpc.
225 */ 212 */
226struct GNUNET_NAT_MiniHandle 213struct GNUNET_NAT_MiniHandle
227{ 214{
228 215
@@ -274,7 +261,7 @@ struct GNUNET_NAT_MiniHandle
274 261
275 /** 262 /**
276 * Did we find our mapping during refresh scan? 263 * Did we find our mapping during refresh scan?
277 */ 264 */
278 int found; 265 int found;
279 266
280 /** 267 /**
@@ -292,8 +279,7 @@ struct GNUNET_NAT_MiniHandle
292 * @param tc scheduler context 279 * @param tc scheduler context
293 */ 280 */
294static void 281static void
295do_refresh (void *cls, 282do_refresh (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
296 const struct GNUNET_SCHEDULER_TaskContext *tc);
297 283
298 284
299/** 285/**
@@ -302,9 +288,7 @@ do_refresh (void *cls,
302 * @param cls the 'struct GNUNET_NAT_MiniHandle' 288 * @param cls the 'struct GNUNET_NAT_MiniHandle'
303 * @param line line of output, NULL at the end 289 * @param line line of output, NULL at the end
304 */ 290 */
305static void 291static void process_map_output (void *cls, const char *line);
306process_map_output (void *cls,
307 const char *line);
308 292
309 293
310/** 294/**
@@ -315,8 +299,7 @@ process_map_output (void *cls,
315 * @param line line of output, NULL at the end 299 * @param line line of output, NULL at the end
316 */ 300 */
317static void 301static void
318process_refresh_output (void *cls, 302process_refresh_output (void *cls, const char *line)
319 const char *line)
320{ 303{
321 struct GNUNET_NAT_MiniHandle *mini = cls; 304 struct GNUNET_NAT_MiniHandle *mini = cls;
322 char pstr[9]; 305 char pstr[9];
@@ -325,99 +308,92 @@ process_refresh_output (void *cls,
325 struct in_addr exip; 308 struct in_addr exip;
326 309
327 if (NULL == line) 310 if (NULL == line)
311 {
312 GNUNET_OS_command_stop (mini->refresh_cmd);
313 mini->refresh_cmd = NULL;
314 if (mini->found == GNUNET_NO)
328 { 315 {
329 GNUNET_OS_command_stop (mini->refresh_cmd); 316 /* mapping disappeared, try to re-create */
330 mini->refresh_cmd = NULL; 317 if (mini->did_map)
331 if (mini->found == GNUNET_NO) 318 {
332 { 319 mini->ac (mini->ac_cls, GNUNET_NO,
333 /* mapping disappeared, try to re-create */ 320 (const struct sockaddr *) &mini->current_addr,
334 if (mini->did_map) 321 sizeof (mini->current_addr));
335 { 322 mini->did_map = GNUNET_NO;
336 mini->ac (mini->ac_cls, GNUNET_NO, 323 }
337 (const struct sockaddr*) &mini->current_addr, 324 GNUNET_snprintf (pstr, sizeof (pstr), "%u", (unsigned int) mini->port);
338 sizeof (mini->current_addr)); 325 mini->map_cmd = GNUNET_OS_command_run (&process_map_output,
339 mini->did_map = GNUNET_NO; 326 mini,
340 } 327 MAP_TIMEOUT,
341 GNUNET_snprintf (pstr, sizeof (pstr), 328 "upnpc",
342 "%u", 329 "upnpc",
343 (unsigned int) mini->port); 330 "-r", pstr,
344 mini->map_cmd = GNUNET_OS_command_run (&process_map_output, 331 mini->is_tcp ? "tcp" : "udp",
345 mini, 332 NULL);
346 MAP_TIMEOUT, 333 if (NULL != mini->map_cmd)
347 "upnpc", 334 return;
348 "upnpc",
349 "-r", pstr,
350 mini->is_tcp ? "tcp" : "udp",
351 NULL);
352 if (NULL != mini->map_cmd)
353 return;
354 }
355 mini->refresh_task = GNUNET_SCHEDULER_add_delayed (MAP_REFRESH_FREQ,
356 &do_refresh,
357 mini);
358 return;
359 } 335 }
360 if (! mini->did_map) 336 mini->refresh_task = GNUNET_SCHEDULER_add_delayed (MAP_REFRESH_FREQ,
361 return; /* never mapped, won't find our mapping anyway */ 337 &do_refresh, mini);
338 return;
339 }
340 if (!mini->did_map)
341 return; /* never mapped, won't find our mapping anyway */
362 342
363 /* we're looking for output of the form: 343 /* we're looking for output of the form:
364 "ExternalIPAddress = 12.134.41.124" */ 344 * "ExternalIPAddress = 12.134.41.124" */
365 345
366 s = strstr (line, "ExternalIPAddress = "); 346 s = strstr (line, "ExternalIPAddress = ");
367 if (NULL != s) 347 if (NULL != s)
368 { 348 {
369 s += strlen ("ExternalIPAddress = "); 349 s += strlen ("ExternalIPAddress = ");
370 if (1 != inet_pton (AF_INET, 350 if (1 != inet_pton (AF_INET, s, &exip))
371 s, &exip)) 351 return; /* skip */
372 return; /* skip */ 352 if (exip.s_addr == mini->current_addr.sin_addr.s_addr)
373 if (exip.s_addr == mini->current_addr.sin_addr.s_addr) 353 return; /* no change */
374 return; /* no change */ 354 /* update mapping */
375 /* update mapping */ 355 mini->ac (mini->ac_cls, GNUNET_NO,
376 mini->ac (mini->ac_cls, GNUNET_NO, 356 (const struct sockaddr *) &mini->current_addr,
377 (const struct sockaddr*) &mini->current_addr, 357 sizeof (mini->current_addr));
378 sizeof (mini->current_addr)); 358 mini->current_addr.sin_addr = exip;
379 mini->current_addr.sin_addr = exip; 359 mini->ac (mini->ac_cls, GNUNET_YES,
380 mini->ac (mini->ac_cls, GNUNET_YES, 360 (const struct sockaddr *) &mini->current_addr,
381 (const struct sockaddr*) &mini->current_addr, 361 sizeof (mini->current_addr));
382 sizeof (mini->current_addr)); 362 return;
383 return; 363 }
384 }
385 /* 364 /*
386 we're looking for output of the form: 365 * we're looking for output of the form:
387 366 *
388 "0 TCP 3000->192.168.2.150:3000 'libminiupnpc' ''" 367 * "0 TCP 3000->192.168.2.150:3000 'libminiupnpc' ''"
389 "1 UDP 3001->192.168.2.150:3001 'libminiupnpc' ''" 368 * "1 UDP 3001->192.168.2.150:3001 'libminiupnpc' ''"
390 369 *
391 the pattern we look for is: 370 * the pattern we look for is:
392 371 *
393 "%s TCP PORT->STRING:OURPORT *" or 372 * "%s TCP PORT->STRING:OURPORT *" or
394 "%s UDP PORT->STRING:OURPORT *" 373 * "%s UDP PORT->STRING:OURPORT *"
395 */ 374 */
396 GNUNET_snprintf (pstr, sizeof (pstr), 375 GNUNET_snprintf (pstr, sizeof (pstr), ":%u ", mini->port);
397 ":%u ",
398 mini->port);
399 if (NULL == (s = strstr (line, "->"))) 376 if (NULL == (s = strstr (line, "->")))
400 return; /* skip */ 377 return; /* skip */
401 if (NULL == strstr (s, pstr)) 378 if (NULL == strstr (s, pstr))
402 return; /* skip */ 379 return; /* skip */
403 if (1 != sscanf (line, 380 if (1 != sscanf (line,
404 (mini->is_tcp) 381 (mini->is_tcp)
405 ? "%*u TCP %u->%*s:%*u %*s" 382 ? "%*u TCP %u->%*s:%*u %*s"
406 : "%*u UDP %u->%*s:%*u %*s", 383 : "%*u UDP %u->%*s:%*u %*s", &nport))
407 &nport)) 384 return; /* skip */
408 return; /* skip */
409 mini->found = GNUNET_YES; 385 mini->found = GNUNET_YES;
410 if (nport == ntohs (mini->current_addr.sin_port)) 386 if (nport == ntohs (mini->current_addr.sin_port))
411 return; /* no change */ 387 return; /* no change */
412 388
413 /* external port changed, update mapping */ 389 /* external port changed, update mapping */
414 mini->ac (mini->ac_cls, GNUNET_NO, 390 mini->ac (mini->ac_cls, GNUNET_NO,
415 (const struct sockaddr*) &mini->current_addr, 391 (const struct sockaddr *) &mini->current_addr,
416 sizeof (mini->current_addr)); 392 sizeof (mini->current_addr));
417 mini->current_addr.sin_port = htons ((uint16_t) nport); 393 mini->current_addr.sin_port = htons ((uint16_t) nport);
418 mini->ac (mini->ac_cls, GNUNET_YES, 394 mini->ac (mini->ac_cls, GNUNET_YES,
419 (const struct sockaddr*) &mini->current_addr, 395 (const struct sockaddr *) &mini->current_addr,
420 sizeof (mini->current_addr)); 396 sizeof (mini->current_addr));
421} 397}
422 398
423 399
@@ -428,20 +404,16 @@ process_refresh_output (void *cls,
428 * @param tc scheduler context 404 * @param tc scheduler context
429 */ 405 */
430static void 406static void
431do_refresh (void *cls, 407do_refresh (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
432 const struct GNUNET_SCHEDULER_TaskContext *tc)
433{ 408{
434 struct GNUNET_NAT_MiniHandle *mini = cls; 409 struct GNUNET_NAT_MiniHandle *mini = cls;
435 410
436 mini->refresh_task = GNUNET_SCHEDULER_NO_TASK; 411 mini->refresh_task = GNUNET_SCHEDULER_NO_TASK;
437 mini->found = GNUNET_NO; 412 mini->found = GNUNET_NO;
438 mini->refresh_cmd = GNUNET_OS_command_run (&process_refresh_output, 413 mini->refresh_cmd = GNUNET_OS_command_run (&process_refresh_output,
439 mini, 414 mini,
440 MAP_TIMEOUT, 415 MAP_TIMEOUT,
441 "upnpc", 416 "upnpc", "upnpc", "-l", NULL);
442 "upnpc",
443 "-l",
444 NULL);
445} 417}
446 418
447 419
@@ -452,8 +424,7 @@ do_refresh (void *cls,
452 * @param line line of output, NULL at the end 424 * @param line line of output, NULL at the end
453 */ 425 */
454static void 426static void
455process_map_output (void *cls, 427process_map_output (void *cls, const char *line)
456 const char *line)
457{ 428{
458 struct GNUNET_NAT_MiniHandle *mini = cls; 429 struct GNUNET_NAT_MiniHandle *mini = cls;
459 const char *ipaddr; 430 const char *ipaddr;
@@ -462,35 +433,32 @@ process_map_output (void *cls,
462 unsigned int port; 433 unsigned int port;
463 434
464 if (NULL == line) 435 if (NULL == line)
465 { 436 {
466 GNUNET_OS_command_stop (mini->map_cmd); 437 GNUNET_OS_command_stop (mini->map_cmd);
467 mini->map_cmd = NULL; 438 mini->map_cmd = NULL;
468 mini->refresh_task = GNUNET_SCHEDULER_add_delayed (MAP_REFRESH_FREQ, 439 mini->refresh_task = GNUNET_SCHEDULER_add_delayed (MAP_REFRESH_FREQ,
469 &do_refresh, 440 &do_refresh, mini);
470 mini); 441 return;
471 return; 442 }
472 }
473 /* 443 /*
474 The upnpc output we're after looks like this: 444 * The upnpc output we're after looks like this:
475 445 *
476 "external 87.123.42.204:3000 TCP is redirected to internal 192.168.2.150:3000" 446 * "external 87.123.42.204:3000 TCP is redirected to internal 192.168.2.150:3000"
477 */ 447 */
478 if ( (NULL == (ipaddr = strstr (line, " "))) || 448 if ((NULL == (ipaddr = strstr (line, " "))) ||
479 (NULL == (pstr = strstr (ipaddr, ":"))) || 449 (NULL == (pstr = strstr (ipaddr, ":"))) ||
480 (1 != sscanf (pstr + 1, "%u", &port)) ) 450 (1 != sscanf (pstr + 1, "%u", &port)))
481 { 451 {
482 return; /* skip line */ 452 return; /* skip line */
483 } 453 }
484 ipa = GNUNET_strdup (ipaddr + 1); 454 ipa = GNUNET_strdup (ipaddr + 1);
485 strstr (ipa, ":")[0] = '\0'; 455 strstr (ipa, ":")[0] = '\0';
486 if (1 != inet_pton (AF_INET, 456 if (1 != inet_pton (AF_INET, ipa, &mini->current_addr.sin_addr))
487 ipa, 457 {
488 &mini->current_addr.sin_addr)) 458 GNUNET_free (ipa);
489 { 459 return; /* skip line */
490 GNUNET_free (ipa); 460 }
491 return; /* skip line */ 461 GNUNET_free (ipa);
492 }
493 GNUNET_free (ipa);
494 462
495 mini->current_addr.sin_port = htons (port); 463 mini->current_addr.sin_port = htons (port);
496 mini->current_addr.sin_family = AF_INET; 464 mini->current_addr.sin_family = AF_INET;
@@ -499,8 +467,8 @@ process_map_output (void *cls,
499#endif 467#endif
500 mini->did_map = GNUNET_YES; 468 mini->did_map = GNUNET_YES;
501 mini->ac (mini->ac_cls, GNUNET_YES, 469 mini->ac (mini->ac_cls, GNUNET_YES,
502 (const struct sockaddr*) &mini->current_addr, 470 (const struct sockaddr *) &mini->current_addr,
503 sizeof (mini->current_addr)); 471 sizeof (mini->current_addr));
504} 472}
505 473
506 474
@@ -519,37 +487,31 @@ process_map_output (void *cls,
519 */ 487 */
520struct GNUNET_NAT_MiniHandle * 488struct GNUNET_NAT_MiniHandle *
521GNUNET_NAT_mini_map_start (uint16_t port, 489GNUNET_NAT_mini_map_start (uint16_t port,
522 int is_tcp, 490 int is_tcp,
523 GNUNET_NAT_AddressCallback ac, 491 GNUNET_NAT_AddressCallback ac, void *ac_cls)
524 void *ac_cls)
525{ 492{
526 struct GNUNET_NAT_MiniHandle *ret; 493 struct GNUNET_NAT_MiniHandle *ret;
527 char pstr[6]; 494 char pstr[6];
528 495
529 if (GNUNET_SYSERR == 496 if (GNUNET_SYSERR == GNUNET_OS_check_helper_binary ("upnpc"))
530 GNUNET_OS_check_helper_binary ("upnpc"))
531 return NULL; 497 return NULL;
532 ret = GNUNET_malloc (sizeof (struct GNUNET_NAT_MiniHandle)); 498 ret = GNUNET_malloc (sizeof (struct GNUNET_NAT_MiniHandle));
533 ret->ac = ac; 499 ret->ac = ac;
534 ret->ac_cls = ac_cls; 500 ret->ac_cls = ac_cls;
535 ret->is_tcp = is_tcp; 501 ret->is_tcp = is_tcp;
536 ret->port = port; 502 ret->port = port;
537 GNUNET_snprintf (pstr, sizeof (pstr), 503 GNUNET_snprintf (pstr, sizeof (pstr), "%u", (unsigned int) port);
538 "%u",
539 (unsigned int) port);
540 ret->map_cmd = GNUNET_OS_command_run (&process_map_output, 504 ret->map_cmd = GNUNET_OS_command_run (&process_map_output,
541 ret, 505 ret,
542 MAP_TIMEOUT, 506 MAP_TIMEOUT,
543 "upnpc", 507 "upnpc",
544 "upnpc", 508 "upnpc",
545 "-r", pstr, 509 "-r", pstr,
546 is_tcp ? "tcp" : "udp", 510 is_tcp ? "tcp" : "udp", NULL);
547 NULL);
548 if (NULL != ret->map_cmd) 511 if (NULL != ret->map_cmd)
549 return ret; 512 return ret;
550 ret->refresh_task = GNUNET_SCHEDULER_add_delayed (MAP_REFRESH_FREQ, 513 ret->refresh_task = GNUNET_SCHEDULER_add_delayed (MAP_REFRESH_FREQ,
551 &do_refresh, 514 &do_refresh, ret);
552 ret);
553 515
554 return ret; 516 return ret;
555} 517}
@@ -562,23 +524,20 @@ GNUNET_NAT_mini_map_start (uint16_t port,
562 * @param line line of output, NULL at the end 524 * @param line line of output, NULL at the end
563 */ 525 */
564static void 526static void
565process_unmap_output (void *cls, 527process_unmap_output (void *cls, const char *line)
566 const char *line)
567{ 528{
568 struct GNUNET_NAT_MiniHandle *mini = cls; 529 struct GNUNET_NAT_MiniHandle *mini = cls;
569 530
570 if (NULL == line) 531 if (NULL == line)
571 { 532 {
572#if DEBUG_NAT 533#if DEBUG_NAT
573 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 534 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "nat", "UPnP unmap done\n");
574 "nat",
575 "UPnP unmap done\n");
576#endif 535#endif
577 GNUNET_OS_command_stop (mini->unmap_cmd); 536 GNUNET_OS_command_stop (mini->unmap_cmd);
578 mini->unmap_cmd = NULL; 537 mini->unmap_cmd = NULL;
579 GNUNET_free (mini); 538 GNUNET_free (mini);
580 return; 539 return;
581 } 540 }
582 /* we don't really care about the output... */ 541 /* we don't really care about the output... */
583} 542}
584 543
@@ -597,48 +556,46 @@ GNUNET_NAT_mini_map_stop (struct GNUNET_NAT_MiniHandle *mini)
597 char pstr[6]; 556 char pstr[6];
598 557
599 if (GNUNET_SCHEDULER_NO_TASK != mini->refresh_task) 558 if (GNUNET_SCHEDULER_NO_TASK != mini->refresh_task)
600 { 559 {
601 GNUNET_SCHEDULER_cancel (mini->refresh_task); 560 GNUNET_SCHEDULER_cancel (mini->refresh_task);
602 mini->refresh_task = GNUNET_SCHEDULER_NO_TASK; 561 mini->refresh_task = GNUNET_SCHEDULER_NO_TASK;
603 } 562 }
604 if (mini->refresh_cmd != NULL) 563 if (mini->refresh_cmd != NULL)
564 {
565 GNUNET_OS_command_stop (mini->refresh_cmd);
566 mini->refresh_cmd = NULL;
567 }
568 if (!mini->did_map)
569 {
570 if (mini->map_cmd != NULL)
605 { 571 {
606 GNUNET_OS_command_stop (mini->refresh_cmd); 572 GNUNET_OS_command_stop (mini->map_cmd);
607 mini->refresh_cmd = NULL; 573 mini->map_cmd = NULL;
608 }
609 if (! mini->did_map)
610 {
611 if (mini->map_cmd != NULL)
612 {
613 GNUNET_OS_command_stop (mini->map_cmd);
614 mini->map_cmd = NULL;
615 }
616 GNUNET_free (mini);
617 return;
618 } 574 }
575 GNUNET_free (mini);
576 return;
577 }
619 mini->ac (mini->ac_cls, GNUNET_NO, 578 mini->ac (mini->ac_cls, GNUNET_NO,
620 (const struct sockaddr*) &mini->current_addr, 579 (const struct sockaddr *) &mini->current_addr,
621 sizeof (mini->current_addr)); 580 sizeof (mini->current_addr));
622 /* Note: oddly enough, deletion uses the external port whereas 581 /* Note: oddly enough, deletion uses the external port whereas
623 addition uses the internal port; this rarely matters since they 582 * addition uses the internal port; this rarely matters since they
624 often are the same, but it might... */ 583 * often are the same, but it might... */
625 GNUNET_snprintf (pstr, sizeof (pstr), 584 GNUNET_snprintf (pstr, sizeof (pstr),
626 "%u", 585 "%u", (unsigned int) ntohs (mini->current_addr.sin_port));
627 (unsigned int) ntohs (mini->current_addr.sin_port));
628#if DEBUG_NAT 586#if DEBUG_NAT
629 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 587 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
630 "nat", 588 "nat",
631 "Unmapping port %u with UPnP\n", 589 "Unmapping port %u with UPnP\n",
632 ntohs (mini->current_addr.sin_port)); 590 ntohs (mini->current_addr.sin_port));
633#endif 591#endif
634 mini->unmap_cmd = GNUNET_OS_command_run (&process_unmap_output, 592 mini->unmap_cmd = GNUNET_OS_command_run (&process_unmap_output,
635 mini, 593 mini,
636 UNMAP_TIMEOUT, 594 UNMAP_TIMEOUT,
637 "upnpc", 595 "upnpc",
638 "upnpc", 596 "upnpc",
639 "-d", pstr, 597 "-d", pstr,
640 mini->is_tcp ? "tcp" : "udp", 598 mini->is_tcp ? "tcp" : "udp", NULL);
641 NULL);
642} 599}
643 600
644 601
diff --git a/src/nat/nat_test.c b/src/nat/nat_test.c
index 8c9933cdb..30db00803 100644
--- a/src/nat/nat_test.c
+++ b/src/nat/nat_test.c
@@ -99,7 +99,7 @@ struct GNUNET_NAT_Test
99 * Function to call with success report 99 * Function to call with success report
100 */ 100 */
101 GNUNET_NAT_TestCallback report; 101 GNUNET_NAT_TestCallback report;
102 102
103 /** 103 /**
104 * Closure for 'report'. 104 * Closure for 'report'.
105 */ 105 */
@@ -167,9 +167,7 @@ struct GNUNET_NAT_Test
167 * @param addrlen actual lenght of the address 167 * @param addrlen actual lenght of the address
168 */ 168 */
169static void 169static void
170reversal_cb (void *cls, 170reversal_cb (void *cls, const struct sockaddr *addr, socklen_t addrlen)
171 const struct sockaddr *addr,
172 socklen_t addrlen)
173{ 171{
174 struct GNUNET_NAT_Test *h = cls; 172 struct GNUNET_NAT_Test *h = cls;
175 const struct sockaddr_in *sa; 173 const struct sockaddr_in *sa;
@@ -178,14 +176,14 @@ reversal_cb (void *cls,
178 return; 176 return;
179 sa = (const struct sockaddr_in *) addr; 177 sa = (const struct sockaddr_in *) addr;
180 if (h->data != sa->sin_port) 178 if (h->data != sa->sin_port)
181 { 179 {
182#if DEBUG_NAT 180#if DEBUG_NAT
183 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 181 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
184 "nat", 182 "nat",
185 "Received connection reversal request for wrong port\n"); 183 "Received connection reversal request for wrong port\n");
186#endif 184#endif
187 return; /* wrong port */ 185 return; /* wrong port */
188 } 186 }
189 /* report success */ 187 /* report success */
190 h->report (h->report_cls, GNUNET_OK); 188 h->report (h->report_cls, GNUNET_OK);
191} 189}
@@ -199,38 +197,31 @@ reversal_cb (void *cls,
199 * @param tc scheduler context 197 * @param tc scheduler context
200 */ 198 */
201static void 199static void
202do_udp_read (void *cls, 200do_udp_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
203 const struct GNUNET_SCHEDULER_TaskContext *tc)
204{ 201{
205 struct GNUNET_NAT_Test *tst = cls; 202 struct GNUNET_NAT_Test *tst = cls;
206 uint16_t data; 203 uint16_t data;
207 204
208 tst->ltask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 205 tst->ltask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
209 tst->lsock, 206 tst->lsock, &do_udp_read, tst);
210 &do_udp_read, 207 if ((NULL != tc->write_ready) &&
211 tst); 208 (GNUNET_NETWORK_fdset_isset (tc->read_ready,
212 if ( (NULL != tc->write_ready) && 209 tst->lsock)) &&
213 (GNUNET_NETWORK_fdset_isset (tc->read_ready, 210 (sizeof (data) ==
214 tst->lsock)) && 211 GNUNET_NETWORK_socket_recv (tst->lsock, &data, sizeof (data))))
215 (sizeof (data) == 212 {
216 GNUNET_NETWORK_socket_recv (tst->lsock, 213 if (data == tst->data)
217 &data, 214 tst->report (tst->report_cls, GNUNET_OK);
218 sizeof (data))) )
219 {
220 if (data == tst->data)
221 tst->report (tst->report_cls, GNUNET_OK);
222#if DEBUG_NAT 215#if DEBUG_NAT
223 else 216 else
224 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 217 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
225 "nat", 218 "nat", "Received data mismatches expected value\n");
226 "Received data mismatches expected value\n");
227#endif 219#endif
228 } 220 }
229#if DEBUG_NAT 221#if DEBUG_NAT
230 else 222 else
231 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 223 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
232 "nat", 224 "nat", "Failed to receive data from inbound connection\n");
233 "Failed to receive data from inbound connection\n");
234#endif 225#endif
235} 226}
236 227
@@ -243,8 +234,7 @@ do_udp_read (void *cls,
243 * @param tc scheduler context 234 * @param tc scheduler context
244 */ 235 */
245static void 236static void
246do_read (void *cls, 237do_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
247 const struct GNUNET_SCHEDULER_TaskContext *tc)
248{ 238{
249 struct NatActivity *na = cls; 239 struct NatActivity *na = cls;
250 struct GNUNET_NAT_Test *tst; 240 struct GNUNET_NAT_Test *tst;
@@ -252,31 +242,25 @@ do_read (void *cls,
252 242
253 na->rtask = GNUNET_SCHEDULER_NO_TASK; 243 na->rtask = GNUNET_SCHEDULER_NO_TASK;
254 tst = na->h; 244 tst = na->h;
255 GNUNET_CONTAINER_DLL_remove (tst->na_head, 245 GNUNET_CONTAINER_DLL_remove (tst->na_head, tst->na_tail, na);
256 tst->na_tail, 246 if ((NULL != tc->write_ready) &&
257 na); 247 (GNUNET_NETWORK_fdset_isset (tc->read_ready,
258 if ( (NULL != tc->write_ready) && 248 na->sock)) &&
259 (GNUNET_NETWORK_fdset_isset (tc->read_ready, 249 (sizeof (data) ==
260 na->sock)) && 250 GNUNET_NETWORK_socket_recv (na->sock, &data, sizeof (data))))
261 (sizeof (data) == 251 {
262 GNUNET_NETWORK_socket_recv (na->sock, 252 if (data == tst->data)
263 &data, 253 tst->report (tst->report_cls, GNUNET_OK);
264 sizeof (data))) )
265 {
266 if (data == tst->data)
267 tst->report (tst->report_cls, GNUNET_OK);
268#if DEBUG_NAT 254#if DEBUG_NAT
269 else 255 else
270 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 256 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
271 "nat" 257 "nat" "Received data mismatches expected value\n");
272 "Received data mismatches expected value\n");
273#endif 258#endif
274 } 259 }
275#if DEBUG_NAT 260#if DEBUG_NAT
276 else 261 else
277 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 262 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
278 "nat", 263 "nat", "Failed to receive data from inbound connection\n");
279 "Failed to receive data from inbound connection\n");
280#endif 264#endif
281 GNUNET_NETWORK_socket_close (na->sock); 265 GNUNET_NETWORK_socket_close (na->sock);
282 GNUNET_free (na); 266 GNUNET_free (na);
@@ -291,8 +275,7 @@ do_read (void *cls,
291 * @param tc scheduler context 275 * @param tc scheduler context
292 */ 276 */
293static void 277static void
294do_accept (void *cls, 278do_accept (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
295 const struct GNUNET_SCHEDULER_TaskContext *tc)
296{ 279{
297 struct GNUNET_NAT_Test *tst = cls; 280 struct GNUNET_NAT_Test *tst = cls;
298 struct GNUNET_NETWORK_Handle *s; 281 struct GNUNET_NETWORK_Handle *s;
@@ -300,32 +283,25 @@ do_accept (void *cls,
300 283
301 tst->ltask = GNUNET_SCHEDULER_NO_TASK; 284 tst->ltask = GNUNET_SCHEDULER_NO_TASK;
302 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) 285 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
303 return; 286 return;
304 tst->ltask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 287 tst->ltask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
305 tst->lsock, 288 tst->lsock, &do_accept, tst);
306 &do_accept,
307 tst);
308 s = GNUNET_NETWORK_socket_accept (tst->lsock, NULL, NULL); 289 s = GNUNET_NETWORK_socket_accept (tst->lsock, NULL, NULL);
309 if (NULL == s) 290 if (NULL == s)
310 { 291 {
311 GNUNET_log_strerror (GNUNET_ERROR_TYPE_INFO, "accept"); 292 GNUNET_log_strerror (GNUNET_ERROR_TYPE_INFO, "accept");
312 return; /* odd error */ 293 return; /* odd error */
313 } 294 }
314#if DEBUG_NAT 295#if DEBUG_NAT
315 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 296 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
316 "nat", 297 "nat", "Got an inbound connection, waiting for data\n");
317 "Got an inbound connection, waiting for data\n");
318#endif 298#endif
319 wl = GNUNET_malloc (sizeof (struct NatActivity)); 299 wl = GNUNET_malloc (sizeof (struct NatActivity));
320 wl->sock = s; 300 wl->sock = s;
321 wl->h = tst; 301 wl->h = tst;
322 wl->rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 302 wl->rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
323 wl->sock, 303 wl->sock, &do_read, wl);
324 &do_read, 304 GNUNET_CONTAINER_DLL_insert (tst->na_head, tst->na_tail, wl);
325 wl);
326 GNUNET_CONTAINER_DLL_insert (tst->na_head,
327 tst->na_tail,
328 wl);
329} 305}
330 306
331 307
@@ -338,11 +314,9 @@ do_accept (void *cls,
338 * @param addr either the previous or the new public IP address 314 * @param addr either the previous or the new public IP address
339 * @param addrlen actual lenght of the address 315 * @param addrlen actual lenght of the address
340 */ 316 */
341static void 317static void
342addr_cb (void *cls, 318addr_cb (void *cls,
343 int add_remove, 319 int add_remove, const struct sockaddr *addr, socklen_t addrlen)
344 const struct sockaddr *addr,
345 socklen_t addrlen)
346{ 320{
347 struct GNUNET_NAT_Test *h = cls; 321 struct GNUNET_NAT_Test *h = cls;
348 struct ClientActivity *ca; 322 struct ClientActivity *ca;
@@ -353,40 +327,37 @@ addr_cb (void *cls,
353 if (GNUNET_YES != add_remove) 327 if (GNUNET_YES != add_remove)
354 return; 328 return;
355 if (addrlen != sizeof (struct sockaddr_in)) 329 if (addrlen != sizeof (struct sockaddr_in))
356 return; /* ignore IPv6 here */ 330 return; /* ignore IPv6 here */
357#if DEBUG_NAT 331#if DEBUG_NAT
358 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 332 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
359 "nat", 333 "nat",
360 "Asking gnunet-nat-server to connect to `%s'\n", 334 "Asking gnunet-nat-server to connect to `%s'\n",
361 GNUNET_a2s (addr, addrlen)); 335 GNUNET_a2s (addr, addrlen));
362#endif 336#endif
363 sa = (const struct sockaddr_in*) addr; 337 sa = (const struct sockaddr_in *) addr;
364 msg.header.size = htons (sizeof(struct GNUNET_NAT_TestMessage)); 338 msg.header.size = htons (sizeof (struct GNUNET_NAT_TestMessage));
365 msg.header.type = htons (GNUNET_MESSAGE_TYPE_NAT_TEST); 339 msg.header.type = htons (GNUNET_MESSAGE_TYPE_NAT_TEST);
366 msg.dst_ipv4 = sa->sin_addr.s_addr; 340 msg.dst_ipv4 = sa->sin_addr.s_addr;
367 msg.dport = sa->sin_port; 341 msg.dport = sa->sin_port;
368 msg.data = h->data; 342 msg.data = h->data;
369 msg.is_tcp = htonl ((uint32_t) h->is_tcp); 343 msg.is_tcp = htonl ((uint32_t) h->is_tcp);
370 344
371 client = GNUNET_CLIENT_connect ("gnunet-nat-server", 345 client = GNUNET_CLIENT_connect ("gnunet-nat-server", h->cfg);
372 h->cfg);
373 if (NULL == client) 346 if (NULL == client)
374 { 347 {
375 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 348 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
376 _("Failed to connect to `gnunet-nat-server'\n")); 349 _("Failed to connect to `gnunet-nat-server'\n"));
377 return; 350 return;
378 } 351 }
379 ca = GNUNET_malloc (sizeof (struct ClientActivity)); 352 ca = GNUNET_malloc (sizeof (struct ClientActivity));
380 ca->client = client; 353 ca->client = client;
381 GNUNET_CONTAINER_DLL_insert (h->ca_head, 354 GNUNET_CONTAINER_DLL_insert (h->ca_head, h->ca_tail, ca);
382 h->ca_tail,
383 ca);
384 GNUNET_break (GNUNET_OK == 355 GNUNET_break (GNUNET_OK ==
385 GNUNET_CLIENT_transmit_and_get_response (client, 356 GNUNET_CLIENT_transmit_and_get_response (client,
386 &msg.header, 357 &msg.header,
387 GNUNET_TIME_UNIT_SECONDS, 358 GNUNET_TIME_UNIT_SECONDS,
388 GNUNET_YES, 359 GNUNET_YES,
389 NULL, NULL)); 360 NULL, NULL));
390} 361}
391 362
392 363
@@ -404,15 +375,14 @@ addr_cb (void *cls,
404 */ 375 */
405struct GNUNET_NAT_Test * 376struct GNUNET_NAT_Test *
406GNUNET_NAT_test_start (const struct GNUNET_CONFIGURATION_Handle *cfg, 377GNUNET_NAT_test_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
407 int is_tcp, 378 int is_tcp,
408 uint16_t bnd_port, 379 uint16_t bnd_port,
409 uint16_t adv_port, 380 uint16_t adv_port,
410 GNUNET_NAT_TestCallback report, 381 GNUNET_NAT_TestCallback report, void *report_cls)
411 void *report_cls)
412{ 382{
413 struct GNUNET_NAT_Test *ret; 383 struct GNUNET_NAT_Test *ret;
414 struct sockaddr_in sa; 384 struct sockaddr_in sa;
415 const struct sockaddr *addrs[] = { (const struct sockaddr*) &sa }; 385 const struct sockaddr *addrs[] = { (const struct sockaddr *) &sa };
416 const socklen_t addrlens[] = { sizeof (sa) }; 386 const socklen_t addrlens[] = { sizeof (sa) };
417 387
418 memset (&sa, 0, sizeof (sa)); 388 memset (&sa, 0, sizeof (sa));
@@ -421,7 +391,7 @@ GNUNET_NAT_test_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
421#if HAVE_SOCKADDR_IN_SIN_LEN 391#if HAVE_SOCKADDR_IN_SIN_LEN
422 sa.sin_len = sizeof (sa); 392 sa.sin_len = sizeof (sa);
423#endif 393#endif
424 394
425 ret = GNUNET_malloc (sizeof (struct GNUNET_NAT_Test)); 395 ret = GNUNET_malloc (sizeof (struct GNUNET_NAT_Test));
426 ret->cfg = cfg; 396 ret->cfg = cfg;
427 ret->is_tcp = is_tcp; 397 ret->is_tcp = is_tcp;
@@ -430,54 +400,47 @@ GNUNET_NAT_test_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
430 ret->report = report; 400 ret->report = report;
431 ret->report_cls = report_cls; 401 ret->report_cls = report_cls;
432 if (bnd_port == 0) 402 if (bnd_port == 0)
433 { 403 {
434 ret->nat = GNUNET_NAT_register (cfg, is_tcp, 404 ret->nat = GNUNET_NAT_register (cfg, is_tcp,
435 0, 405 0,
436 0, NULL, NULL, 406 0, NULL, NULL, &addr_cb, &reversal_cb, ret);
437 &addr_cb, &reversal_cb, ret); 407 }
438 }
439 else 408 else
409 {
410 ret->lsock = GNUNET_NETWORK_socket_create (AF_INET,
411 (is_tcp == GNUNET_YES)
412 ? SOCK_STREAM : SOCK_DGRAM, 0);
413 if ((ret->lsock == NULL) ||
414 (GNUNET_OK != GNUNET_NETWORK_socket_bind (ret->lsock,
415 (const struct sockaddr *) &sa,
416 sizeof (sa))))
417 {
418 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
419 _
420 ("Failed to create listen socket bound to `%s' for NAT test: %s\n"),
421 GNUNET_a2s ((const struct sockaddr *) &sa, sizeof (sa)),
422 STRERROR (errno));
423 if (NULL != ret->lsock)
424 GNUNET_NETWORK_socket_close (ret->lsock);
425 GNUNET_free (ret);
426 return NULL;
427 }
428 if (GNUNET_YES == is_tcp)
429 {
430 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_listen (ret->lsock, 5));
431 ret->ltask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
432 ret->lsock, &do_accept, ret);
433 }
434 else
440 { 435 {
441 ret->lsock = GNUNET_NETWORK_socket_create (AF_INET, 436 ret->ltask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
442 (is_tcp==GNUNET_YES) 437 ret->lsock,
443 ? SOCK_STREAM 438 &do_udp_read, ret);
444 : SOCK_DGRAM, 0);
445 if ( (ret->lsock == NULL) ||
446 (GNUNET_OK != GNUNET_NETWORK_socket_bind (ret->lsock,
447 (const struct sockaddr*) &sa,
448 sizeof (sa))) )
449 {
450 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
451 _("Failed to create listen socket bound to `%s' for NAT test: %s\n"),
452 GNUNET_a2s ((const struct sockaddr*)&sa,
453 sizeof(sa)),
454 STRERROR (errno));
455 if (NULL != ret->lsock)
456 GNUNET_NETWORK_socket_close (ret->lsock);
457 GNUNET_free (ret);
458 return NULL;
459 }
460 if (GNUNET_YES == is_tcp)
461 {
462 GNUNET_break (GNUNET_OK ==
463 GNUNET_NETWORK_socket_listen (ret->lsock, 5));
464 ret->ltask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
465 ret->lsock,
466 &do_accept,
467 ret);
468 }
469 else
470 {
471 ret->ltask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
472 ret->lsock,
473 &do_udp_read,
474 ret);
475 }
476 ret->nat = GNUNET_NAT_register (cfg, is_tcp,
477 adv_port,
478 1, addrs, addrlens,
479 &addr_cb, NULL, ret);
480 } 439 }
440 ret->nat = GNUNET_NAT_register (cfg, is_tcp,
441 adv_port,
442 1, addrs, addrlens, &addr_cb, NULL, ret);
443 }
481 return ret; 444 return ret;
482} 445}
483 446
@@ -494,22 +457,18 @@ GNUNET_NAT_test_stop (struct GNUNET_NAT_Test *tst)
494 struct ClientActivity *cpos; 457 struct ClientActivity *cpos;
495 458
496 while (NULL != (cpos = tst->ca_head)) 459 while (NULL != (cpos = tst->ca_head))
497 { 460 {
498 GNUNET_CONTAINER_DLL_remove (tst->ca_head, 461 GNUNET_CONTAINER_DLL_remove (tst->ca_head, tst->ca_tail, cpos);
499 tst->ca_tail, 462 GNUNET_CLIENT_disconnect (cpos->client, GNUNET_NO);
500 cpos); 463 GNUNET_free (cpos);
501 GNUNET_CLIENT_disconnect (cpos->client, GNUNET_NO); 464 }
502 GNUNET_free (cpos);
503 }
504 while (NULL != (pos = tst->na_head)) 465 while (NULL != (pos = tst->na_head))
505 { 466 {
506 GNUNET_CONTAINER_DLL_remove (tst->na_head, 467 GNUNET_CONTAINER_DLL_remove (tst->na_head, tst->na_tail, pos);
507 tst->na_tail, 468 GNUNET_SCHEDULER_cancel (pos->rtask);
508 pos); 469 GNUNET_NETWORK_socket_close (pos->sock);
509 GNUNET_SCHEDULER_cancel (pos->rtask); 470 GNUNET_free (pos);
510 GNUNET_NETWORK_socket_close (pos->sock); 471 }
511 GNUNET_free (pos);
512 }
513 if (GNUNET_SCHEDULER_NO_TASK != tst->ltask) 472 if (GNUNET_SCHEDULER_NO_TASK != tst->ltask)
514 GNUNET_SCHEDULER_cancel (tst->ltask); 473 GNUNET_SCHEDULER_cancel (tst->ltask);
515 if (NULL != tst->lsock) 474 if (NULL != tst->lsock)
diff --git a/src/nat/test_nat.c b/src/nat/test_nat.c
index c58d83224..12ff30cac 100644
--- a/src/nat/test_nat.c
+++ b/src/nat/test_nat.c
@@ -58,11 +58,10 @@ static void
58addr_callback (void *cls, int add_remove, 58addr_callback (void *cls, int add_remove,
59 const struct sockaddr *addr, socklen_t addrlen) 59 const struct sockaddr *addr, socklen_t addrlen)
60{ 60{
61 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 61 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
62 "Address changed: %s `%s' (%u bytes)\n", 62 "Address changed: %s `%s' (%u bytes)\n",
63 add_remove == GNUNET_YES ? "added" : "removed", 63 add_remove == GNUNET_YES ? "added" : "removed",
64 GNUNET_a2s (addr, addrlen), 64 GNUNET_a2s (addr, addrlen), (unsigned int) addrlen);
65 (unsigned int) addrlen);
66} 65}
67 66
68 67
@@ -74,8 +73,7 @@ stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
74{ 73{
75 struct GNUNET_NAT_Handle *nat = cls; 74 struct GNUNET_NAT_Handle *nat = cls;
76 75
77 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 76 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stopping NAT and quitting...\n");
78 "Stopping NAT and quitting...\n");
79 GNUNET_NAT_unregister (nat); 77 GNUNET_NAT_unregister (nat);
80} 78}
81 79
@@ -132,11 +130,11 @@ run (void *cls,
132 data.addr = NULL; 130 data.addr = NULL;
133 GNUNET_OS_network_interfaces_list (process_if, &data); 131 GNUNET_OS_network_interfaces_list (process_if, &data);
134 if (NULL == data.addr) 132 if (NULL == data.addr)
135 { 133 {
136 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 134 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
137 "Could not find a valid interface address!\n"); 135 "Could not find a valid interface address!\n");
138 exit (GNUNET_SYSERR); 136 exit (GNUNET_SYSERR);
139 } 137 }
140 addr = data.addr; 138 addr = data.addr;
141 GNUNET_assert (addr->sa_family == AF_INET || addr->sa_family == AF_INET6); 139 GNUNET_assert (addr->sa_family == AF_INET || addr->sa_family == AF_INET6);
142 if (addr->sa_family == AF_INET) 140 if (addr->sa_family == AF_INET)
@@ -148,13 +146,11 @@ run (void *cls,
148 "Requesting NAT redirection from address %s...\n", 146 "Requesting NAT redirection from address %s...\n",
149 GNUNET_a2s (addr, data.addrlen)); 147 GNUNET_a2s (addr, data.addrlen));
150 148
151 nat = GNUNET_NAT_register (cfg, 149 nat = GNUNET_NAT_register (cfg, GNUNET_YES /* tcp */ ,
152 GNUNET_YES /* tcp */, 150 2086,
153 2086, 151 1,
154 1, 152 (const struct sockaddr **) &addr,
155 (const struct sockaddr**) &addr, 153 &data.addrlen, &addr_callback, NULL, NULL);
156 &data.addrlen,
157 &addr_callback, NULL, NULL);
158 GNUNET_free (addr); 154 GNUNET_free (addr);
159 GNUNET_SCHEDULER_add_delayed (TIMEOUT, &stop, nat); 155 GNUNET_SCHEDULER_add_delayed (TIMEOUT, &stop, nat);
160} 156}
diff --git a/src/nat/test_nat_mini.c b/src/nat/test_nat_mini.c
index a8381e497..8f689d6bc 100644
--- a/src/nat/test_nat_mini.c
+++ b/src/nat/test_nat_mini.c
@@ -50,10 +50,9 @@ addr_callback (void *cls, int add_remove,
50 const struct sockaddr *addr, socklen_t addrlen) 50 const struct sockaddr *addr, socklen_t addrlen)
51{ 51{
52 fprintf (stderr, 52 fprintf (stderr,
53 "Address changed: %s `%s' (%u bytes)\n", 53 "Address changed: %s `%s' (%u bytes)\n",
54 add_remove == GNUNET_YES ? "added" : "removed", 54 add_remove == GNUNET_YES ? "added" : "removed",
55 GNUNET_a2s (addr, addrlen), 55 GNUNET_a2s (addr, addrlen), (unsigned int) addrlen);
56 (unsigned int) addrlen);
57} 56}
58 57
59 58
@@ -65,8 +64,7 @@ stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
65{ 64{
66 struct GNUNET_NAT_MiniHandle *mini = cls; 65 struct GNUNET_NAT_MiniHandle *mini = cls;
67 66
68 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 67 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stopping NAT and quitting...\n");
69 "Stopping NAT and quitting...\n");
70 GNUNET_NAT_mini_map_stop (mini); 68 GNUNET_NAT_mini_map_stop (mini);
71} 69}
72 70
@@ -83,17 +81,14 @@ run (void *cls,
83 struct GNUNET_NAT_MiniHandle *mini; 81 struct GNUNET_NAT_MiniHandle *mini;
84 82
85 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 83 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
86 "Requesting NAT redirection for port %u...\n", 84 "Requesting NAT redirection for port %u...\n", PORT);
87 PORT); 85 mini = GNUNET_NAT_mini_map_start (PORT, GNUNET_YES /* tcp */ ,
88 mini = GNUNET_NAT_mini_map_start (PORT, 86 &addr_callback, NULL);
89 GNUNET_YES /* tcp */,
90 &addr_callback, NULL);
91 if (NULL == mini) 87 if (NULL == mini)
92 { 88 {
93 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 89 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Could not start UPnP interaction\n");
94 "Could not start UPnP interaction\n"); 90 return;
95 return; 91 }
96 }
97 GNUNET_SCHEDULER_add_delayed (TIMEOUT, &stop, mini); 92 GNUNET_SCHEDULER_add_delayed (TIMEOUT, &stop, mini);
98} 93}
99 94
@@ -127,9 +122,10 @@ main (int argc, char *const argv[])
127 NULL); 122 NULL);
128 123
129 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 124 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
130 "UPnP test for NAT library, timeout set to %d seconds\n", TIMEOUT); 125 "UPnP test for NAT library, timeout set to %d seconds\n",
131 GNUNET_PROGRAM_run (5, argv_prog, "test-nat-mini", 126 TIMEOUT);
132 "nohelp", options, &run, NULL); 127 GNUNET_PROGRAM_run (5, argv_prog, "test-nat-mini", "nohelp", options, &run,
128 NULL);
133 return 0; 129 return 0;
134} 130}
135 131
diff --git a/src/nat/test_nat_test.c b/src/nat/test_nat_test.c
index 32c4fb2d8..520d82d92 100644
--- a/src/nat/test_nat_test.c
+++ b/src/nat/test_nat_test.c
@@ -47,15 +47,13 @@ static struct GNUNET_NAT_Test *tst;
47static GNUNET_SCHEDULER_TaskIdentifier end; 47static GNUNET_SCHEDULER_TaskIdentifier end;
48 48
49static void 49static void
50end_test (void *cls, 50end_test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
51 const struct GNUNET_SCHEDULER_TaskContext *tc)
52{ 51{
53 GNUNET_NAT_test_stop (tst); 52 GNUNET_NAT_test_stop (tst);
54} 53}
55 54
56static void 55static void
57report_success (void *cls, 56report_success (void *cls, int success)
58 int success)
59{ 57{
60 GNUNET_assert (GNUNET_OK == success); 58 GNUNET_assert (GNUNET_OK == success);
61 ret = 0; 59 ret = 0;
@@ -72,13 +70,10 @@ run (void *cls,
72 const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) 70 const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
73{ 71{
74 tst = GNUNET_NAT_test_start (cfg, GNUNET_YES, 72 tst = GNUNET_NAT_test_start (cfg, GNUNET_YES,
75 1285, 1285, 73 1285, 1285, &report_success, NULL);
76 &report_success, NULL);
77 if (NULL == tst) 74 if (NULL == tst)
78 return; 75 return;
79 end = GNUNET_SCHEDULER_add_delayed (TIMEOUT, 76 end = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_test, NULL);
80 &end_test,
81 NULL);
82} 77}
83 78
84 79
@@ -89,6 +84,7 @@ main (int argc, char *const argv[])
89 GNUNET_GETOPT_OPTION_END 84 GNUNET_GETOPT_OPTION_END
90 }; 85 };
91 struct GNUNET_OS_Process *gns; 86 struct GNUNET_OS_Process *gns;
87
92 char *const argv_prog[] = { 88 char *const argv_prog[] = {
93 "test-nat-test", 89 "test-nat-test",
94 "-c", 90 "-c",
@@ -110,23 +106,17 @@ main (int argc, char *const argv[])
110#endif 106#endif
111 NULL); 107 NULL);
112 gns = GNUNET_OS_start_process (NULL, NULL, 108 gns = GNUNET_OS_start_process (NULL, NULL,
113 "gnunet-nat-server", 109 "gnunet-nat-server", "gnunet-nat-server",
114 "gnunet-nat-server",
115#if VERBOSE 110#if VERBOSE
116 "-L", 111 "-L", "DEBUG",
117 "DEBUG",
118#endif 112#endif
119 "-c", "test_nat_test_data.conf", 113 "-c", "test_nat_test_data.conf",
120 "12345", 114 "12345", NULL);
121 NULL);
122 GNUNET_assert (NULL != gns); 115 GNUNET_assert (NULL != gns);
123 GNUNET_PROGRAM_run (5, argv_prog, 116 GNUNET_PROGRAM_run (5, argv_prog,
124 "test-nat-test", "nohelp", 117 "test-nat-test", "nohelp", options, &run, NULL);
125 options,
126 &run, NULL);
127 GNUNET_break (0 == GNUNET_OS_process_kill (gns, SIGTERM)); 118 GNUNET_break (0 == GNUNET_OS_process_kill (gns, SIGTERM));
128 GNUNET_break (GNUNET_OK == 119 GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (gns));
129 GNUNET_OS_process_wait (gns));
130 GNUNET_OS_process_close (gns); 120 GNUNET_OS_process_close (gns);
131 return ret; 121 return ret;
132} 122}