GNUnet 0.21.1
gnunet-daemon-exit.c File Reference

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

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

Go to the source code of this file.

Data Structures

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

Macros

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

Functions

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

Variables

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

Detailed Description

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

Author
Philipp Toelke
Christian Grothoff

TODO:

  • test

Design:

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

Definition in file gnunet-daemon-exit.c.

Macro Definition Documentation

◆ REGEX_MAX_PATH_LEN_IPV4

#define REGEX_MAX_PATH_LEN_IPV4   4

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

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

◆ REGEX_MAX_PATH_LEN_IPV6

#define REGEX_MAX_PATH_LEN_IPV6   8

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

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

◆ REGEX_REFRESH_FREQUENCY

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

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

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

◆ DHT_PUT_FREQUENCY

#define DHT_PUT_FREQUENCY
Value:

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

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

◆ DNS_ADVERTISEMENT_TIMEOUT

#define DNS_ADVERTISEMENT_TIMEOUT
Value:
#define GNUNET_TIME_UNIT_HOURS
One hour.

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

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

◆ LOG

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

Generic logging shorthand.

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

Function Documentation

◆ process_dns_result()

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

Callback called from DNSSTUB resolver when a resolution succeeded.

Parameters
clsNULL
dnsthe response itself
rnumber of bytes in dns

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

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

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

Referenced by handle_dns_request().

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

◆ check_dns_request()

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

Check a request via cadet to perform a DNS query.

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

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

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

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

◆ handle_dns_request()

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

Process a request via cadet to perform a DNS query.

Parameters
clsour struct ChannelState *
msgthe actual message

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

525{
526 struct ChannelState *ts = cls;
527 size_t mlen = ntohs (msg->header.size);
528 size_t dlen = mlen - sizeof(struct GNUNET_MessageHeader);
529 char buf[dlen] GNUNET_ALIGN;
530 struct GNUNET_TUN_DnsHeader *dns_out;
531
532 if (GNUNET_SYSERR == ts->is_dns)
533 {
534 /* channel is DNS from now on */
535 ts->is_dns = GNUNET_YES;
536 }
537 ts->specifics.dns.original_id = msg->dns.id;
538 if (channels[ts->specifics.dns.my_id] == ts)
539 channels[ts->specifics.dns.my_id] = NULL;
542 UINT16_MAX
543 + 1);
544 channels[ts->specifics.dns.my_id] = ts;
545 GNUNET_memcpy (buf,
546 &msg->dns,
547 dlen);
548 dns_out = (struct GNUNET_TUN_DnsHeader *) buf;
549 dns_out->id = ts->specifics.dns.my_id;
551 buf,
552 dlen,
554 NULL);
555 if (NULL == ts->specifics.dns.rs)
556 {
557 GNUNET_break_op (0);
558 return;
559 }
561}
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static GNUNET_NETWORK_STRUCT_END void process_dns_result(void *cls, const struct GNUNET_TUN_DnsHeader *dns, size_t r)
Callback called from DNSSTUB resolver when a resolution succeeded.
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Indicate readiness to receive the next message on a channel.
Definition: cadet_api.c:872
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
struct GNUNET_DNSSTUB_RequestSocket * GNUNET_DNSSTUB_resolve(struct GNUNET_DNSSTUB_Context *ctx, const void *request, size_t request_len, GNUNET_DNSSTUB_ResultCallback rc, void *rc_cls)
Perform DNS resolution using our default IP from init.
Definition: dnsstub.c:526
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to 'struct's.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
@ GNUNET_YES
uint16_t my_id
DNS request ID that we used for forwarding.
struct GNUNET_DNSSTUB_RequestSocket * rs
Socket we are using to transmit this request (must match if we receive a response).
Header for all communications.

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

Here is the call graph for this function:

◆ hash_redirect_info()

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

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

Parameters
hashresulting hash
riinformation about the connection

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

574{
575 char *off;
576
577 memset (hash,
578 0,
579 sizeof(struct GNUNET_HashCode));
580 /* the GNUnet hashmap only uses the first sizeof(unsigned int) of the hash,
581 so we put the IP address in there (and hope for few collisions) */
582 off = (char *) hash;
583 switch (ri->remote_address.af)
584 {
585 case AF_INET:
586 GNUNET_memcpy (off,
588 sizeof(struct in_addr));
589 off += sizeof(struct in_addr);
590 break;
591
592 case AF_INET6:
593 GNUNET_memcpy (off,
595 sizeof(struct in6_addr));
596 off += sizeof(struct in_addr);
597 break;
598
599 default:
600 GNUNET_assert (0);
601 }
602 GNUNET_memcpy (off,
603 &ri->remote_address.port,
604 sizeof(uint16_t));
605 off += sizeof(uint16_t);
606 switch (ri->local_address.af)
607 {
608 case AF_INET:
609 GNUNET_memcpy (off,
611 sizeof(struct in_addr));
612 off += sizeof(struct in_addr);
613 break;
614
615 case AF_INET6:
616 GNUNET_memcpy (off,
618 sizeof(struct in6_addr));
619 off += sizeof(struct in_addr);
620 break;
621
622 default:
623 GNUNET_assert (0);
624 }
625 GNUNET_memcpy (off,
626 &ri->local_address.port,
627 sizeof(uint16_t));
628 off += sizeof(uint16_t);
629 GNUNET_memcpy (off,
631 sizeof(uint8_t));
632 /* off += sizeof (uint8_t); */
633}
A 512-bit hashcode.
struct SocketAddress local_address
Address information we used locally (AF and proto must match "remote_address").
struct SocketAddress remote_address
Address information for the other party (equivalent of the arguments one would give to "connect").
int af
AF_INET or AF_INET6.
union SocketAddress::@45 address
Remote address information.
uint8_t proto
IPPROTO_TCP or IPPROTO_UDP;.
struct in_addr ipv4
Address, if af is AF_INET.
uint16_t port
Remote port, in host byte order!
struct in6_addr ipv6
Address, if af is AF_INET6.

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

Referenced by get_redirect_state().

Here is the caller graph for this function:

◆ get_redirect_state()

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

Get our connection tracking state.

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

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

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

