diff options
author | Christian Grothoff <christian@grothoff.org> | 2017-02-22 17:32:15 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2017-02-22 17:32:15 +0100 |
commit | 88a0df3dcc38c6e82f483bff386c87d8e1ec4459 (patch) | |
tree | c086b6c30a6fc54e0d72aabe7857f3b659915caa /src/vpn | |
parent | 85088f7eedd1146890a5ce9af05fff934a5b1b8d (diff) | |
download | gnunet-88a0df3dcc38c6e82f483bff386c87d8e1ec4459.tar.gz gnunet-88a0df3dcc38c6e82f483bff386c87d8e1ec4459.zip |
converting 'vpn' to new CADET API, not tested/testable, as exit is not converted yet
Diffstat (limited to 'src/vpn')
-rw-r--r-- | src/vpn/Makefile.am | 4 | ||||
-rw-r--r-- | src/vpn/gnunet-service-vpn.c | 1753 |
2 files changed, 844 insertions, 913 deletions
diff --git a/src/vpn/Makefile.am b/src/vpn/Makefile.am index 5517a45e3..417d2eb89 100644 --- a/src/vpn/Makefile.am +++ b/src/vpn/Makefile.am | |||
@@ -59,7 +59,7 @@ gnunet_service_vpn_LDADD = \ | |||
59 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | 59 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ |
60 | $(top_builddir)/src/tun/libgnunettun.la \ | 60 | $(top_builddir)/src/tun/libgnunettun.la \ |
61 | $(top_builddir)/src/util/libgnunetutil.la \ | 61 | $(top_builddir)/src/util/libgnunetutil.la \ |
62 | $(top_builddir)/src/cadet/libgnunetcadet.la \ | 62 | $(top_builddir)/src/cadet/libgnunetcadetnew.la \ |
63 | $(top_builddir)/src/regex/libgnunetregex.la \ | 63 | $(top_builddir)/src/regex/libgnunetregex.la \ |
64 | $(GN_LIBINTL) | 64 | $(GN_LIBINTL) |
65 | gnunet_service_vpn_CFLAGS = \ | 65 | gnunet_service_vpn_CFLAGS = \ |
@@ -79,5 +79,3 @@ libgnunetvpn_la_LIBADD = \ | |||
79 | $(top_builddir)/src/util/libgnunetutil.la $(XLIB) | 79 | $(top_builddir)/src/util/libgnunetutil.la $(XLIB) |
80 | libgnunetvpn_la_LDFLAGS = \ | 80 | libgnunetvpn_la_LDFLAGS = \ |
81 | $(GN_LIB_LDFLAGS) | 81 | $(GN_LIB_LDFLAGS) |
82 | |||
83 | |||
diff --git a/src/vpn/gnunet-service-vpn.c b/src/vpn/gnunet-service-vpn.c index c66023c85..aa0ea51a3 100644 --- a/src/vpn/gnunet-service-vpn.c +++ b/src/vpn/gnunet-service-vpn.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2010, 2011, 2012, 2016 Christian Grothoff | 3 | Copyright (C) 2010, 2011, 2012, 2016, 2017 Christian Grothoff |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -221,11 +221,6 @@ struct ChannelState | |||
221 | struct GNUNET_REGEX_Search *search; | 221 | struct GNUNET_REGEX_Search *search; |
222 | 222 | ||
223 | /** | 223 | /** |
224 | * Active transmission handle, NULL for none. | ||
225 | */ | ||
226 | struct GNUNET_CADET_TransmitHandle *th; | ||
227 | |||
228 | /** | ||
229 | * Entry for this entry in the channel_heap, NULL as long as this | 224 | * Entry for this entry in the channel_heap, NULL as long as this |
230 | * channel state is not fully bound. | 225 | * channel state is not fully bound. |
231 | */ | 226 | */ |
@@ -535,11 +530,6 @@ free_channel_state (struct ChannelState *ts) | |||
535 | 530 | ||
536 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 531 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
537 | "Cleaning up channel state\n"); | 532 | "Cleaning up channel state\n"); |
538 | if (NULL != ts->th) | ||
539 | { | ||
540 | GNUNET_CADET_notify_transmit_ready_cancel (ts->th); | ||
541 | ts->th = NULL; | ||
542 | } | ||
543 | if (NULL != (channel = ts->channel)) | 533 | if (NULL != (channel = ts->channel)) |
544 | { | 534 | { |
545 | ts->channel = NULL; | 535 | ts->channel = NULL; |
@@ -585,97 +575,32 @@ free_channel_state (struct ChannelState *ts) | |||
585 | 575 | ||
586 | 576 | ||
587 | /** | 577 | /** |
588 | * Send a message from the message queue via cadet. | ||
589 | * | ||
590 | * @param cls the `struct ChannelState` with the message queue | ||
591 | * @param size number of bytes available in @a buf | ||
592 | * @param buf where to copy the message | ||
593 | * @return number of bytes copied to @a buf | ||
594 | */ | ||
595 | static size_t | ||
596 | send_to_peer_notify_callback (void *cls, size_t size, void *buf) | ||
597 | { | ||
598 | struct ChannelState *ts = cls; | ||
599 | struct ChannelMessageQueueEntry *tnq; | ||
600 | size_t ret; | ||
601 | |||
602 | ts->th = NULL; | ||
603 | if (NULL == buf) | ||
604 | return 0; | ||
605 | tnq = ts->tmq_head; | ||
606 | GNUNET_assert (NULL != tnq); | ||
607 | GNUNET_assert (size >= tnq->len); | ||
608 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
609 | "Sending %u bytes via cadet channel\n", | ||
610 | (unsigned int) tnq->len); | ||
611 | GNUNET_CONTAINER_DLL_remove (ts->tmq_head, | ||
612 | ts->tmq_tail, | ||
613 | tnq); | ||
614 | ts->tmq_length--; | ||
615 | GNUNET_memcpy (buf, tnq->msg, tnq->len); | ||
616 | ret = tnq->len; | ||
617 | GNUNET_free (tnq); | ||
618 | if (NULL != (tnq = ts->tmq_head)) | ||
619 | { | ||
620 | if (NULL == ts->th) | ||
621 | ts->th = GNUNET_CADET_notify_transmit_ready (ts->channel, | ||
622 | GNUNET_NO /* cork */, | ||
623 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
624 | tnq->len, | ||
625 | &send_to_peer_notify_callback, | ||
626 | ts); | ||
627 | } | ||
628 | GNUNET_STATISTICS_update (stats, | ||
629 | gettext_noop ("# Bytes given to cadet for transmission"), | ||
630 | ret, GNUNET_NO); | ||
631 | return ret; | ||
632 | } | ||
633 | |||
634 | |||
635 | /** | ||
636 | * Add the given message to the given channel and trigger the | 578 | * Add the given message to the given channel and trigger the |
637 | * transmission process. | 579 | * transmission process. |
638 | * | 580 | * |
639 | * @param tnq message to queue | ||
640 | * @param ts channel to queue the message for | 581 | * @param ts channel to queue the message for |
582 | * @param env message to queue | ||
641 | */ | 583 | */ |
642 | static void | 584 | static void |
643 | send_to_channel (struct ChannelMessageQueueEntry *tnq, | 585 | send_to_channel (struct ChannelState *ts, |
644 | struct ChannelState *ts) | 586 | struct GNUNET_MQ_Envelope *env) |
645 | { | 587 | { |
646 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 588 | struct GNUNET_MQ_Handle *mq; |
647 | "Queueing %u bytes for transmission via cadet channel\n", | 589 | |
648 | (unsigned int) tnq->len); | ||
649 | GNUNET_assert (NULL != ts->channel); | 590 | GNUNET_assert (NULL != ts->channel); |
650 | GNUNET_CONTAINER_DLL_insert_tail (ts->tmq_head, | 591 | mq = GNUNET_CADET_get_mq (ts->channel); |
651 | ts->tmq_tail, | 592 | GNUNET_MQ_send (mq, |
652 | tnq); | 593 | env); |
653 | ts->tmq_length++; | 594 | if (GNUNET_MQ_get_length (mq) > MAX_MESSAGE_QUEUE_SIZE) |
654 | if (ts->tmq_length > MAX_MESSAGE_QUEUE_SIZE) | ||
655 | { | 595 | { |
656 | struct ChannelMessageQueueEntry *dq; | 596 | env = GNUNET_MQ_unsent_head (mq); |
657 | 597 | GNUNET_assert (NULL != env); | |
658 | dq = ts->tmq_head; | ||
659 | GNUNET_assert (dq != tnq); | ||
660 | GNUNET_CONTAINER_DLL_remove (ts->tmq_head, | ||
661 | ts->tmq_tail, | ||
662 | dq); | ||
663 | ts->tmq_length--; | ||
664 | GNUNET_CADET_notify_transmit_ready_cancel (ts->th); | ||
665 | ts->th = NULL; | ||
666 | GNUNET_STATISTICS_update (stats, | 598 | GNUNET_STATISTICS_update (stats, |
667 | gettext_noop ("# Bytes dropped in cadet queue (overflow)"), | 599 | gettext_noop ("# Messages dropped in cadet queue (overflow)"), |
668 | dq->len, | 600 | 1, |
669 | GNUNET_NO); | 601 | GNUNET_NO); |
670 | GNUNET_free (dq); | 602 | GNUNET_MQ_discard (env); |
671 | } | 603 | } |
672 | if (NULL == ts->th) | ||
673 | ts->th = GNUNET_CADET_notify_transmit_ready (ts->channel, | ||
674 | GNUNET_NO /* cork */, | ||
675 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
676 | tnq->len, | ||
677 | &send_to_peer_notify_callback, | ||
678 | ts); | ||
679 | } | 604 | } |
680 | 605 | ||
681 | 606 | ||
@@ -710,6 +635,767 @@ print_channel_destination (const struct DestinationEntry *de) | |||
710 | 635 | ||
711 | 636 | ||
712 | /** | 637 | /** |
638 | * Function called whenever a channel is destroyed. Should clean up | ||
639 | * any associated state. | ||
640 | * | ||
641 | * @param cls our `struct ChannelState` | ||
642 | * @param channel connection to the other end (henceforth invalid) | ||
643 | */ | ||
644 | static void | ||
645 | channel_cleaner (void *cls, | ||
646 | const struct GNUNET_CADET_Channel *channel) | ||
647 | { | ||
648 | struct ChannelState *ts = cls; | ||
649 | |||
650 | ts->channel = NULL; /* we must not call GNUNET_CADET_channel_destroy() anymore */ | ||
651 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
652 | "CADET notified us about death of channel to `%s'\n", | ||
653 | print_channel_destination (&ts->destination)); | ||
654 | free_channel_state (ts); | ||
655 | } | ||
656 | |||
657 | |||
658 | /** | ||
659 | * Synthesize a plausible ICMP payload for an ICMP error | ||
660 | * response on the given channel. | ||
661 | * | ||
662 | * @param ts channel information | ||
663 | * @param ipp IPv4 header to fill in (ICMP payload) | ||
664 | * @param udp "UDP" header to fill in (ICMP payload); might actually | ||
665 | * also be the first 8 bytes of the TCP header | ||
666 | */ | ||
667 | static void | ||
668 | make_up_icmpv4_payload (struct ChannelState *ts, | ||
669 | struct GNUNET_TUN_IPv4Header *ipp, | ||
670 | struct GNUNET_TUN_UdpHeader *udp) | ||
671 | { | ||
672 | GNUNET_TUN_initialize_ipv4_header (ipp, | ||
673 | ts->protocol, | ||
674 | sizeof (struct GNUNET_TUN_TcpHeader), | ||
675 | &ts->source_ip.v4, | ||
676 | &ts->destination_ip.v4); | ||
677 | udp->source_port = htons (ts->source_port); | ||
678 | udp->destination_port = htons (ts->destination_port); | ||
679 | udp->len = htons (0); | ||
680 | udp->crc = htons (0); | ||
681 | } | ||
682 | |||
683 | |||
684 | /** | ||
685 | * Synthesize a plausible ICMP payload for an ICMP error | ||
686 | * response on the given channel. | ||
687 | * | ||
688 | * @param ts channel information | ||
689 | * @param ipp IPv6 header to fill in (ICMP payload) | ||
690 | * @param udp "UDP" header to fill in (ICMP payload); might actually | ||
691 | * also be the first 8 bytes of the TCP header | ||
692 | */ | ||
693 | static void | ||
694 | make_up_icmpv6_payload (struct ChannelState *ts, | ||
695 | struct GNUNET_TUN_IPv6Header *ipp, | ||
696 | struct GNUNET_TUN_UdpHeader *udp) | ||
697 | { | ||
698 | GNUNET_TUN_initialize_ipv6_header (ipp, | ||
699 | ts->protocol, | ||
700 | sizeof (struct GNUNET_TUN_TcpHeader), | ||
701 | &ts->source_ip.v6, | ||
702 | &ts->destination_ip.v6); | ||
703 | udp->source_port = htons (ts->source_port); | ||
704 | udp->destination_port = htons (ts->destination_port); | ||
705 | udp->len = htons (0); | ||
706 | udp->crc = htons (0); | ||
707 | } | ||
708 | |||
709 | |||
710 | /** | ||
711 | * We got an ICMP packet back from the CADET channel. Check it is OK. | ||
712 | * | ||
713 | * @param cls our `struct ChannelState *` | ||
714 | * @param message the actual message | ||
715 | * @return #GNUNET_OK to keep the connection open, | ||
716 | * #GNUNET_SYSERR to close it (signal serious error) | ||
717 | */ | ||
718 | static int | ||
719 | check_icmp_back (void *cls, | ||
720 | const struct GNUNET_EXIT_IcmpToVPNMessage *i2v) | ||
721 | { | ||
722 | struct ChannelState *ts = cls; | ||
723 | |||
724 | if (NULL == ts->heap_node) | ||
725 | { | ||
726 | GNUNET_break_op (0); | ||
727 | return GNUNET_SYSERR; | ||
728 | } | ||
729 | if (AF_UNSPEC == ts->af) | ||
730 | { | ||
731 | GNUNET_break_op (0); | ||
732 | return GNUNET_SYSERR; | ||
733 | } | ||
734 | return GNUNET_OK; | ||
735 | } | ||
736 | |||
737 | |||
738 | /** | ||
739 | * We got an ICMP packet back from the CADET channel. Pass it on to the | ||
740 | * local virtual interface via the helper. | ||
741 | * | ||
742 | * @param cls our `struct ChannelState *` | ||
743 | * @param message the actual message | ||
744 | */ | ||
745 | static void | ||
746 | handle_icmp_back (void *cls, | ||
747 | const struct GNUNET_EXIT_IcmpToVPNMessage *i2v) | ||
748 | { | ||
749 | struct ChannelState *ts = cls; | ||
750 | size_t mlen; | ||
751 | |||
752 | GNUNET_STATISTICS_update (stats, | ||
753 | gettext_noop ("# ICMP packets received from cadet"), | ||
754 | 1, | ||
755 | GNUNET_NO); | ||
756 | mlen = ntohs (i2v->header.size) - sizeof (struct GNUNET_EXIT_IcmpToVPNMessage); | ||
757 | { | ||
758 | char sbuf[INET6_ADDRSTRLEN]; | ||
759 | char dbuf[INET6_ADDRSTRLEN]; | ||
760 | |||
761 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
762 | "Received ICMP packet from cadet, sending %u bytes from %s -> %s via TUN\n", | ||
763 | (unsigned int) mlen, | ||
764 | inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof (sbuf)), | ||
765 | inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof (dbuf))); | ||
766 | } | ||
767 | switch (ts->af) | ||
768 | { | ||
769 | case AF_INET: | ||
770 | { | ||
771 | size_t size = sizeof (struct GNUNET_TUN_IPv4Header) | ||
772 | + sizeof (struct GNUNET_TUN_IcmpHeader) | ||
773 | + sizeof (struct GNUNET_MessageHeader) + | ||
774 | sizeof (struct GNUNET_TUN_Layer2PacketHeader) + | ||
775 | mlen; | ||
776 | { | ||
777 | /* reserve some extra space in case we have an ICMP type here where | ||
778 | we will need to make up the payload ourselves */ | ||
779 | char buf[size + sizeof (struct GNUNET_TUN_IPv4Header) + 8] GNUNET_ALIGN; | ||
780 | struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; | ||
781 | struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1]; | ||
782 | struct GNUNET_TUN_IPv4Header *ipv4 = (struct GNUNET_TUN_IPv4Header *) &tun[1]; | ||
783 | struct GNUNET_TUN_IcmpHeader *icmp = (struct GNUNET_TUN_IcmpHeader *) &ipv4[1]; | ||
784 | msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
785 | tun->flags = htons (0); | ||
786 | tun->proto = htons (ETH_P_IPV4); | ||
787 | GNUNET_TUN_initialize_ipv4_header (ipv4, | ||
788 | IPPROTO_ICMP, | ||
789 | sizeof (struct GNUNET_TUN_IcmpHeader) + mlen, | ||
790 | &ts->destination_ip.v4, | ||
791 | &ts->source_ip.v4); | ||
792 | *icmp = i2v->icmp_header; | ||
793 | GNUNET_memcpy (&icmp[1], | ||
794 | &i2v[1], | ||
795 | mlen); | ||
796 | /* For some ICMP types, we need to adjust (make up) the payload here. | ||
797 | Also, depending on the AF used on the other side, we have to | ||
798 | do ICMP PT (translate ICMP types) */ | ||
799 | switch (ntohl (i2v->af)) | ||
800 | { | ||
801 | case AF_INET: | ||
802 | switch (icmp->type) | ||
803 | { | ||
804 | case GNUNET_TUN_ICMPTYPE_ECHO_REPLY: | ||
805 | case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST: | ||
806 | break; | ||
807 | case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE: | ||
808 | case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH: | ||
809 | case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED: | ||
810 | { | ||
811 | struct GNUNET_TUN_IPv4Header *ipp = (struct GNUNET_TUN_IPv4Header *) &icmp[1]; | ||
812 | struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1]; | ||
813 | |||
814 | if (mlen != 0) | ||
815 | { | ||
816 | /* sender did not strip ICMP payload? */ | ||
817 | GNUNET_break_op (0); | ||
818 | return; | ||
819 | } | ||
820 | size += sizeof (struct GNUNET_TUN_IPv4Header) + 8; | ||
821 | GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); | ||
822 | make_up_icmpv4_payload (ts, ipp, udp); | ||
823 | } | ||
824 | break; | ||
825 | default: | ||
826 | GNUNET_break_op (0); | ||
827 | GNUNET_STATISTICS_update (stats, | ||
828 | gettext_noop ("# ICMPv4 packets dropped (type not allowed)"), | ||
829 | 1, GNUNET_NO); | ||
830 | return; | ||
831 | } | ||
832 | /* end AF_INET */ | ||
833 | break; | ||
834 | case AF_INET6: | ||
835 | /* ICMP PT 6-to-4 and possibly making up payloads */ | ||
836 | switch (icmp->type) | ||
837 | { | ||
838 | case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE: | ||
839 | icmp->type = GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE; | ||
840 | { | ||
841 | struct GNUNET_TUN_IPv4Header *ipp = (struct GNUNET_TUN_IPv4Header *) &icmp[1]; | ||
842 | struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1]; | ||
843 | |||
844 | if (mlen != 0) | ||
845 | { | ||
846 | /* sender did not strip ICMP payload? */ | ||
847 | GNUNET_break_op (0); | ||
848 | return; | ||
849 | } | ||
850 | size += sizeof (struct GNUNET_TUN_IPv4Header) + 8; | ||
851 | GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); | ||
852 | make_up_icmpv4_payload (ts, ipp, udp); | ||
853 | } | ||
854 | break; | ||
855 | case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED: | ||
856 | icmp->type = GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED; | ||
857 | { | ||
858 | struct GNUNET_TUN_IPv4Header *ipp = (struct GNUNET_TUN_IPv4Header *) &icmp[1]; | ||
859 | struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1]; | ||
860 | |||
861 | if (mlen != 0) | ||
862 | { | ||
863 | /* sender did not strip ICMP payload? */ | ||
864 | GNUNET_break_op (0); | ||
865 | return; | ||
866 | } | ||
867 | size += sizeof (struct GNUNET_TUN_IPv4Header) + 8; | ||
868 | GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); | ||
869 | make_up_icmpv4_payload (ts, ipp, udp); | ||
870 | } | ||
871 | break; | ||
872 | case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG: | ||
873 | case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM: | ||
874 | GNUNET_STATISTICS_update (stats, | ||
875 | gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"), | ||
876 | 1, GNUNET_NO); | ||
877 | return; | ||
878 | case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST: | ||
879 | icmp->type = GNUNET_TUN_ICMPTYPE_ECHO_REQUEST; | ||
880 | break; | ||
881 | case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY: | ||
882 | icmp->type = GNUNET_TUN_ICMPTYPE_ECHO_REPLY; | ||
883 | break; | ||
884 | default: | ||
885 | GNUNET_break_op (0); | ||
886 | GNUNET_STATISTICS_update (stats, | ||
887 | gettext_noop ("# ICMPv6 packets dropped (type not allowed)"), | ||
888 | 1, GNUNET_NO); | ||
889 | return; | ||
890 | } | ||
891 | /* end AF_INET6 */ | ||
892 | break; | ||
893 | default: | ||
894 | GNUNET_break_op (0); | ||
895 | return; | ||
896 | } | ||
897 | msg->size = htons (size); | ||
898 | GNUNET_TUN_calculate_icmp_checksum (icmp, | ||
899 | &i2v[1], | ||
900 | mlen); | ||
901 | (void) GNUNET_HELPER_send (helper_handle, | ||
902 | msg, | ||
903 | GNUNET_YES, | ||
904 | NULL, NULL); | ||
905 | } | ||
906 | } | ||
907 | break; | ||
908 | case AF_INET6: | ||
909 | { | ||
910 | size_t size = sizeof (struct GNUNET_TUN_IPv6Header) | ||
911 | + sizeof (struct GNUNET_TUN_IcmpHeader) | ||
912 | + sizeof (struct GNUNET_MessageHeader) + | ||
913 | sizeof (struct GNUNET_TUN_Layer2PacketHeader) + | ||
914 | mlen; | ||
915 | { | ||
916 | char buf[size + sizeof (struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN; | ||
917 | struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; | ||
918 | struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1]; | ||
919 | struct GNUNET_TUN_IPv6Header *ipv6 = (struct GNUNET_TUN_IPv6Header *) &tun[1]; | ||
920 | struct GNUNET_TUN_IcmpHeader *icmp = (struct GNUNET_TUN_IcmpHeader *) &ipv6[1]; | ||
921 | msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
922 | tun->flags = htons (0); | ||
923 | tun->proto = htons (ETH_P_IPV6); | ||
924 | GNUNET_TUN_initialize_ipv6_header (ipv6, | ||
925 | IPPROTO_ICMPV6, | ||
926 | sizeof (struct GNUNET_TUN_IcmpHeader) + mlen, | ||
927 | &ts->destination_ip.v6, | ||
928 | &ts->source_ip.v6); | ||
929 | *icmp = i2v->icmp_header; | ||
930 | GNUNET_memcpy (&icmp[1], | ||
931 | &i2v[1], | ||
932 | mlen); | ||
933 | |||
934 | /* For some ICMP types, we need to adjust (make up) the payload here. | ||
935 | Also, depending on the AF used on the other side, we have to | ||
936 | do ICMP PT (translate ICMP types) */ | ||
937 | switch (ntohl (i2v->af)) | ||
938 | { | ||
939 | case AF_INET: | ||
940 | /* ICMP PT 4-to-6 and possibly making up payloads */ | ||
941 | switch (icmp->type) | ||
942 | { | ||
943 | case GNUNET_TUN_ICMPTYPE_ECHO_REPLY: | ||
944 | icmp->type = GNUNET_TUN_ICMPTYPE6_ECHO_REPLY; | ||
945 | break; | ||
946 | case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST: | ||
947 | icmp->type = GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST; | ||
948 | break; | ||
949 | case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE: | ||
950 | icmp->type = GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE; | ||
951 | { | ||
952 | struct GNUNET_TUN_IPv6Header *ipp = (struct GNUNET_TUN_IPv6Header *) &icmp[1]; | ||
953 | struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1]; | ||
954 | |||
955 | if (mlen != 0) | ||
956 | { | ||
957 | /* sender did not strip ICMP payload? */ | ||
958 | GNUNET_break_op (0); | ||
959 | return; | ||
960 | } | ||
961 | size += sizeof (struct GNUNET_TUN_IPv6Header) + 8; | ||
962 | GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); | ||
963 | make_up_icmpv6_payload (ts, ipp, udp); | ||
964 | } | ||
965 | break; | ||
966 | case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED: | ||
967 | icmp->type = GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED; | ||
968 | { | ||
969 | struct GNUNET_TUN_IPv6Header *ipp = (struct GNUNET_TUN_IPv6Header *) &icmp[1]; | ||
970 | struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1]; | ||
971 | |||
972 | if (mlen != 0) | ||
973 | { | ||
974 | /* sender did not strip ICMP payload? */ | ||
975 | GNUNET_break_op (0); | ||
976 | return; | ||
977 | } | ||
978 | size += sizeof (struct GNUNET_TUN_IPv6Header) + 8; | ||
979 | GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); | ||
980 | make_up_icmpv6_payload (ts, ipp, udp); | ||
981 | } | ||
982 | break; | ||
983 | case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH: | ||
984 | GNUNET_STATISTICS_update (stats, | ||
985 | gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"), | ||
986 | 1, GNUNET_NO); | ||
987 | return; | ||
988 | default: | ||
989 | GNUNET_break_op (0); | ||
990 | GNUNET_STATISTICS_update (stats, | ||
991 | gettext_noop ("# ICMPv4 packets dropped (type not allowed)"), | ||
992 | 1, GNUNET_NO); | ||
993 | return; | ||
994 | } | ||
995 | /* end AF_INET */ | ||
996 | break; | ||
997 | case AF_INET6: | ||
998 | switch (icmp->type) | ||
999 | { | ||
1000 | case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE: | ||
1001 | case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED: | ||
1002 | case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG: | ||
1003 | case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM: | ||
1004 | { | ||
1005 | struct GNUNET_TUN_IPv6Header *ipp = (struct GNUNET_TUN_IPv6Header *) &icmp[1]; | ||
1006 | struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1]; | ||
1007 | |||
1008 | if (mlen != 0) | ||
1009 | { | ||
1010 | /* sender did not strip ICMP payload? */ | ||
1011 | GNUNET_break_op (0); | ||
1012 | return; | ||
1013 | } | ||
1014 | size += sizeof (struct GNUNET_TUN_IPv6Header) + 8; | ||
1015 | GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); | ||
1016 | make_up_icmpv6_payload (ts, ipp, udp); | ||
1017 | } | ||
1018 | break; | ||
1019 | case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST: | ||
1020 | break; | ||
1021 | default: | ||
1022 | GNUNET_break_op (0); | ||
1023 | GNUNET_STATISTICS_update (stats, | ||
1024 | gettext_noop ("# ICMPv6 packets dropped (type not allowed)"), | ||
1025 | 1, GNUNET_NO); | ||
1026 | return; | ||
1027 | } | ||
1028 | /* end AF_INET6 */ | ||
1029 | break; | ||
1030 | default: | ||
1031 | GNUNET_break_op (0); | ||
1032 | return; | ||
1033 | } | ||
1034 | msg->size = htons (size); | ||
1035 | GNUNET_TUN_calculate_icmp_checksum (icmp, | ||
1036 | &i2v[1], mlen); | ||
1037 | (void) GNUNET_HELPER_send (helper_handle, | ||
1038 | msg, | ||
1039 | GNUNET_YES, | ||
1040 | NULL, NULL); | ||
1041 | } | ||
1042 | } | ||
1043 | break; | ||
1044 | default: | ||
1045 | GNUNET_assert (0); | ||
1046 | } | ||
1047 | GNUNET_CONTAINER_heap_update_cost (ts->heap_node, | ||
1048 | GNUNET_TIME_absolute_get ().abs_value_us); | ||
1049 | GNUNET_CADET_receive_done (ts->channel); | ||
1050 | } | ||
1051 | |||
1052 | |||
1053 | /** | ||
1054 | * We got a UDP packet back from the CADET channel. Check that it is OK. | ||
1055 | * | ||
1056 | * @param cls our `struct ChannelState *` | ||
1057 | * @param reply the actual message | ||
1058 | * @return #GNUNET_OK to keep the connection open, | ||
1059 | * #GNUNET_SYSERR to close it (signal serious error) | ||
1060 | */ | ||
1061 | static int | ||
1062 | check_udp_back (void *cls, | ||
1063 | const struct GNUNET_EXIT_UdpReplyMessage *reply) | ||
1064 | { | ||
1065 | struct ChannelState *ts = cls; | ||
1066 | |||
1067 | if (NULL == ts->heap_node) | ||
1068 | { | ||
1069 | GNUNET_break_op (0); | ||
1070 | return GNUNET_SYSERR; | ||
1071 | } | ||
1072 | if (AF_UNSPEC == ts->af) | ||
1073 | { | ||
1074 | GNUNET_break_op (0); | ||
1075 | return GNUNET_SYSERR; | ||
1076 | } | ||
1077 | return GNUNET_OK; | ||
1078 | } | ||
1079 | |||
1080 | |||
1081 | /** | ||
1082 | * We got a UDP packet back from the CADET channel. Pass it on to the | ||
1083 | * local virtual interface via the helper. | ||
1084 | * | ||
1085 | * @param cls our `struct ChannelState *` | ||
1086 | * @param reply the actual message | ||
1087 | */ | ||
1088 | static void | ||
1089 | handle_udp_back (void *cls, | ||
1090 | const struct GNUNET_EXIT_UdpReplyMessage *reply) | ||
1091 | { | ||
1092 | struct ChannelState *ts = cls; | ||
1093 | size_t mlen; | ||
1094 | |||
1095 | GNUNET_STATISTICS_update (stats, | ||
1096 | gettext_noop ("# UDP packets received from cadet"), | ||
1097 | 1, | ||
1098 | GNUNET_NO); | ||
1099 | mlen = ntohs (reply->header.size) - sizeof (struct GNUNET_EXIT_UdpReplyMessage); | ||
1100 | { | ||
1101 | char sbuf[INET6_ADDRSTRLEN]; | ||
1102 | char dbuf[INET6_ADDRSTRLEN]; | ||
1103 | |||
1104 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1105 | "Received UDP reply from cadet, sending %u bytes from [%s]:%u -> [%s]:%u via TUN\n", | ||
1106 | (unsigned int) mlen, | ||
1107 | inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof (sbuf)), | ||
1108 | ts->destination_port, | ||
1109 | inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof (dbuf)), | ||
1110 | ts->source_port); | ||
1111 | } | ||
1112 | switch (ts->af) | ||
1113 | { | ||
1114 | case AF_INET: | ||
1115 | { | ||
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) + | ||
1120 | mlen; | ||
1121 | { | ||
1122 | char buf[size] GNUNET_ALIGN; | ||
1123 | struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; | ||
1124 | struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1]; | ||
1125 | struct GNUNET_TUN_IPv4Header *ipv4 = (struct GNUNET_TUN_IPv4Header *) &tun[1]; | ||
1126 | struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipv4[1]; | ||
1127 | msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
1128 | msg->size = htons (size); | ||
1129 | tun->flags = htons (0); | ||
1130 | tun->proto = htons (ETH_P_IPV4); | ||
1131 | GNUNET_TUN_initialize_ipv4_header (ipv4, | ||
1132 | IPPROTO_UDP, | ||
1133 | sizeof (struct GNUNET_TUN_UdpHeader) + mlen, | ||
1134 | &ts->destination_ip.v4, | ||
1135 | &ts->source_ip.v4); | ||
1136 | if (0 == ntohs (reply->source_port)) | ||
1137 | udp->source_port = htons (ts->destination_port); | ||
1138 | else | ||
1139 | udp->source_port = reply->source_port; | ||
1140 | if (0 == ntohs (reply->destination_port)) | ||
1141 | udp->destination_port = htons (ts->source_port); | ||
1142 | else | ||
1143 | udp->destination_port = reply->destination_port; | ||
1144 | udp->len = htons (mlen + sizeof (struct GNUNET_TUN_UdpHeader)); | ||
1145 | GNUNET_TUN_calculate_udp4_checksum (ipv4, | ||
1146 | udp, | ||
1147 | &reply[1], | ||
1148 | mlen); | ||
1149 | GNUNET_memcpy (&udp[1], | ||
1150 | &reply[1], | ||
1151 | mlen); | ||
1152 | (void) GNUNET_HELPER_send (helper_handle, | ||
1153 | msg, | ||
1154 | GNUNET_YES, | ||
1155 | NULL, NULL); | ||
1156 | } | ||
1157 | } | ||
1158 | break; | ||
1159 | case AF_INET6: | ||
1160 | { | ||
1161 | size_t size = sizeof (struct GNUNET_TUN_IPv6Header) | ||
1162 | + sizeof (struct GNUNET_TUN_UdpHeader) | ||
1163 | + sizeof (struct GNUNET_MessageHeader) + | ||
1164 | sizeof (struct GNUNET_TUN_Layer2PacketHeader) + | ||
1165 | mlen; | ||
1166 | { | ||
1167 | char buf[size] GNUNET_ALIGN; | ||
1168 | struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; | ||
1169 | struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1]; | ||
1170 | struct GNUNET_TUN_IPv6Header *ipv6 = (struct GNUNET_TUN_IPv6Header *) &tun[1]; | ||
1171 | struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipv6[1]; | ||
1172 | msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
1173 | msg->size = htons (size); | ||
1174 | tun->flags = htons (0); | ||
1175 | tun->proto = htons (ETH_P_IPV6); | ||
1176 | GNUNET_TUN_initialize_ipv6_header (ipv6, | ||
1177 | IPPROTO_UDP, | ||
1178 | sizeof (struct GNUNET_TUN_UdpHeader) + mlen, | ||
1179 | &ts->destination_ip.v6, | ||
1180 | &ts->source_ip.v6); | ||
1181 | if (0 == ntohs (reply->source_port)) | ||
1182 | udp->source_port = htons (ts->destination_port); | ||
1183 | else | ||
1184 | udp->source_port = reply->source_port; | ||
1185 | if (0 == ntohs (reply->destination_port)) | ||
1186 | udp->destination_port = htons (ts->source_port); | ||
1187 | else | ||
1188 | udp->destination_port = reply->destination_port; | ||
1189 | udp->len = htons (mlen + sizeof (struct GNUNET_TUN_UdpHeader)); | ||
1190 | GNUNET_TUN_calculate_udp6_checksum (ipv6, | ||
1191 | udp, | ||
1192 | &reply[1], mlen); | ||
1193 | GNUNET_memcpy (&udp[1], | ||
1194 | &reply[1], | ||
1195 | mlen); | ||
1196 | (void) GNUNET_HELPER_send (helper_handle, | ||
1197 | msg, | ||
1198 | GNUNET_YES, | ||
1199 | NULL, NULL); | ||
1200 | } | ||
1201 | } | ||
1202 | break; | ||
1203 | default: | ||
1204 | GNUNET_assert (0); | ||
1205 | } | ||
1206 | GNUNET_CONTAINER_heap_update_cost (ts->heap_node, | ||
1207 | GNUNET_TIME_absolute_get ().abs_value_us); | ||
1208 | GNUNET_CADET_receive_done (ts->channel); | ||
1209 | } | ||
1210 | |||
1211 | |||
1212 | /** | ||
1213 | * We got a TCP packet back from the CADET channel. Check it is OK. | ||
1214 | * | ||
1215 | * @param cls our `struct ChannelState *` | ||
1216 | * @param data the actual message | ||
1217 | * @return #GNUNET_OK to keep the connection open, | ||
1218 | * #GNUNET_SYSERR to close it (signal serious error) | ||
1219 | */ | ||
1220 | static int | ||
1221 | check_tcp_back (void *cls, | ||
1222 | const struct GNUNET_EXIT_TcpDataMessage *data) | ||
1223 | { | ||
1224 | struct ChannelState *ts = cls; | ||
1225 | |||
1226 | if (NULL == ts->heap_node) | ||
1227 | { | ||
1228 | GNUNET_break_op (0); | ||
1229 | return GNUNET_SYSERR; | ||
1230 | } | ||
1231 | if (data->tcp_header.off * 4 < sizeof (struct GNUNET_TUN_TcpHeader)) | ||
1232 | { | ||
1233 | GNUNET_break_op (0); | ||
1234 | return GNUNET_SYSERR; | ||
1235 | } | ||
1236 | return GNUNET_OK; | ||
1237 | } | ||
1238 | |||
1239 | |||
1240 | /** | ||
1241 | * We got a TCP packet back from the CADET channel. Pass it on to the | ||
1242 | * local virtual interface via the helper. | ||
1243 | * | ||
1244 | * @param cls our `struct ChannelState *` | ||
1245 | * @param data the actual message | ||
1246 | */ | ||
1247 | static void | ||
1248 | handle_tcp_back (void *cls, | ||
1249 | const struct GNUNET_EXIT_TcpDataMessage *data) | ||
1250 | { | ||
1251 | struct ChannelState *ts = cls; | ||
1252 | size_t mlen; | ||
1253 | |||
1254 | GNUNET_STATISTICS_update (stats, | ||
1255 | gettext_noop ("# TCP packets received from cadet"), | ||
1256 | 1, | ||
1257 | GNUNET_NO); | ||
1258 | mlen = ntohs (data->header.size) - sizeof (struct GNUNET_EXIT_TcpDataMessage); | ||
1259 | { | ||
1260 | char sbuf[INET6_ADDRSTRLEN]; | ||
1261 | char dbuf[INET6_ADDRSTRLEN]; | ||
1262 | |||
1263 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1264 | "Received TCP reply from cadet, sending %u bytes from [%s]:%u -> [%s]:%u via TUN\n", | ||
1265 | (unsigned int) mlen, | ||
1266 | inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof (sbuf)), | ||
1267 | ts->destination_port, | ||
1268 | inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof (dbuf)), | ||
1269 | ts->source_port); | ||
1270 | } | ||
1271 | switch (ts->af) | ||
1272 | { | ||
1273 | case AF_INET: | ||
1274 | { | ||
1275 | size_t size = sizeof (struct GNUNET_TUN_IPv4Header) | ||
1276 | + sizeof (struct GNUNET_TUN_TcpHeader) | ||
1277 | + sizeof (struct GNUNET_MessageHeader) + | ||
1278 | sizeof (struct GNUNET_TUN_Layer2PacketHeader) + | ||
1279 | mlen; | ||
1280 | { | ||
1281 | char buf[size] GNUNET_ALIGN; | ||
1282 | struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; | ||
1283 | struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1]; | ||
1284 | struct GNUNET_TUN_IPv4Header *ipv4 = (struct GNUNET_TUN_IPv4Header *) &tun[1]; | ||
1285 | struct GNUNET_TUN_TcpHeader *tcp = (struct GNUNET_TUN_TcpHeader *) &ipv4[1]; | ||
1286 | msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
1287 | msg->size = htons (size); | ||
1288 | tun->flags = htons (0); | ||
1289 | tun->proto = htons (ETH_P_IPV4); | ||
1290 | GNUNET_TUN_initialize_ipv4_header (ipv4, | ||
1291 | IPPROTO_TCP, | ||
1292 | sizeof (struct GNUNET_TUN_TcpHeader) + mlen, | ||
1293 | &ts->destination_ip.v4, | ||
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, | ||
1299 | tcp, | ||
1300 | &data[1], | ||
1301 | mlen); | ||
1302 | GNUNET_memcpy (&tcp[1], | ||
1303 | &data[1], | ||
1304 | mlen); | ||
1305 | (void) GNUNET_HELPER_send (helper_handle, | ||
1306 | msg, | ||
1307 | GNUNET_YES, | ||
1308 | NULL, NULL); | ||
1309 | } | ||
1310 | } | ||
1311 | break; | ||
1312 | case AF_INET6: | ||
1313 | { | ||
1314 | size_t size = sizeof (struct GNUNET_TUN_IPv6Header) | ||
1315 | + sizeof (struct GNUNET_TUN_TcpHeader) | ||
1316 | + sizeof (struct GNUNET_MessageHeader) + | ||
1317 | sizeof (struct GNUNET_TUN_Layer2PacketHeader) + | ||
1318 | mlen; | ||
1319 | { | ||
1320 | char buf[size] GNUNET_ALIGN; | ||
1321 | struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; | ||
1322 | struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1]; | ||
1323 | struct GNUNET_TUN_IPv6Header *ipv6 = (struct GNUNET_TUN_IPv6Header *) &tun[1]; | ||
1324 | struct GNUNET_TUN_TcpHeader *tcp = (struct GNUNET_TUN_TcpHeader *) &ipv6[1]; | ||
1325 | msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
1326 | msg->size = htons (size); | ||
1327 | tun->flags = htons (0); | ||
1328 | tun->proto = htons (ETH_P_IPV6); | ||
1329 | GNUNET_TUN_initialize_ipv6_header (ipv6, | ||
1330 | IPPROTO_TCP, | ||
1331 | sizeof (struct GNUNET_TUN_TcpHeader) + mlen, | ||
1332 | &ts->destination_ip.v6, | ||
1333 | &ts->source_ip.v6); | ||
1334 | *tcp = data->tcp_header; | ||
1335 | tcp->source_port = htons (ts->destination_port); | ||
1336 | tcp->destination_port = htons (ts->source_port); | ||
1337 | GNUNET_TUN_calculate_tcp6_checksum (ipv6, | ||
1338 | tcp, | ||
1339 | &data[1], | ||
1340 | mlen); | ||
1341 | GNUNET_memcpy (&tcp[1], | ||
1342 | &data[1], | ||
1343 | mlen); | ||
1344 | (void) GNUNET_HELPER_send (helper_handle, | ||
1345 | msg, | ||
1346 | GNUNET_YES, | ||
1347 | NULL, NULL); | ||
1348 | } | ||
1349 | } | ||
1350 | break; | ||
1351 | } | ||
1352 | GNUNET_CONTAINER_heap_update_cost (ts->heap_node, | ||
1353 | GNUNET_TIME_absolute_get ().abs_value_us); | ||
1354 | GNUNET_CADET_receive_done (ts->channel); | ||
1355 | } | ||
1356 | |||
1357 | |||
1358 | /** | ||
1359 | * Create a channel for @a ts to @a target at @a port | ||
1360 | * | ||
1361 | * @param ts channel state to create the channel for | ||
1362 | * @param target peer to connect to | ||
1363 | * @param port destination port | ||
1364 | * @return the channel handle | ||
1365 | */ | ||
1366 | static struct GNUNET_CADET_Channel * | ||
1367 | create_channel (struct ChannelState *ts, | ||
1368 | const struct GNUNET_PeerIdentity *target, | ||
1369 | const struct GNUNET_HashCode *port) | ||
1370 | { | ||
1371 | struct GNUNET_MQ_MessageHandler cadet_handlers[] = { | ||
1372 | GNUNET_MQ_hd_var_size (udp_back, | ||
1373 | GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY, | ||
1374 | struct GNUNET_EXIT_UdpReplyMessage, | ||
1375 | ts), | ||
1376 | GNUNET_MQ_hd_var_size (tcp_back, | ||
1377 | GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_VPN, | ||
1378 | struct GNUNET_EXIT_TcpDataMessage, | ||
1379 | ts), | ||
1380 | GNUNET_MQ_hd_var_size (icmp_back, | ||
1381 | GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_VPN, | ||
1382 | struct GNUNET_EXIT_IcmpToVPNMessage, | ||
1383 | ts), | ||
1384 | GNUNET_MQ_handler_end() | ||
1385 | }; | ||
1386 | |||
1387 | return GNUNET_CADET_channel_creatE (cadet_handle, | ||
1388 | ts, | ||
1389 | target, | ||
1390 | port, | ||
1391 | GNUNET_CADET_OPTION_DEFAULT, | ||
1392 | NULL, | ||
1393 | &channel_cleaner, | ||
1394 | cadet_handlers); | ||
1395 | } | ||
1396 | |||
1397 | |||
1398 | /** | ||
713 | * Regex has found a potential exit peer for us; consider using it. | 1399 | * Regex has found a potential exit peer for us; consider using it. |
714 | * | 1400 | * |
715 | * @param cls the `struct ChannelState` | 1401 | * @param cls the `struct ChannelState` |
@@ -758,11 +1444,9 @@ handle_regex_result (void *cls, | |||
758 | "Creating tunnel to %s for destination %s!\n", | 1444 | "Creating tunnel to %s for destination %s!\n", |
759 | GNUNET_i2s (id), | 1445 | GNUNET_i2s (id), |
760 | print_channel_destination (&ts->destination)); | 1446 | print_channel_destination (&ts->destination)); |
761 | ts->channel = GNUNET_CADET_channel_create (cadet_handle, | 1447 | ts->channel = create_channel (ts, |
762 | ts, | 1448 | id, |
763 | id, | 1449 | &port); |
764 | &port, | ||
765 | GNUNET_CADET_OPTION_DEFAULT); | ||
766 | } | 1450 | } |
767 | 1451 | ||
768 | 1452 | ||
@@ -795,12 +1479,10 @@ create_channel_to_destination (struct DestinationChannel *dt, | |||
795 | GNUNET_TUN_compute_service_cadet_port (&ts->destination.details.service_destination.service_descriptor, | 1479 | GNUNET_TUN_compute_service_cadet_port (&ts->destination.details.service_destination.service_descriptor, |
796 | ts->destination_port, | 1480 | ts->destination_port, |
797 | &cadet_port); | 1481 | &cadet_port); |
798 | ts->channel | 1482 | ts->channel = create_channel (ts, |
799 | = GNUNET_CADET_channel_create (cadet_handle, | 1483 | &dt->destination->details.service_destination.target, |
800 | ts, | 1484 | &cadet_port); |
801 | &dt->destination->details.service_destination.target, | 1485 | |
802 | &cadet_port, | ||
803 | GNUNET_CADET_OPTION_DEFAULT); | ||
804 | if (NULL == ts->channel) | 1486 | if (NULL == ts->channel) |
805 | { | 1487 | { |
806 | GNUNET_break (0); | 1488 | GNUNET_break (0); |
@@ -906,9 +1588,9 @@ route_packet (struct DestinationEntry *destination, | |||
906 | { | 1588 | { |
907 | struct GNUNET_HashCode key; | 1589 | struct GNUNET_HashCode key; |
908 | struct ChannelState *ts; | 1590 | struct ChannelState *ts; |
909 | struct ChannelMessageQueueEntry *tnq; | ||
910 | size_t alen; | 1591 | size_t alen; |
911 | size_t mlen; | 1592 | size_t mlen; |
1593 | struct GNUNET_MQ_Envelope *env; | ||
912 | const struct GNUNET_TUN_UdpHeader *udp; | 1594 | const struct GNUNET_TUN_UdpHeader *udp; |
913 | const struct GNUNET_TUN_TcpHeader *tcp; | 1595 | const struct GNUNET_TUN_TcpHeader *tcp; |
914 | const struct GNUNET_TUN_IcmpHeader *icmp; | 1596 | const struct GNUNET_TUN_IcmpHeader *icmp; |
@@ -1162,12 +1844,9 @@ route_packet (struct DestinationEntry *destination, | |||
1162 | GNUNET_break (0); | 1844 | GNUNET_break (0); |
1163 | return; | 1845 | return; |
1164 | } | 1846 | } |
1165 | tnq = GNUNET_malloc (sizeof (struct ChannelMessageQueueEntry) + mlen); | 1847 | env = GNUNET_MQ_msg_extra (usm, |
1166 | tnq->len = mlen; | 1848 | payload_length - sizeof (struct GNUNET_TUN_UdpHeader), |
1167 | tnq->msg = &tnq[1]; | 1849 | GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE); |
1168 | usm = (struct GNUNET_EXIT_UdpServiceMessage *) &tnq[1]; | ||
1169 | usm->header.size = htons ((uint16_t) mlen); | ||
1170 | usm->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE); | ||
1171 | /* if the source port is below 32000, we assume it has a special | 1850 | /* if the source port is below 32000, we assume it has a special |
1172 | meaning; if not, we pick a random port (this is a heuristic) */ | 1851 | meaning; if not, we pick a random port (this is a heuristic) */ |
1173 | usm->source_port = (ntohs (udp->source_port) < 32000) ? udp->source_port : 0; | 1852 | usm->source_port = (ntohs (udp->source_port) < 32000) ? udp->source_port : 0; |
@@ -1190,12 +1869,9 @@ route_packet (struct DestinationEntry *destination, | |||
1190 | GNUNET_break (0); | 1869 | GNUNET_break (0); |
1191 | return; | 1870 | return; |
1192 | } | 1871 | } |
1193 | tnq = GNUNET_malloc (sizeof (struct ChannelMessageQueueEntry) + mlen); | 1872 | env = GNUNET_MQ_msg_extra (uim, |
1194 | tnq->len = mlen; | 1873 | payload_length + alen - sizeof (struct GNUNET_TUN_UdpHeader), |
1195 | tnq->msg = &tnq[1]; | 1874 | GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET); |
1196 | uim = (struct GNUNET_EXIT_UdpInternetMessage *) &tnq[1]; | ||
1197 | uim->header.size = htons ((uint16_t) mlen); | ||
1198 | uim->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET); | ||
1199 | uim->af = htonl (destination->details.exit_destination.af); | 1875 | uim->af = htonl (destination->details.exit_destination.af); |
1200 | uim->source_port = (ntohs (udp->source_port) < 32000) ? udp->source_port : 0; | 1876 | uim->source_port = (ntohs (udp->source_port) < 32000) ? udp->source_port : 0; |
1201 | uim->destination_port = udp->destination_port; | 1877 | uim->destination_port = udp->destination_port; |
@@ -1215,8 +1891,8 @@ route_packet (struct DestinationEntry *destination, | |||
1215 | GNUNET_assert (0); | 1891 | GNUNET_assert (0); |
1216 | } | 1892 | } |
1217 | GNUNET_memcpy (payload, | 1893 | GNUNET_memcpy (payload, |
1218 | &udp[1], | 1894 | &udp[1], |
1219 | payload_length - sizeof (struct GNUNET_TUN_UdpHeader)); | 1895 | payload_length - sizeof (struct GNUNET_TUN_UdpHeader)); |
1220 | } | 1896 | } |
1221 | break; | 1897 | break; |
1222 | case IPPROTO_TCP: | 1898 | case IPPROTO_TCP: |
@@ -1233,12 +1909,9 @@ route_packet (struct DestinationEntry *destination, | |||
1233 | GNUNET_break (0); | 1909 | GNUNET_break (0); |
1234 | return; | 1910 | return; |
1235 | } | 1911 | } |
1236 | tnq = GNUNET_malloc (sizeof (struct ChannelMessageQueueEntry) + mlen); | 1912 | env = GNUNET_MQ_msg_extra (tsm, |
1237 | tnq->len = mlen; | 1913 | payload_length - sizeof (struct GNUNET_TUN_TcpHeader), |
1238 | tnq->msg = &tnq[1]; | 1914 | GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START); |
1239 | tsm = (struct GNUNET_EXIT_TcpServiceStartMessage *) &tnq[1]; | ||
1240 | tsm->header.size = htons ((uint16_t) mlen); | ||
1241 | tsm->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START); | ||
1242 | tsm->reserved = htonl (0); | 1915 | tsm->reserved = htonl (0); |
1243 | tsm->tcp_header = *tcp; | 1916 | tsm->tcp_header = *tcp; |
1244 | GNUNET_memcpy (&tsm[1], | 1917 | GNUNET_memcpy (&tsm[1], |
@@ -1259,12 +1932,9 @@ route_packet (struct DestinationEntry *destination, | |||
1259 | GNUNET_break (0); | 1932 | GNUNET_break (0); |
1260 | return; | 1933 | return; |
1261 | } | 1934 | } |
1262 | tnq = GNUNET_malloc (sizeof (struct ChannelMessageQueueEntry) + mlen); | 1935 | env = GNUNET_MQ_msg_extra (tim, |
1263 | tnq->len = mlen; | 1936 | payload_length + alen - sizeof (struct GNUNET_TUN_TcpHeader), |
1264 | tnq->msg = &tnq[1]; | 1937 | GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START); |
1265 | tim = (struct GNUNET_EXIT_TcpInternetStartMessage *) &tnq[1]; | ||
1266 | tim->header.size = htons ((uint16_t) mlen); | ||
1267 | tim->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START); | ||
1268 | tim->af = htonl (destination->details.exit_destination.af); | 1938 | tim->af = htonl (destination->details.exit_destination.af); |
1269 | tim->tcp_header = *tcp; | 1939 | tim->tcp_header = *tcp; |
1270 | switch (destination->details.exit_destination.af) | 1940 | switch (destination->details.exit_destination.af) |
@@ -1283,8 +1953,8 @@ route_packet (struct DestinationEntry *destination, | |||
1283 | GNUNET_assert (0); | 1953 | GNUNET_assert (0); |
1284 | } | 1954 | } |
1285 | GNUNET_memcpy (payload, | 1955 | GNUNET_memcpy (payload, |
1286 | &tcp[1], | 1956 | &tcp[1], |
1287 | payload_length - sizeof (struct GNUNET_TUN_TcpHeader)); | 1957 | payload_length - sizeof (struct GNUNET_TUN_TcpHeader)); |
1288 | } | 1958 | } |
1289 | } | 1959 | } |
1290 | else | 1960 | else |
@@ -1298,17 +1968,14 @@ route_packet (struct DestinationEntry *destination, | |||
1298 | GNUNET_break (0); | 1968 | GNUNET_break (0); |
1299 | return; | 1969 | return; |
1300 | } | 1970 | } |
1301 | tnq = GNUNET_malloc (sizeof (struct ChannelMessageQueueEntry) + mlen); | 1971 | env = GNUNET_MQ_msg_extra (tdm, |
1302 | tnq->len = mlen; | 1972 | payload_length - sizeof (struct GNUNET_TUN_TcpHeader), |
1303 | tnq->msg = &tnq[1]; | 1973 | GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT); |
1304 | tdm = (struct GNUNET_EXIT_TcpDataMessage *) &tnq[1]; | ||
1305 | tdm->header.size = htons ((uint16_t) mlen); | ||
1306 | tdm->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT); | ||
1307 | tdm->reserved = htonl (0); | 1974 | tdm->reserved = htonl (0); |
1308 | tdm->tcp_header = *tcp; | 1975 | tdm->tcp_header = *tcp; |
1309 | GNUNET_memcpy (&tdm[1], | 1976 | GNUNET_memcpy (&tdm[1], |
1310 | &tcp[1], | 1977 | &tcp[1], |
1311 | payload_length - sizeof (struct GNUNET_TUN_TcpHeader)); | 1978 | payload_length - sizeof (struct GNUNET_TUN_TcpHeader)); |
1312 | } | 1979 | } |
1313 | break; | 1980 | break; |
1314 | case IPPROTO_ICMP: | 1981 | case IPPROTO_ICMP: |
@@ -1317,19 +1984,6 @@ route_packet (struct DestinationEntry *destination, | |||
1317 | { | 1984 | { |
1318 | struct GNUNET_EXIT_IcmpServiceMessage *ism; | 1985 | struct GNUNET_EXIT_IcmpServiceMessage *ism; |
1319 | 1986 | ||
1320 | mlen = sizeof (struct GNUNET_EXIT_IcmpServiceMessage) + | ||
1321 | payload_length - sizeof (struct GNUNET_TUN_IcmpHeader); | ||
1322 | if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
1323 | { | ||
1324 | GNUNET_break (0); | ||
1325 | return; | ||
1326 | } | ||
1327 | tnq = GNUNET_malloc (sizeof (struct ChannelMessageQueueEntry) + mlen); | ||
1328 | tnq->msg = &tnq[1]; | ||
1329 | ism = (struct GNUNET_EXIT_IcmpServiceMessage *) &tnq[1]; | ||
1330 | ism->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_SERVICE); | ||
1331 | ism->af = htonl (af); /* need to tell destination ICMP protocol family! */ | ||
1332 | ism->icmp_header = *icmp; | ||
1333 | /* ICMP protocol translation will be done by the receiver (as we don't know | 1987 | /* ICMP protocol translation will be done by the receiver (as we don't know |
1334 | the target AF); however, we still need to possibly discard the payload | 1988 | the target AF); however, we still need to possibly discard the payload |
1335 | depending on the ICMP type */ | 1989 | depending on the ICMP type */ |
@@ -1384,12 +2038,20 @@ route_packet (struct DestinationEntry *destination, | |||
1384 | /* update length calculations, as payload_length may have changed */ | 2038 | /* update length calculations, as payload_length may have changed */ |
1385 | mlen = sizeof (struct GNUNET_EXIT_IcmpServiceMessage) + | 2039 | mlen = sizeof (struct GNUNET_EXIT_IcmpServiceMessage) + |
1386 | alen + payload_length - sizeof (struct GNUNET_TUN_IcmpHeader); | 2040 | alen + payload_length - sizeof (struct GNUNET_TUN_IcmpHeader); |
1387 | tnq->len = mlen; | 2041 | if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) |
1388 | ism->header.size = htons ((uint16_t) mlen); | 2042 | { |
1389 | /* finally, copy payload (if there is any left...) */ | 2043 | GNUNET_break (0); |
2044 | return; | ||
2045 | } | ||
2046 | |||
2047 | env = GNUNET_MQ_msg_extra (ism, | ||
2048 | payload_length - sizeof (struct GNUNET_TUN_IcmpHeader), | ||
2049 | GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_SERVICE); | ||
2050 | ism->af = htonl (af); /* need to tell destination ICMP protocol family! */ | ||
2051 | ism->icmp_header = *icmp; | ||
1390 | GNUNET_memcpy (&ism[1], | 2052 | GNUNET_memcpy (&ism[1], |
1391 | &icmp[1], | 2053 | &icmp[1], |
1392 | payload_length - sizeof (struct GNUNET_TUN_IcmpHeader)); | 2054 | payload_length - sizeof (struct GNUNET_TUN_IcmpHeader)); |
1393 | } | 2055 | } |
1394 | else | 2056 | else |
1395 | { | 2057 | { |
@@ -1397,19 +2059,8 @@ route_packet (struct DestinationEntry *destination, | |||
1397 | struct in_addr *ip4dst; | 2059 | struct in_addr *ip4dst; |
1398 | struct in6_addr *ip6dst; | 2060 | struct in6_addr *ip6dst; |
1399 | void *payload; | 2061 | void *payload; |
2062 | uint8_t new_type; | ||
1400 | 2063 | ||
1401 | mlen = sizeof (struct GNUNET_EXIT_IcmpInternetMessage) + | ||
1402 | alen + payload_length - sizeof (struct GNUNET_TUN_IcmpHeader); | ||
1403 | if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
1404 | { | ||
1405 | GNUNET_break (0); | ||
1406 | return; | ||
1407 | } | ||
1408 | tnq = GNUNET_malloc (sizeof (struct ChannelMessageQueueEntry) + mlen); | ||
1409 | tnq->msg = &tnq[1]; | ||
1410 | iim = (struct GNUNET_EXIT_IcmpInternetMessage *) &tnq[1]; | ||
1411 | iim->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_INTERNET); | ||
1412 | iim->icmp_header = *icmp; | ||
1413 | /* Perform ICMP protocol-translation (depending on destination AF and source AF) | 2064 | /* Perform ICMP protocol-translation (depending on destination AF and source AF) |
1414 | and throw away ICMP payload depending on ICMP message type */ | 2065 | and throw away ICMP payload depending on ICMP message type */ |
1415 | switch (af) | 2066 | switch (af) |
@@ -1419,21 +2070,21 @@ route_packet (struct DestinationEntry *destination, | |||
1419 | { | 2070 | { |
1420 | case GNUNET_TUN_ICMPTYPE_ECHO_REPLY: | 2071 | case GNUNET_TUN_ICMPTYPE_ECHO_REPLY: |
1421 | if (destination->details.exit_destination.af == AF_INET6) | 2072 | if (destination->details.exit_destination.af == AF_INET6) |
1422 | iim->icmp_header.type = GNUNET_TUN_ICMPTYPE6_ECHO_REPLY; | 2073 | new_type = GNUNET_TUN_ICMPTYPE6_ECHO_REPLY; |
1423 | break; | 2074 | break; |
1424 | case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST: | 2075 | case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST: |
1425 | if (destination->details.exit_destination.af == AF_INET6) | 2076 | if (destination->details.exit_destination.af == AF_INET6) |
1426 | iim->icmp_header.type = GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST; | 2077 | new_type = GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST; |
1427 | break; | 2078 | break; |
1428 | case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE: | 2079 | case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE: |
1429 | if (destination->details.exit_destination.af == AF_INET6) | 2080 | if (destination->details.exit_destination.af == AF_INET6) |
1430 | iim->icmp_header.type = GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE; | 2081 | new_type = GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE; |
1431 | /* throw away IP-payload, exit will have to make it up anyway */ | 2082 | /* throw away IP-payload, exit will have to make it up anyway */ |
1432 | payload_length = sizeof (struct GNUNET_TUN_IcmpHeader); | 2083 | payload_length = sizeof (struct GNUNET_TUN_IcmpHeader); |
1433 | break; | 2084 | break; |
1434 | case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED: | 2085 | case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED: |
1435 | if (destination->details.exit_destination.af == AF_INET6) | 2086 | if (destination->details.exit_destination.af == AF_INET6) |
1436 | iim->icmp_header.type = GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED; | 2087 | new_type = GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED; |
1437 | /* throw away IP-payload, exit will have to make it up anyway */ | 2088 | /* throw away IP-payload, exit will have to make it up anyway */ |
1438 | payload_length = sizeof (struct GNUNET_TUN_IcmpHeader); | 2089 | payload_length = sizeof (struct GNUNET_TUN_IcmpHeader); |
1439 | break; | 2090 | break; |
@@ -1443,7 +2094,6 @@ route_packet (struct DestinationEntry *destination, | |||
1443 | GNUNET_STATISTICS_update (stats, | 2094 | GNUNET_STATISTICS_update (stats, |
1444 | gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"), | 2095 | gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"), |
1445 | 1, GNUNET_NO); | 2096 | 1, GNUNET_NO); |
1446 | GNUNET_free (tnq); | ||
1447 | return; | 2097 | return; |
1448 | } | 2098 | } |
1449 | /* throw away IP-payload, exit will have to make it up anyway */ | 2099 | /* throw away IP-payload, exit will have to make it up anyway */ |
@@ -1453,7 +2103,6 @@ route_packet (struct DestinationEntry *destination, | |||
1453 | GNUNET_STATISTICS_update (stats, | 2103 | GNUNET_STATISTICS_update (stats, |
1454 | gettext_noop ("# ICMPv4 packets dropped (type not allowed)"), | 2104 | gettext_noop ("# ICMPv4 packets dropped (type not allowed)"), |
1455 | 1, GNUNET_NO); | 2105 | 1, GNUNET_NO); |
1456 | GNUNET_free (tnq); | ||
1457 | return; | 2106 | return; |
1458 | } | 2107 | } |
1459 | /* end of AF_INET */ | 2108 | /* end of AF_INET */ |
@@ -1463,13 +2112,13 @@ route_packet (struct DestinationEntry *destination, | |||
1463 | { | 2112 | { |
1464 | case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE: | 2113 | case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE: |
1465 | if (destination->details.exit_destination.af == AF_INET6) | 2114 | if (destination->details.exit_destination.af == AF_INET6) |
1466 | iim->icmp_header.type = GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE; | 2115 | new_type = GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE; |
1467 | /* throw away IP-payload, exit will have to make it up anyway */ | 2116 | /* throw away IP-payload, exit will have to make it up anyway */ |
1468 | payload_length = sizeof (struct GNUNET_TUN_IcmpHeader); | 2117 | payload_length = sizeof (struct GNUNET_TUN_IcmpHeader); |
1469 | break; | 2118 | break; |
1470 | case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED: | 2119 | case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED: |
1471 | if (destination->details.exit_destination.af == AF_INET) | 2120 | if (destination->details.exit_destination.af == AF_INET) |
1472 | iim->icmp_header.type = GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED; | 2121 | new_type = GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED; |
1473 | /* throw away IP-payload, exit will have to make it up anyway */ | 2122 | /* throw away IP-payload, exit will have to make it up anyway */ |
1474 | payload_length = sizeof (struct GNUNET_TUN_IcmpHeader); | 2123 | payload_length = sizeof (struct GNUNET_TUN_IcmpHeader); |
1475 | break; | 2124 | break; |
@@ -1479,7 +2128,6 @@ route_packet (struct DestinationEntry *destination, | |||
1479 | GNUNET_STATISTICS_update (stats, | 2128 | GNUNET_STATISTICS_update (stats, |
1480 | gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"), | 2129 | gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"), |
1481 | 1, GNUNET_NO); | 2130 | 1, GNUNET_NO); |
1482 | GNUNET_free (tnq); | ||
1483 | return; | 2131 | return; |
1484 | } | 2132 | } |
1485 | /* 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 */ |
@@ -1491,7 +2139,6 @@ route_packet (struct DestinationEntry *destination, | |||
1491 | GNUNET_STATISTICS_update (stats, | 2139 | GNUNET_STATISTICS_update (stats, |
1492 | gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"), | 2140 | gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"), |
1493 | 1, GNUNET_NO); | 2141 | 1, GNUNET_NO); |
1494 | GNUNET_free (tnq); | ||
1495 | return; | 2142 | return; |
1496 | } | 2143 | } |
1497 | /* throw away IP-payload, exit will have to make it up anyway */ | 2144 | /* throw away IP-payload, exit will have to make it up anyway */ |
@@ -1499,17 +2146,16 @@ route_packet (struct DestinationEntry *destination, | |||
1499 | break; | 2146 | break; |
1500 | case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST: | 2147 | case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST: |
1501 | if (destination->details.exit_destination.af == AF_INET) | 2148 | if (destination->details.exit_destination.af == AF_INET) |
1502 | iim->icmp_header.type = GNUNET_TUN_ICMPTYPE_ECHO_REQUEST; | 2149 | new_type = GNUNET_TUN_ICMPTYPE_ECHO_REQUEST; |
1503 | break; | 2150 | break; |
1504 | case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY: | 2151 | case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY: |
1505 | if (destination->details.exit_destination.af == AF_INET) | 2152 | if (destination->details.exit_destination.af == AF_INET) |
1506 | iim->icmp_header.type = GNUNET_TUN_ICMPTYPE_ECHO_REPLY; | 2153 | new_type = GNUNET_TUN_ICMPTYPE_ECHO_REPLY; |
1507 | break; | 2154 | break; |
1508 | default: | 2155 | default: |
1509 | GNUNET_STATISTICS_update (stats, | 2156 | GNUNET_STATISTICS_update (stats, |
1510 | gettext_noop ("# ICMPv6 packets dropped (type not allowed)"), | 2157 | gettext_noop ("# ICMPv6 packets dropped (type not allowed)"), |
1511 | 1, GNUNET_NO); | 2158 | 1, GNUNET_NO); |
1512 | GNUNET_free (tnq); | ||
1513 | return; | 2159 | return; |
1514 | } | 2160 | } |
1515 | /* end of AF_INET6 */ | 2161 | /* end of AF_INET6 */ |
@@ -1517,13 +2163,20 @@ route_packet (struct DestinationEntry *destination, | |||
1517 | default: | 2163 | default: |
1518 | GNUNET_assert (0); | 2164 | GNUNET_assert (0); |
1519 | } | 2165 | } |
2166 | |||
1520 | /* update length calculations, as payload_length may have changed */ | 2167 | /* update length calculations, as payload_length may have changed */ |
1521 | mlen = sizeof (struct GNUNET_EXIT_IcmpInternetMessage) + | 2168 | mlen = sizeof (struct GNUNET_EXIT_IcmpInternetMessage) + |
1522 | alen + payload_length - sizeof (struct GNUNET_TUN_IcmpHeader); | 2169 | alen + payload_length - sizeof (struct GNUNET_TUN_IcmpHeader); |
1523 | tnq->len = mlen; | 2170 | if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) |
1524 | iim->header.size = htons ((uint16_t) mlen); | 2171 | { |
1525 | 2172 | GNUNET_break (0); | |
1526 | /* need to tell destination ICMP protocol family! */ | 2173 | return; |
2174 | } | ||
2175 | env = GNUNET_MQ_msg_extra (iim, | ||
2176 | alen + payload_length - sizeof (struct GNUNET_TUN_IcmpHeader), | ||
2177 | GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_INTERNET); | ||
2178 | iim->icmp_header = *icmp; | ||
2179 | iim->icmp_header.type = new_type; | ||
1527 | iim->af = htonl (destination->details.exit_destination.af); | 2180 | iim->af = htonl (destination->details.exit_destination.af); |
1528 | switch (destination->details.exit_destination.af) | 2181 | switch (destination->details.exit_destination.af) |
1529 | { | 2182 | { |
@@ -1541,8 +2194,8 @@ route_packet (struct DestinationEntry *destination, | |||
1541 | GNUNET_assert (0); | 2194 | GNUNET_assert (0); |
1542 | } | 2195 | } |
1543 | GNUNET_memcpy (payload, | 2196 | GNUNET_memcpy (payload, |
1544 | &icmp[1], | 2197 | &icmp[1], |
1545 | payload_length - sizeof (struct GNUNET_TUN_IcmpHeader)); | 2198 | payload_length - sizeof (struct GNUNET_TUN_IcmpHeader)); |
1546 | } | 2199 | } |
1547 | break; | 2200 | break; |
1548 | default: | 2201 | default: |
@@ -1551,7 +2204,8 @@ route_packet (struct DestinationEntry *destination, | |||
1551 | break; | 2204 | break; |
1552 | } | 2205 | } |
1553 | ts->is_established = GNUNET_YES; | 2206 | ts->is_established = GNUNET_YES; |
1554 | send_to_channel (tnq, ts); | 2207 | send_to_channel (ts, |
2208 | env); | ||
1555 | } | 2209 | } |
1556 | 2210 | ||
1557 | 2211 | ||
@@ -1678,694 +2332,6 @@ message_token (void *cls, | |||
1678 | 2332 | ||
1679 | 2333 | ||
1680 | /** | 2334 | /** |
1681 | * Synthesize a plausible ICMP payload for an ICMP error | ||
1682 | * response on the given channel. | ||
1683 | * | ||
1684 | * @param ts channel information | ||
1685 | * @param ipp IPv4 header to fill in (ICMP payload) | ||
1686 | * @param udp "UDP" header to fill in (ICMP payload); might actually | ||
1687 | * also be the first 8 bytes of the TCP header | ||
1688 | */ | ||
1689 | static void | ||
1690 | make_up_icmpv4_payload (struct ChannelState *ts, | ||
1691 | struct GNUNET_TUN_IPv4Header *ipp, | ||
1692 | struct GNUNET_TUN_UdpHeader *udp) | ||
1693 | { | ||
1694 | GNUNET_TUN_initialize_ipv4_header (ipp, | ||
1695 | ts->protocol, | ||
1696 | sizeof (struct GNUNET_TUN_TcpHeader), | ||
1697 | &ts->source_ip.v4, | ||
1698 | &ts->destination_ip.v4); | ||
1699 | udp->source_port = htons (ts->source_port); | ||
1700 | udp->destination_port = htons (ts->destination_port); | ||
1701 | udp->len = htons (0); | ||
1702 | udp->crc = htons (0); | ||
1703 | } | ||
1704 | |||
1705 | |||
1706 | /** | ||
1707 | * Synthesize a plausible ICMP payload for an ICMP error | ||
1708 | * response on the given channel. | ||
1709 | * | ||
1710 | * @param ts channel information | ||
1711 | * @param ipp IPv6 header to fill in (ICMP payload) | ||
1712 | * @param udp "UDP" header to fill in (ICMP payload); might actually | ||
1713 | * also be the first 8 bytes of the TCP header | ||
1714 | */ | ||
1715 | static void | ||
1716 | make_up_icmpv6_payload (struct ChannelState *ts, | ||
1717 | struct GNUNET_TUN_IPv6Header *ipp, | ||
1718 | struct GNUNET_TUN_UdpHeader *udp) | ||
1719 | { | ||
1720 | GNUNET_TUN_initialize_ipv6_header (ipp, | ||
1721 | ts->protocol, | ||
1722 | sizeof (struct GNUNET_TUN_TcpHeader), | ||
1723 | &ts->source_ip.v6, | ||
1724 | &ts->destination_ip.v6); | ||
1725 | udp->source_port = htons (ts->source_port); | ||
1726 | udp->destination_port = htons (ts->destination_port); | ||
1727 | udp->len = htons (0); | ||
1728 | udp->crc = htons (0); | ||
1729 | } | ||
1730 | |||
1731 | |||
1732 | /** | ||
1733 | * We got an ICMP packet back from the CADET channel. Pass it on to the | ||
1734 | * local virtual interface via the helper. | ||
1735 | * | ||
1736 | * @param cls closure, NULL | ||
1737 | * @param channel connection to the other end | ||
1738 | * @param channel_ctx pointer to our 'struct ChannelState *' | ||
1739 | * @param message the actual message | ||
1740 | * @return #GNUNET_OK to keep the connection open, | ||
1741 | * #GNUNET_SYSERR to close it (signal serious error) | ||
1742 | */ | ||
1743 | static int | ||
1744 | receive_icmp_back (void *cls, | ||
1745 | struct GNUNET_CADET_Channel *channel, | ||
1746 | void **channel_ctx, | ||
1747 | const struct GNUNET_MessageHeader *message) | ||
1748 | { | ||
1749 | struct ChannelState *ts = *channel_ctx; | ||
1750 | const struct GNUNET_EXIT_IcmpToVPNMessage *i2v; | ||
1751 | size_t mlen; | ||
1752 | |||
1753 | GNUNET_STATISTICS_update (stats, | ||
1754 | gettext_noop ("# ICMP packets received from cadet"), | ||
1755 | 1, GNUNET_NO); | ||
1756 | mlen = ntohs (message->size); | ||
1757 | if (mlen < sizeof (struct GNUNET_EXIT_IcmpToVPNMessage)) | ||
1758 | { | ||
1759 | GNUNET_break_op (0); | ||
1760 | return GNUNET_SYSERR; | ||
1761 | } | ||
1762 | if (NULL == ts->heap_node) | ||
1763 | { | ||
1764 | GNUNET_break_op (0); | ||
1765 | return GNUNET_SYSERR; | ||
1766 | } | ||
1767 | if (AF_UNSPEC == ts->af) | ||
1768 | { | ||
1769 | GNUNET_break_op (0); | ||
1770 | return GNUNET_SYSERR; | ||
1771 | } | ||
1772 | i2v = (const struct GNUNET_EXIT_IcmpToVPNMessage *) message; | ||
1773 | mlen -= sizeof (struct GNUNET_EXIT_IcmpToVPNMessage); | ||
1774 | { | ||
1775 | char sbuf[INET6_ADDRSTRLEN]; | ||
1776 | char dbuf[INET6_ADDRSTRLEN]; | ||
1777 | |||
1778 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1779 | "Received ICMP packet from cadet, sending %u bytes from %s -> %s via TUN\n", | ||
1780 | (unsigned int) mlen, | ||
1781 | inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof (sbuf)), | ||
1782 | inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof (dbuf))); | ||
1783 | } | ||
1784 | switch (ts->af) | ||
1785 | { | ||
1786 | case AF_INET: | ||
1787 | { | ||
1788 | size_t size = sizeof (struct GNUNET_TUN_IPv4Header) | ||
1789 | + sizeof (struct GNUNET_TUN_IcmpHeader) | ||
1790 | + sizeof (struct GNUNET_MessageHeader) + | ||
1791 | sizeof (struct GNUNET_TUN_Layer2PacketHeader) + | ||
1792 | mlen; | ||
1793 | { | ||
1794 | /* reserve some extra space in case we have an ICMP type here where | ||
1795 | we will need to make up the payload ourselves */ | ||
1796 | char buf[size + sizeof (struct GNUNET_TUN_IPv4Header) + 8] GNUNET_ALIGN; | ||
1797 | struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; | ||
1798 | struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1]; | ||
1799 | struct GNUNET_TUN_IPv4Header *ipv4 = (struct GNUNET_TUN_IPv4Header *) &tun[1]; | ||
1800 | struct GNUNET_TUN_IcmpHeader *icmp = (struct GNUNET_TUN_IcmpHeader *) &ipv4[1]; | ||
1801 | msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
1802 | tun->flags = htons (0); | ||
1803 | tun->proto = htons (ETH_P_IPV4); | ||
1804 | GNUNET_TUN_initialize_ipv4_header (ipv4, | ||
1805 | IPPROTO_ICMP, | ||
1806 | sizeof (struct GNUNET_TUN_IcmpHeader) + mlen, | ||
1807 | &ts->destination_ip.v4, | ||
1808 | &ts->source_ip.v4); | ||
1809 | *icmp = i2v->icmp_header; | ||
1810 | GNUNET_memcpy (&icmp[1], | ||
1811 | &i2v[1], | ||
1812 | mlen); | ||
1813 | /* For some ICMP types, we need to adjust (make up) the payload here. | ||
1814 | Also, depending on the AF used on the other side, we have to | ||
1815 | do ICMP PT (translate ICMP types) */ | ||
1816 | switch (ntohl (i2v->af)) | ||
1817 | { | ||
1818 | case AF_INET: | ||
1819 | switch (icmp->type) | ||
1820 | { | ||
1821 | case GNUNET_TUN_ICMPTYPE_ECHO_REPLY: | ||
1822 | case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST: | ||
1823 | break; | ||
1824 | case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE: | ||
1825 | case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH: | ||
1826 | case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED: | ||
1827 | { | ||
1828 | struct GNUNET_TUN_IPv4Header *ipp = (struct GNUNET_TUN_IPv4Header *) &icmp[1]; | ||
1829 | struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1]; | ||
1830 | |||
1831 | if (mlen != 0) | ||
1832 | { | ||
1833 | /* sender did not strip ICMP payload? */ | ||
1834 | GNUNET_break_op (0); | ||
1835 | return GNUNET_SYSERR; | ||
1836 | } | ||
1837 | size += sizeof (struct GNUNET_TUN_IPv4Header) + 8; | ||
1838 | GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); | ||
1839 | make_up_icmpv4_payload (ts, ipp, udp); | ||
1840 | } | ||
1841 | break; | ||
1842 | default: | ||
1843 | GNUNET_break_op (0); | ||
1844 | GNUNET_STATISTICS_update (stats, | ||
1845 | gettext_noop ("# ICMPv4 packets dropped (type not allowed)"), | ||
1846 | 1, GNUNET_NO); | ||
1847 | return GNUNET_SYSERR; | ||
1848 | } | ||
1849 | /* end AF_INET */ | ||
1850 | break; | ||
1851 | case AF_INET6: | ||
1852 | /* ICMP PT 6-to-4 and possibly making up payloads */ | ||
1853 | switch (icmp->type) | ||
1854 | { | ||
1855 | case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE: | ||
1856 | icmp->type = GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE; | ||
1857 | { | ||
1858 | struct GNUNET_TUN_IPv4Header *ipp = (struct GNUNET_TUN_IPv4Header *) &icmp[1]; | ||
1859 | struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1]; | ||
1860 | |||
1861 | if (mlen != 0) | ||
1862 | { | ||
1863 | /* sender did not strip ICMP payload? */ | ||
1864 | GNUNET_break_op (0); | ||
1865 | return GNUNET_SYSERR; | ||
1866 | } | ||
1867 | size += sizeof (struct GNUNET_TUN_IPv4Header) + 8; | ||
1868 | GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); | ||
1869 | make_up_icmpv4_payload (ts, ipp, udp); | ||
1870 | } | ||
1871 | break; | ||
1872 | case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED: | ||
1873 | icmp->type = GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED; | ||
1874 | { | ||
1875 | struct GNUNET_TUN_IPv4Header *ipp = (struct GNUNET_TUN_IPv4Header *) &icmp[1]; | ||
1876 | struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1]; | ||
1877 | |||
1878 | if (mlen != 0) | ||
1879 | { | ||
1880 | /* sender did not strip ICMP payload? */ | ||
1881 | GNUNET_break_op (0); | ||
1882 | return GNUNET_SYSERR; | ||
1883 | } | ||
1884 | size += sizeof (struct GNUNET_TUN_IPv4Header) + 8; | ||
1885 | GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); | ||
1886 | make_up_icmpv4_payload (ts, ipp, udp); | ||
1887 | } | ||
1888 | break; | ||
1889 | case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG: | ||
1890 | case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM: | ||
1891 | GNUNET_STATISTICS_update (stats, | ||
1892 | gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"), | ||
1893 | 1, GNUNET_NO); | ||
1894 | return GNUNET_OK; | ||
1895 | case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST: | ||
1896 | icmp->type = GNUNET_TUN_ICMPTYPE_ECHO_REQUEST; | ||
1897 | break; | ||
1898 | case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY: | ||
1899 | icmp->type = GNUNET_TUN_ICMPTYPE_ECHO_REPLY; | ||
1900 | break; | ||
1901 | default: | ||
1902 | GNUNET_break_op (0); | ||
1903 | GNUNET_STATISTICS_update (stats, | ||
1904 | gettext_noop ("# ICMPv6 packets dropped (type not allowed)"), | ||
1905 | 1, GNUNET_NO); | ||
1906 | return GNUNET_SYSERR; | ||
1907 | } | ||
1908 | /* end AF_INET6 */ | ||
1909 | break; | ||
1910 | default: | ||
1911 | GNUNET_break_op (0); | ||
1912 | return GNUNET_SYSERR; | ||
1913 | } | ||
1914 | msg->size = htons (size); | ||
1915 | GNUNET_TUN_calculate_icmp_checksum (icmp, | ||
1916 | &i2v[1], | ||
1917 | mlen); | ||
1918 | (void) GNUNET_HELPER_send (helper_handle, | ||
1919 | msg, | ||
1920 | GNUNET_YES, | ||
1921 | NULL, NULL); | ||
1922 | } | ||
1923 | } | ||
1924 | break; | ||
1925 | case AF_INET6: | ||
1926 | { | ||
1927 | size_t size = sizeof (struct GNUNET_TUN_IPv6Header) | ||
1928 | + sizeof (struct GNUNET_TUN_IcmpHeader) | ||
1929 | + sizeof (struct GNUNET_MessageHeader) + | ||
1930 | sizeof (struct GNUNET_TUN_Layer2PacketHeader) + | ||
1931 | mlen; | ||
1932 | { | ||
1933 | char buf[size + sizeof (struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN; | ||
1934 | struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; | ||
1935 | struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1]; | ||
1936 | struct GNUNET_TUN_IPv6Header *ipv6 = (struct GNUNET_TUN_IPv6Header *) &tun[1]; | ||
1937 | struct GNUNET_TUN_IcmpHeader *icmp = (struct GNUNET_TUN_IcmpHeader *) &ipv6[1]; | ||
1938 | msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
1939 | tun->flags = htons (0); | ||
1940 | tun->proto = htons (ETH_P_IPV6); | ||
1941 | GNUNET_TUN_initialize_ipv6_header (ipv6, | ||
1942 | IPPROTO_ICMPV6, | ||
1943 | sizeof (struct GNUNET_TUN_IcmpHeader) + mlen, | ||
1944 | &ts->destination_ip.v6, | ||
1945 | &ts->source_ip.v6); | ||
1946 | *icmp = i2v->icmp_header; | ||
1947 | GNUNET_memcpy (&icmp[1], | ||
1948 | &i2v[1], | ||
1949 | mlen); | ||
1950 | |||
1951 | /* For some ICMP types, we need to adjust (make up) the payload here. | ||
1952 | Also, depending on the AF used on the other side, we have to | ||
1953 | do ICMP PT (translate ICMP types) */ | ||
1954 | switch (ntohl (i2v->af)) | ||
1955 | { | ||
1956 | case AF_INET: | ||
1957 | /* ICMP PT 4-to-6 and possibly making up payloads */ | ||
1958 | switch (icmp->type) | ||
1959 | { | ||
1960 | case GNUNET_TUN_ICMPTYPE_ECHO_REPLY: | ||
1961 | icmp->type = GNUNET_TUN_ICMPTYPE6_ECHO_REPLY; | ||
1962 | break; | ||
1963 | case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST: | ||
1964 | icmp->type = GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST; | ||
1965 | break; | ||
1966 | case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE: | ||
1967 | icmp->type = GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE; | ||
1968 | { | ||
1969 | struct GNUNET_TUN_IPv6Header *ipp = (struct GNUNET_TUN_IPv6Header *) &icmp[1]; | ||
1970 | struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1]; | ||
1971 | |||
1972 | if (mlen != 0) | ||
1973 | { | ||
1974 | /* sender did not strip ICMP payload? */ | ||
1975 | GNUNET_break_op (0); | ||
1976 | return GNUNET_SYSERR; | ||
1977 | } | ||
1978 | size += sizeof (struct GNUNET_TUN_IPv6Header) + 8; | ||
1979 | GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); | ||
1980 | make_up_icmpv6_payload (ts, ipp, udp); | ||
1981 | } | ||
1982 | break; | ||
1983 | case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED: | ||
1984 | icmp->type = GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED; | ||
1985 | { | ||
1986 | struct GNUNET_TUN_IPv6Header *ipp = (struct GNUNET_TUN_IPv6Header *) &icmp[1]; | ||
1987 | struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1]; | ||
1988 | |||
1989 | if (mlen != 0) | ||
1990 | { | ||
1991 | /* sender did not strip ICMP payload? */ | ||
1992 | GNUNET_break_op (0); | ||
1993 | return GNUNET_SYSERR; | ||
1994 | } | ||
1995 | size += sizeof (struct GNUNET_TUN_IPv6Header) + 8; | ||
1996 | GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); | ||
1997 | make_up_icmpv6_payload (ts, ipp, udp); | ||
1998 | } | ||
1999 | break; | ||
2000 | case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH: | ||
2001 | GNUNET_STATISTICS_update (stats, | ||
2002 | gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"), | ||
2003 | 1, GNUNET_NO); | ||
2004 | return GNUNET_OK; | ||
2005 | default: | ||
2006 | GNUNET_break_op (0); | ||
2007 | GNUNET_STATISTICS_update (stats, | ||
2008 | gettext_noop ("# ICMPv4 packets dropped (type not allowed)"), | ||
2009 | 1, GNUNET_NO); | ||
2010 | return GNUNET_SYSERR; | ||
2011 | } | ||
2012 | /* end AF_INET */ | ||
2013 | break; | ||
2014 | case AF_INET6: | ||
2015 | switch (icmp->type) | ||
2016 | { | ||
2017 | case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE: | ||
2018 | case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED: | ||
2019 | case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG: | ||
2020 | case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM: | ||
2021 | { | ||
2022 | struct GNUNET_TUN_IPv6Header *ipp = (struct GNUNET_TUN_IPv6Header *) &icmp[1]; | ||
2023 | struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1]; | ||
2024 | |||
2025 | if (mlen != 0) | ||
2026 | { | ||
2027 | /* sender did not strip ICMP payload? */ | ||
2028 | GNUNET_break_op (0); | ||
2029 | return GNUNET_SYSERR; | ||
2030 | } | ||
2031 | size += sizeof (struct GNUNET_TUN_IPv6Header) + 8; | ||
2032 | GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); | ||
2033 | make_up_icmpv6_payload (ts, ipp, udp); | ||
2034 | } | ||
2035 | break; | ||
2036 | case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST: | ||
2037 | break; | ||
2038 | default: | ||
2039 | GNUNET_break_op (0); | ||
2040 | GNUNET_STATISTICS_update (stats, | ||
2041 | gettext_noop ("# ICMPv6 packets dropped (type not allowed)"), | ||
2042 | 1, GNUNET_NO); | ||
2043 | return GNUNET_SYSERR; | ||
2044 | } | ||
2045 | /* end AF_INET6 */ | ||
2046 | break; | ||
2047 | default: | ||
2048 | GNUNET_break_op (0); | ||
2049 | return GNUNET_SYSERR; | ||
2050 | } | ||
2051 | msg->size = htons (size); | ||
2052 | GNUNET_TUN_calculate_icmp_checksum (icmp, | ||
2053 | &i2v[1], mlen); | ||
2054 | (void) GNUNET_HELPER_send (helper_handle, | ||
2055 | msg, | ||
2056 | GNUNET_YES, | ||
2057 | NULL, NULL); | ||
2058 | } | ||
2059 | } | ||
2060 | break; | ||
2061 | default: | ||
2062 | GNUNET_assert (0); | ||
2063 | } | ||
2064 | GNUNET_CONTAINER_heap_update_cost (ts->heap_node, | ||
2065 | GNUNET_TIME_absolute_get ().abs_value_us); | ||
2066 | GNUNET_CADET_receive_done (channel); | ||
2067 | return GNUNET_OK; | ||
2068 | } | ||
2069 | |||
2070 | |||
2071 | /** | ||
2072 | * We got a UDP packet back from the CADET channel. Pass it on to the | ||
2073 | * local virtual interface via the helper. | ||
2074 | * | ||
2075 | * @param cls closure, NULL | ||
2076 | * @param channel connection to the other end | ||
2077 | * @param channel_ctx pointer to our 'struct ChannelState *' | ||
2078 | * @param message the actual message | ||
2079 | * @return #GNUNET_OK to keep the connection open, | ||
2080 | * #GNUNET_SYSERR to close it (signal serious error) | ||
2081 | */ | ||
2082 | static int | ||
2083 | receive_udp_back (void *cls, | ||
2084 | struct GNUNET_CADET_Channel *channel, | ||
2085 | void **channel_ctx, | ||
2086 | const struct GNUNET_MessageHeader *message) | ||
2087 | { | ||
2088 | struct ChannelState *ts = *channel_ctx; | ||
2089 | const struct GNUNET_EXIT_UdpReplyMessage *reply; | ||
2090 | size_t mlen; | ||
2091 | |||
2092 | GNUNET_STATISTICS_update (stats, | ||
2093 | gettext_noop ("# UDP packets received from cadet"), | ||
2094 | 1, GNUNET_NO); | ||
2095 | mlen = ntohs (message->size); | ||
2096 | if (mlen < sizeof (struct GNUNET_EXIT_UdpReplyMessage)) | ||
2097 | { | ||
2098 | GNUNET_break_op (0); | ||
2099 | return GNUNET_SYSERR; | ||
2100 | } | ||
2101 | if (NULL == ts->heap_node) | ||
2102 | { | ||
2103 | GNUNET_break_op (0); | ||
2104 | return GNUNET_SYSERR; | ||
2105 | } | ||
2106 | if (AF_UNSPEC == ts->af) | ||
2107 | { | ||
2108 | GNUNET_break_op (0); | ||
2109 | return GNUNET_SYSERR; | ||
2110 | } | ||
2111 | reply = (const struct GNUNET_EXIT_UdpReplyMessage *) message; | ||
2112 | mlen -= sizeof (struct GNUNET_EXIT_UdpReplyMessage); | ||
2113 | { | ||
2114 | char sbuf[INET6_ADDRSTRLEN]; | ||
2115 | char dbuf[INET6_ADDRSTRLEN]; | ||
2116 | |||
2117 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2118 | "Received UDP reply from cadet, sending %u bytes from [%s]:%u -> [%s]:%u via TUN\n", | ||
2119 | (unsigned int) mlen, | ||
2120 | inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof (sbuf)), | ||
2121 | ts->destination_port, | ||
2122 | inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof (dbuf)), | ||
2123 | ts->source_port); | ||
2124 | } | ||
2125 | switch (ts->af) | ||
2126 | { | ||
2127 | case AF_INET: | ||
2128 | { | ||
2129 | size_t size = sizeof (struct GNUNET_TUN_IPv4Header) | ||
2130 | + sizeof (struct GNUNET_TUN_UdpHeader) | ||
2131 | + sizeof (struct GNUNET_MessageHeader) + | ||
2132 | sizeof (struct GNUNET_TUN_Layer2PacketHeader) + | ||
2133 | mlen; | ||
2134 | { | ||
2135 | char buf[size] GNUNET_ALIGN; | ||
2136 | struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; | ||
2137 | struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1]; | ||
2138 | struct GNUNET_TUN_IPv4Header *ipv4 = (struct GNUNET_TUN_IPv4Header *) &tun[1]; | ||
2139 | struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipv4[1]; | ||
2140 | msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
2141 | msg->size = htons (size); | ||
2142 | tun->flags = htons (0); | ||
2143 | tun->proto = htons (ETH_P_IPV4); | ||
2144 | GNUNET_TUN_initialize_ipv4_header (ipv4, | ||
2145 | IPPROTO_UDP, | ||
2146 | sizeof (struct GNUNET_TUN_UdpHeader) + mlen, | ||
2147 | &ts->destination_ip.v4, | ||
2148 | &ts->source_ip.v4); | ||
2149 | if (0 == ntohs (reply->source_port)) | ||
2150 | udp->source_port = htons (ts->destination_port); | ||
2151 | else | ||
2152 | udp->source_port = reply->source_port; | ||
2153 | if (0 == ntohs (reply->destination_port)) | ||
2154 | udp->destination_port = htons (ts->source_port); | ||
2155 | else | ||
2156 | udp->destination_port = reply->destination_port; | ||
2157 | udp->len = htons (mlen + sizeof (struct GNUNET_TUN_UdpHeader)); | ||
2158 | GNUNET_TUN_calculate_udp4_checksum (ipv4, | ||
2159 | udp, | ||
2160 | &reply[1], | ||
2161 | mlen); | ||
2162 | GNUNET_memcpy (&udp[1], | ||
2163 | &reply[1], | ||
2164 | mlen); | ||
2165 | (void) GNUNET_HELPER_send (helper_handle, | ||
2166 | msg, | ||
2167 | GNUNET_YES, | ||
2168 | NULL, NULL); | ||
2169 | } | ||
2170 | } | ||
2171 | break; | ||
2172 | case AF_INET6: | ||
2173 | { | ||
2174 | size_t size = sizeof (struct GNUNET_TUN_IPv6Header) | ||
2175 | + sizeof (struct GNUNET_TUN_UdpHeader) | ||
2176 | + sizeof (struct GNUNET_MessageHeader) + | ||
2177 | sizeof (struct GNUNET_TUN_Layer2PacketHeader) + | ||
2178 | mlen; | ||
2179 | { | ||
2180 | char buf[size] GNUNET_ALIGN; | ||
2181 | struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; | ||
2182 | struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1]; | ||
2183 | struct GNUNET_TUN_IPv6Header *ipv6 = (struct GNUNET_TUN_IPv6Header *) &tun[1]; | ||
2184 | struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipv6[1]; | ||
2185 | msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
2186 | msg->size = htons (size); | ||
2187 | tun->flags = htons (0); | ||
2188 | tun->proto = htons (ETH_P_IPV6); | ||
2189 | GNUNET_TUN_initialize_ipv6_header (ipv6, | ||
2190 | IPPROTO_UDP, | ||
2191 | sizeof (struct GNUNET_TUN_UdpHeader) + mlen, | ||
2192 | &ts->destination_ip.v6, | ||
2193 | &ts->source_ip.v6); | ||
2194 | if (0 == ntohs (reply->source_port)) | ||
2195 | udp->source_port = htons (ts->destination_port); | ||
2196 | else | ||
2197 | udp->source_port = reply->source_port; | ||
2198 | if (0 == ntohs (reply->destination_port)) | ||
2199 | udp->destination_port = htons (ts->source_port); | ||
2200 | else | ||
2201 | udp->destination_port = reply->destination_port; | ||
2202 | udp->len = htons (mlen + sizeof (struct GNUNET_TUN_UdpHeader)); | ||
2203 | GNUNET_TUN_calculate_udp6_checksum (ipv6, | ||
2204 | udp, | ||
2205 | &reply[1], mlen); | ||
2206 | GNUNET_memcpy (&udp[1], | ||
2207 | &reply[1], | ||
2208 | mlen); | ||
2209 | (void) GNUNET_HELPER_send (helper_handle, | ||
2210 | msg, | ||
2211 | GNUNET_YES, | ||
2212 | NULL, NULL); | ||
2213 | } | ||
2214 | } | ||
2215 | break; | ||
2216 | default: | ||
2217 | GNUNET_assert (0); | ||
2218 | } | ||
2219 | GNUNET_CONTAINER_heap_update_cost (ts->heap_node, | ||
2220 | GNUNET_TIME_absolute_get ().abs_value_us); | ||
2221 | GNUNET_CADET_receive_done (channel); | ||
2222 | return GNUNET_OK; | ||
2223 | } | ||
2224 | |||
2225 | |||
2226 | /** | ||
2227 | * We got a TCP packet back from the CADET channel. Pass it on to the | ||
2228 | * local virtual interface via the helper. | ||
2229 | * | ||
2230 | * @param cls closure, NULL | ||
2231 | * @param channel connection to the other end | ||
2232 | * @param channel_ctx pointer to our `struct ChannelState *` | ||
2233 | * @param message the actual message | ||
2234 | * @return #GNUNET_OK to keep the connection open, | ||
2235 | * #GNUNET_SYSERR to close it (signal serious error) | ||
2236 | */ | ||
2237 | static int | ||
2238 | receive_tcp_back (void *cls, | ||
2239 | struct GNUNET_CADET_Channel *channel, | ||
2240 | void **channel_ctx, | ||
2241 | const struct GNUNET_MessageHeader *message) | ||
2242 | { | ||
2243 | struct ChannelState *ts = *channel_ctx; | ||
2244 | const struct GNUNET_EXIT_TcpDataMessage *data; | ||
2245 | size_t mlen; | ||
2246 | |||
2247 | GNUNET_STATISTICS_update (stats, | ||
2248 | gettext_noop ("# TCP packets received from cadet"), | ||
2249 | 1, GNUNET_NO); | ||
2250 | mlen = ntohs (message->size); | ||
2251 | if (mlen < sizeof (struct GNUNET_EXIT_TcpDataMessage)) | ||
2252 | { | ||
2253 | GNUNET_break_op (0); | ||
2254 | return GNUNET_SYSERR; | ||
2255 | } | ||
2256 | if (NULL == ts->heap_node) | ||
2257 | { | ||
2258 | GNUNET_break_op (0); | ||
2259 | return GNUNET_SYSERR; | ||
2260 | } | ||
2261 | data = (const struct GNUNET_EXIT_TcpDataMessage *) message; | ||
2262 | mlen -= sizeof (struct GNUNET_EXIT_TcpDataMessage); | ||
2263 | { | ||
2264 | char sbuf[INET6_ADDRSTRLEN]; | ||
2265 | char dbuf[INET6_ADDRSTRLEN]; | ||
2266 | |||
2267 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2268 | "Received TCP reply from cadet, sending %u bytes from [%s]:%u -> [%s]:%u via TUN\n", | ||
2269 | (unsigned int) mlen, | ||
2270 | inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof (sbuf)), | ||
2271 | ts->destination_port, | ||
2272 | inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof (dbuf)), | ||
2273 | ts->source_port); | ||
2274 | } | ||
2275 | if (data->tcp_header.off * 4 < sizeof (struct GNUNET_TUN_TcpHeader)) | ||
2276 | { | ||
2277 | GNUNET_break_op (0); | ||
2278 | return GNUNET_SYSERR; | ||
2279 | } | ||
2280 | switch (ts->af) | ||
2281 | { | ||
2282 | case AF_INET: | ||
2283 | { | ||
2284 | size_t size = sizeof (struct GNUNET_TUN_IPv4Header) | ||
2285 | + sizeof (struct GNUNET_TUN_TcpHeader) | ||
2286 | + sizeof (struct GNUNET_MessageHeader) + | ||
2287 | sizeof (struct GNUNET_TUN_Layer2PacketHeader) + | ||
2288 | mlen; | ||
2289 | { | ||
2290 | char buf[size] GNUNET_ALIGN; | ||
2291 | struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; | ||
2292 | struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1]; | ||
2293 | struct GNUNET_TUN_IPv4Header *ipv4 = (struct GNUNET_TUN_IPv4Header *) &tun[1]; | ||
2294 | struct GNUNET_TUN_TcpHeader *tcp = (struct GNUNET_TUN_TcpHeader *) &ipv4[1]; | ||
2295 | msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
2296 | msg->size = htons (size); | ||
2297 | tun->flags = htons (0); | ||
2298 | tun->proto = htons (ETH_P_IPV4); | ||
2299 | GNUNET_TUN_initialize_ipv4_header (ipv4, | ||
2300 | IPPROTO_TCP, | ||
2301 | sizeof (struct GNUNET_TUN_TcpHeader) + mlen, | ||
2302 | &ts->destination_ip.v4, | ||
2303 | &ts->source_ip.v4); | ||
2304 | *tcp = data->tcp_header; | ||
2305 | tcp->source_port = htons (ts->destination_port); | ||
2306 | tcp->destination_port = htons (ts->source_port); | ||
2307 | GNUNET_TUN_calculate_tcp4_checksum (ipv4, | ||
2308 | tcp, | ||
2309 | &data[1], | ||
2310 | mlen); | ||
2311 | GNUNET_memcpy (&tcp[1], | ||
2312 | &data[1], | ||
2313 | mlen); | ||
2314 | (void) GNUNET_HELPER_send (helper_handle, | ||
2315 | msg, | ||
2316 | GNUNET_YES, | ||
2317 | NULL, NULL); | ||
2318 | } | ||
2319 | } | ||
2320 | break; | ||
2321 | case AF_INET6: | ||
2322 | { | ||
2323 | size_t size = sizeof (struct GNUNET_TUN_IPv6Header) | ||
2324 | + sizeof (struct GNUNET_TUN_TcpHeader) | ||
2325 | + sizeof (struct GNUNET_MessageHeader) + | ||
2326 | sizeof (struct GNUNET_TUN_Layer2PacketHeader) + | ||
2327 | mlen; | ||
2328 | { | ||
2329 | char buf[size] GNUNET_ALIGN; | ||
2330 | struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf; | ||
2331 | struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1]; | ||
2332 | struct GNUNET_TUN_IPv6Header *ipv6 = (struct GNUNET_TUN_IPv6Header *) &tun[1]; | ||
2333 | struct GNUNET_TUN_TcpHeader *tcp = (struct GNUNET_TUN_TcpHeader *) &ipv6[1]; | ||
2334 | msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER); | ||
2335 | msg->size = htons (size); | ||
2336 | tun->flags = htons (0); | ||
2337 | tun->proto = htons (ETH_P_IPV6); | ||
2338 | GNUNET_TUN_initialize_ipv6_header (ipv6, | ||
2339 | IPPROTO_TCP, | ||
2340 | sizeof (struct GNUNET_TUN_TcpHeader) + mlen, | ||
2341 | &ts->destination_ip.v6, | ||
2342 | &ts->source_ip.v6); | ||
2343 | *tcp = data->tcp_header; | ||
2344 | tcp->source_port = htons (ts->destination_port); | ||
2345 | tcp->destination_port = htons (ts->source_port); | ||
2346 | GNUNET_TUN_calculate_tcp6_checksum (ipv6, | ||
2347 | tcp, | ||
2348 | &data[1], | ||
2349 | mlen); | ||
2350 | GNUNET_memcpy (&tcp[1], | ||
2351 | &data[1], | ||
2352 | mlen); | ||
2353 | (void) GNUNET_HELPER_send (helper_handle, | ||
2354 | msg, | ||
2355 | GNUNET_YES, | ||
2356 | NULL, NULL); | ||
2357 | } | ||
2358 | } | ||
2359 | break; | ||
2360 | } | ||
2361 | GNUNET_CONTAINER_heap_update_cost (ts->heap_node, | ||
2362 | GNUNET_TIME_absolute_get ().abs_value_us); | ||
2363 | GNUNET_CADET_receive_done (channel); | ||
2364 | return GNUNET_OK; | ||
2365 | } | ||
2366 | |||
2367 | |||
2368 | /** | ||
2369 | * Allocate an IPv4 address from the range of the channel | 2335 | * Allocate an IPv4 address from the range of the channel |
2370 | * for a new redirection. | 2336 | * for a new redirection. |
2371 | * | 2337 | * |
@@ -2813,29 +2779,6 @@ handle_client_redirect_to_service (void *cls, | |||
2813 | } | 2779 | } |
2814 | 2780 | ||
2815 | 2781 | ||
2816 | /** | ||
2817 | * Function called whenever a channel is destroyed. Should clean up | ||
2818 | * any associated state. | ||
2819 | * | ||
2820 | * @param cls closure (set from #GNUNET_CADET_connect) | ||
2821 | * @param channel connection to the other end (henceforth invalid) | ||
2822 | * @param channel_ctx place where local state associated | ||
2823 | * with the channel is stored (our `struct ChannelState`) | ||
2824 | */ | ||
2825 | static void | ||
2826 | channel_cleaner (void *cls, | ||
2827 | const struct GNUNET_CADET_Channel *channel, | ||
2828 | void *channel_ctx) | ||
2829 | { | ||
2830 | struct ChannelState *ts = channel_ctx; | ||
2831 | |||
2832 | ts->channel = NULL; /* we must not call GNUNET_CADET_channel_destroy() anymore */ | ||
2833 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2834 | "CADET notified us about death of channel to `%s'\n", | ||
2835 | print_channel_destination (&ts->destination)); | ||
2836 | free_channel_state (ts); | ||
2837 | } | ||
2838 | |||
2839 | 2782 | ||
2840 | /** | 2783 | /** |
2841 | * Free memory occupied by an entry in the destination map. | 2784 | * Free memory occupied by an entry in the destination map. |
@@ -2984,12 +2927,6 @@ run (void *cls, | |||
2984 | const struct GNUNET_CONFIGURATION_Handle *cfg_, | 2927 | const struct GNUNET_CONFIGURATION_Handle *cfg_, |
2985 | struct GNUNET_SERVICE_Handle *service) | 2928 | struct GNUNET_SERVICE_Handle *service) |
2986 | { | 2929 | { |
2987 | static const struct GNUNET_CADET_MessageHandler cadet_handlers[] = { | ||
2988 | { &receive_udp_back, GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY, 0}, | ||
2989 | { &receive_tcp_back, GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_VPN, 0}, | ||
2990 | { &receive_icmp_back, GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_VPN, 0}, | ||
2991 | {NULL, 0, 0} | ||
2992 | }; | ||
2993 | char *ifname; | 2930 | char *ifname; |
2994 | char *ipv6addr; | 2931 | char *ipv6addr; |
2995 | char *ipv6prefix_s; | 2932 | char *ipv6prefix_s; |
@@ -3130,11 +3067,7 @@ run (void *cls, | |||
3130 | } | 3067 | } |
3131 | vpn_argv[6] = NULL; | 3068 | vpn_argv[6] = NULL; |
3132 | 3069 | ||
3133 | cadet_handle | 3070 | cadet_handle = GNUNET_CADET_connecT (cfg_); |
3134 | = GNUNET_CADET_connect (cfg_, | ||
3135 | NULL, | ||
3136 | &channel_cleaner, | ||
3137 | cadet_handlers); | ||
3138 | // FIXME never opens ports??? | 3071 | // FIXME never opens ports??? |
3139 | helper_handle = GNUNET_HELPER_start (GNUNET_NO, | 3072 | helper_handle = GNUNET_HELPER_start (GNUNET_NO, |
3140 | "gnunet-helper-vpn", vpn_argv, | 3073 | "gnunet-helper-vpn", vpn_argv, |