GNUnet 0.22.2
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_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 (GNUNET_OS_project_data_gnunet(), "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 48 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 381 of file gnunet-service-vpn.c.

384{
385 switch (af)
386 {
387 case AF_INET:
388 GNUNET_CRYPTO_hash (address, sizeof(struct in_addr), key);
389 break;
390
391 case AF_INET6:
392 GNUNET_CRYPTO_hash (address, sizeof(struct in6_addr), key);
393 break;
394
395 default:
396 GNUNET_assert (0);
397 break;
398 }
399}
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 415 of file gnunet-service-vpn.c.

422{
423 char *off;
424
425 memset (key, 0, sizeof(struct GNUNET_HashCode));
426 /* the GNUnet hashmap only uses the first sizeof(unsigned int) of the hash,
427 so we put the ports in there (and hope for few collisions) */
428 off = (char *) key;
429 GNUNET_memcpy (off, &source_port, sizeof(uint16_t));
430 off += sizeof(uint16_t);
431 GNUNET_memcpy (off, &destination_port, sizeof(uint16_t));
432 off += sizeof(uint16_t);
433 switch (af)
434 {
435 case AF_INET:
436 GNUNET_memcpy (off, source_ip, sizeof(struct in_addr));
437 off += sizeof(struct in_addr);
438 GNUNET_memcpy (off, destination_ip, sizeof(struct in_addr));
439 off += sizeof(struct in_addr);
440 break;
441
442 case AF_INET6:
443 GNUNET_memcpy (off, source_ip, sizeof(struct in6_addr));
444 off += sizeof(struct in6_addr);
445 GNUNET_memcpy (off, destination_ip, sizeof(struct in6_addr));
446 off += sizeof(struct in6_addr);
447 break;
448
449 default:
450 GNUNET_assert (0);
451 break;
452 }
453 GNUNET_memcpy (off, &protocol, sizeof(uint8_t));
454 /* off += sizeof (uint8_t); */
455}
#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 467 of file gnunet-service-vpn.c.

471{
472 struct GNUNET_MQ_Envelope *env;
474 size_t rlen;
475
476 switch (result_af)
477 {
478 case AF_INET:
479 rlen = sizeof(struct in_addr);
480 break;
481
482 case AF_INET6:
483 rlen = sizeof(struct in6_addr);
484 break;
485
486 case AF_UNSPEC:
487 rlen = 0;
488 break;
489
490 default:
491 GNUNET_assert (0);
492 return;
493 }
495 res->result_af = htonl (result_af);
496 res->request_id = request_id;
497 GNUNET_memcpy (&res[1], addr, rlen);
499}
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:305
#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:61
#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:2500
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 508 of file gnunet-service-vpn.c.

509{
510 struct GNUNET_HashCode key;
511 struct ChannelMessageQueueEntry *tnq;
512 struct GNUNET_CADET_Channel *channel;
513
514 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up channel state\n");
515 if (NULL != (channel = ts->channel))
516 {
517 ts->channel = NULL;
519 return;
520 }
522 gettext_noop ("# Active channels"),
523 -1,
524 GNUNET_NO);
525 while (NULL != (tnq = ts->tmq_head))
526 {
528 ts->tmq_length--;
529 GNUNET_free (tnq);
530 }
531 GNUNET_assert (0 == ts->tmq_length);
532 GNUNET_assert (NULL == ts->destination.heap_node);
533 if (NULL != ts->search)
534 {
536 ts->search = NULL;
537 }
538 if (NULL != ts->heap_node)
539 {
541 ts->heap_node = NULL;
543 ts->protocol,
544 &ts->source_ip,
545 ts->source_port,
546 &ts->destination_ip,
548 &key);
550 GNUNET_YES ==
552 }
553 GNUNET_free (ts);
554}
#define gettext_noop(String)
Definition: gettext.h:74
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:833
#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 565 of file gnunet-service-vpn.c.

566{
567 struct GNUNET_MQ_Handle *mq;
568
569 GNUNET_assert (NULL != ts->channel);
576 {
578 GNUNET_assert (NULL != env);
581 "# Messages dropped in cadet queue (overflow)"),
582 1,
583 GNUNET_NO);
585 }
586}
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:1081
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:847
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:355
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 596 of file gnunet-service-vpn.c.

597{
598 static char dest[256];
599
600 if (de->is_service)
601 {
603 sizeof(dest),
604 "HS: %s-%s",
606 GNUNET_h2s (
608 }
609 else
610 {
611 inet_ntop (de->details.exit_destination.af,
613 dest,
614 sizeof(dest));
615 }
616 return dest;
617}
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 628 of file gnunet-service-vpn.c.

629{
630 struct ChannelState *ts = cls;
631
632 ts->channel =
633 NULL; /* we must not call GNUNET_CADET_channel_destroy() anymore */
635 "CADET notified us about death of channel to `%s'\n",
638}
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 651 of file gnunet-service-vpn.c.

654{
656 ts->protocol,
657 sizeof(struct GNUNET_TUN_TcpHeader),
658 &ts->source_ip.v4,
659 &ts->destination_ip.v4);
660 udp->source_port = htons (ts->source_port);
661 udp->destination_port = htons (ts->destination_port);
662 udp->len = htons (0);
663 udp->crc = htons (0);
664}
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:80
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 677 of file gnunet-service-vpn.c.

680{
682 ts->protocol,
683 sizeof(struct GNUNET_TUN_TcpHeader),
684 &ts->source_ip.v6,
685 &ts->destination_ip.v6);
686 udp->source_port = htons (ts->source_port);
687 udp->destination_port = htons (ts->destination_port);
688 udp->len = htons (0);
689 udp->crc = htons (0);
690}
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:115
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 702 of file gnunet-service-vpn.c.

703{
704 struct ChannelState *ts = cls;
705
706 if (NULL == ts->heap_node)
707 {
708 GNUNET_break_op (0);
709 return GNUNET_SYSERR;
710 }
711 if (AF_UNSPEC == ts->af)
712 {
713 GNUNET_break_op (0);
714 return GNUNET_SYSERR;
715 }
716 return GNUNET_OK;
717}
@ 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 728 of file gnunet-service-vpn.c.

