GNUnet 0.27.0
 
Loading...
Searching...
No Matches
gnunet-daemon-exit.c File Reference

tool to allow IP traffic exit from the GNUnet cadet to the Internet More...

#include "gnunet_common.h"
#include "gnunet_pils_service.h"
#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_protocols.h"
#include "gnunet_applications.h"
#include "gnunet_dht_service.h"
#include "gnunet_cadet_service.h"
#include "gnunet_statistics_service.h"
#include "gnunet_signatures.h"
#include "gnunet_regex_service.h"
#include "exit.h"
#include "block_dns.h"
Include dependency graph for gnunet-daemon-exit.c:

Go to the source code of this file.

Data Structures

struct  SocketAddress
 Information about an address. More...
 
struct  LocalService
 This struct is saved into the services-hashmap to represent a service this peer is specifically offering an exit for (for a specific domain name). More...
 
struct  RedirectInformation
 Information we use to track a connection (the classical 6-tuple of IP-version, protocol, source-IP, destination-IP, source-port and destinatin-port. More...
 
struct  ChannelState
 This struct is saved into connections_map to allow finding the right channel given an IP packet from TUN. More...
 
struct  DnsResponseMessage
 Message with a DNS response. More...
 

Macros

#define REGEX_MAX_PATH_LEN_IPV4   4
 Maximum path compression length for cadet regex announcing for IPv4 address based regex.
 
#define REGEX_MAX_PATH_LEN_IPV6   8
 Maximum path compression length for cadet regex announcing for IPv6 address based regex.
 
#define REGEX_REFRESH_FREQUENCY
 How frequently do we re-announce the regex for the exit?
 
#define DHT_PUT_FREQUENCY
 How frequently do we re-announce the DNS exit in the DHT?
 
#define DNS_ADVERTISEMENT_TIMEOUT
 How long do we typically sign the DNS exit advertisement for?
 
#define LOG(kind, ...)    GNUNET_log_from (kind, "exit", __VA_ARGS__);
 Generic logging shorthand.
 

Functions

static GNUNET_NETWORK_STRUCT_END void process_dns_result (void *cls, const struct GNUNET_TUN_DnsHeader *dns, size_t r)
 Callback called from DNSSTUB resolver when a resolution succeeded.
 
static int check_dns_request (void *cls, const struct DnsResponseMessage *msg)
 Check a request via cadet to perform a DNS query.
 
static void handle_dns_request (void *cls, const struct DnsResponseMessage *msg)
 Process a request via cadet to perform a DNS query.
 
static void hash_redirect_info (struct GNUNET_HashCode *hash, const struct RedirectInformation *ri)
 Given IP information about a connection, calculate the respective hash we would use for the connections_map.
 
static struct ChannelStateget_redirect_state (int af, int protocol, const void *destination_ip, uint16_t destination_port, const void *local_ip, uint16_t local_port, struct GNUNET_HashCode *state_key)
 Get our connection tracking state.
 
static int check_tcp_service (void *cls, const struct GNUNET_EXIT_TcpServiceStartMessage *start)
 Check a request via cadet to send a request to a TCP service offered by this system.
 
static void prepare_ipv4_packet (const void *payload, size_t payload_length, int protocol, const struct GNUNET_TUN_TcpHeader *tcp_header, const struct SocketAddress *src_address, const struct SocketAddress *dst_address, struct GNUNET_TUN_IPv4Header *pkt4)
 Prepare an IPv4 packet for transmission via the TUN interface.
 
static void prepare_ipv6_packet (const void *payload, size_t payload_length, int protocol, const struct GNUNET_TUN_TcpHeader *tcp_header, const struct SocketAddress *src_address, const struct SocketAddress *dst_address, struct GNUNET_TUN_IPv6Header *pkt6)
 Prepare an IPv6 packet for transmission via the TUN interface.
 
static void send_tcp_packet_via_tun (const struct SocketAddress *destination_address, const struct SocketAddress *source_address, const struct GNUNET_TUN_TcpHeader *tcp_header, const void *payload, size_t payload_length)
 Send a TCP packet via the TUN interface.
 
static void send_icmp_packet_via_tun (const struct SocketAddress *destination_address, const struct SocketAddress *source_address, const struct GNUNET_TUN_IcmpHeader *icmp_header, const void *payload, size_t payload_length)
 Send an ICMP packet via the TUN interface.
 
static void setup_fresh_address (int af, uint8_t proto, struct SocketAddress *local_address)
 We need to create a (unique) fresh local address (IP+port).
 
static void setup_state_record (struct ChannelState *state)
 We are starting a fresh connection (TCP or UDP) and need to pick a source port and IP address (within the correct range and address family) to associate replies with the connection / correct cadet channel.
 
static void send_udp_packet_via_tun (const struct SocketAddress *destination_address, const struct SocketAddress *source_address, const void *payload, size_t payload_length)
 Send a UDP packet via the TUN interface.
 
static int check_udp_remote (void *cls, const struct GNUNET_EXIT_UdpInternetMessage *msg)
 Check a request to forward UDP data to the Internet via this peer.
 
static void handle_udp_remote (void *cls, const struct GNUNET_EXIT_UdpInternetMessage *msg)
 Process a request to forward UDP data to the Internet via this peer.
 
static int check_udp_service (void *cls, const struct GNUNET_EXIT_UdpServiceMessage *msg)
 Check a request via cadet to send a request to a UDP service offered by this system.
 
static void handle_udp_service (void *cls, const struct GNUNET_EXIT_UdpServiceMessage *msg)
 Process a request via cadet to send a request to a UDP service offered by this system.
 
static void handle_tcp_service (void *cls, const struct GNUNET_EXIT_TcpServiceStartMessage *start)
 Process a request via cadet to send a request to a TCP service offered by this system.
 
static int check_tcp_remote (void *cls, const struct GNUNET_EXIT_TcpInternetStartMessage *start)
 Check a request to forward TCP data to the Internet via this peer.
 
static void handle_tcp_remote (void *cls, const struct GNUNET_EXIT_TcpInternetStartMessage *start)
 Process a request to forward TCP data to the Internet via this peer.
 
static int check_tcp_data (void *cls, const struct GNUNET_EXIT_TcpDataMessage *data)
 Check a request to forward TCP data on an established connection via this peer.
 
static void handle_tcp_data (void *cls, const struct GNUNET_EXIT_TcpDataMessage *data)
 Process a request to forward TCP data on an established connection via this peer.
 
static void make_up_icmpv4_payload (struct ChannelState *state, struct GNUNET_TUN_IPv4Header *ipp, struct GNUNET_TUN_UdpHeader *udp)
 Synthesize a plausible ICMP payload for an ICMPv4 error response on the given channel.
 
static void make_up_icmpv6_payload (struct ChannelState *state, struct GNUNET_TUN_IPv6Header *ipp, struct GNUNET_TUN_UdpHeader *udp)
 Synthesize a plausible ICMP payload for an ICMPv6 error response on the given channel.
 
static int check_icmp_remote (void *cls, const struct GNUNET_EXIT_IcmpInternetMessage *msg)
 Check a request to forward ICMP data to the Internet via this peer.
 
static void handle_icmp_remote (void *cls, const struct GNUNET_EXIT_IcmpInternetMessage *msg)
 Process a request to forward ICMP data to the Internet via this peer.
 
static uint16_t make_up_icmp_service_payload (struct ChannelState *state, char *buf)
 Setup ICMP payload for ICMP error messages.
 
static int check_icmp_service (void *cls, const struct GNUNET_EXIT_IcmpServiceMessage *msg)
 Check a request via cadet to send ICMP data to a service offered by this system.
 
static void handle_icmp_service (void *cls, const struct GNUNET_EXIT_IcmpServiceMessage *msg)
 Process a request via cadet to send ICMP data to a service offered by this system.
 
static int free_service_record (void *cls, const struct GNUNET_HashCode *key, void *value)
 Free memory associated with a service record.
 
static void * new_service_channel (void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *initiator)
 Callback from CADET for new channels.
 
static void clean_channel (void *cls, const struct GNUNET_CADET_Channel *channel)
 Function called by cadet whenever an inbound channel is destroyed.
 
static void store_service (int proto, const char *name, uint16_t destination_port, struct LocalService *service)
 Given a service descriptor and a destination port, find the respective service entry.
 
static void send_packet_to_cadet_channel (struct ChannelState *s, struct GNUNET_MQ_Envelope *env)
 Send the given packet via the cadet channel.
 
static void icmp_from_helper (const struct GNUNET_TUN_IcmpHeader *icmp, size_t pktlen, int af, const void *destination_ip, const void *source_ip)
 Handles an ICMP packet received from the helper.
 
static void udp_from_helper (const struct GNUNET_TUN_UdpHeader *udp, size_t pktlen, int af, const void *destination_ip, const void *source_ip)
 Handles an UDP packet received from the helper.
 
static void tcp_from_helper (const struct GNUNET_TUN_TcpHeader *tcp, size_t pktlen, int af, const void *destination_ip, const void *source_ip)
 Handles a TCP packet received from the helper.
 
static int message_token (void *cls, const struct GNUNET_MessageHeader *message)
 Receive packets from the helper-process.
 
static void * new_channel (void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *initiator)
 Callback from CADET for new channels.
 
static int free_iterate (void *cls, const struct GNUNET_HashCode *hash, void *value)
 Function that frees everything from a hashmap.
 
static void dummy_task (void *cls)
 Function scheduled as very last function if the service disabled itself because the helper is not installed properly.
 
static void cleanup (void *cls)
 Function scheduled as very last function, cleans up after us.
 
static void add_services (int proto, char *cpy, const char *name)
 Add services to the service map.
 
static void read_service_conf (void *cls, const char *section)
 Reads the configuration and populates #udp_services and #tcp_services.
 
static void do_dht_put (void *cls)
 We are running a DNS exit service, advertise it in the DHT.
 
static void dht_put_cont (void *cls)
 Function called when the DHT PUT operation is complete.
 
static void sign_dns_advertisement (void *cls, const struct GNUNET_PeerIdentity *pid, const struct GNUNET_CRYPTO_EddsaSignature *sig)
 
static void do_initial_dht_put (void *cls, const struct GNUNET_HELLO_Parser *parser, const struct GNUNET_HashCode *hash)
 
static void parse_ip_options ()
 Figure out which IP versions we should support (and which are supported by the OS) according to our configuration.
 
static void advertise_dns_exit ()
 Helper function to open the CADET port for DNS exits and to advertise the DNS exit (if applicable).
 
static int setup_exit_helper_args ()
 Initialize exit_argv.
 
static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg_)
 Main function that will be run by the scheduler.
 
int main (int argc, char *const *argv)
 The main function.
 

Variables

static int global_ret
 Return value from 'main'.
 
static struct GNUNET_REGEX_Announcementregex4
 Handle to our regex announcement for IPv4.
 
static struct GNUNET_REGEX_Announcementregex6
 Handle to our regex announcement for IPv4.
 
static const struct GNUNET_CONFIGURATION_Handlecfg
 The handle to the configuration used throughout the process.
 
static struct GNUNET_HELPER_Handlehelper_handle
 The handle to the helper.
 
static char * exit_argv [8]
 Arguments to the exit helper.
 
static struct in6_addr exit_ipv6addr
 IPv6 address of our TUN interface.
 
static unsigned long long ipv6prefix
 IPv6 prefix (0..127) from configuration file.
 
static struct in_addr exit_ipv4addr
 IPv4 address of our TUN interface.
 
static struct in_addr exit_ipv4mask
 IPv4 netmask of our TUN interface.
 
static struct GNUNET_STATISTICS_Handlestats
 Statistics.
 
static struct GNUNET_CADET_Handlecadet_handle
 The handle to cadet.
 
static struct GNUNET_CONTAINER_MultiHashMapconnections_map
 This hashmaps contains the mapping from peer, service-descriptor, source-port and destination-port to a struct ChannelState.
 
static struct GNUNET_CONTAINER_Heapconnections_heap
 Heap so we can quickly find "old" connections.
 
static unsigned long long max_connections
 If there are at least this many connections, old ones will be removed.
 
static struct GNUNET_CONTAINER_MultiHashMapservices
 This hashmaps saves interesting things about the configured services.
 
static struct ChannelStatechannels [UINT16_MAX+1]
 Array of all open DNS requests from channels.
 
static struct GNUNET_DNSSTUB_Contextdnsstub
 Handle to the DNS Stub resolver.
 
static struct GNUNET_DHT_PutHandledht_put
 Handle for ongoing DHT PUT operations to advertise exit service.
 
static struct GNUNET_DHT_Handledht
 Handle to the DHT.
 
static struct GNUNET_SCHEDULER_Taskdht_task
 Task for doing DHT PUTs to advertise exit service.
 
static struct GNUNET_DNS_Advertisement dns_advertisement
 Advertisement message we put into the DHT to advertise us as a DNS exit.
 
static struct GNUNET_HashCode dht_put_key
 Key we store the DNS advertismenet under.
 
static struct GNUNET_PILS_Handlepils
 The pils service handle.
 
static struct GNUNET_PILS_Operationsign_op
 Operation for signing the dns advertisement.
 
static struct GNUNET_CADET_Portdns_port
 Port for DNS exit.
 
static struct GNUNET_CADET_Portcadet_port4
 Port for IPv4 exit.
 
static struct GNUNET_CADET_Portcadet_port6
 Port for IPv6 exit.
 
static int ipv4_exit
 Are we an IPv4-exit?
 
static int ipv6_exit
 Are we an IPv6-exit?
 
static int ipv4_enabled
 Do we support IPv4 at all on the TUN interface?
 
static int ipv6_enabled
 Do we support IPv6 at all on the TUN interface?
 

Detailed Description

tool to allow IP traffic exit from the GNUnet cadet to the Internet

Author
Philipp Toelke
Christian Grothoff

TODO:

  • test

Design:

  • which code should advertise services? the service model is right now a bit odd, especially as this code DOES the exit and knows the DNS "name", but OTOH this is clearly NOT the place to advertise the service's existence; maybe the daemon should turn into a service with an API to add local-exit services dynamically?

Definition in file gnunet-daemon-exit.c.

Macro Definition Documentation

◆ REGEX_MAX_PATH_LEN_IPV4

#define REGEX_MAX_PATH_LEN_IPV4   4

Maximum path compression length for cadet regex announcing for IPv4 address based regex.

Definition at line 56 of file gnunet-daemon-exit.c.

◆ REGEX_MAX_PATH_LEN_IPV6

#define REGEX_MAX_PATH_LEN_IPV6   8

Maximum path compression length for cadet regex announcing for IPv6 address based regex.

Definition at line 62 of file gnunet-daemon-exit.c.

◆ REGEX_REFRESH_FREQUENCY

#define REGEX_REFRESH_FREQUENCY
Value:
#define GNUNET_TIME_UNIT_MINUTES
One minute.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
Definition time.c:486

How frequently do we re-announce the regex for the exit?

Definition at line 67 of file gnunet-daemon-exit.c.

