GNUnet  0.11.x
Data Structures | Macros | Functions | Variables
gnunet-service-vpn.c File Reference

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

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

Go to the source code of this file.

Data Structures

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

Macros

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

Functions

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

Variables

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

Detailed Description

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

Author
Philipp Toelke
Christian Grothoff

TODO:

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

Referenced by send_to_channel().

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

References GNUNET_assert, and GNUNET_CRYPTO_hash().

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

386 {
387  switch (af)
388  {
389  case AF_INET:
390  GNUNET_CRYPTO_hash (address, sizeof(struct in_addr), key);
391  break;
392 
393  case AF_INET6:
394  GNUNET_CRYPTO_hash (address, sizeof(struct in6_addr), key);
395  break;
396 
397  default:
398  GNUNET_assert (0);
399  break;
400  }
401 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
static char * address
GNS address for this phone.
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 417 of file gnunet-service-vpn.c.

References GNUNET_assert, and GNUNET_memcpy.

Referenced by free_channel_state(), and route_packet().

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

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(), RedirectToIpResponseMessage::request_id, res, and RedirectToIpResponseMessage::result_af.

Referenced by handle_client_redirect_to_ip(), and handle_client_redirect_to_service().

473 {
474  struct GNUNET_MQ_Envelope *env;
476  size_t rlen;
477 
478  switch (result_af)
479  {
480  case AF_INET:
481  rlen = sizeof(struct in_addr);
482  break;
483 
484  case AF_INET6:
485  rlen = sizeof(struct in6_addr);
486  break;
487 
488  case AF_UNSPEC:
489  rlen = 0;
490  break;
491 
492  default:
493  GNUNET_assert (0);
494  return;
495  }
497  res->result_af = htonl (result_af);
498  res->request_id = request_id;
499  GNUNET_memcpy (&res[1], addr, rlen);
501 }
Response from the VPN service to a VPN client informing about the IP that was assigned for the reques...
Definition: vpn.h:129
struct GNUNET_MQ_Handle * GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c)
Obtain the message queue of c.
Definition: service.c:2437
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
uint64_t request_id
Unique ID to match the response to a request.
Definition: vpn.h:145
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
#define GNUNET_MESSAGE_TYPE_VPN_CLIENT_USE_IP
VPN service responds to client with an IP to use for the requested redirection.
static int res
int32_t result_af
Address family of the allocated address that follows; will match "result_af" from the request...
Definition: vpn.h:140
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
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:353
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 510 of file gnunet-service-vpn.c.

References ChannelState::af, ChannelState::channel, 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, DestinationEntry::heap_node, ChannelState::heap_node, ChannelState::protocol, ChannelState::search, ChannelState::source_ip, ChannelState::source_port, ChannelState::tmq_head, ChannelState::tmq_length, and ChannelState::tmq_tail.

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

