GNUnet  0.10.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 373 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().

376 {
377  switch (af)
378  {
379  case AF_INET:
380  GNUNET_CRYPTO_hash(address, sizeof(struct in_addr), key);
381  break;
382 
383  case AF_INET6:
384  GNUNET_CRYPTO_hash(address, sizeof(struct in6_addr), key);
385  break;
386 
387  default:
388  GNUNET_assert(0);
389  break;
390  }
391 }
#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:44
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 407 of file gnunet-service-vpn.c.

References GNUNET_assert, and GNUNET_memcpy.

Referenced by free_channel_state(), and route_packet().

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

463 {
464  struct GNUNET_MQ_Envelope *env;
466  size_t rlen;
467 
468  switch (result_af)
469  {
470  case AF_INET:
471  rlen = sizeof(struct in_addr);
472  break;
473 
474  case AF_INET6:
475  rlen = sizeof(struct in6_addr);
476  break;
477 
478  case AF_UNSPEC:
479  rlen = 0;
480  break;
481 
482  default:
483  GNUNET_assert(0);
484  return;
485  }
487  res->result_af = htonl(result_af);
488  res->request_id = request_id;
489  GNUNET_memcpy(&res[1], addr, rlen);
491 }
Response from the VPN service to a VPN client informing about the IP that was assigned for the reques...
Definition: vpn.h:127
struct GNUNET_MQ_Handle * GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c)
Obtain the message queue of c.
Definition: service.c:2424
#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:142
#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:137
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:351
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 500 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().

501 {
502  struct GNUNET_HashCode key;
503  struct ChannelMessageQueueEntry *tnq;
504  struct GNUNET_CADET_Channel *channel;
505 
506  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Cleaning up channel state\n");
507  if (NULL != (channel = ts->channel))
508  {
509  ts->channel = NULL;
511  return;
512  }
514  gettext_noop("# Active channels"),
515  -1,
516  GNUNET_NO);
517  while (NULL != (tnq = ts->tmq_head))
518  {
520  ts->tmq_length--;
521  GNUNET_free(tnq);
522  }
523  GNUNET_assert(0 == ts->tmq_length);
524  GNUNET_assert(NULL == ts->destination.heap_node);
525  if (NULL != ts->search)
526  {
528  ts->search = NULL;
529  }
530  if (NULL != ts->heap_node)
531  {
533  ts->heap_node = NULL;
535  ts->protocol,
536  &ts->source_ip,
537  ts->source_port,
538  &ts->destination_ip,
539  ts->destination_port,
540  &key);
542  GNUNET_YES ==
544  }
545  GNUNET_free(ts);
546 }
#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:79
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.
union ChannelState::@88 source_ip
IP address of the source on our end, initially uninitialized.
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...
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...
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:900
union ChannelState::@89 destination_ip
Destination IP address used by the source on our end (this is the IP that we pick freely within the V...
#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 557 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().

558 {
559  struct GNUNET_MQ_Handle *mq;
560 
561  GNUNET_assert(NULL != ts->channel);
562  mq = GNUNET_CADET_get_mq(ts->channel);
566  GNUNET_MQ_send(mq, env);
568  {
569  env = GNUNET_MQ_unsent_head(mq);
570  GNUNET_assert(NULL != env);
572  gettext_noop(
573  "# Messages dropped in cadet queue (overflow)"),
574  1,
575  GNUNET_NO);
576  GNUNET_MQ_discard(env);
577  }
578 }
#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:1002
#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:333
#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:319
Handle to a message queue.
Definition: mq.c:84
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:351
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:392
#define gettext_noop(String)
Definition: gettext.h:69
struct GNUNET_MQ_Handle * GNUNET_CADET_get_mq(const struct GNUNET_CADET_Channel *channel)
Obtain the message queue for a connected peer.
Definition: cadet_api.c:1116
Here is the call graph for this function:
Here is the caller graph for this function:

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

589 {
590  static char dest[256];
591 
592  if (de->is_service)
593  {
594  GNUNET_snprintf(dest,
595  sizeof(dest),
596  "HS: %s-%s",
598  GNUNET_h2s(
599  &de->details.service_destination.service_descriptor));
600  }
601  else
602  {
603  inet_ntop(de->details.exit_destination.af,
604  &de->details.exit_destination.ip,
605  dest,
606  sizeof(dest));
607  }
608  return dest;
609 }
int GNUNET_snprintf(char *buf, size_t size, const char *format,...)
Like snprintf, just aborts if the buffer is of insufficient size.
struct DestinationEntry::@84::@85 service_destination
struct DestinationEntry::@84::@86 exit_destination
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...
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
union DestinationEntry::@84 details
Details about the connection (depending on is_service).
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 620 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().

621 {
622  struct ChannelState *ts = cls;
623 
624  ts->channel =
625  NULL; /* we must not call GNUNET_CADET_channel_destroy() anymore */
627  "CADET notified us about death of channel to `%s'\n",
629  free_channel_state(ts);
630 }
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 643 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().

