GNUnet  0.11.x
Data Structures | Macros | Functions | Variables
gnunet-daemon-exit.c File Reference

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

#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_dnsparser_lib.h"
#include "gnunet_dnsstub_lib.h"
#include "gnunet_statistics_service.h"
#include "gnunet_constants.h"
#include "gnunet_signatures.h"
#include "gnunet_tun_lib.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. More...
 
#define REGEX_MAX_PATH_LEN_IPV6   8
 Maximum path compression length for cadet regex announcing for IPv6 address based regex. More...
 
#define REGEX_REFRESH_FREQUENCY
 How frequently do we re-announce the regex for the exit? More...
 
#define DHT_PUT_FREQUENCY
 How frequently do we re-announce the DNS exit in the DHT? More...
 
#define DNS_ADVERTISEMENT_TIMEOUT
 How long do we typically sign the DNS exit advertisement for? More...
 
#define LOG(kind, ...)    GNUNET_log_from (kind, "exit", __VA_ARGS__);
 Generic logging shorthand. More...
 

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. More...
 
static int check_dns_request (void *cls, const struct DnsResponseMessage *msg)
 Check a request via cadet to perform a DNS query. More...
 
static void handle_dns_request (void *cls, const struct DnsResponseMessage *msg)
 Process a request via cadet to perform a DNS query. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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). More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
static uint16_t make_up_icmp_service_payload (struct ChannelState *state, char *buf)
 Setup ICMP payload for ICMP error messages. More...
 
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. More...
 
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. More...
 
static int free_service_record (void *cls, const struct GNUNET_HashCode *key, void *value)
 Free memory associated with a service record. More...
 
static void * new_service_channel (void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *initiator)
 Callback from CADET for new channels. More...
 
static void clean_channel (void *cls, const struct GNUNET_CADET_Channel *channel)
 Function called by cadet whenever an inbound channel is destroyed. More...
 
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. More...
 
static void send_packet_to_cadet_channel (struct ChannelState *s, struct GNUNET_MQ_Envelope *env)
 Send the given packet via the cadet channel. More...
 
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. More...
 
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. More...
 
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. More...
 
static int message_token (void *cls, const struct GNUNET_MessageHeader *message)
 Receive packets from the helper-process. More...
 
static void * new_channel (void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *initiator)
 Callback from CADET for new channels. More...
 
static int free_iterate (void *cls, const struct GNUNET_HashCode *hash, void *value)
 Function that frees everything from a hashmap. More...
 
static void dummy_task (void *cls)
 Function scheduled as very last function if the service disabled itself because the helper is not installed properly. More...
 
static void cleanup (void *cls)
 Function scheduled as very last function, cleans up after us. More...
 
static void add_services (int proto, char *cpy, const char *name)
 Add services to the service map. More...
 
static void read_service_conf (void *cls, const char *section)
 Reads the configuration and populates #udp_services and #tcp_services. More...
 
static void do_dht_put (void *cls)
 We are running a DNS exit service, advertise it in the DHT. More...
 
static void dht_put_cont (void *cls)
 Function called when the DHT PUT operation is complete. More...
 
static void parse_ip_options ()
 Figure out which IP versions we should support (and which are supported by the OS) according to our configuration. More...
 
static void advertise_dns_exit ()
 Helper function to open the CADET port for DNS exits and to advertise the DNS exit (if applicable). More...
 
static int setup_exit_helper_args ()
 Initialize exit_argv. More...
 
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. More...
 
int main (int argc, char *const *argv)
 The main function. More...
 

Variables

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

Detailed Description

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

Author
Philipp Toelke
Christian Grothoff

TODO:

Design:

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 58 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 64 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:311

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

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

◆ DHT_PUT_FREQUENCY

#define DHT_PUT_FREQUENCY
Value:

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

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

◆ DNS_ADVERTISEMENT_TIMEOUT

#define DNS_ADVERTISEMENT_TIMEOUT
Value:
#define GNUNET_TIME_UNIT_HOURS
One hour.

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

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

◆ LOG

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

Generic logging shorthand.

Definition at line 88 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 459 of file gnunet-daemon-exit.c.

462 {
463  struct ChannelState *ts;
464  struct GNUNET_MQ_Envelope *env;
465  struct DnsResponseMessage *resp;
466 
468  "Processing DNS result from stub resolver\n");
469  GNUNET_assert (NULL == cls);
470  if (NULL == dns)
471  return;
472  /* Handle case that this is a reply to a request from a CADET DNS channel */
473  ts = channels[dns->id];
474  if (NULL == ts)
475  return;
477  "Got a response from the stub resolver for DNS request received via CADET!\n");
478  channels[dns->id] = NULL;
479  env = GNUNET_MQ_msg_extra (resp,
480  r - sizeof(struct GNUNET_TUN_DnsHeader),
482  GNUNET_memcpy (&resp->dns,
483  dns,
484  r);
485  resp->dns.id = ts->specifics.dns.original_id;
487  env);
488 }
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static struct ChannelState * channels[UINT16_MAX+1]
Array of all open DNS requests from channels.
#define LOG(kind,...)
Generic logging shorthand.
#define GNUNET_log(kind,...)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
struct GNUNET_MQ_Handle * GNUNET_CADET_get_mq(const struct GNUNET_CADET_Channel *channel)
Obtain the message queue for a connected peer.
Definition: cadet_api.c:1082
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
@ GNUNET_ERROR_TYPE_DEBUG
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:355
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
Definition: gnunet_mq_lib.h:52
#define GNUNET_MESSAGE_TYPE_VPN_DNS_FROM_INTERNET
Type of messages containing an DNS reply from a DNS exit service.
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
union ChannelState::@10 specifics
struct GNUNET_CADET_Channel * channel
Cadet channel that is used for this connection.
struct ChannelState::@10::@12 dns
Message with a DNS response.
struct GNUNET_TUN_DnsHeader dns
DNS header.
uint16_t id
Unique identifier for the request/response.

References ChannelState::channel, channels, DnsResponseMessage::dns, ChannelState::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, 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 500 of file gnunet-daemon-exit.c.

502 {
503  struct ChannelState *ts = cls;
504 
505  if (NULL == dnsstub)
506  {
507  GNUNET_break (0);
508  return GNUNET_SYSERR;
509  }
510  if (GNUNET_NO == ts->is_dns)
511  {
512  GNUNET_break_op (0);
513  return GNUNET_SYSERR;
514  }
515  return GNUNET_OK;
516 }
static struct GNUNET_DNSSTUB_Context * dnsstub
Handle to the DNS Stub resolver.
@ GNUNET_OK
Definition: gnunet_common.h:95
@ GNUNET_NO
Definition: gnunet_common.h:94
@ GNUNET_SYSERR
Definition: gnunet_common.h:93
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
int is_dns
GNUNET_NO if this is a channel for TCP/UDP, GNUNET_YES if this is a channel for DNS,...

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

528 {
529  struct ChannelState *ts = cls;
530  size_t mlen = ntohs (msg->header.size);
531  size_t dlen = mlen - sizeof(struct GNUNET_MessageHeader);
532  char buf[dlen] GNUNET_ALIGN;
533  struct GNUNET_TUN_DnsHeader *dns_out;
534 
535  if (GNUNET_SYSERR == ts->is_dns)
536  {
537  /* channel is DNS from now on */
538  ts->is_dns = GNUNET_YES;
539  }
540  ts->specifics.dns.original_id = msg->dns.id;
541  if (channels[ts->specifics.dns.my_id] == ts)
542  channels[ts->specifics.dns.my_id] = NULL;
543  ts->specifics.dns.my_id = (uint16_t) GNUNET_CRYPTO_random_u32 (
545  UINT16_MAX
546  + 1);
547  channels[ts->specifics.dns.my_id] = ts;
549  &msg->dns,
550  dlen);
551  dns_out = (struct GNUNET_TUN_DnsHeader *) buf;
552  dns_out->id = ts->specifics.dns.my_id;
554  buf,
555  dlen,
557  NULL);
558  if (NULL == ts->specifics.dns.rs)
559  {
560  GNUNET_break_op (0);
561  return;
562  }
564 }
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
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 char buf[2048]
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to 'struct's.
@ GNUNET_YES
Definition: gnunet_common.h:97
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Send an ack on the channel to confirm the processing of a message.
Definition: cadet_api.c:888
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
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:504
Header for all communications.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.

References buf, ChannelState::channel, channels, ChannelState::dns, dnsstub, GNUNET_ALIGN, GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_u32(), GNUNET_DNSSTUB_resolve(), GNUNET_memcpy, GNUNET_SYSERR, GNUNET_YES, GNUNET_TUN_DnsHeader::id, ChannelState::is_dns, msg, process_dns_result(), 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 575 of file gnunet-daemon-exit.c.

