diff options
author | Philipp Tölke <toelke@in.tum.de> | 2011-04-21 13:44:50 +0000 |
---|---|---|
committer | Philipp Tölke <toelke@in.tum.de> | 2011-04-21 13:44:50 +0000 |
commit | f885b85857ae5bd341d54cb7cce0aa5992767773 (patch) | |
tree | 78d34a13de778e78c7f6e0b9da4dbe26be4140b1 /src/vpn | |
parent | e03fb9e56eb3d9a9f0105db2d51ea9a52222819e (diff) | |
download | gnunet-f885b85857ae5bd341d54cb7cce0aa5992767773.tar.gz gnunet-f885b85857ae5bd341d54cb7cce0aa5992767773.zip |
make the service-dns ready to receive answers to queries sent over from remote peers
Diffstat (limited to 'src/vpn')
-rw-r--r-- | src/vpn/gnunet-service-dns-p.h | 23 | ||||
-rw-r--r-- | src/vpn/gnunet-service-dns.c | 127 |
2 files changed, 142 insertions, 8 deletions
diff --git a/src/vpn/gnunet-service-dns-p.h b/src/vpn/gnunet-service-dns-p.h index dd564f434..a25b7fd3f 100644 --- a/src/vpn/gnunet-service-dns-p.h +++ b/src/vpn/gnunet-service-dns-p.h | |||
@@ -44,7 +44,13 @@ enum GNUNET_DNS_ANSWER_Subtype { | |||
44 | * Answers of this type contain an incomplete dns-packet as answer to a | 44 | * Answers of this type contain an incomplete dns-packet as answer to a |
45 | * PTR-Query. The resolved name is not allocated. The addroffset points to it. | 45 | * PTR-Query. The resolved name is not allocated. The addroffset points to it. |
46 | */ | 46 | */ |
47 | GNUNET_DNS_ANSWER_TYPE_REV | 47 | GNUNET_DNS_ANSWER_TYPE_REV, |
48 | |||
49 | /** | ||
50 | * Answers of this type contains an IP-Address but traffic to this IP should | ||
51 | * be routed through the GNUNet. | ||
52 | */ | ||
53 | GNUNET_DNS_ANSWER_TYPE_REMOTE | ||
48 | }; | 54 | }; |
49 | 55 | ||
50 | struct GNUNET_vpn_service_descriptor { | 56 | struct GNUNET_vpn_service_descriptor { |
@@ -55,19 +61,30 @@ struct GNUNET_vpn_service_descriptor { | |||
55 | }; | 61 | }; |
56 | 62 | ||
57 | struct answer_packet { | 63 | struct answer_packet { |
64 | /* General data */ | ||
58 | struct GNUNET_MessageHeader hdr; | 65 | struct GNUNET_MessageHeader hdr; |
59 | enum GNUNET_DNS_ANSWER_Subtype subtype GNUNET_PACKED; | 66 | enum GNUNET_DNS_ANSWER_Subtype subtype GNUNET_PACKED; |
60 | 67 | ||
61 | unsigned from:32 GNUNET_PACKED; | 68 | unsigned from:32 GNUNET_PACKED; |
62 | unsigned to:32 GNUNET_PACKED; | 69 | unsigned to:32 GNUNET_PACKED; |
63 | unsigned dst_port:16 GNUNET_PACKED; | 70 | unsigned dst_port:16 GNUNET_PACKED; |
71 | /* -- */ | ||
64 | 72 | ||
65 | /* Only sensible when subtype == GNUNET_DNS_ANSWER_TYPE_SERVICE */ | 73 | /* Data for GNUNET_DNS_ANSWER_TYPE_SERVICE */ |
66 | struct GNUNET_vpn_service_descriptor service_descr; | 74 | struct GNUNET_vpn_service_descriptor service_descr; |
75 | /* -- */ | ||
67 | 76 | ||
77 | /* Data for GNUNET_DNS_ANSWER_TYPE_REV */ | ||
68 | /* The offsett in octets from the beginning of the struct to the field | 78 | /* The offsett in octets from the beginning of the struct to the field |
69 | * in data where the IP-Address has to go. */ | 79 | * in data where the IP-Address has to go. */ |
70 | unsigned addroffset:16 GNUNET_PACKED; | 80 | uint16_t addroffset GNUNET_PACKED; |
81 | /* -- */ | ||
82 | |||
83 | /* Data for GNUNET_DNS_ANSWER_TYPE_REMOTE */ | ||
84 | /* either 4 or 16 */ | ||
85 | char addrsize; | ||
86 | unsigned char addr[16]; | ||
87 | /* -- */ | ||
71 | 88 | ||
72 | unsigned char data[1]; | 89 | unsigned char data[1]; |
73 | }; | 90 | }; |
diff --git a/src/vpn/gnunet-service-dns.c b/src/vpn/gnunet-service-dns.c index d861e32b2..1daaf5778 100644 --- a/src/vpn/gnunet-service-dns.c +++ b/src/vpn/gnunet-service-dns.c | |||
@@ -255,6 +255,116 @@ send_mesh_query (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
255 | */ | 255 | */ |
256 | } | 256 | } |
257 | 257 | ||
258 | static int | ||
259 | receive_mesh_query (void *cls, | ||
260 | struct GNUNET_MESH_Tunnel *tunnel, | ||
261 | void **ctx, | ||
262 | const struct GNUNET_PeerIdentity *sender, | ||
263 | const struct GNUNET_MessageHeader *message, | ||
264 | const struct GNUNET_TRANSPORT_ATS_Information *atsi) | ||
265 | { | ||
266 | return GNUNET_SYSERR; | ||
267 | } | ||
268 | |||
269 | static int | ||
270 | receive_mesh_answer (void *cls, | ||
271 | struct GNUNET_MESH_Tunnel *tunnel, | ||
272 | void **ctx, | ||
273 | const struct GNUNET_PeerIdentity *sender, | ||
274 | const struct GNUNET_MessageHeader *message, | ||
275 | const struct GNUNET_TRANSPORT_ATS_Information *atsi) | ||
276 | { | ||
277 | /* TODo: size check */ | ||
278 | struct dns_pkt *dns = (struct dns_pkt *) (message + 1); | ||
279 | |||
280 | /* They sent us a packet we were not waiting for */ | ||
281 | if (remote_pending[dns->s.id] == NULL | ||
282 | || remote_pending[dns->s.id]->tunnel != tunnel) | ||
283 | return GNUNET_SYSERR; | ||
284 | if (query_states[dns->s.id].valid != GNUNET_YES) | ||
285 | return GNUNET_SYSERR; | ||
286 | query_states[dns->s.id].valid = GNUNET_NO; | ||
287 | |||
288 | size_t len = sizeof (struct answer_packet) - 1 + sizeof (struct dns_static) + query_states[dns->s.id].namelen + sizeof (struct dns_query_line) + 2 /* To hold the pointer (as defined in RFC1035) to the name */ | ||
289 | + sizeof (struct dns_record_line) - 1 + 16; /* To hold the IPv6-Address */ | ||
290 | |||
291 | struct answer_packet_list *answer = | ||
292 | GNUNET_malloc (len + 2 * sizeof (struct answer_packet_list *)); | ||
293 | memset (answer, 0, len + 2 * sizeof (struct answer_packet_list *)); | ||
294 | |||
295 | answer->pkt.hdr.type = htons (GNUNET_MESSAGE_TYPE_LOCAL_RESPONSE_DNS); | ||
296 | answer->pkt.hdr.size = htons (len); | ||
297 | answer->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_REMOTE; | ||
298 | |||
299 | struct dns_pkt_parsed* pdns = parse_dns_packet(dns); | ||
300 | |||
301 | if (ntohs(pdns->s.ancount) < 1) | ||
302 | { | ||
303 | free_parsed_dns_packet(pdns); | ||
304 | return GNUNET_OK; | ||
305 | } | ||
306 | |||
307 | answer->pkt.addrsize = pdns->answers[0]->data_len; | ||
308 | memcpy(answer->pkt.addr, pdns->answers[0]->data, ntohs(pdns->answers[0]->data_len)); | ||
309 | |||
310 | answer->pkt.from = query_states[dns->s.id].remote_ip; | ||
311 | |||
312 | answer->pkt.to = query_states[dns->s.id].local_ip; | ||
313 | answer->pkt.dst_port = query_states[dns->s.id].local_port; | ||
314 | |||
315 | struct dns_pkt *dpkt = (struct dns_pkt *) answer->pkt.data; | ||
316 | |||
317 | dpkt->s.id = dns->s.id; | ||
318 | dpkt->s.aa = 1; | ||
319 | dpkt->s.qr = 1; | ||
320 | dpkt->s.ra = 1; | ||
321 | dpkt->s.qdcount = htons (1); | ||
322 | dpkt->s.ancount = htons (1); | ||
323 | |||
324 | memcpy (dpkt->data, query_states[dns->s.id].name, | ||
325 | query_states[dns->s.id].namelen); | ||
326 | GNUNET_free (query_states[dns->s.id].name); | ||
327 | |||
328 | struct dns_query_line *dque = | ||
329 | (struct dns_query_line *) (dpkt->data + | ||
330 | (query_states[dns->s.id].namelen)); | ||
331 | dque->type = htons (28); /* AAAA */ | ||
332 | dque->class = htons (1); /* IN */ | ||
333 | |||
334 | char *anname = | ||
335 | (char *) (dpkt->data + (query_states[dns->s.id].namelen) + | ||
336 | sizeof (struct dns_query_line)); | ||
337 | memcpy (anname, "\xc0\x0c", 2); | ||
338 | |||
339 | struct dns_record_line *drec_data = | ||
340 | (struct dns_record_line *) (dpkt->data + | ||
341 | (query_states[dns->s.id].namelen) + | ||
342 | sizeof (struct dns_query_line) + 2); | ||
343 | drec_data->type = htons (28); /* AAAA */ | ||
344 | drec_data->class = htons (1); /* IN */ | ||
345 | |||
346 | drec_data->ttl = pdns->answers[0]->ttl; | ||
347 | drec_data->data_len = htons (16); | ||
348 | |||
349 | /* Calculate at which offset in the packet the IPv6-Address belongs, it is | ||
350 | * filled in by the daemon-vpn */ | ||
351 | answer->pkt.addroffset = | ||
352 | htons ((unsigned short) ((unsigned long) (&drec_data->data) - | ||
353 | (unsigned long) (&answer->pkt))); | ||
354 | |||
355 | GNUNET_CONTAINER_DLL_insert_after (head, tail, tail, answer); | ||
356 | |||
357 | GNUNET_SERVER_notify_transmit_ready (query_states[dns->s.id].client, | ||
358 | len, | ||
359 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
360 | &send_answer, | ||
361 | query_states[dns->s.id].client); | ||
362 | |||
363 | free_parsed_dns_packet(pdns); | ||
364 | return GNUNET_OK; | ||
365 | } | ||
366 | |||
367 | |||
258 | static void | 368 | static void |
259 | send_rev_query(void * cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { | 369 | send_rev_query(void * cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { |
260 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | 370 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) |
@@ -984,11 +1094,18 @@ run (void *cls, | |||
984 | {NULL, NULL, 0, 0} | 1094 | {NULL, NULL, 0, 0} |
985 | }; | 1095 | }; |
986 | 1096 | ||
987 | 1097 | static struct GNUNET_MESH_MessageHandler *mesh_handlers; | |
988 | const static struct GNUNET_MESH_MessageHandler mesh_handlers[] = { | 1098 | |
989 | //{receive_mesh_qery, GNUNET_MESSAGE_TYPE_REMOTE_QUERY_DNS, 0}, | 1099 | if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno(cfg_, "dns", "PROVIDE_EXIT")) |
990 | {NULL, 0, 0} | 1100 | mesh_handlers = (struct GNUNET_MESH_MessageHandler[]) { |
991 | }; | 1101 | {receive_mesh_query, GNUNET_MESSAGE_TYPE_REMOTE_QUERY_DNS, 0}, |
1102 | {NULL, 0, 0} | ||
1103 | }; | ||
1104 | else | ||
1105 | mesh_handlers = (struct GNUNET_MESH_MessageHandler[]) { | ||
1106 | {receive_mesh_answer, GNUNET_MESSAGE_TYPE_REMOTE_ANSWER_DNS, 0}, | ||
1107 | {NULL, 0, 0} | ||
1108 | }; | ||
992 | 1109 | ||
993 | const static GNUNET_MESH_ApplicationType apptypes[] = | 1110 | const static GNUNET_MESH_ApplicationType apptypes[] = |
994 | { GNUNET_APPLICATION_TYPE_INTERNET_RESOLVER, | 1111 | { GNUNET_APPLICATION_TYPE_INTERNET_RESOLVER, |