aboutsummaryrefslogtreecommitdiff
path: root/src/dns
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-01-03 22:51:14 +0000
committerChristian Grothoff <christian@grothoff.org>2012-01-03 22:51:14 +0000
commit0bc020d2fe8fa8aa1e6896cd38c7b9d6c2311267 (patch)
treec4e9795e36241788f438b6b14dfb3a3c74f962d6 /src/dns
parent2b8b0b0dac4286b5f935167b57db5255eab1681f (diff)
downloadgnunet-0bc020d2fe8fa8aa1e6896cd38c7b9d6c2311267.tar.gz
gnunet-0bc020d2fe8fa8aa1e6896cd38c7b9d6c2311267.zip
-misc DNS related bugfixes
Diffstat (limited to 'src/dns')
-rw-r--r--src/dns/Makefile.am1
-rw-r--r--src/dns/dns.conf13
-rw-r--r--src/dns/gnunet-helper-dns.c12
-rw-r--r--src/dns/gnunet-service-dns_new.c127
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 = \
60gnunet_service_dns_new_LDADD = \ 60gnunet_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
66libgnunetdnsparser_la_SOURCES = \ 65libgnunetdnsparser_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
8ACCEPT_FROM = 127.0.0.1; 8ACCEPT_FROM = 127.0.0.1;
9ACCEPT_FROM6 = ::1; 9ACCEPT_FROM6 = ::1;
10UNIXPATH = /tmp/gnunet-service-dns.sock 10UNIXPATH = /tmp/gnunet-service-dns.sock
11PROVIDE_EXIT = NO 11
12PROVIDE_EXIT = YES
13IFNAME = gnunet-dns
14
15# Use RFC 3849-style documentation IPv6 address (RFC 4773 might provide an alternative in the future)
16IPV6ADDR = 2001:DB8::1
17IPV6PREFIX = 126
18
19# Use RFC 3927-style link-local address
20IPV4ADDR = 169.254.1.1
21IPV4MASK = 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
33GNUNET_NETWORK_STRUCT_BEGIN 42GNUNET_NETWORK_STRUCT_BEGIN
43/**
44 * Header from Linux TUN interface.
45 */
46struct 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 */
34struct ip4_header 62struct 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 */
50struct ip6_header 81struct 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 */
63struct udp_packet 97struct 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 */
71struct dns_header 108struct 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 */
266static struct RequestRecord requests[UINT16_MAX]; 303static 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;
279static void 316static void
280cleanup_rr (struct RequestRecord *rr) 317cleanup_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 }