577 {
578  char *off;
579 
580  memset (hash,
581  0,
582  sizeof(struct GNUNET_HashCode));
583  /* the GNUnet hashmap only uses the first sizeof(unsigned int) of the hash,
584  so we put the IP address in there (and hope for few collisions) */
585  off = (char *) hash;
586  switch (ri->remote_address.af)
587  {
588  case AF_INET:
589  GNUNET_memcpy (off,
591  sizeof(struct in_addr));
592  off += sizeof(struct in_addr);
593  break;
594 
595  case AF_INET6:
596  GNUNET_memcpy (off,
598  sizeof(struct in6_addr));
599  off += sizeof(struct in_addr);
600  break;
601 
602  default:
603  GNUNET_assert (0);
604  }
605  GNUNET_memcpy (off,
606  &ri->remote_address.port,
607  sizeof(uint16_t));
608  off += sizeof(uint16_t);
609  switch (ri->local_address.af)
610  {
611  case AF_INET:
612  GNUNET_memcpy (off,
614  sizeof(struct in_addr));
615  off += sizeof(struct in_addr);
616  break;
617 
618  case AF_INET6:
619  GNUNET_memcpy (off,
621  sizeof(struct in6_addr));
622  off += sizeof(struct in_addr);
623  break;
624 
625  default:
626  GNUNET_assert (0);
627  }
628  GNUNET_memcpy (off,
629  &ri->local_address.port,
630  sizeof(uint16_t));
631  off += sizeof(uint16_t);
632  GNUNET_memcpy (off,
633  &ri->remote_address.proto,
634  sizeof(uint8_t));
635  /* off += sizeof (uint8_t); */
636 }
A 512-bit hashcode.
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").
union SocketAddress::@9 address
Remote address information.
int af
AF_INET or AF_INET6.
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.

References SocketAddress::address, SocketAddress::af, GNUNET_assert, GNUNET_memcpy, SocketAddress::ipv4, SocketAddress::ipv6, RedirectInformation::local_address, SocketAddress::port, SocketAddress::proto, and RedirectInformation::remote_address.

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

660 {
661  struct RedirectInformation ri;
662  struct GNUNET_HashCode key;
663  struct ChannelState *state;
664 
665  if (((af == AF_INET) && (protocol == IPPROTO_ICMP)) ||
666  ((af == AF_INET6) && (protocol == IPPROTO_ICMPV6)))
667  {
668  /* ignore ports */
669  destination_port = 0;
670  local_port = 0;
671  }
673  if (af == AF_INET)
674  ri.remote_address.address.ipv4 = *((struct in_addr*) destination_ip);
675  else
676  ri.remote_address.address.ipv6 = *((struct in6_addr*) destination_ip);
677  ri.remote_address.port = destination_port;
678  ri.remote_address.proto = protocol;
679  ri.local_address.af = af;
680  if (af == AF_INET)
681  ri.local_address.address.ipv4 = *((struct in_addr*) local_ip);
682  else
683  ri.local_address.address.ipv6 = *((struct in6_addr*) local_ip);
684  ri.local_address.port = local_port;
685  ri.local_address.proto = protocol;
687  &ri);
688  if (NULL != state_key)
689  *state_key = key;
691  &key);
692  if (NULL == state)
693  return NULL;
694  /* Mark this connection as freshly used */
695  if (NULL == state_key)
696  GNUNET_CONTAINER_heap_update_cost (state->specifics.tcp_udp.heap_node,
697  GNUNET_TIME_absolute_get ().abs_value_us);
698  return state;
699 }
static struct GNUNET_CONTAINER_MultiHashMap * connections_map
This hashmaps contains the mapping from peer, service-descriptor, source-port and destination-port to...
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...
struct GNUNET_HashCode key
The key used in the DHT.
enum State state
current state of profiling
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.
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_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:86
int af
Address family used for this channel on the local TUN interface.
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.
struct RedirectInformation ri
Primary redirection information for this connection.
Information we use to track a connection (the classical 6-tuple of IP-version, protocol,...

References SocketAddress::address, SocketAddress::af, ChannelState::af, connections_map, ChannelState::destination_port, GNUNET_CONTAINER_heap_update_cost(), GNUNET_CONTAINER_multihashmap_get(), GNUNET_TIME_absolute_get(), hash_redirect_info(), SocketAddress::ipv4, SocketAddress::ipv6, key, RedirectInformation::local_address, SocketAddress::port, SocketAddress::proto, ChannelState::protocol, RedirectInformation::remote_address, ChannelState::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 712 of file gnunet-daemon-exit.c.

714 {
715  struct ChannelState *state = cls;
716 
717  if (NULL == state)
718  {
719  GNUNET_break_op (0);
720  return GNUNET_SYSERR;
721  }
722  if (GNUNET_YES == state->is_dns)
723  {
724  GNUNET_break_op (0);
725  return GNUNET_SYSERR;
726  }
727  if (NULL == state->specifics.tcp_udp.serv)
728  {
729  GNUNET_break_op (0);
730  return GNUNET_SYSERR;
731  }
732  if (NULL != state->specifics.tcp_udp.heap_node)
733  {
734  GNUNET_break_op (0);
735  return GNUNET_SYSERR;
736  }
737  if (start->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
738  {
739  GNUNET_break_op (0);
740  return GNUNET_SYSERR;
741  }
742  return GNUNET_OK;
743 }
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:39
TCP packet header.

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

772 {
773  size_t len;
774 
775  len = payload_length;
776  switch (protocol)
777  {
778  case IPPROTO_UDP:
779  len += sizeof(struct GNUNET_TUN_UdpHeader);
780  break;
781 
782  case IPPROTO_TCP:
783  len += sizeof(struct GNUNET_TUN_TcpHeader);
784  GNUNET_assert (NULL != tcp_header);
785  break;
786 
787  default:
788  GNUNET_break (0);
789  return;
790  }
791  if (len + sizeof(struct GNUNET_TUN_IPv4Header) > UINT16_MAX)
792  {
793  GNUNET_break (0);
794  return;
795  }
796 
798  protocol,
799  len,
800  &src_address->address.ipv4,
801  &dst_address->address.ipv4);
802  switch (protocol)
803  {
804  case IPPROTO_UDP:
805  {
806  struct GNUNET_TUN_UdpHeader *pkt4_udp = (struct
807  GNUNET_TUN_UdpHeader *) &pkt4[1];
808 
809  pkt4_udp->source_port = htons (src_address->port);
810  pkt4_udp->destination_port = htons (dst_address->port);
811  pkt4_udp->len = htons ((uint16_t) payload_length);
813  pkt4_udp,
814  payload,
815  payload_length);
816  GNUNET_memcpy (&pkt4_udp[1],
817  payload,
818  payload_length);
819  }
820  break;
821 
822  case IPPROTO_TCP:
823  {
824  struct GNUNET_TUN_TcpHeader *pkt4_tcp = (struct
825  GNUNET_TUN_TcpHeader *) &pkt4[1];
826 
827  *pkt4_tcp = *tcp_header;
829  "Sending TCP packet from port %u to port %u\n",
830  src_address->port,
831  dst_address->port);
832  pkt4_tcp->source_port = htons (src_address->port);
833  pkt4_tcp->destination_port = htons (dst_address->port);
835  pkt4_tcp,
836  payload,
837  payload_length);
838  GNUNET_memcpy (&pkt4_tcp[1],
839  payload,
840  payload_length);
841  }
842  break;
843 
844  default:
845  GNUNET_assert (0);
846  }
847 }
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
static unsigned long long payload
How much data are we currently storing in the database?
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:183
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:46
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:109
Standard IPv4 header.
uint16_t source_port
Source port (in NBO).
uint16_t destination_port
Destination port (in NBO).
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).

References SocketAddress::address, GNUNET_TUN_TcpHeader::destination_port, 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(), SocketAddress::ipv4, GNUNET_TUN_UdpHeader::len, len, payload, SocketAddress::port, ChannelState::protocol, 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:

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

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

References SocketAddress::address, GNUNET_TUN_TcpHeader::destination_port, 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(), SocketAddress::ipv6, GNUNET_TUN_UdpHeader::len, len, 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 962 of file gnunet-daemon-exit.c.

