diff options
-rw-r--r-- | src/transport/gnunet-service-transport_manipulation.c | 997 |
1 files changed, 487 insertions, 510 deletions
diff --git a/src/transport/gnunet-service-transport_manipulation.c b/src/transport/gnunet-service-transport_manipulation.c index 0d087c3bd..4521047c9 100644 --- a/src/transport/gnunet-service-transport_manipulation.c +++ b/src/transport/gnunet-service-transport_manipulation.c | |||
@@ -1,22 +1,22 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | (C) 2010-2013 Christian Grothoff (and other contributing authors) | 3 | (C) 2010-2013 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
7 | by the Free Software Foundation; either version 3, or (at your | 7 | by the Free Software Foundation; either version 3, or (at your |
8 | option) any later version. | 8 | option) any later version. |
9 | 9 | ||
10 | GNUnet is distributed in the hope that it will be useful, but | 10 | GNUnet is distributed in the hope that it will be useful, but |
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | General Public License for more details. | 13 | General Public License for more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU General Public License | 15 | You should have received a copy of the GNU General Public License |
16 | along with GNUnet; see the file COPYING. If not, write to the | 16 | along with GNUnet; see the file COPYING. If not, write to the |
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
18 | Boston, MA 02111-1307, USA. | 18 | Boston, MA 02111-1307, USA. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | /** | 21 | /** |
22 | * @file transport/gnunet-service-transport_manipulation.c | 22 | * @file transport/gnunet-service-transport_manipulation.c |
@@ -36,12 +36,9 @@ | |||
36 | 36 | ||
37 | enum TRAFFIC_METRIC_DIRECTION | 37 | enum TRAFFIC_METRIC_DIRECTION |
38 | { | 38 | { |
39 | TM_SEND = 0, | 39 | TM_SEND = 0, TM_RECEIVE = 1, TM_BOTH = 2 |
40 | TM_RECEIVE = 1, | ||
41 | TM_BOTH = 2 | ||
42 | }; | 40 | }; |
43 | 41 | ||
44 | |||
45 | /** | 42 | /** |
46 | * Struct containing information about manipulations to a specific peer | 43 | * Struct containing information about manipulations to a specific peer |
47 | */ | 44 | */ |
@@ -52,25 +49,25 @@ struct TM_Peer; | |||
52 | */ | 49 | */ |
53 | struct PropManipulationEntry | 50 | struct PropManipulationEntry |
54 | { | 51 | { |
55 | /** | 52 | /** |
56 | * Next in DLL | 53 | * Next in DLL |
57 | */ | 54 | */ |
58 | struct PropManipulationEntry *next; | 55 | struct PropManipulationEntry *next; |
59 | 56 | ||
60 | /** | 57 | /** |
61 | * Previous in DLL | 58 | * Previous in DLL |
62 | */ | 59 | */ |
63 | struct PropManipulationEntry *prev; | 60 | struct PropManipulationEntry *prev; |
64 | 61 | ||
65 | /** | 62 | /** |
66 | * ATS type in HBO | 63 | * ATS type in HBO |
67 | */ | 64 | */ |
68 | uint32_t type; | 65 | uint32_t type; |
69 | 66 | ||
70 | /** | 67 | /** |
71 | * Value in HBO | 68 | * Value in HBO |
72 | */ | 69 | */ |
73 | uint32_t metrics[TM_BOTH]; | 70 | uint32_t metrics[TM_BOTH]; |
74 | 71 | ||
75 | }; | 72 | }; |
76 | 73 | ||
@@ -79,107 +76,104 @@ struct PropManipulationEntry | |||
79 | */ | 76 | */ |
80 | struct TM_Peer | 77 | struct TM_Peer |
81 | { | 78 | { |
82 | /** | 79 | /** |
83 | * Peer ID | 80 | * Peer ID |
84 | */ | 81 | */ |
85 | struct GNUNET_PeerIdentity peer; | 82 | struct GNUNET_PeerIdentity peer; |
86 | 83 | ||
87 | struct PropManipulationEntry *head; | 84 | struct PropManipulationEntry *head; |
88 | struct PropManipulationEntry *tail; | 85 | struct PropManipulationEntry *tail; |
89 | 86 | ||
90 | /** | 87 | /** |
91 | * Peer specific manipulation metrics | 88 | * Peer specific manipulation metrics |
92 | */ | 89 | */ |
93 | uint32_t metrics [TM_BOTH][GNUNET_ATS_QualityPropertiesCount]; | 90 | uint32_t metrics[TM_BOTH][GNUNET_ATS_QualityPropertiesCount]; |
94 | 91 | ||
95 | /** | 92 | /** |
96 | * Task to schedule delayed sendding | 93 | * Task to schedule delayed sendding |
97 | */ | 94 | */ |
98 | GNUNET_SCHEDULER_TaskIdentifier send_delay_task; | 95 | GNUNET_SCHEDULER_TaskIdentifier send_delay_task; |
99 | 96 | ||
100 | /** | 97 | /** |
101 | * Send queue DLL head | 98 | * Send queue DLL head |
102 | */ | 99 | */ |
103 | struct DelayQueueEntry *send_head; | 100 | struct DelayQueueEntry *send_head; |
104 | 101 | ||
105 | /** | 102 | /** |
106 | * Send queue DLL tail | 103 | * Send queue DLL tail |
107 | */ | 104 | */ |
108 | struct DelayQueueEntry *send_tail; | 105 | struct DelayQueueEntry *send_tail; |
109 | }; | 106 | }; |
110 | 107 | ||
111 | |||
112 | struct GST_ManipulationHandle | 108 | struct GST_ManipulationHandle |
113 | { | 109 | { |
114 | /** | 110 | /** |
115 | * Hashmap contain all peers currently manipulated | 111 | * Hashmap contain all peers currently manipulated |
116 | */ | 112 | */ |
117 | struct GNUNET_CONTAINER_MultiPeerMap *peers; | 113 | struct GNUNET_CONTAINER_MultiPeerMap *peers; |
118 | 114 | ||
119 | /** | 115 | /** |
120 | * Peer containing information for general manipulation | 116 | * Peer containing information for general manipulation |
121 | */ | 117 | */ |
122 | struct TM_Peer general; | 118 | struct TM_Peer general; |
123 | }; | 119 | }; |
124 | 120 | ||
125 | |||
126 | |||
127 | /** | 121 | /** |
128 | * Entry in the delay queue for an outbound delayed message | 122 | * Entry in the delay queue for an outbound delayed message |
129 | */ | 123 | */ |
130 | struct DelayQueueEntry | 124 | struct DelayQueueEntry |
131 | { | 125 | { |
132 | /** | 126 | /** |
133 | * Next in DLL | 127 | * Next in DLL |
134 | */ | 128 | */ |
135 | struct DelayQueueEntry *prev; | 129 | struct DelayQueueEntry *prev; |
136 | 130 | ||
137 | /** | 131 | /** |
138 | * Previous in DLL | 132 | * Previous in DLL |
139 | */ | 133 | */ |
140 | struct DelayQueueEntry *next; | 134 | struct DelayQueueEntry *next; |
141 | 135 | ||
142 | /** | 136 | /** |
143 | * Peer this entry is belonging to | 137 | * Peer this entry is belonging to |
144 | * if (NULL == tmp): enqueued in generic DLL and scheduled by generic_send_delay_task | 138 | * if (NULL == tmp): enqueued in generic DLL and scheduled by generic_send_delay_task |
145 | * else: enqueued in tmp->send_head and tmp->send_tail and scheduled by tmp->send_delay_task | 139 | * else: enqueued in tmp->send_head and tmp->send_tail and scheduled by tmp->send_delay_task |
146 | */ | 140 | */ |
147 | struct TM_Peer *tmp; | 141 | struct TM_Peer *tmp; |
148 | 142 | ||
149 | /** | 143 | /** |
150 | * Peer ID | 144 | * Peer ID |
151 | */ | 145 | */ |
152 | struct GNUNET_PeerIdentity id; | 146 | struct GNUNET_PeerIdentity id; |
153 | 147 | ||
154 | /** | 148 | /** |
155 | * Absolute time when to send | 149 | * Absolute time when to send |
156 | */ | 150 | */ |
157 | struct GNUNET_TIME_Absolute sent_at; | 151 | struct GNUNET_TIME_Absolute sent_at; |
158 | 152 | ||
159 | /** | 153 | /** |
160 | * The message | 154 | * The message |
161 | */ | 155 | */ |
162 | void *msg; | 156 | void *msg; |
163 | 157 | ||
164 | /** | 158 | /** |
165 | * The message size | 159 | * The message size |
166 | */ | 160 | */ |
167 | size_t msg_size; | 161 | size_t msg_size; |
168 | 162 | ||
169 | /** | 163 | /** |
170 | * Message timeout | 164 | * Message timeout |
171 | */ | 165 | */ |
172 | struct GNUNET_TIME_Relative timeout; | 166 | struct GNUNET_TIME_Relative timeout; |
173 | 167 | ||
174 | /** | 168 | /** |
175 | * Transports send continuation | 169 | * Transports send continuation |
176 | */ | 170 | */ |
177 | GST_NeighbourSendContinuation cont; | 171 | GST_NeighbourSendContinuation cont; |
178 | 172 | ||
179 | /** | 173 | /** |
180 | * Transports send continuation cls | 174 | * Transports send continuation cls |
181 | */ | 175 | */ |
182 | void *cont_cls; | 176 | void *cont_cls; |
183 | }; | 177 | }; |
184 | 178 | ||
185 | struct GST_ManipulationHandle man_handle; | 179 | struct GST_ManipulationHandle man_handle; |
@@ -200,53 +194,53 @@ struct DelayQueueEntry *generic_dqe_tail; | |||
200 | GNUNET_SCHEDULER_TaskIdentifier generic_send_delay_task; | 194 | GNUNET_SCHEDULER_TaskIdentifier generic_send_delay_task; |
201 | 195 | ||
202 | static void | 196 | static void |
203 | set_metric (struct TM_Peer *dest, int direction, uint32_t type, uint32_t value) | 197 | set_metric(struct TM_Peer *dest, int direction, uint32_t type, uint32_t value) |
204 | { | 198 | { |
205 | struct PropManipulationEntry *cur; | 199 | struct PropManipulationEntry *cur; |
206 | for (cur = dest->head; NULL != cur; cur = cur->next) | 200 | for (cur = dest->head; NULL != cur; cur = cur->next) |
207 | { | 201 | { |
208 | if (cur->type == type) | 202 | if (cur->type == type) |
209 | break; | 203 | break; |
210 | } | 204 | } |
211 | if (NULL == cur) | 205 | if (NULL == cur) |
212 | { | 206 | { |
213 | cur = GNUNET_new (struct PropManipulationEntry); | 207 | cur = GNUNET_new (struct PropManipulationEntry); |
214 | GNUNET_CONTAINER_DLL_insert (dest->head, dest->tail, cur); | 208 | GNUNET_CONTAINER_DLL_insert(dest->head, dest->tail, cur); |
215 | cur->type = type; | 209 | cur->type = type; |
216 | cur->metrics[TM_SEND] = UINT32_MAX; | 210 | cur->metrics[TM_SEND] = UINT32_MAX; |
217 | cur->metrics[TM_RECEIVE] = UINT32_MAX; | 211 | cur->metrics[TM_RECEIVE] = UINT32_MAX; |
218 | } | 212 | } |
219 | 213 | ||
220 | 214 | switch (direction) | |
221 | switch (direction) { | 215 | { |
222 | case TM_BOTH: | 216 | case TM_BOTH: |
223 | cur->metrics[TM_SEND] = value; | 217 | cur->metrics[TM_SEND] = value; |
224 | cur->metrics[TM_RECEIVE] = value; | 218 | cur->metrics[TM_RECEIVE] = value; |
225 | break; | 219 | break; |
226 | case TM_SEND: | 220 | case TM_SEND: |
227 | cur->metrics[TM_SEND] = value; | 221 | cur->metrics[TM_SEND] = value; |
228 | break; | 222 | break; |
229 | case TM_RECEIVE: | 223 | case TM_RECEIVE: |
230 | cur->metrics[TM_RECEIVE] = value; | 224 | cur->metrics[TM_RECEIVE] = value; |
231 | break; | 225 | break; |
232 | default: | 226 | default: |
233 | break; | 227 | break; |
234 | } | 228 | } |
235 | 229 | ||
236 | } | 230 | } |
237 | 231 | ||
238 | static uint32_t | 232 | static uint32_t |
239 | find_metric (struct TM_Peer *dest, uint32_t type, int direction) | 233 | find_metric(struct TM_Peer *dest, uint32_t type, int direction) |
240 | { | 234 | { |
241 | struct PropManipulationEntry *cur; | 235 | struct PropManipulationEntry *cur; |
242 | 236 | ||
243 | for (cur = dest->head; NULL != cur; cur = cur->next) | 237 | for (cur = dest->head; NULL != cur; cur = cur->next) |
244 | { | 238 | { |
245 | if (cur->type == type) | 239 | if (cur->type == type) |
246 | return cur->metrics[direction]; | 240 | return cur->metrics[direction]; |
247 | 241 | ||
248 | } | 242 | } |
249 | return UINT32_MAX; | 243 | return UINT32_MAX; |
250 | } | 244 | } |
251 | 245 | ||
252 | /** | 246 | /** |
@@ -254,19 +248,18 @@ find_metric (struct TM_Peer *dest, uint32_t type, int direction) | |||
254 | */ | 248 | */ |
255 | 249 | ||
256 | static void | 250 | static void |
257 | free_metric (struct TM_Peer *dest) | 251 | free_metric(struct TM_Peer *dest) |
258 | { | 252 | { |
259 | struct PropManipulationEntry *cur; | 253 | struct PropManipulationEntry *cur; |
260 | struct PropManipulationEntry *next; | 254 | struct PropManipulationEntry *next; |
261 | |||
262 | for (cur = dest->head; NULL != cur; cur = next) | ||
263 | { | ||
264 | next = cur->next; | ||
265 | GNUNET_CONTAINER_DLL_remove (dest->head, dest->tail, cur); | ||
266 | GNUNET_free (cur); | ||
267 | } | ||
268 | } | ||
269 | 255 | ||
256 | for (cur = dest->head; NULL != cur; cur = next) | ||
257 | { | ||
258 | next = cur->next; | ||
259 | GNUNET_CONTAINER_DLL_remove(dest->head, dest->tail, cur); | ||
260 | GNUNET_free(cur); | ||
261 | } | ||
262 | } | ||
270 | 263 | ||
271 | /** | 264 | /** |
272 | * Set traffic metric to manipulate | 265 | * Set traffic metric to manipulate |
@@ -276,123 +269,128 @@ free_metric (struct TM_Peer *dest) | |||
276 | * @param message containing information | 269 | * @param message containing information |
277 | */ | 270 | */ |
278 | void | 271 | void |
279 | GST_manipulation_set_metric (void *cls, struct GNUNET_SERVER_Client *client, | 272 | GST_manipulation_set_metric(void *cls, struct GNUNET_SERVER_Client *client, |
280 | const struct GNUNET_MessageHeader *message) | 273 | const struct GNUNET_MessageHeader *message) |
281 | { | 274 | { |
282 | struct TrafficMetricMessage *tm = (struct TrafficMetricMessage *) message; | 275 | struct TrafficMetricMessage *tm = (struct TrafficMetricMessage *) message; |
283 | struct GNUNET_PeerIdentity dummy; | 276 | struct GNUNET_PeerIdentity dummy; |
284 | struct GNUNET_ATS_Information *ats; | 277 | struct GNUNET_ATS_Information *ats; |
285 | struct TM_Peer *tmp; | 278 | struct TM_Peer *tmp; |
286 | uint32_t type; | 279 | uint32_t type; |
287 | uint32_t value; | 280 | uint32_t value; |
288 | uint16_t direction; | 281 | uint16_t direction; |
289 | int c; | 282 | int c; |
290 | int c2; | 283 | int c2; |
291 | 284 | ||
292 | if (0 == ntohs (tm->ats_count)) | 285 | if (0 == ntohs(tm->ats_count)) |
293 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 286 | GNUNET_SERVER_receive_done(client, GNUNET_SYSERR); |
294 | 287 | ||
295 | direction = TM_BOTH; | 288 | direction = TM_BOTH; |
296 | switch (ntohs(tm->direction)) { | 289 | switch (ntohs(tm->direction)) |
297 | case 1: | 290 | { |
298 | direction = TM_SEND; | 291 | case 1: |
299 | break; | 292 | direction = TM_SEND; |
300 | case 2: | 293 | break; |
301 | direction = TM_RECEIVE; | 294 | case 2: |
302 | break; | 295 | direction = TM_RECEIVE; |
303 | case 3: | 296 | break; |
304 | direction = TM_BOTH; | 297 | case 3: |
305 | break; | 298 | direction = TM_BOTH; |
306 | default: | 299 | break; |
307 | break; | 300 | default: |
308 | } | 301 | break; |
309 | 302 | } | |
310 | memset (&dummy, '\0', sizeof (struct GNUNET_PeerIdentity)); | 303 | |
311 | if (0 == memcmp (&tm->peer, &dummy, sizeof (struct GNUNET_PeerIdentity))) | 304 | memset(&dummy, '\0', sizeof(struct GNUNET_PeerIdentity)); |
312 | { | 305 | if (0 == memcmp(&tm->peer, &dummy, sizeof(struct GNUNET_PeerIdentity))) |
313 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received traffic metrics for all peers \n"); | 306 | { |
314 | 307 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | |
315 | ats = (struct GNUNET_ATS_Information *) &tm[1]; | 308 | "Received traffic metrics for all peers \n"); |
316 | for (c = 0; c < ntohs (tm->ats_count); c++) | 309 | |
317 | { | 310 | ats = (struct GNUNET_ATS_Information *) &tm[1]; |
318 | type = htonl (ats[c].type); | 311 | for (c = 0; c < ntohs(tm->ats_count); c++) |
319 | value = htonl (ats[c].value); | 312 | { |
320 | set_metric (&man_handle.general, direction, type, value); | 313 | type = htonl(ats[c].type); |
321 | } | 314 | value = htonl(ats[c].value); |
322 | return; | 315 | set_metric(&man_handle.general, direction, type, value); |
323 | } | 316 | } |
324 | 317 | return; | |
325 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received traffic metrics for peer `%s'\n", | 318 | } |
326 | GNUNET_i2s(&tm->peer)); | 319 | |
327 | 320 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | |
328 | if (NULL == (tmp = GNUNET_CONTAINER_multipeermap_get (man_handle.peers, &tm->peer))) | 321 | "Received traffic metrics for peer `%s'\n", GNUNET_i2s(&tm->peer)); |
329 | { | 322 | |
330 | tmp = GNUNET_new (struct TM_Peer); | 323 | if (NULL |
331 | tmp->peer = (tm->peer); | 324 | == (tmp = GNUNET_CONTAINER_multipeermap_get(man_handle.peers, &tm->peer))) |
332 | for (c = 0; c < TM_BOTH; c++) | 325 | { |
333 | { | 326 | tmp = GNUNET_new (struct TM_Peer); |
334 | for (c2 = 0; c2 < GNUNET_ATS_QualityPropertiesCount; c2++) | 327 | tmp->peer = (tm->peer); |
335 | { | 328 | for (c = 0; c < TM_BOTH; c++) |
336 | tmp->metrics[c][c2] = UINT32_MAX; | 329 | { |
337 | } | 330 | for (c2 = 0; c2 < GNUNET_ATS_QualityPropertiesCount; c2++) |
338 | } | 331 | { |
339 | GNUNET_CONTAINER_multipeermap_put (man_handle.peers, | 332 | tmp->metrics[c][c2] = UINT32_MAX; |
340 | &tm->peer, tmp, | 333 | } |
341 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | 334 | } |
342 | } | 335 | GNUNET_CONTAINER_multipeermap_put(man_handle.peers, &tm->peer, tmp, |
343 | 336 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | |
344 | ats = (struct GNUNET_ATS_Information *) &tm[1]; | 337 | } |
345 | for (c = 0; c < ntohs (tm->ats_count); c++) | 338 | |
346 | { | 339 | ats = (struct GNUNET_ATS_Information *) &tm[1]; |
347 | type = htonl (ats[c].type); | 340 | for (c = 0; c < ntohs(tm->ats_count); c++) |
348 | value = htonl (ats[c].value); | 341 | { |
349 | set_metric (tmp, direction, type, value); | 342 | type = htonl(ats[c].type); |
350 | } | 343 | value = htonl(ats[c].value); |
351 | 344 | set_metric(tmp, direction, type, value); | |
352 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 345 | } |
346 | |||
347 | GNUNET_SERVER_receive_done(client, GNUNET_OK); | ||
353 | } | 348 | } |
354 | 349 | ||
355 | static void | 350 | static void |
356 | send_delayed (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 351 | send_delayed(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
357 | { | 352 | { |
358 | struct DelayQueueEntry *dqe = cls; | 353 | struct DelayQueueEntry *dqe = cls; |
359 | struct DelayQueueEntry *next; | 354 | struct DelayQueueEntry *next; |
360 | struct TM_Peer *tmp = dqe->tmp; | 355 | struct TM_Peer *tmp = dqe->tmp; |
361 | struct GNUNET_TIME_Relative delay; | 356 | struct GNUNET_TIME_Relative delay; |
362 | |||
363 | if (NULL != tmp) | ||
364 | { | ||
365 | GNUNET_break (GNUNET_YES == GST_neighbours_test_connected (&dqe->id)); | ||
366 | tmp->send_delay_task = GNUNET_SCHEDULER_NO_TASK; | ||
367 | GNUNET_CONTAINER_DLL_remove (tmp->send_head, tmp->send_tail, dqe); | ||
368 | GST_neighbours_send (&dqe->id, dqe->msg, dqe->msg_size, dqe->timeout, dqe->cont, dqe->cont_cls); | ||
369 | |||
370 | next = tmp->send_head; | ||
371 | if (NULL != next) | ||
372 | { | ||
373 | /* More delayed messages */ | ||
374 | delay = GNUNET_TIME_absolute_get_remaining (next->sent_at); | ||
375 | tmp->send_delay_task = GNUNET_SCHEDULER_add_delayed (delay, &send_delayed, next); | ||
376 | } | ||
377 | } | ||
378 | else | ||
379 | { | ||
380 | /* Remove from generic queue */ | ||
381 | GNUNET_break (GNUNET_YES == GST_neighbours_test_connected (&dqe->id)); | ||
382 | generic_send_delay_task = GNUNET_SCHEDULER_NO_TASK; | ||
383 | GNUNET_CONTAINER_DLL_remove (generic_dqe_head, generic_dqe_tail, dqe); | ||
384 | GST_neighbours_send (&dqe->id, dqe->msg, dqe->msg_size, dqe->timeout, dqe->cont, dqe->cont_cls); | ||
385 | next = generic_dqe_head; | ||
386 | if (NULL != next) | ||
387 | { | ||
388 | /* More delayed messages */ | ||
389 | delay = GNUNET_TIME_absolute_get_remaining (next->sent_at); | ||
390 | generic_send_delay_task = GNUNET_SCHEDULER_add_delayed (delay, &send_delayed, next); | ||
391 | } | ||
392 | } | ||
393 | GNUNET_free (dqe); | ||
394 | } | ||
395 | 357 | ||
358 | if (NULL != tmp) | ||
359 | { | ||
360 | GNUNET_break(GNUNET_YES == GST_neighbours_test_connected (&dqe->id)); | ||
361 | tmp->send_delay_task = GNUNET_SCHEDULER_NO_TASK; | ||
362 | GNUNET_CONTAINER_DLL_remove(tmp->send_head, tmp->send_tail, dqe); | ||
363 | GST_neighbours_send(&dqe->id, dqe->msg, dqe->msg_size, dqe->timeout, | ||
364 | dqe->cont, dqe->cont_cls); | ||
365 | |||
366 | next = tmp->send_head; | ||
367 | if (NULL != next) | ||
368 | { | ||
369 | /* More delayed messages */ | ||
370 | delay = GNUNET_TIME_absolute_get_remaining(next->sent_at); | ||
371 | tmp->send_delay_task = GNUNET_SCHEDULER_add_delayed(delay, | ||
372 | &send_delayed, next); | ||
373 | } | ||
374 | } | ||
375 | else | ||
376 | { | ||
377 | /* Remove from generic queue */ | ||
378 | GNUNET_break(GNUNET_YES == GST_neighbours_test_connected (&dqe->id)); | ||
379 | generic_send_delay_task = GNUNET_SCHEDULER_NO_TASK; | ||
380 | GNUNET_CONTAINER_DLL_remove(generic_dqe_head, generic_dqe_tail, dqe); | ||
381 | GST_neighbours_send(&dqe->id, dqe->msg, dqe->msg_size, dqe->timeout, | ||
382 | dqe->cont, dqe->cont_cls); | ||
383 | next = generic_dqe_head; | ||
384 | if (NULL != next) | ||
385 | { | ||
386 | /* More delayed messages */ | ||
387 | delay = GNUNET_TIME_absolute_get_remaining(next->sent_at); | ||
388 | generic_send_delay_task = GNUNET_SCHEDULER_add_delayed(delay, | ||
389 | &send_delayed, next); | ||
390 | } | ||
391 | } | ||
392 | GNUNET_free(dqe); | ||
393 | } | ||
396 | 394 | ||
397 | /** | 395 | /** |
398 | * Adapter function between transport's send function and transport plugins | 396 | * Adapter function between transport's send function and transport plugins |
@@ -405,7 +403,7 @@ send_delayed (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
405 | * @param cont_cls cls for continuation | 403 | * @param cont_cls cls for continuation |
406 | */ | 404 | */ |
407 | void | 405 | void |
408 | GST_manipulation_send (const struct GNUNET_PeerIdentity *target, const void *msg, | 406 | GST_manipulation_send(const struct GNUNET_PeerIdentity *target, const void *msg, |
409 | size_t msg_size, struct GNUNET_TIME_Relative timeout, | 407 | size_t msg_size, struct GNUNET_TIME_Relative timeout, |
410 | GST_NeighbourSendContinuation cont, void *cont_cls) | 408 | GST_NeighbourSendContinuation cont, void *cont_cls) |
411 | { | 409 | { |
@@ -413,67 +411,71 @@ GST_manipulation_send (const struct GNUNET_PeerIdentity *target, const void *msg | |||
413 | struct DelayQueueEntry *dqe; | 411 | struct DelayQueueEntry *dqe; |
414 | struct GNUNET_TIME_Relative delay; | 412 | struct GNUNET_TIME_Relative delay; |
415 | 413 | ||
416 | if (NULL != (tmp = GNUNET_CONTAINER_multipeermap_get (man_handle.peers, target))) | 414 | if (NULL |
417 | { | 415 | != (tmp = GNUNET_CONTAINER_multipeermap_get(man_handle.peers, target))) |
418 | GNUNET_break (GNUNET_YES == GST_neighbours_test_connected(target)); | 416 | { |
419 | /* Manipulate here */ | 417 | GNUNET_break(GNUNET_YES == GST_neighbours_test_connected(target)); |
420 | /* Delay */ | 418 | /* Manipulate here */ |
421 | if (UINT32_MAX != find_metric(tmp, GNUNET_ATS_QUALITY_NET_DELAY, TM_SEND)) | 419 | /* Delay */ |
420 | if (UINT32_MAX != find_metric(tmp, GNUNET_ATS_QUALITY_NET_DELAY, TM_SEND)) | ||
421 | { | ||
422 | /* We have a delay */ | ||
423 | delay.rel_value_us = find_metric(tmp, GNUNET_ATS_QUALITY_NET_DELAY, | ||
424 | TM_SEND); | ||
425 | dqe = GNUNET_malloc (sizeof (struct DelayQueueEntry) + msg_size); | ||
426 | dqe->id = *target; | ||
427 | dqe->tmp = tmp; | ||
428 | dqe->sent_at = GNUNET_TIME_absolute_add(GNUNET_TIME_absolute_get(), | ||
429 | delay); | ||
430 | dqe->cont = cont; | ||
431 | dqe->cont_cls = cont_cls; | ||
432 | dqe->msg = &dqe[1]; | ||
433 | dqe->msg_size = msg_size; | ||
434 | dqe->timeout = timeout; | ||
435 | memcpy(dqe->msg, msg, msg_size); | ||
436 | GNUNET_CONTAINER_DLL_insert_tail(tmp->send_head, tmp->send_tail, dqe); | ||
437 | if (GNUNET_SCHEDULER_NO_TASK == tmp->send_delay_task) | ||
438 | tmp->send_delay_task = GNUNET_SCHEDULER_add_delayed(delay, | ||
439 | &send_delayed, dqe); | ||
440 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
441 | "Delaying %u byte message to peer `%s' with generic delay for %ms\n", msg_size, GNUNET_i2s (target), GNUNET_STRINGS_relative_time_to_string (delay, GNUNET_YES)); | ||
442 | return; | ||
443 | } | ||
444 | } | ||
445 | else if (UINT32_MAX | ||
446 | != find_metric(&man_handle.general, GNUNET_ATS_QUALITY_NET_DELAY, | ||
447 | TM_SEND)) | ||
422 | { | 448 | { |
449 | GNUNET_break(GNUNET_YES == GST_neighbours_test_connected(target)); | ||
423 | /* We have a delay */ | 450 | /* We have a delay */ |
424 | delay.rel_value_us = find_metric (tmp, GNUNET_ATS_QUALITY_NET_DELAY, TM_SEND); | 451 | delay.rel_value_us = find_metric(&man_handle.general, |
452 | GNUNET_ATS_QUALITY_NET_DELAY, TM_SEND); | ||
425 | dqe = GNUNET_malloc (sizeof (struct DelayQueueEntry) + msg_size); | 453 | dqe = GNUNET_malloc (sizeof (struct DelayQueueEntry) + msg_size); |
426 | dqe->id = *target; | 454 | dqe->id = *target; |
427 | dqe->tmp = tmp; | 455 | dqe->tmp = NULL; |
428 | dqe->sent_at = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(), delay); | 456 | dqe->sent_at = GNUNET_TIME_absolute_add(GNUNET_TIME_absolute_get(), |
457 | delay); | ||
429 | dqe->cont = cont; | 458 | dqe->cont = cont; |
430 | dqe->cont_cls = cont_cls; | 459 | dqe->cont_cls = cont_cls; |
431 | dqe->msg = &dqe[1]; | 460 | dqe->msg = &dqe[1]; |
432 | dqe->msg_size = msg_size; | 461 | dqe->msg_size = msg_size; |
433 | dqe->timeout = timeout; | 462 | dqe->timeout = timeout; |
434 | memcpy (dqe->msg, msg, msg_size); | 463 | memcpy(dqe->msg, msg, msg_size); |
435 | GNUNET_CONTAINER_DLL_insert_tail (tmp->send_head, tmp->send_tail, dqe); | 464 | GNUNET_CONTAINER_DLL_insert_tail(generic_dqe_head, generic_dqe_tail, dqe); |
436 | if (GNUNET_SCHEDULER_NO_TASK == tmp->send_delay_task) | 465 | if (GNUNET_SCHEDULER_NO_TASK == generic_send_delay_task) |
437 | tmp->send_delay_task =GNUNET_SCHEDULER_add_delayed (delay, &send_delayed, dqe); | 466 | { |
438 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 467 | generic_send_delay_task = GNUNET_SCHEDULER_add_delayed(delay, |
439 | "Delaying %u byte message to peer `%s' with generic delay for %ms\n", | 468 | &send_delayed, dqe); |
440 | msg_size, GNUNET_i2s (target), | 469 | } |
441 | GNUNET_STRINGS_relative_time_to_string (delay, GNUNET_YES)); | 470 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, |
471 | "Delaying %u byte message to peer `%s' with peer specific delay for %s\n", msg_size, GNUNET_i2s (target), GNUNET_STRINGS_relative_time_to_string (delay, GNUNET_YES)); | ||
442 | return; | 472 | return; |
443 | } | 473 | } |
444 | } | ||
445 | else if (UINT32_MAX != find_metric (&man_handle.general, GNUNET_ATS_QUALITY_NET_DELAY, TM_SEND)) | ||
446 | { | ||
447 | GNUNET_break (GNUNET_YES == GST_neighbours_test_connected(target)); | ||
448 | /* We have a delay */ | ||
449 | delay.rel_value_us = find_metric (&man_handle.general, GNUNET_ATS_QUALITY_NET_DELAY, TM_SEND); | ||
450 | dqe = GNUNET_malloc (sizeof (struct DelayQueueEntry) + msg_size); | ||
451 | dqe->id = *target; | ||
452 | dqe->tmp = NULL; | ||
453 | dqe->sent_at = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(), delay); | ||
454 | dqe->cont = cont; | ||
455 | dqe->cont_cls = cont_cls; | ||
456 | dqe->msg = &dqe[1]; | ||
457 | dqe->msg_size = msg_size; | ||
458 | dqe->timeout = timeout; | ||
459 | memcpy (dqe->msg, msg, msg_size); | ||
460 | GNUNET_CONTAINER_DLL_insert_tail (generic_dqe_head, generic_dqe_tail, dqe); | ||
461 | if (GNUNET_SCHEDULER_NO_TASK == generic_send_delay_task) | ||
462 | { | ||
463 | generic_send_delay_task = GNUNET_SCHEDULER_add_delayed (delay, &send_delayed, dqe); | ||
464 | } | ||
465 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
466 | "Delaying %u byte message to peer `%s' with peer specific delay for %s\n", | ||
467 | msg_size, GNUNET_i2s (target), | ||
468 | GNUNET_STRINGS_relative_time_to_string (delay, GNUNET_YES)); | ||
469 | return; | ||
470 | } | ||
471 | 474 | ||
472 | /* Normal sending */ | 475 | /* Normal sending */ |
473 | GST_neighbours_send (target, msg, msg_size, timeout, cont, cont_cls); | 476 | GST_neighbours_send(target, msg, msg_size, timeout, cont, cont_cls); |
474 | } | 477 | } |
475 | 478 | ||
476 | |||
477 | /** | 479 | /** |
478 | * Function that will be called to manipulate ATS information according to | 480 | * Function that will be called to manipulate ATS information according to |
479 | * current manipulation settings | 481 | * current manipulation settings |
@@ -485,36 +487,34 @@ GST_manipulation_send (const struct GNUNET_PeerIdentity *target, const void *msg | |||
485 | * @param ats_count the number of ats information | 487 | * @param ats_count the number of ats information |
486 | */ | 488 | */ |
487 | struct GNUNET_ATS_Information * | 489 | struct GNUNET_ATS_Information * |
488 | GST_manipulation_manipulate_metrics (const struct GNUNET_PeerIdentity *peer, | 490 | GST_manipulation_manipulate_metrics(const struct GNUNET_PeerIdentity *peer, |
489 | const struct GNUNET_HELLO_Address *address, | 491 | const struct GNUNET_HELLO_Address *address, struct Session *session, |
490 | struct Session *session, | 492 | const struct GNUNET_ATS_Information *ats, uint32_t ats_count) |
491 | const struct GNUNET_ATS_Information *ats, | ||
492 | uint32_t ats_count) | ||
493 | { | 493 | { |
494 | struct GNUNET_ATS_Information *ats_new = GNUNET_malloc (sizeof (struct GNUNET_ATS_Information) *ats_count); | 494 | struct GNUNET_ATS_Information *ats_new = |
495 | struct TM_Peer *tmp; | 495 | GNUNET_malloc (sizeof (struct GNUNET_ATS_Information) *ats_count); |
496 | uint32_t m_tmp; | 496 | struct TM_Peer *tmp; |
497 | uint32_t g_tmp; | 497 | uint32_t m_tmp; |
498 | int d; | 498 | uint32_t g_tmp; |
499 | tmp = GNUNET_CONTAINER_multipeermap_get (man_handle.peers, peer); | 499 | int d; |
500 | 500 | tmp = GNUNET_CONTAINER_multipeermap_get(man_handle.peers, peer); | |
501 | for (d = 0; d < ats_count; d++) | 501 | |
502 | { | 502 | for (d = 0; d < ats_count; d++) |
503 | ats_new[d] = ats[d]; | 503 | { |
504 | m_tmp = UINT32_MAX; | 504 | ats_new[d] = ats[d]; |
505 | if (NULL != tmp) | 505 | m_tmp = UINT32_MAX; |
506 | m_tmp = find_metric (tmp, ntohl(ats[d].type), TM_RECEIVE); | 506 | if (NULL != tmp) |
507 | g_tmp = find_metric (&man_handle.general, ntohl(ats[d].type), TM_RECEIVE); | 507 | m_tmp = find_metric(tmp, ntohl(ats[d].type), TM_RECEIVE); |
508 | 508 | g_tmp = find_metric(&man_handle.general, ntohl(ats[d].type), TM_RECEIVE); | |
509 | if (UINT32_MAX != g_tmp) | 509 | |
510 | ats_new[d].value = htonl(g_tmp); | 510 | if (UINT32_MAX != g_tmp) |
511 | if (UINT32_MAX != m_tmp) | 511 | ats_new[d].value = htonl(g_tmp); |
512 | ats_new[d].value = htonl(m_tmp); | 512 | if (UINT32_MAX != m_tmp) |
513 | } | 513 | ats_new[d].value = htonl(m_tmp); |
514 | 514 | } | |
515 | return ats_new; | ||
516 | } | ||
517 | 515 | ||
516 | return ats_new; | ||
517 | } | ||
518 | 518 | ||
519 | /** | 519 | /** |
520 | * Adapter function between transport plugins and transport receive function | 520 | * Adapter function between transport plugins and transport receive function |
@@ -529,47 +529,43 @@ GST_manipulation_manipulate_metrics (const struct GNUNET_PeerIdentity *peer, | |||
529 | * @return manipulated delay for next receive | 529 | * @return manipulated delay for next receive |
530 | */ | 530 | */ |
531 | struct GNUNET_TIME_Relative | 531 | struct GNUNET_TIME_Relative |
532 | GST_manipulation_recv (void *cls, | 532 | GST_manipulation_recv(void *cls, const struct GNUNET_PeerIdentity *peer, |
533 | const struct GNUNET_PeerIdentity *peer, | 533 | const struct GNUNET_MessageHeader *message, struct Session *session, |
534 | const struct GNUNET_MessageHeader *message, | 534 | const char *sender_address, uint16_t sender_address_len) |
535 | struct Session *session, | ||
536 | const char *sender_address, | ||
537 | uint16_t sender_address_len) | ||
538 | { | 535 | { |
539 | struct TM_Peer *tmp; | 536 | struct TM_Peer *tmp; |
540 | uint32_t p_recv_delay; | 537 | uint32_t p_recv_delay; |
541 | uint32_t g_recv_delay; | 538 | uint32_t g_recv_delay; |
542 | struct GNUNET_TIME_Relative quota_delay; | 539 | struct GNUNET_TIME_Relative quota_delay; |
543 | struct GNUNET_TIME_Relative m_delay; | 540 | struct GNUNET_TIME_Relative m_delay; |
544 | 541 | ||
545 | g_recv_delay = find_metric (&man_handle.general, GNUNET_ATS_QUALITY_NET_DELAY, TM_RECEIVE); | 542 | g_recv_delay = find_metric(&man_handle.general, GNUNET_ATS_QUALITY_NET_DELAY, |
546 | if ((g_recv_delay >= GNUNET_TIME_UNIT_ZERO.rel_value_us) && (UINT32_MAX != g_recv_delay)) | 543 | TM_RECEIVE); |
547 | m_delay.rel_value_us = g_recv_delay; /* Global delay */ | 544 | if ((g_recv_delay >= GNUNET_TIME_UNIT_ZERO.rel_value_us) |
548 | else | 545 | && (UINT32_MAX != g_recv_delay)) |
549 | m_delay = GNUNET_TIME_UNIT_ZERO; | 546 | m_delay.rel_value_us = g_recv_delay; /* Global delay */ |
550 | 547 | else | |
551 | if (NULL != (tmp = GNUNET_CONTAINER_multipeermap_get (man_handle.peers, peer))) | 548 | m_delay = GNUNET_TIME_UNIT_ZERO; |
552 | { | ||
553 | /* Manipulate receive delay */ | ||
554 | p_recv_delay = find_metric (tmp, GNUNET_ATS_QUALITY_NET_DELAY, TM_RECEIVE); | ||
555 | if (UINT32_MAX != p_recv_delay) | ||
556 | m_delay.rel_value_us = p_recv_delay; /* Peer specific delay */ | ||
557 | } | ||
558 | |||
559 | quota_delay = GST_receive_callback (cls, peer, message, | ||
560 | session, sender_address, sender_address_len); | ||
561 | |||
562 | if (quota_delay.rel_value_us > m_delay.rel_value_us) | ||
563 | m_delay = quota_delay; | ||
564 | |||
565 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
566 | "Delaying next receive for peer `%s' for %s\n", | ||
567 | GNUNET_i2s (peer), | ||
568 | GNUNET_STRINGS_relative_time_to_string (m_delay, GNUNET_YES)); | ||
569 | return m_delay; | ||
570 | 549 | ||
571 | } | 550 | if (NULL != (tmp = GNUNET_CONTAINER_multipeermap_get(man_handle.peers, peer))) |
551 | { | ||
552 | /* Manipulate receive delay */ | ||
553 | p_recv_delay = find_metric(tmp, GNUNET_ATS_QUALITY_NET_DELAY, TM_RECEIVE); | ||
554 | if (UINT32_MAX != p_recv_delay) | ||
555 | m_delay.rel_value_us = p_recv_delay; /* Peer specific delay */ | ||
556 | } | ||
572 | 557 | ||
558 | quota_delay = GST_receive_callback(cls, peer, message, session, | ||
559 | sender_address, sender_address_len); | ||
560 | |||
561 | if (quota_delay.rel_value_us > m_delay.rel_value_us) | ||
562 | m_delay = quota_delay; | ||
563 | |||
564 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
565 | "Delaying next receive for peer `%s' for %s\n", GNUNET_i2s (peer), GNUNET_STRINGS_relative_time_to_string (m_delay, GNUNET_YES)); | ||
566 | return m_delay; | ||
567 | |||
568 | } | ||
573 | 569 | ||
574 | /** | 570 | /** |
575 | * Initialize traffic manipulation | 571 | * Initialize traffic manipulation |
@@ -577,102 +573,85 @@ GST_manipulation_recv (void *cls, | |||
577 | * @param GST_cfg configuration handle | 573 | * @param GST_cfg configuration handle |
578 | */ | 574 | */ |
579 | void | 575 | void |
580 | GST_manipulation_init (const struct GNUNET_CONFIGURATION_Handle *GST_cfg) | 576 | GST_manipulation_init(const struct GNUNET_CONFIGURATION_Handle *GST_cfg) |
581 | { | 577 | { |
582 | unsigned long long tmp; | 578 | unsigned long long tmp; |
583 | struct GNUNET_TIME_Relative delay; | 579 | struct GNUNET_TIME_Relative delay; |
584 | 580 | ||
585 | if ( (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (GST_cfg, | 581 | if ((GNUNET_OK |
586 | "transport", | 582 | == GNUNET_CONFIGURATION_get_value_number(GST_cfg, "transport", |
587 | "MANIPULATE_DISTANCE_IN", | 583 | "MANIPULATE_DISTANCE_IN", &tmp)) && (tmp > 0)) |
588 | &tmp)) && | 584 | { |
589 | (tmp > 0) ) | 585 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, |
590 | { | 586 | "Setting inbound distance_in to %llu\n", (unsigned long long) tmp); |
591 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 587 | set_metric(&man_handle.general, TM_RECEIVE, |
592 | "Setting inbound distance_in to %llu\n", | 588 | GNUNET_ATS_QUALITY_NET_DISTANCE, tmp); |
593 | (unsigned long long) tmp); | 589 | } |
594 | set_metric (&man_handle.general, TM_RECEIVE, GNUNET_ATS_QUALITY_NET_DISTANCE, tmp); | ||
595 | } | ||
596 | |||
597 | if ( (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (GST_cfg, | ||
598 | "transport", | ||
599 | "MANIPULATE_DISTANCE_OUT", | ||
600 | &tmp)) && | ||
601 | (tmp > 0) ) | ||
602 | { | ||
603 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
604 | "Setting outbound distance_in to %llu\n", | ||
605 | (unsigned long long) tmp); | ||
606 | set_metric (&man_handle.general, TM_SEND, | ||
607 | GNUNET_ATS_QUALITY_NET_DISTANCE, tmp); | ||
608 | } | ||
609 | |||
610 | if ( (GNUNET_OK == GNUNET_CONFIGURATION_get_value_time (GST_cfg, | ||
611 | "transport", | ||
612 | "MANIPULATE_DELAY_IN", | ||
613 | &delay)) && | ||
614 | (delay.rel_value_us > 0) ) | ||
615 | { | ||
616 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
617 | "Delaying inbound traffic for %s\n", | ||
618 | GNUNET_STRINGS_relative_time_to_string (delay, GNUNET_YES)); | ||
619 | set_metric (&man_handle.general, TM_RECEIVE, | ||
620 | GNUNET_ATS_QUALITY_NET_DELAY, | ||
621 | delay.rel_value_us); | ||
622 | } | ||
623 | if ( (GNUNET_OK == GNUNET_CONFIGURATION_get_value_time (GST_cfg, | ||
624 | "transport", | ||
625 | "MANIPULATE_DELAY_OUT", | ||
626 | &delay)) && | ||
627 | (delay.rel_value_us > 0) ) | ||
628 | { | ||
629 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
630 | "Delaying outbound traffic for %s\n", | ||
631 | GNUNET_STRINGS_relative_time_to_string (delay, GNUNET_YES)); | ||
632 | set_metric (&man_handle.general, | ||
633 | TM_SEND, | ||
634 | GNUNET_ATS_QUALITY_NET_DELAY, | ||
635 | delay.rel_value_us); | ||
636 | } | ||
637 | man_handle.peers = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO); | ||
638 | } | ||
639 | 590 | ||
591 | if ((GNUNET_OK | ||
592 | == GNUNET_CONFIGURATION_get_value_number(GST_cfg, "transport", | ||
593 | "MANIPULATE_DISTANCE_OUT", &tmp)) && (tmp > 0)) | ||
594 | { | ||
595 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | ||
596 | "Setting outbound distance_in to %llu\n", (unsigned long long) tmp); | ||
597 | set_metric(&man_handle.general, TM_SEND, GNUNET_ATS_QUALITY_NET_DISTANCE, | ||
598 | tmp); | ||
599 | } | ||
600 | |||
601 | if ((GNUNET_OK | ||
602 | == GNUNET_CONFIGURATION_get_value_time(GST_cfg, "transport", | ||
603 | "MANIPULATE_DELAY_IN", &delay)) && (delay.rel_value_us > 0)) | ||
604 | { | ||
605 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | ||
606 | "Delaying inbound traffic for %s\n", GNUNET_STRINGS_relative_time_to_string (delay, GNUNET_YES)); | ||
607 | set_metric(&man_handle.general, TM_RECEIVE, GNUNET_ATS_QUALITY_NET_DELAY, | ||
608 | delay.rel_value_us); | ||
609 | } | ||
610 | if ((GNUNET_OK | ||
611 | == GNUNET_CONFIGURATION_get_value_time(GST_cfg, "transport", | ||
612 | "MANIPULATE_DELAY_OUT", &delay)) && (delay.rel_value_us > 0)) | ||
613 | { | ||
614 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | ||
615 | "Delaying outbound traffic for %s\n", GNUNET_STRINGS_relative_time_to_string (delay, GNUNET_YES)); | ||
616 | set_metric(&man_handle.general, TM_SEND, GNUNET_ATS_QUALITY_NET_DELAY, | ||
617 | delay.rel_value_us); | ||
618 | } | ||
619 | man_handle.peers = GNUNET_CONTAINER_multipeermap_create(10, GNUNET_NO); | ||
620 | } | ||
640 | 621 | ||
641 | static int | 622 | static int |
642 | free_tmps (void *cls, | 623 | free_tmps(void *cls, const struct GNUNET_PeerIdentity *key, void *value) |
643 | const struct GNUNET_PeerIdentity *key, | ||
644 | void *value) | ||
645 | { | 624 | { |
646 | struct DelayQueueEntry *dqe; | 625 | struct DelayQueueEntry *dqe; |
647 | struct DelayQueueEntry *next; | 626 | struct DelayQueueEntry *next; |
648 | 627 | ||
649 | if (NULL != value) | 628 | if (NULL != value) |
650 | { | 629 | { |
651 | struct TM_Peer *tmp = (struct TM_Peer *) value; | 630 | struct TM_Peer *tmp = (struct TM_Peer *) value; |
652 | 631 | ||
653 | if (GNUNET_YES != GNUNET_CONTAINER_multipeermap_remove (man_handle.peers, key, value)) | 632 | if (GNUNET_YES |
654 | GNUNET_break (0); | 633 | != GNUNET_CONTAINER_multipeermap_remove(man_handle.peers, key, value)) |
655 | free_metric (tmp); | 634 | GNUNET_break(0); |
656 | next = tmp->send_head; | 635 | free_metric(tmp); |
657 | while (NULL != (dqe = next)) | 636 | next = tmp->send_head; |
658 | { | 637 | while (NULL != (dqe = next)) |
659 | next = dqe->next; | 638 | { |
660 | GNUNET_CONTAINER_DLL_remove (tmp->send_head, tmp->send_tail, dqe); | 639 | next = dqe->next; |
661 | if (NULL != dqe->cont) | 640 | GNUNET_CONTAINER_DLL_remove(tmp->send_head, tmp->send_tail, dqe); |
662 | dqe->cont (dqe->cont_cls, GNUNET_SYSERR, dqe->msg_size, 0); | 641 | if (NULL != dqe->cont) |
663 | GNUNET_free (dqe); | 642 | dqe->cont(dqe->cont_cls, GNUNET_SYSERR, dqe->msg_size, 0); |
664 | } | 643 | GNUNET_free(dqe); |
665 | if (GNUNET_SCHEDULER_NO_TASK != tmp->send_delay_task) | 644 | } |
666 | { | 645 | if (GNUNET_SCHEDULER_NO_TASK != tmp->send_delay_task) |
667 | GNUNET_SCHEDULER_cancel (tmp->send_delay_task); | 646 | { |
668 | tmp->send_delay_task = GNUNET_SCHEDULER_NO_TASK; | 647 | GNUNET_SCHEDULER_cancel(tmp->send_delay_task); |
669 | } | 648 | tmp->send_delay_task = GNUNET_SCHEDULER_NO_TASK; |
670 | GNUNET_free (tmp); | 649 | } |
671 | } | 650 | GNUNET_free(tmp); |
651 | } | ||
672 | return GNUNET_OK; | 652 | return GNUNET_OK; |
673 | } | 653 | } |
674 | 654 | ||
675 | |||
676 | /** | 655 | /** |
677 | * Notify manipulation about disconnect so it can discard queued messages | 656 | * Notify manipulation about disconnect so it can discard queued messages |
678 | * | 657 | * |
@@ -725,36 +704,34 @@ GST_manipulation_peer_disconnect(const struct GNUNET_PeerIdentity *peer) | |||
725 | } | 704 | } |
726 | } | 705 | } |
727 | 706 | ||
728 | |||
729 | /** | 707 | /** |
730 | * Stop traffic manipulation | 708 | * Stop traffic manipulation |
731 | */ | 709 | */ |
732 | void | 710 | void |
733 | GST_manipulation_stop () | 711 | GST_manipulation_stop() |
734 | { | 712 | { |
735 | struct DelayQueueEntry *cur; | 713 | struct DelayQueueEntry *cur; |
736 | struct DelayQueueEntry *next; | 714 | struct DelayQueueEntry *next; |
737 | GNUNET_CONTAINER_multipeermap_iterate (man_handle.peers, &free_tmps,NULL); | 715 | GNUNET_CONTAINER_multipeermap_iterate(man_handle.peers, &free_tmps, NULL); |
738 | GNUNET_CONTAINER_multipeermap_destroy (man_handle.peers); | 716 | GNUNET_CONTAINER_multipeermap_destroy(man_handle.peers); |
739 | |||
740 | next = generic_dqe_head; | ||
741 | while (NULL != (cur = next)) | ||
742 | { | ||
743 | next = cur->next; | ||
744 | GNUNET_CONTAINER_DLL_remove (generic_dqe_head, generic_dqe_tail, cur); | ||
745 | if (NULL != cur->cont) | ||
746 | cur->cont (cur->cont_cls, GNUNET_SYSERR, cur->msg_size, 0); | ||
747 | GNUNET_free (cur); | ||
748 | } | ||
749 | if (GNUNET_SCHEDULER_NO_TASK != generic_send_delay_task) | ||
750 | { | ||
751 | GNUNET_SCHEDULER_cancel (generic_send_delay_task); | ||
752 | generic_send_delay_task = GNUNET_SCHEDULER_NO_TASK; | ||
753 | } | ||
754 | |||
755 | free_metric (&man_handle.general); | ||
756 | man_handle.peers = NULL; | ||
757 | } | ||
758 | 717 | ||
718 | next = generic_dqe_head; | ||
719 | while (NULL != (cur = next)) | ||
720 | { | ||
721 | next = cur->next; | ||
722 | GNUNET_CONTAINER_DLL_remove(generic_dqe_head, generic_dqe_tail, cur); | ||
723 | if (NULL != cur->cont) | ||
724 | cur->cont(cur->cont_cls, GNUNET_SYSERR, cur->msg_size, 0); | ||
725 | GNUNET_free(cur); | ||
726 | } | ||
727 | if (GNUNET_SCHEDULER_NO_TASK != generic_send_delay_task) | ||
728 | { | ||
729 | GNUNET_SCHEDULER_cancel(generic_send_delay_task); | ||
730 | generic_send_delay_task = GNUNET_SCHEDULER_NO_TASK; | ||
731 | } | ||
732 | |||
733 | free_metric(&man_handle.general); | ||
734 | man_handle.peers = NULL; | ||
735 | } | ||
759 | 736 | ||
760 | /* end of file gnunet-service-transport_manipulation.c */ | 737 | /* end of file gnunet-service-transport_manipulation.c */ |