aboutsummaryrefslogtreecommitdiff
path: root/src/vpn/gnunet-service-vpn.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-01-07 01:44:52 +0000
committerChristian Grothoff <christian@grothoff.org>2012-01-07 01:44:52 +0000
commit36006b066f1076707712602359ac84da53d1dffb (patch)
treea7acdb5c1d88c2325c4463362b8d09341c8f0df7 /src/vpn/gnunet-service-vpn.c
parent0a671e8ffbff1cb993a1df595b7d0d87a295b4d3 (diff)
downloadgnunet-36006b066f1076707712602359ac84da53d1dffb.tar.gz
gnunet-36006b066f1076707712602359ac84da53d1dffb.zip
-some more hacking on data structures, documenting open issues
Diffstat (limited to 'src/vpn/gnunet-service-vpn.c')
-rw-r--r--src/vpn/gnunet-service-vpn.c595
1 files changed, 288 insertions, 307 deletions
diff --git a/src/vpn/gnunet-service-vpn.c b/src/vpn/gnunet-service-vpn.c
index 4ce1fab78..8f0236846 100644
--- a/src/vpn/gnunet-service-vpn.c
+++ b/src/vpn/gnunet-service-vpn.c
@@ -27,6 +27,13 @@
27 * @author Christian Grothoff 27 * @author Christian Grothoff
28 * 28 *
29 * TODO: 29 * TODO:
30 * - create tunnels
31 * - implement service message handlers
32 * - build mesh messages
33 * - parse mesh replies
34 * - build IP messages from mesh replies
35 * - fully implement shutdown code
36 * - [implement VPN library]
30 * - add back ICMP support (especially needed for IPv6)o 37 * - add back ICMP support (especially needed for IPv6)o
31 */ 38 */
32#include "platform.h" 39#include "platform.h"
@@ -39,23 +46,20 @@
39#include "tcpip_tun.h" 46#include "tcpip_tun.h"
40 47
41 48
42
43
44/** 49/**
45 * Information we track for each IP address to determine which tunnel 50 * Information we track for each IP address to determine which tunnel
46 * to send the traffic over to the destination. 51 * to send the traffic over to the destination.
47 */ 52 */
48struct map_entry 53struct destination_entry
49{ 54{
50 /** 55 /**
51 * Information about the tunnel to use; the associated tunnel 56 * Information about the tunnel to use, NULL if no tunnel
52 * state gives information about the respective local IP that 57 * is available right now.
53 * this tunnel is used with.
54 */ 58 */
55 struct tunnel_state *ts; 59 struct GNUNET_MESH_Tunnel *tunnel;
56 60
57 /** 61 /**
58 * Entry for this entry in the heap. 62 * Entry for this entry in the destination_heap.
59 */ 63 */
60 struct GNUNET_CONTAINER_HeapNode *heap_node; 64 struct GNUNET_CONTAINER_HeapNode *heap_node;
61 65
@@ -75,7 +79,6 @@ struct map_entry
75 */ 79 */
76 union 80 union
77 { 81 {
78
79 /** 82 /**
80 * The description of the service (only used for service tunnels). 83 * The description of the service (only used for service tunnels).
81 */ 84 */
@@ -97,8 +100,7 @@ struct map_entry
97 struct in6_addr v6; 100 struct in6_addr v6;
98 } ip; 101 } ip;
99 102
100 } destination_details; 103 } details;
101
102 104
103}; 105};
104 106
@@ -141,6 +143,11 @@ struct tunnel_state
141 struct GNUNET_MESH_TransmitHandle *th; 143 struct GNUNET_MESH_TransmitHandle *th;
142 144
143 /** 145 /**
146 * Entry for this entry in the tunnel_heap.
147 */
148 struct GNUNET_CONTAINER_HeapNode *heap_node;
149
150 /**
144 * Head of list of messages scheduled for transmission. 151 * Head of list of messages scheduled for transmission.
145 */ 152 */
146 struct tunnel_notify_queue *head; 153 struct tunnel_notify_queue *head;
@@ -151,15 +158,18 @@ struct tunnel_state
151 struct tunnel_notify_queue *tail; 158 struct tunnel_notify_queue *tail;
152 159
153 /** 160 /**
154 * Tunnel for which this is the state. 161 * Destination to which this tunnel leads. Note that
162 * this struct is NOT in the destination_map (but a
163 * local copy) and that the 'heap_node' should always
164 * be NULL.
155 */ 165 */
156 struct GNUNET_MESH_Tunnel *tunnel; 166 struct destination_entry destination;
157 167
158 /** 168 /**
159 * Address family used on our side of this tunnel 169 * GNUNET_NO if this is a tunnel to an Internet-exit,
160 * (AF_INET or AF_INET6). 170 * GNUNET_YES if this tunnel is to a service.
161 */ 171 */
162 int af; 172 int is_service;
163 173
164 /** 174 /**
165 * IP address of the source on our end. 175 * IP address of the source on our end.
@@ -179,10 +189,32 @@ struct tunnel_state
179 } source_ip; 189 } source_ip;
180 190
181 /** 191 /**
182 * Source port used by the sender. 192 * Destination IP address used by the source on our end.
193 */
194 union
195 {
196 /**
197 * Address if af is AF_INET.
198 */
199 struct in_addr v4;
200
201 /**
202 * Address if af is AF_INET6.
203 */
204 struct in6_addr v6;
205
206 } destination_ip;
207
208 /**
209 * Source port used by the sender on our end.
183 */ 210 */
184 uint16_t source_port; 211 uint16_t source_port;
185 212
213 /**
214 * Destination port used by the sender on our end.
215 */
216 uint16_t destination_port;
217
186}; 218};
187 219
188 220
@@ -197,15 +229,26 @@ static const struct GNUNET_CONFIGURATION_Handle *cfg;
197static struct GNUNET_MESH_Handle *mesh_handle; 229static struct GNUNET_MESH_Handle *mesh_handle;
198 230
199/** 231/**
200 * Map from IP address to connection information (mostly with 232 * Map from IP address to destination information (possibly with a
201 * the respective MESH tunnel handle). 233 * MESH tunnel handle for fast setup).
202 */ 234 */
203static struct GNUNET_CONTAINER_MultiHashMap *hashmap; 235static struct GNUNET_CONTAINER_MultiHashMap *destination_map;
204 236
205/** 237/**
206 * Min-Heap sorted by activity time to expire old mappings. 238 * Min-Heap sorted by activity time to expire old mappings.
207 */ 239 */
208static struct GNUNET_CONTAINER_Heap *heap; 240static struct GNUNET_CONTAINER_Heap *destination_heap;
241
242/**
243 * Map from source and destination address (IP+port) to connection
244 * information (mostly with the respective MESH tunnel handle).
245 */
246static struct GNUNET_CONTAINER_MultiHashMap *tunnel_map;
247
248/**
249 * Min-Heap sorted by activity time to expire old mappings.
250 */
251static struct GNUNET_CONTAINER_Heap *tunnel_heap;
209 252
210/** 253/**
211 * The handle to the VPN helper process "gnunet-helper-vpn". 254 * The handle to the VPN helper process "gnunet-helper-vpn".
@@ -221,21 +264,27 @@ static char *vpn_argv[7];
221 * If there are more than this number of address-mappings, old ones 264 * If there are more than this number of address-mappings, old ones
222 * will be removed 265 * will be removed
223 */ 266 */
224static unsigned long long max_mappings; 267static unsigned long long max_destination_mappings;
268
269/**
270 * If there are more than this number of open tunnels, old ones
271 * will be removed
272 */
273static unsigned long long max_tunnel_mappings;
225 274
226 275
227/** 276/**
228 * Compute the key under which we would store an entry in the 277 * Compute the key under which we would store an entry in the
229 * map for the given IP address. 278 * destination_map for the given IP address.
230 * 279 *
231 * @param af address family (AF_INET or AF_INET6) 280 * @param af address family (AF_INET or AF_INET6)
232 * @param address IP address, struct in_addr or struct in6_addr 281 * @param address IP address, struct in_addr or struct in6_addr
233 * @param key where to store the key 282 * @param key where to store the key
234 */ 283 */
235static void 284static void
236get_key_from_ip (int af, 285get_destination_key_from_ip (int af,
237 const void *address, 286 const void *address,
238 GNUNET_HashCode *key) 287 GNUNET_HashCode *key)
239{ 288{
240 switch (af) 289 switch (af)
241 { 290 {
@@ -257,6 +306,60 @@ get_key_from_ip (int af,
257 306
258 307
259/** 308/**
309 * Compute the key under which we would store an entry in the
310 * tunnel_map for the given socket address pair.
311 *
312 * @param af address family (AF_INET or AF_INET6)
313 * @param protocol IPPROTO_TCP or IPPROTO_UDP
314 * @param source_ip sender's source IP, struct in_addr or struct in6_addr
315 * @param source_port sender's source port
316 * @param destination_ip sender's destination IP, struct in_addr or struct in6_addr
317 * @param destination_port sender's destination port
318 * @param key where to store the key
319 */
320static void
321get_tunnel_key_from_ips (int af,
322 uint8_t protocol,
323 const void *source_ip,
324 uint16_t source_port,
325 const void *destination_ip,
326 uint16_t destination_port,
327 GNUNET_HashCode *key)
328{
329 char *off;
330
331 memset (key, 0, sizeof (GNUNET_HashCode));
332 /* the GNUnet hashmap only uses the first sizeof(unsigned int) of the hash,
333 so we put the ports in there (and hope for few collisions) */
334 off = (char*) key;
335 memcpy (off, &source_port, sizeof (uint16_t));
336 off += sizeof (uint16_t);
337 memcpy (off, &destination_port, sizeof (uint16_t));
338 off += sizeof (uint16_t);
339 switch (af)
340 {
341 case AF_INET:
342 memcpy (off, source_ip, sizeof (struct in_addr));
343 off += sizeof (struct in_addr);
344 memcpy (off, destination_ip, sizeof (struct in_addr));
345 off += sizeof (struct in_addr);
346 break;
347 case AF_INET6:
348 memcpy (off, source_ip, sizeof (struct in6_addr));
349 off += sizeof (struct in6_addr);
350 memcpy (off, destination_ip, sizeof (struct in6_addr));
351 off += sizeof (struct in6_addr);
352 break;
353 default:
354 GNUNET_assert (0);
355 break;
356 }
357 memcpy (off, &protocol, sizeof (uint8_t));
358 off += sizeof (uint8_t);
359}
360
361
362/**
260 * Send a message from the message queue via mesh. 363 * Send a message from the message queue via mesh.
261 * 364 *
262 * @param cls the 'struct tunnel_state' with the message queue 365 * @param cls the 'struct tunnel_state' with the message queue
@@ -284,7 +387,7 @@ send_to_peer_notify_callback (void *cls, size_t size, void *buf)
284 ret = tnq->len; 387 ret = tnq->len;
285 GNUNET_free (tnq); 388 GNUNET_free (tnq);
286 if (NULL != (tnq = ts->head)) 389 if (NULL != (tnq = ts->head))
287 ts->th = GNUNET_MESH_notify_transmit_ready (ts->tunnel, 390 ts->th = GNUNET_MESH_notify_transmit_ready (ts->destination.tunnel,
288 GNUNET_NO /* cork */, 391 GNUNET_NO /* cork */,
289 42 /* priority */, 392 42 /* priority */,
290 GNUNET_TIME_UNIT_FOREVER_REL, 393 GNUNET_TIME_UNIT_FOREVER_REL,
@@ -303,15 +406,15 @@ send_to_peer_notify_callback (void *cls, size_t size, void *buf)
303 * @param tnq message to queue 406 * @param tnq message to queue
304 * @param ts tunnel to queue the message for 407 * @param ts tunnel to queue the message for
305 */ 408 */
306/* static */ void 409static void
307send_to_to_tunnel (struct tunnel_notify_queue *tnq, 410send_to_tunnel (struct tunnel_notify_queue *tnq,
308 struct tunnel_state *ts) 411 struct tunnel_state *ts)
309{ 412{
310 GNUNET_CONTAINER_DLL_insert_tail (ts->head, 413 GNUNET_CONTAINER_DLL_insert_tail (ts->head,
311 ts->tail, 414 ts->tail,
312 tnq); 415 tnq);
313 if (NULL == ts->th) 416 if (NULL == ts->th)
314 ts->th = GNUNET_MESH_notify_transmit_ready (ts->tunnel, 417 ts->th = GNUNET_MESH_notify_transmit_ready (ts->destination.tunnel,
315 GNUNET_NO /* cork */, 418 GNUNET_NO /* cork */,
316 42 /* priority */, 419 42 /* priority */,
317 GNUNET_TIME_UNIT_FOREVER_REL, 420 GNUNET_TIME_UNIT_FOREVER_REL,
@@ -323,71 +426,86 @@ send_to_to_tunnel (struct tunnel_notify_queue *tnq,
323 426
324 427
325/** 428/**
326 * Route a packet via mesh to the given destination. Note that 429 * Route a packet via mesh to the given destination.
327 * the source IP may NOT be the one that the tunnel state
328 * of the given destination is associated with. If the tunnel
329 * state is unassociated or identical, it should be used; if
330 * not, a fresh tunnel YUCK...
331 * 430 *
332 * @param destination description of the destination 431 * @param destination description of the destination
333 * @param af address family on this end (AF_INET or AF_INET6) 432 * @param af address family on this end (AF_INET or AF_INET6)
334 * @param protocol IPPROTO_TCP or IPPROTO_UDP 433 * @param protocol IPPROTO_TCP or IPPROTO_UDP
335 * @param source_ip source IP used by the sender (struct in_addr or struct in6_addr) 434 * @param source_ip source IP used by the sender (struct in_addr or struct in6_addr)
435 * @param destination_ip destination IP used by the sender (struct in_addr or struct in6_addr)
336 * @param payload payload of the packet after the IP header 436 * @param payload payload of the packet after the IP header
337 * @param payload_length number of bytes in payload 437 * @param payload_length number of bytes in payload
338 */ 438 */
339static void 439static void
340route_packet (struct map_entry *destination, 440route_packet (struct destination_entry *destination,
341 int af, 441 int af,
342 uint8_t protocol, 442 uint8_t protocol,
343 const void *source_ip, 443 const void *source_ip,
444 const void *destination_ip,
344 const void *payload, 445 const void *payload,
345 size_t payload_length) 446 size_t payload_length)
346{ 447{
347#if 0 448 GNUNET_HashCode key;
348 // FIXME... 449 struct tunnel_state *ts;
450 struct tunnel_notify_queue *tnq;
451
452 switch (protocol)
453 {
454 case IPPROTO_UDP:
455 {
456 const struct udp_packet *udp;
349 457
350 switch (pkt6->nxthdr) 458 if (payload_length < sizeof (struct udp_packet))
351 { 459 {
352 case IPPROTO_UDP: 460 /* blame kernel? */
353 pkt6_udp = (struct ip6_udp *) pkt6; 461 GNUNET_break (0);
354 /* Send dns-packets to the service-dns */ 462 return;
355 /* fall through */ 463 }
356 case IPPROTO_TCP: 464 udp = payload;
357 pkt6_tcp = (struct ip6_tcp *) pkt6; 465 get_tunnel_key_from_ips (af,
358 466 IPPROTO_UDP,
359 if ((key = address6_mapping_exists (&pkt6->ip6_hdr.dadr)) != NULL) 467 source_ip,
360 { 468 ntohs (udp->spt),
361 struct map_entry *me = GNUNET_CONTAINER_multihashmap_get (hashmap, key); 469 destination_ip,
362 470 ntohs (udp->dpt),
363 GNUNET_assert (me != NULL); 471 &key);
364 GNUNET_free (key); 472 }
365 473 break;
366 size_t size = 474 case IPPROTO_TCP:
367 sizeof (struct GNUNET_MESH_Tunnel *) + 475 {
368 sizeof (struct GNUNET_MessageHeader) + sizeof (GNUNET_HashCode) + 476 const struct tcp_packet *tcp;
369 ntohs (pkt6->ip6_hdr.paylgth);
370
371 struct GNUNET_MESH_Tunnel **cls = GNUNET_malloc (size);
372 struct GNUNET_MessageHeader *hdr =
373 (struct GNUNET_MessageHeader *) (cls + 1);
374 GNUNET_HashCode *hc = (GNUNET_HashCode *) (hdr + 1);
375
376 hdr->size =
377 htons (sizeof (struct GNUNET_MessageHeader) +
378 sizeof (GNUNET_HashCode) + ntohs (pkt6->ip6_hdr.paylgth));
379
380 GNUNET_MESH_ApplicationType app_type = 0; /* fix compiler uninitialized warning... */
381 477
382 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "me->addrlen is %d\n", 478 if (payload_length < sizeof (struct tcp_packet))
383 me->addrlen); 479 {
384 if (me->addrlen == 0) 480 /* blame kernel? */
385 { 481 GNUNET_break (0);
386 /* This is a mapping to a gnunet-service */ 482 return;
387 *hc = me->desc; 483 }
484 tcp = payload;
485 get_tunnel_key_from_ips (af,
486 IPPROTO_TCP,
487 source_ip,
488 ntohs (tcp->spt),
489 destination_ip,
490 ntohs (tcp->dpt),
491 &key);
492 }
493 break;
494 default:
495 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
496 _("Protocol %u not supported, dropping\n"),
497 (unsigned int) protocol);
498 return;
499 }
388 500
389 if (me->tunnel == NULL && NULL != cls) 501 /* find tunnel */
390 { 502 ts = GNUNET_CONTAINER_multihashmap_get (tunnel_map,
503 &key);
504 if (NULL == ts)
505 {
506 /* create new tunnel */
507 // FIXME: create tunnel!
508#if 0
391 *cls = 509 *cls =
392 GNUNET_MESH_tunnel_create (mesh_handle, 510 GNUNET_MESH_tunnel_create (mesh_handle,
393 initialize_tunnel_state (16, NULL), 511 initialize_tunnel_state (16, NULL),
@@ -397,88 +515,51 @@ route_packet (struct map_entry *destination,
397 (struct GNUNET_PeerIdentity *) 515 (struct GNUNET_PeerIdentity *)
398 &me->desc); 516 &me->desc);
399 me->tunnel = *cls; 517 me->tunnel = *cls;
400 }
401 else if (NULL != cls)
402 {
403 *cls = me->tunnel;
404 send_pkt_to_peer (cls, (struct GNUNET_PeerIdentity *) 1, NULL);
405 }
406 }
407 else
408 {
409 /* This is a mapping to a "real" address */
410 struct remote_addr *s = (struct remote_addr *) hc;
411
412 s->addrlen = me->addrlen;
413 memcpy (s->addr, me->addr, me->addrlen);
414 s->proto = pkt6->ip6_hdr.nxthdr;
415 if (s->proto == IPPROTO_UDP)
416 {
417 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_REMOTE_UDP);
418 memcpy (hc + 1, &pkt6_udp->udp_hdr, ntohs (pkt6_udp->udp_hdr.len));
419 app_type = GNUNET_APPLICATION_TYPE_INTERNET_UDP_GATEWAY;
420 }
421 else if (s->proto == IPPROTO_TCP)
422 {
423 hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_REMOTE_TCP);
424 memcpy (hc + 1, &pkt6_tcp->tcp_hdr, ntohs (pkt6->ip6_hdr.paylgth));
425 app_type = GNUNET_APPLICATION_TYPE_INTERNET_TCP_GATEWAY;
426 }
427 else
428 {
429 GNUNET_assert (0);
430 }
431 if (me->tunnel == NULL && NULL != cls)
432 {
433 *cls =
434 GNUNET_MESH_tunnel_create (mesh_handle,
435 initialize_tunnel_state (16, NULL),
436 &send_pkt_to_peer, NULL, cls);
437
438 GNUNET_MESH_peer_request_connect_by_type (*cls, app_type);
439 me->tunnel = *cls;
440 }
441 else if (NULL != cls)
442 {
443 *cls = me->tunnel;
444 send_pkt_to_peer (cls, (struct GNUNET_PeerIdentity *) 1, NULL);
445 }
446 }
447 }
448 else
449 {
450 char pbuf[INET6_ADDRSTRLEN];
451 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
452 "Packet to %s, which has no mapping\n",
453 inet_ntop (AF_INET6,
454 &pkt6->ip6_hdr.dadr,
455 pbuf,
456 sizeof (pbuf)));
457 }
458 break;
459
460 case 0x3a:
461 /* ICMPv6 */
462 pkt6_icmp = (struct ip6_icmp *) pkt6;
463 /* If this packet is an icmp-echo-request and a mapping exists, answer */
464 if (pkt6_icmp->icmp_hdr.type == 0x80 &&
465 (key = address6_mapping_exists (&pkt6->ip6_hdr.dadr)) != NULL)
466 {
467 GNUNET_free (key);
468 pkt6_icmp = GNUNET_malloc (ntohs (pkt6->shdr.size));
469 memcpy (pkt6_icmp, pkt6, ntohs (pkt6->shdr.size));
470 GNUNET_SCHEDULER_add_now (&send_icmp6_response, pkt6_icmp);
471 }
472 break;
473 }
474#endif 518#endif
519 }
520
521 /* send via tunnel */
522 switch (protocol)
523 {
524 case IPPROTO_UDP:
525 if (destination->is_service)
526 {
527 tnq = GNUNET_malloc (sizeof (struct tunnel_notify_queue) + 42);
528 // FIXME: build message!
529 }
530 else
531 {
532 tnq = GNUNET_malloc (sizeof (struct tunnel_notify_queue) + 42);
533 // FIXME: build message!
534 }
535 break;
536 case IPPROTO_TCP:
537 if (destination->is_service)
538 {
539 tnq = GNUNET_malloc (sizeof (struct tunnel_notify_queue) + 42);
540 // FIXME: build message!
541 }
542 else
543 {
544 tnq = GNUNET_malloc (sizeof (struct tunnel_notify_queue) + 42);
545 // FIXME: build message!
546 }
547 break;
548 default:
549 /* not supported above, how can we get here !? */
550 GNUNET_assert (0);
551 break;
552 }
553 send_to_tunnel (tnq, ts);
475} 554}
476 555
477 556
478 557
479/** 558/**
480 * Receive packets from the helper-process, identify the 559 * Receive packets from the helper-process (someone send to the local
481 * correct tunnel and forward them on. 560 * virtual tunnel interface). Find the destination mapping, and if it
561 * exists, identify the correct MESH tunnel (or possibly create it)
562 * and forward the packet.
482 * 563 *
483 * @param cls closure, NULL 564 * @param cls closure, NULL
484 * @param client NULL 565 * @param client NULL
@@ -491,7 +572,7 @@ message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED,
491 const struct tun_header *tun; 572 const struct tun_header *tun;
492 size_t mlen; 573 size_t mlen;
493 GNUNET_HashCode key; 574 GNUNET_HashCode key;
494 struct map_entry *me; 575 struct destination_entry *de;
495 576
496 mlen = ntohs (message->size); 577 mlen = ntohs (message->size);
497 if ( (ntohs (message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) || 578 if ( (ntohs (message->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) ||
@@ -515,12 +596,12 @@ message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED,
515 return; 596 return;
516 } 597 }
517 pkt6 = (const struct ip6_header *) &tun[1]; 598 pkt6 = (const struct ip6_header *) &tun[1];
518 get_key_from_ip (AF_INET6, 599 get_destination_key_from_ip (AF_INET6,
519 &pkt6->destination_address, 600 &pkt6->destination_address,
520 &key); 601 &key);
521 me = GNUNET_CONTAINER_multihashmap_get (hashmap, &key); 602 de = GNUNET_CONTAINER_multihashmap_get (destination_map, &key);
522 /* FIXME: do we need to guard against hash collision? */ 603 /* FIXME: do we need to guard against hash collision? */
523 if (NULL == me) 604 if (NULL == de)
524 { 605 {
525 char buf[INET6_ADDRSTRLEN]; 606 char buf[INET6_ADDRSTRLEN];
526 607
@@ -532,10 +613,11 @@ message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED,
532 sizeof (buf))); 613 sizeof (buf)));
533 return; 614 return;
534 } 615 }
535 route_packet (me, 616 route_packet (de,
536 AF_INET6, 617 AF_INET6,
537 pkt6->next_header, 618 pkt6->next_header,
538 &pkt6->source_address, 619 &pkt6->source_address,
620 &pkt6->destination_address,
539 &pkt6[1], 621 &pkt6[1],
540 mlen - sizeof (struct ip6_header)); 622 mlen - sizeof (struct ip6_header));
541 } 623 }
@@ -551,12 +633,12 @@ message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED,
551 return; 633 return;
552 } 634 }
553 pkt4 = (struct ip4_header *) &tun[1]; 635 pkt4 = (struct ip4_header *) &tun[1];
554 get_key_from_ip (AF_INET, 636 get_destination_key_from_ip (AF_INET,
555 &pkt4->destination_address, 637 &pkt4->destination_address,
556 &key); 638 &key);
557 me = GNUNET_CONTAINER_multihashmap_get (hashmap, &key); 639 de = GNUNET_CONTAINER_multihashmap_get (destination_map, &key);
558 /* FIXME: do we need to guard against hash collision? */ 640 /* FIXME: do we need to guard against hash collision? */
559 if (NULL == me) 641 if (NULL == de)
560 { 642 {
561 char buf[INET_ADDRSTRLEN]; 643 char buf[INET_ADDRSTRLEN];
562 644
@@ -574,10 +656,11 @@ message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED,
574 _("Received IPv4 packet with options (dropping it)\n")); 656 _("Received IPv4 packet with options (dropping it)\n"));
575 return; 657 return;
576 } 658 }
577 route_packet (me, 659 route_packet (de,
578 AF_INET, 660 AF_INET,
579 pkt4->protocol, 661 pkt4->protocol,
580 &pkt4->source_address, 662 &pkt4->source_address,
663 &pkt4->destination_address,
581 &pkt4[1], 664 &pkt4[1],
582 mlen - sizeof (struct ip4_header)); 665 mlen - sizeof (struct ip4_header));
583 } 666 }
@@ -591,143 +674,18 @@ message_token (void *cls GNUNET_UNUSED, void *client GNUNET_UNUSED,
591} 674}
592 675
593 676
594#if 0
595
596
597/** 677/**
598 * Create a new Address from an answer-packet 678 * We got a UDP packet back from the MESH tunnel. Pass it on to the
599 */ 679 * local virtual interface via the helper.
600static void 680 *
601new_ip6addr (struct in6_addr *v6addr, 681 * @param cls closure, NULL
602 const GNUNET_HashCode * peer, 682 * @param tunnel connection to the other end
603 const GNUNET_HashCode * service_desc) 683 * @param tunnel_ctx pointer to our 'struct TunnelState *'
604{ /* {{{ */ 684 * @param sender who sent the message
605 unsigned char *buf = (unsigned char*) v6addr; 685 * @param message the actual message
606 char *ipv6addr; 686 * @param atsi performance data for the connection
607 unsigned long long ipv6prefix; 687 * @return GNUNET_OK to keep the connection open,
608 688 * GNUNET_SYSERR to close it (signal serious error)
609 GNUNET_assert (GNUNET_OK ==
610 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6ADDR",
611 &ipv6addr));
612 GNUNET_assert (GNUNET_OK ==
613 GNUNET_CONFIGURATION_get_value_number (cfg, "vpn",
614 "IPV6PREFIX",
615 &ipv6prefix));
616 GNUNET_assert (ipv6prefix < 127);
617 ipv6prefix = (ipv6prefix + 7) / 8;
618
619 inet_pton (AF_INET6, ipv6addr, buf);
620 GNUNET_free (ipv6addr);
621
622 int peer_length = 16 - ipv6prefix - 6;
623
624 if (peer_length <= 0)
625 peer_length = 0;
626
627 int service_length = 16 - ipv6prefix - peer_length;
628
629 if (service_length <= 0)
630 service_length = 0;
631
632 memcpy (buf + ipv6prefix, service_desc, service_length);
633 memcpy (buf + ipv6prefix + service_length, peer, peer_length);
634}
635
636/*}}}*/
637
638
639/**
640 * Create a new Address from an answer-packet
641 */
642static void
643new_ip6addr_remote (struct in6_addr *v6addr,
644 unsigned char *addr, char addrlen)
645{ /* {{{ */
646 unsigned char *buf = (unsigned char*) v6addr;
647 char *ipv6addr;
648 unsigned long long ipv6prefix;
649
650 GNUNET_assert (GNUNET_OK ==
651 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV6ADDR",
652 &ipv6addr));
653 GNUNET_assert (GNUNET_OK ==
654 GNUNET_CONFIGURATION_get_value_number (cfg, "vpn",
655 "IPV6PREFIX",
656 &ipv6prefix));
657 GNUNET_assert (ipv6prefix < 127);
658 ipv6prefix = (ipv6prefix + 7) / 8;
659
660 inet_pton (AF_INET6, ipv6addr, buf);
661 GNUNET_free (ipv6addr);
662
663 int local_length = 16 - ipv6prefix;
664
665 memcpy (buf + ipv6prefix, addr, GNUNET_MIN (addrlen, local_length));
666}
667
668/*}}}*/
669
670/**
671 * Create a new Address from an answer-packet
672 */
673static void
674new_ip4addr_remote (unsigned char *buf, unsigned char *addr, char addrlen)
675{ /* {{{ */
676 char *ipv4addr;
677 char *ipv4mask;
678
679 GNUNET_assert (GNUNET_OK ==
680 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4ADDR",
681 &ipv4addr));
682 GNUNET_assert (GNUNET_OK ==
683 GNUNET_CONFIGURATION_get_value_string (cfg, "vpn", "IPV4MASK",
684 &ipv4mask));
685 uint32_t mask;
686
687 inet_pton (AF_INET, ipv4addr, buf);
688 int r = inet_pton (AF_INET, ipv4mask, &mask);
689
690 mask = htonl (mask);
691 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "inet_pton: %d; %m; mask: %08x\n", r,
692 mask);
693
694 GNUNET_free (ipv4addr);
695
696 int c;
697
698 if (mask)
699 {
700 mask = (mask ^ (mask - 1)) >> 1;
701 for (c = 0; mask; c++)
702 {
703 mask >>= 1;
704 }
705 }
706 else
707 {
708 c = CHAR_BIT * sizeof (mask);
709 }
710
711 c = 32 - c;
712 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "The mask %s has %d leading 1s.\n",
713 ipv4mask, c);
714
715 GNUNET_free (ipv4mask);
716
717 if (c % 8 == 0)
718 c = c / 8;
719 else
720 GNUNET_assert (0);
721
722 memcpy (buf + c, addr, GNUNET_MIN (addrlen, 4 - c));
723}
724
725#endif
726
727
728
729/**
730 * FIXME: document.
731 */ 689 */
732static int 690static int
733receive_udp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, 691receive_udp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
@@ -735,6 +693,7 @@ receive_udp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
735 const struct GNUNET_MessageHeader *message, 693 const struct GNUNET_MessageHeader *message,
736 const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED) 694 const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
737{ 695{
696 // FIXME: parse message, build IP packet, give to TUN!
738#if 0 697#if 0
739 GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1); 698 GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1);
740 struct remote_addr *s = (struct remote_addr *) desc; 699 struct remote_addr *s = (struct remote_addr *) desc;
@@ -903,7 +862,17 @@ receive_udp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
903 862
904 863
905/** 864/**
906 * FIXME: document. 865 * We got a TCP packet back from the MESH tunnel. Pass it on to the
866 * local virtual interface via the helper.
867 *
868 * @param cls closure, NULL
869 * @param tunnel connection to the other end
870 * @param tunnel_ctx pointer to our 'struct TunnelState *'
871 * @param sender who sent the message
872 * @param message the actual message
873 * @param atsi performance data for the connection
874 * @return GNUNET_OK to keep the connection open,
875 * GNUNET_SYSERR to close it (signal serious error)
907 */ 876 */
908static int 877static int
909receive_tcp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, 878receive_tcp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
@@ -912,6 +881,7 @@ receive_tcp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
912 const struct GNUNET_MessageHeader *message, 881 const struct GNUNET_MessageHeader *message,
913 const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED) 882 const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
914{ 883{
884 // FIXME: parse message, build IP packet, give to TUN!
915#if 0 885#if 0
916 GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1); 886 GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1);
917 struct remote_addr *s = (struct remote_addr *) desc; 887 struct remote_addr *s = (struct remote_addr *) desc;
@@ -1129,6 +1099,7 @@ cleanup (void *cls GNUNET_UNUSED,
1129{ 1099{
1130 unsigned int i; 1100 unsigned int i;
1131 1101
1102 // FIXME: clean up heaps and maps!
1132 if (mesh_handle != NULL) 1103 if (mesh_handle != NULL)
1133 { 1104 {
1134 GNUNET_MESH_disconnect (mesh_handle); 1105 GNUNET_MESH_disconnect (mesh_handle);
@@ -1176,13 +1147,20 @@ run (void *cls,
1176 unsigned long long ipv6prefix; 1147 unsigned long long ipv6prefix;
1177 1148
1178 cfg = cfg_; 1149 cfg = cfg_;
1179 hashmap = GNUNET_CONTAINER_multihashmap_create (65536);
1180 heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
1181
1182 if (GNUNET_OK != 1150 if (GNUNET_OK !=
1183 GNUNET_CONFIGURATION_get_value_number (cfg, "vpn", "MAX_MAPPING", 1151 GNUNET_CONFIGURATION_get_value_number (cfg, "vpn", "MAX_MAPPING",
1184 &max_mappings)) 1152 &max_destination_mappings))
1185 max_mappings = 200; 1153 max_destination_mappings = 200;
1154 if (GNUNET_OK !=
1155 GNUNET_CONFIGURATION_get_value_number (cfg, "vpn", "MAX_TUNNELS",
1156 &max_tunnel_mappings))
1157 max_tunnel_mappings = 200;
1158
1159 destination_map = GNUNET_CONTAINER_multihashmap_create (max_destination_mappings * 2);
1160 destination_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
1161 tunnel_map = GNUNET_CONTAINER_multihashmap_create (max_tunnel_mappings * 2);
1162 tunnel_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
1163
1186 1164
1187 vpn_argv[0] = GNUNET_strdup ("vpn-gnunet"); 1165 vpn_argv[0] = GNUNET_strdup ("vpn-gnunet");
1188 if (GNUNET_SYSERR == 1166 if (GNUNET_SYSERR ==
@@ -1255,6 +1233,9 @@ run (void *cls,
1255 &tunnel_cleaner, 1233 &tunnel_cleaner,
1256 handlers, 1234 handlers,
1257 types); 1235 types);
1236 // FIXME: register service handlers to allow destination mappings to
1237 // be created!
1238
1258 helper_handle = GNUNET_HELPER_start ("gnunet-helper-vpn", vpn_argv, 1239 helper_handle = GNUNET_HELPER_start ("gnunet-helper-vpn", vpn_argv,
1259 &message_token, NULL); 1240 &message_token, NULL);
1260 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls); 1241 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, cls);