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

399 {
400  switch (af)
401  {
402  case AF_INET:
404  sizeof (struct in_addr),
405  key);
406  break;
407  case AF_INET6:
409  sizeof (struct in6_addr),
410  key);
411  break;
412  default:
413  GNUNET_assert (0);
414  break;
415  }
416 }
#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 432 of file gnunet-service-vpn.c.

References GNUNET_assert, and GNUNET_memcpy.

Referenced by free_channel_state(), and route_packet().

439 {
440  char *off;
441 
442  memset (key, 0, sizeof (struct GNUNET_HashCode));
443  /* the GNUnet hashmap only uses the first sizeof(unsigned int) of the hash,
444  so we put the ports in there (and hope for few collisions) */
445  off = (char*) key;
446  GNUNET_memcpy (off, &source_port, sizeof (uint16_t));
447  off += sizeof (uint16_t);
448  GNUNET_memcpy (off, &destination_port, sizeof (uint16_t));
449  off += sizeof (uint16_t);
450  switch (af)
451  {
452  case AF_INET:
453  GNUNET_memcpy (off, source_ip, sizeof (struct in_addr));
454  off += sizeof (struct in_addr);
455  GNUNET_memcpy (off, destination_ip, sizeof (struct in_addr));
456  off += sizeof (struct in_addr);
457  break;
458  case AF_INET6:
459  GNUNET_memcpy (off, source_ip, sizeof (struct in6_addr));
460  off += sizeof (struct in6_addr);
461  GNUNET_memcpy (off, destination_ip, sizeof (struct in6_addr));
462  off += sizeof (struct in6_addr);
463  break;
464  default:
465  GNUNET_assert (0);
466  break;
467  }
468  GNUNET_memcpy (off, &protocol, sizeof (uint8_t));
469  /* off += sizeof (uint8_t); */
470 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_memcpy(dst, src, n)
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 482 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().

486 {
487  struct GNUNET_MQ_Envelope *env;
489  size_t rlen;
490 
491  switch (result_af)
492  {
493  case AF_INET:
494  rlen = sizeof (struct in_addr);
495  break;
496  case AF_INET6:
497  rlen = sizeof (struct in6_addr);
498  break;
499  case AF_UNSPEC:
500  rlen = 0;
501  break;
502  default:
503  GNUNET_assert (0);
504  return;
505  }
506  env = GNUNET_MQ_msg_extra (res,
507  rlen,
509  res->result_af = htonl (result_af);
510  res->request_id = request_id;
511  GNUNET_memcpy (&res[1],
512  addr,
513  rlen);
515  env);
516 }
Response from the VPN service to a VPN client informing about the IP that was assigned for the reques...
Definition: vpn.h:131
struct GNUNET_MQ_Handle * GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c)
Obtain the message queue of c.
Definition: service.c:2734
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
uint64_t request_id
Unique ID to match the response to a request.
Definition: vpn.h:148
#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.
#define GNUNET_memcpy(dst, src, n)
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:143
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:353
Here is the call graph for this function:
Here is the caller graph for this function:

◆ free_channel_state()

static void free_channel_state ( struct ChannelState ts)
static

Free resources associated with a channel state.

Parameters
tsstate to free

Definition at line 525 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().

