GNUnet 0.21.1
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
70};
71
72
77{
82
87
92
97 const void *addr;
98
103
107 void *cb_cls;
108
113
118
123
127 uint64_t request_id;
128
133
138
142 uint8_t protocol;
143};
144
145
151static void
152reconnect (struct GNUNET_VPN_Handle *vh);
153
154
163static int
164check_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
206static void
207handle_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
237static 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 }
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
301static void
303 enum GNUNET_MQ_Error error)
304{
305 struct GNUNET_VPN_Handle *vh = cls;
306
307 reconnect (vh);
308}
309
310
316static void
317connect_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
347static 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),
365 vh);
366}
367
368
374void
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
489struct 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
511void
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_MessageHandlers handlers[]
Definition: 003.c:1
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:109
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:981
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:1278
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_Handle * GNUNET_VPN_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the VPN service.
Definition: vpn_api.c:490
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
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
void(* GNUNET_VPN_AllocationCallback)(void *cls, int af, const void *address)
Callback invoked from the VPN service once a redirection is available.
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
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