aboutsummaryrefslogtreecommitdiff
path: root/src/dns
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-01-03 21:02:45 +0000
committerChristian Grothoff <christian@grothoff.org>2012-01-03 21:02:45 +0000
commit1ce43f352bed1f5d95db4f09773b7ecb574c41de (patch)
tree0c5c0affd18f59f03a505eee9d042dab6467e89f /src/dns
parent5b9de1c328efb28856b9239301be1821ecf21bc0 (diff)
downloadgnunet-1ce43f352bed1f5d95db4f09773b7ecb574c41de.tar.gz
gnunet-1ce43f352bed1f5d95db4f09773b7ecb574c41de.zip
-more DNS service hacking
Diffstat (limited to 'src/dns')
-rw-r--r--src/dns/gnunet-service-dns_new.c188
1 files changed, 146 insertions, 42 deletions
diff --git a/src/dns/gnunet-service-dns_new.c b/src/dns/gnunet-service-dns_new.c
index 041b2d12b..14bb19811 100644
--- a/src/dns/gnunet-service-dns_new.c
+++ b/src/dns/gnunet-service-dns_new.c
@@ -31,40 +31,36 @@
31#include "gnunet_dns_service-new.h" 31#include "gnunet_dns_service-new.h"
32 32
33GNUNET_NETWORK_STRUCT_BEGIN 33GNUNET_NETWORK_STRUCT_BEGIN
34struct ip4_hdr 34struct ip4_header
35{ 35{
36 unsigned hdr_lngth:4 GNUNET_PACKED; 36 unsigned header_length:4 GNUNET_PACKED;
37 unsigned version:4 GNUNET_PACKED; 37 unsigned version:4 GNUNET_PACKED;
38
39 uint8_t diff_serv; 38 uint8_t diff_serv;
40 uint16_t tot_lngth GNUNET_PACKED; 39 uint16_t total_length GNUNET_PACKED;
41 40 uint16_t identification GNUNET_PACKED;
42 uint16_t ident GNUNET_PACKED;
43 unsigned flags:3 GNUNET_PACKED; 41 unsigned flags:3 GNUNET_PACKED;
44 unsigned frag_off:13 GNUNET_PACKED; 42 unsigned fragmentation_offset:13 GNUNET_PACKED;
45
46 uint8_t ttl; 43 uint8_t ttl;
47 uint8_t proto; 44 uint8_t protocol;
48 uint16_t chks GNUNET_PACKED; 45 uint16_t checksum GNUNET_PACKED;
49 46 struct in_addr source_address GNUNET_PACKED;
50 struct in_addr sadr GNUNET_PACKED; 47 struct in_addr destination_address GNUNET_PACKED;
51 struct in_addr dadr GNUNET_PACKED;
52}; 48};
53 49
54struct ip6_hdr 50struct ip6_header
55{ 51{
56 unsigned tclass_h:4 GNUNET_PACKED; 52 unsigned traffic_class_h:4 GNUNET_PACKED;
57 unsigned version:4 GNUNET_PACKED; 53 unsigned version:4 GNUNET_PACKED;
58 unsigned tclass_l:4 GNUNET_PACKED; 54 unsigned traffic_class_l:4 GNUNET_PACKED;
59 unsigned flowlbl:20 GNUNET_PACKED; 55 unsigned flow_label:20 GNUNET_PACKED;
60 uint16_t paylgth GNUNET_PACKED; 56 uint16_t payload_length GNUNET_PACKED;
61 uint8_t nxthdr; 57 uint8_t next_header;
62 uint8_t hoplmt; 58 uint8_t hop_limit;
63 struct in6_addr sadr GNUNET_PACKED; 59 struct in6_addr source_address GNUNET_PACKED;
64 struct in6_addr dadr GNUNET_PACKED; 60 struct in6_addr destination_address GNUNET_PACKED;
65}; 61};
66 62
67struct udp_pkt 63struct udp_packet
68{ 64{
69 uint16_t spt GNUNET_PACKED; 65 uint16_t spt GNUNET_PACKED;
70 uint16_t dpt GNUNET_PACKED; 66 uint16_t dpt GNUNET_PACKED;
@@ -72,8 +68,7 @@ struct udp_pkt
72 uint16_t crc GNUNET_PACKED; 68 uint16_t crc GNUNET_PACKED;
73}; 69};
74 70
75 71struct dns_header
76struct dns_hdr
77{ 72{
78 uint16_t id GNUNET_PACKED; 73 uint16_t id GNUNET_PACKED;
79 uint16_t flags GNUNET_PACKED; 74 uint16_t flags GNUNET_PACKED;
@@ -364,17 +359,17 @@ request_done (struct RequestRecord *rr)
364 switch (rr->src_addr.ss_family) 359 switch (rr->src_addr.ss_family)
365 { 360 {
366 case AF_INET: 361 case AF_INET:
367 reply_len += sizeof (struct ip4_hdr); 362 reply_len += sizeof (struct ip4_header);
368 break; 363 break;
369 case AF_INET6: 364 case AF_INET6:
370 reply_len += sizeof (struct ip6_hdr); 365 reply_len += sizeof (struct ip6_header);
371 break; 366 break;
372 default: 367 default:
373 GNUNET_break (0); 368 GNUNET_break (0);
374 cleanup_rr (rr); 369 cleanup_rr (rr);
375 return; 370 return;
376 } 371 }
377 reply_len += sizeof (struct udp_pkt); 372 reply_len += sizeof (struct udp_packet);
378 reply_len += rr->payload_length; 373 reply_len += rr->payload_length;
379 if (reply_len >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 374 if (reply_len >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
380 { 375 {
@@ -400,11 +395,23 @@ request_done (struct RequestRecord *rr)
400 { 395 {
401 struct sockaddr_in *src = (struct sockaddr_in *) &rr->src_addr; 396 struct sockaddr_in *src = (struct sockaddr_in *) &rr->src_addr;
402 struct sockaddr_in *dst = (struct sockaddr_in *) &rr->dst_addr; 397 struct sockaddr_in *dst = (struct sockaddr_in *) &rr->dst_addr;
403 struct ip4_hdr ip; 398 struct ip4_header ip;
404 399
405 spt = dst->sin_port; 400 spt = dst->sin_port;
406 dpt = src->sin_port; 401 dpt = src->sin_port;
407 // FIXME: fill in IP header! 402 ip.header_length = sizeof (struct ip4_header) / 4;
403 ip.version = IPVERSION; /* aka 4 */
404 ip.diff_serv = 0;
405 ip.total_length = htons ((uint16_t) reply_len);
406 ip.identification = (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
407 65536);
408 ip.flags = 0;
409 ip.fragmentation_offset = 0;
410 ip.ttl = 255; /* or lower? */
411 ip.protocol = IPPROTO_UDP;
412 ip.checksum = 0; /* checksum is optional */
413 ip.source_address = dst->sin_addr;
414 ip.destination_address = src->sin_addr;
408 memcpy (&buf[off], &ip, sizeof (ip)); 415 memcpy (&buf[off], &ip, sizeof (ip));
409 off += sizeof (ip); 416 off += sizeof (ip);
410 break; 417 break;
@@ -413,11 +420,19 @@ request_done (struct RequestRecord *rr)
413 { 420 {
414 struct sockaddr_in6 *src = (struct sockaddr_in6 *) &rr->src_addr; 421 struct sockaddr_in6 *src = (struct sockaddr_in6 *) &rr->src_addr;
415 struct sockaddr_in6 *dst = (struct sockaddr_in6 *) &rr->dst_addr; 422 struct sockaddr_in6 *dst = (struct sockaddr_in6 *) &rr->dst_addr;
416 struct ip6_hdr ip; 423 struct ip6_header ip;
417 424
418 spt = dst->sin6_port; 425 spt = dst->sin6_port;
419 dpt = src->sin6_port; 426 dpt = src->sin6_port;
420 // FIXME: fill in IP header! 427 ip.traffic_class_h = 0;
428 ip.version = 6; /* is there a named constant? I couldn't find one */
429 ip.traffic_class_l = 0;
430 ip.flow_label = 0;
431 ip.payload_length = htons ((uint16_t) reply_len);
432 ip.next_header = IPPROTO_UDP;
433 ip.hop_limit = 255; /* or lower? */
434 ip.source_address = dst->sin6_addr;
435 ip.destination_address = src->sin6_addr;
421 memcpy (&buf[off], &ip, sizeof (ip)); 436 memcpy (&buf[off], &ip, sizeof (ip));
422 off += sizeof (ip); 437 off += sizeof (ip);
423 } 438 }
@@ -428,7 +443,7 @@ request_done (struct RequestRecord *rr)
428 443
429 /* now UDP header */ 444 /* now UDP header */
430 { 445 {
431 struct udp_pkt udp; 446 struct udp_packet udp;
432 447
433 udp.spt = spt; 448 udp.spt = spt;
434 udp.dpt = dpt; 449 udp.dpt = dpt;
@@ -553,11 +568,11 @@ next_phase (struct RequestRecord *rr)
553 { 568 {
554 case AF_INET: 569 case AF_INET:
555 dnsout = dnsout4; 570 dnsout = dnsout4;
556 salen = sizeof (struct ip4_hdr); 571 salen = sizeof (struct ip4_header);
557 break; 572 break;
558 case AF_INET6: 573 case AF_INET6:
559 dnsout = dnsout6; 574 dnsout = dnsout6;
560 salen = sizeof (struct ip6_hdr); 575 salen = sizeof (struct ip6_header);
561 break; 576 break;
562 default: 577 default:
563 GNUNET_break (0); 578 GNUNET_break (0);
@@ -652,7 +667,7 @@ read_response (void *cls,
652 struct sockaddr_in addr4; 667 struct sockaddr_in addr4;
653 struct sockaddr_in6 addr6; 668 struct sockaddr_in6 addr6;
654 struct sockaddr *addr; 669 struct sockaddr *addr;
655 struct dns_hdr *dns; 670 struct dns_header *dns;
656 socklen_t addrlen; 671 socklen_t addrlen;
657 struct RequestRecord *rr; 672 struct RequestRecord *rr;
658 ssize_t r; 673 ssize_t r;
@@ -702,14 +717,14 @@ read_response (void *cls,
702 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "recvfrom"); 717 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "recvfrom");
703 return; 718 return;
704 } 719 }
705 if (sizeof (struct dns_hdr) > r) 720 if (sizeof (struct dns_header) > r)
706 { 721 {
707 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 722 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
708 _("Received DNS response that is too small (%u bytes)"), 723 _("Received DNS response that is too small (%u bytes)"),
709 r); 724 r);
710 return; 725 return;
711 } 726 }
712 dns = (struct dns_hdr *) buf; 727 dns = (struct dns_header *) buf;
713 rr = &requests[dns->id]; 728 rr = &requests[dns->id];
714 if (rr->phase != RP_INTERNET_DNS) 729 if (rr->phase != RP_INTERNET_DNS)
715 { 730 {
@@ -918,7 +933,7 @@ handle_client_response (void *cls GNUNET_UNUSED,
918 break; 933 break;
919 case 2: /* update */ 934 case 2: /* update */
920 msize -= sizeof (struct GNUNET_DNS_Response); 935 msize -= sizeof (struct GNUNET_DNS_Response);
921 if ( (sizeof (struct dns_hdr) > msize) || 936 if ( (sizeof (struct dns_header) > msize) ||
922 (RP_MONITOR == rr->phase) ) 937 (RP_MONITOR == rr->phase) )
923 { 938 {
924 GNUNET_break (0); 939 GNUNET_break (0);
@@ -960,10 +975,99 @@ static void
960process_helper_messages (void *cls GNUNET_UNUSED, void *client, 975process_helper_messages (void *cls GNUNET_UNUSED, void *client,
961 const struct GNUNET_MessageHeader *message) 976 const struct GNUNET_MessageHeader *message)
962{ 977{
963 struct RequestRecord *rr = NULL; 978 uint16_t msize;
964 /* FIXME: parse message, create record, start processing! */ 979 const struct ip4_header *ip4;
965 /* FIXME: put request into queue for clients / system DNS */ 980 const struct ip6_header *ip6;
981 const struct udp_packet *udp;
982 const struct dns_header *dns;
983 struct RequestRecord *rr;
984 struct sockaddr_in *srca4;
985 struct sockaddr_in6 *srca6;
986 struct sockaddr_in *dsta4;
987 struct sockaddr_in6 *dsta6;
988
989 msize = ntohs (message->size);
990 if (msize < sizeof (struct GNUNET_MessageHeader) + sizeof (struct ip4_header))
991 {
992 /* non-IP packet received on TUN!? */
993 GNUNET_break (0);
994 return;
995 }
996 msize -= sizeof (struct GNUNET_MessageHeader);
997 ip4 = (const struct ip4_header *) &message[1];
998 ip6 = (const struct ip6_header *) &message[1];
999 if (ip4->version == IPVERSION)
1000 {
1001 udp = (const struct udp_packet*) &ip4[1];
1002 msize -= sizeof (struct ip4_header);
1003 }
1004 else if ( (ip6->version == 6) &&
1005 (msize >= sizeof (struct ip6_header)) )
1006 {
1007 udp = (const struct udp_packet*) &ip6[1];
1008 msize -= sizeof (struct ip6_header);
1009 }
1010 else
1011 {
1012 /* non-IP packet received on TUN!? */
1013 GNUNET_break (0);
1014 return;
1015 }
1016 if (msize <= sizeof (struct udp_packet) + sizeof (struct dns_header))
1017 {
1018 /* non-DNS packet received on TUN, ignore */
1019 /* FIXME: case for statistics... */
1020 return;
1021 }
1022 msize -= sizeof (struct udp_packet);
1023 dns = (const struct dns_header*) &udp[1];
1024 rr = &requests[dns->id];
1025
1026 /* clean up from previous request */
1027 GNUNET_free_non_null (rr->payload);
1028 rr->payload = NULL;
1029 GNUNET_array_grow (rr->client_wait_list,
1030 rr->client_wait_list_length,
1031 0);
1032
1033 /* setup new request */
1034 rr->phase = RP_INIT;
1035 if (ip4->version == IPVERSION)
1036 {
1037 srca4 = (struct sockaddr_in*) &rr->src_addr;
1038 dsta4 = (struct sockaddr_in*) &rr->dst_addr;
1039 memset (srca4, 0, sizeof (struct sockaddr_in));
1040 memset (dsta4, 0, sizeof (struct sockaddr_in));
1041 srca4->sin_family = AF_INET;
1042 dsta4->sin_family = AF_INET;
1043 srca4->sin_addr = ip4->source_address;
1044 dsta4->sin_addr = ip4->destination_address;
1045 srca4->sin_port = udp->spt;
1046 dsta4->sin_port = udp->dpt;
1047 /* FIXME: bother with FreeBSD sin_len crap? */
1048 }
1049 else /* ipv6 */
1050 {
1051 srca6 = (struct sockaddr_in6*) &rr->src_addr;
1052 dsta6 = (struct sockaddr_in6*) &rr->dst_addr;
1053 memset (srca6, 0, sizeof (struct sockaddr_in6));
1054 memset (dsta6, 0, sizeof (struct sockaddr_in6));
1055 srca6->sin6_family = AF_INET6;
1056 dsta6->sin6_family = AF_INET6;
1057 srca6->sin6_addr = ip6->source_address;
1058 dsta6->sin6_addr = ip6->destination_address;
1059 srca6->sin6_port = udp->spt;
1060 dsta6->sin6_port = udp->dpt;
1061 /* FIXME: bother with FreeBSD sin_len crap? */
1062 }
1063 rr->payload = GNUNET_malloc (msize);
1064 rr->payload_length = msize;
1065 memcpy (rr->payload, dns, msize);
1066 rr->request_id = dns->id | (request_id_gen << 16);
966 request_id_gen++; 1067 request_id_gen++;
1068
1069 /* FIXME: case for statistics... */
1070 /* start request processing state machine */
967 next_phase (rr); 1071 next_phase (rr);
968} 1072}
969 1073