729{
730 struct ChannelState *ts = cls;
731 size_t mlen;
732
734 gettext_noop ("# ICMP packets received from cadet"),
735 1,
736 GNUNET_NO);
737 mlen =
738 ntohs (i2v->header.size) - sizeof(struct GNUNET_EXIT_IcmpToVPNMessage);
739 {
740 char sbuf[INET6_ADDRSTRLEN];
741 char dbuf[INET6_ADDRSTRLEN];
742
743 GNUNET_log (
745 "Received ICMP packet from cadet, sending %u bytes from %s -> %s via TUN\n",
746 (unsigned int) mlen,
747 inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof(sbuf)),
748 inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof(dbuf)));
749 }
750 switch (ts->af)
751 {
752 case AF_INET: {
753 size_t size = sizeof(struct GNUNET_TUN_IPv4Header)
754 + sizeof(struct GNUNET_TUN_IcmpHeader)
755 + sizeof(struct GNUNET_MessageHeader)
756 + sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
757 {
758 /* reserve some extra space in case we have an ICMP type here where
759 we will need to make up the payload ourselves */
760 char buf[size + sizeof(struct GNUNET_TUN_IPv4Header) + 8] GNUNET_ALIGN;
761 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
763 (struct GNUNET_TUN_Layer2PacketHeader *) &msg[1];
765 (struct GNUNET_TUN_IPv4Header *) &tun[1];
766 struct GNUNET_TUN_IcmpHeader *icmp =
767 (struct GNUNET_TUN_IcmpHeader *) &ipv4[1];
769 tun->flags = htons (0);
770 tun->proto = htons (ETH_P_IPV4);
772 IPPROTO_ICMP,
773 sizeof(struct GNUNET_TUN_IcmpHeader)
774 + mlen,
775 &ts->destination_ip.v4,
776 &ts->source_ip.v4);
777 *icmp = i2v->icmp_header;
778 GNUNET_memcpy (&icmp[1], &i2v[1], mlen);
779 /* For some ICMP types, we need to adjust (make up) the payload here.
780 Also, depending on the AF used on the other side, we have to
781 do ICMP PT (translate ICMP types) */
782 switch (ntohl (i2v->af))
783 {
784 case AF_INET:
785 switch (icmp->type)
786 {
789 break;
790
794 struct GNUNET_TUN_IPv4Header *ipp =
795 (struct GNUNET_TUN_IPv4Header *) &icmp[1];
796 struct GNUNET_TUN_UdpHeader *udp =
797 (struct GNUNET_TUN_UdpHeader *) &ipp[1];
798
799 if (mlen != 0)
800 {
801 /* sender did not strip ICMP payload? */
802 GNUNET_break_op (0);
803 return;
804 }
805 size += sizeof(struct GNUNET_TUN_IPv4Header) + 8;
806 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
807 make_up_icmpv4_payload (ts, ipp, udp);
808 }
809 break;
810
811 default:
812 GNUNET_break_op (0);
814 stats,
815 gettext_noop ("# ICMPv4 packets dropped (type not allowed)"),
816 1,
817 GNUNET_NO);
818 return;
819 }
820 /* end AF_INET */
821 break;
822
823 case AF_INET6:
824 /* ICMP PT 6-to-4 and possibly making up payloads */
825 switch (icmp->type)
826 {
829 {
830 struct GNUNET_TUN_IPv4Header *ipp =
831 (struct GNUNET_TUN_IPv4Header *) &icmp[1];
832 struct GNUNET_TUN_UdpHeader *udp =
833 (struct GNUNET_TUN_UdpHeader *) &ipp[1];
834
835 if (mlen != 0)
836 {
837 /* sender did not strip ICMP payload? */
838 GNUNET_break_op (0);
839 return;
840 }
841 size += sizeof(struct GNUNET_TUN_IPv4Header) + 8;
842 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
843 make_up_icmpv4_payload (ts, ipp, udp);
844 }
845 break;
846
849 {
850 struct GNUNET_TUN_IPv4Header *ipp =
851 (struct GNUNET_TUN_IPv4Header *) &icmp[1];
852 struct GNUNET_TUN_UdpHeader *udp =
853 (struct GNUNET_TUN_UdpHeader *) &ipp[1];
854
855 if (mlen != 0)
856 {
857 /* sender did not strip ICMP payload? */
858 GNUNET_break_op (0);
859 return;
860 }
861 size += sizeof(struct GNUNET_TUN_IPv4Header) + 8;
862 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
863 make_up_icmpv4_payload (ts, ipp, udp);
864 }
865 break;
866
870 stats,
871 gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"),
872 1,
873 GNUNET_NO);
874 return;
875
878 break;
879
882 break;
883
884 default:
885 GNUNET_break_op (0);
887 stats,
888 gettext_noop ("# ICMPv6 packets dropped (type not allowed)"),
889 1,
890 GNUNET_NO);
891 return;
892 }
893 /* end AF_INET6 */
894 break;
895
896 default:
897 GNUNET_break_op (0);
898 return;
899 }
900 msg->size = htons (size);
901 GNUNET_TUN_calculate_icmp_checksum (icmp, &i2v[1], mlen);
902 (void) GNUNET_HELPER_send (helper_handle, msg, GNUNET_YES, NULL, NULL);
903 }
904 }
905 break;
906
907 case AF_INET6: {
908 size_t size = sizeof(struct GNUNET_TUN_IPv6Header)
909 + sizeof(struct GNUNET_TUN_IcmpHeader)
910 + sizeof(struct GNUNET_MessageHeader)
911 + sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
912 {
913 char buf[size + sizeof(struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
914 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
916 (struct GNUNET_TUN_Layer2PacketHeader *) &msg[1];
918 (struct GNUNET_TUN_IPv6Header *) &tun[1];
919 struct GNUNET_TUN_IcmpHeader *icmp =
920 (struct GNUNET_TUN_IcmpHeader *) &ipv6[1];
922 tun->flags = htons (0);
923 tun->proto = htons (ETH_P_IPV6);
925 IPPROTO_ICMPV6,
926 sizeof(struct GNUNET_TUN_IcmpHeader)
927 + mlen,
928 &ts->destination_ip.v6,
929 &ts->source_ip.v6);
930 *icmp = i2v->icmp_header;
931 GNUNET_memcpy (&icmp[1], &i2v[1], mlen);
932
933 /* For some ICMP types, we need to adjust (make up) the payload here.
934 Also, depending on the AF used on the other side, we have to
935 do ICMP PT (translate ICMP types) */
936 switch (ntohl (i2v->af))
937 {
938 case AF_INET:
939 /* ICMP PT 4-to-6 and possibly making up payloads */
940 switch (icmp->type)
941 {
944 break;
945
948 break;
949
952 {
953 struct GNUNET_TUN_IPv6Header *ipp =
954 (struct GNUNET_TUN_IPv6Header *) &icmp[1];
955 struct GNUNET_TUN_UdpHeader *udp =
956 (struct GNUNET_TUN_UdpHeader *) &ipp[1];
957
958 if (mlen != 0)
959 {
960 /* sender did not strip ICMP payload? */
961 GNUNET_break_op (0);
962 return;
963 }
964 size += sizeof(struct GNUNET_TUN_IPv6Header) + 8;
965 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
966 make_up_icmpv6_payload (ts, ipp, udp);
967 }
968 break;
969
972 {
973 struct GNUNET_TUN_IPv6Header *ipp =
974 (struct GNUNET_TUN_IPv6Header *) &icmp[1];
975 struct GNUNET_TUN_UdpHeader *udp =
976 (struct GNUNET_TUN_UdpHeader *) &ipp[1];
977
978 if (mlen != 0)
979 {
980 /* sender did not strip ICMP payload? */
981 GNUNET_break_op (0);
982 return;
983 }
984 size += sizeof(struct GNUNET_TUN_IPv6Header) + 8;
985 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
986 make_up_icmpv6_payload (ts, ipp, udp);
987 }
988 break;
989
992 stats,
993 gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"),
994 1,
995 GNUNET_NO);
996 return;
997
998 default:
999 GNUNET_break_op (0);
1001 stats,
1002 gettext_noop ("# ICMPv4 packets dropped (type not allowed)"),
1003 1,
1004 GNUNET_NO);
1005 return;
1006 }
1007 /* end AF_INET */
1008 break;
1009
1010 case AF_INET6:
1011 switch (icmp->type)
1012 {
1017 struct GNUNET_TUN_IPv6Header *ipp =
1018 (struct GNUNET_TUN_IPv6Header *) &icmp[1];
1019 struct GNUNET_TUN_UdpHeader *udp =
1020 (struct GNUNET_TUN_UdpHeader *) &ipp[1];
1021
1022 if (mlen != 0)
1023 {
1024 /* sender did not strip ICMP payload? */
1025 GNUNET_break_op (0);
1026 return;
1027 }
1028 size += sizeof(struct GNUNET_TUN_IPv6Header) + 8;
1029 GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
1030 make_up_icmpv6_payload (ts, ipp, udp);
1031 }
1032 break;
1033
1035 break;
1036
1037 default:
1038 GNUNET_break_op (0);
1040 stats,
1041 gettext_noop ("# ICMPv6 packets dropped (type not allowed)"),
1042 1,
1043 GNUNET_NO);
1044 return;
1045 }
1046 /* end AF_INET6 */
1047 break;
1048
1049 default:
1050 GNUNET_break_op (0);
1051 return;
1052 }
1053 msg->size = htons (size);
1054 GNUNET_TUN_calculate_icmp_checksum (icmp, &i2v[1], mlen);
1055 (void) GNUNET_HELPER_send (helper_handle, msg, GNUNET_YES, NULL, NULL);
1056 }
1057 }
1058 break;
1059
1060 default:
1061 GNUNET_assert (0);
1062 }
1064 GNUNET_TIME_absolute_get ().abs_value_us);
1066}
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:875
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:615
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:255
#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 1078 of file gnunet-service-vpn.c.

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

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

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