526 {
527  struct GNUNET_HashCode key;
528  struct ChannelMessageQueueEntry *tnq;
529  struct GNUNET_CADET_Channel *channel;
530 
532  "Cleaning up channel state\n");
533  if (NULL != (channel = ts->channel))
534  {
535  ts->channel = NULL;
537  return;
538  }
540  gettext_noop ("# Active channels"),
541  -1, GNUNET_NO);
542  while (NULL != (tnq = ts->tmq_head))
543  {
545  ts->tmq_tail,
546  tnq);
547  ts->tmq_length--;
548  GNUNET_free (tnq);
549  }
550  GNUNET_assert (0 == ts->tmq_length);
551  GNUNET_assert (NULL == ts->destination.heap_node);
552  if (NULL != ts->search)
553  {
555  ts->search = NULL;
556  }
557  if (NULL != ts->heap_node)
558  {
560  ts->heap_node = NULL;
562  ts->protocol,
563  &ts->source_ip,
564  ts->source_port,
565  &ts->destination_ip,
566  ts->destination_port,
567  &key);
570  &key,
571  ts));
572  }
573  GNUNET_free (ts);
574 }
#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.
union ChannelState::@114 destination_ip
Destination IP address used by the source on our end (this is the IP that we pick freely within the V...
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.
union ChannelState::@113 source_ip
IP address of the source on our end, initially uninitialized.
uint16_t source_port
Source port used by the sender on our end; 0 for uninitialized.
struct DestinationEntry destination
Destination to which this channel leads.
#define GNUNET_NO
Definition: gnunet_common.h:81
Opaque handle to a channel.
Definition: cadet_api.c:80
struct GNUNET_CONTAINER_HeapNode * heap_node
Heap node for this state in the connections_heap.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
int GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
int af
Addess family used for this channel on the local TUN interface.
void GNUNET_REGEX_search_cancel(struct GNUNET_REGEX_Search *s)
Stop search and free all data used by a GNUNET_REGEX_search call.
A messages we have in queue for a particular channel.
A 512-bit hashcode.
struct GNUNET_CADET_Channel * channel
Cadet channel that is used for this connection.
static void get_channel_key_from_ips(int af, uint8_t protocol, const void *source_ip, uint16_t source_port, const void *destination_ip, uint16_t destination_port, struct GNUNET_HashCode *key)
Compute the key under which we would store an entry in the channel_map for the given socket address p...
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:80
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:911
#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 585 of file gnunet-service-vpn.c.

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

Referenced by route_packet().

587 {
588  struct GNUNET_MQ_Handle *mq;
589 
590  GNUNET_assert (NULL != ts->channel);
591  mq = GNUNET_CADET_get_mq (ts->channel);
592  GNUNET_MQ_send (mq,
593  env);
595  {
596  env = GNUNET_MQ_unsent_head (mq);
597  GNUNET_assert (NULL != env);
599  gettext_noop ("# Messages dropped in cadet queue (overflow)"),
600  1,
601  GNUNET_NO);
602  GNUNET_MQ_discard (env);
603  }
604 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_NO
Definition: gnunet_common.h:81
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
unsigned int GNUNET_MQ_get_length(struct GNUNET_MQ_Handle *mq)
Obtain the current length of the message queue.
Definition: mq.c:335
#define MAX_MESSAGE_QUEUE_SIZE
Maximum number of messages we allow in the queue for cadet.
struct GNUNET_CADET_Channel * channel
Cadet channel that is used for this connection.
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition: mq.c:321
Handle to a message queue.
Definition: mq.c:85
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:353
struct GNUNET_MQ_Envelope * GNUNET_MQ_unsent_head(struct GNUNET_MQ_Handle *mq)
Remove the first envelope that has not yet been sent from the message queue and return it...
Definition: mq.c:394
#define gettext_noop(String)
Definition: gettext.h:69
struct GNUNET_MQ_Handle * GNUNET_CADET_get_mq(const struct GNUNET_CADET_Channel *channel)
Obtain the message queue for a connected peer.
Definition: cadet_api.c:1142
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 614 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().

615 {
616  static char dest[256];
617 
618  if (de->is_service)
619  {
620  GNUNET_snprintf (dest,
621  sizeof (dest),
622  "HS: %s-%s",
623  GNUNET_i2s (&de->details.service_destination.target),
624  GNUNET_h2s (&de->details.service_destination.service_descriptor));
625  }
626  else
627  {
628  inet_ntop (de->details.exit_destination.af,
629  &de->details.exit_destination.ip,
630  dest,
631  sizeof (dest));
632  }
633  return dest;
634 }
int GNUNET_snprintf(char *buf, size_t size, const char *format,...)
Like snprintf, just aborts if the buffer is of insufficient size.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
int is_service
GNUNET_NO if this is a channel to an Internet-exit, GNUNET_YES if this channel is to a service...
union DestinationEntry::@109 details
Details about the connection (depending on is_service).
struct DestinationEntry::@109::@110 service_destination
struct DestinationEntry::@109::@111 exit_destination
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
Here is the call graph for this function:
Here is the caller graph for this function:

◆ channel_cleaner()

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

Function called whenever a channel is destroyed.

Should clean up any associated state.

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

Definition at line 645 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().

647 {
648  struct ChannelState *ts = cls;
649 
650  ts->channel = NULL; /* we must not call GNUNET_CADET_channel_destroy() anymore */
652  "CADET notified us about death of channel to `%s'\n",
654  free_channel_state (ts);
655 }
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 668 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().

671 {
673  ts->protocol,
674  sizeof (struct GNUNET_TUN_TcpHeader),
675  &ts->source_ip.v4,
676  &ts->destination_ip.v4);
677  udp->source_port = htons (ts->source_port);
678  udp->destination_port = htons (ts->destination_port);
679  udp->len = htons (0);
680  udp->crc = htons (0);
681 }
union ChannelState::@114 destination_ip
Destination IP address used by the source on our end (this is the IP that we pick freely within the V...
uint8_t protocol
IPPROTO_TCP or IPPROTO_UDP once bound.
union ChannelState::@113 source_ip
IP address of the source on our end, initially uninitialized.
uint16_t source_port
Source port used by the sender on our end; 0 for uninitialized.
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
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.
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 694 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().

697 {
699  ts->protocol,
700  sizeof (struct GNUNET_TUN_TcpHeader),
701  &ts->source_ip.v6,
702  &ts->destination_ip.v6);
703  udp->source_port = htons (ts->source_port);
704  udp->destination_port = htons (ts->destination_port);
705  udp->len = htons (0);
706  udp->crc = htons (0);
707 }
union ChannelState::@114 destination_ip
Destination IP address used by the source on our end (this is the IP that we pick freely within the V...
uint8_t protocol
IPPROTO_TCP or IPPROTO_UDP once bound.
union ChannelState::@113 source_ip
IP address of the source on our end, initially uninitialized.
uint16_t source_port
Source port used by the sender on our end; 0 for uninitialized.
uint16_t destination_port
Destination port (in NBO).
uint16_t len
Number of bytes of payload.
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
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 719 of file gnunet-service-vpn.c.

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

721 {
722  struct ChannelState *ts = cls;
723 
724  if (NULL == ts->heap_node)
725  {
726  GNUNET_break_op (0);
727  return GNUNET_SYSERR;
728  }
729  if (AF_UNSPEC == ts->af)
730  {
731  GNUNET_break_op (0);
732  return GNUNET_SYSERR;
733  }
734  return GNUNET_OK;
735 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
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:79
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 746 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.

748 {
749  struct ChannelState *ts = cls;
750  size_t mlen;
751 
753  gettext_noop ("# ICMP packets received from cadet"),
754  1,
755  GNUNET_NO);
756  mlen = ntohs (i2v->header.size) - sizeof (struct GNUNET_EXIT_IcmpToVPNMessage);
757  {
758  char sbuf[INET6_ADDRSTRLEN];
759  char dbuf[INET6_ADDRSTRLEN];
760 
762  "Received ICMP packet from cadet, sending %u bytes from %s -> %s via TUN\n",
763  (unsigned int) mlen,
764  inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof (sbuf)),
765  inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof (dbuf)));
766  }
767  switch (ts->af)
768  {
769  case AF_INET:
770  {
771  size_t size = sizeof (struct GNUNET_TUN_IPv4Header)
772  + sizeof (struct GNUNET_TUN_IcmpHeader)
773  + sizeof (struct GNUNET_MessageHeader) +
774  sizeof (struct GNUNET_TUN_Layer2PacketHeader) +
775  mlen;
776  {
777  /* reserve some extra space in case we have an ICMP type here where
778  we will need to make up the payload ourselves */
779  char buf[size + sizeof (struct GNUNET_TUN_IPv4Header) + 8] GNUNET_ALIGN;
780  struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
781  struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1];
782  struct GNUNET_TUN_IPv4Header *ipv4 = (struct GNUNET_TUN_IPv4Header *) &tun[1];
783  struct GNUNET_TUN_IcmpHeader *icmp = (struct GNUNET_TUN_IcmpHeader *) &ipv4[1];
784  msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
785  tun->flags = htons (0);
786  tun->proto = htons (ETH_P_IPV4);
788  IPPROTO_ICMP,
789  sizeof (struct GNUNET_TUN_IcmpHeader) + mlen,
790  &ts->destination_ip.v4,
791  &ts->source_ip.v4);
792  *icmp = i2v->icmp_header;
793  GNUNET_memcpy (&icmp[1],
794  &i2v[1],
795  mlen);
796  /* For some ICMP types, we need to adjust (make up) the payload here.
797  Also, depending on the AF used on the other side, we have to
798  do ICMP PT (translate ICMP types) */
799  switch (ntohl (i2v->af))
800  {
801  case AF_INET:
802  switch (icmp->type)
803  {
806  break;
810  {
811  struct GNUNET_TUN_IPv4Header *ipp = (struct GNUNET_TUN_IPv4Header *) &icmp[1];
812  struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1];
813 
814  if (mlen != 0)
815  {
816  /* sender did not strip ICMP payload? */
817  GNUNET_break_op (0);
818  return;
819  }
820  size += sizeof (struct GNUNET_TUN_IPv4Header) + 8;
821  GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
822  make_up_icmpv4_payload (ts, ipp, udp);
823  }
824  break;
825  default:
826  GNUNET_break_op (0);
828  gettext_noop ("# ICMPv4 packets dropped (type not allowed)"),
829  1, GNUNET_NO);
830  return;
831  }
832  /* end AF_INET */
833  break;
834  case AF_INET6:
835  /* ICMP PT 6-to-4 and possibly making up payloads */
836  switch (icmp->type)
837  {
840  {
841  struct GNUNET_TUN_IPv4Header *ipp = (struct GNUNET_TUN_IPv4Header *) &icmp[1];
842  struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1];
843 
844  if (mlen != 0)
845  {
846  /* sender did not strip ICMP payload? */
847  GNUNET_break_op (0);
848  return;
849  }
850  size += sizeof (struct GNUNET_TUN_IPv4Header) + 8;
851  GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
852  make_up_icmpv4_payload (ts, ipp, udp);
853  }
854  break;
857  {
858  struct GNUNET_TUN_IPv4Header *ipp = (struct GNUNET_TUN_IPv4Header *) &icmp[1];
859  struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1];
860 
861  if (mlen != 0)
862  {
863  /* sender did not strip ICMP payload? */
864  GNUNET_break_op (0);
865  return;
866  }
867  size += sizeof (struct GNUNET_TUN_IPv4Header) + 8;
868  GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
869  make_up_icmpv4_payload (ts, ipp, udp);
870  }
871  break;
875  gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"),
876  1, GNUNET_NO);
877  return;
880  break;
883  break;
884  default:
885  GNUNET_break_op (0);
887  gettext_noop ("# ICMPv6 packets dropped (type not allowed)"),
888  1, GNUNET_NO);
889  return;
890  }
891  /* end AF_INET6 */
892  break;
893  default:
894  GNUNET_break_op (0);
895  return;
896  }
897  msg->size = htons (size);
899  &i2v[1],
900  mlen);
902  msg,
903  GNUNET_YES,
904  NULL, NULL);
905  }
906  }
907  break;
908  case AF_INET6:
909  {
910  size_t size = sizeof (struct GNUNET_TUN_IPv6Header)
911  + sizeof (struct GNUNET_TUN_IcmpHeader)
912  + sizeof (struct GNUNET_MessageHeader) +
913  sizeof (struct GNUNET_TUN_Layer2PacketHeader) +
914  mlen;
915  {
916  char buf[size + sizeof (struct GNUNET_TUN_IPv6Header) + 8] GNUNET_ALIGN;
917  struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
918  struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1];
919  struct GNUNET_TUN_IPv6Header *ipv6 = (struct GNUNET_TUN_IPv6Header *) &tun[1];
920  struct GNUNET_TUN_IcmpHeader *icmp = (struct GNUNET_TUN_IcmpHeader *) &ipv6[1];
921  msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
922  tun->flags = htons (0);
923  tun->proto = htons (ETH_P_IPV6);
925  IPPROTO_ICMPV6,
926  sizeof (struct GNUNET_TUN_IcmpHeader) + mlen,
927  &ts->destination_ip.v6,
928  &ts->source_ip.v6);
929  *icmp = i2v->icmp_header;
930  GNUNET_memcpy (&icmp[1],
931  &i2v[1],
932  mlen);
933 
934  /* For some ICMP types, we need to adjust (make up) the payload here.
935  Also, depending on the AF used on the other side, we have to
936  do ICMP PT (translate ICMP types) */
937  switch (ntohl (i2v->af))
938  {
939  case AF_INET:
940  /* ICMP PT 4-to-6 and possibly making up payloads */
941  switch (icmp->type)
942  {
945  break;
948  break;
951  {
952  struct GNUNET_TUN_IPv6Header *ipp = (struct GNUNET_TUN_IPv6Header *) &icmp[1];
953  struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1];
954 
955  if (mlen != 0)
956  {
957  /* sender did not strip ICMP payload? */
958  GNUNET_break_op (0);
959  return;
960  }
961  size += sizeof (struct GNUNET_TUN_IPv6Header) + 8;
962  GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
963  make_up_icmpv6_payload (ts, ipp, udp);
964  }
965  break;
968  {
969  struct GNUNET_TUN_IPv6Header *ipp = (struct GNUNET_TUN_IPv6Header *) &icmp[1];
970  struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1];
971 
972  if (mlen != 0)
973  {
974  /* sender did not strip ICMP payload? */
975  GNUNET_break_op (0);
976  return;
977  }
978  size += sizeof (struct GNUNET_TUN_IPv6Header) + 8;
979  GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
980  make_up_icmpv6_payload (ts, ipp, udp);
981  }
982  break;
985  gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"),
986  1, GNUNET_NO);
987  return;
988  default:
989  GNUNET_break_op (0);
991  gettext_noop ("# ICMPv4 packets dropped (type not allowed)"),
992  1, GNUNET_NO);
993  return;
994  }
995  /* end AF_INET */
996  break;
997  case AF_INET6:
998  switch (icmp->type)
999  {
1004  {
1005  struct GNUNET_TUN_IPv6Header *ipp = (struct GNUNET_TUN_IPv6Header *) &icmp[1];
1006  struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1];
1007 
1008  if (mlen != 0)
1009  {
1010  /* sender did not strip ICMP payload? */
1011  GNUNET_break_op (0);
1012  return;
1013  }
1014  size += sizeof (struct GNUNET_TUN_IPv6Header) + 8;
1015  GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
1016  make_up_icmpv6_payload (ts, ipp, udp);
1017  }
1018  break;
1020  break;
1021  default:
1022  GNUNET_break_op (0);
1024  gettext_noop ("# ICMPv6 packets dropped (type not allowed)"),
1025  1, GNUNET_NO);
1026  return;
1027  }
1028  /* end AF_INET6 */
1029  break;
1030  default:
1031  GNUNET_break_op (0);
1032  return;
1033  }
1034  msg->size = htons (size);
1036  &i2v[1], mlen);
1038  msg,
1039  GNUNET_YES,
1040  NULL, NULL);
1041  }
1042  }
1043  break;
1044  default:
1045  GNUNET_assert (0);
1046  }
1048  GNUNET_TIME_absolute_get ().abs_value_us);
1050 }
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.
union ChannelState::@114 destination_ip
Destination IP address used by the source on our end (this is the IP that we pick freely within the V...
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.
union ChannelState::@113 source_ip
IP address of the source on our end, initially uninitialized.
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.
struct GNUNET_TUN_IcmpHeader icmp_header
ICMP header to use.
Definition: exit.h:287
#define GNUNET_NO
Definition: gnunet_common.h:81
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_memcpy(dst, src, n)
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG
static char buf[2048]
int af
Addess family used for this channel on the local TUN interface.
int32_t af
Address family, AF_INET or AF_INET6, in network byte order.
Definition: exit.h:282
Header from Linux TUN interface.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
struct GNUNET_CADET_Channel * channel
Cadet channel that is used for this connection.
struct in_addr v4
Address if af is AF_INET.
static unsigned int size
Size of the "table".
Definition: peer.c:67
#define GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE
void GNUNET_TUN_calculate_icmp_checksum(struct GNUNET_TUN_IcmpHeader *icmp, const void *payload, uint16_t payload_length)
Calculate ICMP checksum.
Definition: tun.c:260
Message send via cadet to the vpn service to send ICMP data to the VPN's TUN interface.
Definition: exit.h:271
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:973
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:660
#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:80
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_VPN.
Definition: exit.h:276
#define GNUNET_TUN_ICMPTYPE_ECHO_REPLY
static struct GNUNET_HELPER_Handle * helper_handle
The handle to the VPN helper process "gnunet-helper-vpn".
void GNUNET_TUN_initialize_ipv6_header(struct GNUNET_TUN_IPv6Header *ip, uint8_t protocol, uint16_t payload_length, const struct in6_addr *src, const struct in6_addr *dst)
Initialize an IPv6 header.
Definition: tun.c:81
#define ETH_P_IPV4
Number for IPv4.
#define GNUNET_MESSAGE_TYPE_VPN_HELPER
Type of messages between the gnunet-vpn-helper and the daemon.
struct in6_addr v6
Address if af is AF_INET6.
#define gettext_noop(String)
Definition: gettext.h:69
static int ipv6
Option -6: IPv6 requested.
Definition: gnunet-vpn.c:66
Here is the call graph for this function:

◆ check_udp_back()

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

We got a UDP packet back from the CADET channel.

Check that it is OK.

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

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

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

1064 {
1065  struct ChannelState *ts = cls;
1066 
1067  if (NULL == ts->heap_node)
1068  {
1069  GNUNET_break_op (0);
1070  return GNUNET_SYSERR;
1071  }
1072  if (AF_UNSPEC == ts->af)
1073  {
1074  GNUNET_break_op (0);
1075  return GNUNET_SYSERR;
1076  }
1077  return GNUNET_OK;
1078 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
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:79
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 1089 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.

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

◆ check_tcp_back()

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

We got a TCP packet back from the CADET channel.

Check it is OK.

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

Definition at line 1221 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.

1223 {
1224  struct ChannelState *ts = cls;
1225 
1226  if (NULL == ts->heap_node)
1227  {
1228  GNUNET_break_op (0);
1229  return GNUNET_SYSERR;
1230  }
1231  if (data->tcp_header.off * 4 < sizeof (struct GNUNET_TUN_TcpHeader))
1232  {
1233  GNUNET_break_op (0);
1234  return GNUNET_SYSERR;
1235  }
1236  return GNUNET_OK;
1237 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
struct GNUNET_TUN_TcpHeader tcp_header
Skeleton of the TCP header to send.
Definition: exit.h:110
struct GNUNET_CONTAINER_HeapNode * heap_node
Heap node for this state in the connections_heap.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
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 1248 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.

1250 {
1251  struct ChannelState *ts = cls;
1252  size_t mlen;
1253 
1255  gettext_noop ("# TCP packets received from cadet"),
1256  1,
1257  GNUNET_NO);
1258  mlen = ntohs (data->header.size) - sizeof (struct GNUNET_EXIT_TcpDataMessage);
1259  {
1260  char sbuf[INET6_ADDRSTRLEN];
1261  char dbuf[INET6_ADDRSTRLEN];
1262 
1264  "Received TCP reply from cadet, sending %u bytes from [%s]:%u -> [%s]:%u via TUN\n",
1265  (unsigned int) mlen,
1266  inet_ntop (ts->af, &ts->destination_ip, sbuf, sizeof (sbuf)),
1267  ts->destination_port,
1268  inet_ntop (ts->af, &ts->source_ip, dbuf, sizeof (dbuf)),
1269  ts->source_port);
1270  }
1271  switch (ts->af)
1272  {
1273  case AF_INET:
1274  {
1275  size_t size = sizeof (struct GNUNET_TUN_IPv4Header)
1276  + sizeof (struct GNUNET_TUN_TcpHeader)
1277  + sizeof (struct GNUNET_MessageHeader) +
1278  sizeof (struct GNUNET_TUN_Layer2PacketHeader) +
1279  mlen;
1280  {
1281  char buf[size] GNUNET_ALIGN;
1282  struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
1283  struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1];
1284  struct GNUNET_TUN_IPv4Header *ipv4 = (struct GNUNET_TUN_IPv4Header *) &tun[1];
1285  struct GNUNET_TUN_TcpHeader *tcp = (struct GNUNET_TUN_TcpHeader *) &ipv4[1];
1286  msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1287  msg->size = htons (size);
1288  tun->flags = htons (0);
1289  tun->proto = htons (ETH_P_IPV4);
1291  IPPROTO_TCP,
1292  sizeof (struct GNUNET_TUN_TcpHeader) + 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);
1299  tcp,
1300  &data[1],
1301  mlen);
1302  GNUNET_memcpy (&tcp[1],
1303  &data[1],
1304  mlen);
1306  msg,
1307  GNUNET_YES,
1308  NULL, NULL);
1309  }
1310  }
1311  break;
1312  case AF_INET6:
1313  {
1314  size_t size = sizeof (struct GNUNET_TUN_IPv6Header)
1315  + sizeof (struct GNUNET_TUN_TcpHeader)
1316  + sizeof (struct GNUNET_MessageHeader) +
1317  sizeof (struct GNUNET_TUN_Layer2PacketHeader) +
1318  mlen;
1319  {
1320  char buf[size] GNUNET_ALIGN;
1321  struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
1322  struct GNUNET_TUN_Layer2PacketHeader *tun = (struct GNUNET_TUN_Layer2PacketHeader*) &msg[1];
1323  struct GNUNET_TUN_IPv6Header *ipv6 = (struct GNUNET_TUN_IPv6Header *) &tun[1];
1324  struct GNUNET_TUN_TcpHeader *tcp = (struct GNUNET_TUN_TcpHeader *) &ipv6[1];
1325  msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1326  msg->size = htons (size);
1327  tun->flags = htons (0);
1328  tun->proto = htons (ETH_P_IPV6);
1330  IPPROTO_TCP,
1331  sizeof (struct GNUNET_TUN_TcpHeader) + mlen,
1332  &ts->destination_ip.v6,
1333  &ts->source_ip.v6);
1334  *tcp = data->tcp_header;
1335  tcp->source_port = htons (ts->destination_port);
1336  tcp->destination_port = htons (ts->source_port);
1338  tcp,
1339  &data[1],
1340  mlen);
1341  GNUNET_memcpy (&tcp[1],
1342  &data[1],
1343  mlen);
1345  msg,
1346  GNUNET_YES,
1347  NULL, NULL);
1348  }
1349  }
1350  break;
1351  }
1353  GNUNET_TIME_absolute_get ().abs_value_us);
1355 }
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.
union ChannelState::@114 destination_ip
Destination IP address used by the source on our end (this is the IP that we pick freely within the V...
static int ipv4
Option -4: IPv4 requested.
Definition: gnunet-vpn.c:61
union ChannelState::@113 source_ip
IP address of the source on our end, initially uninitialized.
uint16_t source_port
Source port used by the sender on our end; 0 for uninitialized.
#define ETH_P_IPV6
Number for IPv6.
#define GNUNET_NO
Definition: gnunet_common.h:81
Standard IPv4 header.
uint16_t flags
Some flags (unused).
struct GNUNET_TUN_TcpHeader tcp_header
Skeleton of the TCP header to send.
Definition: exit.h:110
struct GNUNET_CONTAINER_HeapNode * heap_node
Heap node for this state in the connections_heap.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
void GNUNET_TUN_calculate_tcp6_checksum(const struct GNUNET_TUN_IPv6Header *ip, struct GNUNET_TUN_TcpHeader *tcp, const void *payload, uint16_t payload_length)
Calculate IPv6 TCP checksum.
Definition: tun.c:147
void GNUNET_TUN_initialize_ipv4_header(struct GNUNET_TUN_IPv4Header *ip, uint8_t protocol, uint16_t payload_length, const struct in_addr *src, const struct in_addr *dst)
Initialize an IPv4 header.
Definition: tun.c:46
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_memcpy(dst, src, n)
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.
struct in_addr v4
Address if af is AF_INET.
static unsigned int size
Size of the "table".
Definition: peer.c:67
TCP packet header.
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:973
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:660
uint16_t destination_port
Destination port used by the sender on our end; 0 for uninitialized.
#define GNUNET_log(kind,...)
struct GNUNET_MessageHeader header
Type is #GNUNET_MESSAGE_TYPE_VPN_TCP_DATA.
Definition: exit.h:99
Header for all communications.
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
#define GNUNET_YES
Definition: gnunet_common.h:80
Message send via cadet between VPN and entry and an exit daemon to transmit TCP data between the VPN ...
Definition: exit.h:94
static struct GNUNET_HELPER_Handle * helper_handle
The handle to the VPN helper process "gnunet-helper-vpn".
void GNUNET_TUN_initialize_ipv6_header(struct GNUNET_TUN_IPv6Header *ip, uint8_t protocol, uint16_t payload_length, const struct in6_addr *src, const struct in6_addr *dst)
Initialize an IPv6 header.
Definition: tun.c:81
#define ETH_P_IPV4
Number for IPv4.
#define GNUNET_MESSAGE_TYPE_VPN_HELPER
Type of messages between the gnunet-vpn-helper and the daemon.
struct in6_addr v6
Address if af is AF_INET6.
#define gettext_noop(String)
Definition: gettext.h:69
static int ipv6
Option -6: IPv6 requested.
Definition: gnunet-vpn.c:66
Here is the call graph for this function:

◆ create_channel()

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

Create a channel for ts to target at port.

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

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

References channel_cleaner(), GNUNET_CADET_channel_create(), GNUNET_CADET_OPTION_DEFAULT, 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().

1370 {
1371  struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
1372  GNUNET_MQ_hd_var_size (udp_back,
1375  ts),
1376  GNUNET_MQ_hd_var_size (tcp_back,
1379  ts),
1380  GNUNET_MQ_hd_var_size (icmp_back,
1383  ts),
1385  };
1386 
1388  ts,
1389  target,
1390  port,
1392  NULL,
1393  &channel_cleaner,
1394  cadet_handlers);
1395 }
#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.
Default options: unreliable, default buffering, not out of order.
static struct GNUNET_CADET_Handle * cadet_handle
Handle to the cadet service.
Message send from exit daemon back to the UDP entry point (used for both Internet and Service exit re...
Definition: exit.h:178
Message handler for a specific message type.
Message send via cadet to the vpn service to send ICMP data to the VPN&#39;s TUN interface.
Definition: exit.h:271
#define GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_VPN
Type of messages containing an ICMP packet for the VPN.
static void channel_cleaner(void *cls, const struct GNUNET_CADET_Channel *channel)
Function called whenever a channel is destroyed.
Message send via cadet between VPN and entry and an exit daemon to transmit TCP data between the VPN ...
Definition: exit.h:94
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
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, enum GNUNET_CADET_ChannelOption options, 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:1088
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 1409 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().

1415 {
1416  struct ChannelState *ts = cls;
1417  struct GNUNET_HashCode port;
1418 
1420  "Exit %s found for destination %s!\n",
1421  GNUNET_i2s (id),
1424  ts->search = NULL;
1425  switch (ts->af)
1426  {
1427  case AF_INET:
1428  /* these must match the strings used in gnunet-daemon-exit */
1431  &port);
1432  break;
1433  case AF_INET6:
1434  /* these must match the strings used in gnunet-daemon-exit */
1437  &port);
1438  break;
1439  default:
1440  GNUNET_break (0);
1441  return;
1442  }
1444  "Creating tunnel to %s for destination %s!\n",
1445  GNUNET_i2s (id),
1447  ts->channel = create_channel (ts,
1448  id,
1449  &port);
1450 }
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:79
#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 1461 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().