657{
658 struct RedirectInformation ri;
659 struct GNUNET_HashCode key;
660 struct ChannelState *state;
661
662 if (((af == AF_INET) && (protocol == IPPROTO_ICMP)) ||
663 ((af == AF_INET6) && (protocol == IPPROTO_ICMPV6)))
664 {
665 /* ignore ports */
667 local_port = 0;
668 }
670 if (af == AF_INET)
671 ri.remote_address.address.ipv4 = *((struct in_addr*) destination_ip);
672 else
673 ri.remote_address.address.ipv6 = *((struct in6_addr*) destination_ip);
674 ri.remote_address.port = destination_port;
675 ri.remote_address.proto = protocol;
676 ri.local_address.af = af;
677 if (af == AF_INET)
678 ri.local_address.address.ipv4 = *((struct in_addr*) local_ip);
679 else
680 ri.local_address.address.ipv6 = *((struct in6_addr*) local_ip);
681 ri.local_address.port = local_port;
682 ri.local_address.proto = protocol;
684 &ri);
685 if (NULL != state_key)
686 *state_key = key;
688 &key);
689 if (NULL == state)
690 return NULL;
691 /* Mark this connection as freshly used */
692 if (NULL == state_key)
693 GNUNET_CONTAINER_heap_update_cost (state->specifics.tcp_udp.heap_node,
694 GNUNET_TIME_absolute_get ().abs_value_us);
695 return state;
696}
static struct GNUNET_CONTAINER_MultiHashMap * connections_map
This hashmaps contains the mapping from peer, service-descriptor, source-port and destination-port to...
static void hash_redirect_info(struct GNUNET_HashCode *hash, const struct RedirectInformation *ri)
Given IP information about a connection, calculate the respective hash we would use for the connectio...
struct GNUNET_HashCode key
The key used in the DHT.
enum State state
current state of profiling
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
void GNUNET_CONTAINER_heap_update_cost(struct GNUNET_CONTAINER_HeapNode *node, GNUNET_CONTAINER_HeapCostType new_cost)
Updates the cost of any node in the tree.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:111
int af
Address family used for this channel on the local TUN interface.
uint8_t protocol
IPPROTO_TCP or IPPROTO_UDP once bound.
uint16_t destination_port
Destination port used by the sender on our end; 0 for uninitialized.
struct RedirectInformation ri
Primary redirection information for this connection.
Information we use to track a connection (the classical 6-tuple of IP-version, protocol,...

References SocketAddress::address, SocketAddress::af, ChannelState::af, connections_map, ChannelState::destination_port, GNUNET_CONTAINER_heap_update_cost(), GNUNET_CONTAINER_multihashmap_get(), GNUNET_TIME_absolute_get(), hash_redirect_info(), SocketAddress::ipv4, SocketAddress::ipv6, key, RedirectInformation::local_address, SocketAddress::port, SocketAddress::proto, ChannelState::protocol, RedirectInformation::remote_address, ChannelState::ri, and state.

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

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

◆ check_tcp_service()

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

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

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

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

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

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

◆ prepare_ipv4_packet()

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

Prepare an IPv4 packet for transmission via the TUN interface.

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

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

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

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

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

Referenced by send_tcp_packet_via_tun(), and send_udp_packet_via_tun().

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

◆ prepare_ipv6_packet()

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

Prepare an IPv6 packet for transmission via the TUN interface.

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

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

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

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

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

Referenced by send_tcp_packet_via_tun(), and send_udp_packet_via_tun().

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

◆ send_tcp_packet_via_tun()

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

Send a TCP packet via the TUN interface.

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

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

964{
965 size_t len;
966
968 gettext_noop ("# TCP packets sent via TUN"),
969 1,
970 GNUNET_NO);
972 "Sending packet with %u bytes TCP payload via TUN\n",
973 (unsigned int) payload_length);
974 len = sizeof(struct GNUNET_MessageHeader) + sizeof(struct
976 switch (source_address->af)
977 {
978 case AF_INET:
979 len += sizeof(struct GNUNET_TUN_IPv4Header);
980 break;
981
982 case AF_INET6:
983 len += sizeof(struct GNUNET_TUN_IPv6Header);
984 break;
985
986 default:
987 GNUNET_break (0);
988 return;
989 }
990 len += sizeof(struct GNUNET_TUN_TcpHeader);
991 len += payload_length;
992 if (len >= GNUNET_MAX_MESSAGE_SIZE)
993 {
994 GNUNET_break (0);
995 return;
996 }
997 {
998 char buf[len] GNUNET_ALIGN;
999 struct GNUNET_MessageHeader *hdr;
1001
1002 hdr = (struct GNUNET_MessageHeader *) buf;
1003 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1004 hdr->size = htons (len);
1005 tun = (struct GNUNET_TUN_Layer2PacketHeader*) &hdr[1];
1006 tun->flags = htons (0);
1007 switch (source_address->af)
1008 {
1009 case AF_INET:
1010 {
1012 = (struct GNUNET_TUN_IPv4Header*) &tun[1];
1013
1014 tun->proto = htons (ETH_P_IPV4);
1016 payload_length,
1017 IPPROTO_TCP,
1018 tcp_header,
1021 ipv4);
1022 }
1023 break;
1024
1025 case AF_INET6:
1026 {
1028 = (struct GNUNET_TUN_IPv6Header*) &tun[1];
1029
1030 tun->proto = htons (ETH_P_IPV6);
1033 IPPROTO_TCP,
1034 tcp_header,
1037 ipv6);
1038 }
1039 break;
1040
1041 default:
1042 GNUNET_assert (0);
1043 break;
1044 }
1045 if (NULL != helper_handle)
1047 (const struct GNUNET_MessageHeader*) buf,
1048 GNUNET_YES,
1049 NULL,
1050 NULL);
1051 }
1052}
#define gettext_noop(String)
Definition: gettext.h:70
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
static void prepare_ipv6_packet(const void *payload, size_t payload_length, int protocol, const struct GNUNET_TUN_TcpHeader *tcp_header, const struct SocketAddress *src_address, const struct SocketAddress *dst_address, struct GNUNET_TUN_IPv6Header *pkt6)
Prepare an IPv6 packet for transmission via the TUN interface.
static void prepare_ipv4_packet(const void *payload, size_t payload_length, int protocol, const struct GNUNET_TUN_TcpHeader *tcp_header, const struct SocketAddress *src_address, const struct SocketAddress *dst_address, struct GNUNET_TUN_IPv4Header *pkt4)
Prepare an IPv4 packet for transmission via the TUN interface.
static struct GNUNET_HELPER_Handle * helper_handle
The handle to the helper.
static int ipv4
Option -4: IPv4 requested.
Definition: gnunet-vpn.c:60
static int ipv6
Option -6: IPv6 requested.
Definition: gnunet-vpn.c:65
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
struct GNUNET_HELPER_SendHandle * GNUNET_HELPER_send(struct GNUNET_HELPER_Handle *h, const struct GNUNET_MessageHeader *msg, bool can_drop, GNUNET_HELPER_Continuation cont, void *cont_cls)
Send an message to the helper.
Definition: helper.c:613
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_MESSAGE_TYPE_VPN_HELPER
Type of messages between the gnunet-vpn-helper and the daemon.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
#define ETH_P_IPV6
Number for IPv6.
#define ETH_P_IPV4
Number for IPv4.
struct in_addr source_address
Origin of the packet.
struct in_addr destination_address
Destination of the packet.
Standard IPv6 header.
struct in6_addr source_address
Origin of the packet.
struct in6_addr destination_address
Destination of the packet.
uint16_t payload_length
Length of the payload, excluding this header.
Header from Linux TUN interface.
uint16_t proto
Here we get an ETH_P_-number.
uint16_t flags
Some flags (unused).

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

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

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

◆ send_icmp_packet_via_tun()

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

Send an ICMP packet via the TUN interface.

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

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

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

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

Referenced by handle_icmp_remote(), and handle_icmp_service().

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

◆ setup_fresh_address()

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

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

Fill one in.

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

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

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

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

Referenced by setup_state_record().

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

◆ setup_state_record()

static void setup_state_record ( struct ChannelState state)
static

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

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

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

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