646 {
648  ts->protocol,
649  sizeof(struct GNUNET_TUN_TcpHeader),
650  &ts->source_ip.v4,
651  &ts->destination_ip.v4);
652  udp->source_port = htons(ts->source_port);
653  udp->destination_port = htons(ts->destination_port);
654  udp->len = htons(0);
655  udp->crc = htons(0);
656 }
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::@88 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.
uint16_t source_port
Source port (in NBO).
uint16_t destination_port
Destination port used by the sender on our end; 0 for uninitialized.
union ChannelState::@89 destination_ip
Destination IP address used by the source on our end (this is the IP that we pick freely within the V...
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 669 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().

672 {
674  ts->protocol,
675  sizeof(struct GNUNET_TUN_TcpHeader),
676  &ts->source_ip.v6,
677  &ts->destination_ip.v6);
678  udp->source_port = htons(ts->source_port);
679  udp->destination_port = htons(ts->destination_port);
680  udp->len = htons(0);
681  udp->crc = htons(0);
682 }
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::@88 source_ip
IP address of the source on our end, initially uninitialized.
TCP packet header.
uint16_t crc
Checksum.
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
union ChannelState::@89 destination_ip
Destination IP address used by the source on our end (this is the IP that we pick freely within the V...
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 694 of file gnunet-service-vpn.c.

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

695 {
696  struct ChannelState *ts = cls;
697 
698  if (NULL == ts->heap_node)
699  {
700  GNUNET_break_op(0);
701  return GNUNET_SYSERR;
702  }
703  if (AF_UNSPEC == ts->af)
704  {
705  GNUNET_break_op(0);
706  return GNUNET_SYSERR;
707  }
708  return GNUNET_OK;
709 }
#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 720 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.

721 {
722  struct ChannelState *ts = cls;
723  size_t mlen;
724 
726  gettext_noop("# ICMP packets received from cadet"),
727  1,
728  GNUNET_NO);
729  mlen =
730  ntohs(i2v->header.size) - sizeof(struct GNUNET_EXIT_IcmpToVPNMessage);
731  {
732  char sbuf[INET6_ADDRSTRLEN];
733  char dbuf[INET6_ADDRSTRLEN];
734 
735  GNUNET_log(
737  "Received ICMP packet from cadet, sending %u bytes from %s -> %s via TUN\n",
738  (unsigned int)mlen,
739  inet_ntop(ts->af, &ts->destination_ip, sbuf, sizeof(sbuf)),
740  inet_ntop(ts->af, &ts->source_ip, dbuf, sizeof(dbuf)));
741  }
742  switch (ts->af)
743  {
744  case AF_INET: {
745  size_t size = sizeof(struct GNUNET_TUN_IPv4Header) +
746  sizeof(struct GNUNET_TUN_IcmpHeader) +
747  sizeof(struct GNUNET_MessageHeader) +
748  sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
749  {
750  /* reserve some extra space in case we have an ICMP type here where
751  we will need to make up the payload ourselves */
752  char buf[size + sizeof(struct GNUNET_TUN_IPv4Header) + 8] GNUNET_ALIGN;
753  struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *)buf;
754  struct GNUNET_TUN_Layer2PacketHeader *tun =
755  (struct GNUNET_TUN_Layer2PacketHeader *)&msg[1];
756  struct GNUNET_TUN_IPv4Header *ipv4 =
757  (struct GNUNET_TUN_IPv4Header *)&tun[1];
758  struct GNUNET_TUN_IcmpHeader *icmp =
759  (struct GNUNET_TUN_IcmpHeader *)&ipv4[1];
760  msg->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
761  tun->flags = htons(0);
762  tun->proto = htons(ETH_P_IPV4);
764  IPPROTO_ICMP,
765  sizeof(struct GNUNET_TUN_IcmpHeader) +
766  mlen,
767  &ts->destination_ip.v4,
768  &ts->source_ip.v4);
769  *icmp = i2v->icmp_header;
770  GNUNET_memcpy(&icmp[1], &i2v[1], mlen);
771  /* For some ICMP types, we need to adjust (make up) the payload here.
772  Also, depending on the AF used on the other side, we have to
773  do ICMP PT (translate ICMP types) */
774  switch (ntohl(i2v->af))
775  {
776  case AF_INET:
777  switch (icmp->type)
778  {
781  break;
782 
786  struct GNUNET_TUN_IPv4Header *ipp =
787  (struct GNUNET_TUN_IPv4Header *)&icmp[1];
788  struct GNUNET_TUN_UdpHeader *udp =
789  (struct GNUNET_TUN_UdpHeader *)&ipp[1];
790 
791  if (mlen != 0)
792  {
793  /* sender did not strip ICMP payload? */
794  GNUNET_break_op(0);
795  return;
796  }
797  size += sizeof(struct GNUNET_TUN_IPv4Header) + 8;
798  GNUNET_assert(8 == sizeof(struct GNUNET_TUN_UdpHeader));
799  make_up_icmpv4_payload(ts, ipp, udp);
800  }
801  break;
802 
803  default:
804  GNUNET_break_op(0);
806  stats,
807  gettext_noop("# ICMPv4 packets dropped (type not allowed)"),
808  1,
809  GNUNET_NO);
810  return;
811  }
812  /* end AF_INET */
813  break;
814 
815  case AF_INET6:
816  /* ICMP PT 6-to-4 and possibly making up payloads */
817  switch (icmp->type)
818  {
821  {
822  struct GNUNET_TUN_IPv4Header *ipp =
823  (struct GNUNET_TUN_IPv4Header *)&icmp[1];
824  struct GNUNET_TUN_UdpHeader *udp =
825  (struct GNUNET_TUN_UdpHeader *)&ipp[1];
826 
827  if (mlen != 0)
828  {
829  /* sender did not strip ICMP payload? */
830  GNUNET_break_op(0);
831  return;
832  }
833  size += sizeof(struct GNUNET_TUN_IPv4Header) + 8;
834  GNUNET_assert(8 == sizeof(struct GNUNET_TUN_UdpHeader));
835  make_up_icmpv4_payload(ts, ipp, udp);
836  }
837  break;
838 
841  {
842  struct GNUNET_TUN_IPv4Header *ipp =
843  (struct GNUNET_TUN_IPv4Header *)&icmp[1];
844  struct GNUNET_TUN_UdpHeader *udp =
845  (struct GNUNET_TUN_UdpHeader *)&ipp[1];
846 
847  if (mlen != 0)
848  {
849  /* sender did not strip ICMP payload? */
850  GNUNET_break_op(0);
851  return;
852  }
853  size += sizeof(struct GNUNET_TUN_IPv4Header) + 8;
854  GNUNET_assert(8 == sizeof(struct GNUNET_TUN_UdpHeader));
855  make_up_icmpv4_payload(ts, ipp, udp);
856  }
857  break;
858 
862  stats,
863  gettext_noop("# ICMPv6 packets dropped (impossible PT to v4)"),
864  1,
865  GNUNET_NO);
866  return;
867 
870  break;
871 
874  break;
875 
876  default:
877  GNUNET_break_op(0);
879  stats,
880  gettext_noop("# ICMPv6 packets dropped (type not allowed)"),
881  1,
882  GNUNET_NO);
883  return;
884  }
885  /* end AF_INET6 */
886  break;
887 
888  default:
889  GNUNET_break_op(0);
890  return;
891  }
892  msg->size = htons(size);
893  GNUNET_TUN_calculate_icmp_checksum(icmp, &i2v[1], mlen);
894  (void)GNUNET_HELPER_send(helper_handle, msg, GNUNET_YES, NULL, NULL);
895  }
896  }
897  break;
898 
899  case AF_INET6: {
900  size_t size = sizeof(struct GNUNET_TUN_IPv6Header) +
901  sizeof(struct GNUNET_TUN_IcmpHeader) +
902  sizeof(struct GNUNET_MessageHeader) +
903  sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
904  {
905  char buf[size + sizeof(struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
906  struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *)buf;
907  struct GNUNET_TUN_Layer2PacketHeader *tun =
908  (struct GNUNET_TUN_Layer2PacketHeader *)&msg[1];
909  struct GNUNET_TUN_IPv6Header *ipv6 =
910  (struct GNUNET_TUN_IPv6Header *)&tun[1];
911  struct GNUNET_TUN_IcmpHeader *icmp =
912  (struct GNUNET_TUN_IcmpHeader *)&ipv6[1];
913  msg->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
914  tun->flags = htons(0);
915  tun->proto = htons(ETH_P_IPV6);
917  IPPROTO_ICMPV6,
918  sizeof(struct GNUNET_TUN_IcmpHeader) +
919  mlen,
920  &ts->destination_ip.v6,
921  &ts->source_ip.v6);
922  *icmp = i2v->icmp_header;
923  GNUNET_memcpy(&icmp[1], &i2v[1], mlen);
924 
925  /* For some ICMP types, we need to adjust (make up) the payload here.
926  Also, depending on the AF used on the other side, we have to
927  do ICMP PT (translate ICMP types) */
928  switch (ntohl(i2v->af))
929  {
930  case AF_INET:
931  /* ICMP PT 4-to-6 and possibly making up payloads */
932  switch (icmp->type)
933  {
936  break;
937 
940  break;
941 
944  {
945  struct GNUNET_TUN_IPv6Header *ipp =
946  (struct GNUNET_TUN_IPv6Header *)&icmp[1];
947  struct GNUNET_TUN_UdpHeader *udp =
948  (struct GNUNET_TUN_UdpHeader *)&ipp[1];
949 
950  if (mlen != 0)
951  {
952  /* sender did not strip ICMP payload? */
953  GNUNET_break_op(0);
954  return;
955  }
956  size += sizeof(struct GNUNET_TUN_IPv6Header) + 8;
957  GNUNET_assert(8 == sizeof(struct GNUNET_TUN_UdpHeader));
958  make_up_icmpv6_payload(ts, ipp, udp);
959  }
960  break;
961 
964  {
965  struct GNUNET_TUN_IPv6Header *ipp =
966  (struct GNUNET_TUN_IPv6Header *)&icmp[1];
967  struct GNUNET_TUN_UdpHeader *udp =
968  (struct GNUNET_TUN_UdpHeader *)&ipp[1];
969 
970  if (mlen != 0)
971  {
972  /* sender did not strip ICMP payload? */
973  GNUNET_break_op(0);
974  return;
975  }
976  size += sizeof(struct GNUNET_TUN_IPv6Header) + 8;
977  GNUNET_assert(8 == sizeof(struct GNUNET_TUN_UdpHeader));
978  make_up_icmpv6_payload(ts, ipp, udp);
979  }
980  break;
981 
984  stats,
985  gettext_noop("# ICMPv4 packets dropped (impossible PT to v6)"),
986  1,
987  GNUNET_NO);
988  return;
989 
990  default:
991  GNUNET_break_op(0);
993  stats,
994  gettext_noop("# ICMPv4 packets dropped (type not allowed)"),
995  1,
996  GNUNET_NO);
997  return;
998  }
999  /* end AF_INET */
1000  break;
1001 
1002  case AF_INET6:
1003  switch (icmp->type)
1004  {
1009  struct GNUNET_TUN_IPv6Header *ipp =
1010  (struct GNUNET_TUN_IPv6Header *)&icmp[1];
1011  struct GNUNET_TUN_UdpHeader *udp =
1012  (struct GNUNET_TUN_UdpHeader *)&ipp[1];
1013 
1014  if (mlen != 0)
1015  {
1016  /* sender did not strip ICMP payload? */
1017  GNUNET_break_op(0);
1018  return;
1019  }
1020  size += sizeof(struct GNUNET_TUN_IPv6Header) + 8;
1021  GNUNET_assert(8 == sizeof(struct GNUNET_TUN_UdpHeader));
1022  make_up_icmpv6_payload(ts, ipp, udp);
1023  }
1024  break;
1025 
1027  break;
1028 
1029  default:
1030  GNUNET_break_op(0);
1032  stats,
1033  gettext_noop("# ICMPv6 packets dropped (type not allowed)"),
1034  1,
1035  GNUNET_NO);
1036  return;
1037  }
1038  /* end AF_INET6 */
1039  break;
1040 
1041  default:
1042  GNUNET_break_op(0);
1043  return;
1044  }
1045  msg->size = htons(size);
1046  GNUNET_TUN_calculate_icmp_checksum(icmp, &i2v[1], mlen);
1047  (void)GNUNET_HELPER_send(helper_handle, msg, GNUNET_YES, NULL, NULL);
1048  }
1049  }
1050  break;
1051 
1052  default:
1053  GNUNET_assert(0);
1054  }
1056  GNUNET_TIME_absolute_get().abs_value_us);
1058 }
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:278
#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:273
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::@88 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:66
#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:263
Standard IPv6 header.
#define GNUNET_TUN_ICMPTYPE_ECHO_REQUEST
#define GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM
#define GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Send an ack on the channel to confirm the processing of a message.
Definition: cadet_api.c:951
static 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:653
#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:267
#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
union ChannelState::@89 destination_ip
Destination IP address used by the source on our end (this is the IP that we pick freely within the V...
#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 1070 of file gnunet-service-vpn.c.

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

1071 {
1072  struct ChannelState *ts = cls;
1073 
1074  if (NULL == ts->heap_node)
1075  {
1076  GNUNET_break_op(0);
1077  return GNUNET_SYSERR;
1078  }
1079  if (AF_UNSPEC == ts->af)
1080  {
1081  GNUNET_break_op(0);
1082  return GNUNET_SYSERR;
1083  }
1084  return GNUNET_OK;
1085 }
#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 1096 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.

1097 {
1098  struct ChannelState *ts = cls;
1099  size_t mlen;
1100 
1102  gettext_noop("# UDP packets received from cadet"),
1103  1,
1104  GNUNET_NO);
1105  mlen =
1106  ntohs(reply->header.size) - sizeof(struct GNUNET_EXIT_UdpReplyMessage);
1107  {
1108  char sbuf[INET6_ADDRSTRLEN];
1109  char dbuf[INET6_ADDRSTRLEN];
1110 
1111  GNUNET_log(
1113  "Received UDP reply from cadet, sending %u bytes from [%s]:%u -> [%s]:%u via TUN\n",
1114  (unsigned int)mlen,
1115  inet_ntop(ts->af, &ts->destination_ip, sbuf, sizeof(sbuf)),
1116  ts->destination_port,
1117  inet_ntop(ts->af, &ts->source_ip, dbuf, sizeof(dbuf)),
1118  ts->source_port);
1119  }
1120  switch (ts->af)
1121  {
1122  case AF_INET: {
1123  size_t size = sizeof(struct GNUNET_TUN_IPv4Header) +
1124  sizeof(struct GNUNET_TUN_UdpHeader) +
1125  sizeof(struct GNUNET_MessageHeader) +
1126  sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
1127  {
1128  char buf[size] GNUNET_ALIGN;
1129  struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *)buf;
1130  struct GNUNET_TUN_Layer2PacketHeader *tun =
1131  (struct GNUNET_TUN_Layer2PacketHeader *)&msg[1];
1132  struct GNUNET_TUN_IPv4Header *ipv4 =
1133  (struct GNUNET_TUN_IPv4Header *)&tun[1];
1134  struct GNUNET_TUN_UdpHeader *udp =
1135  (struct GNUNET_TUN_UdpHeader *)&ipv4[1];
1136  msg->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
1137  msg->size = htons(size);
1138  tun->flags = htons(0);
1139  tun->proto = htons(ETH_P_IPV4);
1141  IPPROTO_UDP,
1142  sizeof(struct GNUNET_TUN_UdpHeader) +
1143  mlen,
1144  &ts->destination_ip.v4,
1145  &ts->source_ip.v4);
1146  if (0 == ntohs(reply->source_port))
1147  udp->source_port = htons(ts->destination_port);
1148  else
1149  udp->source_port = reply->source_port;
1150  if (0 == ntohs(reply->destination_port))
1151  udp->destination_port = htons(ts->source_port);
1152  else
1153  udp->destination_port = reply->destination_port;
1154  udp->len = htons(mlen + sizeof(struct GNUNET_TUN_UdpHeader));
1155  GNUNET_TUN_calculate_udp4_checksum(ipv4, udp, &reply[1], mlen);
1156  GNUNET_memcpy(&udp[1], &reply[1], mlen);
1157  (void)GNUNET_HELPER_send(helper_handle, msg, GNUNET_YES, NULL, NULL);
1158  }
1159  }
1160  break;
1161 
1162  case AF_INET6: {
1163  size_t size = sizeof(struct GNUNET_TUN_IPv6Header) +
1164  sizeof(struct GNUNET_TUN_UdpHeader) +
1165  sizeof(struct GNUNET_MessageHeader) +
1166  sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
1167  {
1168  char buf[size] GNUNET_ALIGN;
1169  struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *)buf;
1170  struct GNUNET_TUN_Layer2PacketHeader *tun =
1171  (struct GNUNET_TUN_Layer2PacketHeader *)&msg[1];
1172  struct GNUNET_TUN_IPv6Header *ipv6 =
1173  (struct GNUNET_TUN_IPv6Header *)&tun[1];
1174  struct GNUNET_TUN_UdpHeader *udp =
1175  (struct GNUNET_TUN_UdpHeader *)&ipv6[1];
1176  msg->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
1177  msg->size = htons(size);
1178  tun->flags = htons(0);
1179  tun->proto = htons(ETH_P_IPV6);
1181  IPPROTO_UDP,
1182  sizeof(struct GNUNET_TUN_UdpHeader) +
1183  mlen,
1184  &ts->destination_ip.v6,
1185  &ts->source_ip.v6);
1186  if (0 == ntohs(reply->source_port))
1187  udp->source_port = htons(ts->destination_port);
1188  else
1189  udp->source_port = reply->source_port;
1190  if (0 == ntohs(reply->destination_port))
1191  udp->destination_port = htons(ts->source_port);
1192  else
1193  udp->destination_port = reply->destination_port;
1194  udp->len = htons(mlen + sizeof(struct GNUNET_TUN_UdpHeader));
1195  GNUNET_TUN_calculate_udp6_checksum(ipv6, udp, &reply[1], mlen);
1196  GNUNET_memcpy(&udp[1], &reply[1], mlen);
1197  (void)GNUNET_HELPER_send(helper_handle, msg, GNUNET_YES, NULL, NULL);
1198  }
1199  }
1200  break;
1201 
1202  default:
1203  GNUNET_assert(0);
1204  }
1206  GNUNET_TIME_absolute_get().abs_value_us);
1208 }
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:177
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:173
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::@88 source_ip
IP address of the source on our end, initially uninitialized.
uint16_t source_port
Source port to use for the UDP reply (0 to use the same port as for the original request).
Definition: exit.h:183
struct in_addr v4
Address if af is AF_INET.
static unsigned int size
Size of the "table".
Definition: peer.c:66
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:951
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:653
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:189
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
union ChannelState::@89 destination_ip
Destination IP address used by the source on our end (this is the IP that we pick freely within the V...
#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 1220 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.

1221 {
1222  struct ChannelState *ts = cls;
1223 
1224  if (NULL == ts->heap_node)
1225  {
1226  GNUNET_break_op(0);
1227  return GNUNET_SYSERR;
1228  }
1229  if (data->tcp_header.off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
1230  {
1231  GNUNET_break_op(0);
1232  return GNUNET_SYSERR;
1233  }
1234  return GNUNET_OK;
1235 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
struct GNUNET_TUN_TcpHeader tcp_header
Skeleton of the TCP header to send.
Definition: exit.h:107
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 1246 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.

1247 {
1248  struct ChannelState *ts = cls;
1249  size_t mlen;
1250 
1252  gettext_noop("# TCP packets received from cadet"),
1253  1,
1254  GNUNET_NO);
1255  mlen = ntohs(data->header.size) - sizeof(struct GNUNET_EXIT_TcpDataMessage);
1256  {
1257  char sbuf[INET6_ADDRSTRLEN];
1258  char dbuf[INET6_ADDRSTRLEN];
1259 
1260  GNUNET_log(
1262  "Received TCP reply from cadet, sending %u bytes from [%s]:%u -> [%s]:%u via TUN\n",
1263  (unsigned int)mlen,
1264  inet_ntop(ts->af, &ts->destination_ip, sbuf, sizeof(sbuf)),
1265  ts->destination_port,
1266  inet_ntop(ts->af, &ts->source_ip, dbuf, sizeof(dbuf)),
1267  ts->source_port);
1268  }
1269  switch (ts->af)
1270  {
1271  case AF_INET: {
1272  size_t size = sizeof(struct GNUNET_TUN_IPv4Header) +
1273  sizeof(struct GNUNET_TUN_TcpHeader) +
1274  sizeof(struct GNUNET_MessageHeader) +
1275  sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
1276  {
1277  char buf[size] GNUNET_ALIGN;
1278  struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *)buf;
1279  struct GNUNET_TUN_Layer2PacketHeader *tun =
1280  (struct GNUNET_TUN_Layer2PacketHeader *)&msg[1];
1281  struct GNUNET_TUN_IPv4Header *ipv4 =
1282  (struct GNUNET_TUN_IPv4Header *)&tun[1];
1283  struct GNUNET_TUN_TcpHeader *tcp =
1284  (struct GNUNET_TUN_TcpHeader *)&ipv4[1];
1285  msg->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
1286  msg->size = htons(size);
1287  tun->flags = htons(0);
1288  tun->proto = htons(ETH_P_IPV4);
1290  IPPROTO_TCP,
1291  sizeof(struct GNUNET_TUN_TcpHeader) +
1292  mlen,
1293  &ts->destination_ip.v4,
1294  &ts->source_ip.v4);
1295  *tcp = data->tcp_header;
1296  tcp->source_port = htons(ts->destination_port);
1297  tcp->destination_port = htons(ts->source_port);
1298  GNUNET_TUN_calculate_tcp4_checksum(ipv4, tcp, &data[1], mlen);
1299  GNUNET_memcpy(&tcp[1], &data[1], mlen);
1300  (void)GNUNET_HELPER_send(helper_handle, msg, GNUNET_YES, NULL, NULL);
1301  }
1302  }
1303  break;
1304 
1305  case AF_INET6: {
1306  size_t size = sizeof(struct GNUNET_TUN_IPv6Header) +
1307  sizeof(struct GNUNET_TUN_TcpHeader) +
1308  sizeof(struct GNUNET_MessageHeader) +
1309  sizeof(struct GNUNET_TUN_Layer2PacketHeader) + mlen;
1310  {
1311  char buf[size] GNUNET_ALIGN;
1312  struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *)buf;
1313  struct GNUNET_TUN_Layer2PacketHeader *tun =
1314  (struct GNUNET_TUN_Layer2PacketHeader *)&msg[1];
1315  struct GNUNET_TUN_IPv6Header *ipv6 =
1316  (struct GNUNET_TUN_IPv6Header *)&tun[1];
1317  struct GNUNET_TUN_TcpHeader *tcp =
1318  (struct GNUNET_TUN_TcpHeader *)&ipv6[1];
1319  msg->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
1320  msg->size = htons(size);
1321  tun->flags = htons(0);
1322  tun->proto = htons(ETH_P_IPV6);
1324  IPPROTO_TCP,
1325  sizeof(struct GNUNET_TUN_TcpHeader) +
1326  mlen,
1327  &ts->destination_ip.v6,
1328  &ts->source_ip.v6);
1329  *tcp = data->tcp_header;
1330  tcp->source_port = htons(ts->destination_port);
1331  tcp->destination_port = htons(ts->source_port);
1332  GNUNET_TUN_calculate_tcp6_checksum(ipv6, tcp, &data[1], mlen);
1333  GNUNET_memcpy(&tcp[1], &data[1], mlen);
1334  (void)GNUNET_HELPER_send(helper_handle, msg, GNUNET_YES, NULL, NULL);
1335  }
1336  }
1337  break;
1338  }
1340  GNUNET_TIME_absolute_get().abs_value_us);
1342 }
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:107
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::@88 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:66
TCP packet header.
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:951
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:653
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:96
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:92
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
union ChannelState::@89 destination_ip
Destination IP address used by the source on our end (this is the IP that we pick freely within the V...
#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 1354 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().

1357 {
1358  struct GNUNET_MQ_MessageHandler cadet_handlers[] =
1359  { GNUNET_MQ_hd_var_size(udp_back,
1362  ts),
1363  GNUNET_MQ_hd_var_size(tcp_back,
1366  ts),
1367  GNUNET_MQ_hd_var_size(icmp_back,
1370  ts),
1372 
1374  ts,
1375  target,
1376  port,
1377  NULL,
1378  &channel_cleaner,
1379  cadet_handlers);
1380 }
#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:173
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:263
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:1065
#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:92
#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 1394 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().

1400 {
1401  struct ChannelState *ts = cls;
1402  struct GNUNET_HashCode port;
1403 
1405  "Exit %s found for destination %s!\n",
1406  GNUNET_i2s(id),
1409  ts->search = NULL;
1410  switch (ts->af)
1411  {
1412  case AF_INET:
1413  /* these must match the strings used in gnunet-daemon-exit */
1416  &port);
1417  break;
1418 
1419  case AF_INET6:
1420  /* these must match the strings used in gnunet-daemon-exit */
1423  &port);
1424  break;
1425 
1426  default:
1427  GNUNET_break(0);
1428  return;
1429  }
1431  "Creating tunnel to %s for destination %s!\n",
1432  GNUNET_i2s(id),
1434  ts->channel = create_channel(ts, id, &port);
1435 }
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:44
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 1446 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().