1229{
1230 struct ChannelState *ts = cls;
1231
1232 if (NULL == ts->heap_node)
1233 {
1234 GNUNET_break_op (0);
1235 return GNUNET_SYSERR;
1236 }
1237 if (data->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
1238 {
1239 GNUNET_break_op (0);
1240 return GNUNET_SYSERR;
1241 }
1242 return GNUNET_OK;
1243}
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 1254 of file gnunet-service-vpn.c.

1255{
1256 struct ChannelState *ts = cls;
1257 size_t mlen;
1258
1260 gettext_noop ("# TCP packets received from cadet"),
1261 1,
1262 GNUNET_NO);
1263 mlen = ntohs (data->header.size) - sizeof(struct GNUNET_EXIT_TcpDataMessage);
1264 {
1265 char sbuf[INET6_ADDRSTRLEN];
1266 char dbuf[INET6_ADDRSTRLEN];
1267
1268 GNUNET_log (
1270 "Received TCP reply from cadet, sending %u bytes from [%s]:%u -> [%s]:%u via TUN\n",
1271 (unsigned int) mlen,
1272 inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof(sbuf)),
1273 ts->destination_port,
1274 inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof(dbuf)),
1275 ts->source_port);
1276 }
1277 switch (ts->af)
1278 {
1279 case AF_INET: {
1280 size_t size = sizeof(struct GNUNET_TUN_IPv4Header)
1281 + sizeof(struct GNUNET_TUN_TcpHeader)
1282 + sizeof(struct GNUNET_MessageHeader)
1283 + sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
1284 {
1285 char buf[size] GNUNET_ALIGN;
1286 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
1287 struct GNUNET_TUN_Layer2PacketHeader *tun =
1288 (struct GNUNET_TUN_Layer2PacketHeader *) &msg[1];
1289 struct GNUNET_TUN_IPv4Header *ipv4 =
1290 (struct GNUNET_TUN_IPv4Header *) &tun[1];
1291 struct GNUNET_TUN_TcpHeader *tcp =
1292 (struct GNUNET_TUN_TcpHeader *) &ipv4[1];
1294 msg->size = htons (size);
1295 tun->flags = htons (0);
1296 tun->proto = htons (ETH_P_IPV4);
1298 IPPROTO_TCP,
1299 sizeof(struct GNUNET_TUN_TcpHeader)
1300 + mlen,
1301 &ts->destination_ip.v4,
1302 &ts->source_ip.v4);
1303 *tcp = data->tcp_header;
1304 tcp->source_port = htons (ts->destination_port);
1305 tcp->destination_port = htons (ts->source_port);
1307 GNUNET_memcpy (&tcp[1], &data[1], mlen);
1308 (void) GNUNET_HELPER_send (helper_handle, msg, GNUNET_YES, NULL, NULL);
1309 }
1310 }
1311 break;
1312
1313 case AF_INET6: {
1314 size_t size = sizeof(struct GNUNET_TUN_IPv6Header)
1315 + sizeof(struct GNUNET_TUN_TcpHeader)
1316 + sizeof(struct GNUNET_MessageHeader)
1317 + sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
1318 {
1319 char buf[size] GNUNET_ALIGN;
1320 struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
1321 struct GNUNET_TUN_Layer2PacketHeader *tun =
1322 (struct GNUNET_TUN_Layer2PacketHeader *) &msg[1];
1323 struct GNUNET_TUN_IPv6Header *ipv6 =
1324 (struct GNUNET_TUN_IPv6Header *) &tun[1];
1325 struct GNUNET_TUN_TcpHeader *tcp =
1326 (struct GNUNET_TUN_TcpHeader *) &ipv6[1];
1328 msg->size = htons (size);
1329 tun->flags = htons (0);
1330 tun->proto = htons (ETH_P_IPV6);
1332 IPPROTO_TCP,
1333 sizeof(struct GNUNET_TUN_TcpHeader)
1334 + mlen,
1335 &ts->destination_ip.v6,
1336 &ts->source_ip.v6);
1337 *tcp = data->tcp_header;
1338 tcp->source_port = htons (ts->destination_port);
1339 tcp->destination_port = htons (ts->source_port);
1341 GNUNET_memcpy (&tcp[1], &data[1], mlen);
1342 (void) GNUNET_HELPER_send (helper_handle, msg, GNUNET_YES, NULL, NULL);
1343 }
1344 }
1345 break;
1346 }
1348 GNUNET_TIME_absolute_get ().abs_value_us);
1350}
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:165
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:135
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 1362 of file gnunet-service-vpn.c.

1365{
1366 struct GNUNET_MQ_MessageHandler cadet_handlers[] =
1367 { GNUNET_MQ_hd_var_size (udp_back,
1370 ts),
1371 GNUNET_MQ_hd_var_size (tcp_back,
1374 ts),
1375 GNUNET_MQ_hd_var_size (icmp_back,
1378 ts),
1380
1382 ts,
1383 target,
1384 port,
1385 NULL,
1387 cadet_handlers);
1388}
static uint16_t port
Port number.
Definition: gnunet-bcd.c:146
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:1030
#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 1402 of file gnunet-service-vpn.c.

1408{
1409 struct ChannelState *ts = cls;
1410 struct GNUNET_HashCode port;
1411
1413 "Exit %s found for destination %s!\n",
1414 GNUNET_i2s (id),
1417 ts->search = NULL;
1418 switch (ts->af)
1419 {
1420 case AF_INET:
1421 /* these must match the strings used in gnunet-daemon-exit */
1424 &port);
1425 break;
1426
1427 case AF_INET6:
1428 /* these must match the strings used in gnunet-daemon-exit */
1431 &port);
1432 break;
1433
1434 default:
1435 GNUNET_break (0);
1436 return;
1437 }
1439 "Creating tunnel to %s for destination %s!\n",
1440 GNUNET_i2s (id),
1442 ts->channel = create_channel (ts, id, &port);
1443}
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 1454 of file gnunet-service-vpn.c.

1455{
1456 struct ChannelState *ts;
1457
1459 gettext_noop ("# Cadet channels created"),
1460 1,
1461 GNUNET_NO);
1462 ts = GNUNET_new (struct ChannelState);
1463 ts->af = client_af;
1464 ts->destination = *dt->destination;
1465 ts->destination.heap_node = NULL; /* copy is NOT in destination heap */
1467 if (dt->destination->is_service)
1468 {
1470
1474 ts->destination_port,
1475 &cadet_port);
1476 ts->channel =
1477 create_channel (ts,
1479 &cadet_port);
1480
1481 if (NULL == ts->channel)
1482 {
1483 GNUNET_break (0);
1484 GNUNET_free (ts);
1485 return NULL;
1486 }
1488 "Creating channel to peer %s offering service %s on port %u\n",
1489 GNUNET_i2s (
1493 (unsigned int) ts->destination_port);
1494 }
1495 else
1496 {
1497 char *policy;
1498
1500 {
1501 case AF_INET: {
1503
1505 exit_destination
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 exit_destination
1521 .ip.v6,
1522 dt->destination_port,
1523 address);
1524 GNUNET_asprintf (&policy,
1525 "%s%s",
1527 address);
1528 break;
1529 }
1530
1531 default:
1532 GNUNET_assert (0);
1533 break;
1534 }
1535
1537 "Requesting connect by string: %s\n",
1538 policy);
1539 ts->search = GNUNET_REGEX_search (cfg, policy, &handle_regex_result, ts);
1540 GNUNET_free (policy);
1541 }
1542 return ts;
1543}
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_REGEX_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
void GNUNET_REGEX_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_REGEX_ipv4toregexsearch.
#define GNUNET_TUN_IPV6_REGEXLEN
Maximum regex string length for use with GNUNET_REGEX_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: tun.c:57
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_ipv4toregexsearch(), GNUNET_REGEX_ipv6toregexsearch(), GNUNET_REGEX_search(), GNUNET_STATISTICS_update(), GNUNET_TUN_compute_service_cadet_port(), GNUNET_TUN_IPV4_REGEXLEN, GNUNET_TUN_IPV6_REGEXLEN, 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 1552 of file gnunet-service-vpn.c.