1293{
1294 struct GNUNET_HashCode key;
1295 struct ChannelState *s;
1296
1297 /* generate fresh, unique address */
1298 do
1299 {
1300 if (NULL == state->specifics.tcp_udp.serv)
1301 setup_fresh_address (state->specifics.tcp_udp.ri.remote_address.af,
1302 state->specifics.tcp_udp.ri.remote_address.proto,
1303 &state->specifics.tcp_udp.ri.local_address);
1304 else
1305 setup_fresh_address (state->specifics.tcp_udp.serv->address.af,
1306 state->specifics.tcp_udp.serv->address.proto,
1307 &state->specifics.tcp_udp.ri.local_address);
1308 }
1309 while (NULL !=
1310 get_redirect_state (state->specifics.tcp_udp.ri.remote_address.af,
1311 state->specifics.tcp_udp.ri.remote_address.proto,
1312 &state->specifics.tcp_udp.ri.remote_address.address,
1313 state->specifics.tcp_udp.ri.remote_address.port,
1314 &state->specifics.tcp_udp.ri.local_address.address,
1315 state->specifics.tcp_udp.ri.local_address.port,
1316 &key));
1317 {
1318 char buf[INET6_ADDRSTRLEN];
1320 "Picked local address %s:%u for new connection\n",
1321 inet_ntop (state->specifics.tcp_udp.ri.local_address.af,
1322 &state->specifics.tcp_udp.ri.local_address.address,
1323 buf,
1324 sizeof(buf)),
1325 (unsigned int) state->specifics.tcp_udp.ri.local_address.port);
1326 }
1327 state->specifics.tcp_udp.state_key = key;
1330 &key, state,
1332 state->specifics.tcp_udp.heap_node
1334 state,
1335 GNUNET_TIME_absolute_get ().abs_value_us);
1337 {
1339 GNUNET_assert (state != s);
1340 s->specifics.tcp_udp.heap_node = NULL;
1344 &s->specifics.tcp_udp.
1345 state_key,
1346 s));
1347 GNUNET_free (s);
1348 }
1349}
static struct ChannelState * get_redirect_state(int af, int protocol, const void *destination_ip, uint16_t destination_port, const void *local_ip, uint16_t local_port, struct GNUNET_HashCode *state_key)
Get our connection tracking state.
static void setup_fresh_address(int af, uint8_t proto, struct SocketAddress *local_address)
We need to create a (unique) fresh local address (IP+port).
static unsigned long long max_connections
If there are at least this many connections, old ones will be removed.
static struct GNUNET_CONTAINER_Heap * connections_heap
Heap so we can quickly find "old" connections.
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition: cadet_api.c:830
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
There must only be one value per key; storing a value should fail if a value under the same key alrea...
void * GNUNET_CONTAINER_heap_remove_root(struct GNUNET_CONTAINER_Heap *heap)
Remove root of the heap.
struct GNUNET_CONTAINER_HeapNode * GNUNET_CONTAINER_heap_insert(struct GNUNET_CONTAINER_Heap *heap, void *element, GNUNET_CONTAINER_HeapCostType cost)
Inserts a new element into the heap.
unsigned int GNUNET_CONTAINER_heap_get_size(const struct GNUNET_CONTAINER_Heap *heap)
Get the current size of the heap.
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_HashCode state_key
Key this state has in the connections_map.
struct ChannelState::@46::@47 tcp_udp
struct GNUNET_CONTAINER_HeapNode * heap_node
Heap node for this state in the connections_heap.

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

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

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

◆ send_udp_packet_via_tun()

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

Send a UDP packet via the TUN interface.

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

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

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

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

Referenced by handle_udp_remote(), and handle_udp_service().

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

◆ check_udp_remote()

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

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

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

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

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

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

◆ handle_udp_remote()

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

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

Parameters
clsour struct ChannelState *
msgthe actual message

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

1485{
1486 struct ChannelState *state = cls;
1487 uint16_t pkt_len = ntohs (msg->header.size) - sizeof(struct
1489 const struct in_addr *v4;
1490 const struct in6_addr *v6;
1491 const void *payload;
1492 int af;
1493
1494 if (GNUNET_SYSERR == state->is_dns)
1495 {
1496 /* channel is UDP/TCP from now on */
1497 state->is_dns = GNUNET_NO;
1498 }
1500 gettext_noop ("# Bytes received from CADET"),
1501 pkt_len, GNUNET_NO);
1503 gettext_noop (
1504 "# UDP IP-exit requests received via cadet"),
1505 1, GNUNET_NO);
1506 af = (int) ntohl (msg->af);
1507 state->specifics.tcp_udp.ri.remote_address.af = af;
1508 switch (af)
1509 {
1510 case AF_INET:
1511 if (pkt_len < sizeof(struct in_addr))
1512 {
1513 GNUNET_break_op (0);
1514 return;
1515 }
1516 if (! ipv4_exit)
1517 {
1518 GNUNET_break_op (0);
1519 return;
1520 }
1521 v4 = (const struct in_addr*) &msg[1];
1522 payload = &v4[1];
1523 pkt_len -= sizeof(struct in_addr);
1524 state->specifics.tcp_udp.ri.remote_address.address.ipv4 = *v4;
1525 break;
1526
1527 case AF_INET6:
1528 if (pkt_len < sizeof(struct in6_addr))
1529 {
1530 GNUNET_break_op (0);
1531 return;
1532 }
1533 if (! ipv6_exit)
1534 {
1535 GNUNET_break_op (0);
1536 return;
1537 }
1538 v6 = (const struct in6_addr*) &msg[1];
1539 payload = &v6[1];
1540 pkt_len -= sizeof(struct in6_addr);
1541 state->specifics.tcp_udp.ri.remote_address.address.ipv6 = *v6;
1542 break;
1543
1544 default:
1545 GNUNET_break_op (0);
1546 return;
1547 }
1548 {
1549 char buf[INET6_ADDRSTRLEN];
1551 "Received data from %s for forwarding to UDP %s:%u\n",
1552 GNUNET_i2s (&state->peer),
1553 inet_ntop (af,
1554 &state->specifics.tcp_udp.ri.remote_address.address,
1555 buf, sizeof(buf)),
1556 (unsigned int) ntohs (msg->destination_port));
1557 }
1558 state->specifics.tcp_udp.ri.remote_address.proto = IPPROTO_UDP;
1559 state->specifics.tcp_udp.ri.remote_address.port = msg->destination_port;
1560 if (NULL == state->specifics.tcp_udp.heap_node)
1562 if (0 != ntohs (msg->source_port))
1563 state->specifics.tcp_udp.ri.local_address.port = msg->source_port;
1564 send_udp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1565 &state->specifics.tcp_udp.ri.local_address,
1566 payload,
1567 pkt_len);
1569}
static void send_udp_packet_via_tun(const struct SocketAddress *destination_address, const struct SocketAddress *source_address, const void *payload, size_t payload_length)
Send a UDP packet via the TUN interface.
static int ipv6_exit
Are we an IPv6-exit?
static void setup_state_record(struct ChannelState *state)
We are starting a fresh connection (TCP or UDP) and need to pick a source port and IP address (within...
static int ipv4_exit
Are we an IPv4-exit?
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
Message send via cadet to an exit daemon to forward UDP data to the Internet.
Definition: exit.h:146

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

Here is the call graph for this function:

◆ check_udp_service()

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

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

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

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

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

References GNUNET_break_op, GNUNET_OK, GNUNET_SYSERR, and state.

◆ handle_udp_service()

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

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

Parameters
clsour struct ChannelState *
msgthe actual message

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

1606{
1607 struct ChannelState *state = cls;
1608 uint16_t pkt_len = ntohs (msg->header.size) - sizeof(struct
1610
1612 gettext_noop ("# Bytes received from CADET"),
1613 pkt_len, GNUNET_NO);
1615 gettext_noop (
1616 "# UDP service requests received via cadet"),
1617 1, GNUNET_NO);
1619 "Received data from %s for forwarding to UDP service %s on port %u\n",
1620 GNUNET_i2s (&state->peer),
1621 GNUNET_h2s (&state->specifics.tcp_udp.serv->descriptor),
1622 (unsigned int) ntohs (msg->destination_port));
1624 if (0 != ntohs (msg->source_port))
1625 state->specifics.tcp_udp.ri.local_address.port = msg->source_port;
1626 send_udp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1627 &state->specifics.tcp_udp.ri.local_address,
1628 &msg[1],
1629 pkt_len);
1631}
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
Message send via cadet to an exit daemon to send UDP data to a local service.
Definition: exit.h:121

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