1463 {
1464  struct ChannelState *ts;
1465 
1467  gettext_noop ("# Cadet channels created"),
1468  1,
1469  GNUNET_NO);
1470  ts = GNUNET_new (struct ChannelState);
1471  ts->af = client_af;
1472  ts->destination = *dt->destination;
1473  ts->destination.heap_node = NULL; /* copy is NOT in destination heap */
1475  if (dt->destination->is_service)
1476  {
1477  struct GNUNET_HashCode cadet_port;
1478 
1480  ts->destination_port,
1481  &cadet_port);
1482  ts->channel = create_channel (ts,
1484  &cadet_port);
1485 
1486  if (NULL == ts->channel)
1487  {
1488  GNUNET_break (0);
1489  GNUNET_free (ts);
1490  return NULL;
1491  }
1493  "Creating channel to peer %s offering service %s on port %u\n",
1495  GNUNET_h2s (&ts->destination.details.service_destination.service_descriptor),
1496  (unsigned int) ts->destination_port);
1497  }
1498  else
1499  {
1500  char *policy;
1501 
1502  switch (dt->destination->details.exit_destination.af)
1503  {
1504  case AF_INET:
1505  {
1507 
1509  dt->destination_port,
1510  address);
1511  GNUNET_asprintf (&policy,
1512  "%s%s",
1514  address);
1515  break;
1516  }
1517  case AF_INET6:
1518  {
1520 
1522  dt->destination_port,
1523  address);
1524  GNUNET_asprintf (&policy,
1525  "%s%s",
1527  address);
1528  break;
1529  }
1530  default:
1531  GNUNET_assert (0);
1532  break;
1533  }
1534 
1536  "Requesting connect by string: %s\n",
1537  policy);
1539  policy,
1541  ts);
1542  GNUNET_free (policy);
1543  }
1544  return ts;
1545 }
struct GNUNET_CONTAINER_HeapNode * heap_node
Entry for this entry in the destination_heap.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
void GNUNET_TUN_ipv4toregexsearch(const struct in_addr *ip, uint16_t port, char *rxstr)
Create a regex in rxstr from the given ip and port.
Definition: regex.c:45
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we use.
static void handle_regex_result(void *cls, const struct GNUNET_PeerIdentity *id, const struct GNUNET_PeerIdentity *get_path, unsigned int get_path_length, const struct GNUNET_PeerIdentity *put_path, unsigned int put_path_length)
Regex has found a potential exit peer for us; consider using it.
struct DestinationEntry destination
Destination to which this channel leads.
#define GNUNET_NO
Definition: gnunet_common.h:81
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.
union DestinationEntry::@109 details
Details about the connection (depending on is_service).
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:823
struct DestinationEntry::@109::@110 service_destination
#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.
struct DestinationEntry::@109::@111 exit_destination
This struct is saved into connections_map to allow finding the right channel given an IP packet from ...
static struct GNUNET_CADET_Channel * create_channel(struct ChannelState *ts, const struct GNUNET_PeerIdentity *target, const struct GNUNET_HashCode *port)
Create a channel for ts to target at port.
static char * address
GNS address for this phone.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_TUN_IPV6_REGEXLEN
Maximum regex string length for use with GNUNET_TUN_ipv6toregexsearch.
#define GNUNET_free(ptr)
Wrapper around free.
#define gettext_noop(String)
Definition: gettext.h:69
Here is the call graph for this function:
Here is the caller graph for this function:

