GNUnet  0.10.x
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 
73 
78 {
83 
88 
93 
98  const void *addr;
99 
104 
108  void *cb_cls;
109 
114 
118  struct GNUNET_HashCode serv;
119 
123  struct GNUNET_TIME_Absolute expiration_time;
124 
128  uint64_t request_id;
129 
134 
138  int addr_af;
139 
143  uint8_t protocol;
144 
145 };
146 
147 
153 static void
154 reconnect (struct GNUNET_VPN_Handle *vh);
155 
156 
165 static int
166 check_use_ip (void *cls,
167  const struct RedirectToIpResponseMessage *rm)
168 {
169  size_t alen;
170  int af;
171 
172  af = (int) ntohl (rm->result_af);
173  switch (af)
174  {
175  case AF_UNSPEC:
176  alen = 0;
177  break;
178  case AF_INET:
179  alen = sizeof (struct in_addr);
180  break;
181  case AF_INET6:
182  alen = sizeof (struct in6_addr);
183  break;
184  default:
185  GNUNET_break (0);
186  return GNUNET_SYSERR;
187  }
188  if ( (ntohs (rm->header.size) != alen + sizeof (*rm)) ||
189  (0 == rm->request_id) )
190  {
191  GNUNET_break (0);
192  return GNUNET_SYSERR;
193  }
194  return GNUNET_OK;
195 }
196 
197 
205 static void
206 handle_use_ip (void *cls,
207  const struct RedirectToIpResponseMessage *rm)
208 {
209  struct GNUNET_VPN_Handle *vh = cls;
211  int af;
212 
213  af = (int) ntohl (rm->result_af);
214  for (rr = vh->rr_head; NULL != rr; rr = rr->next)
215  {
216  if (rr->request_id == rm->request_id)
217  {
219  vh->rr_tail,
220  rr);
221  rr->cb (rr->cb_cls,
222  af,
223  (af == AF_UNSPEC) ? NULL : &rm[1]);
224  GNUNET_free (rr);
225  break;
226  }
227  }
228 }
229 
230 
236 static void
238 {
239  struct GNUNET_VPN_Handle *vh = rr->vh;
240  struct RedirectToIpRequestMessage *rip;
242  struct GNUNET_MQ_Envelope *env;
243  size_t alen;
244 
245  if (NULL == vh->mq)
246  return;
247  if (NULL == rr->addr)
248  {
249  env = GNUNET_MQ_msg (rs,
251  rs->reserved = htonl (0);
253  rs->protocol = htonl (rr->protocol);
254  rs->result_af = htonl (rr->result_af);
255  rs->target = rr->peer;
256  rs->service_descriptor = rr->serv;
257  rs->request_id = rr->request_id = ++vh->request_id_gen;
258  }
259  else
260  {
261  switch (rr->addr_af)
262  {
263  case AF_INET:
264  alen = sizeof (struct in_addr);
265  break;
266  case AF_INET6:
267  alen = sizeof (struct in6_addr);
268  break;
269  default:
270  GNUNET_assert (0);
271  return;
272  }
273  env = GNUNET_MQ_msg_extra (rip,
274  alen,
276  rip->reserved = htonl (0);
278  rip->result_af = htonl (rr->result_af);
279  rip->addr_af = htonl (rr->addr_af);
280  rip->request_id = rr->request_id = ++vh->request_id_gen;
281  GNUNET_memcpy (&rip[1],
282  rr->addr,
283  alen);
284  }
285  GNUNET_MQ_send (vh->mq,
286  env);
287 }
288 
289 
298 static void
299 mq_error_handler (void *cls,
300  enum GNUNET_MQ_Error error)
301 {
302  struct GNUNET_VPN_Handle *vh = cls;
303 
304  reconnect (vh);
305 }
306 
307 
313 static void
314 connect_task (void *cls)
315 {
316  struct GNUNET_VPN_Handle *vh = cls;
317  struct GNUNET_MQ_MessageHandler handlers[] = {
318  GNUNET_MQ_hd_var_size (use_ip,
321  cls),
323  };
325 
326  vh->rt = NULL;
327  vh->mq = GNUNET_CLIENT_connect (vh->cfg,
328  "vpn",
329  handlers,
331  vh);
332  if (NULL == vh->mq)
333  return;
334  for (rr = vh->rr_head; NULL != rr; rr = rr->next)
335  send_request (rr);
336 }
337 
338 
344 static void
346 {
348 
349  GNUNET_MQ_destroy (vh->mq);
350  vh->mq = NULL;
351  vh->request_id_gen = 0;
352  for (rr = vh->rr_head; NULL != rr; rr = rr->next)
353  rr->request_id = 0;
358  &connect_task,
359  vh);
360 }
361 
362 
368 void
370 {
371  struct GNUNET_VPN_Handle *vh;
372 
373  vh = rr->vh;
375  vh->rr_tail,
376  rr);
377  GNUNET_free (rr);
378 }
379 
380 
405  int result_af,
406  uint8_t protocol,
407  const struct GNUNET_PeerIdentity *peer,
408  const struct GNUNET_HashCode *serv,
411  void *cb_cls)
412 {
414 
416  rr->vh = vh;
417  rr->cb = cb;
418  rr->cb_cls = cb_cls;
419  rr->peer = *peer;
420  rr->serv = *serv;
422  rr->result_af = result_af;
423  rr->protocol = protocol;
425  vh->rr_tail,
426  rr);
427  send_request (rr);
428  return rr;
429 }
430 
431 
456  int result_af,
457  int addr_af,
458  const void *addr,
461  void *cb_cls)
462 {
464  size_t alen;
465 
466  switch (addr_af)
467  {
468  case AF_INET:
469  alen = sizeof (struct in_addr);
470  break;
471  case AF_INET6:
472  alen = sizeof (struct in6_addr);
473  break;
474  default:
475  GNUNET_break (0);
476  return NULL;
477  }
478  rr = GNUNET_malloc (sizeof (struct GNUNET_VPN_RedirectionRequest) + alen);
479  rr->vh = vh;
480  rr->addr = &rr[1];
481  rr->cb = cb;
482  rr->cb_cls = cb_cls;
483  rr->expiration_time = expiration_time;
484  rr->result_af = result_af;
485  rr->addr_af = addr_af;
486  GNUNET_memcpy (&rr[1],
487  addr,
488  alen);
490  vh->rr_tail,
491  rr);
492  send_request (rr);
493  return rr;
494 }
495 
496 
503 struct GNUNET_VPN_Handle *
505 {
506  struct GNUNET_VPN_Handle *vh
507  = GNUNET_new (struct GNUNET_VPN_Handle);
508 
509  vh->cfg = cfg;
510  connect_task (vh);
511  if (NULL == vh->mq)
512  {
513  GNUNET_free (vh);
514  return NULL;
515  }
516  return vh;
517 }
518 
519 
525 void
527 {
528  GNUNET_assert (NULL == vh->rr_head);
529  if (NULL != vh->mq)
530  {
531  GNUNET_MQ_destroy (vh->mq);
532  vh->mq = NULL;
533  }
534  if (NULL != vh->rt)
535  {
537  vh->rt = NULL;
538  }
539  GNUNET_free (vh);
540 }
541 
542 /* end of vpn_api.c */
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
struct GNUNET_HashCode service_descriptor
Service descriptor identifying the service.
Definition: vpn.h:116
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_SCHEDULER_Task * rt
Identifier of a reconnect task.
Definition: vpn_api.c:59
int result_af
Desired address family for the result.
Definition: vpn_api.c:133
uint64_t request_id_gen
ID of the last request that was submitted to the service.
Definition: vpn_api.c:69
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:901
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:166
struct GNUNET_PeerIdentity target
Target peer offering the service.
Definition: vpn.h:111
#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...
struct GNUNET_VPN_RedirectionRequest * next
Element in DLL.
Definition: vpn_api.c:82
GNUNET_MQ_Error
Error codes for the queue.
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:286
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_TIME_UNIT_SECONDS
One second.
struct GNUNET_PeerIdentity peer
For service redirection, identity of the peer offering the service.
Definition: vpn_api.c:113
static void connect_task(void *cls)
Connect to the VPN service and start again to transmit our requests.
Definition: vpn_api.c:314
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
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:206
uint64_t request_id
Unique ID to match the response to a request.
Definition: vpn.h:148
int32_t result_af
Address family desired for the result (AF_INET or AF_INET6 or AF_UNSPEC, in nbo)
Definition: vpn.h:106
#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.
int32_t protocol
Desired protocol (IPPROTO_UDP or IPPROTO_TCP)
Definition: vpn.h:101
uint64_t request_id
non-zero if this request has been sent to the service.
Definition: vpn_api.c:128
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void(* GNUNET_VPN_AllocationCallback)(void *cls, int af, const void *address)
Callback invoked from the VPN service once a redirection is available.
struct GNUNET_MQ_Handle * mq
Connection to VPN service.
Definition: vpn_api.c:44
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_TIME_Absolute expiration_time
At what time should the created service mapping expire?
Definition: vpn_api.c:123
Opaque VPN handle.
Definition: vpn_api.c:34
IPC messages between VPN library and VPN service.
uint32_t reserved
Always zero.
Definition: vpn.h:48
struct GNUNET_TIME_Relative backoff
How long do we wait until we try to reconnect?
Definition: vpn_api.c:64
#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
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:1246
#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)
GNUNET_VPN_AllocationCallback cb
Function to call with the designated IP address.
Definition: vpn_api.c:103
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#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...
int32_t result_af
Address family desired for the result (AF_INET or AF_INET6 or AF_UNSPEC, in nbo)
Definition: vpn.h:58
void GNUNET_VPN_disconnect(struct GNUNET_VPN_Handle *vh)
Disconnect from the VPN service.
Definition: vpn_api.c:526
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:439
A 512-bit hashcode.
#define GNUNET_TIME_UNIT_MILLISECONDS
One millisecond.
Message handler for a specific message type.
void GNUNET_VPN_cancel_request(struct GNUNET_VPN_RedirectionRequest *rr)
Cancel redirection request with the service.
Definition: vpn_api.c:369
struct GNUNET_VPN_RedirectionRequest * rr_tail
Tail of list of active redirection requests.
Definition: vpn_api.c:54
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:404
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:271
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_VPN_CLIENT_USE_IP.
Definition: vpn.h:137
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
int32_t result_af
Address family of the allocated address that follows; will match "result_af" from the request...
Definition: vpn.h:143
Opaque redirection request handle.
Definition: vpn_api.c:77
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
uint32_t reserved
Always zero.
Definition: vpn.h:91
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
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
Handle to a message queue.
Definition: mq.c:85
struct GNUNET_VPN_Handle * GNUNET_VPN_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the VPN service.
Definition: vpn_api.c:504
The identity of the host (wraps the signing key of the peer).
configuration data
Definition: configuration.c:85
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:299
int32_t addr_af
Address family used for the destination address (AF_INET or AF_INET6, in nbo)
Definition: vpn.h:63
static void reconnect(struct GNUNET_VPN_Handle *vh)
Disconnect from the service (communication error) and reconnect later.
Definition: vpn_api.c:345
struct GNUNET_TIME_AbsoluteNBO expiration_time
How long should the redirection be maintained at most?
Definition: vpn.h:53
uint8_t protocol
For service redirection, IPPROT_UDP or IPPROTO_TCP.
Definition: vpn_api.c:143
Entry in list of pending tasks.
Definition: scheduler.c:134
void * cb_cls
Closure for cb.
Definition: vpn_api.c:108
struct GNUNET_VPN_RedirectionRequest * rr_head
Head of list of active redirection requests.
Definition: vpn_api.c:49
struct GNUNET_VPN_RedirectionRequest * prev
Element in DLL.
Definition: vpn_api.c:87
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we use.
Definition: vpn_api.c:39
Time for absolute times used by GNUnet, in microseconds.
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:824
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
int addr_af
Address family of addr.
Definition: vpn_api.c:138
uint64_t request_id
Unique ID to match a future response to this request.
Definition: vpn.h:69
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:654
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:499
struct GNUNET_HashCode serv
For service redirection, service descriptor.
Definition: vpn_api.c:118
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
static void send_request(struct GNUNET_VPN_RedirectionRequest *rr)
Add a request to our request queue and transmit it.
Definition: vpn_api.c:237
#define GNUNET_malloc(size)
Wrapper around malloc.
Message send by the VPN client to the VPN service requesting the setup of a redirection from some IP ...
Definition: vpn.h:81
const void * addr
Target IP address for the redirection, or NULL for redirection to service.
Definition: vpn_api.c:98
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_VPN_Handle * vh
Pointer to the VPN struct.
Definition: vpn_api.c:92
Time for relative time used by GNUnet, in microseconds.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:965
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:455