Here is the call graph for this function:

◆ handle_tcp_service()

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

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

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

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

1646{
1647 struct ChannelState *state = cls;
1648 uint16_t pkt_len = ntohs (start->header.size) - sizeof(struct
1650
1651 if (GNUNET_SYSERR == state->is_dns)
1652 {
1653 /* channel is UDP/TCP from now on */
1654 state->is_dns = GNUNET_NO;
1655 }
1657 gettext_noop (
1658 "# TCP service creation requests received via cadet"),
1659 1,
1660 GNUNET_NO);
1662 gettext_noop ("# Bytes received from CADET"),
1663 pkt_len,
1664 GNUNET_NO);
1665 GNUNET_break_op (ntohl (start->reserved) == 0);
1666 /* setup fresh connection */
1668 "Received data from %s for forwarding to TCP service %s on port %u\n",
1669 GNUNET_i2s (&state->peer),
1670 GNUNET_h2s (&state->specifics.tcp_udp.serv->descriptor),
1671 (unsigned int) ntohs (start->tcp_header.destination_port));
1673 send_tcp_packet_via_tun (&state->specifics.tcp_udp.ri.remote_address,
1674 &state->specifics.tcp_udp.ri.local_address,
1675 &start->tcp_header,
1676 &start[1],
1677 pkt_len);
1679}
static void send_tcp_packet_via_tun(const struct SocketAddress *destination_address, const struct SocketAddress *source_address, const struct GNUNET_TUN_TcpHeader *tcp_header, const void *payload, size_t payload_length)
Send a TCP packet via the TUN interface.
Message send via cadet to an exit daemon to initiate forwarding of TCP data to a local service.
Definition: exit.h:38

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

Here is the call graph for this function:

◆ check_tcp_remote()

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

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

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

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

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

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

◆ handle_tcp_remote()

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

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

Parameters
clsour struct ChannelState *
startthe actual message

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

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

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

Here is the call graph for this function:

◆ check_tcp_data()

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

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

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

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

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

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

Here is the call graph for this function:

◆ handle_tcp_data()

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

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

Parameters
clsour struct ChannelState *
datathe actual message

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

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

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

Here is the call graph for this function:

◆ make_up_icmpv4_payload()

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

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

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

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

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

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

Referenced by handle_icmp_remote(), and make_up_icmp_service_payload().

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

◆ make_up_icmpv6_payload()

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

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

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

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

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

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

Referenced by handle_icmp_remote(), and make_up_icmp_service_payload().

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

◆ check_icmp_remote()

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

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

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

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

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

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

◆ handle_icmp_remote()

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

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

Parameters
clsour struct ChannelState *
msgthe actual message

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

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

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

Here is the call graph for this function:

◆ make_up_icmp_service_payload()

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

Setup ICMP payload for ICMP error messages.

Called for both IPv4 and IPv6 addresses.

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

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

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

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

Referenced by handle_icmp_service().

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

◆ check_icmp_service()

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

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

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

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

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

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

◆ handle_icmp_service()

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

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

Parameters
clsour struct ChannelState *
msgthe actual message

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

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

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

Here is the call graph for this function:

◆ free_service_record()

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

Free memory associated with a service record.

Parameters
clsunused
keyservice descriptor
valueservice record to free
Returns
GNUNET_OK

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

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

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

Referenced by cleanup().

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

◆ new_service_channel()

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

Callback from CADET for new channels.

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

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

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

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

Referenced by store_service().

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

◆ clean_channel()

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

Function called by cadet whenever an inbound channel is destroyed.

Should clean up any associated state.

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

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

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

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

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

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

◆ store_service()

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

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

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

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

2564{
2566 GNUNET_MQ_hd_var_size (icmp_service,
2569 service),
2570 GNUNET_MQ_hd_var_size (udp_service,
2573 service),
2574 GNUNET_MQ_hd_var_size (tcp_service,
2577 service),
2578 GNUNET_MQ_hd_var_size (tcp_data,
2581 service),
2583 };
2584
2586
2587 service->name = GNUNET_strdup (name);
2589 &service->descriptor);
2591 destination_port,
2592 &cadet_port);
2594 "Opening CADET port %s for SERVICE exit %s on port %u\n",
2596 name,
2597 (unsigned int) destination_port);
2599 &cadet_port,
2601 service,
2602 NULL,
2604 handlers);
2605 service->is_udp = (IPPROTO_UDP == proto);
2606 if (GNUNET_OK !=
2608 &cadet_port,
2609 service,
2611 {
2613 GNUNET_free (service->name);
2616 _ ("Got duplicate service records for `%s:%u'\n"),
2617 name,
2618 (unsigned int) destination_port);
2619 }
2620}
struct GNUNET_MQ_MessageHandlers handlers[]
Definition: 003.c:1
static void clean_channel(void *cls, const struct GNUNET_CADET_Channel *channel)
Function called by cadet whenever an inbound channel is destroyed.
static void * new_service_channel(void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *initiator)
Callback from CADET for new channels.
static struct GNUNET_CADET_Handle * cadet_handle
The handle to cadet.
static char * name
Name (label) of the records to list.
static struct GNUNET_CADET_Port * cadet_port
Listen port for incoming requests.
struct GNUNET_CADET_Port * GNUNET_CADET_open_port(struct GNUNET_CADET_Handle *h, const struct GNUNET_HashCode *port, GNUNET_CADET_ConnectEventHandler connects, void *connects_cls, GNUNET_CADET_WindowSizeEventHandler window_changes, GNUNET_CADET_DisconnectEventHandler disconnects, const struct GNUNET_MQ_MessageHandler *handlers)
Open a port to receive incoming MQ-based channels.
Definition: cadet_api.c:954
@ GNUNET_ERROR_TYPE_WARNING
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT
Type of messages containing an TCP packet of an established connection.
#define GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_SERVICE
Type of messages containing an ICMP packet for a service.
#define GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START
Type of messages containing an TCP packet for a service.
#define GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE
Type of messages containing an UDP packet for a service.
void GNUNET_TUN_compute_service_cadet_port(const struct GNUNET_HashCode *desc, uint16_t ip_port, struct GNUNET_HashCode *cadet_port)
Compute the CADET port given a service descriptor (returned from GNUNET_TUN_service_name_to_hash) and...
Definition: regex.c:791
void GNUNET_TUN_service_name_to_hash(const char *service_name, struct GNUNET_HashCode *hc)
Hash the service name of a hosted service to the hash code that is used to identify the service on th...
Definition: regex.c:772
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
Message handler for a specific message type.

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

Referenced by add_services().

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

◆ send_packet_to_cadet_channel()

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

Send the given packet via the cadet channel.

Parameters
schannel destination
envmessage to queue

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

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

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

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

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

◆ icmp_from_helper()

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

Handles an ICMP packet received from the helper.

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

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

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

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

Referenced by message_token().

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

◆ udp_from_helper()

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

Handles an UDP packet received from the helper.

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

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

