GNUnet 0.28.0-dev.3-20-gf1136b0b8
 
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;
546 UINT16_MAX
547 + 1);
548 channels[ts->specifics.dns.my_id] = ts;
549 GNUNET_memcpy (buf,
550 &msg->dns,
551 dlen);
552 dns_out = (struct GNUNET_TUN_DnsHeader *) buf;
553 dns_out->id = ts->specifics.dns.my_id;
555 buf,
556 dlen,
558 NULL);
559 if (NULL == ts->specifics.dns.rs)
560 {
561 GNUNET_break_op (0);
562 return;
563 }
565}
566
567
575static void
577 const struct RedirectInformation *ri)
578{
579 char *off;
580
581 memset (hash,
582 0,
583 sizeof(struct GNUNET_HashCode));
584 /* the GNUnet hashmap only uses the first sizeof(unsigned int) of the hash,
585 so we put the IP address in there (and hope for few collisions) */
586 off = (char *) hash;
587 switch (ri->remote_address.af)
588 {
589 case AF_INET:
590 GNUNET_memcpy (off,
591 &ri->remote_address.address.ipv4,
592 sizeof(struct in_addr));
593 off += sizeof(struct in_addr);
594 break;
595
596 case AF_INET6:
597 GNUNET_memcpy (off,
598 &ri->remote_address.address.ipv6,
599 sizeof(struct in6_addr));
600 off += sizeof(struct in_addr);
601 break;
602
603 default:
604 GNUNET_assert (0);
605 }
606 GNUNET_memcpy (off,
607 &ri->remote_address.port,
608 sizeof(uint16_t));
609 off += sizeof(uint16_t);
610 switch (ri->local_address.af)
611 {
612 case AF_INET:
613 GNUNET_memcpy (off,
614 &ri->local_address.address.ipv4,
615 sizeof(struct in_addr));
616 off += sizeof(struct in_addr);
617 break;
618
619 case AF_INET6:
620 GNUNET_memcpy (off,
621 &ri->local_address.address.ipv6,
622 sizeof(struct in6_addr));
623 off += sizeof(struct in_addr);
624 break;
625
626 default:
627 GNUNET_assert (0);
628 }
629 GNUNET_memcpy (off,
630 &ri->local_address.port,
631 sizeof(uint16_t));
632 off += sizeof(uint16_t);
633 GNUNET_memcpy (off,
634 &ri->remote_address.proto,
635 sizeof(uint8_t));
636 /* off += sizeof (uint8_t); */
637}
638
639
653static struct ChannelState *
655 int protocol,
656 const void *destination_ip,
657 uint16_t destination_port,
658 const void *local_ip,
659 uint16_t local_port,
661{
662 struct RedirectInformation ri;
663 struct GNUNET_HashCode key;
664 struct ChannelState *state;
665
666 if (((af == AF_INET) && (protocol == IPPROTO_ICMP)) ||
667 ((af == AF_INET6) && (protocol == IPPROTO_ICMPV6)))
668 {
669 /* ignore ports */
671 local_port = 0;
672 }
673 ri.remote_address.af = af;
674 if (af == AF_INET)
675 ri.remote_address.address.ipv4 = *((struct in_addr*) destination_ip);
676 else
677 ri.remote_address.address.ipv6 = *((struct in6_addr*) destination_ip);
678 ri.remote_address.port = destination_port;
679 ri.remote_address.proto = protocol;
680 ri.local_address.af = af;
681 if (af == AF_INET)
682 ri.local_address.address.ipv4 = *((struct in_addr*) local_ip);
683 else
684 ri.local_address.address.ipv6 = *((struct in6_addr*) local_ip);
685 ri.local_address.port = local_port;
686 ri.local_address.proto = protocol;
688 &ri);
689 if (NULL != state_key)
690 *state_key = key;
692 &key);
693 if (NULL == state)
694 return NULL;
695 /* Mark this connection as freshly used */
696 if (NULL == state_key)
697 GNUNET_CONTAINER_heap_update_cost (state->specifics.tcp_udp.heap_node,
698 GNUNET_TIME_absolute_get ().abs_value_us)
699 ;
700 return state;
701}
702
703
713static int
714check_tcp_service (void *cls,
716{
717 struct ChannelState *state = cls;
718
719 if (NULL == state)
720 {
721 GNUNET_break_op (0);
722 return GNUNET_SYSERR;
723 }
724 if (GNUNET_YES == state->is_dns)
725 {
726 GNUNET_break_op (0);
727 return GNUNET_SYSERR;
728 }
729 if (NULL == state->specifics.tcp_udp.serv)
730 {
731 GNUNET_break_op (0);
732 return GNUNET_SYSERR;
733 }
734 if (NULL != state->specifics.tcp_udp.heap_node)
735 {
736 GNUNET_break_op (0);
737 return GNUNET_SYSERR;
738 }
739 if (start->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
740 {
741 GNUNET_break_op (0);
742 return GNUNET_SYSERR;
743 }
744 return GNUNET_OK;
745}
746
747
766static void
767prepare_ipv4_packet (const void *payload,
768 size_t payload_length,
769 int protocol,
770 const struct GNUNET_TUN_TcpHeader *tcp_header,
771 const struct SocketAddress *src_address,
772 const struct SocketAddress *dst_address,
773 struct GNUNET_TUN_IPv4Header *pkt4)
774{
775 size_t len;
776
777 len = payload_length;
778 switch (protocol)
779 {
780 case IPPROTO_UDP:
781 len += sizeof(struct GNUNET_TUN_UdpHeader);
782 break;
783
784 case IPPROTO_TCP:
785 len += sizeof(struct GNUNET_TUN_TcpHeader);
786 GNUNET_assert (NULL != tcp_header);
787 break;
788
789 default:
790 GNUNET_break (0);
791 return;
792 }
793 if (len + sizeof(struct GNUNET_TUN_IPv4Header) > UINT16_MAX)
794 {
795 GNUNET_break (0);
796 return;
797 }
798
800 protocol,
801 len,
802 &src_address->address.ipv4,
803 &dst_address->address.ipv4);
804 switch (protocol)
805 {
806 case IPPROTO_UDP:
807 {
808 struct GNUNET_TUN_UdpHeader *pkt4_udp = (struct
809 GNUNET_TUN_UdpHeader *) &pkt4[1];
810
811 pkt4_udp->source_port = htons (src_address->port);
812 pkt4_udp->destination_port = htons (dst_address->port);
813 pkt4_udp->len = htons ((uint16_t) payload_length);
815 pkt4_udp,
816 payload,
817 payload_length);
818 GNUNET_memcpy (&pkt4_udp[1],
819 payload,
820 payload_length);
821 }
822 break;
823
824 case IPPROTO_TCP:
825 {
826 struct GNUNET_TUN_TcpHeader *pkt4_tcp = (struct
828
829 *pkt4_tcp = *tcp_header;
831 "Sending TCP packet from port %u to port %u\n",
832 src_address->port,
833 dst_address->port);
834 pkt4_tcp->source_port = htons (src_address->port);
835 pkt4_tcp->destination_port = htons (dst_address->port);
837 pkt4_tcp,
838 payload,
839 payload_length);
841 payload,
842 payload_length);
843 }
844 break;
845
846 default:
847 GNUNET_assert (0);
848 }
849}
850
851
870static void
871prepare_ipv6_packet (const void *payload,
872 size_t payload_length,
873 int protocol,
874 const struct GNUNET_TUN_TcpHeader *tcp_header,
875 const struct SocketAddress *src_address,
876 const struct SocketAddress *dst_address,
878{
879 size_t len;
880
881 len = payload_length;
882 switch (protocol)
883 {
884 case IPPROTO_UDP:
885 len += sizeof(struct GNUNET_TUN_UdpHeader);
886 break;
887
888 case IPPROTO_TCP:
889 len += sizeof(struct GNUNET_TUN_TcpHeader);
890 break;
891
892 default:
893 GNUNET_break (0);
894 return;
895 }
896 if (len > UINT16_MAX)
897 {
898 GNUNET_break (0);
899 return;
900 }
901
903 protocol,
904 len,
905 &src_address->address.ipv6,
906 &dst_address->address.ipv6);
907
908 switch (protocol)
909 {
910 case IPPROTO_UDP:
911 {
912 struct GNUNET_TUN_UdpHeader *pkt6_udp = (struct
913 GNUNET_TUN_UdpHeader *) &pkt6[1];
914
915 pkt6_udp->source_port = htons (src_address->port);
916 pkt6_udp->destination_port = htons (dst_address->port);
917 pkt6_udp->len = htons ((uint16_t) payload_length);
919 pkt6_udp,
920 payload,
921 payload_length);
922 GNUNET_memcpy (&pkt6_udp[1],
923 payload,
924 payload_length);
925 }
926 break;
927
928 case IPPROTO_TCP:
929 {
930 struct GNUNET_TUN_TcpHeader *pkt6_tcp = (struct
932
933 /* GNUNET_memcpy first here as some TCP header fields are initialized this way! */
934 *pkt6_tcp = *tcp_header;
936 pkt6_tcp->destination_port = htons (dst_address->port);
938 pkt6_tcp,
939 payload,
940 payload_length);
942 payload,
943 payload_length);
944 }
945 break;
946
947 default:
948 GNUNET_assert (0);
949 break;
950 }
951}
952
953
963static void
964send_tcp_packet_via_tun (const struct SocketAddress *destination_address,
965 const struct SocketAddress *source_address,
966 const struct GNUNET_TUN_TcpHeader *tcp_header,
967 const void *payload,
968 size_t payload_length)
969{
970 size_t len;
971
973 gettext_noop ("# TCP packets sent via TUN"),
974 1,
975 GNUNET_NO);
977 "Sending packet with %u bytes TCP payload via TUN\n",
978 (unsigned int) payload_length);
979 len = sizeof(struct GNUNET_MessageHeader) + sizeof(struct
981 switch (source_address->af)
982 {
983 case AF_INET:
984 len += sizeof(struct GNUNET_TUN_IPv4Header);
985 break;
986
987 case AF_INET6:
988 len += sizeof(struct GNUNET_TUN_IPv6Header);
989 break;
990
991 default:
992 GNUNET_break (0);
993 return;
994 }
995 len += sizeof(struct GNUNET_TUN_TcpHeader);
996 len += payload_length;
997 if (len >= GNUNET_MAX_MESSAGE_SIZE)
998 {
999 GNUNET_break (0);
1000 return;
1001 }
1002 {
1003 char buf[len] GNUNET_ALIGN;
1004 struct GNUNET_MessageHeader *hdr;
1006
1007 hdr = (struct GNUNET_MessageHeader *) buf;
1008 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1009 hdr->size = htons (len);
1010 tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
1011 tun->flags = htons (0);
1012 switch (source_address->af)
1013 {
1014 case AF_INET:
1015 {
1017 = (struct GNUNET_TUN_IPv4Header*) &tun[1];
1018
1019 tun->proto = htons (ETH_P_IPV4);
1021 payload_length,
1022 IPPROTO_TCP,
1023 tcp_header,
1026 ipv4);
1027 }
1028 break;
1029
1030 case AF_INET6:
1031 {
1033 = (struct GNUNET_TUN_IPv6Header*) &tun[1];
1034
1035 tun->proto = htons (ETH_P_IPV6);
1038 IPPROTO_TCP,
1039 tcp_header,
1042 ipv6);
1043 }
1044 break;
1045
1046 default:
1047 GNUNET_assert (0);
1048 break;
1049 }
1050 if (NULL != helper_handle)
1052 (const struct GNUNET_MessageHeader*) buf,
1053 GNUNET_YES,
1054 NULL,
1055 NULL);
1056 }
1057}
1058
1059
1069static void
1071 const struct SocketAddress *source_address,
1072 const struct GNUNET_TUN_IcmpHeader *icmp_header,
1073 const void *payload, size_t payload_length)
1074{
1075 size_t len;
1076 struct GNUNET_TUN_IcmpHeader *icmp;
1077
1079 gettext_noop ("# ICMP packets sent via TUN"),
1080 1, GNUNET_NO);
1082 "Sending packet with %u bytes ICMP payload via TUN\n",
1083 (unsigned int) payload_length);
1084 len = sizeof(struct GNUNET_MessageHeader) + sizeof(struct
1086 switch (destination_address->af)
1087 {
1088 case AF_INET:
1089 len += sizeof(struct GNUNET_TUN_IPv4Header);
1090 break;
1091
1092 case AF_INET6:
1093 len += sizeof(struct GNUNET_TUN_IPv6Header);
1094 break;
1095
1096 default:
1097 GNUNET_break (0);
1098 return;
1099 }
1100 len += sizeof(struct GNUNET_TUN_IcmpHeader);
1101 len += payload_length;
1102 if (len >= GNUNET_MAX_MESSAGE_SIZE)
1103 {
1104 GNUNET_break (0);
1105 return;
1106 }
1107 {
1108 char buf[len] GNUNET_ALIGN;
1109 struct GNUNET_MessageHeader *hdr;
1111
1112 hdr = (struct GNUNET_MessageHeader *) buf;
1113 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1114 hdr->size = htons (len);
1115 tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
1116 tun->flags = htons (0);
1117 switch (source_address->af)
1118 {
1119 case AF_INET:
1120 {
1121 struct GNUNET_TUN_IPv4Header *ipv4 = (struct
1122 GNUNET_TUN_IPv4Header*) &tun[1];
1123
1124 tun->proto = htons (ETH_P_IPV4);
1126 IPPROTO_ICMP,
1127 sizeof(struct
1129 + payload_length,
1130 &source_address->address.ipv4,
1131 &destination_address->address.ipv4);
1132 icmp = (struct GNUNET_TUN_IcmpHeader*) &ipv4[1];
1133 }
1134 break;
1135
1136 case AF_INET6:
1137 {
1138 struct GNUNET_TUN_IPv6Header *ipv6 = (struct
1139 GNUNET_TUN_IPv6Header*) &tun[1];
1140
1141 tun->proto = htons (ETH_P_IPV6);
1143 IPPROTO_ICMPV6,
1144 sizeof(struct
1147 &source_address->address.ipv6,
1148 &destination_address->address.ipv6);
1149 icmp = (struct GNUNET_TUN_IcmpHeader*) &ipv6[1];
1150 }
1151 break;
1152
1153 default:
1154 GNUNET_assert (0);
1155 break;
1156 }
1157 *icmp = *icmp_header;
1158 GNUNET_memcpy (&icmp[1],
1159 payload,
1160 payload_length);
1162 payload,
1163 payload_length);
1164 if (NULL != helper_handle)
1166 (const struct GNUNET_MessageHeader*) buf,
1167 GNUNET_YES,
1168 NULL, NULL);
1169 }
1170}
1171
1172
1181static void
1182setup_fresh_address (int af,
1183 uint8_t proto,
1184 struct SocketAddress *local_address)
1185{
1186 local_address->af = af;
1187 local_address->proto = (uint8_t) proto;
1188 /* default "local" port range is often 32768--61000,
1189 so we pick a random value in that range */
1190 if (((af == AF_INET) && (proto == IPPROTO_ICMP)) ||
1191 ((af == AF_INET6) && (proto == IPPROTO_ICMPV6)))
1192 local_address->port = 0;
1193 else
1194 local_address->port
1195 = (uint16_t) 32768 + GNUNET_CRYPTO_random_u32 (28232);
1196 switch (af)
1197 {
1198 case AF_INET:
1199 {
1200 struct in_addr addr;
1201 struct in_addr mask;
1202 struct in_addr rnd;
1203
1204 addr = exit_ipv4addr;
1205 mask = exit_ipv4mask;
1206 if (0 == ~mask.s_addr)
1207 {
1208 /* only one valid IP anyway */
1209 local_address->address.ipv4 = addr;
1210 return;
1211 }
1212 /* Given 192.168.0.1/255.255.0.0, we want a mask
1213 of '192.168.255.255', thus: */
1214 mask.s_addr = addr.s_addr | ~mask.s_addr;
1215 /* Pick random IPv4 address within the subnet, except 'addr' or 'mask' itself */
1216 do
1217 {
1218 rnd.s_addr = GNUNET_CRYPTO_random_u32 (UINT32_MAX);
1219 local_address->address.ipv4.s_addr = (addr.s_addr | rnd.s_addr)
1220 & mask.s_addr;
1221 }
1222 while ((local_address->address.ipv4.s_addr == addr.s_addr) ||
1223 (local_address->address.ipv4.s_addr == mask.s_addr));
1224 }
1225 break;
1226
1227 case AF_INET6:
1228 {
1229 struct in6_addr addr;
1230 struct in6_addr mask;
1231 struct in6_addr rnd;
1232 int i;
1233
1234 addr = exit_ipv6addr;
1235 GNUNET_assert (ipv6prefix < 128);
1236 if (ipv6prefix == 127)
1237 {
1238 /* only one valid IP anyway */
1239 local_address->address.ipv6 = addr;
1240 return;
1241 }
1242 /* Given ABCD::/96, we want a mask of 'ABCD::FFFF:FFFF,
1243 thus: */
1244 mask = addr;
1245 for (i = 127; i >= ipv6prefix; i--)
1246 mask.s6_addr[i / 8] |= (1 << (i % 8));
1247
1248 /* Pick random IPv6 address within the subnet, except 'addr' or 'mask' itself */
1249 do
1250 {
1251 for (i = 0; i < 16; i++)
1252 {
1253 rnd.s6_addr[i] = (unsigned char) GNUNET_CRYPTO_random_u32 (
1254 256);
1255 local_address->address.ipv6.s6_addr[i]
1256 = (addr.s6_addr[i] | rnd.s6_addr[i]) & mask.s6_addr[i];
1257 }
1258 }
1259 while ((0 == GNUNET_memcmp (&local_address->address.ipv6,
1260 &addr)) ||
1261 (0 == GNUNET_memcmp (&local_address->address.ipv6,
1262 &mask)));
1263 }
1264 break;
1265
1266 default:
1267 GNUNET_assert (0);
1268 }
1269}
1270
1271
1293static void
1295{
1296 struct GNUNET_HashCode key;
1297 struct ChannelState *s;
1298
1299 /* generate fresh, unique address */
1300 do
1301 {
1302 if (NULL == state->specifics.tcp_udp.serv)
1303 setup_fresh_address (state->specifics.tcp_udp.ri.remote_address.af,
1304 state->specifics.tcp_udp.ri.remote_address.proto,
1305 &state->specifics.tcp_udp.ri.local_address);
1306 else
1307 setup_fresh_address (state->specifics.tcp_udp.serv->address.af,
1308 state->specifics.tcp_udp.serv->address.proto,
1309 &state->specifics.tcp_udp.ri.local_address);
1310 }
1311 while (NULL !=
1312 get_redirect_state (state->specifics.tcp_udp.ri.remote_address.af,
1313 state->specifics.tcp_udp.ri.remote_address.proto,
1314 &state->specifics.tcp_udp.ri.remote_address.address
1315 ,
1316 state->specifics.tcp_udp.ri.remote_address.port,
1317 &state->specifics.tcp_udp.ri.local_address.address,
1318 state->specifics.tcp_udp.ri.local_address.port,
1319 &key));
1320 {
1321 char buf[INET6_ADDRSTRLEN];
1323 "Picked local address %s:%u for new connection\n",
1324 inet_ntop (state->specifics.tcp_udp.ri.local_address.af,
1325 &state->specifics.tcp_udp.ri.local_address.address,
1326 buf,
1327 sizeof(buf)),
1328 (unsigned int) state->specifics.tcp_udp.ri.local_address.port);
1329 }
1330 state->specifics.tcp_udp.state_key = key;
1333 &key, state,
1335 state->specifics.tcp_udp.heap_node
1337 state,
1338 GNUNET_TIME_absolute_get ().abs_value_us);
1340 {
1342 GNUNET_assert (state != s);
1343 s->specifics.tcp_udp.heap_node = NULL;
1347 &s->specifics.tcp_udp.
1348 state_key,
1349 s));
1350 GNUNET_free (s);
1351 }
1352}
1353
1354
1363static void
1364send_udp_packet_via_tun (const struct SocketAddress *destination_address,
1365 const struct SocketAddress *source_address,
1366 const void *payload, size_t payload_length)
1367{
1368 size_t len;
1369
1371 gettext_noop ("# UDP packets sent via TUN"),
1372 1, GNUNET_NO);
1374 "Sending packet with %u bytes UDP payload via TUN\n",
1375 (unsigned int) payload_length);
1376 len = sizeof(struct GNUNET_MessageHeader) + sizeof(struct
1378 switch (source_address->af)
1379 {
1380 case AF_INET:
1381 len += sizeof(struct GNUNET_TUN_IPv4Header);
1382 break;
1383
1384 case AF_INET6:
1385 len += sizeof(struct GNUNET_TUN_IPv6Header);
1386 break;
1387
1388 default:
1389 GNUNET_break (0);
1390 return;
1391 }
1392 len += sizeof(struct GNUNET_TUN_UdpHeader);
1393 len += payload_length;
1395 {
1396 GNUNET_break (0);
1397 return;
1398 }
1399 {
1400 char buf[len] GNUNET_ALIGN;
1401 struct GNUNET_MessageHeader *hdr;
1403
1404 hdr = (struct GNUNET_MessageHeader *) buf;
1405 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1406 hdr->size = htons (len);
1407 tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
1408 tun->flags = htons (0);
1409 switch (source_address->af)
1410 {
1411 case AF_INET:
1412 {
1413 struct GNUNET_TUN_IPv4Header *ipv4 = (struct
1414 GNUNET_TUN_IPv4Header*) &tun[1];
1415
1416 tun->proto = htons (ETH_P_IPV4);
1418 payload_length,
1419 IPPROTO_UDP,
1420 NULL,
1423 ipv4);
1424 }
1425 break;
1426
1427 case AF_INET6:
1428 {
1429 struct GNUNET_TUN_IPv6Header *ipv6 = (struct
1430 GNUNET_TUN_IPv6Header*) &tun[1];
1431
1432 tun->proto = htons (ETH_P_IPV6);
1435 IPPROTO_UDP,
1436 NULL,
1439 ipv6);
1440 }
1441 break;
1442
1443 default:
1444 GNUNET_assert (0);
1445 break;
1446 }
1447 if (NULL != helper_handle)
1449 (const struct GNUNET_MessageHeader*) buf,
1450 GNUNET_YES,
1451 NULL, NULL);
1452 }
1453}
1454
1455
1464static int
1465check_udp_remote (void *cls,
1466 const struct GNUNET_EXIT_UdpInternetMessage *msg)
1467{
1468 struct ChannelState *state = cls;
1469
1470 if (GNUNET_YES == state->is_dns)
1471 {
1472 GNUNET_break_op (0);
1473 return GNUNET_SYSERR;
1474 }
1475 return GNUNET_OK;
1476}
1477
1478
1485static void
1486handle_udp_remote (void *cls,
1487 const struct GNUNET_EXIT_UdpInternetMessage *msg)
1488{
1489 struct ChannelState *state = cls;
1490 uint16_t pkt_len = ntohs (msg->header.size) - sizeof(struct
1492 const struct in_addr *v4;
1493 const struct in6_addr *v6;
1494 const void *payload;
1495 int af;
1496
1497 if (GNUNET_SYSERR == state->is_dns)
1498 {
1499 /* channel is UDP/TCP from now on */
1501 }
1503 gettext_noop ("# Bytes received from CADET"),
1504 pkt_len, GNUNET_NO);
1506 gettext_noop (
1507 "# UDP IP-exit requests received via cadet"),
1508 1, GNUNET_NO);
1509 af = (int) ntohl (msg->af);
1510 state->specifics.tcp_udp.ri.remote_address.af = af;
1511 switch (af)
1512 {
1513 case AF_INET:
1514 if (pkt_len < sizeof(struct in_addr))
1515 {
1516 GNUNET_break_op (0);
1517 return;
1518 }
1519 if (! ipv4_exit)
1520 {
1521 GNUNET_break_op (0);
1522 return;
1523 }
1524 v4 = (const struct in_addr*) &msg[1];
1525 payload = &v4[1];
1526 pkt_len -= sizeof(struct in_addr);
1527 state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
1528 break;
1529
1530 case AF_INET6:
1531 if (pkt_len < sizeof(struct in6_addr))
1532 {
1533 GNUNET_break_op (0);
1534 return;
1535 }
1536 if (! ipv6_exit)
1537 {
1538 GNUNET_break_op (0);
1539 return;
1540 }
1541 v6 = (const struct in6_addr*) &msg[1];
1542 payload = &v6[1];
1543 pkt_len -= sizeof(struct in6_addr);
1544 state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
1545 break;
1546
1547 default:
1548 GNUNET_break_op (0);
1549 return;
1550 }
1551 {
1552 char buf[INET6_ADDRSTRLEN];
1554 "Received data from %s for forwarding to UDP %s:%u\n",
1555 GNUNET_i2s (&state->peer),
1556 inet_ntop (af,
1557 &state->specifics.tcp_udp.ri.remote_address.address,
1558 buf, sizeof(buf)),
1559 (unsigned int) ntohs (msg->destination_port));
1560 }
1561 state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_UDP;
1562 state->specifics.tcp_udp.ri.remote_address.port = msg->destination_port;
1563 if (NULL == state->specifics.tcp_udp.heap_node)
1565 if (0 != ntohs (msg->source_port))
1566 state->specifics.tcp_udp.ri.local_address.port = msg->source_port;
1567 send_udp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1568 &state->specifics.tcp_udp.ri.local_address,
1569 payload,
1570 pkt_len);
1572}
1573
1574
1584static int
1585check_udp_service (void *cls,
1586 const struct GNUNET_EXIT_UdpServiceMessage *msg)
1587{
1588 struct ChannelState *state = cls;
1589
1590 if (NULL == state->specifics.tcp_udp.serv)
1591 {
1592 GNUNET_break_op (0);
1593 return GNUNET_SYSERR;
1594 }
1595 return GNUNET_OK;
1596}
1597
1598
1606static void
1607handle_udp_service (void *cls,
1608 const struct GNUNET_EXIT_UdpServiceMessage *msg)
1609{
1610 struct ChannelState *state = cls;
1611 uint16_t pkt_len = ntohs (msg->header.size) - sizeof(struct
1613
1615 gettext_noop ("# Bytes received from CADET"),
1616 pkt_len, GNUNET_NO);
1618 gettext_noop (
1619 "# UDP service requests received via cadet"),
1620 1, GNUNET_NO);
1622 "Received data from %s for forwarding to UDP service %s on port %u\n",
1623 GNUNET_i2s (&state->peer),
1624 GNUNET_h2s (&state->specifics.tcp_udp.serv->descriptor),
1625 (unsigned int) ntohs (msg->destination_port));
1627 if (0 != ntohs (msg->source_port))
1628 state->specifics.tcp_udp.ri.local_address.port = msg->source_port;
1629 send_udp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1630 &state->specifics.tcp_udp.ri.local_address,
1631 &msg[1],
1632 pkt_len);
1634}
1635
1636
1646static void
1647handle_tcp_service (void *cls,
1649{
1650 struct ChannelState *state = cls;
1651 uint16_t pkt_len = ntohs (start->header.size) - sizeof(struct
1653
1654 if (GNUNET_SYSERR == state->is_dns)
1655 {
1656 /* channel is UDP/TCP from now on */
1658 }
1660 gettext_noop (
1661 "# TCP service creation requests received via cadet"),
1662 1,
1663 GNUNET_NO);
1665 gettext_noop ("# Bytes received from CADET"),
1666 pkt_len,
1667 GNUNET_NO);
1668 GNUNET_break_op (ntohl (start->reserved) == 0);
1669 /* setup fresh connection */
1671 "Received data from %s for forwarding to TCP service %s on port %u\n",
1672 GNUNET_i2s (&state->peer),
1673 GNUNET_h2s (&state->specifics.tcp_udp.serv->descriptor),
1674 (unsigned int) ntohs (start->tcp_header.destination_port));
1676 send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1677 &state->specifics.tcp_udp.ri.local_address,
1678 &start->tcp_header,
1679 &start[1],
1680 pkt_len);
1682}
1683
1684
1693static int
1694check_tcp_remote (void *cls,
1696{
1697 struct ChannelState *state = cls;
1698
1699 if (NULL == state)
1700 {
1701 GNUNET_break_op (0);
1702 return GNUNET_SYSERR;
1703 }
1704 if (GNUNET_YES == state->is_dns)
1705 {
1706 GNUNET_break_op (0);
1707 return GNUNET_SYSERR;
1708 }
1709 if ((NULL != state->specifics.tcp_udp.serv) ||
1710 (NULL != state->specifics.tcp_udp.heap_node))
1711 {
1712 GNUNET_break_op (0);
1713 return GNUNET_SYSERR;
1714 }
1715 if (start->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
1716 {
1717 GNUNET_break_op (0);
1718 return GNUNET_SYSERR;
1719 }
1720 return GNUNET_OK;
1721}
1722
1723
1730static void
1731handle_tcp_remote (void *cls,
1733{
1734 struct ChannelState *state = cls;
1735 uint16_t pkt_len = ntohs (start->header.size) - sizeof(struct
1737 const struct in_addr *v4;
1738 const struct in6_addr *v6;
1739 const void *payload;
1740 int af;
1741
1742 if (GNUNET_SYSERR == state->is_dns)
1743 {
1744 /* channel is UDP/TCP from now on */
1746 }
1748 gettext_noop ("# Bytes received from CADET"),
1749 pkt_len, GNUNET_NO);
1751 gettext_noop (
1752 "# TCP IP-exit creation requests received via cadet"),
1753 1, GNUNET_NO);
1754 af = (int) ntohl (start->af);
1755 state->specifics.tcp_udp.ri.remote_address.af = af;
1756 switch (af)
1757 {
1758 case AF_INET:
1759 if (pkt_len < sizeof(struct in_addr))
1760 {
1761 GNUNET_break_op (0);
1762 return;
1763 }
1764 if (! ipv4_exit)
1765 {
1766 GNUNET_break_op (0);
1767 return;
1768 }
1769 v4 = (const struct in_addr*) &start[1];
1770 payload = &v4[1];
1771 pkt_len -= sizeof(struct in_addr);
1772 state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
1773 break;
1774
1775 case AF_INET6:
1776 if (pkt_len < sizeof(struct in6_addr))
1777 {
1778 GNUNET_break_op (0);
1779 return;
1780 }
1781 if (! ipv6_exit)
1782 {
1783 GNUNET_break_op (0);
1784 return;
1785 }
1786 v6 = (const struct in6_addr*) &start[1];
1787 payload = &v6[1];
1788 pkt_len -= sizeof(struct in6_addr);
1789 state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
1790 break;
1791
1792 default:
1793 GNUNET_break_op (0);
1794 return;
1795 }
1796 {
1797 char buf[INET6_ADDRSTRLEN];
1799 "Received payload from %s for existing TCP stream to %s:%u\n",
1800 GNUNET_i2s (&state->peer),
1801 inet_ntop (af,
1802 &state->specifics.tcp_udp.ri.remote_address.address,
1803 buf, sizeof(buf)),
1804 (unsigned int) ntohs (start->tcp_header.destination_port));
1805 }
1806 state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_TCP;
1807 state->specifics.tcp_udp.ri.remote_address.port = ntohs (
1808 start->tcp_header.destination_port);
1810 send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1811 &state->specifics.tcp_udp.ri.local_address,
1812 &start->tcp_header,
1813 payload,
1814 pkt_len);
1816}
1817
1818
1828static int
1829check_tcp_data (void *cls,
1830 const struct GNUNET_EXIT_TcpDataMessage *data)
1831{
1832 struct ChannelState *state = cls;
1833
1834 if ((NULL == state) ||
1835 (NULL == state->specifics.tcp_udp.heap_node))
1836 {
1837 /* connection should have been up! */
1839 gettext_noop (
1840 "# TCP DATA requests dropped (no session)"),
1841 1, GNUNET_NO);
1842 GNUNET_break_op (0);
1843 return GNUNET_SYSERR;
1844 }
1845 if (data->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
1846 {
1847 GNUNET_break_op (0);
1848 return GNUNET_SYSERR;
1849 }
1850 if (GNUNET_YES == state->is_dns)
1851 {
1852 GNUNET_break_op (0);
1853 return GNUNET_SYSERR;
1854 }
1855 return GNUNET_OK;
1856}
1857
1858
1866static void
1867handle_tcp_data (void *cls,
1868 const struct GNUNET_EXIT_TcpDataMessage *data)
1869{
1870 struct ChannelState *state = cls;
1871 uint16_t pkt_len = ntohs (data->header.size) - sizeof(struct
1873
1875 gettext_noop ("# Bytes received from CADET"),
1876 pkt_len, GNUNET_NO);
1878 gettext_noop (
1879 "# TCP data requests received via cadet"),
1880 1, GNUNET_NO);
1881 if (GNUNET_SYSERR == state->is_dns)
1882 {
1883 /* channel is UDP/TCP from now on */
1884 state->is_dns = GNUNET_NO;
1885 }
1886
1887 GNUNET_break_op (ntohl (data->reserved) == 0);
1888 {
1889 char buf[INET6_ADDRSTRLEN];
1891 "Received additional %u bytes of data from %s for TCP stream to %s:%u\n",
1892 pkt_len,
1893 GNUNET_i2s (&state->peer),
1894 inet_ntop (state->specifics.tcp_udp.ri.remote_address.af,
1895 &state->specifics.tcp_udp.ri.remote_address.address,
1896 buf, sizeof(buf)),
1897 (unsigned int) state->specifics.tcp_udp.ri.remote_address.port);
1898 }
1899
1900 send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1901 &state->specifics.tcp_udp.ri.local_address,
1902 &data->tcp_header,
1903 &data[1], pkt_len);
1905}
1906
1907
1917static void
1919 struct GNUNET_TUN_IPv4Header *ipp,
1920 struct GNUNET_TUN_UdpHeader *udp)
1921{
1923 state->specifics.tcp_udp.ri.remote_address.
1924 proto,
1925 sizeof(struct GNUNET_TUN_TcpHeader),
1926 &state->specifics.tcp_udp.ri.remote_address
1927 .address.ipv4,
1928 &state->specifics.tcp_udp.ri.local_address.
1929 address.ipv4);
1930 udp->source_port = htons (state->specifics.tcp_udp.ri.remote_address.port);
1931 udp->destination_port = htons (
1932 state->specifics.tcp_udp.ri.local_address.port);
1933 udp->len = htons (0);
1934 udp->crc = htons (0);
1935}
1936
1937
1947static void
1949 struct GNUNET_TUN_IPv6Header *ipp,
1950 struct GNUNET_TUN_UdpHeader *udp)
1951{
1953 state->specifics.tcp_udp.ri.remote_address.
1954 proto,
1955 sizeof(struct GNUNET_TUN_TcpHeader),
1956 &state->specifics.tcp_udp.ri.remote_address
1957 .address.ipv6,
1958 &state->specifics.tcp_udp.ri.local_address.
1959 address.ipv6);
1960 udp->source_port = htons (state->specifics.tcp_udp.ri.remote_address.port);
1961 udp->destination_port = htons (
1962 state->specifics.tcp_udp.ri.local_address.port);
1963 udp->len = htons (0);
1964 udp->crc = htons (0);
1965}
1966
1967
1976static int
1977check_icmp_remote (void *cls,
1979{
1980 struct ChannelState *state = cls;
1981
1982 if (GNUNET_YES == state->is_dns)
1983 {
1984 GNUNET_break_op (0);
1985 return GNUNET_SYSERR;
1986 }
1987 return GNUNET_OK;
1988}
1989
1990
1997static void
1998handle_icmp_remote (void *cls,
2000{
2001 struct ChannelState *state = cls;
2002 uint16_t pkt_len = ntohs (msg->header.size) - sizeof(struct
2004 const struct in_addr *v4;
2005 const struct in6_addr *v6;
2006 const void *payload;
2007 char buf[sizeof(struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
2008 int af;
2009
2010 if (GNUNET_SYSERR == state->is_dns)
2011 {
2012 /* channel is UDP/TCP from now on */
2014 }
2016 gettext_noop ("# Bytes received from CADET"),
2017 pkt_len, GNUNET_NO);
2019 gettext_noop (
2020 "# ICMP IP-exit requests received via cadet"),
2021 1, GNUNET_NO);
2022
2023 af = (int) ntohl (msg->af);
2024 if ((NULL != state->specifics.tcp_udp.heap_node) &&
2025 (af != state->specifics.tcp_udp.ri.remote_address.af))
2026 {
2027 /* other peer switched AF on this channel; not allowed */
2028 GNUNET_break_op (0);
2029 return;
2030 }
2031
2032 switch (af)
2033 {
2034 case AF_INET:
2035 if (pkt_len < sizeof(struct in_addr))
2036 {
2037 GNUNET_break_op (0);
2038 return;
2039 }
2040 if (! ipv4_exit)
2041 {
2042 GNUNET_break_op (0);
2043 return;
2044 }
2045 v4 = (const struct in_addr*) &msg[1];
2046 payload = &v4[1];
2047 pkt_len -= sizeof(struct in_addr);
2048 state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
2049 if (NULL == state->specifics.tcp_udp.heap_node)
2050 {
2051 state->specifics.tcp_udp.ri.remote_address.af = af;
2052 state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_ICMP;
2054 }
2055 /* check that ICMP type is something we want to support
2056 and possibly make up payload! */
2057 switch (msg->icmp_header.type)
2058 {
2061 break;
2062
2066 if (0 != pkt_len)
2067 {
2068 GNUNET_break_op (0);
2069 return;
2070 }
2071 /* make up payload */
2072 {
2073 struct GNUNET_TUN_IPv4Header *ipp = (struct
2074 GNUNET_TUN_IPv4Header *) buf;
2075 struct GNUNET_TUN_UdpHeader *udp = (struct
2076 GNUNET_TUN_UdpHeader *) &ipp[1];
2077
2078 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
2079 pkt_len = sizeof(struct GNUNET_TUN_IPv4Header) + 8;
2081 ipp,
2082 udp);
2083 payload = ipp;
2084 }
2085 break;
2086
2087 default:
2088 GNUNET_break_op (0);
2090 gettext_noop (
2091 "# ICMPv4 packets dropped (type not allowed)")
2092 ,
2093 1, GNUNET_NO);
2094 return;
2095 }
2096 /* end AF_INET */
2097 break;
2098
2099 case AF_INET6:
2100 if (pkt_len < sizeof(struct in6_addr))
2101 {
2102 GNUNET_break_op (0);
2103 return;
2104 }
2105 if (! ipv6_exit)
2106 {
2107 GNUNET_break_op (0);
2108 return;
2109 }
2110 v6 = (const struct in6_addr*) &msg[1];
2111 payload = &v6[1];
2112 pkt_len -= sizeof(struct in6_addr);
2113 state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
2114 if (NULL == state->specifics.tcp_udp.heap_node)
2115 {
2116 state->specifics.tcp_udp.ri.remote_address.af = af;
2117 state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_ICMPV6;
2119 }
2120 /* check that ICMP type is something we want to support
2121 and possibly make up payload! */
2122 switch (msg->icmp_header.type)
2123 {
2126 break;
2127
2132 if (0 != pkt_len)
2133 {
2134 GNUNET_break_op (0);
2135 return;
2136 }
2137 /* make up payload */
2138 {
2139 struct GNUNET_TUN_IPv6Header *ipp = (struct
2140 GNUNET_TUN_IPv6Header *) buf;
2141 struct GNUNET_TUN_UdpHeader *udp = (struct
2142 GNUNET_TUN_UdpHeader *) &ipp[1];
2143
2144 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
2145 pkt_len = sizeof(struct GNUNET_TUN_IPv6Header) + 8;
2147 ipp,
2148 udp);
2149 payload = ipp;
2150 }
2151 break;
2152
2153 default:
2154 GNUNET_break_op (0);
2156 gettext_noop (
2157 "# ICMPv6 packets dropped (type not allowed)")
2158 ,
2159 1, GNUNET_NO);
2160 return;
2161 }
2162 /* end AF_INET6 */
2163 break;
2164
2165 default:
2166 /* bad AF */
2167 GNUNET_break_op (0);
2168 return;
2169 }
2170
2171 {
2172 char buf_tmp[INET6_ADDRSTRLEN];
2174 "Received ICMP data from %s for forwarding to %s\n",
2175 GNUNET_i2s (&state->peer),
2176 inet_ntop (af,
2177 &state->specifics.tcp_udp.ri.remote_address.address,
2178 buf_tmp, sizeof(buf_tmp)));
2179 }
2180 send_icmp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
2181 &state->specifics.tcp_udp.ri.local_address,
2182 &msg->icmp_header,
2183 payload, pkt_len);
2185}
2186
2187
2197static uint16_t
2199 char *buf)
2200{
2201 switch (state->specifics.tcp_udp.serv->address.af)
2202 {
2203 case AF_INET:
2204 {
2206 struct GNUNET_TUN_UdpHeader *udp;
2207
2208 ipv4 = (struct GNUNET_TUN_IPv4Header *) buf;
2209 udp = (struct GNUNET_TUN_UdpHeader *) &ipv4[1];
2211 ipv4,
2212 udp);
2213 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
2214 return sizeof(struct GNUNET_TUN_IPv4Header) + 8;
2215 }
2216 break;
2217
2218 case AF_INET6:
2219 {
2221 struct GNUNET_TUN_UdpHeader *udp;
2222
2223 ipv6 = (struct GNUNET_TUN_IPv6Header *) buf;
2224 udp = (struct GNUNET_TUN_UdpHeader *) &ipv6[1];
2226 ipv6,
2227 udp);
2228 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
2229 return sizeof(struct GNUNET_TUN_IPv6Header) + 8;
2230 }
2231 break;
2232
2233 default:
2234 GNUNET_break (0);
2235 }
2236 return 0;
2237}
2238
2239
2249static int
2250check_icmp_service (void *cls,
2251 const struct GNUNET_EXIT_IcmpServiceMessage *msg)
2252{
2253 struct ChannelState *state = cls;
2254
2255 if (GNUNET_YES == state->is_dns)
2256 {
2257 GNUNET_break_op (0);
2258 return GNUNET_SYSERR;
2259 }
2260 if (NULL == state->specifics.tcp_udp.serv)
2261 {
2262 GNUNET_break_op (0);
2263 return GNUNET_SYSERR;
2264 }
2265 return GNUNET_OK;
2266}
2267
2268
2276static void
2277handle_icmp_service (void *cls,
2278 const struct GNUNET_EXIT_IcmpServiceMessage *msg)
2279{
2280 struct ChannelState *state = cls;
2281 uint16_t pkt_len = ntohs (msg->header.size) - sizeof(struct
2283 struct GNUNET_TUN_IcmpHeader icmp;
2284 char buf[sizeof(struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
2285 const void *payload;
2286
2288 gettext_noop ("# Bytes received from CADET"),
2289 pkt_len, GNUNET_NO);
2291 gettext_noop (
2292 "# ICMP service requests received via cadet"),
2293 1, GNUNET_NO);
2294 /* check that we got at least a valid header */
2296 "Received data from %s for forwarding to ICMP service %s\n",
2297 GNUNET_i2s (&state->peer),
2298 GNUNET_h2s (&state->specifics.tcp_udp.serv->descriptor));
2299 icmp = msg->icmp_header;
2300 payload = &msg[1];
2301 state->specifics.tcp_udp.ri.remote_address
2302 = state->specifics.tcp_udp.serv->address;
2304
2305 /* check that ICMP type is something we want to support,
2306 perform ICMP PT if needed and possibly make up payload */
2307 switch (msg->af)
2308 {
2309 case AF_INET:
2310 switch (msg->icmp_header.type)
2311 {
2313 if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2315 break;
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 if (0 != pkt_len)
2326 {
2327 GNUNET_break_op (0);
2328 return;
2329 }
2330 payload = buf;
2331 pkt_len = make_up_icmp_service_payload (state, buf);
2332 break;
2333
2335 if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2337 if (0 != pkt_len)
2338 {
2339 GNUNET_break_op (0);
2340 return;
2341 }
2342 payload = buf;
2343 pkt_len = make_up_icmp_service_payload (state, buf);
2344 break;
2345
2347 if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2348 {
2350 gettext_noop (
2351 "# ICMPv4 packets dropped (impossible PT to v6)"),
2352 1, GNUNET_NO);
2353 return;
2354 }
2355 if (0 != pkt_len)
2356 {
2357 GNUNET_break_op (0);
2358 return;
2359 }
2360 payload = buf;
2361 pkt_len = make_up_icmp_service_payload (state, buf);
2362 break;
2363
2364 default:
2365 GNUNET_break_op (0);
2367 gettext_noop (
2368 "# ICMPv4 packets dropped (type not allowed)")
2369 ,
2370 1, GNUNET_NO);
2371 return;
2372 }
2373 /* end of AF_INET */
2374 break;
2375
2376 case AF_INET6:
2377 switch (msg->icmp_header.type)
2378 {
2380 if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2382 break;
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 if (0 != pkt_len)
2393 {
2394 GNUNET_break_op (0);
2395 return;
2396 }
2397 payload = buf;
2398 pkt_len = make_up_icmp_service_payload (state, buf);
2399 break;
2400
2402 if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2404 if (0 != pkt_len)
2405 {
2406 GNUNET_break_op (0);
2407 return;
2408 }
2409 payload = buf;
2410 pkt_len = make_up_icmp_service_payload (state, buf);
2411 break;
2412
2415 if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2416 {
2418 gettext_noop (
2419 "# ICMPv6 packets dropped (impossible PT to v4)"),
2420 1, GNUNET_NO);
2421 return;
2422 }
2423 if (0 != pkt_len)
2424 {
2425 GNUNET_break_op (0);
2426 return;
2427 }
2428 payload = buf;
2429 pkt_len = make_up_icmp_service_payload (state, buf);
2430 break;
2431
2432 default:
2433 GNUNET_break_op (0);
2435 gettext_noop (
2436 "# ICMPv6 packets dropped (type not allowed)")
2437 ,
2438 1, GNUNET_NO);
2439 return;
2440 }
2441 /* end of AF_INET6 */
2442 break;
2443
2444 default:
2445 GNUNET_break_op (0);
2446 return;
2447 }
2448
2449 send_icmp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
2450 &state->specifics.tcp_udp.ri.local_address,
2451 &icmp,
2452 payload,
2453 pkt_len);
2455}
2456
2457
2466static int
2467free_service_record (void *cls,
2468 const struct GNUNET_HashCode *key,
2469 void *value)
2470{
2471 struct LocalService *service = value;
2472
2475 key,
2476 service));
2478 GNUNET_free (service->name);
2480 return GNUNET_OK;
2481}
2482
2483
2492static void *
2493new_service_channel (void *cls,
2494 struct GNUNET_CADET_Channel *channel,
2495 const struct GNUNET_PeerIdentity *initiator)
2496{
2497 struct LocalService *ls = cls;
2498 struct ChannelState *s = GNUNET_new (struct ChannelState);
2499
2500 s->peer = *initiator;
2502 gettext_noop ("# Inbound CADET channels created"),
2503 1,
2504 GNUNET_NO);
2506 "Received inbound channel from `%s'\n",
2507 GNUNET_i2s (initiator));
2508 s->channel = channel;
2509 s->specifics.tcp_udp.serv = ls;
2510 s->specifics.tcp_udp.ri.remote_address = ls->address;
2511 return s;
2512}
2513
2514
2522static void
2523clean_channel (void *cls,
2524 const struct GNUNET_CADET_Channel *channel)
2525{
2526 struct ChannelState *s = cls;
2527
2529 "Channel destroyed\n");
2530 if (GNUNET_SYSERR == s->is_dns)
2531 {
2532 GNUNET_free (s);
2533 return;
2534 }
2535 if (GNUNET_YES == s->is_dns)
2536 {
2537 if (channels[s->specifics.dns.my_id] == s)
2538 channels[s->specifics.dns.my_id] = NULL;
2539 }
2540 else
2541 {
2542 if (NULL != s->specifics.tcp_udp.heap_node)
2543 {
2546 &s->specifics.tcp_udp
2547 .state_key,
2548 s));
2550 s->specifics.tcp_udp.heap_node = NULL;
2551 }
2552 }
2553 GNUNET_free (s);
2554}
2555
2556
2566static void
2567store_service (int proto,
2568 const char *name,
2569 uint16_t destination_port,
2570 struct LocalService *service)
2571{
2573 GNUNET_MQ_hd_var_size (icmp_service,
2576 service),
2577 GNUNET_MQ_hd_var_size (udp_service,
2580 service),
2581 GNUNET_MQ_hd_var_size (tcp_service,
2584 service),
2585 GNUNET_MQ_hd_var_size (tcp_data,
2588 service),
2590 };
2591
2593
2594 service->name = GNUNET_strdup (name);
2596 &service->descriptor);
2598 destination_port,
2599 &cadet_port);
2601 "Opening CADET port %s for SERVICE exit %s on port %u\n",
2603 name,
2604 (unsigned int) destination_port);
2606 &cadet_port,
2608 service,
2609 NULL,
2611 handlers);
2612 service->is_udp = (IPPROTO_UDP == proto);
2613 if (GNUNET_OK !=
2615 &cadet_port,
2616 service,
2618 {
2620 GNUNET_free (service->name);
2623 _ ("Got duplicate service records for `%s:%u'\n"),
2624 name,
2625 (unsigned int) destination_port);
2626 }
2627}
2628
2629
2636static void
2638 struct GNUNET_MQ_Envelope *env)
2639{
2640 GNUNET_assert (NULL != s);
2642 gettext_noop (
2643 "# Messages transmitted via cadet channels"),
2644 1,
2645 GNUNET_NO);
2647 env);
2648}
2649
2650
2662static void
2663icmp_from_helper (const struct GNUNET_TUN_IcmpHeader *icmp,
2664 size_t pktlen,
2665 int af,
2666 const void *destination_ip,
2667 const void *source_ip)
2668{
2669 struct ChannelState *state;
2670 struct GNUNET_MQ_Envelope *env;
2671 struct GNUNET_EXIT_IcmpToVPNMessage *i2v;
2672 const struct GNUNET_TUN_IPv4Header *ipv4;
2673 const struct GNUNET_TUN_IPv6Header *ipv6;
2674 const struct GNUNET_TUN_UdpHeader *udp;
2675 uint16_t source_port;
2676 uint16_t destination_port;
2677 uint8_t protocol;
2678
2679 {
2680 char sbuf[INET6_ADDRSTRLEN];
2681 char dbuf[INET6_ADDRSTRLEN];
2683 "Received ICMP packet going from %s to %s\n",
2684 inet_ntop (af,
2685 source_ip,
2686 sbuf, sizeof(sbuf)),
2687 inet_ntop (af,
2688 destination_ip,
2689 dbuf, sizeof(dbuf)));
2690 }
2691
2692 if (pktlen < sizeof(struct GNUNET_TUN_IcmpHeader))
2693 {
2694 /* blame kernel */
2695 GNUNET_break (0);
2696 return;
2697 }
2698
2699 /* Find out if this is an ICMP packet in response to an existing
2700 TCP/UDP packet and if so, figure out ports / protocol of the
2701 existing session from the IP data in the ICMP payload */
2702 source_port = 0;
2703 destination_port = 0;
2704 switch (af)
2705 {
2706 case AF_INET:
2707 protocol = IPPROTO_ICMP;
2708 switch (icmp->type)
2709 {
2712 break;
2713
2717 if (pktlen <
2718 sizeof(struct GNUNET_TUN_IcmpHeader)
2719 + sizeof(struct GNUNET_TUN_IPv4Header) + 8)
2720 {
2721 /* blame kernel */
2722 GNUNET_break (0);
2723 return;
2724 }
2725 ipv4 = (const struct GNUNET_TUN_IPv4Header *) &icmp[1];
2726 protocol = ipv4->protocol;
2727 /* could be TCP or UDP, but both have the ports in the right
2728 place, so that doesn't matter here */
2729 udp = (const struct GNUNET_TUN_UdpHeader *) &ipv4[1];
2730 /* swap ports, as they are from the original message */
2731 destination_port = ntohs (udp->source_port);
2732 source_port = ntohs (udp->destination_port);
2733 /* throw away ICMP payload, won't be useful for the other side anyway */
2734 pktlen = sizeof(struct GNUNET_TUN_IcmpHeader);
2735 break;
2736
2737 default:
2739 gettext_noop (
2740 "# ICMPv4 packets dropped (type not allowed)")
2741 ,
2742 1, GNUNET_NO);
2743 return;
2744 }
2745 break;
2746
2747 case AF_INET6:
2748 protocol = IPPROTO_ICMPV6;
2749 switch (icmp->type)
2750 {
2755 if (pktlen <
2756 sizeof(struct GNUNET_TUN_IcmpHeader)
2757 + sizeof(struct GNUNET_TUN_IPv6Header) + 8)
2758 {
2759 /* blame kernel */
2760 GNUNET_break (0);
2761 return;
2762 }
2763 ipv6 = (const struct GNUNET_TUN_IPv6Header *) &icmp[1];
2764 protocol = ipv6->next_header;
2765 /* could be TCP or UDP, but both have the ports in the right
2766 place, so that doesn't matter here */
2767 udp = (const struct GNUNET_TUN_UdpHeader *) &ipv6[1];
2768 /* swap ports, as they are from the original message */
2769 destination_port = ntohs (udp->source_port);
2770 source_port = ntohs (udp->destination_port);
2771 /* throw away ICMP payload, won't be useful for the other side anyway */
2772 pktlen = sizeof(struct GNUNET_TUN_IcmpHeader);
2773 break;
2774
2777 break;
2778
2779 default:
2781 gettext_noop (
2782 "# ICMPv6 packets dropped (type not allowed)")
2783 ,
2784 1, GNUNET_NO);
2785 return;
2786 }
2787 break;
2788
2789 default:
2790 GNUNET_assert (0);
2791 }
2792 switch (protocol)
2793 {
2794 case IPPROTO_ICMP:
2796 IPPROTO_ICMP,
2797 source_ip,
2798 0,
2799 destination_ip,
2800 0,
2801 NULL);
2802 break;
2803
2804 case IPPROTO_ICMPV6:
2806 IPPROTO_ICMPV6,
2807 source_ip,
2808 0,
2809 destination_ip,
2810 0,
2811 NULL);
2812 break;
2813
2814 case IPPROTO_UDP:
2816 IPPROTO_UDP,
2817 source_ip,
2818 source_port,
2819 destination_ip,
2820 destination_port,
2821 NULL);
2822 break;
2823
2824 case IPPROTO_TCP:
2826 IPPROTO_TCP,
2827 source_ip,
2828 source_port,
2829 destination_ip,
2830 destination_port,
2831 NULL);
2832 break;
2833
2834 default:
2836 gettext_noop (
2837 "# ICMP packets dropped (not allowed)"),
2838 1,
2839 GNUNET_NO);
2840 return;
2841 }
2842 if (NULL == state)
2843 {
2845 _ (
2846 "ICMP Packet dropped, have no matching connection information\n"));
2847 return;
2848 }
2849 env = GNUNET_MQ_msg_extra (i2v,
2850 pktlen - sizeof(struct GNUNET_TUN_IcmpHeader),
2852 i2v->af = htonl (af);
2854 icmp,
2855 pktlen);
2857 env);
2858}
2859
2860
2872static void
2874 size_t pktlen,
2875 int af,
2876 const void *destination_ip,
2877 const void *source_ip)
2878{
2879 struct ChannelState *state;
2880 struct GNUNET_MQ_Envelope *env;
2881 struct GNUNET_EXIT_UdpReplyMessage *urm;
2882
2883 {
2884 char sbuf[INET6_ADDRSTRLEN];
2885 char dbuf[INET6_ADDRSTRLEN];
2886
2888 "Received UDP packet going from %s:%u to %s:%u\n",
2889 inet_ntop (af,
2890 source_ip,
2891 sbuf, sizeof(sbuf)),
2892 (unsigned int) ntohs (udp->source_port),
2893 inet_ntop (af,
2894 destination_ip,
2895 dbuf, sizeof(dbuf)),
2896 (unsigned int) ntohs (udp->destination_port));
2897 }
2898
2899 if (pktlen < sizeof(struct GNUNET_TUN_UdpHeader))
2900 {
2901 /* blame kernel */
2902 GNUNET_break (0);
2903 return;
2904 }
2905 if (pktlen != ntohs (udp->len))
2906 {
2907 /* blame kernel */
2908 GNUNET_break (0);
2909 return;
2910 }
2912 IPPROTO_UDP,
2913 source_ip,
2914 ntohs (udp->source_port),
2915 destination_ip,
2916 ntohs (udp->destination_port),
2917 NULL);
2918 if (NULL == state)
2919 {
2921 _ (
2922 "UDP Packet dropped, have no matching connection information\n"));
2923 return;
2924 }
2925 env = GNUNET_MQ_msg_extra (urm,
2926 pktlen - sizeof(struct GNUNET_TUN_UdpHeader),
2928 urm->source_port = htons (0);
2929 urm->destination_port = htons (0);
2930 GNUNET_memcpy (&urm[1],
2931 &udp[1],
2932 pktlen - sizeof(struct GNUNET_TUN_UdpHeader));
2934 env);
2935}
2936
2937
2949static void
2951 size_t pktlen,
2952 int af,
2953 const void *destination_ip,
2954 const void *source_ip)
2955{
2956 struct ChannelState *state;
2957 char buf[pktlen] GNUNET_ALIGN;
2958 struct GNUNET_TUN_TcpHeader *mtcp;
2959 struct GNUNET_EXIT_TcpDataMessage *tdm;
2960 struct GNUNET_MQ_Envelope *env;
2961 size_t mlen;
2962
2963 {
2964 char sbuf[INET6_ADDRSTRLEN];
2965 char dbuf[INET6_ADDRSTRLEN];
2967 "Received TCP packet with %u bytes going from %s:%u to %s:%u\n",
2968 (unsigned int) (pktlen - sizeof(struct GNUNET_TUN_TcpHeader)),
2969 inet_ntop (af,
2970 source_ip,
2971 sbuf, sizeof(sbuf)),
2972 (unsigned int) ntohs (tcp->source_port),
2973 inet_ntop (af,
2974 destination_ip,
2975 dbuf, sizeof(dbuf)),
2976 (unsigned int) ntohs (tcp->destination_port));
2977 }
2978
2979 if (pktlen < sizeof(struct GNUNET_TUN_TcpHeader))
2980 {
2981 /* blame kernel */
2982 GNUNET_break (0);
2983 return;
2984 }
2986 IPPROTO_TCP,
2987 source_ip,
2988 ntohs (tcp->source_port),
2989 destination_ip,
2990 ntohs (tcp->destination_port),
2991 NULL);
2992 if (NULL == state)
2993 {
2995 _ (
2996 "TCP Packet dropped, have no matching connection information\n"));
2997
2998 return;
2999 }
3000 /* mug port numbers and crc to avoid information leakage;
3001 sender will need to lookup the correct values anyway */
3002 GNUNET_memcpy (buf, tcp, pktlen);
3003 mtcp = (struct GNUNET_TUN_TcpHeader *) buf;
3004 mtcp->source_port = 0;
3005 mtcp->destination_port = 0;
3006 mtcp->crc = 0;
3007
3008 mlen = sizeof(struct GNUNET_EXIT_TcpDataMessage) + (pktlen - sizeof(struct
3010 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
3011 {
3012 GNUNET_break (0);
3013 return;
3014 }
3015 env = GNUNET_MQ_msg_extra (tdm,
3016 pktlen - sizeof(struct GNUNET_TUN_TcpHeader),
3018 tdm->reserved = htonl (0);
3020 buf,
3021 pktlen);
3023 env);
3024}
3025
3026
3033static int
3034message_token (void *cls GNUNET_UNUSED,
3035 const struct GNUNET_MessageHeader *message)
3036{
3037 const struct GNUNET_TUN_Layer2PacketHeader *pkt_tun;
3038 size_t size;
3039
3041 "Got %u-byte message of type %u from gnunet-helper-exit\n",
3042 ntohs (message->size),
3043 ntohs (message->type));
3045 gettext_noop ("# Packets received from TUN"),
3046 1, GNUNET_NO);
3047 if (ntohs (message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER)
3048 {
3049 GNUNET_break (0);
3050 return GNUNET_OK;
3051 }
3052 size = ntohs (message->size);
3053 if (size < sizeof(struct GNUNET_TUN_Layer2PacketHeader) + sizeof(struct
3055 {
3056 GNUNET_break (0);
3057 return GNUNET_OK;
3058 }
3060 gettext_noop ("# Bytes received from TUN"),
3061 size, GNUNET_NO);
3062 pkt_tun = (const struct GNUNET_TUN_Layer2PacketHeader *) &message[1];
3063 size -= sizeof(struct GNUNET_TUN_Layer2PacketHeader) + sizeof(struct
3065 switch (ntohs (pkt_tun->proto))
3066 {
3067 case ETH_P_IPV4:
3068 {
3069 const struct GNUNET_TUN_IPv4Header *pkt4;
3070
3071 if (size < sizeof(struct GNUNET_TUN_IPv4Header))
3072 {
3073 /* Kernel to blame? */
3074 GNUNET_break (0);
3075 return GNUNET_OK;
3076 }
3077 pkt4 = (const struct GNUNET_TUN_IPv4Header *) &pkt_tun[1];
3078 if (size != ntohs (pkt4->total_length))
3079 {
3080 /* Kernel to blame? */
3081 GNUNET_break (0);
3082 return GNUNET_OK;
3083 }
3084 if (pkt4->header_length * 4 != sizeof(struct GNUNET_TUN_IPv4Header))
3085 {
3087 _ ("IPv4 packet options received. Ignored.\n"));
3088 return GNUNET_OK;
3089 }
3090
3091 size -= sizeof(struct GNUNET_TUN_IPv4Header);
3092 switch (pkt4->protocol)
3093 {
3094 case IPPROTO_UDP:
3095 udp_from_helper ((const struct GNUNET_TUN_UdpHeader *) &pkt4[1], size,
3096 AF_INET,
3097 &pkt4->destination_address,
3098 &pkt4->source_address);
3099 break;
3100
3101 case IPPROTO_TCP:
3102 tcp_from_helper ((const struct GNUNET_TUN_TcpHeader *) &pkt4[1], size,
3103 AF_INET,
3104 &pkt4->destination_address,
3105 &pkt4->source_address);
3106 break;
3107
3108 case IPPROTO_ICMP:
3109 icmp_from_helper ((const struct GNUNET_TUN_IcmpHeader *) &pkt4[1], size,
3110 AF_INET,
3111 &pkt4->destination_address,
3112 &pkt4->source_address);
3113 break;
3114
3115 default:
3117 _ (
3118 "IPv4 packet with unsupported next header %u received. Ignored.\n"),
3119 (int) pkt4->protocol);
3120 return GNUNET_OK;
3121 }
3122 }
3123 break;
3124
3125 case ETH_P_IPV6:
3126 {
3127 const struct GNUNET_TUN_IPv6Header *pkt6;
3128
3129 if (size < sizeof(struct GNUNET_TUN_IPv6Header))
3130 {
3131 /* Kernel to blame? */
3132 GNUNET_break (0);
3133 return GNUNET_OK;
3134 }
3135 pkt6 = (struct GNUNET_TUN_IPv6Header *) &pkt_tun[1];
3136 if (size != ntohs (pkt6->payload_length) + sizeof(struct
3138 {
3139 /* Kernel to blame? */
3140 GNUNET_break (0);
3141 return GNUNET_OK;
3142 }
3143 size -= sizeof(struct GNUNET_TUN_IPv6Header);
3144 switch (pkt6->next_header)
3145 {
3146 case IPPROTO_UDP:
3147 udp_from_helper ((const struct GNUNET_TUN_UdpHeader *) &pkt6[1], size,
3148 AF_INET6,
3149 &pkt6->destination_address,
3150 &pkt6->source_address);
3151 break;
3152
3153 case IPPROTO_TCP:
3154 tcp_from_helper ((const struct GNUNET_TUN_TcpHeader *) &pkt6[1], size,
3155 AF_INET6,
3156 &pkt6->destination_address,
3157 &pkt6->source_address);
3158 break;
3159
3160 case IPPROTO_ICMPV6:
3161 icmp_from_helper ((const struct GNUNET_TUN_IcmpHeader *) &pkt6[1], size,
3162 AF_INET6,
3163 &pkt6->destination_address,
3164 &pkt6->source_address);
3165 break;
3166
3167 default:
3169 _ (
3170 "IPv6 packet with unsupported next header %d received. Ignored.\n"),
3171 pkt6->next_header);
3172 return GNUNET_OK;
3173 }
3174 }
3175 break;
3176
3177 default:
3179 _ ("Packet from unknown protocol %u received. Ignored.\n"),
3180 ntohs (pkt_tun->proto));
3181 break;
3182 }
3183 return GNUNET_OK;
3184}
3185
3186
3195static void *
3196new_channel (void *cls,
3197 struct GNUNET_CADET_Channel *channel,
3198 const struct GNUNET_PeerIdentity *initiator)
3199{
3200 struct ChannelState *s = GNUNET_new (struct ChannelState);
3201
3202 s->is_dns = GNUNET_SYSERR;
3203 s->peer = *initiator;
3205 gettext_noop ("# Inbound CADET channels created"),
3206 1,
3207 GNUNET_NO);
3209 "Received inbound channel from `%s'\n",
3210 GNUNET_i2s (initiator));
3211 s->channel = channel;
3212 return s;
3213}
3214
3215
3223static int
3224free_iterate (void *cls,
3225 const struct GNUNET_HashCode *hash,
3226 void *value)
3227{
3229 return GNUNET_YES;
3230}
3231
3232
3241static void
3242dummy_task (void *cls)
3243{
3244 /* just terminate */
3245}
3246
3247
3253static void
3254cleanup (void *cls)
3255{
3256 unsigned int i;
3257
3259 "Exit service is shutting down now\n");
3260
3261 if (NULL != helper_handle)
3262 {
3264 helper_handle = NULL;
3265 }
3266 if (NULL != regex4)
3267 {
3269 regex4 = NULL;
3270 }
3271 if (NULL != regex6)
3272 {
3274 regex6 = NULL;
3275 }
3276 if (NULL != services)
3277 {
3280 NULL);
3282 }
3283 if (NULL != dns_port)
3284 {
3286 dns_port = NULL;
3287 }
3288 if (NULL != cadet_port4)
3289 {
3291 cadet_port4 = NULL;
3292 }
3293 if (NULL != cadet_port6)
3294 {
3296 cadet_port6 = NULL;
3297 }
3298 if (NULL != cadet_handle)
3299 {
3301 cadet_handle = NULL;
3302 }
3303 if (NULL != connections_map)
3304 {
3306 &free_iterate,
3307 NULL);
3309 connections_map = NULL;
3310 }
3311 if (NULL != connections_heap)
3312 {
3314 connections_heap = NULL;
3315 }
3316 if (NULL != dnsstub)
3317 {
3319 dnsstub = NULL;
3320 }
3321 if (NULL != sign_op)
3322 {
3324 sign_op = NULL;
3325 }
3326 if (NULL != pils)
3327 {
3329 pils = NULL;
3330 }
3331 if (NULL != dht_task)
3332 {
3334 dht_task = NULL;
3335 }
3336 if (NULL != dht_put)
3337 {
3339 dht_put = NULL;
3340 }
3341 if (NULL != dht)
3342 {
3344 dht = NULL;
3345 }
3346 if (NULL != stats)
3347 {
3349 GNUNET_NO);
3350 stats = NULL;
3351 }
3352 for (i = 0; i < 8; i++)
3354}
3355
3356
3364static void
3365add_services (int proto,
3366 char *cpy,
3367 const char *name)
3368{
3369 char *redirect;
3370 char *hostname;
3371 char *hostport;
3372 struct LocalService *serv;
3373 char *n;
3374 size_t slen;
3375 int local_port;
3376 int remote_port;
3377
3378 slen = strlen (name);
3379 GNUNET_assert (slen >= 8);
3380 n = GNUNET_strndup (name, slen - 8 /* remove .gnunet. */);
3381
3382 for (redirect = strtok (cpy, " ;"); redirect != NULL;
3383 redirect = strtok (NULL, " ;"))
3384 {
3385 if (NULL == (hostname = strstr (redirect, ":")))
3386 {
3388 _ (
3389 "Option `%s' for domain `%s' is not formatted correctly!\n")
3390 ,
3391 redirect,
3392 name);
3393 continue;
3394 }
3395 hostname[0] = '\0';
3396 hostname++;
3397 if (NULL == (hostport = strstr (hostname, ":")))
3398 {
3400 _ (
3401 "Option `%s' for domain `%s' is not formatted correctly!\n")
3402 ,
3403 redirect,
3404 name);
3405 continue;
3406 }
3407 hostport[0] = '\0';
3408 hostport++;
3409
3410 local_port = atoi (redirect);
3411 remote_port = atoi (hostport);
3412
3413 if (! ((local_port > 0) && (local_port < 65536)))
3414 {
3416 _ ("`%s' is not a valid port number (for domain `%s')!"),
3417 redirect,
3418 name);
3419 continue;
3420 }
3421 if (! ((remote_port > 0) && (remote_port < 65536)))
3422 {
3424 _ ("`%s' is not a valid port number (for domain `%s')!"),
3425 hostport,
3426 name);
3427 continue;
3428 }
3429
3430 serv = GNUNET_new (struct LocalService);
3431 serv->address.proto = proto;
3432 serv->address.port = remote_port;
3433 if (0 == strcmp ("localhost4",
3434 hostname))
3435 {
3436 const char *ip4addr = exit_argv[5];
3437
3438 serv->address.af = AF_INET;
3439 GNUNET_assert (1 == inet_pton (AF_INET,
3440 ip4addr,
3441 &serv->address.address.ipv4));
3442 }
3443 else if (0 == strcmp ("localhost6",
3444 hostname))
3445 {
3446 const char *ip6addr = exit_argv[3];
3447
3448 serv->address.af = AF_INET6;
3449 GNUNET_assert (1 == inet_pton (AF_INET6,
3450 ip6addr,
3451 &serv->address.address.ipv6));
3452 }
3453 else
3454 {
3455 struct addrinfo *res;
3456 int ret;
3457
3458 ret = getaddrinfo (hostname,
3459 NULL,
3460 NULL,
3461 &res);
3462 if ((0 != ret) || (NULL == res))
3463 {
3465 _ (
3466 "No addresses found for hostname `%s' of service `%s'!\n")
3467 ,
3468 hostname,
3469 n);
3470 GNUNET_free (serv);
3471 continue;
3472 }
3473
3474 serv->address.af = res->ai_family;
3475 switch (res->ai_family)
3476 {
3477 case AF_INET:
3478 if (! ipv4_enabled)
3479 {
3481 _ (
3482 "Service `%s' configured for IPv4, but IPv4 is disabled!\n"),
3483 n);
3484 freeaddrinfo (res);
3485 GNUNET_free (serv);
3486 continue;
3487 }
3488 serv->address.address.ipv4
3489 = ((struct sockaddr_in *) res->ai_addr)->sin_addr;
3490 break;
3491
3492 case AF_INET6:
3493 if (! ipv6_enabled)
3494 {
3496 _ (
3497 "Service `%s' configured for IPv4, but IPv4 is disabled!\n"),
3498 n);
3499 freeaddrinfo (res);
3500 GNUNET_free (serv);
3501 continue;
3502 }
3503 serv->address.address.ipv6
3504 = ((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
3505 break;
3506
3507 default:
3508 freeaddrinfo (res);
3510 _ (
3511 "No IP addresses found for hostname `%s' of service `%s'!\n"),
3512 hostname,
3513 n);
3514 GNUNET_free (serv);
3515 continue;
3516 }
3517 freeaddrinfo (res);
3518 }
3520 n,
3521 local_port,
3522 serv);
3523 }
3524 GNUNET_free (n);
3525}
3526
3527
3534static void
3535read_service_conf (void *cls,
3536 const char *section)
3537{
3538 char *cpy;
3539
3540 if ((strlen (section) < 8) ||
3541 (0 != strcmp (".gnunet.", section + (strlen (section) - 8))))
3542 return;
3543 if (GNUNET_OK ==
3545 section,
3546 "UDP_REDIRECTS",
3547 &cpy))
3548 {
3549 add_services (IPPROTO_UDP,
3550 cpy,
3551 section);
3552 GNUNET_free (cpy);
3553 }
3554 if (GNUNET_OK ==
3556 section,
3557 "TCP_REDIRECTS",
3558 &cpy))
3559 {
3560 add_services (IPPROTO_TCP,
3561 cpy,
3562 section);
3563 GNUNET_free (cpy);
3564 }
3565}
3566
3567
3574static void
3575do_dht_put (void *cls);
3576
3577
3584static void
3585dht_put_cont (void *cls)
3586{
3587 dht_put = NULL;
3588}
3589
3590
3591static void
3592sign_dns_advertisement (void *cls,
3593 const struct GNUNET_PeerIdentity *pid,
3594 const struct GNUNET_CRYPTO_EddsaSignature *sig)
3595{
3596 GNUNET_assert (sig);
3597
3598 sign_op = NULL;
3599
3601 sizeof (dns_advertisement.signature));
3602
3603 do_dht_put (cls);
3604}
3605
3606
3613static void
3614do_dht_put (void *cls)
3615{
3617
3619 &do_dht_put,
3620 NULL);
3624 {
3625 /* refresh advertisement */
3628
3629 if (NULL != sign_op)
3631
3633 purpose,
3635 return;
3636 }
3637 if (NULL != dht_put)
3640 &dht_put_key,
3641 1 /* replication */,
3644 sizeof(struct GNUNET_DNS_Advertisement),
3646 expiration,
3647 &dht_put_cont,
3648 NULL);
3649}
3650
3651
3652static void
3653do_initial_dht_put (void *cls,
3654 const struct GNUNET_HELLO_Parser *parser,
3655 const struct GNUNET_HashCode *hash)
3656{
3657 const struct GNUNET_PeerIdentity *my_identity;
3658
3661
3663 my_identity, sizeof (*my_identity));
3664 dns_advertisement.purpose.size = htonl (sizeof(struct
3666 - sizeof(struct
3668 );
3671 GNUNET_CRYPTO_hash ("dns",
3672 strlen ("dns"),
3673 &dht_put_key);
3674
3675 if (NULL != sign_op)
3676 {
3678 sign_op = NULL;
3679 }
3680
3681 if (NULL != dht_task)
3683
3685 NULL);
3686}
3687
3688
3693static void
3695{
3697 "exit",
3698 "EXIT_IPV4");
3700 "exit",
3701 "EXIT_IPV6");
3703 "exit",
3704 "ENABLE_IPV4");
3706 "exit",
3707 "ENABLE_IPV6");
3708 if ((ipv4_exit || ipv4_enabled) &&
3709 (GNUNET_OK != GNUNET_NETWORK_test_pf (PF_INET)) )
3710 {
3712 _ (
3713 "This system does not support IPv4, will disable IPv4 functions despite them being enabled in the configuration\n"));
3716 }
3717 if ((ipv6_exit || ipv6_enabled) &&
3718 (GNUNET_OK != GNUNET_NETWORK_test_pf (PF_INET6)) )
3719 {
3721 _ (
3722 "This system does not support IPv6, will disable IPv6 functions despite them being enabled in the configuration\n"));
3725 }
3726 if (ipv4_exit && (! ipv4_enabled))
3727 {
3729 _ (
3730 "Cannot enable IPv4 exit but disable IPv4 on TUN interface, will use ENABLE_IPv4=YES\n"));
3732 }
3733 if (ipv6_exit && (! ipv6_enabled))
3734 {
3736 _ (
3737 "Cannot enable IPv6 exit but disable IPv6 on TUN interface, will use ENABLE_IPv6=YES\n"));
3739 }
3740}
3741
3742
3747static void
3749{
3751 GNUNET_MQ_hd_var_size (dns_request,
3753 struct DnsResponseMessage,
3754 NULL),
3756 };
3757 char *dns_exit;
3758 struct GNUNET_HashCode port;
3759
3760 if (GNUNET_YES !=
3762 "exit",
3763 "EXIT_DNS"))
3764 return;
3765 GNUNET_assert (NULL != (dnsstub = GNUNET_DNSSTUB_start (128)));
3766 dns_exit = NULL;
3767 /* TODO: support using multiple DNS resolvers */
3768 if ((GNUNET_OK !=
3770 "exit",
3771 "DNS_RESOLVER",
3772 &dns_exit)) ||
3773 (GNUNET_OK !=
3775 dns_exit)))
3776 {
3778 "dns",
3779 "DNS_RESOLVER",
3780 _ ("need a valid IPv4 or IPv6 address\n"));
3781 GNUNET_free (dns_exit);
3782 return;
3783 }
3784 /* open port */
3787 &port);
3789 "Opening CADET port %s for DNS exit service\n",
3790 GNUNET_h2s (&port));
3792 &port,
3793 &new_channel,
3794 NULL,
3795 NULL,
3797 handlers);
3798 /* advertise exit */
3799 dht = GNUNET_DHT_connect (cfg, 1);
3800 dht_task = NULL;
3802 sign_op = NULL;
3803 GNUNET_free (dns_exit);
3804}
3805
3806
3812static int
3814{
3815 char *exit_ifname;
3816 char *tun_ifname;
3817 char *ipv6addr;
3818 char *ipv6prefix_s;
3819 char *ipv4addr;
3820 char *ipv4mask;
3821
3822 exit_argv[0] = GNUNET_strdup ("exit-gnunet");
3823 if (GNUNET_SYSERR ==
3825 "exit",
3826 "TUN_IFNAME",
3827 &tun_ifname))
3828 {
3830 "EXIT",
3831 "TUN_IFNAME");
3832 return GNUNET_SYSERR;
3833 }
3834 exit_argv[1] = tun_ifname;
3835 if (ipv4_enabled)
3836 {
3837 if (GNUNET_SYSERR ==
3839 "exit",
3840 "EXIT_IFNAME",
3841 &exit_ifname))
3842 {
3844 "EXIT",
3845 "EXIT_IFNAME");
3846 return GNUNET_SYSERR;
3847 }
3848 exit_argv[2] = exit_ifname;
3849 }
3850 else
3851 {
3852 exit_argv[2] = GNUNET_strdup ("-");
3853 }
3854
3855 if (GNUNET_YES == ipv6_enabled)
3856 {
3857 ipv6addr = NULL;
3858 if (((GNUNET_SYSERR ==
3860 "exit",
3861 "IPV6ADDR",
3862 &ipv6addr)) ||
3863 (1 != inet_pton (AF_INET6,
3864 ipv6addr,
3865 &exit_ipv6addr))))
3866 {
3868 "EXIT",
3869 "IPV6ADDR");
3870 GNUNET_free (ipv6addr);
3871 return GNUNET_SYSERR;
3872 }
3873 exit_argv[3] = ipv6addr;
3874 if (GNUNET_SYSERR ==
3876 "exit",
3877 "IPV6PREFIX",
3878 &ipv6prefix_s))
3879 {
3881 "EXIT",
3882 "IPV6PREFIX");
3883 return GNUNET_SYSERR;
3884 }
3885 exit_argv[4] = ipv6prefix_s;
3886 if ((GNUNET_OK !=
3888 "exit",
3889 "IPV6PREFIX",
3890 &ipv6prefix)) ||
3891 (ipv6prefix >= 127))
3892 {
3894 "EXIT",
3895 "IPV6PREFIX",
3896 _ ("Must be a number"));
3897 return GNUNET_SYSERR;
3898 }
3899 }
3900 else
3901 {
3902 /* IPv6 explicitly disabled */
3903 exit_argv[3] = GNUNET_strdup ("-");
3904 exit_argv[4] = GNUNET_strdup ("-");
3905 }
3906 if (GNUNET_YES == ipv4_enabled)
3907 {
3908 ipv4addr = NULL;
3909 if (((GNUNET_SYSERR ==
3911 "exit",
3912 "IPV4ADDR",
3913 &ipv4addr)) ||
3914 (1 != inet_pton (AF_INET,
3915 ipv4addr,
3916 &exit_ipv4addr))))
3917 {
3919 "EXIT",
3920 "IPV4ADDR");
3921 GNUNET_free (ipv4addr);
3922 return GNUNET_SYSERR;
3923 }
3924 exit_argv[5] = ipv4addr;
3925 ipv4mask = NULL;
3926 if (((GNUNET_SYSERR ==
3928 "exit",
3929 "IPV4MASK",
3930 &ipv4mask)) ||
3931 (1 != inet_pton (AF_INET,
3932 ipv4mask,
3933 &exit_ipv4mask))))
3934 {
3936 "EXIT",
3937 "IPV4MASK");
3938 GNUNET_free (ipv4mask);
3939 return GNUNET_SYSERR;
3940 }
3941 exit_argv[6] = ipv4mask;
3942 }
3943 else
3944 {
3945 /* IPv4 explicitly disabled */
3946 exit_argv[5] = GNUNET_strdup ("-");
3947 exit_argv[6] = GNUNET_strdup ("-");
3948 }
3949 exit_argv[7] = NULL;
3950 return GNUNET_OK;
3951}
3952
3953
3962static void
3963run (void *cls,
3964 char *const *args,
3965 const char *cfgfile,
3966 const struct GNUNET_CONFIGURATION_Handle *cfg_)
3967{
3969 GNUNET_MQ_hd_var_size (icmp_remote,
3972 NULL),
3973 GNUNET_MQ_hd_var_size (udp_remote,
3976 NULL),
3977 GNUNET_MQ_hd_var_size (tcp_remote,
3980 NULL),
3981 GNUNET_MQ_hd_var_size (tcp_data,
3984 NULL),
3986 };
3987 struct GNUNET_HashCode port;
3988 char *policy;
3989 char *binary;
3990 char *regex;
3991 char *prefixed_regex;
3992
3993 cfg = cfg_;
3994 if (GNUNET_OK !=
3996 "exit",
3997 "MAX_CONNECTIONS",
3999 max_connections = 1024;
4003 cfg,
4004 "gnunet-helper-exit");
4005 if ((ipv4_exit) || (ipv6_exit))
4006 {
4007 if (GNUNET_YES !=
4009 GNUNET_YES,
4010 "gnunet-vpn - - - 169.1.3.7 255.255.255.0"))
4011 // no nat, ipv4 only
4012 {
4013 GNUNET_free (binary);
4015 _ (
4016 "`%s' is not SUID or the path is invalid, EXIT will not work\n"),
4017 "gnunet-helper-exit");
4019 NULL);
4020 global_ret = 1;
4021 return;
4022 }
4023 }
4024 if (! (ipv4_enabled || ipv6_enabled))
4025 {
4026 GNUNET_free (binary);
4028 _ ("No useful service enabled. Exiting.\n"));
4030 return;
4031 }
4032
4034 NULL);
4036 cfg);
4038 if (NULL == cadet_handle)
4039 {
4040 GNUNET_free (binary);
4042 return;
4043 }
4045 if (GNUNET_OK !=
4047 {
4048 GNUNET_free (binary);
4050 return;
4051 }
4052
4054 GNUNET_NO);
4056 GNUNET_NO);
4061 NULL);
4062
4063 /* Cadet handle acquired, now open ports and announce regular
4064 expressions matching our exit */
4065 if ((GNUNET_YES == ipv4_enabled) &&
4066 (GNUNET_YES == ipv4_exit))
4067 {
4070 &port);
4072 "Opening CADET port %s for IPv4 gateway service\n",
4073 GNUNET_h2s (&port));
4075 &port,
4076 &new_channel,
4077 NULL,
4078 NULL,
4080 handlers);
4081 policy = NULL;
4082 if (GNUNET_OK !=
4084 "exit",
4085 "EXIT_RANGE_IPV4_POLICY",
4086 &policy))
4087 regex = NULL;
4088 else
4089 regex = GNUNET_REGEX_ipv4policy2regex (policy);
4090 GNUNET_free (policy);
4091 if (NULL != regex)
4092 {
4093 (void) GNUNET_asprintf (&prefixed_regex,
4094 "%s%s",
4096 regex);
4098 prefixed_regex,
4101 GNUNET_free (regex);
4102 GNUNET_free (prefixed_regex);
4103 }
4104 }
4105
4107 {
4110 &port);
4112 "Opening CADET port %s for IPv6 gateway service\n",
4113 GNUNET_h2s (&port));
4115 &port,
4116 &new_channel,
4117 NULL,
4118 NULL,
4120 handlers);
4121 policy = NULL;
4122 if (GNUNET_OK !=
4124 "exit",
4125 "EXIT_RANGE_IPV6_POLICY",
4126 &policy))
4127 regex = NULL;
4128 else
4129 regex = GNUNET_REGEX_ipv6policy2regex (policy);
4130 GNUNET_free (policy);
4131 if (NULL != regex)
4132 {
4133 (void) GNUNET_asprintf (&prefixed_regex,
4134 "%s%s",
4136 regex);
4138 prefixed_regex,
4141 GNUNET_free (regex);
4142 GNUNET_free (prefixed_regex);
4143 }
4144 }
4146 GNUNET_NO,
4147 binary,
4148 exit_argv,
4150 NULL,
4151 NULL);
4152 GNUNET_free (binary);
4153}
4154
4155
4163int
4164main (int argc,
4165 char *const *argv)
4166{
4167 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
4169 };
4170
4171 return (GNUNET_OK ==
4173 argc,
4174 argv,
4175 "gnunet-daemon-exit",
4176 gettext_noop (
4177 "Daemon to run to provide an IP exit node for the VPN"),
4178 options,
4179 &run,
4180 NULL)) ? global_ret : 1;
4181}
4182
4183
4184/* 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.
char * GNUNET_CONFIGURATION_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_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(uint32_t i)
Produce a random value.
void GNUNET_DHT_put_cancel(struct GNUNET_DHT_PutHandle *ph)
Cancels a DHT PUT operation.
Definition dht_api.c:1149
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:1086
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:1058
@ GNUNET_DHT_RO_NONE
Default.
struct GNUNET_DNSSTUB_Context * GNUNET_DNSSTUB_start(unsigned int num_sockets)
Start a DNS stub resolver.
Definition dnsstub.c:585
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:612
void GNUNET_DNSSTUB_stop(struct GNUNET_DNSSTUB_Context *ctx)
Cleanup DNSSTUB resolver.
Definition dnsstub.c:704
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:525
#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:40
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.
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:406
#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 ...
union ChannelState::@78 destination_ip
Destination IP address used by the source on our end (this is the IP that we pick freely within the V...
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.
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;
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}

References ChannelState::channel, channels, ChannelState::dns, dnsstub, GNUNET_ALIGN, GNUNET_break_op, GNUNET_CADET_receive_done(), 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 577 of file gnunet-daemon-exit.c.

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}

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 655 of file gnunet-daemon-exit.c.

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}

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 715 of file gnunet-daemon-exit.c.

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}

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 768 of file gnunet-daemon-exit.c.

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}

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 872 of file gnunet-daemon-exit.c.

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}

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 965 of file gnunet-daemon-exit.c.

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}

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 1071 of file gnunet-daemon-exit.c.

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}

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 1183 of file gnunet-daemon-exit.c.

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

References SocketAddress::address, SocketAddress::af, exit_ipv4addr, exit_ipv4mask, exit_ipv6addr, GNUNET_assert, 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 1295 of file gnunet-daemon-exit.c.

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

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 1365 of file gnunet-daemon-exit.c.

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

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 1466 of file gnunet-daemon-exit.c.

1468{
1469 struct ChannelState *state = cls;
1470
1471 if (GNUNET_YES == state->is_dns)
1472 {
1473 GNUNET_break_op (0);
1474 return GNUNET_SYSERR;
1475 }
1476 return GNUNET_OK;
1477}

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 1487 of file gnunet-daemon-exit.c.

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

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 1586 of file gnunet-daemon-exit.c.

1588{
1589 struct ChannelState *state = cls;
1590
1591 if (NULL == state->specifics.tcp_udp.serv)
1592 {
1593 GNUNET_break_op (0);
1594 return GNUNET_SYSERR;
1595 }
1596 return GNUNET_OK;
1597}

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 1608 of file gnunet-daemon-exit.c.

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

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 1648 of file gnunet-daemon-exit.c.

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

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 1695 of file gnunet-daemon-exit.c.

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

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 1732 of file gnunet-daemon-exit.c.

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

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 1830 of file gnunet-daemon-exit.c.

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

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 1868 of file gnunet-daemon-exit.c.

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

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 1919 of file gnunet-daemon-exit.c.

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

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 1949 of file gnunet-daemon-exit.c.

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

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 1978 of file gnunet-daemon-exit.c.

1980{
1981 struct ChannelState *state = cls;
1982
1983 if (GNUNET_YES == state->is_dns)
1984 {
1985 GNUNET_break_op (0);
1986 return GNUNET_SYSERR;
1987 }
1988 return GNUNET_OK;
1989}

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 1999 of file gnunet-daemon-exit.c.

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

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 2199 of file gnunet-daemon-exit.c.

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

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 2251 of file gnunet-daemon-exit.c.

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

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 2278 of file gnunet-daemon-exit.c.

2280{
2281 struct ChannelState *state = cls;
2282 uint16_t pkt_len = ntohs (msg->header.size) - sizeof(struct
2284 struct GNUNET_TUN_IcmpHeader icmp;
2285 char buf[sizeof(struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
2286 const void *payload;
2287
2289 gettext_noop ("# Bytes received from CADET"),
2290 pkt_len, GNUNET_NO);
2292 gettext_noop (
2293 "# ICMP service requests received via cadet"),
2294 1, GNUNET_NO);
2295 /* check that we got at least a valid header */
2297 "Received data from %s for forwarding to ICMP service %s\n",
2298 GNUNET_i2s (&state->peer),
2299 GNUNET_h2s (&state->specifics.tcp_udp.serv->descriptor));
2300 icmp = msg->icmp_header;
2301 payload = &msg[1];
2302 state->specifics.tcp_udp.ri.remote_address
2303 = state->specifics.tcp_udp.serv->address;
2305
2306 /* check that ICMP type is something we want to support,
2307 perform ICMP PT if needed and possibly make up payload */
2308 switch (msg->af)
2309 {
2310 case AF_INET:
2311 switch (msg->icmp_header.type)
2312 {
2314 if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2316 break;
2317
2319 if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2321 break;
2322
2324 if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2326 if (0 != pkt_len)
2327 {
2328 GNUNET_break_op (0);
2329 return;
2330 }
2331 payload = buf;
2332 pkt_len = make_up_icmp_service_payload (state, buf);
2333 break;
2334
2336 if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2338 if (0 != pkt_len)
2339 {
2340 GNUNET_break_op (0);
2341 return;
2342 }
2343 payload = buf;
2344 pkt_len = make_up_icmp_service_payload (state, buf);
2345 break;
2346
2348 if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2349 {
2351 gettext_noop (
2352 "# ICMPv4 packets dropped (impossible PT to v6)"),
2353 1, GNUNET_NO);
2354 return;
2355 }
2356 if (0 != pkt_len)
2357 {
2358 GNUNET_break_op (0);
2359 return;
2360 }
2361 payload = buf;
2362 pkt_len = make_up_icmp_service_payload (state, buf);
2363 break;
2364
2365 default:
2366 GNUNET_break_op (0);
2368 gettext_noop (
2369 "# ICMPv4 packets dropped (type not allowed)")
2370 ,
2371 1, GNUNET_NO);
2372 return;
2373 }
2374 /* end of AF_INET */
2375 break;
2376
2377 case AF_INET6:
2378 switch (msg->icmp_header.type)
2379 {
2381 if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2383 break;
2384
2386 if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2388 break;
2389
2391 if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2393 if (0 != pkt_len)
2394 {
2395 GNUNET_break_op (0);
2396 return;
2397 }
2398 payload = buf;
2399 pkt_len = make_up_icmp_service_payload (state, buf);
2400 break;
2401
2403 if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2405 if (0 != pkt_len)
2406 {
2407 GNUNET_break_op (0);
2408 return;
2409 }
2410 payload = buf;
2411 pkt_len = make_up_icmp_service_payload (state, buf);
2412 break;
2413
2416 if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2417 {
2419 gettext_noop (
2420 "# ICMPv6 packets dropped (impossible PT to v4)"),
2421 1, GNUNET_NO);
2422 return;
2423 }
2424 if (0 != pkt_len)
2425 {
2426 GNUNET_break_op (0);
2427 return;
2428 }
2429 payload = buf;
2430 pkt_len = make_up_icmp_service_payload (state, buf);
2431 break;
2432
2433 default:
2434 GNUNET_break_op (0);
2436 gettext_noop (
2437 "# ICMPv6 packets dropped (type not allowed)")
2438 ,
2439 1, GNUNET_NO);
2440 return;
2441 }
2442 /* end of AF_INET6 */
2443 break;
2444
2445 default:
2446 GNUNET_break_op (0);
2447 return;
2448 }
2449
2450 send_icmp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
2451 &state->specifics.tcp_udp.ri.local_address,
2452 &icmp,
2453 payload,
2454 pkt_len);
2456}

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 2468 of file gnunet-daemon-exit.c.

