diff options
-rw-r--r-- | src/vpn/gnunet-daemon-vpn.c | 53 | ||||
-rw-r--r-- | src/vpn/gnunet-helper-hijack-dns.c | 9 | ||||
-rw-r--r-- | src/vpn/gnunet-service-dns.c | 70 |
3 files changed, 102 insertions, 30 deletions
diff --git a/src/vpn/gnunet-daemon-vpn.c b/src/vpn/gnunet-daemon-vpn.c index 1213dd9f1..0c3c137fa 100644 --- a/src/vpn/gnunet-daemon-vpn.c +++ b/src/vpn/gnunet-daemon-vpn.c | |||
@@ -215,10 +215,27 @@ send_udp_to_peer (void *cls, | |||
215 | * Create a new Address from an answer-packet | 215 | * Create a new Address from an answer-packet |
216 | */ | 216 | */ |
217 | void | 217 | void |
218 | new_ip6addr(char* buf, const GNUNET_HashCode *peer, const GNUNET_HashCode *service_desc) { /* {{{ */ | 218 | new_ip6addr(unsigned char* buf, const GNUNET_HashCode *peer, const GNUNET_HashCode *service_desc) { /* {{{ */ |
219 | memcpy(buf+14, (int[]){htons(0x3412)}, 2); | 219 | char* ipv6addr; |
220 | memcpy(buf+8, service_desc, 6); | 220 | unsigned long long ipv6prefix; |
221 | memcpy(buf, peer, 8); | 221 | GNUNET_assert(GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "vpn", "IPV6ADDR", &ipv6addr)); |
222 | GNUNET_assert(GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(cfg, "vpn", "IPV6PREFIX", &ipv6prefix)); | ||
223 | GNUNET_assert(ipv6prefix < 127); | ||
224 | ipv6prefix = (ipv6prefix + 7)/8; | ||
225 | |||
226 | inet_pton (AF_INET6, ipv6addr, buf); | ||
227 | GNUNET_free(ipv6addr); | ||
228 | |||
229 | int peer_length = 16 - ipv6prefix - 6; | ||
230 | if (peer_length <= 0) | ||
231 | peer_length = 0; | ||
232 | |||
233 | int service_length = 16 - ipv6prefix - peer_length; | ||
234 | if (service_length <= 0) | ||
235 | service_length = 0; | ||
236 | |||
237 | memcpy(buf+ipv6prefix, service_desc, service_length); | ||
238 | memcpy(buf+ipv6prefix+service_length, peer, peer_length); | ||
222 | } | 239 | } |
223 | /*}}}*/ | 240 | /*}}}*/ |
224 | 241 | ||
@@ -246,7 +263,16 @@ process_answer(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tc) { | |||
246 | 263 | ||
247 | GNUNET_HashCode key; | 264 | GNUNET_HashCode key; |
248 | memset(&key, 0, sizeof(GNUNET_HashCode)); | 265 | memset(&key, 0, sizeof(GNUNET_HashCode)); |
249 | new_ip6addr((char*)&key, &pkt->service_descr.peer, &pkt->service_descr.service_descriptor); | 266 | |
267 | unsigned char* c = ((unsigned char*)pkt)+ntohs(pkt->addroffset); | ||
268 | unsigned char* k = (unsigned char*)&key; | ||
269 | new_ip6addr(c, &pkt->service_descr.peer, &pkt->service_descr.service_descriptor); | ||
270 | /* | ||
271 | * Copy the newly generated ip-address to the key backwarts (as only the first part is hashed) | ||
272 | */ | ||
273 | unsigned int i; | ||
274 | for (i = 0; i < 16; i++) | ||
275 | k[15-i] = c[i]; | ||
250 | 276 | ||
251 | uint16_t namelen = strlen((char*)pkt->data+12)+1; | 277 | uint16_t namelen = strlen((char*)pkt->data+12)+1; |
252 | 278 | ||
@@ -268,14 +294,6 @@ process_answer(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tc) { | |||
268 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Could not store to hashmap\n"); | 294 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Could not store to hashmap\n"); |
269 | } | 295 | } |
270 | 296 | ||
271 | /* | ||
272 | * Copy the newly generated backward ip-address to the packet | ||
273 | */ | ||
274 | char* c = ((char*)pkt)+ntohs(pkt->addroffset); | ||
275 | char* k = (char*)&key; | ||
276 | unsigned int i; | ||
277 | for (i = 0; i < 16; i++) | ||
278 | c[15-i] = k[i]; | ||
279 | 297 | ||
280 | list = GNUNET_malloc(htons(pkt->hdr.size) + 2*sizeof(struct answer_packet_list*)); | 298 | list = GNUNET_malloc(htons(pkt->hdr.size) + 2*sizeof(struct answer_packet_list*)); |
281 | 299 | ||
@@ -374,17 +392,16 @@ receive_udp_back (void *cls, struct GNUNET_MESH_Tunnel* tunnel, | |||
374 | { | 392 | { |
375 | GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1); | 393 | GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1); |
376 | struct udp_pkt *pkt = (struct udp_pkt *) (desc + 1); | 394 | struct udp_pkt *pkt = (struct udp_pkt *) (desc + 1); |
377 | char addr[16]; | ||
378 | const struct GNUNET_PeerIdentity* other = GNUNET_MESH_get_peer(tunnel); | 395 | const struct GNUNET_PeerIdentity* other = GNUNET_MESH_get_peer(tunnel); |
379 | 396 | ||
380 | new_ip6addr(addr, &other->hashPubKey, desc); | ||
381 | |||
382 | size_t size = sizeof(struct ip6_udp) + ntohs(pkt->len) - 1 - sizeof(struct udp_pkt); | 397 | size_t size = sizeof(struct ip6_udp) + ntohs(pkt->len) - 1 - sizeof(struct udp_pkt); |
383 | 398 | ||
384 | struct ip6_udp* pkt6 = alloca(size); | 399 | struct ip6_udp* pkt6 = alloca(size); |
385 | 400 | ||
386 | GNUNET_assert(pkt6 != NULL); | 401 | GNUNET_assert(pkt6 != NULL); |
387 | 402 | ||
403 | new_ip6addr(pkt6->ip6_hdr.sadr, &other->hashPubKey, desc); | ||
404 | |||
388 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Relaying calc:%d gnu:%d udp:%d bytes!\n", size, ntohs(message->size), ntohs(pkt->len)); | 405 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Relaying calc:%d gnu:%d udp:%d bytes!\n", size, ntohs(message->size), ntohs(pkt->len)); |
389 | 406 | ||
390 | pkt6->shdr.type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER); | 407 | pkt6->shdr.type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER); |
@@ -401,10 +418,6 @@ receive_udp_back (void *cls, struct GNUNET_MESH_Tunnel* tunnel, | |||
401 | pkt6->ip6_hdr.nxthdr = 0x11; | 418 | pkt6->ip6_hdr.nxthdr = 0x11; |
402 | pkt6->ip6_hdr.hoplmt = 0xff; | 419 | pkt6->ip6_hdr.hoplmt = 0xff; |
403 | 420 | ||
404 | unsigned int i; | ||
405 | for (i = 0; i < 16; i++) | ||
406 | pkt6->ip6_hdr.sadr[15-i] = addr[i]; | ||
407 | |||
408 | { | 421 | { |
409 | char* ipv6addr; | 422 | char* ipv6addr; |
410 | GNUNET_assert(GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "vpn", "IPV6ADDR", &ipv6addr)); | 423 | GNUNET_assert(GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "vpn", "IPV6ADDR", &ipv6addr)); |
diff --git a/src/vpn/gnunet-helper-hijack-dns.c b/src/vpn/gnunet-helper-hijack-dns.c index 7a41b27d2..ee7ae1873 100644 --- a/src/vpn/gnunet-helper-hijack-dns.c +++ b/src/vpn/gnunet-helper-hijack-dns.c | |||
@@ -47,14 +47,17 @@ int fork_and_exec(char* file, char* cmd[]) { | |||
47 | int main(int argc, char** argv) { | 47 | int main(int argc, char** argv) { |
48 | int delete = 0; | 48 | int delete = 0; |
49 | int port = 0; | 49 | int port = 0; |
50 | if (argc < 2) return GNUNET_SYSERR; | 50 | char* virt_dns; |
51 | if (argc < 3) return GNUNET_SYSERR; | ||
51 | 52 | ||
52 | if (strncmp(argv[1], "-d", 2) == 0) { | 53 | if (strncmp(argv[1], "-d", 2) == 0) { |
53 | if (argc < 3) return GNUNET_SYSERR; | 54 | if (argc < 3) return GNUNET_SYSERR; |
54 | delete = 1; | 55 | delete = 1; |
55 | port = atoi(argv[2]); | 56 | port = atoi(argv[2]); |
57 | virt_dns = argv[3]; | ||
56 | } else { | 58 | } else { |
57 | port = atoi(argv[1]); | 59 | port = atoi(argv[1]); |
60 | virt_dns = argv[2]; | ||
58 | } | 61 | } |
59 | 62 | ||
60 | if (port == 0) return GNUNET_SYSERR; | 63 | if (port == 0) return GNUNET_SYSERR; |
@@ -75,7 +78,7 @@ int main(int argc, char** argv) { | |||
75 | int r; | 78 | int r; |
76 | if (delete) { | 79 | if (delete) { |
77 | e4: | 80 | e4: |
78 | r = fork_and_exec("/sbin/ip", (char*[]){"ip", "route", "del", "default", "via", "10.10.10.2","table","2", NULL}); | 81 | r = fork_and_exec("/sbin/ip", (char*[]){"ip", "route", "del", "default", "via", virt_dns,"table","2", NULL}); |
79 | e3: | 82 | e3: |
80 | r = fork_and_exec("/sbin/ip", (char*[]){"ip", "rule", "del", "fwmark", "3", "table","2", NULL}); | 83 | r = fork_and_exec("/sbin/ip", (char*[]){"ip", "rule", "del", "fwmark", "3", "table","2", NULL}); |
81 | e2: | 84 | e2: |
@@ -90,7 +93,7 @@ e1: | |||
90 | if (!r) goto e2; | 93 | if (!r) goto e2; |
91 | r = fork_and_exec("/sbin/ip", (char*[]){"ip", "rule", "add", "fwmark", "3", "table","2", NULL}); | 94 | r = fork_and_exec("/sbin/ip", (char*[]){"ip", "rule", "add", "fwmark", "3", "table","2", NULL}); |
92 | if (!r) goto e3; | 95 | if (!r) goto e3; |
93 | r = fork_and_exec("/sbin/ip", (char*[]){"ip", "route", "add", "default", "via", "10.10.10.2","table","2", NULL}); | 96 | r = fork_and_exec("/sbin/ip", (char*[]){"ip", "route", "add", "default", "via", virt_dns, "table","2", NULL}); |
94 | if (!r) goto e4; | 97 | if (!r) goto e4; |
95 | } | 98 | } |
96 | if (r) return GNUNET_YES; | 99 | if (r) return GNUNET_YES; |
diff --git a/src/vpn/gnunet-service-dns.c b/src/vpn/gnunet-service-dns.c index b8488d3e1..12a85cdd1 100644 --- a/src/vpn/gnunet-service-dns.c +++ b/src/vpn/gnunet-service-dns.c | |||
@@ -104,6 +104,13 @@ struct receive_dht_cls { | |||
104 | static void | 104 | static void |
105 | hijack(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tc) { | 105 | hijack(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tc) { |
106 | char port_s[6]; | 106 | char port_s[6]; |
107 | char* virt_dns; | ||
108 | |||
109 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg, "vpn", "VIRTDNS", &virt_dns)) | ||
110 | { | ||
111 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "No entry 'VIRTDNS' in configuration!\n"); | ||
112 | exit(1); | ||
113 | } | ||
107 | 114 | ||
108 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Hijacking, port is %d\n", dnsoutport); | 115 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Hijacking, port is %d\n", dnsoutport); |
109 | snprintf(port_s, 6, "%d", dnsoutport); | 116 | snprintf(port_s, 6, "%d", dnsoutport); |
@@ -112,6 +119,7 @@ hijack(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tc) { | |||
112 | "gnunet-helper-hijack-dns", | 119 | "gnunet-helper-hijack-dns", |
113 | "gnunet-hijack-dns", | 120 | "gnunet-hijack-dns", |
114 | port_s, | 121 | port_s, |
122 | virt_dns, | ||
115 | NULL)); | 123 | NULL)); |
116 | } | 124 | } |
117 | 125 | ||
@@ -121,6 +129,13 @@ hijack(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tc) { | |||
121 | static void | 129 | static void |
122 | unhijack(unsigned short port) { | 130 | unhijack(unsigned short port) { |
123 | char port_s[6]; | 131 | char port_s[6]; |
132 | char* virt_dns; | ||
133 | |||
134 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg, "vpn", "VIRTDNS", &virt_dns)) | ||
135 | { | ||
136 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "No entry 'VIRTDNS' in configuration!\n"); | ||
137 | exit(1); | ||
138 | } | ||
124 | 139 | ||
125 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "unHijacking, port is %d\n", port); | 140 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "unHijacking, port is %d\n", port); |
126 | snprintf(port_s, 6, "%d", port); | 141 | snprintf(port_s, 6, "%d", port); |
@@ -130,6 +145,7 @@ unhijack(unsigned short port) { | |||
130 | "gnunet-hijack-dns", | 145 | "gnunet-hijack-dns", |
131 | "-d", | 146 | "-d", |
132 | port_s, | 147 | port_s, |
148 | virt_dns, | ||
133 | NULL); | 149 | NULL); |
134 | } | 150 | } |
135 | 151 | ||
@@ -403,16 +419,56 @@ receive_query(void *cls, | |||
403 | goto outfree; | 419 | goto outfree; |
404 | } | 420 | } |
405 | 421 | ||
422 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Query for '%s'; namelen=%d\n", pdns->queries[0]->name, pdns->queries[0]->namelen); | ||
406 | /* The query is for a PTR of a previosly resolved virtual IP */ | 423 | /* The query is for a PTR of a previosly resolved virtual IP */ |
407 | if (htons(pdns->queries[0]->qtype) == 12 && | 424 | if (htons(pdns->queries[0]->qtype) == 12 && |
408 | pdns->queries[0]->namelen > 19 && | 425 | 74 == pdns->queries[0]->namelen) |
409 | 0 == strncmp(pdns->queries[0]->name+(pdns->queries[0]->namelen - 19), ".4.3.2.1.ip6.arpa.", 19)) | ||
410 | { | 426 | { |
411 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Reverse-Query for .gnunet!\n"); | 427 | char* ipv6addr; |
412 | 428 | char ipv6[16]; | |
413 | GNUNET_SCHEDULER_add_now(send_rev_query, pdns); | 429 | char ipv6rev[74] = "X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.ip6.arpa."; |
414 | 430 | unsigned int i; | |
415 | goto out; | 431 | unsigned long long ipv6prefix; |
432 | unsigned int comparelen; | ||
433 | |||
434 | GNUNET_assert(GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "vpn", "IPV6ADDR", &ipv6addr)); | ||
435 | inet_pton (AF_INET6, ipv6addr, ipv6); | ||
436 | GNUNET_free(ipv6addr); | ||
437 | |||
438 | GNUNET_assert(GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(cfg, "vpn", "IPV6PREFIX", &ipv6prefix)); | ||
439 | GNUNET_assert(ipv6prefix < 127); | ||
440 | ipv6prefix = (ipv6prefix + 7)/8; | ||
441 | |||
442 | for (i = ipv6prefix; i < 16; i++) | ||
443 | ipv6[i] = 0; | ||
444 | |||
445 | for (i = 0; i < 16; i++) | ||
446 | { | ||
447 | unsigned char c1 = ipv6[i] >> 4; | ||
448 | unsigned char c2 = ipv6[i] & 0xf; | ||
449 | |||
450 | if (c1 <= 9) | ||
451 | ipv6rev[62-(4*i)] = c1 + '0'; | ||
452 | else | ||
453 | ipv6rev[62-(4*i)] = c1 + 87; /* 87 is the difference between 'a' and 10 */ | ||
454 | |||
455 | if (c2 <= 9) | ||
456 | ipv6rev[62-((4*i)+2)] = c2 + '0'; | ||
457 | else | ||
458 | ipv6rev[62-((4*i)+2)] = c2 + 87; | ||
459 | } | ||
460 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "My network is %s'.\n", ipv6rev); | ||
461 | comparelen = 10 + 4*ipv6prefix; | ||
462 | if(0 == strncmp(pdns->queries[0]->name+(pdns->queries[0]->namelen - comparelen), | ||
463 | ipv6rev + (74 - comparelen), | ||
464 | comparelen)) | ||
465 | { | ||
466 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Reverse-Query for .gnunet!\n"); | ||
467 | |||
468 | GNUNET_SCHEDULER_add_now(send_rev_query, pdns); | ||
469 | |||
470 | goto out; | ||
471 | } | ||
416 | } | 472 | } |
417 | 473 | ||
418 | /* The query should be sent to the network */ | 474 | /* The query should be sent to the network */ |