511 {
512  struct GNUNET_HashCode key;
513  struct ChannelMessageQueueEntry *tnq;
514  struct GNUNET_CADET_Channel *channel;
515 
516  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up channel state\n");
517  if (NULL != (channel = ts->channel))
518  {
519  ts->channel = NULL;
521  return;
522  }
524  gettext_noop ("# Active channels"),
525  -1,
526  GNUNET_NO);
527  while (NULL != (tnq = ts->tmq_head))
528  {
530  ts->tmq_length--;
531  GNUNET_free (tnq);
532  }
533  GNUNET_assert (0 == ts->tmq_length);
534  GNUNET_assert (NULL == ts->destination.heap_node);
535  if (NULL != ts->search)
536  {
538  ts->search = NULL;
539  }
540  if (NULL != ts->heap_node)
541  {
543  ts->heap_node = NULL;
545  ts->protocol,
546  &ts->source_ip,
547  ts->source_port,
548  &ts->destination_ip,
549  ts->destination_port,
550  &key);
551  GNUNET_assert (
552  GNUNET_YES ==
554  }
555  GNUNET_free (ts);
556 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
struct GNUNET_CONTAINER_HeapNode * heap_node
Entry for this entry in the destination_heap.
struct ChannelMessageQueueEntry * tmq_head
Head of list of messages scheduled for transmission.
uint8_t protocol
IPPROTO_TCP or IPPROTO_UDP once bound.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
uint16_t source_port
Source port used by the sender on our end; 0 for uninitialized.
struct DestinationEntry destination
Destination to which this channel leads.
#define GNUNET_NO
Definition: gnunet_common.h:78
Opaque handle to a channel.
Definition: cadet_api.c:80
struct GNUNET_CONTAINER_HeapNode * heap_node
Heap node for this state in the connections_heap.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
int GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
int af
Addess family used for this channel on the local TUN interface.
void GNUNET_REGEX_search_cancel(struct GNUNET_REGEX_Search *s)
Stop search and free all data used by a GNUNET_REGEX_search call.
A messages we have in queue for a particular channel.
A 512-bit hashcode.
struct GNUNET_CADET_Channel * channel
Cadet channel that is used for this connection.
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...
union ChannelState::@85 source_ip
IP address of the source on our end, initially uninitialized.
struct GNUNET_HashCode key
The key used in the DHT.
static struct GNUNET_CONTAINER_MultiHashMap * channel_map
Map from source and destination address (IP+port) to connection information (mostly with the respecti...
union ChannelState::@86 destination_ip
Destination IP address used by the source on our end (this is the IP that we pick freely within the V...
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
struct ChannelMessageQueueEntry * tmq_tail
Tail of list of messages scheduled for transmission.
uint16_t destination_port
Destination port used by the sender on our end; 0 for uninitialized.
#define GNUNET_log(kind,...)
struct GNUNET_REGEX_Search * search
Active query with REGEX to locate exit.
#define GNUNET_YES
Definition: gnunet_common.h:77
unsigned int tmq_length
Length of the doubly linked 'tmq_head/tmq_tail' list.
void * GNUNET_CONTAINER_heap_remove_node(struct GNUNET_CONTAINER_HeapNode *node)
Removes a node from the heap.
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition: cadet_api.c:903
#define GNUNET_free(ptr)
Wrapper around free.
#define gettext_noop(String)
Definition: gettext.h:69
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 567 of file gnunet-service-vpn.c.

References ChannelState::channel, 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, and mq.

Referenced by route_packet().

568 {
569  struct GNUNET_MQ_Handle *mq;
570 
571  GNUNET_assert (NULL != ts->channel);
572  mq = GNUNET_CADET_get_mq (ts->channel);
576  GNUNET_MQ_send (mq, env);
578  {
579  env = GNUNET_MQ_unsent_head (mq);
580  GNUNET_assert (NULL != env);
582  gettext_noop (
583  "# Messages dropped in cadet queue (overflow)"),
584  1,
585  GNUNET_NO);
586  GNUNET_MQ_discard (env);
587  }
588 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
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:1005
#define GNUNET_NO
Definition: gnunet_common.h:78
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
Best-effort traffic (i.e.
unsigned int GNUNET_MQ_get_length(struct GNUNET_MQ_Handle *mq)
Obtain the current length of the message queue.
Definition: mq.c:335
#define MAX_MESSAGE_QUEUE_SIZE
Maximum number of messages we allow in the queue for cadet.
struct GNUNET_CADET_Channel * channel
Cadet channel that is used for this connection.
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition: mq.c:321
Handle to a message queue.
Definition: mq.c:85
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
Flag to indicate that out-of-order delivery is OK.
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:353
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:394
#define gettext_noop(String)
Definition: gettext.h:69
struct GNUNET_MQ_Handle * GNUNET_CADET_get_mq(const struct GNUNET_CADET_Channel *channel)
Obtain the message queue for a connected peer.
Definition: cadet_api.c:1119
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 598 of file gnunet-service-vpn.c.

References DestinationEntry::details, DestinationEntry::exit_destination, GNUNET_h2s(), GNUNET_i2s(), GNUNET_snprintf(), DestinationEntry::is_service, and DestinationEntry::service_destination.

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

599 {
600  static char dest[256];
601 
602  if (de->is_service)
603  {
604  GNUNET_snprintf (dest,
605  sizeof(dest),
606  "HS: %s-%s",
607  GNUNET_i2s (&de->details.service_destination.target),
608  GNUNET_h2s (
609  &de->details.service_destination.service_descriptor));
610  }
611  else
612  {
613  inet_ntop (de->details.exit_destination.af,
614  &de->details.exit_destination.ip,
615  dest,
616  sizeof(dest));
617  }
618  return dest;
619 }
struct DestinationEntry::@81::@82 service_destination
int GNUNET_snprintf(char *buf, size_t size, const char *format,...)
Like snprintf, just aborts if the buffer is of insufficient size.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
int is_service
GNUNET_NO if this is a channel to an Internet-exit, GNUNET_YES if this channel is to a service...
struct DestinationEntry::@81::@83 exit_destination
union DestinationEntry::@81 details
Details about the connection (depending on is_service).
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
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 630 of file gnunet-service-vpn.c.

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

Referenced by create_channel().

631 {
632  struct ChannelState *ts = cls;
633 
634  ts->channel =
635  NULL; /* we must not call GNUNET_CADET_channel_destroy() anymore */
637  "CADET notified us about death of channel to `%s'\n",
639  free_channel_state (ts);
640 }
static const char * print_channel_destination(const struct DestinationEntry *de)
Output destination of a channel for diagnostics.
struct DestinationEntry destination
Destination to which this channel leads.
static void free_channel_state(struct ChannelState *ts)
Free resources associated with a channel state.
struct GNUNET_CADET_Channel * channel
Cadet channel that is used for this connection.
#define GNUNET_log(kind,...)
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
Here is the call graph for this function:
Here is the caller graph for this function:

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

References GNUNET_TUN_UdpHeader::crc, ChannelState::destination_ip, GNUNET_TUN_UdpHeader::destination_port, ChannelState::destination_port, GNUNET_TUN_initialize_ipv4_header(), GNUNET_TUN_UdpHeader::len, ChannelState::protocol, ChannelState::source_ip, GNUNET_TUN_UdpHeader::source_port, ChannelState::source_port, and ChannelState::v4.

Referenced by handle_icmp_back().

656 {
658  ts->protocol,
659  sizeof(struct GNUNET_TUN_TcpHeader),
660  &ts->source_ip.v4,
661  &ts->destination_ip.v4);
662  udp->source_port = htons (ts->source_port);
663  udp->destination_port = htons (ts->destination_port);
664  udp->len = htons (0);
665  udp->crc = htons (0);
666 }
uint8_t protocol
IPPROTO_TCP or IPPROTO_UDP once bound.
uint16_t source_port
Source port used by the sender on our end; 0 for uninitialized.
uint16_t destination_port
Destination port (in NBO).
uint16_t len
Number of bytes of payload.
void GNUNET_TUN_initialize_ipv4_header(struct GNUNET_TUN_IPv4Header *ip, uint8_t protocol, uint16_t payload_length, const struct in_addr *src, const struct in_addr *dst)
Initialize an IPv4 header.
Definition: tun.c:46
union ChannelState::@85 source_ip
IP address of the source on our end, initially uninitialized.
struct in_addr v4
Address if af is AF_INET.
TCP packet header.
uint16_t crc
Checksum.
union ChannelState::@86 destination_ip
Destination IP address used by the source on our end (this is the IP that we pick freely within the V...
uint16_t source_port
Source port (in NBO).
uint16_t destination_port
Destination port used by the sender on our end; 0 for uninitialized.
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 679 of file gnunet-service-vpn.c.

References GNUNET_TUN_UdpHeader::crc, ChannelState::destination_ip, GNUNET_TUN_UdpHeader::destination_port, ChannelState::destination_port, GNUNET_TUN_initialize_ipv6_header(), GNUNET_TUN_UdpHeader::len, ChannelState::protocol, ChannelState::source_ip, GNUNET_TUN_UdpHeader::source_port, ChannelState::source_port, and ChannelState::v6.

Referenced by handle_icmp_back().

682 {
684  ts->protocol,
685  sizeof(struct GNUNET_TUN_TcpHeader),
686  &ts->source_ip.v6,
687  &ts->destination_ip.v6);
688  udp->source_port = htons (ts->source_port);
689  udp->destination_port = htons (ts->destination_port);
690  udp->len = htons (0);
691  udp->crc = htons (0);
692 }
uint8_t protocol
IPPROTO_TCP or IPPROTO_UDP once bound.
uint16_t source_port
Source port used by the sender on our end; 0 for uninitialized.
uint16_t destination_port
Destination port (in NBO).
uint16_t len
Number of bytes of payload.
union ChannelState::@85 source_ip
IP address of the source on our end, initially uninitialized.
TCP packet header.
uint16_t crc
Checksum.
union ChannelState::@86 destination_ip
Destination IP address used by the source on our end (this is the IP that we pick freely within the V...
uint16_t source_port
Source port (in NBO).
uint16_t destination_port
Destination port used by the sender on our end; 0 for uninitialized.
void GNUNET_TUN_initialize_ipv6_header(struct GNUNET_TUN_IPv6Header *ip, uint8_t protocol, uint16_t payload_length, const struct in6_addr *src, const struct in6_addr *dst)
Initialize an IPv6 header.
Definition: tun.c:81
struct in6_addr v6
Address if af is AF_INET6.
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 *
messagethe actual message
Returns
GNUNET_OK to keep the connection open, GNUNET_SYSERR to close it (signal serious error)

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

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

705 {
706  struct ChannelState *ts = cls;
707 
708  if (NULL == ts->heap_node)
709  {
710  GNUNET_break_op (0);
711  return GNUNET_SYSERR;
712  }
713  if (AF_UNSPEC == ts->af)
714  {
715  GNUNET_break_op (0);
716  return GNUNET_SYSERR;
717  }
718  return GNUNET_OK;
719 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
struct GNUNET_CONTAINER_HeapNode * heap_node
Heap node for this state in the connections_heap.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
int af
Addess family used for this channel on the local TUN interface.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...

◆ 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 *
messagethe actual message

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

References ChannelState::af, GNUNET_EXIT_IcmpToVPNMessage::af, buf, ChannelState::channel, ChannelState::destination_ip, ETH_P_IPV4, ETH_P_IPV6, GNUNET_TUN_Layer2PacketHeader::flags, gettext_noop, 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, GNUNET_EXIT_IcmpToVPNMessage::icmp_header, ipv4, ipv6, make_up_icmpv4_payload(), make_up_icmpv6_payload(), msg, GNUNET_TUN_Layer2PacketHeader::proto, size, GNUNET_MessageHeader::size, ChannelState::source_ip, GNUNET_MessageHeader::type, GNUNET_TUN_IcmpHeader::type, udp, ChannelState::v4, and ChannelState::v6.

731 {
732  struct ChannelState *ts = cls;
733  size_t mlen;
734 
736  gettext_noop ("# ICMP packets received from cadet"),
737  1,
738  GNUNET_NO);
739  mlen =
740  ntohs (i2v->header.size) - sizeof(struct GNUNET_EXIT_IcmpToVPNMessage);
741  {
742  char sbuf[INET6_ADDRSTRLEN];
743  char dbuf[INET6_ADDRSTRLEN];
744 
745  GNUNET_log (
747  "Received ICMP packet from cadet, sending %u bytes from %s -> %s via TUN\n",
748  (unsigned int) mlen,
749  inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof(sbuf)),
750  inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof(dbuf)));
751  }
752  switch (ts->af)
753  {
754  case AF_INET: {
755  size_t size = sizeof(struct GNUNET_TUN_IPv4Header)
756  + sizeof(struct GNUNET_TUN_IcmpHeader)
757  + sizeof(struct GNUNET_MessageHeader)
758  + sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
759  {
760  /* reserve some extra space in case we have an ICMP type here where
761  we will need to make up the payload ourselves */
762  char buf[size + sizeof(struct GNUNET_TUN_IPv4Header) + 8] GNUNET_ALIGN;
763  struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
764  struct GNUNET_TUN_Layer2PacketHeader *tun =
765  (struct GNUNET_TUN_Layer2PacketHeader *) &msg[1];
766  struct GNUNET_TUN_IPv4Header *ipv4 =
767  (struct GNUNET_TUN_IPv4Header *) &tun[1];
768  struct GNUNET_TUN_IcmpHeader *icmp =
769  (struct GNUNET_TUN_IcmpHeader *) &ipv4[1];
770  msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
771  tun->flags = htons (0);
772  tun->proto = htons (ETH_P_IPV4);
774  IPPROTO_ICMP,
775  sizeof(struct GNUNET_TUN_IcmpHeader)
776  + mlen,
777  &ts->destination_ip.v4,
778  &ts->source_ip.v4);
779  *icmp = i2v->icmp_header;
780  GNUNET_memcpy (&icmp[1], &i2v[1], mlen);
781  /* For some ICMP types, we need to adjust (make up) the payload here.
782  Also, depending on the AF used on the other side, we have to
783  do ICMP PT (translate ICMP types) */
784  switch (ntohl (i2v->af))
785  {
786  case AF_INET:
787  switch (icmp->type)
788  {
791  break;
792 
796  struct GNUNET_TUN_IPv4Header *ipp =
797  (struct GNUNET_TUN_IPv4Header *) &icmp[1];
798  struct GNUNET_TUN_UdpHeader *udp =
799  (struct GNUNET_TUN_UdpHeader *) &ipp[1];
800 
801  if (mlen != 0)
802  {
803  /* sender did not strip ICMP payload? */
804  GNUNET_break_op (0);
805  return;
806  }
807  size += sizeof(struct GNUNET_TUN_IPv4Header) + 8;
808  GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
809  make_up_icmpv4_payload (ts, ipp, udp);
810  }
811  break;
812 
813  default:
814  GNUNET_break_op (0);
816  stats,
817  gettext_noop ("# ICMPv4 packets dropped (type not allowed)"),
818  1,
819  GNUNET_NO);
820  return;
821  }
822  /* end AF_INET */
823  break;
824 
825  case AF_INET6:
826  /* ICMP PT 6-to-4 and possibly making up payloads */
827  switch (icmp->type)
828  {
831  {
832  struct GNUNET_TUN_IPv4Header *ipp =
833  (struct GNUNET_TUN_IPv4Header *) &icmp[1];
834  struct GNUNET_TUN_UdpHeader *udp =
835  (struct GNUNET_TUN_UdpHeader *) &ipp[1];
836 
837  if (mlen != 0)
838  {
839  /* sender did not strip ICMP payload? */
840  GNUNET_break_op (0);
841  return;
842  }
843  size += sizeof(struct GNUNET_TUN_IPv4Header) + 8;
844  GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
845  make_up_icmpv4_payload (ts, ipp, udp);
846  }
847  break;
848 
851  {
852  struct GNUNET_TUN_IPv4Header *ipp =
853  (struct GNUNET_TUN_IPv4Header *) &icmp[1];
854  struct GNUNET_TUN_UdpHeader *udp =
855  (struct GNUNET_TUN_UdpHeader *) &ipp[1];
856 
857  if (mlen != 0)
858  {
859  /* sender did not strip ICMP payload? */
860  GNUNET_break_op (0);
861  return;
862  }
863  size += sizeof(struct GNUNET_TUN_IPv4Header) + 8;
864  GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
865  make_up_icmpv4_payload (ts, ipp, udp);
866  }
867  break;
868 
872  stats,
873  gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"),
874  1,
875  GNUNET_NO);
876  return;
877 
880  break;
881 
884  break;
885 
886  default:
887  GNUNET_break_op (0);
889  stats,
890  gettext_noop ("# ICMPv6 packets dropped (type not allowed)"),
891  1,
892  GNUNET_NO);
893  return;
894  }
895  /* end AF_INET6 */
896  break;
897 
898  default:
899  GNUNET_break_op (0);
900  return;
901  }
902  msg->size = htons (size);
903  GNUNET_TUN_calculate_icmp_checksum (icmp, &i2v[1], mlen);
904  (void) GNUNET_HELPER_send (helper_handle, msg, GNUNET_YES, NULL, NULL);
905  }
906  }
907  break;
908 
909  case AF_INET6: {
910  size_t size = sizeof(struct GNUNET_TUN_IPv6Header)
911  + sizeof(struct GNUNET_TUN_IcmpHeader)
912  + sizeof(struct GNUNET_MessageHeader)
913  + sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
914  {
915  char buf[size + sizeof(struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
916  struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
917  struct GNUNET_TUN_Layer2PacketHeader *tun =
918  (struct GNUNET_TUN_Layer2PacketHeader *) &msg[1];
919  struct GNUNET_TUN_IPv6Header *ipv6 =
920  (struct GNUNET_TUN_IPv6Header *) &tun[1];
921  struct GNUNET_TUN_IcmpHeader *icmp =
922  (struct GNUNET_TUN_IcmpHeader *) &ipv6[1];
923  msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
924  tun->flags = htons (0);
925  tun->proto = htons (ETH_P_IPV6);
927  IPPROTO_ICMPV6,
928  sizeof(struct GNUNET_TUN_IcmpHeader)
929  + mlen,
930  &ts->destination_ip.v6,
931  &ts->source_ip.v6);
932  *icmp = i2v->icmp_header;
933  GNUNET_memcpy (&icmp[1], &i2v[1], mlen);
934 
935  /* For some ICMP types, we need to adjust (make up) the payload here.
936  Also, depending on the AF used on the other side, we have to
937  do ICMP PT (translate ICMP types) */
938  switch (ntohl (i2v->af))
939  {
940  case AF_INET:
941  /* ICMP PT 4-to-6 and possibly making up payloads */
942  switch (icmp->type)
943  {
946  break;
947 
950  break;
951 
954  {
955  struct GNUNET_TUN_IPv6Header *ipp =
956  (struct GNUNET_TUN_IPv6Header *) &icmp[1];
957  struct GNUNET_TUN_UdpHeader *udp =
958  (struct GNUNET_TUN_UdpHeader *) &ipp[1];
959 
960  if (mlen != 0)
961  {
962  /* sender did not strip ICMP payload? */
963  GNUNET_break_op (0);
964  return;
965  }
966  size += sizeof(struct GNUNET_TUN_IPv6Header) + 8;
967  GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
968  make_up_icmpv6_payload (ts, ipp, udp);
969  }
970  break;
971 
974  {
975  struct GNUNET_TUN_IPv6Header *ipp =
976  (struct GNUNET_TUN_IPv6Header *) &icmp[1];
977  struct GNUNET_TUN_UdpHeader *udp =
978  (struct GNUNET_TUN_UdpHeader *) &ipp[1];
979 
980  if (mlen != 0)
981  {
982  /* sender did not strip ICMP payload? */
983  GNUNET_break_op (0);
984  return;
985  }
986  size += sizeof(struct GNUNET_TUN_IPv6Header) + 8;
987  GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
988  make_up_icmpv6_payload (ts, ipp, udp);
989  }
990  break;
991 
994  stats,
995  gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"),
996  1,
997  GNUNET_NO);
998  return;
999 
1000  default:
1001  GNUNET_break_op (0);
1003  stats,
1004  gettext_noop ("# ICMPv4 packets dropped (type not allowed)"),
1005  1,
1006  GNUNET_NO);
1007  return;
1008  }
1009  /* end AF_INET */
1010  break;
1011 
1012  case AF_INET6:
1013  switch (icmp->type)
1014  {
1019  struct GNUNET_TUN_IPv6Header *ipp =
1020  (struct GNUNET_TUN_IPv6Header *) &icmp[1];
1021  struct GNUNET_TUN_UdpHeader *udp =
1022  (struct GNUNET_TUN_UdpHeader *) &ipp[1];
1023 
1024  if (mlen != 0)
1025  {
1026  /* sender did not strip ICMP payload? */
1027  GNUNET_break_op (0);
1028  return;
1029  }
1030  size += sizeof(struct GNUNET_TUN_IPv6Header) + 8;
1031  GNUNET_assert (8 == sizeof(struct GNUNET_TUN_UdpHeader));
1032  make_up_icmpv6_payload (ts, ipp, udp);
1033  }
1034  break;
1035 
1037  break;
1038 
1039  default:
1040  GNUNET_break_op (0);
1042  stats,
1043  gettext_noop ("# ICMPv6 packets dropped (type not allowed)"),
1044  1,
1045  GNUNET_NO);
1046  return;
1047  }
1048  /* end AF_INET6 */
1049  break;
1050 
1051  default:
1052  GNUNET_break_op (0);
1053  return;
1054  }
1055  msg->size = htons (size);
1056  GNUNET_TUN_calculate_icmp_checksum (icmp, &i2v[1], mlen);
1057  (void) GNUNET_HELPER_send (helper_handle, msg, GNUNET_YES, NULL, NULL);
1058  }
1059  }
1060  break;
1061 
1062  default:
1063  GNUNET_assert (0);
1064  }
1066  GNUNET_TIME_absolute_get ().abs_value_us);
1068 }
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.
static int udp
Option -u: UDP requested.
Definition: gnunet-vpn.c:76
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
uint16_t proto
Here we get an ETH_P_-number.
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.
#define GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED
static int ipv4
Option -4: IPv4 requested.
Definition: gnunet-vpn.c:61
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
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.
UDP packet header.
#define ETH_P_IPV6
Number for IPv6.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
struct GNUNET_TUN_IcmpHeader icmp_header
ICMP header to use.
Definition: exit.h:287
#define GNUNET_NO
Definition: gnunet_common.h:78
Standard IPv4 header.
uint16_t flags
Some flags (unused).
struct GNUNET_CONTAINER_HeapNode * heap_node
Heap node for this state in the connections_heap.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
#define GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH
void GNUNET_TUN_initialize_ipv4_header(struct GNUNET_TUN_IPv4Header *ip, uint8_t protocol, uint16_t payload_length, const struct in_addr *src, const struct in_addr *dst)
Initialize an IPv4 header.
Definition: tun.c:46
#define GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE
#define GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED
#define GNUNET_TUN_ICMPTYPE6_ECHO_REPLY
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG
static char buf[2048]
int af
Addess family used for this channel on the local TUN interface.
int32_t af
Address family, AF_INET or AF_INET6, in network byte order.
Definition: exit.h:282
Header from Linux TUN interface.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
struct GNUNET_CADET_Channel * channel
Cadet channel that is used for this connection.
union ChannelState::@85 source_ip
IP address of the source on our end, initially uninitialized.
struct in_addr v4
Address if af is AF_INET.
static unsigned int size
Size of the "table".
Definition: peer.c:67
#define GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE
void GNUNET_TUN_calculate_icmp_checksum(struct GNUNET_TUN_IcmpHeader *icmp, const void *payload, uint16_t payload_length)
Calculate ICMP checksum.
Definition: tun.c:260
Message send via cadet to the vpn service to send ICMP data to the VPN's TUN interface.
Definition: exit.h:271
union ChannelState::@86 destination_ip
Destination IP address used by the source on our end (this is the IP that we pick freely within the V...
Standard IPv6 header.
#define GNUNET_TUN_ICMPTYPE_ECHO_REQUEST
#define GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM
#define GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Send an ack on the channel to confirm the processing of a message.
Definition: cadet_api.c:954
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to 'struct's...
struct GNUNET_HELPER_SendHandle * GNUNET_HELPER_send(struct GNUNET_HELPER_Handle *h, const struct GNUNET_MessageHeader *msg, int can_drop, GNUNET_HELPER_Continuation cont, void *cont_cls)
Send an message to the helper.
Definition: helper.c:655
#define GNUNET_log(kind,...)
Header for all communications.
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
#define GNUNET_YES
Definition: gnunet_common.h:77
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_VPN.
Definition: exit.h:276
#define GNUNET_TUN_ICMPTYPE_ECHO_REPLY
static struct GNUNET_HELPER_Handle * helper_handle
The handle to the VPN helper process "gnunet-helper-vpn".
void GNUNET_TUN_initialize_ipv6_header(struct GNUNET_TUN_IPv6Header *ip, uint8_t protocol, uint16_t payload_length, const struct in6_addr *src, const struct in6_addr *dst)
Initialize an IPv6 header.
Definition: tun.c:81
#define ETH_P_IPV4
Number for IPv4.
#define GNUNET_MESSAGE_TYPE_VPN_HELPER
Type of messages between the gnunet-vpn-helper and the daemon.
struct in6_addr v6
Address if af is AF_INET6.
#define gettext_noop(String)
Definition: gettext.h:69
static int ipv6
Option -6: IPv6 requested.
Definition: gnunet-vpn.c:66
Here is the call graph for this function:

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

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

1081 {
1082  struct ChannelState *ts = cls;
1083 
1084  if (NULL == ts->heap_node)
1085  {
1086  GNUNET_break_op (0);
1087  return GNUNET_SYSERR;
1088  }
1089  if (AF_UNSPEC == ts->af)
1090  {
1091  GNUNET_break_op (0);
1092  return GNUNET_SYSERR;
1093  }
1094  return GNUNET_OK;
1095 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
struct GNUNET_CONTAINER_HeapNode * heap_node
Heap node for this state in the connections_heap.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
int af
Addess family used for this channel on the local TUN interface.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...

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

References ChannelState::af, buf, ChannelState::channel, ChannelState::destination_ip, GNUNET_EXIT_UdpReplyMessage::destination_port, GNUNET_TUN_UdpHeader::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, ipv4, ipv6, GNUNET_TUN_UdpHeader::len, msg, GNUNET_TUN_Layer2PacketHeader::proto, size, GNUNET_MessageHeader::size, ChannelState::source_ip, GNUNET_EXIT_UdpReplyMessage::source_port, GNUNET_TUN_UdpHeader::source_port, ChannelState::source_port, GNUNET_MessageHeader::type, udp, ChannelState::v4, and ChannelState::v6.

1107 {
1108  struct ChannelState *ts = cls;
1109  size_t mlen;
1110 
1112  gettext_noop ("# UDP packets received from cadet"),
1113  1,
1114  GNUNET_NO);
1115  mlen =
1116  ntohs (reply->header.size) - sizeof(struct GNUNET_EXIT_UdpReplyMessage);
1117  {
1118  char sbuf[INET6_ADDRSTRLEN];
1119  char dbuf[INET6_ADDRSTRLEN];
1120 
1121  GNUNET_log (
1123  "Received UDP reply from cadet, sending %u bytes from [%s]:%u -> [%s]:%u via TUN\n",
1124  (unsigned int) mlen,
1125  inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof(sbuf)),
1126  ts->destination_port,
1127  inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof(dbuf)),
1128  ts->source_port);
1129  }
1130  switch (ts->af)
1131  {
1132  case AF_INET: {
1133  size_t size = sizeof(struct GNUNET_TUN_IPv4Header)
1134  + sizeof(struct GNUNET_TUN_UdpHeader)
1135  + sizeof(struct GNUNET_MessageHeader)
1136  + sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
1137  {
1138  char buf[size] GNUNET_ALIGN;
1139  struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
1140  struct GNUNET_TUN_Layer2PacketHeader *tun =
1141  (struct GNUNET_TUN_Layer2PacketHeader *) &msg[1];
1142  struct GNUNET_TUN_IPv4Header *ipv4 =
1143  (struct GNUNET_TUN_IPv4Header *) &tun[1];
1144  struct GNUNET_TUN_UdpHeader *udp =
1145  (struct GNUNET_TUN_UdpHeader *) &ipv4[1];
1146  msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1147  msg->size = htons (size);
1148  tun->flags = htons (0);
1149  tun->proto = htons (ETH_P_IPV4);
1151  IPPROTO_UDP,
1152  sizeof(struct GNUNET_TUN_UdpHeader)
1153  + mlen,
1154  &ts->destination_ip.v4,
1155  &ts->source_ip.v4);
1156  if (0 == ntohs (reply->source_port))
1157  udp->source_port = htons (ts->destination_port);
1158  else
1159  udp->source_port = reply->source_port;
1160  if (0 == ntohs (reply->destination_port))
1161  udp->destination_port = htons (ts->source_port);
1162  else
1163  udp->destination_port = reply->destination_port;
1164  udp->len = htons (mlen + sizeof(struct GNUNET_TUN_UdpHeader));
1165  GNUNET_TUN_calculate_udp4_checksum (ipv4, udp, &reply[1], mlen);
1166  GNUNET_memcpy (&udp[1], &reply[1], mlen);
1167  (void) GNUNET_HELPER_send (helper_handle, msg, GNUNET_YES, NULL, NULL);
1168  }
1169  }
1170  break;
1171 
1172  case AF_INET6: {
1173  size_t size = sizeof(struct GNUNET_TUN_IPv6Header)
1174  + sizeof(struct GNUNET_TUN_UdpHeader)
1175  + sizeof(struct GNUNET_MessageHeader)
1176  + sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
1177  {
1178  char buf[size] GNUNET_ALIGN;
1179  struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
1180  struct GNUNET_TUN_Layer2PacketHeader *tun =
1181  (struct GNUNET_TUN_Layer2PacketHeader *) &msg[1];
1182  struct GNUNET_TUN_IPv6Header *ipv6 =
1183  (struct GNUNET_TUN_IPv6Header *) &tun[1];
1184  struct GNUNET_TUN_UdpHeader *udp =
1185  (struct GNUNET_TUN_UdpHeader *) &ipv6[1];
1186  msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1187  msg->size = htons (size);
1188  tun->flags = htons (0);
1189  tun->proto = htons (ETH_P_IPV6);
1191  IPPROTO_UDP,
1192  sizeof(struct GNUNET_TUN_UdpHeader)
1193  + mlen,
1194  &ts->destination_ip.v6,
1195  &ts->source_ip.v6);
1196  if (0 == ntohs (reply->source_port))
1197  udp->source_port = htons (ts->destination_port);
1198  else
1199  udp->source_port = reply->source_port;
1200  if (0 == ntohs (reply->destination_port))
1201  udp->destination_port = htons (ts->source_port);
1202  else
1203  udp->destination_port = reply->destination_port;
1204  udp->len = htons (mlen + sizeof(struct GNUNET_TUN_UdpHeader));
1205  GNUNET_TUN_calculate_udp6_checksum (ipv6, udp, &reply[1], mlen);
1206  GNUNET_memcpy (&udp[1], &reply[1], mlen);
1207  (void) GNUNET_HELPER_send (helper_handle, msg, GNUNET_YES, NULL, NULL);
1208  }
1209  }
1210  break;
1211 
1212  default:
1213  GNUNET_assert (0);
1214  }
1216  GNUNET_TIME_absolute_get ().abs_value_us);
1218 }
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.
static int udp
Option -u: UDP requested.
Definition: gnunet-vpn.c:76
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
uint16_t proto
Here we get an ETH_P_-number.
static int ipv4
Option -4: IPv4 requested.
Definition: gnunet-vpn.c:61
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
uint16_t source_port
Source port used by the sender on our end; 0 for uninitialized.
UDP packet header.
#define ETH_P_IPV6
Number for IPv6.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_NO
Definition: gnunet_common.h:78
Standard IPv4 header.
uint16_t flags
Some flags (unused).
void GNUNET_TUN_calculate_udp4_checksum(const struct GNUNET_TUN_IPv4Header *ip, struct GNUNET_TUN_UdpHeader *udp, const void *payload, uint16_t payload_length)
Calculate IPv4 UDP checksum.
Definition: tun.c:183
struct GNUNET_CONTAINER_HeapNode * heap_node
Heap node for this state in the connections_heap.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
uint16_t destination_port
Destination port (in NBO).
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
uint16_t len
Number of bytes of payload.
void GNUNET_TUN_initialize_ipv4_header(struct GNUNET_TUN_IPv4Header *ip, uint8_t protocol, uint16_t payload_length, const struct in_addr *src, const struct in_addr *dst)
Initialize an IPv4 header.
Definition: tun.c:46
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY.
Definition: exit.h:183
void GNUNET_TUN_calculate_udp6_checksum(const struct GNUNET_TUN_IPv6Header *ip, struct GNUNET_TUN_UdpHeader *udp, const void *payload, uint16_t payload_length)
Calculate IPv6 UDP checksum.
Definition: tun.c:222
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
static char buf[2048]
int af
Addess family used for this channel on the local TUN interface.
Header from Linux TUN interface.
Message send from exit daemon back to the UDP entry point (used for both Internet and Service exit re...
Definition: exit.h:178
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
struct GNUNET_CADET_Channel * channel
Cadet channel that is used for this connection.
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
union ChannelState::@85 source_ip
IP address of the source on our end, initially uninitialized.
struct in_addr v4
Address if af is AF_INET.
static unsigned int size
Size of the "table".
Definition: peer.c:67
union ChannelState::@86 destination_ip
Destination IP address used by the source on our end (this is the IP that we pick freely within the V...
Standard IPv6 header.
uint16_t source_port
Source port (in NBO).
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Send an ack on the channel to confirm the processing of a message.
Definition: cadet_api.c:954
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to 'struct's...
struct GNUNET_HELPER_SendHandle * GNUNET_HELPER_send(struct GNUNET_HELPER_Handle *h, const struct GNUNET_MessageHeader *msg, int can_drop, GNUNET_HELPER_Continuation cont, void *cont_cls)
Send an message to the helper.
Definition: helper.c:655
uint16_t destination_port
Destination port used by the sender on our end; 0 for uninitialized.
#define GNUNET_log(kind,...)
uint16_t destination_port
Destination port to use for the UDP reply (0 to use the same port as for the original request)...
Definition: exit.h:195
Header for all communications.
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
#define GNUNET_YES
Definition: gnunet_common.h:77
static struct GNUNET_HELPER_Handle * helper_handle
The handle to the VPN helper process "gnunet-helper-vpn".
void GNUNET_TUN_initialize_ipv6_header(struct GNUNET_TUN_IPv6Header *ip, uint8_t protocol, uint16_t payload_length, const struct in6_addr *src, const struct in6_addr *dst)
Initialize an IPv6 header.
Definition: tun.c:81
#define ETH_P_IPV4
Number for IPv4.
#define GNUNET_MESSAGE_TYPE_VPN_HELPER
Type of messages between the gnunet-vpn-helper and the daemon.
struct in6_addr v6
Address if af is AF_INET6.
#define gettext_noop(String)
Definition: gettext.h:69
static int ipv6
Option -6: IPv6 requested.
Definition: gnunet-vpn.c:66
Here is the call graph for this function:

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

References GNUNET_break_op, GNUNET_OK, GNUNET_SYSERR, ChannelState::heap_node, GNUNET_TUN_TcpHeader::off, and GNUNET_EXIT_TcpDataMessage::tcp_header.

1231 {
1232  struct ChannelState *ts = cls;
1233 
1234  if (NULL == ts->heap_node)
1235  {
1236  GNUNET_break_op (0);
1237  return GNUNET_SYSERR;
1238  }
1239  if (data->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
1240  {
1241  GNUNET_break_op (0);
1242  return GNUNET_SYSERR;
1243  }
1244  return GNUNET_OK;
1245 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
struct GNUNET_TUN_TcpHeader tcp_header
Skeleton of the TCP header to send.
Definition: exit.h:110
struct GNUNET_CONTAINER_HeapNode * heap_node
Heap node for this state in the connections_heap.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
TCP packet header.
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
unsigned int off
Number of 32-bit words in TCP header.

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

References ChannelState::af, buf, ChannelState::channel, ChannelState::destination_ip, GNUNET_TUN_TcpHeader::destination_port, 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, GNUNET_EXIT_TcpDataMessage::header, ChannelState::heap_node, ipv4, ipv6, msg, GNUNET_TUN_Layer2PacketHeader::proto, size, GNUNET_MessageHeader::size, ChannelState::source_ip, GNUNET_TUN_TcpHeader::source_port, ChannelState::source_port, tcp, GNUNET_EXIT_TcpDataMessage::tcp_header, GNUNET_MessageHeader::type, ChannelState::v4, and ChannelState::v6.

1257 {
1258  struct ChannelState *ts = cls;
1259  size_t mlen;
1260 
1262  gettext_noop ("# TCP packets received from cadet"),
1263  1,
1264  GNUNET_NO);
1265  mlen = ntohs (data->header.size) - sizeof(struct GNUNET_EXIT_TcpDataMessage);
1266  {
1267  char sbuf[INET6_ADDRSTRLEN];
1268  char dbuf[INET6_ADDRSTRLEN];
1269 
1270  GNUNET_log (
1272  "Received TCP reply from cadet, sending %u bytes from [%s]:%u -> [%s]:%u via TUN\n",
1273  (unsigned int) mlen,
1274  inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof(sbuf)),
1275  ts->destination_port,
1276  inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof(dbuf)),
1277  ts->source_port);
1278  }
1279  switch (ts->af)
1280  {
1281  case AF_INET: {
1282  size_t size = sizeof(struct GNUNET_TUN_IPv4Header)
1283  + sizeof(struct GNUNET_TUN_TcpHeader)
1284  + sizeof(struct GNUNET_MessageHeader)
1285  + sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
1286  {
1287  char buf[size] GNUNET_ALIGN;
1288  struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
1289  struct GNUNET_TUN_Layer2PacketHeader *tun =
1290  (struct GNUNET_TUN_Layer2PacketHeader *) &msg[1];
1291  struct GNUNET_TUN_IPv4Header *ipv4 =
1292  (struct GNUNET_TUN_IPv4Header *) &tun[1];
1293  struct GNUNET_TUN_TcpHeader *tcp =
1294  (struct GNUNET_TUN_TcpHeader *) &ipv4[1];
1295  msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1296  msg->size = htons (size);
1297  tun->flags = htons (0);
1298  tun->proto = htons (ETH_P_IPV4);
1300  IPPROTO_TCP,
1301  sizeof(struct GNUNET_TUN_TcpHeader)
1302  + mlen,
1303  &ts->destination_ip.v4,
1304  &ts->source_ip.v4);
1305  *tcp = data->tcp_header;
1306  tcp->source_port = htons (ts->destination_port);
1307  tcp->destination_port = htons (ts->source_port);
1308  GNUNET_TUN_calculate_tcp4_checksum (ipv4, tcp, &data[1], mlen);
1309  GNUNET_memcpy (&tcp[1], &data[1], mlen);
1310  (void) GNUNET_HELPER_send (helper_handle, msg, GNUNET_YES, NULL, NULL);
1311  }
1312  }
1313  break;
1314 
1315  case AF_INET6: {
1316  size_t size = sizeof(struct GNUNET_TUN_IPv6Header)
1317  + sizeof(struct GNUNET_TUN_TcpHeader)
1318  + sizeof(struct GNUNET_MessageHeader)
1319  + sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
1320  {
1321  char buf[size] GNUNET_ALIGN;
1322  struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
1323  struct GNUNET_TUN_Layer2PacketHeader *tun =
1324  (struct GNUNET_TUN_Layer2PacketHeader *) &msg[1];
1325  struct GNUNET_TUN_IPv6Header *ipv6 =
1326  (struct GNUNET_TUN_IPv6Header *) &tun[1];
1327  struct GNUNET_TUN_TcpHeader *tcp =
1328  (struct GNUNET_TUN_TcpHeader *) &ipv6[1];
1329  msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1330  msg->size = htons (size);
1331  tun->flags = htons (0);
1332  tun->proto = htons (ETH_P_IPV6);
1334  IPPROTO_TCP,
1335  sizeof(struct GNUNET_TUN_TcpHeader)
1336  + mlen,
1337  &ts->destination_ip.v6,
1338  &ts->source_ip.v6);
1339  *tcp = data->tcp_header;
1340  tcp->source_port = htons (ts->destination_port);
1341  tcp->destination_port = htons (ts->source_port);
1342  GNUNET_TUN_calculate_tcp6_checksum (ipv6, tcp, &data[1], mlen);
1343  GNUNET_memcpy (&tcp[1], &data[1], mlen);
1344  (void) GNUNET_HELPER_send (helper_handle, msg, GNUNET_YES, NULL, NULL);
1345  }
1346  }
1347  break;
1348  }
1350  GNUNET_TIME_absolute_get ().abs_value_us);
1352 }
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_MessageHeader * msg
Definition: 005.c:2
uint16_t proto
Here we get an ETH_P_-number.
static int ipv4
Option -4: IPv4 requested.
Definition: gnunet-vpn.c:61
uint16_t source_port
Source port used by the sender on our end; 0 for uninitialized.
#define ETH_P_IPV6
Number for IPv6.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_NO
Definition: gnunet_common.h:78
Standard IPv4 header.
uint16_t flags
Some flags (unused).
struct GNUNET_TUN_TcpHeader tcp_header
Skeleton of the TCP header to send.
Definition: exit.h:110
struct GNUNET_CONTAINER_HeapNode * heap_node
Heap node for this state in the connections_heap.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
void GNUNET_TUN_calculate_tcp6_checksum(const struct GNUNET_TUN_IPv6Header *ip, struct GNUNET_TUN_TcpHeader *tcp, const void *payload, uint16_t payload_length)
Calculate IPv6 TCP checksum.
Definition: tun.c:147
void GNUNET_TUN_initialize_ipv4_header(struct GNUNET_TUN_IPv4Header *ip, uint8_t protocol, uint16_t payload_length, const struct in_addr *src, const struct in_addr *dst)
Initialize an IPv4 header.
Definition: tun.c:46
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
void GNUNET_TUN_calculate_tcp4_checksum(const struct GNUNET_TUN_IPv4Header *ip, struct GNUNET_TUN_TcpHeader *tcp, const void *payload, uint16_t payload_length)
Calculate IPv4 TCP checksum.
Definition: tun.c:109
static char buf[2048]
int af
Addess family used for this channel on the local TUN interface.
Header from Linux TUN interface.
uint16_t destination_port
Destination port (in NBO).
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
struct GNUNET_CADET_Channel * channel
Cadet channel that is used for this connection.
union ChannelState::@85 source_ip
IP address of the source on our end, initially uninitialized.
struct in_addr v4
Address if af is AF_INET.
static unsigned int size
Size of the "table".
Definition: peer.c:67
TCP packet header.
union ChannelState::@86 destination_ip
Destination IP address used by the source on our end (this is the IP that we pick freely within the V...
static int tcp
Option -t: TCP requested.
Definition: gnunet-vpn.c:71
Standard IPv6 header.
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Send an ack on the channel to confirm the processing of a message.
Definition: cadet_api.c:954
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to &#39;struct&#39;s...
uint16_t source_port
Source port (in NBO).
struct GNUNET_HELPER_SendHandle * GNUNET_HELPER_send(struct GNUNET_HELPER_Handle *h, const struct GNUNET_MessageHeader *msg, int can_drop, GNUNET_HELPER_Continuation cont, void *cont_cls)
Send an message to the helper.
Definition: helper.c:655
uint16_t destination_port
Destination port used by the sender on our end; 0 for uninitialized.
#define GNUNET_log(kind,...)
struct GNUNET_MessageHeader header
Type is #GNUNET_MESSAGE_TYPE_VPN_TCP_DATA.
Definition: exit.h:99
Header for all communications.
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
#define GNUNET_YES
Definition: gnunet_common.h:77
Message send via cadet between VPN and entry and an exit daemon to transmit TCP data between the VPN ...
Definition: exit.h:94
static struct GNUNET_HELPER_Handle * helper_handle
The handle to the VPN helper process "gnunet-helper-vpn".
void GNUNET_TUN_initialize_ipv6_header(struct GNUNET_TUN_IPv6Header *ip, uint8_t protocol, uint16_t payload_length, const struct in6_addr *src, const struct in6_addr *dst)
Initialize an IPv6 header.
Definition: tun.c:81
#define ETH_P_IPV4
Number for IPv4.
#define GNUNET_MESSAGE_TYPE_VPN_HELPER
Type of messages between the gnunet-vpn-helper and the daemon.
struct in6_addr v6
Address if af is AF_INET6.
#define gettext_noop(String)
Definition: gettext.h:69
static int ipv6
Option -6: IPv6 requested.
Definition: gnunet-vpn.c:66
Here is the call graph for this function:

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

References 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, and GNUNET_MQ_hd_var_size.

Referenced by create_channel_to_destination(), and handle_regex_result().

1367 {
1368  struct GNUNET_MQ_MessageHandler cadet_handlers[] =
1369  { GNUNET_MQ_hd_var_size (udp_back,
1372  ts),
1373  GNUNET_MQ_hd_var_size (tcp_back,
1376  ts),
1377  GNUNET_MQ_hd_var_size (icmp_back,
1380  ts),
1381  GNUNET_MQ_handler_end () };
1382 
1384  ts,
1385  target,
1386  port,
1387  NULL,
1388  &channel_cleaner,
1389  cadet_handlers);
1390 }
#define GNUNET_MESSAGE_TYPE_VPN_UDP_REPLY
Type of messages containing an UDP packet from a remote host.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_VPN
Type of messages containing an TCP packet of an established connection.
static struct GNUNET_CADET_Handle * cadet_handle
Handle to the cadet service.
Message send from exit daemon back to the UDP entry point (used for both Internet and Service exit re...
Definition: exit.h:178
Message handler for a specific message type.
Message send via cadet to the vpn service to send ICMP data to the VPN&#39;s TUN interface.
Definition: exit.h:271
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:1068
#define GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_VPN
Type of messages containing an ICMP packet for the VPN.
static void channel_cleaner(void *cls, const struct GNUNET_CADET_Channel *channel)
Function called whenever a channel is destroyed.
Message send via cadet between VPN and entry and an exit daemon to transmit TCP data between the VPN ...
Definition: exit.h:94
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
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_lengthLenght of get_path.
put_pathPath of the put request.
put_path_lengthLength of the put_path.

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

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(), print_channel_destination(), and ChannelState::search.

Referenced by create_channel_to_destination().

1410 {
1411  struct ChannelState *ts = cls;
1412  struct GNUNET_HashCode port;
1413 
1415  "Exit %s found for destination %s!\n",
1416  GNUNET_i2s (id),
1419  ts->search = NULL;
1420  switch (ts->af)
1421  {
1422  case AF_INET:
1423  /* these must match the strings used in gnunet-daemon-exit */
1426  &port);
1427  break;
1428 
1429  case AF_INET6:
1430  /* these must match the strings used in gnunet-daemon-exit */
1433  &port);
1434  break;
1435 
1436  default:
1437  GNUNET_break (0);
1438  return;
1439  }
1441  "Creating tunnel to %s for destination %s!\n",
1442  GNUNET_i2s (id),
1444  ts->channel = create_channel (ts, id, &port);
1445 }
static const char * print_channel_destination(const struct DestinationEntry *de)
Output destination of a channel for diagnostics.
struct DestinationEntry destination
Destination to which this channel leads.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define GNUNET_APPLICATION_PORT_IPV6_GATEWAY
Internet IPv6 gateway (any TCP/UDP/ICMP).
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
int af
Addess family used for this channel on the local TUN interface.
void GNUNET_REGEX_search_cancel(struct GNUNET_REGEX_Search *s)
Stop search and free all data used by a GNUNET_REGEX_search call.
A 512-bit hashcode.
struct GNUNET_CADET_Channel * channel
Cadet channel that is used for this connection.
static uint16_t port
Port number.
Definition: gnunet-bcd.c:81
#define GNUNET_log(kind,...)
struct GNUNET_REGEX_Search * search
Active query with REGEX to locate exit.
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
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).
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
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 1456 of file gnunet-service-vpn.c.

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