2471{
2472 struct LocalService *service = value;
2473
2476 key,
2477 service));
2479 GNUNET_free (service->name);
2481 return GNUNET_OK;
2482}

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 2494 of file gnunet-daemon-exit.c.

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

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 2524 of file gnunet-daemon-exit.c.

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

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 2568 of file gnunet-daemon-exit.c.

2572{
2574 GNUNET_MQ_hd_var_size (icmp_service,
2577 service),
2578 GNUNET_MQ_hd_var_size (udp_service,
2581 service),
2582 GNUNET_MQ_hd_var_size (tcp_service,
2585 service),
2586 GNUNET_MQ_hd_var_size (tcp_data,
2589 service),
2591 };
2592
2594
2595 service->name = GNUNET_strdup (name);
2597 &service->descriptor);
2599 destination_port,
2600 &cadet_port);
2602 "Opening CADET port %s for SERVICE exit %s on port %u\n",
2604 name,
2605 (unsigned int) destination_port);
2607 &cadet_port,
2609 service,
2610 NULL,
2612 handlers);
2613 service->is_udp = (IPPROTO_UDP == proto);
2614 if (GNUNET_OK !=
2616 &cadet_port,
2617 service,
2619 {
2621 GNUNET_free (service->name);
2624 _ ("Got duplicate service records for `%s:%u'\n"),
2625 name,
2626 (unsigned int) destination_port);
2627 }
2628}

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 2638 of file gnunet-daemon-exit.c.

