aboutsummaryrefslogtreecommitdiff
path: root/src/dns/gnunet-service-dns.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dns/gnunet-service-dns.c')
-rw-r--r--src/dns/gnunet-service-dns.c1251
1 files changed, 632 insertions, 619 deletions
diff --git a/src/dns/gnunet-service-dns.c b/src/dns/gnunet-service-dns.c
index 9c4f1f490..9a2293b2d 100644
--- a/src/dns/gnunet-service-dns.c
+++ b/src/dns/gnunet-service-dns.c
@@ -11,12 +11,12 @@
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU Affero General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 17
18 SPDX-License-Identifier: AGPL3.0-or-later 18 SPDX-License-Identifier: AGPL3.0-or-later
19*/ 19 */
20 20
21/** 21/**
22 * @file dns/gnunet-service-dns.c 22 * @file dns/gnunet-service-dns.c
@@ -59,14 +59,13 @@
59 * Generic logging shorthand 59 * Generic logging shorthand
60 */ 60 */
61#define LOG(kind, ...) \ 61#define LOG(kind, ...) \
62 GNUNET_log_from (kind, "dns", __VA_ARGS__); 62 GNUNET_log_from(kind, "dns", __VA_ARGS__);
63 63
64 64
65/** 65/**
66 * Phases each request goes through. 66 * Phases each request goes through.
67 */ 67 */
68enum RequestPhase 68enum RequestPhase {
69{
70 /** 69 /**
71 * Request has just been received. 70 * Request has just been received.
72 */ 71 */
@@ -112,16 +111,15 @@ enum RequestPhase
112/** 111/**
113 * Entry we keep for each client. 112 * Entry we keep for each client.
114 */ 113 */
115struct ClientRecord 114struct ClientRecord {
116{
117 /** 115 /**
118 * Kept in doubly-linked list. 116 * Kept in doubly-linked list.
119 */ 117 */
120 struct ClientRecord *next; 118 struct ClientRecord *next;
121 119
122 /** 120 /**
123 * Kept in doubly-linked list. 121 * Kept in doubly-linked list.
124 */ 122 */
125 struct ClientRecord *prev; 123 struct ClientRecord *prev;
126 124
127 /** 125 /**
@@ -138,16 +136,13 @@ struct ClientRecord
138 * Flags for the client. 136 * Flags for the client.
139 */ 137 */
140 enum GNUNET_DNS_Flags flags; 138 enum GNUNET_DNS_Flags flags;
141
142}; 139};
143 140
144 141
145/** 142/**
146 * Entry we keep for each active request. 143 * Entry we keep for each active request.
147 */ 144 */
148struct RequestRecord 145struct RequestRecord {
149{
150
151 /** 146 /**
152 * List of clients that still need to see this request (each entry 147 * List of clients that still need to see this request (each entry
153 * is set to NULL when the client is done). 148 * is set to NULL when the client is done).
@@ -197,7 +192,6 @@ struct RequestRecord
197 * In which phase this this request? 192 * In which phase this this request?
198 */ 193 */
199 enum RequestPhase phase; 194 enum RequestPhase phase;
200
201}; 195};
202 196
203 197
@@ -258,14 +252,14 @@ static struct GNUNET_DNSSTUB_Context *dnsstub;
258 * @param rr request to clean up 252 * @param rr request to clean up
259 */ 253 */
260static void 254static void
261cleanup_rr (struct RequestRecord *rr) 255cleanup_rr(struct RequestRecord *rr)
262{ 256{
263 GNUNET_free_non_null (rr->payload); 257 GNUNET_free_non_null(rr->payload);
264 rr->payload = NULL; 258 rr->payload = NULL;
265 rr->payload_length = 0; 259 rr->payload_length = 0;
266 GNUNET_array_grow (rr->client_wait_list, 260 GNUNET_array_grow(rr->client_wait_list,
267 rr->client_wait_list_length, 261 rr->client_wait_list_length,
268 0); 262 0);
269} 263}
270 264
271 265
@@ -275,28 +269,28 @@ cleanup_rr (struct RequestRecord *rr)
275 * @param cls unused 269 * @param cls unused
276 */ 270 */
277static void 271static void
278cleanup_task (void *cls GNUNET_UNUSED) 272cleanup_task(void *cls GNUNET_UNUSED)
279{ 273{
280 if (NULL != hijacker) 274 if (NULL != hijacker)
281 { 275 {
282 GNUNET_HELPER_stop (hijacker, GNUNET_NO); 276 GNUNET_HELPER_stop(hijacker, GNUNET_NO);
283 hijacker = NULL; 277 hijacker = NULL;
284 } 278 }
285 for (unsigned int i=0;i<8;i++) 279 for (unsigned int i = 0; i < 8; i++)
286 GNUNET_free_non_null (helper_argv[i]); 280 GNUNET_free_non_null(helper_argv[i]);
287 for (unsigned int i=0;i<=UINT16_MAX;i++) 281 for (unsigned int i = 0; i <= UINT16_MAX; i++)
288 cleanup_rr (&requests[i]); 282 cleanup_rr(&requests[i]);
289 if (NULL != stats) 283 if (NULL != stats)
290 { 284 {
291 GNUNET_STATISTICS_destroy (stats, 285 GNUNET_STATISTICS_destroy(stats,
292 GNUNET_NO); 286 GNUNET_NO);
293 stats = NULL; 287 stats = NULL;
294 } 288 }
295 if (NULL != dnsstub) 289 if (NULL != dnsstub)
296 { 290 {
297 GNUNET_DNSSTUB_stop (dnsstub); 291 GNUNET_DNSSTUB_stop(dnsstub);
298 dnsstub = NULL; 292 dnsstub = NULL;
299 } 293 }
300} 294}
301 295
302 296
@@ -306,54 +300,56 @@ cleanup_task (void *cls GNUNET_UNUSED)
306 * @param rr request send to the network or just clean up. 300 * @param rr request send to the network or just clean up.
307 */ 301 */
308static void 302static void
309request_done (struct RequestRecord *rr) 303request_done(struct RequestRecord *rr)
310{ 304{
311 struct GNUNET_MessageHeader *hdr; 305 struct GNUNET_MessageHeader *hdr;
312 size_t reply_len; 306 size_t reply_len;
313 uint16_t source_port; 307 uint16_t source_port;
314 uint16_t destination_port; 308 uint16_t destination_port;
315 309
316 GNUNET_array_grow (rr->client_wait_list, 310 GNUNET_array_grow(rr->client_wait_list,
317 rr->client_wait_list_length, 311 rr->client_wait_list_length,
318 0); 312 0);
319 if (RP_RESPONSE_MONITOR != rr->phase) 313 if (RP_RESPONSE_MONITOR != rr->phase)
320 { 314 {
321 /* no response, drop */ 315 /* no response, drop */
322 LOG (GNUNET_ERROR_TYPE_DEBUG, 316 LOG(GNUNET_ERROR_TYPE_DEBUG,
323 "Got no response for request %llu, dropping\n", 317 "Got no response for request %llu, dropping\n",
324 (unsigned long long) rr->request_id); 318 (unsigned long long)rr->request_id);
325 cleanup_rr (rr); 319 cleanup_rr(rr);
326 return; 320 return;
327 } 321 }
328 322
329 LOG (GNUNET_ERROR_TYPE_DEBUG, 323 LOG(GNUNET_ERROR_TYPE_DEBUG,
330 "Transmitting response for request %llu\n", 324 "Transmitting response for request %llu\n",
331 (unsigned long long) rr->request_id); 325 (unsigned long long)rr->request_id);
332 /* send response via hijacker */ 326 /* send response via hijacker */
333 reply_len = sizeof (struct GNUNET_MessageHeader); 327 reply_len = sizeof(struct GNUNET_MessageHeader);
334 reply_len += sizeof (struct GNUNET_TUN_Layer2PacketHeader); 328 reply_len += sizeof(struct GNUNET_TUN_Layer2PacketHeader);
335 switch (rr->src_addr.ss_family) 329 switch (rr->src_addr.ss_family)
336 { 330 {
337 case AF_INET: 331 case AF_INET:
338 reply_len += sizeof (struct GNUNET_TUN_IPv4Header); 332 reply_len += sizeof(struct GNUNET_TUN_IPv4Header);
339 break; 333 break;
340 case AF_INET6: 334
341 reply_len += sizeof (struct GNUNET_TUN_IPv6Header); 335 case AF_INET6:
342 break; 336 reply_len += sizeof(struct GNUNET_TUN_IPv6Header);
343 default: 337 break;
344 GNUNET_break (0); 338
345 cleanup_rr (rr); 339 default:
346 return; 340 GNUNET_break(0);
347 } 341 cleanup_rr(rr);
348 reply_len += sizeof (struct GNUNET_TUN_UdpHeader); 342 return;
343 }
344 reply_len += sizeof(struct GNUNET_TUN_UdpHeader);
349 reply_len += rr->payload_length; 345 reply_len += rr->payload_length;
350 if (reply_len >= GNUNET_MAX_MESSAGE_SIZE) 346 if (reply_len >= GNUNET_MAX_MESSAGE_SIZE)
351 { 347 {
352 /* response too big, drop */ 348 /* response too big, drop */
353 GNUNET_break (0); /* how can this be? */ 349 GNUNET_break(0); /* how can this be? */
354 cleanup_rr(rr); 350 cleanup_rr(rr);
355 return; 351 return;
356 } 352 }
357 { 353 {
358 char buf[reply_len] GNUNET_ALIGN; 354 char buf[reply_len] GNUNET_ALIGN;
359 size_t off; 355 size_t off;
@@ -361,68 +357,70 @@ request_done (struct RequestRecord *rr)
361 struct GNUNET_TUN_IPv6Header ip6; 357 struct GNUNET_TUN_IPv6Header ip6;
362 358
363 /* first, GNUnet message header */ 359 /* first, GNUnet message header */
364 hdr = (struct GNUNET_MessageHeader*) buf; 360 hdr = (struct GNUNET_MessageHeader*)buf;
365 hdr->type = htons (GNUNET_MESSAGE_TYPE_DNS_HELPER); 361 hdr->type = htons(GNUNET_MESSAGE_TYPE_DNS_HELPER);
366 hdr->size = htons ((uint16_t) reply_len); 362 hdr->size = htons((uint16_t)reply_len);
367 off = sizeof (struct GNUNET_MessageHeader); 363 off = sizeof(struct GNUNET_MessageHeader);
368 364
369 /* first, TUN header */ 365 /* first, TUN header */
370 { 366 {
371 struct GNUNET_TUN_Layer2PacketHeader tun; 367 struct GNUNET_TUN_Layer2PacketHeader tun;
372 368
373 tun.flags = htons (0); 369 tun.flags = htons(0);
374 if (rr->src_addr.ss_family == AF_INET) 370 if (rr->src_addr.ss_family == AF_INET)
375 tun.proto = htons (ETH_P_IPV4); 371 tun.proto = htons(ETH_P_IPV4);
376 else 372 else
377 tun.proto = htons (ETH_P_IPV6); 373 tun.proto = htons(ETH_P_IPV6);
378 GNUNET_memcpy (&buf[off], 374 GNUNET_memcpy(&buf[off],
379 &tun, 375 &tun,
380 sizeof (struct GNUNET_TUN_Layer2PacketHeader)); 376 sizeof(struct GNUNET_TUN_Layer2PacketHeader));
381 off += sizeof (struct GNUNET_TUN_Layer2PacketHeader); 377 off += sizeof(struct GNUNET_TUN_Layer2PacketHeader);
382 } 378 }
383 379
384 /* now IP header */ 380 /* now IP header */
385 switch (rr->src_addr.ss_family) 381 switch (rr->src_addr.ss_family)
386 {
387 case AF_INET:
388 { 382 {
389 struct sockaddr_in *src = (struct sockaddr_in *) &rr->src_addr; 383 case AF_INET:
390 struct sockaddr_in *dst = (struct sockaddr_in *) &rr->dst_addr; 384 {
391 385 struct sockaddr_in *src = (struct sockaddr_in *)&rr->src_addr;
392 source_port = dst->sin_port; 386 struct sockaddr_in *dst = (struct sockaddr_in *)&rr->dst_addr;
393 destination_port = src->sin_port; 387
394 GNUNET_TUN_initialize_ipv4_header (&ip4, 388 source_port = dst->sin_port;
395 IPPROTO_UDP, 389 destination_port = src->sin_port;
396 reply_len - off - sizeof (struct GNUNET_TUN_IPv4Header), 390 GNUNET_TUN_initialize_ipv4_header(&ip4,
397 &dst->sin_addr, 391 IPPROTO_UDP,
398 &src->sin_addr); 392 reply_len - off - sizeof(struct GNUNET_TUN_IPv4Header),
399 GNUNET_memcpy (&buf[off], 393 &dst->sin_addr,
400 &ip4, 394 &src->sin_addr);
401 sizeof (ip4)); 395 GNUNET_memcpy(&buf[off],
402 off += sizeof (ip4); 396 &ip4,
397 sizeof(ip4));
398 off += sizeof(ip4);
403 } 399 }
404 break; 400 break;
405 case AF_INET6: 401
402 case AF_INET6:
406 { 403 {
407 struct sockaddr_in6 *src = (struct sockaddr_in6 *) &rr->src_addr; 404 struct sockaddr_in6 *src = (struct sockaddr_in6 *)&rr->src_addr;
408 struct sockaddr_in6 *dst = (struct sockaddr_in6 *) &rr->dst_addr; 405 struct sockaddr_in6 *dst = (struct sockaddr_in6 *)&rr->dst_addr;
409 406
410 source_port = dst->sin6_port; 407 source_port = dst->sin6_port;
411 destination_port = src->sin6_port; 408 destination_port = src->sin6_port;
412 GNUNET_TUN_initialize_ipv6_header (&ip6, 409 GNUNET_TUN_initialize_ipv6_header(&ip6,
413 IPPROTO_UDP, 410 IPPROTO_UDP,
414 reply_len - off - sizeof (struct GNUNET_TUN_IPv6Header), 411 reply_len - off - sizeof(struct GNUNET_TUN_IPv6Header),
415 &dst->sin6_addr, 412 &dst->sin6_addr,
416 &src->sin6_addr); 413 &src->sin6_addr);
417 GNUNET_memcpy (&buf[off], 414 GNUNET_memcpy(&buf[off],
418 &ip6, 415 &ip6,
419 sizeof (ip6)); 416 sizeof(ip6));
420 off += sizeof (ip6); 417 off += sizeof(ip6);
421 } 418 }
422 break; 419 break;
423 default: 420
424 GNUNET_assert (0); 421 default:
425 } 422 GNUNET_assert(0);
423 }
426 424
427 /* now UDP header */ 425 /* now UDP header */
428 { 426 {
@@ -430,40 +428,40 @@ request_done (struct RequestRecord *rr)
430 428
431 udp.source_port = source_port; 429 udp.source_port = source_port;
432 udp.destination_port = destination_port; 430 udp.destination_port = destination_port;
433 udp.len = htons (reply_len - off); 431 udp.len = htons(reply_len - off);
434 if (AF_INET == rr->src_addr.ss_family) 432 if (AF_INET == rr->src_addr.ss_family)
435 GNUNET_TUN_calculate_udp4_checksum (&ip4, 433 GNUNET_TUN_calculate_udp4_checksum(&ip4,
436 &udp, 434 &udp,
437 rr->payload, 435 rr->payload,
438 rr->payload_length); 436 rr->payload_length);
439 else 437 else
440 GNUNET_TUN_calculate_udp6_checksum (&ip6, 438 GNUNET_TUN_calculate_udp6_checksum(&ip6,
441 &udp, 439 &udp,
442 rr->payload, 440 rr->payload,
443 rr->payload_length); 441 rr->payload_length);
444 GNUNET_memcpy (&buf[off], 442 GNUNET_memcpy(&buf[off],
445 &udp, 443 &udp,
446 sizeof (udp)); 444 sizeof(udp));
447 off += sizeof (udp); 445 off += sizeof(udp);
448 } 446 }
449 447
450 /* now DNS payload */ 448 /* now DNS payload */
451 { 449 {
452 GNUNET_memcpy (&buf[off], rr->payload, rr->payload_length); 450 GNUNET_memcpy(&buf[off], rr->payload, rr->payload_length);
453 off += rr->payload_length; 451 off += rr->payload_length;
454 } 452 }
455 /* final checks & sending */ 453 /* final checks & sending */
456 GNUNET_assert (off == reply_len); 454 GNUNET_assert(off == reply_len);
457 (void) GNUNET_HELPER_send (hijacker, 455 (void)GNUNET_HELPER_send(hijacker,
458 hdr, 456 hdr,
459 GNUNET_YES, 457 GNUNET_YES,
460 NULL, NULL); 458 NULL, NULL);
461 GNUNET_STATISTICS_update (stats, 459 GNUNET_STATISTICS_update(stats,
462 gettext_noop ("# DNS requests answered via TUN interface"), 460 gettext_noop("# DNS requests answered via TUN interface"),
463 1, GNUNET_NO); 461 1, GNUNET_NO);
464 } 462 }
465 /* clean up, we're done */ 463 /* clean up, we're done */
466 cleanup_rr (rr); 464 cleanup_rr(rr);
467} 465}
468 466
469 467
@@ -475,31 +473,31 @@ request_done (struct RequestRecord *rr)
475 * @param cr client to send the response to 473 * @param cr client to send the response to
476 */ 474 */
477static void 475static void
478send_request_to_client (struct RequestRecord *rr, 476send_request_to_client(struct RequestRecord *rr,
479 struct ClientRecord *cr) 477 struct ClientRecord *cr)
480{ 478{
481 struct GNUNET_MQ_Envelope *env; 479 struct GNUNET_MQ_Envelope *env;
482 struct GNUNET_DNS_Request *req; 480 struct GNUNET_DNS_Request *req;
483 481
484 if (sizeof (struct GNUNET_DNS_Request) + rr->payload_length >= GNUNET_MAX_MESSAGE_SIZE) 482 if (sizeof(struct GNUNET_DNS_Request) + rr->payload_length >= GNUNET_MAX_MESSAGE_SIZE)
485 { 483 {
486 GNUNET_break (0); 484 GNUNET_break(0);
487 cleanup_rr (rr); 485 cleanup_rr(rr);
488 return; 486 return;
489 } 487 }
490 LOG (GNUNET_ERROR_TYPE_DEBUG, 488 LOG(GNUNET_ERROR_TYPE_DEBUG,
491 "Sending information about request %llu to local client\n", 489 "Sending information about request %llu to local client\n",
492 (unsigned long long) rr->request_id); 490 (unsigned long long)rr->request_id);
493 env = GNUNET_MQ_msg_extra (req, 491 env = GNUNET_MQ_msg_extra(req,
494 rr->payload_length, 492 rr->payload_length,
495 GNUNET_MESSAGE_TYPE_DNS_CLIENT_REQUEST); 493 GNUNET_MESSAGE_TYPE_DNS_CLIENT_REQUEST);
496 req->reserved = htonl (0); 494 req->reserved = htonl(0);
497 req->request_id = rr->request_id; 495 req->request_id = rr->request_id;
498 GNUNET_memcpy (&req[1], 496 GNUNET_memcpy(&req[1],
499 rr->payload, 497 rr->payload,
500 rr->payload_length); 498 rr->payload_length);
501 GNUNET_MQ_send (cr->mq, 499 GNUNET_MQ_send(cr->mq,
502 env); 500 env);
503} 501}
504 502
505 503
@@ -512,9 +510,9 @@ send_request_to_client (struct RequestRecord *rr,
512 * @param r number of bytes in dns 510 * @param r number of bytes in dns
513 */ 511 */
514static void 512static void
515process_dns_result (void *cls, 513process_dns_result(void *cls,
516 const struct GNUNET_TUN_DnsHeader *dns, 514 const struct GNUNET_TUN_DnsHeader *dns,
517 size_t r); 515 size_t r);
518 516
519 517
520/** 518/**
@@ -524,129 +522,138 @@ process_dns_result (void *cls,
524 * @param rr request to process further 522 * @param rr request to process further
525 */ 523 */
526static void 524static void
527next_phase (struct RequestRecord *rr) 525next_phase(struct RequestRecord *rr)
528{ 526{
529 struct ClientRecord *cr; 527 struct ClientRecord *cr;
530 int nz; 528 int nz;
531 529
532 if (rr->phase == RP_DROP) 530 if (rr->phase == RP_DROP)
533 { 531 {
534 cleanup_rr (rr); 532 cleanup_rr(rr);
535 return; 533 return;
536 } 534 }
537 nz = -1; 535 nz = -1;
538 for (unsigned int j=0;j<rr->client_wait_list_length;j++) 536 for (unsigned int j = 0; j < rr->client_wait_list_length; j++)
539 {
540 if (NULL != rr->client_wait_list[j])
541 { 537 {
542 nz = (int) j; 538 if (NULL != rr->client_wait_list[j])
543 break; 539 {
540 nz = (int)j;
541 break;
542 }
544 } 543 }
545 }
546 if (-1 != nz) 544 if (-1 != nz)
547 {
548 send_request_to_client (rr,
549 rr->client_wait_list[nz]);
550 return;
551 }
552 /* done with current phase, advance! */
553 LOG (GNUNET_ERROR_TYPE_DEBUG,
554 "Request %llu now in phase %d\n",
555 rr->request_id,
556 rr->phase);
557 switch (rr->phase)
558 {
559 case RP_INIT:
560 rr->phase = RP_REQUEST_MONITOR;
561 for (cr = clients_head; NULL != cr; cr = cr->next)
562 { 545 {
563 if (0 != (cr->flags & GNUNET_DNS_FLAG_REQUEST_MONITOR)) 546 send_request_to_client(rr,
564 GNUNET_array_append (rr->client_wait_list, 547 rr->client_wait_list[nz]);
565 rr->client_wait_list_length, 548 return;
566 cr);
567 } 549 }
568 next_phase (rr); 550 /* done with current phase, advance! */
569 return; 551 LOG(GNUNET_ERROR_TYPE_DEBUG,
570 case RP_REQUEST_MONITOR: 552 "Request %llu now in phase %d\n",
571 rr->phase = RP_QUERY; 553 rr->request_id,
572 for (cr = clients_head; NULL != cr; cr = cr->next) 554 rr->phase);
555 switch (rr->phase)
573 { 556 {
574 if (0 != (cr->flags & GNUNET_DNS_FLAG_PRE_RESOLUTION)) 557 case RP_INIT:
575 GNUNET_array_append (rr->client_wait_list, 558 rr->phase = RP_REQUEST_MONITOR;
576 rr->client_wait_list_length, 559 for (cr = clients_head; NULL != cr; cr = cr->next)
577 cr); 560 {
578 } 561 if (0 != (cr->flags & GNUNET_DNS_FLAG_REQUEST_MONITOR))
579 next_phase (rr); 562 GNUNET_array_append(rr->client_wait_list,
580 return; 563 rr->client_wait_list_length,
581 case RP_QUERY: 564 cr);
565 }
566 next_phase(rr);
567 return;
568
569 case RP_REQUEST_MONITOR:
570 rr->phase = RP_QUERY;
571 for (cr = clients_head; NULL != cr; cr = cr->next)
572 {
573 if (0 != (cr->flags & GNUNET_DNS_FLAG_PRE_RESOLUTION))
574 GNUNET_array_append(rr->client_wait_list,
575 rr->client_wait_list_length,
576 cr);
577 }
578 next_phase(rr);
579 return;
580
581 case RP_QUERY:
582#if 0 582#if 0
583 /* TODO: optionally, use this to forward DNS requests to the 583 /* TODO: optionally, use this to forward DNS requests to the
584 *original* DNS server instead of the one we have configured... 584 * original* DNS server instead of the one we have configured...
585 (but then we need to create a fresh dnsstub for each request 585 (but then we need to create a fresh dnsstub for each request
586 *and* manage the timeout) */ 586 * and* manage the timeout) */
587 switch (rr->dst_addr.ss_family) 587 switch (rr->dst_addr.ss_family)
588 { 588 {
589 case AF_INET: 589 case AF_INET:
590 salen = sizeof (struct sockaddr_in); 590 salen = sizeof(struct sockaddr_in);
591 sa = (const struct sockaddr *) &rr->dst_addr; 591 sa = (const struct sockaddr *)&rr->dst_addr;
592 break;
593
594 case AF_INET6:
595 salen = sizeof(struct sockaddr_in6);
596 sa = (const struct sockaddr *)&rr->dst_addr;
597 break;
598
599 default:
600 GNUNET_assert(0);
601 }
602#endif
603 rr->phase = RP_INTERNET_DNS;
604 rr->rs = GNUNET_DNSSTUB_resolve(dnsstub,
605 rr->payload,
606 rr->payload_length,
607 &process_dns_result,
608 NULL);
609 if (NULL == rr->rs)
610 {
611 GNUNET_STATISTICS_update(stats,
612 gettext_noop("# DNS exit failed (failed to open socket)"),
613 1,
614 GNUNET_NO);
615 cleanup_rr(rr);
616 return;
617 }
618 return;
619
620 case RP_INTERNET_DNS:
621 rr->phase = RP_MODIFY;
622 for (cr = clients_head; NULL != cr; cr = cr->next)
623 {
624 if (0 != (cr->flags & GNUNET_DNS_FLAG_POST_RESOLUTION))
625 GNUNET_array_append(rr->client_wait_list,
626 rr->client_wait_list_length,
627 cr);
628 }
629 next_phase(rr);
630 return;
631
632 case RP_MODIFY:
633 rr->phase = RP_RESPONSE_MONITOR;
634 for (cr = clients_head; NULL != cr; cr = cr->next)
635 {
636 if (0 != (cr->flags & GNUNET_DNS_FLAG_RESPONSE_MONITOR))
637 GNUNET_array_append(rr->client_wait_list,
638 rr->client_wait_list_length,
639 cr);
640 }
641 next_phase(rr);
642 return;
643
644 case RP_RESPONSE_MONITOR:
645 request_done(rr);
592 break; 646 break;
593 case AF_INET6: 647
594 salen = sizeof (struct sockaddr_in6); 648 case RP_DROP:
595 sa = (const struct sockaddr *) &rr->dst_addr; 649 cleanup_rr(rr);
596 break; 650 break;
651
597 default: 652 default:
598 GNUNET_assert (0); 653 GNUNET_break(0);
599 } 654 cleanup_rr(rr);
600#endif 655 break;
601 rr->phase = RP_INTERNET_DNS;
602 rr->rs = GNUNET_DNSSTUB_resolve (dnsstub,
603 rr->payload,
604 rr->payload_length,
605 &process_dns_result,
606 NULL);
607 if (NULL == rr->rs)
608 {
609 GNUNET_STATISTICS_update (stats,
610 gettext_noop ("# DNS exit failed (failed to open socket)"),
611 1,
612 GNUNET_NO);
613 cleanup_rr (rr);
614 return;
615 }
616 return;
617 case RP_INTERNET_DNS:
618 rr->phase = RP_MODIFY;
619 for (cr = clients_head; NULL != cr; cr = cr->next)
620 {
621 if (0 != (cr->flags & GNUNET_DNS_FLAG_POST_RESOLUTION))
622 GNUNET_array_append (rr->client_wait_list,
623 rr->client_wait_list_length,
624 cr);
625 }
626 next_phase (rr);
627 return;
628 case RP_MODIFY:
629 rr->phase = RP_RESPONSE_MONITOR;
630 for (cr = clients_head; NULL != cr; cr = cr->next)
631 {
632 if (0 != (cr->flags & GNUNET_DNS_FLAG_RESPONSE_MONITOR))
633 GNUNET_array_append (rr->client_wait_list,
634 rr->client_wait_list_length,
635 cr);
636 } 656 }
637 next_phase (rr);
638 return;
639 case RP_RESPONSE_MONITOR:
640 request_done (rr);
641 break;
642 case RP_DROP:
643 cleanup_rr (rr);
644 break;
645 default:
646 GNUNET_break (0);
647 cleanup_rr (rr);
648 break;
649 }
650} 657}
651 658
652 659
@@ -659,18 +666,18 @@ next_phase (struct RequestRecord *rr)
659 * @return our `struct ClientRecord` 666 * @return our `struct ClientRecord`
660 */ 667 */
661static void * 668static void *
662client_connect_cb (void *cls, 669client_connect_cb(void *cls,
663 struct GNUNET_SERVICE_Client *client, 670 struct GNUNET_SERVICE_Client *client,
664 struct GNUNET_MQ_Handle *mq) 671 struct GNUNET_MQ_Handle *mq)
665{ 672{
666 struct ClientRecord *cr = cls; 673 struct ClientRecord *cr = cls;
667 674
668 cr = GNUNET_new (struct ClientRecord); 675 cr = GNUNET_new(struct ClientRecord);
669 cr->client = client; 676 cr->client = client;
670 cr->mq = mq; 677 cr->mq = mq;
671 GNUNET_CONTAINER_DLL_insert (clients_head, 678 GNUNET_CONTAINER_DLL_insert(clients_head,
672 clients_tail, 679 clients_tail,
673 cr); 680 cr);
674 return cr; 681 return cr;
675} 682}
676 683
@@ -683,31 +690,31 @@ client_connect_cb (void *cls,
683 * @param app_ctx our `struct ClientRecord` 690 * @param app_ctx our `struct ClientRecord`
684 */ 691 */
685static void 692static void
686client_disconnect_cb (void *cls, 693client_disconnect_cb(void *cls,
687 struct GNUNET_SERVICE_Client *client, 694 struct GNUNET_SERVICE_Client *client,
688 void *app_ctx) 695 void *app_ctx)
689{ 696{
690 struct ClientRecord *cr = app_ctx; 697 struct ClientRecord *cr = app_ctx;
691 struct RequestRecord *rr; 698 struct RequestRecord *rr;
692 699
693 GNUNET_CONTAINER_DLL_remove (clients_head, 700 GNUNET_CONTAINER_DLL_remove(clients_head,
694 clients_tail, 701 clients_tail,
695 cr); 702 cr);
696 for (unsigned int i=0;i<UINT16_MAX;i++) 703 for (unsigned int i = 0; i < UINT16_MAX; i++)
697 {
698 rr = &requests[i];
699 if (0 == rr->client_wait_list_length)
700 continue; /* not in use */
701 for (unsigned int j=0;j<rr->client_wait_list_length;j++)
702 { 704 {
703 if (rr->client_wait_list[j] == cr) 705 rr = &requests[i];
704 { 706 if (0 == rr->client_wait_list_length)
705 rr->client_wait_list[j] = NULL; 707 continue; /* not in use */
706 next_phase (rr); 708 for (unsigned int j = 0; j < rr->client_wait_list_length; j++)
707 } 709 {
710 if (rr->client_wait_list[j] == cr)
711 {
712 rr->client_wait_list[j] = NULL;
713 next_phase(rr);
714 }
715 }
708 } 716 }
709 } 717 GNUNET_free(cr);
710 GNUNET_free (cr);
711} 718}
712 719
713 720
@@ -720,39 +727,39 @@ client_disconnect_cb (void *cls,
720 * @param r number of bytes in dns 727 * @param r number of bytes in dns
721 */ 728 */
722static void 729static void
723process_dns_result (void *cls, 730process_dns_result(void *cls,
724 const struct GNUNET_TUN_DnsHeader *dns, 731 const struct GNUNET_TUN_DnsHeader *dns,
725 size_t r) 732 size_t r)
726{ 733{
727 struct RequestRecord *rr; 734 struct RequestRecord *rr;
728 735
729 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 736 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
730 "Processing DNS result from stub resolver\n"); 737 "Processing DNS result from stub resolver\n");
731 GNUNET_assert (NULL == cls); 738 GNUNET_assert(NULL == cls);
732 if (NULL == dns) 739 if (NULL == dns)
733 return; /* ignore */ 740 return; /* ignore */
734 741
735 rr = &requests[dns->id]; 742 rr = &requests[dns->id];
736 if (rr->phase != RP_INTERNET_DNS) 743 if (rr->phase != RP_INTERNET_DNS)
737 { 744 {
738 /* unexpected / bogus reply */ 745 /* unexpected / bogus reply */
739 GNUNET_STATISTICS_update (stats, 746 GNUNET_STATISTICS_update(stats,
740 gettext_noop ("# External DNS response discarded (no matching request)"), 747 gettext_noop("# External DNS response discarded (no matching request)"),
741 1, GNUNET_NO); 748 1, GNUNET_NO);
742 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 749 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
743 "Received DNS reply that does not match any pending request. Dropping.\n"); 750 "Received DNS reply that does not match any pending request. Dropping.\n");
744 return; 751 return;
745 } 752 }
746 LOG (GNUNET_ERROR_TYPE_DEBUG, 753 LOG(GNUNET_ERROR_TYPE_DEBUG,
747 "Got a response from the stub resolver for DNS request %llu intercepted locally!\n", 754 "Got a response from the stub resolver for DNS request %llu intercepted locally!\n",
748 (unsigned long long) rr->request_id); 755 (unsigned long long)rr->request_id);
749 GNUNET_free_non_null (rr->payload); 756 GNUNET_free_non_null(rr->payload);
750 rr->payload = GNUNET_malloc (r); 757 rr->payload = GNUNET_malloc(r);
751 GNUNET_memcpy (rr->payload, 758 GNUNET_memcpy(rr->payload,
752 dns, 759 dns,
753 r); 760 r);
754 rr->payload_length = r; 761 rr->payload_length = r;
755 next_phase (rr); 762 next_phase(rr);
756} 763}
757 764
758 765
@@ -763,13 +770,13 @@ process_dns_result (void *cls,
763 * @param reg the init message 770 * @param reg the init message
764 */ 771 */
765static void 772static void
766handle_client_init (void *cls, 773handle_client_init(void *cls,
767 const struct GNUNET_DNS_Register *reg) 774 const struct GNUNET_DNS_Register *reg)
768{ 775{
769 struct ClientRecord *cr = cls; 776 struct ClientRecord *cr = cls;
770 777
771 cr->flags = (enum GNUNET_DNS_Flags) ntohl (reg->flags); 778 cr->flags = (enum GNUNET_DNS_Flags)ntohl(reg->flags);
772 GNUNET_SERVICE_client_continue (cr->client); 779 GNUNET_SERVICE_client_continue(cr->client);
773} 780}
774 781
775 782
@@ -781,8 +788,8 @@ handle_client_init (void *cls,
781 * @return #GNUNET_OK (always fine) 788 * @return #GNUNET_OK (always fine)
782 */ 789 */
783static int 790static int
784check_client_response (void *cls, 791check_client_response(void *cls,
785 const struct GNUNET_DNS_Response *resp) 792 const struct GNUNET_DNS_Response *resp)
786{ 793{
787 return GNUNET_OK; /* any payload is acceptable */ 794 return GNUNET_OK; /* any payload is acceptable */
788} 795}
@@ -795,87 +802,89 @@ check_client_response (void *cls,
795 * @param resp the response 802 * @param resp the response
796 */ 803 */
797static void 804static void
798handle_client_response (void *cls, 805handle_client_response(void *cls,
799 const struct GNUNET_DNS_Response *resp) 806 const struct GNUNET_DNS_Response *resp)
800{ 807{
801 struct ClientRecord *cr = cls; 808 struct ClientRecord *cr = cls;
802 struct RequestRecord *rr; 809 struct RequestRecord *rr;
803 uint16_t msize; 810 uint16_t msize;
804 uint16_t off; 811 uint16_t off;
805 812
806 msize = ntohs (resp->header.size); 813 msize = ntohs(resp->header.size);
807 off = (uint16_t) resp->request_id; 814 off = (uint16_t)resp->request_id;
808 rr = &requests[off]; 815 rr = &requests[off];
809 LOG (GNUNET_ERROR_TYPE_DEBUG, 816 LOG(GNUNET_ERROR_TYPE_DEBUG,
810 "Received DNS response with ID %llu from local client!\n", 817 "Received DNS response with ID %llu from local client!\n",
811 (unsigned long long) resp->request_id); 818 (unsigned long long)resp->request_id);
812 if (rr->request_id != resp->request_id) 819 if (rr->request_id != resp->request_id)
813 {
814 GNUNET_STATISTICS_update (stats,
815 gettext_noop ("# Client response discarded (no matching request)"),
816 1,
817 GNUNET_NO);
818 GNUNET_SERVICE_client_continue (cr->client);
819 return;
820 }
821 for (unsigned int i=0;i<rr->client_wait_list_length;i++)
822 {
823 if (NULL == rr->client_wait_list[i])
824 continue;
825 if (rr->client_wait_list[i] != cr)
826 continue;
827 rr->client_wait_list[i] = NULL;
828 switch (ntohl (resp->drop_flag))
829 { 820 {
830 case 0: /* drop */ 821 GNUNET_STATISTICS_update(stats,
831 rr->phase = RP_DROP; 822 gettext_noop("# Client response discarded (no matching request)"),
832 break; 823 1,
833 case 1: /* no change */ 824 GNUNET_NO);
834 break; 825 GNUNET_SERVICE_client_continue(cr->client);
835 case 2: /* update */ 826 return;
836 msize -= sizeof (struct GNUNET_DNS_Response); 827 }
837 if ( (sizeof (struct GNUNET_TUN_DnsHeader) > msize) || 828 for (unsigned int i = 0; i < rr->client_wait_list_length; i++)
838 (RP_REQUEST_MONITOR == rr->phase) || 829 {
839 (RP_RESPONSE_MONITOR == rr->phase) ) 830 if (NULL == rr->client_wait_list[i])
840 { 831 continue;
841 GNUNET_break (0); 832 if (rr->client_wait_list[i] != cr)
842 GNUNET_SERVICE_client_drop (cr->client); 833 continue;
843 next_phase (rr); 834 rr->client_wait_list[i] = NULL;
844 return; 835 switch (ntohl(resp->drop_flag))
845 } 836 {
846 GNUNET_free_non_null (rr->payload); 837 case 0: /* drop */
847 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 838 rr->phase = RP_DROP;
848 "Changing DNS reply according to client specifications\n"); 839 break;
849 rr->payload = GNUNET_malloc (msize); 840
850 rr->payload_length = msize; 841 case 1: /* no change */
851 GNUNET_memcpy (rr->payload, &resp[1], msize); 842 break;
852 if (rr->phase == RP_QUERY) 843
853 { 844 case 2: /* update */
854 /* clear wait list, we're moving to MODIFY phase next */ 845 msize -= sizeof(struct GNUNET_DNS_Response);
855 GNUNET_array_grow (rr->client_wait_list, 846 if ((sizeof(struct GNUNET_TUN_DnsHeader) > msize) ||
856 rr->client_wait_list_length, 847 (RP_REQUEST_MONITOR == rr->phase) ||
857 0); 848 (RP_RESPONSE_MONITOR == rr->phase))
858 } 849 {
859 /* if query changed to answer, move past DNS resolution phase... */ 850 GNUNET_break(0);
860 if ( (RP_QUERY == rr->phase) && 851 GNUNET_SERVICE_client_drop(cr->client);
861 (rr->payload_length > sizeof (struct GNUNET_TUN_DnsHeader)) && 852 next_phase(rr);
862 ((struct GNUNET_TUN_DnsFlags*)&(((struct GNUNET_TUN_DnsHeader*) rr->payload)->flags))->query_or_response == 1) 853 return;
863 { 854 }
864 rr->phase = RP_INTERNET_DNS; 855 GNUNET_free_non_null(rr->payload);
865 GNUNET_array_grow (rr->client_wait_list, 856 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
866 rr->client_wait_list_length, 857 "Changing DNS reply according to client specifications\n");
867 0); 858 rr->payload = GNUNET_malloc(msize);
868 } 859 rr->payload_length = msize;
869 break; 860 GNUNET_memcpy(rr->payload, &resp[1], msize);
861 if (rr->phase == RP_QUERY)
862 {
863 /* clear wait list, we're moving to MODIFY phase next */
864 GNUNET_array_grow(rr->client_wait_list,
865 rr->client_wait_list_length,
866 0);
867 }
868 /* if query changed to answer, move past DNS resolution phase... */
869 if ((RP_QUERY == rr->phase) &&
870 (rr->payload_length > sizeof(struct GNUNET_TUN_DnsHeader)) &&
871 ((struct GNUNET_TUN_DnsFlags*)&(((struct GNUNET_TUN_DnsHeader*)rr->payload)->flags))->query_or_response == 1)
872 {
873 rr->phase = RP_INTERNET_DNS;
874 GNUNET_array_grow(rr->client_wait_list,
875 rr->client_wait_list_length,
876 0);
877 }
878 break;
879 }
880 next_phase(rr);
881 GNUNET_SERVICE_client_continue(cr->client);
882 return;
870 } 883 }
871 next_phase (rr);
872 GNUNET_SERVICE_client_continue (cr->client);
873 return;
874 }
875 /* odd, client was not on our list for the request, that ought 884 /* odd, client was not on our list for the request, that ought
876 to be an error */ 885 to be an error */
877 GNUNET_break (0); 886 GNUNET_break(0);
878 GNUNET_SERVICE_client_drop (cr->client); 887 GNUNET_SERVICE_client_drop(cr->client);
879} 888}
880 889
881 890
@@ -887,8 +896,8 @@ handle_client_response (void *cls,
887 * @param message the actual message, a DNS request we should handle 896 * @param message the actual message, a DNS request we should handle
888 */ 897 */
889static int 898static int
890process_helper_messages (void *cls, 899process_helper_messages(void *cls,
891 const struct GNUNET_MessageHeader *message) 900 const struct GNUNET_MessageHeader *message)
892{ 901{
893 uint16_t msize; 902 uint16_t msize;
894 const struct GNUNET_TUN_Layer2PacketHeader *tun; 903 const struct GNUNET_TUN_Layer2PacketHeader *tun;
@@ -902,93 +911,95 @@ process_helper_messages (void *cls,
902 struct sockaddr_in *dsta4; 911 struct sockaddr_in *dsta4;
903 struct sockaddr_in6 *dsta6; 912 struct sockaddr_in6 *dsta6;
904 913
905 LOG (GNUNET_ERROR_TYPE_DEBUG, 914 LOG(GNUNET_ERROR_TYPE_DEBUG,
906 "Intercepted message via DNS hijacker\n"); 915 "Intercepted message via DNS hijacker\n");
907 msize = ntohs (message->size); 916 msize = ntohs(message->size);
908 if (msize < sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_TUN_Layer2PacketHeader) + sizeof (struct GNUNET_TUN_IPv4Header)) 917 if (msize < sizeof(struct GNUNET_MessageHeader) + sizeof(struct GNUNET_TUN_Layer2PacketHeader) + sizeof(struct GNUNET_TUN_IPv4Header))
909 {
910 /* non-IP packet received on TUN!? */
911 GNUNET_break (0);
912 return GNUNET_OK;
913 }
914 msize -= sizeof (struct GNUNET_MessageHeader);
915 tun = (const struct GNUNET_TUN_Layer2PacketHeader *) &message[1];
916 msize -= sizeof (struct GNUNET_TUN_Layer2PacketHeader);
917 switch (ntohs (tun->proto))
918 {
919 case ETH_P_IPV4:
920 ip4 = (const struct GNUNET_TUN_IPv4Header *) &tun[1];
921 ip6 = NULL; /* make compiler happy */
922 if ( (msize < sizeof (struct GNUNET_TUN_IPv4Header)) ||
923 (ip4->version != 4) ||
924 (ip4->header_length != sizeof (struct GNUNET_TUN_IPv4Header) / 4) ||
925 (ntohs(ip4->total_length) != msize) ||
926 (ip4->protocol != IPPROTO_UDP) )
927 { 918 {
928 /* non-IP/UDP packet received on TUN (or with options) */ 919 /* non-IP packet received on TUN!? */
929 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 920 GNUNET_break(0);
930 _("Received malformed IPv4-UDP packet on TUN interface.\n"));
931 return GNUNET_OK; 921 return GNUNET_OK;
932 } 922 }
933 udp = (const struct GNUNET_TUN_UdpHeader*) &ip4[1]; 923 msize -= sizeof(struct GNUNET_MessageHeader);
934 msize -= sizeof (struct GNUNET_TUN_IPv4Header); 924 tun = (const struct GNUNET_TUN_Layer2PacketHeader *)&message[1];
935 break; 925 msize -= sizeof(struct GNUNET_TUN_Layer2PacketHeader);
936 case ETH_P_IPV6: 926 switch (ntohs(tun->proto))
937 ip4 = NULL; /* make compiler happy */
938 ip6 = (const struct GNUNET_TUN_IPv6Header *) &tun[1];
939 if ( (msize < sizeof (struct GNUNET_TUN_IPv6Header)) ||
940 (ip6->version != 6) ||
941 (ntohs (ip6->payload_length) != msize - sizeof (struct GNUNET_TUN_IPv6Header)) ||
942 (ip6->next_header != IPPROTO_UDP) )
943 { 927 {
944 /* non-IP/UDP packet received on TUN (or with extensions) */ 928 case ETH_P_IPV4:
945 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 929 ip4 = (const struct GNUNET_TUN_IPv4Header *)&tun[1];
946 _("Received malformed IPv6-UDP packet on TUN interface.\n")); 930 ip6 = NULL; /* make compiler happy */
931 if ((msize < sizeof(struct GNUNET_TUN_IPv4Header)) ||
932 (ip4->version != 4) ||
933 (ip4->header_length != sizeof(struct GNUNET_TUN_IPv4Header) / 4) ||
934 (ntohs(ip4->total_length) != msize) ||
935 (ip4->protocol != IPPROTO_UDP))
936 {
937 /* non-IP/UDP packet received on TUN (or with options) */
938 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
939 _("Received malformed IPv4-UDP packet on TUN interface.\n"));
940 return GNUNET_OK;
941 }
942 udp = (const struct GNUNET_TUN_UdpHeader*)&ip4[1];
943 msize -= sizeof(struct GNUNET_TUN_IPv4Header);
944 break;
945
946 case ETH_P_IPV6:
947 ip4 = NULL; /* make compiler happy */
948 ip6 = (const struct GNUNET_TUN_IPv6Header *)&tun[1];
949 if ((msize < sizeof(struct GNUNET_TUN_IPv6Header)) ||
950 (ip6->version != 6) ||
951 (ntohs(ip6->payload_length) != msize - sizeof(struct GNUNET_TUN_IPv6Header)) ||
952 (ip6->next_header != IPPROTO_UDP))
953 {
954 /* non-IP/UDP packet received on TUN (or with extensions) */
955 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
956 _("Received malformed IPv6-UDP packet on TUN interface.\n"));
957 return GNUNET_OK;
958 }
959 udp = (const struct GNUNET_TUN_UdpHeader *)&ip6[1];
960 msize -= sizeof(struct GNUNET_TUN_IPv6Header);
961 break;
962
963 default:
964 /* non-IP packet received on TUN!? */
965 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
966 _("Got non-IP packet with %u bytes and protocol %u from TUN\n"),
967 (unsigned int)msize,
968 ntohs(tun->proto));
947 return GNUNET_OK; 969 return GNUNET_OK;
948 } 970 }
949 udp = (const struct GNUNET_TUN_UdpHeader *) &ip6[1]; 971 if ((msize <= sizeof(struct GNUNET_TUN_UdpHeader) + sizeof(struct GNUNET_TUN_DnsHeader)) ||
950 msize -= sizeof (struct GNUNET_TUN_IPv6Header); 972 (DNS_PORT != ntohs(udp->destination_port)))
951 break; 973 {
952 default: 974 /* non-DNS packet received on TUN, ignore */
953 /* non-IP packet received on TUN!? */ 975 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
954 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 976 _("DNS interceptor got non-DNS packet (dropped)\n"));
955 _("Got non-IP packet with %u bytes and protocol %u from TUN\n"), 977 GNUNET_STATISTICS_update(stats,
956 (unsigned int) msize, 978 gettext_noop("# Non-DNS UDP packet received via TUN interface"),
957 ntohs (tun->proto)); 979 1, GNUNET_NO);
958 return GNUNET_OK; 980 return GNUNET_OK;
959 } 981 }
960 if ( (msize <= sizeof (struct GNUNET_TUN_UdpHeader) + sizeof (struct GNUNET_TUN_DnsHeader)) || 982 msize -= sizeof(struct GNUNET_TUN_UdpHeader);
961 (DNS_PORT != ntohs (udp->destination_port)) ) 983 dns = (const struct GNUNET_TUN_DnsHeader*)&udp[1];
962 {
963 /* non-DNS packet received on TUN, ignore */
964 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
965 _("DNS interceptor got non-DNS packet (dropped)\n"));
966 GNUNET_STATISTICS_update (stats,
967 gettext_noop ("# Non-DNS UDP packet received via TUN interface"),
968 1, GNUNET_NO);
969 return GNUNET_OK;
970 }
971 msize -= sizeof (struct GNUNET_TUN_UdpHeader);
972 dns = (const struct GNUNET_TUN_DnsHeader*) &udp[1];
973 rr = &requests[dns->id]; 984 rr = &requests[dns->id];
974 985
975 /* clean up from previous request */ 986 /* clean up from previous request */
976 GNUNET_free_non_null (rr->payload); 987 GNUNET_free_non_null(rr->payload);
977 rr->payload = NULL; 988 rr->payload = NULL;
978 GNUNET_array_grow (rr->client_wait_list, 989 GNUNET_array_grow(rr->client_wait_list,
979 rr->client_wait_list_length, 990 rr->client_wait_list_length,
980 0); 991 0);
981 992
982 /* setup new request */ 993 /* setup new request */
983 rr->phase = RP_INIT; 994 rr->phase = RP_INIT;
984 switch (ntohs (tun->proto)) 995 switch (ntohs(tun->proto))
985 {
986 case ETH_P_IPV4:
987 { 996 {
988 srca4 = (struct sockaddr_in*) &rr->src_addr; 997 case ETH_P_IPV4:
989 dsta4 = (struct sockaddr_in*) &rr->dst_addr; 998 {
990 memset (srca4, 0, sizeof (struct sockaddr_in)); 999 srca4 = (struct sockaddr_in*)&rr->src_addr;
991 memset (dsta4, 0, sizeof (struct sockaddr_in)); 1000 dsta4 = (struct sockaddr_in*)&rr->dst_addr;
1001 memset(srca4, 0, sizeof(struct sockaddr_in));
1002 memset(dsta4, 0, sizeof(struct sockaddr_in));
992 srca4->sin_family = AF_INET; 1003 srca4->sin_family = AF_INET;
993 dsta4->sin_family = AF_INET; 1004 dsta4->sin_family = AF_INET;
994 srca4->sin_addr = ip4->source_address; 1005 srca4->sin_addr = ip4->source_address;
@@ -996,17 +1007,18 @@ process_helper_messages (void *cls,
996 srca4->sin_port = udp->source_port; 1007 srca4->sin_port = udp->source_port;
997 dsta4->sin_port = udp->destination_port; 1008 dsta4->sin_port = udp->destination_port;
998#if HAVE_SOCKADDR_IN_SIN_LEN 1009#if HAVE_SOCKADDR_IN_SIN_LEN
999 srca4->sin_len = sizeof (struct sockaddr_in); 1010 srca4->sin_len = sizeof(struct sockaddr_in);
1000 dsta4->sin_len = sizeof (struct sockaddr_in); 1011 dsta4->sin_len = sizeof(struct sockaddr_in);
1001#endif 1012#endif
1002 } 1013 }
1003 break; 1014 break;
1004 case ETH_P_IPV6: 1015
1016 case ETH_P_IPV6:
1005 { 1017 {
1006 srca6 = (struct sockaddr_in6*) &rr->src_addr; 1018 srca6 = (struct sockaddr_in6*)&rr->src_addr;
1007 dsta6 = (struct sockaddr_in6*) &rr->dst_addr; 1019 dsta6 = (struct sockaddr_in6*)&rr->dst_addr;
1008 memset (srca6, 0, sizeof (struct sockaddr_in6)); 1020 memset(srca6, 0, sizeof(struct sockaddr_in6));
1009 memset (dsta6, 0, sizeof (struct sockaddr_in6)); 1021 memset(dsta6, 0, sizeof(struct sockaddr_in6));
1010 srca6->sin6_family = AF_INET6; 1022 srca6->sin6_family = AF_INET6;
1011 dsta6->sin6_family = AF_INET6; 1023 dsta6->sin6_family = AF_INET6;
1012 srca6->sin6_addr = ip6->source_address; 1024 srca6->sin6_addr = ip6->source_address;
@@ -1014,27 +1026,28 @@ process_helper_messages (void *cls,
1014 srca6->sin6_port = udp->source_port; 1026 srca6->sin6_port = udp->source_port;
1015 dsta6->sin6_port = udp->destination_port; 1027 dsta6->sin6_port = udp->destination_port;
1016#if HAVE_SOCKADDR_IN_SIN_LEN 1028#if HAVE_SOCKADDR_IN_SIN_LEN
1017 srca6->sin6_len = sizeof (struct sockaddr_in6); 1029 srca6->sin6_len = sizeof(struct sockaddr_in6);
1018 dsta6->sin6_len = sizeof (struct sockaddr_in6); 1030 dsta6->sin6_len = sizeof(struct sockaddr_in6);
1019#endif 1031#endif
1020 } 1032 }
1021 break; 1033 break;
1022 default: 1034
1023 GNUNET_assert (0); 1035 default:
1024 } 1036 GNUNET_assert(0);
1025 rr->payload = GNUNET_malloc (msize); 1037 }
1038 rr->payload = GNUNET_malloc(msize);
1026 rr->payload_length = msize; 1039 rr->payload_length = msize;
1027 GNUNET_memcpy (rr->payload, dns, msize); 1040 GNUNET_memcpy(rr->payload, dns, msize);
1028 rr->request_id = dns->id | (request_id_gen << 16); 1041 rr->request_id = dns->id | (request_id_gen << 16);
1029 request_id_gen++; 1042 request_id_gen++;
1030 LOG (GNUNET_ERROR_TYPE_DEBUG, 1043 LOG(GNUNET_ERROR_TYPE_DEBUG,
1031 "Creating new DNS request %llu\n", 1044 "Creating new DNS request %llu\n",
1032 (unsigned long long) rr->request_id); 1045 (unsigned long long)rr->request_id);
1033 GNUNET_STATISTICS_update (stats, 1046 GNUNET_STATISTICS_update(stats,
1034 gettext_noop ("# DNS requests received via TUN interface"), 1047 gettext_noop("# DNS requests received via TUN interface"),
1035 1, GNUNET_NO); 1048 1, GNUNET_NO);
1036 /* start request processing state machine */ 1049 /* start request processing state machine */
1037 next_phase (rr); 1050 next_phase(rr);
1038 return GNUNET_OK; 1051 return GNUNET_OK;
1039} 1052}
1040 1053
@@ -1045,9 +1058,9 @@ process_helper_messages (void *cls,
1045 * @param service the initialized service 1058 * @param service the initialized service
1046 */ 1059 */
1047static void 1060static void
1048run (void *cls, 1061run(void *cls,
1049 const struct GNUNET_CONFIGURATION_Handle *cfg_, 1062 const struct GNUNET_CONFIGURATION_Handle *cfg_,
1050 struct GNUNET_SERVICE_Handle *service) 1063 struct GNUNET_SERVICE_Handle *service)
1051{ 1064{
1052 char *ifc_name; 1065 char *ifc_name;
1053 char *ipv4addr; 1066 char *ipv4addr;
@@ -1059,126 +1072,126 @@ run (void *cls,
1059 int nortsetup; 1072 int nortsetup;
1060 1073
1061 cfg = cfg_; 1074 cfg = cfg_;
1062 stats = GNUNET_STATISTICS_create ("dns", cfg); 1075 stats = GNUNET_STATISTICS_create("dns", cfg);
1063 GNUNET_SCHEDULER_add_shutdown (&cleanup_task, 1076 GNUNET_SCHEDULER_add_shutdown(&cleanup_task,
1064 cls); 1077 cls);
1065 dnsstub = GNUNET_DNSSTUB_start (128); 1078 dnsstub = GNUNET_DNSSTUB_start(128);
1066 /* TODO: support multiple DNS_EXIT servers being configured */ 1079 /* TODO: support multiple DNS_EXIT servers being configured */
1067 /* TODO: see above TODO on using DNS server from original packet. 1080 /* TODO: see above TODO on using DNS server from original packet.
1068 Not sure which is best... */ 1081 Not sure which is best... */
1069 dns_exit = NULL; 1082 dns_exit = NULL;
1070 if ( (GNUNET_OK != 1083 if ((GNUNET_OK !=
1071 GNUNET_CONFIGURATION_get_value_string (cfg, 1084 GNUNET_CONFIGURATION_get_value_string(cfg,
1072 "dns", 1085 "dns",
1073 "DNS_EXIT", 1086 "DNS_EXIT",
1074 &dns_exit)) || 1087 &dns_exit)) ||
1075 (GNUNET_OK != 1088 (GNUNET_OK !=
1076 GNUNET_DNSSTUB_add_dns_ip (dnsstub, 1089 GNUNET_DNSSTUB_add_dns_ip(dnsstub,
1077 dns_exit)) ) 1090 dns_exit)))
1078 { 1091 {
1079 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, 1092 GNUNET_log_config_invalid(GNUNET_ERROR_TYPE_ERROR,
1080 "dns", 1093 "dns",
1081 "DNS_EXIT", 1094 "DNS_EXIT",
1082 _("need a valid IPv4 or IPv6 address\n")); 1095 _("need a valid IPv4 or IPv6 address\n"));
1083 GNUNET_free_non_null (dns_exit); 1096 GNUNET_free_non_null(dns_exit);
1084 } 1097 }
1085 binary = GNUNET_OS_get_suid_binary_path (cfg, "gnunet-helper-dns"); 1098 binary = GNUNET_OS_get_suid_binary_path(cfg, "gnunet-helper-dns");
1086 1099
1087 if (GNUNET_YES != 1100 if (GNUNET_YES !=
1088 GNUNET_OS_check_helper_binary (binary, 1101 GNUNET_OS_check_helper_binary(binary,
1089 GNUNET_YES, 1102 GNUNET_YES,
1090 NULL)) // TODO: once we have a windows-testcase, add test parameters here 1103 NULL)) // TODO: once we have a windows-testcase, add test parameters here
1091 { 1104 {
1092 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1105 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
1093 _("`%s' is not SUID or the path is invalid, " 1106 _("`%s' is not SUID or the path is invalid, "
1094 "will not run DNS interceptor\n"), 1107 "will not run DNS interceptor\n"),
1095 binary); 1108 binary);
1096 global_ret = 1; 1109 global_ret = 1;
1097 GNUNET_free (binary); 1110 GNUNET_free(binary);
1098 return; 1111 return;
1099 } 1112 }
1100 GNUNET_free (binary); 1113 GNUNET_free(binary);
1101 1114
1102 helper_argv[0] = GNUNET_strdup ("gnunet-dns"); 1115 helper_argv[0] = GNUNET_strdup("gnunet-dns");
1103 if (GNUNET_SYSERR == 1116 if (GNUNET_SYSERR ==
1104 GNUNET_CONFIGURATION_get_value_string (cfg, 1117 GNUNET_CONFIGURATION_get_value_string(cfg,
1105 "dns", 1118 "dns",
1106 "IFNAME", 1119 "IFNAME",
1107 &ifc_name)) 1120 &ifc_name))
1108 { 1121 {
1109 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1122 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
1110 "No entry 'IFNAME' in configuration!\n"); 1123 "No entry 'IFNAME' in configuration!\n");
1111 GNUNET_free (binary); 1124 GNUNET_free(binary);
1112 GNUNET_SCHEDULER_shutdown (); 1125 GNUNET_SCHEDULER_shutdown();
1113 return; 1126 return;
1114 } 1127 }
1115 helper_argv[1] = ifc_name; 1128 helper_argv[1] = ifc_name;
1116 if ( (GNUNET_SYSERR == 1129 if ((GNUNET_SYSERR ==
1117 GNUNET_CONFIGURATION_get_value_string (cfg, 1130 GNUNET_CONFIGURATION_get_value_string(cfg,
1118 "dns", 1131 "dns",
1119 "IPV6ADDR", 1132 "IPV6ADDR",
1120 &ipv6addr)) ) 1133 &ipv6addr)))
1121 { 1134 {
1122 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1135 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
1123 "No entry 'IPV6ADDR' in configuration!\n"); 1136 "No entry 'IPV6ADDR' in configuration!\n");
1124 GNUNET_free (binary); 1137 GNUNET_free(binary);
1125 GNUNET_SCHEDULER_shutdown (); 1138 GNUNET_SCHEDULER_shutdown();
1126 return; 1139 return;
1127 } 1140 }
1128 helper_argv[2] = ipv6addr; 1141 helper_argv[2] = ipv6addr;
1129 if (GNUNET_SYSERR == 1142 if (GNUNET_SYSERR ==
1130 GNUNET_CONFIGURATION_get_value_string (cfg, 1143 GNUNET_CONFIGURATION_get_value_string(cfg,
1131 "dns", 1144 "dns",
1132 "IPV6PREFIX", 1145 "IPV6PREFIX",
1133 &ipv6prefix)) 1146 &ipv6prefix))
1134 { 1147 {
1135 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1148 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
1136 "No entry 'IPV6PREFIX' in configuration!\n"); 1149 "No entry 'IPV6PREFIX' in configuration!\n");
1137 GNUNET_free (binary); 1150 GNUNET_free(binary);
1138 GNUNET_SCHEDULER_shutdown (); 1151 GNUNET_SCHEDULER_shutdown();
1139 return; 1152 return;
1140 } 1153 }
1141 helper_argv[3] = ipv6prefix; 1154 helper_argv[3] = ipv6prefix;
1142 1155
1143 if (GNUNET_SYSERR == 1156 if (GNUNET_SYSERR ==
1144 GNUNET_CONFIGURATION_get_value_string (cfg, 1157 GNUNET_CONFIGURATION_get_value_string(cfg,
1145 "dns", 1158 "dns",
1146 "IPV4ADDR", 1159 "IPV4ADDR",
1147 &ipv4addr)) 1160 &ipv4addr))
1148 { 1161 {
1149 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1162 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
1150 "No entry 'IPV4ADDR' in configuration!\n"); 1163 "No entry 'IPV4ADDR' in configuration!\n");
1151 GNUNET_free (binary); 1164 GNUNET_free(binary);
1152 GNUNET_SCHEDULER_shutdown (); 1165 GNUNET_SCHEDULER_shutdown();
1153 return; 1166 return;
1154 } 1167 }
1155 helper_argv[4] = ipv4addr; 1168 helper_argv[4] = ipv4addr;
1156 if (GNUNET_SYSERR == 1169 if (GNUNET_SYSERR ==
1157 GNUNET_CONFIGURATION_get_value_string (cfg, "dns", "IPV4MASK", 1170 GNUNET_CONFIGURATION_get_value_string(cfg, "dns", "IPV4MASK",
1158 &ipv4mask)) 1171 &ipv4mask))
1159 { 1172 {
1160 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1173 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
1161 "No entry 'IPV4MASK' in configuration!\n"); 1174 "No entry 'IPV4MASK' in configuration!\n");
1162 GNUNET_free (binary); 1175 GNUNET_free(binary);
1163 GNUNET_SCHEDULER_shutdown (); 1176 GNUNET_SCHEDULER_shutdown();
1164 return; 1177 return;
1165 } 1178 }
1166 helper_argv[5] = ipv4mask; 1179 helper_argv[5] = ipv4mask;
1167 1180
1168 nortsetup = GNUNET_CONFIGURATION_get_value_yesno (cfg, "dns", 1181 nortsetup = GNUNET_CONFIGURATION_get_value_yesno(cfg, "dns",
1169 "SKIP_ROUTING_SETUP"); 1182 "SKIP_ROUTING_SETUP");
1170 if (GNUNET_YES == nortsetup) 1183 if (GNUNET_YES == nortsetup)
1171 helper_argv[6] = GNUNET_strdup("1"); 1184 helper_argv[6] = GNUNET_strdup("1");
1172 else 1185 else
1173 helper_argv[6] = GNUNET_strdup("0"); 1186 helper_argv[6] = GNUNET_strdup("0");
1174 1187
1175 helper_argv[7] = NULL; 1188 helper_argv[7] = NULL;
1176 hijacker = GNUNET_HELPER_start (GNUNET_NO, 1189 hijacker = GNUNET_HELPER_start(GNUNET_NO,
1177 binary, 1190 binary,
1178 helper_argv, 1191 helper_argv,
1179 &process_helper_messages, 1192 &process_helper_messages,
1180 NULL, NULL); 1193 NULL, NULL);
1181 GNUNET_free (binary); 1194 GNUNET_free(binary);
1182} 1195}
1183 1196
1184 1197
@@ -1186,21 +1199,21 @@ run (void *cls,
1186 * Define "main" method using service macro. 1199 * Define "main" method using service macro.
1187 */ 1200 */
1188GNUNET_SERVICE_MAIN 1201GNUNET_SERVICE_MAIN
1189("dns", 1202 ("dns",
1190 GNUNET_SERVICE_OPTION_NONE, 1203 GNUNET_SERVICE_OPTION_NONE,
1191 &run, 1204 &run,
1192 &client_connect_cb, 1205 &client_connect_cb,
1193 &client_disconnect_cb, 1206 &client_disconnect_cb,
1194 NULL, 1207 NULL,
1195 GNUNET_MQ_hd_fixed_size (client_init, 1208 GNUNET_MQ_hd_fixed_size(client_init,
1196 GNUNET_MESSAGE_TYPE_DNS_CLIENT_INIT, 1209 GNUNET_MESSAGE_TYPE_DNS_CLIENT_INIT,
1197 struct GNUNET_DNS_Register, 1210 struct GNUNET_DNS_Register,
1198 NULL), 1211 NULL),
1199 GNUNET_MQ_hd_var_size (client_response, 1212 GNUNET_MQ_hd_var_size(client_response,
1200 GNUNET_MESSAGE_TYPE_DNS_CLIENT_RESPONSE, 1213 GNUNET_MESSAGE_TYPE_DNS_CLIENT_RESPONSE,
1201 struct GNUNET_DNS_Response, 1214 struct GNUNET_DNS_Response,
1202 NULL), 1215 NULL),
1203 GNUNET_MQ_handler_end ()); 1216 GNUNET_MQ_handler_end());
1204 1217
1205 1218
1206/* FIXME: this might need a port on systems without 'getresgid' */ 1219/* FIXME: this might need a port on systems without 'getresgid' */
@@ -1209,28 +1222,28 @@ GNUNET_SERVICE_MAIN
1209 * Enable use of SGID capabilities on POSIX 1222 * Enable use of SGID capabilities on POSIX
1210 */ 1223 */
1211void __attribute__ ((constructor)) 1224void __attribute__ ((constructor))
1212GNUNET_DNS_init () 1225GNUNET_DNS_init()
1213{ 1226{
1214 gid_t rgid; 1227 gid_t rgid;
1215 gid_t egid; 1228 gid_t egid;
1216 gid_t sgid; 1229 gid_t sgid;
1217 1230
1218 if (-1 == getresgid (&rgid, 1231 if (-1 == getresgid(&rgid,
1219 &egid, 1232 &egid,
1220 &sgid)) 1233 &sgid))
1221 { 1234 {
1222 fprintf (stderr, 1235 fprintf(stderr,
1223 "getresgid failed: %s\n", 1236 "getresgid failed: %s\n",
1224 strerror (errno)); 1237 strerror(errno));
1225 } 1238 }
1226 else if (sgid != rgid) 1239 else if (sgid != rgid)
1227 { 1240 {
1228 if (-1 == setregid (sgid, 1241 if (-1 == setregid(sgid,
1229 sgid)) 1242 sgid))
1230 fprintf (stderr, 1243 fprintf(stderr,
1231 "setregid failed: %s\n", 1244 "setregid failed: %s\n",
1232 strerror (errno)); 1245 strerror(errno));
1233 } 1246 }
1234} 1247}
1235#endif 1248#endif
1236 1249