93{
97 int af;
98
102 union
103 {
107 struct in_addr ipv4;
108
112 struct in6_addr ipv6;
113 } address;
114
118 uint8_t proto;
119
123 uint16_t port;
124};
125
126
132struct LocalService
133{
137 struct SocketAddress address;
138
143
147 char *name;
148
152 struct GNUNET_CADET_Port *port;
153
157 int16_t is_udp;
158};
159
160
167{
173
180
181 /*
182 Note 1: additional information might be added here in the
183 future to support protocols that require special handling,
184 such as ftp/tftp
185
186 Note 2: we might also sometimes not match on all components
187 of the tuple, to support protocols where things do not always
188 fully map.
189 */
190};
191
192
199struct ChannelState
200{
205
211
217 int is_dns;
218
219 union
220 {
221 struct
222 {
227
232
236 struct LocalService *serv;
237
241 struct RedirectInformation ri;
242 } tcp_udp;
243
244 struct
245 {
251
255 uint16_t original_id;
256
260 uint16_t my_id;
261 } dns;
262 } specifics;
263};
264
265
269static int global_ret;
270
274static struct GNUNET_REGEX_Announcement *regex4;
275
279static struct GNUNET_REGEX_Announcement *regex6;
280
284static const struct GNUNET_CONFIGURATION_Handle *cfg;
285
290
294static char *exit_argv[8];
295
299static struct in6_addr exit_ipv6addr;
300
304static unsigned long long ipv6prefix;
305
309static struct in_addr exit_ipv4addr;
310
314static struct in_addr exit_ipv4mask;
315
319static struct GNUNET_STATISTICS_Handle *stats;
320
324static struct GNUNET_CADET_Handle *cadet_handle;
325
331
336
340static unsigned long long max_connections;
341
346
350static struct ChannelState *channels[UINT16_MAX + 1];
351
355static struct GNUNET_DNSSTUB_Context *dnsstub;
356
360static struct GNUNET_DHT_PutHandle *dht_put;
361
365static struct GNUNET_DHT_Handle *dht;
366
370static struct GNUNET_SCHEDULER_Task *dht_task;
371
377
381static struct GNUNET_HashCode dht_put_key;
382
386static struct GNUNET_PILS_Handle *pils;
387
391static struct GNUNET_PILS_Operation *sign_op;
392
396static struct GNUNET_CADET_Port *dns_port;
397
401static struct GNUNET_CADET_Port *cadet_port4;
402
406static struct GNUNET_CADET_Port *cadet_port6;
407
411static int ipv4_exit;
412
416static int ipv6_exit;
417
421static int ipv4_enabled;
422
426static int ipv6_enabled;
427
428
430
435{
440
445
446 /* Followed by more DNS payload */
447};
448
450
451
460static void
461process_dns_result (void *cls,
462 const struct GNUNET_TUN_DnsHeader *dns,
463 size_t r)
464{
465 struct ChannelState *ts;
466 struct GNUNET_MQ_Envelope *env;
467 struct DnsResponseMessage *resp;
468
470 "Processing DNS result from stub resolver\n");
471 GNUNET_assert (NULL == cls);
472 if (NULL == dns)
473 return;
474 /* Handle case that this is a reply to a request from a CADET DNS channel */
475 ts = channels[dns->id];
476 if (NULL == ts)
477 return;
479 "Got a response from the stub resolver for DNS request received via CADET!\n");
480 channels[dns->id] = NULL;
481 env = GNUNET_MQ_msg_extra (resp,
482 r - sizeof(struct GNUNET_TUN_DnsHeader),
484 GNUNET_memcpy (&resp->dns,
485 dns,
486 r);
487 resp->dns.id = ts->specifics.dns.original_id;
489 env);
490}
491
492
501static int
502check_dns_request (void *cls,
503 const struct DnsResponseMessage *msg)
504{
505 struct ChannelState *ts = cls;
506
507 if (NULL == dnsstub)
508 {
509 GNUNET_break (0);
510 return GNUNET_SYSERR;
511 }
512 if (GNUNET_NO == ts->is_dns)
513 {
514 GNUNET_break_op (0);
515 return GNUNET_SYSERR;
516 }
517 return GNUNET_OK;
518}
519
520
527static void
528handle_dns_request (void *cls,
529 const struct DnsResponseMessage *msg)
530{
531 struct ChannelState *ts = cls;
532 size_t mlen = ntohs (msg->header.size);
533 size_t dlen = mlen - sizeof(struct GNUNET_MessageHeader);
534 char buf[dlen] GNUNET_ALIGN;
535 struct GNUNET_TUN_DnsHeader *dns_out;
536
537 if (GNUNET_SYSERR == ts->is_dns)
538 {
539 /* channel is DNS from now on */
540 ts->is_dns = GNUNET_YES;
541 }
542 ts->specifics.dns.original_id = msg->dns.id;
543 if (channels[ts->specifics.dns.my_id] == ts)
544 channels[ts->specifics.dns.my_id] = NULL;
547 UINT16_MAX
548 + 1);
549 channels[ts->specifics.dns.my_id] = ts;
550 GNUNET_memcpy (buf,
551 &msg->dns,
552 dlen);
553 dns_out = (struct GNUNET_TUN_DnsHeader *) buf;
554 dns_out->id = ts->specifics.dns.my_id;
556 buf,
557 dlen,
559 NULL);
560 if (NULL == ts->specifics.dns.rs)
561 {
562 GNUNET_break_op (0);
563 return;
564 }
566}
567
568
576static void
578 const struct RedirectInformation *ri)
579{
580 char *off;
581
582 memset (hash,
583 0,
584 sizeof(struct GNUNET_HashCode));
585 /* the GNUnet hashmap only uses the first sizeof(unsigned int) of the hash,
586 so we put the IP address in there (and hope for few collisions) */
587 off = (char *) hash;
588 switch (ri->remote_address.af)
589 {
590 case AF_INET:
591 GNUNET_memcpy (off,
592 &ri->remote_address.address.ipv4,
593 sizeof(struct in_addr));
594 off += sizeof(struct in_addr);
595 break;
596
597 case AF_INET6:
598 GNUNET_memcpy (off,
599 &ri->remote_address.address.ipv6,
600 sizeof(struct in6_addr));
601 off += sizeof(struct in_addr);
602 break;
603
604 default:
605 GNUNET_assert (0);
606 }
607 GNUNET_memcpy (off,
608 &ri->remote_address.port,
609 sizeof(uint16_t));
610 off += sizeof(uint16_t);
611 switch (ri->local_address.af)
612 {
613 case AF_INET:
614 GNUNET_memcpy (off,
615 &ri->local_address.address.ipv4,
616 sizeof(struct in_addr));
617 off += sizeof(struct in_addr);
618 break;
619
620 case AF_INET6:
621 GNUNET_memcpy (off,
622 &ri->local_address.address.ipv6,
623 sizeof(struct in6_addr));
624 off += sizeof(struct in_addr);
625 break;
626
627 default:
628 GNUNET_assert (0);
629 }
630 GNUNET_memcpy (off,
631 &ri->local_address.port,
632 sizeof(uint16_t));
633 off += sizeof(uint16_t);
634 GNUNET_memcpy (off,
635 &ri->remote_address.proto,
636 sizeof(uint8_t));
637 /* off += sizeof (uint8_t); */
638}
639
640
654static struct ChannelState *
656 int protocol,
657 const void *destination_ip,
658 uint16_t destination_port,
659 const void *local_ip,
660 uint16_t local_port,
662{
663 struct RedirectInformation ri;
664 struct GNUNET_HashCode key;
665 struct ChannelState *state;
666
667 if (((af == AF_INET) && (protocol == IPPROTO_ICMP)) ||
668 ((af == AF_INET6) && (protocol == IPPROTO_ICMPV6)))
669 {
670 /* ignore ports */
672 local_port = 0;
673 }
674 ri.remote_address.af = af;
675 if (af == AF_INET)
676 ri.remote_address.address.ipv4 = *((struct in_addr*) destination_ip);
677 else
678 ri.remote_address.address.ipv6 = *((struct in6_addr*) destination_ip);
679 ri.remote_address.port = destination_port;
680 ri.remote_address.proto = protocol;
681 ri.local_address.af = af;
682 if (af == AF_INET)
683 ri.local_address.address.ipv4 = *((struct in_addr*) local_ip);
684 else
685 ri.local_address.address.ipv6 = *((struct in6_addr*) local_ip);
686 ri.local_address.port = local_port;
687 ri.local_address.proto = protocol;
689 &ri);
690 if (NULL != state_key)
691 *state_key = key;
693 &key);
694 if (NULL == state)
695 return NULL;
696 /* Mark this connection as freshly used */
697 if (NULL == state_key)
698 GNUNET_CONTAINER_heap_update_cost (state->specifics.tcp_udp.heap_node,
699 GNUNET_TIME_absolute_get ().abs_value_us)
700 ;
701 return state;
702}
703
704
714static int
715check_tcp_service (void *cls,
717{
718 struct ChannelState *state = cls;
719
720 if (NULL == state)
721 {
722 GNUNET_break_op (0);
723 return GNUNET_SYSERR;
724 }
725 if (GNUNET_YES == state->is_dns)
726 {
727 GNUNET_break_op (0);
728 return GNUNET_SYSERR;
729 }
730 if (NULL == state->specifics.tcp_udp.serv)
731 {
732 GNUNET_break_op (0);
733 return GNUNET_SYSERR;
734 }
735 if (NULL != state->specifics.tcp_udp.heap_node)
736 {
737 GNUNET_break_op (0);
738 return GNUNET_SYSERR;
739 }
740 if (start->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
741 {
742 GNUNET_break_op (0);
743 return GNUNET_SYSERR;
744 }
745 return GNUNET_OK;
746}
747
748
767static void
768prepare_ipv4_packet (const void *payload,
769 size_t payload_length,
770 int protocol,
771 const struct GNUNET_TUN_TcpHeader *tcp_header,
772 const struct SocketAddress *src_address,
773 const struct SocketAddress *dst_address,
774 struct GNUNET_TUN_IPv4Header *pkt4)
775{
776 size_t len;
777
778 len = payload_length;
779 switch (protocol)
780 {
781 case IPPROTO_UDP:
782 len += sizeof(struct GNUNET_TUN_UdpHeader);
783 break;
784
785 case IPPROTO_TCP:
786 len += sizeof(struct GNUNET_TUN_TcpHeader);
787 GNUNET_assert (NULL != tcp_header);
788 break;
789
790 default:
791 GNUNET_break (0);
792 return;
793 }
794 if (len + sizeof(struct GNUNET_TUN_IPv4Header) > UINT16_MAX)
795 {
796 GNUNET_break (0);
797 return;
798 }
799
801 protocol,
802 len,
803 &src_address->address.ipv4,
804 &dst_address->address.ipv4);
805 switch (protocol)
806 {
807 case IPPROTO_UDP:
808 {
809 struct GNUNET_TUN_UdpHeader *pkt4_udp = (struct
810 GNUNET_TUN_UdpHeader *) &pkt4[1];
811
812 pkt4_udp->source_port = htons (src_address->port);
813 pkt4_udp->destination_port = htons (dst_address->port);
814 pkt4_udp->len = htons ((uint16_t) payload_length);
816 pkt4_udp,
817 payload,
818 payload_length);
819 GNUNET_memcpy (&pkt4_udp[1],
820 payload,
821 payload_length);
822 }
823 break;
824
825 case IPPROTO_TCP:
826 {
827 struct GNUNET_TUN_TcpHeader *pkt4_tcp = (struct
829
830 *pkt4_tcp = *tcp_header;
832 "Sending TCP packet from port %u to port %u\n",
833 src_address->port,
834 dst_address->port);
835 pkt4_tcp->source_port = htons (src_address->port);
836 pkt4_tcp->destination_port = htons (dst_address->port);
838 pkt4_tcp,
839 payload,
840 payload_length);
842 payload,
843 payload_length);
844 }
845 break;
846
847 default:
848 GNUNET_assert (0);
849 }
850}
851
852
871static void
872prepare_ipv6_packet (const void *payload,
873 size_t payload_length,
874 int protocol,
875 const struct GNUNET_TUN_TcpHeader *tcp_header,
876 const struct SocketAddress *src_address,
877 const struct SocketAddress *dst_address,
879{
880 size_t len;
881
882 len = payload_length;
883 switch (protocol)
884 {
885 case IPPROTO_UDP:
886 len += sizeof(struct GNUNET_TUN_UdpHeader);
887 break;
888
889 case IPPROTO_TCP:
890 len += sizeof(struct GNUNET_TUN_TcpHeader);
891 break;
892
893 default:
894 GNUNET_break (0);
895 return;
896 }
897 if (len > UINT16_MAX)
898 {
899 GNUNET_break (0);
900 return;
901 }
902
904 protocol,
905 len,
906 &src_address->address.ipv6,
907 &dst_address->address.ipv6);
908
909 switch (protocol)
910 {
911 case IPPROTO_UDP:
912 {
913 struct GNUNET_TUN_UdpHeader *pkt6_udp = (struct
914 GNUNET_TUN_UdpHeader *) &pkt6[1];
915
916 pkt6_udp->source_port = htons (src_address->port);
917 pkt6_udp->destination_port = htons (dst_address->port);
918 pkt6_udp->len = htons ((uint16_t) payload_length);
920 pkt6_udp,
921 payload,
922 payload_length);
923 GNUNET_memcpy (&pkt6_udp[1],
924 payload,
925 payload_length);
926 }
927 break;
928
929 case IPPROTO_TCP:
930 {
931 struct GNUNET_TUN_TcpHeader *pkt6_tcp = (struct
933
934 /* GNUNET_memcpy first here as some TCP header fields are initialized this way! */
935 *pkt6_tcp = *tcp_header;
937 pkt6_tcp->destination_port = htons (dst_address->port);
939 pkt6_tcp,
940 payload,
941 payload_length);
943 payload,
944 payload_length);
945 }
946 break;
947
948 default:
949 GNUNET_assert (0);
950 break;
951 }
952}
953
954
964static void
965send_tcp_packet_via_tun (const struct SocketAddress *destination_address,
966 const struct SocketAddress *source_address,
967 const struct GNUNET_TUN_TcpHeader *tcp_header,
968 const void *payload,
969 size_t payload_length)
970{
971 size_t len;
972
974 gettext_noop ("# TCP packets sent via TUN"),
975 1,
976 GNUNET_NO);
978 "Sending packet with %u bytes TCP payload via TUN\n",
979 (unsigned int) payload_length);
980 len = sizeof(struct GNUNET_MessageHeader) + sizeof(struct
982 switch (source_address->af)
983 {
984 case AF_INET:
985 len += sizeof(struct GNUNET_TUN_IPv4Header);
986 break;
987
988 case AF_INET6:
989 len += sizeof(struct GNUNET_TUN_IPv6Header);
990 break;
991
992 default:
993 GNUNET_break (0);
994 return;
995 }
996 len += sizeof(struct GNUNET_TUN_TcpHeader);
997 len += payload_length;
998 if (len >= GNUNET_MAX_MESSAGE_SIZE)
999 {
1000 GNUNET_break (0);
1001 return;
1002 }
1003 {
1004 char buf[len] GNUNET_ALIGN;
1005 struct GNUNET_MessageHeader *hdr;
1007
1008 hdr = (struct GNUNET_MessageHeader *) buf;
1009 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1010 hdr->size = htons (len);
1011 tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
1012 tun->flags = htons (0);
1013 switch (source_address->af)
1014 {
1015 case AF_INET:
1016 {
1018 = (struct GNUNET_TUN_IPv4Header*) &tun[1];
1019
1020 tun->proto = htons (ETH_P_IPV4);
1022 payload_length,
1023 IPPROTO_TCP,
1024 tcp_header,
1027 ipv4);
1028 }
1029 break;
1030
1031 case AF_INET6:
1032 {
1034 = (struct GNUNET_TUN_IPv6Header*) &tun[1];
1035
1036 tun->proto = htons (ETH_P_IPV6);
1039 IPPROTO_TCP,
1040 tcp_header,
1043 ipv6);
1044 }
1045 break;
1046
1047 default:
1048 GNUNET_assert (0);
1049 break;
1050 }
1051 if (NULL != helper_handle)
1053 (const struct GNUNET_MessageHeader*) buf,
1054 GNUNET_YES,
1055 NULL,
1056 NULL);
1057 }
1058}
1059
1060
1070static void
1072 const struct SocketAddress *source_address,
1073 const struct GNUNET_TUN_IcmpHeader *icmp_header,
1074 const void *payload, size_t payload_length)
1075{
1076 size_t len;
1077 struct GNUNET_TUN_IcmpHeader *icmp;
1078
1080 gettext_noop ("# ICMP packets sent via TUN"),
1081 1, GNUNET_NO);
1083 "Sending packet with %u bytes ICMP payload via TUN\n",
1084 (unsigned int) payload_length);
1085 len = sizeof(struct GNUNET_MessageHeader) + sizeof(struct
1087 switch (destination_address->af)
1088 {
1089 case AF_INET:
1090 len += sizeof(struct GNUNET_TUN_IPv4Header);
1091 break;
1092
1093 case AF_INET6:
1094 len += sizeof(struct GNUNET_TUN_IPv6Header);
1095 break;
1096
1097 default:
1098 GNUNET_break (0);
1099 return;
1100 }
1101 len += sizeof(struct GNUNET_TUN_IcmpHeader);
1102 len += payload_length;
1103 if (len >= GNUNET_MAX_MESSAGE_SIZE)
1104 {
1105 GNUNET_break (0);
1106 return;
1107 }
1108 {
1109 char buf[len] GNUNET_ALIGN;
1110 struct GNUNET_MessageHeader *hdr;
1112
1113 hdr = (struct GNUNET_MessageHeader *) buf;
1114 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1115 hdr->size = htons (len);
1116 tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
1117 tun->flags = htons (0);
1118 switch (source_address->af)
1119 {
1120 case AF_INET:
1121 {
1122 struct GNUNET_TUN_IPv4Header *ipv4 = (struct
1123 GNUNET_TUN_IPv4Header*) &tun[1];
1124
1125 tun->proto = htons (ETH_P_IPV4);
1127 IPPROTO_ICMP,
1128 sizeof(struct
1130 + payload_length,
1131 &source_address->address.ipv4,
1132 &destination_address->address.ipv4);
1133 icmp = (struct GNUNET_TUN_IcmpHeader*) &ipv4[1];
1134 }
1135 break;
1136
1137 case AF_INET6:
1138 {
1139 struct GNUNET_TUN_IPv6Header *ipv6 = (struct
1140 GNUNET_TUN_IPv6Header*) &tun[1];
1141
1142 tun->proto = htons (ETH_P_IPV6);
1144 IPPROTO_ICMPV6,
1145 sizeof(struct
1148 &source_address->address.ipv6,
1149 &destination_address->address.ipv6);
1150 icmp = (struct GNUNET_TUN_IcmpHeader*) &ipv6[1];
1151 }
1152 break;
1153
1154 default:
1155 GNUNET_assert (0);
1156 break;
1157 }
1158 *icmp = *icmp_header;
1159 GNUNET_memcpy (&icmp[1],
1160 payload,
1161 payload_length);
1163 payload,
1164 payload_length);
1165 if (NULL != helper_handle)
1167 (const struct GNUNET_MessageHeader*) buf,
1168 GNUNET_YES,
1169 NULL, NULL);
1170 }
1171}
1172
1173
1182static void
1183setup_fresh_address (int af,
1184 uint8_t proto,
1185 struct SocketAddress *local_address)
1186{
1187 local_address->af = af;
1188 local_address->proto = (uint8_t) proto;
1189 /* default "local" port range is often 32768--61000,
1190 so we pick a random value in that range */
1191 if (((af == AF_INET) && (proto == IPPROTO_ICMP)) ||
1192 ((af == AF_INET6) && (proto == IPPROTO_ICMPV6)))
1193 local_address->port = 0;
1194 else
1195 local_address->port
1197 28232);
1198 switch (af)
1199 {
1200 case AF_INET:
1201 {
1202 struct in_addr addr;
1203 struct in_addr mask;
1204 struct in_addr rnd;
1205
1206 addr = exit_ipv4addr;
1207 mask = exit_ipv4mask;
1208 if (0 == ~mask.s_addr)
1209 {
1210 /* only one valid IP anyway */
1211 local_address->address.ipv4 = addr;
1212 return;
1213 }
1214 /* Given 192.168.0.1/255.255.0.0, we want a mask
1215 of '192.168.255.255', thus: */
1216 mask.s_addr = addr.s_addr | ~mask.s_addr;
1217 /* Pick random IPv4 address within the subnet, except 'addr' or 'mask' itself */
1218 do
1219 {
1221 UINT32_MAX);
1222 local_address->address.ipv4.s_addr = (addr.s_addr | rnd.s_addr)
1223 & mask.s_addr;
1224 }
1225 while ((local_address->address.ipv4.s_addr == addr.s_addr) ||
1226 (local_address->address.ipv4.s_addr == mask.s_addr));
1227 }
1228 break;
1229
1230 case AF_INET6:
1231 {
1232 struct in6_addr addr;
1233 struct in6_addr mask;
1234 struct in6_addr rnd;
1235 int i;
1236
1237 addr = exit_ipv6addr;
1238 GNUNET_assert (ipv6prefix < 128);
1239 if (ipv6prefix == 127)
1240 {
1241 /* only one valid IP anyway */
1242 local_address->address.ipv6 = addr;
1243 return;
1244 }
1245 /* Given ABCD::/96, we want a mask of 'ABCD::FFFF:FFFF,
1246 thus: */
1247 mask = addr;
1248 for (i = 127; i >= ipv6prefix; i--)
1249 mask.s6_addr[i / 8] |= (1 << (i % 8));
1250
1251 /* Pick random IPv6 address within the subnet, except 'addr' or 'mask' itself */
1252 do
1253 {
1254 for (i = 0; i < 16; i++)
1255 {
1256 rnd.s6_addr[i] = (unsigned char) GNUNET_CRYPTO_random_u32 (
1258 256);
1259 local_address->address.ipv6.s6_addr[i]
1260 = (addr.s6_addr[i] | rnd.s6_addr[i]) & mask.s6_addr[i];
1261 }
1262 }
1263 while ((0 == GNUNET_memcmp (&local_address->address.ipv6,
1264 &addr)) ||
1265 (0 == GNUNET_memcmp (&local_address->address.ipv6,
1266 &mask)));
1267 }
1268 break;
1269
1270 default:
1271 GNUNET_assert (0);
1272 }
1273}
1274
1275
1297static void
1299{
1300 struct GNUNET_HashCode key;
1301 struct ChannelState *s;
1302
1303 /* generate fresh, unique address */
1304 do
1305 {
1306 if (NULL == state->specifics.tcp_udp.serv)
1307 setup_fresh_address (state->specifics.tcp_udp.ri.remote_address.af,
1308 state->specifics.tcp_udp.ri.remote_address.proto,
1309 &state->specifics.tcp_udp.ri.local_address);
1310 else
1311 setup_fresh_address (state->specifics.tcp_udp.serv->address.af,
1312 state->specifics.tcp_udp.serv->address.proto,
1313 &state->specifics.tcp_udp.ri.local_address);
1314 }
1315 while (NULL !=
1316 get_redirect_state (state->specifics.tcp_udp.ri.remote_address.af,
1317 state->specifics.tcp_udp.ri.remote_address.proto,
1318 &state->specifics.tcp_udp.ri.remote_address.address
1319 ,
1320 state->specifics.tcp_udp.ri.remote_address.port,
1321 &state->specifics.tcp_udp.ri.local_address.address,
1322 state->specifics.tcp_udp.ri.local_address.port,
1323 &key));
1324 {
1325 char buf[INET6_ADDRSTRLEN];
1327 "Picked local address %s:%u for new connection\n",
1328 inet_ntop (state->specifics.tcp_udp.ri.local_address.af,
1329 &state->specifics.tcp_udp.ri.local_address.address,
1330 buf,
1331 sizeof(buf)),
1332 (unsigned int) state->specifics.tcp_udp.ri.local_address.port);
1333 }
1334 state->specifics.tcp_udp.state_key = key;
1337 &key, state,
1339 state->specifics.tcp_udp.heap_node
1341 state,
1342 GNUNET_TIME_absolute_get ().abs_value_us);
1344 {
1346 GNUNET_assert (state != s);
1347 s->specifics.tcp_udp.heap_node = NULL;
1351 &s->specifics.tcp_udp.
1352 state_key,
1353 s));
1354 GNUNET_free (s);
1355 }
1356}
1357
1358
1367static void
1368send_udp_packet_via_tun (const struct SocketAddress *destination_address,
1369 const struct SocketAddress *source_address,
1370 const void *payload, size_t payload_length)
1371{
1372 size_t len;
1373
1375 gettext_noop ("# UDP packets sent via TUN"),
1376 1, GNUNET_NO);
1378 "Sending packet with %u bytes UDP payload via TUN\n",
1379 (unsigned int) payload_length);
1380 len = sizeof(struct GNUNET_MessageHeader) + sizeof(struct
1382 switch (source_address->af)
1383 {
1384 case AF_INET:
1385 len += sizeof(struct GNUNET_TUN_IPv4Header);
1386 break;
1387
1388 case AF_INET6:
1389 len += sizeof(struct GNUNET_TUN_IPv6Header);
1390 break;
1391
1392 default:
1393 GNUNET_break (0);
1394 return;
1395 }
1396 len += sizeof(struct GNUNET_TUN_UdpHeader);
1397 len += payload_length;
1399 {
1400 GNUNET_break (0);
1401 return;
1402 }
1403 {
1404 char buf[len] GNUNET_ALIGN;
1405 struct GNUNET_MessageHeader *hdr;
1407
1408 hdr = (struct GNUNET_MessageHeader *) buf;
1409 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1410 hdr->size = htons (len);
1411 tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
1412 tun->flags = htons (0);
1413 switch (source_address->af)
1414 {
1415 case AF_INET:
1416 {
1417 struct GNUNET_TUN_IPv4Header *ipv4 = (struct
1418 GNUNET_TUN_IPv4Header*) &tun[1];
1419
1420 tun->proto = htons (ETH_P_IPV4);
1422 payload_length,
1423 IPPROTO_UDP,
1424 NULL,
1427 ipv4);
1428 }
1429 break;
1430
1431 case AF_INET6:
1432 {
1433 struct GNUNET_TUN_IPv6Header *ipv6 = (struct
1434 GNUNET_TUN_IPv6Header*) &tun[1];
1435
1436 tun->proto = htons (ETH_P_IPV6);
1439 IPPROTO_UDP,
1440 NULL,
1443 ipv6);
1444 }
1445 break;
1446
1447 default:
1448 GNUNET_assert (0);
1449 break;
1450 }
1451 if (NULL != helper_handle)
1453 (const struct GNUNET_MessageHeader*) buf,
1454 GNUNET_YES,
1455 NULL, NULL);
1456 }
1457}
1458
1459
1468static int
1469check_udp_remote (void *cls,
1470 const struct GNUNET_EXIT_UdpInternetMessage *msg)
1471{
1472 struct ChannelState *state = cls;
1473
1474 if (GNUNET_YES == state->is_dns)
1475 {
1476 GNUNET_break_op (0);
1477 return GNUNET_SYSERR;
1478 }
1479 return GNUNET_OK;
1480}
1481
1482
1489static void
1490handle_udp_remote (void *cls,
1491 const struct GNUNET_EXIT_UdpInternetMessage *msg)
1492{
1493 struct ChannelState *state = cls;
1494 uint16_t pkt_len = ntohs (msg->header.size) - sizeof(struct
1496 const struct in_addr *v4;
1497 const struct in6_addr *v6;
1498 const void *payload;
1499 int af;
1500
1501 if (GNUNET_SYSERR == state->is_dns)
1502 {
1503 /* channel is UDP/TCP from now on */
1505 }
1507 gettext_noop ("# Bytes received from CADET"),
1508 pkt_len, GNUNET_NO);
1510 gettext_noop (
1511 "# UDP IP-exit requests received via cadet"),
1512 1, GNUNET_NO);
1513 af = (int) ntohl (msg->af);
1514 state->specifics.tcp_udp.ri.remote_address.af = af;
1515 switch (af)
1516 {
1517 case AF_INET:
1518 if (pkt_len < sizeof(struct in_addr))
1519 {
1520 GNUNET_break_op (0);
1521 return;
1522 }
1523 if (! ipv4_exit)
1524 {
1525 GNUNET_break_op (0);
1526 return;
1527 }
1528 v4 = (const struct in_addr*) &msg[1];
1529 payload = &v4[1];
1530 pkt_len -= sizeof(struct in_addr);
1531 state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
1532 break;
1533
1534 case AF_INET6:
1535 if (pkt_len < sizeof(struct in6_addr))
1536 {
1537 GNUNET_break_op (0);
1538 return;
1539 }
1540 if (! ipv6_exit)
1541 {
1542 GNUNET_break_op (0);
1543 return;
1544 }
1545 v6 = (const struct in6_addr*) &msg[1];
1546 payload = &v6[1];
1547 pkt_len -= sizeof(struct in6_addr);
1548 state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
1549 break;
1550
1551 default:
1552 GNUNET_break_op (0);
1553 return;
1554 }
1555 {
1556 char buf[INET6_ADDRSTRLEN];
1558 "Received data from %s for forwarding to UDP %s:%u\n",
1559 GNUNET_i2s (&state->peer),
1560 inet_ntop (af,
1561 &state->specifics.tcp_udp.ri.remote_address.address,
1562 buf, sizeof(buf)),
1563 (unsigned int) ntohs (msg->destination_port));
1564 }
1565 state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_UDP;
1566 state->specifics.tcp_udp.ri.remote_address.port = msg->destination_port;
1567 if (NULL == state->specifics.tcp_udp.heap_node)
1569 if (0 != ntohs (msg->source_port))
1570 state->specifics.tcp_udp.ri.local_address.port = msg->source_port;
1571 send_udp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1572 &state->specifics.tcp_udp.ri.local_address,
1573 payload,
1574 pkt_len);
1576}
1577
1578
1588static int
1589check_udp_service (void *cls,
1590 const struct GNUNET_EXIT_UdpServiceMessage *msg)
1591{
1592 struct ChannelState *state = cls;
1593
1594 if (NULL == state->specifics.tcp_udp.serv)
1595 {
1596 GNUNET_break_op (0);
1597 return GNUNET_SYSERR;
1598 }
1599 return GNUNET_OK;
1600}
1601
1602
1610static void
1611handle_udp_service (void *cls,
1612 const struct GNUNET_EXIT_UdpServiceMessage *msg)
1613{
1614 struct ChannelState *state = cls;
1615 uint16_t pkt_len = ntohs (msg->header.size) - sizeof(struct
1617
1619 gettext_noop ("# Bytes received from CADET"),
1620 pkt_len, GNUNET_NO);
1622 gettext_noop (
1623 "# UDP service requests received via cadet"),
1624 1, GNUNET_NO);
1626 "Received data from %s for forwarding to UDP service %s on port %u\n",
1627 GNUNET_i2s (&state->peer),
1628 GNUNET_h2s (&state->specifics.tcp_udp.serv->descriptor),
1629 (unsigned int) ntohs (msg->destination_port));
1631 if (0 != ntohs (msg->source_port))
1632 state->specifics.tcp_udp.ri.local_address.port = msg->source_port;
1633 send_udp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1634 &state->specifics.tcp_udp.ri.local_address,
1635 &msg[1],
1636 pkt_len);
1638}
1639
1640
1650static void
1651handle_tcp_service (void *cls,
1653{
1654 struct ChannelState *state = cls;
1655 uint16_t pkt_len = ntohs (start->header.size) - sizeof(struct
1657
1658 if (GNUNET_SYSERR == state->is_dns)
1659 {
1660 /* channel is UDP/TCP from now on */
1662 }
1664 gettext_noop (
1665 "# TCP service creation requests received via cadet"),
1666 1,
1667 GNUNET_NO);
1669 gettext_noop ("# Bytes received from CADET"),
1670 pkt_len,
1671 GNUNET_NO);
1672 GNUNET_break_op (ntohl (start->reserved) == 0);
1673 /* setup fresh connection */
1675 "Received data from %s for forwarding to TCP service %s on port %u\n",
1676 GNUNET_i2s (&state->peer),
1677 GNUNET_h2s (&state->specifics.tcp_udp.serv->descriptor),
1678 (unsigned int) ntohs (start->tcp_header.destination_port));
1680 send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1681 &state->specifics.tcp_udp.ri.local_address,
1682 &start->tcp_header,
1683 &start[1],
1684 pkt_len);
1686}
1687
1688
1697static int
1698check_tcp_remote (void *cls,
1700{
1701 struct ChannelState *state = cls;
1702
1703 if (NULL == state)
1704 {
1705 GNUNET_break_op (0);
1706 return GNUNET_SYSERR;
1707 }
1708 if (GNUNET_YES == state->is_dns)
1709 {
1710 GNUNET_break_op (0);
1711 return GNUNET_SYSERR;
1712 }
1713 if ((NULL != state->specifics.tcp_udp.serv) ||
1714 (NULL != state->specifics.tcp_udp.heap_node))
1715 {
1716 GNUNET_break_op (0);
1717 return GNUNET_SYSERR;
1718 }
1719 if (start->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
1720 {
1721 GNUNET_break_op (0);
1722 return GNUNET_SYSERR;
1723 }
1724 return GNUNET_OK;
1725}
1726
1727
1734static void
1735handle_tcp_remote (void *cls,
1737{
1738 struct ChannelState *state = cls;
1739 uint16_t pkt_len = ntohs (start->header.size) - sizeof(struct
1741 const struct in_addr *v4;
1742 const struct in6_addr *v6;
1743 const void *payload;
1744 int af;
1745
1746 if (GNUNET_SYSERR == state->is_dns)
1747 {
1748 /* channel is UDP/TCP from now on */
1750 }
1752 gettext_noop ("# Bytes received from CADET"),
1753 pkt_len, GNUNET_NO);
1755 gettext_noop (
1756 "# TCP IP-exit creation requests received via cadet"),
1757 1, GNUNET_NO);
1758 af = (int) ntohl (start->af);
1759 state->specifics.tcp_udp.ri.remote_address.af = af;
1760 switch (af)
1761 {
1762 case AF_INET:
1763 if (pkt_len < sizeof(struct in_addr))
1764 {
1765 GNUNET_break_op (0);
1766 return;
1767 }
1768 if (! ipv4_exit)
1769 {
1770 GNUNET_break_op (0);
1771 return;
1772 }
1773 v4 = (const struct in_addr*) &start[1];
1774 payload = &v4[1];
1775 pkt_len -= sizeof(struct in_addr);
1776 state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
1777 break;
1778
1779 case AF_INET6:
1780 if (pkt_len < sizeof(struct in6_addr))
1781 {
1782 GNUNET_break_op (0);
1783 return;
1784 }
1785 if (! ipv6_exit)
1786 {
1787 GNUNET_break_op (0);
1788 return;
1789 }
1790 v6 = (const struct in6_addr*) &start[1];
1791 payload = &v6[1];
1792 pkt_len -= sizeof(struct in6_addr);
1793 state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
1794 break;
1795
1796 default:
1797 GNUNET_break_op (0);
1798 return;
1799 }
1800 {
1801 char buf[INET6_ADDRSTRLEN];
1803 "Received payload from %s for existing TCP stream to %s:%u\n",
1804 GNUNET_i2s (&state->peer),
1805 inet_ntop (af,
1806 &state->specifics.tcp_udp.ri.remote_address.address,
1807 buf, sizeof(buf)),
1808 (unsigned int) ntohs (start->tcp_header.destination_port));
1809 }
1810 state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_TCP;
1811 state->specifics.tcp_udp.ri.remote_address.port = ntohs (
1812 start->tcp_header.destination_port);
1814 send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1815 &state->specifics.tcp_udp.ri.local_address,
1816 &start->tcp_header,
1817 payload,
1818 pkt_len);
1820}
1821
1822
1832static int
1833check_tcp_data (void *cls,
1834 const struct GNUNET_EXIT_TcpDataMessage *data)
1835{
1836 struct ChannelState *state = cls;
1837
1838 if ((NULL == state) ||
1839 (NULL == state->specifics.tcp_udp.heap_node))
1840 {
1841 /* connection should have been up! */
1843 gettext_noop (
1844 "# TCP DATA requests dropped (no session)"),
1845 1, GNUNET_NO);
1846 GNUNET_break_op (0);
1847 return GNUNET_SYSERR;
1848 }
1849 if (data->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
1850 {
1851 GNUNET_break_op (0);
1852 return GNUNET_SYSERR;
1853 }
1854 if (GNUNET_YES == state->is_dns)
1855 {
1856 GNUNET_break_op (0);
1857 return GNUNET_SYSERR;
1858 }
1859 return GNUNET_OK;
1860}
1861
1862
1870static void
1871handle_tcp_data (void *cls,
1872 const struct GNUNET_EXIT_TcpDataMessage *data)
1873{
1874 struct ChannelState *state = cls;
1875 uint16_t pkt_len = ntohs (data->header.size) - sizeof(struct
1877
1879 gettext_noop ("# Bytes received from CADET"),
1880 pkt_len, GNUNET_NO);
1882 gettext_noop (
1883 "# TCP data requests received via cadet"),
1884 1, GNUNET_NO);
1885 if (GNUNET_SYSERR == state->is_dns)
1886 {
1887 /* channel is UDP/TCP from now on */
1888 state->is_dns = GNUNET_NO;
1889 }
1890
1891 GNUNET_break_op (ntohl (data->reserved) == 0);
1892 {
1893 char buf[INET6_ADDRSTRLEN];
1895 "Received additional %u bytes of data from %s for TCP stream to %s:%u\n",
1896 pkt_len,
1897 GNUNET_i2s (&state->peer),
1898 inet_ntop (state->specifics.tcp_udp.ri.remote_address.af,
1899 &state->specifics.tcp_udp.ri.remote_address.address,
1900 buf, sizeof(buf)),
1901 (unsigned int) state->specifics.tcp_udp.ri.remote_address.port);
1902 }
1903
1904 send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1905 &state->specifics.tcp_udp.ri.local_address,
1906 &data->tcp_header,
1907 &data[1], pkt_len);
1909}
1910
1911
1921static void
1923 struct GNUNET_TUN_IPv4Header *ipp,
1924 struct GNUNET_TUN_UdpHeader *udp)
1925{
1927 state->specifics.tcp_udp.ri.remote_address.
1928 proto,
1929 sizeof(struct GNUNET_TUN_TcpHeader),
1930 &state->specifics.tcp_udp.ri.remote_address
1931 .address.ipv4,
1932 &state->specifics.tcp_udp.ri.local_address.
1933 address.ipv4);
1934 udp->source_port = htons (state->specifics.tcp_udp.ri.remote_address.port);
1935 udp->destination_port = htons (
1936 state->specifics.tcp_udp.ri.local_address.port);
1937 udp->len = htons (0);
1938 udp->crc = htons (0);
1939}
1940
1941
1951static void
1953 struct GNUNET_TUN_IPv6Header *ipp,
1954 struct GNUNET_TUN_UdpHeader *udp)
1955{
1957 state->specifics.tcp_udp.ri.remote_address.
1958 proto,
1959 sizeof(struct GNUNET_TUN_TcpHeader),
1960 &state->specifics.tcp_udp.ri.remote_address
1961 .address.ipv6,
1962 &state->specifics.tcp_udp.ri.local_address.
1963 address.ipv6);
1964 udp->source_port = htons (state->specifics.tcp_udp.ri.remote_address.port);
1965 udp->destination_port = htons (
1966 state->specifics.tcp_udp.ri.local_address.port);
1967 udp->len = htons (0);
1968 udp->crc = htons (0);
1969}
1970
1971
1980static int
1981check_icmp_remote (void *cls,
1983{
1984 struct ChannelState *state = cls;
1985
1986 if (GNUNET_YES == state->is_dns)
1987 {
1988 GNUNET_break_op (0);
1989 return GNUNET_SYSERR;
1990 }
1991 return GNUNET_OK;
1992}
1993
1994
2001static void
2002handle_icmp_remote (void *cls,
2004{
2005 struct ChannelState *state = cls;
2006 uint16_t pkt_len = ntohs (msg->header.size) - sizeof(struct
2008 const struct in_addr *v4;
2009 const struct in6_addr *v6;
2010 const void *payload;
2011 char buf[sizeof(struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
2012 int af;
2013
2014 if (GNUNET_SYSERR == state->is_dns)
2015 {
2016 /* channel is UDP/TCP from now on */
2018 }
2020 gettext_noop ("# Bytes received from CADET"),
2021 pkt_len, GNUNET_NO);
2023 gettext_noop (
2024 "# ICMP IP-exit requests received via cadet"),
2025 1, GNUNET_NO);
2026
2027 af = (int) ntohl (msg->af);
2028 if ((NULL != state->specifics.tcp_udp.heap_node) &&
2029 (af != state->specifics.tcp_udp.ri.remote_address.af))
2030 {
2031 /* other peer switched AF on this channel; not allowed */
2032 GNUNET_break_op (0);
2033 return;
2034 }
2035
2036 switch (af)
2037 {
2038 case AF_INET:
2039 if (pkt_len < sizeof(struct in_addr))
2040 {
2041 GNUNET_break_op (0);
2042 return;
2043 }
2044 if (! ipv4_exit)
2045 {
2046 GNUNET_break_op (0);
2047 return;
2048 }
2049 v4 = (const struct in_addr*) &msg[1];
2050 payload = &v4[1];
2051 pkt_len -= sizeof(struct in_addr);
2052 state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
2053 if (NULL == state->specifics.tcp_udp.heap_node)
2054 {
2055 state->specifics.tcp_udp.ri.remote_address.af = af;
2056 state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_ICMP;
2058 }
2059 /* check that ICMP type is something we want to support
2060 and possibly make up payload! */
2061 switch (msg->icmp_header.type)
2062 {
2065 break;
2066
2070 if (0 != pkt_len)
2071 {
2072 GNUNET_break_op (0);
2073 return;
2074 }
2075 /* make up payload */
2076 {
2077 struct GNUNET_TUN_IPv4Header *ipp = (struct
2078 GNUNET_TUN_IPv4Header *) buf;
2079 struct GNUNET_TUN_UdpHeader *udp = (struct
2080 GNUNET_TUN_UdpHeader *) &ipp[1];
2081
2082 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
2083 pkt_len = sizeof(struct GNUNET_TUN_IPv4Header) + 8;
2085 ipp,
2086 udp);
2087 payload = ipp;
2088 }
2089 break;
2090
2091 default:
2092 GNUNET_break_op (0);
2094 gettext_noop (
2095 "# ICMPv4 packets dropped (type not allowed)")
2096 ,
2097 1, GNUNET_NO);
2098 return;
2099 }
2100 /* end AF_INET */
2101 break;
2102
2103 case AF_INET6:
2104 if (pkt_len < sizeof(struct in6_addr))
2105 {
2106 GNUNET_break_op (0);
2107 return;
2108 }
2109 if (! ipv6_exit)
2110 {
2111 GNUNET_break_op (0);
2112 return;
2113 }
2114 v6 = (const struct in6_addr*) &msg[1];
2115 payload = &v6[1];
2116 pkt_len -= sizeof(struct in6_addr);
2117 state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
2118 if (NULL == state->specifics.tcp_udp.heap_node)
2119 {
2120 state->specifics.tcp_udp.ri.remote_address.af = af;
2121 state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_ICMPV6;
2123 }
2124 /* check that ICMP type is something we want to support
2125 and possibly make up payload! */
2126 switch (msg->icmp_header.type)
2127 {
2130 break;
2131
2136 if (0 != pkt_len)
2137 {
2138 GNUNET_break_op (0);
2139 return;
2140 }
2141 /* make up payload */
2142 {
2143 struct GNUNET_TUN_IPv6Header *ipp = (struct
2144 GNUNET_TUN_IPv6Header *) buf;
2145 struct GNUNET_TUN_UdpHeader *udp = (struct
2146 GNUNET_TUN_UdpHeader *) &ipp[1];
2147
2148 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
2149 pkt_len = sizeof(struct GNUNET_TUN_IPv6Header) + 8;
2151 ipp,
2152 udp);
2153 payload = ipp;
2154 }
2155 break;
2156
2157 default:
2158 GNUNET_break_op (0);
2160 gettext_noop (
2161 "# ICMPv6 packets dropped (type not allowed)")
2162 ,
2163 1, GNUNET_NO);
2164 return;
2165 }
2166 /* end AF_INET6 */
2167 break;
2168
2169 default:
2170 /* bad AF */
2171 GNUNET_break_op (0);
2172 return;
2173 }
2174
2175 {
2176 char buf_tmp[INET6_ADDRSTRLEN];
2178 "Received ICMP data from %s for forwarding to %s\n",
2179 GNUNET_i2s (&state->peer),
2180 inet_ntop (af,
2181 &state->specifics.tcp_udp.ri.remote_address.address,
2182 buf_tmp, sizeof(buf_tmp)));
2183 }
2184 send_icmp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
2185 &state->specifics.tcp_udp.ri.local_address,
2186 &msg->icmp_header,
2187 payload, pkt_len);
2189}
2190
2191
2201static uint16_t
2203 char *buf)
2204{
2205 switch (state->specifics.tcp_udp.serv->address.af)
2206 {
2207 case AF_INET:
2208 {
2210 struct GNUNET_TUN_UdpHeader *udp;
2211
2212 ipv4 = (struct GNUNET_TUN_IPv4Header *) buf;
2213 udp = (struct GNUNET_TUN_UdpHeader *) &ipv4[1];
2215 ipv4,
2216 udp);
2217 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
2218 return sizeof(struct GNUNET_TUN_IPv4Header) + 8;
2219 }
2220 break;
2221
2222 case AF_INET6:
2223 {
2225 struct GNUNET_TUN_UdpHeader *udp;
2226
2227 ipv6 = (struct GNUNET_TUN_IPv6Header *) buf;
2228 udp = (struct GNUNET_TUN_UdpHeader *) &ipv6[1];
2230 ipv6,
2231 udp);
2232 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
2233 return sizeof(struct GNUNET_TUN_IPv6Header) + 8;
2234 }
2235 break;
2236
2237 default:
2238 GNUNET_break (0);
2239 }
2240 return 0;
2241}
2242
2243
2253static int
2254check_icmp_service (void *cls,
2255 const struct GNUNET_EXIT_IcmpServiceMessage *msg)
2256{
2257 struct ChannelState *state = cls;
2258
2259 if (GNUNET_YES == state->is_dns)
2260 {
2261 GNUNET_break_op (0);
2262 return GNUNET_SYSERR;
2263 }
2264 if (NULL == state->specifics.tcp_udp.serv)
2265 {
2266 GNUNET_break_op (0);
2267 return GNUNET_SYSERR;
2268 }
2269 return GNUNET_OK;
2270}
2271
2272
2280static void
2281handle_icmp_service (void *cls,
2282 const struct GNUNET_EXIT_IcmpServiceMessage *msg)
2283{
2284 struct ChannelState *state = cls;
2285 uint16_t pkt_len = ntohs (msg->header.size) - sizeof(struct
2287 struct GNUNET_TUN_IcmpHeader icmp;
2288 char buf[sizeof(struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
2289 const void *payload;
2290
2292 gettext_noop ("# Bytes received from CADET"),
2293 pkt_len, GNUNET_NO);
2295 gettext_noop (
2296 "# ICMP service requests received via cadet"),
2297 1, GNUNET_NO);
2298 /* check that we got at least a valid header */
2300 "Received data from %s for forwarding to ICMP service %s\n",
2301 GNUNET_i2s (&state->peer),
2302 GNUNET_h2s (&state->specifics.tcp_udp.serv->descriptor));
2303 icmp = msg->icmp_header;
2304 payload = &msg[1];
2305 state->specifics.tcp_udp.ri.remote_address
2306 = state->specifics.tcp_udp.serv->address;
2308
2309 /* check that ICMP type is something we want to support,
2310 perform ICMP PT if needed and possibly make up payload */
2311 switch (msg->af)
2312 {
2313 case AF_INET:
2314 switch (msg->icmp_header.type)
2315 {
2317 if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2319 break;
2320
2322 if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2324 break;
2325
2327 if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2329 if (0 != pkt_len)
2330 {
2331 GNUNET_break_op (0);
2332 return;
2333 }
2334 payload = buf;
2335 pkt_len = make_up_icmp_service_payload (state, buf);
2336 break;
2337
2339 if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2341 if (0 != pkt_len)
2342 {
2343 GNUNET_break_op (0);
2344 return;
2345 }
2346 payload = buf;
2347 pkt_len = make_up_icmp_service_payload (state, buf);
2348 break;
2349
2351 if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2352 {
2354 gettext_noop (
2355 "# ICMPv4 packets dropped (impossible PT to v6)"),
2356 1, GNUNET_NO);
2357 return;
2358 }
2359 if (0 != pkt_len)
2360 {
2361 GNUNET_break_op (0);
2362 return;
2363 }
2364 payload = buf;
2365 pkt_len = make_up_icmp_service_payload (state, buf);
2366 break;
2367
2368 default:
2369 GNUNET_break_op (0);
2371 gettext_noop (
2372 "# ICMPv4 packets dropped (type not allowed)")
2373 ,
2374 1, GNUNET_NO);
2375 return;
2376 }
2377 /* end of AF_INET */
2378 break;
2379
2380 case AF_INET6:
2381 switch (msg->icmp_header.type)
2382 {
2384 if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2386 break;
2387
2389 if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2391 break;
2392
2394 if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2396 if (0 != pkt_len)
2397 {
2398 GNUNET_break_op (0);
2399 return;
2400 }
2401 payload = buf;
2402 pkt_len = make_up_icmp_service_payload (state, buf);
2403 break;
2404
2406 if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2408 if (0 != pkt_len)
2409 {
2410 GNUNET_break_op (0);
2411 return;
2412 }
2413 payload = buf;
2414 pkt_len = make_up_icmp_service_payload (state, buf);
2415 break;
2416
2419 if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2420 {
2422 gettext_noop (
2423 "# ICMPv6 packets dropped (impossible PT to v4)"),
2424 1, GNUNET_NO);
2425 return;
2426 }
2427 if (0 != pkt_len)
2428 {
2429 GNUNET_break_op (0);
2430 return;
2431 }
2432 payload = buf;
2433 pkt_len = make_up_icmp_service_payload (state, buf);
2434 break;
2435
2436 default:
2437 GNUNET_break_op (0);
2439 gettext_noop (
2440 "# ICMPv6 packets dropped (type not allowed)")
2441 ,
2442 1, GNUNET_NO);
2443 return;
2444 }
2445 /* end of AF_INET6 */
2446 break;
2447
2448 default:
2449 GNUNET_break_op (0);
2450 return;
2451 }
2452
2453 send_icmp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
2454 &state->specifics.tcp_udp.ri.local_address,
2455 &icmp,
2456 payload,
2457 pkt_len);
2459}
2460
2461
2470static int
2471free_service_record (void *cls,
2472 const struct GNUNET_HashCode *key,
2473 void *value)
2474{
2475 struct LocalService *service = value;
2476
2479 key,
2480 service));
2482 GNUNET_free (service->name);
2484 return GNUNET_OK;
2485}
2486
2487
2496static void *
2497new_service_channel (void *cls,
2498 struct GNUNET_CADET_Channel *channel,
2499 const struct GNUNET_PeerIdentity *initiator)
2500{
2501 struct LocalService *ls = cls;
2502 struct ChannelState *s = GNUNET_new (struct ChannelState);
2503
2504 s->peer = *initiator;
2506 gettext_noop ("# Inbound CADET channels created"),
2507 1,
2508 GNUNET_NO);
2510 "Received inbound channel from `%s'\n",
2511 GNUNET_i2s (initiator));
2512 s->channel = channel;
2513 s->specifics.tcp_udp.serv = ls;
2514 s->specifics.tcp_udp.ri.remote_address = ls->address;
2515 return s;
2516}
2517
2518
2526static void
2527clean_channel (void *cls,
2528 const struct GNUNET_CADET_Channel *channel)
2529{
2530 struct ChannelState *s = cls;
2531
2533 "Channel destroyed\n");
2534 if (GNUNET_SYSERR == s->is_dns)
2535 {
2536 GNUNET_free (s);
2537 return;
2538 }
2539 if (GNUNET_YES == s->is_dns)
2540 {
2541 if (channels[s->specifics.dns.my_id] == s)
2542 channels[s->specifics.dns.my_id] = NULL;
2543 }
2544 else
2545 {
2546 if (NULL != s->specifics.tcp_udp.heap_node)
2547 {
2550 &s->specifics.tcp_udp
2551 .state_key,
2552 s));
2554 s->specifics.tcp_udp.heap_node = NULL;
2555 }
2556 }
2557 GNUNET_free (s);
2558}
2559
2560
2570static void
2571store_service (int proto,
2572 const char *name,
2573 uint16_t destination_port,
2574 struct LocalService *service)
2575{
2577 GNUNET_MQ_hd_var_size (icmp_service,
2580 service),
2581 GNUNET_MQ_hd_var_size (udp_service,
2584 service),
2585 GNUNET_MQ_hd_var_size (tcp_service,
2588 service),
2589 GNUNET_MQ_hd_var_size (tcp_data,
2592 service),
2594 };
2595
2597
2598 service->name = GNUNET_strdup (name);
2600 &service->descriptor);
2602 destination_port,
2603 &cadet_port);
2605 "Opening CADET port %s for SERVICE exit %s on port %u\n",
2607 name,
2608 (unsigned int) destination_port);
2610 &cadet_port,
2612 service,
2613 NULL,
2615 handlers);
2616 service->is_udp = (IPPROTO_UDP == proto);
2617 if (GNUNET_OK !=
2619 &cadet_port,
2620 service,
2622 {
2624 GNUNET_free (service->name);
2627 _ ("Got duplicate service records for `%s:%u'\n"),
2628 name,
2629 (unsigned int) destination_port);
2630 }
2631}
2632
2633
2640static void
2642 struct GNUNET_MQ_Envelope *env)
2643{
2644 GNUNET_assert (NULL != s);
2646 gettext_noop (
2647 "# Messages transmitted via cadet channels"),
2648 1,
2649 GNUNET_NO);
2651 env);
2652}
2653
2654
2666static void
2667icmp_from_helper (const struct GNUNET_TUN_IcmpHeader *icmp,
2668 size_t pktlen,
2669 int af,
2670 const void *destination_ip,
2671 const void *source_ip)
2672{
2673 struct ChannelState *state;
2674 struct GNUNET_MQ_Envelope *env;
2675 struct GNUNET_EXIT_IcmpToVPNMessage *i2v;
2676 const struct GNUNET_TUN_IPv4Header *ipv4;
2677 const struct GNUNET_TUN_IPv6Header *ipv6;
2678 const struct GNUNET_TUN_UdpHeader *udp;
2679 uint16_t source_port;
2680 uint16_t destination_port;
2681 uint8_t protocol;
2682
2683 {
2684 char sbuf[INET6_ADDRSTRLEN];
2685 char dbuf[INET6_ADDRSTRLEN];
2687 "Received ICMP packet going from %s to %s\n",
2688 inet_ntop (af,
2689 source_ip,
2690 sbuf, sizeof(sbuf)),
2691 inet_ntop (af,
2692 destination_ip,
2693 dbuf, sizeof(dbuf)));
2694 }
2695
2696 if (pktlen < sizeof(struct GNUNET_TUN_IcmpHeader))
2697 {
2698 /* blame kernel */
2699 GNUNET_break (0);
2700 return;
2701 }
2702
2703 /* Find out if this is an ICMP packet in response to an existing
2704 TCP/UDP packet and if so, figure out ports / protocol of the
2705 existing session from the IP data in the ICMP payload */
2706 source_port = 0;
2707 destination_port = 0;
2708 switch (af)
2709 {
2710 case AF_INET:
2711 protocol = IPPROTO_ICMP;
2712 switch (icmp->type)
2713 {
2716 break;
2717
2721 if (pktlen <
2722 sizeof(struct GNUNET_TUN_IcmpHeader)
2723 + sizeof(struct GNUNET_TUN_IPv4Header) + 8)
2724 {
2725 /* blame kernel */
2726 GNUNET_break (0);
2727 return;
2728 }
2729 ipv4 = (const struct GNUNET_TUN_IPv4Header *) &icmp[1];
2730 protocol = ipv4->protocol;
2731 /* could be TCP or UDP, but both have the ports in the right
2732 place, so that doesn't matter here */
2733 udp = (const struct GNUNET_TUN_UdpHeader *) &ipv4[1];
2734 /* swap ports, as they are from the original message */
2735 destination_port = ntohs (udp->source_port);
2736 source_port = ntohs (udp->destination_port);
2737 /* throw away ICMP payload, won't be useful for the other side anyway */
2738 pktlen = sizeof(struct GNUNET_TUN_IcmpHeader);
2739 break;
2740
2741 default:
2743 gettext_noop (
2744 "# ICMPv4 packets dropped (type not allowed)")
2745 ,
2746 1, GNUNET_NO);
2747 return;
2748 }
2749 break;
2750
2751 case AF_INET6:
2752 protocol = IPPROTO_ICMPV6;
2753 switch (icmp->type)
2754 {
2759 if (pktlen <
2760 sizeof(struct GNUNET_TUN_IcmpHeader)
2761 + sizeof(struct GNUNET_TUN_IPv6Header) + 8)
2762 {
2763 /* blame kernel */
2764 GNUNET_break (0);
2765 return;
2766 }
2767 ipv6 = (const struct GNUNET_TUN_IPv6Header *) &icmp[1];
2768 protocol = ipv6->next_header;
2769 /* could be TCP or UDP, but both have the ports in the right
2770 place, so that doesn't matter here */
2771 udp = (const struct GNUNET_TUN_UdpHeader *) &ipv6[1];
2772 /* swap ports, as they are from the original message */
2773 destination_port = ntohs (udp->source_port);
2774 source_port = ntohs (udp->destination_port);
2775 /* throw away ICMP payload, won't be useful for the other side anyway */
2776 pktlen = sizeof(struct GNUNET_TUN_IcmpHeader);
2777 break;
2778
2781 break;
2782
2783 default:
2785 gettext_noop (
2786 "# ICMPv6 packets dropped (type not allowed)")
2787 ,
2788 1, GNUNET_NO);
2789 return;
2790 }
2791 break;
2792
2793 default:
2794 GNUNET_assert (0);
2795 }
2796 switch (protocol)
2797 {
2798 case IPPROTO_ICMP:
2800 IPPROTO_ICMP,
2801 source_ip,
2802 0,
2803 destination_ip,
2804 0,
2805 NULL);
2806 break;
2807
2808 case IPPROTO_ICMPV6:
2810 IPPROTO_ICMPV6,
2811 source_ip,
2812 0,
2813 destination_ip,
2814 0,
2815 NULL);
2816 break;
2817
2818 case IPPROTO_UDP:
2820 IPPROTO_UDP,
2821 source_ip,
2822 source_port,
2823 destination_ip,
2824 destination_port,
2825 NULL);
2826 break;
2827
2828 case IPPROTO_TCP:
2830 IPPROTO_TCP,
2831 source_ip,
2832 source_port,
2833 destination_ip,
2834 destination_port,
2835 NULL);
2836 break;
2837
2838 default:
2840 gettext_noop (
2841 "# ICMP packets dropped (not allowed)"),
2842 1,
2843 GNUNET_NO);
2844 return;
2845 }
2846 if (NULL == state)
2847 {
2849 _ (
2850 "ICMP Packet dropped, have no matching connection information\n"));
2851 return;
2852 }
2853 env = GNUNET_MQ_msg_extra (i2v,
2854 pktlen - sizeof(struct GNUNET_TUN_IcmpHeader),
2856 i2v->af = htonl (af);
2858 icmp,
2859 pktlen);
2861 env);
2862}
2863
2864
2876static void
2878 size_t pktlen,
2879 int af,
2880 const void *destination_ip,
2881 const void *source_ip)
2882{
2883 struct ChannelState *state;
2884 struct GNUNET_MQ_Envelope *env;
2885 struct GNUNET_EXIT_UdpReplyMessage *urm;
2886
2887 {
2888 char sbuf[INET6_ADDRSTRLEN];
2889 char dbuf[INET6_ADDRSTRLEN];
2890
2892 "Received UDP packet going from %s:%u to %s:%u\n",
2893 inet_ntop (af,
2894 source_ip,
2895 sbuf, sizeof(sbuf)),
2896 (unsigned int) ntohs (udp->source_port),
2897 inet_ntop (af,
2898 destination_ip,
2899 dbuf, sizeof(dbuf)),
2900 (unsigned int) ntohs (udp->destination_port));
2901 }
2902
2903 if (pktlen < sizeof(struct GNUNET_TUN_UdpHeader))
2904 {
2905 /* blame kernel */
2906 GNUNET_break (0);
2907 return;
2908 }
2909 if (pktlen != ntohs (udp->len))
2910 {
2911 /* blame kernel */
2912 GNUNET_break (0);
2913 return;
2914 }
2916 IPPROTO_UDP,
2917 source_ip,
2918 ntohs (udp->source_port),
2919 destination_ip,
2920 ntohs (udp->destination_port),
2921 NULL);
2922 if (NULL == state)
2923 {
2925 _ (
2926 "UDP Packet dropped, have no matching connection information\n"));
2927 return;
2928 }
2929 env = GNUNET_MQ_msg_extra (urm,
2930 pktlen - sizeof(struct GNUNET_TUN_UdpHeader),
2932 urm->source_port = htons (0);
2933 urm->destination_port = htons (0);
2934 GNUNET_memcpy (&urm[1],
2935 &udp[1],
2936 pktlen - sizeof(struct GNUNET_TUN_UdpHeader));
2938 env);
2939}
2940
2941
2953static void
2955 size_t pktlen,
2956 int af,
2957 const void *destination_ip,
2958 const void *source_ip)
2959{
2960 struct ChannelState *state;
2961 char buf[pktlen] GNUNET_ALIGN;
2962 struct GNUNET_TUN_TcpHeader *mtcp;
2963 struct GNUNET_EXIT_TcpDataMessage *tdm;
2964 struct GNUNET_MQ_Envelope *env;
2965 size_t mlen;
2966
2967 {
2968 char sbuf[INET6_ADDRSTRLEN];
2969 char dbuf[INET6_ADDRSTRLEN];
2971 "Received TCP packet with %u bytes going from %s:%u to %s:%u\n",
2972 (unsigned int) (pktlen - sizeof(struct GNUNET_TUN_TcpHeader)),
2973 inet_ntop (af,
2974 source_ip,
2975 sbuf, sizeof(sbuf)),
2976 (unsigned int) ntohs (tcp->source_port),
2977 inet_ntop (af,
2978 destination_ip,
2979 dbuf, sizeof(dbuf)),
2980 (unsigned int) ntohs (tcp->destination_port));
2981 }
2982
2983 if (pktlen < sizeof(struct GNUNET_TUN_TcpHeader))
2984 {
2985 /* blame kernel */
2986 GNUNET_break (0);
2987 return;
2988 }
2990 IPPROTO_TCP,
2991 source_ip,
2992 ntohs (tcp->source_port),
2993 destination_ip,
2994 ntohs (tcp->destination_port),
2995 NULL);
2996 if (NULL == state)
2997 {
2999 _ (
3000 "TCP Packet dropped, have no matching connection information\n"));
3001
3002 return;
3003 }
3004 /* mug port numbers and crc to avoid information leakage;
3005 sender will need to lookup the correct values anyway */
3006 GNUNET_memcpy (buf, tcp, pktlen);
3007 mtcp = (struct GNUNET_TUN_TcpHeader *) buf;
3008 mtcp->source_port = 0;
3009 mtcp->destination_port = 0;
3010 mtcp->crc = 0;
3011
3012 mlen = sizeof(struct GNUNET_EXIT_TcpDataMessage) + (pktlen - sizeof(struct
3014 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
3015 {
3016 GNUNET_break (0);
3017 return;
3018 }
3019 env = GNUNET_MQ_msg_extra (tdm,
3020 pktlen - sizeof(struct GNUNET_TUN_TcpHeader),
3022 tdm->reserved = htonl (0);
3024 buf,
3025 pktlen);
3027 env);
3028}
3029
3030
3037static int
3038message_token (void *cls GNUNET_UNUSED,
3039 const struct GNUNET_MessageHeader *message)
3040{
3041 const struct GNUNET_TUN_Layer2PacketHeader *pkt_tun;
3042 size_t size;
3043
3045 "Got %u-byte message of type %u from gnunet-helper-exit\n",
3046 ntohs (message->size),
3047 ntohs (message->type));
3049 gettext_noop ("# Packets received from TUN"),
3050 1, GNUNET_NO);
3051 if (ntohs (message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER)
3052 {
3053 GNUNET_break (0);
3054 return GNUNET_OK;
3055 }
3056 size = ntohs (message->size);
3057 if (size < sizeof(struct GNUNET_TUN_Layer2PacketHeader) + sizeof(struct
3059 {
3060 GNUNET_break (0);
3061 return GNUNET_OK;
3062 }
3064 gettext_noop ("# Bytes received from TUN"),
3065 size, GNUNET_NO);
3066 pkt_tun = (const struct GNUNET_TUN_Layer2PacketHeader *) &message[1];
3067 size -= sizeof(struct GNUNET_TUN_Layer2PacketHeader) + sizeof(struct
3069 switch (ntohs (pkt_tun->proto))
3070 {
3071 case ETH_P_IPV4:
3072 {
3073 const struct GNUNET_TUN_IPv4Header *pkt4;
3074
3075 if (size < sizeof(struct GNUNET_TUN_IPv4Header))
3076 {
3077 /* Kernel to blame? */
3078 GNUNET_break (0);
3079 return GNUNET_OK;
3080 }
3081 pkt4 = (const struct GNUNET_TUN_IPv4Header *) &pkt_tun[1];
3082 if (size != ntohs (pkt4->total_length))
3083 {
3084 /* Kernel to blame? */
3085 GNUNET_break (0);
3086 return GNUNET_OK;
3087 }
3088 if (pkt4->header_length * 4 != sizeof(struct GNUNET_TUN_IPv4Header))
3089 {
3091 _ ("IPv4 packet options received. Ignored.\n"));
3092 return GNUNET_OK;
3093 }
3094
3095 size -= sizeof(struct GNUNET_TUN_IPv4Header);
3096 switch (pkt4->protocol)
3097 {
3098 case IPPROTO_UDP:
3099 udp_from_helper ((const struct GNUNET_TUN_UdpHeader *) &pkt4[1], size,
3100 AF_INET,
3101 &pkt4->destination_address,
3102 &pkt4->source_address);
3103 break;
3104
3105 case IPPROTO_TCP:
3106 tcp_from_helper ((const struct GNUNET_TUN_TcpHeader *) &pkt4[1], size,
3107 AF_INET,
3108 &pkt4->destination_address,
3109 &pkt4->source_address);
3110 break;
3111
3112 case IPPROTO_ICMP:
3113 icmp_from_helper ((const struct GNUNET_TUN_IcmpHeader *) &pkt4[1], size,
3114 AF_INET,
3115 &pkt4->destination_address,
3116 &pkt4->source_address);
3117 break;
3118
3119 default:
3121 _ (
3122 "IPv4 packet with unsupported next header %u received. Ignored.\n"),
3123 (int) pkt4->protocol);
3124 return GNUNET_OK;
3125 }
3126 }
3127 break;
3128
3129 case ETH_P_IPV6:
3130 {
3131 const struct GNUNET_TUN_IPv6Header *pkt6;
3132
3133 if (size < sizeof(struct GNUNET_TUN_IPv6Header))
3134 {
3135 /* Kernel to blame? */
3136 GNUNET_break (0);
3137 return GNUNET_OK;
3138 }
3139 pkt6 = (struct GNUNET_TUN_IPv6Header *) &pkt_tun[1];
3140 if (size != ntohs (pkt6->payload_length) + sizeof(struct
3142 {
3143 /* Kernel to blame? */
3144 GNUNET_break (0);
3145 return GNUNET_OK;
3146 }
3147 size -= sizeof(struct GNUNET_TUN_IPv6Header);
3148 switch (pkt6->next_header)
3149 {
3150 case IPPROTO_UDP:
3151 udp_from_helper ((const struct GNUNET_TUN_UdpHeader *) &pkt6[1], size,
3152 AF_INET6,
3153 &pkt6->destination_address,
3154 &pkt6->source_address);
3155 break;
3156
3157 case IPPROTO_TCP:
3158 tcp_from_helper ((const struct GNUNET_TUN_TcpHeader *) &pkt6[1], size,
3159 AF_INET6,
3160 &pkt6->destination_address,
3161 &pkt6->source_address);
3162 break;
3163
3164 case IPPROTO_ICMPV6:
3165 icmp_from_helper ((const struct GNUNET_TUN_IcmpHeader *) &pkt6[1], size,
3166 AF_INET6,
3167 &pkt6->destination_address,
3168 &pkt6->source_address);
3169 break;
3170
3171 default:
3173 _ (
3174 "IPv6 packet with unsupported next header %d received. Ignored.\n"),
3175 pkt6->next_header);
3176 return GNUNET_OK;
3177 }
3178 }
3179 break;
3180
3181 default:
3183 _ ("Packet from unknown protocol %u received. Ignored.\n"),
3184 ntohs (pkt_tun->proto));
3185 break;
3186 }
3187 return GNUNET_OK;
3188}
3189
3190
3199static void *
3200new_channel (void *cls,
3201 struct GNUNET_CADET_Channel *channel,
3202 const struct GNUNET_PeerIdentity *initiator)
3203{
3204 struct ChannelState *s = GNUNET_new (struct ChannelState);
3205
3206 s->is_dns = GNUNET_SYSERR;
3207 s->peer = *initiator;
3209 gettext_noop ("# Inbound CADET channels created"),
3210 1,
3211 GNUNET_NO);
3213 "Received inbound channel from `%s'\n",
3214 GNUNET_i2s (initiator));
3215 s->channel = channel;
3216 return s;
3217}
3218
3219
3227static int
3228free_iterate (void *cls,
3229 const struct GNUNET_HashCode *hash,
3230 void *value)
3231{
3233 return GNUNET_YES;
3234}
3235
3236
3245static void
3246dummy_task (void *cls)
3247{
3248 /* just terminate */
3249}
3250
3251
3257static void
3258cleanup (void *cls)
3259{
3260 unsigned int i;
3261
3263 "Exit service is shutting down now\n");
3264
3265 if (NULL != helper_handle)
3266 {
3268 helper_handle = NULL;
3269 }
3270 if (NULL != regex4)
3271 {
3273 regex4 = NULL;
3274 }
3275 if (NULL != regex6)
3276 {
3278 regex6 = NULL;
3279 }
3280 if (NULL != services)
3281 {
3284 NULL);
3286 }
3287 if (NULL != dns_port)
3288 {
3290 dns_port = NULL;
3291 }
3292 if (NULL != cadet_port4)
3293 {
3295 cadet_port4 = NULL;
3296 }
3297 if (NULL != cadet_port6)
3298 {
3300 cadet_port6 = NULL;
3301 }
3302 if (NULL != cadet_handle)
3303 {
3305 cadet_handle = NULL;
3306 }
3307 if (NULL != connections_map)
3308 {
3310 &free_iterate,
3311 NULL);
3313 connections_map = NULL;
3314 }
3315 if (NULL != connections_heap)
3316 {
3318 connections_heap = NULL;
3319 }
3320 if (NULL != dnsstub)
3321 {
3323 dnsstub = NULL;
3324 }
3325 if (NULL != sign_op)
3326 {
3328 sign_op = NULL;
3329 }
3330 if (NULL != pils)
3331 {
3333 pils = NULL;
3334 }
3335 if (NULL != dht_task)
3336 {
3338 dht_task = NULL;
3339 }
3340 if (NULL != dht_put)
3341 {
3343 dht_put = NULL;
3344 }
3345 if (NULL != dht)
3346 {
3348 dht = NULL;
3349 }
3350 if (NULL != stats)
3351 {
3353 GNUNET_NO);
3354 stats = NULL;
3355 }
3356 for (i = 0; i < 8; i++)
3358}
3359
3360
3368static void
3369add_services (int proto,
3370 char *cpy,
3371 const char *name)
3372{
3373 char *redirect;
3374 char *hostname;
3375 char *hostport;
3376 struct LocalService *serv;
3377 char *n;
3378 size_t slen;
3379 int local_port;
3380 int remote_port;
3381
3382 slen = strlen (name);
3383 GNUNET_assert (slen >= 8);
3384 n = GNUNET_strndup (name, slen - 8 /* remove .gnunet. */);
3385
3386 for (redirect = strtok (cpy, " ;"); redirect != NULL;
3387 redirect = strtok (NULL, " ;"))
3388 {
3389 if (NULL == (hostname = strstr (redirect, ":")))
3390 {
3392 _ (
3393 "Option `%s' for domain `%s' is not formatted correctly!\n")
3394 ,
3395 redirect,
3396 name);
3397 continue;
3398 }
3399 hostname[0] = '\0';
3400 hostname++;
3401 if (NULL == (hostport = strstr (hostname, ":")))
3402 {
3404 _ (
3405 "Option `%s' for domain `%s' is not formatted correctly!\n")
3406 ,
3407 redirect,
3408 name);
3409 continue;
3410 }
3411 hostport[0] = '\0';
3412 hostport++;
3413
3414 local_port = atoi (redirect);
3415 remote_port = atoi (hostport);
3416
3417 if (! ((local_port > 0) && (local_port < 65536)))
3418 {
3420 _ ("`%s' is not a valid port number (for domain `%s')!"),
3421 redirect,
3422 name);
3423 continue;
3424 }
3425 if (! ((remote_port > 0) && (remote_port < 65536)))
3426 {
3428 _ ("`%s' is not a valid port number (for domain `%s')!"),
3429 hostport,
3430 name);
3431 continue;
3432 }
3433
3434 serv = GNUNET_new (struct LocalService);
3435 serv->address.proto = proto;
3436 serv->address.port = remote_port;
3437 if (0 == strcmp ("localhost4",
3438 hostname))
3439 {
3440 const char *ip4addr = exit_argv[5];
3441
3442 serv->address.af = AF_INET;
3443 GNUNET_assert (1 == inet_pton (AF_INET,
3444 ip4addr,
3445 &serv->address.address.ipv4));
3446 }
3447 else if (0 == strcmp ("localhost6",
3448 hostname))
3449 {
3450 const char *ip6addr = exit_argv[3];
3451
3452 serv->address.af = AF_INET6;
3453 GNUNET_assert (1 == inet_pton (AF_INET6,
3454 ip6addr,
3455 &serv->address.address.ipv6));
3456 }
3457 else
3458 {
3459 struct addrinfo *res;
3460 int ret;
3461
3462 ret = getaddrinfo (hostname,
3463 NULL,
3464 NULL,
3465 &res);
3466 if ((0 != ret) || (NULL == res))
3467 {
3469 _ (
3470 "No addresses found for hostname `%s' of service `%s'!\n")
3471 ,
3472 hostname,
3473 n);
3474 GNUNET_free (serv);
3475 continue;
3476 }
3477
3478 serv->address.af = res->ai_family;
3479 switch (res->ai_family)
3480 {
3481 case AF_INET:
3482 if (! ipv4_enabled)
3483 {
3485 _ (
3486 "Service `%s' configured for IPv4, but IPv4 is disabled!\n"),
3487 n);
3488 freeaddrinfo (res);
3489 GNUNET_free (serv);
3490 continue;
3491 }
3492 serv->address.address.ipv4
3493 = ((struct sockaddr_in *) res->ai_addr)->sin_addr;
3494 break;
3495
3496 case AF_INET6:
3497 if (! ipv6_enabled)
3498 {
3500 _ (
3501 "Service `%s' configured for IPv4, but IPv4 is disabled!\n"),
3502 n);
3503 freeaddrinfo (res);
3504 GNUNET_free (serv);
3505 continue;
3506 }
3507 serv->address.address.ipv6
3508 = ((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
3509 break;
3510
3511 default:
3512 freeaddrinfo (res);
3514 _ (
3515 "No IP addresses found for hostname `%s' of service `%s'!\n"),
3516 hostname,
3517 n);
3518 GNUNET_free (serv);
3519 continue;
3520 }
3521 freeaddrinfo (res);
3522 }
3524 n,
3525 local_port,
3526 serv);
3527 }
3528 GNUNET_free (n);
3529}
3530
3531
3538static void
3539read_service_conf (void *cls,
3540 const char *section)
3541{
3542 char *cpy;
3543
3544 if ((strlen (section) < 8) ||
3545 (0 != strcmp (".gnunet.", section + (strlen (section) - 8))))
3546 return;
3547 if (GNUNET_OK ==
3549 section,
3550 "UDP_REDIRECTS",
3551 &cpy))
3552 {
3553 add_services (IPPROTO_UDP,
3554 cpy,
3555 section);
3556 GNUNET_free (cpy);
3557 }
3558 if (GNUNET_OK ==
3560 section,
3561 "TCP_REDIRECTS",
3562 &cpy))
3563 {
3564 add_services (IPPROTO_TCP,
3565 cpy,
3566 section);
3567 GNUNET_free (cpy);
3568 }
3569}
3570
3571
3578static void
3579do_dht_put (void *cls);
3580
3581
3588static void
3589dht_put_cont (void *cls)
3590{
3591 dht_put = NULL;
3592}
3593
3594
3595static void
3596sign_dns_advertisement (void *cls,
3597 const struct GNUNET_PeerIdentity *pid,
3598 const struct GNUNET_CRYPTO_EddsaSignature *sig)
3599{
3600 GNUNET_assert (sig);
3601
3602 sign_op = NULL;
3603
3605 sizeof (dns_advertisement.signature));
3606
3607 do_dht_put (cls);
3608}
3609
3610
3617static void
3618do_dht_put (void *cls)
3619{
3621
3623 &do_dht_put,
3624 NULL);
3628 {
3629 /* refresh advertisement */
3632
3633 if (NULL != sign_op)
3635
3637 purpose,
3639 return;
3640 }
3641 if (NULL != dht_put)
3644 &dht_put_key,
3645 1 /* replication */,
3648 sizeof(struct GNUNET_DNS_Advertisement),
3650 expiration,
3651 &dht_put_cont,
3652 NULL);
3653}
3654
3655
3656static void
3657do_initial_dht_put (void *cls,
3658 const struct GNUNET_HELLO_Parser *parser,
3659 const struct GNUNET_HashCode *hash)
3660{
3661 const struct GNUNET_PeerIdentity *my_identity;
3662
3665
3667 my_identity, sizeof (*my_identity));
3668 dns_advertisement.purpose.size = htonl (sizeof(struct
3670 - sizeof(struct
3672 );
3675 GNUNET_CRYPTO_hash ("dns",
3676 strlen ("dns"),
3677 &dht_put_key);
3678
3679 if (NULL != sign_op)
3680 {
3682 sign_op = NULL;
3683 }
3684
3685 if (NULL != dht_task)
3687
3689 NULL);
3690}
3691
3692
3697static void
3699{
3701 "exit",
3702 "EXIT_IPV4");
3704 "exit",
3705 "EXIT_IPV6");
3707 "exit",
3708 "ENABLE_IPV4");
3710 "exit",
3711 "ENABLE_IPV6");
3712 if ((ipv4_exit || ipv4_enabled) &&
3713 (GNUNET_OK != GNUNET_NETWORK_test_pf (PF_INET)) )
3714 {
3716 _ (
3717 "This system does not support IPv4, will disable IPv4 functions despite them being enabled in the configuration\n"));
3720 }
3721 if ((ipv6_exit || ipv6_enabled) &&
3722 (GNUNET_OK != GNUNET_NETWORK_test_pf (PF_INET6)) )
3723 {
3725 _ (
3726 "This system does not support IPv6, will disable IPv6 functions despite them being enabled in the configuration\n"));
3729 }
3730 if (ipv4_exit && (! ipv4_enabled))
3731 {
3733 _ (
3734 "Cannot enable IPv4 exit but disable IPv4 on TUN interface, will use ENABLE_IPv4=YES\n"));
3736 }
3737 if (ipv6_exit && (! ipv6_enabled))
3738 {
3740 _ (
3741 "Cannot enable IPv6 exit but disable IPv6 on TUN interface, will use ENABLE_IPv6=YES\n"));
3743 }
3744}
3745
3746
3751static void
3753{
3755 GNUNET_MQ_hd_var_size (dns_request,
3757 struct DnsResponseMessage,
3758 NULL),
3760 };
3761 char *dns_exit;
3762 struct GNUNET_HashCode port;
3763
3764 if (GNUNET_YES !=
3766 "exit",
3767 "EXIT_DNS"))
3768 return;
3769 GNUNET_assert (NULL != (dnsstub = GNUNET_DNSSTUB_start (128)));
3770 dns_exit = NULL;
3771 /* TODO: support using multiple DNS resolvers */
3772 if ((GNUNET_OK !=
3774 "exit",
3775 "DNS_RESOLVER",
3776 &dns_exit)) ||
3777 (GNUNET_OK !=
3779 dns_exit)))
3780 {
3782 "dns",
3783 "DNS_RESOLVER",
3784 _ ("need a valid IPv4 or IPv6 address\n"));
3785 GNUNET_free (dns_exit);
3786 return;
3787 }
3788 /* open port */
3791 &port);
3793 "Opening CADET port %s for DNS exit service\n",
3794 GNUNET_h2s (&port));
3796 &port,
3797 &new_channel,
3798 NULL,
3799 NULL,
3801 handlers);
3802 /* advertise exit */
3803 dht = GNUNET_DHT_connect (cfg, 1);
3804 dht_task = NULL;
3806 sign_op = NULL;
3807 GNUNET_free (dns_exit);
3808}
3809
3810
3816static int
3818{
3819 char *exit_ifname;
3820 char *tun_ifname;
3821 char *ipv6addr;
3822 char *ipv6prefix_s;
3823 char *ipv4addr;
3824 char *ipv4mask;
3825
3826 exit_argv[0] = GNUNET_strdup ("exit-gnunet");
3827 if (GNUNET_SYSERR ==
3829 "exit",
3830 "TUN_IFNAME",
3831 &tun_ifname))
3832 {
3834 "EXIT",
3835 "TUN_IFNAME");
3836 return GNUNET_SYSERR;
3837 }
3838 exit_argv[1] = tun_ifname;
3839 if (ipv4_enabled)
3840 {
3841 if (GNUNET_SYSERR ==
3843 "exit",
3844 "EXIT_IFNAME",
3845 &exit_ifname))
3846 {
3848 "EXIT",
3849 "EXIT_IFNAME");
3850 return GNUNET_SYSERR;
3851 }
3852 exit_argv[2] = exit_ifname;
3853 }
3854 else
3855 {
3856 exit_argv[2] = GNUNET_strdup ("-");
3857 }
3858
3859 if (GNUNET_YES == ipv6_enabled)
3860 {
3861 ipv6addr = NULL;
3862 if (((GNUNET_SYSERR ==
3864 "exit",
3865 "IPV6ADDR",
3866 &ipv6addr)) ||
3867 (1 != inet_pton (AF_INET6,
3868 ipv6addr,
3869 &exit_ipv6addr))))
3870 {
3872 "EXIT",
3873 "IPV6ADDR");
3874 GNUNET_free (ipv6addr);
3875 return GNUNET_SYSERR;
3876 }
3877 exit_argv[3] = ipv6addr;
3878 if (GNUNET_SYSERR ==
3880 "exit",
3881 "IPV6PREFIX",
3882 &ipv6prefix_s))
3883 {
3885 "EXIT",
3886 "IPV6PREFIX");
3887 return GNUNET_SYSERR;
3888 }
3889 exit_argv[4] = ipv6prefix_s;
3890 if ((GNUNET_OK !=
3892 "exit",
3893 "IPV6PREFIX",
3894 &ipv6prefix)) ||
3895 (ipv6prefix >= 127))
3896 {
3898 "EXIT",
3899 "IPV6PREFIX",
3900 _ ("Must be a number"));
3901 return GNUNET_SYSERR;
3902 }
3903 }
3904 else
3905 {
3906 /* IPv6 explicitly disabled */
3907 exit_argv[3] = GNUNET_strdup ("-");
3908 exit_argv[4] = GNUNET_strdup ("-");
3909 }
3910 if (GNUNET_YES == ipv4_enabled)
3911 {
3912 ipv4addr = NULL;
3913 if (((GNUNET_SYSERR ==
3915 "exit",
3916 "IPV4ADDR",
3917 &ipv4addr)) ||
3918 (1 != inet_pton (AF_INET,
3919 ipv4addr,
3920 &exit_ipv4addr))))
3921 {
3923 "EXIT",
3924 "IPV4ADDR");
3925 GNUNET_free (ipv4addr);
3926 return GNUNET_SYSERR;
3927 }
3928 exit_argv[5] = ipv4addr;
3929 ipv4mask = NULL;
3930 if (((GNUNET_SYSERR ==
3932 "exit",
3933 "IPV4MASK",
3934 &ipv4mask)) ||
3935 (1 != inet_pton (AF_INET,
3936 ipv4mask,
3937 &exit_ipv4mask))))
3938 {
3940 "EXIT",
3941 "IPV4MASK");
3942 GNUNET_free (ipv4mask);
3943 return GNUNET_SYSERR;
3944 }
3945 exit_argv[6] = ipv4mask;
3946 }
3947 else
3948 {
3949 /* IPv4 explicitly disabled */
3950 exit_argv[5] = GNUNET_strdup ("-");
3951 exit_argv[6] = GNUNET_strdup ("-");
3952 }
3953 exit_argv[7] = NULL;
3954 return GNUNET_OK;
3955}
3956
3957
3966static void
3967run (void *cls,
3968 char *const *args,
3969 const char *cfgfile,
3970 const struct GNUNET_CONFIGURATION_Handle *cfg_)
3971{
3973 GNUNET_MQ_hd_var_size (icmp_remote,
3976 NULL),
3977 GNUNET_MQ_hd_var_size (udp_remote,
3980 NULL),
3981 GNUNET_MQ_hd_var_size (tcp_remote,
3984 NULL),
3985 GNUNET_MQ_hd_var_size (tcp_data,
3988 NULL),
3990 };
3991 struct GNUNET_HashCode port;
3992 char *policy;
3993 char *binary;
3994 char *regex;
3995 char *prefixed_regex;
3996
3997 cfg = cfg_;
3998 if (GNUNET_OK !=
4000 "exit",
4001 "MAX_CONNECTIONS",
4003 max_connections = 1024;
4006 cfg,
4007 "gnunet-helper-exit");
4008 if ((ipv4_exit) || (ipv6_exit))
4009 {
4010 if (GNUNET_YES !=
4012 GNUNET_YES,
4013 "gnunet-vpn - - - 169.1.3.7 255.255.255.0"))
4014 // no nat, ipv4 only
4015 {
4016 GNUNET_free (binary);
4018 _ (
4019 "`%s' is not SUID or the path is invalid, EXIT will not work\n"),
4020 "gnunet-helper-exit");
4022 NULL);
4023 global_ret = 1;
4024 return;
4025 }
4026 }
4027 if (! (ipv4_enabled || ipv6_enabled))
4028 {
4029 GNUNET_free (binary);
4031 _ ("No useful service enabled. Exiting.\n"));
4033 return;
4034 }
4035
4037 NULL);
4039 cfg);
4041 if (NULL == cadet_handle)
4042 {
4043 GNUNET_free (binary);
4045 return;
4046 }
4048 if (GNUNET_OK !=
4050 {
4051 GNUNET_free (binary);
4053 return;
4054 }
4055
4057 GNUNET_NO);
4059 GNUNET_NO);
4064 NULL);
4065
4066 /* Cadet handle acquired, now open ports and announce regular
4067 expressions matching our exit */
4068 if ((GNUNET_YES == ipv4_enabled) &&
4069 (GNUNET_YES == ipv4_exit))
4070 {
4073 &port);
4075 "Opening CADET port %s for IPv4 gateway service\n",
4076 GNUNET_h2s (&port));
4078 &port,
4079 &new_channel,
4080 NULL,
4081 NULL,
4083 handlers);
4084 policy = NULL;
4085 if (GNUNET_OK !=
4087 "exit",
4088 "EXIT_RANGE_IPV4_POLICY",
4089 &policy))
4090 regex = NULL;
4091 else
4092 regex = GNUNET_REGEX_ipv4policy2regex (policy);
4093 GNUNET_free (policy);
4094 if (NULL != regex)
4095 {
4096 (void) GNUNET_asprintf (&prefixed_regex,
4097 "%s%s",
4099 regex);
4101 prefixed_regex,
4104 GNUNET_free (regex);
4105 GNUNET_free (prefixed_regex);
4106 }
4107 }
4108
4110 {
4113 &port);
4115 "Opening CADET port %s for IPv6 gateway service\n",
4116 GNUNET_h2s (&port));
4118 &port,
4119 &new_channel,
4120 NULL,
4121 NULL,
4123 handlers);
4124 policy = NULL;
4125 if (GNUNET_OK !=
4127 "exit",
4128 "EXIT_RANGE_IPV6_POLICY",
4129 &policy))
4130 regex = NULL;
4131 else
4132 regex = GNUNET_REGEX_ipv6policy2regex (policy);
4133 GNUNET_free (policy);
4134 if (NULL != regex)
4135 {
4136 (void) GNUNET_asprintf (&prefixed_regex,
4137 "%s%s",
4139 regex);
4141 prefixed_regex,
4144 GNUNET_free (regex);
4145 GNUNET_free (prefixed_regex);
4146 }
4147 }
4149 GNUNET_NO,
4150 binary,
4151 exit_argv,
4153 NULL,
4154 NULL);
4155 GNUNET_free (binary);
4156}
4157
4158
4166int
4167main (int argc,
4168 char *const *argv)
4169{
4170 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
4172 };
4173
4174 return (GNUNET_OK ==
4176 argc,
4177 argv,
4178 "gnunet-daemon-exit",
4179 gettext_noop (
4180 "Daemon to run to provide an IP exit node for the VPN"),
4181 options,
4182 &run,
4183 NULL)) ? global_ret : 1;
4184}
4185
4186
4187/* end of gnunet-daemon-exit.c */
struct GNUNET_GETOPT_CommandLineOption options[]
Definition 002.c:5
struct GNUNET_MQ_MessageHandlers handlers[]
Definition 003.c:1
struct GNUNET_MessageHeader * msg
Definition 005.c:2
struct GNUNET_MQ_Envelope * env
Definition 005.c:1
int main()
Program to simulate results from GCP_get_desirability_of_path() for various plausible inputs.
#define gettext_noop(String)
Definition gettext.h:74
static int start
Set if we are to start default services (including ARM).
Definition gnunet-arm.c:38
static int ret
Final status code.
Definition gnunet-arm.c:93
static uint16_t port
Port number.
Definition gnunet-bcd.c:146
static char * address
GNS address for this phone.
static int check_udp_remote(void *cls, const struct GNUNET_EXIT_UdpInternetMessage *msg)
Check a request to forward UDP data to the Internet via this peer.
static int check_dns_request(void *cls, const struct DnsResponseMessage *msg)
Check a request via cadet to perform a DNS query.
static void udp_from_helper(const struct GNUNET_TUN_UdpHeader *udp, size_t pktlen, int af, const void *destination_ip, const void *source_ip)
Handles an UDP packet received from the helper.
static void do_initial_dht_put(void *cls, const struct GNUNET_HELLO_Parser *parser, const struct GNUNET_HashCode *hash)
static struct GNUNET_DHT_Handle * dht
Handle to the DHT.
static void send_udp_packet_via_tun(const struct SocketAddress *destination_address, const struct SocketAddress *source_address, const void *payload, size_t payload_length)
Send a UDP packet via the TUN interface.
static int ipv6_enabled
Do we support IPv6 at all on the TUN interface?
static int check_udp_service(void *cls, const struct GNUNET_EXIT_UdpServiceMessage *msg)
Check a request via cadet to send a request to a UDP service offered by this system.
static void make_up_icmpv4_payload(struct ChannelState *state, struct GNUNET_TUN_IPv4Header *ipp, struct GNUNET_TUN_UdpHeader *udp)
Synthesize a plausible ICMP payload for an ICMPv4 error response on the given channel.
static void clean_channel(void *cls, const struct GNUNET_CADET_Channel *channel)
Function called by cadet whenever an inbound channel is destroyed.
static struct GNUNET_REGEX_Announcement * regex4
Handle to our regex announcement for IPv4.
static void send_packet_to_cadet_channel(struct ChannelState *s, struct GNUNET_MQ_Envelope *env)
Send the given packet via the cadet channel.
static int ipv4_enabled
Do we support IPv4 at all on the TUN interface?
static int check_tcp_service(void *cls, const struct GNUNET_EXIT_TcpServiceStartMessage *start)
Check a request via cadet to send a request to a TCP service offered by this system.
static void send_tcp_packet_via_tun(const struct SocketAddress *destination_address, const struct SocketAddress *source_address, const struct GNUNET_TUN_TcpHeader *tcp_header, const void *payload, size_t payload_length)
Send a TCP packet via the TUN interface.
static struct GNUNET_CONTAINER_MultiHashMap * services
This hashmaps saves interesting things about the configured services.
#define REGEX_MAX_PATH_LEN_IPV4
Maximum path compression length for cadet regex announcing for IPv4 address based regex.
#define DNS_ADVERTISEMENT_TIMEOUT
How long do we typically sign the DNS exit advertisement for?
static struct ChannelState * channels[UINT16_MAX+1]
Array of all open DNS requests from channels.
static unsigned long long ipv6prefix
IPv6 prefix (0..127) from configuration file.
#define REGEX_REFRESH_FREQUENCY
How frequently do we re-announce the regex for the exit?
static struct in6_addr exit_ipv6addr
IPv6 address of our TUN interface.
static struct ChannelState * get_redirect_state(int af, int protocol, const void *destination_ip, uint16_t destination_port, const void *local_ip, uint16_t local_port, struct GNUNET_HashCode *state_key)
Get our connection tracking state.
static void handle_icmp_service(void *cls, const struct GNUNET_EXIT_IcmpServiceMessage *msg)
Process a request via cadet to send ICMP data to a service offered by this system.
static void setup_fresh_address(int af, uint8_t proto, struct SocketAddress *local_address)
We need to create a (unique) fresh local address (IP+port).
static unsigned long long max_connections
If there are at least this many connections, old ones will be removed.
static int global_ret
Return value from 'main'.
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg_)
Main function that will be run by the scheduler.
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
static int setup_exit_helper_args()
Initialize exit_argv.
static const struct GNUNET_CONFIGURATION_Handle * cfg
The handle to the configuration used throughout the process.
static struct GNUNET_DNS_Advertisement dns_advertisement
Advertisement message we put into the DHT to advertise us as a DNS exit.
static void * new_service_channel(void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *initiator)
Callback from CADET for new channels.
static void prepare_ipv6_packet(const void *payload, size_t payload_length, int protocol, const struct GNUNET_TUN_TcpHeader *tcp_header, const struct SocketAddress *src_address, const struct SocketAddress *dst_address, struct GNUNET_TUN_IPv6Header *pkt6)
Prepare an IPv6 packet for transmission via the TUN interface.
static struct GNUNET_DNSSTUB_Context * dnsstub
Handle to the DNS Stub resolver.
static void send_icmp_packet_via_tun(const struct SocketAddress *destination_address, const struct SocketAddress *source_address, const struct GNUNET_TUN_IcmpHeader *icmp_header, const void *payload, size_t payload_length)
Send an ICMP packet via the TUN interface.
static void dht_put_cont(void *cls)
Function called when the DHT PUT operation is complete.
static int check_icmp_service(void *cls, const struct GNUNET_EXIT_IcmpServiceMessage *msg)
Check a request via cadet to send ICMP data to a service offered by this system.
static void store_service(int proto, const char *name, uint16_t destination_port, struct LocalService *service)
Given a service descriptor and a destination port, find the respective service entry.
static struct GNUNET_CONTAINER_MultiHashMap * connections_map
This hashmaps contains the mapping from peer, service-descriptor, source-port and destination-port to...
static int ipv6_exit
Are we an IPv6-exit?
static void icmp_from_helper(const struct GNUNET_TUN_IcmpHeader *icmp, size_t pktlen, int af, const void *destination_ip, const void *source_ip)
Handles an ICMP packet received from the helper.
static void add_services(int proto, char *cpy, const char *name)
Add services to the service map.
static struct GNUNET_CONTAINER_Heap * connections_heap
Heap so we can quickly find "old" connections.
static void tcp_from_helper(const struct GNUNET_TUN_TcpHeader *tcp, size_t pktlen, int af, const void *destination_ip, const void *source_ip)
Handles a TCP packet received from the helper.
static void prepare_ipv4_packet(const void *payload, size_t payload_length, int protocol, const struct GNUNET_TUN_TcpHeader *tcp_header, const struct SocketAddress *src_address, const struct SocketAddress *dst_address, struct GNUNET_TUN_IPv4Header *pkt4)
Prepare an IPv4 packet for transmission via the TUN interface.
static struct GNUNET_DHT_PutHandle * dht_put
Handle for ongoing DHT PUT operations to advertise exit service.
#define REGEX_MAX_PATH_LEN_IPV6
Maximum path compression length for cadet regex announcing for IPv6 address based regex.
static void hash_redirect_info(struct GNUNET_HashCode *hash, const struct RedirectInformation *ri)
Given IP information about a connection, calculate the respective hash we would use for the connectio...
static void handle_tcp_service(void *cls, const struct GNUNET_EXIT_TcpServiceStartMessage *start)
Process a request via cadet to send a request to a TCP service offered by this system.
static uint16_t make_up_icmp_service_payload(struct ChannelState *state, char *buf)
Setup ICMP payload for ICMP error messages.
static struct GNUNET_REGEX_Announcement * regex6
Handle to our regex announcement for IPv4.
static void handle_tcp_remote(void *cls, const struct GNUNET_EXIT_TcpInternetStartMessage *start)
Process a request to forward TCP data to the Internet via this peer.
static struct GNUNET_CADET_Handle * cadet_handle
The handle to cadet.
static void dummy_task(void *cls)
Function scheduled as very last function if the service disabled itself because the helper is not ins...
static void do_dht_put(void *cls)
We are running a DNS exit service, advertise it in the DHT.
static int message_token(void *cls, const struct GNUNET_MessageHeader *message)
Receive packets from the helper-process.
static void handle_icmp_remote(void *cls, const struct GNUNET_EXIT_IcmpInternetMessage *msg)
Process a request to forward ICMP data to the Internet via this peer.
static void handle_udp_service(void *cls, const struct GNUNET_EXIT_UdpServiceMessage *msg)
Process a request via cadet to send a request to a UDP service offered by this system.
static void handle_tcp_data(void *cls, const struct GNUNET_EXIT_TcpDataMessage *data)
Process a request to forward TCP data on an established connection via this peer.
static char * exit_argv[8]
Arguments to the exit helper.
static void read_service_conf(void *cls, const char *section)
Reads the configuration and populates #udp_services and #tcp_services.
static struct GNUNET_CADET_Port * cadet_port4
Port for IPv4 exit.
static GNUNET_NETWORK_STRUCT_END void process_dns_result(void *cls, const struct GNUNET_TUN_DnsHeader *dns, size_t r)
Callback called from DNSSTUB resolver when a resolution succeeded.
static struct in_addr exit_ipv4mask
IPv4 netmask of our TUN interface.
static void parse_ip_options()
Figure out which IP versions we should support (and which are supported by the OS) according to our c...
static struct in_addr exit_ipv4addr
IPv4 address of our TUN interface.
static int free_service_record(void *cls, const struct GNUNET_HashCode *key, void *value)
Free memory associated with a service record.
static struct GNUNET_HashCode dht_put_key
Key we store the DNS advertismenet under.
static void * new_channel(void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *initiator)
Callback from CADET for new channels.
#define LOG(kind,...)
Generic logging shorthand.
static int check_tcp_data(void *cls, const struct GNUNET_EXIT_TcpDataMessage *data)
Check a request to forward TCP data on an established connection via this peer.
static void sign_dns_advertisement(void *cls, const struct GNUNET_PeerIdentity *pid, const struct GNUNET_CRYPTO_EddsaSignature *sig)
#define DHT_PUT_FREQUENCY
How frequently do we re-announce the DNS exit in the DHT?
static int check_icmp_remote(void *cls, const struct GNUNET_EXIT_IcmpInternetMessage *msg)
Check a request to forward ICMP data to the Internet via this peer.
static struct GNUNET_PILS_Operation * sign_op
Operation for signing the dns advertisement.
static void handle_udp_remote(void *cls, const struct GNUNET_EXIT_UdpInternetMessage *msg)
Process a request to forward UDP data to the Internet via this peer.
static void setup_state_record(struct ChannelState *state)
We are starting a fresh connection (TCP or UDP) and need to pick a source port and IP address (within...
static struct GNUNET_CADET_Port * dns_port
Port for DNS exit.
static struct GNUNET_HELPER_Handle * helper_handle
The handle to the helper.
static int ipv4_exit
Are we an IPv4-exit?
static int free_iterate(void *cls, const struct GNUNET_HashCode *hash, void *value)
Function that frees everything from a hashmap.
static void advertise_dns_exit()
Helper function to open the CADET port for DNS exits and to advertise the DNS exit (if applicable).
static struct GNUNET_CADET_Port * cadet_port6
Port for IPv6 exit.
static struct GNUNET_SCHEDULER_Task * dht_task
Task for doing DHT PUTs to advertise exit service.
static int check_tcp_remote(void *cls, const struct GNUNET_EXIT_TcpInternetStartMessage *start)
Check a request to forward TCP data to the Internet via this peer.
static struct GNUNET_PILS_Handle * pils
The pils service handle.
static void make_up_icmpv6_payload(struct ChannelState *state, struct GNUNET_TUN_IPv6Header *ipp, struct GNUNET_TUN_UdpHeader *udp)
Synthesize a plausible ICMP payload for an ICMPv6 error response on the given channel.
static void handle_dns_request(void *cls, const struct DnsResponseMessage *msg)
Process a request via cadet to perform a DNS query.
static char * data
The data to insert into the dht.
struct GNUNET_HashCode key
The key used in the DHT.
static struct GNUNET_TIME_Relative expiration
User supplied expiration value.
static char * name
Name (label) of the records to list.
static int state
The current state of the parser.
static char * res
Currently read line or NULL on EOF.
static char * value
Value of the record to add/remove.
static uint8_t proto
Protocol to use.
static struct GNUNET_NETWORK_Handle * ls
Listen socket for STUN processing.
Definition gnunet-nat.c:85
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.
static unsigned long long payload
How much data are we currently storing in the database?
static struct GNUNET_CADET_Port * cadet_port
Listen port for incoming requests.
static void cleanup()
Cleanup task.
static unsigned long long remote_port
Remote host's port.
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
static int ipv4
Option -4: IPv4 requested.
Definition gnunet-vpn.c:60
static int udp
Option -u: UDP requested.
Definition gnunet-vpn.c:75
static int ipv6
Option -6: IPv6 requested.
Definition gnunet-vpn.c:65
static int tcp
Option -t: TCP requested.
Definition gnunet-vpn.c:70
@ GNUNET_BLOCK_TYPE_DNS
Block for storing DNS exit service advertisements.
struct GNUNET_PILS_Handle * GNUNET_PILS_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_PILS_PidChangeCallback pid_change_cb, void *cls)
Connect to the PILS service.
Definition pils_api.c:465
void GNUNET_PILS_disconnect(struct GNUNET_PILS_Handle *handle)
Disconnect from the PILS service.
Definition pils_api.c:488
void GNUNET_PILS_cancel(struct GNUNET_PILS_Operation *op)
Cancel request.
Definition pils_api.c:623
struct GNUNET_PILS_Operation * GNUNET_PILS_sign_by_peer_identity(struct GNUNET_PILS_Handle *handle, const struct GNUNET_CRYPTO_SignaturePurpose *purpose, GNUNET_PILS_SignResultCallback cb, void *cb_cls)
Sign data with the peer id.
Definition pils_api.c:528
const struct GNUNET_PeerIdentity * GNUNET_PILS_get_identity(const struct GNUNET_PILS_Handle *handle)
Return the current peer identity of a given handle.
Definition pils_api.c:727
#define GNUNET_SIGNATURE_PURPOSE_DNS_RECORD
Signature on a GNUNET_DNS_Advertisement.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
#define GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX
Internet exit regex prefix.
#define GNUNET_APPLICATION_PORT_INTERNET_RESOLVER
Internet DNS resolution (external DNS gateway).
#define GNUNET_APPLICATION_PORT_IPV4_GATEWAY
Internet IPv4 gateway (any TCP/UDP/ICMP).
#define GNUNET_APPLICATION_PORT_IPV6_GATEWAY
Internet IPv6 gateway (any TCP/UDP/ICMP).
struct GNUNET_CADET_Handle * GNUNET_CADET_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the MQ-based cadet service.
Definition cadet_api.c:897
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Indicate readiness to receive the next message on a channel.
Definition cadet_api.c:875
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition cadet_api.c:833
struct GNUNET_MQ_Handle * GNUNET_CADET_get_mq(const struct GNUNET_CADET_Channel *channel)
Obtain the message queue for a connected channel.
Definition cadet_api.c:1081
struct GNUNET_CADET_Port * GNUNET_CADET_open_port(struct GNUNET_CADET_Handle *h, const struct GNUNET_HashCode *port, GNUNET_CADET_ConnectEventHandler connects, void *connects_cls, GNUNET_CADET_WindowSizeEventHandler window_changes, GNUNET_CADET_DisconnectEventHandler disconnects, const struct GNUNET_MQ_MessageHandler *handlers)
Open a port to receive incoming MQ-based channels.
Definition cadet_api.c:966
void GNUNET_CADET_disconnect(struct GNUNET_CADET_Handle *handle)
Disconnect from the cadet service.
Definition cadet_api.c:777
void GNUNET_CADET_close_port(struct GNUNET_CADET_Port *p)
Close a port opened with GNUNET_CADET_open_port.
Definition cadet_api.c:804
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
void GNUNET_CONFIGURATION_iterate_sections(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_CONFIGURATION_SectionIterator iter, void *iter_cls)
Iterate over all sections in the configuration.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
void GNUNET_DHT_put_cancel(struct GNUNET_DHT_PutHandle *ph)
Cancels a DHT PUT operation.
Definition dht_api.c:1150
struct GNUNET_DHT_PutHandle * GNUNET_DHT_put(struct GNUNET_DHT_Handle *handle, const struct GNUNET_HashCode *key, uint32_t desired_replication_level, enum GNUNET_DHT_RouteOption options, enum GNUNET_BLOCK_Type type, size_t size, const void *data, struct GNUNET_TIME_Absolute exp, GNUNET_SCHEDULER_TaskCallback cont, void *cont_cls)
Perform a PUT operation storing data in the DHT.
Definition dht_api.c:1087
struct GNUNET_DHT_Handle * GNUNET_DHT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, unsigned int ht_len)
Initialize the connection with the DHT service.
Definition dht_api.c:1036
void GNUNET_DHT_disconnect(struct GNUNET_DHT_Handle *handle)
Shutdown connection with the DHT service.
Definition dht_api.c:1059
@ GNUNET_DHT_RO_NONE
Default.
struct GNUNET_DNSSTUB_Context * GNUNET_DNSSTUB_start(unsigned int num_sockets)
Start a DNS stub resolver.
Definition dnsstub.c:586
int GNUNET_DNSSTUB_add_dns_ip(struct GNUNET_DNSSTUB_Context *ctx, const char *dns_ip)
Add nameserver for use by the DNSSTUB.
Definition dnsstub.c:613
void GNUNET_DNSSTUB_stop(struct GNUNET_DNSSTUB_Context *ctx)
Cleanup DNSSTUB resolver.
Definition dnsstub.c:705
struct GNUNET_DNSSTUB_RequestSocket * GNUNET_DNSSTUB_resolve(struct GNUNET_DNSSTUB_Context *ctx, const void *request, size_t request_len, GNUNET_DNSSTUB_ResultCallback rc, void *rc_cls)
Perform DNS resolution using our default IP from init.
Definition dnsstub.c:526
#define GNUNET_GETOPT_OPTION_END
Marker for the end of the list of options.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition crypto_hash.c:41
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
There must only be one value per key; storing a value should fail if a value under the same key alrea...
void * GNUNET_CONTAINER_heap_remove_node(struct GNUNET_CONTAINER_HeapNode *node)
Removes a node from the heap.
void * GNUNET_CONTAINER_heap_remove_root(struct GNUNET_CONTAINER_Heap *heap)
Remove root of the heap.
void GNUNET_CONTAINER_heap_update_cost(struct GNUNET_CONTAINER_HeapNode *node, GNUNET_CONTAINER_HeapCostType new_cost)
Updates the cost of any node in the tree.
struct GNUNET_CONTAINER_HeapNode * GNUNET_CONTAINER_heap_insert(struct GNUNET_CONTAINER_Heap *heap, void *element, GNUNET_CONTAINER_HeapCostType cost)
Inserts a new element into the heap.
unsigned int GNUNET_CONTAINER_heap_get_size(const struct GNUNET_CONTAINER_Heap *heap)
Get the current size of the heap.
struct GNUNET_CONTAINER_Heap * GNUNET_CONTAINER_heap_create(enum GNUNET_CONTAINER_HeapOrder order)
Create a new heap.
void GNUNET_CONTAINER_heap_destroy(struct GNUNET_CONTAINER_Heap *heap)
Destroys the heap.
@ GNUNET_CONTAINER_HEAP_ORDER_MIN
Heap with the minimum cost at the root.
struct GNUNET_HELPER_SendHandle * GNUNET_HELPER_send(struct GNUNET_HELPER_Handle *h, const struct GNUNET_MessageHeader *msg, bool can_drop, GNUNET_HELPER_Continuation cont, void *cont_cls)
Send an message to the helper.
Definition helper.c:639
struct GNUNET_HELPER_Handle * GNUNET_HELPER_start(const struct GNUNET_OS_ProjectData *pd, int with_control_pipe, const char *binary_name, char *const binary_argv[], GNUNET_MessageTokenizerCallback cb, GNUNET_HELPER_ExceptionCallback exp_cb, void *cb_cls)
Starts a helper and begins reading from it.
Definition helper.c:484
void GNUNET_HELPER_stop(struct GNUNET_HELPER_Handle *h, int soft_kill)
Kills the helper, closes the pipe, frees the handle and calls wait() on the helper process.
Definition helper.c:562
#define GNUNET_NETWORK_STRUCT_BEGIN
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_log(kind,...)
#define GNUNET_NETWORK_STRUCT_END
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32;.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to 'struct's.
#define GNUNET_UNUSED
gcc-ism to document unused arguments
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
void GNUNET_log_config_invalid(enum GNUNET_ErrorType kind, const char *section, const char *option, const char *required)
Log error message about invalid configuration option value.
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_strndup(a, length)
Wrapper around GNUNET_xstrndup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition mq.c:305
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
enum GNUNET_GenericReturnValue GNUNET_NETWORK_test_pf(int pf)
Test if the given protocol family is supported by this system.
Definition network.c:79
const struct GNUNET_OS_ProjectData * GNUNET_OS_project_data_gnunet(void)
Return default project data used by 'libgnunetutil' for GNUnet.
enum GNUNET_GenericReturnValue GNUNET_OS_check_helper_binary(const char *binary, bool check_suid, const char *params)
Check whether an executable exists and possibly if the suid bit is set on the file.
char * GNUNET_OS_get_suid_binary_path(const struct GNUNET_OS_ProjectData *pd, const struct GNUNET_CONFIGURATION_Handle *cfg, const char *progname)
Given the name of a helper, service or daemon binary construct the full path to the binary using the ...
enum GNUNET_GenericReturnValue GNUNET_PROGRAM_run(const struct GNUNET_OS_ProjectData *pd, int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls)
Run a standard GNUnet command startup sequence (initialize loggers and configuration,...
Definition program.c:407
#define GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY
Type of messages containing an UDP packet from a remote host.
#define GNUNET_MESSAGE_TYPE_VPN_HELPER
Type of messages between the gnunet-vpn-helper and the daemon.
#define GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT
Type of messages containing an TCP packet of an established connection.
#define GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_SERVICE
Type of messages containing an ICMP packet for a service.
#define GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START
Type of messages containing an TCP packet for the Internet.
#define GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START
Type of messages containing an TCP packet for a service.
#define GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE
Type of messages containing an UDP packet for a service.
#define GNUNET_MESSAGE_TYPE_VPN_DNS_TO_INTERNET
Type of messages containing an DNS request for a DNS exit service.
#define GNUNET_MESSAGE_TYPE_VPN_DNS_FROM_INTERNET
Type of messages containing an DNS reply from a DNS exit service.
#define GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_INTERNET
Type of messages containing an ICMP packet for the Internet.
#define GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_VPN
Type of messages containing an TCP packet of an established connection.
#define GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET
Type of messages containing an UDP packet for the Internet.
#define GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_VPN
Type of messages containing an ICMP packet for the VPN.
char * GNUNET_REGEX_ipv6policy2regex(const char *policy)
Convert an exit policy to a regular expression.
Definition regex.c:725
void GNUNET_REGEX_announce_cancel(struct GNUNET_REGEX_Announcement *a)
Stop announcing the regex specified by the given handle.
struct GNUNET_REGEX_Announcement * GNUNET_REGEX_announce(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *regex, struct GNUNET_TIME_Relative refresh_delay, uint16_t compression)
Announce this peer under the given regular expression.
char * GNUNET_REGEX_ipv4policy2regex(const char *policy)
Convert an exit policy to a regular expression.
Definition regex.c:682
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition scheduler.c:572
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition scheduler.c:1345
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:986
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition scheduler.c:1310
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition scheduler.c:1283
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
#define GNUNET_TIME_UNIT_HOURS
One hour.
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition time.c:406
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition time.c:111
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition time.c:737
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition time.c:316
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition time.c:636
void GNUNET_TUN_initialize_ipv6_header(struct GNUNET_TUN_IPv6Header *ip, uint8_t protocol, uint16_t payload_length, const struct in6_addr *src, const struct in6_addr *dst)
Initialize an IPv6 header.
Definition tun.c:115
void GNUNET_TUN_calculate_udp4_checksum(const struct GNUNET_TUN_IPv4Header *ip, struct GNUNET_TUN_UdpHeader *udp, const void *payload, uint16_t payload_length)
Calculate IPv4 UDP checksum.
Definition tun.c:193
GNUNET_NETWORK_STRUCT_END void GNUNET_TUN_initialize_ipv4_header(struct GNUNET_TUN_IPv4Header *ip, uint8_t protocol, uint16_t payload_length, const struct in_addr *src, const struct in_addr *dst)
Initialize an IPv4 header.
Definition tun.c:80
#define GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM
void GNUNET_TUN_calculate_icmp_checksum(struct GNUNET_TUN_IcmpHeader *icmp, const void *payload, uint16_t payload_length)
Calculate ICMP checksum.
Definition tun.c:255
#define GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST
#define GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED
#define GNUNET_TUN_ICMPTYPE6_ECHO_REPLY
#define ETH_P_IPV6
Number for IPv6.
void GNUNET_TUN_compute_service_cadet_port(const struct GNUNET_HashCode *desc, uint16_t ip_port, struct GNUNET_HashCode *cadet_port)
Compute the CADET port given a service descriptor (returned from GNUNET_TUN_service_name_to_hash) and...
Definition tun.c:57
#define ETH_P_IPV4
Number for IPv4.
#define GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED
void GNUNET_TUN_calculate_tcp6_checksum(const struct GNUNET_TUN_IPv6Header *ip, struct GNUNET_TUN_TcpHeader *tcp, const void *payload, uint16_t payload_length)
Calculate IPv6 TCP checksum.
Definition tun.c:165
void GNUNET_TUN_service_name_to_hash(const char *service_name, struct GNUNET_HashCode *hc)
Hash the service name of a hosted service to the hash code that is used to identify the service on th...
Definition tun.c:38
#define GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE
#define GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH
void GNUNET_TUN_calculate_tcp4_checksum(const struct GNUNET_TUN_IPv4Header *ip, struct GNUNET_TUN_TcpHeader *tcp, const void *payload, uint16_t payload_length)
Calculate IPv4 TCP checksum.
Definition tun.c:135
#define GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE
#define GNUNET_TUN_ICMPTYPE_ECHO_REQUEST
#define GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG
#define GNUNET_TUN_ICMPTYPE_ECHO_REPLY
void GNUNET_TUN_calculate_udp6_checksum(const struct GNUNET_TUN_IPv6Header *ip, struct GNUNET_TUN_UdpHeader *udp, const void *payload, uint16_t payload_length)
Calculate IPv6 UDP checksum.
Definition tun.c:224
static unsigned int size
Size of the "table".
Definition peer.c:68
#define _(String)
GNU gettext support macro.
Definition platform.h:179
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
struct LocalService * serv
Associated service record, or NULL for no service.
uint16_t my_id
DNS request ID that we used for forwarding.
struct GNUNET_HashCode state_key
Key this state has in the connections_map.
union ChannelState::@79 destination_ip
Destination IP address used by the source on our end (this is the IP that we pick freely within the V...
struct ChannelState::@54::@55 tcp_udp
struct GNUNET_DNSSTUB_RequestSocket * rs
Socket we are using to transmit this request (must match if we receive a response).
struct ChannelState::@54::@56 dns
int af
Address family used for this channel on the local TUN interface.
struct GNUNET_CADET_Channel * channel
Cadet channel that is used for this connection.
union ChannelState::@54 specifics
struct GNUNET_PeerIdentity peer
Who is the other end of this channel.
int is_dns
GNUNET_NO if this is a channel for TCP/UDP, GNUNET_YES if this is a channel for DNS,...
struct GNUNET_CONTAINER_HeapNode * heap_node
Heap node for this state in the connections_heap.
uint8_t protocol
IPPROTO_TCP or IPPROTO_UDP once bound.
uint16_t destination_port
Destination port used by the sender on our end; 0 for uninitialized.
uint16_t original_id
Original DNS request ID as used by the client.
struct RedirectInformation ri
Primary redirection information for this connection.
Message with a DNS response.
struct GNUNET_MessageHeader header
GNUnet header, of type GNUNET_MESSAGE_TYPE_VPN_DNS_FROM_INTERNET.
struct GNUNET_TUN_DnsHeader dns
DNS header.
Opaque handle to a channel.
Definition cadet.h:116
Opaque handle to the service.
Definition cadet_api.c:39
Opaque handle to a port.
Definition cadet_api.c:80
Handle to a node in a heap.
Internal representation of the hash map.
an ECC signature using EdDSA.
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!...
Connection to the DHT service.
Definition dht_api.c:235
Handle to a PUT request.
Definition dht_api.c:43
Handle to the stub resolver.
Definition dnsstub.c:125
UDP socket we are using for sending DNS requests to the Internet.
Definition dnsstub.c:46
This is the structure describing an DNS exit service.
Definition block_dns.h:45
struct GNUNET_PeerIdentity peer
The peer providing this service.
Definition block_dns.h:65
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does this signature expire?
Definition block_dns.h:60
struct GNUNET_CRYPTO_SignaturePurpose purpose
Beginning of signed portion of the record, signs everything until the end of the struct.
Definition block_dns.h:55
struct GNUNET_CRYPTO_EddsaSignature signature
Signature of the peer affirming that it is offering the service.
Definition block_dns.h:49
Message send via cadet to an exit daemon to forward ICMP data to the Internet.
Definition exit.h:237
Message send via cadet to an exit daemon to send ICMP data to a local service.
Definition exit.h:206
Message send via cadet to the vpn service to send ICMP data to the VPN's TUN interface.
Definition exit.h:272
struct GNUNET_TUN_IcmpHeader icmp_header
ICMP header to use.
Definition exit.h:287
int32_t af
Address family, AF_INET or AF_INET6, in network byte order.
Definition exit.h:282
Message send via cadet between VPN and entry and an exit daemon to transmit TCP data between the VPN ...
Definition exit.h:95
uint32_t reserved
Always 0.
Definition exit.h:104
struct GNUNET_TUN_TcpHeader tcp_header
Skeleton of the TCP header to send.
Definition exit.h:110
Message send via cadet to an exit daemon to initiate forwarding of TCP data to the Internet.
Definition exit.h:64
Message send via cadet to an exit daemon to initiate forwarding of TCP data to a local service.
Definition exit.h:38
Message send via cadet to an exit daemon to forward UDP data to the Internet.
Definition exit.h:146
Message send from exit daemon back to the UDP entry point (used for both Internet and Service exit re...
Definition exit.h:179
uint16_t source_port
Source port to use for the UDP reply (0 to use the same port as for the original request).
Definition exit.h:189
uint16_t destination_port
Destination port to use for the UDP reply (0 to use the same port as for the original request).
Definition exit.h:195
Message send via cadet to an exit daemon to send UDP data to a local service.
Definition exit.h:121
Definition of a command line option.
Context for parsing HELLOs.
Definition hello-uri.c:233
The handle to a helper process.
Definition helper.c:77
A 512-bit hashcode.
Message handler for a specific message type.
Header for all communications.
A handle for the PILS service.
Definition pils_api.c:82
The identity of the host (wraps the signing key of the peer).
Handle to store cached data about a regex announce.
Entry in list of pending tasks.
Definition scheduler.c:141
Handle for the service.
Time for absolute times used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.
uint16_t id
Unique identifier for the request/response.
Standard IPv4 header.
uint16_t total_length
Length of the packet, including this header.
uint8_t protocol
L4-protocol, for example, IPPROTO_UDP or IPPROTO_TCP.
struct in_addr source_address
Origin of the packet.
struct in_addr destination_address
Destination of the packet.
Standard IPv6 header.
struct in6_addr source_address
Origin of the packet.
uint8_t next_header
For example, IPPROTO_UDP or IPPROTO_TCP.
struct in6_addr destination_address
Destination of the packet.
uint16_t payload_length
Length of the payload, excluding this header.
Header from Linux TUN interface.
uint16_t proto
Here we get an ETH_P_-number.
uint16_t flags
Some flags (unused).
TCP packet header.
uint16_t source_port
Source port (in NBO).
unsigned int off
Number of 32-bit words in TCP header.
UDP packet header.
uint16_t len
Number of bytes of payload.
uint16_t destination_port
Destination port (in NBO).
uint16_t source_port
Source port (in NBO).
This struct is saved into the services-hashmap to represent a service this peer is specifically offer...
int16_t is_udp
GNUNET_YES if this is a UDP service, otherwise TCP.
struct GNUNET_CADET_Port * port
Open port with CADET.
struct SocketAddress address
Remote address to use for the service.
struct GNUNET_HashCode descriptor
Descriptor for the service (CADET port).
char * name
DNS name of the service.
Information we use to track a connection (the classical 6-tuple of IP-version, protocol,...
struct SocketAddress local_address
Address information we used locally (AF and proto must match "remote_address").
struct SocketAddress remote_address
Address information for the other party (equivalent of the arguments one would give to "connect").
Information about an address.
int af
AF_INET or AF_INET6.
union SocketAddress::@53 address
Remote address information.
uint8_t proto
IPPROTO_TCP or IPPROTO_UDP;.
struct in_addr ipv4
Address, if af is AF_INET.
uint16_t port
Remote port, in host byte order!
struct in6_addr ipv6
Address, if af is AF_INET6.
enum GNUNET_TIME_RounderInterval ri
Definition time.c:1251

◆ DHT_PUT_FREQUENCY

#define DHT_PUT_FREQUENCY
Value:

How frequently do we re-announce the DNS exit in the DHT?

Definition at line 73 of file gnunet-daemon-exit.c.

◆ DNS_ADVERTISEMENT_TIMEOUT

#define DNS_ADVERTISEMENT_TIMEOUT
Value:

How long do we typically sign the DNS exit advertisement for?

Definition at line 79 of file gnunet-daemon-exit.c.

◆ LOG

#define LOG (   kind,
  ... 
)     GNUNET_log_from (kind, "exit", __VA_ARGS__);

Generic logging shorthand.

Definition at line 86 of file gnunet-daemon-exit.c.

Function Documentation

◆ process_dns_result()

static GNUNET_NETWORK_STRUCT_END void process_dns_result ( void *  cls,
const struct GNUNET_TUN_DnsHeader dns,
size_t  r 
)
static

Callback called from DNSSTUB resolver when a resolution succeeded.

Parameters
clsNULL
dnsthe response itself
rnumber of bytes in dns

Definition at line 462 of file gnunet-daemon-exit.c.

465{
466 struct ChannelState *ts;
467 struct GNUNET_MQ_Envelope *env;
468 struct DnsResponseMessage *resp;
469
471 "Processing DNS result from stub resolver\n");
472 GNUNET_assert (NULL == cls);
473 if (NULL == dns)
474 return;
475 /* Handle case that this is a reply to a request from a CADET DNS channel */
476 ts = channels[dns->id];
477 if (NULL == ts)
478 return;
480 "Got a response from the stub resolver for DNS request received via CADET!\n");
481 channels[dns->id] = NULL;
482 env = GNUNET_MQ_msg_extra (resp,
483 r - sizeof(struct GNUNET_TUN_DnsHeader),
485 GNUNET_memcpy (&resp->dns,
486 dns,
487 r);
488 resp->dns.id = ts->specifics.dns.original_id;
490 env);
491}

References ChannelState::channel, channels, ChannelState::dns, DnsResponseMessage::dns, env, GNUNET_assert, GNUNET_CADET_get_mq(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_VPN_DNS_FROM_INTERNET, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_TUN_DnsHeader::id, LOG, ChannelState::original_id, and ChannelState::specifics.

Referenced by handle_dns_request().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_dns_request()

static int check_dns_request ( void *  cls,
const struct DnsResponseMessage msg 
)
static

Check a request via cadet to perform a DNS query.

Parameters
clsour struct ChannelState *
msgthe actual message
Returns
GNUNET_OK to keep the connection open, GNUNET_SYSERR to close it (signal serious error)

Definition at line 503 of file gnunet-daemon-exit.c.

505{
506 struct ChannelState *ts = cls;
507
508 if (NULL == dnsstub)
509 {
510 GNUNET_break (0);
511 return GNUNET_SYSERR;
512 }
513 if (GNUNET_NO == ts->is_dns)
514 {
515 GNUNET_break_op (0);
516 return GNUNET_SYSERR;
517 }
518 return GNUNET_OK;
519}

References dnsstub, GNUNET_break, GNUNET_break_op, GNUNET_NO, GNUNET_OK, GNUNET_SYSERR, and ChannelState::is_dns.

◆ handle_dns_request()

static void handle_dns_request ( void *  cls,
const struct DnsResponseMessage msg 
)
static

Process a request via cadet to perform a DNS query.

Parameters
clsour struct ChannelState *
msgthe actual message

Definition at line 529 of file gnunet-daemon-exit.c.

531{
532 struct ChannelState *ts = cls;
533 size_t mlen = ntohs (msg->header.size);
534 size_t dlen = mlen - sizeof(struct GNUNET_MessageHeader);
535 char buf[dlen] GNUNET_ALIGN;
536 struct GNUNET_TUN_DnsHeader *dns_out;
537
538 if (GNUNET_SYSERR == ts->is_dns)
539 {
540 /* channel is DNS from now on */
541 ts->is_dns = GNUNET_YES;
542 }
543 ts->specifics.dns.original_id = msg->dns.id;
544 if (channels[ts->specifics.dns.my_id] == ts)
545 channels[ts->specifics.dns.my_id] = NULL;
548 UINT16_MAX
549 + 1);
550 channels[ts->specifics.dns.my_id] = ts;
551 GNUNET_memcpy (buf,
552 &msg->dns,
553 dlen);
554 dns_out = (struct GNUNET_TUN_DnsHeader *) buf;
555 dns_out->id = ts->specifics.dns.my_id;
557 buf,
558 dlen,
560 NULL);
561 if (NULL == ts->specifics.dns.rs)
562 {
563 GNUNET_break_op (0);
564 return;
565 }
567}