2640{
2641 GNUNET_assert (NULL != s);
2643 gettext_noop (
2644 "# Messages transmitted via cadet channels"),
2645 1,
2646 GNUNET_NO);
2648 env);
2649}

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 2664 of file gnunet-daemon-exit.c.

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

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 2874 of file gnunet-daemon-exit.c.

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

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 2951 of file gnunet-daemon-exit.c.

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

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 3035 of file gnunet-daemon-exit.c.

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

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 3197 of file gnunet-daemon-exit.c.

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

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 3225 of file gnunet-daemon-exit.c.

3228{
3230 return GNUNET_YES;
3231}

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 3243 of file gnunet-daemon-exit.c.

3244{
3245 /* just terminate */
3246}

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 3255 of file gnunet-daemon-exit.c.

3256{
3257 unsigned int i;
3258
3260 "Exit service is shutting down now\n");
3261
3262 if (NULL != helper_handle)
3263 {
3265 helper_handle = NULL;
3266 }
3267 if (NULL != regex4)
3268 {
3270 regex4 = NULL;
3271 }
3272 if (NULL != regex6)
3273 {
3275 regex6 = NULL;
3276 }
3277 if (NULL != services)
3278 {
3281 NULL);
3283 }
3284 if (NULL != dns_port)
3285 {
3287 dns_port = NULL;
3288 }
3289 if (NULL != cadet_port4)
3290 {
3292 cadet_port4 = NULL;
3293 }
3294 if (NULL != cadet_port6)
3295 {
3297 cadet_port6 = NULL;
3298 }
3299 if (NULL != cadet_handle)
3300 {
3302 cadet_handle = NULL;
3303 }
3304 if (NULL != connections_map)
3305 {
3307 &free_iterate,
3308 NULL);
3310 connections_map = NULL;
3311 }
3312 if (NULL != connections_heap)
3313 {
3315 connections_heap = NULL;
3316 }
3317 if (NULL != dnsstub)
3318 {
3320 dnsstub = NULL;
3321 }
3322 if (NULL != sign_op)
3323 {
3325 sign_op = NULL;
3326 }
3327 if (NULL != pils)
3328 {
3330 pils = NULL;
3331 }
3332 if (NULL != dht_task)
3333 {
3335 dht_task = NULL;
3336 }
3337 if (NULL != dht_put)
3338 {
3340 dht_put = NULL;
3341 }
3342 if (NULL != dht)
3343 {
3345 dht = NULL;
3346 }
3347 if (NULL != stats)
3348 {
3350 GNUNET_NO);
3351 stats = NULL;
3352 }
3353 for (i = 0; i < 8; i++)
3355}

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 3366 of file gnunet-daemon-exit.c.

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

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 3536 of file gnunet-daemon-exit.c.

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

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 3615 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 3586 of file gnunet-daemon-exit.c.

