GNUnet  0.19.4
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_statistics_service.h"
#include "gnunet_constants.h"
#include "gnunet_signatures.h"
#include "gnunet_regex_service.h"
#include "exit.h"
#include "block_dns.h"
Include dependency graph for gnunet-daemon-exit.c:

Go to the source code of this file.

Data Structures

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

Macros

#define REGEX_MAX_PATH_LEN_IPV4   4
 Maximum path compression length for cadet regex announcing for IPv4 address based regex. 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:

  • test

Design:

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

Definition in file gnunet-daemon-exit.c.

Macro Definition Documentation

◆ REGEX_MAX_PATH_LEN_IPV4

#define REGEX_MAX_PATH_LEN_IPV4   4

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

Definition at line 55 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 61 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:484

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

Definition at line 66 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 72 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 78 of file gnunet-daemon-exit.c.

◆ LOG

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

Generic logging shorthand.

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

459 {
460  struct ChannelState *ts;
461  struct GNUNET_MQ_Envelope *env;
462  struct DnsResponseMessage *resp;
463 
465  "Processing DNS result from stub resolver\n");
466  GNUNET_assert (NULL == cls);
467  if (NULL == dns)
468  return;
469  /* Handle case that this is a reply to a request from a CADET DNS channel */
470  ts = channels[dns->id];
471  if (NULL == ts)
472  return;
474  "Got a response from the stub resolver for DNS request received via CADET!\n");
475  channels[dns->id] = NULL;
476  env = GNUNET_MQ_msg_extra (resp,
477  r - sizeof(struct GNUNET_TUN_DnsHeader),
479  GNUNET_memcpy (&resp->dns,
480  dns,
481  r);
482  resp->dns.id = ts->specifics.dns.original_id;
484  env);
485 }
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.
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:1066
#define GNUNET_log(kind,...)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#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:304
#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:62
#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 497 of file gnunet-daemon-exit.c.

499 {
500  struct ChannelState *ts = cls;
501 
502  if (NULL == dnsstub)
503  {
504  GNUNET_break (0);
505  return GNUNET_SYSERR;
506  }
507  if (GNUNET_NO == ts->is_dns)
508  {
509  GNUNET_break_op (0);
510  return GNUNET_SYSERR;
511  }
512  return GNUNET_OK;
513 }
static struct GNUNET_DNSSTUB_Context * dnsstub
Handle to the DNS Stub resolver.
@ GNUNET_OK
@ GNUNET_NO
@ GNUNET_SYSERR
#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 523 of file gnunet-daemon-exit.c.

525 {
526  struct ChannelState *ts = cls;
527  size_t mlen = ntohs (msg->header.size);
528  size_t dlen = mlen - sizeof(struct GNUNET_MessageHeader);
529  char buf[dlen] GNUNET_ALIGN;
530  struct GNUNET_TUN_DnsHeader *dns_out;
531 
532  if (GNUNET_SYSERR == ts->is_dns)
533  {
534  /* channel is DNS from now on */
535  ts->is_dns = GNUNET_YES;
536  }
537  ts->specifics.dns.original_id = msg->dns.id;
538  if (channels[ts->specifics.dns.my_id] == ts)
539  channels[ts->specifics.dns.my_id] = NULL;
540  ts->specifics.dns.my_id = (uint16_t) GNUNET_CRYPTO_random_u32 (
542  UINT16_MAX
543  + 1);
544  channels[ts->specifics.dns.my_id] = ts;
546  &msg->dns,
547  dlen);
548  dns_out = (struct GNUNET_TUN_DnsHeader *) buf;
549  dns_out->id = ts->specifics.dns.my_id;
551  buf,
552  dlen,
554  NULL);
555  if (NULL == ts->specifics.dns.rs)
556  {
557  GNUNET_break_op (0);
558  return;
559  }
561 }
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]
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:872
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:526
#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
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 572 of file gnunet-daemon-exit.c.

574 {
575  char *off;
576 
577  memset (hash,
578  0,
579  sizeof(struct GNUNET_HashCode));
580  /* the GNUnet hashmap only uses the first sizeof(unsigned int) of the hash,
581  so we put the IP address in there (and hope for few collisions) */
582  off = (char *) hash;
583  switch (ri->remote_address.af)
584  {
585  case AF_INET:
586  GNUNET_memcpy (off,
588  sizeof(struct in_addr));
589  off += sizeof(struct in_addr);
590  break;
591 
592  case AF_INET6:
593  GNUNET_memcpy (off,
595  sizeof(struct in6_addr));
596  off += sizeof(struct in_addr);
597  break;
598 
599  default:
600  GNUNET_assert (0);
601  }
602  GNUNET_memcpy (off,
603  &ri->remote_address.port,
604  sizeof(uint16_t));
605  off += sizeof(uint16_t);
606  switch (ri->local_address.af)
607  {
608  case AF_INET:
609  GNUNET_memcpy (off,
611  sizeof(struct in_addr));
612  off += sizeof(struct in_addr);
613  break;
614 
615  case AF_INET6:
616  GNUNET_memcpy (off,
618  sizeof(struct in6_addr));
619  off += sizeof(struct in_addr);
620  break;
621 
622  default:
623  GNUNET_assert (0);
624  }
625  GNUNET_memcpy (off,
626  &ri->local_address.port,
627  sizeof(uint16_t));
628  off += sizeof(uint16_t);
629  GNUNET_memcpy (off,
630  &ri->remote_address.proto,
631  sizeof(uint8_t));
632  /* off += sizeof (uint8_t); */
633 }
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 650 of file gnunet-daemon-exit.c.