References ChannelState::channel, channels, ChannelState::dns, dnsstub, GNUNET_ALIGN, GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_u32(), GNUNET_DNSSTUB_resolve(), GNUNET_memcpy, GNUNET_SYSERR, GNUNET_YES, GNUNET_TUN_DnsHeader::id, ChannelState::is_dns, msg, ChannelState::my_id, ChannelState::original_id, process_dns_result(), ChannelState::rs, GNUNET_MessageHeader::size, and ChannelState::specifics.

Here is the call graph for this function:

◆ hash_redirect_info()

static void hash_redirect_info ( struct GNUNET_HashCode hash,
const struct RedirectInformation ri 
)
static

Given IP information about a connection, calculate the respective hash we would use for the connections_map.

Parameters
hashresulting hash
riinformation about the connection

Definition at line 578 of file gnunet-daemon-exit.c.

580{
581 char *off;
582
583 memset (hash,
584 0,
585 sizeof(struct GNUNET_HashCode));
586 /* the GNUnet hashmap only uses the first sizeof(unsigned int) of the hash,
587 so we put the IP address in there (and hope for few collisions) */
588 off = (char *) hash;
589 switch (ri->remote_address.af)
590 {
591 case AF_INET:
592 GNUNET_memcpy (off,
593 &ri->remote_address.address.ipv4,
594 sizeof(struct in_addr));
595 off += sizeof(struct in_addr);
596 break;
597
598 case AF_INET6:
599 GNUNET_memcpy (off,
600 &ri->remote_address.address.ipv6,
601 sizeof(struct in6_addr));
602 off += sizeof(struct in_addr);
603 break;
604
605 default:
606 GNUNET_assert (0);
607 }
608 GNUNET_memcpy (off,
609 &ri->remote_address.port,
610 sizeof(uint16_t));
611 off += sizeof(uint16_t);
612 switch (ri->local_address.af)
613 {
614 case AF_INET:
615 GNUNET_memcpy (off,
616 &ri->local_address.address.ipv4,
617 sizeof(struct in_addr));
618 off += sizeof(struct in_addr);
619 break;
620
621 case AF_INET6:
622 GNUNET_memcpy (off,
623 &ri->local_address.address.ipv6,
624 sizeof(struct in6_addr));
625 off += sizeof(struct in_addr);
626 break;
627
628 default:
629 GNUNET_assert (0);
630 }
631 GNUNET_memcpy (off,
632 &ri->local_address.port,
633 sizeof(uint16_t));
634 off += sizeof(uint16_t);
635 GNUNET_memcpy (off,
636 &ri->remote_address.proto,
637 sizeof(uint8_t));
638 /* off += sizeof (uint8_t); */
639}

