diff options
Diffstat (limited to 'src/vpn/gnunet-service-dns.c')
-rw-r--r-- | src/vpn/gnunet-service-dns.c | 138 |
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 | */ | ||
45 | static 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 | */ |
109 | static void | 105 | static void |
110 | hijack(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tc) { | 106 | hijack(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 | ||
169 | static void | ||
170 | send_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 | ||
435 | outfree: | 342 | out: |
436 | free_parsed_dns_packet(pdns); | 343 | free_parsed_dns_packet(pdns); |
437 | pdns = NULL; | 344 | pdns = NULL; |
438 | out: | ||
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 | */ |
582 | static void | 485 | static void |
583 | run (void *cls, | 486 | run (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 | } |