657 {
658  struct RedirectInformation ri;
659  struct GNUNET_HashCode key;
660  struct ChannelState *state;
661 
662  if (((af == AF_INET) && (protocol == IPPROTO_ICMP)) ||
663  ((af == AF_INET6) && (protocol == IPPROTO_ICMPV6)))
664  {
665  /* ignore ports */
666  destination_port = 0;
667  local_port = 0;
668  }
670  if (af == AF_INET)
671  ri.remote_address.address.ipv4 = *((struct in_addr*) destination_ip);
672  else
673  ri.remote_address.address.ipv6 = *((struct in6_addr*) destination_ip);
674  ri.remote_address.port = destination_port;
675  ri.remote_address.proto = protocol;
676  ri.local_address.af = af;
677  if (af == AF_INET)
678  ri.local_address.address.ipv4 = *((struct in_addr*) local_ip);
679  else
680  ri.local_address.address.ipv6 = *((struct in6_addr*) local_ip);
681  ri.local_address.port = local_port;
682  ri.local_address.proto = protocol;
684  &ri);
685  if (NULL != state_key)
686  *state_key = key;
688  &key);
689  if (NULL == state)
690  return NULL;
691  /* Mark this connection as freshly used */
692  if (NULL == state_key)
693  GNUNET_CONTAINER_heap_update_cost (state->specifics.tcp_udp.heap_node,
694  GNUNET_TIME_absolute_get ().abs_value_us);
695  return state;
696 }
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:111
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 709 of file gnunet-daemon-exit.c.

711 {
712  struct ChannelState *state = cls;
713 
714  if (NULL == state)
715  {
716  GNUNET_break_op (0);
717  return GNUNET_SYSERR;
718  }
719  if (GNUNET_YES == state->is_dns)
720  {
721  GNUNET_break_op (0);
722  return GNUNET_SYSERR;
723  }
724  if (NULL == state->specifics.tcp_udp.serv)
725  {
726  GNUNET_break_op (0);
727  return GNUNET_SYSERR;
728  }
729  if (NULL != state->specifics.tcp_udp.heap_node)
730  {
731  GNUNET_break_op (0);
732  return GNUNET_SYSERR;
733  }
734  if (start->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
735  {
736  GNUNET_break_op (0);
737  return GNUNET_SYSERR;
738  }
739  return GNUNET_OK;
740 }
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 762 of file gnunet-daemon-exit.c.

769 {
770  size_t len;
771 
772  len = payload_length;
773  switch (protocol)
774  {
775  case IPPROTO_UDP:
776  len += sizeof(struct GNUNET_TUN_UdpHeader);
777  break;
778 
779  case IPPROTO_TCP:
780  len += sizeof(struct GNUNET_TUN_TcpHeader);
781  GNUNET_assert (NULL != tcp_header);
782  break;
783 
784  default:
785  GNUNET_break (0);
786  return;
787  }
788  if (len + sizeof(struct GNUNET_TUN_IPv4Header) > UINT16_MAX)
789  {
790  GNUNET_break (0);
791  return;
792  }
793 
795  protocol,
796  len,
797  &src_address->address.ipv4,
798  &dst_address->address.ipv4);
799  switch (protocol)
800  {
801  case IPPROTO_UDP:
802  {
803  struct GNUNET_TUN_UdpHeader *pkt4_udp = (struct
804  GNUNET_TUN_UdpHeader *) &pkt4[1];
805 
806  pkt4_udp->source_port = htons (src_address->port);
807  pkt4_udp->destination_port = htons (dst_address->port);
808  pkt4_udp->len = htons ((uint16_t) payload_length);
810  pkt4_udp,
811  payload,
812  payload_length);
813  GNUNET_memcpy (&pkt4_udp[1],
814  payload,
815  payload_length);
816  }
817  break;
818 
819  case IPPROTO_TCP:
820  {
821  struct GNUNET_TUN_TcpHeader *pkt4_tcp = (struct
822  GNUNET_TUN_TcpHeader *) &pkt4[1];
823 
824  *pkt4_tcp = *tcp_header;
826  "Sending TCP packet from port %u to port %u\n",
827  src_address->port,
828  dst_address->port);
829  pkt4_tcp->source_port = htons (src_address->port);
830  pkt4_tcp->destination_port = htons (dst_address->port);
832  pkt4_tcp,
833  payload,
834  payload_length);
835  GNUNET_memcpy (&pkt4_tcp[1],
836  payload,
837  payload_length);
838  }
839  break;
840 
841  default:
842  GNUNET_assert (0);
843  }
844 }
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:160
GNUNET_NETWORK_STRUCT_END void GNUNET_TUN_initialize_ipv4_header(struct GNUNET_TUN_IPv4Header *ip, uint8_t protocol, uint16_t payload_length, const struct in_addr *src, const struct in_addr *dst)
Initialize an IPv4 header.
Definition: tun.c:47
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:102
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 866 of file gnunet-daemon-exit.c.

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

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

