From: Philipp Tölke Date: Wed, 27 Jul 2011 07:28:20 +0000 (+0000) Subject: begin resolving A-records X-Git-Tag: initial-import-from-subversion-38251~17614 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=51074a30f34eee12cb388451a0fd94bfa78d3dd4;p=oweals%2Fgnunet.git begin resolving A-records --- 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)), const struct GNUNET_TRANSPORT_ATS_Information *atsi __attribute__((unused))) { GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1); - struct udp_pkt *pkt = (struct udp_pkt *) (desc + 1); + struct tcp_pkt *pkt = (struct tcp_pkt *) (desc + 1); struct remote_addr *s = (struct remote_addr *) desc; char *buf; size_t len; @@ -1036,11 +1036,11 @@ receive_tcp_remote (void *cls __attribute__((unused)), switch (s->addrlen) { case 4: - prepare_ipv4_packet (len, ntohs (pkt->len), pkt, 0x06, /* TCP */ + prepare_ipv4_packet (len, pkt_len, pkt, 0x06, /* TCP */ &s->addr, tunnel, state, (struct ip_pkt *) buf); break; case 16: - prepare_ipv6_packet (len, ntohs (pkt->len), pkt, 0x06, /* TCP */ + prepare_ipv6_packet (len, pkt_len, pkt, 0x06, /* TCP */ &s->addr, tunnel, state, (struct ip6_pkt *) buf); break; 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) GNUNET_assert (size >= ntohs (hdr->size)); memcpy (buf, hdr, ntohs (hdr->size)); size = ntohs(hdr->size); - GNUNET_free (cls); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sent!\n"); 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) /* save the handle */ GNUNET_MESH_tunnel_set_data(*tunnel, th); } + GNUNET_free (cls); return size; } @@ -331,7 +331,60 @@ new_ip6addr_remote (unsigned char *buf, unsigned char *addr, char addrlen) int local_length = 16 - ipv6prefix; - memcpy (buf + ipv6prefix, addr, GNUNET_MAX (addrlen, local_length)); + memcpy (buf + ipv6prefix, addr, GNUNET_MIN (addrlen, local_length)); +} +/*}}}*/ + +/** + * Create a new Address from an answer-packet + */ +void +new_ip4addr_remote (unsigned char *buf, unsigned char *addr, char addrlen) +{ /* {{{ */ + char *ipv4addr; + char *ipv4mask; + GNUNET_assert (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", + "IPV4ADDR", + &ipv4addr)); + GNUNET_assert (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", + "IPV4MASK", + &ipv4mask)); + uint32_t mask; + inet_pton (AF_INET, ipv4addr, buf); + int r = inet_pton (AF_INET, ipv4mask, &mask); + mask = htonl(mask); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "inet_pton: %d; %m; mask: %08x\n", r, mask); + + GNUNET_free (ipv4addr); + + int c; + + if (mask) + { + mask = (mask ^ (mask - 1)) >> 1; + for (c = 0; mask; c++) + { + mask >>= 1; + } + } + else + { + c = CHAR_BIT * sizeof(mask); + } + + c = 32-c; + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "The mask %s has %d leading 1s.\n", ipv4mask, c); + + GNUNET_free (ipv4mask); + + if (c % 8 == 0) + c = c / 8; + else + GNUNET_assert(0); + + memcpy (buf + c, addr, GNUNET_MIN (addrlen, c)); } /*}}}*/ @@ -463,7 +516,7 @@ process_answer(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tc) { list = GNUNET_malloc(htons(pkt->hdr.size) + 2*sizeof(struct answer_packet_list*)); memcpy(&list->pkt, pkt, htons(pkt->hdr.size)); } - else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_REMOTE) + else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_REMOTE_AAAA) { pkt->subtype = GNUNET_DNS_ANSWER_TYPE_IP; @@ -527,6 +580,60 @@ process_answer(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tc) { list = GNUNET_malloc(htons(pkt->hdr.size) + 2*sizeof(struct answer_packet_list*)); + memcpy(&list->pkt, pkt, htons(pkt->hdr.size)); + } + else if (pkt->subtype == GNUNET_DNS_ANSWER_TYPE_REMOTE_A) + { + pkt->subtype = GNUNET_DNS_ANSWER_TYPE_IP; + + GNUNET_HashCode key; + memset(&key, 0, sizeof(GNUNET_HashCode)); + + unsigned char* c = ((unsigned char*)pkt)+ntohs(pkt->addroffset); + new_ip4addr_remote(c, pkt->addr, pkt->addrsize); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "New mapping to %d.%d.%d.%d\n", + c[0], + c[1], + c[2], + c[3]); + unsigned char* k = (unsigned char*)&key; + /* + * Copy the newly generated ip-address to the key backwards (as only the first part is used in the hash-table) + */ + unsigned int i; + for (i = 0; i < 4; i++) + k[3-i] = c[i]; + + uint16_t namelen = strlen((char*)pkt->data+12)+1; + + struct map_entry* value = GNUNET_malloc(sizeof(struct map_entry) + namelen); + char* name = (char*)(value +1); + + value->namelen = namelen; + memcpy(name, pkt->data+12, namelen); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Setting addrlen to %d\n", pkt->addrsize); + value->addrlen = pkt->addrsize; + memcpy(&value->addr, &pkt->addr, pkt->addrsize); + memset(value->additional_ports, 0, 8192); + + memcpy(&value->hash, &key, sizeof(GNUNET_HashCode)); + + if (GNUNET_NO == + GNUNET_CONTAINER_multihashmap_contains (hashmap, &key)) + { + GNUNET_CONTAINER_multihashmap_put (hashmap, &key, value, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); + value->heap_node = GNUNET_CONTAINER_heap_insert (heap, value, + GNUNET_TIME_absolute_get ().abs_value); + if (GNUNET_CONTAINER_heap_get_size(heap) > max_mappings) + GNUNET_SCHEDULER_add_now(collect_mappings, NULL); + } + else + GNUNET_free(value); + + list = GNUNET_malloc(htons(pkt->hdr.size) + 2*sizeof(struct answer_packet_list*)); + memcpy(&list->pkt, pkt, htons(pkt->hdr.size)); } else 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 { GNUNET_DNS_ANSWER_TYPE_REV, /** - * Answers of this type contains an IP-Address but traffic to this IP should + * Answers of this type contains an IP6-Address but traffic to this IP should * be routed through the GNUNet. */ - GNUNET_DNS_ANSWER_TYPE_REMOTE + GNUNET_DNS_ANSWER_TYPE_REMOTE_AAAA, + + /** + * Answers of this type contains an IP4-Address but traffic to this IP should + * be routed through the GNUNet. + */ + GNUNET_DNS_ANSWER_TYPE_REMOTE_A }; struct 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) GNUNET_assert (size >= (*sz + sizeof (struct GNUNET_MessageHeader))); memcpy (hdr + 1, dns, *sz); - GNUNET_free (cls); if (NULL != GNUNET_MESH_tunnel_get_head(*tunnel)) { @@ -264,6 +263,9 @@ mesh_send_response (void *cls, size_t size, void *buf) /* save the handle */ GNUNET_MESH_tunnel_set_data(*tunnel, th); } + + GNUNET_free (cls); + return ntohs (hdr->size); } @@ -302,7 +304,6 @@ mesh_send (void *cls, size_t size, void *buf) GNUNET_MESH_tunnel_set_data(cls_->tunnel, th); } - GNUNET_free(cls); return size; } @@ -412,7 +413,11 @@ receive_mesh_answer (void *cls __attribute__((unused)), /* They sent us a packet we were not waiting for */ if (remote_pending[dns->s.id] == NULL || remote_pending[dns->s.id]->tunnel != tunnel) - return GNUNET_SYSERR; + return GNUNET_OK; + + GNUNET_free(remote_pending[dns->s.id]); + remote_pending[dns->s.id] = NULL; + if (query_states[dns->s.id].valid != GNUNET_YES) return GNUNET_SYSERR; query_states[dns->s.id].valid = GNUNET_NO; @@ -428,7 +433,6 @@ receive_mesh_answer (void *cls __attribute__((unused)), answer->pkt.hdr.type = htons (GNUNET_MESSAGE_TYPE_LOCAL_RESPONSE_DNS); answer->pkt.hdr.size = htons (len); - answer->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_REMOTE; struct dns_pkt_parsed* pdns = parse_dns_packet(dns); @@ -464,7 +468,16 @@ receive_mesh_answer (void *cls __attribute__((unused)), struct dns_query_line *dque = (struct dns_query_line *) (dpkt->data + (query_states[dns->s.id].namelen)); - dque->type = htons (28); /* AAAA */ + if (16 == answer->pkt.addrsize) + { + answer->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_REMOTE_AAAA; + dque->type = htons (28); /* AAAA */ + } + else + { + answer->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_REMOTE_A; + dque->type = htons (1); /* A */ + } dque->class = htons (1); /* IN */ char *anname =