2869{
2870 struct ChannelState *state;
2871 struct GNUNET_MQ_Envelope *env;
2872 struct GNUNET_EXIT_UdpReplyMessage *urm;
2873
2874 {
2875 char sbuf[INET6_ADDRSTRLEN];
2876 char dbuf[INET6_ADDRSTRLEN];
2877
2879 "Received UDP packet going from %s:%u to %s:%u\n",
2880 inet_ntop (af,
2881 source_ip,
2882 sbuf, sizeof(sbuf)),
2883 (unsigned int) ntohs (udp->source_port),
2884 inet_ntop (af,
2885 destination_ip,
2886 dbuf, sizeof(dbuf)),
2887 (unsigned int) ntohs (udp->destination_port));
2888 }
2889
2890 if (pktlen < sizeof(struct GNUNET_TUN_UdpHeader))
2891 {
2892 /* blame kernel */
2893 GNUNET_break (0);
2894 return;
2895 }
2896 if (pktlen != ntohs (udp->len))
2897 {
2898 /* blame kernel */
2899 GNUNET_break (0);
2900 return;
2901 }
2903 IPPROTO_UDP,
2904 source_ip,
2905 ntohs (udp->source_port),
2906 destination_ip,
2907 ntohs (udp->destination_port),
2908 NULL);
2909 if (NULL == state)
2910 {
2912 _ (
2913 "UDP Packet dropped, have no matching connection information\n"));
2914 return;
2915 }
2916 env = GNUNET_MQ_msg_extra (urm,
2917 pktlen - sizeof(struct GNUNET_TUN_UdpHeader),
2919 urm->source_port = htons (0);
2920 urm->destination_port = htons (0);
2921 GNUNET_memcpy (&urm[1],
2922 &udp[1],
2923 pktlen - sizeof(struct GNUNET_TUN_UdpHeader));
2925 env);
2926}
#define GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY
Type of messages containing an UDP packet from a remote host.
Message send from exit daemon back to the UDP entry point (used for both Internet and Service exit re...
Definition: exit.h:179
uint16_t source_port
Source port to use for the UDP reply (0 to use the same port as for the original request).
Definition: exit.h:189
uint16_t destination_port
Destination port to use for the UDP reply (0 to use the same port as for the original request).
Definition: exit.h:195

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

Referenced by message_token().

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

◆ tcp_from_helper()

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

Handles a TCP packet received from the helper.

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

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

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

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

Referenced by message_token().

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

◆ message_token()

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

Receive packets from the helper-process.

Parameters
clsunused
messagemessage received from helper

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

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

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

Referenced by run().

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

◆ new_channel()

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

Callback from CADET for new channels.

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

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

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

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

Referenced by advertise_dns_exit(), and run().

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

◆ free_iterate()

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

Function that frees everything from a hashmap.

Parameters
clsunused
hashkey
valuevalue to free

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

3218{
3220 return GNUNET_YES;
3221}

References GNUNET_free, GNUNET_YES, and value.

Referenced by cleanup().

Here is the caller graph for this function:

◆ dummy_task()

static void dummy_task ( void *  cls)
static

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

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

Parameters
clsNULL

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

3234{
3235 /* just terminate */
3236}

Referenced by run().

Here is the caller graph for this function:

◆ cleanup()

static void cleanup ( void *  cls)
static

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

Parameters
clsNULL

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

3246{
3247 unsigned int i;
3248
3250 "Exit service is shutting down now\n");
3251
3252 if (NULL != helper_handle)
3253 {
3255 helper_handle = NULL;
3256 }
3257 if (NULL != regex4)
3258 {
3260 regex4 = NULL;
3261 }
3262 if (NULL != regex6)
3263 {
3265 regex6 = NULL;
3266 }
3267 if (NULL != services)
3268 {
3271 NULL);
3273 }
3274 if (NULL != dns_port)
3275 {
3277 dns_port = NULL;
3278 }
3279 if (NULL != cadet_port4)
3280 {
3282 cadet_port4 = NULL;
3283 }
3284 if (NULL != cadet_port6)
3285 {
3287 cadet_port6 = NULL;
3288 }
3289 if (NULL != cadet_handle)
3290 {
3292 cadet_handle = NULL;
3293 }
3294 if (NULL != connections_map)
3295 {
3297 &free_iterate,
3298 NULL);
3300 connections_map = NULL;
3301 }
3302 if (NULL != connections_heap)
3303 {
3305 connections_heap = NULL;
3306 }
3307 if (NULL != dnsstub)
3308 {
3310 dnsstub = NULL;
3311 }
3312 if (NULL != peer_key)
3313 {
3315 peer_key = NULL;
3316 }
3317 if (NULL != dht_task)
3318 {
3320 dht_task = NULL;
3321 }
3322 if (NULL != dht_put)
3323 {
3325 dht_put = NULL;
3326 }
3327 if (NULL != dht)
3328 {
3330 dht = NULL;
3331 }
3332 if (NULL != stats)
3333 {
3335 GNUNET_NO);
3336 stats = NULL;
3337 }
3338 for (i = 0; i < 8; i++)
3340}
static struct GNUNET_DHT_Handle * dht
Handle to the DHT.
static struct GNUNET_REGEX_Announcement * regex4
Handle to our regex announcement for IPv4.
static struct GNUNET_DHT_PutHandle * dht_put
Handle for ongoing DHT PUT operations to advertise exit service.
static struct GNUNET_REGEX_Announcement * regex6
Handle to our regex announcement for IPv4.
static char * exit_argv[8]
Arguments to the exit helper.
static struct GNUNET_CADET_Port * cadet_port4
Port for IPv4 exit.
static int free_service_record(void *cls, const struct GNUNET_HashCode *key, void *value)
Free memory associated with a service record.
static struct GNUNET_CRYPTO_EddsaPrivateKey * peer_key
Private key for this peer.
static struct GNUNET_CADET_Port * dns_port
Port for DNS exit.
static int free_iterate(void *cls, const struct GNUNET_HashCode *hash, void *value)
Function that frees everything from a hashmap.
static struct GNUNET_CADET_Port * cadet_port6
Port for IPv6 exit.
static struct GNUNET_SCHEDULER_Task * dht_task
Task for doing DHT PUTs to advertise exit service.
void GNUNET_CADET_disconnect(struct GNUNET_CADET_Handle *handle)
Disconnect from the cadet service.
Definition: cadet_api.c:774
void GNUNET_DHT_put_cancel(struct GNUNET_DHT_PutHandle *ph)
Cancels a DHT PUT operation.
Definition: dht_api.c:1146
void GNUNET_DHT_disconnect(struct GNUNET_DHT_Handle *handle)
Shutdown connection with the DHT service.
Definition: dht_api.c:1060
void GNUNET_DNSSTUB_stop(struct GNUNET_DNSSTUB_Context *ctx)
Cleanup DNSSTUB resolver.
Definition: dnsstub.c:705
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
void GNUNET_CONTAINER_heap_destroy(struct GNUNET_CONTAINER_Heap *heap)
Destroys the heap.
void GNUNET_HELPER_stop(struct GNUNET_HELPER_Handle *h, int soft_kill)
Kills the helper, closes the pipe, frees the handle and calls wait() on the helper process.
Definition: helper.c:536
void GNUNET_REGEX_announce_cancel(struct GNUNET_REGEX_Announcement *a)
Stop announcing the regex specified by the given handle.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:981
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).

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

Referenced by run().

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

◆ add_services()

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

Add services to the service map.

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

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

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

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

Referenced by read_service_conf().

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

◆ read_service_conf()

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

Reads the configuration and populates #udp_services and #tcp_services.

Parameters
clsunused
sectionname of section in config

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

