aboutsummaryrefslogtreecommitdiff
path: root/src/ats/ats_api_scheduling.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-02-03 14:27:56 +0000
committerChristian Grothoff <christian@grothoff.org>2015-02-03 14:27:56 +0000
commit7aff55d7ef03ec7172e5d219e5a22100c21e8425 (patch)
tree2958999e380146ab541263005b4d0191ff991fd0 /src/ats/ats_api_scheduling.c
parentb2e99dd91c01b5fcc16b3b1031df897aeec05eef (diff)
downloadgnunet-7aff55d7ef03ec7172e5d219e5a22100c21e8425.tar.gz
gnunet-7aff55d7ef03ec7172e5d219e5a22100c21e8425.zip
separate ATS interface scanning logic from ATS scheduling logic
Diffstat (limited to 'src/ats/ats_api_scheduling.c')
-rw-r--r--src/ats/ats_api_scheduling.c383
1 files changed, 0 insertions, 383 deletions
diff --git a/src/ats/ats_api_scheduling.c b/src/ats/ats_api_scheduling.c
index 2daa45a73..954396b66 100644
--- a/src/ats/ats_api_scheduling.c
+++ b/src/ats/ats_api_scheduling.c
@@ -108,44 +108,6 @@ struct GNUNET_ATS_AddressRecord
108 108
109 109
110/** 110/**
111 * We keep a list of our local networks so we can answer
112 * LAN vs. WAN questions. Note: WLAN is not detected yet.
113 * (maybe we can do that heuristically based on interface
114 * name in the future?).
115 *
116 * FIXME: should this be part of the ATS scheduling API?
117 * Seems to be more generic and independent of ATS.
118 */
119struct ATS_Network
120{
121 /**
122 * Kept in a DLL.
123 */
124 struct ATS_Network *next;
125
126 /**
127 * Kept in a DLL.
128 */
129 struct ATS_Network *prev;
130
131 /**
132 * Network address.
133 */
134 struct sockaddr *network;
135
136 /**
137 * Netmask to determine what is in the LAN.
138 */
139 struct sockaddr *netmask;
140
141 /**
142 * How long are @e network and @e netmask?
143 */
144 socklen_t length;
145};
146
147
148/**
149 * Handle to the ATS subsystem for bandwidth/transport scheduling information. 111 * Handle to the ATS subsystem for bandwidth/transport scheduling information.
150 */ 112 */
151struct GNUNET_ATS_SchedulingHandle 113struct GNUNET_ATS_SchedulingHandle
@@ -177,16 +139,6 @@ struct GNUNET_ATS_SchedulingHandle
177 struct GNUNET_MQ_Handle *mq; 139 struct GNUNET_MQ_Handle *mq;
178 140
179 /** 141 /**
180 * Head of LAN networks list.
181 */
182 struct ATS_Network *net_head;
183
184 /**
185 * Tail of LAN networks list.
186 */
187 struct ATS_Network *net_tail;
188
189 /**
190 * Array of session objects (we need to translate them to numbers and back 142 * Array of session objects (we need to translate them to numbers and back
191 * for the protocol; the offset in the array is the session number on the 143 * for the protocol; the offset in the array is the session number on the
192 * network). Index 0 is always NULL and reserved to represent the NULL pointer. 144 * network). Index 0 is always NULL and reserved to represent the NULL pointer.
@@ -200,11 +152,6 @@ struct GNUNET_ATS_SchedulingHandle
200 struct GNUNET_SCHEDULER_Task *task; 152 struct GNUNET_SCHEDULER_Task *task;
201 153
202 /** 154 /**
203 * Task for periodically refreshing our LAN network list.
204 */
205 struct GNUNET_SCHEDULER_Task *interface_task;
206
207 /**
208 * Size of the @e session_array. 155 * Size of the @e session_array.
209 */ 156 */
210 unsigned int session_array_size; 157 unsigned int session_array_size;
@@ -644,325 +591,6 @@ reconnect (struct GNUNET_ATS_SchedulingHandle *sh)
644 591
645 592
646/** 593/**
647 * Delete all entries from the current network list.
648 *
649 * @param sh scheduling handle to clean up
650 */
651static void
652delete_networks (struct GNUNET_ATS_SchedulingHandle *sh)
653{
654 struct ATS_Network *cur;
655
656 while (NULL != (cur = sh->net_head))
657 {
658 GNUNET_CONTAINER_DLL_remove (sh->net_head,
659 sh->net_tail,
660 cur);
661 GNUNET_free (cur);
662 }
663}
664
665
666/**
667 * Function invoked for each interface found. Adds the interface's
668 * network addresses to the respective DLL, so we can distinguish
669 * between LAN and WAN.
670 *
671 * @param cls closure
672 * @param name name of the interface (can be NULL for unknown)
673 * @param isDefault is this presumably the default interface
674 * @param addr address of this interface (can be NULL for unknown or unassigned)
675 * @param broadcast_addr the broadcast address (can be NULL for unknown or unassigned)
676 * @param netmask the network mask (can be NULL for unknown or unassigned)
677 * @param addrlen length of the address
678 * @return #GNUNET_OK to continue iteration
679 */
680static int
681interface_proc (void *cls,
682 const char *name,
683 int isDefault,
684 const struct sockaddr *addr,
685 const struct sockaddr *broadcast_addr,
686 const struct sockaddr *netmask,
687 socklen_t addrlen)
688{
689 struct GNUNET_ATS_SchedulingHandle *sh = cls;
690 /* Calculate network */
691 struct ATS_Network *net = NULL;
692
693 /* Skipping IPv4 loopback addresses since we have special check */
694 if (addr->sa_family == AF_INET)
695 {
696 const struct sockaddr_in *a4 = (const struct sockaddr_in *) addr;
697
698 if ((a4->sin_addr.s_addr & htonl(0xff000000)) == htonl (0x7f000000))
699 return GNUNET_OK;
700 }
701 /* Skipping IPv6 loopback addresses since we have special check */
702 if (addr->sa_family == AF_INET6)
703 {
704 const struct sockaddr_in6 *a6 = (const struct sockaddr_in6 *) addr;
705 if (IN6_IS_ADDR_LOOPBACK (&a6->sin6_addr))
706 return GNUNET_OK;
707 }
708
709 if (addr->sa_family == AF_INET)
710 {
711 const struct sockaddr_in *addr4 = (const struct sockaddr_in *) addr;
712 const struct sockaddr_in *netmask4 = (const struct sockaddr_in *) netmask;
713 struct sockaddr_in *tmp;
714 struct sockaddr_in network4;
715
716 net = GNUNET_malloc (sizeof (struct ATS_Network) + 2 * sizeof (struct sockaddr_in));
717 tmp = (struct sockaddr_in *) &net[1];
718 net->network = (struct sockaddr *) &tmp[0];
719 net->netmask = (struct sockaddr *) &tmp[1];
720 net->length = addrlen;
721
722 memset (&network4, 0, sizeof (network4));
723 network4.sin_family = AF_INET;
724#if HAVE_SOCKADDR_IN_SIN_LEN
725 network4.sin_len = sizeof (network4);
726#endif
727 network4.sin_addr.s_addr = (addr4->sin_addr.s_addr & netmask4->sin_addr.s_addr);
728
729 memcpy (net->netmask, netmask4, sizeof (struct sockaddr_in));
730 memcpy (net->network, &network4, sizeof (struct sockaddr_in));
731 }
732
733 if (addr->sa_family == AF_INET6)
734 {
735 const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *) addr;
736 const struct sockaddr_in6 *netmask6 = (const struct sockaddr_in6 *) netmask;
737 struct sockaddr_in6 * tmp;
738 struct sockaddr_in6 network6;
739
740 net = GNUNET_malloc (sizeof (struct ATS_Network) + 2 * sizeof (struct sockaddr_in6));
741 tmp = (struct sockaddr_in6 *) &net[1];
742 net->network = (struct sockaddr *) &tmp[0];
743 net->netmask = (struct sockaddr *) &tmp[1];
744 net->length = addrlen;
745
746 memset (&network6, 0, sizeof (network6));
747 network6.sin6_family = AF_INET6;
748#if HAVE_SOCKADDR_IN_SIN_LEN
749 network6.sin6_len = sizeof (network6);
750#endif
751 unsigned int c = 0;
752 uint32_t *addr_elem = (uint32_t *) &addr6->sin6_addr;
753 uint32_t *mask_elem = (uint32_t *) &netmask6->sin6_addr;
754 uint32_t *net_elem = (uint32_t *) &network6.sin6_addr;
755 for (c = 0; c < 4; c++)
756 net_elem[c] = addr_elem[c] & mask_elem[c];
757
758 memcpy (net->netmask, netmask6, sizeof (struct sockaddr_in6));
759 memcpy (net->network, &network6, sizeof (struct sockaddr_in6));
760 }
761 if (NULL == net)
762 return GNUNET_OK; /* odd / unsupported address family */
763
764 /* Store in list */
765#if VERBOSE_ATS
766 char * netmask = GNUNET_strdup (GNUNET_a2s((struct sockaddr *) net->netmask, addrlen));
767 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
768 "Adding network `%s', netmask `%s'\n",
769 GNUNET_a2s ((struct sockaddr *) net->network,
770 addrlen),
771 netmask);
772 GNUNET_free (netmask);
773#endif
774 GNUNET_CONTAINER_DLL_insert (sh->net_head,
775 sh->net_tail,
776 net);
777
778 return GNUNET_OK;
779}
780
781
782/**
783 * Periodically get list of network addresses from our interfaces.
784 *
785 * @param cls closure
786 * @param tc Task context
787 */
788static void
789get_addresses (void *cls,
790 const struct GNUNET_SCHEDULER_TaskContext *tc)
791{
792 struct GNUNET_ATS_SchedulingHandle *sh = cls;
793
794 sh->interface_task = NULL;
795 delete_networks (sh);
796 GNUNET_OS_network_interfaces_list (&interface_proc,
797 sh);
798 sh->interface_task = GNUNET_SCHEDULER_add_delayed (INTERFACE_PROCESSING_INTERVAL,
799 &get_addresses,
800 sh);
801}
802
803
804/**
805 * Convert a `enum GNUNET_ATS_Network_Type` to a string
806 *
807 * @param net the network type
808 * @return a string or NULL if invalid
809 */
810const char *
811GNUNET_ATS_print_network_type (enum GNUNET_ATS_Network_Type net)
812{
813 switch (net)
814 {
815 case GNUNET_ATS_NET_UNSPECIFIED:
816 return "UNSPECIFIED";
817 case GNUNET_ATS_NET_LOOPBACK:
818 return "LOOPBACK";
819 case GNUNET_ATS_NET_LAN:
820 return "LAN";
821 case GNUNET_ATS_NET_WAN:
822 return "WAN";
823 case GNUNET_ATS_NET_WLAN:
824 return "WLAN";
825 case GNUNET_ATS_NET_BT:
826 return "BLUETOOTH";
827 default:
828 return NULL;
829 }
830}
831
832
833/**
834 * Convert a ATS property to a string
835 *
836 * @param type the property type
837 * @return a string or NULL if invalid
838 */
839const char *
840GNUNET_ATS_print_property_type (enum GNUNET_ATS_Property type)
841{
842 switch (type)
843 {
844 case GNUNET_ATS_ARRAY_TERMINATOR:
845 return "TERMINATOR";
846 case GNUNET_ATS_UTILIZATION_OUT:
847 return "UTILIZATION_UP";
848 case GNUNET_ATS_UTILIZATION_IN:
849 return "UTILIZATION_DOWN";
850 case GNUNET_ATS_UTILIZATION_PAYLOAD_OUT:
851 return "UTILIZATION_PAYLOAD_UP";
852 case GNUNET_ATS_UTILIZATION_PAYLOAD_IN:
853 return "UTILIZATION_PAYLOAD_DOWN";
854 case GNUNET_ATS_NETWORK_TYPE:
855 return "NETWORK_TYPE";
856 case GNUNET_ATS_QUALITY_NET_DELAY:
857 return "DELAY";
858 case GNUNET_ATS_QUALITY_NET_DISTANCE:
859 return "DISTANCE";
860 case GNUNET_ATS_COST_WAN:
861 return "COST_WAN";
862 case GNUNET_ATS_COST_LAN:
863 return "COST_LAN";
864 case GNUNET_ATS_COST_WLAN:
865 return "COST_WLAN";
866 default:
867 return NULL;
868 }
869}
870
871
872/**
873 * Returns where the address is located: LAN or WAN or ...
874 *
875 * @param sh the scheduling handle
876 * @param addr address
877 * @param addrlen address length
878 * @return type of the network the address belongs to
879 */
880enum GNUNET_ATS_Network_Type
881GNUNET_ATS_address_get_type (struct GNUNET_ATS_SchedulingHandle *sh,
882 const struct sockaddr *addr,
883 socklen_t addrlen)
884{
885 struct ATS_Network *cur = sh->net_head;
886 enum GNUNET_ATS_NetworkType type = GNUNET_ATS_NET_UNSPECIFIED;
887
888 switch (addr->sa_family)
889 {
890 case AF_UNIX:
891 type = GNUNET_ATS_NET_LOOPBACK;
892 break;
893 case AF_INET:
894 {
895 const struct sockaddr_in *a4 = (const struct sockaddr_in *) addr;
896
897 if ((a4->sin_addr.s_addr & htonl(0xff000000)) == htonl (0x7f000000))
898 type = GNUNET_ATS_NET_LOOPBACK;
899 break;
900 }
901 case AF_INET6:
902 {
903 const struct sockaddr_in6 *a6 = (const struct sockaddr_in6 *) addr;
904
905 if (IN6_IS_ADDR_LOOPBACK (&a6->sin6_addr))
906 type = GNUNET_ATS_NET_LOOPBACK;
907 break;
908 }
909 default:
910 GNUNET_break (0);
911 break;
912 }
913
914 /* Check local networks */
915 while ((NULL != cur) && (GNUNET_ATS_NET_UNSPECIFIED == type))
916 {
917 if (addrlen != cur->length)
918 {
919 cur = cur->next;
920 continue;
921 }
922 if (addr->sa_family == AF_INET)
923 {
924 const struct sockaddr_in *a4 = (const struct sockaddr_in *) addr;
925 const struct sockaddr_in *net4 = (const struct sockaddr_in *) cur->network;
926 const struct sockaddr_in *mask4 = (const struct sockaddr_in *) cur->netmask;
927
928 if (((a4->sin_addr.s_addr & mask4->sin_addr.s_addr)) == net4->sin_addr.s_addr)
929 type = GNUNET_ATS_NET_LAN;
930 }
931 if (addr->sa_family == AF_INET6)
932 {
933 const struct sockaddr_in6 *a6 = (const struct sockaddr_in6 *) addr;
934 const struct sockaddr_in6 *net6 = (const struct sockaddr_in6 *) cur->network;
935 const struct sockaddr_in6 *mask6 = (const struct sockaddr_in6 *) cur->netmask;
936
937 int res = GNUNET_YES;
938 int c = 0;
939 uint32_t *addr_elem = (uint32_t *) &a6->sin6_addr;
940 uint32_t *mask_elem = (uint32_t *) &mask6->sin6_addr;
941 uint32_t *net_elem = (uint32_t *) &net6->sin6_addr;
942 for (c = 0; c < 4; c++)
943 if ((addr_elem[c] & mask_elem[c]) != net_elem[c])
944 res = GNUNET_NO;
945
946 if (res == GNUNET_YES)
947 type = GNUNET_ATS_NET_LAN;
948 }
949 cur = cur->next;
950 }
951
952 /* no local network found for this address, default: WAN */
953 if (type == GNUNET_ATS_NET_UNSPECIFIED)
954 type = GNUNET_ATS_NET_WAN;
955 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
956 "ats-scheduling-api",
957 "`%s' is in network `%s'\n",
958 GNUNET_a2s (addr,
959 addrlen),
960 GNUNET_ATS_print_network_type (type));
961 return type;
962}
963
964
965/**
966 * Initialize the ATS subsystem. 594 * Initialize the ATS subsystem.
967 * 595 *
968 * @param cfg configuration to use 596 * @param cfg configuration to use
@@ -984,11 +612,6 @@ GNUNET_ATS_scheduling_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
984 GNUNET_array_grow (sh->session_array, 612 GNUNET_array_grow (sh->session_array,
985 sh->session_array_size, 613 sh->session_array_size,
986 4); 614 4);
987 GNUNET_OS_network_interfaces_list (&interface_proc,
988 sh);
989 sh->interface_task = GNUNET_SCHEDULER_add_delayed (INTERFACE_PROCESSING_INTERVAL,
990 &get_addresses,
991 sh);
992 reconnect (sh); 615 reconnect (sh);
993 return sh; 616 return sh;
994} 617}
@@ -1017,12 +640,6 @@ GNUNET_ATS_scheduling_done (struct GNUNET_ATS_SchedulingHandle *sh)
1017 GNUNET_SCHEDULER_cancel (sh->task); 640 GNUNET_SCHEDULER_cancel (sh->task);
1018 sh->task = NULL; 641 sh->task = NULL;
1019 } 642 }
1020 if (NULL != sh->interface_task)
1021 {
1022 GNUNET_SCHEDULER_cancel (sh->interface_task);
1023 sh->interface_task = NULL;
1024 }
1025 delete_networks (sh);
1026 GNUNET_array_grow (sh->session_array, 643 GNUNET_array_grow (sh->session_array,
1027 sh->session_array_size, 644 sh->session_array_size,
1028 0); 645 0);