GNUnet 0.21.1
gnunet-service-vpn.c File Reference

service that opens a virtual interface and allows its clients to allocate IPs on the virtual interface and to then redirect IP traffic received on those IPs via the GNUnet cadet More...

#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_common.h"
#include "gnunet_protocols.h"
#include "gnunet_applications.h"
#include "gnunet_cadet_service.h"
#include "gnunet_statistics_service.h"
#include "gnunet_constants.h"
#include "gnunet_regex_service.h"
#include "vpn.h"
#include "exit.h"
Include dependency graph for gnunet-service-vpn.c:

Go to the source code of this file.

Data Structures

struct  DestinationChannel
 List of channels we keep for each destination port for a given destination entry. More...
 
struct  DestinationEntry
 Information we track for each IP address to determine which channel to send the traffic over to the destination. More...
 
struct  ChannelMessageQueueEntry
 A messages we have in queue for a particular channel. More...
 
struct  ChannelState
 This struct is saved into connections_map to allow finding the right channel given an IP packet from TUN. More...
 

Macros

#define MAX_MESSAGE_QUEUE_SIZE   4
 Maximum number of messages we allow in the queue for cadet. More...
 

Functions

static void get_destination_key_from_ip (int af, const void *address, struct GNUNET_HashCode *key)
 Compute the key under which we would store an entry in the destination_map for the given IP address. More...
 
static void get_channel_key_from_ips (int af, uint8_t protocol, const void *source_ip, uint16_t source_port, const void *destination_ip, uint16_t destination_port, struct GNUNET_HashCode *key)
 Compute the key under which we would store an entry in the channel_map for the given socket address pair. More...
 
static void send_client_reply (struct GNUNET_SERVICE_Client *client, uint64_t request_id, int result_af, const void *addr)
 Notify the client about the result of its request. More...
 
static void free_channel_state (struct ChannelState *ts)
 Free resources associated with a channel state. More...
 
static void send_to_channel (struct ChannelState *ts, struct GNUNET_MQ_Envelope *env)
 Add the given message to the given channel and trigger the transmission process. More...
 
static const char * print_channel_destination (const struct DestinationEntry *de)
 Output destination of a channel for diagnostics. More...
 
static void channel_cleaner (void *cls, const struct GNUNET_CADET_Channel *channel)
 Function called whenever a channel is destroyed. More...
 
static void make_up_icmpv4_payload (struct ChannelState *ts, struct GNUNET_TUN_IPv4Header *ipp, struct GNUNET_TUN_UdpHeader *udp)
 Synthesize a plausible ICMP payload for an ICMP error response on the given channel. More...
 
static void make_up_icmpv6_payload (struct ChannelState *ts, struct GNUNET_TUN_IPv6Header *ipp, struct GNUNET_TUN_UdpHeader *udp)
 Synthesize a plausible ICMP payload for an ICMP error response on the given channel. More...
 
static int check_icmp_back (void *cls, const struct GNUNET_EXIT_IcmpToVPNMessage *i2v)
 We got an ICMP packet back from the CADET channel. More...
 
static void handle_icmp_back (void *cls, const struct GNUNET_EXIT_IcmpToVPNMessage *i2v)
 We got an ICMP packet back from the CADET channel. More...
 
static int check_udp_back (void *cls, const struct GNUNET_EXIT_UdpReplyMessage *reply)
 We got a UDP packet back from the CADET channel. More...
 
static void handle_udp_back (void *cls, const struct GNUNET_EXIT_UdpReplyMessage *reply)
 We got a UDP packet back from the CADET channel. More...
 
static int check_tcp_back (void *cls, const struct GNUNET_EXIT_TcpDataMessage *data)
 We got a TCP packet back from the CADET channel. More...
 
static void handle_tcp_back (void *cls, const struct GNUNET_EXIT_TcpDataMessage *data)
 We got a TCP packet back from the CADET channel. More...
 
static struct GNUNET_CADET_Channelcreate_channel (struct ChannelState *ts, const struct GNUNET_PeerIdentity *target, const struct GNUNET_HashCode *port)
 Create a channel for ts to target at port. More...
 
static void handle_regex_result (void *cls, const struct GNUNET_PeerIdentity *id, const struct GNUNET_PeerIdentity *get_path, unsigned int get_path_length, const struct GNUNET_PeerIdentity *put_path, unsigned int put_path_length)
 Regex has found a potential exit peer for us; consider using it. More...
 
static struct ChannelStatecreate_channel_to_destination (struct DestinationChannel *dt, int client_af)
 Initialize the given destination entry's cadet channel. More...
 
static void expire_channel (struct ChannelState *except)
 We have too many active channels. More...
 
static void route_packet (struct DestinationEntry *destination, int af, uint8_t protocol, const void *source_ip, const void *destination_ip, const void *payload, size_t payload_length)
 Route a packet via cadet to the given destination. More...
 
static int message_token (void *cls, const struct GNUNET_MessageHeader *message)
 Receive packets from the helper-process (someone send to the local virtual channel interface). More...
 
static int allocate_v4_address (struct in_addr *v4)
 Allocate an IPv4 address from the range of the channel for a new redirection. More...
 
static int allocate_v6_address (struct in6_addr *v6)
 Allocate an IPv6 address from the range of the channel for a new redirection. More...
 
static void free_destination_entry (struct DestinationEntry *de)
 Free resources occupied by a destination entry. More...
 
static void expire_destination (struct DestinationEntry *except)
 We have too many active destinations. More...
 
static int allocate_response_ip (int *result_af, void **addr, struct in_addr *v4, struct in6_addr *v6)
 Allocate an IP address for the response. More...
 
static int check_client_redirect_to_ip (void *cls, const struct RedirectToIpRequestMessage *msg)
 A client asks us to setup a redirection via some exit node to a particular IP. More...
 
static void handle_client_redirect_to_ip (void *cls, const struct RedirectToIpRequestMessage *msg)
 A client asks us to setup a redirection via some exit node to a particular IP. More...
 
static void handle_client_redirect_to_service (void *cls, const struct RedirectToServiceRequestMessage *msg)
 A client asks us to setup a redirection to a particular peer offering a service. More...
 
static int cleanup_destination (void *cls, const struct GNUNET_HashCode *key, void *value)
 Free memory occupied by an entry in the destination map. More...
 
static int cleanup_channel (void *cls, const struct GNUNET_HashCode *key, void *value)
 Free memory occupied by an entry in the channel map. More...
 
static void cleanup (void *cls)
 Function scheduled as very last function, cleans up after us. More...
 
static void * client_connect_cb (void *cls, struct GNUNET_SERVICE_Client *c, struct GNUNET_MQ_Handle *mq)
 Callback called when a client connects to the service. More...
 
static void client_disconnect_cb (void *cls, struct GNUNET_SERVICE_Client *c, void *internal_cls)
 Callback called when a client disconnected from the service. More...
 
static void run (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg_, struct GNUNET_SERVICE_Handle *service)
 Main function that will be run by the scheduler. More...
 
 GNUNET_SERVICE_MAIN ("vpn", GNUNET_SERVICE_OPTION_NONE, &run, &client_connect_cb, &client_disconnect_cb, NULL, GNUNET_MQ_hd_var_size(client_redirect_to_ip, GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_IP, struct RedirectToIpRequestMessage, NULL), GNUNET_MQ_hd_fixed_size(client_redirect_to_service, GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_SERVICE, struct RedirectToServiceRequestMessage, NULL), GNUNET_MQ_handler_end())
 Define "main" method using service macro. More...
 

Variables

static int global_ret
 Return value from main(). More...
 
static const struct GNUNET_CONFIGURATION_Handlecfg
 Configuration we use. More...
 
static struct GNUNET_CADET_Handlecadet_handle
 Handle to the cadet service. More...
 
static struct GNUNET_CONTAINER_MultiHashMapdestination_map
 Map from IP address to destination information (possibly with a CADET channel handle for fast setup). More...
 
static struct GNUNET_CONTAINER_Heapdestination_heap
 Min-Heap sorted by activity time to expire old mappings. More...
 
static struct GNUNET_CONTAINER_MultiHashMapchannel_map
 Map from source and destination address (IP+port) to connection information (mostly with the respective CADET channel handle). More...
 
static struct GNUNET_CONTAINER_Heapchannel_heap
 Min-Heap sorted by activity time to expire old mappings; values are of type 'struct ChannelState'. More...
 
static struct GNUNET_STATISTICS_Handlestats
 Statistics. More...
 
static struct GNUNET_HELPER_Handlehelper_handle
 The handle to the VPN helper process "gnunet-helper-vpn". More...
 
static char * vpn_argv [7]
 Arguments to the vpn helper. More...
 
static unsigned long long ipv6prefix
 Length of the prefix of the VPN's IPv6 network. More...
 
static unsigned long long max_destination_mappings
 If there are more than this number of address-mappings, old ones will be removed. More...
 
static unsigned long long max_channel_mappings
 If there are more than this number of open channels, old ones will be removed. More...
 

Detailed Description

service that opens a virtual interface and allows its clients to allocate IPs on the virtual interface and to then redirect IP traffic received on those IPs via the GNUnet cadet

Author
Philipp Toelke
Christian Grothoff

TODO:

  • keep multiple peers/cadet channels ready as alternative exits / detect & recover from channel-to-exit failure gracefully

Definition in file gnunet-service-vpn.c.

Macro Definition Documentation

◆ MAX_MESSAGE_QUEUE_SIZE

#define MAX_MESSAGE_QUEUE_SIZE   4

Maximum number of messages we allow in the queue for cadet.

Definition at line 49 of file gnunet-service-vpn.c.

Function Documentation

◆ get_destination_key_from_ip()

static void get_destination_key_from_ip ( int  af,
const void *  address,
struct GNUNET_HashCode key 
)
static

Compute the key under which we would store an entry in the destination_map for the given IP address.

Parameters
afaddress family (AF_INET or AF_INET6)
addressIP address, struct in_addr or struct in6_addr
keywhere to store the key

Definition at line 382 of file gnunet-service-vpn.c.

385{
386 switch (af)
387 {
388 case AF_INET:
389 GNUNET_CRYPTO_hash (address, sizeof(struct in_addr), key);
390 break;
391
392 case AF_INET6:
393 GNUNET_CRYPTO_hash (address, sizeof(struct in6_addr), key);
394 break;
395
396 default:
397 GNUNET_assert (0);
398 break;
399 }
400}
static char * address
GNS address for this phone.
struct GNUNET_HashCode key
The key used in the DHT.
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
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.

References address, GNUNET_assert, GNUNET_CRYPTO_hash(), and key.

Referenced by allocate_v4_address(), allocate_v6_address(), handle_client_redirect_to_ip(), handle_client_redirect_to_service(), and message_token().

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

◆ get_channel_key_from_ips()

static void get_channel_key_from_ips ( int  af,
uint8_t  protocol,
const void *  source_ip,
uint16_t  source_port,
const void *  destination_ip,
uint16_t  destination_port,
struct GNUNET_HashCode key 
)
static

Compute the key under which we would store an entry in the channel_map for the given socket address pair.

Parameters
afaddress family (AF_INET or AF_INET6)
protocolIPPROTO_TCP or IPPROTO_UDP
source_ipsender's source IP, struct in_addr or struct in6_addr
source_portsender's source port
destination_ipsender's destination IP, struct in_addr or struct in6_addr
destination_portsender's destination port
keywhere to store the key

Definition at line 416 of file gnunet-service-vpn.c.

423{
424 char *off;
425
426 memset (key, 0, sizeof(struct GNUNET_HashCode));
427 /* the GNUnet hashmap only uses the first sizeof(unsigned int) of the hash,
428 so we put the ports in there (and hope for few collisions) */
429 off = (char *) key;
430 GNUNET_memcpy (off, &source_port, sizeof(uint16_t));
431 off += sizeof(uint16_t);
432 GNUNET_memcpy (off, &destination_port, sizeof(uint16_t));
433 off += sizeof(uint16_t);
434 switch (af)
435 {
436 case AF_INET:
437 GNUNET_memcpy (off, source_ip, sizeof(struct in_addr));
438 off += sizeof(struct in_addr);
439 GNUNET_memcpy (off, destination_ip, sizeof(struct in_addr));
440 off += sizeof(struct in_addr);
441 break;
442
443 case AF_INET6:
444 GNUNET_memcpy (off, source_ip, sizeof(struct in6_addr));
445 off += sizeof(struct in6_addr);
446 GNUNET_memcpy (off, destination_ip, sizeof(struct in6_addr));
447 off += sizeof(struct in6_addr);
448 break;
449
450 default:
451 GNUNET_assert (0);
452 break;
453 }
454 GNUNET_memcpy (off, &protocol, sizeof(uint8_t));
455 /* off += sizeof (uint8_t); */
456}
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
A 512-bit hashcode.

References GNUNET_assert, GNUNET_memcpy, and key.

Referenced by free_channel_state(), and route_packet().

Here is the caller graph for this function:

◆ send_client_reply()

static void send_client_reply ( struct GNUNET_SERVICE_Client client,
uint64_t  request_id,
int  result_af,
const void *  addr 
)
static

Notify the client about the result of its request.

Parameters
clientclient to notify
request_idoriginal request ID to include in response
result_afresulting address family
addrresulting IP address

Definition at line 468 of file gnunet-service-vpn.c.

472{
473 struct GNUNET_MQ_Envelope *env;
475 size_t rlen;
476
477 switch (result_af)
478 {
479 case AF_INET:
480 rlen = sizeof(struct in_addr);
481 break;
482
483 case AF_INET6:
484 rlen = sizeof(struct in6_addr);
485 break;
486
487 case AF_UNSPEC:
488 rlen = 0;
489 break;
490
491 default:
492 GNUNET_assert (0);
493 return;
494 }
496 res->result_af = htonl (result_af);
497 res->request_id = request_id;
498 GNUNET_memcpy (&res[1], addr, rlen);
500}
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static char * res
Currently read line or NULL on EOF.
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_CLIENT_USE_IP
VPN service responds to client with an IP to use for the requested redirection.
struct GNUNET_MQ_Handle * GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c)
Obtain the message queue of c.
Definition: service.c:2566
Response from the VPN service to a VPN client informing about the IP that was assigned for the reques...
Definition: vpn.h:130
int32_t result_af
Address family of the allocated address that follows; will match "result_af" from the request,...
Definition: vpn.h:140

References env, GNUNET_assert, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_VPN_CLIENT_USE_IP, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_SERVICE_client_get_mq(), res, and RedirectToIpResponseMessage::result_af.

Referenced by handle_client_redirect_to_ip(), and handle_client_redirect_to_service().

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

◆ free_channel_state()

static void free_channel_state ( struct ChannelState ts)
static

Free resources associated with a channel state.

Parameters
tsstate to free

Definition at line 509 of file gnunet-service-vpn.c.

