GNUnet  0.20.0
vpn_api.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2012, 2016 Christian Grothoff
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
20 
26 #include "platform.h"
27 #include "gnunet_vpn_service.h"
28 #include "vpn.h"
29 
30 
35 {
40 
45 
50 
55 
60 
65 
69  uint64_t request_id_gen;
70 };
71 
72 
77 {
82 
87 
92 
97  const void *addr;
98 
103 
107  void *cb_cls;
108 
112  struct GNUNET_PeerIdentity peer;
113 
117  struct GNUNET_HashCode serv;
118 
123 
127  uint64_t request_id;
128 
133 
137  int addr_af;
138 
142  uint8_t protocol;
143 };
144 
145 
151 static void
152 reconnect (struct GNUNET_VPN_Handle *vh);
153 
154 
163 static int
164 check_use_ip (void *cls,
165  const struct RedirectToIpResponseMessage *rm)
166 {
167  size_t alen;
168  int af;
169 
170  af = (int) ntohl (rm->result_af);
171  switch (af)
172  {
173  case AF_UNSPEC:
174  alen = 0;
175  break;
176 
177  case AF_INET:
178  alen = sizeof(struct in_addr);
179  break;
180 
181  case AF_INET6:
182  alen = sizeof(struct in6_addr);
183  break;
184 
185  default:
186  GNUNET_break (0);
187  return GNUNET_SYSERR;
188  }
189  if ((ntohs (rm->header.size) != alen + sizeof(*rm)) ||
190  (0 == rm->request_id))
191  {
192  GNUNET_break (0);
193  return GNUNET_SYSERR;
194  }
195  return GNUNET_OK;
196 }
197 
198 
206 static void
207 handle_use_ip (void *cls,
208  const struct RedirectToIpResponseMessage *rm)
209 {
210  struct GNUNET_VPN_Handle *vh = cls;
212  int af;
213 
214  af = (int) ntohl (rm->result_af);
215  for (rr = vh->rr_head; NULL != rr; rr = rr->next)
216  {
217  if (rr->request_id == rm->request_id)
218  {
220  vh->rr_tail,
221  rr);
222  rr->cb (rr->cb_cls,
223  af,
224  (af == AF_UNSPEC) ? NULL : &rm[1]);
225  GNUNET_free (rr);
226  break;
227  }
228  }
229 }
230 
231 
237 static void
239 {
240  struct GNUNET_VPN_Handle *vh = rr->vh;
241  struct RedirectToIpRequestMessage *rip;
243  struct GNUNET_MQ_Envelope *env;
244  size_t alen;
245 
246  if (NULL == vh->mq)
247  return;
248  if (NULL == rr->addr)
249  {
250  env = GNUNET_MQ_msg (rs,
252  rs->reserved = htonl (0);
254  rs->protocol = htonl (rr->protocol);
255  rs->result_af = htonl (rr->result_af);
256  rs->target = rr->peer;
257  rs->service_descriptor = rr->serv;
258  rs->request_id = rr->request_id = ++vh->request_id_gen;
259  }
260  else
261  {
262  switch (rr->addr_af)
263  {
264  case AF_INET:
265  alen = sizeof(struct in_addr);
266  break;
267 
268  case AF_INET6:
269  alen = sizeof(struct in6_addr);
270  break;
271 
272  default:
273  GNUNET_assert (0);
274  return;
275  }
276  env = GNUNET_MQ_msg_extra (rip,
277  alen,
279  rip->reserved = htonl (0);
281  rip->result_af = htonl (rr->result_af);
282  rip->addr_af = htonl (rr->addr_af);
283  rip->request_id = rr->request_id = ++vh->request_id_gen;
284  GNUNET_memcpy (&rip[1],
285  rr->addr,
286  alen);
287  }
288  GNUNET_MQ_send (vh->mq,
289  env);
290 }
291 
292 
301 static void
302 mq_error_handler (void *cls,
303  enum GNUNET_MQ_Error error)
304 {
305  struct GNUNET_VPN_Handle *vh = cls;
306 
307  reconnect (vh);
308 }
309 
310 
316 static void
317 connect_task (void *cls)
318 {
319  struct GNUNET_VPN_Handle *vh = cls;
321  GNUNET_MQ_hd_var_size (use_ip,
324  cls),
326  };
328 
329  vh->rt = NULL;
331  "vpn",
332  handlers,
334  vh);
335  if (NULL == vh->mq)
336  return;
337  for (rr = vh->rr_head; NULL != rr; rr = rr->next)
338  send_request (rr);
339 }
340 
341 
347 static void
349 {
351 
353  vh->mq = NULL;
354  vh->request_id_gen = 0;
355  for (rr = vh->rr_head; NULL != rr; rr = rr->next)
356  rr->request_id = 0;
360  vh->backoff, 2),
364  &connect_task,
365  vh);
366 }
367 
368 
374 void
376 {
377  struct GNUNET_VPN_Handle *vh;
378 
379  vh = rr->vh;
381  vh->rr_tail,
382  rr);
383  GNUNET_free (rr);
384 }
385 
386 
389  int result_af,
390  uint8_t protocol,
391  const struct GNUNET_PeerIdentity *peer,
392  const struct GNUNET_HashCode *serv,
395  void *cb_cls)
396 {
398 
400  rr->vh = vh;
401  rr->cb = cb;
402  rr->cb_cls = cb_cls;
403  rr->peer = *peer;
404  rr->serv = *serv;
406  rr->result_af = result_af;
407  rr->protocol = protocol;
409  vh->rr_tail,
410  rr);
411  send_request (rr);
412  return rr;
413 }
414 
415 
440  int result_af,
441  int addr_af,
442  const void *addr,
445  void *cb_cls)
446 {
448  size_t alen;
449 
450  switch (addr_af)
451  {
452  case AF_INET:
453  alen = sizeof(struct in_addr);
454  break;
455 
456  case AF_INET6:
457  alen = sizeof(struct in6_addr);
458  break;
459 
460  default:
461  GNUNET_break (0);
462  return NULL;
463  }
464  rr = GNUNET_malloc (sizeof(struct GNUNET_VPN_RedirectionRequest) + alen);
465  rr->vh = vh;
466  rr->addr = &rr[1];
467  rr->cb = cb;
468  rr->cb_cls = cb_cls;
469  rr->expiration_time = expiration_time;
470  rr->result_af = result_af;
471  rr->addr_af = addr_af;
472  GNUNET_memcpy (&rr[1],
473  addr,
474  alen);
476  vh->rr_tail,
477  rr);
478  send_request (rr);
479  return rr;
480 }
481 
482 
489 struct GNUNET_VPN_Handle *
491 {
492  struct GNUNET_VPN_Handle *vh
493  = GNUNET_new (struct GNUNET_VPN_Handle);
494 
495  vh->cfg = cfg;
496  connect_task (vh);
497  if (NULL == vh->mq)
498  {
499  GNUNET_free (vh);
500  return NULL;
501  }
502  return vh;
503 }
504 
505 
511 void
513 {
514  GNUNET_assert (NULL == vh->rr_head);
515  if (NULL != vh->mq)
516  {
517  GNUNET_MQ_destroy (vh->mq);
518  vh->mq = NULL;
519  }
520  if (NULL != vh->rt)
521  {
523  vh->rt = NULL;
524  }
525  GNUNET_free (vh);
526 }
527 
528 
529 /* end of vpn_api.c */
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
static struct GNUNET_CADET_MessageHandler handlers[]
Handlers, for diverse services.
API to access the VPN service.
struct GNUNET_MQ_Handle * GNUNET_CLIENT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *service_name, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *error_handler_cls)
Create a message queue to connect to a GNUnet service.
Definition: client.c:1057
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
void * cls
Closure for mv and cb.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
@ GNUNET_SYSERR
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
GNUNET_MQ_Error
Error codes for the queue.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:304
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
Definition: gnunet_mq_lib.h:63
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:78
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:683
#define GNUNET_MESSAGE_TYPE_VPN_CLIENT_USE_IP
VPN service responds to client with an IP to use for the requested redirection.
#define GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_IP
Client asks VPN service to setup an IP to redirect traffic via an exit node to some global IP address...
#define GNUNET_MESSAGE_TYPE_VPN_CLIENT_REDIRECT_TO_SERVICE
Client asks VPN service to setup an IP to redirect traffic to some peer offering a service.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:975
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1272
struct GNUNET_TIME_Relative GNUNET_TIME_relative_min(struct GNUNET_TIME_Relative t1, struct GNUNET_TIME_Relative t2)
Return the minimum of two relative time values.
Definition: time.c:343
struct GNUNET_TIME_Relative GNUNET_TIME_relative_saturating_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Saturating multiply relative time by a given factor.
Definition: time.c:531
struct GNUNET_TIME_Relative GNUNET_TIME_relative_max(struct GNUNET_TIME_Relative t1, struct GNUNET_TIME_Relative t2)
Return the maximum of two relative time values.
Definition: time.c:351
#define GNUNET_TIME_UNIT_SECONDS
One second.
#define GNUNET_TIME_UNIT_MILLISECONDS
One millisecond.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
Definition: time.c:484
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:638
struct GNUNET_VPN_RedirectionRequest * GNUNET_VPN_redirect_to_ip(struct GNUNET_VPN_Handle *vh, int result_af, int addr_af, const void *addr, struct GNUNET_TIME_Absolute expiration_time, GNUNET_VPN_AllocationCallback cb, void *cb_cls)
Tell the VPN that forwarding to the Internet via some exit node is requested.
Definition: vpn_api.c:439
void GNUNET_VPN_cancel_request(struct GNUNET_VPN_RedirectionRequest *rr)
Cancel redirection request with the service.
Definition: vpn_api.c:375
struct GNUNET_VPN_Handle * GNUNET_VPN_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the VPN service.
Definition: vpn_api.c:490
void(* GNUNET_VPN_AllocationCallback)(void *cls, int af, const void *address)
Callback invoked from the VPN service once a redirection is available.
struct GNUNET_VPN_RedirectionRequest * GNUNET_VPN_redirect_to_peer(struct GNUNET_VPN_Handle *vh, int result_af, uint8_t protocol, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_HashCode *serv, struct GNUNET_TIME_Absolute expiration_time, GNUNET_VPN_AllocationCallback cb, void *cb_cls)
Tell the VPN that a forwarding to a particular peer offering a particular service is requested.
Definition: vpn_api.c:388
void GNUNET_VPN_disconnect(struct GNUNET_VPN_Handle *vh)
Disconnect from the VPN service.
Definition: vpn_api.c:512
A 512-bit hashcode.
Handle to a message queue.
Definition: mq.c:87
Message handler for a specific message type.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
The identity of the host (wraps the signing key of the peer).
Entry in list of pending tasks.
Definition: scheduler.c:136
Time for absolute times used by GNUnet, in microseconds.
Time for relative time used by GNUnet, in microseconds.
Opaque VPN handle.
Definition: vpn_api.c:35
struct GNUNET_TIME_Relative backoff
How long do we wait until we try to reconnect?
Definition: vpn_api.c:64
uint64_t request_id_gen
ID of the last request that was submitted to the service.
Definition: vpn_api.c:69
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we use.
Definition: vpn_api.c:39
struct GNUNET_SCHEDULER_Task * rt
Identifier of a reconnect task.
Definition: vpn_api.c:59
struct GNUNET_VPN_RedirectionRequest * rr_tail
Tail of list of active redirection requests.
Definition: vpn_api.c:54
struct GNUNET_MQ_Handle * mq
Connection to VPN service.
Definition: vpn_api.c:44
struct GNUNET_VPN_RedirectionRequest * rr_head
Head of list of active redirection requests.
Definition: vpn_api.c:49
Opaque redirection request handle.
Definition: vpn_api.c:77
const void * addr
Target IP address for the redirection, or NULL for redirection to service.
Definition: vpn_api.c:97
GNUNET_VPN_AllocationCallback cb
Function to call with the designated IP address.
Definition: vpn_api.c:102
void * cb_cls
Closure for cb.
Definition: vpn_api.c:107
struct GNUNET_VPN_Handle * vh
Pointer to the VPN struct.
Definition: vpn_api.c:91
uint64_t request_id
non-zero if this request has been sent to the service.
Definition: vpn_api.c:127
struct GNUNET_PeerIdentity peer
For service redirection, identity of the peer offering the service.
Definition: vpn_api.c:112
uint8_t protocol
For service redirection, IPPROT_UDP or IPPROTO_TCP.
Definition: vpn_api.c:142
struct GNUNET_TIME_Absolute expiration_time
At what time should the created service mapping expire?
Definition: vpn_api.c:122
int addr_af
Address family of addr.
Definition: vpn_api.c:137
int result_af
Desired address family for the result.
Definition: vpn_api.c:132
struct GNUNET_HashCode serv
For service redirection, service descriptor.
Definition: vpn_api.c:117
struct GNUNET_VPN_RedirectionRequest * prev
Element in DLL.
Definition: vpn_api.c:86
struct GNUNET_VPN_RedirectionRequest * next
Element in DLL.
Definition: vpn_api.c:81
Message send by the VPN client to the VPN service requesting the setup of a redirection from some IP ...
Definition: vpn.h:39
uint64_t request_id
Unique ID to match a future response to this request.
Definition: vpn.h:69
uint32_t reserved
Always zero.
Definition: vpn.h:48
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
int32_t result_af
Address family desired for the result (AF_INET or AF_INET6 or AF_UNSPEC, in nbo)
Definition: vpn.h:58
Response from the VPN service to a VPN client informing about the IP that was assigned for the reques...
Definition: vpn.h:130
int32_t result_af
Address family of the allocated address that follows; will match "result_af" from the request,...
Definition: vpn.h:140
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_VPN_CLIENT_USE_IP.
Definition: vpn.h:134
uint64_t request_id
Unique ID to match the response to a request.
Definition: vpn.h:145
Message send by the VPN client to the VPN service requesting the setup of a redirection from some IP ...
Definition: vpn.h:81
int32_t result_af
Address family desired for the result (AF_INET or AF_INET6 or AF_UNSPEC, in nbo)
Definition: vpn.h:105
struct GNUNET_TIME_AbsoluteNBO expiration_time
How long should the redirection be maintained at most?
Definition: vpn.h:95
struct GNUNET_PeerIdentity target
Target peer offering the service.
Definition: vpn.h:110
uint64_t request_id
Unique ID to match a future response to this request.
Definition: vpn.h:121
uint32_t reserved
Always zero.
Definition: vpn.h:90
struct GNUNET_HashCode service_descriptor
Service descriptor identifying the service.
Definition: vpn.h:115
int32_t protocol
Desired protocol (IPPROTO_UDP or IPPROTO_TCP)
Definition: vpn.h:100
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
IPC messages between VPN library and VPN service.
static int check_use_ip(void *cls, const struct RedirectToIpResponseMessage *rm)
Check a GNUNET_MESSAGE_TYPE_VPN_CLIENT_USE_IP message from the VPN service.
Definition: vpn_api.c:164
static void send_request(struct GNUNET_VPN_RedirectionRequest *rr)
Add a request to our request queue and transmit it.
Definition: vpn_api.c:238
static void mq_error_handler(void *cls, enum GNUNET_MQ_Error error)
Generic error handler, called with the appropriate error code and the same closure specified at the c...
Definition: vpn_api.c:302
static void reconnect(struct GNUNET_VPN_Handle *vh)
Disconnect from the service (communication error) and reconnect later.
Definition: vpn_api.c:348
static void connect_task(void *cls)
Connect to the VPN service and start again to transmit our requests.
Definition: vpn_api.c:317
static void handle_use_ip(void *cls, const struct RedirectToIpResponseMessage *rm)
Handle a GNUNET_MESSAGE_TYPE_VPN_CLIENT_USE_IP message from the VPN service.
Definition: vpn_api.c:207