3518{
3519 char *cpy;
3520
3521 if ((strlen (section) < 8) ||
3522 (0 != strcmp (".gnunet.", section + (strlen (section) - 8))))
3523 return;
3524 if (GNUNET_OK ==
3526 section,
3527 "UDP_REDIRECTS",
3528 &cpy))
3529 {
3530 add_services (IPPROTO_UDP,
3531 cpy,
3532 section);
3533 GNUNET_free (cpy);
3534 }
3535 if (GNUNET_OK ==
3537 section,
3538 "TCP_REDIRECTS",
3539 &cpy))
3540 {
3541 add_services (IPPROTO_TCP,
3542 cpy,
3543 section);
3544 GNUNET_free (cpy);
3545 }
3546}
static const struct GNUNET_CONFIGURATION_Handle * cfg
The handle to the configuration used throughout the process.
static void add_services(int proto, char *cpy, const char *name)
Add services to the service map.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.

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

Referenced by run().

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

◆ do_dht_put()

static void do_dht_put ( void *  cls)
static

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

This task is run periodically to do the DHT PUT.

Parameters
clsclosure

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

3580{
3582
3584 &do_dht_put,
3585 NULL);
3588 GNUNET_TIME_UNIT_HOURS.rel_value_us)
3589 {
3590 /* refresh advertisement */
3597 }
3598 if (NULL != dht_put)
3601 &dht_put_key,
3602 1 /* replication */,
3605 sizeof(struct GNUNET_DNS_Advertisement),
3607 expiration,
3608 &dht_put_cont,
3609 NULL);
3610}
#define DNS_ADVERTISEMENT_TIMEOUT
How long do we typically sign the DNS exit advertisement for?
static struct GNUNET_DNS_Advertisement dns_advertisement
Advertisement message we put into the DHT to advertise us as a DNS exit.
static void dht_put_cont(void *cls)
Function called when the DHT PUT operation is complete.
static void do_dht_put(void *cls)
We are running a DNS exit service, advertise it in the DHT.
static struct GNUNET_HashCode dht_put_key
Key we store the DNS advertismenet under.
#define DHT_PUT_FREQUENCY
How frequently do we re-announce the DNS exit in the DHT?
static struct GNUNET_TIME_Relative expiration
User supplied expiration value.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_sign_(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, struct GNUNET_CRYPTO_EddsaSignature *sig)
EdDSA sign a given block.
Definition: crypto_ecc.c:622
struct GNUNET_DHT_PutHandle * GNUNET_DHT_put(struct GNUNET_DHT_Handle *handle, const struct GNUNET_HashCode *key, uint32_t desired_replication_level, enum GNUNET_DHT_RouteOption options, enum GNUNET_BLOCK_Type type, size_t size, const void *data, struct GNUNET_TIME_Absolute exp, GNUNET_SCHEDULER_TaskCallback cont, void *cont_cls)
Perform a PUT operation storing data in the DHT.
Definition: dht_api.c:1088
@ GNUNET_DHT_RO_NONE
Default.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1278
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:405
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:737
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:316
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:638
@ GNUNET_BLOCK_TYPE_DNS
Block for storing DNS exit service advertisements.
This is the structure describing an DNS exit service.
Definition: block_dns.h:45
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does this signature expire?
Definition: block_dns.h:60
struct GNUNET_CRYPTO_EddsaSignature signature
Signature of the peer affirming that it is offering the service.
Definition: block_dns.h:49
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Beginning of signed portion of the record, signs everything until the end of the struct.
Definition: block_dns.h:55
Time for absolute times used by GNUnet, in microseconds.

References dht, dht_put, dht_put_cont(), DHT_PUT_FREQUENCY, dht_put_key, dht_task, dns_advertisement, DNS_ADVERTISEMENT_TIMEOUT, do_dht_put(), expiration, GNUNET_DNS_Advertisement::expiration_time, GNUNET_assert, GNUNET_BLOCK_TYPE_DNS, GNUNET_CRYPTO_eddsa_sign_(), GNUNET_DHT_put(), GNUNET_DHT_put_cancel(), GNUNET_DHT_RO_NONE, GNUNET_OK, GNUNET_SCHEDULER_add_delayed(), GNUNET_TIME_absolute_get_remaining(), GNUNET_TIME_absolute_hton(), GNUNET_TIME_absolute_ntoh(), GNUNET_TIME_relative_to_absolute(), GNUNET_TIME_UNIT_HOURS, peer_key, GNUNET_DNS_Advertisement::purpose, and GNUNET_DNS_Advertisement::signature.

Referenced by advertise_dns_exit(), and do_dht_put().

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

◆ dht_put_cont()

static void dht_put_cont ( void *  cls)
static

Function called when the DHT PUT operation is complete.

Schedules the next PUT.

Parameters
clsclosure, NULL

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

3567{
3568 dht_put = NULL;
3569}

References dht_put.

Referenced by do_dht_put().

Here is the caller graph for this function:

◆ parse_ip_options()

static void parse_ip_options ( )
static

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

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

3619{
3621 "exit",
3622 "EXIT_IPV4");
3624 "exit",
3625 "EXIT_IPV6");
3627 "exit",
3628 "ENABLE_IPV4");
3630 "exit",
3631 "ENABLE_IPV6");
3632 if ((ipv4_exit || ipv4_enabled) &&
3633 (GNUNET_OK != GNUNET_NETWORK_test_pf (PF_INET)) )
3634 {
3636 _ (
3637 "This system does not support IPv4, will disable IPv4 functions despite them being enabled in the configuration\n"));
3640 }
3641 if ((ipv6_exit || ipv6_enabled) &&
3642 (GNUNET_OK != GNUNET_NETWORK_test_pf (PF_INET6)) )
3643 {
3645 _ (
3646 "This system does not support IPv6, will disable IPv6 functions despite them being enabled in the configuration\n"));
3649 }
3650 if (ipv4_exit && (! ipv4_enabled))
3651 {
3653 _ (
3654 "Cannot enable IPv4 exit but disable IPv4 on TUN interface, will use ENABLE_IPv4=YES\n"));
3656 }
3657 if (ipv6_exit && (! ipv6_enabled))
3658 {
3660 _ (
3661 "Cannot enable IPv6 exit but disable IPv6 on TUN interface, will use ENABLE_IPv6=YES\n"));
3663 }
3664}
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
@ GNUNET_ERROR_TYPE_ERROR
enum GNUNET_GenericReturnValue GNUNET_NETWORK_test_pf(int pf)
Test if the given protocol family is supported by this system.
Definition: network.c:79

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

Referenced by run().

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

◆ advertise_dns_exit()

static void advertise_dns_exit ( )
static

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

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