510{
511 struct GNUNET_HashCode key;
512 struct ChannelMessageQueueEntry *tnq;
513 struct GNUNET_CADET_Channel *channel;
514
515 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up channel state\n");
516 if (NULL != (channel = ts->channel))
517 {
518 ts->channel = NULL;
520 return;
521 }
523 gettext_noop ("# Active channels"),
524 -1,
525 GNUNET_NO);
526 while (NULL != (tnq = ts->tmq_head))
527 {
529 ts->tmq_length--;
530 GNUNET_free (tnq);
531 }
532 GNUNET_assert (0 == ts->tmq_length);
533 GNUNET_assert (NULL == ts->destination.heap_node);
534 if (NULL != ts->search)
535 {
537 ts->search = NULL;
538 }
539 if (NULL != ts->heap_node)
540 {
542 ts->heap_node = NULL;
544 ts->protocol,
545 &ts->source_ip,
546 ts->source_port,
547 &ts->destination_ip,
549 &key);
551 GNUNET_YES ==
553 }
554 GNUNET_free (ts);
555}
#define gettext_noop(String)
Definition: gettext.h:70
static void get_channel_key_from_ips(int af, uint8_t protocol, const void *source_ip, uint16_t source_port, const void *destination_ip, uint16_t destination_port, struct GNUNET_HashCode *key)
Compute the key under which we would store an entry in the channel_map for the given socket address p...
static struct GNUNET_CONTAINER_MultiHashMap * channel_map
Map from source and destination address (IP+port) to connection information (mostly with the respecti...
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition: cadet_api.c:830
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
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.
void * GNUNET_CONTAINER_heap_remove_node(struct GNUNET_CONTAINER_HeapNode *node)
Removes a node from the heap.
#define GNUNET_log(kind,...)
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_REGEX_search_cancel(struct GNUNET_REGEX_Search *s)
Stop search and free all data used by a GNUNET_REGEX_search call.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
A messages we have in queue for a particular channel.
unsigned int tmq_length
Length of the doubly linked 'tmq_head/tmq_tail' list.
struct DestinationEntry destination
Destination to which this channel leads.
struct GNUNET_REGEX_Search * search
Active query with REGEX to locate exit.
struct ChannelMessageQueueEntry * tmq_head
Head of list of messages scheduled for transmission.
struct ChannelMessageQueueEntry * tmq_tail
Tail of list of messages scheduled for transmission.
union ChannelState::@71 destination_ip
Destination IP address used by the source on our end (this is the IP that we pick freely within the V...
int af
Address family used for this channel on the local TUN interface.
union ChannelState::@70 source_ip
IP address of the source on our end, initially uninitialized.
uint16_t source_port
Source port used by the sender on our end; 0 for uninitialized.
struct GNUNET_CADET_Channel * channel
Cadet channel that is used for this connection.
struct GNUNET_CONTAINER_HeapNode * heap_node
Heap node for this state in the connections_heap.
uint8_t protocol
IPPROTO_TCP or IPPROTO_UDP once bound.
uint16_t destination_port
Destination port used by the sender on our end; 0 for uninitialized.
struct GNUNET_CONTAINER_HeapNode * heap_node
Entry for this entry in the destination_heap.
Opaque handle to a channel.
Definition: cadet.h:116

References ChannelState::af, ChannelState::channel, channel_map, ChannelState::destination, ChannelState::destination_ip, ChannelState::destination_port, get_channel_key_from_ips(), gettext_noop, GNUNET_assert, GNUNET_CADET_channel_destroy(), GNUNET_CONTAINER_DLL_remove, GNUNET_CONTAINER_heap_remove_node(), GNUNET_CONTAINER_multihashmap_remove(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_NO, GNUNET_REGEX_search_cancel(), GNUNET_STATISTICS_update(), GNUNET_YES, ChannelState::heap_node, DestinationEntry::heap_node, key, ChannelState::protocol, ChannelState::search, ChannelState::source_ip, ChannelState::source_port, stats, ChannelState::tmq_head, ChannelState::tmq_length, and ChannelState::tmq_tail.

Referenced by channel_cleaner(), cleanup_channel(), and expire_channel().

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

◆ send_to_channel()

static void send_to_channel ( struct ChannelState ts,
struct GNUNET_MQ_Envelope env 
)
static

Add the given message to the given channel and trigger the transmission process.

Parameters
tschannel to queue the message for
envmessage to queue

Definition at line 566 of file gnunet-service-vpn.c.

567{
568 struct GNUNET_MQ_Handle *mq;
569
570 GNUNET_assert (NULL != ts->channel);
577 {
579 GNUNET_assert (NULL != env);
582 "# Messages dropped in cadet queue (overflow)"),
583 1,
584 GNUNET_NO);
586 }
587}
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
#define MAX_MESSAGE_QUEUE_SIZE
Maximum number of messages we allow in the queue for cadet.
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
void GNUNET_MQ_env_set_options(struct GNUNET_MQ_Envelope *env, enum GNUNET_MQ_PriorityPreferences pp)
Set application-specific options for this envelope.
Definition: mq.c:830
unsigned int GNUNET_MQ_get_length(struct GNUNET_MQ_Handle *mq)
Obtain the current length of the message queue.
Definition: mq.c:293
struct GNUNET_MQ_Envelope * GNUNET_MQ_unsent_head(struct GNUNET_MQ_Handle *mq)
Remove the first envelope that has not yet been sent from the message queue and return it.
Definition: mq.c:344
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition: mq.c:285
@ GNUNET_MQ_PREF_OUT_OF_ORDER
Flag to indicate that out-of-order delivery is OK.
@ GNUNET_MQ_PRIO_BEST_EFFORT
Best-effort traffic (e.g.
Handle to a message queue.
Definition: mq.c:87

References ChannelState::channel, env, gettext_noop, GNUNET_assert, GNUNET_CADET_get_mq(), GNUNET_MQ_discard(), GNUNET_MQ_env_set_options(), GNUNET_MQ_get_length(), GNUNET_MQ_PREF_OUT_OF_ORDER, GNUNET_MQ_PRIO_BEST_EFFORT, GNUNET_MQ_send(), GNUNET_MQ_unsent_head(), GNUNET_NO, GNUNET_STATISTICS_update(), MAX_MESSAGE_QUEUE_SIZE, mq, and stats.

Referenced by route_packet().

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

◆ print_channel_destination()

static const char * print_channel_destination ( const struct DestinationEntry de)
static

Output destination of a channel for diagnostics.

Parameters
dedestination to process
Returns
diagnostic string describing destination

Definition at line 597 of file gnunet-service-vpn.c.

598{
599 static char dest[256];
600
601 if (de->is_service)
602 {
604 sizeof(dest),
605 "HS: %s-%s",
607 GNUNET_h2s (
609 }
610 else
611 {
612 inet_ntop (de->details.exit_destination.af,
614 dest,
615 sizeof(dest));
616 }
617 return dest;
618}
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
int GNUNET_snprintf(char *buf, size_t size, const char *format,...) __attribute__((format(printf
Like snprintf, just aborts if the buffer is of insufficient size.
int af
Address family used (AF_INET or AF_INET6).
struct GNUNET_PeerIdentity target
Peer offering the service.
union DestinationEntry::@66::@68::@69 ip
IP address of the ultimate destination (only used for exit channels).
struct DestinationEntry::@66::@68 exit_destination
union DestinationEntry::@66 details
Details about the connection (depending on is_service).
struct GNUNET_HashCode service_descriptor
The description of the service (only used for service channels).
struct DestinationEntry::@66::@67 service_destination
int is_service
GNUNET_NO if this is a channel to an Internet-exit, GNUNET_YES if this channel is to a service.

References DestinationEntry::af, warningfilter::dest, DestinationEntry::details, DestinationEntry::exit_destination, GNUNET_h2s(), GNUNET_i2s(), GNUNET_snprintf(), DestinationEntry::ip, DestinationEntry::is_service, DestinationEntry::service_descriptor, DestinationEntry::service_destination, and DestinationEntry::target.

Referenced by channel_cleaner(), cleanup_channel(), expire_channel(), free_destination_entry(), handle_regex_result(), and route_packet().

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

◆ channel_cleaner()

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

Function called whenever a channel is destroyed.

Should clean up any associated state.

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

Definition at line 629 of file gnunet-service-vpn.c.

630{
631 struct ChannelState *ts = cls;
632
633 ts->channel =
634 NULL; /* we must not call GNUNET_CADET_channel_destroy() anymore */
636 "CADET notified us about death of channel to `%s'\n",
639}
static const char * print_channel_destination(const struct DestinationEntry *de)
Output destination of a channel for diagnostics.
static void free_channel_state(struct ChannelState *ts)
Free resources associated with a channel state.
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...

References ChannelState::channel, ChannelState::destination, free_channel_state(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, and print_channel_destination().

Referenced by create_channel().

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

◆ make_up_icmpv4_payload()

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

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

Parameters
tschannel information
ippIPv4 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 652 of file gnunet-service-vpn.c.

655{
657 ts->protocol,
658 sizeof(struct GNUNET_TUN_TcpHeader),
659 &ts->source_ip.v4,
660 &ts->destination_ip.v4);
661 udp->source_port = htons (ts->source_port);
662 udp->destination_port = htons (ts->destination_port);
663 udp->len = htons (0);
664 udp->crc = htons (0);
665}
static int udp
Option -u: UDP requested.
Definition: gnunet-vpn.c:75
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
struct in_addr v4
Address if af is AF_INET.
TCP packet header.

References ChannelState::destination_ip, ChannelState::destination_port, GNUNET_TUN_initialize_ipv4_header(), ChannelState::protocol, ChannelState::source_ip, ChannelState::source_port, udp, and ChannelState::v4.

Referenced by handle_icmp_back().

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 ts,
struct GNUNET_TUN_IPv6Header ipp,
struct GNUNET_TUN_UdpHeader udp 
)
static

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

Parameters
tschannel 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 678 of file gnunet-service-vpn.c.

681{
683 ts->protocol,
684 sizeof(struct GNUNET_TUN_TcpHeader),
685 &ts->source_ip.v6,
686 &ts->destination_ip.v6);
687 udp->source_port = htons (ts->source_port);
688 udp->destination_port = htons (ts->destination_port);
689 udp->len = htons (0);
690 udp->crc = htons (0);
691}
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
struct in6_addr v6
Address if af is AF_INET6.

References ChannelState::destination_ip, ChannelState::destination_port, GNUNET_TUN_initialize_ipv6_header(), ChannelState::protocol, ChannelState::source_ip, ChannelState::source_port, udp, and ChannelState::v6.

Referenced by handle_icmp_back().

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

◆ check_icmp_back()

static int check_icmp_back ( void *  cls,
const struct GNUNET_EXIT_IcmpToVPNMessage i2v 
)
static

We got an ICMP packet back from the CADET channel.

Check it is OK.

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

Definition at line 703 of file gnunet-service-vpn.c.

704{
705 struct ChannelState *ts = cls;
706
707 if (NULL == ts->heap_node)
708 {
709 GNUNET_break_op (0);
710 return GNUNET_SYSERR;
711 }
712 if (AF_UNSPEC == ts->af)
713 {
714 GNUNET_break_op (0);
715 return GNUNET_SYSERR;
716 }
717 return GNUNET_OK;
718}
@ GNUNET_OK
@ GNUNET_SYSERR
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.

References ChannelState::af, GNUNET_break_op, GNUNET_OK, GNUNET_SYSERR, and ChannelState::heap_node.

◆ handle_icmp_back()

static void handle_icmp_back ( void *  cls,
const struct GNUNET_EXIT_IcmpToVPNMessage i2v 
)
static

We got an ICMP packet back from the CADET channel.

Pass it on to the local virtual interface via the helper.

Parameters
clsour struct ChannelState *
i2vthe actual message

Definition at line 729 of file gnunet-service-vpn.c.

730{
731 struct ChannelState *ts = cls;
732 size_t mlen;
733
735 gettext_noop ("# ICMP packets received from cadet"),
736 1,
737 GNUNET_NO);
738 mlen =
739 ntohs (i2v->header.size) - sizeof(struct GNUNET_EXIT_IcmpToVPNMessage);
740 {
741 char sbuf[INET6_ADDRSTRLEN];
742 char dbuf[INET6_ADDRSTRLEN];
743
744 GNUNET_log (
746 "Received ICMP packet from cadet, sending %u bytes from %s -> %s via TUN\n",
747 (unsigned int) mlen,
748 inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof(sbuf)),
749 inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof(dbuf)));
750 }
751 switch (ts->af)
752 {
753 case AF_INET: {
754 size_t size = sizeof(struct GNUNET_TUN_IPv4Header)
755 + sizeof(struct GNUNET_TUN_IcmpHeader)
756 + sizeof(struct GNUNET_MessageHeader)
757 + sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
758 {
759 /* reserve some extra space in case we have an ICMP type here where
760 we will need to make up the payload ourselves */
761 char buf[size + sizeof(struct GNUNET_TUN_IPv4Header) + 8] GNUNET_ALIGN;
762 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
764 (struct GNUNET_TUN_Layer2PacketHeader *) &msg[1];
766 (struct GNUNET_TUN_IPv4Header *) &tun[1];
767 struct GNUNET_TUN_IcmpHeader *icmp =
768 (struct GNUNET_TUN_IcmpHeader *) &ipv4[1];
770 tun->flags = htons (0);
771 tun->proto = htons (ETH_P_IPV4);
773 IPPROTO_ICMP,
774 sizeof(struct GNUNET_TUN_IcmpHeader)
775 + mlen,
776 &ts->destination_ip.v4,
777 &ts->source_ip.v4);
778 *icmp = i2v->icmp_header;
779 GNUNET_memcpy (&icmp[1], &i2v[1], mlen);
780 /* For some ICMP types, we need to adjust (make up) the payload here.
781 Also, depending on the AF used on the other side, we have to
782 do ICMP PT (translate ICMP types) */
783 switch (ntohl (i2v->af))
784 {
785 case AF_INET:
786 switch (icmp->type)
787 {
790 break;
791
795 struct GNUNET_TUN_IPv4Header *ipp =
796 (struct GNUNET_TUN_IPv4Header *) &icmp[1];
797 struct GNUNET_TUN_UdpHeader *udp =
798 (struct GNUNET_TUN_UdpHeader *) &ipp[1];
799
800 if (mlen != 0)
801 {
802 /* sender did not strip ICMP payload? */
803 GNUNET_break_op (0);
804 return;
805 }
806 size += sizeof(struct GNUNET_TUN_IPv4Header) + 8;
807 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
808 make_up_icmpv4_payload (ts, ipp, udp);
809 }
810 break;
811
812 default:
813 GNUNET_break_op (0);
815 stats,
816 gettext_noop ("# ICMPv4 packets dropped (type not allowed)"),
817 1,
818 GNUNET_NO);
819 return;
820 }
821 /* end AF_INET */
822 break;
823
824 case AF_INET6:
825 /* ICMP PT 6-to-4 and possibly making up payloads */
826 switch (icmp->type)
827 {
830 {
831 struct GNUNET_TUN_IPv4Header *ipp =
832 (struct GNUNET_TUN_IPv4Header *) &icmp[1];
833 struct GNUNET_TUN_UdpHeader *udp =
834 (struct GNUNET_TUN_UdpHeader *) &ipp[1];
835
836 if (mlen != 0)
837 {
838 /* sender did not strip ICMP payload? */
839 GNUNET_break_op (0);
840 return;
841 }
842 size += sizeof(struct GNUNET_TUN_IPv4Header) + 8;
843 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
844 make_up_icmpv4_payload (ts, ipp, udp);
845 }
846 break;
847
850 {
851 struct GNUNET_TUN_IPv4Header *ipp =
852 (struct GNUNET_TUN_IPv4Header *) &icmp[1];
853 struct GNUNET_TUN_UdpHeader *udp =
854 (struct GNUNET_TUN_UdpHeader *) &ipp[1];
855
856 if (mlen != 0)
857 {
858 /* sender did not strip ICMP payload? */
859 GNUNET_break_op (0);
860 return;
861 }
862 size += sizeof(struct GNUNET_TUN_IPv4Header) + 8;
863 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
864 make_up_icmpv4_payload (ts, ipp, udp);
865 }
866 break;
867
871 stats,
872 gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"),
873 1,
874 GNUNET_NO);
875 return;
876
879 break;
880
883 break;
884
885 default:
886 GNUNET_break_op (0);
888 stats,
889 gettext_noop ("# ICMPv6 packets dropped (type not allowed)"),
890 1,
891 GNUNET_NO);
892 return;
893 }
894 /* end AF_INET6 */
895 break;
896
897 default:
898 GNUNET_break_op (0);
899 return;
900 }
901 msg->size = htons (size);
902 GNUNET_TUN_calculate_icmp_checksum (icmp, &i2v[1], mlen);
903 (void) GNUNET_HELPER_send (helper_handle, msg, GNUNET_YES, NULL, NULL);
904 }
905 }
906 break;
907
908 case AF_INET6: {
909 size_t size = sizeof(struct GNUNET_TUN_IPv6Header)
910 + sizeof(struct GNUNET_TUN_IcmpHeader)
911 + sizeof(struct GNUNET_MessageHeader)
912 + sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
913 {
914 char buf[size + sizeof(struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
915 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
917 (struct GNUNET_TUN_Layer2PacketHeader *) &msg[1];
919 (struct GNUNET_TUN_IPv6Header *) &tun[1];
920 struct GNUNET_TUN_IcmpHeader *icmp =
921 (struct GNUNET_TUN_IcmpHeader *) &ipv6[1];
923 tun->flags = htons (0);
924 tun->proto = htons (ETH_P_IPV6);
926 IPPROTO_ICMPV6,
927 sizeof(struct GNUNET_TUN_IcmpHeader)
928 + mlen,
929 &ts->destination_ip.v6,
930 &ts->source_ip.v6);
931 *icmp = i2v->icmp_header;
932 GNUNET_memcpy (&icmp[1], &i2v[1], mlen);
933
934 /* For some ICMP types, we need to adjust (make up) the payload here.
935 Also, depending on the AF used on the other side, we have to
936 do ICMP PT (translate ICMP types) */
937 switch (ntohl (i2v->af))
938 {
939 case AF_INET:
940 /* ICMP PT 4-to-6 and possibly making up payloads */
941 switch (icmp->type)
942 {
945 break;
946
949 break;
950
953 {
954 struct GNUNET_TUN_IPv6Header *ipp =
955 (struct GNUNET_TUN_IPv6Header *) &icmp[1];
956 struct GNUNET_TUN_UdpHeader *udp =
957 (struct GNUNET_TUN_UdpHeader *) &ipp[1];
958
959 if (mlen != 0)
960 {
961 /* sender did not strip ICMP payload? */
962 GNUNET_break_op (0);
963 return;
964 }
965 size += sizeof(struct GNUNET_TUN_IPv6Header) + 8;
966 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
967 make_up_icmpv6_payload (ts, ipp, udp);
968 }
969 break;
970
973 {
974 struct GNUNET_TUN_IPv6Header *ipp =
975 (struct GNUNET_TUN_IPv6Header *) &icmp[1];
976 struct GNUNET_TUN_UdpHeader *udp =
977 (struct GNUNET_TUN_UdpHeader *) &ipp[1];
978
979 if (mlen != 0)
980 {
981 /* sender did not strip ICMP payload? */
982 GNUNET_break_op (0);
983 return;
984 }
985 size += sizeof(struct GNUNET_TUN_IPv6Header) + 8;
986 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
987 make_up_icmpv6_payload (ts, ipp, udp);
988 }
989 break;
990
993 stats,
994 gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"),
995 1,
996 GNUNET_NO);
997 return;
998
999 default:
1000 GNUNET_break_op (0);
1002 stats,
1003 gettext_noop ("# ICMPv4 packets dropped (type not allowed)"),
1004 1,
1005 GNUNET_NO);
1006 return;
1007 }
1008 /* end AF_INET */
1009 break;
1010
1011 case AF_INET6:
1012 switch (icmp->type)
1013 {
1018 struct GNUNET_TUN_IPv6Header *ipp =
1019 (struct GNUNET_TUN_IPv6Header *) &icmp[1];
1020 struct GNUNET_TUN_UdpHeader *udp =
1021 (struct GNUNET_TUN_UdpHeader *) &ipp[1];
1022
1023 if (mlen != 0)
1024 {
1025 /* sender did not strip ICMP payload? */
1026 GNUNET_break_op (0);
1027 return;
1028 }
1029 size += sizeof(struct GNUNET_TUN_IPv6Header) + 8;
1030 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
1031 make_up_icmpv6_payload (ts, ipp, udp);
1032 }
1033 break;
1034
1036 break;
1037
1038 default:
1039 GNUNET_break_op (0);
1041 stats,
1042 gettext_noop ("# ICMPv6 packets dropped (type not allowed)"),
1043 1,
1044 GNUNET_NO);
1045 return;
1046 }
1047 /* end AF_INET6 */
1048 break;
1049
1050 default:
1051 GNUNET_break_op (0);
1052 return;
1053 }
1054 msg->size = htons (size);
1055 GNUNET_TUN_calculate_icmp_checksum (icmp, &i2v[1], mlen);
1056 (void) GNUNET_HELPER_send (helper_handle, msg, GNUNET_YES, NULL, NULL);
1057 }
1058 }
1059 break;
1060
1061 default:
1062 GNUNET_assert (0);
1063 }
1065 GNUNET_TIME_absolute_get ().abs_value_us);
1067}
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static void make_up_icmpv6_payload(struct ChannelState *ts, struct GNUNET_TUN_IPv6Header *ipp, struct GNUNET_TUN_UdpHeader *udp)
Synthesize a plausible ICMP payload for an ICMP error response on the given channel.
static void make_up_icmpv4_payload(struct ChannelState *ts, struct GNUNET_TUN_IPv4Header *ipp, struct GNUNET_TUN_UdpHeader *udp)
Synthesize a plausible ICMP payload for an ICMP error response on the given channel.
static struct GNUNET_HELPER_Handle * helper_handle
The handle to the VPN helper process "gnunet-helper-vpn".
static int ipv4
Option -4: IPv4 requested.
Definition: gnunet-vpn.c:60
static int ipv6
Option -6: IPv6 requested.
Definition: gnunet-vpn.c:65
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
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_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_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.
#define GNUNET_MESSAGE_TYPE_VPN_HELPER
Type of messages between the gnunet-vpn-helper and the daemon.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:111
#define GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM
void GNUNET_TUN_calculate_icmp_checksum(struct GNUNET_TUN_IcmpHeader *icmp, const void *payload, uint16_t payload_length)
Calculate ICMP checksum.
Definition: tun.c:222
#define GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST
#define GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED
#define GNUNET_TUN_ICMPTYPE6_ECHO_REPLY
#define ETH_P_IPV6
Number for IPv6.
#define ETH_P_IPV4
Number for IPv4.
#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
static unsigned int size
Size of the "table".
Definition: peer.c:68
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
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_VPN.
Definition: exit.h:276
Header for all communications.
Standard IPv4 header.
Standard IPv6 header.
Header from Linux TUN interface.
uint16_t proto
Here we get an ETH_P_-number.
uint16_t flags
Some flags (unused).
UDP packet header.

