diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-01-10 22:29:03 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-01-10 22:29:03 +0000 |
commit | f1a1df54b3f8e8bfde67df67dcc59e9135110fca (patch) | |
tree | b807e51a32a6de2266fb044af8cc010248be9242 /src/vpn | |
parent | 894248a687a4c5e63de96a58026bf275a10339a0 (diff) | |
download | gnunet-f1a1df54b3f8e8bfde67df67dcc59e9135110fca.tar.gz gnunet-f1a1df54b3f8e8bfde67df67dcc59e9135110fca.zip |
-towards having mesh messages in VPN
Diffstat (limited to 'src/vpn')
-rw-r--r-- | src/vpn/Makefile.am | 2 | ||||
-rw-r--r-- | src/vpn/gnunet-service-vpn.c | 338 |
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) |
57 | gnunet_service_vpn_CFLAGS = \ | ||
58 | -I$(top_srcdir)/src/exit $(CFLAGS) | ||
57 | 59 | ||
58 | gnunet_daemon_exit_SOURCES = \ | 60 | gnunet_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 | */ | ||
414 | static void | ||
415 | send_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 | */ | ||
459 | static void | ||
460 | tunnel_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 | */ | ||
479 | static void | ||
480 | tunnel_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 | */ |
454 | static void | 546 | static void |
455 | send_to_tunnel (struct TunnelMessageQueueEntry *tnq, | 547 | send_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 | */ | ||
1234 | static void | ||
1235 | send_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 | */ | ||
1279 | static void | ||
1280 | tunnel_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 | */ | ||
1299 | static void | ||
1300 | tunnel_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. |