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

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

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

Go to the source code of this file.

Data Structures

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

Macros

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

Functions

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

Variables

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

Detailed Description

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

Author
Philipp Toelke
Christian Grothoff

TODO:

Design:

Definition in file gnunet-daemon-exit.c.

Macro Definition Documentation

◆ REGEX_MAX_PATH_LEN_IPV4

#define REGEX_MAX_PATH_LEN_IPV4   4

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

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

Referenced by run().

◆ REGEX_MAX_PATH_LEN_IPV6

#define REGEX_MAX_PATH_LEN_IPV6   8

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

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

Referenced by run().

◆ REGEX_REFRESH_FREQUENCY

#define REGEX_REFRESH_FREQUENCY   GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 30)

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

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

Referenced by run().

◆ DHT_PUT_FREQUENCY

#define DHT_PUT_FREQUENCY   GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 15)

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

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

Referenced by do_dht_put().

◆ DNS_ADVERTISEMENT_TIMEOUT

#define DNS_ADVERTISEMENT_TIMEOUT   GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_HOURS, 3)

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

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

Referenced by do_dht_put().

◆ LOG

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

Generic logging shorthand.

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

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

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

References ChannelState::channel, 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().

450 {
451  struct ChannelState *ts;
452  struct GNUNET_MQ_Envelope *env;
453  struct DnsResponseMessage *resp;
454 
456  "Processing DNS result from stub resolver\n");
457  GNUNET_assert(NULL == cls);
458  if (NULL == dns)
459  return;
460  /* Handle case that this is a reply to a request from a CADET DNS channel */
461  ts = channels[dns->id];
462  if (NULL == ts)
463  return;
465  "Got a response from the stub resolver for DNS request received via CADET!\n");
466  channels[dns->id] = NULL;
467  env = GNUNET_MQ_msg_extra(resp,
468  r - sizeof(struct GNUNET_TUN_DnsHeader),
470  GNUNET_memcpy(&resp->dns,
471  dns,
472  r);
473  resp->dns.id = ts->specifics.dns.original_id;
475  env);
476 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
struct ChannelState::@13::@15 dns
#define GNUNET_MESSAGE_TYPE_VPN_DNS_FROM_INTERNET
Type of messages containing an DNS reply from a DNS exit service.
#define LOG(kind,...)
Generic logging shorthand.
uint16_t id
Unique identifier for the request/response.
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
struct GNUNET_CADET_Channel * channel
Cadet channel that is used for this connection.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
struct GNUNET_TUN_DnsHeader dns
DNS header.
Message with a DNS response.
#define GNUNET_log(kind,...)
union ChannelState::@13 specifics
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
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:351
static struct ChannelState * channels[UINT16_MAX+1]
Array of all open DNS requests from channels.
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:1116
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 488 of file gnunet-daemon-exit.c.

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

490 {
491  struct ChannelState *ts = cls;
492 
493  if (NULL == dnsstub)
494  {
495  GNUNET_break(0);
496  return GNUNET_SYSERR;
497  }
498  if (GNUNET_NO == ts->is_dns)
499  {
500  GNUNET_break_op(0);
501  return GNUNET_SYSERR;
502  }
503  return GNUNET_OK;
504 }
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static struct GNUNET_DNSSTUB_Context * dnsstub
Handle to the DNS Stub resolver.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
int is_dns
GNUNET_NO if this is a channel for TCP/UDP, GNUNET_YES if this is a channel for DNS, GNUNET_SYSERR if the channel is not yet initialized.
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...

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

References buf, ChannelState::channel, DnsResponseMessage::dns, ChannelState::dns, 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, DnsResponseMessage::header, GNUNET_TUN_DnsHeader::id, ChannelState::is_dns, process_dns_result(), GNUNET_MessageHeader::size, and ChannelState::specifics.

516 {
517  struct ChannelState *ts = cls;
518  size_t mlen = ntohs(msg->header.size);
519  size_t dlen = mlen - sizeof(struct GNUNET_MessageHeader);
520  char buf[dlen] GNUNET_ALIGN;
521  struct GNUNET_TUN_DnsHeader *dout;
522 
523  if (GNUNET_SYSERR == ts->is_dns)
524  {
525  /* channel is DNS from now on */
526  ts->is_dns = GNUNET_YES;
527  }
528  ts->specifics.dns.original_id = msg->dns.id;
529  if (channels[ts->specifics.dns.my_id] == ts)
530  channels[ts->specifics.dns.my_id] = NULL;
532  UINT16_MAX + 1);
533  channels[ts->specifics.dns.my_id] = ts;
535  &msg->dns,
536  dlen);
537  dout = (struct GNUNET_TUN_DnsHeader *)buf;
538  dout->id = ts->specifics.dns.my_id;
540  buf,
541  dlen,
543  NULL);
544  if (NULL == ts->specifics.dns.rs)
545  {
546  GNUNET_break_op(0);
547  return;
548  }
550 }
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
struct GNUNET_MessageHeader header
GNUnet header, of type GNUNET_MESSAGE_TYPE_VPN_DNS_FROM_INTERNET.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
struct ChannelState::@13::@15 dns
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
uint16_t id
Unique identifier for the request/response.
static struct GNUNET_DNSSTUB_Context * dnsstub
Handle to the DNS Stub resolver.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
static char buf[2048]
struct GNUNET_CADET_Channel * channel
Cadet channel that is used for this connection.
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:501
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
struct GNUNET_TUN_DnsHeader dns
DNS header.
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:951
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to 'struct's...
int is_dns
GNUNET_NO if this is a channel for TCP/UDP, GNUNET_YES if this is a channel for DNS, GNUNET_SYSERR if the channel is not yet initialized.
union ChannelState::@13 specifics
Header for all communications.
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
#define GNUNET_YES
Definition: gnunet_common.h:77
static struct ChannelState * channels[UINT16_MAX+1]
Array of all open DNS requests from channels.
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
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.
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 561 of file gnunet-daemon-exit.c.

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

563 {
564  char *off;
565 
566  memset(hash,
567  0,
568  sizeof(struct GNUNET_HashCode));
569  /* the GNUnet hashmap only uses the first sizeof(unsigned int) of the hash,
570  so we put the IP address in there (and hope for few collisions) */
571  off = (char*)hash;
572  switch (ri->remote_address.af)
573  {
574  case AF_INET:
575  GNUNET_memcpy(off,
577  sizeof(struct in_addr));
578  off += sizeof(struct in_addr);
579  break;
580 
581  case AF_INET6:
582  GNUNET_memcpy(off,
584  sizeof(struct in6_addr));
585  off += sizeof(struct in_addr);
586  break;
587 
588  default:
589  GNUNET_assert(0);
590  }
591  GNUNET_memcpy(off,
592  &ri->remote_address.port,
593  sizeof(uint16_t));
594  off += sizeof(uint16_t);
595  switch (ri->local_address.af)
596  {
597  case AF_INET:
598  GNUNET_memcpy(off,
600  sizeof(struct in_addr));
601  off += sizeof(struct in_addr);
602  break;
603 
604  case AF_INET6:
605  GNUNET_memcpy(off,
607  sizeof(struct in6_addr));
608  off += sizeof(struct in_addr);
609  break;
610 
611  default:
612  GNUNET_assert(0);
613  }
614  GNUNET_memcpy(off,
615  &ri->local_address.port,
616  sizeof(uint16_t));
617  off += sizeof(uint16_t);
618  GNUNET_memcpy(off,
619  &ri->remote_address.proto,
620  sizeof(uint8_t));
621  /* off += sizeof (uint8_t); */
622 }
struct in6_addr ipv6
Address, if af is AF_INET6.
union SocketAddress::@12 address
Remote address information.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct in_addr ipv4
Address, if af is AF_INET.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
struct SocketAddress local_address
Address information we used locally (AF and proto must match "remote_address").
A 512-bit hashcode.
uint8_t proto
IPPROTO_TCP or IPPROTO_UDP;.
struct SocketAddress remote_address
Address information for the other party (equivalent of the arguments one would give to "connect")...
int af
AF_INET or AF_INET6.
uint16_t port
Remote port, in host byte order!
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 639 of file gnunet-daemon-exit.c.

References SocketAddress::address, SocketAddress::af, 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, RedirectInformation::remote_address, ChannelState::specifics, state, and ChannelState::tcp_udp.

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

646 {
647  struct RedirectInformation ri;
648  struct GNUNET_HashCode key;
649  struct ChannelState *state;
650 
651  if (((af == AF_INET) && (protocol == IPPROTO_ICMP)) ||
652  ((af == AF_INET6) && (protocol == IPPROTO_ICMPV6)))
653  {
654  /* ignore ports */
655  destination_port = 0;
656  local_port = 0;
657  }
659  if (af == AF_INET)
660  ri.remote_address.address.ipv4 = *((struct in_addr*)destination_ip);
661  else
662  ri.remote_address.address.ipv6 = *((struct in6_addr*)destination_ip);
663  ri.remote_address.port = destination_port;
664  ri.remote_address.proto = protocol;
665  ri.local_address.af = af;
666  if (af == AF_INET)
667  ri.local_address.address.ipv4 = *((struct in_addr*)local_ip);
668  else
669  ri.local_address.address.ipv6 = *((struct in6_addr*)local_ip);
670  ri.local_address.port = local_port;
671  ri.local_address.proto = protocol;
673  &ri);
674  if (NULL != state_key)
675  *state_key = key;
677  &key);
678  if (NULL == state)
679  return NULL;
680  /* Mark this connection as freshly used */
681  if (NULL == state_key)
683  GNUNET_TIME_absolute_get().abs_value_us);
684  return state;
685 }
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.
union SocketAddress::@12 address
Remote address information.
uint8_t protocol
IPPROTO_TCP or IPPROTO_UDP once bound.
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 in_addr ipv4
Address, if af is AF_INET.
struct RedirectInformation ri
Primary redirection information for this connection.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
enum State state
current state of profiling
int af
Addess family used for this channel on the local TUN interface.
A 512-bit hashcode.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
struct GNUNET_HashCode key
The key used in the DHT.
struct SocketAddress remote_address
Address information for the other party (equivalent of the arguments one would give to "connect")...
int af
AF_INET or AF_INET6.
Information we use to track a connection (the classical 6-tuple of IP-version, protocol, source-IP, destination-IP, source-port and destinatin-port.
uint16_t destination_port
Destination port used by the sender on our end; 0 for uninitialized.
union ChannelState::@13 specifics
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
static struct GNUNET_CONTAINER_MultiHashMap * connections_map
This hashmaps contains the mapping from peer, service-descriptor, source-port and destination-port to...
struct ChannelState::@13::@14 tcp_udp
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 699 of file gnunet-daemon-exit.c.

References GNUNET_break_op, GNUNET_OK, GNUNET_SYSERR, GNUNET_YES, ChannelState::is_dns, GNUNET_TUN_TcpHeader::off, ChannelState::specifics, state, GNUNET_EXIT_TcpServiceStartMessage::tcp_header, and ChannelState::tcp_udp.

701 {
702  struct ChannelState *state = cls;
703 
704  if (NULL == state)
705  {
706  GNUNET_break_op(0);
707  return GNUNET_SYSERR;
708  }
709  if (GNUNET_YES == state->is_dns)
710  {
711  GNUNET_break_op(0);
712  return GNUNET_SYSERR;
713  }
714  if (NULL == state->specifics.tcp_udp.serv)
715  {
716  GNUNET_break_op(0);
717  return GNUNET_SYSERR;
718  }
719  if (NULL != state->specifics.tcp_udp.heap_node)
720  {
721  GNUNET_break_op(0);
722  return GNUNET_SYSERR;
723  }
724  if (start->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
725  {
726  GNUNET_break_op(0);
727  return GNUNET_SYSERR;
728  }
729  return GNUNET_OK;
730 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
struct GNUNET_TUN_TcpHeader tcp_header
Skeleton of the TCP header to send.
Definition: exit.h:52
enum State state
current state of profiling
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
TCP packet header.
int is_dns
GNUNET_NO if this is a channel for TCP/UDP, GNUNET_YES if this is a channel for DNS, GNUNET_SYSERR if the channel is not yet initialized.
union ChannelState::@13 specifics
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
#define GNUNET_YES
Definition: gnunet_common.h:77
unsigned int off
Number of 32-bit words in TCP header.
struct ChannelState::@13::@14 tcp_udp

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

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, len, GNUNET_TUN_UdpHeader::len, 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().

759 {
760  size_t len;
761 
762  len = payload_length;
763  switch (protocol)
764  {
765  case IPPROTO_UDP:
766  len += sizeof(struct GNUNET_TUN_UdpHeader);
767  break;
768 
769  case IPPROTO_TCP:
770  len += sizeof(struct GNUNET_TUN_TcpHeader);
771  GNUNET_assert(NULL != tcp_header);
772  break;
773 
774  default:
775  GNUNET_break(0);
776  return;
777  }
778  if (len + sizeof(struct GNUNET_TUN_IPv4Header) > UINT16_MAX)
779  {
780  GNUNET_break(0);
781  return;
782  }
783 
785  protocol,
786  len,
787  &src_address->address.ipv4,
788  &dst_address->address.ipv4);
789  switch (protocol)
790  {
791  case IPPROTO_UDP:
792  {
793  struct GNUNET_TUN_UdpHeader *pkt4_udp = (struct GNUNET_TUN_UdpHeader *)&pkt4[1];
794 
795  pkt4_udp->source_port = htons(src_address->port);
796  pkt4_udp->destination_port = htons(dst_address->port);
797  pkt4_udp->len = htons((uint16_t)payload_length);
799  pkt4_udp,
800  payload,
801  payload_length);
802  GNUNET_memcpy(&pkt4_udp[1],
803  payload,
804  payload_length);
805  }
806  break;
807 
808  case IPPROTO_TCP:
809  {
810  struct GNUNET_TUN_TcpHeader *pkt4_tcp = (struct GNUNET_TUN_TcpHeader *)&pkt4[1];
811 
812  *pkt4_tcp = *tcp_header;
814  "Sending TCP packet from port %u to port %u\n",
815  src_address->port,
816  dst_address->port);
817  pkt4_tcp->source_port = htons(src_address->port);
818  pkt4_tcp->destination_port = htons(dst_address->port);
820  pkt4_tcp,
821  payload,
822  payload_length);
823  GNUNET_memcpy(&pkt4_tcp[1],
824  payload,
825  payload_length);
826  }
827  break;
828 
829  default:
830  GNUNET_assert(0);
831  }
832 }
union SocketAddress::@12 address
Remote address information.
uint8_t protocol
IPPROTO_TCP or IPPROTO_UDP once bound.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct in_addr ipv4
Address, if af is AF_INET.
UDP packet header.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
Standard IPv4 header.
void GNUNET_TUN_calculate_udp4_checksum(const struct GNUNET_TUN_IPv4Header *ip, struct GNUNET_TUN_UdpHeader *udp, const void *payload, uint16_t payload_length)
Calculate IPv4 UDP checksum.
Definition: tun.c:183
uint16_t destination_port
Destination port (in NBO).
uint16_t len
Number of bytes of payload.
void GNUNET_TUN_initialize_ipv4_header(struct GNUNET_TUN_IPv4Header *ip, uint8_t protocol, uint16_t payload_length, const struct in_addr *src, const struct in_addr *dst)
Initialize an IPv4 header.
Definition: tun.c:46
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
void GNUNET_TUN_calculate_tcp4_checksum(const struct GNUNET_TUN_IPv4Header *ip, struct GNUNET_TUN_TcpHeader *tcp, const void *payload, uint16_t payload_length)
Calculate IPv4 TCP checksum.
Definition: tun.c:109
uint16_t destination_port
Destination port (in NBO).
TCP packet header.
static unsigned long long payload
How much data are we currently storing in the database?
uint16_t source_port
Source port (in NBO).
uint16_t source_port
Source port (in NBO).
#define GNUNET_log(kind,...)
uint16_t port
Remote port, in host byte order!
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
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 854 of file gnunet-daemon-exit.c.

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, len, GNUNET_TUN_UdpHeader::len, 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().