References GNUNET_assert, GNUNET_memcpy, and ri.

Referenced by get_redirect_state().

Here is the caller graph for this function:

◆ get_redirect_state()

static struct ChannelState * get_redirect_state ( int  af,
int  protocol,
const void *  destination_ip,
uint16_t  destination_port,
const void *  local_ip,
uint16_t  local_port,
struct GNUNET_HashCode state_key 
)
static

Get our connection tracking state.

Warns if it does not exists, refreshes the timestamp if it does exist.

Parameters
afaddress family
protocolIPPROTO_UDP or IPPROTO_TCP
destination_iptarget IP
destination_porttarget port
local_iplocal IP
local_portlocal port
state_keyset to hash's state if non-NULL
Returns
NULL if we have no tracking information for this tuple

Definition at line 656 of file gnunet-daemon-exit.c.

663{
664 struct RedirectInformation ri;
665 struct GNUNET_HashCode key;
666 struct ChannelState *state;
667
668 if (((af == AF_INET) && (protocol == IPPROTO_ICMP)) ||
669 ((af == AF_INET6) && (protocol == IPPROTO_ICMPV6)))
670 {
671 /* ignore ports */
673 local_port = 0;
674 }
675 ri.remote_address.af = af;
676 if (af == AF_INET)
677 ri.remote_address.address.ipv4 = *((struct in_addr*) destination_ip);
678 else
679 ri.remote_address.address.ipv6 = *((struct in6_addr*) destination_ip);
680 ri.remote_address.port = destination_port;
681 ri.remote_address.proto = protocol;
682 ri.local_address.af = af;
683 if (af == AF_INET)
684 ri.local_address.address.ipv4 = *((struct in_addr*) local_ip);
685 else
686 ri.local_address.address.ipv6 = *((struct in6_addr*) local_ip);
687 ri.local_address.port = local_port;
688 ri.local_address.proto = protocol;
690 &ri);
691 if (NULL != state_key)
692 *state_key = key;
694 &key);
695 if (NULL == state)
696 return NULL;
697 /* Mark this connection as freshly used */
698 if (NULL == state_key)
699 GNUNET_CONTAINER_heap_update_cost (state->specifics.tcp_udp.heap_node,
700 GNUNET_TIME_absolute_get ().abs_value_us)
701 ;
702 return state;
703}