References GNUNET_EXIT_IcmpToVPNMessage::af, ChannelState::af, ChannelState::channel, ChannelState::destination_ip, ETH_P_IPV4, ETH_P_IPV6, GNUNET_TUN_Layer2PacketHeader::flags, gettext_noop, GNUNET_ALIGN, GNUNET_assert, GNUNET_break_op, GNUNET_CADET_receive_done(), GNUNET_CONTAINER_heap_update_cost(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_HELPER_send(), GNUNET_log, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_VPN_HELPER, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_TIME_absolute_get(), GNUNET_TUN_calculate_icmp_checksum(), 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_TUN_initialize_ipv4_header(), GNUNET_TUN_initialize_ipv6_header(), GNUNET_YES, GNUNET_EXIT_IcmpToVPNMessage::header, ChannelState::heap_node, helper_handle, GNUNET_EXIT_IcmpToVPNMessage::icmp_header, ipv4, ipv6, make_up_icmpv4_payload(), make_up_icmpv6_payload(), msg, GNUNET_TUN_Layer2PacketHeader::proto, GNUNET_MessageHeader::size, size, ChannelState::source_ip, stats, GNUNET_MessageHeader::type, GNUNET_TUN_IcmpHeader::type, udp, ChannelState::v4, and ChannelState::v6.

Here is the call graph for this function:

◆ check_udp_back()

static int check_udp_back ( void *  cls,
const struct GNUNET_EXIT_UdpReplyMessage reply 
)
static

We got a UDP packet back from the CADET channel.

Check that it is OK.

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

Definition at line 1079 of file gnunet-service-vpn.c.

1080{
1081 struct ChannelState *ts = cls;
1082
1083 if (NULL == ts->heap_node)
1084 {
1085 GNUNET_break_op (0);
1086 return GNUNET_SYSERR;
1087 }
1088 if (AF_UNSPEC == ts->af)
1089 {
1090 GNUNET_break_op (0);
1091 return GNUNET_SYSERR;
1092 }
1093 return GNUNET_OK;
1094}

References ChannelState::af, GNUNET_break_op, GNUNET_OK, GNUNET_SYSERR, and ChannelState::heap_node.

◆ handle_udp_back()

static void handle_udp_back ( void *  cls,
const struct GNUNET_EXIT_UdpReplyMessage reply 
)
static

We got a UDP packet back from the CADET channel.

Pass it on to the local virtual interface via the helper.

Parameters
clsour struct ChannelState *
replythe actual message

Definition at line 1105 of file gnunet-service-vpn.c.

1106{
1107 struct ChannelState *ts = cls;
1108 size_t mlen;
1109
1111 gettext_noop ("# UDP packets received from cadet"),
1112 1,
1113 GNUNET_NO);
1114 mlen =
1115 ntohs (reply->header.size) - sizeof(struct GNUNET_EXIT_UdpReplyMessage);
1116 {
1117 char sbuf[INET6_ADDRSTRLEN];
1118 char dbuf[INET6_ADDRSTRLEN];
1119
1120 GNUNET_log (
1122 "Received UDP reply from cadet, sending %u bytes from [%s]:%u -> [%s]:%u via TUN\n",
1123 (unsigned int) mlen,
1124 inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof(sbuf)),
1125 ts->destination_port,
1126 inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof(dbuf)),
1127 ts->source_port);
1128 }
1129 switch (ts->af)
1130 {
1131 case AF_INET: {
1132 size_t size = sizeof(struct GNUNET_TUN_IPv4Header)
1133 + sizeof(struct GNUNET_TUN_UdpHeader)
1134 + sizeof(struct GNUNET_MessageHeader)
1135 + sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
1136 {
1137 char buf[size] GNUNET_ALIGN;
1138 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
1139 struct GNUNET_TUN_Layer2PacketHeader *tun =
1140 (struct GNUNET_TUN_Layer2PacketHeader *) &msg[1];
1141 struct GNUNET_TUN_IPv4Header *ipv4 =
1142 (struct GNUNET_TUN_IPv4Header *) &tun[1];
1143 struct GNUNET_TUN_UdpHeader *udp =
1144 (struct GNUNET_TUN_UdpHeader *) &ipv4[1];
1146 msg->size = htons (size);
1147 tun->flags = htons (0);
1148 tun->proto = htons (ETH_P_IPV4);
1150 IPPROTO_UDP,
1151 sizeof(struct GNUNET_TUN_UdpHeader)
1152 + mlen,
1153 &ts->destination_ip.v4,
1154 &ts->source_ip.v4);
1155 if (0 == ntohs (reply->source_port))
1156 udp->source_port = htons (ts->destination_port);
1157 else
1158 udp->source_port = reply->source_port;
1159 if (0 == ntohs (reply->destination_port))
1160 udp->destination_port = htons (ts->source_port);
1161 else
1162 udp->destination_port = reply->destination_port;
1163 udp->len = htons (mlen + sizeof(struct GNUNET_TUN_UdpHeader));
1164 GNUNET_TUN_calculate_udp4_checksum (ipv4, udp, &reply[1], mlen);
1165 GNUNET_memcpy (&udp[1], &reply[1], mlen);
1166 (void) GNUNET_HELPER_send (helper_handle, msg, GNUNET_YES, NULL, NULL);
1167 }
1168 }
1169 break;
1170
1171 case AF_INET6: {
1172 size_t size = sizeof(struct GNUNET_TUN_IPv6Header)
1173 + sizeof(struct GNUNET_TUN_UdpHeader)
1174 + sizeof(struct GNUNET_MessageHeader)
1175 + sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
1176 {
1177 char buf[size] GNUNET_ALIGN;
1178 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
1179 struct GNUNET_TUN_Layer2PacketHeader *tun =
1180 (struct GNUNET_TUN_Layer2PacketHeader *) &msg[1];
1181 struct GNUNET_TUN_IPv6Header *ipv6 =
1182 (struct GNUNET_TUN_IPv6Header *) &tun[1];
1183 struct GNUNET_TUN_UdpHeader *udp =
1184 (struct GNUNET_TUN_UdpHeader *) &ipv6[1];
1186 msg->size = htons (size);
1187 tun->flags = htons (0);
1188 tun->proto = htons (ETH_P_IPV6);
1190 IPPROTO_UDP,
1191 sizeof(struct GNUNET_TUN_UdpHeader)
1192 + mlen,
1193 &ts->destination_ip.v6,
1194 &ts->source_ip.v6);
1195 if (0 == ntohs (reply->source_port))
1196 udp->source_port = htons (ts->destination_port);
1197 else
1198 udp->source_port = reply->source_port;
1199 if (0 == ntohs (reply->destination_port))
1200 udp->destination_port = htons (ts->source_port);
1201 else
1202 udp->destination_port = reply->destination_port;
1203 udp->len = htons (mlen + sizeof(struct GNUNET_TUN_UdpHeader));
1204 GNUNET_TUN_calculate_udp6_checksum (ipv6, udp, &reply[1], mlen);
1205 GNUNET_memcpy (&udp[1], &reply[1], mlen);
1206 (void) GNUNET_HELPER_send (helper_handle, msg, GNUNET_YES, NULL, NULL);
1207 }
1208 }
1209 break;
1210
1211 default:
1212 GNUNET_assert (0);
1213 }
1215 GNUNET_TIME_absolute_get ().abs_value_us);
1217}
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
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
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
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY.
Definition: exit.h:183
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 ChannelState::af, ChannelState::channel, ChannelState::destination_ip, GNUNET_EXIT_UdpReplyMessage::destination_port, ChannelState::destination_port, ETH_P_IPV4, ETH_P_IPV6, GNUNET_TUN_Layer2PacketHeader::flags, gettext_noop, GNUNET_ALIGN, GNUNET_assert, GNUNET_CADET_receive_done(), GNUNET_CONTAINER_heap_update_cost(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_HELPER_send(), GNUNET_log, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_VPN_HELPER, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_TIME_absolute_get(), GNUNET_TUN_calculate_udp4_checksum(), GNUNET_TUN_calculate_udp6_checksum(), GNUNET_TUN_initialize_ipv4_header(), GNUNET_TUN_initialize_ipv6_header(), GNUNET_YES, GNUNET_EXIT_UdpReplyMessage::header, ChannelState::heap_node, helper_handle, ipv4, ipv6, msg, GNUNET_TUN_Layer2PacketHeader::proto, GNUNET_MessageHeader::size, size, ChannelState::source_ip, GNUNET_EXIT_UdpReplyMessage::source_port, ChannelState::source_port, stats, GNUNET_MessageHeader::type, udp, ChannelState::v4, and ChannelState::v6.

Here is the call graph for this function:

◆ check_tcp_back()

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

We got a TCP packet back from the CADET channel.

Check it is OK.

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 1229 of file gnunet-service-vpn.c.

1230{
1231 struct ChannelState *ts = cls;
1232
1233 if (NULL == ts->heap_node)
1234 {
1235 GNUNET_break_op (0);
1236 return GNUNET_SYSERR;
1237 }
1238 if (data->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
1239 {
1240 GNUNET_break_op (0);
1241 return GNUNET_SYSERR;
1242 }
1243 return GNUNET_OK;
1244}
static char * data
The data to insert into the dht.

References data, GNUNET_break_op, GNUNET_OK, GNUNET_SYSERR, and ChannelState::heap_node.

◆ handle_tcp_back()

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

We got a TCP packet back from the CADET channel.

Pass it on to the local virtual interface via the helper.

Parameters
clsour struct ChannelState *
datathe actual message

Definition at line 1255 of file gnunet-service-vpn.c.

1256{
1257 struct ChannelState *ts = cls;
1258 size_t mlen;
1259
1261 gettext_noop ("# TCP packets received from cadet"),
1262 1,
1263 GNUNET_NO);
1264 mlen = ntohs (data->header.size) - sizeof(struct GNUNET_EXIT_TcpDataMessage);
1265 {
1266 char sbuf[INET6_ADDRSTRLEN];
1267 char dbuf[INET6_ADDRSTRLEN];
1268
1269 GNUNET_log (
1271 "Received TCP reply from cadet, sending %u bytes from [%s]:%u -> [%s]:%u via TUN\n",
1272 (unsigned int) mlen,
1273 inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof(sbuf)),
1274 ts->destination_port,
1275 inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof(dbuf)),
1276 ts->source_port);
1277 }
1278 switch (ts->af)
1279 {
1280 case AF_INET: {
1281 size_t size = sizeof(struct GNUNET_TUN_IPv4Header)
1282 + sizeof(struct GNUNET_TUN_TcpHeader)
1283 + sizeof(struct GNUNET_MessageHeader)
1284 + sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
1285 {
1286 char buf[size] GNUNET_ALIGN;
1287 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
1288 struct GNUNET_TUN_Layer2PacketHeader *tun =
1289 (struct GNUNET_TUN_Layer2PacketHeader *) &msg[1];
1290 struct GNUNET_TUN_IPv4Header *ipv4 =
1291 (struct GNUNET_TUN_IPv4Header *) &tun[1];
1292 struct GNUNET_TUN_TcpHeader *tcp =
1293 (struct GNUNET_TUN_TcpHeader *) &ipv4[1];
1295 msg->size = htons (size);
1296 tun->flags = htons (0);
1297 tun->proto = htons (ETH_P_IPV4);
1299 IPPROTO_TCP,
1300 sizeof(struct GNUNET_TUN_TcpHeader)
1301 + mlen,
1302 &ts->destination_ip.v4,
1303 &ts->source_ip.v4);
1304 *tcp = data->tcp_header;
1305 tcp->source_port = htons (ts->destination_port);
1306 tcp->destination_port = htons (ts->source_port);
1308 GNUNET_memcpy (&tcp[1], &data[1], mlen);
1309 (void) GNUNET_HELPER_send (helper_handle, msg, GNUNET_YES, NULL, NULL);
1310 }
1311 }
1312 break;
1313
1314 case AF_INET6: {
1315 size_t size = sizeof(struct GNUNET_TUN_IPv6Header)
1316 + sizeof(struct GNUNET_TUN_TcpHeader)
1317 + sizeof(struct GNUNET_MessageHeader)
1318 + sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
1319 {
1320 char buf[size] GNUNET_ALIGN;
1321 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
1322 struct GNUNET_TUN_Layer2PacketHeader *tun =
1323 (struct GNUNET_TUN_Layer2PacketHeader *) &msg[1];
1324 struct GNUNET_TUN_IPv6Header *ipv6 =
1325 (struct GNUNET_TUN_IPv6Header *) &tun[1];
1326 struct GNUNET_TUN_TcpHeader *tcp =
1327 (struct GNUNET_TUN_TcpHeader *) &ipv6[1];
1329 msg->size = htons (size);
1330 tun->flags = htons (0);
1331 tun->proto = htons (ETH_P_IPV6);
1333 IPPROTO_TCP,
1334 sizeof(struct GNUNET_TUN_TcpHeader)
1335 + mlen,
1336 &ts->destination_ip.v6,
1337 &ts->source_ip.v6);
1338 *tcp = data->tcp_header;
1339 tcp->source_port = htons (ts->destination_port);
1340 tcp->destination_port = htons (ts->source_port);
1342 GNUNET_memcpy (&tcp[1], &data[1], mlen);
1343 (void) GNUNET_HELPER_send (helper_handle, msg, GNUNET_YES, NULL, NULL);
1344 }
1345 }
1346 break;
1347 }
1349 GNUNET_TIME_absolute_get ().abs_value_us);
1351}
static int tcp
Option -t: TCP requested.
Definition: gnunet-vpn.c:70
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_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
Message send via cadet between VPN and entry and an exit daemon to transmit TCP data between the VPN ...
Definition: exit.h:95