861 {
862  size_t len;
863 
864  len = payload_length;
865  switch (protocol)
866  {
867  case IPPROTO_UDP:
868  len += sizeof(struct GNUNET_TUN_UdpHeader);
869  break;
870 
871  case IPPROTO_TCP:
872  len += sizeof(struct GNUNET_TUN_TcpHeader);
873  break;
874 
875  default:
876  GNUNET_break(0);
877  return;
878  }
879  if (len > UINT16_MAX)
880  {
881  GNUNET_break(0);
882  return;
883  }
884 
886  protocol,
887  len,
888  &src_address->address.ipv6,
889  &dst_address->address.ipv6);
890 
891  switch (protocol)
892  {
893  case IPPROTO_UDP:
894  {
895  struct GNUNET_TUN_UdpHeader *pkt6_udp = (struct GNUNET_TUN_UdpHeader *)&pkt6[1];
896 
897  pkt6_udp->source_port = htons(src_address->port);
898  pkt6_udp->destination_port = htons(dst_address->port);
899  pkt6_udp->len = htons((uint16_t)payload_length);
901  pkt6_udp,
902  payload,
903  payload_length);
904  GNUNET_memcpy(&pkt6_udp[1],
905  payload,
906  payload_length);
907  }
908  break;
909 
910  case IPPROTO_TCP:
911  {
912  struct GNUNET_TUN_TcpHeader *pkt6_tcp = (struct GNUNET_TUN_TcpHeader *)&pkt6[1];
913 
914  /* GNUNET_memcpy first here as some TCP header fields are initialized this way! */
915  *pkt6_tcp = *tcp_header;
916  pkt6_tcp->source_port = htons(src_address->port);
917  pkt6_tcp->destination_port = htons(dst_address->port);
919  pkt6_tcp,
920  payload,
921  payload_length);
922  GNUNET_memcpy(&pkt6_tcp[1],
923  payload,
924  payload_length);
925  }
926  break;
927 
928  default:
929  GNUNET_assert(0);
930  break;
931  }
932 }
struct in6_addr ipv6
Address, if af is AF_INET6.
union SocketAddress::@12 address
Remote address information.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
UDP packet header.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
uint16_t destination_port
Destination port (in NBO).
uint16_t len
Number of bytes of payload.
void GNUNET_TUN_calculate_tcp6_checksum(const struct GNUNET_TUN_IPv6Header *ip, struct GNUNET_TUN_TcpHeader *tcp, const void *payload, uint16_t payload_length)
Calculate IPv6 TCP checksum.
Definition: tun.c:147
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
void GNUNET_TUN_calculate_udp6_checksum(const struct GNUNET_TUN_IPv6Header *ip, struct GNUNET_TUN_UdpHeader *udp, const void *payload, uint16_t payload_length)
Calculate IPv6 UDP checksum.
Definition: tun.c:222
uint16_t destination_port
Destination port (in NBO).
TCP packet header.
static unsigned long long payload
How much data are we currently storing in the database?
uint16_t source_port
Source port (in NBO).
uint16_t source_port
Source port (in NBO).
uint16_t port
Remote port, in host byte order!
void GNUNET_TUN_initialize_ipv6_header(struct GNUNET_TUN_IPv6Header *ip, uint8_t protocol, uint16_t payload_length, const struct in6_addr *src, const struct in6_addr *dst)
Initialize an IPv6 header.
Definition: tun.c:81
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
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 945 of file gnunet-daemon-exit.c.

References SocketAddress::af, buf, 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, SocketAddress::ipv4, SocketAddress::ipv6, len, prepare_ipv4_packet(), prepare_ipv6_packet(), GNUNET_TUN_Layer2PacketHeader::proto, GNUNET_MessageHeader::size, and GNUNET_MessageHeader::type.

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

950 {
951  size_t len;
952 
954  gettext_noop("# TCP packets sent via TUN"),
955  1,
956  GNUNET_NO);
958  "Sending packet with %u bytes TCP payload via TUN\n",
959  (unsigned int)payload_length);
960  len = sizeof(struct GNUNET_MessageHeader) + sizeof(struct GNUNET_TUN_Layer2PacketHeader);
961  switch (source_address->af)
962  {
963  case AF_INET:
964  len += sizeof(struct GNUNET_TUN_IPv4Header);
965  break;
966 
967  case AF_INET6:
968  len += sizeof(struct GNUNET_TUN_IPv6Header);
969  break;
970 
971  default:
972  GNUNET_break(0);
973  return;
974  }
975  len += sizeof(struct GNUNET_TUN_TcpHeader);
976  len += payload_length;
977  if (len >= GNUNET_MAX_MESSAGE_SIZE)
978  {
979  GNUNET_break(0);
980  return;
981  }
982  {
983  char buf[len] GNUNET_ALIGN;
984  struct GNUNET_MessageHeader *hdr;
985  struct GNUNET_TUN_Layer2PacketHeader *tun;
986 
987  hdr = (struct GNUNET_MessageHeader *)buf;
988  hdr->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
989  hdr->size = htons(len);
990  tun = (struct GNUNET_TUN_Layer2PacketHeader*)&hdr[1];
991  tun->flags = htons(0);
992  switch (source_address->af)
993  {
994  case AF_INET:
995  {
997  = (struct GNUNET_TUN_IPv4Header*)&tun[1];
998 
999  tun->proto = htons(ETH_P_IPV4);
1001  payload_length,
1002  IPPROTO_TCP,
1003  tcp_header,
1004  source_address,
1005  destination_address,
1006  ipv4);
1007  }
1008  break;
1009 
1010  case AF_INET6:
1011  {
1012  struct GNUNET_TUN_IPv6Header *ipv6
1013  = (struct GNUNET_TUN_IPv6Header*)&tun[1];
1014 
1015  tun->proto = htons(ETH_P_IPV6);
1018  IPPROTO_TCP,
1019  tcp_header,
1020  source_address,
1021  destination_address,
1022  ipv6);
1023  }
1024  break;
1025 
1026  default:
1027  GNUNET_assert(0);
1028  break;
1029  }
1030  if (NULL != helper_handle)
1032  (const struct GNUNET_MessageHeader*)buf,
1033  GNUNET_YES,
1034  NULL,
1035  NULL);
1036  }
1037 }
static struct GNUNET_HELPER_Handle * helper_handle
The handle to the helper.
uint16_t proto
Here we get an ETH_P_-number.
static int ipv4
Option -4: IPv4 requested.
Definition: gnunet-vpn.c:61
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
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.
#define ETH_P_IPV6
Number for IPv6.
#define GNUNET_NO
Definition: gnunet_common.h:78
Standard IPv4 header.
uint16_t flags
Some flags (unused).
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
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 GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
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.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
static char buf[2048]
Header from Linux TUN interface.
TCP packet header.
static unsigned long long payload
How much data are we currently storing in the database?
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
Standard IPv6 header.
int af
AF_INET or AF_INET6.
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to &#39;struct&#39;s...
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
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:653
#define GNUNET_log(kind,...)
uint16_t payload_length
Length of the payload, excluding this header.
Header for all communications.
#define GNUNET_YES
Definition: gnunet_common.h:77
#define ETH_P_IPV4
Number for IPv4.
#define GNUNET_MESSAGE_TYPE_VPN_HELPER
Type of messages between the gnunet-vpn-helper and the daemon.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
#define gettext_noop(String)
Definition: gettext.h:69
static int ipv6
Option -6: IPv6 requested.
Definition: gnunet-vpn.c:66
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 1050 of file gnunet-daemon-exit.c.

References SocketAddress::address, SocketAddress::af, buf, 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, SocketAddress::ipv4, SocketAddress::ipv6, len, GNUNET_TUN_Layer2PacketHeader::proto, GNUNET_MessageHeader::size, and GNUNET_MessageHeader::type.

Referenced by handle_icmp_remote(), and handle_icmp_service().

1054 {
1055  size_t len;
1056  struct GNUNET_TUN_IcmpHeader *icmp;
1057 
1059  gettext_noop("# ICMP packets sent via TUN"),
1060  1, GNUNET_NO);
1062  "Sending packet with %u bytes ICMP payload via TUN\n",
1063  (unsigned int)payload_length);
1064  len = sizeof(struct GNUNET_MessageHeader) + sizeof(struct GNUNET_TUN_Layer2PacketHeader);
1065  switch (destination_address->af)
1066  {
1067  case AF_INET:
1068  len += sizeof(struct GNUNET_TUN_IPv4Header);
1069  break;
1070 
1071  case AF_INET6:
1072  len += sizeof(struct GNUNET_TUN_IPv6Header);
1073  break;
1074 
1075  default:
1076  GNUNET_break(0);
1077  return;
1078  }
1079  len += sizeof(struct GNUNET_TUN_IcmpHeader);
1080  len += payload_length;
1081  if (len >= GNUNET_MAX_MESSAGE_SIZE)
1082  {
1083  GNUNET_break(0);
1084  return;
1085  }
1086  {
1087  char buf[len] GNUNET_ALIGN;
1088  struct GNUNET_MessageHeader *hdr;
1089  struct GNUNET_TUN_Layer2PacketHeader *tun;
1090 
1091  hdr = (struct GNUNET_MessageHeader *)buf;
1092  hdr->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
1093  hdr->size = htons(len);
1094  tun = (struct GNUNET_TUN_Layer2PacketHeader*)&hdr[1];
1095  tun->flags = htons(0);
1096  switch (source_address->af)
1097  {
1098  case AF_INET:
1099  {
1100  struct GNUNET_TUN_IPv4Header * ipv4 = (struct GNUNET_TUN_IPv4Header*)&tun[1];
1101 
1102  tun->proto = htons(ETH_P_IPV4);
1104  IPPROTO_ICMP,
1105  sizeof(struct GNUNET_TUN_IcmpHeader) + payload_length,
1106  &source_address->address.ipv4,
1107  &destination_address->address.ipv4);
1108  icmp = (struct GNUNET_TUN_IcmpHeader*)&ipv4[1];
1109  }
1110  break;
1111 
1112  case AF_INET6:
1113  {
1114  struct GNUNET_TUN_IPv6Header * ipv6 = (struct GNUNET_TUN_IPv6Header*)&tun[1];
1115 
1116  tun->proto = htons(ETH_P_IPV6);
1118  IPPROTO_ICMPV6,
1119  sizeof(struct GNUNET_TUN_IcmpHeader) + payload_length,
1120  &source_address->address.ipv6,
1121  &destination_address->address.ipv6);
1122  icmp = (struct GNUNET_TUN_IcmpHeader*)&ipv6[1];
1123  }
1124  break;
1125 
1126  default:
1127  GNUNET_assert(0);
1128  break;
1129  }
1130  *icmp = *icmp_header;
1131  GNUNET_memcpy(&icmp[1],
1132  payload,
1133  payload_length);
1135  payload,
1136  payload_length);
1137  if (NULL != helper_handle)
1139  (const struct GNUNET_MessageHeader*)buf,
1140  GNUNET_YES,
1141  NULL, NULL);
1142  }
1143 }
static struct GNUNET_HELPER_Handle * helper_handle
The handle to the helper.
struct in6_addr ipv6
Address, if af is AF_INET6.
uint16_t proto
Here we get an ETH_P_-number.
union SocketAddress::@12 address
Remote address information.
static int ipv4
Option -4: IPv4 requested.
Definition: gnunet-vpn.c:61
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct in_addr ipv4
Address, if af is AF_INET.
#define ETH_P_IPV6
Number for IPv6.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_NO
Definition: gnunet_common.h:78
Standard IPv4 header.
uint16_t flags
Some flags (unused).
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
void GNUNET_TUN_initialize_ipv4_header(struct GNUNET_TUN_IPv4Header *ip, uint8_t protocol, uint16_t payload_length, const struct in_addr *src, const struct in_addr *dst)
Initialize an IPv4 header.
Definition: tun.c:46
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
static char buf[2048]
Header from Linux TUN interface.
void GNUNET_TUN_calculate_icmp_checksum(struct GNUNET_TUN_IcmpHeader *icmp, const void *payload, uint16_t payload_length)
Calculate ICMP checksum.
Definition: tun.c:260
static unsigned long long payload
How much data are we currently storing in the database?
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
Standard IPv6 header.
int af
AF_INET or AF_INET6.
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to &#39;struct&#39;s...
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
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:653
#define GNUNET_log(kind,...)
uint16_t payload_length
Length of the payload, excluding this header.
Header for all communications.
#define GNUNET_YES
Definition: gnunet_common.h:77
void GNUNET_TUN_initialize_ipv6_header(struct GNUNET_TUN_IPv6Header *ip, uint8_t protocol, uint16_t payload_length, const struct in6_addr *src, const struct in6_addr *dst)
Initialize an IPv6 header.
Definition: tun.c:81
#define ETH_P_IPV4
Number for IPv4.
#define GNUNET_MESSAGE_TYPE_VPN_HELPER
Type of messages between the gnunet-vpn-helper and the daemon.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
#define gettext_noop(String)
Definition: gettext.h:69
static int ipv6
Option -6: IPv6 requested.
Definition: gnunet-vpn.c:66
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 1155 of file gnunet-daemon-exit.c.

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, and SocketAddress::proto.