964 {
965  size_t len;
966 
968  gettext_noop ("# TCP packets sent via TUN"),
969  1,
970  GNUNET_NO);
972  "Sending packet with %u bytes TCP payload via TUN\n",
973  (unsigned int) payload_length);
974  len = sizeof(struct GNUNET_MessageHeader) + sizeof(struct
976  switch (source_address->af)
977  {
978  case AF_INET:
979  len += sizeof(struct GNUNET_TUN_IPv4Header);
980  break;
981 
982  case AF_INET6:
983  len += sizeof(struct GNUNET_TUN_IPv6Header);
984  break;
985 
986  default:
987  GNUNET_break (0);
988  return;
989  }
990  len += sizeof(struct GNUNET_TUN_TcpHeader);
991  len += payload_length;
993  {
994  GNUNET_break (0);
995  return;
996  }
997  {
998  char buf[len] GNUNET_ALIGN;
999  struct GNUNET_MessageHeader *hdr;
1000  struct GNUNET_TUN_Layer2PacketHeader *tun;
1001 
1002  hdr = (struct GNUNET_MessageHeader *) buf;
1003  hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1004  hdr->size = htons (len);
1005  tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
1006  tun->flags = htons (0);
1007  switch (source_address->af)
1008  {
1009  case AF_INET:
1010  {
1011  struct GNUNET_TUN_IPv4Header *ipv4
1012  = (struct GNUNET_TUN_IPv4Header*) &tun[1];
1013 
1014  tun->proto = htons (ETH_P_IPV4);
1016  payload_length,
1017  IPPROTO_TCP,
1018  tcp_header,
1021  ipv4);
1022  }
1023  break;
1024 
1025  case AF_INET6:
1026  {
1027  struct GNUNET_TUN_IPv6Header *ipv6
1028  = (struct GNUNET_TUN_IPv6Header*) &tun[1];
1029 
1030  tun->proto = htons (ETH_P_IPV6);
1033  IPPROTO_TCP,
1034  tcp_header,
1037  ipv6);
1038  }
1039  break;
1040 
1041  default:
1042  GNUNET_assert (0);
1043  break;
1044  }
1045  if (NULL != helper_handle)
1047  (const struct GNUNET_MessageHeader*) buf,
1048  GNUNET_YES,
1049  NULL,
1050  NULL);
1051  }
1052 }
#define gettext_noop(String)
Definition: gettext.h:70
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:60
static int ipv6
Option -6: IPv6 requested.
Definition: gnunet-vpn.c:65
#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:614
#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 1065 of file gnunet-daemon-exit.c.

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

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

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

1293 {
1294  struct GNUNET_HashCode key;
1295  struct ChannelState *s;
1296 
1297  /* generate fresh, unique address */
1298  do
1299  {
1300  if (NULL == state->specifics.tcp_udp.serv)
1301  setup_fresh_address (state->specifics.tcp_udp.ri.remote_address.af,
1302  state->specifics.tcp_udp.ri.remote_address.proto,
1303  &state->specifics.tcp_udp.ri.local_address);
1304  else
1305  setup_fresh_address (state->specifics.tcp_udp.serv->address.af,
1306  state->specifics.tcp_udp.serv->address.proto,
1307  &state->specifics.tcp_udp.ri.local_address);
1308  }
1309  while (NULL !=
1310  get_redirect_state (state->specifics.tcp_udp.ri.remote_address.af,
1311  state->specifics.tcp_udp.ri.remote_address.proto,
1312  &state->specifics.tcp_udp.ri.remote_address.address,
1313  state->specifics.tcp_udp.ri.remote_address.port,
1314  &state->specifics.tcp_udp.ri.local_address.address,
1315  state->specifics.tcp_udp.ri.local_address.port,
1316  &key));
1317  {
1318  char buf[INET6_ADDRSTRLEN];
1320  "Picked local address %s:%u for new connection\n",
1321  inet_ntop (state->specifics.tcp_udp.ri.local_address.af,
1322  &state->specifics.tcp_udp.ri.local_address.address,
1323  buf,
1324  sizeof(buf)),
1325  (unsigned int) state->specifics.tcp_udp.ri.local_address.port);
1326  }
1327  state->specifics.tcp_udp.state_key = key;
1330  &key, state,
1332  state->specifics.tcp_udp.heap_node
1334  state,
1335  GNUNET_TIME_absolute_get ().abs_value_us);
1337  {
1339  GNUNET_assert (state != s);
1340  s->specifics.tcp_udp.heap_node = NULL;
1344  &s->specifics.tcp_udp.
1345  state_key,
1346  s));
1347  GNUNET_free (s);
1348  }
1349 }
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:830
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
@ 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 1361 of file gnunet-daemon-exit.c.

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

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

1464 {
1465  struct ChannelState *state = cls;
1466 
1467  if (GNUNET_YES == state->is_dns)
1468  {
1469  GNUNET_break_op (0);
1470  return GNUNET_SYSERR;
1471  }
1472  return GNUNET_OK;
1473 }

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

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

1584 {
1585  struct ChannelState *state = cls;
1586 
1587  if (NULL == state->specifics.tcp_udp.serv)
1588  {
1589  GNUNET_break_op (0);
1590  return GNUNET_SYSERR;
1591  }
1592  return GNUNET_OK;
1593 }

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