References ChannelState::af, ChannelState::channel, data, ChannelState::destination_ip, ChannelState::destination_port, ETH_P_IPV4, ETH_P_IPV6, GNUNET_TUN_Layer2PacketHeader::flags, gettext_noop, GNUNET_ALIGN, GNUNET_CADET_receive_done(), GNUNET_CONTAINER_heap_update_cost(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_HELPER_send(), GNUNET_log, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_VPN_HELPER, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_TIME_absolute_get(), GNUNET_TUN_calculate_tcp4_checksum(), GNUNET_TUN_calculate_tcp6_checksum(), GNUNET_TUN_initialize_ipv4_header(), GNUNET_TUN_initialize_ipv6_header(), GNUNET_YES, ChannelState::heap_node, helper_handle, ipv4, ipv6, msg, GNUNET_TUN_Layer2PacketHeader::proto, GNUNET_MessageHeader::size, size, ChannelState::source_ip, ChannelState::source_port, stats, tcp, GNUNET_MessageHeader::type, ChannelState::v4, and ChannelState::v6.

Here is the call graph for this function:

◆ create_channel()

static struct GNUNET_CADET_Channel * create_channel ( struct ChannelState ts,
const struct GNUNET_PeerIdentity target,
const struct GNUNET_HashCode port 
)
static

Create a channel for ts to target at port.

Parameters
tschannel state to create the channel for
targetpeer to connect to
portdestination port
Returns
the channel handle

Definition at line 1363 of file gnunet-service-vpn.c.

1366{
1367 struct GNUNET_MQ_MessageHandler cadet_handlers[] =
1368 { GNUNET_MQ_hd_var_size (udp_back,
1371 ts),
1372 GNUNET_MQ_hd_var_size (tcp_back,
1375 ts),
1376 GNUNET_MQ_hd_var_size (icmp_back,
1379 ts),
1381
1383 ts,
1384 target,
1385 port,
1386 NULL,
1388 cadet_handlers);
1389}
static uint16_t port
Port number.
Definition: gnunet-bcd.c:147
static struct GNUNET_CADET_Handle * cadet_handle
Handle to the cadet service.
static void channel_cleaner(void *cls, const struct GNUNET_CADET_Channel *channel)
Function called whenever a channel is destroyed.
struct GNUNET_CADET_Channel * GNUNET_CADET_channel_create(struct GNUNET_CADET_Handle *h, void *channel_cls, const struct GNUNET_PeerIdentity *destination, const struct GNUNET_HashCode *port, GNUNET_CADET_WindowSizeEventHandler window_changes, GNUNET_CADET_DisconnectEventHandler disconnects, const struct GNUNET_MQ_MessageHandler *handlers)
Create a new channel towards a remote peer.
Definition: cadet_api.c:1015
#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_UDP_REPLY
Type of messages containing an UDP packet from a remote host.
#define GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_VPN
Type of messages containing an TCP packet of an established connection.
#define GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_VPN
Type of messages containing an ICMP packet for the VPN.
Message handler for a specific message type.

References cadet_handle, channel_cleaner(), GNUNET_CADET_channel_create(), GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_VPN, GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_VPN, GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY, GNUNET_MQ_handler_end, GNUNET_MQ_hd_var_size, and port.

Referenced by create_channel_to_destination(), and handle_regex_result().

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

◆ handle_regex_result()

static void handle_regex_result ( void *  cls,
const struct GNUNET_PeerIdentity id,
const struct GNUNET_PeerIdentity get_path,
unsigned int  get_path_length,
const struct GNUNET_PeerIdentity put_path,
unsigned int  put_path_length 
)
static

Regex has found a potential exit peer for us; consider using it.

Parameters
clsthe struct ChannelState
idPeer providing a regex that matches the string.
get_pathPath of the get request.
get_path_lengthLength of get_path.
put_pathPath of the put request.
put_path_lengthLength of the put_path.

Definition at line 1403 of file gnunet-service-vpn.c.

1409{
1410 struct ChannelState *ts = cls;
1411 struct GNUNET_HashCode port;
1412
1414 "Exit %s found for destination %s!\n",
1415 GNUNET_i2s (id),
1418 ts->search = NULL;
1419 switch (ts->af)
1420 {
1421 case AF_INET:
1422 /* these must match the strings used in gnunet-daemon-exit */
1425 &port);
1426 break;
1427
1428 case AF_INET6:
1429 /* these must match the strings used in gnunet-daemon-exit */
1432 &port);
1433 break;
1434
1435 default:
1436 GNUNET_break (0);
1437 return;
1438 }
1440 "Creating tunnel to %s for destination %s!\n",
1441 GNUNET_i2s (id),
1443 ts->channel = create_channel (ts, id, &port);
1444}
static struct GNUNET_CADET_Channel * create_channel(struct ChannelState *ts, const struct GNUNET_PeerIdentity *target, const struct GNUNET_HashCode *port)
Create a channel for ts to target at port.
#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).
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_INFO

References ChannelState::af, ChannelState::channel, create_channel(), ChannelState::destination, GNUNET_APPLICATION_PORT_IPV4_GATEWAY, GNUNET_APPLICATION_PORT_IPV6_GATEWAY, GNUNET_break, GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_INFO, GNUNET_i2s(), GNUNET_log, GNUNET_REGEX_search_cancel(), port, print_channel_destination(), and ChannelState::search.

Referenced by create_channel_to_destination().

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

◆ create_channel_to_destination()

static struct ChannelState * create_channel_to_destination ( struct DestinationChannel dt,
int  client_af 
)
static

Initialize the given destination entry's cadet channel.

Parameters
dtdestination channel for which we need to setup a channel
client_afaddress family of the address returned to the client
Returns
channel state of the channel that was created

Definition at line 1455 of file gnunet-service-vpn.c.

1456{
1457 struct ChannelState *ts;
1458
1460 gettext_noop ("# Cadet channels created"),
1461 1,
1462 GNUNET_NO);
1463 ts = GNUNET_new (struct ChannelState);
1464 ts->af = client_af;
1465 ts->destination = *dt->destination;
1466 ts->destination.heap_node = NULL; /* copy is NOT in destination heap */
1468 if (dt->destination->is_service)
1469 {
1471
1475 ts->destination_port,
1476 &cadet_port);
1477 ts->channel =
1478 create_channel (ts,
1480 &cadet_port);
1481
1482 if (NULL == ts->channel)
1483 {
1484 GNUNET_break (0);
1485 GNUNET_free (ts);
1486 return NULL;
1487 }
1489 "Creating channel to peer %s offering service %s on port %u\n",
1490 GNUNET_i2s (
1494 (unsigned int) ts->destination_port);
1495 }
1496 else
1497 {
1498 char *policy;
1499
1501 {
1502 case AF_INET: {
1504
1506 .ip.v4,
1507 dt->destination_port,
1508 address);
1509 GNUNET_asprintf (&policy,
1510 "%s%s",
1512 address);
1513 break;
1514 }
1515
1516 case AF_INET6: {
1518
1520 .ip.v6,
1521 dt->destination_port,
1522 address);
1523 GNUNET_asprintf (&policy,
1524 "%s%s",
1526 address);
1527 break;
1528 }
1529
1530 default:
1531 GNUNET_assert (0);
1532 break;
1533 }
1534
1536 "Requesting connect by string: %s\n",
1537 policy);
1538 ts->search = GNUNET_REGEX_search (cfg, policy, &handle_regex_result, ts);
1539 GNUNET_free (policy);
1540 }
1541 return ts;
1542}
static struct GNUNET_CADET_Port * cadet_port
Listen port for incoming requests.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we use.
static void handle_regex_result(void *cls, const struct GNUNET_PeerIdentity *id, const struct GNUNET_PeerIdentity *get_path, unsigned int get_path_length, const struct GNUNET_PeerIdentity *put_path, unsigned int put_path_length)
Regex has found a potential exit peer for us; consider using it.
#define GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX
Internet exit regex prefix.
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
struct GNUNET_REGEX_Search * GNUNET_REGEX_search(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *string, GNUNET_REGEX_Found callback, void *callback_cls)
Search for a peer offering a regex matching certain string in the DHT.
void GNUNET_TUN_ipv6toregexsearch(const struct in6_addr *ipv6, uint16_t port, char *rxstr)
Create a regex in rxstr from the given ipv6 and port.
Definition: regex.c:50
#define GNUNET_TUN_IPV4_REGEXLEN
Maximum regex string length for use with GNUNET_TUN_ipv4toregexsearch.
#define GNUNET_TUN_IPV6_REGEXLEN
Maximum regex string length for use with GNUNET_TUN_ipv6toregexsearch.
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_ipv4toregexsearch(const struct in_addr *ip, uint16_t port, char *rxstr)
Create a regex in rxstr from the given ip and port.
Definition: regex.c:37
uint16_t destination_port
Destination port this channel state is used for.
struct DestinationEntry * destination
Destination entry list this struct DestinationChannel belongs with.
struct in_addr v4
Address if af is AF_INET.
struct in6_addr v6
Address if af is AF_INET6.

References address, DestinationEntry::af, ChannelState::af, cadet_port, cfg, ChannelState::channel, create_channel(), DestinationChannel::destination, ChannelState::destination, DestinationChannel::destination_port, ChannelState::destination_port, DestinationEntry::details, DestinationEntry::exit_destination, gettext_noop, GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX, GNUNET_asprintf(), GNUNET_assert, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_h2s(), GNUNET_i2s(), GNUNET_log, GNUNET_new, GNUNET_NO, GNUNET_REGEX_search(), GNUNET_STATISTICS_update(), GNUNET_TUN_compute_service_cadet_port(), GNUNET_TUN_IPV4_REGEXLEN, GNUNET_TUN_ipv4toregexsearch(), GNUNET_TUN_IPV6_REGEXLEN, GNUNET_TUN_ipv6toregexsearch(), handle_regex_result(), DestinationEntry::heap_node, DestinationEntry::ip, DestinationEntry::is_service, ChannelState::search, DestinationEntry::service_descriptor, DestinationEntry::service_destination, stats, DestinationEntry::target, DestinationEntry::v4, and DestinationEntry::v6.

Referenced by route_packet().

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

◆ expire_channel()

static void expire_channel ( struct ChannelState except)
static

We have too many active channels.

Clean up the oldest channel.

Parameters
exceptchannel that must NOT be cleaned up, even if it is the oldest

Definition at line 1551 of file gnunet-service-vpn.c.

1552{
1553 struct ChannelState *ts;
1554
1556 GNUNET_assert (NULL != ts);
1557 if (except == ts)
1558 return; /* can't do this */
1560 "Tearing down expired channel to %s\n",
1562 free_channel_state (ts);
1563}
static struct GNUNET_CONTAINER_Heap * channel_heap
Min-Heap sorted by activity time to expire old mappings; values are of type 'struct ChannelState'.
void * GNUNET_CONTAINER_heap_peek(const struct GNUNET_CONTAINER_Heap *heap)
Get element stored at the root of heap.