3587{
3588 dht_put = NULL;
3589}

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 3593 of file gnunet-daemon-exit.c.

3596{
3597 GNUNET_assert (sig);
3598
3599 sign_op = NULL;
3600
3602 sizeof (dns_advertisement.signature));
3603
3604 do_dht_put (cls);
3605}

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 3654 of file gnunet-daemon-exit.c.

3657{
3658 const struct GNUNET_PeerIdentity *my_identity;
3659
3662
3664 my_identity, sizeof (*my_identity));
3665 dns_advertisement.purpose.size = htonl (sizeof(struct
3667 - sizeof(struct
3669 );
3672 GNUNET_CRYPTO_hash ("dns",
3673 strlen ("dns"),
3674 &dht_put_key);
3675
3676 if (NULL != sign_op)
3677 {
3679 sign_op = NULL;
3680 }
3681
3682 if (NULL != dht_task)
3684
3686 NULL);
3687}

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 3695 of file gnunet-daemon-exit.c.

3696{
3698 "exit",
3699 "EXIT_IPV4");
3701 "exit",
3702 "EXIT_IPV6");
3704 "exit",
3705 "ENABLE_IPV4");
3707 "exit",
3708 "ENABLE_IPV6");
3709 if ((ipv4_exit || ipv4_enabled) &&
3710 (GNUNET_OK != GNUNET_NETWORK_test_pf (PF_INET)) )
3711 {
3713 _ (
3714 "This system does not support IPv4, will disable IPv4 functions despite them being enabled in the configuration\n"));
3717 }
3718 if ((ipv6_exit || ipv6_enabled) &&
3719 (GNUNET_OK != GNUNET_NETWORK_test_pf (PF_INET6)) )
3720 {
3722 _ (
3723 "This system does not support IPv6, will disable IPv6 functions despite them being enabled in the configuration\n"));
3726 }
3727 if (ipv4_exit && (! ipv4_enabled))
3728 {
3730 _ (
3731 "Cannot enable IPv4 exit but disable IPv4 on TUN interface, will use ENABLE_IPv4=YES\n"));
3733 }
3734 if (ipv6_exit && (! ipv6_enabled))
3735 {
3737 _ (
3738 "Cannot enable IPv6 exit but disable IPv6 on TUN interface, will use ENABLE_IPv6=YES\n"));
3740 }
3741}

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 3749 of file gnunet-daemon-exit.c.