Referenced by route_packet().

1457 {
1458  struct ChannelState *ts;
1459 
1461  gettext_noop ("# Cadet channels created"),
1462  1,
1463  GNUNET_NO);
1464  ts = GNUNET_new (struct ChannelState);
1465  ts->af = client_af;
1466  ts->destination = *dt->destination;
1467  ts->destination.heap_node = NULL; /* copy is NOT in destination heap */
1469  if (dt->destination->is_service)
1470  {
1471  struct GNUNET_HashCode cadet_port;
1472 
1475  .service_descriptor,
1476  ts->destination_port,
1477  &cadet_port);
1478  ts->channel =
1479  create_channel (ts,
1481  &cadet_port);
1482 
1483  if (NULL == ts->channel)
1484  {
1485  GNUNET_break (0);
1486  GNUNET_free (ts);
1487  return NULL;
1488  }
1490  "Creating channel to peer %s offering service %s on port %u\n",
1491  GNUNET_i2s (
1492  &dt->destination->details.service_destination.target),
1494  .service_descriptor),
1495  (unsigned int) ts->destination_port);
1496  }
1497  else
1498  {
1499  char *policy;
1500 
1501  switch (dt->destination->details.exit_destination.af)
1502  {
1503  case AF_INET: {
1505 
1507  .ip.v4,
1508  dt->destination_port,
1509  address);
1510  GNUNET_asprintf (&policy,
1511  "%s%s",
1513  address);
1514  break;
1515  }
1516 
1517  case AF_INET6: {
1519 
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 }
struct DestinationEntry::@81::@82 service_destination
struct GNUNET_CONTAINER_HeapNode * heap_node
Entry for this entry in the destination_heap.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
void GNUNET_TUN_ipv4toregexsearch(const struct in_addr *ip, uint16_t port, char *rxstr)
Create a regex in rxstr from the given ip and port.
Definition: regex.c:45
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.
struct DestinationEntry destination
Destination to which this channel leads.
#define GNUNET_NO
Definition: gnunet_common.h:78
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_new(type)
Allocate a struct or union of the given type.
int is_service
GNUNET_NO if this is a channel to an Internet-exit, GNUNET_YES if this channel is to a service...
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
struct DestinationEntry::@81::@83 exit_destination
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
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.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
union DestinationEntry::@81 details
Details about the connection (depending on is_service).
int af
Addess family used for this channel on the local TUN interface.
A 512-bit hashcode.
struct GNUNET_CADET_Channel * channel
Cadet channel that is used for this connection.
void GNUNET_TUN_ipv6toregexsearch(const struct in6_addr *ipv6, uint16_t port, char *rxstr)
Create a regex in rxstr from the given ipv6 and port.
Definition: regex.c:66
#define GNUNET_APPLICATION_TYPE_EXIT_REGEX_PREFIX
Internet exit regex prefix.
void GNUNET_TUN_compute_service_cadet_port(const struct GNUNET_HashCode *desc, uint16_t ip_port, struct GNUNET_HashCode *cadet_port)
Compute the CADET port given a service descriptor (returned from GNUNET_TUN_service_name_to_hash) and...
Definition: regex.c:833
#define GNUNET_TUN_IPV4_REGEXLEN
Maximum regex string length for use with GNUNET_TUN_ipv4toregexsearch.
struct DestinationEntry * destination
Destination entry list this struct DestinationChannel belongs with.
uint16_t destination_port
Destination port this channel state is used for.
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
uint16_t destination_port
Destination port used by the sender on our end; 0 for uninitialized.
#define GNUNET_log(kind,...)
static struct GNUNET_CADET_Port * cadet_port
Listen port for incoming requests.
struct GNUNET_REGEX_Search * search
Active query with REGEX to locate exit.
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
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.
static char * address
GNS address for this phone.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_TUN_IPV6_REGEXLEN
Maximum regex string length for use with GNUNET_TUN_ipv6toregexsearch.
#define GNUNET_free(ptr)
Wrapper around free.
#define gettext_noop(String)
Definition: gettext.h:69
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.

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

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 const char * print_channel_destination(const struct DestinationEntry *de)
Output destination of a channel for diagnostics.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct DestinationEntry destination
Destination to which this channel leads.
static void free_channel_state(struct ChannelState *ts)
Free resources associated with a channel state.
static struct GNUNET_CONTAINER_Heap * channel_heap
Min-Heap sorted by activity time to expire old mappings; values are of type &#39;struct ChannelState&#39;...
void * GNUNET_CONTAINER_heap_peek(const struct GNUNET_CONTAINER_Heap *heap)
Get element stored at the root of heap.
#define GNUNET_log(kind,...)
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
Here is the call graph for this function:
Here is the caller graph for this function:

◆ 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.

References _, GNUNET_EXIT_TcpInternetStartMessage::af, GNUNET_EXIT_UdpInternetMessage::af, GNUNET_EXIT_IcmpServiceMessage::af, ChannelState::af, GNUNET_EXIT_IcmpInternetMessage::af, ChannelState::channel, create_channel_to_destination(), DestinationChannel::destination, ChannelState::destination, ChannelState::destination_ip, DestinationChannel::destination_port, GNUNET_EXIT_UdpServiceMessage::destination_port, GNUNET_EXIT_UdpInternetMessage::destination_port, GNUNET_TUN_TcpHeader::destination_port, GNUNET_TUN_UdpHeader::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, ChannelState::is_established, DestinationEntry::is_service, GNUNET_TUN_UdpHeader::len, max_channel_mappings, DestinationChannel::next, GNUNET_TUN_TcpHeader::off, payload, print_channel_destination(), ChannelState::protocol, GNUNET_EXIT_TcpServiceStartMessage::reserved, GNUNET_EXIT_TcpDataMessage::reserved, ChannelState::search, send_to_channel(), DestinationEntry::service_destination, ChannelState::source_ip, GNUNET_EXIT_UdpServiceMessage::source_port, GNUNET_EXIT_UdpInternetMessage::source_port, GNUNET_TUN_TcpHeader::source_port, GNUNET_TUN_UdpHeader::source_port, ChannelState::source_port, tcp, GNUNET_EXIT_TcpServiceStartMessage::tcp_header, GNUNET_EXIT_TcpInternetStartMessage::tcp_header, GNUNET_EXIT_TcpDataMessage::tcp_header, GNUNET_TUN_IcmpHeader::type, udp, ChannelState::v4, and ChannelState::v6.

Referenced by message_token().

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,
1623  destination_port,
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,
1650  destination_port,
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  {
1692  switch (destination->details.exit_destination.af)
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 (
1744  &destination->details.service_destination.service_descriptor),
1745  GNUNET_i2s (&destination->details.service_destination.target));
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;
1755  GNUNET_CONTAINER_DLL_insert (destination->dt_head,
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);
1794  channel_map,
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  {
1833  struct GNUNET_EXIT_UdpServiceMessage *usm;
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  {
1857  struct GNUNET_EXIT_UdpInternetMessage *uim;
1858  struct in_addr *ip4dst;
1859  struct in6_addr *ip6dst;
1860  void *payload;
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 = &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 = &ip6dst[1];
1889  break;
1890 
1891  default:
1892  GNUNET_assert (0);
1893  }
1894  GNUNET_memcpy (payload,
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 =
1915  GNUNET_MQ_msg_extra (tsm,
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;
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 =
1940  GNUNET_MQ_msg_extra (tim,
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 = &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 = &ip6dst[1];
1958  break;
1959 
1960  default:
1961  GNUNET_assert (0);
1962  }
1963  GNUNET_memcpy (payload,
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  {
1995  struct GNUNET_EXIT_IcmpServiceMessage *ism;
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  {
2079  struct GNUNET_EXIT_IcmpInternetMessage *iim;
2080  struct in_addr *ip4dst;
2081  struct in6_addr *ip6dst;
2082  void *payload;
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)
2194  new_type = GNUNET_TUN_ICMPTYPE_ECHO_REPLY;
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 = &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 = &ip6dst[1];
2239  break;
2240 
2241  default:
2242  GNUNET_assert (0);
2243  }
2244  GNUNET_memcpy (payload,
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  }
2255  ts->is_established = GNUNET_YES;
2256  send_to_channel (ts, env);
2257 }
struct DestinationEntry::@81::@82 service_destination
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.
static int udp
Option -u: UDP requested.
Definition: gnunet-vpn.c:76
static void expire_channel(struct ChannelState *except)
We have too many active channels.
#define GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_SERVICE
Type of messages containing an ICMP packet for a service.
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#define GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_INTERNET
Type of messages containing an ICMP packet for the Internet.
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.
#define GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED
uint8_t protocol
IPPROTO_TCP or IPPROTO_UDP once bound.
struct DestinationChannel * next
Kept in a DLL.
static const char * print_channel_destination(const struct DestinationEntry *de)
Output destination of a channel for diagnostics.
int32_t af
Address family, AF_INET or AF_INET6, in network byte order.
Definition: exit.h:249
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE
Type of messages containing an UDP packet for a service.
#define GNUNET_MESSAGE_TYPE_VPN_TCP_TO_SERVICE_START
Type of messages containing an TCP packet for a service.
uint16_t source_port
Source port used by the sender on our end; 0 for uninitialized.
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.
UDP packet header.
#define GNUNET_MESSAGE_TYPE_VPN_UDP_TO_INTERNET
Type of messages containing an UDP packet for the Internet.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
struct DestinationEntry destination
Destination to which this channel leads.
#define GNUNET_NO
Definition: gnunet_common.h:78
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_new(type)
Allocate a struct or union of the given type.
int32_t af
Address family, AF_INET or AF_INET6, in network byte order.
Definition: exit.h:73
struct GNUNET_TUN_TcpHeader tcp_header
Skeleton of the TCP header to send.
Definition: exit.h:110
struct GNUNET_CONTAINER_HeapNode * heap_node
Heap node for this state in the connections_heap.
int is_service
GNUNET_NO if this is a channel to an Internet-exit, GNUNET_YES if this channel is to a service...
uint16_t destination_port
Destination port (in NBO).
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
uint16_t len
Number of bytes of payload.
#define GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH
struct GNUNET_TUN_TcpHeader tcp_header
Skeleton of the TCP header to send.
Definition: exit.h:53
struct DestinationEntry::@81::@83 exit_destination
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
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.
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
#define GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT
Type of messages containing an TCP packet of an established connection.
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 ICMP data to a local service.
Definition: exit.h:205
#define GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE
#define GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
#define GNUNET_TUN_ICMPTYPE6_ECHO_REPLY
struct GNUNET_TUN_TcpHeader tcp_header
Skeleton of the TCP header to send.
Definition: exit.h:79
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
static struct GNUNET_CONTAINER_Heap * channel_heap
Min-Heap sorted by activity time to expire old mappings; values are of type &#39;struct ChannelState&#39;...
List of channels we keep for each destination port for a given destination entry. ...
#define GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG
uint16_t destination_port
Destination port to use for the UDP request.
Definition: exit.h:165
union DestinationEntry::@81 details
Details about the connection (depending on is_service).
int is_established
Is this channel new (GNUNET_NO), or did we exchange messages with the other side already (GNUNET_YES)...
uint32_t reserved
Always 0.
Definition: exit.h:47
Message send via cadet to an exit daemon to forward ICMP data to the Internet.
Definition: exit.h:236
#define GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START
Type of messages containing an TCP packet for the Internet.
static unsigned long long max_channel_mappings
If there are more than this number of open channels, old ones will be removed.
int af
Addess family used for this channel on the local TUN interface.
A 512-bit hashcode.
uint16_t destination_port
Destination port (in NBO).
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
struct GNUNET_CADET_Channel * channel
Cadet channel that is used for this connection.
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...
union ChannelState::@85 source_ip
IP address of the source on our end, initially uninitialized.
There must only be one value per key; storing a value should fail if a value under the same key alrea...
struct in_addr v4
Address if af is AF_INET.
struct GNUNET_HashCode key
The key used in the DHT.
static struct ChannelState * create_channel_to_destination(struct DestinationChannel *dt, int client_af)
Initialize the given destination entry&#39;s cadet channel.
#define GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static struct GNUNET_CONTAINER_MultiHashMap * channel_map
Map from source and destination address (IP+port) to connection information (mostly with the respecti...
struct DestinationEntry * destination
Destination entry list this struct DestinationChannel belongs with.
TCP packet header.
int GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
static unsigned long long payload
How much data are we currently storing in the database?
uint16_t destination_port
Destination port this channel state is used for.
union ChannelState::@86 destination_ip
Destination IP address used by the source on our end (this is the IP that we pick freely within the V...
static int tcp
Option -t: TCP requested.
Definition: gnunet-vpn.c:71
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
#define GNUNET_TUN_ICMPTYPE_ECHO_REQUEST
#define GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM
Message send via cadet to an exit daemon to send UDP data to a local service.
Definition: exit.h:120
uint16_t source_port
Source port (in NBO).
#define GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
struct DestinationChannel * dt_head
Head of DLL of channels associated with this destination.
uint16_t source_port
Source port (in NBO).
uint16_t destination_port
Destination port used by the sender on our end; 0 for uninitialized.
#define GNUNET_log(kind,...)
Message send via cadet to an exit daemon to initiate forwarding of TCP data to the Internet...
Definition: exit.h:63
int32_t af
Address family, AF_INET or AF_INET6, in network byte order.
Definition: exit.h:218
struct GNUNET_REGEX_Search * search
Active query with REGEX to locate exit.
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
#define GNUNET_YES
Definition: gnunet_common.h:77
unsigned int off
Number of 32-bit words in TCP header.
uint16_t source_port
Source port to use for the UDP request (0 to use a random port).
Definition: exit.h:160
Message send via cadet to an exit daemon to initiate forwarding of TCP data to a local service...
Definition: exit.h:37
#define GNUNET_TUN_ICMPTYPE_ECHO_REPLY
struct DestinationChannel * dt_tail
Tail of DLL of channels associated with this destination.
Message send via cadet between VPN and entry and an exit daemon to transmit TCP data between the VPN ...
Definition: exit.h:94
uint32_t reserved
Always 0.
Definition: exit.h:104
struct GNUNET_TUN_IcmpHeader icmp_header
ICMP header to use.
Definition: exit.h:223
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
uint16_t source_port
Source port to use for the UDP request (0 to use a random port).
Definition: exit.h:130
struct GNUNET_TUN_IcmpHeader icmp_header
ICMP header to use.
Definition: exit.h:255
Message send via cadet to an exit daemon to forward UDP data to the Internet.
Definition: exit.h:145
struct in6_addr v6
Address if af is AF_INET6.
#define gettext_noop(String)
Definition: gettext.h:69
uint16_t destination_port
Destination port to use for the UDP request.
Definition: exit.h:135
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.

References _, buf, GNUNET_TUN_IPv4Header::destination_address, GNUNET_TUN_IPv6Header::destination_address, 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, 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, and GNUNET_MessageHeader::type.

Referenced by run().

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 }
unsigned int header_length
struct in6_addr source_address
Origin of the packet.
uint16_t proto
Here we get an ETH_P_-number.
Information we track for each IP address to determine which channel to send the traffic over to the d...
struct in6_addr destination_address
Destination of the packet.
struct in_addr destination_address
Destination of the packet.
#define ETH_P_IPV6
Number for IPv6.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
Standard IPv4 header.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
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.
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
static char buf[2048]
static struct GNUNET_CONTAINER_MultiHashMap * destination_map
Map from IP address to destination information (possibly with a CADET channel handle for fast setup)...
A 512-bit hashcode.
Header from Linux TUN interface.
uint8_t next_header
For example, IPPROTO_UDP or IPPROTO_TCP.
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...
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.
struct GNUNET_HashCode key
The key used in the DHT.
Standard IPv6 header.
uint8_t protocol
L4-protocol, for example, IPPROTO_UDP or IPPROTO_TCP.
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
#define GNUNET_log(kind,...)
struct in_addr source_address
Origin of the packet.
Header for all communications.
#define ETH_P_IPV4
Number for IPv4.
#define GNUNET_MESSAGE_TYPE_VPN_HELPER
Type of messages between the gnunet-vpn-helper and the daemon.
#define gettext_noop(String)
Definition: gettext.h:69
Here is the call graph for this function:
Here is the caller graph for this function:

◆ 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.

References _, 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, and vpn_argv.

Referenced by allocate_response_ip().

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  return GNUNET_SYSERR;
2413  }
2414  /* Pick random IPv4 address within the subnet, except 'addr' or 'mask' itself */
2415  rnd.s_addr =
2417  v4->s_addr = (addr.s_addr | rnd.s_addr) & mask.s_addr;
2418  get_destination_key_from_ip (AF_INET, v4, &key);
2419  }
2420  while ((GNUNET_YES ==
2422  (v4->s_addr == addr.s_addr) || (v4->s_addr == mask.s_addr));
2423  return GNUNET_OK;
2424 }
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
int 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)...
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
static struct GNUNET_CONTAINER_MultiHashMap * destination_map
Map from IP address to destination information (possibly with a CADET channel handle for fast setup)...
A 512-bit hashcode.
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...
static char * vpn_argv[7]
Arguments to the vpn helper.
struct GNUNET_HashCode key
The key used in the DHT.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:77
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
Here is the call graph for this function:
Here is the caller graph for this function:

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

References _, 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, and vpn_argv.

Referenced by allocate_response_ip().

2437 {
2438  const char *ipv6addr = vpn_argv[2];
2439  struct in6_addr addr;
2440  struct in6_addr mask;
2441  struct in6_addr rnd;
2442  int i;
2443  struct GNUNET_HashCode key;
2444  unsigned int tries;
2445 
2446  GNUNET_assert (1 == inet_pton (AF_INET6, ipv6addr, &addr));
2447  GNUNET_assert (ipv6prefix < 128);
2448  /* Given ABCD::/96, we want a mask of 'ABCD::FFFF:FFFF,
2449  thus: */
2450  mask = addr;
2451  for (i = 127; i >= ipv6prefix; i--)
2452  mask.s6_addr[i / 8] |= (1 << (i % 8));
2453 
2454  /* Pick random IPv6 address within the subnet, except 'addr' or 'mask' itself */
2455  tries = 0;
2456  do
2457  {
2458  tries++;
2459  if (tries > 16)
2460  {
2462  _ (
2463  "Failed to find unallocated IPv6 address in VPN's range\n"));
2464  return GNUNET_SYSERR;
2465  }
2466  for (i = 0; i < 16; i++)
2467  {
2468  rnd.s6_addr[i] =
2470  256);
2471  v6->s6_addr[i] = (addr.s6_addr[i] | rnd.s6_addr[i]) & mask.s6_addr[i];
2472  }
2473  get_destination_key_from_ip (AF_INET6, v6, &key);
2474  }
2475  while ((GNUNET_YES ==
2477  (0 == GNUNET_memcmp (v6, &addr)) ||
2478  (0 == GNUNET_memcmp (v6, &mask)));
2479  return GNUNET_OK;
2480 }
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
int 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)...
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
static struct GNUNET_CONTAINER_MultiHashMap * destination_map
Map from IP address to destination information (possibly with a CADET channel handle for fast setup)...
A 512-bit hashcode.
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...
static char * vpn_argv[7]
Arguments to the vpn helper.
struct GNUNET_HashCode key
The key used in the DHT.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_log(kind,...)
static unsigned long long ipv6prefix
Length of the prefix of the VPN&#39;s IPv6 network.
#define GNUNET_YES
Definition: gnunet_common.h:77
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
Here is the call graph for this function:
Here is the caller graph for this function:

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

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

