aboutsummaryrefslogtreecommitdiff
path: root/src/vpn/gnunet-service-dns.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vpn/gnunet-service-dns.c')
-rw-r--r--src/vpn/gnunet-service-dns.c138
1 files changed, 20 insertions, 118 deletions
diff --git a/src/vpn/gnunet-service-dns.c b/src/vpn/gnunet-service-dns.c
index 7997112c4..f8b1209e9 100644
--- a/src/vpn/gnunet-service-dns.c
+++ b/src/vpn/gnunet-service-dns.c
@@ -39,10 +39,6 @@
39#include "gnunet_crypto_lib.h" 39#include "gnunet_crypto_lib.h"
40#include "gnunet_signatures.h" 40#include "gnunet_signatures.h"
41 41
42/**
43 * The scheduler to use throughout the service
44 */
45static struct GNUNET_SCHEDULER_Handle *sched;
46 42
47/** 43/**
48 * The UDP-Socket through which DNS-Resolves will be sent if they are not to be 44 * The UDP-Socket through which DNS-Resolves will be sent if they are not to be
@@ -107,17 +103,17 @@ struct receive_dht_cls {
107 * Hijack all outgoing DNS-Traffic but for traffic leaving "our" port. 103 * Hijack all outgoing DNS-Traffic but for traffic leaving "our" port.
108 */ 104 */
109static void 105static void
110hijack(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tc) { 106hijack(unsigned short port) {
111 char port_s[6]; 107 char port_s[6];
112 108
113 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Hijacking, port is %d\n", dnsoutport); 109 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Hijacking, port is %d\n", port);
114 snprintf(port_s, 6, "%d", dnsoutport); 110 snprintf(port_s, 6, "%d", port);
115 GNUNET_OS_process_close (GNUNET_OS_start_process(NULL, 111 GNUNET_OS_start_process(NULL,
116 NULL, 112 NULL,
117 "gnunet-helper-hijack-dns", 113 "gnunet-helper-hijack-dns",
118 "gnunet-hijack-dns", 114 "gnunet-hijack-dns",
119 port_s, 115 port_s,
120 NULL)); 116 NULL);
121} 117}
122 118
123/** 119/**
@@ -166,81 +162,6 @@ send_answer(void* cls, size_t size, void* buf) {
166 return len; 162 return len;
167} 163}
168 164
169static void
170send_rev_query(void * cls, const struct GNUNET_SCHEDULER_TaskContext *tc) {
171 struct dns_pkt_parsed* pdns = (struct dns_pkt_parsed*) cls;
172
173 unsigned short id = pdns->s.id;
174
175 if (query_states[id].valid != GNUNET_YES) return;
176 query_states[id].valid = GNUNET_NO;
177
178 GNUNET_assert(query_states[id].namelen == 74);
179
180 size_t len = sizeof(struct answer_packet) - 1 \
181 + sizeof(struct dns_static) \
182 + 74 /* this is the length of a reverse ipv6-lookup */ \
183 + sizeof(struct dns_query_line) \
184 + 2 /* To hold the pointer (as defined in RFC1035) to the name */ \
185 + sizeof(struct dns_record_line) - 1 \
186 - 2 /* We do not know the lenght of the answer yet*/ \
187 - 2 /* No idea why... */ ;
188
189 struct answer_packet_list* answer = GNUNET_malloc(len + 2*sizeof(struct answer_packet_list*));
190 memset(answer, 0, len + 2*sizeof(struct answer_packet_list*));
191
192 answer->pkt.hdr.type = htons(GNUNET_MESSAGE_TYPE_LOCAL_RESPONSE_DNS);
193 answer->pkt.hdr.size = htons(len);
194 answer->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_REV;
195
196 answer->pkt.from = query_states[id].remote_ip;
197
198 answer->pkt.to = query_states[id].local_ip;
199 answer->pkt.dst_port = query_states[id].local_port;
200
201 struct dns_pkt *dpkt = (struct dns_pkt*)answer->pkt.data;
202
203 dpkt->s.id = id;
204 dpkt->s.aa = 1;
205 dpkt->s.qr = 1;
206 dpkt->s.ra = 1;
207 dpkt->s.qdcount = htons(1);
208 dpkt->s.ancount = htons(1);
209
210 memcpy(dpkt->data, query_states[id].name, query_states[id].namelen);
211 GNUNET_free(query_states[id].name);
212
213 struct dns_query_line* dque = (struct dns_query_line*)(dpkt->data+(query_states[id].namelen));
214 dque->type = htons(12); /* PTR */
215 dque->class = htons(1); /* IN */
216
217 char* anname = (char*)(dpkt->data+(query_states[id].namelen)+sizeof(struct dns_query_line));
218 memcpy(anname, (char[]){0xc0, 0x0c}, 2);
219
220 struct dns_record_line *drec_data = (struct dns_record_line*)(dpkt->data+(query_states[id].namelen)+sizeof(struct dns_query_line)+2);
221 drec_data->type = htons(12); /* AAAA */
222 drec_data->class = htons(1); /* IN */
223 drec_data->ttl = htonl(3600); /* FIXME: read from block */
224
225 /* Calculate at which offset in the packet the length of the name and the
226 * name, it is filled in by the daemon-vpn */
227 answer->pkt.addroffset = htons((unsigned short)((unsigned long)(&drec_data->data_len)-(unsigned long)(&answer->pkt)));
228
229 GNUNET_CONTAINER_DLL_insert_after(head, tail, tail, answer);
230
231 GNUNET_SERVER_notify_transmit_ready(query_states[id].client,
232 len,
233 GNUNET_TIME_UNIT_FOREVER_REL,
234 &send_answer,
235 query_states[id].client);
236
237 /*
238 * build
239 * complete dns-packet with empty name in the answer
240 * provide offsett of the name
241 */
242}
243
244/** 165/**
245 * Receive a block from the dht. 166 * Receive a block from the dht.
246 */ 167 */
@@ -315,6 +236,7 @@ receive_dht(void *cls,
315 memcpy(dpkt->data, query_states[id].name, query_states[id].namelen); 236 memcpy(dpkt->data, query_states[id].name, query_states[id].namelen);
316 GNUNET_free(query_states[id].name); 237 GNUNET_free(query_states[id].name);
317 238
239
318 struct dns_query_line* dque = (struct dns_query_line*)(dpkt->data+(query_states[id].namelen)); 240 struct dns_query_line* dque = (struct dns_query_line*)(dpkt->data+(query_states[id].namelen));
319 dque->type = htons(28); /* AAAA */ 241 dque->type = htons(28); /* AAAA */
320 dque->class = htons(1); /* IN */ 242 dque->class = htons(1); /* IN */
@@ -351,9 +273,7 @@ rehijack(void *cls,
351 struct GNUNET_SERVER_Client *client, 273 struct GNUNET_SERVER_Client *client,
352 const struct GNUNET_MessageHeader *message) { 274 const struct GNUNET_MessageHeader *message) {
353 unhijack(dnsoutport); 275 unhijack(dnsoutport);
354 GNUNET_SCHEDULER_add_delayed(sched, GNUNET_TIME_UNIT_SECONDS, hijack, NULL); 276 hijack(dnsoutport);
355
356 GNUNET_SERVER_receive_done(client, GNUNET_OK);
357} 277}
358 278
359/** 279/**
@@ -376,7 +296,6 @@ receive_query(void *cls,
376 query_states[dns->s.id].name = GNUNET_malloc(query_states[dns->s.id].namelen); 296 query_states[dns->s.id].name = GNUNET_malloc(query_states[dns->s.id].namelen);
377 memcpy(query_states[dns->s.id].name, dns->data, query_states[dns->s.id].namelen); 297 memcpy(query_states[dns->s.id].name, dns->data, query_states[dns->s.id].namelen);
378 298
379 /* The query is for a .gnunet-address */
380 if (pdns->queries[0]->namelen > 9 && 299 if (pdns->queries[0]->namelen > 9 &&
381 0 == strncmp(pdns->queries[0]->name+(pdns->queries[0]->namelen - 9), ".gnunet.", 9)) 300 0 == strncmp(pdns->queries[0]->name+(pdns->queries[0]->namelen - 9), ".gnunet.", 9))
382 { 301 {
@@ -404,18 +323,6 @@ receive_query(void *cls,
404 receive_dht, 323 receive_dht,
405 cls); 324 cls);
406 325
407 goto outfree;
408 }
409
410 /* The query is for a PTR of a previosly resolved virtual IP */
411 if (htons(pdns->queries[0]->qtype) == 12 &&
412 pdns->queries[0]->namelen > 19 &&
413 0 == strncmp(pdns->queries[0]->name+(pdns->queries[0]->namelen - 19), ".4.3.2.1.ip6.arpa.", 19))
414 {
415 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Reverse-Query for .gnunet!\n");
416
417 GNUNET_SCHEDULER_add_now(sched, send_rev_query, pdns);
418
419 goto out; 326 goto out;
420 } 327 }
421 328
@@ -432,10 +339,9 @@ receive_query(void *cls,
432 (struct sockaddr*) &dest, 339 (struct sockaddr*) &dest,
433 sizeof dest); 340 sizeof dest);
434 341
435outfree: 342out:
436 free_parsed_dns_packet(pdns); 343 free_parsed_dns_packet(pdns);
437 pdns = NULL; 344 pdns = NULL;
438out:
439 GNUNET_SERVER_receive_done(client, GNUNET_OK); 345 GNUNET_SERVER_receive_done(client, GNUNET_OK);
440} 346}
441 347
@@ -485,8 +391,7 @@ read_response (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) {
485 query_states[dns->s.id].client); 391 query_states[dns->s.id].client);
486 } 392 }
487 393
488 GNUNET_SCHEDULER_add_read_net(sched, 394 GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL,
489 GNUNET_TIME_UNIT_FOREVER_REL,
490 dnsout, 395 dnsout,
491 &read_response, 396 &read_response,
492 NULL); 397 NULL);
@@ -567,21 +472,18 @@ publish_name (void *cls,
567 NULL, 472 NULL,
568 NULL); 473 NULL);
569 474
570 GNUNET_SCHEDULER_add_delayed (sched, 475 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_HOURS,
571 GNUNET_TIME_UNIT_HOURS,
572 publish_name, 476 publish_name,
573 NULL); 477 NULL);
574} 478}
575 479
576/** 480/**
577 * @param cls closure 481 * @param cls closure
578 * @param sched scheduler to use
579 * @param server the initialized server 482 * @param server the initialized server
580 * @param cfg configuration to use 483 * @param cfg configuration to use
581 */ 484 */
582static void 485static void
583run (void *cls, 486run (void *cls,
584 struct GNUNET_SCHEDULER_Handle *sched_,
585 struct GNUNET_SERVER_Handle *server, 487 struct GNUNET_SERVER_Handle *server,
586 const struct GNUNET_CONFIGURATION_Handle *cfg_) 488 const struct GNUNET_CONFIGURATION_Handle *cfg_)
587{ 489{
@@ -593,14 +495,13 @@ run (void *cls,
593 }; 495 };
594 496
595 cfg = cfg_; 497 cfg = cfg_;
596 sched = sched_;
597 498
598 unsigned int i; 499 unsigned int i;
599 for (i = 0; i < 65536; i++) { 500 for (i = 0; i < 65536; i++) {
600 query_states[i].valid = GNUNET_NO; 501 query_states[i].valid = GNUNET_NO;
601 } 502 }
602 503
603 dht = GNUNET_DHT_connect(sched, cfg, 1024); 504 dht = GNUNET_DHT_connect(cfg, 1024);
604 505
605 struct sockaddr_in addr; 506 struct sockaddr_in addr;
606 507
@@ -626,13 +527,14 @@ run (void *cls,
626 527
627 dnsoutport = htons(addr.sin_port); 528 dnsoutport = htons(addr.sin_port);
628 529
629 GNUNET_SCHEDULER_add_now (sched, publish_name, NULL); 530 hijack(htons(addr.sin_port));
531
532 GNUNET_SCHEDULER_add_now (publish_name, NULL);
630 533
631 GNUNET_SCHEDULER_add_read_net(sched, GNUNET_TIME_UNIT_FOREVER_REL, dnsout, &read_response, NULL); 534 GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, dnsout, &read_response, NULL);
632 535
633 GNUNET_SERVER_add_handlers (server, handlers); 536 GNUNET_SERVER_add_handlers (server, handlers);
634 GNUNET_SCHEDULER_add_delayed (sched, 537 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
635 GNUNET_TIME_UNIT_FOREVER_REL,
636 &cleanup_task, 538 &cleanup_task,
637 cls); 539 cls);
638} 540}