3750{
3752 GNUNET_MQ_hd_var_size (dns_request,
3754 struct DnsResponseMessage,
3755 NULL),
3757 };
3758 char *dns_exit;
3759 struct GNUNET_HashCode port;
3760
3761 if (GNUNET_YES !=
3763 "exit",
3764 "EXIT_DNS"))
3765 return;
3766 GNUNET_assert (NULL != (dnsstub = GNUNET_DNSSTUB_start (128)));
3767 dns_exit = NULL;
3768 /* TODO: support using multiple DNS resolvers */
3769 if ((GNUNET_OK !=
3771 "exit",
3772 "DNS_RESOLVER",
3773 &dns_exit)) ||
3774 (GNUNET_OK !=
3776 dns_exit)))
3777 {
3779 "dns",
3780 "DNS_RESOLVER",
3781 _ ("need a valid IPv4 or IPv6 address\n"));
3782 GNUNET_free (dns_exit);
3783 return;
3784 }
3785 /* open port */
3788 &port);
3790 "Opening CADET port %s for DNS exit service\n",
3791 GNUNET_h2s (&port));
3793 &port,
3794 &new_channel,
3795 NULL,
3796 NULL,
3798 handlers);
3799 /* advertise exit */
3800 dht = GNUNET_DHT_connect (cfg, 1);
3801 dht_task = NULL;
3803 sign_op = NULL;
3804 GNUNET_free (dns_exit);
3805}

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 3814 of file gnunet-daemon-exit.c.

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

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 3964 of file gnunet-daemon-exit.c.