◆ expire_channel()

static void expire_channel ( struct ChannelState except)
static

We have too many active channels.

Clean up the oldest channel.

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

Definition at line 1554 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().

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

References _, GNUNET_EXIT_TcpInternetStartMessage::af, GNUNET_EXIT_UdpInternetMessage::af, GNUNET_EXIT_IcmpServiceMessage::af, GNUNET_EXIT_IcmpInternetMessage::af, ChannelState::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().

1588 {
1589  struct GNUNET_HashCode key;
1590  struct ChannelState *ts;
1591  size_t alen;
1592  size_t mlen;
1593  struct GNUNET_MQ_Envelope *env;
1594  const struct GNUNET_TUN_UdpHeader *udp;
1595  const struct GNUNET_TUN_TcpHeader *tcp;
1596  const struct GNUNET_TUN_IcmpHeader *icmp;
1597  struct DestinationChannel *dt;
1598  uint16_t source_port;
1599  uint16_t destination_port;
1600 
1601  switch (protocol)
1602  {
1603  case IPPROTO_UDP:
1604  {
1605  if (payload_length < sizeof (struct GNUNET_TUN_UdpHeader))
1606  {
1607  /* blame kernel? */
1608  GNUNET_break (0);
1609  return;
1610  }
1611  tcp = NULL; /* make compiler happy */
1612  icmp = NULL; /* make compiler happy */
1613  udp = payload;
1614  if (udp->len < sizeof (struct GNUNET_TUN_UdpHeader))
1615  {
1616  GNUNET_break_op (0);
1617  return;
1618  }
1619  source_port = ntohs (udp->source_port);
1620  destination_port = ntohs (udp->destination_port);
1622  IPPROTO_UDP,
1623  source_ip,
1624  source_port,
1625  destination_ip,
1626  destination_port,
1627  &key);
1628  }
1629  break;
1630  case IPPROTO_TCP:
1631  {
1632  if (payload_length < sizeof (struct GNUNET_TUN_TcpHeader))
1633  {
1634  /* blame kernel? */
1635  GNUNET_break (0);
1636  return;
1637  }
1638  udp = NULL; /* make compiler happy */
1639  icmp = NULL; /* make compiler happy */
1640  tcp = payload;
1641  if (tcp->off * 4 < sizeof (struct GNUNET_TUN_TcpHeader))
1642  {
1643  GNUNET_break_op (0);
1644  return;
1645  }
1646  source_port = ntohs (tcp->source_port);
1647  destination_port = ntohs (tcp->destination_port);
1649  IPPROTO_TCP,
1650  source_ip,
1651  source_port,
1652  destination_ip,
1653  destination_port,
1654  &key);
1655  }
1656  break;
1657  case IPPROTO_ICMP:
1658  case IPPROTO_ICMPV6:
1659  {
1660  if ( (AF_INET == af) ^ (protocol == IPPROTO_ICMP) )
1661  {
1662  GNUNET_break (0);
1663  return;
1664  }
1665  if (payload_length < sizeof (struct GNUNET_TUN_IcmpHeader))
1666  {
1667  /* blame kernel? */
1668  GNUNET_break (0);
1669  return;
1670  }
1671  tcp = NULL; /* make compiler happy */
1672  udp = NULL; /* make compiler happy */
1673  icmp = payload;
1674  source_port = 0;
1675  destination_port = 0;
1677  protocol,
1678  source_ip,
1679  0,
1680  destination_ip,
1681  0,
1682  &key);
1683  }
1684  break;
1685  default:
1687  _("Protocol %u not supported, dropping\n"),
1688  (unsigned int) protocol);
1689  return;
1690  }
1691  alen = 0;
1692  if (! destination->is_service)
1693  {
1694  switch (destination->details.exit_destination.af)
1695  {
1696  case AF_INET:
1697  alen = sizeof (struct in_addr);
1698  break;
1699  case AF_INET6:
1700  alen = sizeof (struct in6_addr);
1701  break;
1702  default:
1703  GNUNET_assert (0);
1704  }
1705 
1706  {
1707  char sbuf[INET6_ADDRSTRLEN];
1708  char dbuf[INET6_ADDRSTRLEN];
1709  char xbuf[INET6_ADDRSTRLEN];
1710 
1712  "Routing %s packet from [%s]:%u -> [%s]:%u to destination [%s]:%u\n",
1713  (protocol == IPPROTO_TCP) ? "TCP" : "UDP",
1714  inet_ntop (af,
1715  source_ip,
1716  sbuf,
1717  sizeof (sbuf)),
1718  source_port,
1719  inet_ntop (af,
1720  destination_ip,
1721  dbuf,
1722  sizeof (dbuf)),
1723  destination_port,
1724  inet_ntop (destination->details.exit_destination.af,
1725  &destination->details.exit_destination.ip,
1726  xbuf, sizeof (xbuf)),
1727  destination_port);
1728  }
1729  for (dt = destination->dt_head; NULL != dt; dt = dt->next)
1730  if (dt->destination_port == destination_port)
1731  break;
1732  }
1733  else
1734  {
1735  {
1736  char sbuf[INET6_ADDRSTRLEN];
1737  char dbuf[INET6_ADDRSTRLEN];
1738 
1740  "Routing %s packet from [%s]:%u -> [%s]:%u to service %s at peer %s\n",
1741  (protocol == IPPROTO_TCP) ? "TCP" : "UDP",
1742  inet_ntop (af,
1743  source_ip,
1744  sbuf,
1745  sizeof (sbuf)),
1746  source_port,
1747  inet_ntop (af,
1748  destination_ip,
1749  dbuf,
1750  sizeof (dbuf)),
1751  destination_port,
1752  GNUNET_h2s (&destination->details.service_destination.service_descriptor),
1753  GNUNET_i2s (&destination->details.service_destination.target));
1754  }
1755  for (dt = destination->dt_head; NULL != dt; dt = dt->next)
1756  if (dt->destination_port == destination_port)
1757  break;
1758  }
1759  if (NULL == dt)
1760  {
1761  dt = GNUNET_new (struct DestinationChannel);
1762  dt->destination = destination;
1763  GNUNET_CONTAINER_DLL_insert (destination->dt_head,
1764  destination->dt_tail,
1765  dt);
1766  dt->destination_port = destination_port;
1767  }
1768 
1769  /* see if we have an existing channel for this destination */
1771  &key);
1772  if (NULL == ts)
1773  {
1775  "Creating new channel for key %s\n",
1776  GNUNET_h2s (&key));
1777  /* need to either use the existing channel from the destination (if still
1778  available) or create a fresh one */
1780  af);
1781  if (NULL == ts)
1782  return;
1783  /* now bind existing "unbound" channel to our IP/port tuple */
1784  ts->protocol = protocol;
1785  ts->af = af;
1786  if (AF_INET == af)
1787  {
1788  ts->source_ip.v4 = * (const struct in_addr *) source_ip;
1789  ts->destination_ip.v4 = * (const struct in_addr *) destination_ip;
1790  }
1791  else
1792  {
1793  ts->source_ip.v6 = * (const struct in6_addr *) source_ip;
1794  ts->destination_ip.v6 = * (const struct in6_addr *) destination_ip;
1795  }
1796  ts->source_port = source_port;
1797  ts->destination_port = destination_port;
1799  ts,
1800  GNUNET_TIME_absolute_get ().abs_value_us);
1803  &key,
1804  ts,
1807  gettext_noop ("# Active channels"),
1808  1, GNUNET_NO);
1810  expire_channel (ts);
1811  }
1812  else
1813  {
1815  GNUNET_TIME_absolute_get ().abs_value_us);
1816  }
1817  if (NULL == ts->channel)
1818  {
1820  "Packet dropped, channel to %s not yet ready (%s)\n",
1822  (NULL == ts->search)
1823  ? "EXIT search failed"
1824  : "EXIT search active");
1826  gettext_noop ("# Packets dropped (channel not yet online)"),
1827  1,
1828  GNUNET_NO);
1829  return;
1830  }
1831 
1832  /* send via channel */
1833  switch (protocol)
1834  {
1835  case IPPROTO_UDP:
1836  if (destination->is_service)
1837  {
1838  struct GNUNET_EXIT_UdpServiceMessage *usm;
1839 
1840  mlen = sizeof (struct GNUNET_EXIT_UdpServiceMessage) +
1841  payload_length - sizeof (struct GNUNET_TUN_UdpHeader);
1842  if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1843  {
1844  GNUNET_break (0);
1845  return;
1846  }
1847  env = GNUNET_MQ_msg_extra (usm,
1848  payload_length - sizeof (struct GNUNET_TUN_UdpHeader),
1850  /* if the source port is below 32000, we assume it has a special
1851  meaning; if not, we pick a random port (this is a heuristic) */
1852  usm->source_port = (ntohs (udp->source_port) < 32000) ? udp->source_port : 0;
1853  usm->destination_port = udp->destination_port;
1854  GNUNET_memcpy (&usm[1],
1855  &udp[1],
1856  payload_length - sizeof (struct GNUNET_TUN_UdpHeader));
1857  }
1858  else
1859  {
1860  struct GNUNET_EXIT_UdpInternetMessage *uim;
1861  struct in_addr *ip4dst;
1862  struct in6_addr *ip6dst;
1863  void *payload;
1864 
1865  mlen = sizeof (struct GNUNET_EXIT_UdpInternetMessage) +
1866  alen + payload_length - sizeof (struct GNUNET_TUN_UdpHeader);
1867  if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1868  {
1869  GNUNET_break (0);
1870  return;
1871  }
1872  env = GNUNET_MQ_msg_extra (uim,
1873  payload_length + alen - sizeof (struct GNUNET_TUN_UdpHeader),
1875  uim->af = htonl (destination->details.exit_destination.af);
1876  uim->source_port = (ntohs (udp->source_port) < 32000) ? udp->source_port : 0;
1877  uim->destination_port = udp->destination_port;
1878  switch (destination->details.exit_destination.af)
1879  {
1880  case AF_INET:
1881  ip4dst = (struct in_addr *) &uim[1];
1882  *ip4dst = destination->details.exit_destination.ip.v4;
1883  payload = &ip4dst[1];
1884  break;
1885  case AF_INET6:
1886  ip6dst = (struct in6_addr *) &uim[1];
1887  *ip6dst = destination->details.exit_destination.ip.v6;
1888  payload = &ip6dst[1];
1889  break;
1890  default:
1891  GNUNET_assert (0);
1892  }
1893  GNUNET_memcpy (payload,
1894  &udp[1],
1895  payload_length - sizeof (struct GNUNET_TUN_UdpHeader));
1896  }
1897  break;
1898  case IPPROTO_TCP:
1899  if (GNUNET_NO == ts->is_established)
1900  {
1901  if (destination->is_service)
1902  {
1904 
1905  mlen = sizeof (struct GNUNET_EXIT_TcpServiceStartMessage) +
1906  payload_length - sizeof (struct GNUNET_TUN_TcpHeader);
1907  if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1908  {
1909  GNUNET_break (0);
1910  return;
1911  }
1912  env = GNUNET_MQ_msg_extra (tsm,
1913  payload_length - sizeof (struct GNUNET_TUN_TcpHeader),
1915  tsm->reserved = htonl (0);
1916  tsm->tcp_header = *tcp;
1917  GNUNET_memcpy (&tsm[1],
1918  &tcp[1],
1919  payload_length - sizeof (struct GNUNET_TUN_TcpHeader));
1920  }
1921  else
1922  {
1924  struct in_addr *ip4dst;
1925  struct in6_addr *ip6dst;
1926  void *payload;
1927 
1928  mlen = sizeof (struct GNUNET_EXIT_TcpInternetStartMessage) +
1929  alen + payload_length - sizeof (struct GNUNET_TUN_TcpHeader);
1930  if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1931  {
1932  GNUNET_break (0);
1933  return;
1934  }
1935  env = GNUNET_MQ_msg_extra (tim,
1936  payload_length + alen - sizeof (struct GNUNET_TUN_TcpHeader),
1938  tim->af = htonl (destination->details.exit_destination.af);
1939  tim->tcp_header = *tcp;
1940  switch (destination->details.exit_destination.af)
1941  {
1942  case AF_INET:
1943  ip4dst = (struct in_addr *) &tim[1];
1944  *ip4dst = destination->details.exit_destination.ip.v4;
1945  payload = &ip4dst[1];
1946  break;
1947  case AF_INET6:
1948  ip6dst = (struct in6_addr *) &tim[1];
1949  *ip6dst = destination->details.exit_destination.ip.v6;
1950  payload = &ip6dst[1];
1951  break;
1952  default:
1953  GNUNET_assert (0);
1954  }
1955  GNUNET_memcpy (payload,
1956  &tcp[1],
1957  payload_length - sizeof (struct GNUNET_TUN_TcpHeader));
1958  }
1959  }
1960  else
1961  {
1962  struct GNUNET_EXIT_TcpDataMessage *tdm;
1963 
1964  mlen = sizeof (struct GNUNET_EXIT_TcpDataMessage) +
1965  payload_length - sizeof (struct GNUNET_TUN_TcpHeader);
1966  if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
1967  {
1968  GNUNET_break (0);
1969  return;
1970  }
1971  env = GNUNET_MQ_msg_extra (tdm,
1972  payload_length - sizeof (struct GNUNET_TUN_TcpHeader),
1974  tdm->reserved = htonl (0);
1975  tdm->tcp_header = *tcp;
1976  GNUNET_memcpy (&tdm[1],
1977  &tcp[1],
1978  payload_length - sizeof (struct GNUNET_TUN_TcpHeader));
1979  }
1980  break;
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;
2001  /* throw away ICMP payload, won't be useful for the other side anyway */
2002  payload_length = sizeof (struct GNUNET_TUN_IcmpHeader);
2003  break;
2004  default:
2006  gettext_noop ("# ICMPv4 packets dropped (not allowed)"),
2007  1, GNUNET_NO);
2008  return;
2009  }
2010  /* end of AF_INET */
2011  break;
2012  case AF_INET6:
2013  switch (icmp->type)
2014  {
2019  /* throw away ICMP payload, won't be useful for the other side anyway */
2020  payload_length = sizeof (struct GNUNET_TUN_IcmpHeader);
2021  break;
2024  break;
2025  default:
2027  gettext_noop ("# ICMPv6 packets dropped (not allowed)"),
2028  1, GNUNET_NO);
2029  return;
2030  }
2031  /* end of AF_INET6 */
2032  break;
2033  default:
2034  GNUNET_assert (0);
2035  break;
2036  }
2037 
2038  /* update length calculations, as payload_length may have changed */
2039  mlen = sizeof (struct GNUNET_EXIT_IcmpServiceMessage) +
2040  alen + payload_length - sizeof (struct GNUNET_TUN_IcmpHeader);
2041  if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
2042  {
2043  GNUNET_break (0);
2044  return;
2045  }
2046 
2047  env = GNUNET_MQ_msg_extra (ism,
2048  payload_length - sizeof (struct GNUNET_TUN_IcmpHeader),
2050  ism->af = htonl (af); /* need to tell destination ICMP protocol family! */
2051  ism->icmp_header = *icmp;
2052  GNUNET_memcpy (&ism[1],
2053  &icmp[1],
2054  payload_length - sizeof (struct GNUNET_TUN_IcmpHeader));
2055  }
2056  else
2057  {
2058  struct GNUNET_EXIT_IcmpInternetMessage *iim;
2059  struct in_addr *ip4dst;
2060  struct in6_addr *ip6dst;
2061  void *payload;
2062  uint8_t new_type;
2063 
2064  new_type = icmp->type;
2065  /* Perform ICMP protocol-translation (depending on destination AF and source AF)
2066  and throw away ICMP payload depending on ICMP message type */
2067  switch (af)
2068  {
2069  case AF_INET:
2070  switch (icmp->type)
2071  {
2073  if (destination->details.exit_destination.af == AF_INET6)
2075  break;
2077  if (destination->details.exit_destination.af == AF_INET6)
2079  break;
2081  if (destination->details.exit_destination.af == AF_INET6)
2083  /* throw away IP-payload, exit will have to make it up anyway */
2084  payload_length = sizeof (struct GNUNET_TUN_IcmpHeader);
2085  break;
2087  if (destination->details.exit_destination.af == AF_INET6)
2089  /* throw away IP-payload, exit will have to make it up anyway */
2090  payload_length = sizeof (struct GNUNET_TUN_IcmpHeader);
2091  break;
2093  if (destination->details.exit_destination.af == AF_INET6)
2094  {
2096  gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"),
2097  1, GNUNET_NO);
2098  return;
2099  }
2100  /* throw away IP-payload, exit will have to make it up anyway */
2101  payload_length = sizeof (struct GNUNET_TUN_IcmpHeader);
2102  break;
2103  default:
2105  gettext_noop ("# ICMPv4 packets dropped (type not allowed)"),
2106  1, GNUNET_NO);
2107  return;
2108  }
2109  /* end of AF_INET */
2110  break;
2111  case AF_INET6:
2112  switch (icmp->type)
2113  {
2115  if (destination->details.exit_destination.af == AF_INET)
2117  /* throw away IP-payload, exit will have to make it up anyway */
2118  payload_length = sizeof (struct GNUNET_TUN_IcmpHeader);
2119  break;
2121  if (destination->details.exit_destination.af == AF_INET)
2123  /* throw away IP-payload, exit will have to make it up anyway */
2124  payload_length = sizeof (struct GNUNET_TUN_IcmpHeader);
2125  break;
2127  if (destination->details.exit_destination.af == AF_INET)
2128  {
2130  gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"),
2131  1, GNUNET_NO);
2132  return;
2133  }
2134  /* throw away IP-payload, exit will have to make it up anyway */
2135  payload_length = sizeof (struct GNUNET_TUN_IcmpHeader);
2136  break;
2138  if (destination->details.exit_destination.af == AF_INET)
2139  {
2141  gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"),
2142  1, GNUNET_NO);
2143  return;
2144  }
2145  /* throw away IP-payload, exit will have to make it up anyway */
2146  payload_length = sizeof (struct GNUNET_TUN_IcmpHeader);
2147  break;
2149  if (destination->details.exit_destination.af == AF_INET)
2151  break;
2153  if (destination->details.exit_destination.af == AF_INET)
2154  new_type = GNUNET_TUN_ICMPTYPE_ECHO_REPLY;
2155  break;
2156  default:
2158  gettext_noop ("# ICMPv6 packets dropped (type not allowed)"),
2159  1, GNUNET_NO);
2160  return;
2161  }
2162  /* end of AF_INET6 */
2163  break;
2164  default:
2165  GNUNET_assert (0);
2166  }
2167 
2168  /* update length calculations, as payload_length may have changed */
2169  mlen = sizeof (struct GNUNET_EXIT_IcmpInternetMessage) +
2170  alen + payload_length - sizeof (struct GNUNET_TUN_IcmpHeader);
2171  if (mlen >= GNUNET_MAX_MESSAGE_SIZE)
2172  {
2173  GNUNET_break (0);
2174  return;
2175  }
2176  env = GNUNET_MQ_msg_extra (iim,
2177  alen + payload_length - sizeof (struct GNUNET_TUN_IcmpHeader),
2179  iim->icmp_header = *icmp;
2180  iim->icmp_header.type = new_type;
2181  iim->af = htonl (destination->details.exit_destination.af);
2182  switch (destination->details.exit_destination.af)
2183  {
2184  case AF_INET:
2185  ip4dst = (struct in_addr *) &iim[1];
2186  *ip4dst = destination->details.exit_destination.ip.v4;
2187  payload = &ip4dst[1];
2188  break;
2189  case AF_INET6:
2190  ip6dst = (struct in6_addr *) &iim[1];
2191  *ip6dst = destination->details.exit_destination.ip.v6;
2192  payload = &ip6dst[1];
2193  break;
2194  default:
2195  GNUNET_assert (0);
2196  }
2197  GNUNET_memcpy (payload,
2198  &icmp[1],
2199  payload_length - sizeof (struct GNUNET_TUN_IcmpHeader));
2200  }
2201  break;
2202  default:
2203  /* not supported above, how can we get here !? */
2204  GNUNET_assert (0);
2205  break;
2206  }
2207  ts->is_established = GNUNET_YES;
2208  send_to_channel (ts,
2209  env);
2210 }
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.
union ChannelState::@114 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_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#define GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_INTERNET
Type of messages containing an ICMP packet for the Internet.
struct GNUNET_CONTAINER_HeapNode * GNUNET_CONTAINER_heap_insert(struct GNUNET_CONTAINER_Heap *heap, void *element, GNUNET_CONTAINER_HeapCostType cost)
Inserts a new element into the heap.
#define GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED
uint8_t protocol
IPPROTO_TCP or IPPROTO_UDP once bound.
struct DestinationChannel * next
Kept in a DLL.
static const char * print_channel_destination(const struct DestinationEntry *de)
Output destination of a channel for diagnostics.
int32_t af
Address family, AF_INET or AF_INET6, in network byte order.
Definition: exit.h:249
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_MESSAGE_TYPE_VPN_UDP_TO_SERVICE
Type of messages containing an UDP packet for a service.
union ChannelState::@113 source_ip
IP address of the source on our end, initially uninitialized.
#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.
struct DestinationEntry destination
Destination to which this channel leads.
#define GNUNET_NO
Definition: gnunet_common.h:81
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_new(type)
Allocate a struct or union of the given type.
int32_t af
Address family, AF_INET or AF_INET6, in network byte order.
Definition: exit.h:73
struct GNUNET_TUN_TcpHeader tcp_header
Skeleton of the TCP header to send.
Definition: exit.h:110
struct GNUNET_CONTAINER_HeapNode * heap_node
Heap node for this state in the connections_heap.
int is_service
GNUNET_NO if this is a channel to an Internet-exit, GNUNET_YES if this channel is to a service...
uint16_t destination_port
Destination port (in NBO).
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
uint16_t len
Number of bytes of payload.
#define GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH
struct GNUNET_TUN_TcpHeader tcp_header
Skeleton of the TCP header to send.
Definition: exit.h:53
#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:208
#define GNUNET_MESSAGE_TYPE_VPN_TCP_DATA_TO_EXIT
Type of messages containing an TCP packet of an established connection.
int32_t af
Address family, AF_INET or AF_INET6, in network byte order.
Definition: exit.h:155
Message send via cadet to an exit daemon to send ICMP data to a local service.
Definition: exit.h:205
#define GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE
#define GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
#define GNUNET_TUN_ICMPTYPE6_ECHO_REPLY
#define GNUNET_memcpy(dst, src, n)
struct GNUNET_TUN_TcpHeader tcp_header
Skeleton of the TCP header to send.
Definition: exit.h:79
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
static struct GNUNET_CONTAINER_Heap * channel_heap
Min-Heap sorted by activity time to expire old mappings; values are of type &#39;struct ChannelState&#39;...
List of channels we keep for each destination port for a given destination entry. ...
#define GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG
uint16_t destination_port
Destination port to use for the UDP request.
Definition: exit.h:165
int is_established
Is this channel new (GNUNET_NO), or did we exchange messages with the other side already (GNUNET_YES)...
uint32_t reserved
Always 0.
Definition: exit.h:47
Message send via cadet to an exit daemon to forward ICMP data to the Internet.
Definition: exit.h:236
#define GNUNET_MESSAGE_TYPE_VPN_TCP_TO_INTERNET_START
Type of messages containing an TCP packet for the Internet.
static unsigned long long max_channel_mappings
If there are more than this number of open channels, old ones will be removed.
int af
Addess family used for this channel on the local TUN interface.
A 512-bit hashcode.
union DestinationEntry::@109 details
Details about the connection (depending on is_service).
uint16_t destination_port
Destination port (in NBO).
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
struct GNUNET_CADET_Channel * channel
Cadet channel that is used for this connection.
static void get_channel_key_from_ips(int af, uint8_t protocol, const void *source_ip, uint16_t source_port, const void *destination_ip, uint16_t destination_port, struct GNUNET_HashCode *key)
Compute the key under which we would store an entry in the channel_map for the given socket address p...
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.
struct DestinationEntry::@109::@110 service_destination
#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:120
uint16_t source_port
Source port (in NBO).
#define GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
struct DestinationChannel * dt_head
Head of DLL of channels associated with this destination.
uint16_t source_port
Source port (in NBO).
uint16_t destination_port
Destination port used by the sender on our end; 0 for uninitialized.
#define GNUNET_log(kind,...)
Message send via cadet to an exit daemon to initiate forwarding of TCP data to the Internet...
Definition: exit.h:63
int32_t af
Address family, AF_INET or AF_INET6, in network byte order.
Definition: exit.h:218
struct GNUNET_REGEX_Search * search
Active query with REGEX to locate exit.
struct DestinationEntry::@109::@111 exit_destination
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:80
unsigned int off
Number of 32-bit words in TCP header.
uint16_t source_port
Source port to use for the UDP request (0 to use a random port).
Definition: exit.h:160
Message send via cadet to an exit daemon to initiate forwarding of TCP data to a local service...
Definition: exit.h:37
#define GNUNET_TUN_ICMPTYPE_ECHO_REPLY
struct DestinationChannel * dt_tail
Tail of DLL of channels associated with this destination.
Message send via cadet between VPN and entry and an exit daemon to transmit TCP data between the VPN ...
Definition: exit.h:94
uint32_t reserved
Always 0.
Definition: exit.h:104
struct GNUNET_TUN_IcmpHeader icmp_header
ICMP header to use.
Definition: exit.h:223
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
uint16_t source_port
Source port to use for the UDP request (0 to use a random port).
Definition: exit.h:130
struct GNUNET_TUN_IcmpHeader icmp_header
ICMP header to use.
Definition: exit.h:255
Message send via cadet to an exit daemon to forward UDP data to the Internet.
Definition: exit.h:145
struct in6_addr v6
Address if af is AF_INET6.
#define gettext_noop(String)
Definition: gettext.h:69
uint16_t destination_port
Destination port to use for the UDP request.
Definition: exit.h:135
Here is the call graph for this function:
Here is the caller graph for this function:

◆ message_token()

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

Receive packets from the helper-process (someone send to the local virtual channel interface).

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

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

Definition at line 2226 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().

2228 {
2229  const struct GNUNET_TUN_Layer2PacketHeader *tun;
2230  size_t mlen;
2231  struct GNUNET_HashCode key;
2232  struct DestinationEntry *de;
2233 
2235  gettext_noop ("# Packets received from TUN interface"),
2236  1, GNUNET_NO);
2237  mlen = ntohs (message->size);
2238  if ( (ntohs (message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) ||
2239  (mlen < sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_TUN_Layer2PacketHeader)) )
2240  {
2241  GNUNET_break (0);
2242  return GNUNET_OK;
2243  }
2244  tun = (const struct GNUNET_TUN_Layer2PacketHeader *) &message[1];
2245  mlen -= (sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_TUN_Layer2PacketHeader));
2246  switch (ntohs (tun->proto))
2247  {
2248  case ETH_P_IPV6:
2249  {
2250  const struct GNUNET_TUN_IPv6Header *pkt6;
2251 
2252  if (mlen < sizeof (struct GNUNET_TUN_IPv6Header))
2253  {
2254  /* blame kernel */
2255  GNUNET_break (0);
2256  return GNUNET_OK;
2257  }
2258  pkt6 = (const struct GNUNET_TUN_IPv6Header *) &tun[1];
2259  get_destination_key_from_ip (AF_INET6,
2260  &pkt6->destination_address,
2261  &key);
2263  if (NULL == de)
2264  {
2265  char buf[INET6_ADDRSTRLEN];
2266 
2268  _("Packet received for unmapped destination `%s' (dropping it)\n"),
2269  inet_ntop (AF_INET6,
2270  &pkt6->destination_address,
2271  buf,
2272  sizeof (buf)));
2273  return GNUNET_OK;
2274  }
2275  route_packet (de,
2276  AF_INET6,
2277  pkt6->next_header,
2278  &pkt6->source_address,
2279  &pkt6->destination_address,
2280  &pkt6[1],
2281  mlen - sizeof (struct GNUNET_TUN_IPv6Header));
2282  }
2283  break;
2284  case ETH_P_IPV4:
2285  {
2286  struct GNUNET_TUN_IPv4Header *pkt4;
2287 
2288  if (mlen < sizeof (struct GNUNET_TUN_IPv4Header))
2289  {
2290  /* blame kernel */
2291  GNUNET_break (0);
2292  return GNUNET_OK;
2293  }
2294  pkt4 = (struct GNUNET_TUN_IPv4Header *) &tun[1];
2295  get_destination_key_from_ip (AF_INET,
2296  &pkt4->destination_address,
2297  &key);
2299  if (NULL == de)
2300  {
2301  char buf[INET_ADDRSTRLEN];
2302 
2304  _("Packet received for unmapped destination `%s' (dropping it)\n"),
2305  inet_ntop (AF_INET,
2306  &pkt4->destination_address,
2307  buf,
2308  sizeof (buf)));
2309  return GNUNET_OK;
2310  }
2311  if (pkt4->header_length * 4 != sizeof (struct GNUNET_TUN_IPv4Header))
2312  {
2314  _("Received IPv4 packet with options (dropping it)\n"));
2315  return GNUNET_OK;
2316  }
2317  route_packet (de,
2318  AF_INET,
2319  pkt4->protocol,
2320  &pkt4->source_address,
2321  &pkt4->destination_address,
2322  &pkt4[1],
2323  mlen - sizeof (struct GNUNET_TUN_IPv4Header));
2324  }
2325  break;
2326  default:
2328  _("Received packet of unknown protocol %d from TUN (dropping it)\n"),
2329  (unsigned int) ntohs (tun->proto));
2330  break;
2331  }
2332  return GNUNET_OK;
2333 }
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:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
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:208
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 2345 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, inet_pton(), and vpn_argv.