1447 {
1448  struct ChannelState *ts;
1449 
1451  gettext_noop("# Cadet channels created"),
1452  1,
1453  GNUNET_NO);
1454  ts = GNUNET_new(struct ChannelState);
1455  ts->af = client_af;
1456  ts->destination = *dt->destination;
1457  ts->destination.heap_node = NULL; /* copy is NOT in destination heap */
1459  if (dt->destination->is_service)
1460  {
1461  struct GNUNET_HashCode cadet_port;
1462 
1465  .service_descriptor,
1466  ts->destination_port,
1467  &cadet_port);
1468  ts->channel =
1469  create_channel(ts,
1471  &cadet_port);
1472 
1473  if (NULL == ts->channel)
1474  {
1475  GNUNET_break(0);
1476  GNUNET_free(ts);
1477  return NULL;
1478  }
1480  "Creating channel to peer %s offering service %s on port %u\n",
1481  GNUNET_i2s(
1482  &dt->destination->details.service_destination.target),
1484  .service_descriptor),
1485  (unsigned int)ts->destination_port);
1486  }
1487  else
1488  {
1489  char *policy;
1490 
1491  switch (dt->destination->details.exit_destination.af)
1492  {
1493  case AF_INET: {
1495 
1497  .ip.v4,
1498  dt->destination_port,
1499  address);
1500  GNUNET_asprintf(&policy,
1501  "%s%s",
1503  address);
1504  break;
1505  }
1506 
1507  case AF_INET6: {
1509 
1511  .ip.v6,
1512  dt->destination_port,
1513  address);
1514  GNUNET_asprintf(&policy,
1515  "%s%s",
1517  address);
1518  break;
1519  }
1520 
1521  default:
1522  GNUNET_assert(0);
1523  break;
1524  }
1525 
1527  "Requesting connect by string: %s\n",
1528  policy);
1529  ts->search = GNUNET_REGEX_search(cfg, policy, &handle_regex_result, ts);
1530  GNUNET_free(policy);
1531  }
1532  return ts;
1533 }
struct GNUNET_CONTAINER_HeapNode * heap_node
Entry for this entry in the destination_heap.
struct DestinationEntry::@84::@85 service_destination
struct DestinationEntry::@84::@86 exit_destination
#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.
#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.
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:831
#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).
union DestinationEntry::@84 details
Details about the connection (depending on is_service).
#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 1542 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().