References channel_heap, ChannelState::destination, free_channel_state(), GNUNET_assert, GNUNET_CONTAINER_heap_peek(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, and print_channel_destination().

Referenced by route_packet().

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

◆ route_packet()

static void route_packet ( struct DestinationEntry destination,
int  af,
uint8_t  protocol,
const void *  source_ip,
const void *  destination_ip,
const void *  payload,
size_t  payload_length 
)
static

Route a packet via cadet to the given destination.

Parameters
destinationdescription of the destination
afaddress family on this end (AF_INET or AF_INET6)
protocolIPPROTO_TCP or IPPROTO_UDP or IPPROTO_ICMP or IPPROTO_ICMPV6
source_ipsource IP used by the sender (struct in_addr or struct in6_addr)
destination_ipdestination IP used by the sender (struct in_addr or struct in6_addr)
payloadpayload of the packet after the IP header
payload_lengthnumber of bytes in payload

Definition at line 1578 of file gnunet-service-vpn.c.

1585{
1586 struct GNUNET_HashCode key;
1587 struct ChannelState *ts;
1588 size_t alen;
1589 size_t mlen;
1590 struct GNUNET_MQ_Envelope *env;
1591 const struct GNUNET_TUN_UdpHeader *udp;
1592 const struct GNUNET_TUN_TcpHeader *tcp;
1593 const struct GNUNET_TUN_IcmpHeader *icmp;
1594 struct DestinationChannel *dt;
1595 uint16_t source_port;
1596 uint16_t destination_port;
1597
1598 switch (protocol)
1599 {
1600 case IPPROTO_UDP: {
1601 if (payload_length < sizeof(struct GNUNET_TUN_UdpHeader))
1602 {
1603 /* blame kernel? */
1604 GNUNET_break (0);
1605 return;
1606 }
1607 tcp = NULL; /* make compiler happy */
1608 icmp = NULL; /* make compiler happy */
1609 udp = payload;
1610 if (udp->len < sizeof(struct GNUNET_TUN_UdpHeader))
1611 {
1612 GNUNET_break_op (0);
1613 return;
1614 }
1615 source_port = ntohs (udp->source_port);
1616 destination_port = ntohs (udp->destination_port);
1618 IPPROTO_UDP,
1619 source_ip,
1620 source_port,
1621 destination_ip,
1623 &key);
1624 }
1625 break;
1626
1627 case IPPROTO_TCP: {
1628 if (payload_length < sizeof(struct GNUNET_TUN_TcpHeader))
1629 {
1630 /* blame kernel? */
1631 GNUNET_break (0);
1632 return;
1633 }
1634 udp = NULL; /* make compiler happy */
1635 icmp = NULL; /* make compiler happy */
1636 tcp = payload;
1637 if (tcp->off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
1638 {
1639 GNUNET_break_op (0);
1640 return;
1641 }
1642 source_port = ntohs (tcp->source_port);
1643 destination_port = ntohs (tcp->destination_port);
1645 IPPROTO_TCP,
1646 source_ip,
1647 source_port,
1648 destination_ip,
1650 &key);
1651 }
1652 break;
1653
1654 case IPPROTO_ICMP:
1655 case IPPROTO_ICMPV6: {
1656 if ((AF_INET == af) ^ (protocol == IPPROTO_ICMP))
1657 {
1658 GNUNET_break (0);
1659 return;
1660 }
1661 if (payload_length < sizeof(struct GNUNET_TUN_IcmpHeader))
1662 {
1663 /* blame kernel? */
1664 GNUNET_break (0);
1665 return;
1666 }
1667 tcp = NULL; /* make compiler happy */
1668 udp = NULL; /* make compiler happy */
1669 icmp = payload;
1670 source_port = 0;
1671 destination_port = 0;
1673 protocol,
1674 source_ip,
1675 0,
1676 destination_ip,
1677 0,
1678 &key);
1679 }
1680 break;
1681
1682 default:
1684 _ ("Protocol %u not supported, dropping\n"),
1685 (unsigned int) protocol);
1686 return;
1687 }
1688 alen = 0;
1689 if (! destination->is_service)
1690 {
1692 {
1693 case AF_INET:
1694 alen = sizeof(struct in_addr);
1695 break;
1696
1697 case AF_INET6:
1698 alen = sizeof(struct in6_addr);
1699 break;
1700
1701 default:
1702 GNUNET_assert (0);
1703 }
1704
1705 {
1706 char sbuf[INET6_ADDRSTRLEN];
1707 char dbuf[INET6_ADDRSTRLEN];
1708 char xbuf[INET6_ADDRSTRLEN];
1709
1710 GNUNET_log (
1712 "Routing %s packet from [%s]:%u -> [%s]:%u to destination [%s]:%u\n",
1713 (protocol == IPPROTO_TCP) ? "TCP" : "UDP",
1714 inet_ntop (af, source_ip, sbuf, sizeof(sbuf)),
1715 source_port,
1716 inet_ntop (af, destination_ip, dbuf, sizeof(dbuf)),
1717 destination_port,
1718 inet_ntop (destination->details.exit_destination.af,
1719 &destination->details.exit_destination.ip,
1720 xbuf,
1721 sizeof(xbuf)),
1722 destination_port);
1723 }
1724 for (dt = destination->dt_head; NULL != dt; dt = dt->next)
1725 if (dt->destination_port == destination_port)
1726 break;
1727 }
1728 else
1729 {
1730 {
1731 char sbuf[INET6_ADDRSTRLEN];
1732 char dbuf[INET6_ADDRSTRLEN];
1733
1734 GNUNET_log (
1736 "Routing %s packet from [%s]:%u -> [%s]:%u to service %s at peer %s\n",
1737 (protocol == IPPROTO_TCP) ? "TCP" : "UDP",
1738 inet_ntop (af, source_ip, sbuf, sizeof(sbuf)),
1739 source_port,
1740 inet_ntop (af, destination_ip, dbuf, sizeof(dbuf)),
1741 destination_port,
1742 GNUNET_h2s (
1745 }
1746 for (dt = destination->dt_head; NULL != dt; dt = dt->next)
1747 if (dt->destination_port == destination_port)
1748 break;
1749 }
1750 if (NULL == dt)
1751 {
1752 dt = GNUNET_new (struct DestinationChannel);
1753 dt->destination = destination;
1755 destination->dt_tail,
1756 dt);
1757 dt->destination_port = destination_port;
1758 }
1759
1760 /* see if we have an existing channel for this destination */
1762 if (NULL == ts)
1763 {
1765 "Creating new channel for key %s\n",
1766 GNUNET_h2s (&key));
1767 /* need to either use the existing channel from the destination (if still
1768 available) or create a fresh one */
1769 ts = create_channel_to_destination (dt, af);
1770 if (NULL == ts)
1771 return;
1772 /* now bind existing "unbound" channel to our IP/port tuple */
1773 ts->protocol = protocol;
1774 ts->af = af;
1775 if (AF_INET == af)
1776 {
1777 ts->source_ip.v4 = *(const struct in_addr *) source_ip;
1778 ts->destination_ip.v4 = *(const struct in_addr *) destination_ip;
1779 }
1780 else
1781 {
1782 ts->source_ip.v6 = *(const struct in6_addr *) source_ip;
1783 ts->destination_ip.v6 = *(const struct in6_addr *) destination_ip;
1784 }
1785 ts->source_port = source_port;
1786 ts->destination_port = destination_port;
1787 ts->heap_node =
1789 ts,
1790 GNUNET_TIME_absolute_get ().abs_value_us);
1794 &key,
1795 ts,
1798 gettext_noop ("# Active channels"),
1799 1,
1800 GNUNET_NO);
1803 expire_channel (ts);
1804 }
1805 else
1806 {
1809 .abs_value_us);
1810 }
1811 if (NULL == ts->channel)
1812 {
1814 "Packet dropped, channel to %s not yet ready (%s)\n",
1816 (NULL == ts->search) ? "EXIT search failed"
1817 : "EXIT search active");
1819 gettext_noop (
1820 "# Packets dropped (channel not yet online)"),
1821 1,
1822 GNUNET_NO);
1823 return;
1824 }
1825
1826 /* send via channel */
1827 switch (protocol)
1828 {
1829 case IPPROTO_UDP:
1830 if (destination->is_service)
1831 {
1833
1834 mlen = sizeof(struct GNUNET_EXIT_UdpServiceMessage) + payload_length
1835 - sizeof(struct GNUNET_TUN_UdpHeader);
1836 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1837 {
1838 GNUNET_break (0);
1839 return;
1840 }
1841 env = GNUNET_MQ_msg_extra (usm,
1842 payload_length
1843 - sizeof(struct GNUNET_TUN_UdpHeader),
1845 /* if the source port is below 32000, we assume it has a special
1846 meaning; if not, we pick a random port (this is a heuristic) */
1847 usm->source_port =
1848 (ntohs (udp->source_port) < 32000) ? udp->source_port : 0;
1849 usm->destination_port = udp->destination_port;
1850 GNUNET_memcpy (&usm[1],
1851 &udp[1],
1852 payload_length - sizeof(struct GNUNET_TUN_UdpHeader));
1853 }
1854 else
1855 {
1857 struct in_addr *ip4dst;
1858 struct in6_addr *ip6dst;
1859 void *payload;
1860
1861 mlen = sizeof(struct GNUNET_EXIT_UdpInternetMessage) + alen
1862 + payload_length - sizeof(struct GNUNET_TUN_UdpHeader);
1863 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1864 {
1865 GNUNET_break (0);
1866 return;
1867 }
1868 env = GNUNET_MQ_msg_extra (uim,
1869 payload_length + alen
1870 - sizeof(struct GNUNET_TUN_UdpHeader),
1872 uim->af = htonl (destination->details.exit_destination.af);
1873 uim->source_port =
1874 (ntohs (udp->source_port) < 32000) ? udp->source_port : 0;
1875 uim->destination_port = udp->destination_port;
1876 switch (destination->details.exit_destination.af)
1877 {
1878 case AF_INET:
1879 ip4dst = (struct in_addr *) &uim[1];
1880 *ip4dst = destination->details.exit_destination.ip.v4;
1881 payload = &ip4dst[1];
1882 break;
1883
1884 case AF_INET6:
1885 ip6dst = (struct in6_addr *) &uim[1];
1886 *ip6dst = destination->details.exit_destination.ip.v6;
1887 payload = &ip6dst[1];
1888 break;
1889
1890 default:
1891 GNUNET_assert (0);
1892 }
1894 &udp[1],
1895 payload_length - sizeof(struct GNUNET_TUN_UdpHeader));
1896 }
1897 break;
1898
1899 case IPPROTO_TCP:
1900 if (GNUNET_NO == ts->is_established)
1901 {
1902 if (destination->is_service)
1903 {
1905
1906 mlen = sizeof(struct GNUNET_EXIT_TcpServiceStartMessage)
1907 + payload_length - sizeof(struct GNUNET_TUN_TcpHeader);
1908 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1909 {
1910 GNUNET_break (0);
1911 return;
1912 }
1913 env =
1915 payload_length
1916 - sizeof(struct GNUNET_TUN_TcpHeader),
1918 tsm->reserved = htonl (0);
1919 tsm->tcp_header = *tcp;
1920 GNUNET_memcpy (&tsm[1],
1921 &tcp[1],
1922 payload_length - sizeof(struct GNUNET_TUN_TcpHeader));
1923 }
1924 else
1925 {
1927 struct in_addr *ip4dst;
1928 struct in6_addr *ip6dst;
1929 void *payload;
1930
1931 mlen = sizeof(struct GNUNET_EXIT_TcpInternetStartMessage) + alen
1932 + payload_length - sizeof(struct GNUNET_TUN_TcpHeader);
1933 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1934 {
1935 GNUNET_break (0);
1936 return;
1937 }
1938 env =
1940 payload_length + alen
1941 - sizeof(struct GNUNET_TUN_TcpHeader),
1943 tim->af = htonl (destination->details.exit_destination.af);
1944 tim->tcp_header = *tcp;
1945 switch (destination->details.exit_destination.af)
1946 {
1947 case AF_INET:
1948 ip4dst = (struct in_addr *) &tim[1];
1949 *ip4dst = destination->details.exit_destination.ip.v4;
1950 payload = &ip4dst[1];
1951 break;
1952
1953 case AF_INET6:
1954 ip6dst = (struct in6_addr *) &tim[1];
1955 *ip6dst = destination->details.exit_destination.ip.v6;
1956 payload = &ip6dst[1];
1957 break;
1958
1959 default:
1960 GNUNET_assert (0);
1961 }
1963 &tcp[1],
1964 payload_length - sizeof(struct GNUNET_TUN_TcpHeader));
1965 }
1966 }
1967 else
1968 {
1969 struct GNUNET_EXIT_TcpDataMessage *tdm;
1970
1971 mlen = sizeof(struct GNUNET_EXIT_TcpDataMessage) + payload_length
1972 - sizeof(struct GNUNET_TUN_TcpHeader);
1973 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1974 {
1975 GNUNET_break (0);
1976 return;
1977 }
1978 env = GNUNET_MQ_msg_extra (tdm,
1979 payload_length
1980 - sizeof(struct GNUNET_TUN_TcpHeader),
1982 tdm->reserved = htonl (0);
1983 tdm->tcp_header = *tcp;
1984 GNUNET_memcpy (&tdm[1],
1985 &tcp[1],
1986 payload_length - sizeof(struct GNUNET_TUN_TcpHeader));
1987 }
1988 break;
1989
1990 case IPPROTO_ICMP:
1991 case IPPROTO_ICMPV6:
1992 if (destination->is_service)
1993 {
1995
1996 /* ICMP protocol translation will be done by the receiver (as we don't know
1997 the target AF); however, we still need to possibly discard the payload
1998 depending on the ICMP type */
1999 switch (af)
2000 {
2001 case AF_INET:
2002 switch (icmp->type)
2003 {
2006 break;
2007
2011 /* throw away ICMP payload, won't be useful for the other side anyway */
2012 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2013 break;
2014
2015 default:
2017 gettext_noop (
2018 "# ICMPv4 packets dropped (not allowed)"),
2019 1,
2020 GNUNET_NO);
2021 return;
2022 }
2023 /* end of AF_INET */
2024 break;
2025
2026 case AF_INET6:
2027 switch (icmp->type)
2028 {
2033 /* throw away ICMP payload, won't be useful for the other side anyway */
2034 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2035 break;
2036
2039 break;
2040
2041 default:
2043 gettext_noop (
2044 "# ICMPv6 packets dropped (not allowed)"),
2045 1,
2046 GNUNET_NO);
2047 return;
2048 }
2049 /* end of AF_INET6 */
2050 break;
2051
2052 default:
2053 GNUNET_assert (0);
2054 break;
2055 }
2056
2057 /* update length calculations, as payload_length may have changed */
2058 mlen = sizeof(struct GNUNET_EXIT_IcmpServiceMessage) + alen
2059 + payload_length - sizeof(struct GNUNET_TUN_IcmpHeader);
2060 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
2061 {
2062 GNUNET_break (0);
2063 return;
2064 }
2065
2066 env = GNUNET_MQ_msg_extra (ism,
2067 payload_length
2068 - sizeof(struct GNUNET_TUN_IcmpHeader),
2070 ism->af = htonl (af); /* need to tell destination ICMP protocol family! */
2071 ism->icmp_header = *icmp;
2072 GNUNET_memcpy (&ism[1],
2073 &icmp[1],
2074 payload_length - sizeof(struct GNUNET_TUN_IcmpHeader));
2075 }
2076 else
2077 {
2079 struct in_addr *ip4dst;
2080 struct in6_addr *ip6dst;
2081 void *payload;
2082 uint8_t new_type;
2083
2084 new_type = icmp->type;
2085 /* Perform ICMP protocol-translation (depending on destination AF and source AF)
2086 and throw away ICMP payload depending on ICMP message type */
2087 switch (af)
2088 {
2089 case AF_INET:
2090 switch (icmp->type)
2091 {
2093 if (destination->details.exit_destination.af == AF_INET6)
2095 break;
2096
2098 if (destination->details.exit_destination.af == AF_INET6)
2100 break;
2101
2103 if (destination->details.exit_destination.af == AF_INET6)
2105 /* throw away IP-payload, exit will have to make it up anyway */
2106 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2107 break;
2108
2110 if (destination->details.exit_destination.af == AF_INET6)
2112 /* throw away IP-payload, exit will have to make it up anyway */
2113 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2114 break;
2115
2117 if (destination->details.exit_destination.af == AF_INET6)
2118 {
2120 stats,
2121 gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"),
2122 1,
2123 GNUNET_NO);
2124 return;
2125 }
2126 /* throw away IP-payload, exit will have to make it up anyway */
2127 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2128 break;
2129
2130 default:
2132 stats,
2133 gettext_noop ("# ICMPv4 packets dropped (type not allowed)"),
2134 1,
2135 GNUNET_NO);
2136 return;
2137 }
2138 /* end of AF_INET */
2139 break;
2140
2141 case AF_INET6:
2142 switch (icmp->type)
2143 {
2145 if (destination->details.exit_destination.af == AF_INET)
2147 /* throw away IP-payload, exit will have to make it up anyway */
2148 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2149 break;
2150
2152 if (destination->details.exit_destination.af == AF_INET)
2154 /* throw away IP-payload, exit will have to make it up anyway */
2155 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2156 break;
2157
2159 if (destination->details.exit_destination.af == AF_INET)
2160 {
2162 stats,
2163 gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"),
2164 1,
2165 GNUNET_NO);
2166 return;
2167 }
2168 /* throw away IP-payload, exit will have to make it up anyway */
2169 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2170 break;
2171
2173 if (destination->details.exit_destination.af == AF_INET)
2174 {
2176 stats,
2177 gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"),
2178 1,
2179 GNUNET_NO);
2180 return;
2181 }
2182 /* throw away IP-payload, exit will have to make it up anyway */
2183 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2184 break;
2185
2187 if (destination->details.exit_destination.af == AF_INET)
2189 break;
2190
2192 if (destination->details.exit_destination.af == AF_INET)
2194 break;
2195
2196 default:
2198 stats,
2199 gettext_noop ("# ICMPv6 packets dropped (type not allowed)"),
2200 1,
2201 GNUNET_NO);
2202 return;
2203 }
2204 /* end of AF_INET6 */
2205 break;
2206
2207 default:
2208 GNUNET_assert (0);
2209 }
2210
2211 /* update length calculations, as payload_length may have changed */
2212 mlen = sizeof(struct GNUNET_EXIT_IcmpInternetMessage) + alen
2213 + payload_length - sizeof(struct GNUNET_TUN_IcmpHeader);
2214 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
2215 {
2216 GNUNET_break (0);
2217 return;
2218 }
2219 env = GNUNET_MQ_msg_extra (iim,
2220 alen + payload_length
2221 - sizeof(struct GNUNET_TUN_IcmpHeader),
2223 iim->icmp_header = *icmp;
2224 iim->icmp_header.type = new_type;
2225 iim->af = htonl (destination->details.exit_destination.af);
2226 switch (destination->details.exit_destination.af)
2227 {
2228 case AF_INET:
2229 ip4dst = (struct in_addr *) &iim[1];
2230 *ip4dst = destination->details.exit_destination.ip.v4;
2231 payload = &ip4dst[1];
2232 break;
2233
2234 case AF_INET6:
2235 ip6dst = (struct in6_addr *) &iim[1];
2236 *ip6dst = destination->details.exit_destination.ip.v6;
2237 payload = &ip6dst[1];
2238 break;
2239
2240 default:
2241 GNUNET_assert (0);
2242 }
2244 &icmp[1],
2245 payload_length - sizeof(struct GNUNET_TUN_IcmpHeader));
2246 }
2247 break;
2248
2249 default:
2250 /* not supported above, how can we get here !? */
2251 GNUNET_assert (0);
2252 break;
2253 }
2255 send_to_channel (ts, env);
2256}
static unsigned long long payload
How much data are we currently storing in the database?
static void send_to_channel(struct ChannelState *ts, struct GNUNET_MQ_Envelope *env)
Add the given message to the given channel and trigger the transmission process.
static struct ChannelState * create_channel_to_destination(struct DestinationChannel *dt, int client_af)
Initialize the given destination entry's cadet channel.
static unsigned long long max_channel_mappings
If there are more than this number of open channels, old ones will be removed.
static void expire_channel(struct ChannelState *except)
We have too many active channels.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_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.
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs 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...
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.
@ GNUNET_ERROR_TYPE_WARNING
#define GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT
Type of messages containing an TCP packet of an established connection.
#define GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_SERVICE
Type of messages containing an ICMP packet for a service.
#define GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START
Type of messages containing an TCP packet for the Internet.
#define GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START
Type of messages containing an TCP packet for a service.
#define GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE
Type of messages containing an UDP packet for a service.
#define GNUNET_MESSAGE_TYPE_VPN_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.
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
int is_established
Is this channel new (GNUNET_NO), or did we exchange messages with the other side already (GNUNET_YES)...
List of channels we keep for each destination port for a given destination entry.
struct DestinationChannel * next
Kept in a DLL.
struct DestinationChannel * dt_head
Head of DLL of channels associated with this destination.
struct DestinationChannel * dt_tail
Tail of DLL of channels associated with this destination.
Message send via cadet to an exit daemon to forward ICMP data to the Internet.
Definition: exit.h:237
int32_t af
Address family, AF_INET or AF_INET6, in network byte order.
Definition: exit.h:249
struct GNUNET_TUN_IcmpHeader icmp_header
ICMP header to use.
Definition: exit.h:255
Message send via cadet to an exit daemon to send ICMP data to a local service.
Definition: exit.h:206
struct GNUNET_TUN_IcmpHeader icmp_header
ICMP header to use.
Definition: exit.h:223
int32_t af
Address family, AF_INET or AF_INET6, in network byte order.
Definition: exit.h:218
uint32_t reserved
Always 0.
Definition: exit.h:104
struct GNUNET_TUN_TcpHeader tcp_header
Skeleton of the TCP header to send.
Definition: exit.h:110
Message send via cadet to an exit daemon to initiate forwarding of TCP data to the Internet.
Definition: exit.h:64
struct GNUNET_TUN_TcpHeader tcp_header
Skeleton of the TCP header to send.
Definition: exit.h:79
int32_t af
Address family, AF_INET or AF_INET6, in network byte order.
Definition: exit.h:73
Message send via cadet to an exit daemon to initiate forwarding of TCP data to a local service.
Definition: exit.h:38
uint32_t reserved
Always 0.
Definition: exit.h:47
struct GNUNET_TUN_TcpHeader tcp_header
Skeleton of the TCP header to send.
Definition: exit.h:53
Message send via cadet to an exit daemon to forward UDP data to the Internet.
Definition: exit.h:146
uint16_t source_port
Source port to use for the UDP request (0 to use a random port).
Definition: exit.h:160
uint16_t destination_port
Destination port to use for the UDP request.
Definition: exit.h:165
int32_t af
Address family, AF_INET or AF_INET6, in network byte order.
Definition: exit.h:155
Message send via cadet to an exit daemon to send UDP data to a local service.
Definition: exit.h:121
uint16_t destination_port
Destination port to use for the UDP request.
Definition: exit.h:135
uint16_t source_port
Source port to use for the UDP request (0 to use a random port).
Definition: exit.h:130