References ChannelState::af, connections_map, ChannelState::destination_port, GNUNET_CONTAINER_heap_update_cost(), GNUNET_CONTAINER_multihashmap_get(), GNUNET_TIME_absolute_get(), hash_redirect_info(), key, ChannelState::protocol, ri, and state.

Referenced by icmp_from_helper(), setup_state_record(), tcp_from_helper(), and udp_from_helper().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_tcp_service()

static int check_tcp_service ( void *  cls,
const struct GNUNET_EXIT_TcpServiceStartMessage start 
)
static

Check a request via cadet to send a request to a TCP service offered by this system.

Parameters
clsour struct ChannelState *
startthe actual message
Returns
GNUNET_OK to keep the connection open, GNUNET_SYSERR to close it (signal serious error)

Definition at line 716 of file gnunet-daemon-exit.c.

718{
719 struct ChannelState *state = cls;
720
721 if (NULL == state)
722 {
723 GNUNET_break_op (0);
724 return GNUNET_SYSERR;
725 }
726 if (GNUNET_YES == state->is_dns)
727 {
728 GNUNET_break_op (0);
729 return GNUNET_SYSERR;
730 }
731 if (NULL == state->specifics.tcp_udp.serv)
732 {
733 GNUNET_break_op (0);
734 return GNUNET_SYSERR;
735 }
736 if (NULL != state->specifics.tcp_udp.heap_node)
737 {
738 GNUNET_break_op (0);
739 return GNUNET_SYSERR;
740 }
741 if (start->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
742 {
743 GNUNET_break_op (0);
744 return GNUNET_SYSERR;
745 }
746 return GNUNET_OK;
747}

References GNUNET_break_op, GNUNET_OK, GNUNET_SYSERR, GNUNET_YES, start, and state.

◆ prepare_ipv4_packet()

static void prepare_ipv4_packet ( const void *  payload,
size_t  payload_length,
int  protocol,
const struct GNUNET_TUN_TcpHeader tcp_header,
const struct SocketAddress src_address,
const struct SocketAddress dst_address,
struct GNUNET_TUN_IPv4Header pkt4 
)
static

Prepare an IPv4 packet for transmission via the TUN interface.

Initializes the IP header and calculates checksums (IP+UDP/TCP). For UDP, the UDP header will be fully created, whereas for TCP only the ports and checksum will be filled in. So for TCP, a skeleton TCP header must be part of the provided payload.

Parameters
payloadpayload of the packet (starting with UDP payload or TCP header, depending on protocol)
payload_lengthnumber of bytes in payload
protocolIPPROTO_UDP or IPPROTO_TCP
tcp_headerskeleton of the TCP header, NULL for UDP
src_addresssource address to use (IP and port)
dst_addressdestination address to use (IP and port)
pkt4where to write the assembled packet; must contain enough space for the IP header, UDP/TCP header AND the payload

Definition at line 769 of file gnunet-daemon-exit.c.

776{
777 size_t len;
778
779 len = payload_length;
780 switch (protocol)
781 {
782 case IPPROTO_UDP:
783 len += sizeof(struct GNUNET_TUN_UdpHeader);
784 break;
785
786 case IPPROTO_TCP:
787 len += sizeof(struct GNUNET_TUN_TcpHeader);
788 GNUNET_assert (NULL != tcp_header);
789 break;
790
791 default:
792 GNUNET_break (0);
793 return;
794 }
795 if (len + sizeof(struct GNUNET_TUN_IPv4Header) > UINT16_MAX)
796 {
797 GNUNET_break (0);
798 return;
799 }
800
802 protocol,
803 len,
804 &src_address->address.ipv4,
805 &dst_address->address.ipv4);
806 switch (protocol)
807 {
808 case IPPROTO_UDP:
809 {
810 struct GNUNET_TUN_UdpHeader *pkt4_udp = (struct
811 GNUNET_TUN_UdpHeader *) &pkt4[1];
812
813 pkt4_udp->source_port = htons (src_address->port);
814 pkt4_udp->destination_port = htons (dst_address->port);
815 pkt4_udp->len = htons ((uint16_t) payload_length);
817 pkt4_udp,
818 payload,
819 payload_length);
820 GNUNET_memcpy (&pkt4_udp[1],
821 payload,
822 payload_length);
823 }
824 break;
825
826 case IPPROTO_TCP:
827 {
828 struct GNUNET_TUN_TcpHeader *pkt4_tcp = (struct
830
831 *pkt4_tcp = *tcp_header;
833 "Sending TCP packet from port %u to port %u\n",
834 src_address->port,
835 dst_address->port);
836 pkt4_tcp->source_port = htons (src_address->port);
837 pkt4_tcp->destination_port = htons (dst_address->port);
839 pkt4_tcp,
840 payload,
841 payload_length);
843 payload,
844 payload_length);
845 }
846 break;
847
848 default:
849 GNUNET_assert (0);
850 }
851}

References GNUNET_TUN_UdpHeader::destination_port, GNUNET_assert, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_memcpy, GNUNET_TUN_calculate_tcp4_checksum(), GNUNET_TUN_calculate_udp4_checksum(), GNUNET_TUN_initialize_ipv4_header(), GNUNET_TUN_UdpHeader::len, GNUNET_TUN_TcpHeader::off, payload, SocketAddress::port, ChannelState::protocol, and GNUNET_TUN_UdpHeader::source_port.

Referenced by send_tcp_packet_via_tun(), and send_udp_packet_via_tun().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ prepare_ipv6_packet()

static void prepare_ipv6_packet ( const void *  payload,
size_t  payload_length,
int  protocol,
const struct GNUNET_TUN_TcpHeader tcp_header,
const struct SocketAddress src_address,
const struct SocketAddress dst_address,
struct GNUNET_TUN_IPv6Header pkt6 
)
static

Prepare an IPv6 packet for transmission via the TUN interface.

Initializes the IP header and calculates checksums (IP+UDP/TCP). For UDP, the UDP header will be fully created, whereas for TCP only the ports and checksum will be filled in. So for TCP, a skeleton TCP header must be part of the provided payload.

Parameters
payloadpayload of the packet (starting with UDP payload or TCP header, depending on protocol)
payload_lengthnumber of bytes in payload
protocolIPPROTO_UDP or IPPROTO_TCP
tcp_headerskeleton TCP header data to send, NULL for UDP
src_addresssource address to use (IP and port)
dst_addressdestination address to use (IP and port)
pkt6where to write the assembled packet; must contain enough space for the IP header, UDP/TCP header AND the payload

Definition at line 873 of file gnunet-daemon-exit.c.

880{
881 size_t len;
882
883 len = payload_length;
884 switch (protocol)
885 {
886 case IPPROTO_UDP:
887 len += sizeof(struct GNUNET_TUN_UdpHeader);
888 break;
889
890 case IPPROTO_TCP:
891 len += sizeof(struct GNUNET_TUN_TcpHeader);
892 break;
893
894 default:
895 GNUNET_break (0);
896 return;
897 }
898 if (len > UINT16_MAX)
899 {
900 GNUNET_break (0);
901 return;
902 }
903
905 protocol,
906 len,
907 &src_address->address.ipv6,
908 &dst_address->address.ipv6);
909
910 switch (protocol)
911 {
912 case IPPROTO_UDP:
913 {
914 struct GNUNET_TUN_UdpHeader *pkt6_udp = (struct
915 GNUNET_TUN_UdpHeader *) &pkt6[1];
916
917 pkt6_udp->source_port = htons (src_address->port);
918 pkt6_udp->destination_port = htons (dst_address->port);
919 pkt6_udp->len = htons ((uint16_t) payload_length);
921 pkt6_udp,
922 payload,
923 payload_length);
924 GNUNET_memcpy (&pkt6_udp[1],
925 payload,
926 payload_length);
927 }
928 break;
929
930 case IPPROTO_TCP:
931 {
932 struct GNUNET_TUN_TcpHeader *pkt6_tcp = (struct
934
935 /* GNUNET_memcpy first here as some TCP header fields are initialized this way! */
936 *pkt6_tcp = *tcp_header;
938 pkt6_tcp->destination_port = htons (dst_address->port);
940 pkt6_tcp,
941 payload,
942 payload_length);
944 payload,
945 payload_length);
946 }
947 break;
948
949 default:
950 GNUNET_assert (0);
951 break;
952 }
953}

References GNUNET_TUN_UdpHeader::destination_port, GNUNET_assert, GNUNET_break, GNUNET_memcpy, GNUNET_TUN_calculate_tcp6_checksum(), GNUNET_TUN_calculate_udp6_checksum(), GNUNET_TUN_initialize_ipv6_header(), GNUNET_TUN_UdpHeader::len, GNUNET_TUN_TcpHeader::off, payload, SocketAddress::port, GNUNET_TUN_TcpHeader::source_port, and GNUNET_TUN_UdpHeader::source_port.

Referenced by send_tcp_packet_via_tun(), and send_udp_packet_via_tun().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_tcp_packet_via_tun()

static void send_tcp_packet_via_tun ( const struct SocketAddress destination_address,
const struct SocketAddress source_address,
const struct GNUNET_TUN_TcpHeader tcp_header,
const void *  payload,
size_t  payload_length 
)
static

Send a TCP packet via the TUN interface.

Parameters
destination_addressIP and port to use for the TCP packet's destination
source_addressIP and port to use for the TCP packet's source
tcp_headerheader template to use
payloadpayload of the TCP packet
payload_lengthnumber of bytes in payload

Definition at line 966 of file gnunet-daemon-exit.c.

971{
972 size_t len;
973
975 gettext_noop ("# TCP packets sent via TUN"),
976 1,
977 GNUNET_NO);
979 "Sending packet with %u bytes TCP payload via TUN\n",
980 (unsigned int) payload_length);
981 len = sizeof(struct GNUNET_MessageHeader) + sizeof(struct
983 switch (source_address->af)
984 {
985 case AF_INET:
986 len += sizeof(struct GNUNET_TUN_IPv4Header);
987 break;
988
989 case AF_INET6:
990 len += sizeof(struct GNUNET_TUN_IPv6Header);
991 break;
992
993 default:
994 GNUNET_break (0);
995 return;
996 }
997 len += sizeof(struct GNUNET_TUN_TcpHeader);
998 len += payload_length;
999 if (len >= GNUNET_MAX_MESSAGE_SIZE)
1000 {
1001 GNUNET_break (0);
1002 return;
1003 }
1004 {
1005 char buf[len] GNUNET_ALIGN;
1006 struct GNUNET_MessageHeader *hdr;
1008
1009 hdr = (struct GNUNET_MessageHeader *) buf;
1010 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1011 hdr->size = htons (len);
1012 tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
1013 tun->flags = htons (0);
1014 switch (source_address->af)
1015 {
1016 case AF_INET:
1017 {
1019 = (struct GNUNET_TUN_IPv4Header*) &tun[1];
1020
1021 tun->proto = htons (ETH_P_IPV4);
1023 payload_length,
1024 IPPROTO_TCP,
1025 tcp_header,
1028 ipv4);
1029 }
1030 break;
1031
1032 case AF_INET6:
1033 {
1035 = (struct GNUNET_TUN_IPv6Header*) &tun[1];
1036
1037 tun->proto = htons (ETH_P_IPV6);
1040 IPPROTO_TCP,
1041 tcp_header,
1044 ipv6);
1045 }
1046 break;
1047
1048 default:
1049 GNUNET_assert (0);
1050 break;
1051 }
1052 if (NULL != helper_handle)
1054 (const struct GNUNET_MessageHeader*) buf,
1055 GNUNET_YES,
1056 NULL,
1057 NULL);
1058 }
1059}

References SocketAddress::af, GNUNET_TUN_IPv4Header::destination_address, GNUNET_TUN_IPv6Header::destination_address, ETH_P_IPV4, ETH_P_IPV6, GNUNET_TUN_Layer2PacketHeader::flags, gettext_noop, GNUNET_ALIGN, GNUNET_assert, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_HELPER_send(), GNUNET_log, GNUNET_MAX_MESSAGE_SIZE, GNUNET_MESSAGE_TYPE_VPN_HELPER, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_YES, helper_handle, ipv4, ipv6, payload, GNUNET_TUN_IPv6Header::payload_length, prepare_ipv4_packet(), prepare_ipv6_packet(), GNUNET_TUN_Layer2PacketHeader::proto, GNUNET_MessageHeader::size, GNUNET_TUN_IPv4Header::source_address, GNUNET_TUN_IPv6Header::source_address, stats, and GNUNET_MessageHeader::type.

Referenced by handle_tcp_data(), handle_tcp_remote(), and handle_tcp_service().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_icmp_packet_via_tun()

static void send_icmp_packet_via_tun ( const struct SocketAddress destination_address,
const struct SocketAddress source_address,
const struct GNUNET_TUN_IcmpHeader icmp_header,
const void *  payload,
size_t  payload_length 
)
static

Send an ICMP packet via the TUN interface.

Parameters
destination_addressIP to use for the ICMP packet's destination
source_addressIP to use for the ICMP packet's source
icmp_headerICMP header to send
payloadpayload of the ICMP packet (does NOT include ICMP header)
payload_lengthnumber of bytes of data in payload

Definition at line 1072 of file gnunet-daemon-exit.c.

1076{
1077 size_t len;
1078 struct GNUNET_TUN_IcmpHeader *icmp;
1079
1081 gettext_noop ("# ICMP packets sent via TUN"),
1082 1, GNUNET_NO);
1084 "Sending packet with %u bytes ICMP payload via TUN\n",
1085 (unsigned int) payload_length);
1086 len = sizeof(struct GNUNET_MessageHeader) + sizeof(struct
1088 switch (destination_address->af)
1089 {
1090 case AF_INET:
1091 len += sizeof(struct GNUNET_TUN_IPv4Header);
1092 break;
1093
1094 case AF_INET6:
1095 len += sizeof(struct GNUNET_TUN_IPv6Header);
1096 break;
1097
1098 default:
1099 GNUNET_break (0);
1100 return;
1101 }
1102 len += sizeof(struct GNUNET_TUN_IcmpHeader);
1103 len += payload_length;
1104 if (len >= GNUNET_MAX_MESSAGE_SIZE)
1105 {
1106 GNUNET_break (0);
1107 return;
1108 }
1109 {
1110 char buf[len] GNUNET_ALIGN;
1111 struct GNUNET_MessageHeader *hdr;
1113
1114 hdr = (struct GNUNET_MessageHeader *) buf;
1115 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1116 hdr->size = htons (len);
1117 tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
1118 tun->flags = htons (0);
1119 switch (source_address->af)
1120 {
1121 case AF_INET:
1122 {
1123 struct GNUNET_TUN_IPv4Header *ipv4 = (struct
1124 GNUNET_TUN_IPv4Header*) &tun[1];
1125
1126 tun->proto = htons (ETH_P_IPV4);
1128 IPPROTO_ICMP,
1129 sizeof(struct
1131 + payload_length,
1132 &source_address->address.ipv4,
1133 &destination_address->address.ipv4);
1134 icmp = (struct GNUNET_TUN_IcmpHeader*) &ipv4[1];
1135 }
1136 break;
1137
1138 case AF_INET6:
1139 {
1140 struct GNUNET_TUN_IPv6Header *ipv6 = (struct
1141 GNUNET_TUN_IPv6Header*) &tun[1];
1142
1143 tun->proto = htons (ETH_P_IPV6);
1145 IPPROTO_ICMPV6,
1146 sizeof(struct
1149 &source_address->address.ipv6,
1150 &destination_address->address.ipv6);
1151 icmp = (struct GNUNET_TUN_IcmpHeader*) &ipv6[1];
1152 }
1153 break;
1154
1155 default:
1156 GNUNET_assert (0);
1157 break;
1158 }
1159 *icmp = *icmp_header;
1160 GNUNET_memcpy (&icmp[1],
1161 payload,
1162 payload_length);
1164 payload,
1165 payload_length);
1166 if (NULL != helper_handle)
1168 (const struct GNUNET_MessageHeader*) buf,
1169 GNUNET_YES,
1170 NULL, NULL);
1171 }
1172}

References SocketAddress::af, GNUNET_TUN_IPv4Header::destination_address, GNUNET_TUN_IPv6Header::destination_address, ETH_P_IPV4, ETH_P_IPV6, GNUNET_TUN_Layer2PacketHeader::flags, gettext_noop, GNUNET_ALIGN, GNUNET_assert, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_HELPER_send(), GNUNET_log, GNUNET_MAX_MESSAGE_SIZE, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_VPN_HELPER, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_TUN_calculate_icmp_checksum(), GNUNET_TUN_initialize_ipv4_header(), GNUNET_TUN_initialize_ipv6_header(), GNUNET_YES, helper_handle, ipv4, ipv6, payload, GNUNET_TUN_IPv6Header::payload_length, GNUNET_TUN_Layer2PacketHeader::proto, GNUNET_MessageHeader::size, GNUNET_TUN_IPv4Header::source_address, GNUNET_TUN_IPv6Header::source_address, stats, and GNUNET_MessageHeader::type.

Referenced by handle_icmp_remote(), and handle_icmp_service().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setup_fresh_address()

static void setup_fresh_address ( int  af,
uint8_t  proto,
struct SocketAddress local_address 
)
static

We need to create a (unique) fresh local address (IP+port).

Fill one in.

Parameters
afdesired address family
protodesired protocol (IPPROTO_UDP or IPPROTO_TCP)
local_addressaddress to initialize

Definition at line 1184 of file gnunet-daemon-exit.c.

1187{
1188 local_address->af = af;
1189 local_address->proto = (uint8_t) proto;
1190 /* default "local" port range is often 32768--61000,
1191 so we pick a random value in that range */
1192 if (((af == AF_INET) && (proto == IPPROTO_ICMP)) ||
1193 ((af == AF_INET6) && (proto == IPPROTO_ICMPV6)))
1194 local_address->port = 0;
1195 else
1196 local_address->port
1198 28232);
1199 switch (af)
1200 {
1201 case AF_INET:
1202 {
1203 struct in_addr addr;
1204 struct in_addr mask;
1205 struct in_addr rnd;
1206
1207 addr = exit_ipv4addr;
1208 mask = exit_ipv4mask;
1209 if (0 == ~mask.s_addr)
1210 {
1211 /* only one valid IP anyway */
1212 local_address->address.ipv4 = addr;
1213 return;
1214 }
1215 /* Given 192.168.0.1/255.255.0.0, we want a mask
1216 of '192.168.255.255', thus: */
1217 mask.s_addr = addr.s_addr | ~mask.s_addr;
1218 /* Pick random IPv4 address within the subnet, except 'addr' or 'mask' itself */
1219 do
1220 {
1222 UINT32_MAX);
1223 local_address->address.ipv4.s_addr = (addr.s_addr | rnd.s_addr)
1224 & mask.s_addr;
1225 }
1226 while ((local_address->address.ipv4.s_addr == addr.s_addr) ||
1227 (local_address->address.ipv4.s_addr == mask.s_addr));
1228 }
1229 break;
1230
1231 case AF_INET6:
1232 {
1233 struct in6_addr addr;
1234 struct in6_addr mask;
1235 struct in6_addr rnd;
1236 int i;
1237
1238 addr = exit_ipv6addr;
1239 GNUNET_assert (ipv6prefix < 128);
1240 if (ipv6prefix == 127)
1241 {
1242 /* only one valid IP anyway */
1243 local_address->address.ipv6 = addr;
1244 return;
1245 }
1246 /* Given ABCD::/96, we want a mask of 'ABCD::FFFF:FFFF,
1247 thus: */
1248 mask = addr;
1249 for (i = 127; i >= ipv6prefix; i--)
1250 mask.s6_addr[i / 8] |= (1 << (i % 8));
1251
1252 /* Pick random IPv6 address within the subnet, except 'addr' or 'mask' itself */
1253 do
1254 {
1255 for (i = 0; i < 16; i++)
1256 {
1257 rnd.s6_addr[i] = (unsigned char) GNUNET_CRYPTO_random_u32 (
1259 256);
1260 local_address->address.ipv6.s6_addr[i]
1261 = (addr.s6_addr[i] | rnd.s6_addr[i]) & mask.s6_addr[i];
1262 }
1263 }
1264 while ((0 == GNUNET_memcmp (&local_address->address.ipv6,
1265 &addr)) ||
1266 (0 == GNUNET_memcmp (&local_address->address.ipv6,
1267 &mask)));
1268 }
1269 break;
1270
1271 default:
1272 GNUNET_assert (0);
1273 }
1274}

References SocketAddress::address, SocketAddress::af, exit_ipv4addr, exit_ipv4mask, exit_ipv6addr, GNUNET_assert, GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_u32(), GNUNET_memcmp, SocketAddress::ipv4, SocketAddress::ipv6, ipv6prefix, SocketAddress::port, proto, and SocketAddress::proto.

Referenced by setup_state_record().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setup_state_record()

static void setup_state_record ( struct ChannelState state)
static

We are starting a fresh connection (TCP or UDP) and need to pick a source port and IP address (within the correct range and address family) to associate replies with the connection / correct cadet channel.

This function generates a "fresh" source IP and source port number for a connection After picking a good source address, this function sets up the state in the 'connections_map' and 'connections_heap' to allow finding the state when needed later. The function also makes sure that we remain within memory limits by cleaning up 'old' states.

Parameters
stateskeleton state to setup a record for; should 'state->specifics.tcp_udp.ri.remote_address' filled in so that this code can determine which AF/protocol is going to be used (the 'channel' should also already be set); after calling this function, heap_node and the local_address will be also initialized (heap_node != NULL can be used to test if a state has been fully setup).

Definition at line 1299 of file gnunet-daemon-exit.c.

