aboutsummaryrefslogtreecommitdiff
path: root/src/vpn/gnunet-service-vpn.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2017-02-22 17:32:15 +0100
committerChristian Grothoff <christian@grothoff.org>2017-02-22 17:32:15 +0100
commit88a0df3dcc38c6e82f483bff386c87d8e1ec4459 (patch)
treec086b6c30a6fc54e0d72aabe7857f3b659915caa /src/vpn/gnunet-service-vpn.c
parent85088f7eedd1146890a5ce9af05fff934a5b1b8d (diff)
downloadgnunet-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/gnunet-service-vpn.c')
-rw-r--r--src/vpn/gnunet-service-vpn.c1753
1 files changed, 843 insertions, 910 deletions
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 */
595static size_t
596send_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 */
642static void 584static void
643send_to_channel (struct ChannelMessageQueueEntry *tnq, 585send_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 */
644static void
645channel_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 */
667static void
668make_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 */
693static void
694make_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 */
718static int
719check_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 */
745static void
746handle_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 */
1061static int
1062check_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 */
1088static void
1089handle_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 */
1220static int
1221check_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 */
1247static void
1248handle_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 */
1366static struct GNUNET_CADET_Channel *
1367create_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 */
1689static void
1690make_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 */
1715static void
1716make_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 */
1743static int
1744receive_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 */
2082static int
2083receive_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 */
2237static int
2238receive_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 */
2825static void
2826channel_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,