Referenced by setup_state_record().

1158 {
1159  local_address->af = af;
1160  local_address->proto = (uint8_t)proto;
1161  /* default "local" port range is often 32768--61000,
1162  so we pick a random value in that range */
1163  if (((af == AF_INET) && (proto == IPPROTO_ICMP)) ||
1164  ((af == AF_INET6) && (proto == IPPROTO_ICMPV6)))
1165  local_address->port = 0;
1166  else
1167  local_address->port
1169  28232);
1170  switch (af)
1171  {
1172  case AF_INET:
1173  {
1174  struct in_addr addr;
1175  struct in_addr mask;
1176  struct in_addr rnd;
1177 
1178  addr = exit_ipv4addr;
1179  mask = exit_ipv4mask;
1180  if (0 == ~mask.s_addr)
1181  {
1182  /* only one valid IP anyway */
1183  local_address->address.ipv4 = addr;
1184  return;
1185  }
1186  /* Given 192.168.0.1/255.255.0.0, we want a mask
1187  of '192.168.255.255', thus: */
1188  mask.s_addr = addr.s_addr | ~mask.s_addr;
1189  /* Pick random IPv4 address within the subnet, except 'addr' or 'mask' itself */
1190  do
1191  {
1193  UINT32_MAX);
1194  local_address->address.ipv4.s_addr = (addr.s_addr | rnd.s_addr) & mask.s_addr;
1195  }
1196  while ((local_address->address.ipv4.s_addr == addr.s_addr) ||
1197  (local_address->address.ipv4.s_addr == mask.s_addr));
1198  }
1199  break;
1200 
1201  case AF_INET6:
1202  {
1203  struct in6_addr addr;
1204  struct in6_addr mask;
1205  struct in6_addr rnd;
1206  int i;
1207 
1208  addr = exit_ipv6addr;
1209  GNUNET_assert(ipv6prefix < 128);
1210  if (ipv6prefix == 127)
1211  {
1212  /* only one valid IP anyway */
1213  local_address->address.ipv6 = addr;
1214  return;
1215  }
1216  /* Given ABCD::/96, we want a mask of 'ABCD::FFFF:FFFF,
1217  thus: */
1218  mask = addr;
1219  for (i = 127; i >= ipv6prefix; i--)
1220  mask.s6_addr[i / 8] |= (1 << (i % 8));
1221 
1222  /* Pick random IPv6 address within the subnet, except 'addr' or 'mask' itself */
1223  do
1224  {
1225  for (i = 0; i < 16; i++)
1226  {
1227  rnd.s6_addr[i] = (unsigned char)GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK,
1228  256);
1229  local_address->address.ipv6.s6_addr[i]
1230  = (addr.s6_addr[i] | rnd.s6_addr[i]) & mask.s6_addr[i];
1231  }
1232  }
1233  while ((0 == GNUNET_memcmp(&local_address->address.ipv6,
1234  &addr)) ||
1235  (0 == GNUNET_memcmp(&local_address->address.ipv6,
1236  &mask)));
1237  }
1238  break;
1239 
1240  default:
1241  GNUNET_assert(0);
1242  }
1243 }
static struct in_addr exit_ipv4mask
IPv4 netmask of our TUN interface.
struct in6_addr ipv6
Address, if af is AF_INET6.
static struct in6_addr exit_ipv6addr
IPv6 address of our TUN interface.
union SocketAddress::@12 address
Remote address information.
static uint8_t proto
Protocol to use.
Definition: gnunet-nat.c:60
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct in_addr ipv4
Address, if af is AF_INET.
static unsigned long long ipv6prefix
IPv6 prefix (0..127) from configuration file.
static struct in_addr exit_ipv4addr
IPv4 address of our TUN interface.
uint8_t proto
IPPROTO_TCP or IPPROTO_UDP;.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
int af
AF_INET or AF_INET6.
uint16_t port
Remote port, in host byte order!
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
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 1268 of file gnunet-daemon-exit.c.

References buf, ChannelState::channel, 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, 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().

1269 {
1270  struct GNUNET_HashCode key;
1271  struct ChannelState *s;
1272 
1273  /* generate fresh, unique address */
1274  do
1275  {
1276  if (NULL == state->specifics.tcp_udp.serv)
1277  setup_fresh_address(state->specifics.tcp_udp.ri.remote_address.af,
1278  state->specifics.tcp_udp.ri.remote_address.proto,
1279  &state->specifics.tcp_udp.ri.local_address);
1280  else
1281  setup_fresh_address(state->specifics.tcp_udp.serv->address.af,
1282  state->specifics.tcp_udp.serv->address.proto,
1283  &state->specifics.tcp_udp.ri.local_address);
1284  }
1285  while (NULL !=
1286  get_redirect_state(state->specifics.tcp_udp.ri.remote_address.af,
1287  state->specifics.tcp_udp.ri.remote_address.proto,
1288  &state->specifics.tcp_udp.ri.remote_address.address,
1289  state->specifics.tcp_udp.ri.remote_address.port,
1290  &state->specifics.tcp_udp.ri.local_address.address,
1291  state->specifics.tcp_udp.ri.local_address.port,
1292  &key));
1293  {
1294  char buf[INET6_ADDRSTRLEN];
1296  "Picked local address %s:%u for new connection\n",
1297  inet_ntop(state->specifics.tcp_udp.ri.local_address.af,
1298  &state->specifics.tcp_udp.ri.local_address.address,
1299  buf,
1300  sizeof(buf)),
1301  (unsigned int)state->specifics.tcp_udp.ri.local_address.port);
1302  }
1303  state->specifics.tcp_udp.state_key = key;
1306  &key, state,
1308  state->specifics.tcp_udp.heap_node
1310  state,
1311  GNUNET_TIME_absolute_get().abs_value_us);
1313  {
1315  GNUNET_assert(state != s);
1316  s->specifics.tcp_udp.heap_node = NULL;
1320  &s->specifics.tcp_udp.state_key,
1321  s));
1322  GNUNET_free(s);
1323  }
1324 }
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).
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.
static unsigned long long max_connections
If there are at least this many connections, old ones will be removed.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
static char buf[2048]
int GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
A 512-bit hashcode.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
struct GNUNET_CADET_Channel * channel
Cadet channel that is used for this connection.
unsigned int GNUNET_CONTAINER_heap_get_size(const struct GNUNET_CONTAINER_Heap *heap)
Get the current size of the heap.
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.
There must only be one value per key; storing a value should fail if a value under the same key alrea...
struct GNUNET_HashCode key
The key used in the DHT.
int GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
static struct GNUNET_CONTAINER_Heap * connections_heap
Heap so we can quickly find "old" connections.
#define GNUNET_log(kind,...)
void * GNUNET_CONTAINER_heap_remove_root(struct GNUNET_CONTAINER_Heap *heap)
Remove root of the heap.
union ChannelState::@13 specifics
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
static struct GNUNET_CONTAINER_MultiHashMap * connections_map
This hashmaps contains the mapping from peer, service-descriptor, source-port and destination-port to...
struct ChannelState::@13::@14 tcp_udp
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition: cadet_api.c:900
#define GNUNET_free(ptr)
Wrapper around free.
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 1336 of file gnunet-daemon-exit.c.

References SocketAddress::af, buf, 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, SocketAddress::ipv4, SocketAddress::ipv6, len, prepare_ipv4_packet(), prepare_ipv6_packet(), GNUNET_TUN_Layer2PacketHeader::proto, GNUNET_MessageHeader::size, and GNUNET_MessageHeader::type.

Referenced by handle_udp_remote(), and handle_udp_service().

1339 {
1340  size_t len;
1341 
1343  gettext_noop("# UDP packets sent via TUN"),
1344  1, GNUNET_NO);
1346  "Sending packet with %u bytes UDP payload via TUN\n",
1347  (unsigned int)payload_length);
1348  len = sizeof(struct GNUNET_MessageHeader) + sizeof(struct GNUNET_TUN_Layer2PacketHeader);
1349  switch (source_address->af)
1350  {
1351  case AF_INET:
1352  len += sizeof(struct GNUNET_TUN_IPv4Header);
1353  break;
1354 
1355  case AF_INET6:
1356  len += sizeof(struct GNUNET_TUN_IPv6Header);
1357  break;
1358 
1359  default:
1360  GNUNET_break(0);
1361  return;
1362  }
1363  len += sizeof(struct GNUNET_TUN_UdpHeader);
1364  len += payload_length;
1365  if (len >= GNUNET_MAX_MESSAGE_SIZE)
1366  {
1367  GNUNET_break(0);
1368  return;
1369  }
1370  {
1371  char buf[len] GNUNET_ALIGN;
1372  struct GNUNET_MessageHeader *hdr;
1373  struct GNUNET_TUN_Layer2PacketHeader *tun;
1374 
1375  hdr = (struct GNUNET_MessageHeader *)buf;
1376  hdr->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
1377  hdr->size = htons(len);
1378  tun = (struct GNUNET_TUN_Layer2PacketHeader*)&hdr[1];
1379  tun->flags = htons(0);
1380  switch (source_address->af)
1381  {
1382  case AF_INET:
1383  {
1384  struct GNUNET_TUN_IPv4Header * ipv4 = (struct GNUNET_TUN_IPv4Header*)&tun[1];
1385 
1386  tun->proto = htons(ETH_P_IPV4);
1388  payload_length,
1389  IPPROTO_UDP,
1390  NULL,
1391  source_address,
1392  destination_address,
1393  ipv4);
1394  }
1395  break;
1396 
1397  case AF_INET6:
1398  {
1399  struct GNUNET_TUN_IPv6Header * ipv6 = (struct GNUNET_TUN_IPv6Header*)&tun[1];
1400 
1401  tun->proto = htons(ETH_P_IPV6);
1404  IPPROTO_UDP,
1405  NULL,
1406  source_address,
1407  destination_address,
1408  ipv6);
1409  }
1410  break;
1411 
1412  default:
1413  GNUNET_assert(0);
1414  break;
1415  }
1416  if (NULL != helper_handle)
1418  (const struct GNUNET_MessageHeader*)buf,
1419  GNUNET_YES,
1420  NULL, NULL);
1421  }
1422 }
static struct GNUNET_HELPER_Handle * helper_handle
The handle to the helper.
uint16_t proto
Here we get an ETH_P_-number.
static int ipv4
Option -4: IPv4 requested.
Definition: gnunet-vpn.c:61
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
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.
UDP packet header.
#define ETH_P_IPV6
Number for IPv6.
#define GNUNET_NO
Definition: gnunet_common.h:78
Standard IPv4 header.
uint16_t flags
Some flags (unused).
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
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 GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
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.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
static char buf[2048]
Header from Linux TUN interface.
static unsigned long long payload
How much data are we currently storing in the database?
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
Standard IPv6 header.
int af
AF_INET or AF_INET6.
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to &#39;struct&#39;s...
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
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:653
#define GNUNET_log(kind,...)
uint16_t payload_length
Length of the payload, excluding this header.
Header for all communications.
#define GNUNET_YES
Definition: gnunet_common.h:77
#define ETH_P_IPV4
Number for IPv4.
#define GNUNET_MESSAGE_TYPE_VPN_HELPER
Type of messages between the gnunet-vpn-helper and the daemon.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
#define gettext_noop(String)
Definition: gettext.h:69
static int ipv6
Option -6: IPv6 requested.
Definition: gnunet-vpn.c:66
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 1434 of file gnunet-daemon-exit.c.

References GNUNET_break_op, GNUNET_OK, GNUNET_SYSERR, GNUNET_YES, ChannelState::is_dns, and state.

