aboutsummaryrefslogtreecommitdiff
path: root/src/nat/nat_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nat/nat_api.c')
-rw-r--r--src/nat/nat_api.c271
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 */
382struct GNUNET_NAT_Handle * 382struct GNUNET_NAT_Handle *
383GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, 383GNUNET_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,
710void 709void
711GNUNET_NAT_unregister (struct GNUNET_NAT_Handle *nh) 710GNUNET_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 */
723struct 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 */
755const char *
756GNUNET_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 */
811static int
812check_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 */
825static void
826handle_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 */
869static void
870ah_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 */
892struct GNUNET_NAT_AutoHandle *
893GNUNET_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 */
951void
952GNUNET_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 */