1553{
1554 struct ChannelState *ts;
1555
1557 GNUNET_assert (NULL != ts);
1558 if (except == ts)
1559 return; /* can't do this */
1561 "Tearing down expired channel to %s\n",
1563 free_channel_state (ts);
1564}
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 1579 of file gnunet-service-vpn.c.

1586{
1587 struct GNUNET_HashCode key;
1588 struct ChannelState *ts;
1589 size_t alen;
1590 size_t mlen;
1591 struct GNUNET_MQ_Envelope *env;
1592 const struct GNUNET_TUN_UdpHeader *udp;
1593 const struct GNUNET_TUN_TcpHeader *tcp;
1594 const struct GNUNET_TUN_IcmpHeader *icmp;
1595 struct DestinationChannel *dt;
1596 uint16_t source_port;
1597 uint16_t destination_port;
1598
1599 switch (protocol)
1600 {
1601 case IPPROTO_UDP: {
1602 if (payload_length < sizeof(struct GNUNET_TUN_UdpHeader))
1603 {
1604 /* blame kernel? */
1605 GNUNET_break (0);
1606 return;
1607 }
1608 tcp = NULL; /* make compiler happy */
1609 icmp = NULL; /* make compiler happy */
1610 udp = payload;
1611 if (udp->len < sizeof(struct GNUNET_TUN_UdpHeader))
1612 {
1613 GNUNET_break_op (0);
1614 return;
1615 }
1616 source_port = ntohs (udp->source_port);
1617 destination_port = ntohs (udp->destination_port);
1619 IPPROTO_UDP,
1620 source_ip,
1621 source_port,
1622 destination_ip,
1624 &key);
1625 }
1626 break;
1627
1628 case IPPROTO_TCP: {
1629 if (payload_length < sizeof(struct GNUNET_TUN_TcpHeader))
1630 {
1631 /* blame kernel? */
1632 GNUNET_break (0);
1633 return;
1634 }
1635 udp = NULL; /* make compiler happy */
1636 icmp = NULL; /* make compiler happy */
1637 tcp = payload;
1638 if (tcp->off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
1639 {
1640 GNUNET_break_op (0);
1641 return;
1642 }
1643 source_port = ntohs (tcp->source_port);
1644 destination_port = ntohs (tcp->destination_port);
1646 IPPROTO_TCP,
1647 source_ip,
1648 source_port,
1649 destination_ip,
1651 &key);
1652 }
1653 break;
1654
1655 case IPPROTO_ICMP:
1656 case IPPROTO_ICMPV6: {
1657 if ((AF_INET == af) ^ (protocol == IPPROTO_ICMP))
1658 {
1659 GNUNET_break (0);
1660 return;
1661 }
1662 if (payload_length < sizeof(struct GNUNET_TUN_IcmpHeader))
1663 {
1664 /* blame kernel? */
1665 GNUNET_break (0);
1666 return;
1667 }
1668 tcp = NULL; /* make compiler happy */
1669 udp = NULL; /* make compiler happy */
1670 icmp = payload;
1671 source_port = 0;
1672 destination_port = 0;
1674 protocol,
1675 source_ip,
1676 0,
1677 destination_ip,
1678 0,
1679 &key);
1680 }
1681 break;
1682
1683 default:
1685 _ ("Protocol %u not supported, dropping\n"),
1686 (unsigned int) protocol);
1687 return;
1688 }
1689 alen = 0;
1690 if (! destination->is_service)
1691 {
1693 {
1694 case AF_INET:
1695 alen = sizeof(struct in_addr);
1696 break;
1697
1698 case AF_INET6:
1699 alen = sizeof(struct in6_addr);
1700 break;
1701
1702 default:
1703 GNUNET_assert (0);
1704 }
1705
1706 {
1707 char sbuf[INET6_ADDRSTRLEN];
1708 char dbuf[INET6_ADDRSTRLEN];
1709 char xbuf[INET6_ADDRSTRLEN];
1710
1711 GNUNET_log (
1713 "Routing %s packet from [%s]:%u -> [%s]:%u to destination [%s]:%u\n",
1714 (protocol == IPPROTO_TCP) ? "TCP" : "UDP",
1715 inet_ntop (af, source_ip, sbuf, sizeof(sbuf)),
1716 source_port,
1717 inet_ntop (af, destination_ip, dbuf, sizeof(dbuf)),
1718 destination_port,
1719 inet_ntop (destination->details.exit_destination.af,
1720 &destination->details.exit_destination.ip,
1721 xbuf,
1722 sizeof(xbuf)),
1723 destination_port);
1724 }
1725 for (dt = destination->dt_head; NULL != dt; dt = dt->next)
1726 if (dt->destination_port == destination_port)
1727 break;
1728 }
1729 else
1730 {
1731 {
1732 char sbuf[INET6_ADDRSTRLEN];
1733 char dbuf[INET6_ADDRSTRLEN];
1734
1735 GNUNET_log (
1737 "Routing %s packet from [%s]:%u -> [%s]:%u to service %s at peer %s\n",
1738 (protocol == IPPROTO_TCP) ? "TCP" : "UDP",
1739 inet_ntop (af, source_ip, sbuf, sizeof(sbuf)),
1740 source_port,
1741 inet_ntop (af, destination_ip, dbuf, sizeof(dbuf)),
1742 destination_port,
1743 GNUNET_h2s (
1746 }
1747 for (dt = destination->dt_head; NULL != dt; dt = dt->next)
1748 if (dt->destination_port == destination_port)
1749 break;
1750 }
1751 if (NULL == dt)
1752 {
1753 dt = GNUNET_new (struct DestinationChannel);
1754 dt->destination = destination;
1756 destination->dt_tail,
1757 dt);
1758 dt->destination_port = destination_port;
1759 }
1760
1761 /* see if we have an existing channel for this destination */
1763 if (NULL == ts)
1764 {
1766 "Creating new channel for key %s\n",
1767 GNUNET_h2s (&key));
1768 /* need to either use the existing channel from the destination (if still
1769 available) or create a fresh one */
1770 ts = create_channel_to_destination (dt, af);
1771 if (NULL == ts)
1772 return;
1773 /* now bind existing "unbound" channel to our IP/port tuple */
1774 ts->protocol = protocol;
1775 ts->af = af;
1776 if (AF_INET == af)
1777 {
1778 ts->source_ip.v4 = *(const struct in_addr *) source_ip;
1779 ts->destination_ip.v4 = *(const struct in_addr *) destination_ip;
1780 }
1781 else
1782 {
1783 ts->source_ip.v6 = *(const struct in6_addr *) source_ip;
1784 ts->destination_ip.v6 = *(const struct in6_addr *) destination_ip;
1785 }
1786 ts->source_port = source_port;
1787 ts->destination_port = destination_port;
1788 ts->heap_node =
1790 ts,
1791 GNUNET_TIME_absolute_get ().abs_value_us);
1795 &key,
1796 ts,
1799 gettext_noop ("# Active channels"),
1800 1,
1801 GNUNET_NO);
1804 expire_channel (ts);
1805 }
1806 else
1807 {
1810 .abs_value_us);
1811 }
1812 if (NULL == ts->channel)
1813 {
1815 "Packet dropped, channel to %s not yet ready (%s)\n",
1817 (NULL == ts->search) ? "EXIT search failed"
1818 : "EXIT search active");
1820 gettext_noop (
1821 "# Packets dropped (channel not yet online)"),
1822 1,
1823 GNUNET_NO);
1824 return;
1825 }
1826
1827 /* send via channel */
1828 switch (protocol)
1829 {
1830 case IPPROTO_UDP:
1831 if (destination->is_service)
1832 {
1834
1835 mlen = sizeof(struct GNUNET_EXIT_UdpServiceMessage) + payload_length
1836 - sizeof(struct GNUNET_TUN_UdpHeader);
1837 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1838 {
1839 GNUNET_break (0);
1840 return;
1841 }
1842 env = GNUNET_MQ_msg_extra (usm,
1843 payload_length
1844 - sizeof(struct GNUNET_TUN_UdpHeader),
1846 /* if the source port is below 32000, we assume it has a special
1847 meaning; if not, we pick a random port (this is a heuristic) */
1848 usm->source_port =
1849 (ntohs (udp->source_port) < 32000) ? udp->source_port : 0;
1850 usm->destination_port = udp->destination_port;
1851 GNUNET_memcpy (&usm[1],
1852 &udp[1],
1853 payload_length - sizeof(struct GNUNET_TUN_UdpHeader));
1854 }
1855 else
1856 {
1858 struct in_addr *ip4dst;
1859 struct in6_addr *ip6dst;
1860 void *payload_tmp;
1861
1862 mlen = sizeof(struct GNUNET_EXIT_UdpInternetMessage) + alen
1863 + payload_length - sizeof(struct GNUNET_TUN_UdpHeader);
1864 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1865 {
1866 GNUNET_break (0);
1867 return;
1868 }
1869 env = GNUNET_MQ_msg_extra (uim,
1870 payload_length + alen
1871 - sizeof(struct GNUNET_TUN_UdpHeader),
1873 uim->af = htonl (destination->details.exit_destination.af);
1874 uim->source_port =
1875 (ntohs (udp->source_port) < 32000) ? udp->source_port : 0;
1876 uim->destination_port = udp->destination_port;
1877 switch (destination->details.exit_destination.af)
1878 {
1879 case AF_INET:
1880 ip4dst = (struct in_addr *) &uim[1];
1881 *ip4dst = destination->details.exit_destination.ip.v4;
1882 payload_tmp = &ip4dst[1];
1883 break;
1884
1885 case AF_INET6:
1886 ip6dst = (struct in6_addr *) &uim[1];
1887 *ip6dst = destination->details.exit_destination.ip.v6;
1888 payload_tmp = &ip6dst[1];
1889 break;
1890
1891 default:
1892 GNUNET_assert (0);
1893 }
1894 GNUNET_memcpy (payload_tmp,
1895 &udp[1],
1896 payload_length - sizeof(struct GNUNET_TUN_UdpHeader));
1897 }
1898 break;
1899
1900 case IPPROTO_TCP:
1901 if (GNUNET_NO == ts->is_established)
1902 {
1903 if (destination->is_service)
1904 {
1906
1907 mlen = sizeof(struct GNUNET_EXIT_TcpServiceStartMessage)
1908 + payload_length - sizeof(struct GNUNET_TUN_TcpHeader);
1909 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1910 {
1911 GNUNET_break (0);
1912 return;
1913 }
1914 env =
1916 payload_length
1917 - sizeof(struct GNUNET_TUN_TcpHeader),
1919 tsm->reserved = htonl (0);
1920 tsm->tcp_header = *tcp;
1921 GNUNET_memcpy (&tsm[1],
1922 &tcp[1],
1923 payload_length - sizeof(struct GNUNET_TUN_TcpHeader));
1924 }
1925 else
1926 {
1928 struct in_addr *ip4dst;
1929 struct in6_addr *ip6dst;
1930 void *payload_tmp;
1931
1932 mlen = sizeof(struct GNUNET_EXIT_TcpInternetStartMessage) + alen
1933 + payload_length - sizeof(struct GNUNET_TUN_TcpHeader);
1934 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1935 {
1936 GNUNET_break (0);
1937 return;
1938 }
1939 env =
1941 payload_length + alen
1942 - sizeof(struct GNUNET_TUN_TcpHeader),
1944 tim->af = htonl (destination->details.exit_destination.af);
1945 tim->tcp_header = *tcp;
1946 switch (destination->details.exit_destination.af)
1947 {
1948 case AF_INET:
1949 ip4dst = (struct in_addr *) &tim[1];
1950 *ip4dst = destination->details.exit_destination.ip.v4;
1951 payload_tmp = &ip4dst[1];
1952 break;
1953
1954 case AF_INET6:
1955 ip6dst = (struct in6_addr *) &tim[1];
1956 *ip6dst = destination->details.exit_destination.ip.v6;
1957 payload_tmp = &ip6dst[1];
1958 break;
1959
1960 default:
1961 GNUNET_assert (0);
1962 }
1963 GNUNET_memcpy (payload_tmp,
1964 &tcp[1],
1965 payload_length - sizeof(struct GNUNET_TUN_TcpHeader));
1966 }
1967 }
1968 else
1969 {
1970 struct GNUNET_EXIT_TcpDataMessage *tdm;
1971
1972 mlen = sizeof(struct GNUNET_EXIT_TcpDataMessage) + payload_length
1973 - sizeof(struct GNUNET_TUN_TcpHeader);
1974 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1975 {
1976 GNUNET_break (0);
1977 return;
1978 }
1979 env = GNUNET_MQ_msg_extra (tdm,
1980 payload_length
1981 - sizeof(struct GNUNET_TUN_TcpHeader),
1983 tdm->reserved = htonl (0);
1984 tdm->tcp_header = *tcp;
1985 GNUNET_memcpy (&tdm[1],
1986 &tcp[1],
1987 payload_length - sizeof(struct GNUNET_TUN_TcpHeader));
1988 }
1989 break;
1990
1991 case IPPROTO_ICMP:
1992 case IPPROTO_ICMPV6:
1993 if (destination->is_service)
1994 {
1996
1997 /* ICMP protocol translation will be done by the receiver (as we don't know
1998 the target AF); however, we still need to possibly discard the payload
1999 depending on the ICMP type */
2000 switch (af)
2001 {
2002 case AF_INET:
2003 switch (icmp->type)
2004 {
2007 break;
2008
2012 /* throw away ICMP payload, won't be useful for the other side anyway */
2013 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2014 break;
2015
2016 default:
2018 gettext_noop (
2019 "# ICMPv4 packets dropped (not allowed)"),
2020 1,
2021 GNUNET_NO);
2022 return;
2023 }
2024 /* end of AF_INET */
2025 break;
2026
2027 case AF_INET6:
2028 switch (icmp->type)
2029 {
2034 /* throw away ICMP payload, won't be useful for the other side anyway */
2035 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2036 break;
2037
2040 break;
2041
2042 default:
2044 gettext_noop (
2045 "# ICMPv6 packets dropped (not allowed)"),
2046 1,
2047 GNUNET_NO);
2048 return;
2049 }
2050 /* end of AF_INET6 */
2051 break;
2052
2053 default:
2054 GNUNET_assert (0);
2055 break;
2056 }
2057
2058 /* update length calculations, as payload_length may have changed */
2059 mlen = sizeof(struct GNUNET_EXIT_IcmpServiceMessage) + alen
2060 + payload_length - sizeof(struct GNUNET_TUN_IcmpHeader);
2061 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
2062 {
2063 GNUNET_break (0);
2064 return;
2065 }
2066
2067 env = GNUNET_MQ_msg_extra (ism,
2068 payload_length
2069 - sizeof(struct GNUNET_TUN_IcmpHeader),
2071 ism->af = htonl (af); /* need to tell destination ICMP protocol family! */
2072 ism->icmp_header = *icmp;
2073 GNUNET_memcpy (&ism[1],
2074 &icmp[1],
2075 payload_length - sizeof(struct GNUNET_TUN_IcmpHeader));
2076 }
2077 else
2078 {
2080 struct in_addr *ip4dst;
2081 struct in6_addr *ip6dst;
2082 void *payload_tmp;
2083 uint8_t new_type;
2084
2085 new_type = icmp->type;
2086 /* Perform ICMP protocol-translation (depending on destination AF and source AF)
2087 and throw away ICMP payload depending on ICMP message type */
2088 switch (af)
2089 {
2090 case AF_INET:
2091 switch (icmp->type)
2092 {
2094 if (destination->details.exit_destination.af == AF_INET6)
2096 break;
2097
2099 if (destination->details.exit_destination.af == AF_INET6)
2101 break;
2102
2104 if (destination->details.exit_destination.af == AF_INET6)
2106 /* throw away IP-payload, exit will have to make it up anyway */
2107 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2108 break;
2109
2111 if (destination->details.exit_destination.af == AF_INET6)
2113 /* throw away IP-payload, exit will have to make it up anyway */
2114 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2115 break;
2116
2118 if (destination->details.exit_destination.af == AF_INET6)
2119 {
2121 stats,
2122 gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"),
2123 1,
2124 GNUNET_NO);
2125 return;
2126 }
2127 /* throw away IP-payload, exit will have to make it up anyway */
2128 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2129 break;
2130
2131 default:
2133 stats,
2134 gettext_noop ("# ICMPv4 packets dropped (type not allowed)"),
2135 1,
2136 GNUNET_NO);
2137 return;
2138 }
2139 /* end of AF_INET */
2140 break;
2141
2142 case AF_INET6:
2143 switch (icmp->type)
2144 {
2146 if (destination->details.exit_destination.af == AF_INET)
2148 /* throw away IP-payload, exit will have to make it up anyway */
2149 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2150 break;
2151
2153 if (destination->details.exit_destination.af == AF_INET)
2155 /* throw away IP-payload, exit will have to make it up anyway */
2156 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2157 break;
2158
2160 if (destination->details.exit_destination.af == AF_INET)
2161 {
2163 stats,
2164 gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"),
2165 1,
2166 GNUNET_NO);
2167 return;
2168 }
2169 /* throw away IP-payload, exit will have to make it up anyway */
2170 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2171 break;
2172
2174 if (destination->details.exit_destination.af == AF_INET)
2175 {
2177 stats,
2178 gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"),
2179 1,
2180 GNUNET_NO);
2181 return;
2182 }
2183 /* throw away IP-payload, exit will have to make it up anyway */
2184 payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2185 break;
2186
2188 if (destination->details.exit_destination.af == AF_INET)
2190 break;
2191
2193 if (destination->details.exit_destination.af == AF_INET)
2195 break;
2196
2197 default:
2199 stats,
2200 gettext_noop ("# ICMPv6 packets dropped (type not allowed)"),
2201 1,
2202 GNUNET_NO);
2203 return;
2204 }
2205 /* end of AF_INET6 */
2206 break;
2207
2208 default:
2209 GNUNET_assert (0);
2210 }
2211
2212 /* update length calculations, as payload_length may have changed */
2213 mlen = sizeof(struct GNUNET_EXIT_IcmpInternetMessage) + alen
2214 + payload_length - sizeof(struct GNUNET_TUN_IcmpHeader);
2215 if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
2216 {
2217 GNUNET_break (0);
2218 return;
2219 }
2220 env = GNUNET_MQ_msg_extra (iim,
2221 alen + payload_length
2222 - sizeof(struct GNUNET_TUN_IcmpHeader),
2224 iim->icmp_header = *icmp;
2225 iim->icmp_header.type = new_type;
2226 iim->af = htonl (destination->details.exit_destination.af);
2227 switch (destination->details.exit_destination.af)
2228 {
2229 case AF_INET:
2230 ip4dst = (struct in_addr *) &iim[1];
2231 *ip4dst = destination->details.exit_destination.ip.v4;
2232 payload_tmp = &ip4dst[1];
2233 break;
2234
2235 case AF_INET6:
2236 ip6dst = (struct in6_addr *) &iim[1];
2237 *ip6dst = destination->details.exit_destination.ip.v6;
2238 payload_tmp = &ip6dst[1];
2239 break;
2240
2241 default:
2242 GNUNET_assert (0);
2243 }
2244 GNUNET_memcpy (payload_tmp,
2245 &icmp[1],
2246 payload_length - sizeof(struct GNUNET_TUN_IcmpHeader));
2247 }
2248 break;
2249
2250 default:
2251 /* not supported above, how can we get here !? */
2252 GNUNET_assert (0);
2253 break;
2254 }
2256 send_to_channel (ts, env);
2257}
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 2273 of file gnunet-service-vpn.c.