967 {
968  size_t len;
969 
971  gettext_noop ("# TCP packets sent via TUN"),
972  1,
973  GNUNET_NO);
975  "Sending packet with %u bytes TCP payload via TUN\n",
976  (unsigned int) payload_length);
977  len = sizeof(struct GNUNET_MessageHeader) + sizeof(struct
979  switch (source_address->af)
980  {
981  case AF_INET:
982  len += sizeof(struct GNUNET_TUN_IPv4Header);
983  break;
984 
985  case AF_INET6:
986  len += sizeof(struct GNUNET_TUN_IPv6Header);
987  break;
988 
989  default:
990  GNUNET_break (0);
991  return;
992  }
993  len += sizeof(struct GNUNET_TUN_TcpHeader);
994  len += payload_length;
996  {
997  GNUNET_break (0);
998  return;
999  }
1000  {
1001  char buf[len] GNUNET_ALIGN;
1002  struct GNUNET_MessageHeader *hdr;
1003  struct GNUNET_TUN_Layer2PacketHeader *tun;
1004 
1005  hdr = (struct GNUNET_MessageHeader *) buf;
1006  hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1007  hdr->size = htons (len);
1008  tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
1009  tun->flags = htons (0);
1010  switch (source_address->af)
1011  {
1012  case AF_INET:
1013  {
1014  struct GNUNET_TUN_IPv4Header *ipv4
1015  = (struct GNUNET_TUN_IPv4Header*) &tun[1];
1016 
1017  tun->proto = htons (ETH_P_IPV4);
1019  payload_length,
1020  IPPROTO_TCP,
1021  tcp_header,
1024  ipv4);
1025  }
1026  break;
1027 
1028  case AF_INET6:
1029  {
1030  struct GNUNET_TUN_IPv6Header *ipv6
1031  = (struct GNUNET_TUN_IPv6Header*) &tun[1];
1032 
1033  tun->proto = htons (ETH_P_IPV6);
1036  IPPROTO_TCP,
1037  tcp_header,
1040  ipv6);
1041  }
1042  break;
1043 
1044  default:
1045  GNUNET_assert (0);
1046  break;
1047  }
1048  if (NULL != helper_handle)
1050  (const struct GNUNET_MessageHeader*) buf,
1051  GNUNET_YES,
1052  NULL,
1053  NULL);
1054  }
1055 }
#define gettext_noop(String)
Definition: gettext.h:69
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
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 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_HELPER_Handle * helper_handle
The handle to the helper.
static int ipv4
Option -4: IPv4 requested.
Definition: gnunet-vpn.c:61
static int ipv6
Option -6: IPv6 requested.
Definition: gnunet-vpn.c:66
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
struct GNUNET_HELPER_SendHandle * GNUNET_HELPER_send(struct GNUNET_HELPER_Handle *h, const struct GNUNET_MessageHeader *msg, int can_drop, GNUNET_HELPER_Continuation cont, void *cont_cls)
Send an message to the helper.
Definition: helper.c:657
#define GNUNET_MESSAGE_TYPE_VPN_HELPER
Type of messages between the gnunet-vpn-helper and the daemon.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
#define ETH_P_IPV6
Number for IPv6.
#define ETH_P_IPV4
Number for IPv4.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
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.
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).

References SocketAddress::af, buf, 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, 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_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 1068 of file gnunet-daemon-exit.c.

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

References SocketAddress::af, buf, 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, len, 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 1180 of file gnunet-daemon-exit.c.

1183 {
1184  local_address->af = af;
1185  local_address->proto = (uint8_t) proto;
1186  /* default "local" port range is often 32768--61000,
1187  so we pick a random value in that range */
1188  if (((af == AF_INET) && (proto == IPPROTO_ICMP)) ||
1189  ((af == AF_INET6) && (proto == IPPROTO_ICMPV6)))
1190  local_address->port = 0;
1191  else
1192  local_address->port
1194  28232);
1195  switch (af)
1196  {
1197  case AF_INET:
1198  {
1199  struct in_addr addr;
1200  struct in_addr mask;
1201  struct in_addr rnd;
1202 
1203  addr = exit_ipv4addr;
1204  mask = exit_ipv4mask;
1205  if (0 == ~mask.s_addr)
1206  {
1207  /* only one valid IP anyway */
1208  local_address->address.ipv4 = addr;
1209  return;
1210  }
1211  /* Given 192.168.0.1/255.255.0.0, we want a mask
1212  of '192.168.255.255', thus: */
1213  mask.s_addr = addr.s_addr | ~mask.s_addr;
1214  /* Pick random IPv4 address within the subnet, except 'addr' or 'mask' itself */
1215  do
1216  {
1218  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 (
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 }
static unsigned long long ipv6prefix
IPv6 prefix (0..127) from configuration file.
static struct in6_addr exit_ipv6addr
IPv6 address of our TUN interface.
static struct in_addr exit_ipv4mask
IPv4 netmask of our TUN interface.
static struct in_addr exit_ipv4addr
IPv4 address of our TUN interface.
static uint8_t proto
Protocol to use.
Definition: gnunet-nat.c:60
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.

References SocketAddress::address, SocketAddress::af, exit_ipv4addr, exit_ipv4mask, exit_ipv6addr, GNUNET_assert, GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_u32(), GNUNET_memcmp, SocketAddress::ipv4, SocketAddress::ipv6, ipv6prefix, SocketAddress::port, SocketAddress::proto, and 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  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 }
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 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 struct GNUNET_CONTAINER_Heap * connections_heap
Heap so we can quickly find "old" connections.
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition: cadet_api.c:837
int 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.
int 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.
@ 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_root(struct GNUNET_CONTAINER_Heap *heap)
Remove root of the heap.
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.
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_HashCode state_key
Key this state has in the connections_map.
struct ChannelState::@10::@11 tcp_udp

References buf, 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(), 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 1364 of file gnunet-daemon-exit.c.

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;
1402  struct GNUNET_TUN_Layer2PacketHeader *tun;
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 }

References SocketAddress::af, buf, 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, 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 1465 of file gnunet-daemon-exit.c.

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 }

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

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 */
1500  state->is_dns = GNUNET_NO;
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);
1571  GNUNET_CADET_receive_done (state->channel);
1572 }
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_exit
Are we an IPv6-exit?
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 int ipv4_exit
Are we an IPv4-exit?
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
Message send via cadet to an exit daemon to forward UDP data to the Internet.
Definition: exit.h:146

References buf, gettext_noop, GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_SYSERR, consensus-simulation::int, ipv4_exit, ipv6_exit, 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 1585 of file gnunet-daemon-exit.c.

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 }

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

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);
1633  GNUNET_CADET_receive_done (state->channel);
1634 }
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
Message send via cadet to an exit daemon to send UDP data to a local service.
Definition: exit.h:121

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

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 */
1657  state->is_dns = GNUNET_NO;
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);
1681  GNUNET_CADET_receive_done (state->channel);
1682 }
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.
Message send via cadet to an exit daemon to initiate forwarding of TCP data to a local service.
Definition: exit.h:38

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

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 }

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

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 */
1745  state->is_dns = GNUNET_NO;
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);
1815  GNUNET_CADET_receive_done (state->channel);
1816 }
Message send via cadet to an exit daemon to initiate forwarding of TCP data to the Internet.
Definition: exit.h:64

References buf, gettext_noop, GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_SYSERR, consensus-simulation::int, ipv4_exit, ipv6_exit, 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 *
messagethe actual message
Returns
GNUNET_OK to keep the connection open, GNUNET_SYSERR to close it (signal serious error)

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

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 }
uint32_t data
The data value.

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 *
messagethe actual message

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

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);
1904  GNUNET_CADET_receive_done (state->channel);
1905 }
Message send via cadet between VPN and entry and an exit daemon to transmit TCP data between the VPN ...
Definition: exit.h:95