Referenced by allocate_response_ip().

2346 {
2347  const char *ipv4addr = vpn_argv[4];
2348  const char *ipv4mask = vpn_argv[5];
2349  struct in_addr addr;
2350  struct in_addr mask;
2351  struct in_addr rnd;
2352  struct GNUNET_HashCode key;
2353  unsigned int tries;
2354 
2355  GNUNET_assert (1 == inet_pton (AF_INET, ipv4addr, &addr));
2356  GNUNET_assert (1 == inet_pton (AF_INET, ipv4mask, &mask));
2357  /* Given 192.168.0.1/255.255.0.0, we want a mask
2358  of '192.168.255.255', thus: */
2359  mask.s_addr = addr.s_addr | ~mask.s_addr;
2360  tries = 0;
2361  do
2362  {
2363  tries++;
2364  if (tries > 16)
2365  {
2367  _("Failed to find unallocated IPv4 address in VPN's range\n"));
2368  return GNUNET_SYSERR;
2369  }
2370  /* Pick random IPv4 address within the subnet, except 'addr' or 'mask' itself */
2372  UINT32_MAX);
2373  v4->s_addr = (addr.s_addr | rnd.s_addr) & mask.s_addr;
2374  get_destination_key_from_ip (AF_INET,
2375  v4,
2376  &key);
2377  }
2378  while ( (GNUNET_YES ==
2380  &key)) ||
2381  (v4->s_addr == addr.s_addr) ||
2382  (v4->s_addr == mask.s_addr) );
2383  return GNUNET_OK;
2384 }
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:78
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:208
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:79
static int inet_pton(int af, const char *cp, struct in_addr *buf)
Convert IPv4 address from text to binary form.
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:80
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 2396 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, inet_pton(), ipv6prefix, and vpn_argv.