3673{
3675 GNUNET_MQ_hd_var_size (dns_request,
3677 struct DnsResponseMessage,
3678 NULL),
3680 };
3681 char *dns_exit;
3682 struct GNUNET_HashCode port;
3683
3684 if (GNUNET_YES !=
3686 "exit",
3687 "EXIT_DNS"))
3688 return;
3689 GNUNET_assert (NULL != (dnsstub = GNUNET_DNSSTUB_start (128)));
3690 dns_exit = NULL;
3691 /* TODO: support using multiple DNS resolvers */
3692 if ((GNUNET_OK !=
3694 "exit",
3695 "DNS_RESOLVER",
3696 &dns_exit)) ||
3697 (GNUNET_OK !=
3699 dns_exit)))
3700 {
3702 "dns",
3703 "DNS_RESOLVER",
3704 _ ("need a valid IPv4 or IPv6 address\n"));
3705 GNUNET_free (dns_exit);
3706 return;
3707 }
3708 /* open port */
3711 &port);
3713 "Opening CADET port %s for DNS exit service\n",
3714 GNUNET_h2s (&port));
3716 &port,
3717 &new_channel,
3718 NULL,
3719 NULL,
3721 handlers);
3722 /* advertise exit */
3724 1);
3728 dns_advertisement.purpose.size = htonl (sizeof(struct
3730 - sizeof(struct
3734 GNUNET_CRYPTO_hash ("dns",
3735 strlen ("dns"),
3736 &dht_put_key);
3738 NULL);
3739 GNUNET_free (dns_exit);
3740}
static uint16_t port
Port number.
Definition: gnunet-bcd.c:147
static void * new_channel(void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *initiator)
Callback from CADET for new channels.
#define GNUNET_APPLICATION_PORT_INTERNET_RESOLVER
Internet DNS resolution (external DNS gateway).
void GNUNET_CRYPTO_eddsa_key_get_public(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:198
struct GNUNET_CRYPTO_EddsaPrivateKey * GNUNET_CRYPTO_eddsa_key_create_from_configuration(const struct GNUNET_CONFIGURATION_Handle *cfg)
Create a new private key by reading our peer's key from the file specified in the configuration.
struct GNUNET_DHT_Handle * GNUNET_DHT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, unsigned int ht_len)
Initialize the connection with the DHT service.
Definition: dht_api.c:1037
struct GNUNET_DNSSTUB_Context * GNUNET_DNSSTUB_start(unsigned int num_sockets)
Start a DNS stub resolver.
Definition: dnsstub.c:586
int GNUNET_DNSSTUB_add_dns_ip(struct GNUNET_DNSSTUB_Context *ctx, const char *dns_ip)
Add nameserver for use by the DNSSTUB.
Definition: dnsstub.c:613
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
void GNUNET_log_config_invalid(enum GNUNET_ErrorType kind, const char *section, const char *option, const char *required)
Log error message about invalid configuration option value.
#define GNUNET_MESSAGE_TYPE_VPN_DNS_TO_INTERNET
Type of messages containing an DNS request for a DNS exit service.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1305
#define GNUNET_SIGNATURE_PURPOSE_DNS_RECORD
Signature on a GNUNET_DNS_Advertisement.
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!...
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
an ECC signature using EdDSA.
struct GNUNET_PeerIdentity peer
The peer providing this service.
Definition: block_dns.h:65
struct GNUNET_CRYPTO_EddsaPublicKey public_key

References _, cadet_handle, cfg, clean_channel(), dht, dht_put_key, dht_task, dns_advertisement, dns_port, dnsstub, do_dht_put(), GNUNET_APPLICATION_PORT_INTERNET_RESOLVER, GNUNET_assert, GNUNET_CADET_open_port(), GNUNET_CONFIGURATION_get_value_string(), GNUNET_CONFIGURATION_get_value_yesno(), GNUNET_CRYPTO_eddsa_key_create_from_configuration(), GNUNET_CRYPTO_eddsa_key_get_public(), GNUNET_CRYPTO_hash(), GNUNET_DHT_connect(), GNUNET_DNSSTUB_add_dns_ip(), GNUNET_DNSSTUB_start(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_h2s(), GNUNET_log, GNUNET_log_config_invalid(), GNUNET_MESSAGE_TYPE_VPN_DNS_TO_INTERNET, GNUNET_MQ_handler_end, GNUNET_MQ_hd_var_size, GNUNET_OK, GNUNET_SCHEDULER_add_now(), GNUNET_SIGNATURE_PURPOSE_DNS_RECORD, GNUNET_YES, handlers, new_channel(), GNUNET_DNS_Advertisement::peer, peer_key, port, GNUNET_PeerIdentity::public_key, GNUNET_DNS_Advertisement::purpose, GNUNET_CRYPTO_EccSignaturePurpose::purpose, and GNUNET_CRYPTO_EccSignaturePurpose::size.

Referenced by run().

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

◆ setup_exit_helper_args()

static int setup_exit_helper_args ( )
static

Initialize exit_argv.

Returns
GNUNET_OK on success, GNUNET_SYSERR if we should shutdown

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

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

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

Referenced by run().

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

◆ run()

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

Main function that will be run by the scheduler.

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

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

3903{
3905 GNUNET_MQ_hd_var_size (icmp_remote,
3908 NULL),
3909 GNUNET_MQ_hd_var_size (udp_remote,
3912 NULL),
3913 GNUNET_MQ_hd_var_size (tcp_remote,
3916 NULL),
3917 GNUNET_MQ_hd_var_size (tcp_data,
3920 NULL),
3922 };
3923 struct GNUNET_HashCode port;
3924 char *policy;
3925 char *binary;
3926 char *regex;
3927 char *prefixed_regex;
3928
3929 cfg = cfg_;
3930 if (GNUNET_OK !=
3932 "exit",
3933 "MAX_CONNECTIONS",
3935 max_connections = 1024;
3937 binary = GNUNET_OS_get_suid_binary_path (cfg, "gnunet-helper-exit");
3938 if ((ipv4_exit) || (ipv6_exit))
3939 {
3940 if (GNUNET_YES !=
3942 GNUNET_YES,
3943 "gnunet-vpn - - - 169.1.3.7 255.255.255.0")) // no nat, ipv4 only
3944 {
3945 GNUNET_free (binary);
3947 _ (
3948 "`%s' is not SUID or the path is invalid, EXIT will not work\n"),
3949 "gnunet-helper-exit");
3951 NULL);
3952 global_ret = 1;
3953 return;
3954 }
3955 }
3956 if (! (ipv4_enabled || ipv6_enabled))
3957 {
3958 GNUNET_free (binary);
3960 _ ("No useful service enabled. Exiting.\n"));
3962 return;
3963 }
3964
3966 NULL);
3968 cfg);
3970 if (NULL == cadet_handle)
3971 {
3972 GNUNET_free (binary);
3974 return;
3975 }
3977 if (GNUNET_OK !=
3979 {
3980 GNUNET_free (binary);
3982 return;
3983 }
3984
3986 GNUNET_NO);
3988 GNUNET_NO);
3993 NULL);
3994
3995 /* Cadet handle acquired, now open ports and announce regular
3996 expressions matching our exit */
3997 if ((GNUNET_YES == ipv4_enabled) &&
3998 (GNUNET_YES == ipv4_exit))
3999 {
4002 &port);
4004 "Opening CADET port %s for IPv4 gateway service\n",
4005 GNUNET_h2s (&port));
4007 &port,
4008 &new_channel,
4009 NULL,
4010 NULL,
4012 handlers);
4013 policy = NULL;
4014 if (GNUNET_OK !=
4016 "exit",
4017 "EXIT_RANGE_IPV4_POLICY",
4018 &policy))
4019 regex = NULL;
4020 else
4021 regex = GNUNET_TUN_ipv4policy2regex (policy);
4022 GNUNET_free (policy);
4023 if (NULL != regex)
4024 {
4025 (void) GNUNET_asprintf (&prefixed_regex,
4026 "%s%s",
4028 regex);
4030 prefixed_regex,
4033 GNUNET_free (regex);
4034 GNUNET_free (prefixed_regex);
4035 }
4036 }
4037
4039 {
4042 &port);
4044 "Opening CADET port %s for IPv6 gateway service\n",
4045 GNUNET_h2s (&port));
4047 &port,
4048 &new_channel,
4049 NULL,
4050 NULL,
4052 handlers);
4053 policy = NULL;
4054 if (GNUNET_OK !=
4056 "exit",
4057 "EXIT_RANGE_IPV6_POLICY",
4058 &policy))
4059 regex = NULL;
4060 else
4061 regex = GNUNET_TUN_ipv6policy2regex (policy);
4062 GNUNET_free (policy);
4063 if (NULL != regex)
4064 {
4065 (void) GNUNET_asprintf (&prefixed_regex,
4066 "%s%s",
4068 regex);
4070 prefixed_regex,
4073 GNUNET_free (regex);
4074 GNUNET_free (prefixed_regex);
4075 }
4076 }
4078 binary,
4079 exit_argv,
4081 NULL,
4082 NULL);
4083 GNUNET_free (binary);
4084}
#define REGEX_MAX_PATH_LEN_IPV4
Maximum path compression length for cadet regex announcing for IPv4 address based regex.
#define REGEX_REFRESH_FREQUENCY
How frequently do we re-announce the regex for the exit?
static int global_ret
Return value from 'main'.
static int setup_exit_helper_args()
Initialize exit_argv.
static void cleanup(void *cls)
Function scheduled as very last function, cleans up after us.
#define REGEX_MAX_PATH_LEN_IPV6
Maximum path compression length for cadet regex announcing for IPv6 address based regex.
static void dummy_task(void *cls)
Function scheduled as very last function if the service disabled itself because the helper is not ins...
static int message_token(void *cls, const struct GNUNET_MessageHeader *message)
Receive packets from the helper-process.
static void read_service_conf(void *cls, const char *section)
Reads the configuration and populates #udp_services and #tcp_services.
static void parse_ip_options()
Figure out which IP versions we should support (and which are supported by the OS) according to our c...
static void advertise_dns_exit()
Helper function to open the CADET port for DNS exits and to advertise the DNS exit (if applicable).
#define GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX
Internet exit regex prefix.
#define GNUNET_APPLICATION_PORT_IPV4_GATEWAY
Internet IPv4 gateway (any TCP/UDP/ICMP).
#define GNUNET_APPLICATION_PORT_IPV6_GATEWAY
Internet IPv6 gateway (any TCP/UDP/ICMP).
struct GNUNET_CADET_Handle * GNUNET_CADET_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the MQ-based cadet service.
Definition: cadet_api.c:894
void GNUNET_CONFIGURATION_iterate_sections(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_CONFIGURATION_SectionIterator iter, void *iter_cls)
Iterate over all sections in the configuration.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
struct GNUNET_CONTAINER_Heap * GNUNET_CONTAINER_heap_create(enum GNUNET_CONTAINER_HeapOrder order)
Create a new heap.
@ GNUNET_CONTAINER_HEAP_ORDER_MIN
Heap with the minimum cost at the root.
struct GNUNET_HELPER_Handle * GNUNET_HELPER_start(int with_control_pipe, const char *binary_name, char *const binary_argv[], GNUNET_MessageTokenizerCallback cb, GNUNET_HELPER_ExceptionCallback exp_cb, void *cb_cls)
Starts a helper and begins reading from it.
Definition: helper.c:460
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
char * GNUNET_OS_get_suid_binary_path(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *progname)
Given the name of a helper, service or daemon binary construct the full path to the binary using the ...
enum GNUNET_GenericReturnValue GNUNET_OS_check_helper_binary(const char *binary, bool check_suid, const char *params)
Check whether an executable exists and possibly if the suid bit is set on the file.
#define GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START
Type of messages containing an TCP packet for the Internet.
#define GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_INTERNET
Type of messages containing an ICMP packet for the Internet.
#define GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET
Type of messages containing an UDP packet for the Internet.
struct GNUNET_REGEX_Announcement * GNUNET_REGEX_announce(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *regex, struct GNUNET_TIME_Relative refresh_delay, uint16_t compression)
Announce this peer under the given regular expression.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:567
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition: scheduler.c:1340
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
char * GNUNET_TUN_ipv6policy2regex(const char *policy)
Convert an exit policy to a regular expression.
Definition: regex.c:725
char * GNUNET_TUN_ipv4policy2regex(const char *policy)
Convert an exit policy to a regular expression.
Definition: regex.c:682

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