1606 {
1607  struct ChannelState *state = cls;
1608  uint16_t pkt_len = ntohs (msg->header.size) - sizeof(struct
1610 
1612  gettext_noop ("# Bytes received from CADET"),
1613  pkt_len, GNUNET_NO);
1615  gettext_noop (
1616  "# UDP service requests received via cadet"),
1617  1, GNUNET_NO);
1619  "Received data from %s for forwarding to UDP service %s on port %u\n",
1620  GNUNET_i2s (&state->peer),
1621  GNUNET_h2s (&state->specifics.tcp_udp.serv->descriptor),
1622  (unsigned int) ntohs (msg->destination_port));
1624  if (0 != ntohs (msg->source_port))
1625  state->specifics.tcp_udp.ri.local_address.port = msg->source_port;
1626  send_udp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1627  &state->specifics.tcp_udp.ri.local_address,
1628  &msg[1],
1629  pkt_len);
1630  GNUNET_CADET_receive_done (state->channel);
1631 }
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 1644 of file gnunet-daemon-exit.c.

1646 {
1647  struct ChannelState *state = cls;
1648  uint16_t pkt_len = ntohs (start->header.size) - sizeof(struct
1650 
1651  if (GNUNET_SYSERR == state->is_dns)
1652  {
1653  /* channel is UDP/TCP from now on */
1654  state->is_dns = GNUNET_NO;
1655  }
1657  gettext_noop (
1658  "# TCP service creation requests received via cadet"),
1659  1,
1660  GNUNET_NO);
1662  gettext_noop ("# Bytes received from CADET"),
1663  pkt_len,
1664  GNUNET_NO);
1665  GNUNET_break_op (ntohl (start->reserved) == 0);
1666  /* setup fresh connection */
1668  "Received data from %s for forwarding to TCP service %s on port %u\n",
1669  GNUNET_i2s (&state->peer),
1670  GNUNET_h2s (&state->specifics.tcp_udp.serv->descriptor),
1671  (unsigned int) ntohs (start->tcp_header.destination_port));
1673  send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1674  &state->specifics.tcp_udp.ri.local_address,
1675  &start->tcp_header,
1676  &start[1],
1677  pkt_len);
1678  GNUNET_CADET_receive_done (state->channel);
1679 }
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 1691 of file gnunet-daemon-exit.c.

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

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

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

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

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

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

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

1918 {
1920  state->specifics.tcp_udp.ri.remote_address.
1921  proto,
1922  sizeof(struct GNUNET_TUN_TcpHeader),
1923  &state->specifics.tcp_udp.ri.remote_address
1924  .address.ipv4,
1925  &state->specifics.tcp_udp.ri.local_address.
1926  address.ipv4);
1927  udp->source_port = htons (state->specifics.tcp_udp.ri.remote_address.port);
1928  udp->destination_port = htons (
1929  state->specifics.tcp_udp.ri.local_address.port);
1930  udp->len = htons (0);
1931  udp->crc = htons (0);
1932 }
static char * address
GNS address for this phone.
static int udp
Option -u: UDP requested.
Definition: gnunet-vpn.c:75

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

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

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

1976 {
1977  struct ChannelState *state = cls;
1978 
1979  if (GNUNET_YES == state->is_dns)
1980  {
1981  GNUNET_break_op (0);
1982  return GNUNET_SYSERR;
1983  }
1984  return GNUNET_OK;
1985 }

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

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

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

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

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

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

2274 {
2275  struct ChannelState *state = cls;
2276  uint16_t pkt_len = ntohs (msg->header.size) - sizeof(struct
2278  struct GNUNET_TUN_IcmpHeader icmp;
2279  char buf[sizeof(struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
2280  const void *payload;
2281 
2283  gettext_noop ("# Bytes received from CADET"),
2284  pkt_len, GNUNET_NO);
2286  gettext_noop (
2287  "# ICMP service requests received via cadet"),
2288  1, GNUNET_NO);
2289  /* check that we got at least a valid header */
2291  "Received data from %s for forwarding to ICMP service %s\n",
2292  GNUNET_i2s (&state->peer),
2293  GNUNET_h2s (&state->specifics.tcp_udp.serv->descriptor));
2294  icmp = msg->icmp_header;
2295  payload = &msg[1];
2296  state->specifics.tcp_udp.ri.remote_address
2297  = state->specifics.tcp_udp.serv->address;
2299 
2300  /* check that ICMP type is something we want to support,
2301  perform ICMP PT if needed and possibly make up payload */
2302  switch (msg->af)
2303  {
2304  case AF_INET:
2305  switch (msg->icmp_header.type)
2306  {
2308  if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2309  icmp.type = GNUNET_TUN_ICMPTYPE6_ECHO_REPLY;
2310  break;
2311 
2313  if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2315  break;
2316 
2318  if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2320  if (0 != pkt_len)
2321  {
2322  GNUNET_break_op (0);
2323  return;
2324  }
2325  payload = buf;
2326  pkt_len = make_up_icmp_service_payload (state, buf);
2327  break;
2328 
2330  if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2332  if (0 != pkt_len)
2333  {
2334  GNUNET_break_op (0);
2335  return;
2336  }
2337  payload = buf;
2338  pkt_len = make_up_icmp_service_payload (state, buf);
2339  break;
2340 
2342  if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2343  {
2345  gettext_noop (
2346  "# ICMPv4 packets dropped (impossible PT to v6)"),
2347  1, GNUNET_NO);
2348  return;
2349  }
2350  if (0 != pkt_len)
2351  {
2352  GNUNET_break_op (0);
2353  return;
2354  }
2355  payload = buf;
2356  pkt_len = make_up_icmp_service_payload (state, buf);
2357  break;
2358 
2359  default:
2360  GNUNET_break_op (0);
2362  gettext_noop (
2363  "# ICMPv4 packets dropped (type not allowed)"),
2364  1, GNUNET_NO);
2365  return;
2366  }
2367  /* end of AF_INET */
2368  break;
2369 
2370  case AF_INET6:
2371  switch (msg->icmp_header.type)
2372  {
2374  if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2375  icmp.type = GNUNET_TUN_ICMPTYPE_ECHO_REPLY;
2376  break;
2377 
2379  if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2381  break;
2382 
2384  if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2386  if (0 != pkt_len)
2387  {
2388  GNUNET_break_op (0);
2389  return;
2390  }
2391  payload = buf;
2392  pkt_len = make_up_icmp_service_payload (state, buf);
2393  break;
2394 
2396  if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2398  if (0 != pkt_len)
2399  {
2400  GNUNET_break_op (0);
2401  return;
2402  }
2403  payload = buf;
2404  pkt_len = make_up_icmp_service_payload (state, buf);
2405  break;
2406 
2409  if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2410  {
2412  gettext_noop (
2413  "# ICMPv6 packets dropped (impossible PT to v4)"),
2414  1, GNUNET_NO);
2415  return;
2416  }
2417  if (0 != pkt_len)
2418  {
2419  GNUNET_break_op (0);
2420  return;
2421  }
2422  payload = buf;
2423  pkt_len = make_up_icmp_service_payload (state, buf);
2424  break;
2425 
2426  default:
2427  GNUNET_break_op (0);
2429  gettext_noop (
2430  "# ICMPv6 packets dropped (type not allowed)"),
2431  1, GNUNET_NO);
2432  return;
2433  }
2434  /* end of AF_INET6 */
2435  break;
2436 
2437  default:
2438  GNUNET_break_op (0);
2439  return;
2440  }
2441 
2442  send_icmp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
2443  &state->specifics.tcp_udp.ri.local_address,
2444  &icmp,
2445  payload,
2446  pkt_len);
2447  GNUNET_CADET_receive_done (state->channel);
2448 }
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 2460 of file gnunet-daemon-exit.c.