Referenced by allocate_response_ip().

2397 {
2398  const char *ipv6addr = vpn_argv[2];
2399  struct in6_addr addr;
2400  struct in6_addr mask;
2401  struct in6_addr rnd;
2402  int i;
2403  struct GNUNET_HashCode key;
2404  unsigned int tries;
2405 
2406  GNUNET_assert (1 == inet_pton (AF_INET6, ipv6addr, &addr));
2407  GNUNET_assert (ipv6prefix < 128);
2408  /* Given ABCD::/96, we want a mask of 'ABCD::FFFF:FFFF,
2409  thus: */
2410  mask = addr;
2411  for (i=127;i>=ipv6prefix;i--)
2412  mask.s6_addr[i / 8] |= (1 << (i % 8));
2413 
2414  /* Pick random IPv6 address within the subnet, except 'addr' or 'mask' itself */
2415  tries = 0;
2416  do
2417  {
2418  tries++;
2419  if (tries > 16)
2420  {
2422  _("Failed to find unallocated IPv6 address in VPN's range\n"));
2423  return GNUNET_SYSERR;
2424 
2425  }
2426  for (i=0;i<16;i++)
2427  {
2428  rnd.s6_addr[i] = (unsigned char) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
2429  256);
2430  v6->s6_addr[i]
2431  = (addr.s6_addr[i] | rnd.s6_addr[i]) & mask.s6_addr[i];
2432  }
2433  get_destination_key_from_ip (AF_INET6,
2434  v6,
2435  &key);
2436  }
2437  while ( (GNUNET_YES ==
2439  &key)) ||
2440  (0 == GNUNET_memcmp (v6,
2441  &addr)) ||
2442  (0 == GNUNET_memcmp (v6,
2443  &mask)) );
2444  return GNUNET_OK;
2445 }
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:78
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:208
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:79
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
static int inet_pton(int af, const char *cp, struct in_addr *buf)
Convert IPv4 address from text to binary form.
#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:80
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 2454 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().

2455 {
2456  struct DestinationChannel *dt;
2457 
2459  "Cleaning up destination entry `%s'\n",
2462  gettext_noop ("# Active destinations"),
2463  -1, GNUNET_NO);
2464  while (NULL != (dt = de->dt_head))
2465  {
2467  de->dt_tail,
2468  dt);
2469  GNUNET_free (dt);
2470  }
2471  if (NULL != de->heap_node)
2472  {
2474  de->heap_node = NULL;
2477  &de->key,
2478  de));
2479  }
2480  GNUNET_free (de);
2481 }
#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:81
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:80
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 2490 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().

2491 {
2492  struct DestinationEntry *de;
2493 
2495  GNUNET_assert (NULL != de);
2496  if (except == de)
2497  return; /* can't do this */
2499 }
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 2517 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().

2521 {
2522  *addr = NULL;
2523  switch (*result_af)
2524  {
2525  case AF_INET:
2526  if (GNUNET_OK !=
2528  *result_af = AF_UNSPEC;
2529  else
2530  *addr = v4;
2531  break;
2532  case AF_INET6:
2533  if (GNUNET_OK !=
2535  *result_af = AF_UNSPEC;
2536  else
2537  *addr = v6;
2538  break;
2539  case AF_UNSPEC:
2540  if (GNUNET_OK ==
2542  {
2543  *addr = v4;
2544  *result_af = AF_INET;
2545  }
2546  else if (GNUNET_OK ==
2548  {
2549  *addr = v6;
2550  *result_af = AF_INET6;
2551  }
2552  break;
2553  default:
2554  GNUNET_break (0);
2555  return GNUNET_SYSERR;
2556  }
2557  return GNUNET_OK;
2558 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
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:79
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 2571 of file gnunet-service-vpn.c.

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

2573 {
2574  size_t alen;
2575  int addr_af;
2576 
2577  alen = ntohs (msg->header.size) - sizeof (struct RedirectToIpRequestMessage);
2578  addr_af = (int) htonl (msg->addr_af);
2579  switch (addr_af)
2580  {
2581  case AF_INET:
2582  if (alen != sizeof (struct in_addr))
2583  {
2584  GNUNET_break (0);
2585  return GNUNET_SYSERR;
2586  }
2587  break;
2588  case AF_INET6:
2589  if (alen != sizeof (struct in6_addr))
2590  {
2591  GNUNET_break (0);
2592  return GNUNET_SYSERR;
2593  }
2594  break;
2595  default:
2596  GNUNET_break (0);
2597  return GNUNET_SYSERR;
2598  }
2599  return GNUNET_OK;
2600 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
Message send by the VPN client to the VPN service requesting the setup of a redirection from some IP ...
Definition: vpn.h:38
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_IP.
Definition: vpn.h:43
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
int32_t addr_af
Address family used for the destination address (AF_INET or AF_INET6, in nbo)
Definition: vpn.h:63

◆ handle_client_redirect_to_ip()

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

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

Setup the redirection and give the client the allocated IP.

Parameters
clsclient requesting client
msgredirection request

Definition at line 2612 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.

2614 {
2615  struct GNUNET_SERVICE_Client *client = cls;
2616  size_t alen;
2617  int addr_af;
2618  int result_af;
2619  struct in_addr v4;
2620  struct in6_addr v6;
2621  void *addr;
2622  struct DestinationEntry *de;
2623  struct GNUNET_HashCode key;
2624 
2625  alen = ntohs (msg->header.size) - sizeof (struct RedirectToIpRequestMessage);
2626  addr_af = (int) htonl (msg->addr_af);
2627  /* allocate response IP */
2628  result_af = (int) htonl (msg->result_af);
2629  if (GNUNET_OK != allocate_response_ip (&result_af,
2630  &addr,
2631  &v4, &v6))
2632  {
2633  GNUNET_SERVICE_client_drop (client);
2634  return;
2635  }
2636  /* send reply with our IP address */
2637  send_client_reply (client,
2638  msg->request_id,
2639  result_af,
2640  addr);
2641  if (result_af == AF_UNSPEC)
2642  {
2643  /* failure, we're done */
2645  return;
2646  }
2647 
2648  {
2649  char sbuf[INET6_ADDRSTRLEN];
2650  char dbuf[INET6_ADDRSTRLEN];
2651 
2653  "Allocated address %s for redirection via exit to %s\n",
2654  inet_ntop (result_af,
2655  addr,
2656  sbuf,
2657  sizeof (sbuf)),
2658  inet_ntop (addr_af,
2659  &msg[1],
2660  dbuf,
2661  sizeof (dbuf)));
2662  }
2663 
2664  /* setup destination record */
2665  de = GNUNET_new (struct DestinationEntry);
2666  de->is_service = GNUNET_NO;
2667  de->details.exit_destination.af = addr_af;
2669  &msg[1],
2670  alen);
2671  get_destination_key_from_ip (result_af,
2672  addr,
2673  &key);
2674  de->key = key;
2677  &key,
2678  de,
2681  de,
2684  gettext_noop ("# Active destinations"),
2685  1, GNUNET_NO);
2687  expire_destination (de);
2689 }
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:670
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
Information we track for each IP address to determine which channel to send the traffic over to the d...
struct GNUNET_CONTAINER_HeapNode * GNUNET_CONTAINER_heap_insert(struct GNUNET_CONTAINER_Heap *heap, void *element, GNUNET_CONTAINER_HeapCostType cost)
Inserts a new element into the heap.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static void expire_destination(struct DestinationEntry *except)
We have too many active destinations.
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#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:249
#define GNUNET_memcpy(dst, src, n)
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:58
static struct GNUNET_CONTAINER_MultiHashMap * destination_map
Map from IP address to destination information (possibly with a CADET channel handle for fast setup)...
A 512-bit hashcode.
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2618
union DestinationEntry::@109 details
Details about the connection (depending on is_service).
static void get_destination_key_from_ip(int af, const void *address, struct GNUNET_HashCode *key)
Compute the key under which we would store an entry in the destination_map for the given IP address...
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_IP.
Definition: vpn.h:43
struct GNUNET_HashCode key
The key used in the DHT.
static void send_client_reply(struct GNUNET_SERVICE_Client *client, uint64_t request_id, int result_af, const void *addr)
Notify the client about the result of its request.
int GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
Allow multiple values with the same key.
static struct GNUNET_STATISTICS_Handle * stats
Statistics.
int32_t addr_af
Address family used for the destination address (AF_INET or AF_INET6, in nbo)
Definition: vpn.h:63
struct GNUNET_TIME_AbsoluteNBO expiration_time
How long should the redirection be maintained at most?
Definition: vpn.h:53
#define GNUNET_log(kind,...)
struct DestinationEntry::@109::@111 exit_destination
static struct GNUNET_CONTAINER_Heap * destination_heap
Min-Heap sorted by activity time to expire old mappings.
uint64_t request_id
Unique ID to match a future response to this request.
Definition: vpn.h:69
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2533
#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 2701 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.

2703 {
2704  struct GNUNET_SERVICE_Client *client = cls;
2705  int result_af;
2706  struct in_addr v4;
2707  struct in6_addr v6;
2708  void *addr;
2709  struct DestinationEntry *de;
2710  struct GNUNET_HashCode key;
2711  struct DestinationChannel *dt;
2712 
2713  /* allocate response IP */
2714  result_af = (int) htonl (msg->result_af);
2715  if (GNUNET_OK !=
2716  allocate_response_ip (&result_af,
2717  &addr,
2718  &v4,
2719  &v6))
2720  {
2721  GNUNET_break (0);
2722  GNUNET_SERVICE_client_drop (client);
2723  return;
2724  }
2725  send_client_reply (client,
2726  msg->request_id,
2727  result_af,
2728  addr);
2729  if (result_af == AF_UNSPEC)
2730  {
2731  /* failure, we're done */
2733  _("Failed to allocate IP address for new destination\n"));
2735  return;
2736  }
2737 
2738  {
2739  char sbuf[INET6_ADDRSTRLEN];
2740 
2742  "Allocated address %s for redirection to service %s on peer %s\n",
2743  inet_ntop (result_af,
2744  addr,
2745  sbuf,
2746  sizeof (sbuf)),
2748  GNUNET_i2s (&msg->target));
2749  }
2750 
2751  /* setup destination record */
2752  de = GNUNET_new (struct DestinationEntry);
2753  de->is_service = GNUNET_YES;
2754  de->details.service_destination.target = msg->target;
2755  de->details.service_destination.service_descriptor = msg->service_descriptor;
2756  get_destination_key_from_ip (result_af,
2757  addr,
2758  &key);
2759  de->key = key;
2762  &key,
2763  de,
2765  de->heap_node
2767  de,
2770  expire_destination (de);
2771 
2772  dt = GNUNET_new (struct DestinationChannel);
2773  dt->destination = de;
2775  de->dt_tail,
2776  dt);
2777  /* we're done */
2779 }
struct GNUNET_HashCode service_descriptor
Service descriptor identifying the service.
Definition: vpn.h:116
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:670
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:111
#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:106
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:78
#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:208
Handle to a client that is connected to a service.
Definition: service.c:249
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:2618
union DestinationEntry::@109 details
Details about the connection (depending on is_service).
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.
struct DestinationEntry::@109::@110 service_destination
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:96
uint64_t request_id
Unique ID to match a future response to this request.
Definition: vpn.h:122
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:80
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:2533
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 2792 of file gnunet-service-vpn.c.