References _, GNUNET_EXIT_TcpInternetStartMessage::af, GNUNET_EXIT_UdpInternetMessage::af, GNUNET_EXIT_IcmpServiceMessage::af, GNUNET_EXIT_IcmpInternetMessage::af, DestinationEntry::af, ChannelState::af, ChannelState::channel, channel_heap, channel_map, create_channel_to_destination(), DestinationChannel::destination, ChannelState::destination, ChannelState::destination_ip, GNUNET_EXIT_UdpServiceMessage::destination_port, GNUNET_EXIT_UdpInternetMessage::destination_port, DestinationChannel::destination_port, ChannelState::destination_port, DestinationEntry::details, DestinationEntry::dt_head, DestinationEntry::dt_tail, env, DestinationEntry::exit_destination, expire_channel(), get_channel_key_from_ips(), gettext_noop, GNUNET_assert, GNUNET_break, GNUNET_break_op, GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_heap_insert(), GNUNET_CONTAINER_heap_update_cost(), GNUNET_CONTAINER_multihashmap_get(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_multihashmap_size(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_INFO, GNUNET_ERROR_TYPE_WARNING, GNUNET_h2s(), GNUNET_i2s(), GNUNET_log, GNUNET_MAX_MESSAGE_SIZE, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_INTERNET, GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_SERVICE, GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT, GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START, GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START, GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET, GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE, GNUNET_MQ_msg_extra, GNUNET_new, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_TIME_absolute_get(), 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_YES, ChannelState::heap_node, GNUNET_EXIT_IcmpServiceMessage::icmp_header, GNUNET_EXIT_IcmpInternetMessage::icmp_header, DestinationEntry::ip, ChannelState::is_established, DestinationEntry::is_service, key, max_channel_mappings, DestinationChannel::next, payload, print_channel_destination(), ChannelState::protocol, GNUNET_EXIT_TcpServiceStartMessage::reserved, GNUNET_EXIT_TcpDataMessage::reserved, ChannelState::search, send_to_channel(), DestinationEntry::service_descriptor, DestinationEntry::service_destination, ChannelState::source_ip, GNUNET_EXIT_UdpServiceMessage::source_port, GNUNET_EXIT_UdpInternetMessage::source_port, ChannelState::source_port, stats, DestinationEntry::target, tcp, GNUNET_EXIT_TcpServiceStartMessage::tcp_header, GNUNET_EXIT_TcpInternetStartMessage::tcp_header, GNUNET_EXIT_TcpDataMessage::tcp_header, GNUNET_TUN_IcmpHeader::type, udp, DestinationEntry::v4, ChannelState::v4, DestinationEntry::v6, and ChannelState::v6.

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 (someone send to the local virtual channel interface).

Find the destination mapping, and if it exists, identify the correct CADET channel (or possibly create it) and forward the packet.

Parameters
clsclosure, NULL
messagemessage we got from the client (VPN channel interface)
Returns
GNUNET_OK on success, GNUNET_NO to stop further processing (no error) GNUNET_SYSERR to stop further processing with error

Definition at line 2272 of file gnunet-service-vpn.c.

2273{
2274 const struct GNUNET_TUN_Layer2PacketHeader *tun;
2275 size_t mlen;
2276 struct GNUNET_HashCode key;
2277 struct DestinationEntry *de;
2278
2280 gettext_noop (
2281 "# Packets received from TUN interface"),
2282 1,
2283 GNUNET_NO);
2284 mlen = ntohs (message->size);
2285 if ((ntohs (message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) ||
2286 (mlen < sizeof(struct GNUNET_MessageHeader)
2287 + sizeof(struct GNUNET_TUN_Layer2PacketHeader)))
2288 {
2289 GNUNET_break (0);
2290 return GNUNET_OK;
2291 }
2292 tun = (const struct GNUNET_TUN_Layer2PacketHeader *) &message[1];
2293 mlen -= (sizeof(struct GNUNET_MessageHeader)
2294 + sizeof(struct GNUNET_TUN_Layer2PacketHeader));
2295 switch (ntohs (tun->proto))
2296 {
2297 case ETH_P_IPV6: {
2298 const struct GNUNET_TUN_IPv6Header *pkt6;
2299
2300 if (mlen < sizeof(struct GNUNET_TUN_IPv6Header))
2301 {
2302 /* blame kernel */
2303 GNUNET_break (0);
2304 return GNUNET_OK;
2305 }
2306 pkt6 = (const struct GNUNET_TUN_IPv6Header *) &tun[1];
2309 if (NULL == de)
2310 {
2311 char buf[INET6_ADDRSTRLEN];
2312
2313 GNUNET_log (
2315 _ ("Packet received for unmapped destination `%s' (dropping it)\n"),
2316 inet_ntop (AF_INET6, &pkt6->destination_address, buf, sizeof(buf)));
2317 return GNUNET_OK;
2318 }
2319 route_packet (de,
2320 AF_INET6,
2321 pkt6->next_header,
2322 &pkt6->source_address,
2323 &pkt6->destination_address,
2324 &pkt6[1],
2325 mlen - sizeof(struct GNUNET_TUN_IPv6Header));
2326 }
2327 break;
2328
2329 case ETH_P_IPV4: {
2330 struct GNUNET_TUN_IPv4Header *pkt4;
2331
2332 if (mlen < sizeof(struct GNUNET_TUN_IPv4Header))
2333 {
2334 /* blame kernel */
2335 GNUNET_break (0);
2336 return GNUNET_OK;
2337 }
2338 pkt4 = (struct GNUNET_TUN_IPv4Header *) &tun[1];
2341 if (NULL == de)
2342 {
2343 char buf[INET_ADDRSTRLEN];
2344
2345 GNUNET_log (
2347 _ ("Packet received for unmapped destination `%s' (dropping it)\n"),
2348 inet_ntop (AF_INET, &pkt4->destination_address, buf, sizeof(buf)));
2349 return GNUNET_OK;
2350 }
2351 if (pkt4->header_length * 4 != sizeof(struct GNUNET_TUN_IPv4Header))
2352 {
2354 _ ("Received IPv4 packet with options (dropping it)\n"));
2355 return GNUNET_OK;
2356 }
2357 route_packet (de,
2358 AF_INET,
2359 pkt4->protocol,
2360 &pkt4->source_address,
2361 &pkt4->destination_address,
2362 &pkt4[1],
2363 mlen - sizeof(struct GNUNET_TUN_IPv4Header));
2364 }
2365 break;
2366
2367 default:
2368 GNUNET_log (
2370 _ ("Received packet of unknown protocol %d from TUN (dropping it)\n"),
2371 (unsigned int) ntohs (tun->proto));
2372 break;
2373 }
2374 return GNUNET_OK;
2375}
static struct GNUNET_CONTAINER_MultiHashMap * destination_map
Map from IP address to destination information (possibly with a CADET channel handle for fast setup).
static void route_packet(struct DestinationEntry *destination, int af, uint8_t protocol, const void *source_ip, const void *destination_ip, const void *payload, size_t payload_length)
Route a packet via cadet to the given destination.
static void get_destination_key_from_ip(int af, const void *address, struct GNUNET_HashCode *key)
Compute the key under which we would store an entry in the destination_map for the given IP address.
Information we track for each IP address to determine which channel to send the traffic over to the d...
uint8_t protocol
L4-protocol, for example, IPPROTO_UDP or IPPROTO_TCP.
struct in_addr source_address
Origin of the packet.
struct in_addr destination_address
Destination of the packet.
unsigned int header_length
struct in6_addr source_address
Origin of the packet.
uint8_t next_header
For example, IPPROTO_UDP or IPPROTO_TCP.
struct in6_addr destination_address
Destination of the packet.

References _, GNUNET_TUN_IPv4Header::destination_address, GNUNET_TUN_IPv6Header::destination_address, destination_map, ETH_P_IPV4, ETH_P_IPV6, get_destination_key_from_ip(), gettext_noop, GNUNET_break, GNUNET_CONTAINER_multihashmap_get(), GNUNET_ERROR_TYPE_INFO, GNUNET_log, GNUNET_MESSAGE_TYPE_VPN_HELPER, GNUNET_NO, GNUNET_OK, GNUNET_STATISTICS_update(), GNUNET_TUN_IPv4Header::header_length, key, GNUNET_TUN_IPv6Header::next_header, GNUNET_TUN_Layer2PacketHeader::proto, GNUNET_TUN_IPv4Header::protocol, route_packet(), GNUNET_MessageHeader::size, GNUNET_TUN_IPv4Header::source_address, GNUNET_TUN_IPv6Header::source_address, stats, and GNUNET_MessageHeader::type.

Referenced by run().

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

◆ allocate_v4_address()

static int allocate_v4_address ( struct in_addr *  v4)
static

Allocate an IPv4 address from the range of the channel for a new redirection.

Parameters
v4where to store the address
Returns
GNUNET_OK on success, GNUNET_SYSERR on error

Definition at line 2387 of file gnunet-service-vpn.c.

2388{
2389 const char *ipv4addr = vpn_argv[4];
2390 const char *ipv4mask = vpn_argv[5];
2391 struct in_addr addr;
2392 struct in_addr mask;
2393 struct in_addr rnd;
2394 struct GNUNET_HashCode key;
2395 unsigned int tries;
2396
2397 GNUNET_assert (1 == inet_pton (AF_INET, ipv4addr, &addr));
2398 GNUNET_assert (1 == inet_pton (AF_INET, ipv4mask, &mask));
2399 /* Given 192.168.0.1/255.255.0.0, we want a mask
2400 of '192.168.255.255', thus: */
2401 mask.s_addr = addr.s_addr | ~mask.s_addr;
2402 tries = 0;
2403 do
2404 {
2405 tries++;
2406 if (tries > 16)
2407 {
2409 _ (
2410 "Failed to find unallocated IPv4 address in VPN's range\n"));
2411 return GNUNET_SYSERR;
2412 }
2413 /* Pick random IPv4 address within the subnet, except 'addr' or 'mask' itself */
2414 rnd.s_addr =
2416 v4->s_addr = (addr.s_addr | rnd.s_addr) & mask.s_addr;
2417 get_destination_key_from_ip (AF_INET, v4, &key);
2418 }
2419 while ((GNUNET_YES ==
2421 (v4->s_addr == addr.s_addr) || (v4->s_addr == mask.s_addr));
2422 return GNUNET_OK;
2423}
static char * vpn_argv[7]
Arguments to the vpn helper.
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).
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_contains(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Check if the map contains any value under the given key (including values that are NULL).

References _, destination_map, get_destination_key_from_ip(), GNUNET_assert, GNUNET_CONTAINER_multihashmap_contains(), GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_u32(), GNUNET_ERROR_TYPE_WARNING, GNUNET_log, GNUNET_OK, GNUNET_SYSERR, GNUNET_YES, key, and vpn_argv.

Referenced by allocate_response_ip().

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

◆ allocate_v6_address()

static int allocate_v6_address ( struct in6_addr *  v6)
static

Allocate an IPv6 address from the range of the channel for a new redirection.

Parameters
v6where to store the address
Returns
GNUNET_OK on success, GNUNET_SYSERR on error

Definition at line 2435 of file gnunet-service-vpn.c.

2436{
2437 const char *ipv6addr = vpn_argv[2];
2438 struct in6_addr addr;
2439 struct in6_addr mask;
2440 struct in6_addr rnd;
2441 int i;
2442 struct GNUNET_HashCode key;
2443 unsigned int tries;
2444
2445 GNUNET_assert (1 == inet_pton (AF_INET6, ipv6addr, &addr));
2446 GNUNET_assert (ipv6prefix < 128);
2447 /* Given ABCD::/96, we want a mask of 'ABCD::FFFF:FFFF,
2448 thus: */
2449 mask = addr;
2450 for (i = 127; i >= ipv6prefix; i--)
2451 mask.s6_addr[i / 8] |= (1 << (i % 8));
2452
2453 /* Pick random IPv6 address within the subnet, except 'addr' or 'mask' itself */
2454 tries = 0;
2455 do
2456 {
2457 tries++;
2458 if (tries > 16)
2459 {
2461 _ (
2462 "Failed to find unallocated IPv6 address in VPN's range\n"));
2463 return GNUNET_SYSERR;
2464 }
2465 for (i = 0; i < 16; i++)
2466 {
2467 rnd.s6_addr[i] =
2469 256);
2470 v6->s6_addr[i] = (addr.s6_addr[i] | rnd.s6_addr[i]) & mask.s6_addr[i];
2471 }
2472 get_destination_key_from_ip (AF_INET6, v6, &key);
2473 }
2474 while ((GNUNET_YES ==
2476 (0 == GNUNET_memcmp (v6, &addr)) ||
2477 (0 == GNUNET_memcmp (v6, &mask)));
2478 return GNUNET_OK;
2479}
static unsigned long long ipv6prefix
Length of the prefix of the VPN's IPv6 network.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.

