From 4b082a48b93980cfd1c85371ca75d4909716911c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Philipp=20T=C3=B6lke?= Date: Tue, 26 Oct 2010 13:55:56 +0000 Subject: [PATCH] Answer questions for .gnunet with an ipv6-address --- src/vpn/gnunet-daemon-vpn.c | 29 +++++++++++++------- src/vpn/gnunet-service-dns-p.h | 6 +++++ src/vpn/gnunet-service-dns.c | 49 +++++++++++++++++++++++++++++++--- src/vpn/gnunet-vpn-packet.h | 13 +++++++++ 4 files changed, 84 insertions(+), 13 deletions(-) diff --git a/src/vpn/gnunet-daemon-vpn.c b/src/vpn/gnunet-daemon-vpn.c index 227bcd9ae..a02af54a2 100644 --- a/src/vpn/gnunet-daemon-vpn.c +++ b/src/vpn/gnunet-daemon-vpn.c @@ -36,6 +36,7 @@ #include "gnunet-service-dns-p.h" #include "gnunet_client_lib.h" #include "gnunet_container_lib.h" +#include "block_dns.h" /** * Final status code. @@ -307,8 +308,25 @@ static void process_answer(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tc) { struct answer_packet* pkt = cls; - if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_IP) + if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_SERVICE) { + pkt->subtype = GNUNET_DNS_ANSWER_TYPE_IP; + unsigned char ip6addr[16]; + memcpy(ip6addr, (int[]){htons(0x1234)}, 2); + memcpy(ip6addr+2, &pkt->peer, 7); + memcpy(ip6addr+9, &pkt->service_descriptor, 7); + + memcpy(((char*)pkt)+ntohs(pkt->addroffset), ip6addr, 16); + + /*FIXME: + * -save DNS_Record into hashmap, pointed to by ip + * -regularily walk through hashmap, deleting old entries + * when is an entry old? + * have a last-used field + * don't remove if last-used "recent", ask dht again if record expired + */ + } + struct answer_packet_list* list = GNUNET_malloc(htons(pkt->hdr.size) + 2*sizeof(struct answer_packet_list*)); memcpy(&list->pkt, pkt, htons(pkt->hdr.size)); @@ -318,15 +336,6 @@ process_answer(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tc) { GNUNET_SCHEDULER_add_write_file (mycls.sched, GNUNET_TIME_UNIT_FOREVER_REL, mycls.fh_to_helper, &helper_write, NULL); return; - } - - if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_SERVICE) - { - /*FIXME: - * -find new IP-address for this service - * -create a DNS-Answer - */ - } } static void diff --git a/src/vpn/gnunet-service-dns-p.h b/src/vpn/gnunet-service-dns-p.h index 1e25daa90..690a947a6 100644 --- a/src/vpn/gnunet-service-dns-p.h +++ b/src/vpn/gnunet-service-dns-p.h @@ -40,6 +40,12 @@ struct answer_packet { unsigned dst_port:16 GNUNET_PACKED; unsigned short id GNUNET_PACKED; + GNUNET_HashCode peer; + GNUNET_HashCode service_descriptor; + uint64_t ports; + uint32_t service_type; + + unsigned addroffset:16 GNUNET_PACKED; unsigned char data[1]; }; diff --git a/src/vpn/gnunet-service-dns.c b/src/vpn/gnunet-service-dns.c index 4849749c0..9732f90c4 100644 --- a/src/vpn/gnunet-service-dns.c +++ b/src/vpn/gnunet-service-dns.c @@ -61,6 +61,8 @@ struct dns_query_id_state { unsigned local_ip:32; unsigned remote_ip:32; unsigned local_port:16; + char* name; + unsigned namelen:8; }; static struct dns_query_id_state query_states[65536]; /* This is < 1.5MiB */ @@ -108,20 +110,58 @@ void receive_dht(void *cls, const struct GNUNET_DNS_Record* rec = data; GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Got block of size %d, peer: %08x, desc: %08x\n", size, *((unsigned int*)&rec->peer), *((unsigned int*)&rec->service_descriptor)); - size_t len = sizeof(struct answer_packet) + size - 1; /* 1 for the unsigned char data[1]; */ + size_t len = sizeof(struct answer_packet) - 1 \ + + sizeof(struct dns_static) \ + + query_states[id].namelen \ + + sizeof(struct dns_query_line) \ + + 2 /* To hold the pointer to the name */ \ + + sizeof(struct dns_record_line) - 1 \ + + 16; + ; struct answer_packet_list* answer = GNUNET_malloc(len + 2*sizeof(struct answer_packet_list*)); + memset(answer, 0, len + 2*sizeof(struct answer_packet_list*)); + answer->pkt.hdr.type = htons(GNUNET_MESSAGE_TYPE_LOCAL_RESPONSE_DNS); answer->pkt.hdr.size = htons(len); answer->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_SERVICE; + GNUNET_CRYPTO_hash(&rec->peer, sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &answer->pkt.peer); + memcpy(&answer->pkt.service_descriptor, &rec->service_descriptor, sizeof(GNUNET_HashCode)); + memcpy(&answer->pkt.service_type, &rec->service_type, sizeof(answer->pkt.service_type)); + memcpy(&answer->pkt.ports, &rec->ports, sizeof(answer->pkt.ports)); + answer->pkt.from = query_states[id].remote_ip; answer->pkt.to = query_states[id].local_ip; answer->pkt.dst_port = query_states[id].local_port; - answer->pkt.id = id; + struct dns_pkt *dpkt = (struct dns_pkt*)answer->pkt.data; + + dpkt->s.id = id; + dpkt->s.aa = 1; + dpkt->s.qr = 1; + dpkt->s.ra = 1; + dpkt->s.qdcount = htons(1); + dpkt->s.ancount = htons(1); + + memcpy(dpkt->data, query_states[id].name, query_states[id].namelen); + GNUNET_free(query_states[id].name); + + + struct dns_query_line* dque = (struct dns_query_line*)(dpkt->data+(query_states[id].namelen)); + dque->type = htons(28); + dque->class = htons(1); + + char* anname = (char*)(dpkt->data+(query_states[id].namelen)+sizeof(struct dns_query_line)); + memcpy(anname, (char[]){0xc0, 0x0c}, 2); + + struct dns_record_line *drec_data = (struct dns_record_line*)(dpkt->data+(query_states[id].namelen)+sizeof(struct dns_query_line)+2); + drec_data->type = htons(28); /* AAAA */ + drec_data->class = htons(1); /* IN */ + drec_data->ttl = htonl(3600); /* FIXME: read from block */ + drec_data->data_len = htons(16); - memcpy(answer->pkt.data, data, size); + answer->pkt.addroffset = htons((unsigned short)((unsigned long)(&drec_data->data)-(unsigned long)(&answer->pkt))); GNUNET_CONTAINER_DLL_insert_after(mycls.head, mycls.tail, mycls.tail, answer); @@ -156,6 +196,9 @@ void receive_query(void *cls, struct GNUNET_SERVER_Client *client, const struct query_states[dns->s.id].local_ip = pkt->orig_from; query_states[dns->s.id].local_port = pkt->src_port; query_states[dns->s.id].remote_ip = pkt->orig_to; + query_states[dns->s.id].namelen = strlen((char*)dns->data) + 1; + query_states[dns->s.id].name = GNUNET_malloc(query_states[dns->s.id].namelen); + memcpy(query_states[dns->s.id].name, dns->data, query_states[dns->s.id].namelen); if (pdns->queries[0]->namelen > 9 && 0 == strncmp(pdns->queries[0]->name+(pdns->queries[0]->namelen - 9), ".gnunet.", 9)) { diff --git a/src/vpn/gnunet-vpn-packet.h b/src/vpn/gnunet-vpn-packet.h index 3df33a3f1..6f453d9fd 100644 --- a/src/vpn/gnunet-vpn-packet.h +++ b/src/vpn/gnunet-vpn-packet.h @@ -98,6 +98,11 @@ struct dns_pkt_parsed { struct dns_record** additional; }; +struct dns_query_line { + unsigned short type; + unsigned short class; +}; + struct dns_query { char* name; unsigned char namelen; @@ -105,6 +110,14 @@ struct dns_query { unsigned short qclass; }; +struct dns_record_line { + unsigned short type; + unsigned short class; + unsigned int ttl; + unsigned short data_len; + unsigned char data; +}; + struct dns_record { char* name; unsigned char namelen; -- 2.25.1