References free_destination_entry(), GNUNET_OK, and value.

Referenced by cleanup().

2795 {
2796  struct DestinationEntry *de = value;
2797 
2799  return GNUNET_OK;
2800 }
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:78
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 2812 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().

2815 {
2816  struct ChannelState *ts = value;
2817 
2819  "Tearing down channel to `%s' during cleanup\n",
2821  free_channel_state (ts);
2822  return GNUNET_OK;
2823 }
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:78
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 2832 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().

2833 {
2834  unsigned int i;
2835 
2837  "VPN is shutting down\n");
2838  if (NULL != destination_map)
2839  {
2842  NULL);
2844  destination_map = NULL;
2845  }
2846  if (NULL != destination_heap)
2847  {
2849  destination_heap = NULL;
2850  }
2851  if (NULL != channel_map)
2852  {
2854  &cleanup_channel,
2855  NULL);
2857  channel_map = NULL;
2858  }
2859  if (NULL != channel_heap)
2860  {
2862  channel_heap = NULL;
2863  }
2864  if (NULL != cadet_handle)
2865  {
2867  cadet_handle = NULL;
2868  }
2869  if (NULL != helper_handle)
2870  {
2873  helper_handle = NULL;
2874  }
2875  if (NULL != stats)
2876  {
2878  stats = NULL;
2879  }
2880  for (i=0;i<5;i++)
2882 }
int GNUNET_HELPER_kill(struct GNUNET_HELPER_Handle *h, int soft_kill)
Sends termination signal to the helper process.
Definition: helper.c:180
void GNUNET_CADET_disconnect(struct GNUNET_CADET_Handle *handle)
Disconnect from the cadet service.
Definition: cadet_api.c:849
static int cleanup_destination(void *cls, const struct GNUNET_HashCode *key, void *value)
Free memory occupied by an entry in the destination map.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_HashMapIterator it, void *it_cls)
Iterate over all entries in the map.
#define GNUNET_NO
Definition: gnunet_common.h:81
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:231
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".
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 2894 of file gnunet-service-vpn.c.

Referenced by run().

2897 {
2898  return c;
2899 }
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 2910 of file gnunet-service-vpn.c.

References GNUNET_assert.

Referenced by run().

2913 {
2914  GNUNET_assert (c == internal_cls);
2915 }
#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 2926 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_suid_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, inet_pton(), ipv6prefix, max_channel_mappings, max_destination_mappings, message_token(), and vpn_argv.

2929 {
2930  char *ifname;
2931  char *ipv6addr;
2932  char *ipv6prefix_s;
2933  char *ipv4addr;
2934  char *ipv4mask;
2935  struct in_addr v4;
2936  struct in6_addr v6;
2937  char *binary;
2938 
2939  cfg = cfg_;
2940  binary = GNUNET_OS_get_suid_binary_path (cfg, "gnunet-helper-vpn");
2941 
2942  if (GNUNET_YES !=
2944  GNUNET_YES,
2945  "-d gnunet-vpn - - 169.1.3.3.7 255.255.255.0")) //ipv4 only please!
2946  {
2948  "`%s' is not SUID or the path is invalid, refusing to run.\n",
2949  binary);
2950  GNUNET_free (binary);
2951  global_ret = 1;
2952  /* we won't "really" exit here, as the 'service' is still running;
2953  however, as no handlers are registered, the service won't do
2954  anything either */
2955  return;
2956  }
2957  stats = GNUNET_STATISTICS_create ("vpn", cfg);
2958  if (GNUNET_OK !=
2960  "VPN",
2961  "MAX_MAPPING",
2964  if (GNUNET_OK !=
2966  "VPN",
2967  "MAX_TUNNELS",
2969  max_channel_mappings = 200;
2970 
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  {
2982  GNUNET_free (binary);
2984  return;
2985  }
2986  vpn_argv[1] = ifname;
2987  ipv6addr = NULL;
2988  if (GNUNET_OK == GNUNET_NETWORK_test_pf (PF_INET6))
2989  {
2990  if ( (GNUNET_SYSERR ==
2991  GNUNET_CONFIGURATION_get_value_string (cfg, "VPN", "IPV6ADDR",
2992  &ipv6addr) ||
2993  (1 != inet_pton (AF_INET6, ipv6addr, &v6))) )
2994  {
2996  _("Must specify valid IPv6 address"));
2997  GNUNET_free (binary);
2999  GNUNET_free_non_null (ipv6addr);
3000  return;
3001  }
3002  vpn_argv[2] = ipv6addr;
3003  ipv6prefix_s = NULL;
3004  if (GNUNET_SYSERR ==
3005  GNUNET_CONFIGURATION_get_value_string (cfg, "VPN", "IPV6PREFIX",
3006  &ipv6prefix_s))
3007  {
3008  GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "VPN", "IPV6PREFIX");
3009  GNUNET_free (binary);
3011  GNUNET_free_non_null (ipv6prefix_s);
3012  return;
3013  }
3014  vpn_argv[3] = ipv6prefix_s;
3015  if ( (GNUNET_OK !=
3017  "IPV6PREFIX",
3018  &ipv6prefix)) ||
3019  (ipv6prefix >= 127) )
3020  {
3022  _("Must specify valid IPv6 mask"));
3023  GNUNET_free (binary);
3025  return;
3026  }
3027  }
3028  else
3029  {
3031  _("IPv6 support disabled as this system does not support IPv6\n"));
3032  vpn_argv[2] = GNUNET_strdup ("-");
3033  vpn_argv[3] = GNUNET_strdup ("-");
3034  }
3035  if (GNUNET_OK == GNUNET_NETWORK_test_pf (PF_INET))
3036  {
3037  ipv4addr = NULL;
3038  if ( (GNUNET_SYSERR ==
3039  GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4ADDR",
3040  &ipv4addr) ||
3041  (1 != inet_pton (AF_INET, ipv4addr, &v4))) )
3042  {
3044  _("Must specify valid IPv4 address"));
3045  GNUNET_free (binary);
3047  GNUNET_free_non_null (ipv4addr);
3048  return;
3049  }
3050  vpn_argv[4] = ipv4addr;
3051  ipv4mask = NULL;
3052  if ( (GNUNET_SYSERR ==
3053  GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4MASK",
3054  &ipv4mask) ||
3055  (1 != inet_pton (AF_INET, ipv4mask, &v4))) )
3056  {
3058  _("Must specify valid IPv4 mask"));
3059  GNUNET_free (binary);
3061  GNUNET_free_non_null (ipv4mask);
3062  return;
3063  }
3064  vpn_argv[5] = ipv4mask;
3065  }
3066  else
3067  {
3069  _("IPv4 support disabled as this system does not support IPv4\n"));
3070  vpn_argv[4] = GNUNET_strdup ("-");
3071  vpn_argv[5] = GNUNET_strdup ("-");
3072  }
3073  vpn_argv[6] = NULL;
3074 
3076  // FIXME never opens ports???
3078  binary,
3079  vpn_argv,
3080  &message_token,
3081  NULL,
3082  NULL);
3083  GNUNET_free (binary);
3085  NULL);
3086 }
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:491
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:1293
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:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#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:524
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:995
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
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.
char * GNUNET_OS_get_suid_binary_path(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *progname)
Given the name of a helper, service or daemon binary construct the full path to the binary using the ...
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:79
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.
static int inet_pton(int af, const char *cp, struct in_addr *buf)
Convert IPv4 address from text to binary form.
#define GNUNET_log(kind,...)
static unsigned long long ipv6prefix
Length of the prefix of the VPN&#39;s IPv6 network.
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:80
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:84
#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 319 of file gnunet-service-vpn.c.

Referenced by run().

◆ cfg

const struct GNUNET_CONFIGURATION_Handle* cfg
static

Configuration we use.

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

◆ cadet_handle

struct GNUNET_CADET_Handle* cadet_handle
static

Handle to the cadet service.

Definition at line 329 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 335 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 340 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 346 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 352 of file gnunet-service-vpn.c.

◆ stats

struct GNUNET_STATISTICS_Handle* stats
static

Statistics.

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

◆ vpn_argv

char* vpn_argv[7]
static

Arguments to the vpn helper.

Definition at line 367 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 372 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 378 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 384 of file gnunet-service-vpn.c.

Referenced by route_packet(), and run().