1436 {
1437  struct ChannelState *state = cls;
1438 
1439  if (GNUNET_YES == state->is_dns)
1440  {
1441  GNUNET_break_op(0);
1442  return GNUNET_SYSERR;
1443  }
1444  return GNUNET_OK;
1445 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
enum State state
current state of profiling
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
int is_dns
GNUNET_NO if this is a channel for TCP/UDP, GNUNET_YES if this is a channel for DNS, GNUNET_SYSERR if the channel is not yet initialized.
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
#define GNUNET_YES
Definition: gnunet_common.h:77

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

References SocketAddress::af, GNUNET_EXIT_UdpInternetMessage::af, buf, ChannelState::channel, GNUNET_EXIT_UdpInternetMessage::destination_port, gettext_noop, GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_SYSERR, GNUNET_EXIT_UdpInternetMessage::header, ipv4_exit, ipv6_exit, ChannelState::is_dns, payload, ChannelState::peer, send_udp_packet_via_tun(), setup_state_record(), GNUNET_MessageHeader::size, GNUNET_EXIT_UdpInternetMessage::source_port, ChannelState::specifics, state, and ChannelState::tcp_udp.

1457 {
1458  struct ChannelState *state = cls;
1459  uint16_t pkt_len = ntohs(msg->header.size) - sizeof(struct GNUNET_EXIT_UdpInternetMessage);
1460  const struct in_addr *v4;
1461  const struct in6_addr *v6;
1462  const void *payload;
1463  int af;
1464 
1465  if (GNUNET_SYSERR == state->is_dns)
1466  {
1467  /* channel is UDP/TCP from now on */
1468  state->is_dns = GNUNET_NO;
1469  }
1471  gettext_noop("# Bytes received from CADET"),
1472  pkt_len, GNUNET_NO);
1474  gettext_noop("# UDP IP-exit requests received via cadet"),
1475  1, GNUNET_NO);
1476  af = (int)ntohl(msg->af);
1477  state->specifics.tcp_udp.ri.remote_address.af = af;
1478  switch (af)
1479  {
1480  case AF_INET:
1481  if (pkt_len < sizeof(struct in_addr))
1482  {
1483  GNUNET_break_op(0);
1484  return;
1485  }
1486  if (!ipv4_exit)
1487  {
1488  GNUNET_break_op(0);
1489  return;
1490  }
1491  v4 = (const struct in_addr*)&msg[1];
1492  payload = &v4[1];
1493  pkt_len -= sizeof(struct in_addr);
1494  state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
1495  break;
1496 
1497  case AF_INET6:
1498  if (pkt_len < sizeof(struct in6_addr))
1499  {
1500  GNUNET_break_op(0);
1501  return;
1502  }
1503  if (!ipv6_exit)
1504  {
1505  GNUNET_break_op(0);
1506  return;
1507  }
1508  v6 = (const struct in6_addr*)&msg[1];
1509  payload = &v6[1];
1510  pkt_len -= sizeof(struct in6_addr);
1511  state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
1512  break;
1513 
1514  default:
1515  GNUNET_break_op(0);
1516  return;
1517  }
1518  {
1519  char buf[INET6_ADDRSTRLEN];
1521  "Received data from %s for forwarding to UDP %s:%u\n",
1522  GNUNET_i2s(&state->peer),
1523  inet_ntop(af,
1524  &state->specifics.tcp_udp.ri.remote_address.address,
1525  buf, sizeof(buf)),
1526  (unsigned int)ntohs(msg->destination_port));
1527  }
1528  state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_UDP;
1529  state->specifics.tcp_udp.ri.remote_address.port = msg->destination_port;
1530  if (NULL == state->specifics.tcp_udp.heap_node)
1531  setup_state_record(state);
1532  if (0 != ntohs(msg->source_port))
1533  state->specifics.tcp_udp.ri.local_address.port = msg->source_port;
1534  send_udp_packet_via_tun(&state->specifics.tcp_udp.ri.remote_address,
1535  &state->specifics.tcp_udp.ri.local_address,
1536  payload,
1537  pkt_len);
1539 }
#define GNUNET_NO
Definition: gnunet_common.h:78
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
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...
int32_t af
Address family, AF_INET or AF_INET6, in network byte order.
Definition: exit.h:150
enum State state
current state of profiling
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
uint16_t destination_port
Destination port to use for the UDP request.
Definition: exit.h:160
static char buf[2048]
struct GNUNET_CADET_Channel * channel
Cadet channel that is used for this connection.
static int ipv4_exit
Are we an IPv4-exit?
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static unsigned long long payload
How much data are we currently storing in the database?
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:951
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET.
Definition: exit.h:145
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
#define GNUNET_log(kind,...)
int is_dns
GNUNET_NO if this is a channel for TCP/UDP, GNUNET_YES if this is a channel for DNS, GNUNET_SYSERR if the channel is not yet initialized.
union ChannelState::@13 specifics
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
struct ChannelState::@13::@14 tcp_udp
uint16_t source_port
Source port to use for the UDP request (0 to use a random port).
Definition: exit.h:155
struct GNUNET_PeerIdentity peer
Who is the other end of this channel.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
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.
Message send via cadet to an exit daemon to forward UDP data to the Internet.
Definition: exit.h:141
#define gettext_noop(String)
Definition: gettext.h:69
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 1552 of file gnunet-daemon-exit.c.

References GNUNET_break_op, GNUNET_OK, GNUNET_SYSERR, ChannelState::specifics, state, and ChannelState::tcp_udp.

1554 {
1555  struct ChannelState *state = cls;
1556 
1557  if (NULL == state->specifics.tcp_udp.serv)
1558  {
1559  GNUNET_break_op(0);
1560  return GNUNET_SYSERR;
1561  }
1562  return GNUNET_OK;
1563 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
enum State state
current state of profiling
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
union ChannelState::@13 specifics
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
struct ChannelState::@13::@14 tcp_udp

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

References ChannelState::channel, GNUNET_EXIT_UdpServiceMessage::destination_port, gettext_noop, GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_i2s(), GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_EXIT_UdpServiceMessage::header, LOG, ChannelState::peer, send_udp_packet_via_tun(), setup_state_record(), GNUNET_MessageHeader::size, GNUNET_EXIT_UdpServiceMessage::source_port, ChannelState::specifics, state, and ChannelState::tcp_udp.

1576 {
1577  struct ChannelState *state = cls;
1578  uint16_t pkt_len = ntohs(msg->header.size) - sizeof(struct GNUNET_EXIT_UdpServiceMessage);
1579 
1581  gettext_noop("# Bytes received from CADET"),
1582  pkt_len, GNUNET_NO);
1584  gettext_noop("# UDP service requests received via cadet"),
1585  1, GNUNET_NO);
1587  "Received data from %s for forwarding to UDP service %s on port %u\n",
1588  GNUNET_i2s(&state->peer),
1589  GNUNET_h2s(&state->specifics.tcp_udp.serv->descriptor),
1590  (unsigned int)ntohs(msg->destination_port));
1591  setup_state_record(state);
1592  if (0 != ntohs(msg->source_port))
1593  state->specifics.tcp_udp.ri.local_address.port = msg->source_port;
1594  send_udp_packet_via_tun(&state->specifics.tcp_udp.ri.remote_address,
1595  &state->specifics.tcp_udp.ri.local_address,
1596  &msg[1],
1597  pkt_len);
1599 }
#define GNUNET_NO
Definition: gnunet_common.h:78
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE.
Definition: exit.h:121
#define LOG(kind,...)
Generic logging shorthand.
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...
enum State state
current state of profiling
struct GNUNET_CADET_Channel * channel
Cadet channel that is used for this connection.
Message send via cadet to an exit daemon to send UDP data to a local service.
Definition: exit.h:117
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:951
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
union ChannelState::@13 specifics
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
struct ChannelState::@13::@14 tcp_udp
struct GNUNET_PeerIdentity peer
Who is the other end of this channel.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
uint16_t source_port
Source port to use for the UDP request (0 to use a random port).
Definition: exit.h:126
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.
#define gettext_noop(String)
Definition: gettext.h:69
uint16_t destination_port
Destination port to use for the UDP request.
Definition: exit.h:131
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 1612 of file gnunet-daemon-exit.c.

References ChannelState::channel, GNUNET_TUN_TcpHeader::destination_port, 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, GNUNET_EXIT_TcpServiceStartMessage::header, ChannelState::is_dns, ChannelState::peer, GNUNET_EXIT_TcpServiceStartMessage::reserved, send_tcp_packet_via_tun(), setup_state_record(), GNUNET_MessageHeader::size, ChannelState::specifics, state, GNUNET_EXIT_TcpServiceStartMessage::tcp_header, and ChannelState::tcp_udp.

1614 {
1615  struct ChannelState *state = cls;
1616  uint16_t pkt_len = ntohs(start->header.size) - sizeof(struct GNUNET_EXIT_TcpServiceStartMessage);
1617 
1618  if (GNUNET_SYSERR == state->is_dns)
1619  {
1620  /* channel is UDP/TCP from now on */
1621  state->is_dns = GNUNET_NO;
1622  }
1624  gettext_noop("# TCP service creation requests received via cadet"),
1625  1,
1626  GNUNET_NO);
1628  gettext_noop("# Bytes received from CADET"),
1629  pkt_len,
1630  GNUNET_NO);
1631  GNUNET_break_op(ntohl(start->reserved) == 0);
1632  /* setup fresh connection */
1634  "Received data from %s for forwarding to TCP service %s on port %u\n",
1635  GNUNET_i2s(&state->peer),
1636  GNUNET_h2s(&state->specifics.tcp_udp.serv->descriptor),
1637  (unsigned int)ntohs(start->tcp_header.destination_port));
1638  setup_state_record(state);
1639  send_tcp_packet_via_tun(&state->specifics.tcp_udp.ri.remote_address,
1640  &state->specifics.tcp_udp.ri.local_address,
1641  &start->tcp_header,
1642  &start[1],
1643  pkt_len);
1645 }
#define GNUNET_NO
Definition: gnunet_common.h:78
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
struct GNUNET_TUN_TcpHeader tcp_header
Skeleton of the TCP header to send.
Definition: exit.h:52
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...
enum State state
current state of profiling
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
uint32_t reserved
Always 0.
Definition: exit.h:46
uint16_t destination_port
Destination port (in NBO).
struct GNUNET_CADET_Channel * channel
Cadet channel that is used for this connection.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
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:951
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
#define GNUNET_log(kind,...)
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.
int is_dns
GNUNET_NO if this is a channel for TCP/UDP, GNUNET_YES if this is a channel for DNS, GNUNET_SYSERR if the channel is not yet initialized.
union ChannelState::@13 specifics
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
struct ChannelState::@13::@14 tcp_udp
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START.
Definition: exit.h:41
Message send via cadet to an exit daemon to initiate forwarding of TCP data to a local service...
Definition: exit.h:37
struct GNUNET_PeerIdentity peer
Who is the other end of this channel.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define gettext_noop(String)
Definition: gettext.h:69
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 1657 of file gnunet-daemon-exit.c.

References GNUNET_break_op, GNUNET_OK, GNUNET_SYSERR, GNUNET_YES, ChannelState::is_dns, GNUNET_TUN_TcpHeader::off, ChannelState::specifics, state, GNUNET_EXIT_TcpInternetStartMessage::tcp_header, and ChannelState::tcp_udp.

1659 {
1660  struct ChannelState *state = cls;
1661 
1662  if (NULL == state)
1663  {
1664  GNUNET_break_op(0);
1665  return GNUNET_SYSERR;
1666  }
1667  if (GNUNET_YES == state->is_dns)
1668  {
1669  GNUNET_break_op(0);
1670  return GNUNET_SYSERR;
1671  }
1672  if ((NULL != state->specifics.tcp_udp.serv) ||
1673  (NULL != state->specifics.tcp_udp.heap_node))
1674  {
1675  GNUNET_break_op(0);
1676  return GNUNET_SYSERR;
1677  }
1678  if (start->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
1679  {
1680  GNUNET_break_op(0);
1681  return GNUNET_SYSERR;
1682  }
1683  return GNUNET_OK;
1684 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
enum State state
current state of profiling
struct GNUNET_TUN_TcpHeader tcp_header
Skeleton of the TCP header to send.
Definition: exit.h:77
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
TCP packet header.
int is_dns
GNUNET_NO if this is a channel for TCP/UDP, GNUNET_YES if this is a channel for DNS, GNUNET_SYSERR if the channel is not yet initialized.
union ChannelState::@13 specifics
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
#define GNUNET_YES
Definition: gnunet_common.h:77
unsigned int off
Number of 32-bit words in TCP header.
struct ChannelState::@13::@14 tcp_udp

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

References GNUNET_EXIT_TcpInternetStartMessage::af, SocketAddress::af, buf, ChannelState::channel, GNUNET_TUN_TcpHeader::destination_port, gettext_noop, GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_SYSERR, GNUNET_EXIT_TcpInternetStartMessage::header, ipv4_exit, ipv6_exit, ChannelState::is_dns, payload, ChannelState::peer, send_tcp_packet_via_tun(), setup_state_record(), GNUNET_MessageHeader::size, ChannelState::specifics, state, GNUNET_EXIT_TcpInternetStartMessage::tcp_header, and ChannelState::tcp_udp.

1696 {
1697  struct ChannelState *state = cls;
1698  uint16_t pkt_len = ntohs(start->header.size) - sizeof(struct GNUNET_EXIT_TcpInternetStartMessage);
1699  const struct in_addr *v4;
1700  const struct in6_addr *v6;
1701  const void *payload;
1702  int af;
1703 
1704  if (GNUNET_SYSERR == state->is_dns)
1705  {
1706  /* channel is UDP/TCP from now on */
1707  state->is_dns = GNUNET_NO;
1708  }
1710  gettext_noop("# Bytes received from CADET"),
1711  pkt_len, GNUNET_NO);
1713  gettext_noop("# TCP IP-exit creation requests received via cadet"),
1714  1, GNUNET_NO);
1715  af = (int)ntohl(start->af);
1716  state->specifics.tcp_udp.ri.remote_address.af = af;
1717  switch (af)
1718  {
1719  case AF_INET:
1720  if (pkt_len < sizeof(struct in_addr))
1721  {
1722  GNUNET_break_op(0);
1723  return;
1724  }
1725  if (!ipv4_exit)
1726  {
1727  GNUNET_break_op(0);
1728  return;
1729  }
1730  v4 = (const struct in_addr*)&start[1];
1731  payload = &v4[1];
1732  pkt_len -= sizeof(struct in_addr);
1733  state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
1734  break;
1735 
1736  case AF_INET6:
1737  if (pkt_len < sizeof(struct in6_addr))
1738  {
1739  GNUNET_break_op(0);
1740  return;
1741  }
1742  if (!ipv6_exit)
1743  {
1744  GNUNET_break_op(0);
1745  return;
1746  }
1747  v6 = (const struct in6_addr*)&start[1];
1748  payload = &v6[1];
1749  pkt_len -= sizeof(struct in6_addr);
1750  state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
1751  break;
1752 
1753  default:
1754  GNUNET_break_op(0);
1755  return;
1756  }
1757  {
1758  char buf[INET6_ADDRSTRLEN];
1760  "Received payload from %s for existing TCP stream to %s:%u\n",
1761  GNUNET_i2s(&state->peer),
1762  inet_ntop(af,
1763  &state->specifics.tcp_udp.ri.remote_address.address,
1764  buf, sizeof(buf)),
1765  (unsigned int)ntohs(start->tcp_header.destination_port));
1766  }
1767  state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_TCP;
1768  state->specifics.tcp_udp.ri.remote_address.port = ntohs(start->tcp_header.destination_port);
1769  setup_state_record(state);
1770  send_tcp_packet_via_tun(&state->specifics.tcp_udp.ri.remote_address,
1771  &state->specifics.tcp_udp.ri.local_address,
1772  &start->tcp_header,
1773  payload,
1774  pkt_len);
1776 }
#define GNUNET_NO
Definition: gnunet_common.h:78
int32_t af
Address family, AF_INET or AF_INET6, in network byte order.
Definition: exit.h:71
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
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...
enum State state
current state of profiling
struct GNUNET_TUN_TcpHeader tcp_header
Skeleton of the TCP header to send.
Definition: exit.h:77
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
static char buf[2048]
uint16_t destination_port
Destination port (in NBO).
struct GNUNET_CADET_Channel * channel
Cadet channel that is used for this connection.
static int ipv4_exit
Are we an IPv4-exit?
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static unsigned long long payload
How much data are we currently storing in the database?
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:951
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START.
Definition: exit.h:66
#define GNUNET_log(kind,...)
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 the Internet...
Definition: exit.h:62
int is_dns
GNUNET_NO if this is a channel for TCP/UDP, GNUNET_YES if this is a channel for DNS, GNUNET_SYSERR if the channel is not yet initialized.
union ChannelState::@13 specifics
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
struct ChannelState::@13::@14 tcp_udp
struct GNUNET_PeerIdentity peer
Who is the other end of this channel.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define gettext_noop(String)
Definition: gettext.h:69
Here is the call graph for this function:

◆ check_tcp_data()

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

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

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

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

References gettext_noop, GNUNET_break_op, GNUNET_NO, GNUNET_OK, GNUNET_STATISTICS_update(), GNUNET_SYSERR, GNUNET_YES, ChannelState::is_dns, GNUNET_TUN_TcpHeader::off, ChannelState::specifics, state, GNUNET_EXIT_TcpDataMessage::tcp_header, and ChannelState::tcp_udp.

1791 {
1792  struct ChannelState *state = cls;
1793 
1794  if ((NULL == state) ||
1795  (NULL == state->specifics.tcp_udp.heap_node))
1796  {
1797  /* connection should have been up! */
1799  gettext_noop("# TCP DATA requests dropped (no session)"),
1800  1, GNUNET_NO);
1801  GNUNET_break_op(0);
1802  return GNUNET_SYSERR;
1803  }
1804  if (data->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
1805  {
1806  GNUNET_break_op(0);
1807  return GNUNET_SYSERR;
1808  }
1809  if (GNUNET_YES == state->is_dns)
1810  {
1811  GNUNET_break_op(0);
1812  return GNUNET_SYSERR;
1813  }
1814  return GNUNET_OK;
1815 }
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
struct GNUNET_TUN_TcpHeader tcp_header
Skeleton of the TCP header to send.
Definition: exit.h:107
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
enum State state
current state of profiling
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
TCP packet header.
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
int is_dns
GNUNET_NO if this is a channel for TCP/UDP, GNUNET_YES if this is a channel for DNS, GNUNET_SYSERR if the channel is not yet initialized.
union ChannelState::@13 specifics
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
#define GNUNET_YES
Definition: gnunet_common.h:77
unsigned int off
Number of 32-bit words in TCP header.
struct ChannelState::@13::@14 tcp_udp
#define gettext_noop(String)
Definition: gettext.h:69
Here is the call graph for this function:

◆ handle_tcp_data()

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

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

Parameters
clsour struct ChannelState *
messagethe actual message

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

References buf, ChannelState::channel, gettext_noop, GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_SYSERR, GNUNET_EXIT_TcpDataMessage::header, ChannelState::is_dns, ChannelState::peer, GNUNET_EXIT_TcpDataMessage::reserved, send_tcp_packet_via_tun(), GNUNET_MessageHeader::size, ChannelState::specifics, state, GNUNET_EXIT_TcpDataMessage::tcp_header, and ChannelState::tcp_udp.

1828 {
1829  struct ChannelState *state = cls;
1830  uint16_t pkt_len = ntohs(data->header.size) - sizeof(struct GNUNET_EXIT_TcpDataMessage);
1831 
1833  gettext_noop("# Bytes received from CADET"),
1834  pkt_len, GNUNET_NO);
1836  gettext_noop("# TCP data requests received via cadet"),
1837  1, GNUNET_NO);
1838  if (GNUNET_SYSERR == state->is_dns)
1839  {
1840  /* channel is UDP/TCP from now on */
1841  state->is_dns = GNUNET_NO;
1842  }
1843 
1844  GNUNET_break_op(ntohl(data->reserved) == 0);
1845  {
1846  char buf[INET6_ADDRSTRLEN];
1848  "Received additional %u bytes of data from %s for TCP stream to %s:%u\n",
1849  pkt_len,
1850  GNUNET_i2s(&state->peer),
1851  inet_ntop(state->specifics.tcp_udp.ri.remote_address.af,
1852  &state->specifics.tcp_udp.ri.remote_address.address,
1853  buf, sizeof(buf)),
1854  (unsigned int)state->specifics.tcp_udp.ri.remote_address.port);
1855  }
1856 
1857  send_tcp_packet_via_tun(&state->specifics.tcp_udp.ri.remote_address,
1858  &state->specifics.tcp_udp.ri.local_address,
1859  &data->tcp_header,
1860  &data[1], pkt_len);
1862 }
#define GNUNET_NO
Definition: gnunet_common.h:78
struct GNUNET_TUN_TcpHeader tcp_header
Skeleton of the TCP header to send.
Definition: exit.h:107
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
enum State state
current state of profiling
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
static char buf[2048]
struct GNUNET_CADET_Channel * channel
Cadet channel that is used for this connection.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
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:951
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
#define GNUNET_log(kind,...)
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.
int is_dns
GNUNET_NO if this is a channel for TCP/UDP, GNUNET_YES if this is a channel for DNS, GNUNET_SYSERR if the channel is not yet initialized.
union ChannelState::@13 specifics
struct GNUNET_MessageHeader header
Type is #GNUNET_MESSAGE_TYPE_VPN_TCP_DATA.
Definition: exit.h:96
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
struct ChannelState::@13::@14 tcp_udp
struct GNUNET_PeerIdentity peer
Who is the other end of this channel.
Message send via cadet between VPN and entry and an exit daemon to transmit TCP data between the VPN ...
Definition: exit.h:92
uint32_t reserved
Always 0.
Definition: exit.h:101
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define gettext_noop(String)
Definition: gettext.h:69
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 1875 of file gnunet-daemon-exit.c.

References GNUNET_TUN_UdpHeader::crc, GNUNET_TUN_UdpHeader::destination_port, GNUNET_TUN_initialize_ipv4_header(), GNUNET_TUN_UdpHeader::len, GNUNET_TUN_UdpHeader::source_port, ChannelState::specifics, and ChannelState::tcp_udp.

Referenced by handle_icmp_remote(), and make_up_icmp_service_payload().

1878 {
1880  state->specifics.tcp_udp.ri.remote_address.proto,
1881  sizeof(struct GNUNET_TUN_TcpHeader),
1882  &state->specifics.tcp_udp.ri.remote_address.address.ipv4,
1883  &state->specifics.tcp_udp.ri.local_address.address.ipv4);
1884  udp->source_port = htons(state->specifics.tcp_udp.ri.remote_address.port);
1885  udp->destination_port = htons(state->specifics.tcp_udp.ri.local_address.port);
1886  udp->len = htons(0);
1887  udp->crc = htons(0);
1888 }
uint16_t destination_port
Destination port (in NBO).
uint16_t len
Number of bytes of payload.
void GNUNET_TUN_initialize_ipv4_header(struct GNUNET_TUN_IPv4Header *ip, uint8_t protocol, uint16_t payload_length, const struct in_addr *src, const struct in_addr *dst)
Initialize an IPv4 header.
Definition: tun.c:46
TCP packet header.
uint16_t crc
Checksum.
uint16_t source_port
Source port (in NBO).
union ChannelState::@13 specifics
struct ChannelState::@13::@14 tcp_udp
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 1901 of file gnunet-daemon-exit.c.

References GNUNET_TUN_UdpHeader::crc, GNUNET_TUN_UdpHeader::destination_port, GNUNET_TUN_initialize_ipv6_header(), GNUNET_TUN_UdpHeader::len, GNUNET_TUN_UdpHeader::source_port, ChannelState::specifics, and ChannelState::tcp_udp.

Referenced by handle_icmp_remote(), and make_up_icmp_service_payload().

1904 {
1906  state->specifics.tcp_udp.ri.remote_address.proto,
1907  sizeof(struct GNUNET_TUN_TcpHeader),
1908  &state->specifics.tcp_udp.ri.remote_address.address.ipv6,
1909  &state->specifics.tcp_udp.ri.local_address.address.ipv6);
1910  udp->source_port = htons(state->specifics.tcp_udp.ri.remote_address.port);
1911  udp->destination_port = htons(state->specifics.tcp_udp.ri.local_address.port);
1912  udp->len = htons(0);
1913  udp->crc = htons(0);
1914 }
uint16_t destination_port
Destination port (in NBO).
uint16_t len
Number of bytes of payload.
TCP packet header.
uint16_t crc
Checksum.
uint16_t source_port
Source port (in NBO).
union ChannelState::@13 specifics
struct ChannelState::@13::@14 tcp_udp
void GNUNET_TUN_initialize_ipv6_header(struct GNUNET_TUN_IPv6Header *ip, uint8_t protocol, uint16_t payload_length, const struct in6_addr *src, const struct in6_addr *dst)
Initialize an IPv6 header.
Definition: tun.c:81
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 1926 of file gnunet-daemon-exit.c.

References GNUNET_break_op, GNUNET_OK, GNUNET_SYSERR, GNUNET_YES, ChannelState::is_dns, and state.

1928 {
1929  struct ChannelState *state = cls;
1930 
1931  if (GNUNET_YES == state->is_dns)
1932  {
1933  GNUNET_break_op(0);
1934  return GNUNET_SYSERR;
1935  }
1936  return GNUNET_OK;
1937 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
enum State state
current state of profiling
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
int is_dns
GNUNET_NO if this is a channel for TCP/UDP, GNUNET_YES if this is a channel for DNS, GNUNET_SYSERR if the channel is not yet initialized.
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
#define GNUNET_YES
Definition: gnunet_common.h:77

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

References SocketAddress::af, GNUNET_EXIT_IcmpInternetMessage::af, buf, ChannelState::channel, gettext_noop, 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, GNUNET_EXIT_IcmpInternetMessage::header, GNUNET_EXIT_IcmpInternetMessage::icmp_header, ipv4_exit, ipv6_exit, ChannelState::is_dns, make_up_icmpv4_payload(), make_up_icmpv6_payload(), payload, ChannelState::peer, send_icmp_packet_via_tun(), setup_state_record(), GNUNET_MessageHeader::size, ChannelState::specifics, state, ChannelState::tcp_udp, GNUNET_TUN_IcmpHeader::type, and udp.

1949 {
1950  struct ChannelState *state = cls;
1951  uint16_t pkt_len = ntohs(msg->header.size) - sizeof(struct GNUNET_EXIT_IcmpInternetMessage);
1952  const struct in_addr *v4;
1953  const struct in6_addr *v6;
1954  const void *payload;
1955  char buf[sizeof(struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
1956  int af;
1957 
1958  if (GNUNET_SYSERR == state->is_dns)
1959  {
1960  /* channel is UDP/TCP from now on */
1961  state->is_dns = GNUNET_NO;
1962  }
1964  gettext_noop("# Bytes received from CADET"),
1965  pkt_len, GNUNET_NO);
1967  gettext_noop("# ICMP IP-exit requests received via cadet"),
1968  1, GNUNET_NO);
1969 
1970  af = (int)ntohl(msg->af);
1971  if ((NULL != state->specifics.tcp_udp.heap_node) &&
1972  (af != state->specifics.tcp_udp.ri.remote_address.af))
1973  {
1974  /* other peer switched AF on this channel; not allowed */
1975  GNUNET_break_op(0);
1976  return;
1977  }
1978 
1979  switch (af)
1980  {
1981  case AF_INET:
1982  if (pkt_len < sizeof(struct in_addr))
1983  {
1984  GNUNET_break_op(0);
1985  return;
1986  }
1987  if (!ipv4_exit)
1988  {
1989  GNUNET_break_op(0);
1990  return;
1991  }
1992  v4 = (const struct in_addr*)&msg[1];
1993  payload = &v4[1];
1994  pkt_len -= sizeof(struct in_addr);
1995  state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
1996  if (NULL == state->specifics.tcp_udp.heap_node)
1997  {
1998  state->specifics.tcp_udp.ri.remote_address.af = af;
1999  state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_ICMP;
2000  setup_state_record(state);
2001  }
2002  /* check that ICMP type is something we want to support
2003  and possibly make up payload! */
2004  switch (msg->icmp_header.type)
2005  {
2008  break;
2009 
2013  if (0 != pkt_len)
2014  {
2015  GNUNET_break_op(0);
2016  return;
2017  }
2018  /* make up payload */
2019  {
2020  struct GNUNET_TUN_IPv4Header *ipp = (struct GNUNET_TUN_IPv4Header *)buf;
2021  struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *)&ipp[1];
2022 
2023  GNUNET_assert(8 == sizeof(struct GNUNET_TUN_UdpHeader));
2024  pkt_len = sizeof(struct GNUNET_TUN_IPv4Header) + 8;
2025  make_up_icmpv4_payload(state,
2026  ipp,
2027  udp);
2028  payload = ipp;
2029  }
2030  break;
2031 
2032  default:
2033  GNUNET_break_op(0);
2035  gettext_noop("# ICMPv4 packets dropped (type not allowed)"),
2036  1, GNUNET_NO);
2037  return;
2038  }
2039  /* end AF_INET */
2040  break;
2041 
2042  case AF_INET6:
2043  if (pkt_len < sizeof(struct in6_addr))
2044  {
2045  GNUNET_break_op(0);
2046  return;
2047  }
2048  if (!ipv6_exit)
2049  {
2050  GNUNET_break_op(0);
2051  return;
2052  }
2053  v6 = (const struct in6_addr*)&msg[1];
2054  payload = &v6[1];
2055  pkt_len -= sizeof(struct in6_addr);
2056  state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
2057  if (NULL == state->specifics.tcp_udp.heap_node)
2058  {
2059  state->specifics.tcp_udp.ri.remote_address.af = af;
2060  state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_ICMPV6;
2061  setup_state_record(state);
2062  }
2063  /* check that ICMP type is something we want to support
2064  and possibly make up payload! */
2065  switch (msg->icmp_header.type)
2066  {
2069  break;
2070 
2075  if (0 != pkt_len)
2076  {
2077  GNUNET_break_op(0);
2078  return;
2079  }
2080  /* make up payload */
2081  {
2082  struct GNUNET_TUN_IPv6Header *ipp = (struct GNUNET_TUN_IPv6Header *)buf;
2083  struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *)&ipp[1];
2084 
2085  GNUNET_assert(8 == sizeof(struct GNUNET_TUN_UdpHeader));
2086  pkt_len = sizeof(struct GNUNET_TUN_IPv6Header) + 8;
2087  make_up_icmpv6_payload(state,
2088  ipp,
2089  udp);
2090  payload = ipp;
2091  }
2092  break;
2093 
2094  default:
2095  GNUNET_break_op(0);
2097  gettext_noop("# ICMPv6 packets dropped (type not allowed)"),
2098  1, GNUNET_NO);
2099  return;
2100  }
2101  /* end AF_INET6 */
2102  break;
2103 
2104  default:
2105  /* bad AF */
2106  GNUNET_break_op(0);
2107  return;
2108  }
2109 
2110  {
2111  char buf[INET6_ADDRSTRLEN];
2113  "Received ICMP data from %s for forwarding to %s\n",
2114  GNUNET_i2s(&state->peer),
2115  inet_ntop(af,
2116  &state->specifics.tcp_udp.ri.remote_address.address,
2117  buf, sizeof(buf)));
2118  }
2119  send_icmp_packet_via_tun(&state->specifics.tcp_udp.ri.remote_address,
2120  &state->specifics.tcp_udp.ri.local_address,
2121  &msg->icmp_header,
2122  payload, pkt_len);
2124 }
static int udp
Option -u: UDP requested.
Definition: gnunet-vpn.c:76
#define GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED
int32_t af
Address family, AF_INET or AF_INET6, in network byte order.
Definition: exit.h:241
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
UDP packet header.
#define GNUNET_NO
Definition: gnunet_common.h:78
Standard IPv4 header.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
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 GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH
static int ipv6_exit
Are we an IPv6-exit?
static void make_up_icmpv6_payload(struct ChannelState *state, struct GNUNET_TUN_IPv6Header *ipp, struct GNUNET_TUN_UdpHeader *udp)
Synthesize a plausible ICMP payload for an ICMPv6 error response on the given channel.
static void 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...
#define GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE
#define GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED
#define GNUNET_TUN_ICMPTYPE6_ECHO_REPLY
enum State state
current state of profiling
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG
Message send via cadet to an exit daemon to forward ICMP data to the Internet.
Definition: exit.h:229
static char buf[2048]
struct GNUNET_CADET_Channel * channel
Cadet channel that is used for this connection.
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 int ipv4_exit
Are we an IPv4-exit?
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
#define GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE
static unsigned long long payload
How much data are we currently storing in the database?
Standard IPv6 header.
#define GNUNET_TUN_ICMPTYPE_ECHO_REQUEST
#define GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM
#define GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST
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:951
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.
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to &#39;struct&#39;s...
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
#define GNUNET_log(kind,...)
int is_dns
GNUNET_NO if this is a channel for TCP/UDP, GNUNET_YES if this is a channel for DNS, GNUNET_SYSERR if the channel is not yet initialized.
union ChannelState::@13 specifics
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
struct ChannelState::@13::@14 tcp_udp
#define GNUNET_TUN_ICMPTYPE_ECHO_REPLY
struct GNUNET_PeerIdentity peer
Who is the other end of this channel.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
struct GNUNET_TUN_IcmpHeader icmp_header
ICMP header to use.
Definition: exit.h:247
#define gettext_noop(String)
Definition: gettext.h:69
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_INTERNET.
Definition: exit.h:233
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 2137 of file gnunet-daemon-exit.c.

