diff options
Diffstat (limited to 'src/nat/nat_api.c')
-rw-r--r-- | src/nat/nat_api.c | 271 |
1 files changed, 20 insertions, 251 deletions
diff --git a/src/nat/nat_api.c b/src/nat/nat_api.c index e4dfc1629..eec5d3968 100644 --- a/src/nat/nat_api.c +++ b/src/nat/nat_api.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2007-2016 GNUnet e.V. | 3 | Copyright (C) 2007-2017 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -343,7 +343,7 @@ do_connect (void *cls) | |||
343 | struct GNUNET_MQ_Envelope *env; | 343 | struct GNUNET_MQ_Envelope *env; |
344 | 344 | ||
345 | nh->reconnect_task = NULL; | 345 | nh->reconnect_task = NULL; |
346 | nh->mq = GNUNET_CLIENT_connecT (nh->cfg, | 346 | nh->mq = GNUNET_CLIENT_connect (nh->cfg, |
347 | "nat", | 347 | "nat", |
348 | handlers, | 348 | handlers, |
349 | &mq_error_handler, | 349 | &mq_error_handler, |
@@ -368,8 +368,8 @@ do_connect (void *cls) | |||
368 | * address_callback for any 'plausible' external address. | 368 | * address_callback for any 'plausible' external address. |
369 | * | 369 | * |
370 | * @param cfg configuration to use | 370 | * @param cfg configuration to use |
371 | * @param config_section name of the configuration section for optionsx | ||
371 | * @param proto protocol this is about, IPPROTO_TCP or IPPROTO_UDP | 372 | * @param proto protocol this is about, IPPROTO_TCP or IPPROTO_UDP |
372 | * @param hole_external hostname and port of manually punched hole in NAT, otherwise NULL (or empty string) | ||
373 | * @param num_addrs number of addresses in @a addrs | 373 | * @param num_addrs number of addresses in @a addrs |
374 | * @param addrs list of local addresses packets should be redirected to | 374 | * @param addrs list of local addresses packets should be redirected to |
375 | * @param addrlens actual lengths of the addresses in @a addrs | 375 | * @param addrlens actual lengths of the addresses in @a addrs |
@@ -381,8 +381,8 @@ do_connect (void *cls) | |||
381 | */ | 381 | */ |
382 | struct GNUNET_NAT_Handle * | 382 | struct GNUNET_NAT_Handle * |
383 | GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, | 383 | GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, |
384 | const char *config_section, | ||
384 | uint8_t proto, | 385 | uint8_t proto, |
385 | const char *hole_external, | ||
386 | unsigned int num_addrs, | 386 | unsigned int num_addrs, |
387 | const struct sockaddr **addrs, | 387 | const struct sockaddr **addrs, |
388 | const socklen_t *addrlens, | 388 | const socklen_t *addrlens, |
@@ -393,17 +393,14 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
393 | struct GNUNET_NAT_Handle *nh; | 393 | struct GNUNET_NAT_Handle *nh; |
394 | struct GNUNET_NAT_RegisterMessage *rm; | 394 | struct GNUNET_NAT_RegisterMessage *rm; |
395 | size_t len; | 395 | size_t len; |
396 | size_t hole_external_len; | 396 | size_t str_len; |
397 | char *off; | 397 | char *off; |
398 | 398 | ||
399 | len = 0; | 399 | len = 0; |
400 | for (unsigned int i=0;i<num_addrs;i++) | 400 | for (unsigned int i=0;i<num_addrs;i++) |
401 | len += addrlens[i]; | 401 | len += addrlens[i]; |
402 | hole_external_len | 402 | str_len = strlen (config_section) + 1; |
403 | = (NULL == hole_external) | 403 | len += str_len; |
404 | ? 0 | ||
405 | : strlen (hole_external); | ||
406 | len += hole_external_len; | ||
407 | if ( (len > GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (*rm)) || | 404 | if ( (len > GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (*rm)) || |
408 | (num_addrs > UINT16_MAX) ) | 405 | (num_addrs > UINT16_MAX) ) |
409 | { | 406 | { |
@@ -419,7 +416,7 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
419 | if (NULL != reversal_callback) | 416 | if (NULL != reversal_callback) |
420 | rm->flags |= GNUNET_NAT_RF_REVERSAL; | 417 | rm->flags |= GNUNET_NAT_RF_REVERSAL; |
421 | rm->proto = proto; | 418 | rm->proto = proto; |
422 | rm->hole_external_len = htons (hole_external_len); | 419 | rm->str_len = htons (str_len); |
423 | rm->num_addrs = htons ((uint16_t) num_addrs); | 420 | rm->num_addrs = htons ((uint16_t) num_addrs); |
424 | off = (char *) &rm[1]; | 421 | off = (char *) &rm[1]; |
425 | for (unsigned int i=0;i<num_addrs;i++) | 422 | for (unsigned int i=0;i<num_addrs;i++) |
@@ -459,8 +456,8 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
459 | off += addrlens[i]; | 456 | off += addrlens[i]; |
460 | } | 457 | } |
461 | GNUNET_memcpy (off, | 458 | GNUNET_memcpy (off, |
462 | hole_external, | 459 | config_section, |
463 | hole_external_len); | 460 | str_len); |
464 | 461 | ||
465 | nh = GNUNET_new (struct GNUNET_NAT_Handle); | 462 | nh = GNUNET_new (struct GNUNET_NAT_Handle); |
466 | nh->reg = &rm->header; | 463 | nh->reg = &rm->header; |
@@ -681,6 +678,8 @@ GNUNET_NAT_request_reversal (struct GNUNET_NAT_Handle *nh, | |||
681 | 678 | ||
682 | if (NULL == nh->mq) | 679 | if (NULL == nh->mq) |
683 | return GNUNET_SYSERR; | 680 | return GNUNET_SYSERR; |
681 | GNUNET_break (AF_INET == local_sa->sin_family); | ||
682 | GNUNET_break (AF_INET == remote_sa->sin_family); | ||
684 | env = GNUNET_MQ_msg_extra (req, | 683 | env = GNUNET_MQ_msg_extra (req, |
685 | 2 * sizeof (struct sockaddr_in), | 684 | 2 * sizeof (struct sockaddr_in), |
686 | GNUNET_MESSAGE_TYPE_NAT_REQUEST_CONNECTION_REVERSAL); | 685 | GNUNET_MESSAGE_TYPE_NAT_REQUEST_CONNECTION_REVERSAL); |
@@ -710,249 +709,19 @@ GNUNET_NAT_request_reversal (struct GNUNET_NAT_Handle *nh, | |||
710 | void | 709 | void |
711 | GNUNET_NAT_unregister (struct GNUNET_NAT_Handle *nh) | 710 | GNUNET_NAT_unregister (struct GNUNET_NAT_Handle *nh) |
712 | { | 711 | { |
713 | GNUNET_MQ_destroy (nh->mq); | 712 | if (NULL != nh->mq) |
714 | GNUNET_free (nh->reg); | ||
715 | GNUNET_free (nh); | ||
716 | } | ||
717 | |||
718 | |||
719 | |||
720 | /** | ||
721 | * Handle to auto-configuration in progress. | ||
722 | */ | ||
723 | struct GNUNET_NAT_AutoHandle | ||
724 | { | ||
725 | |||
726 | /** | ||
727 | * Configuration we use. | ||
728 | */ | ||
729 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
730 | |||
731 | /** | ||
732 | * Message queue for communicating with the NAT service. | ||
733 | */ | ||
734 | struct GNUNET_MQ_Handle *mq; | ||
735 | |||
736 | /** | ||
737 | * Function called with the result from the autoconfiguration. | ||
738 | */ | ||
739 | GNUNET_NAT_AutoResultCallback arc; | ||
740 | |||
741 | /** | ||
742 | * Closure for @e arc. | ||
743 | */ | ||
744 | void *arc_cls; | ||
745 | |||
746 | }; | ||
747 | |||
748 | |||
749 | /** | ||
750 | * Converts `enum GNUNET_NAT_StatusCode` to string | ||
751 | * | ||
752 | * @param err error code to resolve to a string | ||
753 | * @return point to a static string containing the error code | ||
754 | */ | ||
755 | const char * | ||
756 | GNUNET_NAT_status2string (enum GNUNET_NAT_StatusCode err) | ||
757 | { | ||
758 | switch (err) | ||
759 | { | ||
760 | case GNUNET_NAT_ERROR_SUCCESS: | ||
761 | return _ ("Operation Successful"); | ||
762 | case GNUNET_NAT_ERROR_IPC_FAILURE: | ||
763 | return _ ("IPC failure"); | ||
764 | case GNUNET_NAT_ERROR_INTERNAL_NETWORK_ERROR: | ||
765 | return _ ("Failure in network subsystem, check permissions."); | ||
766 | case GNUNET_NAT_ERROR_TIMEOUT: | ||
767 | return _ ("Encountered timeout while performing operation"); | ||
768 | case GNUNET_NAT_ERROR_NOT_ONLINE: | ||
769 | return _ ("detected that we are offline"); | ||
770 | case GNUNET_NAT_ERROR_UPNPC_NOT_FOUND: | ||
771 | return _ ("`upnpc` command not found"); | ||
772 | case GNUNET_NAT_ERROR_UPNPC_FAILED: | ||
773 | return _ ("Failed to run `upnpc` command"); | ||
774 | case GNUNET_NAT_ERROR_UPNPC_TIMEOUT: | ||
775 | return _ ("`upnpc' command took too long, process killed"); | ||
776 | case GNUNET_NAT_ERROR_UPNPC_PORTMAP_FAILED: | ||
777 | return _ ("`upnpc' command failed to establish port mapping"); | ||
778 | case GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_NOT_FOUND: | ||
779 | return _ ("`external-ip' command not found"); | ||
780 | case GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_FAILED: | ||
781 | return _ ("Failed to run `external-ip` command"); | ||
782 | case GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_OUTPUT_INVALID: | ||
783 | return _ ("`external-ip' command output invalid"); | ||
784 | case GNUNET_NAT_ERROR_EXTERNAL_IP_ADDRESS_INVALID: | ||
785 | return _ ("no valid address was returned by `external-ip'"); | ||
786 | case GNUNET_NAT_ERROR_NO_VALID_IF_IP_COMBO: | ||
787 | return _ ("Could not determine interface with internal/local network address"); | ||
788 | case GNUNET_NAT_ERROR_HELPER_NAT_SERVER_NOT_FOUND: | ||
789 | return _ ("No functioning gnunet-helper-nat-server installation found"); | ||
790 | case GNUNET_NAT_ERROR_NAT_TEST_START_FAILED: | ||
791 | return _ ("NAT test could not be initialized"); | ||
792 | case GNUNET_NAT_ERROR_NAT_TEST_TIMEOUT: | ||
793 | return _ ("NAT test timeout reached"); | ||
794 | case GNUNET_NAT_ERROR_NAT_REGISTER_FAILED: | ||
795 | return _ ("could not register NAT"); | ||
796 | case GNUNET_NAT_ERROR_HELPER_NAT_CLIENT_NOT_FOUND: | ||
797 | return _ ("No working gnunet-helper-nat-client installation found"); | ||
798 | default: | ||
799 | return "unknown status code"; | ||
800 | } | ||
801 | } | ||
802 | |||
803 | |||
804 | /** | ||
805 | * Check result from autoconfiguration attempt. | ||
806 | * | ||
807 | * @param cls the `struct GNUNET_NAT_AutoHandle` | ||
808 | * @param res the result | ||
809 | * @return #GNUNET_OK if @a res is well-formed (always for now) | ||
810 | */ | ||
811 | static int | ||
812 | check_auto_result (void *cls, | ||
813 | const struct GNUNET_NAT_AutoconfigResultMessage *res) | ||
814 | { | ||
815 | return GNUNET_OK; | ||
816 | } | ||
817 | |||
818 | |||
819 | /** | ||
820 | * Handle result from autoconfiguration attempt. | ||
821 | * | ||
822 | * @param cls the `struct GNUNET_NAT_AutoHandle` | ||
823 | * @param res the result | ||
824 | */ | ||
825 | static void | ||
826 | handle_auto_result (void *cls, | ||
827 | const struct GNUNET_NAT_AutoconfigResultMessage *res) | ||
828 | { | ||
829 | struct GNUNET_NAT_AutoHandle *ah = cls; | ||
830 | size_t left; | ||
831 | struct GNUNET_CONFIGURATION_Handle *cfg; | ||
832 | enum GNUNET_NAT_Type type | ||
833 | = (enum GNUNET_NAT_Type) ntohl (res->type); | ||
834 | enum GNUNET_NAT_StatusCode status | ||
835 | = (enum GNUNET_NAT_StatusCode) ntohl (res->status_code); | ||
836 | |||
837 | left = ntohs (res->header.size) - sizeof (*res); | ||
838 | cfg = GNUNET_CONFIGURATION_create (); | ||
839 | if (GNUNET_OK != | ||
840 | GNUNET_CONFIGURATION_deserialize (cfg, | ||
841 | (const char *) &res[1], | ||
842 | left, | ||
843 | GNUNET_NO)) | ||
844 | { | ||
845 | GNUNET_break (0); | ||
846 | ah->arc (ah->arc_cls, | ||
847 | NULL, | ||
848 | GNUNET_NAT_ERROR_IPC_FAILURE, | ||
849 | type); | ||
850 | } | ||
851 | else | ||
852 | { | ||
853 | ah->arc (ah->arc_cls, | ||
854 | cfg, | ||
855 | status, | ||
856 | type); | ||
857 | } | ||
858 | GNUNET_CONFIGURATION_destroy (cfg); | ||
859 | GNUNET_NAT_autoconfig_cancel (ah); | ||
860 | } | ||
861 | |||
862 | |||
863 | /** | ||
864 | * Handle queue errors by reporting autoconfiguration failure. | ||
865 | * | ||
866 | * @param cls the `struct GNUNET_NAT_AutoHandle *` | ||
867 | * @param error details about the error | ||
868 | */ | ||
869 | static void | ||
870 | ah_error_handler (void *cls, | ||
871 | enum GNUNET_MQ_Error error) | ||
872 | { | ||
873 | struct GNUNET_NAT_AutoHandle *ah = cls; | ||
874 | |||
875 | ah->arc (ah->arc_cls, | ||
876 | NULL, | ||
877 | GNUNET_NAT_ERROR_IPC_FAILURE, | ||
878 | GNUNET_NAT_TYPE_UNKNOWN); | ||
879 | GNUNET_NAT_autoconfig_cancel (ah); | ||
880 | } | ||
881 | |||
882 | |||
883 | /** | ||
884 | * Start auto-configuration routine. The transport adapters should | ||
885 | * be stopped while this function is called. | ||
886 | * | ||
887 | * @param cfg initial configuration | ||
888 | * @param cb function to call with autoconfiguration result | ||
889 | * @param cb_cls closure for @a cb | ||
890 | * @return handle to cancel operation | ||
891 | */ | ||
892 | struct GNUNET_NAT_AutoHandle * | ||
893 | GNUNET_NAT_autoconfig_start (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
894 | GNUNET_NAT_AutoResultCallback cb, | ||
895 | void *cb_cls) | ||
896 | { | ||
897 | struct GNUNET_NAT_AutoHandle *ah = GNUNET_new (struct GNUNET_NAT_AutoHandle); | ||
898 | struct GNUNET_MQ_MessageHandler handlers[] = { | ||
899 | GNUNET_MQ_hd_var_size (auto_result, | ||
900 | GNUNET_MESSAGE_TYPE_NAT_AUTO_CFG_RESULT, | ||
901 | struct GNUNET_NAT_AutoconfigResultMessage, | ||
902 | ah), | ||
903 | GNUNET_MQ_handler_end () | ||
904 | }; | ||
905 | struct GNUNET_MQ_Envelope *env; | ||
906 | struct GNUNET_NAT_AutoconfigRequestMessage *req; | ||
907 | char *buf; | ||
908 | size_t size; | ||
909 | |||
910 | buf = GNUNET_CONFIGURATION_serialize (cfg, | ||
911 | &size); | ||
912 | if (size > GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (*req)) | ||
913 | { | 713 | { |
914 | GNUNET_break (0); | 714 | GNUNET_MQ_destroy (nh->mq); |
915 | GNUNET_free (buf); | 715 | nh->mq = NULL; |
916 | GNUNET_free (ah); | ||
917 | return NULL; | ||
918 | } | 716 | } |
919 | ah->arc = cb; | 717 | if (NULL != nh->reconnect_task) |
920 | ah->arc_cls = cb_cls; | ||
921 | ah->mq = GNUNET_CLIENT_connecT (cfg, | ||
922 | "nat", | ||
923 | handlers, | ||
924 | &ah_error_handler, | ||
925 | ah); | ||
926 | if (NULL == ah->mq) | ||
927 | { | 718 | { |
928 | GNUNET_break (0); | 719 | GNUNET_SCHEDULER_cancel (nh->reconnect_task); |
929 | GNUNET_free (buf); | 720 | nh->reconnect_task = NULL; |
930 | GNUNET_free (ah); | ||
931 | return NULL; | ||
932 | } | 721 | } |
933 | env = GNUNET_MQ_msg_extra (req, | 722 | GNUNET_free (nh->reg); |
934 | size, | 723 | GNUNET_free (nh); |
935 | GNUNET_MESSAGE_TYPE_NAT_REQUEST_AUTO_CFG); | ||
936 | GNUNET_memcpy (&req[1], | ||
937 | buf, | ||
938 | size); | ||
939 | GNUNET_free (buf); | ||
940 | GNUNET_MQ_send (ah->mq, | ||
941 | env); | ||
942 | return ah; | ||
943 | } | 724 | } |
944 | 725 | ||
945 | 726 | ||
946 | /** | ||
947 | * Abort autoconfiguration. | ||
948 | * | ||
949 | * @param ah handle for operation to abort | ||
950 | */ | ||
951 | void | ||
952 | GNUNET_NAT_autoconfig_cancel (struct GNUNET_NAT_AutoHandle *ah) | ||
953 | { | ||
954 | GNUNET_MQ_destroy (ah->mq); | ||
955 | GNUNET_free (ah); | ||
956 | } | ||
957 | |||
958 | /* end of nat_api.c */ | 727 | /* end of nat_api.c */ |