2274{
2275 const struct GNUNET_TUN_Layer2PacketHeader *tun;
2276 size_t mlen;
2277 struct GNUNET_HashCode key;
2278 struct DestinationEntry *de;
2279
2281 gettext_noop (
2282 "# Packets received from TUN interface"),
2283 1,
2284 GNUNET_NO);
2285 mlen = ntohs (message->size);
2286 if ((ntohs (message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) ||
2287 (mlen < sizeof(struct GNUNET_MessageHeader)
2288 + sizeof(struct GNUNET_TUN_Layer2PacketHeader)))
2289 {
2290 GNUNET_break (0);
2291 return GNUNET_OK;
2292 }
2293 tun = (const struct GNUNET_TUN_Layer2PacketHeader *) &message[1];
2294 mlen -= (sizeof(struct GNUNET_MessageHeader)
2295 + sizeof(struct GNUNET_TUN_Layer2PacketHeader));
2296 switch (ntohs (tun->proto))
2297 {
2298 case ETH_P_IPV6: {
2299 const struct GNUNET_TUN_IPv6Header *pkt6;
2300
2301 if (mlen < sizeof(struct GNUNET_TUN_IPv6Header))
2302 {
2303 /* blame kernel */
2304 GNUNET_break (0);
2305 return GNUNET_OK;
2306 }
2307 pkt6 = (const struct GNUNET_TUN_IPv6Header *) &tun[1];
2310 if (NULL == de)
2311 {
2312 char buf[INET6_ADDRSTRLEN];
2313
2314 GNUNET_log (
2316 _ ("Packet received for unmapped destination `%s' (dropping it)\n"),
2317 inet_ntop (AF_INET6, &pkt6->destination_address, buf, sizeof(buf)));
2318 return GNUNET_OK;
2319 }
2320 route_packet (de,
2321 AF_INET6,
2322 pkt6->next_header,
2323 &pkt6->source_address,
2324 &pkt6->destination_address,
2325 &pkt6[1],
2326 mlen - sizeof(struct GNUNET_TUN_IPv6Header));
2327 }
2328 break;
2329
2330 case ETH_P_IPV4: {
2331 struct GNUNET_TUN_IPv4Header *pkt4;
2332
2333 if (mlen < sizeof(struct GNUNET_TUN_IPv4Header))
2334 {
2335 /* blame kernel */
2336 GNUNET_break (0);
2337 return GNUNET_OK;
2338 }
2339 pkt4 = (struct GNUNET_TUN_IPv4Header *) &tun[1];
2342 if (NULL == de)
2343 {
2344 char buf[INET_ADDRSTRLEN];
2345
2346 GNUNET_log (
2348 _ ("Packet received for unmapped destination `%s' (dropping it)\n"),
2349 inet_ntop (AF_INET, &pkt4->destination_address, buf, sizeof(buf)));
2350 return GNUNET_OK;
2351 }
2352 if (pkt4->header_length * 4 != sizeof(struct GNUNET_TUN_IPv4Header))
2353 {
2355 _ ("Received IPv4 packet with options (dropping it)\n"));
2356 return GNUNET_OK;
2357 }
2358 route_packet (de,
2359 AF_INET,
2360 pkt4->protocol,
2361 &pkt4->source_address,
2362 &pkt4->destination_address,
2363 &pkt4[1],
2364 mlen - sizeof(struct GNUNET_TUN_IPv4Header));
2365 }
2366 break;
2367
2368 default:
2369 GNUNET_log (
2371 _ ("Received packet of unknown protocol %d from TUN (dropping it)\n"),
2372 (unsigned int) ntohs (tun->proto));
2373 break;
2374 }
2375 return GNUNET_OK;
2376}
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 2388 of file gnunet-service-vpn.c.