References GNUNET_assert, GNUNET_break, SocketAddress::ipv4, SocketAddress::ipv6, make_up_icmpv4_payload(), make_up_icmpv6_payload(), ChannelState::specifics, ChannelState::tcp_udp, and udp.

Referenced by handle_icmp_service().

2139 {
2140  switch (state->specifics.tcp_udp.serv->address.af)
2141  {
2142  case AF_INET:
2143  {
2144  struct GNUNET_TUN_IPv4Header *ipv4;
2145  struct GNUNET_TUN_UdpHeader *udp;
2146 
2147  ipv4 = (struct GNUNET_TUN_IPv4Header *)buf;
2148  udp = (struct GNUNET_TUN_UdpHeader *)&ipv4[1];
2149  make_up_icmpv4_payload(state,
2150  ipv4,
2151  udp);
2152  GNUNET_assert(8 == sizeof(struct GNUNET_TUN_UdpHeader));
2153  return sizeof(struct GNUNET_TUN_IPv4Header) + 8;
2154  }
2155  break;
2156 
2157  case AF_INET6:
2158  {
2159  struct GNUNET_TUN_IPv6Header *ipv6;
2160  struct GNUNET_TUN_UdpHeader *udp;
2161 
2162  ipv6 = (struct GNUNET_TUN_IPv6Header *)buf;
2163  udp = (struct GNUNET_TUN_UdpHeader *)&ipv6[1];
2164  make_up_icmpv6_payload(state,
2165  ipv6,
2166  udp);
2167  GNUNET_assert(8 == sizeof(struct GNUNET_TUN_UdpHeader));
2168  return sizeof(struct GNUNET_TUN_IPv6Header) + 8;
2169  }
2170  break;
2171 
2172  default:
2173  GNUNET_break(0);
2174  }
2175  return 0;
2176 }
static int udp
Option -u: UDP requested.
Definition: gnunet-vpn.c:76
static int ipv4
Option -4: IPv4 requested.
Definition: gnunet-vpn.c:61
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
UDP packet header.
Standard IPv4 header.
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_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static char buf[2048]
Standard IPv6 header.
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.
union ChannelState::@13 specifics
struct ChannelState::@13::@14 tcp_udp
static int ipv6
Option -6: IPv6 requested.
Definition: gnunet-vpn.c:66
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 2189 of file gnunet-daemon-exit.c.

References GNUNET_break_op, GNUNET_OK, GNUNET_SYSERR, GNUNET_YES, ChannelState::is_dns, ChannelState::specifics, state, and ChannelState::tcp_udp.

2191 {
2192  struct ChannelState *state = cls;
2193 
2194  if (GNUNET_YES == state->is_dns)
2195  {
2196  GNUNET_break_op(0);
2197  return GNUNET_SYSERR;
2198  }
2199  if (NULL == state->specifics.tcp_udp.serv)
2200  {
2201  GNUNET_break_op(0);
2202  return GNUNET_SYSERR;
2203  }
2204  return GNUNET_OK;
2205 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
enum State state
current state of profiling
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
int is_dns
GNUNET_NO if this is a channel for TCP/UDP, GNUNET_YES if this is a channel for DNS, GNUNET_SYSERR if the channel is not yet initialized.
union ChannelState::@13 specifics
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
#define GNUNET_YES
Definition: gnunet_common.h:77
struct ChannelState::@13::@14 tcp_udp

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

References GNUNET_EXIT_IcmpServiceMessage::af, buf, ChannelState::channel, 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_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_IcmpServiceMessage::header, GNUNET_EXIT_IcmpServiceMessage::icmp_header, make_up_icmp_service_payload(), payload, ChannelState::peer, send_icmp_packet_via_tun(), setup_state_record(), GNUNET_MessageHeader::size, ChannelState::specifics, state, ChannelState::tcp_udp, and GNUNET_TUN_IcmpHeader::type.

2218 {
2219  struct ChannelState *state = cls;
2220  uint16_t pkt_len = ntohs(msg->header.size) - sizeof(struct GNUNET_EXIT_IcmpServiceMessage);
2221  struct GNUNET_TUN_IcmpHeader icmp;
2222  char buf[sizeof(struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
2223  const void *payload;
2224 
2226  gettext_noop("# Bytes received from CADET"),
2227  pkt_len, GNUNET_NO);
2229  gettext_noop("# ICMP service requests received via cadet"),
2230  1, GNUNET_NO);
2231  /* check that we got at least a valid header */
2233  "Received data from %s for forwarding to ICMP service %s\n",
2234  GNUNET_i2s(&state->peer),
2235  GNUNET_h2s(&state->specifics.tcp_udp.serv->descriptor));
2236  icmp = msg->icmp_header;
2237  payload = &msg[1];
2238  state->specifics.tcp_udp.ri.remote_address
2239  = state->specifics.tcp_udp.serv->address;
2240  setup_state_record(state);
2241 
2242  /* check that ICMP type is something we want to support,
2243  perform ICMP PT if needed ans possibly make up payload */
2244  switch (msg->af)
2245  {
2246  case AF_INET:
2247  switch (msg->icmp_header.type)
2248  {
2250  if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2251  icmp.type = GNUNET_TUN_ICMPTYPE6_ECHO_REPLY;
2252  break;
2253 
2255  if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2257  break;
2258 
2260  if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2262  if (0 != pkt_len)
2263  {
2264  GNUNET_break_op(0);
2265  return;
2266  }
2267  payload = buf;
2268  pkt_len = make_up_icmp_service_payload(state, buf);
2269  break;
2270 
2272  if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2274  if (0 != pkt_len)
2275  {
2276  GNUNET_break_op(0);
2277  return;
2278  }
2279  payload = buf;
2280  pkt_len = make_up_icmp_service_payload(state, buf);
2281  break;
2282 
2284  if (state->specifics.tcp_udp.serv->address.af == AF_INET6)
2285  {
2287  gettext_noop("# ICMPv4 packets dropped (impossible PT to v6)"),
2288  1, GNUNET_NO);
2289  return;
2290  }
2291  if (0 != pkt_len)
2292  {
2293  GNUNET_break_op(0);
2294  return;
2295  }
2296  payload = buf;
2297  pkt_len = make_up_icmp_service_payload(state, buf);
2298  break;
2299 
2300  default:
2301  GNUNET_break_op(0);
2303  gettext_noop("# ICMPv4 packets dropped (type not allowed)"),
2304  1, GNUNET_NO);
2305  return;
2306  }
2307  /* end of AF_INET */
2308  break;
2309 
2310  case AF_INET6:
2311  switch (msg->icmp_header.type)
2312  {
2314  if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2315  icmp.type = GNUNET_TUN_ICMPTYPE_ECHO_REPLY;
2316  break;
2317 
2319  if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2321  break;
2322 
2324  if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2326  if (0 != pkt_len)
2327  {
2328  GNUNET_break_op(0);
2329  return;
2330  }
2331  payload = buf;
2332  pkt_len = make_up_icmp_service_payload(state, buf);
2333  break;
2334 
2336  if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2338  if (0 != pkt_len)
2339  {
2340  GNUNET_break_op(0);
2341  return;
2342  }
2343  payload = buf;
2344  pkt_len = make_up_icmp_service_payload(state, buf);
2345  break;
2346 
2349  if (state->specifics.tcp_udp.serv->address.af == AF_INET)
2350  {
2352  gettext_noop("# ICMPv6 packets dropped (impossible PT to v4)"),
2353  1, GNUNET_NO);
2354  return;
2355  }
2356  if (0 != pkt_len)
2357  {
2358  GNUNET_break_op(0);
2359  return;
2360  }
2361  payload = buf;
2362  pkt_len = make_up_icmp_service_payload(state, buf);
2363  break;
2364 
2365  default:
2366  GNUNET_break_op(0);
2368  gettext_noop("# ICMPv6 packets dropped (type not allowed)"),
2369  1, GNUNET_NO);
2370  return;
2371  }
2372  /* end of AF_INET6 */
2373  break;
2374 
2375  default:
2376  GNUNET_break_op(0);
2377  return;
2378  }
2379 
2380  send_icmp_packet_via_tun(&state->specifics.tcp_udp.ri.remote_address,
2381  &state->specifics.tcp_udp.ri.local_address,
2382  &icmp,
2383  payload,
2384  pkt_len);
2386 }
static uint16_t make_up_icmp_service_payload(struct ChannelState *state, char *buf)
Setup ICMP payload for ICMP error messages.
#define GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED
#define GNUNET_NO
Definition: gnunet_common.h:78
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
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 GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH
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...
Message send via cadet to an exit daemon to send ICMP data to a local service.
Definition: exit.h:199
#define GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE
#define GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED
#define GNUNET_TUN_ICMPTYPE6_ECHO_REPLY
enum State state
current state of profiling
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG
static char buf[2048]
struct GNUNET_CADET_Channel * channel
Cadet channel that is used for this connection.
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.
#define GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE
static unsigned long long payload
How much data are we currently storing in the database?
Standard IPv6 header.
#define GNUNET_TUN_ICMPTYPE_ECHO_REQUEST
#define GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM
#define GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST
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:951
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to &#39;struct&#39;s...
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
#define GNUNET_log(kind,...)
int32_t af
Address family, AF_INET or AF_INET6, in network byte order.
Definition: exit.h:211
union ChannelState::@13 specifics
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
struct ChannelState::@13::@14 tcp_udp
#define GNUNET_TUN_ICMPTYPE_ECHO_REPLY
struct GNUNET_PeerIdentity peer
Who is the other end of this channel.
struct GNUNET_TUN_IcmpHeader icmp_header
ICMP header to use.
Definition: exit.h:216
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_SERVICE.
Definition: exit.h:203
#define gettext_noop(String)
Definition: gettext.h:69
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 2398 of file gnunet-daemon-exit.c.

References GNUNET_assert, GNUNET_CADET_close_port(), GNUNET_CONTAINER_multihashmap_remove(), GNUNET_free, GNUNET_free_non_null, GNUNET_OK, GNUNET_YES, LocalService::name, LocalService::port, service, and value.

Referenced by cleanup().