Referenced by cleanup_destination(), and expire_destination().

2490 {
2491  struct DestinationChannel *dt;
2492 
2494  "Cleaning up destination entry `%s'\n",
2497  gettext_noop ("# Active destinations"),
2498  -1,
2499  GNUNET_NO);
2500  while (NULL != (dt = de->dt_head))
2501  {
2503  GNUNET_free (dt);
2504  }
2505  if (NULL != de->heap_node)
2506  {
2508  de->heap_node = NULL;
2509  GNUNET_assert (
2510  GNUNET_YES ==
2512  }
2513  GNUNET_free (de);
2514 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
struct GNUNET_CONTAINER_HeapNode * heap_node
Entry for this entry in the destination_heap.
static const char * print_channel_destination(const struct DestinationEntry *de)
Output destination of a channel for diagnostics.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_NO
Definition: gnunet_common.h:78
struct GNUNET_HashCode key
Key under which this entry is in the &#39;destination_map&#39; (only valid if &#39;heap_node != NULL&#39;)...
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
List of channels we keep for each destination port for a given destination entry. ...
int GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
static struct GNUNET_CONTAINER_MultiHashMap * destination_map
Map from IP address to destination information (possibly with a CADET channel handle for fast setup)...
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
struct DestinationChannel * dt_head
Head of DLL of channels associated with this destination.
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:77
void * GNUNET_CONTAINER_heap_remove_node(struct GNUNET_CONTAINER_HeapNode *node)
Removes a node from the heap.
struct DestinationChannel * dt_tail
Tail of DLL of channels associated with this destination.
#define GNUNET_free(ptr)
Wrapper around free.
#define gettext_noop(String)
Definition: gettext.h:69
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 2523 of file gnunet-service-vpn.c.

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

Referenced by handle_client_redirect_to_ip(), and handle_client_redirect_to_service().

2524 {
2525  struct DestinationEntry *de;
2526 
2528  GNUNET_assert (NULL != de);
2529  if (except == de)
2530  return; /* can't do this */
2532 }
Information we track for each IP address to determine which channel to send the traffic over to the d...
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
void * GNUNET_CONTAINER_heap_peek(const struct GNUNET_CONTAINER_Heap *heap)
Get element stored at the root of heap.
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.
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 2550 of file gnunet-service-vpn.c.

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

2554 {
2555  *addr = NULL;
2556  switch (*result_af)
2557  {
2558  case AF_INET:
2559  if (GNUNET_OK != allocate_v4_address (v4))
2560  *result_af = AF_UNSPEC;
2561  else
2562  *addr = v4;
2563  break;
2564 
2565  case AF_INET6:
2566  if (GNUNET_OK != allocate_v6_address (v6))
2567  *result_af = AF_UNSPEC;
2568  else
2569  *addr = v6;
2570  break;
2571 
2572  case AF_UNSPEC:
2573  if (GNUNET_OK == allocate_v4_address (v4))
2574  {
2575  *addr = v4;
2576  *result_af = AF_INET;
2577  }
2578  else if (GNUNET_OK == allocate_v6_address (v6))
2579  {
2580  *addr = v6;
2581  *result_af = AF_INET6;
2582  }
2583  break;
2584 
2585  default:
2586  GNUNET_break (0);
2587  return GNUNET_SYSERR;
2588  }
2589  return GNUNET_OK;
2590 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
static int allocate_v6_address(struct in6_addr *v6)
Allocate an IPv6 address from the range of the channel for a new redirection.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct in_addr v4
Address if af is AF_INET.
struct in6_addr v6
Address if af is AF_INET6.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static int allocate_v4_address(struct in_addr *v4)
Allocate an IPv4 address from the range of the channel for a new redirection.
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 2603 of file gnunet-service-vpn.c.

References RedirectToIpRequestMessage::addr_af, GNUNET_break, GNUNET_OK, GNUNET_SYSERR, RedirectToIpRequestMessage::header, and GNUNET_MessageHeader::size.

2605 {
2606  size_t alen;
2607  int addr_af;
2608 
2609  alen = ntohs (msg->header.size) - sizeof(struct RedirectToIpRequestMessage);
2610  addr_af = (int) htonl (msg->addr_af);
2611  switch (addr_af)
2612  {
2613  case AF_INET:
2614  if (alen != sizeof(struct in_addr))
2615  {
2616  GNUNET_break (0);
2617  return GNUNET_SYSERR;
2618  }
2619  break;
2620 
2621  case AF_INET6:
2622  if (alen != sizeof(struct in6_addr))
2623  {
2624  GNUNET_break (0);
2625  return GNUNET_SYSERR;
2626  }
2627  break;
2628 
2629  default:
2630  GNUNET_break (0);
2631  return GNUNET_SYSERR;
2632  }
2633  return GNUNET_OK;
2634 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
Message send by the VPN client to the VPN service requesting the setup of a redirection from some IP ...
Definition: vpn.h:38
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_IP.
Definition: vpn.h:43
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
int32_t addr_af
Address family used for the destination address (AF_INET or AF_INET6, in nbo)
Definition: vpn.h:63

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

References GNUNET_TIME_Absolute::abs_value_us, RedirectToIpRequestMessage::addr_af, allocate_response_ip(), DestinationEntry::details, DestinationEntry::exit_destination, RedirectToIpRequestMessage::expiration_time, 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(), RedirectToIpRequestMessage::header, DestinationEntry::heap_node, DestinationEntry::is_service, key, DestinationEntry::key, max_destination_mappings, RedirectToIpRequestMessage::request_id, RedirectToIpRequestMessage::result_af, send_client_reply(), and GNUNET_MessageHeader::size.

2648 {
2649  struct GNUNET_SERVICE_Client *client = cls;
2650  size_t alen;
2651  int addr_af;
2652  int result_af;
2653  struct in_addr v4;
2654  struct in6_addr v6;
2655  void *addr;
2656  struct DestinationEntry *de;
2657  struct GNUNET_HashCode key;
2658 
2659  alen = ntohs (msg->header.size) - sizeof(struct RedirectToIpRequestMessage);
2660  addr_af = (int) htonl (msg->addr_af);
2661  /* allocate response IP */
2662  result_af = (int) htonl (msg->result_af);
2663  if (GNUNET_OK != allocate_response_ip (&result_af, &addr, &v4, &v6))
2664  {
2665  GNUNET_SERVICE_client_drop (client);
2666  return;
2667  }
2668  /* send reply with our IP address */
2669  send_client_reply (client, msg->request_id, result_af, addr);
2670  if (result_af == AF_UNSPEC)
2671  {
2672  /* failure, we're done */
2674  return;
2675  }
2676 
2677  {
2678  char sbuf[INET6_ADDRSTRLEN];
2679  char dbuf[INET6_ADDRSTRLEN];
2680 
2682  "Allocated address %s for redirection via exit to %s\n",
2683  inet_ntop (result_af, addr, sbuf, sizeof(sbuf)),
2684  inet_ntop (addr_af, &msg[1], dbuf, sizeof(dbuf)));
2685  }
2686 
2687  /* setup destination record */
2688  de = GNUNET_new (struct DestinationEntry);
2689  de->is_service = GNUNET_NO;
2690  de->details.exit_destination.af = addr_af;
2691  GNUNET_memcpy (&de->details.exit_destination.ip, &msg[1], alen);
2692  get_destination_key_from_ip (result_af, addr, &key);
2693  de->key = key;
2696  &key,
2697  de,
2700  de,
2702  msg->expiration_time)
2703  .abs_value_us);
2705  gettext_noop ("# Active destinations"),
2706  1,
2707  GNUNET_NO);
2710  expire_destination (de);
2712 }
struct GNUNET_CONTAINER_HeapNode * heap_node
Entry for this entry in the destination_heap.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:673
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
Information we track for each IP address to determine which channel to send the traffic over to the d...
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.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static void expire_destination(struct DestinationEntry *except)
We have too many active destinations.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_new(type)
Allocate a struct or union of the given type.
struct GNUNET_HashCode key
Key under which this entry is in the &#39;destination_map&#39; (only valid if &#39;heap_node != NULL&#39;)...
int is_service
GNUNET_NO if this is a channel to an Internet-exit, GNUNET_YES if this channel is to a service...
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
static unsigned long long max_destination_mappings
If there are more than this number of address-mappings, old ones will be removed. ...
struct DestinationEntry::@81::@83 exit_destination
uint64_t abs_value_us
The actual value.
Message send by the VPN client to the VPN service requesting the setup of a redirection from some IP ...
Definition: vpn.h:38
Handle to a client that is connected to a service.
Definition: service.c:250
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.
union DestinationEntry::@81 details
Details about the connection (depending on is_service).
int32_t result_af
Address family desired for the result (AF_INET or AF_INET6 or AF_UNSPEC, in nbo)
Definition: vpn.h:58
static struct GNUNET_CONTAINER_MultiHashMap * destination_map
Map from IP address to destination information (possibly with a CADET channel handle for fast setup)...
A 512-bit hashcode.
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2324
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...
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_IP.
Definition: vpn.h:43
struct GNUNET_HashCode key
The key used in the DHT.
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.
int GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
Allow multiple values with the same key.
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
int32_t addr_af
Address family used for the destination address (AF_INET or AF_INET6, in nbo)
Definition: vpn.h:63
struct GNUNET_TIME_AbsoluteNBO expiration_time
How long should the redirection be maintained at most?
Definition: vpn.h:53
#define GNUNET_log(kind,...)
static struct GNUNET_CONTAINER_Heap * destination_heap
Min-Heap sorted by activity time to expire old mappings.
uint64_t request_id
Unique ID to match a future response to this request.
Definition: vpn.h:69
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2243
#define gettext_noop(String)
Definition: gettext.h:69
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 2724 of file gnunet-service-vpn.c.