2389{
2390 const char *ipv4addr = vpn_argv[4];
2391 const char *ipv4mask = vpn_argv[5];
2392 struct in_addr addr;
2393 struct in_addr mask;
2394 struct in_addr rnd;
2395 struct GNUNET_HashCode key;
2396 unsigned int tries;
2397
2398 GNUNET_assert (1 == inet_pton (AF_INET, ipv4addr, &addr));
2399 GNUNET_assert (1 == inet_pton (AF_INET, ipv4mask, &mask));
2400 /* Given 192.168.0.1/255.255.0.0, we want a mask
2401 of '192.168.255.255', thus: */
2402 mask.s_addr = addr.s_addr | ~mask.s_addr;
2403 tries = 0;
2404 do
2405 {
2406 tries++;
2407 if (tries > 16)
2408 {
2410 _ (
2411 "Failed to find unallocated IPv4 address in VPN's range\n"))
2412 ;
2413 return GNUNET_SYSERR;
2414 }
2415 /* Pick random IPv4 address within the subnet, except 'addr' or 'mask' itself */
2416 rnd.s_addr =
2418 v4->s_addr = (addr.s_addr | rnd.s_addr) & mask.s_addr;
2419 get_destination_key_from_ip (AF_INET, v4, &key);
2420 }
2421 while ((GNUNET_YES ==
2423 (v4->s_addr == addr.s_addr) || (v4->s_addr == mask.s_addr));
2424 return GNUNET_OK;
2425}
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 2437 of file gnunet-service-vpn.c.