1543 {
1544  struct ChannelState *ts;
1545 
1547  GNUNET_assert(NULL != ts);
1548  if (except == ts)
1549  return; /* can't do this */
1551  "Tearing down expired channel to %s\n",
1553  free_channel_state(ts);
1554 }
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 1569 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().

1576 {
1577  struct GNUNET_HashCode key;
1578  struct ChannelState *ts;
1579  size_t alen;
1580  size_t mlen;
1581  struct GNUNET_MQ_Envelope *env;
1582  const struct GNUNET_TUN_UdpHeader *udp;
1583  const struct GNUNET_TUN_TcpHeader *tcp;
1584  const struct GNUNET_TUN_IcmpHeader *icmp;
1585  struct DestinationChannel *dt;
1586  uint16_t source_port;
1587  uint16_t destination_port;
1588 
1589  switch (protocol)
1590  {
1591  case IPPROTO_UDP: {
1592  if (payload_length < sizeof(struct GNUNET_TUN_UdpHeader))
1593  {
1594  /* blame kernel? */
1595  GNUNET_break(0);
1596  return;
1597  }
1598  tcp = NULL; /* make compiler happy */
1599  icmp = NULL; /* make compiler happy */
1600  udp = payload;
1601  if (udp->len < sizeof(struct GNUNET_TUN_UdpHeader))
1602  {
1603  GNUNET_break_op(0);
1604  return;
1605  }
1606  source_port = ntohs(udp->source_port);
1607  destination_port = ntohs(udp->destination_port);
1609  IPPROTO_UDP,
1610  source_ip,
1611  source_port,
1612  destination_ip,
1613  destination_port,
1614  &key);
1615  }
1616  break;
1617 
1618  case IPPROTO_TCP: {
1619  if (payload_length < sizeof(struct GNUNET_TUN_TcpHeader))
1620  {
1621  /* blame kernel? */
1622  GNUNET_break(0);
1623  return;
1624  }
1625  udp = NULL; /* make compiler happy */
1626  icmp = NULL; /* make compiler happy */
1627  tcp = payload;
1628  if (tcp->off * 4 < sizeof(struct GNUNET_TUN_TcpHeader))
1629  {
1630  GNUNET_break_op(0);
1631  return;
1632  }
1633  source_port = ntohs(tcp->source_port);
1634  destination_port = ntohs(tcp->destination_port);
1636  IPPROTO_TCP,
1637  source_ip,
1638  source_port,
1639  destination_ip,
1640  destination_port,
1641  &key);
1642  }
1643  break;
1644 
1645  case IPPROTO_ICMP:
1646  case IPPROTO_ICMPV6: {
1647  if ((AF_INET == af) ^ (protocol == IPPROTO_ICMP))
1648  {
1649  GNUNET_break(0);
1650  return;
1651  }
1652  if (payload_length < sizeof(struct GNUNET_TUN_IcmpHeader))
1653  {
1654  /* blame kernel? */
1655  GNUNET_break(0);
1656  return;
1657  }
1658  tcp = NULL; /* make compiler happy */
1659  udp = NULL; /* make compiler happy */
1660  icmp = payload;
1661  source_port = 0;
1662  destination_port = 0;
1664  protocol,
1665  source_ip,
1666  0,
1667  destination_ip,
1668  0,
1669  &key);
1670  }
1671  break;
1672 
1673  default:
1675  _("Protocol %u not supported, dropping\n"),
1676  (unsigned int)protocol);
1677  return;
1678  }
1679  alen = 0;
1680  if (!destination->is_service)
1681  {
1682  switch (destination->details.exit_destination.af)
1683  {
1684  case AF_INET:
1685  alen = sizeof(struct in_addr);
1686  break;
1687 
1688  case AF_INET6:
1689  alen = sizeof(struct in6_addr);
1690  break;
1691 
1692  default:
1693  GNUNET_assert(0);
1694  }
1695 
1696  {
1697  char sbuf[INET6_ADDRSTRLEN];
1698  char dbuf[INET6_ADDRSTRLEN];
1699  char xbuf[INET6_ADDRSTRLEN];
1700 
1701  GNUNET_log(
1703  "Routing %s packet from [%s]:%u -> [%s]:%u to destination [%s]:%u\n",
1704  (protocol == IPPROTO_TCP) ? "TCP" : "UDP",
1705  inet_ntop(af, source_ip, sbuf, sizeof(sbuf)),
1706  source_port,
1707  inet_ntop(af, destination_ip, dbuf, sizeof(dbuf)),
1708  destination_port,
1709  inet_ntop(destination->details.exit_destination.af,
1710  &destination->details.exit_destination.ip,
1711  xbuf,
1712  sizeof(xbuf)),
1713  destination_port);
1714  }
1715  for (dt = destination->dt_head; NULL != dt; dt = dt->next)
1716  if (dt->destination_port == destination_port)
1717  break;
1718  }
1719  else
1720  {
1721  {
1722  char sbuf[INET6_ADDRSTRLEN];
1723  char dbuf[INET6_ADDRSTRLEN];
1724 
1725  GNUNET_log(
1727  "Routing %s packet from [%s]:%u -> [%s]:%u to service %s at peer %s\n",
1728  (protocol == IPPROTO_TCP) ? "TCP" : "UDP",
1729  inet_ntop(af, source_ip, sbuf, sizeof(sbuf)),
1730  source_port,
1731  inet_ntop(af, destination_ip, dbuf, sizeof(dbuf)),
1732  destination_port,
1733  GNUNET_h2s(
1734  &destination->details.service_destination.service_descriptor),
1735  GNUNET_i2s(&destination->details.service_destination.target));
1736  }
1737  for (dt = destination->dt_head; NULL != dt; dt = dt->next)
1738  if (dt->destination_port == destination_port)
1739  break;
1740  }
1741  if (NULL == dt)
1742  {
1743  dt = GNUNET_new(struct DestinationChannel);
1744  dt->destination = destination;
1745  GNUNET_CONTAINER_DLL_insert(destination->dt_head,
1746  destination->dt_tail,
1747  dt);
1748  dt->destination_port = destination_port;
1749  }
1750 
1751  /* see if we have an existing channel for this destination */
1753  if (NULL == ts)
1754  {
1756  "Creating new channel for key %s\n",
1757  GNUNET_h2s(&key));
1758  /* need to either use the existing channel from the destination (if still
1759  available) or create a fresh one */
1760  ts = create_channel_to_destination(dt, af);
1761  if (NULL == ts)
1762  return;
1763  /* now bind existing "unbound" channel to our IP/port tuple */
1764  ts->protocol = protocol;
1765  ts->af = af;
1766  if (AF_INET == af)
1767  {
1768  ts->source_ip.v4 = *(const struct in_addr *)source_ip;
1769  ts->destination_ip.v4 = *(const struct in_addr *)destination_ip;
1770  }
1771  else
1772  {
1773  ts->source_ip.v6 = *(const struct in6_addr *)source_ip;
1774  ts->destination_ip.v6 = *(const struct in6_addr *)destination_ip;
1775  }
1776  ts->source_port = source_port;
1777  ts->destination_port = destination_port;
1778  ts->heap_node =
1780  ts,
1781  GNUNET_TIME_absolute_get().abs_value_us);
1784  channel_map,
1785  &key,
1786  ts,
1789  gettext_noop("# Active channels"),
1790  1,
1791  GNUNET_NO);
1794  expire_channel(ts);
1795  }
1796  else
1797  {
1800  .abs_value_us);
1801  }
1802  if (NULL == ts->channel)
1803  {
1805  "Packet dropped, channel to %s not yet ready (%s)\n",
1807  (NULL == ts->search) ? "EXIT search failed"
1808  : "EXIT search active");
1810  gettext_noop(
1811  "# Packets dropped (channel not yet online)"),
1812  1,
1813  GNUNET_NO);
1814  return;
1815  }
1816 
1817  /* send via channel */
1818  switch (protocol)
1819  {
1820  case IPPROTO_UDP:
1821  if (destination->is_service)
1822  {
1823  struct GNUNET_EXIT_UdpServiceMessage *usm;
1824 
1825  mlen = sizeof(struct GNUNET_EXIT_UdpServiceMessage) + payload_length -
1826  sizeof(struct GNUNET_TUN_UdpHeader);
1827  if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1828  {
1829  GNUNET_break(0);
1830  return;
1831  }
1832  env = GNUNET_MQ_msg_extra(usm,
1833  payload_length -
1834  sizeof(struct GNUNET_TUN_UdpHeader),
1836  /* if the source port is below 32000, we assume it has a special
1837  meaning; if not, we pick a random port (this is a heuristic) */
1838  usm->source_port =
1839  (ntohs(udp->source_port) < 32000) ? udp->source_port : 0;
1840  usm->destination_port = udp->destination_port;
1841  GNUNET_memcpy(&usm[1],
1842  &udp[1],
1843  payload_length - sizeof(struct GNUNET_TUN_UdpHeader));
1844  }
1845  else
1846  {
1847  struct GNUNET_EXIT_UdpInternetMessage *uim;
1848  struct in_addr *ip4dst;
1849  struct in6_addr *ip6dst;
1850  void *payload;
1851 
1852  mlen = sizeof(struct GNUNET_EXIT_UdpInternetMessage) + alen +
1853  payload_length - sizeof(struct GNUNET_TUN_UdpHeader);
1854  if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1855  {
1856  GNUNET_break(0);
1857  return;
1858  }
1859  env = GNUNET_MQ_msg_extra(uim,
1860  payload_length + alen -
1861  sizeof(struct GNUNET_TUN_UdpHeader),
1863  uim->af = htonl(destination->details.exit_destination.af);
1864  uim->source_port =
1865  (ntohs(udp->source_port) < 32000) ? udp->source_port : 0;
1866  uim->destination_port = udp->destination_port;
1867  switch (destination->details.exit_destination.af)
1868  {
1869  case AF_INET:
1870  ip4dst = (struct in_addr *)&uim[1];
1871  *ip4dst = destination->details.exit_destination.ip.v4;
1872  payload = &ip4dst[1];
1873  break;
1874 
1875  case AF_INET6:
1876  ip6dst = (struct in6_addr *)&uim[1];
1877  *ip6dst = destination->details.exit_destination.ip.v6;
1878  payload = &ip6dst[1];
1879  break;
1880 
1881  default:
1882  GNUNET_assert(0);
1883  }
1884  GNUNET_memcpy(payload,
1885  &udp[1],
1886  payload_length - sizeof(struct GNUNET_TUN_UdpHeader));
1887  }
1888  break;
1889 
1890  case IPPROTO_TCP:
1891  if (GNUNET_NO == ts->is_established)
1892  {
1893  if (destination->is_service)
1894  {
1896 
1897  mlen = sizeof(struct GNUNET_EXIT_TcpServiceStartMessage) +
1898  payload_length - sizeof(struct GNUNET_TUN_TcpHeader);
1899  if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1900  {
1901  GNUNET_break(0);
1902  return;
1903  }
1904  env =
1905  GNUNET_MQ_msg_extra(tsm,
1906  payload_length -
1907  sizeof(struct GNUNET_TUN_TcpHeader),
1909  tsm->reserved = htonl(0);
1910  tsm->tcp_header = *tcp;
1911  GNUNET_memcpy(&tsm[1],
1912  &tcp[1],
1913  payload_length - sizeof(struct GNUNET_TUN_TcpHeader));
1914  }
1915  else
1916  {
1918  struct in_addr *ip4dst;
1919  struct in6_addr *ip6dst;
1920  void *payload;
1921 
1922  mlen = sizeof(struct GNUNET_EXIT_TcpInternetStartMessage) + alen +
1923  payload_length - sizeof(struct GNUNET_TUN_TcpHeader);
1924  if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1925  {
1926  GNUNET_break(0);
1927  return;
1928  }
1929  env =
1930  GNUNET_MQ_msg_extra(tim,
1931  payload_length + alen -
1932  sizeof(struct GNUNET_TUN_TcpHeader),
1934  tim->af = htonl(destination->details.exit_destination.af);
1935  tim->tcp_header = *tcp;
1936  switch (destination->details.exit_destination.af)
1937  {
1938  case AF_INET:
1939  ip4dst = (struct in_addr *)&tim[1];
1940  *ip4dst = destination->details.exit_destination.ip.v4;
1941  payload = &ip4dst[1];
1942  break;
1943 
1944  case AF_INET6:
1945  ip6dst = (struct in6_addr *)&tim[1];
1946  *ip6dst = destination->details.exit_destination.ip.v6;
1947  payload = &ip6dst[1];
1948  break;
1949 
1950  default:
1951  GNUNET_assert(0);
1952  }
1953  GNUNET_memcpy(payload,
1954  &tcp[1],
1955  payload_length - sizeof(struct GNUNET_TUN_TcpHeader));
1956  }
1957  }
1958  else
1959  {
1960  struct GNUNET_EXIT_TcpDataMessage *tdm;
1961 
1962  mlen = sizeof(struct GNUNET_EXIT_TcpDataMessage) + payload_length -
1963  sizeof(struct GNUNET_TUN_TcpHeader);
1964  if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1965  {
1966  GNUNET_break(0);
1967  return;
1968  }
1969  env = GNUNET_MQ_msg_extra(tdm,
1970  payload_length -
1971  sizeof(struct GNUNET_TUN_TcpHeader),
1973  tdm->reserved = htonl(0);
1974  tdm->tcp_header = *tcp;
1975  GNUNET_memcpy(&tdm[1],
1976  &tcp[1],
1977  payload_length - sizeof(struct GNUNET_TUN_TcpHeader));
1978  }
1979  break;
1980 
1981  case IPPROTO_ICMP:
1982  case IPPROTO_ICMPV6:
1983  if (destination->is_service)
1984  {
1985  struct GNUNET_EXIT_IcmpServiceMessage *ism;
1986 
1987  /* ICMP protocol translation will be done by the receiver (as we don't know
1988  the target AF); however, we still need to possibly discard the payload
1989  depending on the ICMP type */
1990  switch (af)
1991  {
1992  case AF_INET:
1993  switch (icmp->type)
1994  {
1997  break;
1998 
2002  /* throw away ICMP payload, won't be useful for the other side anyway */
2003  payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2004  break;
2005 
2006  default:
2008  gettext_noop(
2009  "# ICMPv4 packets dropped (not allowed)"),
2010  1,
2011  GNUNET_NO);
2012  return;
2013  }
2014  /* end of AF_INET */
2015  break;
2016 
2017  case AF_INET6:
2018  switch (icmp->type)
2019  {
2024  /* throw away ICMP payload, won't be useful for the other side anyway */
2025  payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2026  break;
2027 
2030  break;
2031 
2032  default:
2034  gettext_noop(
2035  "# ICMPv6 packets dropped (not allowed)"),
2036  1,
2037  GNUNET_NO);
2038  return;
2039  }
2040  /* end of AF_INET6 */
2041  break;
2042 
2043  default:
2044  GNUNET_assert(0);
2045  break;
2046  }
2047 
2048  /* update length calculations, as payload_length may have changed */
2049  mlen = sizeof(struct GNUNET_EXIT_IcmpServiceMessage) + alen +
2050  payload_length - sizeof(struct GNUNET_TUN_IcmpHeader);
2051  if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
2052  {
2053  GNUNET_break(0);
2054  return;
2055  }
2056 
2057  env = GNUNET_MQ_msg_extra(ism,
2058  payload_length -
2059  sizeof(struct GNUNET_TUN_IcmpHeader),
2061  ism->af = htonl(af); /* need to tell destination ICMP protocol family! */
2062  ism->icmp_header = *icmp;
2063  GNUNET_memcpy(&ism[1],
2064  &icmp[1],
2065  payload_length - sizeof(struct GNUNET_TUN_IcmpHeader));
2066  }
2067  else
2068  {
2069  struct GNUNET_EXIT_IcmpInternetMessage *iim;
2070  struct in_addr *ip4dst;
2071  struct in6_addr *ip6dst;
2072  void *payload;
2073  uint8_t new_type;
2074 
2075  new_type = icmp->type;
2076  /* Perform ICMP protocol-translation (depending on destination AF and source AF)
2077  and throw away ICMP payload depending on ICMP message type */
2078  switch (af)
2079  {
2080  case AF_INET:
2081  switch (icmp->type)
2082  {
2084  if (destination->details.exit_destination.af == AF_INET6)
2086  break;
2087 
2089  if (destination->details.exit_destination.af == AF_INET6)
2091  break;
2092 
2094  if (destination->details.exit_destination.af == AF_INET6)
2096  /* throw away IP-payload, exit will have to make it up anyway */
2097  payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2098  break;
2099 
2101  if (destination->details.exit_destination.af == AF_INET6)
2103  /* throw away IP-payload, exit will have to make it up anyway */
2104  payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2105  break;
2106 
2108  if (destination->details.exit_destination.af == AF_INET6)
2109  {
2111  stats,
2112  gettext_noop("# ICMPv4 packets dropped (impossible PT to v6)"),
2113  1,
2114  GNUNET_NO);
2115  return;
2116  }
2117  /* throw away IP-payload, exit will have to make it up anyway */
2118  payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2119  break;
2120 
2121  default:
2123  stats,
2124  gettext_noop("# ICMPv4 packets dropped (type not allowed)"),
2125  1,
2126  GNUNET_NO);
2127  return;
2128  }
2129  /* end of AF_INET */
2130  break;
2131 
2132  case AF_INET6:
2133  switch (icmp->type)
2134  {
2136  if (destination->details.exit_destination.af == AF_INET)
2138  /* throw away IP-payload, exit will have to make it up anyway */
2139  payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2140  break;
2141 
2143  if (destination->details.exit_destination.af == AF_INET)
2145  /* throw away IP-payload, exit will have to make it up anyway */
2146  payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2147  break;
2148 
2150  if (destination->details.exit_destination.af == AF_INET)
2151  {
2153  stats,
2154  gettext_noop("# ICMPv6 packets dropped (impossible PT to v4)"),
2155  1,
2156  GNUNET_NO);
2157  return;
2158  }
2159  /* throw away IP-payload, exit will have to make it up anyway */
2160  payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2161  break;
2162 
2164  if (destination->details.exit_destination.af == AF_INET)
2165  {
2167  stats,
2168  gettext_noop("# ICMPv6 packets dropped (impossible PT to v4)"),
2169  1,
2170  GNUNET_NO);
2171  return;
2172  }
2173  /* throw away IP-payload, exit will have to make it up anyway */
2174  payload_length = sizeof(struct GNUNET_TUN_IcmpHeader);
2175  break;
2176 
2178  if (destination->details.exit_destination.af == AF_INET)
2180  break;
2181 
2183  if (destination->details.exit_destination.af == AF_INET)
2184  new_type = GNUNET_TUN_ICMPTYPE_ECHO_REPLY;
2185  break;
2186 
2187  default:
2189  stats,
2190  gettext_noop("# ICMPv6 packets dropped (type not allowed)"),
2191  1,
2192  GNUNET_NO);
2193  return;
2194  }
2195  /* end of AF_INET6 */
2196  break;
2197 
2198  default:
2199  GNUNET_assert(0);
2200  }
2201 
2202  /* update length calculations, as payload_length may have changed */
2203  mlen = sizeof(struct GNUNET_EXIT_IcmpInternetMessage) + alen +
2204  payload_length - sizeof(struct GNUNET_TUN_IcmpHeader);
2205  if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
2206  {
2207  GNUNET_break(0);
2208  return;
2209  }
2210  env = GNUNET_MQ_msg_extra(iim,
2211  alen + payload_length -
2212  sizeof(struct GNUNET_TUN_IcmpHeader),
2214  iim->icmp_header = *icmp;
2215  iim->icmp_header.type = new_type;
2216  iim->af = htonl(destination->details.exit_destination.af);
2217  switch (destination->details.exit_destination.af)
2218  {
2219  case AF_INET:
2220  ip4dst = (struct in_addr *)&iim[1];
2221  *ip4dst = destination->details.exit_destination.ip.v4;
2222  payload = &ip4dst[1];
2223  break;
2224 
2225  case AF_INET6:
2226  ip6dst = (struct in6_addr *)&iim[1];
2227  *ip6dst = destination->details.exit_destination.ip.v6;
2228  payload = &ip6dst[1];
2229  break;
2230 
2231  default:
2232  GNUNET_assert(0);
2233  }
2234  GNUNET_memcpy(payload,
2235  &icmp[1],
2236  payload_length - sizeof(struct GNUNET_TUN_IcmpHeader));
2237  }
2238  break;
2239 
2240  default:
2241  /* not supported above, how can we get here !? */
2242  GNUNET_assert(0);
2243  break;
2244  }
2245  ts->is_established = GNUNET_YES;
2246  send_to_channel(ts, env);
2247 }
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 DestinationEntry::@84::@85 service_destination
struct DestinationChannel * next
Kept in a DLL.
struct DestinationEntry::@84::@86 exit_destination
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:241
#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:71
struct GNUNET_TUN_TcpHeader tcp_header
Skeleton of the TCP header to send.
Definition: exit.h:107
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:52
#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:150
Message send via cadet to an exit daemon to send ICMP data to a local service.
Definition: exit.h:199
#define GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE
#define GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED
#define GNUNET_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:77
#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:160
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:46
Message send via cadet to an exit daemon to forward ICMP data to the Internet.
Definition: exit.h:229
#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.
union ChannelState::@88 source_ip
IP address of the source on our end, initially uninitialized.
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...
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.
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:117
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:62
int32_t af
Address family, AF_INET or AF_INET6, in network byte order.
Definition: exit.h:211
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:155
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:92
uint32_t reserved
Always 0.
Definition: exit.h:101
struct GNUNET_TUN_IcmpHeader icmp_header
ICMP header to use.
Definition: exit.h:216
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
uint16_t source_port
Source port to use for the UDP request (0 to use a random port).
Definition: exit.h:126
struct GNUNET_TUN_IcmpHeader icmp_header
ICMP header to use.
Definition: exit.h:247
union DestinationEntry::@84 details
Details about the connection (depending on is_service).
union ChannelState::@89 destination_ip
Destination IP address used by the source on our end (this is the IP that we pick freely within the V...
Message send via cadet to an exit daemon to forward UDP data to the Internet.
Definition: exit.h:141
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:131
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 2263 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().

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

2379 {
2380  const char *ipv4addr = vpn_argv[4];
2381  const char *ipv4mask = vpn_argv[5];
2382  struct in_addr addr;
2383  struct in_addr mask;
2384  struct in_addr rnd;
2385  struct GNUNET_HashCode key;
2386  unsigned int tries;
2387 
2388  GNUNET_assert(1 == inet_pton(AF_INET, ipv4addr, &addr));
2389  GNUNET_assert(1 == inet_pton(AF_INET, ipv4mask, &mask));
2390  /* Given 192.168.0.1/255.255.0.0, we want a mask
2391  of '192.168.255.255', thus: */
2392  mask.s_addr = addr.s_addr | ~mask.s_addr;
2393  tries = 0;
2394  do
2395  {
2396  tries++;
2397  if (tries > 16)
2398  {
2400  _(
2401  "Failed to find unallocated IPv4 address in VPN's range\n"));
2402  return GNUNET_SYSERR;
2403  }
2404  /* Pick random IPv4 address within the subnet, except 'addr' or 'mask' itself */
2405  rnd.s_addr =
2407  v4->s_addr = (addr.s_addr | rnd.s_addr) & mask.s_addr;
2408  get_destination_key_from_ip(AF_INET, v4, &key);
2409  }
2410  while ((GNUNET_YES ==
2412  (v4->s_addr == addr.s_addr) || (v4->s_addr == mask.s_addr));
2413  return GNUNET_OK;
2414 }
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 2426 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().

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

2480 {
2481  struct DestinationChannel *dt;
2482 
2484  "Cleaning up destination entry `%s'\n",
2487  gettext_noop("# Active destinations"),
2488  -1,
2489  GNUNET_NO);
2490  while (NULL != (dt = de->dt_head))
2491  {
2493  GNUNET_free(dt);
2494  }
2495  if (NULL != de->heap_node)
2496  {
2498  de->heap_node = NULL;
2499  GNUNET_assert(
2500  GNUNET_YES ==
2502  }
2503  GNUNET_free(de);
2504 }
#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 2513 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().

2514 {
2515  struct DestinationEntry *de;
2516 
2518  GNUNET_assert(NULL != de);
2519  if (except == de)
2520  return; /* can't do this */
2522 }
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 2540 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().

2544 {
2545  *addr = NULL;
2546  switch (*result_af)
2547  {
2548  case AF_INET:
2550  *result_af = AF_UNSPEC;
2551  else
2552  *addr = v4;
2553  break;
2554 
2555  case AF_INET6:
2557  *result_af = AF_UNSPEC;
2558  else
2559  *addr = v6;
2560  break;
2561 
2562  case AF_UNSPEC:
2564  {
2565  *addr = v4;
2566  *result_af = AF_INET;
2567  }
2568  else if (GNUNET_OK == allocate_v6_address(v6))
2569  {
2570  *addr = v6;
2571  *result_af = AF_INET6;
2572  }
2573  break;
2574 
2575  default:
2576  GNUNET_break(0);
2577  return GNUNET_SYSERR;
2578  }
2579  return GNUNET_OK;
2580 }
#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 2593 of file gnunet-service-vpn.c.

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

2595 {
2596  size_t alen;
2597  int addr_af;
2598 
2599  alen = ntohs(msg->header.size) - sizeof(struct RedirectToIpRequestMessage);
2600  addr_af = (int)htonl(msg->addr_af);
2601  switch (addr_af)
2602  {
2603  case AF_INET:
2604  if (alen != sizeof(struct in_addr))
2605  {
2606  GNUNET_break(0);
2607  return GNUNET_SYSERR;
2608  }
2609  break;
2610 
2611  case AF_INET6:
2612  if (alen != sizeof(struct in6_addr))
2613  {
2614  GNUNET_break(0);
2615  return GNUNET_SYSERR;
2616  }
2617  break;
2618 
2619  default:
2620  GNUNET_break(0);
2621  return GNUNET_SYSERR;
2622  }
2623  return GNUNET_OK;
2624 }
#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:42
#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:62

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

2638 {
2639  struct GNUNET_SERVICE_Client *client = cls;
2640  size_t alen;
2641  int addr_af;
2642  int result_af;
2643  struct in_addr v4;
2644  struct in6_addr v6;
2645  void *addr;
2646  struct DestinationEntry *de;
2647  struct GNUNET_HashCode key;
2648 
2649  alen = ntohs(msg->header.size) - sizeof(struct RedirectToIpRequestMessage);
2650  addr_af = (int)htonl(msg->addr_af);
2651  /* allocate response IP */
2652  result_af = (int)htonl(msg->result_af);
2653  if (GNUNET_OK != allocate_response_ip(&result_af, &addr, &v4, &v6))
2654  {
2656  return;
2657  }
2658  /* send reply with our IP address */
2659  send_client_reply(client, msg->request_id, result_af, addr);
2660  if (result_af == AF_UNSPEC)
2661  {
2662  /* failure, we're done */
2664  return;
2665  }
2666 
2667  {
2668  char sbuf[INET6_ADDRSTRLEN];
2669  char dbuf[INET6_ADDRSTRLEN];
2670 
2672  "Allocated address %s for redirection via exit to %s\n",
2673  inet_ntop(result_af, addr, sbuf, sizeof(sbuf)),
2674  inet_ntop(addr_af, &msg[1], dbuf, sizeof(dbuf)));
2675  }
2676 
2677  /* setup destination record */
2678  de = GNUNET_new(struct DestinationEntry);
2679  de->is_service = GNUNET_NO;
2680  de->details.exit_destination.af = addr_af;
2681  GNUNET_memcpy(&de->details.exit_destination.ip, &msg[1], alen);
2682  get_destination_key_from_ip(result_af, addr, &key);
2683  de->key = key;
2686  &key,
2687  de,
2690  de,
2692  msg->expiration_time)
2693  .abs_value_us);
2695  gettext_noop("# Active destinations"),
2696  1,
2697  GNUNET_NO);
2700  expire_destination(de);
2702 }
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:671
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.
struct DestinationEntry::@84::@86 exit_destination
#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. ...
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:246
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.
int32_t result_af
Address family desired for the result (AF_INET or AF_INET6 or AF_UNSPEC, in nbo)
Definition: vpn.h:57
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:2315
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:42
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:62
struct GNUNET_TIME_AbsoluteNBO expiration_time
How long should the redirection be maintained at most?
Definition: vpn.h:52
#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:68
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2234
union DestinationEntry::@84 details
Details about the connection (depending on is_service).
#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 2714 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.

