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 
39 
44 
49 
54 
59 
64 
68  uint64_t request_id_gen;
69 };
70 
71 
80 
85 
90 
95  const void *addr;
96 
101 
105  void *cb_cls;
106 
111 
115  struct GNUNET_HashCode serv;
116 
120  struct GNUNET_TIME_Absolute expiration_time;
121 
125  uint64_t request_id;
126 
131 
135  int addr_af;
136 
140  uint8_t protocol;
141 };
142 
143 
149 static void
150 reconnect(struct GNUNET_VPN_Handle *vh);
151 
152 
161 static int
162 check_use_ip(void *cls,
163  const struct RedirectToIpResponseMessage *rm)
164 {
165  size_t alen;
166  int af;
167 
168  af = (int)ntohl(rm->result_af);
169  switch (af)
170  {
171  case AF_UNSPEC:
172  alen = 0;
173  break;
174 
175  case AF_INET:
176  alen = sizeof(struct in_addr);
177  break;
178 
179  case AF_INET6:
180  alen = sizeof(struct in6_addr);
181  break;
182 
183  default:
184  GNUNET_break(0);
185  return GNUNET_SYSERR;
186  }
187  if ((ntohs(rm->header.size) != alen + sizeof(*rm)) ||
188  (0 == rm->request_id))
189  {
190  GNUNET_break(0);
191  return GNUNET_SYSERR;
192  }
193  return GNUNET_OK;
194 }
195 
196 
204 static void
205 handle_use_ip(void *cls,
206  const struct RedirectToIpResponseMessage *rm)
207 {
208  struct GNUNET_VPN_Handle *vh = cls;
210  int af;
211 
212  af = (int)ntohl(rm->result_af);
213  for (rr = vh->rr_head; NULL != rr; rr = rr->next)
214  {
215  if (rr->request_id == rm->request_id)
216  {
218  vh->rr_tail,
219  rr);
220  rr->cb(rr->cb_cls,
221  af,
222  (af == AF_UNSPEC) ? NULL : &rm[1]);
223  GNUNET_free(rr);
224  break;
225  }
226  }
227 }
228 
229 
235 static void
237 {
238  struct GNUNET_VPN_Handle *vh = rr->vh;
239  struct RedirectToIpRequestMessage *rip;
241  struct GNUNET_MQ_Envelope *env;
242  size_t alen;
243 
244  if (NULL == vh->mq)
245  return;
246  if (NULL == rr->addr)
247  {
248  env = GNUNET_MQ_msg(rs,
250  rs->reserved = htonl(0);
252  rs->protocol = htonl(rr->protocol);
253  rs->result_af = htonl(rr->result_af);
254  rs->target = rr->peer;
255  rs->service_descriptor = rr->serv;
256  rs->request_id = rr->request_id = ++vh->request_id_gen;
257  }
258  else
259  {
260  switch (rr->addr_af)
261  {
262  case AF_INET:
263  alen = sizeof(struct in_addr);
264  break;
265 
266  case AF_INET6:
267  alen = sizeof(struct in6_addr);
268  break;
269 
270  default:
271  GNUNET_assert(0);
272  return;
273  }
274  env = GNUNET_MQ_msg_extra(rip,
275  alen,
277  rip->reserved = htonl(0);
279  rip->result_af = htonl(rr->result_af);
280  rip->addr_af = htonl(rr->addr_af);
281  rip->request_id = rr->request_id = ++vh->request_id_gen;
282  GNUNET_memcpy(&rip[1],
283  rr->addr,
284  alen);
285  }
286  GNUNET_MQ_send(vh->mq,
287  env);
288 }
289 
290 
299 static void
301  enum GNUNET_MQ_Error error)
302 {
303  struct GNUNET_VPN_Handle *vh = cls;
304 
305  reconnect(vh);
306 }
307 
308 
314 static void
315 connect_task(void *cls)
316 {
317  struct GNUNET_VPN_Handle *vh = cls;
318  struct GNUNET_MQ_MessageHandler handlers[] = {
319  GNUNET_MQ_hd_var_size(use_ip,
322  cls),
324  };
326 
327  vh->rt = NULL;
328  vh->mq = GNUNET_CLIENT_connect(vh->cfg,
329  "vpn",
330  handlers,
332  vh);
333  if (NULL == vh->mq)
334  return;
335  for (rr = vh->rr_head; NULL != rr; rr = rr->next)
336  send_request(rr);
337 }
338 
339 
345 static void
347 {
349 
350  GNUNET_MQ_destroy(vh->mq);
351  vh->mq = NULL;
352  vh->request_id_gen = 0;
353  for (rr = vh->rr_head; NULL != rr; rr = rr->next)
354  rr->request_id = 0;
359  &connect_task,
360  vh);
361 }
362 
363 
369 void
371 {
372  struct GNUNET_VPN_Handle *vh;
373 
374  vh = rr->vh;
376  vh->rr_tail,
377  rr);
378  GNUNET_free(rr);
379 }
380 
381 
406  int result_af,
407  uint8_t protocol,
408  const struct GNUNET_PeerIdentity *peer,
409  const struct GNUNET_HashCode *serv,
412  void *cb_cls)
413 {
415 
417  rr->vh = vh;
418  rr->cb = cb;
419  rr->cb_cls = cb_cls;
420  rr->peer = *peer;
421  rr->serv = *serv;
423  rr->result_af = result_af;
424  rr->protocol = protocol;
426  vh->rr_tail,
427  rr);
428  send_request(rr);
429  return rr;
430 }
431 
432 
457  int result_af,
458  int addr_af,
459  const void *addr,
462  void *cb_cls)
463 {
465  size_t alen;
466 
467  switch (addr_af)
468  {
469  case AF_INET:
470  alen = sizeof(struct in_addr);
471  break;
472 
473  case AF_INET6:
474  alen = sizeof(struct in6_addr);
475  break;
476 
477  default:
478  GNUNET_break(0);
479  return NULL;
480  }
481  rr = GNUNET_malloc(sizeof(struct GNUNET_VPN_RedirectionRequest) + alen);
482  rr->vh = vh;
483  rr->addr = &rr[1];
484  rr->cb = cb;
485  rr->cb_cls = cb_cls;
486  rr->expiration_time = expiration_time;
487  rr->result_af = result_af;
488  rr->addr_af = addr_af;
489  GNUNET_memcpy(&rr[1],
490  addr,
491  alen);
493  vh->rr_tail,
494  rr);
495  send_request(rr);
496  return rr;
497 }
498 
499 
506 struct GNUNET_VPN_Handle *
508 {
509  struct GNUNET_VPN_Handle *vh
510  = GNUNET_new(struct GNUNET_VPN_Handle);
511 
512  vh->cfg = cfg;
513  connect_task(vh);
514  if (NULL == vh->mq)
515  {
516  GNUNET_free(vh);
517  return NULL;
518  }
519  return vh;
520 }
521 
522 
528 void
530 {
531  GNUNET_assert(NULL == vh->rr_head);
532  if (NULL != vh->mq)
533  {
534  GNUNET_MQ_destroy(vh->mq);
535  vh->mq = NULL;
536  }
537  if (NULL != vh->rt)
538  {
540  vh->rt = NULL;
541  }
542  GNUNET_free(vh);
543 }
544 
545 /* 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:113
Response from the VPN service to a VPN client informing about the IP that was assigned for the reques...
Definition: vpn.h:127
struct GNUNET_SCHEDULER_Task * rt
Identifier of a reconnect task.
Definition: vpn_api.c:58
int result_af
Desired address family for the result.
Definition: vpn_api.c:130
uint64_t request_id_gen
ID of the last request that was submitted to the service.
Definition: vpn_api.c:68
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:900
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:162
struct GNUNET_PeerIdentity target
Target peer offering the service.
Definition: vpn.h:108
#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:79
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:287
#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:110
static void connect_task(void *cls)
Connect to the VPN service and start again to transmit our requests.
Definition: vpn_api.c:315
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#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:205
uint64_t request_id
Unique ID to match the response to a request.
Definition: vpn.h:142
int32_t result_af
Address family desired for the result (AF_INET or AF_INET6 or AF_UNSPEC, in nbo)
Definition: vpn.h:103
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_new(type)
Allocate a struct or union of the given type.
int32_t protocol
Desired protocol (IPPROTO_UDP or IPPROTO_TCP)
Definition: vpn.h:98
uint64_t request_id
non-zero if this request has been sent to the service.
Definition: vpn_api.c:125
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:43
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:120
Opaque VPN handle.
Definition: vpn_api.c:34
IPC messages between VPN library and VPN service.
uint32_t reserved
Always zero.
Definition: vpn.h:47
struct GNUNET_TIME_Relative backoff
How long do we wait until we try to reconnect?
Definition: vpn_api.c:63
#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:1237
#define GNUNET_MESSAGE_TYPE_VPN_CLIENT_USE_IP
VPN service responds to client with an IP to use for the requested redirection.
GNUNET_VPN_AllocationCallback cb
Function to call with the designated IP address.
Definition: vpn_api.c:100
#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:57
void GNUNET_VPN_disconnect(struct GNUNET_VPN_Handle *vh)
Disconnect from the VPN service.
Definition: vpn_api.c:529
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:440
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:370
struct GNUNET_VPN_RedirectionRequest * rr_tail
Tail of list of active redirection requests.
Definition: vpn_api.c:53
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:405
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:272
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:131
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
int32_t result_af
Address family of the allocated address that follows; will match "result_af" from the request...
Definition: vpn.h:137
Opaque redirection request handle.
Definition: vpn_api.c:75
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
uint32_t reserved
Always zero.
Definition: vpn.h:88
#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:93
uint64_t request_id
Unique ID to match a future response to this request.
Definition: vpn.h:119
Handle to a message queue.
Definition: mq.c:84
struct GNUNET_VPN_Handle * GNUNET_VPN_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the VPN service.
Definition: vpn_api.c:507
The identity of the host (wraps the signing key of the peer).
configuration data
Definition: configuration.c:83
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:300
int32_t addr_af
Address family used for the destination address (AF_INET or AF_INET6, in nbo)
Definition: vpn.h:62
static void reconnect(struct GNUNET_VPN_Handle *vh)
Disconnect from the service (communication error) and reconnect later.
Definition: vpn_api.c:346
struct GNUNET_TIME_AbsoluteNBO expiration_time
How long should the redirection be maintained at most?
Definition: vpn.h:52
uint8_t protocol
For service redirection, IPPROT_UDP or IPPROTO_TCP.
Definition: vpn_api.c:140
Entry in list of pending tasks.
Definition: scheduler.c:131
void * cb_cls
Closure for cb.
Definition: vpn_api.c:105
struct GNUNET_VPN_RedirectionRequest * rr_head
Head of list of active redirection requests.
Definition: vpn_api.c:48
struct GNUNET_VPN_RedirectionRequest * prev
Element in DLL.
Definition: vpn_api.c:84
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we use.
Definition: vpn_api.c:38
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:821
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:351
int addr_af
Address family of addr.
Definition: vpn_api.c:135
uint64_t request_id
Unique ID to match a future response to this request.
Definition: vpn.h:68
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:655
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:115
#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:236
#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:79
const void * addr
Target IP address for the redirection, or NULL for redirection to service.
Definition: vpn_api.c:95
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_VPN_Handle * vh
Pointer to the VPN struct.
Definition: vpn_api.c:89
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:956
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:456