diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-01-03 22:51:14 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-01-03 22:51:14 +0000 |
commit | 0bc020d2fe8fa8aa1e6896cd38c7b9d6c2311267 (patch) | |
tree | c4e9795e36241788f438b6b14dfb3a3c74f962d6 /src/dns | |
parent | 2b8b0b0dac4286b5f935167b57db5255eab1681f (diff) | |
download | gnunet-0bc020d2fe8fa8aa1e6896cd38c7b9d6c2311267.tar.gz gnunet-0bc020d2fe8fa8aa1e6896cd38c7b9d6c2311267.zip |
-misc DNS related bugfixes
Diffstat (limited to 'src/dns')
-rw-r--r-- | src/dns/Makefile.am | 1 | ||||
-rw-r--r-- | src/dns/dns.conf | 13 | ||||
-rw-r--r-- | src/dns/gnunet-helper-dns.c | 12 | ||||
-rw-r--r-- | src/dns/gnunet-service-dns_new.c | 127 |
4 files changed, 135 insertions, 18 deletions
diff --git a/src/dns/Makefile.am b/src/dns/Makefile.am index 2d5efb2f6..674f4bf57 100644 --- a/src/dns/Makefile.am +++ b/src/dns/Makefile.am | |||
@@ -60,7 +60,6 @@ gnunet_service_dns_new_SOURCES = \ | |||
60 | gnunet_service_dns_new_LDADD = \ | 60 | gnunet_service_dns_new_LDADD = \ |
61 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | 61 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ |
62 | $(top_builddir)/src/util/libgnunetutil.la \ | 62 | $(top_builddir)/src/util/libgnunetutil.la \ |
63 | $(top_builddir)/src/dns/libgnunetdnsparser.la \ | ||
64 | $(GN_LIBINTL) | 63 | $(GN_LIBINTL) |
65 | 64 | ||
66 | libgnunetdnsparser_la_SOURCES = \ | 65 | libgnunetdnsparser_la_SOURCES = \ |
diff --git a/src/dns/dns.conf b/src/dns/dns.conf index 59d827692..f8590bf61 100644 --- a/src/dns/dns.conf +++ b/src/dns/dns.conf | |||
@@ -8,4 +8,15 @@ BINARY = gnunet-service-dns | |||
8 | ACCEPT_FROM = 127.0.0.1; | 8 | ACCEPT_FROM = 127.0.0.1; |
9 | ACCEPT_FROM6 = ::1; | 9 | ACCEPT_FROM6 = ::1; |
10 | UNIXPATH = /tmp/gnunet-service-dns.sock | 10 | UNIXPATH = /tmp/gnunet-service-dns.sock |
11 | PROVIDE_EXIT = NO | 11 | |
12 | PROVIDE_EXIT = YES | ||
13 | IFNAME = gnunet-dns | ||
14 | |||
15 | # Use RFC 3849-style documentation IPv6 address (RFC 4773 might provide an alternative in the future) | ||
16 | IPV6ADDR = 2001:DB8::1 | ||
17 | IPV6PREFIX = 126 | ||
18 | |||
19 | # Use RFC 3927-style link-local address | ||
20 | IPV4ADDR = 169.254.1.1 | ||
21 | IPV4MASK = 255.255.0.0 | ||
22 | |||
diff --git a/src/dns/gnunet-helper-dns.c b/src/dns/gnunet-helper-dns.c index 07cc9647c..56b8713cf 100644 --- a/src/dns/gnunet-helper-dns.c +++ b/src/dns/gnunet-helper-dns.c | |||
@@ -760,7 +760,9 @@ main (int argc, char *const*argv) | |||
760 | return 6; | 760 | return 6; |
761 | } | 761 | } |
762 | } | 762 | } |
763 | if (SIG_ERR == signal (SIGTERM, &signal_handler)) | 763 | if ( (SIG_ERR == signal (SIGTERM, &signal_handler)) || |
764 | (SIG_ERR == signal (SIGINT, &signal_handler)) || | ||
765 | (SIG_ERR == signal (SIGHUP, &signal_handler)) ) | ||
764 | { | 766 | { |
765 | fprintf (stderr, | 767 | fprintf (stderr, |
766 | "Fatal: could not initialize signal handler: %s\n", | 768 | "Fatal: could not initialize signal handler: %s\n", |
@@ -779,7 +781,9 @@ main (int argc, char *const*argv) | |||
779 | if (-1 == (fd_tun = init_tun (dev))) | 781 | if (-1 == (fd_tun = init_tun (dev))) |
780 | { | 782 | { |
781 | fprintf (stderr, "Fatal: could not initialize tun-interface\n"); | 783 | fprintf (stderr, "Fatal: could not initialize tun-interface\n"); |
784 | (void) signal (SIGTERM, SIG_IGN); | ||
782 | (void) signal (SIGINT, SIG_IGN); | 785 | (void) signal (SIGINT, SIG_IGN); |
786 | (void) signal (SIGHUP, SIG_IGN); | ||
783 | (void) close (cpipe[0]); | 787 | (void) close (cpipe[0]); |
784 | (void) close (cpipe[1]); | 788 | (void) close (cpipe[1]); |
785 | return 5; | 789 | return 5; |
@@ -793,7 +797,9 @@ main (int argc, char *const*argv) | |||
793 | if ((prefix_len < 1) || (prefix_len > 127)) | 797 | if ((prefix_len < 1) || (prefix_len > 127)) |
794 | { | 798 | { |
795 | fprintf (stderr, "Fatal: prefix_len out of range\n"); | 799 | fprintf (stderr, "Fatal: prefix_len out of range\n"); |
800 | (void) signal (SIGTERM, SIG_IGN); | ||
796 | (void) signal (SIGINT, SIG_IGN); | 801 | (void) signal (SIGINT, SIG_IGN); |
802 | (void) signal (SIGHUP, SIG_IGN); | ||
797 | (void) close (cpipe[0]); | 803 | (void) close (cpipe[0]); |
798 | (void) close (cpipe[1]); | 804 | (void) close (cpipe[1]); |
799 | return 2; | 805 | return 2; |
@@ -941,8 +947,10 @@ main (int argc, char *const*argv) | |||
941 | cleanup_rest: | 947 | cleanup_rest: |
942 | /* close virtual interface */ | 948 | /* close virtual interface */ |
943 | (void) close (fd_tun); | 949 | (void) close (fd_tun); |
944 | /* remove SIGINT handler so we can close the pipes */ | 950 | /* remove signal handler so we can close the pipes */ |
951 | (void) signal (SIGTERM, SIG_IGN); | ||
945 | (void) signal (SIGINT, SIG_IGN); | 952 | (void) signal (SIGINT, SIG_IGN); |
953 | (void) signal (SIGHUP, SIG_IGN); | ||
946 | (void) close (cpipe[0]); | 954 | (void) close (cpipe[0]); |
947 | (void) close (cpipe[1]); | 955 | (void) close (cpipe[1]); |
948 | return r; | 956 | return r; |
diff --git a/src/dns/gnunet-service-dns_new.c b/src/dns/gnunet-service-dns_new.c index 14bb19811..8d9727425 100644 --- a/src/dns/gnunet-service-dns_new.c +++ b/src/dns/gnunet-service-dns_new.c | |||
@@ -30,7 +30,35 @@ | |||
30 | #include "dns_new.h" | 30 | #include "dns_new.h" |
31 | #include "gnunet_dns_service-new.h" | 31 | #include "gnunet_dns_service-new.h" |
32 | 32 | ||
33 | /* see http://www.iana.org/assignments/ethernet-numbers */ | ||
34 | #ifndef ETH_P_IPV4 | ||
35 | #define ETH_P_IPV4 0x0800 | ||
36 | #endif | ||
37 | |||
38 | #ifndef ETH_P_IPV6 | ||
39 | #define ETH_P_IPV6 0x86DD | ||
40 | #endif | ||
41 | |||
33 | GNUNET_NETWORK_STRUCT_BEGIN | 42 | GNUNET_NETWORK_STRUCT_BEGIN |
43 | /** | ||
44 | * Header from Linux TUN interface. | ||
45 | */ | ||
46 | struct tun_header | ||
47 | { | ||
48 | /** | ||
49 | * Some flags (unused). | ||
50 | */ | ||
51 | uint16_t flags; | ||
52 | |||
53 | /** | ||
54 | * Here we get an ETH_P_-number. | ||
55 | */ | ||
56 | uint16_t proto; | ||
57 | }; | ||
58 | |||
59 | /** | ||
60 | * Standard IPv4 header. | ||
61 | */ | ||
34 | struct ip4_header | 62 | struct ip4_header |
35 | { | 63 | { |
36 | unsigned header_length:4 GNUNET_PACKED; | 64 | unsigned header_length:4 GNUNET_PACKED; |
@@ -47,6 +75,9 @@ struct ip4_header | |||
47 | struct in_addr destination_address GNUNET_PACKED; | 75 | struct in_addr destination_address GNUNET_PACKED; |
48 | }; | 76 | }; |
49 | 77 | ||
78 | /** | ||
79 | * Standard IPv6 header. | ||
80 | */ | ||
50 | struct ip6_header | 81 | struct ip6_header |
51 | { | 82 | { |
52 | unsigned traffic_class_h:4 GNUNET_PACKED; | 83 | unsigned traffic_class_h:4 GNUNET_PACKED; |
@@ -60,6 +91,9 @@ struct ip6_header | |||
60 | struct in6_addr destination_address GNUNET_PACKED; | 91 | struct in6_addr destination_address GNUNET_PACKED; |
61 | }; | 92 | }; |
62 | 93 | ||
94 | /** | ||
95 | * UDP packet header. | ||
96 | */ | ||
63 | struct udp_packet | 97 | struct udp_packet |
64 | { | 98 | { |
65 | uint16_t spt GNUNET_PACKED; | 99 | uint16_t spt GNUNET_PACKED; |
@@ -68,6 +102,9 @@ struct udp_packet | |||
68 | uint16_t crc GNUNET_PACKED; | 102 | uint16_t crc GNUNET_PACKED; |
69 | }; | 103 | }; |
70 | 104 | ||
105 | /** | ||
106 | * DNS header. | ||
107 | */ | ||
71 | struct dns_header | 108 | struct dns_header |
72 | { | 109 | { |
73 | uint16_t id GNUNET_PACKED; | 110 | uint16_t id GNUNET_PACKED; |
@@ -263,7 +300,7 @@ static struct GNUNET_SERVER_NotificationContext *nc; | |||
263 | /** | 300 | /** |
264 | * Array of all open requests. | 301 | * Array of all open requests. |
265 | */ | 302 | */ |
266 | static struct RequestRecord requests[UINT16_MAX]; | 303 | static struct RequestRecord requests[UINT16_MAX + 1]; |
267 | 304 | ||
268 | /** | 305 | /** |
269 | * Generator for unique request IDs. | 306 | * Generator for unique request IDs. |
@@ -279,7 +316,7 @@ static uint64_t request_id_gen; | |||
279 | static void | 316 | static void |
280 | cleanup_rr (struct RequestRecord *rr) | 317 | cleanup_rr (struct RequestRecord *rr) |
281 | { | 318 | { |
282 | GNUNET_free (rr->payload); | 319 | GNUNET_free_non_null (rr->payload); |
283 | rr->payload = NULL; | 320 | rr->payload = NULL; |
284 | rr->payload_length = 0; | 321 | rr->payload_length = 0; |
285 | GNUNET_array_grow (rr->client_wait_list, | 322 | GNUNET_array_grow (rr->client_wait_list, |
@@ -356,6 +393,7 @@ request_done (struct RequestRecord *rr) | |||
356 | 393 | ||
357 | /* send response via hijacker */ | 394 | /* send response via hijacker */ |
358 | reply_len = sizeof (struct GNUNET_MessageHeader); | 395 | reply_len = sizeof (struct GNUNET_MessageHeader); |
396 | reply_len += sizeof (struct tun_header); | ||
359 | switch (rr->src_addr.ss_family) | 397 | switch (rr->src_addr.ss_family) |
360 | { | 398 | { |
361 | case AF_INET: | 399 | case AF_INET: |
@@ -381,6 +419,9 @@ request_done (struct RequestRecord *rr) | |||
381 | { | 419 | { |
382 | char buf[reply_len]; | 420 | char buf[reply_len]; |
383 | size_t off; | 421 | size_t off; |
422 | uint16_t *udp_crcp; | ||
423 | char *udp_crc_start; | ||
424 | uint16_t udp_crc_length; | ||
384 | 425 | ||
385 | /* first, GNUnet message header */ | 426 | /* first, GNUnet message header */ |
386 | hdr = (struct GNUNET_MessageHeader*) buf; | 427 | hdr = (struct GNUNET_MessageHeader*) buf; |
@@ -388,7 +429,22 @@ request_done (struct RequestRecord *rr) | |||
388 | hdr->size = htons ((uint16_t) reply_len); | 429 | hdr->size = htons ((uint16_t) reply_len); |
389 | off = sizeof (struct GNUNET_MessageHeader); | 430 | off = sizeof (struct GNUNET_MessageHeader); |
390 | 431 | ||
432 | /* first, TUN header */ | ||
433 | { | ||
434 | struct tun_header tun; | ||
435 | |||
436 | tun.flags = htons (0); | ||
437 | if (rr->src_addr.ss_family == AF_INET) | ||
438 | tun.proto = htons (ETH_P_IPV4); | ||
439 | else | ||
440 | tun.proto = htons (ETH_P_IPV6); | ||
441 | memcpy (&buf[off], &tun, sizeof (struct tun_header)); | ||
442 | off += sizeof (struct tun_header); | ||
443 | } | ||
444 | |||
391 | /* now IP header */ | 445 | /* now IP header */ |
446 | udp_crc_start = &buf[off]; | ||
447 | udp_crc_length = reply_len - off; | ||
392 | switch (rr->src_addr.ss_family) | 448 | switch (rr->src_addr.ss_family) |
393 | { | 449 | { |
394 | case AF_INET: | 450 | case AF_INET: |
@@ -412,6 +468,8 @@ request_done (struct RequestRecord *rr) | |||
412 | ip.checksum = 0; /* checksum is optional */ | 468 | ip.checksum = 0; /* checksum is optional */ |
413 | ip.source_address = dst->sin_addr; | 469 | ip.source_address = dst->sin_addr; |
414 | ip.destination_address = src->sin_addr; | 470 | ip.destination_address = src->sin_addr; |
471 | |||
472 | ip.checksum = GNUNET_CRYPTO_crc16_n ((uint16_t*) &ip, sizeof (ip)); | ||
415 | memcpy (&buf[off], &ip, sizeof (ip)); | 473 | memcpy (&buf[off], &ip, sizeof (ip)); |
416 | off += sizeof (ip); | 474 | off += sizeof (ip); |
417 | break; | 475 | break; |
@@ -448,16 +506,23 @@ request_done (struct RequestRecord *rr) | |||
448 | udp.spt = spt; | 506 | udp.spt = spt; |
449 | udp.dpt = dpt; | 507 | udp.dpt = dpt; |
450 | udp.len = htons (reply_len - off); | 508 | udp.len = htons (reply_len - off); |
451 | udp.crc = 0; /* checksum is optional */ | 509 | udp.crc = 0; /* checksum will be set later */ |
510 | |||
452 | memcpy (&buf[off], &udp, sizeof (udp)); | 511 | memcpy (&buf[off], &udp, sizeof (udp)); |
512 | udp_crcp = (uint16_t*) &buf[off + offsetof (struct udp_packet, crc)]; | ||
453 | off += sizeof (udp); | 513 | off += sizeof (udp); |
454 | } | 514 | } |
455 | /* now DNS header */ | 515 | /* now DNS header */ |
456 | { | 516 | { |
457 | memcpy (&buf[off], rr->payload, rr->payload_length); | 517 | memcpy (&buf[off], rr->payload, rr->payload_length); |
458 | off += rr->payload_length; | 518 | off += rr->payload_length; |
519 | |||
520 | fprintf (stderr, | ||
521 | "Sending %u bytes UDP packet to TUN\n", | ||
522 | (unsigned int) rr->payload_length); | ||
459 | } | 523 | } |
460 | 524 | ||
525 | *udp_crcp = GNUNET_CRYPTO_crc16_n ((uint16_t *)udp_crc_start, udp_crc_length); | ||
461 | /* final checks & sending */ | 526 | /* final checks & sending */ |
462 | GNUNET_assert (off == reply_len); | 527 | GNUNET_assert (off == reply_len); |
463 | GNUNET_HELPER_send (hijacker, | 528 | GNUNET_HELPER_send (hijacker, |
@@ -579,6 +644,12 @@ next_phase (struct RequestRecord *rr) | |||
579 | cleanup_rr (rr); | 644 | cleanup_rr (rr); |
580 | return; | 645 | return; |
581 | } | 646 | } |
647 | if (NULL == dnsout) | ||
648 | { | ||
649 | /* fail, FIXME: case for statistics! */ | ||
650 | cleanup_rr (rr); | ||
651 | return; | ||
652 | } | ||
582 | GNUNET_NETWORK_socket_sendto (dnsout, | 653 | GNUNET_NETWORK_socket_sendto (dnsout, |
583 | rr->payload, | 654 | rr->payload, |
584 | rr->payload_length, | 655 | rr->payload_length, |
@@ -735,6 +806,10 @@ read_response (void *cls, | |||
735 | GNUNET_free_non_null (rr->payload); | 806 | GNUNET_free_non_null (rr->payload); |
736 | rr->payload = GNUNET_malloc (len); | 807 | rr->payload = GNUNET_malloc (len); |
737 | memcpy (rr->payload, buf, len); | 808 | memcpy (rr->payload, buf, len); |
809 | rr->payload_length = len; | ||
810 | fprintf (stderr, | ||
811 | "Received %u bytes UDP packet from DNS server\n", | ||
812 | (unsigned int) len); | ||
738 | next_phase (rr); | 813 | next_phase (rr); |
739 | } | 814 | } |
740 | } | 815 | } |
@@ -976,6 +1051,7 @@ process_helper_messages (void *cls GNUNET_UNUSED, void *client, | |||
976 | const struct GNUNET_MessageHeader *message) | 1051 | const struct GNUNET_MessageHeader *message) |
977 | { | 1052 | { |
978 | uint16_t msize; | 1053 | uint16_t msize; |
1054 | const struct tun_header *tun; | ||
979 | const struct ip4_header *ip4; | 1055 | const struct ip4_header *ip4; |
980 | const struct ip6_header *ip6; | 1056 | const struct ip6_header *ip6; |
981 | const struct udp_packet *udp; | 1057 | const struct udp_packet *udp; |
@@ -987,29 +1063,52 @@ process_helper_messages (void *cls GNUNET_UNUSED, void *client, | |||
987 | struct sockaddr_in6 *dsta6; | 1063 | struct sockaddr_in6 *dsta6; |
988 | 1064 | ||
989 | msize = ntohs (message->size); | 1065 | msize = ntohs (message->size); |
990 | if (msize < sizeof (struct GNUNET_MessageHeader) + sizeof (struct ip4_header)) | 1066 | if (msize < sizeof (struct GNUNET_MessageHeader) + sizeof (struct tun_header) + sizeof (struct ip4_header)) |
991 | { | 1067 | { |
992 | /* non-IP packet received on TUN!? */ | 1068 | /* non-IP packet received on TUN!? */ |
993 | GNUNET_break (0); | 1069 | GNUNET_break (0); |
994 | return; | 1070 | return; |
995 | } | 1071 | } |
996 | msize -= sizeof (struct GNUNET_MessageHeader); | 1072 | msize -= sizeof (struct GNUNET_MessageHeader); |
997 | ip4 = (const struct ip4_header *) &message[1]; | 1073 | tun = (const struct tun_header *) &message[1]; |
998 | ip6 = (const struct ip6_header *) &message[1]; | 1074 | msize -= sizeof (struct tun_header); |
999 | if (ip4->version == IPVERSION) | 1075 | switch (ntohs (tun->proto)) |
1000 | { | 1076 | { |
1077 | case ETH_P_IPV4: | ||
1078 | ip4 = (const struct ip4_header *) &tun[1]; | ||
1079 | if ( (msize < sizeof (struct ip4_header)) || | ||
1080 | (ip4->version != IPVERSION) || | ||
1081 | (ip4->header_length != sizeof (struct ip4_header) / 4) || | ||
1082 | (ntohs(ip4->total_length) != msize) || | ||
1083 | (ip4->protocol != IPPROTO_UDP) ) | ||
1084 | { | ||
1085 | /* non-IP/UDP packet received on TUN (or with options) */ | ||
1086 | GNUNET_break (0); | ||
1087 | return; | ||
1088 | } | ||
1001 | udp = (const struct udp_packet*) &ip4[1]; | 1089 | udp = (const struct udp_packet*) &ip4[1]; |
1002 | msize -= sizeof (struct ip4_header); | 1090 | msize -= sizeof (struct ip4_header); |
1003 | } | 1091 | break; |
1004 | else if ( (ip6->version == 6) && | 1092 | case ETH_P_IPV6: |
1005 | (msize >= sizeof (struct ip6_header)) ) | 1093 | ip6 = (const struct ip6_header *) &tun[1]; |
1006 | { | 1094 | if ( (msize < sizeof (struct ip6_header)) || |
1095 | (ip6->version != 6) || | ||
1096 | (ntohs (ip6->payload_length) != msize) || | ||
1097 | (ip6->next_header != IPPROTO_UDP) ) | ||
1098 | { | ||
1099 | /* non-IP/UDP packet received on TUN (or with extensions) */ | ||
1100 | GNUNET_break (0); | ||
1101 | return; | ||
1102 | } | ||
1007 | udp = (const struct udp_packet*) &ip6[1]; | 1103 | udp = (const struct udp_packet*) &ip6[1]; |
1008 | msize -= sizeof (struct ip6_header); | 1104 | msize -= sizeof (struct ip6_header); |
1009 | } | 1105 | break; |
1010 | else | 1106 | default: |
1011 | { | ||
1012 | /* non-IP packet received on TUN!? */ | 1107 | /* non-IP packet received on TUN!? */ |
1108 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1109 | _("Got packet with %u bytes and protocol %u from TUN\n"), | ||
1110 | (unsigned int) msize, | ||
1111 | ntohs (tun->proto)); | ||
1013 | GNUNET_break (0); | 1112 | GNUNET_break (0); |
1014 | return; | 1113 | return; |
1015 | } | 1114 | } |