References buf, 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 1918 of file gnunet-daemon-exit.c.

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 }
static char * address
GNS address for this phone.
static int udp
Option -u: UDP requested.
Definition: gnunet-vpn.c:76

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

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 }

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

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 }

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

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 */
2013  state->is_dns = GNUNET_NO;
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
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  1, GNUNET_NO);
2093  return;
2094  }
2095  /* end AF_INET */
2096  break;
2097 
2098  case AF_INET6:
2099  if (pkt_len < sizeof(struct in6_addr))
2100  {
2101  GNUNET_break_op (0);
2102  return;
2103  }
2104  if (! ipv6_exit)
2105  {
2106  GNUNET_break_op (0);
2107  return;
2108  }
2109  v6 = (const struct in6_addr*) &msg[1];
2110  payload = &v6[1];
2111  pkt_len -= sizeof(struct in6_addr);
2112  state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
2113  if (NULL == state->specifics.tcp_udp.heap_node)
2114  {
2115  state->specifics.tcp_udp.ri.remote_address.af = af;
2116  state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_ICMPV6;
2118  }
2119  /* check that ICMP type is something we want to support
2120  and possibly make up payload! */
2121  switch (msg->icmp_header.type)
2122  {
2125  break;
2126 
2131  if (0 != pkt_len)
2132  {
2133  GNUNET_break_op (0);
2134  return;
2135  }
2136  /* make up payload */
2137  {
2138  struct GNUNET_TUN_IPv6Header *ipp = (struct
2140  struct GNUNET_TUN_UdpHeader *udp = (struct
2141  GNUNET_TUN_UdpHeader *) &ipp[1];
2142 
2143  GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
2144  pkt_len = sizeof(struct GNUNET_TUN_IPv6Header) + 8;
2146  ipp,
2147  udp);
2148  payload = ipp;
2149  }
2150  break;
2151 
2152  default:
2153  GNUNET_break_op (0);
2155  gettext_noop (
2156  "# ICMPv6 packets dropped (type not allowed)"),
2157  1, GNUNET_NO);
2158  return;
2159  }
2160  /* end AF_INET6 */
2161  break;
2162 
2163  default:
2164  /* bad AF */
2165  GNUNET_break_op (0);
2166  return;
2167  }
2168 
2169  {
2170  char buf[INET6_ADDRSTRLEN];
2172  "Received ICMP data from %s for forwarding to %s\n",
2173  GNUNET_i2s (&state->peer),
2174  inet_ntop (af,
2175  &state->specifics.tcp_udp.ri.remote_address.address,
2176  buf, sizeof(buf)));
2177  }
2178  send_icmp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
2179  &state->specifics.tcp_udp.ri.local_address,
2180  &msg->icmp_header,
2181  payload, pkt_len);
2182  GNUNET_CADET_receive_done (state->channel);
2183 }
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 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 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.
#define GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM
#define GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST
#define GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED
#define GNUNET_TUN_ICMPTYPE6_ECHO_REPLY
#define GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED
#define GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE
#define GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH
#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
Message send via cadet to an exit daemon to forward ICMP data to the Internet.
Definition: exit.h:237

References buf, 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, consensus-simulation::int, ipv4_exit, ipv6_exit, 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 2196 of file gnunet-daemon-exit.c.

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

References buf, 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 2248 of file gnunet-daemon-exit.c.

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

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

2277 {
2278  struct ChannelState *state = cls;
2279  uint16_t pkt_len = ntohs (msg->header.size) - sizeof(struct
2281  struct GNUNET_TUN_IcmpHeader icmp;
2282  char buf[sizeof(struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
2283  const void *payload;
2284 
2286  gettext_noop ("# Bytes received from CADET"),
2287  pkt_len, GNUNET_NO);
2289  gettext_noop (
2290  "# ICMP service requests received via cadet"),
2291  1, GNUNET_NO);
2292  /* check that we got at least a valid header */
2294  "Received data from %s for forwarding to ICMP service %s\n",
2295  GNUNET_i2s (&state->peer),
2296  GNUNET_h2s (&state->specifics.tcp_udp.serv->descriptor));
2297  icmp = msg->icmp_header;
2298  payload = &msg[1];
2299  state->specifics.tcp_udp.ri.remote_address
2300  = state->specifics.tcp_udp.serv->address;
2302 
2303  /* check that ICMP type is something we want to support,
2304  perform ICMP PT if needed and possibly make up payload */
2305  switch (msg->af)
2306  {
2307  case AF_INET:
2308  switch (msg->icmp_header.type)
2309  {
2311  if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2312  icmp.type = GNUNET_TUN_ICMPTYPE6_ECHO_REPLY;
2313  break;
2314 
2316  if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2318  break;
2319 
2321  if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2323  if (0 != pkt_len)
2324  {
2325  GNUNET_break_op (0);
2326  return;
2327  }
2328  payload = buf;
2329  pkt_len = make_up_icmp_service_payload (state, buf);
2330  break;
2331 
2333  if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2335  if (0 != pkt_len)
2336  {
2337  GNUNET_break_op (0);
2338  return;
2339  }
2340  payload = buf;
2341  pkt_len = make_up_icmp_service_payload (state, buf);
2342  break;
2343 
2345  if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2346  {
2348  gettext_noop (
2349  "# ICMPv4 packets dropped (impossible PT to v6)"),
2350  1, GNUNET_NO);
2351  return;
2352  }
2353  if (0 != pkt_len)
2354  {
2355  GNUNET_break_op (0);
2356  return;
2357  }
2358  payload = buf;
2359  pkt_len = make_up_icmp_service_payload (state, buf);
2360  break;
2361 
2362  default:
2363  GNUNET_break_op (0);
2365  gettext_noop (
2366  "# ICMPv4 packets dropped (type not allowed)"),
2367  1, GNUNET_NO);
2368  return;
2369  }
2370  /* end of AF_INET */
2371  break;
2372 
2373  case AF_INET6:
2374  switch (msg->icmp_header.type)
2375  {
2377  if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2378  icmp.type = GNUNET_TUN_ICMPTYPE_ECHO_REPLY;
2379  break;
2380 
2382  if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2384  break;
2385 
2387  if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2389  if (0 != pkt_len)
2390  {
2391  GNUNET_break_op (0);
2392  return;
2393  }
2394  payload = buf;
2395  pkt_len = make_up_icmp_service_payload (state, buf);
2396  break;
2397 
2399  if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2401  if (0 != pkt_len)
2402  {
2403  GNUNET_break_op (0);
2404  return;
2405  }
2406  payload = buf;
2407  pkt_len = make_up_icmp_service_payload (state, buf);
2408  break;
2409 
2412  if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2413  {
2415  gettext_noop (
2416  "# ICMPv6 packets dropped (impossible PT to v4)"),
2417  1, GNUNET_NO);
2418  return;
2419  }
2420  if (0 != pkt_len)
2421  {
2422  GNUNET_break_op (0);
2423  return;
2424  }
2425  payload = buf;
2426  pkt_len = make_up_icmp_service_payload (state, buf);
2427  break;
2428 
2429  default:
2430  GNUNET_break_op (0);
2432  gettext_noop (
2433  "# ICMPv6 packets dropped (type not allowed)"),
2434  1, GNUNET_NO);
2435  return;
2436  }
2437  /* end of AF_INET6 */
2438  break;
2439 
2440  default:
2441  GNUNET_break_op (0);
2442  return;
2443  }
2444 
2445  send_icmp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
2446  &state->specifics.tcp_udp.ri.local_address,
2447  &icmp,
2448  payload,
2449  pkt_len);
2450  GNUNET_CADET_receive_done (state->channel);
2451 }
static uint16_t make_up_icmp_service_payload(struct ChannelState *state, char *buf)
Setup ICMP payload for ICMP error messages.
Message send via cadet to an exit daemon to send ICMP data to a local service.
Definition: exit.h:206

References buf, 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 2463 of file gnunet-daemon-exit.c.

2466 {
2467  struct LocalService *service = value;
2468 
2471  key,
2472  service));
2474  GNUNET_free (service->name);
2475  GNUNET_free (service);
2476  return GNUNET_OK;
2477 }
static struct GNUNET_CONTAINER_MultiHashMap * services
This hashmaps saves interesting things about the configured services.
static char * value
Value of the record to add/remove.
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
void GNUNET_CADET_close_port(struct GNUNET_CADET_Port *p)
Close a port opened with GNUNET_CADET_open_port().
Definition: cadet_api.c:808
This struct is saved into the services-hashmap to represent a service this peer is specifically offer...

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

2492 {
2493  struct LocalService *ls = cls;
2494  struct ChannelState *s = GNUNET_new (struct ChannelState);
2495 
2496  s->peer = *initiator;
2498  gettext_noop ("# Inbound CADET channels created"),
2499  1,
2500  GNUNET_NO);
2502  "Received inbound channel from `%s'\n",
2503  GNUNET_i2s (initiator));
2504  s->channel = channel;
2505  s->specifics.tcp_udp.serv = ls;
2506  s->specifics.tcp_udp.ri.remote_address = ls->address;
2507  return s;
2508 }
static struct GNUNET_NETWORK_Handle * ls
Listen socket for STUN processing.
Definition: gnunet-nat.c:85
#define GNUNET_new(type)
Allocate a struct or union of the given type.
struct GNUNET_PeerIdentity peer
Who is the other end of this channel.

References ChannelState::channel, gettext_noop, GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_new, GNUNET_NO, GNUNET_STATISTICS_update(), ls, ChannelState::peer, 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 2519 of file gnunet-daemon-exit.c.

