aboutsummaryrefslogtreecommitdiff
path: root/src/vpn
diff options
context:
space:
mode:
authorPhilipp Tölke <toelke@in.tum.de>2011-07-27 07:28:20 +0000
committerPhilipp Tölke <toelke@in.tum.de>2011-07-27 07:28:20 +0000
commit51074a30f34eee12cb388451a0fd94bfa78d3dd4 (patch)
tree65d83b65034041a8c4c2be69a88a21f8131fac85 /src/vpn
parent2bafcee957905f901c23507d9542e5e2d75a17d9 (diff)
downloadgnunet-51074a30f34eee12cb388451a0fd94bfa78d3dd4.tar.gz
gnunet-51074a30f34eee12cb388451a0fd94bfa78d3dd4.zip
begin resolving A-records
Diffstat (limited to 'src/vpn')
-rw-r--r--src/vpn/gnunet-daemon-exit.c6
-rw-r--r--src/vpn/gnunet-daemon-vpn.c113
-rw-r--r--src/vpn/gnunet-service-dns-p.h10
-rw-r--r--src/vpn/gnunet-service-dns.c23
4 files changed, 139 insertions, 13 deletions
diff --git a/src/vpn/gnunet-daemon-exit.c b/src/vpn/gnunet-daemon-exit.c
index cf9f58be3..631873ced 100644
--- a/src/vpn/gnunet-daemon-exit.c
+++ b/src/vpn/gnunet-daemon-exit.c
@@ -1013,7 +1013,7 @@ receive_tcp_remote (void *cls __attribute__((unused)),
1013 const struct GNUNET_TRANSPORT_ATS_Information *atsi __attribute__((unused))) 1013 const struct GNUNET_TRANSPORT_ATS_Information *atsi __attribute__((unused)))
1014{ 1014{
1015 GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1); 1015 GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1);
1016 struct udp_pkt *pkt = (struct udp_pkt *) (desc + 1); 1016 struct tcp_pkt *pkt = (struct tcp_pkt *) (desc + 1);
1017 struct remote_addr *s = (struct remote_addr *) desc; 1017 struct remote_addr *s = (struct remote_addr *) desc;
1018 char *buf; 1018 char *buf;
1019 size_t len; 1019 size_t len;
@@ -1036,11 +1036,11 @@ receive_tcp_remote (void *cls __attribute__((unused)),
1036 switch (s->addrlen) 1036 switch (s->addrlen)
1037 { 1037 {
1038 case 4: 1038 case 4:
1039 prepare_ipv4_packet (len, ntohs (pkt->len), pkt, 0x06, /* TCP */ 1039 prepare_ipv4_packet (len, pkt_len, pkt, 0x06, /* TCP */
1040 &s->addr, tunnel, state, (struct ip_pkt *) buf); 1040 &s->addr, tunnel, state, (struct ip_pkt *) buf);
1041 break; 1041 break;
1042 case 16: 1042 case 16:
1043 prepare_ipv6_packet (len, ntohs (pkt->len), pkt, 0x06, /* TCP */ 1043 prepare_ipv6_packet (len, pkt_len, pkt, 0x06, /* TCP */
1044 &s->addr, tunnel, state, (struct ip6_pkt *) buf); 1044 &s->addr, tunnel, state, (struct ip6_pkt *) buf);
1045 break; 1045 break;
1046 default: 1046 default:
diff --git a/src/vpn/gnunet-daemon-vpn.c b/src/vpn/gnunet-daemon-vpn.c
index ece7b554a..257ab22b8 100644
--- a/src/vpn/gnunet-daemon-vpn.c
+++ b/src/vpn/gnunet-daemon-vpn.c
@@ -200,7 +200,6 @@ send_pkt_to_peer_notify_callback (void *cls, size_t size, void *buf)
200 GNUNET_assert (size >= ntohs (hdr->size)); 200 GNUNET_assert (size >= ntohs (hdr->size));
201 memcpy (buf, hdr, ntohs (hdr->size)); 201 memcpy (buf, hdr, ntohs (hdr->size));
202 size = ntohs(hdr->size); 202 size = ntohs(hdr->size);
203 GNUNET_free (cls);
204 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sent!\n"); 203 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sent!\n");
205 204
206 if (NULL != GNUNET_MESH_tunnel_get_head(*tunnel)) 205 if (NULL != GNUNET_MESH_tunnel_get_head(*tunnel))
@@ -225,6 +224,7 @@ send_pkt_to_peer_notify_callback (void *cls, size_t size, void *buf)
225 /* save the handle */ 224 /* save the handle */
226 GNUNET_MESH_tunnel_set_data(*tunnel, th); 225 GNUNET_MESH_tunnel_set_data(*tunnel, th);
227 } 226 }
227 GNUNET_free (cls);
228 228
229 return size; 229 return size;
230} 230}
@@ -331,7 +331,60 @@ new_ip6addr_remote (unsigned char *buf, unsigned char *addr, char addrlen)
331 331
332 int local_length = 16 - ipv6prefix; 332 int local_length = 16 - ipv6prefix;
333 333
334 memcpy (buf + ipv6prefix, addr, GNUNET_MAX (addrlen, local_length)); 334 memcpy (buf + ipv6prefix, addr, GNUNET_MIN (addrlen, local_length));
335}
336/*}}}*/
337
338/**
339 * Create a new Address from an answer-packet
340 */
341void
342new_ip4addr_remote (unsigned char *buf, unsigned char *addr, char addrlen)
343{ /* {{{ */
344 char *ipv4addr;
345 char *ipv4mask;
346 GNUNET_assert (GNUNET_OK ==
347 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn",
348 "IPV4ADDR",
349 &ipv4addr));
350 GNUNET_assert (GNUNET_OK ==
351 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn",
352 "IPV4MASK",
353 &ipv4mask));
354 uint32_t mask;
355 inet_pton (AF_INET, ipv4addr, buf);
356 int r = inet_pton (AF_INET, ipv4mask, &mask);
357 mask = htonl(mask);
358 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "inet_pton: %d; %m; mask: %08x\n", r, mask);
359
360 GNUNET_free (ipv4addr);
361
362 int c;
363
364 if (mask)
365 {
366 mask = (mask ^ (mask - 1)) >> 1;
367 for (c = 0; mask; c++)
368 {
369 mask >>= 1;
370 }
371 }
372 else
373 {
374 c = CHAR_BIT * sizeof(mask);
375 }
376
377 c = 32-c;
378 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "The mask %s has %d leading 1s.\n", ipv4mask, c);
379
380 GNUNET_free (ipv4mask);
381
382 if (c % 8 == 0)
383 c = c / 8;
384 else
385 GNUNET_assert(0);
386
387 memcpy (buf + c, addr, GNUNET_MIN (addrlen, c));
335} 388}
336/*}}}*/ 389/*}}}*/
337 390
@@ -463,7 +516,7 @@ process_answer(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tc) {
463 list = GNUNET_malloc(htons(pkt->hdr.size) + 2*sizeof(struct answer_packet_list*)); 516 list = GNUNET_malloc(htons(pkt->hdr.size) + 2*sizeof(struct answer_packet_list*));
464 memcpy(&list->pkt, pkt, htons(pkt->hdr.size)); 517 memcpy(&list->pkt, pkt, htons(pkt->hdr.size));
465 } 518 }
466 else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_REMOTE) 519 else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_REMOTE_AAAA)
467 { 520 {
468 pkt->subtype = GNUNET_DNS_ANSWER_TYPE_IP; 521 pkt->subtype = GNUNET_DNS_ANSWER_TYPE_IP;
469 522
@@ -529,6 +582,60 @@ process_answer(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tc) {
529 582
530 memcpy(&list->pkt, pkt, htons(pkt->hdr.size)); 583 memcpy(&list->pkt, pkt, htons(pkt->hdr.size));
531 } 584 }
585 else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_REMOTE_A)
586 {
587 pkt->subtype = GNUNET_DNS_ANSWER_TYPE_IP;
588
589 GNUNET_HashCode key;
590 memset(&key, 0, sizeof(GNUNET_HashCode));
591
592 unsigned char* c = ((unsigned char*)pkt)+ntohs(pkt->addroffset);
593 new_ip4addr_remote(c, pkt->addr, pkt->addrsize);
594 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "New mapping to %d.%d.%d.%d\n",
595 c[0],
596 c[1],
597 c[2],
598 c[3]);
599 unsigned char* k = (unsigned char*)&key;
600 /*
601 * Copy the newly generated ip-address to the key backwards (as only the first part is used in the hash-table)
602 */
603 unsigned int i;
604 for (i = 0; i < 4; i++)
605 k[3-i] = c[i];
606
607 uint16_t namelen = strlen((char*)pkt->data+12)+1;
608
609 struct map_entry* value = GNUNET_malloc(sizeof(struct map_entry) + namelen);
610 char* name = (char*)(value +1);
611
612 value->namelen = namelen;
613 memcpy(name, pkt->data+12, namelen);
614
615 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Setting addrlen to %d\n", pkt->addrsize);
616 value->addrlen = pkt->addrsize;
617 memcpy(&value->addr, &pkt->addr, pkt->addrsize);
618 memset(value->additional_ports, 0, 8192);
619
620 memcpy(&value->hash, &key, sizeof(GNUNET_HashCode));
621
622 if (GNUNET_NO ==
623 GNUNET_CONTAINER_multihashmap_contains (hashmap, &key))
624 {
625 GNUNET_CONTAINER_multihashmap_put (hashmap, &key, value,
626 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
627 value->heap_node = GNUNET_CONTAINER_heap_insert (heap, value,
628 GNUNET_TIME_absolute_get ().abs_value);
629 if (GNUNET_CONTAINER_heap_get_size(heap) > max_mappings)
630 GNUNET_SCHEDULER_add_now(collect_mappings, NULL);
631 }
632 else
633 GNUNET_free(value);
634
635 list = GNUNET_malloc(htons(pkt->hdr.size) + 2*sizeof(struct answer_packet_list*));
636
637 memcpy(&list->pkt, pkt, htons(pkt->hdr.size));
638 }
532 else 639 else
533 { 640 {
534 GNUNET_break(0); 641 GNUNET_break(0);
diff --git a/src/vpn/gnunet-service-dns-p.h b/src/vpn/gnunet-service-dns-p.h
index a25b7fd3f..6ffc2e58b 100644
--- a/src/vpn/gnunet-service-dns-p.h
+++ b/src/vpn/gnunet-service-dns-p.h
@@ -47,10 +47,16 @@ enum GNUNET_DNS_ANSWER_Subtype {
47 GNUNET_DNS_ANSWER_TYPE_REV, 47 GNUNET_DNS_ANSWER_TYPE_REV,
48 48
49 /** 49 /**
50 * Answers of this type contains an IP-Address but traffic to this IP should 50 * Answers of this type contains an IP6-Address but traffic to this IP should
51 * be routed through the GNUNet. 51 * be routed through the GNUNet.
52 */ 52 */
53 GNUNET_DNS_ANSWER_TYPE_REMOTE 53 GNUNET_DNS_ANSWER_TYPE_REMOTE_AAAA,
54
55 /**
56 * Answers of this type contains an IP4-Address but traffic to this IP should
57 * be routed through the GNUNet.
58 */
59 GNUNET_DNS_ANSWER_TYPE_REMOTE_A
54}; 60};
55 61
56struct GNUNET_vpn_service_descriptor { 62struct GNUNET_vpn_service_descriptor {
diff --git a/src/vpn/gnunet-service-dns.c b/src/vpn/gnunet-service-dns.c
index e876940c8..0c2304097 100644
--- a/src/vpn/gnunet-service-dns.c
+++ b/src/vpn/gnunet-service-dns.c
@@ -241,7 +241,6 @@ mesh_send_response (void *cls, size_t size, void *buf)
241 GNUNET_assert (size >= (*sz + sizeof (struct GNUNET_MessageHeader))); 241 GNUNET_assert (size >= (*sz + sizeof (struct GNUNET_MessageHeader)));
242 242
243 memcpy (hdr + 1, dns, *sz); 243 memcpy (hdr + 1, dns, *sz);
244 GNUNET_free (cls);
245 244
246 if (NULL != GNUNET_MESH_tunnel_get_head(*tunnel)) 245 if (NULL != GNUNET_MESH_tunnel_get_head(*tunnel))
247 { 246 {
@@ -264,6 +263,9 @@ mesh_send_response (void *cls, size_t size, void *buf)
264 /* save the handle */ 263 /* save the handle */
265 GNUNET_MESH_tunnel_set_data(*tunnel, th); 264 GNUNET_MESH_tunnel_set_data(*tunnel, th);
266 } 265 }
266
267 GNUNET_free (cls);
268
267 return ntohs (hdr->size); 269 return ntohs (hdr->size);
268} 270}
269 271
@@ -302,7 +304,6 @@ mesh_send (void *cls, size_t size, void *buf)
302 GNUNET_MESH_tunnel_set_data(cls_->tunnel, th); 304 GNUNET_MESH_tunnel_set_data(cls_->tunnel, th);
303 } 305 }
304 306
305 GNUNET_free(cls);
306 return size; 307 return size;
307} 308}
308 309
@@ -412,7 +413,11 @@ receive_mesh_answer (void *cls __attribute__((unused)),
412 /* They sent us a packet we were not waiting for */ 413 /* They sent us a packet we were not waiting for */
413 if (remote_pending[dns->s.id] == NULL 414 if (remote_pending[dns->s.id] == NULL
414 || remote_pending[dns->s.id]->tunnel != tunnel) 415 || remote_pending[dns->s.id]->tunnel != tunnel)
415 return GNUNET_SYSERR; 416 return GNUNET_OK;
417
418 GNUNET_free(remote_pending[dns->s.id]);
419 remote_pending[dns->s.id] = NULL;
420
416 if (query_states[dns->s.id].valid != GNUNET_YES) 421 if (query_states[dns->s.id].valid != GNUNET_YES)
417 return GNUNET_SYSERR; 422 return GNUNET_SYSERR;
418 query_states[dns->s.id].valid = GNUNET_NO; 423 query_states[dns->s.id].valid = GNUNET_NO;
@@ -428,7 +433,6 @@ receive_mesh_answer (void *cls __attribute__((unused)),
428 433
429 answer->pkt.hdr.type = htons (GNUNET_MESSAGE_TYPE_LOCAL_RESPONSE_DNS); 434 answer->pkt.hdr.type = htons (GNUNET_MESSAGE_TYPE_LOCAL_RESPONSE_DNS);
430 answer->pkt.hdr.size = htons (len); 435 answer->pkt.hdr.size = htons (len);
431 answer->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_REMOTE;
432 436
433 struct dns_pkt_parsed* pdns = parse_dns_packet(dns); 437 struct dns_pkt_parsed* pdns = parse_dns_packet(dns);
434 438
@@ -464,7 +468,16 @@ receive_mesh_answer (void *cls __attribute__((unused)),
464 struct dns_query_line *dque = 468 struct dns_query_line *dque =
465 (struct dns_query_line *) (dpkt->data + 469 (struct dns_query_line *) (dpkt->data +
466 (query_states[dns->s.id].namelen)); 470 (query_states[dns->s.id].namelen));
467 dque->type = htons (28); /* AAAA */ 471 if (16 == answer->pkt.addrsize)
472 {
473 answer->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_REMOTE_AAAA;
474 dque->type = htons (28); /* AAAA */
475 }
476 else
477 {
478 answer->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_REMOTE_A;
479 dque->type = htons (1); /* A */
480 }
468 dque->class = htons (1); /* IN */ 481 dque->class = htons (1); /* IN */
469 482
470 char *anname = 483 char *anname =