aboutsummaryrefslogtreecommitdiff
path: root/src/vpn/gnunet-service-vpn.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vpn/gnunet-service-vpn.c')
-rw-r--r--src/vpn/gnunet-service-vpn.c3814
1 files changed, 1935 insertions, 1879 deletions
diff --git a/src/vpn/gnunet-service-vpn.c b/src/vpn/gnunet-service-vpn.c
index e2d8a8e50..4c042ea80 100644
--- a/src/vpn/gnunet-service-vpn.c
+++ b/src/vpn/gnunet-service-vpn.c
@@ -16,7 +16,7 @@
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 vpn/gnunet-service-vpn.c 22 * @file vpn/gnunet-service-vpn.c
@@ -65,9 +65,7 @@ struct DestinationEntry;
65 * List of channels we keep for each destination port for a given 65 * List of channels we keep for each destination port for a given
66 * destination entry. 66 * destination entry.
67 */ 67 */
68struct DestinationChannel 68struct DestinationChannel {
69{
70
71 /** 69 /**
72 * Kept in a DLL. 70 * Kept in a DLL.
73 */ 71 */
@@ -94,9 +92,7 @@ struct DestinationChannel
94 * Information we track for each IP address to determine which channel 92 * Information we track for each IP address to determine which channel
95 * to send the traffic over to the destination. 93 * to send the traffic over to the destination.
96 */ 94 */
97struct DestinationEntry 95struct DestinationEntry {
98{
99
100 /** 96 /**
101 * Key under which this entry is in the 'destination_map' (only valid 97 * Key under which this entry is in the 'destination_map' (only valid
102 * if 'heap_node != NULL'). 98 * if 'heap_node != NULL').
@@ -127,11 +123,8 @@ struct DestinationEntry
127 /** 123 /**
128 * Details about the connection (depending on is_service). 124 * Details about the connection (depending on is_service).
129 */ 125 */
130 union 126 union {
131 { 127 struct {
132
133 struct
134 {
135 /** 128 /**
136 * The description of the service (only used for service channels). 129 * The description of the service (only used for service channels).
137 */ 130 */
@@ -141,12 +134,9 @@ struct DestinationEntry
141 * Peer offering the service. 134 * Peer offering the service.
142 */ 135 */
143 struct GNUNET_PeerIdentity target; 136 struct GNUNET_PeerIdentity target;
144
145 } service_destination; 137 } service_destination;
146 138
147 struct 139 struct {
148 {
149
150 /** 140 /**
151 * Address family used (AF_INET or AF_INET6). 141 * Address family used (AF_INET or AF_INET6).
152 */ 142 */
@@ -155,21 +145,18 @@ struct DestinationEntry
155 /** 145 /**
156 * IP address of the ultimate destination (only used for exit channels). 146 * IP address of the ultimate destination (only used for exit channels).
157 */ 147 */
158 union 148 union {
159 {
160 /** 149 /**
161 * Address if af is AF_INET. 150 * Address if af is AF_INET.
162 */ 151 */
163 struct in_addr v4; 152 struct in_addr v4;
164 153
165 /** 154 /**
166 * Address if af is AF_INET6. 155 * Address if af is AF_INET6.
167 */ 156 */
168 struct in6_addr v6; 157 struct in6_addr v6;
169 } ip; 158 } ip;
170
171 } exit_destination; 159 } exit_destination;
172
173 } details; 160 } details;
174}; 161};
175 162
@@ -177,8 +164,7 @@ struct DestinationEntry
177/** 164/**
178 * A messages we have in queue for a particular channel. 165 * A messages we have in queue for a particular channel.
179 */ 166 */
180struct ChannelMessageQueueEntry 167struct ChannelMessageQueueEntry {
181{
182 /** 168 /**
183 * This is a doubly-linked list. 169 * This is a doubly-linked list.
184 */ 170 */
@@ -204,9 +190,7 @@ struct ChannelMessageQueueEntry
204/** 190/**
205 * State we keep for each of our channels. 191 * State we keep for each of our channels.
206 */ 192 */
207struct ChannelState 193struct ChannelState {
208{
209
210 /** 194 /**
211 * Information about the channel to use, NULL if no channel 195 * Information about the channel to use, NULL if no channel
212 * is available right now. 196 * is available right now.
@@ -266,8 +250,7 @@ struct ChannelState
266 /** 250 /**
267 * IP address of the source on our end, initially uninitialized. 251 * IP address of the source on our end, initially uninitialized.
268 */ 252 */
269 union 253 union {
270 {
271 /** 254 /**
272 * Address if af is AF_INET. 255 * Address if af is AF_INET.
273 */ 256 */
@@ -277,15 +260,13 @@ struct ChannelState
277 * Address if af is AF_INET6. 260 * Address if af is AF_INET6.
278 */ 261 */
279 struct in6_addr v6; 262 struct in6_addr v6;
280
281 } source_ip; 263 } source_ip;
282 264
283 /** 265 /**
284 * Destination IP address used by the source on our end (this is the IP 266 * Destination IP address used by the source on our end (this is the IP
285 * that we pick freely within the VPN's channel IP range). 267 * that we pick freely within the VPN's channel IP range).
286 */ 268 */
287 union 269 union {
288 {
289 /** 270 /**
290 * Address if af is AF_INET. 271 * Address if af is AF_INET.
291 */ 272 */
@@ -295,7 +276,6 @@ struct ChannelState
295 * Address if af is AF_INET6. 276 * Address if af is AF_INET6.
296 */ 277 */
297 struct in6_addr v6; 278 struct in6_addr v6;
298
299 } destination_ip; 279 } destination_ip;
300 280
301 /** 281 /**
@@ -390,22 +370,24 @@ static unsigned long long max_channel_mappings;
390 * @param key where to store the key 370 * @param key where to store the key
391 */ 371 */
392static void 372static void
393get_destination_key_from_ip (int af, 373get_destination_key_from_ip(int af,
394 const void *address, 374 const void *address,
395 struct GNUNET_HashCode *key) 375 struct GNUNET_HashCode *key)
396{ 376{
397 switch (af) 377 switch (af)
398 { 378 {
399 case AF_INET: 379 case AF_INET:
400 GNUNET_CRYPTO_hash (address, sizeof (struct in_addr), key); 380 GNUNET_CRYPTO_hash(address, sizeof(struct in_addr), key);
401 break; 381 break;
402 case AF_INET6: 382
403 GNUNET_CRYPTO_hash (address, sizeof (struct in6_addr), key); 383 case AF_INET6:
404 break; 384 GNUNET_CRYPTO_hash(address, sizeof(struct in6_addr), key);
405 default: 385 break;
406 GNUNET_assert (0); 386
407 break; 387 default:
408 } 388 GNUNET_assert(0);
389 break;
390 }
409} 391}
410 392
411 393
@@ -422,43 +404,45 @@ get_destination_key_from_ip (int af,
422 * @param key where to store the key 404 * @param key where to store the key
423 */ 405 */
424static void 406static void
425get_channel_key_from_ips (int af, 407get_channel_key_from_ips(int af,
426 uint8_t protocol, 408 uint8_t protocol,
427 const void *source_ip, 409 const void *source_ip,
428 uint16_t source_port, 410 uint16_t source_port,
429 const void *destination_ip, 411 const void *destination_ip,
430 uint16_t destination_port, 412 uint16_t destination_port,
431 struct GNUNET_HashCode *key) 413 struct GNUNET_HashCode *key)
432{ 414{
433 char *off; 415 char *off;
434 416
435 memset (key, 0, sizeof (struct GNUNET_HashCode)); 417 memset(key, 0, sizeof(struct GNUNET_HashCode));
436 /* the GNUnet hashmap only uses the first sizeof(unsigned int) of the hash, 418 /* the GNUnet hashmap only uses the first sizeof(unsigned int) of the hash,
437 so we put the ports in there (and hope for few collisions) */ 419 so we put the ports in there (and hope for few collisions) */
438 off = (char *) key; 420 off = (char *)key;
439 GNUNET_memcpy (off, &source_port, sizeof (uint16_t)); 421 GNUNET_memcpy(off, &source_port, sizeof(uint16_t));
440 off += sizeof (uint16_t); 422 off += sizeof(uint16_t);
441 GNUNET_memcpy (off, &destination_port, sizeof (uint16_t)); 423 GNUNET_memcpy(off, &destination_port, sizeof(uint16_t));
442 off += sizeof (uint16_t); 424 off += sizeof(uint16_t);
443 switch (af) 425 switch (af)
444 { 426 {
445 case AF_INET: 427 case AF_INET:
446 GNUNET_memcpy (off, source_ip, sizeof (struct in_addr)); 428 GNUNET_memcpy(off, source_ip, sizeof(struct in_addr));
447 off += sizeof (struct in_addr); 429 off += sizeof(struct in_addr);
448 GNUNET_memcpy (off, destination_ip, sizeof (struct in_addr)); 430 GNUNET_memcpy(off, destination_ip, sizeof(struct in_addr));
449 off += sizeof (struct in_addr); 431 off += sizeof(struct in_addr);
450 break; 432 break;
451 case AF_INET6: 433
452 GNUNET_memcpy (off, source_ip, sizeof (struct in6_addr)); 434 case AF_INET6:
453 off += sizeof (struct in6_addr); 435 GNUNET_memcpy(off, source_ip, sizeof(struct in6_addr));
454 GNUNET_memcpy (off, destination_ip, sizeof (struct in6_addr)); 436 off += sizeof(struct in6_addr);
455 off += sizeof (struct in6_addr); 437 GNUNET_memcpy(off, destination_ip, sizeof(struct in6_addr));
456 break; 438 off += sizeof(struct in6_addr);
457 default: 439 break;
458 GNUNET_assert (0); 440
459 break; 441 default:
460 } 442 GNUNET_assert(0);
461 GNUNET_memcpy (off, &protocol, sizeof (uint8_t)); 443 break;
444 }
445 GNUNET_memcpy(off, &protocol, sizeof(uint8_t));
462 /* off += sizeof (uint8_t); */ 446 /* off += sizeof (uint8_t); */
463} 447}
464 448
@@ -472,35 +456,38 @@ get_channel_key_from_ips (int af,
472 * @param addr resulting IP address 456 * @param addr resulting IP address
473 */ 457 */
474static void 458static void
475send_client_reply (struct GNUNET_SERVICE_Client *client, 459send_client_reply(struct GNUNET_SERVICE_Client *client,
476 uint64_t request_id, 460 uint64_t request_id,
477 int result_af, 461 int result_af,
478 const void *addr) 462 const void *addr)
479{ 463{
480 struct GNUNET_MQ_Envelope *env; 464 struct GNUNET_MQ_Envelope *env;
481 struct RedirectToIpResponseMessage *res; 465 struct RedirectToIpResponseMessage *res;
482 size_t rlen; 466 size_t rlen;
483 467
484 switch (result_af) 468 switch (result_af)
485 { 469 {
486 case AF_INET: 470 case AF_INET:
487 rlen = sizeof (struct in_addr); 471 rlen = sizeof(struct in_addr);
488 break; 472 break;
489 case AF_INET6: 473
490 rlen = sizeof (struct in6_addr); 474 case AF_INET6:
491 break; 475 rlen = sizeof(struct in6_addr);
492 case AF_UNSPEC: 476 break;
493 rlen = 0; 477
494 break; 478 case AF_UNSPEC:
495 default: 479 rlen = 0;
496 GNUNET_assert (0); 480 break;
497 return; 481
498 } 482 default:
499 env = GNUNET_MQ_msg_extra (res, rlen, GNUNET_MESSAGE_TYPE_VPN_CLIENT_USE_IP); 483 GNUNET_assert(0);
500 res->result_af = htonl (result_af); 484 return;
485 }
486 env = GNUNET_MQ_msg_extra(res, rlen, GNUNET_MESSAGE_TYPE_VPN_CLIENT_USE_IP);
487 res->result_af = htonl(result_af);
501 res->request_id = request_id; 488 res->request_id = request_id;
502 GNUNET_memcpy (&res[1], addr, rlen); 489 GNUNET_memcpy(&res[1], addr, rlen);
503 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), env); 490 GNUNET_MQ_send(GNUNET_SERVICE_client_get_mq(client), env);
504} 491}
505 492
506 493
@@ -510,52 +497,52 @@ send_client_reply (struct GNUNET_SERVICE_Client *client,
510 * @param ts state to free 497 * @param ts state to free
511 */ 498 */
512static void 499static void
513free_channel_state (struct ChannelState *ts) 500free_channel_state(struct ChannelState *ts)
514{ 501{
515 struct GNUNET_HashCode key; 502 struct GNUNET_HashCode key;
516 struct ChannelMessageQueueEntry *tnq; 503 struct ChannelMessageQueueEntry *tnq;
517 struct GNUNET_CADET_Channel *channel; 504 struct GNUNET_CADET_Channel *channel;
518 505
519 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up channel state\n"); 506 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Cleaning up channel state\n");
520 if (NULL != (channel = ts->channel)) 507 if (NULL != (channel = ts->channel))
521 { 508 {
522 ts->channel = NULL; 509 ts->channel = NULL;
523 GNUNET_CADET_channel_destroy (channel); 510 GNUNET_CADET_channel_destroy(channel);
524 return; 511 return;
525 } 512 }
526 GNUNET_STATISTICS_update (stats, 513 GNUNET_STATISTICS_update(stats,
527 gettext_noop ("# Active channels"), 514 gettext_noop("# Active channels"),
528 -1, 515 -1,
529 GNUNET_NO); 516 GNUNET_NO);
530 while (NULL != (tnq = ts->tmq_head)) 517 while (NULL != (tnq = ts->tmq_head))
531 { 518 {
532 GNUNET_CONTAINER_DLL_remove (ts->tmq_head, ts->tmq_tail, tnq); 519 GNUNET_CONTAINER_DLL_remove(ts->tmq_head, ts->tmq_tail, tnq);
533 ts->tmq_length--; 520 ts->tmq_length--;
534 GNUNET_free (tnq); 521 GNUNET_free(tnq);
535 } 522 }
536 GNUNET_assert (0 == ts->tmq_length); 523 GNUNET_assert(0 == ts->tmq_length);
537 GNUNET_assert (NULL == ts->destination.heap_node); 524 GNUNET_assert(NULL == ts->destination.heap_node);
538 if (NULL != ts->search) 525 if (NULL != ts->search)
539 { 526 {
540 GNUNET_REGEX_search_cancel (ts->search); 527 GNUNET_REGEX_search_cancel(ts->search);
541 ts->search = NULL; 528 ts->search = NULL;
542 } 529 }
543 if (NULL != ts->heap_node) 530 if (NULL != ts->heap_node)
544 { 531 {
545 GNUNET_CONTAINER_heap_remove_node (ts->heap_node); 532 GNUNET_CONTAINER_heap_remove_node(ts->heap_node);
546 ts->heap_node = NULL; 533 ts->heap_node = NULL;
547 get_channel_key_from_ips (ts->af, 534 get_channel_key_from_ips(ts->af,
548 ts->protocol, 535 ts->protocol,
549 &ts->source_ip, 536 &ts->source_ip,
550 ts->source_port, 537 ts->source_port,
551 &ts->destination_ip, 538 &ts->destination_ip,
552 ts->destination_port, 539 ts->destination_port,
553 &key); 540 &key);
554 GNUNET_assert ( 541 GNUNET_assert(
555 GNUNET_YES == 542 GNUNET_YES ==
556 GNUNET_CONTAINER_multihashmap_remove (channel_map, &key, ts)); 543 GNUNET_CONTAINER_multihashmap_remove(channel_map, &key, ts));
557 } 544 }
558 GNUNET_free (ts); 545 GNUNET_free(ts);
559} 546}
560 547
561 548
@@ -567,27 +554,27 @@ free_channel_state (struct ChannelState *ts)
567 * @param env message to queue 554 * @param env message to queue
568 */ 555 */
569static void 556static void
570send_to_channel (struct ChannelState *ts, struct GNUNET_MQ_Envelope *env) 557send_to_channel(struct ChannelState *ts, struct GNUNET_MQ_Envelope *env)
571{ 558{
572 struct GNUNET_MQ_Handle *mq; 559 struct GNUNET_MQ_Handle *mq;
573 560
574 GNUNET_assert (NULL != ts->channel); 561 GNUNET_assert(NULL != ts->channel);
575 mq = GNUNET_CADET_get_mq (ts->channel); 562 mq = GNUNET_CADET_get_mq(ts->channel);
576 GNUNET_MQ_env_set_options (env, 563 GNUNET_MQ_env_set_options(env,
577 GNUNET_MQ_PRIO_BEST_EFFORT | 564 GNUNET_MQ_PRIO_BEST_EFFORT |
578 GNUNET_MQ_PREF_OUT_OF_ORDER); 565 GNUNET_MQ_PREF_OUT_OF_ORDER);
579 GNUNET_MQ_send (mq, env); 566 GNUNET_MQ_send(mq, env);
580 if (GNUNET_MQ_get_length (mq) > MAX_MESSAGE_QUEUE_SIZE) 567 if (GNUNET_MQ_get_length(mq) > MAX_MESSAGE_QUEUE_SIZE)
581 { 568 {
582 env = GNUNET_MQ_unsent_head (mq); 569 env = GNUNET_MQ_unsent_head(mq);
583 GNUNET_assert (NULL != env); 570 GNUNET_assert(NULL != env);
584 GNUNET_STATISTICS_update (stats, 571 GNUNET_STATISTICS_update(stats,
585 gettext_noop ( 572 gettext_noop(
586 "# Messages dropped in cadet queue (overflow)"), 573 "# Messages dropped in cadet queue (overflow)"),
587 1, 574 1,
588 GNUNET_NO); 575 GNUNET_NO);
589 GNUNET_MQ_discard (env); 576 GNUNET_MQ_discard(env);
590 } 577 }
591} 578}
592 579
593 580
@@ -598,26 +585,26 @@ send_to_channel (struct ChannelState *ts, struct GNUNET_MQ_Envelope *env)
598 * @return diagnostic string describing destination 585 * @return diagnostic string describing destination
599 */ 586 */
600static const char * 587static const char *
601print_channel_destination (const struct DestinationEntry *de) 588print_channel_destination(const struct DestinationEntry *de)
602{ 589{
603 static char dest[256]; 590 static char dest[256];
604 591
605 if (de->is_service) 592 if (de->is_service)
606 { 593 {
607 GNUNET_snprintf (dest, 594 GNUNET_snprintf(dest,
608 sizeof (dest), 595 sizeof(dest),
609 "HS: %s-%s", 596 "HS: %s-%s",
610 GNUNET_i2s (&de->details.service_destination.target), 597 GNUNET_i2s(&de->details.service_destination.target),
611 GNUNET_h2s ( 598 GNUNET_h2s(
612 &de->details.service_destination.service_descriptor)); 599 &de->details.service_destination.service_descriptor));
613 } 600 }
614 else 601 else
615 { 602 {
616 inet_ntop (de->details.exit_destination.af, 603 inet_ntop(de->details.exit_destination.af,
617 &de->details.exit_destination.ip, 604 &de->details.exit_destination.ip,
618 dest, 605 dest,
619 sizeof (dest)); 606 sizeof(dest));
620 } 607 }
621 return dest; 608 return dest;
622} 609}
623 610
@@ -630,16 +617,16 @@ print_channel_destination (const struct DestinationEntry *de)
630 * @param channel connection to the other end (henceforth invalid) 617 * @param channel connection to the other end (henceforth invalid)
631 */ 618 */
632static void 619static void
633channel_cleaner (void *cls, const struct GNUNET_CADET_Channel *channel) 620channel_cleaner(void *cls, const struct GNUNET_CADET_Channel *channel)
634{ 621{
635 struct ChannelState *ts = cls; 622 struct ChannelState *ts = cls;
636 623
637 ts->channel = 624 ts->channel =
638 NULL; /* we must not call GNUNET_CADET_channel_destroy() anymore */ 625 NULL; /* we must not call GNUNET_CADET_channel_destroy() anymore */
639 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 626 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
640 "CADET notified us about death of channel to `%s'\n", 627 "CADET notified us about death of channel to `%s'\n",
641 print_channel_destination (&ts->destination)); 628 print_channel_destination(&ts->destination));
642 free_channel_state (ts); 629 free_channel_state(ts);
643} 630}
644 631
645 632
@@ -653,19 +640,19 @@ channel_cleaner (void *cls, const struct GNUNET_CADET_Channel *channel)
653 * also be the first 8 bytes of the TCP header 640 * also be the first 8 bytes of the TCP header
654 */ 641 */
655static void 642static void
656make_up_icmpv4_payload (struct ChannelState *ts, 643make_up_icmpv4_payload(struct ChannelState *ts,
657 struct GNUNET_TUN_IPv4Header *ipp, 644 struct GNUNET_TUN_IPv4Header *ipp,
658 struct GNUNET_TUN_UdpHeader *udp) 645 struct GNUNET_TUN_UdpHeader *udp)
659{ 646{
660 GNUNET_TUN_initialize_ipv4_header (ipp, 647 GNUNET_TUN_initialize_ipv4_header(ipp,
661 ts->protocol, 648 ts->protocol,
662 sizeof (struct GNUNET_TUN_TcpHeader), 649 sizeof(struct GNUNET_TUN_TcpHeader),
663 &ts->source_ip.v4, 650 &ts->source_ip.v4,
664 &ts->destination_ip.v4); 651 &ts->destination_ip.v4);
665 udp->source_port = htons (ts->source_port); 652 udp->source_port = htons(ts->source_port);
666 udp->destination_port = htons (ts->destination_port); 653 udp->destination_port = htons(ts->destination_port);
667 udp->len = htons (0); 654 udp->len = htons(0);
668 udp->crc = htons (0); 655 udp->crc = htons(0);
669} 656}
670 657
671 658
@@ -679,19 +666,19 @@ make_up_icmpv4_payload (struct ChannelState *ts,
679 * also be the first 8 bytes of the TCP header 666 * also be the first 8 bytes of the TCP header
680 */ 667 */
681static void 668static void
682make_up_icmpv6_payload (struct ChannelState *ts, 669make_up_icmpv6_payload(struct ChannelState *ts,
683 struct GNUNET_TUN_IPv6Header *ipp, 670 struct GNUNET_TUN_IPv6Header *ipp,
684 struct GNUNET_TUN_UdpHeader *udp) 671 struct GNUNET_TUN_UdpHeader *udp)
685{ 672{
686 GNUNET_TUN_initialize_ipv6_header (ipp, 673 GNUNET_TUN_initialize_ipv6_header(ipp,
687 ts->protocol, 674 ts->protocol,
688 sizeof (struct GNUNET_TUN_TcpHeader), 675 sizeof(struct GNUNET_TUN_TcpHeader),
689 &ts->source_ip.v6, 676 &ts->source_ip.v6,
690 &ts->destination_ip.v6); 677 &ts->destination_ip.v6);
691 udp->source_port = htons (ts->source_port); 678 udp->source_port = htons(ts->source_port);
692 udp->destination_port = htons (ts->destination_port); 679 udp->destination_port = htons(ts->destination_port);
693 udp->len = htons (0); 680 udp->len = htons(0);
694 udp->crc = htons (0); 681 udp->crc = htons(0);
695} 682}
696 683
697 684
@@ -704,20 +691,20 @@ make_up_icmpv6_payload (struct ChannelState *ts,
704 * #GNUNET_SYSERR to close it (signal serious error) 691 * #GNUNET_SYSERR to close it (signal serious error)
705 */ 692 */
706static int 693static int
707check_icmp_back (void *cls, const struct GNUNET_EXIT_IcmpToVPNMessage *i2v) 694check_icmp_back(void *cls, const struct GNUNET_EXIT_IcmpToVPNMessage *i2v)
708{ 695{
709 struct ChannelState *ts = cls; 696 struct ChannelState *ts = cls;
710 697
711 if (NULL == ts->heap_node) 698 if (NULL == ts->heap_node)
712 { 699 {
713 GNUNET_break_op (0); 700 GNUNET_break_op(0);
714 return GNUNET_SYSERR; 701 return GNUNET_SYSERR;
715 } 702 }
716 if (AF_UNSPEC == ts->af) 703 if (AF_UNSPEC == ts->af)
717 { 704 {
718 GNUNET_break_op (0); 705 GNUNET_break_op(0);
719 return GNUNET_SYSERR; 706 return GNUNET_SYSERR;
720 } 707 }
721 return GNUNET_OK; 708 return GNUNET_OK;
722} 709}
723 710
@@ -730,324 +717,344 @@ check_icmp_back (void *cls, const struct GNUNET_EXIT_IcmpToVPNMessage *i2v)
730 * @param message the actual message 717 * @param message the actual message
731 */ 718 */
732static void 719static void
733handle_icmp_back (void *cls, const struct GNUNET_EXIT_IcmpToVPNMessage *i2v) 720handle_icmp_back(void *cls, const struct GNUNET_EXIT_IcmpToVPNMessage *i2v)
734{ 721{
735 struct ChannelState *ts = cls; 722 struct ChannelState *ts = cls;
736 size_t mlen; 723 size_t mlen;
737 724
738 GNUNET_STATISTICS_update (stats, 725 GNUNET_STATISTICS_update(stats,
739 gettext_noop ("# ICMP packets received from cadet"), 726 gettext_noop("# ICMP packets received from cadet"),
740 1, 727 1,
741 GNUNET_NO); 728 GNUNET_NO);
742 mlen = 729 mlen =
743 ntohs (i2v->header.size) - sizeof (struct GNUNET_EXIT_IcmpToVPNMessage); 730 ntohs(i2v->header.size) - sizeof(struct GNUNET_EXIT_IcmpToVPNMessage);
744 { 731 {
745 char sbuf[INET6_ADDRSTRLEN]; 732 char sbuf[INET6_ADDRSTRLEN];
746 char dbuf[INET6_ADDRSTRLEN]; 733 char dbuf[INET6_ADDRSTRLEN];
747 734
748 GNUNET_log ( 735 GNUNET_log(
749 GNUNET_ERROR_TYPE_DEBUG, 736 GNUNET_ERROR_TYPE_DEBUG,
750 "Received ICMP packet from cadet, sending %u bytes from %s -> %s via TUN\n", 737 "Received ICMP packet from cadet, sending %u bytes from %s -> %s via TUN\n",
751 (unsigned int) mlen, 738 (unsigned int)mlen,
752 inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof (sbuf)), 739 inet_ntop(ts->af, &ts->destination_ip, sbuf, sizeof(sbuf)),
753 inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof (dbuf))); 740 inet_ntop(ts->af, &ts->source_ip, dbuf, sizeof(dbuf)));
754 } 741 }
755 switch (ts->af) 742 switch (ts->af)
756 {
757 case AF_INET: {
758 size_t size = sizeof (struct GNUNET_TUN_IPv4Header) +
759 sizeof (struct GNUNET_TUN_IcmpHeader) +
760 sizeof (struct GNUNET_MessageHeader) +
761 sizeof (struct GNUNET_TUN_Layer2PacketHeader) + mlen;
762 { 743 {
763 /* reserve some extra space in case we have an ICMP type here where 744 case AF_INET: {
764 we will need to make up the payload ourselves */ 745 size_t size = sizeof(struct GNUNET_TUN_IPv4Header) +
765 char buf[size + sizeof (struct GNUNET_TUN_IPv4Header) + 8] GNUNET_ALIGN; 746 sizeof(struct GNUNET_TUN_IcmpHeader) +
766 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; 747 sizeof(struct GNUNET_MessageHeader) +
767 struct GNUNET_TUN_Layer2PacketHeader *tun = 748 sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
768 (struct GNUNET_TUN_Layer2PacketHeader *) &msg[1];
769 struct GNUNET_TUN_IPv4Header *ipv4 =
770 (struct GNUNET_TUN_IPv4Header *) &tun[1];
771 struct GNUNET_TUN_IcmpHeader *icmp =
772 (struct GNUNET_TUN_IcmpHeader *) &ipv4[1];
773 msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
774 tun->flags = htons (0);
775 tun->proto = htons (ETH_P_IPV4);
776 GNUNET_TUN_initialize_ipv4_header (ipv4,
777 IPPROTO_ICMP,
778 sizeof (struct GNUNET_TUN_IcmpHeader) +
779 mlen,
780 &ts->destination_ip.v4,
781 &ts->source_ip.v4);
782 *icmp = i2v->icmp_header;
783 GNUNET_memcpy (&icmp[1], &i2v[1], mlen);
784 /* For some ICMP types, we need to adjust (make up) the payload here.
785 Also, depending on the AF used on the other side, we have to
786 do ICMP PT (translate ICMP types) */
787 switch (ntohl (i2v->af))
788 { 749 {
789 case AF_INET: 750 /* reserve some extra space in case we have an ICMP type here where
790 switch (icmp->type) 751 we will need to make up the payload ourselves */
791 { 752 char buf[size + sizeof(struct GNUNET_TUN_IPv4Header) + 8] GNUNET_ALIGN;
792 case GNUNET_TUN_ICMPTYPE_ECHO_REPLY: 753 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *)buf;
793 case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST: 754 struct GNUNET_TUN_Layer2PacketHeader *tun =
794 break; 755 (struct GNUNET_TUN_Layer2PacketHeader *)&msg[1];
795 case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE: 756 struct GNUNET_TUN_IPv4Header *ipv4 =
796 case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH: 757 (struct GNUNET_TUN_IPv4Header *)&tun[1];
797 case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED: { 758 struct GNUNET_TUN_IcmpHeader *icmp =
798 struct GNUNET_TUN_IPv4Header *ipp = 759 (struct GNUNET_TUN_IcmpHeader *)&ipv4[1];
799 (struct GNUNET_TUN_IPv4Header *) &icmp[1]; 760 msg->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
800 struct GNUNET_TUN_UdpHeader *udp = 761 tun->flags = htons(0);
801 (struct GNUNET_TUN_UdpHeader *) &ipp[1]; 762 tun->proto = htons(ETH_P_IPV4);
802 763 GNUNET_TUN_initialize_ipv4_header(ipv4,
803 if (mlen != 0) 764 IPPROTO_ICMP,
765 sizeof(struct GNUNET_TUN_IcmpHeader) +
766 mlen,
767 &ts->destination_ip.v4,
768 &ts->source_ip.v4);
769 *icmp = i2v->icmp_header;
770 GNUNET_memcpy(&icmp[1], &i2v[1], mlen);
771 /* For some ICMP types, we need to adjust (make up) the payload here.
772 Also, depending on the AF used on the other side, we have to
773 do ICMP PT (translate ICMP types) */
774 switch (ntohl(i2v->af))
804 { 775 {
805 /* sender did not strip ICMP payload? */ 776 case AF_INET:
806 GNUNET_break_op (0); 777 switch (icmp->type)
778 {
779 case GNUNET_TUN_ICMPTYPE_ECHO_REPLY:
780 case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST:
781 break;
782
783 case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE:
784 case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH:
785 case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED: {
786 struct GNUNET_TUN_IPv4Header *ipp =
787 (struct GNUNET_TUN_IPv4Header *)&icmp[1];
788 struct GNUNET_TUN_UdpHeader *udp =
789 (struct GNUNET_TUN_UdpHeader *)&ipp[1];
790
791 if (mlen != 0)
792 {
793 /* sender did not strip ICMP payload? */
794 GNUNET_break_op(0);
795 return;
796 }
797 size += sizeof(struct GNUNET_TUN_IPv4Header) + 8;
798 GNUNET_assert(8 == sizeof(struct GNUNET_TUN_UdpHeader));
799 make_up_icmpv4_payload(ts, ipp, udp);
800 }
801 break;
802
803 default:
804 GNUNET_break_op(0);
805 GNUNET_STATISTICS_update(
806 stats,
807 gettext_noop("# ICMPv4 packets dropped (type not allowed)"),
808 1,
809 GNUNET_NO);
810 return;
811 }
812 /* end AF_INET */
813 break;
814
815 case AF_INET6:
816 /* ICMP PT 6-to-4 and possibly making up payloads */
817 switch (icmp->type)
818 {
819 case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE:
820 icmp->type = GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE;
821 {
822 struct GNUNET_TUN_IPv4Header *ipp =
823 (struct GNUNET_TUN_IPv4Header *)&icmp[1];
824 struct GNUNET_TUN_UdpHeader *udp =
825 (struct GNUNET_TUN_UdpHeader *)&ipp[1];
826
827 if (mlen != 0)
828 {
829 /* sender did not strip ICMP payload? */
830 GNUNET_break_op(0);
831 return;
832 }
833 size += sizeof(struct GNUNET_TUN_IPv4Header) + 8;
834 GNUNET_assert(8 == sizeof(struct GNUNET_TUN_UdpHeader));
835 make_up_icmpv4_payload(ts, ipp, udp);
836 }
837 break;
838
839 case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED:
840 icmp->type = GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED;
841 {
842 struct GNUNET_TUN_IPv4Header *ipp =
843 (struct GNUNET_TUN_IPv4Header *)&icmp[1];
844 struct GNUNET_TUN_UdpHeader *udp =
845 (struct GNUNET_TUN_UdpHeader *)&ipp[1];
846
847 if (mlen != 0)
848 {
849 /* sender did not strip ICMP payload? */
850 GNUNET_break_op(0);
851 return;
852 }
853 size += sizeof(struct GNUNET_TUN_IPv4Header) + 8;
854 GNUNET_assert(8 == sizeof(struct GNUNET_TUN_UdpHeader));
855 make_up_icmpv4_payload(ts, ipp, udp);
856 }
857 break;
858
859 case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG:
860 case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM:
861 GNUNET_STATISTICS_update(
862 stats,
863 gettext_noop("# ICMPv6 packets dropped (impossible PT to v4)"),
864 1,
865 GNUNET_NO);
866 return;
867
868 case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST:
869 icmp->type = GNUNET_TUN_ICMPTYPE_ECHO_REQUEST;
870 break;
871
872 case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY:
873 icmp->type = GNUNET_TUN_ICMPTYPE_ECHO_REPLY;
874 break;
875
876 default:
877 GNUNET_break_op(0);
878 GNUNET_STATISTICS_update(
879 stats,
880 gettext_noop("# ICMPv6 packets dropped (type not allowed)"),
881 1,
882 GNUNET_NO);
883 return;
884 }
885 /* end AF_INET6 */
886 break;
887
888 default:
889 GNUNET_break_op(0);
807 return; 890 return;
808 } 891 }
809 size += sizeof (struct GNUNET_TUN_IPv4Header) + 8; 892 msg->size = htons(size);
810 GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); 893 GNUNET_TUN_calculate_icmp_checksum(icmp, &i2v[1], mlen);
811 make_up_icmpv4_payload (ts, ipp, udp); 894 (void)GNUNET_HELPER_send(helper_handle, msg, GNUNET_YES, NULL, NULL);
812 }
813 break;
814 default:
815 GNUNET_break_op (0);
816 GNUNET_STATISTICS_update (
817 stats,
818 gettext_noop ("# ICMPv4 packets dropped (type not allowed)"),
819 1,
820 GNUNET_NO);
821 return;
822 }
823 /* end AF_INET */
824 break;
825 case AF_INET6:
826 /* ICMP PT 6-to-4 and possibly making up payloads */
827 switch (icmp->type)
828 {
829 case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE:
830 icmp->type = GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE;
831 {
832 struct GNUNET_TUN_IPv4Header *ipp =
833 (struct GNUNET_TUN_IPv4Header *) &icmp[1];
834 struct GNUNET_TUN_UdpHeader *udp =
835 (struct GNUNET_TUN_UdpHeader *) &ipp[1];
836
837 if (mlen != 0)
838 {
839 /* sender did not strip ICMP payload? */
840 GNUNET_break_op (0);
841 return;
842 }
843 size += sizeof (struct GNUNET_TUN_IPv4Header) + 8;
844 GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
845 make_up_icmpv4_payload (ts, ipp, udp);
846 }
847 break;
848 case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED:
849 icmp->type = GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED;
850 {
851 struct GNUNET_TUN_IPv4Header *ipp =
852 (struct GNUNET_TUN_IPv4Header *) &icmp[1];
853 struct GNUNET_TUN_UdpHeader *udp =
854 (struct GNUNET_TUN_UdpHeader *) &ipp[1];
855
856 if (mlen != 0)
857 {
858 /* sender did not strip ICMP payload? */
859 GNUNET_break_op (0);
860 return;
861 }
862 size += sizeof (struct GNUNET_TUN_IPv4Header) + 8;
863 GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
864 make_up_icmpv4_payload (ts, ipp, udp);
865 }
866 break;
867 case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG:
868 case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM:
869 GNUNET_STATISTICS_update (
870 stats,
871 gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"),
872 1,
873 GNUNET_NO);
874 return;
875 case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST:
876 icmp->type = GNUNET_TUN_ICMPTYPE_ECHO_REQUEST;
877 break;
878 case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY:
879 icmp->type = GNUNET_TUN_ICMPTYPE_ECHO_REPLY;
880 break;
881 default:
882 GNUNET_break_op (0);
883 GNUNET_STATISTICS_update (
884 stats,
885 gettext_noop ("# ICMPv6 packets dropped (type not allowed)"),
886 1,
887 GNUNET_NO);
888 return;
889 }
890 /* end AF_INET6 */
891 break;
892 default:
893 GNUNET_break_op (0);
894 return;
895 } 895 }
896 msg->size = htons (size);
897 GNUNET_TUN_calculate_icmp_checksum (icmp, &i2v[1], mlen);
898 (void) GNUNET_HELPER_send (helper_handle, msg, GNUNET_YES, NULL, NULL);
899 } 896 }
900 } 897 break;
901 break;
902 case AF_INET6: {
903 size_t size = sizeof (struct GNUNET_TUN_IPv6Header) +
904 sizeof (struct GNUNET_TUN_IcmpHeader) +
905 sizeof (struct GNUNET_MessageHeader) +
906 sizeof (struct GNUNET_TUN_Layer2PacketHeader) + mlen;
907 {
908 char buf[size + sizeof (struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
909 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
910 struct GNUNET_TUN_Layer2PacketHeader *tun =
911 (struct GNUNET_TUN_Layer2PacketHeader *) &msg[1];
912 struct GNUNET_TUN_IPv6Header *ipv6 =
913 (struct GNUNET_TUN_IPv6Header *) &tun[1];
914 struct GNUNET_TUN_IcmpHeader *icmp =
915 (struct GNUNET_TUN_IcmpHeader *) &ipv6[1];
916 msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
917 tun->flags = htons (0);
918 tun->proto = htons (ETH_P_IPV6);
919 GNUNET_TUN_initialize_ipv6_header (ipv6,
920 IPPROTO_ICMPV6,
921 sizeof (struct GNUNET_TUN_IcmpHeader) +
922 mlen,
923 &ts->destination_ip.v6,
924 &ts->source_ip.v6);
925 *icmp = i2v->icmp_header;
926 GNUNET_memcpy (&icmp[1], &i2v[1], mlen);
927
928 /* For some ICMP types, we need to adjust (make up) the payload here.
929 Also, depending on the AF used on the other side, we have to
930 do ICMP PT (translate ICMP types) */
931 switch (ntohl (i2v->af))
932 {
933 case AF_INET:
934 /* ICMP PT 4-to-6 and possibly making up payloads */
935 switch (icmp->type)
936 {
937 case GNUNET_TUN_ICMPTYPE_ECHO_REPLY:
938 icmp->type = GNUNET_TUN_ICMPTYPE6_ECHO_REPLY;
939 break;
940 case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST:
941 icmp->type = GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST;
942 break;
943 case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE:
944 icmp->type = GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE;
945 {
946 struct GNUNET_TUN_IPv6Header *ipp =
947 (struct GNUNET_TUN_IPv6Header *) &icmp[1];
948 struct GNUNET_TUN_UdpHeader *udp =
949 (struct GNUNET_TUN_UdpHeader *) &ipp[1];
950
951 if (mlen != 0)
952 {
953 /* sender did not strip ICMP payload? */
954 GNUNET_break_op (0);
955 return;
956 }
957 size += sizeof (struct GNUNET_TUN_IPv6Header) + 8;
958 GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
959 make_up_icmpv6_payload (ts, ipp, udp);
960 }
961 break;
962 case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED:
963 icmp->type = GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED;
964 {
965 struct GNUNET_TUN_IPv6Header *ipp =
966 (struct GNUNET_TUN_IPv6Header *) &icmp[1];
967 struct GNUNET_TUN_UdpHeader *udp =
968 (struct GNUNET_TUN_UdpHeader *) &ipp[1];
969 898
970 if (mlen != 0) 899 case AF_INET6: {
971 { 900 size_t size = sizeof(struct GNUNET_TUN_IPv6Header) +
972 /* sender did not strip ICMP payload? */ 901 sizeof(struct GNUNET_TUN_IcmpHeader) +
973 GNUNET_break_op (0); 902 sizeof(struct GNUNET_MessageHeader) +
974 return; 903 sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
975 } 904 {
976 size += sizeof (struct GNUNET_TUN_IPv6Header) + 8; 905 char buf[size + sizeof(struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
977 GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); 906 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *)buf;
978 make_up_icmpv6_payload (ts, ipp, udp); 907 struct GNUNET_TUN_Layer2PacketHeader *tun =
979 } 908 (struct GNUNET_TUN_Layer2PacketHeader *)&msg[1];
980 break; 909 struct GNUNET_TUN_IPv6Header *ipv6 =
981 case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH: 910 (struct GNUNET_TUN_IPv6Header *)&tun[1];
982 GNUNET_STATISTICS_update ( 911 struct GNUNET_TUN_IcmpHeader *icmp =
983 stats, 912 (struct GNUNET_TUN_IcmpHeader *)&ipv6[1];
984 gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"), 913 msg->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
985 1, 914 tun->flags = htons(0);
986 GNUNET_NO); 915 tun->proto = htons(ETH_P_IPV6);
987 return; 916 GNUNET_TUN_initialize_ipv6_header(ipv6,
988 default: 917 IPPROTO_ICMPV6,
989 GNUNET_break_op (0); 918 sizeof(struct GNUNET_TUN_IcmpHeader) +
990 GNUNET_STATISTICS_update ( 919 mlen,
991 stats, 920 &ts->destination_ip.v6,
992 gettext_noop ("# ICMPv4 packets dropped (type not allowed)"), 921 &ts->source_ip.v6);
993 1, 922 *icmp = i2v->icmp_header;
994 GNUNET_NO); 923 GNUNET_memcpy(&icmp[1], &i2v[1], mlen);
995 return; 924
996 } 925 /* For some ICMP types, we need to adjust (make up) the payload here.
997 /* end AF_INET */ 926 Also, depending on the AF used on the other side, we have to
998 break; 927 do ICMP PT (translate ICMP types) */
999 case AF_INET6: 928 switch (ntohl(i2v->af))
1000 switch (icmp->type)
1001 {
1002 case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE:
1003 case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED:
1004 case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG:
1005 case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM: {
1006 struct GNUNET_TUN_IPv6Header *ipp =
1007 (struct GNUNET_TUN_IPv6Header *) &icmp[1];
1008 struct GNUNET_TUN_UdpHeader *udp =
1009 (struct GNUNET_TUN_UdpHeader *) &ipp[1];
1010
1011 if (mlen != 0)
1012 { 929 {
1013 /* sender did not strip ICMP payload? */ 930 case AF_INET:
1014 GNUNET_break_op (0); 931 /* ICMP PT 4-to-6 and possibly making up payloads */
932 switch (icmp->type)
933 {
934 case GNUNET_TUN_ICMPTYPE_ECHO_REPLY:
935 icmp->type = GNUNET_TUN_ICMPTYPE6_ECHO_REPLY;
936 break;
937
938 case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST:
939 icmp->type = GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST;
940 break;
941
942 case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE:
943 icmp->type = GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE;
944 {
945 struct GNUNET_TUN_IPv6Header *ipp =
946 (struct GNUNET_TUN_IPv6Header *)&icmp[1];
947 struct GNUNET_TUN_UdpHeader *udp =
948 (struct GNUNET_TUN_UdpHeader *)&ipp[1];
949
950 if (mlen != 0)
951 {
952 /* sender did not strip ICMP payload? */
953 GNUNET_break_op(0);
954 return;
955 }
956 size += sizeof(struct GNUNET_TUN_IPv6Header) + 8;
957 GNUNET_assert(8 == sizeof(struct GNUNET_TUN_UdpHeader));
958 make_up_icmpv6_payload(ts, ipp, udp);
959 }
960 break;
961
962 case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED:
963 icmp->type = GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED;
964 {
965 struct GNUNET_TUN_IPv6Header *ipp =
966 (struct GNUNET_TUN_IPv6Header *)&icmp[1];
967 struct GNUNET_TUN_UdpHeader *udp =
968 (struct GNUNET_TUN_UdpHeader *)&ipp[1];
969
970 if (mlen != 0)
971 {
972 /* sender did not strip ICMP payload? */
973 GNUNET_break_op(0);
974 return;
975 }
976 size += sizeof(struct GNUNET_TUN_IPv6Header) + 8;
977 GNUNET_assert(8 == sizeof(struct GNUNET_TUN_UdpHeader));
978 make_up_icmpv6_payload(ts, ipp, udp);
979 }
980 break;
981
982 case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH:
983 GNUNET_STATISTICS_update(
984 stats,
985 gettext_noop("# ICMPv4 packets dropped (impossible PT to v6)"),
986 1,
987 GNUNET_NO);
988 return;
989
990 default:
991 GNUNET_break_op(0);
992 GNUNET_STATISTICS_update(
993 stats,
994 gettext_noop("# ICMPv4 packets dropped (type not allowed)"),
995 1,
996 GNUNET_NO);
997 return;
998 }
999 /* end AF_INET */
1000 break;
1001
1002 case AF_INET6:
1003 switch (icmp->type)
1004 {
1005 case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE:
1006 case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED:
1007 case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG:
1008 case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM: {
1009 struct GNUNET_TUN_IPv6Header *ipp =
1010 (struct GNUNET_TUN_IPv6Header *)&icmp[1];
1011 struct GNUNET_TUN_UdpHeader *udp =
1012 (struct GNUNET_TUN_UdpHeader *)&ipp[1];
1013
1014 if (mlen != 0)
1015 {
1016 /* sender did not strip ICMP payload? */
1017 GNUNET_break_op(0);
1018 return;
1019 }
1020 size += sizeof(struct GNUNET_TUN_IPv6Header) + 8;
1021 GNUNET_assert(8 == sizeof(struct GNUNET_TUN_UdpHeader));
1022 make_up_icmpv6_payload(ts, ipp, udp);
1023 }
1024 break;
1025
1026 case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST:
1027 break;
1028
1029 default:
1030 GNUNET_break_op(0);
1031 GNUNET_STATISTICS_update(
1032 stats,
1033 gettext_noop("# ICMPv6 packets dropped (type not allowed)"),
1034 1,
1035 GNUNET_NO);
1036 return;
1037 }
1038 /* end AF_INET6 */
1039 break;
1040
1041 default:
1042 GNUNET_break_op(0);
1015 return; 1043 return;
1016 } 1044 }
1017 size += sizeof (struct GNUNET_TUN_IPv6Header) + 8; 1045 msg->size = htons(size);
1018 GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); 1046 GNUNET_TUN_calculate_icmp_checksum(icmp, &i2v[1], mlen);
1019 make_up_icmpv6_payload (ts, ipp, udp); 1047 (void)GNUNET_HELPER_send(helper_handle, msg, GNUNET_YES, NULL, NULL);
1020 }
1021 break;
1022 case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST:
1023 break;
1024 default:
1025 GNUNET_break_op (0);
1026 GNUNET_STATISTICS_update (
1027 stats,
1028 gettext_noop ("# ICMPv6 packets dropped (type not allowed)"),
1029 1,
1030 GNUNET_NO);
1031 return;
1032 }
1033 /* end AF_INET6 */
1034 break;
1035 default:
1036 GNUNET_break_op (0);
1037 return;
1038 } 1048 }
1039 msg->size = htons (size);
1040 GNUNET_TUN_calculate_icmp_checksum (icmp, &i2v[1], mlen);
1041 (void) GNUNET_HELPER_send (helper_handle, msg, GNUNET_YES, NULL, NULL);
1042 } 1049 }
1043 } 1050 break;
1044 break; 1051
1045 default: 1052 default:
1046 GNUNET_assert (0); 1053 GNUNET_assert(0);
1047 } 1054 }
1048 GNUNET_CONTAINER_heap_update_cost (ts->heap_node, 1055 GNUNET_CONTAINER_heap_update_cost(ts->heap_node,
1049 GNUNET_TIME_absolute_get ().abs_value_us); 1056 GNUNET_TIME_absolute_get().abs_value_us);
1050 GNUNET_CADET_receive_done (ts->channel); 1057 GNUNET_CADET_receive_done(ts->channel);
1051} 1058}
1052 1059
1053 1060
@@ -1060,20 +1067,20 @@ handle_icmp_back (void *cls, const struct GNUNET_EXIT_IcmpToVPNMessage *i2v)
1060 * #GNUNET_SYSERR to close it (signal serious error) 1067 * #GNUNET_SYSERR to close it (signal serious error)
1061 */ 1068 */
1062static int 1069static int
1063check_udp_back (void *cls, const struct GNUNET_EXIT_UdpReplyMessage *reply) 1070check_udp_back(void *cls, const struct GNUNET_EXIT_UdpReplyMessage *reply)
1064{ 1071{
1065 struct ChannelState *ts = cls; 1072 struct ChannelState *ts = cls;
1066 1073
1067 if (NULL == ts->heap_node) 1074 if (NULL == ts->heap_node)
1068 { 1075 {
1069 GNUNET_break_op (0); 1076 GNUNET_break_op(0);
1070 return GNUNET_SYSERR; 1077 return GNUNET_SYSERR;
1071 } 1078 }
1072 if (AF_UNSPEC == ts->af) 1079 if (AF_UNSPEC == ts->af)
1073 { 1080 {
1074 GNUNET_break_op (0); 1081 GNUNET_break_op(0);
1075 return GNUNET_SYSERR; 1082 return GNUNET_SYSERR;
1076 } 1083 }
1077 return GNUNET_OK; 1084 return GNUNET_OK;
1078} 1085}
1079 1086
@@ -1086,116 +1093,118 @@ check_udp_back (void *cls, const struct GNUNET_EXIT_UdpReplyMessage *reply)
1086 * @param reply the actual message 1093 * @param reply the actual message
1087 */ 1094 */
1088static void 1095static void
1089handle_udp_back (void *cls, const struct GNUNET_EXIT_UdpReplyMessage *reply) 1096handle_udp_back(void *cls, const struct GNUNET_EXIT_UdpReplyMessage *reply)
1090{ 1097{
1091 struct ChannelState *ts = cls; 1098 struct ChannelState *ts = cls;
1092 size_t mlen; 1099 size_t mlen;
1093 1100
1094 GNUNET_STATISTICS_update (stats, 1101 GNUNET_STATISTICS_update(stats,
1095 gettext_noop ("# UDP packets received from cadet"), 1102 gettext_noop("# UDP packets received from cadet"),
1096 1, 1103 1,
1097 GNUNET_NO); 1104 GNUNET_NO);
1098 mlen = 1105 mlen =
1099 ntohs (reply->header.size) - sizeof (struct GNUNET_EXIT_UdpReplyMessage); 1106 ntohs(reply->header.size) - sizeof(struct GNUNET_EXIT_UdpReplyMessage);
1100 { 1107 {
1101 char sbuf[INET6_ADDRSTRLEN]; 1108 char sbuf[INET6_ADDRSTRLEN];
1102 char dbuf[INET6_ADDRSTRLEN]; 1109 char dbuf[INET6_ADDRSTRLEN];
1103 1110
1104 GNUNET_log ( 1111 GNUNET_log(
1105 GNUNET_ERROR_TYPE_DEBUG, 1112 GNUNET_ERROR_TYPE_DEBUG,
1106 "Received UDP reply from cadet, sending %u bytes from [%s]:%u -> [%s]:%u via TUN\n", 1113 "Received UDP reply from cadet, sending %u bytes from [%s]:%u -> [%s]:%u via TUN\n",
1107 (unsigned int) mlen, 1114 (unsigned int)mlen,
1108 inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof (sbuf)), 1115 inet_ntop(ts->af, &ts->destination_ip, sbuf, sizeof(sbuf)),
1109 ts->destination_port, 1116 ts->destination_port,
1110 inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof (dbuf)), 1117 inet_ntop(ts->af, &ts->source_ip, dbuf, sizeof(dbuf)),
1111 ts->source_port); 1118 ts->source_port);
1112 } 1119 }
1113 switch (ts->af) 1120 switch (ts->af)
1114 {
1115 case AF_INET: {
1116 size_t size = sizeof (struct GNUNET_TUN_IPv4Header) +
1117 sizeof (struct GNUNET_TUN_UdpHeader) +
1118 sizeof (struct GNUNET_MessageHeader) +
1119 sizeof (struct GNUNET_TUN_Layer2PacketHeader) + mlen;
1120 { 1121 {
1121 char buf[size] GNUNET_ALIGN; 1122 case AF_INET: {
1122 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; 1123 size_t size = sizeof(struct GNUNET_TUN_IPv4Header) +
1123 struct GNUNET_TUN_Layer2PacketHeader *tun = 1124 sizeof(struct GNUNET_TUN_UdpHeader) +
1124 (struct GNUNET_TUN_Layer2PacketHeader *) &msg[1]; 1125 sizeof(struct GNUNET_MessageHeader) +
1125 struct GNUNET_TUN_IPv4Header *ipv4 = 1126 sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
1126 (struct GNUNET_TUN_IPv4Header *) &tun[1]; 1127 {
1127 struct GNUNET_TUN_UdpHeader *udp = 1128 char buf[size] GNUNET_ALIGN;
1128 (struct GNUNET_TUN_UdpHeader *) &ipv4[1]; 1129 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *)buf;
1129 msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); 1130 struct GNUNET_TUN_Layer2PacketHeader *tun =
1130 msg->size = htons (size); 1131 (struct GNUNET_TUN_Layer2PacketHeader *)&msg[1];
1131 tun->flags = htons (0); 1132 struct GNUNET_TUN_IPv4Header *ipv4 =
1132 tun->proto = htons (ETH_P_IPV4); 1133 (struct GNUNET_TUN_IPv4Header *)&tun[1];
1133 GNUNET_TUN_initialize_ipv4_header (ipv4, 1134 struct GNUNET_TUN_UdpHeader *udp =
1134 IPPROTO_UDP, 1135 (struct GNUNET_TUN_UdpHeader *)&ipv4[1];
1135 sizeof (struct GNUNET_TUN_UdpHeader) + 1136 msg->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
1136 mlen, 1137 msg->size = htons(size);
1137 &ts->destination_ip.v4, 1138 tun->flags = htons(0);
1138 &ts->source_ip.v4); 1139 tun->proto = htons(ETH_P_IPV4);
1139 if (0 == ntohs (reply->source_port)) 1140 GNUNET_TUN_initialize_ipv4_header(ipv4,
1140 udp->source_port = htons (ts->destination_port); 1141 IPPROTO_UDP,
1141 else 1142 sizeof(struct GNUNET_TUN_UdpHeader) +
1142 udp->source_port = reply->source_port; 1143 mlen,
1143 if (0 == ntohs (reply->destination_port)) 1144 &ts->destination_ip.v4,
1144 udp->destination_port = htons (ts->source_port); 1145 &ts->source_ip.v4);
1145 else 1146 if (0 == ntohs(reply->source_port))
1146 udp->destination_port = reply->destination_port; 1147 udp->source_port = htons(ts->destination_port);
1147 udp->len = htons (mlen + sizeof (struct GNUNET_TUN_UdpHeader)); 1148 else
1148 GNUNET_TUN_calculate_udp4_checksum (ipv4, udp, &reply[1], mlen); 1149 udp->source_port = reply->source_port;
1149 GNUNET_memcpy (&udp[1], &reply[1], mlen); 1150 if (0 == ntohs(reply->destination_port))
1150 (void) GNUNET_HELPER_send (helper_handle, msg, GNUNET_YES, NULL, NULL); 1151 udp->destination_port = htons(ts->source_port);
1152 else
1153 udp->destination_port = reply->destination_port;
1154 udp->len = htons(mlen + sizeof(struct GNUNET_TUN_UdpHeader));
1155 GNUNET_TUN_calculate_udp4_checksum(ipv4, udp, &reply[1], mlen);
1156 GNUNET_memcpy(&udp[1], &reply[1], mlen);
1157 (void)GNUNET_HELPER_send(helper_handle, msg, GNUNET_YES, NULL, NULL);
1158 }
1151 } 1159 }
1152 } 1160 break;
1153 break; 1161
1154 case AF_INET6: { 1162 case AF_INET6: {
1155 size_t size = sizeof (struct GNUNET_TUN_IPv6Header) + 1163 size_t size = sizeof(struct GNUNET_TUN_IPv6Header) +
1156 sizeof (struct GNUNET_TUN_UdpHeader) + 1164 sizeof(struct GNUNET_TUN_UdpHeader) +
1157 sizeof (struct GNUNET_MessageHeader) + 1165 sizeof(struct GNUNET_MessageHeader) +
1158 sizeof (struct GNUNET_TUN_Layer2PacketHeader) + mlen; 1166 sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
1159 { 1167 {
1160 char buf[size] GNUNET_ALIGN; 1168 char buf[size] GNUNET_ALIGN;
1161 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; 1169 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *)buf;
1162 struct GNUNET_TUN_Layer2PacketHeader *tun = 1170 struct GNUNET_TUN_Layer2PacketHeader *tun =
1163 (struct GNUNET_TUN_Layer2PacketHeader *) &msg[1]; 1171 (struct GNUNET_TUN_Layer2PacketHeader *)&msg[1];
1164 struct GNUNET_TUN_IPv6Header *ipv6 = 1172 struct GNUNET_TUN_IPv6Header *ipv6 =
1165 (struct GNUNET_TUN_IPv6Header *) &tun[1]; 1173 (struct GNUNET_TUN_IPv6Header *)&tun[1];
1166 struct GNUNET_TUN_UdpHeader *udp = 1174 struct GNUNET_TUN_UdpHeader *udp =
1167 (struct GNUNET_TUN_UdpHeader *) &ipv6[1]; 1175 (struct GNUNET_TUN_UdpHeader *)&ipv6[1];
1168 msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); 1176 msg->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
1169 msg->size = htons (size); 1177 msg->size = htons(size);
1170 tun->flags = htons (0); 1178 tun->flags = htons(0);
1171 tun->proto = htons (ETH_P_IPV6); 1179 tun->proto = htons(ETH_P_IPV6);
1172 GNUNET_TUN_initialize_ipv6_header (ipv6, 1180 GNUNET_TUN_initialize_ipv6_header(ipv6,
1173 IPPROTO_UDP, 1181 IPPROTO_UDP,
1174 sizeof (struct GNUNET_TUN_UdpHeader) + 1182 sizeof(struct GNUNET_TUN_UdpHeader) +
1175 mlen, 1183 mlen,
1176 &ts->destination_ip.v6, 1184 &ts->destination_ip.v6,
1177 &ts->source_ip.v6); 1185 &ts->source_ip.v6);
1178 if (0 == ntohs (reply->source_port)) 1186 if (0 == ntohs(reply->source_port))
1179 udp->source_port = htons (ts->destination_port); 1187 udp->source_port = htons(ts->destination_port);
1180 else 1188 else
1181 udp->source_port = reply->source_port; 1189 udp->source_port = reply->source_port;
1182 if (0 == ntohs (reply->destination_port)) 1190 if (0 == ntohs(reply->destination_port))
1183 udp->destination_port = htons (ts->source_port); 1191 udp->destination_port = htons(ts->source_port);
1184 else 1192 else
1185 udp->destination_port = reply->destination_port; 1193 udp->destination_port = reply->destination_port;
1186 udp->len = htons (mlen + sizeof (struct GNUNET_TUN_UdpHeader)); 1194 udp->len = htons(mlen + sizeof(struct GNUNET_TUN_UdpHeader));
1187 GNUNET_TUN_calculate_udp6_checksum (ipv6, udp, &reply[1], mlen); 1195 GNUNET_TUN_calculate_udp6_checksum(ipv6, udp, &reply[1], mlen);
1188 GNUNET_memcpy (&udp[1], &reply[1], mlen); 1196 GNUNET_memcpy(&udp[1], &reply[1], mlen);
1189 (void) GNUNET_HELPER_send (helper_handle, msg, GNUNET_YES, NULL, NULL); 1197 (void)GNUNET_HELPER_send(helper_handle, msg, GNUNET_YES, NULL, NULL);
1198 }
1190 } 1199 }
1191 } 1200 break;
1192 break; 1201
1193 default: 1202 default:
1194 GNUNET_assert (0); 1203 GNUNET_assert(0);
1195 } 1204 }
1196 GNUNET_CONTAINER_heap_update_cost (ts->heap_node, 1205 GNUNET_CONTAINER_heap_update_cost(ts->heap_node,
1197 GNUNET_TIME_absolute_get ().abs_value_us); 1206 GNUNET_TIME_absolute_get().abs_value_us);
1198 GNUNET_CADET_receive_done (ts->channel); 1207 GNUNET_CADET_receive_done(ts->channel);
1199} 1208}
1200 1209
1201 1210
@@ -1208,20 +1217,20 @@ handle_udp_back (void *cls, const struct GNUNET_EXIT_UdpReplyMessage *reply)
1208 * #GNUNET_SYSERR to close it (signal serious error) 1217 * #GNUNET_SYSERR to close it (signal serious error)
1209 */ 1218 */
1210static int 1219static int
1211check_tcp_back (void *cls, const struct GNUNET_EXIT_TcpDataMessage *data) 1220check_tcp_back(void *cls, const struct GNUNET_EXIT_TcpDataMessage *data)
1212{ 1221{
1213 struct ChannelState *ts = cls; 1222 struct ChannelState *ts = cls;
1214 1223
1215 if (NULL == ts->heap_node) 1224 if (NULL == ts->heap_node)
1216 { 1225 {
1217 GNUNET_break_op (0); 1226 GNUNET_break_op(0);
1218 return GNUNET_SYSERR; 1227 return GNUNET_SYSERR;
1219 } 1228 }
1220 if (data->tcp_header.off * 4 < sizeof (struct GNUNET_TUN_TcpHeader)) 1229 if (data->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
1221 { 1230 {
1222 GNUNET_break_op (0); 1231 GNUNET_break_op(0);
1223 return GNUNET_SYSERR; 1232 return GNUNET_SYSERR;
1224 } 1233 }
1225 return GNUNET_OK; 1234 return GNUNET_OK;
1226} 1235}
1227 1236
@@ -1234,101 +1243,102 @@ check_tcp_back (void *cls, const struct GNUNET_EXIT_TcpDataMessage *data)
1234 * @param data the actual message 1243 * @param data the actual message
1235 */ 1244 */
1236static void 1245static void
1237handle_tcp_back (void *cls, const struct GNUNET_EXIT_TcpDataMessage *data) 1246handle_tcp_back(void *cls, const struct GNUNET_EXIT_TcpDataMessage *data)
1238{ 1247{
1239 struct ChannelState *ts = cls; 1248 struct ChannelState *ts = cls;
1240 size_t mlen; 1249 size_t mlen;
1241 1250
1242 GNUNET_STATISTICS_update (stats, 1251 GNUNET_STATISTICS_update(stats,
1243 gettext_noop ("# TCP packets received from cadet"), 1252 gettext_noop("# TCP packets received from cadet"),
1244 1, 1253 1,
1245 GNUNET_NO); 1254 GNUNET_NO);
1246 mlen = ntohs (data->header.size) - sizeof (struct GNUNET_EXIT_TcpDataMessage); 1255 mlen = ntohs(data->header.size) - sizeof(struct GNUNET_EXIT_TcpDataMessage);
1247 { 1256 {
1248 char sbuf[INET6_ADDRSTRLEN]; 1257 char sbuf[INET6_ADDRSTRLEN];
1249 char dbuf[INET6_ADDRSTRLEN]; 1258 char dbuf[INET6_ADDRSTRLEN];
1250 1259
1251 GNUNET_log ( 1260 GNUNET_log(
1252 GNUNET_ERROR_TYPE_DEBUG, 1261 GNUNET_ERROR_TYPE_DEBUG,
1253 "Received TCP reply from cadet, sending %u bytes from [%s]:%u -> [%s]:%u via TUN\n", 1262 "Received TCP reply from cadet, sending %u bytes from [%s]:%u -> [%s]:%u via TUN\n",
1254 (unsigned int) mlen, 1263 (unsigned int)mlen,
1255 inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof (sbuf)), 1264 inet_ntop(ts->af, &ts->destination_ip, sbuf, sizeof(sbuf)),
1256 ts->destination_port, 1265 ts->destination_port,
1257 inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof (dbuf)), 1266 inet_ntop(ts->af, &ts->source_ip, dbuf, sizeof(dbuf)),
1258 ts->source_port); 1267 ts->source_port);
1259 } 1268 }
1260 switch (ts->af) 1269 switch (ts->af)
1261 {
1262 case AF_INET: {
1263 size_t size = sizeof (struct GNUNET_TUN_IPv4Header) +
1264 sizeof (struct GNUNET_TUN_TcpHeader) +
1265 sizeof (struct GNUNET_MessageHeader) +
1266 sizeof (struct GNUNET_TUN_Layer2PacketHeader) + mlen;
1267 { 1270 {
1268 char buf[size] GNUNET_ALIGN; 1271 case AF_INET: {
1269 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; 1272 size_t size = sizeof(struct GNUNET_TUN_IPv4Header) +
1270 struct GNUNET_TUN_Layer2PacketHeader *tun = 1273 sizeof(struct GNUNET_TUN_TcpHeader) +
1271 (struct GNUNET_TUN_Layer2PacketHeader *) &msg[1]; 1274 sizeof(struct GNUNET_MessageHeader) +
1272 struct GNUNET_TUN_IPv4Header *ipv4 = 1275 sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
1273 (struct GNUNET_TUN_IPv4Header *) &tun[1]; 1276 {
1274 struct GNUNET_TUN_TcpHeader *tcp = 1277 char buf[size] GNUNET_ALIGN;
1275 (struct GNUNET_TUN_TcpHeader *) &ipv4[1]; 1278 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *)buf;
1276 msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); 1279 struct GNUNET_TUN_Layer2PacketHeader *tun =
1277 msg->size = htons (size); 1280 (struct GNUNET_TUN_Layer2PacketHeader *)&msg[1];
1278 tun->flags = htons (0); 1281 struct GNUNET_TUN_IPv4Header *ipv4 =
1279 tun->proto = htons (ETH_P_IPV4); 1282 (struct GNUNET_TUN_IPv4Header *)&tun[1];
1280 GNUNET_TUN_initialize_ipv4_header (ipv4, 1283 struct GNUNET_TUN_TcpHeader *tcp =
1281 IPPROTO_TCP, 1284 (struct GNUNET_TUN_TcpHeader *)&ipv4[1];
1282 sizeof (struct GNUNET_TUN_TcpHeader) + 1285 msg->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
1283 mlen, 1286 msg->size = htons(size);
1284 &ts->destination_ip.v4, 1287 tun->flags = htons(0);
1285 &ts->source_ip.v4); 1288 tun->proto = htons(ETH_P_IPV4);
1286 *tcp = data->tcp_header; 1289 GNUNET_TUN_initialize_ipv4_header(ipv4,
1287 tcp->source_port = htons (ts->destination_port); 1290 IPPROTO_TCP,
1288 tcp->destination_port = htons (ts->source_port); 1291 sizeof(struct GNUNET_TUN_TcpHeader) +
1289 GNUNET_TUN_calculate_tcp4_checksum (ipv4, tcp, &data[1], mlen); 1292 mlen,
1290 GNUNET_memcpy (&tcp[1], &data[1], mlen); 1293 &ts->destination_ip.v4,
1291 (void) GNUNET_HELPER_send (helper_handle, msg, GNUNET_YES, NULL, NULL); 1294 &ts->source_ip.v4);
1295 *tcp = data->tcp_header;
1296 tcp->source_port = htons(ts->destination_port);
1297 tcp->destination_port = htons(ts->source_port);
1298 GNUNET_TUN_calculate_tcp4_checksum(ipv4, tcp, &data[1], mlen);
1299 GNUNET_memcpy(&tcp[1], &data[1], mlen);
1300 (void)GNUNET_HELPER_send(helper_handle, msg, GNUNET_YES, NULL, NULL);
1301 }
1292 } 1302 }
1293 } 1303 break;
1294 break; 1304
1295 case AF_INET6: { 1305 case AF_INET6: {
1296 size_t size = sizeof (struct GNUNET_TUN_IPv6Header) + 1306 size_t size = sizeof(struct GNUNET_TUN_IPv6Header) +
1297 sizeof (struct GNUNET_TUN_TcpHeader) + 1307 sizeof(struct GNUNET_TUN_TcpHeader) +
1298 sizeof (struct GNUNET_MessageHeader) + 1308 sizeof(struct GNUNET_MessageHeader) +
1299 sizeof (struct GNUNET_TUN_Layer2PacketHeader) + mlen; 1309 sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
1300 { 1310 {
1301 char buf[size] GNUNET_ALIGN; 1311 char buf[size] GNUNET_ALIGN;
1302 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; 1312 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *)buf;
1303 struct GNUNET_TUN_Layer2PacketHeader *tun = 1313 struct GNUNET_TUN_Layer2PacketHeader *tun =
1304 (struct GNUNET_TUN_Layer2PacketHeader *) &msg[1]; 1314 (struct GNUNET_TUN_Layer2PacketHeader *)&msg[1];
1305 struct GNUNET_TUN_IPv6Header *ipv6 = 1315 struct GNUNET_TUN_IPv6Header *ipv6 =
1306 (struct GNUNET_TUN_IPv6Header *) &tun[1]; 1316 (struct GNUNET_TUN_IPv6Header *)&tun[1];
1307 struct GNUNET_TUN_TcpHeader *tcp = 1317 struct GNUNET_TUN_TcpHeader *tcp =
1308 (struct GNUNET_TUN_TcpHeader *) &ipv6[1]; 1318 (struct GNUNET_TUN_TcpHeader *)&ipv6[1];
1309 msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); 1319 msg->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
1310 msg->size = htons (size); 1320 msg->size = htons(size);
1311 tun->flags = htons (0); 1321 tun->flags = htons(0);
1312 tun->proto = htons (ETH_P_IPV6); 1322 tun->proto = htons(ETH_P_IPV6);
1313 GNUNET_TUN_initialize_ipv6_header (ipv6, 1323 GNUNET_TUN_initialize_ipv6_header(ipv6,
1314 IPPROTO_TCP, 1324 IPPROTO_TCP,
1315 sizeof (struct GNUNET_TUN_TcpHeader) + 1325 sizeof(struct GNUNET_TUN_TcpHeader) +
1316 mlen, 1326 mlen,
1317 &ts->destination_ip.v6, 1327 &ts->destination_ip.v6,
1318 &ts->source_ip.v6); 1328 &ts->source_ip.v6);
1319 *tcp = data->tcp_header; 1329 *tcp = data->tcp_header;
1320 tcp->source_port = htons (ts->destination_port); 1330 tcp->source_port = htons(ts->destination_port);
1321 tcp->destination_port = htons (ts->source_port); 1331 tcp->destination_port = htons(ts->source_port);
1322 GNUNET_TUN_calculate_tcp6_checksum (ipv6, tcp, &data[1], mlen); 1332 GNUNET_TUN_calculate_tcp6_checksum(ipv6, tcp, &data[1], mlen);
1323 GNUNET_memcpy (&tcp[1], &data[1], mlen); 1333 GNUNET_memcpy(&tcp[1], &data[1], mlen);
1324 (void) GNUNET_HELPER_send (helper_handle, msg, GNUNET_YES, NULL, NULL); 1334 (void)GNUNET_HELPER_send(helper_handle, msg, GNUNET_YES, NULL, NULL);
1335 }
1325 } 1336 }
1326 } 1337 break;
1327 break; 1338 }
1328 } 1339 GNUNET_CONTAINER_heap_update_cost(ts->heap_node,
1329 GNUNET_CONTAINER_heap_update_cost (ts->heap_node, 1340 GNUNET_TIME_absolute_get().abs_value_us);
1330 GNUNET_TIME_absolute_get ().abs_value_us); 1341 GNUNET_CADET_receive_done(ts->channel);
1331 GNUNET_CADET_receive_done (ts->channel);
1332} 1342}
1333 1343
1334 1344
@@ -1341,32 +1351,32 @@ handle_tcp_back (void *cls, const struct GNUNET_EXIT_TcpDataMessage *data)
1341 * @return the channel handle 1351 * @return the channel handle
1342 */ 1352 */
1343static struct GNUNET_CADET_Channel * 1353static struct GNUNET_CADET_Channel *
1344create_channel (struct ChannelState *ts, 1354create_channel(struct ChannelState *ts,
1345 const struct GNUNET_PeerIdentity *target, 1355 const struct GNUNET_PeerIdentity *target,
1346 const struct GNUNET_HashCode *port) 1356 const struct GNUNET_HashCode *port)
1347{ 1357{
1348 struct GNUNET_MQ_MessageHandler cadet_handlers[] = 1358 struct GNUNET_MQ_MessageHandler cadet_handlers[] =
1349 {GNUNET_MQ_hd_var_size (udp_back, 1359 { GNUNET_MQ_hd_var_size(udp_back,
1350 GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY, 1360 GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY,
1351 struct GNUNET_EXIT_UdpReplyMessage, 1361 struct GNUNET_EXIT_UdpReplyMessage,
1352 ts), 1362 ts),
1353 GNUNET_MQ_hd_var_size (tcp_back, 1363 GNUNET_MQ_hd_var_size(tcp_back,
1354 GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_VPN, 1364 GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_VPN,
1355 struct GNUNET_EXIT_TcpDataMessage, 1365 struct GNUNET_EXIT_TcpDataMessage,
1356 ts), 1366 ts),
1357 GNUNET_MQ_hd_var_size (icmp_back, 1367 GNUNET_MQ_hd_var_size(icmp_back,
1358 GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_VPN, 1368 GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_VPN,
1359 struct GNUNET_EXIT_IcmpToVPNMessage, 1369 struct GNUNET_EXIT_IcmpToVPNMessage,
1360 ts), 1370 ts),
1361 GNUNET_MQ_handler_end ()}; 1371 GNUNET_MQ_handler_end() };
1362 1372
1363 return GNUNET_CADET_channel_create (cadet_handle, 1373 return GNUNET_CADET_channel_create(cadet_handle,
1364 ts, 1374 ts,
1365 target, 1375 target,
1366 port, 1376 port,
1367 NULL, 1377 NULL,
1368 &channel_cleaner, 1378 &channel_cleaner,
1369 cadet_handlers); 1379 cadet_handlers);
1370} 1380}
1371 1381
1372 1382
@@ -1381,45 +1391,47 @@ create_channel (struct ChannelState *ts,
1381 * @param put_path_length Length of the @a put_path. 1391 * @param put_path_length Length of the @a put_path.
1382 */ 1392 */
1383static void 1393static void
1384handle_regex_result (void *cls, 1394handle_regex_result(void *cls,
1385 const struct GNUNET_PeerIdentity *id, 1395 const struct GNUNET_PeerIdentity *id,
1386 const struct GNUNET_PeerIdentity *get_path, 1396 const struct GNUNET_PeerIdentity *get_path,
1387 unsigned int get_path_length, 1397 unsigned int get_path_length,
1388 const struct GNUNET_PeerIdentity *put_path, 1398 const struct GNUNET_PeerIdentity *put_path,
1389 unsigned int put_path_length) 1399 unsigned int put_path_length)
1390{ 1400{
1391 struct ChannelState *ts = cls; 1401 struct ChannelState *ts = cls;
1392 struct GNUNET_HashCode port; 1402 struct GNUNET_HashCode port;
1393 1403
1394 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1404 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1395 "Exit %s found for destination %s!\n", 1405 "Exit %s found for destination %s!\n",
1396 GNUNET_i2s (id), 1406 GNUNET_i2s(id),
1397 print_channel_destination (&ts->destination)); 1407 print_channel_destination(&ts->destination));
1398 GNUNET_REGEX_search_cancel (ts->search); 1408 GNUNET_REGEX_search_cancel(ts->search);
1399 ts->search = NULL; 1409 ts->search = NULL;
1400 switch (ts->af) 1410 switch (ts->af)
1401 { 1411 {
1402 case AF_INET: 1412 case AF_INET:
1403 /* these must match the strings used in gnunet-daemon-exit */ 1413 /* these must match the strings used in gnunet-daemon-exit */
1404 GNUNET_CRYPTO_hash (GNUNET_APPLICATION_PORT_IPV4_GATEWAY, 1414 GNUNET_CRYPTO_hash(GNUNET_APPLICATION_PORT_IPV4_GATEWAY,
1405 strlen (GNUNET_APPLICATION_PORT_IPV4_GATEWAY), 1415 strlen(GNUNET_APPLICATION_PORT_IPV4_GATEWAY),
1406 &port); 1416 &port);
1407 break; 1417 break;
1408 case AF_INET6: 1418
1409 /* these must match the strings used in gnunet-daemon-exit */ 1419 case AF_INET6:
1410 GNUNET_CRYPTO_hash (GNUNET_APPLICATION_PORT_IPV6_GATEWAY, 1420 /* these must match the strings used in gnunet-daemon-exit */
1411 strlen (GNUNET_APPLICATION_PORT_IPV6_GATEWAY), 1421 GNUNET_CRYPTO_hash(GNUNET_APPLICATION_PORT_IPV6_GATEWAY,
1412 &port); 1422 strlen(GNUNET_APPLICATION_PORT_IPV6_GATEWAY),
1413 break; 1423 &port);
1414 default: 1424 break;
1415 GNUNET_break (0); 1425
1416 return; 1426 default:
1417 } 1427 GNUNET_break(0);
1418 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1428 return;
1419 "Creating tunnel to %s for destination %s!\n", 1429 }
1420 GNUNET_i2s (id), 1430 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1421 print_channel_destination (&ts->destination)); 1431 "Creating tunnel to %s for destination %s!\n",
1422 ts->channel = create_channel (ts, id, &port); 1432 GNUNET_i2s(id),
1433 print_channel_destination(&ts->destination));
1434 ts->channel = create_channel(ts, id, &port);
1423} 1435}
1424 1436
1425 1437
@@ -1431,90 +1443,92 @@ handle_regex_result (void *cls,
1431 * @return channel state of the channel that was created 1443 * @return channel state of the channel that was created
1432 */ 1444 */
1433static struct ChannelState * 1445static struct ChannelState *
1434create_channel_to_destination (struct DestinationChannel *dt, int client_af) 1446create_channel_to_destination(struct DestinationChannel *dt, int client_af)
1435{ 1447{
1436 struct ChannelState *ts; 1448 struct ChannelState *ts;
1437 1449
1438 GNUNET_STATISTICS_update (stats, 1450 GNUNET_STATISTICS_update(stats,
1439 gettext_noop ("# Cadet channels created"), 1451 gettext_noop("# Cadet channels created"),
1440 1, 1452 1,
1441 GNUNET_NO); 1453 GNUNET_NO);
1442 ts = GNUNET_new (struct ChannelState); 1454 ts = GNUNET_new(struct ChannelState);
1443 ts->af = client_af; 1455 ts->af = client_af;
1444 ts->destination = *dt->destination; 1456 ts->destination = *dt->destination;
1445 ts->destination.heap_node = NULL; /* copy is NOT in destination heap */ 1457 ts->destination.heap_node = NULL; /* copy is NOT in destination heap */
1446 ts->destination_port = dt->destination_port; 1458 ts->destination_port = dt->destination_port;
1447 if (dt->destination->is_service) 1459 if (dt->destination->is_service)
1448 {
1449 struct GNUNET_HashCode cadet_port;
1450
1451 GNUNET_TUN_compute_service_cadet_port (&ts->destination.details
1452 .service_destination
1453 .service_descriptor,
1454 ts->destination_port,
1455 &cadet_port);
1456 ts->channel =
1457 create_channel (ts,
1458 &dt->destination->details.service_destination.target,
1459 &cadet_port);
1460
1461 if (NULL == ts->channel)
1462 { 1460 {
1463 GNUNET_break (0); 1461 struct GNUNET_HashCode cadet_port;
1464 GNUNET_free (ts); 1462
1465 return NULL; 1463 GNUNET_TUN_compute_service_cadet_port(&ts->destination.details
1466 } 1464 .service_destination
1467 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1465 .service_descriptor,
1468 "Creating channel to peer %s offering service %s on port %u\n", 1466 ts->destination_port,
1469 GNUNET_i2s ( 1467 &cadet_port);
1470 &dt->destination->details.service_destination.target), 1468 ts->channel =
1471 GNUNET_h2s (&ts->destination.details.service_destination 1469 create_channel(ts,
1472 .service_descriptor), 1470 &dt->destination->details.service_destination.target,
1473 (unsigned int) ts->destination_port); 1471 &cadet_port);
1474 } 1472
1473 if (NULL == ts->channel)
1474 {
1475 GNUNET_break(0);
1476 GNUNET_free(ts);
1477 return NULL;
1478 }
1479 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1480 "Creating channel to peer %s offering service %s on port %u\n",
1481 GNUNET_i2s(
1482 &dt->destination->details.service_destination.target),
1483 GNUNET_h2s(&ts->destination.details.service_destination
1484 .service_descriptor),
1485 (unsigned int)ts->destination_port);
1486 }
1475 else 1487 else
1476 {
1477 char *policy;
1478
1479 switch (dt->destination->details.exit_destination.af)
1480 { 1488 {
1481 case AF_INET: { 1489 char *policy;
1482 char address[GNUNET_TUN_IPV4_REGEXLEN];
1483 1490
1484 GNUNET_TUN_ipv4toregexsearch (&dt->destination->details.exit_destination 1491 switch (dt->destination->details.exit_destination.af)
1492 {
1493 case AF_INET: {
1494 char address[GNUNET_TUN_IPV4_REGEXLEN];
1495
1496 GNUNET_TUN_ipv4toregexsearch(&dt->destination->details.exit_destination
1485 .ip.v4, 1497 .ip.v4,
1486 dt->destination_port, 1498 dt->destination_port,
1487 address); 1499 address);
1488 GNUNET_asprintf (&policy, 1500 GNUNET_asprintf(&policy,
1489 "%s%s", 1501 "%s%s",
1490 GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX, 1502 GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX,
1491 address); 1503 address);
1492 break; 1504 break;
1493 } 1505 }
1494 case AF_INET6: { 1506
1495 char address[GNUNET_TUN_IPV6_REGEXLEN]; 1507 case AF_INET6: {
1508 char address[GNUNET_TUN_IPV6_REGEXLEN];
1496 1509
1497 GNUNET_TUN_ipv6toregexsearch (&dt->destination->details.exit_destination 1510 GNUNET_TUN_ipv6toregexsearch(&dt->destination->details.exit_destination
1498 .ip.v6, 1511 .ip.v6,
1499 dt->destination_port, 1512 dt->destination_port,
1500 address); 1513 address);
1501 GNUNET_asprintf (&policy, 1514 GNUNET_asprintf(&policy,
1502 "%s%s", 1515 "%s%s",
1503 GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX, 1516 GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX,
1504 address); 1517 address);
1505 break; 1518 break;
1506 } 1519 }
1507 default:
1508 GNUNET_assert (0);
1509 break;
1510 }
1511 1520
1512 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1521 default:
1513 "Requesting connect by string: %s\n", 1522 GNUNET_assert(0);
1514 policy); 1523 break;
1515 ts->search = GNUNET_REGEX_search (cfg, policy, &handle_regex_result, ts); 1524 }
1516 GNUNET_free (policy); 1525
1517 } 1526 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1527 "Requesting connect by string: %s\n",
1528 policy);
1529 ts->search = GNUNET_REGEX_search(cfg, policy, &handle_regex_result, ts);
1530 GNUNET_free(policy);
1531 }
1518 return ts; 1532 return ts;
1519} 1533}
1520 1534
@@ -1525,18 +1539,18 @@ create_channel_to_destination (struct DestinationChannel *dt, int client_af)
1525 * @param except channel that must NOT be cleaned up, even if it is the oldest 1539 * @param except channel that must NOT be cleaned up, even if it is the oldest
1526 */ 1540 */
1527static void 1541static void
1528expire_channel (struct ChannelState *except) 1542expire_channel(struct ChannelState *except)
1529{ 1543{
1530 struct ChannelState *ts; 1544 struct ChannelState *ts;
1531 1545
1532 ts = GNUNET_CONTAINER_heap_peek (channel_heap); 1546 ts = GNUNET_CONTAINER_heap_peek(channel_heap);
1533 GNUNET_assert (NULL != ts); 1547 GNUNET_assert(NULL != ts);
1534 if (except == ts) 1548 if (except == ts)
1535 return; /* can't do this */ 1549 return; /* can't do this */
1536 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1550 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1537 "Tearing down expired channel to %s\n", 1551 "Tearing down expired channel to %s\n",
1538 print_channel_destination (&except->destination)); 1552 print_channel_destination(&except->destination));
1539 free_channel_state (ts); 1553 free_channel_state(ts);
1540} 1554}
1541 1555
1542 1556
@@ -1552,13 +1566,13 @@ expire_channel (struct ChannelState *except)
1552 * @param payload_length number of bytes in @a payload 1566 * @param payload_length number of bytes in @a payload
1553 */ 1567 */
1554static void 1568static void
1555route_packet (struct DestinationEntry *destination, 1569route_packet(struct DestinationEntry *destination,
1556 int af, 1570 int af,
1557 uint8_t protocol, 1571 uint8_t protocol,
1558 const void *source_ip, 1572 const void *source_ip,
1559 const void *destination_ip, 1573 const void *destination_ip,
1560 const void *payload, 1574 const void *payload,
1561 size_t payload_length) 1575 size_t payload_length)
1562{ 1576{
1563 struct GNUNET_HashCode key; 1577 struct GNUNET_HashCode key;
1564 struct ChannelState *ts; 1578 struct ChannelState *ts;
@@ -1573,630 +1587,663 @@ route_packet (struct DestinationEntry *destination,
1573 uint16_t destination_port; 1587 uint16_t destination_port;
1574 1588
1575 switch (protocol) 1589 switch (protocol)
1576 {
1577 case IPPROTO_UDP: {
1578 if (payload_length < sizeof (struct GNUNET_TUN_UdpHeader))
1579 {
1580 /* blame kernel? */
1581 GNUNET_break (0);
1582 return;
1583 }
1584 tcp = NULL; /* make compiler happy */
1585 icmp = NULL; /* make compiler happy */
1586 udp = payload;
1587 if (udp->len < sizeof (struct GNUNET_TUN_UdpHeader))
1588 { 1590 {
1589 GNUNET_break_op (0); 1591 case IPPROTO_UDP: {
1590 return; 1592 if (payload_length < sizeof(struct GNUNET_TUN_UdpHeader))
1591 } 1593 {
1592 source_port = ntohs (udp->source_port); 1594 /* blame kernel? */
1593 destination_port = ntohs (udp->destination_port); 1595 GNUNET_break(0);
1594 get_channel_key_from_ips (af, 1596 return;
1595 IPPROTO_UDP, 1597 }
1596 source_ip, 1598 tcp = NULL; /* make compiler happy */
1597 source_port, 1599 icmp = NULL; /* make compiler happy */
1598 destination_ip, 1600 udp = payload;
1599 destination_port, 1601 if (udp->len < sizeof(struct GNUNET_TUN_UdpHeader))
1600 &key); 1602 {
1601 } 1603 GNUNET_break_op(0);
1602 break; 1604 return;
1603 case IPPROTO_TCP: { 1605 }
1604 if (payload_length < sizeof (struct GNUNET_TUN_TcpHeader)) 1606 source_port = ntohs(udp->source_port);
1605 { 1607 destination_port = ntohs(udp->destination_port);
1606 /* blame kernel? */ 1608 get_channel_key_from_ips(af,
1607 GNUNET_break (0); 1609 IPPROTO_UDP,
1608 return; 1610 source_ip,
1611 source_port,
1612 destination_ip,
1613 destination_port,
1614 &key);
1609 } 1615 }
1610 udp = NULL; /* make compiler happy */ 1616 break;
1611 icmp = NULL; /* make compiler happy */ 1617
1612 tcp = payload; 1618 case IPPROTO_TCP: {
1613 if (tcp->off * 4 < sizeof (struct GNUNET_TUN_TcpHeader)) 1619 if (payload_length < sizeof(struct GNUNET_TUN_TcpHeader))
1614 { 1620 {
1615 GNUNET_break_op (0); 1621 /* blame kernel? */
1616 return; 1622 GNUNET_break(0);
1623 return;
1624 }
1625 udp = NULL; /* make compiler happy */
1626 icmp = NULL; /* make compiler happy */
1627 tcp = payload;
1628 if (tcp->off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
1629 {
1630 GNUNET_break_op(0);
1631 return;
1632 }
1633 source_port = ntohs(tcp->source_port);
1634 destination_port = ntohs(tcp->destination_port);
1635 get_channel_key_from_ips(af,
1636 IPPROTO_TCP,
1637 source_ip,
1638 source_port,
1639 destination_ip,
1640 destination_port,
1641 &key);
1617 } 1642 }
1618 source_port = ntohs (tcp->source_port); 1643 break;
1619 destination_port = ntohs (tcp->destination_port); 1644
1620 get_channel_key_from_ips (af, 1645 case IPPROTO_ICMP:
1621 IPPROTO_TCP, 1646 case IPPROTO_ICMPV6: {
1622 source_ip, 1647 if ((AF_INET == af) ^ (protocol == IPPROTO_ICMP))
1623 source_port, 1648 {
1624 destination_ip, 1649 GNUNET_break(0);
1625 destination_port, 1650 return;
1626 &key); 1651 }
1627 } 1652 if (payload_length < sizeof(struct GNUNET_TUN_IcmpHeader))
1628 break; 1653 {
1629 case IPPROTO_ICMP: 1654 /* blame kernel? */
1630 case IPPROTO_ICMPV6: { 1655 GNUNET_break(0);
1631 if ((AF_INET == af) ^ (protocol == IPPROTO_ICMP)) 1656 return;
1632 { 1657 }
1633 GNUNET_break (0); 1658 tcp = NULL; /* make compiler happy */
1634 return; 1659 udp = NULL; /* make compiler happy */
1660 icmp = payload;
1661 source_port = 0;
1662 destination_port = 0;
1663 get_channel_key_from_ips(af,
1664 protocol,
1665 source_ip,
1666 0,
1667 destination_ip,
1668 0,
1669 &key);
1635 } 1670 }
1636 if (payload_length < sizeof (struct GNUNET_TUN_IcmpHeader)) 1671 break;
1637 { 1672
1638 /* blame kernel? */ 1673 default:
1639 GNUNET_break (0); 1674 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1675 _("Protocol %u not supported, dropping\n"),
1676 (unsigned int)protocol);
1640 return; 1677 return;
1641 } 1678 }
1642 tcp = NULL; /* make compiler happy */
1643 udp = NULL; /* make compiler happy */
1644 icmp = payload;
1645 source_port = 0;
1646 destination_port = 0;
1647 get_channel_key_from_ips (af,
1648 protocol,
1649 source_ip,
1650 0,
1651 destination_ip,
1652 0,
1653 &key);
1654 }
1655 break;
1656 default:
1657 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1658 _ ("Protocol %u not supported, dropping\n"),
1659 (unsigned int) protocol);
1660 return;
1661 }
1662 alen = 0; 1679 alen = 0;
1663 if (! destination->is_service) 1680 if (!destination->is_service)
1664 {
1665 switch (destination->details.exit_destination.af)
1666 { 1681 {
1667 case AF_INET: 1682 switch (destination->details.exit_destination.af)
1668 alen = sizeof (struct in_addr); 1683 {
1669 break; 1684 case AF_INET:
1670 case AF_INET6: 1685 alen = sizeof(struct in_addr);
1671 alen = sizeof (struct in6_addr); 1686 break;
1672 break;
1673 default:
1674 GNUNET_assert (0);
1675 }
1676
1677 {
1678 char sbuf[INET6_ADDRSTRLEN];
1679 char dbuf[INET6_ADDRSTRLEN];
1680 char xbuf[INET6_ADDRSTRLEN];
1681
1682 GNUNET_log (
1683 GNUNET_ERROR_TYPE_DEBUG,
1684 "Routing %s packet from [%s]:%u -> [%s]:%u to destination [%s]:%u\n",
1685 (protocol == IPPROTO_TCP) ? "TCP" : "UDP",
1686 inet_ntop (af, source_ip, sbuf, sizeof (sbuf)),
1687 source_port,
1688 inet_ntop (af, destination_ip, dbuf, sizeof (dbuf)),
1689 destination_port,
1690 inet_ntop (destination->details.exit_destination.af,
1691 &destination->details.exit_destination.ip,
1692 xbuf,
1693 sizeof (xbuf)),
1694 destination_port);
1695 }
1696 for (dt = destination->dt_head; NULL != dt; dt = dt->next)
1697 if (dt->destination_port == destination_port)
1698 break;
1699 }
1700 else
1701 {
1702 {
1703 char sbuf[INET6_ADDRSTRLEN];
1704 char dbuf[INET6_ADDRSTRLEN];
1705
1706 GNUNET_log (
1707 GNUNET_ERROR_TYPE_DEBUG,
1708 "Routing %s packet from [%s]:%u -> [%s]:%u to service %s at peer %s\n",
1709 (protocol == IPPROTO_TCP) ? "TCP" : "UDP",
1710 inet_ntop (af, source_ip, sbuf, sizeof (sbuf)),
1711 source_port,
1712 inet_ntop (af, destination_ip, dbuf, sizeof (dbuf)),
1713 destination_port,
1714 GNUNET_h2s (
1715 &destination->details.service_destination.service_descriptor),
1716 GNUNET_i2s (&destination->details.service_destination.target));
1717 }
1718 for (dt = destination->dt_head; NULL != dt; dt = dt->next)
1719 if (dt->destination_port == destination_port)
1720 break;
1721 }
1722 if (NULL == dt)
1723 {
1724 dt = GNUNET_new (struct DestinationChannel);
1725 dt->destination = destination;
1726 GNUNET_CONTAINER_DLL_insert (destination->dt_head,
1727 destination->dt_tail,
1728 dt);
1729 dt->destination_port = destination_port;
1730 }
1731 1687
1732 /* see if we have an existing channel for this destination */ 1688 case AF_INET6:
1733 ts = GNUNET_CONTAINER_multihashmap_get (channel_map, &key); 1689 alen = sizeof(struct in6_addr);
1734 if (NULL == ts) 1690 break;
1735 {
1736 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1737 "Creating new channel for key %s\n",
1738 GNUNET_h2s (&key));
1739 /* need to either use the existing channel from the destination (if still
1740 available) or create a fresh one */
1741 ts = create_channel_to_destination (dt, af);
1742 if (NULL == ts)
1743 return;
1744 /* now bind existing "unbound" channel to our IP/port tuple */
1745 ts->protocol = protocol;
1746 ts->af = af;
1747 if (AF_INET == af)
1748 {
1749 ts->source_ip.v4 = *(const struct in_addr *) source_ip;
1750 ts->destination_ip.v4 = *(const struct in_addr *) destination_ip;
1751 }
1752 else
1753 {
1754 ts->source_ip.v6 = *(const struct in6_addr *) source_ip;
1755 ts->destination_ip.v6 = *(const struct in6_addr *) destination_ip;
1756 }
1757 ts->source_port = source_port;
1758 ts->destination_port = destination_port;
1759 ts->heap_node =
1760 GNUNET_CONTAINER_heap_insert (channel_heap,
1761 ts,
1762 GNUNET_TIME_absolute_get ().abs_value_us);
1763 GNUNET_assert (GNUNET_YES ==
1764 GNUNET_CONTAINER_multihashmap_put (
1765 channel_map,
1766 &key,
1767 ts,
1768 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1769 GNUNET_STATISTICS_update (stats,
1770 gettext_noop ("# Active channels"),
1771 1,
1772 GNUNET_NO);
1773 while (GNUNET_CONTAINER_multihashmap_size (channel_map) >
1774 max_channel_mappings)
1775 expire_channel (ts);
1776 }
1777 else
1778 {
1779 GNUNET_CONTAINER_heap_update_cost (ts->heap_node,
1780 GNUNET_TIME_absolute_get ()
1781 .abs_value_us);
1782 }
1783 if (NULL == ts->channel)
1784 {
1785 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1786 "Packet dropped, channel to %s not yet ready (%s)\n",
1787 print_channel_destination (&ts->destination),
1788 (NULL == ts->search) ? "EXIT search failed"
1789 : "EXIT search active");
1790 GNUNET_STATISTICS_update (stats,
1791 gettext_noop (
1792 "# Packets dropped (channel not yet online)"),
1793 1,
1794 GNUNET_NO);
1795 return;
1796 }
1797 1691
1798 /* send via channel */ 1692 default:
1799 switch (protocol) 1693 GNUNET_assert(0);
1800 { 1694 }
1801 case IPPROTO_UDP:
1802 if (destination->is_service)
1803 {
1804 struct GNUNET_EXIT_UdpServiceMessage *usm;
1805 1695
1806 mlen = sizeof (struct GNUNET_EXIT_UdpServiceMessage) + payload_length -
1807 sizeof (struct GNUNET_TUN_UdpHeader);
1808 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1809 { 1696 {
1810 GNUNET_break (0); 1697 char sbuf[INET6_ADDRSTRLEN];
1811 return; 1698 char dbuf[INET6_ADDRSTRLEN];
1699 char xbuf[INET6_ADDRSTRLEN];
1700
1701 GNUNET_log(
1702 GNUNET_ERROR_TYPE_DEBUG,
1703 "Routing %s packet from [%s]:%u -> [%s]:%u to destination [%s]:%u\n",
1704 (protocol == IPPROTO_TCP) ? "TCP" : "UDP",
1705 inet_ntop(af, source_ip, sbuf, sizeof(sbuf)),
1706 source_port,
1707 inet_ntop(af, destination_ip, dbuf, sizeof(dbuf)),
1708 destination_port,
1709 inet_ntop(destination->details.exit_destination.af,
1710 &destination->details.exit_destination.ip,
1711 xbuf,
1712 sizeof(xbuf)),
1713 destination_port);
1812 } 1714 }
1813 env = GNUNET_MQ_msg_extra (usm, 1715 for (dt = destination->dt_head; NULL != dt; dt = dt->next)
1814 payload_length - 1716 if (dt->destination_port == destination_port)
1815 sizeof (struct GNUNET_TUN_UdpHeader), 1717 break;
1816 GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE); 1718 }
1817 /* if the source port is below 32000, we assume it has a special 1719 else
1818 meaning; if not, we pick a random port (this is a heuristic) */
1819 usm->source_port =
1820 (ntohs (udp->source_port) < 32000) ? udp->source_port : 0;
1821 usm->destination_port = udp->destination_port;
1822 GNUNET_memcpy (&usm[1],
1823 &udp[1],
1824 payload_length - sizeof (struct GNUNET_TUN_UdpHeader));
1825 }
1826 else
1827 { 1720 {
1828 struct GNUNET_EXIT_UdpInternetMessage *uim;
1829 struct in_addr *ip4dst;
1830 struct in6_addr *ip6dst;
1831 void *payload;
1832
1833 mlen = sizeof (struct GNUNET_EXIT_UdpInternetMessage) + alen +
1834 payload_length - sizeof (struct GNUNET_TUN_UdpHeader);
1835 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1836 { 1721 {
1837 GNUNET_break (0); 1722 char sbuf[INET6_ADDRSTRLEN];
1838 return; 1723 char dbuf[INET6_ADDRSTRLEN];
1724
1725 GNUNET_log(
1726 GNUNET_ERROR_TYPE_DEBUG,
1727 "Routing %s packet from [%s]:%u -> [%s]:%u to service %s at peer %s\n",
1728 (protocol == IPPROTO_TCP) ? "TCP" : "UDP",
1729 inet_ntop(af, source_ip, sbuf, sizeof(sbuf)),
1730 source_port,
1731 inet_ntop(af, destination_ip, dbuf, sizeof(dbuf)),
1732 destination_port,
1733 GNUNET_h2s(
1734 &destination->details.service_destination.service_descriptor),
1735 GNUNET_i2s(&destination->details.service_destination.target));
1839 } 1736 }
1840 env = GNUNET_MQ_msg_extra (uim, 1737 for (dt = destination->dt_head; NULL != dt; dt = dt->next)
1841 payload_length + alen - 1738 if (dt->destination_port == destination_port)
1842 sizeof (struct GNUNET_TUN_UdpHeader), 1739 break;
1843 GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET);
1844 uim->af = htonl (destination->details.exit_destination.af);
1845 uim->source_port =
1846 (ntohs (udp->source_port) < 32000) ? udp->source_port : 0;
1847 uim->destination_port = udp->destination_port;
1848 switch (destination->details.exit_destination.af)
1849 {
1850 case AF_INET:
1851 ip4dst = (struct in_addr *) &uim[1];
1852 *ip4dst = destination->details.exit_destination.ip.v4;
1853 payload = &ip4dst[1];
1854 break;
1855 case AF_INET6:
1856 ip6dst = (struct in6_addr *) &uim[1];
1857 *ip6dst = destination->details.exit_destination.ip.v6;
1858 payload = &ip6dst[1];
1859 break;
1860 default:
1861 GNUNET_assert (0);
1862 }
1863 GNUNET_memcpy (payload,
1864 &udp[1],
1865 payload_length - sizeof (struct GNUNET_TUN_UdpHeader));
1866 } 1740 }
1867 break; 1741 if (NULL == dt)
1868 case IPPROTO_TCP:
1869 if (GNUNET_NO == ts->is_established)
1870 { 1742 {
1871 if (destination->is_service) 1743 dt = GNUNET_new(struct DestinationChannel);
1872 { 1744 dt->destination = destination;
1873 struct GNUNET_EXIT_TcpServiceStartMessage *tsm; 1745 GNUNET_CONTAINER_DLL_insert(destination->dt_head,
1746 destination->dt_tail,
1747 dt);
1748 dt->destination_port = destination_port;
1749 }
1874 1750
1875 mlen = sizeof (struct GNUNET_EXIT_TcpServiceStartMessage) + 1751 /* see if we have an existing channel for this destination */
1876 payload_length - sizeof (struct GNUNET_TUN_TcpHeader); 1752 ts = GNUNET_CONTAINER_multihashmap_get(channel_map, &key);
1877 if (mlen >= GNUNET_MAX_MESSAGE_SIZE) 1753 if (NULL == ts)
1754 {
1755 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1756 "Creating new channel for key %s\n",
1757 GNUNET_h2s(&key));
1758 /* need to either use the existing channel from the destination (if still
1759 available) or create a fresh one */
1760 ts = create_channel_to_destination(dt, af);
1761 if (NULL == ts)
1762 return;
1763 /* now bind existing "unbound" channel to our IP/port tuple */
1764 ts->protocol = protocol;
1765 ts->af = af;
1766 if (AF_INET == af)
1878 { 1767 {
1879 GNUNET_break (0); 1768 ts->source_ip.v4 = *(const struct in_addr *)source_ip;
1880 return; 1769 ts->destination_ip.v4 = *(const struct in_addr *)destination_ip;
1881 } 1770 }
1882 env =
1883 GNUNET_MQ_msg_extra (tsm,
1884 payload_length -
1885 sizeof (struct GNUNET_TUN_TcpHeader),
1886 GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START);
1887 tsm->reserved = htonl (0);
1888 tsm->tcp_header = *tcp;
1889 GNUNET_memcpy (&tsm[1],
1890 &tcp[1],
1891 payload_length - sizeof (struct GNUNET_TUN_TcpHeader));
1892 }
1893 else 1771 else
1894 {
1895 struct GNUNET_EXIT_TcpInternetStartMessage *tim;
1896 struct in_addr *ip4dst;
1897 struct in6_addr *ip6dst;
1898 void *payload;
1899
1900 mlen = sizeof (struct GNUNET_EXIT_TcpInternetStartMessage) + alen +
1901 payload_length - sizeof (struct GNUNET_TUN_TcpHeader);
1902 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1903 { 1772 {
1904 GNUNET_break (0); 1773 ts->source_ip.v6 = *(const struct in6_addr *)source_ip;
1905 return; 1774 ts->destination_ip.v6 = *(const struct in6_addr *)destination_ip;
1906 }
1907 env =
1908 GNUNET_MQ_msg_extra (tim,
1909 payload_length + alen -
1910 sizeof (struct GNUNET_TUN_TcpHeader),
1911 GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START);
1912 tim->af = htonl (destination->details.exit_destination.af);
1913 tim->tcp_header = *tcp;
1914 switch (destination->details.exit_destination.af)
1915 {
1916 case AF_INET:
1917 ip4dst = (struct in_addr *) &tim[1];
1918 *ip4dst = destination->details.exit_destination.ip.v4;
1919 payload = &ip4dst[1];
1920 break;
1921 case AF_INET6:
1922 ip6dst = (struct in6_addr *) &tim[1];
1923 *ip6dst = destination->details.exit_destination.ip.v6;
1924 payload = &ip6dst[1];
1925 break;
1926 default:
1927 GNUNET_assert (0);
1928 } 1775 }
1929 GNUNET_memcpy (payload, 1776 ts->source_port = source_port;
1930 &tcp[1], 1777 ts->destination_port = destination_port;
1931 payload_length - sizeof (struct GNUNET_TUN_TcpHeader)); 1778 ts->heap_node =
1932 } 1779 GNUNET_CONTAINER_heap_insert(channel_heap,
1780 ts,
1781 GNUNET_TIME_absolute_get().abs_value_us);
1782 GNUNET_assert(GNUNET_YES ==
1783 GNUNET_CONTAINER_multihashmap_put(
1784 channel_map,
1785 &key,
1786 ts,
1787 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1788 GNUNET_STATISTICS_update(stats,
1789 gettext_noop("# Active channels"),
1790 1,
1791 GNUNET_NO);
1792 while (GNUNET_CONTAINER_multihashmap_size(channel_map) >
1793 max_channel_mappings)
1794 expire_channel(ts);
1933 } 1795 }
1934 else 1796 else
1935 { 1797 {
1936 struct GNUNET_EXIT_TcpDataMessage *tdm; 1798 GNUNET_CONTAINER_heap_update_cost(ts->heap_node,
1937 1799 GNUNET_TIME_absolute_get()
1938 mlen = sizeof (struct GNUNET_EXIT_TcpDataMessage) + payload_length - 1800 .abs_value_us);
1939 sizeof (struct GNUNET_TUN_TcpHeader);
1940 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1941 {
1942 GNUNET_break (0);
1943 return;
1944 }
1945 env = GNUNET_MQ_msg_extra (tdm,
1946 payload_length -
1947 sizeof (struct GNUNET_TUN_TcpHeader),
1948 GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT);
1949 tdm->reserved = htonl (0);
1950 tdm->tcp_header = *tcp;
1951 GNUNET_memcpy (&tdm[1],
1952 &tcp[1],
1953 payload_length - sizeof (struct GNUNET_TUN_TcpHeader));
1954 } 1801 }
1955 break; 1802 if (NULL == ts->channel)
1956 case IPPROTO_ICMP:
1957 case IPPROTO_ICMPV6:
1958 if (destination->is_service)
1959 { 1803 {
1960 struct GNUNET_EXIT_IcmpServiceMessage *ism; 1804 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
1805 "Packet dropped, channel to %s not yet ready (%s)\n",
1806 print_channel_destination(&ts->destination),
1807 (NULL == ts->search) ? "EXIT search failed"
1808 : "EXIT search active");
1809 GNUNET_STATISTICS_update(stats,
1810 gettext_noop(
1811 "# Packets dropped (channel not yet online)"),
1812 1,
1813 GNUNET_NO);
1814 return;
1815 }
1961 1816
1962 /* ICMP protocol translation will be done by the receiver (as we don't know 1817 /* send via channel */
1963 the target AF); however, we still need to possibly discard the payload 1818 switch (protocol)
1964 depending on the ICMP type */ 1819 {
1965 switch (af) 1820 case IPPROTO_UDP:
1966 { 1821 if (destination->is_service)
1967 case AF_INET:
1968 switch (icmp->type)
1969 { 1822 {
1970 case GNUNET_TUN_ICMPTYPE_ECHO_REPLY: 1823 struct GNUNET_EXIT_UdpServiceMessage *usm;
1971 case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST: 1824
1972 break; 1825 mlen = sizeof(struct GNUNET_EXIT_UdpServiceMessage) + payload_length -
1973 case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE: 1826 sizeof(struct GNUNET_TUN_UdpHeader);
1974 case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH: 1827 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1975 case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED: 1828 {
1976 /* throw away ICMP payload, won't be useful for the other side anyway */ 1829 GNUNET_break(0);
1977 payload_length = sizeof (struct GNUNET_TUN_IcmpHeader); 1830 return;
1978 break; 1831 }
1979 default: 1832 env = GNUNET_MQ_msg_extra(usm,
1980 GNUNET_STATISTICS_update (stats, 1833 payload_length -
1981 gettext_noop ( 1834 sizeof(struct GNUNET_TUN_UdpHeader),
1982 "# ICMPv4 packets dropped (not allowed)"), 1835 GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE);
1983 1, 1836 /* if the source port is below 32000, we assume it has a special
1984 GNUNET_NO); 1837 meaning; if not, we pick a random port (this is a heuristic) */
1985 return; 1838 usm->source_port =
1839 (ntohs(udp->source_port) < 32000) ? udp->source_port : 0;
1840 usm->destination_port = udp->destination_port;
1841 GNUNET_memcpy(&usm[1],
1842 &udp[1],
1843 payload_length - sizeof(struct GNUNET_TUN_UdpHeader));
1986 } 1844 }
1987 /* end of AF_INET */ 1845 else
1988 break;
1989 case AF_INET6:
1990 switch (icmp->type)
1991 { 1846 {
1992 case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE: 1847 struct GNUNET_EXIT_UdpInternetMessage *uim;
1993 case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG: 1848 struct in_addr *ip4dst;
1994 case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED: 1849 struct in6_addr *ip6dst;
1995 case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM: 1850 void *payload;
1996 /* throw away ICMP payload, won't be useful for the other side anyway */ 1851
1997 payload_length = sizeof (struct GNUNET_TUN_IcmpHeader); 1852 mlen = sizeof(struct GNUNET_EXIT_UdpInternetMessage) + alen +
1998 break; 1853 payload_length - sizeof(struct GNUNET_TUN_UdpHeader);
1999 case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST: 1854 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
2000 case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY: 1855 {
2001 break; 1856 GNUNET_break(0);
2002 default: 1857 return;
2003 GNUNET_STATISTICS_update (stats, 1858 }
2004 gettext_noop ( 1859 env = GNUNET_MQ_msg_extra(uim,
2005 "# ICMPv6 packets dropped (not allowed)"), 1860 payload_length + alen -
2006 1, 1861 sizeof(struct GNUNET_TUN_UdpHeader),
2007 GNUNET_NO); 1862 GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET);
2008 return; 1863 uim->af = htonl(destination->details.exit_destination.af);
1864 uim->source_port =
1865 (ntohs(udp->source_port) < 32000) ? udp->source_port : 0;
1866 uim->destination_port = udp->destination_port;
1867 switch (destination->details.exit_destination.af)
1868 {
1869 case AF_INET:
1870 ip4dst = (struct in_addr *)&uim[1];
1871 *ip4dst = destination->details.exit_destination.ip.v4;
1872 payload = &ip4dst[1];
1873 break;
1874
1875 case AF_INET6:
1876 ip6dst = (struct in6_addr *)&uim[1];
1877 *ip6dst = destination->details.exit_destination.ip.v6;
1878 payload = &ip6dst[1];
1879 break;
1880
1881 default:
1882 GNUNET_assert(0);
1883 }
1884 GNUNET_memcpy(payload,
1885 &udp[1],
1886 payload_length - sizeof(struct GNUNET_TUN_UdpHeader));
2009 } 1887 }
2010 /* end of AF_INET6 */ 1888 break;
2011 break;
2012 default:
2013 GNUNET_assert (0);
2014 break;
2015 }
2016 1889
2017 /* update length calculations, as payload_length may have changed */ 1890 case IPPROTO_TCP:
2018 mlen = sizeof (struct GNUNET_EXIT_IcmpServiceMessage) + alen + 1891 if (GNUNET_NO == ts->is_established)
2019 payload_length - sizeof (struct GNUNET_TUN_IcmpHeader); 1892 {
2020 if (mlen >= GNUNET_MAX_MESSAGE_SIZE) 1893 if (destination->is_service)
2021 { 1894 {
2022 GNUNET_break (0); 1895 struct GNUNET_EXIT_TcpServiceStartMessage *tsm;
2023 return; 1896
2024 } 1897 mlen = sizeof(struct GNUNET_EXIT_TcpServiceStartMessage) +
1898 payload_length - sizeof(struct GNUNET_TUN_TcpHeader);
1899 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1900 {
1901 GNUNET_break(0);
1902 return;
1903 }
1904 env =
1905 GNUNET_MQ_msg_extra(tsm,
1906 payload_length -
1907 sizeof(struct GNUNET_TUN_TcpHeader),
1908 GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START);
1909 tsm->reserved = htonl(0);
1910 tsm->tcp_header = *tcp;
1911 GNUNET_memcpy(&tsm[1],
1912 &tcp[1],
1913 payload_length - sizeof(struct GNUNET_TUN_TcpHeader));
1914 }
1915 else
1916 {
1917 struct GNUNET_EXIT_TcpInternetStartMessage *tim;
1918 struct in_addr *ip4dst;
1919 struct in6_addr *ip6dst;
1920 void *payload;
1921
1922 mlen = sizeof(struct GNUNET_EXIT_TcpInternetStartMessage) + alen +
1923 payload_length - sizeof(struct GNUNET_TUN_TcpHeader);
1924 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1925 {
1926 GNUNET_break(0);
1927 return;
1928 }
1929 env =
1930 GNUNET_MQ_msg_extra(tim,
1931 payload_length + alen -
1932 sizeof(struct GNUNET_TUN_TcpHeader),
1933 GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START);
1934 tim->af = htonl(destination->details.exit_destination.af);
1935 tim->tcp_header = *tcp;
1936 switch (destination->details.exit_destination.af)
1937 {
1938 case AF_INET:
1939 ip4dst = (struct in_addr *)&tim[1];
1940 *ip4dst = destination->details.exit_destination.ip.v4;
1941 payload = &ip4dst[1];
1942 break;
1943
1944 case AF_INET6:
1945 ip6dst = (struct in6_addr *)&tim[1];
1946 *ip6dst = destination->details.exit_destination.ip.v6;
1947 payload = &ip6dst[1];
1948 break;
1949
1950 default:
1951 GNUNET_assert(0);
1952 }
1953 GNUNET_memcpy(payload,
1954 &tcp[1],
1955 payload_length - sizeof(struct GNUNET_TUN_TcpHeader));
1956 }
1957 }
1958 else
1959 {
1960 struct GNUNET_EXIT_TcpDataMessage *tdm;
2025 1961
2026 env = GNUNET_MQ_msg_extra (ism, 1962 mlen = sizeof(struct GNUNET_EXIT_TcpDataMessage) + payload_length -
2027 payload_length - 1963 sizeof(struct GNUNET_TUN_TcpHeader);
2028 sizeof (struct GNUNET_TUN_IcmpHeader), 1964 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
2029 GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_SERVICE); 1965 {
2030 ism->af = htonl (af); /* need to tell destination ICMP protocol family! */ 1966 GNUNET_break(0);
2031 ism->icmp_header = *icmp; 1967 return;
2032 GNUNET_memcpy (&ism[1], 1968 }
2033 &icmp[1], 1969 env = GNUNET_MQ_msg_extra(tdm,
2034 payload_length - sizeof (struct GNUNET_TUN_IcmpHeader)); 1970 payload_length -
2035 } 1971 sizeof(struct GNUNET_TUN_TcpHeader),
2036 else 1972 GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT);
2037 { 1973 tdm->reserved = htonl(0);
2038 struct GNUNET_EXIT_IcmpInternetMessage *iim; 1974 tdm->tcp_header = *tcp;
2039 struct in_addr *ip4dst; 1975 GNUNET_memcpy(&tdm[1],
2040 struct in6_addr *ip6dst; 1976 &tcp[1],
2041 void *payload; 1977 payload_length - sizeof(struct GNUNET_TUN_TcpHeader));
2042 uint8_t new_type; 1978 }
2043 1979 break;
2044 new_type = icmp->type; 1980
2045 /* Perform ICMP protocol-translation (depending on destination AF and source AF) 1981 case IPPROTO_ICMP:
2046 and throw away ICMP payload depending on ICMP message type */ 1982 case IPPROTO_ICMPV6:
2047 switch (af) 1983 if (destination->is_service)
2048 {
2049 case AF_INET:
2050 switch (icmp->type)
2051 { 1984 {
2052 case GNUNET_TUN_ICMPTYPE_ECHO_REPLY: 1985 struct GNUNET_EXIT_IcmpServiceMessage *ism;
2053 if (destination->details.exit_destination.af == AF_INET6) 1986
2054 new_type = GNUNET_TUN_ICMPTYPE6_ECHO_REPLY; 1987 /* ICMP protocol translation will be done by the receiver (as we don't know
2055 break; 1988 the target AF); however, we still need to possibly discard the payload
2056 case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST: 1989 depending on the ICMP type */
2057 if (destination->details.exit_destination.af == AF_INET6) 1990 switch (af)
2058 new_type = GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST; 1991 {
2059 break; 1992 case AF_INET:
2060 case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE: 1993 switch (icmp->type)
2061 if (destination->details.exit_destination.af == AF_INET6) 1994 {
2062 new_type = GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE; 1995 case GNUNET_TUN_ICMPTYPE_ECHO_REPLY:
2063 /* throw away IP-payload, exit will have to make it up anyway */ 1996 case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST:
2064 payload_length = sizeof (struct GNUNET_TUN_IcmpHeader); 1997 break;
2065 break; 1998
2066 case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED: 1999 case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE:
2067 if (destination->details.exit_destination.af == AF_INET6) 2000 case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH:
2068 new_type = GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED; 2001 case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED:
2069 /* throw away IP-payload, exit will have to make it up anyway */ 2002 /* throw away ICMP payload, won't be useful for the other side anyway */
2070 payload_length = sizeof (struct GNUNET_TUN_IcmpHeader); 2003 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2071 break; 2004 break;
2072 case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH: 2005
2073 if (destination->details.exit_destination.af == AF_INET6) 2006 default:
2074 { 2007 GNUNET_STATISTICS_update(stats,
2075 GNUNET_STATISTICS_update ( 2008 gettext_noop(
2076 stats, 2009 "# ICMPv4 packets dropped (not allowed)"),
2077 gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"), 2010 1,
2078 1, 2011 GNUNET_NO);
2079 GNUNET_NO); 2012 return;
2080 return; 2013 }
2081 } 2014 /* end of AF_INET */
2082 /* throw away IP-payload, exit will have to make it up anyway */ 2015 break;
2083 payload_length = sizeof (struct GNUNET_TUN_IcmpHeader); 2016
2084 break; 2017 case AF_INET6:
2085 default: 2018 switch (icmp->type)
2086 GNUNET_STATISTICS_update ( 2019 {
2087 stats, 2020 case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE:
2088 gettext_noop ("# ICMPv4 packets dropped (type not allowed)"), 2021 case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG:
2089 1, 2022 case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED:
2090 GNUNET_NO); 2023 case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM:
2091 return; 2024 /* throw away ICMP payload, won't be useful for the other side anyway */
2025 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2026 break;
2027
2028 case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST:
2029 case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY:
2030 break;
2031
2032 default:
2033 GNUNET_STATISTICS_update(stats,
2034 gettext_noop(
2035 "# ICMPv6 packets dropped (not allowed)"),
2036 1,
2037 GNUNET_NO);
2038 return;
2039 }
2040 /* end of AF_INET6 */
2041 break;
2042
2043 default:
2044 GNUNET_assert(0);
2045 break;
2046 }
2047
2048 /* update length calculations, as payload_length may have changed */
2049 mlen = sizeof(struct GNUNET_EXIT_IcmpServiceMessage) + alen +
2050 payload_length - sizeof(struct GNUNET_TUN_IcmpHeader);
2051 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
2052 {
2053 GNUNET_break(0);
2054 return;
2055 }
2056
2057 env = GNUNET_MQ_msg_extra(ism,
2058 payload_length -
2059 sizeof(struct GNUNET_TUN_IcmpHeader),
2060 GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_SERVICE);
2061 ism->af = htonl(af); /* need to tell destination ICMP protocol family! */
2062 ism->icmp_header = *icmp;
2063 GNUNET_memcpy(&ism[1],
2064 &icmp[1],
2065 payload_length - sizeof(struct GNUNET_TUN_IcmpHeader));
2092 } 2066 }
2093 /* end of AF_INET */ 2067 else
2094 break;
2095 case AF_INET6:
2096 switch (icmp->type)
2097 { 2068 {
2098 case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE: 2069 struct GNUNET_EXIT_IcmpInternetMessage *iim;
2099 if (destination->details.exit_destination.af == AF_INET) 2070 struct in_addr *ip4dst;
2100 new_type = GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE; 2071 struct in6_addr *ip6dst;
2101 /* throw away IP-payload, exit will have to make it up anyway */ 2072 void *payload;
2102 payload_length = sizeof (struct GNUNET_TUN_IcmpHeader); 2073 uint8_t new_type;
2103 break; 2074
2104 case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED: 2075 new_type = icmp->type;
2105 if (destination->details.exit_destination.af == AF_INET) 2076 /* Perform ICMP protocol-translation (depending on destination AF and source AF)
2106 new_type = GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED; 2077 and throw away ICMP payload depending on ICMP message type */
2107 /* throw away IP-payload, exit will have to make it up anyway */ 2078 switch (af)
2108 payload_length = sizeof (struct GNUNET_TUN_IcmpHeader); 2079 {
2109 break; 2080 case AF_INET:
2110 case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG: 2081 switch (icmp->type)
2111 if (destination->details.exit_destination.af == AF_INET) 2082 {
2112 { 2083 case GNUNET_TUN_ICMPTYPE_ECHO_REPLY:
2113 GNUNET_STATISTICS_update ( 2084 if (destination->details.exit_destination.af == AF_INET6)
2114 stats, 2085 new_type = GNUNET_TUN_ICMPTYPE6_ECHO_REPLY;
2115 gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"), 2086 break;
2116 1, 2087
2117 GNUNET_NO); 2088 case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST:
2118 return; 2089 if (destination->details.exit_destination.af == AF_INET6)
2119 } 2090 new_type = GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST;
2120 /* throw away IP-payload, exit will have to make it up anyway */ 2091 break;
2121 payload_length = sizeof (struct GNUNET_TUN_IcmpHeader); 2092
2122 break; 2093 case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE:
2123 case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM: 2094 if (destination->details.exit_destination.af == AF_INET6)
2124 if (destination->details.exit_destination.af == AF_INET) 2095 new_type = GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE;
2125 { 2096 /* throw away IP-payload, exit will have to make it up anyway */
2126 GNUNET_STATISTICS_update ( 2097 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2127 stats, 2098 break;
2128 gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"), 2099
2129 1, 2100 case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED:
2130 GNUNET_NO); 2101 if (destination->details.exit_destination.af == AF_INET6)
2131 return; 2102 new_type = GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED;
2132 } 2103 /* throw away IP-payload, exit will have to make it up anyway */
2133 /* throw away IP-payload, exit will have to make it up anyway */ 2104 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2134 payload_length = sizeof (struct GNUNET_TUN_IcmpHeader); 2105 break;
2135 break; 2106
2136 case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST: 2107 case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH:
2137 if (destination->details.exit_destination.af == AF_INET) 2108 if (destination->details.exit_destination.af == AF_INET6)
2138 new_type = GNUNET_TUN_ICMPTYPE_ECHO_REQUEST; 2109 {
2139 break; 2110 GNUNET_STATISTICS_update(
2140 case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY: 2111 stats,
2141 if (destination->details.exit_destination.af == AF_INET) 2112 gettext_noop("# ICMPv4 packets dropped (impossible PT to v6)"),
2142 new_type = GNUNET_TUN_ICMPTYPE_ECHO_REPLY; 2113 1,
2143 break; 2114 GNUNET_NO);
2144 default: 2115 return;
2145 GNUNET_STATISTICS_update ( 2116 }
2146 stats, 2117 /* throw away IP-payload, exit will have to make it up anyway */
2147 gettext_noop ("# ICMPv6 packets dropped (type not allowed)"), 2118 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2148 1, 2119 break;
2149 GNUNET_NO); 2120
2150 return; 2121 default:
2122 GNUNET_STATISTICS_update(
2123 stats,
2124 gettext_noop("# ICMPv4 packets dropped (type not allowed)"),
2125 1,
2126 GNUNET_NO);
2127 return;
2128 }
2129 /* end of AF_INET */
2130 break;
2131
2132 case AF_INET6:
2133 switch (icmp->type)
2134 {
2135 case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE:
2136 if (destination->details.exit_destination.af == AF_INET)
2137 new_type = GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE;
2138 /* throw away IP-payload, exit will have to make it up anyway */
2139 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2140 break;
2141
2142 case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED:
2143 if (destination->details.exit_destination.af == AF_INET)
2144 new_type = GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED;
2145 /* throw away IP-payload, exit will have to make it up anyway */
2146 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2147 break;
2148
2149 case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG:
2150 if (destination->details.exit_destination.af == AF_INET)
2151 {
2152 GNUNET_STATISTICS_update(
2153 stats,
2154 gettext_noop("# ICMPv6 packets dropped (impossible PT to v4)"),
2155 1,
2156 GNUNET_NO);
2157 return;
2158 }
2159 /* throw away IP-payload, exit will have to make it up anyway */
2160 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2161 break;
2162
2163 case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM:
2164 if (destination->details.exit_destination.af == AF_INET)
2165 {
2166 GNUNET_STATISTICS_update(
2167 stats,
2168 gettext_noop("# ICMPv6 packets dropped (impossible PT to v4)"),
2169 1,
2170 GNUNET_NO);
2171 return;
2172 }
2173 /* throw away IP-payload, exit will have to make it up anyway */
2174 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2175 break;
2176
2177 case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST:
2178 if (destination->details.exit_destination.af == AF_INET)
2179 new_type = GNUNET_TUN_ICMPTYPE_ECHO_REQUEST;
2180 break;
2181
2182 case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY:
2183 if (destination->details.exit_destination.af == AF_INET)
2184 new_type = GNUNET_TUN_ICMPTYPE_ECHO_REPLY;
2185 break;
2186
2187 default:
2188 GNUNET_STATISTICS_update(
2189 stats,
2190 gettext_noop("# ICMPv6 packets dropped (type not allowed)"),
2191 1,
2192 GNUNET_NO);
2193 return;
2194 }
2195 /* end of AF_INET6 */
2196 break;
2197
2198 default:
2199 GNUNET_assert(0);
2200 }
2201
2202 /* update length calculations, as payload_length may have changed */
2203 mlen = sizeof(struct GNUNET_EXIT_IcmpInternetMessage) + alen +
2204 payload_length - sizeof(struct GNUNET_TUN_IcmpHeader);
2205 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
2206 {
2207 GNUNET_break(0);
2208 return;
2209 }
2210 env = GNUNET_MQ_msg_extra(iim,
2211 alen + payload_length -
2212 sizeof(struct GNUNET_TUN_IcmpHeader),
2213 GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_INTERNET);
2214 iim->icmp_header = *icmp;
2215 iim->icmp_header.type = new_type;
2216 iim->af = htonl(destination->details.exit_destination.af);
2217 switch (destination->details.exit_destination.af)
2218 {
2219 case AF_INET:
2220 ip4dst = (struct in_addr *)&iim[1];
2221 *ip4dst = destination->details.exit_destination.ip.v4;
2222 payload = &ip4dst[1];
2223 break;
2224
2225 case AF_INET6:
2226 ip6dst = (struct in6_addr *)&iim[1];
2227 *ip6dst = destination->details.exit_destination.ip.v6;
2228 payload = &ip6dst[1];
2229 break;
2230
2231 default:
2232 GNUNET_assert(0);
2233 }
2234 GNUNET_memcpy(payload,
2235 &icmp[1],
2236 payload_length - sizeof(struct GNUNET_TUN_IcmpHeader));
2151 } 2237 }
2152 /* end of AF_INET6 */ 2238 break;
2153 break;
2154 default:
2155 GNUNET_assert (0);
2156 }
2157 2239
2158 /* update length calculations, as payload_length may have changed */ 2240 default:
2159 mlen = sizeof (struct GNUNET_EXIT_IcmpInternetMessage) + alen + 2241 /* not supported above, how can we get here !? */
2160 payload_length - sizeof (struct GNUNET_TUN_IcmpHeader); 2242 GNUNET_assert(0);
2161 if (mlen >= GNUNET_MAX_MESSAGE_SIZE) 2243 break;
2162 {
2163 GNUNET_break (0);
2164 return;
2165 }
2166 env = GNUNET_MQ_msg_extra (iim,
2167 alen + payload_length -
2168 sizeof (struct GNUNET_TUN_IcmpHeader),
2169 GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_INTERNET);
2170 iim->icmp_header = *icmp;
2171 iim->icmp_header.type = new_type;
2172 iim->af = htonl (destination->details.exit_destination.af);
2173 switch (destination->details.exit_destination.af)
2174 {
2175 case AF_INET:
2176 ip4dst = (struct in_addr *) &iim[1];
2177 *ip4dst = destination->details.exit_destination.ip.v4;
2178 payload = &ip4dst[1];
2179 break;
2180 case AF_INET6:
2181 ip6dst = (struct in6_addr *) &iim[1];
2182 *ip6dst = destination->details.exit_destination.ip.v6;
2183 payload = &ip6dst[1];
2184 break;
2185 default:
2186 GNUNET_assert (0);
2187 }
2188 GNUNET_memcpy (payload,
2189 &icmp[1],
2190 payload_length - sizeof (struct GNUNET_TUN_IcmpHeader));
2191 } 2244 }
2192 break;
2193 default:
2194 /* not supported above, how can we get here !? */
2195 GNUNET_assert (0);
2196 break;
2197 }
2198 ts->is_established = GNUNET_YES; 2245 ts->is_established = GNUNET_YES;
2199 send_to_channel (ts, env); 2246 send_to_channel(ts, env);
2200} 2247}
2201 2248
2202 2249
@@ -2213,106 +2260,108 @@ route_packet (struct DestinationEntry *destination,
2213 * #GNUNET_SYSERR to stop further processing with error 2260 * #GNUNET_SYSERR to stop further processing with error
2214 */ 2261 */
2215static int 2262static int
2216message_token (void *cls, const struct GNUNET_MessageHeader *message) 2263message_token(void *cls, const struct GNUNET_MessageHeader *message)
2217{ 2264{
2218 const struct GNUNET_TUN_Layer2PacketHeader *tun; 2265 const struct GNUNET_TUN_Layer2PacketHeader *tun;
2219 size_t mlen; 2266 size_t mlen;
2220 struct GNUNET_HashCode key; 2267 struct GNUNET_HashCode key;
2221 struct DestinationEntry *de; 2268 struct DestinationEntry *de;
2222 2269
2223 GNUNET_STATISTICS_update (stats, 2270 GNUNET_STATISTICS_update(stats,
2224 gettext_noop ( 2271 gettext_noop(
2225 "# Packets received from TUN interface"), 2272 "# Packets received from TUN interface"),
2226 1, 2273 1,
2227 GNUNET_NO); 2274 GNUNET_NO);
2228 mlen = ntohs (message->size); 2275 mlen = ntohs(message->size);
2229 if ((ntohs (message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) || 2276 if ((ntohs(message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) ||
2230 (mlen < sizeof (struct GNUNET_MessageHeader) + 2277 (mlen < sizeof(struct GNUNET_MessageHeader) +
2231 sizeof (struct GNUNET_TUN_Layer2PacketHeader))) 2278 sizeof(struct GNUNET_TUN_Layer2PacketHeader)))
2232 {
2233 GNUNET_break (0);
2234 return GNUNET_OK;
2235 }
2236 tun = (const struct GNUNET_TUN_Layer2PacketHeader *) &message[1];
2237 mlen -= (sizeof (struct GNUNET_MessageHeader) +
2238 sizeof (struct GNUNET_TUN_Layer2PacketHeader));
2239 switch (ntohs (tun->proto))
2240 {
2241 case ETH_P_IPV6: {
2242 const struct GNUNET_TUN_IPv6Header *pkt6;
2243
2244 if (mlen < sizeof (struct GNUNET_TUN_IPv6Header))
2245 { 2279 {
2246 /* blame kernel */ 2280 GNUNET_break(0);
2247 GNUNET_break (0);
2248 return GNUNET_OK; 2281 return GNUNET_OK;
2249 } 2282 }
2250 pkt6 = (const struct GNUNET_TUN_IPv6Header *) &tun[1]; 2283 tun = (const struct GNUNET_TUN_Layer2PacketHeader *)&message[1];
2251 get_destination_key_from_ip (AF_INET6, &pkt6->destination_address, &key); 2284 mlen -= (sizeof(struct GNUNET_MessageHeader) +
2252 de = GNUNET_CONTAINER_multihashmap_get (destination_map, &key); 2285 sizeof(struct GNUNET_TUN_Layer2PacketHeader));
2253 if (NULL == de) 2286 switch (ntohs(tun->proto))
2254 { 2287 {
2255 char buf[INET6_ADDRSTRLEN]; 2288 case ETH_P_IPV6: {
2289 const struct GNUNET_TUN_IPv6Header *pkt6;
2256 2290
2257 GNUNET_log ( 2291 if (mlen < sizeof(struct GNUNET_TUN_IPv6Header))
2258 GNUNET_ERROR_TYPE_INFO, 2292 {
2259 _ ("Packet received for unmapped destination `%s' (dropping it)\n"), 2293 /* blame kernel */
2260 inet_ntop (AF_INET6, &pkt6->destination_address, buf, sizeof (buf))); 2294 GNUNET_break(0);
2261 return GNUNET_OK; 2295 return GNUNET_OK;
2296 }
2297 pkt6 = (const struct GNUNET_TUN_IPv6Header *)&tun[1];
2298 get_destination_key_from_ip(AF_INET6, &pkt6->destination_address, &key);
2299 de = GNUNET_CONTAINER_multihashmap_get(destination_map, &key);
2300 if (NULL == de)
2301 {
2302 char buf[INET6_ADDRSTRLEN];
2303
2304 GNUNET_log(
2305 GNUNET_ERROR_TYPE_INFO,
2306 _("Packet received for unmapped destination `%s' (dropping it)\n"),
2307 inet_ntop(AF_INET6, &pkt6->destination_address, buf, sizeof(buf)));
2308 return GNUNET_OK;
2309 }
2310 route_packet(de,
2311 AF_INET6,
2312 pkt6->next_header,
2313 &pkt6->source_address,
2314 &pkt6->destination_address,
2315 &pkt6[1],
2316 mlen - sizeof(struct GNUNET_TUN_IPv6Header));
2262 } 2317 }
2263 route_packet (de, 2318 break;
2264 AF_INET6,
2265 pkt6->next_header,
2266 &pkt6->source_address,
2267 &pkt6->destination_address,
2268 &pkt6[1],
2269 mlen - sizeof (struct GNUNET_TUN_IPv6Header));
2270 }
2271 break;
2272 case ETH_P_IPV4: {
2273 struct GNUNET_TUN_IPv4Header *pkt4;
2274 2319
2275 if (mlen < sizeof (struct GNUNET_TUN_IPv4Header)) 2320 case ETH_P_IPV4: {
2276 { 2321 struct GNUNET_TUN_IPv4Header *pkt4;
2277 /* blame kernel */ 2322
2278 GNUNET_break (0); 2323 if (mlen < sizeof(struct GNUNET_TUN_IPv4Header))
2279 return GNUNET_OK; 2324 {
2325 /* blame kernel */
2326 GNUNET_break(0);
2327 return GNUNET_OK;
2328 }
2329 pkt4 = (struct GNUNET_TUN_IPv4Header *)&tun[1];
2330 get_destination_key_from_ip(AF_INET, &pkt4->destination_address, &key);
2331 de = GNUNET_CONTAINER_multihashmap_get(destination_map, &key);
2332 if (NULL == de)
2333 {
2334 char buf[INET_ADDRSTRLEN];
2335
2336 GNUNET_log(
2337 GNUNET_ERROR_TYPE_INFO,
2338 _("Packet received for unmapped destination `%s' (dropping it)\n"),
2339 inet_ntop(AF_INET, &pkt4->destination_address, buf, sizeof(buf)));
2340 return GNUNET_OK;
2341 }
2342 if (pkt4->header_length * 4 != sizeof(struct GNUNET_TUN_IPv4Header))
2343 {
2344 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
2345 _("Received IPv4 packet with options (dropping it)\n"));
2346 return GNUNET_OK;
2347 }
2348 route_packet(de,
2349 AF_INET,
2350 pkt4->protocol,
2351 &pkt4->source_address,
2352 &pkt4->destination_address,
2353 &pkt4[1],
2354 mlen - sizeof(struct GNUNET_TUN_IPv4Header));
2280 } 2355 }
2281 pkt4 = (struct GNUNET_TUN_IPv4Header *) &tun[1]; 2356 break;
2282 get_destination_key_from_ip (AF_INET, &pkt4->destination_address, &key);
2283 de = GNUNET_CONTAINER_multihashmap_get (destination_map, &key);
2284 if (NULL == de)
2285 {
2286 char buf[INET_ADDRSTRLEN];
2287 2357
2288 GNUNET_log ( 2358 default:
2359 GNUNET_log(
2289 GNUNET_ERROR_TYPE_INFO, 2360 GNUNET_ERROR_TYPE_INFO,
2290 _ ("Packet received for unmapped destination `%s' (dropping it)\n"), 2361 _("Received packet of unknown protocol %d from TUN (dropping it)\n"),
2291 inet_ntop (AF_INET, &pkt4->destination_address, buf, sizeof (buf))); 2362 (unsigned int)ntohs(tun->proto));
2292 return GNUNET_OK; 2363 break;
2293 }
2294 if (pkt4->header_length * 4 != sizeof (struct GNUNET_TUN_IPv4Header))
2295 {
2296 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2297 _ ("Received IPv4 packet with options (dropping it)\n"));
2298 return GNUNET_OK;
2299 } 2364 }
2300 route_packet (de,
2301 AF_INET,
2302 pkt4->protocol,
2303 &pkt4->source_address,
2304 &pkt4->destination_address,
2305 &pkt4[1],
2306 mlen - sizeof (struct GNUNET_TUN_IPv4Header));
2307 }
2308 break;
2309 default:
2310 GNUNET_log (
2311 GNUNET_ERROR_TYPE_INFO,
2312 _ ("Received packet of unknown protocol %d from TUN (dropping it)\n"),
2313 (unsigned int) ntohs (tun->proto));
2314 break;
2315 }
2316 return GNUNET_OK; 2365 return GNUNET_OK;
2317} 2366}
2318 2367
@@ -2326,7 +2375,7 @@ message_token (void *cls, const struct GNUNET_MessageHeader *message)
2326 * #GNUNET_SYSERR on error 2375 * #GNUNET_SYSERR on error
2327 */ 2376 */
2328static int 2377static int
2329allocate_v4_address (struct in_addr *v4) 2378allocate_v4_address(struct in_addr *v4)
2330{ 2379{
2331 const char *ipv4addr = vpn_argv[4]; 2380 const char *ipv4addr = vpn_argv[4];
2332 const char *ipv4mask = vpn_argv[5]; 2381 const char *ipv4mask = vpn_argv[5];
@@ -2336,30 +2385,31 @@ allocate_v4_address (struct in_addr *v4)
2336 struct GNUNET_HashCode key; 2385 struct GNUNET_HashCode key;
2337 unsigned int tries; 2386 unsigned int tries;
2338 2387
2339 GNUNET_assert (1 == inet_pton (AF_INET, ipv4addr, &addr)); 2388 GNUNET_assert(1 == inet_pton(AF_INET, ipv4addr, &addr));
2340 GNUNET_assert (1 == inet_pton (AF_INET, ipv4mask, &mask)); 2389 GNUNET_assert(1 == inet_pton(AF_INET, ipv4mask, &mask));
2341 /* Given 192.168.0.1/255.255.0.0, we want a mask 2390 /* Given 192.168.0.1/255.255.0.0, we want a mask
2342 of '192.168.255.255', thus: */ 2391 of '192.168.255.255', thus: */
2343 mask.s_addr = addr.s_addr | ~mask.s_addr; 2392 mask.s_addr = addr.s_addr | ~mask.s_addr;
2344 tries = 0; 2393 tries = 0;
2345 do 2394 do
2346 {
2347 tries++;
2348 if (tries > 16)
2349 { 2395 {
2350 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2396 tries++;
2351 _ ( 2397 if (tries > 16)
2352 "Failed to find unallocated IPv4 address in VPN's range\n")); 2398 {
2353 return GNUNET_SYSERR; 2399 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
2400 _(
2401 "Failed to find unallocated IPv4 address in VPN's range\n"));
2402 return GNUNET_SYSERR;
2403 }
2404 /* Pick random IPv4 address within the subnet, except 'addr' or 'mask' itself */
2405 rnd.s_addr =
2406 GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX);
2407 v4->s_addr = (addr.s_addr | rnd.s_addr) & mask.s_addr;
2408 get_destination_key_from_ip(AF_INET, v4, &key);
2354 } 2409 }
2355 /* Pick random IPv4 address within the subnet, except 'addr' or 'mask' itself */ 2410 while ((GNUNET_YES ==
2356 rnd.s_addr = 2411 GNUNET_CONTAINER_multihashmap_contains(destination_map, &key)) ||
2357 GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX); 2412 (v4->s_addr == addr.s_addr) || (v4->s_addr == mask.s_addr));
2358 v4->s_addr = (addr.s_addr | rnd.s_addr) & mask.s_addr;
2359 get_destination_key_from_ip (AF_INET, v4, &key);
2360 } while ((GNUNET_YES ==
2361 GNUNET_CONTAINER_multihashmap_contains (destination_map, &key)) ||
2362 (v4->s_addr == addr.s_addr) || (v4->s_addr == mask.s_addr));
2363 return GNUNET_OK; 2413 return GNUNET_OK;
2364} 2414}
2365 2415
@@ -2373,7 +2423,7 @@ allocate_v4_address (struct in_addr *v4)
2373 * #GNUNET_SYSERR on error 2423 * #GNUNET_SYSERR on error
2374 */ 2424 */
2375static int 2425static int
2376allocate_v6_address (struct in6_addr *v6) 2426allocate_v6_address(struct in6_addr *v6)
2377{ 2427{
2378 const char *ipv6addr = vpn_argv[2]; 2428 const char *ipv6addr = vpn_argv[2];
2379 struct in6_addr addr; 2429 struct in6_addr addr;
@@ -2383,8 +2433,8 @@ allocate_v6_address (struct in6_addr *v6)
2383 struct GNUNET_HashCode key; 2433 struct GNUNET_HashCode key;
2384 unsigned int tries; 2434 unsigned int tries;
2385 2435
2386 GNUNET_assert (1 == inet_pton (AF_INET6, ipv6addr, &addr)); 2436 GNUNET_assert(1 == inet_pton(AF_INET6, ipv6addr, &addr));
2387 GNUNET_assert (ipv6prefix < 128); 2437 GNUNET_assert(ipv6prefix < 128);
2388 /* Given ABCD::/96, we want a mask of 'ABCD::FFFF:FFFF, 2438 /* Given ABCD::/96, we want a mask of 'ABCD::FFFF:FFFF,
2389 thus: */ 2439 thus: */
2390 mask = addr; 2440 mask = addr;
@@ -2394,27 +2444,28 @@ allocate_v6_address (struct in6_addr *v6)
2394 /* Pick random IPv6 address within the subnet, except 'addr' or 'mask' itself */ 2444 /* Pick random IPv6 address within the subnet, except 'addr' or 'mask' itself */
2395 tries = 0; 2445 tries = 0;
2396 do 2446 do
2397 {
2398 tries++;
2399 if (tries > 16)
2400 { 2447 {
2401 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2448 tries++;
2402 _ ( 2449 if (tries > 16)
2403 "Failed to find unallocated IPv6 address in VPN's range\n")); 2450 {
2404 return GNUNET_SYSERR; 2451 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
2452 _(
2453 "Failed to find unallocated IPv6 address in VPN's range\n"));
2454 return GNUNET_SYSERR;
2455 }
2456 for (i = 0; i < 16; i++)
2457 {
2458 rnd.s6_addr[i] =
2459 (unsigned char)GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK,
2460 256);
2461 v6->s6_addr[i] = (addr.s6_addr[i] | rnd.s6_addr[i]) & mask.s6_addr[i];
2462 }
2463 get_destination_key_from_ip(AF_INET6, v6, &key);
2405 } 2464 }
2406 for (i = 0; i < 16; i++) 2465 while ((GNUNET_YES ==
2407 { 2466 GNUNET_CONTAINER_multihashmap_contains(destination_map, &key)) ||
2408 rnd.s6_addr[i] = 2467 (0 == GNUNET_memcmp(v6, &addr)) ||
2409 (unsigned char) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 2468 (0 == GNUNET_memcmp(v6, &mask)));
2410 256);
2411 v6->s6_addr[i] = (addr.s6_addr[i] | rnd.s6_addr[i]) & mask.s6_addr[i];
2412 }
2413 get_destination_key_from_ip (AF_INET6, v6, &key);
2414 } while ((GNUNET_YES ==
2415 GNUNET_CONTAINER_multihashmap_contains (destination_map, &key)) ||
2416 (0 == GNUNET_memcmp (v6, &addr)) ||
2417 (0 == GNUNET_memcmp (v6, &mask)));
2418 return GNUNET_OK; 2469 return GNUNET_OK;
2419} 2470}
2420 2471
@@ -2425,31 +2476,31 @@ allocate_v6_address (struct in6_addr *v6)
2425 * @param de entry to free 2476 * @param de entry to free
2426 */ 2477 */
2427static void 2478static void
2428free_destination_entry (struct DestinationEntry *de) 2479free_destination_entry(struct DestinationEntry *de)
2429{ 2480{
2430 struct DestinationChannel *dt; 2481 struct DestinationChannel *dt;
2431 2482
2432 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2483 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2433 "Cleaning up destination entry `%s'\n", 2484 "Cleaning up destination entry `%s'\n",
2434 print_channel_destination (de)); 2485 print_channel_destination(de));
2435 GNUNET_STATISTICS_update (stats, 2486 GNUNET_STATISTICS_update(stats,
2436 gettext_noop ("# Active destinations"), 2487 gettext_noop("# Active destinations"),
2437 -1, 2488 -1,
2438 GNUNET_NO); 2489 GNUNET_NO);
2439 while (NULL != (dt = de->dt_head)) 2490 while (NULL != (dt = de->dt_head))
2440 { 2491 {
2441 GNUNET_CONTAINER_DLL_remove (de->dt_head, de->dt_tail, dt); 2492 GNUNET_CONTAINER_DLL_remove(de->dt_head, de->dt_tail, dt);
2442 GNUNET_free (dt); 2493 GNUNET_free(dt);
2443 } 2494 }
2444 if (NULL != de->heap_node) 2495 if (NULL != de->heap_node)
2445 { 2496 {
2446 GNUNET_CONTAINER_heap_remove_node (de->heap_node); 2497 GNUNET_CONTAINER_heap_remove_node(de->heap_node);
2447 de->heap_node = NULL; 2498 de->heap_node = NULL;
2448 GNUNET_assert ( 2499 GNUNET_assert(
2449 GNUNET_YES == 2500 GNUNET_YES ==
2450 GNUNET_CONTAINER_multihashmap_remove (destination_map, &de->key, de)); 2501 GNUNET_CONTAINER_multihashmap_remove(destination_map, &de->key, de));
2451 } 2502 }
2452 GNUNET_free (de); 2503 GNUNET_free(de);
2453} 2504}
2454 2505
2455 2506
@@ -2459,15 +2510,15 @@ free_destination_entry (struct DestinationEntry *de)
2459 * @param except destination that must NOT be cleaned up, even if it is the oldest 2510 * @param except destination that must NOT be cleaned up, even if it is the oldest
2460 */ 2511 */
2461static void 2512static void
2462expire_destination (struct DestinationEntry *except) 2513expire_destination(struct DestinationEntry *except)
2463{ 2514{
2464 struct DestinationEntry *de; 2515 struct DestinationEntry *de;
2465 2516
2466 de = GNUNET_CONTAINER_heap_peek (destination_heap); 2517 de = GNUNET_CONTAINER_heap_peek(destination_heap);
2467 GNUNET_assert (NULL != de); 2518 GNUNET_assert(NULL != de);
2468 if (except == de) 2519 if (except == de)
2469 return; /* can't do this */ 2520 return; /* can't do this */
2470 free_destination_entry (de); 2521 free_destination_entry(de);
2471} 2522}
2472 2523
2473 2524
@@ -2486,42 +2537,45 @@ expire_destination (struct DestinationEntry *except)
2486 * an unsupported address family (not AF_INET, AF_INET6 or AF_UNSPEC) 2537 * an unsupported address family (not AF_INET, AF_INET6 or AF_UNSPEC)
2487 */ 2538 */
2488static int 2539static int
2489allocate_response_ip (int *result_af, 2540allocate_response_ip(int *result_af,
2490 void **addr, 2541 void **addr,
2491 struct in_addr *v4, 2542 struct in_addr *v4,
2492 struct in6_addr *v6) 2543 struct in6_addr *v6)
2493{ 2544{
2494 *addr = NULL; 2545 *addr = NULL;
2495 switch (*result_af) 2546 switch (*result_af)
2496 {
2497 case AF_INET:
2498 if (GNUNET_OK != allocate_v4_address (v4))
2499 *result_af = AF_UNSPEC;
2500 else
2501 *addr = v4;
2502 break;
2503 case AF_INET6:
2504 if (GNUNET_OK != allocate_v6_address (v6))
2505 *result_af = AF_UNSPEC;
2506 else
2507 *addr = v6;
2508 break;
2509 case AF_UNSPEC:
2510 if (GNUNET_OK == allocate_v4_address (v4))
2511 {
2512 *addr = v4;
2513 *result_af = AF_INET;
2514 }
2515 else if (GNUNET_OK == allocate_v6_address (v6))
2516 { 2547 {
2517 *addr = v6; 2548 case AF_INET:
2518 *result_af = AF_INET6; 2549 if (GNUNET_OK != allocate_v4_address(v4))
2550 *result_af = AF_UNSPEC;
2551 else
2552 *addr = v4;
2553 break;
2554
2555 case AF_INET6:
2556 if (GNUNET_OK != allocate_v6_address(v6))
2557 *result_af = AF_UNSPEC;
2558 else
2559 *addr = v6;
2560 break;
2561
2562 case AF_UNSPEC:
2563 if (GNUNET_OK == allocate_v4_address(v4))
2564 {
2565 *addr = v4;
2566 *result_af = AF_INET;
2567 }
2568 else if (GNUNET_OK == allocate_v6_address(v6))
2569 {
2570 *addr = v6;
2571 *result_af = AF_INET6;
2572 }
2573 break;
2574
2575 default:
2576 GNUNET_break(0);
2577 return GNUNET_SYSERR;
2519 } 2578 }
2520 break;
2521 default:
2522 GNUNET_break (0);
2523 return GNUNET_SYSERR;
2524 }
2525 return GNUNET_OK; 2579 return GNUNET_OK;
2526} 2580}
2527 2581
@@ -2536,34 +2590,36 @@ allocate_response_ip (int *result_af,
2536 * @return #GNUNET_OK if @a msg is well-formed 2590 * @return #GNUNET_OK if @a msg is well-formed
2537 */ 2591 */
2538static int 2592static int
2539check_client_redirect_to_ip (void *cls, 2593check_client_redirect_to_ip(void *cls,
2540 const struct RedirectToIpRequestMessage *msg) 2594 const struct RedirectToIpRequestMessage *msg)
2541{ 2595{
2542 size_t alen; 2596 size_t alen;
2543 int addr_af; 2597 int addr_af;
2544 2598
2545 alen = ntohs (msg->header.size) - sizeof (struct RedirectToIpRequestMessage); 2599 alen = ntohs(msg->header.size) - sizeof(struct RedirectToIpRequestMessage);
2546 addr_af = (int) htonl (msg->addr_af); 2600 addr_af = (int)htonl(msg->addr_af);
2547 switch (addr_af) 2601 switch (addr_af)
2548 {
2549 case AF_INET:
2550 if (alen != sizeof (struct in_addr))
2551 {
2552 GNUNET_break (0);
2553 return GNUNET_SYSERR;
2554 }
2555 break;
2556 case AF_INET6:
2557 if (alen != sizeof (struct in6_addr))
2558 { 2602 {
2559 GNUNET_break (0); 2603 case AF_INET:
2604 if (alen != sizeof(struct in_addr))
2605 {
2606 GNUNET_break(0);
2607 return GNUNET_SYSERR;
2608 }
2609 break;
2610
2611 case AF_INET6:
2612 if (alen != sizeof(struct in6_addr))
2613 {
2614 GNUNET_break(0);
2615 return GNUNET_SYSERR;
2616 }
2617 break;
2618
2619 default:
2620 GNUNET_break(0);
2560 return GNUNET_SYSERR; 2621 return GNUNET_SYSERR;
2561 } 2622 }
2562 break;
2563 default:
2564 GNUNET_break (0);
2565 return GNUNET_SYSERR;
2566 }
2567 return GNUNET_OK; 2623 return GNUNET_OK;
2568} 2624}
2569 2625
@@ -2577,8 +2633,8 @@ check_client_redirect_to_ip (void *cls,
2577 * @param msg redirection request 2633 * @param msg redirection request
2578 */ 2634 */
2579static void 2635static void
2580handle_client_redirect_to_ip (void *cls, 2636handle_client_redirect_to_ip(void *cls,
2581 const struct RedirectToIpRequestMessage *msg) 2637 const struct RedirectToIpRequestMessage *msg)
2582{ 2638{
2583 struct GNUNET_SERVICE_Client *client = cls; 2639 struct GNUNET_SERVICE_Client *client = cls;
2584 size_t alen; 2640 size_t alen;
@@ -2590,59 +2646,59 @@ handle_client_redirect_to_ip (void *cls,
2590 struct DestinationEntry *de; 2646 struct DestinationEntry *de;
2591 struct GNUNET_HashCode key; 2647 struct GNUNET_HashCode key;
2592 2648
2593 alen = ntohs (msg->header.size) - sizeof (struct RedirectToIpRequestMessage); 2649 alen = ntohs(msg->header.size) - sizeof(struct RedirectToIpRequestMessage);
2594 addr_af = (int) htonl (msg->addr_af); 2650 addr_af = (int)htonl(msg->addr_af);
2595 /* allocate response IP */ 2651 /* allocate response IP */
2596 result_af = (int) htonl (msg->result_af); 2652 result_af = (int)htonl(msg->result_af);
2597 if (GNUNET_OK != allocate_response_ip (&result_af, &addr, &v4, &v6)) 2653 if (GNUNET_OK != allocate_response_ip(&result_af, &addr, &v4, &v6))
2598 { 2654 {
2599 GNUNET_SERVICE_client_drop (client); 2655 GNUNET_SERVICE_client_drop(client);
2600 return; 2656 return;
2601 } 2657 }
2602 /* send reply with our IP address */ 2658 /* send reply with our IP address */
2603 send_client_reply (client, msg->request_id, result_af, addr); 2659 send_client_reply(client, msg->request_id, result_af, addr);
2604 if (result_af == AF_UNSPEC) 2660 if (result_af == AF_UNSPEC)
2605 { 2661 {
2606 /* failure, we're done */ 2662 /* failure, we're done */
2607 GNUNET_SERVICE_client_continue (client); 2663 GNUNET_SERVICE_client_continue(client);
2608 return; 2664 return;
2609 } 2665 }
2610 2666
2611 { 2667 {
2612 char sbuf[INET6_ADDRSTRLEN]; 2668 char sbuf[INET6_ADDRSTRLEN];
2613 char dbuf[INET6_ADDRSTRLEN]; 2669 char dbuf[INET6_ADDRSTRLEN];
2614 2670
2615 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2671 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2616 "Allocated address %s for redirection via exit to %s\n", 2672 "Allocated address %s for redirection via exit to %s\n",
2617 inet_ntop (result_af, addr, sbuf, sizeof (sbuf)), 2673 inet_ntop(result_af, addr, sbuf, sizeof(sbuf)),
2618 inet_ntop (addr_af, &msg[1], dbuf, sizeof (dbuf))); 2674 inet_ntop(addr_af, &msg[1], dbuf, sizeof(dbuf)));
2619 } 2675 }
2620 2676
2621 /* setup destination record */ 2677 /* setup destination record */
2622 de = GNUNET_new (struct DestinationEntry); 2678 de = GNUNET_new(struct DestinationEntry);
2623 de->is_service = GNUNET_NO; 2679 de->is_service = GNUNET_NO;
2624 de->details.exit_destination.af = addr_af; 2680 de->details.exit_destination.af = addr_af;
2625 GNUNET_memcpy (&de->details.exit_destination.ip, &msg[1], alen); 2681 GNUNET_memcpy(&de->details.exit_destination.ip, &msg[1], alen);
2626 get_destination_key_from_ip (result_af, addr, &key); 2682 get_destination_key_from_ip(result_af, addr, &key);
2627 de->key = key; 2683 de->key = key;
2628 GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put ( 2684 GNUNET_assert(GNUNET_OK == GNUNET_CONTAINER_multihashmap_put(
2629 destination_map, 2685 destination_map,
2630 &key, 2686 &key,
2631 de, 2687 de,
2632 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); 2688 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
2633 de->heap_node = GNUNET_CONTAINER_heap_insert (destination_heap, 2689 de->heap_node = GNUNET_CONTAINER_heap_insert(destination_heap,
2634 de, 2690 de,
2635 GNUNET_TIME_absolute_ntoh ( 2691 GNUNET_TIME_absolute_ntoh(
2636 msg->expiration_time) 2692 msg->expiration_time)
2637 .abs_value_us); 2693 .abs_value_us);
2638 GNUNET_STATISTICS_update (stats, 2694 GNUNET_STATISTICS_update(stats,
2639 gettext_noop ("# Active destinations"), 2695 gettext_noop("# Active destinations"),
2640 1, 2696 1,
2641 GNUNET_NO); 2697 GNUNET_NO);
2642 while (GNUNET_CONTAINER_multihashmap_size (destination_map) > 2698 while (GNUNET_CONTAINER_multihashmap_size(destination_map) >
2643 max_destination_mappings) 2699 max_destination_mappings)
2644 expire_destination (de); 2700 expire_destination(de);
2645 GNUNET_SERVICE_client_continue (client); 2701 GNUNET_SERVICE_client_continue(client);
2646} 2702}
2647 2703
2648 2704
@@ -2655,7 +2711,7 @@ handle_client_redirect_to_ip (void *cls,
2655 * @param msg redirection request 2711 * @param msg redirection request
2656 */ 2712 */
2657static void 2713static void
2658handle_client_redirect_to_service ( 2714handle_client_redirect_to_service(
2659 void *cls, 2715 void *cls,
2660 const struct RedirectToServiceRequestMessage *msg) 2716 const struct RedirectToServiceRequestMessage *msg)
2661{ 2717{
@@ -2669,59 +2725,59 @@ handle_client_redirect_to_service (
2669 struct DestinationChannel *dt; 2725 struct DestinationChannel *dt;
2670 2726
2671 /* allocate response IP */ 2727 /* allocate response IP */
2672 result_af = (int) htonl (msg->result_af); 2728 result_af = (int)htonl(msg->result_af);
2673 if (GNUNET_OK != allocate_response_ip (&result_af, &addr, &v4, &v6)) 2729 if (GNUNET_OK != allocate_response_ip(&result_af, &addr, &v4, &v6))
2674 { 2730 {
2675 GNUNET_break (0); 2731 GNUNET_break(0);
2676 GNUNET_SERVICE_client_drop (client); 2732 GNUNET_SERVICE_client_drop(client);
2677 return; 2733 return;
2678 } 2734 }
2679 send_client_reply (client, msg->request_id, result_af, addr); 2735 send_client_reply(client, msg->request_id, result_af, addr);
2680 if (result_af == AF_UNSPEC) 2736 if (result_af == AF_UNSPEC)
2681 { 2737 {
2682 /* failure, we're done */ 2738 /* failure, we're done */
2683 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2739 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
2684 _ ("Failed to allocate IP address for new destination\n")); 2740 _("Failed to allocate IP address for new destination\n"));
2685 GNUNET_SERVICE_client_continue (client); 2741 GNUNET_SERVICE_client_continue(client);
2686 return; 2742 return;
2687 } 2743 }
2688 2744
2689 { 2745 {
2690 char sbuf[INET6_ADDRSTRLEN]; 2746 char sbuf[INET6_ADDRSTRLEN];
2691 2747
2692 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2748 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2693 "Allocated address %s for redirection to service %s on peer %s\n", 2749 "Allocated address %s for redirection to service %s on peer %s\n",
2694 inet_ntop (result_af, addr, sbuf, sizeof (sbuf)), 2750 inet_ntop(result_af, addr, sbuf, sizeof(sbuf)),
2695 GNUNET_h2s (&msg->service_descriptor), 2751 GNUNET_h2s(&msg->service_descriptor),
2696 GNUNET_i2s (&msg->target)); 2752 GNUNET_i2s(&msg->target));
2697 } 2753 }
2698 2754
2699 /* setup destination record */ 2755 /* setup destination record */
2700 de = GNUNET_new (struct DestinationEntry); 2756 de = GNUNET_new(struct DestinationEntry);
2701 de->is_service = GNUNET_YES; 2757 de->is_service = GNUNET_YES;
2702 de->details.service_destination.target = msg->target; 2758 de->details.service_destination.target = msg->target;
2703 de->details.service_destination.service_descriptor = msg->service_descriptor; 2759 de->details.service_destination.service_descriptor = msg->service_descriptor;
2704 get_destination_key_from_ip (result_af, addr, &key); 2760 get_destination_key_from_ip(result_af, addr, &key);
2705 de->key = key; 2761 de->key = key;
2706 GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put ( 2762 GNUNET_assert(GNUNET_OK == GNUNET_CONTAINER_multihashmap_put(
2707 destination_map, 2763 destination_map,
2708 &key, 2764 &key,
2709 de, 2765 de,
2710 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); 2766 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
2711 de->heap_node = GNUNET_CONTAINER_heap_insert (destination_heap, 2767 de->heap_node = GNUNET_CONTAINER_heap_insert(destination_heap,
2712 de, 2768 de,
2713 GNUNET_TIME_absolute_ntoh ( 2769 GNUNET_TIME_absolute_ntoh(
2714 msg->expiration_time) 2770 msg->expiration_time)
2715 .abs_value_us); 2771 .abs_value_us);
2716 while (GNUNET_CONTAINER_multihashmap_size (destination_map) > 2772 while (GNUNET_CONTAINER_multihashmap_size(destination_map) >
2717 max_destination_mappings) 2773 max_destination_mappings)
2718 expire_destination (de); 2774 expire_destination(de);
2719 2775
2720 dt = GNUNET_new (struct DestinationChannel); 2776 dt = GNUNET_new(struct DestinationChannel);
2721 dt->destination = de; 2777 dt->destination = de;
2722 GNUNET_CONTAINER_DLL_insert (de->dt_head, de->dt_tail, dt); 2778 GNUNET_CONTAINER_DLL_insert(de->dt_head, de->dt_tail, dt);
2723 /* we're done */ 2779 /* we're done */
2724 GNUNET_SERVICE_client_continue (client); 2780 GNUNET_SERVICE_client_continue(client);
2725} 2781}
2726 2782
2727 2783
@@ -2734,11 +2790,11 @@ handle_client_redirect_to_service (
2734 * @return #GNUNET_OK (continue to iterate) 2790 * @return #GNUNET_OK (continue to iterate)
2735 */ 2791 */
2736static int 2792static int
2737cleanup_destination (void *cls, const struct GNUNET_HashCode *key, void *value) 2793cleanup_destination(void *cls, const struct GNUNET_HashCode *key, void *value)
2738{ 2794{
2739 struct DestinationEntry *de = value; 2795 struct DestinationEntry *de = value;
2740 2796
2741 free_destination_entry (de); 2797 free_destination_entry(de);
2742 return GNUNET_OK; 2798 return GNUNET_OK;
2743} 2799}
2744 2800
@@ -2752,14 +2808,14 @@ cleanup_destination (void *cls, const struct GNUNET_HashCode *key, void *value)
2752 * @return #GNUNET_OK (continue to iterate) 2808 * @return #GNUNET_OK (continue to iterate)
2753 */ 2809 */
2754static int 2810static int
2755cleanup_channel (void *cls, const struct GNUNET_HashCode *key, void *value) 2811cleanup_channel(void *cls, const struct GNUNET_HashCode *key, void *value)
2756{ 2812{
2757 struct ChannelState *ts = value; 2813 struct ChannelState *ts = value;
2758 2814
2759 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2815 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2760 "Tearing down channel to `%s' during cleanup\n", 2816 "Tearing down channel to `%s' during cleanup\n",
2761 print_channel_destination (&ts->destination)); 2817 print_channel_destination(&ts->destination));
2762 free_channel_state (ts); 2818 free_channel_state(ts);
2763 return GNUNET_OK; 2819 return GNUNET_OK;
2764} 2820}
2765 2821
@@ -2770,53 +2826,53 @@ cleanup_channel (void *cls, const struct GNUNET_HashCode *key, void *value)
2770 * @param cls unused 2826 * @param cls unused
2771 */ 2827 */
2772static void 2828static void
2773cleanup (void *cls) 2829cleanup(void *cls)
2774{ 2830{
2775 unsigned int i; 2831 unsigned int i;
2776 2832
2777 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "VPN is shutting down\n"); 2833 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "VPN is shutting down\n");
2778 if (NULL != destination_map) 2834 if (NULL != destination_map)
2779 { 2835 {
2780 GNUNET_CONTAINER_multihashmap_iterate (destination_map, 2836 GNUNET_CONTAINER_multihashmap_iterate(destination_map,
2781 &cleanup_destination, 2837 &cleanup_destination,
2782 NULL); 2838 NULL);
2783 GNUNET_CONTAINER_multihashmap_destroy (destination_map); 2839 GNUNET_CONTAINER_multihashmap_destroy(destination_map);
2784 destination_map = NULL; 2840 destination_map = NULL;
2785 } 2841 }
2786 if (NULL != destination_heap) 2842 if (NULL != destination_heap)
2787 { 2843 {
2788 GNUNET_CONTAINER_heap_destroy (destination_heap); 2844 GNUNET_CONTAINER_heap_destroy(destination_heap);
2789 destination_heap = NULL; 2845 destination_heap = NULL;
2790 } 2846 }
2791 if (NULL != channel_map) 2847 if (NULL != channel_map)
2792 { 2848 {
2793 GNUNET_CONTAINER_multihashmap_iterate (channel_map, &cleanup_channel, NULL); 2849 GNUNET_CONTAINER_multihashmap_iterate(channel_map, &cleanup_channel, NULL);
2794 GNUNET_CONTAINER_multihashmap_destroy (channel_map); 2850 GNUNET_CONTAINER_multihashmap_destroy(channel_map);
2795 channel_map = NULL; 2851 channel_map = NULL;
2796 } 2852 }
2797 if (NULL != channel_heap) 2853 if (NULL != channel_heap)
2798 { 2854 {
2799 GNUNET_CONTAINER_heap_destroy (channel_heap); 2855 GNUNET_CONTAINER_heap_destroy(channel_heap);
2800 channel_heap = NULL; 2856 channel_heap = NULL;
2801 } 2857 }
2802 if (NULL != cadet_handle) 2858 if (NULL != cadet_handle)
2803 { 2859 {
2804 GNUNET_CADET_disconnect (cadet_handle); 2860 GNUNET_CADET_disconnect(cadet_handle);
2805 cadet_handle = NULL; 2861 cadet_handle = NULL;
2806 } 2862 }
2807 if (NULL != helper_handle) 2863 if (NULL != helper_handle)
2808 { 2864 {
2809 GNUNET_HELPER_kill (helper_handle, GNUNET_NO); 2865 GNUNET_HELPER_kill(helper_handle, GNUNET_NO);
2810 GNUNET_HELPER_wait (helper_handle); 2866 GNUNET_HELPER_wait(helper_handle);
2811 helper_handle = NULL; 2867 helper_handle = NULL;
2812 } 2868 }
2813 if (NULL != stats) 2869 if (NULL != stats)
2814 { 2870 {
2815 GNUNET_STATISTICS_destroy (stats, GNUNET_NO); 2871 GNUNET_STATISTICS_destroy(stats, GNUNET_NO);
2816 stats = NULL; 2872 stats = NULL;
2817 } 2873 }
2818 for (i = 0; i < 5; i++) 2874 for (i = 0; i < 5; i++)
2819 GNUNET_free_non_null (vpn_argv[i]); 2875 GNUNET_free_non_null(vpn_argv[i]);
2820} 2876}
2821 2877
2822 2878
@@ -2829,9 +2885,9 @@ cleanup (void *cls)
2829 * @return @a c 2885 * @return @a c
2830 */ 2886 */
2831static void * 2887static void *
2832client_connect_cb (void *cls, 2888client_connect_cb(void *cls,
2833 struct GNUNET_SERVICE_Client *c, 2889 struct GNUNET_SERVICE_Client *c,
2834 struct GNUNET_MQ_Handle *mq) 2890 struct GNUNET_MQ_Handle *mq)
2835{ 2891{
2836 return c; 2892 return c;
2837} 2893}
@@ -2845,11 +2901,11 @@ client_connect_cb (void *cls,
2845 * @param internal_cls should be equal to @a c 2901 * @param internal_cls should be equal to @a c
2846 */ 2902 */
2847static void 2903static void
2848client_disconnect_cb (void *cls, 2904client_disconnect_cb(void *cls,
2849 struct GNUNET_SERVICE_Client *c, 2905 struct GNUNET_SERVICE_Client *c,
2850 void *internal_cls) 2906 void *internal_cls)
2851{ 2907{
2852 GNUNET_assert (c == internal_cls); 2908 GNUNET_assert(c == internal_cls);
2853} 2909}
2854 2910
2855 2911
@@ -2861,9 +2917,9 @@ client_disconnect_cb (void *cls,
2861 * @param service the initialized service 2917 * @param service the initialized service
2862 */ 2918 */
2863static void 2919static void
2864run (void *cls, 2920run(void *cls,
2865 const struct GNUNET_CONFIGURATION_Handle *cfg_, 2921 const struct GNUNET_CONFIGURATION_Handle *cfg_,
2866 struct GNUNET_SERVICE_Handle *service) 2922 struct GNUNET_SERVICE_Handle *service)
2867{ 2923{
2868 char *ifname; 2924 char *ifname;
2869 char *ipv6addr; 2925 char *ipv6addr;
@@ -2874,187 +2930,187 @@ run (void *cls,
2874 struct in6_addr v6; 2930 struct in6_addr v6;
2875 char *binary; 2931 char *binary;
2876 2932
2877 binary = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-vpn"); 2933 binary = GNUNET_OS_get_libexec_binary_path("gnunet-helper-vpn");
2878 2934
2879 if (GNUNET_YES != 2935 if (GNUNET_YES !=
2880 GNUNET_OS_check_helper_binary ( 2936 GNUNET_OS_check_helper_binary(
2881 binary, 2937 binary,
2882 GNUNET_YES, 2938 GNUNET_YES,
2883 "-d gnunet-vpn - - 169.1.3.3.7 255.255.255.0")) //ipv4 only please! 2939 "-d gnunet-vpn - - 169.1.3.3.7 255.255.255.0")) //ipv4 only please!
2884 { 2940 {
2885 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2941 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
2886 "`%s' is not SUID, refusing to run.\n", 2942 "`%s' is not SUID, refusing to run.\n",
2887 "gnunet-helper-vpn"); 2943 "gnunet-helper-vpn");
2888 GNUNET_free (binary); 2944 GNUNET_free(binary);
2889 global_ret = 1; 2945 global_ret = 1;
2890 /* we won't "really" exit here, as the 'service' is still running; 2946 /* we won't "really" exit here, as the 'service' is still running;
2891 however, as no handlers are registered, the service won't do 2947 however, as no handlers are registered, the service won't do
2892 anything either */ 2948 anything either */
2893 return; 2949 return;
2894 } 2950 }
2895 GNUNET_free (binary); 2951 GNUNET_free(binary);
2896 cfg = cfg_; 2952 cfg = cfg_;
2897 stats = GNUNET_STATISTICS_create ("vpn", cfg); 2953 stats = GNUNET_STATISTICS_create("vpn", cfg);
2898 if (GNUNET_OK != 2954 if (GNUNET_OK !=
2899 GNUNET_CONFIGURATION_get_value_number (cfg, 2955 GNUNET_CONFIGURATION_get_value_number(cfg,
2900 "VPN", 2956 "VPN",
2901 "MAX_MAPPING", 2957 "MAX_MAPPING",
2902 &max_destination_mappings)) 2958 &max_destination_mappings))
2903 max_destination_mappings = 200; 2959 max_destination_mappings = 200;
2904 if (GNUNET_OK != 2960 if (GNUNET_OK !=
2905 GNUNET_CONFIGURATION_get_value_number (cfg, 2961 GNUNET_CONFIGURATION_get_value_number(cfg,
2906 "VPN", 2962 "VPN",
2907 "MAX_TUNNELS", 2963 "MAX_TUNNELS",
2908 &max_channel_mappings)) 2964 &max_channel_mappings))
2909 max_channel_mappings = 200; 2965 max_channel_mappings = 200;
2910 2966
2911 destination_map = 2967 destination_map =
2912 GNUNET_CONTAINER_multihashmap_create (max_destination_mappings * 2, 2968 GNUNET_CONTAINER_multihashmap_create(max_destination_mappings * 2,
2913 GNUNET_NO); 2969 GNUNET_NO);
2914 destination_heap = 2970 destination_heap =
2915 GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); 2971 GNUNET_CONTAINER_heap_create(GNUNET_CONTAINER_HEAP_ORDER_MIN);
2916 channel_map = 2972 channel_map =
2917 GNUNET_CONTAINER_multihashmap_create (max_channel_mappings * 2, GNUNET_NO); 2973 GNUNET_CONTAINER_multihashmap_create(max_channel_mappings * 2, GNUNET_NO);
2918 channel_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); 2974 channel_heap = GNUNET_CONTAINER_heap_create(GNUNET_CONTAINER_HEAP_ORDER_MIN);
2919 2975
2920 2976
2921 vpn_argv[0] = GNUNET_strdup ("vpn-gnunet"); 2977 vpn_argv[0] = GNUNET_strdup("vpn-gnunet");
2922 if (GNUNET_SYSERR == 2978 if (GNUNET_SYSERR ==
2923 GNUNET_CONFIGURATION_get_value_string (cfg, "VPN", "IFNAME", &ifname)) 2979 GNUNET_CONFIGURATION_get_value_string(cfg, "VPN", "IFNAME", &ifname))
2924 {
2925 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "VPN", "IFNAME");
2926 GNUNET_SCHEDULER_shutdown ();
2927 return;
2928 }
2929 vpn_argv[1] = ifname;
2930 ipv6addr = NULL;
2931 if (GNUNET_OK == GNUNET_NETWORK_test_pf (PF_INET6))
2932 {
2933 if ((GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
2934 "VPN",
2935 "IPV6ADDR",
2936 &ipv6addr) ||
2937 (1 != inet_pton (AF_INET6, ipv6addr, &v6))))
2938 {
2939 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
2940 "VPN",
2941 "IPV6ADDR",
2942 _ ("Must specify valid IPv6 address"));
2943 GNUNET_SCHEDULER_shutdown ();
2944 GNUNET_free_non_null (ipv6addr);
2945 return;
2946 }
2947 vpn_argv[2] = ipv6addr;
2948 ipv6prefix_s = NULL;
2949 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
2950 "VPN",
2951 "IPV6PREFIX",
2952 &ipv6prefix_s))
2953 { 2980 {
2954 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "VPN", "IPV6PREFIX"); 2981 GNUNET_log_config_missing(GNUNET_ERROR_TYPE_ERROR, "VPN", "IFNAME");
2955 GNUNET_SCHEDULER_shutdown (); 2982 GNUNET_SCHEDULER_shutdown();
2956 GNUNET_free_non_null (ipv6prefix_s);
2957 return; 2983 return;
2958 } 2984 }
2959 vpn_argv[3] = ipv6prefix_s; 2985 vpn_argv[1] = ifname;
2960 if ((GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, 2986 ipv6addr = NULL;
2961 "VPN", 2987 if (GNUNET_OK == GNUNET_NETWORK_test_pf(PF_INET6))
2962 "IPV6PREFIX",
2963 &ipv6prefix)) ||
2964 (ipv6prefix >= 127))
2965 { 2988 {
2966 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, 2989 if ((GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg,
2967 "VPN", 2990 "VPN",
2968 "IPV4MASK", 2991 "IPV6ADDR",
2969 _ ("Must specify valid IPv6 mask")); 2992 &ipv6addr) ||
2970 GNUNET_SCHEDULER_shutdown (); 2993 (1 != inet_pton(AF_INET6, ipv6addr, &v6))))
2971 return; 2994 {
2995 GNUNET_log_config_invalid(GNUNET_ERROR_TYPE_ERROR,
2996 "VPN",
2997 "IPV6ADDR",
2998 _("Must specify valid IPv6 address"));
2999 GNUNET_SCHEDULER_shutdown();
3000 GNUNET_free_non_null(ipv6addr);
3001 return;
3002 }
3003 vpn_argv[2] = ipv6addr;
3004 ipv6prefix_s = NULL;
3005 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg,
3006 "VPN",
3007 "IPV6PREFIX",
3008 &ipv6prefix_s))
3009 {
3010 GNUNET_log_config_missing(GNUNET_ERROR_TYPE_ERROR, "VPN", "IPV6PREFIX");
3011 GNUNET_SCHEDULER_shutdown();
3012 GNUNET_free_non_null(ipv6prefix_s);
3013 return;
3014 }
3015 vpn_argv[3] = ipv6prefix_s;
3016 if ((GNUNET_OK != GNUNET_CONFIGURATION_get_value_number(cfg,
3017 "VPN",
3018 "IPV6PREFIX",
3019 &ipv6prefix)) ||
3020 (ipv6prefix >= 127))
3021 {
3022 GNUNET_log_config_invalid(GNUNET_ERROR_TYPE_ERROR,
3023 "VPN",
3024 "IPV4MASK",
3025 _("Must specify valid IPv6 mask"));
3026 GNUNET_SCHEDULER_shutdown();
3027 return;
3028 }
2972 } 3029 }
2973 }
2974 else 3030 else
2975 {
2976 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2977 _ (
2978 "IPv6 support disabled as this system does not support IPv6\n"));
2979 vpn_argv[2] = GNUNET_strdup ("-");
2980 vpn_argv[3] = GNUNET_strdup ("-");
2981 }
2982 if (GNUNET_OK == GNUNET_NETWORK_test_pf (PF_INET))
2983 {
2984 ipv4addr = NULL;
2985 if ((GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
2986 "vpn",
2987 "IPV4ADDR",
2988 &ipv4addr) ||
2989 (1 != inet_pton (AF_INET, ipv4addr, &v4))))
2990 { 3031 {
2991 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, 3032 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
2992 "VPN", 3033 _(
2993 "IPV4ADDR", 3034 "IPv6 support disabled as this system does not support IPv6\n"));
2994 _ ("Must specify valid IPv4 address")); 3035 vpn_argv[2] = GNUNET_strdup("-");
2995 GNUNET_SCHEDULER_shutdown (); 3036 vpn_argv[3] = GNUNET_strdup("-");
2996 GNUNET_free_non_null (ipv4addr);
2997 return;
2998 } 3037 }
2999 vpn_argv[4] = ipv4addr; 3038 if (GNUNET_OK == GNUNET_NETWORK_test_pf(PF_INET))
3000 ipv4mask = NULL;
3001 if ((GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
3002 "vpn",
3003 "IPV4MASK",
3004 &ipv4mask) ||
3005 (1 != inet_pton (AF_INET, ipv4mask, &v4))))
3006 { 3039 {
3007 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, 3040 ipv4addr = NULL;
3008 "VPN", 3041 if ((GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg,
3009 "IPV4MASK", 3042 "vpn",
3010 _ ("Must specify valid IPv4 mask")); 3043 "IPV4ADDR",
3011 GNUNET_SCHEDULER_shutdown (); 3044 &ipv4addr) ||
3012 GNUNET_free_non_null (ipv4mask); 3045 (1 != inet_pton(AF_INET, ipv4addr, &v4))))
3013 return; 3046 {
3047 GNUNET_log_config_invalid(GNUNET_ERROR_TYPE_ERROR,
3048 "VPN",
3049 "IPV4ADDR",
3050 _("Must specify valid IPv4 address"));
3051 GNUNET_SCHEDULER_shutdown();
3052 GNUNET_free_non_null(ipv4addr);
3053 return;
3054 }
3055 vpn_argv[4] = ipv4addr;
3056 ipv4mask = NULL;
3057 if ((GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg,
3058 "vpn",
3059 "IPV4MASK",
3060 &ipv4mask) ||
3061 (1 != inet_pton(AF_INET, ipv4mask, &v4))))
3062 {
3063 GNUNET_log_config_invalid(GNUNET_ERROR_TYPE_ERROR,
3064 "VPN",
3065 "IPV4MASK",
3066 _("Must specify valid IPv4 mask"));
3067 GNUNET_SCHEDULER_shutdown();
3068 GNUNET_free_non_null(ipv4mask);
3069 return;
3070 }
3071 vpn_argv[5] = ipv4mask;
3014 } 3072 }
3015 vpn_argv[5] = ipv4mask;
3016 }
3017 else 3073 else
3018 { 3074 {
3019 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 3075 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
3020 _ ( 3076 _(
3021 "IPv4 support disabled as this system does not support IPv4\n")); 3077 "IPv4 support disabled as this system does not support IPv4\n"));
3022 vpn_argv[4] = GNUNET_strdup ("-"); 3078 vpn_argv[4] = GNUNET_strdup("-");
3023 vpn_argv[5] = GNUNET_strdup ("-"); 3079 vpn_argv[5] = GNUNET_strdup("-");
3024 } 3080 }
3025 vpn_argv[6] = NULL; 3081 vpn_argv[6] = NULL;
3026 3082
3027 cadet_handle = GNUNET_CADET_connect (cfg_); 3083 cadet_handle = GNUNET_CADET_connect(cfg_);
3028 // FIXME never opens ports??? 3084 // FIXME never opens ports???
3029 helper_handle = GNUNET_HELPER_start (GNUNET_NO, 3085 helper_handle = GNUNET_HELPER_start(GNUNET_NO,
3030 "gnunet-helper-vpn", 3086 "gnunet-helper-vpn",
3031 vpn_argv, 3087 vpn_argv,
3032 &message_token, 3088 &message_token,
3033 NULL, 3089 NULL,
3034 NULL); 3090 NULL);
3035 GNUNET_SCHEDULER_add_shutdown (&cleanup, NULL); 3091 GNUNET_SCHEDULER_add_shutdown(&cleanup, NULL);
3036} 3092}
3037 3093
3038 3094
3039/** 3095/**
3040 * Define "main" method using service macro. 3096 * Define "main" method using service macro.
3041 */ 3097 */
3042GNUNET_SERVICE_MAIN ( 3098GNUNET_SERVICE_MAIN(
3043 "vpn", 3099 "vpn",
3044 GNUNET_SERVICE_OPTION_NONE, 3100 GNUNET_SERVICE_OPTION_NONE,
3045 &run, 3101 &run,
3046 &client_connect_cb, 3102 &client_connect_cb,
3047 &client_disconnect_cb, 3103 &client_disconnect_cb,
3048 NULL, 3104 NULL,
3049 GNUNET_MQ_hd_var_size (client_redirect_to_ip, 3105 GNUNET_MQ_hd_var_size(client_redirect_to_ip,
3050 GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_IP, 3106 GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_IP,
3051 struct RedirectToIpRequestMessage, 3107 struct RedirectToIpRequestMessage,
3052 NULL), 3108 NULL),
3053 GNUNET_MQ_hd_fixed_size (client_redirect_to_service, 3109 GNUNET_MQ_hd_fixed_size(client_redirect_to_service,
3054 GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_SERVICE, 3110 GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_SERVICE,
3055 struct RedirectToServiceRequestMessage, 3111 struct RedirectToServiceRequestMessage,
3056 NULL), 3112 NULL),
3057 GNUNET_MQ_handler_end ()); 3113 GNUNET_MQ_handler_end());
3058 3114
3059 3115
3060/* end of gnunet-service-vpn.c */ 3116/* end of gnunet-service-vpn.c */