2521 {
2522  struct ChannelState *s = cls;
2523 
2525  "Channel destroyed\n");
2526  if (GNUNET_SYSERR == s->is_dns)
2527  {
2528  GNUNET_free (s);
2529  return;
2530  }
2531  if (GNUNET_YES == s->is_dns)
2532  {
2533  if (channels[s->specifics.dns.my_id] == s)
2534  channels[s->specifics.dns.my_id] = NULL;
2535  }
2536  else
2537  {
2538  if (NULL != s->specifics.tcp_udp.heap_node)
2539  {
2542  &s->specifics.tcp_udp
2543  .state_key,
2544  s));
2546  s->specifics.tcp_udp.heap_node = NULL;
2547  }
2548  }
2549  GNUNET_free (s);
2550 }
void * GNUNET_CONTAINER_heap_remove_node(struct GNUNET_CONTAINER_HeapNode *node)
Removes a node from the heap.

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::is_dns, LOG, ChannelState::specifics, 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 2563 of file gnunet-daemon-exit.c.

2567 {
2568  struct GNUNET_MQ_MessageHandler handlers[] = {
2569  GNUNET_MQ_hd_var_size (icmp_service,
2572  service),
2573  GNUNET_MQ_hd_var_size (udp_service,
2576  service),
2577  GNUNET_MQ_hd_var_size (tcp_service,
2580  service),
2581  GNUNET_MQ_hd_var_size (tcp_data,
2584  service),
2586  };
2587 
2588  struct GNUNET_HashCode cadet_port;
2589 
2590  service->name = GNUNET_strdup (name);
2592  &service->descriptor);
2594  destination_port,
2595  &cadet_port);
2597  "Opening CADET port %s for SERVICE exit %s on port %u\n",
2599  name,
2600  (unsigned int) destination_port);
2602  &cadet_port,
2604  service,
2605  NULL,
2606  &clean_channel,
2607  handlers);
2608  service->is_udp = (IPPROTO_UDP == proto);
2609  if (GNUNET_OK !=
2611  &cadet_port,
2612  service,
2614  {
2616  GNUNET_free (service->name);
2617  GNUNET_free (service);
2619  _ ("Got duplicate service records for `%s:%u'\n"),
2620  name,
2621  (unsigned int) destination_port);
2622  }
2623 }
static struct GNUNET_CADET_MessageHandler handlers[]
Handlers, for diverse services.
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_CADET_Handle * cadet_handle
The handle to cadet.
static void * new_service_channel(void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *initiator)
Callback from CADET for new channels.
static struct GNUNET_CADET_Port * cadet_port
Listen port for incoming requests.
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:970
@ GNUNET_ERROR_TYPE_WARNING
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#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_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.
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: regex.c:833
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: regex.c:814
#define _(String)
GNU gettext support macro.
Definition: platform.h:177
const char * name
Message handler for a specific message type.

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

2635 {
2636  GNUNET_assert (NULL != s);
2638  gettext_noop (
2639  "# Messages transmitted via cadet channels"),
2640  1,
2641  GNUNET_NO);
2643  env);
2644 }

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

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

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

2872 {
2873  struct ChannelState *state;
2874  struct GNUNET_MQ_Envelope *env;
2875  struct GNUNET_EXIT_UdpReplyMessage *urm;
2876 
2877  {
2878  char sbuf[INET6_ADDRSTRLEN];
2879  char dbuf[INET6_ADDRSTRLEN];
2880 
2882  "Received UDP packet going from %s:%u to %s:%u\n",
2883  inet_ntop (af,
2884  source_ip,
2885  sbuf, sizeof(sbuf)),
2886  (unsigned int) ntohs (udp->source_port),
2887  inet_ntop (af,
2888  destination_ip,
2889  dbuf, sizeof(dbuf)),
2890  (unsigned int) ntohs (udp->destination_port));
2891  }
2892 
2893  if (pktlen < sizeof(struct GNUNET_TUN_UdpHeader))
2894  {
2895  /* blame kernel */
2896  GNUNET_break (0);
2897  return;
2898  }
2899  if (pktlen != ntohs (udp->len))
2900  {
2901  /* blame kernel */
2902  GNUNET_break (0);
2903  return;
2904  }
2905  state = get_redirect_state (af,
2906  IPPROTO_UDP,
2907  source_ip,
2908  ntohs (udp->source_port),
2909  destination_ip,
2910  ntohs (udp->destination_port),
2911  NULL);
2912  if (NULL == state)
2913  {
2915  _ (
2916  "UDP Packet dropped, have no matching connection information\n"));
2917  return;
2918  }
2919  env = GNUNET_MQ_msg_extra (urm,
2920  pktlen - sizeof(struct GNUNET_TUN_UdpHeader),
2922  urm->source_port = htons (0);
2923  urm->destination_port = htons (0);
2924  GNUNET_memcpy (&urm[1],
2925  &udp[1],
2926  pktlen - sizeof(struct GNUNET_TUN_UdpHeader));
2928  env);
2929 }
#define GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY
Type of messages containing an UDP packet from a remote host.
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

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

2949 {
2950  struct ChannelState *state;
2951  char buf[pktlen] GNUNET_ALIGN;
2952  struct GNUNET_TUN_TcpHeader *mtcp;
2953  struct GNUNET_EXIT_TcpDataMessage *tdm;
2954  struct GNUNET_MQ_Envelope *env;
2955  size_t mlen;
2956 
2957  {
2958  char sbuf[INET6_ADDRSTRLEN];
2959  char dbuf[INET6_ADDRSTRLEN];
2961  "Received TCP packet with %u bytes going from %s:%u to %s:%u\n",
2962  (unsigned int) (pktlen - sizeof(struct GNUNET_TUN_TcpHeader)),
2963  inet_ntop (af,
2964  source_ip,
2965  sbuf, sizeof(sbuf)),
2966  (unsigned int) ntohs (tcp->source_port),
2967  inet_ntop (af,
2968  destination_ip,
2969  dbuf, sizeof(dbuf)),
2970  (unsigned int) ntohs (tcp->destination_port));
2971  }
2972 
2973  if (pktlen < sizeof(struct GNUNET_TUN_TcpHeader))
2974  {
2975  /* blame kernel */
2976  GNUNET_break (0);
2977  return;
2978  }
2979  state = get_redirect_state (af,
2980  IPPROTO_TCP,
2981  source_ip,
2982  ntohs (tcp->source_port),
2983  destination_ip,
2984  ntohs (tcp->destination_port),
2985  NULL);
2986  if (NULL == state)
2987  {
2989  _ (
2990  "TCP Packet dropped, have no matching connection information\n"));
2991 
2992  return;
2993  }
2994  /* mug port numbers and crc to avoid information leakage;
2995  sender will need to lookup the correct values anyway */
2996  GNUNET_memcpy (buf, tcp, pktlen);
2997  mtcp = (struct GNUNET_TUN_TcpHeader *) buf;
2998  mtcp->source_port = 0;
2999  mtcp->destination_port = 0;
3000  mtcp->crc = 0;
3001 
3002  mlen = sizeof(struct GNUNET_EXIT_TcpDataMessage) + (pktlen - sizeof(struct
3004  if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
3005  {
3006  GNUNET_break (0);
3007  return;
3008  }
3009  env = GNUNET_MQ_msg_extra (tdm,
3010  pktlen - sizeof(struct GNUNET_TUN_TcpHeader),
3012  tdm->reserved = htonl (0);
3013  GNUNET_memcpy (&tdm->tcp_header,
3014  buf,
3015  pktlen);
3017  env);
3018 }
static int tcp
Option -t: TCP requested.
Definition: gnunet-vpn.c:71
#define GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_VPN
Type of messages containing an TCP packet of an established connection.
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
uint16_t crc
Checksum.

References _, buf, GNUNET_TUN_TcpHeader::crc, GNUNET_TUN_TcpHeader::destination_port, 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_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 3028 of file gnunet-daemon-exit.c.

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

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

3193 {
3194  struct ChannelState *s = GNUNET_new (struct ChannelState);
3195 
3196  s->is_dns = GNUNET_SYSERR;
3197  s->peer = *initiator;
3199  gettext_noop ("# Inbound CADET channels created"),
3200  1,
3201  GNUNET_NO);
3203  "Received inbound channel from `%s'\n",
3204  GNUNET_i2s (initiator));
3205  s->channel = channel;
3206  return s;
3207 }

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

3221 {
3222  GNUNET_free (value);
3223  return GNUNET_YES;
3224 }

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
tcscheduler context

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

3238 {
3239  /* just terminate */
3240 }

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