References _, destination_map, get_destination_key_from_ip(), GNUNET_assert, GNUNET_CONTAINER_multihashmap_contains(), GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_u32(), GNUNET_ERROR_TYPE_WARNING, GNUNET_log, GNUNET_memcmp, GNUNET_OK, GNUNET_SYSERR, GNUNET_YES, ipv6prefix, key, and vpn_argv.

Referenced by allocate_response_ip().

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

◆ free_destination_entry()

static void free_destination_entry ( struct DestinationEntry de)
static

Free resources occupied by a destination entry.

Parameters
deentry to free

Definition at line 2488 of file gnunet-service-vpn.c.

2489{
2490 struct DestinationChannel *dt;
2491
2493 "Cleaning up destination entry `%s'\n",
2496 gettext_noop ("# Active destinations"),
2497 -1,
2498 GNUNET_NO);
2499 while (NULL != (dt = de->dt_head))
2500 {
2502 GNUNET_free (dt);
2503 }
2504 if (NULL != de->heap_node)
2505 {
2507 de->heap_node = NULL;
2509 GNUNET_YES ==
2511 }
2512 GNUNET_free (de);
2513}
struct GNUNET_HashCode key
Key under which this entry is in the 'destination_map' (only valid if 'heap_node !...

References destination_map, DestinationEntry::dt_head, DestinationEntry::dt_tail, gettext_noop, GNUNET_assert, GNUNET_CONTAINER_DLL_remove, GNUNET_CONTAINER_heap_remove_node(), GNUNET_CONTAINER_multihashmap_remove(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_YES, DestinationEntry::heap_node, DestinationEntry::key, print_channel_destination(), and stats.

Referenced by cleanup_destination(), and expire_destination().

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

◆ expire_destination()

static void expire_destination ( struct DestinationEntry except)
static

We have too many active destinations.

Clean up the oldest destination.

Parameters
exceptdestination that must NOT be cleaned up, even if it is the oldest

Definition at line 2522 of file gnunet-service-vpn.c.

2523{
2524 struct DestinationEntry *de;
2525
2527 GNUNET_assert (NULL != de);
2528 if (except == de)
2529 return; /* can't do this */
2531}
static void free_destination_entry(struct DestinationEntry *de)
Free resources occupied by a destination entry.
static struct GNUNET_CONTAINER_Heap * destination_heap
Min-Heap sorted by activity time to expire old mappings.

References destination_heap, free_destination_entry(), GNUNET_assert, and GNUNET_CONTAINER_heap_peek().

Referenced by handle_client_redirect_to_ip(), and handle_client_redirect_to_service().

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

◆ allocate_response_ip()

static int allocate_response_ip ( int *  result_af,
void **  addr,
struct in_addr *  v4,
struct in6_addr *  v6 
)
static

Allocate an IP address for the response.

Parameters
result_afdesired address family; set to the actual address family; can initially be AF_UNSPEC if there is no preference; will be set to AF_UNSPEC if the allocation failed
addrset to either v4 or v6 depending on which storage location was used; set to NULL if allocation failed
v4storage space for an IPv4 address
v6storage space for an IPv6 address
Returns
GNUNET_OK normally, GNUNET_SYSERR if * result_af was an unsupported address family (not AF_INET, AF_INET6 or AF_UNSPEC)

Definition at line 2549 of file gnunet-service-vpn.c.

2553{
2554 *addr = NULL;
2555 switch (*result_af)
2556 {
2557 case AF_INET:
2558 if (GNUNET_OK != allocate_v4_address (v4))
2559 *result_af = AF_UNSPEC;
2560 else
2561 *addr = v4;
2562 break;
2563
2564 case AF_INET6:
2565 if (GNUNET_OK != allocate_v6_address (v6))
2566 *result_af = AF_UNSPEC;
2567 else
2568 *addr = v6;
2569 break;
2570
2571 case AF_UNSPEC:
2572 if (GNUNET_OK == allocate_v4_address (v4))
2573 {
2574 *addr = v4;
2575 *result_af = AF_INET;
2576 }
2577 else if (GNUNET_OK == allocate_v6_address (v6))
2578 {
2579 *addr = v6;
2580 *result_af = AF_INET6;
2581 }
2582 break;
2583
2584 default:
2585 GNUNET_break (0);
2586 return GNUNET_SYSERR;
2587 }
2588 return GNUNET_OK;
2589}
static int allocate_v6_address(struct in6_addr *v6)
Allocate an IPv6 address from the range of the channel for a new redirection.
static int allocate_v4_address(struct in_addr *v4)
Allocate an IPv4 address from the range of the channel for a new redirection.

References allocate_v4_address(), allocate_v6_address(), GNUNET_break, GNUNET_OK, GNUNET_SYSERR, DestinationEntry::v4, and DestinationEntry::v6.

Referenced by handle_client_redirect_to_ip(), and handle_client_redirect_to_service().

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

◆ check_client_redirect_to_ip()

static int check_client_redirect_to_ip ( void *  cls,
const struct RedirectToIpRequestMessage msg 
)
static

A client asks us to setup a redirection via some exit node to a particular IP.

Check if msg is well-formed. allocated IP.

Parameters
clsclient requesting client
msgredirection request
Returns
GNUNET_OK if msg is well-formed

Definition at line 2602 of file gnunet-service-vpn.c.

2604{
2605 size_t alen;
2606 int addr_af;
2607
2608 alen = ntohs (msg->header.size) - sizeof(struct RedirectToIpRequestMessage);
2609 addr_af = (int) htonl (msg->addr_af);
2610 switch (addr_af)
2611 {
2612 case AF_INET:
2613 if (alen != sizeof(struct in_addr))
2614 {
2615 GNUNET_break (0);
2616 return GNUNET_SYSERR;
2617 }
2618 break;
2619
2620 case AF_INET6:
2621 if (alen != sizeof(struct in6_addr))
2622 {
2623 GNUNET_break (0);
2624 return GNUNET_SYSERR;
2625 }
2626 break;
2627
2628 default:
2629 GNUNET_break (0);
2630 return GNUNET_SYSERR;
2631 }
2632 return GNUNET_OK;
2633}
Message send by the VPN client to the VPN service requesting the setup of a redirection from some IP ...
Definition: vpn.h:39
int32_t addr_af
Address family used for the destination address (AF_INET or AF_INET6, in nbo)
Definition: vpn.h:63

References RedirectToIpRequestMessage::addr_af, GNUNET_break, GNUNET_OK, GNUNET_SYSERR, consensus-simulation::int, msg, and GNUNET_MessageHeader::size.

◆ handle_client_redirect_to_ip()

static void handle_client_redirect_to_ip ( void *  cls,
const struct RedirectToIpRequestMessage msg 
)
static

A client asks us to setup a redirection via some exit node to a particular IP.

Setup the redirection and give the client the allocated IP.

Parameters
clsclient requesting client
msgredirection request

Definition at line 2645 of file gnunet-service-vpn.c.

2647{
2648 struct GNUNET_SERVICE_Client *client = cls;
2649 size_t alen;
2650 int addr_af;
2651 int result_af;
2652 struct in_addr v4;
2653 struct in6_addr v6;
2654 void *addr;
2655 struct DestinationEntry *de;
2656 struct GNUNET_HashCode key;
2657
2658 alen = ntohs (msg->header.size) - sizeof(struct RedirectToIpRequestMessage);
2659 addr_af = (int) htonl (msg->addr_af);
2660 /* allocate response IP */
2661 result_af = (int) htonl (msg->result_af);
2662 if (GNUNET_OK != allocate_response_ip (&result_af, &addr, &v4, &v6))
2663 {
2665 return;
2666 }
2667 /* send reply with our IP address */
2668 send_client_reply (client, msg->request_id, result_af, addr);
2669 if (result_af == AF_UNSPEC)
2670 {
2671 /* failure, we're done */
2673 return;
2674 }
2675
2676 {
2677 char sbuf[INET6_ADDRSTRLEN];
2678 char dbuf[INET6_ADDRSTRLEN];
2679
2681 "Allocated address %s for redirection via exit to %s\n",
2682 inet_ntop (result_af, addr, sbuf, sizeof(sbuf)),
2683 inet_ntop (addr_af, &msg[1], dbuf, sizeof(dbuf)));
2684 }
2685
2686 /* setup destination record */
2687 de = GNUNET_new (struct DestinationEntry);
2688 de->is_service = GNUNET_NO;
2690 GNUNET_memcpy (&de->details.exit_destination.ip, &msg[1], alen);
2692 de->key = key;
2695 &key,
2696 de,
2699 de,
2701 msg->expiration_time)
2702 .abs_value_us);
2704 gettext_noop ("# Active destinations"),
2705 1,
2706 GNUNET_NO);
2709 expire_destination (de);
2711}
static int allocate_response_ip(int *result_af, void **addr, struct in_addr *v4, struct in6_addr *v6)
Allocate an IP address for the response.
static void send_client_reply(struct GNUNET_SERVICE_Client *client, uint64_t request_id, int result_af, const void *addr)
Notify the client about the result of its request.
static unsigned long long max_destination_mappings
If there are more than this number of address-mappings, old ones will be removed.
static void expire_destination(struct DestinationEntry *except)
We have too many active destinations.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE
Allow multiple values with the same key.
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2484
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2455
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:737
Handle to a client that is connected to a service.
Definition: service.c:246
uint64_t abs_value_us
The actual value.
int32_t result_af
Address family desired for the result (AF_INET or AF_INET6 or AF_UNSPEC, in nbo)
Definition: vpn.h:58

References GNUNET_TIME_Absolute::abs_value_us, RedirectToIpRequestMessage::addr_af, DestinationEntry::af, allocate_response_ip(), destination_heap, destination_map, DestinationEntry::details, DestinationEntry::exit_destination, expire_destination(), get_destination_key_from_ip(), gettext_noop, GNUNET_assert, GNUNET_CONTAINER_heap_insert(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_multihashmap_size(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_memcpy, GNUNET_new, GNUNET_NO, GNUNET_OK, GNUNET_SERVICE_client_continue(), GNUNET_SERVICE_client_drop(), GNUNET_STATISTICS_update(), GNUNET_TIME_absolute_ntoh(), DestinationEntry::heap_node, consensus-simulation::int, DestinationEntry::ip, DestinationEntry::is_service, key, DestinationEntry::key, max_destination_mappings, msg, RedirectToIpRequestMessage::result_af, send_client_reply(), GNUNET_MessageHeader::size, and stats.

Here is the call graph for this function:

◆ handle_client_redirect_to_service()

static void handle_client_redirect_to_service ( void *  cls,
const struct RedirectToServiceRequestMessage msg 
)
static

A client asks us to setup a redirection to a particular peer offering a service.

Setup the redirection and give the client the allocated IP.

Parameters
clsrequesting client
msgredirection request

Definition at line 2723 of file gnunet-service-vpn.c.

2726{
2727 struct GNUNET_SERVICE_Client *client = cls;
2728 int result_af;
2729 struct in_addr v4;
2730 struct in6_addr v6;
2731 void *addr;
2732 struct DestinationEntry *de;
2733 struct GNUNET_HashCode key;
2734 struct DestinationChannel *dt;
2735
2736 /* allocate response IP */
2737 result_af = (int) htonl (msg->result_af);
2738 if (GNUNET_OK != allocate_response_ip (&result_af, &addr, &v4, &v6))
2739 {
2740 GNUNET_break (0);
2742 return;
2743 }
2744 send_client_reply (client, msg->request_id, result_af, addr);
2745 if (result_af == AF_UNSPEC)
2746 {
2747 /* failure, we're done */
2749 _ ("Failed to allocate IP address for new destination\n"));
2751 return;
2752 }
2753
2754 {
2755 char sbuf[INET6_ADDRSTRLEN];
2756
2758 "Allocated address %s for redirection to service %s on peer %s\n",
2759 inet_ntop (result_af, addr, sbuf, sizeof(sbuf)),
2760 GNUNET_h2s (&msg->service_descriptor),
2761 GNUNET_i2s (&msg->target));
2762 }
2763
2764 /* setup destination record */
2765 de = GNUNET_new (struct DestinationEntry);
2766 de->is_service = GNUNET_YES;
2767 de->details.service_destination.target = msg->target;
2768 de->details.service_destination.service_descriptor = msg->service_descriptor;
2769 get_destination_key_from_ip (result_af, addr, &key);
2770 de->key = key;
2773 &key,
2774 de,
2777 de,
2779 msg->expiration_time)
2780 .abs_value_us);
2783 expire_destination (de);
2784
2785 dt = GNUNET_new (struct DestinationChannel);
2786 dt->destination = de;
2788 /* we're done */
2790}
@ GNUNET_ERROR_TYPE_ERROR