2463 {
2464  struct LocalService *service = value;
2465 
2468  key,
2469  service));
2471  GNUNET_free (service->name);
2472  GNUNET_free (service);
2473  return GNUNET_OK;
2474 }
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:801
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 2486 of file gnunet-daemon-exit.c.

2489 {
2490  struct LocalService *ls = cls;
2491  struct ChannelState *s = GNUNET_new (struct ChannelState);
2492 
2493  s->peer = *initiator;
2495  gettext_noop ("# Inbound CADET channels created"),
2496  1,
2497  GNUNET_NO);
2499  "Received inbound channel from `%s'\n",
2500  GNUNET_i2s (initiator));
2501  s->channel = channel;
2502  s->specifics.tcp_udp.serv = ls;
2503  s->specifics.tcp_udp.ri.remote_address = ls->address;
2504  return s;
2505 }
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 2516 of file gnunet-daemon-exit.c.

2518 {
2519  struct ChannelState *s = cls;
2520 
2522  "Channel destroyed\n");
2523  if (GNUNET_SYSERR == s->is_dns)
2524  {
2525  GNUNET_free (s);
2526  return;
2527  }
2528  if (GNUNET_YES == s->is_dns)
2529  {
2530  if (channels[s->specifics.dns.my_id] == s)
2531  channels[s->specifics.dns.my_id] = NULL;
2532  }
2533  else
2534  {
2535  if (NULL != s->specifics.tcp_udp.heap_node)
2536  {
2539  &s->specifics.tcp_udp
2540  .state_key,
2541  s));
2543  s->specifics.tcp_udp.heap_node = NULL;
2544  }
2545  }
2546  GNUNET_free (s);
2547 }
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 2560 of file gnunet-daemon-exit.c.

2564 {
2565  struct GNUNET_MQ_MessageHandler handlers[] = {
2566  GNUNET_MQ_hd_var_size (icmp_service,
2569  service),
2570  GNUNET_MQ_hd_var_size (udp_service,
2573  service),
2574  GNUNET_MQ_hd_var_size (tcp_service,
2577  service),
2578  GNUNET_MQ_hd_var_size (tcp_data,
2581  service),
2583  };
2584 
2585  struct GNUNET_HashCode cadet_port;
2586 
2587  service->name = GNUNET_strdup (name);
2589  &service->descriptor);
2591  destination_port,
2592  &cadet_port);
2594  "Opening CADET port %s for SERVICE exit %s on port %u\n",
2596  name,
2597  (unsigned int) destination_port);
2599  &cadet_port,
2601  service,
2602  NULL,
2603  &clean_channel,
2604  handlers);
2605  service->is_udp = (IPPROTO_UDP == proto);
2606  if (GNUNET_OK !=
2608  &cadet_port,
2609  service,
2611  {
2613  GNUNET_free (service->name);
2614  GNUNET_free (service);
2616  _ ("Got duplicate service records for `%s:%u'\n"),
2617  name,
2618  (unsigned int) destination_port);
2619  }
2620 }
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:954
@ 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:791
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:772
#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 2630 of file gnunet-daemon-exit.c.

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

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

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

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

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

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

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

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

3218 {
3219  GNUNET_free (value);
3220  return GNUNET_YES;
3221 }

References GNUNET_free, GNUNET_YES, and value.

Referenced by cleanup().

Here is the caller graph for this function:

◆ dummy_task()

static void dummy_task ( void *  cls)
static

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

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

Parameters
clsNULL

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