3250 {
3251  unsigned int i;
3252 
3254  "Exit service is shutting down now\n");
3255 
3256  if (NULL != helper_handle)
3257  {
3259  helper_handle = NULL;
3260  }
3261  if (NULL != regex4)
3262  {
3264  regex4 = NULL;
3265  }
3266  if (NULL != regex6)
3267  {
3269  regex6 = NULL;
3270  }
3271  if (NULL != services)
3272  {
3275  NULL);
3277  }
3278  if (NULL != dns_port)
3279  {
3281  dns_port = NULL;
3282  }
3283  if (NULL != cadet_port4)
3284  {
3286  cadet_port4 = NULL;
3287  }
3288  if (NULL != cadet_port6)
3289  {
3291  cadet_port6 = NULL;
3292  }
3293  if (NULL != cadet_handle)
3294  {
3296  cadet_handle = NULL;
3297  }
3298  if (NULL != connections_map)
3299  {
3301  &free_iterate,
3302  NULL);
3304  connections_map = NULL;
3305  }
3306  if (NULL != connections_heap)
3307  {
3309  connections_heap = NULL;
3310  }
3311  if (NULL != dnsstub)
3312  {
3314  dnsstub = NULL;
3315  }
3316  if (NULL != peer_key)
3317  {
3319  peer_key = NULL;
3320  }
3321  if (NULL != dht_task)
3322  {
3324  dht_task = NULL;
3325  }
3326  if (NULL != dht_put)
3327  {
3329  dht_put = NULL;
3330  }
3331  if (NULL != dht)
3332  {
3334  dht = NULL;
3335  }
3336  if (NULL != stats)
3337  {
3339  GNUNET_NO);
3340  stats = NULL;
3341  }
3342  for (i = 0; i < 8; i++)
3343  GNUNET_free (exit_argv[i]);
3344 }
static struct GNUNET_DHT_Handle * dht
Handle to the DHT.
static struct GNUNET_REGEX_Announcement * regex4
Handle to our regex announcement for IPv4.
static struct GNUNET_DHT_PutHandle * dht_put
Handle for ongoing DHT PUT operations to advertise exit service.
static struct GNUNET_REGEX_Announcement * regex6
Handle to our regex announcement for IPv4.
static char * exit_argv[8]
Arguments to the exit helper.
static struct GNUNET_CADET_Port * cadet_port4
Port for IPv4 exit.
static int free_service_record(void *cls, const struct GNUNET_HashCode *key, void *value)
Free memory associated with a service record.
static struct GNUNET_CRYPTO_EddsaPrivateKey * peer_key
Private key for this peer.
static struct GNUNET_CADET_Port * dns_port
Port for DNS exit.
static int free_iterate(void *cls, const struct GNUNET_HashCode *hash, void *value)
Function that frees everything from a hashmap.
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.
void GNUNET_CADET_disconnect(struct GNUNET_CADET_Handle *handle)
Disconnect from the cadet service.
Definition: cadet_api.c:775
void GNUNET_DHT_put_cancel(struct GNUNET_DHT_PutHandle *ph)
Cancels a DHT PUT operation.
Definition: dht_api.c:1035
void GNUNET_DHT_disconnect(struct GNUNET_DHT_Handle *handle)
Shutdown connection with the DHT service.
Definition: dht_api.c:918
void GNUNET_DNSSTUB_stop(struct GNUNET_DNSSTUB_Context *ctx)
Cleanup DNSSTUB resolver.
Definition: dnsstub.c:690
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
void GNUNET_CONTAINER_heap_destroy(struct GNUNET_CONTAINER_Heap *heap)
Destroys the heap.
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:567
void GNUNET_REGEX_announce_cancel(struct GNUNET_REGEX_Announcement *a)
Stop announcing the regex specified by the given handle.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:972
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).

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_REGEX_announce_cancel(), GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_destroy(), helper_handle, peer_key, regex4, regex6, services, and stats.

Referenced by curl_check_hdr(), decrypt_new_element(), deserialize_download(), deserialize_fi_node(), deserialize_publish_file(), deserialize_search(), deserialize_search_result(), deserialize_unindex_file(), GNUNET_ATS_solver_logging_write_to_disk(), GNUNET_FS_download_sync_(), GNUNET_FS_file_information_sync_(), GNUNET_FS_publish_sync_(), GNUNET_FS_search_result_sync_(), GNUNET_FS_search_sync_(), GNUNET_FS_unindex_sync_(), handle_barrier_status(), main(), prc_stop_cb(), read_download_request(), run(), switch_address_bl_check_cont(), and verify_fair().

Here is the call graph for this function:
Here is the caller 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 3355 of file gnunet-daemon-exit.c.

3358 {
3359  char *redirect;
3360  char *hostname;
3361  char *hostport;
3362  struct LocalService *serv;
3363  char *n;
3364  size_t slen;
3365 
3366  slen = strlen (name);
3367  GNUNET_assert (slen >= 8);
3368  n = GNUNET_strndup (name, slen - 8 /* remove .gnunet. */);
3369 
3370  for (redirect = strtok (cpy, " ;"); redirect != NULL;
3371  redirect = strtok (NULL, " ;"))
3372  {
3373  if (NULL == (hostname = strstr (redirect, ":")))
3374  {
3376  _ (
3377  "Option `%s' for domain `%s' is not formatted correctly!\n"),
3378  redirect,
3379  name);
3380  continue;
3381  }
3382  hostname[0] = '\0';
3383  hostname++;
3384  if (NULL == (hostport = strstr (hostname, ":")))
3385  {
3387  _ (
3388  "Option `%s' for domain `%s' is not formatted correctly!\n"),
3389  redirect,
3390  name);
3391  continue;
3392  }
3393  hostport[0] = '\0';
3394  hostport++;
3395 
3396  int local_port = atoi (redirect);
3397  int remote_port = atoi (hostport);
3398 
3399  if (! ((local_port > 0) && (local_port < 65536)))
3400  {
3402  _ ("`%s' is not a valid port number (for domain `%s')!"),
3403  redirect,
3404  name);
3405  continue;
3406  }
3407  if (! ((remote_port > 0) && (remote_port < 65536)))
3408  {
3410  _ ("`%s' is not a valid port number (for domain `%s')!"),
3411  hostport,
3412  name);
3413  continue;
3414  }
3415 
3416  serv = GNUNET_new (struct LocalService);
3417  serv->address.proto = proto;
3418  serv->address.port = remote_port;
3419  if (0 == strcmp ("localhost4",
3420  hostname))
3421  {
3422  const char *ip4addr = exit_argv[5];
3423 
3424  serv->address.af = AF_INET;
3425  GNUNET_assert (1 == inet_pton (AF_INET,
3426  ip4addr,
3427  &serv->address.address.ipv4));
3428  }
3429  else if (0 == strcmp ("localhost6",
3430  hostname))
3431  {
3432  const char *ip6addr = exit_argv[3];
3433 
3434  serv->address.af = AF_INET6;
3435  GNUNET_assert (1 == inet_pton (AF_INET6,
3436  ip6addr,
3437  &serv->address.address.ipv6));
3438  }
3439  else
3440  {
3441  struct addrinfo *res;
3442  int ret;
3443 
3444  ret = getaddrinfo (hostname,
3445  NULL,
3446  NULL,
3447  &res);
3448  if ((0 != ret) || (NULL == res))
3449  {
3451  _ (
3452  "No addresses found for hostname `%s' of service `%s'!\n"),
3453  hostname,
3454  n);
3455  GNUNET_free (serv);
3456  continue;
3457  }
3458 
3459  serv->address.af = res->ai_family;
3460  switch (res->ai_family)
3461  {
3462  case AF_INET:
3463  if (! ipv4_enabled)
3464  {
3466  _ (
3467  "Service `%s' configured for IPv4, but IPv4 is disabled!\n"),
3468  n);
3469  freeaddrinfo (res);
3470  GNUNET_free (serv);
3471  continue;
3472  }
3473  serv->address.address.ipv4
3474  = ((struct sockaddr_in *) res->ai_addr)->sin_addr;
3475  break;
3476 
3477  case AF_INET6:
3478  if (! ipv6_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.ipv6
3489  = ((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
3490  break;
3491 
3492  default:
3493  freeaddrinfo (res);
3495  _ (
3496  "No IP addresses found for hostname `%s' of service `%s'!\n"),
3497  hostname,
3498  n);
3499  GNUNET_free (serv);
3500  continue;
3501  }
3502  freeaddrinfo (res);
3503  }
3505  n,
3506  local_port,
3507  serv);
3508  }
3509  GNUNET_free (n);
3510 }
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static int res
static int ipv6_enabled
Do we support IPv6 at all on the TUN interface?
static int ipv4_enabled
Do we support IPv4 at all on the TUN interface?
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 char * hostname
Our hostname; we give this to all the peers we start.
static unsigned long long remote_port
Remote host's port.
#define GNUNET_strndup(a, length)
Wrapper around GNUNET_xstrndup_.
struct SocketAddress address
Remote address to use for the service.

References _, SocketAddress::address, LocalService::address, SocketAddress::af, exit_argv, GNUNET_assert, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_log, GNUNET_new, GNUNET_strndup, hostname, SocketAddress::ipv4, ipv4_enabled, SocketAddress::ipv6, ipv6_enabled, name, SocketAddress::port, SocketAddress::proto, 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 3520 of file gnunet-daemon-exit.c.