2401 {
2402  struct LocalService *service = value;
2403 
2406  key,
2407  service));
2408  GNUNET_CADET_close_port(service->port);
2409  GNUNET_free_non_null(service->name);
2410  GNUNET_free(service);
2411  return GNUNET_OK;
2412 }
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
char * name
DNS name of the service.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
This struct is saved into the services-hashmap to represent a service this peer is specifically offer...
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
struct GNUNET_CADET_Port * port
Open port with CADET.
static char * value
Value of the record to add/remove.
static struct GNUNET_CONTAINER_MultiHashMap * services
This hashmaps saves interesting things about the configured services.
int GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
void GNUNET_CADET_close_port(struct GNUNET_CADET_Port *p)
Close a port opened with GNUNET_CADET_open_port().
Definition: cadet_api.c:871
#define GNUNET_YES
Definition: gnunet_common.h:77
#define GNUNET_free(ptr)
Wrapper around free.
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 2424 of file gnunet-daemon-exit.c.

References LocalService::address, ChannelState::channel, gettext_noop, GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_new, GNUNET_NO, GNUNET_STATISTICS_update(), ls, ChannelState::peer, ChannelState::specifics, and ChannelState::tcp_udp.

Referenced by store_service().

2427 {
2428  struct LocalService *ls = cls;
2429  struct ChannelState *s = GNUNET_new(struct ChannelState);
2430 
2431  s->peer = *initiator;
2433  gettext_noop("# Inbound CADET channels created"),
2434  1,
2435  GNUNET_NO);
2437  "Received inbound channel from `%s'\n",
2438  GNUNET_i2s(initiator));
2439  s->channel = channel;
2440  s->specifics.tcp_udp.serv = ls;
2441  s->specifics.tcp_udp.ri.remote_address = ls->address;
2442  return s;
2443 }
This struct is saved into the services-hashmap to represent a service this peer is specifically offer...
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_new(type)
Allocate a struct or union of the given type.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
struct GNUNET_CADET_Channel * channel
Cadet channel that is used for this connection.
struct SocketAddress address
Remote address to use for the service.
static struct GNUNET_NETWORK_Handle * ls
Listen socket for STUN processing.
Definition: gnunet-nat.c:85
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
#define GNUNET_log(kind,...)
union ChannelState::@13 specifics
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
struct ChannelState::@13::@14 tcp_udp
struct GNUNET_PeerIdentity peer
Who is the other end of this channel.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define gettext_noop(String)
Definition: gettext.h:69
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 2454 of file gnunet-daemon-exit.c.

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

2456 {
2457  struct ChannelState *s = cls;
2458 
2460  "Channel destroyed\n");
2461  if (GNUNET_SYSERR == s->is_dns)
2462  {
2463  GNUNET_free(s);
2464  return;
2465  }
2466  if (GNUNET_YES == s->is_dns)
2467  {
2468  if (channels[s->specifics.dns.my_id] == s)
2469  channels[s->specifics.dns.my_id] = NULL;
2470  }
2471  else
2472  {
2473  if (NULL != s->specifics.tcp_udp.heap_node)
2474  {
2477  &s->specifics.tcp_udp.state_key,
2478  s));
2480  s->specifics.tcp_udp.heap_node = NULL;
2481  }
2482  }
2483  GNUNET_free(s);
2484 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct ChannelState::@13::@15 dns
#define LOG(kind,...)
Generic logging shorthand.
int GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
int is_dns
GNUNET_NO if this is a channel for TCP/UDP, GNUNET_YES if this is a channel for DNS, GNUNET_SYSERR if the channel is not yet initialized.
union ChannelState::@13 specifics
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
#define GNUNET_YES
Definition: gnunet_common.h:77
static struct GNUNET_CONTAINER_MultiHashMap * connections_map
This hashmaps contains the mapping from peer, service-descriptor, source-port and destination-port to...
static struct ChannelState * channels[UINT16_MAX+1]
Array of all open DNS requests from channels.
struct ChannelState::@13::@14 tcp_udp
void * GNUNET_CONTAINER_heap_remove_node(struct GNUNET_CONTAINER_HeapNode *node)
Removes a node from the heap.
#define GNUNET_free(ptr)
Wrapper around free.
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 2497 of file gnunet-daemon-exit.c.

References _, clean_channel(), LocalService::descriptor, 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_free_non_null, 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(), LocalService::is_udp, LocalService::name, new_service_channel(), LocalService::port, and SocketAddress::proto.

Referenced by add_services().

2501 {
2502  struct GNUNET_MQ_MessageHandler handlers[] = {
2503  GNUNET_MQ_hd_var_size(icmp_service,
2506  service),
2507  GNUNET_MQ_hd_var_size(udp_service,
2510  service),
2511  GNUNET_MQ_hd_var_size(tcp_service,
2514  service),
2515  GNUNET_MQ_hd_var_size(tcp_data,
2518  service),
2520  };
2521 
2522  struct GNUNET_HashCode cadet_port;
2523 
2524  service->name = GNUNET_strdup(name);
2526  &service->descriptor);
2528  destination_port,
2529  &cadet_port);
2531  "Opening CADET port %s for SERVICE exit %s on port %u\n",
2533  name,
2534  (unsigned int)destination_port);
2536  &cadet_port,
2538  service,
2539  NULL,
2540  &clean_channel,
2541  handlers);
2542  service->is_udp = (IPPROTO_UDP == proto);
2543  if (GNUNET_OK !=
2545  &cadet_port,
2546  service,
2548  {
2549  GNUNET_CADET_close_port(service->port);
2550  GNUNET_free_non_null(service->name);
2551  GNUNET_free(service);
2553  _("Got duplicate service records for `%s:%u'\n"),
2554  name,
2555  (unsigned int)destination_port);
2556  }
2557 }
static struct GNUNET_CADET_Handle * cadet_handle
The handle to cadet.
char * name
DNS name of the service.
#define GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_SERVICE
Type of messages containing an ICMP packet for a service.
static uint8_t proto
Protocol to use.
Definition: gnunet-nat.c:60
#define GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE
Type of messages containing an UDP 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_OK
Named constants for return values.
Definition: gnunet_common.h:75
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
struct GNUNET_CADET_Port * port
Open port with CADET.
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
#define GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT
Type of messages containing an TCP packet of an established connection.
Message send via cadet to an exit daemon to send ICMP data to a local service.
Definition: exit.h:199
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 incomming MQ-based channels.
Definition: cadet_api.c:1007
static struct GNUNET_CADET_MessageHandler handlers[]
Handlers, for diverse services.
static struct GNUNET_CONTAINER_MultiHashMap * services
This hashmaps saves interesting things about the configured services.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
int16_t is_udp
GNUNET_YES if this is a UDP service, otherwise TCP.
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:812
static void * new_service_channel(void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *initiator)
Callback from CADET for new channels.
A 512-bit hashcode.
Message handler for a specific message type.
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:831
There must only be one value per key; storing a value should fail if a value under the same key alrea...
const char * name
int GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
Message send via cadet to an exit daemon to send UDP data to a local service.
Definition: exit.h:117
struct GNUNET_HashCode descriptor
Descriptor for the service (CADET port).
#define GNUNET_log(kind,...)
static struct GNUNET_CADET_Port * cadet_port
Listen port for incoming requests.
void GNUNET_CADET_close_port(struct GNUNET_CADET_Port *p)
Close a port opened with GNUNET_CADET_open_port().
Definition: cadet_api.c:871
Message send via cadet to an exit daemon to initiate forwarding of TCP data to a local service...
Definition: exit.h:37
Message send via cadet between VPN and entry and an exit daemon to transmit TCP data between the VPN ...
Definition: exit.h:92
static void clean_channel(void *cls, const struct GNUNET_CADET_Channel *channel)
Function called by cadet whenever an inbound channel is destroyed.
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_free(ptr)
Wrapper around free.
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 2567 of file gnunet-daemon-exit.c.

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

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

2569 {
2570  GNUNET_assert(NULL != s);
2572  gettext_noop("# Messages transmitted via cadet channels"),
2573  1,
2574  GNUNET_NO);
2576  env);
2577 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_NO
Definition: gnunet_common.h:78
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
struct GNUNET_CADET_Channel * channel
Cadet channel that is used for this connection.
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
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:351
#define gettext_noop(String)
Definition: gettext.h:69
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:1116
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 2592 of file gnunet-daemon-exit.c.

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, SocketAddress::ipv4, SocketAddress::ipv6, GNUNET_TUN_IPv6Header::next_header, GNUNET_TUN_IPv4Header::protocol, send_packet_to_cadet_channel(), GNUNET_TUN_UdpHeader::source_port, state, GNUNET_TUN_IcmpHeader::type, and udp.

Referenced by message_token().

2597 {
2598  struct ChannelState *state;
2599  struct GNUNET_MQ_Envelope *env;
2600  struct GNUNET_EXIT_IcmpToVPNMessage *i2v;
2601  const struct GNUNET_TUN_IPv4Header *ipv4;
2602  const struct GNUNET_TUN_IPv6Header *ipv6;
2603  const struct GNUNET_TUN_UdpHeader *udp;
2604  uint16_t source_port;
2605  uint16_t destination_port;
2606  uint8_t protocol;
2607 
2608  {
2609  char sbuf[INET6_ADDRSTRLEN];
2610  char dbuf[INET6_ADDRSTRLEN];
2612  "Received ICMP packet going from %s to %s\n",
2613  inet_ntop(af,
2614  source_ip,
2615  sbuf, sizeof(sbuf)),
2616  inet_ntop(af,
2617  destination_ip,
2618  dbuf, sizeof(dbuf)));
2619  }
2620 
2621  if (pktlen < sizeof(struct GNUNET_TUN_IcmpHeader))
2622  {
2623  /* blame kernel */
2624  GNUNET_break(0);
2625  return;
2626  }
2627 
2628  /* Find out if this is an ICMP packet in response to an existing
2629  TCP/UDP packet and if so, figure out ports / protocol of the
2630  existing session from the IP data in the ICMP payload */
2631  source_port = 0;
2632  destination_port = 0;
2633  switch (af)
2634  {
2635  case AF_INET:
2636  protocol = IPPROTO_ICMP;
2637  switch (icmp->type)
2638  {
2641  break;
2642 
2646  if (pktlen <
2647  sizeof(struct GNUNET_TUN_IcmpHeader) +
2648  sizeof(struct GNUNET_TUN_IPv4Header) + 8)
2649  {
2650  /* blame kernel */
2651  GNUNET_break(0);
2652  return;
2653  }
2654  ipv4 = (const struct GNUNET_TUN_IPv4Header *)&icmp[1];
2655  protocol = ipv4->protocol;
2656  /* could be TCP or UDP, but both have the ports in the right
2657  place, so that doesn't matter here */
2658  udp = (const struct GNUNET_TUN_UdpHeader *)&ipv4[1];
2659  /* swap ports, as they are from the original message */
2660  destination_port = ntohs(udp->source_port);
2661  source_port = ntohs(udp->destination_port);
2662  /* throw away ICMP payload, won't be useful for the other side anyway */
2663  pktlen = sizeof(struct GNUNET_TUN_IcmpHeader);
2664  break;
2665 
2666  default:
2668  gettext_noop("# ICMPv4 packets dropped (type not allowed)"),
2669  1, GNUNET_NO);
2670  return;
2671  }
2672  break;
2673 
2674  case AF_INET6:
2675  protocol = IPPROTO_ICMPV6;
2676  switch (icmp->type)
2677  {
2682  if (pktlen <
2683  sizeof(struct GNUNET_TUN_IcmpHeader) +
2684  sizeof(struct GNUNET_TUN_IPv6Header) + 8)
2685  {
2686  /* blame kernel */
2687  GNUNET_break(0);
2688  return;
2689  }
2690  ipv6 = (const struct GNUNET_TUN_IPv6Header *)&icmp[1];
2691  protocol = ipv6->next_header;
2692  /* could be TCP or UDP, but both have the ports in the right
2693  place, so that doesn't matter here */
2694  udp = (const struct GNUNET_TUN_UdpHeader *)&ipv6[1];
2695  /* swap ports, as they are from the original message */
2696  destination_port = ntohs(udp->source_port);
2697  source_port = ntohs(udp->destination_port);
2698  /* throw away ICMP payload, won't be useful for the other side anyway */
2699  pktlen = sizeof(struct GNUNET_TUN_IcmpHeader);
2700  break;
2701 
2704  break;
2705 
2706  default:
2708  gettext_noop("# ICMPv6 packets dropped (type not allowed)"),
2709  1, GNUNET_NO);
2710  return;
2711  }
2712  break;
2713 
2714  default:
2715  GNUNET_assert(0);
2716  }
2717  switch (protocol)
2718  {
2719  case IPPROTO_ICMP:
2720  state = get_redirect_state(af,
2721  IPPROTO_ICMP,
2722  source_ip,
2723  0,
2724  destination_ip,
2725  0,
2726  NULL);
2727  break;
2728 
2729  case IPPROTO_ICMPV6:
2730  state = get_redirect_state(af,
2731  IPPROTO_ICMPV6,
2732  source_ip,
2733  0,
2734  destination_ip,
2735  0,
2736  NULL);
2737  break;
2738 
2739  case IPPROTO_UDP:
2740  state = get_redirect_state(af,
2741  IPPROTO_UDP,
2742  source_ip,
2743  source_port,
2744  destination_ip,
2745  destination_port,
2746  NULL);
2747  break;
2748 
2749  case IPPROTO_TCP:
2750  state = get_redirect_state(af,
2751  IPPROTO_TCP,
2752  source_ip,
2753  source_port,
2754  destination_ip,
2755  destination_port,
2756  NULL);
2757  break;
2758 
2759  default:
2761  gettext_noop("# ICMP packets dropped (not allowed)"),
2762  1,
2763  GNUNET_NO);
2764  return;
2765  }
2766  if (NULL == state)
2767  {
2769  _("ICMP Packet dropped, have no matching connection information\n"));
2770  return;
2771  }
2772  env = GNUNET_MQ_msg_extra(i2v,
2773  pktlen - sizeof(struct GNUNET_TUN_IcmpHeader),
2775  i2v->af = htonl(af);
2776  GNUNET_memcpy(&i2v->icmp_header,
2777  icmp,
2778  pktlen);
2780  env);
2781 }
static int udp
Option -u: UDP requested.
Definition: gnunet-vpn.c:76
#define GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED
static int ipv4
Option -4: IPv4 requested.
Definition: gnunet-vpn.c:61
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
UDP packet header.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
struct GNUNET_TUN_IcmpHeader icmp_header
ICMP header to use.
Definition: exit.h:278
#define GNUNET_NO
Definition: gnunet_common.h:78
Standard IPv4 header.
uint16_t destination_port
Destination port (in NBO).
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 GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
#define GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE
#define GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
#define GNUNET_TUN_ICMPTYPE6_ECHO_REPLY
enum State state
current state of profiling
#define GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG
int32_t af
Address family, AF_INET or AF_INET6, in network byte order.
Definition: exit.h:273
uint8_t next_header
For example, IPPROTO_UDP or IPPROTO_TCP.
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.
#define GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
Message send via cadet to the vpn service to send ICMP data to the VPN&#39;s TUN interface.
Definition: exit.h:263
Standard IPv6 header.
#define GNUNET_TUN_ICMPTYPE_ECHO_REQUEST
#define GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM
uint8_t protocol
L4-protocol, for example, IPPROTO_UDP or IPPROTO_TCP.
uint16_t source_port
Source port (in NBO).
static void send_packet_to_cadet_channel(struct ChannelState *s, struct GNUNET_MQ_Envelope *env)
Send the given packet via the cadet channel.
#define GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST
#define GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_VPN
Type of messages containing an ICMP packet for the VPN.
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
#define GNUNET_log(kind,...)
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
#define GNUNET_TUN_ICMPTYPE_ECHO_REPLY
#define gettext_noop(String)
Definition: gettext.h:69
static int ipv6
Option -6: IPv6 requested.
Definition: gnunet-vpn.c:66
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 2796 of file gnunet-daemon-exit.c.