1300{
1301 struct GNUNET_HashCode key;
1302 struct ChannelState *s;
1303
1304 /* generate fresh, unique address */
1305 do
1306 {
1307 if (NULL == state->specifics.tcp_udp.serv)
1308 setup_fresh_address (state->specifics.tcp_udp.ri.remote_address.af,
1309 state->specifics.tcp_udp.ri.remote_address.proto,
1310 &state->specifics.tcp_udp.ri.local_address);
1311 else
1312 setup_fresh_address (state->specifics.tcp_udp.serv->address.af,
1313 state->specifics.tcp_udp.serv->address.proto,
1314 &state->specifics.tcp_udp.ri.local_address);
1315 }
1316 while (NULL !=
1317 get_redirect_state (state->specifics.tcp_udp.ri.remote_address.af,
1318 state->specifics.tcp_udp.ri.remote_address.proto,
1319 &state->specifics.tcp_udp.ri.remote_address.address
1320 ,
1321 state->specifics.tcp_udp.ri.remote_address.port,
1322 &state->specifics.tcp_udp.ri.local_address.address,
1323 state->specifics.tcp_udp.ri.local_address.port,
1324 &key));
1325 {
1326 char buf[INET6_ADDRSTRLEN];
1328 "Picked local address %s:%u for new connection\n",
1329 inet_ntop (state->specifics.tcp_udp.ri.local_address.af,
1330 &state->specifics.tcp_udp.ri.local_address.address,
1331 buf,
1332 sizeof(buf)),
1333 (unsigned int) state->specifics.tcp_udp.ri.local_address.port);
1334 }
1335 state->specifics.tcp_udp.state_key = key;
1338 &key, state,
1340 state->specifics.tcp_udp.heap_node
1342 state,
1343 GNUNET_TIME_absolute_get ().abs_value_us);
1345 {
1347 GNUNET_assert (state != s);
1348 s->specifics.tcp_udp.heap_node = NULL;
1352 &s->specifics.tcp_udp.
1353 state_key,
1354 s));
1355 GNUNET_free (s);
1356 }
1357}

References ChannelState::channel, connections_heap, connections_map, get_redirect_state(), GNUNET_assert, GNUNET_CADET_channel_destroy(), GNUNET_CONTAINER_heap_get_size(), GNUNET_CONTAINER_heap_insert(), GNUNET_CONTAINER_heap_remove_root(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_multihashmap_remove(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_OK, GNUNET_TIME_absolute_get(), ChannelState::heap_node, key, max_connections, setup_fresh_address(), ChannelState::specifics, state, ChannelState::state_key, and ChannelState::tcp_udp.

Referenced by handle_icmp_remote(), handle_icmp_service(), handle_tcp_remote(), handle_tcp_service(), handle_udp_remote(), and handle_udp_service().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_udp_packet_via_tun()

static void send_udp_packet_via_tun ( const struct SocketAddress destination_address,
const struct SocketAddress source_address,
const void *  payload,
size_t  payload_length 
)
static

Send a UDP packet via the TUN interface.

Parameters
destination_addressIP and port to use for the UDP packet's destination
source_addressIP and port to use for the UDP packet's source
payloadpayload of the UDP packet (does NOT include UDP header)
payload_lengthnumber of bytes of data in payload

Definition at line 1369 of file gnunet-daemon-exit.c.

1372{
1373 size_t len;
1374
1376 gettext_noop ("# UDP packets sent via TUN"),
1377 1, GNUNET_NO);
1379 "Sending packet with %u bytes UDP payload via TUN\n",
1380 (unsigned int) payload_length);
1381 len = sizeof(struct GNUNET_MessageHeader) + sizeof(struct
1383 switch (source_address->af)
1384 {
1385 case AF_INET:
1386 len += sizeof(struct GNUNET_TUN_IPv4Header);
1387 break;
1388
1389 case AF_INET6:
1390 len += sizeof(struct GNUNET_TUN_IPv6Header);
1391 break;
1392
1393 default:
1394 GNUNET_break (0);
1395 return;
1396 }
1397 len += sizeof(struct GNUNET_TUN_UdpHeader);
1398 len += payload_length;
1400 {
1401 GNUNET_break (0);
1402 return;
1403 }
1404 {
1405 char buf[len] GNUNET_ALIGN;
1406 struct GNUNET_MessageHeader *hdr;
1408
1409 hdr = (struct GNUNET_MessageHeader *) buf;
1410 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1411 hdr->size = htons (len);
1412 tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
1413 tun->flags = htons (0);
1414 switch (source_address->af)
1415 {
1416 case AF_INET:
1417 {
1418 struct GNUNET_TUN_IPv4Header *ipv4 = (struct
1419 GNUNET_TUN_IPv4Header*) &tun[1];
1420
1421 tun->proto = htons (ETH_P_IPV4);
1423 payload_length,
1424 IPPROTO_UDP,
1425 NULL,
1428 ipv4);
1429 }
1430 break;
1431
1432 case AF_INET6:
1433 {
1434 struct GNUNET_TUN_IPv6Header *ipv6 = (struct
1435 GNUNET_TUN_IPv6Header*) &tun[1];
1436
1437 tun->proto = htons (ETH_P_IPV6);
1440 IPPROTO_UDP,
1441 NULL,
1444 ipv6);
1445 }
1446 break;
1447
1448 default:
1449 GNUNET_assert (0);
1450 break;
1451 }
1452 if (NULL != helper_handle)
1454 (const struct GNUNET_MessageHeader*) buf,
1455 GNUNET_YES,
1456 NULL, NULL);
1457 }
1458}

References SocketAddress::af, GNUNET_TUN_IPv4Header::destination_address, GNUNET_TUN_IPv6Header::destination_address, ETH_P_IPV4, ETH_P_IPV6, GNUNET_TUN_Layer2PacketHeader::flags, gettext_noop, GNUNET_ALIGN, GNUNET_assert, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_HELPER_send(), GNUNET_log, GNUNET_MAX_MESSAGE_SIZE, GNUNET_MESSAGE_TYPE_VPN_HELPER, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_YES, helper_handle, ipv4, ipv6, GNUNET_TUN_UdpHeader::len, payload, GNUNET_TUN_IPv6Header::payload_length, prepare_ipv4_packet(), prepare_ipv6_packet(), GNUNET_TUN_Layer2PacketHeader::proto, GNUNET_MessageHeader::size, GNUNET_TUN_IPv4Header::source_address, GNUNET_TUN_IPv6Header::source_address, stats, and GNUNET_MessageHeader::type.

Referenced by handle_udp_remote(), and handle_udp_service().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_udp_remote()

static int check_udp_remote ( void *  cls,
const struct GNUNET_EXIT_UdpInternetMessage msg 
)
static

Check a request to forward UDP data to the Internet via this peer.

Parameters
clsour struct ChannelState *
msgthe actual message
Returns
GNUNET_OK to keep the connection open, GNUNET_SYSERR to close it (signal serious error)

Definition at line 1470 of file gnunet-daemon-exit.c.

1472{
1473 struct ChannelState *state = cls;
1474
1475 if (GNUNET_YES == state->is_dns)
1476 {
1477 GNUNET_break_op (0);
1478 return GNUNET_SYSERR;
1479 }
1480 return GNUNET_OK;
1481}

References GNUNET_break_op, GNUNET_OK, GNUNET_SYSERR, GNUNET_YES, and state.

◆ handle_udp_remote()

static void handle_udp_remote ( void *  cls,
const struct GNUNET_EXIT_UdpInternetMessage msg 
)
static

Process a request to forward UDP data to the Internet via this peer.

Parameters
clsour struct ChannelState *
msgthe actual message

Definition at line 1491 of file gnunet-daemon-exit.c.

1493{
1494 struct ChannelState *state = cls;
1495 uint16_t pkt_len = ntohs (msg->header.size) - sizeof(struct
1497 const struct in_addr *v4;
1498 const struct in6_addr *v6;
1499 const void *payload;
1500 int af;
1501
1502 if (GNUNET_SYSERR == state->is_dns)
1503 {
1504 /* channel is UDP/TCP from now on */
1506 }
1508 gettext_noop ("# Bytes received from CADET"),
1509 pkt_len, GNUNET_NO);
1511 gettext_noop (
1512 "# UDP IP-exit requests received via cadet"),
1513 1, GNUNET_NO);
1514 af = (int) ntohl (msg->af);
1515 state->specifics.tcp_udp.ri.remote_address.af = af;
1516 switch (af)
1517 {
1518 case AF_INET:
1519 if (pkt_len < sizeof(struct in_addr))
1520 {
1521 GNUNET_break_op (0);
1522 return;
1523 }
1524 if (! ipv4_exit)
1525 {
1526 GNUNET_break_op (0);
1527 return;
1528 }
1529 v4 = (const struct in_addr*) &msg[1];
1530 payload = &v4[1];
1531 pkt_len -= sizeof(struct in_addr);
1532 state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
1533 break;
1534
1535 case AF_INET6:
1536 if (pkt_len < sizeof(struct in6_addr))
1537 {
1538 GNUNET_break_op (0);
1539 return;
1540 }
1541 if (! ipv6_exit)
1542 {
1543 GNUNET_break_op (0);
1544 return;
1545 }
1546 v6 = (const struct in6_addr*) &msg[1];
1547 payload = &v6[1];
1548 pkt_len -= sizeof(struct in6_addr);
1549 state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
1550 break;
1551
1552 default:
1553 GNUNET_break_op (0);
1554 return;
1555 }
1556 {
1557 char buf[INET6_ADDRSTRLEN];
1559 "Received data from %s for forwarding to UDP %s:%u\n",
1560 GNUNET_i2s (&state->peer),
1561 inet_ntop (af,
1562 &state->specifics.tcp_udp.ri.remote_address.address,
1563 buf, sizeof(buf)),
1564 (unsigned int) ntohs (msg->destination_port));
1565 }
1566 state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_UDP;
1567 state->specifics.tcp_udp.ri.remote_address.port = msg->destination_port;
1568 if (NULL == state->specifics.tcp_udp.heap_node)
1570 if (0 != ntohs (msg->source_port))
1571 state->specifics.tcp_udp.ri.local_address.port = msg->source_port;
1572 send_udp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1573 &state->specifics.tcp_udp.ri.local_address,
1574 payload,
1575 pkt_len);
1577}

References gettext_noop, GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_SYSERR, ipv4_exit, ipv6_exit, ChannelState::is_dns, msg, payload, send_udp_packet_via_tun(), setup_state_record(), GNUNET_MessageHeader::size, state, and stats.

Here is the call graph for this function:

◆ check_udp_service()

static int check_udp_service ( void *  cls,
const struct GNUNET_EXIT_UdpServiceMessage msg 
)
static

Check a request via cadet to send a request to a UDP service offered by this system.

Parameters
clsour struct ChannelState *
msgthe actual message
Returns
GNUNET_OK to keep the connection open, GNUNET_SYSERR to close it (signal serious error)

Definition at line 1590 of file gnunet-daemon-exit.c.

1592{
1593 struct ChannelState *state = cls;
1594
1595 if (NULL == state->specifics.tcp_udp.serv)
1596 {
1597 GNUNET_break_op (0);
1598 return GNUNET_SYSERR;
1599 }
1600 return GNUNET_OK;
1601}

References GNUNET_break_op, GNUNET_OK, GNUNET_SYSERR, and state.

◆ handle_udp_service()

static void handle_udp_service ( void *  cls,
const struct GNUNET_EXIT_UdpServiceMessage msg 
)
static

Process a request via cadet to send a request to a UDP service offered by this system.

Parameters
clsour struct ChannelState *
msgthe actual message

Definition at line 1612 of file gnunet-daemon-exit.c.

1614{
1615 struct ChannelState *state = cls;
1616 uint16_t pkt_len = ntohs (msg->header.size) - sizeof(struct
1618
1620 gettext_noop ("# Bytes received from CADET"),
1621 pkt_len, GNUNET_NO);
1623 gettext_noop (
1624 "# UDP service requests received via cadet"),
1625 1, GNUNET_NO);
1627 "Received data from %s for forwarding to UDP service %s on port %u\n",
1628 GNUNET_i2s (&state->peer),
1629 GNUNET_h2s (&state->specifics.tcp_udp.serv->descriptor),
1630 (unsigned int) ntohs (msg->destination_port));
1632 if (0 != ntohs (msg->source_port))
1633 state->specifics.tcp_udp.ri.local_address.port = msg->source_port;
1634 send_udp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1635 &state->specifics.tcp_udp.ri.local_address,
1636 &msg[1],
1637 pkt_len);
1639}

References gettext_noop, GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_i2s(), GNUNET_NO, GNUNET_STATISTICS_update(), LOG, msg, send_udp_packet_via_tun(), setup_state_record(), GNUNET_MessageHeader::size, state, and stats.

Here is the call graph for this function:

◆ handle_tcp_service()

static void handle_tcp_service ( void *  cls,
const struct GNUNET_EXIT_TcpServiceStartMessage start 
)
static

Process a request via cadet to send a request to a TCP service offered by this system.

Parameters
clsour struct ChannelState *
startthe actual message
Returns
GNUNET_OK to keep the connection open, GNUNET_SYSERR to close it (signal serious error)

Definition at line 1652 of file gnunet-daemon-exit.c.

1654{
1655 struct ChannelState *state = cls;
1656 uint16_t pkt_len = ntohs (start->header.size) - sizeof(struct
1658
1659 if (GNUNET_SYSERR == state->is_dns)
1660 {
1661 /* channel is UDP/TCP from now on */
1663 }
1665 gettext_noop (
1666 "# TCP service creation requests received via cadet"),
1667 1,
1668 GNUNET_NO);
1670 gettext_noop ("# Bytes received from CADET"),
1671 pkt_len,
1672 GNUNET_NO);
1673 GNUNET_break_op (ntohl (start->reserved) == 0);
1674 /* setup fresh connection */
1676 "Received data from %s for forwarding to TCP service %s on port %u\n",
1677 GNUNET_i2s (&state->peer),
1678 GNUNET_h2s (&state->specifics.tcp_udp.serv->descriptor),
1679 (unsigned int) ntohs (start->tcp_header.destination_port));
1681 send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1682 &state->specifics.tcp_udp.ri.local_address,
1683 &start->tcp_header,
1684 &start[1],
1685 pkt_len);
1687}

References gettext_noop, GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_i2s(), GNUNET_log, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_SYSERR, ChannelState::is_dns, send_tcp_packet_via_tun(), setup_state_record(), start, state, and stats.

Here is the call graph for this function:

◆ check_tcp_remote()

static int check_tcp_remote ( void *  cls,
const struct GNUNET_EXIT_TcpInternetStartMessage start 
)
static

Check a request to forward TCP data to the Internet via this peer.

Parameters
clsour struct ChannelState *
startthe actual message
Returns
GNUNET_OK to keep the connection open, GNUNET_SYSERR to close it (signal serious error)

Definition at line 1699 of file gnunet-daemon-exit.c.

1701{
1702 struct ChannelState *state = cls;
1703
1704 if (NULL == state)
1705 {
1706 GNUNET_break_op (0);
1707 return GNUNET_SYSERR;
1708 }
1709 if (GNUNET_YES == state->is_dns)
1710 {
1711 GNUNET_break_op (0);
1712 return GNUNET_SYSERR;
1713 }
1714 if ((NULL != state->specifics.tcp_udp.serv) ||
1715 (NULL != state->specifics.tcp_udp.heap_node))
1716 {
1717 GNUNET_break_op (0);
1718 return GNUNET_SYSERR;
1719 }
1720 if (start->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
1721 {
1722 GNUNET_break_op (0);
1723 return GNUNET_SYSERR;
1724 }
1725 return GNUNET_OK;
1726}

References GNUNET_break_op, GNUNET_OK, GNUNET_SYSERR, GNUNET_YES, start, and state.

◆ handle_tcp_remote()

static void handle_tcp_remote ( void *  cls,
const struct GNUNET_EXIT_TcpInternetStartMessage start 
)
static

Process a request to forward TCP data to the Internet via this peer.

Parameters
clsour struct ChannelState *
startthe actual message

Definition at line 1736 of file gnunet-daemon-exit.c.

1738{
1739 struct ChannelState *state = cls;
1740 uint16_t pkt_len = ntohs (start->header.size) - sizeof(struct
1742 const struct in_addr *v4;
1743 const struct in6_addr *v6;
1744 const void *payload;
1745 int af;
1746
1747 if (GNUNET_SYSERR == state->is_dns)
1748 {
1749 /* channel is UDP/TCP from now on */
1751 }
1753 gettext_noop ("# Bytes received from CADET"),
1754 pkt_len, GNUNET_NO);
1756 gettext_noop (
1757 "# TCP IP-exit creation requests received via cadet"),
1758 1, GNUNET_NO);
1759 af = (int) ntohl (start->af);
1760 state->specifics.tcp_udp.ri.remote_address.af = af;
1761 switch (af)
1762 {
1763 case AF_INET:
1764 if (pkt_len < sizeof(struct in_addr))
1765 {
1766 GNUNET_break_op (0);
1767 return;
1768 }
1769 if (! ipv4_exit)
1770 {
1771 GNUNET_break_op (0);
1772 return;
1773 }
1774 v4 = (const struct in_addr*) &start[1];
1775 payload = &v4[1];
1776 pkt_len -= sizeof(struct in_addr);
1777 state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
1778 break;
1779
1780 case AF_INET6:
1781 if (pkt_len < sizeof(struct in6_addr))
1782 {
1783 GNUNET_break_op (0);
1784 return;
1785 }
1786 if (! ipv6_exit)
1787 {
1788 GNUNET_break_op (0);
1789 return;
1790 }
1791 v6 = (const struct in6_addr*) &start[1];
1792 payload = &v6[1];
1793 pkt_len -= sizeof(struct in6_addr);
1794 state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
1795 break;
1796
1797 default:
1798 GNUNET_break_op (0);
1799 return;
1800 }
1801 {
1802 char buf[INET6_ADDRSTRLEN];
1804 "Received payload from %s for existing TCP stream to %s:%u\n",
1805 GNUNET_i2s (&state->peer),
1806 inet_ntop (af,
1807 &state->specifics.tcp_udp.ri.remote_address.address,
1808 buf, sizeof(buf)),
1809 (unsigned int) ntohs (start->tcp_header.destination_port));
1810 }
1811 state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_TCP;
1812 state->specifics.tcp_udp.ri.remote_address.port = ntohs (
1813 start->tcp_header.destination_port);
1815 send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1816 &state->specifics.tcp_udp.ri.local_address,
1817 &start->tcp_header,
1818 payload,
1819 pkt_len);
1821}

References gettext_noop, GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_SYSERR, ipv4_exit, ipv6_exit, ChannelState::is_dns, payload, send_tcp_packet_via_tun(), setup_state_record(), start, state, and stats.

Here is the call graph for this function:

◆ check_tcp_data()

static int check_tcp_data ( void *  cls,
const struct GNUNET_EXIT_TcpDataMessage data 
)
static

Check a request to forward TCP data on an established connection via this peer.

Parameters
clsour struct ChannelState *
datathe actual message
Returns
GNUNET_OK to keep the connection open, GNUNET_SYSERR to close it (signal serious error)

Definition at line 1834 of file gnunet-daemon-exit.c.

1836{
1837 struct ChannelState *state = cls;
1838
1839 if ((NULL == state) ||
1840 (NULL == state->specifics.tcp_udp.heap_node))
1841 {
1842 /* connection should have been up! */
1844 gettext_noop (
1845 "# TCP DATA requests dropped (no session)"),
1846 1, GNUNET_NO);
1847 GNUNET_break_op (0);
1848 return GNUNET_SYSERR;
1849 }
1850 if (data->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
1851 {
1852 GNUNET_break_op (0);
1853 return GNUNET_SYSERR;
1854 }
1855 if (GNUNET_YES == state->is_dns)
1856 {
1857 GNUNET_break_op (0);
1858 return GNUNET_SYSERR;
1859 }
1860 return GNUNET_OK;
1861}

References data, gettext_noop, GNUNET_break_op, GNUNET_NO, GNUNET_OK, GNUNET_STATISTICS_update(), GNUNET_SYSERR, GNUNET_YES, state, and stats.

Here is the call graph for this function:

◆ handle_tcp_data()

static void handle_tcp_data ( void *  cls,
const struct GNUNET_EXIT_TcpDataMessage data 
)
static

Process a request to forward TCP data on an established connection via this peer.

Parameters
clsour struct ChannelState *
datathe actual message

Definition at line 1872 of file gnunet-daemon-exit.c.

1874{
1875 struct ChannelState *state = cls;
1876 uint16_t pkt_len = ntohs (data->header.size) - sizeof(struct
1878
1880 gettext_noop ("# Bytes received from CADET"),
1881 pkt_len, GNUNET_NO);
1883 gettext_noop (
1884 "# TCP data requests received via cadet"),
1885 1, GNUNET_NO);
1886 if (GNUNET_SYSERR == state->is_dns)
1887 {
1888 /* channel is UDP/TCP from now on */
1889 state->is_dns = GNUNET_NO;
1890 }
1891
1892 GNUNET_break_op (ntohl (data->reserved) == 0);
1893 {
1894 char buf[INET6_ADDRSTRLEN];
1896 "Received additional %u bytes of data from %s for TCP stream to %s:%u\n",
1897 pkt_len,
1898 GNUNET_i2s (&state->peer),
1899 inet_ntop (state->specifics.tcp_udp.ri.remote_address.af,
1900 &state->specifics.tcp_udp.ri.remote_address.address,
1901 buf, sizeof(buf)),
1902 (unsigned int) state->specifics.tcp_udp.ri.remote_address.port);
1903 }
1904
1905 send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1906 &state->specifics.tcp_udp.ri.local_address,
1907 &data->tcp_header,
1908 &data[1], pkt_len);
1910}

References data, gettext_noop, GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_SYSERR, send_tcp_packet_via_tun(), state, and stats.

Here is the call graph for this function:

◆ make_up_icmpv4_payload()

static void make_up_icmpv4_payload ( struct ChannelState state,
struct GNUNET_TUN_IPv4Header ipp,
struct GNUNET_TUN_UdpHeader udp 
)
static

Synthesize a plausible ICMP payload for an ICMPv4 error response on the given channel.

Parameters
statechannel information
ippIPv6 header to fill in (ICMP payload)
udp"UDP" header to fill in (ICMP payload); might actually also be the first 8 bytes of the TCP header

Definition at line 1923 of file gnunet-daemon-exit.c.

1926{
1928 state->specifics.tcp_udp.ri.remote_address.
1929 proto,
1930 sizeof(struct GNUNET_TUN_TcpHeader),
1931 &state->specifics.tcp_udp.ri.remote_address
1932 .address.ipv4,
1933 &state->specifics.tcp_udp.ri.local_address.
1934 address.ipv4);
1935 udp->source_port = htons (state->specifics.tcp_udp.ri.remote_address.port);
1936 udp->destination_port = htons (
1937 state->specifics.tcp_udp.ri.local_address.port);
1938 udp->len = htons (0);
1939 udp->crc = htons (0);
1940}

References address, GNUNET_TUN_initialize_ipv4_header(), proto, state, and udp.

Referenced by handle_icmp_remote(), and make_up_icmp_service_payload().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ make_up_icmpv6_payload()

static void make_up_icmpv6_payload ( struct ChannelState state,
struct GNUNET_TUN_IPv6Header ipp,
struct GNUNET_TUN_UdpHeader udp 
)
static

Synthesize a plausible ICMP payload for an ICMPv6 error response on the given channel.

Parameters
statechannel information
ippIPv6 header to fill in (ICMP payload)
udp"UDP" header to fill in (ICMP payload); might actually also be the first 8 bytes of the TCP header

Definition at line 1953 of file gnunet-daemon-exit.c.

1956{
1958 state->specifics.tcp_udp.ri.remote_address.
1959 proto,
1960 sizeof(struct GNUNET_TUN_TcpHeader),
1961 &state->specifics.tcp_udp.ri.remote_address
1962 .address.ipv6,
1963 &state->specifics.tcp_udp.ri.local_address.
1964 address.ipv6);
1965 udp->source_port = htons (state->specifics.tcp_udp.ri.remote_address.port);
1966 udp->destination_port = htons (
1967 state->specifics.tcp_udp.ri.local_address.port);
1968 udp->len = htons (0);
1969 udp->crc = htons (0);
1970}

References address, GNUNET_TUN_initialize_ipv6_header(), proto, state, and udp.

Referenced by handle_icmp_remote(), and make_up_icmp_service_payload().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_icmp_remote()

static int check_icmp_remote ( void *  cls,
const struct GNUNET_EXIT_IcmpInternetMessage msg 
)
static

Check a request to forward ICMP data to the Internet via this peer.

Parameters
clsour struct ChannelState *
msgthe actual message
Returns
GNUNET_OK to keep the connection open, GNUNET_SYSERR to close it (signal serious error)

Definition at line 1982 of file gnunet-daemon-exit.c.

1984{
1985 struct ChannelState *state = cls;
1986
1987 if (GNUNET_YES == state->is_dns)
1988 {
1989 GNUNET_break_op (0);
1990 return GNUNET_SYSERR;
1991 }
1992 return GNUNET_OK;
1993}

References GNUNET_break_op, GNUNET_OK, GNUNET_SYSERR, GNUNET_YES, and state.

◆ handle_icmp_remote()

static void handle_icmp_remote ( void *  cls,
const struct GNUNET_EXIT_IcmpInternetMessage msg 
)
static

Process a request to forward ICMP data to the Internet via this peer.

Parameters
clsour struct ChannelState *
msgthe actual message

Definition at line 2003 of file gnunet-daemon-exit.c.

2005{
2006 struct ChannelState *state = cls;
2007 uint16_t pkt_len = ntohs (msg->header.size) - sizeof(struct
2009 const struct in_addr *v4;
2010 const struct in6_addr *v6;
2011 const void *payload;
2012 char buf[sizeof(struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
2013 int af;
2014
2015 if (GNUNET_SYSERR == state->is_dns)
2016 {
2017 /* channel is UDP/TCP from now on */
2019 }
2021 gettext_noop ("# Bytes received from CADET"),
2022 pkt_len, GNUNET_NO);
2024 gettext_noop (
2025 "# ICMP IP-exit requests received via cadet"),
2026 1, GNUNET_NO);
2027
2028 af = (int) ntohl (msg->af);
2029 if ((NULL != state->specifics.tcp_udp.heap_node) &&
2030 (af != state->specifics.tcp_udp.ri.remote_address.af))
2031 {
2032 /* other peer switched AF on this channel; not allowed */
2033 GNUNET_break_op (0);
2034 return;
2035 }
2036
2037 switch (af)
2038 {
2039 case AF_INET:
2040 if (pkt_len < sizeof(struct in_addr))
2041 {
2042 GNUNET_break_op (0);
2043 return;
2044 }
2045 if (! ipv4_exit)
2046 {
2047 GNUNET_break_op (0);
2048 return;
2049 }
2050 v4 = (const struct in_addr*) &msg[1];
2051 payload = &v4[1];
2052 pkt_len -= sizeof(struct in_addr);
2053 state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
2054 if (NULL == state->specifics.tcp_udp.heap_node)
2055 {
2056 state->specifics.tcp_udp.ri.remote_address.af = af;
2057 state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_ICMP;
2059 }
2060 /* check that ICMP type is something we want to support
2061 and possibly make up payload! */
2062 switch (msg->icmp_header.type)
2063 {
2066 break;
2067
2071 if (0 != pkt_len)
2072 {
2073 GNUNET_break_op (0);
2074 return;
2075 }
2076 /* make up payload */
2077 {
2078 struct GNUNET_TUN_IPv4Header *ipp = (struct
2079 GNUNET_TUN_IPv4Header *) buf;
2080 struct GNUNET_TUN_UdpHeader *udp = (struct
2081 GNUNET_TUN_UdpHeader *) &ipp[1];
2082
2083 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
2084 pkt_len = sizeof(struct GNUNET_TUN_IPv4Header) + 8;
2086 ipp,
2087 udp);
2088 payload = ipp;
2089 }
2090 break;
2091
2092 default:
2093 GNUNET_break_op (0);
2095 gettext_noop (
2096 "# ICMPv4 packets dropped (type not allowed)")
2097 ,
2098 1, GNUNET_NO);
2099 return;
2100 }
2101 /* end AF_INET */
2102 break;
2103
2104 case AF_INET6:
2105 if (pkt_len < sizeof(struct in6_addr))
2106 {
2107 GNUNET_break_op (0);
2108 return;
2109 }
2110 if (! ipv6_exit)
2111 {
2112 GNUNET_break_op (0);
2113 return;
2114 }
2115 v6 = (const struct in6_addr*) &msg[1];
2116 payload = &v6[1];
2117 pkt_len -= sizeof(struct in6_addr);
2118 state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
2119 if (NULL == state->specifics.tcp_udp.heap_node)
2120 {
2121 state->specifics.tcp_udp.ri.remote_address.af = af;
2122 state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_ICMPV6;
2124 }
2125 /* check that ICMP type is something we want to support
2126 and possibly make up payload! */
2127 switch (msg->icmp_header.type)
2128 {
2131 break;
2132
2137 if (0 != pkt_len)
2138 {
2139 GNUNET_break_op (0);
2140 return;
2141 }
2142 /* make up payload */
2143 {
2144 struct GNUNET_TUN_IPv6Header *ipp = (struct
2145 GNUNET_TUN_IPv6Header *) buf;
2146 struct GNUNET_TUN_UdpHeader *udp = (struct
2147 GNUNET_TUN_UdpHeader *) &ipp[1];
2148
2149 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
2150 pkt_len = sizeof(struct GNUNET_TUN_IPv6Header) + 8;
2152 ipp,
2153 udp);
2154 payload = ipp;
2155 }
2156 break;
2157
2158 default:
2159 GNUNET_break_op (0);
2161 gettext_noop (
2162 "# ICMPv6 packets dropped (type not allowed)")
2163 ,
2164 1, GNUNET_NO);
2165 return;
2166 }
2167 /* end AF_INET6 */
2168 break;
2169
2170 default:
2171 /* bad AF */
2172 GNUNET_break_op (0);
2173 return;
2174 }
2175
2176 {
2177 char buf_tmp[INET6_ADDRSTRLEN];
2179 "Received ICMP data from %s for forwarding to %s\n",
2180 GNUNET_i2s (&state->peer),
2181 inet_ntop (af,
2182 &state->specifics.tcp_udp.ri.remote_address.address,
2183 buf_tmp, sizeof(buf_tmp)));
2184 }
2185 send_icmp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
2186 &state->specifics.tcp_udp.ri.local_address,
2187 &msg->icmp_header,
2188 payload, pkt_len);
2190}

References gettext_noop, GNUNET_ALIGN, GNUNET_assert, GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_SYSERR, GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE, GNUNET_TUN_ICMPTYPE6_ECHO_REPLY, GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST, GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG, GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM, GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED, GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE, GNUNET_TUN_ICMPTYPE_ECHO_REPLY, GNUNET_TUN_ICMPTYPE_ECHO_REQUEST, GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH, GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED, ipv4_exit, ipv6_exit, ChannelState::is_dns, make_up_icmpv4_payload(), make_up_icmpv6_payload(), msg, payload, send_icmp_packet_via_tun(), setup_state_record(), GNUNET_MessageHeader::size, state, stats, GNUNET_MessageHeader::type, and udp.

Here is the call graph for this function:

◆ make_up_icmp_service_payload()

static uint16_t make_up_icmp_service_payload ( struct ChannelState state,
char *  buf 
)
static

Setup ICMP payload for ICMP error messages.

Called for both IPv4 and IPv6 addresses.

Parameters
statecontext for creating the IP Packet
bufwhere to create the payload, has at least sizeof (struct GNUNET_TUN_IPv6Header) + 8 bytes
Returns
number of bytes of payload we created in buf

Definition at line 2203 of file gnunet-daemon-exit.c.

2205{
2206 switch (state->specifics.tcp_udp.serv->address.af)
2207 {
2208 case AF_INET:
2209 {
2211 struct GNUNET_TUN_UdpHeader *udp;
2212
2213 ipv4 = (struct GNUNET_TUN_IPv4Header *) buf;
2214 udp = (struct GNUNET_TUN_UdpHeader *) &ipv4[1];
2216 ipv4,
2217 udp);
2218 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
2219 return sizeof(struct GNUNET_TUN_IPv4Header) + 8;
2220 }
2221 break;
2222
2223 case AF_INET6:
2224 {
2226 struct GNUNET_TUN_UdpHeader *udp;
2227
2228 ipv6 = (struct GNUNET_TUN_IPv6Header *) buf;
2229 udp = (struct GNUNET_TUN_UdpHeader *) &ipv6[1];
2231 ipv6,
2232 udp);
2233 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
2234 return sizeof(struct GNUNET_TUN_IPv6Header) + 8;
2235 }
2236 break;
2237
2238 default:
2239 GNUNET_break (0);
2240 }
2241 return 0;
2242}

References GNUNET_assert, GNUNET_break, ipv4, ipv6, make_up_icmpv4_payload(), make_up_icmpv6_payload(), state, and udp.

Referenced by handle_icmp_service().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_icmp_service()

static int check_icmp_service ( void *  cls,
const struct GNUNET_EXIT_IcmpServiceMessage msg 
)
static

Check a request via cadet to send ICMP data to a service offered by this system.

Parameters
clsour struct ChannelState *
msgthe actual message
Returns
GNUNET_OK to keep the connection open, GNUNET_SYSERR to close it (signal serious error)

Definition at line 2255 of file gnunet-daemon-exit.c.

2257{
2258 struct ChannelState *state = cls;
2259
2260 if (GNUNET_YES == state->is_dns)
2261 {
2262 GNUNET_break_op (0);
2263 return GNUNET_SYSERR;
2264 }
2265 if (NULL == state->specifics.tcp_udp.serv)
2266 {
2267 GNUNET_break_op (0);
2268 return GNUNET_SYSERR;
2269 }
2270 return GNUNET_OK;
2271}

References GNUNET_break_op, GNUNET_OK, GNUNET_SYSERR, GNUNET_YES, and state.

◆ handle_icmp_service()

static void handle_icmp_service ( void *  cls,
const struct GNUNET_EXIT_IcmpServiceMessage msg 
)
static