3522 {
3523  char *cpy;
3524 
3525  if ((strlen (section) < 8) ||
3526  (0 != strcmp (".gnunet.", section + (strlen (section) - 8))))
3527  return;
3528  if (GNUNET_OK ==
3530  section,
3531  "UDP_REDIRECTS",
3532  &cpy))
3533  {
3534  add_services (IPPROTO_UDP,
3535  cpy,
3536  section);
3537  GNUNET_free (cpy);
3538  }
3539  if (GNUNET_OK ==
3541  section,
3542  "TCP_REDIRECTS",
3543  &cpy))
3544  {
3545  add_services (IPPROTO_TCP,
3546  cpy,
3547  section);
3548  GNUNET_free (cpy);
3549  }
3550 }
static const struct GNUNET_CONFIGURATION_Handle * cfg
The handle to the configuration used throughout the process.
static void add_services(int proto, char *cpy, const char *name)
Add services to the service map.
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.

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

3584 {
3586 
3588  &do_dht_put,
3589  NULL);
3591  if (GNUNET_TIME_absolute_get_remaining (expiration).rel_value_us <
3592  GNUNET_TIME_UNIT_HOURS.rel_value_us)
3593  {
3594  /* refresh advertisement */
3601  }
3602  if (NULL != dht_put)
3605  &dht_put_key,
3606  1 /* replication */,
3609  sizeof(struct GNUNET_DNS_Advertisement),
3611  expiration,
3612  &dht_put_cont,
3613  NULL);
3614 }
static char * expiration
Credential TTL.
Definition: gnunet-abd.c:96
#define DNS_ADVERTISEMENT_TIMEOUT
How long do we typically sign the DNS exit advertisement for?
static struct GNUNET_DNS_Advertisement dns_advertisement
Advertisement message we put into the DHT to advertise us as a DNS exit.
static void dht_put_cont(void *cls)
Function called when the DHT PUT operation is complete.
static void do_dht_put(void *cls)
We are running a DNS exit service, advertise it in the DHT.
static struct GNUNET_HashCode dht_put_key
Key we store the DNS advertismenet under.
#define DHT_PUT_FREQUENCY
How frequently do we re-announce the DNS exit in the DHT?
@ GNUNET_BLOCK_TYPE_DNS
Block for storing DNS exit service advertisements.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_sign_(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, struct GNUNET_CRYPTO_EddsaSignature *sig)
EdDSA sign a given block.
Definition: crypto_ecc.c:599
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:966
@ GNUNET_DHT_RO_NONE
Default.
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:1269
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:232
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:542
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:181
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:464
This is the structure describing an DNS exit service.
Definition: block_dns.h:41
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does this signature expire?
Definition: block_dns.h:56
struct GNUNET_CRYPTO_EddsaSignature signature
Signature of the peer affirming that it is offering the service.
Definition: block_dns.h:45
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Beginning of signed portion of the record, signs everything until the end of the struct.
Definition: block_dns.h:51
Time for absolute times used by GNUnet, in microseconds.

References dht, dht_put, dht_put_cont(), DHT_PUT_FREQUENCY, dht_put_key, dht_task, dns_advertisement, DNS_ADVERTISEMENT_TIMEOUT, expiration, GNUNET_DNS_Advertisement::expiration_time, GNUNET_assert, GNUNET_BLOCK_TYPE_DNS, GNUNET_CRYPTO_eddsa_sign_(), GNUNET_DHT_put(), GNUNET_DHT_put_cancel(), GNUNET_DHT_RO_NONE, GNUNET_OK, 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, peer_key, GNUNET_DNS_Advertisement::purpose, and GNUNET_DNS_Advertisement::signature.

Referenced by advertise_dns_exit().

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

3571 {
3572  dht_put = NULL;
3573 }

References dht_put.

Referenced by do_dht_put().

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

3623 {
3625  "exit",
3626  "EXIT_IPV4");
3628  "exit",
3629  "EXIT_IPV6");
3631  "exit",
3632  "ENABLE_IPV4");
3634  "exit",
3635  "ENABLE_IPV6");
3636  if ((ipv4_exit || ipv4_enabled) &&
3637  (GNUNET_OK != GNUNET_NETWORK_test_pf (PF_INET)) )
3638  {
3640  _ (
3641  "This system does not support IPv4, will disable IPv4 functions despite them being enabled in the configuration\n"));
3642  ipv4_exit = GNUNET_NO;
3644  }
3645  if ((ipv6_exit || ipv6_enabled) &&
3646  (GNUNET_OK != GNUNET_NETWORK_test_pf (PF_INET6)) )
3647  {
3649  _ (
3650  "This system does not support IPv6, will disable IPv6 functions despite them being enabled in the configuration\n"));
3651  ipv6_exit = GNUNET_NO;
3653  }
3654  if (ipv4_exit && (! ipv4_enabled))
3655  {
3657  _ (
3658  "Cannot enable IPv4 exit but disable IPv4 on TUN interface, will use ENABLE_IPv4=YES\n"));
3660  }
3661  if (ipv6_exit && (! ipv6_enabled))
3662  {
3664  _ (
3665  "Cannot enable IPv6 exit but disable IPv6 on TUN interface, will use ENABLE_IPv6=YES\n"));
3667  }
3668 }
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".
@ GNUNET_ERROR_TYPE_ERROR
int GNUNET_NETWORK_test_pf(int pf)
Test if the given protocol family is supported by this system.
Definition: network.c:85

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

