diff options
author | Christian Grothoff <christian@grothoff.org> | 2015-02-10 23:24:01 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2015-02-10 23:24:01 +0000 |
commit | 1c323bd4cbb388a9e7515a1f733a3062bf093aee (patch) | |
tree | 7cc525d79149d44840b9f7a0040aaf3e69ecd665 /src/transport/gnunet-service-transport_manipulation.c | |
parent | aedaaed687db1ff20b447378f01ad7306921450c (diff) | |
download | gnunet-1c323bd4cbb388a9e7515a1f733a3062bf093aee.tar.gz gnunet-1c323bd4cbb388a9e7515a1f733a3062bf093aee.zip |
fixing #3657 (replace ATS_Information with struct), but WIHTOUT fixing ATS testcases yet
Diffstat (limited to 'src/transport/gnunet-service-transport_manipulation.c')
-rw-r--r-- | src/transport/gnunet-service-transport_manipulation.c | 667 |
1 files changed, 230 insertions, 437 deletions
diff --git a/src/transport/gnunet-service-transport_manipulation.c b/src/transport/gnunet-service-transport_manipulation.c index f52634edc..b58ade999 100644 --- a/src/transport/gnunet-service-transport_manipulation.c +++ b/src/transport/gnunet-service-transport_manipulation.c | |||
@@ -34,66 +34,36 @@ | |||
34 | #include "gnunet-service-transport.h" | 34 | #include "gnunet-service-transport.h" |
35 | #include "transport.h" | 35 | #include "transport.h" |
36 | 36 | ||
37 | enum TRAFFIC_METRIC_DIRECTION | ||
38 | { | ||
39 | TM_SEND = 0, TM_RECEIVE = 1, TM_BOTH = 2 | ||
40 | }; | ||
41 | |||
42 | 37 | ||
43 | /** | 38 | /** |
44 | * Struct containing information about manipulations to a specific peer | 39 | * Struct containing information about manipulations to a specific peer |
45 | */ | 40 | */ |
46 | struct TM_Peer; | 41 | struct TM_Peer |
47 | |||
48 | /** | ||
49 | * Manipulation entry | ||
50 | */ | ||
51 | struct PropManipulationEntry | ||
52 | { | 42 | { |
53 | /** | 43 | /** |
54 | * Next in DLL | 44 | * Peer ID |
55 | */ | ||
56 | struct PropManipulationEntry *next; | ||
57 | |||
58 | /** | ||
59 | * Previous in DLL | ||
60 | */ | ||
61 | struct PropManipulationEntry *prev; | ||
62 | |||
63 | /** | ||
64 | * ATS type in HBO | ||
65 | */ | 45 | */ |
66 | uint32_t type; | 46 | struct GNUNET_PeerIdentity peer; |
67 | 47 | ||
68 | /** | 48 | /** |
69 | * Value in HBO | 49 | * How long to delay incoming messages for this peer. |
70 | */ | 50 | */ |
71 | uint32_t metrics[TM_BOTH]; | 51 | struct GNUNET_TIME_Relative delay_in; |
72 | 52 | ||
73 | }; | ||
74 | |||
75 | /** | ||
76 | * Struct containing information about manipulations to a specific peer | ||
77 | */ | ||
78 | struct TM_Peer | ||
79 | { | ||
80 | /** | 53 | /** |
81 | * Peer ID | 54 | * How long to delay outgoing messages for this peer. |
82 | */ | 55 | */ |
83 | struct GNUNET_PeerIdentity peer; | 56 | struct GNUNET_TIME_Relative delay_out; |
84 | |||
85 | struct PropManipulationEntry *head; | ||
86 | struct PropManipulationEntry *tail; | ||
87 | 57 | ||
88 | /** | 58 | /** |
89 | * Peer specific manipulation metrics | 59 | * Manipulated properties to use for this peer. |
90 | */ | 60 | */ |
91 | uint32_t metrics[TM_BOTH][GNUNET_ATS_QualityPropertiesCount]; | 61 | struct GNUNET_ATS_Properties properties; |
92 | 62 | ||
93 | /** | 63 | /** |
94 | * Task to schedule delayed sendding | 64 | * Task to schedule delayed sendding |
95 | */ | 65 | */ |
96 | struct GNUNET_SCHEDULER_Task * send_delay_task; | 66 | struct GNUNET_SCHEDULER_Task *send_delay_task; |
97 | 67 | ||
98 | /** | 68 | /** |
99 | * Send queue DLL head | 69 | * Send queue DLL head |
@@ -107,19 +77,6 @@ struct TM_Peer | |||
107 | }; | 77 | }; |
108 | 78 | ||
109 | 79 | ||
110 | struct GST_ManipulationHandle | ||
111 | { | ||
112 | /** | ||
113 | * Hashmap contain all peers currently manipulated | ||
114 | */ | ||
115 | struct GNUNET_CONTAINER_MultiPeerMap *peers; | ||
116 | |||
117 | /** | ||
118 | * Peer containing information for general manipulation | ||
119 | */ | ||
120 | struct TM_Peer general; | ||
121 | }; | ||
122 | |||
123 | /** | 80 | /** |
124 | * Entry in the delay queue for an outbound delayed message | 81 | * Entry in the delay queue for an outbound delayed message |
125 | */ | 82 | */ |
@@ -136,9 +93,10 @@ struct DelayQueueEntry | |||
136 | struct DelayQueueEntry *next; | 93 | struct DelayQueueEntry *next; |
137 | 94 | ||
138 | /** | 95 | /** |
139 | * Peer this entry is belonging to | 96 | * Peer this entry is belonging to if (NULL == tmp): enqueued in |
140 | * if (NULL == tmp): enqueued in generic DLL and scheduled by generic_send_delay_task | 97 | * generic DLL and scheduled by generic_send_delay_task else: |
141 | * else: enqueued in tmp->send_head and tmp->send_tail and scheduled by tmp->send_delay_task | 98 | * enqueued in tmp->send_head and tmp->send_tail and scheduled by |
99 | * tmp->send_delay_task | ||
142 | */ | 100 | */ |
143 | struct TM_Peer *tmp; | 101 | struct TM_Peer *tmp; |
144 | 102 | ||
@@ -178,91 +136,35 @@ struct DelayQueueEntry | |||
178 | void *cont_cls; | 136 | void *cont_cls; |
179 | }; | 137 | }; |
180 | 138 | ||
181 | struct GST_ManipulationHandle man_handle; | ||
182 | |||
183 | /** | 139 | /** |
184 | * DLL head for delayed messages based on general delay | 140 | * Hashmap contain all peers currently manipulated |
185 | */ | 141 | */ |
186 | struct DelayQueueEntry *generic_dqe_head; | 142 | static struct GNUNET_CONTAINER_MultiPeerMap *peers; |
187 | 143 | ||
188 | /** | 144 | /** |
189 | * DLL tail for delayed messages based on general delay | 145 | * Inbound delay to apply to all peers. |
190 | */ | 146 | */ |
191 | struct DelayQueueEntry *generic_dqe_tail; | 147 | static struct GNUNET_TIME_Relative delay_in; |
192 | 148 | ||
193 | /** | 149 | /** |
194 | * Task to schedule delayed sending based on general delay | 150 | * Outbound delay to apply to all peers. |
195 | */ | 151 | */ |
196 | struct GNUNET_SCHEDULER_Task * generic_send_delay_task; | 152 | static struct GNUNET_TIME_Relative delay_out; |
197 | |||
198 | |||
199 | static void | ||
200 | set_metric(struct TM_Peer *dest, int direction, uint32_t type, uint32_t value) | ||
201 | { | ||
202 | struct PropManipulationEntry *cur; | ||
203 | for (cur = dest->head; NULL != cur; cur = cur->next) | ||
204 | { | ||
205 | if (cur->type == type) | ||
206 | break; | ||
207 | } | ||
208 | if (NULL == cur) | ||
209 | { | ||
210 | cur = GNUNET_new (struct PropManipulationEntry); | ||
211 | GNUNET_CONTAINER_DLL_insert(dest->head, dest->tail, cur); | ||
212 | cur->type = type; | ||
213 | cur->metrics[TM_SEND] = UINT32_MAX; | ||
214 | cur->metrics[TM_RECEIVE] = UINT32_MAX; | ||
215 | } | ||
216 | |||
217 | switch (direction) | ||
218 | { | ||
219 | case TM_BOTH: | ||
220 | cur->metrics[TM_SEND] = value; | ||
221 | cur->metrics[TM_RECEIVE] = value; | ||
222 | break; | ||
223 | case TM_SEND: | ||
224 | cur->metrics[TM_SEND] = value; | ||
225 | break; | ||
226 | case TM_RECEIVE: | ||
227 | cur->metrics[TM_RECEIVE] = value; | ||
228 | break; | ||
229 | default: | ||
230 | break; | ||
231 | } | ||
232 | } | ||
233 | |||
234 | |||
235 | static uint32_t | ||
236 | find_metric(struct TM_Peer *dest, uint32_t type, int direction) | ||
237 | { | ||
238 | struct PropManipulationEntry *cur; | ||
239 | |||
240 | for (cur = dest->head; NULL != cur; cur = cur->next) | ||
241 | { | ||
242 | if (cur->type == type) | ||
243 | return cur->metrics[direction]; | ||
244 | |||
245 | } | ||
246 | return UINT32_MAX; | ||
247 | } | ||
248 | 153 | ||
154 | /** | ||
155 | * DLL head for delayed messages based on general delay | ||
156 | */ | ||
157 | static struct DelayQueueEntry *generic_dqe_head; | ||
249 | 158 | ||
250 | /** | 159 | /** |
251 | * Clean up metrics for a peer | 160 | * DLL tail for delayed messages based on general delay |
252 | */ | 161 | */ |
253 | static void | 162 | static struct DelayQueueEntry *generic_dqe_tail; |
254 | free_metric(struct TM_Peer *dest) | ||
255 | { | ||
256 | struct PropManipulationEntry *cur; | ||
257 | struct PropManipulationEntry *next; | ||
258 | 163 | ||
259 | for (cur = dest->head; NULL != cur; cur = next) | 164 | /** |
260 | { | 165 | * Task to schedule delayed sending based on general delay |
261 | next = cur->next; | 166 | */ |
262 | GNUNET_CONTAINER_DLL_remove(dest->head, dest->tail, cur); | 167 | static struct GNUNET_SCHEDULER_Task *generic_send_delay_task; |
263 | GNUNET_free(cur); | ||
264 | } | ||
265 | } | ||
266 | 168 | ||
267 | 169 | ||
268 | /** | 170 | /** |
@@ -273,134 +175,106 @@ free_metric(struct TM_Peer *dest) | |||
273 | * @param message containing information | 175 | * @param message containing information |
274 | */ | 176 | */ |
275 | void | 177 | void |
276 | GST_manipulation_set_metric(void *cls, struct GNUNET_SERVER_Client *client, | 178 | GST_manipulation_set_metric (void *cls, |
277 | const struct GNUNET_MessageHeader *message) | 179 | struct GNUNET_SERVER_Client *client, |
180 | const struct GNUNET_MessageHeader *message) | ||
278 | { | 181 | { |
279 | struct TrafficMetricMessage *tm = (struct TrafficMetricMessage *) message; | 182 | const struct TrafficMetricMessage *tm; |
280 | struct GNUNET_PeerIdentity dummy; | 183 | static struct GNUNET_PeerIdentity zero; |
281 | struct GNUNET_ATS_Information *ats; | ||
282 | struct TM_Peer *tmp; | 184 | struct TM_Peer *tmp; |
283 | uint32_t type; | ||
284 | uint32_t value; | ||
285 | uint16_t direction; | ||
286 | int c; | ||
287 | int c2; | ||
288 | |||
289 | if (0 == ntohs(tm->ats_count)) | ||
290 | GNUNET_SERVER_receive_done(client, GNUNET_SYSERR); | ||
291 | |||
292 | direction = TM_BOTH; | ||
293 | switch (ntohs(tm->direction)) | ||
294 | { | ||
295 | case 1: | ||
296 | direction = TM_SEND; | ||
297 | break; | ||
298 | case 2: | ||
299 | direction = TM_RECEIVE; | ||
300 | break; | ||
301 | case 3: | ||
302 | direction = TM_BOTH; | ||
303 | break; | ||
304 | default: | ||
305 | break; | ||
306 | } | ||
307 | |||
308 | memset(&dummy, '\0', sizeof(struct GNUNET_PeerIdentity)); | ||
309 | if (0 == memcmp(&tm->peer, &dummy, sizeof(struct GNUNET_PeerIdentity))) | ||
310 | { | ||
311 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
312 | "Received traffic metrics for all peers \n"); | ||
313 | |||
314 | ats = (struct GNUNET_ATS_Information *) &tm[1]; | ||
315 | for (c = 0; c < ntohs(tm->ats_count); c++) | ||
316 | { | ||
317 | type = htonl(ats[c].type); | ||
318 | value = htonl(ats[c].value); | ||
319 | set_metric(&man_handle.general, direction, type, value); | ||
320 | } | ||
321 | return; | ||
322 | } | ||
323 | |||
324 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
325 | "Received traffic metrics for peer `%s'\n", GNUNET_i2s(&tm->peer)); | ||
326 | |||
327 | if (NULL | ||
328 | == (tmp = GNUNET_CONTAINER_multipeermap_get(man_handle.peers, &tm->peer))) | ||
329 | { | ||
330 | tmp = GNUNET_new (struct TM_Peer); | ||
331 | tmp->peer = (tm->peer); | ||
332 | for (c = 0; c < TM_BOTH; c++) | ||
333 | { | ||
334 | for (c2 = 0; c2 < GNUNET_ATS_QualityPropertiesCount; c2++) | ||
335 | { | ||
336 | tmp->metrics[c][c2] = UINT32_MAX; | ||
337 | } | ||
338 | } | ||
339 | GNUNET_CONTAINER_multipeermap_put(man_handle.peers, &tm->peer, tmp, | ||
340 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | ||
341 | } | ||
342 | 185 | ||
343 | ats = (struct GNUNET_ATS_Information *) &tm[1]; | 186 | tm = (const struct TrafficMetricMessage *) message; |
344 | for (c = 0; c < ntohs(tm->ats_count); c++) | 187 | if (0 == memcmp (&tm->peer, |
345 | { | 188 | &zero, |
346 | type = htonl(ats[c].type); | 189 | sizeof(struct GNUNET_PeerIdentity))) |
347 | value = htonl(ats[c].value); | 190 | { |
348 | set_metric(tmp, direction, type, value); | 191 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
349 | } | 192 | "Received traffic metrics for all peers\n"); |
350 | 193 | delay_in = GNUNET_TIME_relative_ntoh (tm->delay_in); | |
351 | GNUNET_SERVER_receive_done(client, GNUNET_OK); | 194 | delay_out = GNUNET_TIME_relative_ntoh (tm->delay_out); |
195 | GNUNET_SERVER_receive_done (client, | ||
196 | GNUNET_OK); | ||
197 | return; | ||
198 | } | ||
199 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
200 | "Received traffic metrics for peer `%s'\n", | ||
201 | GNUNET_i2s(&tm->peer)); | ||
202 | if (NULL == | ||
203 | (tmp = GNUNET_CONTAINER_multipeermap_get (peers, | ||
204 | &tm->peer))) | ||
205 | { | ||
206 | tmp = GNUNET_new (struct TM_Peer); | ||
207 | tmp->peer = tm->peer; | ||
208 | GNUNET_CONTAINER_multipeermap_put (peers, | ||
209 | &tm->peer, | ||
210 | tmp, | ||
211 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | ||
212 | } | ||
213 | GNUNET_ATS_properties_ntoh (&tmp->properties, | ||
214 | &tm->properties); | ||
215 | tmp->delay_in = GNUNET_TIME_relative_ntoh (tm->delay_in); | ||
216 | tmp->delay_out = GNUNET_TIME_relative_ntoh (tm->delay_out); | ||
217 | GNUNET_SERVER_receive_done (client, | ||
218 | GNUNET_OK); | ||
352 | } | 219 | } |
353 | 220 | ||
354 | 221 | ||
222 | /** | ||
223 | * We have delayed transmission, now it is time to send the | ||
224 | * message. | ||
225 | * | ||
226 | * @param cls the `struct DelayQueueEntry` to transmit | ||
227 | * @param tc unused | ||
228 | */ | ||
355 | static void | 229 | static void |
356 | send_delayed(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 230 | send_delayed (void *cls, |
231 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
357 | { | 232 | { |
358 | struct DelayQueueEntry *dqe = cls; | 233 | struct DelayQueueEntry *dqe = cls; |
359 | struct DelayQueueEntry *next; | 234 | struct DelayQueueEntry *next; |
360 | struct TM_Peer *tmp = dqe->tmp; | 235 | struct TM_Peer *tmp = dqe->tmp; |
361 | struct GNUNET_TIME_Relative delay; | 236 | struct GNUNET_TIME_Relative delay; |
362 | 237 | ||
238 | GNUNET_break (GNUNET_YES == | ||
239 | GST_neighbours_test_connected (&dqe->id)); | ||
363 | if (NULL != tmp) | 240 | if (NULL != tmp) |
241 | { | ||
242 | tmp->send_delay_task = NULL; | ||
243 | GNUNET_CONTAINER_DLL_remove (tmp->send_head, | ||
244 | tmp->send_tail, | ||
245 | dqe); | ||
246 | next = tmp->send_head; | ||
247 | if (NULL != next) | ||
364 | { | 248 | { |
365 | GNUNET_break (GNUNET_YES == | 249 | /* More delayed messages */ |
366 | GST_neighbours_test_connected (&dqe->id)); | 250 | delay = GNUNET_TIME_absolute_get_remaining(next->sent_at); |
367 | tmp->send_delay_task = NULL; | 251 | tmp->send_delay_task = GNUNET_SCHEDULER_add_delayed(delay, |
368 | GNUNET_CONTAINER_DLL_remove (tmp->send_head, | 252 | &send_delayed, next); |
369 | tmp->send_tail, | ||
370 | dqe); | ||
371 | GST_neighbours_send (&dqe->id, | ||
372 | dqe->msg, | ||
373 | dqe->msg_size, | ||
374 | dqe->timeout, | ||
375 | dqe->cont, | ||
376 | dqe->cont_cls); | ||
377 | |||
378 | next = tmp->send_head; | ||
379 | if (NULL != next) | ||
380 | { | ||
381 | /* More delayed messages */ | ||
382 | delay = GNUNET_TIME_absolute_get_remaining(next->sent_at); | ||
383 | tmp->send_delay_task = GNUNET_SCHEDULER_add_delayed(delay, | ||
384 | &send_delayed, next); | ||
385 | } | ||
386 | } | 253 | } |
254 | } | ||
387 | else | 255 | else |
256 | { | ||
257 | /* Remove from generic queue */ | ||
258 | generic_send_delay_task = NULL; | ||
259 | GNUNET_CONTAINER_DLL_remove (generic_dqe_head, | ||
260 | generic_dqe_tail, | ||
261 | dqe); | ||
262 | next = generic_dqe_head; | ||
263 | if (NULL != next) | ||
388 | { | 264 | { |
389 | /* Remove from generic queue */ | 265 | /* More delayed messages */ |
390 | GNUNET_break(GNUNET_YES == GST_neighbours_test_connected (&dqe->id)); | 266 | delay = GNUNET_TIME_absolute_get_remaining(next->sent_at); |
391 | generic_send_delay_task = NULL; | 267 | generic_send_delay_task = GNUNET_SCHEDULER_add_delayed (delay, |
392 | GNUNET_CONTAINER_DLL_remove(generic_dqe_head, generic_dqe_tail, dqe); | 268 | &send_delayed, |
393 | GST_neighbours_send(&dqe->id, dqe->msg, dqe->msg_size, dqe->timeout, | 269 | next); |
394 | dqe->cont, dqe->cont_cls); | ||
395 | next = generic_dqe_head; | ||
396 | if (NULL != next) | ||
397 | { | ||
398 | /* More delayed messages */ | ||
399 | delay = GNUNET_TIME_absolute_get_remaining(next->sent_at); | ||
400 | generic_send_delay_task = GNUNET_SCHEDULER_add_delayed(delay, | ||
401 | &send_delayed, next); | ||
402 | } | ||
403 | } | 270 | } |
271 | } | ||
272 | GST_neighbours_send (&dqe->id, | ||
273 | dqe->msg, | ||
274 | dqe->msg_size, | ||
275 | dqe->timeout, | ||
276 | dqe->cont, | ||
277 | dqe->cont_cls); | ||
404 | GNUNET_free(dqe); | 278 | GNUNET_free(dqe); |
405 | } | 279 | } |
406 | 280 | ||
@@ -427,41 +301,14 @@ GST_manipulation_send (const struct GNUNET_PeerIdentity *target, | |||
427 | struct TM_Peer *tmp; | 301 | struct TM_Peer *tmp; |
428 | struct DelayQueueEntry *dqe; | 302 | struct DelayQueueEntry *dqe; |
429 | struct GNUNET_TIME_Relative delay; | 303 | struct GNUNET_TIME_Relative delay; |
430 | int do_delay; | ||
431 | 304 | ||
432 | do_delay = GNUNET_NO; | ||
433 | if (NULL != (tmp = | 305 | if (NULL != (tmp = |
434 | GNUNET_CONTAINER_multipeermap_get (man_handle.peers, | 306 | GNUNET_CONTAINER_multipeermap_get (peers, |
435 | target))) | 307 | target))) |
436 | { | 308 | delay = tmp->delay_out; |
437 | GNUNET_break (GNUNET_YES == | 309 | else |
438 | GST_neighbours_test_connected(target)); | 310 | delay = delay_out; |
439 | /* check for peer-specific delay */ | 311 | if (0 == delay.rel_value_us) |
440 | if (UINT32_MAX != | ||
441 | find_metric (tmp, | ||
442 | GNUNET_ATS_QUALITY_NET_DELAY, | ||
443 | TM_SEND)) | ||
444 | { | ||
445 | /* We have a delay */ | ||
446 | delay.rel_value_us = find_metric(tmp, GNUNET_ATS_QUALITY_NET_DELAY, | ||
447 | TM_SEND); | ||
448 | do_delay = GNUNET_YES; | ||
449 | } | ||
450 | } | ||
451 | else if (UINT32_MAX != | ||
452 | find_metric(&man_handle.general, | ||
453 | GNUNET_ATS_QUALITY_NET_DELAY, | ||
454 | TM_SEND)) | ||
455 | { | ||
456 | GNUNET_break (GNUNET_YES == | ||
457 | GST_neighbours_test_connected (target)); | ||
458 | /* We have a delay */ | ||
459 | delay.rel_value_us = find_metric (&man_handle.general, | ||
460 | GNUNET_ATS_QUALITY_NET_DELAY, | ||
461 | TM_SEND); | ||
462 | do_delay = GNUNET_YES; | ||
463 | } | ||
464 | if (GNUNET_NO == do_delay) | ||
465 | { | 312 | { |
466 | /* Normal sending */ | 313 | /* Normal sending */ |
467 | GST_neighbours_send (target, | 314 | GST_neighbours_send (target, |
@@ -516,46 +363,22 @@ GST_manipulation_send (const struct GNUNET_PeerIdentity *target, | |||
516 | * Function that will be called to manipulate ATS information according to | 363 | * Function that will be called to manipulate ATS information according to |
517 | * current manipulation settings | 364 | * current manipulation settings |
518 | * | 365 | * |
519 | * @param peer the peer | ||
520 | * @param address binary address | 366 | * @param address binary address |
521 | * @param session the session | 367 | * @param session the session |
522 | * @param ats the ats information | 368 | * @param prop[IN|OUT] metrics to modify |
523 | * @param ats_count the number of ats information | ||
524 | */ | 369 | */ |
525 | struct GNUNET_ATS_Information * | 370 | void |
526 | GST_manipulation_manipulate_metrics (const struct GNUNET_HELLO_Address *address, | 371 | GST_manipulation_manipulate_metrics (const struct GNUNET_HELLO_Address *address, |
527 | struct Session *session, | 372 | struct Session *session, |
528 | const struct GNUNET_ATS_Information *ats, | 373 | struct GNUNET_ATS_Properties *prop) |
529 | uint32_t ats_count) | ||
530 | { | 374 | { |
531 | const struct GNUNET_PeerIdentity *peer = &address->peer; | 375 | const struct GNUNET_PeerIdentity *peer = &address->peer; |
532 | struct GNUNET_ATS_Information *ats_new; | ||
533 | struct TM_Peer *tmp; | 376 | struct TM_Peer *tmp; |
534 | uint32_t m_tmp; | 377 | |
535 | uint32_t g_tmp; | 378 | tmp = GNUNET_CONTAINER_multipeermap_get (peers, |
536 | uint32_t d; | 379 | peer); |
537 | 380 | if (NULL != tmp) | |
538 | if (0 == ats_count) | 381 | *prop = tmp->properties; |
539 | return NULL; | ||
540 | ats_new = GNUNET_malloc (sizeof (struct GNUNET_ATS_Information) * ats_count); | ||
541 | tmp = GNUNET_CONTAINER_multipeermap_get (man_handle.peers, peer); | ||
542 | for (d = 0; d < ats_count; d++) | ||
543 | { | ||
544 | ats_new[d] = ats[d]; | ||
545 | m_tmp = UINT32_MAX; | ||
546 | if (NULL != tmp) | ||
547 | m_tmp = find_metric (tmp, ntohl(ats[d].type), | ||
548 | TM_RECEIVE); | ||
549 | g_tmp = find_metric (&man_handle.general, | ||
550 | ntohl(ats[d].type), | ||
551 | TM_RECEIVE); | ||
552 | |||
553 | if (UINT32_MAX != g_tmp) | ||
554 | ats_new[d].value = htonl(g_tmp); | ||
555 | if (UINT32_MAX != m_tmp) | ||
556 | ats_new[d].value = htonl(m_tmp); | ||
557 | } | ||
558 | return ats_new; | ||
559 | } | 382 | } |
560 | 383 | ||
561 | 384 | ||
@@ -576,32 +399,22 @@ GST_manipulation_recv (void *cls, | |||
576 | const struct GNUNET_MessageHeader *message) | 399 | const struct GNUNET_MessageHeader *message) |
577 | { | 400 | { |
578 | struct TM_Peer *tmp; | 401 | struct TM_Peer *tmp; |
579 | uint32_t p_recv_delay; | ||
580 | uint32_t g_recv_delay; | ||
581 | struct GNUNET_TIME_Relative quota_delay; | 402 | struct GNUNET_TIME_Relative quota_delay; |
582 | struct GNUNET_TIME_Relative m_delay; | 403 | struct GNUNET_TIME_Relative m_delay; |
583 | 404 | ||
584 | g_recv_delay = find_metric(&man_handle.general, GNUNET_ATS_QUALITY_NET_DELAY, | 405 | if (NULL != |
585 | TM_RECEIVE); | 406 | (tmp = GNUNET_CONTAINER_multipeermap_get (peers, |
586 | if ((g_recv_delay >= GNUNET_TIME_UNIT_ZERO.rel_value_us) | 407 | &address->peer))) |
587 | && (UINT32_MAX != g_recv_delay)) | 408 | m_delay = tmp->delay_in; |
588 | m_delay.rel_value_us = g_recv_delay; /* Global delay */ | ||
589 | else | 409 | else |
590 | m_delay = GNUNET_TIME_UNIT_ZERO; | 410 | m_delay = delay_in; |
591 | 411 | ||
592 | if (NULL != (tmp = GNUNET_CONTAINER_multipeermap_get(man_handle.peers, &address->peer))) | 412 | quota_delay = GST_receive_callback (cls, |
593 | { | 413 | address, |
594 | /* Manipulate receive delay */ | 414 | session, |
595 | p_recv_delay = find_metric(tmp, GNUNET_ATS_QUALITY_NET_DELAY, TM_RECEIVE); | 415 | message); |
596 | if (UINT32_MAX != p_recv_delay) | 416 | m_delay = GNUNET_TIME_relative_max (m_delay, |
597 | m_delay.rel_value_us = p_recv_delay; /* Peer specific delay */ | 417 | quota_delay); |
598 | } | ||
599 | |||
600 | quota_delay = GST_receive_callback(cls, address, session, message); | ||
601 | |||
602 | if (quota_delay.rel_value_us > m_delay.rel_value_us) | ||
603 | m_delay = quota_delay; | ||
604 | |||
605 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 418 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
606 | "Delaying next receive for peer `%s' for %s\n", | 419 | "Delaying next receive for peer `%s' for %s\n", |
607 | GNUNET_i2s (&address->peer), | 420 | GNUNET_i2s (&address->peer), |
@@ -613,63 +426,110 @@ GST_manipulation_recv (void *cls, | |||
613 | 426 | ||
614 | /** | 427 | /** |
615 | * Initialize traffic manipulation | 428 | * Initialize traffic manipulation |
616 | * | ||
617 | * @param GST_cfg configuration handle | ||
618 | */ | 429 | */ |
619 | void | 430 | void |
620 | GST_manipulation_init(const struct GNUNET_CONFIGURATION_Handle *GST_cfg) | 431 | GST_manipulation_init () |
621 | { | 432 | { |
622 | unsigned long long tmp; | ||
623 | struct GNUNET_TIME_Relative delay; | 433 | struct GNUNET_TIME_Relative delay; |
624 | 434 | ||
625 | if ( (GNUNET_OK == | 435 | if ( (GNUNET_OK == |
626 | GNUNET_CONFIGURATION_get_value_number(GST_cfg, | 436 | GNUNET_CONFIGURATION_get_value_time (GST_cfg, |
627 | "transport", | 437 | "transport", |
628 | "MANIPULATE_DISTANCE_IN", | 438 | "MANIPULATE_DELAY_IN", |
629 | &tmp)) && | 439 | &delay)) && |
630 | (tmp > 0) ) | 440 | (delay.rel_value_us > 0) ) |
631 | { | 441 | { |
632 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | 442 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
633 | "Setting inbound distance_in to %llu\n", | 443 | "Delaying inbound traffic for %s\n", |
634 | (unsigned long long) tmp); | 444 | GNUNET_STRINGS_relative_time_to_string (delay, |
635 | set_metric (&man_handle.general, | 445 | GNUNET_YES)); |
636 | TM_RECEIVE, | 446 | delay_in = delay; |
637 | GNUNET_ATS_QUALITY_NET_DISTANCE, | ||
638 | tmp); | ||
639 | } | 447 | } |
448 | if ( (GNUNET_OK == | ||
449 | GNUNET_CONFIGURATION_get_value_time (GST_cfg, | ||
450 | "transport", | ||
451 | "MANIPULATE_DELAY_OUT", | ||
452 | &delay)) && | ||
453 | (delay.rel_value_us > 0) ) | ||
454 | { | ||
455 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
456 | "Delaying outbound traffic for %s\n", | ||
457 | GNUNET_STRINGS_relative_time_to_string (delay, | ||
458 | GNUNET_YES)); | ||
459 | delay_out = delay; | ||
460 | } | ||
461 | peers = GNUNET_CONTAINER_multipeermap_create (4, | ||
462 | GNUNET_NO); | ||
463 | } | ||
640 | 464 | ||
641 | if ((GNUNET_OK | ||
642 | == GNUNET_CONFIGURATION_get_value_number(GST_cfg, "transport", | ||
643 | "MANIPULATE_DISTANCE_OUT", &tmp)) && (tmp > 0)) | ||
644 | { | ||
645 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | ||
646 | "Setting outbound distance_in to %llu\n", (unsigned long long) tmp); | ||
647 | set_metric(&man_handle.general, TM_SEND, GNUNET_ATS_QUALITY_NET_DISTANCE, | ||
648 | tmp); | ||
649 | } | ||
650 | 465 | ||
651 | if ((GNUNET_OK | 466 | /** |
652 | == GNUNET_CONFIGURATION_get_value_time(GST_cfg, "transport", | 467 | * Notify manipulation about disconnect so it can discard queued messages |
653 | "MANIPULATE_DELAY_IN", &delay)) && (delay.rel_value_us > 0)) | 468 | * |
469 | * @param peer the disconnecting peer | ||
470 | */ | ||
471 | void | ||
472 | GST_manipulation_peer_disconnect (const struct GNUNET_PeerIdentity *peer) | ||
473 | { | ||
474 | struct TM_Peer *tmp; | ||
475 | struct DelayQueueEntry *dqe; | ||
476 | struct DelayQueueEntry *next; | ||
477 | |||
478 | tmp = GNUNET_CONTAINER_multipeermap_get (peers, | ||
479 | peer); | ||
480 | if (NULL != tmp) | ||
481 | { | ||
482 | while (NULL != (dqe = tmp->send_head)) | ||
654 | { | 483 | { |
655 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | 484 | GNUNET_CONTAINER_DLL_remove (tmp->send_head, |
656 | "Delaying inbound traffic for %s\n", GNUNET_STRINGS_relative_time_to_string (delay, GNUNET_YES)); | 485 | tmp->send_tail, |
657 | set_metric(&man_handle.general, TM_RECEIVE, GNUNET_ATS_QUALITY_NET_DELAY, | 486 | dqe); |
658 | delay.rel_value_us); | 487 | if (NULL != dqe->cont) |
488 | dqe->cont (dqe->cont_cls, | ||
489 | GNUNET_SYSERR, | ||
490 | dqe->msg_size, | ||
491 | 0); | ||
492 | GNUNET_free(dqe); | ||
659 | } | 493 | } |
660 | if ((GNUNET_OK | 494 | } |
661 | == GNUNET_CONFIGURATION_get_value_time(GST_cfg, "transport", | 495 | next = generic_dqe_head; |
662 | "MANIPULATE_DELAY_OUT", &delay)) && (delay.rel_value_us > 0)) | 496 | while (NULL != (dqe = next)) |
497 | { | ||
498 | next = dqe->next; | ||
499 | if (0 == memcmp(peer, &dqe->id, sizeof(dqe->id))) | ||
663 | { | 500 | { |
664 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | 501 | GNUNET_CONTAINER_DLL_remove (generic_dqe_head, |
665 | "Delaying outbound traffic for %s\n", GNUNET_STRINGS_relative_time_to_string (delay, GNUNET_YES)); | 502 | generic_dqe_tail, |
666 | set_metric(&man_handle.general, TM_SEND, GNUNET_ATS_QUALITY_NET_DELAY, | 503 | dqe); |
667 | delay.rel_value_us); | 504 | if (NULL != dqe->cont) |
505 | dqe->cont (dqe->cont_cls, | ||
506 | GNUNET_SYSERR, | ||
507 | dqe->msg_size, | ||
508 | 0); | ||
509 | GNUNET_free(dqe); | ||
668 | } | 510 | } |
669 | man_handle.peers = GNUNET_CONTAINER_multipeermap_create(10, GNUNET_NO); | 511 | } |
512 | if (NULL != generic_send_delay_task) | ||
513 | { | ||
514 | GNUNET_SCHEDULER_cancel (generic_send_delay_task); | ||
515 | generic_send_delay_task = NULL; | ||
516 | if (NULL != generic_dqe_head) | ||
517 | generic_send_delay_task | ||
518 | = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining(generic_dqe_head->sent_at), | ||
519 | &send_delayed, | ||
520 | generic_dqe_head); | ||
521 | } | ||
670 | } | 522 | } |
671 | 523 | ||
672 | 524 | ||
525 | /** | ||
526 | * Free manipulation information about a peer. | ||
527 | * | ||
528 | * @param cls NULL | ||
529 | * @param key peer the info is about | ||
530 | * @param value a `struct TM_Peer` to free | ||
531 | * @return #GNUNET_OK (continue to iterate) | ||
532 | */ | ||
673 | static int | 533 | static int |
674 | free_tmps (void *cls, | 534 | free_tmps (void *cls, |
675 | const struct GNUNET_PeerIdentity *key, | 535 | const struct GNUNET_PeerIdentity *key, |
@@ -678,13 +538,10 @@ free_tmps (void *cls, | |||
678 | struct TM_Peer *tmp = value; | 538 | struct TM_Peer *tmp = value; |
679 | struct DelayQueueEntry *dqe; | 539 | struct DelayQueueEntry *dqe; |
680 | 540 | ||
681 | if (NULL == tmp) | ||
682 | return GNUNET_OK; | ||
683 | GNUNET_break (GNUNET_YES == | 541 | GNUNET_break (GNUNET_YES == |
684 | GNUNET_CONTAINER_multipeermap_remove (man_handle.peers, | 542 | GNUNET_CONTAINER_multipeermap_remove (peers, |
685 | key, | 543 | key, |
686 | value)); | 544 | value)); |
687 | free_metric (tmp); | ||
688 | while (NULL != (dqe = tmp->send_head)) | 545 | while (NULL != (dqe = tmp->send_head)) |
689 | { | 546 | { |
690 | GNUNET_CONTAINER_DLL_remove (tmp->send_head, | 547 | GNUNET_CONTAINER_DLL_remove (tmp->send_head, |
@@ -699,89 +556,27 @@ free_tmps (void *cls, | |||
699 | } | 556 | } |
700 | if (NULL != tmp->send_delay_task) | 557 | if (NULL != tmp->send_delay_task) |
701 | { | 558 | { |
702 | GNUNET_SCHEDULER_cancel(tmp->send_delay_task); | 559 | GNUNET_SCHEDULER_cancel (tmp->send_delay_task); |
703 | tmp->send_delay_task = NULL; | 560 | tmp->send_delay_task = NULL; |
704 | } | 561 | } |
705 | GNUNET_free(tmp); | 562 | GNUNET_free (tmp); |
706 | return GNUNET_OK; | 563 | return GNUNET_OK; |
707 | } | 564 | } |
708 | 565 | ||
709 | 566 | ||
710 | /** | 567 | /** |
711 | * Notify manipulation about disconnect so it can discard queued messages | ||
712 | * | ||
713 | * @param peer the disconnecting peer | ||
714 | */ | ||
715 | void | ||
716 | GST_manipulation_peer_disconnect (const struct GNUNET_PeerIdentity *peer) | ||
717 | { | ||
718 | struct TM_Peer *tmp; | ||
719 | struct DelayQueueEntry *dqe; | ||
720 | struct DelayQueueEntry *next; | ||
721 | |||
722 | if (NULL != (tmp = GNUNET_CONTAINER_multipeermap_get(man_handle.peers, peer))) | ||
723 | { | ||
724 | while (NULL != (dqe = tmp->send_head)) | ||
725 | { | ||
726 | GNUNET_CONTAINER_DLL_remove (tmp->send_head, | ||
727 | tmp->send_tail, | ||
728 | dqe); | ||
729 | if (NULL != dqe->cont) | ||
730 | dqe->cont (dqe->cont_cls, | ||
731 | GNUNET_SYSERR, | ||
732 | dqe->msg_size, | ||
733 | 0); | ||
734 | GNUNET_free(dqe); | ||
735 | } | ||
736 | } | ||
737 | else if (UINT32_MAX != find_metric (&man_handle.general, | ||
738 | GNUNET_ATS_QUALITY_NET_DELAY, | ||
739 | TM_SEND)) | ||
740 | { | ||
741 | next = generic_dqe_head; | ||
742 | while (NULL != (dqe = next)) | ||
743 | { | ||
744 | next = dqe->next; | ||
745 | if (0 == memcmp(peer, &dqe->id, sizeof(dqe->id))) | ||
746 | { | ||
747 | GNUNET_CONTAINER_DLL_remove (generic_dqe_head, | ||
748 | generic_dqe_tail, | ||
749 | dqe); | ||
750 | if (NULL != dqe->cont) | ||
751 | dqe->cont (dqe->cont_cls, | ||
752 | GNUNET_SYSERR, | ||
753 | dqe->msg_size, | ||
754 | 0); | ||
755 | GNUNET_free(dqe); | ||
756 | } | ||
757 | } | ||
758 | if (NULL != generic_send_delay_task) | ||
759 | { | ||
760 | GNUNET_SCHEDULER_cancel (generic_send_delay_task); | ||
761 | generic_send_delay_task = NULL; | ||
762 | if (NULL != generic_dqe_head) | ||
763 | generic_send_delay_task | ||
764 | = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining(generic_dqe_head->sent_at), | ||
765 | &send_delayed, | ||
766 | generic_dqe_head); | ||
767 | } | ||
768 | } | ||
769 | } | ||
770 | |||
771 | |||
772 | /** | ||
773 | * Stop traffic manipulation | 568 | * Stop traffic manipulation |
774 | */ | 569 | */ |
775 | void | 570 | void |
776 | GST_manipulation_stop() | 571 | GST_manipulation_stop () |
777 | { | 572 | { |
778 | struct DelayQueueEntry *cur; | 573 | struct DelayQueueEntry *cur; |
779 | 574 | ||
780 | GNUNET_CONTAINER_multipeermap_iterate (man_handle.peers, | 575 | GNUNET_CONTAINER_multipeermap_iterate (peers, |
781 | &free_tmps, | 576 | &free_tmps, |
782 | NULL); | 577 | NULL); |
783 | GNUNET_CONTAINER_multipeermap_destroy (man_handle.peers); | 578 | GNUNET_CONTAINER_multipeermap_destroy (peers); |
784 | 579 | peers = NULL; | |
785 | while (NULL != (cur = generic_dqe_head)) | 580 | while (NULL != (cur = generic_dqe_head)) |
786 | { | 581 | { |
787 | GNUNET_CONTAINER_DLL_remove (generic_dqe_head, | 582 | GNUNET_CONTAINER_DLL_remove (generic_dqe_head, |
@@ -799,8 +594,6 @@ GST_manipulation_stop() | |||
799 | GNUNET_SCHEDULER_cancel (generic_send_delay_task); | 594 | GNUNET_SCHEDULER_cancel (generic_send_delay_task); |
800 | generic_send_delay_task = NULL; | 595 | generic_send_delay_task = NULL; |
801 | } | 596 | } |
802 | free_metric (&man_handle.general); | ||
803 | man_handle.peers = NULL; | ||
804 | } | 597 | } |
805 | 598 | ||
806 | /* end of file gnunet-service-transport_manipulation.c */ | 599 | /* end of file gnunet-service-transport_manipulation.c */ |