aboutsummaryrefslogtreecommitdiff
path: root/src/experimentation/gnunet-daemon-experimentation.c
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2013-05-22 12:19:53 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2013-05-22 12:19:53 +0000
commit93287c8fecfc7fce37f0d9dfb1dc5b1bd7a9f7b3 (patch)
tree725fc53c61d77998631295a951006d9987d1df73 /src/experimentation/gnunet-daemon-experimentation.c
parent4289fca5aeefd0652ae60bc16f90ed911c7e1c60 (diff)
downloadgnunet-93287c8fecfc7fce37f0d9dfb1dc5b1bd7a9f7b3.tar.gz
gnunet-93287c8fecfc7fce37f0d9dfb1dc5b1bd7a9f7b3.zip
changes
Diffstat (limited to 'src/experimentation/gnunet-daemon-experimentation.c')
-rw-r--r--src/experimentation/gnunet-daemon-experimentation.c146
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
35static struct GNUNET_CORE_Handle *ch; 35static struct GNUNET_CORE_Handle *ch;
36 36
37static struct GNUNET_PeerIdentity me; 37static struct GNUNET_PeerIdentity me;
38 38
39static 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
54struct Experimentation_Request
55{
56 struct GNUNET_MessageHeader msg;
47}; 57};
48 58
49/** 59/**
@@ -64,6 +74,31 @@ struct GNUNET_CONTAINER_MultiHashMap *nodes_active;
64struct GNUNET_CONTAINER_MultiHashMap *nodes_inactive; 74struct GNUNET_CONTAINER_MultiHashMap *nodes_inactive;
65 75
66 76
77static 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
67static int 102static int
68cleanup_nodes (void *cls, 103cleanup_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
131static int is_me (const struct GNUNET_PeerIdentity *id) 181static 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
224size_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
251static 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 */
170void core_connect_handler (void *cls, 276void 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