References _, GNUNET_TIME_Absolute::abs_value_us, allocate_response_ip(), DestinationChannel::destination, DestinationEntry::details, DestinationEntry::dt_head, DestinationEntry::dt_tail, RedirectToServiceRequestMessage::expiration_time, 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, DestinationEntry::is_service, key, DestinationEntry::key, max_destination_mappings, RedirectToServiceRequestMessage::request_id, RedirectToServiceRequestMessage::result_af, send_client_reply(), RedirectToServiceRequestMessage::service_descriptor, DestinationEntry::service_destination, and RedirectToServiceRequestMessage::target.

2727 {
2728  struct GNUNET_SERVICE_Client *client = cls;
2729  int result_af;
2730  struct in_addr v4;
2731  struct in6_addr v6;
2732  void *addr;
2733  struct DestinationEntry *de;
2734  struct GNUNET_HashCode key;
2735  struct DestinationChannel *dt;
2736 
2737  /* allocate response IP */
2738  result_af = (int) htonl (msg->result_af);
2739  if (GNUNET_OK != allocate_response_ip (&result_af, &addr, &v4, &v6))
2740  {
2741  GNUNET_break (0);
2742  GNUNET_SERVICE_client_drop (client);
2743  return;
2744  }
2745  send_client_reply (client, msg->request_id, result_af, addr);
2746  if (result_af == AF_UNSPEC)
2747  {
2748  /* failure, we're done */
2750  _ ("Failed to allocate IP address for new destination\n"));
2752  return;
2753  }
2754 
2755  {
2756  char sbuf[INET6_ADDRSTRLEN];
2757 
2759  "Allocated address %s for redirection to service %s on peer %s\n",
2760  inet_ntop (result_af, addr, sbuf, sizeof(sbuf)),
2762  GNUNET_i2s (&msg->target));
2763  }
2764 
2765  /* setup destination record */
2766  de = GNUNET_new (struct DestinationEntry);
2767  de->is_service = GNUNET_YES;
2768  de->details.service_destination.target = msg->target;
2769  de->details.service_destination.service_descriptor = msg->service_descriptor;
2770  get_destination_key_from_ip (result_af, addr, &key);
2771  de->key = key;
2774  &key,
2775  de,
2778  de,
2780  msg->expiration_time)
2781  .abs_value_us);
2784  expire_destination (de);
2785 
2786  dt = GNUNET_new (struct DestinationChannel);
2787  dt->destination = de;
2789  /* we're done */
2791 }
struct DestinationEntry::@81::@82 service_destination
struct GNUNET_HashCode service_descriptor
Service descriptor identifying the service.
Definition: vpn.h:115
struct GNUNET_CONTAINER_HeapNode * heap_node
Entry for this entry in the destination_heap.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:673
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
Information we track for each IP address to determine which channel to send the traffic over to the d...
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.
struct GNUNET_PeerIdentity target
Target peer offering the service.
Definition: vpn.h:110
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static void expire_destination(struct DestinationEntry *except)
We have too many active destinations.
int32_t result_af
Address family desired for the result (AF_INET or AF_INET6 or AF_UNSPEC, in nbo)
Definition: vpn.h:105
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_new(type)
Allocate a struct or union of the given type.
struct GNUNET_HashCode key
Key under which this entry is in the &#39;destination_map&#39; (only valid if &#39;heap_node != NULL&#39;)...
int is_service
GNUNET_NO if this is a channel to an Internet-exit, GNUNET_YES if this channel is to a service...
static unsigned long long max_destination_mappings
If there are more than this number of address-mappings, old ones will be removed. ...
uint64_t abs_value_us
The actual value.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
Handle to a client that is connected to a service.
Definition: service.c:250
List of channels we keep for each destination port for a given destination entry. ...
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.
union DestinationEntry::@81 details
Details about the connection (depending on is_service).
static struct GNUNET_CONTAINER_MultiHashMap * destination_map
Map from IP address to destination information (possibly with a CADET channel handle for fast setup)...
A 512-bit hashcode.
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2324
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...
struct GNUNET_HashCode key
The key used in the DHT.
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.
struct DestinationEntry * destination
Destination entry list this struct DestinationChannel belongs with.
int GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
struct GNUNET_TIME_AbsoluteNBO expiration_time
How long should the redirection be maintained at most?
Definition: vpn.h:95
uint64_t request_id
Unique ID to match a future response to this request.
Definition: vpn.h:121
Allow multiple values with the same key.
struct DestinationChannel * dt_head
Head of DLL of channels associated with this destination.
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:77
static struct GNUNET_CONTAINER_Heap * destination_heap
Min-Heap sorted by activity time to expire old mappings.
struct DestinationChannel * dt_tail
Tail of DLL of channels associated with this destination.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2243
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 2803 of file gnunet-service-vpn.c.

