diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2013-05-22 12:19:53 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2013-05-22 12:19:53 +0000 |
commit | 93287c8fecfc7fce37f0d9dfb1dc5b1bd7a9f7b3 (patch) | |
tree | 725fc53c61d77998631295a951006d9987d1df73 /src/experimentation/gnunet-daemon-experimentation.c | |
parent | 4289fca5aeefd0652ae60bc16f90ed911c7e1c60 (diff) | |
download | gnunet-93287c8fecfc7fce37f0d9dfb1dc5b1bd7a9f7b3.tar.gz gnunet-93287c8fecfc7fce37f0d9dfb1dc5b1bd7a9f7b3.zip |
changes
Diffstat (limited to 'src/experimentation/gnunet-daemon-experimentation.c')
-rw-r--r-- | src/experimentation/gnunet-daemon-experimentation.c | 146 |
1 files changed, 123 insertions, 23 deletions
diff --git a/src/experimentation/gnunet-daemon-experimentation.c b/src/experimentation/gnunet-daemon-experimentation.c index 8a6fba4b2..0f39b926f 100644 --- a/src/experimentation/gnunet-daemon-experimentation.c +++ b/src/experimentation/gnunet-daemon-experimentation.c | |||
@@ -26,16 +26,18 @@ | |||
26 | */ | 26 | */ |
27 | #include "platform.h" | 27 | #include "platform.h" |
28 | #include "gnunet_getopt_lib.h" | 28 | #include "gnunet_getopt_lib.h" |
29 | #include "gnunet_container_lib.h" | 29 | #include "gnunet_util_lib.h" |
30 | #include "gnunet_program_lib.h" | ||
31 | #include "gnunet_core_service.h" | 30 | #include "gnunet_core_service.h" |
31 | #include "gnunet_statistics_service.h" | ||
32 | 32 | ||
33 | #define EXP_RESPONSE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) | 33 | #define EXP_RESPONSE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 2) |
34 | 34 | ||
35 | static struct GNUNET_CORE_Handle *ch; | 35 | static struct GNUNET_CORE_Handle *ch; |
36 | 36 | ||
37 | static struct GNUNET_PeerIdentity me; | 37 | static struct GNUNET_PeerIdentity me; |
38 | 38 | ||
39 | static struct GNUNET_STATISTICS_Handle *stats; | ||
40 | |||
39 | /** | 41 | /** |
40 | * A experimentation node | 42 | * A experimentation node |
41 | */ | 43 | */ |
@@ -44,6 +46,14 @@ struct Node | |||
44 | struct GNUNET_PeerIdentity id; | 46 | struct GNUNET_PeerIdentity id; |
45 | 47 | ||
46 | GNUNET_SCHEDULER_TaskIdentifier timeout_task; | 48 | GNUNET_SCHEDULER_TaskIdentifier timeout_task; |
49 | |||
50 | struct GNUNET_CORE_TransmitHandle *cth; | ||
51 | }; | ||
52 | |||
53 | |||
54 | struct Experimentation_Request | ||
55 | { | ||
56 | struct GNUNET_MessageHeader msg; | ||
47 | }; | 57 | }; |
48 | 58 | ||
49 | /** | 59 | /** |
@@ -64,6 +74,31 @@ struct GNUNET_CONTAINER_MultiHashMap *nodes_active; | |||
64 | struct GNUNET_CONTAINER_MultiHashMap *nodes_inactive; | 74 | struct GNUNET_CONTAINER_MultiHashMap *nodes_inactive; |
65 | 75 | ||
66 | 76 | ||
77 | static void update_stats (struct GNUNET_CONTAINER_MultiHashMap *m) | ||
78 | { | ||
79 | GNUNET_assert (NULL != m); | ||
80 | GNUNET_assert (NULL != stats); | ||
81 | |||
82 | if (m == nodes_active) | ||
83 | { | ||
84 | GNUNET_STATISTICS_set (stats, "# nodes active", | ||
85 | GNUNET_CONTAINER_multihashmap_size(m), GNUNET_NO); | ||
86 | } | ||
87 | else if (m == nodes_inactive) | ||
88 | { | ||
89 | GNUNET_STATISTICS_set (stats, "# nodes inactive", | ||
90 | GNUNET_CONTAINER_multihashmap_size(m), GNUNET_NO); | ||
91 | } | ||
92 | else if (m == nodes_requested) | ||
93 | { | ||
94 | GNUNET_STATISTICS_set (stats, "# nodes requested", | ||
95 | GNUNET_CONTAINER_multihashmap_size(m), GNUNET_NO); | ||
96 | } | ||
97 | else | ||
98 | GNUNET_break (0); | ||
99 | |||
100 | } | ||
101 | |||
67 | static int | 102 | static int |
68 | cleanup_nodes (void *cls, | 103 | cleanup_nodes (void *cls, |
69 | const struct GNUNET_HashCode * key, | 104 | const struct GNUNET_HashCode * key, |
@@ -78,6 +113,12 @@ cleanup_nodes (void *cls, | |||
78 | GNUNET_SCHEDULER_cancel (n->timeout_task); | 113 | GNUNET_SCHEDULER_cancel (n->timeout_task); |
79 | n->timeout_task = GNUNET_SCHEDULER_NO_TASK; | 114 | n->timeout_task = GNUNET_SCHEDULER_NO_TASK; |
80 | } | 115 | } |
116 | if (NULL != n->cth) | ||
117 | { | ||
118 | GNUNET_CORE_notify_transmit_ready_cancel (n->cth); | ||
119 | n->cth = NULL; | ||
120 | } | ||
121 | |||
81 | 122 | ||
82 | GNUNET_CONTAINER_multihashmap_remove (cur, key, value); | 123 | GNUNET_CONTAINER_multihashmap_remove (cur, key, value); |
83 | GNUNET_free (value); | 124 | GNUNET_free (value); |
@@ -105,6 +146,7 @@ cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
105 | GNUNET_CONTAINER_multihashmap_iterate (nodes_requested, | 146 | GNUNET_CONTAINER_multihashmap_iterate (nodes_requested, |
106 | &cleanup_nodes, | 147 | &cleanup_nodes, |
107 | nodes_requested); | 148 | nodes_requested); |
149 | update_stats (nodes_requested); | ||
108 | GNUNET_CONTAINER_multihashmap_destroy (nodes_requested); | 150 | GNUNET_CONTAINER_multihashmap_destroy (nodes_requested); |
109 | nodes_requested = NULL; | 151 | nodes_requested = NULL; |
110 | } | 152 | } |
@@ -114,6 +156,7 @@ cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
114 | GNUNET_CONTAINER_multihashmap_iterate (nodes_active, | 156 | GNUNET_CONTAINER_multihashmap_iterate (nodes_active, |
115 | &cleanup_nodes, | 157 | &cleanup_nodes, |
116 | nodes_active); | 158 | nodes_active); |
159 | update_stats (nodes_active); | ||
117 | GNUNET_CONTAINER_multihashmap_destroy (nodes_active); | 160 | GNUNET_CONTAINER_multihashmap_destroy (nodes_active); |
118 | nodes_active = NULL; | 161 | nodes_active = NULL; |
119 | } | 162 | } |
@@ -123,9 +166,16 @@ cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
123 | GNUNET_CONTAINER_multihashmap_iterate (nodes_inactive, | 166 | GNUNET_CONTAINER_multihashmap_iterate (nodes_inactive, |
124 | &cleanup_nodes, | 167 | &cleanup_nodes, |
125 | nodes_inactive); | 168 | nodes_inactive); |
169 | update_stats (nodes_inactive); | ||
126 | GNUNET_CONTAINER_multihashmap_destroy (nodes_inactive); | 170 | GNUNET_CONTAINER_multihashmap_destroy (nodes_inactive); |
127 | nodes_inactive = NULL; | 171 | nodes_inactive = NULL; |
128 | } | 172 | } |
173 | |||
174 | if (NULL != stats) | ||
175 | { | ||
176 | GNUNET_STATISTICS_destroy (stats, GNUNET_NO); | ||
177 | stats = NULL; | ||
178 | } | ||
129 | } | 179 | } |
130 | 180 | ||
131 | static int is_me (const struct GNUNET_PeerIdentity *id) | 181 | static int is_me (const struct GNUNET_PeerIdentity *id) |
@@ -149,18 +199,74 @@ remove_request (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
149 | { | 199 | { |
150 | struct Node *n = cls; | 200 | struct Node *n = cls; |
151 | 201 | ||
202 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Removing request for peer %s due to timeout\n"), | ||
203 | GNUNET_i2s (&n->id)); | ||
204 | |||
152 | if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (nodes_requested, &n->id.hashPubKey)) | 205 | if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (nodes_requested, &n->id.hashPubKey)) |
153 | GNUNET_break (0); | 206 | GNUNET_break (0); |
154 | else | 207 | else |
155 | { | 208 | { |
156 | GNUNET_CONTAINER_multihashmap_remove (nodes_requested, &n->id.hashPubKey, n); | 209 | GNUNET_CONTAINER_multihashmap_remove (nodes_requested, &n->id.hashPubKey, n); |
210 | update_stats (nodes_requested); | ||
157 | GNUNET_CONTAINER_multihashmap_put (nodes_inactive, &n->id.hashPubKey, n, | 211 | GNUNET_CONTAINER_multihashmap_put (nodes_inactive, &n->id.hashPubKey, n, |
158 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | 212 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); |
213 | update_stats (nodes_inactive); | ||
159 | n->timeout_task = GNUNET_SCHEDULER_NO_TASK; | 214 | n->timeout_task = GNUNET_SCHEDULER_NO_TASK; |
215 | if (NULL != n->cth) | ||
216 | { | ||
217 | GNUNET_CORE_notify_transmit_ready_cancel (n->cth); | ||
218 | n->cth = NULL; | ||
219 | } | ||
160 | } | 220 | } |
161 | } | 221 | } |
162 | 222 | ||
163 | 223 | ||
224 | size_t send_request_cb (void *cls, size_t bufsize, void *buf) | ||
225 | { | ||
226 | struct Node *n = cls; | ||
227 | struct Experimentation_Request msg; | ||
228 | size_t size = sizeof (msg); | ||
229 | |||
230 | n->cth = NULL; | ||
231 | if (buf == NULL) | ||
232 | { | ||
233 | /* client disconnected */ | ||
234 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client disconnected\n"); | ||
235 | if (GNUNET_SCHEDULER_NO_TASK != n->timeout_task) | ||
236 | GNUNET_SCHEDULER_cancel (n->timeout_task); | ||
237 | GNUNET_SCHEDULER_add_now (&remove_request, n); | ||
238 | return 0; | ||
239 | } | ||
240 | GNUNET_assert (bufsize >= size); | ||
241 | |||
242 | msg.msg.size = htons (size); | ||
243 | msg.msg.type = htons (GNUNET_MESSAGE_TYPE_EXPERIMENTATION_REQUEST); | ||
244 | memcpy (buf, &msg, size); | ||
245 | |||
246 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Sending request to peer %s\n"), | ||
247 | GNUNET_i2s (&n->id)); | ||
248 | return size; | ||
249 | } | ||
250 | |||
251 | static void send_request (const struct GNUNET_PeerIdentity *peer) | ||
252 | { | ||
253 | struct Node *n; | ||
254 | size_t size; | ||
255 | |||
256 | size = sizeof (struct Experimentation_Request); | ||
257 | n = GNUNET_malloc (sizeof (struct Node)); | ||
258 | n->id = *peer; | ||
259 | n->timeout_task = GNUNET_SCHEDULER_add_delayed (EXP_RESPONSE_TIMEOUT, &remove_request, n); | ||
260 | n->cth = GNUNET_CORE_notify_transmit_ready(ch, GNUNET_NO, 0, | ||
261 | GNUNET_TIME_relative_get_forever_(), | ||
262 | peer, size, send_request_cb, n); | ||
263 | |||
264 | GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (nodes_requested, | ||
265 | &peer->hashPubKey, n, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)); | ||
266 | |||
267 | update_stats (nodes_requested); | ||
268 | } | ||
269 | |||
164 | /** | 270 | /** |
165 | * Method called whenever a given peer connects. | 271 | * Method called whenever a given peer connects. |
166 | * | 272 | * |
@@ -168,10 +274,8 @@ remove_request (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
168 | * @param peer peer identity this notification is about | 274 | * @param peer peer identity this notification is about |
169 | */ | 275 | */ |
170 | void core_connect_handler (void *cls, | 276 | void core_connect_handler (void *cls, |
171 | const struct GNUNET_PeerIdentity * peer) | 277 | const struct GNUNET_PeerIdentity *peer) |
172 | { | 278 | { |
173 | struct Node *n; | ||
174 | |||
175 | if (GNUNET_YES == is_me(peer)) | 279 | if (GNUNET_YES == is_me(peer)) |
176 | return; | 280 | return; |
177 | 281 | ||
@@ -182,23 +286,12 @@ void core_connect_handler (void *cls, | |||
182 | return; /* We already sent a request */ | 286 | return; /* We already sent a request */ |
183 | 287 | ||
184 | if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (nodes_active, &peer->hashPubKey)) | 288 | if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (nodes_active, &peer->hashPubKey)) |
185 | return; /*This peer is known as active */ | 289 | return; /* This peer is known as active */ |
186 | 290 | ||
187 | if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (nodes_inactive, &peer->hashPubKey)) | 291 | if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (nodes_inactive, &peer->hashPubKey)) |
188 | return; /*This peer is known as inactive */ | 292 | return; /* This peer is known as inactive */ |
189 | |||
190 | /* Send request */ | ||
191 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Sending request to peer %s\n"), | ||
192 | GNUNET_i2s (peer)); | ||
193 | |||
194 | n = GNUNET_malloc (sizeof (struct Node)); | ||
195 | n->id = *peer; | ||
196 | n->timeout_task = GNUNET_SCHEDULER_add_delayed (EXP_RESPONSE_TIMEOUT, &remove_request, n); | ||
197 | |||
198 | GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (nodes_requested, | ||
199 | &peer->hashPubKey, n, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)); | ||
200 | |||
201 | 293 | ||
294 | send_request (peer); | ||
202 | 295 | ||
203 | } | 296 | } |
204 | 297 | ||
@@ -232,9 +325,12 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
232 | { | 325 | { |
233 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Experimentation daemon starting ...\n")); | 326 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Experimentation daemon starting ...\n")); |
234 | 327 | ||
235 | nodes_requested = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO); | 328 | stats = GNUNET_STATISTICS_create ("experimentation", cfg); |
236 | nodes_active = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO); | 329 | if (NULL == stats) |
237 | nodes_inactive = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO); | 330 | { |
331 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Failed to create statistics!\n")); | ||
332 | return; | ||
333 | } | ||
238 | 334 | ||
239 | /* Connecting to core service to find partners */ | 335 | /* Connecting to core service to find partners */ |
240 | ch = GNUNET_CORE_connect (cfg, NULL, | 336 | ch = GNUNET_CORE_connect (cfg, NULL, |
@@ -248,6 +344,10 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
248 | return; | 344 | return; |
249 | } | 345 | } |
250 | 346 | ||
347 | nodes_requested = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO); | ||
348 | nodes_active = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO); | ||
349 | nodes_inactive = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO); | ||
350 | |||
251 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup_task, | 351 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup_task, |
252 | NULL); | 352 | NULL); |
253 | 353 | ||