References _, GNUNET_TIME_Absolute::abs_value_us, allocate_response_ip(), DestinationChannel::destination, destination_heap, destination_map, DestinationEntry::details, DestinationEntry::dt_head, DestinationEntry::dt_tail, expire_destination(), get_destination_key_from_ip(), GNUNET_assert, GNUNET_break, GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_heap_insert(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_multihashmap_size(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_h2s(), GNUNET_i2s(), GNUNET_log, GNUNET_new, GNUNET_OK, GNUNET_SERVICE_client_continue(), GNUNET_SERVICE_client_drop(), GNUNET_TIME_absolute_ntoh(), GNUNET_YES, DestinationEntry::heap_node, consensus-simulation::int, DestinationEntry::is_service, key, DestinationEntry::key, max_destination_mappings, msg, send_client_reply(), DestinationEntry::service_descriptor, DestinationEntry::service_destination, and DestinationEntry::target.

Here is the call graph for this function:

◆ cleanup_destination()

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

Free memory occupied by an entry in the destination map.

Parameters
clsunused
keyunused
valuea struct DestinationEntry *
Returns
GNUNET_OK (continue to iterate)

Definition at line 2802 of file gnunet-service-vpn.c.

2803{
2804 struct DestinationEntry *de = value;
2805
2807 return GNUNET_OK;
2808}
static char * value
Value of the record to add/remove.

References free_destination_entry(), GNUNET_OK, and value.

Referenced by cleanup().

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

◆ cleanup_channel()

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

Free memory occupied by an entry in the channel map.

Parameters
clsunused
keyunused
valuea struct ChannelState *
Returns
GNUNET_OK (continue to iterate)

Definition at line 2820 of file gnunet-service-vpn.c.

2821{
2822 struct ChannelState *ts = value;
2823
2825 "Tearing down channel to `%s' during cleanup\n",
2827 free_channel_state (ts);
2828 return GNUNET_OK;
2829}

References ChannelState::destination, free_channel_state(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_OK, print_channel_destination(), and value.

Referenced by cleanup().

Here is the call graph for this function:
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
clsunused

Definition at line 2838 of file gnunet-service-vpn.c.

2839{
2840 unsigned int i;
2841
2842 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "VPN is shutting down\n");
2843 if (NULL != destination_map)
2844 {
2847 NULL);
2849 destination_map = NULL;
2850 }
2851 if (NULL != destination_heap)
2852 {
2854 destination_heap = NULL;
2855 }
2856 if (NULL != channel_map)
2857 {
2860 channel_map = NULL;
2861 }
2862 if (NULL != channel_heap)
2863 {
2865 channel_heap = NULL;
2866 }
2867 if (NULL != cadet_handle)
2868 {
2870 cadet_handle = NULL;
2871 }
2872 if (NULL != helper_handle)
2873 {
2876 helper_handle = NULL;
2877 }
2878 if (NULL != stats)
2879 {
2881 stats = NULL;
2882 }
2883 for (i = 0; i < 5; i++)
2884 GNUNET_free (vpn_argv[i]);
2885}
static int cleanup_destination(void *cls, const struct GNUNET_HashCode *key, void *value)
Free memory occupied by an entry in the destination map.
static int cleanup_channel(void *cls, const struct GNUNET_HashCode *key, void *value)
Free memory occupied by an entry in the channel map.
void GNUNET_CADET_disconnect(struct GNUNET_CADET_Handle *handle)
Disconnect from the cadet service.
Definition: cadet_api.c:774
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.
enum GNUNET_GenericReturnValue GNUNET_HELPER_wait(struct GNUNET_HELPER_Handle *h)
Reap the helper process.
Definition: helper.c:206
enum GNUNET_GenericReturnValue GNUNET_HELPER_kill(struct GNUNET_HELPER_Handle *h, int soft_kill)
Sends termination signal to the helper process.
Definition: helper.c:166
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).

References cadet_handle, channel_heap, channel_map, cleanup_channel(), cleanup_destination(), destination_heap, destination_map, GNUNET_CADET_disconnect(), GNUNET_CONTAINER_heap_destroy(), GNUNET_CONTAINER_multihashmap_destroy(), GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_HELPER_kill(), GNUNET_HELPER_wait(), GNUNET_log, GNUNET_NO, GNUNET_STATISTICS_destroy(), helper_handle, stats, and vpn_argv.

Referenced by run().

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

◆ client_connect_cb()

static void * client_connect_cb ( void *  cls,
struct GNUNET_SERVICE_Client c,
struct GNUNET_MQ_Handle mq 
)
static

Callback called when a client connects to the service.

Parameters
clsclosure for the service
cthe new client that connected to the service
mqthe message queue used to send messages to the client
Returns
c

Definition at line 2897 of file gnunet-service-vpn.c.

2900{
2901 return c;
2902}

◆ client_disconnect_cb()

static void client_disconnect_cb ( void *  cls,
struct GNUNET_SERVICE_Client c,
void *  internal_cls 
)
static

Callback called when a client disconnected from the service.

Parameters
clsclosure for the service
cthe client that disconnected
internal_clsshould be equal to c

Definition at line 2913 of file gnunet-service-vpn.c.

2916{
2917 GNUNET_assert (c == internal_cls);
2918}

References GNUNET_assert.

◆ run()

static void run ( void *  cls,
const struct GNUNET_CONFIGURATION_Handle cfg_,
struct GNUNET_SERVICE_Handle service 
)
static

Main function that will be run by the scheduler.

Parameters
clsclosure
cfg_configuration
servicethe initialized service

Definition at line 2929 of file gnunet-service-vpn.c.

2932{
2933 char *ifname;
2934 char *ipv6addr;
2935 char *ipv6prefix_s;
2936 char *ipv4addr;
2937 char *ipv4mask;
2938 struct in_addr v4;
2939 struct in6_addr v6;
2940 char *binary;
2941
2942 cfg = cfg_;
2943 binary = GNUNET_OS_get_suid_binary_path (cfg, "gnunet-helper-vpn");
2944
2945 if (GNUNET_YES !=
2947 binary,
2948 GNUNET_YES,
2949 "-d gnunet-vpn - - 169.1.3.3.7 255.255.255.0")) // ipv4 only please!
2950 {
2952 "`%s' is not SUID or the path is invalid, refusing to run.\n",
2953 binary);
2954 GNUNET_free (binary);
2955 global_ret = 1;
2956 /* we won't "really" exit here, as the 'service' is still running;
2957 however, as no handlers are registered, the service won't do
2958 anything either */
2959 return;
2960 }
2962 if (GNUNET_OK !=
2964 "VPN",
2965 "MAX_MAPPING",
2968 if (GNUNET_OK !=
2970 "VPN",
2971 "MAX_TUNNELS",
2974
2977 GNUNET_NO);
2980 channel_map =
2983
2984
2985 vpn_argv[0] = GNUNET_strdup ("vpn-gnunet");
2986 if (GNUNET_SYSERR ==
2987 GNUNET_CONFIGURATION_get_value_string (cfg, "VPN", "IFNAME", &ifname))
2988 {
2990 GNUNET_free (binary);
2992 return;
2993 }
2994 vpn_argv[1] = ifname;
2995 ipv6addr = NULL;
2996 if (GNUNET_OK == GNUNET_NETWORK_test_pf (PF_INET6))
2997 {
2999 "VPN",
3000 "IPV6ADDR",
3001 &ipv6addr)) ||
3002 (1 != inet_pton (AF_INET6, ipv6addr, &v6))))
3003 {
3005 "VPN",
3006 "IPV6ADDR",
3007 _ ("Must specify valid IPv6 address"));
3008 GNUNET_free (binary);
3010 GNUNET_free (ipv6addr);
3011 return;
3012 }
3013 vpn_argv[2] = ipv6addr;
3014 ipv6prefix_s = NULL;
3016 "VPN",
3017 "IPV6PREFIX",
3018 &ipv6prefix_s))
3019 {
3022 GNUNET_free (ipv6prefix_s);
3023 return;
3024 }
3025 vpn_argv[3] = ipv6prefix_s;
3027 "VPN",
3028 "IPV6PREFIX",
3029 &ipv6prefix)) ||
3030 (ipv6prefix >= 127))
3031 {
3033 "VPN",
3034 "IPV4MASK",
3035 _ ("Must specify valid IPv6 mask"));
3036 GNUNET_free (binary);
3038 return;
3039 }
3040 }
3041 else
3042 {
3044 _ (
3045 "IPv6 support disabled as this system does not support IPv6\n"));
3046 vpn_argv[2] = GNUNET_strdup ("-");
3047 vpn_argv[3] = GNUNET_strdup ("-");
3048 }
3049 if (GNUNET_OK == GNUNET_NETWORK_test_pf (PF_INET))
3050 {
3051 ipv4addr = NULL;
3053 "vpn",
3054 "IPV4ADDR",
3055 &ipv4addr)) ||
3056 (1 != inet_pton (AF_INET, ipv4addr, &v4))))
3057 {
3059 "VPN",
3060 "IPV4ADDR",
3061 _ ("Must specify valid IPv4 address"));
3062 GNUNET_free (binary);
3064 GNUNET_free (ipv4addr);
3065 return;
3066 }
3067 vpn_argv[4] = ipv4addr;
3068 ipv4mask = NULL;
3070 "vpn",
3071 "IPV4MASK",
3072 &ipv4mask)) ||
3073 (1 != inet_pton (AF_INET, ipv4mask, &v4))))
3074 {
3076 "VPN",
3077 "IPV4MASK",
3078 _ ("Must specify valid IPv4 mask"));
3079 GNUNET_free (binary);
3081 GNUNET_free (ipv4mask);
3082 return;
3083 }
3084 vpn_argv[5] = ipv4mask;
3085 }
3086 else
3087 {
3089 _ (
3090 "IPv4 support disabled as this system does not support IPv4\n"));
3091 vpn_argv[4] = GNUNET_strdup ("-");
3092 vpn_argv[5] = GNUNET_strdup ("-");
3093 }
3094 vpn_argv[6] = NULL;
3095
3097 // FIXME never opens ports???
3099 binary,
3100 vpn_argv,
3102 NULL,
3103 NULL);
3104 GNUNET_free (binary);
3106}
static int global_ret
Return value from main().
static void cleanup(void *cls)
Function scheduled as very last function, cleans up after us.
static int message_token(void *cls, const struct GNUNET_MessageHeader *message)
Receive packets from the helper-process (someone send to the local virtual channel interface).
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
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.
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.
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
void GNUNET_log_config_invalid(enum GNUNET_ErrorType kind, const char *section, const char *option, const char *required)
Log error message about invalid configuration option value.
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
enum GNUNET_GenericReturnValue GNUNET_NETWORK_test_pf(int pf)
Test if the given protocol family is supported by this system.
Definition: network.c:79
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.
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.

References _, cadet_handle, cfg, channel_heap, channel_map, cleanup(), destination_heap, destination_map, global_ret, GNUNET_CADET_connect(), GNUNET_CONFIGURATION_get_value_number(), GNUNET_CONFIGURATION_get_value_string(), GNUNET_CONTAINER_heap_create(), GNUNET_CONTAINER_HEAP_ORDER_MIN, GNUNET_CONTAINER_multihashmap_create(), GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_free, GNUNET_HELPER_start(), GNUNET_log, GNUNET_log_config_invalid(), GNUNET_log_config_missing(), GNUNET_NETWORK_test_pf(), GNUNET_NO, GNUNET_OK, GNUNET_OS_check_helper_binary(), GNUNET_OS_get_suid_binary_path(), GNUNET_SCHEDULER_add_shutdown(), GNUNET_SCHEDULER_shutdown(), GNUNET_STATISTICS_create(), GNUNET_strdup, GNUNET_SYSERR, GNUNET_YES, helper_handle, ipv6prefix, max_channel_mappings, max_destination_mappings, message_token(), stats, and vpn_argv.

Here is the call graph for this function:

◆ GNUNET_SERVICE_MAIN()

GNUNET_SERVICE_MAIN ( "vpn"  ,
GNUNET_SERVICE_OPTION_NONE  ,
run,
client_connect_cb,
client_disconnect_cb,
NULL  ,
GNUNET_MQ_hd_var_size(client_redirect_to_ip, GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_IP, struct RedirectToIpRequestMessage, NULL)  ,
GNUNET_MQ_hd_fixed_size(client_redirect_to_service, GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_SERVICE, struct RedirectToServiceRequestMessage, NULL)  ,
GNUNET_MQ_handler_end()   
)

Define "main" method using service macro.

Variable Documentation

◆ global_ret

int global_ret
static

Return value from main().

Definition at line 305 of file gnunet-service-vpn.c.

Referenced by run().

◆ cfg

const struct GNUNET_CONFIGURATION_Handle* cfg
static

Configuration we use.

Definition at line 310 of file gnunet-service-vpn.c.

Referenced by create_channel_to_destination(), and run().

◆ cadet_handle

struct GNUNET_CADET_Handle* cadet_handle
static

Handle to the cadet service.

Definition at line 315 of file gnunet-service-vpn.c.

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

◆ destination_map

struct GNUNET_CONTAINER_MultiHashMap* destination_map
static

Map from IP address to destination information (possibly with a CADET channel handle for fast setup).

Definition at line 321 of file gnunet-service-vpn.c.

Referenced by allocate_v4_address(), allocate_v6_address(), cleanup(), free_destination_entry(), handle_client_redirect_to_ip(), handle_client_redirect_to_service(), message_token(), and run().

◆ destination_heap

struct GNUNET_CONTAINER_Heap* destination_heap
static

Min-Heap sorted by activity time to expire old mappings.

Definition at line 326 of file gnunet-service-vpn.c.

Referenced by cleanup(), expire_destination(), handle_client_redirect_to_ip(), handle_client_redirect_to_service(), and run().

◆ channel_map

struct GNUNET_CONTAINER_MultiHashMap* channel_map
static

Map from source and destination address (IP+port) to connection information (mostly with the respective CADET channel handle).

Definition at line 332 of file gnunet-service-vpn.c.

Referenced by cleanup(), free_channel_state(), route_packet(), and run().

◆ channel_heap

struct GNUNET_CONTAINER_Heap* channel_heap
static

Min-Heap sorted by activity time to expire old mappings; values are of type 'struct ChannelState'.

Definition at line 338 of file gnunet-service-vpn.c.

Referenced by cleanup(), expire_channel(), route_packet(), and run().

◆ stats

◆ helper_handle

struct GNUNET_HELPER_Handle* helper_handle
static

The handle to the VPN helper process "gnunet-helper-vpn".

Definition at line 348 of file gnunet-service-vpn.c.

Referenced by cleanup(), handle_icmp_back(), handle_tcp_back(), handle_udp_back(), and run().

◆ vpn_argv

char* vpn_argv[7]
static

Arguments to the vpn helper.

Definition at line 353 of file gnunet-service-vpn.c.

Referenced by allocate_v4_address(), allocate_v6_address(), cleanup(), and run().

◆ ipv6prefix

unsigned long long ipv6prefix
static

Length of the prefix of the VPN's IPv6 network.

Definition at line 358 of file gnunet-service-vpn.c.

Referenced by allocate_v6_address(), and run().

◆ max_destination_mappings

unsigned long long max_destination_mappings
static

If there are more than this number of address-mappings, old ones will be removed.

Definition at line 364 of file gnunet-service-vpn.c.

Referenced by handle_client_redirect_to_ip(), handle_client_redirect_to_service(), and run().

◆ max_channel_mappings

unsigned long long max_channel_mappings
static

If there are more than this number of open channels, old ones will be removed.

Definition at line 370 of file gnunet-service-vpn.c.

Referenced by route_packet(), and run().