3234 {
3235  /* just terminate */
3236 }

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

3246 {
3247  unsigned int i;
3248 
3250  "Exit service is shutting down now\n");
3251 
3252  if (NULL != helper_handle)
3253  {
3255  helper_handle = NULL;
3256  }
3257  if (NULL != regex4)
3258  {
3260  regex4 = NULL;
3261  }
3262  if (NULL != regex6)
3263  {
3265  regex6 = NULL;
3266  }
3267  if (NULL != services)
3268  {
3271  NULL);
3273  }
3274  if (NULL != dns_port)
3275  {
3277  dns_port = NULL;
3278  }
3279  if (NULL != cadet_port4)
3280  {
3282  cadet_port4 = NULL;
3283  }
3284  if (NULL != cadet_port6)
3285  {
3287  cadet_port6 = NULL;
3288  }
3289  if (NULL != cadet_handle)
3290  {
3292  cadet_handle = NULL;
3293  }
3294  if (NULL != connections_map)
3295  {
3297  &free_iterate,
3298  NULL);
3300  connections_map = NULL;
3301  }
3302  if (NULL != connections_heap)
3303  {
3305  connections_heap = NULL;
3306  }
3307  if (NULL != dnsstub)
3308  {
3310  dnsstub = NULL;
3311  }
3312  if (NULL != peer_key)
3313  {
3315  peer_key = NULL;
3316  }
3317  if (NULL != dht_task)
3318  {
3320  dht_task = NULL;
3321  }
3322  if (NULL != dht_put)
3323  {
3325  dht_put = NULL;
3326  }
3327  if (NULL != dht)
3328  {
3330  dht = NULL;
3331  }
3332  if (NULL != stats)
3333  {
3335  GNUNET_NO);
3336  stats = NULL;
3337  }
3338  for (i = 0; i < 8; i++)
3339  GNUNET_free (exit_argv[i]);
3340 }
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:774
void GNUNET_DHT_put_cancel(struct GNUNET_DHT_PutHandle *ph)
Cancels a DHT PUT operation.
Definition: dht_api.c:1148
void GNUNET_DHT_disconnect(struct GNUNET_DHT_Handle *handle)
Shutdown connection with the DHT service.
Definition: dht_api.c:1062
void GNUNET_DNSSTUB_stop(struct GNUNET_DNSSTUB_Context *ctx)
Cleanup DNSSTUB resolver.
Definition: dnsstub.c:705
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
void GNUNET_CONTAINER_multihashmap_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:537
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:975
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 3351 of file gnunet-daemon-exit.c.

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

3518 {
3519  char *cpy;
3520 
3521  if ((strlen (section) < 8) ||
3522  (0 != strcmp (".gnunet.", section + (strlen (section) - 8))))
3523  return;
3524  if (GNUNET_OK ==
3526  section,
3527  "UDP_REDIRECTS",
3528  &cpy))
3529  {
3530  add_services (IPPROTO_UDP,
3531  cpy,
3532  section);
3533  GNUNET_free (cpy);
3534  }
3535  if (GNUNET_OK ==
3537  section,
3538  "TCP_REDIRECTS",
3539  &cpy))
3540  {
3541  add_services (IPPROTO_TCP,
3542  cpy,
3543  section);
3544  GNUNET_free (cpy);
3545  }
3546 }
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 3579 of file gnunet-daemon-exit.c.

3580 {
3582 
3584  &do_dht_put,
3585  NULL);
3587  if (GNUNET_TIME_absolute_get_remaining (expiration).rel_value_us <
3588  GNUNET_TIME_UNIT_HOURS.rel_value_us)
3589  {
3590  /* refresh advertisement */
3597  }
3598  if (NULL != dht_put)
3601  &dht_put_key,
3602  1 /* replication */,
3605  sizeof(struct GNUNET_DNS_Advertisement),
3607  expiration,
3608  &dht_put_cont,
3609  NULL);
3610 }
@ GNUNET_BLOCK_TYPE_DNS
Block for storing DNS exit service advertisements.
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?
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:619
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:1090
@ 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:1272
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:405
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:737
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:316
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:638
This is the structure describing an DNS exit service.
Definition: block_dns.h:45
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does this signature expire?
Definition: block_dns.h:60
struct GNUNET_CRYPTO_EddsaSignature signature
Signature of the peer affirming that it is offering the service.
Definition: block_dns.h:49
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Beginning of signed portion of the record, signs everything until the end of the struct.
Definition: block_dns.h:55
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 3566 of file gnunet-daemon-exit.c.

3567 {
3568  dht_put = NULL;
3569 }

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

3619 {
3621  "exit",
3622  "EXIT_IPV4");
3624  "exit",
3625  "EXIT_IPV6");
3627  "exit",
3628  "ENABLE_IPV4");
3630  "exit",
3631  "ENABLE_IPV6");
3632  if ((ipv4_exit || ipv4_enabled) &&
3633  (GNUNET_OK != GNUNET_NETWORK_test_pf (PF_INET)) )
3634  {
3636  _ (
3637  "This system does not support IPv4, will disable IPv4 functions despite them being enabled in the configuration\n"));
3638  ipv4_exit = GNUNET_NO;
3640  }
3641  if ((ipv6_exit || ipv6_enabled) &&
3642  (GNUNET_OK != GNUNET_NETWORK_test_pf (PF_INET6)) )
3643  {
3645  _ (
3646  "This system does not support IPv6, will disable IPv6 functions despite them being enabled in the configuration\n"));
3647  ipv6_exit = GNUNET_NO;
3649  }
3650  if (ipv4_exit && (! ipv4_enabled))
3651  {
3653  _ (
3654  "Cannot enable IPv4 exit but disable IPv4 on TUN interface, will use ENABLE_IPv4=YES\n"));
3656  }
3657  if (ipv6_exit && (! ipv6_enabled))
3658  {
3660  _ (
3661  "Cannot enable IPv6 exit but disable IPv6 on TUN interface, will use ENABLE_IPv6=YES\n"));
3663  }
3664 }
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
enum GNUNET_GenericReturnValue GNUNET_NETWORK_test_pf(int pf)
Test if the given protocol family is supported by this system.
Definition: network.c:79

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