2717 {
2718  struct GNUNET_SERVICE_Client *client = cls;
2719  int result_af;
2720  struct in_addr v4;
2721  struct in6_addr v6;
2722  void *addr;
2723  struct DestinationEntry *de;
2724  struct GNUNET_HashCode key;
2725  struct DestinationChannel *dt;
2726 
2727  /* allocate response IP */
2728  result_af = (int)htonl(msg->result_af);
2729  if (GNUNET_OK != allocate_response_ip(&result_af, &addr, &v4, &v6))
2730  {
2731  GNUNET_break(0);
2733  return;
2734  }
2735  send_client_reply(client, msg->request_id, result_af, addr);
2736  if (result_af == AF_UNSPEC)
2737  {
2738  /* failure, we're done */
2740  _("Failed to allocate IP address for new destination\n"));
2742  return;
2743  }
2744 
2745  {
2746  char sbuf[INET6_ADDRSTRLEN];
2747 
2749  "Allocated address %s for redirection to service %s on peer %s\n",
2750  inet_ntop(result_af, addr, sbuf, sizeof(sbuf)),
2752  GNUNET_i2s(&msg->target));
2753  }
2754 
2755  /* setup destination record */
2756  de = GNUNET_new(struct DestinationEntry);
2757  de->is_service = GNUNET_YES;
2758  de->details.service_destination.target = msg->target;
2759  de->details.service_destination.service_descriptor = msg->service_descriptor;
2760  get_destination_key_from_ip(result_af, addr, &key);
2761  de->key = key;
2764  &key,
2765  de,
2768  de,
2770  msg->expiration_time)
2771  .abs_value_us);
2774  expire_destination(de);
2775 
2776  dt = GNUNET_new(struct DestinationChannel);
2777  dt->destination = de;
2779  /* we're done */
2781 }
struct GNUNET_HashCode service_descriptor
Service descriptor identifying the service.
Definition: vpn.h:113
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:671
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:108
struct DestinationEntry::@84::@85 service_destination
#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:103
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:246
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.
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:2315
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:93
uint64_t request_id
Unique ID to match a future response to this request.
Definition: vpn.h:119
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:2234
union DestinationEntry::@84 details
Details about the connection (depending on is_service).
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 2793 of file gnunet-service-vpn.c.