Process a request via cadet to send ICMP data to a service offered by this system.

Parameters
clsour struct ChannelState *
msgthe actual message

Definition at line 2282 of file gnunet-daemon-exit.c.

2284{
2285 struct ChannelState *state = cls;
2286 uint16_t pkt_len = ntohs (msg->header.size) - sizeof(struct
2288 struct GNUNET_TUN_IcmpHeader icmp;
2289 char buf[sizeof(struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
2290 const void *payload;
2291
2293 gettext_noop ("# Bytes received from CADET"),
2294 pkt_len, GNUNET_NO);
2296 gettext_noop (
2297 "# ICMP service requests received via cadet"),
2298 1, GNUNET_NO);
2299 /* check that we got at least a valid header */
2301 "Received data from %s for forwarding to ICMP service %s\n",
2302 GNUNET_i2s (&state->peer),
2303 GNUNET_h2s (&state->specifics.tcp_udp.serv->descriptor));
2304 icmp = msg->icmp_header;
2305 payload = &msg[1];
2306 state->specifics.tcp_udp.ri.remote_address
2307 = state->specifics.tcp_udp.serv->address;
2309
2310 /* check that ICMP type is something we want to support,
2311 perform ICMP PT if needed and possibly make up payload */
2312 switch (msg->af)
2313 {
2314 case AF_INET:
2315 switch (msg->icmp_header.type)
2316 {
2318 if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2320 break;
2321
2323 if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2325 break;
2326
2328 if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2330 if (0 != pkt_len)
2331 {
2332 GNUNET_break_op (0);
2333 return;
2334 }
2335 payload = buf;
2336 pkt_len = make_up_icmp_service_payload (state, buf);
2337 break;
2338
2340 if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2342 if (0 != pkt_len)
2343 {
2344 GNUNET_break_op (0);
2345 return;
2346 }
2347 payload = buf;
2348 pkt_len = make_up_icmp_service_payload (state, buf);
2349 break;
2350
2352 if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2353 {
2355 gettext_noop (
2356 "# ICMPv4 packets dropped (impossible PT to v6)"),
2357 1, GNUNET_NO);
2358 return;
2359 }
2360 if (0 != pkt_len)
2361 {
2362 GNUNET_break_op (0);
2363 return;
2364 }
2365 payload = buf;
2366 pkt_len = make_up_icmp_service_payload (state, buf);
2367 break;
2368
2369 default:
2370 GNUNET_break_op (0);
2372 gettext_noop (
2373 "# ICMPv4 packets dropped (type not allowed)")
2374 ,
2375 1, GNUNET_NO);
2376 return;
2377 }
2378 /* end of AF_INET */
2379 break;
2380
2381 case AF_INET6:
2382 switch (msg->icmp_header.type)
2383 {
2385 if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2387 break;
2388
2390 if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2392 break;
2393
2395 if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2397 if (0 != pkt_len)
2398 {
2399 GNUNET_break_op (0);
2400 return;
2401 }
2402 payload = buf;
2403 pkt_len = make_up_icmp_service_payload (state, buf);
2404 break;
2405
2407 if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2409 if (0 != pkt_len)
2410 {
2411 GNUNET_break_op (0);
2412 return;
2413 }
2414 payload = buf;
2415 pkt_len = make_up_icmp_service_payload (state, buf);
2416 break;
2417
2420 if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2421 {
2423 gettext_noop (
2424 "# ICMPv6 packets dropped (impossible PT to v4)"),
2425 1, GNUNET_NO);
2426 return;
2427 }
2428 if (0 != pkt_len)
2429 {
2430 GNUNET_break_op (0);
2431 return;
2432 }
2433 payload = buf;
2434 pkt_len = make_up_icmp_service_payload (state, buf);
2435 break;
2436
2437 default:
2438 GNUNET_break_op (0);
2440 gettext_noop (
2441 "# ICMPv6 packets dropped (type not allowed)")
2442 ,
2443 1, GNUNET_NO);
2444 return;
2445 }
2446 /* end of AF_INET6 */
2447 break;
2448
2449 default:
2450 GNUNET_break_op (0);
2451 return;
2452 }
2453
2454 send_icmp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
2455 &state->specifics.tcp_udp.ri.local_address,
2456 &icmp,
2457 payload,
2458 pkt_len);
2460}

References gettext_noop, GNUNET_ALIGN, GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_i2s(), GNUNET_log, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE, GNUNET_TUN_ICMPTYPE6_ECHO_REPLY, GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST, GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG, GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM, GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED, GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE, GNUNET_TUN_ICMPTYPE_ECHO_REPLY, GNUNET_TUN_ICMPTYPE_ECHO_REQUEST, GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH, GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED, make_up_icmp_service_payload(), msg, payload, send_icmp_packet_via_tun(), setup_state_record(), GNUNET_MessageHeader::size, state, stats, GNUNET_MessageHeader::type, and GNUNET_TUN_IcmpHeader::type.

Here is the call graph for this function:

◆ free_service_record()

static int free_service_record ( void *  cls,
const struct GNUNET_HashCode key,
void *  value 
)
static

Free memory associated with a service record.

Parameters
clsunused
keyservice descriptor
valueservice record to free
Returns
GNUNET_OK

Definition at line 2472 of file gnunet-daemon-exit.c.

2475{
2476 struct LocalService *service = value;
2477
2480 key,
2481 service));
2483 GNUNET_free (service->name);
2485 return GNUNET_OK;
2486}

References GNUNET_assert, GNUNET_CADET_close_port(), GNUNET_CONTAINER_multihashmap_remove(), GNUNET_free, GNUNET_OK, GNUNET_YES, key, service, services, and value.

Referenced by cleanup().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ new_service_channel()

static void * new_service_channel ( void *  cls,
struct GNUNET_CADET_Channel channel,
const struct GNUNET_PeerIdentity initiator 
)
static

Callback from CADET for new channels.

Parameters
clsclosure
channelnew handle to the channel
initiatorpeer that started the channel
Returns
initial channel context for the channel

Definition at line 2498 of file gnunet-daemon-exit.c.

2501{
2502 struct LocalService *ls = cls;
2503 struct ChannelState *s = GNUNET_new (struct ChannelState);
2504
2505 s->peer = *initiator;
2507 gettext_noop ("# Inbound CADET channels created"),
2508 1,
2509 GNUNET_NO);
2511 "Received inbound channel from `%s'\n",
2512 GNUNET_i2s (initiator));
2513 s->channel = channel;
2514 s->specifics.tcp_udp.serv = ls;
2515 s->specifics.tcp_udp.ri.remote_address = ls->address;
2516 return s;
2517}

References ChannelState::channel, gettext_noop, GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_new, GNUNET_NO, GNUNET_STATISTICS_update(), ls, ChannelState::peer, RedirectInformation::remote_address, ChannelState::ri, ChannelState::serv, ChannelState::specifics, stats, and ChannelState::tcp_udp.

Referenced by store_service().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ clean_channel()

static void clean_channel ( void *  cls,
const struct GNUNET_CADET_Channel channel 
)
static

Function called by cadet whenever an inbound channel is destroyed.

Should clean up any associated state.

Parameters
clsour struct ChannelState *
channelconnection to the other end (henceforth invalid)

Definition at line 2528 of file gnunet-daemon-exit.c.

2530{
2531 struct ChannelState *s = cls;
2532
2534 "Channel destroyed\n");
2535 if (GNUNET_SYSERR == s->is_dns)
2536 {
2537 GNUNET_free (s);
2538 return;
2539 }
2540 if (GNUNET_YES == s->is_dns)
2541 {
2542 if (channels[s->specifics.dns.my_id] == s)
2543 channels[s->specifics.dns.my_id] = NULL;
2544 }
2545 else
2546 {
2547 if (NULL != s->specifics.tcp_udp.heap_node)
2548 {
2551 &s->specifics.tcp_udp
2552 .state_key,
2553 s));
2555 s->specifics.tcp_udp.heap_node = NULL;
2556 }
2557 }
2558 GNUNET_free (s);
2559}

References channels, connections_map, ChannelState::dns, GNUNET_assert, GNUNET_CONTAINER_heap_remove_node(), GNUNET_CONTAINER_multihashmap_remove(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_SYSERR, GNUNET_YES, ChannelState::heap_node, ChannelState::is_dns, LOG, ChannelState::my_id, ChannelState::specifics, ChannelState::state_key, and ChannelState::tcp_udp.

Referenced by advertise_dns_exit(), run(), and store_service().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ store_service()

static void store_service ( int  proto,
const char *  name,
uint16_t  destination_port,
struct LocalService service 
)
static

Given a service descriptor and a destination port, find the respective service entry.

Parameters
protoIPPROTO_TCP or IPPROTO_UDP
namename of the service
destination_portdestination port
serviceservice information record to store (service->name will be set).

Definition at line 2572 of file gnunet-daemon-exit.c.

2576{
2578 GNUNET_MQ_hd_var_size (icmp_service,
2581 service),
2582 GNUNET_MQ_hd_var_size (udp_service,
2585 service),
2586 GNUNET_MQ_hd_var_size (tcp_service,
2589 service),
2590 GNUNET_MQ_hd_var_size (tcp_data,
2593 service),
2595 };
2596
2598
2599 service->name = GNUNET_strdup (name);
2601 &service->descriptor);
2603 destination_port,
2604 &cadet_port);
2606 "Opening CADET port %s for SERVICE exit %s on port %u\n",
2608 name,
2609 (unsigned int) destination_port);
2611 &cadet_port,
2613 service,
2614 NULL,
2616 handlers);
2617 service->is_udp = (IPPROTO_UDP == proto);
2618 if (GNUNET_OK !=
2620 &cadet_port,
2621 service,
2623 {
2625 GNUNET_free (service->name);
2628 _ ("Got duplicate service records for `%s:%u'\n"),
2629 name,
2630 (unsigned int) destination_port);
2631 }
2632}

References _, cadet_handle, cadet_port, clean_channel(), GNUNET_CADET_close_port(), GNUNET_CADET_open_port(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_h2s(), GNUNET_log, GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_SERVICE, GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT, GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START, GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE, GNUNET_MQ_handler_end, GNUNET_MQ_hd_var_size, GNUNET_OK, GNUNET_strdup, GNUNET_TUN_compute_service_cadet_port(), GNUNET_TUN_service_name_to_hash(), handlers, name, new_service_channel(), proto, service, and services.

Referenced by add_services().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_packet_to_cadet_channel()

static void send_packet_to_cadet_channel ( struct ChannelState s,
struct GNUNET_MQ_Envelope env 
)
static

Send the given packet via the cadet channel.

Parameters
schannel destination
envmessage to queue

Definition at line 2642 of file gnunet-daemon-exit.c.

2644{
2645 GNUNET_assert (NULL != s);
2647 gettext_noop (
2648 "# Messages transmitted via cadet channels"),
2649 1,
2650 GNUNET_NO);
2652 env);
2653}

References ChannelState::channel, env, gettext_noop, GNUNET_assert, GNUNET_CADET_get_mq(), GNUNET_MQ_send(), GNUNET_NO, GNUNET_STATISTICS_update(), and stats.

Referenced by icmp_from_helper(), tcp_from_helper(), and udp_from_helper().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ icmp_from_helper()

static void icmp_from_helper ( const struct GNUNET_TUN_IcmpHeader icmp,
size_t  pktlen,
int  af,
const void *  destination_ip,
const void *  source_ip 
)
static

Handles an ICMP packet received from the helper.

Parameters
icmpA pointer to the Packet
pktlennumber of bytes in icmp
afaddress family (AFINET or AF_INET6)
destination_ipdestination IP-address of the IP packet (should be our local address)
source_iporiginal source IP-address of the IP packet (should be the original destination address)

Definition at line 2668 of file gnunet-daemon-exit.c.

2673{
2674 struct ChannelState *state;
2675 struct GNUNET_MQ_Envelope *env;
2676 struct GNUNET_EXIT_IcmpToVPNMessage *i2v;
2677 const struct GNUNET_TUN_IPv4Header *ipv4;
2678 const struct GNUNET_TUN_IPv6Header *ipv6;
2679 const struct GNUNET_TUN_UdpHeader *udp;
2680 uint16_t source_port;
2681 uint16_t destination_port;
2682 uint8_t protocol;
2683
2684 {
2685 char sbuf[INET6_ADDRSTRLEN];
2686 char dbuf[INET6_ADDRSTRLEN];
2688 "Received ICMP packet going from %s to %s\n",
2689 inet_ntop (af,
2690 source_ip,
2691 sbuf, sizeof(sbuf)),
2692 inet_ntop (af,
2693 destination_ip,
2694 dbuf, sizeof(dbuf)));
2695 }
2696
2697 if (pktlen < sizeof(struct GNUNET_TUN_IcmpHeader))
2698 {
2699 /* blame kernel */
2700 GNUNET_break (0);
2701 return;
2702 }
2703
2704 /* Find out if this is an ICMP packet in response to an existing
2705 TCP/UDP packet and if so, figure out ports / protocol of the
2706 existing session from the IP data in the ICMP payload */
2707 source_port = 0;
2708 destination_port = 0;
2709 switch (af)
2710 {
2711 case AF_INET:
2712 protocol = IPPROTO_ICMP;
2713 switch (icmp->type)
2714 {
2717 break;
2718
2722 if (pktlen <
2723 sizeof(struct GNUNET_TUN_IcmpHeader)
2724 + sizeof(struct GNUNET_TUN_IPv4Header) + 8)
2725 {
2726 /* blame kernel */
2727 GNUNET_break (0);
2728 return;
2729 }
2730 ipv4 = (const struct GNUNET_TUN_IPv4Header *) &icmp[1];
2731 protocol = ipv4->protocol;
2732 /* could be TCP or UDP, but both have the ports in the right
2733 place, so that doesn't matter here */
2734 udp = (const struct GNUNET_TUN_UdpHeader *) &ipv4[1];
2735 /* swap ports, as they are from the original message */
2736 destination_port = ntohs (udp->source_port);
2737 source_port = ntohs (udp->destination_port);
2738 /* throw away ICMP payload, won't be useful for the other side anyway */
2739 pktlen = sizeof(struct GNUNET_TUN_IcmpHeader);
2740 break;
2741
2742 default:
2744 gettext_noop (
2745 "# ICMPv4 packets dropped (type not allowed)")
2746 ,
2747 1, GNUNET_NO);
2748 return;
2749 }
2750 break;
2751
2752 case AF_INET6:
2753 protocol = IPPROTO_ICMPV6;
2754 switch (icmp->type)
2755 {
2760 if (pktlen <
2761 sizeof(struct GNUNET_TUN_IcmpHeader)
2762 + sizeof(struct GNUNET_TUN_IPv6Header) + 8)
2763 {
2764 /* blame kernel */
2765 GNUNET_break (0);
2766 return;
2767 }
2768 ipv6 = (const struct GNUNET_TUN_IPv6Header *) &icmp[1];
2769 protocol = ipv6->next_header;
2770 /* could be TCP or UDP, but both have the ports in the right
2771 place, so that doesn't matter here */
2772 udp = (const struct GNUNET_TUN_UdpHeader *) &ipv6[1];
2773 /* swap ports, as they are from the original message */
2774 destination_port = ntohs (udp->source_port);
2775 source_port = ntohs (udp->destination_port);
2776 /* throw away ICMP payload, won't be useful for the other side anyway */
2777 pktlen = sizeof(struct GNUNET_TUN_IcmpHeader);
2778 break;
2779
2782 break;
2783
2784 default:
2786 gettext_noop (
2787 "# ICMPv6 packets dropped (type not allowed)")
2788 ,
2789 1, GNUNET_NO);
2790 return;
2791 }
2792 break;
2793
2794 default:
2795 GNUNET_assert (0);
2796 }
2797 switch (protocol)
2798 {
2799 case IPPROTO_ICMP:
2801 IPPROTO_ICMP,
2802 source_ip,
2803 0,
2804 destination_ip,
2805 0,
2806 NULL);
2807 break;
2808
2809 case IPPROTO_ICMPV6:
2811 IPPROTO_ICMPV6,
2812 source_ip,
2813 0,
2814 destination_ip,
2815 0,
2816 NULL);
2817 break;
2818
2819 case IPPROTO_UDP:
2821 IPPROTO_UDP,
2822 source_ip,
2823 source_port,
2824 destination_ip,
2825 destination_port,
2826 NULL);
2827 break;
2828
2829 case IPPROTO_TCP:
2831 IPPROTO_TCP,
2832 source_ip,
2833 source_port,
2834 destination_ip,
2835 destination_port,
2836 NULL);
2837 break;
2838
2839 default:
2841 gettext_noop (
2842 "# ICMP packets dropped (not allowed)"),
2843 1,
2844 GNUNET_NO);
2845 return;
2846 }
2847 if (NULL == state)
2848 {
2850 _ (
2851 "ICMP Packet dropped, have no matching connection information\n"));
2852 return;
2853 }
2854 env = GNUNET_MQ_msg_extra (i2v,
2855 pktlen - sizeof(struct GNUNET_TUN_IcmpHeader),
2857 i2v->af = htonl (af);
2859 icmp,
2860 pktlen);
2862 env);
2863}

References _, GNUNET_EXIT_IcmpToVPNMessage::af, GNUNET_TUN_UdpHeader::destination_port, env, get_redirect_state(), gettext_noop, GNUNET_assert, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_INFO, GNUNET_log, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_VPN, GNUNET_MQ_msg_extra, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE, GNUNET_TUN_ICMPTYPE6_ECHO_REPLY, GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST, GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG, GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM, GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED, GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE, GNUNET_TUN_ICMPTYPE_ECHO_REPLY, GNUNET_TUN_ICMPTYPE_ECHO_REQUEST, GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH, GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED, GNUNET_EXIT_IcmpToVPNMessage::icmp_header, ipv4, ipv6, GNUNET_TUN_IPv4Header::protocol, send_packet_to_cadet_channel(), GNUNET_TUN_UdpHeader::source_port, state, stats, GNUNET_TUN_IcmpHeader::type, and udp.

Referenced by message_token().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ udp_from_helper()

static void udp_from_helper ( const struct GNUNET_TUN_UdpHeader udp,
size_t  pktlen,
int  af,
const void *  destination_ip,
const void *  source_ip 
)
static

Handles an UDP packet received from the helper.

Parameters
udpA pointer to the Packet
pktlennumber of bytes in 'udp'
afaddress family (AFINET or AF_INET6)
destination_ipdestination IP-address of the IP packet (should be our local address)
source_iporiginal source IP-address of the IP packet (should be the original destination address)

Definition at line 2878 of file gnunet-daemon-exit.c.

2883{
2884 struct ChannelState *state;
2885 struct GNUNET_MQ_Envelope *env;
2886 struct GNUNET_EXIT_UdpReplyMessage *urm;
2887
2888 {
2889 char sbuf[INET6_ADDRSTRLEN];
2890 char dbuf[INET6_ADDRSTRLEN];
2891
2893 "Received UDP packet going from %s:%u to %s:%u\n",
2894 inet_ntop (af,
2895 source_ip,
2896 sbuf, sizeof(sbuf)),
2897 (unsigned int) ntohs (udp->source_port),
2898 inet_ntop (af,
2899 destination_ip,
2900 dbuf, sizeof(dbuf)),
2901 (unsigned int) ntohs (udp->destination_port));
2902 }
2903
2904 if (pktlen < sizeof(struct GNUNET_TUN_UdpHeader))
2905 {
2906 /* blame kernel */
2907 GNUNET_break (0);
2908 return;
2909 }
2910 if (pktlen != ntohs (udp->len))
2911 {
2912 /* blame kernel */
2913 GNUNET_break (0);
2914 return;
2915 }
2917 IPPROTO_UDP,
2918 source_ip,
2919 ntohs (udp->source_port),
2920 destination_ip,
2921 ntohs (udp->destination_port),
2922 NULL);
2923 if (NULL == state)
2924 {
2926 _ (
2927 "UDP Packet dropped, have no matching connection information\n"));
2928 return;
2929 }
2930 env = GNUNET_MQ_msg_extra (urm,
2931 pktlen - sizeof(struct GNUNET_TUN_UdpHeader),
2933 urm->source_port = htons (0);
2934 urm->destination_port = htons (0);
2935 GNUNET_memcpy (&urm[1],
2936 &udp[1],
2937 pktlen - sizeof(struct GNUNET_TUN_UdpHeader));
2939 env);
2940}

References _, GNUNET_EXIT_UdpReplyMessage::destination_port, env, get_redirect_state(), GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_INFO, GNUNET_log, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY, GNUNET_MQ_msg_extra, send_packet_to_cadet_channel(), GNUNET_EXIT_UdpReplyMessage::source_port, state, and udp.

Referenced by message_token().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ tcp_from_helper()

static void tcp_from_helper ( const struct GNUNET_TUN_TcpHeader tcp,
size_t  pktlen,
int  af,
const void *  destination_ip,
const void *  source_ip 
)
static

Handles a TCP packet received from the helper.

Parameters
tcpA pointer to the Packet
pktlenthe length of the packet, including its TCP header
afaddress family (AFINET or AF_INET6)
destination_ipdestination IP-address of the IP packet (should be our local address)
source_iporiginal source IP-address of the IP packet (should be the original destination address)

Definition at line 2955 of file gnunet-daemon-exit.c.

2960{
2961 struct ChannelState *state;
2962 char buf[pktlen] GNUNET_ALIGN;
2963 struct GNUNET_TUN_TcpHeader *mtcp;
2964 struct GNUNET_EXIT_TcpDataMessage *tdm;
2965 struct GNUNET_MQ_Envelope *env;
2966 size_t mlen;
2967
2968 {
2969 char sbuf[INET6_ADDRSTRLEN];
2970 char dbuf[INET6_ADDRSTRLEN];
2972 "Received TCP packet with %u bytes going from %s:%u to %s:%u\n",
2973 (unsigned int) (pktlen - sizeof(struct GNUNET_TUN_TcpHeader)),
2974 inet_ntop (af,
2975 source_ip,
2976 sbuf, sizeof(sbuf)),
2977 (unsigned int) ntohs (tcp->source_port),
2978 inet_ntop (af,
2979 destination_ip,
2980 dbuf, sizeof(dbuf)),
2981 (unsigned int) ntohs (tcp->destination_port));
2982 }
2983
2984 if (pktlen < sizeof(struct GNUNET_TUN_TcpHeader))
2985 {
2986 /* blame kernel */
2987 GNUNET_break (0);
2988 return;
2989 }
2991 IPPROTO_TCP,
2992 source_ip,
2993 ntohs (tcp->source_port),
2994 destination_ip,
2995 ntohs (tcp->destination_port),
2996 NULL);
2997 if (NULL == state)
2998 {
3000 _ (
3001 "TCP Packet dropped, have no matching connection information\n"));
3002
3003 return;
3004 }
3005 /* mug port numbers and crc to avoid information leakage;
3006 sender will need to lookup the correct values anyway */
3007 GNUNET_memcpy (buf, tcp, pktlen);
3008 mtcp = (struct GNUNET_TUN_TcpHeader *) buf;
3009 mtcp->source_port = 0;
3010 mtcp->destination_port = 0;
3011 mtcp->crc = 0;
3012
3013 mlen = sizeof(struct GNUNET_EXIT_TcpDataMessage) + (pktlen - sizeof(struct
3015 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
3016 {
3017 GNUNET_break (0);
3018 return;
3019 }
3020 env = GNUNET_MQ_msg_extra (tdm,
3021 pktlen - sizeof(struct GNUNET_TUN_TcpHeader),
3023 tdm->reserved = htonl (0);
3025 buf,
3026 pktlen);
3028 env);
3029}

References _, env, get_redirect_state(), GNUNET_ALIGN, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_INFO, GNUNET_log, GNUNET_MAX_MESSAGE_SIZE, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_VPN, GNUNET_MQ_msg_extra, GNUNET_TUN_TcpHeader::off, GNUNET_EXIT_TcpDataMessage::reserved, send_packet_to_cadet_channel(), GNUNET_TUN_TcpHeader::source_port, state, tcp, and GNUNET_EXIT_TcpDataMessage::tcp_header.

Referenced by message_token().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ message_token()

static int message_token ( void *  cls,
const struct GNUNET_MessageHeader message 
)
static

Receive packets from the helper-process.

Parameters
clsunused
messagemessage received from helper

Definition at line 3039 of file gnunet-daemon-exit.c.

3041{
3042 const struct GNUNET_TUN_Layer2PacketHeader *pkt_tun;
3043 size_t size;
3044
3046 "Got %u-byte message of type %u from gnunet-helper-exit\n",
3047 ntohs (message->size),
3048 ntohs (message->type));
3050 gettext_noop ("# Packets received from TUN"),
3051 1, GNUNET_NO);
3052 if (ntohs (message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER)
3053 {
3054 GNUNET_break (0);
3055 return GNUNET_OK;
3056 }
3057 size = ntohs (message->size);
3058 if (size < sizeof(struct GNUNET_TUN_Layer2PacketHeader) + sizeof(struct
3060 {
3061 GNUNET_break (0);
3062 return GNUNET_OK;
3063 }
3065 gettext_noop ("# Bytes received from TUN"),
3066 size, GNUNET_NO);
3067 pkt_tun = (const struct GNUNET_TUN_Layer2PacketHeader *) &message[1];
3068 size -= sizeof(struct GNUNET_TUN_Layer2PacketHeader) + sizeof(struct
3070 switch (ntohs (pkt_tun->proto))
3071 {
3072 case ETH_P_IPV4:
3073 {
3074 const struct GNUNET_TUN_IPv4Header *pkt4;
3075
3076 if (size < sizeof(struct GNUNET_TUN_IPv4Header))
3077 {
3078 /* Kernel to blame? */
3079 GNUNET_break (0);
3080 return GNUNET_OK;
3081 }
3082 pkt4 = (const struct GNUNET_TUN_IPv4Header *) &pkt_tun[1];
3083 if (size != ntohs (pkt4->total_length))
3084 {
3085 /* Kernel to blame? */
3086 GNUNET_break (0);
3087 return GNUNET_OK;
3088 }
3089 if (pkt4->header_length * 4 != sizeof(struct GNUNET_TUN_IPv4Header))
3090 {
3092 _ ("IPv4 packet options received. Ignored.\n"));
3093 return GNUNET_OK;
3094 }
3095
3096 size -= sizeof(struct GNUNET_TUN_IPv4Header);
3097 switch (pkt4->protocol)
3098 {
3099 case IPPROTO_UDP:
3100 udp_from_helper ((const struct GNUNET_TUN_UdpHeader *) &pkt4[1], size,
3101 AF_INET,
3102 &pkt4->destination_address,
3103 &pkt4->source_address);
3104 break;
3105
3106 case IPPROTO_TCP:
3107 tcp_from_helper ((const struct GNUNET_TUN_TcpHeader *) &pkt4[1], size,
3108 AF_INET,
3109 &pkt4->destination_address,
3110 &pkt4->source_address);
3111 break;
3112
3113 case IPPROTO_ICMP:
3114 icmp_from_helper ((const struct GNUNET_TUN_IcmpHeader *) &pkt4[1], size,
3115 AF_INET,
3116 &pkt4->destination_address,
3117 &pkt4->source_address);
3118 break;
3119
3120 default:
3122 _ (
3123 "IPv4 packet with unsupported next header %u received. Ignored.\n"),
3124 (int) pkt4->protocol);
3125 return GNUNET_OK;
3126 }
3127 }
3128 break;
3129
3130 case ETH_P_IPV6:
3131 {
3132 const struct GNUNET_TUN_IPv6Header *pkt6;
3133
3134 if (size < sizeof(struct GNUNET_TUN_IPv6Header))
3135 {
3136 /* Kernel to blame? */
3137 GNUNET_break (0);
3138 return GNUNET_OK;
3139 }
3140 pkt6 = (struct GNUNET_TUN_IPv6Header *) &pkt_tun[1];
3141 if (size != ntohs (pkt6->payload_length) + sizeof(struct
3143 {
3144 /* Kernel to blame? */
3145 GNUNET_break (0);
3146 return GNUNET_OK;
3147 }
3148 size -= sizeof(struct GNUNET_TUN_IPv6Header);
3149 switch (pkt6->next_header)
3150 {
3151 case IPPROTO_UDP:
3152 udp_from_helper ((const struct GNUNET_TUN_UdpHeader *) &pkt6[1], size,
3153 AF_INET6,
3154 &pkt6->destination_address,
3155 &pkt6->source_address);
3156 break;
3157
3158 case IPPROTO_TCP:
3159 tcp_from_helper ((const struct GNUNET_TUN_TcpHeader *) &pkt6[1], size,
3160 AF_INET6,
3161 &pkt6->destination_address,
3162 &pkt6->source_address);
3163 break;
3164
3165 case IPPROTO_ICMPV6:
3166 icmp_from_helper ((const struct GNUNET_TUN_IcmpHeader *) &pkt6[1], size,
3167 AF_INET6,
3168 &pkt6->destination_address,
3169 &pkt6->source_address);
3170 break;
3171
3172 default:
3174 _ (
3175 "IPv6 packet with unsupported next header %d received. Ignored.\n"),
3176 pkt6->next_header);
3177 return GNUNET_OK;
3178 }
3179 }
3180 break;
3181
3182 default:
3184 _ ("Packet from unknown protocol %u received. Ignored.\n"),
3185 ntohs (pkt_tun->proto));
3186 break;
3187 }
3188 return GNUNET_OK;
3189}

References _, ETH_P_IPV4, ETH_P_IPV6, gettext_noop, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_log, GNUNET_MESSAGE_TYPE_VPN_HELPER, GNUNET_NO, GNUNET_OK, GNUNET_STATISTICS_update(), GNUNET_TUN_IPv4Header::header_length, icmp_from_helper(), GNUNET_TUN_IPv6Header::next_header, GNUNET_TUN_IPv6Header::payload_length, GNUNET_TUN_Layer2PacketHeader::proto, GNUNET_TUN_IPv4Header::protocol, GNUNET_MessageHeader::size, size, stats, tcp_from_helper(), GNUNET_TUN_IPv4Header::total_length, GNUNET_MessageHeader::type, and udp_from_helper().

Referenced by run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ new_channel()

static void * new_channel ( void *  cls,
struct GNUNET_CADET_Channel channel,
const struct GNUNET_PeerIdentity initiator 
)
static

Callback from CADET for new channels.

Parameters
clsclosure
channelnew handle to the channel
initiatorpeer that started the channel
Returns
initial channel context for the channel

Definition at line 3201 of file gnunet-daemon-exit.c.

3204{
3205 struct ChannelState *s = GNUNET_new (struct ChannelState);
3206
3207 s->is_dns = GNUNET_SYSERR;
3208 s->peer = *initiator;
3210 gettext_noop ("# Inbound CADET channels created"),
3211 1,
3212 GNUNET_NO);
3214 "Received inbound channel from `%s'\n",
3215 GNUNET_i2s (initiator));
3216 s->channel = channel;
3217 return s;
3218}

References ChannelState::channel, gettext_noop, GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_new, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_SYSERR, ChannelState::is_dns, ChannelState::peer, and stats.

Referenced by advertise_dns_exit(), and run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ free_iterate()

static int free_iterate ( void *  cls,
const struct GNUNET_HashCode hash,
void *  value 
)
static

Function that frees everything from a hashmap.

Parameters
clsunused
hashkey
valuevalue to free

Definition at line 3229 of file gnunet-daemon-exit.c.

3232{
3234 return GNUNET_YES;
3235}

References GNUNET_free, GNUNET_YES, and value.

Referenced by cleanup().

Here is the caller graph for this function:

◆ dummy_task()

static void dummy_task ( void *  cls)
static

Function scheduled as very last function if the service disabled itself because the helper is not installed properly.

Does nothing, except for keeping the service process alive by virtue of being scheduled.

Parameters
clsNULL

Definition at line 3247 of file gnunet-daemon-exit.c.

3248{
3249 /* just terminate */
3250}

Referenced by run().

Here is the caller graph for this function:

◆ cleanup()

static void cleanup ( void *  cls)
static

Function scheduled as very last function, cleans up after us.

Parameters
clsNULL

Definition at line 3259 of file gnunet-daemon-exit.c.

3260{
3261 unsigned int i;
3262
3264 "Exit service is shutting down now\n");
3265
3266 if (NULL != helper_handle)
3267 {
3269 helper_handle = NULL;
3270 }
3271 if (NULL != regex4)
3272 {
3274 regex4 = NULL;
3275 }
3276 if (NULL != regex6)
3277 {
3279 regex6 = NULL;
3280 }
3281 if (NULL != services)
3282 {
3285 NULL);
3287 }
3288 if (NULL != dns_port)
3289 {
3291 dns_port = NULL;
3292 }
3293 if (NULL != cadet_port4)
3294 {
3296 cadet_port4 = NULL;
3297 }
3298 if (NULL != cadet_port6)
3299 {
3301 cadet_port6 = NULL;
3302 }
3303 if (NULL != cadet_handle)
3304 {
3306 cadet_handle = NULL;
3307 }
3308 if (NULL != connections_map)
3309 {
3311 &free_iterate,
3312 NULL);
3314 connections_map = NULL;
3315 }
3316 if (NULL != connections_heap)
3317 {
3319 connections_heap = NULL;
3320 }
3321 if (NULL != dnsstub)
3322 {
3324 dnsstub = NULL;
3325 }
3326 if (NULL != sign_op)
3327 {
3329 sign_op = NULL;
3330 }
3331 if (NULL != pils)
3332 {
3334 pils = NULL;
3335 }
3336 if (NULL != dht_task)
3337 {
3339 dht_task = NULL;
3340 }
3341 if (NULL != dht_put)
3342 {
3344 dht_put = NULL;
3345 }
3346 if (NULL != dht)
3347 {
3349 dht = NULL;
3350 }
3351 if (NULL != stats)
3352 {
3354 GNUNET_NO);
3355 stats = NULL;
3356 }
3357 for (i = 0; i < 8; i++)
3359}

