aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-01-10 22:29:03 +0000
committerChristian Grothoff <christian@grothoff.org>2012-01-10 22:29:03 +0000
commitf1a1df54b3f8e8bfde67df67dcc59e9135110fca (patch)
treeb807e51a32a6de2266fb044af8cc010248be9242 /src
parent894248a687a4c5e63de96a58026bf275a10339a0 (diff)
downloadgnunet-f1a1df54b3f8e8bfde67df67dcc59e9135110fca.tar.gz
gnunet-f1a1df54b3f8e8bfde67df67dcc59e9135110fca.zip
-towards having mesh messages in VPN
Diffstat (limited to 'src')
-rw-r--r--src/vpn/Makefile.am2
-rw-r--r--src/vpn/gnunet-service-vpn.c338
2 files changed, 219 insertions, 121 deletions
diff --git a/src/vpn/Makefile.am b/src/vpn/Makefile.am
index 28eb86b7d..857232a99 100644
--- a/src/vpn/Makefile.am
+++ b/src/vpn/Makefile.am
@@ -54,6 +54,8 @@ gnunet_service_vpn_LDADD = \
54 $(top_builddir)/src/util/libgnunetutil.la \ 54 $(top_builddir)/src/util/libgnunetutil.la \
55 $(top_builddir)/src/mesh/libgnunetmesh.la \ 55 $(top_builddir)/src/mesh/libgnunetmesh.la \
56 $(GN_LIBINTL) 56 $(GN_LIBINTL)
57gnunet_service_vpn_CFLAGS = \
58 -I$(top_srcdir)/src/exit $(CFLAGS)
57 59
58gnunet_daemon_exit_SOURCES = \ 60gnunet_daemon_exit_SOURCES = \
59 gnunet-daemon-exit.c 61 gnunet-daemon-exit.c
diff --git a/src/vpn/gnunet-service-vpn.c b/src/vpn/gnunet-service-vpn.c
index f405bab78..db0a4f2be 100644
--- a/src/vpn/gnunet-service-vpn.c
+++ b/src/vpn/gnunet-service-vpn.c
@@ -27,7 +27,6 @@
27 * @author Christian Grothoff 27 * @author Christian Grothoff
28 * 28 *
29 * TODO: 29 * TODO:
30 * - define mesh message formats between VPN and EXIT!
31 * - build mesh messages 30 * - build mesh messages
32 * - parse mesh replies 31 * - parse mesh replies
33 * - build IP messages from mesh replies 32 * - build IP messages from mesh replies
@@ -46,7 +45,7 @@
46#include "gnunet_constants.h" 45#include "gnunet_constants.h"
47#include "tcpip_tun.h" 46#include "tcpip_tun.h"
48#include "vpn.h" 47#include "vpn.h"
49 48#include "exit.h"
50 49
51/** 50/**
52 * Information we track for each IP address to determine which tunnel 51 * Information we track for each IP address to determine which tunnel
@@ -405,6 +404,99 @@ get_tunnel_key_from_ips (int af,
405 404
406 405
407/** 406/**
407 * Notify the client about the result of its request.
408 *
409 * @param client client to notify
410 * @param request_id original request ID to include in response
411 * @param result_af resulting address family
412 * @param addr resulting IP address
413 */
414static void
415send_client_reply (struct GNUNET_SERVER_Client *client,
416 uint64_t request_id,
417 int result_af,
418 const void *addr)
419{
420 char buf[sizeof (struct RedirectToIpResponseMessage) + sizeof (struct in6_addr)];
421 struct RedirectToIpResponseMessage *res;
422 size_t rlen;
423
424 switch (result_af)
425 {
426 case AF_INET:
427 rlen = sizeof (struct in_addr);
428 break;
429 case AF_INET6:
430 rlen = sizeof (struct in6_addr);
431 break;
432 case AF_UNSPEC:
433 rlen = 0;
434 break;
435 default:
436 GNUNET_assert (0);
437 return;
438 }
439 res = (struct RedirectToIpResponseMessage *) buf;
440 res->header.size = htons (sizeof (struct RedirectToIpResponseMessage) + rlen);
441 res->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_CLIENT_USE_IP);
442 res->result_af = htonl (result_af);
443 res->request_id = request_id;
444 memcpy (&res[1], addr, rlen);
445 GNUNET_SERVER_notification_context_add (nc, client);
446 GNUNET_SERVER_notification_context_unicast (nc,
447 client,
448 &res->header,
449 GNUNET_NO);
450}
451
452
453/**
454 * Method called whenever a peer has disconnected from the tunnel.
455 *
456 * @param cls closure
457 * @param peer peer identity the tunnel stopped working with
458 */
459static void
460tunnel_peer_disconnect_handler (void *cls,
461 const struct
462 GNUNET_PeerIdentity * peer)
463{
464 /* FIXME: should we do anything here?
465 - stop transmitting to the tunnel (start queueing?)
466 - possibly destroy the tunnel entirely (unless service tunnel?)
467 */
468}
469
470
471/**
472 * Method called whenever a peer has connected to the tunnel. Notifies
473 * the waiting client that the tunnel is now up.
474 *
475 * @param cls closure
476 * @param peer peer identity the tunnel was created to, NULL on timeout
477 * @param atsi performance data for the connection
478 */
479static void
480tunnel_peer_connect_handler (void *cls,
481 const struct GNUNET_PeerIdentity
482 * peer,
483 const struct
484 GNUNET_ATS_Information * atsi)
485{
486 struct TunnelState *ts = cls;
487
488 if (NULL == ts->client)
489 return; /* nothing to do */
490 send_client_reply (ts->client,
491 ts->request_id,
492 ts->af,
493 &ts->destination_ip);
494 GNUNET_SERVER_client_drop (ts->client);
495 ts->client = NULL;
496}
497
498
499/**
408 * Send a message from the message queue via mesh. 500 * Send a message from the message queue via mesh.
409 * 501 *
410 * @param cls the 'struct TunnelState' with the message queue 502 * @param cls the 'struct TunnelState' with the message queue
@@ -453,7 +545,7 @@ send_to_peer_notify_callback (void *cls, size_t size, void *buf)
453 */ 545 */
454static void 546static void
455send_to_tunnel (struct TunnelMessageQueueEntry *tnq, 547send_to_tunnel (struct TunnelMessageQueueEntry *tnq,
456 struct TunnelState *ts) 548 struct TunnelState *ts)
457{ 549{
458 GNUNET_CONTAINER_DLL_insert_tail (ts->head, 550 GNUNET_CONTAINER_DLL_insert_tail (ts->head,
459 ts->tail, 551 ts->tail,
@@ -493,13 +585,17 @@ route_packet (struct DestinationEntry *destination,
493 GNUNET_HashCode key; 585 GNUNET_HashCode key;
494 struct TunnelState *ts; 586 struct TunnelState *ts;
495 struct TunnelMessageQueueEntry *tnq; 587 struct TunnelMessageQueueEntry *tnq;
496 588 size_t alen;
589 size_t mlen;
590 GNUNET_MESH_ApplicationType app_type;
591 int is_new;
592 const struct udp_packet *udp;
593 const struct tcp_packet *tcp;
594
497 switch (protocol) 595 switch (protocol)
498 { 596 {
499 case IPPROTO_UDP: 597 case IPPROTO_UDP:
500 { 598 {
501 const struct udp_packet *udp;
502
503 if (payload_length < sizeof (struct udp_packet)) 599 if (payload_length < sizeof (struct udp_packet))
504 { 600 {
505 /* blame kernel? */ 601 /* blame kernel? */
@@ -518,8 +614,6 @@ route_packet (struct DestinationEntry *destination,
518 break; 614 break;
519 case IPPROTO_TCP: 615 case IPPROTO_TCP:
520 { 616 {
521 const struct tcp_packet *tcp;
522
523 if (payload_length < sizeof (struct tcp_packet)) 617 if (payload_length < sizeof (struct tcp_packet))
524 { 618 {
525 /* blame kernel? */ 619 /* blame kernel? */
@@ -543,24 +637,53 @@ route_packet (struct DestinationEntry *destination,
543 return; 637 return;
544 } 638 }
545 639
640 if (! destination->is_service)
641 {
642 switch (destination->details.exit_destination.af)
643 {
644 case AF_INET:
645 alen = sizeof (struct in_addr);
646 app_type = GNUNET_APPLICATION_TYPE_IPV4_GATEWAY;
647 break;
648 case AF_INET6:
649 alen = sizeof (struct in6_addr);
650 app_type = GNUNET_APPLICATION_TYPE_IPV6_GATEWAY;
651 break;
652 default:
653 alen = 0;
654 GNUNET_assert (0);
655 }
656 }
657 else
658 {
659 /* make compiler happy */
660 alen = 0;
661 app_type = 0;
662 }
663
664 // FIXME: something is horrifically wrong here about
665 // how we lookup 'ts', match it and how we decide about
666 // creating new tunnels!
546 /* find tunnel */ 667 /* find tunnel */
668 is_new = GNUNET_NO;
547 ts = GNUNET_CONTAINER_multihashmap_get (tunnel_map, 669 ts = GNUNET_CONTAINER_multihashmap_get (tunnel_map,
548 &key); 670 &key);
549 if (NULL == ts) 671 if (NULL == ts)
550 { 672 {
551 /* create new tunnel */ 673 /* create new tunnel */
552 // FIXME: create tunnel! 674 is_new = GNUNET_YES;
553#if 0 675 ts = GNUNET_malloc (sizeof (struct TunnelState));
554 *cls = 676 ts->destination.tunnel = GNUNET_MESH_tunnel_create (mesh_handle,
555 GNUNET_MESH_tunnel_create (mesh_handle, 677 ts,
556 initialize_tunnel_state (16, NULL), 678 &tunnel_peer_connect_handler,
557 &send_pkt_to_peer, NULL, cls); 679 &tunnel_peer_disconnect_handler,
558 680 ts);
559 GNUNET_MESH_peer_request_connect_add (*cls, 681 if (destination->is_service)
560 (struct GNUNET_PeerIdentity *) 682 GNUNET_MESH_peer_request_connect_add (ts->destination.tunnel,
561 &me->desc); 683 &destination->details.service_destination.target);
562 me->tunnel = *cls; 684 else
563#endif 685 GNUNET_MESH_peer_request_connect_by_type (ts->destination.tunnel,
686 app_type);
564 } 687 }
565 688
566 /* send via tunnel */ 689 /* send via tunnel */
@@ -569,26 +692,93 @@ route_packet (struct DestinationEntry *destination,
569 case IPPROTO_UDP: 692 case IPPROTO_UDP:
570 if (destination->is_service) 693 if (destination->is_service)
571 { 694 {
572 tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueueEntry) + 42); 695 struct GNUNET_EXIT_UdpServiceMessage *usm;
696
697 mlen = sizeof (struct GNUNET_EXIT_UdpServiceMessage) +
698 payload_length - sizeof (struct udp_packet);
699 if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
700 {
701 GNUNET_break (0);
702 return;
703 }
704 tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueueEntry) + mlen);
705 usm = (struct GNUNET_EXIT_UdpServiceMessage *) &tnq[1];
706 usm->header.size = htons ((uint16_t) mlen);
707 usm->service_descriptor = destination->details.service_destination.service_descriptor;
573 // FIXME: build message! 708 // FIXME: build message!
574 } 709 }
575 else 710 else
576 { 711 {
577 tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueueEntry) + 42); 712 struct GNUNET_EXIT_UdpInternetMessage *uim;
713
714 mlen = sizeof (struct GNUNET_EXIT_UdpInternetMessage) +
715 alen + payload_length - sizeof (struct udp_packet);
716 if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
717 {
718 GNUNET_break (0);
719 return;
720 }
721 tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueueEntry) +
722 mlen);
723 uim = (struct GNUNET_EXIT_UdpInternetMessage *) &tnq[1];
724 uim->header.size = htons ((uint16_t) mlen);
725 uim->af = htonl (destination->details.exit_destination.af);
726
578 // FIXME: build message! 727 // FIXME: build message!
579 } 728 }
580 break; 729 break;
581 case IPPROTO_TCP: 730 case IPPROTO_TCP:
582 if (destination->is_service) 731 if (is_new)
583 { 732 {
584 tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueueEntry) + 42); 733 if (destination->is_service)
585 // FIXME: build message! 734 {
735 struct GNUNET_EXIT_TcpServiceStartMessage *tsm;
736
737 mlen = sizeof (struct GNUNET_EXIT_TcpServiceStartMessage) +
738 payload_length - sizeof (struct tcp_packet);
739 if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
740 {
741 GNUNET_break (0);
742 return;
743 }
744 tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueueEntry) + mlen);
745 tsm = (struct GNUNET_EXIT_TcpServiceStartMessage *) &tnq[1];
746 tsm->header.size = htons ((uint16_t) mlen);
747 // FIXME: build message!
748 }
749 else
750 {
751 struct GNUNET_EXIT_TcpInternetStartMessage *tim;
752
753 mlen = sizeof (struct GNUNET_EXIT_TcpInternetStartMessage) +
754 alen + payload_length - sizeof (struct tcp_packet);
755 if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
756 {
757 GNUNET_break (0);
758 return;
759 }
760 tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueueEntry) + mlen);
761 tim = (struct GNUNET_EXIT_TcpInternetStartMessage *) &tnq[1];
762 tim->header.size = htons ((uint16_t) mlen);
763 // FIXME: build message!
764 }
586 } 765 }
587 else 766 else
588 { 767 {
589 tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueueEntry) + 42); 768 struct GNUNET_EXIT_TcpDataMessage *tdm;
769
770 mlen = sizeof (struct GNUNET_EXIT_TcpDataMessage) +
771 alen + payload_length - sizeof (struct tcp_packet);
772 if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
773 {
774 GNUNET_break (0);
775 return;
776 }
777 tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueueEntry) + mlen);
778 tdm = (struct GNUNET_EXIT_TcpDataMessage *) &tnq[1];
779 tdm->header.size = htons ((uint16_t) mlen);
590 // FIXME: build message! 780 // FIXME: build message!
591 } 781 }
592 break; 782 break;
593 default: 783 default:
594 /* not supported above, how can we get here !? */ 784 /* not supported above, how can we get here !? */
@@ -599,7 +789,6 @@ route_packet (struct DestinationEntry *destination,
599} 789}
600 790
601 791
602
603/** 792/**
604 * Receive packets from the helper-process (someone send to the local 793 * Receive packets from the helper-process (someone send to the local
605 * virtual tunnel interface). Find the destination mapping, and if it 794 * virtual tunnel interface). Find the destination mapping, and if it
@@ -1224,99 +1413,6 @@ allocate_v6_address (struct in6_addr *v6)
1224 1413
1225 1414
1226/** 1415/**
1227 * Notify the client about the result of its request.
1228 *
1229 * @param client client to notify
1230 * @param request_id original request ID to include in response
1231 * @param result_af resulting address family
1232 * @param addr resulting IP address
1233 */
1234static void
1235send_client_reply (struct GNUNET_SERVER_Client *client,
1236 uint64_t request_id,
1237 int result_af,
1238 const void *addr)
1239{
1240 char buf[sizeof (struct RedirectToIpResponseMessage) + sizeof (struct in6_addr)];
1241 struct RedirectToIpResponseMessage *res;
1242 size_t rlen;
1243
1244 switch (result_af)
1245 {
1246 case AF_INET:
1247 rlen = sizeof (struct in_addr);
1248 break;
1249 case AF_INET6:
1250 rlen = sizeof (struct in6_addr);
1251 break;
1252 case AF_UNSPEC:
1253 rlen = 0;
1254 break;
1255 default:
1256 GNUNET_assert (0);
1257 return;
1258 }
1259 res = (struct RedirectToIpResponseMessage *) buf;
1260 res->header.size = htons (sizeof (struct RedirectToIpResponseMessage) + rlen);
1261 res->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_CLIENT_USE_IP);
1262 res->result_af = htonl (result_af);
1263 res->request_id = request_id;
1264 memcpy (&res[1], addr, rlen);
1265 GNUNET_SERVER_notification_context_add (nc, client);
1266 GNUNET_SERVER_notification_context_unicast (nc,
1267 client,
1268 &res->header,
1269 GNUNET_NO);
1270}
1271
1272
1273/**
1274 * Method called whenever a peer has disconnected from the tunnel.
1275 *
1276 * @param cls closure
1277 * @param peer peer identity the tunnel stopped working with
1278 */
1279static void
1280tunnel_peer_disconnect_handler (void *cls,
1281 const struct
1282 GNUNET_PeerIdentity * peer)
1283{
1284 /* FIXME: should we do anything here?
1285 - stop transmitting to the tunnel (start queueing?)
1286 - possibly destroy the tunnel entirely (unless service tunnel?)
1287 */
1288}
1289
1290
1291/**
1292 * Method called whenever a peer has connected to the tunnel. Notifies
1293 * the waiting client that the tunnel is now up.
1294 *
1295 * @param cls closure
1296 * @param peer peer identity the tunnel was created to, NULL on timeout
1297 * @param atsi performance data for the connection
1298 */
1299static void
1300tunnel_peer_connect_handler (void *cls,
1301 const struct GNUNET_PeerIdentity
1302 * peer,
1303 const struct
1304 GNUNET_ATS_Information * atsi)
1305{
1306 struct TunnelState *ts = cls;
1307
1308 if (NULL == ts->client)
1309 return; /* nothing to do */
1310 send_client_reply (ts->client,
1311 ts->request_id,
1312 ts->af,
1313 &ts->destination_ip);
1314 GNUNET_SERVER_client_drop (ts->client);
1315 ts->client = NULL;
1316}
1317
1318
1319/**
1320 * A client asks us to setup a redirection via some exit 1416 * A client asks us to setup a redirection via some exit
1321 * node to a particular IP. Setup the redirection and 1417 * node to a particular IP. Setup the redirection and
1322 * give the client the allocated IP. 1418 * give the client the allocated IP.