References free_destination_entry(), GNUNET_OK, and value.

Referenced by cleanup().

2794 {
2795  struct DestinationEntry *de = value;
2796 
2798  return GNUNET_OK;
2799 }
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 2811 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().

2812 {
2813  struct ChannelState *ts = value;
2814 
2816  "Tearing down channel to `%s' during cleanup\n",
2818  free_channel_state(ts);
2819  return GNUNET_OK;
2820 }
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 2829 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().

2830 {
2831  unsigned int i;
2832 
2833  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "VPN is shutting down\n");
2834  if (NULL != destination_map)
2835  {
2838  NULL);
2840  destination_map = NULL;
2841  }
2842  if (NULL != destination_heap)
2843  {
2845  destination_heap = NULL;
2846  }
2847  if (NULL != channel_map)
2848  {
2851  channel_map = NULL;
2852  }
2853  if (NULL != channel_heap)
2854  {
2856  channel_heap = NULL;
2857  }
2858  if (NULL != cadet_handle)
2859  {
2861  cadet_handle = NULL;
2862  }
2863  if (NULL != helper_handle)
2864  {
2867  helper_handle = NULL;
2868  }
2869  if (NULL != stats)
2870  {
2872  stats = NULL;
2873  }
2874  for (i = 0; i < 5; i++)
2876 }
int GNUNET_HELPER_kill(struct GNUNET_HELPER_Handle *h, int soft_kill)
Sends termination signal to the helper process.
Definition: helper.c:175
void GNUNET_CADET_disconnect(struct GNUNET_CADET_Handle *handle)
Disconnect from the cadet service.
Definition: cadet_api.c:838
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:223
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 2888 of file gnunet-service-vpn.c.