Referenced by main().

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

◆ main()

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

The main function.

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

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

4097{
4098 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
4100 };
4101
4102 if (GNUNET_OK !=
4104 argv,
4105 &argc,
4106 &argv))
4107 return 2;
4108
4109 return (GNUNET_OK ==
4110 GNUNET_PROGRAM_run (argc,
4111 argv,
4112 "gnunet-daemon-exit",
4113 gettext_noop (
4114 "Daemon to run to provide an IP exit node for the VPN"),
4115 options,
4116 &run,
4117 NULL)) ? global_ret : 1;
4118}
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
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.
enum GNUNET_GenericReturnValue GNUNET_PROGRAM_run(int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls)
Run a standard GNUnet command startup sequence (initialize loggers and configuration,...
Definition: program.c:400
enum GNUNET_GenericReturnValue GNUNET_STRINGS_get_utf8_args(int argc, char *const *argv, int *u8argc, char *const **u8argv)
Returns utf-8 encoded arguments.
Definition: strings.c:1230
Definition of a command line option.

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

Here is the call graph for this function:

Variable Documentation

◆ global_ret

int global_ret
static

Return value from 'main'.

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

Referenced by main(), and run().

◆ regex4

struct GNUNET_REGEX_Announcement* regex4
static

Handle to our regex announcement for IPv4.

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

Referenced by cleanup(), and run().

◆ regex6

struct GNUNET_REGEX_Announcement* regex6
static

Handle to our regex announcement for IPv4.

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

Referenced by cleanup(), and run().

◆ cfg

const struct GNUNET_CONFIGURATION_Handle* cfg
static

The handle to the configuration used throughout the process.

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

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

◆ helper_handle

struct GNUNET_HELPER_Handle* helper_handle
static

The handle to the helper.

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

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

◆ exit_argv

char* exit_argv[8]
static

Arguments to the exit helper.

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

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

◆ exit_ipv6addr

struct in6_addr exit_ipv6addr
static

IPv6 address of our TUN interface.

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

Referenced by setup_exit_helper_args(), and setup_fresh_address().

◆ ipv6prefix

unsigned long long ipv6prefix
static

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

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

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

◆ exit_ipv4addr

struct in_addr exit_ipv4addr
static

IPv4 address of our TUN interface.

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

Referenced by setup_exit_helper_args(), and setup_fresh_address().

◆ exit_ipv4mask

struct in_addr exit_ipv4mask
static

IPv4 netmask of our TUN interface.

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

Referenced by setup_exit_helper_args(), and setup_fresh_address().

◆ stats

◆ cadet_handle

struct GNUNET_CADET_Handle* cadet_handle
static

The handle to cadet.

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

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

◆ connections_map

struct GNUNET_CONTAINER_MultiHashMap* connections_map
static

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

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

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

◆ connections_heap

struct GNUNET_CONTAINER_Heap* connections_heap
static

Heap so we can quickly find "old" connections.

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

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

◆ max_connections

unsigned long long max_connections
static

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

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

Referenced by run(), and setup_state_record().

◆ services

struct GNUNET_CONTAINER_MultiHashMap* services
static

This hashmaps saves interesting things about the configured services.

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

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

◆ channels

struct ChannelState* channels[UINT16_MAX+1]
static

Array of all open DNS requests from channels.

Definition at line