2438{
2439 const char *ipv6addr = vpn_argv[2];
2440 struct in6_addr addr;
2441 struct in6_addr mask;
2442 struct in6_addr rnd;
2443 int i;
2444 struct GNUNET_HashCode key;
2445 unsigned int tries;
2446
2447 GNUNET_assert (1 == inet_pton (AF_INET6, ipv6addr, &addr));
2448 GNUNET_assert (ipv6prefix < 128);
2449 /* Given ABCD::/96, we want a mask of 'ABCD::FFFF:FFFF,
2450 thus: */
2451 mask = addr;
2452 for (i = 127; i >= ipv6prefix; i--)
2453 mask.s6_addr[i / 8] |= (1 << (i % 8));
2454
2455 /* Pick random IPv6 address within the subnet, except 'addr' or 'mask' itself */
2456 tries = 0;
2457 do
2458 {
2459 tries++;
2460 if (tries > 16)
2461 {
2463 _ (
2464 "Failed to find unallocated IPv6 address in VPN's range\n"))
2465 ;
2466 return GNUNET_SYSERR;
2467 }
2468 for (i = 0; i < 16; i++)
2469 {
2470 rnd.s6_addr[i] =
2472 256);
2473 v6->s6_addr[i] = (addr.s6_addr[i] | rnd.s6_addr[i]) & mask.s6_addr[i];
2474 }
2475 get_destination_key_from_ip (AF_INET6, v6, &key);
2476 }
2477 while ((GNUNET_YES ==
2479 (0 == GNUNET_memcmp (v6, &addr)) ||
2480 (0 == GNUNET_memcmp (v6, &mask)));
2481 return GNUNET_OK;
2482}
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 2491 of file gnunet-service-vpn.c.

2492{
2493 struct DestinationChannel *dt;
2494
2496 "Cleaning up destination entry `%s'\n",
2499 gettext_noop ("# Active destinations"),
2500 -1,
2501 GNUNET_NO);
2502 while (NULL != (dt = de->dt_head))
2503 {
2505 GNUNET_free (dt);
2506 }
2507 if (NULL != de->heap_node)
2508 {
2510 de->heap_node = NULL;
2512 GNUNET_YES ==
2514 }
2515 GNUNET_free (de);
2516}
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 2525 of file gnunet-service-vpn.c.

2526{
2527 struct DestinationEntry *de;
2528
2530 GNUNET_assert (NULL != de);
2531 if (except == de)
2532 return; /* can't do this */
2534}
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 2552 of file gnunet-service-vpn.c.

2556{
2557 *addr = NULL;
2558 switch (*result_af)
2559 {
2560 case AF_INET:
2561 if (GNUNET_OK != allocate_v4_address (v4))
2562 *result_af = AF_UNSPEC;
2563 else
2564 *addr = v4;
2565 break;
2566
2567 case AF_INET6:
2568 if (GNUNET_OK != allocate_v6_address (v6))
2569 *result_af = AF_UNSPEC;
2570 else
2571 *addr = v6;
2572 break;
2573
2574 case AF_UNSPEC:
2575 if (GNUNET_OK == allocate_v4_address (v4))
2576 {
2577 *addr = v4;
2578 *result_af = AF_INET;
2579 }
2580 else if (GNUNET_OK == allocate_v6_address (v6))
2581 {
2582 *addr = v6;
2583 *result_af = AF_INET6;
2584 }
2585 break;
2586
2587 default:
2588 GNUNET_break (0);
2589 return GNUNET_SYSERR;
2590 }
2591 return GNUNET_OK;
2592}
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 2605 of file gnunet-service-vpn.c.

2607{
2608 size_t alen;
2609 int addr_af;
2610
2611 alen = ntohs (msg->header.size) - sizeof(struct RedirectToIpRequestMessage);
2612 addr_af = (int) htonl (msg->addr_af);
2613 switch (addr_af)
2614 {
2615 case AF_INET:
2616 if (alen != sizeof(struct in_addr))
2617 {
2618 GNUNET_break (0);
2619 return GNUNET_SYSERR;
2620 }
2621 break;
2622
2623 case AF_INET6:
2624 if (alen != sizeof(struct in6_addr))
2625 {
2626 GNUNET_break (0);
2627 return GNUNET_SYSERR;
2628 }
2629 break;
2630
2631 default:
2632 GNUNET_break (0);
2633 return GNUNET_SYSERR;
2634 }
2635 return GNUNET_OK;
2636}
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 2648 of file gnunet-service-vpn.c.

2650{
2651 struct GNUNET_SERVICE_Client *client = cls;
2652 size_t alen;
2653 int addr_af;
2654 int result_af;
2655 struct in_addr v4;
2656 struct in6_addr v6;
2657 void *addr;
2658 struct DestinationEntry *de;
2659 struct GNUNET_HashCode key;
2660
2661 alen = ntohs (msg->header.size) - sizeof(struct RedirectToIpRequestMessage);
2662 addr_af = (int) htonl (msg->addr_af);
2663 /* allocate response IP */
2664 result_af = (int) htonl (msg->result_af);
2665 if (GNUNET_OK != allocate_response_ip (&result_af, &addr, &v4, &v6))
2666 {
2668 return;
2669 }
2670 /* send reply with our IP address */
2671 send_client_reply (client, msg->request_id, result_af, addr);
2672 if (result_af == AF_UNSPEC)
2673 {
2674 /* failure, we're done */
2676 return;
2677 }
2678
2679 {
2680 char sbuf[INET6_ADDRSTRLEN];
2681 char dbuf[INET6_ADDRSTRLEN];
2682
2684 "Allocated address %s for redirection via exit to %s\n",
2685 inet_ntop (result_af, addr, sbuf, sizeof(sbuf)),
2686 inet_ntop (addr_af, &msg[1], dbuf, sizeof(dbuf)));
2687 }
2688
2689 /* setup destination record */
2690 de = GNUNET_new (struct DestinationEntry);
2691 de->is_service = GNUNET_NO;
2693 GNUNET_memcpy (&de->details.exit_destination.ip, &msg[1], alen);
2695 de->key = key;
2698 &key,
2699 de,
2702 de,
2704 msg->expiration_time)
2705 .abs_value_us);
2707 gettext_noop ("# Active destinations"),
2708 1,
2709 GNUNET_NO);
2712 expire_destination (de);
2714}
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:2418
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2389
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:741
Handle to a client that is connected to a service.
Definition: service.c:249
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 2726 of file gnunet-service-vpn.c.

2729{
2730 struct GNUNET_SERVICE_Client *client = cls;
2731 int result_af;
2732 struct in_addr v4;
2733 struct in6_addr v6;
2734 void *addr;
2735 struct DestinationEntry *de;
2736 struct GNUNET_HashCode key;
2737 struct DestinationChannel *dt;
2738
2739 /* allocate response IP */
2740 result_af = (int) htonl (msg->result_af);
2741 if (GNUNET_OK != allocate_response_ip (&result_af, &addr, &v4, &v6))
2742 {
2743 GNUNET_break (0);
2745 return;
2746 }
2747 send_client_reply (client, msg->request_id, result_af, addr);
2748 if (result_af == AF_UNSPEC)
2749 {
2750 /* failure, we're done */
2752 _ ("Failed to allocate IP address for new destination\n"));
2754 return;
2755 }
2756
2757 {
2758 char sbuf[INET6_ADDRSTRLEN];
2759
2761 "Allocated address %s for redirection to service %s on peer %s\n",
2762 inet_ntop (result_af, addr, sbuf, sizeof(sbuf)),
2763 GNUNET_h2s (&msg->service_descriptor),
2764 GNUNET_i2s (&msg->target));
2765 }
2766
2767 /* setup destination record */
2768 de = GNUNET_new (struct DestinationEntry);
2769 de->is_service = GNUNET_YES;
2770 de->details.service_destination.target = msg->target;
2771 de->details.service_destination.service_descriptor = msg->service_descriptor;
2772 get_destination_key_from_ip (result_af, addr, &key);
2773 de->key = key;
2776 &key,
2777 de,
2780 de,
2782 msg->expiration_time)
2783 .abs_value_us);
2786 expire_destination (de);
2787
2788 dt = GNUNET_new (struct DestinationChannel);
2789 dt->destination = de;
2791 /* we're done */
2793}
@ 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 2805 of file gnunet-service-vpn.c.