References cadet_handle, cadet_port4, cadet_port6, connections_heap, connections_map, dht, dht_put, dht_task, dns_port, dnsstub, exit_argv, free_iterate(), free_service_record(), GNUNET_CADET_close_port(), GNUNET_CADET_disconnect(), GNUNET_CONTAINER_heap_destroy(), GNUNET_CONTAINER_multihashmap_destroy(), GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_DHT_disconnect(), GNUNET_DHT_put_cancel(), GNUNET_DNSSTUB_stop(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_HELPER_stop(), GNUNET_log, GNUNET_NO, GNUNET_PILS_cancel(), GNUNET_PILS_disconnect(), GNUNET_REGEX_announce_cancel(), GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_destroy(), helper_handle, pils, regex4, regex6, services, sign_op, and stats.

Here is the call graph for this function:

◆ add_services()

static void add_services ( int  proto,
char *  cpy,
const char *  name 
)
static

Add services to the service map.

Parameters
protoIPPROTO_TCP or IPPROTO_UDP
cpycopy of the service descriptor (can be mutilated)
nameDNS name of the service

Definition at line 3370 of file gnunet-daemon-exit.c.

3373{
3374 char *redirect;
3375 char *hostname;
3376 char *hostport;
3377 struct LocalService *serv;
3378 char *n;
3379 size_t slen;
3380 int local_port;
3381 int remote_port;
3382
3383 slen = strlen (name);
3384 GNUNET_assert (slen >= 8);
3385 n = GNUNET_strndup (name, slen - 8 /* remove .gnunet. */);
3386
3387 for (redirect = strtok (cpy, " ;"); redirect != NULL;
3388 redirect = strtok (NULL, " ;"))
3389 {
3390 if (NULL == (hostname = strstr (redirect, ":")))
3391 {
3393 _ (
3394 "Option `%s' for domain `%s' is not formatted correctly!\n")
3395 ,
3396 redirect,
3397 name);
3398 continue;
3399 }
3400 hostname[0] = '\0';
3401 hostname++;
3402 if (NULL == (hostport = strstr (hostname, ":")))
3403 {
3405 _ (
3406 "Option `%s' for domain `%s' is not formatted correctly!\n")
3407 ,
3408 redirect,
3409 name);
3410 continue;
3411 }
3412 hostport[0] = '\0';
3413 hostport++;
3414
3415 local_port = atoi (redirect);
3416 remote_port = atoi (hostport);
3417
3418 if (! ((local_port > 0) && (local_port < 65536)))
3419 {
3421 _ ("`%s' is not a valid port number (for domain `%s')!"),
3422 redirect,
3423 name);
3424 continue;
3425 }
3426 if (! ((remote_port > 0) && (remote_port < 65536)))
3427 {
3429 _ ("`%s' is not a valid port number (for domain `%s')!"),
3430 hostport,
3431 name);
3432 continue;
3433 }
3434
3435 serv = GNUNET_new (struct LocalService);
3436 serv->address.proto = proto;
3437 serv->address.port = remote_port;
3438 if (0 == strcmp ("localhost4",
3439 hostname))
3440 {
3441 const char *ip4addr = exit_argv[5];
3442
3443 serv->address.af = AF_INET;
3444 GNUNET_assert (1 == inet_pton (AF_INET,
3445 ip4addr,
3446 &serv->address.address.ipv4));
3447 }
3448 else if (0 == strcmp ("localhost6",
3449 hostname))
3450 {
3451 const char *ip6addr = exit_argv[3];
3452
3453 serv->address.af = AF_INET6;
3454 GNUNET_assert (1 == inet_pton (AF_INET6,
3455 ip6addr,
3456 &serv->address.address.ipv6));
3457 }
3458 else
3459 {
3460 struct addrinfo *res;
3461 int ret;
3462
3463 ret = getaddrinfo (hostname,
3464 NULL,
3465 NULL,
3466 &res);
3467 if ((0 != ret) || (NULL == res))
3468 {
3470 _ (
3471 "No addresses found for hostname `%s' of service `%s'!\n")
3472 ,
3473 hostname,
3474 n);
3475 GNUNET_free (serv);
3476 continue;
3477 }
3478
3479 serv->address.af = res->ai_family;
3480 switch (res->ai_family)
3481 {
3482 case AF_INET:
3483 if (! ipv4_enabled)
3484 {
3486 _ (
3487 "Service `%s' configured for IPv4, but IPv4 is disabled!\n"),
3488 n);
3489 freeaddrinfo (res);
3490 GNUNET_free (serv);
3491 continue;
3492 }
3493 serv->address.address.ipv4
3494 = ((struct sockaddr_in *) res->ai_addr)->sin_addr;
3495 break;
3496
3497 case AF_INET6:
3498 if (! ipv6_enabled)
3499 {
3501 _ (
3502 "Service `%s' configured for IPv4, but IPv4 is disabled!\n"),
3503 n);
3504 freeaddrinfo (res);
3505 GNUNET_free (serv);
3506 continue;
3507 }
3508 serv->address.address.ipv6
3509 = ((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
3510 break;
3511
3512 default:
3513 freeaddrinfo (res);
3515 _ (
3516 "No IP addresses found for hostname `%s' of service `%s'!\n"),
3517 hostname,
3518 n);
3519 GNUNET_free (serv);
3520 continue;
3521 }
3522 freeaddrinfo (res);
3523 }
3525 n,
3526 local_port,
3527 serv);
3528 }
3529 GNUNET_free (n);
3530}

References _, SocketAddress::address, LocalService::address, SocketAddress::af, exit_argv, GNUNET_assert, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_log, GNUNET_new, GNUNET_strndup, SocketAddress::ipv4, ipv4_enabled, SocketAddress::ipv6, ipv6_enabled, name, SocketAddress::port, proto, SocketAddress::proto, remote_port, res, ret, and store_service().

Referenced by read_service_conf().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ read_service_conf()

static void read_service_conf ( void *  cls,
const char *  section 
)
static

Reads the configuration and populates #udp_services and #tcp_services.

Parameters
clsunused
sectionname of section in config

Definition at line 3540 of file gnunet-daemon-exit.c.

3542{
3543 char *cpy;
3544
3545 if ((strlen (section) < 8) ||
3546 (0 != strcmp (".gnunet.", section + (strlen (section) - 8))))
3547 return;
3548 if (GNUNET_OK ==
3550 section,
3551 "UDP_REDIRECTS",
3552 &cpy))
3553 {
3554 add_services (IPPROTO_UDP,
3555 cpy,
3556 section);
3557 GNUNET_free (cpy);
3558 }
3559 if (GNUNET_OK ==
3561 section,
3562 "TCP_REDIRECTS",
3563 &cpy))
3564 {
3565 add_services (IPPROTO_TCP,
3566 cpy,
3567 section);
3568 GNUNET_free (cpy);
3569 }
3570}

References add_services(), cfg, GNUNET_CONFIGURATION_get_value_string(), GNUNET_free, and GNUNET_OK.

Referenced by run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_dht_put()

static void do_dht_put ( void *  cls)
static

We are running a DNS exit service, advertise it in the DHT.

This task is run periodically to do the DHT PUT.

Parameters
clsclosure

Definition at line 3619 of file gnunet-daemon-exit.c.

References dht, dht_put, dht_put_cont(), DHT_PUT_FREQUENCY, dht_put_key, dht_task, dns_advertisement, DNS_ADVERTISEMENT_TIMEOUT, do_dht_put(), expiration, GNUNET_DNS_Advertisement::expiration_time, GNUNET_BLOCK_TYPE_DNS, GNUNET_DHT_put(), GNUNET_DHT_put_cancel(), GNUNET_DHT_RO_NONE, GNUNET_PILS_cancel(), GNUNET_PILS_sign_by_peer_identity(), GNUNET_SCHEDULER_add_delayed(), GNUNET_TIME_absolute_get_remaining(), GNUNET_TIME_absolute_hton(), GNUNET_TIME_absolute_ntoh(), GNUNET_TIME_relative_to_absolute(), GNUNET_TIME_UNIT_HOURS, pils, GNUNET_TIME_Relative::rel_value_us, sign_dns_advertisement(), and sign_op.

Referenced by do_dht_put(), do_initial_dht_put(), and sign_dns_advertisement().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ dht_put_cont()

static void dht_put_cont ( void *  cls)
static

Function called when the DHT PUT operation is complete.

Schedules the next PUT.

Parameters
clsclosure, NULL

Definition at line 3590 of file gnunet-daemon-exit.c.

3591{
3592 dht_put = NULL;
3593}

References dht_put.

Referenced by do_dht_put().

Here is the caller graph for this function:

◆ sign_dns_advertisement()

static void sign_dns_advertisement ( void *  cls,
const struct GNUNET_PeerIdentity pid,
const struct GNUNET_CRYPTO_EddsaSignature sig 
)
static

Definition at line 3597 of file gnunet-daemon-exit.c.

3600{
3601 GNUNET_assert (sig);
3602
3603 sign_op = NULL;
3604
3606 sizeof (dns_advertisement.signature));
3607
3608 do_dht_put (cls);
3609}

References dns_advertisement, do_dht_put(), GNUNET_assert, GNUNET_memcpy, sign_op, and GNUNET_DNS_Advertisement::signature.

Referenced by do_dht_put().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_initial_dht_put()

static void do_initial_dht_put ( void *  cls,
const struct GNUNET_HELLO_Parser parser,
const struct GNUNET_HashCode hash 
)
static

Definition at line 3658 of file gnunet-daemon-exit.c.

3661{
3662 const struct GNUNET_PeerIdentity *my_identity;
3663
3666
3668 my_identity, sizeof (*my_identity));
3669 dns_advertisement.purpose.size = htonl (sizeof(struct
3671 - sizeof(struct
3673 );
3676 GNUNET_CRYPTO_hash ("dns",
3677 strlen ("dns"),
3678 &dht_put_key);
3679
3680 if (NULL != sign_op)
3681 {
3683 sign_op = NULL;
3684 }
3685
3686 if (NULL != dht_task)
3688
3690 NULL);
3691}

References dht_put_key, dht_task, dns_advertisement, do_dht_put(), GNUNET_assert, GNUNET_CRYPTO_hash(), GNUNET_memcpy, GNUNET_PILS_cancel(), GNUNET_PILS_get_identity(), GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_cancel(), GNUNET_SIGNATURE_PURPOSE_DNS_RECORD, my_identity, GNUNET_DNS_Advertisement::peer, pils, GNUNET_DNS_Advertisement::purpose, GNUNET_CRYPTO_SignaturePurpose::purpose, sign_op, and GNUNET_CRYPTO_SignaturePurpose::size.

Referenced by advertise_dns_exit().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ parse_ip_options()

static void parse_ip_options ( )
static

Figure out which IP versions we should support (and which are supported by the OS) according to our configuration.

Definition at line 3699 of file gnunet-daemon-exit.c.

3700{
3702 "exit",
3703 "EXIT_IPV4");
3705 "exit",
3706 "EXIT_IPV6");
3708 "exit",
3709 "ENABLE_IPV4");
3711 "exit",
3712 "ENABLE_IPV6");
3713 if ((ipv4_exit || ipv4_enabled) &&
3714 (GNUNET_OK != GNUNET_NETWORK_test_pf (PF_INET)) )
3715 {
3717 _ (
3718 "This system does not support IPv4, will disable IPv4 functions despite them being enabled in the configuration\n"));
3721 }
3722 if ((ipv6_exit || ipv6_enabled) &&
3723 (GNUNET_OK != GNUNET_NETWORK_test_pf (PF_INET6)) )
3724 {
3726 _ (
3727 "This system does not support IPv6, will disable IPv6 functions despite them being enabled in the configuration\n"));
3730 }
3731 if (ipv4_exit && (! ipv4_enabled))
3732 {
3734 _ (
3735 "Cannot enable IPv4 exit but disable IPv4 on TUN interface, will use ENABLE_IPv4=YES\n"));
3737 }
3738 if (ipv6_exit && (! ipv6_enabled))
3739 {
3741 _ (
3742 "Cannot enable IPv6 exit but disable IPv6 on TUN interface, will use ENABLE_IPv6=YES\n"));
3744 }
3745}

References _, cfg, GNUNET_CONFIGURATION_get_value_yesno(), GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_NETWORK_test_pf(), GNUNET_NO, GNUNET_OK, GNUNET_YES, ipv4_enabled, ipv4_exit, ipv6_enabled, and ipv6_exit.

Referenced by run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ advertise_dns_exit()

static void advertise_dns_exit ( )
static

Helper function to open the CADET port for DNS exits and to advertise the DNS exit (if applicable).

Definition at line 3753 of file gnunet-daemon-exit.c.

3754{
3756 GNUNET_MQ_hd_var_size (dns_request,
3758 struct DnsResponseMessage,
3759 NULL),
3761 };
3762 char *dns_exit;
3763 struct GNUNET_HashCode port;
3764
3765 if (GNUNET_YES !=
3767 "exit",
3768 "EXIT_DNS"))
3769 return;
3770 GNUNET_assert (NULL != (dnsstub = GNUNET_DNSSTUB_start (128)));
3771 dns_exit = NULL;
3772 /* TODO: support using multiple DNS resolvers */
3773 if ((GNUNET_OK !=
3775 "exit",
3776 "DNS_RESOLVER",
3777 &dns_exit)) ||
3778 (GNUNET_OK !=
3780 dns_exit)))
3781 {
3783 "dns",
3784 "DNS_RESOLVER",
3785 _ ("need a valid IPv4 or IPv6 address\n"));
3786 GNUNET_free (dns_exit);
3787 return;
3788 }
3789 /* open port */
3792 &port);
3794 "Opening CADET port %s for DNS exit service\n",
3795 GNUNET_h2s (&port));
3797 &port,
3798 &new_channel,
3799 NULL,
3800 NULL,
3802 handlers);
3803 /* advertise exit */
3804 dht = GNUNET_DHT_connect (cfg, 1);
3805 dht_task = NULL;
3807 sign_op = NULL;
3808 GNUNET_free (dns_exit);
3809}

References _, cadet_handle, cfg, clean_channel(), dht, dht_task, dns_port, dnsstub, do_initial_dht_put(), GNUNET_APPLICATION_PORT_INTERNET_RESOLVER, GNUNET_assert, GNUNET_CADET_open_port(), GNUNET_CONFIGURATION_get_value_string(), GNUNET_CONFIGURATION_get_value_yesno(), GNUNET_CRYPTO_hash(), GNUNET_DHT_connect(), GNUNET_DNSSTUB_add_dns_ip(), GNUNET_DNSSTUB_start(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_h2s(), GNUNET_log, GNUNET_log_config_invalid(), GNUNET_MESSAGE_TYPE_VPN_DNS_TO_INTERNET, GNUNET_MQ_handler_end, GNUNET_MQ_hd_var_size, GNUNET_OK, GNUNET_PILS_connect(), GNUNET_YES, handlers, new_channel(), pils, port, and sign_op.

Referenced by run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setup_exit_helper_args()

static int setup_exit_helper_args ( )
static

Initialize exit_argv.

Returns
GNUNET_OK on success, GNUNET_SYSERR if we should shutdown

Definition at line 3818 of file gnunet-daemon-exit.c.

3819{
3820 char *exit_ifname;
3821 char *tun_ifname;
3822 char *ipv6addr;
3823 char *ipv6prefix_s;
3824 char *ipv4addr;
3825 char *ipv4mask;
3826
3827 exit_argv[0] = GNUNET_strdup ("exit-gnunet");
3828 if (GNUNET_SYSERR ==
3830 "exit",
3831 "TUN_IFNAME",
3832 &tun_ifname))
3833 {
3835 "EXIT",
3836 "TUN_IFNAME");
3837 return GNUNET_SYSERR;
3838 }
3839 exit_argv[1] = tun_ifname;
3840 if (ipv4_enabled)
3841 {
3842 if (GNUNET_SYSERR ==
3844 "exit",
3845 "EXIT_IFNAME",
3846 &exit_ifname))
3847 {
3849 "EXIT",
3850 "EXIT_IFNAME");
3851 return GNUNET_SYSERR;
3852 }
3853 exit_argv[2] = exit_ifname;
3854 }
3855 else
3856 {
3857 exit_argv[2] = GNUNET_strdup ("-");
3858 }
3859
3860 if (GNUNET_YES == ipv6_enabled)
3861 {
3862 ipv6addr = NULL;
3863 if (((GNUNET_SYSERR ==
3865 "exit",
3866 "IPV6ADDR",
3867 &ipv6addr)) ||
3868 (1 != inet_pton (AF_INET6,
3869 ipv6addr,
3870 &exit_ipv6addr))))
3871 {
3873 "EXIT",
3874 "IPV6ADDR");
3875 GNUNET_free (ipv6addr);
3876 return GNUNET_SYSERR;
3877 }
3878 exit_argv[3] = ipv6addr;
3879 if (GNUNET_SYSERR ==
3881 "exit",
3882 "IPV6PREFIX",
3883 &ipv6prefix_s))
3884 {
3886 "EXIT",
3887 "IPV6PREFIX");
3888 return GNUNET_SYSERR;
3889 }
3890 exit_argv[4] = ipv6prefix_s;
3891 if ((GNUNET_OK !=
3893 "exit",
3894 "IPV6PREFIX",
3895 &ipv6prefix)) ||
3896 (ipv6prefix >= 127))
3897 {
3899 "EXIT",
3900 "IPV6PREFIX",
3901 _ ("Must be a number"));
3902 return GNUNET_SYSERR;
3903 }
3904 }
3905 else
3906 {
3907 /* IPv6 explicitly disabled */
3908 exit_argv[3] = GNUNET_strdup ("-");
3909 exit_argv[4] = GNUNET_strdup ("-");
3910 }
3911 if (GNUNET_YES == ipv4_enabled)
3912 {
3913 ipv4addr = NULL;
3914 if (((GNUNET_SYSERR ==
3916 "exit",
3917 "IPV4ADDR",
3918 &ipv4addr)) ||
3919 (1 != inet_pton (AF_INET,
3920 ipv4addr,
3921 &exit_ipv4addr))))
3922 {
3924 "EXIT",
3925 "IPV4ADDR");
3926 GNUNET_free (ipv4addr);
3927 return GNUNET_SYSERR;
3928 }
3929 exit_argv[5] = ipv4addr;
3930 ipv4mask = NULL;
3931 if (((GNUNET_SYSERR ==
3933 "exit",
3934 "IPV4MASK",
3935 &ipv4mask)) ||
3936 (1 != inet_pton (AF_INET,
3937 ipv4mask,
3938 &exit_ipv4mask))))
3939 {
3941 "EXIT",
3942 "IPV4MASK");
3943 GNUNET_free (ipv4mask);
3944 return GNUNET_SYSERR;
3945 }
3946 exit_argv[6] = ipv4mask;
3947 }
3948 else
3949 {
3950 /* IPv4 explicitly disabled */
3951 exit_argv[5] = GNUNET_strdup ("-");
3952 exit_argv[6] = GNUNET_strdup ("-");
3953 }
3954 exit_argv[7] = NULL;
3955 return GNUNET_OK;
3956}

References _, cfg, exit_argv, exit_ipv4addr, exit_ipv4mask, exit_ipv6addr, GNUNET_CONFIGURATION_get_value_number(), GNUNET_CONFIGURATION_get_value_string(), GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log_config_invalid(), GNUNET_log_config_missing(), GNUNET_OK, GNUNET_strdup, GNUNET_SYSERR, GNUNET_YES, ipv4_enabled, ipv6_enabled, and ipv6prefix.

Referenced by run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ run()

static void run ( void *  cls,
char *const *  args,
const char *  cfgfile,
const struct GNUNET_CONFIGURATION_Handle cfg_ 
)
static

Main function that will be run by the scheduler.

Parameters
clsclosure
argsremaining command-line arguments
cfgfilename of the configuration file used (for saving, can be NULL!)
cfg_configuration

Definition at line 3968 of file gnunet-daemon-exit.c.

3972{
3974 GNUNET_MQ_hd_var_size (icmp_remote,
3977 NULL),
3978 GNUNET_MQ_hd_var_size (udp_remote,
3981 NULL),
3982 GNUNET_MQ_hd_var_size (tcp_remote,
3985 NULL),
3986 GNUNET_MQ_hd_var_size (tcp_data,
3989 NULL),
3991 };
3992 struct GNUNET_HashCode port;
3993 char *policy;
3994 char *binary;
3995 char *regex;
3996 char *prefixed_regex;
3997
3998 cfg = cfg_;
3999 if (GNUNET_OK !=
4001 "exit",
4002 "MAX_CONNECTIONS",
4004 max_connections = 1024;
4007 cfg,
4008 "gnunet-helper-exit");
4009 if ((ipv4_exit) || (ipv6_exit))
4010 {
4011 if (GNUNET_YES !=
4013 GNUNET_YES,
4014 "gnunet-vpn - - - 169.1.3.7 255.255.255.0"))
4015 // no nat, ipv4 only
4016 {
4017 GNUNET_free (binary);
4019 _ (
4020 "`%s' is not SUID or the path is invalid, EXIT will not work\n"),
4021 "gnunet-helper-exit");
4023 NULL);
4024 global_ret = 1;
4025 return;
4026 }
4027 }
4028 if (! (ipv4_enabled || ipv6_enabled))
4029 {
4030 GNUNET_free (binary);
4032 _ ("No useful service enabled. Exiting.\n"));
4034 return;
4035 }
4036
4038 NULL);
4040 cfg);
4042 if (NULL == cadet_handle)
4043 {
4044 GNUNET_free (binary);
4046 return;
4047 }
4049 if (GNUNET_OK !=
4051 {
4052 GNUNET_free (binary);
4054 return;
4055 }
4056
4058 GNUNET_NO);
4060 GNUNET_NO);
4065 NULL);
4066
4067 /* Cadet handle acquired, now open ports and announce regular
4068 expressions matching our exit */
4069 if ((GNUNET_YES == ipv4_enabled) &&
4070 (GNUNET_YES == ipv4_exit))
4071 {
4074 &port);
4076 "Opening CADET port %s for IPv4 gateway service\n",
4077 GNUNET_h2s (&port));
4079 &port,
4080 &new_channel,
4081 NULL,
4082 NULL,
4084 handlers);
4085 policy = NULL;
4086 if (GNUNET_OK !=
4088 "exit",
4089 "EXIT_RANGE_IPV4_POLICY",
4090 &policy))
4091 regex = NULL;
4092 else
4093 regex = GNUNET_REGEX_ipv4policy2regex (policy);
4094 GNUNET_free (policy);
4095 if (NULL != regex)
4096 {
4097 (void) GNUNET_asprintf (&prefixed_regex,
4098 "%s%s",
4100 regex);
4102 prefixed_regex,
4105 GNUNET_free (regex);
4106 GNUNET_free (prefixed_regex);
4107 }
4108 }
4109
4111 {
4114 &port);
4116 "Opening CADET port %s for IPv6 gateway service\n",
4117 GNUNET_h2s (&port));
4119 &port,
4120 &new_channel,
4121 NULL,
4122 NULL,
4124 handlers);
4125 policy = NULL;
4126 if (GNUNET_OK !=
4128 "exit",
4129 "EXIT_RANGE_IPV6_POLICY",
4130 &policy))
4131 regex = NULL;
4132 else
4133 regex = GNUNET_REGEX_ipv6policy2regex (policy);
4134 GNUNET_free (policy);
4135 if (NULL != regex)
4136 {
4137 (void) GNUNET_asprintf (&prefixed_regex,
4138 "%s%s",
4140 regex);
4142 prefixed_regex,
4145 GNUNET_free (regex);
4146 GNUNET_free (prefixed_regex);
4147 }
4148 }
4150 GNUNET_NO,
4151 binary,
4152 exit_argv,
4154 NULL,
4155 NULL);
4156 GNUNET_free (binary);
4157}

References _, advertise_dns_exit(), cadet_handle, cadet_port4, cadet_port6, cfg, clean_channel(), cleanup(), connections_heap, connections_map, dummy_task(), exit_argv, global_ret, GNUNET_APPLICATION_PORT_IPV4_GATEWAY, GNUNET_APPLICATION_PORT_IPV6_GATEWAY, GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX, GNUNET_asprintf(), GNUNET_CADET_connect(), GNUNET_CADET_open_port(), GNUNET_CONFIGURATION_get_value_number(), GNUNET_CONFIGURATION_get_value_string(), GNUNET_CONFIGURATION_iterate_sections(), GNUNET_CONTAINER_heap_create(), GNUNET_CONTAINER_HEAP_ORDER_MIN, GNUNET_CONTAINER_multihashmap_create(), GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_h2s(), GNUNET_HELPER_start(), GNUNET_log, GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_INTERNET, GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT, GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START, GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET, GNUNET_MQ_handler_end, GNUNET_MQ_hd_var_size, GNUNET_NO, GNUNET_OK, GNUNET_OS_check_helper_binary(), GNUNET_OS_get_suid_binary_path(), GNUNET_OS_project_data_gnunet(), GNUNET_REGEX_announce(), GNUNET_REGEX_ipv4policy2regex(), GNUNET_REGEX_ipv6policy2regex(), GNUNET_SCHEDULER_add_shutdown(), GNUNET_SCHEDULER_shutdown(), GNUNET_STATISTICS_create(), GNUNET_YES, handlers, helper_handle, ipv4_enabled, ipv4_exit, ipv6_enabled, ipv6_exit, max_connections, message_token(), new_channel(), parse_ip_options(), port, read_service_conf(), regex4, regex6, REGEX_MAX_PATH_LEN_IPV4, REGEX_MAX_PATH_LEN_IPV6, REGEX_REFRESH_FREQUENCY, services, setup_exit_helper_args(), and stats.

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ main()

int main ( int  argc,
char *const *  argv 
)

The main function.

Parameters
argcnumber of arguments from the command line
argvcommand line arguments
Returns
0 ok, 1 on error

Definition at line 4168 of file gnunet-daemon-exit.c.

4170{
4171 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
4173 };
4174
4175 return (GNUNET_OK ==
4177 argc,
4178 argv,
4179 "gnunet-daemon-exit",
4180 gettext_noop (
4181 "Daemon to run to provide an IP exit node for the VPN"),
4182 options,
4183 &run,
4184 NULL)) ? global_ret : 1;
4185}

References gettext_noop, global_ret, GNUNET_GETOPT_OPTION_END, GNUNET_OK, GNUNET_OS_project_data_gnunet(), GNUNET_PROGRAM_run(), options, and run().

Here is the call graph for this function:

Variable Documentation

◆ global_ret

int global_ret
static

Return value from 'main'.

Definition at line 270 of file gnunet-daemon-exit.c.

Referenced by main(), and run().

◆ regex4

struct GNUNET_REGEX_Announcement* regex4
static

Handle to our regex announcement for IPv4.

Definition at line 275 of file gnunet-daemon-exit.c.

Referenced by cleanup(), and run().

◆ regex6

struct GNUNET_REGEX_Announcement* regex6
static

Handle to our regex announcement for IPv4.

Definition at line 280 of file gnunet-daemon-exit.c.

Referenced by cleanup(), and run().

◆ cfg

const struct GNUNET_CONFIGURATION_Handle* cfg
static

The handle to the configuration used throughout the process.

Definition at line 285 of file gnunet-daemon-exit.c.

Referenced by advertise_dns_exit(), parse_ip_options(), read_service_conf(), run(), and setup_exit_helper_args().

◆ helper_handle

struct GNUNET_HELPER_Handle* helper_handle
static

The handle to the helper.

Definition at line 290 of file gnunet-daemon-exit.c.

Referenced by cleanup(), run(), send_icmp_packet_via_tun(), send_tcp_packet_via_tun(), and send_udp_packet_via_tun().

◆ exit_argv

char* exit_argv[8]
static

Arguments to the exit helper.

Definition at line 295 of file gnunet-daemon-exit.c.

Referenced by add_services(), cleanup(), run(), and setup_exit_helper_args().

◆ exit_ipv6addr

struct in6_addr exit_ipv6addr
static

IPv6 address of our TUN interface.

Definition at line 300 of file gnunet-daemon-exit.c.

Referenced by setup_exit_helper_args(), and setup_fresh_address().

◆ ipv6prefix

unsigned long long ipv6prefix
static

IPv6 prefix (0..127) from configuration file.

Definition at line 305 of file gnunet-daemon-exit.c.

Referenced by run(), setup_exit_helper_args(), and setup_fresh_address().

◆ exit_ipv4addr

struct in_addr exit_ipv4addr
static

IPv4 address of our TUN interface.

Definition at line 310 of file gnunet-daemon-exit.c.

Referenced by setup_exit_helper_args(), and setup_fresh_address().

◆ exit_ipv4mask

struct in_addr exit_ipv4mask
static

IPv4 netmask of our TUN interface.

Definition at line 315 of file gnunet-daemon-exit.c.

Referenced by setup_exit_helper_args(), and setup_fresh_address().

◆ stats

◆ cadet_handle

struct GNUNET_CADET_Handle* cadet_handle
static

The handle to cadet.

Definition at line 325 of file gnunet-daemon-exit.c.

Referenced by advertise_dns_exit(), cleanup(), run(), and store_service().

◆ connections_map

struct GNUNET_CONTAINER_MultiHashMap* connections_map
static

This hashmaps contains the mapping from peer, service-descriptor, source-port and destination-port to a struct ChannelState.

Definition at line 331 of file gnunet-daemon-exit.c.

Referenced by clean_channel(), cleanup(), get_redirect_state(), run(), and setup_state_record().

◆ connections_heap

struct GNUNET_CONTAINER_Heap* connections_heap
static

Heap so we can quickly find "old" connections.

Definition at line 336 of file gnunet-daemon-exit.c.

Referenced by cleanup(), run(), and setup_state_record().

◆ max_connections

unsigned long long max_connections
static

If there are at least this many connections, old ones will be removed.

Definition at line 341 of file gnunet-daemon-exit.c.

Referenced by run(), and setup_state_record().

◆ services

struct GNUNET_CONTAINER_MultiHashMap* services
static

This hashmaps saves interesting things about the configured services.

Definition at line 346 of file gnunet-daemon-exit.c.

Referenced by cleanup(), free_service_record(), GSC_SVCI_add(), GSC_SVCI_remove(), run(), and store_service().

◆ channels

struct ChannelState* channels[UINT16_MAX+1]
static

Array of all open DNS requests from channels.

Definition at line 351 of file gnunet-daemon-exit.c.

Referenced by clean_channel(), handle_dns_request(), and process_dns_result().

◆ dnsstub

struct GNUNET_DNSSTUB_Context* dnsstub
static

Handle to the DNS Stub resolver.

Definition at line 356 of file gnunet-daemon-exit.c.

Referenced by advertise_dns_exit(), check_dns_request(), cleanup(), and handle_dns_request().

◆ dht_put

struct GNUNET_DHT_PutHandle* dht_put
static

Handle for ongoing DHT PUT operations to advertise exit service.

Definition at line 361 of file gnunet-daemon-exit.c.

Referenced by cleanup(), dht_put_cont(), and do_dht_put().

◆ dht

struct GNUNET_DHT_Handle* dht
static

◆ dht_task

struct GNUNET_SCHEDULER_Task* dht_task
static

Task for doing DHT PUTs to advertise exit service.

Definition at line 371 of file gnunet-daemon-exit.c.

Referenced by advertise_dns_exit(), cleanup(), do_dht_put(), and do_initial_dht_put().

◆ dns_advertisement

struct GNUNET_DNS_Advertisement dns_advertisement
static

Advertisement message we put into the DHT to advertise us as a DNS exit.

Definition at line 377 of file gnunet-daemon-exit.c.

Referenced by do_dht_put(), do_initial_dht_put(), and sign_dns_advertisement().

◆ dht_put_key

struct GNUNET_HashCode dht_put_key
static

Key we store the DNS advertismenet under.

Definition at line 382 of file gnunet-daemon-exit.c.

Referenced by do_dht_put(), and do_initial_dht_put().

◆ pils

struct GNUNET_PILS_Handle* pils
static

The pils service handle.

Definition at line 387 of file gnunet-daemon-exit.c.

Referenced by advertise_dns_exit(), cleanup(), do_dht_put(), and do_initial_dht_put().

◆ sign_op

struct GNUNET_PILS_Operation* sign_op
static

Operation for signing the dns advertisement.

Definition at line 392 of file gnunet-daemon-exit.c.

Referenced by advertise_dns_exit(), cleanup(), do_dht_put(), do_initial_dht_put(), and sign_dns_advertisement().

◆ dns_port

struct GNUNET_CADET_Port* dns_port
static

Port for DNS exit.

Definition at line 397 of file gnunet-daemon-exit.c.

Referenced by advertise_dns_exit(), and cleanup().

◆ cadet_port4

struct GNUNET_CADET_Port* cadet_port4
static

Port for IPv4 exit.

Definition at line 402 of file gnunet-daemon-exit.c.

Referenced by cleanup(), and run().

◆ cadet_port6

struct GNUNET_CADET_Port* cadet_port6
static

Port for IPv6 exit.

Definition at line 407 of file gnunet-daemon-exit.c.

Referenced by cleanup(), and run().

◆ ipv4_exit

int ipv4_exit
static

Are we an IPv4-exit?

Definition at line 412 of file gnunet-daemon-exit.c.

Referenced by handle_icmp_remote(), handle_tcp_remote(), handle_udp_remote(), parse_ip_options(), and run().

◆ ipv6_exit

int ipv6_exit
static

Are we an IPv6-exit?

Definition at line 417 of file gnunet-daemon-exit.c.

Referenced by handle_icmp_remote(), handle_tcp_remote(), handle_udp_remote(), parse_ip_options(), and run().

◆ ipv4_enabled

int ipv4_enabled
static

Do we support IPv4 at all on the TUN interface?

Definition at line 422 of file gnunet-daemon-exit.c.

Referenced by add_services(), parse_ip_options(), run(), and setup_exit_helper_args().

◆ ipv6_enabled

int ipv6_enabled
static

Do we support IPv6 at all on the TUN interface?

Definition at line 427 of file gnunet-daemon-exit.c.

Referenced by add_services(), parse_ip_options(), run(), and setup_exit_helper_args().