References _, GNUNET_EXIT_UdpReplyMessage::destination_port, GNUNET_TUN_UdpHeader::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, GNUNET_TUN_UdpHeader::len, send_packet_to_cadet_channel(), GNUNET_EXIT_UdpReplyMessage::source_port, GNUNET_TUN_UdpHeader::source_port, and state.

Referenced by message_token().

2801 {
2802  struct ChannelState *state;
2803  struct GNUNET_MQ_Envelope *env;
2804  struct GNUNET_EXIT_UdpReplyMessage *urm;
2805 
2806  {
2807  char sbuf[INET6_ADDRSTRLEN];
2808  char dbuf[INET6_ADDRSTRLEN];
2809 
2811  "Received UDP packet going from %s:%u to %s:%u\n",
2812  inet_ntop(af,
2813  source_ip,
2814  sbuf, sizeof(sbuf)),
2815  (unsigned int)ntohs(udp->source_port),
2816  inet_ntop(af,
2817  destination_ip,
2818  dbuf, sizeof(dbuf)),
2819  (unsigned int)ntohs(udp->destination_port));
2820  }
2821 
2822  if (pktlen < sizeof(struct GNUNET_TUN_UdpHeader))
2823  {
2824  /* blame kernel */
2825  GNUNET_break(0);
2826  return;
2827  }
2828  if (pktlen != ntohs(udp->len))
2829  {
2830  /* blame kernel */
2831  GNUNET_break(0);
2832  return;
2833  }
2834  state = get_redirect_state(af,
2835  IPPROTO_UDP,
2836  source_ip,
2837  ntohs(udp->source_port),
2838  destination_ip,
2839  ntohs(udp->destination_port),
2840  NULL);
2841  if (NULL == state)
2842  {
2844  _("UDP Packet dropped, have no matching connection information\n"));
2845  return;
2846  }
2847  env = GNUNET_MQ_msg_extra(urm,
2848  pktlen - sizeof(struct GNUNET_TUN_UdpHeader),
2850  urm->source_port = htons(0);
2851  urm->destination_port = htons(0);
2852  GNUNET_memcpy(&urm[1],
2853  &udp[1],
2854  pktlen - sizeof(struct GNUNET_TUN_UdpHeader));
2856  env);
2857 }
UDP packet header.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
uint16_t destination_port
Destination port (in NBO).
uint16_t len
Number of bytes of payload.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
enum State state
current state of profiling
#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:173
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:183
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.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
uint16_t source_port
Source port (in NBO).
static void send_packet_to_cadet_channel(struct ChannelState *s, struct GNUNET_MQ_Envelope *env)
Send the given packet via the cadet channel.
#define GNUNET_log(kind,...)
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:189
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
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 2872 of file gnunet-daemon-exit.c.

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, and GNUNET_EXIT_TcpDataMessage::tcp_header.

Referenced by message_token().

2877 {
2878  struct ChannelState *state;
2879  char buf[pktlen] GNUNET_ALIGN;
2880  struct GNUNET_TUN_TcpHeader *mtcp;
2881  struct GNUNET_EXIT_TcpDataMessage *tdm;
2882  struct GNUNET_MQ_Envelope *env;
2883  size_t mlen;
2884 
2885  {
2886  char sbuf[INET6_ADDRSTRLEN];
2887  char dbuf[INET6_ADDRSTRLEN];
2889  "Received TCP packet with %u bytes going from %s:%u to %s:%u\n",
2890  (unsigned int)(pktlen - sizeof(struct GNUNET_TUN_TcpHeader)),
2891  inet_ntop(af,
2892  source_ip,
2893  sbuf, sizeof(sbuf)),
2894  (unsigned int)ntohs(tcp->source_port),
2895  inet_ntop(af,
2896  destination_ip,
2897  dbuf, sizeof(dbuf)),
2898  (unsigned int)ntohs(tcp->destination_port));
2899  }
2900 
2901  if (pktlen < sizeof(struct GNUNET_TUN_TcpHeader))
2902  {
2903  /* blame kernel */
2904  GNUNET_break(0);
2905  return;
2906  }
2907  state = get_redirect_state(af,
2908  IPPROTO_TCP,
2909  source_ip,
2910  ntohs(tcp->source_port),
2911  destination_ip,
2912  ntohs(tcp->destination_port),
2913  NULL);
2914  if (NULL == state)
2915  {
2917  _("TCP Packet dropped, have no matching connection information\n"));
2918 
2919  return;
2920  }
2921  /* mug port numbers and crc to avoid information leakage;
2922  sender will need to lookup the correct values anyway */
2923  GNUNET_memcpy(buf, tcp, pktlen);
2924  mtcp = (struct GNUNET_TUN_TcpHeader *)buf;
2925  mtcp->source_port = 0;
2926  mtcp->destination_port = 0;
2927  mtcp->crc = 0;
2928 
2929  mlen = sizeof(struct GNUNET_EXIT_TcpDataMessage) + (pktlen - sizeof(struct GNUNET_TUN_TcpHeader));
2930  if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
2931  {
2932  GNUNET_break(0);
2933  return;
2934  }
2935  env = GNUNET_MQ_msg_extra(tdm,
2936  pktlen - sizeof(struct GNUNET_TUN_TcpHeader),
2938  tdm->reserved = htonl(0);
2939  GNUNET_memcpy(&tdm->tcp_header,
2940  buf,
2941  pktlen);
2943  env);
2944 }
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
struct GNUNET_TUN_TcpHeader tcp_header
Skeleton of the TCP header to send.
Definition: exit.h:107
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
enum State state
current state of profiling
#define GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_VPN
Type of messages containing an TCP packet of an established connection.
static char buf[2048]
uint16_t destination_port
Destination port (in NBO).
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.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
TCP packet header.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
static void send_packet_to_cadet_channel(struct ChannelState *s, struct GNUNET_MQ_Envelope *env)
Send the given packet via the cadet channel.
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to &#39;struct&#39;s...
uint16_t source_port
Source port (in NBO).
#define GNUNET_log(kind,...)
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
Message send via cadet between VPN and entry and an exit daemon to transmit TCP data between the VPN ...
Definition: exit.h:92
uint32_t reserved
Always 0.
Definition: exit.h:101
uint16_t crc
Checksum.
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 2954 of file gnunet-daemon-exit.c.

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, size, GNUNET_MessageHeader::size, tcp_from_helper(), GNUNET_TUN_IPv4Header::total_length, GNUNET_MessageHeader::type, and udp_from_helper().

Referenced by run().

2956 {
2957  const struct GNUNET_TUN_Layer2PacketHeader *pkt_tun;
2958  size_t size;
2959 
2961  "Got %u-byte message of type %u from gnunet-helper-exit\n",
2962  ntohs(message->size),
2963  ntohs(message->type));
2965  gettext_noop("# Packets received from TUN"),
2966  1, GNUNET_NO);
2967  if (ntohs(message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER)
2968  {
2969  GNUNET_break(0);
2970  return GNUNET_OK;
2971  }
2972  size = ntohs(message->size);
2973  if (size < sizeof(struct GNUNET_TUN_Layer2PacketHeader) + sizeof(struct GNUNET_MessageHeader))
2974  {
2975  GNUNET_break(0);
2976  return GNUNET_OK;
2977  }
2979  gettext_noop("# Bytes received from TUN"),
2980  size, GNUNET_NO);
2981  pkt_tun = (const struct GNUNET_TUN_Layer2PacketHeader *)&message[1];
2982  size -= sizeof(struct GNUNET_TUN_Layer2PacketHeader) + sizeof(struct GNUNET_MessageHeader);
2983  switch (ntohs(pkt_tun->proto))
2984  {
2985  case ETH_P_IPV4:
2986  {
2987  const struct GNUNET_TUN_IPv4Header *pkt4;
2988 
2989  if (size < sizeof(struct GNUNET_TUN_IPv4Header))
2990  {
2991  /* Kernel to blame? */
2992  GNUNET_break(0);
2993  return GNUNET_OK;
2994  }
2995  pkt4 = (const struct GNUNET_TUN_IPv4Header *)&pkt_tun[1];
2996  if (size != ntohs(pkt4->total_length))
2997  {
2998  /* Kernel to blame? */
2999  GNUNET_break(0);
3000  return GNUNET_OK;
3001  }
3002  if (pkt4->header_length * 4 != sizeof(struct GNUNET_TUN_IPv4Header))
3003  {
3005  _("IPv4 packet options received. Ignored.\n"));
3006  return GNUNET_OK;
3007  }
3008 
3009  size -= sizeof(struct GNUNET_TUN_IPv4Header);
3010  switch (pkt4->protocol)
3011  {
3012  case IPPROTO_UDP:
3013  udp_from_helper((const struct GNUNET_TUN_UdpHeader *)&pkt4[1], size,
3014  AF_INET,
3015  &pkt4->destination_address,
3016  &pkt4->source_address);
3017  break;
3018 
3019  case IPPROTO_TCP:
3020  tcp_from_helper((const struct GNUNET_TUN_TcpHeader *)&pkt4[1], size,
3021  AF_INET,
3022  &pkt4->destination_address,
3023  &pkt4->source_address);
3024  break;
3025 
3026  case IPPROTO_ICMP:
3027  icmp_from_helper((const struct GNUNET_TUN_IcmpHeader *)&pkt4[1], size,
3028  AF_INET,
3029  &pkt4->destination_address,
3030  &pkt4->source_address);
3031  break;
3032 
3033  default:
3035  _("IPv4 packet with unsupported next header %u received. Ignored.\n"),
3036  (int)pkt4->protocol);
3037  return GNUNET_OK;
3038  }
3039  }
3040  break;
3041 
3042  case ETH_P_IPV6:
3043  {
3044  const struct GNUNET_TUN_IPv6Header *pkt6;
3045 
3046  if (size < sizeof(struct GNUNET_TUN_IPv6Header))
3047  {
3048  /* Kernel to blame? */
3049  GNUNET_break(0);
3050  return GNUNET_OK;
3051  }
3052  pkt6 = (struct GNUNET_TUN_IPv6Header *)&pkt_tun[1];
3053  if (size != ntohs(pkt6->payload_length) + sizeof(struct GNUNET_TUN_IPv6Header))
3054  {
3055  /* Kernel to blame? */
3056  GNUNET_break(0);
3057  return GNUNET_OK;
3058  }
3059  size -= sizeof(struct GNUNET_TUN_IPv6Header);
3060  switch (pkt6->next_header)
3061  {
3062  case IPPROTO_UDP:
3063  udp_from_helper((const struct GNUNET_TUN_UdpHeader *)&pkt6[1], size,
3064  AF_INET6,
3065  &pkt6->destination_address,
3066  &pkt6->source_address);
3067  break;
3068 
3069  case IPPROTO_TCP:
3070  tcp_from_helper((const struct GNUNET_TUN_TcpHeader *)&pkt6[1], size,
3071  AF_INET6,
3072  &pkt6->destination_address,
3073  &pkt6->source_address);
3074  break;
3075 
3076  case IPPROTO_ICMPV6:
3077  icmp_from_helper((const struct GNUNET_TUN_IcmpHeader *)&pkt6[1], size,
3078  AF_INET6,
3079  &pkt6->destination_address,
3080  &pkt6->source_address);
3081  break;
3082 
3083  default:
3085  _("IPv6 packet with unsupported next header %d received. Ignored.\n"),
3086  pkt6->next_header);
3087  return GNUNET_OK;
3088  }
3089  }
3090  break;
3091 
3092  default:
3094  _("Packet from unknown protocol %u received. Ignored.\n"),
3095  ntohs(pkt_tun->proto));
3096  break;
3097  }
3098  return GNUNET_OK;
3099 }
unsigned int header_length
uint16_t proto
Here we get an ETH_P_-number.
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.
UDP packet header.
#define ETH_P_IPV6
Number for IPv6.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
Standard IPv4 header.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
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.
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 GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
Header from Linux TUN interface.
uint8_t next_header
For example, IPPROTO_UDP or IPPROTO_TCP.
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 unsigned int size
Size of the "table".
Definition: peer.c:66
TCP packet header.
Standard IPv6 header.
uint8_t protocol
L4-protocol, for example, IPPROTO_UDP or IPPROTO_TCP.
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
#define GNUNET_log(kind,...)
uint16_t payload_length
Length of the payload, excluding this header.
Header for all communications.
uint16_t total_length
Length of the packet, including this header.
#define ETH_P_IPV4
Number for IPv4.
#define GNUNET_MESSAGE_TYPE_VPN_HELPER
Type of messages between the gnunet-vpn-helper and the daemon.
#define gettext_noop(String)
Definition: gettext.h:69
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 
)