2806{
2807 struct DestinationEntry *de = value;
2808
2810 return GNUNET_OK;
2811}
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 2823 of file gnunet-service-vpn.c.

2824{
2825 struct ChannelState *ts = value;
2826
2828 "Tearing down channel to `%s' during cleanup\n",
2830 free_channel_state (ts);
2831 return GNUNET_OK;
2832}

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

2842{
2843 unsigned int i;
2844
2845 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "VPN is shutting down\n");
2846 if (NULL != destination_map)
2847 {
2850 NULL);
2852 destination_map = NULL;
2853 }
2854 if (NULL != destination_heap)
2855 {
2857 destination_heap = NULL;
2858 }
2859 if (NULL != channel_map)
2860 {
2863 channel_map = NULL;
2864 }
2865 if (NULL != channel_heap)
2866 {
2868 channel_heap = NULL;
2869 }
2870 if (NULL != cadet_handle)
2871 {
2873 cadet_handle = NULL;
2874 }
2875 if (NULL != helper_handle)
2876 {
2879 helper_handle = NULL;
2880 }
2881 if (NULL != stats)
2882 {
2884 stats = NULL;
2885 }
2886 for (i = 0; i < 5; i++)
2887 GNUNET_free (vpn_argv[i]);
2888}
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:777
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 2900 of file gnunet-service-vpn.c.

2903{
2904 return c;
2905}

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

2919{
2920 GNUNET_assert (c == internal_cls);
2921}

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

2935{
2936 char *ifname;
2937 char *ipv6addr;
2938 char *ipv6prefix_s;
2939 char *ipv4addr;
2940 char *ipv4mask;
2941 struct in_addr v4;
2942 struct in6_addr v6;
2943 char *binary;
2944
2945 cfg = cfg_;
2947 cfg,
2948 "gnunet-helper-vpn");
2949
2950 if (GNUNET_YES !=
2952 binary,
2953 GNUNET_YES,
2954 "-d gnunet-vpn - - 169.1.3.3.7 255.255.255.0")) // ipv4 only please!
2955 {
2957 "`%s' is not SUID or the path is invalid, refusing to run.\n",
2958 binary);
2959 GNUNET_free (binary);
2960 global_ret = 1;
2961 /* we won't "really" exit here, as the 'service' is still running;
2962 however, as no handlers are registered, the service won't do
2963 anything either */
2964 return;
2965 }
2967 if (GNUNET_OK !=
2969 "VPN",
2970 "MAX_MAPPING",
2973 if (GNUNET_OK !=
2975 "VPN",
2976 "MAX_TUNNELS",
2979
2982 GNUNET_NO);
2985 channel_map =
2988
2989
2990 vpn_argv[0] = GNUNET_strdup ("vpn-gnunet");
2991 if (GNUNET_SYSERR ==
2992 GNUNET_CONFIGURATION_get_value_string (cfg, "VPN", "IFNAME", &ifname))
2993 {
2995 GNUNET_free (binary);
2997 return;
2998 }
2999 vpn_argv[1] = ifname;
3000 ipv6addr = NULL;
3001 if (GNUNET_OK == GNUNET_NETWORK_test_pf (PF_INET6))
3002 {
3004 "VPN",
3005 "IPV6ADDR",
3006 &ipv6addr)) ||
3007 (1 != inet_pton (AF_INET6, ipv6addr, &v6))))
3008 {
3010 "VPN",
3011 "IPV6ADDR",
3012 _ ("Must specify valid IPv6 address"));
3013 GNUNET_free (binary);
3015 GNUNET_free (ipv6addr);
3016 return;
3017 }
3018 vpn_argv[2] = ipv6addr;
3019 ipv6prefix_s = NULL;
3020 if (GNUNET_SYSERR ==
3022 "VPN",
3023 "IPV6PREFIX",
3024 &ipv6prefix_s))
3025 {
3027 "VPN",
3028 "IPV6PREFIX");
3030 GNUNET_free (ipv6prefix_s);
3031 return;
3032 }
3033 vpn_argv[3] = ipv6prefix_s;
3034 if ((GNUNET_OK !=
3036 "VPN",
3037 "IPV6PREFIX",
3038 &ipv6prefix)) ||
3039 (ipv6prefix >= 127))
3040 {
3042 "VPN",
3043 "IPV4MASK",
3044 _ ("Must specify valid IPv6 mask"));
3045 GNUNET_free (binary);
3047 return;
3048 }
3049 }
3050 else
3051 {
3053 _ (
3054 "IPv6 support disabled as this system does not support IPv6\n"));
3055 vpn_argv[2] = GNUNET_strdup ("-");
3056 vpn_argv[3] = GNUNET_strdup ("-");
3057 }
3058 if (GNUNET_OK == GNUNET_NETWORK_test_pf (PF_INET))
3059 {
3060 ipv4addr = NULL;
3061 if (((GNUNET_SYSERR ==
3063 "vpn",
3064 "IPV4ADDR",
3065 &ipv4addr)) ||
3066 (1 != inet_pton (AF_INET, ipv4addr, &v4))))
3067 {
3069 "VPN",
3070 "IPV4ADDR",
3071 _ ("Must specify valid IPv4 address"));
3072 GNUNET_free (binary);
3074 GNUNET_free (ipv4addr);
3075 return;
3076 }
3077 vpn_argv[4] = ipv4addr;
3078 ipv4mask = NULL;
3079 if (((GNUNET_SYSERR ==
3081 "vpn",
3082 "IPV4MASK",
3083 &ipv4mask)) ||
3084 (1 != inet_pton (AF_INET, ipv4mask, &v4))))
3085 {
3087 "VPN",
3088 "IPV4MASK",
3089 _ ("Must specify valid IPv4 mask"));
3090 GNUNET_free (binary);
3092 GNUNET_free (ipv4mask);
3093 return;
3094 }
3095 vpn_argv[5] = ipv4mask;
3096 }
3097 else
3098 {
3100 _ (
3101 "IPv4 support disabled as this system does not support IPv4\n"));
3102 vpn_argv[4] = GNUNET_strdup ("-");
3103 vpn_argv[5] = GNUNET_strdup ("-");
3104 }
3105 vpn_argv[6] = NULL;
3106
3108 // FIXME never opens ports???
3110 GNUNET_NO,
3111 binary,
3112 vpn_argv,
3114 NULL,
3115 NULL);
3116 GNUNET_free (binary);
3118}
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:897
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(const struct GNUNET_OS_ProjectData *pd, 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
const struct GNUNET_OS_ProjectData * GNUNET_OS_project_data_gnunet(void)
Return default project data used by 'libgnunetutil' for GNUnet.
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.
char * GNUNET_OS_get_suid_binary_path(const struct GNUNET_OS_ProjectData *pd, 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 ...
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:1339
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_OS_project_data_gnunet(), 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 ( GNUNET_OS_project_data_gnunet()  ,
"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 304 of file gnunet-service-vpn.c.

Referenced by run().

◆ cfg

const struct GNUNET_CONFIGURATION_Handle* cfg
static

Configuration we use.

Definition at line 309 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 314 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 320 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 325 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 331 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 337 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 347 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 352 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 357 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 363 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 369 of file gnunet-service-vpn.c.

Referenced by route_packet(), and run().