diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2011-12-13 12:31:32 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2011-12-13 12:31:32 +0000 |
commit | e9a2275de31a09124c983716a611c7a8fc3ee167 (patch) | |
tree | c79ccb582039293e78a576fd29c1cec9d3d70b12 | |
parent | 92bf2c7f90bb5e77bd30d3297b40e2299ad816f5 (diff) | |
download | gnunet-e9a2275de31a09124c983716a611c7a8fc3ee167.tar.gz gnunet-e9a2275de31a09124c983716a611c7a8fc3ee167.zip |
move code from service to api
fix bug
add test
-rw-r--r-- | src/ats/Makefile.am | 9 | ||||
-rw-r--r-- | src/ats/ats_api_scheduling.c | 263 | ||||
-rw-r--r-- | src/ats/gnunet-service-ats_addresses.c | 222 | ||||
-rw-r--r-- | src/ats/gnunet-service-ats_addresses.h | 10 | ||||
-rw-r--r-- | src/include/gnunet_ats_service.h | 13 |
5 files changed, 284 insertions, 233 deletions
diff --git a/src/ats/Makefile.am b/src/ats/Makefile.am index adccc7e35..79cefe378 100644 --- a/src/ats/Makefile.am +++ b/src/ats/Makefile.am | |||
@@ -42,7 +42,8 @@ gnunet_service_ats_LDADD = \ | |||
42 | 42 | ||
43 | 43 | ||
44 | check_PROGRAMS = \ | 44 | check_PROGRAMS = \ |
45 | test_ats_api_scheduling | 45 | test_ats_api_scheduling \ |
46 | test_ats_api_scheduling_get_type | ||
46 | # test_ats_api_bandwidth_consumption | 47 | # test_ats_api_bandwidth_consumption |
47 | 48 | ||
48 | if ENABLE_TEST_RUN | 49 | if ENABLE_TEST_RUN |
@@ -55,6 +56,12 @@ test_ats_api_scheduling_LDADD = \ | |||
55 | $(top_builddir)/src/util/libgnunetutil.la \ | 56 | $(top_builddir)/src/util/libgnunetutil.la \ |
56 | $(top_builddir)/src/ats/libgnunetats.la | 57 | $(top_builddir)/src/ats/libgnunetats.la |
57 | 58 | ||
59 | test_ats_api_scheduling_get_type_SOURCES = \ | ||
60 | test_ats_api_scheduling_get_type.c | ||
61 | test_ats_api_scheduling_get_type_LDADD = \ | ||
62 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
63 | $(top_builddir)/src/ats/libgnunetats.la | ||
64 | |||
58 | #test_ats_api_bandwidth_consumption_SOURCES = \ | 65 | #test_ats_api_bandwidth_consumption_SOURCES = \ |
59 | # test_ats_api_bandwidth_consumption.c | 66 | # test_ats_api_bandwidth_consumption.c |
60 | #test_ats_api_bandwidth_consumption_LDADD = \ | 67 | #test_ats_api_bandwidth_consumption_LDADD = \ |
diff --git a/src/ats/ats_api_scheduling.c b/src/ats/ats_api_scheduling.c index 0658e362c..c5a9c623f 100644 --- a/src/ats/ats_api_scheduling.c +++ b/src/ats/ats_api_scheduling.c | |||
@@ -80,6 +80,19 @@ struct SessionRecord | |||
80 | }; | 80 | }; |
81 | 81 | ||
82 | 82 | ||
83 | struct ATS_Network | ||
84 | { | ||
85 | struct ATS_Network * next; | ||
86 | |||
87 | struct ATS_Network * prev; | ||
88 | |||
89 | struct sockaddr *network; | ||
90 | struct sockaddr *netmask; | ||
91 | socklen_t length; | ||
92 | }; | ||
93 | |||
94 | |||
95 | |||
83 | /** | 96 | /** |
84 | * Handle to the ATS subsystem for bandwidth/transport scheduling information. | 97 | * Handle to the ATS subsystem for bandwidth/transport scheduling information. |
85 | */ | 98 | */ |
@@ -122,6 +135,17 @@ struct GNUNET_ATS_SchedulingHandle | |||
122 | struct GNUNET_CLIENT_TransmitHandle *th; | 135 | struct GNUNET_CLIENT_TransmitHandle *th; |
123 | 136 | ||
124 | /** | 137 | /** |
138 | * Head of network list | ||
139 | */ | ||
140 | struct ATS_Network * net_head; | ||
141 | |||
142 | /** | ||
143 | * Tail of network list | ||
144 | */ | ||
145 | struct ATS_Network * net_tail; | ||
146 | |||
147 | |||
148 | /** | ||
125 | * Array of session objects (we need to translate them to numbers and back | 149 | * Array of session objects (we need to translate them to numbers and back |
126 | * for the protocol; the offset in the array is the session number on the | 150 | * for the protocol; the offset in the array is the session number on the |
127 | * network). Index 0 is always NULL and reserved to represent the NULL pointer. | 151 | * network). Index 0 is always NULL and reserved to represent the NULL pointer. |
@@ -135,6 +159,13 @@ struct GNUNET_ATS_SchedulingHandle | |||
135 | GNUNET_SCHEDULER_TaskIdentifier task; | 159 | GNUNET_SCHEDULER_TaskIdentifier task; |
136 | 160 | ||
137 | /** | 161 | /** |
162 | * Task retrieving interfaces from the system | ||
163 | */ | ||
164 | |||
165 | GNUNET_SCHEDULER_TaskIdentifier interface_task; | ||
166 | |||
167 | |||
168 | /** | ||
138 | * Size of the session array. | 169 | * Size of the session array. |
139 | */ | 170 | */ |
140 | unsigned int session_array_size; | 171 | unsigned int session_array_size; |
@@ -585,6 +616,228 @@ reconnect (struct GNUNET_ATS_SchedulingHandle *sh) | |||
585 | do_transmit (sh); | 616 | do_transmit (sh); |
586 | } | 617 | } |
587 | 618 | ||
619 | /** | ||
620 | * delete the current network list | ||
621 | */ | ||
622 | |||
623 | static void | ||
624 | delete_networks (struct GNUNET_ATS_SchedulingHandle *sh) | ||
625 | { | ||
626 | struct ATS_Network * cur = sh->net_head; | ||
627 | while (cur != NULL) | ||
628 | { | ||
629 | GNUNET_CONTAINER_DLL_remove(sh->net_head, sh->net_tail, cur); | ||
630 | GNUNET_free (cur); | ||
631 | cur = sh->net_head; | ||
632 | } | ||
633 | } | ||
634 | |||
635 | |||
636 | static int | ||
637 | interface_proc (void *cls, const char *name, | ||
638 | int isDefault, | ||
639 | const struct sockaddr * | ||
640 | addr, | ||
641 | const struct sockaddr * | ||
642 | broadcast_addr, | ||
643 | const struct sockaddr * | ||
644 | netmask, socklen_t addrlen) | ||
645 | { | ||
646 | struct GNUNET_ATS_SchedulingHandle * sh = cls; | ||
647 | /* Calculate network */ | ||
648 | struct ATS_Network *net = NULL; | ||
649 | |||
650 | /* Skipping IPv4 loopback addresses since we have special check */ | ||
651 | if (addr->sa_family == AF_INET) | ||
652 | { | ||
653 | struct sockaddr_in * a4 = (struct sockaddr_in *) addr; | ||
654 | |||
655 | if ((a4->sin_addr.s_addr & htonl(0xff000000)) == htonl (0x7f000000)) | ||
656 | return GNUNET_OK; | ||
657 | } | ||
658 | /* Skipping IPv6 loopback addresses since we have special check */ | ||
659 | if (addr->sa_family == AF_INET6) | ||
660 | { | ||
661 | struct sockaddr_in6 * a6 = (struct sockaddr_in6 *) addr; | ||
662 | if (IN6_IS_ADDR_LOOPBACK (&a6->sin6_addr)) | ||
663 | return GNUNET_OK; | ||
664 | } | ||
665 | |||
666 | if (addr->sa_family == AF_INET) | ||
667 | { | ||
668 | struct sockaddr_in *addr4 = (struct sockaddr_in *) addr; | ||
669 | struct sockaddr_in *netmask4 = (struct sockaddr_in *) netmask; | ||
670 | struct sockaddr_in *tmp = NULL; | ||
671 | struct sockaddr_in network4; | ||
672 | |||
673 | net = GNUNET_malloc(sizeof (struct ATS_Network) + 2 * sizeof (struct sockaddr_in)); | ||
674 | tmp = (struct sockaddr_in *) &net[1]; | ||
675 | net->network = (struct sockaddr *) &tmp[0]; | ||
676 | net->netmask = (struct sockaddr *) &tmp[1]; | ||
677 | net->length = addrlen; | ||
678 | |||
679 | network4.sin_family = AF_INET; | ||
680 | network4.sin_port = htons (0); | ||
681 | #if HAVE_SOCKADDR_IN_SIN_LEN | ||
682 | network4.sin_len = sizeof (network4); | ||
683 | #endif | ||
684 | network4.sin_addr.s_addr = (addr4->sin_addr.s_addr & netmask4->sin_addr.s_addr); | ||
685 | |||
686 | memcpy (net->netmask, netmask4, sizeof (struct sockaddr_in)); | ||
687 | memcpy (net->network, &network4, sizeof (struct sockaddr_in)); | ||
688 | } | ||
689 | |||
690 | if (addr->sa_family == AF_INET6) | ||
691 | { | ||
692 | struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) addr; | ||
693 | struct sockaddr_in6 *netmask6 = (struct sockaddr_in6 *) netmask; | ||
694 | struct sockaddr_in6 * tmp = NULL; | ||
695 | struct sockaddr_in6 network6; | ||
696 | |||
697 | net = GNUNET_malloc(sizeof (struct ATS_Network) + 2 * sizeof (struct sockaddr_in6)); | ||
698 | tmp = (struct sockaddr_in6 *) &net[1]; | ||
699 | net->network = (struct sockaddr *) &tmp[0]; | ||
700 | net->netmask = (struct sockaddr *) &tmp[1]; | ||
701 | net->length = addrlen; | ||
702 | |||
703 | network6.sin6_family = AF_INET6; | ||
704 | network6.sin6_port = htons (0); | ||
705 | #if HAVE_SOCKADDR_IN_SIN_LEN | ||
706 | network6.sin6_len = sizeof (network6); | ||
707 | #endif | ||
708 | int c = 0; | ||
709 | uint32_t *addr_elem = (uint32_t *) &addr6->sin6_addr; | ||
710 | uint32_t *mask_elem = (uint32_t *) &netmask6->sin6_addr; | ||
711 | uint32_t *net_elem = (uint32_t *) &network6.sin6_addr; | ||
712 | for (c = 0; c < 4; c++) | ||
713 | net_elem[c] = addr_elem[c] & mask_elem[c]; | ||
714 | |||
715 | memcpy (net->netmask, netmask6, sizeof (struct sockaddr_in6)); | ||
716 | memcpy (net->network, &network6, sizeof (struct sockaddr_in6)); | ||
717 | } | ||
718 | |||
719 | /* Store in list */ | ||
720 | if (net != NULL) | ||
721 | { | ||
722 | char * netmask = strdup (GNUNET_a2s((struct sockaddr *) net->netmask, addrlen)); | ||
723 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding network `%s', netmask `%s'\n", | ||
724 | GNUNET_a2s((struct sockaddr *) net->network, addrlen), | ||
725 | netmask); | ||
726 | GNUNET_free (netmask); | ||
727 | GNUNET_CONTAINER_DLL_insert(sh->net_head, sh->net_tail, net); | ||
728 | } | ||
729 | return GNUNET_OK; | ||
730 | } | ||
731 | |||
732 | |||
733 | |||
734 | /** | ||
735 | * Periodically get list of addresses | ||
736 | * @param cls closure | ||
737 | * @param tc Task context | ||
738 | */ | ||
739 | static void | ||
740 | get_addresses (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
741 | { | ||
742 | struct GNUNET_ATS_SchedulingHandle * sh = cls; | ||
743 | sh->interface_task = GNUNET_SCHEDULER_NO_TASK; | ||
744 | delete_networks (sh); | ||
745 | GNUNET_OS_network_interfaces_list(interface_proc, sh); | ||
746 | |||
747 | sh->interface_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, get_addresses, NULL); | ||
748 | } | ||
749 | |||
750 | /** | ||
751 | * Returns where the address is located: LAN or WAN or ... | ||
752 | * @param addr address | ||
753 | * @param addrlen address length | ||
754 | * @return location as GNUNET_ATS_Information | ||
755 | */ | ||
756 | |||
757 | struct GNUNET_ATS_Information | ||
758 | GNUNET_ATS_address_get_type (struct GNUNET_ATS_SchedulingHandle * sh, const struct sockaddr * addr, socklen_t addrlen) | ||
759 | { | ||
760 | struct GNUNET_ATS_Information ats; | ||
761 | struct ATS_Network * cur = sh->net_head; | ||
762 | int type = GNUNET_ATS_NET_UNSPECIFIED; | ||
763 | |||
764 | /* IPv4 loopback check */ | ||
765 | if (addr->sa_family == AF_INET) | ||
766 | { | ||
767 | struct sockaddr_in * a4 = (struct sockaddr_in *) addr; | ||
768 | |||
769 | if ((a4->sin_addr.s_addr & htonl(0xff000000)) == htonl (0x7f000000)) | ||
770 | type = GNUNET_ATS_NET_LOOPBACK; | ||
771 | } | ||
772 | /* IPv6 loopback check */ | ||
773 | if (addr->sa_family == AF_INET6) | ||
774 | { | ||
775 | struct sockaddr_in6 * a6 = (struct sockaddr_in6 *) addr; | ||
776 | if (IN6_IS_ADDR_LOOPBACK (&a6->sin6_addr)) | ||
777 | type = GNUNET_ATS_NET_LOOPBACK; | ||
778 | } | ||
779 | |||
780 | /* Check local networks */ | ||
781 | while ((cur != NULL) && (type == GNUNET_ATS_NET_UNSPECIFIED)) | ||
782 | { | ||
783 | if (addrlen != cur->length) | ||
784 | { | ||
785 | cur = cur->next; | ||
786 | continue; | ||
787 | } | ||
788 | |||
789 | if (addr->sa_family == AF_INET) | ||
790 | { | ||
791 | struct sockaddr_in * a4 = (struct sockaddr_in *) addr; | ||
792 | struct sockaddr_in * net4 = (struct sockaddr_in *) cur->network; | ||
793 | struct sockaddr_in * mask4 = (struct sockaddr_in *) cur->netmask; | ||
794 | |||
795 | if (((a4->sin_addr.s_addr & mask4->sin_addr.s_addr)) == net4->sin_addr.s_addr) | ||
796 | { | ||
797 | char * net = strdup (GNUNET_a2s ((const struct sockaddr *) net4, addrlen)); | ||
798 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "`%s' is in network `%s'\n", | ||
799 | GNUNET_a2s ((const struct sockaddr *)a4, addrlen), | ||
800 | net); | ||
801 | GNUNET_free (net); | ||
802 | type = GNUNET_ATS_NET_LAN; | ||
803 | } | ||
804 | } | ||
805 | if (addr->sa_family == AF_INET6) | ||
806 | { | ||
807 | struct sockaddr_in6 * a6 = (struct sockaddr_in6 *) addr; | ||
808 | struct sockaddr_in6 * net6 = (struct sockaddr_in6 *) cur->network; | ||
809 | struct sockaddr_in6 * mask6 = (struct sockaddr_in6 *) cur->netmask; | ||
810 | |||
811 | int res = GNUNET_YES; | ||
812 | int c = 0; | ||
813 | uint32_t *addr_elem = (uint32_t *) &a6->sin6_addr; | ||
814 | uint32_t *mask_elem = (uint32_t *) &mask6->sin6_addr; | ||
815 | uint32_t *net_elem = (uint32_t *) &net6->sin6_addr; | ||
816 | for (c = 0; c < 4; c++) | ||
817 | if ((addr_elem[c] & mask_elem[c]) != net_elem[c]) | ||
818 | res = GNUNET_NO; | ||
819 | |||
820 | if (res == GNUNET_YES) | ||
821 | { | ||
822 | char * net = strdup (GNUNET_a2s ((const struct sockaddr *) net6, addrlen)); | ||
823 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "`%s' is in network `%s'\n", | ||
824 | GNUNET_a2s ((const struct sockaddr *) a6, addrlen), | ||
825 | net); | ||
826 | GNUNET_free (net); | ||
827 | type = GNUNET_ATS_NET_LAN; | ||
828 | } | ||
829 | } | ||
830 | cur = cur->next; | ||
831 | } | ||
832 | |||
833 | /* local network found for this address, default: WAN */ | ||
834 | if (type == GNUNET_ATS_NET_UNSPECIFIED) | ||
835 | type = GNUNET_ATS_NET_WAN; | ||
836 | |||
837 | ats.type = htonl (GNUNET_ATS_NETWORK_TYPE); | ||
838 | ats.value = htonl (type); | ||
839 | return ats; | ||
840 | } | ||
588 | 841 | ||
589 | /** | 842 | /** |
590 | * Initialize the ATS subsystem. | 843 | * Initialize the ATS subsystem. |
@@ -606,6 +859,8 @@ GNUNET_ATS_scheduling_init (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
606 | sh->suggest_cb = suggest_cb; | 859 | sh->suggest_cb = suggest_cb; |
607 | sh->suggest_cb_cls = suggest_cb_cls; | 860 | sh->suggest_cb_cls = suggest_cb_cls; |
608 | GNUNET_array_grow (sh->session_array, sh->session_array_size, 4); | 861 | GNUNET_array_grow (sh->session_array, sh->session_array_size, 4); |
862 | GNUNET_OS_network_interfaces_list(interface_proc, sh); | ||
863 | sh->interface_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, get_addresses, NULL); | ||
609 | reconnect (sh); | 864 | reconnect (sh); |
610 | return sh; | 865 | return sh; |
611 | } | 866 | } |
@@ -636,6 +891,14 @@ GNUNET_ATS_scheduling_done (struct GNUNET_ATS_SchedulingHandle *sh) | |||
636 | GNUNET_SCHEDULER_cancel (sh->task); | 891 | GNUNET_SCHEDULER_cancel (sh->task); |
637 | sh->task = GNUNET_SCHEDULER_NO_TASK; | 892 | sh->task = GNUNET_SCHEDULER_NO_TASK; |
638 | } | 893 | } |
894 | |||
895 | delete_networks (sh); | ||
896 | if (sh->interface_task != GNUNET_SCHEDULER_NO_TASK) | ||
897 | { | ||
898 | GNUNET_SCHEDULER_cancel(sh->interface_task); | ||
899 | sh->interface_task = GNUNET_SCHEDULER_NO_TASK; | ||
900 | } | ||
901 | |||
639 | GNUNET_array_grow (sh->session_array, sh->session_array_size, 0); | 902 | GNUNET_array_grow (sh->session_array, sh->session_array_size, 0); |
640 | GNUNET_free (sh); | 903 | GNUNET_free (sh); |
641 | } | 904 | } |
diff --git a/src/ats/gnunet-service-ats_addresses.c b/src/ats/gnunet-service-ats_addresses.c index 19fe8152c..159ff685e 100644 --- a/src/ats/gnunet-service-ats_addresses.c +++ b/src/ats/gnunet-service-ats_addresses.c | |||
@@ -73,22 +73,6 @@ struct ATS_Address | |||
73 | 73 | ||
74 | }; | 74 | }; |
75 | 75 | ||
76 | struct ATS_Network | ||
77 | { | ||
78 | struct ATS_Network * next; | ||
79 | |||
80 | struct ATS_Network * prev; | ||
81 | |||
82 | struct sockaddr *network; | ||
83 | struct sockaddr *netmask; | ||
84 | socklen_t length; | ||
85 | }; | ||
86 | |||
87 | |||
88 | struct ATS_Network * net_head; | ||
89 | |||
90 | struct ATS_Network * net_tail; | ||
91 | |||
92 | static struct GNUNET_CONTAINER_MultiHashMap *addresses; | 76 | static struct GNUNET_CONTAINER_MultiHashMap *addresses; |
93 | 77 | ||
94 | static unsigned long long wan_quota_in; | 78 | static unsigned long long wan_quota_in; |
@@ -97,9 +81,6 @@ static unsigned long long wan_quota_out; | |||
97 | 81 | ||
98 | static unsigned int active_addr_count; | 82 | static unsigned int active_addr_count; |
99 | 83 | ||
100 | static GNUNET_SCHEDULER_TaskIdentifier interface_task; | ||
101 | |||
102 | |||
103 | /** | 84 | /** |
104 | * Update a bandwidth assignment for a peer. This trivial method currently | 85 | * Update a bandwidth assignment for a peer. This trivial method currently |
105 | * simply assigns the same share to all active connections. | 86 | * simply assigns the same share to all active connections. |
@@ -475,202 +456,7 @@ GAS_addresses_change_preference (const struct GNUNET_PeerIdentity *peer, | |||
475 | // do nothing for now... | 456 | // do nothing for now... |
476 | } | 457 | } |
477 | 458 | ||
478 | /** | ||
479 | * Returns where the address is located: LAN or WAN or ... | ||
480 | * @param addr address | ||
481 | * @param addrlen address length | ||
482 | * @return location as GNUNET_ATS_Information | ||
483 | */ | ||
484 | |||
485 | struct GNUNET_ATS_Information | ||
486 | GAS_addresses_type (const struct sockaddr * addr, socklen_t addrlen) | ||
487 | { | ||
488 | struct GNUNET_ATS_Information ats; | ||
489 | struct ATS_Network * cur = net_head; | ||
490 | int type = GNUNET_ATS_NET_UNSPECIFIED; | ||
491 | |||
492 | /* IPv4 loopback check */ | ||
493 | if (addr->sa_family == AF_INET) | ||
494 | { | ||
495 | struct sockaddr_in * a4 = (struct sockaddr_in *) addr; | ||
496 | |||
497 | if (((a4->sin_addr.s_addr & htonl(0xff000000)) & htonl (0x7f000000)) == htonl (0x7f000000)) | ||
498 | type = GNUNET_ATS_NET_LOOPBACK; | ||
499 | } | ||
500 | /* IPv6 loopback check */ | ||
501 | if (addr->sa_family == AF_INET6) | ||
502 | { | ||
503 | struct sockaddr_in6 * a6 = (struct sockaddr_in6 *) addr; | ||
504 | if (IN6_IS_ADDR_LOOPBACK (&a6->sin6_addr)) | ||
505 | type = GNUNET_ATS_NET_LOOPBACK; | ||
506 | } | ||
507 | |||
508 | /* Check local networks */ | ||
509 | while ((cur != NULL) && (type == GNUNET_ATS_NET_UNSPECIFIED)) | ||
510 | { | ||
511 | if (addrlen != cur->length) | ||
512 | { | ||
513 | cur = cur->next; | ||
514 | continue; | ||
515 | } | ||
516 | |||
517 | if (addr->sa_family == AF_INET) | ||
518 | { | ||
519 | struct sockaddr_in * a4 = (struct sockaddr_in *) addr; | ||
520 | struct sockaddr_in * net4 = (struct sockaddr_in *) cur->network; | ||
521 | struct sockaddr_in * mask4 = (struct sockaddr_in *) cur->netmask; | ||
522 | |||
523 | if (((a4->sin_addr.s_addr & mask4->sin_addr.s_addr) & net4->sin_addr.s_addr) == net4->sin_addr.s_addr) | ||
524 | { | ||
525 | char * net = strdup (GNUNET_a2s ((const struct sockaddr *) net4, addrlen)); | ||
526 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "`%s' is in network `%s'\n", | ||
527 | GNUNET_a2s ((const struct sockaddr *)a4, addrlen), | ||
528 | net); | ||
529 | GNUNET_free (net); | ||
530 | type = GNUNET_ATS_NET_LAN; | ||
531 | } | ||
532 | } | ||
533 | if (addr->sa_family == AF_INET6) | ||
534 | { | ||
535 | struct sockaddr_in6 * a6 = (struct sockaddr_in6 *) addr; | ||
536 | struct sockaddr_in6 * net6 = (struct sockaddr_in6 *) cur->network; | ||
537 | struct sockaddr_in6 * mask6 = (struct sockaddr_in6 *) cur->netmask; | ||
538 | |||
539 | int res = GNUNET_YES; | ||
540 | int c = 0; | ||
541 | for (c = 0; c < 4; c++) | ||
542 | { | ||
543 | if (((a6->sin6_addr.__in6_u.__u6_addr32[c] & mask6->sin6_addr.__in6_u.__u6_addr32[c]) | net6->sin6_addr.__in6_u.__u6_addr32[c]) != net6->sin6_addr.__in6_u.__u6_addr32[c]) | ||
544 | res = GNUNET_NO; | ||
545 | } | ||
546 | |||
547 | if (res == GNUNET_YES) | ||
548 | { | ||
549 | char * net = strdup (GNUNET_a2s ((const struct sockaddr *) net6, addrlen)); | ||
550 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "`%s' is in network `%s'\n", | ||
551 | GNUNET_a2s ((const struct sockaddr *) a6, addrlen), | ||
552 | net); | ||
553 | GNUNET_free (net); | ||
554 | type = GNUNET_ATS_NET_LAN; | ||
555 | } | ||
556 | } | ||
557 | cur = cur->next; | ||
558 | } | ||
559 | |||
560 | /* local network found for this address, default: WAN */ | ||
561 | if (type == GNUNET_ATS_NET_UNSPECIFIED) | ||
562 | type = GNUNET_ATS_NET_WAN; | ||
563 | 459 | ||
564 | ats.type = htonl (GNUNET_ATS_NETWORK_TYPE); | ||
565 | ats.value = htonl (type); | ||
566 | return ats; | ||
567 | } | ||
568 | |||
569 | static int | ||
570 | interface_proc (void *cls, const char *name, | ||
571 | int isDefault, | ||
572 | const struct sockaddr * | ||
573 | addr, | ||
574 | const struct sockaddr * | ||
575 | broadcast_addr, | ||
576 | const struct sockaddr * | ||
577 | netmask, socklen_t addrlen) | ||
578 | { | ||
579 | /* Calculate network */ | ||
580 | struct ATS_Network *net = NULL; | ||
581 | if (addr->sa_family == AF_INET) | ||
582 | { | ||
583 | struct sockaddr_in *addr4 = (struct sockaddr_in *) addr; | ||
584 | struct sockaddr_in *netmask4 = (struct sockaddr_in *) netmask; | ||
585 | struct sockaddr_in *tmp = NULL; | ||
586 | struct sockaddr_in network4; | ||
587 | |||
588 | net = GNUNET_malloc(sizeof (struct ATS_Network) + 2 * sizeof (struct sockaddr_in)); | ||
589 | tmp = (struct sockaddr_in *) &net[1]; | ||
590 | net->network = (struct sockaddr *) &tmp[0]; | ||
591 | net->netmask = (struct sockaddr *) &tmp[1]; | ||
592 | net->length = addrlen; | ||
593 | |||
594 | network4.sin_family = AF_INET; | ||
595 | network4.sin_port = htons (0); | ||
596 | #if HAVE_SOCKADDR_IN_SIN_LEN | ||
597 | network4.sin_len = sizeof (network4); | ||
598 | #endif | ||
599 | network4.sin_addr.s_addr = (addr4->sin_addr.s_addr & netmask4->sin_addr.s_addr); | ||
600 | |||
601 | memcpy (net->netmask, netmask4, sizeof (struct sockaddr_in)); | ||
602 | memcpy (net->network, &network4, sizeof (struct sockaddr_in)); | ||
603 | |||
604 | char * netmask = strdup (GNUNET_a2s((struct sockaddr *) net->netmask, addrlen)); | ||
605 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding network `%s', netmask `%s'\n", | ||
606 | GNUNET_a2s((struct sockaddr *) net->network, addrlen), | ||
607 | netmask); | ||
608 | GNUNET_free (netmask); | ||
609 | |||
610 | } | ||
611 | |||
612 | if (addr->sa_family == AF_INET6) | ||
613 | { | ||
614 | struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) addr; | ||
615 | struct sockaddr_in6 *netmask6 = (struct sockaddr_in6 *) netmask; | ||
616 | struct sockaddr_in6 * tmp = NULL; | ||
617 | struct sockaddr_in6 network6; | ||
618 | |||
619 | net = GNUNET_malloc(sizeof (struct ATS_Network) + 2 * sizeof (struct sockaddr_in6)); | ||
620 | tmp = (struct sockaddr_in6 *) &net[1]; | ||
621 | net->network = (struct sockaddr *) &tmp[0]; | ||
622 | net->netmask = (struct sockaddr *) &tmp[1]; | ||
623 | net->length = addrlen; | ||
624 | |||
625 | network6.sin6_family = AF_INET6; | ||
626 | network6.sin6_port = htons (0); | ||
627 | #if HAVE_SOCKADDR_IN_SIN_LEN | ||
628 | network6.sin6_len = sizeof (network6); | ||
629 | #endif | ||
630 | int c = 0; | ||
631 | for (c = 0; c < 4; c++) | ||
632 | { | ||
633 | network6.sin6_addr.__in6_u.__u6_addr32[c] = addr6->sin6_addr.__in6_u.__u6_addr32[c] & netmask6->sin6_addr.__in6_u.__u6_addr32[c]; | ||
634 | } | ||
635 | |||
636 | memcpy (net->netmask, netmask6, sizeof (struct sockaddr_in6)); | ||
637 | memcpy (net->network, &network6, sizeof (struct sockaddr_in6)); | ||
638 | |||
639 | char * netmask = strdup (GNUNET_a2s((struct sockaddr *) net->netmask, addrlen)); | ||
640 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding network `%s', netmask `%s'\n", | ||
641 | GNUNET_a2s((struct sockaddr *) net->network, addrlen), | ||
642 | netmask); | ||
643 | GNUNET_free (netmask); | ||
644 | } | ||
645 | |||
646 | /* Store in list */ | ||
647 | if (net != NULL) | ||
648 | GNUNET_CONTAINER_DLL_insert(net_head, net_tail, net); | ||
649 | |||
650 | return GNUNET_OK; | ||
651 | } | ||
652 | |||
653 | static void | ||
654 | delete_networks () | ||
655 | { | ||
656 | struct ATS_Network * cur = net_head; | ||
657 | while (cur != NULL) | ||
658 | { | ||
659 | GNUNET_CONTAINER_DLL_remove(net_head, net_tail, cur); | ||
660 | GNUNET_free (cur); | ||
661 | cur = net_head; | ||
662 | } | ||
663 | } | ||
664 | |||
665 | static void | ||
666 | get_addresses (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
667 | { | ||
668 | interface_task = GNUNET_SCHEDULER_NO_TASK; | ||
669 | delete_networks (); | ||
670 | GNUNET_OS_network_interfaces_list(interface_proc, NULL); | ||
671 | |||
672 | interface_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, get_addresses, NULL); | ||
673 | } | ||
674 | 460 | ||
675 | /** | 461 | /** |
676 | * Initialize address subsystem. | 462 | * Initialize address subsystem. |
@@ -689,8 +475,6 @@ GAS_addresses_init (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
689 | "WAN_QUOTA_OUT", | 475 | "WAN_QUOTA_OUT", |
690 | &wan_quota_out)); | 476 | &wan_quota_out)); |
691 | addresses = GNUNET_CONTAINER_multihashmap_create (128); | 477 | addresses = GNUNET_CONTAINER_multihashmap_create (128); |
692 | |||
693 | interface_task = GNUNET_SCHEDULER_add_now(get_addresses, NULL); | ||
694 | } | 478 | } |
695 | 479 | ||
696 | 480 | ||
@@ -727,12 +511,6 @@ GAS_addresses_destroy_all () | |||
727 | void | 511 | void |
728 | GAS_addresses_done () | 512 | GAS_addresses_done () |
729 | { | 513 | { |
730 | delete_networks (); | ||
731 | if (interface_task != GNUNET_SCHEDULER_NO_TASK) | ||
732 | { | ||
733 | GNUNET_SCHEDULER_cancel(interface_task); | ||
734 | interface_task = GNUNET_SCHEDULER_NO_TASK; | ||
735 | } | ||
736 | GAS_addresses_destroy_all (); | 514 | GAS_addresses_destroy_all (); |
737 | GNUNET_CONTAINER_multihashmap_destroy (addresses); | 515 | GNUNET_CONTAINER_multihashmap_destroy (addresses); |
738 | addresses = NULL; | 516 | addresses = NULL; |
diff --git a/src/ats/gnunet-service-ats_addresses.h b/src/ats/gnunet-service-ats_addresses.h index ab5f249e4..41a9b739f 100644 --- a/src/ats/gnunet-service-ats_addresses.h +++ b/src/ats/gnunet-service-ats_addresses.h | |||
@@ -46,16 +46,6 @@ void | |||
46 | GAS_addresses_done (void); | 46 | GAS_addresses_done (void); |
47 | 47 | ||
48 | /** | 48 | /** |
49 | * Returns where the address is located: LAN or WAN or ... | ||
50 | * @param addr address | ||
51 | * @param addrlen address length | ||
52 | * @return location as GNUNET_ATS_Information | ||
53 | */ | ||
54 | |||
55 | struct GNUNET_ATS_Information | ||
56 | GAS_addresses_type (const struct sockaddr * addr, socklen_t addrlen); | ||
57 | |||
58 | /** | ||
59 | * This address is now used or not used anymore | 49 | * This address is now used or not used anymore |
60 | */ | 50 | */ |
61 | void | 51 | void |
diff --git a/src/include/gnunet_ats_service.h b/src/include/gnunet_ats_service.h index 898a06654..421855710 100644 --- a/src/include/gnunet_ats_service.h +++ b/src/include/gnunet_ats_service.h | |||
@@ -522,6 +522,19 @@ void | |||
522 | GNUNET_ATS_suggest_address_cancel (struct GNUNET_ATS_SchedulingHandle *sh, | 522 | GNUNET_ATS_suggest_address_cancel (struct GNUNET_ATS_SchedulingHandle *sh, |
523 | const struct GNUNET_PeerIdentity *peer); | 523 | const struct GNUNET_PeerIdentity *peer); |
524 | 524 | ||
525 | |||
526 | /** | ||
527 | * Returns where the address is located: LAN or WAN or ... | ||
528 | * @param addr address | ||
529 | * @param addrlen address length | ||
530 | * @return location as GNUNET_ATS_Information | ||
531 | */ | ||
532 | struct GNUNET_ATS_Information | ||
533 | GNUNET_ATS_address_get_type (struct GNUNET_ATS_SchedulingHandle *sh, | ||
534 | const struct sockaddr * addr, | ||
535 | socklen_t addrlen); | ||
536 | |||
537 | |||
525 | /** | 538 | /** |
526 | * We have updated performance statistics for a given address. Note | 539 | * We have updated performance statistics for a given address. Note |
527 | * that this function can be called for addresses that are currently | 540 | * that this function can be called for addresses that are currently |