References free_destination_entry(), GNUNET_OK, and value.

Referenced by cleanup().

2804 {
2805  struct DestinationEntry *de = value;
2806 
2808  return GNUNET_OK;
2809 }
Information we track for each IP address to determine which channel to send the traffic over to the d...
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
static char * value
Value of the record to add/remove.
static void free_destination_entry(struct DestinationEntry *de)
Free resources occupied by a destination entry.
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 2821 of file gnunet-service-vpn.c.

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

Referenced by cleanup().

2822 {
2823  struct ChannelState *ts = value;
2824 
2826  "Tearing down channel to `%s' during cleanup\n",
2828  free_channel_state (ts);
2829  return GNUNET_OK;
2830 }
static const char * print_channel_destination(const struct DestinationEntry *de)
Output destination of a channel for diagnostics.
struct DestinationEntry destination
Destination to which this channel leads.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
static char * value
Value of the record to add/remove.
static void free_channel_state(struct ChannelState *ts)
Free resources associated with a channel state.
#define GNUNET_log(kind,...)
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cleanup()

static void cleanup ( void *  cls)
static

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

Parameters
clsunused

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

References cleanup_channel(), cleanup_destination(), GNUNET_CADET_disconnect(), GNUNET_CONTAINER_heap_destroy(), GNUNET_CONTAINER_multihashmap_destroy(), GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free_non_null, GNUNET_HELPER_kill(), GNUNET_HELPER_wait(), GNUNET_log, GNUNET_NO, GNUNET_STATISTICS_destroy(), and vpn_argv.