3673 {
3674  struct GNUNET_MQ_MessageHandler handlers[] = {
3675  GNUNET_MQ_hd_var_size (dns_request,
3677  struct DnsResponseMessage,
3678  NULL),
3680  };
3681  char *dns_exit;
3682  struct GNUNET_HashCode port;
3683 
3684  if (GNUNET_YES !=
3686  "exit",
3687  "EXIT_DNS"))
3688  return;
3689  GNUNET_assert (NULL != (dnsstub = GNUNET_DNSSTUB_start (128)));
3690  dns_exit = NULL;
3691  /* TODO: support using multiple DNS resolvers */
3692  if ((GNUNET_OK !=
3694  "exit",
3695  "DNS_RESOLVER",
3696  &dns_exit)) ||
3697  (GNUNET_OK !=
3699  dns_exit)))
3700  {
3702  "dns",
3703  "DNS_RESOLVER",
3704  _ ("need a valid IPv4 or IPv6 address\n"));
3705  GNUNET_free (dns_exit);
3706  return;
3707  }
3708  /* open port */
3711  &port);
3713  "Opening CADET port %s for DNS exit service\n",
3714  GNUNET_h2s (&port));
3716  &port,
3717  &new_channel,
3718  NULL,
3719  NULL,
3720  &clean_channel,
3721  handlers);
3722  /* advertise exit */
3724  1);
3728  dns_advertisement.purpose.size = htonl (sizeof(struct
3730  - sizeof(struct
3734  GNUNET_CRYPTO_hash ("dns",
3735  strlen ("dns"),
3736  &dht_put_key);
3738  NULL);
3739  GNUNET_free (dns_exit);
3740 }
#define GNUNET_SIGNATURE_PURPOSE_DNS_RECORD
Signature on a GNUNET_DNS_Advertisement.
static uint16_t port
Port number.
Definition: gnunet-bcd.c:147
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:1039
int GNUNET_DNSSTUB_add_dns_ip(struct GNUNET_DNSSTUB_Context *ctx, const char *dns_ip)
Add nameserver for use by the DNSSTUB.
Definition: dnsstub.c:613
struct GNUNET_DNSSTUB_Context * GNUNET_DNSSTUB_start(unsigned int num_sockets)
Start a DNS stub resolver.
Definition: dnsstub.c:586
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:1299
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:65
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 3749 of file gnunet-daemon-exit.c.

3750 {
3751  char *exit_ifname;
3752  char *tun_ifname;
3753  char *ipv6addr;
3754  char *ipv6prefix_s;
3755  char *ipv4addr;
3756  char *ipv4mask;
3757 
3758  exit_argv[0] = GNUNET_strdup ("exit-gnunet");
3759  if (GNUNET_SYSERR ==
3761  "exit",
3762  "TUN_IFNAME",
3763  &tun_ifname))
3764  {
3766  "EXIT",
3767  "TUN_IFNAME");
3768  return GNUNET_SYSERR;
3769  }
3770  exit_argv[1] = tun_ifname;
3771  if (ipv4_enabled)
3772  {
3773  if (GNUNET_SYSERR ==
3775  "exit",
3776  "EXIT_IFNAME",
3777  &exit_ifname))
3778  {
3780  "EXIT",
3781  "EXIT_IFNAME");
3782  return GNUNET_SYSERR;
3783  }
3784  exit_argv[2] = exit_ifname;
3785  }
3786  else
3787  {
3788  exit_argv[2] = GNUNET_strdup ("-");
3789  }
3790 
3791  if (GNUNET_YES == ipv6_enabled)
3792  {
3793  ipv6addr = NULL;
3794  if (((GNUNET_SYSERR ==
3796  "exit",
3797  "IPV6ADDR",
3798  &ipv6addr)) ||
3799  (1 != inet_pton (AF_INET6,
3800  ipv6addr,
3801  &exit_ipv6addr))))
3802  {
3804  "EXIT",
3805  "IPV6ADDR");
3806  GNUNET_free (ipv6addr);
3807  return GNUNET_SYSERR;
3808  }
3809  exit_argv[3] = ipv6addr;
3810  if (GNUNET_SYSERR ==
3812  "exit",
3813  "IPV6PREFIX",
3814  &ipv6prefix_s))
3815  {
3817  "EXIT",
3818  "IPV6PREFIX");
3819  return GNUNET_SYSERR;
3820  }
3821  exit_argv[4] = ipv6prefix_s;
3822  if ((GNUNET_OK !=
3824  "exit",
3825  "IPV6PREFIX",
3826  &ipv6prefix)) ||
3827  (ipv6prefix >= 127))
3828  {
3830  "EXIT",
3831  "IPV6PREFIX",
3832  _ ("Must be a number"));
3833  return GNUNET_SYSERR;
3834  }
3835  }
3836  else
3837  {
3838  /* IPv6 explicitly disabled */
3839  exit_argv[3] = GNUNET_strdup ("-");
3840  exit_argv[4] = GNUNET_strdup ("-");
3841  }
3842  if (GNUNET_YES == ipv4_enabled)
3843  {
3844  ipv4addr = NULL;
3845  if (((GNUNET_SYSERR ==
3847  "exit",
3848  "IPV4ADDR",
3849  &ipv4addr)) ||
3850  (1 != inet_pton (AF_INET,
3851  ipv4addr,
3852  &exit_ipv4addr))))
3853  {
3855  "EXIT",
3856  "IPV4ADDR");
3857  GNUNET_free (ipv4addr);
3858  return GNUNET_SYSERR;
3859  }
3860  exit_argv[5] = ipv4addr;
3861  ipv4mask = NULL;
3862  if (((GNUNET_SYSERR ==
3864  "exit",
3865  "IPV4MASK",
3866  &ipv4mask)) ||
3867  (1 != inet_pton (AF_INET,
3868  ipv4mask,
3869  &exit_ipv4mask))))
3870  {
3872  "EXIT",
3873  "IPV4MASK");
3874  GNUNET_free (ipv4mask);
3875  return GNUNET_SYSERR;
3876  }
3877  exit_argv[6] = ipv4mask;
3878  }
3879  else
3880  {
3881  /* IPv4 explicitly disabled */
3882  exit_argv[5] = GNUNET_strdup ("-");
3883  exit_argv[6] = GNUNET_strdup ("-");
3884  }
3885  exit_argv[7] = NULL;
3886  return GNUNET_OK;
3887 }
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 3899 of file gnunet-daemon-exit.c.

