aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/vpn/gnunet-daemon-vpn.c53
-rw-r--r--src/vpn/gnunet-helper-hijack-dns.c9
-rw-r--r--src/vpn/gnunet-service-dns.c70
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 */
217void 217void
218new_ip6addr(char* buf, const GNUNET_HashCode *peer, const GNUNET_HashCode *service_desc) { /* {{{ */ 218new_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[]) {
47int main(int argc, char** argv) { 47int 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) {
77e4: 80e4:
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});
79e3: 82e3:
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});
81e2: 84e2:
@@ -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 {
104static void 104static void
105hijack(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tc) { 105hijack(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) {
121static void 129static void
122unhijack(unsigned short port) { 130unhijack(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 */