Referenced by run().

2840 {
2841  unsigned int i;
2842 
2843  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "VPN is shutting down\n");
2844  if (NULL != destination_map)
2845  {
2848  NULL);
2850  destination_map = NULL;
2851  }
2852  if (NULL != destination_heap)
2853  {
2855  destination_heap = NULL;
2856  }
2857  if (NULL != channel_map)
2858  {
2861  channel_map = NULL;
2862  }
2863  if (NULL != channel_heap)
2864  {
2866  channel_heap = NULL;
2867  }
2868  if (NULL != cadet_handle)
2869  {
2871  cadet_handle = NULL;
2872  }
2873  if (NULL != helper_handle)
2874  {
2877  helper_handle = NULL;
2878  }
2879  if (NULL != stats)
2880  {
2882  stats = NULL;
2883  }
2884  for (i = 0; i < 5; i++)
2886 }
int GNUNET_HELPER_kill(struct GNUNET_HELPER_Handle *h, int soft_kill)
Sends termination signal to the helper process.
Definition: helper.c:177
void GNUNET_CADET_disconnect(struct GNUNET_CADET_Handle *handle)
Disconnect from the cadet service.
Definition: cadet_api.c:841
static int cleanup_destination(void *cls, const struct GNUNET_HashCode *key, void *value)
Free memory occupied by an entry in the destination map.
#define GNUNET_NO
Definition: gnunet_common.h:78
static int cleanup_channel(void *cls, const struct GNUNET_HashCode *key, void *value)
Free memory occupied by an entry in the channel map.
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
static struct GNUNET_CONTAINER_Heap * channel_heap
Min-Heap sorted by activity time to expire old mappings; values are of type &#39;struct ChannelState&#39;...
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
static struct GNUNET_CONTAINER_MultiHashMap * destination_map
Map from IP address to destination information (possibly with a CADET channel handle for fast setup)...
static struct GNUNET_CADET_Handle * cadet_handle
Handle to the cadet service.
void GNUNET_CONTAINER_heap_destroy(struct GNUNET_CONTAINER_Heap *heap)
Destroys the heap.
static char * vpn_argv[7]
Arguments to the vpn helper.
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.
#define GNUNET_log(kind,...)
int GNUNET_HELPER_wait(struct GNUNET_HELPER_Handle *h)
Reap the helper process.
Definition: helper.c:225
static struct GNUNET_CONTAINER_Heap * destination_heap
Min-Heap sorted by activity time to expire old mappings.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
static struct GNUNET_HELPER_Handle * helper_handle
The handle to the VPN helper process "gnunet-helper-vpn".
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 2898 of file gnunet-service-vpn.c.

