diff options
-rw-r--r-- | src/hostlist/gnunet-daemon-hostlist.c | 50 | ||||
-rw-r--r-- | src/hostlist/gnunet-daemon-hostlist.h | 25 | ||||
-rw-r--r-- | src/hostlist/hostlist-client.c | 451 | ||||
-rw-r--r-- | src/hostlist/hostlist-client.h | 42 | ||||
-rw-r--r-- | src/hostlist/hostlist-server.c | 214 | ||||
-rw-r--r-- | src/hostlist/hostlist-server.h | 2 |
6 files changed, 324 insertions, 460 deletions
diff --git a/src/hostlist/gnunet-daemon-hostlist.c b/src/hostlist/gnunet-daemon-hostlist.c index 3622e0e8f..c06ee5f56 100644 --- a/src/hostlist/gnunet-daemon-hostlist.c +++ b/src/hostlist/gnunet-daemon-hostlist.c | |||
@@ -168,21 +168,11 @@ static int advertisement_handler (void *cls, | |||
168 | struct GNUNET_TIME_Relative latency, | 168 | struct GNUNET_TIME_Relative latency, |
169 | uint32_t distance) | 169 | uint32_t distance) |
170 | { | 170 | { |
171 | if ( !learning ) | 171 | GNUNET_assert (NULL != client_adv_handler); |
172 | { | 172 | return (*client_adv_handler) (cls, peer, message, latency, distance); |
173 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
174 | "Recieved hostlist advertisement, but I am not learning!\n"); | ||
175 | return GNUNET_NO; | ||
176 | } | ||
177 | |||
178 | if (learning && (NULL != client_adv_handler)) | ||
179 | { | ||
180 | (*client_adv_handler) (cls, peer, message, latency, distance); | ||
181 | return GNUNET_YES; | ||
182 | } | ||
183 | return GNUNET_NO; | ||
184 | } | 173 | } |
185 | 174 | ||
175 | |||
186 | /** | 176 | /** |
187 | * Method called whenever a given peer connects. Wrapper to call both client's and server's functions | 177 | * Method called whenever a given peer connects. Wrapper to call both client's and server's functions |
188 | * | 178 | * |
@@ -260,14 +250,22 @@ cleaning_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
260 | } | 250 | } |
261 | 251 | ||
262 | /** | 252 | /** |
263 | * List of handlers for the messages understood by this | 253 | * List of handlers if we are learning. |
264 | * service. | ||
265 | */ | 254 | */ |
266 | static struct GNUNET_CORE_MessageHandler handlers[] = { | 255 | static struct GNUNET_CORE_MessageHandler learn_handlers[] = { |
267 | { &advertisement_handler, GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT, 0}, | 256 | { &advertisement_handler, GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT, 0}, |
257 | { NULL, 0, 0 } | ||
258 | }; | ||
259 | |||
260 | |||
261 | /** | ||
262 | * List of handlers if we are not learning. | ||
263 | */ | ||
264 | static struct GNUNET_CORE_MessageHandler no_learn_handlers[] = { | ||
268 | { NULL, 0, 0 } | 265 | { NULL, 0, 0 } |
269 | }; | 266 | }; |
270 | 267 | ||
268 | |||
271 | /** | 269 | /** |
272 | * Main function that will be run. | 270 | * Main function that will be run. |
273 | * | 271 | * |
@@ -295,13 +293,13 @@ run (void *cls, | |||
295 | stats = GNUNET_STATISTICS_create (sched, "hostlist", cfg); | 293 | stats = GNUNET_STATISTICS_create (sched, "hostlist", cfg); |
296 | 294 | ||
297 | core = GNUNET_CORE_connect (sched, cfg, | 295 | core = GNUNET_CORE_connect (sched, cfg, |
298 | GNUNET_TIME_UNIT_FOREVER_REL, | 296 | GNUNET_TIME_UNIT_FOREVER_REL, |
299 | NULL, | 297 | NULL, |
300 | &core_init, | 298 | &core_init, |
301 | NULL, &connect_handler, &disconnect_handler, | 299 | NULL, &connect_handler, &disconnect_handler, |
302 | NULL, GNUNET_NO, | 300 | NULL, GNUNET_NO, |
303 | NULL, GNUNET_NO, | 301 | NULL, GNUNET_NO, |
304 | handlers); | 302 | learning? learn_handlers : no_learn_handlers); |
305 | 303 | ||
306 | if (bootstrapping) | 304 | if (bootstrapping) |
307 | { | 305 | { |
@@ -312,10 +310,6 @@ run (void *cls, | |||
312 | { | 310 | { |
313 | GNUNET_HOSTLIST_server_start (cfg, sched, stats, core, &server_ch, &server_dh, advertising ); | 311 | GNUNET_HOSTLIST_server_start (cfg, sched, stats, core, &server_ch, &server_dh, advertising ); |
314 | } | 312 | } |
315 | if (learning) | ||
316 | { | ||
317 | |||
318 | } | ||
319 | 313 | ||
320 | GNUNET_SCHEDULER_add_delayed (sched, | 314 | GNUNET_SCHEDULER_add_delayed (sched, |
321 | GNUNET_TIME_UNIT_FOREVER_REL, | 315 | GNUNET_TIME_UNIT_FOREVER_REL, |
diff --git a/src/hostlist/gnunet-daemon-hostlist.h b/src/hostlist/gnunet-daemon-hostlist.h index 7c30344b2..0b185ab7e 100644 --- a/src/hostlist/gnunet-daemon-hostlist.h +++ b/src/hostlist/gnunet-daemon-hostlist.h | |||
@@ -41,30 +41,5 @@ | |||
41 | */ | 41 | */ |
42 | #define DEBUG_HOSTLIST GNUNET_NO | 42 | #define DEBUG_HOSTLIST GNUNET_NO |
43 | 43 | ||
44 | /** | ||
45 | * A HOSTLIST_ADV message is used to exchange information about | ||
46 | * hostlist advertisements. This struct is always | ||
47 | * followed by the actual url under which the hostlist can be obtained: | ||
48 | * | ||
49 | * 1) transport-name (0-terminated) | ||
50 | * 2) address-length (uint32_t, network byte order; possibly | ||
51 | * unaligned!) | ||
52 | * 3) address expiration (GNUNET_TIME_AbsoluteNBO); possibly | ||
53 | * unaligned!) | ||
54 | * 4) address (address-length bytes; possibly unaligned!) | ||
55 | */ | ||
56 | struct GNUNET_HOSTLIST_ADV_Message | ||
57 | { | ||
58 | /** | ||
59 | * Type will be GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT. | ||
60 | */ | ||
61 | struct GNUNET_MessageHeader header; | ||
62 | |||
63 | /** | ||
64 | * Always zero (for alignment). | ||
65 | */ | ||
66 | uint32_t reserved GNUNET_PACKED; | ||
67 | }; | ||
68 | |||
69 | 44 | ||
70 | /* end of gnunet-daemon-hostlist.h */ | 45 | /* end of gnunet-daemon-hostlist.h */ |
diff --git a/src/hostlist/hostlist-client.c b/src/hostlist/hostlist-client.c index ccc00a2ab..d882cdfbd 100644 --- a/src/hostlist/hostlist-client.c +++ b/src/hostlist/hostlist-client.c | |||
@@ -21,7 +21,8 @@ | |||
21 | /** | 21 | /** |
22 | * @file hostlist/hostlist-client.c | 22 | * @file hostlist/hostlist-client.c |
23 | * @brief hostlist support. Downloads HELLOs via HTTP. | 23 | * @brief hostlist support. Downloads HELLOs via HTTP. |
24 | * @author Christian Grothoff, Matthias Wachs | 24 | * @author Christian Grothoff |
25 | * @author Matthias Wachs | ||
25 | */ | 26 | */ |
26 | 27 | ||
27 | #include "platform.h" | 28 | #include "platform.h" |
@@ -37,6 +38,8 @@ | |||
37 | 38 | ||
38 | #define DEBUG_HOSTLIST_CLIENT GNUNET_YES | 39 | #define DEBUG_HOSTLIST_CLIENT GNUNET_YES |
39 | 40 | ||
41 | #define MAX_URL_LEN 1000 | ||
42 | |||
40 | /** | 43 | /** |
41 | * Number of connections that we must have to NOT download | 44 | * Number of connections that we must have to NOT download |
42 | * hostlists anymore. | 45 | * hostlists anymore. |
@@ -44,6 +47,58 @@ | |||
44 | #define MIN_CONNECTIONS 4 | 47 | #define MIN_CONNECTIONS 4 |
45 | 48 | ||
46 | /** | 49 | /** |
50 | * A single hostlist obtained by hostlist advertisements | ||
51 | */ | ||
52 | struct GNUNET_Hostlist | ||
53 | { | ||
54 | struct GNUNET_Hostlist * prev; | ||
55 | |||
56 | struct GNUNET_Hostlist * next; | ||
57 | |||
58 | /** | ||
59 | * URI where hostlist can be obtained | ||
60 | */ | ||
61 | const char *hostlist_uri; | ||
62 | |||
63 | /** | ||
64 | * Peer offering the hostlist. TO BE REMOVED. | ||
65 | */ | ||
66 | struct GNUNET_PeerIdentity peer; | ||
67 | |||
68 | /** | ||
69 | * Value describing the quality of the hostlist, the bigger the better but (should) never < 0 | ||
70 | * used for deciding which hostlist is replaced if MAX_NUMBER_HOSTLISTS in data structure is reached | ||
71 | * intial value = HOSTLIST_INITIAL | ||
72 | * increased every successful download by HOSTLIST_SUCCESSFULL_DOWNLOAD | ||
73 | * increased every successful download by number of obtained HELLO messages | ||
74 | * decreased every failed download by HOSTLIST_SUCCESSFULL_DOWNLOAD | ||
75 | */ | ||
76 | uint64_t quality; | ||
77 | |||
78 | /** | ||
79 | * Time the hostlist advertisement was recieved and the entry was created | ||
80 | */ | ||
81 | struct GNUNET_TIME_Absolute time_creation; | ||
82 | |||
83 | /** | ||
84 | * Last time the hostlist was obtained | ||
85 | */ | ||
86 | struct GNUNET_TIME_Absolute time_last_usage; | ||
87 | |||
88 | /** | ||
89 | * Number of HELLO messages obtained during last download | ||
90 | */ | ||
91 | uint32_t hello_count; | ||
92 | |||
93 | /** | ||
94 | * Number of times the hostlist was obtained | ||
95 | */ | ||
96 | uint32_t times_used; | ||
97 | |||
98 | }; | ||
99 | |||
100 | |||
101 | /** | ||
47 | * Our configuration. | 102 | * Our configuration. |
48 | */ | 103 | */ |
49 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | 104 | static const struct GNUNET_CONFIGURATION_Handle *cfg; |
@@ -114,19 +169,18 @@ static int bogus_url; | |||
114 | static unsigned int connection_count; | 169 | static unsigned int connection_count; |
115 | 170 | ||
116 | /** | 171 | /** |
117 | * Set if the user allows us to learn about new hostlists | ||
118 | * from the network. | ||
119 | */ | ||
120 | static int learning; | ||
121 | |||
122 | /** | ||
123 | * At what time MUST the current hostlist request be done? | 172 | * At what time MUST the current hostlist request be done? |
124 | */ | 173 | */ |
125 | static struct GNUNET_TIME_Absolute end_time; | 174 | static struct GNUNET_TIME_Absolute end_time; |
126 | 175 | ||
127 | struct GNUNET_Hostlist * dll_head; | 176 | /* DLL_? */ |
128 | struct GNUNET_Hostlist * dll_tail; | 177 | static struct GNUNET_Hostlist * dll_head; |
129 | int dll_size; | 178 | |
179 | /* DLL_? */ | ||
180 | static struct GNUNET_Hostlist * dll_tail; | ||
181 | |||
182 | /* DLL_? */ | ||
183 | static unsigned int dll_size; | ||
130 | 184 | ||
131 | /** | 185 | /** |
132 | * Process downloaded bits by calling callback on each HELLO. | 186 | * Process downloaded bits by calling callback on each HELLO. |
@@ -352,7 +406,7 @@ clean_up () | |||
352 | * receiving task with the scheduler. | 406 | * receiving task with the scheduler. |
353 | */ | 407 | */ |
354 | static void | 408 | static void |
355 | run_multi (); | 409 | run_multi (void); |
356 | 410 | ||
357 | 411 | ||
358 | /** | 412 | /** |
@@ -723,88 +777,54 @@ disconnect_handler (void *cls, | |||
723 | GNUNET_NO); | 777 | GNUNET_NO); |
724 | } | 778 | } |
725 | 779 | ||
726 | static int dll_contains ( char * uri) | ||
727 | { | ||
728 | struct GNUNET_Hostlist * actual = dll_head; | ||
729 | |||
730 | if (dll_size == 0) | ||
731 | return GNUNET_NO; | ||
732 | actual = dll_head; | ||
733 | 780 | ||
734 | while ( GNUNET_YES ) | 781 | /* DLL_? */ |
735 | { | 782 | static int |
736 | if ( 0 == strcmp(actual->hostlist_uri,uri) ) return GNUNET_YES; | 783 | dll_contains (const char * uri) |
737 | if (actual == dll_tail) break; | 784 | { |
738 | actual = actual->next; | 785 | struct GNUNET_Hostlist * pos; |
739 | } | ||
740 | 786 | ||
787 | pos = dll_head; | ||
788 | while (pos != NULL) | ||
789 | { | ||
790 | if (0 == strcmp(pos->hostlist_uri, uri) ) | ||
791 | return GNUNET_YES; | ||
792 | pos = pos->next; | ||
793 | } | ||
741 | return GNUNET_NO; | 794 | return GNUNET_NO; |
742 | } | 795 | } |
743 | 796 | ||
744 | struct GNUNET_Hostlist * dll_get ( char * uri ) | ||
745 | { | ||
746 | struct GNUNET_Hostlist * actual = dll_head; | ||
747 | |||
748 | if (dll_size == 0) | ||
749 | return NULL; | ||
750 | actual = dll_head; | ||
751 | |||
752 | while ( GNUNET_YES) | ||
753 | { | ||
754 | if ( 0 == strcmp(actual->hostlist_uri,uri) ) return actual; | ||
755 | if (actual == dll_tail) break; | ||
756 | actual = actual->next; | ||
757 | } | ||
758 | |||
759 | return NULL; | ||
760 | } | ||
761 | 797 | ||
762 | struct GNUNET_Hostlist * dll_get_lowest_quality ( ) | 798 | /* DLL_? */ |
799 | static struct GNUNET_Hostlist * | ||
800 | dll_get_lowest_quality ( ) | ||
763 | { | 801 | { |
764 | struct GNUNET_Hostlist * actual = dll_head; | 802 | struct GNUNET_Hostlist * pos; |
765 | struct GNUNET_Hostlist * lowest = NULL; | 803 | struct GNUNET_Hostlist * lowest; |
766 | 804 | ||
767 | if (dll_size == 0) | 805 | if (dll_size == 0) |
768 | return lowest; | 806 | return NULL; |
769 | 807 | lowest = dll_head; | |
770 | lowest = dll_tail; | 808 | pos = dll_head->next; |
771 | actual = dll_head; | 809 | while (pos != NULL) |
772 | 810 | { | |
773 | while ( GNUNET_YES) | 811 | if (pos->quality < lowest->quality) |
774 | { | 812 | lowest = pos; |
775 | if ( actual->quality < lowest->quality) lowest = actual; | 813 | pos = pos->next; |
776 | if (actual == dll_tail) break; | 814 | } |
777 | actual = actual->next; | ||
778 | } | ||
779 | |||
780 | return lowest; | 815 | return lowest; |
781 | } | 816 | } |
782 | 817 | ||
783 | static int dll_insert ( struct GNUNET_Hostlist * elem) | ||
784 | { | ||
785 | if (dll_size <= MAX_NUMBER_HOSTLISTS) | ||
786 | { | ||
787 | GNUNET_CONTAINER_DLL_insert(dll_head, dll_tail,elem); | ||
788 | dll_size++; | ||
789 | return GNUNET_OK; | ||
790 | } | ||
791 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
792 | "Maximum number of %u for hostlist entries reached, \n", MAX_NUMBER_HOSTLISTS ); | ||
793 | return GNUNET_SYSERR; | ||
794 | } | ||
795 | 818 | ||
796 | static int dll_remove ( struct GNUNET_Hostlist * elem) | 819 | #if DUMMY |
820 | /* TO BE REMOVED later */ | ||
821 | static void dll_insert ( struct GNUNET_Hostlist *hostlist) | ||
797 | { | 822 | { |
798 | if ( GNUNET_YES == dll_contains (elem->hostlist_uri)) | 823 | GNUNET_CONTAINER_DLL_insert(dll_head, dll_tail, hostlist); |
799 | { | 824 | dll_size++; |
800 | GNUNET_CONTAINER_DLL_remove(dll_head, dll_tail,elem); | ||
801 | dll_size--; | ||
802 | return GNUNET_OK; | ||
803 | } | ||
804 | return GNUNET_SYSERR; | ||
805 | } | 825 | } |
806 | 826 | ||
807 | void create_dummy_entries () | 827 | static void create_dummy_entries () |
808 | { | 828 | { |
809 | 829 | ||
810 | /* test */ | 830 | /* test */ |
@@ -869,6 +889,7 @@ void create_dummy_entries () | |||
869 | "Adding test peer '%s' with URI %s and quality %u to dll \n", GNUNET_h2s (&hostlist4->peer.hashPubKey) , hostlist4->hostlist_uri, hostlist4->quality); | 889 | "Adding test peer '%s' with URI %s and quality %u to dll \n", GNUNET_h2s (&hostlist4->peer.hashPubKey) , hostlist4->hostlist_uri, hostlist4->quality); |
870 | dll_insert (hostlist4); | 890 | dll_insert (hostlist4); |
871 | } | 891 | } |
892 | #endif | ||
872 | 893 | ||
873 | /** | 894 | /** |
874 | * Method called whenever an advertisement message arrives. | 895 | * Method called whenever an advertisement message arrives. |
@@ -886,81 +907,64 @@ advertisement_handler (void *cls, | |||
886 | struct GNUNET_TIME_Relative latency, | 907 | struct GNUNET_TIME_Relative latency, |
887 | uint32_t distance) | 908 | uint32_t distance) |
888 | { | 909 | { |
889 | if ( !learning ) | 910 | size_t size; |
890 | return GNUNET_NO; | 911 | size_t uri_size; |
891 | 912 | const struct GNUNET_MessageHeader * incoming; | |
892 | int size = ntohs (message->size); | 913 | const char *uri; |
893 | int uri_size = size - sizeof ( struct GNUNET_HOSTLIST_ADV_Message ); | ||
894 | char * uri = GNUNET_malloc ( uri_size ); | ||
895 | struct GNUNET_Hostlist * hostlist; | 914 | struct GNUNET_Hostlist * hostlist; |
896 | 915 | ||
897 | if ( ntohs (message->type) != GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT) | 916 | GNUNET_assert (ntohs (message->type) == GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT); |
898 | return GNUNET_NO; | 917 | size = ntohs (message->size); |
899 | 918 | if (size <= sizeof(struct GNUNET_MessageHeader)) | |
900 | const struct GNUNET_HOSTLIST_ADV_Message * incoming = (const struct GNUNET_HOSTLIST_ADV_Message *) message; | ||
901 | memcpy ( uri, &incoming[1], uri_size ); | ||
902 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
903 | "Hostlist client recieved advertisement from '%s' containing URI %s\n", GNUNET_i2s (peer), uri ); | ||
904 | |||
905 | create_dummy_entries(); | ||
906 | |||
907 | hostlist = GNUNET_malloc ( sizeof (struct GNUNET_Hostlist) ); | ||
908 | |||
909 | hostlist->peer = (*peer); | ||
910 | hostlist->hello_count = 0; | ||
911 | hostlist->hostlist_uri = GNUNET_malloc ( uri_size); | ||
912 | memcpy ( hostlist->hostlist_uri, &incoming[1], uri_size ); | ||
913 | hostlist->time_creation = GNUNET_TIME_absolute_get(); | ||
914 | hostlist->time_last_usage = GNUNET_TIME_absolute_get_zero(); | ||
915 | hostlist->times_used = 0; | ||
916 | hostlist->quality = HOSTLIST_INITIAL; | ||
917 | |||
918 | if ( GNUNET_YES != dll_contains (hostlist->hostlist_uri) ) | ||
919 | { | 919 | { |
920 | if ( MAX_NUMBER_HOSTLISTS > dll_size ) | 920 | GNUNET_break_op (0); |
921 | { | 921 | return GNUNET_SYSERR; |
922 | /* Entries available, add hostlist to dll */ | ||
923 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
924 | "Adding uri '%s' to dll\n", hostlist->hostlist_uri ); | ||
925 | dll_insert ( hostlist ); | ||
926 | return GNUNET_YES; | ||
927 | } | ||
928 | else | ||
929 | { | ||
930 | /* No free entries available, replace existing entry */ | ||
931 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
932 | "No free slots for hostlist available, searching for hostlist to replace\n" ); | ||
933 | |||
934 | struct GNUNET_Hostlist * lowest_quality = dll_get_lowest_quality(); | ||
935 | |||
936 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
937 | "Hostlist with URI %s has the worst quality of all with value %u \n", lowest_quality->hostlist_uri, lowest_quality->quality ); | ||
938 | /* replacing the entry with worst quality, if quality is below initial quality value */ | ||
939 | if ( lowest_quality->quality < HOSTLIST_INITIAL) | ||
940 | { | ||
941 | dll_remove(lowest_quality); | ||
942 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
943 | "URI '%s' removed \n",lowest_quality->hostlist_uri); | ||
944 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
945 | "URI '%s' added %s\n", hostlist->hostlist_uri); | ||
946 | dll_insert ( hostlist ); | ||
947 | } | ||
948 | return GNUNET_YES; | ||
949 | } | ||
950 | } | 922 | } |
951 | else | 923 | incoming = (const struct GNUNET_MessageHeader *) message; |
924 | uri = (const char*) &incoming[1]; | ||
925 | uri_size = size - sizeof (struct GNUNET_MessageHeader); | ||
926 | if (uri [uri_size - 1] != '\0') | ||
952 | { | 927 | { |
953 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 928 | GNUNET_break_op (0); |
954 | "Hostlist URI already in database\n"); | 929 | return GNUNET_SYSERR; |
955 | } | 930 | } |
931 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
932 | "Hostlist client recieved advertisement from `%s' containing URI `%s'\n", | ||
933 | GNUNET_i2s (peer), | ||
934 | uri); | ||
935 | if (GNUNET_YES != dll_contains (uri)) | ||
936 | return GNUNET_OK; | ||
937 | hostlist = GNUNET_malloc (sizeof (struct GNUNET_Hostlist) + uri_size); | ||
938 | hostlist->peer = *peer; | ||
939 | hostlist->hostlist_uri = (const char*) &hostlist[1]; | ||
940 | memcpy (&hostlist[1], uri, uri_size); | ||
941 | hostlist->time_creation = GNUNET_TIME_absolute_get(); | ||
942 | hostlist->time_last_usage = GNUNET_TIME_absolute_get_zero(); | ||
943 | hostlist->quality = HOSTLIST_INITIAL; | ||
944 | #if DUMMY | ||
945 | create_dummy_entries(); /* FIXME: remove later... */ | ||
946 | #endif | ||
947 | GNUNET_CONTAINER_DLL_insert(dll_head, dll_tail, hostlist); | ||
948 | dll_size++; | ||
949 | |||
950 | if (MAX_NUMBER_HOSTLISTS >= dll_size) | ||
951 | return GNUNET_OK; | ||
956 | 952 | ||
957 | /* since hostlist already existed in hashmap, object can be destroyed */ | 953 | /* No free entries available, replace existing entry */ |
958 | GNUNET_free ( hostlist->hostlist_uri ); | 954 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
959 | GNUNET_free ( hostlist ); | 955 | "Removing lowest quality entry\n" ); |
960 | 956 | struct GNUNET_Hostlist * lowest_quality = dll_get_lowest_quality(); | |
961 | return GNUNET_YES; | 957 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
958 | "Hostlist with URI `%s' has the worst quality of all with value %llu\n", | ||
959 | lowest_quality->hostlist_uri, | ||
960 | (unsigned long long) lowest_quality->quality); | ||
961 | GNUNET_CONTAINER_DLL_remove (dll_head, dll_tail, lowest_quality); | ||
962 | dll_size--; | ||
963 | GNUNET_free (lowest_quality); | ||
964 | return GNUNET_OK; | ||
962 | } | 965 | } |
963 | 966 | ||
967 | |||
964 | /** | 968 | /** |
965 | * Continuation called by the statistics code once | 969 | * Continuation called by the statistics code once |
966 | * we go the stat. Initiates hostlist download scheduling. | 970 | * we go the stat. Initiates hostlist download scheduling. |
@@ -998,11 +1002,13 @@ process_stat (void *cls, | |||
998 | 1002 | ||
999 | /** | 1003 | /** |
1000 | * Method to load persistent hostlist file during hostlist client startup | 1004 | * Method to load persistent hostlist file during hostlist client startup |
1001 | * param c configuration to use | ||
1002 | */ | 1005 | */ |
1003 | static int load_hostlist_file () | 1006 | static void |
1007 | load_hostlist_file () | ||
1004 | { | 1008 | { |
1005 | char *filename; | 1009 | char *filename; |
1010 | char *uri; | ||
1011 | char *emsg; | ||
1006 | 1012 | ||
1007 | if (GNUNET_OK != | 1013 | if (GNUNET_OK != |
1008 | GNUNET_CONFIGURATION_get_value_string (cfg, | 1014 | GNUNET_CONFIGURATION_get_value_string (cfg, |
@@ -1013,46 +1019,57 @@ static int load_hostlist_file () | |||
1013 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1019 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1014 | _("No `%s' specified in `%s' configuration, cannot load hostlists from file.\n"), | 1020 | _("No `%s' specified in `%s' configuration, cannot load hostlists from file.\n"), |
1015 | "HOSTLISTFILE", "HOSTLIST"); | 1021 | "HOSTLISTFILE", "HOSTLIST"); |
1016 | return GNUNET_SYSERR; | 1022 | return; |
1017 | } | 1023 | } |
1018 | 1024 | ||
1019 | struct GNUNET_BIO_ReadHandle * rh = GNUNET_BIO_read_open (filename); | 1025 | struct GNUNET_BIO_ReadHandle * rh = GNUNET_BIO_read_open (filename); |
1020 | if ( NULL == rh) | 1026 | if (NULL == rh) |
1021 | { | 1027 | { |
1022 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1028 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
1023 | ("Could not open file %s for reading to load hostlists\n"), filename); | 1029 | _("Could not open file `%s' for reading to load hostlists: %s\n"), |
1024 | return GNUNET_SYSERR; | 1030 | filename, |
1031 | STRERROR (errno)); | ||
1032 | GNUNET_free (filename); | ||
1033 | return; | ||
1025 | } | 1034 | } |
1026 | 1035 | ||
1027 | /* add code to read hostlists to file using bio */ | 1036 | /* add code to read hostlists to file using bio */ |
1028 | char *buffer = GNUNET_malloc (1000 * sizeof (char)); | 1037 | uri = NULL; |
1029 | /* char *token; | 1038 | while ( (GNUNET_OK == GNUNET_BIO_read_string (rh, "url" , &uri, MAX_URL_LEN)) && |
1030 | 1039 | #if 0 | |
1031 | while (GNUNET_OK == GNUNET_BIO_read_string (rh, NULL , &buffer, 1000) ) | 1040 | (GNUNET_OK == GNUNET_BIO_read_int32 (rh, ×_used)) && |
1032 | { | 1041 | (GNUNET_OK == GNUNET_BIO_read_int32 (rh, &hellos_returned)) && |
1033 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1042 | (GNUNET_OK == GNUNET_BIO_read_int64 (rh, &last_used.value)) && |
1034 | ("Read from file %s : %s \n"), filename, buffer); | 1043 | (GNUNET_OK == GNUNET_BIO_read_int64 (rh, &created.value)) && |
1035 | 1044 | (GNUNET_OK == GNUNET_BIO_read_int64 (rh, &quality)) | |
1036 | pch = strtok (str," ,.-"); | 1045 | #else |
1037 | while (pch != NULL) | 1046 | (1) |
1047 | #endif | ||
1048 | ) | ||
1038 | { | 1049 | { |
1039 | printf ("%s\n",pch); | 1050 | #if 0 |
1040 | pch = strtok (NULL, " ,.-"); | 1051 | hostlist = GNUNET_malloc (...); |
1041 | } | 1052 | #endif |
1042 | 1053 | uri = NULL; | |
1043 | } | 1054 | } |
1044 | */ | 1055 | GNUNET_free_non_null (uri); |
1045 | GNUNET_BIO_read_close ( rh , &buffer); | 1056 | emsg = NULL; |
1046 | return GNUNET_OK; | 1057 | GNUNET_BIO_read_close (rh, &emsg); |
1058 | if (emsg != NULL) | ||
1059 | GNUNET_free (emsg); | ||
1060 | GNUNET_free (filename); | ||
1047 | } | 1061 | } |
1048 | 1062 | ||
1063 | |||
1049 | /** | 1064 | /** |
1050 | * Method to load persistent hostlist file during hostlist client shutdown | 1065 | * Method to load persistent hostlist file during hostlist client shutdown |
1051 | * param c configuration to use | ||
1052 | */ | 1066 | */ |
1053 | static int save_hostlist_file () | 1067 | static void save_hostlist_file () |
1054 | { | 1068 | { |
1055 | char *filename; | 1069 | char *filename; |
1070 | struct GNUNET_Hostlist *pos; | ||
1071 | struct GNUNET_BIO_WriteHandle * wh; | ||
1072 | int ok; | ||
1056 | 1073 | ||
1057 | if (GNUNET_OK != | 1074 | if (GNUNET_OK != |
1058 | GNUNET_CONFIGURATION_get_value_string (cfg, | 1075 | GNUNET_CONFIGURATION_get_value_string (cfg, |
@@ -1063,71 +1080,48 @@ static int save_hostlist_file () | |||
1063 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1080 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1064 | _("No `%s' specified in `%s' configuration, cannot save hostlists to file.\n"), | 1081 | _("No `%s' specified in `%s' configuration, cannot save hostlists to file.\n"), |
1065 | "HOSTLISTFILE", "HOSTLIST"); | 1082 | "HOSTLISTFILE", "HOSTLIST"); |
1066 | return GNUNET_SYSERR; | 1083 | return; |
1067 | } | 1084 | } |
1068 | 1085 | wh = GNUNET_BIO_write_open (filename); | |
1069 | struct GNUNET_BIO_WriteHandle * wh = GNUNET_BIO_write_open (filename); | ||
1070 | if ( NULL == wh) | 1086 | if ( NULL == wh) |
1071 | { | 1087 | { |
1072 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1088 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1073 | ("Could not open file %s for writing to save hostlists\n"), | 1089 | _("Could not open file `%s' for writing to save hostlists: %s\n"), |
1074 | filename); | 1090 | filename, |
1075 | return GNUNET_SYSERR; | 1091 | STRERROR (errno)); |
1092 | return; | ||
1076 | } | 1093 | } |
1094 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1095 | _("Writing hostlist URIs to `%s'\n"), | ||
1096 | filename); | ||
1077 | 1097 | ||
1078 | /* add code to write hostlists to file using bio */ | 1098 | /* add code to write hostlists to file using bio */ |
1079 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1099 | ok = GNUNET_YES; |
1080 | "Writing hostlist to disk\n"); | 1100 | while (NULL != (pos = dll_head)) |
1081 | struct GNUNET_Hostlist * actual = dll_head; | 1101 | { |
1082 | struct GNUNET_Hostlist * next; | 1102 | GNUNET_CONTAINER_DLL_remove (dll_head, dll_tail, pos); |
1083 | char * content = GNUNET_malloc(1000 * sizeof (char)); | 1103 | dll_size--; |
1084 | char * buffer = GNUNET_malloc(1000 * sizeof (char)); | 1104 | if (GNUNET_YES == ok) |
1085 | 1105 | { | |
1086 | actual = dll_head; | 1106 | if ( (GNUNET_OK != |
1087 | while ( GNUNET_YES) | 1107 | GNUNET_BIO_write_string (wh, pos->hostlist_uri)) || |
1088 | { | 1108 | (GNUNET_OK != |
1089 | /* serialize content */ | 1109 | GNUNET_BIO_write_int32 (wh, pos->times_used)) || |
1090 | /* uri;hello_count;quality; */ | 1110 | (0) ) |
1091 | strcpy(content,actual->hostlist_uri); | 1111 | { |
1092 | strcat(content,";"); | 1112 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1093 | sprintf(buffer, "%lu", actual->hello_count); | 1113 | _("Error writing hostlist URIs to file `%s'\n"), |
1094 | strcat(content,buffer); | 1114 | filename); |
1095 | strcat(content,";"); | 1115 | ok = GNUNET_NO; |
1096 | sprintf(buffer, "%llu", (long long unsigned int) actual->quality); | 1116 | } |
1097 | strcat(content,buffer); | 1117 | } |
1098 | strcat(content,";"); | 1118 | GNUNET_free (pos); |
1099 | sprintf(buffer, "%llu", (long long unsigned int) actual->time_creation.value); | 1119 | } |
1100 | strcat(content,buffer); | ||
1101 | strcat(content,";"); | ||
1102 | sprintf(buffer, "%llu", (long long unsigned int) actual->time_last_usage.value); | ||
1103 | strcat(content,buffer); | ||
1104 | strcat(content,";"); | ||
1105 | sprintf(buffer, "%lu", actual->times_used); | ||
1106 | strcat(content,buffer); | ||
1107 | strcat(content,";"); | ||
1108 | |||
1109 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1110 | ("Content to write: %s\n"), | ||
1111 | content); | ||
1112 | |||
1113 | GNUNET_BIO_write_string ( wh, content ); | ||
1114 | |||
1115 | |||
1116 | if (actual == dll_tail) break; | ||
1117 | next = actual->next; | ||
1118 | GNUNET_free (actual->hostlist_uri); | ||
1119 | GNUNET_free (actual); | ||
1120 | actual = next; | ||
1121 | } | ||
1122 | GNUNET_free (actual->hostlist_uri); | ||
1123 | GNUNET_free (actual); | ||
1124 | GNUNET_free (content); | ||
1125 | |||
1126 | if ( GNUNET_OK != GNUNET_BIO_write_close ( wh ) ) | 1120 | if ( GNUNET_OK != GNUNET_BIO_write_close ( wh ) ) |
1127 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1121 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1128 | ("Error while closing file %s\n"), | 1122 | _("Error writing hostlist URIs to file `%s'\n"), |
1129 | filename); | 1123 | filename); |
1130 | return GNUNET_OK; | 1124 | GNUNET_free (filename); |
1131 | } | 1125 | } |
1132 | 1126 | ||
1133 | /** | 1127 | /** |
@@ -1164,9 +1158,10 @@ GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c, | |||
1164 | proxy = NULL; | 1158 | proxy = NULL; |
1165 | *ch = &connect_handler; | 1159 | *ch = &connect_handler; |
1166 | *dh = &disconnect_handler; | 1160 | *dh = &disconnect_handler; |
1167 | *msgh = &advertisement_handler; | 1161 | if (learn) |
1168 | 1162 | *msgh = &advertisement_handler; | |
1169 | learning = learn; | 1163 | else |
1164 | *msgh = NULL; | ||
1170 | dll_head = NULL; | 1165 | dll_head = NULL; |
1171 | dll_tail = NULL; | 1166 | dll_tail = NULL; |
1172 | load_hostlist_file (); | 1167 | load_hostlist_file (); |
diff --git a/src/hostlist/hostlist-client.h b/src/hostlist/hostlist-client.h index 37fc55c19..1393df8f1 100644 --- a/src/hostlist/hostlist-client.h +++ b/src/hostlist/hostlist-client.h | |||
@@ -42,48 +42,6 @@ | |||
42 | #define HOSTLIST_FAILED_DOWNLOAD 100 | 42 | #define HOSTLIST_FAILED_DOWNLOAD 100 |
43 | #define HOSTLIST_SUCCESSFUL_DOWNLOAD 100 | 43 | #define HOSTLIST_SUCCESSFUL_DOWNLOAD 100 |
44 | 44 | ||
45 | /* | ||
46 | * a single hostlist obtained by hostlist advertisements | ||
47 | */ | ||
48 | struct GNUNET_Hostlist | ||
49 | { | ||
50 | struct GNUNET_Hostlist * prev; | ||
51 | struct GNUNET_Hostlist * next; | ||
52 | /* | ||
53 | * peer offering the hostlist | ||
54 | */ | ||
55 | struct GNUNET_PeerIdentity peer; | ||
56 | /* | ||
57 | * URI where hostlist can be obtained | ||
58 | */ | ||
59 | char * hostlist_uri; | ||
60 | /* | ||
61 | * number of HELLO messages obtained during last download | ||
62 | */ | ||
63 | unsigned long hello_count; | ||
64 | /* | ||
65 | * number of times the hostlist was obtained | ||
66 | */ | ||
67 | unsigned long times_used; | ||
68 | /* | ||
69 | * time the hostlist advertisement was recieved and the entry was created | ||
70 | */ | ||
71 | struct GNUNET_TIME_Absolute time_creation; | ||
72 | /* | ||
73 | * last time the hostlist was obtained | ||
74 | */ | ||
75 | struct GNUNET_TIME_Absolute time_last_usage; | ||
76 | /* | ||
77 | * value describing the quality of the hostlist, the bigger the better but (should) never < 0 | ||
78 | * used for deciding which hostlist is replaced if MAX_NUMBER_HOSTLISTS in data structure is reached | ||
79 | * intial value = HOSTLIST_INITIAL | ||
80 | * increased every successful download by HOSTLIST_SUCCESSFULL_DOWNLOAD | ||
81 | * increased every successful download by number of obtained HELLO messages | ||
82 | * decreased every failed download by HOSTLIST_SUCCESSFULL_DOWNLOAD | ||
83 | */ | ||
84 | uint64_t quality; | ||
85 | }; | ||
86 | |||
87 | 45 | ||
88 | /** | 46 | /** |
89 | * Start downloading hostlists from hostlist servers as necessary. | 47 | * Start downloading hostlists from hostlist servers as necessary. |
diff --git a/src/hostlist/hostlist-server.c b/src/hostlist/hostlist-server.c index c04e99c42..e9a72d42b 100644 --- a/src/hostlist/hostlist-server.c +++ b/src/hostlist/hostlist-server.c | |||
@@ -109,15 +109,18 @@ struct HostSet | |||
109 | */ | 109 | */ |
110 | static int advertising; | 110 | static int advertising; |
111 | 111 | ||
112 | /* | 112 | /** |
113 | * How many times was the hostlist advertised? | 113 | * How many times was the hostlist advertised? |
114 | */ | 114 | */ |
115 | static uint64_t hostlist_adv_count = 0; | 115 | static uint64_t hostlist_adv_count; |
116 | 116 | ||
117 | /* | 117 | /* FIXME: define once... */ |
118 | #define MAX_URL_LEN 1000 | ||
119 | |||
120 | /** | ||
118 | * Buffer for the hostlist address | 121 | * Buffer for the hostlist address |
119 | */ | 122 | */ |
120 | char hostlist_uri[255]; | 123 | static char * hostlist_uri; |
121 | 124 | ||
122 | 125 | ||
123 | /** | 126 | /** |
@@ -373,6 +376,7 @@ access_handler_callback (void *cls, | |||
373 | return MHD_queue_response (connection, MHD_HTTP_OK, response); | 376 | return MHD_queue_response (connection, MHD_HTTP_OK, response); |
374 | } | 377 | } |
375 | 378 | ||
379 | |||
376 | /** | 380 | /** |
377 | * Handler called by core when core is ready to transmit message | 381 | * Handler called by core when core is ready to transmit message |
378 | * @param cls closure | 382 | * @param cls closure |
@@ -384,139 +388,35 @@ adv_transmit_ready ( void *cls, size_t size, void *buf) | |||
384 | { | 388 | { |
385 | size_t transmission_size; | 389 | size_t transmission_size; |
386 | size_t uri_size; /* Including \0 termination! */ | 390 | size_t uri_size; /* Including \0 termination! */ |
387 | uri_size = strlen ( hostlist_uri ) + 1; | 391 | struct GNUNET_MessageHeader header; |
388 | 392 | char *cbuf; | |
389 | struct GNUNET_HOSTLIST_ADV_Message * adv_message; | ||
390 | adv_message = GNUNET_malloc ( sizeof(struct GNUNET_HOSTLIST_ADV_Message) + uri_size); | ||
391 | if ( NULL == adv_message) | ||
392 | { | ||
393 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, | ||
394 | "Could not allocate memory for the message"); | ||
395 | return GNUNET_NO; | ||
396 | } | ||
397 | transmission_size = sizeof (struct GNUNET_HOSTLIST_ADV_Message) + uri_size; | ||
398 | |||
399 | adv_message->header.type = htons (GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT); | ||
400 | adv_message->header.size = htons (transmission_size); | ||
401 | memcpy(&adv_message[1],hostlist_uri,uri_size); | ||
402 | 393 | ||
403 | if (buf == NULL) | 394 | if (buf == NULL) |
404 | { | 395 | { |
405 | GNUNET_log ( GNUNET_ERROR_TYPE_DEBUG, "Transmission failed, buffer invalid!\n" ); | 396 | GNUNET_log ( GNUNET_ERROR_TYPE_DEBUG, |
397 | "Transmission failed, buffer invalid!\n" ); | ||
406 | return 0; | 398 | return 0; |
407 | } | 399 | } |
408 | 400 | uri_size = strlen ( hostlist_uri ) + 1; | |
409 | if ( size >= transmission_size ) | 401 | transmission_size = sizeof (struct GNUNET_MessageHeader) + uri_size; |
410 | { | 402 | header.type = htons (GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT); |
411 | memcpy ( buf, adv_message, transmission_size ); | 403 | header.size = htons (transmission_size); |
412 | GNUNET_log ( GNUNET_ERROR_TYPE_DEBUG, "Sent advertisement message: Copied %d bytes into buffer!\n", transmission_size); | 404 | GNUNET_assert (size >= transmission_size); |
413 | GNUNET_free ( adv_message ); | 405 | memcpy (buf, &header, sizeof (struct GNUNET_MessageHeader)); |
414 | return transmission_size; | 406 | cbuf = buf; |
415 | } | 407 | memcpy (&cbuf[sizeof (struct GNUNET_MessageHeader)], |
416 | 408 | hostlist_uri, uri_size); | |
409 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
410 | "Sent advertisement message: Copied %u bytes into buffer!\n", | ||
411 | (unsigned int) transmission_size); | ||
417 | hostlist_adv_count++; | 412 | hostlist_adv_count++; |
418 | GNUNET_STATISTICS_set (stats, | 413 | GNUNET_STATISTICS_set (stats, |
419 | gettext_noop("# hostlist advertisements send"), | 414 | gettext_noop("# hostlist advertisements send"), |
420 | hostlist_adv_count, | 415 | hostlist_adv_count, |
421 | GNUNET_YES); | 416 | GNUNET_YES); |
422 | 417 | return transmission_size; | |
423 | GNUNET_free (adv_message ); | ||
424 | return size; | ||
425 | } | 418 | } |
426 | 419 | ||
427 | /** | ||
428 | * Method that asks core service to transmit the message to the peer | ||
429 | * @param peer peer to transmit message to | ||
430 | * @param size size of the message | ||
431 | */ | ||
432 | static size_t | ||
433 | adv_transmit_message ( const struct GNUNET_PeerIdentity * peer, size_t size ) | ||
434 | { | ||
435 | /* transmit message to peer */ | ||
436 | if ( NULL == core) | ||
437 | { | ||
438 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
439 | _("Not connected to core, unable to send advertisement message\n")); | ||
440 | return GNUNET_NO; | ||
441 | } | ||
442 | |||
443 | struct GNUNET_TIME_Relative timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, GNUNET_ADV_TIMEOUT); | ||
444 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
445 | _("Asked core to transmit advertisement message with a size of %u bytes\n"), size); | ||
446 | struct GNUNET_CORE_TransmitHandle * th; | ||
447 | th = GNUNET_CORE_notify_transmit_ready (core, | ||
448 | 0, | ||
449 | timeout, | ||
450 | peer, | ||
451 | size, | ||
452 | &adv_transmit_ready, NULL); | ||
453 | if ( NULL == th ) | ||
454 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
455 | _("Advertisement message could not be queued by core\n")); | ||
456 | return GNUNET_NO; | ||
457 | |||
458 | return GNUNET_YES; | ||
459 | } | ||
460 | |||
461 | /** | ||
462 | * Method that assembles our hostlist advertisement message | ||
463 | * @param peer peer to send the hostlist advertisement | ||
464 | */ | ||
465 | static size_t | ||
466 | adv_create_message ( const struct GNUNET_PeerIdentity * peer ) | ||
467 | |||
468 | { | ||
469 | size_t length = 0; | ||
470 | size_t size = 0; | ||
471 | unsigned long long port; | ||
472 | |||
473 | char *uri; | ||
474 | char hostname[GNUNET_OS_get_hostname_max_length() + 1]; | ||
475 | char *protocol = "http://"; | ||
476 | char *port_s = GNUNET_malloc(6 * sizeof(char)); | ||
477 | |||
478 | if (0 != gethostname (hostname, sizeof (hostname) - 1)) | ||
479 | { | ||
480 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, | ||
481 | "Could not get system's hostname, unable to create advertisement message"); | ||
482 | return GNUNET_NO; | ||
483 | } | ||
484 | if (-1 == GNUNET_CONFIGURATION_get_value_number (cfg, | ||
485 | "HOSTLIST", | ||
486 | "HTTPPORT", | ||
487 | &port)) | ||
488 | return GNUNET_SYSERR; | ||
489 | |||
490 | sprintf(port_s, "%llu", port); | ||
491 | length = strlen(hostname)+strlen(protocol)+strlen(port_s)+2; | ||
492 | size = (length+1) * sizeof (char); | ||
493 | uri = GNUNET_malloc(size); | ||
494 | uri = strcpy(uri, protocol); | ||
495 | uri = strcat(uri, hostname); | ||
496 | uri = strcat(uri, ":"); | ||
497 | uri = strcat(uri, port_s); | ||
498 | uri = strcat(uri, "/"); | ||
499 | if ( length < 255); | ||
500 | strcpy(hostlist_uri,uri); | ||
501 | |||
502 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Address to obtain hostlist: %s\n", hostlist_uri); | ||
503 | |||
504 | if ( ( size + sizeof( struct GNUNET_HOSTLIST_ADV_Message )) > GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
505 | { | ||
506 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, | ||
507 | "Advertisement message is bigger than GNUNET allows"); | ||
508 | return GNUNET_NO; | ||
509 | } | ||
510 | |||
511 | /* Request core to transmit message to peer */ | ||
512 | size = size + sizeof ( struct GNUNET_HOSTLIST_ADV_Message ); | ||
513 | adv_transmit_message(peer, size); | ||
514 | |||
515 | GNUNET_free ( port_s ); | ||
516 | GNUNET_free ( uri ); | ||
517 | |||
518 | return GNUNET_OK; | ||
519 | } | ||
520 | 420 | ||
521 | /** | 421 | /** |
522 | * Method called whenever a given peer connects. | 422 | * Method called whenever a given peer connects. |
@@ -533,18 +433,37 @@ connect_handler (void *cls, | |||
533 | struct GNUNET_TIME_Relative latency, | 433 | struct GNUNET_TIME_Relative latency, |
534 | uint32_t distance) | 434 | uint32_t distance) |
535 | { | 435 | { |
436 | size_t size; | ||
437 | |||
536 | if ( !advertising ) | 438 | if ( !advertising ) |
537 | return; | 439 | return; |
538 | 440 | if (hostlist_uri == NULL) | |
539 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
540 | "A new peer connected to the server, preparing to send hostlist advertisement\n"); | ||
541 | /* create a new advertisement message */ | ||
542 | if ( (GNUNET_OK != adv_create_message(peer))) | ||
543 | { | ||
544 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
545 | _(" GNUNET_OK Could not create a hostlist advertisement message, impossible to advertise hostlist\n")); | ||
546 | return; | 441 | return; |
547 | } | 442 | size = strlen (hostlist_uri) + 1; |
443 | if (size + sizeof (struct GNUNET_MessageHeader) > GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
444 | { | ||
445 | GNUNET_break (0); | ||
446 | return; | ||
447 | } | ||
448 | size += sizeof (struct GNUNET_MessageHeader); | ||
449 | if (NULL == core) | ||
450 | { | ||
451 | GNUNET_break (0); | ||
452 | return; | ||
453 | } | ||
454 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
455 | "Asked core to transmit advertisement message with a size of %u bytes\n", | ||
456 | size); | ||
457 | if (NULL == GNUNET_CORE_notify_transmit_ready (core, | ||
458 | 0, | ||
459 | GNUNET_ADV_TIMEOUT, | ||
460 | peer, | ||
461 | size, | ||
462 | &adv_transmit_ready, NULL)) | ||
463 | { | ||
464 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
465 | _("Advertisement message could not be queued by core\n")); | ||
466 | } | ||
548 | } | 467 | } |
549 | 468 | ||
550 | 469 | ||
@@ -559,7 +478,7 @@ disconnect_handler (void *cls, | |||
559 | const struct | 478 | const struct |
560 | GNUNET_PeerIdentity * peer) | 479 | GNUNET_PeerIdentity * peer) |
561 | { | 480 | { |
562 | 481 | /* nothing to do */ | |
563 | } | 482 | } |
564 | 483 | ||
565 | 484 | ||
@@ -570,6 +489,7 @@ disconnect_handler (void *cls, | |||
570 | static GNUNET_SCHEDULER_TaskIdentifier | 489 | static GNUNET_SCHEDULER_TaskIdentifier |
571 | prepare_daemon (struct MHD_Daemon *daemon_handle); | 490 | prepare_daemon (struct MHD_Daemon *daemon_handle); |
572 | 491 | ||
492 | |||
573 | /** | 493 | /** |
574 | * Call MHD to process pending requests and then go back | 494 | * Call MHD to process pending requests and then go back |
575 | * and schedule the next run. | 495 | * and schedule the next run. |
@@ -666,6 +586,8 @@ GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c, | |||
666 | int advertise) | 586 | int advertise) |
667 | { | 587 | { |
668 | unsigned long long port; | 588 | unsigned long long port; |
589 | char *hostname; | ||
590 | size_t size; | ||
669 | 591 | ||
670 | advertising = advertise; | 592 | advertising = advertise; |
671 | if ( !advertising ) | 593 | if ( !advertising ) |
@@ -685,6 +607,26 @@ GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c, | |||
685 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 607 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
686 | _("Hostlist service starts on port %llu\n"), | 608 | _("Hostlist service starts on port %llu\n"), |
687 | port); | 609 | port); |
610 | hostname = GNUNET_RESOLVER_local_hostname_get (); | ||
611 | if (NULL != hostname) | ||
612 | { | ||
613 | size = strlen (hostname); | ||
614 | if (size + 15 > MAX_URL_LEN) | ||
615 | { | ||
616 | GNUNET_break (0); | ||
617 | } | ||
618 | else | ||
619 | { | ||
620 | GNUNET_asprintf (&hostlist_uri, | ||
621 | "http://%s:%u/", | ||
622 | hostname, | ||
623 | (unsigned int) port); | ||
624 | GNUNET_free (hostname); | ||
625 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
626 | _("Address to obtain hostlist: `%s'\n"), | ||
627 | hostlist_uri); | ||
628 | } | ||
629 | } | ||
688 | daemon_handle_v6 = MHD_start_daemon (MHD_USE_IPv6 | 630 | daemon_handle_v6 = MHD_start_daemon (MHD_USE_IPv6 |
689 | #if DEBUG_HOSTLIST_SERVER | 631 | #if DEBUG_HOSTLIST_SERVER |
690 | | MHD_USE_DEBUG | 632 | | MHD_USE_DEBUG |
@@ -725,7 +667,7 @@ GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c, | |||
725 | return GNUNET_SYSERR; | 667 | return GNUNET_SYSERR; |
726 | } | 668 | } |
727 | 669 | ||
728 | core=co; | 670 | core = co; |
729 | 671 | ||
730 | *server_ch = &connect_handler; | 672 | *server_ch = &connect_handler; |
731 | *server_dh = &disconnect_handler; | 673 | *server_dh = &disconnect_handler; |
diff --git a/src/hostlist/hostlist-server.h b/src/hostlist/hostlist-server.h index cffcac05f..f704f890d 100644 --- a/src/hostlist/hostlist-server.h +++ b/src/hostlist/hostlist-server.h | |||
@@ -31,7 +31,7 @@ | |||
31 | #include "gnunet_statistics_service.h" | 31 | #include "gnunet_statistics_service.h" |
32 | #include "gnunet_util_lib.h" | 32 | #include "gnunet_util_lib.h" |
33 | 33 | ||
34 | #define GNUNET_ADV_TIMEOUT 2500 | 34 | #define GNUNET_ADV_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5) |
35 | 35 | ||
36 | /** | 36 | /** |
37 | * Start server offering our hostlist. | 37 | * Start server offering our hostlist. |