Referenced by run().

2891 {
2892  return c;
2893 }
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 2904 of file gnunet-service-vpn.c.

References GNUNET_assert.

Referenced by run().

2907 {
2908  GNUNET_assert(c == internal_cls);
2909 }
#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 2920 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.

2923 {
2924  char *ifname;
2925  char *ipv6addr;
2926  char *ipv6prefix_s;
2927  char *ipv4addr;
2928  char *ipv4mask;
2929  struct in_addr v4;
2930  struct in6_addr v6;
2931  char *binary;
2932 
2933  binary = GNUNET_OS_get_libexec_binary_path("gnunet-helper-vpn");
2934 
2935  if (GNUNET_YES !=
2937  binary,
2938  GNUNET_YES,
2939  "-d gnunet-vpn - - 169.1.3.3.7 255.255.255.0")) //ipv4 only please!
2940  {
2942  "`%s' is not SUID, refusing to run.\n",
2943  "gnunet-helper-vpn");
2944  GNUNET_free(binary);
2945  global_ret = 1;
2946  /* we won't "really" exit here, as the 'service' is still running;
2947  however, as no handlers are registered, the service won't do
2948  anything either */
2949  return;
2950  }
2951  GNUNET_free(binary);
2952  cfg = cfg_;
2954  if (GNUNET_OK !=
2956  "VPN",
2957  "MAX_MAPPING",
2960  if (GNUNET_OK !=
2962  "VPN",
2963  "MAX_TUNNELS",
2965  max_channel_mappings = 200;
2966 
2967  destination_map =
2969  GNUNET_NO);
2972  channel_map =
2975 
2976 
2977  vpn_argv[0] = GNUNET_strdup("vpn-gnunet");
2978  if (GNUNET_SYSERR ==
2979  GNUNET_CONFIGURATION_get_value_string(cfg, "VPN", "IFNAME", &ifname))
2980  {
2983  return;
2984  }
2985  vpn_argv[1] = ifname;
2986  ipv6addr = NULL;
2987  if (GNUNET_OK == GNUNET_NETWORK_test_pf(PF_INET6))
2988  {
2990  "VPN",
2991  "IPV6ADDR",
2992  &ipv6addr) ||
2993  (1 != inet_pton(AF_INET6, ipv6addr, &v6))))
2994  {
2996  "VPN",
2997  "IPV6ADDR",
2998  _("Must specify valid IPv6 address"));
3000  GNUNET_free_non_null(ipv6addr);
3001  return;
3002  }
3003  vpn_argv[2] = ipv6addr;
3004  ipv6prefix_s = NULL;
3006  "VPN",
3007  "IPV6PREFIX",
3008  &ipv6prefix_s))
3009  {
3010  GNUNET_log_config_missing(GNUNET_ERROR_TYPE_ERROR, "VPN", "IPV6PREFIX");
3012  GNUNET_free_non_null(ipv6prefix_s);
3013  return;
3014  }
3015  vpn_argv[3] = ipv6prefix_s;
3017  "VPN",
3018  "IPV6PREFIX",
3019  &ipv6prefix)) ||
3020  (ipv6prefix >= 127))
3021  {
3023  "VPN",
3024  "IPV4MASK",
3025  _("Must specify valid IPv6 mask"));
3027  return;
3028  }
3029  }
3030  else
3031  {
3033  _(
3034  "IPv6 support disabled as this system does not support IPv6\n"));
3035  vpn_argv[2] = GNUNET_strdup("-");
3036  vpn_argv[3] = GNUNET_strdup("-");
3037  }
3038  if (GNUNET_OK == GNUNET_NETWORK_test_pf(PF_INET))
3039  {
3040  ipv4addr = NULL;
3042  "vpn",
3043  "IPV4ADDR",
3044  &ipv4addr) ||
3045  (1 != inet_pton(AF_INET, ipv4addr, &v4))))
3046  {
3048  "VPN",
3049  "IPV4ADDR",
3050  _("Must specify valid IPv4 address"));
3052  GNUNET_free_non_null(ipv4addr);
3053  return;
3054  }
3055  vpn_argv[4] = ipv4addr;
3056  ipv4mask = NULL;
3058  "vpn",
3059  "IPV4MASK",
3060  &ipv4mask) ||
3061  (1 != inet_pton(AF_INET, ipv4mask, &v4))))
3062  {
3064  "VPN",
3065  "IPV4MASK",
3066  _("Must specify valid IPv4 mask"));
3068  GNUNET_free_non_null(ipv4mask);
3069  return;
3070  }
3071  vpn_argv[5] = ipv4mask;
3072  }
3073  else
3074  {
3076  _(
3077  "IPv4 support disabled as this system does not support IPv4\n"));
3078  vpn_argv[4] = GNUNET_strdup("-");
3079  vpn_argv[5] = GNUNET_strdup("-");
3080  }
3081  vpn_argv[6] = NULL;
3082 
3084  // FIXME never opens ports???
3086  "gnunet-helper-vpn",
3087  vpn_argv,
3088  &message_token,
3089  NULL,
3090  NULL);
3092 }
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:487
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:1284
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:517
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:973
#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:78
#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 296 of file gnunet-service-vpn.c.

Referenced by run().

◆ cfg

const struct GNUNET_CONFIGURATION_Handle* cfg
static

Configuration we use.

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

◆ cadet_handle

struct GNUNET_CADET_Handle* cadet_handle
static

Handle to the cadet service.

Definition at line 306 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 312 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 317 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 323 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 329 of file gnunet-service-vpn.c.

◆ stats

struct GNUNET_STATISTICS_Handle* stats
static

Statistics.

Definition at line 334 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 339 of file gnunet-service-vpn.c.

◆ vpn_argv

char* vpn_argv[7]
static

Arguments to the vpn helper.

Definition at line 344 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 349 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 355 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 361 of file gnunet-service-vpn.c.

Referenced by route_packet(), and run().