Referenced by run().

2901 {
2902  return c;
2903 }
Here is the caller graph for this function:

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

References GNUNET_assert.

Referenced by run().

2917 {
2918  GNUNET_assert (c == internal_cls);
2919 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
Here is the caller graph for this function:

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

References _, cleanup(), client_connect_cb(), client_disconnect_cb(), 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_free_non_null, GNUNET_HELPER_start(), GNUNET_log, GNUNET_log_config_invalid(), GNUNET_log_config_missing(), GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_IP, GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_SERVICE, GNUNET_MQ_handler_end, GNUNET_MQ_hd_fixed_size, GNUNET_MQ_hd_var_size, GNUNET_NETWORK_test_pf(), GNUNET_NO, GNUNET_OK, GNUNET_OS_check_helper_binary(), GNUNET_OS_get_libexec_binary_path(), GNUNET_SCHEDULER_add_shutdown(), GNUNET_SCHEDULER_shutdown(), GNUNET_SERVICE_MAIN(), GNUNET_SERVICE_OPTION_NONE, GNUNET_STATISTICS_create(), GNUNET_strdup, GNUNET_SYSERR, GNUNET_YES, ipv6prefix, max_channel_mappings, max_destination_mappings, message_token(), and vpn_argv.

2933 {
2934  char *ifname;
2935  char *ipv6addr;
2936  char *ipv6prefix_s;
2937  char *ipv4addr;
2938  char *ipv4mask;
2939  struct in_addr v4;
2940  struct in6_addr v6;
2941  char *binary;
2942 
2943  binary = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-vpn");
2944 
2945  if (GNUNET_YES !=
2947  binary,
2948  GNUNET_YES,
2949  "-d gnunet-vpn - - 169.1.3.3.7 255.255.255.0")) // ipv4 only please!
2950  {
2952  "`%s' is not SUID, refusing to run.\n",
2953  "gnunet-helper-vpn");
2954  GNUNET_free (binary);
2955  global_ret = 1;
2956  /* we won't "really" exit here, as the 'service' is still running;
2957  however, as no handlers are registered, the service won't do
2958  anything either */
2959  return;
2960  }
2961  GNUNET_free (binary);
2962  cfg = cfg_;
2963  stats = GNUNET_STATISTICS_create ("vpn", cfg);
2964  if (GNUNET_OK !=
2966  "VPN",
2967  "MAX_MAPPING",
2970  if (GNUNET_OK !=
2972  "VPN",
2973  "MAX_TUNNELS",
2975  max_channel_mappings = 200;
2976 
2977  destination_map =
2979  GNUNET_NO);
2982  channel_map =
2985 
2986 
2987  vpn_argv[0] = GNUNET_strdup ("vpn-gnunet");
2988  if (GNUNET_SYSERR ==
2989  GNUNET_CONFIGURATION_get_value_string (cfg, "VPN", "IFNAME", &ifname))
2990  {
2993  return;
2994  }
2995  vpn_argv[1] = ifname;
2996  ipv6addr = NULL;
2997  if (GNUNET_OK == GNUNET_NETWORK_test_pf (PF_INET6))
2998  {
3000  "VPN",
3001  "IPV6ADDR",
3002  &ipv6addr)) ||
3003  (1 != inet_pton (AF_INET6, ipv6addr, &v6))))
3004  {
3006  "VPN",
3007  "IPV6ADDR",
3008  _ ("Must specify valid IPv6 address"));
3010  GNUNET_free_non_null (ipv6addr);
3011  return;
3012  }
3013  vpn_argv[2] = ipv6addr;
3014  ipv6prefix_s = NULL;
3016  "VPN",
3017  "IPV6PREFIX",
3018  &ipv6prefix_s))
3019  {
3020  GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "VPN", "IPV6PREFIX");
3022  GNUNET_free_non_null (ipv6prefix_s);
3023  return;
3024  }
3025  vpn_argv[3] = ipv6prefix_s;
3027  "VPN",
3028  "IPV6PREFIX",
3029  &ipv6prefix)) ||
3030  (ipv6prefix >= 127))
3031  {
3033  "VPN",
3034  "IPV4MASK",
3035  _ ("Must specify valid IPv6 mask"));
3037  return;
3038  }
3039  }
3040  else
3041  {
3043  _ (
3044  "IPv6 support disabled as this system does not support IPv6\n"));
3045  vpn_argv[2] = GNUNET_strdup ("-");
3046  vpn_argv[3] = GNUNET_strdup ("-");
3047  }
3048  if (GNUNET_OK == GNUNET_NETWORK_test_pf (PF_INET))
3049  {
3050  ipv4addr = NULL;
3052  "vpn",
3053  "IPV4ADDR",
3054  &ipv4addr)) ||
3055  (1 != inet_pton (AF_INET, ipv4addr, &v4))))
3056  {
3058  "VPN",
3059  "IPV4ADDR",
3060  _ ("Must specify valid IPv4 address"));
3062  GNUNET_free_non_null (ipv4addr);
3063  return;
3064  }
3065  vpn_argv[4] = ipv4addr;
3066  ipv4mask = NULL;
3068  "vpn",
3069  "IPV4MASK",
3070  &ipv4mask)) ||
3071  (1 != inet_pton (AF_INET, ipv4mask, &v4))))
3072  {
3074  "VPN",
3075  "IPV4MASK",
3076  _ ("Must specify valid IPv4 mask"));
3078  GNUNET_free_non_null (ipv4mask);
3079  return;
3080  }
3081  vpn_argv[5] = ipv4mask;
3082  }
3083  else
3084  {
3086  _ (
3087  "IPv4 support disabled as this system does not support IPv4\n"));
3088  vpn_argv[4] = GNUNET_strdup ("-");
3089  vpn_argv[5] = GNUNET_strdup ("-");
3090  }
3091  vpn_argv[6] = NULL;
3092 
3094  // FIXME never opens ports???
3096  "gnunet-helper-vpn",
3097  vpn_argv,
3098  &message_token,
3099  NULL,
3100  NULL);
3102 }
int 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.
struct GNUNET_HELPER_Handle * GNUNET_HELPER_start(int with_control_pipe, const char *binary_name, char *const binary_argv[], GNUNET_MessageTokenizerCallback cb, GNUNET_HELPER_ExceptionCallback exp_cb, void *cb_cls)
Starts a helper and begins reading from it.
Definition: helper.c:489
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, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1300
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we use.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
int GNUNET_OS_check_helper_binary(const char *binary, int check_suid, const char *params)
Check whether an executable exists and possibly if the suid bit is set on the file.
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_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:526
static unsigned long long max_destination_mappings
If there are more than this number of address-mappings, old ones will be removed. ...
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
struct GNUNET_CADET_Handle * GNUNET_CADET_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the MQ-based cadet service.
Definition: cadet_api.c:976
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
static int global_ret
Return value from main().
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
static struct GNUNET_CONTAINER_Heap * channel_heap
Min-Heap sorted by activity time to expire old mappings; values are of type &#39;struct ChannelState&#39;...
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)...
static void cleanup(void *cls)
Function scheduled as very last function, cleans up after us.
static unsigned long long max_channel_mappings
If there are more than this number of open channels, old ones will be removed.
static struct GNUNET_CONTAINER_MultiHashMap * destination_map
Map from IP address to destination information (possibly with a CADET channel handle for fast setup)...
static struct GNUNET_CADET_Handle * cadet_handle
Handle to the cadet service.
Heap with the minimum cost at the root.
int 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.
static char * vpn_argv[7]
Arguments to the vpn helper.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static struct GNUNET_CONTAINER_MultiHashMap * channel_map
Map from source and destination address (IP+port) to connection information (mostly with the respecti...
struct GNUNET_CONTAINER_Heap * GNUNET_CONTAINER_heap_create(enum GNUNET_CONTAINER_HeapOrder order)
Create a new heap.
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
#define GNUNET_log(kind,...)
static unsigned long long ipv6prefix
Length of the prefix of the VPN&#39;s IPv6 network.
char * GNUNET_OS_get_libexec_binary_path(const char *progname)
Given the name of a gnunet-helper, gnunet-service or gnunet-daemon binary, try to prefix it with the ...
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
#define GNUNET_YES
Definition: gnunet_common.h:77
static struct GNUNET_CONTAINER_Heap * destination_heap
Min-Heap sorted by activity time to expire old mappings.
static struct GNUNET_HELPER_Handle * helper_handle
The handle to the VPN helper process "gnunet-helper-vpn".
int GNUNET_NETWORK_test_pf(int pf)
Test if the given protocol family is supported by this system.
Definition: network.c:85
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:

◆ GNUNET_SERVICE_MAIN()

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

Define "main" method using service macro.

Referenced by run().

Here is the caller graph for this function:

Variable Documentation

◆ global_ret

int global_ret
static

Return value from main().

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

Referenced by run().

◆ cfg

const struct GNUNET_CONFIGURATION_Handle* cfg
static

Configuration we use.

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

◆ cadet_handle

struct GNUNET_CADET_Handle* cadet_handle
static

Handle to the cadet service.

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

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

◆ destination_heap

struct GNUNET_CONTAINER_Heap* destination_heap
static

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

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

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

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

◆ stats

struct GNUNET_STATISTICS_Handle* stats
static

Statistics.

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

◆ helper_handle

struct GNUNET_HELPER_Handle* helper_handle
static

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

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

◆ vpn_argv

char* vpn_argv[7]
static

Arguments to the vpn helper.

Definition at line 354 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 359 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 365 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 371 of file gnunet-service-vpn.c.

Referenced by route_packet(), and run().