3903 {
3904  struct GNUNET_MQ_MessageHandler handlers[] = {
3905  GNUNET_MQ_hd_var_size (icmp_remote,
3908  NULL),
3909  GNUNET_MQ_hd_var_size (udp_remote,
3912  NULL),
3913  GNUNET_MQ_hd_var_size (tcp_remote,
3916  NULL),
3917  GNUNET_MQ_hd_var_size (tcp_data,
3920  NULL),
3922  };
3923  struct GNUNET_HashCode port;
3924  char *policy;
3925  char *binary;
3926  char *regex;
3927  char *prefixed_regex;
3928 
3929  cfg = cfg_;
3930  if (GNUNET_OK !=
3932  "exit",
3933  "MAX_CONNECTIONS",
3934  &max_connections))
3935  max_connections = 1024;
3936  parse_ip_options ();
3937  binary = GNUNET_OS_get_suid_binary_path (cfg, "gnunet-helper-exit");
3938  if ((ipv4_exit) || (ipv6_exit))
3939  {
3940  if (GNUNET_YES !=
3942  GNUNET_YES,
3943  "gnunet-vpn - - - 169.1.3.7 255.255.255.0")) // no nat, ipv4 only
3944  {
3945  GNUNET_free (binary);
3947  _ (
3948  "`%s' is not SUID or the path is invalid, EXIT will not work\n"),
3949  "gnunet-helper-exit");
3951  NULL);
3952  global_ret = 1;
3953  return;
3954  }
3955  }
3956  if (! (ipv4_enabled || ipv6_enabled))
3957  {
3958  GNUNET_free (binary);
3960  _ ("No useful service enabled. Exiting.\n"));
3962  return;
3963  }
3964 
3966  NULL);
3967  stats = GNUNET_STATISTICS_create ("exit",
3968  cfg);
3970  if (NULL == cadet_handle)
3971  {
3972  GNUNET_free (binary);
3974  return;
3975  }
3976  advertise_dns_exit ();
3977  if (GNUNET_OK !=
3979  {
3980  GNUNET_free (binary);
3982  return;
3983  }
3984 
3986  GNUNET_NO);
3988  GNUNET_NO);
3993  NULL);
3994 
3995  /* Cadet handle acquired, now open ports and announce regular
3996  expressions matching our exit */
3997  if ((GNUNET_YES == ipv4_enabled) &&
3998  (GNUNET_YES == ipv4_exit))
3999  {
4002  &port);
4004  "Opening CADET port %s for IPv4 gateway service\n",
4005  GNUNET_h2s (&port));
4007  &port,
4008  &new_channel,
4009  NULL,
4010  NULL,
4011  &clean_channel,
4012  handlers);
4013  policy = NULL;
4014  if (GNUNET_OK !=
4016  "exit",
4017  "EXIT_RANGE_IPV4_POLICY",
4018  &policy))
4019  regex = NULL;
4020  else
4021  regex = GNUNET_TUN_ipv4policy2regex (policy);
4022  GNUNET_free (policy);
4023  if (NULL != regex)
4024  {
4025  (void) GNUNET_asprintf (&prefixed_regex,
4026  "%s%s",
4028  regex);
4030  prefixed_regex,
4033  GNUNET_free (regex);
4034  GNUNET_free (prefixed_regex);
4035  }
4036  }
4037 
4038  if ((GNUNET_YES == ipv6_enabled) && (GNUNET_YES == ipv6_exit))
4039  {
4042  &port);
4044  "Opening CADET port %s for IPv6 gateway service\n",
4045  GNUNET_h2s (&port));
4047  &port,
4048  &new_channel,
4049  NULL,
4050  NULL,