3968{
3970 GNUNET_MQ_hd_var_size (icmp_remote,
3973 NULL),
3974 GNUNET_MQ_hd_var_size (udp_remote,
3977 NULL),
3978 GNUNET_MQ_hd_var_size (tcp_remote,
3981 NULL),
3982 GNUNET_MQ_hd_var_size (tcp_data,
3985 NULL),
3987 };
3988 struct GNUNET_HashCode port;
3989 char *policy;
3990 char *binary;
3991 char *regex;
3992 char *prefixed_regex;
3993
3994 cfg = cfg_;
3995 if (GNUNET_OK !=
3997 "exit",
3998 "MAX_CONNECTIONS",
4000 max_connections = 1024;
4004 cfg,
4005 "gnunet-helper-exit");
4006 if ((ipv4_exit) || (ipv6_exit))
4007 {
4008 if (GNUNET_YES !=
4010 GNUNET_YES,
4011 "gnunet-vpn - - - 169.1.3.7 255.255.255.0"))
4012 // no nat, ipv4 only
4013 {
4014 GNUNET_free (binary);
4016 _ (
4017 "`%s' is not SUID or the path is invalid, EXIT will not work\n"),
4018 "gnunet-helper-exit");
4020 NULL);
4021 global_ret = 1;
4022 return;
4023 }
4024 }
4025 if (! (ipv4_enabled || ipv6_enabled))
4026 {
4027 GNUNET_free (binary);
4029 _ ("No useful service enabled. Exiting.\n"));
4031 return;
4032 }
4033
4035 NULL);
4037 cfg);
4039 if (NULL == cadet_handle)
4040 {
4041 GNUNET_free (binary);
4043 return;
4044 }
4046 if (GNUNET_OK !=
4048 {
4049 GNUNET_free (binary);
4051 return;
4052 }
4053
4055 GNUNET_NO);
4057 GNUNET_NO);
4062 NULL);
4063
4064 /* Cadet handle acquired, now open ports and announce regular
4065 expressions matching our exit */
4066 if ((GNUNET_YES == ipv4_enabled) &&
4067 (GNUNET_YES == ipv4_exit))
4068 {
4071 &port);
4073 "Opening CADET port %s for IPv4 gateway service\n",
4074 GNUNET_h2s (&port));
4076 &port,
4077 &new_channel,
4078 NULL,
4079 NULL,
4081 handlers);
4082 policy = NULL;
4083 if (GNUNET_OK !=
4085 "exit",
4086 "EXIT_RANGE_IPV4_POLICY",
4087 &policy))
4088 regex = NULL;
4089 else
4090 regex = GNUNET_REGEX_ipv4policy2regex (policy);
4091 GNUNET_free (policy);
4092 if (NULL != regex)
4093 {
4094 (void) GNUNET_asprintf (&prefixed_regex,
4095 "%s%s",
4097 regex);
4099 prefixed_regex,
4102 GNUNET_free (regex);
4103 GNUNET_free (prefixed_regex);
4104 }
4105 }
4106
4108 {
4111 &port);
4113 "Opening CADET port %s for IPv6 gateway service\n",
4114 GNUNET_h2s (&port));
4116 &port,
4117 &new_channel,
4118 NULL,
4119 NULL,
4121 handlers);
4122 policy = NULL;
4123 if (GNUNET_OK !=
4125 "exit",
4126 "EXIT_RANGE_IPV6_POLICY",
4127 &policy))
4128 regex = NULL;
4129 else
4130 regex = GNUNET_REGEX_ipv6policy2regex (policy);
4131 GNUNET_free (policy);
4132 if (NULL != regex)
4133 {
4134 (void) GNUNET_asprintf (&prefixed_regex,
4135 "%s%s",
4137 regex);
4139 prefixed_regex,
4142 GNUNET_free (regex);
4143 GNUNET_free (prefixed_regex);
4144 }
4145 }
4147 GNUNET_NO,
4148 binary,
4149 exit_argv,
4151 NULL,
4152 NULL);
4153 GNUNET_free (binary);
4154}

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_suid_binary_path(), 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_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 4165 of file gnunet-daemon-exit.c.

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

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().