aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-service-transport_manipulation.c
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2013-12-29 17:08:38 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2013-12-29 17:08:38 +0000
commit54c98ba960690442aaf982e7a39045ad42d67547 (patch)
tree576c6eb9486d0ac6693598b0ee95509bdf8b9c9f /src/transport/gnunet-service-transport_manipulation.c
parent51f61878a275964742c245e1695a6c8ef4e40b4c (diff)
downloadgnunet-54c98ba960690442aaf982e7a39045ad42d67547.tar.gz
gnunet-54c98ba960690442aaf982e7a39045ad42d67547.zip
fixing file indent
Diffstat (limited to 'src/transport/gnunet-service-transport_manipulation.c')
-rw-r--r--src/transport/gnunet-service-transport_manipulation.c997
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
37enum TRAFFIC_METRIC_DIRECTION 37enum 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 */
53struct PropManipulationEntry 50struct 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 */
80struct TM_Peer 77struct 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
112struct GST_ManipulationHandle 108struct 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 */
130struct DelayQueueEntry 124struct 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
185struct GST_ManipulationHandle man_handle; 179struct GST_ManipulationHandle man_handle;
@@ -200,53 +194,53 @@ struct DelayQueueEntry *generic_dqe_tail;
200GNUNET_SCHEDULER_TaskIdentifier generic_send_delay_task; 194GNUNET_SCHEDULER_TaskIdentifier generic_send_delay_task;
201 195
202static void 196static void
203set_metric (struct TM_Peer *dest, int direction, uint32_t type, uint32_t value) 197set_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
238static uint32_t 232static uint32_t
239find_metric (struct TM_Peer *dest, uint32_t type, int direction) 233find_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
256static void 250static void
257free_metric (struct TM_Peer *dest) 251free_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 */
278void 271void
279GST_manipulation_set_metric (void *cls, struct GNUNET_SERVER_Client *client, 272GST_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
355static void 350static void
356send_delayed (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 351send_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 */
407void 405void
408GST_manipulation_send (const struct GNUNET_PeerIdentity *target, const void *msg, 406GST_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 */
487struct GNUNET_ATS_Information * 489struct GNUNET_ATS_Information *
488GST_manipulation_manipulate_metrics (const struct GNUNET_PeerIdentity *peer, 490GST_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 */
531struct GNUNET_TIME_Relative 531struct GNUNET_TIME_Relative
532GST_manipulation_recv (void *cls, 532GST_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 */
579void 575void
580GST_manipulation_init (const struct GNUNET_CONFIGURATION_Handle *GST_cfg) 576GST_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
641static int 622static int
642free_tmps (void *cls, 623free_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 */
732void 710void
733GST_manipulation_stop () 711GST_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 */