3677 {
3678  struct GNUNET_MQ_MessageHandler handlers[] = {
3679  GNUNET_MQ_hd_var_size (dns_request,
3681  struct DnsResponseMessage,
3682  NULL),
3684  };
3685  char *dns_exit;
3686  struct GNUNET_HashCode port;
3687 
3688  if (GNUNET_YES !=
3690  "exit",
3691  "EXIT_DNS"))
3692  return;
3693  GNUNET_assert (NULL != (dnsstub = GNUNET_DNSSTUB_start (128)));
3694  dns_exit = NULL;
3695  /* TODO: support using multiple DNS resolvers */
3696  if ((GNUNET_OK !=
3698  "exit",
3699  "DNS_RESOLVER",
3700  &dns_exit)) ||
3701  (GNUNET_OK !=
3703  dns_exit)))
3704  {
3706  "dns",
3707  "DNS_RESOLVER",
3708  _ ("need a valid IPv4 or IPv6 address\n"));
3709  GNUNET_free (dns_exit);
3710  return;
3711  }
3712  /* open port */
3715  &port);
3717  "Opening CADET port %s for DNS exit service\n",
3718  GNUNET_h2s (&port));
3720  &port,
3721  &new_channel,
3722  NULL,
3723  NULL,
3724  &clean_channel,
3725  handlers);
3726  /* advertise exit */
3728  1);
3732  dns_advertisement.purpose.size = htonl (sizeof(struct
3734  - sizeof(struct
3738  GNUNET_CRYPTO_hash ("dns",
3739  strlen ("dns"),
3740  &dht_put_key);
3742  NULL);
3743  GNUNET_free (dns_exit);
3744 }
static uint16_t port
Port number.
Definition: gnunet-bcd.c:83
static void * new_channel(void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *initiator)
Callback from CADET for new channels.
#define GNUNET_APPLICATION_PORT_INTERNET_RESOLVER
Internet DNS resolution (external DNS gateway).
struct GNUNET_CRYPTO_EddsaPrivateKey * GNUNET_CRYPTO_eddsa_key_create_from_configuration(const struct GNUNET_CONFIGURATION_Handle *cfg)
Create a new private key by reading our peer's key from the file specified in the configuration.
void GNUNET_CRYPTO_eddsa_key_get_public(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:197
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:890
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:591
struct GNUNET_DNSSTUB_Context * GNUNET_DNSSTUB_start(unsigned int num_sockets)
Start a DNS stub resolver.
Definition: dnsstub.c:564
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
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.
#define GNUNET_MESSAGE_TYPE_VPN_DNS_TO_INTERNET
Type of messages containing an DNS request for a DNS exit service.
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:1296
#define GNUNET_SIGNATURE_PURPOSE_DNS_RECORD
Signature of an GNUNET_DNS_Advertisement.
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!...
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
an ECC signature using EdDSA.
struct GNUNET_PeerIdentity peer
The peer providing this service.
Definition: block_dns.h:61
struct GNUNET_CRYPTO_EddsaPublicKey public_key

References _, cadet_handle, cfg, clean_channel(), dht, dht_put_key, dht_task, dns_advertisement, dns_port, dnsstub, do_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_eddsa_key_create_from_configuration(), GNUNET_CRYPTO_eddsa_key_get_public(), 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_SCHEDULER_add_now(), GNUNET_SIGNATURE_PURPOSE_DNS_RECORD, GNUNET_YES, handlers, new_channel(), GNUNET_DNS_Advertisement::peer, peer_key, port, GNUNET_PeerIdentity::public_key, GNUNET_DNS_Advertisement::purpose, GNUNET_CRYPTO_EccSignaturePurpose::purpose, and GNUNET_CRYPTO_EccSignaturePurpose::size.

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

3754 {
3755  char *exit_ifname;
3756  char *tun_ifname;
3757  char *ipv6addr;
3758  char *ipv6prefix_s;
3759  char *ipv4addr;
3760  char *ipv4mask;
3761 
3762  exit_argv[0] = GNUNET_strdup ("exit-gnunet");
3763  if (GNUNET_SYSERR ==
3765  "exit",
3766  "TUN_IFNAME",
3767  &tun_ifname))
3768  {
3770  "EXIT",
3771  "TUN_IFNAME");
3772  return GNUNET_SYSERR;
3773  }
3774  exit_argv[1] = tun_ifname;
3775  if (ipv4_enabled)
3776  {
3777  if (GNUNET_SYSERR ==
3779  "exit",
3780  "EXIT_IFNAME",
3781  &exit_ifname))
3782  {
3784  "EXIT",
3785  "EXIT_IFNAME");
3786  return GNUNET_SYSERR;
3787  }
3788  exit_argv[2] = exit_ifname;
3789  }
3790  else
3791  {
3792  exit_argv[2] = GNUNET_strdup ("-");
3793  }
3794 
3795  if (GNUNET_YES == ipv6_enabled)
3796  {
3797  ipv6addr = NULL;
3798  if (((GNUNET_SYSERR ==
3800  "exit",
3801  "IPV6ADDR",
3802  &ipv6addr)) ||
3803  (1 != inet_pton (AF_INET6,
3804  ipv6addr,
3805  &exit_ipv6addr))))
3806  {
3808  "EXIT",
3809  "IPV6ADDR");
3810  GNUNET_free (ipv6addr);
3811  return GNUNET_SYSERR;
3812  }
3813  exit_argv[3] = ipv6addr;
3814  if (GNUNET_SYSERR ==
3816  "exit",
3817  "IPV6PREFIX",
3818  &ipv6prefix_s))
3819  {
3821  "EXIT",
3822  "IPV6PREFIX");
3823  return GNUNET_SYSERR;
3824  }
3825  exit_argv[4] = ipv6prefix_s;
3826  if ((GNUNET_OK !=
3828  "exit",
3829  "IPV6PREFIX",
3830  &ipv6prefix)) ||
3831  (ipv6prefix >= 127))
3832  {
3834  "EXIT",
3835  "IPV6PREFIX",
3836  _ ("Must be a number"));
3837  return GNUNET_SYSERR;
3838  }
3839  }
3840  else
3841  {
3842  /* IPv6 explicitly disabled */
3843  exit_argv[3] = GNUNET_strdup ("-");
3844  exit_argv[4] = GNUNET_strdup ("-");
3845  }
3846  if (GNUNET_YES == ipv4_enabled)
3847  {
3848  ipv4addr = NULL;
3849  if (((GNUNET_SYSERR ==
3851  "exit",
3852  "IPV4ADDR",
3853  &ipv4addr)) ||
3854  (1 != inet_pton (AF_INET,
3855  ipv4addr,
3856  &exit_ipv4addr))))
3857  {
3859  "EXIT",
3860  "IPV4ADDR");
3861  GNUNET_free (ipv4addr);
3862  return GNUNET_SYSERR;
3863  }
3864  exit_argv[5] = ipv4addr;
3865  ipv4mask = NULL;
3866  if (((GNUNET_SYSERR ==
3868  "exit",
3869  "IPV4MASK",
3870  &ipv4mask)) ||
3871  (1 != inet_pton (AF_INET,
3872  ipv4mask,
3873  &exit_ipv4mask))))
3874  {
3876  "EXIT",
3877  "IPV4MASK");
3878  GNUNET_free (ipv4mask);
3879  return GNUNET_SYSERR;
3880  }
3881  exit_argv[6] = ipv4mask;
3882  }
3883  else
3884  {
3885  /* IPv4 explicitly disabled */
3886  exit_argv[5] = GNUNET_strdup ("-");
3887  exit_argv[6] = GNUNET_strdup ("-");
3888  }
3889  exit_argv[7] = NULL;
3890  return GNUNET_OK;
3891 }
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_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.

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

3907 {
3908  struct GNUNET_MQ_MessageHandler handlers[] = {
3909  GNUNET_MQ_hd_var_size (icmp_remote,
3912  NULL),
3913  GNUNET_MQ_hd_var_size (udp_remote,
3916  NULL),
3917  GNUNET_MQ_hd_var_size (tcp_remote,
3920  NULL),
3921  GNUNET_MQ_hd_var_size (tcp_data,
3924  NULL),
3926  };
3927  struct GNUNET_HashCode port;
3928  char *policy;
3929  char *binary;
3930  char *regex;
3931  char *prefixed_regex;
3932 
3933  cfg = cfg_;
3934  if (GNUNET_OK !=
3936  "exit",
3937  "MAX_CONNECTIONS",
3938  &max_connections))
3939  max_connections = 1024;
3940  parse_ip_options ();
3941  binary = GNUNET_OS_get_suid_binary_path (cfg, "gnunet-helper-exit");
3942  if ((ipv4_exit) || (ipv6_exit))
3943  {
3944  if (GNUNET_YES !=
3946  GNUNET_YES,
3947  "gnunet-vpn - - - 169.1.3.7 255.255.255.0")) // no nat, ipv4 only
3948  {
3949  GNUNET_free (binary);
3951  _ (
3952  "`%s' is not SUID or the path is invalid, EXIT will not work\n"),
3953  "gnunet-helper-exit");
3955  NULL);
3956  global_ret = 1;
3957  return;
3958  }
3959  }
3960  if (! (ipv4_enabled || ipv6_enabled))
3961  {
3962  GNUNET_free (binary);
3964  _ ("No useful service enabled. Exiting.\n"));
3966  return;
3967  }
3968 
3970  NULL);
3971  stats = GNUNET_STATISTICS_create ("exit",
3972  cfg);
3974  if (NULL == cadet_handle)
3975  {
3976  GNUNET_free (binary);
3978  return;
3979  }
3980  advertise_dns_exit ();
3981  if (GNUNET_OK !=
3983  {
3984  GNUNET_free (binary);
3986  return;
3987  }
3988 
3990  GNUNET_NO);
3992  GNUNET_NO);
3997  NULL);
3998 
3999  /* Cadet handle acquired, now open ports and announce regular
4000  expressions matching our exit */
4001  if ((GNUNET_YES == ipv4_enabled) &&
4002  (GNUNET_YES == ipv4_exit))
4003  {
4006  &port);
4008  "Opening CADET port %s for IPv4 gateway service\n",
4009  GNUNET_h2s (&port));
4011  &port,
4012  &new_channel,
4013  NULL,
4014  NULL,
4015  &clean_channel,
4016  handlers);
4017  policy = NULL;
4018  if (GNUNET_OK !=
4020  "exit",
4021  "EXIT_RANGE_IPV4_POLICY",
4022  &policy))
4023  regex = NULL;
4024  else
4025  regex = GNUNET_TUN_ipv4policy2regex (policy);
4026  GNUNET_free (policy);
4027  if (NULL != regex)
4028  {
4029  (void) GNUNET_asprintf (&prefixed_regex,
4030  "%s%s",
4032  regex);
4034  prefixed_regex,
4037  GNUNET_free (regex);
4038  GNUNET_free (prefixed_regex);
4039  }
4040  }
4041 
4042  if ((GNUNET_YES == ipv6_enabled) && (GNUNET_YES == ipv6_exit))
4043  {
4046  &port);
4048  "Opening CADET port %s for IPv6 gateway service\n",
4049  GNUNET_h2s (&port));
4051  &port,
4052  &new_channel,
4053  NULL,
4054  NULL,
4055  &clean_channel,
4056  handlers);
4057  policy = NULL;
4058  if (GNUNET_OK !=
4060  "exit",
4061  "EXIT_RANGE_IPV6_POLICY",
4062  &policy))
4063  regex = NULL;
4064  else
4065  regex = GNUNET_TUN_ipv6policy2regex (policy);
4066  GNUNET_free (policy);
4067  if (NULL != regex)
4068  {
4069  (void) GNUNET_asprintf (&prefixed_regex,
4070  "%s%s",
4072  regex);
4073